@kamod-ch/ui 0.2.1 → 1.0.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 (57) hide show
  1. package/README.md +102 -15
  2. package/dist/{AlertDialog-ALB541qy.d.ts → AlertDialog-GadhKjPC.d.ts} +1 -1
  3. package/dist/{DialogContent-CK1t4m4e.d.ts → DialogContent-cQHSRQdT.d.ts} +1 -1
  4. package/dist/{Drawer-B3pZMn5j.d.ts → Drawer-CdjXZxxK.d.ts} +1 -1
  5. package/dist/{Sheet-s0xRF22F.d.ts → Sheet-DZ-p-aHY.d.ts} +1 -1
  6. package/dist/{chunk-MJG6UKD4.js → chunk-262EK2XT.js} +9 -17
  7. package/dist/chunk-262EK2XT.js.map +1 -0
  8. package/dist/chunk-B47B6KK6.js +59 -0
  9. package/dist/chunk-B47B6KK6.js.map +1 -0
  10. package/dist/{chunk-JKXSX67K.js → chunk-EMUPVA2F.js} +4 -4
  11. package/dist/chunk-EMUPVA2F.js.map +1 -0
  12. package/dist/{chunk-26CRIZXP.js → chunk-HCTZJYHK.js} +19 -17
  13. package/dist/chunk-HCTZJYHK.js.map +1 -0
  14. package/dist/{chunk-4BJJOHZT.js → chunk-HHLQYMPT.js} +3 -3
  15. package/dist/{chunk-4BJJOHZT.js.map → chunk-HHLQYMPT.js.map} +1 -1
  16. package/dist/{chunk-YJGECAOZ.js → chunk-IQH3XSOI.js} +4 -4
  17. package/dist/{chunk-YJGECAOZ.js.map → chunk-IQH3XSOI.js.map} +1 -1
  18. package/dist/{chunk-LFJF3M6M.js → chunk-JSHUWI3C.js} +3 -3
  19. package/dist/{chunk-LFJF3M6M.js.map → chunk-JSHUWI3C.js.map} +1 -1
  20. package/dist/{chunk-PZS2D2QM.js → chunk-NILG56Z7.js} +3 -3
  21. package/dist/{chunk-PZS2D2QM.js.map → chunk-NILG56Z7.js.map} +1 -1
  22. package/dist/{chunk-2HZCH73K.js → chunk-STRBBF45.js} +5 -5
  23. package/dist/chunk-STRBBF45.js.map +1 -0
  24. package/dist/{chunk-YVALXJRN.js → chunk-TXKPDNRD.js} +7 -8
  25. package/dist/chunk-TXKPDNRD.js.map +1 -0
  26. package/dist/{chunk-YTJRKLUR.js → chunk-UARVH66B.js} +4 -4
  27. package/dist/{chunk-YTJRKLUR.js.map → chunk-UARVH66B.js.map} +1 -1
  28. package/dist/{chunk-ROKLAZHC.js → chunk-UIA74JVN.js} +3 -3
  29. package/dist/{chunk-ROKLAZHC.js.map → chunk-UIA74JVN.js.map} +1 -1
  30. package/dist/{chunk-BQP4UA44.js → chunk-X2YUFNK7.js} +3 -3
  31. package/dist/{chunk-BQP4UA44.js.map → chunk-X2YUFNK7.js.map} +1 -1
  32. package/dist/{chunk-3DNIMQX6.js → chunk-XNYAQZIB.js} +15 -9
  33. package/dist/chunk-XNYAQZIB.js.map +1 -0
  34. package/dist/components/alert-dialog/index.d.ts +3 -3
  35. package/dist/components/alert-dialog/index.js +3 -2
  36. package/dist/components/command/index.js +4 -3
  37. package/dist/components/context-menu/index.d.ts +1 -1
  38. package/dist/components/context-menu/index.js +2 -1
  39. package/dist/components/dialog/index.d.ts +3 -3
  40. package/dist/components/dialog/index.js +3 -2
  41. package/dist/components/drawer/index.d.ts +3 -3
  42. package/dist/components/drawer/index.js +4 -3
  43. package/dist/components/radio-group/index.js +2 -2
  44. package/dist/components/selectable-card/index.js +2 -2
  45. package/dist/components/sheet/index.d.ts +3 -3
  46. package/dist/components/sheet/index.js +4 -3
  47. package/dist/components/tabs/index.js +1 -1
  48. package/dist/components/theme-toggle/index.js +1 -1
  49. package/dist/index.d.ts +4 -4
  50. package/dist/index.js +14 -13
  51. package/package.json +4 -2
  52. package/dist/chunk-26CRIZXP.js.map +0 -1
  53. package/dist/chunk-2HZCH73K.js.map +0 -1
  54. package/dist/chunk-3DNIMQX6.js.map +0 -1
  55. package/dist/chunk-JKXSX67K.js.map +0 -1
  56. package/dist/chunk-MJG6UKD4.js.map +0 -1
  57. package/dist/chunk-YVALXJRN.js.map +0 -1
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  <p align="center">
2
- <img src="https://raw.githubusercontent.com/kamod-ch/kamod-ui/main/.github/assets/logo-kamod-ui-dark.svg#gh-light-mode-only" alt="Kamod UI" width="162" />
3
- <img src="https://raw.githubusercontent.com/kamod-ch/kamod-ui/main/.github/assets/logo-kamod-ui-light.svg#gh-dark-mode-only" alt="Kamod UI" width="162" />
2
+ <img src="https://raw.githubusercontent.com/kamod-ch/kamod-ui/main/.github/assets/logo-kamod-ui-dark.svg#gh-light-mode-only" alt="kamod | UI" width="280" />
3
+ <img src="https://raw.githubusercontent.com/kamod-ch/kamod-ui/main/.github/assets/logo-kamod-ui-light.svg#gh-dark-mode-only" alt="kamod | UI" width="280" />
4
4
  </p>
5
5
 
6
6
  <h1 align="center">Kamod UI</h1>
@@ -16,6 +16,8 @@ Lightweight UI components for **Preact** and **Tailwind**: composable primitives
16
16
 
