@alfadocs/ui-kit-debug 0.23.0 → 0.24.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/dist/_chunks/{autocomplete-BxfabhZ8.js → autocomplete-C7xq06bP.js} +40 -40
- package/dist/_chunks/{autocomplete-BxfabhZ8.js.map → autocomplete-C7xq06bP.js.map} +1 -1
- package/dist/_chunks/editable-currency-cell-renderer-DJB5MxAI.js +2349 -0
- package/dist/_chunks/editable-currency-cell-renderer-DJB5MxAI.js.map +1 -0
- package/dist/_chunks/locale-picker-CYBhgSHR.js +575 -0
- package/dist/_chunks/locale-picker-CYBhgSHR.js.map +1 -0
- package/dist/_chunks/{patient-shell-DavGODt9.js → patient-shell-B164drIa.js} +40 -55
- package/dist/_chunks/patient-shell-B164drIa.js.map +1 -0
- package/dist/_chunks/settings-ca2Yi9R8.js +21 -0
- package/dist/_chunks/settings-ca2Yi9R8.js.map +1 -0
- package/dist/_chunks/sun-Eweh5fvi.js +50 -0
- package/dist/_chunks/sun-Eweh5fvi.js.map +1 -0
- package/dist/_chunks/{theme-toggle-BswYl0Yp.js → theme-toggle-FrotC2VI.js} +85 -127
- package/dist/_chunks/{theme-toggle-BswYl0Yp.js.map → theme-toggle-FrotC2VI.js.map} +1 -1
- package/dist/_chunks/use-locale-BkCIHujH.js +20 -0
- package/dist/_chunks/use-locale-BkCIHujH.js.map +1 -0
- package/dist/_chunks/use-scroll-to-first-error-BrK7dKB_.js +55 -0
- package/dist/_chunks/use-scroll-to-first-error-BrK7dKB_.js.map +1 -0
- package/dist/_chunks/{whatsapp-button-CtlLwM3M.js → whatsapp-button-DUjlWGKf.js} +26 -25
- package/dist/_chunks/{whatsapp-button-CtlLwM3M.js.map → whatsapp-button-DUjlWGKf.js.map} +1 -1
- package/dist/agent-catalog.json +59 -1
- package/dist/components/autocomplete/autocomplete.d.ts.map +1 -1
- package/dist/components/autocomplete/index.js +1 -1
- package/dist/components/data-table/data-table.d.ts.map +1 -1
- package/dist/components/data-table/filters/number-filter.d.ts +56 -0
- package/dist/components/data-table/filters/number-filter.d.ts.map +1 -0
- package/dist/components/data-table/filters/text-filter.d.ts +49 -0
- package/dist/components/data-table/filters/text-filter.d.ts.map +1 -0
- package/dist/components/data-table/index.d.ts +4 -0
- package/dist/components/data-table/index.d.ts.map +1 -1
- package/dist/components/data-table/index.js +25 -21
- package/dist/components/header-settings/index.js +205 -0
- package/dist/components/header-settings/index.js.map +1 -0
- package/dist/components/locale-picker/index.js +7 -0
- package/dist/components/locale-picker/index.js.map +1 -0
- package/dist/components/theme-toggle/index.js +1 -1
- package/dist/components/whatsapp-button/index.js +1 -1
- package/dist/components/whatsapp-button/whatsapp-button.d.ts +14 -1
- package/dist/components/whatsapp-button/whatsapp-button.d.ts.map +1 -1
- package/dist/fonts/Lexend-VF-latin-ext.woff2 +0 -0
- package/dist/fonts/Lexend-VF-latin.woff2 +0 -0
- package/dist/fonts/Lexend-VF-vietnamese.woff2 +0 -0
- package/dist/fonts/NotoSansArabic-VF-arabic.woff2 +0 -0
- package/dist/fonts/NotoSansDevanagari-VF-devanagari.woff2 +0 -0
- package/dist/hooks/index.js +29 -28
- package/dist/hooks/index.js.map +1 -1
- package/dist/i18n/config.js +2726 -134
- package/dist/i18n/config.js.map +1 -1
- package/dist/i18n/locales/ar.d.ts +147 -3
- package/dist/i18n/locales/ar.d.ts.map +1 -1
- package/dist/i18n/locales/de.d.ts +147 -3
- package/dist/i18n/locales/de.d.ts.map +1 -1
- package/dist/i18n/locales/el.d.ts +147 -3
- package/dist/i18n/locales/el.d.ts.map +1 -1
- package/dist/i18n/locales/es.d.ts +147 -3
- package/dist/i18n/locales/es.d.ts.map +1 -1
- package/dist/i18n/locales/fr.d.ts +147 -3
- package/dist/i18n/locales/fr.d.ts.map +1 -1
- package/dist/i18n/locales/hi.d.ts +147 -3
- package/dist/i18n/locales/hi.d.ts.map +1 -1
- package/dist/i18n/locales/ja.d.ts +147 -3
- package/dist/i18n/locales/ja.d.ts.map +1 -1
- package/dist/i18n/locales/nl.d.ts +147 -3
- package/dist/i18n/locales/nl.d.ts.map +1 -1
- package/dist/i18n/locales/pl.d.ts +149 -5
- package/dist/i18n/locales/pl.d.ts.map +1 -1
- package/dist/i18n/locales/pt.d.ts +147 -3
- package/dist/i18n/locales/pt.d.ts.map +1 -1
- package/dist/i18n/locales/ro.d.ts +147 -3
- package/dist/i18n/locales/ro.d.ts.map +1 -1
- package/dist/i18n/locales/ru.d.ts +148 -4
- package/dist/i18n/locales/ru.d.ts.map +1 -1
- package/dist/i18n/locales/sq.d.ts +147 -3
- package/dist/i18n/locales/sq.d.ts.map +1 -1
- package/dist/i18n/locales/sv.d.ts +147 -3
- package/dist/i18n/locales/sv.d.ts.map +1 -1
- package/dist/i18n/locales/tr.d.ts +147 -3
- package/dist/i18n/locales/tr.d.ts.map +1 -1
- package/dist/i18n/locales/zh.d.ts +147 -3
- package/dist/i18n/locales/zh.d.ts.map +1 -1
- package/dist/i18n/resources.d.ts +294 -6
- package/dist/i18n/resources.d.ts.map +1 -1
- package/dist/index.js +512 -507
- package/dist/index.js.map +1 -1
- package/dist/locales/ar.json +149 -5
- package/dist/locales/de.json +149 -5
- package/dist/locales/el.json +149 -5
- package/dist/locales/en.json +147 -3
- package/dist/locales/es.json +149 -5
- package/dist/locales/fr.json +149 -5
- package/dist/locales/hi.json +149 -5
- package/dist/locales/it.json +147 -3
- package/dist/locales/ja.json +149 -5
- package/dist/locales/nl.json +149 -5
- package/dist/locales/pl.json +151 -7
- package/dist/locales/pt.json +149 -5
- package/dist/locales/ro.json +149 -5
- package/dist/locales/ru.json +150 -6
- package/dist/locales/sq.json +149 -5
- package/dist/locales/sv.json +149 -5
- package/dist/locales/tr.json +149 -5
- package/dist/locales/zh.json +149 -5
- package/dist/patterns/patient-shell/index.js +1 -1
- package/dist/tokens.css +2 -2
- package/package.json +10 -1
- package/dist/_chunks/editable-currency-cell-renderer-1t42gENX.js +0 -1972
- package/dist/_chunks/editable-currency-cell-renderer-1t42gENX.js.map +0 -1
- package/dist/_chunks/patient-shell-DavGODt9.js.map +0 -1
- package/dist/_chunks/use-locale-C5rS3Xon.js +0 -71
- package/dist/_chunks/use-locale-C5rS3Xon.js.map +0 -1
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import { jsx as a, jsxs as o } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef as k, useRef as l, useImperativeHandle as T, useCallback as A, useMemo as C } from "react";
|
|
3
|
+
import { c as R } from "../../_chunks/index-D2ZczOXr.js";
|
|
4
|
+
import { useTranslation as N } from "react-i18next";
|
|
5
|
+
import { I } from "../../_chunks/icon-button-C4CGcYuz.js";
|
|
6
|
+
import { D as i } from "../../_chunks/dropdown-menu-DZxwF23X.js";
|
|
7
|
+
import { S as E } from "../../_chunks/switch-D916VW86.js";
|
|
8
|
+
import { c as b, a as M, L as _ } from "../../_chunks/locale-picker-CYBhgSHR.js";
|
|
9
|
+
import { u as H } from "../../_chunks/use-locale-BkCIHujH.js";
|
|
10
|
+
import { u as O } from "../../_chunks/use-theme-B1cwAXJR.js";
|
|
11
|
+
import { u as P } from "../../_chunks/registry-C9nwlNyL.js";
|
|
12
|
+
import { S as x } from "../../_chunks/settings-ca2Yi9R8.js";
|
|
13
|
+
import { S as K, M as j, a as z } from "../../_chunks/sun-Eweh5fvi.js";
|
|
14
|
+
const D = {
|
|
15
|
+
id: "header-settings",
|
|
16
|
+
capabilities: ["view_change"],
|
|
17
|
+
state: {},
|
|
18
|
+
actions: {
|
|
19
|
+
set_locale: {
|
|
20
|
+
safety: "write",
|
|
21
|
+
argsType: "{ locale: string }",
|
|
22
|
+
descriptionKey: "ui.agent.headerSettings.actions.setLocale",
|
|
23
|
+
description: "Switch the active locale to the given IETF tag.",
|
|
24
|
+
invoke: (t, s) => {
|
|
25
|
+
t.setLocale(s.locale);
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
set_theme: {
|
|
29
|
+
safety: "write",
|
|
30
|
+
argsType: '{ theme: "light" | "dark" | "system" }',
|
|
31
|
+
descriptionKey: "ui.agent.headerSettings.actions.setTheme",
|
|
32
|
+
description: "Switch the theme preference.",
|
|
33
|
+
invoke: (t, s) => {
|
|
34
|
+
t.setTheme(s.theme);
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
set_accessibility: {
|
|
38
|
+
safety: "write",
|
|
39
|
+
argsType: '{ accessibility: "default" | "accessible" }',
|
|
40
|
+
descriptionKey: "ui.agent.headerSettings.actions.setAccessibility",
|
|
41
|
+
description: "Switch the accessibility preference.",
|
|
42
|
+
invoke: (t, s) => {
|
|
43
|
+
t.setAccessibility(s.accessibility);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
domHooks: {
|
|
48
|
+
root: {
|
|
49
|
+
attr: "data-component",
|
|
50
|
+
value: "header-settings",
|
|
51
|
+
description: "Marks the HeaderSettings wrapper."
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
function V(t, s) {
|
|
56
|
+
if (!(typeof window > "u"))
|
|
57
|
+
try {
|
|
58
|
+
window.localStorage.setItem(t, s);
|
|
59
|
+
} catch {
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
function G(t) {
|
|
63
|
+
if (typeof document > "u") return;
|
|
64
|
+
const s = document.documentElement;
|
|
65
|
+
s.lang = t, s.dir = b[t].dir;
|
|
66
|
+
}
|
|
67
|
+
const W = R("ds:inline-flex ds:items-center", {
|
|
68
|
+
variants: {
|
|
69
|
+
align: {
|
|
70
|
+
start: "",
|
|
71
|
+
end: ""
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
defaultVariants: { align: "end" }
|
|
75
|
+
}), B = [
|
|
76
|
+
"ds:w-[20rem] ds:p-[var(--spacing-xs)]",
|
|
77
|
+
"ds:rounded-[var(--radius-md)] ds:border ds:border-border",
|
|
78
|
+
"ds:bg-background ds:text-foreground ds:shadow-[var(--shadow-lg)]"
|
|
79
|
+
].join(" "), F = k(
|
|
80
|
+
(t, s) => {
|
|
81
|
+
const {
|
|
82
|
+
align: g = "end",
|
|
83
|
+
disabled: y = !1,
|
|
84
|
+
className: S,
|
|
85
|
+
id: p,
|
|
86
|
+
...v
|
|
87
|
+
} = t, { t: r } = N(), n = O(), { setLocale: m } = H(), h = l(null);
|
|
88
|
+
T(s, () => h.current, []);
|
|
89
|
+
const u = A(
|
|
90
|
+
(e) => {
|
|
91
|
+
m(e), G(e), V(_, e);
|
|
92
|
+
},
|
|
93
|
+
[m]
|
|
94
|
+
), f = l(u);
|
|
95
|
+
f.current = u;
|
|
96
|
+
const c = l(n);
|
|
97
|
+
c.current = n;
|
|
98
|
+
const w = C(
|
|
99
|
+
() => ({
|
|
100
|
+
setLocale: (e) => {
|
|
101
|
+
Object.prototype.hasOwnProperty.call(b, e) && f.current(e);
|
|
102
|
+
},
|
|
103
|
+
setTheme: (e) => c.current.setTheme(e),
|
|
104
|
+
setAccessibility: (e) => c.current.setAccessibility(e)
|
|
105
|
+
}),
|
|
106
|
+
[]
|
|
107
|
+
);
|
|
108
|
+
P(D, w, p);
|
|
109
|
+
const L = n.accessibility === "accessible";
|
|
110
|
+
return /* @__PURE__ */ a(
|
|
111
|
+
"div",
|
|
112
|
+
{
|
|
113
|
+
ref: h,
|
|
114
|
+
"data-component": "header-settings",
|
|
115
|
+
"data-component-id": p,
|
|
116
|
+
className: W({ align: g, className: S }),
|
|
117
|
+
...v,
|
|
118
|
+
children: /* @__PURE__ */ o(i.Root, { children: [
|
|
119
|
+
/* @__PURE__ */ a(i.Trigger, { asChild: !0, children: /* @__PURE__ */ a(
|
|
120
|
+
I,
|
|
121
|
+
{
|
|
122
|
+
disabled: y,
|
|
123
|
+
icon: /* @__PURE__ */ a(x, { "aria-hidden": !0 }),
|
|
124
|
+
"aria-label": r("navigation.headerSettings.trigger")
|
|
125
|
+
}
|
|
126
|
+
) }),
|
|
127
|
+
/* @__PURE__ */ a(i.Portal, { children: /* @__PURE__ */ o(
|
|
128
|
+
i.Content,
|
|
129
|
+
{
|
|
130
|
+
align: g,
|
|
131
|
+
sideOffset: 8,
|
|
132
|
+
className: B,
|
|
133
|
+
onKeyDownCapture: (e) => {
|
|
134
|
+
const d = e.target;
|
|
135
|
+
(d == null ? void 0 : d.tagName) === "INPUT" && // Always allow Escape so the menu can close.
|
|
136
|
+
e.key !== "Escape" && e.stopPropagation();
|
|
137
|
+
},
|
|
138
|
+
children: [
|
|
139
|
+
/* @__PURE__ */ a(i.Label, { children: r("navigation.headerSettings.language.label") }),
|
|
140
|
+
/* @__PURE__ */ a(
|
|
141
|
+
"div",
|
|
142
|
+
{
|
|
143
|
+
role: "group",
|
|
144
|
+
"aria-label": r("navigation.headerSettings.language.label"),
|
|
145
|
+
className: "ds:py-[var(--spacing-xs)]",
|
|
146
|
+
children: /* @__PURE__ */ a(M.SearchList, {})
|
|
147
|
+
}
|
|
148
|
+
),
|
|
149
|
+
/* @__PURE__ */ a(i.Separator, {}),
|
|
150
|
+
/* @__PURE__ */ a(i.Label, { children: r("navigation.headerSettings.appearance.label") }),
|
|
151
|
+
/* @__PURE__ */ o(
|
|
152
|
+
i.RadioGroup,
|
|
153
|
+
{
|
|
154
|
+
value: n.theme,
|
|
155
|
+
onValueChange: (e) => n.setTheme(e),
|
|
156
|
+
children: [
|
|
157
|
+
/* @__PURE__ */ o(i.RadioItem, { value: "light", children: [
|
|
158
|
+
/* @__PURE__ */ a(K, { "aria-hidden": !0, className: "ds:size-4" }),
|
|
159
|
+
r("navigation.headerSettings.appearance.light")
|
|
160
|
+
] }),
|
|
161
|
+
/* @__PURE__ */ o(i.RadioItem, { value: "dark", children: [
|
|
162
|
+
/* @__PURE__ */ a(j, { "aria-hidden": !0, className: "ds:size-4" }),
|
|
163
|
+
r("navigation.headerSettings.appearance.dark")
|
|
164
|
+
] }),
|
|
165
|
+
/* @__PURE__ */ o(i.RadioItem, { value: "system", children: [
|
|
166
|
+
/* @__PURE__ */ a(z, { "aria-hidden": !0, className: "ds:size-4" }),
|
|
167
|
+
r("navigation.headerSettings.appearance.system")
|
|
168
|
+
] })
|
|
169
|
+
]
|
|
170
|
+
}
|
|
171
|
+
),
|
|
172
|
+
/* @__PURE__ */ a(i.Separator, {}),
|
|
173
|
+
/* @__PURE__ */ a(
|
|
174
|
+
"div",
|
|
175
|
+
{
|
|
176
|
+
role: "group",
|
|
177
|
+
"aria-label": r(
|
|
178
|
+
"navigation.headerSettings.appearance.accessible"
|
|
179
|
+
),
|
|
180
|
+
className: "ds:px-[var(--spacing-sm)] ds:py-[var(--spacing-sm)]",
|
|
181
|
+
children: /* @__PURE__ */ a(
|
|
182
|
+
E,
|
|
183
|
+
{
|
|
184
|
+
label: r("navigation.headerSettings.appearance.accessible"),
|
|
185
|
+
labelSide: "start",
|
|
186
|
+
size: "sm",
|
|
187
|
+
checked: L,
|
|
188
|
+
onCheckedChange: (e) => n.setAccessibility(e ? "accessible" : "default")
|
|
189
|
+
}
|
|
190
|
+
)
|
|
191
|
+
}
|
|
192
|
+
)
|
|
193
|
+
]
|
|
194
|
+
}
|
|
195
|
+
) })
|
|
196
|
+
] })
|
|
197
|
+
}
|
|
198
|
+
);
|
|
199
|
+
}
|
|
200
|
+
);
|
|
201
|
+
F.displayName = "HeaderSettings";
|
|
202
|
+
export {
|
|
203
|
+
F as HeaderSettings
|
|
204
|
+
};
|
|
205
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../src/components/header-settings/header-settings.agent.ts","../../../src/components/header-settings/header-settings.tsx"],"sourcesContent":["/* -------------------------------------------------------------------- */\n/* Agent adapter — HeaderSettings. */\n/* -------------------------------------------------------------------- */\n\nimport type { AgentAdapter } from '../../agent/types';\nimport type { HeaderSettingsHandle } from './header-settings';\n\nexport const headerSettingsAgent: AgentAdapter<HeaderSettingsHandle> = {\n id: 'header-settings',\n capabilities: ['view_change'],\n state: {},\n actions: {\n set_locale: {\n safety: 'write',\n argsType: '{ locale: string }',\n descriptionKey: 'ui.agent.headerSettings.actions.setLocale',\n description: 'Switch the active locale to the given IETF tag.',\n invoke: (handle, args: { locale: string }) => {\n // Validation happens inside the handle so the agent surface\n // accepts arbitrary tags and silently drops unknown ones.\n handle.setLocale(args.locale);\n },\n },\n set_theme: {\n safety: 'write',\n argsType: '{ theme: \"light\" | \"dark\" | \"system\" }',\n descriptionKey: 'ui.agent.headerSettings.actions.setTheme',\n description: 'Switch the theme preference.',\n invoke: (handle, args: { theme: 'light' | 'dark' | 'system' }) => {\n handle.setTheme(args.theme);\n },\n },\n set_accessibility: {\n safety: 'write',\n argsType: '{ accessibility: \"default\" | \"accessible\" }',\n descriptionKey: 'ui.agent.headerSettings.actions.setAccessibility',\n description: 'Switch the accessibility preference.',\n invoke: (handle, args: { accessibility: 'default' | 'accessible' }) => {\n handle.setAccessibility(args.accessibility);\n },\n },\n },\n domHooks: {\n root: {\n attr: 'data-component',\n value: 'header-settings',\n description: 'Marks the HeaderSettings wrapper.',\n },\n },\n};\n","import {\n forwardRef,\n useCallback,\n useImperativeHandle,\n useMemo,\n useRef,\n type HTMLAttributes,\n} from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { Monitor, Moon, Settings, Sun } from 'lucide-react';\nimport { IconButton } from '../button/icon-button';\nimport { DropdownMenu } from '../dropdown-menu/dropdown-menu';\nimport { Switch } from '../switch/switch';\nimport {\n LocalePicker,\n LOCALE_STORAGE_KEY,\n} from '../locale-picker/locale-picker';\nimport {\n useTheme,\n type AccessibilityPreference,\n type ThemePreference,\n} from '../../hooks';\nimport { useLocale } from '../../hooks/use-locale';\nimport { LOCALE_META, type Locale } from '../../i18n/locale-meta';\nimport { useAgentRegistration } from '../../agent/registry';\nimport { headerSettingsAgent } from './header-settings.agent';\n\nfunction safeWriteStorage(key: string, value: string): void {\n if (typeof window === 'undefined') return;\n try {\n window.localStorage.setItem(key, value);\n } catch {\n /* Storage can throw in private mode — silent-fail per use-theme.ts. */\n }\n}\n\nfunction applyDocumentAttrs(locale: Locale): void {\n if (typeof document === 'undefined') return;\n const root = document.documentElement;\n root.lang = locale;\n root.dir = LOCALE_META[locale].dir;\n}\n\n/* ------------------------------------------------------------------ */\n/* CVA */\n/* ------------------------------------------------------------------ */\n\nconst wrapperVariants = cva('ds:inline-flex ds:items-center', {\n variants: {\n align: {\n start: '',\n end: '',\n },\n },\n defaultVariants: { align: 'end' },\n});\n\nconst dropdownContentClasses = [\n 'ds:w-[20rem] ds:p-[var(--spacing-xs)]',\n 'ds:rounded-[var(--radius-md)] ds:border ds:border-border',\n 'ds:bg-background ds:text-foreground ds:shadow-[var(--shadow-lg)]',\n].join(' ');\n\n/* ------------------------------------------------------------------ */\n/* Public types */\n/* ------------------------------------------------------------------ */\n\nexport interface HeaderSettingsProps\n extends\n Omit<HTMLAttributes<HTMLDivElement>, 'onChange'>,\n VariantProps<typeof wrapperVariants> {\n /** Anchor side for the dropdown. Defaults to `end` (matches LTR + RTL). */\n align?: 'start' | 'end';\n /** Disable the trigger entirely. */\n disabled?: boolean;\n}\n\nexport interface HeaderSettingsHandle {\n /**\n * Switch the active locale. Widened to `string` (vs. `Locale`) so\n * agent surfaces with untyped inputs can call through without\n * extra casting — invalid tags no-op silently.\n */\n setLocale: (next: string) => void;\n setTheme: (next: ThemePreference) => void;\n setAccessibility: (next: AccessibilityPreference) => void;\n}\n\n/* ------------------------------------------------------------------ */\n/* HeaderSettings */\n/* */\n/* Single button → single DropdownMenu surface. Inside the menu, the */\n/* \"Language\" section embeds `LocalePicker.SearchList` (the kit's */\n/* searchable list without its own trigger / popover) and the */\n/* \"Appearance\" section mirrors `ThemeToggle`'s menu-variant internals */\n/* using `DropdownMenu.RadioGroup` + `CheckboxItem`. Both sections */\n/* read/write the same hooks (`useLocale`, `useTheme`) that the */\n/* standalone components use, so there's no state duplication. */\n/* ------------------------------------------------------------------ */\n\nexport const HeaderSettings = forwardRef<HTMLDivElement, HeaderSettingsProps>(\n (props, ref) => {\n const {\n align = 'end',\n disabled = false,\n className,\n id,\n ...rest\n } = props as HeaderSettingsProps & { id?: string };\n\n const { t } = useTranslation();\n const theme = useTheme();\n const { setLocale: setLocaleI18n } = useLocale();\n\n const forwardedRef = useRef<HTMLDivElement | null>(null);\n useImperativeHandle(ref, () => forwardedRef.current as HTMLDivElement, []);\n\n // Same side-effect chain as LocalePicker's internal helper:\n // i18next.changeLanguage → document.dir/lang → persist.\n // Inlined here (rather than exported from locale-picker) because\n // it's three small calls; the LocalePicker.SearchList component\n // continues to own its own copy for inline use, and both apply\n // the same persistence key (`alfadocs-ui.locale`) so a write from\n // either path is visible to the other on next mount.\n const setLocaleWithPersistence = useCallback(\n (next: Locale) => {\n void setLocaleI18n(next);\n applyDocumentAttrs(next);\n safeWriteStorage(LOCALE_STORAGE_KEY, next);\n },\n [setLocaleI18n],\n );\n const setLocaleRef = useRef(setLocaleWithPersistence);\n setLocaleRef.current = setLocaleWithPersistence;\n\n const themeRef = useRef(theme);\n themeRef.current = theme;\n const agentHandle = useMemo<HeaderSettingsHandle>(\n () => ({\n setLocale: (next: string) => {\n // Mirrors LocalePicker's gating — silently drop unknown tags\n // rather than crash mid-cascade. `LOCALES_WITH_BUNDLES` is\n // re-imported via the LOCALE_META keys so this file doesn't\n // need the resources module on the build-agent-catalog path.\n if (Object.prototype.hasOwnProperty.call(LOCALE_META, next)) {\n setLocaleRef.current(next as Locale);\n }\n },\n setTheme: (next) => themeRef.current.setTheme(next),\n setAccessibility: (next) => themeRef.current.setAccessibility(next),\n }),\n [],\n );\n useAgentRegistration(headerSettingsAgent, agentHandle, id);\n\n const accessibleChecked = theme.accessibility === 'accessible';\n\n return (\n <div\n ref={forwardedRef}\n data-component=\"header-settings\"\n data-component-id={id}\n className={wrapperVariants({ align, className })}\n {...rest}\n >\n <DropdownMenu.Root>\n <DropdownMenu.Trigger asChild>\n <IconButton\n disabled={disabled}\n icon={<Settings aria-hidden />}\n aria-label={t('navigation.headerSettings.trigger')}\n />\n </DropdownMenu.Trigger>\n <DropdownMenu.Portal>\n <DropdownMenu.Content\n align={align}\n sideOffset={8}\n className={dropdownContentClasses}\n // Search input inside the menu owns its own keyboard\n // capture (cmdk). Stop Radix Menu's typeahead from\n // intercepting letters typed into the search field —\n // `onKeyDownCapture` runs before the menu's listener.\n onKeyDownCapture={(event) => {\n const target = event.target as HTMLElement | null;\n if (\n target?.tagName === 'INPUT' &&\n // Always allow Escape so the menu can close.\n event.key !== 'Escape'\n ) {\n event.stopPropagation();\n }\n }}\n >\n <DropdownMenu.Label>\n {t('navigation.headerSettings.language.label')}\n </DropdownMenu.Label>\n {/* The searchable list owns its own keyboard nav (cmdk).\n Wrap in `role=\"group\"` (vs. `role=\"presentation\"`)\n so the menu's `aria-required-children` rule sees a\n permitted child role, not the cmdk input/listbox\n leaking up as direct children of `role=\"menu\"`. */}\n <div\n role=\"group\"\n aria-label={t('navigation.headerSettings.language.label')}\n className=\"ds:py-[var(--spacing-xs)]\"\n >\n <LocalePicker.SearchList />\n </div>\n\n <DropdownMenu.Separator />\n\n <DropdownMenu.Label>\n {t('navigation.headerSettings.appearance.label')}\n </DropdownMenu.Label>\n <DropdownMenu.RadioGroup\n value={theme.theme}\n onValueChange={(next) =>\n theme.setTheme(next as ThemePreference)\n }\n >\n <DropdownMenu.RadioItem value=\"light\">\n <Sun aria-hidden className=\"ds:size-4\" />\n {t('navigation.headerSettings.appearance.light')}\n </DropdownMenu.RadioItem>\n <DropdownMenu.RadioItem value=\"dark\">\n <Moon aria-hidden className=\"ds:size-4\" />\n {t('navigation.headerSettings.appearance.dark')}\n </DropdownMenu.RadioItem>\n <DropdownMenu.RadioItem value=\"system\">\n <Monitor aria-hidden className=\"ds:size-4\" />\n {t('navigation.headerSettings.appearance.system')}\n </DropdownMenu.RadioItem>\n </DropdownMenu.RadioGroup>\n\n <DropdownMenu.Separator />\n\n {/* Accessible-mode toggle uses the kit's Switch primitive\n for a clearer visual affordance than a checkbox tick.\n Rendered inside a `presentation` row (not a\n DropdownMenu.CheckboxItem) — the Switch is focusable\n via Tab while the menu is open, so keyboard users\n still reach it; arrow keys keep moving between the\n three theme radios above without falling into the\n switch's roving collection.\n\n When the switch flips, `setAccessibility` writes\n through useTheme (the same store the standalone\n ThemeToggle uses) so document.documentElement gets\n the `theme-accessible` class instantly — including\n swapping `--font-sans` to Lexend for Latin scripts\n (see src/tokens/index.css). */}\n {/* `role=\"group\"` so the menu's `aria-required-children`\n (which only permits menuitem* / group / separator /\n menu inside `role=\"menu\"`) is satisfied — the Switch's\n `role=\"switch\"` would be a forbidden direct child of\n the menu. `aria-label` names the group so SR users\n hear \"Accessibility toggle, group\". */}\n <div\n role=\"group\"\n aria-label={t(\n 'navigation.headerSettings.appearance.accessible',\n )}\n className=\"ds:px-[var(--spacing-sm)] ds:py-[var(--spacing-sm)]\"\n >\n <Switch\n label={t('navigation.headerSettings.appearance.accessible')}\n labelSide=\"start\"\n size=\"sm\"\n checked={accessibleChecked}\n onCheckedChange={(next) =>\n theme.setAccessibility(next ? 'accessible' : 'default')\n }\n />\n </div>\n </DropdownMenu.Content>\n </DropdownMenu.Portal>\n </DropdownMenu.Root>\n </div>\n );\n },\n);\n\nHeaderSettings.displayName = 'HeaderSettings';\n"],"names":["headerSettingsAgent","handle","args","safeWriteStorage","key","value","applyDocumentAttrs","locale","root","LOCALE_META","wrapperVariants","cva","dropdownContentClasses","HeaderSettings","forwardRef","props","ref","align","disabled","className","id","rest","t","useTranslation","theme","useTheme","setLocaleI18n","useLocale","forwardedRef","useRef","useImperativeHandle","setLocaleWithPersistence","useCallback","next","LOCALE_STORAGE_KEY","setLocaleRef","themeRef","agentHandle","useMemo","useAgentRegistration","accessibleChecked","jsx","jsxs","DropdownMenu","IconButton","Settings","event","target","LocalePicker","Sun","Moon","Monitor","Switch"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
|
|
@@ -22,10 +22,23 @@ export interface WhatsAppButtonProps extends Omit<AnchorHTMLAttributes<HTMLAncho
|
|
|
22
22
|
message?: string;
|
|
23
23
|
/**
|
|
24
24
|
* Override the visible / accessible label. Defaults to
|
|
25
|
-
* `t('whatsApp.label')`
|
|
25
|
+
* `t('whatsApp.label')` (or `t('whatsApp.questionPrompt')` when
|
|
26
|
+
* `tone="question"`) for the pill variant, and
|
|
26
27
|
* `t('whatsApp.fabLabel')` for the FAB.
|
|
27
28
|
*/
|
|
28
29
|
label?: ReactNode;
|
|
30
|
+
/**
|
|
31
|
+
* Copy tone for the pill variant.
|
|
32
|
+
* - `standard` (default) — brief "Chat on WhatsApp" affordance.
|
|
33
|
+
* - `question` — invitational "Have questions? Chat on WhatsApp"
|
|
34
|
+
* copy. Routes through `t('whatsApp.questionPrompt')`. Use on
|
|
35
|
+
* public-facing surfaces (booking pages, marketing) where the
|
|
36
|
+
* button is the only prompt encouraging engagement.
|
|
37
|
+
*
|
|
38
|
+
* Ignored for `variant="fab"` — the floating action button is
|
|
39
|
+
* glyph-only and its `aria-label` stays concise via `fabLabel`.
|
|
40
|
+
*/
|
|
41
|
+
tone?: 'standard' | 'question';
|
|
29
42
|
}
|
|
30
43
|
export declare const WhatsAppButton: import("react").ForwardRefExoticComponent<WhatsAppButtonProps & import("react").RefAttributes<HTMLAnchorElement>>;
|
|
31
44
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"whatsapp-button.d.ts","sourceRoot":"","sources":["../../../src/components/whatsapp-button/whatsapp-button.tsx"],"names":[],"mappings":"AAqBA,OAAO,EAGL,KAAK,oBAAoB,EACzB,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AACf,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AA8BlE,QAAA,MAAM,YAAY;;;8EA4FjB,CAAC;AAEF,QAAA,MAAM,gBAAgB;;8EAgBpB,CAAC;AAyCH,MAAM,WAAW,mBACf,SACE,IAAI,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,EAAE,MAAM,GAAG,UAAU,CAAC,EAClE,YAAY,CAAC,OAAO,YAAY,CAAC,EACjC,YAAY,CAAC,OAAO,gBAAgB,CAAC;IACvC;;;;OAIG;IACH,WAAW,EAAE,MAAM,CAAC;IACpB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB
|
|
1
|
+
{"version":3,"file":"whatsapp-button.d.ts","sourceRoot":"","sources":["../../../src/components/whatsapp-button/whatsapp-button.tsx"],"names":[],"mappings":"AAqBA,OAAO,EAGL,KAAK,oBAAoB,EACzB,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AACf,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AA8BlE,QAAA,MAAM,YAAY;;;8EA4FjB,CAAC;AAEF,QAAA,MAAM,gBAAgB;;8EAgBpB,CAAC;AAyCH,MAAM,WAAW,mBACf,SACE,IAAI,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,EAAE,MAAM,GAAG,UAAU,CAAC,EAClE,YAAY,CAAC,OAAO,YAAY,CAAC,EACjC,YAAY,CAAC,OAAO,gBAAgB,CAAC;IACvC;;;;OAIG;IACH,WAAW,EAAE,MAAM,CAAC;IACpB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;OAKG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB;;;;;;;;;;OAUG;IACH,IAAI,CAAC,EAAE,UAAU,GAAG,UAAU,CAAC;CAChC;AAMD,eAAO,MAAM,cAAc,mHA+G1B,CAAC"}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/dist/hooks/index.js
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import { u as D } from "../_chunks/use-prefers-reduced-motion-BMwIQRjB.js";
|
|
2
|
-
import { u as w, a as _
|
|
3
|
-
import { u as
|
|
4
|
-
import {
|
|
5
|
-
import { u as
|
|
6
|
-
import { u as
|
|
7
|
-
import { u as
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import { u as
|
|
2
|
+
import { u as w, a as _ } from "../_chunks/use-scroll-to-first-error-BrK7dKB_.js";
|
|
3
|
+
import { u as I } from "../_chunks/use-count-up-BLLetaZ8.js";
|
|
4
|
+
import { u as K } from "../_chunks/use-locale-BkCIHujH.js";
|
|
5
|
+
import { A as O, T as H, a as R, r as Y, t as q, u as B } from "../_chunks/use-theme-B1cwAXJR.js";
|
|
6
|
+
import { u as P } from "../_chunks/use-controllable-state-BiY4xTzM.js";
|
|
7
|
+
import { u as V } from "../_chunks/use-copy-to-clipboard-Cyfc_dlv.js";
|
|
8
|
+
import { u as Q } from "../_chunks/use-debounced-callback-BisrB-Fq.js";
|
|
9
|
+
import { useState as b, useEffect as l, useRef as T, useLayoutEffect as x } from "react";
|
|
10
|
+
import { u as J, a as N } from "../_chunks/use-direction-D6rvvG9G.js";
|
|
11
|
+
import { u as X } from "../_chunks/use-persistent-state-i23OWy6G.js";
|
|
11
12
|
function S(e, t) {
|
|
12
|
-
const [o, s] =
|
|
13
|
+
const [o, s] = b(e);
|
|
13
14
|
return l(() => {
|
|
14
15
|
if (t <= 0) {
|
|
15
16
|
s(e);
|
|
@@ -62,8 +63,8 @@ function C(e, t = {}) {
|
|
|
62
63
|
r.preventDefault();
|
|
63
64
|
return;
|
|
64
65
|
}
|
|
65
|
-
const m = c[0],
|
|
66
|
-
r.shiftKey ? (i === m || !n.contains(i)) && (r.preventDefault(),
|
|
66
|
+
const m = c[0], p = c[c.length - 1], i = document.activeElement;
|
|
67
|
+
r.shiftKey ? (i === m || !n.contains(i)) && (r.preventDefault(), p.focus()) : (i === p || !n.contains(i)) && (r.preventDefault(), m.focus());
|
|
67
68
|
}
|
|
68
69
|
return u.addEventListener("keydown", d), () => {
|
|
69
70
|
if (u.removeEventListener("keydown", d), a && f.current) {
|
|
@@ -77,25 +78,25 @@ function C(e, t = {}) {
|
|
|
77
78
|
}
|
|
78
79
|
const L = typeof window < "u" ? x : l;
|
|
79
80
|
export {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
81
|
+
O as ACCESSIBILITY_STORAGE_KEY,
|
|
82
|
+
H as THEME_CLASS,
|
|
83
|
+
R as THEME_STORAGE_KEY,
|
|
84
|
+
Y as resolveTheme,
|
|
85
|
+
q as themeClassList,
|
|
86
|
+
P as useControllableState,
|
|
87
|
+
V as useCopyToClipboard,
|
|
88
|
+
I as useCountUp,
|
|
89
|
+
Q as useDebouncedCallback,
|
|
89
90
|
S as useDebouncedValue,
|
|
90
|
-
|
|
91
|
-
|
|
91
|
+
J as useDirection,
|
|
92
|
+
N as useDocumentDirection,
|
|
92
93
|
C as useFocusTrap,
|
|
93
94
|
L as useIsomorphicLayoutEffect,
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
95
|
+
K as useLocale,
|
|
96
|
+
w as useMediaQuery,
|
|
97
|
+
X as usePersistentState,
|
|
97
98
|
D as usePrefersReducedMotion,
|
|
98
|
-
|
|
99
|
-
|
|
99
|
+
_ as useScrollToFirstError,
|
|
100
|
+
B as useTheme
|
|
100
101
|
};
|
|
101
102
|
//# sourceMappingURL=index.js.map
|
package/dist/hooks/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../src/hooks/use-debounced-value.ts","../../src/hooks/use-focus-trap.ts","../../src/hooks/use-isomorphic-layout-effect.ts"],"sourcesContent":["import { useEffect, useState } from 'react';\n\n/**\n * Returns a value that lags `input` by `delayMs`. Each new `input`\n * resets the timer; the returned value updates once `input` has been\n * stable for `delayMs` ms.\n *\n * Companion to `useDebouncedCallback` — use this when you want the\n * debounced *value* (to drive a derived effect, query, or render),\n * and use the callback hook when you want the debounced *action*.\n *\n * @example\n * const [query, setQuery] = useState('');\n * const debouncedQuery = useDebouncedValue(query, 250);\n * useEffect(() => { void search(debouncedQuery); }, [debouncedQuery]);\n */\nexport function useDebouncedValue<T>(input: T, delayMs: number): T {\n const [value, setValue] = useState<T>(input);\n\n useEffect(() => {\n if (delayMs <= 0) {\n setValue(input);\n return;\n }\n const timer = setTimeout(() => setValue(input), delayMs);\n return () => clearTimeout(timer);\n }, [input, delayMs]);\n\n return value;\n}\n","import { useEffect, useRef, type RefObject } from 'react';\n\n/* -------------------------------------------------------------------- */\n/* Focus trap */\n/* */\n/* Lightweight focus-trap hook for components that compose a Radix */\n/* primitive without the overlay primitive (Dialog, AlertDialog, Sheet) */\n/* — those handle focus trapping for free via `@radix-ui/react-dialog`. */\n/* */\n/* This hook is intentionally NOT a Radix `<FocusScope>` re-export — it */\n/* is a hook so it composes inside `forwardRef` components without */\n/* nesting another wrapper element. If you need the full Radix */\n/* contract (return-focus management, loop, asChild), use */\n/* `@radix-ui/react-focus-scope` directly. */\n/* -------------------------------------------------------------------- */\n\nexport interface UseFocusTrapOptions {\n /** When `false` the trap is inert. Defaults to `true`. */\n enabled?: boolean;\n /**\n * When `true`, focus initial autofocus into the first focusable\n * descendant on mount / enable. @default true\n */\n autoFocus?: boolean;\n /**\n * When `true`, restores focus to the previously-focused element on\n * unmount / disable. @default true\n */\n restoreFocus?: boolean;\n}\n\nconst FOCUSABLE_SELECTOR = [\n 'a[href]',\n 'button:not([disabled])',\n 'input:not([disabled]):not([type=\"hidden\"])',\n 'select:not([disabled])',\n 'textarea:not([disabled])',\n '[tabindex]:not([tabindex=\"-1\"])',\n '[contenteditable=\"true\"]',\n 'audio[controls]',\n 'video[controls]',\n].join(',');\n\nfunction getFocusable(container: HTMLElement): HTMLElement[] {\n return Array.from(\n container.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTOR),\n ).filter((el) => {\n if (el.hidden) return false;\n if (el.getAttribute('aria-hidden') === 'true') return false;\n // `inert` ancestors block focus — checked via a quick walk.\n let node: HTMLElement | null = el;\n while (node) {\n if (node.hasAttribute('inert')) return false;\n node = node.parentElement;\n }\n return true;\n });\n}\n\n/**\n * Constrain Tab navigation to descendants of `containerRef`. Wraps Tab\n * forward from the last focusable to the first, and Shift+Tab back from\n * the first to the last. Optionally autofocuses on enable and restores\n * focus on disable.\n *\n * Use this for inline modal patterns or focus zones that don't ship\n * with their own Radix overlay. Don't stack it inside Dialog / Sheet —\n * Radix already traps focus in those.\n *\n * @example\n * const ref = useRef<HTMLDivElement>(null);\n * useFocusTrap(ref, { enabled: open });\n * return <div ref={ref}>…</div>;\n */\nexport function useFocusTrap<T extends HTMLElement>(\n containerRef: RefObject<T | null>,\n options: UseFocusTrapOptions = {},\n): void {\n const { enabled = true, autoFocus = true, restoreFocus = true } = options;\n const previouslyFocused = useRef<HTMLElement | null>(null);\n\n useEffect(() => {\n if (!enabled) return;\n const container = containerRef.current;\n if (!container) return;\n\n previouslyFocused.current =\n typeof document !== 'undefined' &&\n document.activeElement instanceof HTMLElement\n ? document.activeElement\n : null;\n\n if (autoFocus) {\n const focusable = getFocusable(container);\n // Container itself is the fallback focus target — needs `tabIndex`\n // to receive focus, but `-1` is fine.\n const target =\n focusable[0] ?? (container.tabIndex >= -1 ? container : null);\n target?.focus();\n }\n\n function onKeyDown(event: KeyboardEvent) {\n if (event.key !== 'Tab') return;\n const root = containerRef.current;\n if (!root) return;\n const focusable = getFocusable(root);\n if (focusable.length === 0) {\n event.preventDefault();\n return;\n }\n const first = focusable[0];\n const last = focusable[focusable.length - 1];\n const active = document.activeElement;\n\n if (event.shiftKey) {\n if (active === first || !root.contains(active)) {\n event.preventDefault();\n last.focus();\n }\n } else {\n if (active === last || !root.contains(active)) {\n event.preventDefault();\n first.focus();\n }\n }\n }\n\n container.addEventListener('keydown', onKeyDown);\n\n return () => {\n container.removeEventListener('keydown', onKeyDown);\n if (restoreFocus && previouslyFocused.current) {\n // Defer so a parent unmount that takes the previous element with\n // it doesn't cause a focus-on-detached-node throw.\n const target = previouslyFocused.current;\n queueMicrotask(() => {\n if (target.isConnected) target.focus();\n });\n }\n };\n }, [enabled, autoFocus, restoreFocus, containerRef]);\n}\n","import { useEffect, useLayoutEffect } from 'react';\n\n/**\n * `useLayoutEffect` on the client, `useEffect` during SSR. Use when you\n * need a layout effect (e.g. measuring DOM, syncing a ref) without\n * triggering React's \"useLayoutEffect does nothing on the server\"\n * warning when the same component renders under SSR.\n *\n * The check is `typeof window` rather than `typeof document` so the\n * shim is correct in any non-browser runtime (Node, Deno, edge\n * runtimes, workers).\n */\nexport const useIsomorphicLayoutEffect =\n typeof window !== 'undefined' ? useLayoutEffect : useEffect;\n"],"names":["useDebouncedValue","input","delayMs","value","setValue","useState","useEffect","timer","FOCUSABLE_SELECTOR","getFocusable","container","el","node","useFocusTrap","containerRef","options","enabled","autoFocus","restoreFocus","previouslyFocused","useRef","target","onKeyDown","event","root","focusable","first","last","active","useIsomorphicLayoutEffect","useLayoutEffect"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../src/hooks/use-debounced-value.ts","../../src/hooks/use-focus-trap.ts","../../src/hooks/use-isomorphic-layout-effect.ts"],"sourcesContent":["import { useEffect, useState } from 'react';\n\n/**\n * Returns a value that lags `input` by `delayMs`. Each new `input`\n * resets the timer; the returned value updates once `input` has been\n * stable for `delayMs` ms.\n *\n * Companion to `useDebouncedCallback` — use this when you want the\n * debounced *value* (to drive a derived effect, query, or render),\n * and use the callback hook when you want the debounced *action*.\n *\n * @example\n * const [query, setQuery] = useState('');\n * const debouncedQuery = useDebouncedValue(query, 250);\n * useEffect(() => { void search(debouncedQuery); }, [debouncedQuery]);\n */\nexport function useDebouncedValue<T>(input: T, delayMs: number): T {\n const [value, setValue] = useState<T>(input);\n\n useEffect(() => {\n if (delayMs <= 0) {\n setValue(input);\n return;\n }\n const timer = setTimeout(() => setValue(input), delayMs);\n return () => clearTimeout(timer);\n }, [input, delayMs]);\n\n return value;\n}\n","import { useEffect, useRef, type RefObject } from 'react';\n\n/* -------------------------------------------------------------------- */\n/* Focus trap */\n/* */\n/* Lightweight focus-trap hook for components that compose a Radix */\n/* primitive without the overlay primitive (Dialog, AlertDialog, Sheet) */\n/* — those handle focus trapping for free via `@radix-ui/react-dialog`. */\n/* */\n/* This hook is intentionally NOT a Radix `<FocusScope>` re-export — it */\n/* is a hook so it composes inside `forwardRef` components without */\n/* nesting another wrapper element. If you need the full Radix */\n/* contract (return-focus management, loop, asChild), use */\n/* `@radix-ui/react-focus-scope` directly. */\n/* -------------------------------------------------------------------- */\n\nexport interface UseFocusTrapOptions {\n /** When `false` the trap is inert. Defaults to `true`. */\n enabled?: boolean;\n /**\n * When `true`, focus initial autofocus into the first focusable\n * descendant on mount / enable. @default true\n */\n autoFocus?: boolean;\n /**\n * When `true`, restores focus to the previously-focused element on\n * unmount / disable. @default true\n */\n restoreFocus?: boolean;\n}\n\nconst FOCUSABLE_SELECTOR = [\n 'a[href]',\n 'button:not([disabled])',\n 'input:not([disabled]):not([type=\"hidden\"])',\n 'select:not([disabled])',\n 'textarea:not([disabled])',\n '[tabindex]:not([tabindex=\"-1\"])',\n '[contenteditable=\"true\"]',\n 'audio[controls]',\n 'video[controls]',\n].join(',');\n\nfunction getFocusable(container: HTMLElement): HTMLElement[] {\n return Array.from(\n container.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTOR),\n ).filter((el) => {\n if (el.hidden) return false;\n if (el.getAttribute('aria-hidden') === 'true') return false;\n // `inert` ancestors block focus — checked via a quick walk.\n let node: HTMLElement | null = el;\n while (node) {\n if (node.hasAttribute('inert')) return false;\n node = node.parentElement;\n }\n return true;\n });\n}\n\n/**\n * Constrain Tab navigation to descendants of `containerRef`. Wraps Tab\n * forward from the last focusable to the first, and Shift+Tab back from\n * the first to the last. Optionally autofocuses on enable and restores\n * focus on disable.\n *\n * Use this for inline modal patterns or focus zones that don't ship\n * with their own Radix overlay. Don't stack it inside Dialog / Sheet —\n * Radix already traps focus in those.\n *\n * @example\n * const ref = useRef<HTMLDivElement>(null);\n * useFocusTrap(ref, { enabled: open });\n * return <div ref={ref}>…</div>;\n */\nexport function useFocusTrap<T extends HTMLElement>(\n containerRef: RefObject<T | null>,\n options: UseFocusTrapOptions = {},\n): void {\n const { enabled = true, autoFocus = true, restoreFocus = true } = options;\n const previouslyFocused = useRef<HTMLElement | null>(null);\n\n useEffect(() => {\n if (!enabled) return;\n const container = containerRef.current;\n if (!container) return;\n\n previouslyFocused.current =\n typeof document !== 'undefined' &&\n document.activeElement instanceof HTMLElement\n ? document.activeElement\n : null;\n\n if (autoFocus) {\n const focusable = getFocusable(container);\n // Container itself is the fallback focus target — needs `tabIndex`\n // to receive focus, but `-1` is fine.\n const target =\n focusable[0] ?? (container.tabIndex >= -1 ? container : null);\n target?.focus();\n }\n\n function onKeyDown(event: KeyboardEvent) {\n if (event.key !== 'Tab') return;\n const root = containerRef.current;\n if (!root) return;\n const focusable = getFocusable(root);\n if (focusable.length === 0) {\n event.preventDefault();\n return;\n }\n const first = focusable[0];\n const last = focusable[focusable.length - 1];\n const active = document.activeElement;\n\n if (event.shiftKey) {\n if (active === first || !root.contains(active)) {\n event.preventDefault();\n last.focus();\n }\n } else {\n if (active === last || !root.contains(active)) {\n event.preventDefault();\n first.focus();\n }\n }\n }\n\n container.addEventListener('keydown', onKeyDown);\n\n return () => {\n container.removeEventListener('keydown', onKeyDown);\n if (restoreFocus && previouslyFocused.current) {\n // Defer so a parent unmount that takes the previous element with\n // it doesn't cause a focus-on-detached-node throw.\n const target = previouslyFocused.current;\n queueMicrotask(() => {\n if (target.isConnected) target.focus();\n });\n }\n };\n }, [enabled, autoFocus, restoreFocus, containerRef]);\n}\n","import { useEffect, useLayoutEffect } from 'react';\n\n/**\n * `useLayoutEffect` on the client, `useEffect` during SSR. Use when you\n * need a layout effect (e.g. measuring DOM, syncing a ref) without\n * triggering React's \"useLayoutEffect does nothing on the server\"\n * warning when the same component renders under SSR.\n *\n * The check is `typeof window` rather than `typeof document` so the\n * shim is correct in any non-browser runtime (Node, Deno, edge\n * runtimes, workers).\n */\nexport const useIsomorphicLayoutEffect =\n typeof window !== 'undefined' ? useLayoutEffect : useEffect;\n"],"names":["useDebouncedValue","input","delayMs","value","setValue","useState","useEffect","timer","FOCUSABLE_SELECTOR","getFocusable","container","el","node","useFocusTrap","containerRef","options","enabled","autoFocus","restoreFocus","previouslyFocused","useRef","target","onKeyDown","event","root","focusable","first","last","active","useIsomorphicLayoutEffect","useLayoutEffect"],"mappings":";;;;;;;;;;;AAgBO,SAASA,EAAqBC,GAAUC,GAAoB;AACjE,QAAM,CAACC,GAAOC,CAAQ,IAAIC,EAAYJ,CAAK;AAE3C,SAAAK,EAAU,MAAM;AACd,QAAIJ,KAAW,GAAG;AAChB,MAAAE,EAASH,CAAK;AACd;AAAA,IACF;AACA,UAAMM,IAAQ,WAAW,MAAMH,EAASH,CAAK,GAAGC,CAAO;AACvD,WAAO,MAAM,aAAaK,CAAK;AAAA,EACjC,GAAG,CAACN,GAAOC,CAAO,CAAC,GAEZC;AACT;ACEA,MAAMK,IAAqB;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,EAAE,KAAK,GAAG;AAEV,SAASC,EAAaC,GAAuC;AAC3D,SAAO,MAAM;AAAA,IACXA,EAAU,iBAA8BF,CAAkB;AAAA,EAAA,EAC1D,OAAO,CAACG,MAAO;AAEf,QADIA,EAAG,UACHA,EAAG,aAAa,aAAa,MAAM,OAAQ,QAAO;AAEtD,QAAIC,IAA2BD;AAC/B,WAAOC,KAAM;AACX,UAAIA,EAAK,aAAa,OAAO,EAAG,QAAO;AACvC,MAAAA,IAAOA,EAAK;AAAA,IACd;AACA,WAAO;AAAA,EACT,CAAC;AACH;AAiBO,SAASC,EACdC,GACAC,IAA+B,IACzB;AACN,QAAM,EAAE,SAAAC,IAAU,IAAM,WAAAC,IAAY,IAAM,cAAAC,IAAe,OAASH,GAC5DI,IAAoBC,EAA2B,IAAI;AAEzD,EAAAd,EAAU,MAAM;AACd,QAAI,CAACU,EAAS;AACd,UAAMN,IAAYI,EAAa;AAC/B,QAAI,CAACJ,EAAW;AAQhB,QANAS,EAAkB,UAChB,OAAO,WAAa,OACpB,SAAS,yBAAyB,cAC9B,SAAS,gBACT,MAEFF,GAAW;AAIb,YAAMI,IAHYZ,EAAaC,CAAS,EAI5B,CAAC,MAAMA,EAAU,YAAY,KAAKA,IAAY;AAC1D,MAAAW,KAAA,QAAAA,EAAQ;AAAA,IACV;AAEA,aAASC,EAAUC,GAAsB;AACvC,UAAIA,EAAM,QAAQ,MAAO;AACzB,YAAMC,IAAOV,EAAa;AAC1B,UAAI,CAACU,EAAM;AACX,YAAMC,IAAYhB,EAAae,CAAI;AACnC,UAAIC,EAAU,WAAW,GAAG;AAC1B,QAAAF,EAAM,eAAA;AACN;AAAA,MACF;AACA,YAAMG,IAAQD,EAAU,CAAC,GACnBE,IAAOF,EAAUA,EAAU,SAAS,CAAC,GACrCG,IAAS,SAAS;AAExB,MAAIL,EAAM,YACJK,MAAWF,KAAS,CAACF,EAAK,SAASI,CAAM,OAC3CL,EAAM,eAAA,GACNI,EAAK,MAAA,MAGHC,MAAWD,KAAQ,CAACH,EAAK,SAASI,CAAM,OAC1CL,EAAM,eAAA,GACNG,EAAM,MAAA;AAAA,IAGZ;AAEA,WAAAhB,EAAU,iBAAiB,WAAWY,CAAS,GAExC,MAAM;AAEX,UADAZ,EAAU,oBAAoB,WAAWY,CAAS,GAC9CJ,KAAgBC,EAAkB,SAAS;AAG7C,cAAME,IAASF,EAAkB;AACjC,uBAAe,MAAM;AACnB,UAAIE,EAAO,eAAaA,EAAO,MAAA;AAAA,QACjC,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF,GAAG,CAACL,GAASC,GAAWC,GAAcJ,CAAY,CAAC;AACrD;ACjIO,MAAMe,IACX,OAAO,SAAW,MAAcC,IAAkBxB;"}
|