@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,60 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Scroll container with an overlay scrollbar (Base UI scroll-area, ADR-0001). The viewport is the
|
|
4
|
+
* native scroller, so wheel, touch, trackpad, keyboard (↑ ↓ PageUp PageDown Home End Space once
|
|
5
|
+
* focused), find-in-page and `scrollTo` all keep working; the custom thumb only mirrors it and can
|
|
6
|
+
* be dragged. The viewport is a named `role="region"`; Base UI puts it in the tab order only while
|
|
7
|
+
* it actually overflows (axe `scrollable-region-focusable`), so a short list adds no tab stop.
|
|
8
|
+
* Under `forced-colors: active` the overlay is hidden and the native scrollbar comes back.
|
|
9
|
+
* Motion: the overlay fades in on hover / scroll / focus (CSS opacity, --rl-motion-fast; tokens are
|
|
10
|
+
* 0 under reduced motion).
|
|
11
|
+
*
|
|
12
|
+
* `onScrollIntentUp` reports user intent to move up — wheel up, ↑ / PageUp / Home / Shift+Space on
|
|
13
|
+
* the focused viewport, dragging the thumb upward, or pressing the track above the thumb — and is
|
|
14
|
+
* never called for programmatic scrolling. Use it to leave "follow latest" modes. It may fire many
|
|
15
|
+
* times per gesture (once per event); it fires even at the top edge, because it is intent, not
|
|
16
|
+
* position.
|
|
17
|
+
*
|
|
18
|
+
* <ScrollArea label="运行日志" maxHeight="20rem">{lines}</ScrollArea>
|
|
19
|
+
*/
|
|
20
|
+
export type ScrollAreaOrientation = 'vertical' | 'both';
|
|
21
|
+
export type ScrollReveal = 'always' | 'hover' | 'scroll';
|
|
22
|
+
export type ScrollAreaProps = Omit<React.HTMLAttributes<HTMLDivElement>, 'children' | 'onScroll' | 'aria-label' | 'role'> & {
|
|
23
|
+
/** Accessible name of the scrollable region, e.g. 「运行日志」. */
|
|
24
|
+
label: string;
|
|
25
|
+
children: React.ReactNode;
|
|
26
|
+
/** Ref to the native scroller (for `scrollTo`, measuring, observers). */
|
|
27
|
+
viewportRef?: React.Ref<HTMLDivElement>;
|
|
28
|
+
/** CSS length that caps the viewport height, e.g. `"20rem"`. Without it the area fills its parent. */
|
|
29
|
+
maxHeight?: string;
|
|
30
|
+
/** `vertical` (default) wraps content to the width; `both` also scrolls horizontally. */
|
|
31
|
+
orientation?: ScrollAreaOrientation;
|
|
32
|
+
/** Native scroll events of the viewport. */
|
|
33
|
+
onScroll?: React.UIEventHandler<HTMLDivElement>;
|
|
34
|
+
/** The user tried to scroll up (see component docs). */
|
|
35
|
+
onScrollIntentUp?: () => void;
|
|
36
|
+
/** Class on the viewport, for padding or content layout. */
|
|
37
|
+
viewportClassName?: string;
|
|
38
|
+
reveal?: ScrollReveal;
|
|
39
|
+
thumbMinSize?: string;
|
|
40
|
+
};
|
|
41
|
+
export declare const ScrollArea: React.ForwardRefExoticComponent<Omit<React.HTMLAttributes<HTMLDivElement>, "children" | "role" | "aria-label" | "onScroll"> & {
|
|
42
|
+
/** Accessible name of the scrollable region, e.g. 「运行日志」. */
|
|
43
|
+
label: string;
|
|
44
|
+
children: React.ReactNode;
|
|
45
|
+
/** Ref to the native scroller (for `scrollTo`, measuring, observers). */
|
|
46
|
+
viewportRef?: React.Ref<HTMLDivElement>;
|
|
47
|
+
/** CSS length that caps the viewport height, e.g. `"20rem"`. Without it the area fills its parent. */
|
|
48
|
+
maxHeight?: string;
|
|
49
|
+
/** `vertical` (default) wraps content to the width; `both` also scrolls horizontally. */
|
|
50
|
+
orientation?: ScrollAreaOrientation;
|
|
51
|
+
/** Native scroll events of the viewport. */
|
|
52
|
+
onScroll?: React.UIEventHandler<HTMLDivElement>;
|
|
53
|
+
/** The user tried to scroll up (see component docs). */
|
|
54
|
+
onScrollIntentUp?: () => void;
|
|
55
|
+
/** Class on the viewport, for padding or content layout. */
|
|
56
|
+
viewportClassName?: string;
|
|
57
|
+
reveal?: ScrollReveal;
|
|
58
|
+
thumbMinSize?: string;
|
|
59
|
+
} & React.RefAttributes<HTMLDivElement>>;
|
|
60
|
+
//# sourceMappingURL=ScrollArea.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ScrollArea.d.ts","sourceRoot":"","sources":["../../src/components/ScrollArea.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B;;;;;;;;;;;;;;;;;GAiBG;AAEH,MAAM,MAAM,qBAAqB,GAAG,UAAU,GAAG,MAAM,CAAC;AACxD,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,CAAC;AAEzD,MAAM,MAAM,eAAe,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,UAAU,GAAG,UAAU,GAAG,YAAY,GAAG,MAAM,CAAC,GAAG;IAC1H,6DAA6D;IAC7D,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,yEAAyE;IACzE,WAAW,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IACxC,sGAAsG;IACtG,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yFAAyF;IACzF,WAAW,CAAC,EAAE,qBAAqB,CAAC;IACpC,4CAA4C;IAC5C,QAAQ,CAAC,EAAE,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,CAAC;IAChD,wDAAwD;IACxD,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC9B,4DAA4D;IAC5D,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAIF,eAAO,MAAM,UAAU;IArBrB,6DAA6D;WACtD,MAAM;cACH,KAAK,CAAC,SAAS;IACzB,yEAAyE;kBAC3D,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC;IACvC,sGAAsG;gBAC1F,MAAM;IAClB,yFAAyF;kBAC3E,qBAAqB;IACnC,4CAA4C;eACjC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;IAC/C,wDAAwD;uBACrC,MAAM,IAAI;IAC7B,4DAA4D;wBACxC,MAAM;aACjB,YAAY;mBACN,MAAM;wCA+FrB,CAAC"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { ScrollArea as BaseScrollArea } from '@base-ui/react/scroll-area';
|
|
5
|
+
import { cx } from '../utils/cx.js';
|
|
6
|
+
const UP_KEYS = new Set(['ArrowUp', 'PageUp', 'Home']);
|
|
7
|
+
export const ScrollArea = React.forwardRef(function ScrollArea({ label, children, viewportRef, maxHeight, orientation = 'vertical', onScroll, onScrollIntentUp, viewportClassName, reveal = 'hover', thumbMinSize, className, style, ...rest }, ref) {
|
|
8
|
+
const dragY = React.useRef(null);
|
|
9
|
+
const thumbRef = React.useRef(null);
|
|
10
|
+
const both = orientation === 'both';
|
|
11
|
+
const intent = onScrollIntentUp;
|
|
12
|
+
const viewportHandlers = intent
|
|
13
|
+
? {
|
|
14
|
+
onWheel: (event) => {
|
|
15
|
+
if (event.deltaY < 0)
|
|
16
|
+
intent();
|
|
17
|
+
},
|
|
18
|
+
onKeyDown: (event) => {
|
|
19
|
+
if (event.target !== event.currentTarget || event.altKey || event.ctrlKey || event.metaKey)
|
|
20
|
+
return;
|
|
21
|
+
if (UP_KEYS.has(event.key) || (event.key === ' ' && event.shiftKey))
|
|
22
|
+
intent();
|
|
23
|
+
},
|
|
24
|
+
}
|
|
25
|
+
: {};
|
|
26
|
+
const scrollbarHandlers = intent
|
|
27
|
+
? {
|
|
28
|
+
onPointerDown: (event) => {
|
|
29
|
+
const thumb = thumbRef.current;
|
|
30
|
+
if (!thumb || thumb.contains(event.target))
|
|
31
|
+
return;
|
|
32
|
+
// Pressing the track above the thumb pages up.
|
|
33
|
+
if (event.clientY < thumb.getBoundingClientRect().top)
|
|
34
|
+
intent();
|
|
35
|
+
},
|
|
36
|
+
}
|
|
37
|
+
: {};
|
|
38
|
+
const thumbHandlers = intent
|
|
39
|
+
? {
|
|
40
|
+
onPointerDown: (event) => {
|
|
41
|
+
dragY.current = event.clientY;
|
|
42
|
+
},
|
|
43
|
+
onPointerMove: (event) => {
|
|
44
|
+
if (dragY.current === null)
|
|
45
|
+
return;
|
|
46
|
+
if (event.clientY < dragY.current)
|
|
47
|
+
intent();
|
|
48
|
+
dragY.current = event.clientY;
|
|
49
|
+
},
|
|
50
|
+
onPointerUp: () => {
|
|
51
|
+
dragY.current = null;
|
|
52
|
+
},
|
|
53
|
+
onPointerCancel: () => {
|
|
54
|
+
dragY.current = null;
|
|
55
|
+
},
|
|
56
|
+
}
|
|
57
|
+
: {};
|
|
58
|
+
const rootStyle = maxHeight !== undefined ? { ...style, '--rl-scroll-area-max-height': maxHeight } : style;
|
|
59
|
+
return (_jsxs(BaseScrollArea.Root, { ...rest, ref: ref, className: cx('rl-scroll-area', className), "data-slot": "scroll-area", "data-orientation": orientation, style: { ...rootStyle, ...(thumbMinSize ? { '--rl-scroll-thumb-min': thumbMinSize } : undefined) }, "data-reveal": reveal, children: [_jsx(BaseScrollArea.Viewport, { ref: viewportRef, role: "region", "aria-label": label, className: cx('rl-scroll-area__viewport', viewportClassName),
|
|
60
|
+
// Vertical-only areas wrap to the width instead of growing a horizontal scroller.
|
|
61
|
+
style: both ? undefined : { overflowX: 'hidden' }, onScroll: onScroll, ...viewportHandlers, children: _jsx(BaseScrollArea.Content, { className: "rl-scroll-area__content", style: both ? undefined : { minWidth: 0 }, children: children }) }), _jsx(BaseScrollArea.Scrollbar, { className: "rl-scroll-area__scrollbar", orientation: "vertical", ...scrollbarHandlers, children: _jsx(BaseScrollArea.Thumb, { ref: thumbRef, className: "rl-scroll-area__thumb", ...thumbHandlers }) }), both && (_jsxs(_Fragment, { children: [_jsx(BaseScrollArea.Scrollbar, { className: "rl-scroll-area__scrollbar", orientation: "horizontal", children: _jsx(BaseScrollArea.Thumb, { className: "rl-scroll-area__thumb" }) }), _jsx(BaseScrollArea.Corner, { className: "rl-scroll-area__corner" })] }))] }));
|
|
62
|
+
});
|
|
63
|
+
//# sourceMappingURL=ScrollArea.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ScrollArea.js","sourceRoot":"","sources":["../../src/components/ScrollArea.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { InputSize } from './Input.js';
|
|
3
|
+
/**
|
|
4
|
+
* Single-value select on Base UI Select (ADR-0001): combobox + listbox semantics, typeahead,
|
|
5
|
+
* arrow/Home/End navigation, Escape to cancel, focus return. Inside `<Field>` it takes the
|
|
6
|
+
* field's label, description, error and validity; standalone, pass `aria-label`.
|
|
7
|
+
* Popup motion is a CSS transition on Base UI's starting/ending styles (--rl-motion-fast).
|
|
8
|
+
*/
|
|
9
|
+
export interface SelectOption {
|
|
10
|
+
value: string;
|
|
11
|
+
label: React.ReactNode;
|
|
12
|
+
disabled?: boolean;
|
|
13
|
+
}
|
|
14
|
+
export interface SelectGroup {
|
|
15
|
+
label: React.ReactNode;
|
|
16
|
+
options: readonly SelectOption[];
|
|
17
|
+
}
|
|
18
|
+
export type SelectProps = {
|
|
19
|
+
options: readonly (SelectOption | SelectGroup)[];
|
|
20
|
+
value?: string | null;
|
|
21
|
+
defaultValue?: string | null;
|
|
22
|
+
onValueChange?: (value: string | null) => void;
|
|
23
|
+
placeholder?: React.ReactNode;
|
|
24
|
+
name?: string;
|
|
25
|
+
required?: boolean;
|
|
26
|
+
disabled?: boolean;
|
|
27
|
+
readOnly?: boolean;
|
|
28
|
+
size?: InputSize;
|
|
29
|
+
/** Mark invalid outside a Field (inside a Field, validity comes from Field). */
|
|
30
|
+
invalid?: boolean;
|
|
31
|
+
open?: boolean;
|
|
32
|
+
onOpenChange?: (open: boolean) => void;
|
|
33
|
+
id?: string;
|
|
34
|
+
'aria-label'?: string;
|
|
35
|
+
'aria-labelledby'?: string;
|
|
36
|
+
className?: string;
|
|
37
|
+
};
|
|
38
|
+
export declare const Select: React.ForwardRefExoticComponent<SelectProps & React.RefAttributes<HTMLButtonElement>>;
|
|
39
|
+
//# sourceMappingURL=Select.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Select.d.ts","sourceRoot":"","sources":["../../src/components/Select.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAK/B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C;;;;;GAKG;AAEH,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,OAAO,EAAE,SAAS,YAAY,EAAE,CAAC;CAClC;AAED,MAAM,MAAM,WAAW,GAAG;IACxB,OAAO,EAAE,SAAS,CAAC,YAAY,GAAG,WAAW,CAAC,EAAE,CAAC;IACjD,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAC/C,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,gFAAgF;IAChF,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AA+BF,eAAO,MAAM,MAAM,uFAoFjB,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { Select as BaseSelect } from '@base-ui/react/select';
|
|
5
|
+
import { useRhineMessages } from '../provider/messages.js';
|
|
6
|
+
import { usePortalContainer } from '../provider/portal.js';
|
|
7
|
+
import { cx } from '../utils/cx.js';
|
|
8
|
+
const isGroup = (item) => 'options' in item;
|
|
9
|
+
function Chevron() {
|
|
10
|
+
return (_jsx("svg", { viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.75", "aria-hidden": "true", focusable: "false", children: _jsx("path", { d: "m4 6 4 4 4-4", strokeLinecap: "round", strokeLinejoin: "round" }) }));
|
|
11
|
+
}
|
|
12
|
+
function Check() {
|
|
13
|
+
return (_jsx("svg", { viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.75", "aria-hidden": "true", focusable: "false", children: _jsx("path", { d: "m3 8.5 3.5 3.5L13 4.5", strokeLinecap: "round", strokeLinejoin: "round" }) }));
|
|
14
|
+
}
|
|
15
|
+
function Option({ option }) {
|
|
16
|
+
return (_jsxs(BaseSelect.Item, { value: option.value, disabled: option.disabled, className: "rl-select__item", children: [_jsx(BaseSelect.ItemIndicator, { className: "rl-select__indicator", children: _jsx(Check, {}) }), _jsx(BaseSelect.ItemText, { className: "rl-select__item-text", children: option.label })] }));
|
|
17
|
+
}
|
|
18
|
+
export const Select = React.forwardRef(function Select({ options, value, defaultValue, onValueChange, placeholder: placeholderProp, name, required, disabled, readOnly, size = 'md', invalid, open, onOpenChange, id, className, ...aria }, ref) {
|
|
19
|
+
const container = usePortalContainer();
|
|
20
|
+
const messages = useRhineMessages();
|
|
21
|
+
const items = React.useMemo(() => options.flatMap((o) => (isGroup(o) ? o.options : [o])).map((o) => ({ value: o.value, label: o.label })), [options]);
|
|
22
|
+
return (_jsxs(BaseSelect.Root, { items: items, value: value, defaultValue: defaultValue, onValueChange: onValueChange ? (v) => onValueChange(v ?? null) : undefined, name: name, required: required, disabled: disabled, readOnly: readOnly, open: open, onOpenChange: onOpenChange ? (o) => onOpenChange(o) : undefined, id: id, children: [_jsxs(BaseSelect.Trigger, { ...aria, ref: ref, ...(invalid ? { 'aria-invalid': true } : null), className: cx('rl-select', className), "data-slot": "select", "data-size": size, "data-invalid": invalid || undefined, children: [_jsx(BaseSelect.Value, { className: "rl-select__value", placeholder: placeholderProp === undefined ? messages.select.placeholder : placeholderProp }), _jsx(BaseSelect.Icon, { className: "rl-select__icon", children: _jsx(Chevron, {}) })] }), _jsx(BaseSelect.Portal, { container: container, children: _jsx(BaseSelect.Positioner, { className: "rl-select__positioner", sideOffset: 4, collisionPadding: 8, alignItemWithTrigger: false, positionMethod: "fixed", children: _jsx(BaseSelect.Popup, { className: "rl-select__popup", children: _jsx(BaseSelect.List, { className: "rl-select__list", children: options.map((item, index) => isGroup(item) ? (_jsxs(BaseSelect.Group, { className: "rl-select__group", children: [_jsx(BaseSelect.GroupLabel, { className: "rl-select__group-label", children: item.label }), item.options.map((o) => (_jsx(Option, { option: o }, o.value)))] }, `g-${index}`)) : (_jsx(Option, { option: item }, item.value))) }) }) }) })] }));
|
|
23
|
+
});
|
|
24
|
+
//# sourceMappingURL=Select.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Select.js","sourceRoot":"","sources":["../../src/components/Select.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
export type SeparatorOrientation = 'horizontal' | 'vertical';
|
|
3
|
+
export type SeparatorTone = 'subtle' | 'default' | 'strong';
|
|
4
|
+
export type SeparatorProps = Omit<React.ComponentPropsWithoutRef<'div'>, 'role' | 'children'> & {
|
|
5
|
+
orientation?: SeparatorOrientation;
|
|
6
|
+
tone?: SeparatorTone;
|
|
7
|
+
/**
|
|
8
|
+
* Purely visual rule: removed from the accessibility tree. Use for decoration inside a
|
|
9
|
+
* group whose structure is already conveyed by headings or lists.
|
|
10
|
+
*/
|
|
11
|
+
decorative?: boolean;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Thin rule between groups of content (`role="separator"`). It is never the only boundary of
|
|
15
|
+
* an interactive region (DESIGN.md §3); focus, error and selection have their own styles.
|
|
16
|
+
*/
|
|
17
|
+
export declare const Separator: React.ForwardRefExoticComponent<Omit<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref">, "children" | "role"> & {
|
|
18
|
+
orientation?: SeparatorOrientation;
|
|
19
|
+
tone?: SeparatorTone;
|
|
20
|
+
/**
|
|
21
|
+
* Purely visual rule: removed from the accessibility tree. Use for decoration inside a
|
|
22
|
+
* group whose structure is already conveyed by headings or lists.
|
|
23
|
+
*/
|
|
24
|
+
decorative?: boolean;
|
|
25
|
+
} & React.RefAttributes<HTMLDivElement>>;
|
|
26
|
+
//# sourceMappingURL=Separator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Separator.d.ts","sourceRoot":"","sources":["../../src/components/Separator.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,MAAM,MAAM,oBAAoB,GAAG,YAAY,GAAG,UAAU,CAAC;AAC7D,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC;AAE5D,MAAM,MAAM,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,wBAAwB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,UAAU,CAAC,GAAG;IAC9F,WAAW,CAAC,EAAE,oBAAoB,CAAC;IACnC,IAAI,CAAC,EAAE,aAAa,CAAC;IACrB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,SAAS;kBAbN,oBAAoB;WAC3B,aAAa;IACpB;;;OAGG;iBACU,OAAO;wCAqBpB,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { Separator as BaseSeparator } from '@base-ui/react/separator';
|
|
5
|
+
import { cx } from '../utils/cx.js';
|
|
6
|
+
/**
|
|
7
|
+
* Thin rule between groups of content (`role="separator"`). It is never the only boundary of
|
|
8
|
+
* an interactive region (DESIGN.md §3); focus, error and selection have their own styles.
|
|
9
|
+
*/
|
|
10
|
+
export const Separator = React.forwardRef(function Separator({ orientation = 'horizontal', tone = 'default', decorative = false, className, ...rest }, ref) {
|
|
11
|
+
const shared = {
|
|
12
|
+
...rest,
|
|
13
|
+
className: cx('rl-separator', className),
|
|
14
|
+
'data-slot': 'separator',
|
|
15
|
+
'data-tone': tone,
|
|
16
|
+
};
|
|
17
|
+
if (decorative) {
|
|
18
|
+
return _jsx("div", { ...shared, ref: ref, "aria-hidden": "true", "data-orientation": orientation });
|
|
19
|
+
}
|
|
20
|
+
return _jsx(BaseSeparator, { ...shared, ref: ref, orientation: orientation });
|
|
21
|
+
});
|
|
22
|
+
//# sourceMappingURL=Separator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Separator.js","sourceRoot":"","sources":["../../src/components/Separator.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,SAAS,IAAI,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACtE,OAAO,EAAE,EAAE,EAAE,MAAM,gBAAgB,CAAC;AAepC;;;GAGG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,KAAK,CAAC,UAAU,CAAiC,SAAS,SAAS,CAC1F,EAAE,WAAW,GAAG,YAAY,EAAE,IAAI,GAAG,SAAS,EAAE,UAAU,GAAG,KAAK,EAAE,SAAS,EAAE,GAAG,IAAI,EAAE,EACxF,GAAG;IAEH,MAAM,MAAM,GAAG;QACb,GAAG,IAAI;QACP,SAAS,EAAE,EAAE,CAAC,cAAc,EAAE,SAAS,CAAC;QACxC,WAAW,EAAE,WAAW;QACxB,WAAW,EAAE,IAAI;KAClB,CAAC;IACF,IAAI,UAAU,EAAE,CAAC;QACf,OAAO,iBAAS,MAAM,EAAE,GAAG,EAAE,GAAG,iBAAc,MAAM,sBAAmB,WAAW,GAAI,CAAC;IACzF,CAAC;IACD,OAAO,KAAC,aAAa,OAAK,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,WAAW,EAAE,WAAW,GAAI,CAAC;AAC3E,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Placeholder block for content that is still loading (ADR-0006 §7). Always `aria-hidden`:
|
|
4
|
+
* the container owns `aria-busy` and a visible or visually hidden 「正在加载」 text.
|
|
5
|
+
* Pulses on `--rl-motion-loop`; static under reduced motion.
|
|
6
|
+
*
|
|
7
|
+
* <div aria-busy="true">
|
|
8
|
+
* <Skeleton shape="text" lines={3} />
|
|
9
|
+
* <span className="rl-visually-hidden">正在加载</span>
|
|
10
|
+
* </div>
|
|
11
|
+
*/
|
|
12
|
+
export type SkeletonShape = 'text' | 'block' | 'circle';
|
|
13
|
+
export type SkeletonProps = Omit<React.HTMLAttributes<HTMLSpanElement>, 'children' | 'role'> & {
|
|
14
|
+
shape?: SkeletonShape;
|
|
15
|
+
/** CSS length, e.g. `'12rem'`, `'60%'` or `'var(--rl-space-16)'`. */
|
|
16
|
+
width?: string;
|
|
17
|
+
/** CSS length. Text defaults to one line height; block and circle to `--rl-space-16`. */
|
|
18
|
+
height?: string;
|
|
19
|
+
/** Text only: number of lines; the last one is 60% wide. */
|
|
20
|
+
lines?: number;
|
|
21
|
+
};
|
|
22
|
+
export declare const Skeleton: React.ForwardRefExoticComponent<Omit<React.HTMLAttributes<HTMLSpanElement>, "children" | "role"> & {
|
|
23
|
+
shape?: SkeletonShape;
|
|
24
|
+
/** CSS length, e.g. `'12rem'`, `'60%'` or `'var(--rl-space-16)'`. */
|
|
25
|
+
width?: string;
|
|
26
|
+
/** CSS length. Text defaults to one line height; block and circle to `--rl-space-16`. */
|
|
27
|
+
height?: string;
|
|
28
|
+
/** Text only: number of lines; the last one is 60% wide. */
|
|
29
|
+
lines?: number;
|
|
30
|
+
} & React.RefAttributes<HTMLSpanElement>>;
|
|
31
|
+
//# sourceMappingURL=Skeleton.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Skeleton.d.ts","sourceRoot":"","sources":["../../src/components/Skeleton.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B;;;;;;;;;GASG;AAEH,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;AAExD,MAAM,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,eAAe,CAAC,EAAE,UAAU,GAAG,MAAM,CAAC,GAAG;IAC7F,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,qEAAqE;IACrE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yFAAyF;IACzF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,4DAA4D;IAC5D,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAIF,eAAO,MAAM,QAAQ;YAXX,aAAa;IACrB,qEAAqE;YAC7D,MAAM;IACd,yFAAyF;aAChF,MAAM;IACf,4DAA4D;YACpD,MAAM;yCA4Cd,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { cx } from '../utils/cx.js';
|
|
5
|
+
export const Skeleton = React.forwardRef(function Skeleton({ shape = 'text', width, height, lines = 1, className, style, ...rest }, ref) {
|
|
6
|
+
const vars = {
|
|
7
|
+
...style,
|
|
8
|
+
...(width !== undefined && { '--rl-skeleton-width': width }),
|
|
9
|
+
...(height !== undefined && { '--rl-skeleton-height': height }),
|
|
10
|
+
};
|
|
11
|
+
const count = shape === 'text' ? Math.max(1, Math.floor(lines)) : 1;
|
|
12
|
+
if (count > 1) {
|
|
13
|
+
return (_jsx("span", { ...rest, ref: ref, className: cx('rl-skeleton-lines', className), "data-slot": "skeleton", style: vars, "aria-hidden": "true", children: Array.from({ length: count }, (_, i) => (_jsx("span", { className: "rl-skeleton", "data-shape": "text", "data-last": i === count - 1 || undefined }, i))) }));
|
|
14
|
+
}
|
|
15
|
+
return (_jsx("span", { ...rest, ref: ref, className: cx('rl-skeleton', className), "data-slot": "skeleton", "data-shape": shape, style: vars, "aria-hidden": "true" }));
|
|
16
|
+
});
|
|
17
|
+
//# sourceMappingURL=Skeleton.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Skeleton.js","sourceRoot":"","sources":["../../src/components/Skeleton.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,EAAE,EAAE,MAAM,gBAAgB,CAAC;AA2BpC,MAAM,CAAC,MAAM,QAAQ,GAAG,KAAK,CAAC,UAAU,CAAiC,SAAS,QAAQ,CACxF,EAAE,KAAK,GAAG,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,GAAG,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,IAAI,EAAE,EACvE,GAAG;IAEH,MAAM,IAAI,GAAkB;QAC1B,GAAG,KAAK;QACR,GAAG,CAAC,KAAK,KAAK,SAAS,IAAI,EAAE,qBAAqB,EAAE,KAAK,EAAE,CAAC;QAC5D,GAAG,CAAC,MAAM,KAAK,SAAS,IAAI,EAAE,sBAAsB,EAAE,MAAM,EAAE,CAAC;KAChE,CAAC;IACF,MAAM,KAAK,GAAG,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAEpE,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;QACd,OAAO,CACL,kBACM,IAAI,EACR,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,EAAE,CAAC,mBAAmB,EAAE,SAAS,CAAC,eACnC,UAAU,EACpB,KAAK,EAAE,IAAI,iBACC,MAAM,YAEjB,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CACvC,eAAc,SAAS,EAAC,aAAa,gBAAY,MAAM,eAAY,CAAC,KAAK,KAAK,GAAG,CAAC,IAAI,SAAS,IAApF,CAAC,CAAuF,CACpG,CAAC,GACG,CACR,CAAC;IACJ,CAAC;IAED,OAAO,CACL,kBACM,IAAI,EACR,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,EAAE,CAAC,aAAa,EAAE,SAAS,CAAC,eAC7B,UAAU,gBACR,KAAK,EACjB,KAAK,EAAE,IAAI,iBACC,MAAM,GAClB,CACH,CAAC;AACJ,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Value on a continuous or stepped scale, on Base UI Slider (ADR-0010 §2). Each thumb is a
|
|
4
|
+
* native `<input type="range">` (visually hidden inside the thumb), named by the visible `label`
|
|
5
|
+
* through `aria-labelledby`, so the value submits with the form under `name`.
|
|
6
|
+
*
|
|
7
|
+
* Keyboard (Base UI): ←/↓ and →/↑ step, Shift + arrow or PageUp/PageDown take `largeStep`,
|
|
8
|
+
* Home/End jump to min/max. Dragging writes position directly; no transition runs while dragging.
|
|
9
|
+
*
|
|
10
|
+
* Discrete levels (e.g. an effort setting) use `marks`: ticks + labels under the track, and the
|
|
11
|
+
* mark label becomes the spoken value (`aria-valuetext`) when the thumb sits on it.
|
|
12
|
+
*
|
|
13
|
+
* <Slider label="执行强度" min={0} max={4} marks={levels} defaultValue={2} />
|
|
14
|
+
* <Slider label="温度范围" defaultValue={[20, 60]} thumbLabels={['下限', '上限']} />
|
|
15
|
+
*/
|
|
16
|
+
export interface SliderMark {
|
|
17
|
+
value: number;
|
|
18
|
+
/** Visible tick label; also the spoken value when the thumb is on this mark. */
|
|
19
|
+
label?: React.ReactNode;
|
|
20
|
+
/** Spoken text when `label` is not a string. */
|
|
21
|
+
valueText?: string;
|
|
22
|
+
}
|
|
23
|
+
type SliderValue = number | readonly number[];
|
|
24
|
+
/** The value shape `onValueChange` reports: a number for single sliders, an array for ranges. */
|
|
25
|
+
export type SliderChangeValue<V extends SliderValue> = V extends number ? number : number[];
|
|
26
|
+
export type SliderProps<V extends SliderValue = number> = Omit<React.HTMLAttributes<HTMLDivElement>, 'children' | 'defaultValue' | 'onChange' | 'aria-label' | 'aria-labelledby'> & {
|
|
27
|
+
/** Visible label; names every thumb (required, ADR-0001 naming rule). */
|
|
28
|
+
label: React.ReactNode;
|
|
29
|
+
/** The name comes from `label` (use `thumbLabels` for range thumbs). */
|
|
30
|
+
'aria-label'?: never;
|
|
31
|
+
'aria-labelledby'?: never;
|
|
32
|
+
/** Keep the label for assistive tech only. */
|
|
33
|
+
hideLabel?: boolean;
|
|
34
|
+
description?: React.ReactNode;
|
|
35
|
+
/** Single number, or an array for a range slider (one thumb per entry). */
|
|
36
|
+
value?: V;
|
|
37
|
+
defaultValue?: V;
|
|
38
|
+
onValueChange?: (value: SliderChangeValue<V>) => void;
|
|
39
|
+
/** Fires once per interaction (pointer release, key press). */
|
|
40
|
+
onValueCommitted?: (value: SliderChangeValue<V>) => void;
|
|
41
|
+
min?: number;
|
|
42
|
+
max?: number;
|
|
43
|
+
step?: number;
|
|
44
|
+
/** Step for PageUp / PageDown and Shift + arrow (default 10). */
|
|
45
|
+
largeStep?: number;
|
|
46
|
+
/** Minimum distance, in steps, between range thumbs. */
|
|
47
|
+
minStepsBetweenValues?: number;
|
|
48
|
+
marks?: readonly SliderMark[];
|
|
49
|
+
/** Intl options for the displayed and spoken value; locale comes from RhineProvider. */
|
|
50
|
+
format?: Intl.NumberFormatOptions;
|
|
51
|
+
/** Custom text for one value (display and default `aria-valuetext`). Wins over `format`. */
|
|
52
|
+
formatValue?: (value: number) => string;
|
|
53
|
+
/** Spoken value per thumb; wins over mark labels and `formatValue`. */
|
|
54
|
+
getAriaValueText?: (formattedValue: string, value: number, index: number) => string;
|
|
55
|
+
/** Distinct accessible names for range thumbs (e.g. ['下限', '上限']). */
|
|
56
|
+
thumbLabels?: readonly string[];
|
|
57
|
+
/** Show the current value next to the label (`<output>`). */
|
|
58
|
+
showValue?: boolean;
|
|
59
|
+
name?: string;
|
|
60
|
+
disabled?: boolean;
|
|
61
|
+
ref?: React.Ref<HTMLDivElement>;
|
|
62
|
+
};
|
|
63
|
+
export declare function Slider<V extends SliderValue = number>({ label, hideLabel, description, value, defaultValue, onValueChange, onValueCommitted, min, max, step, largeStep, minStepsBetweenValues, marks, format, formatValue, getAriaValueText, thumbLabels, showValue, name, disabled, className, ref, ...rest }: SliderProps<V>): React.JSX.Element;
|
|
64
|
+
export {};
|
|
65
|
+
//# sourceMappingURL=Slider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Slider.d.ts","sourceRoot":"","sources":["../../src/components/Slider.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAK/B;;;;;;;;;;;;;GAaG;AAEH,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,gFAAgF;IAChF,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,gDAAgD;IAChD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,KAAK,WAAW,GAAG,MAAM,GAAG,SAAS,MAAM,EAAE,CAAC;AAC9C,iGAAiG;AACjG,MAAM,MAAM,iBAAiB,CAAC,CAAC,SAAS,WAAW,IAAI,CAAC,SAAS,MAAM,GAAG,MAAM,GAAG,MAAM,EAAE,CAAC;AAE5F,MAAM,MAAM,WAAW,CAAC,CAAC,SAAS,WAAW,GAAG,MAAM,IAAI,IAAI,CAC5D,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EACpC,UAAU,GAAG,cAAc,GAAG,UAAU,GAAG,YAAY,GAAG,iBAAiB,CAC5E,GAAG;IACF,yEAAyE;IACzE,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,wEAAwE;IACxE,YAAY,CAAC,EAAE,KAAK,CAAC;IACrB,iBAAiB,CAAC,EAAE,KAAK,CAAC;IAC1B,8CAA8C;IAC9C,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC9B,2EAA2E;IAC3E,KAAK,CAAC,EAAE,CAAC,CAAC;IACV,YAAY,CAAC,EAAE,CAAC,CAAC;IACjB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,iBAAiB,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;IACtD,+DAA+D;IAC/D,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE,iBAAiB,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;IACzD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,iEAAiE;IACjE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wDAAwD;IACxD,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,KAAK,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;IAC9B,wFAAwF;IACxF,MAAM,CAAC,EAAE,IAAI,CAAC,mBAAmB,CAAC;IAClC,4FAA4F;IAC5F,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IACxC,uEAAuE;IACvE,gBAAgB,CAAC,EAAE,CAAC,cAAc,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IACpF,sEAAsE;IACtE,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,6DAA6D;IAC7D,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;CACjC,CAAC;AAQF,wBAAgB,MAAM,CAAC,CAAC,SAAS,WAAW,GAAG,MAAM,EAAE,EACrD,KAAK,EACL,SAAiB,EACjB,WAAW,EACX,KAAK,EACL,YAAY,EACZ,aAAa,EACb,gBAAgB,EAChB,GAAO,EACP,GAAS,EACT,IAAQ,EACR,SAAS,EACT,qBAAqB,EACrB,KAAK,EACL,MAAM,EACN,WAAW,EACX,gBAAgB,EAChB,WAAW,EACX,SAAiB,EACjB,IAAI,EACJ,QAAQ,EACR,SAAS,EACT,GAAG,EACH,GAAG,IAAI,EACR,EAAE,WAAW,CAAC,CAAC,CAAC,qBAoFhB"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { Slider as BaseSlider } from '@base-ui/react/slider';
|
|
5
|
+
import { useRhineLocale } from '../provider/messages.js';
|
|
6
|
+
import { cx } from '../utils/cx.js';
|
|
7
|
+
function markText(mark) {
|
|
8
|
+
if (!mark)
|
|
9
|
+
return undefined;
|
|
10
|
+
if (mark.valueText != null)
|
|
11
|
+
return mark.valueText;
|
|
12
|
+
return typeof mark.label === 'string' || typeof mark.label === 'number' ? String(mark.label) : undefined;
|
|
13
|
+
}
|
|
14
|
+
export function Slider({ label, hideLabel = false, description, value, defaultValue, onValueChange, onValueCommitted, min = 0, max = 100, step = 1, largeStep, minStepsBetweenValues, marks, format, formatValue, getAriaValueText, thumbLabels, showValue = false, name, disabled, className, ref, ...rest }) {
|
|
15
|
+
const { locale } = useRhineLocale();
|
|
16
|
+
const descriptionId = React.useId();
|
|
17
|
+
const current = value ?? defaultValue;
|
|
18
|
+
const thumbCount = Array.isArray(current) ? current.length : 1;
|
|
19
|
+
const range = max - min || 1;
|
|
20
|
+
const markFor = (v) => marks?.find((m) => m.value === v);
|
|
21
|
+
const textFor = (formatted, v) => markText(markFor(v)) ?? (formatValue ? formatValue(v) : formatted);
|
|
22
|
+
const valueText = (formatted, v, index) => getAriaValueText ? getAriaValueText(formatted, v, index) : textFor(formatted, v);
|
|
23
|
+
// Base UI may hand out a frozen array; copy it so callers can keep and mutate their state.
|
|
24
|
+
const normalize = (next) => (Array.isArray(next) ? [...next] : next);
|
|
25
|
+
return (_jsxs(BaseSlider.Root, { ...rest, ref: ref, value: value, defaultValue: defaultValue, onValueChange: onValueChange ? (next) => onValueChange(normalize(next)) : undefined, onValueCommitted: onValueCommitted ? (next) => onValueCommitted(normalize(next)) : undefined, min: min, max: max, step: step, largeStep: largeStep, minStepsBetweenValues: minStepsBetweenValues, format: format, locale: locale, name: name, disabled: disabled, className: cx('rl-slider', className), "data-slot": "slider", "data-has-marks": marks?.some((m) => m.label != null) || undefined, children: [_jsxs("div", { className: cx('rl-slider__header', hideLabel && !showValue && 'rl-visually-hidden'), children: [_jsx(BaseSlider.Label, { className: cx('rl-slider__label', hideLabel && 'rl-visually-hidden'), children: label }), showValue && (_jsx(BaseSlider.Value, { className: "rl-slider__value", children: (formatted, values) => values.map((v, i) => textFor(formatted[i] ?? String(v), v)).join(' – ') }))] }), _jsxs(BaseSlider.Control, { className: "rl-slider__control", children: [_jsxs(BaseSlider.Track, { className: "rl-slider__track", children: [_jsx(BaseSlider.Indicator, { className: "rl-slider__indicator" }), Array.from({ length: thumbCount }, (_, index) => (_jsx(BaseSlider.Thumb, { index: index, className: "rl-slider__thumb", getAriaLabel: thumbLabels ? (i) => thumbLabels[i] ?? '' : undefined, getAriaValueText: valueText, "aria-describedby": description != null ? descriptionId : undefined }, index)))] }), marks && marks.length > 0 && (_jsx("div", { className: "rl-slider__marks", "aria-hidden": "true", children: marks.map((mark) => {
|
|
26
|
+
const percent = ((Math.min(max, Math.max(min, mark.value)) - min) / range) * 100;
|
|
27
|
+
return (_jsxs("span", { className: "rl-slider__mark", "data-edge": percent === 0 ? 'start' : percent === 100 ? 'end' : undefined, style: { '--rl-slider-mark-position': `${percent}%` }, children: [_jsx("span", { className: "rl-slider__tick" }), mark.label != null && _jsx("span", { className: "rl-slider__mark-label", children: mark.label })] }, mark.value));
|
|
28
|
+
}) }))] }), description != null && (_jsx("p", { id: descriptionId, className: "rl-slider__description", children: description }))] }));
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=Slider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Slider.js","sourceRoot":"","sources":["../../src/components/Slider.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Indeterminate activity indicator (ADR-0006 §7). With `label` it is a polite status
|
|
4
|
+
* (`role="status"` + visually hidden text); without, it is decorative and the surrounding
|
|
5
|
+
* control carries the busy state (e.g. Button `aria-busy`). Rotation runs on motion/react and
|
|
6
|
+
* stops under reduced motion (OS or RhineProvider), leaving a longer static arc.
|
|
7
|
+
*
|
|
8
|
+
* <Spinner size="sm" label="正在加载记录" />
|
|
9
|
+
*/
|
|
10
|
+
export type SpinnerSize = 'sm' | 'md' | 'lg';
|
|
11
|
+
export type SpinnerProps = Omit<React.HTMLAttributes<HTMLSpanElement>, 'children' | 'role'> & {
|
|
12
|
+
/** Maps to the icon-size tokens. */
|
|
13
|
+
size?: SpinnerSize;
|
|
14
|
+
/** Spoken status text, e.g. 「正在加载」. Omit for a decorative spinner. */
|
|
15
|
+
label?: string;
|
|
16
|
+
};
|
|
17
|
+
export declare const Spinner: React.ForwardRefExoticComponent<Omit<React.HTMLAttributes<HTMLSpanElement>, "children" | "role"> & {
|
|
18
|
+
/** Maps to the icon-size tokens. */
|
|
19
|
+
size?: SpinnerSize;
|
|
20
|
+
/** Spoken status text, e.g. 「正在加载」. Omit for a decorative spinner. */
|
|
21
|
+
label?: string;
|
|
22
|
+
} & React.RefAttributes<HTMLSpanElement>>;
|
|
23
|
+
//# sourceMappingURL=Spinner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Spinner.d.ts","sourceRoot":"","sources":["../../src/components/Spinner.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAM/B;;;;;;;GAOG;AAEH,MAAM,MAAM,WAAW,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAE7C,MAAM,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,eAAe,CAAC,EAAE,UAAU,GAAG,MAAM,CAAC,GAAG;IAC5F,oCAAoC;IACpC,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,sEAAsE;IACtE,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,eAAO,MAAM,OAAO;IANlB,oCAAoC;WAC7B,WAAW;IAClB,sEAAsE;YAC9D,MAAM;yCAkCd,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { motion } from 'motion/react';
|
|
5
|
+
import { transition } from '../motion/presets.js';
|
|
6
|
+
import { useRhineMotion } from '../motion/useRhineMotion.js';
|
|
7
|
+
import { cx } from '../utils/cx.js';
|
|
8
|
+
export const Spinner = React.forwardRef(function Spinner({ size = 'md', label, className, ...rest }, ref) {
|
|
9
|
+
const { reduced } = useRhineMotion();
|
|
10
|
+
const named = label !== undefined && label !== '';
|
|
11
|
+
return (_jsxs("span", { ...rest, ref: ref, className: cx('rl-spinner', className), "data-slot": "spinner", "data-size": size, "data-reduced": reduced || undefined, role: named ? 'status' : undefined, "aria-hidden": named ? undefined : true, children: [_jsxs(motion.svg, { className: "rl-spinner__svg", viewBox: "0 0 16 16", "aria-hidden": "true", focusable: "false", animate: reduced ? { rotate: 0 } : { rotate: 360 }, transition: reduced ? transition.instant : transition.loop, children: [_jsx("circle", { className: "rl-spinner__track", cx: "8", cy: "8", r: "6" }), _jsx("circle", { className: "rl-spinner__arc", cx: "8", cy: "8", r: "6", pathLength: "100" })] }), named && _jsx("span", { className: "rl-visually-hidden", children: label })] }));
|
|
12
|
+
});
|
|
13
|
+
//# sourceMappingURL=Spinner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Spinner.js","sourceRoot":"","sources":["../../src/components/Spinner.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,EAAE,EAAE,MAAM,gBAAgB,CAAC;AAoBpC,MAAM,CAAC,MAAM,OAAO,GAAG,KAAK,CAAC,UAAU,CAAgC,SAAS,OAAO,CACrF,EAAE,IAAI,GAAG,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,IAAI,EAAE,EAC1C,GAAG;IAEH,MAAM,EAAE,OAAO,EAAE,GAAG,cAAc,EAAE,CAAC;IACrC,MAAM,KAAK,GAAG,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,EAAE,CAAC;IAClD,OAAO,CACL,mBACM,IAAI,EACR,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,EAAE,CAAC,YAAY,EAAE,SAAS,CAAC,eAC5B,SAAS,eACR,IAAI,kBACD,OAAO,IAAI,SAAS,EAClC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,iBACrB,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,aAErC,MAAC,MAAM,CAAC,GAAG,IACT,SAAS,EAAC,iBAAiB,EAC3B,OAAO,EAAC,WAAW,iBACP,MAAM,EAClB,SAAS,EAAC,OAAO,EACjB,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,EAClD,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,aAE1D,iBAAQ,SAAS,EAAC,mBAAmB,EAAC,EAAE,EAAC,GAAG,EAAC,EAAE,EAAC,GAAG,EAAC,CAAC,EAAC,GAAG,GAAG,EAC5D,iBAAQ,SAAS,EAAC,iBAAiB,EAAC,EAAE,EAAC,GAAG,EAAC,EAAE,EAAC,GAAG,EAAC,CAAC,EAAC,GAAG,EAAC,UAAU,EAAC,KAAK,GAAG,IAChE,EACZ,KAAK,IAAI,eAAM,SAAS,EAAC,oBAAoB,YAAE,KAAK,GAAQ,IACxD,CACR,CAAC;AACJ,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { ButtonSize, ButtonVariant } from './Button.js';
|
|
3
|
+
import type { MenuAlign, MenuSide } from './Menu.js';
|
|
4
|
+
/**
|
|
5
|
+
* A primary action with an attached menu of related actions ("导出 CSV ▾ → 导出 JSON / 导出 PDF").
|
|
6
|
+
* Both halves are real `<button>`s inside a `role="group"` named by `label`, drawn in one frame.
|
|
7
|
+
* The main part is the public Button (loading keeps focus and announces busy); the toggle is an
|
|
8
|
+
* IconButton (name from `menuLabel`) that opens the public Menu (Base UI: menu / menuitem
|
|
9
|
+
* semantics, arrow keys, typeahead, Escape returns focus to the toggle). Enter / Space / ↓ on the
|
|
10
|
+
* toggle open the menu. While `loading` the toggle is `aria-disabled` and refuses to open (it keeps
|
|
11
|
+
* focus, so choosing a menu item that starts the busy state never drops focus to the page), and an
|
|
12
|
+
* open menu closes. `disabled` disables both halves natively. Motion: Button press + Menu CSS
|
|
13
|
+
* transition only.
|
|
14
|
+
*
|
|
15
|
+
* <SplitButton label="导出 CSV" menuLabel="更多导出格式" onClick={exportCsv}>
|
|
16
|
+
* <MenuItem onSelect={exportJson}>导出 JSON</MenuItem>
|
|
17
|
+
* </SplitButton>
|
|
18
|
+
*/
|
|
19
|
+
export type SplitButtonProps = Omit<React.HTMLAttributes<HTMLDivElement>, 'onClick' | 'children' | 'role' | 'aria-label'> & {
|
|
20
|
+
/** Text of the main action; also names the group. */
|
|
21
|
+
label: string;
|
|
22
|
+
onClick?: (event: React.MouseEvent<HTMLButtonElement>) => void;
|
|
23
|
+
/** Accessible name of the menu toggle, e.g. 「更多导出方式」. */
|
|
24
|
+
menuLabel: string;
|
|
25
|
+
/** Menu content: MenuItem, MenuGroup, MenuSeparator… */
|
|
26
|
+
children: React.ReactNode;
|
|
27
|
+
variant?: ButtonVariant;
|
|
28
|
+
size?: ButtonSize;
|
|
29
|
+
disabled?: boolean;
|
|
30
|
+
/** Busy main action; the toggle stays focusable but will not open until it settles. */
|
|
31
|
+
loading?: boolean;
|
|
32
|
+
/** Decorative leading icon of the main action. */
|
|
33
|
+
iconStart?: React.ReactNode;
|
|
34
|
+
menuSide?: MenuSide;
|
|
35
|
+
menuAlign?: MenuAlign;
|
|
36
|
+
menuOpen?: boolean;
|
|
37
|
+
onMenuOpenChange?: (open: boolean) => void;
|
|
38
|
+
};
|
|
39
|
+
export declare const SplitButton: React.ForwardRefExoticComponent<Omit<React.HTMLAttributes<HTMLDivElement>, "children" | "role" | "aria-label" | "onClick"> & {
|
|
40
|
+
/** Text of the main action; also names the group. */
|
|
41
|
+
label: string;
|
|
42
|
+
onClick?: (event: React.MouseEvent<HTMLButtonElement>) => void;
|
|
43
|
+
/** Accessible name of the menu toggle, e.g. 「更多导出方式」. */
|
|
44
|
+
menuLabel: string;
|
|
45
|
+
/** Menu content: MenuItem, MenuGroup, MenuSeparator… */
|
|
46
|
+
children: React.ReactNode;
|
|
47
|
+
variant?: ButtonVariant;
|
|
48
|
+
size?: ButtonSize;
|
|
49
|
+
disabled?: boolean;
|
|
50
|
+
/** Busy main action; the toggle stays focusable but will not open until it settles. */
|
|
51
|
+
loading?: boolean;
|
|
52
|
+
/** Decorative leading icon of the main action. */
|
|
53
|
+
iconStart?: React.ReactNode;
|
|
54
|
+
menuSide?: MenuSide;
|
|
55
|
+
menuAlign?: MenuAlign;
|
|
56
|
+
menuOpen?: boolean;
|
|
57
|
+
onMenuOpenChange?: (open: boolean) => void;
|
|
58
|
+
} & React.RefAttributes<HTMLDivElement>>;
|
|
59
|
+
//# sourceMappingURL=SplitButton.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SplitButton.d.ts","sourceRoot":"","sources":["../../src/components/SplitButton.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAI7D,OAAO,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAErD;;;;;;;;;;;;;;GAcG;AAEH,MAAM,MAAM,gBAAgB,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,SAAS,GAAG,UAAU,GAAG,MAAM,GAAG,YAAY,CAAC,GAAG;IAC1H,qDAAqD;IACrD,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,CAAC,iBAAiB,CAAC,KAAK,IAAI,CAAC;IAC/D,yDAAyD;IACzD,SAAS,EAAE,MAAM,CAAC;IAClB,wDAAwD;IACxD,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,uFAAuF;IACvF,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,kDAAkD;IAClD,SAAS,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC5B,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;CAC5C,CAAC;AAkBF,eAAO,MAAM,WAAW;IApCtB,qDAAqD;WAC9C,MAAM;cACH,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,CAAC,iBAAiB,CAAC,KAAK,IAAI;IAC9D,yDAAyD;eAC9C,MAAM;IACjB,wDAAwD;cAC9C,KAAK,CAAC,SAAS;cACf,aAAa;WAChB,UAAU;eACN,OAAO;IAClB,uFAAuF;cAC7E,OAAO;IACjB,kDAAkD;gBACtC,KAAK,CAAC,SAAS;eAChB,QAAQ;gBACP,SAAS;eACV,OAAO;uBACC,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI;wCAmF1C,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { cx } from '../utils/cx.js';
|
|
5
|
+
import { Button } from './Button.js';
|
|
6
|
+
import { IconButton } from './IconButton.js';
|
|
7
|
+
import { Menu } from './Menu.js';
|
|
8
|
+
const toggleVariant = {
|
|
9
|
+
primary: 'primary',
|
|
10
|
+
// Accent has no IconButton twin; split.css paints the toggle with the accent tokens.
|
|
11
|
+
accent: 'primary',
|
|
12
|
+
secondary: 'secondary',
|
|
13
|
+
ghost: 'ghost',
|
|
14
|
+
};
|
|
15
|
+
function Chevron() {
|
|
16
|
+
return (_jsx("svg", { viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", "aria-hidden": "true", focusable: "false", children: _jsx("path", { d: "m4 6 4 4 4-4", strokeLinecap: "round", strokeLinejoin: "round" }) }));
|
|
17
|
+
}
|
|
18
|
+
export const SplitButton = React.forwardRef(function SplitButton({ label, onClick, menuLabel, children, variant = 'primary', size = 'md', disabled = false, loading = false, iconStart, menuSide = 'bottom', menuAlign = 'end', menuOpen, onMenuOpenChange, className, ...rest }, ref) {
|
|
19
|
+
const [innerOpen, setInnerOpen] = React.useState(false);
|
|
20
|
+
const open = (menuOpen ?? innerOpen) && !loading && !disabled;
|
|
21
|
+
const handleOpenChange = (next) => {
|
|
22
|
+
if (next && loading)
|
|
23
|
+
return;
|
|
24
|
+
if (menuOpen === undefined)
|
|
25
|
+
setInnerOpen(next);
|
|
26
|
+
onMenuOpenChange?.(next);
|
|
27
|
+
};
|
|
28
|
+
return (_jsxs("div", { ...rest, ref: ref, role: "group", "aria-label": label, className: cx('rl-split-button', className), "data-slot": "split-button", "data-variant": variant, "data-size": size, "data-disabled": disabled || undefined, children: [_jsx(Button, { className: "rl-split-button__main", variant: variant, size: size, disabled: disabled, loading: loading, iconStart: iconStart, onClick: onClick, children: label }), _jsx(Menu, { side: menuSide, align: menuAlign, open: open, onOpenChange: handleOpenChange, disabled: disabled, trigger: _jsx(IconButton, { className: "rl-split-button__toggle", label: menuLabel, icon: _jsx(Chevron, {}), variant: toggleVariant[variant], size: size, disabled: disabled, "aria-disabled": loading || undefined }), children: children })] }));
|
|
29
|
+
});
|
|
30
|
+
//# sourceMappingURL=SplitButton.js.map
|