@aceshooting/lyra-ui 27.0.0 → 28.0.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 +55 -63
- package/README.md +7 -3
- package/dist/cli/css-declarations.mjs +1 -0
- package/dist/cli/lyra-rename-ledger.mjs +1 -1
- package/dist/cli/migrate-wa.mjs +9 -4
- package/dist/cli/migration-contract.json +1 -1
- package/dist/cli/migration-renames.mjs +2 -2
- package/dist/cli/migration-theme-scopes.mjs +3 -0
- package/dist/cli/theme-scope-vocabulary.generated.mjs +1 -0
- package/dist/components/agent-tools/activity-feed/activity-feed.class.js +1 -1
- package/dist/components/agent-tools/agent-eval-dashboard/agent-eval-dashboard.class.js +1 -1
- package/dist/components/agent-tools/agent-question/agent-question.class.js +1 -1
- package/dist/components/agent-tools/agent-run/agent-run.class.js +1 -1
- package/dist/components/agent-tools/agent-trace/agent-trace.class.js +1 -1
- package/dist/components/agent-tools/approval-queue/approval-queue.class.js +1 -1
- package/dist/components/agent-tools/artifact-panel/artifact-panel.class.js +1 -1
- package/dist/components/agent-tools/background-runs/background-runs.class.js +1 -1
- package/dist/components/agent-tools/browser-frame/browser-frame.class.js +1 -1
- package/dist/components/agent-tools/budget-meter/budget-meter.class.js +1 -1
- package/dist/components/agent-tools/change-review/change-review.class.js +1 -1
- package/dist/components/agent-tools/commit-card/commit-card.class.js +1 -1
- package/dist/components/agent-tools/compare-panel/compare-panel.class.js +1 -1
- package/dist/components/agent-tools/confirm-bar/confirm-bar.class.js +1 -1
- package/dist/components/agent-tools/connector-manager/connector-manager.class.js +1 -1
- package/dist/components/agent-tools/context-inspector/context-inspector.class.js +1 -1
- package/dist/components/agent-tools/eval-dataset/eval-dataset.class.js +1 -1
- package/dist/components/agent-tools/eval-result/eval-result.class.js +1 -1
- package/dist/components/agent-tools/evaluation-run/evaluation-run.class.js +1 -1
- package/dist/components/agent-tools/mcp-app/mcp-app.class.js +1 -1
- package/dist/components/agent-tools/permission-grant/permission-grant.class.js +1 -1
- package/dist/components/agent-tools/permission-rules/permission-rules.class.js +1 -1
- package/dist/components/agent-tools/policy-summary/policy-summary.class.js +1 -1
- package/dist/components/agent-tools/prompt-studio/prompt-studio.class.js +1 -1
- package/dist/components/agent-tools/result-card/result-field.class.js +1 -1
- package/dist/components/agent-tools/schema-viewer/schema-viewer.class.js +1 -1
- package/dist/components/agent-tools/span-waterfall/span-waterfall.class.js +1 -1
- package/dist/components/agent-tools/stack-trace/stack-trace.class.js +1 -1
- package/dist/components/agent-tools/subagent-panel/subagent-panel.class.js +2 -2
- package/dist/components/agent-tools/task-list/task-list.class.js +2 -2
- package/dist/components/agent-tools/terminal/terminal.class.js +1 -1
- package/dist/components/agent-tools/test-results/test-results.class.js +1 -1
- package/dist/components/agent-tools/thinking-panel/thinking-panel.class.js +1 -1
- package/dist/components/agent-tools/tool-approval-dialog/tool-approval-dialog.class.js +1 -1
- package/dist/components/agent-tools/tool-call-block/tool-call-block.class.js +1 -1
- package/dist/components/agent-tools/tool-call-chip/tool-call-chip.class.js +1 -1
- package/dist/components/agent-tools/tool-param-form/tool-param-form.class.js +1 -1
- package/dist/components/agent-tools/tool-result-dialog/tool-result-dialog.class.js +1 -1
- package/dist/components/agent-tools/tool-result-view/tool-result-view.class.js +1 -1
- package/dist/components/agent-tools/tool-select-dialog/tool-select-dialog.class.js +1 -1
- package/dist/components/agent-tools/tool-timeline/tool-timeline.class.js +1 -1
- package/dist/components/agent-tools/trace-tree/trace-tree.class.js +2 -2
- package/dist/components/charts/chart/box-plot.class.js +1 -1
- package/dist/components/charts/chart/chart-token-cache.js +2 -2
- package/dist/components/charts/chart/chart.class.d.ts +1 -1
- package/dist/components/charts/chart/chart.class.js +3 -3
- package/dist/components/charts/chart/histogram.class.js +1 -1
- package/dist/components/charts/chart/lite-chart.class.js +1 -1
- package/dist/components/conversation/agent-workspace/agent-workspace.class.js +1 -1
- package/dist/components/conversation/audio-visualizer/audio-visualizer.class.js +1 -1
- package/dist/components/conversation/branch-picker/branch-picker.class.js +1 -1
- package/dist/components/conversation/chat-composer/chat-composer.class.js +1 -1
- package/dist/components/conversation/chat-message/chat-message.class.js +1 -1
- package/dist/components/conversation/chat-viewport/chat-viewport.class.js +1 -1
- package/dist/components/conversation/checkpoint/checkpoint.class.js +1 -1
- package/dist/components/conversation/code-block/code-block-base.class.js +1 -1
- package/dist/components/conversation/code-block/code-block-core.class.js +1 -1
- package/dist/components/conversation/code-block/code-block.class.js +1 -1
- package/dist/components/conversation/conversation-item/conversation-item.class.js +1 -1
- package/dist/components/conversation/generation-metrics/generation-metrics.class.js +1 -1
- package/dist/components/conversation/handoff-divider/handoff-divider.class.js +1 -1
- package/dist/components/conversation/markdown/markdown-base.class.js +1 -1
- package/dist/components/conversation/markdown/markdown-core.class.js +1 -1
- package/dist/components/conversation/markdown/markdown.class.js +1 -1
- package/dist/components/conversation/message-actions/message-actions.class.js +1 -1
- package/dist/components/conversation/message-feedback/message-feedback.class.js +1 -1
- package/dist/components/conversation/message-parts/message-parts.class.js +1 -1
- package/dist/components/conversation/model-select/model-select.class.js +1 -1
- package/dist/components/conversation/model-settings-panel/model-settings-panel.class.js +1 -1
- package/dist/components/conversation/prompt-input/prompt-input.class.js +1 -1
- package/dist/components/conversation/prompt-queue/prompt-queue.class.js +1 -1
- package/dist/components/conversation/push-to-talk/push-to-talk.class.js +1 -1
- package/dist/components/conversation/realtime-session/realtime-session.class.js +1 -1
- package/dist/components/conversation/selection-toolbar/selection-toolbar.class.js +1 -1
- package/dist/components/conversation/stream-status/stream-status.class.js +1 -1
- package/dist/components/conversation/suggestion-chips/suggestion-chips.class.js +1 -1
- package/dist/components/conversation/thread-list/thread-list.class.js +1 -1
- package/dist/components/conversation/transcript-feed/transcript-feed.class.js +1 -1
- package/dist/components/conversation/typing-indicator/typing-indicator.class.js +1 -1
- package/dist/components/conversation/usage-badge/usage-badge.class.js +1 -1
- package/dist/components/conversation/voice-picker/voice-picker.class.js +1 -1
- package/dist/components/data/calendar/calendar.class.js +1 -1
- package/dist/components/data/condition-builder/condition-builder.class.js +1 -1
- package/dist/components/data/context-meter/context-meter.class.js +1 -1
- package/dist/components/data/data-grid/data-grid.class.d.ts +2 -2
- package/dist/components/data/data-grid/data-grid.class.js +3 -3
- package/dist/components/data/document-library/document-library.class.js +1 -1
- package/dist/components/data/env-list/env-list.class.js +1 -1
- package/dist/components/data/file-tree/file-tree.class.d.ts +2 -2
- package/dist/components/data/file-tree/file-tree.class.js +1 -1
- package/dist/components/data/flow-canvas/flow-canvas.class.js +1 -1
- package/dist/components/data/flow-controls/flow-controls.class.js +1 -1
- package/dist/components/data/flow-minimap/flow-minimap.class.js +1 -1
- package/dist/components/data/flow-node/flow-node.class.js +1 -1
- package/dist/components/data/flow-run-status/flow-run-status.class.js +1 -1
- package/dist/components/data/funnel/funnel.class.js +1 -1
- package/dist/components/data/gauge/gauge.class.js +1 -1
- package/dist/components/data/graph-query-builder/graph-query-builder.class.js +1 -1
- package/dist/components/data/heatmap/heatmap.class.js +1 -1
- package/dist/components/data/pagination/pagination.class.d.ts +2 -0
- package/dist/components/data/pagination/pagination.class.js +1 -1
- package/dist/components/data/pagination/pagination.styles.js +1 -1
- package/dist/components/data/sequence-strip/sequence-strip.class.js +1 -1
- package/dist/components/data/sparkline/sparkline.class.js +1 -1
- package/dist/components/data/stat/stat.class.js +1 -1
- package/dist/components/data/table/table.class.d.ts +23 -2
- package/dist/components/data/table/table.class.js +5 -3
- package/dist/components/data/table/table.styles.js +1 -1
- package/dist/components/data/timeline/timeline.class.js +1 -1
- package/dist/components/data/tree/tree.class.js +1 -1
- package/dist/components/data/word-cloud/word-cloud.class.js +1 -1
- package/dist/components/forms/button/button.class.js +1 -1
- package/dist/components/forms/checkbox/checkbox.class.js +1 -1
- package/dist/components/forms/checkbox-group/checkbox-group.class.js +1 -1
- package/dist/components/forms/code-editor/code-editor.class.js +1 -1
- package/dist/components/forms/color-picker/color-picker.class.d.ts +8 -4
- package/dist/components/forms/color-picker/color-picker.class.js +2 -2
- package/dist/components/forms/combobox/combobox.class.js +1 -1
- package/dist/components/forms/country-picker/country-picker.class.js +1 -1
- package/dist/components/forms/currency-picker/currency-picker.class.js +1 -1
- package/dist/components/forms/date-picker/date-input.class.js +1 -1
- package/dist/components/forms/date-picker/date-picker.class.js +1 -1
- package/dist/components/forms/emoji-picker/emoji-data-loader.js +1 -1
- package/dist/components/forms/emoji-picker/emoji-picker.class.d.ts +7 -4
- package/dist/components/forms/emoji-picker/emoji-picker.class.js +5 -5
- package/dist/components/forms/icon-button/icon-button.class.d.ts +4 -0
- package/dist/components/forms/icon-button/icon-button.class.js +1 -1
- package/dist/components/forms/icon-button/icon-button.styles.js +1 -1
- package/dist/components/forms/input/input-shared.js +1 -1
- package/dist/components/forms/input/input.class.js +1 -1
- package/dist/components/forms/input/native-time-input.class.js +1 -1
- package/dist/components/forms/input/number-input.class.js +1 -1
- package/dist/components/forms/input/time-input.class.js +1 -1
- package/dist/components/forms/locale-picker/locale-picker.class.js +1 -1
- package/dist/components/forms/otp-input/otp-input.class.js +1 -1
- package/dist/components/forms/phone-input/phone-input.class.js +1 -1
- package/dist/components/forms/radio/radio-group.class.js +1 -1
- package/dist/components/forms/radio/radio.class.js +1 -1
- package/dist/components/forms/rubric-form/rubric-form.class.js +4 -4
- package/dist/components/forms/select/select.class.js +1 -1
- package/dist/components/forms/signature-pad/signature-pad.class.js +1 -1
- package/dist/components/forms/slider/slider.class.js +1 -1
- package/dist/components/forms/switch/switch.class.js +1 -1
- package/dist/components/forms/textarea/textarea.class.js +1 -1
- package/dist/components/forms/time-range/time-range.class.js +1 -1
- package/dist/components/forms/time-zone-picker/time-zone-picker.class.js +1 -1
- package/dist/components/forms/token-input/token-input.class.js +1 -1
- package/dist/components/forms/unit-picker/unit-picker.class.js +1 -1
- package/dist/components/layout/app-rail/app-rail-item.class.js +1 -1
- package/dist/components/layout/app-rail/app-rail.class.d.ts +70 -7
- package/dist/components/layout/app-rail/app-rail.class.js +16 -4
- package/dist/components/layout/app-rail/app-rail.styles.js +1 -1
- package/dist/components/layout/app-rail-group/app-rail-group.class.js +1 -1
- package/dist/components/layout/breadcrumb/breadcrumb.class.js +1 -1
- package/dist/components/layout/card/card.class.js +1 -1
- package/dist/components/layout/carousel/carousel.class.js +1 -1
- package/dist/components/layout/command-palette/command-palette.class.js +1 -1
- package/dist/components/layout/dashboard-grid/dashboard-grid.class.js +1 -1
- package/dist/components/layout/details/accordion-item.class.js +1 -1
- package/dist/components/layout/details/details.class.js +1 -1
- package/dist/components/layout/dock-panel/dock-panel.class.js +1 -1
- package/dist/components/layout/drilldown-panel/drilldown-panel.class.js +1 -1
- package/dist/components/layout/filter-bar/filter-bar.class.js +1 -1
- package/dist/components/layout/menu/menu.class.js +1 -1
- package/dist/components/layout/menubar/menubar.class.js +1 -1
- package/dist/components/layout/multi-split/multi-split.class.js +1 -1
- package/dist/components/layout/navigation-menu/navigation-menu.class.js +1 -1
- package/dist/components/layout/page/page.class.js +1 -1
- package/dist/components/layout/reorder-list/reorder-item.class.js +1 -1
- package/dist/components/layout/reorder-list/reorder-list.class.js +1 -1
- package/dist/components/layout/responsive-panel/responsive-panel.class.js +1 -1
- package/dist/components/layout/scroller/scroller.class.js +1 -1
- package/dist/components/layout/segmented/segmented.class.d.ts +7 -4
- package/dist/components/layout/segmented/segmented.styles.js +1 -1
- package/dist/components/layout/split-panel/split-panel.class.js +1 -1
- package/dist/components/layout/tab-group/tab-group.class.js +1 -1
- package/dist/components/layout/tab-group/tab.class.js +1 -1
- package/dist/components/layout/virtual-list/virtual-list.styles.js +1 -1
- package/dist/components/layout/widget/widget.class.js +1 -1
- package/dist/components/media/animated-image/animated-image.class.js +1 -1
- package/dist/components/media/attachment-chip/attachment-chip.class.js +1 -1
- package/dist/components/media/attachment-trigger/attachment-trigger.class.js +2 -2
- package/dist/components/media/av-player/av-player.class.js +1 -1
- package/dist/components/media/avatar-group/avatar-group.class.js +1 -1
- package/dist/components/media/drop-zone/drop-zone.class.js +1 -1
- package/dist/components/media/file-icon/file-icon.class.js +1 -1
- package/dist/components/media/file-input/file-input.class.js +1 -1
- package/dist/components/media/flag/flag.class.js +1 -1
- package/dist/components/media/image-comparer/image-comparer.class.js +1 -1
- package/dist/components/media/image-viewer/image-viewer.class.d.ts +2 -1
- package/dist/components/media/image-viewer/image-viewer.class.js +4 -2
- package/dist/components/media/image-viewer/image-viewer.styles.js +1 -1
- package/dist/components/media/lightbox/lightbox.class.js +1 -1
- package/dist/components/media/map/map.class.js +1 -1
- package/dist/components/media/media-card/media-card.class.js +1 -1
- package/dist/components/media/pan-zoom/pan-zoom.class.js +1 -1
- package/dist/components/media/qr-code/qr-code.class.d.ts +2 -2
- package/dist/components/media/qr-code/qr-code.class.js +1 -1
- package/dist/components/media/sequence-playback/sequence-playback.class.js +1 -1
- package/dist/components/media/video/video.class.js +1 -1
- package/dist/components/media/video-playlist/video-playlist.class.js +1 -1
- package/dist/components/media/zoomable-frame/zoomable-frame.class.js +1 -1
- package/dist/components/overlays/alert/alert.class.js +1 -1
- package/dist/components/overlays/badge/tag.class.js +1 -1
- package/dist/components/overlays/callout/callout.class.js +1 -1
- package/dist/components/overlays/chip/chip-group.class.js +1 -1
- package/dist/components/overlays/chip/chip.class.js +1 -1
- package/dist/components/overlays/context-menu/context-menu.class.js +1 -1
- package/dist/components/overlays/dialog/confirm.js +1 -1
- package/dist/components/overlays/dialog/dialog.class.js +1 -1
- package/dist/components/overlays/kbd/kbd.class.js +1 -1
- package/dist/components/overlays/overlay/popover.class.js +1 -1
- package/dist/components/overlays/overlay/tooltip.class.js +1 -1
- package/dist/components/overlays/progress/progress-bar.class.js +1 -1
- package/dist/components/overlays/progress/progress-ring.class.js +1 -1
- package/dist/components/overlays/rating/rating.class.js +1 -1
- package/dist/components/overlays/skeleton/skeleton.class.js +1 -1
- package/dist/components/overlays/spinner/spinner.class.js +1 -1
- package/dist/components/overlays/toast/toast-item.class.js +1 -1
- package/dist/components/overlays/toast/toast.class.js +1 -1
- package/dist/components/retrieval/chunk-inspector/chunk-inspector.class.js +1 -1
- package/dist/components/retrieval/citation-badge/citation-badge.class.js +1 -1
- package/dist/components/retrieval/claim-evidence/claim-evidence.class.js +1 -1
- package/dist/components/retrieval/community-card/community-card.class.js +1 -1
- package/dist/components/retrieval/embedding-explorer/embedding-explorer.class.js +1 -1
- package/dist/components/retrieval/entity-card/entity-card.class.js +1 -1
- package/dist/components/retrieval/entity-chip/entity-chip.class.js +1 -1
- package/dist/components/retrieval/entity-dossier/entity-dossier.class.js +1 -1
- package/dist/components/retrieval/graph/graph.class.js +1 -1
- package/dist/components/retrieval/graph-legend/graph-legend.class.js +1 -1
- package/dist/components/retrieval/grounding-summary/grounding-summary.class.js +2 -2
- package/dist/components/retrieval/ingestion-queue/ingestion-queue.class.js +1 -1
- package/dist/components/retrieval/knowledge-base/knowledge-base.class.js +1 -1
- package/dist/components/retrieval/knowledge-base-admin/knowledge-base-admin.class.js +1 -1
- package/dist/components/retrieval/knowledge-graph-explorer/knowledge-graph-explorer.class.js +1 -1
- package/dist/components/retrieval/memory-panel/memory-panel.class.js +1 -1
- package/dist/components/retrieval/mind-map/mind-map.class.js +1 -1
- package/dist/components/retrieval/neighbor-list/neighbor-list.class.js +1 -1
- package/dist/components/retrieval/node-palette/node-palette.class.js +1 -1
- package/dist/components/retrieval/path-strip/path-strip.class.js +1 -1
- package/dist/components/retrieval/provenance-panel/provenance-panel.class.js +1 -1
- package/dist/components/retrieval/rag-answer/rag-answer.class.js +1 -1
- package/dist/components/retrieval/rag-eval-dashboard/rag-eval-dashboard.class.js +1 -1
- package/dist/components/retrieval/research-progress/research-progress.class.js +1 -1
- package/dist/components/retrieval/retrieval-compare/retrieval-compare.class.js +1 -1
- package/dist/components/retrieval/retrieval-results/retrieval-results.class.js +1 -1
- package/dist/components/retrieval/retrieval-search/retrieval-search.class.js +1 -1
- package/dist/components/retrieval/retrieval-trace/retrieval-trace.class.js +1 -1
- package/dist/components/retrieval/source-card/source-card.class.js +1 -1
- package/dist/components/retrieval/source-list/source-list.class.js +1 -1
- package/dist/components/retrieval/source-picker/source-picker.class.js +1 -1
- package/dist/components/utility/copy-button/copy-button.class.js +1 -1
- package/dist/components/utility/diff-view/diff-view.class.js +1 -1
- package/dist/components/utility/export-button/export-button.class.js +1 -1
- package/dist/components/utility/icon/icon.class.js +1 -1
- package/dist/components/utility/json-viewer/json-viewer.class.js +1 -1
- package/dist/components/utility/known-date/known-date.class.js +1 -1
- package/dist/components/utility/mention-popover/mention-popover.class.js +1 -1
- package/dist/components/utility/poll-status/poll-status.class.js +1 -1
- package/dist/components/utility/random-content/random-content.class.js +1 -1
- package/dist/components/utility/tour/tour.class.js +1 -1
- package/dist/components/viewers/archive-viewer/archive-viewer.class.js +1 -1
- package/dist/components/viewers/calendar-viewer/calendar-viewer.class.js +1 -1
- package/dist/components/viewers/contact-viewer/contact-viewer.class.js +1 -1
- package/dist/components/viewers/csv-viewer/csv-viewer.class.js +1 -1
- package/dist/components/viewers/dataset-viewer/dataset-viewer.class.js +2 -2
- package/dist/components/viewers/document-compare/document-compare.class.js +1 -1
- package/dist/components/viewers/document-preview/document-preview.class.js +1 -1
- package/dist/components/viewers/document-viewer/document-viewer.class.js +1 -1
- package/dist/components/viewers/docx-viewer/docx-viewer.class.js +1 -1
- package/dist/components/viewers/ebook-viewer/ebook-viewer.class.js +1 -1
- package/dist/components/viewers/email-viewer/email-viewer.class.js +1 -1
- package/dist/components/viewers/geojson-view/geojson-view.class.js +1 -1
- package/dist/components/viewers/geojson-view/geojson-viewer.class.js +1 -1
- package/dist/components/viewers/highlight-layer/highlight-layer.class.js +1 -1
- package/dist/components/viewers/html-viewer/html-viewer.class.js +1 -1
- package/dist/components/viewers/include/include.class.js +1 -1
- package/dist/components/viewers/notebook-viewer/notebook-viewer.class.js +1 -1
- package/dist/components/viewers/page-rail/page-rail.class.d.ts +1 -1
- package/dist/components/viewers/page-rail/page-rail.class.js +3 -3
- package/dist/components/viewers/pdf-viewer/pdf-viewer.class.d.ts +2 -2
- package/dist/components/viewers/pdf-viewer/pdf-viewer.class.js +2 -2
- package/dist/components/viewers/pptx-viewer/pptx-viewer.class.js +1 -1
- package/dist/components/viewers/spreadsheet-viewer/spreadsheet-viewer.class.js +1 -1
- package/dist/components/viewers/svg-viewer/svg-viewer.class.js +1 -1
- package/dist/components/viewers/xml-viewer/xml-viewer.class.js +1 -1
- package/dist/events.d.ts +6 -1
- package/dist/framework-types.d.ts +1 -1
- package/dist/internal/accessibility-visibility.js +1 -1
- package/dist/internal/collection-snapshot.js +1 -1
- package/dist/internal/default-strings/agent-tools.generated.js +1 -0
- package/dist/internal/default-strings/charts.generated.js +1 -0
- package/dist/internal/default-strings/conversation.generated.js +1 -0
- package/dist/internal/default-strings/data.generated.js +1 -0
- package/dist/internal/default-strings/forms.generated.js +1 -0
- package/dist/internal/default-strings/layout.generated.js +1 -0
- package/dist/internal/default-strings/media.generated.js +1 -0
- package/dist/internal/default-strings/overlays.generated.js +1 -0
- package/dist/internal/default-strings/retrieval.generated.js +1 -0
- package/dist/internal/default-strings/shared.generated.js +1 -0
- package/dist/internal/default-strings/utility.generated.js +1 -0
- package/dist/internal/default-strings/viewers.generated.js +5 -0
- package/dist/internal/dev-mode-attribute-warning.development.js +1 -1
- package/dist/internal/dev-mode-attribute-warning.production.js +1 -1
- package/dist/internal/document-tokens.d.ts +11 -0
- package/dist/internal/document-tokens.generated.js +15 -0
- package/dist/internal/document-tokens.js +3 -0
- package/dist/internal/form-associated.d.ts +1 -1
- package/dist/internal/form-associated.js +1 -1
- package/dist/internal/glass-surface.styles.js +1 -1
- package/dist/internal/host-tokens.styles.js +1 -0
- package/dist/internal/image-zoom.js +1 -0
- package/dist/internal/intl-cache.js +1 -1
- package/dist/internal/localization-types.d.ts +1 -1
- package/dist/internal/localization.js +2 -2
- package/dist/internal/lyra-element.d.ts +4 -2
- package/dist/internal/lyra-element.js +2 -2
- package/dist/internal/opaque-content-border.styles.js +1 -1
- package/dist/internal/open-overlay-raise.styles.js +1 -0
- package/dist/internal/optional-peer-failure.js +1 -0
- package/dist/internal/package-metadata.js +1 -1
- package/dist/internal/prefix.js +1 -1
- package/dist/internal/specialist-host-tokens.styles.js +1 -0
- package/dist/internal/specialist-tokens.generated.js +2 -0
- package/dist/internal/step-value.js +1 -1
- package/dist/internal/theme-observation.js +1 -1
- package/dist/internal/theme-scopes.d.ts +11 -0
- package/dist/internal/theme-scopes.js +1 -0
- package/dist/looks/shadcn.css +1 -1
- package/dist/lyra.d.ts +1 -1
- package/dist/lyra.js +1 -1
- package/dist/styles/design-tokens.css +1 -1
- package/dist/styles/tokens-root.css +1 -1
- package/dist/surfaces/glass.css +1 -1
- package/dist/testing/happy-dom-shims.d.ts +21 -2
- package/dist/testing/happy-dom-shims.js +1 -1
- package/dist/testing/index.d.ts +1 -1
- package/dist/testing/index.js +1 -1
- package/dist/testing/interaction-drivers.d.ts +66 -7
- package/dist/testing/interaction-drivers.js +1 -1
- package/dist/testing/jsdom-shims.d.ts +70 -0
- package/dist/testing/jsdom-shims.js +1 -0
- package/dist/theme/look-inputs.d.ts +1 -1
- package/dist/theme/look-inputs.js +37 -41
- package/dist/theme/theme.d.ts +13 -0
- package/dist/theme/theme.js +1 -1
- package/dist/theme.css +1 -1
- package/dist/utilities/index.d.ts +1 -1
- package/dist/utilities/index.js +1 -1
- package/dist/utilities/scoped-registry.d.ts +3 -0
- package/dist/utilities/scoped-registry.js +1 -1
- package/dist/utilities/theme-scopes.d.ts +1 -0
- package/dist/utilities/theme-scopes.js +1 -0
- package/dist/utilities/tokens.d.ts +1 -0
- package/dist/utilities/tokens.js +1 -0
- package/llms/components/lr-app-rail.md +51 -4
- package/llms/components/lr-emoji-picker.md +13 -8
- package/llms/components/lr-icon-button.md +13 -1
- package/llms/components/lr-image-viewer.md +8 -0
- package/llms/components/lr-pagination.md +4 -2
- package/llms/components/lr-segmented.md +7 -3
- package/llms/components/lr-table.md +14 -12
- package/llms/components/lr-thread-list.md +4 -3
- package/llms/migration.md +9 -0
- package/llms/peers.md +1 -1
- package/llms/shared/events-and-types.md +41 -0
- package/llms/shared/frameworks-and-ssr.md +16 -0
- package/llms/shared/imports-and-registration.md +4 -3
- package/llms/shared/native-styles-and-utilities.md +38 -3
- package/llms/shared/styles-and-tokens.md +242 -102
- package/llms/shared/testing-and-utilities.md +90 -6
- package/llms/shared.md +431 -114
- package/llms/tokens.md +31 -49
- package/locales.json +138 -138
- package/package.json +14 -7
- package/registrations.json +1 -1
- package/dist/internal/default-strings.generated.js +0 -5
- package/dist/internal/specialist-tokens.styles.js +0 -1
- package/dist/internal/tokens/palette.styles.js +0 -1
- package/dist/internal/tokens.styles.js +0 -1
package/llms/shared.md
CHANGED
|
@@ -184,11 +184,12 @@ The entry points, then:
|
|
|
184
184
|
- **`lr-flag`** registers from the barrel, but resolving a flag by `country`/`language` (rather than
|
|
185
185
|
a pre-resolved `src`) additionally needs
|
|
186
186
|
`import '@aceshooting/lyra-ui/components/media/flag/flag-peer.js';` once.
|
|
187
|
-
- **Other subpaths.** `@aceshooting/lyra-ui/theme.css` (ready-made light/dark theme
|
|
187
|
+
- **Other subpaths.** `@aceshooting/lyra-ui/theme.css` (ready-made light/dark theme, including the
|
|
188
|
+
document token layer),
|
|
188
189
|
`@aceshooting/lyra-ui/looks/shadcn.css` (opt-in shadcn/ui look, imported after `theme.css` — see
|
|
189
190
|
[The shadcn look](#the-shadcn-look--looksshadcncss)),
|
|
190
|
-
`@aceshooting/lyra-ui/tokens-root.css` (
|
|
191
|
-
|
|
191
|
+
`@aceshooting/lyra-ui/tokens-root.css` (the document token layer alone, for pages that do not
|
|
192
|
+
use `theme.css`; link one of the two, not both),
|
|
192
193
|
`@aceshooting/lyra-ui/native.css` (opt-in native-element styles inside `.lr-native`),
|
|
193
194
|
`@aceshooting/lyra-ui/utilities.css` (opt-in light-DOM layout/text/typography utilities),
|
|
194
195
|
`@aceshooting/lyra-ui/theme.js` (the zero-dependency style runtime),
|
|
@@ -880,17 +881,18 @@ Three layers, and **which one you set decides how far the override reaches**:
|
|
|
880
881
|
3. **`--lr-<component>-*`** — per-component properties, for one element at a time. Listed in each
|
|
881
882
|
component's own section.
|
|
882
883
|
|
|
883
|
-
**Layer 2 (`--lr-*`) is declared
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
[`tokens-root.css`](#reading-the-resolved-tokens-from-your-own-components--tokens-rootcss)
|
|
890
|
-
|
|
884
|
+
**Layer 2 (`--lr-*`) is declared once per document, not on each component** (since 28.0.0). The
|
|
885
|
+
_document token layer_ declares every shared output on `:root` and re-derives it only at
|
|
886
|
+
[theme scopes](#theme-scopes). `theme.css` carries it, so a page that imports `theme.css` has it from
|
|
887
|
+
first paint; on a page without `theme.css`, registering the first `lr-*` element adopts the same text
|
|
888
|
+
as a constructed stylesheet. Components inherit the result, and so do your own elements —
|
|
889
|
+
`body { color: var(--lr-color-text) }` resolves everywhere the layer applies.
|
|
890
|
+
[`tokens-root.css`](#reading-the-resolved-tokens-from-your-own-components--tokens-rootcss) is the
|
|
891
|
+
layer alone, for pages that do not use `theme.css`. Retheme through layer 1 (`--lr-theme-*`) **on a theme scope**: `:root`, a
|
|
892
|
+
mode scope, a style-axis boundary, or any element marked `data-lr-theme-scope`.
|
|
891
893
|
See [Where an override actually reaches](#where-an-override-actually-reaches) below for the full
|
|
892
|
-
inheritance rules, including
|
|
893
|
-
|
|
894
|
+
inheritance rules, including per-component `--lr-<component>-*` hooks (layer 3), which inherit
|
|
895
|
+
through wrappers.
|
|
894
896
|
|
|
895
897
|
### Lyra signature starter
|
|
896
898
|
|
|
@@ -904,7 +906,6 @@ mode; `accent: null` explicitly clears the accent, while `resetLyraStyle()` rest
|
|
|
904
906
|
@layer lr-base, lr-theme, lr-theme-preset, lr-utilities, lr-overrides;
|
|
905
907
|
@layer lr-theme-preset.look, lr-theme-preset.density, lr-theme-preset.surface, lr-theme-preset.accent, lr-theme-preset.mode;
|
|
906
908
|
@import "@aceshooting/lyra-ui/theme.css";
|
|
907
|
-
@import "@aceshooting/lyra-ui/tokens-root.css";
|
|
908
909
|
```
|
|
909
910
|
|
|
910
911
|
Keep both layer-order statements before these imports. Bundlers can hoist statements from imported
|
|
@@ -1084,20 +1085,35 @@ design launcher. Keep these layout rules shared across application headers and a
|
|
|
1084
1085
|
|
|
1085
1086
|
### Reading the resolved tokens from your own components — `tokens-root.css`
|
|
1086
1087
|
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1088
|
+
Since 28.0.0 the resolved layer lives in the document, so your own elements read it like any
|
|
1089
|
+
component does: `var(--lr-color-border)` inside **your** component resolves wherever the layer
|
|
1090
|
+
applies. `theme.css` carries the layer, so importing `theme.css` is enough, including for
|
|
1091
|
+
server-rendered pages and for application elements that paint before any Lyra element exists.
|
|
1092
|
+
`tokens-root.css` is the same layer alone, as a static stylesheet, for pages that do not use
|
|
1093
|
+
`theme.css`:
|
|
1094
|
+
|
|
1095
|
+
- **Server-rendered pages.** Declarative shadow roots no longer carry the layer, so link
|
|
1096
|
+
`theme.css` (or `tokens-root.css`) for a correct first paint before hydration (see
|
|
1097
|
+
[Theme scopes](#theme-scopes) for application shadow roots).
|
|
1098
|
+
- **Application elements that paint before the first Lyra element is registered**, for example
|
|
1099
|
+
ahead of a lazily loaded route; otherwise they change value when the layer is adopted.
|
|
1100
|
+
- **Large pages that load Lyra late.** Without a static copy, the layer is adopted when the first
|
|
1101
|
+
Lyra element is registered, which usually happens while the document is still small. A route that
|
|
1102
|
+
imports Lyra only after the page already holds a large DOM pays a one-off, whole-document style
|
|
1103
|
+
invalidation then. A document whose root already resolves the layer (it links `theme.css` or
|
|
1104
|
+
`tokens-root.css`) keeps the static copy and adopts no constructed one.
|
|
1105
|
+
|
|
1106
|
+
Link one of the two, not both: the second copy changes no value, but every scope matches the layer
|
|
1107
|
+
twice.
|
|
1093
1108
|
|
|
1094
1109
|
```css
|
|
1095
|
-
@import "@aceshooting/lyra-ui/theme.css"; /* the --lr-theme-*
|
|
1096
|
-
|
|
1110
|
+
@import "@aceshooting/lyra-ui/theme.css"; /* the --lr-theme-* inputs, Lyra's layer order, and the resolved --lr-* layer */
|
|
1111
|
+
/* or, without theme.css: */
|
|
1112
|
+
@import "@aceshooting/lyra-ui/tokens-root.css"; /* the resolved --lr-* layer alone */
|
|
1097
1113
|
```
|
|
1098
1114
|
|
|
1099
1115
|
```css
|
|
1100
|
-
/*
|
|
1116
|
+
/* Valid in your own component's stylesheet, in plain application CSS, anywhere. */
|
|
1101
1117
|
.app-panel {
|
|
1102
1118
|
padding: var(--lr-space-m);
|
|
1103
1119
|
border: var(--lr-border-width-thin) solid var(--lr-color-border);
|
|
@@ -1112,10 +1128,9 @@ Import one optional stylesheet and the curated part of layer 2 exists at documen
|
|
|
1112
1128
|
}
|
|
1113
1129
|
```
|
|
1114
1130
|
|
|
1115
|
-
**
|
|
1116
|
-
it can change without a major version
|
|
1117
|
-
|
|
1118
|
-
inside a Lyra UI without looking foreign:
|
|
1131
|
+
**Every output is visible on `:root`; only a subset is public API.** `--lr-*` is internal precisely
|
|
1132
|
+
so it can change without a major version. The stable subset is what an application's own component
|
|
1133
|
+
needs to sit inside a Lyra UI without looking foreign, and the file's header lists it:
|
|
1119
1134
|
|
|
1120
1135
|
| Family | Names |
|
|
1121
1136
|
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
@@ -1128,53 +1143,122 @@ inside a Lyra UI without looking foreign:
|
|
|
1128
1143
|
| Typography | `--lr-font`, `--lr-font-mono`, the ten `--lr-font-size-*` steps, the four `--lr-font-weight-*` steps |
|
|
1129
1144
|
| State and motion | `--lr-focus-ring`, `--lr-focus-ring-color`, `--lr-focus-ring-width`, `--lr-focus-ring-offset`, `--lr-opacity-disabled`, `--lr-opacity-muted`, `--lr-duration-fast`, `--lr-duration-base`, `--lr-easing-standard`, `--lr-easing-emphasized`, `--lr-transition-fast`, `--lr-transition-base`, `--lr-transition-interactive` |
|
|
1130
1145
|
|
|
1131
|
-
The grid
|
|
1132
|
-
only guaranteed legible under the matching `on-quiet` foreground
|
|
1133
|
-
alone would hand you a pairing with nothing behind it.
|
|
1146
|
+
The grid is stable as a whole because its contrast guarantee is **per tier** — a `fill-quiet`
|
|
1147
|
+
background is only guaranteed legible under the matching `on-quiet` foreground.
|
|
1134
1148
|
|
|
1135
|
-
**
|
|
1136
|
-
|
|
1137
|
-
`--lr-size-*` (value-named geometry constants, frozen internals), the chart, graph and terminal
|
|
1138
|
-
palettes (generated ramps that move with the palette tooling), `--lr-layer-*` (stacking order is
|
|
1139
|
-
your decision), `--lr-color-mix-*` and `--lr-hover-brightness` (inputs to the library's own
|
|
1140
|
-
interaction recipe), `--lr-line-height-*`, the per-control internals (`--lr-icon-button-size`,
|
|
1149
|
+
**Visible but internal** (read them at your own risk; they may change in any release): `--lr-size-*`,
|
|
1150
|
+
`--lr-layer-*`, `--lr-color-mix-*`, `--lr-hover-brightness`, `--lr-line-height-*`,
|
|
1141
1151
|
`--lr-otp-input-segment-size`, `--lr-scroll-fade-size`, `--lr-popover-viewport-clamp`,
|
|
1142
|
-
`--lr-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
of
|
|
1152
|
+
`--lr-mask-opaque`, `--lr-color-no-data`, and the private `--_lr-*` names. **Not in the layer at all:**
|
|
1153
|
+
`--lr-ramp-*` (tooling-only), the chart, graph and terminal palettes (per host, on the components that
|
|
1154
|
+
draw with them), the form-control ladder, and the per-element names `--lr-icon-button-size`,
|
|
1155
|
+
`--lr-radius-button` and `--lr-safe-area-*`. If you need one of these, ask for it to be added to the
|
|
1156
|
+
stable subset rather than reading it from the document.
|
|
1146
1157
|
|
|
1147
1158
|
**Stability promise.** Every name in the table is public API from the release that introduced it: it
|
|
1148
1159
|
will not be renamed or removed outside a major version, and its meaning will not change. Its _value_
|
|
1149
1160
|
may change in a minor exactly as it may inside a component — a palette retune moves your elements
|
|
1150
|
-
and the kit's together, which is the point.
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
and
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1161
|
+
and the kit's together, which is the point.
|
|
1162
|
+
|
|
1163
|
+
**Modes follow the nearest mode scope.** The layer follows the OS preference at the root and accepts
|
|
1164
|
+
`.lr-light` / `.lr-dark`, `data-lr-theme` and `data-lr-mode` scopes, in every engine, with or without
|
|
1165
|
+
`theme.css`. When `theme.css` is installed its requested mode owns the switches. A mode-neutral
|
|
1166
|
+
scope keeps its ancestor's mode. Forced colours, increased contrast and reduced motion apply at every
|
|
1167
|
+
scope and again on every component host.
|
|
1168
|
+
|
|
1169
|
+
Public outputs sit in the `lr-theme` cascade layer (the fallback mode switches in `lr-base`), so any
|
|
1170
|
+
unlayered application rule beats them regardless of load order, and the file declares custom
|
|
1171
|
+
properties only — notably not `color-scheme` — so importing it paints nothing by itself.
|
|
1172
|
+
|
|
1173
|
+
### Theme scopes
|
|
1174
|
+
|
|
1175
|
+
A **theme scope** is an element that re-derives the whole token layer from the `--lr-theme-*` inputs
|
|
1176
|
+
and the mode it sees. The list is closed: `:root`; the mode scopes `.lr-light`, `.lr-dark` and
|
|
1177
|
+
`[data-lr-theme]` (any value); the style-axis boundaries `[data-lr-mode]`, `[data-lr-look]`,
|
|
1178
|
+
`[data-lr-accent]`, `[data-lr-density]`, `[data-lr-contrast]`, `[data-lr-motion]`; a look's scoped
|
|
1179
|
+
`.light` / `.dark` aliases; the design-token fixture scopes `.lr-token-light`, `.lr-token-dark`,
|
|
1180
|
+
`[data-lr-design-token-mode]`; and the mode-neutral marker **`data-lr-theme-scope`**.
|
|
1167
1181
|
|
|
1168
1182
|
```html
|
|
1169
|
-
<!--
|
|
1170
|
-
<section
|
|
1183
|
+
<!-- Re-theme one region: mark it, then set inputs on it. -->
|
|
1184
|
+
<section data-lr-theme-scope style="--lr-theme-color-brand-fill-loud: #7c3aed">
|
|
1185
|
+
<lr-button variant="brand">Save</lr-button>
|
|
1186
|
+
</section>
|
|
1187
|
+
|
|
1188
|
+
<!-- Mode scopes are already scopes; a marked region inside one keeps its mode. -->
|
|
1189
|
+
<aside class="lr-dark"><div data-lr-theme-scope style="--lr-theme-space-m: 1rem">…</div></aside>
|
|
1190
|
+
|
|
1191
|
+
<!-- A single re-themed component. -->
|
|
1192
|
+
<lr-button data-lr-theme-scope style="--lr-theme-color-brand-fill-loud: #7c3aed">Save</lr-button>
|
|
1193
|
+
```
|
|
1194
|
+
|
|
1195
|
+
- **The marker follows HTML presence semantics:** `data-lr-theme-scope="false"` still marks. React
|
|
1196
|
+
renders `data-*={false}` as `"false"`, so write `data-lr-theme-scope=""` (or omit the attribute);
|
|
1197
|
+
the development build warns on the literal `"false"`.
|
|
1198
|
+
- **Nesting** works like inheritance: a scope re-derives from what it inherits plus what it sets, and
|
|
1199
|
+
its descendants inherit the result until the next scope. The marker only re-derives the `--lr-*`
|
|
1200
|
+
outputs, so an input set on `:root` (inline, in your stylesheet, or by `setLyraStyle()`) or on an
|
|
1201
|
+
outer scope reaches a marked region exactly as it reaches an unmarked one, and adding a marker
|
|
1202
|
+
where nothing needs it changes nothing. With `theme.css`, mode scopes and the style-axis
|
|
1203
|
+
boundaries also re-resolve the inputs from the selected look, accent and mode, so an input set
|
|
1204
|
+
above one of them stops there (set it on that boundary, or below it). A scope costs a little less
|
|
1205
|
+
than one component did before 28.0.0, so put inputs on a common ancestor rather than marking every
|
|
1206
|
+
row of a list.
|
|
1207
|
+
- **`applyLyraStyleScope()`** writes the marker whenever it writes inline inputs.
|
|
1208
|
+
- **Brand regions in the default look.** The marker re-derives outputs but is not a style boundary,
|
|
1209
|
+
so the roles that follow brand in the default Shadcn look (the neutral loud tier) keep the brand
|
|
1210
|
+
of the nearest boundary inside the first example above. For a brand region call
|
|
1211
|
+
`applyLyraStyleScope(el, { accent: '#7c3aed' })`, which writes the `data-lr-accent="custom"`
|
|
1212
|
+
boundary, or set the `--lr-theme-color-neutral-*-loud` inputs on the region too.
|
|
1213
|
+
- **Which inputs need a scope.** Only the `--lr-theme-*` inputs the layer consumes (listed in
|
|
1214
|
+
`llms/tokens.md`). Inputs read on the host itself keep working on any element: the chart,
|
|
1215
|
+
graph and terminal palettes, the form-control heights and radius, the icon-button size, the
|
|
1216
|
+
button radius, scrollbar and progress-ring inputs.
|
|
1217
|
+
|
|
1218
|
+
**Application shadow roots.** Custom properties inherit across shadow boundaries; selectors do not.
|
|
1219
|
+
A scope _inside_ your own component's shadow root therefore needs the layer adopted in that root.
|
|
1220
|
+
Lyra does that on demand: when a Lyra element connects inside an application shadow root and it is,
|
|
1221
|
+
or sits below, a scope in that root, an unlayered copy of the layer with zero-specificity
|
|
1222
|
+
(`:where()`) selectors is appended to the root's `adoptedStyleSheets`, so your component's own rules
|
|
1223
|
+
there still win (unless you put them in a cascade layer).
|
|
1224
|
+
"Below" follows the flat tree, so a Lyra element slotted into your component (directly, or through
|
|
1225
|
+
forwarded slots) counts as below the scopes around its slot, also when your component renders its
|
|
1226
|
+
slots right after connecting, as Lit does. A Lyra element inside a slotted non-Lyra wrapper does not
|
|
1227
|
+
trigger it. Library components' own shadow roots never receive it. Call
|
|
1228
|
+
`adoptLyraTokens(root)` (from `@aceshooting/lyra-ui/utilities/tokens.js`, or the package root) for a
|
|
1229
|
+
root whose scopes appear after its Lyra elements connected, a root that has scopes but no Lyra
|
|
1230
|
+
element yet, or an iframe that holds application elements only. Server-rendered application roots
|
|
1231
|
+
that contain scopes include `<link rel="stylesheet" href="…/tokens-root.css">`.
|
|
1232
|
+
|
|
1233
|
+
```js
|
|
1234
|
+
// An application component whose shadow root holds scopes before any Lyra element connects in it.
|
|
1235
|
+
import { adoptLyraTokens } from "@aceshooting/lyra-ui/utilities/tokens.js";
|
|
1236
|
+
adoptLyraTokens(this.shadowRoot); // adoptLyraTokens(root: Document | ShadowRoot): void, idempotent
|
|
1171
1237
|
```
|
|
1172
1238
|
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
also
|
|
1177
|
-
|
|
1239
|
+
**Append, never replace.** Lyra appends its sheet to `document.adoptedStyleSheets` and to an
|
|
1240
|
+
application root's. An application that later assigns a new array wholesale removes it until the next
|
|
1241
|
+
Lyra element connects there; append to the existing array instead.
|
|
1242
|
+
In Chromium, Lyra also appends a one-rule sheet to `document.adoptedStyleSheets`: a private root
|
|
1243
|
+
property (`--_lr-root-inputs`) that follows every theme input. It lets Chromium skip a full
|
|
1244
|
+
custom-property comparison per element when the root is re-themed (an accent or spacing input
|
|
1245
|
+
written on `<html>` with dark islands or other scopes on the page costs about half as much). Firefox
|
|
1246
|
+
and Safari do not get it; they already stop at unchanged scopes, which the property would defeat.
|
|
1247
|
+
When `theme.css` or `tokens-root.css` provides the layer, that sheet goes in only at the first
|
|
1248
|
+
attribute change on `<html>` (an inline input, a mode or look attribute, a class), so a route that registers Lyra late on a large page does not restyle every element for it.
|
|
1249
|
+
|
|
1250
|
+
**Layer order.** On a page with no Lyra stylesheet, the adopted sheet's layer statement is the last
|
|
1251
|
+
the browser sees, so Lyra's layers sort after yours. Declare Lyra's order first (import `theme.css`,
|
|
1252
|
+
or repeat `@layer lr-base, lr-theme, lr-theme-preset, lr-utilities, lr-overrides;` before your own
|
|
1253
|
+
layers), or leave application overrides of `--lr-*` outputs unlayered.
|
|
1254
|
+
|
|
1255
|
+
**Finding unscoped inputs.** `findUnscopedThemeInputs(root?)` (from
|
|
1256
|
+
`@aceshooting/lyra-ui/utilities/theme-scopes.js`; `findUnscopedThemeInputs(root?: Document |
|
|
1257
|
+
DocumentFragment | Element): Element[]`) returns, without logging, every element under `root`
|
|
1258
|
+
(through open shadow roots) whose inline style sets a layer-consumed input and that is not a scope. `lyra-ui-migrate --rule=theme-scopes`
|
|
1259
|
+
adds the marker in HTML, Lit and JSX templates and reports dynamic inputs and stylesheet rules;
|
|
1260
|
+
`lyra-ui-migrate --origin=lyra-v26` runs the same rule together with the other Lyra 27 moves (relocated
|
|
1261
|
+
locale and editor-data specifiers, `ToolStatus`) and reports removed localization keys.
|
|
1178
1262
|
|
|
1179
1263
|
### The colour ramp and the semantic grid
|
|
1180
1264
|
|
|
@@ -1215,8 +1299,9 @@ These guarantees apply in both modes.
|
|
|
1215
1299
|
rethemed without forking anything beneath it:
|
|
1216
1300
|
|
|
1217
1301
|
```css
|
|
1218
|
-
/* Both the grid slot and the flat alias below now resolve to this
|
|
1219
|
-
|
|
1302
|
+
/* Both the grid slot and the flat alias below now resolve to this, for every component inside
|
|
1303
|
+
the panel (mark the panel <div class="invoice-panel" data-lr-theme-scope>, or use :root). */
|
|
1304
|
+
.invoice-panel[data-lr-theme-scope] {
|
|
1220
1305
|
--lr-theme-color-brand-fill-loud: #7c3aed;
|
|
1221
1306
|
}
|
|
1222
1307
|
```
|
|
@@ -1391,6 +1476,13 @@ first statement the browser sees is appended at the end, so an older four-name s
|
|
|
1391
1476
|
`lr-theme-preset`) would rank an imported look preset above `lr-overrides` and your own layer. Every Lyra stylesheet that declares an order repeats the same five names for exactly this
|
|
1392
1477
|
reason.
|
|
1393
1478
|
|
|
1479
|
+
The same rule decides application **fallback fills**. A page that keeps plain `background` rules
|
|
1480
|
+
for dialogs or panels (so it also renders without the component bundle) and uses an unlayered rule
|
|
1481
|
+
on an `.lr-surface-chrome` element overrides the Glass fill; declare a low-priority layer before
|
|
1482
|
+
Lyra's names (`@layer app-base, lr-base, lr-theme, lr-theme-preset, lr-utilities, lr-overrides;`)
|
|
1483
|
+
for those fallbacks, or set `--lr-surface-background`. See
|
|
1484
|
+
[Application fallback fills and cascade layers](native-styles-and-utilities.md#application-fallback-fills-and-cascade-layers).
|
|
1485
|
+
|
|
1394
1486
|
<a id="the-shadcn-look--themesshadcncss"></a>
|
|
1395
1487
|
|
|
1396
1488
|
### The shadcn look — looks/shadcn.css
|
|
@@ -1437,25 +1529,33 @@ compatibility aliases above.
|
|
|
1437
1529
|
|
|
1438
1530
|
### Where an override actually reaches
|
|
1439
1531
|
|
|
1440
|
-
**Shared computed `--lr-*`
|
|
1441
|
-
|
|
1442
|
-
`--lr-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1532
|
+
**Shared computed `--lr-*` outputs are resolved at theme scopes and inherited everywhere else.** That
|
|
1533
|
+
includes palette, spacing, radius, typography and motion outputs such as `--lr-color-brand`,
|
|
1534
|
+
`--lr-space-m` and `--lr-radius`. No component re-declares them on its host (since 28.0.0), so:
|
|
1535
|
+
|
|
1536
|
+
- **A `--lr-theme-*` input** retunes everything below it **when it is set on a theme scope**. Set on a
|
|
1537
|
+
plain wrapper, a component's inline style, or an application component's own `:host` rule, it no
|
|
1538
|
+
longer re-derives the components below; add `data-lr-theme-scope` to that element.
|
|
1539
|
+
- **A `--lr-*` output** set on an ancestor now reaches every component below it, until the next theme
|
|
1540
|
+
scope (which re-derives every output). The outputs _derived_ from it (`--lr-focus-ring` from
|
|
1541
|
+
`--lr-focus-ring-color`, `--lr-color-brand` from `--lr-color-brand-fill-loud`,
|
|
1542
|
+
`--lr-transition-interactive` from `--lr-transition-fast`) keep the scope's values unless the
|
|
1543
|
+
element is itself a scope.
|
|
1544
|
+
- **Border outputs stop at an opaque content interior.** The bodies of `lr-card`, `lr-details` and
|
|
1545
|
+
`lr-accordion-item` restore the nearest scope's unqualified `--lr-color-border` and
|
|
1546
|
+
`--lr-color-border-strong` for their content (inside a glass surface the surface would otherwise
|
|
1547
|
+
hand its translucency-qualified borders to opaque content). A `--lr-color-border` set on such a
|
|
1548
|
+
component, or above it, still applies to the chrome that reads it, but not to the content; set
|
|
1549
|
+
`--lr-theme-color-surface-border` on a theme scope, or a component hook such as
|
|
1550
|
+
`--lr-input-border-color`, to reach the content.
|
|
1451
1551
|
|
|
1452
1552
|
```css
|
|
1453
|
-
/* Reaches everything in the subtree, however deeply nested. */
|
|
1454
|
-
.invoice-panel {
|
|
1553
|
+
/* Reaches everything in the subtree, however deeply nested: the element is a theme scope. */
|
|
1554
|
+
.invoice-panel[data-lr-theme-scope] {
|
|
1455
1555
|
--lr-theme-color-brand-fill-loud: #7c3aed;
|
|
1456
1556
|
}
|
|
1457
1557
|
|
|
1458
|
-
/*
|
|
1558
|
+
/* An output reaches the subtree down to the next scope; its dependants do not follow it. */
|
|
1459
1559
|
.invoice-panel {
|
|
1460
1560
|
--lr-color-brand: #7c3aed;
|
|
1461
1561
|
}
|
|
@@ -1478,8 +1578,9 @@ reliable way to theme a group of matching components:
|
|
|
1478
1578
|
State and size selectors change only the private fallback. An inherited or direct public value
|
|
1479
1579
|
continues to win in every state and size tier.
|
|
1480
1580
|
|
|
1481
|
-
**Diagnostic:** if a
|
|
1482
|
-
|
|
1581
|
+
**Diagnostic:** if a `--lr-theme-*` input has no effect on a nested component, check that the element
|
|
1582
|
+
carrying it is a theme scope (the development build warns once per page about an inline input on an
|
|
1583
|
+
element that is not, and `findUnscopedThemeInputs()` lists them). If a documented component-specific hook
|
|
1483
1584
|
fails when inherited from a wrapper, that is a component bug; setting the same hook directly on
|
|
1484
1585
|
every host should not be necessary.
|
|
1485
1586
|
|
|
@@ -1589,28 +1690,16 @@ consult it rather than guessing a token name.
|
|
|
1589
1690
|
}
|
|
1590
1691
|
```
|
|
1591
1692
|
|
|
1592
|
-
|
|
1593
|
-
`data-lr-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
`data-lr-theme="dark"` pins dark on a light machine the same way, and a `.lr-dark` /
|
|
1603
|
-
`data-lr-theme="dark"` _ancestor_ is followed as well (through `:host-context()` where the engine
|
|
1604
|
-
has it, and through `theme.css`'s inheriting custom properties everywhere else).
|
|
1605
|
-
|
|
1606
|
-
Note the asymmetry: the _light_ pin is read on the component itself (`:host([data-lr-theme='light'])`),
|
|
1607
|
-
while a _dark_ ancestor is followed through `:host-context()`. Putting `data-lr-theme="light"` on
|
|
1608
|
-
`<html>` — what `setLyraStyle({ mode: 'light' })` does — pins the page through
|
|
1609
|
-
`theme.css`'s real `--lr-theme-*` values, which inherit into every shadow root. Without `theme.css`
|
|
1610
|
-
there are no such values to inherit, so put the attribute on the components you actually need
|
|
1611
|
-
pinned.
|
|
1612
|
-
|
|
1613
|
-
The token layer also sets `:host([hidden]) { display: none !important; }` and an inherited
|
|
1693
|
+
Switch modes by putting `class="lr-light"`/`class="lr-dark"` (or `data-lr-theme="light"`/`"dark"`,
|
|
1694
|
+
or `data-lr-mode`) on any element, including a component itself; with `theme.css` imported it also
|
|
1695
|
+
sets `color-scheme`. **Every engine follows the nearest mode scope, with or without `theme.css`:** the
|
|
1696
|
+
document layer carries mode to every scope through two inherited private switches, so a `.lr-light`
|
|
1697
|
+
island inside a `.lr-dark` region is light, a mode-neutral scope keeps its ancestor's mode, and the
|
|
1698
|
+
OS preference decides the root unless the root carries an explicit mode. A real `--lr-theme-*` value
|
|
1699
|
+
still wins over the built-in light or dark default. (Before 28.0.0 an ancestor mode reached
|
|
1700
|
+
components without `theme.css` only in Chromium, through `:host-context()`.)
|
|
1701
|
+
|
|
1702
|
+
Each component host also keeps `:host([hidden]) { display: none !important; }` and an inherited
|
|
1614
1703
|
`box-sizing: border-box` reset.
|
|
1615
1704
|
|
|
1616
1705
|
### Style runtime — @aceshooting/lyra-ui/theme.js
|
|
@@ -1623,8 +1712,11 @@ import {
|
|
|
1623
1712
|
getLyraStyle,
|
|
1624
1713
|
resetLyraStyle,
|
|
1625
1714
|
setLyraStyle,
|
|
1715
|
+
startLyraStyle,
|
|
1626
1716
|
} from "@aceshooting/lyra-ui/theme.js";
|
|
1627
1717
|
|
|
1718
|
+
startLyraStyle(); // adopt the saved style and follow the OS without writing storage
|
|
1719
|
+
|
|
1628
1720
|
setLyraStyle({ mode: "dark" }); // unspecified axes keep their current value
|
|
1629
1721
|
setLyraStyle({ accent: "sapphire" }); // named palette accent
|
|
1630
1722
|
setLyraStyle({ accent: "#7c3aed" }); // absolute CSS color
|
|
@@ -1695,6 +1787,27 @@ initial snapshot; it does not install a live system-mode listener. This option c
|
|
|
1695
1787
|
the bootstrap. Later runtime calls such as `setLyraStyle()` follow their own style and persistence
|
|
1696
1788
|
policy, so choose that policy explicitly if the application initializes the runtime afterward.
|
|
1697
1789
|
|
|
1790
|
+
**Starting the runtime after the bootstrap — `startLyraStyle()`.** A page that inlines only the
|
|
1791
|
+
bootstrap and loads `theme.js` later in a deferred bundle calls `startLyraStyle()` once. It adopts
|
|
1792
|
+
the saved style (the defaults when nothing is saved) on the document root and, while the mode is
|
|
1793
|
+
System, attaches the live `prefers-color-scheme` listener. It never writes storage: no record is
|
|
1794
|
+
created, a v1 record is not migrated, and an operating-system flip afterwards repaints without
|
|
1795
|
+
saving. Repeated calls do not stack listeners. The call emits no `lr-style-change`; a later
|
|
1796
|
+
operating-system flip emits `changed: ["resolvedMode"]`. The first `setLyraStyle()` takes over the
|
|
1797
|
+
same listener. Do not call `setLyraStyle({})` for this: it persists the current record.
|
|
1798
|
+
|
|
1799
|
+
~~~ts
|
|
1800
|
+
// deferred bundle, after <script>lyraThemeBootstrap</script> in <head>
|
|
1801
|
+
import { startLyraStyle } from "@aceshooting/lyra-ui/theme.js";
|
|
1802
|
+
|
|
1803
|
+
startLyraStyle(); // adopts the saved style, follows the OS while mode is System, never writes
|
|
1804
|
+
~~~
|
|
1805
|
+
|
|
1806
|
+
`startLyraStyle()` always reads the runtime's own `localStorage['lyra-theme']` record and applies
|
|
1807
|
+
the whole profile in it. A page whose bootstrap uses `data-lr-theme-restore="mode"` or an
|
|
1808
|
+
application-owned storage key does not pair with it: the start would apply axes or a record the
|
|
1809
|
+
bootstrap deliberately ignored. Such pages call `setLyraStyle()` with the policy they want.
|
|
1810
|
+
|
|
1698
1811
|
**Migrating the retired theme facade.** New code uses setLyraStyle() and getLyraStyle(). Map old auto mode to system, an old surface reference color to accentBackground, and an old token map to overrides; review custom CSS colors that share a gemstone name before choosing a named accent. Replace preset definitions with a LyraLook plus explicit style choices. Replace selectors for data-lr-theme-preset with the actual axis they need, such as data-lr-look="shadcn". Import theme.css in place of the removed fixed themes/shadcn.css facade and select the look with setLyraStyle({ look: "shadcn" }) or a scoped data-lr-look attribute. Listen for lr-style-change and read event.detail.style and event.detail.changed; the old theme and preset events are no longer emitted. For the complete project-by-project sequence, see [Upgrading from v23 to v24](v23-to-v24-migration.md).
|
|
1699
1812
|
|
|
1700
1813
|
Historical v1 stored records remain readable by the runtime and bootstrap. The removed JavaScript functions, preset subpaths, preset event, root marker, and fixed stylesheet are not available in the current API.
|
|
@@ -1825,8 +1938,8 @@ uses a substring class selector, so a class such as `app-lr-flex-preview` does n
|
|
|
1825
1938
|
assets repeat `@layer lr-base, lr-theme, lr-theme-preset, lr-utilities, lr-overrides`; an ordinary unlayered
|
|
1826
1939
|
application rule therefore beats them regardless of load order. A third opt-in asset,
|
|
1827
1940
|
[`tokens-root.css`](#reading-the-resolved-tokens-from-your-own-components--tokens-rootcss), is not a
|
|
1828
|
-
style sheet in the same sense — it declares custom properties only
|
|
1829
|
-
|
|
1941
|
+
style sheet in the same sense — it declares custom properties only: the document token layer that
|
|
1942
|
+
the first connected Lyra element would otherwise adopt, available before any component connects.
|
|
1830
1943
|
|
|
1831
1944
|
### Utility class inventory
|
|
1832
1945
|
|
|
@@ -1908,7 +2021,8 @@ keeps that surface's text colour. Heading tracking reads `--lr-heading-letter-sp
|
|
|
1908
2021
|
| Muted | `lr-text-sm lr-text-quiet` |
|
|
1909
2022
|
|
|
1910
2023
|
For an exact 0.875rem muted/small size, use a class of your own with the token chain (resolved
|
|
1911
|
-
`--lr-*` tokens
|
|
2024
|
+
`--lr-*` tokens exist at document scope once a Lyra element has connected or `tokens-root.css` is
|
|
2025
|
+
loaded; the chain covers the moment before):
|
|
1912
2026
|
|
|
1913
2027
|
```css
|
|
1914
2028
|
.app-muted {
|
|
@@ -2098,6 +2212,40 @@ contrast/motion choices. Nested chrome suppresses repeated blur; independently p
|
|
|
2098
2212
|
surfaces begin their own material root. Keep cards, data tables, charts, map layers and editing
|
|
2099
2213
|
fields outside the automatic chrome class.
|
|
2100
2214
|
|
|
2215
|
+
#### Application fallback fills and cascade layers
|
|
2216
|
+
|
|
2217
|
+
Lyra paints the `.lr-surface-chrome` fill from a rule inside its cascade layers
|
|
2218
|
+
(`lr-theme-preset.surface`). An **unlayered** application rule that sets `background` on the same
|
|
2219
|
+
element — a generic `dialog { background: … }`, a `.panel` class — beats every layered rule
|
|
2220
|
+
whatever its specificity, so the element keeps the application's opaque fill and the Glass
|
|
2221
|
+
treatment disappears without a warning. No `revert-layer` workaround is needed; put the
|
|
2222
|
+
application's fallback where it ranks below Lyra:
|
|
2223
|
+
|
|
2224
|
+
```css
|
|
2225
|
+
/* 1. A low-priority application layer named before Lyra's. This order statement must be the first
|
|
2226
|
+
the browser sees: put it at the top of the entry stylesheet, before the theme.css import. */
|
|
2227
|
+
@layer app-base, lr-base, lr-theme, lr-theme-preset, lr-utilities, lr-overrides;
|
|
2228
|
+
@import "@aceshooting/lyra-ui/theme.css";
|
|
2229
|
+
|
|
2230
|
+
@layer app-base {
|
|
2231
|
+
dialog,
|
|
2232
|
+
.panel {
|
|
2233
|
+
background: #fff; /* still paints when the Lyra stylesheets are absent */
|
|
2234
|
+
}
|
|
2235
|
+
}
|
|
2236
|
+
|
|
2237
|
+
/* 2. Or choose the chrome's base fill through its token; Glass mixes it at the surface opacity. */
|
|
2238
|
+
.panel.lr-surface-chrome {
|
|
2239
|
+
--lr-surface-background: #fff;
|
|
2240
|
+
}
|
|
2241
|
+
```
|
|
2242
|
+
|
|
2243
|
+
An application layer declared after Lyra's (or unnamed until after `theme.css` loads) ranks above
|
|
2244
|
+
the surface layer and disables Glass in the same way as an unlayered rule. Keep unlayered
|
|
2245
|
+
`background` rules off `.lr-surface-chrome` elements, or exclude them with
|
|
2246
|
+
`:not(.lr-surface-chrome)`. See [Cascade layers](styles-and-tokens.md#cascade-layers) for the full
|
|
2247
|
+
order.
|
|
2248
|
+
|
|
2101
2249
|
## Localization: `locale`, `strings`, and the locale runtime
|
|
2102
2250
|
|
|
2103
2251
|
Every built-in string — button labels, accessible names, descriptions, validation messages, status
|
|
@@ -2622,6 +2770,22 @@ browser-bundle argument for excluding them does not apply to a server render. Us
|
|
|
2622
2770
|
template; the component renders when its definition upgrades in the browser. Use this for initial
|
|
2623
2771
|
renders that require light-DOM traversal, layout, canvas, observers, media, or other browser APIs.
|
|
2624
2772
|
|
|
2773
|
+
**Link the token layer in `<head>`.** Since 28.0.0 declarative shadow roots no longer carry the
|
|
2774
|
+
shared `--lr-*` layer (one server-rendered `lr-button` is about 34 KB smaller). `theme.css` carries
|
|
2775
|
+
it, so for a correct first paint before hydration link `theme.css` after the no-flash bootstrap (a
|
|
2776
|
+
page that does not use `theme.css` links `styles/tokens-root.css`, the layer alone, instead):
|
|
2777
|
+
|
|
2778
|
+
```html
|
|
2779
|
+
<link rel="stylesheet" href="/node_modules/@aceshooting/lyra-ui/dist/theme.css" />
|
|
2780
|
+
```
|
|
2781
|
+
|
|
2782
|
+
Hydration then skips the constructed copy. An application's **own** declarative shadow roots that
|
|
2783
|
+
contain theme scopes (for example a `.lr-dark` region or a `data-lr-theme-scope` wrapper) include the
|
|
2784
|
+
same `<link rel="stylesheet" href="…/tokens-root.css">` inside their template: document styles do not
|
|
2785
|
+
reach into a shadow root until hydration adopts the layer there. Without any link and without
|
|
2786
|
+
JavaScript, server-rendered components paint without resolved tokens, as a page without Lyra's styles
|
|
2787
|
+
always did.
|
|
2788
|
+
|
|
2625
2789
|
Server setup (the fallback must precede Lit's renderer):
|
|
2626
2790
|
|
|
2627
2791
|
```ts
|
|
@@ -2698,6 +2862,60 @@ only targets in the element's own or an ancestor shadow scope (sibling and desce
|
|
|
2698
2862
|
targets are dropped); `null` clears it and removes the attribute; a changed `aria-controls`
|
|
2699
2863
|
attribute resolves ids in the element's own root instead.
|
|
2700
2864
|
|
|
2865
|
+
`installHappyDomShims()` also calls `installHappyDomCascadeLayerShim()`. Happy DOM 20 drops every
|
|
2866
|
+
rule inside an `@layer` block from its CSSOM, while `CSS.supports('at-rule(@layer)')` still reports
|
|
2867
|
+
support. Lyra's stylesheets declare their probe properties (`--_lr-style-resolver`, the
|
|
2868
|
+
`--_lr-*-installed` markers, the token-layer sentinel) inside cascade layers, so under Happy DOM
|
|
2869
|
+
`theme.css` looked absent: `setLyraStyle()` warned that a stylesheet was missing and took its
|
|
2870
|
+
no-stylesheet fallback. The shim passes the text that `CSSStyleSheet.replaceSync()`/`replace()`
|
|
2871
|
+
parse (the path used by `<style>`, `<link rel="stylesheet">` and constructed sheets) through the
|
|
2872
|
+
exported `flattenCascadeLayers(css)`. That function drops `@layer a, b;` statements and unwraps
|
|
2873
|
+
each layer block in place, leaving comments, strings, `url(...)` and `@import … layer(x)` as they
|
|
2874
|
+
are. The probes then resolve as they do in a browser. Layer precedence is not modelled: the
|
|
2875
|
+
unwrapped rules cascade in source order, so assert behaviour, not values that depend on which layer
|
|
2876
|
+
wins. `insertRule()` is unchanged. The shim detects the defect by parsing a layered rule, so it is
|
|
2877
|
+
a no-op in every browser and without a `CSSStyleSheet` global; it installs once and returns a
|
|
2878
|
+
function that restores the original methods. Install it before any stylesheet is parsed (in the
|
|
2879
|
+
same `setupFiles` entry): a sheet parsed earlier keeps the rules it dropped.
|
|
2880
|
+
|
|
2881
|
+
### jsdom: `installJsdomShims()`
|
|
2882
|
+
|
|
2883
|
+
jsdom implements no `adoptedStyleSheets`, so Lit renders one `<style>` element per component
|
|
2884
|
+
shadow root. jsdom registers each of those sheets on the document, not the shadow root, and every
|
|
2885
|
+
`getComputedStyle()` call then matches the element against every rule of every sheet. With a few
|
|
2886
|
+
hundred Lyra elements on the page a single computed-style read can take over 100 ms, and Lyra
|
|
2887
|
+
reads computed style to decide which slotted text is visible, so whole tests slow to a crawl.
|
|
2888
|
+
|
|
2889
|
+
`installJsdomShims()` installs the two jsdom shims. `installJsdomAdoptedStyleSheetsShim()` adds an inert
|
|
2890
|
+
`adoptedStyleSheets` to `Document` and `ShadowRoot`, so Lit adopts each component's constructed
|
|
2891
|
+
stylesheet instead of appending `<style>` elements. Adopted sheets are stored and read back (the
|
|
2892
|
+
same array until reassigned, so `push()` persists) but never applied; jsdom could not cascade them
|
|
2893
|
+
per shadow root anyway. `getComputedStyle()` then sees only the document's own sheets and inline
|
|
2894
|
+
styles, so assert behaviour and DOM rather than component styling. A jsdom release without
|
|
2895
|
+
`CSSStyleSheet.prototype.replace()`/`replaceSync()`, which Lit also requires, gets inert versions
|
|
2896
|
+
that record the text. The shim installs only when `navigator.userAgent` carries jsdom's
|
|
2897
|
+
`jsdom/<version>` signature and `adoptedStyleSheets` is missing, so it is a no-op in browsers,
|
|
2898
|
+
under Happy DOM and in plain Node projects. It installs once and returns a function that removes
|
|
2899
|
+
what it added.
|
|
2900
|
+
|
|
2901
|
+
jsdom's `ElementInternals` has no form association, so every Lyra form control (`lr-button`,
|
|
2902
|
+
`lr-input`, `lr-checkbox`, …) throws in its constructor there. `installJsdomFormAssociatedShim()`
|
|
2903
|
+
adds, only where missing, an inert `setFormValue()`, a `setValidity()` that `validity`,
|
|
2904
|
+
`validationMessage`, `checkValidity()` and `reportValidity()` reflect, `willValidate`, `form` (the
|
|
2905
|
+
host's closest `<form>`) and a `Set` for `states`. Nothing is submitted and no `invalid` event
|
|
2906
|
+
fires. It has the same jsdom detection, install-once and restore behaviour.
|
|
2907
|
+
|
|
2908
|
+
Lit decides whether it can adopt stylesheets when its module is first evaluated, so call the shim
|
|
2909
|
+
in a `setupFiles` entry before anything imports Lit or a Lyra component. Importing
|
|
2910
|
+
`@aceshooting/lyra-ui/testing` does not load Lit:
|
|
2911
|
+
|
|
2912
|
+
```ts
|
|
2913
|
+
// vitest.setup.ts (environment: 'jsdom')
|
|
2914
|
+
import { installJsdomShims } from '@aceshooting/lyra-ui/testing';
|
|
2915
|
+
|
|
2916
|
+
installJsdomShims();
|
|
2917
|
+
```
|
|
2918
|
+
|
|
2701
2919
|
## Constructing a validated test event: `createLyraEvent()`
|
|
2702
2920
|
|
|
2703
2921
|
`@aceshooting/lyra-ui/testing` also exports
|
|
@@ -2730,8 +2948,9 @@ semantics of their own that this factory does not model.
|
|
|
2730
2948
|
|
|
2731
2949
|
## Driving a component's real activation path: interaction drivers
|
|
2732
2950
|
|
|
2733
|
-
For the exact gap `createLyraEvent()` leaves open — choosing an option,
|
|
2734
|
-
decision, toggling a switch, activating a step
|
|
2951
|
+
For the exact gap `createLyraEvent()` leaves open — choosing an option, a swatch or a currency,
|
|
2952
|
+
submitting a confirm decision, toggling a switch, activating a step, opening and closing a
|
|
2953
|
+
popover — `@aceshooting/lyra-ui/testing` exports a small
|
|
2735
2954
|
set of typed interaction drivers, one per interaction, that go through the real component's own
|
|
2736
2955
|
activation path (its own shadow-part lookup and `.click()`, the same as its own tests) instead of
|
|
2737
2956
|
a downstream suite reverse-engineering internal detail shapes or shadow-part selectors itself:
|
|
@@ -2739,17 +2958,43 @@ a downstream suite reverse-engineering internal detail shapes or shadow-part sel
|
|
|
2739
2958
|
```ts
|
|
2740
2959
|
import {
|
|
2741
2960
|
chooseOption,
|
|
2961
|
+
chooseSwatch,
|
|
2962
|
+
chooseCurrency,
|
|
2963
|
+
openPopover,
|
|
2964
|
+
closePopover,
|
|
2742
2965
|
submitConfirmDecision,
|
|
2743
2966
|
toggleSwitch,
|
|
2744
2967
|
activateStep,
|
|
2745
2968
|
} from '@aceshooting/lyra-ui/testing';
|
|
2746
2969
|
|
|
2747
2970
|
await chooseOption(combobox, 'banana'); // opens the listbox, clicks the matching [part="option"] row
|
|
2971
|
+
await chooseSwatch(swatchPicker, 'ruby'); // clicks the matching swatch radio
|
|
2972
|
+
await chooseCurrency(currencyPicker, 'EUR'); // opens the composed listbox, clicks the EUR option
|
|
2973
|
+
await openPopover(popover); // clicks the slotted (or `for`) trigger, waits for lr-after-show
|
|
2974
|
+
await closePopover(popover); // presses Escape, waits for lr-after-hide; { via: 'trigger' } clicks instead
|
|
2748
2975
|
await submitConfirmDecision(confirmBar, 'approved'); // clicks [part="approve-button"]
|
|
2749
2976
|
await toggleSwitch(switchEl); // calls switchEl.click(), lr-switch's own activation path
|
|
2750
2977
|
await activateStep(stepper, 'review'); // clicks the [part="step"] button for that stepId (or pass an index)
|
|
2751
2978
|
```
|
|
2752
2979
|
|
|
2980
|
+
`chooseSwatch(picker, value)` clicks the `<lr-swatch-picker>` radio whose value matches (the first
|
|
2981
|
+
enabled one when values repeat). When it resolves, `lr-change` (only if the selection moved) and
|
|
2982
|
+
`lr-activate` have fired. `chooseCurrency(picker, code)` drives the select, or the lazily loaded
|
|
2983
|
+
combobox of a `searchable` picker, that `<lr-currency-picker>` composes. The code must match the
|
|
2984
|
+
catalog exactly (`"EUR"`). When it resolves, the picker has emitted `input`, `lr-input`, `change`
|
|
2985
|
+
and `lr-change` once if the value changed.
|
|
2986
|
+
|
|
2987
|
+
`openPopover(popover, { timeoutMs? })` clicks the `<lr-popover>` interaction trigger (the slotted
|
|
2988
|
+
`trigger` element, else its `for` target) and resolves after `lr-show` and `lr-after-show`. A
|
|
2989
|
+
`hover`/`focus` popover opens and pins, as for a user's click. `closePopover(popover, { via?,
|
|
2990
|
+
timeoutMs? })` presses Escape on the focused element by default, which closes the topmost overlay,
|
|
2991
|
+
or clicks the trigger again with `via: 'trigger'`. It resolves after `lr-hide` and `lr-after-hide`,
|
|
2992
|
+
with focus back on the trigger. Both resolve at once when the popover is already in the requested
|
|
2993
|
+
state. They throw when the interaction is refused: an `lr-show`/`lr-hide` veto, a disabled popover
|
|
2994
|
+
or trigger, `trigger="manual"`, no trigger, or Escape going to a newer overlay. Use `show()`/`hide()`
|
|
2995
|
+
for manual and `showAt()` popovers. A missing `lr-after-*` event rejects after `timeoutMs`
|
|
2996
|
+
(default 2000).
|
|
2997
|
+
|
|
2753
2998
|
`chooseOption()` accepts any of `<lr-combobox>`, `<lr-select>`, `<lr-model-select>`,
|
|
2754
2999
|
`<lr-locale-picker>` and `<lr-voice-picker>` — every component that independently implements the
|
|
2755
3000
|
same `[part="option"]` row plus `data-value` delegated-click pattern for its own listbox/popup.
|
|
@@ -2765,13 +3010,14 @@ immediately after it see the render reached by that interaction. Host-driven asy
|
|
|
2765
3010
|
still need their own completion check. Each driver also throws a plain `Error` — never a
|
|
2766
3011
|
silent no-op — when the requested interaction cannot actually happen: the target is disabled, the
|
|
2767
3012
|
option owner/stepper is read-only or has no matching row/step currently rendered, or the confirm
|
|
2768
|
-
bar is already decided. That is the exact failure mode a hand-rolled event misses (for example
|
|
3013
|
+
bar is already decided, or a popover's lifecycle event was vetoed. That is the exact failure mode a hand-rolled event misses (for example
|
|
2769
3014
|
dispatching a confirm event without `cancelable`, which makes a `preventDefault()`-based
|
|
2770
3015
|
pending-state handler a silent no-op that still looks tested) — these drivers exercise the
|
|
2771
3016
|
component for real, so a precondition that blocks the interaction is surfaced as a thrown error
|
|
2772
3017
|
instead of quietly doing nothing.
|
|
2773
3018
|
|
|
2774
|
-
Pure DOM operations only (`Element.click()`, shadow-part queries,
|
|
3019
|
+
Pure DOM operations only (`Element.click()`, an Escape `KeyboardEvent`, shadow-part queries,
|
|
3020
|
+
public properties) — no
|
|
2775
3021
|
`@web/test-runner`/CDP-only helper, so they also run under a downstream suite's own
|
|
2776
3022
|
happy-dom/jsdom environment, not only a real browser.
|
|
2777
3023
|
|
|
@@ -3120,7 +3366,8 @@ arrowPadding?: number; hoverBridge?: HTMLElement; onPlaced?: (result: PlacementR
|
|
|
3120
3366
|
(`next`); the `value` getter/setter (`next`); `defaultValue`; `customError`; `disabled`; `required`; readonly
|
|
3121
3367
|
`effectiveDisabled`; the `form` getter/setter (`owner`); readonly `labels`, `validity`,
|
|
3122
3368
|
`validationMessage`, and `willValidate`; `setFormValue(next)`; `getForm()`; `checkValidity()`;
|
|
3123
|
-
`reportValidity()`; `setCustomValidity(message)`; `resetValidity()`; `formResetCallback()`;
|
|
3369
|
+
`reportValidity()`; `setCustomValidity(message)`; `resetValidity()`; `formResetCallback()`;
|
|
3370
|
+
`formDisabledCallback(disabled)`; and
|
|
3124
3371
|
`formStateRestoreCallback(state, reason)`.
|
|
3125
3372
|
Writing `null` to `defaultValue` removes its markup value and resets the default to the adapter's
|
|
3126
3373
|
empty value; reading it still returns `TValue`. This does not overwrite a dirty live value.
|
|
@@ -3143,7 +3390,8 @@ HTMLFormElement | null; set form(owner: FormOwnerValue); readonly labels: NodeLi
|
|
|
3143
3390
|
validity: ValidityState; readonly validationMessage: string; readonly willValidate: boolean;
|
|
3144
3391
|
setFormValue(next: TValue): void; getForm(): HTMLFormElement | null; checkValidity(): boolean;
|
|
3145
3392
|
reportValidity(): boolean; setCustomValidity(message: string): void; resetValidity(): void;
|
|
3146
|
-
formResetCallback(): void;
|
|
3393
|
+
formResetCallback(): void; formDisabledCallback(disabled: boolean): void;
|
|
3394
|
+
formStateRestoreCallback(state: FormSubmissionValue, reason:
|
|
3147
3395
|
'autocomplete' | 'restore'): void }`. The exported subclass seam is
|
|
3148
3396
|
`FormAssociatedSubclassInterface<TValue> { protected captureLiveValueCheckpoint(): { readonly
|
|
3149
3397
|
value: TValue; readonly dirty: boolean }; protected restoreLiveValueCheckpoint(checkpoint: {
|
|
@@ -4245,6 +4493,16 @@ These named interfaces and helper signatures are available to typed integrations
|
|
|
4245
4493
|
`resolveCanvasColor(/* public names: scope, color, fallback */): unknown`
|
|
4246
4494
|
`resolveCanvasColors(/* public names: scope, colors, fallback */): unknown`
|
|
4247
4495
|
|
|
4496
|
+
- **`internal-document-tokens-contracts`** — Shared utility contracts.
|
|
4497
|
+
`adoptLyraTokens(root: Document | ShadowRoot): void`
|
|
4498
|
+
Adopts the document token layer into a document or shadow root. Idempotent; see "Application
|
|
4499
|
+
shadow roots" in the styles and tokens guide for when a root needs it.
|
|
4500
|
+
|
|
4501
|
+
- **`internal-theme-scopes-contracts`** — Shared utility contracts.
|
|
4502
|
+
`findUnscopedThemeInputs(root?: Document | DocumentFragment | Element): Element[]`
|
|
4503
|
+
Lists elements that set an inline `--lr-theme-*` input the layer consumes without being a theme
|
|
4504
|
+
scope. Reads inline styles only and logs nothing.
|
|
4505
|
+
|
|
4248
4506
|
- **`internal-localization-runtime-contracts`** — Shared utility contracts.
|
|
4249
4507
|
`getLyraLocaleDirection(/* public names: locale */): unknown`
|
|
4250
4508
|
`getLyraLocale(): unknown`
|
|
@@ -4980,15 +5238,45 @@ These named interfaces and helper signatures are available to typed integrations
|
|
|
4980
5238
|
- **`testing-happy-dom-shims-contracts`** — Shared utility contracts.
|
|
4981
5239
|
`installHappyDomFormAssociatedShims(): unknown`
|
|
4982
5240
|
`installHappyDomShadowFocusShim(): unknown`
|
|
5241
|
+
`flattenCascadeLayers(/* public names: css */): unknown`
|
|
4983
5242
|
`installHappyDomAriaControlsShim(/* public names: proto */): unknown`
|
|
5243
|
+
`installHappyDomCascadeLayerShim(/* public names: proto, misbehaves */): unknown`
|
|
4984
5244
|
`installHappyDomShims(): unknown`
|
|
4985
5245
|
`installStubInternalsForTest(/* public names: host */): unknown`
|
|
4986
5246
|
|
|
5247
|
+
- **`testing-jsdom-shims-contracts`** — Shared utility contracts.
|
|
5248
|
+
`JsdomAdoptedStyleSheetsTargets {
|
|
5249
|
+
documentPrototype?: object;
|
|
5250
|
+
shadowRootPrototype?: object;
|
|
5251
|
+
styleSheetPrototype?: object;
|
|
5252
|
+
isJsdom?: () => boolean;
|
|
5253
|
+
}`
|
|
5254
|
+
`installJsdomAdoptedStyleSheetsShim(targets?: JsdomAdoptedStyleSheetsTargets): () => void`
|
|
5255
|
+
`JsdomFormAssociatedTargets {
|
|
5256
|
+
internalsPrototype?: object;
|
|
5257
|
+
elementPrototype?: object;
|
|
5258
|
+
isJsdom?: () => boolean;
|
|
5259
|
+
}`
|
|
5260
|
+
`installJsdomFormAssociatedShim(targets?: JsdomFormAssociatedTargets): () => void`
|
|
5261
|
+
`installJsdomShims(): () => void`
|
|
5262
|
+
See "jsdom: `installJsdomShims()`" above for the full contract.
|
|
5263
|
+
|
|
4987
5264
|
- **`testing-interaction-drivers-contracts`** — Shared utility contracts.
|
|
4988
5265
|
`chooseOption(/* public names: owner, value */): unknown`
|
|
4989
5266
|
`submitConfirmDecision(/* public names: owner, decision */): unknown`
|
|
4990
5267
|
`toggleSwitch(/* public names: switchEl */): unknown`
|
|
4991
5268
|
`activateStep(/* public names: stepper, target */): unknown`
|
|
5269
|
+
`chooseSwatch(/* public names: picker, value */): unknown`
|
|
5270
|
+
`chooseCurrency(/* public names: picker, code */): unknown`
|
|
5271
|
+
`PopoverDriverOptions {
|
|
5272
|
+
timeoutMs: unknown;
|
|
5273
|
+
}`
|
|
5274
|
+
`ClosePopoverOptions {
|
|
5275
|
+
via: unknown;
|
|
5276
|
+
timeoutMs: unknown;
|
|
5277
|
+
}`
|
|
5278
|
+
`openPopover(/* public names: popover, options */): unknown`
|
|
5279
|
+
`closePopover(/* public names: popover, options */): unknown`
|
|
4992
5280
|
See "Driving a component's real activation path: interaction drivers" above for the full contract.
|
|
4993
5281
|
|
|
4994
5282
|
- **`testing-wait-for-mount-contracts`** — Shared utility contracts.
|
|
@@ -5085,6 +5373,7 @@ These named interfaces and helper signatures are available to typed integrations
|
|
|
5085
5373
|
`parseLyraStyleRecord(value: unknown): Readonly<LyraStyle>`
|
|
5086
5374
|
`resetLyraStyle(fields?: readonly LyraStyleField[]): Readonly<LyraStyle>`
|
|
5087
5375
|
`setLyraStyle(choices: LyraStyleChoices): Readonly<LyraStyle>`
|
|
5376
|
+
`startLyraStyle(): Readonly<LyraStyle>`
|
|
5088
5377
|
|
|
5089
5378
|
- **`vue-contracts`** — Framework integration type contracts, including the multi-split
|
|
5090
5379
|
`for` launcher id and `trigger` element reference.
|
|
@@ -5873,7 +6162,35 @@ of the backdrop; the default foreground qualification covers 60%, while a custom
|
|
|
5873
6162
|
cannot guarantee contrast against every backdrop. Solid and accessibility preferences retain
|
|
5874
6163
|
opaque fills regardless of this input.
|
|
5875
6164
|
Dark Glass deepens the selected fill at opacity below 70% so light foregrounds remain readable
|
|
5876
|
-
against bright backdrops; at 70% and above, the selected fill keeps its original color.
|
|
6165
|
+
against bright backdrops; at 70% and above, the selected fill keeps its original color. The
|
|
6166
|
+
deepening blends toward a darkened `--lr-color-surface` (10% of the surface, the rest black), not
|
|
6167
|
+
pure black, so a lifted dark palette (for example a neutral grey `--lr-theme-color-surface-default`
|
|
6168
|
+
and overlay tokens) lifts its Glass chrome with it. That share is small on purpose: the stock
|
|
6169
|
+
palettes are qualified for 4.5:1 text over a pure white backdrop at 60% opacity, which caps how
|
|
6170
|
+
light the pane can get. To paint a lifted palette's own overlay colour, set `--lr-theme-surface-opacity`
|
|
6171
|
+
to 0.7 or higher.
|
|
6172
|
+
|
|
6173
|
+
`--lr-theme-surface-glass-dark-share` is the public input for that share. It is a percentage,
|
|
6174
|
+
default `10%`, read in dark mode only, below 70% opacity. It sets how much of `--lr-color-surface`
|
|
6175
|
+
the deepening anchor keeps (the rest is black), so raising it lifts dark Glass chrome toward the
|
|
6176
|
+
surface. It inherits, so set it on `:root` for the whole app or on any container for that subtree;
|
|
6177
|
+
values outside 0% to 100% clamp. It is deliberately not registered with `@property` (a registered
|
|
6178
|
+
inherited property slows every re-theme in Chromium), so a value that is not a percentage voids the
|
|
6179
|
+
dark fill; the development build warns about one set on `:root`. The default paints exactly as before. For a softer grey dark mode:
|
|
6180
|
+
|
|
6181
|
+
```css
|
|
6182
|
+
:root {
|
|
6183
|
+
--lr-theme-color-surface-default: #1f2023;
|
|
6184
|
+
--lr-theme-color-surface-raised: #1f2023;
|
|
6185
|
+
--lr-theme-color-surface-overlay: #1f2023;
|
|
6186
|
+
--lr-theme-surface-glass-dark-share: 60%;
|
|
6187
|
+
}
|
|
6188
|
+
```
|
|
6189
|
+
|
|
6190
|
+
The trade-off is contrast: the 4.5:1 qualification over a white backdrop at 60% opacity holds for
|
|
6191
|
+
the stock palettes only at the 10% default, and a lighter pane lowers light-text contrast over bright
|
|
6192
|
+
backdrops. After raising the share, re-measure your own text colours, or raise
|
|
6193
|
+
`--lr-theme-surface-opacity` to 0.7 or higher, where the fill keeps the palette's own colour.
|
|
5877
6194
|
Necessary control borders use the effective painted opacity: their glass adjustment grows as
|
|
5878
6195
|
transparency increases and disappears at 100% opacity. Ordinary and strong borders share this
|
|
5879
6196
|
adjustment; decorative borders and explicit component border overrides keep their own tokens.
|