@zentauri-ui/zentauri-components 1.9.2 → 2.0.0
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.
- package/CHANGELOG.md +17 -0
- package/README.md +32 -5
- package/cli/registry.json +14 -0
- package/dist/{chunk-L4PDJ6IB.mjs → chunk-44NX3DAZ.mjs} +3 -3
- package/dist/{chunk-L4PDJ6IB.mjs.map → chunk-44NX3DAZ.mjs.map} +1 -1
- package/dist/chunk-FAMHSJTK.js +19 -0
- package/dist/{chunk-AQHY4S33.js.map → chunk-FAMHSJTK.js.map} +1 -1
- package/dist/chunk-I42UYWYA.mjs +128 -0
- package/dist/chunk-I42UYWYA.mjs.map +1 -0
- package/dist/{chunk-5J6QMTES.js → chunk-IKXO5SJ4.js} +21 -5
- package/dist/chunk-IKXO5SJ4.js.map +1 -0
- package/dist/{chunk-OPUO55TO.mjs → chunk-JXSM2EHC.mjs} +3 -3
- package/dist/{chunk-OPUO55TO.mjs.map → chunk-JXSM2EHC.mjs.map} +1 -1
- package/dist/{chunk-LQPKZ5ZD.js → chunk-LS4GY2ZQ.js} +6 -6
- package/dist/{chunk-LQPKZ5ZD.js.map → chunk-LS4GY2ZQ.js.map} +1 -1
- package/dist/{chunk-VIKQGO4W.mjs → chunk-VQQHVKEU.mjs} +21 -5
- package/dist/{chunk-VIKQGO4W.mjs.map → chunk-VQQHVKEU.mjs.map} +1 -1
- package/dist/chunk-ZVRGLG35.js +144 -0
- package/dist/chunk-ZVRGLG35.js.map +1 -0
- package/dist/design-system/combobox.d.ts +124 -0
- package/dist/design-system/combobox.d.ts.map +1 -0
- package/dist/design-system/facade.js +6 -5
- package/dist/design-system/facade.js.map +1 -1
- package/dist/design-system/facade.mjs +5 -4
- package/dist/design-system/facade.mjs.map +1 -1
- package/dist/design-system/index.d.ts +1 -0
- package/dist/design-system/index.d.ts.map +1 -1
- package/dist/hooks/index.d.ts +13 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/useCookie/index.d.ts +2 -0
- package/dist/hooks/useCookie/index.d.ts.map +1 -0
- package/dist/hooks/useCookie/useCookie.d.ts +36 -0
- package/dist/hooks/useCookie/useCookie.d.ts.map +1 -0
- package/dist/hooks/useCookie.js +82 -0
- package/dist/hooks/useCookie.js.map +1 -0
- package/dist/hooks/useCookie.mjs +80 -0
- package/dist/hooks/useCookie.mjs.map +1 -0
- package/dist/hooks/useCountdown/index.d.ts +2 -0
- package/dist/hooks/useCountdown/index.d.ts.map +1 -0
- package/dist/hooks/useCountdown/useCountdown.d.ts +40 -0
- package/dist/hooks/useCountdown/useCountdown.d.ts.map +1 -0
- package/dist/hooks/useCountdown.js +60 -0
- package/dist/hooks/useCountdown.js.map +1 -0
- package/dist/hooks/useCountdown.mjs +58 -0
- package/dist/hooks/useCountdown.mjs.map +1 -0
- package/dist/hooks/useEventListener/index.d.ts +2 -0
- package/dist/hooks/useEventListener/index.d.ts.map +1 -0
- package/dist/hooks/useEventListener/useEventListener.d.ts +22 -0
- package/dist/hooks/useEventListener/useEventListener.d.ts.map +1 -0
- package/dist/hooks/useEventListener.js +45 -0
- package/dist/hooks/useEventListener.js.map +1 -0
- package/dist/hooks/useEventListener.mjs +43 -0
- package/dist/hooks/useEventListener.mjs.map +1 -0
- package/dist/hooks/useGeolocation/index.d.ts +2 -0
- package/dist/hooks/useGeolocation/index.d.ts.map +1 -0
- package/dist/hooks/useGeolocation/useGeolocation.d.ts +48 -0
- package/dist/hooks/useGeolocation/useGeolocation.d.ts.map +1 -0
- package/dist/hooks/useGeolocation.js +111 -0
- package/dist/hooks/useGeolocation.js.map +1 -0
- package/dist/hooks/useGeolocation.mjs +109 -0
- package/dist/hooks/useGeolocation.mjs.map +1 -0
- package/dist/hooks/useHotkeys/index.d.ts +2 -0
- package/dist/hooks/useHotkeys/index.d.ts.map +1 -0
- package/dist/hooks/useHotkeys/useHotkeys.d.ts +24 -0
- package/dist/hooks/useHotkeys/useHotkeys.d.ts.map +1 -0
- package/dist/hooks/useHotkeys.js +86 -0
- package/dist/hooks/useHotkeys.js.map +1 -0
- package/dist/hooks/useHotkeys.mjs +84 -0
- package/dist/hooks/useHotkeys.mjs.map +1 -0
- package/dist/hooks/useIdleTimeout/index.d.ts +2 -0
- package/dist/hooks/useIdleTimeout/index.d.ts.map +1 -0
- package/dist/hooks/useIdleTimeout/useIdleTimeout.d.ts +31 -0
- package/dist/hooks/useIdleTimeout/useIdleTimeout.d.ts.map +1 -0
- package/dist/hooks/useIdleTimeout.js +77 -0
- package/dist/hooks/useIdleTimeout.js.map +1 -0
- package/dist/hooks/useIdleTimeout.mjs +75 -0
- package/dist/hooks/useIdleTimeout.mjs.map +1 -0
- package/dist/hooks/useInterval/index.d.ts +2 -0
- package/dist/hooks/useInterval/index.d.ts.map +1 -0
- package/dist/hooks/useInterval/useInterval.d.ts +12 -0
- package/dist/hooks/useInterval/useInterval.d.ts.map +1 -0
- package/dist/hooks/useInterval.js +27 -0
- package/dist/hooks/useInterval.js.map +1 -0
- package/dist/hooks/useInterval.mjs +25 -0
- package/dist/hooks/useInterval.mjs.map +1 -0
- package/dist/hooks/useKeyPress/index.d.ts +2 -0
- package/dist/hooks/useKeyPress/index.d.ts.map +1 -0
- package/dist/hooks/useKeyPress/useKeyPress.d.ts +15 -0
- package/dist/hooks/useKeyPress/useKeyPress.d.ts.map +1 -0
- package/dist/hooks/useKeyPress.js +47 -0
- package/dist/hooks/useKeyPress.js.map +1 -0
- package/dist/hooks/useKeyPress.mjs +45 -0
- package/dist/hooks/useKeyPress.mjs.map +1 -0
- package/dist/hooks/useLongPress/index.d.ts +2 -0
- package/dist/hooks/useLongPress/index.d.ts.map +1 -0
- package/dist/hooks/useLongPress/useLongPress.d.ts +46 -0
- package/dist/hooks/useLongPress/useLongPress.d.ts.map +1 -0
- package/dist/hooks/useLongPress.js +116 -0
- package/dist/hooks/useLongPress.js.map +1 -0
- package/dist/hooks/useLongPress.mjs +114 -0
- package/dist/hooks/useLongPress.mjs.map +1 -0
- package/dist/hooks/usePrevious/index.d.ts +2 -0
- package/dist/hooks/usePrevious/index.d.ts.map +1 -0
- package/dist/hooks/usePrevious/usePrevious.d.ts +13 -0
- package/dist/hooks/usePrevious/usePrevious.d.ts.map +1 -0
- package/dist/hooks/usePrevious.js +17 -0
- package/dist/hooks/usePrevious.js.map +1 -0
- package/dist/hooks/usePrevious.mjs +15 -0
- package/dist/hooks/usePrevious.mjs.map +1 -0
- package/dist/hooks/useScrollPosition/index.d.ts +2 -0
- package/dist/hooks/useScrollPosition/index.d.ts.map +1 -0
- package/dist/hooks/useScrollPosition/useScrollPosition.d.ts +37 -0
- package/dist/hooks/useScrollPosition/useScrollPosition.d.ts.map +1 -0
- package/dist/hooks/useScrollPosition.js +41 -0
- package/dist/hooks/useScrollPosition.js.map +1 -0
- package/dist/hooks/useScrollPosition.mjs +39 -0
- package/dist/hooks/useScrollPosition.mjs.map +1 -0
- package/dist/hooks/useTimeout/index.d.ts +2 -0
- package/dist/hooks/useTimeout/index.d.ts.map +1 -0
- package/dist/hooks/useTimeout/useTimeout.d.ts +19 -0
- package/dist/hooks/useTimeout/useTimeout.d.ts.map +1 -0
- package/dist/hooks/useTimeout.js +38 -0
- package/dist/hooks/useTimeout.js.map +1 -0
- package/dist/hooks/useTimeout.mjs +36 -0
- package/dist/hooks/useTimeout.mjs.map +1 -0
- package/dist/hooks/useVirtualList/index.d.ts +2 -0
- package/dist/hooks/useVirtualList/index.d.ts.map +1 -0
- package/dist/hooks/useVirtualList/useVirtualList.d.ts +47 -0
- package/dist/hooks/useVirtualList/useVirtualList.d.ts.map +1 -0
- package/dist/hooks/useVirtualList.js +87 -0
- package/dist/hooks/useVirtualList.js.map +1 -0
- package/dist/hooks/useVirtualList.mjs +85 -0
- package/dist/hooks/useVirtualList.mjs.map +1 -0
- package/dist/lib/facade.d.ts.map +1 -1
- package/dist/ui/buttons/animated.js +8 -7
- package/dist/ui/buttons/animated.js.map +1 -1
- package/dist/ui/buttons/animated.mjs +6 -5
- package/dist/ui/buttons/animated.mjs.map +1 -1
- package/dist/ui/buttons.js +9 -8
- package/dist/ui/buttons.mjs +7 -6
- package/dist/ui/combobox/combobox-base.d.ts +37 -0
- package/dist/ui/combobox/combobox-base.d.ts.map +1 -0
- package/dist/ui/combobox/combobox.d.ts +6 -0
- package/dist/ui/combobox/combobox.d.ts.map +1 -0
- package/dist/ui/combobox/index.d.ts +4 -0
- package/dist/ui/combobox/index.d.ts.map +1 -0
- package/dist/ui/combobox/types.d.ts +70 -0
- package/dist/ui/combobox/types.d.ts.map +1 -0
- package/dist/ui/combobox/variants.d.ts +17 -0
- package/dist/ui/combobox/variants.d.ts.map +1 -0
- package/dist/ui/combobox.js +510 -0
- package/dist/ui/combobox.js.map +1 -0
- package/dist/ui/combobox.mjs +495 -0
- package/dist/ui/combobox.mjs.map +1 -0
- package/dist/ui/dynamic-stepper.js +18 -17
- package/dist/ui/dynamic-stepper.js.map +1 -1
- package/dist/ui/dynamic-stepper.mjs +7 -6
- package/dist/ui/dynamic-stepper.mjs.map +1 -1
- package/dist/ui/pagination.js +14 -13
- package/dist/ui/pagination.js.map +1 -1
- package/dist/ui/pagination.mjs +6 -5
- package/dist/ui/pagination.mjs.map +1 -1
- package/package.json +1 -1
- package/src/design-system/combobox.ts +204 -0
- package/src/design-system/index.ts +1 -0
- package/src/hooks/index.ts +50 -0
- package/src/hooks/useCookie/index.ts +5 -0
- package/src/hooks/useCookie/useCookie.test.ts +57 -0
- package/src/hooks/useCookie/useCookie.ts +133 -0
- package/src/hooks/useCountdown/index.ts +5 -0
- package/src/hooks/useCountdown/useCountdown.test.ts +113 -0
- package/src/hooks/useCountdown/useCountdown.ts +106 -0
- package/src/hooks/useEventListener/index.ts +4 -0
- package/src/hooks/useEventListener/useEventListener.test.ts +60 -0
- package/src/hooks/useEventListener/useEventListener.ts +98 -0
- package/src/hooks/useGeolocation/index.ts +6 -0
- package/src/hooks/useGeolocation/useGeolocation.test.ts +108 -0
- package/src/hooks/useGeolocation/useGeolocation.ts +173 -0
- package/src/hooks/useHotkeys/index.ts +5 -0
- package/src/hooks/useHotkeys/useHotkeys.test.ts +82 -0
- package/src/hooks/useHotkeys/useHotkeys.ts +130 -0
- package/src/hooks/useIdleTimeout/index.ts +5 -0
- package/src/hooks/useIdleTimeout/useIdleTimeout.test.ts +97 -0
- package/src/hooks/useIdleTimeout/useIdleTimeout.ts +111 -0
- package/src/hooks/useInterval/index.ts +1 -0
- package/src/hooks/useInterval/useInterval.test.ts +56 -0
- package/src/hooks/useInterval/useInterval.ts +36 -0
- package/src/hooks/useKeyPress/index.ts +1 -0
- package/src/hooks/useKeyPress/useKeyPress.test.ts +67 -0
- package/src/hooks/useKeyPress/useKeyPress.ts +65 -0
- package/src/hooks/useLongPress/index.ts +5 -0
- package/src/hooks/useLongPress/useLongPress.test.ts +180 -0
- package/src/hooks/useLongPress/useLongPress.ts +177 -0
- package/src/hooks/usePrevious/index.ts +1 -0
- package/src/hooks/usePrevious/usePrevious.test.ts +33 -0
- package/src/hooks/usePrevious/usePrevious.ts +24 -0
- package/src/hooks/useScrollPosition/index.ts +5 -0
- package/src/hooks/useScrollPosition/useScrollPosition.test.ts +69 -0
- package/src/hooks/useScrollPosition/useScrollPosition.ts +88 -0
- package/src/hooks/useTimeout/index.ts +1 -0
- package/src/hooks/useTimeout/useTimeout.test.ts +63 -0
- package/src/hooks/useTimeout/useTimeout.ts +58 -0
- package/src/hooks/useVirtualList/index.ts +6 -0
- package/src/hooks/useVirtualList/useVirtualList.test.ts +102 -0
- package/src/hooks/useVirtualList/useVirtualList.ts +144 -0
- package/src/lib/facade.test.ts +7 -7
- package/src/lib/facade.ts +6 -2
- package/src/ui/combobox/combobox-base.tsx +552 -0
- package/src/ui/combobox/combobox.test.tsx +292 -0
- package/src/ui/combobox/combobox.tsx +8 -0
- package/src/ui/combobox/index.ts +33 -0
- package/src/ui/combobox/types.ts +91 -0
- package/src/ui/combobox/variants.ts +58 -0
- package/dist/chunk-5J6QMTES.js.map +0 -1
- package/dist/chunk-AQHY4S33.js +0 -19
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
export const zuiComboboxTriggerBase =
|
|
2
|
+
"flex items-center cursor-pointer justify-between rounded-md border transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--zui-combobox-trigger-ring-focus,oklch(44.6%_0.03_256.802))] dark:focus-visible:ring-[var(--zui-combobox-trigger-ring-focus-dark,oklch(70.7%_0.022_261.325))] focus-visible:ring-offset-2";
|
|
3
|
+
|
|
4
|
+
export const zuiComboboxTriggerVariants = {
|
|
5
|
+
default:
|
|
6
|
+
"border-[color:var(--zui-combobox-trigger-default-border,oklch(87.2%_0.01_258.338))] dark:border-[color:var(--zui-combobox-trigger-default-border-dark,oklch(87.2%_0.01_258.338))] bg-[var(--zui-combobox-trigger-default-bg,#ffffff)] dark:bg-[var(--zui-combobox-trigger-default-bg-dark,#000000)] text-[color:var(--zui-combobox-trigger-default-fg,oklch(13%_0.028_261.692))] dark:text-[color:var(--zui-combobox-trigger-default-fg-dark,#ffffff)]",
|
|
7
|
+
outline:
|
|
8
|
+
"border-2 border-[color:var(--zui-combobox-trigger-outline-border,oklch(55.1%_0.027_264.364))] dark:border-[color:var(--zui-combobox-trigger-outline-border-dark,oklch(55.1%_0.027_264.364))] text-[color:var(--zui-combobox-trigger-outline-fg,oklch(13%_0.028_261.692))] dark:text-[color:var(--zui-combobox-trigger-outline-fg-dark,oklch(96.7%_0.003_264.542))]",
|
|
9
|
+
ghost:
|
|
10
|
+
"border-[color:var(--zui-combobox-trigger-ghost-border,transparent)] dark:border-[color:var(--zui-combobox-trigger-ghost-border-dark,transparent)] text-[color:var(--zui-combobox-trigger-ghost-fg,oklch(13%_0.028_261.692))] dark:text-[color:var(--zui-combobox-trigger-ghost-fg-dark,oklch(96.7%_0.003_264.542))]",
|
|
11
|
+
sky: "border-[color:var(--zui-combobox-trigger-sky-border,oklch(44.3%_0.11_240.79))] dark:border-[color:var(--zui-combobox-trigger-sky-border-dark,oklch(58.8%_0.158_241.966))] text-[color:var(--zui-combobox-trigger-sky-fg,oklch(29.3%_0.066_243.157))] dark:text-[color:var(--zui-combobox-trigger-sky-fg-dark,oklch(58.8%_0.158_241.966))]",
|
|
12
|
+
rose: "border-[color:var(--zui-combobox-trigger-rose-border,oklch(45.5%_0.188_13.697))] dark:border-[color:var(--zui-combobox-trigger-rose-border-dark,oklch(58.6%_0.253_17.585))] text-[color:var(--zui-combobox-trigger-rose-fg,oklch(27.1%_0.105_12.094))] dark:text-[color:var(--zui-combobox-trigger-rose-fg-dark,oklch(58.6%_0.253_17.585))]",
|
|
13
|
+
purple:
|
|
14
|
+
"border-[color:var(--zui-combobox-trigger-purple-border,oklch(43.8%_0.218_303.724))] dark:border-[color:var(--zui-combobox-trigger-purple-border-dark,oklch(55.8%_0.288_302.321))] text-[color:var(--zui-combobox-trigger-purple-fg,oklch(29.1%_0.149_302.717))] dark:text-[color:var(--zui-combobox-trigger-purple-fg-dark,oklch(55.8%_0.288_302.321))]",
|
|
15
|
+
pink: "border-[color:var(--zui-combobox-trigger-pink-border,oklch(45.9%_0.187_3.815))] dark:border-[color:var(--zui-combobox-trigger-pink-border-dark,oklch(59.2%_0.249_0.584))] text-[color:var(--zui-combobox-trigger-pink-fg,oklch(28.4%_0.109_3.907))] dark:text-[color:var(--zui-combobox-trigger-pink-fg-dark,oklch(59.2%_0.249_0.584))]",
|
|
16
|
+
orange:
|
|
17
|
+
"border-[color:var(--zui-combobox-trigger-orange-border,oklch(47%_0.157_37.304))] dark:border-[color:var(--zui-combobox-trigger-orange-border-dark,oklch(64.6%_0.222_41.116))] text-[color:var(--zui-combobox-trigger-orange-fg,oklch(26.6%_0.079_36.259))] dark:text-[color:var(--zui-combobox-trigger-orange-fg-dark,oklch(64.6%_0.222_41.116))]",
|
|
18
|
+
yellow:
|
|
19
|
+
"border-[color:var(--zui-combobox-trigger-yellow-border,oklch(47.6%_0.114_61.907))] dark:border-[color:var(--zui-combobox-trigger-yellow-border-dark,oklch(68.1%_0.162_75.834))] text-[color:var(--zui-combobox-trigger-yellow-fg,oklch(28.6%_0.066_53.813))] dark:text-[color:var(--zui-combobox-trigger-yellow-fg-dark,oklch(68.1%_0.162_75.834))]",
|
|
20
|
+
teal: "border-[color:var(--zui-combobox-trigger-teal-border,oklch(43.7%_0.078_188.216))] dark:border-[color:var(--zui-combobox-trigger-teal-border-dark,oklch(60%_0.118_184.704))] text-[color:var(--zui-combobox-trigger-teal-fg,oklch(27.7%_0.046_192.524))] dark:text-[color:var(--zui-combobox-trigger-teal-fg-dark,oklch(60%_0.118_184.704))]",
|
|
21
|
+
indigo:
|
|
22
|
+
"border-[color:var(--zui-combobox-trigger-indigo-border,oklch(58.5%_0.233_277.117))] dark:border-[color:var(--zui-combobox-trigger-indigo-border-dark,oklch(58.5%_0.233_277.117))] text-[color:var(--zui-combobox-trigger-indigo-fg,oklch(25.7%_0.09_281.288))] dark:text-[color:var(--zui-combobox-trigger-indigo-fg-dark,oklch(58.5%_0.233_277.117))]",
|
|
23
|
+
emerald:
|
|
24
|
+
"border-[color:var(--zui-combobox-trigger-emerald-border,oklch(43.2%_0.095_166.913))] dark:border-[color:var(--zui-combobox-trigger-emerald-border-dark,oklch(59.6%_0.145_163.225))] text-[color:var(--zui-combobox-trigger-emerald-fg,oklch(26.2%_0.051_172.552))] dark:text-[color:var(--zui-combobox-trigger-emerald-fg-dark,oklch(59.6%_0.145_163.225))]",
|
|
25
|
+
glass:
|
|
26
|
+
"border-[color:var(--zui-combobox-trigger-glass-border,#00000026)] dark:border-[color:var(--zui-combobox-trigger-glass-border-dark,#ffffff26)] bg-[var(--zui-combobox-trigger-glass-bg,#0000001a)] dark:bg-[var(--zui-combobox-trigger-glass-bg-dark,#ffffff1a)] text-[color:var(--zui-combobox-trigger-glass-fg,oklch(13%_0.028_261.692))] dark:text-[color:var(--zui-combobox-trigger-glass-fg-dark,#ffffff)] backdrop-blur-md",
|
|
27
|
+
"gradient-blue":
|
|
28
|
+
"bg-linear-to-r from-[var(--zui-combobox-trigger-gradient-blue-from,oklch(37.9%_0.146_265.522))] dark:from-[var(--zui-combobox-trigger-gradient-blue-from-dark,oklch(54.6%_0.245_262.881))] to-[var(--zui-combobox-trigger-gradient-blue-to,oklch(38.1%_0.176_304.987))] dark:to-[var(--zui-combobox-trigger-gradient-blue-to-dark,oklch(55.8%_0.288_302.321))] backdrop-blur-xl text-[color:var(--zui-combobox-trigger-gradient-blue-fg,#ffffff)] dark:text-[color:var(--zui-combobox-trigger-gradient-blue-fg-dark,#ffffff)]",
|
|
29
|
+
"gradient-green":
|
|
30
|
+
"bg-linear-to-r from-[var(--zui-combobox-trigger-gradient-green-from,oklch(39.3%_0.095_152.535))] dark:from-[var(--zui-combobox-trigger-gradient-green-from-dark,oklch(62.7%_0.194_149.214))] to-[var(--zui-combobox-trigger-gradient-green-to,oklch(40.5%_0.101_131.063))] dark:to-[var(--zui-combobox-trigger-gradient-green-to-dark,oklch(64.8%_0.2_131.684))] backdrop-blur-xl text-[color:var(--zui-combobox-trigger-gradient-green-fg,#ffffff)] dark:text-[color:var(--zui-combobox-trigger-gradient-green-fg-dark,#ffffff)]",
|
|
31
|
+
"gradient-red":
|
|
32
|
+
"bg-linear-to-r from-[var(--zui-combobox-trigger-gradient-red-from,oklch(39.6%_0.141_25.723))] dark:from-[var(--zui-combobox-trigger-gradient-red-from-dark,oklch(57.7%_0.245_27.325))] to-[var(--zui-combobox-trigger-gradient-red-to,oklch(40.8%_0.153_2.432))] dark:to-[var(--zui-combobox-trigger-gradient-red-to-dark,oklch(59.2%_0.249_0.584))] backdrop-blur-xl text-[color:var(--zui-combobox-trigger-gradient-red-fg,#ffffff)] dark:text-[color:var(--zui-combobox-trigger-gradient-red-fg-dark,#ffffff)]",
|
|
33
|
+
"gradient-yellow":
|
|
34
|
+
"bg-linear-to-r from-[var(--zui-combobox-trigger-gradient-yellow-from,oklch(42.1%_0.095_57.708))] dark:from-[var(--zui-combobox-trigger-gradient-yellow-from-dark,oklch(68.1%_0.162_75.834))] to-[var(--zui-combobox-trigger-gradient-yellow-to,oklch(40.8%_0.123_38.172))] dark:to-[var(--zui-combobox-trigger-gradient-yellow-to-dark,oklch(64.6%_0.222_41.116))] backdrop-blur-xl text-[color:var(--zui-combobox-trigger-gradient-yellow-fg,#ffffff)] dark:text-[color:var(--zui-combobox-trigger-gradient-yellow-fg-dark,#ffffff)]",
|
|
35
|
+
"gradient-purple":
|
|
36
|
+
"bg-linear-to-r from-[var(--zui-combobox-trigger-gradient-purple-from,oklch(38.1%_0.176_304.987))] dark:from-[var(--zui-combobox-trigger-gradient-purple-from-dark,oklch(55.8%_0.288_302.321))] to-[var(--zui-combobox-trigger-gradient-purple-to,oklch(40.8%_0.153_2.432))] dark:to-[var(--zui-combobox-trigger-gradient-purple-to-dark,oklch(59.2%_0.249_0.584))] backdrop-blur-xl text-[color:var(--zui-combobox-trigger-gradient-purple-fg,#ffffff)] dark:text-[color:var(--zui-combobox-trigger-gradient-purple-fg-dark,#ffffff)]",
|
|
37
|
+
"gradient-teal":
|
|
38
|
+
"bg-linear-to-r from-[var(--zui-combobox-trigger-gradient-teal-from,oklch(38.6%_0.063_188.416))] dark:from-[var(--zui-combobox-trigger-gradient-teal-from-dark,oklch(60%_0.118_184.704))] to-[var(--zui-combobox-trigger-gradient-teal-to,oklch(39.8%_0.07_227.392))] dark:to-[var(--zui-combobox-trigger-gradient-teal-to-dark,oklch(60.9%_0.126_221.723))] backdrop-blur-xl text-[color:var(--zui-combobox-trigger-gradient-teal-fg,#ffffff)] dark:text-[color:var(--zui-combobox-trigger-gradient-teal-fg-dark,#ffffff)]",
|
|
39
|
+
"gradient-indigo":
|
|
40
|
+
"bg-linear-to-r from-[var(--zui-combobox-trigger-gradient-indigo-from,oklch(35.9%_0.144_278.697))] dark:from-[var(--zui-combobox-trigger-gradient-indigo-from-dark,oklch(51.1%_0.262_276.966))] to-[var(--zui-combobox-trigger-gradient-indigo-to,oklch(38.1%_0.176_304.987))] dark:to-[var(--zui-combobox-trigger-gradient-indigo-to-dark,oklch(55.8%_0.288_302.321))] backdrop-blur-xl text-[color:var(--zui-combobox-trigger-gradient-indigo-fg,#ffffff)] dark:text-[color:var(--zui-combobox-trigger-gradient-indigo-fg-dark,#ffffff)]",
|
|
41
|
+
"gradient-pink":
|
|
42
|
+
"bg-linear-to-r from-[var(--zui-combobox-trigger-gradient-pink-from,oklch(40.8%_0.153_2.432))] dark:from-[var(--zui-combobox-trigger-gradient-pink-from-dark,oklch(59.2%_0.249_0.584))] to-[var(--zui-combobox-trigger-gradient-pink-to,oklch(41%_0.159_10.272))] dark:to-[var(--zui-combobox-trigger-gradient-pink-to-dark,oklch(58.6%_0.253_17.585))] backdrop-blur-xl text-[color:var(--zui-combobox-trigger-gradient-pink-fg,#ffffff)] dark:text-[color:var(--zui-combobox-trigger-gradient-pink-fg-dark,#ffffff)]",
|
|
43
|
+
"gradient-orange":
|
|
44
|
+
"bg-linear-to-r from-[var(--zui-combobox-trigger-gradient-orange-from,oklch(40.8%_0.123_38.172))] dark:from-[var(--zui-combobox-trigger-gradient-orange-from-dark,oklch(64.6%_0.222_41.116))] to-[var(--zui-combobox-trigger-gradient-orange-to,oklch(39.6%_0.141_25.723))] dark:to-[var(--zui-combobox-trigger-gradient-orange-to-dark,oklch(57.7%_0.245_27.325))] backdrop-blur-xl text-[color:var(--zui-combobox-trigger-gradient-orange-fg,#ffffff)] dark:text-[color:var(--zui-combobox-trigger-gradient-orange-fg-dark,#ffffff)]",
|
|
45
|
+
blue: "border border-[color:var(--zui-combobox-trigger-blue-border,#2563eb)] dark:border-[color:var(--zui-combobox-trigger-blue-border-dark,#3b82f6)] text-[color:var(--zui-combobox-trigger-blue-fg,#2563eb)] dark:text-[color:var(--zui-combobox-trigger-blue-fg-dark,#3b82f6)] hover:bg-[var(--zui-combobox-trigger-blue-bg-hover,#2563eb14)] dark:hover:bg-[var(--zui-combobox-trigger-blue-bg-hover-dark,#3b82f624)]",
|
|
46
|
+
cyan: "border border-[color:var(--zui-combobox-trigger-cyan-border,#0891b2)] dark:border-[color:var(--zui-combobox-trigger-cyan-border-dark,#22d3ee)] text-[color:var(--zui-combobox-trigger-cyan-fg,#0891b2)] dark:text-[color:var(--zui-combobox-trigger-cyan-fg-dark,#22d3ee)] hover:bg-[var(--zui-combobox-trigger-cyan-bg-hover,#0891b214)] dark:hover:bg-[var(--zui-combobox-trigger-cyan-bg-hover-dark,#22d3ee24)]",
|
|
47
|
+
green:
|
|
48
|
+
"border border-[color:var(--zui-combobox-trigger-green-border,#16a34a)] dark:border-[color:var(--zui-combobox-trigger-green-border-dark,#22c55e)] text-[color:var(--zui-combobox-trigger-green-fg,#16a34a)] dark:text-[color:var(--zui-combobox-trigger-green-fg-dark,#22c55e)] hover:bg-[var(--zui-combobox-trigger-green-bg-hover,#16a34a14)] dark:hover:bg-[var(--zui-combobox-trigger-green-bg-hover-dark,#22c55e24)]",
|
|
49
|
+
lime: "border border-[color:var(--zui-combobox-trigger-lime-border,#65a30d)] dark:border-[color:var(--zui-combobox-trigger-lime-border-dark,#a3e635)] text-[color:var(--zui-combobox-trigger-lime-fg,#65a30d)] dark:text-[color:var(--zui-combobox-trigger-lime-fg-dark,#a3e635)] hover:bg-[var(--zui-combobox-trigger-lime-bg-hover,#65a30d14)] dark:hover:bg-[var(--zui-combobox-trigger-lime-bg-hover-dark,#a3e63524)]",
|
|
50
|
+
mint: "border border-[color:var(--zui-combobox-trigger-mint-border,#10b981)] dark:border-[color:var(--zui-combobox-trigger-mint-border-dark,#6ee7b7)] text-[color:var(--zui-combobox-trigger-mint-fg,#10b981)] dark:text-[color:var(--zui-combobox-trigger-mint-fg-dark,#6ee7b7)] hover:bg-[var(--zui-combobox-trigger-mint-bg-hover,#10b98114)] dark:hover:bg-[var(--zui-combobox-trigger-mint-bg-hover-dark,#6ee7b724)]",
|
|
51
|
+
ocean:
|
|
52
|
+
"border border-[color:var(--zui-combobox-trigger-ocean-border,#0284c7)] dark:border-[color:var(--zui-combobox-trigger-ocean-border-dark,#38bdf8)] text-[color:var(--zui-combobox-trigger-ocean-fg,#0284c7)] dark:text-[color:var(--zui-combobox-trigger-ocean-fg-dark,#38bdf8)] hover:bg-[var(--zui-combobox-trigger-ocean-bg-hover,#0284c714)] dark:hover:bg-[var(--zui-combobox-trigger-ocean-bg-hover-dark,#38bdf824)]",
|
|
53
|
+
sapphire:
|
|
54
|
+
"border border-[color:var(--zui-combobox-trigger-sapphire-border,#1d4ed8)] dark:border-[color:var(--zui-combobox-trigger-sapphire-border-dark,#60a5fa)] text-[color:var(--zui-combobox-trigger-sapphire-fg,#1d4ed8)] dark:text-[color:var(--zui-combobox-trigger-sapphire-fg-dark,#60a5fa)] hover:bg-[var(--zui-combobox-trigger-sapphire-bg-hover,#1d4ed814)] dark:hover:bg-[var(--zui-combobox-trigger-sapphire-bg-hover-dark,#60a5fa24)]",
|
|
55
|
+
lavender:
|
|
56
|
+
"border border-[color:var(--zui-combobox-trigger-lavender-border,#8b5cf6)] dark:border-[color:var(--zui-combobox-trigger-lavender-border-dark,#a78bfa)] text-[color:var(--zui-combobox-trigger-lavender-fg,#8b5cf6)] dark:text-[color:var(--zui-combobox-trigger-lavender-fg-dark,#a78bfa)] hover:bg-[var(--zui-combobox-trigger-lavender-bg-hover,#8b5cf614)] dark:hover:bg-[var(--zui-combobox-trigger-lavender-bg-hover-dark,#a78bfa24)]",
|
|
57
|
+
ruby: "border border-[color:var(--zui-combobox-trigger-ruby-border,#be123c)] dark:border-[color:var(--zui-combobox-trigger-ruby-border-dark,#fb7185)] text-[color:var(--zui-combobox-trigger-ruby-fg,#be123c)] dark:text-[color:var(--zui-combobox-trigger-ruby-fg-dark,#fb7185)] hover:bg-[var(--zui-combobox-trigger-ruby-bg-hover,#be123c14)] dark:hover:bg-[var(--zui-combobox-trigger-ruby-bg-hover-dark,#fb718524)]",
|
|
58
|
+
red: "border border-[color:var(--zui-combobox-trigger-red-border,#dc2626)] dark:border-[color:var(--zui-combobox-trigger-red-border-dark,#ef4444)] text-[color:var(--zui-combobox-trigger-red-fg,#dc2626)] dark:text-[color:var(--zui-combobox-trigger-red-fg-dark,#ef4444)] hover:bg-[var(--zui-combobox-trigger-red-bg-hover,#dc262614)] dark:hover:bg-[var(--zui-combobox-trigger-red-bg-hover-dark,#ef444424)]",
|
|
59
|
+
slate:
|
|
60
|
+
"border border-[color:var(--zui-combobox-trigger-slate-border,#475569)] dark:border-[color:var(--zui-combobox-trigger-slate-border-dark,#64748b)] text-[color:var(--zui-combobox-trigger-slate-fg,#475569)] dark:text-[color:var(--zui-combobox-trigger-slate-fg-dark,#64748b)] hover:bg-[var(--zui-combobox-trigger-slate-bg-hover,#47556914)] dark:hover:bg-[var(--zui-combobox-trigger-slate-bg-hover-dark,#64748b24)]",
|
|
61
|
+
zinc: "border border-[color:var(--zui-combobox-trigger-zinc-border,#52525b)] dark:border-[color:var(--zui-combobox-trigger-zinc-border-dark,#71717a)] text-[color:var(--zui-combobox-trigger-zinc-fg,#52525b)] dark:text-[color:var(--zui-combobox-trigger-zinc-fg-dark,#71717a)] hover:bg-[var(--zui-combobox-trigger-zinc-bg-hover,#52525b14)] dark:hover:bg-[var(--zui-combobox-trigger-zinc-bg-hover-dark,#71717a24)]",
|
|
62
|
+
stone:
|
|
63
|
+
"border border-[color:var(--zui-combobox-trigger-stone-border,#57534e)] dark:border-[color:var(--zui-combobox-trigger-stone-border-dark,#78716c)] text-[color:var(--zui-combobox-trigger-stone-fg,#57534e)] dark:text-[color:var(--zui-combobox-trigger-stone-fg-dark,#78716c)] hover:bg-[var(--zui-combobox-trigger-stone-bg-hover,#57534e14)] dark:hover:bg-[var(--zui-combobox-trigger-stone-bg-hover-dark,#78716c24)]",
|
|
64
|
+
royal:
|
|
65
|
+
"border border-[color:var(--zui-combobox-trigger-royal-border,#4338ca)] dark:border-[color:var(--zui-combobox-trigger-royal-border-dark,#818cf8)] text-[color:var(--zui-combobox-trigger-royal-fg,#4338ca)] dark:text-[color:var(--zui-combobox-trigger-royal-fg-dark,#818cf8)] hover:bg-[var(--zui-combobox-trigger-royal-bg-hover,#4338ca14)] dark:hover:bg-[var(--zui-combobox-trigger-royal-bg-hover-dark,#818cf824)]",
|
|
66
|
+
electric:
|
|
67
|
+
"border border-[color:var(--zui-combobox-trigger-electric-border,#0ea5e9)] dark:border-[color:var(--zui-combobox-trigger-electric-border-dark,#38bdf8)] text-[color:var(--zui-combobox-trigger-electric-fg,#0ea5e9)] dark:text-[color:var(--zui-combobox-trigger-electric-fg-dark,#38bdf8)] hover:bg-[var(--zui-combobox-trigger-electric-bg-hover,#0ea5e914)] dark:hover:bg-[var(--zui-combobox-trigger-electric-bg-hover-dark,#38bdf824)]",
|
|
68
|
+
forest:
|
|
69
|
+
"border border-[color:var(--zui-combobox-trigger-forest-border,#166534)] dark:border-[color:var(--zui-combobox-trigger-forest-border-dark,#4ade80)] text-[color:var(--zui-combobox-trigger-forest-fg,#166534)] dark:text-[color:var(--zui-combobox-trigger-forest-fg-dark,#4ade80)] hover:bg-[var(--zui-combobox-trigger-forest-bg-hover,#16653414)] dark:hover:bg-[var(--zui-combobox-trigger-forest-bg-hover-dark,#4ade8024)]",
|
|
70
|
+
sunset:
|
|
71
|
+
"border border-[color:var(--zui-combobox-trigger-sunset-border,#ea580c)] dark:border-[color:var(--zui-combobox-trigger-sunset-border-dark,#fb923c)] text-[color:var(--zui-combobox-trigger-sunset-fg,#ea580c)] dark:text-[color:var(--zui-combobox-trigger-sunset-fg-dark,#fb923c)] hover:bg-[var(--zui-combobox-trigger-sunset-bg-hover,#ea580c14)] dark:hover:bg-[var(--zui-combobox-trigger-sunset-bg-hover-dark,#fb923c24)]",
|
|
72
|
+
magenta:
|
|
73
|
+
"border border-[color:var(--zui-combobox-trigger-magenta-border,#c026d3)] dark:border-[color:var(--zui-combobox-trigger-magenta-border-dark,#e879f9)] text-[color:var(--zui-combobox-trigger-magenta-fg,#c026d3)] dark:text-[color:var(--zui-combobox-trigger-magenta-fg-dark,#e879f9)] hover:bg-[var(--zui-combobox-trigger-magenta-bg-hover,#c026d314)] dark:hover:bg-[var(--zui-combobox-trigger-magenta-bg-hover-dark,#e879f924)]",
|
|
74
|
+
crimson:
|
|
75
|
+
"border border-[color:var(--zui-combobox-trigger-crimson-border,#b91c1c)] dark:border-[color:var(--zui-combobox-trigger-crimson-border-dark,#f87171)] text-[color:var(--zui-combobox-trigger-crimson-fg,#b91c1c)] dark:text-[color:var(--zui-combobox-trigger-crimson-fg-dark,#f87171)] hover:bg-[var(--zui-combobox-trigger-crimson-bg-hover,#b91c1c14)] dark:hover:bg-[var(--zui-combobox-trigger-crimson-bg-hover-dark,#f8717124)]",
|
|
76
|
+
aqua: "border border-[color:var(--zui-combobox-trigger-aqua-border,#0f766e)] dark:border-[color:var(--zui-combobox-trigger-aqua-border-dark,#2dd4bf)] text-[color:var(--zui-combobox-trigger-aqua-fg,#0f766e)] dark:text-[color:var(--zui-combobox-trigger-aqua-fg-dark,#2dd4bf)] hover:bg-[var(--zui-combobox-trigger-aqua-bg-hover,#0f766e14)] dark:hover:bg-[var(--zui-combobox-trigger-aqua-bg-hover-dark,#2dd4bf24)]",
|
|
77
|
+
plum: "border border-[color:var(--zui-combobox-trigger-plum-border,#7e22ce)] dark:border-[color:var(--zui-combobox-trigger-plum-border-dark,#c084fc)] text-[color:var(--zui-combobox-trigger-plum-fg,#7e22ce)] dark:text-[color:var(--zui-combobox-trigger-plum-fg-dark,#c084fc)] hover:bg-[var(--zui-combobox-trigger-plum-bg-hover,#7e22ce14)] dark:hover:bg-[var(--zui-combobox-trigger-plum-bg-hover-dark,#c084fc24)]",
|
|
78
|
+
} as const;
|
|
79
|
+
|
|
80
|
+
export const zuiComboboxSizes = {
|
|
81
|
+
sm: "px-2 py-1 text-sm",
|
|
82
|
+
md: "px-3 py-2",
|
|
83
|
+
lg: "px-4 py-3 text-lg",
|
|
84
|
+
} as const;
|
|
85
|
+
|
|
86
|
+
export const zuiComboboxItemBase =
|
|
87
|
+
"cursor-pointer px-3 py-2 rounded-md focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--zui-combobox-item-ring-focus,oklch(44.6%_0.03_256.802))] dark:focus-visible:ring-[var(--zui-combobox-item-ring-focus-dark,oklch(70.7%_0.022_261.325))] focus-visible:ring-inset";
|
|
88
|
+
|
|
89
|
+
export const zuiComboboxItemAppearances = {
|
|
90
|
+
default:
|
|
91
|
+
"bg-[var(--zui-combobox-item-default-bg,#ffffff)] dark:bg-[var(--zui-combobox-item-default-bg-dark,#000000)] text-[color:var(--zui-combobox-item-default-fg,oklch(21%_0.034_264.665))] dark:text-[color:var(--zui-combobox-item-default-fg-dark,oklch(92.8%_0.006_264.531))] data-[selected=true]:bg-[var(--zui-combobox-item-default-selected-bg,oklch(92.8%_0.006_264.531))] dark:data-[selected=true]:bg-[var(--zui-combobox-item-default-selected-bg-dark,oklch(27%_0.006_264.531))] data-[selected=true]:text-[color:var(--zui-combobox-item-default-selected-fg,oklch(37.3%_0.034_259.733))] dark:data-[selected=true]:text-[color:var(--zui-combobox-item-default-selected-fg-dark,oklch(92.8%_0.006_264.531))]",
|
|
92
|
+
glass:
|
|
93
|
+
"bg-[var(--zui-combobox-item-glass-bg,#0000001a)] dark:bg-[var(--zui-combobox-item-glass-bg-dark,#ffffff1a)] text-[color:var(--zui-combobox-item-glass-fg,oklch(37.3%_0.034_259.733))] dark:text-[color:var(--zui-combobox-item-glass-fg-dark,oklch(92.8%_0.006_264.531))]",
|
|
94
|
+
outline:
|
|
95
|
+
"border-2 border-[color:var(--zui-combobox-item-outline-border,oklch(55.1%_0.027_264.364))] dark:border-[color:var(--zui-combobox-item-outline-border-dark,oklch(55.1%_0.027_264.364))] text-[color:var(--zui-combobox-item-outline-fg,oklch(21%_0.034_264.665))] dark:text-[color:var(--zui-combobox-item-outline-fg-dark,oklch(96.7%_0.003_264.542))]",
|
|
96
|
+
ghost:
|
|
97
|
+
"border-[color:var(--zui-combobox-item-ghost-border,transparent)] dark:border-[color:var(--zui-combobox-item-ghost-border-dark,transparent)] text-[color:var(--zui-combobox-item-ghost-fg,oklch(21%_0.034_264.665))] dark:text-[color:var(--zui-combobox-item-ghost-fg-dark,oklch(96.7%_0.003_264.542))]",
|
|
98
|
+
sky: "text-[color:var(--zui-combobox-item-sky-fg,oklch(39.1%_0.09_240.876))] dark:text-[color:var(--zui-combobox-item-sky-fg-dark,oklch(90.1%_0.058_230.902))] hover:bg-[var(--zui-combobox-item-sky-bg-hover,oklch(90.1%_0.058_230.902))] dark:hover:bg-[var(--zui-combobox-item-sky-bg-hover-dark,oklch(28%_0.04_232))]",
|
|
99
|
+
rose: "text-[color:var(--zui-combobox-item-rose-fg,oklch(41%_0.159_10.272))] dark:text-[color:var(--zui-combobox-item-rose-fg-dark,oklch(89.2%_0.058_10.001))] hover:bg-[var(--zui-combobox-item-rose-bg-hover,oklch(89.2%_0.058_10.001))] dark:hover:bg-[var(--zui-combobox-item-rose-bg-hover-dark,oklch(27%_0.05_10))]",
|
|
100
|
+
purple:
|
|
101
|
+
"text-[color:var(--zui-combobox-item-purple-fg,oklch(38.1%_0.176_304.987))] dark:text-[color:var(--zui-combobox-item-purple-fg-dark,oklch(90.2%_0.063_306.703))] hover:bg-[var(--zui-combobox-item-purple-bg-hover,oklch(90.2%_0.063_306.703))] dark:hover:bg-[var(--zui-combobox-item-purple-bg-hover-dark,oklch(26%_0.06_304))]",
|
|
102
|
+
pink: "text-[color:var(--zui-combobox-item-pink-fg,oklch(40.8%_0.153_2.432))] dark:text-[color:var(--zui-combobox-item-pink-fg-dark,oklch(89.9%_0.061_343.231))] hover:bg-[var(--zui-combobox-item-pink-bg-hover,oklch(89.9%_0.061_343.231))] dark:hover:bg-[var(--zui-combobox-item-pink-bg-hover-dark,oklch(27%_0.05_343))]",
|
|
103
|
+
orange:
|
|
104
|
+
"text-[color:var(--zui-combobox-item-orange-fg,oklch(40.8%_0.123_38.172))] dark:text-[color:var(--zui-combobox-item-orange-fg-dark,oklch(90.1%_0.076_70.697))] hover:bg-[var(--zui-combobox-item-orange-bg-hover,oklch(90.1%_0.076_70.697))] dark:hover:bg-[var(--zui-combobox-item-orange-bg-hover-dark,oklch(27%_0.04_38))]",
|
|
105
|
+
yellow:
|
|
106
|
+
"text-[color:var(--zui-combobox-item-yellow-fg,oklch(42.1%_0.095_57.708))] dark:text-[color:var(--zui-combobox-item-yellow-fg-dark,oklch(94.5%_0.129_101.54))] hover:bg-[var(--zui-combobox-item-yellow-bg-hover,oklch(94.5%_0.129_101.54))] dark:hover:bg-[var(--zui-combobox-item-yellow-bg-hover-dark,oklch(28%_0.05_58))]",
|
|
107
|
+
teal: "text-[color:var(--zui-combobox-item-teal-fg,oklch(38.6%_0.063_188.416))] dark:text-[color:var(--zui-combobox-item-teal-fg-dark,oklch(91%_0.096_180.426))] hover:bg-[var(--zui-combobox-item-teal-bg-hover,oklch(91%_0.096_180.426))] dark:hover:bg-[var(--zui-combobox-item-teal-bg-hover-dark,oklch(26%_0.04_188))]",
|
|
108
|
+
indigo:
|
|
109
|
+
"text-[color:var(--zui-combobox-item-indigo-fg,oklch(35.9%_0.144_278.697))] dark:text-[color:var(--zui-combobox-item-indigo-fg-dark,oklch(87%_0.065_274.039))] hover:bg-[var(--zui-combobox-item-indigo-bg-hover,oklch(87%_0.065_274.039))] dark:hover:bg-[var(--zui-combobox-item-indigo-bg-hover-dark,oklch(25%_0.06_278))]",
|
|
110
|
+
emerald:
|
|
111
|
+
"text-[color:var(--zui-combobox-item-emerald-fg,oklch(37.8%_0.077_168.94))] dark:text-[color:var(--zui-combobox-item-emerald-fg-dark,oklch(90.5%_0.093_164.15))] hover:bg-[var(--zui-combobox-item-emerald-bg-hover,oklch(90.5%_0.093_164.15))] dark:hover:bg-[var(--zui-combobox-item-emerald-bg-hover-dark,oklch(26%_0.04_167))]",
|
|
112
|
+
blue: "hover:bg-[var(--zui-combobox-item-blue-bg-hover,#2563eb18)] dark:hover:bg-[var(--zui-combobox-item-blue-bg-hover-dark,#3b82f62e)] hover:text-[color:var(--zui-combobox-item-blue-fg-hover,#2563eb)] dark:hover:text-[color:var(--zui-combobox-item-blue-fg-hover-dark,#3b82f6)] bg-[var(--zui-combobox-item-blue-bg,#2563eb10)] dark:bg-[var(--zui-combobox-item-blue-bg-dark,#3b82f61f)] text-[color:var(--zui-combobox-item-blue-fg,#2563eb)] dark:text-[color:var(--zui-combobox-item-blue-fg-dark,#3b82f6)]",
|
|
113
|
+
cyan: "hover:bg-[var(--zui-combobox-item-cyan-bg-hover,#0891b218)] dark:hover:bg-[var(--zui-combobox-item-cyan-bg-hover-dark,#22d3ee2e)] hover:text-[color:var(--zui-combobox-item-cyan-fg-hover,#0891b2)] dark:hover:text-[color:var(--zui-combobox-item-cyan-fg-hover-dark,#22d3ee)] bg-[var(--zui-combobox-item-cyan-bg,#0891b210)] dark:bg-[var(--zui-combobox-item-cyan-bg-dark,#22d3ee1f)] text-[color:var(--zui-combobox-item-cyan-fg,#0891b2)] dark:text-[color:var(--zui-combobox-item-cyan-fg-dark,#22d3ee)]",
|
|
114
|
+
green:
|
|
115
|
+
"hover:bg-[var(--zui-combobox-item-green-bg-hover,#16a34a18)] dark:hover:bg-[var(--zui-combobox-item-green-bg-hover-dark,#22c55e2e)] hover:text-[color:var(--zui-combobox-item-green-fg-hover,#16a34a)] dark:hover:text-[color:var(--zui-combobox-item-green-fg-hover-dark,#22c55e)] bg-[var(--zui-combobox-item-green-bg,#16a34a10)] dark:bg-[var(--zui-combobox-item-green-bg-dark,#22c55e1f)] text-[color:var(--zui-combobox-item-green-fg,#16a34a)] dark:text-[color:var(--zui-combobox-item-green-fg-dark,#22c55e)]",
|
|
116
|
+
lavender:
|
|
117
|
+
"hover:bg-[var(--zui-combobox-item-lavender-bg-hover,#8b5cf618)] dark:hover:bg-[var(--zui-combobox-item-lavender-bg-hover-dark,#a78bfa2e)] hover:text-[color:var(--zui-combobox-item-lavender-fg-hover,#8b5cf6)] dark:hover:text-[color:var(--zui-combobox-item-lavender-fg-hover-dark,#a78bfa)] bg-[var(--zui-combobox-item-lavender-bg,#8b5cf610)] dark:bg-[var(--zui-combobox-item-lavender-bg-dark,#a78bfa1f)] text-[color:var(--zui-combobox-item-lavender-fg,#8b5cf6)] dark:text-[color:var(--zui-combobox-item-lavender-fg-dark,#a78bfa)]",
|
|
118
|
+
red: "hover:bg-[var(--zui-combobox-item-red-bg-hover,#dc262618)] dark:hover:bg-[var(--zui-combobox-item-red-bg-hover-dark,#ef44442e)] hover:text-[color:var(--zui-combobox-item-red-fg-hover,#dc2626)] dark:hover:text-[color:var(--zui-combobox-item-red-fg-hover-dark,#ef4444)] bg-[var(--zui-combobox-item-red-bg,#dc262610)] dark:bg-[var(--zui-combobox-item-red-bg-dark,#ef44441f)] text-[color:var(--zui-combobox-item-red-fg,#dc2626)] dark:text-[color:var(--zui-combobox-item-red-fg-dark,#ef4444)]",
|
|
119
|
+
} as const;
|
|
120
|
+
|
|
121
|
+
export const zuiComboboxDisabled = {
|
|
122
|
+
true: "opacity-50 cursor-not-allowed",
|
|
123
|
+
} as const;
|
|
124
|
+
|
|
125
|
+
export const zuiComboboxContentBase =
|
|
126
|
+
"absolute z-10 mt-2 w-full rounded-md border bg-[var(--zui-combobox-content-bg,#ffffff)] dark:bg-[var(--zui-combobox-content-bg-dark,#000000)] shadow-md overflow-hidden";
|
|
127
|
+
|
|
128
|
+
export const zuiComboboxContentAppearances = {
|
|
129
|
+
default:
|
|
130
|
+
"bg-[var(--zui-combobox-content-default-bg,#ffffff)] dark:bg-[var(--zui-combobox-content-default-bg-dark,#000000)] shadow-md",
|
|
131
|
+
glass:
|
|
132
|
+
"bg-[var(--zui-combobox-content-glass-bg,#0000001a)] dark:bg-[var(--zui-combobox-content-glass-bg-dark,#ffffff1a)] backdrop-blur-md",
|
|
133
|
+
outline:
|
|
134
|
+
"border-2 border-[color:var(--zui-combobox-content-outline-border,oklch(55.1%_0.027_264.364))] dark:border-[color:var(--zui-combobox-content-outline-border-dark,oklch(55.1%_0.027_264.364))]",
|
|
135
|
+
ghost:
|
|
136
|
+
"border-[color:var(--zui-combobox-content-ghost-border,transparent)] dark:border-[color:var(--zui-combobox-content-ghost-border-dark,transparent)]",
|
|
137
|
+
sky: "border-[color:var(--zui-combobox-content-sky-border,oklch(39.1%_0.09_240.876))] dark:border-[color:var(--zui-combobox-content-sky-border-dark,oklch(58.8%_0.158_241.966))]",
|
|
138
|
+
rose: "border-[color:var(--zui-combobox-content-rose-border,oklch(41%_0.159_10.272))] dark:border-[color:var(--zui-combobox-content-rose-border-dark,oklch(58.6%_0.253_17.585))]",
|
|
139
|
+
purple:
|
|
140
|
+
"border-[color:var(--zui-combobox-content-purple-border,oklch(38.1%_0.176_304.987))] dark:border-[color:var(--zui-combobox-content-purple-border-dark,oklch(55.8%_0.288_302.321))]",
|
|
141
|
+
pink: "border-[color:var(--zui-combobox-content-pink-border,oklch(40.8%_0.153_2.432))] dark:border-[color:var(--zui-combobox-content-pink-border-dark,oklch(59.2%_0.249_0.584))]",
|
|
142
|
+
orange:
|
|
143
|
+
"border-[color:var(--zui-combobox-content-orange-border,oklch(40.8%_0.123_38.172))] dark:border-[color:var(--zui-combobox-content-orange-border-dark,oklch(64.6%_0.222_41.116))]",
|
|
144
|
+
yellow:
|
|
145
|
+
"border-[color:var(--zui-combobox-content-yellow-border,oklch(42.1%_0.095_57.708))] dark:border-[color:var(--zui-combobox-content-yellow-border-dark,oklch(68.1%_0.162_75.834))]",
|
|
146
|
+
teal: "border-[color:var(--zui-combobox-content-teal-border,oklch(38.6%_0.063_188.416))] dark:border-[color:var(--zui-combobox-content-teal-border-dark,oklch(60%_0.118_184.704))]",
|
|
147
|
+
indigo:
|
|
148
|
+
"border-[color:var(--zui-combobox-content-indigo-border,oklch(35.9%_0.144_278.697))] dark:border-[color:var(--zui-combobox-content-indigo-border-dark,oklch(51.1%_0.262_276.966))]",
|
|
149
|
+
emerald:
|
|
150
|
+
"border-[color:var(--zui-combobox-content-emerald-border,oklch(37.8%_0.077_168.94))] dark:border-[color:var(--zui-combobox-content-emerald-border-dark,oklch(59.6%_0.145_163.225))]",
|
|
151
|
+
blue: "border border-[color:var(--zui-combobox-content-blue-border,#2563eb)] dark:border-[color:var(--zui-combobox-content-blue-border-dark,#3b82f6)] bg-[var(--zui-combobox-content-blue-bg,#2563eb14)] dark:bg-[var(--zui-combobox-content-blue-bg-dark,#3b82f624)]",
|
|
152
|
+
red: "border border-[color:var(--zui-combobox-content-red-border,#dc2626)] dark:border-[color:var(--zui-combobox-content-red-border-dark,#ef4444)] bg-[var(--zui-combobox-content-red-bg,#dc262614)] dark:bg-[var(--zui-combobox-content-red-bg-dark,#ef444424)]",
|
|
153
|
+
} as const;
|
|
154
|
+
|
|
155
|
+
export const zuiComboboxSpacing = {
|
|
156
|
+
none: "space-y-0",
|
|
157
|
+
default: "space-y-1",
|
|
158
|
+
sm: "space-y-2",
|
|
159
|
+
md: "space-y-3",
|
|
160
|
+
lg: "space-y-4",
|
|
161
|
+
xl: "space-y-5",
|
|
162
|
+
} as const;
|
|
163
|
+
|
|
164
|
+
export const zuiComboboxSearchRowBase =
|
|
165
|
+
"flex items-center gap-2 border-b px-3 py-2 border-[color:var(--zui-combobox-search-border,oklch(87.2%_0.01_258.338))] dark:border-[color:var(--zui-combobox-search-border-dark,oklch(27%_0.006_264.531))]";
|
|
166
|
+
|
|
167
|
+
export const zuiComboboxSearchInputBase =
|
|
168
|
+
"w-full bg-transparent text-sm outline-none placeholder:text-[color:var(--zui-combobox-search-placeholder,oklch(55.1%_0.027_264.364))] dark:placeholder:text-[color:var(--zui-combobox-search-placeholder-dark,oklch(55.1%_0.027_264.364))] text-[color:var(--zui-combobox-search-fg,oklch(13%_0.028_261.692))] dark:text-[color:var(--zui-combobox-search-fg-dark,#ffffff)]";
|
|
169
|
+
|
|
170
|
+
export const zuiComboboxSearchIconBase =
|
|
171
|
+
"size-4 shrink-0 opacity-50 text-[color:var(--zui-combobox-search-icon,currentColor)]";
|
|
172
|
+
|
|
173
|
+
export const zuiComboboxListBase =
|
|
174
|
+
"max-h-60 overflow-y-auto py-1 rounded-md border focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-1";
|
|
175
|
+
|
|
176
|
+
export const zuiComboboxListAppearances = {
|
|
177
|
+
default:
|
|
178
|
+
"border-[color:var(--zui-combobox-list-default-border,oklch(87.2%_0.01_258.338))] dark:border-[color:var(--zui-combobox-list-default-border-dark,oklch(27%_0.006_264.531))] focus-visible:ring-[color:var(--zui-combobox-list-default-ring,oklch(44.6%_0.03_256.802))] dark:focus-visible:ring-[color:var(--zui-combobox-list-default-ring-dark,oklch(70.7%_0.022_261.325))]",
|
|
179
|
+
glass:
|
|
180
|
+
"border-[color:var(--zui-combobox-list-glass-border,#0000001a)] dark:border-[color:var(--zui-combobox-list-glass-border-dark,#ffffff1a)] focus-visible:ring-[color:var(--zui-combobox-list-glass-ring,oklch(44.6%_0.03_256.802))] dark:focus-visible:ring-[color:var(--zui-combobox-list-glass-ring-dark,oklch(70.7%_0.022_261.325))]",
|
|
181
|
+
outline:
|
|
182
|
+
"border-[color:var(--zui-combobox-list-outline-border,oklch(55.1%_0.027_264.364))] dark:border-[color:var(--zui-combobox-list-outline-border-dark,oklch(55.1%_0.027_264.364))] focus-visible:ring-[color:var(--zui-combobox-list-outline-ring,oklch(55.1%_0.027_264.364))] dark:focus-visible:ring-[color:var(--zui-combobox-list-outline-ring-dark,oklch(55.1%_0.027_264.364))]",
|
|
183
|
+
ghost:
|
|
184
|
+
"border-transparent focus-visible:ring-[color:var(--zui-combobox-list-ghost-ring,oklch(44.6%_0.03_256.802))] dark:focus-visible:ring-[color:var(--zui-combobox-list-ghost-ring-dark,oklch(70.7%_0.022_261.325))]",
|
|
185
|
+
sky: "border-[color:var(--zui-combobox-list-sky-border,oklch(39.1%_0.09_240.876))] dark:border-[color:var(--zui-combobox-list-sky-border-dark,oklch(58.8%_0.158_241.966))] focus-visible:ring-[color:var(--zui-combobox-list-sky-ring,oklch(39.1%_0.09_240.876))] dark:focus-visible:ring-[color:var(--zui-combobox-list-sky-ring-dark,oklch(58.8%_0.158_241.966))]",
|
|
186
|
+
rose: "border-[color:var(--zui-combobox-list-rose-border,oklch(41%_0.159_10.272))] dark:border-[color:var(--zui-combobox-list-rose-border-dark,oklch(58.6%_0.253_17.585))] focus-visible:ring-[color:var(--zui-combobox-list-rose-ring,oklch(41%_0.159_10.272))] dark:focus-visible:ring-[color:var(--zui-combobox-list-rose-ring-dark,oklch(58.6%_0.253_17.585))]",
|
|
187
|
+
purple:
|
|
188
|
+
"border-[color:var(--zui-combobox-list-purple-border,oklch(38.1%_0.176_304.987))] dark:border-[color:var(--zui-combobox-list-purple-border-dark,oklch(55.8%_0.288_302.321))] focus-visible:ring-[color:var(--zui-combobox-list-purple-ring,oklch(38.1%_0.176_304.987))] dark:focus-visible:ring-[color:var(--zui-combobox-list-purple-ring-dark,oklch(55.8%_0.288_302.321))]",
|
|
189
|
+
pink: "border-[color:var(--zui-combobox-list-pink-border,oklch(40.8%_0.153_2.432))] dark:border-[color:var(--zui-combobox-list-pink-border-dark,oklch(59.2%_0.249_0.584))] focus-visible:ring-[color:var(--zui-combobox-list-pink-ring,oklch(40.8%_0.153_2.432))] dark:focus-visible:ring-[color:var(--zui-combobox-list-pink-ring-dark,oklch(59.2%_0.249_0.584))]",
|
|
190
|
+
orange:
|
|
191
|
+
"border-[color:var(--zui-combobox-list-orange-border,oklch(40.8%_0.123_38.172))] dark:border-[color:var(--zui-combobox-list-orange-border-dark,oklch(64.6%_0.222_41.116))] focus-visible:ring-[color:var(--zui-combobox-list-orange-ring,oklch(40.8%_0.123_38.172))] dark:focus-visible:ring-[color:var(--zui-combobox-list-orange-ring-dark,oklch(64.6%_0.222_41.116))]",
|
|
192
|
+
yellow:
|
|
193
|
+
"border-[color:var(--zui-combobox-list-yellow-border,oklch(42.1%_0.095_57.708))] dark:border-[color:var(--zui-combobox-list-yellow-border-dark,oklch(68.1%_0.162_75.834))] focus-visible:ring-[color:var(--zui-combobox-list-yellow-ring,oklch(42.1%_0.095_57.708))] dark:focus-visible:ring-[color:var(--zui-combobox-list-yellow-ring-dark,oklch(68.1%_0.162_75.834))]",
|
|
194
|
+
teal: "border-[color:var(--zui-combobox-list-teal-border,oklch(38.6%_0.063_188.416))] dark:border-[color:var(--zui-combobox-list-teal-border-dark,oklch(60%_0.118_184.704))] focus-visible:ring-[color:var(--zui-combobox-list-teal-ring,oklch(38.6%_0.063_188.416))] dark:focus-visible:ring-[color:var(--zui-combobox-list-teal-ring-dark,oklch(60%_0.118_184.704))]",
|
|
195
|
+
indigo:
|
|
196
|
+
"border-[color:var(--zui-combobox-list-indigo-border,oklch(35.9%_0.144_278.697))] dark:border-[color:var(--zui-combobox-list-indigo-border-dark,oklch(51.1%_0.262_276.966))] focus-visible:ring-[color:var(--zui-combobox-list-indigo-ring,oklch(35.9%_0.144_278.697))] dark:focus-visible:ring-[color:var(--zui-combobox-list-indigo-ring-dark,oklch(51.1%_0.262_276.966))]",
|
|
197
|
+
emerald:
|
|
198
|
+
"border-[color:var(--zui-combobox-list-emerald-border,oklch(37.8%_0.077_168.94))] dark:border-[color:var(--zui-combobox-list-emerald-border-dark,oklch(59.6%_0.145_163.225))] focus-visible:ring-[color:var(--zui-combobox-list-emerald-ring,oklch(37.8%_0.077_168.94))] dark:focus-visible:ring-[color:var(--zui-combobox-list-emerald-ring-dark,oklch(59.6%_0.145_163.225))]",
|
|
199
|
+
blue: "border-[color:var(--zui-combobox-list-blue-border,#2563eb)] dark:border-[color:var(--zui-combobox-list-blue-border-dark,#3b82f6)] focus-visible:ring-[color:var(--zui-combobox-list-blue-ring,#2563eb)] dark:focus-visible:ring-[color:var(--zui-combobox-list-blue-ring-dark,#3b82f6)]",
|
|
200
|
+
red: "border-[color:var(--zui-combobox-list-red-border,#dc2626)] dark:border-[color:var(--zui-combobox-list-red-border-dark,#ef4444)] focus-visible:ring-[color:var(--zui-combobox-list-red-ring,#dc2626)] dark:focus-visible:ring-[color:var(--zui-combobox-list-red-ring-dark,#ef4444)]",
|
|
201
|
+
} as const;
|
|
202
|
+
|
|
203
|
+
export const zuiComboboxEmptyBase =
|
|
204
|
+
"px-3 py-6 text-center text-sm text-[color:var(--zui-combobox-empty-fg,oklch(55.1%_0.027_264.364))] dark:text-[color:var(--zui-combobox-empty-fg-dark,oklch(55.1%_0.027_264.364))]";
|
package/src/hooks/index.ts
CHANGED
|
@@ -5,7 +5,22 @@ export {
|
|
|
5
5
|
type ClickOutsideEventType,
|
|
6
6
|
type UseClickOutsideParams,
|
|
7
7
|
} from "./useClickOutside";
|
|
8
|
+
export {
|
|
9
|
+
useEventListener,
|
|
10
|
+
type UseEventListenerTarget,
|
|
11
|
+
} from "./useEventListener";
|
|
8
12
|
export { useFocusManagement } from "./useFocusManagement";
|
|
13
|
+
export {
|
|
14
|
+
useGeolocation,
|
|
15
|
+
type GeolocationCoordinatesSnapshot,
|
|
16
|
+
type UseGeolocationParams,
|
|
17
|
+
type UseGeolocationResult,
|
|
18
|
+
} from "./useGeolocation";
|
|
19
|
+
export {
|
|
20
|
+
useHotkeys,
|
|
21
|
+
type HotkeyHandler,
|
|
22
|
+
type UseHotkeysOptions,
|
|
23
|
+
} from "./useHotkeys";
|
|
9
24
|
export {
|
|
10
25
|
buildPaginationItems,
|
|
11
26
|
usePagination,
|
|
@@ -17,6 +32,16 @@ export {
|
|
|
17
32
|
useControllableState,
|
|
18
33
|
type UseControllableStateParams,
|
|
19
34
|
} from "./useControllableState";
|
|
35
|
+
export {
|
|
36
|
+
useCookie,
|
|
37
|
+
type CookieOptions,
|
|
38
|
+
type UseCookieResult,
|
|
39
|
+
} from "./useCookie";
|
|
40
|
+
export {
|
|
41
|
+
useCountdown,
|
|
42
|
+
type UseCountdownParams,
|
|
43
|
+
type UseCountdownResult,
|
|
44
|
+
} from "./useCountdown";
|
|
20
45
|
export { useDebouncedValue } from "./useDebouncedValue";
|
|
21
46
|
export {
|
|
22
47
|
useDisclosure,
|
|
@@ -28,6 +53,12 @@ export {
|
|
|
28
53
|
type UseDocumentTitleParams,
|
|
29
54
|
} from "./useDocumentTitle";
|
|
30
55
|
export { useHover } from "./useHover";
|
|
56
|
+
export {
|
|
57
|
+
useIdleTimeout,
|
|
58
|
+
type UseIdleTimeoutParams,
|
|
59
|
+
type UseIdleTimeoutResult,
|
|
60
|
+
} from "./useIdleTimeout";
|
|
61
|
+
export { useInterval } from "./useInterval";
|
|
31
62
|
export { useInView, type UseInViewParams } from "./useInView";
|
|
32
63
|
export {
|
|
33
64
|
useIntersectionObserver,
|
|
@@ -35,7 +66,13 @@ export {
|
|
|
35
66
|
} from "./useIntersectionObserver";
|
|
36
67
|
export { useIsomorphicLayoutEffect } from "./useIsomorphicLayoutEffect";
|
|
37
68
|
export { useIsMounted } from "./useIsMounted";
|
|
69
|
+
export { useKeyPress } from "./useKeyPress";
|
|
38
70
|
export { useLocalStorage, type UseLocalStorageResult } from "./useLocalStorage";
|
|
71
|
+
export {
|
|
72
|
+
useLongPress,
|
|
73
|
+
type UseLongPressHandlers,
|
|
74
|
+
type UseLongPressOptions,
|
|
75
|
+
} from "./useLongPress";
|
|
39
76
|
export { useMediaQuery } from "./useMediaQuery";
|
|
40
77
|
export { useNetworkStatus } from "./useNetworkStatus";
|
|
41
78
|
export { usePageVisibility } from "./usePageVisibility";
|
|
@@ -44,7 +81,13 @@ export {
|
|
|
44
81
|
type ColorSchemePreference,
|
|
45
82
|
} from "./usePrefersColorScheme";
|
|
46
83
|
export { usePrefersReducedMotion } from "./usePrefersReducedMotion";
|
|
84
|
+
export { usePrevious } from "./usePrevious";
|
|
47
85
|
export { useResizeObserver, type ElementSize } from "./useResizeObserver";
|
|
86
|
+
export {
|
|
87
|
+
useScrollPosition,
|
|
88
|
+
type ScrollPosition,
|
|
89
|
+
type UseScrollPositionParams,
|
|
90
|
+
} from "./useScrollPosition";
|
|
48
91
|
export {
|
|
49
92
|
useSessionStorage,
|
|
50
93
|
type UseSessionStorageResult,
|
|
@@ -62,5 +105,12 @@ export {
|
|
|
62
105
|
type UseTableSortResult,
|
|
63
106
|
} from "./useTableSort";
|
|
64
107
|
export { useThrottledCallback } from "./useThrottledCallback";
|
|
108
|
+
export { useTimeout, type UseTimeoutResult } from "./useTimeout";
|
|
65
109
|
export { useToggle } from "./useToggle";
|
|
110
|
+
export {
|
|
111
|
+
useVirtualList,
|
|
112
|
+
type UseVirtualListParams,
|
|
113
|
+
type UseVirtualListResult,
|
|
114
|
+
type VirtualItem,
|
|
115
|
+
} from "./useVirtualList";
|
|
66
116
|
export { useWindowSize, type WindowSize } from "./useWindowSize";
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { act, renderHook } from "@testing-library/react";
|
|
2
|
+
import { afterEach, describe, expect, it } from "vitest";
|
|
3
|
+
|
|
4
|
+
import { useCookie } from "./useCookie";
|
|
5
|
+
|
|
6
|
+
describe("useCookie", () => {
|
|
7
|
+
afterEach(() => {
|
|
8
|
+
for (const row of document.cookie.split("; ")) {
|
|
9
|
+
const name = row.split("=")[0];
|
|
10
|
+
if (name) {
|
|
11
|
+
document.cookie = `${name}=; path=/; max-age=0`;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it("should fall back to initialValue when the cookie is absent", () => {
|
|
17
|
+
const { result } = renderHook(() => useCookie("zui-test", "fallback"));
|
|
18
|
+
expect(result.current[0]).toBe("fallback");
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it("should read an existing cookie", () => {
|
|
22
|
+
document.cookie = "zui-test=stored; path=/";
|
|
23
|
+
const { result } = renderHook(() => useCookie("zui-test", "fallback"));
|
|
24
|
+
expect(result.current[0]).toBe("stored");
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it("should write the cookie and update state", () => {
|
|
28
|
+
const { result } = renderHook(() => useCookie("zui-test"));
|
|
29
|
+
act(() => {
|
|
30
|
+
result.current[1]("hello world");
|
|
31
|
+
});
|
|
32
|
+
expect(result.current[0]).toBe("hello world");
|
|
33
|
+
expect(document.cookie).toContain("zui-test=hello%20world");
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it("should remove the cookie and reset state to null", () => {
|
|
37
|
+
document.cookie = "zui-test=stored; path=/";
|
|
38
|
+
const { result } = renderHook(() => useCookie("zui-test"));
|
|
39
|
+
act(() => {
|
|
40
|
+
result.current[2]();
|
|
41
|
+
});
|
|
42
|
+
expect(result.current[0]).toBeNull();
|
|
43
|
+
expect(document.cookie).not.toContain("zui-test=stored");
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it("should re-read when the cookie name changes", () => {
|
|
47
|
+
document.cookie = "zui-a=alpha; path=/";
|
|
48
|
+
document.cookie = "zui-b=beta; path=/";
|
|
49
|
+
const { result, rerender } = renderHook(
|
|
50
|
+
({ name }: { name: string }) => useCookie(name),
|
|
51
|
+
{ initialProps: { name: "zui-a" } },
|
|
52
|
+
);
|
|
53
|
+
expect(result.current[0]).toBe("alpha");
|
|
54
|
+
rerender({ name: "zui-b" });
|
|
55
|
+
expect(result.current[0]).toBe("beta");
|
|
56
|
+
});
|
|
57
|
+
});
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useCallback, useEffect, useState } from "react";
|
|
4
|
+
|
|
5
|
+
export type CookieOptions = {
|
|
6
|
+
/** Lifetime in seconds (sets `max-age`). Omit for a session cookie. */
|
|
7
|
+
maxAgeSeconds?: number;
|
|
8
|
+
/** Absolute expiry (sets `expires`). */
|
|
9
|
+
expires?: Date;
|
|
10
|
+
/** Cookie path (default `"/"`). */
|
|
11
|
+
path?: string;
|
|
12
|
+
/** Cookie domain. */
|
|
13
|
+
domain?: string;
|
|
14
|
+
/** Restrict to HTTPS. */
|
|
15
|
+
secure?: boolean;
|
|
16
|
+
/** SameSite attribute. `"none"` automatically forces `secure` per browser requirements. */
|
|
17
|
+
sameSite?: "strict" | "lax" | "none";
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export type UseCookieResult = [
|
|
21
|
+
string | null,
|
|
22
|
+
(value: string, options?: CookieOptions) => void,
|
|
23
|
+
(options?: Pick<CookieOptions, "path" | "domain">) => void,
|
|
24
|
+
];
|
|
25
|
+
|
|
26
|
+
function readCookie(name: string): string | null {
|
|
27
|
+
if (typeof document === "undefined") {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
const prefix = `${encodeURIComponent(name)}=`;
|
|
31
|
+
const match = document.cookie
|
|
32
|
+
.split("; ")
|
|
33
|
+
.find((row) => row.startsWith(prefix));
|
|
34
|
+
if (!match) {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
try {
|
|
38
|
+
return decodeURIComponent(match.slice(prefix.length));
|
|
39
|
+
} catch {
|
|
40
|
+
// Malformed cookie value — return null rather than crashing.
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function serializeCookie(
|
|
46
|
+
name: string,
|
|
47
|
+
value: string,
|
|
48
|
+
options: CookieOptions,
|
|
49
|
+
): string {
|
|
50
|
+
const {
|
|
51
|
+
maxAgeSeconds,
|
|
52
|
+
expires,
|
|
53
|
+
path = "/",
|
|
54
|
+
domain,
|
|
55
|
+
sameSite,
|
|
56
|
+
} = options;
|
|
57
|
+
// SameSite=None requires Secure; enforce it automatically.
|
|
58
|
+
const secure = options.secure || sameSite === "none";
|
|
59
|
+
let cookie = `${encodeURIComponent(name)}=${encodeURIComponent(value)}; path=${path}`;
|
|
60
|
+
if (maxAgeSeconds != null) {
|
|
61
|
+
cookie += `; max-age=${maxAgeSeconds}`;
|
|
62
|
+
}
|
|
63
|
+
if (expires) {
|
|
64
|
+
cookie += `; expires=${expires.toUTCString()}`;
|
|
65
|
+
}
|
|
66
|
+
if (domain) {
|
|
67
|
+
cookie += `; domain=${domain}`;
|
|
68
|
+
}
|
|
69
|
+
if (secure) {
|
|
70
|
+
cookie += "; secure";
|
|
71
|
+
}
|
|
72
|
+
if (sameSite) {
|
|
73
|
+
cookie += `; samesite=${sameSite}`;
|
|
74
|
+
}
|
|
75
|
+
return cookie;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Reads and writes a single cookie with React state that stays in sync with your updates.
|
|
80
|
+
*
|
|
81
|
+
* - Initial state is `initialValue` (or `null`) to avoid SSR hydration mismatches; the actual
|
|
82
|
+
* cookie value is read on mount via a `useEffect`.
|
|
83
|
+
* - `setCookie` writes `document.cookie` (URI-encoded) and updates state in the same call.
|
|
84
|
+
* - `removeCookie` expires the cookie via `max-age=0`; pass the same `path` / `domain` used when setting.
|
|
85
|
+
* - Reactivity covers writes made through this hook instance; cookies changed elsewhere are
|
|
86
|
+
* re-read only when `name` changes (the browser offers no cookie change event in wide support).
|
|
87
|
+
* - `SameSite="none"` automatically forces the `Secure` flag per browser requirements.
|
|
88
|
+
*
|
|
89
|
+
* @param name - Cookie name.
|
|
90
|
+
* @param initialValue - Fallback when the cookie is absent (and during SSR).
|
|
91
|
+
* @returns `[value, setCookie, removeCookie]`.
|
|
92
|
+
*/
|
|
93
|
+
export function useCookie(
|
|
94
|
+
name: string,
|
|
95
|
+
initialValue?: string,
|
|
96
|
+
): UseCookieResult {
|
|
97
|
+
// Initialize to initialValue (not readCookie) to avoid SSR hydration mismatches.
|
|
98
|
+
// The effect below syncs the actual cookie value after mount.
|
|
99
|
+
const [value, setValueState] = useState<string | null>(initialValue ?? null);
|
|
100
|
+
|
|
101
|
+
const setCookie = useCallback(
|
|
102
|
+
(value: string, options: CookieOptions = {}) => {
|
|
103
|
+
if (typeof document === "undefined") {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
document.cookie = serializeCookie(name, value, options);
|
|
107
|
+
setValueState(value);
|
|
108
|
+
},
|
|
109
|
+
[name],
|
|
110
|
+
);
|
|
111
|
+
|
|
112
|
+
const removeCookie = useCallback(
|
|
113
|
+
(options: Pick<CookieOptions, "path" | "domain"> = {}) => {
|
|
114
|
+
if (typeof document === "undefined") {
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
document.cookie = serializeCookie(name, "", {
|
|
118
|
+
...options,
|
|
119
|
+
maxAgeSeconds: 0,
|
|
120
|
+
});
|
|
121
|
+
setValueState(null);
|
|
122
|
+
},
|
|
123
|
+
[name],
|
|
124
|
+
);
|
|
125
|
+
|
|
126
|
+
useEffect(() => {
|
|
127
|
+
setValueState(readCookie(name) ?? initialValue ?? null);
|
|
128
|
+
// Intentionally keyed by name only: initialValue is a fallback, not a data source.
|
|
129
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
130
|
+
}, [name]);
|
|
131
|
+
|
|
132
|
+
return [value, setCookie, removeCookie];
|
|
133
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { act, renderHook } from "@testing-library/react";
|
|
2
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
3
|
+
|
|
4
|
+
import { useCountdown } from "./useCountdown";
|
|
5
|
+
|
|
6
|
+
describe("useCountdown", () => {
|
|
7
|
+
beforeEach(() => {
|
|
8
|
+
vi.useFakeTimers();
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
afterEach(() => {
|
|
12
|
+
vi.useRealTimers();
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it("should stay idle until started", () => {
|
|
16
|
+
const { result } = renderHook(() =>
|
|
17
|
+
useCountdown({ countStart: 5, intervalMs: 100 }),
|
|
18
|
+
);
|
|
19
|
+
act(() => {
|
|
20
|
+
vi.advanceTimersByTime(500);
|
|
21
|
+
});
|
|
22
|
+
expect(result.current.count).toBe(5);
|
|
23
|
+
expect(result.current.isRunning).toBe(false);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it("should count down once started", () => {
|
|
27
|
+
const { result } = renderHook(() =>
|
|
28
|
+
useCountdown({ countStart: 5, intervalMs: 100 }),
|
|
29
|
+
);
|
|
30
|
+
act(() => {
|
|
31
|
+
result.current.start();
|
|
32
|
+
});
|
|
33
|
+
act(() => {
|
|
34
|
+
vi.advanceTimersByTime(300);
|
|
35
|
+
});
|
|
36
|
+
expect(result.current.count).toBe(2);
|
|
37
|
+
expect(result.current.isRunning).toBe(true);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it("should auto start when configured", () => {
|
|
41
|
+
const { result } = renderHook(() =>
|
|
42
|
+
useCountdown({ countStart: 3, intervalMs: 100, autoStart: true }),
|
|
43
|
+
);
|
|
44
|
+
act(() => {
|
|
45
|
+
vi.advanceTimersByTime(100);
|
|
46
|
+
});
|
|
47
|
+
expect(result.current.count).toBe(2);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it("should pause and resume", () => {
|
|
51
|
+
const { result } = renderHook(() =>
|
|
52
|
+
useCountdown({ countStart: 5, intervalMs: 100 }),
|
|
53
|
+
);
|
|
54
|
+
act(() => {
|
|
55
|
+
result.current.start();
|
|
56
|
+
});
|
|
57
|
+
act(() => {
|
|
58
|
+
vi.advanceTimersByTime(200);
|
|
59
|
+
});
|
|
60
|
+
act(() => {
|
|
61
|
+
result.current.pause();
|
|
62
|
+
});
|
|
63
|
+
act(() => {
|
|
64
|
+
vi.advanceTimersByTime(500);
|
|
65
|
+
});
|
|
66
|
+
expect(result.current.count).toBe(3);
|
|
67
|
+
act(() => {
|
|
68
|
+
result.current.resume();
|
|
69
|
+
});
|
|
70
|
+
act(() => {
|
|
71
|
+
vi.advanceTimersByTime(100);
|
|
72
|
+
});
|
|
73
|
+
expect(result.current.count).toBe(2);
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it("should stop at countStop and call onComplete once", () => {
|
|
77
|
+
const onComplete = vi.fn();
|
|
78
|
+
const { result } = renderHook(() =>
|
|
79
|
+
useCountdown({ countStart: 2, intervalMs: 100, onComplete }),
|
|
80
|
+
);
|
|
81
|
+
act(() => {
|
|
82
|
+
result.current.start();
|
|
83
|
+
});
|
|
84
|
+
act(() => {
|
|
85
|
+
vi.advanceTimersByTime(1000);
|
|
86
|
+
});
|
|
87
|
+
expect(result.current.count).toBe(0);
|
|
88
|
+
expect(result.current.isRunning).toBe(false);
|
|
89
|
+
expect(result.current.isComplete).toBe(true);
|
|
90
|
+
expect(onComplete).toHaveBeenCalledTimes(1);
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
it("should reset back to countStart without running", () => {
|
|
94
|
+
const { result } = renderHook(() =>
|
|
95
|
+
useCountdown({ countStart: 5, intervalMs: 100 }),
|
|
96
|
+
);
|
|
97
|
+
act(() => {
|
|
98
|
+
result.current.start();
|
|
99
|
+
});
|
|
100
|
+
act(() => {
|
|
101
|
+
vi.advanceTimersByTime(200);
|
|
102
|
+
});
|
|
103
|
+
act(() => {
|
|
104
|
+
result.current.reset();
|
|
105
|
+
});
|
|
106
|
+
expect(result.current.count).toBe(5);
|
|
107
|
+
expect(result.current.isRunning).toBe(false);
|
|
108
|
+
act(() => {
|
|
109
|
+
vi.advanceTimersByTime(500);
|
|
110
|
+
});
|
|
111
|
+
expect(result.current.count).toBe(5);
|
|
112
|
+
});
|
|
113
|
+
});
|