17
17
  **[Demo](https://ui.kamod.ch/)** · **[Component docs](https://ui.kamod.ch/docs/button)** · **[npm](https://www.npmjs.com/package/@kamod-ch/ui)** · **[GitHub](https://github.com/kamod-ch/kamod-ui)** · **[Issues](https://github.com/kamod-ch/kamod-ui/issues)**
18
18
 
19
+ > Demo snippets in this repo use local aliases like `@/components/kamod-ui/*`. In your app, install `@kamod-ch/ui` and import from the package.
20
+
19
21
  > If Kamod UI saves you time, **[star the repo](https://github.com/kamod-ch/kamod-ui)** — it helps others discover the project.
20
22
 
21
23
  ![hero](https://raw.githubusercontent.com/kamod-ch/kamod-ui/main/.github/assets/kitchen-sink.png)
@@ -44,21 +46,104 @@ Many UI kits are heavier than necessary, overly opinionated, or tied to React. K
44
46
 
45
47
  ## Quick start
46
48
 
49
+ ### Vite + Preact + Tailwind v4 starter
50
+
47
51
  ```bash
48
- pnpm add @kamod-ch/ui preact @preact/signals tailwindcss
52
+ pnpm create vite@latest my-app -- --template preact-ts
53
+ cd my-app
54
+ pnpm add @kamod-ch/ui @preact/signals
55
+ pnpm add -D tailwindcss @tailwindcss/vite
56
+ ```
57
+
58
+ ```ts
59
+ // vite.config.ts
60
+ import { defineConfig } from "vite";
61
+ import preact from "@preact/preset-vite";
62
+ import tailwindcss from "@tailwindcss/vite";
63
+
64
+ export default defineConfig({
65
+ plugins: [preact(), tailwindcss()],
66
+ });
49
67
  ```
50
68
 
51
69
  ```css
52
- /* app.css */
70
+ /* src/app.css */
53
71
  @import "tailwindcss";
54
72
  @import "@kamod-ch/ui/theme.css";
73
+
74
+ :root {
75
+ font-family: Inter, system-ui, sans-serif;
76
+ }
77
+ ```
78
+
79
+ ```tsx
80
+ // src/main.tsx
81
+ import { render } from "preact";
82
+ import { App } from "./app";
83
+ import "./app.css";
84
+
85
+ render(<App />, document.getElementById("app")!);
55
86
  ```
56
87
 
57
88
  ```tsx
89
+ // src/app.tsx
58
90
  import { Button } from "@kamod-ch/ui";
59
91
 
60
92
  export function App() {
61
- return <Button>Click me</Button>;
93
+ return (
94
+ <main class="p-6">
95
+ <Button>Click me</Button>
96
+ </main>
97
+ );
98
+ }
99
+ ```
100
+
101
+ This is the smallest full setup. If you already have a Vite app, keep the `@kamod-ch/ui/theme.css` import and add `@kamod-ch/ui` + `@preact/signals`.
102
+
103
+ Browse the [live component docs](https://ui.kamod.ch/docs/button) for variants, composition, and RTL examples.
104
+
105
+ ## Troubleshooting (Tailwind v4)
106
+
107
+ ### Components look unstyled
108
+
109
+ Make sure your global CSS imports both files, in this order:
110
+
111
+ ```css
112
+ @import "tailwindcss";
113
+ @import "@kamod-ch/ui/theme.css";
114
+ ```
115
+
116
+ If `theme.css` is missing, Kamod's component classes and semantic tokens will not compile.
117
+
118
+ ### Tailwind works in CSS but utility classes are missing in Vite
119
+
120
+ If you're using Vite, make sure the Tailwind v4 plugin is installed and enabled:
121
+
122
+ ```ts
123
+ import tailwindcss from "@tailwindcss/vite";
124
+
125
+ export default defineConfig({
126
+ plugins: [tailwindcss()],
127
+ });
128
+ ```
129
+
130
+ Without the plugin, Vite may not process the Tailwind v4 import pipeline correctly.
131
+
132
+ ### You're on Tailwind v3
133
+
134
+ Kamod UI requires Tailwind CSS v4. Tailwind v3 does not support the import-based setup used here.
135
+
136
+ ### Theme overrides do not apply
137
+
138
+ Override CSS variables after importing `theme.css`, not before it:
139
+
140
+ ```css
141
+ @import "tailwindcss";
142
+ @import "@kamod-ch/ui/theme.css";
143
+
144
+ :root {
145
+ --primary: var(--color-fuchsia-700);
146
+ --radius: 0.75rem;
62
147
  }
63
148
  ```
64
149
 
@@ -80,7 +165,7 @@ Browse the [live component docs](https://ui.kamod.ch/docs/button) for variants,
80
165
  pnpm add @kamod-ch/ui preact @preact/signals
81
166
  ```
82
167
 
83
- The published library on npm is **[`@kamod-ch/ui`](https://www.npmjs.com/package/@kamod-ch/ui)**. This monorepo root and `apps/demo` are not published. The former package [`@kamod-ui/core`](https://www.npmjs.com/package/@kamod-ui/core) and the unscoped [`kamod-ui`](https://www.npmjs.com/package/kamod-ui) name are legacy — install `@kamod-ch/ui` instead.
168
+ The published library on npm is **[`@kamod-ch/ui`](https://www.npmjs.com/package/@kamod-ch/ui)**. This monorepo root and `packages/docs` are not published. The former package [`@kamod-ui/core`](https://www.npmjs.com/package/@kamod-ui/core) and the unscoped [`kamod-ui`](https://www.npmjs.com/package/kamod-ui) name are legacy — install `@kamod-ch/ui` instead.
84
169
 
85
170
  Import the default theme once so Tailwind compiles component classes and semantic CSS tokens:
86
171
 
@@ -97,11 +182,11 @@ Import the default theme once so Tailwind compiles component classes and semanti
97
182
 
98
183
  **Import signals yourself** when you use Kamod's lower-level helpers:
99
184
 
100
- | Use case | Import |
101
- | ----------------------------------- | -------------------------------------------------------------------------------- |
185
+ | Use case | Import |
186
+ | ----------------------------------- | ------------------------------------------------------------------------------ |
102
187
  | Custom controlled primitives | `@kamod-ch/ui/lib/signals` → `createControllableSignal` |
103
188
  | Overlay dismiss / roving focus | `@kamod-ch/ui/lib/interactive` → `createDismissableLayer`, `createRovingFocus` |
104
- | Advanced toast / sonner integration | `@kamod-ch/ui/toast` or `@kamod-ch/ui/sonner` stores |
189
+ | Advanced toast / sonner integration | `@kamod-ch/ui/toast` or `@kamod-ch/ui/sonner` stores |
105
190
 
106
191
  See the [**Signals** column in the component reference](https://github.com/kamod-ch/kamod-ui/blob/main/.docs/COMPONENTS.md) for which exports use signals internally (direct, indirect via Dialog/Popover, or none).
107
192
 
@@ -114,6 +199,8 @@ import { Button } from "@kamod-ch/ui"; // root barrel
114
199
  import { Button } from "@kamod-ch/ui/button"; // per-component subpath
115
200
  ```
116
201
 
202
+ The demo docs in `packages/docs` rewrite the same examples to local aliases like `@/components/kamod-ui/button`. That alias only exists inside the demo app; in your app, install `@kamod-ch/ui` and import from the package.
203
+
117
204
  The package ships a minimal `sideEffects` list (progress indeterminate keyframes and CSS only), so modern bundlers tree-shake the root barrel reliably.
118
205
 
119
206
  ### Component sizes
@@ -146,7 +233,7 @@ Override semantic tokens after importing the default theme:
146
233
  }
147
234
  ```
148
235
 
149
- For full control, copy from [`packages/core/src/theme.css`](https://github.com/kamod-ch/kamod-ui/blob/main/packages/core/src/theme.css) or see the demo's [`foundation.css`](https://github.com/kamod-ch/kamod-ui/blob/main/apps/demo/src/styles/foundation.css) and [`themes.css`](https://github.com/kamod-ch/kamod-ui/blob/main/apps/demo/src/styles/themes.css).
236
+ For full control, copy from [`packages/core/src/theme.css`](https://github.com/kamod-ch/kamod-ui/blob/main/packages/core/src/theme.css) or see the demo's [`foundation.css`](https://github.com/kamod-ch/kamod-ui/blob/main/packages/docs/src/styles/foundation.css) and [`themes.css`](https://github.com/kamod-ch/kamod-ui/blob/main/packages/docs/src/styles/themes.css).
150
237
 
151
238
  ## Documentation
152
239
 
@@ -165,13 +252,13 @@ Open the URL printed in the terminal for the kitchen sink and component docs. Qu
165
252
 
166
253
  ## Contributing
167
254
 
168
- | Workspace | Path | Role |
169
- | ---------------- | ---------------- | ---------------------------------------- |
170
- | `@kamod-ch/ui` | `packages/core/` | Published library (65 component exports) |
171
- | `demo` | `apps/demo/` | Kitchen sink + interactive docs |
255
+ | Workspace | Path | Role |
256
+ | ------------------- | ---------------- | ---------------------------------------- |
257
+ | `@kamod-ch/ui` | `packages/core/` | Published library (65 component exports) |
258
+ | `@kamod-ch/ui-docs` | `packages/docs/` | Kitchen sink + interactive docs |
172
259
 
173
260
  - Open issues for bugs and ideas; PRs welcome for components, docs, and examples.
174
- - Key scripts: `pnpm dev`, `pnpm check`, `pnpm fmt`, `pnpm lint`, `pnpm docs:components`
261
+ - Key scripts: `pnpm dev`, `pnpm check`, `pnpm format`, `pnpm lint`, `pnpm docs:components`
175
262
  - Tooling details: [`.docs/interna.md`](https://github.com/kamod-ch/kamod-ui/blob/main/.docs/interna.md)
176
263
 
177
264
  Maintainers: see [`.docs/MAINTAINERS.md`](https://github.com/kamod-ch/kamod-ui/blob/main/.docs/MAINTAINERS.md) for npm release workflow.
@@ -3,7 +3,7 @@ import { ComponentChildren, JSX } from 'preact';
3
3
  import { VariantProps } from 'tailwind-variants';
4
4
  import { b as button } from './Button-vQnkiVTI.js';
5
5
  import { e as DialogCloseProps, d as DialogTriggerProps, c as DialogProps } from './Dialog-BOIteLfe.js';
6
- import { b as DialogContentProps } from './DialogContent-CK1t4m4e.js';
6
+ import { b as DialogContentProps } from './DialogContent-cQHSRQdT.js';
7
7
 
8
8
  type AlertDialogActionProps = DialogCloseProps & {
9
9
  variant?: VariantProps<typeof button>["variant"];
@@ -19,6 +19,6 @@ type DialogContentProps = JSX.HTMLAttributes<HTMLDivElement> & {
19
19
  * - **modal (default):** Backdrop + centered panel; use `class` only for sizing (e.g. `sm:max-w-sm`).
20
20
  * - **slot:** Single root node — **required** for legacy/custom layouts that already implement `fixed inset-0` overlay + inner card (otherwise you stack two modals).
21
21
  */
22
- declare const DialogContent: ({ forceMount, presentation, showCloseButton, class: className, children, onKeyDown, "data-slot": dataSlot, "aria-labelledby": ariaLabelledBy, "aria-describedby": ariaDescribedBy, ...rest }: DialogContentProps) => preact.VNode<any> | null;
22
+ declare const DialogContent: ({ forceMount, presentation, showCloseButton, class: className, children, onKeyDown, "data-slot": dataSlot, "aria-labelledby": ariaLabelledBy, "aria-describedby": ariaDescribedBy, ...rest }: DialogContentProps) => JSX.Element | preact.VNode<{}> | null;
23
23
 
24
24
  export { DialogContent as D, type DialogContentPresentation as a, type DialogContentProps as b };
@@ -2,7 +2,7 @@ import * as preact from 'preact';
2
2
  import { ComponentChildren } from 'preact';
3
3
  import { e as DialogCloseProps, d as DialogTriggerProps } from './Dialog-BOIteLfe.js';
4
4
  import { c as DialogDescriptionProps, b as DialogTitleProps } from './DialogTitle-CerJD0oA.js';
5
- import { g as SheetFooterProps, f as SheetHeaderProps, e as SheetContentProps, d as SheetProps } from './Sheet-s0xRF22F.js';
5
+ import { g as SheetFooterProps, f as SheetHeaderProps, e as SheetContentProps, d as SheetProps } from './Sheet-DZ-p-aHY.js';
6
6
 
7
7
  type DrawerCloseProps = DialogCloseProps;
8
8
  declare const DrawerClose: (props: DrawerCloseProps) => preact.JSX.Element;
@@ -19,7 +19,7 @@ type SheetContentProps = JSX.HTMLAttributes<HTMLDivElement> & {
19
19
  children?: ComponentChildren;
20
20
  "data-slot"?: string;
21
21
  };
22
- declare const SheetContent: ({ side, showCloseButton, children, class: className, forceMount, "data-slot": dataSlot, "aria-labelledby": ariaLabelledBy, "aria-describedby": ariaDescribedBy, ...rest }: SheetContentProps) => preact.VNode<any> | null;
22
+ declare const SheetContent: ({ side, showCloseButton, children, class: className, forceMount, "data-slot": dataSlot, "aria-labelledby": ariaLabelledBy, "aria-describedby": ariaDescribedBy, ...rest }: SheetContentProps) => JSX.Element | preact.VNode<{}> | null;
23
23
 
24
24
  type SheetProps = DialogProps & {
25
25
  children?: ComponentChildren;
@@ -1,6 +1,7 @@
1
1
  import { Button } from './chunk-5FBD2NTR.js';
2
2
  import { cn } from './chunk-MS2ZNYCJ.js';
3
- import { useState, useEffect } from 'preact/hooks';
3
+ import { syncThemeFromStorage, resolvedColorSchemeSignal, setColorScheme } from '@kamod-ch/themes';
4
+ import { useEffect } from 'preact/hooks';
4
5
  import { jsx, jsxs } from 'preact/jsx-runtime';
5
6
 
6
7
  var SunIcon = ({ class: className }) => /* @__PURE__ */ jsxs(
@@ -41,21 +42,11 @@ var MoonIcon = ({ class: className }) => /* @__PURE__ */ jsx(
41
42
  children: /* @__PURE__ */ jsx("path", { d: "M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z" })
42
43
  }
43
44
  );
44
- var resolveInitialDarkMode = () => {
45
- if (typeof window === "undefined") return false;
46
- const stored = window.localStorage.getItem("theme");
47
- if (stored === "dark") return true;
48
- if (stored === "light") return false;
49
- return window.matchMedia("(prefers-color-scheme: dark)").matches;
50
- };
51
45
  var ThemeToggle = ({ children, onClick, ...rest }) => {
52
- const [darkMode, setDarkMode] = useState(resolveInitialDarkMode);
53
46
  useEffect(() => {
54
- document.documentElement.classList.toggle("dark", darkMode);
55
- if (typeof window !== "undefined") {
56
- window.localStorage.setItem("theme", darkMode ? "dark" : "light");
57
- }
58
- }, [darkMode]);
47
+ syncThemeFromStorage();
48
+ }, []);
49
+ const darkMode = resolvedColorSchemeSignal.value === "dark";
59
50
  return /* @__PURE__ */ jsx(
60
51
  Button,
61
52
  {
@@ -66,7 +57,8 @@ var ThemeToggle = ({ children, onClick, ...rest }) => {
66
57
  "data-state": darkMode ? "dark" : "light",
67
58
  "aria-label": children == null ? darkMode ? "Light mode" : "Dark mode" : void 0,
68
59
  onClick: (event) => {
69
- setDarkMode((current) => !current);
60
+ const next = resolvedColorSchemeSignal.value === "dark" ? "light" : "dark";
61
+ setColorScheme(next);
70
62
  onClick?.(event);
71
63
  },
72
64
  ...rest,
@@ -79,5 +71,5 @@ var ThemeToggle = ({ children, onClick, ...rest }) => {
79
71
  var theme_toggle_default = ThemeToggle;
80
72
 
81
73
  export { ThemeToggle, theme_toggle_default };
82
- //# sourceMappingURL=chunk-MJG6UKD4.js.map
83
- //# sourceMappingURL=chunk-MJG6UKD4.js.map
74
+ //# sourceMappingURL=chunk-262EK2XT.js.map
75
+ //# sourceMappingURL=chunk-262EK2XT.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/theme-toggle/ThemeToggle.tsx","../src/components/theme-toggle/index.ts"],"names":[],"mappings":"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","file":"chunk-262EK2XT.js","sourcesContent":["import { resolvedColorSchemeSignal, setColorScheme, syncThemeFromStorage } from \"@kamod-ch/themes\";\nimport type { ComponentChildren, JSX } from \"preact\";\nimport { useEffect } from \"preact/hooks\";\nimport { cn } from \"../../lib/utils\";\nimport { Button } from \"../button\";\n\nexport type ThemeToggleProps = Omit<JSX.ButtonHTMLAttributes<HTMLButtonElement>, \"class\"> & {\n class?: string;\n children?: ComponentChildren;\n};\n\nconst SunIcon = ({ class: className }: { class?: string }) => (\n <svg\n class={cn(\"size-4 shrink-0\", className)}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"4\" />\n <path d=\"M12 2v2\" />\n <path d=\"M12 20v2\" />\n <path d=\"m4.93 4.93 1.41 1.41\" />\n <path d=\"m17.66 17.66 1.41 1.41\" />\n <path d=\"M2 12h2\" />\n <path d=\"M20 12h2\" />\n <path d=\"m6.34 17.66-1.41 1.41\" />\n <path d=\"m19.07 4.93-1.41 1.41\" />\n </svg>\n);\n\nconst MoonIcon = ({ class: className }: { class?: string }) => (\n <svg\n class={cn(\"size-4 shrink-0\", className)}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z\" />\n </svg>\n);\n\nexport const ThemeToggle = ({ children, onClick, ...rest }: ThemeToggleProps) => {\n useEffect(() => {\n syncThemeFromStorage();\n }, []);\n\n const darkMode = resolvedColorSchemeSignal.value === \"dark\";\n\n return (\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"icon\"\n data-slot=\"theme-toggle\"\n data-state={darkMode ? \"dark\" : \"light\"}\n aria-label={children == null ? (darkMode ? \"Light mode\" : \"Dark mode\") : undefined}\n onClick={(event) => {\n const next = resolvedColorSchemeSignal.value === \"dark\" ? \"light\" : \"dark\";\n setColorScheme(next);\n onClick?.(event);\n }}\n {...rest}\n >\n {children ?? (darkMode ? <SunIcon /> : <MoonIcon />)}\n </Button>\n );\n};\n","import { ThemeToggle } from \"./ThemeToggle\";\n\nexport { ThemeToggle };\n\nexport default ThemeToggle;\n"]}
@@ -0,0 +1,59 @@
1
+ import { createElement, render } from 'preact';
2
+
3
+ // src/lib/createPortal.tsx
4
+ function ContextProvider() {
5
+ this.getChildContext = () => this.props.context;
6
+ return this.props.children;
7
+ }
8
+ function Portal(props) {
9
+ const container = props._container;
10
+ this.componentWillUnmount = () => {
11
+ if (this._temp) {
12
+ render(null, this._temp);
13
+ this._temp = null;
14
+ this._container = null;
15
+ }
16
+ };
17
+ if (this._container && this._container !== container) {
18
+ this.componentWillUnmount();
19
+ }
20
+ if (!this._temp) {
21
+ let root = this._vnode;
22
+ while (root != null && !root._mask && root._parent != null) {
23
+ root = root._parent;
24
+ }
25
+ this._container = container;
26
+ this._temp = {
27
+ nodeType: 1,
28
+ parentNode: container,
29
+ childNodes: [],
30
+ _children: { _mask: root?._mask },
31
+ contains: () => true,
32
+ namespaceURI: container.namespaceURI,
33
+ insertBefore: (child, before) => {
34
+ this._temp.childNodes.push(child);
35
+ this._container.insertBefore(child, before);
36
+ },
37
+ removeChild: (child) => {
38
+ this._temp.childNodes.splice(this._temp.childNodes.indexOf(child) >>> 1, 1);
39
+ this._container.removeChild(child);
40
+ }
41
+ };
42
+ }
43
+ render(
44
+ createElement(ContextProvider, { context: this.context }, props._vnode),
45
+ this._temp
46
+ );
47
+ }
48
+ function createPortal(vnode, container) {
49
+ const el = createElement(Portal, {
50
+ _vnode: vnode,
51
+ _container: container
52
+ });
53
+ el.containerInfo = container;
54
+ return el;
55
+ }
56
+
57
+ export { createPortal };
58
+ //# sourceMappingURL=chunk-B47B6KK6.js.map
59
+ //# sourceMappingURL=chunk-B47B6KK6.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/createPortal.tsx"],"names":[],"mappings":";;;AAiCA,SAAS,eAAA,GAGN;AACD,EAAA,IAAA,CAAK,eAAA,GAAkB,MAAM,IAAA,CAAK,KAAA,CAAM,OAAA;AACxC,EAAA,OAAO,KAAK,KAAA,CAAM,QAAA;AACpB;AAEA,SAAS,OAA6B,KAAA,EAAoB;AACxD,EAAA,MAAM,YAAY,KAAA,CAAM,UAAA;AAExB,EAAA,IAAA,CAAK,uBAAuB,MAAM;AAChC,IAAA,IAAI,KAAK,KAAA,EAAO;AACd,MAAA,MAAA,CAAO,IAAA,EAAM,KAAK,KAA2B,CAAA;AAC7C,MAAA,IAAA,CAAK,KAAA,GAAQ,IAAA;AACb,MAAA,IAAA,CAAK,UAAA,GAAa,IAAA;AAAA,IACpB;AAAA,EACF,CAAA;AAEA,EAAA,IAAI,IAAA,CAAK,UAAA,IAAc,IAAA,CAAK,UAAA,KAAe,SAAA,EAAW;AACpD,IAAA,IAAA,CAAK,oBAAA,EAAqB;AAAA,EAC5B;AAEA,EAAA,IAAI,CAAC,KAAK,KAAA,EAAO;AACf,IAAA,IAAI,OAAY,IAAA,CAAK,MAAA;AACrB,IAAA,OAAO,QAAQ,IAAA,IAAQ,CAAC,KAAK,KAAA,IAAS,IAAA,CAAK,WAAW,IAAA,EAAM;AAC1D,MAAA,IAAA,GAAO,IAAA,CAAK,OAAA;AAAA,IACd;AAEA,IAAA,IAAA,CAAK,UAAA,GAAa,SAAA;AAElB,IAAA,IAAA,CAAK,KAAA,GAAQ;AAAA,MACX,QAAA,EAAU,CAAA;AAAA,MACV,UAAA,EAAY,SAAA;AAAA,MACZ,YAAY,EAAC;AAAA,MACb,SAAA,EAAW,EAAE,KAAA,EAAO,IAAA,EAAM,KAAA,EAAM;AAAA,MAChC,UAAU,MAAM,IAAA;AAAA,MAChB,cAAc,SAAA,CAAU,YAAA;AAAA,MACxB,YAAA,EAAc,CAAC,KAAA,EAAO,MAAA,KAAW;AAC/B,QAAA,IAAA,CAAK,KAAA,CAAO,UAAA,CAAW,IAAA,CAAK,KAAkB,CAAA;AAC9C,QAAA,IAAA,CAAK,UAAA,CAAY,YAAA,CAAa,KAAA,EAAO,MAAM,CAAA;AAAA,MAC7C,CAAA;AAAA,MACA,WAAA,EAAa,CAAC,KAAA,KAAU;AACtB,QAAA,IAAA,CAAK,KAAA,CAAO,UAAA,CAAW,MAAA,CAAO,IAAA,CAAK,KAAA,CAAO,WAAW,OAAA,CAAQ,KAAkB,CAAA,KAAM,CAAA,EAAG,CAAC,CAAA;AACzF,QAAA,IAAA,CAAK,UAAA,CAAY,YAAY,KAAK,CAAA;AAAA,MACpC;AAAA,KACF;AAAA,EACF;AAEA,EAAA,MAAA;AAAA,IACE,aAAA,CAAc,iBAAwB,EAAE,OAAA,EAAS,KAAK,OAAA,EAAQ,EAAG,MAAM,MAAM,CAAA;AAAA,IAC7E,IAAA,CAAK;AAAA,GACP;AACF;AAEO,SAAS,YAAA,CAAa,OAA0B,SAAA,EAA+B;AACpF,EAAA,MAAM,EAAA,GAAK,cAAc,MAAA,EAAe;AAAA,IACtC,MAAA,EAAQ,KAAA;AAAA,IACR,UAAA,EAAY;AAAA,GACb,CAAA;AACD,EAAC,GAA+C,aAAA,GAAgB,SAAA;AAChE,EAAA,OAAO,EAAA;AACT","file":"chunk-B47B6KK6.js","sourcesContent":["import { type ComponentChildren, createElement, render, type VNode } from \"preact\";\n\n/**\n * Minimal DOM parent used by Preact's renderer to mount portal children into `document.body`\n * while preserving context and hooks from the calling tree.\n *\n * @see preact/compat/src/portals.js (inlined to avoid a preact/compat dependency)\n */\ntype PortalMountParent = {\n nodeType: 1;\n parentNode: HTMLElement;\n childNodes: ChildNode[];\n _children: { _mask?: unknown };\n contains: () => true;\n namespaceURI: string | null;\n insertBefore: (child: Node, before: Node | null) => void;\n removeChild: (child: Node) => void;\n};\n\ntype PortalProps = {\n _vnode: any;\n _container: HTMLElement;\n};\n\ntype PortalInstance = {\n _vnode?: any;\n _temp: PortalMountParent | null;\n _container: HTMLElement | null;\n context: Record<string, unknown>;\n props: PortalProps;\n componentWillUnmount: () => void;\n};\n\nfunction ContextProvider(this: {\n getChildContext: () => unknown;\n props: { context: unknown; children: ComponentChildren };\n}) {\n this.getChildContext = () => this.props.context;\n return this.props.children;\n}\n\nfunction Portal(this: PortalInstance, props: PortalProps) {\n const container = props._container;\n\n this.componentWillUnmount = () => {\n if (this._temp) {\n render(null, this._temp as unknown as Element);\n this._temp = null;\n this._container = null;\n }\n };\n\n if (this._container && this._container !== container) {\n this.componentWillUnmount();\n }\n\n if (!this._temp) {\n let root: any = this._vnode;\n while (root != null && !root._mask && root._parent != null) {\n root = root._parent;\n }\n\n this._container = container;\n\n this._temp = {\n nodeType: 1,\n parentNode: container,\n childNodes: [],\n _children: { _mask: root?._mask },\n contains: () => true,\n namespaceURI: container.namespaceURI,\n insertBefore: (child, before) => {\n this._temp!.childNodes.push(child as ChildNode);\n this._container!.insertBefore(child, before);\n },\n removeChild: (child) => {\n this._temp!.childNodes.splice(this._temp!.childNodes.indexOf(child as ChildNode) >>> 1, 1);\n this._container!.removeChild(child);\n },\n };\n }\n\n render(\n createElement(ContextProvider as any, { context: this.context }, props._vnode),\n this._temp as unknown as Element,\n );\n}\n\nexport function createPortal(vnode: ComponentChildren, container: HTMLElement): VNode {\n const el = createElement(Portal as any, {\n _vnode: vnode,\n _container: container,\n }) as VNode;\n (el as VNode & { containerInfo?: HTMLElement }).containerInfo = container;\n return el;\n}\n"]}
@@ -1,7 +1,7 @@
1
- import { Dialog, useDialog, useModalPanelA11y, dialogViewportBleedClass, DialogClose } from './chunk-4BJJOHZT.js';
1
+ import { Dialog, useDialog, useModalPanelA11y, dialogViewportBleedClass, DialogClose } from './chunk-HHLQYMPT.js';
2
+ import { createPortal } from './chunk-B47B6KK6.js';
2
3
  import { cn } from './chunk-MS2ZNYCJ.js';
3
4
  import { jsx, jsxs, Fragment } from 'preact/jsx-runtime';
4
- import { createPortal } from 'preact/compat';
5
5
 
6
6
  var Sheet = ({ children, lockBodyScroll = true, ...rest }) => /* @__PURE__ */ jsx(Dialog, { "data-slot": "sheet", lockBodyScroll, ...rest, children });
7
7
  var sidePanelClass = {
@@ -91,5 +91,5 @@ var SheetFooter = ({ children, ...rest }) => /* @__PURE__ */ jsx("div", { "data-
91
91
  var SheetHeader = ({ children, ...rest }) => /* @__PURE__ */ jsx("div", { "data-slot": "sheet-header", ...rest, children });
92
92
 
93
93
  export { Sheet, SheetContent, SheetFooter, SheetHeader };
94
- //# sourceMappingURL=chunk-JKXSX67K.js.map
95
- //# sourceMappingURL=chunk-JKXSX67K.js.map
94
+ //# sourceMappingURL=chunk-EMUPVA2F.js.map
95
+ //# sourceMappingURL=chunk-EMUPVA2F.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/sheet/Sheet.tsx","../src/components/sheet/SheetContent.tsx","../src/components/sheet/SheetFooter.tsx","../src/components/sheet/SheetHeader.tsx"],"names":["jsx"],"mappings":"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","file":"chunk-EMUPVA2F.js","sourcesContent":["import type { ComponentChildren } from \"preact\";\nimport { Dialog, type DialogProps } from \"../dialog/Dialog\";\n\nexport type SheetProps = DialogProps & { children?: ComponentChildren };\n\nexport const Sheet = ({ children, lockBodyScroll = true, ...rest }: SheetProps) => (\n <Dialog data-slot=\"sheet\" lockBodyScroll={lockBodyScroll} {...rest}>\n {children}\n </Dialog>\n);\n","import type { ComponentChildren, JSX } from \"preact\";\nimport { createPortal } from \"../../lib/createPortal\";\nimport { cn } from \"../../lib/utils\";\nimport { useDialog } from \"../dialog/Dialog\";\nimport { dialogViewportBleedClass } from \"../dialog/DialogContent\";\nimport { useModalPanelA11y } from \"../dialog/useModalPanelA11y\";\nimport { SheetClose } from \"./SheetClose\";\n\nexport type SheetContentProps = JSX.HTMLAttributes<HTMLDivElement> & {\n side?: \"left\" | \"right\" | \"top\" | \"bottom\";\n forceMount?: boolean;\n showCloseButton?: boolean;\n children?: ComponentChildren;\n \"data-slot\"?: string;\n};\n\nconst sidePanelClass: Record<NonNullable<SheetContentProps[\"side\"]>, string> = {\n right:\n \"inset-y-0 right-0 h-full w-full max-w-md border-l data-[state=open]:slide-in-from-right data-[state=closed]:slide-out-to-right\",\n left: \"inset-y-0 left-0 h-full w-full max-w-md border-r data-[state=open]:slide-in-from-left data-[state=closed]:slide-out-to-left\",\n top: \"inset-x-0 top-0 max-h-[85dvh] h-auto w-full min-w-0 border-b rounded-b-xl data-[state=open]:slide-in-from-top data-[state=closed]:slide-out-to-top\",\n bottom:\n \"inset-x-0 bottom-0 max-h-[85dvh] h-auto w-full min-w-0 border-t rounded-t-xl data-[state=open]:slide-in-from-bottom data-[state=closed]:slide-out-to-bottom\",\n};\n\nexport const SheetContent = ({\n side = \"right\",\n showCloseButton = true,\n children,\n class: className,\n forceMount = false,\n \"data-slot\": dataSlot = \"sheet-content\",\n \"aria-labelledby\": ariaLabelledBy,\n \"aria-describedby\": ariaDescribedBy,\n ...rest\n}: SheetContentProps) => {\n const dialog = useDialog();\n const isOpen = dialog.open.value;\n const { panelRef, labelledBy, describedBy } = useModalPanelA11y(isOpen || forceMount);\n if (!isOpen && !forceMount) return null;\n\n const state = isOpen ? \"open\" : \"closed\";\n const isHorizontalEdge = side === \"top\" || side === \"bottom\";\n const edgePadding =\n side === \"top\"\n ? \"px-6 pb-6 pt-[calc(1.5rem+env(safe-area-inset-top,0px))]\"\n : side === \"bottom\"\n ? \"px-6 pt-6 pb-[calc(1.5rem+env(safe-area-inset-bottom,0px))]\"\n : \"p-6\";\n\n const modalA11y = {\n \"aria-labelledby\": ariaLabelledBy ?? labelledBy,\n \"aria-describedby\": ariaDescribedBy ?? describedBy,\n };\n\n const tree = (\n <>\n <div\n aria-hidden=\"true\"\n data-slot=\"sheet-overlay\"\n data-state={state}\n class={cn(\n \"fade-in fade-out\",\n dialogViewportBleedClass,\n \"z-40 bg-black/50 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fill-mode-forwards\",\n )}\n />\n <div\n ref={panelRef}\n {...rest}\n {...modalA11y}\n role=\"dialog\"\n aria-modal=\"true\"\n tabIndex={-1}\n data-side={side}\n data-state={state}\n data-slot={dataSlot}\n class={cn(\n \"fixed z-50 flex min-h-0 min-w-0 flex-col gap-4 overflow-y-auto border bg-background shadow-lg outline-none\",\n edgePadding,\n \"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fill-mode-forwards duration-300\",\n sidePanelClass[side],\n className,\n isHorizontalEdge && \"w-full !max-w-none\",\n )}\n >\n {showCloseButton ? (\n <SheetClose\n data-slot=\"sheet-close\"\n aria-label=\"Close sheet\"\n class={cn(\n \"absolute right-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none\",\n side === \"top\" ? \"top-[calc(1rem+env(safe-area-inset-top,0px))]\" : \"top-4\",\n )}\n >\n Close\n </SheetClose>\n ) : null}\n {children}\n </div>\n </>\n );\n\n if (typeof document === \"undefined\") return tree;\n return createPortal(tree, document.body);\n};\n","import type { ComponentChildren, JSX } from \"preact\";\n\nexport type SheetFooterProps = JSX.HTMLAttributes<HTMLDivElement> & {\n children?: ComponentChildren;\n};\n\nexport const SheetFooter = ({ children, ...rest }: SheetFooterProps) => (\n <div data-slot=\"sheet-footer\" {...rest}>\n {children}\n </div>\n);\n","import type { ComponentChildren, JSX } from \"preact\";\n\nexport type SheetHeaderProps = JSX.HTMLAttributes<HTMLDivElement> & {\n children?: ComponentChildren;\n};\n\nexport const SheetHeader = ({ children, ...rest }: SheetHeaderProps) => (\n <div data-slot=\"sheet-header\" {...rest}>\n {children}\n </div>\n);\n"]}
@@ -1,8 +1,7 @@
1
1
  import { createIdFactory } from './chunk-PPYJQNE5.js';
2
2
  import { cn } from './chunk-MS2ZNYCJ.js';
3
- import { useSignal } from '@preact/signals';
4
3
  import { createContext } from 'preact';
5
- import { useMemo, useEffect, useContext } from 'preact/hooks';
4
+ import { useState, useMemo, useEffect, useContext } from 'preact/hooks';
6
5
  import { jsx } from 'preact/jsx-runtime';
7
6
  import { tv } from 'tailwind-variants';
8
7
 
@@ -32,29 +31,31 @@ var Tabs = ({
32
31
  children,
33
32
  ...rest
34
33
  }) => {
35
- const value = useSignal(defaultValue);
34
+ const [value, setLocalValue] = useState(defaultValue);
36
35
  const baseId = useMemo(() => createIdFactory("tabs")(), []);
37
36
  const triggerId = useMemo(() => (tabValue) => `${baseId}-trigger-${tabValue}`, [baseId]);
38
37
  const contentId = useMemo(() => (tabValue) => `${baseId}-content-${tabValue}`, [baseId]);
39
38
  const setValue = (next) => {
40
39
  if (!syncKey) {
41
- value.value = next;
40
+ setLocalValue(next);
42
41
  return;
43
42
  }
44
- const syncEntry = getOrCreateSyncEntry(syncKey, value.value);
43
+ const syncEntry = getOrCreateSyncEntry(syncKey, value);
45
44
  if (syncEntry.value === next) return;
46
45
  syncEntry.value = next;
47
- value.value = next;
46
+ setLocalValue(next);
48
47
  syncEntry.subscribers.forEach((subscriber) => subscriber(next));
49
48
  };
50
49
  useEffect(() => {
51
50
  if (!syncKey) return;
52
51
  const syncEntry = getOrCreateSyncEntry(syncKey, defaultValue);
53
52
  syncEntry.instancesCount += 1;
54
- value.value = syncEntry.value;
53
+ setLocalValue(syncEntry.value);
55
54
  const subscriber = (nextValue) => {
56
- if (value.value === nextValue) return;
57
- value.value = nextValue;
55
+ setLocalValue((currentValue) => {
56
+ if (currentValue === nextValue) return currentValue;
57
+ return nextValue;
58
+ });
58
59
  };
59
60
  syncEntry.subscribers.add(subscriber);
60
61
  return () => {
@@ -64,7 +65,7 @@ var Tabs = ({
64
65
  syncRegistry.delete(syncKey);
65
66
  }
66
67
  };
67
- }, [defaultValue, syncKey, value]);
68
+ }, [defaultValue, syncKey]);
68
69
  return /* @__PURE__ */ jsx(TabsContext.Provider, { value: { value, setValue, orientation, baseId, triggerId, contentId }, children: /* @__PURE__ */ jsx(
69
70
  "div",
70
71
  {
@@ -85,7 +86,7 @@ var TabsContent = ({
85
86
  ...rest
86
87
  }) => {
87
88
  const tabs = useTabs();
88
- const active = tabs.value.value === value;
89
+ const active = tabs.value === value;
89
90
  const id = idProp ?? tabs.contentId(value);
90
91
  const labelledBy = tabs.triggerId(value);
91
92
  if (!active && !forceMount) return null;
@@ -119,7 +120,7 @@ var tabsList = tv({
119
120
  variants: {
120
121
  variant: {
121
122
  default: "",
122
- line: "rounded-none gap-1 bg-transparent p-0"
123
+ line: "gap-1 rounded-none bg-transparent p-0 ring-0 group-data-[orientation=horizontal]/tabs:rounded-none"
123
124
  }
124
125
  },
125
126
  defaultVariants: {
@@ -152,7 +153,7 @@ var TabsTrigger = ({
152
153
  ...rest
153
154
  }) => {
154
155
  const tabs = useTabs();
155
- const active = tabs.value.value === value;
156
+ const active = tabs.value === value;
156
157
  const id = idProp ?? tabs.triggerId(value);
157
158
  const controlsId = tabs.contentId(value);
158
159
  return /* @__PURE__ */ jsx(
@@ -174,13 +175,14 @@ var TabsTrigger = ({
174
175
  "dark:group-data-[variant=default]/tabs-list:data-[state=active]:shadow-[0_1px_2px_-0.5px_rgb(0_0_0/0.35)] dark:group-data-[variant=default]/tabs-list:data-[state=active]:ring-1 dark:group-data-[variant=default]/tabs-list:data-[state=active]:ring-white/[0.08]",
175
176
  "group-data-[variant=line]/tabs-list:rounded-none group-data-[variant=line]/tabs-list:px-0 group-data-[variant=line]/tabs-list:data-[state=active]:shadow-none dark:group-data-[variant=line]/tabs-list:data-[state=active]:ring-0",
176
177
  "[&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
177
- "group-data-[variant=line]/tabs-list:bg-transparent group-data-[variant=line]/tabs-list:data-[state=active]:bg-transparent group-data-[variant=line]/tabs-list:data-[state=active]:text-foreground",
178
+ "group-data-[variant=line]/tabs-list:bg-transparent group-data-[variant=line]/tabs-list:data-[state=active]:bg-transparent group-data-[variant=line]/tabs-list:data-[state=active]:font-semibold group-data-[variant=line]/tabs-list:data-[state=active]:text-foreground",
179
+ "group-data-[variant=line]/tabs-list:data-[state=inactive]:font-normal group-data-[variant=line]/tabs-list:data-[state=inactive]:text-muted-foreground",
178
180
  "dark:group-data-[variant=line]/tabs-list:data-[state=active]:border-transparent dark:group-data-[variant=line]/tabs-list:data-[state=active]:bg-transparent",
179
181
  "dark:group-data-[variant=default]/tabs-list:data-[state=active]:bg-input/30 dark:group-data-[variant=default]/tabs-list:data-[state=active]:text-foreground",
180
182
  "after:absolute after:bg-foreground after:opacity-0 after:transition-opacity",
181
183
  "group-data-[orientation=horizontal]/tabs:after:inset-x-0 group-data-[orientation=horizontal]/tabs:after:bottom-[-5px] group-data-[orientation=horizontal]/tabs:after:h-0.5",
182
184
  "group-data-[orientation=vertical]/tabs:after:inset-y-0 group-data-[orientation=vertical]/tabs:after:-right-1 group-data-[orientation=vertical]/tabs:after:w-0.5",
183
- "group-data-[variant=line]/tabs-list:data-[state=active]:after:opacity-100",
185
+ "group-data-[variant=line]/tabs-list:data-[state=active]:after:h-[2px] group-data-[variant=line]/tabs-list:data-[state=active]:after:opacity-100",
184
186
  className
185
187
  ),
186
188
  "data-slot": "tabs-trigger",
@@ -240,5 +242,5 @@ var tabs_default = {
240
242
  };
241
243
 
242
244
  export { Tabs, TabsContent, TabsList, TabsTrigger, tabs_default };
243
- //# sourceMappingURL=chunk-26CRIZXP.js.map
244
- //# sourceMappingURL=chunk-26CRIZXP.js.map
245
+ //# sourceMappingURL=chunk-HCTZJYHK.js.map
246
+ //# sourceMappingURL=chunk-HCTZJYHK.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/tabs/Tabs.tsx","../src/components/tabs/TabsContent.tsx","../src/components/tabs/TabsList.tsx","../src/components/tabs/TabsTrigger.tsx","../src/components/tabs/index.ts"],"names":["jsx"],"mappings":"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","file":"chunk-HCTZJYHK.js","sourcesContent":["import type { ComponentChildren, JSX } from \"preact\";\nimport { createContext } from \"preact\";\nimport { useContext, useEffect, useMemo, useState } from \"preact/hooks\";\nimport { createIdFactory } from \"../../lib/interactive\";\nimport { cn } from \"../../lib/utils\";\n\ntype TabsContextValue = {\n value: string;\n setValue: (next: string) => void;\n orientation: \"horizontal\" | \"vertical\";\n baseId: string;\n triggerId: (tabValue: string) => string;\n contentId: (tabValue: string) => string;\n};\n\nconst TabsContext = createContext<TabsContextValue | null>(null);\n\nexport const useTabs = () => {\n const context = useContext(TabsContext);\n if (!context) throw new Error(\"Tabs subcomponents must be used within Tabs\");\n return context;\n};\n\nexport type TabsProps = JSX.HTMLAttributes<HTMLDivElement> & {\n defaultValue: string;\n syncKey?: string;\n orientation?: \"horizontal\" | \"vertical\";\n children?: ComponentChildren;\n};\n\ntype SyncSubscriber = (nextValue: string) => void;\n\ntype SyncRegistryEntry = {\n value: string;\n subscribers: Set<SyncSubscriber>;\n instancesCount: number;\n};\n\nconst syncRegistry = new Map<string, SyncRegistryEntry>();\n\nconst getOrCreateSyncEntry = (key: string, initialValue: string): SyncRegistryEntry => {\n const existing = syncRegistry.get(key);\n if (existing) return existing;\n\n const created: SyncRegistryEntry = {\n value: initialValue,\n subscribers: new Set<SyncSubscriber>(),\n instancesCount: 0,\n };\n syncRegistry.set(key, created);\n return created;\n};\n\nexport const Tabs = ({\n defaultValue,\n syncKey,\n orientation = \"horizontal\",\n class: className,\n children,\n ...rest\n}: TabsProps) => {\n const [value, setLocalValue] = useState(defaultValue);\n const baseId = useMemo(() => createIdFactory(\"tabs\")(), []);\n const triggerId = useMemo(() => (tabValue: string) => `${baseId}-trigger-${tabValue}`, [baseId]);\n const contentId = useMemo(() => (tabValue: string) => `${baseId}-content-${tabValue}`, [baseId]);\n const setValue = (next: string) => {\n if (!syncKey) {\n setLocalValue(next);\n return;\n }\n\n const syncEntry = getOrCreateSyncEntry(syncKey, value);\n if (syncEntry.value === next) return;\n\n syncEntry.value = next;\n setLocalValue(next);\n syncEntry.subscribers.forEach((subscriber) => subscriber(next));\n };\n\n useEffect(() => {\n if (!syncKey) return;\n\n const syncEntry = getOrCreateSyncEntry(syncKey, defaultValue);\n syncEntry.instancesCount += 1;\n setLocalValue(syncEntry.value);\n\n const subscriber: SyncSubscriber = (nextValue) => {\n setLocalValue((currentValue) => {\n if (currentValue === nextValue) return currentValue;\n return nextValue;\n });\n };\n syncEntry.subscribers.add(subscriber);\n\n return () => {\n syncEntry.subscribers.delete(subscriber);\n syncEntry.instancesCount -= 1;\n if (syncEntry.instancesCount <= 0) {\n syncRegistry.delete(syncKey);\n }\n };\n }, [defaultValue, syncKey]);\n\n return (\n <TabsContext.Provider value={{ value, setValue, orientation, baseId, triggerId, contentId }}>\n <div\n class={cn(\"group/tabs\", className)}\n data-slot=\"tabs\"\n data-orientation={orientation}\n {...rest}\n >\n {children}\n </div>\n </TabsContext.Provider>\n );\n};\n","import type { ComponentChildren, JSX } from \"preact\";\nimport { cn } from \"../../lib/utils\";\nimport { useTabs } from \"./Tabs\";\n\nexport type TabsContentProps = JSX.HTMLAttributes<HTMLDivElement> & {\n value: string;\n forceMount?: boolean;\n children?: ComponentChildren;\n};\n\nexport const TabsContent = ({\n value,\n forceMount = false,\n class: className,\n children,\n id: idProp,\n ...rest\n}: TabsContentProps) => {\n const tabs = useTabs();\n const active = tabs.value === value;\n const id = idProp ?? tabs.contentId(value);\n const labelledBy = tabs.triggerId(value);\n\n if (!active && !forceMount) return null;\n\n return (\n <div\n role=\"tabpanel\"\n id={id}\n aria-labelledby={labelledBy}\n aria-hidden={!active || undefined}\n data-slot=\"tabs-content\"\n data-state={active ? \"active\" : \"inactive\"}\n class={cn(\n \"mt-2 outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\",\n className,\n )}\n tabIndex={0}\n hidden={!active && forceMount ? true : undefined}\n {...rest}\n >\n {children}\n </div>\n );\n};\n","import type { ComponentChildren, JSX } from \"preact\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\nimport { cn } from \"../../lib/utils\";\nimport { useTabs } from \"./Tabs\";\n\nconst tabsList = tv({\n base: [\n \"group/tabs-list inline-flex w-fit items-stretch justify-center gap-0.5 rounded-md bg-muted/80 p-0.5 text-muted-foreground\",\n \"ring-1 ring-inset ring-black/[0.04] dark:ring-white/[0.06]\",\n \"group-data-[orientation=horizontal]/tabs:h-9 group-data-[orientation=horizontal]/tabs:rounded-full\",\n \"group-data-[orientation=vertical]/tabs:h-fit group-data-[orientation=vertical]/tabs:flex-col group-data-[orientation=vertical]/tabs:rounded-xl group-data-[orientation=vertical]/tabs:gap-0.5 group-data-[orientation=vertical]/tabs:p-1\",\n ],\n variants: {\n variant: {\n default: \"\",\n line: \"gap-1 rounded-none bg-transparent p-0 ring-0 group-data-[orientation=horizontal]/tabs:rounded-none\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n },\n});\n\nexport type TabsListProps = JSX.HTMLAttributes<HTMLDivElement> &\n VariantProps<typeof tabsList> & {\n children?: ComponentChildren;\n };\n\nexport const TabsList = ({ variant, class: className, children, ...rest }: TabsListProps) => {\n const tabs = useTabs();\n\n return (\n <div\n role=\"tablist\"\n aria-orientation={tabs.orientation}\n class={cn(tabsList({ variant }), className)}\n data-slot=\"tabs-list\"\n data-variant={variant ?? \"default\"}\n data-orientation={tabs.orientation}\n {...rest}\n >\n {children}\n </div>\n );\n};\n","import type { ComponentChildren, JSX } from \"preact\";\nimport { cn } from \"../../lib/utils\";\nimport { useTabs } from \"./Tabs\";\n\nexport type TabsTriggerProps = JSX.ButtonHTMLAttributes<HTMLButtonElement> & {\n value: string;\n children?: ComponentChildren;\n};\n\nexport const TabsTrigger = ({\n value,\n class: className,\n children,\n onClick,\n onKeyDown,\n id: idProp,\n ...rest\n}: TabsTriggerProps) => {\n const tabs = useTabs();\n const active = tabs.value === value;\n const id = idProp ?? tabs.triggerId(value);\n const controlsId = tabs.contentId(value);\n\n return (\n <button\n type=\"button\"\n role=\"tab\"\n id={id}\n aria-controls={controlsId}\n class={cn(\n \"relative inline-flex h-full min-h-0 flex-1 items-center justify-center gap-1.5 border border-transparent px-3 py-1 text-sm whitespace-nowrap text-muted-foreground transition-[color,box-shadow,background-color,font-weight] duration-200 ease-out\",\n \"group-data-[orientation=horizontal]/tabs:rounded-full group-data-[orientation=vertical]/tabs:rounded-md\",\n \"group-data-[orientation=vertical]/tabs:w-full group-data-[orientation=vertical]/tabs:justify-start\",\n \"hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background\",\n \"disabled:pointer-events-none disabled:opacity-50 dark:hover:text-foreground\",\n \"group-data-[variant=default]/tabs-list:data-[state=inactive]:font-medium\",\n \"group-data-[variant=default]/tabs-list:data-[state=active]:bg-background group-data-[variant=default]/tabs-list:data-[state=active]:font-semibold group-data-[variant=default]/tabs-list:data-[state=active]:text-foreground\",\n \"group-data-[variant=default]/tabs-list:data-[state=active]:shadow-[0_1px_2px_-0.5px_rgb(0_0_0/0.06),0_1px_3px_-1px_rgb(0_0_0/0.08)]\",\n \"dark:group-data-[variant=default]/tabs-list:data-[state=active]:shadow-[0_1px_2px_-0.5px_rgb(0_0_0/0.35)] dark:group-data-[variant=default]/tabs-list:data-[state=active]:ring-1 dark:group-data-[variant=default]/tabs-list:data-[state=active]:ring-white/[0.08]\",\n \"group-data-[variant=line]/tabs-list:rounded-none group-data-[variant=line]/tabs-list:px-0 group-data-[variant=line]/tabs-list:data-[state=active]:shadow-none dark:group-data-[variant=line]/tabs-list:data-[state=active]:ring-0\",\n \"[&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n \"group-data-[variant=line]/tabs-list:bg-transparent group-data-[variant=line]/tabs-list:data-[state=active]:bg-transparent group-data-[variant=line]/tabs-list:data-[state=active]:font-semibold group-data-[variant=line]/tabs-list:data-[state=active]:text-foreground\",\n \"group-data-[variant=line]/tabs-list:data-[state=inactive]:font-normal group-data-[variant=line]/tabs-list:data-[state=inactive]:text-muted-foreground\",\n \"dark:group-data-[variant=line]/tabs-list:data-[state=active]:border-transparent dark:group-data-[variant=line]/tabs-list:data-[state=active]:bg-transparent\",\n \"dark:group-data-[variant=default]/tabs-list:data-[state=active]:bg-input/30 dark:group-data-[variant=default]/tabs-list:data-[state=active]:text-foreground\",\n \"after:absolute after:bg-foreground after:opacity-0 after:transition-opacity\",\n \"group-data-[orientation=horizontal]/tabs:after:inset-x-0 group-data-[orientation=horizontal]/tabs:after:bottom-[-5px] group-data-[orientation=horizontal]/tabs:after:h-0.5\",\n \"group-data-[orientation=vertical]/tabs:after:inset-y-0 group-data-[orientation=vertical]/tabs:after:-right-1 group-data-[orientation=vertical]/tabs:after:w-0.5\",\n \"group-data-[variant=line]/tabs-list:data-[state=active]:after:h-[2px] group-data-[variant=line]/tabs-list:data-[state=active]:after:opacity-100\",\n className,\n )}\n data-slot=\"tabs-trigger\"\n data-state={active ? \"active\" : \"inactive\"}\n data-active={active ? \"true\" : undefined}\n data-value={value}\n data-orientation={tabs.orientation}\n aria-selected={active}\n tabIndex={active ? 0 : -1}\n onClick={(event) => {\n tabs.setValue(value);\n onClick?.(event);\n }}\n onKeyDown={(event) => {\n onKeyDown?.(event);\n if (event.defaultPrevented) return;\n if (![\"ArrowLeft\", \"ArrowRight\", \"ArrowUp\", \"ArrowDown\", \"Home\", \"End\"].includes(event.key))\n return;\n\n const tabList = event.currentTarget.closest('[role=\"tablist\"]');\n if (!tabList) return;\n\n const triggers = Array.from(\n tabList.querySelectorAll<HTMLButtonElement>('[role=\"tab\"]:not([disabled])'),\n );\n const currentIndex = triggers.indexOf(event.currentTarget);\n if (currentIndex === -1 || triggers.length === 0) return;\n\n const horizontal = tabs.orientation === \"horizontal\";\n let nextIndex = currentIndex;\n\n if (event.key === \"Home\") nextIndex = 0;\n if (event.key === \"End\") nextIndex = triggers.length - 1;\n if (event.key === \"ArrowRight\" && horizontal)\n nextIndex = (currentIndex + 1) % triggers.length;\n if (event.key === \"ArrowLeft\" && horizontal)\n nextIndex = (currentIndex - 1 + triggers.length) % triggers.length;\n if (event.key === \"ArrowDown\" && !horizontal)\n nextIndex = (currentIndex + 1) % triggers.length;\n if (event.key === \"ArrowUp\" && !horizontal)\n nextIndex = (currentIndex - 1 + triggers.length) % triggers.length;\n\n if (nextIndex === currentIndex) return;\n event.preventDefault();\n const next = triggers[nextIndex];\n next.focus();\n const nextValue = next.getAttribute(\"data-value\");\n if (nextValue) tabs.setValue(nextValue);\n }}\n {...rest}\n >\n {children}\n </button>\n );\n};\n","import { Tabs } from \"./Tabs\";\nimport { TabsContent } from \"./TabsContent\";\nimport { TabsList } from \"./TabsList\";\nimport { TabsTrigger } from \"./TabsTrigger\";\n\nexport { Tabs, TabsContent, TabsList, TabsTrigger };\n\nexport default {\n Root: Tabs,\n List: TabsList,\n Trigger: TabsTrigger,\n Content: TabsContent,\n};\n"]}
@@ -1,3 +1,4 @@
1
+ import { createPortal } from './chunk-B47B6KK6.js';
1
2
  import { createControllableSignal } from './chunk-C7WEQOUA.js';
2
3
  import { createIdFactory, createDismissableLayer, trapFocus, isPointerWithinModalDialogPanelSlop } from './chunk-PPYJQNE5.js';
3
4
  import { cn } from './chunk-MS2ZNYCJ.js';
@@ -5,7 +6,6 @@ import { signal } from '@preact/signals';
5
6
  import { createContext, isValidElement, cloneElement } from 'preact';
6
7
  import { useContext, useRef, useMemo, useEffect, useLayoutEffect } from 'preact/hooks';
7
8
  import { jsx, jsxs, Fragment } from 'preact/jsx-runtime';
8
- import { createPortal } from 'preact/compat';
9
9
 
10
10
  var SCROLL_LOCK_COUNT_ATTR = "data-kamod-scroll-lock-count";
11
11
  var SCROLL_LOCK_BODY_OVERFLOW_ATTR = "data-kamod-scroll-lock-body-overflow";
@@ -473,5 +473,5 @@ var DialogTrigger = ({
473
473
  };
474
474
 
475
475
  export { Dialog, DialogClose, DialogContent, DialogDescription, DialogTitle, DialogTrigger, dialogViewportBleedClass, useDialog, useModalPanelA11y };
476
- //# sourceMappingURL=chunk-4BJJOHZT.js.map
477
- //# sourceMappingURL=chunk-4BJJOHZT.js.map
476
+ //# sourceMappingURL=chunk-HHLQYMPT.js.map
477
+ //# sourceMappingURL=chunk-HHLQYMPT.js.map