react-aria
Version:
Spectrum UI components in React
1 lines • 3.62 kB
Source Map (JSON)
{"mappings":";;;AAAA;;;;;;;;;;CAUC;;AAWM,SAAS,0CAAkB,YAA2B;IAC3D,IAAI,CAAC,OAAO,SAAS,GAAG,CAAA,GAAA,eAAO,EAAE;IACjC,iGAAiG;IACjG,sDAAsD;IACtD,IAAI,YAAY,CAAA,GAAA,aAAK,EAAE;IACvB,IAAI,SAAyC,CAAA,GAAA,aAAK,EAAuB;IAEzE,0EAA0E;IAC1E,yCAAyC;IACzC,IAAI,UAAU,CAAA,GAAA,aAAK,EAAE;QACnB,IAAI,CAAC,OAAO,OAAO,EACjB;QAEF,uCAAuC;QACvC,IAAI,WAAW,OAAO,OAAO,CAAC,IAAI;QAElC,8CAA8C;QAC9C,IAAI,SAAS,IAAI,EAAE;YACjB,OAAO,OAAO,GAAG;YACjB;QACF;QAEA,iDAAiD;QACjD,8CAA8C;QAC9C,8DAA8D;QAC9D,IAAI,UAAU,OAAO,KAAK,SAAS,KAAK,EACtC,QAAQ,OAAO;aAEf,SAAS,SAAS,KAAK;IAE3B;IAEA,CAAA,GAAA,yCAAc,EAAE;QACd,UAAU,OAAO,GAAG;QACpB,uEAAuE;QACvE,IAAI,OAAO,OAAO,EAChB,QAAQ,OAAO;IAEnB;IAEA,IAAI,QAAQ,CAAA,GAAA,kBAAU,EACpB,CAAA;QACE,OAAO,OAAO,GAAG,GAAG,UAAU,OAAO;QACrC,QAAQ,OAAO;IACjB,GACA;QAAC;KAAQ;IAGX,OAAO;QAAC;QAAO;KAAM;AACvB","sources":["packages/react-aria/src/utils/useValueEffect.ts"],"sourcesContent":["/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {Dispatch, RefObject, useCallback, useRef, useState} from 'react';\nimport {useLayoutEffect} from './useLayoutEffect';\n\ntype SetValueAction<S> = (prev: S) => Generator<any, void, unknown>;\n\n// This hook works like `useState`, but when setting the value, you pass a generator function\n// that can yield multiple values. Each yielded value updates the state and waits for the next\n// layout effect, then continues the generator. This allows sequential updates to state to be\n// written linearly.\nexport function useValueEffect<S>(defaultValue: S | (() => S)): [S, Dispatch<SetValueAction<S>>] {\n let [value, setValue] = useState(defaultValue);\n // Keep an up to date copy of value in a ref so we can access the current value in the generator.\n // This allows us to maintain a stable queue function.\n let currValue = useRef(value);\n let effect: RefObject<Generator<S> | null> = useRef<Generator<S> | null>(null);\n\n // Store the function in a ref so we can always access the current version\n // which has the proper `value` in scope.\n let nextRef = useRef(() => {\n if (!effect.current) {\n return;\n }\n // Run the generator to the next yield.\n let newValue = effect.current.next();\n\n // If the generator is done, reset the effect.\n if (newValue.done) {\n effect.current = null;\n return;\n }\n\n // If the value is the same as the current value,\n // then continue to the next yield. Otherwise,\n // set the value in state and wait for the next layout effect.\n if (currValue.current === newValue.value) {\n nextRef.current();\n } else {\n setValue(newValue.value);\n }\n });\n\n useLayoutEffect(() => {\n currValue.current = value;\n // If there is an effect currently running, continue to the next yield.\n if (effect.current) {\n nextRef.current();\n }\n });\n\n let queue = useCallback(\n fn => {\n effect.current = fn(currValue.current);\n nextRef.current();\n },\n [nextRef]\n );\n\n return [value, queue];\n}\n"],"names":[],"version":3,"file":"useValueEffect.mjs.map"}