forty-cdk 0.38.0 → 0.40.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 +12 -11
- package/accordion/README.md +17 -12
- package/aspect-ratio/README.md +1 -1
- package/avatar/README.md +21 -0
- package/breadcrumbs/README.md +25 -20
- package/breakpoints/README.md +17 -25
- package/button/README.md +1 -1
- package/calendar/README.md +17 -5
- package/carousel/README.md +38 -31
- package/combobox/README.md +60 -23
- package/context-menu/README.md +25 -1
- package/date-field/README.md +14 -10
- package/date-picker/README.md +37 -9
- package/defaults/README.md +1 -1
- package/dialog/README.md +33 -1
- package/drag-drop/README.md +61 -22
- package/drawer/README.md +27 -1
- package/dropdown-menu/README.md +27 -1
- package/fesm2022/forty-cdk-calendar.mjs.map +1 -1
- package/fesm2022/forty-cdk-carousel.mjs +2 -2
- package/fesm2022/forty-cdk-carousel.mjs.map +1 -1
- package/fesm2022/forty-cdk-combobox.mjs +250 -191
- package/fesm2022/forty-cdk-combobox.mjs.map +1 -1
- package/fesm2022/forty-cdk-context-menu.mjs.map +1 -1
- package/fesm2022/forty-cdk-core-overlay.mjs +30 -9
- package/fesm2022/forty-cdk-core-overlay.mjs.map +1 -1
- package/fesm2022/forty-cdk-core.mjs +13 -22
- package/fesm2022/forty-cdk-core.mjs.map +1 -1
- package/fesm2022/forty-cdk-date-field.mjs +4 -9
- package/fesm2022/forty-cdk-date-field.mjs.map +1 -1
- package/fesm2022/forty-cdk-date-picker.mjs +5 -5
- package/fesm2022/forty-cdk-date-picker.mjs.map +1 -1
- package/fesm2022/forty-cdk-defaults.mjs +4 -4
- package/fesm2022/forty-cdk-defaults.mjs.map +1 -1
- package/fesm2022/forty-cdk-dialog.mjs +8 -8
- package/fesm2022/forty-cdk-dialog.mjs.map +1 -1
- package/fesm2022/forty-cdk-drag-drop.mjs +63 -60
- package/fesm2022/forty-cdk-drag-drop.mjs.map +1 -1
- package/fesm2022/forty-cdk-drawer.mjs +51 -63
- package/fesm2022/forty-cdk-drawer.mjs.map +1 -1
- package/fesm2022/forty-cdk-dropdown-menu.mjs.map +1 -1
- package/fesm2022/forty-cdk-field.mjs +2 -2
- package/fesm2022/forty-cdk-field.mjs.map +1 -1
- package/fesm2022/forty-cdk-fieldset.mjs +2 -2
- package/fesm2022/forty-cdk-fieldset.mjs.map +1 -1
- package/fesm2022/forty-cdk-file-upload.mjs +6 -3
- package/fesm2022/forty-cdk-file-upload.mjs.map +1 -1
- package/fesm2022/forty-cdk-id-salt.mjs +14 -0
- package/fesm2022/forty-cdk-id-salt.mjs.map +1 -0
- package/fesm2022/forty-cdk-internationalized-date.mjs +10 -4
- package/fesm2022/forty-cdk-internationalized-date.mjs.map +1 -1
- package/fesm2022/forty-cdk-listbox.mjs +199 -135
- package/fesm2022/forty-cdk-listbox.mjs.map +1 -1
- package/fesm2022/forty-cdk-menu.mjs +32 -46
- package/fesm2022/forty-cdk-menu.mjs.map +1 -1
- package/fesm2022/forty-cdk-navigation-menu.mjs +27 -25
- package/fesm2022/forty-cdk-navigation-menu.mjs.map +1 -1
- package/fesm2022/forty-cdk-popover.mjs.map +1 -1
- package/fesm2022/forty-cdk-progress.mjs +4 -1
- package/fesm2022/forty-cdk-progress.mjs.map +1 -1
- package/fesm2022/forty-cdk-scroll-area.mjs +14 -3
- package/fesm2022/forty-cdk-scroll-area.mjs.map +1 -1
- package/fesm2022/forty-cdk-select.mjs +245 -207
- package/fesm2022/forty-cdk-select.mjs.map +1 -1
- package/fesm2022/forty-cdk-separator.mjs.map +1 -1
- package/fesm2022/forty-cdk-shared.mjs +2 -1
- package/fesm2022/forty-cdk-slider.mjs +2 -2
- package/fesm2022/forty-cdk-slider.mjs.map +1 -1
- package/fesm2022/forty-cdk-stepper.mjs.map +1 -1
- package/fesm2022/forty-cdk-table-virtualization.mjs.map +1 -1
- package/fesm2022/forty-cdk-table.mjs +9 -6
- package/fesm2022/forty-cdk-table.mjs.map +1 -1
- package/fesm2022/forty-cdk-testing.mjs +35 -13
- package/fesm2022/forty-cdk-testing.mjs.map +1 -1
- package/fesm2022/forty-cdk-time-field.mjs +9 -11
- package/fesm2022/forty-cdk-time-field.mjs.map +1 -1
- package/fesm2022/forty-cdk-time-picker.mjs +2 -2
- package/fesm2022/forty-cdk-time-picker.mjs.map +1 -1
- package/fesm2022/forty-cdk-toast.mjs +11 -7
- package/fesm2022/forty-cdk-toast.mjs.map +1 -1
- package/fesm2022/forty-cdk-toggle.mjs.map +1 -1
- package/fesm2022/forty-cdk-toolbar.mjs.map +1 -1
- package/fesm2022/forty-cdk-tree.mjs +280 -174
- package/fesm2022/forty-cdk-tree.mjs.map +1 -1
- package/fesm2022/forty-cdk-virtual-reorder.mjs +1 -1
- package/fesm2022/forty-cdk-virtual-reorder.mjs.map +1 -1
- package/fesm2022/forty-cdk-virtualization.mjs +2 -1
- package/fesm2022/forty-cdk-virtualization.mjs.map +1 -1
- package/file-upload/README.md +12 -12
- package/hover-card/README.md +7 -1
- package/id-salt/README.md +41 -0
- package/listbox/README.md +60 -41
- package/menu/README.md +73 -35
- package/menubar/README.md +26 -2
- package/navigation-menu/README.md +125 -14
- package/number-input/README.md +28 -1
- package/package.json +5 -1
- package/pagination/README.md +39 -16
- package/popover/README.md +8 -8
- package/progress/README.md +50 -10
- package/radio-group/README.md +21 -2
- package/scroll-area/README.md +35 -6
- package/search/README.md +23 -9
- package/select/README.md +31 -23
- package/separator/README.md +2 -2
- package/shared/README.md +6 -6
- package/slider/README.md +19 -0
- package/stepper/README.md +31 -15
- package/switch/README.md +19 -6
- package/table/README.md +42 -36
- package/table-virtualization/README.md +1 -1
- package/tabs/README.md +39 -15
- package/testing/README.md +1 -1
- package/time-field/README.md +13 -9
- package/time-picker/README.md +8 -3
- package/toast/README.md +6 -2
- package/toggle/README.md +88 -68
- package/toolbar/README.md +19 -0
- package/tree/README.md +70 -58
- package/types/forty-cdk-calendar.d.ts +8 -2
- package/types/forty-cdk-carousel.d.ts +2 -1
- package/types/forty-cdk-combobox.d.ts +184 -87
- package/types/forty-cdk-context-menu.d.ts +4 -13
- package/types/forty-cdk-core-overlay.d.ts +86 -65
- package/types/forty-cdk-core.d.ts +61 -117
- package/types/forty-cdk-date-field.d.ts +15 -18
- package/types/forty-cdk-defaults.d.ts +33 -33
- package/types/forty-cdk-drag-drop.d.ts +10 -6
- package/types/forty-cdk-drawer.d.ts +2 -1
- package/types/forty-cdk-dropdown-menu.d.ts +3 -11
- package/types/forty-cdk-file-upload.d.ts +10 -4
- package/types/forty-cdk-id-salt.d.ts +40 -0
- package/types/forty-cdk-internationalized-date.d.ts +10 -6
- package/types/forty-cdk-listbox.d.ts +177 -63
- package/types/forty-cdk-menu.d.ts +25 -38
- package/types/forty-cdk-navigation-menu.d.ts +6 -0
- package/types/forty-cdk-popover.d.ts +8 -2
- package/types/forty-cdk-progress.d.ts +9 -10
- package/types/forty-cdk-scroll-area.d.ts +49 -10
- package/types/forty-cdk-select.d.ts +220 -127
- package/types/forty-cdk-separator.d.ts +1 -1
- package/types/forty-cdk-shared.d.ts +2 -1
- package/types/forty-cdk-stepper.d.ts +14 -9
- package/types/forty-cdk-table.d.ts +2 -2
- package/types/forty-cdk-testing.d.ts +38 -5
- package/types/forty-cdk-time-field.d.ts +14 -20
- package/types/forty-cdk-time-picker.d.ts +15 -6
- package/types/forty-cdk-toast.d.ts +37 -18
- package/types/forty-cdk-toggle.d.ts +4 -3
- package/types/forty-cdk-toolbar.d.ts +6 -16
- package/types/forty-cdk-tree.d.ts +331 -69
- package/types/forty-cdk-virtual-reorder.d.ts +5 -1
- package/virtual-reorder/README.md +3 -1
- package/virtualization/README.md +3 -1
- package/visually-hidden/README.md +16 -3
package/README.md
CHANGED
|
@@ -42,18 +42,19 @@ Two packages are regular dependencies, installed automatically and never declare
|
|
|
42
42
|
|
|
43
43
|
## Entry points
|
|
44
44
|
|
|
45
|
-
**The package name itself exports nothing.** `import { … } from 'forty-cdk'` resolves to no symbol, and your editor will not auto-import anything under the bare package name — by design, so that the bare name never becomes a second import path for a symbol. There are
|
|
45
|
+
**The package name itself exports nothing.** `import { … } from 'forty-cdk'` resolves to no symbol, and your editor will not auto-import anything under the bare package name — by design, so that the bare name never becomes a second import path for a symbol. There are seven specifiers you do import from:
|
|
46
46
|
|
|
47
|
-
| Specifier | What it exports
|
|
48
|
-
| ---------------------------------------- |
|
|
49
|
-
| `forty-cdk/<primitive>` | The primitive's directives, components, context tokens and defaults provider — `ForDialog` from `forty-cdk/dialog`, `ForAccordion` from `forty-cdk/accordion`, and so on for every entry in the tables below.
|
|
50
|
-
| [`forty-cdk/shared`](shared) | The cross-primitive contract types a primitive's public API references — `WritingDirection`, `VetoableEvent`, `DateAdapter`, `FloatingSide`, … — declared once and published once. Eight ship from their own primitive instead; that README names them.
|
|
51
|
-
| `forty-cdk/internationalized-date` | The `@internationalized/date` adapters, kept apart so that optional peer stays genuinely optional.
|
|
52
|
-
| [`forty-cdk/defaults`](defaults) | Every `provideFor<Primitive>Defaults` with its token and interface. Each primitive re-exports its own pair too, but a root provider imported from the primitive loads the primitive at startup; imported from here, it does not.
|
|
53
|
-
| [`forty-cdk/date-adapter`](date-adapter) | The `DateAdapter` contract, the `FOR_DATE_ADAPTER` token and `provideNativeDateAdapter`. `forty-cdk/shared` re-exports them, but a root provider imported from there loads the code every primitive shares at startup; imported from here, it does not.
|
|
54
|
-
| [`forty-cdk/
|
|
47
|
+
| Specifier | What it exports |
|
|
48
|
+
| ---------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
49
|
+
| `forty-cdk/<primitive>` | The primitive's directives, components, context tokens and defaults provider — `ForDialog` from `forty-cdk/dialog`, `ForAccordion` from `forty-cdk/accordion`, and so on for every entry in the tables below. |
|
|
50
|
+
| [`forty-cdk/shared`](shared) | The cross-primitive contract types a primitive's public API references — `WritingDirection`, `VetoableEvent`, `DateAdapter`, `FloatingSide`, … — declared once and published once. Eight ship from their own primitive instead; that README names them. |
|
|
51
|
+
| `forty-cdk/internationalized-date` | The `@internationalized/date` adapters, kept apart so that optional peer stays genuinely optional. |
|
|
52
|
+
| [`forty-cdk/defaults`](defaults) | Every `provideFor<Primitive>Defaults` with its token and interface. Each primitive re-exports its own pair too, but a root provider imported from the primitive loads the primitive at startup; imported from here, it does not. |
|
|
53
|
+
| [`forty-cdk/date-adapter`](date-adapter) | The `DateAdapter` contract, the `FOR_DATE_ADAPTER` token and `provideNativeDateAdapter`. `forty-cdk/shared` re-exports them, but a root provider imported from there loads the code every primitive shares at startup; imported from here, it does not. |
|
|
54
|
+
| [`forty-cdk/id-salt`](id-salt) | `FOR_ID_SALT` and `provideForIdSalt`, the per-app salt for the ids the primitives generate when several forty-cdk apps share a page. `forty-cdk/shared` re-exports them, but a root provider imported from there loads the code every primitive shares at startup; imported from here, it does not. |
|
|
55
|
+
| [`forty-cdk/testing`](testing) | Spec helpers: keyboard and mouse events dispatched the way a browser dispatches them, stubs for the browser APIs jsdom lacks, and dialog and drawer refs for content mounted outside its manager. |
|
|
55
56
|
|
|
56
|
-
`forty-cdk/core` and `forty-cdk/core-overlay` resolve too, but neither is **public**: together they hold the engines and DI singletons the library refactors freely, and they exist so every primitive resolves that shared implementation to one compiled module. They are two rather than one for a bundling reason you get for free: a published module is a bundler's chunk-splitting unit, so keeping the positioning engine (`@floating-ui/dom` and the overlay shells) in its own module means a lazy route that renders no overlay does not load it. Measured on a seven-lazy-route app, that is **41.7 kB raw / 12.1 kB transfer** a non-overlay route no longer pays. If a symbol you need is not exported by the
|
|
57
|
+
`forty-cdk/core` and `forty-cdk/core-overlay` resolve too, but neither is **public**: together they hold the engines and DI singletons the library refactors freely, and they exist so every primitive resolves that shared implementation to one compiled module. They are two rather than one for a bundling reason you get for free: a published module is a bundler's chunk-splitting unit, so keeping the positioning engine (`@floating-ui/dom` and the overlay shells) in its own module means a lazy route that renders no overlay does not load it. Measured on a seven-lazy-route app, that is **41.7 kB raw / 12.1 kB transfer** a non-overlay route no longer pays. If a symbol you need is not exported by the seven specifiers above, it is internal by design — [open an issue](https://github.com/tutkli/forty-cdk/issues) rather than importing from either.
|
|
57
58
|
|
|
58
59
|
## Errors
|
|
59
60
|
|
|
@@ -71,7 +72,7 @@ Fix: Move ForDialogTitle inside a [forDialog] element, declaring any ng-template
|
|
|
71
72
|
|
|
72
73
|
The code is `FORCDK-<AREA>-<NUMBER>`, where the area is the entry point you imported from — so `FORCDK-DATE-PICKER-003` came from `forty-cdk/date-picker`, and `FORCDK-CORE-*` from machinery shared across primitives (those still print the prefix of the primitive you actually wrote). **A code is stable and always means the same failure**, so it is safe to search for, quote in an issue, or match on in your own error handling; a retired code is never reused for something else.
|
|
73
74
|
|
|
74
|
-
Warnings are dev-mode only
|
|
75
|
+
Warnings are dev-mode only, and so are the checks on a value you passed: an invalid column name, a misordered list of snap points or an unbound required input throws in development and is skipped in a production build, where the primitive degrades instead. Do not rely on catching one of those in production. A piece that resolved no context, or an overlay trigger that resolved no root, is different: it would fail one line later anyway, so it throws in every build and says why.
|
|
75
76
|
|
|
76
77
|
## Primitives
|
|
77
78
|
|
package/accordion/README.md
CHANGED
|
@@ -113,12 +113,13 @@ A disabled item cannot be toggled and is skipped by the arrow keys, while stayin
|
|
|
113
113
|
|
|
114
114
|
| Property | Type | Description |
|
|
115
115
|
| ------------- | ----------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
116
|
-
| `value` | `model<readonly string[]>` | Currently open item values. In single mode the array has 0 or 1 element.<br>**Default:**
|
|
116
|
+
| `value` | `model<readonly string[]>` | Currently open item values. In single mode the array has 0 or 1 element.<br>**Default:** `[]` |
|
|
117
117
|
| `multiple` | `input<boolean>` | When true, multiple items can be open simultaneously.<br>**Default:** `false` |
|
|
118
118
|
| `collapsible` | `input<boolean>` | Single mode only: when true, the open item can be collapsed by clicking it. Otherwise once any item is open, exactly one stays open.<br>**Default:** `false` |
|
|
119
119
|
| `disabled` | `input<boolean>` | When true, disables every item: each trigger reflects the native `disabled` attribute and cannot toggle. Composes with a per-item `[disabled]`.<br>**Default:** `false` |
|
|
120
120
|
| `orientation` | `input<'horizontal' \| 'vertical'>` | Layout direction of the trigger list. In horizontal mode ArrowLeft/Right replace ArrowUp/Down.<br>**Default:** `'vertical'` |
|
|
121
121
|
| `dir` | `input<'ltr' \| 'rtl' \| null>` | Writing direction. Only relevant in horizontal mode, where it swaps the meaning of Left/Right arrows. `null` inherits the nearest `[dir]` / `<html dir>`, else `'ltr'`.<br>**Default:** `null` |
|
|
122
|
+
| `loop` | `input<boolean>` | When true, arrow navigation wraps from the last trigger to the first and back. Set `false` to stop at the ends.<br>**Default:** `true` |
|
|
122
123
|
|
|
123
124
|
| Data attribute | Values |
|
|
124
125
|
| ------------------ | -------------------------- |
|
|
@@ -127,10 +128,10 @@ A disabled item cannot be toggled and is skipped by the arrow keys, while stayin
|
|
|
127
128
|
|
|
128
129
|
### `ForAccordionItem`
|
|
129
130
|
|
|
130
|
-
| Property | Type | Description
|
|
131
|
-
| ---------- | ------------------------ |
|
|
132
|
-
| `value` | `input.required<string>` | Unique identifier within the accordion. Required.<br>**Default:** —
|
|
133
|
-
| `disabled` | `input<boolean>` | When true, the trigger ignores clicks and exposes the native `disabled` attribute.<br>**Default:**
|
|
131
|
+
| Property | Type | Description |
|
|
132
|
+
| ---------- | ------------------------ | ---------------------------------------------------------------------------------------------------------- |
|
|
133
|
+
| `value` | `input.required<string>` | Unique identifier within the accordion. Required.<br>**Default:** — |
|
|
134
|
+
| `disabled` | `input<boolean>` | When true, the trigger ignores clicks and exposes the native `disabled` attribute.<br>**Default:** `false` |
|
|
134
135
|
|
|
135
136
|
| Data attribute | Values |
|
|
136
137
|
| ------------------ | -------------------------- |
|
|
@@ -143,6 +144,7 @@ A disabled item cannot be toggled and is skipped by the arrow keys, while stayin
|
|
|
143
144
|
| Data attribute | Values |
|
|
144
145
|
| ------------------ | -------------------------- |
|
|
145
146
|
| `data-state` | `open` \| `closed` |
|
|
147
|
+
| `data-disabled` | present \| absent |
|
|
146
148
|
| `data-orientation` | `horizontal` \| `vertical` |
|
|
147
149
|
|
|
148
150
|
### `ForAccordionContent`
|
|
@@ -150,17 +152,20 @@ A disabled item cannot be toggled and is skipped by the arrow keys, while stayin
|
|
|
150
152
|
| Data attribute | Values |
|
|
151
153
|
| ------------------ | -------------------------- |
|
|
152
154
|
| `data-state` | `open` \| `closed` |
|
|
155
|
+
| `data-disabled` | present \| absent |
|
|
153
156
|
| `data-orientation` | `horizontal` \| `vertical` |
|
|
154
157
|
|
|
158
|
+
`data-disabled` on the item, trigger and content reflects the item's own `[disabled]` or the root's, whichever is set.
|
|
159
|
+
|
|
155
160
|
## Keyboard
|
|
156
161
|
|
|
157
|
-
| Key | Action
|
|
158
|
-
| -------------------------------------------- |
|
|
159
|
-
| <kbd>Enter</kbd> / <kbd>Space</kbd> | Toggle the focused trigger (native button).
|
|
160
|
-
| <kbd>ArrowDown</kbd> / <kbd>ArrowUp</kbd> | Move focus between triggers (vertical, default).
|
|
161
|
-
| <kbd>ArrowLeft</kbd> / <kbd>ArrowRight</kbd> | Move focus between triggers (horizontal, flipped under `dir='rtl'`).
|
|
162
|
-
| <kbd>Home</kbd> | Jump to the first trigger.
|
|
163
|
-
| <kbd>End</kbd> | Jump to the last trigger.
|
|
162
|
+
| Key | Action |
|
|
163
|
+
| -------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
|
|
164
|
+
| <kbd>Enter</kbd> / <kbd>Space</kbd> | Toggle the focused trigger (native button). |
|
|
165
|
+
| <kbd>ArrowDown</kbd> / <kbd>ArrowUp</kbd> | Move focus between triggers (vertical, default). Wraps around unless `loop` is `false`, skips disabled. |
|
|
166
|
+
| <kbd>ArrowLeft</kbd> / <kbd>ArrowRight</kbd> | Move focus between triggers (horizontal, flipped under `dir='rtl'`). Wraps around unless `loop` is `false`, skips disabled. |
|
|
167
|
+
| <kbd>Home</kbd> | Jump to the first trigger. |
|
|
168
|
+
| <kbd>End</kbd> | Jump to the last trigger. |
|
|
164
169
|
|
|
165
170
|
## Accessibility
|
|
166
171
|
|
package/aspect-ratio/README.md
CHANGED
|
@@ -39,7 +39,7 @@ If your ratio is a literal constant, prefer the CSS property directly and keep t
|
|
|
39
39
|
|
|
40
40
|
## Examples
|
|
41
41
|
|
|
42
|
-
|
|
42
|
+
Narrow the browser window until the frame shrinks and watch it hold its 16 / 9 ratio. The primitive writes the ratio and nothing else, so every border, colour and inset below is your own CSS.
|
|
43
43
|
|
|
44
44
|
```ts
|
|
45
45
|
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
package/avatar/README.md
CHANGED
|
@@ -96,10 +96,31 @@ When the image errors, the directive flips `shouldShowFallback()` and the initia
|
|
|
96
96
|
| -------------- | ------------------------------------------ |
|
|
97
97
|
| `data-status` | `idle` \| `loading` \| `loaded` \| `error` |
|
|
98
98
|
|
|
99
|
+
## Scoped defaults
|
|
100
|
+
|
|
101
|
+
`provideForAvatarDefaults` configures avatar defaults for an injector subtree, either at the application root or in any component's `providers` array. Partial overrides inherit unspecified keys from the parent scope (or the library fallbacks at the root).
|
|
102
|
+
|
|
103
|
+
| Key | Library fallback | Meaning |
|
|
104
|
+
| ----------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
105
|
+
| `fallbackDelayMs` | `0` | Milliseconds to wait before the fallback shows while the image is idle or loading, for avatars that don't set `fallbackDelayMs` themselves. An `error` status always shows the fallback at once. |
|
|
106
|
+
|
|
107
|
+
Per-instance inputs always win over the scope defaults.
|
|
108
|
+
|
|
109
|
+
```ts
|
|
110
|
+
import { type ApplicationConfig } from '@angular/core';
|
|
111
|
+
import { provideForAvatarDefaults } from 'forty-cdk/defaults';
|
|
112
|
+
|
|
113
|
+
export const appConfig: ApplicationConfig = {
|
|
114
|
+
providers: [provideForAvatarDefaults({ fallbackDelayMs: 500 })],
|
|
115
|
+
};
|
|
116
|
+
```
|
|
117
|
+
|
|
99
118
|
## Accessibility
|
|
100
119
|
|
|
101
120
|
The directive does not impose a `role`. Pair the avatar with visible name text or `aria-label` on the surrounding element when identity matters. Set `alt=""` on the `<img>` for purely decorative avatars next to a name, or provide a meaningful `alt` description if the avatar stands alone.
|
|
102
121
|
|
|
122
|
+
A meaningful `alt` names the avatar only while the image is shown: once it fails, the image is hidden and the fallback initials are all that is left to announce. When an avatar stands alone, name the root instead (`role="img"` with an `aria-label`) and give the `<img>` `alt=""`, so the fallback carries the same name as the loaded image.
|
|
123
|
+
|
|
103
124
|
## Styling
|
|
104
125
|
|
|
105
126
|
forty-cdk ships no styles: put your own class on each piece and key your CSS off the `data-*` attributes listed under [API](#api), not off the `for*` selectors ([Styling forty-cdk](../../../docs/styling.md) explains why).
|
package/breadcrumbs/README.md
CHANGED
|
@@ -23,7 +23,7 @@ A labelled navigation landmark for a breadcrumb trail: links with aria-current='
|
|
|
23
23
|
|
|
24
24
|
## Examples
|
|
25
25
|
|
|
26
|
-
Walk the trail with `Tab`: the last crumb is the page you are on, so it carries `aria-current="page"` and is
|
|
26
|
+
Walk the trail with `Tab`: the last crumb is the page you are on, so it carries `aria-current="page"` and is announced as the current page.
|
|
27
27
|
|
|
28
28
|
```ts
|
|
29
29
|
import { ChangeDetectionStrategy, Component, signal } from '@angular/core';
|
|
@@ -86,22 +86,6 @@ export class BreadcrumbsDefaultExample {
|
|
|
86
86
|
|
|
87
87
|
The primitive renders whatever items you give it, so collapsing a deep path is a consumer decision. Here the middle is folded into an expandable ellipsis button that reveals the hidden crumbs. The trail stays a single accessible navigation landmark either way.
|
|
88
88
|
|
|
89
|
-
## Localizing the label
|
|
90
|
-
|
|
91
|
-
`Breadcrumb` is verbalized by screen readers, so translate it per injector scope with `provideForBreadcrumbsDefaults`. Configure it at the application root, or in any component's `providers` to scope the translation to a subtree. A per-instance `[ariaLabel]` still wins over the scope default.
|
|
92
|
-
|
|
93
|
-
<!-- snippet: fragment -->
|
|
94
|
-
|
|
95
|
-
```ts
|
|
96
|
-
import { provideForBreadcrumbsDefaults } from 'forty-cdk/defaults';
|
|
97
|
-
|
|
98
|
-
bootstrapApplication(App, {
|
|
99
|
-
providers: [provideForBreadcrumbsDefaults({ label: 'Ruta de navegación' })],
|
|
100
|
-
});
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
For a language the app sets or switches after bootstrap, pass `label` as a function and the overrides as a factory, as [Localizing default text](../shared/README.md#localizing-default-text) shows.
|
|
104
|
-
|
|
105
89
|
## API
|
|
106
90
|
|
|
107
91
|
### `ForBreadcrumbs`
|
|
@@ -112,9 +96,30 @@ For a language the app sets or switches after bootstrap, pass `label` as a funct
|
|
|
112
96
|
|
|
113
97
|
### `ForBreadcrumbItem`
|
|
114
98
|
|
|
115
|
-
| Property | Type | Description
|
|
116
|
-
| --------- | ---------------- |
|
|
117
|
-
| `current` | `input<boolean>` | When true, reflects `aria-current="page"` on the link.<br>**Default:**
|
|
99
|
+
| Property | Type | Description |
|
|
100
|
+
| --------- | ---------------- | ------------------------------------------------------------------------------ |
|
|
101
|
+
| `current` | `input<boolean>` | When true, reflects `aria-current="page"` on the link.<br>**Default:** `false` |
|
|
102
|
+
|
|
103
|
+
## Scoped defaults
|
|
104
|
+
|
|
105
|
+
`provideForBreadcrumbsDefaults` configures breadcrumb defaults for an injector subtree, either at the application root or in any component's `providers` array. Partial overrides inherit unspecified keys from the parent scope (or the library fallbacks at the root).
|
|
106
|
+
|
|
107
|
+
| Key | Library fallback | Meaning |
|
|
108
|
+
| ------- | ---------------- | ------------------------------------------------------------------------------------------------- |
|
|
109
|
+
| `label` | `'Breadcrumb'` | Accessible name of the `navigation` landmark, for trails that don't set `[ariaLabel]` themselves. |
|
|
110
|
+
|
|
111
|
+
`label` is verbalized by screen readers, so translate it here to rename every breadcrumb landmark in the scope. It accepts a string or a function returning one; a function can read a language signal, so the name follows a language the app sets or switches after bootstrap, as [Localizing default text](../shared/README.md#localizing-default-text) shows.
|
|
112
|
+
|
|
113
|
+
Per-instance inputs always win over the scope defaults.
|
|
114
|
+
|
|
115
|
+
```ts
|
|
116
|
+
import { type ApplicationConfig } from '@angular/core';
|
|
117
|
+
import { provideForBreadcrumbsDefaults } from 'forty-cdk/defaults';
|
|
118
|
+
|
|
119
|
+
export const appConfig: ApplicationConfig = {
|
|
120
|
+
providers: [provideForBreadcrumbsDefaults({ label: 'Ruta de navegación' })],
|
|
121
|
+
};
|
|
122
|
+
```
|
|
118
123
|
|
|
119
124
|
## Accessibility
|
|
120
125
|
|
package/breakpoints/README.md
CHANGED
|
@@ -10,9 +10,15 @@ A signal-first, zoneless, SSR-safe viewport breakpoint observer (injectBreakpoin
|
|
|
10
10
|
|
|
11
11
|
It is a headless reactive utility, not a UI primitive: no DOM, no ARIA, no template. Configure the breakpoint map **once** via a provider and read it anywhere with `injectBreakpoints()`, so there is no need to repeat the breakpoint set at every call site.
|
|
12
12
|
|
|
13
|
-
##
|
|
13
|
+
## Scoped defaults
|
|
14
14
|
|
|
15
|
-
Configuring is optional: without a provider the Tailwind scale
|
|
15
|
+
`provideForBreakpointsDefaults` sets the scope's `breakpoints` map, so `injectBreakpoints()` can be called with no arguments. Configuring is optional: without a provider the Tailwind scale is used. Provide it in your application config, or again in any component's `providers` array to replace the map for that subtree only. The nearest scope wins, and its map replaces the parent's wholesale: it is never merged key by key.
|
|
16
|
+
|
|
17
|
+
| Key | Library fallback | Meaning |
|
|
18
|
+
| ------------- | ------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
19
|
+
| `breakpoints` | `forBreakpointsTailwind`: `sm` 640, `md` 768, `lg` 1024, `xl` 1280, `2xl` 1536 | Each breakpoint name paired with its `min-width` threshold in CSS pixels. The query methods derive from these names, sorted ascending by threshold. |
|
|
20
|
+
|
|
21
|
+
The provider takes the map itself rather than an object with a `breakpoints` key, or a function returning the map when it has to be built where `inject()` is available:
|
|
16
22
|
|
|
17
23
|
```ts
|
|
18
24
|
import { ApplicationConfig } from '@angular/core';
|
|
@@ -25,21 +31,12 @@ export const appConfig: ApplicationConfig = {
|
|
|
25
31
|
};
|
|
26
32
|
```
|
|
27
33
|
|
|
28
|
-
Providing it again on a component injector replaces the map for that subtree only (nearest scope wins; the map is replaced wholesale, never merged key-by-key).
|
|
29
|
-
|
|
30
34
|
## Examples
|
|
31
35
|
|
|
32
|
-
Resize the
|
|
36
|
+
Resize the browser window and watch the matched breakpoint change: the breakpoints follow the viewport, not the preview frame. `injectBreakpoints()` hands back signals, so the template, width range included, re-renders without a listener of your own.
|
|
33
37
|
|
|
34
38
|
```ts
|
|
35
|
-
import {
|
|
36
|
-
afterNextRender,
|
|
37
|
-
ChangeDetectionStrategy,
|
|
38
|
-
Component,
|
|
39
|
-
DestroyRef,
|
|
40
|
-
inject,
|
|
41
|
-
signal,
|
|
42
|
-
} from '@angular/core';
|
|
39
|
+
import { ChangeDetectionStrategy, Component, computed } from '@angular/core';
|
|
43
40
|
import { forBreakpointsTailwind, injectBreakpoints } from 'forty-cdk/breakpoints';
|
|
44
41
|
|
|
45
42
|
type TailwindName = keyof typeof forBreakpointsTailwind;
|
|
@@ -52,7 +49,7 @@ type TailwindName = keyof typeof forBreakpointsTailwind;
|
|
|
52
49
|
<div class="bp-readout">
|
|
53
50
|
<span class="bp-readout-label">active breakpoint</span>
|
|
54
51
|
<span class="bp-active">{{ active() ?? 'below sm' }}</span>
|
|
55
|
-
<span class="bp-width">viewport
|
|
52
|
+
<span class="bp-width">viewport {{ range() }}</span>
|
|
56
53
|
</div>
|
|
57
54
|
|
|
58
55
|
<ul class="bp-grid">
|
|
@@ -81,17 +78,12 @@ export class BreakpointsActiveExample {
|
|
|
81
78
|
only: this.bp.only(name),
|
|
82
79
|
}));
|
|
83
80
|
|
|
84
|
-
protected readonly
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
const
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
onResize();
|
|
91
|
-
globalThis.addEventListener('resize', onResize, { passive: true });
|
|
92
|
-
destroyRef.onDestroy(() => globalThis.removeEventListener('resize', onResize));
|
|
93
|
-
});
|
|
94
|
-
}
|
|
81
|
+
protected readonly range = computed(() => {
|
|
82
|
+
const index = this.rows.findIndex((row) => row.name === this.active());
|
|
83
|
+
const from = this.rows[index]?.min ?? 0;
|
|
84
|
+
const to = this.rows[index + 1]?.min;
|
|
85
|
+
return to === undefined ? `${from}px and up` : `${from}px to ${to - 1}px`;
|
|
86
|
+
});
|
|
95
87
|
}
|
|
96
88
|
```
|
|
97
89
|
|
package/button/README.md
CHANGED
|
@@ -5,7 +5,7 @@ archetype: [composable-ui]
|
|
|
5
5
|
apgUrl: https://www.w3.org/WAI/ARIA/apg/patterns/button/
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
#
|
|
8
|
+
# Button
|
|
9
9
|
|
|
10
10
|
Turns any element (a native `<button>` or a custom host like `<div>` / `<span>`) into an accessible button with keyboard activation. Disabled stays focusable (aria-disabled, never the native attribute) and pressed / hovered / focus-visible are reflected as data-\* hooks.
|
|
11
11
|
|
package/calendar/README.md
CHANGED
|
@@ -188,7 +188,7 @@ export class CalendarDefaultExample {
|
|
|
188
188
|
|
|
189
189
|
### States
|
|
190
190
|
|
|
191
|
-
One class and one directive, three states. `disabled` turns off focus movement and selection for the whole calendar; `readonly` keeps days focusable and the grid still pages, but clicking or pressing `Enter` no longer changes the selection, and a click moves only the focused day to the clicked cell. Each reflects a root hook (`data-disabled` and `data-readonly`)
|
|
191
|
+
One class and one directive, three states. `disabled` turns off focus movement and selection for the whole calendar; `readonly` keeps days focusable and the grid still pages, but clicking or pressing `Enter` no longer changes the selection, and a click moves only the focused day to the clicked cell. Each reflects a root hook (`data-disabled` and `data-readonly`) that the example's stylesheet keys on. A disabled calendar also disables its prev / next buttons, which reflect `data-disabled` of their own rather than the native attribute.
|
|
192
192
|
|
|
193
193
|
### Constraints & week start
|
|
194
194
|
|
|
@@ -341,12 +341,18 @@ The recommended path is `[forCalendarMonthSelect]` and `[forCalendarYearSelect]`
|
|
|
341
341
|
/>
|
|
342
342
|
</svg>
|
|
343
343
|
</button>
|
|
344
|
-
<select forCalendarMonthSelect #m="forCalendarMonthSelect">
|
|
344
|
+
<select forCalendarMonthSelect #m="forCalendarMonthSelect" aria-label="Month">
|
|
345
345
|
@for (opt of m.options(); track opt.value) {
|
|
346
346
|
<option [value]="opt.value" [disabled]="opt.disabled">{{ opt.label }}</option>
|
|
347
347
|
}
|
|
348
348
|
</select>
|
|
349
|
-
<select
|
|
349
|
+
<select
|
|
350
|
+
forCalendarYearSelect
|
|
351
|
+
#y="forCalendarYearSelect"
|
|
352
|
+
aria-label="Year"
|
|
353
|
+
[minYear]="1900"
|
|
354
|
+
[maxYear]="2100"
|
|
355
|
+
>
|
|
350
356
|
@for (opt of y.years(); track opt.value) {
|
|
351
357
|
<option [value]="opt.value" [disabled]="opt.disabled">{{ opt.value }}</option>
|
|
352
358
|
}
|
|
@@ -389,6 +395,8 @@ The default window is **anchored to the current year** (not the visible year), s
|
|
|
389
395
|
|
|
390
396
|
**Keep `[forCalendarHeading]` in the DOM.** The grid's `aria-labelledby` points at the heading's id. When dropdowns replace the visible heading, keep a visually-hidden `[forCalendarHeading]` so the grid stays named. Removing the heading entirely leaves `aria-labelledby` pointing at a missing element.
|
|
391
397
|
|
|
398
|
+
**Name each `<select>` yourself.** Neither directive names the element it sits on, and the heading names the grid, not the dropdowns. Without a name a screen reader announces only the value each one holds, so give each an `aria-label` as the snippet above does, or a `<label for>`.
|
|
399
|
+
|
|
392
400
|
The lower-level hooks (`visibleMonthNumber()`, `visibleYear()`, `monthOptions()`, `goToMonth()`, `goToYear()`, `isYearDisabled()`) in the table above remain available for any other UI.
|
|
393
401
|
|
|
394
402
|
## View switching
|
|
@@ -536,6 +544,8 @@ Auto-disabled when the entire previous / next page would be outside `[min, max]`
|
|
|
536
544
|
|
|
537
545
|
## Scoped defaults
|
|
538
546
|
|
|
547
|
+
`provideForCalendarDefaults` configures calendar defaults for an injector subtree, either at the application root or in any component's `providers` array. Partial overrides inherit unspecified keys from the parent scope (or the library fallbacks at the root).
|
|
548
|
+
|
|
539
549
|
```ts
|
|
540
550
|
import { provideForCalendarDefaults } from 'forty-cdk/defaults';
|
|
541
551
|
|
|
@@ -548,6 +558,8 @@ providers: [
|
|
|
548
558
|
];
|
|
549
559
|
```
|
|
550
560
|
|
|
561
|
+
`firstDayOfWeek` sets the first column's weekday as a **0-6** index (`0` = Sunday, `1` = Monday) for calendars that don't bind `[firstDayOfWeek]`. Its fallback `null` takes the week start from the date adapter's `getFirstDayOfWeek()`, and a calendar's own `[firstDayOfWeek]` input always wins over the scope default.
|
|
562
|
+
|
|
551
563
|
`outsideMonthLabel` builds the `aria-label` of a padding day outside the visible month from its formatted full date (default `"<date> (outside month)"`), so assistive tech can tell it apart from the month on screen. A calendar bound to its own `[dateLabel]` formatter ignores it.
|
|
552
564
|
|
|
553
565
|
## Keyboard
|
|
@@ -575,7 +587,7 @@ Implements the [WAI-ARIA Grid pattern](https://www.w3.org/WAI/ARIA/apg/patterns/
|
|
|
575
587
|
- **`aria-selected`** is always emitted (`"true"` / `"false"`); **`aria-current="date"`** marks today; **`aria-disabled`** marks unavailable dates (truthy-only).
|
|
576
588
|
- **`aria-multiselectable="true"`** is set on the day grid in `selectionMode="range"`, where a committed range selects several cells, and is absent in single mode.
|
|
577
589
|
- **Roving tabindex**: exactly one cell (the focused date) is tabbable. `Tab` enters and leaves the grid in one stop.
|
|
578
|
-
- **Boolean `data-*`** on the cell, present when true and absent when false: `data-selected`, `data-today`, `data-highlighted` (the
|
|
590
|
+
- **Boolean `data-*`** on the cell, present when true and absent when false: `data-selected`, `data-today`, `data-highlighted` (the roving tab-stop cell, kept after focus leaves the grid), `data-disabled` and `data-outside-month`.
|
|
579
591
|
|
|
580
592
|
## Styling
|
|
581
593
|
|
|
@@ -592,7 +604,7 @@ forty-cdk ships no styles: put your own class on each piece and key your CSS off
|
|
|
592
604
|
.calendar-cell[data-today] {
|
|
593
605
|
outline: 1px solid var(--accent);
|
|
594
606
|
}
|
|
595
|
-
.calendar-cell[data-outside-month] {
|
|
607
|
+
.calendar-cell[data-outside-month]:not([data-selected]) {
|
|
596
608
|
opacity: 0.4;
|
|
597
609
|
}
|
|
598
610
|
.calendar-cell[data-disabled] {
|
package/carousel/README.md
CHANGED
|
@@ -5,7 +5,7 @@ archetype: [composable-ui]
|
|
|
5
5
|
apgUrl: https://www.w3.org/WAI/ARIA/apg/patterns/carousel/
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
#
|
|
8
|
+
# Carousel
|
|
9
9
|
|
|
10
10
|
A slideshow of content panels with previous / next controls, an indicator group, optional looping and multi-slide views, and an accessible autoplay mode with a pause control.
|
|
11
11
|
|
|
@@ -267,7 +267,7 @@ the defaults with `startLabel` / `stopLabel` inputs:
|
|
|
267
267
|
```
|
|
268
268
|
|
|
269
269
|
Both defaults come from the scope's `rotationStartLabel` / `rotationStopLabel`
|
|
270
|
-
(see [
|
|
270
|
+
(see [Scoped defaults](#scoped-defaults)); set either
|
|
271
271
|
input to `null` when the button carries a visible text label and you don't want
|
|
272
272
|
an `aria-label` overriding it.
|
|
273
273
|
|
|
@@ -357,40 +357,47 @@ horizontal carousels (allows vertical page scroll) and `pan-x` for vertical
|
|
|
357
357
|
carousels (allows horizontal page scroll). A mostly-cross-axis swipe is never
|
|
358
358
|
captured, so page scrolling on the perpendicular axis is unaffected.
|
|
359
359
|
|
|
360
|
-
##
|
|
360
|
+
## Scoped defaults
|
|
361
361
|
|
|
362
|
-
|
|
363
|
-
indicator's is `"Go to slide N"`, and the rotation control's swaps between
|
|
364
|
-
`"Start automatic slide show"` and `"Stop automatic slide show"`. The root and
|
|
365
|
-
each slide also carry an `aria-roledescription` (`"carousel"` / `"slide"`), which
|
|
366
|
-
a screen reader speaks in place of the `group` role. Localize them all centrally
|
|
367
|
-
with `provideForCarouselDefaults` instead of setting `ariaLabel` on every slide
|
|
368
|
-
and indicator:
|
|
362
|
+
`provideForCarouselDefaults` configures carousel defaults for an injector subtree, either at the application root or in any component's `providers` array. Partial overrides inherit unspecified keys from the parent scope (or the library fallbacks at the root), so you can localize just the labels and inherit the rest.
|
|
369
363
|
|
|
370
|
-
|
|
364
|
+
| Key | Library fallback | Meaning |
|
|
365
|
+
| ---------------------- | ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
366
|
+
| `loop` | `false` | Whether `next` past the last slide wraps to the first and `prev` before the first wraps to the last, for carousels that don't set `loop` themselves. |
|
|
367
|
+
| `align` | `'start'` | Alignment of the active slide within the viewport, for carousels that don't set `align` themselves. |
|
|
368
|
+
| `slidesPerView` | `1` | Number of slides visible at once, for carousels that don't set `slidesPerView` themselves. |
|
|
369
|
+
| `containScroll` | `false` | Whether the track offset is clamped so trailing slides sit flush at the viewport edge, for carousels that don't set `containScroll` themselves. See [Contain scroll](#contain-scroll). |
|
|
370
|
+
| `autoplay` | `false` | Whether the carousel rotates automatically on mount (never under reduced motion), for carousels that don't set `autoplay` themselves. |
|
|
371
|
+
| `autoplayInterval` | `5000` | Milliseconds between automatic slide advances, for carousels that don't set `autoplayInterval` themselves. |
|
|
372
|
+
| `slideLabel` | `"N of M"`, e.g. `"2 of 5"` | Builds each slide's default `aria-label` from `position` (1-based) and `total` (the slide count) and returns the string. |
|
|
373
|
+
| `indicatorLabel` | `"Go to slide N"` | Builds each indicator's default `aria-label` from `position` (1-based) and returns the string. |
|
|
374
|
+
| `rotationStartLabel` | `'Start automatic slide show'` | Accessible name of `[forCarouselRotationControl]` while rotation is stopped, for controls that don't set `[startLabel]` themselves. |
|
|
375
|
+
| `rotationStopLabel` | `'Stop automatic slide show'` | Accessible name of `[forCarouselRotationControl]` while rotation is playing, for controls that don't set `[stopLabel]` themselves. |
|
|
376
|
+
| `roleDescription` | `'carousel'` | `aria-roledescription` of the carousel root, spoken in place of its `group` role. An empty string drops the attribute. |
|
|
377
|
+
| `slideRoleDescription` | `'slide'` | `aria-roledescription` of each `[forCarouselSlide]`, spoken in place of its `group` role. An empty string drops the attribute. |
|
|
378
|
+
|
|
379
|
+
Per-instance inputs always win over the scope defaults: an `ariaLabel` on `[forCarouselSlide]` / `[forCarouselIndicator]` overrides the built label, as do `[startLabel]` / `[stopLabel]` on `[forCarouselRotationControl]`.
|
|
380
|
+
|
|
381
|
+
`rotationStartLabel`, `rotationStopLabel`, `roleDescription` and `slideRoleDescription` each accept a string or a function returning one; a function can read a language signal, so the text follows a language the app sets or switches after bootstrap, as [Localizing default text](../shared/README.md#localizing-default-text) shows. Localize them all centrally instead of setting `ariaLabel` on every slide and indicator:
|
|
371
382
|
|
|
372
383
|
```ts
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
384
|
+
import { type ApplicationConfig } from '@angular/core';
|
|
385
|
+
import { provideForCarouselDefaults } from 'forty-cdk/defaults';
|
|
386
|
+
|
|
387
|
+
export const appConfig: ApplicationConfig = {
|
|
388
|
+
providers: [
|
|
389
|
+
provideForCarouselDefaults({
|
|
390
|
+
slideLabel: (position, total) => `Diapositiva ${position} de ${total}`,
|
|
391
|
+
indicatorLabel: (position) => `Ir a la diapositiva ${position}`,
|
|
392
|
+
rotationStartLabel: 'Iniciar la presentación',
|
|
393
|
+
rotationStopLabel: 'Detener la presentación',
|
|
394
|
+
roleDescription: 'carrusel',
|
|
395
|
+
slideRoleDescription: 'diapositiva',
|
|
396
|
+
}),
|
|
397
|
+
],
|
|
398
|
+
};
|
|
383
399
|
```
|
|
384
400
|
|
|
385
|
-
`position` is the 1-based slide index and `total` is the slide count. Overrides
|
|
386
|
-
merge with the parent scope, so you can localize just the labels and inherit the
|
|
387
|
-
rest of the defaults. A per-element `ariaLabel` on `[forCarouselSlide]` /
|
|
388
|
-
`[forCarouselIndicator]` still takes precedence over the localized default, as do
|
|
389
|
-
`[startLabel]` / `[stopLabel]` on `[forCarouselRotationControl]`. For a language
|
|
390
|
-
the app sets or switches after bootstrap, pass the text keys as functions and the
|
|
391
|
-
overrides as a factory, as
|
|
392
|
-
[Localizing default text](../shared/README.md#localizing-default-text) shows.
|
|
393
|
-
|
|
394
401
|
## Indicators map 1:1 to slides
|
|
395
402
|
|
|
396
403
|
The picker assumes **one `[forCarouselIndicator]` per `[forCarouselSlide]`**: the
|
|
@@ -487,7 +494,7 @@ Implements the [WAI-ARIA Carousel pattern](https://www.w3.org/WAI/ARIA/apg/patte
|
|
|
487
494
|
`aria-label="N of M"` by default. Override per slide with the `ariaLabel` input,
|
|
488
495
|
or localize the default format and both role descriptions app-wide with
|
|
489
496
|
`provideForCarouselDefaults` (see
|
|
490
|
-
[
|
|
497
|
+
[Scoped defaults](#scoped-defaults)).
|
|
491
498
|
- Slides outside the viewport receive `aria-hidden="true"` and `inert` to remove them from
|
|
492
499
|
the accessibility tree and focus order. The visible set follows the laid-out offset, so
|
|
493
500
|
`align` and `containScroll` decide which slides stay reachable.
|