@ecopages/radiant-ui 0.1.0-beta.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/README.md +70 -0
- package/dist/components/ui/alert/alert.css +27 -0
- package/dist/components/ui/alert/alert.d.ts +4 -0
- package/dist/components/ui/alert/alert.script.d.ts +25 -0
- package/dist/components/ui/alert/index.d.ts +2 -0
- package/dist/components/ui/alert/index.js +2 -0
- package/dist/components/ui/alert/index.js.map +7 -0
- package/dist/components/ui/breadcrumb/breadcrumb.css +41 -0
- package/dist/components/ui/breadcrumb/breadcrumb.d.ts +59 -0
- package/dist/components/ui/breadcrumb/breadcrumb.script.d.ts +40 -0
- package/dist/components/ui/breadcrumb/index.d.ts +2 -0
- package/dist/components/ui/breadcrumb/index.js +2 -0
- package/dist/components/ui/breadcrumb/index.js.map +7 -0
- package/dist/components/ui/button/button.d.ts +37 -0
- package/dist/components/ui/button/index.d.ts +1 -0
- package/dist/components/ui/button/index.js +2 -0
- package/dist/components/ui/button/index.js.map +7 -0
- package/dist/components/ui/carousel/carousel.css +170 -0
- package/dist/components/ui/carousel/carousel.d.ts +39 -0
- package/dist/components/ui/carousel/carousel.script.d.ts +113 -0
- package/dist/components/ui/carousel/index.d.ts +2 -0
- package/dist/components/ui/carousel/index.js +2 -0
- package/dist/components/ui/carousel/index.js.map +7 -0
- package/dist/components/ui/checkbox/checkbox.css +55 -0
- package/dist/components/ui/checkbox/checkbox.d.ts +4 -0
- package/dist/components/ui/checkbox/checkbox.script.d.ts +58 -0
- package/dist/components/ui/checkbox/index.d.ts +2 -0
- package/dist/components/ui/checkbox/index.js +2 -0
- package/dist/components/ui/checkbox/index.js.map +7 -0
- package/dist/components/ui/combobox/combobox.css +65 -0
- package/dist/components/ui/combobox/combobox.d.ts +53 -0
- package/dist/components/ui/combobox/combobox.script.d.ts +89 -0
- package/dist/components/ui/combobox/index.d.ts +2 -0
- package/dist/components/ui/combobox/index.js +2 -0
- package/dist/components/ui/combobox/index.js.map +7 -0
- package/dist/components/ui/dialog/dialog-registry.d.ts +34 -0
- package/dist/components/ui/dialog/dialog-registry.test.d.ts +1 -0
- package/dist/components/ui/dialog/dialog-types.d.ts +55 -0
- package/dist/components/ui/dialog/dialog.css +53 -0
- package/dist/components/ui/dialog/dialog.d.ts +36 -0
- package/dist/components/ui/dialog/dialog.script.d.ts +61 -0
- package/dist/components/ui/dialog/index.d.ts +4 -0
- package/dist/components/ui/dialog/index.js +2 -0
- package/dist/components/ui/dialog/index.js.map +7 -0
- package/dist/components/ui/disclosure/disclosure-group.script.d.ts +31 -0
- package/dist/components/ui/disclosure/disclosure.css +105 -0
- package/dist/components/ui/disclosure/disclosure.d.ts +35 -0
- package/dist/components/ui/disclosure/disclosure.script.d.ts +38 -0
- package/dist/components/ui/disclosure/index.d.ts +3 -0
- package/dist/components/ui/disclosure/index.js +2 -0
- package/dist/components/ui/disclosure/index.js.map +7 -0
- package/dist/components/ui/feed/feed.css +14 -0
- package/dist/components/ui/feed/feed.d.ts +12 -0
- package/dist/components/ui/feed/feed.script.d.ts +22 -0
- package/dist/components/ui/feed/index.d.ts +2 -0
- package/dist/components/ui/feed/index.js +2 -0
- package/dist/components/ui/feed/index.js.map +7 -0
- package/dist/components/ui/field/field-context.d.ts +20 -0
- package/dist/components/ui/field/field-description.d.ts +8 -0
- package/dist/components/ui/field/field-error.d.ts +9 -0
- package/dist/components/ui/field/field-ssr-hydration.test.d.ts +1 -0
- package/dist/components/ui/field/field.css +26 -0
- package/dist/components/ui/field/field.d.ts +4 -0
- package/dist/components/ui/field/field.script.d.ts +68 -0
- package/dist/components/ui/field/index.d.ts +5 -0
- package/dist/components/ui/field/index.js +2 -0
- package/dist/components/ui/field/index.js.map +7 -0
- package/dist/components/ui/form/control-protocol.d.ts +19 -0
- package/dist/components/ui/form/form-context.d.ts +27 -0
- package/dist/components/ui/form/form-field.test.d.ts +3 -0
- package/dist/components/ui/form/form-store.d.ts +53 -0
- package/dist/components/ui/form/form-store.test.d.ts +1 -0
- package/dist/components/ui/form/form.css +12 -0
- package/dist/components/ui/form/form.d.ts +5 -0
- package/dist/components/ui/form/form.script.d.ts +67 -0
- package/dist/components/ui/form/index.d.ts +7 -0
- package/dist/components/ui/form/index.js +2 -0
- package/dist/components/ui/form/index.js.map +7 -0
- package/dist/components/ui/form/resolvers.d.ts +3 -0
- package/dist/components/ui/form/types.d.ts +72 -0
- package/dist/components/ui/grid/grid.css +47 -0
- package/dist/components/ui/grid/grid.d.ts +7 -0
- package/dist/components/ui/grid/grid.script.d.ts +26 -0
- package/dist/components/ui/grid/index.d.ts +2 -0
- package/dist/components/ui/grid/index.js +2 -0
- package/dist/components/ui/grid/index.js.map +7 -0
- package/dist/components/ui/input/index.d.ts +1 -0
- package/dist/components/ui/input/index.js +2 -0
- package/dist/components/ui/input/index.js.map +7 -0
- package/dist/components/ui/input/input.css +32 -0
- package/dist/components/ui/input/input.d.ts +23 -0
- package/dist/components/ui/label/index.d.ts +1 -0
- package/dist/components/ui/label/index.js +2 -0
- package/dist/components/ui/label/index.js.map +7 -0
- package/dist/components/ui/label/label.css +8 -0
- package/dist/components/ui/label/label.d.ts +9 -0
- package/dist/components/ui/listbox/index.d.ts +2 -0
- package/dist/components/ui/listbox/index.js +2 -0
- package/dist/components/ui/listbox/index.js.map +7 -0
- package/dist/components/ui/listbox/listbox.css +23 -0
- package/dist/components/ui/listbox/listbox.d.ts +12 -0
- package/dist/components/ui/listbox/listbox.script.d.ts +40 -0
- package/dist/components/ui/menu-button/index.d.ts +2 -0
- package/dist/components/ui/menu-button/index.js +2 -0
- package/dist/components/ui/menu-button/index.js.map +7 -0
- package/dist/components/ui/menu-button/menu-button.css +43 -0
- package/dist/components/ui/menu-button/menu-button.d.ts +13 -0
- package/dist/components/ui/menu-button/menu-button.script.d.ts +64 -0
- package/dist/components/ui/menubar/index.d.ts +2 -0
- package/dist/components/ui/menubar/index.js +2 -0
- package/dist/components/ui/menubar/index.js.map +7 -0
- package/dist/components/ui/menubar/menubar.css +45 -0
- package/dist/components/ui/menubar/menubar.d.ts +16 -0
- package/dist/components/ui/menubar/menubar.script.d.ts +52 -0
- package/dist/components/ui/meter/index.d.ts +2 -0
- package/dist/components/ui/meter/index.js +2 -0
- package/dist/components/ui/meter/index.js.map +7 -0
- package/dist/components/ui/meter/meter.css +17 -0
- package/dist/components/ui/meter/meter.d.ts +4 -0
- package/dist/components/ui/meter/meter.script.d.ts +33 -0
- package/dist/components/ui/navigation-menu/index.d.ts +2 -0
- package/dist/components/ui/navigation-menu/index.js +2 -0
- package/dist/components/ui/navigation-menu/index.js.map +7 -0
- package/dist/components/ui/navigation-menu/navigation-menu.css +90 -0
- package/dist/components/ui/navigation-menu/navigation-menu.d.ts +28 -0
- package/dist/components/ui/navigation-menu/navigation-menu.script.d.ts +49 -0
- package/dist/components/ui/radio-group/index.d.ts +2 -0
- package/dist/components/ui/radio-group/index.js +2 -0
- package/dist/components/ui/radio-group/index.js.map +7 -0
- package/dist/components/ui/radio-group/radio-group.css +44 -0
- package/dist/components/ui/radio-group/radio-group.d.ts +12 -0
- package/dist/components/ui/radio-group/radio-group.script.d.ts +52 -0
- package/dist/components/ui/sidebar/index.d.ts +3 -0
- package/dist/components/ui/sidebar/index.js +2 -0
- package/dist/components/ui/sidebar/index.js.map +7 -0
- package/dist/components/ui/sidebar/sidebar-trigger.script.d.ts +53 -0
- package/dist/components/ui/sidebar/sidebar.css +362 -0
- package/dist/components/ui/sidebar/sidebar.d.ts +141 -0
- package/dist/components/ui/sidebar/sidebar.script.d.ts +140 -0
- package/dist/components/ui/sidebar/sidebar.test.d.ts +1 -0
- package/dist/components/ui/slider/index.d.ts +2 -0
- package/dist/components/ui/slider/index.js +2 -0
- package/dist/components/ui/slider/index.js.map +7 -0
- package/dist/components/ui/slider/slider.css +51 -0
- package/dist/components/ui/slider/slider.d.ts +7 -0
- package/dist/components/ui/slider/slider.script.d.ts +102 -0
- package/dist/components/ui/spinbutton/index.d.ts +2 -0
- package/dist/components/ui/spinbutton/index.js +2 -0
- package/dist/components/ui/spinbutton/index.js.map +7 -0
- package/dist/components/ui/spinbutton/spinbutton.css +19 -0
- package/dist/components/ui/spinbutton/spinbutton.d.ts +4 -0
- package/dist/components/ui/spinbutton/spinbutton.script.d.ts +64 -0
- package/dist/components/ui/switch/index.d.ts +2 -0
- package/dist/components/ui/switch/index.js +2 -0
- package/dist/components/ui/switch/index.js.map +7 -0
- package/dist/components/ui/switch/switch.css +47 -0
- package/dist/components/ui/switch/switch.d.ts +4 -0
- package/dist/components/ui/switch/switch.script.d.ts +51 -0
- package/dist/components/ui/tabs/index.d.ts +2 -0
- package/dist/components/ui/tabs/index.js +2 -0
- package/dist/components/ui/tabs/index.js.map +7 -0
- package/dist/components/ui/tabs/tabs.css +28 -0
- package/dist/components/ui/tabs/tabs.d.ts +12 -0
- package/dist/components/ui/tabs/tabs.script.d.ts +54 -0
- package/dist/components/ui/textarea/index.d.ts +1 -0
- package/dist/components/ui/textarea/index.js +2 -0
- package/dist/components/ui/textarea/index.js.map +7 -0
- package/dist/components/ui/textarea/textarea.css +33 -0
- package/dist/components/ui/textarea/textarea.d.ts +23 -0
- package/dist/components/ui/toast/index.d.ts +5 -0
- package/dist/components/ui/toast/index.js +2 -0
- package/dist/components/ui/toast/index.js.map +7 -0
- package/dist/components/ui/toast/toast-api.d.ts +29 -0
- package/dist/components/ui/toast/toast-context.d.ts +59 -0
- package/dist/components/ui/toast/toast-state.d.ts +25 -0
- package/dist/components/ui/toast/toast.css +315 -0
- package/dist/components/ui/toast/toast.d.ts +8 -0
- package/dist/components/ui/toast/toast.script.d.ts +91 -0
- package/dist/components/ui/toast/toast.test.d.ts +2 -0
- package/dist/components/ui/toast/toaster.script.d.ts +79 -0
- package/dist/components/ui/toolbar/index.d.ts +2 -0
- package/dist/components/ui/toolbar/index.js +2 -0
- package/dist/components/ui/toolbar/index.js.map +7 -0
- package/dist/components/ui/toolbar/toolbar.css +16 -0
- package/dist/components/ui/toolbar/toolbar.d.ts +4 -0
- package/dist/components/ui/toolbar/toolbar.script.d.ts +30 -0
- package/dist/components/ui/tooltip/index.d.ts +2 -0
- package/dist/components/ui/tooltip/index.js +2 -0
- package/dist/components/ui/tooltip/index.js.map +7 -0
- package/dist/components/ui/tooltip/tooltip.css +25 -0
- package/dist/components/ui/tooltip/tooltip.d.ts +4 -0
- package/dist/components/ui/tooltip/tooltip.script.d.ts +70 -0
- package/dist/components/ui/tree/index.d.ts +2 -0
- package/dist/components/ui/tree/index.js +2 -0
- package/dist/components/ui/tree/index.js.map +7 -0
- package/dist/components/ui/tree/tree.css +54 -0
- package/dist/components/ui/tree/tree.d.ts +13 -0
- package/dist/components/ui/tree/tree.script.d.ts +45 -0
- package/dist/components/ui/treegrid/index.d.ts +2 -0
- package/dist/components/ui/treegrid/index.js +2 -0
- package/dist/components/ui/treegrid/index.js.map +7 -0
- package/dist/components/ui/treegrid/treegrid.css +77 -0
- package/dist/components/ui/treegrid/treegrid.d.ts +14 -0
- package/dist/components/ui/treegrid/treegrid.script.d.ts +49 -0
- package/dist/components/ui/window-splitter/index.d.ts +2 -0
- package/dist/components/ui/window-splitter/index.js +2 -0
- package/dist/components/ui/window-splitter/index.js.map +7 -0
- package/dist/components/ui/window-splitter/window-splitter.css +35 -0
- package/dist/components/ui/window-splitter/window-splitter.d.ts +8 -0
- package/dist/components/ui/window-splitter/window-splitter.script.d.ts +49 -0
- package/dist/index.d.ts +36 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +7 -0
- package/dist/lib/focusable-elements.d.ts +2 -0
- package/dist/lib/radiant-view.d.ts +17 -0
- package/dist/lib/roving-tabindex.d.ts +27 -0
- package/dist/styles/components/button.css +115 -0
- package/dist/styles/radiant-ui-core.css +7 -0
- package/dist/styles/radiant-ui.css +10 -0
- package/dist/styles/styles.css +36 -0
- package/dist/styles/tailwind.css +41 -0
- package/dist/styles/themes/aurora.css +19 -0
- package/dist/styles/themes/default-compact-soft.css +19 -0
- package/dist/styles/themes/default.css +2 -0
- package/dist/styles/themes/glacier.css +19 -0
- package/dist/styles/tokens/colors/aurora.css +73 -0
- package/dist/styles/tokens/colors/basalt.css +36 -0
- package/dist/styles/tokens/colors/glacier.css +45 -0
- package/dist/styles/tokens/colors/palettes.css +3 -0
- package/dist/styles/tokens/elevation/default.css +22 -0
- package/dist/styles/tokens/elevation/flat.css +22 -0
- package/dist/styles/tokens/motion/default.css +19 -0
- package/dist/styles/tokens/motion/snappy.css +19 -0
- package/dist/styles/tokens/presets/colors/aurora.css +126 -0
- package/dist/styles/tokens/presets/colors/basalt.css +126 -0
- package/dist/styles/tokens/presets/colors/ember.css +134 -0
- package/dist/styles/tokens/presets/colors/glacier.css +130 -0
- package/dist/styles/tokens/presets/colors/index.css +4 -0
- package/dist/styles/tokens/presets/radius.css +45 -0
- package/dist/styles/tokens/presets/spacing.css +57 -0
- package/dist/styles/tokens/radius/default.css +34 -0
- package/dist/styles/tokens/radius/edgy.css +35 -0
- package/dist/styles/tokens/radius/sharp.css +2 -0
- package/dist/styles/tokens/radius/soft.css +34 -0
- package/dist/styles/tokens/semantic.css +80 -0
- package/dist/styles/tokens/spacing/compact.css +23 -0
- package/dist/styles/tokens/spacing/default.css +23 -0
- package/dist/styles/tokens/spacing/scale-bridge.css +17 -0
- package/dist/styles/tokens/spacing/wide.css +23 -0
- package/dist/styles/tokens/system.css +36 -0
- package/dist/styles/tokens/typography/default.css +37 -0
- package/dist/styles/utilities/sheen.css +7 -0
- package/dist/types.d.ts +14 -0
- package/package.json +371 -0
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { RadiantElement } from '@ecopages/radiant';
|
|
2
|
+
export type RuiCarouselTransition = 'none' | 'slide' | 'fade';
|
|
3
|
+
/** Where default prev/next chrome is laid out. `toolbar` places controls below the slide; `overlay` pins them to the slide edges. */
|
|
4
|
+
export type RuiCarouselControlsVariant = 'toolbar' | 'overlay';
|
|
5
|
+
export type RuiCarouselProps = {
|
|
6
|
+
label?: string;
|
|
7
|
+
index?: number;
|
|
8
|
+
autoplay?: boolean;
|
|
9
|
+
/** Autoplay interval in milliseconds. */
|
|
10
|
+
interval?: number;
|
|
11
|
+
transition?: RuiCarouselTransition;
|
|
12
|
+
/** Layout for built-in prev/next (and rotation) chrome. Default: toolbar below the slide. */
|
|
13
|
+
controlsVariant?: RuiCarouselControlsVariant;
|
|
14
|
+
showIndicators?: boolean;
|
|
15
|
+
showRotationControl?: boolean;
|
|
16
|
+
loop?: boolean;
|
|
17
|
+
/** When true, prev/next wrap and controls stay enabled at the ends. Default: true. */
|
|
18
|
+
wrap?: boolean;
|
|
19
|
+
/** Authored slide count for render-time control state before slot projection. */
|
|
20
|
+
slideCount?: number;
|
|
21
|
+
};
|
|
22
|
+
type RuiCarouselBindings = {
|
|
23
|
+
label: string;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* `<rui-carousel>` — sequentially displays one slide at a time.
|
|
27
|
+
*
|
|
28
|
+
* Implements the [APG Carousel pattern](https://www.w3.org/WAI/ARIA/apg/patterns/carousel/):
|
|
29
|
+
* labeled `carousel` region, slide groups or tab panels, optional tabbed pickers,
|
|
30
|
+
* rotation control when autoplay is enabled, and `aria-live` on the slide container.
|
|
31
|
+
*
|
|
32
|
+
* @element rui-carousel
|
|
33
|
+
* @slot prev - Optional custom previous control. Use `data-carousel-action="prev"`.
|
|
34
|
+
* @slot next - Optional custom next control. Use `data-carousel-action="next"`.
|
|
35
|
+
* @slot rotation - Optional play/pause control when `show-rotation-control` is set. Use `data-carousel-action="rotation"`.
|
|
36
|
+
*/
|
|
37
|
+
export declare class RuiCarousel extends RadiantElement<RuiCarouselBindings> {
|
|
38
|
+
label: string;
|
|
39
|
+
index: number;
|
|
40
|
+
autoplay: boolean;
|
|
41
|
+
interval: number;
|
|
42
|
+
transition: RuiCarouselTransition;
|
|
43
|
+
controlsVariant: RuiCarouselControlsVariant;
|
|
44
|
+
showIndicators: boolean;
|
|
45
|
+
showRotationControl: boolean;
|
|
46
|
+
loop: boolean;
|
|
47
|
+
wrap: boolean;
|
|
48
|
+
slideCount: number;
|
|
49
|
+
private timer;
|
|
50
|
+
private paused;
|
|
51
|
+
/** User explicitly resumed rotation (e.g. via rotation control) despite reduced motion. */
|
|
52
|
+
private userOverrideReducedMotion;
|
|
53
|
+
private swipePointerId;
|
|
54
|
+
private swipeStartX;
|
|
55
|
+
private swipeStartY;
|
|
56
|
+
connectedCallback(): void;
|
|
57
|
+
disconnectedCallback(): void;
|
|
58
|
+
onSlideStateUpdated(): void;
|
|
59
|
+
onAutoplayUpdated(): void;
|
|
60
|
+
onIndicatorsUpdated(): void;
|
|
61
|
+
private prefersReducedMotion;
|
|
62
|
+
private getCarouselId;
|
|
63
|
+
private slidePanelId;
|
|
64
|
+
private tabId;
|
|
65
|
+
private shouldShowRotationControl;
|
|
66
|
+
private syncSlideAccessibility;
|
|
67
|
+
private getSlides;
|
|
68
|
+
private get shouldWrap();
|
|
69
|
+
private normalizeIndex;
|
|
70
|
+
private sync;
|
|
71
|
+
private syncPrevNextDisabled;
|
|
72
|
+
private syncIndicators;
|
|
73
|
+
private syncRotationControl;
|
|
74
|
+
private syncAriaLive;
|
|
75
|
+
private canAutoplayRotate;
|
|
76
|
+
private syncAutoplay;
|
|
77
|
+
private start;
|
|
78
|
+
private stop;
|
|
79
|
+
private goTo;
|
|
80
|
+
private userNavigate;
|
|
81
|
+
private isSwipeExcludedTarget;
|
|
82
|
+
prev(): void;
|
|
83
|
+
next(): void;
|
|
84
|
+
toggleRotation(): void;
|
|
85
|
+
onIndicatorClick(event: Event): void;
|
|
86
|
+
onIndicatorKeydown(event: KeyboardEvent): void;
|
|
87
|
+
onRootPointerEnter(event: PointerEvent): void;
|
|
88
|
+
onRootPointerLeave(event: PointerEvent): void;
|
|
89
|
+
onRootFocusIn(): void;
|
|
90
|
+
onRootFocusOut(event: FocusEvent): void;
|
|
91
|
+
onViewportPointerDown(event: PointerEvent): void;
|
|
92
|
+
onViewportPointerMove(event: PointerEvent): void;
|
|
93
|
+
onViewportPointerUp(event: PointerEvent): void;
|
|
94
|
+
onViewportPointerCancel(event: PointerEvent): void;
|
|
95
|
+
/**
|
|
96
|
+
* Only `aria-label` is bound below. Everything else in this render() stays
|
|
97
|
+
* a plain read — audited, not an outstanding gap:
|
|
98
|
+
* - disablePrev/disableNext must apply uniformly to the default button AND
|
|
99
|
+
* any consumer-supplied `[data-carousel-action="prev"/"next"]` element
|
|
100
|
+
* slotted in (see syncPrevNextDisabled()) — a binding only patches this
|
|
101
|
+
* host's own template position, not a slotted replacement.
|
|
102
|
+
* - playing/ariaLive derive from `paused` and the live `timer` handle,
|
|
103
|
+
* plain instance fields mutated across pointer/focus/keyboard handlers
|
|
104
|
+
* and `setInterval`, not reactive members — promoting them would add an
|
|
105
|
+
* explicit notify step at every one of those call sites for no behavior
|
|
106
|
+
* change and real drift risk.
|
|
107
|
+
* - the indicator buttons are a variable-length list built with
|
|
108
|
+
* `replaceChildren()` (see syncIndicators()) — bindings patch one value
|
|
109
|
+
* at one position, they don't reconcile a dynamic list.
|
|
110
|
+
*/
|
|
111
|
+
render(): import("@ecopages/jsx").JsxRenderable;
|
|
112
|
+
}
|
|
113
|
+
export {};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export { RuiCarousel as RuiCarouselElement, type RuiCarouselProps, type RuiCarouselControlsVariant, } from './carousel.script';
|
|
2
|
+
export { RuiCarousel, RuiCarouselNext, RuiCarouselPrev, RuiCarouselRotation, RuiCarouselSlide, type RuiCarouselSlideData, type RuiCarouselSlideProps, type RuiCarouselControlProps, type RuiCarouselRotationProps, } from './carousel';
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{RadiantElement as A,customElement as I,onEvent as u,onUpdated as _,prop as d}from"@ecopages/radiant";var S=48,b=@I("rui-carousel")class extends A{@d({type:String,defaultValue:"Carousel"})label;@d({type:Number,reflect:!0,defaultValue:0})index;@d({type:Boolean,reflect:!0,defaultValue:!1})autoplay;@d({type:Number,defaultValue:4e3})interval;@d({type:String,defaultValue:"none"})transition;@d({type:String,defaultValue:"toolbar",attribute:"controls-variant"})controlsVariant;@d({type:Boolean,defaultValue:!1})showIndicators;@d({type:Boolean,defaultValue:!1})showRotationControl;@d({type:Boolean,defaultValue:!0})loop;@d({type:Boolean,defaultValue:!0})wrap;@d({type:Number,defaultValue:0})slideCount;timer=null;paused=!1;userOverrideReducedMotion=!1;swipePointerId=null;swipeStartX=0;swipeStartY=0;connectedCallback(){super.connectedCallback(),queueMicrotask(()=>{this.autoplay&&this.prefersReducedMotion()&&(this.paused=!0),this.sync(),this.syncAutoplay(),this.syncIndicators(),this.syncAriaLive()})}disconnectedCallback(){this.stop(),super.disconnectedCallback()}@_(["index","transition","loop","wrap","controlsVariant"])onSlideStateUpdated(){this.sync(),this.syncIndicators(),this.syncAutoplay()}@_(["autoplay","showRotationControl","interval"])onAutoplayUpdated(){this.syncAutoplay(),this.syncRotationControl()}@_(["showIndicators"])onIndicatorsUpdated(){this.syncIndicators()}prefersReducedMotion(){return typeof window<"u"&&typeof window.matchMedia=="function"&&window.matchMedia("(prefers-reduced-motion: reduce)").matches}getCarouselId(){return this.id||"rui-carousel"}slidePanelId(t,e){let r=t.getAttribute("data-slide")??String(e),o=`${this.getCarouselId()}-panel-${r}`;return t.id=o,o}tabId(t){return`${this.getCarouselId()}-tab-${t}`}shouldShowRotationControl(){return this.autoplay||this.showRotationControl}syncSlideAccessibility(t,e){let r=t.length;t.forEach((o,n)=>{let s=n===e,l=`${n+1} of ${r}`;this.showIndicators?(this.slidePanelId(o,n),o.setAttribute("role","tabpanel"),o.setAttribute("aria-labelledby",this.tabId(n)),o.setAttribute("aria-label",l),o.removeAttribute("aria-roledescription")):(o.setAttribute("role","group"),o.setAttribute("aria-roledescription","slide"),o.setAttribute("aria-label",l),o.removeAttribute("aria-labelledby"),o.removeAttribute("tabindex")),this.transition==="none"?o.hidden=!s:o.hidden=!1,o.setAttribute("aria-hidden",String(!s)),o.setAttribute("data-active",s?"true":"false")})}getSlides(){return Array.from(this.querySelectorAll("[data-slide]"))}get shouldWrap(){return this.wrap&&this.loop}normalizeIndex(t,e){return e<=0?0:this.shouldWrap?(t%e+e)%e:Math.min(Math.max(t,0),e-1)}sync(){let t=this.getSlides();if(!t.length)return;let e=this.normalizeIndex(this.index,t.length);e!==this.index&&(this.index=e);let r=this.querySelector(".rui-carousel__track");r&&this.transition==="slide"&&r.style.setProperty("--rui-carousel-index",String(e)),this.syncSlideAccessibility(t,e),this.syncPrevNextDisabled(t.length,e)}syncPrevNextDisabled(t,e){let r=!this.shouldWrap&&t>0&&e<=0,o=!this.shouldWrap&&t>0&&e>=t-1;for(let n of this.querySelectorAll('[data-carousel-action="prev"]'))this.shouldWrap?n.removeAttribute("disabled"):n.disabled=r;for(let n of this.querySelectorAll('[data-carousel-action="next"]'))this.shouldWrap?n.removeAttribute("disabled"):n.disabled=o}syncIndicators(){let t=this.querySelector('[data-ref="indicators"]');if(!t)return;let e=this.getSlides(),r=this.normalizeIndex(this.index,e.length);Array.from(t.querySelectorAll("[data-carousel-indicator]")).length!==e.length&&t.replaceChildren(...e.map((s,l)=>{let i=document.createElement("button");return i.type="button",i.className="rui-carousel__indicator",i.id=this.tabId(l),i.setAttribute("role","tab"),i.setAttribute("data-carousel-indicator",String(l)),i.setAttribute("aria-controls",this.slidePanelId(s,l)),i.setAttribute("aria-label",`Slide ${l+1}`),i})),Array.from(t.querySelectorAll("[data-carousel-indicator]")).forEach((s,l)=>{let i=l===r,c=e[l];c&&(s.id=this.tabId(l),s.setAttribute("aria-controls",this.slidePanelId(c,l))),s.setAttribute("aria-selected",String(i)),s.tabIndex=i?0:-1})}syncRotationControl(){for(let t of this.querySelectorAll('[data-carousel-action="rotation"]')){let e=this.autoplay&&!this.paused;t.setAttribute("aria-pressed",String(e)),t.setAttribute("aria-label",e?"Pause rotation":"Start rotation")}}syncAriaLive(){let t=this.querySelector('[data-ref="viewport"]');if(!t)return;let e=this.autoplay&&!this.paused&&this.timer!==null;t.setAttribute("aria-live",e?"off":"polite"),t.setAttribute("aria-atomic","false")}canAutoplayRotate(){return!(!this.autoplay||this.paused||this.prefersReducedMotion()&&!this.userOverrideReducedMotion)}syncAutoplay(){this.canAutoplayRotate()?this.start():this.stop(),this.syncRotationControl(),this.syncAriaLive()}start(){let t=this.getSlides();if(!t.length)return;if(!this.shouldWrap&&this.index>=t.length-1){this.stop();return}this.stop();let e=Math.max(0,this.interval);this.timer=setInterval(()=>{let r=this.getSlides();if(r.length){if(!this.shouldWrap&&this.index>=r.length-1){this.stop(),this.syncAriaLive();return}this.goTo(this.index+1)}},e),this.syncAriaLive()}stop(){this.timer&&clearInterval(this.timer),this.timer=null,this.syncAriaLive()}goTo(t){let e=this.getSlides();e.length&&(this.index=this.normalizeIndex(t,e.length),this.sync(),this.syncIndicators())}userNavigate(t){this.paused=!0,this.stop(),this.goTo(this.index+t)}isSwipeExcludedTarget(t){return t instanceof Element?!!t.closest("button, a, input, textarea, select, [data-carousel-indicator], [data-carousel-action]"):!1}@u({selector:'[data-carousel-action="prev"]',type:"click"})prev(){this.userNavigate(-1)}@u({selector:'[data-carousel-action="next"]',type:"click"})next(){this.userNavigate(1)}@u({selector:'[data-carousel-action="rotation"]',type:"click"})toggleRotation(){this.autoplay?(this.paused=!this.paused,this.paused||(this.userOverrideReducedMotion=!0)):(this.autoplay=!0,this.paused=!1,this.userOverrideReducedMotion=!0),this.syncAutoplay()}@u({selector:"[data-carousel-indicator]",type:"click"})onIndicatorClick(t){let e=t.target.closest("[data-carousel-indicator]");if(!e)return;let r=Number(e.getAttribute("data-carousel-indicator"));Number.isFinite(r)&&(this.paused=!0,this.stop(),this.goTo(r),e.focus())}@u({selector:"[data-carousel-indicator]",type:"keydown"})onIndicatorKeydown(t){let e=this.getSlides();if(!e.length)return;let r=t.target.closest("[data-carousel-indicator]");if(!r)return;let o=Number(r.getAttribute("data-carousel-indicator"));if(!Number.isFinite(o))return;if(t.key==="ArrowRight")o=this.normalizeIndex(o+1,e.length);else if(t.key==="ArrowLeft")o=this.normalizeIndex(o-1,e.length);else if(t.key==="Home")o=0;else if(t.key==="End")o=e.length-1;else if(t.key===" "||t.key==="Enter"){t.preventDefault(),this.paused=!0,this.stop(),this.goTo(o);return}else return;t.preventDefault(),this.paused=!0,this.stop(),this.goTo(o),Array.from(this.querySelectorAll('[data-ref="indicators"] [data-carousel-indicator]'))[o]?.focus()}@u({ref:"root",type:"pointerenter"})onRootPointerEnter(t){this.autoplay&&t.pointerType==="mouse"&&this.stop()}@u({ref:"root",type:"pointerleave"})onRootPointerLeave(t){this.autoplay&&!this.paused&&t.pointerType==="mouse"&&this.syncAutoplay()}@u({ref:"root",type:"focusin"})onRootFocusIn(){this.autoplay&&this.stop()}@u({ref:"root",type:"focusout"})onRootFocusOut(t){let e=t.relatedTarget;e&&this.contains(e)||this.autoplay&&!this.paused&&this.syncAutoplay()}@u({ref:"viewport",type:"pointerdown"})onViewportPointerDown(t){t.button!==0||this.isSwipeExcludedTarget(t.target)||(this.swipePointerId=t.pointerId,this.swipeStartX=t.clientX,this.swipeStartY=t.clientY)}@u({ref:"viewport",type:"pointermove"})onViewportPointerMove(t){this.swipePointerId,t.pointerId}@u({ref:"viewport",type:"pointerup"})onViewportPointerUp(t){if(this.swipePointerId!==t.pointerId)return;let e=t.clientX-this.swipeStartX,r=t.clientY-this.swipeStartY;this.swipePointerId=null,!(Math.abs(e)<S||Math.abs(e)<=Math.abs(r))&&(e<0?this.next():this.prev())}@u({ref:"viewport",type:"pointercancel"})onViewportPointerCancel(t){this.swipePointerId===t.pointerId&&(this.swipePointerId=null)}render(){let t=this.shouldShowRotationControl(),e=Math.max(this.getSlides().length,this.slideCount),r=this.normalizeIndex(this.index,e||1),o=!this.shouldWrap&&e>0&&r<=0,n=!this.shouldWrap&&e>0&&r>=e-1,s=this.autoplay&&!this.paused,l=s&&this.timer!==null?"off":"polite",i=this.controlsVariant==="overlay";queueMicrotask(()=>{this.sync(),this.syncIndicators(),this.syncRotationControl(),this.syncAriaLive()});let c=React.createElement("slot",{name:"prev"},React.createElement("button",{type:"button","data-carousel-action":"prev","data-ref":"prev",class:`rui-carousel__nav rui-button rui-button--outline rui-button--sm${i?" rui-carousel__nav--overlay":" rui-carousel__nav--toolbar"}`,"aria-label":"Previous slide",disabled:o},i?React.createElement("span",{class:"rui-carousel__nav-icon","aria-hidden":"true"},"\u2039"):React.createElement("span",{class:"rui-carousel__nav-label"},React.createElement("span",{class:"rui-carousel__nav-icon","aria-hidden":"true"},"\u2039"),"Previous"))),p=React.createElement("slot",{name:"next"},React.createElement("button",{type:"button","data-carousel-action":"next","data-ref":"next",class:`rui-carousel__nav rui-button rui-button--outline rui-button--sm${i?" rui-carousel__nav--overlay":" rui-carousel__nav--toolbar"}`,"aria-label":"Next slide",disabled:n},i?React.createElement("span",{class:"rui-carousel__nav-icon","aria-hidden":"true"},"\u203A"):React.createElement("span",{class:"rui-carousel__nav-label"},"Next",React.createElement("span",{class:"rui-carousel__nav-icon","aria-hidden":"true"},"\u203A")))),v=t?React.createElement("slot",{name:"rotation"},React.createElement("button",{type:"button","data-carousel-action":"rotation","data-ref":"rotation",class:`rui-carousel__rotation rui-button rui-button--ghost rui-button--sm${i?" rui-carousel__rotation--overlay":""}`,"aria-pressed":s,"aria-label":s?"Pause rotation":"Start rotation"},s?"Pause":"Play")):null,h=this.showIndicators?React.createElement("div",{class:`rui-carousel__indicators${i?" rui-carousel__indicators--overlay":""}`,"data-ref":"indicators",role:"tablist","aria-label":"Choose slide to display"}):null,y=React.createElement("div",{class:"rui-carousel__toolbar"},t?React.createElement("div",{class:"rui-carousel__toolbar-rotation"},v):null,React.createElement("div",{class:"rui-carousel__toolbar-side rui-carousel__toolbar-side--start"},c),React.createElement("div",{class:"rui-carousel__toolbar-center"},h),React.createElement("div",{class:"rui-carousel__toolbar-side rui-carousel__toolbar-side--end"},p)),f=i?React.createElement("div",{class:"rui-carousel__overlay-chrome"},t?React.createElement("div",{class:"rui-carousel__overlay-rotation"},v):null,React.createElement("div",{class:"rui-carousel__controls rui-carousel__controls--overlay"},c,p),h):null;return React.createElement("section",{class:`rui-carousel rui-carousel--${this.transition} rui-carousel--controls-${this.controlsVariant}`,"data-ref":"root","aria-roledescription":"carousel","aria-label":this.$.label},React.createElement("div",{class:"rui-carousel__stage"},React.createElement("div",{class:"rui-carousel__viewport","data-ref":"viewport","aria-live":l,"aria-atomic":!1},React.createElement("div",{class:"rui-carousel__track",style:this.transition==="slide"?{"--rui-carousel-index":String(this.index)}:void 0},React.createElement("slot",null)),f)),i?null:React.createElement("div",{class:"rui-carousel__footer"},y))}};var P=Symbol.for("@ecopages/storybook-radiant.viewElement"),R=Symbol.for("@ecopages/storybook-radiant.scriptModule"),g=Symbol.for("@ecopages/storybook-radiant.scriptExport");function T(a,t){a[P]=t;let e=t[R];e&&(a[R]=e,a[g]=t[g]??t.name)}function C(a,t){let e=(r=>t(r));return T(e,a),e}import"./carousel.css";function m(...a){return a.filter(Boolean).join(" ")}function x({id:a,children:t,class:e}){return React.createElement("div",{class:m("rui-carousel__slide",e),"data-slide":a},t)}function w(){return React.createElement("span",{class:"rui-carousel__nav-label"},React.createElement("span",{class:"rui-carousel__nav-icon","aria-hidden":"true"},"\u2039"),"Previous")}function E(){return React.createElement("span",{class:"rui-carousel__nav-label"},"Next",React.createElement("span",{class:"rui-carousel__nav-icon","aria-hidden":"true"},"\u203A"))}function M({slot:a="prev",children:t,class:e,disabled:r,overlay:o}){return React.createElement("button",{slot:a,type:"button","data-carousel-action":"prev","data-ref":"prev",class:m("rui-carousel__nav rui-button rui-button--outline rui-button--sm",o?"rui-carousel__nav--overlay":"rui-carousel__nav--toolbar",e),"aria-label":"Previous slide",disabled:r},t??(o?React.createElement("span",{class:"rui-carousel__nav-icon","aria-hidden":"true"},"\u2039"):w()))}function L({slot:a="next",children:t,class:e,disabled:r,overlay:o}){return React.createElement("button",{slot:a,type:"button","data-carousel-action":"next","data-ref":"next",class:m("rui-carousel__nav rui-button rui-button--outline rui-button--sm",o?"rui-carousel__nav--overlay":"rui-carousel__nav--toolbar",e),"aria-label":"Next slide",disabled:r},t??(o?React.createElement("span",{class:"rui-carousel__nav-icon","aria-hidden":"true"},"\u203A"):E()))}function V({slot:a="rotation",children:t,class:e,overlay:r}){return React.createElement("button",{slot:a,type:"button","data-carousel-action":"rotation","data-ref":"rotation",class:m("rui-carousel__rotation rui-button rui-button--ghost rui-button--sm",r&&"rui-carousel__rotation--overlay",e),"aria-pressed":!1,"aria-label":"Start rotation"},t??"Play")}var N=C(b,({slot:a,label:t,index:e,autoplay:r,interval:o,transition:n,controlsVariant:s,showIndicators:l,showRotationControl:i,loop:c,wrap:p,slides:v,children:h})=>{if(h!=null)return React.createElement("rui-carousel",{slot:a,label:t,index:e,autoplay:r,interval:o,transition:n,controlsVariant:s,showIndicators:l,showRotationControl:i,loop:c,wrap:p},h);let y=v??[];return React.createElement("rui-carousel",{slot:a,label:t,index:e,autoplay:r,interval:o,transition:n,controlsVariant:s,showIndicators:l,showRotationControl:i,loop:c,wrap:p,slideCount:y.length},y.map(f=>React.createElement(x,{id:f.id},f.children)))});export{N as RuiCarousel,b as RuiCarouselElement,L as RuiCarouselNext,M as RuiCarouselPrev,V as RuiCarouselRotation,x as RuiCarouselSlide};
|
|
2
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/components/ui/carousel/carousel.script.tsx", "../../../../src/lib/radiant-view.ts", "../../../../src/components/ui/carousel/carousel.tsx"],
|
|
4
|
+
"sourcesContent": ["import { RadiantElement, customElement, onEvent, onUpdated, prop } from '@ecopages/radiant';\n\nexport type RuiCarouselTransition = 'none' | 'slide' | 'fade';\n\n/** Where default prev/next chrome is laid out. `toolbar` places controls below the slide; `overlay` pins them to the slide edges. */\nexport type RuiCarouselControlsVariant = 'toolbar' | 'overlay';\n\nexport type RuiCarouselProps = {\n\tlabel?: string;\n\tindex?: number;\n\tautoplay?: boolean;\n\t/** Autoplay interval in milliseconds. */\n\tinterval?: number;\n\ttransition?: RuiCarouselTransition;\n\t/** Layout for built-in prev/next (and rotation) chrome. Default: toolbar below the slide. */\n\tcontrolsVariant?: RuiCarouselControlsVariant;\n\tshowIndicators?: boolean;\n\tshowRotationControl?: boolean;\n\tloop?: boolean;\n\t/** When true, prev/next wrap and controls stay enabled at the ends. Default: true. */\n\twrap?: boolean;\n\t/** Authored slide count for render-time control state before slot projection. */\n\tslideCount?: number;\n};\n\nconst SWIPE_THRESHOLD_PX = 48;\n\ntype RuiCarouselBindings = {\n\tlabel: string;\n};\n\n/**\n * `<rui-carousel>` \u2014 sequentially displays one slide at a time.\n *\n * Implements the [APG Carousel pattern](https://www.w3.org/WAI/ARIA/apg/patterns/carousel/):\n * labeled `carousel` region, slide groups or tab panels, optional tabbed pickers,\n * rotation control when autoplay is enabled, and `aria-live` on the slide container.\n *\n * @element rui-carousel\n * @slot prev - Optional custom previous control. Use `data-carousel-action=\"prev\"`.\n * @slot next - Optional custom next control. Use `data-carousel-action=\"next\"`.\n * @slot rotation - Optional play/pause control when `show-rotation-control` is set. Use `data-carousel-action=\"rotation\"`.\n */\n@customElement('rui-carousel')\nexport class RuiCarousel extends RadiantElement<RuiCarouselBindings> {\n\t@prop({ type: String, defaultValue: 'Carousel' }) label: string;\n\t@prop({ type: Number, reflect: true, defaultValue: 0 }) index: number;\n\t@prop({ type: Boolean, reflect: true, defaultValue: false }) autoplay: boolean;\n\t@prop({ type: Number, defaultValue: 4000 }) interval: number;\n\t@prop({ type: String, defaultValue: 'none' }) transition: RuiCarouselTransition;\n\t@prop({ type: String, defaultValue: 'toolbar', attribute: 'controls-variant' })\n\tcontrolsVariant: RuiCarouselControlsVariant;\n\t@prop({ type: Boolean, defaultValue: false }) showIndicators: boolean;\n\t@prop({ type: Boolean, defaultValue: false }) showRotationControl: boolean;\n\t@prop({ type: Boolean, defaultValue: true }) loop: boolean;\n\t@prop({ type: Boolean, defaultValue: true }) wrap: boolean;\n\t@prop({ type: Number, defaultValue: 0 }) slideCount: number;\n\n\tprivate timer: ReturnType<typeof setInterval> | null = null;\n\tprivate paused = false;\n\t/** User explicitly resumed rotation (e.g. via rotation control) despite reduced motion. */\n\tprivate userOverrideReducedMotion = false;\n\tprivate swipePointerId: number | null = null;\n\tprivate swipeStartX = 0;\n\tprivate swipeStartY = 0;\n\n\toverride connectedCallback(): void {\n\t\tsuper.connectedCallback();\n\t\tqueueMicrotask(() => {\n\t\t\tif (this.autoplay && this.prefersReducedMotion()) {\n\t\t\t\tthis.paused = true;\n\t\t\t}\n\t\t\tthis.sync();\n\t\t\tthis.syncAutoplay();\n\t\t\tthis.syncIndicators();\n\t\t\tthis.syncAriaLive();\n\t\t});\n\t}\n\n\toverride disconnectedCallback(): void {\n\t\tthis.stop();\n\t\tsuper.disconnectedCallback();\n\t}\n\n\t@onUpdated(['index', 'transition', 'loop', 'wrap', 'controlsVariant'])\n\tonSlideStateUpdated(): void {\n\t\tthis.sync();\n\t\tthis.syncIndicators();\n\t\tthis.syncAutoplay();\n\t}\n\n\t@onUpdated(['autoplay', 'showRotationControl', 'interval'])\n\tonAutoplayUpdated(): void {\n\t\tthis.syncAutoplay();\n\t\tthis.syncRotationControl();\n\t}\n\n\t@onUpdated(['showIndicators'])\n\tonIndicatorsUpdated(): void {\n\t\tthis.syncIndicators();\n\t}\n\n\tprivate prefersReducedMotion(): boolean {\n\t\treturn (\n\t\t\ttypeof window !== 'undefined' &&\n\t\t\ttypeof window.matchMedia === 'function' &&\n\t\t\twindow.matchMedia('(prefers-reduced-motion: reduce)').matches\n\t\t);\n\t}\n\n\tprivate getCarouselId(): string {\n\t\treturn this.id || 'rui-carousel';\n\t}\n\n\tprivate slidePanelId(slide: HTMLElement, index: number): string {\n\t\tconst key = slide.getAttribute('data-slide') ?? String(index);\n\t\tconst panelId = `${this.getCarouselId()}-panel-${key}`;\n\t\tslide.id = panelId;\n\t\treturn panelId;\n\t}\n\n\tprivate tabId(index: number): string {\n\t\treturn `${this.getCarouselId()}-tab-${index}`;\n\t}\n\n\tprivate shouldShowRotationControl(): boolean {\n\t\treturn this.autoplay || this.showRotationControl;\n\t}\n\n\tprivate syncSlideAccessibility(slides: HTMLElement[], activeIndex: number): void {\n\t\tconst count = slides.length;\n\n\t\tslides.forEach((slide, i) => {\n\t\t\tconst active = i === activeIndex;\n\t\t\tconst positionLabel = `${i + 1} of ${count}`;\n\n\t\t\tif (this.showIndicators) {\n\t\t\t\tthis.slidePanelId(slide, i);\n\t\t\t\tslide.setAttribute('role', 'tabpanel');\n\t\t\t\tslide.setAttribute('aria-labelledby', this.tabId(i));\n\t\t\t\tslide.setAttribute('aria-label', positionLabel);\n\t\t\t\tslide.removeAttribute('aria-roledescription');\n\t\t\t} else {\n\t\t\t\tslide.setAttribute('role', 'group');\n\t\t\t\tslide.setAttribute('aria-roledescription', 'slide');\n\t\t\t\tslide.setAttribute('aria-label', positionLabel);\n\t\t\t\tslide.removeAttribute('aria-labelledby');\n\t\t\t\tslide.removeAttribute('tabindex');\n\t\t\t}\n\n\t\t\tif (this.transition === 'none') {\n\t\t\t\tslide.hidden = !active;\n\t\t\t} else {\n\t\t\t\tslide.hidden = false;\n\t\t\t}\n\n\t\t\tslide.setAttribute('aria-hidden', String(!active));\n\t\t\tslide.setAttribute('data-active', active ? 'true' : 'false');\n\t\t});\n\t}\n\n\tprivate getSlides(): HTMLElement[] {\n\t\treturn Array.from(this.querySelectorAll<HTMLElement>('[data-slide]'));\n\t}\n\n\tprivate get shouldWrap(): boolean {\n\t\treturn this.wrap && this.loop;\n\t}\n\n\tprivate normalizeIndex(raw: number, count: number): number {\n\t\tif (count <= 0) {\n\t\t\treturn 0;\n\t\t}\n\n\t\tif (!this.shouldWrap) {\n\t\t\treturn Math.min(Math.max(raw, 0), count - 1);\n\t\t}\n\n\t\treturn ((raw % count) + count) % count;\n\t}\n\n\tprivate sync(): void {\n\t\tconst slides = this.getSlides();\n\t\tif (!slides.length) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst normalized = this.normalizeIndex(this.index, slides.length);\n\t\tif (normalized !== this.index) {\n\t\t\tthis.index = normalized;\n\t\t}\n\n\t\tconst track = this.querySelector<HTMLElement>('.rui-carousel__track');\n\t\tif (track && this.transition === 'slide') {\n\t\t\ttrack.style.setProperty('--rui-carousel-index', String(normalized));\n\t\t}\n\n\t\tthis.syncSlideAccessibility(slides, normalized);\n\n\t\tthis.syncPrevNextDisabled(slides.length, normalized);\n\t}\n\n\tprivate syncPrevNextDisabled(count: number, normalized: number): void {\n\t\tconst disablePrev = !this.shouldWrap && count > 0 && normalized <= 0;\n\t\tconst disableNext = !this.shouldWrap && count > 0 && normalized >= count - 1;\n\n\t\tfor (const button of this.querySelectorAll<HTMLButtonElement>('[data-carousel-action=\"prev\"]')) {\n\t\t\tif (this.shouldWrap) {\n\t\t\t\tbutton.removeAttribute('disabled');\n\t\t\t} else {\n\t\t\t\tbutton.disabled = disablePrev;\n\t\t\t}\n\t\t}\n\n\t\tfor (const button of this.querySelectorAll<HTMLButtonElement>('[data-carousel-action=\"next\"]')) {\n\t\t\tif (this.shouldWrap) {\n\t\t\t\tbutton.removeAttribute('disabled');\n\t\t\t} else {\n\t\t\t\tbutton.disabled = disableNext;\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate syncIndicators(): void {\n\t\tconst container = this.querySelector<HTMLElement>('[data-ref=\"indicators\"]');\n\t\tif (!container) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst slides = this.getSlides();\n\t\tconst normalized = this.normalizeIndex(this.index, slides.length);\n\t\tconst existing = Array.from(container.querySelectorAll<HTMLButtonElement>('[data-carousel-indicator]'));\n\n\t\tif (existing.length !== slides.length) {\n\t\t\tcontainer.replaceChildren(\n\t\t\t\t...slides.map((slide, i) => {\n\t\t\t\t\tconst button = document.createElement('button');\n\t\t\t\t\tbutton.type = 'button';\n\t\t\t\t\tbutton.className = 'rui-carousel__indicator';\n\t\t\t\t\tbutton.id = this.tabId(i);\n\t\t\t\t\tbutton.setAttribute('role', 'tab');\n\t\t\t\t\tbutton.setAttribute('data-carousel-indicator', String(i));\n\t\t\t\t\tbutton.setAttribute('aria-controls', this.slidePanelId(slide, i));\n\t\t\t\t\tbutton.setAttribute('aria-label', `Slide ${i + 1}`);\n\t\t\t\t\treturn button;\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\n\t\tconst indicators = Array.from(container.querySelectorAll<HTMLButtonElement>('[data-carousel-indicator]'));\n\t\tindicators.forEach((indicator, i) => {\n\t\t\tconst selected = i === normalized;\n\t\t\tconst slide = slides[i];\n\t\t\tif (slide) {\n\t\t\t\tindicator.id = this.tabId(i);\n\t\t\t\tindicator.setAttribute('aria-controls', this.slidePanelId(slide, i));\n\t\t\t}\n\t\t\tindicator.setAttribute('aria-selected', String(selected));\n\t\t\tindicator.tabIndex = selected ? 0 : -1;\n\t\t});\n\t}\n\n\tprivate syncRotationControl(): void {\n\t\tfor (const toggle of this.querySelectorAll<HTMLButtonElement>('[data-carousel-action=\"rotation\"]')) {\n\t\t\tconst playing = this.autoplay && !this.paused;\n\t\t\ttoggle.setAttribute('aria-pressed', String(playing));\n\t\t\ttoggle.setAttribute('aria-label', playing ? 'Pause rotation' : 'Start rotation');\n\t\t}\n\t}\n\n\tprivate syncAriaLive(): void {\n\t\tconst viewport = this.querySelector<HTMLElement>('[data-ref=\"viewport\"]');\n\t\tif (!viewport) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst rotating = this.autoplay && !this.paused && this.timer !== null;\n\t\tviewport.setAttribute('aria-live', rotating ? 'off' : 'polite');\n\t\tviewport.setAttribute('aria-atomic', 'false');\n\t}\n\n\tprivate canAutoplayRotate(): boolean {\n\t\tif (!this.autoplay || this.paused) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif (this.prefersReducedMotion() && !this.userOverrideReducedMotion) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t}\n\n\tprivate syncAutoplay(): void {\n\t\tif (this.canAutoplayRotate()) {\n\t\t\tthis.start();\n\t\t} else {\n\t\t\tthis.stop();\n\t\t}\n\n\t\tthis.syncRotationControl();\n\t\tthis.syncAriaLive();\n\t}\n\n\tprivate start(): void {\n\t\tconst slides = this.getSlides();\n\t\tif (!slides.length) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (!this.shouldWrap && this.index >= slides.length - 1) {\n\t\t\tthis.stop();\n\t\t\treturn;\n\t\t}\n\n\t\tthis.stop();\n\t\tconst ms = Math.max(0, this.interval);\n\t\tthis.timer = setInterval(() => {\n\t\t\tconst currentSlides = this.getSlides();\n\t\t\tif (!currentSlides.length) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (!this.shouldWrap && this.index >= currentSlides.length - 1) {\n\t\t\t\tthis.stop();\n\t\t\t\tthis.syncAriaLive();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis.goTo(this.index + 1);\n\t\t}, ms);\n\t\tthis.syncAriaLive();\n\t}\n\n\tprivate stop(): void {\n\t\tif (this.timer) {\n\t\t\tclearInterval(this.timer);\n\t\t}\n\n\t\tthis.timer = null;\n\t\tthis.syncAriaLive();\n\t}\n\n\tprivate goTo(next: number): void {\n\t\tconst slides = this.getSlides();\n\t\tif (!slides.length) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.index = this.normalizeIndex(next, slides.length);\n\t\tthis.sync();\n\t\tthis.syncIndicators();\n\t}\n\n\tprivate userNavigate(delta: number): void {\n\t\tthis.paused = true;\n\t\tthis.stop();\n\t\tthis.goTo(this.index + delta);\n\t}\n\n\tprivate isSwipeExcludedTarget(target: EventTarget | null): boolean {\n\t\tif (!(target instanceof Element)) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn Boolean(\n\t\t\ttarget.closest('button, a, input, textarea, select, [data-carousel-indicator], [data-carousel-action]'),\n\t\t);\n\t}\n\n\t@onEvent({ selector: '[data-carousel-action=\"prev\"]', type: 'click' })\n\tprev(): void {\n\t\tthis.userNavigate(-1);\n\t}\n\n\t@onEvent({ selector: '[data-carousel-action=\"next\"]', type: 'click' })\n\tnext(): void {\n\t\tthis.userNavigate(1);\n\t}\n\n\t@onEvent({ selector: '[data-carousel-action=\"rotation\"]', type: 'click' })\n\ttoggleRotation(): void {\n\t\tif (!this.autoplay) {\n\t\t\tthis.autoplay = true;\n\t\t\tthis.paused = false;\n\t\t\tthis.userOverrideReducedMotion = true;\n\t\t} else {\n\t\t\tthis.paused = !this.paused;\n\t\t\tif (!this.paused) {\n\t\t\t\tthis.userOverrideReducedMotion = true;\n\t\t\t}\n\t\t}\n\n\t\tthis.syncAutoplay();\n\t}\n\n\t@onEvent({ selector: '[data-carousel-indicator]', type: 'click' })\n\tonIndicatorClick(event: Event): void {\n\t\tconst button = (event.target as HTMLElement).closest<HTMLButtonElement>('[data-carousel-indicator]');\n\t\tif (!button) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst indicatorIndex = Number(button.getAttribute('data-carousel-indicator'));\n\t\tif (!Number.isFinite(indicatorIndex)) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.paused = true;\n\t\tthis.stop();\n\t\tthis.goTo(indicatorIndex);\n\t\tbutton.focus();\n\t}\n\n\t@onEvent({ selector: '[data-carousel-indicator]', type: 'keydown' })\n\tonIndicatorKeydown(event: KeyboardEvent): void {\n\t\tconst slides = this.getSlides();\n\t\tif (!slides.length) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst current = (event.target as HTMLElement).closest<HTMLButtonElement>('[data-carousel-indicator]');\n\t\tif (!current) {\n\t\t\treturn;\n\t\t}\n\n\t\tlet nextIndex = Number(current.getAttribute('data-carousel-indicator'));\n\t\tif (!Number.isFinite(nextIndex)) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (event.key === 'ArrowRight') {\n\t\t\tnextIndex = this.normalizeIndex(nextIndex + 1, slides.length);\n\t\t} else if (event.key === 'ArrowLeft') {\n\t\t\tnextIndex = this.normalizeIndex(nextIndex - 1, slides.length);\n\t\t} else if (event.key === 'Home') {\n\t\t\tnextIndex = 0;\n\t\t} else if (event.key === 'End') {\n\t\t\tnextIndex = slides.length - 1;\n\t\t} else if (event.key === ' ' || event.key === 'Enter') {\n\t\t\tevent.preventDefault();\n\t\t\tthis.paused = true;\n\t\t\tthis.stop();\n\t\t\tthis.goTo(nextIndex);\n\t\t\treturn;\n\t\t} else {\n\t\t\treturn;\n\t\t}\n\n\t\tevent.preventDefault();\n\t\tthis.paused = true;\n\t\tthis.stop();\n\t\tthis.goTo(nextIndex);\n\n\t\tconst indicators = Array.from(\n\t\t\tthis.querySelectorAll<HTMLButtonElement>('[data-ref=\"indicators\"] [data-carousel-indicator]'),\n\t\t);\n\t\tindicators[nextIndex]?.focus();\n\t}\n\n\t@onEvent({ ref: 'root', type: 'pointerenter' })\n\tonRootPointerEnter(event: PointerEvent): void {\n\t\tif (this.autoplay && event.pointerType === 'mouse') {\n\t\t\tthis.stop();\n\t\t}\n\t}\n\n\t@onEvent({ ref: 'root', type: 'pointerleave' })\n\tonRootPointerLeave(event: PointerEvent): void {\n\t\tif (this.autoplay && !this.paused && event.pointerType === 'mouse') {\n\t\t\tthis.syncAutoplay();\n\t\t}\n\t}\n\n\t@onEvent({ ref: 'root', type: 'focusin' })\n\tonRootFocusIn(): void {\n\t\tif (this.autoplay) {\n\t\t\tthis.stop();\n\t\t}\n\t}\n\n\t@onEvent({ ref: 'root', type: 'focusout' })\n\tonRootFocusOut(event: FocusEvent): void {\n\t\tconst next = event.relatedTarget as Node | null;\n\t\tif (next && this.contains(next)) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.autoplay && !this.paused) {\n\t\t\tthis.syncAutoplay();\n\t\t}\n\t}\n\n\t@onEvent({ ref: 'viewport', type: 'pointerdown' })\n\tonViewportPointerDown(event: PointerEvent): void {\n\t\tif (event.button !== 0 || this.isSwipeExcludedTarget(event.target)) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.swipePointerId = event.pointerId;\n\t\tthis.swipeStartX = event.clientX;\n\t\tthis.swipeStartY = event.clientY;\n\t}\n\n\t@onEvent({ ref: 'viewport', type: 'pointermove' })\n\tonViewportPointerMove(event: PointerEvent): void {\n\t\tif (this.swipePointerId !== event.pointerId) {\n\t\t\treturn;\n\t\t}\n\t}\n\n\t@onEvent({ ref: 'viewport', type: 'pointerup' })\n\tonViewportPointerUp(event: PointerEvent): void {\n\t\tif (this.swipePointerId !== event.pointerId) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst dx = event.clientX - this.swipeStartX;\n\t\tconst dy = event.clientY - this.swipeStartY;\n\t\tthis.swipePointerId = null;\n\n\t\tif (Math.abs(dx) < SWIPE_THRESHOLD_PX || Math.abs(dx) <= Math.abs(dy)) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (dx < 0) {\n\t\t\tthis.next();\n\t\t} else {\n\t\t\tthis.prev();\n\t\t}\n\t}\n\n\t@onEvent({ ref: 'viewport', type: 'pointercancel' })\n\tonViewportPointerCancel(event: PointerEvent): void {\n\t\tif (this.swipePointerId === event.pointerId) {\n\t\t\tthis.swipePointerId = null;\n\t\t}\n\t}\n\n\t/**\n\t * Only `aria-label` is bound below. Everything else in this render() stays\n\t * a plain read \u2014 audited, not an outstanding gap:\n\t * - disablePrev/disableNext must apply uniformly to the default button AND\n\t * any consumer-supplied `[data-carousel-action=\"prev\"/\"next\"]` element\n\t * slotted in (see syncPrevNextDisabled()) \u2014 a binding only patches this\n\t * host's own template position, not a slotted replacement.\n\t * - playing/ariaLive derive from `paused` and the live `timer` handle,\n\t * plain instance fields mutated across pointer/focus/keyboard handlers\n\t * and `setInterval`, not reactive members \u2014 promoting them would add an\n\t * explicit notify step at every one of those call sites for no behavior\n\t * change and real drift risk.\n\t * - the indicator buttons are a variable-length list built with\n\t * `replaceChildren()` (see syncIndicators()) \u2014 bindings patch one value\n\t * at one position, they don't reconcile a dynamic list.\n\t */\n\toverride render() {\n\t\tconst showRotation = this.shouldShowRotationControl();\n\t\tconst slideCount = Math.max(this.getSlides().length, this.slideCount);\n\t\tconst normalized = this.normalizeIndex(this.index, slideCount || 1);\n\t\tconst disablePrev = !this.shouldWrap && slideCount > 0 && normalized <= 0;\n\t\tconst disableNext = !this.shouldWrap && slideCount > 0 && normalized >= slideCount - 1;\n\t\tconst playing = this.autoplay && !this.paused;\n\t\tconst ariaLive = playing && this.timer !== null ? 'off' : 'polite';\n\t\tconst overlay = this.controlsVariant === 'overlay';\n\n\t\tqueueMicrotask(() => {\n\t\t\tthis.sync();\n\t\t\tthis.syncIndicators();\n\t\t\tthis.syncRotationControl();\n\t\t\tthis.syncAriaLive();\n\t\t});\n\n\t\tconst prevControl = (\n\t\t\t<slot name=\"prev\">\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tdata-carousel-action=\"prev\"\n\t\t\t\t\tdata-ref=\"prev\"\n\t\t\t\t\tclass={`rui-carousel__nav rui-button rui-button--outline rui-button--sm${overlay ? ' rui-carousel__nav--overlay' : ' rui-carousel__nav--toolbar'}`}\n\t\t\t\t\taria-label=\"Previous slide\"\n\t\t\t\t\tdisabled={disablePrev}\n\t\t\t\t>\n\t\t\t\t\t{overlay ? (\n\t\t\t\t\t\t<span class=\"rui-carousel__nav-icon\" aria-hidden=\"true\">\n\t\t\t\t\t\t\t\u2039\n\t\t\t\t\t\t</span>\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<span class=\"rui-carousel__nav-label\">\n\t\t\t\t\t\t\t<span class=\"rui-carousel__nav-icon\" aria-hidden=\"true\">\n\t\t\t\t\t\t\t\t\u2039\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\tPrevious\n\t\t\t\t\t\t</span>\n\t\t\t\t\t)}\n\t\t\t\t</button>\n\t\t\t</slot>\n\t\t);\n\n\t\tconst nextControl = (\n\t\t\t<slot name=\"next\">\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tdata-carousel-action=\"next\"\n\t\t\t\t\tdata-ref=\"next\"\n\t\t\t\t\tclass={`rui-carousel__nav rui-button rui-button--outline rui-button--sm${overlay ? ' rui-carousel__nav--overlay' : ' rui-carousel__nav--toolbar'}`}\n\t\t\t\t\taria-label=\"Next slide\"\n\t\t\t\t\tdisabled={disableNext}\n\t\t\t\t>\n\t\t\t\t\t{overlay ? (\n\t\t\t\t\t\t<span class=\"rui-carousel__nav-icon\" aria-hidden=\"true\">\n\t\t\t\t\t\t\t\u203A\n\t\t\t\t\t\t</span>\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<span class=\"rui-carousel__nav-label\">\n\t\t\t\t\t\t\tNext\n\t\t\t\t\t\t\t<span class=\"rui-carousel__nav-icon\" aria-hidden=\"true\">\n\t\t\t\t\t\t\t\t\u203A\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t</span>\n\t\t\t\t\t)}\n\t\t\t\t</button>\n\t\t\t</slot>\n\t\t);\n\n\t\tconst rotationControl = showRotation ? (\n\t\t\t<slot name=\"rotation\">\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tdata-carousel-action=\"rotation\"\n\t\t\t\t\tdata-ref=\"rotation\"\n\t\t\t\t\tclass={`rui-carousel__rotation rui-button rui-button--ghost rui-button--sm${overlay ? ' rui-carousel__rotation--overlay' : ''}`}\n\t\t\t\t\taria-pressed={playing}\n\t\t\t\t\taria-label={playing ? 'Pause rotation' : 'Start rotation'}\n\t\t\t\t>\n\t\t\t\t\t{playing ? 'Pause' : 'Play'}\n\t\t\t\t</button>\n\t\t\t</slot>\n\t\t) : null;\n\n\t\tconst indicators = this.showIndicators ? (\n\t\t\t<div\n\t\t\t\tclass={`rui-carousel__indicators${overlay ? ' rui-carousel__indicators--overlay' : ''}`}\n\t\t\t\tdata-ref=\"indicators\"\n\t\t\t\trole=\"tablist\"\n\t\t\t\taria-label=\"Choose slide to display\"\n\t\t\t/>\n\t\t) : null;\n\n\t\tconst toolbarControls = (\n\t\t\t<div class=\"rui-carousel__toolbar\">\n\t\t\t\t{showRotation ? <div class=\"rui-carousel__toolbar-rotation\">{rotationControl}</div> : null}\n\t\t\t\t<div class=\"rui-carousel__toolbar-side rui-carousel__toolbar-side--start\">{prevControl}</div>\n\t\t\t\t<div class=\"rui-carousel__toolbar-center\">{indicators}</div>\n\t\t\t\t<div class=\"rui-carousel__toolbar-side rui-carousel__toolbar-side--end\">{nextControl}</div>\n\t\t\t</div>\n\t\t);\n\n\t\tconst overlayChrome = overlay ? (\n\t\t\t<div class=\"rui-carousel__overlay-chrome\">\n\t\t\t\t{showRotation ? <div class=\"rui-carousel__overlay-rotation\">{rotationControl}</div> : null}\n\t\t\t\t<div class=\"rui-carousel__controls rui-carousel__controls--overlay\">\n\t\t\t\t\t{prevControl}\n\t\t\t\t\t{nextControl}\n\t\t\t\t</div>\n\t\t\t\t{indicators}\n\t\t\t</div>\n\t\t) : null;\n\n\t\treturn (\n\t\t\t<section\n\t\t\t\tclass={`rui-carousel rui-carousel--${this.transition} rui-carousel--controls-${this.controlsVariant}`}\n\t\t\t\tdata-ref=\"root\"\n\t\t\t\taria-roledescription=\"carousel\"\n\t\t\t\taria-label={this.$.label}\n\t\t\t>\n\t\t\t\t<div class=\"rui-carousel__stage\">\n\t\t\t\t\t<div class=\"rui-carousel__viewport\" data-ref=\"viewport\" aria-live={ariaLive} aria-atomic={false}>\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tclass=\"rui-carousel__track\"\n\t\t\t\t\t\t\tstyle={\n\t\t\t\t\t\t\t\tthis.transition === 'slide' ? { '--rui-carousel-index': String(this.index) } : undefined\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<slot></slot>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t{overlayChrome}\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t{!overlay ? <div class=\"rui-carousel__footer\">{toolbarControls}</div> : null}\n\t\t\t</section>\n\t\t);\n\t}\n}\n", "import type { JsxRenderable } from '@ecopages/jsx';\n\nconst RADIANT_VIEW_ELEMENT = Symbol.for('@ecopages/storybook-radiant.viewElement');\nconst RADIANT_SCRIPT_MODULE = Symbol.for('@ecopages/storybook-radiant.scriptModule');\nconst RADIANT_SCRIPT_EXPORT = Symbol.for('@ecopages/storybook-radiant.scriptExport');\n\nexport type RadiantViewComponent<TArgs = unknown> = ((args: TArgs) => JsxRenderable) & {\n\t[RADIANT_VIEW_ELEMENT]?: CustomElementConstructor;\n\t[RADIANT_SCRIPT_MODULE]?: string;\n\t[RADIANT_SCRIPT_EXPORT]?: string;\n};\n\nfunction linkViewToElement<TArgs>(\n\tview: RadiantViewComponent<TArgs>,\n\telement: CustomElementConstructor & {\n\t\t[RADIANT_SCRIPT_MODULE]?: string;\n\t\t[RADIANT_SCRIPT_EXPORT]?: string;\n\t},\n): void {\n\tview[RADIANT_VIEW_ELEMENT] = element;\n\n\tconst ssrModule = element[RADIANT_SCRIPT_MODULE];\n\tif (ssrModule) {\n\t\tview[RADIANT_SCRIPT_MODULE] = ssrModule;\n\t\tview[RADIANT_SCRIPT_EXPORT] = element[RADIANT_SCRIPT_EXPORT] ?? element.name;\n\t}\n}\n\n/** Link a JSX view export to its RadiantElement class (same symbols as the Storybook framework). */\nexport function defineRadiantView<TArgs>(\n\telement: CustomElementConstructor & {\n\t\t[RADIANT_SCRIPT_MODULE]?: string;\n\t\t[RADIANT_SCRIPT_EXPORT]?: string;\n\t},\n\trender: (args: TArgs) => JsxRenderable,\n): RadiantViewComponent<TArgs> {\n\tconst view = ((args: TArgs) => render(args)) as RadiantViewComponent<TArgs>;\n\tlinkViewToElement(view, element);\n\treturn view;\n}\n\n/** Re-copy SSR metadata from the linked element (e.g. after HMR). */\nexport function syncRadiantViewMetadata(view: RadiantViewComponent): void {\n\tconst element = view[RADIANT_VIEW_ELEMENT];\n\tif (element) {\n\t\tlinkViewToElement(view, element);\n\t}\n}\n", "import type { JsxRenderable } from '@ecopages/jsx';\nimport type { RadiantSlotProps, WithChildren } from '../../../types';\nimport { defineRadiantView } from '../../../lib/radiant-view';\nimport type { RuiCarouselProps } from './carousel.script';\nimport { RuiCarousel as RuiCarouselElement } from './carousel.script';\nimport './carousel.css';\n\nfunction cx(...parts: Array<string | false | null | undefined>): string {\n\treturn parts.filter(Boolean).join(' ');\n}\n\nexport type RuiCarouselSlideData = { id: string; children: JsxRenderable };\n\nexport type RuiCarouselSlideProps = {\n\tid: string;\n\tindex?: number;\n\tchildren: JsxRenderable;\n\tclass?: string;\n};\n\n/** Slide in the default carousel slot (APG `group` / `tabpanel` roles are applied by the host). */\nexport function RuiCarouselSlide({ id, children, class: className }: RuiCarouselSlideProps) {\n\treturn (\n\t\t<div class={cx('rui-carousel__slide', className)} data-slide={id}>\n\t\t\t{children}\n\t\t</div>\n\t);\n}\n\nexport type RuiCarouselControlProps = RadiantSlotProps & {\n\tchildren?: JsxRenderable;\n\tclass?: string;\n\tdisabled?: boolean;\n\t/** Match `controls-variant=\"overlay\"` on the carousel for circular on-slide chrome. */\n\toverlay?: boolean;\n};\n\nfunction toolbarPrevLabel() {\n\treturn (\n\t\t<span class=\"rui-carousel__nav-label\">\n\t\t\t<span class=\"rui-carousel__nav-icon\" aria-hidden=\"true\">\n\t\t\t\t\u2039\n\t\t\t</span>\n\t\t\tPrevious\n\t\t</span>\n\t);\n}\n\nfunction toolbarNextLabel() {\n\treturn (\n\t\t<span class=\"rui-carousel__nav-label\">\n\t\t\tNext\n\t\t\t<span class=\"rui-carousel__nav-icon\" aria-hidden=\"true\">\n\t\t\t\t\u203A\n\t\t\t</span>\n\t\t</span>\n\t);\n}\n\n/** Previous control slotted into `prev` by default. */\nexport function RuiCarouselPrev({\n\tslot = 'prev',\n\tchildren,\n\tclass: className,\n\tdisabled,\n\toverlay,\n}: RuiCarouselControlProps) {\n\treturn (\n\t\t<button\n\t\t\tslot={slot}\n\t\t\ttype=\"button\"\n\t\t\tdata-carousel-action=\"prev\"\n\t\t\tdata-ref=\"prev\"\n\t\t\tclass={cx(\n\t\t\t\t'rui-carousel__nav rui-button rui-button--outline rui-button--sm',\n\t\t\t\toverlay ? 'rui-carousel__nav--overlay' : 'rui-carousel__nav--toolbar',\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\taria-label=\"Previous slide\"\n\t\t\tdisabled={disabled}\n\t\t>\n\t\t\t{children ??\n\t\t\t\t(overlay ? (\n\t\t\t\t\t<span class=\"rui-carousel__nav-icon\" aria-hidden=\"true\">\n\t\t\t\t\t\t\u2039\n\t\t\t\t\t</span>\n\t\t\t\t) : (\n\t\t\t\t\ttoolbarPrevLabel()\n\t\t\t\t))}\n\t\t</button>\n\t);\n}\n\n/** Next control slotted into `next` by default. */\nexport function RuiCarouselNext({\n\tslot = 'next',\n\tchildren,\n\tclass: className,\n\tdisabled,\n\toverlay,\n}: RuiCarouselControlProps) {\n\treturn (\n\t\t<button\n\t\t\tslot={slot}\n\t\t\ttype=\"button\"\n\t\t\tdata-carousel-action=\"next\"\n\t\t\tdata-ref=\"next\"\n\t\t\tclass={cx(\n\t\t\t\t'rui-carousel__nav rui-button rui-button--outline rui-button--sm',\n\t\t\t\toverlay ? 'rui-carousel__nav--overlay' : 'rui-carousel__nav--toolbar',\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\taria-label=\"Next slide\"\n\t\t\tdisabled={disabled}\n\t\t>\n\t\t\t{children ??\n\t\t\t\t(overlay ? (\n\t\t\t\t\t<span class=\"rui-carousel__nav-icon\" aria-hidden=\"true\">\n\t\t\t\t\t\t\u203A\n\t\t\t\t\t</span>\n\t\t\t\t) : (\n\t\t\t\t\ttoolbarNextLabel()\n\t\t\t\t))}\n\t\t</button>\n\t);\n}\n\nexport type RuiCarouselRotationProps = RadiantSlotProps & {\n\tchildren?: JsxRenderable;\n\tclass?: string;\n\toverlay?: boolean;\n};\n\n/** Play/pause rotation control slotted into `rotation` by default. */\nexport function RuiCarouselRotation({\n\tslot = 'rotation',\n\tchildren,\n\tclass: className,\n\toverlay,\n}: RuiCarouselRotationProps) {\n\treturn (\n\t\t<button\n\t\t\tslot={slot}\n\t\t\ttype=\"button\"\n\t\t\tdata-carousel-action=\"rotation\"\n\t\t\tdata-ref=\"rotation\"\n\t\t\tclass={cx(\n\t\t\t\t'rui-carousel__rotation rui-button rui-button--ghost rui-button--sm',\n\t\t\t\toverlay && 'rui-carousel__rotation--overlay',\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\taria-pressed={false}\n\t\t\taria-label=\"Start rotation\"\n\t\t>\n\t\t\t{children ?? 'Play'}\n\t\t</button>\n\t);\n}\n\nexport const RuiCarousel = defineRadiantView(\n\tRuiCarouselElement,\n\t({\n\t\tslot,\n\t\tlabel,\n\t\tindex,\n\t\tautoplay,\n\t\tinterval,\n\t\ttransition,\n\t\tcontrolsVariant,\n\t\tshowIndicators,\n\t\tshowRotationControl,\n\t\tloop,\n\t\twrap,\n\t\tslides,\n\t\tchildren,\n\t}: RuiCarouselProps &\n\t\tRadiantSlotProps &\n\t\tWithChildren<{\n\t\t\tslides?: RuiCarouselSlideData[];\n\t\t}>) => {\n\t\tif (children != null) {\n\t\t\treturn (\n\t\t\t\t<rui-carousel\n\t\t\t\t\tslot={slot}\n\t\t\t\t\tlabel={label}\n\t\t\t\t\tindex={index}\n\t\t\t\t\tautoplay={autoplay}\n\t\t\t\t\tinterval={interval}\n\t\t\t\t\ttransition={transition}\n\t\t\t\t\tcontrolsVariant={controlsVariant}\n\t\t\t\t\tshowIndicators={showIndicators}\n\t\t\t\t\tshowRotationControl={showRotationControl}\n\t\t\t\t\tloop={loop}\n\t\t\t\t\twrap={wrap}\n\t\t\t\t>\n\t\t\t\t\t{children}\n\t\t\t\t</rui-carousel>\n\t\t\t);\n\t\t}\n\n\t\tconst slideList = slides ?? [];\n\n\t\treturn (\n\t\t\t<rui-carousel\n\t\t\t\tslot={slot}\n\t\t\t\tlabel={label}\n\t\t\t\tindex={index}\n\t\t\t\tautoplay={autoplay}\n\t\t\t\tinterval={interval}\n\t\t\t\ttransition={transition}\n\t\t\t\tcontrolsVariant={controlsVariant}\n\t\t\t\tshowIndicators={showIndicators}\n\t\t\t\tshowRotationControl={showRotationControl}\n\t\t\t\tloop={loop}\n\t\t\t\twrap={wrap}\n\t\t\t\tslideCount={slideList.length}\n\t\t\t>\n\t\t\t\t{slideList.map((slide) => (\n\t\t\t\t\t<RuiCarouselSlide id={slide.id}>{slide.children}</RuiCarouselSlide>\n\t\t\t\t))}\n\t\t\t</rui-carousel>\n\t\t);\n\t},\n);\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["RadiantElement", "customElement", "onEvent", "onUpdated", "prop", "SWIPE_THRESHOLD_PX", "RuiCarousel", "slide", "index", "key", "panelId", "slides", "activeIndex", "count", "i", "active", "positionLabel", "raw", "normalized", "track", "disablePrev", "disableNext", "button", "container", "indicator", "selected", "toggle", "playing", "viewport", "rotating", "ms", "currentSlides", "next", "delta", "target", "event", "indicatorIndex", "current", "nextIndex", "dx", "dy", "showRotation", "slideCount", "ariaLive", "overlay", "prevControl", "nextControl", "rotationControl", "indicators", "toolbarControls", "overlayChrome", "RADIANT_VIEW_ELEMENT", "RADIANT_SCRIPT_MODULE", "RADIANT_SCRIPT_EXPORT", "linkViewToElement", "view", "element", "ssrModule", "defineRadiantView", "render", "args", "cx", "parts", "RuiCarouselSlide", "id", "children", "className", "toolbarPrevLabel", "toolbarNextLabel", "RuiCarouselPrev", "slot", "disabled", "overlay", "RuiCarouselNext", "RuiCarouselRotation", "RuiCarousel", "defineRadiantView", "label", "index", "autoplay", "interval", "transition", "controlsVariant", "showIndicators", "showRotationControl", "loop", "wrap", "slides", "slideList", "slide"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
@reference '../../../styles/radiant-ui.css';
|
|
2
|
+
|
|
3
|
+
rui-checkbox {
|
|
4
|
+
@apply inline-flex;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
@layer components {
|
|
8
|
+
.rui-checkbox {
|
|
9
|
+
@apply inline-flex items-center gap-inline cursor-pointer text-sm text-on-background;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.rui-checkbox:has(input:disabled) {
|
|
13
|
+
@apply cursor-not-allowed opacity-disabled;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.rui-checkbox__input {
|
|
17
|
+
@apply sr-only;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.rui-checkbox__control {
|
|
21
|
+
@apply relative size-4 shrink-0 rounded-xs border border-border bg-background;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.rui-checkbox__input:focus-visible + .rui-checkbox__control {
|
|
25
|
+
@apply ring-2 ring-focus-ring ring-offset-2;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.rui-checkbox__input:checked:not(:indeterminate):not([aria-checked='mixed']) + .rui-checkbox__control {
|
|
29
|
+
@apply border-primary bg-primary;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.rui-checkbox__input:checked:not(:indeterminate):not([aria-checked='mixed']) + .rui-checkbox__control::after {
|
|
33
|
+
content: '';
|
|
34
|
+
@apply absolute left-1/2 top-1/2 block size-2 -translate-x-1/2 -translate-y-1/2;
|
|
35
|
+
background: currentColor;
|
|
36
|
+
color: var(--color-on-primary, white);
|
|
37
|
+
clip-path: polygon(14% 44%, 0 65%, 50% 100%, 100% 16%, 80% 0%, 43% 62%);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.rui-checkbox__input:indeterminate + .rui-checkbox__control,
|
|
41
|
+
.rui-checkbox__input[aria-checked='mixed'] + .rui-checkbox__control {
|
|
42
|
+
@apply border-primary bg-background;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.rui-checkbox__input:indeterminate + .rui-checkbox__control::after,
|
|
46
|
+
.rui-checkbox__input[aria-checked='mixed'] + .rui-checkbox__control::after {
|
|
47
|
+
content: '';
|
|
48
|
+
@apply absolute left-1/2 top-1/2 block h-0.5 w-2.5 -translate-x-1/2 -translate-y-1/2 rounded-full bg-primary;
|
|
49
|
+
clip-path: none;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.rui-checkbox__label {
|
|
53
|
+
@apply select-none;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { WithChildren, RadiantSlotProps } from '../../../types';
|
|
2
|
+
import type { RuiCheckboxProps } from './checkbox.script';
|
|
3
|
+
import './checkbox.css';
|
|
4
|
+
export declare const RuiCheckbox: import("../../../lib/radiant-view").RadiantViewComponent<WithChildren<RuiCheckboxProps & RadiantSlotProps>>;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { RadiantElement } from '@ecopages/radiant';
|
|
2
|
+
import type { EventEmitter } from '@ecopages/radiant/tools/event-emitter';
|
|
3
|
+
export type RuiCheckboxProps = {
|
|
4
|
+
/** Whether the checkbox is checked. Default: `false`. */
|
|
5
|
+
checked?: boolean;
|
|
6
|
+
/**
|
|
7
|
+
* Partially checked (mixed) state for group controllers.
|
|
8
|
+
* When `true`, the native input's `indeterminate` IDL is set and
|
|
9
|
+
* `aria-checked="mixed"` is exposed. Default: `false`.
|
|
10
|
+
*/
|
|
11
|
+
indeterminate?: boolean;
|
|
12
|
+
/** Disable the checkbox. Default: `false`. */
|
|
13
|
+
disabled?: boolean;
|
|
14
|
+
/** Value submitted with forms when checked. */
|
|
15
|
+
value?: string;
|
|
16
|
+
/** Associates the control with a form field name. */
|
|
17
|
+
name?: string;
|
|
18
|
+
};
|
|
19
|
+
export type RuiCheckboxChangeDetail = {
|
|
20
|
+
checked: boolean;
|
|
21
|
+
indeterminate: boolean;
|
|
22
|
+
};
|
|
23
|
+
type RuiCheckboxBindings = {
|
|
24
|
+
checked: boolean;
|
|
25
|
+
indeterminate: boolean;
|
|
26
|
+
disabled: boolean;
|
|
27
|
+
value: string;
|
|
28
|
+
name: string;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* `<rui-checkbox>` — a dual-state or tri-state checkbox.
|
|
32
|
+
*
|
|
33
|
+
* Implements the WAI-ARIA APG Checkbox pattern on a native
|
|
34
|
+
* `<input type="checkbox">`. Checked state uses the HTML `checked` attribute;
|
|
35
|
+
* the mixed state uses the `indeterminate` IDL property with `aria-checked="mixed"`.
|
|
36
|
+
*
|
|
37
|
+
* @see https://www.w3.org/WAI/ARIA/apg/patterns/checkbox/
|
|
38
|
+
*
|
|
39
|
+
* Keyboard interaction (native to the checkbox):
|
|
40
|
+
* - `Space`: toggle checked state
|
|
41
|
+
*
|
|
42
|
+
* @element rui-checkbox
|
|
43
|
+
* @slot - Visible label for the checkbox.
|
|
44
|
+
* @fires rui-change - Emitted after the checked/indeterminate state changes.
|
|
45
|
+
*/
|
|
46
|
+
export declare class RuiCheckbox extends RadiantElement<RuiCheckboxBindings> {
|
|
47
|
+
checked: boolean;
|
|
48
|
+
indeterminate: boolean;
|
|
49
|
+
disabled: boolean;
|
|
50
|
+
value: string;
|
|
51
|
+
name: string;
|
|
52
|
+
changeEvent: EventEmitter<RuiCheckboxChangeDetail>;
|
|
53
|
+
private readonly nameAttr;
|
|
54
|
+
private readonly resolvedAriaChecked;
|
|
55
|
+
onInputChange(event: Event): void;
|
|
56
|
+
render(): import("@ecopages/jsx").JsxRenderable;
|
|
57
|
+
}
|
|
58
|
+
export {};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{RadiantElement as u,customElement as m,event as h,onEvent as b,prop as n}from"@ecopages/radiant";var i=@m("rui-checkbox")class extends u{@n({type:Boolean,reflect:!0,defaultValue:!1})checked;@n({type:Boolean,reflect:!0,defaultValue:!1})indeterminate;@n({type:Boolean,reflect:!0,defaultValue:!1})disabled;@n({type:String,defaultValue:"on"})value;@n({type:String,defaultValue:""})name;@h({name:"rui-change",bubbles:!0,composed:!0})changeEvent;nameAttr=this.$.name.map(e=>e||void 0);resolvedAriaChecked=this.$.indeterminate.map(e=>e?"mixed":void 0);@b({ref:"input",type:"change"})onInputChange(e){let t=e.target;this.indeterminate=!1,this.checked=t.checked,this.changeEvent.emit({checked:this.checked,indeterminate:!1})}render(){return React.createElement("label",{class:"rui-checkbox"},React.createElement("input",{type:"checkbox","data-ref":"input","data-rui-control":!0,"data-rui-control-type":"boolean",class:"rui-checkbox__input","prop:checked":this.$.checked,disabled:this.$.disabled,"prop:value":this.$.value,name:this.nameAttr,"prop:indeterminate":this.$.indeterminate,"aria-checked":this.resolvedAriaChecked}),React.createElement("span",{class:"rui-checkbox__control","aria-hidden":"true"}),React.createElement("span",{class:"rui-checkbox__label"},React.createElement("slot",null)))}};var R=Symbol.for("@ecopages/storybook-radiant.viewElement"),r=Symbol.for("@ecopages/storybook-radiant.scriptModule"),s=Symbol.for("@ecopages/storybook-radiant.scriptExport");function k(o,e){o[R]=e;let t=e[r];t&&(o[r]=t,o[s]=e[s]??e.name)}function c(o,e){let t=(a=>e(a));return k(t,o),t}import"./checkbox.css";var g=c(i,({slot:o,checked:e,indeterminate:t,disabled:a,value:l,name:d,children:p})=>React.createElement("rui-checkbox",{slot:o,checked:e,indeterminate:t,disabled:a,value:l,name:d},p));export{g as RuiCheckbox,i as RuiCheckboxElement};
|
|
2
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/components/ui/checkbox/checkbox.script.tsx", "../../../../src/lib/radiant-view.ts", "../../../../src/components/ui/checkbox/checkbox.tsx"],
|
|
4
|
+
"sourcesContent": ["import { RadiantElement, customElement, event, onEvent, prop } from '@ecopages/radiant';\nimport type { EventEmitter } from '@ecopages/radiant/tools/event-emitter';\n\nexport type RuiCheckboxProps = {\n\t/** Whether the checkbox is checked. Default: `false`. */\n\tchecked?: boolean;\n\t/**\n\t * Partially checked (mixed) state for group controllers.\n\t * When `true`, the native input's `indeterminate` IDL is set and\n\t * `aria-checked=\"mixed\"` is exposed. Default: `false`.\n\t */\n\tindeterminate?: boolean;\n\t/** Disable the checkbox. Default: `false`. */\n\tdisabled?: boolean;\n\t/** Value submitted with forms when checked. */\n\tvalue?: string;\n\t/** Associates the control with a form field name. */\n\tname?: string;\n};\n\nexport type RuiCheckboxChangeDetail = {\n\tchecked: boolean;\n\tindeterminate: boolean;\n};\n\ntype RuiCheckboxBindings = {\n\tchecked: boolean;\n\tindeterminate: boolean;\n\tdisabled: boolean;\n\tvalue: string;\n\tname: string;\n};\n\n/**\n * `<rui-checkbox>` \u2014 a dual-state or tri-state checkbox.\n *\n * Implements the WAI-ARIA APG Checkbox pattern on a native\n * `<input type=\"checkbox\">`. Checked state uses the HTML `checked` attribute;\n * the mixed state uses the `indeterminate` IDL property with `aria-checked=\"mixed\"`.\n *\n * @see https://www.w3.org/WAI/ARIA/apg/patterns/checkbox/\n *\n * Keyboard interaction (native to the checkbox):\n * - `Space`: toggle checked state\n *\n * @element rui-checkbox\n * @slot - Visible label for the checkbox.\n * @fires rui-change - Emitted after the checked/indeterminate state changes.\n */\n@customElement('rui-checkbox')\nexport class RuiCheckbox extends RadiantElement<RuiCheckboxBindings> {\n\t@prop({ type: Boolean, reflect: true, defaultValue: false }) checked: boolean;\n\t@prop({ type: Boolean, reflect: true, defaultValue: false }) indeterminate: boolean;\n\t@prop({ type: Boolean, reflect: true, defaultValue: false }) disabled: boolean;\n\t@prop({ type: String, defaultValue: 'on' }) value: string;\n\t@prop({ type: String, defaultValue: '' }) name: string;\n\n\t@event({ name: 'rui-change', bubbles: true, composed: true })\n\tchangeEvent: EventEmitter<RuiCheckboxChangeDetail>;\n\n\tprivate readonly nameAttr = this.$.name.map((name) => name || undefined);\n\tprivate readonly resolvedAriaChecked = this.$.indeterminate.map((indeterminate) =>\n\t\tindeterminate ? 'mixed' : undefined,\n\t);\n\n\t@onEvent({ ref: 'input', type: 'change' })\n\tonInputChange(event: Event): void {\n\t\tconst input = event.target as HTMLInputElement;\n\t\tthis.indeterminate = false;\n\t\tthis.checked = input.checked;\n\t\tthis.changeEvent.emit({ checked: this.checked, indeterminate: false });\n\t}\n\n\toverride render() {\n\t\treturn (\n\t\t\t<label class=\"rui-checkbox\">\n\t\t\t\t<input\n\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\tdata-ref=\"input\"\n\t\t\t\t\tdata-rui-control\n\t\t\t\t\tdata-rui-control-type=\"boolean\"\n\t\t\t\t\tclass=\"rui-checkbox__input\"\n\t\t\t\t\tprop:checked={this.$.checked}\n\t\t\t\t\tdisabled={this.$.disabled}\n\t\t\t\t\tprop:value={this.$.value}\n\t\t\t\t\tname={this.nameAttr}\n\t\t\t\t\tprop:indeterminate={this.$.indeterminate}\n\t\t\t\t\taria-checked={this.resolvedAriaChecked}\n\t\t\t\t/>\n\t\t\t\t<span class=\"rui-checkbox__control\" aria-hidden=\"true\"></span>\n\t\t\t\t<span class=\"rui-checkbox__label\">\n\t\t\t\t\t<slot></slot>\n\t\t\t\t</span>\n\t\t\t</label>\n\t\t);\n\t}\n}\n", "import type { JsxRenderable } from '@ecopages/jsx';\n\nconst RADIANT_VIEW_ELEMENT = Symbol.for('@ecopages/storybook-radiant.viewElement');\nconst RADIANT_SCRIPT_MODULE = Symbol.for('@ecopages/storybook-radiant.scriptModule');\nconst RADIANT_SCRIPT_EXPORT = Symbol.for('@ecopages/storybook-radiant.scriptExport');\n\nexport type RadiantViewComponent<TArgs = unknown> = ((args: TArgs) => JsxRenderable) & {\n\t[RADIANT_VIEW_ELEMENT]?: CustomElementConstructor;\n\t[RADIANT_SCRIPT_MODULE]?: string;\n\t[RADIANT_SCRIPT_EXPORT]?: string;\n};\n\nfunction linkViewToElement<TArgs>(\n\tview: RadiantViewComponent<TArgs>,\n\telement: CustomElementConstructor & {\n\t\t[RADIANT_SCRIPT_MODULE]?: string;\n\t\t[RADIANT_SCRIPT_EXPORT]?: string;\n\t},\n): void {\n\tview[RADIANT_VIEW_ELEMENT] = element;\n\n\tconst ssrModule = element[RADIANT_SCRIPT_MODULE];\n\tif (ssrModule) {\n\t\tview[RADIANT_SCRIPT_MODULE] = ssrModule;\n\t\tview[RADIANT_SCRIPT_EXPORT] = element[RADIANT_SCRIPT_EXPORT] ?? element.name;\n\t}\n}\n\n/** Link a JSX view export to its RadiantElement class (same symbols as the Storybook framework). */\nexport function defineRadiantView<TArgs>(\n\telement: CustomElementConstructor & {\n\t\t[RADIANT_SCRIPT_MODULE]?: string;\n\t\t[RADIANT_SCRIPT_EXPORT]?: string;\n\t},\n\trender: (args: TArgs) => JsxRenderable,\n): RadiantViewComponent<TArgs> {\n\tconst view = ((args: TArgs) => render(args)) as RadiantViewComponent<TArgs>;\n\tlinkViewToElement(view, element);\n\treturn view;\n}\n\n/** Re-copy SSR metadata from the linked element (e.g. after HMR). */\nexport function syncRadiantViewMetadata(view: RadiantViewComponent): void {\n\tconst element = view[RADIANT_VIEW_ELEMENT];\n\tif (element) {\n\t\tlinkViewToElement(view, element);\n\t}\n}\n", "import type { WithChildren, RadiantSlotProps } from '../../../types';\nimport { defineRadiantView } from '../../../lib/radiant-view';\nimport type { RuiCheckboxProps } from './checkbox.script';\nimport { RuiCheckbox as RuiCheckboxElement } from './checkbox.script';\nimport './checkbox.css';\n\nexport const RuiCheckbox = defineRadiantView(\n\tRuiCheckboxElement,\n\t({\n\t\tslot,\n\t\tchecked,\n\t\tindeterminate,\n\t\tdisabled,\n\t\tvalue,\n\t\tname,\n\t\tchildren,\n\t}: WithChildren<RuiCheckboxProps & RadiantSlotProps>) => (\n\t\t<rui-checkbox\n\t\t\tslot={slot}\n\t\t\tchecked={checked}\n\t\t\tindeterminate={indeterminate}\n\t\t\tdisabled={disabled}\n\t\t\tvalue={value}\n\t\t\tname={name}\n\t\t>\n\t\t\t{children}\n\t\t</rui-checkbox>\n\t),\n);\n"],
|
|
5
|
+
"mappings": "AAAA,OAAS,kBAAAA,EAAgB,iBAAAC,EAAe,SAAAC,EAAO,WAAAC,EAAS,QAAAC,MAAY,oBAkD7D,IAAMC,EADb,CAACJ,EAAc,cAAc,CACtB,cAA0BD,CAAoC,CACpE,CAACI,EAAK,CAAE,KAAM,QAAS,QAAS,GAAM,aAAc,EAAM,CAAC,CAAE,QAC7D,CAACA,EAAK,CAAE,KAAM,QAAS,QAAS,GAAM,aAAc,EAAM,CAAC,CAAE,cAC7D,CAACA,EAAK,CAAE,KAAM,QAAS,QAAS,GAAM,aAAc,EAAM,CAAC,CAAE,SAC7D,CAACA,EAAK,CAAE,KAAM,OAAQ,aAAc,IAAK,CAAC,CAAE,MAC5C,CAACA,EAAK,CAAE,KAAM,OAAQ,aAAc,EAAG,CAAC,CAAE,KAE1C,CAACF,EAAM,CAAE,KAAM,aAAc,QAAS,GAAM,SAAU,EAAK,CAAC,CAC5D,YAEiB,SAAW,KAAK,EAAE,KAAK,IAAKI,GAASA,GAAQ,MAAS,EACtD,oBAAsB,KAAK,EAAE,cAAc,IAAKC,GAChEA,EAAgB,QAAU,MAC3B,EAEA,CAACJ,EAAQ,CAAE,IAAK,QAAS,KAAM,QAAS,CAAC,CACzC,cAAcD,EAAoB,CACjC,IAAMM,EAAQN,EAAM,OACpB,KAAK,cAAgB,GACrB,KAAK,QAAUM,EAAM,QACrB,KAAK,YAAY,KAAK,CAAE,QAAS,KAAK,QAAS,cAAe,EAAM,CAAC,CACtE,CAES,QAAS,CACjB,OACC,oBAAC,SAAM,MAAM,gBACZ,oBAAC,SACA,KAAK,WACL,WAAS,QACT,mBAAgB,GAChB,wBAAsB,UACtB,MAAM,sBACN,eAAc,KAAK,EAAE,QACrB,SAAU,KAAK,EAAE,SACjB,aAAY,KAAK,EAAE,MACnB,KAAM,KAAK,SACX,qBAAoB,KAAK,EAAE,cAC3B,eAAc,KAAK,oBACpB,EACA,oBAAC,QAAK,MAAM,wBAAwB,cAAY,OAAO,EACvD,oBAAC,QAAK,MAAM,uBACX,oBAAC,WAAK,CACP,CACD,CAEF,CACD,EC9FA,IAAMC,EAAuB,OAAO,IAAI,yCAAyC,EAC3EC,EAAwB,OAAO,IAAI,0CAA0C,EAC7EC,EAAwB,OAAO,IAAI,0CAA0C,EAQnF,SAASC,EACRC,EACAC,EAIO,CACPD,EAAKJ,CAAoB,EAAIK,EAE7B,IAAMC,EAAYD,EAAQJ,CAAqB,EAC3CK,IACHF,EAAKH,CAAqB,EAAIK,EAC9BF,EAAKF,CAAqB,EAAIG,EAAQH,CAAqB,GAAKG,EAAQ,KAE1E,CAGO,SAASE,EACfF,EAIAG,EAC8B,CAC9B,IAAMJ,GAASK,GAAgBD,EAAOC,CAAI,GAC1C,OAAAN,EAAkBC,EAAMC,CAAO,EACxBD,CACR,CCnCA,MAAO,iBAEA,IAAMM,EAAcC,EAC1BD,EACA,CAAC,CACA,KAAAE,EACA,QAAAC,EACA,cAAAC,EACA,SAAAC,EACA,MAAAC,EACA,KAAAC,EACA,SAAAC,CACD,IACC,oBAAC,gBACA,KAAMN,EACN,QAASC,EACT,cAAeC,EACf,SAAUC,EACV,MAAOC,EACP,KAAMC,GAELC,CACF,CAEF",
|
|
6
|
+
"names": ["RadiantElement", "customElement", "event", "onEvent", "prop", "RuiCheckbox", "name", "indeterminate", "input", "RADIANT_VIEW_ELEMENT", "RADIANT_SCRIPT_MODULE", "RADIANT_SCRIPT_EXPORT", "linkViewToElement", "view", "element", "ssrModule", "defineRadiantView", "render", "args", "RuiCheckbox", "defineRadiantView", "slot", "checked", "indeterminate", "disabled", "value", "name", "children"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
@reference '../../../styles/radiant-ui.css';
|
|
2
|
+
|
|
3
|
+
rui-combobox {
|
|
4
|
+
@apply relative inline-flex flex-col;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
@layer components {
|
|
8
|
+
.rui-combobox {
|
|
9
|
+
@apply relative w-64 text-sm;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.rui-combobox__control {
|
|
13
|
+
@apply relative flex items-stretch rounded-button border border-border bg-background;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.rui-combobox__control:focus-within {
|
|
17
|
+
@apply ring-2 ring-focus-ring;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.rui-combobox__input {
|
|
21
|
+
@apply min-w-0 flex-1 border-0 bg-transparent px-3 py-2 text-on-background outline-none;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.rui-combobox__input:disabled {
|
|
25
|
+
@apply cursor-not-allowed opacity-muted;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.rui-combobox__trigger {
|
|
29
|
+
@apply inline-flex shrink-0 items-center justify-center border-0 border-l border-border bg-transparent px-2;
|
|
30
|
+
@apply cursor-pointer text-on-surface;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.rui-combobox__trigger:disabled {
|
|
34
|
+
@apply cursor-not-allowed opacity-muted;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.rui-combobox__trigger:focus-visible {
|
|
38
|
+
@apply bg-surface outline-none;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.rui-combobox__listbox {
|
|
42
|
+
@apply absolute top-full z-popover mt-1 max-h-48 w-full overflow-auto rounded-container border border-border bg-background p-1 shadow-md rui-sheen;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.rui-combobox__listbox[hidden] {
|
|
46
|
+
display: none;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.rui-combobox__option {
|
|
50
|
+
@apply cursor-pointer rounded-control px-3 py-2 text-on-background;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.rui-combobox__option[aria-disabled='true'] {
|
|
54
|
+
@apply cursor-not-allowed opacity-muted;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.rui-combobox__option:hover {
|
|
58
|
+
@apply bg-surface outline-none;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.rui-combobox__option[data-active],
|
|
62
|
+
.rui-combobox__option[aria-selected='true'] {
|
|
63
|
+
@apply bg-primary text-on-primary outline-none rui-sheen;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { JsxRenderable } from '@ecopages/jsx';
|
|
2
|
+
import type { RadiantSlotProps } from '../../../types';
|
|
3
|
+
import type { RuiComboboxProps } from './combobox.script';
|
|
4
|
+
import './combobox.css';
|
|
5
|
+
export type RuiComboboxControlProps = RadiantSlotProps & {
|
|
6
|
+
children: JsxRenderable;
|
|
7
|
+
class?: string;
|
|
8
|
+
};
|
|
9
|
+
/** Input row wrapper for the combobox input and optional trigger icon. */
|
|
10
|
+
export declare function RuiComboboxControl({ slot, children, class: className }: RuiComboboxControlProps): JsxRenderable;
|
|
11
|
+
export type RuiComboboxInputProps = {
|
|
12
|
+
placeholder?: string;
|
|
13
|
+
disabled?: boolean;
|
|
14
|
+
class?: string;
|
|
15
|
+
};
|
|
16
|
+
/** Text input with `role="combobox"`. Place inside `RuiComboboxControl`. */
|
|
17
|
+
export declare function RuiComboboxInput({ placeholder, disabled, class: className }: RuiComboboxInputProps): JsxRenderable;
|
|
18
|
+
export type RuiComboboxTriggerProps = {
|
|
19
|
+
children?: JsxRenderable;
|
|
20
|
+
class?: string;
|
|
21
|
+
'aria-label'?: string;
|
|
22
|
+
disabled?: boolean;
|
|
23
|
+
};
|
|
24
|
+
/** Optional open button placed inside `RuiComboboxControl`. */
|
|
25
|
+
export declare function RuiComboboxTrigger({ children, class: className, 'aria-label': ariaLabel, disabled, }: RuiComboboxTriggerProps): JsxRenderable;
|
|
26
|
+
export type RuiComboboxListboxProps = RadiantSlotProps & {
|
|
27
|
+
children: JsxRenderable;
|
|
28
|
+
class?: string;
|
|
29
|
+
};
|
|
30
|
+
/** Popup listbox slotted into `listbox` by default. */
|
|
31
|
+
export declare function RuiComboboxListbox({ slot, children, class: className }: RuiComboboxListboxProps): JsxRenderable;
|
|
32
|
+
export type RuiComboboxOptionProps = {
|
|
33
|
+
value: string;
|
|
34
|
+
/** Display text committed to the input when selected. Defaults to `children` text. */
|
|
35
|
+
label?: string;
|
|
36
|
+
children: JsxRenderable;
|
|
37
|
+
class?: string;
|
|
38
|
+
disabled?: boolean;
|
|
39
|
+
};
|
|
40
|
+
/** Listbox option placed inside `RuiComboboxListbox`. */
|
|
41
|
+
export declare function RuiComboboxOption({ value, label, children, class: className, disabled }: RuiComboboxOptionProps): JsxRenderable;
|
|
42
|
+
export type RuiComboboxOptionData = {
|
|
43
|
+
value: string;
|
|
44
|
+
label: JsxRenderable;
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* Combobox view. Pair with `RuiLabel` (sibling or via `RuiField`) for the visible name —
|
|
48
|
+
* do not nest a combobox-specific label.
|
|
49
|
+
*/
|
|
50
|
+
export declare const RuiCombobox: import("../../../lib/radiant-view").RadiantViewComponent<RuiComboboxProps & RadiantSlotProps & {
|
|
51
|
+
options?: RuiComboboxOptionData[];
|
|
52
|
+
children?: JsxRenderable;
|
|
53
|
+
}>;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { RadiantElement } from '@ecopages/radiant';
|
|
2
|
+
import type { EventEmitter } from '@ecopages/radiant/tools/event-emitter';
|
|
3
|
+
export type RuiComboboxProps = {
|
|
4
|
+
value?: string;
|
|
5
|
+
/** Accessible name when there is no visible `RuiLabel` associated with the input. */
|
|
6
|
+
label?: string;
|
|
7
|
+
placeholder?: string;
|
|
8
|
+
disabled?: boolean;
|
|
9
|
+
/**
|
|
10
|
+
* When true, focusing the input opens the listbox (visual focus stays on the
|
|
11
|
+
* input until ArrowDown / ArrowUp). Defaults to false — APG list autocomplete
|
|
12
|
+
* opens on ArrowDown, typing, or the trigger button.
|
|
13
|
+
*/
|
|
14
|
+
openOnFocus?: boolean;
|
|
15
|
+
};
|
|
16
|
+
export type RuiComboboxChangeDetail = {
|
|
17
|
+
value: string;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* `<rui-combobox>` — a composition-first combobox with a listbox popup.
|
|
21
|
+
*
|
|
22
|
+
* Implements the APG Combobox pattern (list autocomplete, manual selection).
|
|
23
|
+
* DOM focus stays on the combobox input; visual focus moves into the popup via
|
|
24
|
+
* `aria-activedescendant` when the user presses ArrowDown / ArrowUp.
|
|
25
|
+
*
|
|
26
|
+
* Pair with `RuiLabel` (sibling, or via `RuiField`) for the visible name.
|
|
27
|
+
* Compose with `data-combobox-input`, optional `data-combobox-trigger`,
|
|
28
|
+
* `data-combobox-listbox`, and `data-combobox-option` (see view helpers).
|
|
29
|
+
*
|
|
30
|
+
* @see https://www.w3.org/WAI/ARIA/apg/patterns/combobox/
|
|
31
|
+
* @see https://www.w3.org/WAI/ARIA/apg/patterns/combobox/examples/combobox-autocomplete-list/
|
|
32
|
+
* @element rui-combobox
|
|
33
|
+
* @slot control - Input row (`RuiComboboxControl` with input and trigger).
|
|
34
|
+
* @slot listbox - Popup listbox (`RuiComboboxListbox`).
|
|
35
|
+
* @fires rui-change
|
|
36
|
+
*/
|
|
37
|
+
export declare class RuiCombobox extends RadiantElement {
|
|
38
|
+
value: string;
|
|
39
|
+
label: string;
|
|
40
|
+
placeholder: string;
|
|
41
|
+
disabled: boolean;
|
|
42
|
+
openOnFocus: boolean;
|
|
43
|
+
changeEvent: EventEmitter<RuiComboboxChangeDetail>;
|
|
44
|
+
private open;
|
|
45
|
+
/** True when visual focus is in the listbox (aria-activedescendant is set). */
|
|
46
|
+
private listboxHasVisualFocus;
|
|
47
|
+
private activeIndex;
|
|
48
|
+
private skipNextFocusOpen;
|
|
49
|
+
private readonly uid;
|
|
50
|
+
private get listboxId();
|
|
51
|
+
private get inputId();
|
|
52
|
+
private getInput;
|
|
53
|
+
private getTrigger;
|
|
54
|
+
private getListbox;
|
|
55
|
+
private getOptions;
|
|
56
|
+
private getVisibleOptions;
|
|
57
|
+
private getOptionLabel;
|
|
58
|
+
private ensureOptionIds;
|
|
59
|
+
private getAccessibleName;
|
|
60
|
+
private isComboboxInput;
|
|
61
|
+
/** Prefer `RuiLabel` as a previous sibling or Field-managed label. */
|
|
62
|
+
private findAssociatedLabel;
|
|
63
|
+
private syncLabel;
|
|
64
|
+
private syncTrigger;
|
|
65
|
+
private syncInput;
|
|
66
|
+
private clearActiveOption;
|
|
67
|
+
private setActiveOption;
|
|
68
|
+
private setVisualFocusCombobox;
|
|
69
|
+
private setOpen;
|
|
70
|
+
private filterOptions;
|
|
71
|
+
private select;
|
|
72
|
+
private syncFromValue;
|
|
73
|
+
private initialize;
|
|
74
|
+
connectedCallback(): void;
|
|
75
|
+
onPropsUpdated(): void;
|
|
76
|
+
onRootFocusIn(event: FocusEvent): void;
|
|
77
|
+
onRootInput(event: Event): void;
|
|
78
|
+
onRootKeydown(event: KeyboardEvent): void;
|
|
79
|
+
/** Filter, open, and move the active option by one step (wrapping) toward `direction`. */
|
|
80
|
+
private moveActive;
|
|
81
|
+
private handleInputKeydown;
|
|
82
|
+
onTriggerClick(event: Event): void;
|
|
83
|
+
onOptionPointerOver(event: Event): void;
|
|
84
|
+
onOptionMouseDown(event: Event): void;
|
|
85
|
+
onOptionClick(event: Event): void;
|
|
86
|
+
onFocusOut(event: FocusEvent): void;
|
|
87
|
+
onDocumentClick(event: Event): void;
|
|
88
|
+
render(): import("@ecopages/jsx").JsxRenderable;
|
|
89
|
+
}
|