@nori-ui/core 1.8.0 → 1.9.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 (39) hide show
  1. package/dist/{chunk-PLQPBMG2.js → chunk-BXZGCOKT.js} +2 -2
  2. package/dist/{chunk-PLQPBMG2.js.map → chunk-BXZGCOKT.js.map} +1 -1
  3. package/dist/{chunk-RI4Y2C5U.js → chunk-KLK7OMFT.js} +3 -3
  4. package/dist/{chunk-RI4Y2C5U.js.map → chunk-KLK7OMFT.js.map} +1 -1
  5. package/dist/chunk-OHWRTHGL.js +495 -0
  6. package/dist/chunk-OHWRTHGL.js.map +1 -0
  7. package/dist/{chunk-V5QSMDZL.js → chunk-QB6RH6UU.js} +3 -3
  8. package/dist/{chunk-V5QSMDZL.js.map → chunk-QB6RH6UU.js.map} +1 -1
  9. package/dist/chunk-S763GTIZ.js +350 -0
  10. package/dist/chunk-S763GTIZ.js.map +1 -0
  11. package/dist/chunk-UJRVWGK7.js +3 -0
  12. package/dist/chunk-UJRVWGK7.js.map +1 -0
  13. package/dist/client.cjs +2248 -1424
  14. package/dist/client.cjs.map +1 -1
  15. package/dist/client.d.cts +2 -0
  16. package/dist/client.d.ts +2 -0
  17. package/dist/client.js +13 -10
  18. package/dist/client.js.map +1 -1
  19. package/dist/components/Accordion/index.js +2 -2
  20. package/dist/components/Command/index.cjs +1371 -0
  21. package/dist/components/Command/index.cjs.map +1 -0
  22. package/dist/components/Command/index.d.cts +89 -0
  23. package/dist/components/Command/index.d.ts +89 -0
  24. package/dist/components/Command/index.js +11 -0
  25. package/dist/components/Command/index.js.map +1 -0
  26. package/dist/components/Dialog/index.js +2 -1
  27. package/dist/components/Sidebar/index.cjs +675 -0
  28. package/dist/components/Sidebar/index.cjs.map +1 -0
  29. package/dist/components/Sidebar/index.d.cts +109 -0
  30. package/dist/components/Sidebar/index.d.ts +109 -0
  31. package/dist/components/Sidebar/index.js +7 -0
  32. package/dist/components/Sidebar/index.js.map +1 -0
  33. package/dist/components/Switch/index.js +2 -2
  34. package/dist/index.cjs +2248 -1424
  35. package/dist/index.cjs.map +1 -1
  36. package/dist/index.d.cts +2 -0
  37. package/dist/index.d.ts +2 -0
  38. package/dist/index.js +13 -10
  39. package/package.json +1 -1
