@lo-tek/interfaces 0.0.0-stage → 0.37.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 +3254 -0
- package/LICENSE +21 -0
- package/README.md +129 -2
- package/agent/astro.md +400 -0
- package/agent/bundles.md +429 -0
- package/agent/datastar.md +409 -0
- package/agent/html.md +388 -0
- package/agent/react.md +440 -0
- package/agent/templates.md +472 -0
- package/core/lotek-core.wasm +0 -0
- package/core/lotek.wasm +0 -0
- package/dist/cli.d.ts +12 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +14 -0
- package/dist/cli.js.map +1 -0
- package/dist/components/css/accordion/accordion.d.ts +37 -0
- package/dist/components/css/accordion/accordion.d.ts.map +1 -0
- package/dist/components/css/accordion/accordion.js +31 -0
- package/dist/components/css/accordion/accordion.js.map +1 -0
- package/dist/components/css/alert/alert.d.ts +35 -0
- package/dist/components/css/alert/alert.d.ts.map +1 -0
- package/dist/components/css/alert/alert.js +29 -0
- package/dist/components/css/alert/alert.js.map +1 -0
- package/dist/components/css/avatar/avatar.d.ts +40 -0
- package/dist/components/css/avatar/avatar.d.ts.map +1 -0
- package/dist/components/css/avatar/avatar.js +30 -0
- package/dist/components/css/avatar/avatar.js.map +1 -0
- package/dist/components/css/badge/badge.d.ts +24 -0
- package/dist/components/css/badge/badge.d.ts.map +1 -0
- package/dist/components/css/badge/badge.js +24 -0
- package/dist/components/css/badge/badge.js.map +1 -0
- package/dist/components/css/breadcrumbs/breadcrumbs.d.ts +26 -0
- package/dist/components/css/breadcrumbs/breadcrumbs.d.ts.map +1 -0
- package/dist/components/css/breadcrumbs/breadcrumbs.js +24 -0
- package/dist/components/css/breadcrumbs/breadcrumbs.js.map +1 -0
- package/dist/components/css/button/button.d.ts +26 -0
- package/dist/components/css/button/button.d.ts.map +1 -0
- package/dist/components/css/button/button.js +25 -0
- package/dist/components/css/button/button.js.map +1 -0
- package/dist/components/css/card/card.d.ts +36 -0
- package/dist/components/css/card/card.d.ts.map +1 -0
- package/dist/components/css/card/card.js +28 -0
- package/dist/components/css/card/card.js.map +1 -0
- package/dist/components/css/checkbox/checkbox.d.ts +32 -0
- package/dist/components/css/checkbox/checkbox.d.ts.map +1 -0
- package/dist/components/css/checkbox/checkbox.js +27 -0
- package/dist/components/css/checkbox/checkbox.js.map +1 -0
- package/dist/components/css/divider/divider.d.ts +29 -0
- package/dist/components/css/divider/divider.d.ts.map +1 -0
- package/dist/components/css/divider/divider.js +23 -0
- package/dist/components/css/divider/divider.js.map +1 -0
- package/dist/components/css/error-text/error-text.d.ts +24 -0
- package/dist/components/css/error-text/error-text.d.ts.map +1 -0
- package/dist/components/css/error-text/error-text.js +18 -0
- package/dist/components/css/error-text/error-text.js.map +1 -0
- package/dist/components/css/fieldset/fieldset.d.ts +55 -0
- package/dist/components/css/fieldset/fieldset.d.ts.map +1 -0
- package/dist/components/css/fieldset/fieldset.js +39 -0
- package/dist/components/css/fieldset/fieldset.js.map +1 -0
- package/dist/components/css/file-upload/file-upload.d.ts +41 -0
- package/dist/components/css/file-upload/file-upload.d.ts.map +1 -0
- package/dist/components/css/file-upload/file-upload.js +32 -0
- package/dist/components/css/file-upload/file-upload.js.map +1 -0
- package/dist/components/css/heading/heading.d.ts +29 -0
- package/dist/components/css/heading/heading.d.ts.map +1 -0
- package/dist/components/css/heading/heading.js +23 -0
- package/dist/components/css/heading/heading.js.map +1 -0
- package/dist/components/css/help-text/help-text.d.ts +24 -0
- package/dist/components/css/help-text/help-text.d.ts.map +1 -0
- package/dist/components/css/help-text/help-text.js +23 -0
- package/dist/components/css/help-text/help-text.js.map +1 -0
- package/dist/components/css/icon/icon.d.ts +34 -0
- package/dist/components/css/icon/icon.d.ts.map +1 -0
- package/dist/components/css/icon/icon.js +25 -0
- package/dist/components/css/icon/icon.js.map +1 -0
- package/dist/components/css/input/input.d.ts +40 -0
- package/dist/components/css/input/input.d.ts.map +1 -0
- package/dist/components/css/input/input.js +45 -0
- package/dist/components/css/input/input.js.map +1 -0
- package/dist/components/css/label/label.d.ts +33 -0
- package/dist/components/css/label/label.d.ts.map +1 -0
- package/dist/components/css/label/label.js +23 -0
- package/dist/components/css/label/label.js.map +1 -0
- package/dist/components/css/link/link.d.ts +28 -0
- package/dist/components/css/link/link.d.ts.map +1 -0
- package/dist/components/css/link/link.js +20 -0
- package/dist/components/css/link/link.js.map +1 -0
- package/dist/components/css/list/list.d.ts +31 -0
- package/dist/components/css/list/list.d.ts.map +1 -0
- package/dist/components/css/list/list.js +25 -0
- package/dist/components/css/list/list.js.map +1 -0
- package/dist/components/css/pagination/pagination.d.ts +27 -0
- package/dist/components/css/pagination/pagination.d.ts.map +1 -0
- package/dist/components/css/pagination/pagination.js +25 -0
- package/dist/components/css/pagination/pagination.js.map +1 -0
- package/dist/components/css/paragraph/paragraph.d.ts +36 -0
- package/dist/components/css/paragraph/paragraph.d.ts.map +1 -0
- package/dist/components/css/paragraph/paragraph.js +26 -0
- package/dist/components/css/paragraph/paragraph.js.map +1 -0
- package/dist/components/css/progress/progress.d.ts +53 -0
- package/dist/components/css/progress/progress.d.ts.map +1 -0
- package/dist/components/css/progress/progress.js +38 -0
- package/dist/components/css/progress/progress.js.map +1 -0
- package/dist/components/css/radio/radio.d.ts +32 -0
- package/dist/components/css/radio/radio.d.ts.map +1 -0
- package/dist/components/css/radio/radio.js +27 -0
- package/dist/components/css/radio/radio.js.map +1 -0
- package/dist/components/css/search/search.d.ts +34 -0
- package/dist/components/css/search/search.d.ts.map +1 -0
- package/dist/components/css/search/search.js +32 -0
- package/dist/components/css/search/search.js.map +1 -0
- package/dist/components/css/select/select.d.ts +40 -0
- package/dist/components/css/select/select.d.ts.map +1 -0
- package/dist/components/css/select/select.js +31 -0
- package/dist/components/css/select/select.js.map +1 -0
- package/dist/components/css/shared.d.ts +90 -0
- package/dist/components/css/shared.d.ts.map +1 -0
- package/dist/components/css/shared.js +167 -0
- package/dist/components/css/shared.js.map +1 -0
- package/dist/components/css/skeleton/skeleton.d.ts +29 -0
- package/dist/components/css/skeleton/skeleton.d.ts.map +1 -0
- package/dist/components/css/skeleton/skeleton.js +23 -0
- package/dist/components/css/skeleton/skeleton.js.map +1 -0
- package/dist/components/css/skip-link/skip-link.d.ts +18 -0
- package/dist/components/css/skip-link/skip-link.d.ts.map +1 -0
- package/dist/components/css/skip-link/skip-link.js +16 -0
- package/dist/components/css/skip-link/skip-link.js.map +1 -0
- package/dist/components/css/spinner/spinner.d.ts +33 -0
- package/dist/components/css/spinner/spinner.d.ts.map +1 -0
- package/dist/components/css/spinner/spinner.js +25 -0
- package/dist/components/css/spinner/spinner.js.map +1 -0
- package/dist/components/css/sr-only/sr-only.d.ts +17 -0
- package/dist/components/css/sr-only/sr-only.d.ts.map +1 -0
- package/dist/components/css/sr-only/sr-only.js +15 -0
- package/dist/components/css/sr-only/sr-only.js.map +1 -0
- package/dist/components/css/switch/switch.d.ts +37 -0
- package/dist/components/css/switch/switch.d.ts.map +1 -0
- package/dist/components/css/switch/switch.js +29 -0
- package/dist/components/css/switch/switch.js.map +1 -0
- package/dist/components/css/table/table.d.ts +76 -0
- package/dist/components/css/table/table.d.ts.map +1 -0
- package/dist/components/css/table/table.js +59 -0
- package/dist/components/css/table/table.js.map +1 -0
- package/dist/components/css/tag/tag.d.ts +35 -0
- package/dist/components/css/tag/tag.d.ts.map +1 -0
- package/dist/components/css/tag/tag.js +27 -0
- package/dist/components/css/tag/tag.js.map +1 -0
- package/dist/components/css/textarea/textarea.d.ts +23 -0
- package/dist/components/css/textarea/textarea.d.ts.map +1 -0
- package/dist/components/css/textarea/textarea.js +18 -0
- package/dist/components/css/textarea/textarea.js.map +1 -0
- package/dist/components/css/toggle-group/toggle-group.d.ts +31 -0
- package/dist/components/css/toggle-group/toggle-group.d.ts.map +1 -0
- package/dist/components/css/toggle-group/toggle-group.js +29 -0
- package/dist/components/css/toggle-group/toggle-group.js.map +1 -0
- package/dist/components/css/tooltip/tooltip.d.ts +31 -0
- package/dist/components/css/tooltip/tooltip.d.ts.map +1 -0
- package/dist/components/css/tooltip/tooltip.js +29 -0
- package/dist/components/css/tooltip/tooltip.js.map +1 -0
- package/dist/components/default-texts.d.ts +35 -0
- package/dist/components/default-texts.d.ts.map +1 -0
- package/dist/components/default-texts.js +35 -0
- package/dist/components/default-texts.js.map +1 -0
- package/dist/components/events.d.ts +77 -0
- package/dist/components/events.d.ts.map +1 -0
- package/dist/components/events.js +3 -0
- package/dist/components/events.js.map +1 -0
- package/dist/components/frame/dialog/dialog.d.ts +122 -0
- package/dist/components/frame/dialog/dialog.d.ts.map +1 -0
- package/dist/components/frame/dialog/dialog.js +112 -0
- package/dist/components/frame/dialog/dialog.js.map +1 -0
- package/dist/components/frame/dialog/lt-dialog.d.ts +104 -0
- package/dist/components/frame/dialog/lt-dialog.d.ts.map +1 -0
- package/dist/components/frame/dialog/lt-dialog.js +431 -0
- package/dist/components/frame/dialog/lt-dialog.js.map +1 -0
- package/dist/components/frame/error-summary/error-summary.d.ts +40 -0
- package/dist/components/frame/error-summary/error-summary.d.ts.map +1 -0
- package/dist/components/frame/error-summary/error-summary.js +32 -0
- package/dist/components/frame/error-summary/error-summary.js.map +1 -0
- package/dist/components/frame/error-summary/lt-error-summary.d.ts +82 -0
- package/dist/components/frame/error-summary/lt-error-summary.d.ts.map +1 -0
- package/dist/components/frame/error-summary/lt-error-summary.js +302 -0
- package/dist/components/frame/error-summary/lt-error-summary.js.map +1 -0
- package/dist/components/frame/field/field-core.d.ts +92 -0
- package/dist/components/frame/field/field-core.d.ts.map +1 -0
- package/dist/components/frame/field/field-core.js +63 -0
- package/dist/components/frame/field/field-core.js.map +1 -0
- package/dist/components/frame/field/lt-field.d.ts +173 -0
- package/dist/components/frame/field/lt-field.d.ts.map +1 -0
- package/dist/components/frame/field/lt-field.js +580 -0
- package/dist/components/frame/field/lt-field.js.map +1 -0
- package/dist/components/frame/popover/lt-popover.d.ts +132 -0
- package/dist/components/frame/popover/lt-popover.d.ts.map +1 -0
- package/dist/components/frame/popover/lt-popover.js +490 -0
- package/dist/components/frame/popover/lt-popover.js.map +1 -0
- package/dist/components/frame/popover/popover.d.ts +49 -0
- package/dist/components/frame/popover/popover.d.ts.map +1 -0
- package/dist/components/frame/popover/popover.js +64 -0
- package/dist/components/frame/popover/popover.js.map +1 -0
- package/dist/components/frame/session-timeout/lt-session-timeout.d.ts +198 -0
- package/dist/components/frame/session-timeout/lt-session-timeout.d.ts.map +1 -0
- package/dist/components/frame/session-timeout/lt-session-timeout.js +573 -0
- package/dist/components/frame/session-timeout/lt-session-timeout.js.map +1 -0
- package/dist/components/frame/session-timeout/session-timeout.d.ts +113 -0
- package/dist/components/frame/session-timeout/session-timeout.d.ts.map +1 -0
- package/dist/components/frame/session-timeout/session-timeout.js +101 -0
- package/dist/components/frame/session-timeout/session-timeout.js.map +1 -0
- package/dist/components/frame/suggestion/lt-suggestion.d.ts +361 -0
- package/dist/components/frame/suggestion/lt-suggestion.d.ts.map +1 -0
- package/dist/components/frame/suggestion/lt-suggestion.js +1152 -0
- package/dist/components/frame/suggestion/lt-suggestion.js.map +1 -0
- package/dist/components/frame/suggestion/suggestion.d.ts +143 -0
- package/dist/components/frame/suggestion/suggestion.d.ts.map +1 -0
- package/dist/components/frame/suggestion/suggestion.js +127 -0
- package/dist/components/frame/suggestion/suggestion.js.map +1 -0
- package/dist/components/frame/tabs/lt-tabs.d.ts +404 -0
- package/dist/components/frame/tabs/lt-tabs.d.ts.map +1 -0
- package/dist/components/frame/tabs/lt-tabs.js +1201 -0
- package/dist/components/frame/tabs/lt-tabs.js.map +1 -0
- package/dist/components/frame/tabs/tabs.d.ts +112 -0
- package/dist/components/frame/tabs/tabs.d.ts.map +1 -0
- package/dist/components/frame/tabs/tabs.js +107 -0
- package/dist/components/frame/tabs/tabs.js.map +1 -0
- package/dist/components/host-element.d.ts +135 -0
- package/dist/components/host-element.d.ts.map +1 -0
- package/dist/components/host-element.js +366 -0
- package/dist/components/host-element.js.map +1 -0
- package/dist/components/standalone/connection-status/connection-status.d.ts +28 -0
- package/dist/components/standalone/connection-status/connection-status.d.ts.map +1 -0
- package/dist/components/standalone/connection-status/connection-status.js +22 -0
- package/dist/components/standalone/connection-status/connection-status.js.map +1 -0
- package/dist/components/standalone/connection-status/lt-connection-status.d.ts +81 -0
- package/dist/components/standalone/connection-status/lt-connection-status.d.ts.map +1 -0
- package/dist/components/standalone/connection-status/lt-connection-status.js +216 -0
- package/dist/components/standalone/connection-status/lt-connection-status.js.map +1 -0
- package/dist/components/standalone/toast/lt-toast.d.ts +109 -0
- package/dist/components/standalone/toast/lt-toast.d.ts.map +1 -0
- package/dist/components/standalone/toast/lt-toast.js +256 -0
- package/dist/components/standalone/toast/lt-toast.js.map +1 -0
- package/dist/components/standalone/toast/toast.d.ts +52 -0
- package/dist/components/standalone/toast/toast.d.ts.map +1 -0
- package/dist/components/standalone/toast/toast.js +42 -0
- package/dist/components/standalone/toast/toast.js.map +1 -0
- package/dist/diagnostics/core.d.ts +137 -0
- package/dist/diagnostics/core.d.ts.map +1 -0
- package/dist/diagnostics/core.js +72 -0
- package/dist/diagnostics/core.js.map +1 -0
- package/dist/diagnostics/default-core.d.ts +10 -0
- package/dist/diagnostics/default-core.d.ts.map +1 -0
- package/dist/diagnostics/default-core.js +72 -0
- package/dist/diagnostics/default-core.js.map +1 -0
- package/dist/diagnostics/index.d.ts +84 -0
- package/dist/diagnostics/index.d.ts.map +1 -0
- package/dist/diagnostics/index.js +106 -0
- package/dist/diagnostics/index.js.map +1 -0
- package/dist/dom.d.ts +55 -0
- package/dist/dom.d.ts.map +1 -0
- package/dist/dom.js +162 -0
- package/dist/dom.js.map +1 -0
- package/dist/index.d.ts +97 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +58 -0
- package/dist/index.js.map +1 -0
- package/dist/jsx/react.d.ts +180 -0
- package/dist/jsx/react.d.ts.map +1 -0
- package/dist/jsx/react.js +2 -0
- package/dist/jsx/react.js.map +1 -0
- package/dist/lotek.css +3617 -0
- package/dist/lt.d.ts +325 -0
- package/dist/lt.d.ts.map +1 -0
- package/dist/lt.js +183 -0
- package/dist/lt.js.map +1 -0
- package/dist/react.d.ts +492 -0
- package/dist/react.d.ts.map +1 -0
- package/dist/react.js +296 -0
- package/dist/react.js.map +1 -0
- package/dist/register.d.ts +17 -0
- package/dist/register.d.ts.map +1 -0
- package/dist/register.js +35 -0
- package/dist/register.js.map +1 -0
- package/dist/tokens/color.d.ts +43 -0
- package/dist/tokens/color.d.ts.map +1 -0
- package/dist/tokens/color.js +123 -0
- package/dist/tokens/color.js.map +1 -0
- package/dist/tokens/contract.d.ts +18 -0
- package/dist/tokens/contract.d.ts.map +1 -0
- package/dist/tokens/contract.js +18 -0
- package/dist/tokens/contract.js.map +1 -0
- package/dist/tokens/matrix-cells.d.ts +30 -0
- package/dist/tokens/matrix-cells.d.ts.map +1 -0
- package/dist/tokens/matrix-cells.js +273 -0
- package/dist/tokens/matrix-cells.js.map +1 -0
- package/dist/tokens/matrix.d.ts +18 -0
- package/dist/tokens/matrix.d.ts.map +1 -0
- package/dist/tokens/matrix.js +21 -0
- package/dist/tokens/matrix.js.map +1 -0
- package/dist/tokens/theme-check.d.ts +42 -0
- package/dist/tokens/theme-check.d.ts.map +1 -0
- package/dist/tokens/theme-check.js +10 -0
- package/dist/tokens/theme-check.js.map +1 -0
- package/dist/tokens/theme.d.ts +94 -0
- package/dist/tokens/theme.d.ts.map +1 -0
- package/dist/tokens/theme.js +14 -0
- package/dist/tokens/theme.js.map +1 -0
- package/dist/tokens/tokens.d.ts +122 -0
- package/dist/tokens/tokens.d.ts.map +1 -0
- package/dist/tokens/tokens.js +158 -0
- package/dist/tokens/tokens.js.map +1 -0
- package/dist/vocabulary/classes.d.ts +3 -0
- package/dist/vocabulary/classes.d.ts.map +1 -0
- package/dist/vocabulary/classes.js +1320 -0
- package/dist/vocabulary/classes.js.map +1 -0
- package/dist/vocabulary/elements.d.ts +3 -0
- package/dist/vocabulary/elements.d.ts.map +1 -0
- package/dist/vocabulary/elements.js +410 -0
- package/dist/vocabulary/elements.js.map +1 -0
- package/dist/vocabulary/types.d.ts +175 -0
- package/dist/vocabulary/types.d.ts.map +1 -0
- package/dist/vocabulary/types.js +11 -0
- package/dist/vocabulary/types.js.map +1 -0
- package/dist/wasi-host.d.ts +24 -0
- package/dist/wasi-host.d.ts.map +1 -0
- package/dist/wasi-host.js +140 -0
- package/dist/wasi-host.js.map +1 -0
- package/live-templates.xml +62 -0
- package/manifest/files.json +373 -0
- package/manifest/manifest.json +4965 -0
- package/manifest/manifest.schema.json +513 -0
- package/package.json +404 -4
- package/src/cli.ts +21 -0
- package/src/components/css/accordion/accordion.css +102 -0
- package/src/components/css/accordion/accordion.ts +50 -0
- package/src/components/css/alert/alert.css +53 -0
- package/src/components/css/alert/alert.ts +48 -0
- package/src/components/css/avatar/avatar.css +96 -0
- package/src/components/css/avatar/avatar.ts +57 -0
- package/src/components/css/badge/badge.css +42 -0
- package/src/components/css/badge/badge.ts +43 -0
- package/src/components/css/breadcrumbs/breadcrumbs.css +62 -0
- package/src/components/css/breadcrumbs/breadcrumbs.ts +30 -0
- package/src/components/css/button/button.css +128 -0
- package/src/components/css/button/button.ts +44 -0
- package/src/components/css/card/card.css +65 -0
- package/src/components/css/card/card.ts +50 -0
- package/src/components/css/checkbox/checkbox.css +114 -0
- package/src/components/css/checkbox/checkbox.ts +50 -0
- package/src/components/css/divider/divider.css +38 -0
- package/src/components/css/divider/divider.ts +42 -0
- package/src/components/css/error-text/error-text.css +21 -0
- package/src/components/css/error-text/error-text.ts +37 -0
- package/src/components/css/fieldset/fieldset.css +72 -0
- package/src/components/css/fieldset/fieldset.ts +87 -0
- package/src/components/css/file-upload/file-upload.css +102 -0
- package/src/components/css/file-upload/file-upload.ts +65 -0
- package/src/components/css/heading/heading.css +33 -0
- package/src/components/css/heading/heading.ts +42 -0
- package/src/components/css/help-text/help-text.css +24 -0
- package/src/components/css/help-text/help-text.ts +42 -0
- package/src/components/css/icon/icon.css +20 -0
- package/src/components/css/icon/icon.ts +44 -0
- package/src/components/css/input/input.css +145 -0
- package/src/components/css/input/input.ts +77 -0
- package/src/components/css/label/label.css +42 -0
- package/src/components/css/label/label.ts +51 -0
- package/src/components/css/link/link.css +38 -0
- package/src/components/css/link/link.ts +38 -0
- package/src/components/css/list/list.css +53 -0
- package/src/components/css/list/list.ts +44 -0
- package/src/components/css/pagination/pagination.css +95 -0
- package/src/components/css/pagination/pagination.ts +33 -0
- package/src/components/css/paragraph/paragraph.css +31 -0
- package/src/components/css/paragraph/paragraph.ts +53 -0
- package/src/components/css/progress/progress.css +161 -0
- package/src/components/css/progress/progress.ts +78 -0
- package/src/components/css/radio/radio.css +94 -0
- package/src/components/css/radio/radio.ts +50 -0
- package/src/components/css/search/search.css +50 -0
- package/src/components/css/search/search.ts +56 -0
- package/src/components/css/select/select.css +321 -0
- package/src/components/css/select/select.ts +63 -0
- package/src/components/css/shared.ts +199 -0
- package/src/components/css/skeleton/skeleton.css +62 -0
- package/src/components/css/skeleton/skeleton.ts +43 -0
- package/src/components/css/skip-link/skip-link.css +41 -0
- package/src/components/css/skip-link/skip-link.ts +22 -0
- package/src/components/css/spinner/spinner.css +48 -0
- package/src/components/css/spinner/spinner.ts +48 -0
- package/src/components/css/sr-only/sr-only.css +16 -0
- package/src/components/css/sr-only/sr-only.ts +21 -0
- package/src/components/css/switch/switch.css +105 -0
- package/src/components/css/switch/switch.ts +50 -0
- package/src/components/css/table/table.css +159 -0
- package/src/components/css/table/table.ts +107 -0
- package/src/components/css/tag/tag.css +58 -0
- package/src/components/css/tag/tag.ts +49 -0
- package/src/components/css/textarea/textarea.css +83 -0
- package/src/components/css/textarea/textarea.ts +40 -0
- package/src/components/css/toggle-group/toggle-group.css +92 -0
- package/src/components/css/toggle-group/toggle-group.ts +37 -0
- package/src/components/css/tooltip/tooltip.css +89 -0
- package/src/components/css/tooltip/tooltip.ts +37 -0
- package/src/components/default-texts.ts +34 -0
- package/src/components/events.ts +68 -0
- package/src/components/frame/dialog/dialog.css +306 -0
- package/src/components/frame/dialog/dialog.ts +166 -0
- package/src/components/frame/dialog/lt-dialog.ts +510 -0
- package/src/components/frame/error-summary/error-summary.css +47 -0
- package/src/components/frame/error-summary/error-summary.ts +56 -0
- package/src/components/frame/error-summary/lt-error-summary.ts +344 -0
- package/src/components/frame/field/field-core.ts +152 -0
- package/src/components/frame/field/field.css +17 -0
- package/src/components/frame/field/lt-field.ts +753 -0
- package/src/components/frame/popover/lt-popover.ts +555 -0
- package/src/components/frame/popover/popover.css +50 -0
- package/src/components/frame/popover/popover.ts +102 -0
- package/src/components/frame/session-timeout/lt-session-timeout.ts +681 -0
- package/src/components/frame/session-timeout/session-timeout.css +50 -0
- package/src/components/frame/session-timeout/session-timeout.ts +156 -0
- package/src/components/frame/suggestion/lt-suggestion.ts +1358 -0
- package/src/components/frame/suggestion/suggestion.css +132 -0
- package/src/components/frame/suggestion/suggestion.ts +172 -0
- package/src/components/frame/tabs/lt-tabs.ts +1319 -0
- package/src/components/frame/tabs/tabs.css +128 -0
- package/src/components/frame/tabs/tabs.ts +188 -0
- package/src/components/host-element.ts +400 -0
- package/src/components/standalone/connection-status/connection-status.css +41 -0
- package/src/components/standalone/connection-status/connection-status.ts +41 -0
- package/src/components/standalone/connection-status/lt-connection-status.ts +242 -0
- package/src/components/standalone/toast/lt-toast.ts +300 -0
- package/src/components/standalone/toast/toast.css +78 -0
- package/src/components/standalone/toast/toast.ts +70 -0
- package/src/diagnostics/core.ts +210 -0
- package/src/diagnostics/default-core.ts +81 -0
- package/src/diagnostics/index.ts +150 -0
- package/src/dom.ts +185 -0
- package/src/index.ts +218 -0
- package/src/jsx/react.ts +212 -0
- package/src/lt.ts +192 -0
- package/src/react.ts +411 -0
- package/src/register.ts +43 -0
- package/src/tailwind/tailwind.css +169 -0
- package/src/tokens/boundary.css +104 -0
- package/src/tokens/color-contract.json +231 -0
- package/src/tokens/color.ts +150 -0
- package/src/tokens/contract.ts +24 -0
- package/src/tokens/matrix-cells.ts +375 -0
- package/src/tokens/matrix.ts +32 -0
- package/src/tokens/theme-check.ts +51 -0
- package/src/tokens/theme.ts +104 -0
- package/src/tokens/tokens.css +569 -0
- package/src/tokens/tokens.ts +223 -0
- package/src/vocabulary/classes.ts +1322 -0
- package/src/vocabulary/elements.ts +412 -0
- package/src/vocabulary/types.ts +178 -0
- package/src/wasi-host.ts +155 -0
- package/web-types.json +800 -0
|
@@ -0,0 +1,409 @@
|
|
|
1
|
+
# LO-TEK with Datastar
|
|
2
|
+
|
|
3
|
+
The rulebook for LO-TEK together with [Datastar](https://data-star.dev), which
|
|
4
|
+
adds reactivity to ordinary HTML with `data-*` attributes. One script, no
|
|
5
|
+
build step, the same premise as LO-TEK.
|
|
6
|
+
|
|
7
|
+
That means two things for this file: the addresses are URLs, since a browser
|
|
8
|
+
without a bundler does not resolve a package name, and the state is controlled
|
|
9
|
+
with attributes, which is exactly what the `frame` components expect.
|
|
10
|
+
|
|
11
|
+
This is @lo-tek/interfaces 0.37.0. The file is generated by the package and
|
|
12
|
+
follows its version, so it can never say anything other than the code next to
|
|
13
|
+
it.
|
|
14
|
+
|
|
15
|
+
## Short version
|
|
16
|
+
|
|
17
|
+
1. **One `<link>` to `lotek.css`, before everything else.** Without it, the
|
|
18
|
+
components look unstyled. The answer is then to add the link, never to
|
|
19
|
+
write your own CSS to make them look right.
|
|
20
|
+
2. **Use only the classes and elements in the tables below.** `lt-modal`,
|
|
21
|
+
`lt-datepicker` and `data-variant="outlined"` exist in other design
|
|
22
|
+
systems, not in LO-TEK. If you are unsure whether something exists, it is
|
|
23
|
+
listed here or it does not exist.
|
|
24
|
+
3. **No hard-coded colours or pixels.** `var(--lt-color-…)` and
|
|
25
|
+
`var(--lt-spacing-…)`.
|
|
26
|
+
4. **`defineLt*()` runs once in a `<script type="module">` with the full
|
|
27
|
+
URL,** and the state is set with `data-attr:`, which adds and removes the
|
|
28
|
+
attribute. `hidden="false"` would hide the error text all the same.
|
|
29
|
+
5. **Run the check on what you have written:**
|
|
30
|
+
`npx @lo-tek/interfaces check page.html`. It knows every class, every
|
|
31
|
+
element, every attribute and every allowed value, prints
|
|
32
|
+
`file:line:column: error: message`, or `warning:`, and exits with an error
|
|
33
|
+
code if it finds anything. With the app running, also check every page you
|
|
34
|
+
have changed: `npx @lo-tek/interfaces check http://localhost:8080/page`.
|
|
35
|
+
That also requires every `for` and `aria-describedby` to point to an id
|
|
36
|
+
that exists, and every field to have a label. You are done when both answer
|
|
37
|
+
"The markup matches LO-TEK".
|
|
38
|
+
|
|
39
|
+
## 1. The stylesheet and Datastar
|
|
40
|
+
|
|
41
|
+
```html
|
|
42
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.37.0/dist/lotek.css">
|
|
43
|
+
<script
|
|
44
|
+
type="module"
|
|
45
|
+
src="https://cdn.jsdelivr.net/gh/starfederation/datastar@v1.0.4/bundles/datastar.js"
|
|
46
|
+
></script>
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
`lotek.css` is 103 kB, 13 kB compressed, and has all the components. If you
|
|
50
|
+
want only what you use, `tokens.css` defines all the variables, and all the
|
|
51
|
+
other stylesheets build on it. It must be loaded, and comes first out of
|
|
52
|
+
habit: the order between it and the others does not matter.
|
|
53
|
+
|
|
54
|
+
## 2. What exists
|
|
55
|
+
|
|
56
|
+
35 CSS components and 9 web components, and this is the whole list. The
|
|
57
|
+
classes are `lt-` + kebab-case. Variants are always `data-*` attributes, never
|
|
58
|
+
classes of their own: `data-variant="secondary"`, not `lt-button--secondary`.
|
|
59
|
+
The default variant has no attribute.
|
|
60
|
+
|
|
61
|
+
### CSS components (no JavaScript)
|
|
62
|
+
|
|
63
|
+
| Class | Stylesheet | Attributes |
|
|
64
|
+
| --- | --- | --- |
|
|
65
|
+
| `lt-accordion`<br>`lt-accordion__content` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.37.0/src/components/css/accordion/accordion.css` | `data-variant`: plain |
|
|
66
|
+
| `lt-alert`<br>`lt-alert__title` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.37.0/src/components/css/alert/alert.css` | `data-color`: info, success, warning, danger |
|
|
67
|
+
| `lt-avatar`<br>`lt-avatar-stack` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.37.0/src/components/css/avatar/avatar.css` | `data-variant`: square<br>`data-size`: small, large |
|
|
68
|
+
| `lt-badge` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.37.0/src/components/css/badge/badge.css` | `data-color`: success, warning, danger, neutral |
|
|
69
|
+
| `lt-breadcrumbs` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.37.0/src/components/css/breadcrumbs/breadcrumbs.css` | none |
|
|
70
|
+
| `lt-button` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.37.0/src/components/css/button/button.css` | `data-variant`: secondary, ghost, danger |
|
|
71
|
+
| `lt-card`<br>`lt-card__title` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.37.0/src/components/css/card/card.css` | `data-variant`: filled<br>`data-interactive` (flag) |
|
|
72
|
+
| `lt-checkbox`<br>`lt-checkbox-row` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.37.0/src/components/css/checkbox/checkbox.css` | `data-state`: invalid, success |
|
|
73
|
+
| `lt-divider` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.37.0/src/components/css/divider/divider.css` | `data-variant`: subtle, strong |
|
|
74
|
+
| `lt-error-text` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.37.0/src/components/css/error-text/error-text.css` | `data-variant`: warning |
|
|
75
|
+
| `lt-fieldset`<br>`lt-legend` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.37.0/src/components/css/fieldset/fieldset.css` | `data-state`: invalid, success<br>`data-required`: symbol, text<br>`data-optional` (flag) |
|
|
76
|
+
| `lt-file-upload`<br>`lt-file-upload-list` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.37.0/src/components/css/file-upload/file-upload.css` | `data-state`: invalid, success |
|
|
77
|
+
| `lt-heading` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.37.0/src/components/css/heading/heading.css` | `data-size`: xs, s, m, xl, mega |
|
|
78
|
+
| `lt-help-text` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.37.0/src/components/css/help-text/help-text.css` | `data-variant`: strong, success, warning |
|
|
79
|
+
| `lt-icon` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.37.0/src/components/css/icon/icon.css` | none |
|
|
80
|
+
| `lt-input` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.37.0/src/components/css/input/input.css` | `data-state`: invalid, success<br>`data-variant`: date, datetime-local, time |
|
|
81
|
+
| `lt-label` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.37.0/src/components/css/label/label.css` | `data-required`: symbol, text<br>`data-optional` (flag) |
|
|
82
|
+
| `lt-link` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.37.0/src/components/css/link/link.css` | none |
|
|
83
|
+
| `lt-list` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.37.0/src/components/css/list/list.css` | `data-variant`: plain, divided |
|
|
84
|
+
| `lt-pagination`<br>`lt-pagination__gap` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.37.0/src/components/css/pagination/pagination.css` | none |
|
|
85
|
+
| `lt-paragraph` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.37.0/src/components/css/paragraph/paragraph.css` | `data-variant`: lead<br>`data-size`: small, large |
|
|
86
|
+
| `lt-progress` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.37.0/src/components/css/progress/progress.css` | `data-color`: success, warning, danger |
|
|
87
|
+
| `lt-radio`<br>`lt-radio-row` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.37.0/src/components/css/radio/radio.css` | `data-state`: invalid, success |
|
|
88
|
+
| `lt-search`<br>`lt-search-row` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.37.0/src/components/css/search/search.css` | `data-state`: invalid, success |
|
|
89
|
+
| `lt-select` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.37.0/src/components/css/select/select.css` | `data-state`: invalid, success<br>`data-picker`: styled |
|
|
90
|
+
| `lt-skeleton` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.37.0/src/components/css/skeleton/skeleton.css` | `data-variant`: text, circle |
|
|
91
|
+
| `lt-skip-link` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.37.0/src/components/css/skip-link/skip-link.css` | none |
|
|
92
|
+
| `lt-spinner` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.37.0/src/components/css/spinner/spinner.css` | `data-size`: small, large |
|
|
93
|
+
| `lt-sr-only` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.37.0/src/components/css/sr-only/sr-only.css` | none |
|
|
94
|
+
| `lt-switch`<br>`lt-switch-row` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.37.0/src/components/css/switch/switch.css` | none |
|
|
95
|
+
| `lt-table`<br>`lt-table__sort`<br>`lt-table-scroll` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.37.0/src/components/css/table/table.css` | `data-variant`: striped<br>`data-hoverable` (flag) |
|
|
96
|
+
| `lt-tag` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.37.0/src/components/css/tag/tag.css` | `data-variant`: filled<br>`data-selectable` (flag) |
|
|
97
|
+
| `lt-textarea` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.37.0/src/components/css/textarea/textarea.css` | `data-state`: invalid, success |
|
|
98
|
+
| `lt-toggle-group`<br>`lt-toggle-group__option` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.37.0/src/components/css/toggle-group/toggle-group.css` | none |
|
|
99
|
+
| `lt-tooltip`<br>`lt-tooltip__bubble` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.37.0/src/components/css/tooltip/tooltip.css` | none |
|
|
100
|
+
|
|
101
|
+
There is also `lt-theme-control`, a class on a radio button that lets the user
|
|
102
|
+
choose a theme. It is in `tokens.css`, and is described under Tokens.
|
|
103
|
+
|
|
104
|
+
## 3. Tokens
|
|
105
|
+
|
|
106
|
+
One layer. A colour is a cell in a matrix of **family**, that is, what it
|
|
107
|
+
means, and **role**, that is, what it does, and the name is
|
|
108
|
+
`--lt-color-<family>-<role>`. Every family has every role, so
|
|
109
|
+
`--lt-color-danger-border` and `--lt-color-success-border` both exist. The
|
|
110
|
+
roles are the same whatever the family: `surface` is a tinted surface, `fill`
|
|
111
|
+
a filled one, `content` the text on top of `fill`, `border` a border, and
|
|
112
|
+
`text` the family's colour as text. Border and text each have a weaker and a
|
|
113
|
+
stronger step next to them.
|
|
114
|
+
|
|
115
|
+
```
|
|
116
|
+
Families: `accent`, `visited`, `brand1`, `brand2`, `brand3`, `neutral`, `danger`, `warning`, `success`.
|
|
117
|
+
|
|
118
|
+
Roles: `surface`, `border-subtle`, `border`, `border-strong`, `fill`, `text`, `text-strong`, `text-subtle`, `content`.
|
|
119
|
+
|
|
120
|
+
Outside the matrix: `--lt-color-disabled-surface`, `--lt-color-disabled-text`, `--lt-color-neutral-canvas`, `--lt-color-neutral-raised`, `--lt-color-overlay`, `--lt-focus-ring`, `--lt-icon-calendar`, `--lt-icon-check`, `--lt-icon-clock`, `--lt-icon-dash`, `--lt-icon-search`, `--lt-shadow-overlay`.
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Spacing: `--lt-spacing-0-5`, `--lt-spacing-1`, `--lt-spacing-10`,
|
|
124
|
+
`--lt-spacing-12`, `--lt-spacing-16`, `--lt-spacing-2`, `--lt-spacing-3`,
|
|
125
|
+
`--lt-spacing-4`, `--lt-spacing-5`, `--lt-spacing-6`, `--lt-spacing-7`,
|
|
126
|
+
`--lt-spacing-8`, `--lt-spacing-px`.
|
|
127
|
+
|
|
128
|
+
Font: `--lt-font-size-l`, `--lt-font-size-m`, `--lt-font-size-mega`,
|
|
129
|
+
`--lt-font-size-reference`, `--lt-font-size-s`, `--lt-font-size-xl`,
|
|
130
|
+
`--lt-font-size-xs`, `--lt-font-size-xxl`, `--lt-font-size-xxs`,
|
|
131
|
+
`--lt-font-weight-bold`, `--lt-font-weight-medium`,
|
|
132
|
+
`--lt-font-weight-regular`, `--lt-font-weight-semibold`.
|
|
133
|
+
|
|
134
|
+
Line height: `--lt-line-height-article`, `--lt-line-height-compact`,
|
|
135
|
+
`--lt-line-height-default`, `--lt-line-height-heading`.
|
|
136
|
+
|
|
137
|
+
`disabled` and `neutral` are not the same. `disabled` is for controls that are
|
|
138
|
+
turned off, and is exempt from the contrast requirement in WCAG 1.4.3.
|
|
139
|
+
`neutral` is for subdued information the user actually has to read or press,
|
|
140
|
+
and holds 4.5:1. Never use the `disabled` colours to subdue something that is
|
|
141
|
+
meant to be read.
|
|
142
|
+
|
|
143
|
+
### Light and dark
|
|
144
|
+
|
|
145
|
+
Without you doing anything, the colours follow the device's setting. A page
|
|
146
|
+
that wants to decide for itself sets `data-theme="light"` or
|
|
147
|
+
`data-theme="dark"` on `<html>`.
|
|
148
|
+
|
|
149
|
+
The attribute is a **theme boundary** and works on any element, not only on
|
|
150
|
+
the root. One theme can sit inside another, both ways.
|
|
151
|
+
|
|
152
|
+
This is what an embedded component should use. When you put LO-TEK into a page
|
|
153
|
+
you do not control, set the attribute on the component's own root element:
|
|
154
|
+
|
|
155
|
+
```html
|
|
156
|
+
<div data-theme="light">
|
|
157
|
+
<button class="lt-button">Save</button>
|
|
158
|
+
</div>
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
The component is then light whatever the device is set to, and the host is
|
|
162
|
+
left alone.
|
|
163
|
+
|
|
164
|
+
**The host's CSS stops at the boundary.** The host often has rules without a
|
|
165
|
+
layer, such as `button { background: none; border: none }` or a normalize, and
|
|
166
|
+
they beat `@layer lotek`. In that case, set `data-lt-boundary` on the same
|
|
167
|
+
root element:
|
|
168
|
+
|
|
169
|
+
```html
|
|
170
|
+
<div data-lt-boundary data-theme="light">
|
|
171
|
+
<button class="lt-button">Save</button>
|
|
172
|
+
</div>
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
Below the root element the browser then ignores the host's CSS without a
|
|
176
|
+
layer, unless a rule of the host's wins on specificity as described below, and
|
|
177
|
+
LO-TEK's layer applies again. The rule is in `lotek.css` and in
|
|
178
|
+
`https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.37.0/src/tokens/boundary.css`.
|
|
179
|
+
Fonts and other inherited properties still come from the host, and the
|
|
180
|
+
`--lt-*` variables work. Three things follow from it:
|
|
181
|
+
|
|
182
|
+
- Your own CSS inside the boundary must be in a layer after `lotek`. CSS
|
|
183
|
+
without a layer disappears there in the same way as the host's.
|
|
184
|
+
- Elements without a LO-TEK class lose the host's CSS without a layer. A layer
|
|
185
|
+
the host has declared before `lotek`, such as Tailwind's Preflight in
|
|
186
|
+
`base`, still applies where LO-TEK sets nothing.
|
|
187
|
+
- The boundary has the specificity (0,2,0). A rule from the host with the same
|
|
188
|
+
specificity wins if it is loaded after the boundary, and one with more
|
|
189
|
+
always wins. So do `!important` and layers the host has declared after
|
|
190
|
+
`lotek`.
|
|
191
|
+
|
|
192
|
+
LO-TEK sets `color-scheme` only where someone has chosen a theme: on
|
|
193
|
+
`[data-theme="light"]`, on `[data-theme="dark"]` and on the options of the
|
|
194
|
+
theme picker below. Bare `:root` never gets it. The property controls the
|
|
195
|
+
browser's own surfaces, that is, scrollbars, dropdowns and calendar panels,
|
|
196
|
+
and it is inherited. A child can opt out with `color-scheme: normal`, but that
|
|
197
|
+
is a counter-rule the host never asked to have to write: with the value on the
|
|
198
|
+
root, it applied to the whole document, including where the package is only a
|
|
199
|
+
guest. If the whole page should follow the system, write
|
|
200
|
+
`color-scheme: light dark` on `<html>` yourself, in the same way as you set
|
|
201
|
+
the layer order yourself.
|
|
202
|
+
|
|
203
|
+
### Letting the user choose a theme
|
|
204
|
+
|
|
205
|
+
`lt-theme-control` on a radio button makes `value` a theme choice. It is plain
|
|
206
|
+
CSS, without a line of JavaScript:
|
|
207
|
+
|
|
208
|
+
```html
|
|
209
|
+
<fieldset class="lt-toggle-group">
|
|
210
|
+
<legend class="lt-sr-only">Theme</legend>
|
|
211
|
+
<label class="lt-toggle-group__option">
|
|
212
|
+
<input class="lt-theme-control" type="radio" name="theme"
|
|
213
|
+
value="auto" checked /> Follow the system
|
|
214
|
+
</label>
|
|
215
|
+
<label class="lt-toggle-group__option">
|
|
216
|
+
<input class="lt-theme-control" type="radio" name="theme"
|
|
217
|
+
value="light" /> Light
|
|
218
|
+
</label>
|
|
219
|
+
<label class="lt-toggle-group__option">
|
|
220
|
+
<input class="lt-theme-control" type="radio" name="theme"
|
|
221
|
+
value="dark" /> Dark
|
|
222
|
+
</label>
|
|
223
|
+
</fieldset>
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
The choice controls two things. LO-TEK's colours come from the tokens, and the
|
|
227
|
+
browser's **own** surfaces from `color-scheme`: `light` gives `light`, `dark`
|
|
228
|
+
gives `dark`, and `auto` gives `light dark`. `light dark` is not a theme, but
|
|
229
|
+
the statement that the page works in both, so the browser can choose by the
|
|
230
|
+
system.
|
|
231
|
+
|
|
232
|
+
"Follow the system" has no theme block, and that is on purpose: a value
|
|
233
|
+
without a block matches nothing, and then the media query applies again.
|
|
234
|
+
|
|
235
|
+
Do not write `color-scheme` yourself when the picker is in use. Such a rule
|
|
236
|
+
outside a layer beats `@layer lotek` and locks the browser's surfaces to the
|
|
237
|
+
system while the user has chosen something else.
|
|
238
|
+
|
|
239
|
+
`light` and `dark` win over `data-theme` on `<html>`, so the server can send
|
|
240
|
+
the stored choice while a click still takes effect before the response is
|
|
241
|
+
back. `auto` does not: it means "no override from me", so if the server has
|
|
242
|
+
written `data-theme`, the server's value stands. For "follow the system" to
|
|
243
|
+
work at once, whatever stores the choice must also remove the attribute.
|
|
244
|
+
|
|
245
|
+
Two things it does not do. It **stores nothing**: submit the group in a form
|
|
246
|
+
and store the choice in a cookie the server reads, or in `localStorage`. And
|
|
247
|
+
it must be in the **same tree as `<html>`**, since `:has()` does not see out
|
|
248
|
+
of its own tree; a control inside a shadow root does not set the theme on the
|
|
249
|
+
page.
|
|
250
|
+
|
|
251
|
+
## 4. Web components
|
|
252
|
+
|
|
253
|
+
Three rules apply to all of them:
|
|
254
|
+
|
|
255
|
+
1. **`defineLt*()` runs once** in a `<script type="module">` in the page
|
|
256
|
+
template. The import has no side effect on its own; it is the `define` call
|
|
257
|
+
that registers the element.
|
|
258
|
+
2. **Boolean attributes are true as long as they are present.**
|
|
259
|
+
`hidden="false"`, `disabled="false"` and `open="false"` turn it *on*. To
|
|
260
|
+
turn any of them off, remove the attribute entirely.
|
|
261
|
+
3. **You write the markup, the component adds the behaviour.** `<lt-field>`
|
|
262
|
+
does not create your label or your control. You write `for` on the label
|
|
263
|
+
and `id` on the control, or wrap the control in a `<label>`, so the field
|
|
264
|
+
has a name without JavaScript too. The component wires the help text and
|
|
265
|
+
the error text with `aria-describedby` and `aria-invalid`, and never writes
|
|
266
|
+
an id on the control: an id the server did not send makes an update from
|
|
267
|
+
the server replace the field, with the focus and what the user has typed.
|
|
268
|
+
The field is invalid when the error text is there without `hidden`.
|
|
269
|
+
|
|
270
|
+
| Element | Category | Stylesheet | Registration | Attributes | Events | Classes inside |
|
|
271
|
+
| --- | --- | --- | --- | --- | --- | --- |
|
|
272
|
+
| `<lt-field>` | frame | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.37.0/src/components/frame/field/field.css` | `defineLtField()` from `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.37.0/dist/components/frame/field/lt-field.js` | `disabled` (flag)<br>`optional` (flag)<br>`described-by` (text) | none | none |
|
|
273
|
+
| `<lt-tabs>` | frame | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.37.0/src/components/frame/tabs/tabs.css` | `defineLtTabs()` from `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.37.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` |
|
|
274
|
+
| `<lt-error-summary>` | frame | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.37.0/src/components/frame/error-summary/error-summary.css` | `defineLtErrorSummary()` from `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.37.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` |
|
|
275
|
+
| `<lt-popover>` | frame | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.37.0/src/components/frame/popover/popover.css` | `defineLtPopover()` from `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.37.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` |
|
|
276
|
+
| `<lt-suggestion>` | frame | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.37.0/src/components/frame/suggestion/suggestion.css` | `defineLtSuggestion()` from `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.37.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` |
|
|
277
|
+
| `<lt-dialog>` | frame | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.37.0/src/components/frame/dialog/dialog.css` | `defineLtDialog()` from `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.37.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` |
|
|
278
|
+
| `<lt-toast>` | standalone | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.37.0/src/components/standalone/toast/toast.css` | `defineLtToast()` from `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.37.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` |
|
|
279
|
+
| `<lt-session-timeout>` | frame | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.37.0/src/components/frame/session-timeout/session-timeout.css` | `defineLtSessionTimeout()` from `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.37.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` |
|
|
280
|
+
| `<lt-connection-status>` | standalone | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.37.0/src/components/standalone/connection-status/connection-status.css` | `defineLtConnectionStatus()` from `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.37.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` |
|
|
281
|
+
|
|
282
|
+
None of them uses shadow DOM. The content is in plain DOM, so `querySelector`,
|
|
283
|
+
`FormData` and ordinary CSS work straight into it.
|
|
284
|
+
|
|
285
|
+
## 5. A form with Datastar
|
|
286
|
+
|
|
287
|
+
```html
|
|
288
|
+
<form
|
|
289
|
+
data-signals="{name: '', touched: false}"
|
|
290
|
+
data-computed:invalid="$touched && $name.trim() === ''"
|
|
291
|
+
>
|
|
292
|
+
<lt-field>
|
|
293
|
+
<label class="lt-label" for="name" data-required="symbol">Full name</label>
|
|
294
|
+
<input
|
|
295
|
+
class="lt-input"
|
|
296
|
+
id="name"
|
|
297
|
+
type="text"
|
|
298
|
+
name="name"
|
|
299
|
+
data-bind:name
|
|
300
|
+
data-on:blur="$touched = true"
|
|
301
|
+
/>
|
|
302
|
+
<p class="lt-error-text" hidden data-attr:hidden="!$invalid">Enter your name.</p>
|
|
303
|
+
</lt-field>
|
|
304
|
+
|
|
305
|
+
<button class="lt-button" type="submit">Send</button>
|
|
306
|
+
</form>
|
|
307
|
+
|
|
308
|
+
<script type="module">
|
|
309
|
+
import { defineLtField } from
|
|
310
|
+
"https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.37.0/dist/components/frame/field/lt-field.js"
|
|
311
|
+
|
|
312
|
+
defineLtField()
|
|
313
|
+
</script>
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
`data-signals` creates the state, `data-computed:invalid` derives the
|
|
317
|
+
validation from it, `data-bind:name` binds the field both ways, and
|
|
318
|
+
`data-on:blur` records that the user has left it.
|
|
319
|
+
|
|
320
|
+
`data-attr:hidden` on the error text is the link to the component: it sets
|
|
321
|
+
`hidden` when the field is valid and removes it when it is invalid, and
|
|
322
|
+
`<lt-field>` counts the field as invalid when the error text is visible. None
|
|
323
|
+
of the React pitfalls exist here. Datastar works directly on the attributes.
|
|
324
|
+
|
|
325
|
+
## 6. HTML from the server
|
|
326
|
+
|
|
327
|
+
Datastar can let the server send HTML as the page runs, over Server-Sent
|
|
328
|
+
Events. A web component upgrades itself when it is inserted into the document,
|
|
329
|
+
as long as `defineLtField()` has run once. The server can therefore send this
|
|
330
|
+
as plain HTML:
|
|
331
|
+
|
|
332
|
+
```html
|
|
333
|
+
<lt-field>
|
|
334
|
+
<label class="lt-label" for="email" data-required="text">Email address</label>
|
|
335
|
+
<input class="lt-input" id="email" type="email" value="alex@" />
|
|
336
|
+
<p class="lt-help-text">We will send the receipt here.</p>
|
|
337
|
+
<p class="lt-error-text">Enter a valid address.</p>
|
|
338
|
+
</lt-field>
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
The component then gives the help text and the error text ids, adds
|
|
342
|
+
`aria-invalid` because the error text is visible, and builds
|
|
343
|
+
`aria-describedby`, without any JavaScript being sent for this particular
|
|
344
|
+
field. That is the point of the `frame` components living in plain DOM: the
|
|
345
|
+
markup is the data, and the accessibility is wired where it lands.
|
|
346
|
+
|
|
347
|
+
If the server patches a component that holds state, the question is what
|
|
348
|
+
decides it. By default the web component does: `<lt-tabs>` remembers the tab
|
|
349
|
+
the user selected, and puts it back after a patch. `outer` and `inner` morph,
|
|
350
|
+
so the links are kept and the selection with them. `replace` replaces the
|
|
351
|
+
nodes, and then the component selects the tab the server marked with
|
|
352
|
+
`aria-selected="true"`, otherwise the one the URL points to, otherwise the one
|
|
353
|
+
whose panel the server left without `hidden`, otherwise the first. And a morph
|
|
354
|
+
keeps an element only when the ids match: an element with an id the server did
|
|
355
|
+
not send is replaced. The components therefore never write an id on what the
|
|
356
|
+
user touches. The tabs are links without an id, and the panels have the id the
|
|
357
|
+
link points to, the same on every render, as `lt.tabs()` writes it. The panel
|
|
358
|
+
in `<lt-popover>` needs an id in the same way; the component creates none. The
|
|
359
|
+
control in `<lt-field>` and the field in `<lt-suggestion>` never get an id
|
|
360
|
+
from the component: the template writes `for` and `id`, which HTML requires
|
|
361
|
+
for the field to have a name without JavaScript, or the label wraps the field
|
|
362
|
+
and no id is needed. `<lt-field>` and `<lt-suggestion>` warn in the console
|
|
363
|
+
when a patch replaces the field with one that has another id, the same `name`
|
|
364
|
+
and another value, and `<lt-popover>` when a patch replaces the open panel
|
|
365
|
+
with one that has another id. `<lt-tabs>` repairs the selection without a
|
|
366
|
+
word. If the server should be able to move the tab, say so with
|
|
367
|
+
`server-controlled`:
|
|
368
|
+
|
|
369
|
+
```html
|
|
370
|
+
<lt-tabs server-controlled data-on:tab-select="$tab = evt.detail.index">
|
|
371
|
+
<ul class="lt-tabs__list" aria-label="Parts of the case">
|
|
372
|
+
<li><a href="#application">Application</a></li>
|
|
373
|
+
<li><a href="#attachments">Attachments</a></li>
|
|
374
|
+
</ul>
|
|
375
|
+
<section class="lt-tabs__panel" id="application">…</section>
|
|
376
|
+
<section class="lt-tabs__panel" id="attachments" hidden="until-found">…</section>
|
|
377
|
+
</lt-tabs>
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
The attribute exists on `<lt-tabs>`, `<lt-popover>`, `<lt-dialog>` and
|
|
381
|
+
`<lt-suggestion>`. Without it the server and the component would fight over
|
|
382
|
+
the same state.
|
|
383
|
+
|
|
384
|
+
`lt` can be used on the server or in a build step. Datastar does not need it
|
|
385
|
+
in the browser.
|
|
386
|
+
|
|
387
|
+
## Known pitfalls
|
|
388
|
+
|
|
389
|
+
| Symptom | Cause |
|
|
390
|
+
| --- | --- |
|
|
391
|
+
| The styles are missing | The `<link>` to `lotek.css` is missing, or its address answers 404. With one stylesheet per component instead, `tokens.css` is not loaded |
|
|
392
|
+
| An `<lt-toast>` or `<lt-connection-status>` shows nothing, an `<lt-session-timeout>` never warns, or another component does nothing | The `define` function has not run. `<lt-toast>` and `<lt-connection-status>` create their content themselves and are empty without it, and `<lt-session-timeout>` does not count the time. The markup in the others comes from you and is there regardless, with two exceptions until they are registered. `<lt-tabs>` shows one panel: of those the server left without `hidden`, the one the URL points to, otherwise the first, and under `server-controlled` always the first. `<lt-suggestion>` hides the list |
|
|
393
|
+
| A component speaks English on a page in another language | The text in the markup comes from you, and is written with the app's own translation setup. The few default texts the package has are replaced with `label` and `close-label` on `<lt-toast>`, `offline-text` and `online-text` on `<lt-connection-status>`, `count-none`, `count-one` and `count-other` on `<lt-suggestion>`, and `--lt-label-required-text`, `--lt-label-optional-text` and `--lt-label-required-symbol` in CSS. Numbers and durations follow the nearest `lang`, usually the one on `<html>`. See https://lo-tek.sobernetics.no/translation/ |
|
|
394
|
+
| The error text never shows, and the field counts as valid | `hidden="false"` is set on the error text, and it hides it all the same. The attribute must be removed, not set to `false` |
|
|
395
|
+
| `SyntaxError` in the browser | TypeScript syntax in a `<script type="module">` without a build step |
|
|
396
|
+
|
|
397
|
+
## When CSS is not enough
|
|
398
|
+
|
|
399
|
+
The components are customised with tokens and `--lt-` variables. If that is
|
|
400
|
+
not enough, `npx @lo-tek/interfaces takeover <component>` copies the source
|
|
401
|
+
code of one component into `src/lotek/<component>/`, so the code is yours to
|
|
402
|
+
change. The copy is TypeScript that imports from the package by name, so it
|
|
403
|
+
needs a build step. It is renamed from `lt-` to `app-`, and a
|
|
404
|
+
`lotek-manifest.json` next to it teaches the check the new names:
|
|
405
|
+
`npx @lo-tek/interfaces check --manifest=src/lotek/<component>/lotek-manifest.json <files>`.
|
|
406
|
+
A complete colour theme from your brand colours is made with
|
|
407
|
+
`npx @lo-tek/interfaces theme`.
|
|
408
|
+
|
|
409
|
+
All of this, with live examples: https://lo-tek.sobernetics.no/
|