@cardstack/boxel-cli 0.10.0 → 0.10.1-unstable.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/bundled-realms/pretui/README.md +49 -0
- package/bundled-realms/pretui/color/LICENSE +21 -0
- package/bundled-realms/pretui/color/README.md +155 -0
- package/bundled-realms/pretui/color/index.js +78 -0
- package/bundled-realms/pretui/color-engine.ts +1243 -0
- package/bundled-realms/pretui/components/accordion.gts +58 -0
- package/bundled-realms/pretui/components/accordion.md +60 -0
- package/bundled-realms/pretui/components/accordion.usage.gts +129 -0
- package/bundled-realms/pretui/components/action-bar.gts +407 -0
- package/bundled-realms/pretui/components/action-bar.md +48 -0
- package/bundled-realms/pretui/components/action-bar.usage.gts +213 -0
- package/bundled-realms/pretui/components/affix.gts +116 -0
- package/bundled-realms/pretui/components/affix.md +54 -0
- package/bundled-realms/pretui/components/affix.usage.gts +73 -0
- package/bundled-realms/pretui/components/agent-question.gts +116 -0
- package/bundled-realms/pretui/components/agent-question.md +50 -0
- package/bundled-realms/pretui/components/agent-question.usage.gts +22 -0
- package/bundled-realms/pretui/components/ai-instructions.gts +378 -0
- package/bundled-realms/pretui/components/ai-instructions.md +49 -0
- package/bundled-realms/pretui/components/ai-instructions.usage.gts +101 -0
- package/bundled-realms/pretui/components/alert-dialog.gts +223 -0
- package/bundled-realms/pretui/components/alert-dialog.md +76 -0
- package/bundled-realms/pretui/components/alert-dialog.usage.gts +128 -0
- package/bundled-realms/pretui/components/alert.gts +163 -0
- package/bundled-realms/pretui/components/alert.md +57 -0
- package/bundled-realms/pretui/components/alert.usage.gts +99 -0
- package/bundled-realms/pretui/components/amount-input.gts +621 -0
- package/bundled-realms/pretui/components/amount-input.md +63 -0
- package/bundled-realms/pretui/components/amount-input.usage.gts +170 -0
- package/bundled-realms/pretui/components/angle-dial.gts +367 -0
- package/bundled-realms/pretui/components/angle-dial.md +56 -0
- package/bundled-realms/pretui/components/angle-dial.usage.gts +166 -0
- package/bundled-realms/pretui/components/animated-image.gts +291 -0
- package/bundled-realms/pretui/components/animated-image.md +49 -0
- package/bundled-realms/pretui/components/animated-image.usage.gts +127 -0
- package/bundled-realms/pretui/components/app-shell.gts +19 -0
- package/bundled-realms/pretui/components/app-shell.md +43 -0
- package/bundled-realms/pretui/components/app-shell.usage.gts +52 -0
- package/bundled-realms/pretui/components/approval-footer.gts +69 -0
- package/bundled-realms/pretui/components/approval-footer.md +49 -0
- package/bundled-realms/pretui/components/approval-footer.usage.gts +22 -0
- package/bundled-realms/pretui/components/aspect-ratio.gts +328 -0
- package/bundled-realms/pretui/components/aspect-ratio.md +72 -0
- package/bundled-realms/pretui/components/aspect-ratio.usage.gts +174 -0
- package/bundled-realms/pretui/components/asset-grid.gts +542 -0
- package/bundled-realms/pretui/components/asset-grid.md +54 -0
- package/bundled-realms/pretui/components/asset-grid.usage.gts +171 -0
- package/bundled-realms/pretui/components/asset-well.gts +731 -0
- package/bundled-realms/pretui/components/asset-well.md +72 -0
- package/bundled-realms/pretui/components/asset-well.usage.gts +264 -0
- package/bundled-realms/pretui/components/audio-player.gts +152 -0
- package/bundled-realms/pretui/components/audio-player.md +51 -0
- package/bundled-realms/pretui/components/audio-player.usage.gts +118 -0
- package/bundled-realms/pretui/components/autocomplete.gts +1150 -0
- package/bundled-realms/pretui/components/autocomplete.md +67 -0
- package/bundled-realms/pretui/components/autocomplete.usage.gts +339 -0
- package/bundled-realms/pretui/components/avatar-group.gts +30 -0
- package/bundled-realms/pretui/components/avatar-group.md +48 -0
- package/bundled-realms/pretui/components/avatar-group.usage.gts +39 -0
- package/bundled-realms/pretui/components/avatar.gts +134 -0
- package/bundled-realms/pretui/components/avatar.md +69 -0
- package/bundled-realms/pretui/components/avatar.usage.gts +101 -0
- package/bundled-realms/pretui/components/backdrop.gts +179 -0
- package/bundled-realms/pretui/components/backdrop.md +56 -0
- package/bundled-realms/pretui/components/backdrop.usage.gts +223 -0
- package/bundled-realms/pretui/components/background-field.gts +743 -0
- package/bundled-realms/pretui/components/background-field.md +62 -0
- package/bundled-realms/pretui/components/background-field.usage.gts +328 -0
- package/bundled-realms/pretui/components/badge.gts +188 -0
- package/bundled-realms/pretui/components/badge.md +62 -0
- package/bundled-realms/pretui/components/badge.usage.gts +73 -0
- package/bundled-realms/pretui/components/bar-list.gts +255 -0
- package/bundled-realms/pretui/components/bar-list.md +49 -0
- package/bundled-realms/pretui/components/bar-list.usage.gts +129 -0
- package/bundled-realms/pretui/components/board.gts +108 -0
- package/bundled-realms/pretui/components/board.md +54 -0
- package/bundled-realms/pretui/components/board.usage.gts +321 -0
- package/bundled-realms/pretui/components/bottom-nav.gts +217 -0
- package/bundled-realms/pretui/components/bottom-nav.md +64 -0
- package/bundled-realms/pretui/components/bottom-nav.usage.gts +68 -0
- package/bundled-realms/pretui/components/breadcrumb.gts +56 -0
- package/bundled-realms/pretui/components/breadcrumb.md +52 -0
- package/bundled-realms/pretui/components/breadcrumb.usage.gts +24 -0
- package/bundled-realms/pretui/components/broken-link.gts +46 -0
- package/bundled-realms/pretui/components/broken-link.md +50 -0
- package/bundled-realms/pretui/components/broken-link.usage.gts +57 -0
- package/bundled-realms/pretui/components/button-group.gts +246 -0
- package/bundled-realms/pretui/components/button-group.md +46 -0
- package/bundled-realms/pretui/components/button-group.usage.gts +137 -0
- package/bundled-realms/pretui/components/button.examples.gts +67 -0
- package/bundled-realms/pretui/components/button.gts +594 -0
- package/bundled-realms/pretui/components/button.md +81 -0
- package/bundled-realms/pretui/components/button.usage.gts +159 -0
- package/bundled-realms/pretui/components/calendar.gts +457 -0
- package/bundled-realms/pretui/components/calendar.md +57 -0
- package/bundled-realms/pretui/components/calendar.usage.gts +161 -0
- package/bundled-realms/pretui/components/callout.gts +2 -0
- package/bundled-realms/pretui/components/callout.md +40 -0
- package/bundled-realms/pretui/components/callout.usage.gts +48 -0
- package/bundled-realms/pretui/components/card.gts +637 -0
- package/bundled-realms/pretui/components/card.md +105 -0
- package/bundled-realms/pretui/components/card.usage.gts +279 -0
- package/bundled-realms/pretui/components/carousel.gts +583 -0
- package/bundled-realms/pretui/components/carousel.md +53 -0
- package/bundled-realms/pretui/components/carousel.usage.gts +220 -0
- package/bundled-realms/pretui/components/cascader.gts +436 -0
- package/bundled-realms/pretui/components/cascader.md +61 -0
- package/bundled-realms/pretui/components/cascader.usage.gts +79 -0
- package/bundled-realms/pretui/components/channel-slider.gts +251 -0
- package/bundled-realms/pretui/components/channel-slider.md +51 -0
- package/bundled-realms/pretui/components/channel-slider.usage.gts +104 -0
- package/bundled-realms/pretui/components/chart.gts +1011 -0
- package/bundled-realms/pretui/components/chart.md +60 -0
- package/bundled-realms/pretui/components/chart.usage.gts +660 -0
- package/bundled-realms/pretui/components/checkbox-card.gts +82 -0
- package/bundled-realms/pretui/components/checkbox-card.md +73 -0
- package/bundled-realms/pretui/components/checkbox-card.usage.gts +114 -0
- package/bundled-realms/pretui/components/checkbox.examples.gts +61 -0
- package/bundled-realms/pretui/components/checkbox.gts +123 -0
- package/bundled-realms/pretui/components/checkbox.md +55 -0
- package/bundled-realms/pretui/components/checkbox.usage.gts +31 -0
- package/bundled-realms/pretui/components/chip.gts +136 -0
- package/bundled-realms/pretui/components/chip.md +54 -0
- package/bundled-realms/pretui/components/chip.usage.gts +97 -0
- package/bundled-realms/pretui/components/code-block.gts +888 -0
- package/bundled-realms/pretui/components/code-block.md +61 -0
- package/bundled-realms/pretui/components/code-block.usage.gts +374 -0
- package/bundled-realms/pretui/components/collapsed-turn.gts +44 -0
- package/bundled-realms/pretui/components/collapsed-turn.md +48 -0
- package/bundled-realms/pretui/components/collapsed-turn.usage.gts +21 -0
- package/bundled-realms/pretui/components/collapsible.gts +283 -0
- package/bundled-realms/pretui/components/collapsible.md +69 -0
- package/bundled-realms/pretui/components/collapsible.usage.gts +173 -0
- package/bundled-realms/pretui/components/color-area.gts +339 -0
- package/bundled-realms/pretui/components/color-area.md +49 -0
- package/bundled-realms/pretui/components/color-area.usage.gts +72 -0
- package/bundled-realms/pretui/components/color-field.gts +179 -0
- package/bundled-realms/pretui/components/color-field.md +47 -0
- package/bundled-realms/pretui/components/color-field.usage.gts +87 -0
- package/bundled-realms/pretui/components/color-palette.gts +198 -0
- package/bundled-realms/pretui/components/color-palette.md +48 -0
- package/bundled-realms/pretui/components/color-picker.gts +721 -0
- package/bundled-realms/pretui/components/color-picker.md +59 -0
- package/bundled-realms/pretui/components/color-picker.usage.gts +122 -0
- package/bundled-realms/pretui/components/color-stop-editor.gts +184 -0
- package/bundled-realms/pretui/components/color-stop-editor.md +46 -0
- package/bundled-realms/pretui/components/color-stop-editor.usage.gts +75 -0
- package/bundled-realms/pretui/components/combobox.gts +333 -0
- package/bundled-realms/pretui/components/combobox.md +49 -0
- package/bundled-realms/pretui/components/combobox.usage.gts +143 -0
- package/bundled-realms/pretui/components/command-palette.gts +982 -0
- package/bundled-realms/pretui/components/command-palette.md +47 -0
- package/bundled-realms/pretui/components/command-palette.usage.gts +95 -0
- package/bundled-realms/pretui/components/command.gts +2 -0
- package/bundled-realms/pretui/components/command.md +45 -0
- package/bundled-realms/pretui/components/command.usage.gts +58 -0
- package/bundled-realms/pretui/components/compaction-chip.gts +273 -0
- package/bundled-realms/pretui/components/compaction-chip.md +45 -0
- package/bundled-realms/pretui/components/compaction-chip.usage.gts +110 -0
- package/bundled-realms/pretui/components/comparison.gts +223 -0
- package/bundled-realms/pretui/components/comparison.md +46 -0
- package/bundled-realms/pretui/components/comparison.usage.gts +148 -0
- package/bundled-realms/pretui/components/composer.gts +566 -0
- package/bundled-realms/pretui/components/composer.md +59 -0
- package/bundled-realms/pretui/components/composer.usage.gts +173 -0
- package/bundled-realms/pretui/components/compound-field.gts +289 -0
- package/bundled-realms/pretui/components/compound-field.md +66 -0
- package/bundled-realms/pretui/components/compound-field.usage.gts +378 -0
- package/bundled-realms/pretui/components/contact-link.gts +583 -0
- package/bundled-realms/pretui/components/contact-link.md +53 -0
- package/bundled-realms/pretui/components/contact-link.usage.gts +273 -0
- package/bundled-realms/pretui/components/context-menu.gts +811 -0
- package/bundled-realms/pretui/components/context-menu.md +74 -0
- package/bundled-realms/pretui/components/context-menu.usage.gts +244 -0
- package/bundled-realms/pretui/components/copy-button.gts +237 -0
- package/bundled-realms/pretui/components/copy-button.md +71 -0
- package/bundled-realms/pretui/components/copy-button.usage.gts +135 -0
- package/bundled-realms/pretui/components/copy-fit.gts +396 -0
- package/bundled-realms/pretui/components/copy-fit.md +60 -0
- package/bundled-realms/pretui/components/copy-fit.usage.gts +200 -0
- package/bundled-realms/pretui/components/cta-band.gts +285 -0
- package/bundled-realms/pretui/components/cta-band.md +50 -0
- package/bundled-realms/pretui/components/cta-band.usage.gts +208 -0
- package/bundled-realms/pretui/components/cue.gts +180 -0
- package/bundled-realms/pretui/components/cue.md +53 -0
- package/bundled-realms/pretui/components/cue.usage.gts +88 -0
- package/bundled-realms/pretui/components/cursor-trail.gts +221 -0
- package/bundled-realms/pretui/components/cursor-trail.md +56 -0
- package/bundled-realms/pretui/components/cursor-trail.usage.gts +218 -0
- package/bundled-realms/pretui/components/dashboard-grid.gts +939 -0
- package/bundled-realms/pretui/components/dashboard-grid.md +60 -0
- package/bundled-realms/pretui/components/dashboard-grid.usage.gts +307 -0
- package/bundled-realms/pretui/components/dashboard-item.gts +286 -0
- package/bundled-realms/pretui/components/dashboard-item.md +52 -0
- package/bundled-realms/pretui/components/dashboard-item.usage.gts +87 -0
- package/bundled-realms/pretui/components/data-grid.gts +263 -0
- package/bundled-realms/pretui/components/data-grid.md +64 -0
- package/bundled-realms/pretui/components/data-grid.usage.gts +50 -0
- package/bundled-realms/pretui/components/data-table.gts +1618 -0
- package/bundled-realms/pretui/components/data-table.md +104 -0
- package/bundled-realms/pretui/components/data-table.usage.gts +324 -0
- package/bundled-realms/pretui/components/date-picker.gts +98 -0
- package/bundled-realms/pretui/components/date-picker.md +59 -0
- package/bundled-realms/pretui/components/date-picker.usage.gts +66 -0
- package/bundled-realms/pretui/components/date-range-picker.gts +131 -0
- package/bundled-realms/pretui/components/date-range-picker.md +55 -0
- package/bundled-realms/pretui/components/date-range-picker.usage.gts +125 -0
- package/bundled-realms/pretui/components/date-time-picker.gts +227 -0
- package/bundled-realms/pretui/components/date-time-picker.md +60 -0
- package/bundled-realms/pretui/components/date-time-picker.usage.gts +64 -0
- package/bundled-realms/pretui/components/defer.gts +374 -0
- package/bundled-realms/pretui/components/defer.md +61 -0
- package/bundled-realms/pretui/components/defer.usage.gts +174 -0
- package/bundled-realms/pretui/components/delta.gts +45 -0
- package/bundled-realms/pretui/components/delta.md +53 -0
- package/bundled-realms/pretui/components/delta.usage.gts +31 -0
- package/bundled-realms/pretui/components/descriptions.gts +365 -0
- package/bundled-realms/pretui/components/descriptions.md +73 -0
- package/bundled-realms/pretui/components/descriptions.usage.gts +123 -0
- package/bundled-realms/pretui/components/dialog.gts +153 -0
- package/bundled-realms/pretui/components/dialog.md +60 -0
- package/bundled-realms/pretui/components/dialog.usage.gts +86 -0
- package/bundled-realms/pretui/components/diff-block.gts +89 -0
- package/bundled-realms/pretui/components/diff-block.md +51 -0
- package/bundled-realms/pretui/components/diff-block.usage.gts +27 -0
- package/bundled-realms/pretui/components/disclosure.gts +2 -0
- package/bundled-realms/pretui/components/disclosure.md +45 -0
- package/bundled-realms/pretui/components/disclosure.usage.gts +47 -0
- package/bundled-realms/pretui/components/divider.gts +75 -0
- package/bundled-realms/pretui/components/divider.md +49 -0
- package/bundled-realms/pretui/components/divider.usage.gts +98 -0
- package/bundled-realms/pretui/components/doc-report.gts +306 -0
- package/bundled-realms/pretui/components/doc-report.md +45 -0
- package/bundled-realms/pretui/components/doc-report.usage.gts +126 -0
- package/bundled-realms/pretui/components/dock.gts +165 -0
- package/bundled-realms/pretui/components/dock.md +42 -0
- package/bundled-realms/pretui/components/dock.usage.gts +114 -0
- package/bundled-realms/pretui/components/drawer.gts +166 -0
- package/bundled-realms/pretui/components/drawer.md +66 -0
- package/bundled-realms/pretui/components/drawer.usage.gts +111 -0
- package/bundled-realms/pretui/components/dropzone.gts +314 -0
- package/bundled-realms/pretui/components/dropzone.md +56 -0
- package/bundled-realms/pretui/components/dropzone.usage.gts +203 -0
- package/bundled-realms/pretui/components/dueling-picklist.gts +991 -0
- package/bundled-realms/pretui/components/dueling-picklist.md +67 -0
- package/bundled-realms/pretui/components/dueling-picklist.usage.gts +182 -0
- package/bundled-realms/pretui/components/dynamic-island.gts +264 -0
- package/bundled-realms/pretui/components/dynamic-island.md +45 -0
- package/bundled-realms/pretui/components/dynamic-island.usage.gts +195 -0
- package/bundled-realms/pretui/components/easing-curve.gts +629 -0
- package/bundled-realms/pretui/components/easing-curve.md +46 -0
- package/bundled-realms/pretui/components/easing-curve.usage.gts +122 -0
- package/bundled-realms/pretui/components/edit-in-place.gts +559 -0
- package/bundled-realms/pretui/components/edit-in-place.md +63 -0
- package/bundled-realms/pretui/components/edit-in-place.usage.gts +209 -0
- package/bundled-realms/pretui/components/editable.gts +299 -0
- package/bundled-realms/pretui/components/editable.md +79 -0
- package/bundled-realms/pretui/components/editable.usage.gts +68 -0
- package/bundled-realms/pretui/components/email-input.gts +83 -0
- package/bundled-realms/pretui/components/email-input.md +52 -0
- package/bundled-realms/pretui/components/email-input.usage.gts +90 -0
- package/bundled-realms/pretui/components/emoji-button.gts +162 -0
- package/bundled-realms/pretui/components/emoji-button.md +46 -0
- package/bundled-realms/pretui/components/emoji-button.usage.gts +174 -0
- package/bundled-realms/pretui/components/emoji-picker.gts +1396 -0
- package/bundled-realms/pretui/components/emoji-picker.md +53 -0
- package/bundled-realms/pretui/components/emoji-picker.usage.gts +235 -0
- package/bundled-realms/pretui/components/empty-state.gts +162 -0
- package/bundled-realms/pretui/components/empty-state.md +63 -0
- package/bundled-realms/pretui/components/empty-state.usage.gts +113 -0
- package/bundled-realms/pretui/components/empty.gts +2 -0
- package/bundled-realms/pretui/components/empty.md +43 -0
- package/bundled-realms/pretui/components/empty.usage.gts +33 -0
- package/bundled-realms/pretui/components/entity-display.gts +126 -0
- package/bundled-realms/pretui/components/entity-display.md +50 -0
- package/bundled-realms/pretui/components/error-summary.gts +321 -0
- package/bundled-realms/pretui/components/error-summary.md +60 -0
- package/bundled-realms/pretui/components/error-summary.usage.gts +155 -0
- package/bundled-realms/pretui/components/expression-builder.gts +1211 -0
- package/bundled-realms/pretui/components/expression-builder.md +60 -0
- package/bundled-realms/pretui/components/expression-builder.usage.gts +246 -0
- package/bundled-realms/pretui/components/fab.gts +2 -0
- package/bundled-realms/pretui/components/fab.md +38 -0
- package/bundled-realms/pretui/components/fab.usage.gts +38 -0
- package/bundled-realms/pretui/components/feature-voting.gts +365 -0
- package/bundled-realms/pretui/components/feature-voting.md +44 -0
- package/bundled-realms/pretui/components/feature-voting.usage.gts +114 -0
- package/bundled-realms/pretui/components/feed.gts +244 -0
- package/bundled-realms/pretui/components/feed.md +56 -0
- package/bundled-realms/pretui/components/feed.usage.gts +250 -0
- package/bundled-realms/pretui/components/field-error.gts +127 -0
- package/bundled-realms/pretui/components/field-error.md +60 -0
- package/bundled-realms/pretui/components/field-error.usage.gts +146 -0
- package/bundled-realms/pretui/components/field.gts +185 -0
- package/bundled-realms/pretui/components/field.md +60 -0
- package/bundled-realms/pretui/components/field.usage.gts +73 -0
- package/bundled-realms/pretui/components/fieldset.gts +124 -0
- package/bundled-realms/pretui/components/fieldset.md +65 -0
- package/bundled-realms/pretui/components/fieldset.usage.gts +105 -0
- package/bundled-realms/pretui/components/file-trigger.gts +185 -0
- package/bundled-realms/pretui/components/file-trigger.md +53 -0
- package/bundled-realms/pretui/components/file-trigger.usage.gts +121 -0
- package/bundled-realms/pretui/components/file-upload.gts +353 -0
- package/bundled-realms/pretui/components/file-upload.md +63 -0
- package/bundled-realms/pretui/components/file-upload.usage.gts +64 -0
- package/bundled-realms/pretui/components/filmstrip.gts +465 -0
- package/bundled-realms/pretui/components/filmstrip.md +53 -0
- package/bundled-realms/pretui/components/filmstrip.usage.gts +115 -0
- package/bundled-realms/pretui/components/filter-chips.gts +236 -0
- package/bundled-realms/pretui/components/filter-chips.md +58 -0
- package/bundled-realms/pretui/components/filter-chips.usage.gts +102 -0
- package/bundled-realms/pretui/components/filter-set.gts +293 -0
- package/bundled-realms/pretui/components/filter-set.md +60 -0
- package/bundled-realms/pretui/components/filter-set.usage.gts +145 -0
- package/bundled-realms/pretui/components/float-button.gts +339 -0
- package/bundled-realms/pretui/components/float-button.md +69 -0
- package/bundled-realms/pretui/components/float-button.usage.gts +134 -0
- package/bundled-realms/pretui/components/fold.gts +86 -0
- package/bundled-realms/pretui/components/fold.md +54 -0
- package/bundled-realms/pretui/components/fold.usage.gts +19 -0
- package/bundled-realms/pretui/components/form-field.gts +609 -0
- package/bundled-realms/pretui/components/form-field.md +77 -0
- package/bundled-realms/pretui/components/form-field.usage.gts +279 -0
- package/bundled-realms/pretui/components/form-footer.gts +246 -0
- package/bundled-realms/pretui/components/form-footer.md +59 -0
- package/bundled-realms/pretui/components/form-footer.usage.gts +217 -0
- package/bundled-realms/pretui/components/form-layout.gts +130 -0
- package/bundled-realms/pretui/components/form-layout.md +52 -0
- package/bundled-realms/pretui/components/form-layout.usage.gts +200 -0
- package/bundled-realms/pretui/components/form-section.gts +434 -0
- package/bundled-realms/pretui/components/form-section.md +67 -0
- package/bundled-realms/pretui/components/form-section.usage.gts +402 -0
- package/bundled-realms/pretui/components/form.gts +315 -0
- package/bundled-realms/pretui/components/form.md +82 -0
- package/bundled-realms/pretui/components/form.usage.gts +306 -0
- package/bundled-realms/pretui/components/format-bytes.gts +212 -0
- package/bundled-realms/pretui/components/format-bytes.md +47 -0
- package/bundled-realms/pretui/components/format-bytes.usage.gts +274 -0
- package/bundled-realms/pretui/components/format-date.gts +249 -0
- package/bundled-realms/pretui/components/format-date.md +55 -0
- package/bundled-realms/pretui/components/format-date.usage.gts +245 -0
- package/bundled-realms/pretui/components/format-number.gts +138 -0
- package/bundled-realms/pretui/components/format-number.md +51 -0
- package/bundled-realms/pretui/components/format-number.usage.gts +261 -0
- package/bundled-realms/pretui/components/formatted-value.gts +65 -0
- package/bundled-realms/pretui/components/freestyle-usage.gts +311 -0
- package/bundled-realms/pretui/components/freestyle-usage.md +49 -0
- package/bundled-realms/pretui/components/gallery.gts +819 -0
- package/bundled-realms/pretui/components/gallery.md +65 -0
- package/bundled-realms/pretui/components/gallery.usage.gts +212 -0
- package/bundled-realms/pretui/components/gradient-editor.gts +682 -0
- package/bundled-realms/pretui/components/gradient-editor.md +43 -0
- package/bundled-realms/pretui/components/gradient-editor.usage.gts +69 -0
- package/bundled-realms/pretui/components/graph-layout.md +54 -0
- package/bundled-realms/pretui/components/graph-layout.usage.gts +343 -0
- package/bundled-realms/pretui/components/graph-outline.gts +553 -0
- package/bundled-realms/pretui/components/graph-outline.md +50 -0
- package/bundled-realms/pretui/components/graph-outline.usage.gts +88 -0
- package/bundled-realms/pretui/components/grid.gts +68 -0
- package/bundled-realms/pretui/components/grid.md +54 -0
- package/bundled-realms/pretui/components/grid.usage.gts +144 -0
- package/bundled-realms/pretui/components/handle.gts +192 -0
- package/bundled-realms/pretui/components/handle.md +55 -0
- package/bundled-realms/pretui/components/handle.usage.gts +174 -0
- package/bundled-realms/pretui/components/hero-split.gts +307 -0
- package/bundled-realms/pretui/components/hero-split.md +50 -0
- package/bundled-realms/pretui/components/hero-split.usage.gts +200 -0
- package/bundled-realms/pretui/components/hover-actions.gts +485 -0
- package/bundled-realms/pretui/components/hover-actions.md +55 -0
- package/bundled-realms/pretui/components/hover-actions.usage.gts +224 -0
- package/bundled-realms/pretui/components/hover-card.gts +347 -0
- package/bundled-realms/pretui/components/hover-card.md +72 -0
- package/bundled-realms/pretui/components/hover-card.usage.gts +174 -0
- package/bundled-realms/pretui/components/hover-video-player.gts +315 -0
- package/bundled-realms/pretui/components/hover-video-player.md +57 -0
- package/bundled-realms/pretui/components/hover-video-player.usage.gts +152 -0
- package/bundled-realms/pretui/components/icon-button.examples.gts +69 -0
- package/bundled-realms/pretui/components/icon-button.gts +153 -0
- package/bundled-realms/pretui/components/icon-button.md +72 -0
- package/bundled-realms/pretui/components/icon-button.usage.gts +208 -0
- package/bundled-realms/pretui/components/image-cropper.gts +693 -0
- package/bundled-realms/pretui/components/image-cropper.md +52 -0
- package/bundled-realms/pretui/components/image-cropper.usage.gts +108 -0
- package/bundled-realms/pretui/components/image-frame.gts +91 -0
- package/bundled-realms/pretui/components/image-frame.md +42 -0
- package/bundled-realms/pretui/components/image-frame.usage.gts +28 -0
- package/bundled-realms/pretui/components/image.gts +326 -0
- package/bundled-realms/pretui/components/image.md +71 -0
- package/bundled-realms/pretui/components/image.usage.gts +126 -0
- package/bundled-realms/pretui/components/in-view.gts +245 -0
- package/bundled-realms/pretui/components/in-view.md +53 -0
- package/bundled-realms/pretui/components/in-view.usage.gts +264 -0
- package/bundled-realms/pretui/components/indicator.gts +137 -0
- package/bundled-realms/pretui/components/indicator.md +60 -0
- package/bundled-realms/pretui/components/indicator.usage.gts +66 -0
- package/bundled-realms/pretui/components/infinite-scroll.gts +163 -0
- package/bundled-realms/pretui/components/infinite-scroll.md +54 -0
- package/bundled-realms/pretui/components/infinite-scroll.usage.gts +73 -0
- package/bundled-realms/pretui/components/input-group.gts +264 -0
- package/bundled-realms/pretui/components/input-group.md +55 -0
- package/bundled-realms/pretui/components/input-group.usage.gts +283 -0
- package/bundled-realms/pretui/components/input.examples.gts +61 -0
- package/bundled-realms/pretui/components/input.gts +202 -0
- package/bundled-realms/pretui/components/input.md +67 -0
- package/bundled-realms/pretui/components/input.usage.gts +208 -0
- package/bundled-realms/pretui/components/interactive-input.gts +343 -0
- package/bundled-realms/pretui/components/interactive-input.md +45 -0
- package/bundled-realms/pretui/components/interactive-input.usage.gts +98 -0
- package/bundled-realms/pretui/components/item.gts +218 -0
- package/bundled-realms/pretui/components/item.md +66 -0
- package/bundled-realms/pretui/components/item.usage.gts +121 -0
- package/bundled-realms/pretui/components/joystick.gts +381 -0
- package/bundled-realms/pretui/components/joystick.md +52 -0
- package/bundled-realms/pretui/components/joystick.usage.gts +140 -0
- package/bundled-realms/pretui/components/json-editor.gts +1016 -0
- package/bundled-realms/pretui/components/json-editor.md +51 -0
- package/bundled-realms/pretui/components/json-editor.usage.gts +230 -0
- package/bundled-realms/pretui/components/json-tree.gts +596 -0
- package/bundled-realms/pretui/components/json-tree.md +52 -0
- package/bundled-realms/pretui/components/json-tree.usage.gts +217 -0
- package/bundled-realms/pretui/components/jump-chip.gts +230 -0
- package/bundled-realms/pretui/components/jump-chip.md +44 -0
- package/bundled-realms/pretui/components/jump-chip.usage.gts +151 -0
- package/bundled-realms/pretui/components/kbd.gts +60 -0
- package/bundled-realms/pretui/components/kbd.md +50 -0
- package/bundled-realms/pretui/components/kbd.usage.gts +98 -0
- package/bundled-realms/pretui/components/key-value.gts +150 -0
- package/bundled-realms/pretui/components/key-value.md +81 -0
- package/bundled-realms/pretui/components/key-value.usage.gts +125 -0
- package/bundled-realms/pretui/components/known-date.gts +770 -0
- package/bundled-realms/pretui/components/known-date.md +56 -0
- package/bundled-realms/pretui/components/known-date.usage.gts +192 -0
- package/bundled-realms/pretui/components/label.gts +60 -0
- package/bundled-realms/pretui/components/label.md +56 -0
- package/bundled-realms/pretui/components/label.usage.gts +63 -0
- package/bundled-realms/pretui/components/layer-manager.gts +1884 -0
- package/bundled-realms/pretui/components/layer-manager.md +59 -0
- package/bundled-realms/pretui/components/layer-manager.usage.gts +233 -0
- package/bundled-realms/pretui/components/lightbox.gts +461 -0
- package/bundled-realms/pretui/components/lightbox.md +57 -0
- package/bundled-realms/pretui/components/lightbox.usage.gts +180 -0
- package/bundled-realms/pretui/components/line-grid.examples.gts +156 -0
- package/bundled-realms/pretui/components/line-grid.gts +523 -0
- package/bundled-realms/pretui/components/line-grid.md +55 -0
- package/bundled-realms/pretui/components/line-grid.usage.gts +181 -0
- package/bundled-realms/pretui/components/list.gts +679 -0
- package/bundled-realms/pretui/components/list.md +90 -0
- package/bundled-realms/pretui/components/list.usage.gts +203 -0
- package/bundled-realms/pretui/components/loader.gts +2 -0
- package/bundled-realms/pretui/components/loader.md +33 -0
- package/bundled-realms/pretui/components/loader.usage.gts +35 -0
- package/bundled-realms/pretui/components/loading-overlay.gts +120 -0
- package/bundled-realms/pretui/components/loading-overlay.md +68 -0
- package/bundled-realms/pretui/components/loading-overlay.usage.gts +102 -0
- package/bundled-realms/pretui/components/loading-state.gts +124 -0
- package/bundled-realms/pretui/components/loading-state.md +48 -0
- package/bundled-realms/pretui/components/loading-state.usage.gts +16 -0
- package/bundled-realms/pretui/components/lookup.gts +451 -0
- package/bundled-realms/pretui/components/lookup.md +59 -0
- package/bundled-realms/pretui/components/lookup.usage.gts +235 -0
- package/bundled-realms/pretui/components/magnetic.gts +158 -0
- package/bundled-realms/pretui/components/magnetic.md +48 -0
- package/bundled-realms/pretui/components/magnetic.usage.gts +125 -0
- package/bundled-realms/pretui/components/marquee.gts +141 -0
- package/bundled-realms/pretui/components/marquee.md +43 -0
- package/bundled-realms/pretui/components/marquee.usage.gts +116 -0
- package/bundled-realms/pretui/components/masonry.gts +95 -0
- package/bundled-realms/pretui/components/masonry.md +59 -0
- package/bundled-realms/pretui/components/masonry.usage.gts +238 -0
- package/bundled-realms/pretui/components/media-inspector.gts +145 -0
- package/bundled-realms/pretui/components/media-inspector.md +46 -0
- package/bundled-realms/pretui/components/media-inspector.usage.gts +83 -0
- package/bundled-realms/pretui/components/media-player.gts +1133 -0
- package/bundled-realms/pretui/components/media-player.md +74 -0
- package/bundled-realms/pretui/components/media-player.usage.gts +265 -0
- package/bundled-realms/pretui/components/media-viewer.gts +136 -0
- package/bundled-realms/pretui/components/media-viewer.md +47 -0
- package/bundled-realms/pretui/components/media-viewer.usage.gts +70 -0
- package/bundled-realms/pretui/components/mentions.gts +340 -0
- package/bundled-realms/pretui/components/mentions.md +65 -0
- package/bundled-realms/pretui/components/mentions.usage.gts +73 -0
- package/bundled-realms/pretui/components/menu-panel.gts +367 -0
- package/bundled-realms/pretui/components/menu.gts +652 -0
- package/bundled-realms/pretui/components/menu.md +69 -0
- package/bundled-realms/pretui/components/menu.usage.gts +116 -0
- package/bundled-realms/pretui/components/menubar.gts +1200 -0
- package/bundled-realms/pretui/components/menubar.md +49 -0
- package/bundled-realms/pretui/components/menubar.usage.gts +220 -0
- package/bundled-realms/pretui/components/meter.gts +113 -0
- package/bundled-realms/pretui/components/meter.md +50 -0
- package/bundled-realms/pretui/components/meter.usage.gts +50 -0
- package/bundled-realms/pretui/components/modal.gts +2 -0
- package/bundled-realms/pretui/components/modal.md +41 -0
- package/bundled-realms/pretui/components/modal.usage.gts +50 -0
- package/bundled-realms/pretui/components/model-viewer.gts +658 -0
- package/bundled-realms/pretui/components/model-viewer.md +57 -0
- package/bundled-realms/pretui/components/model-viewer.usage.gts +123 -0
- package/bundled-realms/pretui/components/money-input.gts +66 -0
- package/bundled-realms/pretui/components/money-input.md +43 -0
- package/bundled-realms/pretui/components/money-input.usage.gts +293 -0
- package/bundled-realms/pretui/components/morphing-dialog.gts +173 -0
- package/bundled-realms/pretui/components/morphing-dialog.md +46 -0
- package/bundled-realms/pretui/components/morphing-dialog.usage.gts +168 -0
- package/bundled-realms/pretui/components/morphing-popover.gts +245 -0
- package/bundled-realms/pretui/components/morphing-popover.md +47 -0
- package/bundled-realms/pretui/components/morphing-popover.usage.gts +176 -0
- package/bundled-realms/pretui/components/multi-select.gts +392 -0
- package/bundled-realms/pretui/components/multi-select.md +57 -0
- package/bundled-realms/pretui/components/multi-select.usage.gts +97 -0
- package/bundled-realms/pretui/components/native-select.gts +212 -0
- package/bundled-realms/pretui/components/native-select.md +77 -0
- package/bundled-realms/pretui/components/native-select.usage.gts +109 -0
- package/bundled-realms/pretui/components/navigation-menu.gts +351 -0
- package/bundled-realms/pretui/components/navigation-menu.md +65 -0
- package/bundled-realms/pretui/components/navigation-menu.usage.gts +61 -0
- package/bundled-realms/pretui/components/node-canvas.gts +1174 -0
- package/bundled-realms/pretui/components/node-canvas.md +57 -0
- package/bundled-realms/pretui/components/node-canvas.usage.gts +548 -0
- package/bundled-realms/pretui/components/node-card.gts +181 -0
- package/bundled-realms/pretui/components/node-card.md +53 -0
- package/bundled-realms/pretui/components/node-card.usage.gts +156 -0
- package/bundled-realms/pretui/components/notification.gts +242 -0
- package/bundled-realms/pretui/components/notification.md +69 -0
- package/bundled-realms/pretui/components/notification.usage.gts +125 -0
- package/bundled-realms/pretui/components/number-input.gts +191 -0
- package/bundled-realms/pretui/components/number-input.md +54 -0
- package/bundled-realms/pretui/components/number-input.usage.gts +132 -0
- package/bundled-realms/pretui/components/odometer.gts +349 -0
- package/bundled-realms/pretui/components/odometer.md +55 -0
- package/bundled-realms/pretui/components/odometer.usage.gts +258 -0
- package/bundled-realms/pretui/components/onboarding.gts +298 -0
- package/bundled-realms/pretui/components/onboarding.md +48 -0
- package/bundled-realms/pretui/components/onboarding.usage.gts +155 -0
- package/bundled-realms/pretui/components/origin-grid.gts +486 -0
- package/bundled-realms/pretui/components/origin-grid.md +47 -0
- package/bundled-realms/pretui/components/origin-grid.usage.gts +87 -0
- package/bundled-realms/pretui/components/otp-input.gts +289 -0
- package/bundled-realms/pretui/components/otp-input.md +47 -0
- package/bundled-realms/pretui/components/otp-input.usage.gts +131 -0
- package/bundled-realms/pretui/components/page-scaffold.gts +343 -0
- package/bundled-realms/pretui/components/page-scaffold.md +57 -0
- package/bundled-realms/pretui/components/page-scaffold.usage.gts +391 -0
- package/bundled-realms/pretui/components/pagination.gts +150 -0
- package/bundled-realms/pretui/components/pagination.md +56 -0
- package/bundled-realms/pretui/components/pagination.usage.gts +33 -0
- package/bundled-realms/pretui/components/panel-section.gts +301 -0
- package/bundled-realms/pretui/components/panel-section.md +48 -0
- package/bundled-realms/pretui/components/panel-section.usage.gts +137 -0
- package/bundled-realms/pretui/components/panel.gts +158 -0
- package/bundled-realms/pretui/components/panel.md +58 -0
- package/bundled-realms/pretui/components/panel.usage.gts +82 -0
- package/bundled-realms/pretui/components/password-input.gts +329 -0
- package/bundled-realms/pretui/components/password-input.md +58 -0
- package/bundled-realms/pretui/components/password-input.usage.gts +156 -0
- package/bundled-realms/pretui/components/password-strength.gts +485 -0
- package/bundled-realms/pretui/components/password-strength.md +50 -0
- package/bundled-realms/pretui/components/password-strength.usage.gts +34 -0
- package/bundled-realms/pretui/components/path-text.gts +288 -0
- package/bundled-realms/pretui/components/path-text.md +58 -0
- package/bundled-realms/pretui/components/path-text.usage.gts +239 -0
- package/bundled-realms/pretui/components/period-input.gts +1100 -0
- package/bundled-realms/pretui/components/period-input.md +54 -0
- package/bundled-realms/pretui/components/period-input.usage.gts +299 -0
- package/bundled-realms/pretui/components/phone-input.gts +80 -0
- package/bundled-realms/pretui/components/phone-input.md +55 -0
- package/bundled-realms/pretui/components/phone-input.usage.gts +91 -0
- package/bundled-realms/pretui/components/pin-input.gts +2 -0
- package/bundled-realms/pretui/components/pin-input.md +45 -0
- package/bundled-realms/pretui/components/pin-input.usage.gts +39 -0
- package/bundled-realms/pretui/components/pip-scale.gts +717 -0
- package/bundled-realms/pretui/components/pip-scale.md +55 -0
- package/bundled-realms/pretui/components/pip-scale.usage.gts +318 -0
- package/bundled-realms/pretui/components/popconfirm.gts +380 -0
- package/bundled-realms/pretui/components/popconfirm.md +78 -0
- package/bundled-realms/pretui/components/popconfirm.usage.gts +171 -0
- package/bundled-realms/pretui/components/popover.gts +198 -0
- package/bundled-realms/pretui/components/popover.md +57 -0
- package/bundled-realms/pretui/components/popover.usage.gts +106 -0
- package/bundled-realms/pretui/components/popup.gts +85 -0
- package/bundled-realms/pretui/components/popup.md +42 -0
- package/bundled-realms/pretui/components/popup.usage.gts +23 -0
- package/bundled-realms/pretui/components/presence.gts +156 -0
- package/bundled-realms/pretui/components/presence.md +55 -0
- package/bundled-realms/pretui/components/presence.usage.gts +204 -0
- package/bundled-realms/pretui/components/progress-bar.gts +177 -0
- package/bundled-realms/pretui/components/progress-bar.md +63 -0
- package/bundled-realms/pretui/components/progress-bar.usage.gts +172 -0
- package/bundled-realms/pretui/components/progress-radial.gts +67 -0
- package/bundled-realms/pretui/components/progress-radial.md +55 -0
- package/bundled-realms/pretui/components/progress-radial.usage.gts +76 -0
- package/bundled-realms/pretui/components/prompt-library.gts +358 -0
- package/bundled-realms/pretui/components/prompt-library.md +45 -0
- package/bundled-realms/pretui/components/prompt-library.usage.gts +117 -0
- package/bundled-realms/pretui/components/property-row.gts +316 -0
- package/bundled-realms/pretui/components/property-row.md +55 -0
- package/bundled-realms/pretui/components/property-row.usage.gts +146 -0
- package/bundled-realms/pretui/components/property-sheet.gts +133 -0
- package/bundled-realms/pretui/components/property-sheet.md +48 -0
- package/bundled-realms/pretui/components/property-sheet.usage.gts +132 -0
- package/bundled-realms/pretui/components/prose.gts +31 -0
- package/bundled-realms/pretui/components/prose.md +57 -0
- package/bundled-realms/pretui/components/prose.usage.gts +15 -0
- package/bundled-realms/pretui/components/pulsing-border.gts +297 -0
- package/bundled-realms/pretui/components/pulsing-border.md +65 -0
- package/bundled-realms/pretui/components/pulsing-border.usage.gts +253 -0
- package/bundled-realms/pretui/components/qr-code.gts +660 -0
- package/bundled-realms/pretui/components/qr-code.md +58 -0
- package/bundled-realms/pretui/components/qr-code.usage.gts +224 -0
- package/bundled-realms/pretui/components/queued-message.gts +83 -0
- package/bundled-realms/pretui/components/queued-message.md +53 -0
- package/bundled-realms/pretui/components/queued-message.usage.gts +21 -0
- package/bundled-realms/pretui/components/radio-card.gts +88 -0
- package/bundled-realms/pretui/components/radio-card.md +72 -0
- package/bundled-realms/pretui/components/radio-card.usage.gts +148 -0
- package/bundled-realms/pretui/components/radio-group.gts +119 -0
- package/bundled-realms/pretui/components/radio-group.md +46 -0
- package/bundled-realms/pretui/components/radio-group.usage.gts +80 -0
- package/bundled-realms/pretui/components/range-slider.gts +34 -0
- package/bundled-realms/pretui/components/range-slider.md +47 -0
- package/bundled-realms/pretui/components/range-slider.usage.gts +46 -0
- package/bundled-realms/pretui/components/rating.examples.gts +67 -0
- package/bundled-realms/pretui/components/rating.gts +266 -0
- package/bundled-realms/pretui/components/rating.md +55 -0
- package/bundled-realms/pretui/components/rating.usage.gts +96 -0
- package/bundled-realms/pretui/components/readiness-panel.gts +856 -0
- package/bundled-realms/pretui/components/readiness-panel.md +64 -0
- package/bundled-realms/pretui/components/readiness-panel.usage.gts +372 -0
- package/bundled-realms/pretui/components/recommendation.gts +316 -0
- package/bundled-realms/pretui/components/recommendation.md +49 -0
- package/bundled-realms/pretui/components/recommendation.usage.gts +103 -0
- package/bundled-realms/pretui/components/record-detail.gts +1170 -0
- package/bundled-realms/pretui/components/record-detail.md +63 -0
- package/bundled-realms/pretui/components/record-detail.usage.gts +533 -0
- package/bundled-realms/pretui/components/record-face.gts +153 -0
- package/bundled-realms/pretui/components/record-pill.gts +116 -0
- package/bundled-realms/pretui/components/record-pill.md +55 -0
- package/bundled-realms/pretui/components/record-pill.usage.gts +108 -0
- package/bundled-realms/pretui/components/relative-time.gts +88 -0
- package/bundled-realms/pretui/components/relative-time.md +58 -0
- package/bundled-realms/pretui/components/relative-time.usage.gts +89 -0
- package/bundled-realms/pretui/components/reorder.gts +620 -0
- package/bundled-realms/pretui/components/reorder.md +47 -0
- package/bundled-realms/pretui/components/reorder.usage.gts +171 -0
- package/bundled-realms/pretui/components/resizable.gts +2 -0
- package/bundled-realms/pretui/components/resizable.md +37 -0
- package/bundled-realms/pretui/components/resizable.usage.gts +53 -0
- package/bundled-realms/pretui/components/result-card.gts +68 -0
- package/bundled-realms/pretui/components/result-card.md +45 -0
- package/bundled-realms/pretui/components/result-card.usage.gts +29 -0
- package/bundled-realms/pretui/components/result.gts +204 -0
- package/bundled-realms/pretui/components/result.md +67 -0
- package/bundled-realms/pretui/components/result.usage.gts +85 -0
- package/bundled-realms/pretui/components/rule-row.gts +462 -0
- package/bundled-realms/pretui/components/rule-row.md +60 -0
- package/bundled-realms/pretui/components/rule-row.usage.gts +157 -0
- package/bundled-realms/pretui/components/scroll-area.gts +121 -0
- package/bundled-realms/pretui/components/scroll-area.md +59 -0
- package/bundled-realms/pretui/components/scroll-area.usage.gts +175 -0
- package/bundled-realms/pretui/components/scroll-progress.gts +222 -0
- package/bundled-realms/pretui/components/scroll-progress.md +48 -0
- package/bundled-realms/pretui/components/scroll-progress.usage.gts +162 -0
- package/bundled-realms/pretui/components/scroller.gts +323 -0
- package/bundled-realms/pretui/components/scroller.md +44 -0
- package/bundled-realms/pretui/components/scroller.usage.gts +184 -0
- package/bundled-realms/pretui/components/scrub-input.gts +691 -0
- package/bundled-realms/pretui/components/scrub-input.md +61 -0
- package/bundled-realms/pretui/components/scrub-input.usage.gts +275 -0
- package/bundled-realms/pretui/components/search-input.gts +141 -0
- package/bundled-realms/pretui/components/search-input.md +56 -0
- package/bundled-realms/pretui/components/search-input.usage.gts +91 -0
- package/bundled-realms/pretui/components/segmented-control.gts +198 -0
- package/bundled-realms/pretui/components/segmented-control.md +39 -0
- package/bundled-realms/pretui/components/segmented-control.usage.gts +66 -0
- package/bundled-realms/pretui/components/select.examples.gts +80 -0
- package/bundled-realms/pretui/components/select.gts +481 -0
- package/bundled-realms/pretui/components/select.md +71 -0
- package/bundled-realms/pretui/components/select.usage.gts +109 -0
- package/bundled-realms/pretui/components/separator.gts +2 -0
- package/bundled-realms/pretui/components/separator.md +36 -0
- package/bundled-realms/pretui/components/separator.usage.gts +32 -0
- package/bundled-realms/pretui/components/session-prep.gts +164 -0
- package/bundled-realms/pretui/components/session-prep.md +48 -0
- package/bundled-realms/pretui/components/session-prep.usage.gts +122 -0
- package/bundled-realms/pretui/components/sheet-toolbar.gts +130 -0
- package/bundled-realms/pretui/components/sheet-toolbar.md +51 -0
- package/bundled-realms/pretui/components/sheet-toolbar.usage.gts +151 -0
- package/bundled-realms/pretui/components/sheet.gts +1166 -0
- package/bundled-realms/pretui/components/sheet.md +78 -0
- package/bundled-realms/pretui/components/sheet.usage.gts +318 -0
- package/bundled-realms/pretui/components/sidebar.gts +1165 -0
- package/bundled-realms/pretui/components/sidebar.md +88 -0
- package/bundled-realms/pretui/components/sidebar.usage.gts +360 -0
- package/bundled-realms/pretui/components/signature-pad.gts +840 -0
- package/bundled-realms/pretui/components/signature-pad.md +57 -0
- package/bundled-realms/pretui/components/signature-pad.usage.gts +222 -0
- package/bundled-realms/pretui/components/skeleton.gts +46 -0
- package/bundled-realms/pretui/components/skeleton.md +56 -0
- package/bundled-realms/pretui/components/skeleton.usage.gts +56 -0
- package/bundled-realms/pretui/components/skip-link.gts +65 -0
- package/bundled-realms/pretui/components/skip-link.md +49 -0
- package/bundled-realms/pretui/components/skip-link.usage.gts +47 -0
- package/bundled-realms/pretui/components/slide-over.gts +2 -0
- package/bundled-realms/pretui/components/slide-over.md +41 -0
- package/bundled-realms/pretui/components/slide-over.usage.gts +50 -0
- package/bundled-realms/pretui/components/slider.examples.gts +61 -0
- package/bundled-realms/pretui/components/slider.gts +331 -0
- package/bundled-realms/pretui/components/slider.md +59 -0
- package/bundled-realms/pretui/components/slider.usage.gts +99 -0
- package/bundled-realms/pretui/components/sliding-highlight.gts +249 -0
- package/bundled-realms/pretui/components/sliding-highlight.md +58 -0
- package/bundled-realms/pretui/components/sliding-highlight.usage.gts +184 -0
- package/bundled-realms/pretui/components/snackbar.gts +2 -0
- package/bundled-realms/pretui/components/snackbar.md +34 -0
- package/bundled-realms/pretui/components/snackbar.usage.gts +31 -0
- package/bundled-realms/pretui/components/sonner.gts +2 -0
- package/bundled-realms/pretui/components/sonner.md +42 -0
- package/bundled-realms/pretui/components/sonner.usage.gts +43 -0
- package/bundled-realms/pretui/components/sparkline.gts +233 -0
- package/bundled-realms/pretui/components/sparkline.md +58 -0
- package/bundled-realms/pretui/components/sparkline.usage.gts +74 -0
- package/bundled-realms/pretui/components/spinner.gts +57 -0
- package/bundled-realms/pretui/components/spinner.md +49 -0
- package/bundled-realms/pretui/components/spinner.usage.gts +65 -0
- package/bundled-realms/pretui/components/split-panes.gts +69 -0
- package/bundled-realms/pretui/components/split-panes.md +54 -0
- package/bundled-realms/pretui/components/split-panes.usage.gts +171 -0
- package/bundled-realms/pretui/components/spotlight.gts +174 -0
- package/bundled-realms/pretui/components/spotlight.md +51 -0
- package/bundled-realms/pretui/components/spotlight.usage.gts +197 -0
- package/bundled-realms/pretui/components/stack-divider.gts +58 -0
- package/bundled-realms/pretui/components/stack.gts +284 -0
- package/bundled-realms/pretui/components/stack.md +81 -0
- package/bundled-realms/pretui/components/stack.usage.gts +228 -0
- package/bundled-realms/pretui/components/stacking-cards.gts +137 -0
- package/bundled-realms/pretui/components/stacking-cards.md +40 -0
- package/bundled-realms/pretui/components/stacking-cards.usage.gts +124 -0
- package/bundled-realms/pretui/components/stat.gts +216 -0
- package/bundled-realms/pretui/components/stat.md +57 -0
- package/bundled-realms/pretui/components/stat.usage.gts +16 -0
- package/bundled-realms/pretui/components/statement-table.examples.gts +185 -0
- package/bundled-realms/pretui/components/statement-table.gts +792 -0
- package/bundled-realms/pretui/components/statement-table.md +58 -0
- package/bundled-realms/pretui/components/statement-table.usage.gts +252 -0
- package/bundled-realms/pretui/components/status-chip.gts +37 -0
- package/bundled-realms/pretui/components/status-chip.md +48 -0
- package/bundled-realms/pretui/components/status-chip.usage.gts +36 -0
- package/bundled-realms/pretui/components/step-list.gts +624 -0
- package/bundled-realms/pretui/components/step-list.md +50 -0
- package/bundled-realms/pretui/components/step-list.usage.gts +166 -0
- package/bundled-realms/pretui/components/stepper.gts +201 -0
- package/bundled-realms/pretui/components/stepper.md +54 -0
- package/bundled-realms/pretui/components/stepper.usage.gts +103 -0
- package/bundled-realms/pretui/components/steps-with-media.gts +254 -0
- package/bundled-realms/pretui/components/steps-with-media.md +54 -0
- package/bundled-realms/pretui/components/steps-with-media.usage.gts +208 -0
- package/bundled-realms/pretui/components/streaming-text.gts +77 -0
- package/bundled-realms/pretui/components/streaming-text.md +55 -0
- package/bundled-realms/pretui/components/streaming-text.usage.gts +15 -0
- package/bundled-realms/pretui/components/swatch-chip.gts +104 -0
- package/bundled-realms/pretui/components/swatch-chip.md +47 -0
- package/bundled-realms/pretui/components/swatch-chip.usage.gts +21 -0
- package/bundled-realms/pretui/components/swatch.gts +141 -0
- package/bundled-realms/pretui/components/swatch.md +50 -0
- package/bundled-realms/pretui/components/swatch.usage.gts +80 -0
- package/bundled-realms/pretui/components/switch.examples.gts +53 -0
- package/bundled-realms/pretui/components/switch.gts +118 -0
- package/bundled-realms/pretui/components/switch.md +62 -0
- package/bundled-realms/pretui/components/switch.usage.gts +59 -0
- package/bundled-realms/pretui/components/table-of-contents.gts +384 -0
- package/bundled-realms/pretui/components/table-of-contents.md +75 -0
- package/bundled-realms/pretui/components/table-of-contents.usage.gts +270 -0
- package/bundled-realms/pretui/components/table.gts +158 -0
- package/bundled-realms/pretui/components/table.md +80 -0
- package/bundled-realms/pretui/components/table.usage.gts +44 -0
- package/bundled-realms/pretui/components/tabs.gts +117 -0
- package/bundled-realms/pretui/components/tabs.md +58 -0
- package/bundled-realms/pretui/components/tabs.usage.gts +94 -0
- package/bundled-realms/pretui/components/tags-input.gts +52 -0
- package/bundled-realms/pretui/components/tags-input.md +48 -0
- package/bundled-realms/pretui/components/tags-input.usage.gts +56 -0
- package/bundled-realms/pretui/components/task-row.gts +483 -0
- package/bundled-realms/pretui/components/task-row.md +48 -0
- package/bundled-realms/pretui/components/task-row.usage.gts +119 -0
- package/bundled-realms/pretui/components/terminal-animation.gts +355 -0
- package/bundled-realms/pretui/components/terminal-animation.md +49 -0
- package/bundled-realms/pretui/components/terminal-animation.usage.gts +110 -0
- package/bundled-realms/pretui/components/text-effects.gts +339 -0
- package/bundled-realms/pretui/components/text-effects.md +49 -0
- package/bundled-realms/pretui/components/text-effects.usage.gts +192 -0
- package/bundled-realms/pretui/components/text-morph.gts +292 -0
- package/bundled-realms/pretui/components/text-morph.md +45 -0
- package/bundled-realms/pretui/components/text-morph.usage.gts +117 -0
- package/bundled-realms/pretui/components/text-rotate.gts +121 -0
- package/bundled-realms/pretui/components/text-rotate.md +44 -0
- package/bundled-realms/pretui/components/text-rotate.usage.gts +73 -0
- package/bundled-realms/pretui/components/text-scramble.gts +189 -0
- package/bundled-realms/pretui/components/text-scramble.md +42 -0
- package/bundled-realms/pretui/components/text-scramble.usage.gts +80 -0
- package/bundled-realms/pretui/components/text-shimmer.gts +89 -0
- package/bundled-realms/pretui/components/text-shimmer.md +42 -0
- package/bundled-realms/pretui/components/text-shimmer.usage.gts +69 -0
- package/bundled-realms/pretui/components/textarea.gts +112 -0
- package/bundled-realms/pretui/components/textarea.md +51 -0
- package/bundled-realms/pretui/components/textarea.usage.gts +100 -0
- package/bundled-realms/pretui/components/theme-frame.gts +272 -0
- package/bundled-realms/pretui/components/theme-frame.md +48 -0
- package/bundled-realms/pretui/components/thinking.gts +431 -0
- package/bundled-realms/pretui/components/thinking.md +47 -0
- package/bundled-realms/pretui/components/thinking.usage.gts +134 -0
- package/bundled-realms/pretui/components/tilt.gts +194 -0
- package/bundled-realms/pretui/components/tilt.md +50 -0
- package/bundled-realms/pretui/components/tilt.usage.gts +174 -0
- package/bundled-realms/pretui/components/time-input.gts +583 -0
- package/bundled-realms/pretui/components/time-input.md +51 -0
- package/bundled-realms/pretui/components/time-input.usage.gts +110 -0
- package/bundled-realms/pretui/components/timeline.gts +269 -0
- package/bundled-realms/pretui/components/timeline.md +63 -0
- package/bundled-realms/pretui/components/timeline.usage.gts +180 -0
- package/bundled-realms/pretui/components/toast.gts +85 -0
- package/bundled-realms/pretui/components/toast.md +57 -0
- package/bundled-realms/pretui/components/toast.usage.gts +18 -0
- package/bundled-realms/pretui/components/toaster.gts +808 -0
- package/bundled-realms/pretui/components/toaster.md +83 -0
- package/bundled-realms/pretui/components/toaster.usage.gts +256 -0
- package/bundled-realms/pretui/components/toggle-group.gts +435 -0
- package/bundled-realms/pretui/components/toggle-group.md +59 -0
- package/bundled-realms/pretui/components/toggle-group.usage.gts +260 -0
- package/bundled-realms/pretui/components/toggle-matrix.gts +994 -0
- package/bundled-realms/pretui/components/toggle-matrix.md +44 -0
- package/bundled-realms/pretui/components/toggle-matrix.usage.gts +243 -0
- package/bundled-realms/pretui/components/toggle.gts +235 -0
- package/bundled-realms/pretui/components/toggle.md +59 -0
- package/bundled-realms/pretui/components/toggle.usage.gts +244 -0
- package/bundled-realms/pretui/components/token-input.gts +483 -0
- package/bundled-realms/pretui/components/token-input.md +50 -0
- package/bundled-realms/pretui/components/token-input.usage.gts +137 -0
- package/bundled-realms/pretui/components/token.gts +197 -0
- package/bundled-realms/pretui/components/token.md +63 -0
- package/bundled-realms/pretui/components/token.usage.gts +128 -0
- package/bundled-realms/pretui/components/toolbar.gts +62 -0
- package/bundled-realms/pretui/components/toolbar.md +50 -0
- package/bundled-realms/pretui/components/toolbar.usage.gts +78 -0
- package/bundled-realms/pretui/components/tooltip.gts +212 -0
- package/bundled-realms/pretui/components/tooltip.md +53 -0
- package/bundled-realms/pretui/components/tooltip.usage.gts +64 -0
- package/bundled-realms/pretui/components/tour.gts +436 -0
- package/bundled-realms/pretui/components/tour.md +62 -0
- package/bundled-realms/pretui/components/tour.usage.gts +70 -0
- package/bundled-realms/pretui/components/transfer.gts +2 -0
- package/bundled-realms/pretui/components/transfer.md +39 -0
- package/bundled-realms/pretui/components/transfer.usage.gts +52 -0
- package/bundled-realms/pretui/components/transmute.gts +103 -0
- package/bundled-realms/pretui/components/transmute.md +49 -0
- package/bundled-realms/pretui/components/transmute.usage.gts +16 -0
- package/bundled-realms/pretui/components/tree-select.gts +596 -0
- package/bundled-realms/pretui/components/tree-select.md +70 -0
- package/bundled-realms/pretui/components/tree-select.usage.gts +75 -0
- package/bundled-realms/pretui/components/tree.gts +532 -0
- package/bundled-realms/pretui/components/tree.md +68 -0
- package/bundled-realms/pretui/components/tree.usage.gts +278 -0
- package/bundled-realms/pretui/components/trim-bar.gts +611 -0
- package/bundled-realms/pretui/components/trim-bar.md +48 -0
- package/bundled-realms/pretui/components/trim-bar.usage.gts +112 -0
- package/bundled-realms/pretui/components/typewriter.gts +122 -0
- package/bundled-realms/pretui/components/typewriter.md +45 -0
- package/bundled-realms/pretui/components/typewriter.usage.gts +105 -0
- package/bundled-realms/pretui/components/typography.gts +379 -0
- package/bundled-realms/pretui/components/typography.md +77 -0
- package/bundled-realms/pretui/components/typography.usage.gts +52 -0
- package/bundled-realms/pretui/components/url-input.gts +130 -0
- package/bundled-realms/pretui/components/url-input.md +58 -0
- package/bundled-realms/pretui/components/url-input.usage.gts +97 -0
- package/bundled-realms/pretui/components/usage-action.gts +16 -0
- package/bundled-realms/pretui/components/usage-argument.gts +109 -0
- package/bundled-realms/pretui/components/usage-argument.md +44 -0
- package/bundled-realms/pretui/components/usage-array.gts +80 -0
- package/bundled-realms/pretui/components/usage-array.md +47 -0
- package/bundled-realms/pretui/components/usage-bool.gts +62 -0
- package/bundled-realms/pretui/components/usage-bool.md +47 -0
- package/bundled-realms/pretui/components/usage-component-arg.gts +16 -0
- package/bundled-realms/pretui/components/usage-css-variable.gts +56 -0
- package/bundled-realms/pretui/components/usage-css-variable.md +48 -0
- package/bundled-realms/pretui/components/usage-number.gts +127 -0
- package/bundled-realms/pretui/components/usage-number.md +48 -0
- package/bundled-realms/pretui/components/usage-object.gts +58 -0
- package/bundled-realms/pretui/components/usage-object.md +48 -0
- package/bundled-realms/pretui/components/usage-string.gts +89 -0
- package/bundled-realms/pretui/components/usage-string.md +46 -0
- package/bundled-realms/pretui/components/usage-yield.gts +16 -0
- package/bundled-realms/pretui/components/value-input.gts +265 -0
- package/bundled-realms/pretui/components/value-input.md +49 -0
- package/bundled-realms/pretui/components/value-input.usage.gts +176 -0
- package/bundled-realms/pretui/components/video-player.gts +80 -0
- package/bundled-realms/pretui/components/video-player.md +46 -0
- package/bundled-realms/pretui/components/video-player.usage.gts +107 -0
- package/bundled-realms/pretui/components/viewport.gts +520 -0
- package/bundled-realms/pretui/components/viewport.md +55 -0
- package/bundled-realms/pretui/components/visually-hidden.gts +49 -0
- package/bundled-realms/pretui/components/visually-hidden.md +47 -0
- package/bundled-realms/pretui/components/visually-hidden.usage.gts +27 -0
- package/bundled-realms/pretui/components/watermark.gts +141 -0
- package/bundled-realms/pretui/components/watermark.md +58 -0
- package/bundled-realms/pretui/components/watermark.usage.gts +63 -0
- package/bundled-realms/pretui/components/waveform.gts +376 -0
- package/bundled-realms/pretui/components/waveform.md +56 -0
- package/bundled-realms/pretui/components/waveform.usage.gts +131 -0
- package/bundled-realms/pretui/components/wizard.gts +677 -0
- package/bundled-realms/pretui/components/wizard.md +58 -0
- package/bundled-realms/pretui/components/wizard.usage.gts +188 -0
- package/bundled-realms/pretui/components/work-item.gts +207 -0
- package/bundled-realms/pretui/components/work-item.md +58 -0
- package/bundled-realms/pretui/components/work-item.usage.gts +103 -0
- package/bundled-realms/pretui/components/zoomable-frame.gts +541 -0
- package/bundled-realms/pretui/components/zoomable-frame.md +50 -0
- package/bundled-realms/pretui/components/zoomable-frame.usage.gts +175 -0
- package/bundled-realms/pretui/cropper/LICENSE +21 -0
- package/bundled-realms/pretui/cropper/README.md +92 -0
- package/bundled-realms/pretui/cropper/index.js +81 -0
- package/bundled-realms/pretui/data-component.gts +1161 -0
- package/bundled-realms/pretui/demo-design-layers.gts +112 -0
- package/bundled-realms/pretui/demo-design-tools.gts +463 -0
- package/bundled-realms/pretui/demo-design-value.gts +9 -0
- package/bundled-realms/pretui/demo-forms-core.gts +82 -0
- package/bundled-realms/pretui/demo-forms-expression.gts +76 -0
- package/bundled-realms/pretui/demo-forms-record.gts +16 -0
- package/bundled-realms/pretui/demo-foundations-more.gts +10 -0
- package/bundled-realms/pretui/demo-foundations.gts +8 -0
- package/bundled-realms/pretui/demo-ink-feedback.gts +12 -0
- package/bundled-realms/pretui/demo-json.gts +17 -0
- package/bundled-realms/pretui/demo-locations.ts +103 -0
- package/bundled-realms/pretui/demo-media-library.gts +101 -0
- package/bundled-realms/pretui/demo-media.gts +6 -0
- package/bundled-realms/pretui/demo-menu.gts +182 -0
- package/bundled-realms/pretui/demo-motion-core.gts +4 -0
- package/bundled-realms/pretui/demo-motion-pointer.gts +21 -0
- package/bundled-realms/pretui/demo-reading-format.gts +10 -0
- package/bundled-realms/pretui/demo-structure-dashboard.gts +212 -0
- package/bundled-realms/pretui/demo-structure-data.gts +4 -0
- package/bundled-realms/pretui/demo-structure-scroll.gts +19 -0
- package/bundled-realms/pretui/demo-structure.gts +21 -0
- package/bundled-realms/pretui/demo-surfaces-grid.gts +104 -0
- package/bundled-realms/pretui/demo-texture.gts +21 -0
- package/bundled-realms/pretui/docs/catalog-taxonomy.md +200 -0
- package/bundled-realms/pretui/docs/composites.md +13 -0
- package/bundled-realms/pretui/docs/reading.md +12 -0
- package/bundled-realms/pretui/docs/structure.md +8 -0
- package/bundled-realms/pretui/emoji-data/LICENSE +202 -0
- package/bundled-realms/pretui/emoji-data/LICENSE.data +202 -0
- package/bundled-realms/pretui/emoji-data/LICENSE.emojibase +21 -0
- package/bundled-realms/pretui/emoji-data/LICENSE.unicode +39 -0
- package/bundled-realms/pretui/emoji-data/README.md +360 -0
- package/bundled-realms/pretui/emoji-data/data.ts +45 -0
- package/bundled-realms/pretui/emoji-data/engine.ts +465 -0
- package/bundled-realms/pretui/example-gallery.gts +129 -0
- package/bundled-realms/pretui/examples-kit.gts +228 -0
- package/bundled-realms/pretui/examples-listing.gts +51 -0
- package/bundled-realms/pretui/examples.gts +584 -0
- package/bundled-realms/pretui/focus.gts +459 -0
- package/bundled-realms/pretui/gridstack/LICENSE +21 -0
- package/bundled-realms/pretui/gridstack/README.md +103 -0
- package/bundled-realms/pretui/gridstack/index.js +169 -0
- package/bundled-realms/pretui/icon-registry.gts +753 -0
- package/bundled-realms/pretui/index.json +11 -0
- package/bundled-realms/pretui/internal/agentic-chat.gts +101 -0
- package/bundled-realms/pretui/internal/blocks.gts +35 -0
- package/bundled-realms/pretui/internal/choice-cards.gts +258 -0
- package/bundled-realms/pretui/internal/color-fixtures.gts +3 -0
- package/bundled-realms/pretui/internal/composites-fixtures.gts +16 -0
- package/bundled-realms/pretui/internal/corner-mark.gts +83 -0
- package/bundled-realms/pretui/internal/design-tools.gts +881 -0
- package/bundled-realms/pretui/internal/extras.gts +31 -0
- package/bundled-realms/pretui/internal/feedback.gts +27 -0
- package/bundled-realms/pretui/internal/file-intake-fixtures.gts +17 -0
- package/bundled-realms/pretui/internal/file-intake.gts +193 -0
- package/bundled-realms/pretui/internal/forms-core.gts +394 -0
- package/bundled-realms/pretui/internal/forms-expression.gts +837 -0
- package/bundled-realms/pretui/internal/forms-picker-fixtures.gts +10 -0
- package/bundled-realms/pretui/internal/forms-picker.gts +129 -0
- package/bundled-realms/pretui/internal/forms-record.gts +173 -0
- package/bundled-realms/pretui/internal/freestyle.gts +117 -0
- package/bundled-realms/pretui/internal/ink.gts +25 -0
- package/bundled-realms/pretui/internal/json-tree.gts +526 -0
- package/bundled-realms/pretui/internal/keep-style.gts +168 -0
- package/bundled-realms/pretui/internal/media-assets.gts +10 -0
- package/bundled-realms/pretui/internal/media-library.gts +14 -0
- package/bundled-realms/pretui/internal/media-viewer.gts +322 -0
- package/bundled-realms/pretui/internal/media-wave.gts +270 -0
- package/bundled-realms/pretui/internal/menu.gts +522 -0
- package/bundled-realms/pretui/internal/money-fixtures.gts +6 -0
- package/bundled-realms/pretui/internal/money.gts +477 -0
- package/bundled-realms/pretui/internal/motion-core.gts +54 -0
- package/bundled-realms/pretui/internal/motion-pointer.gts +234 -0
- package/bundled-realms/pretui/internal/overlay-confirm.gts +35 -0
- package/bundled-realms/pretui/internal/overlay.gts +291 -0
- package/bundled-realms/pretui/internal/reading-extras.gts +56 -0
- package/bundled-realms/pretui/internal/reading-format.gts +232 -0
- package/bundled-realms/pretui/internal/reading-listing.gts +232 -0
- package/bundled-realms/pretui/internal/structure-chart.gts +414 -0
- package/bundled-realms/pretui/internal/structure-dashboard.gts +503 -0
- package/bundled-realms/pretui/internal/structure-flow.gts +48 -0
- package/bundled-realms/pretui/internal/structure-layout-fixtures.gts +36 -0
- package/bundled-realms/pretui/internal/structure-layout.gts +99 -0
- package/bundled-realms/pretui/internal/structure-morph.gts +140 -0
- package/bundled-realms/pretui/internal/structure-scenes.gts +25 -0
- package/bundled-realms/pretui/internal/structure-scroll.gts +72 -0
- package/bundled-realms/pretui/internal/structure-shell-fixtures.gts +25 -0
- package/bundled-realms/pretui/internal/surfaces-canvas-fixtures.gts +5 -0
- package/bundled-realms/pretui/internal/surfaces-canvas.gts +283 -0
- package/bundled-realms/pretui/internal/texture.gts +81 -0
- package/bundled-realms/pretui/internal/toggle-controls-fixtures.gts +7 -0
- package/bundled-realms/pretui/internal/toggle-controls.gts +81 -0
- package/bundled-realms/pretui/json-model.ts +1981 -0
- package/bundled-realms/pretui/media-chrome/LICENSE +19 -0
- package/bundled-realms/pretui/media-chrome/README.md +111 -0
- package/bundled-realms/pretui/media-chrome/index.js +1647 -0
- package/bundled-realms/pretui/media-examples.gts +315 -0
- package/bundled-realms/pretui/model-viewer/LICENSE +202 -0
- package/{LICENSE → bundled-realms/pretui/model-viewer/LICENSE-gainmap-js} +1 -1
- package/bundled-realms/pretui/model-viewer/LICENSE-lit +28 -0
- package/bundled-realms/pretui/model-viewer/LICENSE-three +21 -0
- package/bundled-realms/pretui/model-viewer/NOTICE +67 -0
- package/bundled-realms/pretui/model-viewer/README.md +122 -0
- package/bundled-realms/pretui/model-viewer/index.js +6413 -0
- package/bundled-realms/pretui/package.json +51 -0
- package/bundled-realms/pretui/photoswipe/LICENSE +21 -0
- package/bundled-realms/pretui/photoswipe/README.md +91 -0
- package/bundled-realms/pretui/photoswipe/index.js +149 -0
- package/bundled-realms/pretui/photoswipe/style.ts +465 -0
- package/bundled-realms/pretui/plot/LICENSE +13 -0
- package/bundled-realms/pretui/plot/LICENSE.d3 +13 -0
- package/bundled-realms/pretui/plot/LICENSE.interval-tree-1d +22 -0
- package/bundled-realms/pretui/plot/LICENSE.isoformat +13 -0
- package/bundled-realms/pretui/plot/README.md +35 -0
- package/bundled-realms/pretui/plot/index.d.ts +31 -0
- package/bundled-realms/pretui/plot/index.js +449 -0
- package/bundled-realms/pretui/pretui-component.gts +1336 -0
- package/bundled-realms/pretui/pretui-css.gts +380 -0
- package/bundled-realms/pretui/pretui-primitives.gts +162 -0
- package/bundled-realms/pretui/qrcode/LICENSE +34 -0
- package/bundled-realms/pretui/qrcode/README.md +87 -0
- package/bundled-realms/pretui/qrcode/index.js +35 -0
- package/bundled-realms/pretui/realm.json +16 -0
- package/bundled-realms/pretui/registry.ts +40 -0
- package/bundled-realms/pretui/sigpad/LICENSE +21 -0
- package/bundled-realms/pretui/sigpad/README.md +103 -0
- package/bundled-realms/pretui/sigpad/index.js +30 -0
- package/bundled-realms/pretui/structure-dashboard-css.ts +166 -0
- package/bundled-realms/pretui/surfaces/README.md +37 -0
- package/bundled-realms/pretui/surfaces/canvas/LICENSE.d3 +168 -0
- package/bundled-realms/pretui/surfaces/canvas/LICENSE.xyflow +21 -0
- package/bundled-realms/pretui/surfaces/canvas/index.js +25420 -0
- package/bundled-realms/pretui/surfaces/grid/LICENSE.tanstack +50 -0
- package/bundled-realms/pretui/surfaces/grid/index.js +21478 -0
- package/bundled-realms/pretui/surfaces/layout/index.js +9036 -0
- package/bundled-realms/pretui/surfaces-canvas-css.ts +1640 -0
- package/bundled-realms/pretui/surfaces-canvas-layout.ts +607 -0
- package/bundled-realms/pretui/tsconfig.json +54 -0
- package/bundled-realms/pretui/wavesurfer/LICENSE +29 -0
- package/bundled-realms/pretui/wavesurfer/README.md +85 -0
- package/bundled-realms/pretui/wavesurfer/index.js +184 -0
- package/bundled-realms/pretui/zxcvbn/LICENSE +21 -0
- package/bundled-realms/pretui/zxcvbn/README.md +192 -0
- package/bundled-realms/pretui/zxcvbn/index.d.ts +28 -0
- package/bundled-realms/pretui/zxcvbn/index.js +5931 -0
- package/bundled-test-harness/index.html +1 -1
- package/bundled-test-harness/tests/index.html +1 -1
- package/dist/api.js +1 -1
- package/dist/index.js +33 -33
- package/package.json +1 -1
- package/src/lib/test-engine.ts +14 -4
|
@@ -0,0 +1,1884 @@
|
|
|
1
|
+
// Pretui — LayerManager: a layers panel with nesting, visibility, locking and keyboard reordering.
|
|
2
|
+
// Pretui — design-layers: LayerManager.
|
|
3
|
+
//
|
|
4
|
+
// The ordered, nestable, visibility-and-lock list every design tool has, and
|
|
5
|
+
// the one every implementation of it gets wrong in the same place.
|
|
6
|
+
//
|
|
7
|
+
// ── The naming collision, stated up front ───────────────────────────────
|
|
8
|
+
//
|
|
9
|
+
// The boxel-catalog sourcing analysis (§15) uses the name `LayerManager` for
|
|
10
|
+
// something else entirely: a module-level **z-index allocator** that orders
|
|
11
|
+
// the kit's seven stacking surfaces (`Popup`, `Popover`, `Dialog`, `Drawer`,
|
|
12
|
+
// `Tooltip`, `Menu`, `Toast`) inside a tier. That is a real and separate
|
|
13
|
+
// need, it is a utility rather than a rendered component, and Pretui already
|
|
14
|
+
// carries the tier scale for it in `pretui-css.gts` (`PRETUI_Z`,
|
|
15
|
+
// `PretuiZLayer`). The two must not share a name in one kit. This file is
|
|
16
|
+
// the DESIGN-TOOL layer list; the allocator wants a name of its own —
|
|
17
|
+
// `ZAllocator` or `StackOrder` — and its z-window rationale from the source
|
|
18
|
+
// is worth preserving verbatim as a comment wherever it lands.
|
|
19
|
+
//
|
|
20
|
+
// ── The one thing that makes this component worth building ──────────────
|
|
21
|
+
//
|
|
22
|
+
// E5 of the sourcing analysis audited five drag implementations across the
|
|
23
|
+
// corpus. Four had **no keyboard path at all** — `<div>` handlers, no
|
|
24
|
+
// `tabindex`, no `role`, no move-to-bucket command, no live region. A
|
|
25
|
+
// reorder that requires a pointer is not a reorder with a missing feature;
|
|
26
|
+
// it is a control half the readers cannot operate. So the keyboard path here
|
|
27
|
+
// is the PRIMARY implementation and the pointer path is written on top of
|
|
28
|
+
// it: `layerDrag` calls the very same four operations the arrow keys call,
|
|
29
|
+
// which is why they cannot drift apart.
|
|
30
|
+
//
|
|
31
|
+
// The four operations, and why they are the right four:
|
|
32
|
+
//
|
|
33
|
+
// raise / lower swap with the previous / next SIBLING
|
|
34
|
+
// indent become the last child of the previous sibling
|
|
35
|
+
// outdent become the next sibling of the parent
|
|
36
|
+
//
|
|
37
|
+
// Any position in any tree is reachable by a sequence of those four, they
|
|
38
|
+
// each have an obvious announcement, and each one is visually continuous —
|
|
39
|
+
// the row lands adjacent to where it left. The alternative model, "drop
|
|
40
|
+
// anywhere in the flattened list", needs hit-testing, produces ambiguous
|
|
41
|
+
// targets at every level boundary, and is exactly what the corpus's
|
|
42
|
+
// `document.elementFromPoint()` on every `pointermove` was paying for.
|
|
43
|
+
//
|
|
44
|
+
// ── Better than the inspiration (E5, and every layers panel) ────────────
|
|
45
|
+
//
|
|
46
|
+
// • **Keyboard reorder ACROSS nesting levels**, not just within a level.
|
|
47
|
+
// Up/down reorder among siblings; left/right change the nesting. E5's
|
|
48
|
+
// three sources could not reorder at all without a pointer.
|
|
49
|
+
// • **Two forced synchronous layouts per pointermove, deleted.** The
|
|
50
|
+
// sources called `document.elementFromPoint()` on every move and then
|
|
51
|
+
// `getBoundingClientRect()` on every tile in the hovered zone,
|
|
52
|
+
// unthrottled. This reads ONE rect, once, at pointerdown, and derives
|
|
53
|
+
// every step from pointer deltas against it.
|
|
54
|
+
// • **`pointercancel` is handled.** The sources added window
|
|
55
|
+
// `pointermove`/`pointerup` on drag start and removed them only in
|
|
56
|
+
// `pointerup`, with no `willDestroy` and no cancel handler — so a drag
|
|
57
|
+
// interrupted by a browser gesture stranded global listeners. Every
|
|
58
|
+
// listener here lives in an `ember-modifier` and is removed in its
|
|
59
|
+
// destructor, and `pointercancel` restores the original order.
|
|
60
|
+
// • **Stable ids, never array indices.** All four corpus implementations
|
|
61
|
+
// keyed on array index, so any reorder or async refresh mid-interaction
|
|
62
|
+
// targeted the wrong row. Every operation here takes a `LayerNode.id`.
|
|
63
|
+
// • **Drop state is not colour-only.** The grabbed row carries a raised
|
|
64
|
+
// shadow, `aria-pressed` on its handle, and a live-region sentence.
|
|
65
|
+
// • **Inherited state is modelled.** A child of a hidden group IS hidden,
|
|
66
|
+
// and its own toggle says so ("hidden by Cover art") instead of
|
|
67
|
+
// reporting a flag that has no effect. No panel in the corpus did this.
|
|
68
|
+
// • **A treegrid, not a tree.** A `role='treeitem'` is ONE tab stop, so a
|
|
69
|
+
// tree with per-row buttons either buries them or breaks the pattern.
|
|
70
|
+
// The APG's answer is `treegrid`: rows of cells, arrows between cells,
|
|
71
|
+
// and every per-row control reachable without leaving the composite.
|
|
72
|
+
//
|
|
73
|
+
// Realm laws: no timers, no `Date.now`, no `Math.random`, no side-effect CSS
|
|
74
|
+
// imports, unnamed container queries only, no `.dark`, every colour a token
|
|
75
|
+
// with a light fallback. The pure functions at the top take no DOM and are
|
|
76
|
+
// unit-tested in `design-layers.test.gts`.
|
|
77
|
+
import Component from '@glimmer/component';
|
|
78
|
+
import { tracked } from '@glimmer/tracking';
|
|
79
|
+
import { guidFor } from '@ember/object/internals';
|
|
80
|
+
import { modifier } from 'ember-modifier';
|
|
81
|
+
|
|
82
|
+
import { focusWhen, listen, rovingTabindex } from '../focus';
|
|
83
|
+
import { cssDeclaration, cssStyleFrom } from '../pretui-css';
|
|
84
|
+
import { EmptyState } from './empty-state';
|
|
85
|
+
|
|
86
|
+
// ═══════════════════════════════════════════════════════════════════════
|
|
87
|
+
// The model — pure. No DOM below this line until the modifier.
|
|
88
|
+
// ═══════════════════════════════════════════════════════════════════════
|
|
89
|
+
|
|
90
|
+
/** One layer. `children` is what makes it a group; everything else is flat. */
|
|
91
|
+
export interface LayerNode {
|
|
92
|
+
/** Stable identity. Every operation in this file takes one of these and
|
|
93
|
+
* never an array index — the defect all four corpus implementations
|
|
94
|
+
* shared. */
|
|
95
|
+
id: string;
|
|
96
|
+
/** The name shown, and the root of every announcement. */
|
|
97
|
+
name: string;
|
|
98
|
+
/** Free-form kind — `'frame'`, `'group'`, `'text'`, `'image'`, `'shape'`,
|
|
99
|
+
* `'component'`, `'mask'`. Drives the row glyph and the spoken kind word;
|
|
100
|
+
* an unknown kind falls back to a neutral mark rather than nothing. */
|
|
101
|
+
kind?: string;
|
|
102
|
+
/** This layer's OWN visibility flag. An ancestor's flag can override the
|
|
103
|
+
* effect without changing this value — see `LayerRow.inheritedHidden`. */
|
|
104
|
+
hidden?: boolean;
|
|
105
|
+
/** This layer's OWN lock flag, on the same terms. */
|
|
106
|
+
locked?: boolean;
|
|
107
|
+
/** Children, front-to-back, matching the panel's top-to-bottom order. */
|
|
108
|
+
children?: readonly LayerNode[];
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/** One VISIBLE row of the flattened tree, with everything ARIA and the
|
|
112
|
+
* keyboard need precomputed. */
|
|
113
|
+
export interface LayerRow {
|
|
114
|
+
node: LayerNode;
|
|
115
|
+
id: string;
|
|
116
|
+
name: string;
|
|
117
|
+
/** 1-based, straight into `aria-level`. */
|
|
118
|
+
level: number;
|
|
119
|
+
/** 1-based position among its siblings, straight into `aria-posinset`. */
|
|
120
|
+
posinset: number;
|
|
121
|
+
setsize: number;
|
|
122
|
+
parentId: string | undefined;
|
|
123
|
+
parentName: string | undefined;
|
|
124
|
+
hasChildren: boolean;
|
|
125
|
+
expanded: boolean;
|
|
126
|
+
/** the node's own flags */
|
|
127
|
+
hidden: boolean;
|
|
128
|
+
locked: boolean;
|
|
129
|
+
/** an ancestor's flag is doing the work */
|
|
130
|
+
inheritedHidden: boolean;
|
|
131
|
+
inheritedLocked: boolean;
|
|
132
|
+
/** what the reader actually sees on the canvas */
|
|
133
|
+
effectiveHidden: boolean;
|
|
134
|
+
effectiveLocked: boolean;
|
|
135
|
+
glyph: string;
|
|
136
|
+
kindWord: string;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/** A text mark per kind. Text, so it survives greyscale and a still frame —
|
|
140
|
+
* Law 8 — and so a `role`-bearing ancestor never trips realm lint's
|
|
141
|
+
* `require-presentational-children` on an `<svg>`. */
|
|
142
|
+
const KIND_GLYPH: Readonly<Record<string, string>> = {
|
|
143
|
+
frame: '▢',
|
|
144
|
+
group: '▤',
|
|
145
|
+
text: 'T',
|
|
146
|
+
image: '▣',
|
|
147
|
+
shape: '◆',
|
|
148
|
+
component: '◈',
|
|
149
|
+
mask: '◐',
|
|
150
|
+
vector: '✎',
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
const KIND_WORD: Readonly<Record<string, string>> = {
|
|
154
|
+
frame: 'frame',
|
|
155
|
+
group: 'group',
|
|
156
|
+
text: 'text',
|
|
157
|
+
image: 'image',
|
|
158
|
+
shape: 'shape',
|
|
159
|
+
component: 'component',
|
|
160
|
+
mask: 'mask',
|
|
161
|
+
vector: 'vector',
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
const DEFAULT_GLYPH = '·';
|
|
165
|
+
|
|
166
|
+
export function layerGlyph(kind: string | undefined): string {
|
|
167
|
+
return (kind && KIND_GLYPH[kind]) || DEFAULT_GLYPH;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export function layerKindWord(kind: string | undefined): string {
|
|
171
|
+
return (kind && KIND_WORD[kind]) || 'layer';
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Flatten the tree to the rows a reader can actually see, resolving
|
|
176
|
+
* inherited visibility and lock on the way down.
|
|
177
|
+
*
|
|
178
|
+
* The inheritance is the part worth having. A layers panel that shows a
|
|
179
|
+
* child's own `hidden: false` while its parent group is hidden is reporting
|
|
180
|
+
* a flag that has no effect on anything — the reader looks at the canvas,
|
|
181
|
+
* sees nothing, and looks at the panel, which says the layer is visible.
|
|
182
|
+
* Resolving it here means the row, the toggle's accessible name and the
|
|
183
|
+
* announcement all agree.
|
|
184
|
+
*/
|
|
185
|
+
export function flattenLayers(
|
|
186
|
+
nodes: readonly LayerNode[],
|
|
187
|
+
expanded: ReadonlySet<string>,
|
|
188
|
+
): LayerRow[] {
|
|
189
|
+
const out: LayerRow[] = [];
|
|
190
|
+
const walk = (
|
|
191
|
+
list: readonly LayerNode[],
|
|
192
|
+
level: number,
|
|
193
|
+
parent: LayerNode | undefined,
|
|
194
|
+
hiddenAbove: boolean,
|
|
195
|
+
lockedAbove: boolean,
|
|
196
|
+
): void => {
|
|
197
|
+
list.forEach((node, index) => {
|
|
198
|
+
const hidden = node.hidden ?? false;
|
|
199
|
+
const locked = node.locked ?? false;
|
|
200
|
+
const hasChildren = (node.children?.length ?? 0) > 0;
|
|
201
|
+
const isOpen = hasChildren && expanded.has(node.id);
|
|
202
|
+
out.push({
|
|
203
|
+
node,
|
|
204
|
+
id: node.id,
|
|
205
|
+
name: node.name,
|
|
206
|
+
level,
|
|
207
|
+
posinset: index + 1,
|
|
208
|
+
setsize: list.length,
|
|
209
|
+
parentId: parent?.id,
|
|
210
|
+
parentName: parent?.name,
|
|
211
|
+
hasChildren,
|
|
212
|
+
expanded: isOpen,
|
|
213
|
+
hidden,
|
|
214
|
+
locked,
|
|
215
|
+
inheritedHidden: hiddenAbove,
|
|
216
|
+
inheritedLocked: lockedAbove,
|
|
217
|
+
effectiveHidden: hidden || hiddenAbove,
|
|
218
|
+
effectiveLocked: locked || lockedAbove,
|
|
219
|
+
glyph: layerGlyph(node.kind),
|
|
220
|
+
kindWord: layerKindWord(node.kind),
|
|
221
|
+
});
|
|
222
|
+
if (isOpen && node.children) {
|
|
223
|
+
walk(
|
|
224
|
+
node.children,
|
|
225
|
+
level + 1,
|
|
226
|
+
node,
|
|
227
|
+
hiddenAbove || hidden,
|
|
228
|
+
lockedAbove || locked,
|
|
229
|
+
);
|
|
230
|
+
}
|
|
231
|
+
});
|
|
232
|
+
};
|
|
233
|
+
walk(nodes, 1, undefined, false, false);
|
|
234
|
+
return out;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/** Every id in the tree, in flattened order, ignoring expansion. Used for
|
|
238
|
+
* "expand all" and for validating a caller's selection. */
|
|
239
|
+
export function allLayerIds(nodes: readonly LayerNode[]): string[] {
|
|
240
|
+
const out: string[] = [];
|
|
241
|
+
const walk = (list: readonly LayerNode[]): void => {
|
|
242
|
+
for (const node of list) {
|
|
243
|
+
out.push(node.id);
|
|
244
|
+
if (node.children) {
|
|
245
|
+
walk(node.children);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
};
|
|
249
|
+
walk(nodes);
|
|
250
|
+
return out;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/** Ids of every branch, so a caller can open the whole tree without knowing
|
|
254
|
+
* its shape. */
|
|
255
|
+
export function branchLayerIds(nodes: readonly LayerNode[]): string[] {
|
|
256
|
+
const out: string[] = [];
|
|
257
|
+
const walk = (list: readonly LayerNode[]): void => {
|
|
258
|
+
for (const node of list) {
|
|
259
|
+
if ((node.children?.length ?? 0) > 0) {
|
|
260
|
+
out.push(node.id);
|
|
261
|
+
walk(node.children as readonly LayerNode[]);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
};
|
|
265
|
+
walk(nodes);
|
|
266
|
+
return out;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/** A structural clone with every array fresh, so a mutation below can never
|
|
270
|
+
* reach the tree a caller handed in. Mutating a caller's array is the bug
|
|
271
|
+
* that makes a Glimmer consumer stop re-rendering. */
|
|
272
|
+
function cloneLayers(nodes: readonly LayerNode[]): LayerNode[] {
|
|
273
|
+
return nodes.map((node) =>
|
|
274
|
+
node.children
|
|
275
|
+
? { ...node, children: cloneLayers(node.children) }
|
|
276
|
+
: { ...node },
|
|
277
|
+
);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/** One step of the path to a node: the array it lives in and where. */
|
|
281
|
+
interface LayerSite {
|
|
282
|
+
list: LayerNode[];
|
|
283
|
+
index: number;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/** The chain from the root array down to the node's own site, or
|
|
287
|
+
* `undefined` when the id is not in the tree. */
|
|
288
|
+
function locateLayer(
|
|
289
|
+
root: LayerNode[],
|
|
290
|
+
id: string,
|
|
291
|
+
): LayerSite[] | undefined {
|
|
292
|
+
const walk = (list: LayerNode[], trail: LayerSite[]): LayerSite[] | undefined => {
|
|
293
|
+
for (let index = 0; index < list.length; index++) {
|
|
294
|
+
const node = list[index];
|
|
295
|
+
const here = trail.concat([{ list, index }]);
|
|
296
|
+
if (node.id === id) {
|
|
297
|
+
return here;
|
|
298
|
+
}
|
|
299
|
+
if (node.children) {
|
|
300
|
+
const kids = node.children as LayerNode[];
|
|
301
|
+
const found = walk(kids, here);
|
|
302
|
+
if (found) {
|
|
303
|
+
return found;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
return undefined;
|
|
308
|
+
};
|
|
309
|
+
return walk(root, []);
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
export type LayerMoveIntent = 'raise' | 'lower' | 'indent' | 'outdent';
|
|
313
|
+
|
|
314
|
+
/** Where a layer ended up, in the words an announcement needs. */
|
|
315
|
+
export interface LayerMoveResult {
|
|
316
|
+
/** false when the move was impossible — already first, already at the
|
|
317
|
+
* root, no previous sibling to nest into. The tree comes back unchanged
|
|
318
|
+
* and the caller says so out loud rather than doing nothing silently. */
|
|
319
|
+
moved: boolean;
|
|
320
|
+
tree: LayerNode[];
|
|
321
|
+
level: number;
|
|
322
|
+
position: number;
|
|
323
|
+
setsize: number;
|
|
324
|
+
parentName: string | undefined;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
function describeLayer(tree: LayerNode[], id: string): Omit<LayerMoveResult, 'moved' | 'tree'> {
|
|
328
|
+
const chain = locateLayer(tree, id);
|
|
329
|
+
if (!chain || chain.length === 0) {
|
|
330
|
+
return { level: 1, position: 1, setsize: 1, parentName: undefined };
|
|
331
|
+
}
|
|
332
|
+
const site = chain[chain.length - 1];
|
|
333
|
+
const parent =
|
|
334
|
+
chain.length > 1
|
|
335
|
+
? chain[chain.length - 2].list[chain[chain.length - 2].index]
|
|
336
|
+
: undefined;
|
|
337
|
+
return {
|
|
338
|
+
level: chain.length,
|
|
339
|
+
position: site.index + 1,
|
|
340
|
+
setsize: site.list.length,
|
|
341
|
+
parentName: parent?.name,
|
|
342
|
+
};
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* Move one layer by one step, returning a NEW tree.
|
|
347
|
+
*
|
|
348
|
+
* The four intents are complete — every position in any tree is reachable by
|
|
349
|
+
* a sequence of them — and every one of them is visually continuous, so the
|
|
350
|
+
* row lands next to where it left rather than teleporting. That is what
|
|
351
|
+
* makes them announceable, and it is why the keyboard and the pointer can
|
|
352
|
+
* share them.
|
|
353
|
+
*/
|
|
354
|
+
export function moveLayer(
|
|
355
|
+
nodes: readonly LayerNode[],
|
|
356
|
+
id: string,
|
|
357
|
+
intent: LayerMoveIntent,
|
|
358
|
+
): LayerMoveResult {
|
|
359
|
+
const tree = cloneLayers(nodes);
|
|
360
|
+
const blocked = (): LayerMoveResult => ({
|
|
361
|
+
moved: false,
|
|
362
|
+
tree: cloneLayers(nodes),
|
|
363
|
+
...describeLayer(tree, id),
|
|
364
|
+
});
|
|
365
|
+
|
|
366
|
+
const chain = locateLayer(tree, id);
|
|
367
|
+
if (!chain || chain.length === 0) {
|
|
368
|
+
return blocked();
|
|
369
|
+
}
|
|
370
|
+
const site = chain[chain.length - 1];
|
|
371
|
+
const node = site.list[site.index];
|
|
372
|
+
|
|
373
|
+
if (intent === 'raise' || intent === 'lower') {
|
|
374
|
+
const target = site.index + (intent === 'raise' ? -1 : 1);
|
|
375
|
+
if (target < 0 || target >= site.list.length) {
|
|
376
|
+
return blocked();
|
|
377
|
+
}
|
|
378
|
+
site.list[site.index] = site.list[target];
|
|
379
|
+
site.list[target] = node;
|
|
380
|
+
} else if (intent === 'indent') {
|
|
381
|
+
// Into the layer directly above it, at the END of that layer's children:
|
|
382
|
+
// adjacent to where it was standing, which is the only landing spot that
|
|
383
|
+
// does not make the row appear to jump.
|
|
384
|
+
if (site.index === 0) {
|
|
385
|
+
return blocked();
|
|
386
|
+
}
|
|
387
|
+
const host = site.list[site.index - 1];
|
|
388
|
+
site.list.splice(site.index, 1);
|
|
389
|
+
host.children = ((host.children as LayerNode[] | undefined) ?? []).concat([
|
|
390
|
+
node,
|
|
391
|
+
]);
|
|
392
|
+
} else {
|
|
393
|
+
// Out to just after its parent — again adjacent.
|
|
394
|
+
if (chain.length < 2) {
|
|
395
|
+
return blocked();
|
|
396
|
+
}
|
|
397
|
+
const parentSite = chain[chain.length - 2];
|
|
398
|
+
site.list.splice(site.index, 1);
|
|
399
|
+
parentSite.list.splice(parentSite.index + 1, 0, node);
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
return { moved: true, tree, ...describeLayer(tree, id) };
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
/** Set one boolean flag on one layer, returning a NEW tree. The panel never
|
|
406
|
+
* mutates what it was given, so a caller holding the same array elsewhere is
|
|
407
|
+
* never surprised. */
|
|
408
|
+
export function setLayerFlag(
|
|
409
|
+
nodes: readonly LayerNode[],
|
|
410
|
+
id: string,
|
|
411
|
+
flagName: 'hidden' | 'locked',
|
|
412
|
+
value: boolean,
|
|
413
|
+
): LayerNode[] {
|
|
414
|
+
const tree = cloneLayers(nodes);
|
|
415
|
+
const chain = locateLayer(tree, id);
|
|
416
|
+
if (!chain || chain.length === 0) {
|
|
417
|
+
return tree;
|
|
418
|
+
}
|
|
419
|
+
const site = chain[chain.length - 1];
|
|
420
|
+
site.list[site.index] = { ...site.list[site.index], [flagName]: value };
|
|
421
|
+
return tree;
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
export type LayerPhase = 'grab' | 'move' | 'blocked' | 'drop' | 'cancel';
|
|
425
|
+
|
|
426
|
+
/**
|
|
427
|
+
* What the live region says.
|
|
428
|
+
*
|
|
429
|
+
* Exported and pure because it is the part of this component a sighted
|
|
430
|
+
* reviewer never sees, and therefore the part most likely to be wrong; and
|
|
431
|
+
* because a host rendering its own status should use these words rather than
|
|
432
|
+
* invent a second vocabulary. Positions and levels are 1-based — screen
|
|
433
|
+
* reader copy counts from one, always.
|
|
434
|
+
*/
|
|
435
|
+
export function layerAnnouncement(
|
|
436
|
+
phase: LayerPhase,
|
|
437
|
+
name: string,
|
|
438
|
+
level: number,
|
|
439
|
+
position: number,
|
|
440
|
+
setsize: number,
|
|
441
|
+
parentName?: string,
|
|
442
|
+
): string {
|
|
443
|
+
const inside = parentName ? ', inside ' + parentName : ', at the top level';
|
|
444
|
+
const place =
|
|
445
|
+
'level ' + level + ', position ' + position + ' of ' + setsize + inside;
|
|
446
|
+
switch (phase) {
|
|
447
|
+
case 'grab':
|
|
448
|
+
return (
|
|
449
|
+
name +
|
|
450
|
+
' grabbed, ' +
|
|
451
|
+
place +
|
|
452
|
+
'. Up and down to reorder, right to nest it inside the layer above, left to move it out, Enter to drop, Escape to cancel.'
|
|
453
|
+
);
|
|
454
|
+
case 'move':
|
|
455
|
+
return name + ', ' + place + '.';
|
|
456
|
+
case 'blocked':
|
|
457
|
+
return name + ' cannot move any further that way. Still ' + place + '.';
|
|
458
|
+
case 'drop':
|
|
459
|
+
return name + ' dropped at ' + place + '.';
|
|
460
|
+
case 'cancel':
|
|
461
|
+
return 'Move cancelled. ' + name + ' returned to ' + place + '.';
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
// ═══════════════════════════════════════════════════════════════════════
|
|
466
|
+
// The pointer half — one rect read, once
|
|
467
|
+
// ═══════════════════════════════════════════════════════════════════════
|
|
468
|
+
|
|
469
|
+
/** What `layerDrag` needs from the component. Kept as an interface so the
|
|
470
|
+
* modifier and the component cannot drift. */
|
|
471
|
+
export interface LayerDragHost {
|
|
472
|
+
/** px of horizontal travel that counts as one nesting step */
|
|
473
|
+
indentStep: number;
|
|
474
|
+
grabByPointer: (id: string) => void;
|
|
475
|
+
stepByPointer: (intent: LayerMoveIntent) => void;
|
|
476
|
+
dropMove: () => void;
|
|
477
|
+
cancelMove: () => void;
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
/**
|
|
481
|
+
* Drag a layer with the pointer, mapped onto exactly the same four
|
|
482
|
+
* operations the keyboard drives.
|
|
483
|
+
*
|
|
484
|
+
* Vertical travel is raise/lower, horizontal travel is outdent/indent. That
|
|
485
|
+
* mapping is what makes the pointer path free: there is no hit-testing, no
|
|
486
|
+
* `elementFromPoint`, no per-tile `getBoundingClientRect` — ONE rect is read
|
|
487
|
+
* at pointerdown to learn the row height, and every step after that is
|
|
488
|
+
* arithmetic on pointer deltas. The corpus implementations this replaces did
|
|
489
|
+
* two forced synchronous layouts on every single `pointermove`.
|
|
490
|
+
*
|
|
491
|
+
* Installed on the HANDLE rather than on the list, deliberately: the kit's
|
|
492
|
+
* shared `dragsSurface` `preventDefault()`s every primary press inside the
|
|
493
|
+
* surface it owns, which would make the visibility and lock buttons in every
|
|
494
|
+
* row unfocusable by pointer. A layers panel is a list whose rows are FULL
|
|
495
|
+
* of controls, so the shared surface modifier is the wrong shape here and
|
|
496
|
+
* the limitation is named rather than worked around.
|
|
497
|
+
*/
|
|
498
|
+
export const layerDrag = modifier(
|
|
499
|
+
(
|
|
500
|
+
el: HTMLElement,
|
|
501
|
+
[host, id, disabled]: [LayerDragHost, string, boolean | undefined],
|
|
502
|
+
) => {
|
|
503
|
+
let pointerId: number | undefined;
|
|
504
|
+
let anchorX = 0;
|
|
505
|
+
let anchorY = 0;
|
|
506
|
+
let rowHeight = 24;
|
|
507
|
+
|
|
508
|
+
const release = (): void => {
|
|
509
|
+
if (pointerId !== undefined && el.hasPointerCapture(pointerId)) {
|
|
510
|
+
el.releasePointerCapture(pointerId);
|
|
511
|
+
}
|
|
512
|
+
pointerId = undefined;
|
|
513
|
+
};
|
|
514
|
+
|
|
515
|
+
const down = (event: Event): void => {
|
|
516
|
+
const pointer = event as PointerEvent;
|
|
517
|
+
if (disabled || pointer.button !== 0 || pointerId !== undefined) {
|
|
518
|
+
return;
|
|
519
|
+
}
|
|
520
|
+
pointer.preventDefault();
|
|
521
|
+
pointerId = pointer.pointerId;
|
|
522
|
+
el.setPointerCapture(pointerId);
|
|
523
|
+
anchorX = pointer.clientX;
|
|
524
|
+
anchorY = pointer.clientY;
|
|
525
|
+
// THE one layout read of the whole gesture.
|
|
526
|
+
const row = el.closest('[data-layer-row]');
|
|
527
|
+
rowHeight = row ? Math.max(12, row.getBoundingClientRect().height) : 24;
|
|
528
|
+
// dragsSurface's lesson, applied: preventDefault suppresses the
|
|
529
|
+
// browser's focus-on-press, so focus is restored by hand and the
|
|
530
|
+
// gesture can always be finished from the keyboard.
|
|
531
|
+
el.focus();
|
|
532
|
+
host.grabByPointer(id);
|
|
533
|
+
};
|
|
534
|
+
|
|
535
|
+
const move = (event: Event): void => {
|
|
536
|
+
const pointer = event as PointerEvent;
|
|
537
|
+
if (pointerId === undefined || pointer.pointerId !== pointerId) {
|
|
538
|
+
return;
|
|
539
|
+
}
|
|
540
|
+
const dy = pointer.clientY - anchorY;
|
|
541
|
+
const dx = pointer.clientX - anchorX;
|
|
542
|
+
// Vertical wins ties: reordering is the common intent, and a diagonal
|
|
543
|
+
// drag that re-nested on the way past would be unusable.
|
|
544
|
+
if (Math.abs(dy) >= rowHeight) {
|
|
545
|
+
host.stepByPointer(dy > 0 ? 'lower' : 'raise');
|
|
546
|
+
// Re-anchor on every threshold crossing, applied or blocked. The row
|
|
547
|
+
// has moved under the pointer by exactly one row, so the pointer's
|
|
548
|
+
// current position IS the new origin — and a blocked direction
|
|
549
|
+
// therefore never accrues a debt that snaps back later.
|
|
550
|
+
anchorY = pointer.clientY;
|
|
551
|
+
anchorX = pointer.clientX;
|
|
552
|
+
} else if (Math.abs(dx) >= host.indentStep) {
|
|
553
|
+
host.stepByPointer(dx > 0 ? 'indent' : 'outdent');
|
|
554
|
+
anchorX = pointer.clientX;
|
|
555
|
+
}
|
|
556
|
+
};
|
|
557
|
+
|
|
558
|
+
const up = (event: Event): void => {
|
|
559
|
+
const pointer = event as PointerEvent;
|
|
560
|
+
if (pointerId === undefined || pointer.pointerId !== pointerId) {
|
|
561
|
+
return;
|
|
562
|
+
}
|
|
563
|
+
release();
|
|
564
|
+
host.dropMove();
|
|
565
|
+
};
|
|
566
|
+
|
|
567
|
+
// The handler the corpus forgot. A drag interrupted by a browser gesture
|
|
568
|
+
// — a back-swipe, a context menu, a window drag — fires pointercancel
|
|
569
|
+
// and NOT pointerup, so without this the row stays grabbed forever and
|
|
570
|
+
// the listeners stay attached.
|
|
571
|
+
const abort = (event: Event): void => {
|
|
572
|
+
const pointer = event as PointerEvent;
|
|
573
|
+
if (pointerId === undefined || pointer.pointerId !== pointerId) {
|
|
574
|
+
return;
|
|
575
|
+
}
|
|
576
|
+
release();
|
|
577
|
+
host.cancelMove();
|
|
578
|
+
};
|
|
579
|
+
|
|
580
|
+
el.addEventListener('pointerdown', down);
|
|
581
|
+
el.addEventListener('pointermove', move);
|
|
582
|
+
el.addEventListener('pointerup', up);
|
|
583
|
+
el.addEventListener('pointercancel', abort);
|
|
584
|
+
|
|
585
|
+
return () => {
|
|
586
|
+
release();
|
|
587
|
+
el.removeEventListener('pointerdown', down);
|
|
588
|
+
el.removeEventListener('pointermove', move);
|
|
589
|
+
el.removeEventListener('pointerup', up);
|
|
590
|
+
el.removeEventListener('pointercancel', abort);
|
|
591
|
+
};
|
|
592
|
+
},
|
|
593
|
+
);
|
|
594
|
+
|
|
595
|
+
// ═══════════════════════════════════════════════════════════════════════
|
|
596
|
+
// LayerManager
|
|
597
|
+
// ═══════════════════════════════════════════════════════════════════════
|
|
598
|
+
|
|
599
|
+
export type LayerSelectionMode = 'none' | 'single' | 'multi';
|
|
600
|
+
|
|
601
|
+
/** Which cells a row carries, left to right. The name cell is not optional
|
|
602
|
+
* — a row without a name is not a row. */
|
|
603
|
+
type LayerColumn = 'handle' | 'name' | 'hidden' | 'locked';
|
|
604
|
+
|
|
605
|
+
/** One rendered row: `LayerRow` plus everything the template needs, so the
|
|
606
|
+
* template itself stays declarative. */
|
|
607
|
+
interface RenderRow extends LayerRow {
|
|
608
|
+
selected: boolean;
|
|
609
|
+
grabbed: boolean;
|
|
610
|
+
expandedAttr: 'true' | 'false' | undefined;
|
|
611
|
+
selectedAttr: 'true' | 'false';
|
|
612
|
+
grabbedAttr: 'true' | 'false';
|
|
613
|
+
indentStyle: ReturnType<typeof cssStyleFrom>;
|
|
614
|
+
handleLabel: string;
|
|
615
|
+
hiddenLabel: string;
|
|
616
|
+
lockedLabel: string;
|
|
617
|
+
hiddenPressed: 'true' | 'false';
|
|
618
|
+
lockedPressed: 'true' | 'false';
|
|
619
|
+
/** A word beside the name whenever state is on, so the row still reads in
|
|
620
|
+
* greyscale and in a screenshot — never an icon tint alone. */
|
|
621
|
+
stateWord: string;
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
export interface LayerManagerSignature {
|
|
625
|
+
Args: {
|
|
626
|
+
/** Controlled tree, front-to-back (the top row is the front-most layer,
|
|
627
|
+
* as in every design tool). Omit for the uncontrolled case. */
|
|
628
|
+
layers?: readonly LayerNode[];
|
|
629
|
+
/** Initial tree when uncontrolled. */
|
|
630
|
+
defaultLayers?: readonly LayerNode[];
|
|
631
|
+
/** Fires with the NEXT WHOLE TREE after any structural change — a move,
|
|
632
|
+
* a visibility flip, a lock flip. One channel, so a host can store the
|
|
633
|
+
* result without reassembling it from deltas. */
|
|
634
|
+
onLayersChange?: (next: LayerNode[]) => void;
|
|
635
|
+
|
|
636
|
+
/** Controlled expansion, as ids. */
|
|
637
|
+
expanded?: readonly string[];
|
|
638
|
+
/** Initial expansion when uncontrolled. */
|
|
639
|
+
defaultExpanded?: readonly string[];
|
|
640
|
+
onExpandedChange?: (ids: string[]) => void;
|
|
641
|
+
|
|
642
|
+
/** `'single'` (default), `'multi'` or `'none'`. */
|
|
643
|
+
selectionMode?: LayerSelectionMode;
|
|
644
|
+
/** Controlled selection, as ids. */
|
|
645
|
+
selected?: readonly string[];
|
|
646
|
+
/** Initial selection when uncontrolled. */
|
|
647
|
+
defaultSelected?: readonly string[];
|
|
648
|
+
onSelectionChange?: (ids: string[], nodes: LayerNode[]) => void;
|
|
649
|
+
|
|
650
|
+
/** The delta, for hosts that want it narrower than the whole tree. */
|
|
651
|
+
onVisibilityChange?: (node: LayerNode, hidden: boolean) => void;
|
|
652
|
+
onLockChange?: (node: LayerNode, locked: boolean) => void;
|
|
653
|
+
/** Double-click, or Enter on the name cell — "open this layer". */
|
|
654
|
+
onActivate?: (node: LayerNode) => void;
|
|
655
|
+
|
|
656
|
+
/** Accessible name for the grid. @default 'Layers' */
|
|
657
|
+
label?: string;
|
|
658
|
+
/** px of indent per nesting level. Also `--pretui-lm-indent`. @default 14 */
|
|
659
|
+
indent?: number;
|
|
660
|
+
/** Row height preset: `'compact'` or `'comfortable'` (default). */
|
|
661
|
+
density?: 'compact' | 'comfortable';
|
|
662
|
+
/** Offer the grab handle and the whole move contract. @default true */
|
|
663
|
+
reorderable?: boolean;
|
|
664
|
+
/** Offer the visibility toggle. @default true */
|
|
665
|
+
showVisibility?: boolean;
|
|
666
|
+
/** Offer the lock toggle. @default true */
|
|
667
|
+
showLock?: boolean;
|
|
668
|
+
/** Dimmed; nothing moves and nothing toggles. Rows stay focusable and
|
|
669
|
+
* readable, because a disabled panel is still information. */
|
|
670
|
+
disabled?: boolean;
|
|
671
|
+
};
|
|
672
|
+
Blocks: {
|
|
673
|
+
/** Replaces the name cell's contents; receives the row. */
|
|
674
|
+
name: [LayerRow];
|
|
675
|
+
/** Extra cells' worth of trailing content inside the name cell —
|
|
676
|
+
* a blend-mode chip, an opacity readout. Keep focusable controls OUT of
|
|
677
|
+
* it: the row is a grid and a stray tab stop breaks the composite. */
|
|
678
|
+
trailing: [LayerRow];
|
|
679
|
+
/** Replaces the default empty state. */
|
|
680
|
+
empty: [];
|
|
681
|
+
};
|
|
682
|
+
Element: HTMLDivElement;
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
export class LayerManager
|
|
686
|
+
extends Component<LayerManagerSignature>
|
|
687
|
+
implements LayerDragHost
|
|
688
|
+
{
|
|
689
|
+
private guid = guidFor(this);
|
|
690
|
+
|
|
691
|
+
// ── state ──────────────────────────────────────────────────────────────
|
|
692
|
+
|
|
693
|
+
@tracked private ownLayers: LayerNode[] | undefined = undefined;
|
|
694
|
+
@tracked private ownExpanded: string[] | undefined = undefined;
|
|
695
|
+
@tracked private ownSelected: string[] | undefined = undefined;
|
|
696
|
+
|
|
697
|
+
/** The in-flight tree while a move is happening. `undefined` means "the
|
|
698
|
+
* order is exactly what the caller gave us". Holding it separately is what
|
|
699
|
+
* lets Escape restore the original without the caller ever having been
|
|
700
|
+
* told about the intermediate steps. */
|
|
701
|
+
@tracked private working: LayerNode[] | undefined = undefined;
|
|
702
|
+
/** The tree as it stood when the grab began, so cancel is exact. */
|
|
703
|
+
private beforeGrab: LayerNode[] | undefined = undefined;
|
|
704
|
+
@tracked private grabbedId: string | undefined = undefined;
|
|
705
|
+
|
|
706
|
+
/** The keyboard cursor: which row, and which column within it. */
|
|
707
|
+
@tracked private cursorId: string | undefined = undefined;
|
|
708
|
+
@tracked private cursorCol = 0;
|
|
709
|
+
/** True only while the keyboard is driving, so `focusWhen` never steals
|
|
710
|
+
* focus on a plain re-render or during a pointer gesture. */
|
|
711
|
+
@tracked private navigating = false;
|
|
712
|
+
/** Where a Shift-range starts — held apart from the cursor so a range
|
|
713
|
+
* extends from where the reader began. */
|
|
714
|
+
@tracked private anchorId: string | undefined = undefined;
|
|
715
|
+
|
|
716
|
+
@tracked private announcement = '';
|
|
717
|
+
|
|
718
|
+
// ── derived config ─────────────────────────────────────────────────────
|
|
719
|
+
|
|
720
|
+
get label(): string {
|
|
721
|
+
return this.args.label ?? 'Layers';
|
|
722
|
+
}
|
|
723
|
+
get hintId(): string {
|
|
724
|
+
return this.guid + '-lm-hint';
|
|
725
|
+
}
|
|
726
|
+
get density(): 'compact' | 'comfortable' {
|
|
727
|
+
return this.args.density === 'compact' ? 'compact' : 'comfortable';
|
|
728
|
+
}
|
|
729
|
+
get reorderable(): boolean {
|
|
730
|
+
return (this.args.reorderable ?? true) && !this.args.disabled;
|
|
731
|
+
}
|
|
732
|
+
get showVisibility(): boolean {
|
|
733
|
+
return this.args.showVisibility ?? true;
|
|
734
|
+
}
|
|
735
|
+
get showLock(): boolean {
|
|
736
|
+
return this.args.showLock ?? true;
|
|
737
|
+
}
|
|
738
|
+
get mode(): LayerSelectionMode {
|
|
739
|
+
return this.args.selectionMode ?? 'single';
|
|
740
|
+
}
|
|
741
|
+
get multi(): boolean {
|
|
742
|
+
return this.mode === 'multi';
|
|
743
|
+
}
|
|
744
|
+
get multiAttr(): 'true' | undefined {
|
|
745
|
+
return this.multi ? 'true' : undefined;
|
|
746
|
+
}
|
|
747
|
+
get indentStep(): number {
|
|
748
|
+
return Math.max(4, Math.round(this.args.indent ?? 14));
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
get columns(): LayerColumn[] {
|
|
752
|
+
const out: LayerColumn[] = [];
|
|
753
|
+
if (this.reorderable) {
|
|
754
|
+
out.push('handle');
|
|
755
|
+
}
|
|
756
|
+
out.push('name');
|
|
757
|
+
if (this.showVisibility) {
|
|
758
|
+
out.push('hidden');
|
|
759
|
+
}
|
|
760
|
+
if (this.showLock) {
|
|
761
|
+
out.push('locked');
|
|
762
|
+
}
|
|
763
|
+
return out;
|
|
764
|
+
}
|
|
765
|
+
get colCount(): number {
|
|
766
|
+
return this.columns.length;
|
|
767
|
+
}
|
|
768
|
+
private colIndex(column: LayerColumn): number {
|
|
769
|
+
return this.columns.indexOf(column);
|
|
770
|
+
}
|
|
771
|
+
get handleCol(): number {
|
|
772
|
+
return this.colIndex('handle');
|
|
773
|
+
}
|
|
774
|
+
get nameCol(): number {
|
|
775
|
+
return this.colIndex('name');
|
|
776
|
+
}
|
|
777
|
+
get hiddenCol(): number {
|
|
778
|
+
return this.colIndex('hidden');
|
|
779
|
+
}
|
|
780
|
+
get lockedCol(): number {
|
|
781
|
+
return this.colIndex('locked');
|
|
782
|
+
}
|
|
783
|
+
/** `aria-colindex` is 1-based; the internal cursor is not. */
|
|
784
|
+
get handleAria(): number {
|
|
785
|
+
return this.handleCol + 1;
|
|
786
|
+
}
|
|
787
|
+
get nameAria(): number {
|
|
788
|
+
return this.nameCol + 1;
|
|
789
|
+
}
|
|
790
|
+
get hiddenAria(): number {
|
|
791
|
+
return this.hiddenCol + 1;
|
|
792
|
+
}
|
|
793
|
+
get lockedAria(): number {
|
|
794
|
+
return this.lockedCol + 1;
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
get hostStyle() {
|
|
798
|
+
return cssStyleFrom([
|
|
799
|
+
cssDeclaration('--pretui-lm-indent', this.indentStep + 'px'),
|
|
800
|
+
]);
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
// ── derived data ───────────────────────────────────────────────────────
|
|
804
|
+
|
|
805
|
+
get layers(): readonly LayerNode[] {
|
|
806
|
+
if (this.working) {
|
|
807
|
+
return this.working;
|
|
808
|
+
}
|
|
809
|
+
if (this.args.layers !== undefined) {
|
|
810
|
+
return this.args.layers;
|
|
811
|
+
}
|
|
812
|
+
if (this.ownLayers !== undefined) {
|
|
813
|
+
return this.ownLayers;
|
|
814
|
+
}
|
|
815
|
+
return this.args.defaultLayers ?? [];
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
get expandedSet(): ReadonlySet<string> {
|
|
819
|
+
const ids =
|
|
820
|
+
this.args.expanded ??
|
|
821
|
+
this.ownExpanded ??
|
|
822
|
+
this.args.defaultExpanded ??
|
|
823
|
+
branchLayerIds(this.layers);
|
|
824
|
+
return new Set(ids);
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
get selectedIds(): readonly string[] {
|
|
828
|
+
if (this.mode === 'none') {
|
|
829
|
+
return [];
|
|
830
|
+
}
|
|
831
|
+
return (
|
|
832
|
+
this.args.selected ?? this.ownSelected ?? this.args.defaultSelected ?? []
|
|
833
|
+
);
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
get baseRows(): LayerRow[] {
|
|
837
|
+
return flattenLayers(this.layers, this.expandedSet);
|
|
838
|
+
}
|
|
839
|
+
get hasRows(): boolean {
|
|
840
|
+
return this.baseRows.length > 0;
|
|
841
|
+
}
|
|
842
|
+
get rowCount(): number {
|
|
843
|
+
return this.baseRows.length;
|
|
844
|
+
}
|
|
845
|
+
|
|
846
|
+
/** The cursor row id, defaulted to the first row so there is always
|
|
847
|
+
* exactly one tab stop — never zero, never two. */
|
|
848
|
+
get cursorRowId(): string | undefined {
|
|
849
|
+
const rows = this.baseRows;
|
|
850
|
+
if (rows.length === 0) {
|
|
851
|
+
return undefined;
|
|
852
|
+
}
|
|
853
|
+
const wanted = this.cursorId;
|
|
854
|
+
if (wanted && rows.some((row) => row.id === wanted)) {
|
|
855
|
+
return wanted;
|
|
856
|
+
}
|
|
857
|
+
return rows[0].id;
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
/** The cursor column, clamped to the columns that actually exist — so
|
|
861
|
+
* turning `@showLock` off cannot strand the tab stop on a cell that is no
|
|
862
|
+
* longer rendered. */
|
|
863
|
+
get cursorColumn(): number {
|
|
864
|
+
return Math.max(0, Math.min(this.colCount - 1, this.cursorCol));
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
get rows(): RenderRow[] {
|
|
868
|
+
const chosen = new Set(this.selectedIds);
|
|
869
|
+
return this.baseRows.map((row) => {
|
|
870
|
+
const selected = chosen.has(row.id);
|
|
871
|
+
const grabbed = this.grabbedId === row.id;
|
|
872
|
+
const words: string[] = [];
|
|
873
|
+
if (row.effectiveHidden) {
|
|
874
|
+
words.push('hidden');
|
|
875
|
+
}
|
|
876
|
+
if (row.effectiveLocked) {
|
|
877
|
+
words.push('locked');
|
|
878
|
+
}
|
|
879
|
+
return {
|
|
880
|
+
...row,
|
|
881
|
+
selected,
|
|
882
|
+
grabbed,
|
|
883
|
+
expandedAttr: row.hasChildren
|
|
884
|
+
? row.expanded
|
|
885
|
+
? ('true' as const)
|
|
886
|
+
: ('false' as const)
|
|
887
|
+
: undefined,
|
|
888
|
+
selectedAttr: selected ? ('true' as const) : ('false' as const),
|
|
889
|
+
grabbedAttr: grabbed ? ('true' as const) : ('false' as const),
|
|
890
|
+
indentStyle: cssStyleFrom([
|
|
891
|
+
cssDeclaration('--pretui-lm-level', String(row.level - 1)),
|
|
892
|
+
]),
|
|
893
|
+
handleLabel: this.handleNameFor(row, grabbed),
|
|
894
|
+
hiddenLabel: this.visibilityNameFor(row),
|
|
895
|
+
lockedLabel: this.lockNameFor(row),
|
|
896
|
+
hiddenPressed: row.hidden ? ('true' as const) : ('false' as const),
|
|
897
|
+
lockedPressed: row.locked ? ('true' as const) : ('false' as const),
|
|
898
|
+
stateWord: words.join(' · '),
|
|
899
|
+
};
|
|
900
|
+
});
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
private placeOf(row: LayerRow): string {
|
|
904
|
+
return (
|
|
905
|
+
'level ' +
|
|
906
|
+
row.level +
|
|
907
|
+
', position ' +
|
|
908
|
+
row.posinset +
|
|
909
|
+
' of ' +
|
|
910
|
+
row.setsize
|
|
911
|
+
);
|
|
912
|
+
}
|
|
913
|
+
|
|
914
|
+
private handleNameFor(row: LayerRow, grabbed: boolean): string {
|
|
915
|
+
return (
|
|
916
|
+
(grabbed ? 'Moving ' : 'Move ') +
|
|
917
|
+
row.name +
|
|
918
|
+
', ' +
|
|
919
|
+
row.kindWord +
|
|
920
|
+
', ' +
|
|
921
|
+
this.placeOf(row)
|
|
922
|
+
);
|
|
923
|
+
}
|
|
924
|
+
|
|
925
|
+
/** The accessible name says what the button DOES and what is currently
|
|
926
|
+
* true, including when an ancestor is the reason. A toggle that reports a
|
|
927
|
+
* flag with no effect is the defect this fixes. */
|
|
928
|
+
private visibilityNameFor(row: LayerRow): string {
|
|
929
|
+
if (row.inheritedHidden && !row.hidden) {
|
|
930
|
+
return 'Show ' + row.name + ' — hidden by ' + (row.parentName ?? 'a group');
|
|
931
|
+
}
|
|
932
|
+
return (row.hidden ? 'Show ' : 'Hide ') + row.name;
|
|
933
|
+
}
|
|
934
|
+
|
|
935
|
+
private lockNameFor(row: LayerRow): string {
|
|
936
|
+
if (row.inheritedLocked && !row.locked) {
|
|
937
|
+
return 'Unlock ' + row.name + ' — locked by ' + (row.parentName ?? 'a group');
|
|
938
|
+
}
|
|
939
|
+
return (row.locked ? 'Unlock ' : 'Lock ') + row.name;
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
isCursor = (row: RenderRow, column: number): boolean => {
|
|
943
|
+
return row.id === this.cursorRowId && column === this.cursorColumn;
|
|
944
|
+
};
|
|
945
|
+
takesFocus = (row: RenderRow, column: number): boolean => {
|
|
946
|
+
return this.navigating && this.isCursor(row, column);
|
|
947
|
+
};
|
|
948
|
+
|
|
949
|
+
// ── writes ─────────────────────────────────────────────────────────────
|
|
950
|
+
|
|
951
|
+
private publishLayers(next: LayerNode[]): void {
|
|
952
|
+
if (this.args.layers === undefined) {
|
|
953
|
+
this.ownLayers = next;
|
|
954
|
+
}
|
|
955
|
+
this.args.onLayersChange?.(next);
|
|
956
|
+
}
|
|
957
|
+
|
|
958
|
+
private publishExpanded(ids: string[]): void {
|
|
959
|
+
if (this.args.expanded === undefined) {
|
|
960
|
+
this.ownExpanded = ids;
|
|
961
|
+
}
|
|
962
|
+
this.args.onExpandedChange?.(ids);
|
|
963
|
+
}
|
|
964
|
+
|
|
965
|
+
private publishSelection(ids: string[]): void {
|
|
966
|
+
const order = this.baseRows.map((row) => row.id);
|
|
967
|
+
const unique = Array.from(new Set(ids)).sort(
|
|
968
|
+
(a, b) => order.indexOf(a) - order.indexOf(b),
|
|
969
|
+
);
|
|
970
|
+
if (this.args.selected === undefined) {
|
|
971
|
+
this.ownSelected = unique;
|
|
972
|
+
}
|
|
973
|
+
const byId = new Map(this.baseRows.map((row) => [row.id, row.node]));
|
|
974
|
+
this.args.onSelectionChange?.(
|
|
975
|
+
unique,
|
|
976
|
+
unique.map((id) => byId.get(id)).filter((n): n is LayerNode => !!n),
|
|
977
|
+
);
|
|
978
|
+
}
|
|
979
|
+
|
|
980
|
+
private moveCursor(id: string, column: number, keyboard: boolean): void {
|
|
981
|
+
this.cursorId = id;
|
|
982
|
+
this.cursorCol = Math.max(0, Math.min(this.colCount - 1, column));
|
|
983
|
+
this.navigating = keyboard;
|
|
984
|
+
}
|
|
985
|
+
|
|
986
|
+
private toggleExpanded(id: string): void {
|
|
987
|
+
const next = new Set(this.expandedSet);
|
|
988
|
+
if (next.has(id)) {
|
|
989
|
+
next.delete(id);
|
|
990
|
+
} else {
|
|
991
|
+
next.add(id);
|
|
992
|
+
}
|
|
993
|
+
this.publishExpanded(Array.from(next));
|
|
994
|
+
}
|
|
995
|
+
|
|
996
|
+
private selectOnly(id: string): void {
|
|
997
|
+
if (this.mode === 'none') {
|
|
998
|
+
return;
|
|
999
|
+
}
|
|
1000
|
+
this.anchorId = id;
|
|
1001
|
+
this.publishSelection([id]);
|
|
1002
|
+
}
|
|
1003
|
+
|
|
1004
|
+
private toggleSelected(id: string): void {
|
|
1005
|
+
if (this.mode === 'none') {
|
|
1006
|
+
return;
|
|
1007
|
+
}
|
|
1008
|
+
if (!this.multi) {
|
|
1009
|
+
this.selectOnly(id);
|
|
1010
|
+
return;
|
|
1011
|
+
}
|
|
1012
|
+
this.anchorId = id;
|
|
1013
|
+
const current = this.selectedIds.slice();
|
|
1014
|
+
const at = current.indexOf(id);
|
|
1015
|
+
if (at === -1) {
|
|
1016
|
+
current.push(id);
|
|
1017
|
+
} else {
|
|
1018
|
+
current.splice(at, 1);
|
|
1019
|
+
}
|
|
1020
|
+
this.publishSelection(current);
|
|
1021
|
+
}
|
|
1022
|
+
|
|
1023
|
+
private extendSelection(id: string): void {
|
|
1024
|
+
if (!this.multi) {
|
|
1025
|
+
this.selectOnly(id);
|
|
1026
|
+
return;
|
|
1027
|
+
}
|
|
1028
|
+
const order = this.baseRows.map((row) => row.id);
|
|
1029
|
+
const from = this.anchorId ? order.indexOf(this.anchorId) : -1;
|
|
1030
|
+
const to = order.indexOf(id);
|
|
1031
|
+
if (from === -1 || to === -1) {
|
|
1032
|
+
this.selectOnly(id);
|
|
1033
|
+
return;
|
|
1034
|
+
}
|
|
1035
|
+
const lo = Math.min(from, to);
|
|
1036
|
+
const hi = Math.max(from, to);
|
|
1037
|
+
this.publishSelection(order.slice(lo, hi + 1));
|
|
1038
|
+
}
|
|
1039
|
+
|
|
1040
|
+
private flipFlag(row: LayerRow, flagName: 'hidden' | 'locked'): void {
|
|
1041
|
+
if (this.args.disabled) {
|
|
1042
|
+
return;
|
|
1043
|
+
}
|
|
1044
|
+
const value = !(flagName === 'hidden' ? row.hidden : row.locked);
|
|
1045
|
+
const next = setLayerFlag(this.layers, row.id, flagName, value);
|
|
1046
|
+
this.publishLayers(next);
|
|
1047
|
+
if (flagName === 'hidden') {
|
|
1048
|
+
this.args.onVisibilityChange?.(row.node, value);
|
|
1049
|
+
} else {
|
|
1050
|
+
this.args.onLockChange?.(row.node, value);
|
|
1051
|
+
}
|
|
1052
|
+
}
|
|
1053
|
+
|
|
1054
|
+
// ── the move contract, shared by keyboard and pointer ──────────────────
|
|
1055
|
+
|
|
1056
|
+
private rowById(id: string): LayerRow | undefined {
|
|
1057
|
+
return this.baseRows.find((row) => row.id === id);
|
|
1058
|
+
}
|
|
1059
|
+
|
|
1060
|
+
private say(
|
|
1061
|
+
phase: LayerPhase,
|
|
1062
|
+
name: string,
|
|
1063
|
+
level: number,
|
|
1064
|
+
position: number,
|
|
1065
|
+
setsize: number,
|
|
1066
|
+
parentName: string | undefined,
|
|
1067
|
+
): void {
|
|
1068
|
+
this.announcement = layerAnnouncement(
|
|
1069
|
+
phase,
|
|
1070
|
+
name,
|
|
1071
|
+
level,
|
|
1072
|
+
position,
|
|
1073
|
+
setsize,
|
|
1074
|
+
parentName,
|
|
1075
|
+
);
|
|
1076
|
+
}
|
|
1077
|
+
|
|
1078
|
+
private beginMove(id: string): void {
|
|
1079
|
+
if (!this.reorderable || this.grabbedId !== undefined) {
|
|
1080
|
+
return;
|
|
1081
|
+
}
|
|
1082
|
+
const row = this.rowById(id);
|
|
1083
|
+
if (!row) {
|
|
1084
|
+
return;
|
|
1085
|
+
}
|
|
1086
|
+
this.beforeGrab = cloneLayers(this.layers);
|
|
1087
|
+
this.working = cloneLayers(this.layers);
|
|
1088
|
+
this.grabbedId = id;
|
|
1089
|
+
this.say('grab', row.name, row.level, row.posinset, row.setsize, row.parentName);
|
|
1090
|
+
}
|
|
1091
|
+
|
|
1092
|
+
private stepMove(intent: LayerMoveIntent): void {
|
|
1093
|
+
const id = this.grabbedId;
|
|
1094
|
+
if (id === undefined) {
|
|
1095
|
+
return;
|
|
1096
|
+
}
|
|
1097
|
+
const before = this.rowById(id);
|
|
1098
|
+
const result = moveLayer(this.layers, id, intent);
|
|
1099
|
+
this.working = result.tree;
|
|
1100
|
+
const name = before?.name ?? '';
|
|
1101
|
+
this.say(
|
|
1102
|
+
result.moved ? 'move' : 'blocked',
|
|
1103
|
+
name,
|
|
1104
|
+
result.level,
|
|
1105
|
+
result.position,
|
|
1106
|
+
result.setsize,
|
|
1107
|
+
result.parentName,
|
|
1108
|
+
);
|
|
1109
|
+
// Nesting can move a row into a collapsed parent, which would make the
|
|
1110
|
+
// thing being dragged vanish. Opening it is not a courtesy, it is a
|
|
1111
|
+
// correctness fix.
|
|
1112
|
+
if (result.moved && intent === 'indent') {
|
|
1113
|
+
const landed = flattenLayers(result.tree, this.expandedSet).some(
|
|
1114
|
+
(row) => row.id === id,
|
|
1115
|
+
);
|
|
1116
|
+
if (!landed) {
|
|
1117
|
+
const chain = locateLayer(result.tree, id);
|
|
1118
|
+
if (chain && chain.length > 1) {
|
|
1119
|
+
const parentSite = chain[chain.length - 2];
|
|
1120
|
+
const parent = parentSite.list[parentSite.index];
|
|
1121
|
+
const next = new Set(this.expandedSet);
|
|
1122
|
+
next.add(parent.id);
|
|
1123
|
+
this.publishExpanded(Array.from(next));
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
1126
|
+
}
|
|
1127
|
+
}
|
|
1128
|
+
|
|
1129
|
+
private endMove(commit: boolean): void {
|
|
1130
|
+
const id = this.grabbedId;
|
|
1131
|
+
if (id === undefined) {
|
|
1132
|
+
return;
|
|
1133
|
+
}
|
|
1134
|
+
const tree = (commit ? this.working : this.beforeGrab) ?? cloneLayers(this.layers);
|
|
1135
|
+
const name = this.rowById(id)?.name ?? '';
|
|
1136
|
+
// The landing place is read from the SETTLED tree by the same pure
|
|
1137
|
+
// function the move used, never by round-tripping through tracked state
|
|
1138
|
+
// — writing `working` and reading it back in one handler is exactly the
|
|
1139
|
+
// backtracking shape the kit has paid for before.
|
|
1140
|
+
const place = describeLayer(tree, id);
|
|
1141
|
+
this.grabbedId = undefined;
|
|
1142
|
+
this.working = undefined;
|
|
1143
|
+
this.beforeGrab = undefined;
|
|
1144
|
+
this.say(
|
|
1145
|
+
commit ? 'drop' : 'cancel',
|
|
1146
|
+
name,
|
|
1147
|
+
place.level,
|
|
1148
|
+
place.position,
|
|
1149
|
+
place.setsize,
|
|
1150
|
+
place.parentName,
|
|
1151
|
+
);
|
|
1152
|
+
this.publishLayers(tree);
|
|
1153
|
+
}
|
|
1154
|
+
|
|
1155
|
+
// LayerDragHost — the pointer path calls the SAME three entry points the
|
|
1156
|
+
// keyboard does, which is why they cannot drift apart.
|
|
1157
|
+
grabByPointer = (id: string): void => {
|
|
1158
|
+
this.navigating = false;
|
|
1159
|
+
this.moveCursor(id, this.handleCol, false);
|
|
1160
|
+
this.beginMove(id);
|
|
1161
|
+
};
|
|
1162
|
+
stepByPointer = (intent: LayerMoveIntent): void => {
|
|
1163
|
+
this.stepMove(intent);
|
|
1164
|
+
};
|
|
1165
|
+
dropMove = (): void => {
|
|
1166
|
+
this.endMove(true);
|
|
1167
|
+
};
|
|
1168
|
+
cancelMove = (): void => {
|
|
1169
|
+
this.endMove(false);
|
|
1170
|
+
};
|
|
1171
|
+
|
|
1172
|
+
// ── pointer, delegated ─────────────────────────────────────────────────
|
|
1173
|
+
|
|
1174
|
+
private cellFrom(event: Event): { id: string; col: number } | undefined {
|
|
1175
|
+
const target = event.target;
|
|
1176
|
+
if (!(target instanceof Element)) {
|
|
1177
|
+
return undefined;
|
|
1178
|
+
}
|
|
1179
|
+
const cell = target.closest('[data-layer-cell]');
|
|
1180
|
+
if (!(cell instanceof HTMLElement)) {
|
|
1181
|
+
return undefined;
|
|
1182
|
+
}
|
|
1183
|
+
const id = cell.getAttribute('data-layer-id');
|
|
1184
|
+
const col = Number.parseInt(cell.getAttribute('data-col') ?? '', 10);
|
|
1185
|
+
if (!id || Number.isNaN(col)) {
|
|
1186
|
+
return undefined;
|
|
1187
|
+
}
|
|
1188
|
+
return { id, col };
|
|
1189
|
+
}
|
|
1190
|
+
|
|
1191
|
+
onGridClick = (event: Event): void => {
|
|
1192
|
+
const target = event.target;
|
|
1193
|
+
if (!(target instanceof Element)) {
|
|
1194
|
+
return;
|
|
1195
|
+
}
|
|
1196
|
+
|
|
1197
|
+
const twisty = target.closest('[data-layer-twisty]');
|
|
1198
|
+
if (twisty instanceof HTMLElement) {
|
|
1199
|
+
const id = twisty.getAttribute('data-layer-id');
|
|
1200
|
+
if (id) {
|
|
1201
|
+
this.toggleExpanded(id);
|
|
1202
|
+
}
|
|
1203
|
+
return;
|
|
1204
|
+
}
|
|
1205
|
+
|
|
1206
|
+
const toggle = target.closest('[data-layer-toggle]');
|
|
1207
|
+
if (toggle instanceof HTMLElement) {
|
|
1208
|
+
const id = toggle.getAttribute('data-layer-id');
|
|
1209
|
+
const flagName = toggle.getAttribute('data-layer-flag');
|
|
1210
|
+
const row = id ? this.rowById(id) : undefined;
|
|
1211
|
+
if (row && (flagName === 'hidden' || flagName === 'locked')) {
|
|
1212
|
+
this.moveCursor(
|
|
1213
|
+
row.id,
|
|
1214
|
+
flagName === 'hidden' ? this.hiddenCol : this.lockedCol,
|
|
1215
|
+
false,
|
|
1216
|
+
);
|
|
1217
|
+
this.flipFlag(row, flagName);
|
|
1218
|
+
}
|
|
1219
|
+
return;
|
|
1220
|
+
}
|
|
1221
|
+
|
|
1222
|
+
const cell = this.cellFrom(event);
|
|
1223
|
+
if (!cell) {
|
|
1224
|
+
return;
|
|
1225
|
+
}
|
|
1226
|
+
this.moveCursor(cell.id, cell.col, false);
|
|
1227
|
+
const mouse = event as MouseEvent;
|
|
1228
|
+
if (mouse.shiftKey) {
|
|
1229
|
+
this.extendSelection(cell.id);
|
|
1230
|
+
} else if (mouse.metaKey || mouse.ctrlKey) {
|
|
1231
|
+
this.toggleSelected(cell.id);
|
|
1232
|
+
} else {
|
|
1233
|
+
this.selectOnly(cell.id);
|
|
1234
|
+
}
|
|
1235
|
+
};
|
|
1236
|
+
|
|
1237
|
+
onGridDblClick = (event: Event): void => {
|
|
1238
|
+
const cell = this.cellFrom(event);
|
|
1239
|
+
const row = cell ? this.rowById(cell.id) : undefined;
|
|
1240
|
+
if (row) {
|
|
1241
|
+
this.args.onActivate?.(row.node);
|
|
1242
|
+
}
|
|
1243
|
+
};
|
|
1244
|
+
|
|
1245
|
+
// ── keyboard ───────────────────────────────────────────────────────────
|
|
1246
|
+
|
|
1247
|
+
onGridKeydown = (raw: Event): void => {
|
|
1248
|
+
const event = raw as KeyboardEvent;
|
|
1249
|
+
const cell = this.cellFrom(event);
|
|
1250
|
+
if (!cell) {
|
|
1251
|
+
return;
|
|
1252
|
+
}
|
|
1253
|
+
if (this.grabbedId !== undefined && cell.id === this.grabbedId) {
|
|
1254
|
+
this.moveKeys(event);
|
|
1255
|
+
return;
|
|
1256
|
+
}
|
|
1257
|
+
this.navigationKeys(event, cell.id, cell.col);
|
|
1258
|
+
};
|
|
1259
|
+
|
|
1260
|
+
/** While a row is grabbed the arrows mean something else entirely, so the
|
|
1261
|
+
* two key maps are separate functions rather than one with a flag in the
|
|
1262
|
+
* middle — the shape a reviewer can check. */
|
|
1263
|
+
private moveKeys(event: KeyboardEvent): void {
|
|
1264
|
+
switch (event.key) {
|
|
1265
|
+
case 'ArrowUp':
|
|
1266
|
+
event.preventDefault();
|
|
1267
|
+
this.stepMove('raise');
|
|
1268
|
+
break;
|
|
1269
|
+
case 'ArrowDown':
|
|
1270
|
+
event.preventDefault();
|
|
1271
|
+
this.stepMove('lower');
|
|
1272
|
+
break;
|
|
1273
|
+
case 'ArrowRight':
|
|
1274
|
+
event.preventDefault();
|
|
1275
|
+
this.stepMove('indent');
|
|
1276
|
+
break;
|
|
1277
|
+
case 'ArrowLeft':
|
|
1278
|
+
event.preventDefault();
|
|
1279
|
+
this.stepMove('outdent');
|
|
1280
|
+
break;
|
|
1281
|
+
case 'Enter':
|
|
1282
|
+
case ' ':
|
|
1283
|
+
event.preventDefault();
|
|
1284
|
+
this.endMove(true);
|
|
1285
|
+
break;
|
|
1286
|
+
case 'Escape':
|
|
1287
|
+
event.preventDefault();
|
|
1288
|
+
this.endMove(false);
|
|
1289
|
+
break;
|
|
1290
|
+
case 'Tab':
|
|
1291
|
+
// Leaving with a row still in the air would strand it. Drop first,
|
|
1292
|
+
// then let the browser move focus normally.
|
|
1293
|
+
this.endMove(true);
|
|
1294
|
+
break;
|
|
1295
|
+
default:
|
|
1296
|
+
break;
|
|
1297
|
+
}
|
|
1298
|
+
}
|
|
1299
|
+
|
|
1300
|
+
private navigationKeys(
|
|
1301
|
+
event: KeyboardEvent,
|
|
1302
|
+
id: string,
|
|
1303
|
+
col: number,
|
|
1304
|
+
): void {
|
|
1305
|
+
const rows = this.baseRows;
|
|
1306
|
+
const index = rows.findIndex((row) => row.id === id);
|
|
1307
|
+
if (index === -1) {
|
|
1308
|
+
return;
|
|
1309
|
+
}
|
|
1310
|
+
const row = rows[index];
|
|
1311
|
+
const last = rows.length - 1;
|
|
1312
|
+
const lastCol = this.colCount - 1;
|
|
1313
|
+
|
|
1314
|
+
switch (event.key) {
|
|
1315
|
+
case 'ArrowDown': {
|
|
1316
|
+
event.preventDefault();
|
|
1317
|
+
const next = rows[Math.min(last, index + 1)];
|
|
1318
|
+
this.moveCursor(next.id, col, true);
|
|
1319
|
+
if (event.shiftKey) {
|
|
1320
|
+
this.extendSelection(next.id);
|
|
1321
|
+
}
|
|
1322
|
+
return;
|
|
1323
|
+
}
|
|
1324
|
+
case 'ArrowUp': {
|
|
1325
|
+
event.preventDefault();
|
|
1326
|
+
const next = rows[Math.max(0, index - 1)];
|
|
1327
|
+
this.moveCursor(next.id, col, true);
|
|
1328
|
+
if (event.shiftKey) {
|
|
1329
|
+
this.extendSelection(next.id);
|
|
1330
|
+
}
|
|
1331
|
+
return;
|
|
1332
|
+
}
|
|
1333
|
+
case 'ArrowRight': {
|
|
1334
|
+
event.preventDefault();
|
|
1335
|
+
// The treegrid rule: on the row's first cell a collapsed branch
|
|
1336
|
+
// opens; everywhere else the cursor walks right through the cells.
|
|
1337
|
+
if (col === 0 && row.hasChildren && !row.expanded) {
|
|
1338
|
+
this.toggleExpanded(row.id);
|
|
1339
|
+
return;
|
|
1340
|
+
}
|
|
1341
|
+
this.moveCursor(row.id, Math.min(lastCol, col + 1), true);
|
|
1342
|
+
return;
|
|
1343
|
+
}
|
|
1344
|
+
case 'ArrowLeft': {
|
|
1345
|
+
event.preventDefault();
|
|
1346
|
+
if (col === 0) {
|
|
1347
|
+
if (row.hasChildren && row.expanded) {
|
|
1348
|
+
this.toggleExpanded(row.id);
|
|
1349
|
+
return;
|
|
1350
|
+
}
|
|
1351
|
+
if (row.parentId) {
|
|
1352
|
+
this.moveCursor(row.parentId, 0, true);
|
|
1353
|
+
}
|
|
1354
|
+
return;
|
|
1355
|
+
}
|
|
1356
|
+
this.moveCursor(row.id, Math.max(0, col - 1), true);
|
|
1357
|
+
return;
|
|
1358
|
+
}
|
|
1359
|
+
case 'Home':
|
|
1360
|
+
event.preventDefault();
|
|
1361
|
+
this.moveCursor(rows[0].id, col, true);
|
|
1362
|
+
return;
|
|
1363
|
+
case 'End':
|
|
1364
|
+
event.preventDefault();
|
|
1365
|
+
this.moveCursor(rows[last].id, col, true);
|
|
1366
|
+
return;
|
|
1367
|
+
case ' ': {
|
|
1368
|
+
event.preventDefault();
|
|
1369
|
+
// Space acts on whatever the cursor is in — the keyboard twin of
|
|
1370
|
+
// clicking that exact cell, which is the parity test.
|
|
1371
|
+
if (col === this.handleCol && this.reorderable) {
|
|
1372
|
+
this.beginMove(row.id);
|
|
1373
|
+
} else if (col === this.hiddenCol) {
|
|
1374
|
+
this.flipFlag(row, 'hidden');
|
|
1375
|
+
} else if (col === this.lockedCol) {
|
|
1376
|
+
this.flipFlag(row, 'locked');
|
|
1377
|
+
} else {
|
|
1378
|
+
this.toggleSelected(row.id);
|
|
1379
|
+
}
|
|
1380
|
+
return;
|
|
1381
|
+
}
|
|
1382
|
+
case 'Enter': {
|
|
1383
|
+
event.preventDefault();
|
|
1384
|
+
if (col === this.handleCol && this.reorderable) {
|
|
1385
|
+
this.beginMove(row.id);
|
|
1386
|
+
} else if (col === this.hiddenCol) {
|
|
1387
|
+
this.flipFlag(row, 'hidden');
|
|
1388
|
+
} else if (col === this.lockedCol) {
|
|
1389
|
+
this.flipFlag(row, 'locked');
|
|
1390
|
+
} else {
|
|
1391
|
+
this.selectOnly(row.id);
|
|
1392
|
+
this.args.onActivate?.(row.node);
|
|
1393
|
+
}
|
|
1394
|
+
return;
|
|
1395
|
+
}
|
|
1396
|
+
case 'a':
|
|
1397
|
+
case 'A':
|
|
1398
|
+
if ((event.metaKey || event.ctrlKey) && this.multi) {
|
|
1399
|
+
event.preventDefault();
|
|
1400
|
+
this.publishSelection(rows.map((visible) => visible.id));
|
|
1401
|
+
}
|
|
1402
|
+
return;
|
|
1403
|
+
case 'Escape':
|
|
1404
|
+
if (this.selectedIds.length > 0) {
|
|
1405
|
+
event.preventDefault();
|
|
1406
|
+
this.publishSelection([]);
|
|
1407
|
+
}
|
|
1408
|
+
return;
|
|
1409
|
+
default:
|
|
1410
|
+
return;
|
|
1411
|
+
}
|
|
1412
|
+
}
|
|
1413
|
+
|
|
1414
|
+
<template>
|
|
1415
|
+
<div
|
|
1416
|
+
class='pretui-lm'
|
|
1417
|
+
data-density={{this.density}}
|
|
1418
|
+
data-disabled={{if @disabled 'true'}}
|
|
1419
|
+
style={{this.hostStyle}}
|
|
1420
|
+
data-test-pretui-layer-manager
|
|
1421
|
+
...attributes
|
|
1422
|
+
>
|
|
1423
|
+
{{#if this.hasRows}}
|
|
1424
|
+
<div
|
|
1425
|
+
class='pretui-lm-grid'
|
|
1426
|
+
role='treegrid'
|
|
1427
|
+
aria-label={{this.label}}
|
|
1428
|
+
aria-multiselectable={{this.multiAttr}}
|
|
1429
|
+
aria-colcount={{this.colCount}}
|
|
1430
|
+
aria-rowcount={{this.rowCount}}
|
|
1431
|
+
aria-describedby={{this.hintId}}
|
|
1432
|
+
data-test-pretui-layer-grid
|
|
1433
|
+
{{listen 'click' this.onGridClick}}
|
|
1434
|
+
{{listen 'dblclick' this.onGridDblClick}}
|
|
1435
|
+
{{listen 'keydown' this.onGridKeydown}}
|
|
1436
|
+
>
|
|
1437
|
+
{{#each this.rows key='id' as |row|}}
|
|
1438
|
+
<div
|
|
1439
|
+
class='pretui-lm-row'
|
|
1440
|
+
role='row'
|
|
1441
|
+
data-layer-row
|
|
1442
|
+
data-layer-id={{row.id}}
|
|
1443
|
+
data-selected={{if row.selected 'true'}}
|
|
1444
|
+
data-grabbed={{if row.grabbed 'true'}}
|
|
1445
|
+
data-hidden={{if row.effectiveHidden 'true'}}
|
|
1446
|
+
data-locked={{if row.effectiveLocked 'true'}}
|
|
1447
|
+
data-branch={{if row.hasChildren 'true'}}
|
|
1448
|
+
aria-level={{row.level}}
|
|
1449
|
+
aria-posinset={{row.posinset}}
|
|
1450
|
+
aria-setsize={{row.setsize}}
|
|
1451
|
+
aria-expanded={{row.expandedAttr}}
|
|
1452
|
+
aria-selected={{row.selectedAttr}}
|
|
1453
|
+
data-test-pretui-layer-row
|
|
1454
|
+
>
|
|
1455
|
+
{{#if this.reorderable}}
|
|
1456
|
+
<div
|
|
1457
|
+
class='pretui-lm-cell pretui-lm-cellGrab'
|
|
1458
|
+
role='gridcell'
|
|
1459
|
+
aria-colindex={{this.handleAria}}
|
|
1460
|
+
>
|
|
1461
|
+
<button
|
|
1462
|
+
type='button'
|
|
1463
|
+
class='pretui-lm-handle'
|
|
1464
|
+
data-layer-cell='handle'
|
|
1465
|
+
data-layer-id={{row.id}}
|
|
1466
|
+
data-col={{this.handleCol}}
|
|
1467
|
+
data-test-pretui-layer-handle
|
|
1468
|
+
aria-label={{row.handleLabel}}
|
|
1469
|
+
aria-pressed={{row.grabbedAttr}}
|
|
1470
|
+
{{rovingTabindex (this.isCursor row this.handleCol)}}
|
|
1471
|
+
{{focusWhen (this.takesFocus row this.handleCol)}}
|
|
1472
|
+
{{layerDrag this row.id @disabled}}
|
|
1473
|
+
><span class='pretui-lm-grip' aria-hidden='true'></span></button>
|
|
1474
|
+
</div>
|
|
1475
|
+
{{/if}}
|
|
1476
|
+
|
|
1477
|
+
<div
|
|
1478
|
+
class='pretui-lm-cell pretui-lm-cellName'
|
|
1479
|
+
role='gridcell'
|
|
1480
|
+
aria-colindex={{this.nameAria}}
|
|
1481
|
+
data-layer-cell='name'
|
|
1482
|
+
data-layer-id={{row.id}}
|
|
1483
|
+
data-col={{this.nameCol}}
|
|
1484
|
+
style={{row.indentStyle}}
|
|
1485
|
+
data-test-pretui-layer-name
|
|
1486
|
+
{{rovingTabindex (this.isCursor row this.nameCol)}}
|
|
1487
|
+
{{focusWhen (this.takesFocus row this.nameCol)}}
|
|
1488
|
+
>
|
|
1489
|
+
<span
|
|
1490
|
+
class='pretui-lm-twisty'
|
|
1491
|
+
data-layer-twisty
|
|
1492
|
+
data-layer-id={{row.id}}
|
|
1493
|
+
data-open={{if row.expanded 'true'}}
|
|
1494
|
+
data-leaf={{unless row.hasChildren 'true'}}
|
|
1495
|
+
aria-hidden='true'
|
|
1496
|
+
></span>
|
|
1497
|
+
<span class='pretui-lm-glyph' aria-hidden='true'>{{row.glyph}}</span>
|
|
1498
|
+
{{#if (has-block 'name')}}
|
|
1499
|
+
{{yield row to='name'}}
|
|
1500
|
+
{{else}}
|
|
1501
|
+
<span class='pretui-lm-text'>{{row.name}}</span>
|
|
1502
|
+
{{/if}}
|
|
1503
|
+
{{#if row.stateWord}}
|
|
1504
|
+
{{!-- The word is the second channel. A dimmed row is a
|
|
1505
|
+
colour, and a colour alone is never a state. --}}
|
|
1506
|
+
<span class='pretui-lm-badge'>{{row.stateWord}}</span>
|
|
1507
|
+
{{/if}}
|
|
1508
|
+
{{#if (has-block 'trailing')}}
|
|
1509
|
+
<span class='pretui-lm-trailing'>{{yield row to='trailing'}}</span>
|
|
1510
|
+
{{/if}}
|
|
1511
|
+
</div>
|
|
1512
|
+
|
|
1513
|
+
{{#if this.showVisibility}}
|
|
1514
|
+
<div
|
|
1515
|
+
class='pretui-lm-cell pretui-lm-cellFlag'
|
|
1516
|
+
role='gridcell'
|
|
1517
|
+
aria-colindex={{this.hiddenAria}}
|
|
1518
|
+
>
|
|
1519
|
+
<button
|
|
1520
|
+
type='button'
|
|
1521
|
+
class='pretui-lm-toggle'
|
|
1522
|
+
data-layer-cell='hidden'
|
|
1523
|
+
data-layer-toggle
|
|
1524
|
+
data-layer-flag='hidden'
|
|
1525
|
+
data-layer-id={{row.id}}
|
|
1526
|
+
data-col={{this.hiddenCol}}
|
|
1527
|
+
data-inherited={{if row.inheritedHidden 'true'}}
|
|
1528
|
+
data-test-pretui-layer-visibility
|
|
1529
|
+
aria-label={{row.hiddenLabel}}
|
|
1530
|
+
aria-pressed={{row.hiddenPressed}}
|
|
1531
|
+
aria-disabled={{if @disabled 'true'}}
|
|
1532
|
+
{{rovingTabindex (this.isCursor row this.hiddenCol)}}
|
|
1533
|
+
{{focusWhen (this.takesFocus row this.hiddenCol)}}
|
|
1534
|
+
><span class='pretui-lm-eye' aria-hidden='true'></span></button>
|
|
1535
|
+
</div>
|
|
1536
|
+
{{/if}}
|
|
1537
|
+
|
|
1538
|
+
{{#if this.showLock}}
|
|
1539
|
+
<div
|
|
1540
|
+
class='pretui-lm-cell pretui-lm-cellFlag'
|
|
1541
|
+
role='gridcell'
|
|
1542
|
+
aria-colindex={{this.lockedAria}}
|
|
1543
|
+
>
|
|
1544
|
+
<button
|
|
1545
|
+
type='button'
|
|
1546
|
+
class='pretui-lm-toggle'
|
|
1547
|
+
data-layer-cell='locked'
|
|
1548
|
+
data-layer-toggle
|
|
1549
|
+
data-layer-flag='locked'
|
|
1550
|
+
data-layer-id={{row.id}}
|
|
1551
|
+
data-col={{this.lockedCol}}
|
|
1552
|
+
data-inherited={{if row.inheritedLocked 'true'}}
|
|
1553
|
+
data-test-pretui-layer-lock
|
|
1554
|
+
aria-label={{row.lockedLabel}}
|
|
1555
|
+
aria-pressed={{row.lockedPressed}}
|
|
1556
|
+
aria-disabled={{if @disabled 'true'}}
|
|
1557
|
+
{{rovingTabindex (this.isCursor row this.lockedCol)}}
|
|
1558
|
+
{{focusWhen (this.takesFocus row this.lockedCol)}}
|
|
1559
|
+
><span class='pretui-lm-lock' aria-hidden='true'></span></button>
|
|
1560
|
+
</div>
|
|
1561
|
+
{{/if}}
|
|
1562
|
+
</div>
|
|
1563
|
+
{{/each}}
|
|
1564
|
+
</div>
|
|
1565
|
+
|
|
1566
|
+
<p id={{this.hintId}} class='pretui-lm-hint'>Arrow keys move between
|
|
1567
|
+
rows and cells. On a handle, press Enter or Space to pick a layer
|
|
1568
|
+
up, then up and down to reorder it, right to nest it inside the
|
|
1569
|
+
layer above, left to move it back out, Enter to drop and Escape to
|
|
1570
|
+
cancel.</p>
|
|
1571
|
+
<p
|
|
1572
|
+
class='pretui-lm-live'
|
|
1573
|
+
role='status'
|
|
1574
|
+
aria-live='polite'
|
|
1575
|
+
data-test-pretui-layer-status
|
|
1576
|
+
>{{this.announcement}}</p>
|
|
1577
|
+
{{else if (has-block 'empty')}}
|
|
1578
|
+
{{yield to='empty'}}
|
|
1579
|
+
{{else}}
|
|
1580
|
+
<EmptyState
|
|
1581
|
+
@title='No layers yet'
|
|
1582
|
+
@message='Draw something, or drop a file onto the canvas, and it will appear here.'
|
|
1583
|
+
/>
|
|
1584
|
+
{{/if}}
|
|
1585
|
+
</div>
|
|
1586
|
+
|
|
1587
|
+
<style scoped>
|
|
1588
|
+
@layer PretComponent {
|
|
1589
|
+
.pretui-lm {
|
|
1590
|
+
--pretui-lm-indent: 14px;
|
|
1591
|
+
--pretui-lm-row-h: 26px;
|
|
1592
|
+
display: grid;
|
|
1593
|
+
gap: var(--space-2, 6px);
|
|
1594
|
+
min-width: 0;
|
|
1595
|
+
}
|
|
1596
|
+
.pretui-lm[data-density='compact'] {
|
|
1597
|
+
--pretui-lm-row-h: 22px;
|
|
1598
|
+
}
|
|
1599
|
+
.pretui-lm[data-disabled='true'] {
|
|
1600
|
+
opacity: 0.55;
|
|
1601
|
+
}
|
|
1602
|
+
|
|
1603
|
+
.pretui-lm-grid {
|
|
1604
|
+
display: grid;
|
|
1605
|
+
min-width: 0;
|
|
1606
|
+
}
|
|
1607
|
+
.pretui-lm-row {
|
|
1608
|
+
--pretui-lm-level: 0;
|
|
1609
|
+
display: flex;
|
|
1610
|
+
align-items: center;
|
|
1611
|
+
gap: 2px;
|
|
1612
|
+
min-width: 0;
|
|
1613
|
+
height: var(--pretui-lm-row-h);
|
|
1614
|
+
border-radius: var(--radius-sm, 6px);
|
|
1615
|
+
}
|
|
1616
|
+
.pretui-lm-row:hover {
|
|
1617
|
+
background: var(
|
|
1618
|
+
--hover,
|
|
1619
|
+
color-mix(in oklch, var(--foreground) 5%, transparent)
|
|
1620
|
+
);
|
|
1621
|
+
}
|
|
1622
|
+
.pretui-lm-row[data-selected='true'] {
|
|
1623
|
+
background: color-mix(
|
|
1624
|
+
in oklch,
|
|
1625
|
+
var(--primary) 14%,
|
|
1626
|
+
var(--card)
|
|
1627
|
+
);
|
|
1628
|
+
}
|
|
1629
|
+
/* Law 5: the raised state encodes "this is the layer you are
|
|
1630
|
+
carrying" — a fact the reader would otherwise infer from rows
|
|
1631
|
+
shuffling. It rests in a still frame, so nothing depends on motion
|
|
1632
|
+
to be legible (Law 8). */
|
|
1633
|
+
.pretui-lm-row[data-grabbed='true'] {
|
|
1634
|
+
background: var(--card);
|
|
1635
|
+
box-shadow: var(
|
|
1636
|
+
--pretui-shadow-raised,
|
|
1637
|
+
0 0 0 1px var(--border),
|
|
1638
|
+
0 2px 10px rgb(0 0 0 / 0.22)
|
|
1639
|
+
);
|
|
1640
|
+
}
|
|
1641
|
+
|
|
1642
|
+
.pretui-lm-cell {
|
|
1643
|
+
display: flex;
|
|
1644
|
+
align-items: center;
|
|
1645
|
+
min-width: 0;
|
|
1646
|
+
}
|
|
1647
|
+
.pretui-lm-cell:focus-visible,
|
|
1648
|
+
.pretui-lm-handle:focus-visible,
|
|
1649
|
+
.pretui-lm-toggle:focus-visible {
|
|
1650
|
+
outline: 2px solid var(--ring);
|
|
1651
|
+
outline-offset: -1px;
|
|
1652
|
+
border-radius: var(--radius-sm, 6px);
|
|
1653
|
+
}
|
|
1654
|
+
.pretui-lm-cellName {
|
|
1655
|
+
flex: 1 1 auto;
|
|
1656
|
+
gap: 4px;
|
|
1657
|
+
/* min-width: 0 with the ellipsis below is the fix for the flex
|
|
1658
|
+
overflow that otherwise blows the row out on a long name
|
|
1659
|
+
. */
|
|
1660
|
+
min-width: 0;
|
|
1661
|
+
padding-inline-start: calc(
|
|
1662
|
+
var(--pretui-lm-indent, 14px) * var(--pretui-lm-level, 0)
|
|
1663
|
+
);
|
|
1664
|
+
}
|
|
1665
|
+
.pretui-lm-cellGrab,
|
|
1666
|
+
.pretui-lm-cellFlag {
|
|
1667
|
+
flex: 0 0 auto;
|
|
1668
|
+
}
|
|
1669
|
+
|
|
1670
|
+
.pretui-lm-handle,
|
|
1671
|
+
.pretui-lm-toggle {
|
|
1672
|
+
display: grid;
|
|
1673
|
+
place-items: center;
|
|
1674
|
+
width: var(--pretui-lm-row-h);
|
|
1675
|
+
height: var(--pretui-lm-row-h);
|
|
1676
|
+
padding: 0;
|
|
1677
|
+
border: 0;
|
|
1678
|
+
background: none;
|
|
1679
|
+
color: var(--muted-foreground);
|
|
1680
|
+
cursor: pointer;
|
|
1681
|
+
}
|
|
1682
|
+
.pretui-lm-handle {
|
|
1683
|
+
cursor: grab;
|
|
1684
|
+
width: 16px;
|
|
1685
|
+
}
|
|
1686
|
+
.pretui-lm-row[data-grabbed='true'] .pretui-lm-handle {
|
|
1687
|
+
cursor: grabbing;
|
|
1688
|
+
}
|
|
1689
|
+
.pretui-lm-grip {
|
|
1690
|
+
width: 6px;
|
|
1691
|
+
height: 10px;
|
|
1692
|
+
background-image: radial-gradient(currentColor 40%, transparent 42%);
|
|
1693
|
+
background-size: 3px 3px;
|
|
1694
|
+
opacity: 0.75;
|
|
1695
|
+
}
|
|
1696
|
+
|
|
1697
|
+
/* The twisty is a CSS triangle rather than a glyph, so it rotates
|
|
1698
|
+
rather than swapping — one element, two states, no reflow
|
|
1699
|
+
. */
|
|
1700
|
+
.pretui-lm-twisty {
|
|
1701
|
+
flex: 0 0 auto;
|
|
1702
|
+
width: 10px;
|
|
1703
|
+
height: 10px;
|
|
1704
|
+
border-inline-start: 4px solid currentColor;
|
|
1705
|
+
border-block-start: 4px solid transparent;
|
|
1706
|
+
border-block-end: 4px solid transparent;
|
|
1707
|
+
color: var(--muted-foreground);
|
|
1708
|
+
cursor: pointer;
|
|
1709
|
+
transition: transform var(--pretui-lm-transition, 140ms) ease;
|
|
1710
|
+
}
|
|
1711
|
+
.pretui-lm-twisty[data-open='true'] {
|
|
1712
|
+
transform: rotate(90deg);
|
|
1713
|
+
}
|
|
1714
|
+
.pretui-lm-twisty[data-leaf='true'] {
|
|
1715
|
+
border-inline-start-color: transparent;
|
|
1716
|
+
cursor: default;
|
|
1717
|
+
}
|
|
1718
|
+
|
|
1719
|
+
.pretui-lm-glyph {
|
|
1720
|
+
flex: 0 0 auto;
|
|
1721
|
+
width: 13px;
|
|
1722
|
+
text-align: center;
|
|
1723
|
+
font-size: 10px;
|
|
1724
|
+
line-height: 1;
|
|
1725
|
+
color: var(--muted-foreground);
|
|
1726
|
+
}
|
|
1727
|
+
.pretui-lm-text {
|
|
1728
|
+
min-width: 0;
|
|
1729
|
+
overflow: hidden;
|
|
1730
|
+
text-overflow: ellipsis;
|
|
1731
|
+
white-space: nowrap;
|
|
1732
|
+
font-size: var(--text-ui-md, 12.5px);
|
|
1733
|
+
color: var(--foreground);
|
|
1734
|
+
}
|
|
1735
|
+
.pretui-lm-badge {
|
|
1736
|
+
flex: 0 0 auto;
|
|
1737
|
+
font-size: var(--text-ui-xs, 10px);
|
|
1738
|
+
letter-spacing: 0.04em;
|
|
1739
|
+
text-transform: uppercase;
|
|
1740
|
+
color: var(--muted-foreground);
|
|
1741
|
+
}
|
|
1742
|
+
.pretui-lm-trailing {
|
|
1743
|
+
flex: 0 0 auto;
|
|
1744
|
+
display: flex;
|
|
1745
|
+
align-items: center;
|
|
1746
|
+
gap: 4px;
|
|
1747
|
+
}
|
|
1748
|
+
/* Hidden and locked read in greyscale: the name loses weight and the
|
|
1749
|
+
word beside it says which. Never the tint alone. */
|
|
1750
|
+
.pretui-lm-row[data-hidden='true'] .pretui-lm-text,
|
|
1751
|
+
.pretui-lm-row[data-hidden='true'] .pretui-lm-glyph {
|
|
1752
|
+
opacity: 0.5;
|
|
1753
|
+
}
|
|
1754
|
+
.pretui-lm-row[data-locked='true'] .pretui-lm-text {
|
|
1755
|
+
font-style: italic;
|
|
1756
|
+
}
|
|
1757
|
+
|
|
1758
|
+
/* ── the eye ── a shape, drawn, so the state is legible without a
|
|
1759
|
+
colour and without an icon font. */
|
|
1760
|
+
.pretui-lm-eye {
|
|
1761
|
+
position: relative;
|
|
1762
|
+
display: block;
|
|
1763
|
+
width: 13px;
|
|
1764
|
+
height: 8px;
|
|
1765
|
+
border: 1.25px solid currentColor;
|
|
1766
|
+
border-radius: 100% / 62%;
|
|
1767
|
+
}
|
|
1768
|
+
.pretui-lm-eye::before {
|
|
1769
|
+
content: '';
|
|
1770
|
+
position: absolute;
|
|
1771
|
+
inset-block-start: 1px;
|
|
1772
|
+
inset-inline-start: 4px;
|
|
1773
|
+
width: 3.5px;
|
|
1774
|
+
height: 3.5px;
|
|
1775
|
+
border-radius: 50%;
|
|
1776
|
+
background: currentColor;
|
|
1777
|
+
}
|
|
1778
|
+
/* Pressed means "this layer is hidden", so the slash appears — the
|
|
1779
|
+
shape carries the state and aria-pressed carries it again. */
|
|
1780
|
+
.pretui-lm-toggle[aria-pressed='true'] .pretui-lm-eye::after {
|
|
1781
|
+
content: '';
|
|
1782
|
+
position: absolute;
|
|
1783
|
+
inset-block-start: 3px;
|
|
1784
|
+
inset-inline-start: -2px;
|
|
1785
|
+
width: 17px;
|
|
1786
|
+
height: 1.25px;
|
|
1787
|
+
background: currentColor;
|
|
1788
|
+
transform: rotate(-32deg);
|
|
1789
|
+
}
|
|
1790
|
+
/* An ancestor is doing the hiding: the button is drawn quietly and its
|
|
1791
|
+
accessible name names the group responsible, rather than reporting a
|
|
1792
|
+
flag that has no effect. */
|
|
1793
|
+
.pretui-lm-toggle[data-inherited='true'] {
|
|
1794
|
+
opacity: 0.45;
|
|
1795
|
+
}
|
|
1796
|
+
|
|
1797
|
+
/* ── the padlock ── body plus shackle; unlocked tilts the shackle
|
|
1798
|
+
open rather than changing colour. */
|
|
1799
|
+
.pretui-lm-lock {
|
|
1800
|
+
position: relative;
|
|
1801
|
+
display: block;
|
|
1802
|
+
width: 9px;
|
|
1803
|
+
height: 7px;
|
|
1804
|
+
margin-block-start: 4px;
|
|
1805
|
+
border: 1.25px solid currentColor;
|
|
1806
|
+
border-radius: 1.5px;
|
|
1807
|
+
}
|
|
1808
|
+
.pretui-lm-lock::before {
|
|
1809
|
+
content: '';
|
|
1810
|
+
position: absolute;
|
|
1811
|
+
inset-block-start: -5px;
|
|
1812
|
+
inset-inline-start: 1px;
|
|
1813
|
+
width: 5px;
|
|
1814
|
+
height: 5px;
|
|
1815
|
+
border: 1.25px solid currentColor;
|
|
1816
|
+
border-block-end: 0;
|
|
1817
|
+
border-radius: 3px 3px 0 0;
|
|
1818
|
+
transform-origin: 100% 100%;
|
|
1819
|
+
transition: transform var(--pretui-lm-transition, 140ms) ease;
|
|
1820
|
+
}
|
|
1821
|
+
.pretui-lm-toggle[aria-pressed='false'] .pretui-lm-lock::before {
|
|
1822
|
+
transform: rotate(-28deg) translateY(-1px);
|
|
1823
|
+
}
|
|
1824
|
+
.pretui-lm-toggle[aria-pressed='true'] .pretui-lm-lock {
|
|
1825
|
+
background: color-mix(in oklch, currentColor 22%, transparent);
|
|
1826
|
+
}
|
|
1827
|
+
|
|
1828
|
+
/* The flag controls are quiet at rest and full strength the moment the
|
|
1829
|
+
row is engaged — but they are never absent and never invisible. A
|
|
1830
|
+
focusable control at opacity 0 is worse than no control at all. */
|
|
1831
|
+
.pretui-lm-toggle {
|
|
1832
|
+
opacity: 0.55;
|
|
1833
|
+
}
|
|
1834
|
+
.pretui-lm-row:hover .pretui-lm-toggle,
|
|
1835
|
+
.pretui-lm-row:focus-within .pretui-lm-toggle,
|
|
1836
|
+
.pretui-lm-row[data-hidden='true'] .pretui-lm-toggle,
|
|
1837
|
+
.pretui-lm-row[data-locked='true'] .pretui-lm-toggle {
|
|
1838
|
+
opacity: 1;
|
|
1839
|
+
}
|
|
1840
|
+
|
|
1841
|
+
.pretui-lm-hint {
|
|
1842
|
+
margin: 0;
|
|
1843
|
+
font-size: var(--text-ui-sm, 11.5px);
|
|
1844
|
+
color: var(--muted-foreground);
|
|
1845
|
+
}
|
|
1846
|
+
/* Text for assistive technology only. Not display:none — that removes
|
|
1847
|
+
it from the accessibility tree along with everything it would say. */
|
|
1848
|
+
.pretui-lm-live {
|
|
1849
|
+
position: absolute;
|
|
1850
|
+
width: 1px;
|
|
1851
|
+
height: 1px;
|
|
1852
|
+
margin: -1px;
|
|
1853
|
+
padding: 0;
|
|
1854
|
+
overflow: hidden;
|
|
1855
|
+
clip-path: inset(50%);
|
|
1856
|
+
white-space: nowrap;
|
|
1857
|
+
border: 0;
|
|
1858
|
+
}
|
|
1859
|
+
|
|
1860
|
+
@media (prefers-reduced-motion: reduce) {
|
|
1861
|
+
.pretui-lm-twisty,
|
|
1862
|
+
.pretui-lm-lock::before {
|
|
1863
|
+
transition: none;
|
|
1864
|
+
}
|
|
1865
|
+
}
|
|
1866
|
+
/* A 26px row is not a 44px touch target, so on a coarse pointer the
|
|
1867
|
+
controls grow into the row rather than the row growing into the
|
|
1868
|
+
page — and the hover-quietened toggles stop being quiet, because
|
|
1869
|
+
there is no hover to reveal them. */
|
|
1870
|
+
@media (any-pointer: coarse) {
|
|
1871
|
+
.pretui-lm {
|
|
1872
|
+
--pretui-lm-row-h: 36px;
|
|
1873
|
+
}
|
|
1874
|
+
.pretui-lm-handle {
|
|
1875
|
+
width: 28px;
|
|
1876
|
+
}
|
|
1877
|
+
.pretui-lm-toggle {
|
|
1878
|
+
opacity: 1;
|
|
1879
|
+
}
|
|
1880
|
+
}
|
|
1881
|
+
}
|
|
1882
|
+
</style>
|
|
1883
|
+
</template>
|
|
1884
|
+
}
|