@@ -0,0 +1,495 @@
1
+ import { Dialog } from './chunk-BXZGCOKT.js';
2
+ import { px } from './chunk-5A2QOOVN.js';
3
+ import { useThemeColors } from './chunk-R5JMDDCB.js';
4
+ import { cn } from './chunk-CHXHRJNZ.js';
5
+ import { __name } from './chunk-WCQVDF3K.js';
6
+ import { createContext, useContext, isValidElement, Children, useState, useCallback, useEffect, useId, cloneElement, useRef } from 'react';
7
+ import { Platform, Text, Pressable, View, TextInput, ScrollView } from 'react-native';
8
+ import { jsx, jsxs } from 'nativewind/jsx-runtime';
9
+
10
+ var CommandContext = createContext(null);
11
+ function useCommandContext(caller) {
12
+ const ctx = useContext(CommandContext);
13
+ if (!ctx) {
14
+ throw new Error(`<${caller}> must be rendered inside <Command>.`);
15
+ }
16
+ return ctx;
17
+ }
18
+ __name(useCommandContext, "useCommandContext");
19
+ var CommandRoot = /* @__PURE__ */ __name(({ open, defaultOpen = false, onOpenChange, children }) => {
20
+ const [inner, setInner] = useState(defaultOpen);
21
+ const isControlled = open !== void 0;
22
+ const current = isControlled ? open : inner;
23
+ const [query, setQuery] = useState("");
24
+ const setOpen = useCallback(
25
+ (next) => {
26
+ if (!isControlled) {
27
+ setInner(next);
28
+ }
29
+ if (!next) {
30
+ setQuery("");
31
+ }
32
+ onOpenChange?.(next);
33
+ },
34
+ [isControlled, onOpenChange]
35
+ );
36
+ useEffect(() => {
37
+ if (Platform.OS !== "web") {
38
+ return;
39
+ }
40
+ const handler = /* @__PURE__ */ __name((e) => {
41
+ if ((e.metaKey || e.ctrlKey) && e.key === "k") {
42
+ e.preventDefault();
43
+ setOpen(!current);
44
+ }
45
+ }, "handler");
46
+ window.addEventListener("keydown", handler);
47
+ return () => window.removeEventListener("keydown", handler);
48
+ }, [current, setOpen]);
49
+ const ctxValue = {
50
+ open: current,
51
+ setOpen,
52
+ query,
53
+ setQuery
54
+ };
55
+ return /* @__PURE__ */ jsx(CommandContext.Provider, { value: ctxValue, children });
56
+ }, "CommandRoot");
57
+ var CommandTrigger = /* @__PURE__ */ __name(({ children, className, testID }) => {
58
+ const ctx = useCommandContext("Command.Trigger");
59
+ const open = /* @__PURE__ */ __name(() => ctx.setOpen(true), "open");
60
+ if (Platform.OS === "web") {
61
+ if (isValidElement(children)) {
62
+ const child = children;
63
+ const existingOnClick = child.props.onClick;
64
+ const existingOnPress = child.props.onPress;
65
+ const fire = /* @__PURE__ */ __name((e) => {
66
+ existingOnClick?.(e);
67
+ existingOnPress?.(e);
68
+ open();
69
+ }, "fire");
70
+ const extraProps = {
71
+ onClick: fire,
72
+ "aria-haspopup": "dialog",
73
+ "aria-expanded": ctx.open ? "true" : "false"
74
+ };
75
+ if (existingOnPress !== void 0) {
76
+ extraProps.onPress = fire;
77
+ }
78
+ return cloneElement(child, extraProps);
79
+ }
80
+ return /* @__PURE__ */ jsx(
81
+ "button",
82
+ {
83
+ type: "button",
84
+ "data-testid": testID,
85
+ className: cn("nori-command-trigger", className),
86
+ "aria-haspopup": "dialog",
87
+ "aria-expanded": ctx.open,
88
+ onClick: open,
89
+ children
90
+ }
91
+ );
92
+ }
93
+ return /* @__PURE__ */ jsx(Pressable, { testID, onPress: open, accessibilityRole: "button", children });
94
+ }, "CommandTrigger");
95
+ var CommandDialogInner = /* @__PURE__ */ __name(({
96
+ placeholder = "Type a command or search\u2026",
97
+ children,
98
+ className,
99
+ testID
100
+ }) => {
101
+ const ctx = useCommandContext("Command.Dialog");
102
+ const colors = useThemeColors();
103
+ const inputRef = useRef(null);
104
+ useEffect(() => {
105
+ if (!ctx.open) {
106
+ return;
107
+ }
108
+ if (Platform.OS !== "web") {
109
+ return;
110
+ }
111
+ const id = setTimeout(() => inputRef.current?.focus(), 50);
112
+ return () => clearTimeout(id);
113
+ }, [ctx.open]);
114
+ const contentProps = testID !== void 0 ? { testID, className: cn("nori-command-dialog", className) } : { className: cn("nori-command-dialog", className) };
115
+ return /* @__PURE__ */ jsx(Dialog, { open: ctx.open, onOpenChange: ctx.setOpen, children: /* @__PURE__ */ jsx(Dialog.Content, { ...contentProps, children: Platform.OS === "web" ? /* @__PURE__ */ jsxs(
116
+ "div",
117
+ {
118
+ style: {
119
+ maxHeight: "80vh",
120
+ display: "flex",
121
+ flexDirection: "column",
122
+ overflow: "hidden",
123
+ minWidth: 360
124
+ },
125
+ children: [
126
+ /* @__PURE__ */ jsxs(
127
+ "div",
128
+ {
129
+ style: {
130
+ padding: `${colors.spacing["3"]}px ${colors.spacing["4"]}px`,
131
+ borderBottom: `1px solid ${colors.semantic.border.default}`,
132
+ display: "flex",
133
+ alignItems: "center",
134
+ gap: colors.spacing["2"]
135
+ },
136
+ children: [
137
+ /* @__PURE__ */ jsx(
138
+ "svg",
139
+ {
140
+ width: "16",
141
+ height: "16",
142
+ viewBox: "0 0 16 16",
143
+ fill: "none",
144
+ "aria-hidden": "true",
145
+ style: { color: colors.semantic.text.muted, flexShrink: 0 },
146
+ children: /* @__PURE__ */ jsx(
147
+ "path",
148
+ {
149
+ d: "M6.5 11a4.5 4.5 0 1 0 0-9 4.5 4.5 0 0 0 0 9ZM14 14l-3-3",
150
+ stroke: "currentColor",
151
+ strokeWidth: "1.5",
152
+ strokeLinecap: "round",
153
+ strokeLinejoin: "round"
154
+ }
155
+ )
156
+ }
157
+ ),
158
+ /* @__PURE__ */ jsx(
159
+ "input",
160
+ {
161
+ ref: inputRef,
162
+ type: "text",
163
+ role: "combobox",
164
+ "aria-expanded": true,
165
+ "aria-autocomplete": "list",
166
+ autoComplete: "off",
167
+ spellCheck: false,
168
+ placeholder,
169
+ value: ctx.query,
170
+ onChange: (e) => ctx.setQuery(e.target.value),
171
+ style: {
172
+ flex: 1,
173
+ fontSize: 15,
174
+ background: "transparent",
175
+ border: "none",
176
+ outline: "none",
177
+ color: colors.semantic.text.default,
178
+ width: "100%"
179
+ }
180
+ }
181
+ )
182
+ ]
183
+ }
184
+ ),
185
+ /* @__PURE__ */ jsx("div", { role: "listbox", style: { overflowY: "auto", flex: 1, maxHeight: 400 }, children })
186
+ ]
187
+ }
188
+ ) : /* @__PURE__ */ jsxs(View, { style: { flex: 1 }, children: [
189
+ /* @__PURE__ */ jsx(
190
+ TextInput,
191
+ {
192
+ placeholder,
193
+ placeholderTextColor: colors.semantic.text.muted,
194
+ value: ctx.query,
195
+ onChangeText: ctx.setQuery,
196
+ autoFocus: ctx.open,
197
+ style: {
198
+ fontSize: 15,
199
+ color: colors.semantic.text.default,
200
+ paddingHorizontal: px(colors.spacing["4"]),
201
+ paddingVertical: px(colors.spacing["3"]),
202
+ borderBottomWidth: 1,
203
+ borderBottomColor: colors.semantic.border.default
204
+ }
205
+ }
206
+ ),
207
+ /* @__PURE__ */ jsx(ScrollView, { style: { maxHeight: 400 }, children })
208
+ ] }) }) });
209
+ }, "CommandDialogInner");
210
+ var CommandEmpty = /* @__PURE__ */ __name(({ children, className, testID }) => {
211
+ const colors = useThemeColors();
212
+ if (Platform.OS === "web") {
213
+ return /* @__PURE__ */ jsx(
214
+ "div",
215
+ {
216
+ "data-testid": testID,
217
+ role: "status",
218
+ "aria-live": "polite",
219
+ className: cn("nori-command-empty", className),
220
+ style: {
221
+ paddingTop: colors.spacing["6"],
222
+ paddingBottom: colors.spacing["6"],
223
+ paddingLeft: colors.spacing["4"],
224
+ paddingRight: colors.spacing["4"],
225
+ textAlign: "center",
226
+ color: colors.semantic.text.muted,
227
+ fontSize: 14
228
+ },
229
+ children
230
+ }
231
+ );
232
+ }
233
+ return /* @__PURE__ */ jsx(
234
+ View,
235
+ {
236
+ testID,
237
+ style: {
238
+ paddingVertical: px(colors.spacing["6"]),
239
+ paddingHorizontal: px(colors.spacing["4"]),
240
+ alignItems: "center"
241
+ },
242
+ children: /* @__PURE__ */ jsx(Text, { style: { color: colors.semantic.text.muted, fontSize: 14 }, children: typeof children === "string" ? children : "No results found." })
243
+ }
244
+ );
245
+ }, "CommandEmpty");
246
+ var CommandGroup = /* @__PURE__ */ __name(({ heading, children, className, testID }) => {
247
+ const ctx = useCommandContext("Command.Group");
248
+ const groupId = useId();
249
+ const colors = useThemeColors();
250
+ const visibleCount = countVisibleItems(children, ctx.query);
251
+ if (visibleCount === 0) {
252
+ return null;
253
+ }
254
+ if (Platform.OS === "web") {
255
+ return /* @__PURE__ */ jsxs(
256
+ "section",
257
+ {
258
+ "data-testid": testID,
259
+ "aria-labelledby": heading ? `${groupId}-heading` : void 0,
260
+ className: cn("nori-command-group", className),
261
+ children: [
262
+ heading && /* @__PURE__ */ jsx(
263
+ "div",
264
+ {
265
+ id: `${groupId}-heading`,
266
+ style: {
267
+ padding: `${colors.spacing["2"]}px ${colors.spacing["4"]}px ${colors.spacing["1"]}px`,
268
+ fontSize: 11,
269
+ fontWeight: 600,
270
+ letterSpacing: "0.05em",
271
+ textTransform: "uppercase",
272
+ color: colors.semantic.text.muted
273
+ },
274
+ children: heading
275
+ }
276
+ ),
277
+ /* @__PURE__ */ jsx("div", { style: { paddingBottom: colors.spacing["2"] }, children })
278
+ ]
279
+ }
280
+ );
281
+ }
282
+ return /* @__PURE__ */ jsxs(View, { testID, children: [
283
+ heading && /* @__PURE__ */ jsx(
284
+ View,
285
+ {
286
+ style: {
287
+ paddingHorizontal: px(colors.spacing["4"]),
288
+ paddingTop: px(colors.spacing["2"]),
289
+ paddingBottom: px(colors.spacing["1"])
290
+ },
291
+ children: /* @__PURE__ */ jsx(
292
+ Text,
293
+ {
294
+ style: {
295
+ fontSize: 11,
296
+ fontWeight: "600",
297
+ textTransform: "uppercase",
298
+ color: colors.semantic.text.muted,
299
+ letterSpacing: 0.5
300
+ },
301
+ children: heading
302
+ }
303
+ )
304
+ }
305
+ ),
306
+ children
307
+ ] });
308
+ }, "CommandGroup");
309
+ var CommandItem = /* @__PURE__ */ __name(({ onSelect, disabled = false, children, className, testID }) => {
310
+ const ctx = useCommandContext("Command.Item");
311
+ const colors = useThemeColors();
312
+ const text = extractText(children);
313
+ const visible = matchesQuery(text, ctx.query);
314
+ if (!visible) {
315
+ return null;
316
+ }
317
+ const handleSelect = /* @__PURE__ */ __name(() => {
318
+ if (disabled) {
319
+ return;
320
+ }
321
+ onSelect?.();
322
+ ctx.setOpen(false);
323
+ }, "handleSelect");
324
+ if (Platform.OS === "web") {
325
+ return /* @__PURE__ */ jsx(
326
+ "div",
327
+ {
328
+ "data-testid": testID,
329
+ role: "option",
330
+ "aria-selected": "false",
331
+ "aria-disabled": disabled,
332
+ tabIndex: disabled ? -1 : 0,
333
+ className: cn("nori-command-item", className),
334
+ onClick: handleSelect,
335
+ onKeyDown: (e) => {
336
+ if (e.key === "Enter") {
337
+ e.preventDefault();
338
+ handleSelect();
339
+ }
340
+ },
341
+ onMouseEnter: (e) => {
342
+ if (!disabled) {
343
+ e.currentTarget.style.background = `${colors.semantic.interactive.primary}14`;
344
+ }
345
+ },
346
+ onMouseLeave: (e) => {
347
+ e.currentTarget.style.background = "transparent";
348
+ },
349
+ onFocus: (e) => {
350
+ if (!disabled) {
351
+ e.currentTarget.style.background = `${colors.semantic.interactive.primary}14`;
352
+ }
353
+ },
354
+ onBlur: (e) => {
355
+ e.currentTarget.style.background = "transparent";
356
+ },
357
+ style: {
358
+ display: "flex",
359
+ alignItems: "center",
360
+ justifyContent: "space-between",
361
+ padding: `${colors.spacing["2"]}px ${colors.spacing["4"]}px`,
362
+ cursor: disabled ? "not-allowed" : "pointer",
363
+ opacity: disabled ? 0.5 : 1,
364
+ fontSize: 14,
365
+ color: colors.semantic.text.default,
366
+ borderRadius: colors.radius.sm,
367
+ margin: `0 ${colors.spacing["1"]}px`,
368
+ outline: "none"
369
+ },
370
+ children
371
+ }
372
+ );
373
+ }
374
+ return /* @__PURE__ */ jsx(
375
+ Pressable,
376
+ {
377
+ testID,
378
+ onPress: handleSelect,
379
+ disabled,
380
+ accessibilityRole: "button",
381
+ style: ({ pressed }) => ({
382
+ flexDirection: "row",
383
+ alignItems: "center",
384
+ justifyContent: "space-between",
385
+ paddingHorizontal: px(colors.spacing["4"]),
386
+ paddingVertical: px(colors.spacing["3"]),
387
+ opacity: disabled ? 0.5 : pressed ? 0.7 : 1
388
+ }),
389
+ children: typeof children === "string" ? /* @__PURE__ */ jsx(Text, { style: { fontSize: 14, color: colors.semantic.text.default }, children }) : children
390
+ }
391
+ );
392
+ }, "CommandItem");
393
+ var CommandShortcut = /* @__PURE__ */ __name(({ children, className }) => {
394
+ const colors = useThemeColors();
395
+ if (Platform.OS === "web") {
396
+ return /* @__PURE__ */ jsx(
397
+ "span",
398
+ {
399
+ "aria-hidden": "true",
400
+ className: cn("nori-command-shortcut", className),
401
+ style: {
402
+ marginLeft: "auto",
403
+ fontSize: 12,
404
+ color: colors.semantic.text.muted,
405
+ letterSpacing: "0.05em",
406
+ opacity: 0.7
407
+ },
408
+ children
409
+ }
410
+ );
411
+ }
412
+ return /* @__PURE__ */ jsx(
413
+ Text,
414
+ {
415
+ style: {
416
+ fontSize: 12,
417
+ color: colors.semantic.text.muted,
418
+ opacity: 0.7
419
+ },
420
+ children: typeof children === "string" ? children : null
421
+ }
422
+ );
423
+ }, "CommandShortcut");
424
+ function extractText(node) {
425
+ if (typeof node === "string" || typeof node === "number") {
426
+ return String(node);
427
+ }
428
+ if (Array.isArray(node)) {
429
+ return node.map(extractText).join(" ");
430
+ }
431
+ if (isValidElement(node)) {
432
+ const el = node;
433
+ return extractText(el.props.children);
434
+ }
435
+ return "";
436
+ }
437
+ __name(extractText, "extractText");
438
+ function matchesQuery(text, query) {
439
+ if (!query.trim()) {
440
+ return true;
441
+ }
442
+ return text.toLowerCase().includes(query.toLowerCase().trim());
443
+ }
444
+ __name(matchesQuery, "matchesQuery");
445
+ function countVisibleItems(children, query) {
446
+ let count = 0;
447
+ Children.forEach(children, (child) => {
448
+ if (!isValidElement(child)) {
449
+ return;
450
+ }
451
+ const props = child.props;
452
+ if ("onSelect" in props || !("heading" in props)) {
453
+ const text = extractText(props.children);
454
+ if (matchesQuery(text, query)) {
455
+ count++;
456
+ }
457
+ }
458
+ });
459
+ return count;
460
+ }
461
+ __name(countVisibleItems, "countVisibleItems");
462
+ var CommandDialogWrapper = /* @__PURE__ */ __name((props) => {
463
+ const ctx = useCommandContext("Command.Dialog");
464
+ const { children, ...rest } = props;
465
+ let anyVisible = false;
466
+ let emptyNode = null;
467
+ Children.forEach(children, (child) => {
468
+ if (!isValidElement(child)) {
469
+ return;
470
+ }
471
+ const childProps = child.props;
472
+ if (!("heading" in childProps) && !("onSelect" in childProps) && !("icon" in childProps)) {
473
+ emptyNode = child;
474
+ return;
475
+ }
476
+ const groupChildren = childProps.children;
477
+ const count = countVisibleItems(groupChildren, ctx.query);
478
+ if (count > 0) {
479
+ anyVisible = true;
480
+ }
481
+ });
482
+ return /* @__PURE__ */ jsx(CommandDialogInner, { ...rest, children: anyVisible ? children : emptyNode ?? /* @__PURE__ */ jsx(CommandEmpty, { children: "No results found." }) });
483
+ }, "CommandDialogWrapper");
484
+ var Command = Object.assign(CommandRoot, {
485
+ Trigger: CommandTrigger,
486
+ Dialog: CommandDialogWrapper,
487
+ Empty: CommandEmpty,
488
+ Group: CommandGroup,
489
+ Item: CommandItem,
490
+ Shortcut: CommandShortcut
491
+ });
492
+
493
+ export { Command, useCommandContext };
494
+ //# sourceMappingURL=chunk-OHWRTHGL.js.map
495
+ //# sourceMappingURL=chunk-OHWRTHGL.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/Command/Command.tsx"],"names":["RNTextInput","RNText"],"mappings":"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","file":"chunk-OHWRTHGL.js","sourcesContent":["'use client';\n\n/**\n * Command — cmdk-style command palette (compound component).\n *\n * Anatomy:\n * Command Root — owns open state and filter query.\n * Command.Trigger Element that opens the palette. Default asChild.\n * Command.Dialog The modal surface (search input + item list).\n * Command.Empty Shown when no items match the current query.\n * Command.Group Labelled section of items.\n * Command.Item Selectable action/navigation entry.\n * Command.Shortcut Inline keyboard shortcut hint (right-aligned).\n *\n * Web behaviour:\n * - Global ⌘K / Ctrl+K shortcut opens the palette.\n * - Search input filters items by substring (case-insensitive).\n * - Escape closes (inherited from Dialog).\n *\n * Native behaviour:\n * - Trigger tap opens the palette (no global keyboard shortcut).\n * - Same filtering logic; scrollable list.\n *\n * Implementation note:\n * Reuses the Dialog primitive as the modal surface so we inherit focus\n * trap, scroll lock, backdrop blur, and Escape-to-close for free.\n */\n\nimport {\n Children,\n cloneElement,\n createContext,\n isValidElement,\n type ReactElement,\n type ReactNode,\n useCallback,\n useContext,\n useEffect,\n useId,\n useRef,\n useState,\n} from 'react';\nimport { Platform, Pressable, Text as RNText, TextInput as RNTextInput, ScrollView, View } from 'react-native';\nimport { px } from '../../theme/px';\nimport { useThemeColors } from '../../theme/use-theme-colors';\nimport { cn } from '../../utils/cn';\nimport { Dialog } from '../Dialog/Dialog';\n\n// ---------------------------------------------------------------------------\n// Context\n// ---------------------------------------------------------------------------\n\ntype CommandContextValue = {\n open: boolean;\n setOpen: (next: boolean) => void;\n query: string;\n setQuery: (q: string) => void;\n};\n\nconst CommandContext = createContext<CommandContextValue | null>(null);\n\nfunction useCommandContext(caller: string): CommandContextValue {\n const ctx = useContext(CommandContext);\n if (!ctx) {\n throw new Error(`<${caller}> must be rendered inside <Command>.`);\n }\n return ctx;\n}\n\n// ---------------------------------------------------------------------------\n// Root\n// ---------------------------------------------------------------------------\n\nexport type CommandProps = {\n /** Controlled open state. */\n open?: boolean;\n /** Uncontrolled initial open state. @defaultValue false */\n defaultOpen?: boolean;\n /** Fires with the new open state. */\n onOpenChange?: (open: boolean) => void;\n children?: ReactNode;\n};\n\n/**\n * Root of the Command compound. Owns open state and filter query.\n * Registers the global ⌘K / Ctrl+K shortcut on web.\n */\nconst CommandRoot = ({ open, defaultOpen = false, onOpenChange, children }: CommandProps) => {\n const [inner, setInner] = useState<boolean>(defaultOpen);\n const isControlled = open !== undefined;\n const current = isControlled ? (open as boolean) : inner;\n const [query, setQuery] = useState('');\n\n const setOpen = useCallback(\n (next: boolean) => {\n if (!isControlled) {\n setInner(next);\n }\n if (!next) {\n // Reset query on close so the palette starts fresh next time.\n setQuery('');\n }\n onOpenChange?.(next);\n },\n [isControlled, onOpenChange]\n );\n\n // Global ⌘K / Ctrl+K on web only\n useEffect(() => {\n if (Platform.OS !== 'web') {\n return;\n }\n const handler = (e: KeyboardEvent) => {\n if ((e.metaKey || e.ctrlKey) && e.key === 'k') {\n e.preventDefault();\n setOpen(!current);\n }\n };\n window.addEventListener('keydown', handler);\n return () => window.removeEventListener('keydown', handler);\n }, [current, setOpen]);\n\n const ctxValue: CommandContextValue = {\n open: current,\n setOpen,\n query,\n setQuery,\n };\n\n return <CommandContext.Provider value={ctxValue}>{children}</CommandContext.Provider>;\n};\n\n// ---------------------------------------------------------------------------\n// Trigger\n// ---------------------------------------------------------------------------\n\nexport type CommandTriggerProps = {\n children?: ReactNode;\n className?: string;\n testID?: string;\n};\n\n/**\n * Element that opens the command palette when activated.\n * On web it also receives aria-haspopup=\"dialog\" and aria-expanded.\n */\nconst CommandTrigger = ({ children, className, testID }: CommandTriggerProps) => {\n const ctx = useCommandContext('Command.Trigger');\n\n const open = () => ctx.setOpen(true);\n\n if (Platform.OS === 'web') {\n if (isValidElement(children)) {\n const child = children as ReactElement<{\n onClick?: (e: unknown) => void;\n onPress?: (e: unknown) => void;\n 'aria-haspopup'?: string;\n 'aria-expanded'?: string | boolean;\n }>;\n const existingOnClick = child.props.onClick;\n const existingOnPress = child.props.onPress;\n const fire = (e: unknown) => {\n existingOnClick?.(e);\n existingOnPress?.(e);\n open();\n };\n // Only forward onPress if the child already has it (i.e. it's a RN\n // Pressable-style element). Plain HTML elements (button, a, etc.)\n // don't have onPress and React DOM warns when it receives it.\n const extraProps: Record<string, unknown> = {\n onClick: fire,\n 'aria-haspopup': 'dialog',\n 'aria-expanded': ctx.open ? 'true' : 'false',\n };\n if (existingOnPress !== undefined) {\n extraProps.onPress = fire;\n }\n return cloneElement(child, extraProps as Parameters<typeof cloneElement>[1]);\n }\n return (\n <button\n type=\"button\"\n data-testid={testID}\n className={cn('nori-command-trigger', className)}\n aria-haspopup=\"dialog\"\n aria-expanded={ctx.open}\n onClick={open}\n >\n {children}\n </button>\n );\n }\n\n // Native\n return (\n <Pressable testID={testID} onPress={open} accessibilityRole=\"button\">\n {children}\n </Pressable>\n );\n};\n\n// ---------------------------------------------------------------------------\n// Dialog (modal surface)\n// ---------------------------------------------------------------------------\n\nexport type CommandDialogProps = {\n /** Placeholder text for the search input. @defaultValue 'Type a command or search…' */\n placeholder?: string;\n children?: ReactNode;\n className?: string;\n testID?: string;\n};\n\n/**\n * The modal surface of the command palette.\n *\n * Wraps Dialog.Content and adds a search TextInput above the item list.\n * Children are typically Command.Empty and Command.Group elements.\n */\nconst CommandDialogInner = ({\n placeholder = 'Type a command or search…',\n children,\n className,\n testID,\n}: CommandDialogProps) => {\n const ctx = useCommandContext('Command.Dialog');\n const colors = useThemeColors();\n const inputRef = useRef<HTMLInputElement | null>(null);\n\n // Auto-focus search input when the dialog opens\n useEffect(() => {\n if (!ctx.open) {\n return;\n }\n if (Platform.OS !== 'web') {\n return;\n }\n const id = setTimeout(() => inputRef.current?.focus(), 50);\n return () => clearTimeout(id);\n }, [ctx.open]);\n\n const contentProps =\n testID !== undefined\n ? { testID, className: cn('nori-command-dialog', className) }\n : { className: cn('nori-command-dialog', className) };\n\n return (\n <Dialog open={ctx.open} onOpenChange={ctx.setOpen}>\n <Dialog.Content {...contentProps}>\n {Platform.OS === 'web' ? (\n <div\n style={{\n maxHeight: '80vh',\n display: 'flex',\n flexDirection: 'column',\n overflow: 'hidden',\n minWidth: 360,\n }}\n >\n {/* Search bar */}\n <div\n style={{\n padding: `${colors.spacing['3']}px ${colors.spacing['4']}px`,\n borderBottom: `1px solid ${colors.semantic.border.default}`,\n display: 'flex',\n alignItems: 'center',\n gap: colors.spacing['2'],\n }}\n >\n {/* Magnifier icon — inline SVG; no extra dep */}\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n aria-hidden=\"true\"\n style={{ color: colors.semantic.text.muted, flexShrink: 0 }}\n >\n <path\n d=\"M6.5 11a4.5 4.5 0 1 0 0-9 4.5 4.5 0 0 0 0 9ZM14 14l-3-3\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n <input\n ref={inputRef}\n type=\"text\"\n role=\"combobox\"\n aria-expanded={true}\n aria-autocomplete=\"list\"\n autoComplete=\"off\"\n spellCheck={false}\n placeholder={placeholder}\n value={ctx.query}\n onChange={(e) => ctx.setQuery(e.target.value)}\n style={\n {\n flex: 1,\n fontSize: 15,\n background: 'transparent',\n border: 'none',\n outline: 'none',\n color: colors.semantic.text.default,\n width: '100%',\n } as React.CSSProperties\n }\n />\n </div>\n {/* Items list */}\n <div role=\"listbox\" style={{ overflowY: 'auto', flex: 1, maxHeight: 400 }}>\n {children}\n </div>\n </div>\n ) : (\n <View style={{ flex: 1 }}>\n <RNTextInput\n placeholder={placeholder}\n placeholderTextColor={colors.semantic.text.muted}\n value={ctx.query}\n onChangeText={ctx.setQuery}\n autoFocus={ctx.open}\n style={{\n fontSize: 15,\n color: colors.semantic.text.default,\n paddingHorizontal: px(colors.spacing['4']),\n paddingVertical: px(colors.spacing['3']),\n borderBottomWidth: 1,\n borderBottomColor: colors.semantic.border.default,\n }}\n />\n <ScrollView style={{ maxHeight: 400 }}>{children}</ScrollView>\n </View>\n )}\n </Dialog.Content>\n </Dialog>\n );\n};\n\n// ---------------------------------------------------------------------------\n// Empty\n// ---------------------------------------------------------------------------\n\nexport type CommandEmptyProps = {\n children?: ReactNode;\n className?: string;\n testID?: string;\n};\n\n/**\n * Shown when the current query has no matching Command.Item descendants.\n */\nconst CommandEmpty = ({ children, className, testID }: CommandEmptyProps) => {\n const colors = useThemeColors();\n\n if (Platform.OS === 'web') {\n return (\n <div\n data-testid={testID}\n role=\"status\"\n aria-live=\"polite\"\n className={cn('nori-command-empty', className)}\n style={\n {\n paddingTop: colors.spacing['6'],\n paddingBottom: colors.spacing['6'],\n paddingLeft: colors.spacing['4'],\n paddingRight: colors.spacing['4'],\n textAlign: 'center',\n color: colors.semantic.text.muted,\n fontSize: 14,\n } as React.CSSProperties\n }\n >\n {children}\n </div>\n );\n }\n return (\n <View\n testID={testID}\n style={{\n paddingVertical: px(colors.spacing['6']),\n paddingHorizontal: px(colors.spacing['4']),\n alignItems: 'center',\n }}\n >\n <RNText style={{ color: colors.semantic.text.muted, fontSize: 14 }}>\n {typeof children === 'string' ? children : 'No results found.'}\n </RNText>\n </View>\n );\n};\n\n// ---------------------------------------------------------------------------\n// Group\n// ---------------------------------------------------------------------------\n\nexport type CommandGroupProps = {\n /** Section heading. */\n heading?: string;\n children?: ReactNode;\n className?: string;\n testID?: string;\n};\n\n/**\n * Labelled group of Command.Item elements.\n * Hides itself when all its items are filtered out.\n */\nconst CommandGroup = ({ heading, children, className, testID }: CommandGroupProps) => {\n const ctx = useCommandContext('Command.Group');\n const groupId = useId();\n const colors = useThemeColors();\n\n const visibleCount = countVisibleItems(children, ctx.query);\n\n if (visibleCount === 0) {\n return null;\n }\n\n if (Platform.OS === 'web') {\n return (\n <section\n data-testid={testID}\n aria-labelledby={heading ? `${groupId}-heading` : undefined}\n className={cn('nori-command-group', className)}\n >\n {heading && (\n <div\n id={`${groupId}-heading`}\n style={\n {\n padding: `${colors.spacing['2']}px ${colors.spacing['4']}px ${colors.spacing['1']}px`,\n fontSize: 11,\n fontWeight: 600,\n letterSpacing: '0.05em',\n textTransform: 'uppercase',\n color: colors.semantic.text.muted,\n } as React.CSSProperties\n }\n >\n {heading}\n </div>\n )}\n <div style={{ paddingBottom: colors.spacing['2'] }}>{children}</div>\n </section>\n );\n }\n\n return (\n <View testID={testID}>\n {heading && (\n <View\n style={{\n paddingHorizontal: px(colors.spacing['4']),\n paddingTop: px(colors.spacing['2']),\n paddingBottom: px(colors.spacing['1']),\n }}\n >\n <RNText\n style={{\n fontSize: 11,\n fontWeight: '600',\n textTransform: 'uppercase',\n color: colors.semantic.text.muted,\n letterSpacing: 0.5,\n }}\n >\n {heading}\n </RNText>\n </View>\n )}\n {children}\n </View>\n );\n};\n\n// ---------------------------------------------------------------------------\n// Item\n// ---------------------------------------------------------------------------\n\nexport type CommandItemProps = {\n /** Fires when the item is selected (click or Enter). */\n onSelect?: () => void;\n /** Disable the item. @defaultValue false */\n disabled?: boolean;\n children?: ReactNode;\n className?: string;\n testID?: string;\n};\n\n/**\n * Selectable command item. Filters itself out when the current query does\n * not match its text content.\n */\nconst CommandItem = ({ onSelect, disabled = false, children, className, testID }: CommandItemProps) => {\n const ctx = useCommandContext('Command.Item');\n const colors = useThemeColors();\n\n const text = extractText(children);\n const visible = matchesQuery(text, ctx.query);\n\n if (!visible) {\n return null;\n }\n\n const handleSelect = () => {\n if (disabled) {\n return;\n }\n onSelect?.();\n ctx.setOpen(false);\n };\n\n if (Platform.OS === 'web') {\n return (\n <div\n data-testid={testID}\n role=\"option\"\n aria-selected=\"false\"\n aria-disabled={disabled}\n tabIndex={disabled ? -1 : 0}\n className={cn('nori-command-item', className)}\n onClick={handleSelect}\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n handleSelect();\n }\n }}\n onMouseEnter={(e) => {\n if (!disabled) {\n (e.currentTarget as HTMLElement).style.background = `${colors.semantic.interactive.primary}14`;\n }\n }}\n onMouseLeave={(e) => {\n (e.currentTarget as HTMLElement).style.background = 'transparent';\n }}\n onFocus={(e) => {\n if (!disabled) {\n (e.currentTarget as HTMLElement).style.background = `${colors.semantic.interactive.primary}14`;\n }\n }}\n onBlur={(e) => {\n (e.currentTarget as HTMLElement).style.background = 'transparent';\n }}\n style={\n {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: `${colors.spacing['2']}px ${colors.spacing['4']}px`,\n cursor: disabled ? 'not-allowed' : 'pointer',\n opacity: disabled ? 0.5 : 1,\n fontSize: 14,\n color: colors.semantic.text.default,\n borderRadius: colors.radius.sm,\n margin: `0 ${colors.spacing['1']}px`,\n outline: 'none',\n } as React.CSSProperties\n }\n >\n {children}\n </div>\n );\n }\n\n return (\n <Pressable\n testID={testID}\n onPress={handleSelect}\n disabled={disabled}\n accessibilityRole=\"button\"\n style={({ pressed }: { pressed: boolean }) => ({\n flexDirection: 'row' as const,\n alignItems: 'center' as const,\n justifyContent: 'space-between' as const,\n paddingHorizontal: px(colors.spacing['4']),\n paddingVertical: px(colors.spacing['3']),\n opacity: disabled ? 0.5 : pressed ? 0.7 : 1,\n })}\n >\n {typeof children === 'string' ? (\n <RNText style={{ fontSize: 14, color: colors.semantic.text.default }}>{children}</RNText>\n ) : (\n children\n )}\n </Pressable>\n );\n};\n\n// ---------------------------------------------------------------------------\n// Shortcut\n// ---------------------------------------------------------------------------\n\nexport type CommandShortcutProps = {\n children?: ReactNode;\n className?: string;\n};\n\n/**\n * Keyboard shortcut hint rendered right-aligned inside a Command.Item.\n */\nconst CommandShortcut = ({ children, className }: CommandShortcutProps) => {\n const colors = useThemeColors();\n\n if (Platform.OS === 'web') {\n return (\n <span\n aria-hidden=\"true\"\n className={cn('nori-command-shortcut', className)}\n style={{\n marginLeft: 'auto',\n fontSize: 12,\n color: colors.semantic.text.muted,\n letterSpacing: '0.05em',\n opacity: 0.7,\n }}\n >\n {children}\n </span>\n );\n }\n\n return (\n <RNText\n style={{\n fontSize: 12,\n color: colors.semantic.text.muted,\n opacity: 0.7,\n }}\n >\n {typeof children === 'string' ? children : null}\n </RNText>\n );\n};\n\n// ---------------------------------------------------------------------------\n// Filter helpers\n// ---------------------------------------------------------------------------\n\n/** Extract concatenated text from a ReactNode tree for query matching. */\nfunction extractText(node: ReactNode): string {\n if (typeof node === 'string' || typeof node === 'number') {\n return String(node);\n }\n if (Array.isArray(node)) {\n return node.map(extractText).join(' ');\n }\n if (isValidElement(node)) {\n const el = node as ReactElement<{ children?: ReactNode }>;\n return extractText(el.props.children);\n }\n return '';\n}\n\n/** Case-insensitive substring match. Empty query matches everything. */\nfunction matchesQuery(text: string, query: string): boolean {\n if (!query.trim()) {\n return true;\n }\n return text.toLowerCase().includes(query.toLowerCase().trim());\n}\n\n/**\n * Count how many Command.Item children would be visible for the given query.\n * Inspects direct CommandItem-shaped children only (duck-typed by `onSelect` prop).\n */\nfunction countVisibleItems(children: ReactNode, query: string): number {\n let count = 0;\n Children.forEach(children, (child) => {\n if (!isValidElement(child)) {\n return;\n }\n const props = child.props as Record<string, unknown>;\n // CommandItem is duck-typed: has `onSelect` or no `heading`\n if ('onSelect' in props || !('heading' in props)) {\n const text = extractText(props.children as ReactNode);\n if (matchesQuery(text, query)) {\n count++;\n }\n }\n });\n return count;\n}\n\n// ---------------------------------------------------------------------------\n// Public Dialog wrapper: auto-show Empty when no group renders anything\n// ---------------------------------------------------------------------------\n\n/**\n * Wraps CommandDialogInner to automatically surface Command.Empty when all\n * items are filtered away. This is what is exposed as `Command.Dialog`.\n */\nconst CommandDialogWrapper = (props: CommandDialogProps) => {\n const ctx = useCommandContext('Command.Dialog');\n const { children, ...rest } = props;\n\n let anyVisible = false;\n let emptyNode: ReactNode = null;\n\n Children.forEach(children, (child) => {\n if (!isValidElement(child)) {\n return;\n }\n const childProps = child.props as Record<string, unknown>;\n\n // Detect Empty: has no heading, no onSelect, no icon — purely a display node\n if (!('heading' in childProps) && !('onSelect' in childProps) && !('icon' in childProps)) {\n emptyNode = child;\n return;\n }\n\n // It's a Group — count visible items in its children\n const groupChildren = childProps.children as ReactNode;\n const count = countVisibleItems(groupChildren, ctx.query);\n if (count > 0) {\n anyVisible = true;\n }\n });\n\n return (\n <CommandDialogInner {...rest}>\n {anyVisible ? children : (emptyNode ?? <CommandEmpty>No results found.</CommandEmpty>)}\n </CommandDialogInner>\n );\n};\n\n// ---------------------------------------------------------------------------\n// Compound export\n// ---------------------------------------------------------------------------\n\n/**\n * cmdk-style command palette.\n *\n * ```tsx\n * <Command>\n * <Command.Trigger>\n * <Button>Search<Kbd>⌘K</Kbd></Button>\n * </Command.Trigger>\n * <Command.Dialog placeholder=\"Type a command or search…\">\n * <Command.Empty>No results found.</Command.Empty>\n * <Command.Group heading=\"Suggestions\">\n * <Command.Item onSelect={() => navigate('/calendar')}>Calendar</Command.Item>\n * <Command.Item onSelect={() => navigate('/emoji')}>Search Emoji</Command.Item>\n * </Command.Group>\n * <Command.Group heading=\"Settings\">\n * <Command.Item onSelect={() => navigate('/profile')}>\n * Profile<Command.Shortcut>⌘P</Command.Shortcut>\n * </Command.Item>\n * </Command.Group>\n * </Command.Dialog>\n * </Command>\n * ```\n */\nexport const Command = Object.assign(CommandRoot, {\n Trigger: CommandTrigger,\n Dialog: CommandDialogWrapper,\n Empty: CommandEmpty,\n Group: CommandGroup,\n Item: CommandItem,\n Shortcut: CommandShortcut,\n});\n\n// Re-export context hook for advanced use.\nexport { useCommandContext };\n\nimport type React from 'react';\n"]}
@@ -1,5 +1,5 @@
1
- import { useAnimatedNumber } from './chunk-RB3YBWQ4.js';
2
1
  import { AnimatedView } from './chunk-RGJ3NBKE.js';
2
+ import { useAnimatedNumber } from './chunk-RB3YBWQ4.js';
3
3
  import { defaultSemanticIcons } from './chunk-7Z4NMNX6.js';
4
4
  import { px } from './chunk-5A2QOOVN.js';
5
5
  import { useThemeColors } from './chunk-R5JMDDCB.js';
@@ -446,5 +446,5 @@ var Accordion = Object.assign(AccordionRoot, {
446
446
  });
447
447
 
448
448
  export { Accordion };
449
- //# sourceMappingURL=chunk-V5QSMDZL.js.map
450
- //# sourceMappingURL=chunk-V5QSMDZL.js.map
449
+ //# sourceMappingURL=chunk-QB6RH6UU.js.map
450
+ //# sourceMappingURL=chunk-QB6RH6UU.js.map