UNPKG

jotai-controller

Version:

A powerful state management library built on top of Jotai with controller pattern for React applications

1,608 lines (1,564 loc) 2.7 MB
import { useStore, useAtom as useAtom$1, createStore as createStore$1, atom as atom$1 } from 'jotai'; import { useHydrateAtoms, createJSONStorage, atomWithStorage as atomWithStorage$1, RESET } from 'jotai/utils'; import { jsx, jsxs, Fragment as Fragment$1 } from 'react/jsx-runtime'; import * as React from 'react'; import React__default, { useCallback as useCallback$1, useState as useState$1, useRef as useRef$1, useLayoutEffect as useLayoutEffect$1, useEffect as useEffect$1, Fragment, createContext as createContext$1, useContext as useContext$1, useMemo as useMemo$1, useId as useId$3, forwardRef as forwardRef$1, cloneElement, Children, createElement as createElement$1, Component, memo, useReducer } from 'react'; import { atom, INTERNAL_overrideCreateStore, createStore } from 'jotai/vanilla'; import { INTERNAL_initializeStoreHooksRev2, INTERNAL_buildStoreRev2 } from 'jotai/vanilla/internals'; import { useSetAtom, useAtom, useAtomValue, Provider } from 'jotai/react'; import { atomWithStorage, atomWithDefault } from 'jotai/vanilla/utils'; import * as ReactDOM from 'react-dom'; import ReactDOM__default, { flushSync, createPortal } from 'react-dom'; function _mergeNamespaces(n, m) { m.forEach(function (e) { e && typeof e !== 'string' && !Array.isArray(e) && Object.keys(e).forEach(function (k) { if (k !== 'default' && !(k in n)) { var d = Object.getOwnPropertyDescriptor(e, k); Object.defineProperty(n, k, d.get ? d : { enumerable: true, get: function () { return e[k]; } }); } }); }); return Object.freeze(n); } (undefined && undefined.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; /* eslint-disable @typescript-eslint/no-non-null-assertion */ const id = (x) => x; const Left = (value) => ({ _tag: 'Left', value, }); const Right = (value) => ({ _tag: 'Right', value, }); const either = (mapLeft, mapRight, e) => (e._tag === 'Left' ? mapLeft(e.value) : mapRight(e.value)); const profunctorFn = { dimap: (f, g, fn) => (x) => g(fn(f(x))), first: (f) => ([x, y]) => [f(x), y], right: (f) => (e) => e._tag === 'Left' ? e : Right(f(e.value)), wander: (f) => (xs) => xs.map(f), }; const monoidFirst = { empty: () => undefined, foldMap: (f, xs) => { for (let i = 0; i < xs.length; i++) { const x = f(xs[i]); if (x != undefined) return x; } return undefined; }, }; const monoidArray = { empty: () => [], foldMap: (f, xs) => { let acc = []; xs.forEach((x) => { acc = acc.concat(f(x)); }); return acc; }, }; const profunctorConst = (monoid) => ({ dimap: (f, _g, toF) => (x) => toF(f(x)), first: (toF) => ([x, _y]) => toF(x), right: (toF) => (e) => e._tag === 'Left' ? monoid.empty() : toF(e.value), wander: (toF) => (xs) => monoid.foldMap(toF, xs), }); const compositionType = { Equivalence: { Equivalence: 'Equivalence', Iso: 'Iso', Lens: 'Lens', Prism: 'Prism', Traversal: 'Traversal', Getter: 'Getter', AffineFold: 'AffineFold', Fold: 'Fold', Setter: 'Setter', }, Iso: { Equivalence: 'Iso', Iso: 'Iso', Lens: 'Lens', Prism: 'Prism', Traversal: 'Traversal', Getter: 'Getter', AffineFold: 'AffineFold', Fold: 'Fold', Setter: 'Setter', }, Lens: { Equivalence: 'Lens', Iso: 'Lens', Lens: 'Lens', Prism: 'Prism', Traversal: 'Traversal', Getter: 'Getter', AffineFold: 'AffineFold', Fold: 'Fold', Setter: 'Setter', }, Prism: { Equivalence: 'Prism', Iso: 'Prism', Lens: 'Prism', Prism: 'Prism', Traversal: 'Traversal', Getter: 'AffineFold', AffineFold: 'AffineFold', Fold: 'Fold', Setter: 'Setter', }, Traversal: { Equivalence: 'Traversal', Iso: 'Traversal', Lens: 'Traversal', Prism: 'Traversal', Traversal: 'Traversal', Getter: 'Fold', AffineFold: 'Fold', Fold: 'Fold', Setter: 'Setter', }, Getter: { Equivalence: 'Getter', Iso: 'Getter', Lens: 'Getter', Prism: 'AffineFold', Traversal: 'Fold', Getter: 'Getter', AffineFold: 'AffineFold', Fold: 'Fold', Setter: undefined, }, AffineFold: { Equivalence: 'AffineFold', Iso: 'AffineFold', Lens: 'AffineFold', Prism: 'AffineFold', Traversal: 'Fold', Getter: 'AffineFold', AffineFold: 'AffineFold', Fold: 'Fold', Setter: undefined, }, Fold: { Equivalence: 'Fold', Iso: 'Fold', Lens: 'Fold', Prism: 'Fold', Traversal: 'Fold', Getter: 'Fold', AffineFold: 'Fold', Fold: 'Fold', Setter: undefined, }, Setter: { Equivalence: undefined, Iso: undefined, Lens: undefined, Prism: undefined, Traversal: undefined, Getter: undefined, AffineFold: undefined, Fold: undefined, Setter: undefined, }, }; const withTag = (tag, optic) => { const result = optic; result._tag = tag; return result; }; const removable = (optic) => { optic._removable = true; return optic; }; function compose(optic1, optic2, optic3) { switch (arguments.length) { case 2: { const next = (P, optic) => optic1(P, optic2(P, optic)); next._tag = compositionType[optic1._tag][optic2._tag]; next._removable = optic2._removable || false; return next; } default: { const tag1 = compositionType[optic1._tag][optic2._tag]; const next = (P, optic) => optic1(P, optic2(P, optic3(P, optic))); next._tag = compositionType[tag1][optic3._tag]; next._removable = optic3._removable || false; return next; } } } const eq = /* @__PURE__ */ withTag('Equivalence', (_P, optic) => optic); const iso = (there, back) => withTag('Iso', (P, optic) => P.dimap(there, back, optic)); const lens = (view, update) => withTag('Lens', (P, optic) => P.dimap((x) => [view(x), x], update, P.first(optic))); const prism = (match, build) => withTag('Prism', (P, optic) => P.dimap(match, (x) => either(id, build, x), P.right(optic))); const elems = /* @__PURE__ */ withTag('Traversal', (P, optic) => P.dimap(id, id, P.wander(optic))); const to = (fn) => withTag('Getter', (P, optic) => P.dimap(fn, id, optic)); ///////////////////////////////////////////////////////////////////////////// const modify$1 = (optic, fn, source) => optic(profunctorFn, fn)(source); const set$1 = (optic, value, source) => optic(profunctorFn, () => value)(source); const get$1 = (optic, source) => optic(profunctorConst({}), id)(source); const preview$1 = (optic, source) => optic(profunctorConst(monoidFirst), id)(source); const collect$1 = (optic, source) => optic(profunctorConst(monoidArray), (x) => [x])(source); ///////////////////////////////////////////////////////////////////////////// const indexed = /* @__PURE__ */ iso((value) => value.map((v, k) => [k, v]), (value) => { const sorted = [...value].sort((a, b) => a[0] - b[0]); const result = []; for (let i = 0; i < sorted.length; ++i) { if (i === sorted.length - 1 || sorted[i][0] !== sorted[i + 1][0]) { result.push(sorted[i][1]); } } return result; }); const prop = (key) => lens((source) => source[key], ([value, source]) => (Object.assign(Object.assign({}, source), { [key]: value }))); const pick = (keys) => lens((source) => { const value = {}; for (const key of keys) { value[key] = source[key]; } return value; }, ([value, source]) => { const result = Object.assign({}, source); for (const key of keys) { delete result[key]; } return Object.assign(result, value); }); const nth = (n) => lens((value) => value[n], ([value, source]) => { const result = source.slice(); result[n] = value; return result; }); const fst = /* @__PURE__ */ nth(0); const when = (pred) => prism((x) => (pred(x) ? Right(x) : Left(x)), id); const noMatch = /* @__PURE__ */ Symbol('__no_match__'); const mustMatch = /* @__PURE__ */ when((source) => source !== noMatch); const removeMe = /* @__PURE__ */ Symbol('__remove_me__'); const at = (i) => removable(compose(lens((source) => (0 <= i && i < source.length ? source[i] : noMatch), ([value, source]) => { if (value === noMatch) { return source; } if (value === removeMe) { if (typeof source === 'string') { return source.substring(0, i) + source.substring(i + 1); } else { return [...source.slice(0, i), ...source.slice(i + 1)]; } } if (typeof source === 'string') { if (i === 0) { return value + source.substring(1); } if (i === source.length) { return source.substring(0, i - 1) + value; } return source.substring(0, i) + value + source.substring(i + 1); } else { const result = source.slice(); result[i] = value; return result; } }), mustMatch)); const optional = /* @__PURE__ */ prism((source) => (source === undefined ? Left(undefined) : Right(source)), id); const guard = (fn) => prism((source) => (fn(source) ? Right(source) : Left(source)), id); const find = (predicate) => removable(compose(lens((source) => { const index = source.findIndex(predicate); if (index === -1) { return [noMatch, -1]; } return [source[index], index]; }, ([[value, index], source]) => { if (value === noMatch) { return source; } if (value === removeMe) { return [...source.slice(0, index), ...source.slice(index + 1)]; } const result = source.slice(); result[index] = value; return result; }), fst, mustMatch)); const filter = (predicate) => compose(lens((source) => { const indexes = source .map((item, index) => (predicate(item) ? index : null)) .filter((index) => index != null); return [indexes.map((index) => source[index]), indexes]; }, ([[values, indexes], source]) => { const sn = source.length, vn = values.length; let si = 0, ii = 0, vi = 0; const result = []; while (si < sn) { if (indexes[ii] === si) { ++ii; if (vi < vn) { result.push(values[vi]); ++vi; } } else { result.push(source[si]); } ++si; } while (vi < vn) { result.push(values[vi++]); } return result; }), fst); const valueOr = (defaultValue) => lens((source) => (source === undefined ? defaultValue : source), ([value, _source]) => value); const partsOf = (traversal) => compose(lens((source) => { const value = collect$1(traversal, source); return [value, value.length]; }, ([[value, originalLength], source]) => { if (value.length !== originalLength) { throw new Error('cannot add/remove elements through partsOf'); } let i = 0; return modify$1(traversal, () => value[i++], source); }), fst); const reread = (fn) => lens((source) => fn(source), ([value, _]) => value); const rewrite = (fn) => lens((source) => source, ([value, _]) => fn(value)); const prependTo = /* @__PURE__ */ lens((_source) => undefined, ([value, source]) => { if (value === undefined) return source; return [value, ...source]; }); const appendTo = /* @__PURE__ */ lens((_source) => undefined, ([value, source]) => { if (value === undefined) return source; return [...source, value]; }); const chars = /* @__PURE__ */ compose(iso((s) => s.split(''), (a) => a.join('')), elems); const words = /* @__PURE__ */ compose(iso((s) => s.split(/\b/), (a) => a.join('')), elems, when((s) => !/\s+/.test(s))); ///////////////////////////////////////////////////////////////////////////// class Optic { constructor(_ref) { this._ref = _ref; } get _tag() { return this._ref._tag; } get _removable() { return this._ref._removable; } compose(other) { return new Optic(compose(this._ref, other._ref)); } iso(there, back) { return new Optic(compose(this._ref, iso(there, back))); } lens(view, set) { return new Optic(compose(this._ref, lens(view, ([value, source]) => set(source, value)))); } indexed() { return new Optic(compose(this._ref, indexed)); } prop(key) { return new Optic(compose(this._ref, prop(key))); } path(...keys) { if (keys.length === 1) { keys = keys[0].split('.'); } return new Optic(keys.reduce((ref, key) => compose(ref, prop(key)), this._ref)); } pick(keys) { return new Optic(compose(this._ref, pick(keys))); } nth(n) { return new Optic(compose(this._ref, nth(n))); } filter(predicate) { return new Optic(compose(this._ref, filter(predicate))); } valueOr(defaultValue) { return new Optic(compose(this._ref, valueOr(defaultValue))); } partsOf(traversalOrFn) { const traversal = typeof traversalOrFn === 'function' ? traversalOrFn(optic$1) : traversalOrFn; return new Optic(compose(this._ref, partsOf(traversal._ref))); } reread(fn) { return new Optic(compose(this._ref, reread(fn))); } rewrite(fn) { return new Optic(compose(this._ref, rewrite(fn))); } optional() { return new Optic(compose(this._ref, optional)); } guard_() { return (fn) => this.guard(fn); } guard(fn) { return new Optic(compose(this._ref, guard(fn))); } at(i) { return new Optic(compose(this._ref, at(i))); } head() { return new Optic(compose(this._ref, at(0))); } index(i) { return new Optic(compose(this._ref, at(i))); } find(predicate) { return new Optic(compose(this._ref, find(predicate))); } elems() { return new Optic(compose(this._ref, elems)); } to(fn) { return new Optic(compose(this._ref, to(fn))); } when(predicate) { return new Optic(compose(this._ref, when(predicate))); } chars() { return new Optic(compose(this._ref, chars)); } words() { return new Optic(compose(this._ref, words)); } prependTo() { return new Optic(compose(this._ref, prependTo)); } appendTo() { return new Optic(compose(this._ref, appendTo)); } } const optic$1 = /* @__PURE__ */ new Optic(eq); /* eslint-disable @typescript-eslint/adjacent-overload-signatures, @typescript-eslint/no-unused-vars */ // This file is generated, do not edit! See ../scripts/generate-index.ts function optic() { return optic$1; } function get(optic) { return (source) => get$1(optic._ref, source); } function preview(optic) { return (source) => preview$1(optic._ref, source); } function collect(optic) { return (source) => collect$1(optic._ref, source); } function modify(optic) { return (f) => (source) => modify$1(optic._ref, f, source); } function set(optic) { return (value) => (source) => set$1(optic._ref, value, source); } /* eslint-disable @typescript-eslint/no-explicit-any */ const getCached = (c, m, k) => (m.has(k) ? m : m.set(k, c())).get(k); const cache1 = new WeakMap(); const memo2 = (create, dep1, dep2) => { const cache2 = getCached(() => new WeakMap(), cache1, dep1); return getCached(create, cache2, dep2); }; const isFunction = (x) => typeof x === 'function'; // Implementation function focusAtom(baseAtom, callback) { return memo2(() => { const focus = callback(optic()); const derivedAtom = atom((get) => { const base = get(baseAtom); return base instanceof Promise ? base.then((v) => getValueUsingOptic(focus, v)) : getValueUsingOptic(focus, base); }, (get, set$1, update) => { const newValueProducer = isFunction(update) ? modify(focus)(update) : set(focus)(update); const base = get(baseAtom); return set$1(baseAtom, (base instanceof Promise ? base.then(newValueProducer) : newValueProducer(base))); }); return derivedAtom; }, baseAtom, callback); } const getValueUsingOptic = (focus, bigValue) => { if (focus._tag === 'Traversal') { const values = collect(focus)(bigValue); return values; } if (focus._tag === 'Prism') { const value = preview(focus)(bigValue); return value; } const value = get(focus)(bigValue); return value; }; // src/utils/useAtomsSnapshot.ts var isDevToolsStore = (store) => { return "subscribeStore" in store; }; var __composeWithDevTools = (store) => { const { sub, set, get } = store; const storeListeners = /* @__PURE__ */ new Set(); const recentlySetAtomsMap = /* @__PURE__ */ new WeakMap(); const reduceCountOrRemoveRecentlySetAtom = (atom, onFound) => { const foundCount = recentlySetAtomsMap.get(atom); if (typeof foundCount === "number") { if (foundCount > 1) { recentlySetAtomsMap.set(atom, foundCount - 1); } else { recentlySetAtomsMap.delete(atom); } onFound?.(); } }; const increaseCountRecentlySetAtom = (atom) => { const foundCount = recentlySetAtomsMap.get(atom); recentlySetAtomsMap.set(atom, (foundCount || 0) + 1); }; store.sub = (...args) => { const unsub = sub(...args); storeListeners.forEach((l) => l({ type: "sub" })); return () => { unsub(); reduceCountOrRemoveRecentlySetAtom(args[0]); storeListeners.forEach((l) => l({ type: "unsub" })); }; }; store.get = (...args) => { const value = get(...args); reduceCountOrRemoveRecentlySetAtom(args[0], () => { if (value instanceof Promise) { value.finally(() => { Promise.resolve().then(() => { storeListeners.forEach((l) => l({ type: "async-get" })); }); }); } }); return value; }; store.set = (...args) => { const value = set(...args); increaseCountRecentlySetAtom(args[0]); storeListeners.forEach((l) => l({ type: "set" })); return value; }; store.subscribeStore = (l) => { storeListeners.add(l); return () => { storeListeners.delete(l); }; }; store.getMountedAtoms = () => { return store.get_mounted_atoms(); }; store.getAtomState = (atom) => { const aState = store.get_internal_weak_map().get(atom); if (aState) { return { v: aState.v, e: aState.e, d: new Set(aState.d.keys()) }; } return void 0; }; store.getMountedAtomState = (atom) => { const aState = store.get_internal_weak_map().get(atom); if (aState && "m" in aState) { return { l: aState.m.l, t: aState.m.t }; } return void 0; }; store.restoreAtoms = (values) => { store.restore_atoms(values); storeListeners.forEach((l) => l({ type: "restore" })); }; return store; }; var createDevStore = () => { let inRestoreAtom = 0; const storeHooks = INTERNAL_initializeStoreHooksRev2({}); const atomStateMap = /* @__PURE__ */ new WeakMap(); const mountedAtoms = /* @__PURE__ */ new WeakMap(); const store = INTERNAL_buildStoreRev2( atomStateMap, mountedAtoms, void 0, void 0, void 0, void 0, storeHooks, void 0, (_store, atom, get, set, ...args) => { if (inRestoreAtom) { return set(atom, ...args); } return atom.write(get, set, ...args); } ); const debugMountedAtoms = /* @__PURE__ */ new Set(); storeHooks.m.add(void 0, (atom) => { debugMountedAtoms.add(atom); const atomState = atomStateMap.get(atom); atomState.m = mountedAtoms.get(atom); }); storeHooks.u.add(void 0, (atom) => { debugMountedAtoms.delete(atom); const atomState = atomStateMap.get(atom); delete atomState.m; }); const devStore = { // store dev methods (these are tentative and subject to change without notice) get_internal_weak_map: () => atomStateMap, get_mounted_atoms: () => debugMountedAtoms, restore_atoms: (values) => { const restoreAtom = { read: () => null, write: (_get, set) => { ++inRestoreAtom; try { for (const [atom, value] of values) { if ("init" in atom) { set(atom, value); } } } finally { --inRestoreAtom; } } }; store.set(restoreAtom); } }; return Object.assign(store, devStore); }; var isDevStore = (store) => { return "get_internal_weak_map" in store; }; INTERNAL_overrideCreateStore((prev) => { return createDevStore; }); var composeWithDevTools = (store) => { if (isDevToolsStore(store)) { return store; } if (isDevStore(store)) { return __composeWithDevTools(store); } return store; }; // src/utils/hooks/useDevToolsStore.ts var useDevToolsStore = (options) => { const store = useStore(options); return composeWithDevTools(store); }; // src/utils/useAtomsSnapshot.ts var isEqualAtomsValues = (left, right) => left.size === right.size && Array.from(left).every(([left2, v]) => Object.is(right.get(left2), v)); var isEqualAtomsDependents = (left, right) => left.size === right.size && Array.from(left).every(([a, dLeft]) => { const dRight = right.get(a); return dRight && dLeft.size === dRight.size && Array.from(dLeft).every((d) => dRight.has(d)); }); function useAtomsSnapshot({ shouldShowPrivateAtoms = false, ...options } = {}) { const store = useDevToolsStore(options); const [atomsSnapshot, setAtomsSnapshot] = useState$1(() => ({ values: /* @__PURE__ */ new Map(), dependents: /* @__PURE__ */ new Map() })); const duringReactRenderPhase = useRef$1(true); duringReactRenderPhase.current = true; useLayoutEffect$1(() => { duringReactRenderPhase.current = false; }); useEffect$1(() => { if (!isDevToolsStore(store)) return; let prevValues = /* @__PURE__ */ new Map(); let prevDependents = /* @__PURE__ */ new Map(); const callback = () => { const values = /* @__PURE__ */ new Map(); const dependents = /* @__PURE__ */ new Map(); for (const atom of store.getMountedAtoms() || []) { if (!shouldShowPrivateAtoms && atom.debugPrivate) { continue; } const atomState = store.getAtomState(atom); if (atomState) { if ("v" in atomState) { values.set(atom, atomState.v); } } const mounted = store.getMountedAtomState(atom); if (mounted) { let atomDependents = mounted.t; if (!shouldShowPrivateAtoms) { atomDependents = new Set( Array.from(atomDependents.values()).filter( /* NOTE: This just removes private atoms from the dependents list, instead of hiding them from the dependency chain and showing the nested dependents of the private atoms. */ (dependent) => !dependent.debugPrivate ) ); } dependents.set(atom, atomDependents); } } if (isEqualAtomsValues(prevValues, values) && isEqualAtomsDependents(prevDependents, dependents)) { return; } prevValues = values; prevDependents = dependents; const deferrableAtomSetAction = () => setAtomsSnapshot({ values, dependents }); if (duringReactRenderPhase.current) { Promise.resolve().then(deferrableAtomSetAction); } else { deferrableAtomSetAction(); } }; const unsubscribe = store.subscribeStore(callback); callback(); return unsubscribe; }, [store, shouldShowPrivateAtoms]); return atomsSnapshot; } function useGotoAtomsSnapshot(options) { const store = useDevToolsStore(options); return useCallback$1( (snapshot) => { if (isDevToolsStore(store)) { store.restoreAtoms(snapshot.values); } }, [store] ); } function keys(object) { return Object.keys(object); } function isObject(item) { return item && typeof item === "object" && !Array.isArray(item); } function deepMerge(target, source) { const result = { ...target }; const _source = source; if (isObject(target) && isObject(source)) { Object.keys(source).forEach((key) => { if (isObject(_source[key])) { if (!(key in target)) { result[key] = _source[key]; } else { result[key] = deepMerge(result[key], _source[key]); } } else { result[key] = _source[key]; } }); } return result; } function camelToKebabCase(value) { return value.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`); } function getTransformedScaledValue(value) { if (typeof value !== "string" || !value.includes("var(--mantine-scale)")) { return value; } return value.match(/^calc\((.*?)\)$/)?.[1].split("*")[0].trim(); } function px(value) { const transformedValue = getTransformedScaledValue(value); if (typeof transformedValue === "number") { return transformedValue; } if (typeof transformedValue === "string") { if (transformedValue.includes("calc") || transformedValue.includes("var")) { return transformedValue; } if (transformedValue.includes("px")) { return Number(transformedValue.replace("px", "")); } if (transformedValue.includes("rem")) { return Number(transformedValue.replace("rem", "")) * 16; } if (transformedValue.includes("em")) { return Number(transformedValue.replace("em", "")) * 16; } return Number(transformedValue); } return NaN; } function scaleRem(remValue) { if (remValue === "0rem") { return "0rem"; } return `calc(${remValue} * var(--mantine-scale))`; } function createConverter(units, { shouldScale = false } = {}) { function converter(value) { if (value === 0 || value === "0") { return `0${units}`; } if (typeof value === "number") { const val = `${value / 16}${units}`; return shouldScale ? scaleRem(val) : val; } if (typeof value === "string") { if (value === "") { return value; } if (value.startsWith("calc(") || value.startsWith("clamp(") || value.includes("rgba(")) { return value; } if (value.includes(",")) { return value.split(",").map((val) => converter(val)).join(","); } if (value.includes(" ")) { return value.split(" ").map((val) => converter(val)).join(" "); } if (value.includes(units)) { return shouldScale ? scaleRem(value) : value; } const replaced = value.replace("px", ""); if (!Number.isNaN(Number(replaced))) { const val = `${Number(replaced) / 16}${units}`; return shouldScale ? scaleRem(val) : val; } } return value; } return converter; } const rem = createConverter("rem", { shouldScale: true }); const em = createConverter("em"); function filterProps(props) { return Object.keys(props).reduce((acc, key) => { if (props[key] !== void 0) { acc[key] = props[key]; } return acc; }, {}); } function isNumberLike(value) { if (typeof value === "number") { return true; } if (typeof value === "string") { if (value.startsWith("calc(") || value.startsWith("var(") || value.includes(" ") && value.trim() !== "") { return true; } const cssUnitsRegex = /^[+-]?[0-9]+(\.[0-9]+)?(px|em|rem|ex|ch|lh|rlh|vw|vh|vmin|vmax|vb|vi|svw|svh|lvw|lvh|dvw|dvh|cm|mm|in|pt|pc|q|cqw|cqh|cqi|cqb|cqmin|cqmax|%)?$/; const values = value.trim().split(/\s+/); return values.every((val) => cssUnitsRegex.test(val)); } return false; } function isElement$1(value) { if (Array.isArray(value) || value === null) { return false; } if (typeof value === "object") { if (value.type === Fragment) { return false; } return true; } return false; } function createSafeContext(errorMessage) { const Context = createContext$1(null); const useSafeContext = () => { const ctx = useContext$1(Context); if (ctx === null) { throw new Error(errorMessage); } return ctx; }; const Provider = ({ children, value }) => /* @__PURE__ */ jsx(Context.Provider, { value, children }); return [Provider, useSafeContext]; } function createOptionalContext(initialValue = null) { const Context = createContext$1(initialValue); const useOptionalContext = () => useContext$1(Context); const Provider = ({ children, value }) => /* @__PURE__ */ jsx(Context.Provider, { value, children }); return [Provider, useOptionalContext]; } function getSafeId(uid, errorMessage) { return (value) => { if (typeof value !== "string" || value.trim().length === 0) { throw new Error(errorMessage); } return `${uid}-${value}`; }; } function findElementAncestor(element, selector) { let _element = element; while ((_element = _element.parentElement) && !_element.matches(selector)) { } return _element; } function getPreviousIndex$1(current, elements, loop) { for (let i = current - 1; i >= 0; i -= 1) { if (!elements[i].disabled) { return i; } } if (loop) { for (let i = elements.length - 1; i > -1; i -= 1) { if (!elements[i].disabled) { return i; } } } return current; } function getNextIndex$1(current, elements, loop) { for (let i = current + 1; i < elements.length; i += 1) { if (!elements[i].disabled) { return i; } } if (loop) { for (let i = 0; i < elements.length; i += 1) { if (!elements[i].disabled) { return i; } } } return current; } function onSameLevel(target, sibling, parentSelector) { return findElementAncestor(target, parentSelector) === findElementAncestor(sibling, parentSelector); } function createScopedKeydownHandler({ parentSelector, siblingSelector, onKeyDown, loop = true, activateOnFocus = false, dir = "rtl", orientation }) { return (event) => { onKeyDown?.(event); const elements = Array.from( findElementAncestor(event.currentTarget, parentSelector)?.querySelectorAll( siblingSelector ) || [] ).filter((node) => onSameLevel(event.currentTarget, node, parentSelector)); const current = elements.findIndex((el) => event.currentTarget === el); const _nextIndex = getNextIndex$1(current, elements, loop); const _previousIndex = getPreviousIndex$1(current, elements, loop); const nextIndex = dir === "rtl" ? _previousIndex : _nextIndex; const previousIndex = dir === "rtl" ? _nextIndex : _previousIndex; switch (event.key) { case "ArrowRight": { if (orientation === "horizontal") { event.stopPropagation(); event.preventDefault(); elements[nextIndex].focus(); activateOnFocus && elements[nextIndex].click(); } break; } case "ArrowLeft": { if (orientation === "horizontal") { event.stopPropagation(); event.preventDefault(); elements[previousIndex].focus(); activateOnFocus && elements[previousIndex].click(); } break; } case "ArrowUp": { if (orientation === "vertical") { event.stopPropagation(); event.preventDefault(); elements[_previousIndex].focus(); activateOnFocus && elements[_previousIndex].click(); } break; } case "ArrowDown": { if (orientation === "vertical") { event.stopPropagation(); event.preventDefault(); elements[_nextIndex].focus(); activateOnFocus && elements[_nextIndex].click(); } break; } case "Home": { event.stopPropagation(); event.preventDefault(); !elements[0].disabled && elements[0].focus(); break; } case "End": { event.stopPropagation(); event.preventDefault(); const last = elements.length - 1; !elements[last].disabled && elements[last].focus(); break; } } }; } const elevations = { app: 100, modal: 200, popover: 300, overlay: 400, max: 9999 }; function getDefaultZIndex(level) { return elevations[level]; } const noop$1 = () => { }; function closeOnEscape(callback, options = { active: true }) { if (typeof callback !== "function" || !options.active) { return options.onKeyDown || noop$1; } return (event) => { if (event.key === "Escape") { callback(event); options.onTrigger?.(); } }; } function getSize(size, prefix = "size", convertToRem = true) { if (size === void 0) { return void 0; } return isNumberLike(size) ? convertToRem ? rem(size) : size : `var(--${prefix}-${size})`; } function getSpacing(size) { return getSize(size, "mantine-spacing"); } function getRadius(size) { if (size === void 0) { return "var(--mantine-radius-default)"; } return getSize(size, "mantine-radius"); } function getFontSize(size) { return getSize(size, "mantine-font-size"); } function getLineHeight(size) { return getSize(size, "mantine-line-height", false); } function getShadow(size) { if (!size) { return void 0; } return getSize(size, "mantine-shadow", false); } function clamp$2(value, min, max) { if (min === void 0 && max === void 0) { return value; } if (min !== void 0 && max === void 0) { return Math.max(value, min); } if (min === void 0 && max !== void 0) { return Math.min(value, max); } return Math.min(Math.max(value, min), max); } function randomId(prefix = "mantine-") { return `${prefix}${Math.random().toString(36).slice(2, 11)}`; } function useCallbackRef(callback) { const callbackRef = useRef$1(callback); useEffect$1(() => { callbackRef.current = callback; }); return useMemo$1(() => (...args) => callbackRef.current?.(...args), []); } function useDebouncedCallback(callback, options) { const delay = typeof options === "number" ? options : options.delay; const flushOnUnmount = typeof options === "number" ? false : options.flushOnUnmount; const handleCallback = useCallbackRef(callback); const debounceTimerRef = useRef$1(0); const flushRef = useRef$1(() => { }); const lastCallback = Object.assign( useCallback$1( (...args) => { window.clearTimeout(debounceTimerRef.current); const flush = () => { if (debounceTimerRef.current !== 0) { debounceTimerRef.current = 0; handleCallback(...args); } }; flushRef.current = flush; lastCallback.flush = flush; debounceTimerRef.current = window.setTimeout(flush, delay); }, [handleCallback, delay] ), { flush: flushRef.current } ); useEffect$1( () => () => { window.clearTimeout(debounceTimerRef.current); if (flushOnUnmount) { lastCallback.flush(); } }, [lastCallback, flushOnUnmount] ); return lastCallback; } const DEFAULT_EVENTS = ["mousedown", "touchstart"]; function useClickOutside(handler, events, nodes) { const ref = useRef$1(null); useEffect$1(() => { const listener = (event) => { const { target } = event ?? {}; if (Array.isArray(nodes)) { const shouldIgnore = target?.hasAttribute("data-ignore-outside-clicks") || !document.body.contains(target) && target.tagName !== "HTML"; const shouldTrigger = nodes.every((node) => !!node && !event.composedPath().includes(node)); shouldTrigger && !shouldIgnore && handler(); } else if (ref.current && !ref.current.contains(target)) { handler(); } }; (events || DEFAULT_EVENTS).forEach((fn) => document.addEventListener(fn, listener)); return () => { (events || DEFAULT_EVENTS).forEach((fn) => document.removeEventListener(fn, listener)); }; }, [ref, handler, nodes]); return ref; } function useClipboard({ timeout = 2e3 } = {}) { const [error, setError] = useState$1(null); const [copied, setCopied] = useState$1(false); const [copyTimeout, setCopyTimeout] = useState$1(null); const handleCopyResult = (value) => { window.clearTimeout(copyTimeout); setCopyTimeout(window.setTimeout(() => setCopied(false), timeout)); setCopied(value); }; const copy = (valueToCopy) => { if ("clipboard" in navigator) { navigator.clipboard.writeText(valueToCopy).then(() => handleCopyResult(true)).catch((err) => setError(err)); } else { setError(new Error("useClipboard: navigator.clipboard is not supported")); } }; const reset = () => { setCopied(false); setError(null); window.clearTimeout(copyTimeout); }; return { copy, reset, error, copied }; } function attachMediaListener(query, callback) { try { query.addEventListener("change", callback); return () => query.removeEventListener("change", callback); } catch (e) { query.addListener(callback); return () => query.removeListener(callback); } } function getInitialValue(query, initialValue) { if (typeof window !== "undefined" && "matchMedia" in window) { return window.matchMedia(query).matches; } return false; } function useMediaQuery(query, initialValue, { getInitialValueInEffect } = { getInitialValueInEffect: true }) { const [matches, setMatches] = useState$1( getInitialValueInEffect ? initialValue : getInitialValue(query) ); const queryRef = useRef$1(null); useEffect$1(() => { if ("matchMedia" in window) { queryRef.current = window.matchMedia(query); setMatches(queryRef.current.matches); return attachMediaListener(queryRef.current, (event) => setMatches(event.matches)); } return void 0; }, [query]); return matches; } function useColorScheme(initialValue, options) { return useMediaQuery("(prefers-color-scheme: dark)", initialValue === "dark", options) ? "dark" : "light"; } const useIsomorphicEffect = typeof document !== "undefined" ? useLayoutEffect$1 : useEffect$1; function useDidUpdate(fn, dependencies) { const mounted = useRef$1(false); useEffect$1( () => () => { mounted.current = false; }, [] ); useEffect$1(() => { if (mounted.current) { return fn(); } mounted.current = true; return void 0; }, dependencies); } function useFocusReturn({ opened, shouldReturnFocus = true }) { const lastActiveElement = useRef$1(null); const returnFocus = () => { if (lastActiveElement.current && "focus" in lastActiveElement.current && typeof lastActiveElement.current.focus === "function") { lastActiveElement.current?.focus({ preventScroll: true }); } }; useDidUpdate(() => { let timeout = -1; const clearFocusTimeout = (event) => { if (event.key === "Tab") { window.clearTimeout(timeout); } }; document.addEventListener("keydown", clearFocusTimeout); if (opened) { lastActiveElement.current = document.activeElement; } else if (shouldReturnFocus) { timeout = window.setTimeout(returnFocus, 10); } return () => { window.clearTimeout(timeout); document.removeEventListener("keydown", clearFocusTimeout); }; }, [opened, shouldReturnFocus]); return returnFocus; } const TABBABLE_NODES = /input|select|textarea|button|object/; const FOCUS_SELECTOR = "a, input, select, textarea, button, object, [tabindex]"; function hidden(element) { if (process.env.NODE_ENV === "test") { return false; } return element.style.display === "none"; } function visible(element) { const isHidden = element.getAttribute("aria-hidden") || element.getAttribute("hidden") || element.getAttribute("type") === "hidden"; if (isHidden) { return false; } let parentElement = element; while (parentElement) { if (parentElement === document.body || parentElement.nodeType === 11) { break; } if (hidden(parentElement)) { return false; } parentElement = parentElement.parentNode; } return true; } function getElementTabIndex(element) { let tabIndex = element.getAttribute("tabindex"); if (tabIndex === null) { tabIndex = void 0; } return parseInt(tabIndex, 10); } function focusable(element) { const nodeName = element.nodeName.toLowerCase(); const isTabIndexNotNaN = !Number.isNaN(getElementTabIndex(element)); const res = ( // @ts-expect-error function accepts any html element but if it is a button, it should not be disabled to trigger the condition TABBABLE_NODES.test(nodeName) && !element.disabled || (element instanceof HTMLAnchorElement ? element.href || isTabIndexNotNaN : isTabIndexNotNaN) ); return res && visible(element); } function tabbable(element) { const tabIndex = getElementTabIndex(element); const isTabIndexNaN = Number.isNaN(tabIndex); return (isTabIndexNaN || tabIndex >= 0) && focusable(element); } function findTabbableDescendants(element) { return Array.from(element.querySelectorAll(FOCUS_SELECTOR)).filter(tabbable); } function scopeTab(node, event) { const tabbable = findTabbableDescendants(node); if (!tabbable.length) { event.preventDefault(); return; } const finalTabbable = tabbable[event.shiftKey ? 0 : tabbable.length - 1]; const root = node.getRootNode(); let leavingFinalTabbable = finalTabbable === root.activeElement || node === root.activeElement; const activeElement = root.activeElement; const activeElementIsRadio = activeElement.tagName === "INPUT" && activeElement.getAttribute("type") === "radio"; if (activeElementIsRadio) { const activeRadioGroup = tabbable.filter( (element) => element.getAttribute("type") === "radio" && element.getAttribute("name") === activeElement.getAttribute("name") ); leavingFinalTabbable = activeRadioGroup.includes(finalTabbable); } if (!leavingFinalTabbable) { return; } event.preventDefault(); const target = tabbable[event.shiftKey ? tabbable.length - 1 : 0]; if (target) { target.focus(); } } function useFocusTrap(active = true) { const ref = useRef$1(null); const focusNode = (node) => { let focusElement = node.querySelector("[data-autofocus]"); if (!focusElement) { const children = Array.from(node.querySelectorAll(FOCUS_SELECTOR)); focusElement = children.find(tabbable) || children.find(focusable) || null; if (!focusElement && focusable(node)) { focusElement = node; } } if (focusElement) { focusElement.focus({ preventScroll: true }); } else if (process.env.NODE_ENV === "development") { console.warn( "[@mantine/hooks/use-focus-trap] Failed to find focusable element within provided node", node ); } }; const setRef = useCallback$1( (node) => { if (!active) { return; } if (node === null) { return; } if (ref.current === node) { return; } if (node) { setTimeout(() => { if (node.getRootNode()) { focusNode(node); } else if (process.env.NODE_ENV === "development") { console.warn("[@mantine/hooks/use-focus-trap] Ref node is not part of the dom", node); } }); ref.current = node; } else { ref.current = null; } }, [active] ); useEffect$1(() => { if (!active) { return void 0; } ref.current && setTimeout(() => focusNode(ref.current)); const handleKeyDown = (event) => { if (event.key === "Tab" && ref.current) { scopeTab(ref.current, event); } }; document.addEventListener("keydown", handleKeyDown); return () => document.removeEventListener("keydown", handleKeyDown); }, [active]); return setRef; } const __useId = React__default["useId".toString()] || (() => void 0); function useReactId$1() { const id = __useId(); return id ? `mantine-${id.replace(/:/g, "")}` : ""; } function useId$2(staticId) { const reactId = useReactId$1(); const [uuid, setUuid] = useState$1(reactId); useIsomorphicEffect(() => { setUuid(randomId()); }, []); if (typeof staticId === "string") { return staticId; } if (typeof window === "undefined") { return reactId; } return uuid; } function useInterval(fn, interval, { autoInvoke = false } = {}) { const [active, setActive] = useState$1(false); const intervalRef = useRef$1(null); const fnRef = useRef$1(null); const start = () => { setActive((old) => { if (!old && (!intervalRef.current || intervalRef.current === -1)) { intervalRef.current = window.setInterval(fnRef.current, interval); } return true; }); }; const stop = () => { setActive(false); window.clearInterval(intervalRef.current || -1); intervalRef.current = -1; }; const toggle = () => { if (active) { stop(); } else { start(); } }; useEffect$1(() => { fnRef.current = fn; active && start(); return stop; }, [fn, active, interval]); useEffect$1(() => { if (autoInvoke) { start(); } }, []); return { start, stop, toggle, active }; } function useWindowEvent(type, listener, options) { useEffect$1(() => { window.addEventListener(type, listener, options); return () => window.removeEventListener(type, listener, options); }, [type, listener]); } function assignRef(ref, value) { if (typeof ref === "function") { return ref(value); } else if (typeof ref === "object" && ref !== null && "current" in ref) { ref.current = value; } } function mergeRefs(...refs) { const cleanupMap = /* @__PURE__ */ new Map(); return (node) => { refs.forEach((ref) => { const cleanup = assignRef(ref, node); if (cleanup) { cleanupMap.set(ref, cleanup); } }); if (cleanupMap.size > 0) { return () => { refs.forEach((ref) => { const cleanup = cleanupMap.get(ref); if (cleanup) { cleanup(); } else { assignRef(ref, null); } }); cleanupMap.clear(); }; } }; } function useMergedRef(...refs) { return useCallback$1(mergeRefs(...refs), refs); } function useMove(onChange, handlers, dir = "ltr") { const ref = useRef$1(null); const mounted = useRef$1(false); const isSliding = useRef$1(false); const frame = useRef$1(0); const [active, setActive] = useState$1(false); useEffect$1(() => { mounted.current = true; }, []); useEffect$1(() => { const node = ref.current; const onScrub = ({ x, y }) => { cancelAnimationFrame(frame.current); frame.current = requestAnimationFrame(() => { if (mounted.current && node) { node.style.userSelect = "none"; const rect = node.getBoundingClientRect(); if (rect.width && rect.height) { const _x = clamp$2((x - rect.left) / rect.width, 0, 1); onChange({ x: dir === "ltr" ? _x : 1 - _x, y: clamp$2((y - rect.top) / rect.height, 0, 1) }); } } }); }; const bindEvents = () => { document.addEventListener("mousemove", onMouseMove); document.addEventListener("mouseup", stopScrubbing); document.addEventListener("touchmove", onTouchMove); document.addEventListener("touchend", stopScrubbing); }; const unbindEvents = () => { document.removeEventListener("mousemove", onMouseMove); document.removeEventListener("mouseup", stopScrubbing); document.removeEventListener("touchmove", onTouchMove); document.removeEventListener("touchend", stopScrubbing); }; const startScrubbing = () => { if (!isSliding.current && mounted.current) { isSliding.current = true; typeof handlers?.onScrubStart === "function" && handlers.onScrubStart(); setActive(true); bindEvents(); } }; const stopScrubbing = () => { if (isSliding.current && mounted.current) { isSliding.current = false; setActive(false); unbindEvents(); setTimeout(() => { typeof handlers?.onScrubEnd === "function" && handlers.onScrubEnd(); }, 0); } }; const onMouseDown = (event) => { startScrubbing(); event.preventDefault(); onMouseMove(event); }; const onMouseMove = (event) => onScrub({ x: event.clientX, y: event.clientY }); const onTouchStart = (event) => { if (event.cancelable) { event.preventDefault(); } startScrubbing(); onTouchMove(event); }; const onTouchMove = (event) => { if (event.cancelable) { event.preventDefault(); } onScrub({ x: event.changedTouches[0].clientX, y: event.changedTouches[0].clientY }); }; node?.addEventListener("mousedown", onMouseDown); node?.addEventListener("touchstart", onTouchStart, { passive: fals