@chromvoid/uikit 0.1.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/LICENSE +8 -0
- package/README.md +96 -0
- package/dist/components/cv-accordion-item.d.ts +69 -0
- package/dist/components/cv-accordion-item.js +176 -0
- package/dist/components/cv-accordion.d.ts +79 -0
- package/dist/components/cv-accordion.js +310 -0
- package/dist/components/cv-alert-dialog.d.ts +86 -0
- package/dist/components/cv-alert-dialog.js +393 -0
- package/dist/components/cv-alert.d.ts +48 -0
- package/dist/components/cv-alert.js +156 -0
- package/dist/components/cv-badge.d.ts +56 -0
- package/dist/components/cv-badge.js +280 -0
- package/dist/components/cv-breadcrumb-item.d.ts +35 -0
- package/dist/components/cv-breadcrumb-item.js +64 -0
- package/dist/components/cv-breadcrumb.d.ts +39 -0
- package/dist/components/cv-breadcrumb.js +160 -0
- package/dist/components/cv-button.d.ts +83 -0
- package/dist/components/cv-button.js +541 -0
- package/dist/components/cv-callout.d.ts +32 -0
- package/dist/components/cv-callout.js +221 -0
- package/dist/components/cv-card.d.ts +48 -0
- package/dist/components/cv-card.js +269 -0
- package/dist/components/cv-carousel-slide.d.ts +25 -0
- package/dist/components/cv-carousel-slide.js +51 -0
- package/dist/components/cv-carousel.d.ts +96 -0
- package/dist/components/cv-carousel.js +457 -0
- package/dist/components/cv-checkbox.d.ts +84 -0
- package/dist/components/cv-checkbox.js +274 -0
- package/dist/components/cv-combobox-group.d.ts +15 -0
- package/dist/components/cv-combobox-group.js +34 -0
- package/dist/components/cv-combobox-option.d.ts +30 -0
- package/dist/components/cv-combobox-option.js +66 -0
- package/dist/components/cv-combobox.d.ts +135 -0
- package/dist/components/cv-combobox.js +834 -0
- package/dist/components/cv-command-item.d.ts +30 -0
- package/dist/components/cv-command-item.js +68 -0
- package/dist/components/cv-command-palette.d.ts +105 -0
- package/dist/components/cv-command-palette.js +578 -0
- package/dist/components/cv-context-menu.d.ts +98 -0
- package/dist/components/cv-context-menu.js +515 -0
- package/dist/components/cv-copy-button.d.ts +61 -0
- package/dist/components/cv-copy-button.js +318 -0
- package/dist/components/cv-date-picker.d.ts +161 -0
- package/dist/components/cv-date-picker.js +803 -0
- package/dist/components/cv-dialog.d.ts +89 -0
- package/dist/components/cv-dialog.js +459 -0
- package/dist/components/cv-disclosure.d.ts +57 -0
- package/dist/components/cv-disclosure.js +241 -0
- package/dist/components/cv-drawer.d.ts +102 -0
- package/dist/components/cv-drawer.js +595 -0
- package/dist/components/cv-feed-article.d.ts +26 -0
- package/dist/components/cv-feed-article.js +52 -0
- package/dist/components/cv-feed.d.ts +62 -0
- package/dist/components/cv-feed.js +310 -0
- package/dist/components/cv-grid-cell.d.ts +30 -0
- package/dist/components/cv-grid-cell.js +57 -0
- package/dist/components/cv-grid-column.d.ts +30 -0
- package/dist/components/cv-grid-column.js +43 -0
- package/dist/components/cv-grid-row.d.ts +30 -0
- package/dist/components/cv-grid-row.js +42 -0
- package/dist/components/cv-grid.d.ts +119 -0
- package/dist/components/cv-grid.js +567 -0
- package/dist/components/cv-icon.d.ts +57 -0
- package/dist/components/cv-icon.js +352 -0
- package/dist/components/cv-input.d.ts +127 -0
- package/dist/components/cv-input.js +482 -0
- package/dist/components/cv-landmark.d.ts +32 -0
- package/dist/components/cv-landmark.js +62 -0
- package/dist/components/cv-link.d.ts +22 -0
- package/dist/components/cv-link.js +99 -0
- package/dist/components/cv-listbox-group.d.ts +15 -0
- package/dist/components/cv-listbox-group.js +42 -0
- package/dist/components/cv-listbox.d.ts +81 -0
- package/dist/components/cv-listbox.js +388 -0
- package/dist/components/cv-menu-button.d.ts +118 -0
- package/dist/components/cv-menu-button.js +822 -0
- package/dist/components/cv-menu-group.d.ts +20 -0
- package/dist/components/cv-menu-group.js +48 -0
- package/dist/components/cv-menu-item.d.ts +52 -0
- package/dist/components/cv-menu-item.js +105 -0
- package/dist/components/cv-menu.d.ts +62 -0
- package/dist/components/cv-menu.js +414 -0
- package/dist/components/cv-meter.d.ts +66 -0
- package/dist/components/cv-meter.js +154 -0
- package/dist/components/cv-number.d.ts +139 -0
- package/dist/components/cv-number.js +553 -0
- package/dist/components/cv-option.d.ts +30 -0
- package/dist/components/cv-option.js +84 -0
- package/dist/components/cv-popover.d.ts +87 -0
- package/dist/components/cv-popover.js +373 -0
- package/dist/components/cv-progress-ring.d.ts +45 -0
- package/dist/components/cv-progress-ring.js +169 -0
- package/dist/components/cv-progress.d.ts +45 -0
- package/dist/components/cv-progress.js +148 -0
- package/dist/components/cv-radio-group.d.ts +79 -0
- package/dist/components/cv-radio-group.js +398 -0
- package/dist/components/cv-radio.d.ts +36 -0
- package/dist/components/cv-radio.js +123 -0
- package/dist/components/cv-select-group.d.ts +15 -0
- package/dist/components/cv-select-group.js +44 -0
- package/dist/components/cv-select-option.d.ts +30 -0
- package/dist/components/cv-select-option.js +66 -0
- package/dist/components/cv-select.d.ts +128 -0
- package/dist/components/cv-select.js +666 -0
- package/dist/components/cv-sidebar-item.d.ts +26 -0
- package/dist/components/cv-sidebar-item.js +142 -0
- package/dist/components/cv-sidebar.d.ts +171 -0
- package/dist/components/cv-sidebar.js +767 -0
- package/dist/components/cv-slider-multi-thumb.d.ts +73 -0
- package/dist/components/cv-slider-multi-thumb.js +374 -0
- package/dist/components/cv-slider.d.ts +84 -0
- package/dist/components/cv-slider.js +328 -0
- package/dist/components/cv-spinbutton.d.ts +121 -0
- package/dist/components/cv-spinbutton.js +486 -0
- package/dist/components/cv-spinner.d.ts +18 -0
- package/dist/components/cv-spinner.js +95 -0
- package/dist/components/cv-switch.d.ts +81 -0
- package/dist/components/cv-switch.js +285 -0
- package/dist/components/cv-tab-panel.d.ts +20 -0
- package/dist/components/cv-tab-panel.js +37 -0
- package/dist/components/cv-tab.d.ts +40 -0
- package/dist/components/cv-tab.js +132 -0
- package/dist/components/cv-table-cell.d.ts +31 -0
- package/dist/components/cv-table-cell.js +49 -0
- package/dist/components/cv-table-column.d.ts +37 -0
- package/dist/components/cv-table-column.js +63 -0
- package/dist/components/cv-table-row.d.ts +30 -0
- package/dist/components/cv-table-row.js +45 -0
- package/dist/components/cv-table.d.ts +147 -0
- package/dist/components/cv-table.js +607 -0
- package/dist/components/cv-tabs.d.ts +70 -0
- package/dist/components/cv-tabs.js +524 -0
- package/dist/components/cv-textarea.d.ts +108 -0
- package/dist/components/cv-textarea.js +328 -0
- package/dist/components/cv-toast-region.d.ts +39 -0
- package/dist/components/cv-toast-region.js +162 -0
- package/dist/components/cv-toast.d.ts +67 -0
- package/dist/components/cv-toast.js +315 -0
- package/dist/components/cv-toolbar-item.d.ts +25 -0
- package/dist/components/cv-toolbar-item.js +72 -0
- package/dist/components/cv-toolbar-separator.d.ts +25 -0
- package/dist/components/cv-toolbar-separator.js +45 -0
- package/dist/components/cv-toolbar.d.ts +63 -0
- package/dist/components/cv-toolbar.js +295 -0
- package/dist/components/cv-tooltip.d.ts +83 -0
- package/dist/components/cv-tooltip.js +455 -0
- package/dist/components/cv-treegrid-cell.d.ts +30 -0
- package/dist/components/cv-treegrid-cell.js +57 -0
- package/dist/components/cv-treegrid-column.d.ts +37 -0
- package/dist/components/cv-treegrid-column.js +53 -0
- package/dist/components/cv-treegrid-row.d.ts +55 -0
- package/dist/components/cv-treegrid-row.js +90 -0
- package/dist/components/cv-treegrid.d.ts +96 -0
- package/dist/components/cv-treegrid.js +632 -0
- package/dist/components/cv-treeitem.d.ts +58 -0
- package/dist/components/cv-treeitem.js +144 -0
- package/dist/components/cv-treeview.d.ts +70 -0
- package/dist/components/cv-treeview.js +396 -0
- package/dist/components/cv-window-splitter.d.ts +79 -0
- package/dist/components/cv-window-splitter.js +316 -0
- package/dist/components/index.d.ts +94 -0
- package/dist/components/index.js +79 -0
- package/dist/dialog/create-dialog-controller.d.ts +31 -0
- package/dist/dialog/create-dialog-controller.js +320 -0
- package/dist/dialog/index.d.ts +2 -0
- package/dist/dialog/index.js +1 -0
- package/dist/form-associated/FormAssociatedReatomElement.d.ts +25 -0
- package/dist/form-associated/FormAssociatedReatomElement.js +70 -0
- package/dist/form-associated/withFormAssociated.d.ts +5 -0
- package/dist/form-associated/withFormAssociated.js +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +9 -0
- package/dist/reatom-lit/ReatomLitElement.d.ts +27 -0
- package/dist/reatom-lit/ReatomLitElement.js +118 -0
- package/dist/reatom-lit/html.d.ts +4 -0
- package/dist/reatom-lit/html.js +10 -0
- package/dist/reatom-lit/index.d.ts +4 -0
- package/dist/reatom-lit/index.js +4 -0
- package/dist/reatom-lit/watch.d.ts +15 -0
- package/dist/reatom-lit/watch.js +40 -0
- package/dist/reatom-lit/withReatomElement.d.ts +4 -0
- package/dist/reatom-lit/withReatomElement.js +57 -0
- package/dist/register.d.ts +1 -0
- package/dist/register.js +84 -0
- package/dist/styles/component-styles.d.ts +4 -0
- package/dist/styles/component-styles.js +78 -0
- package/dist/theme/cv-theme-provider.d.ts +32 -0
- package/dist/theme/cv-theme-provider.js +110 -0
- package/dist/theme/index.d.ts +4 -0
- package/dist/theme/index.js +2 -0
- package/dist/theme/theme-engine.d.ts +4 -0
- package/dist/theme/theme-engine.js +67 -0
- package/dist/theme/tokens.css +265 -0
- package/dist/theme/types.d.ts +7 -0
- package/dist/theme/types.js +1 -0
- package/dist/toast/create-toast-controller.d.ts +12 -0
- package/dist/toast/create-toast-controller.js +12 -0
- package/dist/toast/index.d.ts +2 -0
- package/dist/toast/index.js +1 -0
- package/package.json +146 -0
- package/specs/_template.md +110 -0
- package/specs/components/accordion.md +207 -0
- package/specs/components/alert.md +83 -0
- package/specs/components/badge.md +183 -0
- package/specs/components/breadcrumb.md +152 -0
- package/specs/components/button.md +227 -0
- package/specs/components/callout.md +153 -0
- package/specs/components/card.md +192 -0
- package/specs/components/carousel.md +232 -0
- package/specs/components/checkbox.md +141 -0
- package/specs/components/combobox.md +427 -0
- package/specs/components/context-menu.md +375 -0
- package/specs/components/copy-button.md +236 -0
- package/specs/components/date-picker.md +290 -0
- package/specs/components/dialog.md +184 -0
- package/specs/components/disclosure.md +151 -0
- package/specs/components/drawer.md +216 -0
- package/specs/components/feed.md +266 -0
- package/specs/components/grid.md +423 -0
- package/specs/components/input.md +237 -0
- package/specs/components/landmark.md +92 -0
- package/specs/components/link.md +117 -0
- package/specs/components/listbox.md +327 -0
- package/specs/components/menu.md +508 -0
- package/specs/components/meter.md +148 -0
- package/specs/components/number.md +268 -0
- package/specs/components/option.md +167 -0
- package/specs/components/popover.md +207 -0
- package/specs/components/progress-ring.md +134 -0
- package/specs/components/progress.md +110 -0
- package/specs/components/radio.md +208 -0
- package/specs/components/select.md +305 -0
- package/specs/components/sidebar.md +204 -0
- package/specs/components/spinbutton.md +157 -0
- package/specs/components/spinner.md +83 -0
- package/specs/components/switch.md +145 -0
- package/specs/components/table.md +372 -0
- package/specs/components/tabs.md +242 -0
- package/specs/components/textarea.md +166 -0
- package/specs/components/theme.md +364 -0
- package/specs/components/toast.md +198 -0
- package/specs/components/toolbar.md +258 -0
- package/specs/components/tooltip.md +152 -0
- package/specs/components/treegrid.md +363 -0
- package/specs/components/treeview.md +263 -0
- package/specs/components/window-splitter.md +225 -0
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
# cv-carousel
|
|
2
|
+
|
|
3
|
+
Slideshow component that cycles through a set of slides with navigation controls, indicators, and optional autoplay.
|
|
4
|
+
|
|
5
|
+
**Headless:** [`createCarousel`](https://github.com/chromvoid/headless-ui/blob/main/specs/components/carousel.md)
|
|
6
|
+
|
|
7
|
+
## Anatomy
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
<cv-carousel> (host)
|
|
11
|
+
└── <section part="base" role="region" aria-roledescription="carousel">
|
|
12
|
+
├── <div part="controls">
|
|
13
|
+
│ ├── <button part="control prev" aria-label="Previous slide">
|
|
14
|
+
│ ├── <button part="control next" aria-label="Next slide">
|
|
15
|
+
│ └── <button part="control play-pause" aria-label="Stop/Start slide rotation">
|
|
16
|
+
├── <div part="slides" role="group">
|
|
17
|
+
│ └── <slot> ← cv-carousel-slide elements
|
|
18
|
+
└── <div part="indicators">
|
|
19
|
+
└── <button part="indicator"> ← one per slide
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Attributes
|
|
23
|
+
|
|
24
|
+
| Attribute | Type | Default | Description |
|
|
25
|
+
| ------------------- | ------- | ------- | ------------------------------------------------------------------- |
|
|
26
|
+
| `value` | String | `""` | Identifier of the active slide (matches `cv-carousel-slide[value]`) |
|
|
27
|
+
| `active-index` | Number | `0` | Zero-based index of the active slide |
|
|
28
|
+
| `autoplay` | Boolean | `false` | Enables automatic slide rotation |
|
|
29
|
+
| `autoplay-interval` | Number | `5000` | Autoplay interval in milliseconds |
|
|
30
|
+
| `visible-slides` | Number | `1` | Number of slides visible at once |
|
|
31
|
+
| `paused` | Boolean | `false` | Whether autoplay is paused |
|
|
32
|
+
| `aria-label` | String | `""` | Accessible name for the carousel region |
|
|
33
|
+
| `aria-labelledby` | String | `""` | ID of the element that labels the carousel |
|
|
34
|
+
|
|
35
|
+
`value` and `active-index` are synchronized: setting one updates the other. When both are set, `value` takes precedence.
|
|
36
|
+
|
|
37
|
+
## Slots
|
|
38
|
+
|
|
39
|
+
| Slot | Description |
|
|
40
|
+
| ----------- | ---------------------------- |
|
|
41
|
+
| `(default)` | `cv-carousel-slide` elements |
|
|
42
|
+
|
|
43
|
+
## CSS Parts
|
|
44
|
+
|
|
45
|
+
| Part | Element | Description |
|
|
46
|
+
| ------------ | ----------- | ---------------------------------------------------------------------------- |
|
|
47
|
+
| `base` | `<section>` | Root wrapper with `role="region"` and `aria-roledescription="carousel"` |
|
|
48
|
+
| `controls` | `<div>` | Container for navigation and play/pause buttons |
|
|
49
|
+
| `slides` | `<div>` | Slide container with `role="group"` |
|
|
50
|
+
| `indicators` | `<div>` | Container for indicator buttons |
|
|
51
|
+
| `control` | `<button>` | Shared part on all control buttons (prev, next, play-pause) |
|
|
52
|
+
| `prev` | `<button>` | Previous slide button (also has `control` part) |
|
|
53
|
+
| `next` | `<button>` | Next slide button (also has `control` part) |
|
|
54
|
+
| `play-pause` | `<button>` | Play/pause toggle button (also has `control` part) |
|
|
55
|
+
| `indicator` | `<button>` | Individual indicator button; `[data-active="true"]` when its slide is active |
|
|
56
|
+
|
|
57
|
+
## CSS Custom Properties
|
|
58
|
+
|
|
59
|
+
| Property | Default | Description |
|
|
60
|
+
| -------------------------------- | -------------------------- | --------------------------------------------------------------- |
|
|
61
|
+
| `--cv-carousel-gap` | `var(--cv-space-2, 8px)` | Gap between base layout sections (controls, slides, indicators) |
|
|
62
|
+
| `--cv-carousel-control-size` | `32px` | Min block/inline size of control and indicator buttons |
|
|
63
|
+
| `--cv-carousel-control-radius` | `var(--cv-radius-sm, 6px)` | Border radius of control and indicator buttons |
|
|
64
|
+
| `--cv-carousel-slide-min-height` | `120px` | Minimum block size of each slide |
|
|
65
|
+
|
|
66
|
+
## Visual States
|
|
67
|
+
|
|
68
|
+
| Host selector | Description |
|
|
69
|
+
| ----------------------- | ---------------------------------------------------------- |
|
|
70
|
+
| `:host([autoplay])` | Autoplay is enabled |
|
|
71
|
+
| `:host([paused])` | Autoplay is paused (user-initiated or focus/hover-induced) |
|
|
72
|
+
| `:host([active-index])` | Reflects the current active slide index |
|
|
73
|
+
|
|
74
|
+
## Events
|
|
75
|
+
|
|
76
|
+
| Event | Detail | Description |
|
|
77
|
+
| ----------- | --------------------------------------------------------------------- | -------------------------------------------------------- |
|
|
78
|
+
| `cv-input` | `{activeIndex: number, activeValue: string \| null, paused: boolean}` | Fires on any state change (active index or paused state) |
|
|
79
|
+
| `cv-change` | `{activeIndex: number, activeValue: string \| null, paused: boolean}` | Fires when the active slide index changes |
|
|
80
|
+
|
|
81
|
+
Both events bubble and are composed. `cv-input` fires on every state change (index or pause). `cv-change` fires only when the active index changes.
|
|
82
|
+
|
|
83
|
+
## Reactive State Mapping
|
|
84
|
+
|
|
85
|
+
`cv-carousel` is a visual adapter over headless `createCarousel`.
|
|
86
|
+
|
|
87
|
+
| UIKit Property | Direction | Headless Binding |
|
|
88
|
+
| ------------------- | -------------- | ----------------------------------------------------------------- |
|
|
89
|
+
| `active-index` | attr -> action | `actions.moveTo(value)` |
|
|
90
|
+
| `value` | attr -> action | resolved to index via slide records, then `actions.moveTo(index)` |
|
|
91
|
+
| `paused` | attr -> action | `actions.pause()` / `actions.play()` |
|
|
92
|
+
| `autoplay` | attr -> option | passed as `autoplay` in `createCarousel(options)` |
|
|
93
|
+
| `autoplay-interval` | attr -> option | passed as `autoplayIntervalMs` in `createCarousel(options)` |
|
|
94
|
+
| `visible-slides` | attr -> option | passed as `visibleSlides` in `createCarousel(options)` |
|
|
95
|
+
| `aria-label` | attr -> option | passed as `ariaLabel` in `createCarousel(options)` |
|
|
96
|
+
| `aria-labelledby` | attr -> option | passed as `ariaLabelledBy` in `createCarousel(options)` |
|
|
97
|
+
|
|
98
|
+
| Headless State | Direction | DOM Reflection |
|
|
99
|
+
| ----------------------------- | --------------- | ---------------------------------------------------- |
|
|
100
|
+
| `state.activeSlideIndex()` | state -> attr | `[active-index]` host attribute |
|
|
101
|
+
| `state.isPaused()` | state -> attr | `[paused]` host attribute |
|
|
102
|
+
| `state.slideCount()` | state -> render | determines number of indicator buttons |
|
|
103
|
+
| `state.visibleSlideIndices()` | state -> render | determines `aria-hidden` and `data-active` on slides |
|
|
104
|
+
|
|
105
|
+
**Contract spreading:**
|
|
106
|
+
|
|
107
|
+
- `contracts.getRootProps()` is spread onto `[part="base"]` (`role`, `aria-roledescription`, `aria-label`, `aria-labelledby`, `aria-live`, focus/pointer handlers).
|
|
108
|
+
- `contracts.getSlideGroupProps()` is spread onto `[part="slides"]` (`role`, `aria-label`).
|
|
109
|
+
- `contracts.getSlideProps(index)` is spread onto each `cv-carousel-slide` element (`role`, `aria-roledescription`, `aria-label`, `aria-hidden`, `data-active`).
|
|
110
|
+
- `contracts.getPrevButtonProps()` is spread onto `[part="prev"]` (`aria-controls`, `aria-label`, `onClick`).
|
|
111
|
+
- `contracts.getNextButtonProps()` is spread onto `[part="next"]` (`aria-controls`, `aria-label`, `onClick`).
|
|
112
|
+
- `contracts.getPlayPauseButtonProps()` is spread onto `[part="play-pause"]` (`aria-controls`, `aria-label`, `onClick`). Returns `aria-label` only, no `aria-pressed` per W3C APG guidance.
|
|
113
|
+
- `contracts.getIndicatorProps(index)` is spread onto each `[part="indicator"]` (`aria-controls`, `aria-label`, `aria-current`, `data-active`, `onClick`).
|
|
114
|
+
|
|
115
|
+
**UIKit does NOT own:**
|
|
116
|
+
|
|
117
|
+
- Navigation logic (wrapping, clamping) -- headless `moveNext`/`movePrev`/`moveTo`.
|
|
118
|
+
- Autoplay timer lifecycle -- headless manages start/stop/resume.
|
|
119
|
+
- `aria-live` toggling -- headless sets `off` during autoplay, `polite` on manual navigation.
|
|
120
|
+
- Pause-on-focus / pause-on-hover -- headless focus/pointer handlers.
|
|
121
|
+
|
|
122
|
+
## Keyboard Interaction
|
|
123
|
+
|
|
124
|
+
Keyboard events are delegated to `actions.handleKeyDown()`. The UIKit layer only prevents default on carousel-relevant keys.
|
|
125
|
+
|
|
126
|
+
| Key | Action |
|
|
127
|
+
| ------------ | ---------------------- |
|
|
128
|
+
| `ArrowRight` | Move to next slide |
|
|
129
|
+
| `ArrowLeft` | Move to previous slide |
|
|
130
|
+
| `Home` | Move to first slide |
|
|
131
|
+
| `End` | Move to last slide |
|
|
132
|
+
|
|
133
|
+
## Swipe Gesture
|
|
134
|
+
|
|
135
|
+
The UIKit adapter provides basic horizontal swipe detection on the `[part="slides"]` area:
|
|
136
|
+
|
|
137
|
+
- A horizontal swipe right-to-left triggers `actions.moveNext()`.
|
|
138
|
+
- A horizontal swipe left-to-right triggers `actions.movePrev()`.
|
|
139
|
+
- Swipe detection uses `pointerdown` / `pointermove` / `pointerup` with a minimum distance threshold.
|
|
140
|
+
- Vertical scrolling is not intercepted; the gesture must be predominantly horizontal to trigger navigation.
|
|
141
|
+
|
|
142
|
+
This is a UIKit-only concern; the headless model does not handle touch/swipe.
|
|
143
|
+
|
|
144
|
+
## Imperative API
|
|
145
|
+
|
|
146
|
+
| Method | Description |
|
|
147
|
+
| --------- | ------------------------- |
|
|
148
|
+
| `next()` | Advance to the next slide |
|
|
149
|
+
| `prev()` | Go to the previous slide |
|
|
150
|
+
| `play()` | Resume autoplay |
|
|
151
|
+
| `pause()` | Pause autoplay |
|
|
152
|
+
|
|
153
|
+
## Usage
|
|
154
|
+
|
|
155
|
+
```html
|
|
156
|
+
<!-- Basic carousel -->
|
|
157
|
+
<cv-carousel aria-label="Product gallery">
|
|
158
|
+
<cv-carousel-slide value="slide-1">Slide 1 content</cv-carousel-slide>
|
|
159
|
+
<cv-carousel-slide value="slide-2">Slide 2 content</cv-carousel-slide>
|
|
160
|
+
<cv-carousel-slide value="slide-3">Slide 3 content</cv-carousel-slide>
|
|
161
|
+
</cv-carousel>
|
|
162
|
+
|
|
163
|
+
<!-- Autoplay carousel -->
|
|
164
|
+
<cv-carousel aria-label="News feed" autoplay autoplay-interval="3000">
|
|
165
|
+
<cv-carousel-slide value="news-1">Breaking news</cv-carousel-slide>
|
|
166
|
+
<cv-carousel-slide value="news-2">Sports update</cv-carousel-slide>
|
|
167
|
+
</cv-carousel>
|
|
168
|
+
|
|
169
|
+
<!-- Multiple visible slides -->
|
|
170
|
+
<cv-carousel aria-label="Team members" visible-slides="3">
|
|
171
|
+
<cv-carousel-slide value="member-1">Alice</cv-carousel-slide>
|
|
172
|
+
<cv-carousel-slide value="member-2">Bob</cv-carousel-slide>
|
|
173
|
+
<cv-carousel-slide value="member-3">Charlie</cv-carousel-slide>
|
|
174
|
+
<cv-carousel-slide value="member-4">Diana</cv-carousel-slide>
|
|
175
|
+
</cv-carousel>
|
|
176
|
+
|
|
177
|
+
<!-- Controlled by value -->
|
|
178
|
+
<cv-carousel aria-label="Steps" value="step-2">
|
|
179
|
+
<cv-carousel-slide value="step-1">Step 1</cv-carousel-slide>
|
|
180
|
+
<cv-carousel-slide value="step-2">Step 2</cv-carousel-slide>
|
|
181
|
+
<cv-carousel-slide value="step-3">Step 3</cv-carousel-slide>
|
|
182
|
+
</cv-carousel>
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
## Child Elements
|
|
186
|
+
|
|
187
|
+
### cv-carousel-slide
|
|
188
|
+
|
|
189
|
+
Individual slide within a carousel. The parent `cv-carousel` manages all ARIA attributes on this element via headless contracts.
|
|
190
|
+
|
|
191
|
+
#### Anatomy
|
|
192
|
+
|
|
193
|
+
```
|
|
194
|
+
<cv-carousel-slide> (host)
|
|
195
|
+
└── <div part="base">
|
|
196
|
+
└── <slot>
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
#### Attributes
|
|
200
|
+
|
|
201
|
+
| Attribute | Type | Default | Description |
|
|
202
|
+
| --------- | ------- | ------- | --------------------------------------------------------------------------- |
|
|
203
|
+
| `value` | String | `""` | Unique identifier for this slide. Auto-generated as `slide-{n}` if omitted. |
|
|
204
|
+
| `label` | String | `""` | Accessible label for the slide. Falls back to `textContent` if omitted. |
|
|
205
|
+
| `active` | Boolean | `false` | Whether this slide is currently active. Managed by parent. |
|
|
206
|
+
|
|
207
|
+
#### Slots
|
|
208
|
+
|
|
209
|
+
| Slot | Description |
|
|
210
|
+
| ----------- | ------------- |
|
|
211
|
+
| `(default)` | Slide content |
|
|
212
|
+
|
|
213
|
+
#### CSS Parts
|
|
214
|
+
|
|
215
|
+
| Part | Element | Description |
|
|
216
|
+
| ------ | ------- | ---------------------------------- |
|
|
217
|
+
| `base` | `<div>` | Root wrapper for the slide content |
|
|
218
|
+
|
|
219
|
+
#### CSS Custom Properties
|
|
220
|
+
|
|
221
|
+
| Property | Default | Description |
|
|
222
|
+
| -------------------------------- | --------------------------- | ------------------------------- |
|
|
223
|
+
| `--cv-carousel-slide-min-height` | `120px` | Minimum block size of the slide |
|
|
224
|
+
| `--cv-carousel-slide-padding` | `var(--cv-space-4, 16px)` | Padding inside the slide |
|
|
225
|
+
| `--cv-carousel-slide-radius` | `var(--cv-radius-md, 10px)` | Border radius of the slide |
|
|
226
|
+
|
|
227
|
+
#### Visual States
|
|
228
|
+
|
|
229
|
+
| Host selector | Description |
|
|
230
|
+
| ----------------- | ----------------------------------------------------------- |
|
|
231
|
+
| `:host([active])` | Slide is currently active; border uses `--cv-color-primary` |
|
|
232
|
+
| `:host([hidden])` | Slide is not visible; `display: none` |
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# cv-checkbox
|
|
2
|
+
|
|
3
|
+
Two-state or three-state (indeterminate) toggle control with a visual indicator.
|
|
4
|
+
|
|
5
|
+
**Headless:** [`createCheckbox`](https://github.com/chromvoid/headless-ui/blob/main/specs/components/checkbox.md)
|
|
6
|
+
|
|
7
|
+
## Cross-Spec Consistency
|
|
8
|
+
|
|
9
|
+
This document is the UIKit surface contract for Checkbox.
|
|
10
|
+
|
|
11
|
+
- The canonical state model, invariants, and user-driven transitions are defined by the headless spec.
|
|
12
|
+
- Any intentional divergence between UIKit and headless MUST be explicitly documented in both specs to prevent drift.
|
|
13
|
+
|
|
14
|
+
## Anatomy
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
<cv-checkbox> (host)
|
|
18
|
+
└── <div part="base" role="checkbox">
|
|
19
|
+
├── <span part="indicator">
|
|
20
|
+
│ └── <span part="checkmark">
|
|
21
|
+
└── <slot> ← label
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Attributes
|
|
25
|
+
|
|
26
|
+
| Attribute | Type | Default | Description |
|
|
27
|
+
| --------------- | ------- | ------- | -------------------------------------------------------------- |
|
|
28
|
+
| `checked` | Boolean | `false` | Checked state |
|
|
29
|
+
| `indeterminate` | Boolean | `false` | Indeterminate state (takes precedence over `checked` visually) |
|
|
30
|
+
| `disabled` | Boolean | `false` | Prevents interaction |
|
|
31
|
+
| `read-only` | Boolean | `false` | Visible but not toggleable |
|
|
32
|
+
|
|
33
|
+
## Slots
|
|
34
|
+
|
|
35
|
+
| Slot | Description |
|
|
36
|
+
| ----------- | ------------------------------------------- |
|
|
37
|
+
| `(default)` | Label text or content next to the indicator |
|
|
38
|
+
|
|
39
|
+
## CSS Parts
|
|
40
|
+
|
|
41
|
+
| Part | Element | Description |
|
|
42
|
+
| ----------- | -------- | ------------------------------------------------------------------------------- |
|
|
43
|
+
| `base` | `<div>` | Root interactive element with `role="checkbox"` |
|
|
44
|
+
| `indicator` | `<span>` | Box that contains the checkmark |
|
|
45
|
+
| `checkmark` | `<span>` | Visual mark inside the indicator (square when checked, line when indeterminate) |
|
|
46
|
+
|
|
47
|
+
## CSS Custom Properties
|
|
48
|
+
|
|
49
|
+
No component-specific custom properties. Styling uses design tokens:
|
|
50
|
+
|
|
51
|
+
- `--cv-space-2` — gap between indicator and label
|
|
52
|
+
- `--cv-radius-sm` — indicator border radius
|
|
53
|
+
- `--cv-color-border` — indicator border color
|
|
54
|
+
- `--cv-color-surface` — indicator background
|
|
55
|
+
- `--cv-color-primary` — checked/indeterminate accent color
|
|
56
|
+
- `--cv-color-text` — label text color
|
|
57
|
+
- `--cv-duration-fast` — transition duration
|
|
58
|
+
- `--cv-easing-standard` — transition easing
|
|
59
|
+
|
|
60
|
+
## Visual States
|
|
61
|
+
|
|
62
|
+
| Host selector | Description |
|
|
63
|
+
| ------------------------ | --------------------------------------------------------------- |
|
|
64
|
+
| `:host([checked])` | Primary-tinted indicator border and background, solid checkmark |
|
|
65
|
+
| `:host([indeterminate])` | Horizontal line checkmark (2px height, full width) |
|
|
66
|
+
| `:host([disabled])` | Reduced opacity (`0.55`), `cursor: not-allowed` |
|
|
67
|
+
|
|
68
|
+
## ARIA
|
|
69
|
+
|
|
70
|
+
- When `checked=true` and `indeterminate=false`, `aria-checked="true"`.
|
|
71
|
+
- When `checked=false` and `indeterminate=true`, `aria-checked="mixed"`.
|
|
72
|
+
- When `checked=false` and `indeterminate=false`, `aria-checked="false"`.
|
|
73
|
+
|
|
74
|
+
## State Invariants and Transitions
|
|
75
|
+
|
|
76
|
+
- Canonical conceptual states are exactly: `unchecked`, `checked`, `indeterminate`.
|
|
77
|
+
- If represented as booleans, `indeterminate=true` implies `checked=false`.
|
|
78
|
+
- User toggle transition: `indeterminate` -> `checked`.
|
|
79
|
+
- Disabled or read-only checkboxes do not respond to toggle actions.
|
|
80
|
+
|
|
81
|
+
## Events
|
|
82
|
+
|
|
83
|
+
| Event | Detail | Description |
|
|
84
|
+
| ----------- | -------------------------------------------------------------- | ------------------------ |
|
|
85
|
+
| `cv-input` | `{ checked: boolean, indeterminate: boolean, value?: string }` | Fires on toggle |
|
|
86
|
+
| `cv-change` | `{ checked: boolean, indeterminate: boolean, value?: string }` | Fires when state commits |
|
|
87
|
+
|
|
88
|
+
## Usage
|
|
89
|
+
|
|
90
|
+
```html
|
|
91
|
+
<cv-checkbox>Accept terms</cv-checkbox>
|
|
92
|
+
|
|
93
|
+
<cv-checkbox checked>Remember me</cv-checkbox>
|
|
94
|
+
|
|
95
|
+
<cv-checkbox indeterminate>Select all (partial)</cv-checkbox>
|
|
96
|
+
|
|
97
|
+
<cv-checkbox disabled>Unavailable option</cv-checkbox>
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Migration Notes (Non-normative)
|
|
101
|
+
|
|
102
|
+
This section documents known terminology/payload changes and the breaking-change communication policy.
|
|
103
|
+
|
|
104
|
+
### Terminology change: `mixed` -> `indeterminate`
|
|
105
|
+
|
|
106
|
+
- `indeterminate` is the canonical third-state term.
|
|
107
|
+
- `mixed` remains an ARIA token only (used exclusively in `aria-checked="mixed"`).
|
|
108
|
+
|
|
109
|
+
### Payload change: legacy detail -> current detail
|
|
110
|
+
|
|
111
|
+
- Old (legacy docs): `{ value: boolean | "mixed", checked: boolean, mixed: boolean }`.
|
|
112
|
+
- New (current contract): `{ checked: boolean, indeterminate: boolean, value?: string }`.
|
|
113
|
+
|
|
114
|
+
Mappings:
|
|
115
|
+
|
|
116
|
+
- `value === "mixed"` or `mixed === true` -> `indeterminate=true` and `checked=false`.
|
|
117
|
+
- Prefer reading `indeterminate` and `checked` instead of interpreting `value`.
|
|
118
|
+
|
|
119
|
+
### Breaking-change communication policy
|
|
120
|
+
|
|
121
|
+
This change is breaking for consumers that relied on legacy terminology (`mixed`) or the legacy event detail shape.
|
|
122
|
+
|
|
123
|
+
When this contract changes in a breaking way, this section MUST explicitly document:
|
|
124
|
+
|
|
125
|
+
- terminology changes (old term -> new term)
|
|
126
|
+
- payload shape changes (old shape -> new shape)
|
|
127
|
+
- a short statement that the change is breaking and requires consumer migration
|
|
128
|
+
|
|
129
|
+
### Parity matrix (Headless vs UIKit)
|
|
130
|
+
|
|
131
|
+
This matrix is intentionally short and exists to prevent drift between `headless-ui/specs/components/checkbox.md` and `uikit/specs/components/checkbox.md`.
|
|
132
|
+
|
|
133
|
+
| Surface | Headless | UIKit |
|
|
134
|
+
| ---------------------------- | ------------------------------------------ | ---------------------------------------- |
|
|
135
|
+
| Canonical third-state term | `indeterminate` | `indeterminate` attribute + event detail |
|
|
136
|
+
| ARIA token for third state | `aria-checked="mixed"` only | `aria-checked="mixed"` only |
|
|
137
|
+
| State representation | `checked:boolean`, `indeterminate:boolean` | `checked`/`indeterminate` attributes |
|
|
138
|
+
| User toggle transition | `indeterminate` -> `checked` | `indeterminate` -> `checked` |
|
|
139
|
+
| Disabled/read-only semantics | cannot toggle | cannot toggle |
|
|
140
|
+
| Payload on user interaction | N/A (actions/state API) | `{ checked, indeterminate, value? }` |
|
|
141
|
+
| Form primitives | specified (see headless spec) | not specified on `cv-checkbox` surface |
|