@gusnips/react 0.9.25 → 0.9.26

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/README.md CHANGED
@@ -350,6 +350,38 @@ It keeps the page and drops only a fragment carrying a credential, because the p
350
350
  worth returning to. `createRequireAuth` uses it; use it anywhere else you record where someone was:
351
351
  a dead-session redirect is the common one.
352
352
 
353
+ ## Keep the email between sign-in screens
354
+
355
+ ```tsx
356
+ import { recallAuthEmail, rememberAuthEmail } from "@gusnips/react";
357
+
358
+ <input
359
+ name="email"
360
+ type="email"
361
+ defaultValue={recallAuthEmail()}
362
+ onChange={(event) => rememberAuthEmail(event.currentTarget.value)}
363
+ />;
364
+ ```
365
+
366
+ Sign in, "use a code instead", forgot password and create account are separate screens, and each
367
+ one used to open with an empty email field. Put those two props on every one of them and the
368
+ address follows the person. Call `forgetAuthEmail()` where your app learns a session exists, so the
369
+ next person at this browser starts empty.
370
+
371
+ It is kept in `localStorage` for 30 minutes after the last keystroke, and never in a URL, where it
372
+ would reach `Referer`, access logs, history and analytics. It is `localStorage` and not
373
+ `sessionStorage` because an emailed link opens in a new tab, and a new tab does not inherit
374
+ `sessionStorage`. That tab is where a person lands on sign-in after confirming an account. Where
375
+ the browser blocks site data, or on React Native, the address lasts in memory until the page or the
376
+ app is left.
377
+
378
+ - Read it once, when the screen opens. It is not a store: nothing re-renders when it changes. On a
379
+ prerendered page, read it after hydration, never while rendering.
380
+ - Leave the field uncontrolled. A `defaultValue` and a change handler are enough. Also call
381
+ `rememberAuthEmail(value)` where you read the field at submit, because some password managers fill
382
+ a form without firing events.
383
+ - Never put a password, a code or a token here.
384
+
353
385
  ## Never dead-end anyone
354
386
 
