@cdx-ui/utils 0.0.1-alpha.1

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.
Files changed (108) hide show
  1. package/README.md +11 -0
  2. package/lib/commonjs/common/accessibilityUtils.js +9 -0
  3. package/lib/commonjs/common/accessibilityUtils.js.map +1 -0
  4. package/lib/commonjs/common/cn.js +12 -0
  5. package/lib/commonjs/common/cn.js.map +1 -0
  6. package/lib/commonjs/common/composeEventHandlers.js +14 -0
  7. package/lib/commonjs/common/composeEventHandlers.js.map +1 -0
  8. package/lib/commonjs/common/getSpacedChild.js +27 -0
  9. package/lib/commonjs/common/getSpacedChild.js.map +1 -0
  10. package/lib/commonjs/common/index.js +48 -0
  11. package/lib/commonjs/common/index.js.map +1 -0
  12. package/lib/commonjs/common/mergeRefs.js +18 -0
  13. package/lib/commonjs/common/mergeRefs.js.map +1 -0
  14. package/lib/commonjs/common/useControllableState.js +65 -0
  15. package/lib/commonjs/common/useControllableState.js.map +1 -0
  16. package/lib/commonjs/context/createContext.js +31 -0
  17. package/lib/commonjs/context/createContext.js.map +1 -0
  18. package/lib/commonjs/context/index.js +13 -0
  19. package/lib/commonjs/context/index.js.map +1 -0
  20. package/lib/commonjs/form-control/index.js +25 -0
  21. package/lib/commonjs/form-control/index.js.map +1 -0
  22. package/lib/commonjs/form-control/useFormControl.js +51 -0
  23. package/lib/commonjs/form-control/useFormControl.js.map +1 -0
  24. package/lib/commonjs/index.js +50 -0
  25. package/lib/commonjs/index.js.map +1 -0
  26. package/lib/commonjs/package.json +1 -0
  27. package/lib/commonjs/style/context/index.js +18 -0
  28. package/lib/commonjs/style/context/index.js.map +1 -0
  29. package/lib/commonjs/style/index.js +28 -0
  30. package/lib/commonjs/style/index.js.map +1 -0
  31. package/lib/commonjs/style/withStyleContext/index.js +33 -0
  32. package/lib/commonjs/style/withStyleContext/index.js.map +1 -0
  33. package/lib/module/common/accessibilityUtils.js +4 -0
  34. package/lib/module/common/accessibilityUtils.js.map +1 -0
  35. package/lib/module/common/cn.js +8 -0
  36. package/lib/module/common/cn.js.map +1 -0
  37. package/lib/module/common/composeEventHandlers.js +10 -0
  38. package/lib/module/common/composeEventHandlers.js.map +1 -0
  39. package/lib/module/common/getSpacedChild.js +22 -0
  40. package/lib/module/common/getSpacedChild.js.map +1 -0
  41. package/lib/module/common/index.js +9 -0
  42. package/lib/module/common/index.js.map +1 -0
  43. package/lib/module/common/mergeRefs.js +14 -0
  44. package/lib/module/common/mergeRefs.js.map +1 -0
  45. package/lib/module/common/useControllableState.js +62 -0
  46. package/lib/module/common/useControllableState.js.map +1 -0
  47. package/lib/module/context/createContext.js +27 -0
  48. package/lib/module/context/createContext.js.map +1 -0
  49. package/lib/module/context/index.js +4 -0
  50. package/lib/module/context/index.js.map +1 -0
  51. package/lib/module/form-control/index.js +4 -0
  52. package/lib/module/form-control/index.js.map +1 -0
  53. package/lib/module/form-control/useFormControl.js +43 -0
  54. package/lib/module/form-control/useFormControl.js.map +1 -0
  55. package/lib/module/index.js +7 -0
  56. package/lib/module/index.js.map +1 -0
  57. package/lib/module/style/context/index.js +12 -0
  58. package/lib/module/style/context/index.js.map +1 -0
  59. package/lib/module/style/index.js +5 -0
  60. package/lib/module/style/index.js.map +1 -0
  61. package/lib/module/style/withStyleContext/index.js +28 -0
  62. package/lib/module/style/withStyleContext/index.js.map +1 -0
  63. package/lib/typescript/common/accessibilityUtils.d.ts +2 -0
  64. package/lib/typescript/common/accessibilityUtils.d.ts.map +1 -0
  65. package/lib/typescript/common/cn.d.ts +3 -0
  66. package/lib/typescript/common/cn.d.ts.map +1 -0
  67. package/lib/typescript/common/composeEventHandlers.d.ts +2 -0
  68. package/lib/typescript/common/composeEventHandlers.d.ts.map +1 -0
  69. package/lib/typescript/common/getSpacedChild.d.ts +5 -0
  70. package/lib/typescript/common/getSpacedChild.d.ts.map +1 -0
  71. package/lib/typescript/common/index.d.ts +7 -0
  72. package/lib/typescript/common/index.d.ts.map +1 -0
  73. package/lib/typescript/common/mergeRefs.d.ts +3 -0
  74. package/lib/typescript/common/mergeRefs.d.ts.map +1 -0
  75. package/lib/typescript/common/useControllableState.d.ts +8 -0
  76. package/lib/typescript/common/useControllableState.d.ts.map +1 -0
  77. package/lib/typescript/context/createContext.d.ts +6 -0
  78. package/lib/typescript/context/createContext.d.ts.map +1 -0
  79. package/lib/typescript/context/index.d.ts +2 -0
  80. package/lib/typescript/context/index.d.ts.map +1 -0
  81. package/lib/typescript/form-control/index.d.ts +2 -0
  82. package/lib/typescript/form-control/index.d.ts.map +1 -0
  83. package/lib/typescript/form-control/useFormControl.d.ts +38 -0
  84. package/lib/typescript/form-control/useFormControl.d.ts.map +1 -0
  85. package/lib/typescript/index.d.ts +5 -0
  86. package/lib/typescript/index.d.ts.map +1 -0
  87. package/lib/typescript/style/context/index.d.ts +5 -0
  88. package/lib/typescript/style/context/index.d.ts.map +1 -0
  89. package/lib/typescript/style/index.d.ts +3 -0
  90. package/lib/typescript/style/index.d.ts.map +1 -0
  91. package/lib/typescript/style/withStyleContext/index.d.ts +6 -0
  92. package/lib/typescript/style/withStyleContext/index.d.ts.map +1 -0
  93. package/package.json +65 -0
  94. package/src/common/accessibilityUtils.ts +1 -0
  95. package/src/common/cn.ts +6 -0
  96. package/src/common/composeEventHandlers.ts +7 -0
  97. package/src/common/getSpacedChild.tsx +32 -0
  98. package/src/common/index.ts +6 -0
  99. package/src/common/mergeRefs.ts +13 -0
  100. package/src/common/useControllableState.ts +75 -0
  101. package/src/context/createContext.tsx +27 -0
  102. package/src/context/index.ts +1 -0
  103. package/src/form-control/index.ts +8 -0
  104. package/src/form-control/useFormControl.tsx +63 -0
  105. package/src/index.ts +4 -0
  106. package/src/style/context/index.tsx +14 -0
  107. package/src/style/index.tsx +2 -0
  108. package/src/style/withStyleContext/index.tsx +36 -0
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+
3
+ export function mergeRefs(...refs) {
4
+ return value => {
5
+ for (const ref of refs) {
6
+ if (typeof ref === 'function') {
7
+ ref(value);
8
+ } else if (ref != null) {
9
+ ref.current = value;
10
+ }
11
+ }
12
+ };
13
+ }
14
+ //# sourceMappingURL=mergeRefs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["mergeRefs","refs","value","ref","current"],"sourceRoot":"../../../src","sources":["common/mergeRefs.ts"],"mappings":";;AAEA,OAAO,SAASA,SAASA,CAAI,GAAGC,IAA4B,EAAkB;EAC5E,OAAQC,KAAe,IAAK;IAC1B,KAAK,MAAMC,GAAG,IAAIF,IAAI,EAAE;MACtB,IAAI,OAAOE,GAAG,KAAK,UAAU,EAAE;QAC7BA,GAAG,CAACD,KAAK,CAAC;MACZ,CAAC,MAAM,IAAIC,GAAG,IAAI,IAAI,EAAE;QACtBA,GAAG,CAACC,OAAO,GAAGF,KAAK;MACrB;IACF;EACF,CAAC;AACH","ignoreList":[]}
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+
3
+ // This project uses code from WorkOS/Radix Primitives.
4
+ // The code is licensed under the MIT License.
5
+ // https://github.com/radix-ui/primitives/tree/main
6
+
7
+ import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
8
+ function useControllableState({
9
+ prop,
10
+ defaultProp,
11
+ onChange = () => {}
12
+ }) {
13
+ const [uncontrolledProp, setUncontrolledProp] = useUncontrolledState({
14
+ defaultProp,
15
+ onChange
16
+ });
17
+ const isControlled = prop !== undefined;
18
+ const value = isControlled ? prop : uncontrolledProp;
19
+ const handleChange = useCallbackRef(onChange);
20
+ const setValue = useCallback(nextValue => {
21
+ if (isControlled) {
22
+ const setter = nextValue;
23
+ const value = typeof nextValue === 'function' ? setter(prop) : nextValue;
24
+ if (value !== prop) handleChange(value);
25
+ } else {
26
+ setUncontrolledProp(nextValue);
27
+ }
28
+ }, [isControlled, prop, setUncontrolledProp, handleChange]);
29
+ return [value, setValue];
30
+ }
31
+ function useUncontrolledState({
32
+ defaultProp,
33
+ onChange
34
+ }) {
35
+ const uncontrolledState = useState(defaultProp);
36
+ const [value] = uncontrolledState;
37
+ const prevValueRef = useRef(value);
38
+ const handleChange = useCallbackRef(onChange);
39
+ useEffect(() => {
40
+ if (prevValueRef.current !== value) {
41
+ handleChange(value);
42
+ prevValueRef.current = value;
43
+ }
44
+ }, [value, prevValueRef, handleChange]);
45
+ return uncontrolledState;
46
+ }
47
+
48
+ /**
49
+ * A custom hook that converts a callback to a ref to avoid triggering re-renders when passed as a
50
+ * prop or avoid re-executing effects when passed as a dependency
51
+ */
52
+ function useCallbackRef(callback) {
53
+ const callbackRef = useRef(callback);
54
+ useEffect(() => {
55
+ callbackRef.current = callback;
56
+ });
57
+
58
+ // https://github.com/facebook/react/issues/19240
59
+ return useMemo(() => (...args) => callbackRef.current?.(...args), []);
60
+ }
61
+ export { useControllableState };
62
+ //# sourceMappingURL=useControllableState.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["useCallback","useEffect","useMemo","useRef","useState","useControllableState","prop","defaultProp","onChange","uncontrolledProp","setUncontrolledProp","useUncontrolledState","isControlled","undefined","value","handleChange","useCallbackRef","setValue","nextValue","setter","uncontrolledState","prevValueRef","current","callback","callbackRef","args"],"sourceRoot":"../../../src","sources":["common/useControllableState.ts"],"mappings":";;AAAA;AACA;AACA;;AAEA,SAASA,WAAW,EAAEC,SAAS,EAAEC,OAAO,EAAEC,MAAM,EAAEC,QAAQ,QAAQ,OAAO;AAUzE,SAASC,oBAAoBA,CAAI;EAC/BC,IAAI;EACJC,WAAW;EACXC,QAAQ,GAAGA,CAAA,KAAM,CAAC;AACW,CAAC,EAAE;EAChC,MAAM,CAACC,gBAAgB,EAAEC,mBAAmB,CAAC,GAAGC,oBAAoB,CAAC;IAAEJ,WAAW;IAAEC;EAAS,CAAC,CAAC;EAC/F,MAAMI,YAAY,GAAGN,IAAI,KAAKO,SAAS;EACvC,MAAMC,KAAK,GAAGF,YAAY,GAAGN,IAAI,GAAGG,gBAAgB;EACpD,MAAMM,YAAY,GAAGC,cAAc,CAACR,QAAQ,CAAC;EAE7C,MAAMS,QAA6D,GAAGjB,WAAW,CAC9EkB,SAAS,IAAK;IACb,IAAIN,YAAY,EAAE;MAChB,MAAMO,MAAM,GAAGD,SAA0B;MACzC,MAAMJ,KAAK,GAAG,OAAOI,SAAS,KAAK,UAAU,GAAGC,MAAM,CAACb,IAAI,CAAC,GAAGY,SAAS;MACxE,IAAIJ,KAAK,KAAKR,IAAI,EAAES,YAAY,CAACD,KAAU,CAAC;IAC9C,CAAC,MAAM;MACLJ,mBAAmB,CAACQ,SAAS,CAAC;IAChC;EACF,CAAC,EACD,CAACN,YAAY,EAAEN,IAAI,EAAEI,mBAAmB,EAAEK,YAAY,CACxD,CAAC;EAED,OAAO,CAACD,KAAK,EAAEG,QAAQ,CAAC;AAC1B;AAEA,SAASN,oBAAoBA,CAAI;EAC/BJ,WAAW;EACXC;AAC2C,CAAC,EAAE;EAC9C,MAAMY,iBAAiB,GAAGhB,QAAQ,CAAgBG,WAAW,CAAC;EAC9D,MAAM,CAACO,KAAK,CAAC,GAAGM,iBAAiB;EACjC,MAAMC,YAAY,GAAGlB,MAAM,CAACW,KAAK,CAAC;EAClC,MAAMC,YAAY,GAAGC,cAAc,CAACR,QAAQ,CAAC;EAE7CP,SAAS,CAAC,MAAM;IACd,IAAIoB,YAAY,CAACC,OAAO,KAAKR,KAAK,EAAE;MAClCC,YAAY,CAACD,KAAU,CAAC;MACxBO,YAAY,CAACC,OAAO,GAAGR,KAAK;IAC9B;EACF,CAAC,EAAE,CAACA,KAAK,EAAEO,YAAY,EAAEN,YAAY,CAAC,CAAC;EAEvC,OAAOK,iBAAiB;AAC1B;;AAEA;AACA;AACA;AACA;AACA,SAASJ,cAAcA,CAAoCO,QAAuB,EAAK;EACrF,MAAMC,WAAW,GAAGrB,MAAM,CAACoB,QAAQ,CAAC;EAEpCtB,SAAS,CAAC,MAAM;IACduB,WAAW,CAACF,OAAO,GAAGC,QAAQ;EAChC,CAAC,CAAC;;EAEF;EACA,OAAOrB,OAAO,CAAC,MAAO,CAAC,GAAGuB,IAAI,KAAKD,WAAW,CAACF,OAAO,GAAG,GAAGG,IAAI,CAAO,EAAE,EAAE,CAAC;AAC9E;AAEA,SAASpB,oBAAoB","ignoreList":[]}
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+
3
+ import { createContext as createReactContext, useContext } from 'react';
4
+ import { jsx as _jsx } from "react/jsx-runtime";
5
+ export function createContext(displayName) {
6
+ const Context = /*#__PURE__*/createReactContext(undefined);
7
+ const Provider = props => {
8
+ const {
9
+ children,
10
+ value
11
+ } = props;
12
+ return /*#__PURE__*/_jsx(Context.Provider, {
13
+ value: value,
14
+ children: children
15
+ });
16
+ };
17
+ Provider.displayName = `${displayName}Provider`;
18
+ function useC() {
19
+ const context = useContext(Context);
20
+ if (context === undefined) {
21
+ throw new Error(`use${displayName} must be used within a ${displayName}Provider`);
22
+ }
23
+ return context;
24
+ }
25
+ return [Provider, useC];
26
+ }
27
+ //# sourceMappingURL=createContext.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["createContext","createReactContext","useContext","jsx","_jsx","displayName","Context","undefined","Provider","props","children","value","useC","context","Error"],"sourceRoot":"../../../src","sources":["context/createContext.tsx"],"mappings":";;AAAA,SAEEA,aAAa,IAAIC,kBAAkB,EAEnCC,UAAU,QACL,OAAO;AAAC,SAAAC,GAAA,IAAAC,IAAA;AAEf,OAAO,SAASJ,aAAaA,CAAIK,WAAmB,EAAE;EACpD,MAAMC,OAAO,gBAAGL,kBAAkB,CAAgBM,SAAS,CAAC;EAE5D,MAAMC,QAA0D,GAAIC,KAAK,IAAK;IAC5E,MAAM;MAAEC,QAAQ;MAAEC;IAAM,CAAC,GAAGF,KAAK;IACjC,oBAAOL,IAAA,CAACE,OAAO,CAACE,QAAQ;MAACG,KAAK,EAAEA,KAAM;MAAAD,QAAA,EAAEA;IAAQ,CAAmB,CAAC;EACtE,CAAC;EAEDF,QAAQ,CAACH,WAAW,GAAG,GAAGA,WAAW,UAAU;EAE/C,SAASO,IAAIA,CAAA,EAAM;IACjB,MAAMC,OAAO,GAAGX,UAAU,CAACI,OAAO,CAAC;IACnC,IAAIO,OAAO,KAAKN,SAAS,EAAE;MACzB,MAAM,IAAIO,KAAK,CAAC,MAAMT,WAAW,0BAA0BA,WAAW,UAAU,CAAC;IACnF;IACA,OAAOQ,OAAO;EAChB;EAEA,OAAO,CAACL,QAAQ,EAAEI,IAAI,CAAC;AACzB","ignoreList":[]}
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+
3
+ export { createContext } from './createContext';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["createContext"],"sourceRoot":"../../../src","sources":["context/index.ts"],"mappings":";;AAAA,SAASA,aAAa,QAAQ,iBAAiB","ignoreList":[]}
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+
3
+ export { FormControlContext, useFormControl, useFormControlContext } from './useFormControl';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["FormControlContext","useFormControl","useFormControlContext"],"sourceRoot":"../../../src","sources":["form-control/index.ts"],"mappings":";;AAAA,SAIEA,kBAAkB,EAClBC,cAAc,EACdC,qBAAqB,QAChB,kBAAkB","ignoreList":[]}
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+
3
+ import React from 'react';
4
+ import { ariaAttr } from '../common/accessibilityUtils';
5
+ export const FormControlContext = /*#__PURE__*/React.createContext({});
6
+ /**
7
+ * Hook that merges local field props with the nearest FormControl context
8
+ * and returns normalised HTML / ARIA attributes for input elements.
9
+ */
10
+ export function useFormControl(props) {
11
+ const field = useFormControlContext();
12
+ const describedBy = [];
13
+ if (field?.hasFeedbackText && field.feedbackId) {
14
+ describedBy.push(field.feedbackId);
15
+ }
16
+ if (field?.hasHelpText && field.helpTextId) {
17
+ describedBy.push(field.helpTextId);
18
+ }
19
+ const ariaDescribedBy = describedBy.join(' ');
20
+ const {
21
+ isInvalid,
22
+ isDisabled,
23
+ isReadOnly,
24
+ isRequired,
25
+ ...cleanProps
26
+ } = props;
27
+ const id = props.id ?? (field?.id ? `${field.id}-input` : undefined);
28
+ return {
29
+ ...cleanProps,
30
+ id,
31
+ disabled: isDisabled || field?.isDisabled,
32
+ readOnly: isReadOnly || field?.isReadOnly,
33
+ required: isRequired || field?.isRequired,
34
+ 'aria-invalid': ariaAttr(isInvalid || field?.isInvalid),
35
+ 'aria-required': ariaAttr(isRequired || field?.isRequired),
36
+ 'aria-readonly': ariaAttr(isReadOnly || field?.isReadOnly),
37
+ 'aria-describedby': ariaDescribedBy || undefined
38
+ };
39
+ }
40
+ export const useFormControlContext = () => {
41
+ return React.useContext(FormControlContext);
42
+ };
43
+ //# sourceMappingURL=useFormControl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["React","ariaAttr","FormControlContext","createContext","useFormControl","props","field","useFormControlContext","describedBy","hasFeedbackText","feedbackId","push","hasHelpText","helpTextId","ariaDescribedBy","join","isInvalid","isDisabled","isReadOnly","isRequired","cleanProps","id","undefined","disabled","readOnly","required","useContext"],"sourceRoot":"../../../src","sources":["form-control/useFormControl.tsx"],"mappings":";;AAAA,OAAOA,KAAK,MAAM,OAAO;AACzB,SAASC,QAAQ,QAAQ,8BAA8B;AAqBvD,OAAO,MAAMC,kBAAkB,gBAAGF,KAAK,CAACG,aAAa,CAAmC,CAAC,CAAC,CAAC;AAM3F;AACA;AACA;AACA;AACA,OAAO,SAASC,cAAcA,CAACC,KAA4B,EAAE;EAC3D,MAAMC,KAAK,GAAGC,qBAAqB,CAAC,CAAC;EACrC,MAAMC,WAAqB,GAAG,EAAE;EAEhC,IAAIF,KAAK,EAAEG,eAAe,IAAIH,KAAK,CAACI,UAAU,EAAE;IAC9CF,WAAW,CAACG,IAAI,CAACL,KAAK,CAACI,UAAU,CAAC;EACpC;EACA,IAAIJ,KAAK,EAAEM,WAAW,IAAIN,KAAK,CAACO,UAAU,EAAE;IAC1CL,WAAW,CAACG,IAAI,CAACL,KAAK,CAACO,UAAU,CAAC;EACpC;EACA,MAAMC,eAAe,GAAGN,WAAW,CAACO,IAAI,CAAC,GAAG,CAAC;EAE7C,MAAM;IAAEC,SAAS;IAAEC,UAAU;IAAEC,UAAU;IAAEC,UAAU;IAAE,GAAGC;EAAW,CAAC,GAAGf,KAAK;EAC9E,MAAMgB,EAAE,GAAGhB,KAAK,CAACgB,EAAE,KAAKf,KAAK,EAAEe,EAAE,GAAG,GAAGf,KAAK,CAACe,EAAE,QAAQ,GAAGC,SAAS,CAAC;EAEpE,OAAO;IACL,GAAGF,UAAU;IACbC,EAAE;IACFE,QAAQ,EAAEN,UAAU,IAAIX,KAAK,EAAEW,UAAU;IACzCO,QAAQ,EAAEN,UAAU,IAAIZ,KAAK,EAAEY,UAAU;IACzCO,QAAQ,EAAEN,UAAU,IAAIb,KAAK,EAAEa,UAAU;IACzC,cAAc,EAAElB,QAAQ,CAACe,SAAS,IAAIV,KAAK,EAAEU,SAAS,CAAC;IACvD,eAAe,EAAEf,QAAQ,CAACkB,UAAU,IAAIb,KAAK,EAAEa,UAAU,CAAC;IAC1D,eAAe,EAAElB,QAAQ,CAACiB,UAAU,IAAIZ,KAAK,EAAEY,UAAU,CAAC;IAC1D,kBAAkB,EAAEJ,eAAe,IAAIQ;EACzC,CAAC;AACH;AAEA,OAAO,MAAMf,qBAAqB,GAAGA,CAAA,KAAM;EACzC,OAAOP,KAAK,CAAC0B,UAAU,CAACxB,kBAAkB,CAAC;AAC7C,CAAC","ignoreList":[]}
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+
3
+ export * from './common';
4
+ export * from './context';
5
+ export * from './form-control';
6
+ export * from './style';
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":[],"sourceRoot":"../../src","sources":["index.ts"],"mappings":";;AAAA,cAAc,UAAU;AACxB,cAAc,WAAW;AACzB,cAAc,gBAAgB;AAC9B,cAAc,SAAS","ignoreList":[]}
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+
3
+ import { createContext, useContext } from 'react';
4
+ export const ParentContext = /*#__PURE__*/createContext({});
5
+ export const useParentContext = () => {
6
+ return useContext(ParentContext);
7
+ };
8
+ export const useStyleContext = (scope = 'Global') => {
9
+ const parentContextValues = useParentContext();
10
+ return parentContextValues[scope];
11
+ };
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["createContext","useContext","ParentContext","useParentContext","useStyleContext","scope","parentContextValues"],"sourceRoot":"../../../../src","sources":["style/context/index.tsx"],"mappings":";;AAAA,SAASA,aAAa,EAAEC,UAAU,QAAQ,OAAO;AAIjD,OAAO,MAAMC,aAAa,gBAAGF,aAAa,CAAkB,CAAC,CAAC,CAAC;AAE/D,OAAO,MAAMG,gBAAgB,GAAGA,CAAA,KAAuB;EACrD,OAAOF,UAAU,CAACC,aAAa,CAAC;AAClC,CAAC;AAED,OAAO,MAAME,eAAe,GAAGA,CAACC,KAAK,GAAG,QAAQ,KAAK;EACnD,MAAMC,mBAAmB,GAAGH,gBAAgB,CAAC,CAAC;EAC9C,OAAOG,mBAAmB,CAACD,KAAK,CAAC;AACnC,CAAC","ignoreList":[]}
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+
3
+ export * from './context';
4
+ export * from './withStyleContext';
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":[],"sourceRoot":"../../../src","sources":["style/index.tsx"],"mappings":";;AAAA,cAAc,WAAW;AACzB,cAAc,oBAAoB","ignoreList":[]}
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+
3
+ import { forwardRef, useMemo } from 'react';
4
+ import { ParentContext, useParentContext } from '../context';
5
+ import { jsx as _jsx } from "react/jsx-runtime";
6
+ export const withStyleContext = (Component, scope = 'Global') => {
7
+ const Wrapped = /*#__PURE__*/forwardRef(({
8
+ context,
9
+ ...props
10
+ }, ref) => {
11
+ const parentContextValues = useParentContext();
12
+ const contextValues = useMemo(() => {
13
+ return {
14
+ ...parentContextValues,
15
+ [scope]: context
16
+ };
17
+ }, [parentContextValues, context]);
18
+ return /*#__PURE__*/_jsx(ParentContext.Provider, {
19
+ value: contextValues,
20
+ children: /*#__PURE__*/_jsx(Component, {
21
+ ...props,
22
+ ref: ref
23
+ })
24
+ });
25
+ });
26
+ return Wrapped;
27
+ };
28
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["forwardRef","useMemo","ParentContext","useParentContext","jsx","_jsx","withStyleContext","Component","scope","Wrapped","context","props","ref","parentContextValues","contextValues","Provider","value","children"],"sourceRoot":"../../../../src","sources":["style/withStyleContext/index.tsx"],"mappings":";;AAAA,SAMEA,UAAU,EACVC,OAAO,QACF,OAAO;AACd,SAASC,aAAa,EAAwBC,gBAAgB,QAAQ,YAAY;AAAC,SAAAC,GAAA,IAAAC,IAAA;AAMnF,OAAO,MAAMC,gBAAgB,GAAGA,CAAwBC,SAAY,EAAEC,KAAK,GAAG,QAAQ,KAAK;EAIzF,MAAMC,OAAO,gBAAGT,UAAU,CAAa,CAAC;IAAEU,OAAO;IAAE,GAAGC;EAAM,CAAC,EAAEC,GAAG,KAAK;IACrE,MAAMC,mBAAmB,GAAGV,gBAAgB,CAAC,CAAC;IAE9C,MAAMW,aAA8B,GAAGb,OAAO,CAAC,MAAM;MACnD,OAAO;QAAE,GAAGY,mBAAmB;QAAE,CAACL,KAAK,GAAGE;MAAQ,CAAC;IACrD,CAAC,EAAE,CAACG,mBAAmB,EAAEH,OAAO,CAAC,CAAC;IAElC,oBACEL,IAAA,CAACH,aAAa,CAACa,QAAQ;MAACC,KAAK,EAAEF,aAAc;MAAAG,QAAA,eAE3CZ,IAAA,CAACE,SAAS;QAAA,GAAKI,KAAK;QAAEC,GAAG,EAAEA;MAAI,CAAE;IAAC,CACZ,CAAC;EAE7B,CAAC,CAAC;EAEF,OAAOH,OAAO;AAChB,CAAC","ignoreList":[]}
@@ -0,0 +1,2 @@
1
+ export declare const ariaAttr: (condition: boolean | undefined) => true | undefined;
2
+ //# sourceMappingURL=accessibilityUtils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accessibilityUtils.d.ts","sourceRoot":"","sources":["../../../src/common/accessibilityUtils.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,QAAQ,GAAI,WAAW,OAAO,GAAG,SAAS,qBAAmC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { type ClassValue } from 'clsx';
2
+ export declare function cn(...inputs: ClassValue[]): string;
3
+ //# sourceMappingURL=cn.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cn.d.ts","sourceRoot":"","sources":["../../../src/common/cn.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,UAAU,EAAQ,MAAM,MAAM,CAAC;AAG7C,wBAAgB,EAAE,CAAC,GAAG,MAAM,EAAE,UAAU,EAAE,UAEzC"}
@@ -0,0 +1,2 @@
1
+ export declare function composeEventHandlers<E>(...args: (null | undefined | ((event: E) => void))[]): (event: E) => void;
2
+ //# sourceMappingURL=composeEventHandlers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"composeEventHandlers.d.ts","sourceRoot":"","sources":["../../../src/common/composeEventHandlers.ts"],"names":[],"mappings":"AAAA,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,CAAC,IAAI,GAAG,SAAS,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC,CAAC,EAAE,IAC9D,OAAO,CAAC,UAKrC"}
@@ -0,0 +1,5 @@
1
+ import React from 'react';
2
+ type ReactChildArray = ReturnType<typeof React.Children.toArray>;
3
+ export declare function flattenChildren(children: React.ReactNode, keys?: (string | number)[]): ReactChildArray;
4
+ export {};
5
+ //# sourceMappingURL=getSpacedChild.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getSpacedChild.d.ts","sourceRoot":"","sources":["../../../src/common/getSpacedChild.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,KAAK,eAAe,GAAG,UAAU,CAAC,OAAO,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;AAIjE,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,KAAK,CAAC,SAAS,EACzB,IAAI,GAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAO,GAC7B,eAAe,CAsBjB"}
@@ -0,0 +1,7 @@
1
+ export { ariaAttr } from './accessibilityUtils';
2
+ export { cn } from './cn';
3
+ export { composeEventHandlers } from './composeEventHandlers';
4
+ export { flattenChildren } from './getSpacedChild';
5
+ export { mergeRefs } from './mergeRefs';
6
+ export { type UseControllableStateParams, useControllableState } from './useControllableState';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/common/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,EAAE,EAAE,MAAM,MAAM,CAAC;AAC1B,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,KAAK,0BAA0B,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Ref, RefCallback } from 'react';
2
+ export declare function mergeRefs<T>(...refs: (Ref<T> | undefined)[]): RefCallback<T>;
3
+ //# sourceMappingURL=mergeRefs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mergeRefs.d.ts","sourceRoot":"","sources":["../../../src/common/mergeRefs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAE9C,wBAAgB,SAAS,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,EAAE,GAAG,WAAW,CAAC,CAAC,CAAC,CAU5E"}
@@ -0,0 +1,8 @@
1
+ export interface UseControllableStateParams<T> {
2
+ prop?: T | undefined;
3
+ defaultProp?: T | undefined;
4
+ onChange?: (state: T) => void;
5
+ }
6
+ declare function useControllableState<T>({ prop, defaultProp, onChange, }: UseControllableStateParams<T>): readonly [T | undefined, import("react").Dispatch<import("react").SetStateAction<T | undefined>>];
7
+ export { useControllableState };
8
+ //# sourceMappingURL=useControllableState.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useControllableState.d.ts","sourceRoot":"","sources":["../../../src/common/useControllableState.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,0BAA0B,CAAC,CAAC;IAC3C,IAAI,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC;IACrB,WAAW,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC;IAC5B,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;CAC/B;AAID,iBAAS,oBAAoB,CAAC,CAAC,EAAE,EAC/B,IAAI,EACJ,WAAW,EACX,QAAmB,GACpB,EAAE,0BAA0B,CAAC,CAAC,CAAC,qGAoB/B;AAoCD,OAAO,EAAE,oBAAoB,EAAE,CAAC"}
@@ -0,0 +1,6 @@
1
+ import { type ReactNode } from 'react';
2
+ export declare function createContext<T>(displayName: string): readonly [import("react").FunctionComponent<{
3
+ children: ReactNode;
4
+ value: T;
5
+ }>, () => T];
6
+ //# sourceMappingURL=createContext.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createContext.d.ts","sourceRoot":"","sources":["../../../src/context/createContext.tsx"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,SAAS,EAEf,MAAM,OAAO,CAAC;AAEf,wBAAgB,aAAa,CAAC,CAAC,EAAE,WAAW,EAAE,MAAM;cAGR,SAAS;WAAS,CAAC;UAO5C,CAAC,EASnB"}
@@ -0,0 +1,2 @@
1
+ export { createContext } from './createContext';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/context/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { type FormControlContextValue, type FormControlFieldProps, type FormControlState, FormControlContext, useFormControl, useFormControlContext, } from './useFormControl';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/form-control/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,uBAAuB,EAC5B,KAAK,qBAAqB,EAC1B,KAAK,gBAAgB,EACrB,kBAAkB,EAClB,cAAc,EACd,qBAAqB,GACtB,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,38 @@
1
+ import React from 'react';
2
+ type HTMLProps = Record<string, unknown>;
3
+ export interface FormControlState {
4
+ isRequired: boolean;
5
+ isInvalid: boolean;
6
+ isDisabled: boolean;
7
+ isReadOnly: boolean;
8
+ }
9
+ export interface FormControlContextValue extends FormControlState {
10
+ hasFeedbackText: boolean;
11
+ hasHelpText: boolean;
12
+ id: string;
13
+ labelId: string;
14
+ feedbackId: string;
15
+ helpTextId: string;
16
+ htmlProps: HTMLProps;
17
+ }
18
+ export declare const FormControlContext: React.Context<Partial<FormControlContextValue>>;
19
+ export interface FormControlFieldProps extends Partial<FormControlState> {
20
+ id?: string;
21
+ }
22
+ /**
23
+ * Hook that merges local field props with the nearest FormControl context
24
+ * and returns normalised HTML / ARIA attributes for input elements.
25
+ */
26
+ export declare function useFormControl(props: FormControlFieldProps): {
27
+ id: string | undefined;
28
+ disabled: boolean | undefined;
29
+ readOnly: boolean | undefined;
30
+ required: boolean | undefined;
31
+ 'aria-invalid': boolean | undefined;
32
+ 'aria-required': boolean | undefined;
33
+ 'aria-readonly': boolean | undefined;
34
+ 'aria-describedby': string | undefined;
35
+ };
36
+ export declare const useFormControlContext: () => Partial<FormControlContextValue>;
37
+ export {};
38
+ //# sourceMappingURL=useFormControl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useFormControl.d.ts","sourceRoot":"","sources":["../../../src/form-control/useFormControl.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,KAAK,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEzC,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,uBAAwB,SAAQ,gBAAgB;IAC/D,eAAe,EAAE,OAAO,CAAC;IACzB,WAAW,EAAE,OAAO,CAAC;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,SAAS,CAAC;CACtB;AAED,eAAO,MAAM,kBAAkB,iDAA4D,CAAC;AAE5F,MAAM,WAAW,qBAAsB,SAAQ,OAAO,CAAC,gBAAgB,CAAC;IACtE,EAAE,CAAC,EAAE,MAAM,CAAC;CACb;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,qBAAqB;;;;;;;;;EA0B1D;AAED,eAAO,MAAM,qBAAqB,wCAEjC,CAAC"}
@@ -0,0 +1,5 @@
1
+ export * from './common';
2
+ export * from './context';
3
+ export * from './form-control';
4
+ export * from './style';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,SAAS,CAAC"}
@@ -0,0 +1,5 @@
1
+ export type StyleContextMap = Record<string, unknown>;
2
+ export declare const ParentContext: import("react").Context<StyleContextMap>;
3
+ export declare const useParentContext: () => StyleContextMap;
4
+ export declare const useStyleContext: (scope?: string) => Record<string, unknown>;
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/style/context/index.tsx"],"names":[],"mappings":"AAEA,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEtD,eAAO,MAAM,aAAa,0CAAqC,CAAC;AAEhE,eAAO,MAAM,gBAAgB,QAAO,eAEnC,CAAC;AAEF,eAAO,MAAM,eAAe,GAAI,cAAgB,KAET,MAAM,CAAC,MAAM,EAAE,OAAO,CAC5D,CAAC"}
@@ -0,0 +1,3 @@
1
+ export * from './context';
2
+ export * from './withStyleContext';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/style/index.tsx"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,cAAc,oBAAoB,CAAC"}
@@ -0,0 +1,6 @@
1
+ import { type ComponentPropsWithoutRef, type ComponentRef, type ElementType, type ForwardRefExoticComponent, type RefAttributes } from 'react';
2
+ export interface WithStyleContextProps {
3
+ context?: Record<string, unknown>;
4
+ }
5
+ export declare const withStyleContext: <T extends ElementType>(Component: T, scope?: string) => ForwardRefExoticComponent<(ComponentPropsWithoutRef<T> & WithStyleContextProps) & RefAttributes<ComponentRef<T>>>;
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/style/withStyleContext/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,wBAAwB,EAC7B,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,yBAAyB,EAC9B,KAAK,aAAa,EAGnB,MAAM,OAAO,CAAC;AAGf,MAAM,WAAW,qBAAqB;IACpC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED,eAAO,MAAM,gBAAgB,GAAI,CAAC,SAAS,WAAW,EAAE,WAAW,CAAC,EAAE,cAAgB,KAmBlE,yBAAyB,CAAC,wDAAQ,aAAa,iBAAK,CACvE,CAAC"}
package/package.json ADDED
@@ -0,0 +1,65 @@
1
+ {
2
+ "name": "@cdx-ui/utils",
3
+ "version": "0.0.1-alpha.1",
4
+ "main": "lib/commonjs/index.js",
5
+ "module": "lib/module/index.js",
6
+ "react-native": "src/index.ts",
7
+ "types": "lib/typescript/index.d.ts",
8
+ "source": "src/index.ts",
9
+ "exports": {
10
+ ".": {
11
+ "react-native": "./src/index.ts",
12
+ "source": "./src/index.ts",
13
+ "types": "./lib/typescript/index.d.ts",
14
+ "import": "./lib/module/index.js",
15
+ "require": "./lib/commonjs/index.js",
16
+ "default": "./lib/module/index.js"
17
+ }
18
+ },
19
+ "files": [
20
+ "lib",
21
+ "src"
22
+ ],
23
+ "react-native-builder-bob": {
24
+ "source": "src",
25
+ "output": "lib",
26
+ "targets": [
27
+ "commonjs",
28
+ "module",
29
+ "typescript"
30
+ ]
31
+ },
32
+ "dependencies": {
33
+ "clsx": "2.1.1",
34
+ "tailwind-merge": "3.5.0"
35
+ },
36
+ "peerDependencies": {
37
+ "react": ">=18.0.0",
38
+ "react-native": ">=0.74.0",
39
+ "react-native-web": ">=0.19.0"
40
+ },
41
+ "devDependencies": {
42
+ "@types/react": "*",
43
+ "@types/react-dom": "*",
44
+ "react": "*",
45
+ "react-dom": "*",
46
+ "react-native": "*",
47
+ "react-native-builder-bob": "*",
48
+ "react-native-web": "*",
49
+ "typescript": "*"
50
+ },
51
+ "nx": {
52
+ "tags": [
53
+ "type:lib",
54
+ "scope:utils"
55
+ ]
56
+ },
57
+ "sideEffects": false,
58
+ "publishConfig": {
59
+ "access": "public"
60
+ },
61
+ "scripts": {
62
+ "build": "bob build",
63
+ "lint": "eslint src/"
64
+ }
65
+ }
@@ -0,0 +1 @@
1
+ export const ariaAttr = (condition: boolean | undefined) => (condition ? true : undefined);
@@ -0,0 +1,6 @@
1
+ import { type ClassValue, clsx } from 'clsx';
2
+ import { twMerge } from 'tailwind-merge';
3
+
4
+ export function cn(...inputs: ClassValue[]) {
5
+ return twMerge(clsx(inputs));
6
+ }
@@ -0,0 +1,7 @@
1
+ export function composeEventHandlers<E>(...args: (null | undefined | ((event: E) => void))[]) {
2
+ return function handleEvent(event: E) {
3
+ for (let i = 0; i < args.length; i++) {
4
+ args[i]?.(event);
5
+ }
6
+ };
7
+ }
@@ -0,0 +1,32 @@
1
+ import React from 'react';
2
+
3
+ type ReactChildArray = ReturnType<typeof React.Children.toArray>;
4
+
5
+ // TODO: Rename file
6
+
7
+ export function flattenChildren(
8
+ children: React.ReactNode,
9
+ keys: (string | number)[] = [],
10
+ ): ReactChildArray {
11
+ const childrenArray = React.Children.toArray(children);
12
+ return childrenArray.reduce((flatChildren: ReactChildArray, child, index: number) => {
13
+ if (
14
+ React.isValidElement<{ children?: React.ReactNode }>(child) &&
15
+ child.type === React.Fragment
16
+ ) {
17
+ return flatChildren.concat(
18
+ flattenChildren(child.props.children, keys.concat(child.key || index)),
19
+ );
20
+ }
21
+ if (React.isValidElement(child)) {
22
+ flatChildren.push(
23
+ React.cloneElement(child, {
24
+ key: keys.concat(String(child.key || index)).join('.'),
25
+ }),
26
+ );
27
+ } else {
28
+ flatChildren.push(child);
29
+ }
30
+ return flatChildren;
31
+ }, []);
32
+ }
@@ -0,0 +1,6 @@
1
+ export { ariaAttr } from './accessibilityUtils';
2
+ export { cn } from './cn';
3
+ export { composeEventHandlers } from './composeEventHandlers';
4
+ export { flattenChildren } from './getSpacedChild';
5
+ export { mergeRefs } from './mergeRefs';
6
+ export { type UseControllableStateParams, useControllableState } from './useControllableState';
@@ -0,0 +1,13 @@
1
+ import type { Ref, RefCallback } from 'react';
2
+
3
+ export function mergeRefs<T>(...refs: (Ref<T> | undefined)[]): RefCallback<T> {
4
+ return (value: T | null) => {
5
+ for (const ref of refs) {
6
+ if (typeof ref === 'function') {
7
+ ref(value);
8
+ } else if (ref != null) {
9
+ ref.current = value;
10
+ }
11
+ }
12
+ };
13
+ }