@zayne-labs/toolkit-react 0.12.2 → 0.12.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- import * as react0 from "react";
1
+ import * as react1 from "react";
2
2
 
3
3
  //#region src/hooks/useClickOutside.d.ts
4
4
  type UseClickOutsideOptions<TElement extends HTMLElement> = {
@@ -7,7 +7,7 @@ type UseClickOutsideOptions<TElement extends HTMLElement> = {
7
7
  ref?: Array<React.RefObject<TElement>> | React.RefObject<TElement>;
8
8
  };
9
9
  declare const useClickOutside: <TElement extends HTMLElement>(options: UseClickOutsideOptions<TElement>) => {
10
- ref: react0.RefObject<TElement | null>;
10
+ ref: react1.RefObject<TElement | null>;
11
11
  };
12
12
  //#endregion
13
13
  export { useClickOutside };
@@ -9,8 +9,7 @@ const useClickOutside = (options) => {
9
9
  const savedOnClick = useCallbackRef(onClick);
10
10
  useEffect(() => {
11
11
  if (!enabled) return;
12
- const elementArray = toArray(refOrRefArray).map((ref) => ref.current);
13
- const cleanup = onClickOutside(elementArray, savedOnClick);
12
+ const cleanup = onClickOutside(toArray(refOrRefArray).map((ref) => ref.current), savedOnClick);
14
13
  return () => cleanup();
15
14
  }, [
16
15
  enabled,
@@ -1 +1 @@
1
- {"version":3,"file":"useClickOutside.js","names":[],"sources":["../../../src/hooks/useClickOutside.ts"],"sourcesContent":["import { onClickOutside, toArray } from \"@zayne-labs/toolkit-core\";\nimport { useEffect, useRef } from \"react\";\nimport { useCallbackRef } from \"./useCallbackRef\";\n\ntype UseClickOutsideOptions<TElement extends HTMLElement> = {\n\tenabled?: boolean;\n\tonClick: (event: MouseEvent | TouchEvent) => void;\n\tref?: Array<React.RefObject<TElement>> | React.RefObject<TElement>;\n};\n\nconst useClickOutside = <TElement extends HTMLElement>(options: UseClickOutsideOptions<TElement>) => {\n\tconst innerRef = useRef<TElement>(null);\n\n\tconst { enabled = true, onClick, ref: refOrRefArray = innerRef } = options;\n\n\tconst savedOnClick = useCallbackRef(onClick);\n\n\tuseEffect(() => {\n\t\tif (!enabled) return;\n\n\t\tconst elementArray = toArray(refOrRefArray).map((ref) => ref.current);\n\n\t\tconst cleanup = onClickOutside(elementArray, savedOnClick);\n\n\t\treturn () => cleanup();\n\t}, [enabled, refOrRefArray, savedOnClick]);\n\n\treturn {\n\t\tref: innerRef,\n\t};\n};\n\nexport { useClickOutside };\n"],"mappings":";;;;;AAUA,MAAM,mBAAiD,YAA8C;CACpG,MAAM,WAAW,OAAiB,KAAK;CAEvC,MAAM,EAAE,UAAU,MAAM,SAAS,KAAK,gBAAgB,aAAa;CAEnE,MAAM,eAAe,eAAe,QAAQ;AAE5C,iBAAgB;AACf,MAAI,CAAC,QAAS;EAEd,MAAM,eAAe,QAAQ,cAAc,CAAC,KAAK,QAAQ,IAAI,QAAQ;EAErE,MAAM,UAAU,eAAe,cAAc,aAAa;AAE1D,eAAa,SAAS;IACpB;EAAC;EAAS;EAAe;EAAa,CAAC;AAE1C,QAAO,EACN,KAAK,UACL"}
1
+ {"version":3,"file":"useClickOutside.js","names":[],"sources":["../../../src/hooks/useClickOutside.ts"],"sourcesContent":["import { onClickOutside, toArray } from \"@zayne-labs/toolkit-core\";\nimport { useEffect, useRef } from \"react\";\nimport { useCallbackRef } from \"./useCallbackRef\";\n\ntype UseClickOutsideOptions<TElement extends HTMLElement> = {\n\tenabled?: boolean;\n\tonClick: (event: MouseEvent | TouchEvent) => void;\n\tref?: Array<React.RefObject<TElement>> | React.RefObject<TElement>;\n};\n\nconst useClickOutside = <TElement extends HTMLElement>(options: UseClickOutsideOptions<TElement>) => {\n\tconst innerRef = useRef<TElement>(null);\n\n\tconst { enabled = true, onClick, ref: refOrRefArray = innerRef } = options;\n\n\tconst savedOnClick = useCallbackRef(onClick);\n\n\tuseEffect(() => {\n\t\tif (!enabled) return;\n\n\t\tconst elementArray = toArray(refOrRefArray).map((ref) => ref.current);\n\n\t\tconst cleanup = onClickOutside(elementArray, savedOnClick);\n\n\t\treturn () => cleanup();\n\t}, [enabled, refOrRefArray, savedOnClick]);\n\n\treturn {\n\t\tref: innerRef,\n\t};\n};\n\nexport { useClickOutside };\n"],"mappings":";;;;;AAUA,MAAM,mBAAiD,YAA8C;CACpG,MAAM,WAAW,OAAiB,KAAK;CAEvC,MAAM,EAAE,UAAU,MAAM,SAAS,KAAK,gBAAgB,aAAa;CAEnE,MAAM,eAAe,eAAe,QAAQ;AAE5C,iBAAgB;AACf,MAAI,CAAC,QAAS;EAId,MAAM,UAAU,eAFK,QAAQ,cAAc,CAAC,KAAK,QAAQ,IAAI,QAAQ,EAExB,aAAa;AAE1D,eAAa,SAAS;IACpB;EAAC;EAAS;EAAe;EAAa,CAAC;AAE1C,QAAO,EACN,KAAK,UACL"}
@@ -1,8 +1,8 @@
1
1
  import { PossibleRef } from "../utils/composeRefs.js";
2
- import * as react1 from "react";
2
+ import * as react0 from "react";
3
3
 
4
4
  //#region src/hooks/useComposeRefs.d.ts
5
- declare const useComposeRefs: <TRef extends HTMLElement>(...refs: Array<PossibleRef<TRef>>) => react1.RefCallback<TRef>;
5
+ declare const useComposeRefs: <TRef extends HTMLElement>(...refs: Array<PossibleRef<TRef>>) => react0.RefCallback<TRef>;
6
6
  //#endregion
7
7
  export { useComposeRefs };
8
8
  //# sourceMappingURL=useComposeRefs.d.ts.map
@@ -56,7 +56,7 @@ const useControllableState = (options) => {
56
56
  const [unControlledState, setUncontrolledState] = useState(defaultValue);
57
57
  const isControlled = valueProp !== void 0;
58
58
  const currentValue = isControlled ? valueProp : unControlledState;
59
- const setValue = useCallback((newValue) => {
59
+ return [currentValue, useCallback((newValue) => {
60
60
  const nextValue = isFunction(newValue) ? newValue(currentValue) : newValue;
61
61
  if (stableEqualityFn(currentValue, nextValue)) return;
62
62
  stableOnchangeProp(nextValue);
@@ -67,8 +67,7 @@ const useControllableState = (options) => {
67
67
  stableOnchangeProp,
68
68
  stableEqualityFn,
69
69
  currentValue
70
- ]);
71
- return [currentValue, setValue];
70
+ ])];
72
71
  };
73
72
 
74
73
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"useControllable.js","names":["setValue: StateSetter<TValue>"],"sources":["../../../src/hooks/useControllable.ts"],"sourcesContent":["\"use client\";\n\nimport { isFunction } from \"@zayne-labs/toolkit-type-helpers\";\nimport { useCallback, useMemo, useState } from \"react\";\nimport type { StateSetter } from \"@/utils\";\nimport { useCallbackRef } from \"./useCallbackRef\";\n\ntype UseControllablePropOptions<TProp> = {\n\tprop: TProp | undefined;\n\tstate: TProp;\n};\n\n/**\n * @description Given a prop value and state value, the useControllableProp hook is used to determine whether a component is controlled or uncontrolled, and also returns the computed value.\n */\nexport const useControllableProp = <TProp>(options: UseControllablePropOptions<TProp>) => {\n\tconst { prop, state } = options;\n\n\tconst isControlled = prop !== undefined;\n\n\tconst value = isControlled ? prop : state;\n\n\tconst result = useMemo<[isControlled: typeof isControlled, value: typeof value]>(\n\t\t() => [isControlled, value],\n\t\t[isControlled, value]\n\t);\n\n\treturn result;\n};\n\ntype UseControllableStateOptions<TValue> = {\n\tdefaultValue?: TValue | (() => TValue);\n\tequalityFn?: (prevState: TValue, nextValue: TValue) => boolean;\n\tonChange?: (value: TValue) => void;\n\tvalue?: TValue;\n};\n\n/**\n * @description React hook to manage state that can be either controlled or uncontrolled.\n * - When `options.value` is provided, the hook operates in controlled mode.\n * In this mode, `value` always equals `options.value` and `setValue` will\n * invoke `options.onChange(next)` without mutating internal state.\n * - When `options.value` is not provided, the hook operates in uncontrolled\n * mode, initializing internal state from `options.defaultValue` and updating\n * it via `setValue`.\n * - All updates are gated by `options.equalityFn(prev, next)` which defaults\n * to `Object.is`.\n *\n * @param options - Configuration options for the hook.\n * @param options.value - Controlled value. If defined, the state is controlled.\n * @param options.defaultValue - Initial value for the uncontrolled state. Can be a\n * function for lazy initialization or a direct value.\n * @param options.onChange - Callback fired when a new value is requested. In\n * controlled mode, this is invoked instead of updating internal state. In\n * uncontrolled mode, it is called after the internal state updates.\n * @param options.equalityFn - Predicate that decides whether to commit an\n * update given `prevState` and `nextValue`. If the values are equal, the update\n * is skipped. Defaults to `Object.is`.\n * @returns A tuple `[value, setValue]` just like React.useState.\n *\n * @example\n * // Uncontrolled usage\n * const [value, setValue] = useControllableState({ defaultValue: 0 });\n *\n * @example\n * // Controlled usage\n * const [value, setValue] = useControllableState({\n * value: props.value,\n * onChange: props.onChange,\n * });\n */\nexport const useControllableState = <TValue>(options: UseControllableStateOptions<TValue>) => {\n\tconst { defaultValue, equalityFn = Object.is, onChange: onChangeProp, value: valueProp } = options;\n\n\tconst stableOnchangeProp = useCallbackRef(onChangeProp);\n\tconst stableEqualityFn = useCallbackRef(equalityFn);\n\n\tconst [unControlledState, setUncontrolledState] = useState(defaultValue as TValue);\n\n\tconst isControlled = valueProp !== undefined;\n\n\tconst currentValue = isControlled ? valueProp : unControlledState;\n\n\tconst setValue: StateSetter<TValue> = useCallback(\n\t\t(newValue) => {\n\t\t\tconst nextValue = isFunction(newValue) ? newValue(currentValue) : newValue;\n\n\t\t\tif (stableEqualityFn(currentValue, nextValue)) return;\n\n\t\t\t// == Always call onChangeProp whether the value is controlled or uncontrolled,\n\t\t\t// == just in case the onChangeProp is used to perform side effects\n\t\t\t// == without necessarily updating the controlled valueProp\n\t\t\tstableOnchangeProp(nextValue);\n\n\t\t\tif (isControlled) return;\n\n\t\t\tsetUncontrolledState(nextValue);\n\t\t},\n\t\t[isControlled, stableOnchangeProp, stableEqualityFn, currentValue]\n\t);\n\n\treturn [currentValue, setValue] as [value: typeof currentValue, setValue: typeof setValue];\n};\n"],"mappings":";;;;;;;;;;;AAeA,MAAa,uBAA8B,YAA+C;CACzF,MAAM,EAAE,MAAM,UAAU;CAExB,MAAM,eAAe,SAAS;CAE9B,MAAM,QAAQ,eAAe,OAAO;AAOpC,QALe,cACR,CAAC,cAAc,MAAM,EAC3B,CAAC,cAAc,MAAM,CACrB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8CF,MAAa,wBAAgC,YAAiD;CAC7F,MAAM,EAAE,cAAc,aAAa,OAAO,IAAI,UAAU,cAAc,OAAO,cAAc;CAE3F,MAAM,qBAAqB,eAAe,aAAa;CACvD,MAAM,mBAAmB,eAAe,WAAW;CAEnD,MAAM,CAAC,mBAAmB,wBAAwB,SAAS,aAAuB;CAElF,MAAM,eAAe,cAAc;CAEnC,MAAM,eAAe,eAAe,YAAY;CAEhD,MAAMA,WAAgC,aACpC,aAAa;EACb,MAAM,YAAY,WAAW,SAAS,GAAG,SAAS,aAAa,GAAG;AAElE,MAAI,iBAAiB,cAAc,UAAU,CAAE;AAK/C,qBAAmB,UAAU;AAE7B,MAAI,aAAc;AAElB,uBAAqB,UAAU;IAEhC;EAAC;EAAc;EAAoB;EAAkB;EAAa,CAClE;AAED,QAAO,CAAC,cAAc,SAAS"}
1
+ {"version":3,"file":"useControllable.js","names":[],"sources":["../../../src/hooks/useControllable.ts"],"sourcesContent":["\"use client\";\n\nimport { isFunction } from \"@zayne-labs/toolkit-type-helpers\";\nimport { useCallback, useMemo, useState } from \"react\";\nimport type { StateSetter } from \"@/utils\";\nimport { useCallbackRef } from \"./useCallbackRef\";\n\ntype UseControllablePropOptions<TProp> = {\n\tprop: TProp | undefined;\n\tstate: TProp;\n};\n\n/**\n * @description Given a prop value and state value, the useControllableProp hook is used to determine whether a component is controlled or uncontrolled, and also returns the computed value.\n */\nexport const useControllableProp = <TProp>(options: UseControllablePropOptions<TProp>) => {\n\tconst { prop, state } = options;\n\n\tconst isControlled = prop !== undefined;\n\n\tconst value = isControlled ? prop : state;\n\n\tconst result = useMemo<[isControlled: typeof isControlled, value: typeof value]>(\n\t\t() => [isControlled, value],\n\t\t[isControlled, value]\n\t);\n\n\treturn result;\n};\n\ntype UseControllableStateOptions<TValue> = {\n\tdefaultValue?: TValue | (() => TValue);\n\tequalityFn?: (prevState: TValue, nextValue: TValue) => boolean;\n\tonChange?: (value: TValue) => void;\n\tvalue?: TValue;\n};\n\n/**\n * @description React hook to manage state that can be either controlled or uncontrolled.\n * - When `options.value` is provided, the hook operates in controlled mode.\n * In this mode, `value` always equals `options.value` and `setValue` will\n * invoke `options.onChange(next)` without mutating internal state.\n * - When `options.value` is not provided, the hook operates in uncontrolled\n * mode, initializing internal state from `options.defaultValue` and updating\n * it via `setValue`.\n * - All updates are gated by `options.equalityFn(prev, next)` which defaults\n * to `Object.is`.\n *\n * @param options - Configuration options for the hook.\n * @param options.value - Controlled value. If defined, the state is controlled.\n * @param options.defaultValue - Initial value for the uncontrolled state. Can be a\n * function for lazy initialization or a direct value.\n * @param options.onChange - Callback fired when a new value is requested. In\n * controlled mode, this is invoked instead of updating internal state. In\n * uncontrolled mode, it is called after the internal state updates.\n * @param options.equalityFn - Predicate that decides whether to commit an\n * update given `prevState` and `nextValue`. If the values are equal, the update\n * is skipped. Defaults to `Object.is`.\n * @returns A tuple `[value, setValue]` just like React.useState.\n *\n * @example\n * // Uncontrolled usage\n * const [value, setValue] = useControllableState({ defaultValue: 0 });\n *\n * @example\n * // Controlled usage\n * const [value, setValue] = useControllableState({\n * value: props.value,\n * onChange: props.onChange,\n * });\n */\nexport const useControllableState = <TValue>(options: UseControllableStateOptions<TValue>) => {\n\tconst { defaultValue, equalityFn = Object.is, onChange: onChangeProp, value: valueProp } = options;\n\n\tconst stableOnchangeProp = useCallbackRef(onChangeProp);\n\tconst stableEqualityFn = useCallbackRef(equalityFn);\n\n\tconst [unControlledState, setUncontrolledState] = useState(defaultValue as TValue);\n\n\tconst isControlled = valueProp !== undefined;\n\n\tconst currentValue = isControlled ? valueProp : unControlledState;\n\n\tconst setValue: StateSetter<TValue> = useCallback(\n\t\t(newValue) => {\n\t\t\tconst nextValue = isFunction(newValue) ? newValue(currentValue) : newValue;\n\n\t\t\tif (stableEqualityFn(currentValue, nextValue)) return;\n\n\t\t\t// == Always call onChangeProp whether the value is controlled or uncontrolled,\n\t\t\t// == just in case the onChangeProp is used to perform side effects\n\t\t\t// == without necessarily updating the controlled valueProp\n\t\t\tstableOnchangeProp(nextValue);\n\n\t\t\tif (isControlled) return;\n\n\t\t\tsetUncontrolledState(nextValue);\n\t\t},\n\t\t[isControlled, stableOnchangeProp, stableEqualityFn, currentValue]\n\t);\n\n\treturn [currentValue, setValue] as [value: typeof currentValue, setValue: typeof setValue];\n};\n"],"mappings":";;;;;;;;;;;AAeA,MAAa,uBAA8B,YAA+C;CACzF,MAAM,EAAE,MAAM,UAAU;CAExB,MAAM,eAAe,SAAS;CAE9B,MAAM,QAAQ,eAAe,OAAO;AAOpC,QALe,cACR,CAAC,cAAc,MAAM,EAC3B,CAAC,cAAc,MAAM,CACrB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8CF,MAAa,wBAAgC,YAAiD;CAC7F,MAAM,EAAE,cAAc,aAAa,OAAO,IAAI,UAAU,cAAc,OAAO,cAAc;CAE3F,MAAM,qBAAqB,eAAe,aAAa;CACvD,MAAM,mBAAmB,eAAe,WAAW;CAEnD,MAAM,CAAC,mBAAmB,wBAAwB,SAAS,aAAuB;CAElF,MAAM,eAAe,cAAc;CAEnC,MAAM,eAAe,eAAe,YAAY;AAoBhD,QAAO,CAAC,cAlB8B,aACpC,aAAa;EACb,MAAM,YAAY,WAAW,SAAS,GAAG,SAAS,aAAa,GAAG;AAElE,MAAI,iBAAiB,cAAc,UAAU,CAAE;AAK/C,qBAAmB,UAAU;AAE7B,MAAI,aAAc;AAElB,uBAAqB,UAAU;IAEhC;EAAC;EAAc;EAAoB;EAAkB;EAAa,CAClE,CAE8B"}
@@ -1,4 +1,4 @@
1
- import * as react4 from "react";
1
+ import * as react7 from "react";
2
2
  import { AllowedClipboardItems, CopyToClipboardOptions } from "@zayne-labs/toolkit-core";
3
3
 
4
4
  //#region src/hooks/useCopyToClipboard.d.ts
@@ -7,7 +7,7 @@ declare const useCopyToClipboard: (options?: CopyToClipboardOptions & {
7
7
  }) => {
8
8
  handleCopy: (valueToCopy: AllowedClipboardItems) => void;
9
9
  hasCopied: boolean;
10
- setValue: react4.Dispatch<react4.SetStateAction<AllowedClipboardItems>>;
10
+ setValue: react7.Dispatch<react7.SetStateAction<AllowedClipboardItems>>;
11
11
  value: AllowedClipboardItems;
12
12
  };
13
13
  //#endregion
@@ -1,4 +1,4 @@
1
- import * as react6 from "react";
1
+ import * as react2 from "react";
2
2
  import { CallbackFn } from "@zayne-labs/toolkit-type-helpers";
3
3
 
4
4
  //#region src/hooks/useDebounce.d.ts
@@ -11,13 +11,13 @@ declare const useDebouncedFn: <TParams>(callBackFn: CallbackFn<TParams>, delay:
11
11
  cancelMaxWait(): void;
12
12
  };
13
13
  declare const useDebouncedState: <TValue>(defaultValue: TValue, delay: number | undefined) => readonly [TValue, {
14
- (...params: react6.SetStateAction<TValue>[]): void;
15
- (params: react6.SetStateAction<TValue> | react6.SetStateAction<TValue>[], overrideOptions: {
14
+ (...params: react2.SetStateAction<TValue>[]): void;
15
+ (params: react2.SetStateAction<TValue> | react2.SetStateAction<TValue>[], overrideOptions: {
16
16
  $delay: number;
17
17
  }): void;
18
18
  cancel: () => void;
19
19
  cancelMaxWait(): void;
20
- }, react6.Dispatch<react6.SetStateAction<TValue>>];
20
+ }, react2.Dispatch<react2.SetStateAction<TValue>>];
21
21
  //#endregion
22
22
  export { useDebouncedFn, useDebouncedState };
23
23
  //# sourceMappingURL=useDebounce.d.ts.map
@@ -1,16 +1,16 @@
1
- import * as _zayne_labs_toolkit_core1 from "@zayne-labs/toolkit-core";
1
+ import * as _zayne_labs_toolkit_core0 from "@zayne-labs/toolkit-core";
2
2
  import { LocationInfo, LocationStoreApi, LocationStoreOptions } from "@zayne-labs/toolkit-core";
3
3
  import { SelectorFn } from "@zayne-labs/toolkit-type-helpers";
4
4
 
5
5
  //#region src/hooks/useLocationState.d.ts
6
6
  type UseLocationResult<TSlice> = [state: TSlice, actions: LocationStoreApi];
7
- declare const createUseLocationState: (options?: LocationStoreOptions) => Omit<_zayne_labs_toolkit_core1.StoreApi<_zayne_labs_toolkit_core1.URLInfoObject>, "resetState" | "setState"> & {
8
- push: (url: string | _zayne_labs_toolkit_core1.PartialURLInfo, options?: {
9
- state?: _zayne_labs_toolkit_core1.PartialURLInfo["state"];
7
+ declare const createUseLocationState: (options?: LocationStoreOptions) => Omit<_zayne_labs_toolkit_core0.StoreApi<_zayne_labs_toolkit_core0.URLInfoObject>, "resetState" | "setState"> & {
8
+ push: (url: string | _zayne_labs_toolkit_core0.PartialURLInfo, options?: {
9
+ state?: _zayne_labs_toolkit_core0.PartialURLInfo["state"];
10
10
  }) => void;
11
11
  replace: LocationStoreApi["push"];
12
12
  triggerPopstateEvent: (nextLocationState?: LocationInfo["state"]) => void;
13
- } & (<TSlice = _zayne_labs_toolkit_core1.URLInfoObject>(selector?: SelectorFn<LocationInfo, TSlice>) => UseLocationResult<TSlice>);
13
+ } & (<TSlice = _zayne_labs_toolkit_core0.URLInfoObject>(selector?: SelectorFn<LocationInfo, TSlice>) => UseLocationResult<TSlice>);
14
14
  declare const useLocationState: <TSlice = LocationInfo>(selector?: SelectorFn<LocationInfo, TSlice>, options?: LocationStoreOptions) => UseLocationResult<TSlice>;
15
15
  //#endregion
16
16
  export { createUseLocationState, useLocationState };
@@ -25,17 +25,16 @@ const useScrollObserver = (options = {}) => {
25
25
  savedOnIntersection,
26
26
  threshold
27
27
  ]);
28
- const observedElementRef = useCallbackRef((element) => {
29
- const cleanupFn = handleObservation(element);
30
- if (!element) {
31
- cleanupFn?.();
32
- return;
33
- }
34
- return cleanupFn;
35
- });
36
28
  return {
37
29
  isScrolled,
38
- observedElementRef
30
+ observedElementRef: useCallbackRef((element) => {
31
+ const cleanupFn = handleObservation(element);
32
+ if (!element) {
33
+ cleanupFn?.();
34
+ return;
35
+ }
36
+ return cleanupFn;
37
+ })
39
38
  };
40
39
  };
41
40
 
@@ -1 +1 @@
1
- {"version":3,"file":"useScrollObserver.js","names":["observedElementRef: RefCallback<TElement>"],"sources":["../../../src/hooks/useScrollObserver.ts"],"sourcesContent":["import { createScrollObserver, type ScrollObserverOptions } from \"@zayne-labs/toolkit-core\";\nimport { type RefCallback, useMemo, useState } from \"react\";\nimport { useCallbackRef } from \"./useCallbackRef\";\n\nconst useScrollObserver = <TElement extends HTMLElement>(options: ScrollObserverOptions = {}) => {\n\tconst { onIntersection, root, rootMargin = \"10px 0px 0px 0px\", threshold } = options;\n\n\tconst [isScrolled, setIsScrolled] = useState(false);\n\n\tconst savedOnIntersection = useCallbackRef(onIntersection);\n\n\tconst { handleObservation } = useMemo(() => {\n\t\treturn createScrollObserver({\n\t\t\tonIntersection: (entry, observer) => {\n\t\t\t\tconst newIsScrolledState = !entry.isIntersecting;\n\n\t\t\t\tsetIsScrolled(newIsScrolledState);\n\n\t\t\t\t// eslint-disable-next-line no-param-reassign -- Mutation is fine here\n\t\t\t\t(entry.target as HTMLElement).dataset.scrolled = String(newIsScrolledState);\n\n\t\t\t\tsavedOnIntersection(entry, observer);\n\t\t\t},\n\t\t\troot,\n\t\t\trootMargin,\n\t\t\tthreshold,\n\t\t});\n\t}, [root, rootMargin, savedOnIntersection, threshold]);\n\n\tconst observedElementRef: RefCallback<TElement> = useCallbackRef((element) => {\n\t\tconst cleanupFn = handleObservation(element);\n\n\t\t// == React 18 may not call the cleanup function so we need to call it manually on element unmount\n\t\tif (!element) {\n\t\t\tcleanupFn?.();\n\t\t\treturn;\n\t\t}\n\n\t\treturn cleanupFn;\n\t});\n\n\treturn { isScrolled, observedElementRef };\n};\n\nexport { useScrollObserver };\n"],"mappings":";;;;;AAIA,MAAM,qBAAmD,UAAiC,EAAE,KAAK;CAChG,MAAM,EAAE,gBAAgB,MAAM,aAAa,oBAAoB,cAAc;CAE7E,MAAM,CAAC,YAAY,iBAAiB,SAAS,MAAM;CAEnD,MAAM,sBAAsB,eAAe,eAAe;CAE1D,MAAM,EAAE,sBAAsB,cAAc;AAC3C,SAAO,qBAAqB;GAC3B,iBAAiB,OAAO,aAAa;IACpC,MAAM,qBAAqB,CAAC,MAAM;AAElC,kBAAc,mBAAmB;AAGjC,IAAC,MAAM,OAAuB,QAAQ,WAAW,OAAO,mBAAmB;AAE3E,wBAAoB,OAAO,SAAS;;GAErC;GACA;GACA;GACA,CAAC;IACA;EAAC;EAAM;EAAY;EAAqB;EAAU,CAAC;CAEtD,MAAMA,qBAA4C,gBAAgB,YAAY;EAC7E,MAAM,YAAY,kBAAkB,QAAQ;AAG5C,MAAI,CAAC,SAAS;AACb,gBAAa;AACb;;AAGD,SAAO;GACN;AAEF,QAAO;EAAE;EAAY;EAAoB"}
1
+ {"version":3,"file":"useScrollObserver.js","names":[],"sources":["../../../src/hooks/useScrollObserver.ts"],"sourcesContent":["import { createScrollObserver, type ScrollObserverOptions } from \"@zayne-labs/toolkit-core\";\nimport { type RefCallback, useMemo, useState } from \"react\";\nimport { useCallbackRef } from \"./useCallbackRef\";\n\nconst useScrollObserver = <TElement extends HTMLElement>(options: ScrollObserverOptions = {}) => {\n\tconst { onIntersection, root, rootMargin = \"10px 0px 0px 0px\", threshold } = options;\n\n\tconst [isScrolled, setIsScrolled] = useState(false);\n\n\tconst savedOnIntersection = useCallbackRef(onIntersection);\n\n\tconst { handleObservation } = useMemo(() => {\n\t\treturn createScrollObserver({\n\t\t\tonIntersection: (entry, observer) => {\n\t\t\t\tconst newIsScrolledState = !entry.isIntersecting;\n\n\t\t\t\tsetIsScrolled(newIsScrolledState);\n\n\t\t\t\t// eslint-disable-next-line no-param-reassign -- Mutation is fine here\n\t\t\t\t(entry.target as HTMLElement).dataset.scrolled = String(newIsScrolledState);\n\n\t\t\t\tsavedOnIntersection(entry, observer);\n\t\t\t},\n\t\t\troot,\n\t\t\trootMargin,\n\t\t\tthreshold,\n\t\t});\n\t}, [root, rootMargin, savedOnIntersection, threshold]);\n\n\tconst observedElementRef: RefCallback<TElement> = useCallbackRef((element) => {\n\t\tconst cleanupFn = handleObservation(element);\n\n\t\t// == React 18 may not call the cleanup function so we need to call it manually on element unmount\n\t\tif (!element) {\n\t\t\tcleanupFn?.();\n\t\t\treturn;\n\t\t}\n\n\t\treturn cleanupFn;\n\t});\n\n\treturn { isScrolled, observedElementRef };\n};\n\nexport { useScrollObserver };\n"],"mappings":";;;;;AAIA,MAAM,qBAAmD,UAAiC,EAAE,KAAK;CAChG,MAAM,EAAE,gBAAgB,MAAM,aAAa,oBAAoB,cAAc;CAE7E,MAAM,CAAC,YAAY,iBAAiB,SAAS,MAAM;CAEnD,MAAM,sBAAsB,eAAe,eAAe;CAE1D,MAAM,EAAE,sBAAsB,cAAc;AAC3C,SAAO,qBAAqB;GAC3B,iBAAiB,OAAO,aAAa;IACpC,MAAM,qBAAqB,CAAC,MAAM;AAElC,kBAAc,mBAAmB;AAGjC,IAAC,MAAM,OAAuB,QAAQ,WAAW,OAAO,mBAAmB;AAE3E,wBAAoB,OAAO,SAAS;;GAErC;GACA;GACA;GACA,CAAC;IACA;EAAC;EAAM;EAAY;EAAqB;EAAU,CAAC;AActD,QAAO;EAAE;EAAY,oBAZ6B,gBAAgB,YAAY;GAC7E,MAAM,YAAY,kBAAkB,QAAQ;AAG5C,OAAI,CAAC,SAAS;AACb,iBAAa;AACb;;AAGD,UAAO;IACN;EAEuC"}
@@ -1,11 +1,11 @@
1
- import * as react2 from "react";
1
+ import * as react9 from "react";
2
2
 
3
3
  //#region src/hooks/useSearch.d.ts
4
4
  declare const useSearch: <TData>(initialData: TData[], delay?: number) => {
5
5
  data: TData[];
6
6
  isLoading: boolean;
7
7
  query: string;
8
- setQuery: react2.Dispatch<react2.SetStateAction<string>>;
8
+ setQuery: react9.Dispatch<react9.SetStateAction<string>>;
9
9
  };
10
10
  //#endregion
11
11
  export { useSearch };
@@ -15,12 +15,11 @@ const useSearch = (initialData, delay) => {
15
15
  const [isLoading, setIsLoading] = useState(false);
16
16
  const handleDebouncedSearch = useDebouncedFn(() => {
17
17
  const query = searchQuery.toLowerCase();
18
- const filteredResults = initialData.filter((item) => {
18
+ setFilteredData(initialData.filter((item) => {
19
19
  if (isSerializable(item)) return item.toString().toLowerCase().includes(query);
20
20
  if (isPlainObject(item)) return checkObjectPropsForQuery(item, query);
21
21
  return false;
22
- });
23
- setFilteredData(filteredResults);
22
+ }));
24
23
  setIsLoading(false);
25
24
  }, delay);
26
25
  useAfterMountEffect(() => {
@@ -1 +1 @@
1
- {"version":3,"file":"useSearch.js","names":[],"sources":["../../../src/hooks/useSearch.ts"],"sourcesContent":["import { isPlainObject } from \"@zayne-labs/toolkit-type-helpers\";\nimport { useState } from \"react\";\nimport { useAfterMountEffect } from \"./effects/useAfterMountEffect\";\nimport { useDebouncedFn } from \"./useDebounce\";\n\nconst isSerializable = (item: unknown): item is boolean | number | string =>\n\ttypeof item === \"string\" || typeof item === \"number\" || typeof item === \"boolean\";\n\nconst checkObjectPropsForQuery = (item: Record<string, unknown>, query: string): boolean => {\n\tfor (const value of Object.values(item)) {\n\t\tif (isSerializable(value) && value.toString().toLowerCase().includes(query)) {\n\t\t\treturn true;\n\t\t}\n\t}\n\treturn false;\n};\n\nconst useSearch = <TData>(initialData: TData[], delay?: number) => {\n\tconst [searchQuery, setSearchQuery] = useState(\"\");\n\tconst [filteredData, setFilteredData] = useState(initialData);\n\tconst [isLoading, setIsLoading] = useState(false);\n\n\tconst handleDebouncedSearch = useDebouncedFn(() => {\n\t\tconst query = searchQuery.toLowerCase();\n\n\t\tconst filteredResults = initialData.filter((item) => {\n\t\t\tif (isSerializable(item)) {\n\t\t\t\treturn item.toString().toLowerCase().includes(query);\n\t\t\t}\n\n\t\t\tif (isPlainObject(item)) {\n\t\t\t\treturn checkObjectPropsForQuery(item, query);\n\t\t\t}\n\n\t\t\treturn false;\n\t\t});\n\n\t\tsetFilteredData(filteredResults);\n\t\tsetIsLoading(false);\n\t}, delay);\n\n\tuseAfterMountEffect(() => {\n\t\tsetIsLoading(true);\n\t\thandleDebouncedSearch();\n\t}, [searchQuery]);\n\n\treturn { data: filteredData, isLoading, query: searchQuery, setQuery: setSearchQuery };\n};\n\nexport { useSearch };\n"],"mappings":";;;;;;AAKA,MAAM,kBAAkB,SACvB,OAAO,SAAS,YAAY,OAAO,SAAS,YAAY,OAAO,SAAS;AAEzE,MAAM,4BAA4B,MAA+B,UAA2B;AAC3F,MAAK,MAAM,SAAS,OAAO,OAAO,KAAK,CACtC,KAAI,eAAe,MAAM,IAAI,MAAM,UAAU,CAAC,aAAa,CAAC,SAAS,MAAM,CAC1E,QAAO;AAGT,QAAO;;AAGR,MAAM,aAAoB,aAAsB,UAAmB;CAClE,MAAM,CAAC,aAAa,kBAAkB,SAAS,GAAG;CAClD,MAAM,CAAC,cAAc,mBAAmB,SAAS,YAAY;CAC7D,MAAM,CAAC,WAAW,gBAAgB,SAAS,MAAM;CAEjD,MAAM,wBAAwB,qBAAqB;EAClD,MAAM,QAAQ,YAAY,aAAa;EAEvC,MAAM,kBAAkB,YAAY,QAAQ,SAAS;AACpD,OAAI,eAAe,KAAK,CACvB,QAAO,KAAK,UAAU,CAAC,aAAa,CAAC,SAAS,MAAM;AAGrD,OAAI,cAAc,KAAK,CACtB,QAAO,yBAAyB,MAAM,MAAM;AAG7C,UAAO;IACN;AAEF,kBAAgB,gBAAgB;AAChC,eAAa,MAAM;IACjB,MAAM;AAET,2BAA0B;AACzB,eAAa,KAAK;AAClB,yBAAuB;IACrB,CAAC,YAAY,CAAC;AAEjB,QAAO;EAAE,MAAM;EAAc;EAAW,OAAO;EAAa,UAAU;EAAgB"}
1
+ {"version":3,"file":"useSearch.js","names":[],"sources":["../../../src/hooks/useSearch.ts"],"sourcesContent":["import { isPlainObject } from \"@zayne-labs/toolkit-type-helpers\";\nimport { useState } from \"react\";\nimport { useAfterMountEffect } from \"./effects/useAfterMountEffect\";\nimport { useDebouncedFn } from \"./useDebounce\";\n\nconst isSerializable = (item: unknown): item is boolean | number | string =>\n\ttypeof item === \"string\" || typeof item === \"number\" || typeof item === \"boolean\";\n\nconst checkObjectPropsForQuery = (item: Record<string, unknown>, query: string): boolean => {\n\tfor (const value of Object.values(item)) {\n\t\tif (isSerializable(value) && value.toString().toLowerCase().includes(query)) {\n\t\t\treturn true;\n\t\t}\n\t}\n\treturn false;\n};\n\nconst useSearch = <TData>(initialData: TData[], delay?: number) => {\n\tconst [searchQuery, setSearchQuery] = useState(\"\");\n\tconst [filteredData, setFilteredData] = useState(initialData);\n\tconst [isLoading, setIsLoading] = useState(false);\n\n\tconst handleDebouncedSearch = useDebouncedFn(() => {\n\t\tconst query = searchQuery.toLowerCase();\n\n\t\tconst filteredResults = initialData.filter((item) => {\n\t\t\tif (isSerializable(item)) {\n\t\t\t\treturn item.toString().toLowerCase().includes(query);\n\t\t\t}\n\n\t\t\tif (isPlainObject(item)) {\n\t\t\t\treturn checkObjectPropsForQuery(item, query);\n\t\t\t}\n\n\t\t\treturn false;\n\t\t});\n\n\t\tsetFilteredData(filteredResults);\n\t\tsetIsLoading(false);\n\t}, delay);\n\n\tuseAfterMountEffect(() => {\n\t\tsetIsLoading(true);\n\t\thandleDebouncedSearch();\n\t}, [searchQuery]);\n\n\treturn { data: filteredData, isLoading, query: searchQuery, setQuery: setSearchQuery };\n};\n\nexport { useSearch };\n"],"mappings":";;;;;;AAKA,MAAM,kBAAkB,SACvB,OAAO,SAAS,YAAY,OAAO,SAAS,YAAY,OAAO,SAAS;AAEzE,MAAM,4BAA4B,MAA+B,UAA2B;AAC3F,MAAK,MAAM,SAAS,OAAO,OAAO,KAAK,CACtC,KAAI,eAAe,MAAM,IAAI,MAAM,UAAU,CAAC,aAAa,CAAC,SAAS,MAAM,CAC1E,QAAO;AAGT,QAAO;;AAGR,MAAM,aAAoB,aAAsB,UAAmB;CAClE,MAAM,CAAC,aAAa,kBAAkB,SAAS,GAAG;CAClD,MAAM,CAAC,cAAc,mBAAmB,SAAS,YAAY;CAC7D,MAAM,CAAC,WAAW,gBAAgB,SAAS,MAAM;CAEjD,MAAM,wBAAwB,qBAAqB;EAClD,MAAM,QAAQ,YAAY,aAAa;AAcvC,kBAZwB,YAAY,QAAQ,SAAS;AACpD,OAAI,eAAe,KAAK,CACvB,QAAO,KAAK,UAAU,CAAC,aAAa,CAAC,SAAS,MAAM;AAGrD,OAAI,cAAc,KAAK,CACtB,QAAO,yBAAyB,MAAM,MAAM;AAG7C,UAAO;IACN,CAE8B;AAChC,eAAa,MAAM;IACjB,MAAM;AAET,2BAA0B;AACzB,eAAa,KAAK;AAClB,yBAAuB;IACrB,CAAC,YAAY,CAAC;AAEjB,QAAO;EAAE,MAAM;EAAc;EAAW,OAAO;EAAa,UAAU;EAAgB"}
@@ -1,12 +1,12 @@
1
- import * as _zayne_labs_toolkit_core0 from "@zayne-labs/toolkit-core";
1
+ import * as _zayne_labs_toolkit_core4 from "@zayne-labs/toolkit-core";
2
2
  import { LocationStoreOptions, URLSearchParamsInit } from "@zayne-labs/toolkit-core";
3
3
 
4
4
  //#region src/hooks/useSearchParams.d.ts
5
5
  type UseSearchParamsOptions = LocationStoreOptions & {
6
6
  action?: "push" | "replace";
7
7
  };
8
- declare const useSearchParams: <TSearchParams extends URLSearchParamsInit>(options?: UseSearchParamsOptions) => [searchParams: URLSearchParams, setSearchParams: (newQueryParams: TSearchParams | ((prev: URLSearchParams) => TSearchParams)) => void, triggerPopstateEvent: (nextLocationState?: _zayne_labs_toolkit_core0.LocationInfo["state"]) => void];
9
- declare const useSearchParamsObject: <TSearchParams extends Record<string, string>>(options?: UseSearchParamsOptions) => [searchParamsObject: TSearchParams, setSearchParamsObject: (newQueryParams: TSearchParams | ((prev: TSearchParams) => TSearchParams)) => void, triggerPopstateEvent: (nextLocationState?: _zayne_labs_toolkit_core0.LocationInfo["state"]) => void];
8
+ declare const useSearchParams: <TSearchParams extends URLSearchParamsInit>(options?: UseSearchParamsOptions) => [searchParams: URLSearchParams, setSearchParams: (newQueryParams: TSearchParams | ((prev: URLSearchParams) => TSearchParams)) => void, triggerPopstateEvent: (nextLocationState?: _zayne_labs_toolkit_core4.LocationInfo["state"]) => void];
9
+ declare const useSearchParamsObject: <TSearchParams extends Record<string, string>>(options?: UseSearchParamsOptions) => [searchParamsObject: TSearchParams, setSearchParamsObject: (newQueryParams: TSearchParams | ((prev: TSearchParams) => TSearchParams)) => void, triggerPopstateEvent: (nextLocationState?: _zayne_labs_toolkit_core4.LocationInfo["state"]) => void];
10
10
  //#endregion
11
11
  export { useSearchParams, useSearchParamsObject };
12
12
  //# sourceMappingURL=useSearchParams.d.ts.map
@@ -7,8 +7,7 @@ const useSearchParams = (options) => {
7
7
  const { action = "push",...restOfOptions } = options ?? {};
8
8
  const [searchParams, actions] = useLocationState((state) => state.search, restOfOptions);
9
9
  const setSearchParams = (newQueryParams) => {
10
- const params = isFunction(newQueryParams) ? newQueryParams(searchParams) : newQueryParams;
11
- const nextSearchParams = createSearchParams(params);
10
+ const nextSearchParams = createSearchParams(isFunction(newQueryParams) ? newQueryParams(searchParams) : newQueryParams);
12
11
  actions[action]({ search: nextSearchParams });
13
12
  };
14
13
  return [
@@ -21,8 +20,7 @@ const useSearchParamsObject = (options) => {
21
20
  const [searchParams, setSearchParams, triggerPopstateEvent] = useSearchParams(options);
22
21
  const searchParamsObject = Object.fromEntries(searchParams);
23
22
  const setSearchParamsObject = (newQueryParams) => {
24
- const params = isFunction(newQueryParams) ? newQueryParams(searchParamsObject) : newQueryParams;
25
- setSearchParams(params);
23
+ setSearchParams(isFunction(newQueryParams) ? newQueryParams(searchParamsObject) : newQueryParams);
26
24
  };
27
25
  return [
28
26
  searchParamsObject,
@@ -1 +1 @@
1
- {"version":3,"file":"useSearchParams.js","names":[],"sources":["../../../src/hooks/useSearchParams.ts"],"sourcesContent":["import {\n\tcreateSearchParams,\n\ttype LocationStoreOptions,\n\ttype URLSearchParamsInit,\n} from \"@zayne-labs/toolkit-core\";\nimport { isFunction } from \"@zayne-labs/toolkit-type-helpers\";\nimport { useLocationState } from \"./useLocationState\";\n\ntype UseSearchParamsOptions = LocationStoreOptions & {\n\taction?: \"push\" | \"replace\";\n};\n\nexport const useSearchParams = <TSearchParams extends URLSearchParamsInit>(\n\toptions?: UseSearchParamsOptions\n) => {\n\tconst { action = \"push\", ...restOfOptions } = options ?? {};\n\n\tconst [searchParams, actions] = useLocationState((state) => state.search, restOfOptions);\n\n\tconst setSearchParams = (\n\t\tnewQueryParams: TSearchParams | ((prev: URLSearchParams) => TSearchParams)\n\t) => {\n\t\tconst params = isFunction(newQueryParams) ? newQueryParams(searchParams) : newQueryParams;\n\n\t\tconst nextSearchParams = createSearchParams(params);\n\n\t\tactions[action]({ search: nextSearchParams });\n\t};\n\n\treturn [searchParams, setSearchParams, actions.triggerPopstateEvent] as [\n\t\tsearchParams: typeof searchParams,\n\t\tsetSearchParams: typeof setSearchParams,\n\t\ttriggerPopstateEvent: typeof actions.triggerPopstateEvent,\n\t];\n};\n\nexport const useSearchParamsObject = <TSearchParams extends Record<string, string>>(\n\toptions?: UseSearchParamsOptions\n) => {\n\tconst [searchParams, setSearchParams, triggerPopstateEvent] = useSearchParams(options);\n\n\tconst searchParamsObject = Object.fromEntries(searchParams) as TSearchParams;\n\n\tconst setSearchParamsObject = (\n\t\tnewQueryParams: TSearchParams | ((prev: TSearchParams) => TSearchParams)\n\t) => {\n\t\tconst params = isFunction(newQueryParams) ? newQueryParams(searchParamsObject) : newQueryParams;\n\n\t\tsetSearchParams(params);\n\t};\n\n\treturn [searchParamsObject, setSearchParamsObject, triggerPopstateEvent] as [\n\t\tsearchParamsObject: typeof searchParamsObject,\n\t\tsetSearchParamsObject: typeof setSearchParamsObject,\n\t\ttriggerPopstateEvent: typeof triggerPopstateEvent,\n\t];\n};\n"],"mappings":";;;;;AAYA,MAAa,mBACZ,YACI;CACJ,MAAM,EAAE,SAAS,OAAQ,GAAG,kBAAkB,WAAW,EAAE;CAE3D,MAAM,CAAC,cAAc,WAAW,kBAAkB,UAAU,MAAM,QAAQ,cAAc;CAExF,MAAM,mBACL,mBACI;EACJ,MAAM,SAAS,WAAW,eAAe,GAAG,eAAe,aAAa,GAAG;EAE3E,MAAM,mBAAmB,mBAAmB,OAAO;AAEnD,UAAQ,QAAQ,EAAE,QAAQ,kBAAkB,CAAC;;AAG9C,QAAO;EAAC;EAAc;EAAiB,QAAQ;EAAqB;;AAOrE,MAAa,yBACZ,YACI;CACJ,MAAM,CAAC,cAAc,iBAAiB,wBAAwB,gBAAgB,QAAQ;CAEtF,MAAM,qBAAqB,OAAO,YAAY,aAAa;CAE3D,MAAM,yBACL,mBACI;EACJ,MAAM,SAAS,WAAW,eAAe,GAAG,eAAe,mBAAmB,GAAG;AAEjF,kBAAgB,OAAO;;AAGxB,QAAO;EAAC;EAAoB;EAAuB;EAAqB"}
1
+ {"version":3,"file":"useSearchParams.js","names":[],"sources":["../../../src/hooks/useSearchParams.ts"],"sourcesContent":["import {\n\tcreateSearchParams,\n\ttype LocationStoreOptions,\n\ttype URLSearchParamsInit,\n} from \"@zayne-labs/toolkit-core\";\nimport { isFunction } from \"@zayne-labs/toolkit-type-helpers\";\nimport { useLocationState } from \"./useLocationState\";\n\ntype UseSearchParamsOptions = LocationStoreOptions & {\n\taction?: \"push\" | \"replace\";\n};\n\nexport const useSearchParams = <TSearchParams extends URLSearchParamsInit>(\n\toptions?: UseSearchParamsOptions\n) => {\n\tconst { action = \"push\", ...restOfOptions } = options ?? {};\n\n\tconst [searchParams, actions] = useLocationState((state) => state.search, restOfOptions);\n\n\tconst setSearchParams = (\n\t\tnewQueryParams: TSearchParams | ((prev: URLSearchParams) => TSearchParams)\n\t) => {\n\t\tconst params = isFunction(newQueryParams) ? newQueryParams(searchParams) : newQueryParams;\n\n\t\tconst nextSearchParams = createSearchParams(params);\n\n\t\tactions[action]({ search: nextSearchParams });\n\t};\n\n\treturn [searchParams, setSearchParams, actions.triggerPopstateEvent] as [\n\t\tsearchParams: typeof searchParams,\n\t\tsetSearchParams: typeof setSearchParams,\n\t\ttriggerPopstateEvent: typeof actions.triggerPopstateEvent,\n\t];\n};\n\nexport const useSearchParamsObject = <TSearchParams extends Record<string, string>>(\n\toptions?: UseSearchParamsOptions\n) => {\n\tconst [searchParams, setSearchParams, triggerPopstateEvent] = useSearchParams(options);\n\n\tconst searchParamsObject = Object.fromEntries(searchParams) as TSearchParams;\n\n\tconst setSearchParamsObject = (\n\t\tnewQueryParams: TSearchParams | ((prev: TSearchParams) => TSearchParams)\n\t) => {\n\t\tconst params = isFunction(newQueryParams) ? newQueryParams(searchParamsObject) : newQueryParams;\n\n\t\tsetSearchParams(params);\n\t};\n\n\treturn [searchParamsObject, setSearchParamsObject, triggerPopstateEvent] as [\n\t\tsearchParamsObject: typeof searchParamsObject,\n\t\tsetSearchParamsObject: typeof setSearchParamsObject,\n\t\ttriggerPopstateEvent: typeof triggerPopstateEvent,\n\t];\n};\n"],"mappings":";;;;;AAYA,MAAa,mBACZ,YACI;CACJ,MAAM,EAAE,SAAS,OAAQ,GAAG,kBAAkB,WAAW,EAAE;CAE3D,MAAM,CAAC,cAAc,WAAW,kBAAkB,UAAU,MAAM,QAAQ,cAAc;CAExF,MAAM,mBACL,mBACI;EAGJ,MAAM,mBAAmB,mBAFV,WAAW,eAAe,GAAG,eAAe,aAAa,GAAG,eAExB;AAEnD,UAAQ,QAAQ,EAAE,QAAQ,kBAAkB,CAAC;;AAG9C,QAAO;EAAC;EAAc;EAAiB,QAAQ;EAAqB;;AAOrE,MAAa,yBACZ,YACI;CACJ,MAAM,CAAC,cAAc,iBAAiB,wBAAwB,gBAAgB,QAAQ;CAEtF,MAAM,qBAAqB,OAAO,YAAY,aAAa;CAE3D,MAAM,yBACL,mBACI;AAGJ,kBAFe,WAAW,eAAe,GAAG,eAAe,mBAAmB,GAAG,eAE1D;;AAGxB,QAAO;EAAC;EAAoB;EAAuB;EAAqB"}
@@ -3,14 +3,13 @@ import { useCallback, useState } from "react";
3
3
  //#region src/hooks/useToggle.ts
4
4
  const useToggle = (initialValue = false) => {
5
5
  const [value, setValue] = useState(initialValue);
6
- const toggleValue = useCallback((newValue) => {
6
+ return [value, useCallback((newValue) => {
7
7
  if (typeof newValue === "boolean") {
8
8
  setValue(newValue);
9
9
  return;
10
10
  }
11
11
  setValue((prev) => !prev);
12
- }, []);
13
- return [value, toggleValue];
12
+ }, [])];
14
13
  };
15
14
 
16
15
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"useToggle.js","names":[],"sources":["../../../src/hooks/useToggle.ts"],"sourcesContent":["import { useCallback, useState } from \"react\";\n\ntype InitialState = boolean | (() => boolean);\n\nconst useToggle = (initialValue: InitialState = false) => {\n\tconst [value, setValue] = useState(initialValue);\n\n\tconst toggleValue = useCallback(<TValue>(newValue?: TValue) => {\n\t\tif (typeof newValue === \"boolean\") {\n\t\t\tsetValue(newValue);\n\t\t\treturn;\n\t\t}\n\n\t\tsetValue((prev) => !prev);\n\t}, []);\n\n\treturn [value, toggleValue] as [value: typeof value, toggleValue: typeof toggleValue];\n};\n\nexport { useToggle };\n"],"mappings":";;;AAIA,MAAM,aAAa,eAA6B,UAAU;CACzD,MAAM,CAAC,OAAO,YAAY,SAAS,aAAa;CAEhD,MAAM,cAAc,aAAqB,aAAsB;AAC9D,MAAI,OAAO,aAAa,WAAW;AAClC,YAAS,SAAS;AAClB;;AAGD,YAAU,SAAS,CAAC,KAAK;IACvB,EAAE,CAAC;AAEN,QAAO,CAAC,OAAO,YAAY"}
1
+ {"version":3,"file":"useToggle.js","names":[],"sources":["../../../src/hooks/useToggle.ts"],"sourcesContent":["import { useCallback, useState } from \"react\";\n\ntype InitialState = boolean | (() => boolean);\n\nconst useToggle = (initialValue: InitialState = false) => {\n\tconst [value, setValue] = useState(initialValue);\n\n\tconst toggleValue = useCallback(<TValue>(newValue?: TValue) => {\n\t\tif (typeof newValue === \"boolean\") {\n\t\t\tsetValue(newValue);\n\t\t\treturn;\n\t\t}\n\n\t\tsetValue((prev) => !prev);\n\t}, []);\n\n\treturn [value, toggleValue] as [value: typeof value, toggleValue: typeof toggleValue];\n};\n\nexport { useToggle };\n"],"mappings":";;;AAIA,MAAM,aAAa,eAA6B,UAAU;CACzD,MAAM,CAAC,OAAO,YAAY,SAAS,aAAa;AAWhD,QAAO,CAAC,OATY,aAAqB,aAAsB;AAC9D,MAAI,OAAO,aAAa,WAAW;AAClC,YAAS,SAAS;AAClB;;AAGD,YAAU,SAAS,CAAC,KAAK;IACvB,EAAE,CAAC,CAEqB"}
@@ -0,0 +1,8 @@
1
+ import { twMerge } from "tailwind-merge";
2
+
3
+ //#region src/lib/utils/cn.ts
4
+ const cnMerge = (...classNames) => twMerge(classNames);
5
+
6
+ //#endregion
7
+ export { cnMerge };
8
+ //# sourceMappingURL=cn.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cn.js","names":["cnMerge: typeof twMerge"],"sources":["../../../../src/lib/utils/cn.ts"],"sourcesContent":["import { twJoin, twMerge } from \"tailwind-merge\";\n\nexport const cnMerge: typeof twMerge = (...classNames) => twMerge(classNames);\n\nexport const cnJoin: typeof twJoin = (...classNames) => twJoin(classNames);\n"],"mappings":";;;AAEA,MAAaA,WAA2B,GAAG,eAAe,QAAQ,WAAW"}
@@ -46,8 +46,7 @@ const calculateSlotOccurrences = (childrenArray, SlotComponent) => {
46
46
  */
47
47
  const getSingleSlot = (children, SlotComponent, options = {}) => {
48
48
  const { errorMessage = "Only one instance of the SlotComponent is allowed", throwOnMultipleSlotMatch = false } = options;
49
- const actualChildren = isValidElement(children) && children.type === Fragment ? children.props.children : children;
50
- const childrenArray = toArray(actualChildren);
49
+ const childrenArray = toArray(isValidElement(children) && children.type === Fragment ? children.props.children : children);
51
50
  if (throwOnMultipleSlotMatch && calculateSlotOccurrences(childrenArray, SlotComponent) > 1) throw new AssertionError(errorMessage);
52
51
  return childrenArray.find((child) => matchesSlotComponent(child, SlotComponent));
53
52
  };
@@ -69,8 +68,7 @@ const getMultipleSlots = (children, SlotComponents, options) => {
69
68
  * @description Returns all children that are not slot elements (i.e., don't match any of the provided slot components)
70
69
  */
71
70
  const getRegularChildren = (children, SlotComponentOrComponents) => {
72
- const actualChildren = isValidElement(children) && children.type === Fragment ? children.props.children : children;
73
- return toArray(actualChildren).filter((child) => !matchesAnySlotComponent(child, toArray(SlotComponentOrComponents)));
71
+ return toArray(isValidElement(children) && children.type === Fragment ? children.props.children : children).filter((child) => !matchesAnySlotComponent(child, toArray(SlotComponentOrComponents)));
74
72
  };
75
73
 
76
74
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"getSlot.js","names":["ReactFragment"],"sources":["../../../../src/utils/getSlot/getSlot.ts"],"sourcesContent":["import { toArray } from \"@zayne-labs/toolkit-core\";\nimport {\n\ttype AnyFunction,\n\tAssertionError,\n\tisArray,\n\tisFunction,\n\ttype Prettify,\n\ttype UnknownObject,\n} from \"@zayne-labs/toolkit-type-helpers\";\nimport { isValidElement, Fragment as ReactFragment } from \"react\";\nimport type { InferProps } from \"../types\";\n\nexport type FunctionalComponent<TProps extends UnknownObject = never> = React.FunctionComponent<TProps>;\n\nconst isWithSlotSymbol = <TFunction extends AnyFunction>(\n\tcomponent: TFunction\n): component is Record<\"slotSymbol\", unknown> & TFunction => {\n\treturn \"slotSymbol\" in component && Boolean(component.slotSymbol);\n};\n\nconst isWithSlotReference = <TFunction extends AnyFunction>(\n\tcomponent: TFunction\n): component is Record<\"slotReference\", unknown> & TFunction => {\n\treturn \"slotReference\" in component && Boolean(component.slotReference);\n};\n/**\n * @description Checks if a react child (within the children array) matches the provided SlotComponent using multiple matching strategies:\n * 1. Matches by slot symbol property\n * 2. Matches by component name\n */\n\nexport const matchesSlotComponent = (child: React.ReactNode, SlotComponent: FunctionalComponent) => {\n\tif (!isValidElement(child) || !isFunction(child.type)) {\n\t\treturn false;\n\t}\n\n\tconst resolvedChildType =\n\t\tisWithSlotReference(child.type) ? (child.type.slotReference as FunctionalComponent) : child.type;\n\n\tconst hasMatchingSlotSymbol =\n\t\tisWithSlotSymbol(resolvedChildType)\n\t\t&& isWithSlotSymbol(SlotComponent)\n\t\t&& resolvedChildType.slotSymbol === SlotComponent.slotSymbol;\n\n\tif (hasMatchingSlotSymbol) {\n\t\treturn true;\n\t}\n\n\tif (child.type.name === SlotComponent.name) {\n\t\treturn true;\n\t}\n\n\treturn false;\n};\n\n/**\n * @description Checks if a react child (within the children array) matches any of the provided SlotComponents.\n */\nexport const matchesAnySlotComponent = (child: React.ReactNode, SlotComponents: FunctionalComponent[]) => {\n\tconst matchesSlot = SlotComponents.some((SlotComponent) => matchesSlotComponent(child, SlotComponent));\n\n\treturn matchesSlot;\n};\n\ntype SlotOptions = {\n\t/**\n\t * @description The error message to throw when multiple slots are found for a given slot component\n\t */\n\terrorMessage?: string;\n\t/**\n\t * @description When true, an AssertionError will be thrown if multiple slots are found for a given slot component\n\t */\n\tthrowOnMultipleSlotMatch?: boolean;\n};\n\n/**\n * @description Counts how many times a given slot component appears in an array of children\n * @internal\n */\nconst calculateSlotOccurrences = (\n\tchildrenArray: React.ReactNode[],\n\tSlotComponent: FunctionalComponent\n) => {\n\tlet count = 0;\n\n\tfor (const child of childrenArray) {\n\t\tif (!matchesSlotComponent(child, SlotComponent)) continue;\n\n\t\tcount += 1;\n\t}\n\n\treturn count;\n};\n\n/**\n * @description Retrieves a single slot element from a collection of React children that matches the provided SlotComponent component.\n *\n * @throws { AssertionError } when throwOnMultipleSlotMatch is true and multiple slots are found\n */\nexport const getSingleSlot = (\n\tchildren: React.ReactNode,\n\tSlotComponent: FunctionalComponent,\n\toptions: SlotOptions = {}\n) => {\n\tconst {\n\t\terrorMessage = \"Only one instance of the SlotComponent is allowed\",\n\t\tthrowOnMultipleSlotMatch = false,\n\t} = options;\n\n\tconst actualChildren =\n\t\tisValidElement<InferProps<typeof ReactFragment>>(children) && children.type === ReactFragment ?\n\t\t\tchildren.props.children\n\t\t:\tchildren;\n\n\tconst childrenArray = toArray<React.ReactNode>(actualChildren);\n\n\tconst shouldThrow =\n\t\tthrowOnMultipleSlotMatch && calculateSlotOccurrences(childrenArray, SlotComponent) > 1;\n\n\tif (shouldThrow) {\n\t\tthrow new AssertionError(errorMessage);\n\t}\n\n\tconst slotElement = childrenArray.find((child) => matchesSlotComponent(child, SlotComponent));\n\n\treturn slotElement;\n};\n\n// NOTE - You can imitate const type parameter by extending readonly[] | []\n\ntype MultipleSlotsOptions = {\n\t/**\n\t * @description The error message to throw when multiple slots are found for a given slot component\n\t * If a string is provided, the same message will be used for all slot components\n\t * If an array is provided, each string in the array will be used as the errorMessage for the corresponding slot component\n\t */\n\terrorMessage?: string | string[];\n\t/**\n\t * @description When true, an AssertionError will be thrown if multiple slots are found for a given slot component\n\t * If a boolean is provided, the same value will be used for all slot components\n\t * If an array is provided, each boolean in the array will be used as the throwOnMultipleSlotMatch value for the corresponding slot component\n\t */\n\tthrowOnMultipleSlotMatch?: boolean | boolean[];\n};\n\ntype GetMultipleSlotsResult<TSlotComponents extends FunctionalComponent[]> = {\n\tregularChildren: React.ReactNode[];\n\tslots: { [Key in keyof TSlotComponents]: ReturnType<TSlotComponents[Key]> };\n};\n\n/**\n * @description The same as getSingleSlot, but for multiple slot components\n */\nexport const getMultipleSlots = <const TSlotComponents extends FunctionalComponent[]>(\n\tchildren: React.ReactNode,\n\tSlotComponents: TSlotComponents,\n\toptions?: MultipleSlotsOptions\n): Prettify<GetMultipleSlotsResult<TSlotComponents>> => {\n\tconst { errorMessage, throwOnMultipleSlotMatch } = options ?? {};\n\n\tconst slots = SlotComponents.map((SlotComponent, index) =>\n\t\tgetSingleSlot(children, SlotComponent, {\n\t\t\terrorMessage: isArray(errorMessage) ? errorMessage[index] : errorMessage,\n\t\t\tthrowOnMultipleSlotMatch:\n\t\t\t\tisArray(throwOnMultipleSlotMatch) ? throwOnMultipleSlotMatch[index] : throwOnMultipleSlotMatch,\n\t\t})\n\t);\n\n\tconst regularChildren = getRegularChildren(children, SlotComponents);\n\n\treturn { regularChildren, slots } as GetMultipleSlotsResult<TSlotComponents>;\n};\n\n/**\n * @description Returns all children that are not slot elements (i.e., don't match any of the provided slot components)\n */\nexport const getRegularChildren = (\n\tchildren: React.ReactNode,\n\tSlotComponentOrComponents: FunctionalComponent | FunctionalComponent[]\n) => {\n\tconst actualChildren =\n\t\tisValidElement<InferProps<typeof ReactFragment>>(children) && children.type === ReactFragment ?\n\t\t\tchildren.props.children\n\t\t:\tchildren;\n\n\tconst childrenArray = toArray<React.ReactNode>(actualChildren);\n\n\tconst regularChildren = childrenArray.filter(\n\t\t(child) => !matchesAnySlotComponent(child, toArray(SlotComponentOrComponents))\n\t);\n\n\treturn regularChildren;\n};\n"],"mappings":";;;;;AAcA,MAAM,oBACL,cAC4D;AAC5D,QAAO,gBAAgB,aAAa,QAAQ,UAAU,WAAW;;AAGlE,MAAM,uBACL,cAC+D;AAC/D,QAAO,mBAAmB,aAAa,QAAQ,UAAU,cAAc;;;;;;;AAQxE,MAAa,wBAAwB,OAAwB,kBAAuC;AACnG,KAAI,CAAC,eAAe,MAAM,IAAI,CAAC,WAAW,MAAM,KAAK,CACpD,QAAO;CAGR,MAAM,oBACL,oBAAoB,MAAM,KAAK,GAAI,MAAM,KAAK,gBAAwC,MAAM;AAO7F,KAJC,iBAAiB,kBAAkB,IAChC,iBAAiB,cAAc,IAC/B,kBAAkB,eAAe,cAAc,WAGlD,QAAO;AAGR,KAAI,MAAM,KAAK,SAAS,cAAc,KACrC,QAAO;AAGR,QAAO;;;;;AAMR,MAAa,2BAA2B,OAAwB,mBAA0C;AAGzG,QAFoB,eAAe,MAAM,kBAAkB,qBAAqB,OAAO,cAAc,CAAC;;;;;;AAoBvG,MAAM,4BACL,eACA,kBACI;CACJ,IAAI,QAAQ;AAEZ,MAAK,MAAM,SAAS,eAAe;AAClC,MAAI,CAAC,qBAAqB,OAAO,cAAc,CAAE;AAEjD,WAAS;;AAGV,QAAO;;;;;;;AAQR,MAAa,iBACZ,UACA,eACA,UAAuB,EAAE,KACrB;CACJ,MAAM,EACL,eAAe,qDACf,2BAA2B,UACxB;CAEJ,MAAM,iBACL,eAAiD,SAAS,IAAI,SAAS,SAASA,WAC/E,SAAS,MAAM,WACd;CAEH,MAAM,gBAAgB,QAAyB,eAAe;AAK9D,KAFC,4BAA4B,yBAAyB,eAAe,cAAc,GAAG,EAGrF,OAAM,IAAI,eAAe,aAAa;AAKvC,QAFoB,cAAc,MAAM,UAAU,qBAAqB,OAAO,cAAc,CAAC;;;;;AA8B9F,MAAa,oBACZ,UACA,gBACA,YACuD;CACvD,MAAM,EAAE,cAAc,6BAA6B,WAAW,EAAE;CAEhE,MAAM,QAAQ,eAAe,KAAK,eAAe,UAChD,cAAc,UAAU,eAAe;EACtC,cAAc,QAAQ,aAAa,GAAG,aAAa,SAAS;EAC5D,0BACC,QAAQ,yBAAyB,GAAG,yBAAyB,SAAS;EACvE,CAAC,CACF;AAID,QAAO;EAAE,iBAFe,mBAAmB,UAAU,eAAe;EAE1C;EAAO;;;;;AAMlC,MAAa,sBACZ,UACA,8BACI;CACJ,MAAM,iBACL,eAAiD,SAAS,IAAI,SAAS,SAASA,WAC/E,SAAS,MAAM,WACd;AAQH,QANsB,QAAyB,eAAe,CAExB,QACpC,UAAU,CAAC,wBAAwB,OAAO,QAAQ,0BAA0B,CAAC,CAC9E"}
1
+ {"version":3,"file":"getSlot.js","names":["ReactFragment"],"sources":["../../../../src/utils/getSlot/getSlot.ts"],"sourcesContent":["import { toArray } from \"@zayne-labs/toolkit-core\";\nimport {\n\ttype AnyFunction,\n\tAssertionError,\n\tisArray,\n\tisFunction,\n\ttype Prettify,\n\ttype UnknownObject,\n} from \"@zayne-labs/toolkit-type-helpers\";\nimport { isValidElement, Fragment as ReactFragment } from \"react\";\nimport type { InferProps } from \"../types\";\n\nexport type FunctionalComponent<TProps extends UnknownObject = never> = React.FunctionComponent<TProps>;\n\nconst isWithSlotSymbol = <TFunction extends AnyFunction>(\n\tcomponent: TFunction\n): component is Record<\"slotSymbol\", unknown> & TFunction => {\n\treturn \"slotSymbol\" in component && Boolean(component.slotSymbol);\n};\n\nconst isWithSlotReference = <TFunction extends AnyFunction>(\n\tcomponent: TFunction\n): component is Record<\"slotReference\", unknown> & TFunction => {\n\treturn \"slotReference\" in component && Boolean(component.slotReference);\n};\n/**\n * @description Checks if a react child (within the children array) matches the provided SlotComponent using multiple matching strategies:\n * 1. Matches by slot symbol property\n * 2. Matches by component name\n */\n\nexport const matchesSlotComponent = (child: React.ReactNode, SlotComponent: FunctionalComponent) => {\n\tif (!isValidElement(child) || !isFunction(child.type)) {\n\t\treturn false;\n\t}\n\n\tconst resolvedChildType =\n\t\tisWithSlotReference(child.type) ? (child.type.slotReference as FunctionalComponent) : child.type;\n\n\tconst hasMatchingSlotSymbol =\n\t\tisWithSlotSymbol(resolvedChildType)\n\t\t&& isWithSlotSymbol(SlotComponent)\n\t\t&& resolvedChildType.slotSymbol === SlotComponent.slotSymbol;\n\n\tif (hasMatchingSlotSymbol) {\n\t\treturn true;\n\t}\n\n\tif (child.type.name === SlotComponent.name) {\n\t\treturn true;\n\t}\n\n\treturn false;\n};\n\n/**\n * @description Checks if a react child (within the children array) matches any of the provided SlotComponents.\n */\nexport const matchesAnySlotComponent = (child: React.ReactNode, SlotComponents: FunctionalComponent[]) => {\n\tconst matchesSlot = SlotComponents.some((SlotComponent) => matchesSlotComponent(child, SlotComponent));\n\n\treturn matchesSlot;\n};\n\ntype SlotOptions = {\n\t/**\n\t * @description The error message to throw when multiple slots are found for a given slot component\n\t */\n\terrorMessage?: string;\n\t/**\n\t * @description When true, an AssertionError will be thrown if multiple slots are found for a given slot component\n\t */\n\tthrowOnMultipleSlotMatch?: boolean;\n};\n\n/**\n * @description Counts how many times a given slot component appears in an array of children\n * @internal\n */\nconst calculateSlotOccurrences = (\n\tchildrenArray: React.ReactNode[],\n\tSlotComponent: FunctionalComponent\n) => {\n\tlet count = 0;\n\n\tfor (const child of childrenArray) {\n\t\tif (!matchesSlotComponent(child, SlotComponent)) continue;\n\n\t\tcount += 1;\n\t}\n\n\treturn count;\n};\n\n/**\n * @description Retrieves a single slot element from a collection of React children that matches the provided SlotComponent component.\n *\n * @throws { AssertionError } when throwOnMultipleSlotMatch is true and multiple slots are found\n */\nexport const getSingleSlot = (\n\tchildren: React.ReactNode,\n\tSlotComponent: FunctionalComponent,\n\toptions: SlotOptions = {}\n) => {\n\tconst {\n\t\terrorMessage = \"Only one instance of the SlotComponent is allowed\",\n\t\tthrowOnMultipleSlotMatch = false,\n\t} = options;\n\n\tconst actualChildren =\n\t\tisValidElement<InferProps<typeof ReactFragment>>(children) && children.type === ReactFragment ?\n\t\t\tchildren.props.children\n\t\t:\tchildren;\n\n\tconst childrenArray = toArray<React.ReactNode>(actualChildren);\n\n\tconst shouldThrow =\n\t\tthrowOnMultipleSlotMatch && calculateSlotOccurrences(childrenArray, SlotComponent) > 1;\n\n\tif (shouldThrow) {\n\t\tthrow new AssertionError(errorMessage);\n\t}\n\n\tconst slotElement = childrenArray.find((child) => matchesSlotComponent(child, SlotComponent));\n\n\treturn slotElement;\n};\n\n// NOTE - You can imitate const type parameter by extending readonly[] | []\n\ntype MultipleSlotsOptions = {\n\t/**\n\t * @description The error message to throw when multiple slots are found for a given slot component\n\t * If a string is provided, the same message will be used for all slot components\n\t * If an array is provided, each string in the array will be used as the errorMessage for the corresponding slot component\n\t */\n\terrorMessage?: string | string[];\n\t/**\n\t * @description When true, an AssertionError will be thrown if multiple slots are found for a given slot component\n\t * If a boolean is provided, the same value will be used for all slot components\n\t * If an array is provided, each boolean in the array will be used as the throwOnMultipleSlotMatch value for the corresponding slot component\n\t */\n\tthrowOnMultipleSlotMatch?: boolean | boolean[];\n};\n\ntype GetMultipleSlotsResult<TSlotComponents extends FunctionalComponent[]> = {\n\tregularChildren: React.ReactNode[];\n\tslots: { [Key in keyof TSlotComponents]: ReturnType<TSlotComponents[Key]> };\n};\n\n/**\n * @description The same as getSingleSlot, but for multiple slot components\n */\nexport const getMultipleSlots = <const TSlotComponents extends FunctionalComponent[]>(\n\tchildren: React.ReactNode,\n\tSlotComponents: TSlotComponents,\n\toptions?: MultipleSlotsOptions\n): Prettify<GetMultipleSlotsResult<TSlotComponents>> => {\n\tconst { errorMessage, throwOnMultipleSlotMatch } = options ?? {};\n\n\tconst slots = SlotComponents.map((SlotComponent, index) =>\n\t\tgetSingleSlot(children, SlotComponent, {\n\t\t\terrorMessage: isArray(errorMessage) ? errorMessage[index] : errorMessage,\n\t\t\tthrowOnMultipleSlotMatch:\n\t\t\t\tisArray(throwOnMultipleSlotMatch) ? throwOnMultipleSlotMatch[index] : throwOnMultipleSlotMatch,\n\t\t})\n\t);\n\n\tconst regularChildren = getRegularChildren(children, SlotComponents);\n\n\treturn { regularChildren, slots } as GetMultipleSlotsResult<TSlotComponents>;\n};\n\n/**\n * @description Returns all children that are not slot elements (i.e., don't match any of the provided slot components)\n */\nexport const getRegularChildren = (\n\tchildren: React.ReactNode,\n\tSlotComponentOrComponents: FunctionalComponent | FunctionalComponent[]\n) => {\n\tconst actualChildren =\n\t\tisValidElement<InferProps<typeof ReactFragment>>(children) && children.type === ReactFragment ?\n\t\t\tchildren.props.children\n\t\t:\tchildren;\n\n\tconst childrenArray = toArray<React.ReactNode>(actualChildren);\n\n\tconst regularChildren = childrenArray.filter(\n\t\t(child) => !matchesAnySlotComponent(child, toArray(SlotComponentOrComponents))\n\t);\n\n\treturn regularChildren;\n};\n"],"mappings":";;;;;AAcA,MAAM,oBACL,cAC4D;AAC5D,QAAO,gBAAgB,aAAa,QAAQ,UAAU,WAAW;;AAGlE,MAAM,uBACL,cAC+D;AAC/D,QAAO,mBAAmB,aAAa,QAAQ,UAAU,cAAc;;;;;;;AAQxE,MAAa,wBAAwB,OAAwB,kBAAuC;AACnG,KAAI,CAAC,eAAe,MAAM,IAAI,CAAC,WAAW,MAAM,KAAK,CACpD,QAAO;CAGR,MAAM,oBACL,oBAAoB,MAAM,KAAK,GAAI,MAAM,KAAK,gBAAwC,MAAM;AAO7F,KAJC,iBAAiB,kBAAkB,IAChC,iBAAiB,cAAc,IAC/B,kBAAkB,eAAe,cAAc,WAGlD,QAAO;AAGR,KAAI,MAAM,KAAK,SAAS,cAAc,KACrC,QAAO;AAGR,QAAO;;;;;AAMR,MAAa,2BAA2B,OAAwB,mBAA0C;AAGzG,QAFoB,eAAe,MAAM,kBAAkB,qBAAqB,OAAO,cAAc,CAAC;;;;;;AAoBvG,MAAM,4BACL,eACA,kBACI;CACJ,IAAI,QAAQ;AAEZ,MAAK,MAAM,SAAS,eAAe;AAClC,MAAI,CAAC,qBAAqB,OAAO,cAAc,CAAE;AAEjD,WAAS;;AAGV,QAAO;;;;;;;AAQR,MAAa,iBACZ,UACA,eACA,UAAuB,EAAE,KACrB;CACJ,MAAM,EACL,eAAe,qDACf,2BAA2B,UACxB;CAOJ,MAAM,gBAAgB,QAJrB,eAAiD,SAAS,IAAI,SAAS,SAASA,WAC/E,SAAS,MAAM,WACd,SAE2D;AAK9D,KAFC,4BAA4B,yBAAyB,eAAe,cAAc,GAAG,EAGrF,OAAM,IAAI,eAAe,aAAa;AAKvC,QAFoB,cAAc,MAAM,UAAU,qBAAqB,OAAO,cAAc,CAAC;;;;;AA8B9F,MAAa,oBACZ,UACA,gBACA,YACuD;CACvD,MAAM,EAAE,cAAc,6BAA6B,WAAW,EAAE;CAEhE,MAAM,QAAQ,eAAe,KAAK,eAAe,UAChD,cAAc,UAAU,eAAe;EACtC,cAAc,QAAQ,aAAa,GAAG,aAAa,SAAS;EAC5D,0BACC,QAAQ,yBAAyB,GAAG,yBAAyB,SAAS;EACvE,CAAC,CACF;AAID,QAAO;EAAE,iBAFe,mBAAmB,UAAU,eAAe;EAE1C;EAAO;;;;;AAMlC,MAAa,sBACZ,UACA,8BACI;AAYJ,QANsB,QAJrB,eAAiD,SAAS,IAAI,SAAS,SAASA,WAC/E,SAAS,MAAM,WACd,SAE2D,CAExB,QACpC,UAAU,CAAC,wBAAwB,OAAO,QAAQ,0BAA0B,CAAC,CAC9E"}
@@ -41,8 +41,7 @@ const slotComponentSymbol = Symbol("slot-component");
41
41
  */
42
42
  const getSlotMap = (children) => {
43
43
  const slots = { default: [] };
44
- const actualChildren = isValidElement(children) && children.type === Fragment ? children.props.children : children;
45
- const childrenArray = toArray(actualChildren);
44
+ const childrenArray = toArray(isValidElement(children) && children.type === Fragment ? children.props.children : children);
46
45
  for (const child of childrenArray) {
47
46
  if (!isValidElement(child) || !isFunction(child.type)) {
48
47
  slots.default.push(child);
@@ -1 +1 @@
1
- {"version":3,"file":"getSlotMap.js","names":["slots: Record<string, TSlotComponentProps[\"children\"]> & { default: React.ReactNode[] }","ReactFragment"],"sources":["../../../../src/utils/getSlotMap/getSlotMap.ts"],"sourcesContent":["import { toArray } from \"@zayne-labs/toolkit-core\";\nimport {\n\ttype CallbackFn,\n\ttype EmptyObject,\n\tisFunction,\n\ttype Prettify,\n\ttype UnionToIntersection,\n\ttype UnknownObject,\n} from \"@zayne-labs/toolkit-type-helpers\";\nimport { isValidElement, Fragment as ReactFragment } from \"react\";\nimport type { InferProps } from \"../types\";\n\ntype GetSlotName<TSlotComponentProps extends GetSlotComponentProps> =\n\tstring extends TSlotComponentProps[\"name\"] ? never\n\t: \"default\" extends TSlotComponentProps[\"name\"] ? never\n\t: TSlotComponentProps[\"name\"];\n\ntype GetSpecificSlotsType<TSlotComponentProps extends GetSlotComponentProps> = {\n\t// This conditional before the remapping will prevent an Indexed Record type from showing up if the props are not passed, enhancing type safety\n\t[TName in keyof TSlotComponentProps as GetSlotName<TSlotComponentProps>]: Extract<\n\t\tTSlotComponentProps[\"children\"],\n\t\tReact.ReactNode\n\t>;\n};\n\n/**\n * Maps slot names to their corresponding children types\n */\nexport type GetSlotMapResult<TSlotComponentProps extends GetSlotComponentProps> = UnionToIntersection<\n\tGetSpecificSlotsType<TSlotComponentProps>\n> & { default: React.ReactNode[] };\n\n/**\n * Symbol used to identify SlotComponent instances\n */\nexport const slotComponentSymbol = Symbol(\"slot-component\");\n\n/**\n * @description Creates a map of named slots from React children. Returns an object mapping slot names to their children,\n * with a default slot for unmatched children.\n *\n * @example\n * ```tsx\n * import { type GetSlotComponentProps, SlotComponent } from \"@zayne-labs/toolkit-react/utils\"\n *\n * type SlotProps = GetSlotComponentProps<\"header\" | \"footer\">;\n *\n * function Parent({ children }: { children: React.ReactNode }) {\n * const slots = getSlotMap<SlotProps>(children);\n *\n * return (\n * <div>\n * <header>{slots.header}</header>\n * <main>{slots.default}</main>\n * <footer>{slots.footer}</footer>\n * </div>\n * );\n * }\n * ```\n *\n * Usage:\n * ```tsx\n * <Parent>\n * <SlotComponent name=\"header\">Header Content</SlotComponent>\n * <div>Random stuff</div>\n * <SlotComponent name=\"footer\">Footer Content</SlotComponent>\n * </Parent>\n * ```\n */\nexport const getSlotMap = <TSlotComponentProps extends GetSlotComponentProps>(\n\tchildren: React.ReactNode\n): Prettify<GetSlotMapResult<TSlotComponentProps>> => {\n\tconst slots: Record<string, TSlotComponentProps[\"children\"]> & { default: React.ReactNode[] } = {\n\t\tdefault: [],\n\t};\n\n\tconst isFragment = isValidElement<InferProps<HTMLElement>>(children) && children.type === ReactFragment;\n\n\tconst actualChildren = isFragment ? children.props.children : children;\n\n\tconst childrenArray = toArray<React.ReactNode>(actualChildren);\n\n\tfor (const child of childrenArray) {\n\t\tif (!isValidElement<TSlotComponentProps>(child) || !isFunction(child.type)) {\n\t\t\tslots.default.push(child);\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst childType = child.type as SlotWithNameAndSymbol;\n\n\t\tconst isSlotElement =\n\t\t\tchildType.slotSymbol === slotComponentSymbol && Boolean(childType.slotName ?? child.props.name);\n\n\t\tif (!isSlotElement) {\n\t\t\tslots.default.push(child);\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst slotName = childType.slotName ?? child.props.name;\n\n\t\tif (slotName === \"default\") {\n\t\t\tslots.default.push(child);\n\t\t\tcontinue;\n\t\t}\n\n\t\tslots[slotName] = child;\n\t}\n\n\treturn slots as GetSlotMapResult<TSlotComponentProps>;\n};\n\n/**\n * @description Produce props for the SlotComponent\n *\n * @example\n * ```ts\n * // Pattern One (slot or slots have same children type, which is just React.ReactNode by default)\n * type SlotProps = GetSlotComponentProps<\"header\" | \"content\" | \"footer\">;\n *\n * // Pattern Two (some slots can have different children type)\n * type SlotProps = GetSlotComponentProps<\"header\", React.ReactNode> | GetSlotComponentProps<\"header\", (renderProp: RenderProp) => React.ReactNode>;\n * ```\n */\nexport type GetSlotComponentProps<\n\tTName extends string = string,\n\tTChildren extends CallbackFn<never, React.ReactNode> | React.ReactNode =\n\t\t| CallbackFn<never, React.ReactNode>\n\t\t| React.ReactNode,\n> = {\n\tchildren: TChildren;\n\t/**\n\t * Name of the slot where content should be rendered\n\t */\n\tname: TName;\n};\n\n/**\n * @description Creates a slot component\n */\nexport const createSlotComponent = <TSlotComponentProps extends GetSlotComponentProps>() => {\n\tconst SlotComponent = (props: TSlotComponentProps) => props.children as React.ReactNode;\n\n\tSlotComponent.slotSymbol = slotComponentSymbol;\n\n\treturn SlotComponent;\n};\n\ntype SlotWithNameAndSymbol<\n\tTSlotComponentProps extends GetSlotComponentProps = GetSlotComponentProps,\n\tTOtherProps extends UnknownObject = EmptyObject,\n> = {\n\t(props: Pick<TSlotComponentProps, \"children\"> & TOtherProps): React.ReactNode;\n\treadonly slotName?: TSlotComponentProps[\"name\"];\n\treadonly slotSymbol?: symbol;\n};\n\nfunction DefaultSlotComponent(props: Pick<GetSlotComponentProps, \"children\">): React.ReactNode {\n\treturn props.children as React.ReactNode;\n}\n\n/**\n * @description Adds a slot symbol and name to a slot component passed in\n */\nexport const withSlotNameAndSymbol = <\n\tTSlotComponentProps extends GetSlotComponentProps,\n\tTOtherProps extends UnknownObject = EmptyObject,\n>(\n\tname: TSlotComponentProps[\"name\"],\n\tSlotComponent: SlotWithNameAndSymbol<TSlotComponentProps, TOtherProps> = DefaultSlotComponent\n) => {\n\t/* eslint-disable no-param-reassign -- This is necessary */\n\t// @ts-expect-error -- This is necessary for the time being, to prevent type errors and accidental overrides on consumer side\n\tSlotComponent.slotSymbol = slotComponentSymbol;\n\t// @ts-expect-error -- This is necessary for the time being, to prevent type errors and accidental overrides on consumer side\n\tSlotComponent.slotName = name;\n\n\t/* eslint-enable no-param-reassign -- This is necessary */\n\n\treturn SlotComponent;\n};\n"],"mappings":";;;;;;;;AAmCA,MAAa,sBAAsB,OAAO,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkC3D,MAAa,cACZ,aACqD;CACrD,MAAMA,QAA0F,EAC/F,SAAS,EAAE,EACX;CAID,MAAM,iBAFa,eAAwC,SAAS,IAAI,SAAS,SAASC,WAEtD,SAAS,MAAM,WAAW;CAE9D,MAAM,gBAAgB,QAAyB,eAAe;AAE9D,MAAK,MAAM,SAAS,eAAe;AAClC,MAAI,CAAC,eAAoC,MAAM,IAAI,CAAC,WAAW,MAAM,KAAK,EAAE;AAC3E,SAAM,QAAQ,KAAK,MAAM;AACzB;;EAGD,MAAM,YAAY,MAAM;AAKxB,MAAI,EAFH,UAAU,eAAe,uBAAuB,QAAQ,UAAU,YAAY,MAAM,MAAM,KAAK,GAE5E;AACnB,SAAM,QAAQ,KAAK,MAAM;AACzB;;EAGD,MAAM,WAAW,UAAU,YAAY,MAAM,MAAM;AAEnD,MAAI,aAAa,WAAW;AAC3B,SAAM,QAAQ,KAAK,MAAM;AACzB;;AAGD,QAAM,YAAY;;AAGnB,QAAO;;;;;AA+BR,MAAa,4BAA+E;CAC3F,MAAM,iBAAiB,UAA+B,MAAM;AAE5D,eAAc,aAAa;AAE3B,QAAO;;AAYR,SAAS,qBAAqB,OAAiE;AAC9F,QAAO,MAAM;;;;;AAMd,MAAa,yBAIZ,MACA,gBAAyE,yBACrE;AAGJ,eAAc,aAAa;AAE3B,eAAc,WAAW;AAIzB,QAAO"}
1
+ {"version":3,"file":"getSlotMap.js","names":["slots: Record<string, TSlotComponentProps[\"children\"]> & { default: React.ReactNode[] }","ReactFragment"],"sources":["../../../../src/utils/getSlotMap/getSlotMap.ts"],"sourcesContent":["import { toArray } from \"@zayne-labs/toolkit-core\";\nimport {\n\ttype CallbackFn,\n\ttype EmptyObject,\n\tisFunction,\n\ttype Prettify,\n\ttype UnionToIntersection,\n\ttype UnknownObject,\n} from \"@zayne-labs/toolkit-type-helpers\";\nimport { isValidElement, Fragment as ReactFragment } from \"react\";\nimport type { InferProps } from \"../types\";\n\ntype GetSlotName<TSlotComponentProps extends GetSlotComponentProps> =\n\tstring extends TSlotComponentProps[\"name\"] ? never\n\t: \"default\" extends TSlotComponentProps[\"name\"] ? never\n\t: TSlotComponentProps[\"name\"];\n\ntype GetSpecificSlotsType<TSlotComponentProps extends GetSlotComponentProps> = {\n\t// This conditional before the remapping will prevent an Indexed Record type from showing up if the props are not passed, enhancing type safety\n\t[TName in keyof TSlotComponentProps as GetSlotName<TSlotComponentProps>]: Extract<\n\t\tTSlotComponentProps[\"children\"],\n\t\tReact.ReactNode\n\t>;\n};\n\n/**\n * Maps slot names to their corresponding children types\n */\nexport type GetSlotMapResult<TSlotComponentProps extends GetSlotComponentProps> = UnionToIntersection<\n\tGetSpecificSlotsType<TSlotComponentProps>\n> & { default: React.ReactNode[] };\n\n/**\n * Symbol used to identify SlotComponent instances\n */\nexport const slotComponentSymbol = Symbol(\"slot-component\");\n\n/**\n * @description Creates a map of named slots from React children. Returns an object mapping slot names to their children,\n * with a default slot for unmatched children.\n *\n * @example\n * ```tsx\n * import { type GetSlotComponentProps, SlotComponent } from \"@zayne-labs/toolkit-react/utils\"\n *\n * type SlotProps = GetSlotComponentProps<\"header\" | \"footer\">;\n *\n * function Parent({ children }: { children: React.ReactNode }) {\n * const slots = getSlotMap<SlotProps>(children);\n *\n * return (\n * <div>\n * <header>{slots.header}</header>\n * <main>{slots.default}</main>\n * <footer>{slots.footer}</footer>\n * </div>\n * );\n * }\n * ```\n *\n * Usage:\n * ```tsx\n * <Parent>\n * <SlotComponent name=\"header\">Header Content</SlotComponent>\n * <div>Random stuff</div>\n * <SlotComponent name=\"footer\">Footer Content</SlotComponent>\n * </Parent>\n * ```\n */\nexport const getSlotMap = <TSlotComponentProps extends GetSlotComponentProps>(\n\tchildren: React.ReactNode\n): Prettify<GetSlotMapResult<TSlotComponentProps>> => {\n\tconst slots: Record<string, TSlotComponentProps[\"children\"]> & { default: React.ReactNode[] } = {\n\t\tdefault: [],\n\t};\n\n\tconst isFragment = isValidElement<InferProps<HTMLElement>>(children) && children.type === ReactFragment;\n\n\tconst actualChildren = isFragment ? children.props.children : children;\n\n\tconst childrenArray = toArray<React.ReactNode>(actualChildren);\n\n\tfor (const child of childrenArray) {\n\t\tif (!isValidElement<TSlotComponentProps>(child) || !isFunction(child.type)) {\n\t\t\tslots.default.push(child);\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst childType = child.type as SlotWithNameAndSymbol;\n\n\t\tconst isSlotElement =\n\t\t\tchildType.slotSymbol === slotComponentSymbol && Boolean(childType.slotName ?? child.props.name);\n\n\t\tif (!isSlotElement) {\n\t\t\tslots.default.push(child);\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst slotName = childType.slotName ?? child.props.name;\n\n\t\tif (slotName === \"default\") {\n\t\t\tslots.default.push(child);\n\t\t\tcontinue;\n\t\t}\n\n\t\tslots[slotName] = child;\n\t}\n\n\treturn slots as GetSlotMapResult<TSlotComponentProps>;\n};\n\n/**\n * @description Produce props for the SlotComponent\n *\n * @example\n * ```ts\n * // Pattern One (slot or slots have same children type, which is just React.ReactNode by default)\n * type SlotProps = GetSlotComponentProps<\"header\" | \"content\" | \"footer\">;\n *\n * // Pattern Two (some slots can have different children type)\n * type SlotProps = GetSlotComponentProps<\"header\", React.ReactNode> | GetSlotComponentProps<\"header\", (renderProp: RenderProp) => React.ReactNode>;\n * ```\n */\nexport type GetSlotComponentProps<\n\tTName extends string = string,\n\tTChildren extends CallbackFn<never, React.ReactNode> | React.ReactNode =\n\t\t| CallbackFn<never, React.ReactNode>\n\t\t| React.ReactNode,\n> = {\n\tchildren: TChildren;\n\t/**\n\t * Name of the slot where content should be rendered\n\t */\n\tname: TName;\n};\n\n/**\n * @description Creates a slot component\n */\nexport const createSlotComponent = <TSlotComponentProps extends GetSlotComponentProps>() => {\n\tconst SlotComponent = (props: TSlotComponentProps) => props.children as React.ReactNode;\n\n\tSlotComponent.slotSymbol = slotComponentSymbol;\n\n\treturn SlotComponent;\n};\n\ntype SlotWithNameAndSymbol<\n\tTSlotComponentProps extends GetSlotComponentProps = GetSlotComponentProps,\n\tTOtherProps extends UnknownObject = EmptyObject,\n> = {\n\t(props: Pick<TSlotComponentProps, \"children\"> & TOtherProps): React.ReactNode;\n\treadonly slotName?: TSlotComponentProps[\"name\"];\n\treadonly slotSymbol?: symbol;\n};\n\nfunction DefaultSlotComponent(props: Pick<GetSlotComponentProps, \"children\">): React.ReactNode {\n\treturn props.children as React.ReactNode;\n}\n\n/**\n * @description Adds a slot symbol and name to a slot component passed in\n */\nexport const withSlotNameAndSymbol = <\n\tTSlotComponentProps extends GetSlotComponentProps,\n\tTOtherProps extends UnknownObject = EmptyObject,\n>(\n\tname: TSlotComponentProps[\"name\"],\n\tSlotComponent: SlotWithNameAndSymbol<TSlotComponentProps, TOtherProps> = DefaultSlotComponent\n) => {\n\t/* eslint-disable no-param-reassign -- This is necessary */\n\t// @ts-expect-error -- This is necessary for the time being, to prevent type errors and accidental overrides on consumer side\n\tSlotComponent.slotSymbol = slotComponentSymbol;\n\t// @ts-expect-error -- This is necessary for the time being, to prevent type errors and accidental overrides on consumer side\n\tSlotComponent.slotName = name;\n\n\t/* eslint-enable no-param-reassign -- This is necessary */\n\n\treturn SlotComponent;\n};\n"],"mappings":";;;;;;;;AAmCA,MAAa,sBAAsB,OAAO,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkC3D,MAAa,cACZ,aACqD;CACrD,MAAMA,QAA0F,EAC/F,SAAS,EAAE,EACX;CAMD,MAAM,gBAAgB,QAJH,eAAwC,SAAS,IAAI,SAAS,SAASC,WAEtD,SAAS,MAAM,WAAW,SAEA;AAE9D,MAAK,MAAM,SAAS,eAAe;AAClC,MAAI,CAAC,eAAoC,MAAM,IAAI,CAAC,WAAW,MAAM,KAAK,EAAE;AAC3E,SAAM,QAAQ,KAAK,MAAM;AACzB;;EAGD,MAAM,YAAY,MAAM;AAKxB,MAAI,EAFH,UAAU,eAAe,uBAAuB,QAAQ,UAAU,YAAY,MAAM,MAAM,KAAK,GAE5E;AACnB,SAAM,QAAQ,KAAK,MAAM;AACzB;;EAGD,MAAM,WAAW,UAAU,YAAY,MAAM,MAAM;AAEnD,MAAI,aAAa,WAAW;AAC3B,SAAM,QAAQ,KAAK,MAAM;AACzB;;AAGD,QAAM,YAAY;;AAGnB,QAAO;;;;;AA+BR,MAAa,4BAA+E;CAC3F,MAAM,iBAAiB,UAA+B,MAAM;AAE5D,eAAc,aAAa;AAE3B,QAAO;;AAYR,SAAS,qBAAqB,OAAiE;AAC9F,QAAO,MAAM;;;;;AAMd,MAAa,yBAIZ,MACA,gBAAyE,yBACrE;AAGJ,eAAc,aAAa;AAE3B,eAAc,WAAW;AAIzB,QAAO"}
@@ -1,4 +1,5 @@
1
1
  import { composeTwoEventHandlers } from "./composeEventHandlers.js";
2
+ import { cnMerge } from "../lib/utils/cn.js";
2
3
  import { isFunction } from "@zayne-labs/toolkit-type-helpers";
3
4
 
4
5
  //#region src/utils/mergeTwoProps.ts
@@ -7,10 +8,6 @@ const isEventHandler = (key, value) => {
7
8
  if (!isFunction(value) || thirdCharCode === void 0) return false;
8
9
  return key.startsWith("on") && thirdCharCode >= 65 && thirdCharCode <= 90;
9
10
  };
10
- const mergeTwoClassNames = (formerClassName, latterClassName) => {
11
- if (!latterClassName || !formerClassName) return latterClassName || formerClassName;
12
- return formerClassName + " " + latterClassName;
13
- };
14
11
  const mergeTwoProps = (formerProps, latterProps) => {
15
12
  if (!latterProps || !formerProps) return latterProps ?? formerProps ?? {};
16
13
  const propsAccumulator = { ...formerProps };
@@ -18,7 +15,7 @@ const mergeTwoProps = (formerProps, latterProps) => {
18
15
  const formerPropValue = formerProps[latterPropName];
19
16
  const latterPropValue = latterProps[latterPropName];
20
17
  if (latterPropName === "className" || latterPropName === "class") {
21
- propsAccumulator[latterPropName] = mergeTwoClassNames(formerPropValue, latterPropValue);
18
+ propsAccumulator[latterPropName] = cnMerge(formerPropValue, latterPropValue);
22
19
  continue;
23
20
  }
24
21
  if (latterPropName === "style") {
@@ -1 +1 @@
1
- {"version":3,"file":"mergeTwoProps.js","names":[],"sources":["../../../src/utils/mergeTwoProps.ts"],"sourcesContent":["import { type AnyFunction, isFunction } from \"@zayne-labs/toolkit-type-helpers\";\nimport { composeTwoEventHandlers } from \"./composeEventHandlers\";\n\n// == This approach is more efficient than using a regex.\nconst isEventHandler = (key: string, value: unknown): value is AnyFunction => {\n\tconst thirdCharCode = key.codePointAt(2);\n\n\tif (!isFunction(value) || thirdCharCode === undefined) {\n\t\treturn false;\n\t}\n\n\tconst isHandler = key.startsWith(\"on\") && thirdCharCode >= 65 /* A */ && thirdCharCode <= 90; /* Z */\n\n\treturn isHandler;\n};\n\nconst mergeTwoClassNames = (formerClassName: string | undefined, latterClassName: string | undefined) => {\n\tif (!latterClassName || !formerClassName) {\n\t\t// eslint-disable-next-line ts-eslint/prefer-nullish-coalescing -- Logical OR is fit for this case\n\t\treturn latterClassName || formerClassName;\n\t}\n\n\t// eslint-disable-next-line prefer-template -- String concatenation is more performant than template literals in this case\n\treturn formerClassName + \" \" + latterClassName;\n};\n\nexport const mergeTwoProps = <TProps extends Record<never, never>>(\n\tformerProps: TProps | undefined,\n\tlatterProps: TProps | undefined\n): TProps => {\n\t// == If no props are provided, return an empty object\n\tif (!latterProps || !formerProps) {\n\t\treturn latterProps ?? formerProps ?? ({} as TProps);\n\t}\n\n\tconst propsAccumulator = { ...formerProps } as Record<string, unknown>;\n\n\tfor (const latterPropName of Object.keys(latterProps)) {\n\t\tconst formerPropValue = (formerProps as Record<string, unknown>)[latterPropName];\n\t\tconst latterPropValue = (latterProps as Record<string, unknown>)[latterPropName];\n\n\t\t// == If the prop is `className` or `class`, we merge them\n\t\tif (latterPropName === \"className\" || latterPropName === \"class\") {\n\t\t\tpropsAccumulator[latterPropName] = mergeTwoClassNames(\n\t\t\t\tformerPropValue as string,\n\t\t\t\tlatterPropValue as string\n\t\t\t);\n\t\t\tcontinue;\n\t\t}\n\n\t\t// == If the prop is `style`, we merge them\n\t\tif (latterPropName === \"style\") {\n\t\t\tpropsAccumulator[latterPropName] = {\n\t\t\t\t...(formerPropValue as object),\n\t\t\t\t...(latterPropValue as object),\n\t\t\t};\n\t\t\tcontinue;\n\t\t}\n\n\t\t// == If the handler exists on both, we compose them\n\t\tif (isEventHandler(latterPropName, latterPropValue)) {\n\t\t\tpropsAccumulator[latterPropName] = composeTwoEventHandlers(\n\t\t\t\tformerPropValue as AnyFunction | undefined,\n\t\t\t\tlatterPropValue\n\t\t\t);\n\n\t\t\tcontinue;\n\t\t}\n\n\t\t// == latterProps override by default\n\t\tpropsAccumulator[latterPropName] = latterPropValue;\n\t}\n\n\treturn propsAccumulator as TProps;\n};\n"],"mappings":";;;;AAIA,MAAM,kBAAkB,KAAa,UAAyC;CAC7E,MAAM,gBAAgB,IAAI,YAAY,EAAE;AAExC,KAAI,CAAC,WAAW,MAAM,IAAI,kBAAkB,OAC3C,QAAO;AAKR,QAFkB,IAAI,WAAW,KAAK,IAAI,iBAAiB,MAAc,iBAAiB;;AAK3F,MAAM,sBAAsB,iBAAqC,oBAAwC;AACxG,KAAI,CAAC,mBAAmB,CAAC,gBAExB,QAAO,mBAAmB;AAI3B,QAAO,kBAAkB,MAAM;;AAGhC,MAAa,iBACZ,aACA,gBACY;AAEZ,KAAI,CAAC,eAAe,CAAC,YACpB,QAAO,eAAe,eAAgB,EAAE;CAGzC,MAAM,mBAAmB,EAAE,GAAG,aAAa;AAE3C,MAAK,MAAM,kBAAkB,OAAO,KAAK,YAAY,EAAE;EACtD,MAAM,kBAAmB,YAAwC;EACjE,MAAM,kBAAmB,YAAwC;AAGjE,MAAI,mBAAmB,eAAe,mBAAmB,SAAS;AACjE,oBAAiB,kBAAkB,mBAClC,iBACA,gBACA;AACD;;AAID,MAAI,mBAAmB,SAAS;AAC/B,oBAAiB,kBAAkB;IAClC,GAAI;IACJ,GAAI;IACJ;AACD;;AAID,MAAI,eAAe,gBAAgB,gBAAgB,EAAE;AACpD,oBAAiB,kBAAkB,wBAClC,iBACA,gBACA;AAED;;AAID,mBAAiB,kBAAkB;;AAGpC,QAAO"}
1
+ {"version":3,"file":"mergeTwoProps.js","names":[],"sources":["../../../src/utils/mergeTwoProps.ts"],"sourcesContent":["import { type AnyFunction, isFunction } from \"@zayne-labs/toolkit-type-helpers\";\nimport { cnMerge } from \"@/lib/utils/cn\";\nimport { composeTwoEventHandlers } from \"./composeEventHandlers\";\n\n// == This approach is more efficient than using a regex.\nconst isEventHandler = (key: string, value: unknown): value is AnyFunction => {\n\tconst thirdCharCode = key.codePointAt(2);\n\n\tif (!isFunction(value) || thirdCharCode === undefined) {\n\t\treturn false;\n\t}\n\n\tconst isHandler = key.startsWith(\"on\") && thirdCharCode >= 65 /* A */ && thirdCharCode <= 90; /* Z */\n\n\treturn isHandler;\n};\n\n// const mergeTwoClassNames = (formerClassName: string | undefined, latterClassName: string | undefined) => {\n// \tif (!latterClassName || !formerClassName) {\n// \t\t// eslint-disable-next-line ts-eslint/prefer-nullish-coalescing -- Logical OR is fit for this case\n// \t\treturn latterClassName || formerClassName;\n// \t}\n\n// \t// eslint-disable-next-line prefer-template -- String concatenation is more performant than template literals in this case\n// \treturn formerClassName + \" \" + latterClassName;\n// };\n\nexport const mergeTwoProps = <TProps extends Record<never, never>>(\n\tformerProps: TProps | undefined,\n\tlatterProps: TProps | undefined\n): TProps => {\n\t// == If no props are provided, return an empty object\n\tif (!latterProps || !formerProps) {\n\t\treturn latterProps ?? formerProps ?? ({} as TProps);\n\t}\n\n\tconst propsAccumulator = { ...formerProps } as Record<string, unknown>;\n\n\tfor (const latterPropName of Object.keys(latterProps)) {\n\t\tconst formerPropValue = (formerProps as Record<string, unknown>)[latterPropName];\n\t\tconst latterPropValue = (latterProps as Record<string, unknown>)[latterPropName];\n\n\t\t// == If the prop is `className` or `class`, we merge them\n\t\tif (latterPropName === \"className\" || latterPropName === \"class\") {\n\t\t\tpropsAccumulator[latterPropName] = cnMerge(formerPropValue as string, latterPropValue as string);\n\t\t\tcontinue;\n\t\t}\n\n\t\t// == If the prop is `style`, we merge them\n\t\tif (latterPropName === \"style\") {\n\t\t\tpropsAccumulator[latterPropName] = {\n\t\t\t\t...(formerPropValue as object),\n\t\t\t\t...(latterPropValue as object),\n\t\t\t};\n\t\t\tcontinue;\n\t\t}\n\n\t\t// == If the handler exists on both, we compose them\n\t\tif (isEventHandler(latterPropName, latterPropValue)) {\n\t\t\tpropsAccumulator[latterPropName] = composeTwoEventHandlers(\n\t\t\t\tformerPropValue as AnyFunction | undefined,\n\t\t\t\tlatterPropValue\n\t\t\t);\n\n\t\t\tcontinue;\n\t\t}\n\n\t\t// == latterProps override by default\n\t\tpropsAccumulator[latterPropName] = latterPropValue;\n\t}\n\n\treturn propsAccumulator as TProps;\n};\n"],"mappings":";;;;;AAKA,MAAM,kBAAkB,KAAa,UAAyC;CAC7E,MAAM,gBAAgB,IAAI,YAAY,EAAE;AAExC,KAAI,CAAC,WAAW,MAAM,IAAI,kBAAkB,OAC3C,QAAO;AAKR,QAFkB,IAAI,WAAW,KAAK,IAAI,iBAAiB,MAAc,iBAAiB;;AAe3F,MAAa,iBACZ,aACA,gBACY;AAEZ,KAAI,CAAC,eAAe,CAAC,YACpB,QAAO,eAAe,eAAgB,EAAE;CAGzC,MAAM,mBAAmB,EAAE,GAAG,aAAa;AAE3C,MAAK,MAAM,kBAAkB,OAAO,KAAK,YAAY,EAAE;EACtD,MAAM,kBAAmB,YAAwC;EACjE,MAAM,kBAAmB,YAAwC;AAGjE,MAAI,mBAAmB,eAAe,mBAAmB,SAAS;AACjE,oBAAiB,kBAAkB,QAAQ,iBAA2B,gBAA0B;AAChG;;AAID,MAAI,mBAAmB,SAAS;AAC/B,oBAAiB,kBAAkB;IAClC,GAAI;IACJ,GAAI;IACJ;AACD;;AAID,MAAI,eAAe,gBAAgB,gBAAgB,EAAE;AACpD,oBAAiB,kBAAkB,wBAClC,iBACA,gBACA;AAED;;AAID,mBAAiB,kBAAkB;;AAGpC,QAAO"}
@@ -10,8 +10,7 @@ const createZustandContext = (options) => {
10
10
  return createElement(Provider, { value: store }, children);
11
11
  }
12
12
  const useZustandStoreContext = (selector) => {
13
- const zustandStore = useCustomContext();
14
- return useStore(zustandStore, selector);
13
+ return useStore(useCustomContext(), selector);
15
14
  };
16
15
  return [ZustandStoreContextProvider, useZustandStoreContext];
17
16
  };
@@ -1 +1 @@
1
- {"version":3,"file":"createZustandContext.js","names":[],"sources":["../../../src/zustand/createZustandContext.ts"],"sourcesContent":["import type { StoreApi } from \"@zayne-labs/toolkit-core\";\nimport type { SelectorFn } from \"@zayne-labs/toolkit-type-helpers\";\nimport { createElement } from \"react\";\nimport { type CustomContextOptions, createCustomContext, useStore } from \"../hooks\";\n\nconst createZustandContext = <\n\tTState extends Record<string, unknown>,\n\tTStore extends StoreApi<TState> = StoreApi<TState>,\n>(\n\toptions?: CustomContextOptions<TStore, true>\n) => {\n\tconst [Provider, useCustomContext] = createCustomContext(options);\n\n\ttype ZustandStoreContextProviderProps = {\n\t\tchildren: React.ReactNode;\n\t\tstore: TStore;\n\t};\n\n\tfunction ZustandStoreContextProvider(props: ZustandStoreContextProviderProps) {\n\t\tconst { children, store } = props;\n\n\t\treturn createElement(Provider, { value: store }, children);\n\t}\n\n\tconst useZustandStoreContext = <TResult = TState>(selector?: SelectorFn<TState, TResult>): TResult => {\n\t\tconst zustandStore = useCustomContext();\n\n\t\treturn useStore(zustandStore, selector);\n\t};\n\n\treturn [ZustandStoreContextProvider, useZustandStoreContext] as [\n\t\tZustandStoreContextProvider: typeof ZustandStoreContextProvider,\n\t\tuseZustandStoreContext: typeof useZustandStoreContext,\n\t];\n};\n\nexport { createZustandContext };\n"],"mappings":";;;;;AAKA,MAAM,wBAIL,YACI;CACJ,MAAM,CAAC,UAAU,oBAAoB,oBAAoB,QAAQ;CAOjE,SAAS,4BAA4B,OAAyC;EAC7E,MAAM,EAAE,UAAU,UAAU;AAE5B,SAAO,cAAc,UAAU,EAAE,OAAO,OAAO,EAAE,SAAS;;CAG3D,MAAM,0BAA4C,aAAoD;EACrG,MAAM,eAAe,kBAAkB;AAEvC,SAAO,SAAS,cAAc,SAAS;;AAGxC,QAAO,CAAC,6BAA6B,uBAAuB"}
1
+ {"version":3,"file":"createZustandContext.js","names":[],"sources":["../../../src/zustand/createZustandContext.ts"],"sourcesContent":["import type { StoreApi } from \"@zayne-labs/toolkit-core\";\nimport type { SelectorFn } from \"@zayne-labs/toolkit-type-helpers\";\nimport { createElement } from \"react\";\nimport { type CustomContextOptions, createCustomContext, useStore } from \"../hooks\";\n\nconst createZustandContext = <\n\tTState extends Record<string, unknown>,\n\tTStore extends StoreApi<TState> = StoreApi<TState>,\n>(\n\toptions?: CustomContextOptions<TStore, true>\n) => {\n\tconst [Provider, useCustomContext] = createCustomContext(options);\n\n\ttype ZustandStoreContextProviderProps = {\n\t\tchildren: React.ReactNode;\n\t\tstore: TStore;\n\t};\n\n\tfunction ZustandStoreContextProvider(props: ZustandStoreContextProviderProps) {\n\t\tconst { children, store } = props;\n\n\t\treturn createElement(Provider, { value: store }, children);\n\t}\n\n\tconst useZustandStoreContext = <TResult = TState>(selector?: SelectorFn<TState, TResult>): TResult => {\n\t\tconst zustandStore = useCustomContext();\n\n\t\treturn useStore(zustandStore, selector);\n\t};\n\n\treturn [ZustandStoreContextProvider, useZustandStoreContext] as [\n\t\tZustandStoreContextProvider: typeof ZustandStoreContextProvider,\n\t\tuseZustandStoreContext: typeof useZustandStoreContext,\n\t];\n};\n\nexport { createZustandContext };\n"],"mappings":";;;;;AAKA,MAAM,wBAIL,YACI;CACJ,MAAM,CAAC,UAAU,oBAAoB,oBAAoB,QAAQ;CAOjE,SAAS,4BAA4B,OAAyC;EAC7E,MAAM,EAAE,UAAU,UAAU;AAE5B,SAAO,cAAc,UAAU,EAAE,OAAO,OAAO,EAAE,SAAS;;CAG3D,MAAM,0BAA4C,aAAoD;AAGrG,SAAO,SAFc,kBAAkB,EAET,SAAS;;AAGxC,QAAO,CAAC,6BAA6B,uBAAuB"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@zayne-labs/toolkit-react",
3
3
  "type": "module",
4
- "version": "0.12.2",
4
+ "version": "0.12.4",
5
5
  "description": "A collection of utility functions, types and composables used by my other projects. Nothing too fancy but can be useful.",
6
6
  "author": "Ryan Zayne",
7
7
  "license": "MIT",
@@ -32,7 +32,8 @@
32
32
  },
33
33
  "peerDependencies": {
34
34
  "@types/react": ">=19.0.0",
35
- "react": ">=19.0.0"
35
+ "react": ">=19.0.0",
36
+ "tailwind-merge": "^2.5.0 || ^3.0.0"
36
37
  },
37
38
  "peerDependenciesMeta": {
38
39
  "@types/react": {
@@ -43,8 +44,8 @@
43
44
  }
44
45
  },
45
46
  "dependencies": {
46
- "@zayne-labs/toolkit-core": "0.12.2",
47
- "@zayne-labs/toolkit-type-helpers": "0.12.2"
47
+ "@zayne-labs/toolkit-core": "0.12.4",
48
+ "@zayne-labs/toolkit-type-helpers": "0.12.4"
48
49
  },
49
50
  "devDependencies": {
50
51
  "@arethetypeswrong/cli": "^0.18.2",
@@ -52,15 +53,16 @@
52
53
  "@size-limit/esbuild-why": "^11.2.0",
53
54
  "@size-limit/preset-small-lib": "^11.2.0",
54
55
  "@total-typescript/ts-reset": "^0.6.1",
55
- "@types/node": "^24.6.2",
56
- "@types/react": "^19.2.0",
57
- "@zayne-labs/tsconfig": "0.10.4",
56
+ "@types/node": "^24.7.2",
57
+ "@types/react": "^19.2.2",
58
+ "@zayne-labs/tsconfig": "0.10.9",
58
59
  "concurrently": "^9.2.1",
59
60
  "cross-env": "^10.1.0",
60
- "publint": "^0.3.13",
61
+ "publint": "^0.3.14",
61
62
  "react": "^19.2.0",
62
63
  "size-limit": "^11.2.0",
63
- "tsdown": "^0.15.6",
64
+ "tailwind-merge": "3.3.1",
65
+ "tsdown": "^0.15.7",
64
66
  "typescript": "5.9.3"
65
67
  },
66
68
  "publishConfig": {