355
387
  ```ts
@@ -497,6 +529,110 @@ toast needs no `catch`. Outside a component, `copyText(text)` does the write on
497
529
  The words are yours, and so is the live region: a label that changes needs `aria-live` to be
498
530
  heard.
499
531
 
532
+ ## Slash commands in a text field
533
+
534
+ A slash command is text like `/help` that picks an action instead of sending a message.
535
+
536
+ ```ts
537
+ import { parseCommand } from "@gusnips/react/commands";
538
+
539
+ parseCommand("/help");
540
+ // { name: "help" }
541
+ ```
542
+
543
+ Names have no leading slash. Give each command other names (`aliases`) and search words (`tags`):
544
+
545
+ ```ts
546
+ const commands = [
547
+ {
548
+ name: "help",
549
+ description: "See commands",
550
+ aliases: ["commands", "shortcuts"],
551
+ tags: ["keyboard", "guide"],
552
+ },
553
+ ];
554
+ ```
555
+
556
+ `/commands` runs `/help`. Searching for `keyboard` finds its menu row, but `/keyboard` is not an
557
+ executable name. `matchCommands(commands, query)` searches names, aliases, tags and descriptions,
558
+ ignoring case and accents. Exact names rank first, then aliases, name prefixes, alias prefixes,
559
+ tags and descriptions. Equal ranks keep registry order; each name gets one row.
560
+
561
+ `resolveCommand(commands, name)` answers `matched`, `unknown` or `ambiguous`. An exact name wins
562
+ over an alias. Two commands sharing an alias are ambiguous, not a reason to run the first one.
563
+
564
+ For a controlled text field, use the hook:
565
+
566
+ ```tsx
567
+ import { useSlashCommands } from "@gusnips/react/commands";
568
+
569
+ const slash = useSlashCommands({
570
+ text,
571
+ commands,
572
+ onChange: setText,
573
+ onExecute: runCommand,
574
+ onError: showCommandError,
575
+ });
576
+
577
+ function submit() {
578
+ if (slash.submit()) return;
579
+ sendMessage(text);
580
+ }
581
+ ```
582
+
583
+ The functions in that example belong to your app. `runCommand(command, arg, altKey)` gets the
584
+ original command object, the argument and whether Alt was held. It owns permissions and action
585
+ errors. Supply only commands allowed in this field, with descriptions and tags in the current
586
+ language. Changing those commands or the language refreshes the menu even if `text` stays the same.
587
+
588
+ Call `slash.handleKeyDown(event)` first in the field's key handler. If it returns `true`, stop
589
+ your own handler. Arrows move the selection; Enter picks it. Tab completes the name without
590
+ running it. Escape hides the menu until the query changes. Shift+Enter stays yours. During IME
591
+ composition (when a keyboard combines keystrokes into a character), the hook lets the browser
592
+ finish that character without running or sending anything.
593
+
594
+ Render the rows in your own menu. Keep focus in the field with the browser's `preventDefault`
595
+ on mouse down; use click for the action so keyboard and screen-reader clicks work too:
596
+
597
+ ```tsx
598
+ return slash.open ? (
599
+ <div id={slash.listId} role="listbox" aria-label="Commands">
600
+ {slash.items.map((command, index) => (
601
+ <button
602
+ key={command.name}
603
+ id={slash.itemId(command)}
604
+ type="button"
605
+ role="option"
606
+ tabIndex={-1}
607
+ aria-selected={slash.index === index}
608
+ onMouseEnter={() => slash.highlight(index)}
609
+ onMouseDown={(event) => event.preventDefault()}
610
+ onClick={(event) => slash.pick(command, event.altKey)}
611
+ >
612
+ /{command.name}: {command.description}
613
+ </button>
614
+ ))}
615
+ </div>
616
+ ) : null;
617
+ ```
618
+
619
+ Give the field `role="combobox"`, `aria-autocomplete="list"`, `aria-expanded={slash.open}`,
620
+ `aria-controls={slash.open ? slash.listId : undefined}` and `aria-activedescendant={slash.activeId}`.
621
+ Translate the menu label too. If there are no rows, explain how to find commands and offer a
622
+ "See commands" button that calls `slash.showAll()`. It opens the full list, even after Escape.
623
+ `onError` is required: show what was not recognized, or which names share an alias, with the
624
+ same way back to the list.
625
+
626
+ Set `takesArg: true` when a command accepts an argument. Selecting it, or submitting its bare
627
+ alias, completes `/name ` without running it. Completion keeps arguments already typed.
628
+ `parseCommand` leaves multiline text as a normal message.
629
+
630
+ Call `submit()` before every normal send, queue or quota check, including button and imperative
631
+ paths. It returns `true` for commands it ran, completed or rejected, so unknown commands never
632
+ silently become model messages. It returns `false` for ordinary text. The hook never sends a
633
+ message, clears a draft or changes attached files; those stay with the app. It also has no timer
634
+ or scheduler: offer a repeat command only when your app has real scheduling behind it.
635
+
500
636
  ## Also here
501
637
 
502
638
  `ErrorBoundary`, an SSE reader split into a platform-free parser and a stream wrapper,
@@ -577,6 +713,7 @@ lives behind a subpath, so you install a dependency only if you import the thing
577
713
  | `@gusnips/react/ui` | the seven wrappers | @base-ui/react |
578
714
  | `@gusnips/react/contract` | two prerender names | nothing |
579
715
  | `@gusnips/react/theme` | `createTheme`, `startTheme` | react |
716
+ | `@gusnips/react/commands` | slash matching and `useSlashCommands` | react |
580
717
 
581
718
  The rule behind that table: **a peer marked optional must not be reachable from the main entry
582
719
  point.** An optional peer the barrel imports anyway is not optional: it is a required one whose
@@ -0,0 +1,80 @@
1
+ export interface SlashCommand {
2
+ /** One token, without the leading slash. */
3
+ name: string;
4
+ description: string;
5
+ /** Other executable names. Tags only help search. */
6
+ aliases: readonly string[];
7
+ tags: readonly string[];
8
+ takesArg?: boolean;
9
+ }
10
+ export interface ParsedCommand {
11
+ name: string;
12
+ /** Undefined before a space; empty after a space with no argument yet. */
13
+ arg?: string;
14
+ }
15
+ /** Multiline text and a slash inside a message are not commands. */
16
+ export declare function parseCommand(text: string): ParsedCommand | null;
17
+ export type CommandResolution<T extends SlashCommand = SlashCommand> = {
18
+ kind: "matched";
19
+ command: T;
20
+ } | {
21
+ kind: "unknown";
22
+ name: string;
23
+ } | {
24
+ kind: "ambiguous";
25
+ name: string;
26
+ commands: readonly T[];
27
+ };
28
+ /** Exact names win over aliases. Search tags never execute an action. */
29
+ export declare function resolveCommand<T extends SlashCommand>(commands: readonly T[], name: string): CommandResolution<T>;
30
+ /** One row per name, in registry order when two results have the same rank. */
31
+ export declare function matchCommands<T extends SlashCommand>(commands: readonly T[], query: string): T[];
32
+ /** Replace only the name, keeping the argument already typed. */
33
+ export declare function completeCommand(command: SlashCommand, text: string): string;
34
+ export type CommandProblem<T extends SlashCommand = SlashCommand> = Exclude<CommandResolution<T>, {
35
+ kind: "matched";
36
+ }>;
37
+ export interface CommandOptions<T extends SlashCommand> {
38
+ text: string;
39
+ /** Supply only commands allowed here, with current translated descriptions and tags. */
40
+ commands: readonly T[];
41
+ onChange: (text: string) => void;
42
+ /** The app owns authorization, errors, draft cleanup and attachments. */
43
+ onExecute: (command: T, arg: string | undefined, altKey: boolean) => void;
44
+ /** Required: show a way back to the available commands, never send this text to the model. */
45
+ onError: (problem: CommandProblem<T>) => void;
46
+ }
47
+ /** Structural so React events and small test events both fit. */
48
+ export interface CommandKeyEvent {
49
+ key: string;
50
+ shiftKey?: boolean;
51
+ altKey?: boolean;
52
+ ctrlKey?: boolean;
53
+ metaKey?: boolean;
54
+ isComposing?: boolean;
55
+ keyCode?: number;
56
+ nativeEvent?: {
57
+ isComposing?: boolean;
58
+ keyCode?: number;
59
+ };
60
+ preventDefault: () => void;
61
+ }
62
+ export interface SlashCommandMenu<T extends SlashCommand = SlashCommand> {
63
+ parsed: ParsedCommand | null;
64
+ open: boolean;
65
+ items: readonly T[];
66
+ index: number;
67
+ active: T | undefined;
68
+ listId: string;
69
+ itemId: (command: T) => string;
70
+ activeId: string | undefined;
71
+ highlight: (index: number) => void;
72
+ close: () => void;
73
+ showAll: () => void;
74
+ pick: (command: T, altKey?: boolean) => void;
75
+ submit: (altKey?: boolean) => boolean;
76
+ handleKeyDown: (event: CommandKeyEvent) => boolean;
77
+ }
78
+ /** A controlled textarea menu. No UI, browser globals, timers or attachment state. */
79
+ export declare function useSlashCommands<T extends SlashCommand>({ text, commands, onChange, onExecute, onError, }: CommandOptions<T>): SlashCommandMenu<T>;
80
+ //# sourceMappingURL=commands.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,192 @@
1
+ import { useId, useState } from "react";
2
+ /** Multiline text and a slash inside a message are not commands. */
3
+ export function parseCommand(text) {
4
+ if (/[\r\n\u{2028}\u{2029}]/u.test(text))
5
+ return null;
6
+ const match = /^\s*\/(\S*)(?:[^\S\r\n]+(.*))?$/u.exec(text);
7
+ if (!match)
8
+ return null;
9
+ const name = (match[1] ?? "").toLowerCase();
10
+ return match[2] === undefined ? { name } : { name, arg: match[2] };
11
+ }
12
+ /** Exact names win over aliases. Search tags never execute an action. */
13
+ export function resolveCommand(commands, name) {
14
+ const token = name.toLowerCase();
15
+ if (!token)
16
+ return { kind: "unknown", name };
17
+ let matches = commands.filter((command) => command.name.toLowerCase() === token);
18
+ if (matches.length === 0) {
19
+ matches = commands.filter((command) => command.aliases.some((alias) => alias.toLowerCase() === token));
20
+ }
21
+ if (matches.length > 1)
22
+ return { kind: "ambiguous", name, commands: matches };
23
+ const command = matches[0];
24
+ return command ? { kind: "matched", command } : { kind: "unknown", name };
25
+ }
26
+ function searchText(text) {
27
+ return text.normalize("NFD").replace(/\p{M}/gu, "").toLowerCase();
28
+ }
29
+ function rank(command, query) {
30
+ if (!query)
31
+ return 0;
32
+ const name = searchText(command.name);
33
+ const aliases = command.aliases.map(searchText);
34
+ if (name === query)
35
+ return 0;
36
+ if (aliases.includes(query))
37
+ return 1;
38
+ if (name.startsWith(query))
39
+ return 2;
40
+ if (aliases.some((alias) => alias.startsWith(query)))
41
+ return 3;
42
+ if (command.tags.some((tag) => searchText(tag).includes(query)))
43
+ return 4;
44
+ if (searchText(command.description).includes(query))
45
+ return 5;
46
+ return Infinity;
47
+ }
48
+ /** One row per name, in registry order when two results have the same rank. */
49
+ export function matchCommands(commands, query) {
50
+ const token = searchText(query.trim());
51
+ const names = new Set();
52
+ return commands
53
+ .filter((command) => {
54
+ const name = command.name.toLowerCase();
55
+ if (names.has(name))
56
+ return false;
57
+ names.add(name);
58
+ return true;
59
+ })
60
+ .map((command) => ({ command, rank: rank(command, token) }))
61
+ .filter((match) => Number.isFinite(match.rank))
62
+ .sort((a, b) => a.rank - b.rank)
63
+ .map((match) => match.command);
64
+ }
65
+ /** Replace only the name, keeping the argument already typed. */
66
+ export function completeCommand(command, text) {
67
+ const arg = parseCommand(text)?.arg;
68
+ if (arg !== undefined)
69
+ return `/${command.name} ${arg}`;
70
+ return `/${command.name}${command.takesArg ? " " : ""}`;
71
+ }
72
+ /** A controlled textarea menu. No UI, browser globals, timers or attachment state. */
73
+ export function useSlashCommands({ text, commands, onChange, onExecute, onError, }) {
74
+ const parsed = parseCommand(text);
75
+ const resolution = parsed ? resolveCommand(commands, parsed.name) : null;
76
+ const editingName = parsed !== null && (parsed.arg === undefined || resolution?.kind !== "matched");
77
+ const items = editingName ? matchCommands(commands, parsed.name) : [];
78
+ const key = JSON.stringify([text, items.map((command) => command.name)]);
79
+ const [state, setState] = useState({ key, text, index: 0, deliberate: false, dismissed: false });
80
+ // Reset selection on a changed result set, but keep Escape's dismissal until the draft changes.
81
+ if (state.key !== key) {
82
+ setState({
83
+ key,
84
+ text,
85
+ index: 0,
86
+ deliberate: false,
87
+ dismissed: state.text === text && state.dismissed,
88
+ });
89
+ }
90
+ const listId = `${useId()}-commands`;
91
+ const open = editingName && !state.dismissed;
92
+ const active = open ? items[state.index] : undefined;
93
+ const itemId = (command) => `${listId}-${encodeURIComponent(command.name)}`;
94
+ function close() {
95
+ setState((current) => ({ ...current, dismissed: true }));
96
+ }
97
+ function showAll() {
98
+ setState((current) => ({ ...current, index: 0, deliberate: false, dismissed: false }));
99
+ onChange("/");
100
+ }
101
+ function highlight(index) {
102
+ if (!items[index])
103
+ return;
104
+ setState((current) => ({ ...current, index, deliberate: true }));
105
+ }
106
+ function pick(command, altKey = false) {
107
+ // Re-resolve against current capabilities, not a descriptor retained by a caller.
108
+ const selected = resolveCommand(commands, command.name);
109
+ if (selected.kind !== "matched") {
110
+ onError(selected);
111
+ return;
112
+ }
113
+ if (selected.command.takesArg || parsed?.arg) {
114
+ onChange(completeCommand(selected.command, text));
115
+ return;
116
+ }
117
+ onExecute(selected.command, parsed?.arg, altKey);
118
+ }
119
+ /** Call before the normal send/queue/quota path, including button and imperative submits. */
120
+ function submit(altKey = false) {
121
+ if (!parsed || !resolution)
122
+ return false;
123
+ if (resolution.kind !== "matched") {
124
+ onError(resolution);
125
+ return true;
126
+ }
127
+ if (resolution.command.takesArg &&
128
+ parsed.arg === undefined &&
129
+ parsed.name !== resolution.command.name.toLowerCase()) {
130
+ onChange(completeCommand(resolution.command, text));
131
+ return true;
132
+ }
133
+ onExecute(resolution.command, parsed.arg, altKey);
134
+ return true;
135
+ }
136
+ /** Call first. True means skip your own key handler; IME still gets the browser's default. */
137
+ function handleKeyDown(event) {
138
+ const native = event.nativeEvent ?? event;
139
+ if (native.isComposing || native.keyCode === 229)
140
+ return true;
141
+ if (event.shiftKey)
142
+ return false;
143
+ if (open && event.key === "Escape") {
144
+ event.preventDefault();
145
+ close();
146
+ return true;
147
+ }
148
+ if (open && items.length > 0 && !event.ctrlKey && !event.metaKey) {
149
+ if (event.key === "ArrowDown" || event.key === "ArrowUp") {
150
+ event.preventDefault();
151
+ const step = event.key === "ArrowDown" ? 1 : -1;
152
+ highlight((state.index + step + items.length) % items.length);
153
+ return true;
154
+ }
155
+ if (active && (event.key === "Enter" || event.key === "Tab")) {
156
+ event.preventDefault();
157
+ if (event.key === "Tab") {
158
+ onChange(completeCommand(active, text));
159
+ }
160
+ else if (resolution?.kind === "ambiguous" && !state.deliberate) {
161
+ onError(resolution);
162
+ }
163
+ else {
164
+ pick(active, event.altKey);
165
+ }
166
+ return true;
167
+ }
168
+ }
169
+ if (parsed && event.key === "Enter") {
170
+ event.preventDefault();
171
+ return submit(event.altKey);
172
+ }
173
+ return false;
174
+ }
175
+ return {
176
+ parsed,
177
+ open,
178
+ items,
179
+ index: state.index,
180
+ active,
181
+ listId,
182
+ itemId,
183
+ activeId: active ? itemId(active) : undefined,
184
+ highlight,
185
+ close,
186
+ showAll,
187
+ pick,
188
+ submit,
189
+ handleKeyDown,
190
+ };
191
+ }
192
+ //# sourceMappingURL=commands.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commands.js","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":"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"}
package/dist/ui/menu.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { Menu as Primitive } from "@base-ui/react/menu";
2
2
  import type { ReactNode } from "react";
3
- export declare const Menu: <Payload>(props: Primitive.Root.Props<Payload>) => React.JSX.Element;
3
+ export declare const Menu: typeof Primitive.Root;
4
4
  export declare const MenuTrigger: Primitive.Trigger;
5
5
  export declare const MenuPortal: import("react").ForwardRefExoticComponent<Omit<import("@base-ui/react").ContextMenuPortalProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
6
6
  export declare const MenuPositioner: import("react").ForwardRefExoticComponent<Omit<import("@base-ui/react").MenuPositionerProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
@@ -1 +1 @@
1
- {"version":3,"file":"menu.d.ts","sourceRoot":"","sources":["../../src/ui/menu.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,IAAI,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAavC,eAAO,MAAM,IAAI,sEAAiB,CAAC;AACnC,eAAO,MAAM,WAAW,mBAAoB,CAAC;AAC7C,eAAO,MAAM,UAAU,yJAAmB,CAAC;AAC3C,eAAO,MAAM,cAAc,sJAAuB,CAAC;AACnD,eAAO,MAAM,SAAS,wJAAkB,CAAC;AACzC,eAAO,MAAM,YAAY,2JAAqB,CAAC;AAC/C,eAAO,MAAM,SAAS,wJAAkB,CAAC;AACzC,eAAO,MAAM,YAAY,oJAAqB,CAAC;AAC/C,eAAO,MAAM,gBAAgB,4JAAyB,CAAC;AACvD,eAAO,MAAM,yBAAyB,yKAAkC,CAAC;AACzE,eAAO,MAAM,sBAAsB,sKAA+B,CAAC;AACnE,eAAO,MAAM,eAAe,8BAAwB,CAAC;AACrD,eAAO,MAAM,kBAAkB,8JAA2B,CAAC;AAE3D,MAAM,MAAM,gBAAgB,GAAG,SAAS,CAAC,KAAK,CAAC,KAAK,GAAG;IACrD;;;;;OAKG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qDAAqD;IACrD,SAAS,CAAC,EAAE,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IAChD;;;;;OAKG;IACH,eAAe,CAAC,EAAE,SAAS,CAAC,UAAU,CAAC,KAAK,CAAC;CAC9C,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,EAC1B,SAAS,EACT,QAAQ,EACR,KAAK,EACL,SAAS,EACT,eAAe,EACf,GAAG,IAAI,EACR,EAAE,gBAAgB,+BA6BlB;AAcD,wBAAgB,QAAQ,CAAC,EAAE,SAAS,EAAE,GAAG,IAAI,EAAE,EAAE,SAAS,CAAC,IAAI,CAAC,KAAK,+BAEpE;AAED,wBAAgB,aAAa,CAAC,EAAE,SAAS,EAAE,GAAG,IAAI,EAAE,EAAE,SAAS,CAAC,SAAS,CAAC,KAAK,+BAI9E;AAED,oFAAoF;AACpF,KAAK,gBAAgB,GAAG;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAa3C;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE,EAAE,SAAS,CAAC,KAAK,CAAC,KAAK,GAAG,gBAAgB,+BAS/F;AAED,sGAAsG;AACtG,wBAAgB,cAAc,CAAC,EAC7B,KAAK,EACL,QAAQ,EACR,GAAG,IAAI,EACR,EAAE,SAAS,CAAC,UAAU,CAAC,KAAK,GAAG,gBAAgB,+BAS/C;AAED,MAAM,MAAM,kBAAkB,GAAG,SAAS,CAAC,SAAS,CAAC,KAAK,GAAG;IAC3D,gCAAgC;IAChC,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB,CAAC;AAEF;;;GAGG;AACH,wBAAgB,aAAa,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,IAAI,EAAE,EAAE,kBAAkB,+BAY5F"}
1
+ {"version":3,"file":"menu.d.ts","sourceRoot":"","sources":["../../src/ui/menu.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,IAAI,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAavC,eAAO,MAAM,IAAI,uBAAiB,CAAC;AACnC,eAAO,MAAM,WAAW,mBAAoB,CAAC;AAC7C,eAAO,MAAM,UAAU,yJAAmB,CAAC;AAC3C,eAAO,MAAM,cAAc,sJAAuB,CAAC;AACnD,eAAO,MAAM,SAAS,wJAAkB,CAAC;AACzC,eAAO,MAAM,YAAY,2JAAqB,CAAC;AAC/C,eAAO,MAAM,SAAS,wJAAkB,CAAC;AACzC,eAAO,MAAM,YAAY,oJAAqB,CAAC;AAC/C,eAAO,MAAM,gBAAgB,4JAAyB,CAAC;AACvD,eAAO,MAAM,yBAAyB,yKAAkC,CAAC;AACzE,eAAO,MAAM,sBAAsB,sKAA+B,CAAC;AACnE,eAAO,MAAM,eAAe,8BAAwB,CAAC;AACrD,eAAO,MAAM,kBAAkB,8JAA2B,CAAC;AAE3D,MAAM,MAAM,gBAAgB,GAAG,SAAS,CAAC,KAAK,CAAC,KAAK,GAAG;IACrD;;;;;OAKG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qDAAqD;IACrD,SAAS,CAAC,EAAE,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IAChD;;;;;OAKG;IACH,eAAe,CAAC,EAAE,SAAS,CAAC,UAAU,CAAC,KAAK,CAAC;CAC9C,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,EAC1B,SAAS,EACT,QAAQ,EACR,KAAK,EACL,SAAS,EACT,eAAe,EACf,GAAG,IAAI,EACR,EAAE,gBAAgB,+BA6BlB;AAcD,wBAAgB,QAAQ,CAAC,EAAE,SAAS,EAAE,GAAG,IAAI,EAAE,EAAE,SAAS,CAAC,IAAI,CAAC,KAAK,+BAEpE;AAED,wBAAgB,aAAa,CAAC,EAAE,SAAS,EAAE,GAAG,IAAI,EAAE,EAAE,SAAS,CAAC,SAAS,CAAC,KAAK,+BAI9E;AAED,oFAAoF;AACpF,KAAK,gBAAgB,GAAG;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAa3C;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE,EAAE,SAAS,CAAC,KAAK,CAAC,KAAK,GAAG,gBAAgB,+BAS/F;AAED,sGAAsG;AACtG,wBAAgB,cAAc,CAAC,EAC7B,KAAK,EACL,QAAQ,EACR,GAAG,IAAI,EACR,EAAE,SAAS,CAAC,UAAU,CAAC,KAAK,GAAG,gBAAgB,+BAS/C;AAED,MAAM,MAAM,kBAAkB,GAAG,SAAS,CAAC,SAAS,CAAC,KAAK,GAAG;IAC3D,gCAAgC;IAChC,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB,CAAC;AAEF;;;GAGG;AACH,wBAAgB,aAAa,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,IAAI,EAAE,EAAE,kBAAkB,+BAY5F"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gusnips/react",
3
- "version": "0.9.25",
3
+ "version": "0.9.26",
4
4
  "description": "The headless runtime under a Vite + React SPA: typed fetch client with single-flight refresh, auth store, query defaults, route guards, error boundary, stale-tab recovery, i18n bootstrap.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -41,6 +41,10 @@
41
41
  "./theme": {
42
42
  "types": "./dist/theme.d.ts",
43
43
  "default": "./dist/theme.js"
44
+ },
45
+ "./commands": {
46
+ "types": "./dist/commands.d.ts",
47
+ "default": "./dist/commands.js"
44
48
  }
45
49
  },
46
50
  "types": "./dist/index.d.ts",