@pastweb/components-core 2.0.0 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Accordion/README.md +251 -0
- package/dist/Button/README.md +143 -0
- package/dist/Buttons/README.md +108 -0
- package/dist/Carousel/README.md +204 -0
- package/dist/Checkbox/README.md +140 -0
- package/dist/DateTimePicker/README.md +125 -0
- package/dist/DropDown/README.md +237 -0
- package/dist/FileUploader/README.md +224 -0
- package/dist/Icon/README.md +103 -0
- package/dist/Input/README.md +212 -0
- package/dist/Link/README.md +108 -0
- package/dist/Notification/README.md +141 -0
- package/dist/Pagination/README.md +147 -0
- package/dist/Panel/README.md +158 -0
- package/dist/Placeholder/README.md +124 -0
- package/dist/ProgressBar/README.md +137 -0
- package/dist/Radio/README.md +144 -0
- package/dist/RangeSlider/README.md +120 -0
- package/dist/ScrollArea/README.md +105 -0
- package/dist/Select/README.md +243 -0
- package/dist/SheetController/README.md +143 -0
- package/dist/Spinner/README.md +80 -0
- package/dist/SplitLayout/README.md +132 -0
- package/dist/Stepper/README.md +146 -0
- package/dist/Table/README.md +76 -0
- package/dist/Tabs/README.md +352 -0
- package/dist/Tabs/utils/index.d.cts +2 -1
- package/dist/Tag/README.md +90 -0
- package/dist/TaskBar/README.md +105 -0
- package/dist/TextArea/README.md +141 -0
- package/dist/ToastController/README.md +119 -0
- package/dist/Toggle/README.md +109 -0
- package/dist/Tooltip/README.md +128 -0
- package/dist/Walktour/README.md +188 -0
- package/dist/WindowController/README.md +190 -0
- package/package.json +5 -2
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
# Carousel
|
|
2
|
+
|
|
3
|
+
Carousel presents one item from an ordered collection and provides controls for
|
|
4
|
+
moving through the collection. Its web contract follows the WAI-ARIA carousel
|
|
5
|
+
pattern.
|
|
6
|
+
|
|
7
|
+
## When to use
|
|
8
|
+
|
|
9
|
+
Use a carousel only when the content has a meaningful sequence and users can
|
|
10
|
+
understand the page without seeing every slide.
|
|
11
|
+
|
|
12
|
+
## Carousel props
|
|
13
|
+
|
|
14
|
+
| PropName | Type | Required | Default | Description |
|
|
15
|
+
|---|---|---:|---:|---|
|
|
16
|
+
| `cls` | `(...args: ClassValue[]) => string` | yes | - | Resolves component and state classes. |
|
|
17
|
+
| `ariaLabel` | `string` | no | `'Carousel'` | Names the carousel region. Supply a content-specific label. |
|
|
18
|
+
| `className` | `string` | no | `""` | Adds classes to the carousel. |
|
|
19
|
+
| `current` | `number` | no | `0` | Sets the current slide index. |
|
|
20
|
+
| `disabled` | `boolean` | no | - | Prevents navigation and disables controls. |
|
|
21
|
+
| `id` | `string` | no | generated | Supplies the carousel ID. Generated IDs use the `carousel` prefix. |
|
|
22
|
+
| `showCommands` | `boolean` | no | `true` | Renders navigation controls. |
|
|
23
|
+
| `prevAriaLabel` | `string` | no | `'Previous slide'` | Names the previous control. |
|
|
24
|
+
| `nextAriaLabel` | `string` | no | `'Next slide'` | Names the next control. |
|
|
25
|
+
| `onCurrentChange` | `(current: number) => void` | no | - | Reports navigation changes. |
|
|
26
|
+
|
|
27
|
+
## CarouselItem props
|
|
28
|
+
|
|
29
|
+
| PropName | Type | Required | Default | Description |
|
|
30
|
+
|---|---|---:|---:|---|
|
|
31
|
+
| `cls` | `(...args: ClassValue[]) => string` | yes | - | Resolves item classes. |
|
|
32
|
+
| `className` | `string` | no | `""` | Adds classes to the slide. |
|
|
33
|
+
| `disabled` | `boolean` | no | - | Disables the slide and exposes its disabled state. |
|
|
34
|
+
|
|
35
|
+
## Mediator state
|
|
36
|
+
|
|
37
|
+
`carouselMediator` exposes renderer-ready state for the root semantics and
|
|
38
|
+
track presentation:
|
|
39
|
+
|
|
40
|
+
| State | Type | Description |
|
|
41
|
+
|---|---|---|
|
|
42
|
+
| `ariaLabel` | `string \| undefined` | Normalized carousel name. |
|
|
43
|
+
| `ariaLive` | `'off' \| 'polite'` | Live-region mode for slide changes. |
|
|
44
|
+
| `ariaRoleDescription` | `'carousel' \| undefined` | Carousel role description when the root is named. |
|
|
45
|
+
| `className` | `string` | Complete root class name. |
|
|
46
|
+
| `current` | `number` | Current slide index. |
|
|
47
|
+
| `isDisabled` | `true \| undefined` | Renderer-ready disabled and ARIA value. |
|
|
48
|
+
| `itemsCount` | `number` | Number of registered CarouselItem instances. |
|
|
49
|
+
| `prevAriaLabel` / `nextAriaLabel` | `string` | Normalized navigation-control names. |
|
|
50
|
+
| `role` | `'region' \| undefined` | Region role when the root is named. |
|
|
51
|
+
| `transform` | `string` | Renderer-ready track transform. |
|
|
52
|
+
|
|
53
|
+
`carouselItemMediator` reads the Carousel context internally and exposes the
|
|
54
|
+
following renderer-ready state:
|
|
55
|
+
|
|
56
|
+
| State | Type | Description |
|
|
57
|
+
|---|---|---|
|
|
58
|
+
| `ariaHidden` | `true \| undefined` | Hides an inactive slide from the accessibility tree. |
|
|
59
|
+
| `ariaLabel` | `string` | One-based position label in the form `n of total`. |
|
|
60
|
+
| `ariaRoleDescription` | `'slide'` | Renderer-ready slide role description. |
|
|
61
|
+
| `className` | `string` | Complete item class name, including active and disabled state classes. |
|
|
62
|
+
| `index` | `number` | Stable zero-based registration index. |
|
|
63
|
+
| `inert` | `true \| undefined` | Prevents interaction with descendants of an inactive slide. |
|
|
64
|
+
| `isActive` | `boolean` | Whether this item matches the current Carousel index. |
|
|
65
|
+
| `isDisabled` | `true \| undefined` | Normalized local or inherited disabled state. |
|
|
66
|
+
| `role` | `'group'` | Renderer-ready slide group role. |
|
|
67
|
+
|
|
68
|
+
## Carousel mediator context
|
|
69
|
+
|
|
70
|
+
`carouselMediator.getContext()` exposes live state and stable commands for
|
|
71
|
+
`CarouselItem` and custom descendant controls. Framework renderers publish this
|
|
72
|
+
contract through `CAROUSEL_CONTEXT_KEY`; command slots do not receive mediator
|
|
73
|
+
state or methods as slot props.
|
|
74
|
+
|
|
75
|
+
| Property or method | Type | Description |
|
|
76
|
+
|---|---|---|
|
|
77
|
+
| `current` | `number` | Live current slide index. |
|
|
78
|
+
| `isDisabled` | `true \| undefined` | Live normalized Carousel disabled state. |
|
|
79
|
+
| `itemsCount` | `number` | Live number of registered CarouselItem descendants. |
|
|
80
|
+
| `prev` | `() => void` | Selects the previous enabled position when navigation is available. |
|
|
81
|
+
| `next` | `() => void` | Selects the next enabled position when navigation is available. |
|
|
82
|
+
| `registerItem` | `() => number` | Registers a CarouselItem and returns its stable zero-based index. |
|
|
83
|
+
|
|
84
|
+
## Slots
|
|
85
|
+
|
|
86
|
+
| SlotName | Description | Access |
|
|
87
|
+
|---|---|---|
|
|
88
|
+
| default | Supplies `CarouselItem` children. | - |
|
|
89
|
+
| `commands` | Replaces the navigation controls while preserving behavior. | Carousel context |
|
|
90
|
+
|
|
91
|
+
## Utility classes
|
|
92
|
+
|
|
93
|
+
The Carousel does not currently define component-specific utility classes.
|
|
94
|
+
|
|
95
|
+
## CSS Variables
|
|
96
|
+
|
|
97
|
+
| Variable | Part | State | CSS property | Default | Description | Platforms |
|
|
98
|
+
|---|---|---|---|---|---|---|
|
|
99
|
+
| `--pw_Carousel_root_default_max-width` | `root` | `default` | `max-width` | `800px` | Maximum carousel width. | Web, Capacitor |
|
|
100
|
+
| `--pw_Carousel_root_disabled_opacity` | `root` | `disabled` | `opacity` | `var(--pw_disabled_opacity)` | Disabled carousel opacity. | Web, Capacitor, NativeScript |
|
|
101
|
+
| `--pw_Carousel_track_default_transition-duration` | `track` | `default` | `transition-duration` | `0.5s` | Slide movement duration. | Web, Capacitor; NativeScript adapter |
|
|
102
|
+
| `--pw_Carousel_control_default_background-color` | `control` | `default` | `background-color` | `rgba(0,0,0,.6)` | Control background. | Web, Capacitor, NativeScript |
|
|
103
|
+
| `--pw_Carousel_control_hover_background-color` | `control` | `hover` | `background-color` | `rgba(0,0,0,.8)` | Hover background. | Web, Capacitor |
|
|
104
|
+
| `--pw_Carousel_control_default_color` | `control` | `default` | `color` | `white` | Control foreground. | Web, Capacitor, NativeScript |
|
|
105
|
+
| `--pw_Carousel_control_default_padding` | `control` | `default` | `padding` | `0.75em 1em` | Control spacing. | Web, Capacitor, NativeScript |
|
|
106
|
+
| `--pw_Carousel_control_default_font-size` | `control` | `default` | `font-size` | `1.25em` | Control icon size. | Web, Capacitor, NativeScript |
|
|
107
|
+
| `--pw_Carousel_control_default_border-radius` | `control` | `default` | `border-radius` | `var(--pw_border-radius)` | Control corner radius. | Web, Capacitor, NativeScript |
|
|
108
|
+
| `--pw_Carousel_control_default_transition-duration` | `control` | `default` | `transition-duration` | `0.3s` | Control state duration. | Web, Capacitor |
|
|
109
|
+
| `--pw_CarouselItem_root_default_min-height` | `root` | `default` | `min-height` | `300px` | Minimum slide height. | Web, Capacitor, NativeScript |
|
|
110
|
+
| `--pw_CarouselItem_root_default_transition-duration` | `root` | `default` | `transition-duration` | `0.5s` | Slide visual transition duration. | Web, Capacitor; NativeScript adapter |
|
|
111
|
+
| `--pw_CarouselItem_root_disabled_opacity` | `root` | `disabled` | `opacity` | `var(--pw_disabled_opacity)` | Disabled slide opacity. | Web, Capacitor, NativeScript |
|
|
112
|
+
|
|
113
|
+
```xts
|
|
114
|
+
import { setContext, useBeforeMount, useBeforeUnmount, useMediator, withDefaultProps } from '@pastweb/x';
|
|
115
|
+
import {
|
|
116
|
+
carouselItemMediator,
|
|
117
|
+
carouselMediator,
|
|
118
|
+
CAROUSEL_CONTEXT_KEY,
|
|
119
|
+
DEFAULT_CAROUSEL_ITEM_PROPS,
|
|
120
|
+
DEFAULT_PROPS,
|
|
121
|
+
} from '@pastweb/components-core/Carousel';
|
|
122
|
+
|
|
123
|
+
export function Carousel(props: CarouselProps) {
|
|
124
|
+
const p = withDefaultProps<CarouselDefaultProps>(props, DEFAULT_PROPS);
|
|
125
|
+
const m = useMediator<CarouselMediator>(carouselMediator, p);
|
|
126
|
+
const s = m.state;
|
|
127
|
+
const c = m.getContext();
|
|
128
|
+
|
|
129
|
+
setContext(CAROUSEL_CONTEXT_KEY, c);
|
|
130
|
+
|
|
131
|
+
useBeforeUnmount(m.useBeforeUnmount);
|
|
132
|
+
|
|
133
|
+
return (
|
|
134
|
+
<div
|
|
135
|
+
id={m.id}
|
|
136
|
+
class={s.className}
|
|
137
|
+
role={s.role}
|
|
138
|
+
aria-roledescription={s.ariaRoleDescription}
|
|
139
|
+
aria-label={s.ariaLabel}
|
|
140
|
+
aria-disabled={s.isDisabled}
|
|
141
|
+
@keydown={m.onKeyDown}
|
|
142
|
+
>
|
|
143
|
+
<div class={p.cls('carouselInner')} #style={{ transform: s.transform }} aria-live={s.ariaLive}>
|
|
144
|
+
{p.children}
|
|
145
|
+
</div>
|
|
146
|
+
<slot #if={p.showCommands} name="commands">
|
|
147
|
+
<button class={p.cls('prev')} type="button" @click={m.prev} disabled={s.isDisabled} aria-disabled={s.isDisabled} aria-label={s.prevAriaLabel}>
|
|
148
|
+
<span aria-hidden="true">◄</span>
|
|
149
|
+
</button>
|
|
150
|
+
<button class={p.cls('next')} type="button" @click={m.next} disabled={s.isDisabled} aria-disabled={s.isDisabled} aria-label={s.nextAriaLabel}>
|
|
151
|
+
<span aria-hidden="true">►</span>
|
|
152
|
+
</button>
|
|
153
|
+
</slot>
|
|
154
|
+
</div>
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
export function CarouselItem(props: CarouselItemProps) {
|
|
159
|
+
const p = withDefaultProps<CarouselItemDefaultProps>(props, DEFAULT_CAROUSEL_ITEM_PROPS);
|
|
160
|
+
const m = useMediator<CarouselItemMediator>(carouselItemMediator, p);
|
|
161
|
+
const s = m.state;
|
|
162
|
+
|
|
163
|
+
useBeforeMount(m.useBeforeMount);
|
|
164
|
+
|
|
165
|
+
return (
|
|
166
|
+
<div
|
|
167
|
+
class={s.className}
|
|
168
|
+
role={s.role}
|
|
169
|
+
aria-roledescription={s.ariaRoleDescription}
|
|
170
|
+
aria-label={s.ariaLabel}
|
|
171
|
+
aria-hidden={s.ariaHidden}
|
|
172
|
+
aria-disabled={s.isDisabled}
|
|
173
|
+
inert={s.inert}
|
|
174
|
+
>
|
|
175
|
+
<slot />
|
|
176
|
+
</div>
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
## Keyboard interaction
|
|
182
|
+
|
|
183
|
+
- `Tab` and `Shift+Tab` move through the carousel and its native controls in document order.
|
|
184
|
+
- `ArrowLeft` and `ArrowRight` move to the previous and next slides when the carousel is focused.
|
|
185
|
+
- Collapsed or inactive slide content is inert and removed from sequential focus.
|
|
186
|
+
|
|
187
|
+
## Accessibility notes
|
|
188
|
+
|
|
189
|
+
- The carousel is a labelled region with `aria-roledescription="carousel"`.
|
|
190
|
+
- Slides use `role="group"`, expose their position, and inactive slides are
|
|
191
|
+
`aria-hidden` and inert.
|
|
192
|
+
- The default `ariaLabel` is `"Carousel"`. An explicit empty string omits the
|
|
193
|
+
root label, region role, and carousel role description.
|
|
194
|
+
- A disabled Carousel passes the same normalized `true` value to its
|
|
195
|
+
`is-disabled` class, control `disabled`/`aria-disabled` attributes, root
|
|
196
|
+
`aria-disabled`, and inherited CarouselItem state.
|
|
197
|
+
- Left and Right Arrow navigate; native buttons remain in normal tab order.
|
|
198
|
+
- Shared styles honor `prefers-reduced-motion` and `forced-colors`.
|
|
199
|
+
|
|
200
|
+
## Standards
|
|
201
|
+
|
|
202
|
+
- WCAG 2.2: https://www.w3.org/TR/WCAG22/
|
|
203
|
+
- WAI-ARIA Carousel pattern: https://www.w3.org/WAI/ARIA/apg/patterns/carousel/
|
|
204
|
+
- GOV.UK guidance: https://design-system.service.gov.uk/components/
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# Checkbox
|
|
2
|
+
|
|
3
|
+
Checkbox renders a native binary choice with a visible label or explicit
|
|
4
|
+
accessible name. Its rendering contract follows the WAI-ARIA Checkbox pattern
|
|
5
|
+
and targets WCAG 2.2 Level AA.
|
|
6
|
+
|
|
7
|
+
## When to use
|
|
8
|
+
|
|
9
|
+
Use a checkbox when users may independently select or clear one option. Provide
|
|
10
|
+
a concise visible label that describes the choice. Do not use a checkbox when
|
|
11
|
+
exactly one option must be selected from a group; use radio buttons then.
|
|
12
|
+
|
|
13
|
+
## Props
|
|
14
|
+
|
|
15
|
+
| PropName | Type | Required | Default | Description |
|
|
16
|
+
|---|---|---:|---:|---|
|
|
17
|
+
| `cls` | `(...args: ClassValue[]) => string` | yes | - | Resolves component and state classes. |
|
|
18
|
+
| `ariaLabel` | `string` | no | `"Checkbox"` | Names the checkbox when no visible `label` is supplied. Pass an empty string to omit the accessible name. |
|
|
19
|
+
| `checkChar` | `string` | no | `✔` | Supplies the default checked mark. |
|
|
20
|
+
| `className` | `string` | no | `""` | Adds classes to the wrapper. |
|
|
21
|
+
| `id` | `string` | no | generated | Supplies the native input ID. Generated IDs use the `checkbox` prefix. |
|
|
22
|
+
| `disabled` | `boolean` | no | - | Makes the choice unavailable. |
|
|
23
|
+
| `label` | `string` | no | `""` | Supplies the visible accessible label. |
|
|
24
|
+
| `labelPlacement` | `Placement` | no | `'top-start'` | Places the visible label around the box. |
|
|
25
|
+
| `name` | `string` | no | - | Supplies the form field name. |
|
|
26
|
+
| `value` | `boolean` | no | - | Controls the checked state. |
|
|
27
|
+
| `tabIndex` | `number` | no | `0` | Controls sequential focus order. Prefer the default document order. |
|
|
28
|
+
| `onChange` | `(checked: boolean) => void` | no | noop | Reports checked-state changes. |
|
|
29
|
+
|
|
30
|
+
## Mediator API
|
|
31
|
+
|
|
32
|
+
| Property | Type | Description |
|
|
33
|
+
|---|---|---|
|
|
34
|
+
| `id` | `string` | Resolved input ID. Generated IDs use the `checkbox` prefix; an explicit `id` is exposed as `_${id}`. |
|
|
35
|
+
|
|
36
|
+
## Mediator state
|
|
37
|
+
|
|
38
|
+
| Property | Type | Description |
|
|
39
|
+
|---|---|---|
|
|
40
|
+
| `ariaLabel` | `string \| undefined` | Normalized accessible name when no visible `label` is present. Empty labels are omitted. |
|
|
41
|
+
| `isDisabled` | `true \| undefined` | Is `true` when the checkbox is disabled; otherwise omitted. Renderers use this value directly for `.is-disabled`, `disabled`, and `aria-disabled`. |
|
|
42
|
+
| `value` | `boolean` | Checked state consumed as `.is-checked` and the native `checked` property. |
|
|
43
|
+
|
|
44
|
+
## Slots
|
|
45
|
+
|
|
46
|
+
| SlotName | Description | Default content | Props |
|
|
47
|
+
|---|---|---|---|
|
|
48
|
+
| `check` | Replaces the decorative checked mark. | `<span>{checkChar}</span>` | `{ checkChar }` |
|
|
49
|
+
|
|
50
|
+
## CSS Variables
|
|
51
|
+
|
|
52
|
+
| Variable | Part | State | CSS property | Default | Description | Platforms |
|
|
53
|
+
|---|---|---|---|---|---|---|
|
|
54
|
+
| `--pw_Checkbox_root_default_margin` | `root` | `default` | `margin` | shared margins | Component spacing. | Web, Capacitor, NativeScript |
|
|
55
|
+
| `--pw_Checkbox_root_disabled_opacity` | `root` | `disabled` | `opacity` | `var(--pw_disabled_opacity)` | Disabled opacity. | Web, Capacitor, NativeScript |
|
|
56
|
+
| `--pw_Checkbox_root_default_size` | `root` | `default` | `size` | line-height plus padding and border | Box width and height, with a 44px web minimum. | Web, Capacitor, NativeScript |
|
|
57
|
+
| `--pw_Checkbox_root_default_background-color` | `root` | `default` | `background-color` | `var(--pw_control_background-color)` | Box background. | Web, Capacitor, NativeScript |
|
|
58
|
+
| `--pw_Checkbox_root_default_border-color` | `root` | `default` | `border-color` | `var(--pw_border-color)` | Box border colour. | Web, Capacitor, NativeScript |
|
|
59
|
+
| `--pw_Checkbox_root_default_border-width` | `root` | `default` | `border-width` | `var(--pw_border-width)` | Box border width. | Web, Capacitor, NativeScript |
|
|
60
|
+
| `--pw_Checkbox_root_default_border-style` | `root` | `default` | `border-style` | `var(--pw_border-style)` | Box border style. | Web, Capacitor, NativeScript |
|
|
61
|
+
| `--pw_Checkbox_root_default_border-radius` | `root` | `default` | `border-radius` | `var(--pw_border-radius)` | Box corner radius. | Web, Capacitor, NativeScript |
|
|
62
|
+
| `--pw_Checkbox_check_default_size` | `check` | `default` | `font-size` | `1.5em` | Checked mark size. | Web, Capacitor, NativeScript |
|
|
63
|
+
| `--pw_Checkbox_label_default_color` | `label` | `default` | `color` | `var(--pw_label_text_color)` | Label colour. | Web, Capacitor, NativeScript |
|
|
64
|
+
|
|
65
|
+
```xts
|
|
66
|
+
import { useBeforeUnmount, useMediator, withDefaultProps } from '@pastweb/x';
|
|
67
|
+
import { checkboxMediator } from '@pastweb/components-core/Checkbox';
|
|
68
|
+
import { DEFAULT_PROPS } from './constants';
|
|
69
|
+
|
|
70
|
+
export function Checkbox(props: CheckboxProps) {
|
|
71
|
+
const p = withDefaultProps<CheckboxDefaultProps>(props, DEFAULT_PROPS);
|
|
72
|
+
const m = useMediator<CheckboxMediator>(checkboxMediator, p);
|
|
73
|
+
const s = m.state;
|
|
74
|
+
|
|
75
|
+
useBeforeUnmount(m.useBeforeUnmount);
|
|
76
|
+
|
|
77
|
+
return (
|
|
78
|
+
<div
|
|
79
|
+
class={p.cls('Checkbox', `label-${p.labelPlacement}`, p.className, {
|
|
80
|
+
'is-disabled': s.isDisabled,
|
|
81
|
+
'is-checked': s.value,
|
|
82
|
+
})}
|
|
83
|
+
>
|
|
84
|
+
<label class={p.cls('control')}>
|
|
85
|
+
<span class={p.cls('box')}>
|
|
86
|
+
<input
|
|
87
|
+
type="checkbox"
|
|
88
|
+
class={p.cls('input')}
|
|
89
|
+
id={m.id}
|
|
90
|
+
name={p.name}
|
|
91
|
+
checked={s.value}
|
|
92
|
+
disabled={s.isDisabled}
|
|
93
|
+
aria-disabled={s.isDisabled}
|
|
94
|
+
aria-label={s.ariaLabel}
|
|
95
|
+
tabIndex={p.tabIndex}
|
|
96
|
+
@change={event => m.onChange(event.target.checked)}
|
|
97
|
+
/>
|
|
98
|
+
<slot name="check" props={{ checkChar: p.checkChar }}>
|
|
99
|
+
<span class={p.cls('check')} aria-hidden="true">{p.checkChar}</span>
|
|
100
|
+
</slot>
|
|
101
|
+
</span>
|
|
102
|
+
<span #if={p.label} class={p.cls('label', p.labelPlacement)}>{p.label}</span>
|
|
103
|
+
</label>
|
|
104
|
+
</div>
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Keyboard interaction
|
|
110
|
+
|
|
111
|
+
- `Tab` and `Shift+Tab` move focus to and from the native checkbox in document order.
|
|
112
|
+
- `Space` toggles the checked state through native checkbox behavior.
|
|
113
|
+
|
|
114
|
+
## Accessibility notes
|
|
115
|
+
|
|
116
|
+
- The input remains a native checkbox. One wrapping label supplies the visible
|
|
117
|
+
accessible name, avoiding multiple labels for the same control.
|
|
118
|
+
- When visible label text is absent, the mediator exposes `ariaLabel`. The
|
|
119
|
+
default name is `Checkbox`. An explicit empty string omits the name.
|
|
120
|
+
- Disabled checkboxes use the native `disabled` property, `aria-disabled="true"`,
|
|
121
|
+
and the `is-disabled` class.
|
|
122
|
+
- Checked state is exposed through the native `checked` property and the
|
|
123
|
+
`is-checked` class.
|
|
124
|
+
- The decorative check is hidden from assistive technology. Replacement `check`
|
|
125
|
+
slot content must remain decorative.
|
|
126
|
+
- Shared web styles provide at least a 44 by 44 CSS-pixel target, visible focus,
|
|
127
|
+
forced-colours treatment, and reduced-motion behavior.
|
|
128
|
+
|
|
129
|
+
## Known limitations
|
|
130
|
+
|
|
131
|
+
- The custom checked mark is visual only. Do not place interactive content in
|
|
132
|
+
the `check` slot.
|
|
133
|
+
- Automated accessibility checks do not by themselves establish WCAG
|
|
134
|
+
conformance.
|
|
135
|
+
|
|
136
|
+
## Standards
|
|
137
|
+
|
|
138
|
+
- WCAG 2.2: https://www.w3.org/TR/WCAG22/
|
|
139
|
+
- WAI-ARIA Checkbox pattern: https://www.w3.org/WAI/ARIA/apg/patterns/checkbox/
|
|
140
|
+
- GOV.UK Checkboxes guidance: https://design-system.service.gov.uk/components/checkboxes/
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# DateTimePicker
|
|
2
|
+
|
|
3
|
+
`DateTimePicker` is a framework-neutral calendar and time-selection mediator. Renderers provide the target and popup integration; the mediator owns value normalization, single/multiple/range selection, calendar navigation, date rules, and keyboard intent.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- Single, multiple, and range date selection.
|
|
8
|
+
- Optional time selection, calendar-only, and time-only modes.
|
|
9
|
+
- Controlled or uncontrolled popup visibility and selected values.
|
|
10
|
+
- Keyboard calendar navigation, date rules, localized labels, and accessible IDs.
|
|
11
|
+
- A renderer-neutral target-props context for custom trigger implementations.
|
|
12
|
+
|
|
13
|
+
```xts
|
|
14
|
+
<DateTimePicker
|
|
15
|
+
mode="range"
|
|
16
|
+
enableTime
|
|
17
|
+
minDate={today}
|
|
18
|
+
disable={[weekends]}
|
|
19
|
+
locale={{ months, weekdays, clear: 'Clear' }}
|
|
20
|
+
onChange={value => booking.dates = value}
|
|
21
|
+
/>
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Values
|
|
25
|
+
|
|
26
|
+
Use a `Date`, an array of `Date` values, or `null`. `single` returns one date in an array internally and `multiple`/`range` return arrays. The public change callback uses `Date | Date[] | null` so consumers can preserve the same value shape they provide.
|
|
27
|
+
|
|
28
|
+
```xts
|
|
29
|
+
<DateTimePicker value={departure} onChange={value => departure = value} />
|
|
30
|
+
<DateTimePicker mode="multiple" defaultValue={[firstDate, secondDate]} />
|
|
31
|
+
<DateTimePicker mode="range" value={stay} />
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Calendar rules and language
|
|
35
|
+
|
|
36
|
+
`minDate`, `maxDate`, `disable`, and `enable` constrain selection. Rules accept a date, an inclusive `{ from, to }` range, or a predicate returning `true` when it matches.
|
|
37
|
+
|
|
38
|
+
The component does not read an application i18n service. Supply the calendar words directly with `locale` when a language is required.
|
|
39
|
+
|
|
40
|
+
```xts
|
|
41
|
+
<DateTimePicker
|
|
42
|
+
minDate={today}
|
|
43
|
+
disable={[date => date.getDay() === 0 || date.getDay() === 6]}
|
|
44
|
+
locale={{
|
|
45
|
+
months: italianMonths,
|
|
46
|
+
weekdays: italianWeekdays,
|
|
47
|
+
previousMonth: 'Mese precedente',
|
|
48
|
+
nextMonth: 'Mese successivo',
|
|
49
|
+
}}
|
|
50
|
+
/>
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Rendering modes
|
|
54
|
+
|
|
55
|
+
The default picker is positioned locally, like `Select`. Set `inline` for an always-visible calendar that does not open and close.
|
|
56
|
+
|
|
57
|
+
```xts
|
|
58
|
+
<DateTimePicker inline weekNumbers showMonths={1} />
|
|
59
|
+
<DateTimePicker enableTime noCalendar minuteIncrement={15} />
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Calendar presentation
|
|
63
|
+
|
|
64
|
+
Set `yearSelect` to render a compact year selector beside the month name. Its range follows `minDate` and `maxDate`, or otherwise surrounds the viewed year.
|
|
65
|
+
|
|
66
|
+
`workingWeekDays` counts working days from Monday (default `5` for Monday–Friday). Remaining days receive the `is-free-day` state. Saturdays and Sundays always receive `is-sat` and `is-sun`; dates listed in `holidaysDates` receive `is-holiday`. Use `getDayClassName` for application-specific states.
|
|
67
|
+
|
|
68
|
+
```xts
|
|
69
|
+
<DateTimePicker
|
|
70
|
+
yearSelect
|
|
71
|
+
workingWeekDays={4}
|
|
72
|
+
holidaysDates={[companyHoliday]}
|
|
73
|
+
getDayClassName={date => date.toDateString() === releaseDay.toDateString() ? 'is-release-day' : undefined}
|
|
74
|
+
/>
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Target and accessibility labels
|
|
78
|
+
|
|
79
|
+
Renderers use their default target when no `target` slot is supplied. The default target displays date and time values as `<date> - <time>`, caps its width at `20rem`, and horizontally scrolls long multiple selections while keeping the arrow visible. Override the width through `--pw_DateTimePicker_target_default_max-width`.
|
|
80
|
+
|
|
81
|
+
Set `label` and `labelPlacement` to render a visible label using the same placement utilities as `Select`. `labelPlacement` defaults to `'top-start'` and accepts the standard placement values such as `'bottom'`, `'left-end'`, and `'right-start'`. A visible label is linked to the default target through `aria-labelledby`.
|
|
82
|
+
|
|
83
|
+
```xts
|
|
84
|
+
<DateTimePicker label="Appointment" labelPlacement="left" />
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Provide `ariaLabel`, `previousMonthAriaLabel`, `nextMonthAriaLabel`, `yearSelectAriaLabel`, `selectTimeAriaLabel`, and `backToCalendarAriaLabel` when the default English labels do not fit the product vocabulary.
|
|
88
|
+
|
|
89
|
+
```xts
|
|
90
|
+
<DateTimePicker
|
|
91
|
+
ariaLabel="Appointment date and time"
|
|
92
|
+
previousMonthAriaLabel="Show previous appointment month"
|
|
93
|
+
selectTimeAriaLabel="Choose appointment time"
|
|
94
|
+
/>
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Renderer integration
|
|
98
|
+
|
|
99
|
+
Renderers own their target, calendar, and time-toggle references, then provide
|
|
100
|
+
them together after mounting. This keeps the mediator independent of framework
|
|
101
|
+
ref objects and slot mechanisms.
|
|
102
|
+
|
|
103
|
+
```xts
|
|
104
|
+
const triggerReference = getTriggerElement();
|
|
105
|
+
const calendarReference = getCalendarElement();
|
|
106
|
+
const timeToggleReference = getTimeToggleElement();
|
|
107
|
+
|
|
108
|
+
mediator.useMounted(
|
|
109
|
+
triggerReference,
|
|
110
|
+
calendarReference,
|
|
111
|
+
timeToggleReference,
|
|
112
|
+
);
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Custom targets consume renderer-provided bindings from the shared
|
|
116
|
+
`DATETIME_PICKER_TRIGGER_PROPS_CONTEXT_KEY`. The core
|
|
117
|
+
`DateTimePickerTriggerProps` contract provides the ID, role, tab index, ARIA
|
|
118
|
+
attributes, and click/keyboard handlers. Each renderer adapts only its own ref
|
|
119
|
+
and event types.
|
|
120
|
+
|
|
121
|
+
## Summary
|
|
122
|
+
|
|
123
|
+
Use DateTimePicker when users need to choose a date, date range, or time with
|
|
124
|
+
calendar guidance. Use a native date input when the browser-provided control is
|
|
125
|
+
sufficient and a richer calendar interface is unnecessary.
|