@lo-tek/interfaces 0.41.0 → 0.43.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +107 -0
- package/agent/astro.md +1 -1
- package/agent/bundles.md +1 -1
- package/agent/datastar.md +57 -50
- package/agent/html.md +53 -53
- package/agent/kotlin.md +4 -4
- package/agent/react.md +1 -1
- package/agent/templates.md +50 -50
- package/dist/components/frame/dialog/lt-dialog.d.ts +11 -3
- package/dist/components/frame/dialog/lt-dialog.d.ts.map +1 -1
- package/dist/components/frame/dialog/lt-dialog.js +59 -46
- package/dist/components/frame/dialog/lt-dialog.js.map +1 -1
- package/dist/components/frame/error-summary/lt-error-summary.d.ts +9 -6
- package/dist/components/frame/error-summary/lt-error-summary.d.ts.map +1 -1
- package/dist/components/frame/error-summary/lt-error-summary.js +38 -57
- package/dist/components/frame/error-summary/lt-error-summary.js.map +1 -1
- package/dist/components/frame/field/lt-field.d.ts +17 -26
- package/dist/components/frame/field/lt-field.d.ts.map +1 -1
- package/dist/components/frame/field/lt-field.js +81 -143
- package/dist/components/frame/field/lt-field.js.map +1 -1
- package/dist/components/frame/popover/lt-popover.d.ts +1 -1
- package/dist/components/frame/popover/lt-popover.d.ts.map +1 -1
- package/dist/components/frame/popover/lt-popover.js +31 -33
- package/dist/components/frame/popover/lt-popover.js.map +1 -1
- package/dist/components/frame/session-timeout/lt-session-timeout.d.ts +14 -2
- package/dist/components/frame/session-timeout/lt-session-timeout.d.ts.map +1 -1
- package/dist/components/frame/session-timeout/lt-session-timeout.js +73 -46
- package/dist/components/frame/session-timeout/lt-session-timeout.js.map +1 -1
- package/dist/components/frame/suggestion/lt-suggestion.d.ts +5 -7
- package/dist/components/frame/suggestion/lt-suggestion.d.ts.map +1 -1
- package/dist/components/frame/suggestion/lt-suggestion.js +57 -72
- package/dist/components/frame/suggestion/lt-suggestion.js.map +1 -1
- package/dist/components/frame/tabs/lt-tabs.d.ts +14 -5
- package/dist/components/frame/tabs/lt-tabs.d.ts.map +1 -1
- package/dist/components/frame/tabs/lt-tabs.js +86 -106
- package/dist/components/frame/tabs/lt-tabs.js.map +1 -1
- package/dist/components/frame/term/lt-term.d.ts +5 -1
- package/dist/components/frame/term/lt-term.d.ts.map +1 -1
- package/dist/components/frame/term/lt-term.js +23 -21
- package/dist/components/frame/term/lt-term.js.map +1 -1
- package/dist/components/host-element.d.ts +137 -2
- package/dist/components/host-element.d.ts.map +1 -1
- package/dist/components/host-element.js +187 -4
- package/dist/components/host-element.js.map +1 -1
- package/dist/lotek.css +1 -1
- package/dist/react.d.ts +51 -437
- package/dist/react.d.ts.map +1 -1
- package/dist/react.js +48 -208
- package/dist/react.js.map +1 -1
- package/live-templates-kotlin.xml +4 -6
- package/manifest/manifest.json +1 -1
- package/package.json +7 -3
- package/src/components/frame/dialog/lt-dialog.ts +56 -50
- package/src/components/frame/error-summary/lt-error-summary.ts +33 -46
- package/src/components/frame/field/lt-field.ts +99 -207
- package/src/components/frame/popover/lt-popover.ts +37 -35
- package/src/components/frame/session-timeout/lt-session-timeout.ts +88 -46
- package/src/components/frame/suggestion/lt-suggestion.ts +59 -73
- package/src/components/frame/tabs/lt-tabs.ts +96 -122
- package/src/components/frame/term/lt-term.ts +27 -21
- package/src/components/host-element.ts +306 -3
- package/src/react.ts +125 -240
- package/web-types.json +1 -1
package/agent/templates.md
CHANGED
|
@@ -20,7 +20,7 @@ the attributes in a template that cannot call a builder function, and no type
|
|
|
20
20
|
stops `data-variant="outlined"`. That is why item 5 applies more strictly here
|
|
21
21
|
than anywhere else: the check is the only thing that reads your markup.
|
|
22
22
|
|
|
23
|
-
This is @lo-tek/interfaces 0.
|
|
23
|
+
This is @lo-tek/interfaces 0.43.0. The file is generated by the package and
|
|
24
24
|
follows its version, so it can never say anything other than the code next to
|
|
25
25
|
it.
|
|
26
26
|
|
|
@@ -54,7 +54,7 @@ it.
|
|
|
54
54
|
One link in the page template, with all the components:
|
|
55
55
|
|
|
56
56
|
```html
|
|
57
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
57
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.43.0/dist/lotek.css">
|
|
58
58
|
```
|
|
59
59
|
|
|
60
60
|
Or from your own server, if you copy the file into your static assets.
|
|
@@ -80,42 +80,42 @@ The default variant has no attribute.
|
|
|
80
80
|
|
|
81
81
|
| Class | Stylesheet | Attributes |
|
|
82
82
|
| --- | --- | --- |
|
|
83
|
-
| `lt-accordion`<br>`lt-accordion__content` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
84
|
-
| `lt-alert`<br>`lt-alert__title` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
85
|
-
| `lt-avatar`<br>`lt-avatar-stack` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
86
|
-
| `lt-badge` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
87
|
-
| `lt-breadcrumbs` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
88
|
-
| `lt-button` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
89
|
-
| `lt-card`<br>`lt-card__title` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
90
|
-
| `lt-checkbox`<br>`lt-checkbox-row` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
91
|
-
| `lt-divider` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
92
|
-
| `lt-error-text` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
93
|
-
| `lt-fieldset`<br>`lt-legend` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
94
|
-
| `lt-file-upload`<br>`lt-file-upload-list` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
95
|
-
| `lt-heading` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
96
|
-
| `lt-help-text` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
97
|
-
| `lt-icon` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
98
|
-
| `lt-input` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
99
|
-
| `lt-label` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
100
|
-
| `lt-link` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
101
|
-
| `lt-list` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
102
|
-
| `lt-pagination`<br>`lt-pagination__gap` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
103
|
-
| `lt-paragraph` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
104
|
-
| `lt-progress` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
105
|
-
| `lt-radio`<br>`lt-radio-row` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
106
|
-
| `lt-search`<br>`lt-search-row` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
107
|
-
| `lt-select` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
108
|
-
| `lt-skeleton` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
109
|
-
| `lt-skip-link` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
110
|
-
| `lt-spinner` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
111
|
-
| `lt-sr-only` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
112
|
-
| `lt-steps` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
113
|
-
| `lt-switch`<br>`lt-switch-row` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
114
|
-
| `lt-table`<br>`lt-table__sort`<br>`lt-table-scroll` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
115
|
-
| `lt-tag` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
116
|
-
| `lt-textarea` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
117
|
-
| `lt-toggle-group`<br>`lt-toggle-group__option` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
118
|
-
| `lt-tooltip`<br>`lt-tooltip__bubble` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
83
|
+
| `lt-accordion`<br>`lt-accordion__content` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.43.0/src/components/css/accordion/accordion.css` | `data-variant`: plain |
|
|
84
|
+
| `lt-alert`<br>`lt-alert__title` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.43.0/src/components/css/alert/alert.css` | `data-color`: info, success, warning, danger |
|
|
85
|
+
| `lt-avatar`<br>`lt-avatar-stack` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.43.0/src/components/css/avatar/avatar.css` | `data-variant`: square<br>`data-size`: small, large |
|
|
86
|
+
| `lt-badge` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.43.0/src/components/css/badge/badge.css` | `data-color`: success, warning, danger, neutral |
|
|
87
|
+
| `lt-breadcrumbs` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.43.0/src/components/css/breadcrumbs/breadcrumbs.css` | none |
|
|
88
|
+
| `lt-button` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.43.0/src/components/css/button/button.css` | `data-variant`: secondary, ghost, danger |
|
|
89
|
+
| `lt-card`<br>`lt-card__title` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.43.0/src/components/css/card/card.css` | `data-variant`: filled<br>`data-interactive` (flag) |
|
|
90
|
+
| `lt-checkbox`<br>`lt-checkbox-row` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.43.0/src/components/css/checkbox/checkbox.css` | `data-state`: invalid, success |
|
|
91
|
+
| `lt-divider` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.43.0/src/components/css/divider/divider.css` | `data-variant`: subtle, strong |
|
|
92
|
+
| `lt-error-text` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.43.0/src/components/css/error-text/error-text.css` | `data-variant`: warning |
|
|
93
|
+
| `lt-fieldset`<br>`lt-legend` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.43.0/src/components/css/fieldset/fieldset.css` | `data-state`: invalid, success<br>`data-required`: symbol, text<br>`data-optional` (flag) |
|
|
94
|
+
| `lt-file-upload`<br>`lt-file-upload-list` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.43.0/src/components/css/file-upload/file-upload.css` | `data-state`: invalid, success |
|
|
95
|
+
| `lt-heading` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.43.0/src/components/css/heading/heading.css` | `data-size`: xs, s, m, xl, mega |
|
|
96
|
+
| `lt-help-text` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.43.0/src/components/css/help-text/help-text.css` | `data-variant`: strong, success, warning |
|
|
97
|
+
| `lt-icon` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.43.0/src/components/css/icon/icon.css` | none |
|
|
98
|
+
| `lt-input` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.43.0/src/components/css/input/input.css` | `data-state`: invalid, success<br>`data-variant`: date, datetime-local, time |
|
|
99
|
+
| `lt-label` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.43.0/src/components/css/label/label.css` | `data-required`: symbol, text<br>`data-optional` (flag) |
|
|
100
|
+
| `lt-link` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.43.0/src/components/css/link/link.css` | none |
|
|
101
|
+
| `lt-list` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.43.0/src/components/css/list/list.css` | `data-variant`: plain, divided |
|
|
102
|
+
| `lt-pagination`<br>`lt-pagination__gap` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.43.0/src/components/css/pagination/pagination.css` | none |
|
|
103
|
+
| `lt-paragraph` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.43.0/src/components/css/paragraph/paragraph.css` | `data-variant`: lead<br>`data-size`: small, large |
|
|
104
|
+
| `lt-progress` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.43.0/src/components/css/progress/progress.css` | `data-color`: success, warning, danger |
|
|
105
|
+
| `lt-radio`<br>`lt-radio-row` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.43.0/src/components/css/radio/radio.css` | `data-state`: invalid, success |
|
|
106
|
+
| `lt-search`<br>`lt-search-row` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.43.0/src/components/css/search/search.css` | `data-state`: invalid, success |
|
|
107
|
+
| `lt-select` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.43.0/src/components/css/select/select.css` | `data-state`: invalid, success<br>`data-picker`: styled |
|
|
108
|
+
| `lt-skeleton` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.43.0/src/components/css/skeleton/skeleton.css` | `data-variant`: text, circle |
|
|
109
|
+
| `lt-skip-link` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.43.0/src/components/css/skip-link/skip-link.css` | none |
|
|
110
|
+
| `lt-spinner` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.43.0/src/components/css/spinner/spinner.css` | `data-size`: small, large |
|
|
111
|
+
| `lt-sr-only` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.43.0/src/components/css/sr-only/sr-only.css` | none |
|
|
112
|
+
| `lt-steps` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.43.0/src/components/css/steps/steps.css` | none |
|
|
113
|
+
| `lt-switch`<br>`lt-switch-row` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.43.0/src/components/css/switch/switch.css` | none |
|
|
114
|
+
| `lt-table`<br>`lt-table__sort`<br>`lt-table-scroll` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.43.0/src/components/css/table/table.css` | `data-variant`: striped<br>`data-hoverable` (flag) |
|
|
115
|
+
| `lt-tag` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.43.0/src/components/css/tag/tag.css` | `data-variant`: filled<br>`data-selectable` (flag) |
|
|
116
|
+
| `lt-textarea` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.43.0/src/components/css/textarea/textarea.css` | `data-state`: invalid, success |
|
|
117
|
+
| `lt-toggle-group`<br>`lt-toggle-group__option` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.43.0/src/components/css/toggle-group/toggle-group.css` | none |
|
|
118
|
+
| `lt-tooltip`<br>`lt-tooltip__bubble` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.43.0/src/components/css/tooltip/tooltip.css` | none |
|
|
119
119
|
|
|
120
120
|
There is also `lt-theme-control`, a class on a radio button that lets the user
|
|
121
121
|
choose a theme. It is in `tokens.css`, and is described under Tokens.
|
|
@@ -194,7 +194,7 @@ root element:
|
|
|
194
194
|
Below the root element the browser then ignores the host's CSS without a
|
|
195
195
|
layer, unless a rule of the host's wins on specificity as described below, and
|
|
196
196
|
LO-TEK's layer applies again. The rule is in `lotek.css` and in
|
|
197
|
-
`https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
197
|
+
`https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.43.0/src/tokens/boundary.css`.
|
|
198
198
|
Fonts and other inherited properties still come from the host, and the
|
|
199
199
|
`--lt-*` variables work. Three things follow from it:
|
|
200
200
|
|
|
@@ -288,16 +288,16 @@ Three rules apply to all of them:
|
|
|
288
288
|
|
|
289
289
|
| Element | Category | Stylesheet | Registration | Attributes | Events | Classes inside |
|
|
290
290
|
| --- | --- | --- | --- | --- | --- | --- |
|
|
291
|
-
| `<lt-field>` | frame | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
292
|
-
| `<lt-tabs>` | frame | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
293
|
-
| `<lt-error-summary>` | frame | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
294
|
-
| `<lt-popover>` | frame | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
295
|
-
| `<lt-term>` | frame | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
296
|
-
| `<lt-suggestion>` | frame | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
297
|
-
| `<lt-dialog>` | frame | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
298
|
-
| `<lt-toast>` | standalone | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
299
|
-
| `<lt-session-timeout>` | frame | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
300
|
-
| `<lt-connection-status>` | standalone | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
291
|
+
| `<lt-field>` | frame | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.43.0/src/components/frame/field/field.css` | `defineLtField()` from `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.43.0/dist/components/frame/field/lt-field.js` | `disabled` (flag)<br>`optional` (flag)<br>`described-by` (text) | none | none |
|
|
292
|
+
| `<lt-tabs>` | frame | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.43.0/src/components/frame/tabs/tabs.css` | `defineLtTabs()` from `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.43.0/dist/components/frame/tabs/lt-tabs.js` | `server-controlled` (flag)<br>`activation`: manual, automatic | `tab-select` (index) | `lt-tabs__list`<br>`lt-tabs__panel` |
|
|
293
|
+
| `<lt-error-summary>` | frame | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.43.0/src/components/frame/error-summary/error-summary.css` | `defineLtErrorSummary()` from `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.43.0/dist/components/frame/error-summary/lt-error-summary.js` | `data-autofocus`: false, true<br>`hidden` (flag) | none | `lt-error-summary`<br>`lt-error-summary__title` |
|
|
294
|
+
| `<lt-popover>` | frame | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.43.0/src/components/frame/popover/popover.css` | `defineLtPopover()` from `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.43.0/dist/components/frame/popover/lt-popover.js` | `open` (flag)<br>`placement`: bottom-start, bottom-end, top-start, top-end<br>`server-controlled` (flag) | `popover-toggle` (open) | `lt-popover` |
|
|
295
|
+
| `<lt-term>` | frame | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.43.0/src/components/frame/term/term.css` | `defineLtTerm()` from `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.43.0/dist/components/frame/term/lt-term.js` | none | none | `lt-term`<br>`lt-term__entry` |
|
|
296
|
+
| `<lt-suggestion>` | frame | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.43.0/src/components/frame/suggestion/suggestion.css` | `defineLtSuggestion()` from `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.43.0/dist/components/frame/suggestion/lt-suggestion.js` | `prefiltered` (flag)<br>`count-none` (text)<br>`count-zero` (text)<br>`count-one` (text)<br>`count-two` (text)<br>`count-few` (text)<br>`count-many` (text)<br>`count-other` (text)<br>`server-controlled` (flag) | `suggestion-select` (value, label) | `lt-suggestion__list`<br>`lt-suggestion__option`<br>`lt-suggestion__value`<br>`lt-suggestion__empty` |
|
|
297
|
+
| `<lt-dialog>` | frame | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.43.0/src/components/frame/dialog/dialog.css` | `defineLtDialog()` from `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.43.0/dist/components/frame/dialog/lt-dialog.js` | `open` (flag)<br>`server-controlled` (flag) | `dialog-toggle` (open, returnValue) | `lt-dialog` (`data-color`: brand, info, success, warning, danger)<br>`lt-dialog__body`<br>`lt-dialog__title`<br>`lt-dialog__footer`<br>`lt-dialog__header`<br>`lt-dialog__subtitle` |
|
|
298
|
+
| `<lt-toast>` | standalone | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.43.0/src/components/standalone/toast/toast.css` | `defineLtToast()` from `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.43.0/dist/components/standalone/toast/lt-toast.js` | `duration` (number)<br>`label` (text)<br>`close-label` (text) | `toast-dismiss` | `lt-toast`<br>`lt-toast__message`<br>`lt-toast__close` |
|
|
299
|
+
| `<lt-session-timeout>` | frame | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.43.0/src/components/frame/session-timeout/session-timeout.css` | `defineLtSessionTimeout()` from `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.43.0/dist/components/frame/session-timeout/lt-session-timeout.js` | `warn-at` (number)<br>`expires-at` (number)<br>`activity-interval` (number) | `session-warn`<br>`session-extend`<br>`session-logout`<br>`session-expired`<br>`session-activity` | `lt-session-timeout`<br>`lt-session-timeout__dialog`<br>`lt-session-timeout__title`<br>`lt-session-timeout__text`<br>`lt-session-timeout__count`<br>`lt-session-timeout__actions` |
|
|
300
|
+
| `<lt-connection-status>` | standalone | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.43.0/src/components/standalone/connection-status/connection-status.css` | `defineLtConnectionStatus()` from `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.43.0/dist/components/standalone/connection-status/lt-connection-status.js` | `offline-text` (text)<br>`online-text` (text) | `connection-lost`<br>`connection-restored` | `lt-connection-status`<br>`lt-connection-status__bar` |
|
|
301
301
|
|
|
302
302
|
None of them uses shadow DOM. The content is in plain DOM, so `querySelector`,
|
|
303
303
|
`FormData` and ordinary CSS work straight into it.
|
|
@@ -334,7 +334,7 @@ The registration, once in the page template:
|
|
|
334
334
|
```html
|
|
335
335
|
<script type="module">
|
|
336
336
|
import { defineLtField } from
|
|
337
|
-
"https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
337
|
+
"https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.43.0/dist/components/frame/field/lt-field.js"
|
|
338
338
|
|
|
339
339
|
defineLtField()
|
|
340
340
|
</script>
|
|
@@ -12,7 +12,7 @@ export declare const LT_DIALOG_PARTS: {
|
|
|
12
12
|
};
|
|
13
13
|
export declare class LtDialog extends HostElement {
|
|
14
14
|
static observedAttributes: readonly ["open", "server-controlled"];
|
|
15
|
-
private
|
|
15
|
+
private readonly watch;
|
|
16
16
|
/**
|
|
17
17
|
* A separate observer for `open` on the `<dialog>` itself.
|
|
18
18
|
*
|
|
@@ -21,9 +21,10 @@ export declare class LtDialog extends HostElement {
|
|
|
21
21
|
* an observer running all of `sync()` there would have seen a host still
|
|
22
22
|
* saying "open" and a dialog that was not modal, and opened it again before
|
|
23
23
|
* `close` was handled. This one does only one thing: it puts the attribute
|
|
24
|
-
* back on a dialog that is still in the top layer.
|
|
24
|
+
* back on a dialog that is still in the top layer. It is started again on
|
|
25
|
+
* a dialog the server replaced.
|
|
25
26
|
*/
|
|
26
|
-
private
|
|
27
|
+
private readonly openWatch;
|
|
27
28
|
private dialogElement?;
|
|
28
29
|
/**
|
|
29
30
|
* What the component last reported, so it reports only when the state
|
|
@@ -50,6 +51,13 @@ export declare class LtDialog extends HostElement {
|
|
|
50
51
|
private get dialog();
|
|
51
52
|
/** The id the component gave the heading, so a patch gets the same one back. */
|
|
52
53
|
private titleId?;
|
|
54
|
+
/**
|
|
55
|
+
* The `aria-labelledby` the component wrote on the `<dialog>`. Another
|
|
56
|
+
* value there is the server's, and stays; the component's own follows the
|
|
57
|
+
* title, so a patch that replaces the title does not leave the name
|
|
58
|
+
* pointing at an id that is gone.
|
|
59
|
+
*/
|
|
60
|
+
private readonly own;
|
|
53
61
|
/** The wiring alone, for an attribute record. See the observer. */
|
|
54
62
|
private rewire;
|
|
55
63
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lt-dialog.d.ts","sourceRoot":"","sources":["../../../../src/components/frame/dialog/lt-dialog.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,WAAW,
|
|
1
|
+
{"version":3,"file":"lt-dialog.d.ts","sourceRoot":"","sources":["../../../../src/components/frame/dialog/lt-dialog.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,WAAW,EAYZ,MAAM,uBAAuB,CAAA;AAO9B,eAAO,MAAM,aAAa,EAAG,WAAoB,CAAA;AAEjD;;;;GAIG;AACH,eAAO,MAAM,eAAe;;;;CAIlB,CAAA;AA4DV,qBAAa,QAAS,SAAQ,WAAW;IACvC,MAAM,CAAC,kBAAkB,yCAAuC;IAEhE,OAAO,CAAC,QAAQ,CAAC,KAAK,CAgBrB;IACD;;;;;;;;;;OAUG;IACH,OAAO,CAAC,QAAQ,CAAC,SAAS,CAExB;IACF,OAAO,CAAC,aAAa,CAAC,CAAmB;IACzC;;;;;;;;OAQG;IACH,OAAO,CAAC,YAAY,CAAC,CAAS;IAE9B,gEAAgE;IAChE,IAAI,IAAI,IAAI,OAAO,CAElB;IAED,IAAI,IAAI,CAAC,KAAK,EAAE,OAAO,EAEtB;IAED,iBAAiB,IAAI,IAAI;IA8BzB,oBAAoB,IAAI,IAAI;IAO5B,wBAAwB,IAAI,IAAI;IAIhC;;;;;OAKG;IACH,OAAO,KAAK,MAAM,GAEjB;IAED,gFAAgF;IAChF,OAAO,CAAC,OAAO,CAAC,CAAQ;IACxB;;;;;OAKG;IACH,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAc;IAElC,mEAAmE;IACnE,OAAO,CAAC,MAAM;IAKd;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,SAAS;IAYjB;;;;OAIG;IACH,OAAO,CAAC,QAAQ;IAQhB;;;;;;;;OAQG;IACH,OAAO,CAAC,IAAI;IAsCZ,OAAO,CAAC,MAAM;IAed;;;;;;;;;;;;;OAaG;IACH,OAAO,CAAC,UAAU;IAwBlB,OAAO,CAAC,WAAW,CAYlB;IAED,OAAO,CAAC,IAAI;CAoJb;AAED,wBAAgB,cAAc,CAAC,OAAO,GAAE,MAAsB,GAAG,IAAI,CAEpE"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { addClass, defineElement, HostElement, isServerControlled, SERVER_CONTROLLED, setAttr, setFlag, uniqueId, warnAboutMarkup, } from "../../host-element.js";
|
|
1
|
+
import { addClass, defineElement, HostElement, hasName, isServerControlled, nameFromHeading, ownership, restoreModalOpen, SERVER_CONTROLLED, setAttr, setFlag, uniqueId, warnAboutMarkup, watcher, } from "../../host-element.js";
|
|
2
2
|
import { DIALOG_BODY_CLASS, DIALOG_CLASS, DIALOG_TITLE_CLASS, } from "./dialog.js";
|
|
3
3
|
export const LT_DIALOG_TAG = "lt-dialog";
|
|
4
4
|
/**
|
|
@@ -71,6 +71,41 @@ const upgradeChecked = new WeakSet();
|
|
|
71
71
|
export class LtDialog extends HostElement {
|
|
72
72
|
constructor() {
|
|
73
73
|
super(...arguments);
|
|
74
|
+
this.watch = watcher((records) => {
|
|
75
|
+
const swapped = records.some((record) => record.type === "childList" && record.target === this);
|
|
76
|
+
if (swapped)
|
|
77
|
+
this.sync();
|
|
78
|
+
else
|
|
79
|
+
this.rewire();
|
|
80
|
+
}, {
|
|
81
|
+
childList: true,
|
|
82
|
+
subtree: true,
|
|
83
|
+
attributes: true,
|
|
84
|
+
// `aria-label` too: removed, the dialog is named after its title
|
|
85
|
+
// again, and without it here the dialog was left without a name.
|
|
86
|
+
attributeFilter: ["class", "id", "aria-labelledby", "aria-label"],
|
|
87
|
+
});
|
|
88
|
+
/**
|
|
89
|
+
* A separate observer for `open` on the `<dialog>` itself.
|
|
90
|
+
*
|
|
91
|
+
* It cannot be merged with the other one. When the user closes the dialog,
|
|
92
|
+
* the browser removes the attribute first and sends `close` afterwards, and
|
|
93
|
+
* an observer running all of `sync()` there would have seen a host still
|
|
94
|
+
* saying "open" and a dialog that was not modal, and opened it again before
|
|
95
|
+
* `close` was handled. This one does only one thing: it puts the attribute
|
|
96
|
+
* back on a dialog that is still in the top layer. It is started again on
|
|
97
|
+
* a dialog the server replaced.
|
|
98
|
+
*/
|
|
99
|
+
this.openWatch = watcher(() => this.repairOpen(), {
|
|
100
|
+
attributeFilter: ["open"],
|
|
101
|
+
});
|
|
102
|
+
/**
|
|
103
|
+
* The `aria-labelledby` the component wrote on the `<dialog>`. Another
|
|
104
|
+
* value there is the server's, and stays; the component's own follows the
|
|
105
|
+
* title, so a patch that replaces the title does not leave the name
|
|
106
|
+
* pointing at an id that is gone.
|
|
107
|
+
*/
|
|
108
|
+
this.own = ownership();
|
|
74
109
|
this.handleClose = () => {
|
|
75
110
|
// `close` is queued, not synchronous. If the server manages to close and
|
|
76
111
|
// open again in the same task, this event no longer applies, and without
|
|
@@ -118,28 +153,12 @@ export class LtDialog extends HostElement {
|
|
|
118
153
|
* and opened it again before the close was handled. Every write compares
|
|
119
154
|
* first, or the observer would trigger itself.
|
|
120
155
|
*/
|
|
121
|
-
this.
|
|
122
|
-
const swapped = records.some((record) => record.type === "childList" && record.target === this);
|
|
123
|
-
if (swapped)
|
|
124
|
-
this.sync();
|
|
125
|
-
else
|
|
126
|
-
this.rewire();
|
|
127
|
-
});
|
|
128
|
-
this.observer.observe(this, {
|
|
129
|
-
childList: true,
|
|
130
|
-
subtree: true,
|
|
131
|
-
attributes: true,
|
|
132
|
-
// `aria-label` too: removed, the dialog is named after its title
|
|
133
|
-
// again, and without it here the dialog was left without a name.
|
|
134
|
-
attributeFilter: ["class", "id", "aria-labelledby", "aria-label"],
|
|
135
|
-
});
|
|
156
|
+
this.watch.start(this);
|
|
136
157
|
this.sync();
|
|
137
158
|
}
|
|
138
159
|
disconnectedCallback() {
|
|
139
|
-
this.
|
|
140
|
-
this.
|
|
141
|
-
this.openObserver?.disconnect();
|
|
142
|
-
this.openObserver = undefined;
|
|
160
|
+
this.watch.stop();
|
|
161
|
+
this.openWatch.stop();
|
|
143
162
|
this.dialogElement?.removeEventListener("close", this.handleClose);
|
|
144
163
|
this.dialogElement = undefined;
|
|
145
164
|
}
|
|
@@ -188,8 +207,7 @@ export class LtDialog extends HostElement {
|
|
|
188
207
|
*/
|
|
189
208
|
nameless(dialog) {
|
|
190
209
|
return (dialog.childElementCount > 0 &&
|
|
191
|
-
!dialog
|
|
192
|
-
!dialog.hasAttribute("aria-label") &&
|
|
210
|
+
!hasName(dialog) &&
|
|
193
211
|
this.headingOf(dialog) === null);
|
|
194
212
|
}
|
|
195
213
|
/**
|
|
@@ -203,10 +221,21 @@ export class LtDialog extends HostElement {
|
|
|
203
221
|
*/
|
|
204
222
|
wire(dialog) {
|
|
205
223
|
addClass(dialog, DIALOG_CLASS);
|
|
206
|
-
const
|
|
207
|
-
|
|
224
|
+
const name = nameFromHeading(this.own, this, dialog, () => {
|
|
225
|
+
const title = this.headingOf(dialog);
|
|
226
|
+
if (!title)
|
|
227
|
+
return null;
|
|
228
|
+
addClass(title, DIALOG_TITLE_CLASS);
|
|
229
|
+
if (!title.id) {
|
|
230
|
+
this.titleId ??= uniqueId("lt-dialog-title");
|
|
231
|
+
setAttr(title, "id", this.titleId);
|
|
232
|
+
}
|
|
233
|
+
return title.id;
|
|
234
|
+
});
|
|
235
|
+
if (name === "server") {
|
|
208
236
|
// The attribute can list several ids. The title is the first one that
|
|
209
237
|
// is inside the dialog.
|
|
238
|
+
const named = (dialog.getAttribute("aria-labelledby") ?? "").trim();
|
|
210
239
|
const root = this.getRootNode();
|
|
211
240
|
const title = named
|
|
212
241
|
.split(/\s+/)
|
|
@@ -214,12 +243,8 @@ export class LtDialog extends HostElement {
|
|
|
214
243
|
.find((element) => element !== null && dialog.contains(element));
|
|
215
244
|
if (title)
|
|
216
245
|
addClass(title, DIALOG_TITLE_CLASS);
|
|
217
|
-
return;
|
|
218
246
|
}
|
|
219
|
-
if (
|
|
220
|
-
return;
|
|
221
|
-
const title = this.headingOf(dialog);
|
|
222
|
-
if (!title) {
|
|
247
|
+
else if (name === "none") {
|
|
223
248
|
warnAboutMarkup(this, "the dialog has no name: it has no aria-labelledby, no " +
|
|
224
249
|
"aria-label and no heading outside the body, so a screen reader " +
|
|
225
250
|
'announces it as "dialog" without saying what it is about. Give ' +
|
|
@@ -227,14 +252,7 @@ export class LtDialog extends HostElement {
|
|
|
227
252
|
const now = this.dialog;
|
|
228
253
|
return now !== null && this.nameless(now);
|
|
229
254
|
});
|
|
230
|
-
return;
|
|
231
255
|
}
|
|
232
|
-
addClass(title, DIALOG_TITLE_CLASS);
|
|
233
|
-
if (!title.id) {
|
|
234
|
-
this.titleId ??= uniqueId("lt-dialog-title");
|
|
235
|
-
setAttr(title, "id", this.titleId);
|
|
236
|
-
}
|
|
237
|
-
setAttr(dialog, "aria-labelledby", title.id);
|
|
238
256
|
}
|
|
239
257
|
notify(open, returnValue = "") {
|
|
240
258
|
// A dialog starts closed: one that never opened reported a close.
|
|
@@ -265,13 +283,11 @@ export class LtDialog extends HostElement {
|
|
|
265
283
|
*/
|
|
266
284
|
repairOpen() {
|
|
267
285
|
const dialog = this.dialogElement;
|
|
268
|
-
if (!dialog?.isConnected || !dialog.matches(":modal") || dialog.open) {
|
|
269
|
-
return;
|
|
270
|
-
}
|
|
271
286
|
// The attribute must come back either way: without it `close()` does
|
|
272
287
|
// nothing, and the dialog stayed in the top layer, invisible, with the
|
|
273
288
|
// rest of the page inert.
|
|
274
|
-
|
|
289
|
+
if (!dialog || !restoreModalOpen(dialog))
|
|
290
|
+
return;
|
|
275
291
|
if (!isServerControlled(this))
|
|
276
292
|
return;
|
|
277
293
|
/*
|
|
@@ -303,8 +319,7 @@ export class LtDialog extends HostElement {
|
|
|
303
319
|
// listener stayed attached to a detached node for as long as the host
|
|
304
320
|
// lived.
|
|
305
321
|
if (!dialog) {
|
|
306
|
-
this.
|
|
307
|
-
this.openObserver = undefined;
|
|
322
|
+
this.openWatch.stop();
|
|
308
323
|
this.dialogElement?.removeEventListener("close", this.handleClose);
|
|
309
324
|
this.dialogElement = undefined;
|
|
310
325
|
}
|
|
@@ -314,7 +329,7 @@ export class LtDialog extends HostElement {
|
|
|
314
329
|
// If the component is detached, a morph is building the server's
|
|
315
330
|
// version in a separate tree, and there is nothing to report. An
|
|
316
331
|
// empty element is a region the server has not filled yet.
|
|
317
|
-
() => this.
|
|
332
|
+
() => this.dialog === null, { silentWhenEmpty: true });
|
|
318
333
|
return;
|
|
319
334
|
}
|
|
320
335
|
this.wire(dialog);
|
|
@@ -323,9 +338,7 @@ export class LtDialog extends HostElement {
|
|
|
323
338
|
this.dialogElement?.removeEventListener("close", this.handleClose);
|
|
324
339
|
this.dialogElement = dialog;
|
|
325
340
|
dialog.addEventListener("close", this.handleClose);
|
|
326
|
-
this.
|
|
327
|
-
this.openObserver = new MutationObserver(() => this.repairOpen());
|
|
328
|
-
this.openObserver.observe(dialog, { attributeFilter: ["open"] });
|
|
341
|
+
this.openWatch.start(dialog);
|
|
329
342
|
}
|
|
330
343
|
this.repairOpen();
|
|
331
344
|
/*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lt-dialog.js","sourceRoot":"","sources":["../../../../src/components/frame/dialog/lt-dialog.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EACR,aAAa,EACb,WAAW,EACX,kBAAkB,EAClB,iBAAiB,EACjB,OAAO,EACP,OAAO,EACP,QAAQ,EACR,eAAe,
|
|
1
|
+
{"version":3,"file":"lt-dialog.js","sourceRoot":"","sources":["../../../../src/components/frame/dialog/lt-dialog.ts"],"names":[],"mappings":"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"}
|
|
@@ -27,14 +27,17 @@ export declare class LtErrorSummary extends HostElement {
|
|
|
27
27
|
private focusAttempted;
|
|
28
28
|
/** Where focus was when `hidden` last changed, until the deferred round has run. */
|
|
29
29
|
private focusBefore;
|
|
30
|
-
private observer?;
|
|
31
30
|
/**
|
|
32
|
-
* The `aria-labelledby` the component wrote on the box,
|
|
33
|
-
*
|
|
34
|
-
* heading, so a patch that replaces the heading does not leave the name
|
|
35
|
-
* pointing at an id that is gone.
|
|
31
|
+
* The `aria-labelledby` the component wrote on the box, through
|
|
32
|
+
* `nameFromHeading()`.
|
|
36
33
|
*/
|
|
37
|
-
private
|
|
34
|
+
private readonly own;
|
|
35
|
+
/**
|
|
36
|
+
* An id only matters on the heading, which the name points at, and a name
|
|
37
|
+
* only on the box. The same attributes on a link or a field inside the box
|
|
38
|
+
* are not ours to follow.
|
|
39
|
+
*/
|
|
40
|
+
private readonly watch;
|
|
38
41
|
connectedCallback(): void;
|
|
39
42
|
attributeChangedCallback(): void;
|
|
40
43
|
/** Takes focus off the box, or off a link in it. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lt-error-summary.d.ts","sourceRoot":"","sources":["../../../../src/components/frame/error-summary/lt-error-summary.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,WAAW,
|
|
1
|
+
{"version":3,"file":"lt-error-summary.d.ts","sourceRoot":"","sources":["../../../../src/components/frame/error-summary/lt-error-summary.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,WAAW,EAOZ,MAAM,uBAAuB,CAAA;AAK9B,eAAO,MAAM,oBAAoB,EAAG,kBAA2B,CAAA;AAE/D;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB;;;CAGzB,CAAA;AA4CV,qBAAa,cAAe,SAAQ,WAAW;IAC7C,MAAM,CAAC,kBAAkB,wCAAwC;IAEjE,OAAO,CAAC,UAAU,CAAQ;IAC1B;;;;;;;;;;OAUG;IACH,OAAO,CAAC,cAAc,CAAQ;IAC9B,oFAAoF;IACpF,OAAO,CAAC,WAAW,CAA4B;IAC/C;;;OAGG;IACH,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAc;IAClC;;;;OAIG;IACH,OAAO,CAAC,QAAQ,CAAC,KAAK,CA2BrB;IAED,iBAAiB,IAAI,IAAI;IAazB,wBAAwB,IAAI,IAAI;IAyBhC,oDAAoD;IACpD,OAAO,CAAC,UAAU;IAKlB,oBAAoB,IAAI,IAAI;IAK5B;;;;;;;;;;OAUG;IACH,OAAO,KAAK,WAAW,GAEtB;IAED;;;OAGG;IACH,OAAO,CAAC,IAAI;IAoCZ,OAAO,CAAC,IAAI;IAyGZ;;;;;;;;;;;;;;;;;;OAkBG;IACH,OAAO,CAAC,gBAAgB;IAWxB;;;;;;;OAOG;IACH,OAAO,CAAC,aAAa;IAarB,OAAO,CAAC,eAAe,CAwCtB;CACF;AAYD,wBAAgB,oBAAoB,CAClC,OAAO,GAAE,MAA6B,GACrC,IAAI,CAEN"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { addClass, defineElement, HostElement, setAttr, warnAboutMarkup, } from "../../host-element.js";
|
|
1
|
+
import { addClass, defineElement, HostElement, hasName, nameFromHeading, ownership, setAttr, warnAboutMarkup, watcher, } from "../../host-element.js";
|
|
2
2
|
import { ERROR_SUMMARY_CLASS, ERROR_SUMMARY_TITLE_CLASS, } from "./error-summary.js";
|
|
3
3
|
export const LT_ERROR_SUMMARY_TAG = "lt-error-summary";
|
|
4
4
|
/**
|
|
@@ -69,12 +69,39 @@ export class LtErrorSummary extends HostElement {
|
|
|
69
69
|
*/
|
|
70
70
|
this.focusAttempted = false;
|
|
71
71
|
/**
|
|
72
|
-
* The `aria-labelledby` the component wrote on the box,
|
|
73
|
-
*
|
|
74
|
-
* heading, so a patch that replaces the heading does not leave the name
|
|
75
|
-
* pointing at an id that is gone.
|
|
72
|
+
* The `aria-labelledby` the component wrote on the box, through
|
|
73
|
+
* `nameFromHeading()`.
|
|
76
74
|
*/
|
|
77
|
-
this.
|
|
75
|
+
this.own = ownership();
|
|
76
|
+
/**
|
|
77
|
+
* An id only matters on the heading, which the name points at, and a name
|
|
78
|
+
* only on the box. The same attributes on a link or a field inside the box
|
|
79
|
+
* are not ours to follow.
|
|
80
|
+
*/
|
|
81
|
+
this.watch = watcher((records) => {
|
|
82
|
+
const relevant = records.some((r) => {
|
|
83
|
+
if (r.attributeName === "id")
|
|
84
|
+
return r.target.matches(LT_ERROR_SUMMARY_PARTS.title);
|
|
85
|
+
if (r.attributeName === "aria-label" ||
|
|
86
|
+
r.attributeName === "aria-labelledby")
|
|
87
|
+
return r.target === this;
|
|
88
|
+
return true;
|
|
89
|
+
});
|
|
90
|
+
if (relevant)
|
|
91
|
+
this.sync();
|
|
92
|
+
}, {
|
|
93
|
+
childList: true,
|
|
94
|
+
subtree: true,
|
|
95
|
+
attributes: true,
|
|
96
|
+
attributeFilter: [
|
|
97
|
+
"class",
|
|
98
|
+
"role",
|
|
99
|
+
"tabindex",
|
|
100
|
+
"aria-labelledby",
|
|
101
|
+
"aria-label",
|
|
102
|
+
"id",
|
|
103
|
+
],
|
|
104
|
+
});
|
|
78
105
|
this.handleLinkClick = (event) => {
|
|
79
106
|
const link = event.target?.closest?.(LT_ERROR_SUMMARY_PARTS.link);
|
|
80
107
|
if (!link || !this.contains(link))
|
|
@@ -121,34 +148,7 @@ export class LtErrorSummary extends HostElement {
|
|
|
121
148
|
// does not fire in plain DOM. The attributes are the ones the component
|
|
122
149
|
// fills in itself, so a patch that removes them gets them back. Every
|
|
123
150
|
// write compares first, or the observer would trigger itself.
|
|
124
|
-
|
|
125
|
-
// name only on the box. The same attributes on a link or a field inside
|
|
126
|
-
// the box are not ours to follow.
|
|
127
|
-
this.observer = new MutationObserver((records) => {
|
|
128
|
-
const relevant = records.some((r) => {
|
|
129
|
-
if (r.attributeName === "id")
|
|
130
|
-
return r.target.matches(LT_ERROR_SUMMARY_PARTS.title);
|
|
131
|
-
if (r.attributeName === "aria-label" ||
|
|
132
|
-
r.attributeName === "aria-labelledby")
|
|
133
|
-
return r.target === this;
|
|
134
|
-
return true;
|
|
135
|
-
});
|
|
136
|
-
if (relevant)
|
|
137
|
-
this.sync();
|
|
138
|
-
});
|
|
139
|
-
this.observer.observe(this, {
|
|
140
|
-
childList: true,
|
|
141
|
-
subtree: true,
|
|
142
|
-
attributes: true,
|
|
143
|
-
attributeFilter: [
|
|
144
|
-
"class",
|
|
145
|
-
"role",
|
|
146
|
-
"tabindex",
|
|
147
|
-
"aria-labelledby",
|
|
148
|
-
"aria-label",
|
|
149
|
-
"id",
|
|
150
|
-
],
|
|
151
|
-
});
|
|
151
|
+
this.watch.start(this);
|
|
152
152
|
this.sync();
|
|
153
153
|
}
|
|
154
154
|
attributeChangedCallback() {
|
|
@@ -184,8 +184,7 @@ export class LtErrorSummary extends HostElement {
|
|
|
184
184
|
focused.blur();
|
|
185
185
|
}
|
|
186
186
|
disconnectedCallback() {
|
|
187
|
-
this.
|
|
188
|
-
this.observer = undefined;
|
|
187
|
+
this.watch.stop();
|
|
189
188
|
this.removeEventListener("click", this.handleLinkClick);
|
|
190
189
|
}
|
|
191
190
|
/**
|
|
@@ -231,29 +230,11 @@ export class LtErrorSummary extends HostElement {
|
|
|
231
230
|
* nothing, so it counts as missing.
|
|
232
231
|
* `check-accessibility-tree.ts` checks the name a screen reader gets.
|
|
233
232
|
*/
|
|
234
|
-
const
|
|
235
|
-
|
|
236
|
-
const ours = labelledBy !== null && labelledBy === this.labelledByWritten;
|
|
237
|
-
if (labelledBy !== null && !ours)
|
|
238
|
-
this.labelledByWritten = null;
|
|
239
|
-
if (title?.id && label === null && (labelledBy === null || ours)) {
|
|
240
|
-
setAttr(this, "aria-labelledby", title.id);
|
|
241
|
-
this.labelledByWritten = title.id;
|
|
242
|
-
}
|
|
243
|
-
else if (ours) {
|
|
244
|
-
// The heading is gone or lost its id, or the server named the box
|
|
245
|
-
// with `aria-label`, which `aria-labelledby` would otherwise win over.
|
|
246
|
-
this.removeAttribute("aria-labelledby");
|
|
247
|
-
this.labelledByWritten = null;
|
|
248
|
-
}
|
|
249
|
-
if (title && !title.id && label === null && labelledBy === null)
|
|
233
|
+
const name = nameFromHeading(this.own, this, this, () => title?.id || null);
|
|
234
|
+
if (name === "none" && title && !title.id)
|
|
250
235
|
warnAboutMarkup(this, "has a heading without an id and no name, so it takes focus as an alert a screen reader cannot name. Give the heading an id and the box aria-labelledby pointing at it, as lt.errorSummary({ id }) does.", () => {
|
|
251
236
|
const now = this.querySelector(LT_ERROR_SUMMARY_PARTS.title);
|
|
252
|
-
return
|
|
253
|
-
now !== null &&
|
|
254
|
-
!now.id &&
|
|
255
|
-
!this.getAttribute("aria-label")?.trim() &&
|
|
256
|
-
!this.getAttribute("aria-labelledby")?.trim());
|
|
237
|
+
return this.isConnected && now !== null && !now.id && !hasName(this);
|
|
257
238
|
});
|
|
258
239
|
}
|
|
259
240
|
sync() {
|