@lo-tek/interfaces 0.37.0 → 0.38.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 +137 -2
- package/README.md +4 -3
- package/agent/astro.md +1 -1
- package/agent/bundles.md +1 -1
- package/agent/datastar.md +48 -48
- package/agent/html.md +51 -51
- package/agent/react.md +1 -1
- package/agent/templates.md +49 -49
- package/core/lotek-core.wasm +0 -0
- package/core/lotek.wasm +0 -0
- package/dist/components/default-texts.d.ts +6 -0
- package/dist/components/default-texts.d.ts.map +1 -1
- package/dist/components/default-texts.js +6 -0
- package/dist/components/default-texts.js.map +1 -1
- package/dist/components/frame/dialog/lt-dialog.d.ts.map +1 -1
- package/dist/components/frame/dialog/lt-dialog.js +5 -2
- package/dist/components/frame/dialog/lt-dialog.js.map +1 -1
- package/dist/components/frame/error-summary/error-summary.d.ts +15 -2
- package/dist/components/frame/error-summary/error-summary.d.ts.map +1 -1
- package/dist/components/frame/error-summary/error-summary.js +33 -11
- package/dist/components/frame/error-summary/error-summary.js.map +1 -1
- package/dist/components/frame/error-summary/lt-error-summary.d.ts +11 -0
- package/dist/components/frame/error-summary/lt-error-summary.d.ts.map +1 -1
- package/dist/components/frame/error-summary/lt-error-summary.js +114 -8
- package/dist/components/frame/error-summary/lt-error-summary.js.map +1 -1
- package/dist/components/frame/field/lt-field.d.ts.map +1 -1
- package/dist/components/frame/field/lt-field.js +34 -14
- package/dist/components/frame/field/lt-field.js.map +1 -1
- package/dist/components/frame/popover/lt-popover.d.ts +6 -2
- package/dist/components/frame/popover/lt-popover.d.ts.map +1 -1
- package/dist/components/frame/popover/lt-popover.js +44 -14
- package/dist/components/frame/popover/lt-popover.js.map +1 -1
- package/dist/components/frame/session-timeout/lt-session-timeout.d.ts.map +1 -1
- package/dist/components/frame/session-timeout/lt-session-timeout.js +43 -6
- package/dist/components/frame/session-timeout/lt-session-timeout.js.map +1 -1
- package/dist/components/frame/suggestion/lt-suggestion.d.ts +8 -2
- package/dist/components/frame/suggestion/lt-suggestion.d.ts.map +1 -1
- package/dist/components/frame/suggestion/lt-suggestion.js +56 -37
- package/dist/components/frame/suggestion/lt-suggestion.js.map +1 -1
- package/dist/components/frame/tabs/lt-tabs.d.ts +32 -10
- package/dist/components/frame/tabs/lt-tabs.d.ts.map +1 -1
- package/dist/components/frame/tabs/lt-tabs.js +85 -21
- package/dist/components/frame/tabs/lt-tabs.js.map +1 -1
- package/dist/components/host-element.d.ts +49 -0
- package/dist/components/host-element.d.ts.map +1 -1
- package/dist/components/host-element.js +74 -0
- package/dist/components/host-element.js.map +1 -1
- package/dist/components/standalone/connection-status/connection-status.d.ts +5 -1
- package/dist/components/standalone/connection-status/connection-status.d.ts.map +1 -1
- package/dist/components/standalone/connection-status/connection-status.js +5 -1
- package/dist/components/standalone/connection-status/connection-status.js.map +1 -1
- package/dist/components/standalone/connection-status/lt-connection-status.d.ts +11 -6
- package/dist/components/standalone/connection-status/lt-connection-status.d.ts.map +1 -1
- package/dist/components/standalone/connection-status/lt-connection-status.js +34 -10
- package/dist/components/standalone/connection-status/lt-connection-status.js.map +1 -1
- package/dist/diagnostics/core.d.ts +34 -0
- package/dist/diagnostics/core.d.ts.map +1 -1
- package/dist/diagnostics/core.js +14 -2
- package/dist/diagnostics/core.js.map +1 -1
- package/dist/lotek.css +1 -1
- package/dist/lt.d.ts +1 -1
- package/dist/react.d.ts +2 -0
- package/dist/react.d.ts.map +1 -1
- package/dist/vocabulary/classes.d.ts.map +1 -1
- package/dist/vocabulary/classes.js +34 -0
- package/dist/vocabulary/classes.js.map +1 -1
- package/dist/vocabulary/elements.d.ts.map +1 -1
- package/dist/vocabulary/elements.js +87 -7
- package/dist/vocabulary/elements.js.map +1 -1
- package/dist/vocabulary/types.d.ts +54 -0
- package/dist/vocabulary/types.d.ts.map +1 -1
- package/live-templates.xml +3 -2
- package/manifest/manifest.json +133 -8
- package/manifest/manifest.schema.json +73 -0
- package/package.json +2 -1
- package/src/components/default-texts.ts +7 -0
- package/src/components/frame/dialog/lt-dialog.ts +5 -2
- package/src/components/frame/error-summary/error-summary.ts +45 -11
- package/src/components/frame/error-summary/lt-error-summary.ts +121 -7
- package/src/components/frame/field/lt-field.ts +65 -28
- package/src/components/frame/popover/lt-popover.ts +43 -12
- package/src/components/frame/session-timeout/lt-session-timeout.ts +40 -6
- package/src/components/frame/suggestion/lt-suggestion.ts +57 -36
- package/src/components/frame/tabs/lt-tabs.ts +114 -38
- package/src/components/host-element.ts +93 -0
- package/src/components/standalone/connection-status/connection-status.ts +7 -1
- package/src/components/standalone/connection-status/lt-connection-status.ts +36 -10
- package/src/diagnostics/core.ts +19 -2
- package/src/vocabulary/classes.ts +34 -0
- package/src/vocabulary/elements.ts +87 -7
- package/src/vocabulary/types.ts +50 -0
- package/web-types.json +1 -1
package/agent/templates.md
CHANGED
|
@@ -14,7 +14,7 @@ the attributes in a template, and no type stops `data-variant="outlined"`.
|
|
|
14
14
|
That is why item 5 applies more strictly here than anywhere else: the check is
|
|
15
15
|
the only thing that reads your markup.
|
|
16
16
|
|
|
17
|
-
This is @lo-tek/interfaces 0.
|
|
17
|
+
This is @lo-tek/interfaces 0.38.0. The file is generated by the package and
|
|
18
18
|
follows its version, so it can never say anything other than the code next to
|
|
19
19
|
it.
|
|
20
20
|
|
|
@@ -48,7 +48,7 @@ it.
|
|
|
48
48
|
One link in the page template, with all the components:
|
|
49
49
|
|
|
50
50
|
```html
|
|
51
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
51
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/dist/lotek.css">
|
|
52
52
|
```
|
|
53
53
|
|
|
54
54
|
Or from your own server, if you copy the file into your static assets.
|
|
@@ -74,41 +74,41 @@ The default variant has no attribute.
|
|
|
74
74
|
|
|
75
75
|
| Class | Stylesheet | Attributes |
|
|
76
76
|
| --- | --- | --- |
|
|
77
|
-
| `lt-accordion`<br>`lt-accordion__content` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
78
|
-
| `lt-alert`<br>`lt-alert__title` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
79
|
-
| `lt-avatar`<br>`lt-avatar-stack` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
80
|
-
| `lt-badge` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
81
|
-
| `lt-breadcrumbs` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
82
|
-
| `lt-button` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
83
|
-
| `lt-card`<br>`lt-card__title` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
84
|
-
| `lt-checkbox`<br>`lt-checkbox-row` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
85
|
-
| `lt-divider` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
86
|
-
| `lt-error-text` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
87
|
-
| `lt-fieldset`<br>`lt-legend` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
88
|
-
| `lt-file-upload`<br>`lt-file-upload-list` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
89
|
-
| `lt-heading` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
90
|
-
| `lt-help-text` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
91
|
-
| `lt-icon` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
92
|
-
| `lt-input` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
93
|
-
| `lt-label` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
94
|
-
| `lt-link` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
95
|
-
| `lt-list` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
96
|
-
| `lt-pagination`<br>`lt-pagination__gap` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
97
|
-
| `lt-paragraph` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
98
|
-
| `lt-progress` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
99
|
-
| `lt-radio`<br>`lt-radio-row` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
100
|
-
| `lt-search`<br>`lt-search-row` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
101
|
-
| `lt-select` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
102
|
-
| `lt-skeleton` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
103
|
-
| `lt-skip-link` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
104
|
-
| `lt-spinner` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
105
|
-
| `lt-sr-only` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
106
|
-
| `lt-switch`<br>`lt-switch-row` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
107
|
-
| `lt-table`<br>`lt-table__sort`<br>`lt-table-scroll` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
108
|
-
| `lt-tag` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
109
|
-
| `lt-textarea` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
110
|
-
| `lt-toggle-group`<br>`lt-toggle-group__option` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
111
|
-
| `lt-tooltip`<br>`lt-tooltip__bubble` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
77
|
+
| `lt-accordion`<br>`lt-accordion__content` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/accordion/accordion.css` | `data-variant`: plain |
|
|
78
|
+
| `lt-alert`<br>`lt-alert__title` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/alert/alert.css` | `data-color`: info, success, warning, danger |
|
|
79
|
+
| `lt-avatar`<br>`lt-avatar-stack` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/avatar/avatar.css` | `data-variant`: square<br>`data-size`: small, large |
|
|
80
|
+
| `lt-badge` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/badge/badge.css` | `data-color`: success, warning, danger, neutral |
|
|
81
|
+
| `lt-breadcrumbs` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/breadcrumbs/breadcrumbs.css` | none |
|
|
82
|
+
| `lt-button` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/button/button.css` | `data-variant`: secondary, ghost, danger |
|
|
83
|
+
| `lt-card`<br>`lt-card__title` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/card/card.css` | `data-variant`: filled<br>`data-interactive` (flag) |
|
|
84
|
+
| `lt-checkbox`<br>`lt-checkbox-row` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/checkbox/checkbox.css` | `data-state`: invalid, success |
|
|
85
|
+
| `lt-divider` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/divider/divider.css` | `data-variant`: subtle, strong |
|
|
86
|
+
| `lt-error-text` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/error-text/error-text.css` | `data-variant`: warning |
|
|
87
|
+
| `lt-fieldset`<br>`lt-legend` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/fieldset/fieldset.css` | `data-state`: invalid, success<br>`data-required`: symbol, text<br>`data-optional` (flag) |
|
|
88
|
+
| `lt-file-upload`<br>`lt-file-upload-list` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/file-upload/file-upload.css` | `data-state`: invalid, success |
|
|
89
|
+
| `lt-heading` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/heading/heading.css` | `data-size`: xs, s, m, xl, mega |
|
|
90
|
+
| `lt-help-text` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/help-text/help-text.css` | `data-variant`: strong, success, warning |
|
|
91
|
+
| `lt-icon` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/icon/icon.css` | none |
|
|
92
|
+
| `lt-input` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/input/input.css` | `data-state`: invalid, success<br>`data-variant`: date, datetime-local, time |
|
|
93
|
+
| `lt-label` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/label/label.css` | `data-required`: symbol, text<br>`data-optional` (flag) |
|
|
94
|
+
| `lt-link` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/link/link.css` | none |
|
|
95
|
+
| `lt-list` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/list/list.css` | `data-variant`: plain, divided |
|
|
96
|
+
| `lt-pagination`<br>`lt-pagination__gap` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/pagination/pagination.css` | none |
|
|
97
|
+
| `lt-paragraph` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/paragraph/paragraph.css` | `data-variant`: lead<br>`data-size`: small, large |
|
|
98
|
+
| `lt-progress` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/progress/progress.css` | `data-color`: success, warning, danger |
|
|
99
|
+
| `lt-radio`<br>`lt-radio-row` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/radio/radio.css` | `data-state`: invalid, success |
|
|
100
|
+
| `lt-search`<br>`lt-search-row` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/search/search.css` | `data-state`: invalid, success |
|
|
101
|
+
| `lt-select` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/select/select.css` | `data-state`: invalid, success<br>`data-picker`: styled |
|
|
102
|
+
| `lt-skeleton` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/skeleton/skeleton.css` | `data-variant`: text, circle |
|
|
103
|
+
| `lt-skip-link` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/skip-link/skip-link.css` | none |
|
|
104
|
+
| `lt-spinner` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/spinner/spinner.css` | `data-size`: small, large |
|
|
105
|
+
| `lt-sr-only` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/sr-only/sr-only.css` | none |
|
|
106
|
+
| `lt-switch`<br>`lt-switch-row` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/switch/switch.css` | none |
|
|
107
|
+
| `lt-table`<br>`lt-table__sort`<br>`lt-table-scroll` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/table/table.css` | `data-variant`: striped<br>`data-hoverable` (flag) |
|
|
108
|
+
| `lt-tag` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/tag/tag.css` | `data-variant`: filled<br>`data-selectable` (flag) |
|
|
109
|
+
| `lt-textarea` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/textarea/textarea.css` | `data-state`: invalid, success |
|
|
110
|
+
| `lt-toggle-group`<br>`lt-toggle-group__option` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/toggle-group/toggle-group.css` | none |
|
|
111
|
+
| `lt-tooltip`<br>`lt-tooltip__bubble` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/tooltip/tooltip.css` | none |
|
|
112
112
|
|
|
113
113
|
There is also `lt-theme-control`, a class on a radio button that lets the user
|
|
114
114
|
choose a theme. It is in `tokens.css`, and is described under Tokens.
|
|
@@ -187,7 +187,7 @@ root element:
|
|
|
187
187
|
Below the root element the browser then ignores the host's CSS without a
|
|
188
188
|
layer, unless a rule of the host's wins on specificity as described below, and
|
|
189
189
|
LO-TEK's layer applies again. The rule is in `lotek.css` and in
|
|
190
|
-
`https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
190
|
+
`https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/tokens/boundary.css`.
|
|
191
191
|
Fonts and other inherited properties still come from the host, and the
|
|
192
192
|
`--lt-*` variables work. Three things follow from it:
|
|
193
193
|
|
|
@@ -281,15 +281,15 @@ Three rules apply to all of them:
|
|
|
281
281
|
|
|
282
282
|
| Element | Category | Stylesheet | Registration | Attributes | Events | Classes inside |
|
|
283
283
|
| --- | --- | --- | --- | --- | --- | --- |
|
|
284
|
-
| `<lt-field>` | frame | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
285
|
-
| `<lt-tabs>` | frame | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
286
|
-
| `<lt-error-summary>` | frame | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
287
|
-
| `<lt-popover>` | frame | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
288
|
-
| `<lt-suggestion>` | frame | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
289
|
-
| `<lt-dialog>` | frame | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
290
|
-
| `<lt-toast>` | standalone | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
291
|
-
| `<lt-session-timeout>` | frame | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
292
|
-
| `<lt-connection-status>` | standalone | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
284
|
+
| `<lt-field>` | frame | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/frame/field/field.css` | `defineLtField()` from `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/dist/components/frame/field/lt-field.js` | `disabled` (flag)<br>`optional` (flag)<br>`described-by` (text) | none | none |
|
|
285
|
+
| `<lt-tabs>` | frame | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/frame/tabs/tabs.css` | `defineLtTabs()` from `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.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` |
|
|
286
|
+
| `<lt-error-summary>` | frame | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/frame/error-summary/error-summary.css` | `defineLtErrorSummary()` from `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.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` |
|
|
287
|
+
| `<lt-popover>` | frame | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/frame/popover/popover.css` | `defineLtPopover()` from `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.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` |
|
|
288
|
+
| `<lt-suggestion>` | frame | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/frame/suggestion/suggestion.css` | `defineLtSuggestion()` from `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.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` |
|
|
289
|
+
| `<lt-dialog>` | frame | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/frame/dialog/dialog.css` | `defineLtDialog()` from `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.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` |
|
|
290
|
+
| `<lt-toast>` | standalone | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/standalone/toast/toast.css` | `defineLtToast()` from `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.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` |
|
|
291
|
+
| `<lt-session-timeout>` | frame | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/frame/session-timeout/session-timeout.css` | `defineLtSessionTimeout()` from `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.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` |
|
|
292
|
+
| `<lt-connection-status>` | standalone | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/standalone/connection-status/connection-status.css` | `defineLtConnectionStatus()` from `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.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` |
|
|
293
293
|
|
|
294
294
|
None of them uses shadow DOM. The content is in plain DOM, so `querySelector`,
|
|
295
295
|
`FormData` and ordinary CSS work straight into it.
|
|
@@ -326,7 +326,7 @@ The registration, once in the page template:
|
|
|
326
326
|
```html
|
|
327
327
|
<script type="module">
|
|
328
328
|
import { defineLtField } from
|
|
329
|
-
"https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.
|
|
329
|
+
"https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/dist/components/frame/field/lt-field.js"
|
|
330
330
|
|
|
331
331
|
defineLtField()
|
|
332
332
|
</script>
|
|
@@ -433,7 +433,7 @@ The check is also in the editor as you type. The VS Code extension "LO-TEK for
|
|
|
433
433
|
VS Code" gives completion, explanations, error messages and quick fixes in
|
|
434
434
|
sixteen template languages. WebStorm and IntelliJ IDEA Ultimate read
|
|
435
435
|
`web-types.json` from the package without any extension, and the plugin
|
|
436
|
-
"LO-TEK
|
|
436
|
+
"LO-TEK Interfaces" from JetBrains Marketplace adds the error messages and
|
|
437
437
|
completion in HTML in a string marked with `@Language("HTML")` or
|
|
438
438
|
`// language=HTML`.
|
|
439
439
|
|
package/core/lotek-core.wasm
CHANGED
|
Binary file
|
package/core/lotek.wasm
CHANGED
|
Binary file
|
|
@@ -16,6 +16,12 @@
|
|
|
16
16
|
* read from an `--lt-` variable with the text as the fallback, and
|
|
17
17
|
* `check-texts.ts` requires that.
|
|
18
18
|
*/
|
|
19
|
+
/**
|
|
20
|
+
* The language the texts are in. `lotek check` warns about a component that
|
|
21
|
+
* shows one of them on a page in another language, without the attribute or
|
|
22
|
+
* CSS variable that replaces it.
|
|
23
|
+
*/
|
|
24
|
+
export declare const DEFAULT_LANGUAGE = "en";
|
|
19
25
|
export declare const DEFAULT_TEXTS: {
|
|
20
26
|
/** `aria-label` on the `<lt-toast>` region. Replaced with `label`. */
|
|
21
27
|
readonly toastRegion: "Notifications";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"default-texts.d.ts","sourceRoot":"","sources":["../../src/components/default-texts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,aAAa;IACxB,sEAAsE;;IAEtE,qEAAqE;;IAErE,0FAA0F;;IAE1F,gFAAgF;;IAEhF,wFAAwF;;IAExF,iEAAiE;;IAEjE,mFAAmF;;CAE3E,CAAA"}
|
|
1
|
+
{"version":3,"file":"default-texts.d.ts","sourceRoot":"","sources":["../../src/components/default-texts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,OAAO,CAAA;AAEpC,eAAO,MAAM,aAAa;IACxB,sEAAsE;;IAEtE,qEAAqE;;IAErE,0FAA0F;;IAE1F,gFAAgF;;IAEhF,wFAAwF;;IAExF,iEAAiE;;IAEjE,mFAAmF;;CAE3E,CAAA"}
|
|
@@ -16,6 +16,12 @@
|
|
|
16
16
|
* read from an `--lt-` variable with the text as the fallback, and
|
|
17
17
|
* `check-texts.ts` requires that.
|
|
18
18
|
*/
|
|
19
|
+
/**
|
|
20
|
+
* The language the texts are in. `lotek check` warns about a component that
|
|
21
|
+
* shows one of them on a page in another language, without the attribute or
|
|
22
|
+
* CSS variable that replaces it.
|
|
23
|
+
*/
|
|
24
|
+
export const DEFAULT_LANGUAGE = "en";
|
|
19
25
|
export const DEFAULT_TEXTS = {
|
|
20
26
|
/** `aria-label` on the `<lt-toast>` region. Replaced with `label`. */
|
|
21
27
|
toastRegion: "Notifications",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"default-texts.js","sourceRoot":"","sources":["../../src/components/default-texts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,sEAAsE;IACtE,WAAW,EAAE,eAAe;IAC5B,qEAAqE;IACrE,UAAU,EAAE,eAAe;IAC3B,0FAA0F;IAC1F,iBAAiB,EAAE,kDAAkD;IACrE,gFAAgF;IAChF,gBAAgB,EAAE,sBAAsB;IACxC,wFAAwF;IACxF,cAAc,EAAE,YAAY;IAC5B,iEAAiE;IACjE,aAAa,EAAE,WAAW;IAC1B,mFAAmF;IACnF,eAAe,EAAE,aAAa;CACtB,CAAA"}
|
|
1
|
+
{"version":3,"file":"default-texts.js","sourceRoot":"","sources":["../../src/components/default-texts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH;;;;GAIG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,CAAA;AAEpC,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,sEAAsE;IACtE,WAAW,EAAE,eAAe;IAC5B,qEAAqE;IACrE,UAAU,EAAE,eAAe;IAC3B,0FAA0F;IAC1F,iBAAiB,EAAE,kDAAkD;IACrE,gFAAgF;IAChF,gBAAgB,EAAE,sBAAsB;IACxC,wFAAwF;IACxF,cAAc,EAAE,YAAY;IAC5B,iEAAiE;IACjE,aAAa,EAAE,WAAW;IAC1B,mFAAmF;IACnF,eAAe,EAAE,aAAa;CACtB,CAAA"}
|
|
@@ -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,EAOZ,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,CAAkB;IACnC;;;;;;;;;OASG;IACH,OAAO,CAAC,YAAY,CAAC,CAAkB;IACvC,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;
|
|
1
|
+
{"version":3,"file":"lt-dialog.d.ts","sourceRoot":"","sources":["../../../../src/components/frame/dialog/lt-dialog.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,WAAW,EAOZ,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,CAAkB;IACnC;;;;;;;;;OASG;IACH,OAAO,CAAC,YAAY,CAAC,CAAkB;IACvC,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;IA4CzB,oBAAoB,IAAI,IAAI;IAS5B,wBAAwB,IAAI,IAAI;IAIhC;;;;;OAKG;IACH,OAAO,KAAK,MAAM,GAEjB;IAED,gFAAgF;IAChF,OAAO,CAAC,OAAO,CAAC,CAAQ;IAExB,mEAAmE;IACnE,OAAO,CAAC,MAAM;IAKd;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,SAAS;IAYjB;;;;OAIG;IACH,OAAO,CAAC,QAAQ;IAShB;;;;;;;;OAQG;IACH,OAAO,CAAC,IAAI;IAwCZ,OAAO,CAAC,MAAM;IAed;;;;;;;;;;;;;OAaG;IACH,OAAO,CAAC,UAAU;IA4BlB,OAAO,CAAC,WAAW,CAYlB;IAED,OAAO,CAAC,IAAI;CAsJb;AAED,wBAAgB,cAAc,CAAC,OAAO,GAAE,MAAsB,GAAG,IAAI,CAEpE"}
|
|
@@ -129,7 +129,9 @@ export class LtDialog extends HostElement {
|
|
|
129
129
|
childList: true,
|
|
130
130
|
subtree: true,
|
|
131
131
|
attributes: true,
|
|
132
|
-
|
|
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"],
|
|
133
135
|
});
|
|
134
136
|
this.sync();
|
|
135
137
|
}
|
|
@@ -235,7 +237,8 @@ export class LtDialog extends HostElement {
|
|
|
235
237
|
setAttr(dialog, "aria-labelledby", title.id);
|
|
236
238
|
}
|
|
237
239
|
notify(open, returnValue = "") {
|
|
238
|
-
|
|
240
|
+
// A dialog starts closed: one that never opened reported a close.
|
|
241
|
+
if (open === (this.lastNotified ?? false))
|
|
239
242
|
return;
|
|
240
243
|
this.lastNotified = open;
|
|
241
244
|
this.dispatchEvent(new CustomEvent("dialog-toggle", {
|
|
@@ -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,GAChB,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EACL,iBAAiB,EACjB,YAAY,EACZ,kBAAkB,GACnB,MAAM,aAAa,CAAA;AAEpB,MAAM,CAAC,MAAM,aAAa,GAAG,WAAoB,CAAA;AAEjD;;;;GAIG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,MAAM,EAAE,iBAAiB;IACzB,KAAK,EAAE,wBAAwB;IAC/B,IAAI,EAAE,IAAI,iBAAiB,EAAE;CACrB,CAAA;AAEV;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AACH;;;;;;;;;GASG;AACH,MAAM,cAAc,GAAG,IAAI,OAAO,EAAqB,CAAA;AAEvD,MAAM,OAAO,QAAS,SAAQ,WAAW;IAAzC;;
|
|
1
|
+
{"version":3,"file":"lt-dialog.js","sourceRoot":"","sources":["../../../../src/components/frame/dialog/lt-dialog.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,6 +5,13 @@ export type ErrorSummaryOptions = {
|
|
|
5
5
|
count?: number;
|
|
6
6
|
/** The id of the box, so the form can move focus here after submission. */
|
|
7
7
|
id?: string;
|
|
8
|
+
/**
|
|
9
|
+
* The id of the heading. The box takes its name from it with
|
|
10
|
+
* `aria-labelledby`. Default: the box's `id` with `-title`, so the markup
|
|
11
|
+
* carries the wiring whenever the box has an id. An empty one counts as
|
|
12
|
+
* none; one with whitespace throws.
|
|
13
|
+
*/
|
|
14
|
+
titleId?: string;
|
|
8
15
|
};
|
|
9
16
|
export type ErrorSummaryAttributes = {
|
|
10
17
|
host: {
|
|
@@ -13,9 +20,11 @@ export type ErrorSummaryAttributes = {
|
|
|
13
20
|
tabindex: "-1";
|
|
14
21
|
id?: string;
|
|
15
22
|
hidden?: true;
|
|
23
|
+
"aria-labelledby"?: string;
|
|
16
24
|
};
|
|
17
25
|
title: {
|
|
18
26
|
class: typeof ERROR_SUMMARY_TITLE_CLASS;
|
|
27
|
+
id?: string;
|
|
19
28
|
};
|
|
20
29
|
};
|
|
21
30
|
/**
|
|
@@ -27,7 +36,11 @@ export type ErrorSummaryAttributes = {
|
|
|
27
36
|
* every morph in Datastar.
|
|
28
37
|
*
|
|
29
38
|
* ```ts
|
|
30
|
-
* const summary = lt.errorSummary({
|
|
39
|
+
* const summary = lt.errorSummary({
|
|
40
|
+
* count: errors.length,
|
|
41
|
+
* id: "errors",
|
|
42
|
+
* titleId: "errors-title",
|
|
43
|
+
* })
|
|
31
44
|
* ```
|
|
32
45
|
* ```html
|
|
33
46
|
* <lt-error-summary {...summary.host}>
|
|
@@ -36,5 +49,5 @@ export type ErrorSummaryAttributes = {
|
|
|
36
49
|
* </lt-error-summary>
|
|
37
50
|
* ```
|
|
38
51
|
*/
|
|
39
|
-
export declare const errorSummary: ({ count, id, }?: ErrorSummaryOptions) => ErrorSummaryAttributes;
|
|
52
|
+
export declare const errorSummary: ({ count, id, titleId: givenTitleId, }?: ErrorSummaryOptions) => ErrorSummaryAttributes;
|
|
40
53
|
//# sourceMappingURL=error-summary.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error-summary.d.ts","sourceRoot":"","sources":["../../../../src/components/frame/error-summary/error-summary.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,mBAAmB,EAAG,kBAA2B,CAAA;AAC9D,eAAO,MAAM,yBAAyB,EAAG,yBAAkC,CAAA;AAE3E,MAAM,MAAM,mBAAmB,GAAG;IAChC,iFAAiF;IACjF,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,2EAA2E;IAC3E,EAAE,CAAC,EAAE,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"error-summary.d.ts","sourceRoot":"","sources":["../../../../src/components/frame/error-summary/error-summary.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,mBAAmB,EAAG,kBAA2B,CAAA;AAC9D,eAAO,MAAM,yBAAyB,EAAG,yBAAkC,CAAA;AAE3E,MAAM,MAAM,mBAAmB,GAAG;IAChC,iFAAiF;IACjF,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,2EAA2E;IAC3E,EAAE,CAAC,EAAE,MAAM,CAAA;IACX;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,sBAAsB,GAAG;IACnC,IAAI,EAAE;QACJ,KAAK,EAAE,OAAO,mBAAmB,CAAA;QACjC,IAAI,EAAE,OAAO,CAAA;QACb,QAAQ,EAAE,IAAI,CAAA;QACd,EAAE,CAAC,EAAE,MAAM,CAAA;QACX,MAAM,CAAC,EAAE,IAAI,CAAA;QACb,iBAAiB,CAAC,EAAE,MAAM,CAAA;KAC3B,CAAA;IACD,KAAK,EAAE;QACL,KAAK,EAAE,OAAO,yBAAyB,CAAA;QACvC,EAAE,CAAC,EAAE,MAAM,CAAA;KACZ,CAAA;CACF,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,YAAY,GAAI,wCAI1B,mBAAwB,KAAG,sBA6B7B,CAAA"}
|
|
@@ -10,7 +10,11 @@ export const ERROR_SUMMARY_TITLE_CLASS = "lt-error-summary__title";
|
|
|
10
10
|
* every morph in Datastar.
|
|
11
11
|
*
|
|
12
12
|
* ```ts
|
|
13
|
-
* const summary = lt.errorSummary({
|
|
13
|
+
* const summary = lt.errorSummary({
|
|
14
|
+
* count: errors.length,
|
|
15
|
+
* id: "errors",
|
|
16
|
+
* titleId: "errors-title",
|
|
17
|
+
* })
|
|
14
18
|
* ```
|
|
15
19
|
* ```html
|
|
16
20
|
* <lt-error-summary {...summary.host}>
|
|
@@ -19,14 +23,32 @@ export const ERROR_SUMMARY_TITLE_CLASS = "lt-error-summary__title";
|
|
|
19
23
|
* </lt-error-summary>
|
|
20
24
|
* ```
|
|
21
25
|
*/
|
|
22
|
-
export const errorSummary = ({ count = 0, id, } = {}) =>
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
26
|
+
export const errorSummary = ({ count = 0, id, titleId: givenTitleId, } = {}) => {
|
|
27
|
+
/*
|
|
28
|
+
* The heading's id is written here, by whoever renders, never by the web
|
|
29
|
+
* component: Datastar and idiomorph replace an element whose id the server
|
|
30
|
+
* did not send, so an id from the component gave the heading a new one on
|
|
31
|
+
* every patch. An empty one names nothing.
|
|
32
|
+
*/
|
|
33
|
+
const titleId = givenTitleId?.trim()
|
|
34
|
+
? givenTitleId
|
|
35
|
+
: id?.trim()
|
|
36
|
+
? `${id}-title`
|
|
37
|
+
: undefined;
|
|
38
|
+
// `aria-labelledby` splits on whitespace, so the box would point at two
|
|
39
|
+
// ids, neither of them the heading's.
|
|
40
|
+
if (titleId !== undefined && /\s/.test(titleId))
|
|
41
|
+
throw new Error(`lt.errorSummary(): the titleId "${titleId}" contains whitespace. aria-labelledby splits on whitespace, so the box would point at ids that are not the heading's.`);
|
|
42
|
+
return {
|
|
43
|
+
host: attributes({
|
|
44
|
+
class: ERROR_SUMMARY_CLASS,
|
|
45
|
+
role: "alert",
|
|
46
|
+
tabindex: "-1",
|
|
47
|
+
id,
|
|
48
|
+
hidden: count === 0 ? true : undefined,
|
|
49
|
+
"aria-labelledby": titleId,
|
|
50
|
+
}),
|
|
51
|
+
title: attributes({ class: ERROR_SUMMARY_TITLE_CLASS, id: titleId }),
|
|
52
|
+
};
|
|
53
|
+
};
|
|
32
54
|
//# sourceMappingURL=error-summary.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error-summary.js","sourceRoot":"","sources":["../../../../src/components/frame/error-summary/error-summary.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAEhD,MAAM,CAAC,MAAM,mBAAmB,GAAG,kBAA2B,CAAA;AAC9D,MAAM,CAAC,MAAM,yBAAyB,GAAG,yBAAkC,CAAA;
|
|
1
|
+
{"version":3,"file":"error-summary.js","sourceRoot":"","sources":["../../../../src/components/frame/error-summary/error-summary.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAEhD,MAAM,CAAC,MAAM,mBAAmB,GAAG,kBAA2B,CAAA;AAC9D,MAAM,CAAC,MAAM,yBAAyB,GAAG,yBAAkC,CAAA;AA+B3E;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,EAC3B,KAAK,GAAG,CAAC,EACT,EAAE,EACF,OAAO,EAAE,YAAY,MACE,EAAE,EAA0B,EAAE;IACrD;;;;;OAKG;IACH,MAAM,OAAO,GAAG,YAAY,EAAE,IAAI,EAAE;QAClC,CAAC,CAAC,YAAY;QACd,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE;YACV,CAAC,CAAC,GAAG,EAAE,QAAQ;YACf,CAAC,CAAC,SAAS,CAAA;IACf,wEAAwE;IACxE,sCAAsC;IACtC,IAAI,OAAO,KAAK,SAAS,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC;QAC7C,MAAM,IAAI,KAAK,CACb,mCAAmC,OAAO,wHAAwH,CACnK,CAAA;IACH,OAAO;QACL,IAAI,EAAE,UAAU,CAAC;YACf,KAAK,EAAE,mBAAmB;YAC1B,IAAI,EAAE,OAAgB;YACtB,QAAQ,EAAE,IAAa;YACvB,EAAE;YACF,MAAM,EAAE,KAAK,KAAK,CAAC,CAAC,CAAC,CAAE,IAAc,CAAC,CAAC,CAAC,SAAS;YACjD,iBAAiB,EAAE,OAAO;SAC3B,CAAC;QACF,KAAK,EAAE,UAAU,CAAC,EAAE,KAAK,EAAE,yBAAyB,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC;KACrE,CAAA;AACH,CAAC,CAAA"}
|
|
@@ -25,9 +25,20 @@ export declare class LtErrorSummary extends HostElement {
|
|
|
25
25
|
* live validation patched the list.
|
|
26
26
|
*/
|
|
27
27
|
private focusAttempted;
|
|
28
|
+
/** Where focus was when `hidden` last changed, until the deferred round has run. */
|
|
29
|
+
private focusBefore;
|
|
28
30
|
private observer?;
|
|
31
|
+
/**
|
|
32
|
+
* The `aria-labelledby` the component wrote on the box, or null. Another
|
|
33
|
+
* value there is the server's, and stays; the component's own follows the
|
|
34
|
+
* heading, so a patch that replaces the heading does not leave the name
|
|
35
|
+
* pointing at an id that is gone.
|
|
36
|
+
*/
|
|
37
|
+
private labelledByWritten;
|
|
29
38
|
connectedCallback(): void;
|
|
30
39
|
attributeChangedCallback(): void;
|
|
40
|
+
/** Takes focus off the box, or off a link in it. */
|
|
41
|
+
private blurInside;
|
|
31
42
|
disconnectedCallback(): void;
|
|
32
43
|
/**
|
|
33
44
|
* Whether the box takes focus when it becomes visible. Default: yes.
|
|
@@ -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,EAGZ,MAAM,uBAAuB,CAAA;AAK9B,eAAO,MAAM,oBAAoB,EAAG,kBAA2B,CAAA;AAE/D;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB;;;CAGzB,CAAA;
|
|
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,EAGZ,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,OAAO,CAAC,QAAQ,CAAC,CAAkB;IACnC;;;;;OAKG;IACH,OAAO,CAAC,iBAAiB,CAAsB;IAE/C,iBAAiB,IAAI,IAAI;IAyCzB,wBAAwB,IAAI,IAAI;IAyBhC,oDAAoD;IACpD,OAAO,CAAC,UAAU;IAKlB,oBAAoB,IAAI,IAAI;IAM5B;;;;;;;;;;OAUG;IACH,OAAO,KAAK,WAAW,GAEtB;IAED;;;OAGG;IACH,OAAO,CAAC,IAAI;IAsDZ,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"}
|
|
@@ -19,7 +19,8 @@ export const LT_ERROR_SUMMARY_PARTS = {
|
|
|
19
19
|
* class, `role="alert"` and `tabindex="-1"` on the box, and the component
|
|
20
20
|
* leaves them alone. When the markup comes from a template without
|
|
21
21
|
* JavaScript, the component fills in those three and the class on the
|
|
22
|
-
* heading, and sets them back when a patch removes them.
|
|
22
|
+
* heading, and sets them back when a patch removes them. Either way, a box
|
|
23
|
+
* without a name gets `aria-labelledby` pointing at its heading. The component
|
|
23
24
|
* creates no nodes: it used to, and then the heading disappeared on the
|
|
24
25
|
* first morph in Datastar and never came back.
|
|
25
26
|
*
|
|
@@ -67,6 +68,13 @@ export class LtErrorSummary extends HostElement {
|
|
|
67
68
|
* live validation patched the list.
|
|
68
69
|
*/
|
|
69
70
|
this.focusAttempted = false;
|
|
71
|
+
/**
|
|
72
|
+
* The `aria-labelledby` the component wrote on the box, or null. Another
|
|
73
|
+
* value there is the server's, and stays; the component's own follows the
|
|
74
|
+
* heading, so a patch that replaces the heading does not leave the name
|
|
75
|
+
* pointing at an id that is gone.
|
|
76
|
+
*/
|
|
77
|
+
this.labelledByWritten = null;
|
|
70
78
|
this.handleLinkClick = (event) => {
|
|
71
79
|
const link = event.target?.closest?.(LT_ERROR_SUMMARY_PARTS.link);
|
|
72
80
|
if (!link || !this.contains(link))
|
|
@@ -113,21 +121,67 @@ export class LtErrorSummary extends HostElement {
|
|
|
113
121
|
// does not fire in plain DOM. The attributes are the ones the component
|
|
114
122
|
// fills in itself, so a patch that removes them gets them back. Every
|
|
115
123
|
// write compares first, or the observer would trigger itself.
|
|
116
|
-
|
|
124
|
+
// An id only matters on the heading, which the name points at, and a
|
|
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
|
+
});
|
|
117
139
|
this.observer.observe(this, {
|
|
118
140
|
childList: true,
|
|
119
141
|
subtree: true,
|
|
120
142
|
attributes: true,
|
|
121
|
-
attributeFilter: [
|
|
143
|
+
attributeFilter: [
|
|
144
|
+
"class",
|
|
145
|
+
"role",
|
|
146
|
+
"tabindex",
|
|
147
|
+
"aria-labelledby",
|
|
148
|
+
"aria-label",
|
|
149
|
+
"id",
|
|
150
|
+
],
|
|
122
151
|
});
|
|
123
152
|
this.sync();
|
|
124
153
|
}
|
|
125
154
|
attributeChangedCallback() {
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
155
|
+
/*
|
|
156
|
+
* The server can send the box hidden and later only remove `hidden` on
|
|
157
|
+
* the same node. Without this, a summary that just became visible never
|
|
158
|
+
* gets focus, and that is the whole reason the component exists.
|
|
159
|
+
*
|
|
160
|
+
* A microtask later, not now. A morph sets `hidden` in its attribute
|
|
161
|
+
* pass, before it updates the children; focus moved then made the box
|
|
162
|
+
* the focused element, and idiomorph with `ignoreActiveValue` leaves the
|
|
163
|
+
* children of the focused element as they were, so the new errors never
|
|
164
|
+
* arrived. Found by the code review of PR 240.
|
|
165
|
+
*/
|
|
166
|
+
// Where focus was when the box was shown. React gives it back there
|
|
167
|
+
// after the commit, and the box takes it anyway; a script that moves it
|
|
168
|
+
// somewhere else in the same turn has decided, and the box leaves it.
|
|
169
|
+
this.focusBefore ??= document.activeElement;
|
|
170
|
+
// Hidden: let go of focus now, in the morph's attribute pass, so the
|
|
171
|
+
// morph still updates the content (see `sync()`).
|
|
172
|
+
if (this.hidden)
|
|
173
|
+
this.blurInside();
|
|
174
|
+
queueMicrotask(() => {
|
|
175
|
+
if (this.isConnected)
|
|
176
|
+
this.sync();
|
|
177
|
+
this.focusBefore = undefined;
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
/** Takes focus off the box, or off a link in it. */
|
|
181
|
+
blurInside() {
|
|
182
|
+
const focused = this.getRootNode().activeElement;
|
|
183
|
+
if (focused instanceof HTMLElement && this.contains(focused))
|
|
184
|
+
focused.blur();
|
|
131
185
|
}
|
|
132
186
|
disconnectedCallback() {
|
|
133
187
|
this.observer?.disconnect();
|
|
@@ -163,6 +217,44 @@ export class LtErrorSummary extends HostElement {
|
|
|
163
217
|
const title = this.querySelector(LT_ERROR_SUMMARY_PARTS.title);
|
|
164
218
|
if (title)
|
|
165
219
|
addClass(title, ERROR_SUMMARY_TITLE_CLASS);
|
|
220
|
+
/*
|
|
221
|
+
* The box takes focus, so it needs a name: without one a screen reader
|
|
222
|
+
* says only "alert" when the focus lands, and the heading is what says
|
|
223
|
+
* how many errors there are. The template writes the heading's id and
|
|
224
|
+
* the box's `aria-labelledby`, as it writes `for` and `id` on a field;
|
|
225
|
+
* `lt.errorSummary({ id })` writes both. The component never writes an
|
|
226
|
+
* id: Datastar and idiomorph replace an element whose id the server did
|
|
227
|
+
* not send, so an id from the component gave the heading a new one on
|
|
228
|
+
* every patch. When the heading has an id and the box no name, the
|
|
229
|
+
* component points `aria-labelledby` at it, and follows a heading a
|
|
230
|
+
* patch has replaced. A blank `aria-label` or `aria-labelledby` names
|
|
231
|
+
* nothing, so it counts as missing.
|
|
232
|
+
* `check-accessibility-tree.ts` checks the name a screen reader gets.
|
|
233
|
+
*/
|
|
234
|
+
const labelledBy = this.getAttribute("aria-labelledby")?.trim() || null;
|
|
235
|
+
const label = this.getAttribute("aria-label")?.trim() || null;
|
|
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)
|
|
250
|
+
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
|
+
const now = this.querySelector(LT_ERROR_SUMMARY_PARTS.title);
|
|
252
|
+
return (this.isConnected &&
|
|
253
|
+
now !== null &&
|
|
254
|
+
!now.id &&
|
|
255
|
+
!this.getAttribute("aria-label")?.trim() &&
|
|
256
|
+
!this.getAttribute("aria-labelledby")?.trim());
|
|
257
|
+
});
|
|
166
258
|
}
|
|
167
259
|
sync() {
|
|
168
260
|
this.wire();
|
|
@@ -180,6 +272,15 @@ export class LtErrorSummary extends HostElement {
|
|
|
180
272
|
if (this.hidden) {
|
|
181
273
|
this.hasFocused = false;
|
|
182
274
|
this.focusAttempted = false;
|
|
275
|
+
/*
|
|
276
|
+
* A hidden box gives up focus. HTML's focus fixup rule moves focus
|
|
277
|
+
* off an element that is no longer rendered; Chromium does it at
|
|
278
|
+
* once, Firefox and WebKit left it on the hidden box. idiomorph leaves
|
|
279
|
+
* the content of the focused element as it was, so the next errors
|
|
280
|
+
* the server sent never reached the box, which then showed an empty
|
|
281
|
+
* heading and list. Found by the model test.
|
|
282
|
+
*/
|
|
283
|
+
this.blurInside();
|
|
183
284
|
}
|
|
184
285
|
if (links.length === 0) {
|
|
185
286
|
// The flags are not reset by an empty list, only by `hidden` above. A
|
|
@@ -228,6 +329,11 @@ export class LtErrorSummary extends HostElement {
|
|
|
228
329
|
const nobodyTyping = !active || active === document.body;
|
|
229
330
|
if (this.focusAttempted && !nobodyTyping)
|
|
230
331
|
return;
|
|
332
|
+
const movedByScript = this.focusBefore !== undefined &&
|
|
333
|
+
active !== this.focusBefore &&
|
|
334
|
+
!nobodyTyping;
|
|
335
|
+
if (movedByScript)
|
|
336
|
+
return;
|
|
231
337
|
const root = this.getRootNode();
|
|
232
338
|
this.focusAttempted = true;
|
|
233
339
|
this.focus();
|