@wzrhine/react 0.0.0-stage → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +99 -0
- package/LICENSE +21 -0
- package/README.md +37 -3
- package/dist/advanced.css +398 -0
- package/dist/archive.css +704 -0
- package/dist/command.css +671 -0
- package/dist/components/Accordion.d.ts +82 -0
- package/dist/components/Accordion.d.ts.map +1 -0
- package/dist/components/Accordion.js +19 -0
- package/dist/components/Accordion.js.map +1 -0
- package/dist/components/Alert.d.ts +63 -0
- package/dist/components/Alert.d.ts.map +1 -0
- package/dist/components/Alert.js +29 -0
- package/dist/components/Alert.js.map +1 -0
- package/dist/components/AlertDialog.d.ts +49 -0
- package/dist/components/AlertDialog.d.ts.map +1 -0
- package/dist/components/AlertDialog.js +122 -0
- package/dist/components/AlertDialog.js.map +1 -0
- package/dist/components/ArchiveCard.d.ts +58 -0
- package/dist/components/ArchiveCard.d.ts.map +1 -0
- package/dist/components/ArchiveCard.js +40 -0
- package/dist/components/ArchiveCard.js.map +1 -0
- package/dist/components/Badge.d.ts +17 -0
- package/dist/components/Badge.d.ts.map +1 -0
- package/dist/components/Badge.js +16 -0
- package/dist/components/Badge.js.map +1 -0
- package/dist/components/Breadcrumb.d.ts +48 -0
- package/dist/components/Breadcrumb.d.ts.map +1 -0
- package/dist/components/Breadcrumb.js +55 -0
- package/dist/components/Breadcrumb.js.map +1 -0
- package/dist/components/Button.d.ts +33 -0
- package/dist/components/Button.d.ts.map +1 -0
- package/dist/components/Button.js +24 -0
- package/dist/components/Button.js.map +1 -0
- package/dist/components/Checkbox.d.ts +81 -0
- package/dist/components/Checkbox.d.ts.map +1 -0
- package/dist/components/Checkbox.js +34 -0
- package/dist/components/Checkbox.js.map +1 -0
- package/dist/components/Collapsible.d.ts +47 -0
- package/dist/components/Collapsible.d.ts.map +1 -0
- package/dist/components/Collapsible.js +12 -0
- package/dist/components/Collapsible.js.map +1 -0
- package/dist/components/Combobox.d.ts +74 -0
- package/dist/components/Combobox.d.ts.map +1 -0
- package/dist/components/Combobox.js +61 -0
- package/dist/components/Combobox.js.map +1 -0
- package/dist/components/CommandPalette.d.ts +77 -0
- package/dist/components/CommandPalette.d.ts.map +1 -0
- package/dist/components/CommandPalette.js +150 -0
- package/dist/components/CommandPalette.js.map +1 -0
- package/dist/components/ContextMenu.d.ts +31 -0
- package/dist/components/ContextMenu.d.ts.map +1 -0
- package/dist/components/ContextMenu.js +25 -0
- package/dist/components/ContextMenu.js.map +1 -0
- package/dist/components/DataTable.d.ts +83 -0
- package/dist/components/DataTable.d.ts.map +1 -0
- package/dist/components/DataTable.js +97 -0
- package/dist/components/DataTable.js.map +1 -0
- package/dist/components/Dialog.d.ts +49 -0
- package/dist/components/Dialog.d.ts.map +1 -0
- package/dist/components/Dialog.js +48 -0
- package/dist/components/Dialog.js.map +1 -0
- package/dist/components/Drawer.d.ts +56 -0
- package/dist/components/Drawer.d.ts.map +1 -0
- package/dist/components/Drawer.js +92 -0
- package/dist/components/Drawer.js.map +1 -0
- package/dist/components/EmptyState.d.ts +39 -0
- package/dist/components/EmptyState.d.ts.map +1 -0
- package/dist/components/EmptyState.js +19 -0
- package/dist/components/EmptyState.js.map +1 -0
- package/dist/components/Field.d.ts +37 -0
- package/dist/components/Field.d.ts.map +1 -0
- package/dist/components/Field.js +12 -0
- package/dist/components/Field.js.map +1 -0
- package/dist/components/Fieldset.d.ts +25 -0
- package/dist/components/Fieldset.d.ts.map +1 -0
- package/dist/components/Fieldset.js +17 -0
- package/dist/components/Fieldset.js.map +1 -0
- package/dist/components/FileDropZone.d.ts +60 -0
- package/dist/components/FileDropZone.d.ts.map +1 -0
- package/dist/components/FileDropZone.js +121 -0
- package/dist/components/FileDropZone.js.map +1 -0
- package/dist/components/Form.d.ts +22 -0
- package/dist/components/Form.d.ts.map +1 -0
- package/dist/components/Form.js +20 -0
- package/dist/components/Form.js.map +1 -0
- package/dist/components/Icon.d.ts +25 -0
- package/dist/components/Icon.d.ts.map +1 -0
- package/dist/components/Icon.js +38 -0
- package/dist/components/Icon.js.map +1 -0
- package/dist/components/IconButton.d.ts +25 -0
- package/dist/components/IconButton.d.ts.map +1 -0
- package/dist/components/IconButton.js +14 -0
- package/dist/components/IconButton.js.map +1 -0
- package/dist/components/Input.d.ts +24 -0
- package/dist/components/Input.d.ts.map +1 -0
- package/dist/components/Input.js +15 -0
- package/dist/components/Input.js.map +1 -0
- package/dist/components/Menu.d.ts +66 -0
- package/dist/components/Menu.d.ts.map +1 -0
- package/dist/components/Menu.js +34 -0
- package/dist/components/Menu.js.map +1 -0
- package/dist/components/MetadataList.d.ts +51 -0
- package/dist/components/MetadataList.d.ts.map +1 -0
- package/dist/components/MetadataList.js +25 -0
- package/dist/components/MetadataList.js.map +1 -0
- package/dist/components/NumberField.d.ts +54 -0
- package/dist/components/NumberField.d.ts.map +1 -0
- package/dist/components/NumberField.js +27 -0
- package/dist/components/NumberField.js.map +1 -0
- package/dist/components/Pagination.d.ts +40 -0
- package/dist/components/Pagination.d.ts.map +1 -0
- package/dist/components/Pagination.js +64 -0
- package/dist/components/Pagination.js.map +1 -0
- package/dist/components/Popover.d.ts +49 -0
- package/dist/components/Popover.d.ts.map +1 -0
- package/dist/components/Popover.js +14 -0
- package/dist/components/Popover.js.map +1 -0
- package/dist/components/Progress.d.ts +57 -0
- package/dist/components/Progress.d.ts.map +1 -0
- package/dist/components/Progress.js +31 -0
- package/dist/components/Progress.js.map +1 -0
- package/dist/components/Radio.d.ts +68 -0
- package/dist/components/Radio.d.ts.map +1 -0
- package/dist/components/Radio.js +18 -0
- package/dist/components/Radio.js.map +1 -0
- package/dist/components/RecordHeader.d.ts +53 -0
- package/dist/components/RecordHeader.d.ts.map +1 -0
- package/dist/components/RecordHeader.js +19 -0
- package/dist/components/RecordHeader.js.map +1 -0
- package/dist/components/ResizeHandle.d.ts +32 -0
- package/dist/components/ResizeHandle.d.ts.map +1 -0
- package/dist/components/ResizeHandle.js +33 -0
- package/dist/components/ResizeHandle.js.map +1 -0
- package/dist/components/ScrollArea.d.ts +60 -0
- package/dist/components/ScrollArea.d.ts.map +1 -0
- package/dist/components/ScrollArea.js +63 -0
- package/dist/components/ScrollArea.js.map +1 -0
- package/dist/components/Select.d.ts +39 -0
- package/dist/components/Select.d.ts.map +1 -0
- package/dist/components/Select.js +24 -0
- package/dist/components/Select.js.map +1 -0
- package/dist/components/Separator.d.ts +26 -0
- package/dist/components/Separator.d.ts.map +1 -0
- package/dist/components/Separator.js +22 -0
- package/dist/components/Separator.js.map +1 -0
- package/dist/components/Skeleton.d.ts +31 -0
- package/dist/components/Skeleton.d.ts.map +1 -0
- package/dist/components/Skeleton.js +17 -0
- package/dist/components/Skeleton.js.map +1 -0
- package/dist/components/Slider.d.ts +65 -0
- package/dist/components/Slider.d.ts.map +1 -0
- package/dist/components/Slider.js +30 -0
- package/dist/components/Slider.js.map +1 -0
- package/dist/components/Spinner.d.ts +23 -0
- package/dist/components/Spinner.d.ts.map +1 -0
- package/dist/components/Spinner.js +13 -0
- package/dist/components/Spinner.js.map +1 -0
- package/dist/components/SplitButton.d.ts +59 -0
- package/dist/components/SplitButton.d.ts.map +1 -0
- package/dist/components/SplitButton.js +30 -0
- package/dist/components/SplitButton.js.map +1 -0
- package/dist/components/Stat.d.ts +53 -0
- package/dist/components/Stat.d.ts.map +1 -0
- package/dist/components/Stat.js +23 -0
- package/dist/components/Stat.js.map +1 -0
- package/dist/components/StatusBadge.d.ts +19 -0
- package/dist/components/StatusBadge.d.ts.map +1 -0
- package/dist/components/StatusBadge.js +8 -0
- package/dist/components/StatusBadge.js.map +1 -0
- package/dist/components/StatusIndicator.d.ts +29 -0
- package/dist/components/StatusIndicator.d.ts.map +1 -0
- package/dist/components/StatusIndicator.js +8 -0
- package/dist/components/StatusIndicator.js.map +1 -0
- package/dist/components/Surface.d.ts +29 -0
- package/dist/components/Surface.d.ts.map +1 -0
- package/dist/components/Surface.js +8 -0
- package/dist/components/Surface.js.map +1 -0
- package/dist/components/Switch.d.ts +22 -0
- package/dist/components/Switch.d.ts.map +1 -0
- package/dist/components/Switch.js +11 -0
- package/dist/components/Switch.js.map +1 -0
- package/dist/components/Tabs.d.ts +45 -0
- package/dist/components/Tabs.d.ts.map +1 -0
- package/dist/components/Tabs.js +49 -0
- package/dist/components/Tabs.js.map +1 -0
- package/dist/components/Text.d.ts +33 -0
- package/dist/components/Text.d.ts.map +1 -0
- package/dist/components/Text.js +21 -0
- package/dist/components/Text.js.map +1 -0
- package/dist/components/Textarea.d.ts +54 -0
- package/dist/components/Textarea.d.ts.map +1 -0
- package/dist/components/Textarea.js +31 -0
- package/dist/components/Textarea.js.map +1 -0
- package/dist/components/Timeline.d.ts +35 -0
- package/dist/components/Timeline.d.ts.map +1 -0
- package/dist/components/Timeline.js +13 -0
- package/dist/components/Timeline.js.map +1 -0
- package/dist/components/Toast.d.ts +67 -0
- package/dist/components/Toast.d.ts.map +1 -0
- package/dist/components/Toast.js +94 -0
- package/dist/components/Toast.js.map +1 -0
- package/dist/components/Tooltip.d.ts +26 -0
- package/dist/components/Tooltip.d.ts.map +1 -0
- package/dist/components/Tooltip.js +15 -0
- package/dist/components/Tooltip.js.map +1 -0
- package/dist/components/Tree.d.ts +28 -0
- package/dist/components/Tree.d.ts.map +1 -0
- package/dist/components/Tree.js +129 -0
- package/dist/components/Tree.js.map +1 -0
- package/dist/components/VisuallyHidden.d.ts +17 -0
- package/dist/components/VisuallyHidden.d.ts.map +1 -0
- package/dist/components/VisuallyHidden.js +12 -0
- package/dist/components/VisuallyHidden.js.map +1 -0
- package/dist/components/Workbench.d.ts +31 -0
- package/dist/components/Workbench.d.ts.map +1 -0
- package/dist/components/Workbench.js +71 -0
- package/dist/components/Workbench.js.map +1 -0
- package/dist/components/fieldParts.d.ts +17 -0
- package/dist/components/fieldParts.d.ts.map +1 -0
- package/dist/components/fieldParts.js +22 -0
- package/dist/components/fieldParts.js.map +1 -0
- package/dist/components/meter-utils.d.ts +15 -0
- package/dist/components/meter-utils.d.ts.map +1 -0
- package/dist/components/meter-utils.js +15 -0
- package/dist/components/meter-utils.js.map +1 -0
- package/dist/components/navigation.d.ts +38 -0
- package/dist/components/navigation.d.ts.map +1 -0
- package/dist/components/navigation.js +96 -0
- package/dist/components/navigation.js.map +1 -0
- package/dist/components/pagination-utils.d.ts +10 -0
- package/dist/components/pagination-utils.d.ts.map +1 -0
- package/dist/components/pagination-utils.js +36 -0
- package/dist/components/pagination-utils.js.map +1 -0
- package/dist/components.css +678 -0
- package/dist/data.css +600 -0
- package/dist/disclosure.css +93 -0
- package/dist/drawer.css +226 -0
- package/dist/feedback.css +454 -0
- package/dist/forms.css +533 -0
- package/dist/index.d.ts +129 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +67 -0
- package/dist/index.js.map +1 -0
- package/dist/motion/lifecycle.d.ts +44 -0
- package/dist/motion/lifecycle.d.ts.map +1 -0
- package/dist/motion/lifecycle.js +73 -0
- package/dist/motion/lifecycle.js.map +1 -0
- package/dist/motion/presence.d.ts +69 -0
- package/dist/motion/presence.d.ts.map +1 -0
- package/dist/motion/presence.js +103 -0
- package/dist/motion/presence.js.map +1 -0
- package/dist/motion/presets.d.ts +63 -0
- package/dist/motion/presets.d.ts.map +1 -0
- package/dist/motion/presets.js +30 -0
- package/dist/motion/presets.js.map +1 -0
- package/dist/motion/resolve.d.ts +31 -0
- package/dist/motion/resolve.d.ts.map +1 -0
- package/dist/motion/resolve.js +40 -0
- package/dist/motion/resolve.js.map +1 -0
- package/dist/motion/useRhineMotion.d.ts +19 -0
- package/dist/motion/useRhineMotion.d.ts.map +1 -0
- package/dist/motion/useRhineMotion.js +19 -0
- package/dist/motion/useRhineMotion.js.map +1 -0
- package/dist/motion/visibility.d.ts +6 -0
- package/dist/motion/visibility.d.ts.map +1 -0
- package/dist/motion/visibility.js +31 -0
- package/dist/motion/visibility.js.map +1 -0
- package/dist/overlays.css +465 -0
- package/dist/provider/RhineProvider.d.ts +65 -0
- package/dist/provider/RhineProvider.d.ts.map +1 -0
- package/dist/provider/RhineProvider.js +26 -0
- package/dist/provider/RhineProvider.js.map +1 -0
- package/dist/provider/messages.d.ts +209 -0
- package/dist/provider/messages.d.ts.map +1 -0
- package/dist/provider/messages.js +168 -0
- package/dist/provider/messages.js.map +1 -0
- package/dist/provider/portal.d.ts +17 -0
- package/dist/provider/portal.d.ts.map +1 -0
- package/dist/provider/portal.js +20 -0
- package/dist/provider/portal.js.map +1 -0
- package/dist/reset.css +45 -0
- package/dist/split.css +159 -0
- package/dist/status.css +353 -0
- package/dist/utils/cx.d.ts +2 -0
- package/dist/utils/cx.d.ts.map +1 -0
- package/dist/utils/cx.js +4 -0
- package/dist/utils/cx.js.map +1 -0
- package/package.json +67 -3
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Modal command search (ADR-0010 §2): Base UI Dialog (focus trap, Escape, scroll lock, focus
|
|
4
|
+
* return to whatever was focused before opening) around an inline, always-open Base UI
|
|
5
|
+
* Autocomplete list. Focus stays in the input; ↑ / ↓ move the active option through
|
|
6
|
+
* `aria-activedescendant`, Enter runs it, Esc closes the dialog. The first match is always
|
|
7
|
+
* highlighted. Disabled commands stay visible with their reason and cannot run.
|
|
8
|
+
* Enter/exit motion follows Dialog (motion/react: backdrop fast, panel 280ms + 8px rise;
|
|
9
|
+
* opacity only under reduced motion).
|
|
10
|
+
*
|
|
11
|
+
* Async / server-side search: control the query with `query` + `onQueryChange`, pass
|
|
12
|
+
* `filter={null}` so the palette shows `commands` exactly as given, and set `loading` while a
|
|
13
|
+
* request is in flight (a polite status row with a Spinner; the list is `aria-busy`; the empty
|
|
14
|
+
* text waits until loading ends). The palette resets an uncontrolled query on open; a controlled
|
|
15
|
+
* one is reset through `onQueryChange('')`, so a host that mirrors the value behaves the same.
|
|
16
|
+
*
|
|
17
|
+
* <CommandPalette hotkey="mod+k" commands={commands} onSelect={(c) => run(c.id)} />
|
|
18
|
+
*/
|
|
19
|
+
export interface CommandItem {
|
|
20
|
+
id: string;
|
|
21
|
+
label: string;
|
|
22
|
+
description?: string;
|
|
23
|
+
/** Group heading; commands sharing it are listed together in first-seen order. */
|
|
24
|
+
group?: string;
|
|
25
|
+
/** Visual shortcut hint such as "Ctrl E" (hidden from assistive tech, like MenuItem). Wire it yourself. */
|
|
26
|
+
shortcut?: string;
|
|
27
|
+
/** Extra search terms (synonyms, English names). */
|
|
28
|
+
keywords?: readonly string[];
|
|
29
|
+
disabled?: boolean;
|
|
30
|
+
/** Shown under a disabled command, e.g. 「需要编辑权限」. */
|
|
31
|
+
disabledReason?: string;
|
|
32
|
+
/** Decorative leading icon (hidden from assistive tech). */
|
|
33
|
+
icon?: React.ReactNode;
|
|
34
|
+
/** Secondary trailing text such as a path or 「3 分钟前」; part of the option's name. */
|
|
35
|
+
meta?: React.ReactNode;
|
|
36
|
+
}
|
|
37
|
+
/** Local match predicate of CommandPalette. */
|
|
38
|
+
export type CommandFilter = (command: CommandItem, query: string) => boolean;
|
|
39
|
+
export type CommandPaletteProps = {
|
|
40
|
+
commands: readonly CommandItem[];
|
|
41
|
+
/** Runs a command. Return `false` to keep the palette open. */
|
|
42
|
+
onSelect: (command: CommandItem) => boolean | void;
|
|
43
|
+
open?: boolean;
|
|
44
|
+
defaultOpen?: boolean;
|
|
45
|
+
onOpenChange?: (open: boolean) => void;
|
|
46
|
+
/** Element that opens the palette (usually a Button). */
|
|
47
|
+
trigger?: React.ReactElement<Record<string, unknown>>;
|
|
48
|
+
/**
|
|
49
|
+
* Global shortcut that toggles the palette, e.g. `mod+k` (`mod` = ⌘ on Apple platforms, Ctrl
|
|
50
|
+
* elsewhere). Combine with `ctrl`, `meta`, `alt`, `shift`. Ignored during IME composition.
|
|
51
|
+
*/
|
|
52
|
+
hotkey?: string;
|
|
53
|
+
/** Accessible name of the dialog (visually hidden; default from messages). */
|
|
54
|
+
title?: string;
|
|
55
|
+
placeholder?: string;
|
|
56
|
+
emptyText?: React.ReactNode;
|
|
57
|
+
/** Footer keyboard hint (default from messages); `null` hides it. */
|
|
58
|
+
hint?: React.ReactNode | null;
|
|
59
|
+
/**
|
|
60
|
+
* Custom match. Default: every whitespace-separated term appears in label, keywords, group or
|
|
61
|
+
* description. `null` turns local filtering off (results already filtered by the host / server).
|
|
62
|
+
*/
|
|
63
|
+
filter?: CommandFilter | null;
|
|
64
|
+
/** Controlled search text. */
|
|
65
|
+
query?: string;
|
|
66
|
+
/** Every change of the search text (typing, clearing, reset on open). */
|
|
67
|
+
onQueryChange?: (query: string) => void;
|
|
68
|
+
/** A search is in flight: shows the status row and marks the list busy. */
|
|
69
|
+
loading?: boolean;
|
|
70
|
+
/** Status text while `loading` (default from messages). */
|
|
71
|
+
loadingText?: React.ReactNode;
|
|
72
|
+
className?: string;
|
|
73
|
+
};
|
|
74
|
+
/** Parses `mod+k` style hotkeys into a predicate over keyboard events. */
|
|
75
|
+
export declare function matchHotkey(hotkey: string, event: KeyboardEvent, apple?: boolean): boolean;
|
|
76
|
+
export declare function CommandPalette({ commands, onSelect, open: openProp, defaultOpen, onOpenChange, trigger, hotkey, title, placeholder, emptyText, hint, filter, query: queryProp, onQueryChange, loading, loadingText, className, }: CommandPaletteProps): React.JSX.Element;
|
|
77
|
+
//# sourceMappingURL=CommandPalette.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CommandPalette.d.ts","sourceRoot":"","sources":["../../src/components/CommandPalette.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAU/B;;;;;;;;;;;;;;;;GAgBG;AAEH,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kFAAkF;IAClF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2GAA2G;IAC3G,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oDAAoD;IACpD,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,qDAAqD;IACrD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,4DAA4D;IAC5D,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,oFAAoF;IACpF,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CACxB;AAED,+CAA+C;AAC/C,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;AAE7E,MAAM,MAAM,mBAAmB,GAAG;IAChC,QAAQ,EAAE,SAAS,WAAW,EAAE,CAAC;IACjC,+DAA+D;IAC/D,QAAQ,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,OAAO,GAAG,IAAI,CAAC;IACnD,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,yDAAyD;IACzD,OAAO,CAAC,EAAE,KAAK,CAAC,YAAY,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACtD;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8EAA8E;IAC9E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC5B,qEAAqE;IACrE,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC;IAC9B;;;OAGG;IACH,MAAM,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IAC9B,8BAA8B;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yEAAyE;IACzE,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,2EAA2E;IAC3E,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,2DAA2D;IAC3D,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AA2CF,0EAA0E;AAC1E,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,UAAoB,GAAG,OAAO,CAmBpG;AAaD,wBAAgB,cAAc,CAAC,EAC7B,QAAQ,EACR,QAAQ,EACR,IAAI,EAAE,QAAQ,EACd,WAAmB,EACnB,YAAY,EACZ,OAAO,EACP,MAAM,EACN,KAAK,EACL,WAAW,EACX,SAAS,EACT,IAAI,EACJ,MAAsB,EACtB,KAAK,EAAE,SAAS,EAChB,aAAa,EACb,OAAe,EACf,WAAW,EACX,SAAS,GACV,EAAE,mBAAmB,qBAuLrB"}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { Autocomplete } from '@base-ui/react/autocomplete';
|
|
5
|
+
import { Dialog as BaseDialog } from '@base-ui/react/dialog';
|
|
6
|
+
import { AnimatePresence, motion } from 'motion/react';
|
|
7
|
+
import { useRhineMotion } from '../motion/useRhineMotion.js';
|
|
8
|
+
import { useRhineMessages } from '../provider/messages.js';
|
|
9
|
+
import { usePortalContainer } from '../provider/portal.js';
|
|
10
|
+
import { cx } from '../utils/cx.js';
|
|
11
|
+
import { Spinner } from './Spinner.js';
|
|
12
|
+
const normalize = (text) => text.toLocaleLowerCase();
|
|
13
|
+
const terms = (query) => normalize(query).split(/\s+/).filter(Boolean);
|
|
14
|
+
function defaultFilter(command, query) {
|
|
15
|
+
const haystack = normalize([command.label, command.description ?? '', command.group ?? '', ...(command.keywords ?? [])].join(' '));
|
|
16
|
+
return terms(query).every((term) => haystack.includes(term));
|
|
17
|
+
}
|
|
18
|
+
/** Label split into plain and matched parts; matched parts render as <mark>. */
|
|
19
|
+
function highlight(label, query) {
|
|
20
|
+
const words = terms(query);
|
|
21
|
+
if (words.length === 0)
|
|
22
|
+
return label;
|
|
23
|
+
const lower = normalize(label);
|
|
24
|
+
const marks = new Array(label.length).fill(false);
|
|
25
|
+
for (const word of words) {
|
|
26
|
+
let from = lower.indexOf(word);
|
|
27
|
+
while (from !== -1) {
|
|
28
|
+
for (let i = from; i < from + word.length; i += 1)
|
|
29
|
+
marks[i] = true;
|
|
30
|
+
from = lower.indexOf(word, from + word.length);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
const parts = [];
|
|
34
|
+
let start = 0;
|
|
35
|
+
for (let i = 1; i <= label.length; i += 1) {
|
|
36
|
+
if (i === label.length || marks[i] !== marks[start]) {
|
|
37
|
+
const text = label.slice(start, i);
|
|
38
|
+
parts.push(marks[start] ? _jsx("mark", { className: "rl-command__mark", children: text }, start) : text);
|
|
39
|
+
start = i;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return parts;
|
|
43
|
+
}
|
|
44
|
+
function isApplePlatform() {
|
|
45
|
+
if (typeof navigator === 'undefined')
|
|
46
|
+
return false;
|
|
47
|
+
const platform = navigator.userAgentData?.platform ?? navigator.platform ?? '';
|
|
48
|
+
return /mac|iphone|ipad|ipod/i.test(platform);
|
|
49
|
+
}
|
|
50
|
+
/** Parses `mod+k` style hotkeys into a predicate over keyboard events. */
|
|
51
|
+
export function matchHotkey(hotkey, event, apple = isApplePlatform()) {
|
|
52
|
+
const parts = hotkey.toLowerCase().split('+').map((p) => p.trim()).filter(Boolean);
|
|
53
|
+
const key = parts.pop();
|
|
54
|
+
if (!key)
|
|
55
|
+
return false;
|
|
56
|
+
const want = { ctrl: false, meta: false, alt: false, shift: false };
|
|
57
|
+
for (const part of parts) {
|
|
58
|
+
if (part === 'mod')
|
|
59
|
+
want[apple ? 'meta' : 'ctrl'] = true;
|
|
60
|
+
else if (part === 'ctrl' || part === 'control')
|
|
61
|
+
want.ctrl = true;
|
|
62
|
+
else if (part === 'meta' || part === 'cmd')
|
|
63
|
+
want.meta = true;
|
|
64
|
+
else if (part === 'alt' || part === 'option')
|
|
65
|
+
want.alt = true;
|
|
66
|
+
else if (part === 'shift')
|
|
67
|
+
want.shift = true;
|
|
68
|
+
}
|
|
69
|
+
return (event.key.toLowerCase() === key &&
|
|
70
|
+
event.ctrlKey === want.ctrl &&
|
|
71
|
+
event.metaKey === want.meta &&
|
|
72
|
+
event.altKey === want.alt &&
|
|
73
|
+
event.shiftKey === want.shift);
|
|
74
|
+
}
|
|
75
|
+
function SearchIcon() {
|
|
76
|
+
return (_jsxs("svg", { viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.75", "aria-hidden": "true", focusable: "false", children: [_jsx("circle", { cx: "7", cy: "7", r: "4.75" }), _jsx("path", { d: "m10.5 10.5 3.5 3.5", strokeLinecap: "round" })] }));
|
|
77
|
+
}
|
|
78
|
+
const offset = 8;
|
|
79
|
+
export function CommandPalette({ commands, onSelect, open: openProp, defaultOpen = false, onOpenChange, trigger, hotkey, title, placeholder, emptyText, hint, filter = defaultFilter, query: queryProp, onQueryChange, loading = false, loadingText, className, }) {
|
|
80
|
+
const messages = useRhineMessages().commandPalette;
|
|
81
|
+
const container = usePortalContainer();
|
|
82
|
+
const motionPrefs = useRhineMotion();
|
|
83
|
+
const rise = motionPrefs.reduced ? 0 : offset;
|
|
84
|
+
const [uncontrolled, setUncontrolled] = React.useState(defaultOpen);
|
|
85
|
+
const controlled = openProp !== undefined;
|
|
86
|
+
const open = controlled ? openProp : uncontrolled;
|
|
87
|
+
const [innerQuery, setInnerQuery] = React.useState('');
|
|
88
|
+
const query = queryProp ?? innerQuery;
|
|
89
|
+
const latestQuery = React.useRef(onQueryChange);
|
|
90
|
+
latestQuery.current = onQueryChange;
|
|
91
|
+
const setQuery = React.useCallback((next) => {
|
|
92
|
+
setInnerQuery(next);
|
|
93
|
+
latestQuery.current?.(next);
|
|
94
|
+
}, []);
|
|
95
|
+
const inputRef = React.useRef(null);
|
|
96
|
+
const hintId = React.useId();
|
|
97
|
+
const setOpen = React.useCallback((next) => {
|
|
98
|
+
if (next && latest.current.query !== '')
|
|
99
|
+
setQuery('');
|
|
100
|
+
if (!controlled)
|
|
101
|
+
setUncontrolled(next);
|
|
102
|
+
onOpenChange?.(next);
|
|
103
|
+
}, [controlled, onOpenChange, setQuery]);
|
|
104
|
+
// Latest values for the document listener without re-subscribing on every render.
|
|
105
|
+
const latest = React.useRef({ open, query, setOpen: () => undefined });
|
|
106
|
+
latest.current = { open, query, setOpen };
|
|
107
|
+
React.useEffect(() => {
|
|
108
|
+
if (!hotkey)
|
|
109
|
+
return undefined;
|
|
110
|
+
const onKeyDown = (event) => {
|
|
111
|
+
if (event.isComposing || event.keyCode === 229 || event.repeat)
|
|
112
|
+
return;
|
|
113
|
+
if (!matchHotkey(hotkey, event))
|
|
114
|
+
return;
|
|
115
|
+
event.preventDefault();
|
|
116
|
+
latest.current.setOpen(!latest.current.open);
|
|
117
|
+
};
|
|
118
|
+
document.addEventListener('keydown', onKeyDown);
|
|
119
|
+
return () => document.removeEventListener('keydown', onKeyDown);
|
|
120
|
+
}, [hotkey]);
|
|
121
|
+
const groups = React.useMemo(() => {
|
|
122
|
+
const trimmed = query.trim();
|
|
123
|
+
const map = new Map();
|
|
124
|
+
for (const command of commands) {
|
|
125
|
+
if (filter !== null && trimmed !== '' && !filter(command, trimmed))
|
|
126
|
+
continue;
|
|
127
|
+
const key = command.group ?? '';
|
|
128
|
+
let group = map.get(key);
|
|
129
|
+
if (!group) {
|
|
130
|
+
group = { value: key, items: [] };
|
|
131
|
+
map.set(key, group);
|
|
132
|
+
}
|
|
133
|
+
group.items.push(command);
|
|
134
|
+
}
|
|
135
|
+
return [...map.values()];
|
|
136
|
+
}, [commands, filter, query]);
|
|
137
|
+
const run = (command) => {
|
|
138
|
+
if (command.disabled)
|
|
139
|
+
return;
|
|
140
|
+
if (onSelect(command) !== false)
|
|
141
|
+
setOpen(false);
|
|
142
|
+
};
|
|
143
|
+
const footer = hint === undefined ? messages.hint : hint;
|
|
144
|
+
return (_jsxs(BaseDialog.Root, { open: open, onOpenChange: (next) => setOpen(next), children: [trigger && _jsx(BaseDialog.Trigger, { render: trigger }), _jsx(AnimatePresence, { children: open && (_jsxs(BaseDialog.Portal, { keepMounted: true, container: container, children: [_jsx(BaseDialog.Backdrop, { className: "rl-dialog__backdrop", render: _jsx(motion.div, { initial: { opacity: 0 }, animate: { opacity: 1 }, exit: { opacity: 0 }, transition: motionPrefs.get('fast') }) }), _jsxs(BaseDialog.Popup, { className: cx('rl-command', className), "data-slot": "command-palette", initialFocus: inputRef, render: _jsx(motion.div, { initial: { opacity: 0, y: rise }, animate: { opacity: 1, y: 0 }, exit: { opacity: 0, y: rise }, transition: motionPrefs.get('panel') }), children: [_jsx(BaseDialog.Title, { className: "rl-visually-hidden", children: title ?? messages.title }), _jsxs(Autocomplete.Root, { open: true, inline: true, items: groups, filter: null, autoHighlight: "always", keepHighlight: true, value: query, onValueChange: (next, details) => {
|
|
145
|
+
// Selecting fills the input by default; a palette keeps the typed query instead.
|
|
146
|
+
if (details.reason !== 'item-press')
|
|
147
|
+
setQuery(next);
|
|
148
|
+
}, itemToStringValue: (command) => command.label, children: [_jsxs("div", { className: "rl-command__search", children: [_jsx("span", { className: "rl-command__search-icon", "aria-hidden": "true", children: _jsx(SearchIcon, {}) }), _jsx(Autocomplete.Input, { ref: inputRef, className: "rl-command__input", "aria-label": messages.inputLabel, "aria-describedby": footer != null ? hintId : undefined, placeholder: placeholder ?? messages.placeholder })] }), _jsx(BaseDialog.Close, { className: "rl-visually-hidden", children: messages.close }), _jsxs("div", { className: "rl-command__body", children: [_jsx(Autocomplete.Status, { className: "rl-command__status", children: loading ? (_jsxs(_Fragment, { children: [_jsx(Spinner, { size: "sm" }), _jsx("span", { children: loadingText ?? messages.loading })] })) : null }), _jsx(Autocomplete.Empty, { className: "rl-command__empty", children: loading ? null : (emptyText ?? messages.empty) }), _jsx(Autocomplete.List, { className: "rl-command__list", "aria-busy": loading || undefined, children: (group) => (_jsxs(Autocomplete.Group, { items: group.items, className: "rl-command__group", children: [group.value !== '' && _jsx(Autocomplete.GroupLabel, { className: "rl-command__group-label", children: group.value }), _jsx(Autocomplete.Collection, { children: (command) => (_jsxs(Autocomplete.Item, { value: command, disabled: command.disabled, className: "rl-command__item", "data-command-id": command.id, "data-icon": command.icon != null || undefined, onClick: () => run(command), children: [command.icon != null && (_jsx("span", { className: "rl-command__icon", "aria-hidden": "true", children: command.icon })), _jsxs("span", { className: "rl-command__text", children: [_jsx("span", { className: "rl-command__label", children: highlight(command.label, query) }), command.description != null && _jsx("span", { className: "rl-command__description", children: command.description }), command.disabled && command.disabledReason != null && (_jsx("span", { className: "rl-command__reason", children: command.disabledReason }))] }), command.meta != null && _jsx("span", { className: "rl-command__meta", children: command.meta }), command.shortcut != null && (_jsx("kbd", { className: "rl-command__shortcut", "aria-hidden": "true", children: command.shortcut }))] }, command.id)) })] }, `g-${group.value}`)) })] }), footer != null && (_jsx("p", { id: hintId, className: "rl-command__hint", children: footer }))] })] })] })) })] }));
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=CommandPalette.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CommandPalette.js","sourceRoot":"","sources":["../../src/components/CommandPalette.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,EAAE,EAAE,MAAM,gBAAgB,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAgFvC,MAAM,SAAS,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,CAAC,iBAAiB,EAAE,CAAC;AAC7D,MAAM,KAAK,GAAG,CAAC,KAAa,EAAE,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;AAE/E,SAAS,aAAa,CAAC,OAAoB,EAAE,KAAa;IACxD,MAAM,QAAQ,GAAG,SAAS,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,WAAW,IAAI,EAAE,EAAE,OAAO,CAAC,KAAK,IAAI,EAAE,EAAE,GAAG,CAAC,OAAO,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACnI,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;AAC/D,CAAC;AAED,gFAAgF;AAChF,SAAS,SAAS,CAAC,KAAa,EAAE,KAAa;IAC7C,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;IAC3B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACrC,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;IAC/B,MAAM,KAAK,GAAG,IAAI,KAAK,CAAU,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC3D,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC/B,OAAO,IAAI,KAAK,CAAC,CAAC,EAAE,CAAC;YACnB,KAAK,IAAI,CAAC,GAAG,IAAI,EAAE,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC;gBAAE,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;YACnE,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;QACjD,CAAC;IACH,CAAC;IACD,MAAM,KAAK,GAAsB,EAAE,CAAC;IACpC,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QAC1C,IAAI,CAAC,KAAK,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;YACpD,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;YACnC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,eAAkB,SAAS,EAAC,kBAAkB,YAAE,IAAI,IAAzC,KAAK,CAA4C,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YAC/F,KAAK,GAAG,CAAC,CAAC;QACZ,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,eAAe;IACtB,IAAI,OAAO,SAAS,KAAK,WAAW;QAAE,OAAO,KAAK,CAAC;IACnD,MAAM,QAAQ,GAAI,SAAmE,CAAC,aAAa,EAAE,QAAQ,IAAI,SAAS,CAAC,QAAQ,IAAI,EAAE,CAAC;IAC1I,OAAO,uBAAuB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;AAChD,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,WAAW,CAAC,MAAc,EAAE,KAAoB,EAAE,KAAK,GAAG,eAAe,EAAE;IACzF,MAAM,KAAK,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACnF,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,EAAE,CAAC;IACxB,IAAI,CAAC,GAAG;QAAE,OAAO,KAAK,CAAC;IACvB,MAAM,IAAI,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;IACpE,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,KAAK,KAAK;YAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;aACpD,IAAI,IAAI,KAAK,MAAM,IAAI,IAAI,KAAK,SAAS;YAAE,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;aAC5D,IAAI,IAAI,KAAK,MAAM,IAAI,IAAI,KAAK,KAAK;YAAE,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;aACxD,IAAI,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,QAAQ;YAAE,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC;aACzD,IAAI,IAAI,KAAK,OAAO;YAAE,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;IAC/C,CAAC;IACD,OAAO,CACL,KAAK,CAAC,GAAG,CAAC,WAAW,EAAE,KAAK,GAAG;QAC/B,KAAK,CAAC,OAAO,KAAK,IAAI,CAAC,IAAI;QAC3B,KAAK,CAAC,OAAO,KAAK,IAAI,CAAC,IAAI;QAC3B,KAAK,CAAC,MAAM,KAAK,IAAI,CAAC,GAAG;QACzB,KAAK,CAAC,QAAQ,KAAK,IAAI,CAAC,KAAK,CAC9B,CAAC;AACJ,CAAC;AAED,SAAS,UAAU;IACjB,OAAO,CACL,eAAK,OAAO,EAAC,WAAW,EAAC,IAAI,EAAC,MAAM,EAAC,MAAM,EAAC,cAAc,EAAC,WAAW,EAAC,MAAM,iBAAa,MAAM,EAAC,SAAS,EAAC,OAAO,aAChH,iBAAQ,EAAE,EAAC,GAAG,EAAC,EAAE,EAAC,GAAG,EAAC,CAAC,EAAC,MAAM,GAAG,EACjC,eAAM,CAAC,EAAC,oBAAoB,EAAC,aAAa,EAAC,OAAO,GAAG,IACjD,CACP,CAAC;AACJ,CAAC;AAED,MAAM,MAAM,GAAG,CAAC,CAAC;AAEjB,MAAM,UAAU,cAAc,CAAC,EAC7B,QAAQ,EACR,QAAQ,EACR,IAAI,EAAE,QAAQ,EACd,WAAW,GAAG,KAAK,EACnB,YAAY,EACZ,OAAO,EACP,MAAM,EACN,KAAK,EACL,WAAW,EACX,SAAS,EACT,IAAI,EACJ,MAAM,GAAG,aAAa,EACtB,KAAK,EAAE,SAAS,EAChB,aAAa,EACb,OAAO,GAAG,KAAK,EACf,WAAW,EACX,SAAS,GACW;IACpB,MAAM,QAAQ,GAAG,gBAAgB,EAAE,CAAC,cAAc,CAAC;IACnD,MAAM,SAAS,GAAG,kBAAkB,EAAE,CAAC;IACvC,MAAM,WAAW,GAAG,cAAc,EAAE,CAAC;IACrC,MAAM,IAAI,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IAC9C,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;IACpE,MAAM,UAAU,GAAG,QAAQ,KAAK,SAAS,CAAC;IAC1C,MAAM,IAAI,GAAG,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC;IAClD,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IACvD,MAAM,KAAK,GAAG,SAAS,IAAI,UAAU,CAAC;IACtC,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;IAChD,WAAW,CAAC,OAAO,GAAG,aAAa,CAAC;IACpC,MAAM,QAAQ,GAAG,KAAK,CAAC,WAAW,CAAC,CAAC,IAAY,EAAE,EAAE;QAClD,aAAa,CAAC,IAAI,CAAC,CAAC;QACpB,WAAW,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC,EAAE,EAAE,CAAC,CAAC;IACP,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAmB,IAAI,CAAC,CAAC;IACtD,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC;IAE7B,MAAM,OAAO,GAAG,KAAK,CAAC,WAAW,CAC/B,CAAC,IAAa,EAAE,EAAE;QAChB,IAAI,IAAI,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,KAAK,EAAE;YAAE,QAAQ,CAAC,EAAE,CAAC,CAAC;QACtD,IAAI,CAAC,UAAU;YAAE,eAAe,CAAC,IAAI,CAAC,CAAC;QACvC,YAAY,EAAE,CAAC,IAAI,CAAC,CAAC;IACvB,CAAC,EACD,CAAC,UAAU,EAAE,YAAY,EAAE,QAAQ,CAAC,CACrC,CAAC;IAEF,kFAAkF;IAClF,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAqE,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC;IAC3I,MAAM,CAAC,OAAO,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;IAE1C,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,IAAI,CAAC,MAAM;YAAE,OAAO,SAAS,CAAC;QAC9B,MAAM,SAAS,GAAG,CAAC,KAAoB,EAAE,EAAE;YACzC,IAAI,KAAK,CAAC,WAAW,IAAI,KAAK,CAAC,OAAO,KAAK,GAAG,IAAI,KAAK,CAAC,MAAM;gBAAE,OAAO;YACvE,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,KAAK,CAAC;gBAAE,OAAO;YACxC,KAAK,CAAC,cAAc,EAAE,CAAC;YACvB,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC/C,CAAC,CAAC;QACF,QAAQ,CAAC,gBAAgB,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;QAChD,OAAO,GAAG,EAAE,CAAC,QAAQ,CAAC,mBAAmB,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IAClE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;IAEb,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE;QAChC,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;QAC7B,MAAM,GAAG,GAAG,IAAI,GAAG,EAAwB,CAAC;QAC5C,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAC/B,IAAI,MAAM,KAAK,IAAI,IAAI,OAAO,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC;gBAAE,SAAS;YAC7E,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC;YAChC,IAAI,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACzB,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,KAAK,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;gBAClC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YACtB,CAAC;YACD,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC5B,CAAC;QACD,OAAO,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;IAC3B,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;IAE9B,MAAM,GAAG,GAAG,CAAC,OAAoB,EAAE,EAAE;QACnC,IAAI,OAAO,CAAC,QAAQ;YAAE,OAAO;QAC7B,IAAI,QAAQ,CAAC,OAAO,CAAC,KAAK,KAAK;YAAE,OAAO,CAAC,KAAK,CAAC,CAAC;IAClD,CAAC,CAAC;IAEF,MAAM,MAAM,GAAG,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;IAEzD,OAAO,CACL,MAAC,UAAU,CAAC,IAAI,IAAC,IAAI,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,aAC/D,OAAO,IAAI,KAAC,UAAU,CAAC,OAAO,IAAC,MAAM,EAAE,OAAO,GAAI,EACnD,KAAC,eAAe,cACb,IAAI,IAAI,CACP,MAAC,UAAU,CAAC,MAAM,IAAC,WAAW,QAAC,SAAS,EAAE,SAAS,aACjD,KAAC,UAAU,CAAC,QAAQ,IAClB,SAAS,EAAC,qBAAqB,EAC/B,MAAM,EACJ,KAAC,MAAM,CAAC,GAAG,IAAC,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE,UAAU,EAAE,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,GAAI,GAE7H,EACF,MAAC,UAAU,CAAC,KAAK,IACf,SAAS,EAAE,EAAE,CAAC,YAAY,EAAE,SAAS,CAAC,eAC5B,iBAAiB,EAC3B,YAAY,EAAE,QAAQ,EACtB,MAAM,EACJ,KAAC,MAAM,CAAC,GAAG,IACT,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,EAChC,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAC7B,IAAI,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,EAC7B,UAAU,EAAE,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,GACpC,aAGJ,KAAC,UAAU,CAAC,KAAK,IAAC,SAAS,EAAC,oBAAoB,YAAE,KAAK,IAAI,QAAQ,CAAC,KAAK,GAAoB,EAC7F,MAAC,YAAY,CAAC,IAAI,IAChB,IAAI,QACJ,MAAM,QACN,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,IAAI,EACZ,aAAa,EAAC,QAAQ,EACtB,aAAa,QACb,KAAK,EAAE,KAAK,EACZ,aAAa,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE;wCAC/B,iFAAiF;wCACjF,IAAI,OAAO,CAAC,MAAM,KAAK,YAAY;4CAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;oCACtD,CAAC,EACD,iBAAiB,EAAE,CAAC,OAAoB,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,aAE1D,eAAK,SAAS,EAAC,oBAAoB,aACjC,eAAM,SAAS,EAAC,yBAAyB,iBAAa,MAAM,YAC1D,KAAC,UAAU,KAAG,GACT,EACP,KAAC,YAAY,CAAC,KAAK,IACjB,GAAG,EAAE,QAAQ,EACb,SAAS,EAAC,mBAAmB,gBACjB,QAAQ,CAAC,UAAU,sBACb,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,EACrD,WAAW,EAAE,WAAW,IAAI,QAAQ,CAAC,WAAW,GAChD,IACE,EACN,KAAC,UAAU,CAAC,KAAK,IAAC,SAAS,EAAC,oBAAoB,YAAE,QAAQ,CAAC,KAAK,GAAoB,EACpF,eAAK,SAAS,EAAC,kBAAkB,aAE/B,KAAC,YAAY,CAAC,MAAM,IAAC,SAAS,EAAC,oBAAoB,YAChD,OAAO,CAAC,CAAC,CAAC,CACT,8BACE,KAAC,OAAO,IAAC,IAAI,EAAC,IAAI,GAAG,EACrB,yBAAO,WAAW,IAAI,QAAQ,CAAC,OAAO,GAAQ,IAC7C,CACJ,CAAC,CAAC,CAAC,IAAI,GACY,EACtB,KAAC,YAAY,CAAC,KAAK,IAAC,SAAS,EAAC,mBAAmB,YAAE,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,IAAI,QAAQ,CAAC,KAAK,CAAC,GAAsB,EACvH,KAAC,YAAY,CAAC,IAAI,IAAC,SAAS,EAAC,kBAAkB,eAAY,OAAO,IAAI,SAAS,YAC5E,CAAC,KAAmB,EAAE,EAAE,CAAC,CACxB,MAAC,YAAY,CAAC,KAAK,IAA0B,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,SAAS,EAAC,mBAAmB,aAC3F,KAAK,CAAC,KAAK,KAAK,EAAE,IAAI,KAAC,YAAY,CAAC,UAAU,IAAC,SAAS,EAAC,yBAAyB,YAAE,KAAK,CAAC,KAAK,GAA2B,EAC3H,KAAC,YAAY,CAAC,UAAU,cACrB,CAAC,OAAoB,EAAE,EAAE,CAAC,CACzB,MAAC,YAAY,CAAC,IAAI,IAEhB,KAAK,EAAE,OAAO,EACd,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAC1B,SAAS,EAAC,kBAAkB,qBACX,OAAO,CAAC,EAAE,eAChB,OAAO,CAAC,IAAI,IAAI,IAAI,IAAI,SAAS,EAC5C,OAAO,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,aAE1B,OAAO,CAAC,IAAI,IAAI,IAAI,IAAI,CACvB,eAAM,SAAS,EAAC,kBAAkB,iBAAa,MAAM,YAClD,OAAO,CAAC,IAAI,GACR,CACR,EACD,gBAAM,SAAS,EAAC,kBAAkB,aAChC,eAAM,SAAS,EAAC,mBAAmB,YAAE,SAAS,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,GAAQ,EAC3E,OAAO,CAAC,WAAW,IAAI,IAAI,IAAI,eAAM,SAAS,EAAC,yBAAyB,YAAE,OAAO,CAAC,WAAW,GAAQ,EACrG,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,cAAc,IAAI,IAAI,IAAI,CACrD,eAAM,SAAS,EAAC,oBAAoB,YAAE,OAAO,CAAC,cAAc,GAAQ,CACrE,IACI,EACN,OAAO,CAAC,IAAI,IAAI,IAAI,IAAI,eAAM,SAAS,EAAC,kBAAkB,YAAE,OAAO,CAAC,IAAI,GAAQ,EAChF,OAAO,CAAC,QAAQ,IAAI,IAAI,IAAI,CAC3B,cAAK,SAAS,EAAC,sBAAsB,iBAAa,MAAM,YACrD,OAAO,CAAC,QAAQ,GACb,CACP,KAzBI,OAAO,CAAC,EAAE,CA0BG,CACrB,GACuB,KAjCH,KAAK,KAAK,CAAC,KAAK,EAAE,CAkCtB,CACtB,GACiB,IAChB,EACL,MAAM,IAAI,IAAI,IAAI,CACjB,YAAG,EAAE,EAAE,MAAM,EAAE,SAAS,EAAC,kBAAkB,YACxC,MAAM,GACL,CACL,IACiB,IACH,IACD,CACrB,GACe,IACF,CACnB,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Context menu on Base UI ContextMenu (ADR-0010 §2). Opens at the pointer on right click, on
|
|
4
|
+
* long press (touch, 500 ms) and, from the keyboard, on Shift+F10 / the ContextMenu key while the
|
|
5
|
+
* target has focus (the browser fires `contextmenu` on the focused element). It reuses the Menu
|
|
6
|
+
* parts and styling: put `MenuItem`, `MenuCheckboxItem`, `MenuRadioGroup`, `MenuGroup` and
|
|
7
|
+
* `MenuSeparator` inside. Escape and outside click close it; focus returns to the target.
|
|
8
|
+
*
|
|
9
|
+
* The target must be reachable by keyboard: it gets `tabIndex={0}` unless it sets its own.
|
|
10
|
+
* Every command must also be available elsewhere (a Menu button, a toolbar); a context menu is
|
|
11
|
+
* a shortcut, not the only path (ACCESSIBILITY.md).
|
|
12
|
+
*
|
|
13
|
+
* <ContextMenu trigger={<div className="row">REC-0142</div>}>
|
|
14
|
+
* <MenuItem onSelect={copy}>复制编号</MenuItem>
|
|
15
|
+
* </ContextMenu>
|
|
16
|
+
*/
|
|
17
|
+
export type ContextMenuProps = {
|
|
18
|
+
/** The area that opens the menu: one element (usually a row or card) that can hold focus. */
|
|
19
|
+
trigger: React.ReactElement<Record<string, unknown>>;
|
|
20
|
+
/** Menu items (`MenuItem` and friends from Menu). */
|
|
21
|
+
children: React.ReactNode;
|
|
22
|
+
open?: boolean;
|
|
23
|
+
defaultOpen?: boolean;
|
|
24
|
+
onOpenChange?: (open: boolean) => void;
|
|
25
|
+
/** Leave the browser's native context menu in place. */
|
|
26
|
+
disabled?: boolean;
|
|
27
|
+
/** Class name for the popup. */
|
|
28
|
+
className?: string;
|
|
29
|
+
};
|
|
30
|
+
export declare function ContextMenu({ trigger, children, open, defaultOpen, onOpenChange, disabled, className }: ContextMenuProps): React.JSX.Element;
|
|
31
|
+
//# sourceMappingURL=ContextMenu.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ContextMenu.d.ts","sourceRoot":"","sources":["../../src/components/ContextMenu.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAK/B;;;;;;;;;;;;;;GAcG;AAEH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,6FAA6F;IAC7F,OAAO,EAAE,KAAK,CAAC,YAAY,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACrD,qDAAqD;IACrD,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,wDAAwD;IACxD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,gCAAgC;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAkBF,wBAAgB,WAAW,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,gBAAgB,qBA0BxH"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { ContextMenu as BaseContextMenu } from '@base-ui/react/context-menu';
|
|
4
|
+
import { usePortalContainer } from '../provider/portal.js';
|
|
5
|
+
import { cx } from '../utils/cx.js';
|
|
6
|
+
/**
|
|
7
|
+
* Not every engine turns Shift+F10 / the ContextMenu key into a `contextmenu` event on the focused
|
|
8
|
+
* element, so the keyboard path is explicit: it dispatches one at the element's centre. Base UI
|
|
9
|
+
* opens on it; if the browser also fires its own, opening again is a no-op.
|
|
10
|
+
*/
|
|
11
|
+
function openFromKeyboard(event) {
|
|
12
|
+
const isShortcut = (event.key === 'F10' && event.shiftKey) || event.key === 'ContextMenu';
|
|
13
|
+
if (!isShortcut || event.defaultPrevented)
|
|
14
|
+
return;
|
|
15
|
+
event.preventDefault();
|
|
16
|
+
const target = event.currentTarget;
|
|
17
|
+
const rect = target.getBoundingClientRect();
|
|
18
|
+
target.dispatchEvent(new MouseEvent('contextmenu', { bubbles: true, cancelable: true, clientX: rect.left + rect.width / 2, clientY: rect.top + rect.height / 2 }));
|
|
19
|
+
}
|
|
20
|
+
export function ContextMenu({ trigger, children, open, defaultOpen, onOpenChange, disabled, className }) {
|
|
21
|
+
const container = usePortalContainer();
|
|
22
|
+
const ownTabIndex = trigger.props.tabIndex;
|
|
23
|
+
return (_jsxs(BaseContextMenu.Root, { open: open, defaultOpen: defaultOpen, onOpenChange: onOpenChange ? (next) => onOpenChange(next) : undefined, disabled: disabled, children: [_jsx(BaseContextMenu.Trigger, { render: trigger, tabIndex: ownTabIndex ?? 0, onKeyDown: disabled ? undefined : openFromKeyboard, className: "rl-context-menu__trigger", "data-slot": "context-menu-trigger" }), _jsx(BaseContextMenu.Portal, { container: container, children: _jsx(BaseContextMenu.Positioner, { className: "rl-menu__positioner", collisionPadding: 8, children: _jsx(BaseContextMenu.Popup, { className: cx('rl-menu', 'rl-context-menu', className), "data-slot": "context-menu", children: children }) }) })] }));
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=ContextMenu.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ContextMenu.js","sourceRoot":"","sources":["../../src/components/ContextMenu.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAGb,OAAO,EAAE,WAAW,IAAI,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC7E,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,EAAE,EAAE,MAAM,gBAAgB,CAAC;AAgCpC;;;;GAIG;AACH,SAAS,gBAAgB,CAAC,KAAuC;IAC/D,MAAM,UAAU,GAAG,CAAC,KAAK,CAAC,GAAG,KAAK,KAAK,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC,GAAG,KAAK,aAAa,CAAC;IAC1F,IAAI,CAAC,UAAU,IAAI,KAAK,CAAC,gBAAgB;QAAE,OAAO;IAClD,KAAK,CAAC,cAAc,EAAE,CAAC;IACvB,MAAM,MAAM,GAAG,KAAK,CAAC,aAAa,CAAC;IACnC,MAAM,IAAI,GAAG,MAAM,CAAC,qBAAqB,EAAE,CAAC;IAC5C,MAAM,CAAC,aAAa,CAClB,IAAI,UAAU,CAAC,aAAa,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,CAC7I,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,EAAE,SAAS,EAAoB;IACvH,MAAM,SAAS,GAAG,kBAAkB,EAAE,CAAC;IACvC,MAAM,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC,QAA8B,CAAC;IACjE,OAAO,CACL,MAAC,eAAe,CAAC,IAAI,IACnB,IAAI,EAAE,IAAI,EACV,WAAW,EAAE,WAAW,EACxB,YAAY,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,EACrE,QAAQ,EAAE,QAAQ,aAElB,KAAC,eAAe,CAAC,OAAO,IACtB,MAAM,EAAE,OAAO,EACf,QAAQ,EAAE,WAAW,IAAI,CAAC,EAC1B,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,gBAAgB,EAClD,SAAS,EAAC,0BAA0B,eAC1B,sBAAsB,GAChC,EACF,KAAC,eAAe,CAAC,MAAM,IAAC,SAAS,EAAE,SAAS,YAC1C,KAAC,eAAe,CAAC,UAAU,IAAC,SAAS,EAAC,qBAAqB,EAAC,gBAAgB,EAAE,CAAC,YAC7E,KAAC,eAAe,CAAC,KAAK,IAAC,SAAS,EAAE,EAAE,CAAC,SAAS,EAAE,iBAAiB,EAAE,SAAS,CAAC,eAAY,cAAc,YACpG,QAAQ,GACa,GACG,GACN,IACJ,CACxB,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { PaginationLabels } from './Pagination.js';
|
|
3
|
+
/**
|
|
4
|
+
* Data table on a native <table>: real header cells, a caption, sortable columns that
|
|
5
|
+
* report `aria-sort`, optional row selection with named checkboxes, and an empty state.
|
|
6
|
+
* Wide tables scroll horizontally inside a focusable, labelled region instead of
|
|
7
|
+
* shrinking text. Sorting is controlled: the component reports the requested order and
|
|
8
|
+
* the caller supplies sorted rows, so it never reorders data it does not understand.
|
|
9
|
+
* Pagination works the same way (ADR-0005 §6): the table renders the pager and the caller
|
|
10
|
+
* supplies the current page's rows (`paginate()` helps for client-side data).
|
|
11
|
+
*/
|
|
12
|
+
export type DataTableStatus = 'ready' | 'loading' | 'error';
|
|
13
|
+
export interface DataTablePagination {
|
|
14
|
+
page: number;
|
|
15
|
+
onPageChange: (page: number) => void;
|
|
16
|
+
pageSize: number;
|
|
17
|
+
/** Total rows across all pages; drives the page count and the range summary. */
|
|
18
|
+
totalItems: number;
|
|
19
|
+
siblingCount?: number;
|
|
20
|
+
labels?: PaginationLabels;
|
|
21
|
+
}
|
|
22
|
+
export type SortDirection = 'ascending' | 'descending';
|
|
23
|
+
export interface SortState {
|
|
24
|
+
column: string;
|
|
25
|
+
direction: SortDirection;
|
|
26
|
+
}
|
|
27
|
+
export interface DataTableColumn<Row> {
|
|
28
|
+
key: string;
|
|
29
|
+
header: React.ReactNode;
|
|
30
|
+
/** Cell content. Defaults to `String(row[key])` when the row has that property. */
|
|
31
|
+
cell?: (row: Row) => React.ReactNode;
|
|
32
|
+
/** Allow sorting by this column. */
|
|
33
|
+
sortable?: boolean;
|
|
34
|
+
align?: 'start' | 'end' | 'center';
|
|
35
|
+
/** Monospace, tabular figures for IDs, numbers and timestamps. */
|
|
36
|
+
mono?: boolean;
|
|
37
|
+
/** Fixed column width as a CSS length or token, e.g. `var(--rl-space-16)`. */
|
|
38
|
+
width?: string;
|
|
39
|
+
/** Header text visually hidden but kept for screen readers (e.g. an actions column). */
|
|
40
|
+
hideHeader?: boolean;
|
|
41
|
+
/** Use this column's cell as the row header (<th scope="row">). One per table. */
|
|
42
|
+
rowHeader?: boolean;
|
|
43
|
+
}
|
|
44
|
+
export type DataTableProps<Row> = {
|
|
45
|
+
/** Visible caption; also names the scroll region. Required for an accessible table. */
|
|
46
|
+
caption: React.ReactNode;
|
|
47
|
+
/** Hide the caption visually (keep it for assistive tech) when a heading already labels the table. */
|
|
48
|
+
hideCaption?: boolean;
|
|
49
|
+
columns: readonly DataTableColumn<Row>[];
|
|
50
|
+
rows: readonly Row[];
|
|
51
|
+
getRowId: (row: Row) => string;
|
|
52
|
+
sort?: SortState | null;
|
|
53
|
+
onSortChange?: (sort: SortState) => void;
|
|
54
|
+
/** Enables a checkbox column. */
|
|
55
|
+
selectedIds?: ReadonlySet<string>;
|
|
56
|
+
onSelectionChange?: (ids: Set<string>) => void;
|
|
57
|
+
/** Accessible name for a row's checkbox; defaults to the row id. */
|
|
58
|
+
getRowLabel?: (row: Row) => string;
|
|
59
|
+
/** Empty-state title (rendered by EmptyState size="sm", as a paragraph). */
|
|
60
|
+
emptyText?: React.ReactNode;
|
|
61
|
+
/** Secondary line under the empty text, e.g. how to get results. */
|
|
62
|
+
emptyDescription?: React.ReactNode;
|
|
63
|
+
/** Optional action under the empty text, e.g. a "clear filters" button. */
|
|
64
|
+
emptyAction?: React.ReactNode;
|
|
65
|
+
/**
|
|
66
|
+
* `loading`: skeleton rows on first load; with existing rows they stay visible but dimmed.
|
|
67
|
+
* `error`: message + optional retry. Sorting, selection and paging are disabled in both.
|
|
68
|
+
*/
|
|
69
|
+
status?: DataTableStatus;
|
|
70
|
+
/** Skeleton rows on first load. */
|
|
71
|
+
loadingRows?: number;
|
|
72
|
+
loadingText?: React.ReactNode;
|
|
73
|
+
errorText?: React.ReactNode;
|
|
74
|
+
onRetry?: () => void;
|
|
75
|
+
retryLabel?: React.ReactNode;
|
|
76
|
+
pagination?: DataTablePagination;
|
|
77
|
+
density?: 'comfortable' | 'compact';
|
|
78
|
+
/** Accessible label for the horizontal scroll region; defaults to the caption text. */
|
|
79
|
+
scrollLabel?: string;
|
|
80
|
+
className?: string;
|
|
81
|
+
};
|
|
82
|
+
export declare function DataTable<Row>({ caption, hideCaption, columns, rows, getRowId, sort, onSortChange, selectedIds, onSelectionChange, getRowLabel, emptyText: emptyTextProp, emptyDescription, emptyAction, status, loadingRows, loadingText: loadingTextProp, errorText: errorTextProp, onRetry, retryLabel: retryLabelProp, pagination, density, scrollLabel, className, }: DataTableProps<Row>): React.JSX.Element;
|
|
83
|
+
//# sourceMappingURL=DataTable.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DataTable.d.ts","sourceRoot":"","sources":["../../src/components/DataTable.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { useRhineLocale } from '../provider/messages.js';
|
|
5
|
+
import { cx } from '../utils/cx.js';
|
|
6
|
+
import { Button } from './Button.js';
|
|
7
|
+
import { EmptyState } from './EmptyState.js';
|
|
8
|
+
import { Pagination } from './Pagination.js';
|
|
9
|
+
import { Skeleton } from './Skeleton.js';
|
|
10
|
+
function SortIcon({ direction }) {
|
|
11
|
+
return (_jsxs("svg", { className: "rl-table__sort-icon", viewBox: "0 0 16 16", "aria-hidden": "true", focusable: "false", "data-direction": direction ?? 'none', children: [_jsx("path", { className: "rl-table__sort-up", d: "M5 6.5 8 3.5l3 3" }), _jsx("path", { className: "rl-table__sort-down", d: "M5 9.5 8 12.5l3-3" })] }));
|
|
12
|
+
}
|
|
13
|
+
function defaultCell(row, key) {
|
|
14
|
+
const value = row[key];
|
|
15
|
+
return value === null || value === undefined ? '' : String(value);
|
|
16
|
+
}
|
|
17
|
+
export function DataTable({ caption, hideCaption = false, columns, rows, getRowId, sort, onSortChange, selectedIds, onSelectionChange, getRowLabel, emptyText: emptyTextProp, emptyDescription, emptyAction, status = 'ready', loadingRows = 5, loadingText: loadingTextProp, errorText: errorTextProp, onRetry, retryLabel: retryLabelProp, pagination, density = 'comfortable', scrollLabel, className, }) {
|
|
18
|
+
const { messages, formatNumber } = useRhineLocale();
|
|
19
|
+
const m = messages.dataTable;
|
|
20
|
+
// A prop given as `undefined` falls back to the messages, matching the old default parameters.
|
|
21
|
+
const emptyText = emptyTextProp === undefined ? m.empty : emptyTextProp;
|
|
22
|
+
const loadingText = loadingTextProp === undefined ? m.loading : loadingTextProp;
|
|
23
|
+
const errorText = errorTextProp === undefined ? m.error : errorTextProp;
|
|
24
|
+
const retryLabel = retryLabelProp === undefined ? m.retry : retryLabelProp;
|
|
25
|
+
const captionId = React.useId();
|
|
26
|
+
const scrollRef = React.useRef(null);
|
|
27
|
+
const busy = status !== 'ready';
|
|
28
|
+
const loading = status === 'loading';
|
|
29
|
+
const firstLoad = loading && rows.length === 0;
|
|
30
|
+
const selectable = selectedIds !== undefined && onSelectionChange !== undefined;
|
|
31
|
+
const rowIds = React.useMemo(() => rows.map(getRowId), [rows, getRowId]);
|
|
32
|
+
const selectedCount = selectable ? rowIds.filter((id) => selectedIds.has(id)).length : 0;
|
|
33
|
+
const allSelected = selectable && rows.length > 0 && selectedCount === rows.length;
|
|
34
|
+
/** Selected rows that are not on this page (pagination keeps the caller's selection). */
|
|
35
|
+
const offPageSelected = selectable ? selectedIds.size - selectedCount : 0;
|
|
36
|
+
const someSelected = selectable && selectedCount > 0 && !allSelected;
|
|
37
|
+
const headerCheckbox = React.useRef(null);
|
|
38
|
+
React.useEffect(() => {
|
|
39
|
+
if (headerCheckbox.current)
|
|
40
|
+
headerCheckbox.current.indeterminate = someSelected;
|
|
41
|
+
}, [someSelected]);
|
|
42
|
+
const toggleAll = () => {
|
|
43
|
+
if (!selectable)
|
|
44
|
+
return;
|
|
45
|
+
const next = new Set(selectedIds);
|
|
46
|
+
if (allSelected)
|
|
47
|
+
rowIds.forEach((id) => next.delete(id));
|
|
48
|
+
else
|
|
49
|
+
rowIds.forEach((id) => next.add(id));
|
|
50
|
+
onSelectionChange(next);
|
|
51
|
+
};
|
|
52
|
+
const toggleRow = (id) => {
|
|
53
|
+
if (!selectable)
|
|
54
|
+
return;
|
|
55
|
+
const next = new Set(selectedIds);
|
|
56
|
+
if (next.has(id))
|
|
57
|
+
next.delete(id);
|
|
58
|
+
else
|
|
59
|
+
next.add(id);
|
|
60
|
+
onSelectionChange(next);
|
|
61
|
+
};
|
|
62
|
+
const requestSort = (column) => {
|
|
63
|
+
if (!onSortChange)
|
|
64
|
+
return;
|
|
65
|
+
const direction = sort?.column === column && sort.direction === 'ascending' ? 'descending' : 'ascending';
|
|
66
|
+
onSortChange({ column, direction });
|
|
67
|
+
};
|
|
68
|
+
const columnCount = columns.length + (selectable ? 1 : 0);
|
|
69
|
+
const changePage = (next) => {
|
|
70
|
+
// New page starts at its first row; focus stays on the pager (Pagination keeps it).
|
|
71
|
+
if (scrollRef.current)
|
|
72
|
+
scrollRef.current.scrollTop = 0;
|
|
73
|
+
pagination.onPageChange(next);
|
|
74
|
+
};
|
|
75
|
+
const table = (_jsxs("div", { ref: scrollRef, className: cx('rl-table-scroll', !pagination && className), "data-slot": "data-table", "data-density": density, "data-status": status, role: "region", "aria-labelledby": scrollLabel ? undefined : captionId, "aria-label": scrollLabel, tabIndex: 0, children: [_jsxs("table", { className: "rl-table", "aria-busy": loading || undefined, children: [_jsx("caption", { id: captionId, className: hideCaption ? 'rl-visually-hidden' : 'rl-table__caption', children: caption }), _jsxs("colgroup", { children: [selectable && _jsx("col", { className: "rl-table__col-select" }), columns.map((column) => (_jsx("col", { style: column.width ? { width: column.width } : undefined }, column.key)))] }), _jsx("thead", { children: _jsxs("tr", { children: [selectable && (_jsx("th", { scope: "col", className: "rl-table__select", children: _jsx("input", { ref: headerCheckbox, type: "checkbox", className: "rl-table__checkbox", checked: allSelected, onChange: toggleAll, disabled: rows.length === 0 || busy, "aria-label": allSelected ? m.deselectAll : m.selectAll }) })), columns.map((column) => {
|
|
76
|
+
const active = sort?.column === column.key ? sort.direction : null;
|
|
77
|
+
const headerContent = column.hideHeader ? _jsx("span", { className: "rl-visually-hidden", children: column.header }) : column.header;
|
|
78
|
+
return (_jsx("th", { scope: "col", "data-align": column.align ?? 'start', "aria-sort": column.sortable ? (active ?? 'none') : undefined, children: column.sortable && onSortChange ? (_jsxs("button", { type: "button", className: "rl-table__sort", onClick: () => requestSort(column.key), "data-active": active ? true : undefined, disabled: busy, children: [headerContent, _jsx(SortIcon, { direction: active })] })) : (headerContent) }, column.key));
|
|
79
|
+
})] }) }), _jsx("tbody", { "data-stale": (loading && !firstLoad) || undefined, children: status === 'error' ? (_jsx("tr", { children: _jsxs("td", { colSpan: columnCount, className: "rl-table__message", "data-kind": "error", children: [_jsxs("div", { className: "rl-table__message-body", role: "alert", children: [_jsxs("svg", { className: "rl-table__message-icon", viewBox: "0 0 16 16", "aria-hidden": "true", focusable: "false", children: [_jsx("path", { d: "M8 1.75 15 14.25H1L8 1.75Z" }), _jsx("path", { d: "M8 6.5v3.25M8 11.75v.01" })] }), _jsx("span", { children: errorText })] }), onRetry && (_jsx(Button, { size: "sm", variant: "secondary", onClick: onRetry, children: retryLabel }))] }) })) : firstLoad ? (Array.from({ length: loadingRows }, (_, i) => (_jsx("tr", { className: "rl-table__skeleton-row", "aria-hidden": "true", children: Array.from({ length: columnCount }, (_, c) => (_jsx("td", { children: _jsx(Skeleton, { className: "rl-table__skeleton", width: i % 2 === 1 ? '50%' : '70%' }) }, c))) }, `skeleton-${i}`)))) : rows.length === 0 ? (_jsx("tr", { children: _jsx("td", { colSpan: columnCount, className: "rl-table__empty", children: _jsx(EmptyState, { size: "sm", kind: "no-results", icon: null, title: emptyText, description: emptyDescription, action: emptyAction }) }) })) : (rows.map((row) => {
|
|
80
|
+
const id = getRowId(row);
|
|
81
|
+
const selected = selectable && selectedIds.has(id);
|
|
82
|
+
return (_jsxs("tr", { "data-selected": selected || undefined, children: [selectable && (_jsx("td", { className: "rl-table__select", children: _jsx("input", { type: "checkbox", className: "rl-table__checkbox", checked: selected, onChange: () => toggleRow(id), disabled: busy, "aria-label": m.selectRow(getRowLabel ? getRowLabel(row) : id) }) })), columns.map((column) => {
|
|
83
|
+
const content = column.cell ? column.cell(row) : defaultCell(row, column.key);
|
|
84
|
+
const props = {
|
|
85
|
+
'data-align': column.align ?? 'start',
|
|
86
|
+
'data-mono': column.mono || undefined,
|
|
87
|
+
};
|
|
88
|
+
return column.rowHeader ? (_jsx("th", { ...props, scope: "row", children: content }, column.key)) : (_jsx("td", { ...props, children: content }, column.key));
|
|
89
|
+
})] }, id));
|
|
90
|
+
})) })] }), loading && (
|
|
91
|
+
// Visible on first load (skeleton rows are aria-hidden); announced in both cases.
|
|
92
|
+
_jsx("p", { className: firstLoad ? 'rl-table__loading' : 'rl-visually-hidden', role: "status", children: loadingText }))] }));
|
|
93
|
+
if (!pagination && !(selectable && offPageSelected > 0))
|
|
94
|
+
return table;
|
|
95
|
+
return (_jsxs("div", { className: cx('rl-table-frame', className), "data-slot": "data-table-frame", children: [table, _jsxs("div", { className: "rl-table__footer", children: [selectable && selectedIds.size > 0 && (_jsx("p", { className: "rl-table__selection", role: "status", children: m.selection(selectedIds.size, offPageSelected, formatNumber) })), pagination && (_jsx(Pagination, { className: "rl-table__pagination", page: pagination.page, onPageChange: changePage, pageSize: pagination.pageSize, totalItems: pagination.totalItems, siblingCount: pagination.siblingCount, labels: pagination.labels, busy: busy }))] })] }));
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=DataTable.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DataTable.js","sourceRoot":"","sources":["../../src/components/DataTable.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Modal dialog on Base UI Dialog (ADR-0001): focus trap, Escape, scroll lock, inert background
|
|
4
|
+
* and focus return are handled by Base UI; enter/exit run through motion/react (panel 280ms,
|
|
5
|
+
* 8px rise; opacity-only under reduced motion). Open state is always owned here so exit
|
|
6
|
+
* animations can finish before unmount, whether the caller controls `open` or not.
|
|
7
|
+
*/
|
|
8
|
+
export type DialogSize = 'sm' | 'md' | 'lg';
|
|
9
|
+
/** Why the user is trying to close the dialog (ADR-0006 §3). */
|
|
10
|
+
export type DialogCloseReason = 'escape' | 'outside' | 'close-button' | 'trigger';
|
|
11
|
+
export type DialogProps = {
|
|
12
|
+
/** Element that opens the dialog (usually a Button). Omit when opening programmatically. */
|
|
13
|
+
trigger?: React.ReactElement<Record<string, unknown>>;
|
|
14
|
+
title: React.ReactNode;
|
|
15
|
+
description?: React.ReactNode;
|
|
16
|
+
/** Small archive-style label above the title, e.g. "ARCHIVE / CONFIRM". */
|
|
17
|
+
eyebrow?: React.ReactNode;
|
|
18
|
+
/** Footer actions. Use `<DialogClose>` for buttons that only dismiss. */
|
|
19
|
+
actions?: React.ReactNode;
|
|
20
|
+
children?: React.ReactNode;
|
|
21
|
+
open?: boolean;
|
|
22
|
+
defaultOpen?: boolean;
|
|
23
|
+
onOpenChange?: (open: boolean) => void;
|
|
24
|
+
/** Fires after the exit animation, when focus has returned. */
|
|
25
|
+
onClosed?: () => void;
|
|
26
|
+
size?: DialogSize;
|
|
27
|
+
/** `false` keeps outside clicks from dismissing (use for destructive confirmations). */
|
|
28
|
+
dismissOnOutsideClick?: boolean;
|
|
29
|
+
/** Element to focus on open; defaults to the first tabbable element. */
|
|
30
|
+
initialFocus?: React.RefObject<HTMLElement | null>;
|
|
31
|
+
/** Render the standard top-right close control (default true). */
|
|
32
|
+
closeButton?: boolean;
|
|
33
|
+
/** Focus target after closing; `false` leaves focus where the browser left it. */
|
|
34
|
+
finalFocus?: boolean | null | React.RefObject<HTMLElement | null>;
|
|
35
|
+
/**
|
|
36
|
+
* Called before a user-initiated close. Return `false` to keep the dialog open (focus stays put),
|
|
37
|
+
* e.g. to ask "放弃未保存的更改?" in a nested AlertDialog. Programmatic `open={false}` skips it.
|
|
38
|
+
*/
|
|
39
|
+
onCloseRequest?: (reason: DialogCloseReason) => boolean | void;
|
|
40
|
+
className?: string;
|
|
41
|
+
};
|
|
42
|
+
export declare function Dialog({ trigger, title, description, eyebrow, actions, children, open: openProp, defaultOpen, onOpenChange, onClosed, size, dismissOnOutsideClick, initialFocus, closeButton, finalFocus, onCloseRequest, className, }: DialogProps): React.JSX.Element;
|
|
43
|
+
export type DialogCloseProps = {
|
|
44
|
+
/** The element that closes the dialog, typically `<Button variant="ghost">取消</Button>`. */
|
|
45
|
+
children: React.ReactElement<Record<string, unknown>>;
|
|
46
|
+
};
|
|
47
|
+
/** Wraps a button so activating it closes the nearest Dialog. */
|
|
48
|
+
export declare function DialogClose({ children }: DialogCloseProps): React.JSX.Element;
|
|
49
|
+
//# sourceMappingURL=Dialog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Dialog.d.ts","sourceRoot":"","sources":["../../src/components/Dialog.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAS/B;;;;;GAKG;AAEH,MAAM,MAAM,UAAU,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAE5C,gEAAgE;AAChE,MAAM,MAAM,iBAAiB,GAAG,QAAQ,GAAG,SAAS,GAAG,cAAc,GAAG,SAAS,CAAC;AASlF,MAAM,MAAM,WAAW,GAAG;IACxB,4FAA4F;IAC5F,OAAO,CAAC,EAAE,KAAK,CAAC,YAAY,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACtD,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC9B,2EAA2E;IAC3E,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,yEAAyE;IACzE,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,wFAAwF;IACxF,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,wEAAwE;IACxE,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IACnD,kEAAkE;IAClE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,kFAAkF;IAClF,UAAU,CAAC,EAAE,OAAO,GAAG,IAAI,GAAG,KAAK,CAAC,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IAClE;;;OAGG;IACH,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,iBAAiB,KAAK,OAAO,GAAG,IAAI,CAAC;IAC/D,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAIF,wBAAgB,MAAM,CAAC,EACrB,OAAO,EACP,KAAK,EACL,WAAW,EACX,OAAO,EACP,OAAO,EACP,QAAQ,EACR,IAAI,EAAE,QAAQ,EACd,WAAmB,EACnB,YAAY,EACZ,QAAQ,EACR,IAAW,EACX,qBAA4B,EAC5B,YAAY,EACZ,WAAkB,EAClB,UAAU,EACV,cAAc,EACd,SAAS,GACV,EAAE,WAAW,qBA6Eb;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,2FAA2F;IAC3F,QAAQ,EAAE,KAAK,CAAC,YAAY,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACvD,CAAC;AAEF,iEAAiE;AACjE,wBAAgB,WAAW,CAAC,EAAE,QAAQ,EAAE,EAAE,gBAAgB,qBAEzD"}
|