@gjermundgaraba-designs/pixel-paper 0.26.0 → 0.27.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/DESIGN.md +28 -3
- package/dist/src/adapters/diagram.d.ts +38 -0
- package/dist/src/adapters/diagram.d.ts.map +1 -0
- package/dist/src/adapters/diagram.js +206 -0
- package/dist/src/adapters/mermaid.d.ts +2 -20
- package/dist/src/adapters/mermaid.d.ts.map +1 -1
- package/dist/src/adapters/mermaid.js +9 -229
- package/dist/src/announcer/announcer.d.ts +0 -4
- package/dist/src/announcer/announcer.d.ts.map +1 -1
- package/dist/src/announcer/announcer.js +19 -18
- package/dist/src/attributes/attributes.d.ts.map +1 -1
- package/dist/src/{audioFrame/audioFrame.d.ts → audio-frame/audio-frame.d.ts} +1 -1
- package/dist/src/audio-frame/audio-frame.d.ts.map +1 -0
- package/dist/src/{audioFrame/audioFrame.js → audio-frame/audio-frame.js} +1 -1
- package/dist/src/audio-frame/index.d.ts +3 -0
- package/dist/src/audio-frame/index.d.ts.map +1 -0
- package/dist/src/audio-frame/index.js +1 -0
- package/dist/src/banner/banner.d.ts.map +1 -1
- package/dist/src/banner/index.d.ts.map +1 -1
- package/dist/src/{barChart/barChart.d.ts → bar-chart/bar-chart.d.ts} +2 -2
- package/dist/src/bar-chart/bar-chart.d.ts.map +1 -0
- package/dist/src/{barChart/barChart.js → bar-chart/bar-chart.js} +40 -35
- package/dist/src/bar-chart/index.d.ts +3 -0
- package/dist/src/bar-chart/index.d.ts.map +1 -0
- package/dist/src/bar-chart/index.js +1 -0
- package/dist/src/bench/bench.d.ts.map +1 -1
- package/dist/src/bench/index.d.ts.map +1 -1
- package/dist/src/board/board.d.ts +45 -46
- package/dist/src/board/board.d.ts.map +1 -1
- package/dist/src/board/board.js +76 -102
- package/dist/src/board/index.d.ts +1 -1
- package/dist/src/board/index.d.ts.map +1 -1
- package/dist/src/button/button.d.ts +1 -2
- package/dist/src/button/button.d.ts.map +1 -1
- package/dist/src/button/button.js +7 -5
- package/dist/src/button/index.d.ts +1 -1
- package/dist/src/button/index.d.ts.map +1 -1
- package/dist/src/card/card.d.ts.map +1 -1
- package/dist/src/card/card.js +4 -2
- package/dist/src/card/index.d.ts.map +1 -1
- package/dist/src/{chartTable/chartTable.d.ts → chart-table/chart-table.d.ts} +4 -14
- package/dist/src/chart-table/chart-table.d.ts.map +1 -0
- package/dist/src/{chartTable/chartTable.js → chart-table/chart-table.js} +9 -16
- package/dist/src/chip/chip.d.ts.map +1 -1
- package/dist/src/chip/chip.js +4 -2
- package/dist/src/chip/index.d.ts.map +1 -1
- package/dist/src/choice/choice.d.ts.map +1 -1
- package/dist/src/choice/choice.js +3 -1
- package/dist/src/choice/index.d.ts.map +1 -1
- package/dist/src/choices/choices.d.ts.map +1 -1
- package/dist/src/choices/index.d.ts.map +1 -1
- package/dist/src/{codeEditor/codeEditor.d.ts → code-editor/code-editor.d.ts} +1 -1
- package/dist/src/code-editor/code-editor.d.ts.map +1 -0
- package/dist/src/{codeEditor/codeEditor.js → code-editor/code-editor.js} +2 -2
- package/dist/src/code-editor/index.d.ts +3 -0
- package/dist/src/code-editor/index.d.ts.map +1 -0
- package/dist/src/code-editor/index.js +1 -0
- package/dist/src/{codeSurface/codeSurface.d.ts → code-surface/code-surface.d.ts} +1 -1
- package/dist/src/code-surface/code-surface.d.ts.map +1 -0
- package/dist/src/{codeSurface/codeSurface.js → code-surface/code-surface.js} +6 -1
- package/dist/src/code-surface/index.d.ts +3 -0
- package/dist/src/code-surface/index.d.ts.map +1 -0
- package/dist/src/code-surface/index.js +1 -0
- package/dist/src/{commandPalette/commandPalette.d.ts → command-palette/command-palette.d.ts} +85 -77
- package/dist/src/command-palette/command-palette.d.ts.map +1 -0
- package/dist/src/command-palette/command-palette.js +625 -0
- package/dist/src/{commandPalette → command-palette}/index.d.ts +2 -2
- package/dist/src/command-palette/index.d.ts.map +1 -0
- package/dist/src/{commandPalette → command-palette}/index.js +1 -1
- package/dist/src/{commandPalette → command-palette}/keys.d.ts +0 -21
- package/dist/src/command-palette/keys.d.ts.map +1 -0
- package/dist/src/command-palette/keys.js +85 -0
- package/dist/src/{commandPalette → command-palette}/match.d.ts +5 -11
- package/dist/src/command-palette/match.d.ts.map +1 -0
- package/dist/src/{commandPalette → command-palette}/match.js +20 -24
- package/dist/src/{commandPalette → command-palette}/message.d.ts +37 -26
- package/dist/src/command-palette/message.d.ts.map +1 -0
- package/dist/src/{commandPalette → command-palette}/message.js +8 -20
- package/dist/src/{confirmDialog/confirmDialog.d.ts → confirm-dialog/confirm-dialog.d.ts} +1 -1
- package/dist/src/confirm-dialog/confirm-dialog.d.ts.map +1 -0
- package/dist/src/{confirmDialog/confirmDialog.js → confirm-dialog/confirm-dialog.js} +18 -23
- package/dist/src/confirm-dialog/index.d.ts +3 -0
- package/dist/src/confirm-dialog/index.d.ts.map +1 -0
- package/dist/src/{confirmDialog → confirm-dialog}/index.js +1 -1
- package/dist/src/{contextMenu/contextMenu.d.ts → context-menu/context-menu.d.ts} +18 -21
- package/dist/src/context-menu/context-menu.d.ts.map +1 -0
- package/dist/src/{contextMenu/contextMenu.js → context-menu/context-menu.js} +45 -57
- package/dist/src/{contextMenu → context-menu}/index.d.ts +2 -2
- package/dist/src/context-menu/index.d.ts.map +1 -0
- package/dist/src/{contextMenu → context-menu}/index.js +1 -1
- package/dist/src/{copyButton/copyButton.d.ts → copy-button/copy-button.d.ts} +5 -7
- package/dist/src/copy-button/copy-button.d.ts.map +1 -0
- package/dist/src/{copyButton/copyButton.js → copy-button/copy-button.js} +18 -27
- package/dist/src/copy-button/index.d.ts +3 -0
- package/dist/src/copy-button/index.d.ts.map +1 -0
- package/dist/src/copy-button/index.js +1 -0
- package/dist/src/crumbs/crumbs.d.ts +1 -1
- package/dist/src/crumbs/crumbs.d.ts.map +1 -1
- package/dist/src/crumbs/index.d.ts.map +1 -1
- package/dist/src/deck/deck.d.ts.map +1 -1
- package/dist/src/deck/index.d.ts.map +1 -1
- package/dist/src/dialog/dialog.d.ts +6 -14
- package/dist/src/dialog/dialog.d.ts.map +1 -1
- package/dist/src/dialog/dialog.js +29 -36
- package/dist/src/dialog/fold.d.ts +3 -3
- package/dist/src/dialog/fold.d.ts.map +1 -1
- package/dist/src/dialog/fold.js +5 -4
- package/dist/src/dialog/index.d.ts +1 -1
- package/dist/src/dialog/index.d.ts.map +1 -1
- package/dist/src/disclosure/disclosure.d.ts.map +1 -1
- package/dist/src/disclosure/disclosure.js +3 -1
- package/dist/src/disclosure/index.d.ts.map +1 -1
- package/dist/src/dom/html-element.d.ts +3 -0
- package/dist/src/dom/html-element.d.ts.map +1 -0
- package/dist/src/dom/html-element.js +6 -0
- package/dist/src/drag/drag.d.ts +0 -34
- package/dist/src/drag/drag.d.ts.map +1 -1
- package/dist/src/drag/drag.js +27 -73
- package/dist/src/{dropZone/dropZone.d.ts → drop-zone/drop-zone.d.ts} +3 -3
- package/dist/src/drop-zone/drop-zone.d.ts.map +1 -0
- package/dist/src/{dropZone/dropZone.js → drop-zone/drop-zone.js} +13 -19
- package/dist/src/drop-zone/index.d.ts +3 -0
- package/dist/src/drop-zone/index.d.ts.map +1 -0
- package/dist/src/drop-zone/index.js +1 -0
- package/dist/src/{editableTitle/editableTitle.d.ts → editable-title/editable-title.d.ts} +14 -12
- package/dist/src/editable-title/editable-title.d.ts.map +1 -0
- package/dist/src/{editableTitle/editableTitle.js → editable-title/editable-title.js} +33 -39
- package/dist/src/editable-title/index.d.ts +4 -0
- package/dist/src/editable-title/index.d.ts.map +1 -0
- package/dist/src/{editableTitle → editable-title}/index.js +1 -1
- package/dist/src/{emptyState/emptyState.d.ts → empty-state/empty-state.d.ts} +1 -1
- package/dist/src/empty-state/empty-state.d.ts.map +1 -0
- package/dist/src/{emptyState/emptyState.js → empty-state/empty-state.js} +5 -2
- package/dist/src/empty-state/index.d.ts +3 -0
- package/dist/src/empty-state/index.d.ts.map +1 -0
- package/dist/src/empty-state/index.js +1 -0
- package/dist/src/{errorSummary/errorSummary.d.ts → error-summary/error-summary.d.ts} +2 -2
- package/dist/src/error-summary/error-summary.d.ts.map +1 -0
- package/dist/src/{errorSummary/errorSummary.js → error-summary/error-summary.js} +7 -5
- package/dist/src/error-summary/index.d.ts +3 -0
- package/dist/src/error-summary/index.d.ts.map +1 -0
- package/dist/src/error-summary/index.js +1 -0
- package/dist/src/field/field.d.ts +2 -7
- package/dist/src/field/field.d.ts.map +1 -1
- package/dist/src/field/field.js +12 -13
- package/dist/src/field/index.d.ts.map +1 -1
- package/dist/src/{fieldGrid/fieldGrid.d.ts → field-grid/field-grid.d.ts} +1 -1
- package/dist/src/field-grid/field-grid.d.ts.map +1 -0
- package/dist/src/{fieldGrid/fieldGrid.js → field-grid/field-grid.js} +1 -1
- package/dist/src/field-grid/index.d.ts +3 -0
- package/dist/src/field-grid/index.d.ts.map +1 -0
- package/dist/src/field-grid/index.js +1 -0
- package/dist/src/fields/fields.d.ts.map +1 -1
- package/dist/src/fields/fields.js +4 -1
- package/dist/src/fields/index.d.ts.map +1 -1
- package/dist/src/fieldset/fieldset.d.ts.map +1 -1
- package/dist/src/fieldset/index.d.ts.map +1 -1
- package/dist/src/{fileTree/fileTree.d.ts → file-tree/file-tree.d.ts} +5 -5
- package/dist/src/file-tree/file-tree.d.ts.map +1 -0
- package/dist/src/file-tree/file-tree.js +242 -0
- package/dist/src/file-tree/index.d.ts +3 -0
- package/dist/src/file-tree/index.d.ts.map +1 -0
- package/dist/src/{fileTree → file-tree}/index.js +1 -1
- package/dist/src/{filterChip/filterChip.d.ts → filter-chip/filter-chip.d.ts} +1 -1
- package/dist/src/filter-chip/filter-chip.d.ts.map +1 -0
- package/dist/src/{filterChip/filterChip.js → filter-chip/filter-chip.js} +11 -7
- package/dist/src/filter-chip/index.d.ts +3 -0
- package/dist/src/filter-chip/index.d.ts.map +1 -0
- package/dist/src/filter-chip/index.js +1 -0
- package/dist/src/{filterStrip/filterStrip.d.ts → filter-strip/filter-strip.d.ts} +1 -1
- package/dist/src/filter-strip/filter-strip.d.ts.map +1 -0
- package/dist/src/{filterStrip/filterStrip.js → filter-strip/filter-strip.js} +1 -1
- package/dist/src/filter-strip/index.d.ts +3 -0
- package/dist/src/filter-strip/index.d.ts.map +1 -0
- package/dist/src/filter-strip/index.js +1 -0
- package/dist/src/{flashWord/flashWord.d.ts → flash-word/flash-word.d.ts} +2 -2
- package/dist/src/flash-word/flash-word.d.ts.map +1 -0
- package/dist/src/{flashWord/flashWord.js → flash-word/flash-word.js} +2 -3
- package/dist/src/flash-word/index.d.ts +3 -0
- package/dist/src/flash-word/index.d.ts.map +1 -0
- package/dist/src/flash-word/index.js +1 -0
- package/dist/src/focus/focus.d.ts.map +1 -1
- package/dist/src/focus/focus.js +0 -2
- package/dist/src/format/format.d.ts +0 -7
- package/dist/src/format/format.d.ts.map +1 -1
- package/dist/src/format/format.js +7 -16
- package/dist/src/format/index.d.ts.map +1 -1
- package/dist/src/glyph/glyph.d.ts +1 -2
- package/dist/src/glyph/glyph.d.ts.map +1 -1
- package/dist/src/glyph/glyph.js +0 -2
- package/dist/src/glyph/glyphs.d.ts +19 -4
- package/dist/src/glyph/glyphs.d.ts.map +1 -1
- package/dist/src/glyph/glyphs.js +2577 -2594
- package/dist/src/glyph/index.d.ts.map +1 -1
- package/dist/src/group/group.d.ts.map +1 -1
- package/dist/src/group/index.d.ts.map +1 -1
- package/dist/src/history/history.d.ts +1 -1
- package/dist/src/history/history.d.ts.map +1 -1
- package/dist/src/history/history.js +6 -3
- package/dist/src/history/index.d.ts.map +1 -1
- package/dist/src/{iconButton/iconButton.d.ts → icon-button/icon-button.d.ts} +1 -1
- package/dist/src/icon-button/icon-button.d.ts.map +1 -0
- package/dist/src/{iconButton/iconButton.js → icon-button/icon-button.js} +6 -4
- package/dist/src/icon-button/index.d.ts +3 -0
- package/dist/src/icon-button/index.d.ts.map +1 -0
- package/dist/src/icon-button/index.js +1 -0
- package/dist/src/identity/identity.d.ts.map +1 -1
- package/dist/src/identity/index.d.ts.map +1 -1
- package/dist/src/{imageFrame/imageFrame.d.ts → image-frame/image-frame.d.ts} +1 -1
- package/dist/src/image-frame/image-frame.d.ts.map +1 -0
- package/dist/src/{imageFrame/imageFrame.js → image-frame/image-frame.js} +19 -12
- package/dist/src/image-frame/index.d.ts +3 -0
- package/dist/src/image-frame/index.d.ts.map +1 -0
- package/dist/src/image-frame/index.js +1 -0
- package/dist/src/index.d.ts +41 -41
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +41 -41
- package/dist/src/inline-input/index.d.ts +3 -0
- package/dist/src/inline-input/index.d.ts.map +1 -0
- package/dist/src/{inlineInput → inline-input}/index.js +1 -1
- package/dist/src/{inlineInput/inlineInput.d.ts → inline-input/inline-input.d.ts} +8 -12
- package/dist/src/inline-input/inline-input.d.ts.map +1 -0
- package/dist/src/{inlineInput/inlineInput.js → inline-input/inline-input.js} +60 -75
- package/dist/src/key-help/index.d.ts +3 -0
- package/dist/src/key-help/index.d.ts.map +1 -0
- package/dist/src/{keyHelp → key-help}/index.js +1 -1
- package/dist/src/{keyHelp/keyHelp.d.ts → key-help/key-help.d.ts} +7 -7
- package/dist/src/key-help/key-help.d.ts.map +1 -0
- package/dist/src/{keyHelp/keyHelp.js → key-help/key-help.js} +48 -47
- package/dist/src/key-hint/index.d.ts +4 -0
- package/dist/src/key-hint/index.d.ts.map +1 -0
- package/dist/src/key-hint/index.js +2 -0
- package/dist/src/{keyHint/keyHint.d.ts → key-hint/key-hint.d.ts} +2 -2
- package/dist/src/key-hint/key-hint.d.ts.map +1 -0
- package/dist/src/{keyHint/keyHint.js → key-hint/key-hint.js} +2 -2
- package/dist/src/{keyHint/keyLabel.d.ts → key-hint/key-label.d.ts} +2 -3
- package/dist/src/key-hint/key-label.d.ts.map +1 -0
- package/dist/src/{keyHint/keyLabel.js → key-hint/key-label.js} +29 -24
- package/dist/src/keymap/index.d.ts.map +1 -1
- package/dist/src/keymap/keymap.d.ts +2 -2
- package/dist/src/keymap/keymap.d.ts.map +1 -1
- package/dist/src/keymap/keymap.js +3 -1
- package/dist/src/keys/keys.d.ts +0 -2
- package/dist/src/keys/keys.d.ts.map +1 -1
- package/dist/src/keys/keys.js +0 -2
- package/dist/src/line-chart/index.d.ts +3 -0
- package/dist/src/line-chart/index.d.ts.map +1 -0
- package/dist/src/line-chart/index.js +1 -0
- package/dist/src/{lineChart/lineChart.d.ts → line-chart/line-chart.d.ts} +2 -2
- package/dist/src/line-chart/line-chart.d.ts.map +1 -0
- package/dist/src/{lineChart/lineChart.js → line-chart/line-chart.js} +52 -44
- package/dist/src/line-diff/diff.d.ts +29 -0
- package/dist/src/line-diff/diff.d.ts.map +1 -0
- package/dist/src/line-diff/diff.js +85 -0
- package/dist/src/line-diff/index.d.ts +5 -0
- package/dist/src/line-diff/index.d.ts.map +1 -0
- package/dist/src/line-diff/index.js +2 -0
- package/dist/src/{lineDiff/lineDiff.d.ts → line-diff/line-diff.d.ts} +1 -1
- package/dist/src/line-diff/line-diff.d.ts.map +1 -0
- package/dist/src/{lineDiff/lineDiff.js → line-diff/line-diff.js} +26 -19
- package/dist/src/{lineDiff → line-diff}/patch.d.ts +5 -9
- package/dist/src/line-diff/patch.d.ts.map +1 -0
- package/dist/src/{lineDiff → line-diff}/patch.js +54 -62
- package/dist/src/link-button/index.d.ts +3 -0
- package/dist/src/link-button/index.d.ts.map +1 -0
- package/dist/src/link-button/index.js +1 -0
- package/dist/src/{linkButton/linkButton.d.ts → link-button/link-button.d.ts} +2 -2
- package/dist/src/link-button/link-button.d.ts.map +1 -0
- package/dist/src/{linkButton/linkButton.js → link-button/link-button.js} +1 -1
- package/dist/src/link-state/index.d.ts +3 -0
- package/dist/src/link-state/index.d.ts.map +1 -0
- package/dist/src/link-state/index.js +1 -0
- package/dist/src/{linkState/linkState.d.ts → link-state/link-state.d.ts} +1 -1
- package/dist/src/link-state/link-state.d.ts.map +1 -0
- package/dist/src/link-state/link-state.js +24 -0
- package/dist/src/live-region/index.d.ts +3 -0
- package/dist/src/live-region/index.d.ts.map +1 -0
- package/dist/src/live-region/index.js +1 -0
- package/dist/src/{liveRegion/liveRegion.d.ts → live-region/live-region.d.ts} +6 -3
- package/dist/src/live-region/live-region.d.ts.map +1 -0
- package/dist/src/{liveRegion/liveRegion.js → live-region/live-region.js} +7 -5
- package/dist/src/loading/index.d.ts.map +1 -1
- package/dist/src/loading/loading.d.ts.map +1 -1
- package/dist/src/loading/loading.js +5 -1
- package/dist/src/mark/index.d.ts.map +1 -1
- package/dist/src/mark/mark.d.ts +0 -4
- package/dist/src/mark/mark.d.ts.map +1 -1
- package/dist/src/mark/mark.js +6 -3
- package/dist/src/media/index.d.ts.map +1 -1
- package/dist/src/media/media.d.ts +17 -42
- package/dist/src/media/media.d.ts.map +1 -1
- package/dist/src/media/media.js +106 -104
- package/dist/src/menu/index.d.ts.map +1 -1
- package/dist/src/menu/item.d.ts +8 -8
- package/dist/src/menu/item.d.ts.map +1 -1
- package/dist/src/menu/menu.d.ts +2 -5
- package/dist/src/menu/menu.d.ts.map +1 -1
- package/dist/src/menu/menu.js +19 -30
- package/dist/src/menu/slip.d.ts +4 -18
- package/dist/src/menu/slip.d.ts.map +1 -1
- package/dist/src/menu/slip.js +36 -36
- package/dist/src/meter/index.d.ts.map +1 -1
- package/dist/src/meter/meter.d.ts +1 -1
- package/dist/src/meter/meter.d.ts.map +1 -1
- package/dist/src/meter/meter.js +12 -15
- package/dist/src/monogram/index.d.ts.map +1 -1
- package/dist/src/monogram/monogram.d.ts.map +1 -1
- package/dist/src/monogram/monogram.js +9 -8
- package/dist/src/nav-strip/index.d.ts +3 -0
- package/dist/src/nav-strip/index.d.ts.map +1 -0
- package/dist/src/nav-strip/index.js +1 -0
- package/dist/src/{navStrip/navStrip.d.ts → nav-strip/nav-strip.d.ts} +3 -6
- package/dist/src/nav-strip/nav-strip.d.ts.map +1 -0
- package/dist/src/nav-strip/nav-strip.js +25 -0
- package/dist/src/notice/index.d.ts.map +1 -1
- package/dist/src/notice/notice.d.ts +0 -4
- package/dist/src/notice/notice.d.ts.map +1 -1
- package/dist/src/notice/notice.js +1 -4
- package/dist/src/outcome/index.d.ts.map +1 -1
- package/dist/src/outcome/outcome.d.ts.map +1 -1
- package/dist/src/outcome/outcome.js +1 -1
- package/dist/src/page-head/index.d.ts +3 -0
- package/dist/src/page-head/index.d.ts.map +1 -0
- package/dist/src/page-head/index.js +1 -0
- package/dist/src/{pageHead/pageHead.d.ts → page-head/page-head.d.ts} +1 -1
- package/dist/src/page-head/page-head.d.ts.map +1 -0
- package/dist/src/{pageHead/pageHead.js → page-head/page-head.js} +1 -1
- package/dist/src/panel/index.d.ts.map +1 -1
- package/dist/src/panel/panel.d.ts +0 -1
- package/dist/src/panel/panel.d.ts.map +1 -1
- package/dist/src/panel/panel.js +0 -1
- package/dist/src/password-field/index.d.ts +3 -0
- package/dist/src/password-field/index.d.ts.map +1 -0
- package/dist/src/password-field/index.js +1 -0
- package/dist/src/{passwordField/passwordField.d.ts → password-field/password-field.d.ts} +1 -1
- package/dist/src/password-field/password-field.d.ts.map +1 -0
- package/dist/src/{passwordField/passwordField.js → password-field/password-field.js} +4 -5
- package/dist/src/places/index.d.ts.map +1 -1
- package/dist/src/places/places.d.ts +3 -4
- package/dist/src/places/places.d.ts.map +1 -1
- package/dist/src/places/places.js +8 -2
- package/dist/src/props-list/index.d.ts +3 -0
- package/dist/src/props-list/index.d.ts.map +1 -0
- package/dist/src/props-list/index.js +1 -0
- package/dist/src/{propsList/propsList.d.ts → props-list/props-list.d.ts} +2 -2
- package/dist/src/props-list/props-list.d.ts.map +1 -0
- package/dist/src/{propsList/propsList.js → props-list/props-list.js} +2 -2
- package/dist/src/prose/index.d.ts.map +1 -1
- package/dist/src/prose/prose.d.ts.map +1 -1
- package/dist/src/query-chip/index.d.ts +3 -0
- package/dist/src/query-chip/index.d.ts.map +1 -0
- package/dist/src/query-chip/index.js +1 -0
- package/dist/src/{queryChip/queryChip.d.ts → query-chip/query-chip.d.ts} +1 -1
- package/dist/src/query-chip/query-chip.d.ts.map +1 -0
- package/dist/src/{queryChip/queryChip.js → query-chip/query-chip.js} +7 -4
- package/dist/src/{radioChoices → radio-choices}/index.d.ts +2 -2
- package/dist/src/radio-choices/index.d.ts.map +1 -0
- package/dist/src/{radioChoices → radio-choices}/index.js +1 -1
- package/dist/src/{radioChoices/radioChoices.d.ts → radio-choices/radio-choices.d.ts} +3 -3
- package/dist/src/radio-choices/radio-choices.d.ts.map +1 -0
- package/dist/src/{radioChoices/radioChoices.js → radio-choices/radio-choices.js} +25 -24
- package/dist/src/rail/index.d.ts.map +1 -1
- package/dist/src/rail/rail.d.ts +16 -32
- package/dist/src/rail/rail.d.ts.map +1 -1
- package/dist/src/rail/rail.js +97 -65
- package/dist/src/reel/index.d.ts +1 -1
- package/dist/src/reel/index.d.ts.map +1 -1
- package/dist/src/reel/layout.d.ts +12 -54
- package/dist/src/reel/layout.d.ts.map +1 -1
- package/dist/src/reel/layout.js +120 -145
- package/dist/src/reel/reel.d.ts +35 -34
- package/dist/src/reel/reel.d.ts.map +1 -1
- package/dist/src/reel/reel.js +253 -233
- package/dist/src/remote/index.d.ts.map +1 -1
- package/dist/src/remote/remote.d.ts +2 -2
- package/dist/src/remote/remote.d.ts.map +1 -1
- package/dist/src/remote/remote.js +6 -2
- package/dist/src/rows/index.d.ts.map +1 -1
- package/dist/src/rows/rows.d.ts +2 -2
- package/dist/src/rows/rows.d.ts.map +1 -1
- package/dist/src/rows/rows.js +16 -7
- package/dist/src/scheme/index.d.ts +1 -1
- package/dist/src/scheme/index.d.ts.map +1 -1
- package/dist/src/scheme/index.js +1 -1
- package/dist/src/scheme/{schemeSwitch.d.ts → scheme-switch.d.ts} +2 -2
- package/dist/src/scheme/scheme-switch.d.ts.map +1 -0
- package/dist/src/scheme/{schemeSwitch.js → scheme-switch.js} +33 -38
- package/dist/src/scheme/scheme.d.ts +0 -2
- package/dist/src/scheme/scheme.d.ts.map +1 -1
- package/dist/src/scheme/scheme.js +0 -2
- package/dist/src/secret/index.d.ts.map +1 -1
- package/dist/src/secret/secret.d.ts.map +1 -1
- package/dist/src/segmented/index.d.ts.map +1 -1
- package/dist/src/segmented/segmented.d.ts.map +1 -1
- package/dist/src/segmented/segmented.js +14 -3
- package/dist/src/select-all/index.d.ts +3 -0
- package/dist/src/select-all/index.d.ts.map +1 -0
- package/dist/src/select-all/index.js +1 -0
- package/dist/src/{selectAll/selectAll.d.ts → select-all/select-all.d.ts} +1 -1
- package/dist/src/select-all/select-all.d.ts.map +1 -0
- package/dist/src/{selectAll/selectAll.js → select-all/select-all.js} +2 -2
- package/dist/src/select-field/index.d.ts +3 -0
- package/dist/src/select-field/index.d.ts.map +1 -0
- package/dist/src/select-field/index.js +1 -0
- package/dist/src/{selectField/selectField.d.ts → select-field/select-field.d.ts} +2 -2
- package/dist/src/select-field/select-field.d.ts.map +1 -0
- package/dist/src/{selectField/selectField.js → select-field/select-field.js} +10 -7
- package/dist/src/sheet/index.d.ts.map +1 -1
- package/dist/src/sheet/sheet.d.ts.map +1 -1
- package/dist/src/sheet/sheet.js +4 -1
- package/dist/src/skip-link/index.d.ts +2 -0
- package/dist/src/skip-link/index.d.ts.map +1 -0
- package/dist/src/skip-link/index.js +1 -0
- package/dist/src/{skipLink/skipLink.d.ts → skip-link/skip-link.d.ts} +1 -3
- package/dist/src/skip-link/skip-link.d.ts.map +1 -0
- package/dist/src/{skipLink/skipLink.js → skip-link/skip-link.js} +7 -11
- package/dist/src/slot/slot.d.ts +1 -4
- package/dist/src/slot/slot.d.ts.map +1 -1
- package/dist/src/slot/slot.js +3 -3
- package/dist/src/sortable/index.d.ts.map +1 -1
- package/dist/src/sortable/sortable.d.ts +44 -44
- package/dist/src/sortable/sortable.d.ts.map +1 -1
- package/dist/src/sortable/sortable.js +60 -93
- package/dist/src/stack/index.d.ts.map +1 -1
- package/dist/src/stack/stack.d.ts.map +1 -1
- package/dist/src/stack/stack.js +0 -2
- package/dist/src/stage/index.d.ts.map +1 -1
- package/dist/src/stage/stage.d.ts +1 -1
- package/dist/src/stage/stage.d.ts.map +1 -1
- package/dist/src/stage/stage.js +4 -1
- package/dist/src/stat/index.d.ts.map +1 -1
- package/dist/src/stat/stat.d.ts +1 -1
- package/dist/src/stat/stat.d.ts.map +1 -1
- package/dist/src/stat/stat.js +17 -8
- package/dist/src/status-bar/index.d.ts +4 -0
- package/dist/src/status-bar/index.d.ts.map +1 -0
- package/dist/src/status-bar/index.js +2 -0
- package/dist/src/{statusBar/statusBar.d.ts → status-bar/status-bar.d.ts} +4 -4
- package/dist/src/status-bar/status-bar.d.ts.map +1 -0
- package/dist/src/{statusBar/statusBar.js → status-bar/status-bar.js} +5 -6
- package/dist/src/subscription/{prefixKeys.d.ts → prefix-keys.d.ts} +1 -2
- package/dist/src/subscription/prefix-keys.d.ts.map +1 -0
- package/dist/src/subscription/{prefixKeys.js → prefix-keys.js} +2 -5
- package/dist/src/table/index.d.ts.map +1 -1
- package/dist/src/table/table.d.ts +1 -1
- package/dist/src/table/table.d.ts.map +1 -1
- package/dist/src/table/table.js +19 -7
- package/dist/src/tabs/index.d.ts.map +1 -1
- package/dist/src/tabs/tabs.d.ts +4 -4
- package/dist/src/tabs/tabs.d.ts.map +1 -1
- package/dist/src/tabs/tabs.js +1 -6
- package/dist/src/tag/index.d.ts.map +1 -1
- package/dist/src/tag/tag.d.ts.map +1 -1
- package/dist/src/tag/tag.js +4 -1
- package/dist/src/text-button/index.d.ts +3 -0
- package/dist/src/text-button/index.d.ts.map +1 -0
- package/dist/src/text-button/index.js +1 -0
- package/dist/src/{textButton/textButton.d.ts → text-button/text-button.d.ts} +1 -1
- package/dist/src/text-button/text-button.d.ts.map +1 -0
- package/dist/src/{textButton/textButton.js → text-button/text-button.js} +2 -2
- package/dist/src/textarea-field/index.d.ts +3 -0
- package/dist/src/textarea-field/index.d.ts.map +1 -0
- package/dist/src/textarea-field/index.js +1 -0
- package/dist/src/{textareaField/textareaField.d.ts → textarea-field/textarea-field.d.ts} +1 -1
- package/dist/src/textarea-field/textarea-field.d.ts.map +1 -0
- package/dist/src/{textareaField/textareaField.js → textarea-field/textarea-field.js} +2 -2
- package/dist/src/time/index.d.ts.map +1 -1
- package/dist/src/time/time.d.ts.map +1 -1
- package/dist/src/time/time.js +16 -9
- package/dist/src/tips/index.d.ts.map +1 -1
- package/dist/src/tips/tips.d.ts +7 -18
- package/dist/src/tips/tips.d.ts.map +1 -1
- package/dist/src/tips/tips.js +67 -65
- package/dist/src/toast/index.d.ts.map +1 -1
- package/dist/src/toast/stack.d.ts +1 -8
- package/dist/src/toast/stack.d.ts.map +1 -1
- package/dist/src/toast/stack.js +5 -18
- package/dist/src/toast/toast.d.ts +3 -5
- package/dist/src/toast/toast.d.ts.map +1 -1
- package/dist/src/toast/toast.js +42 -39
- package/dist/src/toc/index.d.ts.map +1 -1
- package/dist/src/toc/toc.d.ts +3 -3
- package/dist/src/toc/toc.d.ts.map +1 -1
- package/dist/src/toc/toc.js +10 -7
- package/dist/src/toolbar/index.d.ts.map +1 -1
- package/dist/src/toolbar/toolbar.d.ts +1 -1
- package/dist/src/toolbar/toolbar.d.ts.map +1 -1
- package/dist/src/toolbar/toolbar.js +27 -24
- package/dist/src/{topBar/barHeight.d.ts → top-bar/bar-height.d.ts} +1 -2
- package/dist/src/top-bar/bar-height.d.ts.map +1 -0
- package/dist/src/{topBar/barHeight.js → top-bar/bar-height.js} +20 -13
- package/dist/src/top-bar/index.d.ts +4 -0
- package/dist/src/top-bar/index.d.ts.map +1 -0
- package/dist/src/top-bar/index.js +2 -0
- package/dist/src/{topBar/topBar.d.ts → top-bar/top-bar.d.ts} +3 -3
- package/dist/src/top-bar/top-bar.d.ts.map +1 -0
- package/dist/src/{topBar/topBar.js → top-bar/top-bar.js} +2 -2
- package/dist/src/video-frame/index.d.ts +3 -0
- package/dist/src/video-frame/index.d.ts.map +1 -0
- package/dist/src/video-frame/index.js +1 -0
- package/dist/src/{videoFrame/videoFrame.d.ts → video-frame/video-frame.d.ts} +1 -1
- package/dist/src/video-frame/video-frame.d.ts.map +1 -0
- package/dist/src/{videoFrame/videoFrame.js → video-frame/video-frame.js} +11 -7
- package/dist/src/wall/index.d.ts.map +1 -1
- package/dist/src/wall/wall.d.ts.map +1 -1
- package/dist/src/window/index.d.ts.map +1 -1
- package/dist/src/window/window.d.ts +2 -2
- package/dist/src/window/window.d.ts.map +1 -1
- package/dist/src/window/window.js +4 -2
- package/dist/src/wordmark/index.d.ts.map +1 -1
- package/dist/src/wordmark/wordmark.d.ts.map +1 -1
- package/dist/src/wrap/index.d.ts.map +1 -1
- package/dist/src/wrap/wrap.d.ts.map +1 -1
- package/package.json +6 -6
- package/src/adapters/diagram.ts +278 -0
- package/src/adapters/mermaid.ts +13 -273
- package/src/announcer/announcer.ts +54 -35
- package/src/attributes/attributes.ts +3 -1
- package/src/{audioFrame/audioFrame.ts → audio-frame/audio-frame.ts} +4 -6
- package/src/audio-frame/index.ts +3 -0
- package/src/banner/banner.ts +5 -4
- package/src/banner/index.ts +1 -0
- package/src/{barChart/barChart.ts → bar-chart/bar-chart.ts} +81 -43
- package/src/bar-chart/index.ts +3 -0
- package/src/bench/bench.ts +5 -4
- package/src/bench/index.ts +1 -0
- package/src/board/board.ts +338 -243
- package/src/board/index.ts +8 -1
- package/src/button/button.ts +24 -16
- package/src/button/index.ts +8 -1
- package/src/card/card.ts +23 -21
- package/src/card/index.ts +1 -0
- package/src/chart-table/chart-table.ts +87 -0
- package/src/chip/chip.ts +13 -9
- package/src/chip/index.ts +1 -0
- package/src/choice/choice.ts +13 -7
- package/src/choice/index.ts +1 -0
- package/src/choices/choices.ts +4 -3
- package/src/choices/index.ts +1 -0
- package/src/{codeEditor/codeEditor.ts → code-editor/code-editor.ts} +5 -4
- package/src/code-editor/index.ts +3 -0
- package/src/{codeSurface/codeSurface.ts → code-surface/code-surface.ts} +11 -5
- package/src/code-surface/index.ts +3 -0
- package/src/{commandPalette/commandPalette.ts → command-palette/command-palette.ts} +470 -295
- package/src/{commandPalette → command-palette}/index.ts +12 -2
- package/src/{commandPalette → command-palette}/keys.ts +44 -43
- package/src/{commandPalette → command-palette}/match.ts +42 -30
- package/src/{commandPalette → command-palette}/message.ts +13 -20
- package/src/{confirmDialog/confirmDialog.ts → confirm-dialog/confirm-dialog.ts} +51 -46
- package/src/{confirmDialog → confirm-dialog}/index.ts +3 -2
- package/src/{contextMenu/contextMenu.ts → context-menu/context-menu.ts} +71 -70
- package/src/{contextMenu → context-menu}/index.ts +4 -2
- package/src/{copyButton/copyButton.ts → copy-button/copy-button.ts} +51 -54
- package/src/{copyButton → copy-button}/index.ts +3 -2
- package/src/crumbs/crumbs.ts +7 -6
- package/src/crumbs/index.ts +1 -0
- package/src/deck/deck.ts +4 -3
- package/src/deck/index.ts +1 -0
- package/src/dialog/dialog.ts +135 -113
- package/src/dialog/fold.ts +44 -25
- package/src/dialog/index.ts +9 -1
- package/src/disclosure/disclosure.ts +14 -8
- package/src/disclosure/index.ts +1 -0
- package/src/dom/html-element.ts +10 -0
- package/src/drag/drag.ts +102 -119
- package/src/{dropZone/dropZone.ts → drop-zone/drop-zone.ts} +43 -43
- package/src/drop-zone/index.ts +11 -0
- package/src/{editableTitle/editableTitle.ts → editable-title/editable-title.ts} +29 -32
- package/src/{editableTitle → editable-title}/index.ts +4 -2
- package/src/{emptyState/emptyState.ts → empty-state/empty-state.ts} +9 -5
- package/src/empty-state/index.ts +3 -0
- package/src/{errorSummary/errorSummary.ts → error-summary/error-summary.ts} +16 -7
- package/src/error-summary/index.ts +3 -0
- package/src/field/field.ts +38 -28
- package/src/field/index.ts +1 -0
- package/src/{fieldGrid/fieldGrid.ts → field-grid/field-grid.ts} +4 -3
- package/src/field-grid/index.ts +3 -0
- package/src/fields/fields.ts +9 -5
- package/src/fields/index.ts +1 -0
- package/src/fieldset/fieldset.ts +6 -5
- package/src/fieldset/index.ts +1 -0
- package/src/{fileTree/fileTree.ts → file-tree/file-tree.ts} +241 -166
- package/src/file-tree/index.ts +12 -0
- package/src/{filterChip/filterChip.ts → filter-chip/filter-chip.ts} +32 -13
- package/src/filter-chip/index.ts +3 -0
- package/src/{filterStrip/filterStrip.ts → filter-strip/filter-strip.ts} +4 -3
- package/src/filter-strip/index.ts +3 -0
- package/src/{flashWord/flashWord.ts → flash-word/flash-word.ts} +9 -7
- package/src/flash-word/index.ts +3 -0
- package/src/focus/focus.ts +5 -5
- package/src/format/format.ts +37 -31
- package/src/format/index.ts +1 -0
- package/src/glyph/glyph.ts +7 -6
- package/src/glyph/glyphs.ts +2601 -2611
- package/src/glyph/index.ts +3 -0
- package/src/group/group.ts +4 -3
- package/src/group/index.ts +1 -0
- package/src/history/history.ts +18 -10
- package/src/history/index.ts +1 -0
- package/src/{iconButton/iconButton.ts → icon-button/icon-button.ts} +13 -7
- package/src/icon-button/index.ts +3 -0
- package/src/identity/identity.ts +7 -6
- package/src/identity/index.ts +1 -0
- package/src/{imageFrame/imageFrame.ts → image-frame/image-frame.ts} +43 -25
- package/src/image-frame/index.ts +3 -0
- package/src/index.ts +139 -41
- package/src/{inlineInput → inline-input}/index.ts +3 -2
- package/src/{inlineInput/inlineInput.ts → inline-input/inline-input.ts} +97 -88
- package/src/{keyHelp → key-help}/index.ts +3 -2
- package/src/{keyHelp/keyHelp.ts → key-help/key-help.ts} +74 -62
- package/src/key-hint/index.ts +5 -0
- package/src/{keyHint/keyHint.ts → key-hint/key-hint.ts} +10 -5
- package/src/{keyHint/keyLabel.ts → key-hint/key-label.ts} +43 -22
- package/src/keymap/index.ts +1 -0
- package/src/keymap/keymap.ts +23 -9
- package/src/keys/keys.ts +0 -2
- package/src/line-chart/index.ts +3 -0
- package/src/{lineChart/lineChart.ts → line-chart/line-chart.ts} +71 -49
- package/src/line-diff/diff.ts +196 -0
- package/src/line-diff/index.ts +7 -0
- package/src/{lineDiff/lineDiff.ts → line-diff/line-diff.ts} +45 -23
- package/src/{lineDiff → line-diff}/patch.ts +104 -76
- package/src/link-button/index.ts +3 -0
- package/src/{linkButton/linkButton.ts → link-button/link-button.ts} +7 -5
- package/src/link-state/index.ts +3 -0
- package/src/{linkState/linkState.ts → link-state/link-state.ts} +20 -9
- package/src/live-region/index.ts +3 -0
- package/src/{liveRegion/liveRegion.ts → live-region/live-region.ts} +15 -11
- package/src/loading/index.ts +1 -0
- package/src/loading/loading.ts +10 -5
- package/src/mark/index.ts +1 -0
- package/src/mark/mark.ts +17 -15
- package/src/media/index.ts +1 -0
- package/src/media/media.ts +255 -157
- package/src/menu/index.ts +4 -0
- package/src/menu/item.ts +10 -11
- package/src/menu/menu.ts +110 -97
- package/src/menu/slip.ts +129 -92
- package/src/meter/index.ts +1 -0
- package/src/meter/meter.ts +52 -33
- package/src/monogram/index.ts +1 -0
- package/src/monogram/monogram.ts +27 -19
- package/src/nav-strip/index.ts +3 -0
- package/src/{navStrip/navStrip.ts → nav-strip/nav-strip.ts} +21 -13
- package/src/notice/index.ts +1 -0
- package/src/notice/notice.ts +24 -16
- package/src/outcome/index.ts +1 -0
- package/src/outcome/outcome.ts +14 -6
- package/src/page-head/index.ts +3 -0
- package/src/{pageHead/pageHead.ts → page-head/page-head.ts} +6 -5
- package/src/panel/index.ts +1 -0
- package/src/panel/panel.ts +6 -6
- package/src/password-field/index.ts +3 -0
- package/src/{passwordField/passwordField.ts → password-field/password-field.ts} +13 -13
- package/src/pixel-paper.css +26 -508
- package/src/places/index.ts +1 -0
- package/src/places/places.ts +22 -11
- package/src/props-list/index.ts +3 -0
- package/src/{propsList/propsList.ts → props-list/props-list.ts} +6 -6
- package/src/prose/index.ts +1 -0
- package/src/prose/prose.ts +4 -4
- package/src/query-chip/index.ts +3 -0
- package/src/{queryChip/queryChip.ts → query-chip/query-chip.ts} +18 -7
- package/src/{radioChoices → radio-choices}/index.ts +3 -2
- package/src/{radioChoices/radioChoices.ts → radio-choices/radio-choices.ts} +79 -65
- package/src/rail/index.ts +1 -0
- package/src/rail/rail.ts +291 -225
- package/src/reel/index.ts +8 -1
- package/src/reel/layout.ts +393 -238
- package/src/reel/reel.ts +750 -452
- package/src/remote/index.ts +1 -0
- package/src/remote/remote.ts +18 -11
- package/src/rows/index.ts +1 -0
- package/src/rows/rows.ts +83 -47
- package/src/scheme/index.ts +3 -1
- package/src/scheme/{schemeSwitch.ts → scheme-switch.ts} +24 -35
- package/src/scheme/scheme.ts +4 -4
- package/src/secret/index.ts +1 -0
- package/src/secret/secret.ts +5 -4
- package/src/segmented/index.ts +1 -0
- package/src/segmented/segmented.ts +22 -10
- package/src/select-all/index.ts +3 -0
- package/src/{selectAll/selectAll.ts → select-all/select-all.ts} +9 -8
- package/src/{selectField → select-field}/index.ts +3 -2
- package/src/{selectField/selectField.ts → select-field/select-field.ts} +25 -11
- package/src/sheet/index.ts +1 -0
- package/src/sheet/sheet.ts +9 -5
- package/src/skip-link/index.ts +1 -0
- package/src/{skipLink/skipLink.ts → skip-link/skip-link.ts} +9 -15
- package/src/slot/slot.ts +5 -6
- package/src/sortable/index.ts +1 -0
- package/src/sortable/sortable.ts +287 -206
- package/src/stack/index.ts +1 -0
- package/src/stack/stack.ts +6 -7
- package/src/stage/index.ts +1 -0
- package/src/stage/stage.ts +12 -8
- package/src/stat/index.ts +1 -0
- package/src/stat/stat.ts +39 -20
- package/src/status-bar/index.ts +5 -0
- package/src/{statusBar/statusBar.ts → status-bar/status-bar.ts} +18 -11
- package/src/subscription/{prefixKeys.ts → prefix-keys.ts} +5 -6
- package/src/table/index.ts +1 -0
- package/src/table/table.ts +49 -24
- package/src/tabs/index.ts +1 -0
- package/src/tabs/tabs.ts +58 -60
- package/src/tag/index.ts +1 -0
- package/src/tag/tag.ts +14 -7
- package/src/text-button/index.ts +3 -0
- package/src/{textButton/textButton.ts → text-button/text-button.ts} +7 -5
- package/src/textarea-field/index.ts +3 -0
- package/src/{textareaField/textareaField.ts → textarea-field/textarea-field.ts} +15 -7
- package/src/time/index.ts +1 -0
- package/src/time/time.ts +58 -25
- package/src/tips/index.ts +1 -0
- package/src/tips/tips.ts +183 -127
- package/src/toast/index.ts +3 -0
- package/src/toast/stack.ts +22 -23
- package/src/toast/toast.ts +168 -100
- package/src/toc/index.ts +1 -0
- package/src/toc/toc.ts +42 -27
- package/src/tokens.css +7 -24
- package/src/toolbar/index.ts +1 -0
- package/src/toolbar/toolbar.ts +78 -40
- package/src/{topBar/barHeight.ts → top-bar/bar-height.ts} +26 -12
- package/src/top-bar/index.ts +5 -0
- package/src/{topBar/topBar.ts → top-bar/top-bar.ts} +13 -7
- package/src/video-frame/index.ts +3 -0
- package/src/{videoFrame/videoFrame.ts → video-frame/video-frame.ts} +31 -18
- package/src/wall/index.ts +1 -0
- package/src/wall/wall.ts +13 -10
- package/src/window/index.ts +1 -0
- package/src/window/window.ts +15 -9
- package/src/wordmark/index.ts +1 -0
- package/src/wordmark/wordmark.ts +4 -3
- package/src/wrap/index.ts +1 -0
- package/src/wrap/wrap.ts +4 -3
- package/dist/src/audioFrame/audioFrame.d.ts.map +0 -1
- package/dist/src/audioFrame/index.d.ts +0 -3
- package/dist/src/audioFrame/index.d.ts.map +0 -1
- package/dist/src/audioFrame/index.js +0 -1
- package/dist/src/barChart/barChart.d.ts.map +0 -1
- package/dist/src/barChart/index.d.ts +0 -3
- package/dist/src/barChart/index.d.ts.map +0 -1
- package/dist/src/barChart/index.js +0 -1
- package/dist/src/chartTable/chartTable.d.ts.map +0 -1
- package/dist/src/codeEditor/codeEditor.d.ts.map +0 -1
- package/dist/src/codeEditor/index.d.ts +0 -3
- package/dist/src/codeEditor/index.d.ts.map +0 -1
- package/dist/src/codeEditor/index.js +0 -1
- package/dist/src/codeSurface/codeSurface.d.ts.map +0 -1
- package/dist/src/codeSurface/index.d.ts +0 -3
- package/dist/src/codeSurface/index.d.ts.map +0 -1
- package/dist/src/codeSurface/index.js +0 -1
- package/dist/src/commandPalette/commandPalette.d.ts.map +0 -1
- package/dist/src/commandPalette/commandPalette.js +0 -611
- package/dist/src/commandPalette/index.d.ts.map +0 -1
- package/dist/src/commandPalette/keys.d.ts.map +0 -1
- package/dist/src/commandPalette/keys.js +0 -102
- package/dist/src/commandPalette/match.d.ts.map +0 -1
- package/dist/src/commandPalette/message.d.ts.map +0 -1
- package/dist/src/confirmDialog/confirmDialog.d.ts.map +0 -1
- package/dist/src/confirmDialog/index.d.ts +0 -3
- package/dist/src/confirmDialog/index.d.ts.map +0 -1
- package/dist/src/contextMenu/contextMenu.d.ts.map +0 -1
- package/dist/src/contextMenu/index.d.ts.map +0 -1
- package/dist/src/copyButton/copyButton.d.ts.map +0 -1
- package/dist/src/copyButton/index.d.ts +0 -3
- package/dist/src/copyButton/index.d.ts.map +0 -1
- package/dist/src/copyButton/index.js +0 -1
- package/dist/src/dropZone/dropZone.d.ts.map +0 -1
- package/dist/src/dropZone/index.d.ts +0 -3
- package/dist/src/dropZone/index.d.ts.map +0 -1
- package/dist/src/dropZone/index.js +0 -1
- package/dist/src/editableTitle/editableTitle.d.ts.map +0 -1
- package/dist/src/editableTitle/index.d.ts +0 -4
- package/dist/src/editableTitle/index.d.ts.map +0 -1
- package/dist/src/emptyState/emptyState.d.ts.map +0 -1
- package/dist/src/emptyState/index.d.ts +0 -3
- package/dist/src/emptyState/index.d.ts.map +0 -1
- package/dist/src/emptyState/index.js +0 -1
- package/dist/src/errorSummary/errorSummary.d.ts.map +0 -1
- package/dist/src/errorSummary/index.d.ts +0 -3
- package/dist/src/errorSummary/index.d.ts.map +0 -1
- package/dist/src/errorSummary/index.js +0 -1
- package/dist/src/fieldGrid/fieldGrid.d.ts.map +0 -1
- package/dist/src/fieldGrid/index.d.ts +0 -3
- package/dist/src/fieldGrid/index.d.ts.map +0 -1
- package/dist/src/fieldGrid/index.js +0 -1
- package/dist/src/fileTree/fileTree.d.ts.map +0 -1
- package/dist/src/fileTree/fileTree.js +0 -230
- package/dist/src/fileTree/index.d.ts +0 -3
- package/dist/src/fileTree/index.d.ts.map +0 -1
- package/dist/src/filterChip/filterChip.d.ts.map +0 -1
- package/dist/src/filterChip/index.d.ts +0 -3
- package/dist/src/filterChip/index.d.ts.map +0 -1
- package/dist/src/filterChip/index.js +0 -1
- package/dist/src/filterStrip/filterStrip.d.ts.map +0 -1
- package/dist/src/filterStrip/index.d.ts +0 -3
- package/dist/src/filterStrip/index.d.ts.map +0 -1
- package/dist/src/filterStrip/index.js +0 -1
- package/dist/src/flashWord/flashWord.d.ts.map +0 -1
- package/dist/src/flashWord/index.d.ts +0 -3
- package/dist/src/flashWord/index.d.ts.map +0 -1
- package/dist/src/flashWord/index.js +0 -1
- package/dist/src/iconButton/iconButton.d.ts.map +0 -1
- package/dist/src/iconButton/index.d.ts +0 -3
- package/dist/src/iconButton/index.d.ts.map +0 -1
- package/dist/src/iconButton/index.js +0 -1
- package/dist/src/imageFrame/imageFrame.d.ts.map +0 -1
- package/dist/src/imageFrame/index.d.ts +0 -3
- package/dist/src/imageFrame/index.d.ts.map +0 -1
- package/dist/src/imageFrame/index.js +0 -1
- package/dist/src/inlineInput/index.d.ts +0 -3
- package/dist/src/inlineInput/index.d.ts.map +0 -1
- package/dist/src/inlineInput/inlineInput.d.ts.map +0 -1
- package/dist/src/keyHelp/index.d.ts +0 -3
- package/dist/src/keyHelp/index.d.ts.map +0 -1
- package/dist/src/keyHelp/keyHelp.d.ts.map +0 -1
- package/dist/src/keyHint/index.d.ts +0 -4
- package/dist/src/keyHint/index.d.ts.map +0 -1
- package/dist/src/keyHint/index.js +0 -2
- package/dist/src/keyHint/keyHint.d.ts.map +0 -1
- package/dist/src/keyHint/keyLabel.d.ts.map +0 -1
- package/dist/src/lineChart/index.d.ts +0 -3
- package/dist/src/lineChart/index.d.ts.map +0 -1
- package/dist/src/lineChart/index.js +0 -1
- package/dist/src/lineChart/lineChart.d.ts.map +0 -1
- package/dist/src/lineDiff/diff.d.ts +0 -41
- package/dist/src/lineDiff/diff.d.ts.map +0 -1
- package/dist/src/lineDiff/diff.js +0 -92
- package/dist/src/lineDiff/index.d.ts +0 -5
- package/dist/src/lineDiff/index.d.ts.map +0 -1
- package/dist/src/lineDiff/index.js +0 -2
- package/dist/src/lineDiff/lineDiff.d.ts.map +0 -1
- package/dist/src/lineDiff/patch.d.ts.map +0 -1
- package/dist/src/linkButton/index.d.ts +0 -3
- package/dist/src/linkButton/index.d.ts.map +0 -1
- package/dist/src/linkButton/index.js +0 -1
- package/dist/src/linkButton/linkButton.d.ts.map +0 -1
- package/dist/src/linkState/index.d.ts +0 -3
- package/dist/src/linkState/index.d.ts.map +0 -1
- package/dist/src/linkState/index.js +0 -1
- package/dist/src/linkState/linkState.d.ts.map +0 -1
- package/dist/src/linkState/linkState.js +0 -14
- package/dist/src/liveRegion/index.d.ts +0 -3
- package/dist/src/liveRegion/index.d.ts.map +0 -1
- package/dist/src/liveRegion/index.js +0 -1
- package/dist/src/liveRegion/liveRegion.d.ts.map +0 -1
- package/dist/src/navStrip/index.d.ts +0 -3
- package/dist/src/navStrip/index.d.ts.map +0 -1
- package/dist/src/navStrip/index.js +0 -1
- package/dist/src/navStrip/navStrip.d.ts.map +0 -1
- package/dist/src/navStrip/navStrip.js +0 -27
- package/dist/src/pageHead/index.d.ts +0 -3
- package/dist/src/pageHead/index.d.ts.map +0 -1
- package/dist/src/pageHead/index.js +0 -1
- package/dist/src/pageHead/pageHead.d.ts.map +0 -1
- package/dist/src/passwordField/index.d.ts +0 -3
- package/dist/src/passwordField/index.d.ts.map +0 -1
- package/dist/src/passwordField/index.js +0 -1
- package/dist/src/passwordField/passwordField.d.ts.map +0 -1
- package/dist/src/propsList/index.d.ts +0 -3
- package/dist/src/propsList/index.d.ts.map +0 -1
- package/dist/src/propsList/index.js +0 -1
- package/dist/src/propsList/propsList.d.ts.map +0 -1
- package/dist/src/queryChip/index.d.ts +0 -3
- package/dist/src/queryChip/index.d.ts.map +0 -1
- package/dist/src/queryChip/index.js +0 -1
- package/dist/src/queryChip/queryChip.d.ts.map +0 -1
- package/dist/src/radioChoices/index.d.ts.map +0 -1
- package/dist/src/radioChoices/radioChoices.d.ts.map +0 -1
- package/dist/src/scheme/schemeSwitch.d.ts.map +0 -1
- package/dist/src/selectAll/index.d.ts +0 -3
- package/dist/src/selectAll/index.d.ts.map +0 -1
- package/dist/src/selectAll/index.js +0 -1
- package/dist/src/selectAll/selectAll.d.ts.map +0 -1
- package/dist/src/selectField/index.d.ts +0 -3
- package/dist/src/selectField/index.d.ts.map +0 -1
- package/dist/src/selectField/index.js +0 -1
- package/dist/src/selectField/selectField.d.ts.map +0 -1
- package/dist/src/skipLink/index.d.ts +0 -2
- package/dist/src/skipLink/index.d.ts.map +0 -1
- package/dist/src/skipLink/index.js +0 -1
- package/dist/src/skipLink/skipLink.d.ts.map +0 -1
- package/dist/src/statusBar/index.d.ts +0 -4
- package/dist/src/statusBar/index.d.ts.map +0 -1
- package/dist/src/statusBar/index.js +0 -2
- package/dist/src/statusBar/statusBar.d.ts.map +0 -1
- package/dist/src/subscription/prefixKeys.d.ts.map +0 -1
- package/dist/src/textButton/index.d.ts +0 -3
- package/dist/src/textButton/index.d.ts.map +0 -1
- package/dist/src/textButton/index.js +0 -1
- package/dist/src/textButton/textButton.d.ts.map +0 -1
- package/dist/src/textareaField/index.d.ts +0 -3
- package/dist/src/textareaField/index.d.ts.map +0 -1
- package/dist/src/textareaField/index.js +0 -1
- package/dist/src/textareaField/textareaField.d.ts.map +0 -1
- package/dist/src/topBar/barHeight.d.ts.map +0 -1
- package/dist/src/topBar/index.d.ts +0 -4
- package/dist/src/topBar/index.d.ts.map +0 -1
- package/dist/src/topBar/index.js +0 -2
- package/dist/src/topBar/topBar.d.ts.map +0 -1
- package/dist/src/videoFrame/index.d.ts +0 -3
- package/dist/src/videoFrame/index.d.ts.map +0 -1
- package/dist/src/videoFrame/index.js +0 -1
- package/dist/src/videoFrame/videoFrame.d.ts.map +0 -1
- package/src/audioFrame/index.ts +0 -2
- package/src/barChart/index.ts +0 -2
- package/src/chartTable/chartTable.ts +0 -88
- package/src/codeEditor/index.ts +0 -2
- package/src/codeSurface/index.ts +0 -2
- package/src/dropZone/index.ts +0 -2
- package/src/emptyState/index.ts +0 -2
- package/src/errorSummary/index.ts +0 -2
- package/src/fieldGrid/index.ts +0 -2
- package/src/fileTree/index.ts +0 -2
- package/src/filterChip/index.ts +0 -2
- package/src/filterStrip/index.ts +0 -2
- package/src/flashWord/index.ts +0 -2
- package/src/iconButton/index.ts +0 -2
- package/src/imageFrame/index.ts +0 -2
- package/src/keyHint/index.ts +0 -3
- package/src/lineChart/index.ts +0 -2
- package/src/lineDiff/diff.ts +0 -182
- package/src/lineDiff/index.ts +0 -4
- package/src/linkButton/index.ts +0 -2
- package/src/linkState/index.ts +0 -2
- package/src/liveRegion/index.ts +0 -2
- package/src/navStrip/index.ts +0 -2
- package/src/pageHead/index.ts +0 -2
- package/src/passwordField/index.ts +0 -2
- package/src/propsList/index.ts +0 -2
- package/src/queryChip/index.ts +0 -2
- package/src/selectAll/index.ts +0 -2
- package/src/skipLink/index.ts +0 -1
- package/src/statusBar/index.ts +0 -3
- package/src/textButton/index.ts +0 -2
- package/src/textareaField/index.ts +0 -2
- package/src/topBar/index.ts +0 -3
- package/src/videoFrame/index.ts +0 -2
package/src/reel/reel.ts
CHANGED
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
Option,
|
|
8
8
|
Order,
|
|
9
9
|
Queue,
|
|
10
|
+
Record,
|
|
10
11
|
Schema,
|
|
11
12
|
Stream,
|
|
12
13
|
String,
|
|
@@ -24,6 +25,7 @@ import type * as Update from "foldkit/update";
|
|
|
24
25
|
|
|
25
26
|
import * as Announcer from "../announcer/announcer.ts";
|
|
26
27
|
import * as Button from "../button/button.ts";
|
|
28
|
+
import { htmlElement } from "../dom/html-element.ts";
|
|
27
29
|
import {
|
|
28
30
|
LEFT_BUTTON,
|
|
29
31
|
escapeKeys,
|
|
@@ -33,17 +35,11 @@ import {
|
|
|
33
35
|
splitterAttributes,
|
|
34
36
|
} from "../drag/drag.ts";
|
|
35
37
|
import * as Glyph from "../glyph/glyph.ts";
|
|
36
|
-
import * as IconButton from "../
|
|
38
|
+
import * as IconButton from "../icon-button/icon-button.ts";
|
|
37
39
|
import { isPlain } from "../keys/keys.ts";
|
|
38
|
-
import { prefixKeys } from "../subscription/
|
|
39
|
-
|
|
40
|
+
import { prefixKeys } from "../subscription/prefix-keys.ts";
|
|
40
41
|
import {
|
|
41
|
-
type Column,
|
|
42
|
-
type ColumnBox,
|
|
43
|
-
type Layout,
|
|
44
42
|
OutMessage,
|
|
45
|
-
type Pane,
|
|
46
|
-
type Place,
|
|
47
43
|
Resize,
|
|
48
44
|
Splitter,
|
|
49
45
|
Step,
|
|
@@ -71,15 +67,11 @@ import {
|
|
|
71
67
|
whereWords,
|
|
72
68
|
widthWords,
|
|
73
69
|
} from "./layout.ts";
|
|
70
|
+
import type { Column, ColumnBox, Layout, Pane, Place } from "./layout.ts";
|
|
74
71
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
/** How the keyboard carries what it holds: said on the grip and once it is picked up. */
|
|
78
|
-
const KEYBOARD_MOVES = "Arrow keys move it, space drops it, escape or tab puts it back.";
|
|
72
|
+
const KEYBOARD_MOVES =
|
|
73
|
+
"Arrow keys move it, space drops it, escape or tab puts it back.";
|
|
79
74
|
|
|
80
|
-
/** The words a reel says. `{pane}` is a pane's label, `{subject}` what moves (the held pane,
|
|
81
|
-
* or a column a key moves, by its first pane), `{where}` a place and `{column}` a column's
|
|
82
|
-
* number. */
|
|
83
75
|
const COPY = {
|
|
84
76
|
paneGrip: "Move {pane}",
|
|
85
77
|
gripHelp: `Press space to pick it up. ${KEYBOARD_MOVES}`,
|
|
@@ -98,40 +90,42 @@ const COPY = {
|
|
|
98
90
|
gone: "Move cancelled.",
|
|
99
91
|
};
|
|
100
92
|
|
|
101
|
-
|
|
102
|
-
|
|
93
|
+
const Focus = Schema.Struct({
|
|
94
|
+
paneId: Schema.String,
|
|
95
|
+
column: Schema.Finite,
|
|
96
|
+
row: Schema.Finite,
|
|
97
|
+
});
|
|
103
98
|
|
|
104
|
-
/** How something is held: by a pointer, pressed at (`pressX`, `pressY`) and now at (`x`,
|
|
105
|
-
* `y`), carrying it once it has moved past the threshold; or by the keyboard, on its grip. */
|
|
106
99
|
const By = defineTaggedUnion({
|
|
107
100
|
Pointer: {
|
|
108
|
-
pointerId: Schema.
|
|
109
|
-
pressX: Schema.
|
|
110
|
-
pressY: Schema.
|
|
111
|
-
x: Schema.
|
|
112
|
-
y: Schema.
|
|
101
|
+
pointerId: Schema.Finite,
|
|
102
|
+
pressX: Schema.Finite,
|
|
103
|
+
pressY: Schema.Finite,
|
|
104
|
+
x: Schema.Finite,
|
|
105
|
+
y: Schema.Finite,
|
|
113
106
|
isCarrying: Schema.Boolean,
|
|
114
107
|
},
|
|
115
108
|
Keyboard: {},
|
|
116
109
|
});
|
|
110
|
+
|
|
117
111
|
type By = typeof By.Type;
|
|
118
112
|
|
|
119
|
-
/** The pane held, how, and where it would land: none while a pointer is outside the reel. */
|
|
120
113
|
const Held = Schema.Struct({
|
|
121
114
|
paneId: Schema.String,
|
|
122
115
|
by: By,
|
|
123
116
|
maybeTarget: Schema.Option(Target),
|
|
124
117
|
});
|
|
118
|
+
|
|
125
119
|
type Held = typeof Held.Type;
|
|
126
120
|
|
|
127
|
-
/** A splitter a pointer drags, pressed at (`pressX`, `pressY`), with the resize it previews. */
|
|
128
121
|
const Resizing = Schema.Struct({
|
|
129
122
|
splitter: Splitter,
|
|
130
|
-
pointerId: Schema.
|
|
131
|
-
pressX: Schema.
|
|
132
|
-
pressY: Schema.
|
|
123
|
+
pointerId: Schema.Finite,
|
|
124
|
+
pressX: Schema.Finite,
|
|
125
|
+
pressY: Schema.Finite,
|
|
133
126
|
maybeResize: Schema.Option(Resize),
|
|
134
127
|
});
|
|
128
|
+
|
|
135
129
|
type Resizing = typeof Resizing.Type;
|
|
136
130
|
|
|
137
131
|
/** Schema for a reel: its id, the focused pane, what is held and a splitter being dragged. All
|
|
@@ -142,30 +136,31 @@ export const Model = Schema.Struct({
|
|
|
142
136
|
maybeHeld: Schema.Option(Held),
|
|
143
137
|
maybeResizing: Schema.Option(Resizing),
|
|
144
138
|
});
|
|
139
|
+
|
|
145
140
|
export type Model = typeof Model.Type;
|
|
146
141
|
|
|
147
142
|
/** How a reel shows its panes: side by side in their columns (`Strip`), or one at a time at
|
|
148
143
|
* the reel's full size under a tab per pane (`Tabs`). The application holds it and passes it
|
|
149
144
|
* in; the layout is the same in both. */
|
|
150
145
|
export const Arrangement = Schema.Literals(["Strip", "Tabs"]);
|
|
151
|
-
export type Arrangement = typeof Arrangement.Type;
|
|
152
146
|
|
|
153
|
-
|
|
147
|
+
export type Arrangement = typeof Arrangement.Type;
|
|
154
148
|
|
|
155
149
|
const PointerAt = Schema.Struct({
|
|
156
|
-
clientX: Schema.
|
|
157
|
-
clientY: Schema.
|
|
150
|
+
clientX: Schema.Finite,
|
|
151
|
+
clientY: Schema.Finite,
|
|
158
152
|
maybeTarget: Schema.Option(Target),
|
|
159
153
|
});
|
|
154
|
+
|
|
160
155
|
type PointerAt = typeof PointerAt.Type;
|
|
161
156
|
|
|
162
157
|
/** Union of all Messages a reel can produce. */
|
|
163
158
|
export const Message = defineMessageUnion({
|
|
164
159
|
PressedGrip: {
|
|
165
160
|
paneId: Schema.String,
|
|
166
|
-
pointerId: Schema.
|
|
167
|
-
clientX: Schema.
|
|
168
|
-
clientY: Schema.
|
|
161
|
+
pointerId: Schema.Finite,
|
|
162
|
+
clientX: Schema.Finite,
|
|
163
|
+
clientY: Schema.Finite,
|
|
169
164
|
},
|
|
170
165
|
PressedGripKey: { paneId: Schema.String },
|
|
171
166
|
MovedPointer: PointerAt.fields,
|
|
@@ -180,14 +175,14 @@ export const Message = defineMessageUnion({
|
|
|
180
175
|
SteppedTab: { paneId: Schema.String },
|
|
181
176
|
PressedSplitter: {
|
|
182
177
|
splitter: Splitter,
|
|
183
|
-
pointerId: Schema.
|
|
184
|
-
clientX: Schema.
|
|
185
|
-
clientY: Schema.
|
|
178
|
+
pointerId: Schema.Finite,
|
|
179
|
+
clientX: Schema.Finite,
|
|
180
|
+
clientY: Schema.Finite,
|
|
186
181
|
},
|
|
187
|
-
MovedSplitter: { share: Schema.
|
|
188
|
-
ReleasedSplitter: { share: Schema.
|
|
182
|
+
MovedSplitter: { share: Schema.Finite },
|
|
183
|
+
ReleasedSplitter: { share: Schema.Finite },
|
|
189
184
|
CancelledSplitter: {},
|
|
190
|
-
PressedSplitterKey: { splitter: Splitter, share: Schema.
|
|
185
|
+
PressedSplitterKey: { splitter: Splitter, share: Schema.Finite },
|
|
191
186
|
CompletedAnnounceReel: {},
|
|
192
187
|
CompletedFocusPane: {},
|
|
193
188
|
CompletedFocusTab: {},
|
|
@@ -195,9 +190,8 @@ export const Message = defineMessageUnion({
|
|
|
195
190
|
CompletedScrollIntoView: {},
|
|
196
191
|
CompletedSizeLiftedPane: {},
|
|
197
192
|
});
|
|
198
|
-
export type Message = typeof Message.Type;
|
|
199
193
|
|
|
200
|
-
|
|
194
|
+
export type Message = typeof Message.Type;
|
|
201
195
|
|
|
202
196
|
/** Configuration for creating a reel with `init`. The `id` must be unique in the document;
|
|
203
197
|
* the reel's DOM hooks are scoped by it. */
|
|
@@ -211,72 +205,77 @@ export const init = (config: InitConfig): Model => ({
|
|
|
211
205
|
maybeResizing: Option.none(),
|
|
212
206
|
});
|
|
213
207
|
|
|
214
|
-
// ACCESSORS
|
|
215
|
-
|
|
216
208
|
const focusedPlace = (model: Model, layout: Layout): Option.Option<Place> =>
|
|
217
209
|
Option.orElse(
|
|
218
210
|
Option.flatMap(model.maybeFocus, (focus) =>
|
|
219
211
|
Option.orElse(placeOf(layout, focus.paneId), () => {
|
|
220
|
-
const column = Number.clamp(focus.column, {
|
|
212
|
+
const column = Number.clamp(focus.column, {
|
|
213
|
+
minimum: 0,
|
|
214
|
+
maximum: layout.length - 1,
|
|
215
|
+
});
|
|
216
|
+
|
|
221
217
|
const rows = Option.match(Array.get(layout, column), {
|
|
222
218
|
onNone: () => 0,
|
|
223
219
|
onSome: (found) => found.panes.length,
|
|
224
220
|
});
|
|
225
|
-
|
|
226
|
-
|
|
221
|
+
|
|
222
|
+
return placeAt(
|
|
223
|
+
layout,
|
|
224
|
+
column,
|
|
225
|
+
Number.clamp(focus.row, { minimum: 0, maximum: rows - 1 })
|
|
226
|
+
);
|
|
227
|
+
})
|
|
227
228
|
),
|
|
228
|
-
() => firstPlace(layout)
|
|
229
|
+
() => firstPlace(layout)
|
|
229
230
|
);
|
|
230
231
|
|
|
231
232
|
/** The pane focus is on: the one last focused, or, when it has gone from `layout`, the pane
|
|
232
233
|
* now nearest its place; the first pane before any is focused. None for an empty layout. */
|
|
233
|
-
export const focusedPaneId = (
|
|
234
|
+
export const focusedPaneId = (
|
|
235
|
+
model: Model,
|
|
236
|
+
layout: Layout
|
|
237
|
+
): Option.Option<string> =>
|
|
234
238
|
Option.map(focusedPlace(model, layout), ({ pane }) => pane.id);
|
|
235
239
|
|
|
236
240
|
const isHolding = (model: Model): boolean => Option.isSome(model.maybeHeld);
|
|
237
241
|
|
|
238
|
-
|
|
239
|
-
|
|
242
|
+
const isIdle = (model: Model): boolean =>
|
|
243
|
+
!isHolding(model) && Option.isNone(model.maybeResizing);
|
|
240
244
|
|
|
241
|
-
/** Whether `held` is carried: by the keyboard, or by a pointer past the threshold. */
|
|
242
245
|
const isCarried = (held: Held): boolean =>
|
|
243
|
-
By.match(held.by, {
|
|
244
|
-
|
|
245
|
-
|
|
246
|
+
By.match(held.by, {
|
|
247
|
+
Pointer: ({ isCarrying }) => isCarrying,
|
|
248
|
+
Keyboard: () => true,
|
|
249
|
+
});
|
|
246
250
|
|
|
247
|
-
const paneHook = (model: Model, paneId: string): string =>
|
|
251
|
+
const paneHook = (model: Model, paneId: string): string =>
|
|
252
|
+
`${model.id}/pane/${paneId}`;
|
|
248
253
|
|
|
249
|
-
const columnHook = (model: Model, columnId: string): string =>
|
|
254
|
+
const columnHook = (model: Model, columnId: string): string =>
|
|
255
|
+
`${model.id}/column/${columnId}`;
|
|
250
256
|
|
|
251
|
-
const tabHook = (model: Model, paneId: string): string =>
|
|
257
|
+
const tabHook = (model: Model, paneId: string): string =>
|
|
258
|
+
`${model.id}/tab/${paneId}`;
|
|
252
259
|
|
|
253
260
|
const scrollerOf = (reelHook: string): Option.Option<HTMLElement> =>
|
|
254
|
-
|
|
255
|
-
document.querySelector<HTMLElement>(`[data-reel="${CSS.escape(reelHook)}"] > .reel-view`),
|
|
256
|
-
);
|
|
261
|
+
htmlElement(`[data-reel="${CSS.escape(reelHook)}"] > .reel-view`);
|
|
257
262
|
|
|
258
263
|
const paneElement = (hook: string): Option.Option<HTMLElement> =>
|
|
259
|
-
|
|
260
|
-
document.querySelector<HTMLElement>(`[data-reel-pane="${CSS.escape(hook)}"]`),
|
|
261
|
-
);
|
|
264
|
+
htmlElement(`[data-reel-pane="${CSS.escape(hook)}"]`);
|
|
262
265
|
|
|
263
|
-
/** Puts the keyboard in `pane`: on its control marked `data-reel-focus` (a terminal's input),
|
|
264
|
-
* or on the pane itself, without scrolling the page. */
|
|
265
266
|
const focusInto = (pane: HTMLElement): void => {
|
|
266
|
-
Option.getOrElse(
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
).focus({ preventScroll: true });
|
|
267
|
+
Option.getOrElse(htmlElement("[data-reel-focus]", pane), () => pane).focus({
|
|
268
|
+
preventScroll: true,
|
|
269
|
+
});
|
|
270
270
|
};
|
|
271
271
|
|
|
272
|
-
// COMMAND
|
|
273
|
-
|
|
274
272
|
/** Says a focus move, a move or a step of a drag through the page's live region (as
|
|
275
273
|
* `Announcer.Announce` does). */
|
|
276
274
|
export const AnnounceReel = Command.define("AnnounceReel", {
|
|
277
275
|
args: { text: Schema.String },
|
|
278
276
|
messages: [Message.CompletedAnnounceReel],
|
|
279
|
-
execute: ({ text }) =>
|
|
277
|
+
execute: ({ text }) =>
|
|
278
|
+
Announcer.announce(text).pipe(Effect.as(Message.CompletedAnnounceReel())),
|
|
280
279
|
});
|
|
281
280
|
|
|
282
281
|
/** Focuses the pane `paneHook` names, unless focus is already inside it: the control in it
|
|
@@ -290,10 +289,14 @@ export const FocusPane = Command.define("FocusPane", {
|
|
|
290
289
|
yield* Render.afterCommit;
|
|
291
290
|
yield* Effect.sync(() => {
|
|
292
291
|
Option.map(
|
|
293
|
-
Option.filter(
|
|
294
|
-
|
|
292
|
+
Option.filter(
|
|
293
|
+
paneElement(hook),
|
|
294
|
+
(pane) => !pane.contains(document.activeElement)
|
|
295
|
+
),
|
|
296
|
+
focusInto
|
|
295
297
|
);
|
|
296
298
|
});
|
|
299
|
+
|
|
297
300
|
return Message.CompletedFocusPane();
|
|
298
301
|
}),
|
|
299
302
|
});
|
|
@@ -307,8 +310,14 @@ export const FocusTab = Command.define("FocusTab", {
|
|
|
307
310
|
Effect.gen(function* () {
|
|
308
311
|
yield* Render.afterCommit;
|
|
309
312
|
yield* Effect.sync(() => {
|
|
310
|
-
|
|
313
|
+
Option.map(
|
|
314
|
+
htmlElement(`[data-reel-tab="${CSS.escape(hook)}"]`),
|
|
315
|
+
(tab) => {
|
|
316
|
+
tab.focus();
|
|
317
|
+
}
|
|
318
|
+
);
|
|
311
319
|
});
|
|
320
|
+
|
|
312
321
|
return Message.CompletedFocusTab();
|
|
313
322
|
}),
|
|
314
323
|
});
|
|
@@ -323,10 +332,12 @@ export const RestoreFocus = Command.define("RestoreFocus", {
|
|
|
323
332
|
yield* Render.afterCommit;
|
|
324
333
|
yield* Effect.sync(() => {
|
|
325
334
|
const active = document.activeElement;
|
|
335
|
+
|
|
326
336
|
if (active === null || active === document.body) {
|
|
327
337
|
Option.map(paneElement(hook), focusInto);
|
|
328
338
|
}
|
|
329
339
|
});
|
|
340
|
+
|
|
330
341
|
return Message.CompletedRestoreFocus();
|
|
331
342
|
}),
|
|
332
343
|
});
|
|
@@ -343,42 +354,52 @@ export const ScrollIntoView = Command.define("ScrollIntoView", {
|
|
|
343
354
|
yield* Effect.sync(() => {
|
|
344
355
|
document
|
|
345
356
|
.querySelector(
|
|
346
|
-
`[data-reel-pane="${CSS.escape(hook)}"], [data-reel-hook="${CSS.escape(hook)}"]
|
|
357
|
+
`[data-reel-pane="${CSS.escape(hook)}"], [data-reel-hook="${CSS.escape(hook)}"]`
|
|
347
358
|
)
|
|
348
359
|
?.scrollIntoView({ block: "nearest", inline: "nearest" });
|
|
349
360
|
});
|
|
361
|
+
|
|
350
362
|
return Message.CompletedScrollIntoView();
|
|
351
363
|
}),
|
|
352
364
|
});
|
|
353
365
|
|
|
354
|
-
// UPDATE
|
|
355
|
-
|
|
356
366
|
/** What the reel reads from its parent as each Message arrives: the layout as the
|
|
357
367
|
* application holds it now, and how the view shows it (`Strip` when not given), which
|
|
358
368
|
* `perform` reads. */
|
|
359
|
-
export type UpdateContext = Readonly<{
|
|
369
|
+
export type UpdateContext = Readonly<{
|
|
370
|
+
layout: Layout;
|
|
371
|
+
arrangement?: Arrangement;
|
|
372
|
+
}>;
|
|
360
373
|
|
|
361
374
|
type UpdateReturn = Update.ReturnWithOutMessage<Model, Message, OutMessage>;
|
|
362
375
|
|
|
363
|
-
/** How far a pointer moves from its press before it carries what it pressed. */
|
|
364
376
|
const CARRY_THRESHOLD = 5;
|
|
365
377
|
|
|
366
378
|
const withHeld = (model: Model, maybeHeld: Option.Option<Held>): Model =>
|
|
367
379
|
modifyFields(model, { maybeHeld: () => maybeHeld });
|
|
368
380
|
|
|
369
|
-
const withResizing = (
|
|
370
|
-
|
|
381
|
+
const withResizing = (
|
|
382
|
+
model: Model,
|
|
383
|
+
maybeResizing: Option.Option<Resizing>
|
|
384
|
+
): Model => modifyFields(model, { maybeResizing: () => maybeResizing });
|
|
371
385
|
|
|
372
386
|
const focusOn = (model: Model, place: Place): Model =>
|
|
373
387
|
modifyFields(model, {
|
|
374
388
|
maybeFocus: () =>
|
|
375
|
-
Option.some({
|
|
389
|
+
Option.some({
|
|
390
|
+
paneId: place.pane.id,
|
|
391
|
+
column: place.columnIndex,
|
|
392
|
+
row: place.row,
|
|
393
|
+
}),
|
|
376
394
|
});
|
|
377
395
|
|
|
378
396
|
const announce = (text: string) => AnnounceReel({ text });
|
|
379
397
|
|
|
380
398
|
const heldLabel = (layout: Layout, held: Held): string =>
|
|
381
|
-
Option.getOrElse(
|
|
399
|
+
Option.getOrElse(
|
|
400
|
+
subjectWords(layout, Subject.Pane({ paneId: held.paneId })),
|
|
401
|
+
() => ""
|
|
402
|
+
);
|
|
382
403
|
|
|
383
404
|
const heldWords = (layout: Layout, held: Held): string =>
|
|
384
405
|
String.capitalize(heldLabel(layout, held));
|
|
@@ -386,21 +407,26 @@ const heldWords = (layout: Layout, held: Held): string =>
|
|
|
386
407
|
const scrollToTarget = (model: Model, layout: Layout, target: Target) =>
|
|
387
408
|
Array.fromOption(
|
|
388
409
|
Option.map(columnOfTarget(layout, target), (columnId) =>
|
|
389
|
-
ScrollIntoView({ hook: columnHook(model, columnId) })
|
|
390
|
-
)
|
|
410
|
+
ScrollIntoView({ hook: columnHook(model, columnId) })
|
|
411
|
+
)
|
|
391
412
|
);
|
|
392
413
|
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
414
|
+
const letGo = (
|
|
415
|
+
model: Model,
|
|
416
|
+
layout: Layout,
|
|
417
|
+
held: Held,
|
|
418
|
+
putBack: string
|
|
419
|
+
): UpdateReturn => {
|
|
396
420
|
const released = withHeld(model, Option.none());
|
|
421
|
+
|
|
397
422
|
if (!isCarried(held)) {
|
|
398
423
|
return { model: released };
|
|
399
424
|
}
|
|
400
425
|
|
|
401
426
|
const subject = heldWords(layout, held);
|
|
427
|
+
|
|
402
428
|
const maybeRequest = Option.flatMap(held.maybeTarget, (target) =>
|
|
403
|
-
requestOf(layout, held.paneId, target)
|
|
429
|
+
requestOf(layout, held.paneId, target)
|
|
404
430
|
);
|
|
405
431
|
|
|
406
432
|
return Option.match(maybeRequest, {
|
|
@@ -415,10 +441,13 @@ const letGo = (model: Model, layout: Layout, held: Held, putBack: string): Updat
|
|
|
415
441
|
fill(COPY.dropped, {
|
|
416
442
|
subject,
|
|
417
443
|
where: Option.getOrElse(
|
|
418
|
-
whereWords(
|
|
419
|
-
|
|
444
|
+
whereWords(
|
|
445
|
+
apply(layout, request),
|
|
446
|
+
Subject.Pane({ paneId: held.paneId })
|
|
447
|
+
),
|
|
448
|
+
() => WHERE_IT_WAS
|
|
420
449
|
),
|
|
421
|
-
})
|
|
450
|
+
})
|
|
422
451
|
),
|
|
423
452
|
],
|
|
424
453
|
outMessage: request,
|
|
@@ -429,109 +458,156 @@ const letGo = (model: Model, layout: Layout, held: Held, putBack: string): Updat
|
|
|
429
458
|
const cancel = (model: Model, layout: Layout, held: Held): UpdateReturn =>
|
|
430
459
|
letGo(model, layout, { ...held, maybeTarget: Option.none() }, COPY.cancelled);
|
|
431
460
|
|
|
432
|
-
const lift = (
|
|
461
|
+
const lift = (
|
|
462
|
+
model: Model,
|
|
463
|
+
layout: Layout,
|
|
464
|
+
paneId: string,
|
|
465
|
+
by: By
|
|
466
|
+
): UpdateReturn =>
|
|
433
467
|
Option.match(
|
|
434
468
|
Option.filter(originOf(layout, paneId), () => isIdle(model)),
|
|
435
469
|
{
|
|
436
470
|
onNone: () => ({ model }),
|
|
437
471
|
onSome: (origin) => {
|
|
438
472
|
const held: Held = { paneId, by, maybeTarget: Option.some(origin) };
|
|
473
|
+
|
|
439
474
|
return {
|
|
440
475
|
model: withHeld(model, Option.some(held)),
|
|
441
476
|
commands:
|
|
442
477
|
by._tag === "Keyboard"
|
|
443
|
-
? [
|
|
478
|
+
? [
|
|
479
|
+
announce(
|
|
480
|
+
fill(COPY.pickedUpByKeyboard, {
|
|
481
|
+
subject: heldWords(layout, held),
|
|
482
|
+
})
|
|
483
|
+
),
|
|
484
|
+
]
|
|
444
485
|
: [],
|
|
445
486
|
};
|
|
446
487
|
},
|
|
447
|
-
}
|
|
488
|
+
}
|
|
448
489
|
);
|
|
449
490
|
|
|
450
|
-
const movePointer = (
|
|
491
|
+
const movePointer = (
|
|
492
|
+
model: Model,
|
|
493
|
+
layout: Layout,
|
|
494
|
+
held: Held,
|
|
495
|
+
pointer: PointerAt
|
|
496
|
+
): UpdateReturn =>
|
|
451
497
|
By.match(held.by, {
|
|
452
498
|
Keyboard: () => ({ model }),
|
|
453
499
|
Pointer: (by) => {
|
|
454
500
|
const isCarrying =
|
|
455
501
|
by.isCarrying ||
|
|
456
|
-
Math.hypot(pointer.clientX - by.pressX, pointer.clientY - by.pressY) >
|
|
502
|
+
Math.hypot(pointer.clientX - by.pressX, pointer.clientY - by.pressY) >
|
|
503
|
+
CARRY_THRESHOLD;
|
|
504
|
+
|
|
457
505
|
const next: Held = {
|
|
458
506
|
...held,
|
|
459
|
-
by: By.Pointer({
|
|
507
|
+
by: By.Pointer({
|
|
508
|
+
...by,
|
|
509
|
+
x: pointer.clientX,
|
|
510
|
+
y: pointer.clientY,
|
|
511
|
+
isCarrying,
|
|
512
|
+
}),
|
|
460
513
|
maybeTarget: isCarrying ? pointer.maybeTarget : held.maybeTarget,
|
|
461
514
|
};
|
|
515
|
+
|
|
462
516
|
return {
|
|
463
517
|
model: withHeld(model, Option.some(next)),
|
|
464
518
|
commands:
|
|
465
519
|
isCarrying && !by.isCarrying
|
|
466
|
-
? [
|
|
520
|
+
? [
|
|
521
|
+
announce(
|
|
522
|
+
fill(COPY.pickedUp, { subject: heldWords(layout, held) })
|
|
523
|
+
),
|
|
524
|
+
]
|
|
467
525
|
: [],
|
|
468
526
|
};
|
|
469
527
|
},
|
|
470
528
|
});
|
|
471
529
|
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
530
|
+
const stepHeld = (
|
|
531
|
+
model: Model,
|
|
532
|
+
layout: Layout,
|
|
533
|
+
held: Held,
|
|
534
|
+
step: Step
|
|
535
|
+
): UpdateReturn =>
|
|
475
536
|
Option.match(
|
|
476
537
|
Option.filter(held.maybeTarget, () => held.by._tag === "Keyboard"),
|
|
477
538
|
{
|
|
478
539
|
onNone: () => ({ model }),
|
|
479
540
|
onSome: (target) => {
|
|
480
541
|
const next = steppedTarget(layout, held.paneId, target, step);
|
|
542
|
+
|
|
481
543
|
if (Equal.equals(next, target)) {
|
|
482
544
|
return { model };
|
|
483
545
|
}
|
|
546
|
+
|
|
484
547
|
return {
|
|
485
|
-
model: withHeld(
|
|
548
|
+
model: withHeld(
|
|
549
|
+
model,
|
|
550
|
+
Option.some({ ...held, maybeTarget: Option.some(next) })
|
|
551
|
+
),
|
|
486
552
|
commands: [
|
|
487
553
|
announce(
|
|
488
554
|
fill(COPY.over, {
|
|
489
555
|
subject: heldWords(layout, held),
|
|
490
556
|
where: landingWords(layout, held.paneId, next),
|
|
491
|
-
})
|
|
557
|
+
})
|
|
492
558
|
),
|
|
493
559
|
...scrollToTarget(model, layout, next),
|
|
494
560
|
],
|
|
495
561
|
};
|
|
496
562
|
},
|
|
497
|
-
}
|
|
563
|
+
}
|
|
498
564
|
);
|
|
499
565
|
|
|
500
|
-
const whileHeld = (
|
|
566
|
+
const whileHeld = (
|
|
567
|
+
model: Model,
|
|
568
|
+
f: (held: Held) => UpdateReturn
|
|
569
|
+
): UpdateReturn =>
|
|
501
570
|
Option.match(model.maybeHeld, { onNone: () => ({ model }), onSome: f });
|
|
502
571
|
|
|
503
|
-
const whileHeldBy = (
|
|
572
|
+
const whileHeldBy = (
|
|
573
|
+
model: Model,
|
|
574
|
+
by: By["_tag"],
|
|
575
|
+
f: (held: Held) => UpdateReturn
|
|
576
|
+
): UpdateReturn =>
|
|
504
577
|
whileHeld(model, (held) => (held.by._tag === by ? f(held) : { model }));
|
|
505
578
|
|
|
506
|
-
/** The resize a splitter dragged `share` of its scale asks for: previewed while it moves, and
|
|
507
|
-
* asked for when it is let go. */
|
|
508
579
|
const resizeSplitter = (
|
|
509
580
|
model: Model,
|
|
510
581
|
layout: Layout,
|
|
511
582
|
share: number,
|
|
512
|
-
isLetGo: boolean
|
|
583
|
+
isLetGo: boolean
|
|
513
584
|
): UpdateReturn =>
|
|
514
585
|
Option.match(model.maybeResizing, {
|
|
515
586
|
onNone: () => ({ model }),
|
|
516
587
|
onSome: (resizing) => {
|
|
517
588
|
const maybeResize = resizeOf(layout, resizing.splitter, share);
|
|
589
|
+
|
|
518
590
|
if (!isLetGo) {
|
|
519
|
-
return {
|
|
591
|
+
return {
|
|
592
|
+
model: withResizing(model, Option.some({ ...resizing, maybeResize })),
|
|
593
|
+
};
|
|
520
594
|
}
|
|
595
|
+
|
|
521
596
|
return Option.match(maybeResize, {
|
|
522
597
|
onNone: () => ({ model: withResizing(model, Option.none()) }),
|
|
523
|
-
onSome: (resize) => ({
|
|
598
|
+
onSome: (resize) => ({
|
|
599
|
+
model: withResizing(model, Option.none()),
|
|
600
|
+
outMessage: resize,
|
|
601
|
+
}),
|
|
524
602
|
});
|
|
525
603
|
},
|
|
526
604
|
});
|
|
527
605
|
|
|
528
|
-
/** Shows the pane `paneId` under its tab and moves the keyboard as `focus` says: into the
|
|
529
|
-
* pane for a press, onto the tab for an arrow. */
|
|
530
606
|
const selectTab = (
|
|
531
607
|
model: Model,
|
|
532
608
|
layout: Layout,
|
|
533
609
|
paneId: string,
|
|
534
|
-
focus: Command.Command<Message
|
|
610
|
+
focus: Command.Command<Message>
|
|
535
611
|
): UpdateReturn =>
|
|
536
612
|
Option.match(placeOf(layout, paneId), {
|
|
537
613
|
onNone: () => ({ model }),
|
|
@@ -540,7 +616,11 @@ const selectTab = (
|
|
|
540
616
|
|
|
541
617
|
/** Processes a reel Message against the layout as the application holds it now, and returns
|
|
542
618
|
* the next Model, Commands and OutMessage. */
|
|
543
|
-
export const update = (
|
|
619
|
+
export const update = (
|
|
620
|
+
model: Model,
|
|
621
|
+
message: Message,
|
|
622
|
+
context: UpdateContext
|
|
623
|
+
): UpdateReturn => {
|
|
544
624
|
const { layout } = context;
|
|
545
625
|
|
|
546
626
|
return Message.match<UpdateReturn>(message, {
|
|
@@ -556,47 +636,72 @@ export const update = (model: Model, message: Message, context: UpdateContext):
|
|
|
556
636
|
x: clientX,
|
|
557
637
|
y: clientY,
|
|
558
638
|
isCarrying: false,
|
|
559
|
-
})
|
|
639
|
+
})
|
|
560
640
|
),
|
|
561
641
|
PressedGripKey: ({ paneId }) => lift(model, layout, paneId, By.Keyboard()),
|
|
562
642
|
MovedPointer: (pointer) =>
|
|
563
|
-
whileHeldBy(model, "Pointer", (held) =>
|
|
643
|
+
whileHeldBy(model, "Pointer", (held) =>
|
|
644
|
+
movePointer(model, layout, held, pointer)
|
|
645
|
+
),
|
|
564
646
|
ReleasedPointer: (pointer) =>
|
|
565
647
|
whileHeldBy(model, "Pointer", (held) =>
|
|
566
648
|
letGo(
|
|
567
649
|
model,
|
|
568
650
|
layout,
|
|
569
|
-
isCarried(held)
|
|
570
|
-
|
|
571
|
-
|
|
651
|
+
isCarried(held)
|
|
652
|
+
? { ...held, maybeTarget: pointer.maybeTarget }
|
|
653
|
+
: held,
|
|
654
|
+
COPY.putBack
|
|
655
|
+
)
|
|
572
656
|
),
|
|
573
657
|
CancelledPointer: () =>
|
|
574
658
|
whileHeldBy(model, "Pointer", (held) =>
|
|
575
|
-
letGo(
|
|
659
|
+
letGo(
|
|
660
|
+
model,
|
|
661
|
+
layout,
|
|
662
|
+
{ ...held, maybeTarget: Option.none() },
|
|
663
|
+
COPY.putBack
|
|
664
|
+
)
|
|
576
665
|
),
|
|
577
666
|
SteppedHeld: ({ step }) =>
|
|
578
|
-
whileHeldBy(model, "Keyboard", (held) =>
|
|
667
|
+
whileHeldBy(model, "Keyboard", (held) =>
|
|
668
|
+
stepHeld(model, layout, held, step)
|
|
669
|
+
),
|
|
579
670
|
DroppedHeld: () =>
|
|
580
|
-
whileHeldBy(model, "Keyboard", (held) =>
|
|
581
|
-
|
|
671
|
+
whileHeldBy(model, "Keyboard", (held) =>
|
|
672
|
+
letGo(model, layout, held, COPY.putBack)
|
|
673
|
+
),
|
|
674
|
+
LeftGrip: () =>
|
|
675
|
+
whileHeldBy(model, "Keyboard", (held) => cancel(model, layout, held)),
|
|
582
676
|
PressedEscape: () =>
|
|
583
677
|
Option.isSome(model.maybeResizing)
|
|
584
678
|
? { model: withResizing(model, Option.none()) }
|
|
585
679
|
: whileHeld(model, (held) => cancel(model, layout, held)),
|
|
586
680
|
PressedTab: ({ paneId }) =>
|
|
587
|
-
selectTab(
|
|
681
|
+
selectTab(
|
|
682
|
+
model,
|
|
683
|
+
layout,
|
|
684
|
+
paneId,
|
|
685
|
+
FocusPane({ paneHook: paneHook(model, paneId) })
|
|
686
|
+
),
|
|
588
687
|
SteppedTab: ({ paneId }) =>
|
|
589
|
-
selectTab(
|
|
688
|
+
selectTab(
|
|
689
|
+
model,
|
|
690
|
+
layout,
|
|
691
|
+
paneId,
|
|
692
|
+
FocusTab({ tabHook: tabHook(model, paneId) })
|
|
693
|
+
),
|
|
590
694
|
FocusedPane: ({ paneId }) =>
|
|
591
695
|
Option.match(
|
|
592
696
|
Option.filter(
|
|
593
697
|
placeOf(layout, paneId),
|
|
594
|
-
() =>
|
|
698
|
+
() =>
|
|
699
|
+
!Option.exists(model.maybeFocus, (focus) => focus.paneId === paneId)
|
|
595
700
|
),
|
|
596
701
|
{
|
|
597
702
|
onNone: () => ({ model }),
|
|
598
703
|
onSome: (place) => ({ model: focusOn(model, place) }),
|
|
599
|
-
}
|
|
704
|
+
}
|
|
600
705
|
),
|
|
601
706
|
PressedSplitter: ({ splitter, pointerId, clientX, clientY }) =>
|
|
602
707
|
!isIdle(model) || !isSplitterPresent(layout, splitter)
|
|
@@ -610,7 +715,7 @@ export const update = (model: Model, message: Message, context: UpdateContext):
|
|
|
610
715
|
pressX: clientX,
|
|
611
716
|
pressY: clientY,
|
|
612
717
|
maybeResize: Option.none(),
|
|
613
|
-
})
|
|
718
|
+
})
|
|
614
719
|
),
|
|
615
720
|
},
|
|
616
721
|
MovedSplitter: ({ share }) => resizeSplitter(model, layout, share, false),
|
|
@@ -630,8 +735,6 @@ export const update = (model: Model, message: Message, context: UpdateContext):
|
|
|
630
735
|
});
|
|
631
736
|
};
|
|
632
737
|
|
|
633
|
-
// CAPABILITIES
|
|
634
|
-
|
|
635
738
|
/**
|
|
636
739
|
* Brings the reel in line with a layout that changed: call it whenever the application changes
|
|
637
740
|
* the layout, by a request it applied, another client's or one of its own (a pane closed). The
|
|
@@ -640,26 +743,34 @@ export const update = (model: Model, message: Message, context: UpdateContext):
|
|
|
640
743
|
* gone is cancelled, and one whose target's column has gone aims where it started;
|
|
641
744
|
* a splitter whose column or pane has gone lets go.
|
|
642
745
|
*/
|
|
643
|
-
export const reconcile = (
|
|
746
|
+
export const reconcile = (
|
|
747
|
+
model: Model,
|
|
748
|
+
context: UpdateContext
|
|
749
|
+
): UpdateReturn => {
|
|
644
750
|
const { layout } = context;
|
|
751
|
+
|
|
645
752
|
const isFocusGone = Option.exists(model.maybeFocus, (focus) =>
|
|
646
|
-
Option.isNone(placeOf(layout, focus.paneId))
|
|
753
|
+
Option.isNone(placeOf(layout, focus.paneId))
|
|
647
754
|
);
|
|
755
|
+
|
|
648
756
|
const maybePlace = Option.filter(focusedPlace(model, layout), () =>
|
|
649
|
-
Option.isSome(model.maybeFocus)
|
|
757
|
+
Option.isSome(model.maybeFocus)
|
|
650
758
|
);
|
|
759
|
+
|
|
651
760
|
const focused = Option.match(maybePlace, {
|
|
652
761
|
onNone: () => model,
|
|
653
762
|
onSome: (place) => focusOn(model, place),
|
|
654
763
|
});
|
|
764
|
+
|
|
655
765
|
const restore = Array.fromOption(
|
|
656
766
|
Option.map(
|
|
657
767
|
Option.filter(maybePlace, () => isFocusGone),
|
|
658
|
-
(place) => RestoreFocus({ paneHook: paneHook(model, place.pane.id) })
|
|
659
|
-
)
|
|
768
|
+
(place) => RestoreFocus({ paneHook: paneHook(model, place.pane.id) })
|
|
769
|
+
)
|
|
660
770
|
);
|
|
771
|
+
|
|
661
772
|
const settled = Option.exists(model.maybeResizing, ({ splitter }) =>
|
|
662
|
-
isSplitterPresent(layout, splitter)
|
|
773
|
+
isSplitterPresent(layout, splitter)
|
|
663
774
|
)
|
|
664
775
|
? focused
|
|
665
776
|
: withResizing(focused, Option.none());
|
|
@@ -673,10 +784,17 @@ export const reconcile = (model: Model, context: UpdateContext): UpdateReturn =>
|
|
|
673
784
|
commands: [...restore, announce(COPY.gone)],
|
|
674
785
|
};
|
|
675
786
|
}
|
|
787
|
+
|
|
676
788
|
const maybeTarget = Option.orElse(
|
|
677
|
-
Option.filter(held.maybeTarget, (target) =>
|
|
678
|
-
|
|
789
|
+
Option.filter(held.maybeTarget, (target) =>
|
|
790
|
+
isTargetPresent(layout, target)
|
|
791
|
+
),
|
|
792
|
+
() =>
|
|
793
|
+
held.by._tag === "Keyboard"
|
|
794
|
+
? originOf(layout, held.paneId)
|
|
795
|
+
: Option.none()
|
|
679
796
|
);
|
|
797
|
+
|
|
680
798
|
return {
|
|
681
799
|
model: withHeld(settled, Option.some({ ...held, maybeTarget })),
|
|
682
800
|
commands: restore,
|
|
@@ -704,25 +822,33 @@ export const Action = Schema.Literals([
|
|
|
704
822
|
"CycleWidth",
|
|
705
823
|
"PullOut",
|
|
706
824
|
]);
|
|
825
|
+
|
|
707
826
|
export type Action = typeof Action.Type;
|
|
708
827
|
|
|
709
|
-
const focusStep = (
|
|
828
|
+
const focusStep = (
|
|
829
|
+
model: Model,
|
|
830
|
+
layout: Layout,
|
|
831
|
+
place: Place
|
|
832
|
+
): UpdateReturn => ({
|
|
710
833
|
model: focusOn(model, place),
|
|
711
834
|
commands: [
|
|
712
835
|
FocusPane({ paneHook: paneHook(model, place.pane.id) }),
|
|
713
836
|
ScrollIntoView({ hook: paneHook(model, place.pane.id) }),
|
|
714
|
-
announce(
|
|
837
|
+
announce(
|
|
838
|
+
fill(COPY.focused, {
|
|
839
|
+
pane: place.pane.label,
|
|
840
|
+
where: placeWords(layout, place),
|
|
841
|
+
})
|
|
842
|
+
),
|
|
715
843
|
],
|
|
716
844
|
});
|
|
717
845
|
|
|
718
|
-
/** Asks for `request` with focus kept on the pane it moves, at its new place, the reel
|
|
719
|
-
* scrolled to it and the move said; nothing where it would change nothing. */
|
|
720
846
|
const requestStep = (
|
|
721
847
|
model: Model,
|
|
722
848
|
layout: Layout,
|
|
723
849
|
place: Place,
|
|
724
850
|
subject: Subject,
|
|
725
|
-
maybeRequest: Option.Option<OutMessage
|
|
851
|
+
maybeRequest: Option.Option<OutMessage>
|
|
726
852
|
): UpdateReturn =>
|
|
727
853
|
Option.match(
|
|
728
854
|
Option.filter(maybeRequest, (request) => isChange(layout, request)),
|
|
@@ -730,50 +856,67 @@ const requestStep = (
|
|
|
730
856
|
onNone: () => ({ model }),
|
|
731
857
|
onSome: (request) => {
|
|
732
858
|
const next = apply(layout, request);
|
|
733
|
-
|
|
734
|
-
const
|
|
735
|
-
|
|
859
|
+
|
|
860
|
+
const landing = Option.getOrElse(
|
|
861
|
+
placeOf(next, place.pane.id),
|
|
862
|
+
() => place
|
|
863
|
+
);
|
|
864
|
+
|
|
865
|
+
const words = Option.getOrElse(
|
|
866
|
+
subjectWords(layout, subject),
|
|
867
|
+
() => place.pane.label
|
|
868
|
+
);
|
|
869
|
+
|
|
870
|
+
const where = Option.getOrElse(
|
|
871
|
+
whereWords(next, subject),
|
|
872
|
+
() => WHERE_IT_WAS
|
|
873
|
+
);
|
|
736
874
|
|
|
737
875
|
return {
|
|
738
876
|
model: focusOn(model, landing),
|
|
739
877
|
commands: [
|
|
740
878
|
ScrollIntoView({ hook: paneHook(model, place.pane.id) }),
|
|
741
|
-
announce(
|
|
879
|
+
announce(
|
|
880
|
+
fill(COPY.moved, { subject: String.capitalize(words), where })
|
|
881
|
+
),
|
|
742
882
|
],
|
|
743
883
|
outMessage: request,
|
|
744
884
|
};
|
|
745
885
|
},
|
|
746
|
-
}
|
|
886
|
+
}
|
|
747
887
|
);
|
|
748
888
|
|
|
749
|
-
|
|
750
|
-
const readingOrder = (layout: Layout): ReadonlyArray<Pane> =>
|
|
889
|
+
const readingOrder = (layout: Layout): readonly Pane[] =>
|
|
751
890
|
Array.flatMap(layout, (column) => column.panes);
|
|
752
891
|
|
|
753
|
-
|
|
754
|
-
* down to the one after. */
|
|
755
|
-
const TAB_STEPS: Readonly<Partial<Record<Action, number>>> = {
|
|
892
|
+
const TAB_STEPS: Partial<Record.ReadonlyRecord<Action, number>> = {
|
|
756
893
|
FocusLeft: -1,
|
|
757
894
|
FocusUp: -1,
|
|
758
895
|
FocusRight: 1,
|
|
759
896
|
FocusDown: 1,
|
|
760
897
|
};
|
|
761
898
|
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
899
|
+
const performTabbed = (
|
|
900
|
+
model: Model,
|
|
901
|
+
action: Action,
|
|
902
|
+
layout: Layout
|
|
903
|
+
): UpdateReturn => {
|
|
765
904
|
const panes = readingOrder(layout);
|
|
905
|
+
|
|
766
906
|
const maybeNext = Option.flatMap(
|
|
767
907
|
Option.all({
|
|
768
908
|
step: Option.fromUndefinedOr(TAB_STEPS[action]),
|
|
769
909
|
index: Option.flatMap(focusedPaneId(model, layout), (paneId) =>
|
|
770
|
-
Array.findFirstIndex(panes, (pane) => pane.id === paneId)
|
|
910
|
+
Array.findFirstIndex(panes, (pane) => pane.id === paneId)
|
|
771
911
|
),
|
|
772
912
|
}),
|
|
773
913
|
({ step, index }) =>
|
|
774
914
|
Option.flatMap(Array.get(panes, index + step), (pane) =>
|
|
775
|
-
Option.map(placeOf(layout, pane.id), (place) => ({
|
|
776
|
-
|
|
915
|
+
Option.map(placeOf(layout, pane.id), (place) => ({
|
|
916
|
+
place,
|
|
917
|
+
tab: index + step + 1,
|
|
918
|
+
}))
|
|
919
|
+
)
|
|
777
920
|
);
|
|
778
921
|
|
|
779
922
|
return Option.match(
|
|
@@ -784,10 +927,16 @@ const performTabbed = (model: Model, action: Action, layout: Layout): UpdateRetu
|
|
|
784
927
|
model: focusOn(model, place),
|
|
785
928
|
commands: [
|
|
786
929
|
FocusPane({ paneHook: paneHook(model, place.pane.id) }),
|
|
787
|
-
announce(
|
|
930
|
+
announce(
|
|
931
|
+
fill(COPY.focusedTab, {
|
|
932
|
+
pane: place.pane.label,
|
|
933
|
+
tab,
|
|
934
|
+
tabs: panes.length,
|
|
935
|
+
})
|
|
936
|
+
),
|
|
788
937
|
],
|
|
789
938
|
}),
|
|
790
|
-
}
|
|
939
|
+
}
|
|
791
940
|
);
|
|
792
941
|
};
|
|
793
942
|
|
|
@@ -802,7 +951,11 @@ const columnIdAt = (layout: Layout, index: number): Option.Option<string> =>
|
|
|
802
951
|
* held, or where there is nowhere to go. Under tabs, only the focus keys act, stepping from tab
|
|
803
952
|
* to tab.
|
|
804
953
|
*/
|
|
805
|
-
export const perform = (
|
|
954
|
+
export const perform = (
|
|
955
|
+
model: Model,
|
|
956
|
+
action: Action,
|
|
957
|
+
context: UpdateContext
|
|
958
|
+
): UpdateReturn => {
|
|
806
959
|
const { layout, arrangement = "Strip" } = context;
|
|
807
960
|
|
|
808
961
|
if (arrangement === "Tabs") {
|
|
@@ -817,26 +970,37 @@ export const perform = (model: Model, action: Action, context: UpdateContext): U
|
|
|
817
970
|
const { column, columnIndex, row, pane } = place;
|
|
818
971
|
const rows = column.panes.length;
|
|
819
972
|
const paneId = pane.id;
|
|
973
|
+
|
|
820
974
|
const ask = (
|
|
821
975
|
maybeRequest: Option.Option<OutMessage>,
|
|
822
|
-
subject: Subject = Subject.Pane({ paneId })
|
|
976
|
+
subject: Subject = Subject.Pane({ paneId })
|
|
823
977
|
) => requestStep(model, layout, place, subject, maybeRequest);
|
|
978
|
+
|
|
824
979
|
const focusAt = (toColumn: number, toRow: number): UpdateReturn =>
|
|
825
980
|
Option.match(
|
|
826
981
|
Option.flatMap(Array.get(layout, toColumn), (found) =>
|
|
827
982
|
placeAt(
|
|
828
983
|
layout,
|
|
829
984
|
toColumn,
|
|
830
|
-
Number.clamp(toRow, {
|
|
831
|
-
|
|
985
|
+
Number.clamp(toRow, {
|
|
986
|
+
minimum: 0,
|
|
987
|
+
maximum: found.panes.length - 1,
|
|
988
|
+
})
|
|
989
|
+
)
|
|
832
990
|
),
|
|
833
991
|
{
|
|
834
992
|
onNone: () => ({ model }),
|
|
835
993
|
onSome: (next) =>
|
|
836
|
-
next.pane.id === paneId
|
|
837
|
-
|
|
994
|
+
next.pane.id === paneId
|
|
995
|
+
? { model }
|
|
996
|
+
: focusStep(model, layout, next),
|
|
997
|
+
}
|
|
838
998
|
);
|
|
839
|
-
|
|
999
|
+
|
|
1000
|
+
const sideways = (
|
|
1001
|
+
toColumn: number,
|
|
1002
|
+
edge: Option.Option<string>
|
|
1003
|
+
): UpdateReturn =>
|
|
840
1004
|
ask(
|
|
841
1005
|
Option.match(Array.get(layout, toColumn), {
|
|
842
1006
|
onSome: (found) =>
|
|
@@ -845,66 +1009,100 @@ export const perform = (model: Model, action: Action, context: UpdateContext): U
|
|
|
845
1009
|
paneId,
|
|
846
1010
|
toColumnId: found.id,
|
|
847
1011
|
toIndex: Math.min(row, found.panes.length),
|
|
848
|
-
})
|
|
1012
|
+
})
|
|
849
1013
|
),
|
|
850
1014
|
onNone: () =>
|
|
851
1015
|
Option.liftPredicate(
|
|
852
|
-
OutMessage.PulledOutPane({
|
|
853
|
-
|
|
1016
|
+
OutMessage.PulledOutPane({
|
|
1017
|
+
paneId,
|
|
1018
|
+
maybeBeforeColumnId: edge,
|
|
1019
|
+
}),
|
|
1020
|
+
() => rows > 1
|
|
854
1021
|
),
|
|
855
|
-
})
|
|
1022
|
+
})
|
|
856
1023
|
);
|
|
857
|
-
|
|
1024
|
+
|
|
1025
|
+
const moveColumn = (
|
|
1026
|
+
maybeBefore: Option.Option<Option.Option<string>>
|
|
1027
|
+
): UpdateReturn =>
|
|
858
1028
|
ask(
|
|
859
1029
|
Option.map(maybeBefore, (maybeBeforeColumnId) =>
|
|
860
|
-
OutMessage.MovedColumn({
|
|
1030
|
+
OutMessage.MovedColumn({
|
|
1031
|
+
columnId: column.id,
|
|
1032
|
+
maybeBeforeColumnId,
|
|
1033
|
+
})
|
|
861
1034
|
),
|
|
862
|
-
Subject.Column({ columnId: column.id })
|
|
1035
|
+
Subject.Column({ columnId: column.id })
|
|
863
1036
|
);
|
|
864
1037
|
|
|
865
1038
|
return Match.value(action).pipe(
|
|
866
1039
|
Match.withReturnType<UpdateReturn>(),
|
|
867
1040
|
Match.when("FocusLeft", () => focusAt(columnIndex - 1, row)),
|
|
868
1041
|
Match.when("FocusRight", () => focusAt(columnIndex + 1, row)),
|
|
869
|
-
Match.when("FocusUp", () =>
|
|
1042
|
+
Match.when("FocusUp", () =>
|
|
1043
|
+
row > 0 ? focusAt(columnIndex, row - 1) : { model }
|
|
1044
|
+
),
|
|
870
1045
|
Match.when("FocusDown", () => focusAt(columnIndex, row + 1)),
|
|
871
1046
|
Match.when("MovePaneUp", () =>
|
|
872
1047
|
ask(
|
|
873
1048
|
Option.some(
|
|
874
|
-
OutMessage.MovedPane({
|
|
875
|
-
|
|
876
|
-
|
|
1049
|
+
OutMessage.MovedPane({
|
|
1050
|
+
paneId,
|
|
1051
|
+
toColumnId: column.id,
|
|
1052
|
+
toIndex: row - 1,
|
|
1053
|
+
})
|
|
1054
|
+
)
|
|
1055
|
+
)
|
|
877
1056
|
),
|
|
878
1057
|
Match.when("MovePaneDown", () =>
|
|
879
1058
|
ask(
|
|
880
1059
|
Option.some(
|
|
881
|
-
OutMessage.MovedPane({
|
|
882
|
-
|
|
883
|
-
|
|
1060
|
+
OutMessage.MovedPane({
|
|
1061
|
+
paneId,
|
|
1062
|
+
toColumnId: column.id,
|
|
1063
|
+
toIndex: row + 1,
|
|
1064
|
+
})
|
|
1065
|
+
)
|
|
1066
|
+
)
|
|
1067
|
+
),
|
|
1068
|
+
Match.when("MovePaneLeft", () =>
|
|
1069
|
+
sideways(columnIndex - 1, columnIdAt(layout, 0))
|
|
1070
|
+
),
|
|
1071
|
+
Match.when("MovePaneRight", () =>
|
|
1072
|
+
sideways(columnIndex + 1, Option.none())
|
|
884
1073
|
),
|
|
885
|
-
Match.when("MovePaneLeft", () => sideways(columnIndex - 1, columnIdAt(layout, 0))),
|
|
886
|
-
Match.when("MovePaneRight", () => sideways(columnIndex + 1, Option.none())),
|
|
887
1074
|
Match.when("MoveColumnLeft", () =>
|
|
888
1075
|
moveColumn(
|
|
889
|
-
Option.map(columnIdAt(layout, columnIndex - 1), (before) =>
|
|
890
|
-
|
|
1076
|
+
Option.map(columnIdAt(layout, columnIndex - 1), (before) =>
|
|
1077
|
+
Option.some(before)
|
|
1078
|
+
)
|
|
1079
|
+
)
|
|
891
1080
|
),
|
|
892
1081
|
Match.when("MoveColumnRight", () =>
|
|
893
1082
|
moveColumn(
|
|
894
1083
|
Option.map(columnIdAt(layout, columnIndex + 1), () =>
|
|
895
|
-
columnIdAt(layout, columnIndex + 2)
|
|
896
|
-
)
|
|
897
|
-
)
|
|
1084
|
+
columnIdAt(layout, columnIndex + 2)
|
|
1085
|
+
)
|
|
1086
|
+
)
|
|
898
1087
|
),
|
|
899
1088
|
Match.when("CycleWidth", () => {
|
|
900
1089
|
const width = nextPreset(column.width);
|
|
1090
|
+
|
|
901
1091
|
return {
|
|
902
1092
|
model,
|
|
903
1093
|
commands: [
|
|
904
1094
|
ScrollIntoView({ hook: paneHook(model, paneId) }),
|
|
905
|
-
announce(
|
|
1095
|
+
announce(
|
|
1096
|
+
fill(COPY.widened, {
|
|
1097
|
+
column: columnIndex + 1,
|
|
1098
|
+
width: widthWords(width),
|
|
1099
|
+
})
|
|
1100
|
+
),
|
|
906
1101
|
],
|
|
907
|
-
outMessage: OutMessage.ResizedColumn({
|
|
1102
|
+
outMessage: OutMessage.ResizedColumn({
|
|
1103
|
+
columnId: column.id,
|
|
1104
|
+
width,
|
|
1105
|
+
}),
|
|
908
1106
|
};
|
|
909
1107
|
}),
|
|
910
1108
|
Match.when("PullOut", () =>
|
|
@@ -914,60 +1112,59 @@ export const perform = (model: Model, action: Action, context: UpdateContext): U
|
|
|
914
1112
|
paneId,
|
|
915
1113
|
maybeBeforeColumnId: columnIdAt(layout, columnIndex + 1),
|
|
916
1114
|
}),
|
|
917
|
-
() => rows > 1
|
|
918
|
-
)
|
|
919
|
-
)
|
|
1115
|
+
() => rows > 1
|
|
1116
|
+
)
|
|
1117
|
+
)
|
|
920
1118
|
),
|
|
921
|
-
Match.exhaustive
|
|
1119
|
+
Match.exhaustive
|
|
922
1120
|
);
|
|
923
1121
|
},
|
|
924
|
-
}
|
|
1122
|
+
}
|
|
925
1123
|
);
|
|
926
1124
|
};
|
|
927
1125
|
|
|
928
|
-
// SUBSCRIPTION
|
|
929
|
-
|
|
930
|
-
/** How near the reel's edges a carried pane scrolls it, how fast, and the longest frame it
|
|
931
|
-
* counts, so a tab coming back from the background does not jump. */
|
|
932
1126
|
const EDGE_SCROLL = 40;
|
|
933
1127
|
const EDGE_SCROLL_PIXELS_PER_MILLI = 0.8;
|
|
934
1128
|
const LONGEST_FRAME_MILLIS = 50;
|
|
935
1129
|
|
|
936
|
-
|
|
937
|
-
const columnBoxOf = (element: Element): ColumnBox => {
|
|
1130
|
+
const columnBoxOf = (element: HTMLElement): ColumnBox => {
|
|
938
1131
|
const rect = element.getBoundingClientRect();
|
|
1132
|
+
|
|
939
1133
|
return {
|
|
940
|
-
id: element.
|
|
1134
|
+
id: element.dataset["reelColumn"] ?? "",
|
|
941
1135
|
left: rect.left,
|
|
942
1136
|
right: rect.right,
|
|
943
1137
|
};
|
|
944
1138
|
};
|
|
945
1139
|
|
|
946
|
-
|
|
947
|
-
|
|
1140
|
+
const slotMiddlesOf = (
|
|
1141
|
+
element: HTMLElement,
|
|
1142
|
+
heldId: string
|
|
1143
|
+
): readonly number[] =>
|
|
948
1144
|
Array.map(
|
|
949
1145
|
Array.filter(
|
|
950
|
-
Array.fromIterable(
|
|
951
|
-
|
|
1146
|
+
Array.fromIterable(
|
|
1147
|
+
element.querySelectorAll<HTMLElement>("[data-reel-slot]")
|
|
1148
|
+
),
|
|
1149
|
+
(slot) => slot.dataset["reelSlot"] !== heldId
|
|
952
1150
|
),
|
|
953
1151
|
(slot) => {
|
|
954
1152
|
const slotRect = slot.getBoundingClientRect();
|
|
1153
|
+
|
|
955
1154
|
return slotRect.top + slotRect.height / 2;
|
|
956
|
-
}
|
|
1155
|
+
}
|
|
957
1156
|
);
|
|
958
1157
|
|
|
959
|
-
/** Where a pointer at (`clientX`, `clientY`) would drop the pane `paneId` in the reel
|
|
960
|
-
* `reelHook` names, read from where its columns sit and the slots of the one it is over: none
|
|
961
|
-
* outside the reel. */
|
|
962
1158
|
const pointerTarget = (
|
|
963
1159
|
reelHook: string,
|
|
964
1160
|
paneId: string,
|
|
965
1161
|
clientX: number,
|
|
966
|
-
clientY: number
|
|
1162
|
+
clientY: number
|
|
967
1163
|
): Option.Option<Target> =>
|
|
968
1164
|
Option.map(
|
|
969
1165
|
Option.filter(scrollerOf(reelHook), (view) => {
|
|
970
1166
|
const rect = view.getBoundingClientRect();
|
|
1167
|
+
|
|
971
1168
|
return (
|
|
972
1169
|
clientX >= rect.left &&
|
|
973
1170
|
clientX <= rect.right &&
|
|
@@ -976,72 +1173,91 @@ const pointerTarget = (
|
|
|
976
1173
|
);
|
|
977
1174
|
}),
|
|
978
1175
|
(view) => {
|
|
979
|
-
const columns = Array.fromIterable(
|
|
980
|
-
|
|
981
|
-
Option.match(Array.get(columns, index), {
|
|
982
|
-
onNone: () => [],
|
|
983
|
-
onSome: (column) => slotMiddlesOf(column, paneId),
|
|
984
|
-
}),
|
|
1176
|
+
const columns = Array.fromIterable(
|
|
1177
|
+
view.querySelectorAll<HTMLElement>("[data-reel-column]")
|
|
985
1178
|
);
|
|
986
|
-
|
|
1179
|
+
|
|
1180
|
+
return targetAtPoint(
|
|
1181
|
+
Array.map(columns, columnBoxOf),
|
|
1182
|
+
clientX,
|
|
1183
|
+
clientY,
|
|
1184
|
+
(index) =>
|
|
1185
|
+
Option.match(Array.get(columns, index), {
|
|
1186
|
+
onNone: () => [],
|
|
1187
|
+
onSome: (column) => slotMiddlesOf(column, paneId),
|
|
1188
|
+
})
|
|
1189
|
+
);
|
|
1190
|
+
}
|
|
987
1191
|
);
|
|
988
1192
|
|
|
989
1193
|
const PointerHold = Schema.Struct({
|
|
990
1194
|
reelHook: Schema.String,
|
|
991
1195
|
paneId: Schema.String,
|
|
992
|
-
pointerId: Schema.
|
|
1196
|
+
pointerId: Schema.Finite,
|
|
993
1197
|
});
|
|
1198
|
+
|
|
994
1199
|
type PointerHold = typeof PointerHold.Type;
|
|
995
1200
|
|
|
996
1201
|
const pointerAt = (hold: PointerHold, event: PointerEvent): PointerAt => ({
|
|
997
1202
|
clientX: event.clientX,
|
|
998
1203
|
clientY: event.clientY,
|
|
999
|
-
maybeTarget: pointerTarget(
|
|
1204
|
+
maybeTarget: pointerTarget(
|
|
1205
|
+
hold.reelHook,
|
|
1206
|
+
hold.paneId,
|
|
1207
|
+
event.clientX,
|
|
1208
|
+
event.clientY
|
|
1209
|
+
),
|
|
1000
1210
|
});
|
|
1001
1211
|
|
|
1002
|
-
/** The pressing pointer's moves, release and cancel; another pointer's are not the reel's. A
|
|
1003
|
-
* pointer reports moves faster than the page draws, and each reads the reel's layout, so its
|
|
1004
|
-
* moves are read once a frame, at the latest; a release first reads the move not read yet,
|
|
1005
|
-
* so the pane is carried as far as the pointer went, and a cancel drops it. */
|
|
1006
1212
|
const pointerMessages = (hold: PointerHold): Stream.Stream<Message> =>
|
|
1007
1213
|
Stream.callback<Message>((queue) =>
|
|
1008
1214
|
Effect.acquireRelease(
|
|
1009
1215
|
Effect.sync(() => {
|
|
1010
1216
|
const state = { maybeMove: Option.none<PointerEvent>(), frame: 0 };
|
|
1011
|
-
|
|
1012
|
-
Queue.offerUnsafe(queue, message);
|
|
1013
|
-
};
|
|
1217
|
+
|
|
1014
1218
|
const readMove = (): void => {
|
|
1015
1219
|
cancelAnimationFrame(state.frame);
|
|
1016
|
-
Option.map(state.maybeMove, (event) =>
|
|
1017
|
-
|
|
1018
|
-
|
|
1220
|
+
Option.map(state.maybeMove, (event) => {
|
|
1221
|
+
Queue.offerUnsafe(
|
|
1222
|
+
queue,
|
|
1223
|
+
Message.MovedPointer(pointerAt(hold, event))
|
|
1224
|
+
);
|
|
1225
|
+
});
|
|
1019
1226
|
state.maybeMove = Option.none();
|
|
1020
1227
|
};
|
|
1228
|
+
|
|
1021
1229
|
const onMove = (event: PointerEvent): void => {
|
|
1022
1230
|
if (event.pointerId === hold.pointerId) {
|
|
1023
1231
|
if (Option.isNone(state.maybeMove)) {
|
|
1024
1232
|
state.frame = requestAnimationFrame(readMove);
|
|
1025
1233
|
}
|
|
1234
|
+
|
|
1026
1235
|
state.maybeMove = Option.some(event);
|
|
1027
1236
|
}
|
|
1028
1237
|
};
|
|
1238
|
+
|
|
1029
1239
|
const onUp = (event: PointerEvent): void => {
|
|
1030
1240
|
if (event.pointerId === hold.pointerId) {
|
|
1031
1241
|
readMove();
|
|
1032
|
-
|
|
1242
|
+
Queue.offerUnsafe(
|
|
1243
|
+
queue,
|
|
1244
|
+
Message.ReleasedPointer(pointerAt(hold, event))
|
|
1245
|
+
);
|
|
1033
1246
|
}
|
|
1034
1247
|
};
|
|
1248
|
+
|
|
1035
1249
|
const onCancel = (event: PointerEvent): void => {
|
|
1036
1250
|
if (event.pointerId === hold.pointerId) {
|
|
1037
1251
|
cancelAnimationFrame(state.frame);
|
|
1038
1252
|
state.maybeMove = Option.none();
|
|
1039
|
-
|
|
1253
|
+
Queue.offerUnsafe(queue, Message.CancelledPointer());
|
|
1040
1254
|
}
|
|
1041
1255
|
};
|
|
1256
|
+
|
|
1042
1257
|
document.addEventListener("pointermove", onMove);
|
|
1043
1258
|
document.addEventListener("pointerup", onUp);
|
|
1044
1259
|
document.addEventListener("pointercancel", onCancel);
|
|
1260
|
+
|
|
1045
1261
|
return { state, onMove, onUp, onCancel };
|
|
1046
1262
|
}),
|
|
1047
1263
|
({ state, onMove, onUp, onCancel }) =>
|
|
@@ -1050,23 +1266,20 @@ const pointerMessages = (hold: PointerHold): Stream.Stream<Message> =>
|
|
|
1050
1266
|
document.removeEventListener("pointermove", onMove);
|
|
1051
1267
|
document.removeEventListener("pointerup", onUp);
|
|
1052
1268
|
document.removeEventListener("pointercancel", onCancel);
|
|
1053
|
-
})
|
|
1054
|
-
)
|
|
1269
|
+
})
|
|
1270
|
+
)
|
|
1055
1271
|
);
|
|
1056
1272
|
|
|
1057
|
-
/** Which way a pointer at `at` scrolls a box from `low` to `high`: towards the edge it is near. */
|
|
1058
1273
|
const towards = (at: number, low: number, high: number): number => {
|
|
1059
1274
|
if (at < low + EDGE_SCROLL) {
|
|
1060
1275
|
return -1;
|
|
1061
1276
|
} else if (at > high - EDGE_SCROLL) {
|
|
1062
1277
|
return 1;
|
|
1063
|
-
} else {
|
|
1064
|
-
return 0;
|
|
1065
1278
|
}
|
|
1279
|
+
|
|
1280
|
+
return 0;
|
|
1066
1281
|
};
|
|
1067
1282
|
|
|
1068
|
-
/** While a pointer carries a pane near the reel's edges, the reel scrolls that way,
|
|
1069
|
-
* by the time each frame took, so a drop can reach a column or a place out of view. */
|
|
1070
1283
|
const edgeScroll = (hold: PointerHold): Stream.Stream<never> =>
|
|
1071
1284
|
Stream.callback<never>(() =>
|
|
1072
1285
|
Effect.acquireRelease(
|
|
@@ -1076,51 +1289,57 @@ const edgeScroll = (hold: PointerHold): Stream.Stream<never> =>
|
|
|
1076
1289
|
frame: 0,
|
|
1077
1290
|
last: performance.now(),
|
|
1078
1291
|
};
|
|
1292
|
+
|
|
1079
1293
|
const onMove = (event: PointerEvent): void => {
|
|
1080
1294
|
if (event.pointerId === hold.pointerId) {
|
|
1081
1295
|
state.maybeAt = Option.some({ x: event.clientX, y: event.clientY });
|
|
1082
1296
|
}
|
|
1083
1297
|
};
|
|
1298
|
+
|
|
1084
1299
|
const step = (now: number): void => {
|
|
1085
1300
|
const distance =
|
|
1086
|
-
Math.min(now - state.last, LONGEST_FRAME_MILLIS) *
|
|
1301
|
+
Math.min(now - state.last, LONGEST_FRAME_MILLIS) *
|
|
1302
|
+
EDGE_SCROLL_PIXELS_PER_MILLI;
|
|
1303
|
+
|
|
1087
1304
|
state.last = now;
|
|
1088
1305
|
Option.map(
|
|
1089
1306
|
Option.all({ view: scrollerOf(hold.reelHook), at: state.maybeAt }),
|
|
1090
1307
|
({ view, at }) => {
|
|
1091
1308
|
const rect = view.getBoundingClientRect();
|
|
1092
|
-
view.scrollLeft +=
|
|
1309
|
+
view.scrollLeft +=
|
|
1310
|
+
towards(at.x, rect.left, rect.right) * distance;
|
|
1093
1311
|
view.scrollTop += towards(at.y, rect.top, rect.bottom) * distance;
|
|
1094
|
-
}
|
|
1312
|
+
}
|
|
1095
1313
|
);
|
|
1096
1314
|
state.frame = requestAnimationFrame(step);
|
|
1097
1315
|
};
|
|
1316
|
+
|
|
1098
1317
|
document.addEventListener("pointermove", onMove);
|
|
1099
1318
|
state.frame = requestAnimationFrame(step);
|
|
1319
|
+
|
|
1100
1320
|
return { state, onMove };
|
|
1101
1321
|
}),
|
|
1102
1322
|
({ state, onMove }) =>
|
|
1103
1323
|
Effect.sync(() => {
|
|
1104
1324
|
cancelAnimationFrame(state.frame);
|
|
1105
1325
|
document.removeEventListener("pointermove", onMove);
|
|
1106
|
-
})
|
|
1107
|
-
).pipe(Effect.flatMap(() => Effect.never))
|
|
1326
|
+
})
|
|
1327
|
+
).pipe(Effect.flatMap(() => Effect.never))
|
|
1108
1328
|
);
|
|
1109
1329
|
|
|
1110
1330
|
const SplitterHold = Schema.Struct({
|
|
1111
1331
|
reelHook: Schema.String,
|
|
1112
1332
|
splitter: Splitter,
|
|
1113
|
-
pointerId: Schema.
|
|
1114
|
-
pressX: Schema.
|
|
1115
|
-
pressY: Schema.
|
|
1333
|
+
pointerId: Schema.Finite,
|
|
1334
|
+
pressX: Schema.Finite,
|
|
1335
|
+
pressY: Schema.Finite,
|
|
1116
1336
|
});
|
|
1337
|
+
|
|
1117
1338
|
type SplitterHold = typeof SplitterHold.Type;
|
|
1118
1339
|
|
|
1119
|
-
const heightOf = (element: Element): number =>
|
|
1340
|
+
const heightOf = (element: Element): number =>
|
|
1341
|
+
element.getBoundingClientRect().height;
|
|
1120
1342
|
|
|
1121
|
-
/** The pixels a splitter's share is counted in, read when its drag begins: the reel's width
|
|
1122
|
-
* less a gutter for a width (a column is `width × (view − gutter) − gutter` wide), its
|
|
1123
|
-
* column's panes' height for a pane splitter. */
|
|
1124
1343
|
const scaleOf = (hold: SplitterHold): number =>
|
|
1125
1344
|
Option.getOrElse(
|
|
1126
1345
|
Option.map(scrollerOf(hold.reelHook), (view) =>
|
|
@@ -1130,36 +1349,42 @@ const scaleOf = (hold: SplitterHold): number =>
|
|
|
1130
1349
|
Option.getOrElse(
|
|
1131
1350
|
Option.map(
|
|
1132
1351
|
Option.fromNullishOr(view.querySelector(".reel-gap")),
|
|
1133
|
-
(gap) => gap.getBoundingClientRect().width
|
|
1352
|
+
(gap) => gap.getBoundingClientRect().width
|
|
1134
1353
|
),
|
|
1135
|
-
() => 0
|
|
1354
|
+
() => 0
|
|
1136
1355
|
),
|
|
1137
1356
|
Split: ({ abovePaneId }) =>
|
|
1138
1357
|
Number.sumAll(
|
|
1139
1358
|
Array.map(
|
|
1140
1359
|
Array.fromIterable(
|
|
1141
1360
|
view
|
|
1142
|
-
.querySelector(
|
|
1361
|
+
.querySelector(
|
|
1362
|
+
`[data-reel-slot="${CSS.escape(abovePaneId)}"]`
|
|
1363
|
+
)
|
|
1143
1364
|
?.closest(".reel-column")
|
|
1144
|
-
?.querySelectorAll("[data-reel-slot]") ?? []
|
|
1365
|
+
?.querySelectorAll("[data-reel-slot]") ?? []
|
|
1145
1366
|
),
|
|
1146
|
-
heightOf
|
|
1147
|
-
)
|
|
1367
|
+
heightOf
|
|
1368
|
+
)
|
|
1148
1369
|
),
|
|
1149
|
-
})
|
|
1370
|
+
})
|
|
1150
1371
|
),
|
|
1151
|
-
() => 0
|
|
1372
|
+
() => 0
|
|
1152
1373
|
);
|
|
1153
1374
|
|
|
1154
|
-
/** The dragging pointer's moves, release and cancel, as shares of the splitter's scale. */
|
|
1155
1375
|
const splitterMessages = (hold: SplitterHold): Stream.Stream<Message> =>
|
|
1156
1376
|
Stream.suspend(() => {
|
|
1157
1377
|
const scale = scaleOf(hold);
|
|
1378
|
+
|
|
1158
1379
|
const shareOf = (event: PointerEvent): number => {
|
|
1159
1380
|
const moved =
|
|
1160
|
-
hold.splitter._tag === "Width"
|
|
1381
|
+
hold.splitter._tag === "Width"
|
|
1382
|
+
? event.clientX - hold.pressX
|
|
1383
|
+
: event.clientY - hold.pressY;
|
|
1384
|
+
|
|
1161
1385
|
return scale > 0 ? moved / scale : 0;
|
|
1162
1386
|
};
|
|
1387
|
+
|
|
1163
1388
|
return dragMessages<Message>(hold.pointerId, {
|
|
1164
1389
|
moved: (event) => Message.MovedSplitter({ share: shareOf(event) }),
|
|
1165
1390
|
released: (event) => Message.ReleasedSplitter({ share: shareOf(event) }),
|
|
@@ -1167,7 +1392,10 @@ const splitterMessages = (hold: SplitterHold): Stream.Stream<Message> =>
|
|
|
1167
1392
|
});
|
|
1168
1393
|
});
|
|
1169
1394
|
|
|
1170
|
-
const pointerHoldOf = (
|
|
1395
|
+
const pointerHoldOf = (
|
|
1396
|
+
model: Model,
|
|
1397
|
+
isCarryingOnly: boolean
|
|
1398
|
+
): Option.Option<PointerHold> =>
|
|
1171
1399
|
Option.flatMap(model.maybeHeld, ({ paneId, by }) =>
|
|
1172
1400
|
By.match(by, {
|
|
1173
1401
|
Keyboard: () => Option.none(),
|
|
@@ -1175,47 +1403,57 @@ const pointerHoldOf = (model: Model, isCarryingOnly: boolean): Option.Option<Poi
|
|
|
1175
1403
|
isCarryingOnly && !isCarrying
|
|
1176
1404
|
? Option.none()
|
|
1177
1405
|
: Option.some({ reelHook: model.id, paneId, pointerId }),
|
|
1178
|
-
})
|
|
1406
|
+
})
|
|
1179
1407
|
);
|
|
1180
1408
|
|
|
1181
1409
|
const reelSubscriptions = Subscription.make<Model, Message>()((entry) => ({
|
|
1182
1410
|
pointer: entry(
|
|
1183
1411
|
{ maybeHold: Schema.Option(PointerHold) },
|
|
1184
1412
|
{
|
|
1185
|
-
modelToDependencies: (model) => ({
|
|
1413
|
+
modelToDependencies: (model) => ({
|
|
1414
|
+
maybeHold: pointerHoldOf(model, false),
|
|
1415
|
+
}),
|
|
1186
1416
|
dependenciesToStream: ({ maybeHold }) =>
|
|
1187
1417
|
Option.match(maybeHold, {
|
|
1188
1418
|
onNone: () => Stream.empty,
|
|
1189
1419
|
onSome: (hold) => Stream.merge(pointerMessages(hold), markDragging),
|
|
1190
1420
|
}),
|
|
1191
|
-
}
|
|
1421
|
+
}
|
|
1192
1422
|
),
|
|
1193
1423
|
edge: entry(
|
|
1194
1424
|
{ maybeHold: Schema.Option(PointerHold) },
|
|
1195
1425
|
{
|
|
1196
|
-
modelToDependencies: (model) => ({
|
|
1426
|
+
modelToDependencies: (model) => ({
|
|
1427
|
+
maybeHold: pointerHoldOf(model, true),
|
|
1428
|
+
}),
|
|
1197
1429
|
dependenciesToStream: ({ maybeHold }) =>
|
|
1198
|
-
Option.match(maybeHold, {
|
|
1199
|
-
|
|
1430
|
+
Option.match(maybeHold, {
|
|
1431
|
+
onNone: () => Stream.empty,
|
|
1432
|
+
onSome: edgeScroll,
|
|
1433
|
+
}),
|
|
1434
|
+
}
|
|
1200
1435
|
),
|
|
1201
1436
|
resize: entry(
|
|
1202
1437
|
{ maybeHold: Schema.Option(SplitterHold) },
|
|
1203
1438
|
{
|
|
1204
1439
|
modelToDependencies: (model) => ({
|
|
1205
|
-
maybeHold: Option.map(
|
|
1206
|
-
|
|
1207
|
-
splitter,
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1440
|
+
maybeHold: Option.map(
|
|
1441
|
+
model.maybeResizing,
|
|
1442
|
+
({ splitter, pointerId, pressX, pressY }) => ({
|
|
1443
|
+
reelHook: model.id,
|
|
1444
|
+
splitter,
|
|
1445
|
+
pointerId,
|
|
1446
|
+
pressX,
|
|
1447
|
+
pressY,
|
|
1448
|
+
})
|
|
1449
|
+
),
|
|
1212
1450
|
}),
|
|
1213
1451
|
dependenciesToStream: ({ maybeHold }) =>
|
|
1214
1452
|
Option.match(maybeHold, {
|
|
1215
1453
|
onNone: () => Stream.empty,
|
|
1216
1454
|
onSome: (hold) => Stream.merge(splitterMessages(hold), markDragging),
|
|
1217
1455
|
}),
|
|
1218
|
-
}
|
|
1456
|
+
}
|
|
1219
1457
|
),
|
|
1220
1458
|
escape: entry(
|
|
1221
1459
|
{ isHolding: Schema.Boolean },
|
|
@@ -1225,7 +1463,7 @@ const reelSubscriptions = Subscription.make<Model, Message>()((entry) => ({
|
|
|
1225
1463
|
}),
|
|
1226
1464
|
dependenciesToStream: ({ isHolding: isHoldingNow }) =>
|
|
1227
1465
|
isHoldingNow ? escapeKeys(Message.PressedEscape()) : Stream.empty,
|
|
1228
|
-
}
|
|
1466
|
+
}
|
|
1229
1467
|
),
|
|
1230
1468
|
}));
|
|
1231
1469
|
|
|
@@ -1237,28 +1475,29 @@ const reelSubscriptions = Subscription.make<Model, Message>()((entry) => ({
|
|
|
1237
1475
|
export const subscriptions = <Prefix extends string>(keyPrefix: Prefix) =>
|
|
1238
1476
|
prefixKeys(keyPrefix, reelSubscriptions);
|
|
1239
1477
|
|
|
1240
|
-
// MOUNT
|
|
1241
|
-
|
|
1242
1478
|
/** Sizes the copy that follows the pointer to what it lifts, and keeps the pointer where it
|
|
1243
1479
|
* pressed. Measures the source once, when the copy appears. */
|
|
1244
1480
|
export const SizeLiftedPane = Mount.define("SizeLiftedPane", {
|
|
1245
|
-
args: {
|
|
1481
|
+
args: {
|
|
1482
|
+
sourceSelector: Schema.String,
|
|
1483
|
+
pressX: Schema.Finite,
|
|
1484
|
+
pressY: Schema.Finite,
|
|
1485
|
+
},
|
|
1246
1486
|
messages: [Message.CompletedSizeLiftedPane],
|
|
1247
1487
|
execute: ({ element, sourceSelector, pressX, pressY }) =>
|
|
1248
1488
|
Effect.sync(() => {
|
|
1249
1489
|
measureLift(element, sourceSelector, pressX, pressY);
|
|
1490
|
+
|
|
1250
1491
|
return Message.CompletedSizeLiftedPane();
|
|
1251
1492
|
}),
|
|
1252
1493
|
});
|
|
1253
1494
|
|
|
1254
|
-
// VIEW
|
|
1255
|
-
|
|
1256
1495
|
/** What the reel hands `toPaneView` for each pane: put `lead` in the Window's `lead` and give
|
|
1257
1496
|
* it `id`. */
|
|
1258
1497
|
export type PaneRender = Readonly<{
|
|
1259
1498
|
/** The title bar's `lead`: the pane's grip, a quiet glyph button named "Move <label>", or
|
|
1260
1499
|
* nothing under tabs, where a pane does not move. */
|
|
1261
|
-
lead:
|
|
1500
|
+
lead: readonly Html[];
|
|
1262
1501
|
/** The window's id, unique in the document. */
|
|
1263
1502
|
id: string;
|
|
1264
1503
|
}>;
|
|
@@ -1278,7 +1517,7 @@ export type ViewInputs = Readonly<{
|
|
|
1278
1517
|
* their tabs (`Tabs`). Pass the same to `perform`. */
|
|
1279
1518
|
arrangement?: Arrangement;
|
|
1280
1519
|
/** What a pane's tab prints before its label: a kind glyph. Nothing when not given. */
|
|
1281
|
-
toTabLeadView?: (pane: Pane) =>
|
|
1520
|
+
toTabLeadView?: (pane: Pane) => readonly Html[];
|
|
1282
1521
|
}>;
|
|
1283
1522
|
|
|
1284
1523
|
type ReelInfo = Readonly<{
|
|
@@ -1293,10 +1532,9 @@ type ReelInfo = Readonly<{
|
|
|
1293
1532
|
|
|
1294
1533
|
const helpId = (model: Model): string => `${model.id}-grip-help`;
|
|
1295
1534
|
|
|
1296
|
-
/** The share of the reel or the column a splitter's arrow key moves. */
|
|
1297
1535
|
const SPLITTER_STEP = 0.05;
|
|
1298
1536
|
|
|
1299
|
-
const HELD_STEPS:
|
|
1537
|
+
const HELD_STEPS: Record.ReadonlyRecord<string, Step> = {
|
|
1300
1538
|
ArrowUp: "Up",
|
|
1301
1539
|
ArrowDown: "Down",
|
|
1302
1540
|
ArrowLeft: "Left",
|
|
@@ -1305,57 +1543,75 @@ const HELD_STEPS: Readonly<Record<string, Step>> = {
|
|
|
1305
1543
|
|
|
1306
1544
|
const isDropKey = (key: string): boolean => key === " " || key === "Enter";
|
|
1307
1545
|
|
|
1308
|
-
/** The anchor every pane is pinned to under tabs: the one slot, the reel's full size. */
|
|
1309
1546
|
const STAGE_ANCHOR = "--reel-stage";
|
|
1310
1547
|
|
|
1311
|
-
/** The anchor that pins a pane to its slot. Pane ids are the application's, so the name is
|
|
1312
|
-
* the pane's place in the id order, which the slot and the pane read from one list. */
|
|
1313
1548
|
const anchorName = (index: number): string => `--reel-${index}`;
|
|
1314
1549
|
|
|
1315
|
-
/** The panes in their layer's order: by id, which no move changes. */
|
|
1316
1550
|
const byId = Order.mapInput(Order.String, (pane: Pane) => pane.id);
|
|
1317
1551
|
|
|
1318
|
-
|
|
1552
|
+
const stableDomOrder = (layout: Layout): readonly Pane[] =>
|
|
1553
|
+
Array.sort(
|
|
1554
|
+
Array.flatMap(layout, (column) => column.panes),
|
|
1555
|
+
byId
|
|
1556
|
+
);
|
|
1557
|
+
|
|
1319
1558
|
const markOf = (model: Model, layout: Layout): Option.Option<Target> =>
|
|
1320
1559
|
Option.flatMap(Option.filter(model.maybeHeld, isCarried), (held) =>
|
|
1321
1560
|
Option.filter(held.maybeTarget, (target) =>
|
|
1322
|
-
Option.isSome(requestOf(layout, held.paneId, target))
|
|
1323
|
-
)
|
|
1561
|
+
Option.isSome(requestOf(layout, held.paneId, target))
|
|
1562
|
+
)
|
|
1324
1563
|
);
|
|
1325
1564
|
|
|
1326
1565
|
const carriedIdOf = (model: Model): Option.Option<string> =>
|
|
1327
1566
|
Option.map(Option.filter(model.maybeHeld, isCarried), ({ paneId }) => paneId);
|
|
1328
1567
|
|
|
1329
1568
|
const gripView = (model: Model, pane: Pane, h: HtmlBuilder<Message>): Html => {
|
|
1330
|
-
const maybeHeldHere = Option.filter(
|
|
1569
|
+
const maybeHeldHere = Option.filter(
|
|
1570
|
+
model.maybeHeld,
|
|
1571
|
+
(held) => held.paneId === pane.id
|
|
1572
|
+
);
|
|
1573
|
+
|
|
1331
1574
|
const isHeld = Option.exists(maybeHeldHere, isCarried);
|
|
1332
|
-
const isKeyboardHeld = Option.exists(maybeHeldHere, (held) => held.by._tag === "Keyboard");
|
|
1333
1575
|
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1576
|
+
const isKeyboardHeld = Option.exists(
|
|
1577
|
+
maybeHeldHere,
|
|
1578
|
+
(held) => held.by._tag === "Keyboard"
|
|
1579
|
+
);
|
|
1580
|
+
|
|
1581
|
+
const onGripKey: Attribute<Message> = h.OnKeyDownPreventDefault(
|
|
1582
|
+
(key, modifiers) => {
|
|
1583
|
+
if (!isPlain(modifiers)) {
|
|
1584
|
+
return Option.none();
|
|
1585
|
+
} else if (isKeyboardHeld) {
|
|
1586
|
+
return isDropKey(key)
|
|
1587
|
+
? Option.some(Message.DroppedHeld())
|
|
1588
|
+
: Option.map(Record.get(HELD_STEPS, key), (step) =>
|
|
1589
|
+
Message.SteppedHeld({ step })
|
|
1590
|
+
);
|
|
1591
|
+
}
|
|
1592
|
+
|
|
1346
1593
|
return Option.liftPredicate(
|
|
1347
1594
|
Message.PressedGripKey({ paneId: pane.id }),
|
|
1348
|
-
() => isIdle(model) && isDropKey(key)
|
|
1595
|
+
() => isIdle(model) && isDropKey(key)
|
|
1349
1596
|
);
|
|
1350
1597
|
}
|
|
1351
|
-
|
|
1598
|
+
);
|
|
1352
1599
|
|
|
1353
1600
|
const onGripPress: Attribute<Message> = h.OnPointerDown(
|
|
1354
|
-
(
|
|
1601
|
+
(
|
|
1602
|
+
_pointerType,
|
|
1603
|
+
button,
|
|
1604
|
+
_screenX,
|
|
1605
|
+
_screenY,
|
|
1606
|
+
_time,
|
|
1607
|
+
clientX,
|
|
1608
|
+
clientY,
|
|
1609
|
+
pointerId
|
|
1610
|
+
) =>
|
|
1355
1611
|
Option.liftPredicate(
|
|
1356
1612
|
Message.PressedGrip({ paneId: pane.id, pointerId, clientX, clientY }),
|
|
1357
|
-
() => isIdle(model) && button === LEFT_BUTTON
|
|
1358
|
-
)
|
|
1613
|
+
() => isIdle(model) && button === LEFT_BUTTON
|
|
1614
|
+
)
|
|
1359
1615
|
);
|
|
1360
1616
|
|
|
1361
1617
|
return IconButton.view(
|
|
@@ -1373,15 +1629,14 @@ const gripView = (model: Model, pane: Pane, h: HtmlBuilder<Message>): Html => {
|
|
|
1373
1629
|
...(isKeyboardHeld ? [h.OnBlur(Message.LeftGrip())] : []),
|
|
1374
1630
|
],
|
|
1375
1631
|
},
|
|
1376
|
-
h
|
|
1632
|
+
h
|
|
1377
1633
|
);
|
|
1378
1634
|
};
|
|
1379
1635
|
|
|
1380
|
-
/** A splitter's handlers: a pointer drags it, and its arrows step it by `SPLITTER_STEP`. */
|
|
1381
1636
|
const reelSplitterAttributes = (
|
|
1382
1637
|
model: Model,
|
|
1383
1638
|
splitter: Splitter,
|
|
1384
|
-
h: HtmlBuilder<Message
|
|
1639
|
+
h: HtmlBuilder<Message>
|
|
1385
1640
|
): ReadonlyArray<Attribute<Message>> =>
|
|
1386
1641
|
splitterAttributes(
|
|
1387
1642
|
{
|
|
@@ -1390,25 +1645,28 @@ const reelSplitterAttributes = (
|
|
|
1390
1645
|
onPress: (pointerId, clientX, clientY) =>
|
|
1391
1646
|
Message.PressedSplitter({ splitter, pointerId, clientX, clientY }),
|
|
1392
1647
|
onStep: (direction) =>
|
|
1393
|
-
Message.PressedSplitterKey({
|
|
1648
|
+
Message.PressedSplitterKey({
|
|
1649
|
+
splitter,
|
|
1650
|
+
share: direction * SPLITTER_STEP,
|
|
1651
|
+
}),
|
|
1394
1652
|
},
|
|
1395
|
-
h
|
|
1653
|
+
h
|
|
1396
1654
|
);
|
|
1397
1655
|
|
|
1398
|
-
/** The pane a drop into `column` is marked on, and the class that marks it: the pane it would
|
|
1399
|
-
* land before, or the last one when it would land at the end, the carried pane left out. */
|
|
1400
1656
|
const dropMarkOf = (
|
|
1401
1657
|
info: ReelInfo,
|
|
1402
|
-
column: Column
|
|
1658
|
+
column: Column
|
|
1403
1659
|
): Option.Option<Readonly<{ paneId: string; markClass: string }>> =>
|
|
1404
1660
|
Option.flatMap(info.maybeMark, (mark) => {
|
|
1405
1661
|
if (mark._tag !== "Into" || mark.columnId !== column.id) {
|
|
1406
1662
|
return Option.none();
|
|
1407
1663
|
}
|
|
1664
|
+
|
|
1408
1665
|
const others = Array.filter(
|
|
1409
1666
|
column.panes,
|
|
1410
|
-
(pane) => !Option.contains(info.maybeCarriedId, pane.id)
|
|
1667
|
+
(pane) => !Option.contains(info.maybeCarriedId, pane.id)
|
|
1411
1668
|
);
|
|
1669
|
+
|
|
1412
1670
|
return Option.orElse(
|
|
1413
1671
|
Option.map(Array.get(others, mark.index), ({ id }) => ({
|
|
1414
1672
|
paneId: id,
|
|
@@ -1417,35 +1675,48 @@ const dropMarkOf = (
|
|
|
1417
1675
|
() =>
|
|
1418
1676
|
Option.map(
|
|
1419
1677
|
Option.filter(Array.last(others), () => mark.index >= others.length),
|
|
1420
|
-
({ id }) => ({ paneId: id, markClass: " drop-after" })
|
|
1421
|
-
)
|
|
1678
|
+
({ id }) => ({ paneId: id, markClass: " drop-after" })
|
|
1679
|
+
)
|
|
1422
1680
|
);
|
|
1423
1681
|
});
|
|
1424
1682
|
|
|
1425
|
-
const isGapMarked = (
|
|
1683
|
+
const isGapMarked = (
|
|
1684
|
+
info: ReelInfo,
|
|
1685
|
+
maybeBeforeColumnId: Option.Option<string>
|
|
1686
|
+
): boolean =>
|
|
1426
1687
|
Option.exists(
|
|
1427
1688
|
info.maybeMark,
|
|
1428
|
-
(mark) =>
|
|
1689
|
+
(mark) =>
|
|
1690
|
+
mark._tag === "Gap" &&
|
|
1691
|
+
Equal.equals(mark.maybeBeforeColumnId, maybeBeforeColumnId)
|
|
1429
1692
|
);
|
|
1430
1693
|
|
|
1431
1694
|
const slotView = (
|
|
1432
1695
|
anchors: ReadonlyMap<string, string>,
|
|
1433
1696
|
maybeDropMark: Option.Option<Readonly<{ paneId: string; markClass: string }>>,
|
|
1434
1697
|
pane: Pane,
|
|
1435
|
-
h: HtmlBuilder<Message
|
|
1698
|
+
h: HtmlBuilder<Message>
|
|
1436
1699
|
): Html =>
|
|
1437
1700
|
h.keyed("div")(pane.id, [
|
|
1438
1701
|
h.Class(
|
|
1439
1702
|
`reel-slot${Option.match(
|
|
1440
1703
|
Option.filter(maybeDropMark, ({ paneId }) => paneId === pane.id),
|
|
1441
|
-
{ onNone: () => "", onSome: ({ markClass }) => markClass }
|
|
1442
|
-
)}
|
|
1704
|
+
{ onNone: () => "", onSome: ({ markClass }) => markClass }
|
|
1705
|
+
)}`
|
|
1443
1706
|
),
|
|
1444
1707
|
h.DataAttribute("reel-slot", pane.id),
|
|
1445
|
-
h.Style({
|
|
1708
|
+
h.Style({
|
|
1709
|
+
"--reel-weight": `${pane.weight}`,
|
|
1710
|
+
"--reel-anchor": anchors.get(pane.id) ?? "none",
|
|
1711
|
+
}),
|
|
1446
1712
|
]);
|
|
1447
1713
|
|
|
1448
|
-
const splitView = (
|
|
1714
|
+
const splitView = (
|
|
1715
|
+
model: Model,
|
|
1716
|
+
above: Pane,
|
|
1717
|
+
share: number,
|
|
1718
|
+
h: HtmlBuilder<Message>
|
|
1719
|
+
): Html =>
|
|
1449
1720
|
h.keyed("div")(`split:${above.id}`, [
|
|
1450
1721
|
h.Class("reel-split"),
|
|
1451
1722
|
h.Role("separator"),
|
|
@@ -1455,7 +1726,11 @@ const splitView = (model: Model, above: Pane, share: number, h: HtmlBuilder<Mess
|
|
|
1455
1726
|
h.AriaValuenow(Math.round(share * 100)),
|
|
1456
1727
|
h.Tabindex(0),
|
|
1457
1728
|
h.DataAttribute("reel-split", above.id),
|
|
1458
|
-
...reelSplitterAttributes(
|
|
1729
|
+
...reelSplitterAttributes(
|
|
1730
|
+
model,
|
|
1731
|
+
Splitter.Split({ abovePaneId: above.id }),
|
|
1732
|
+
h
|
|
1733
|
+
),
|
|
1459
1734
|
]);
|
|
1460
1735
|
|
|
1461
1736
|
const columnView = (
|
|
@@ -1463,19 +1738,21 @@ const columnView = (
|
|
|
1463
1738
|
anchors: ReadonlyMap<string, string>,
|
|
1464
1739
|
column: Column,
|
|
1465
1740
|
index: number,
|
|
1466
|
-
h: HtmlBuilder<Message
|
|
1467
|
-
):
|
|
1741
|
+
h: HtmlBuilder<Message>
|
|
1742
|
+
): readonly Html[] => {
|
|
1468
1743
|
const { model, layout } = info;
|
|
1469
1744
|
const total = Number.sumAll(Array.map(column.panes, (pane) => pane.weight));
|
|
1470
1745
|
const maybeDropMark = dropMarkOf(info, column);
|
|
1746
|
+
|
|
1471
1747
|
const stack = Array.flatMap(column.panes, (pane, row) => [
|
|
1472
1748
|
...Array.fromOption(
|
|
1473
1749
|
Option.map(Array.get(column.panes, row - 1), (above) =>
|
|
1474
|
-
splitView(model, above, total > 0 ? above.weight / total : 0, h)
|
|
1475
|
-
)
|
|
1750
|
+
splitView(model, above, total > 0 ? above.weight / total : 0, h)
|
|
1751
|
+
)
|
|
1476
1752
|
),
|
|
1477
1753
|
slotView(anchors, maybeDropMark, pane, h),
|
|
1478
1754
|
]);
|
|
1755
|
+
|
|
1479
1756
|
const maybeNextId = Option.map(Array.get(layout, index + 1), ({ id }) => id);
|
|
1480
1757
|
|
|
1481
1758
|
return [
|
|
@@ -1487,10 +1764,12 @@ const columnView = (
|
|
|
1487
1764
|
h.DataAttribute("reel-hook", columnHook(model, column.id)),
|
|
1488
1765
|
h.Style({ "--reel-width": `${column.width}` }),
|
|
1489
1766
|
],
|
|
1490
|
-
stack
|
|
1767
|
+
stack
|
|
1491
1768
|
),
|
|
1492
1769
|
h.keyed("div")(`resize:${column.id}`, [
|
|
1493
|
-
h.Class(
|
|
1770
|
+
h.Class(
|
|
1771
|
+
`reel-gap reel-resize${isGapMarked(info, maybeNextId) ? " drop-here" : ""}`
|
|
1772
|
+
),
|
|
1494
1773
|
h.Role("separator"),
|
|
1495
1774
|
h.AriaLabel(fill(COPY.widthLabel, { column: index + 1 })),
|
|
1496
1775
|
h.AriaValuemin(0),
|
|
@@ -1499,35 +1778,35 @@ const columnView = (
|
|
|
1499
1778
|
h.AriaValuetext(widthWords(column.width)),
|
|
1500
1779
|
h.Tabindex(0),
|
|
1501
1780
|
h.DataAttribute("reel-resize", column.id),
|
|
1502
|
-
...reelSplitterAttributes(
|
|
1781
|
+
...reelSplitterAttributes(
|
|
1782
|
+
model,
|
|
1783
|
+
Splitter.Width({ columnId: column.id }),
|
|
1784
|
+
h
|
|
1785
|
+
),
|
|
1503
1786
|
]),
|
|
1504
1787
|
];
|
|
1505
1788
|
};
|
|
1506
1789
|
|
|
1507
1790
|
const paneLayerView = (
|
|
1508
1791
|
info: ReelInfo,
|
|
1509
|
-
|
|
1792
|
+
panesInDomOrder: readonly Pane[],
|
|
1510
1793
|
anchors: ReadonlyMap<string, string>,
|
|
1511
|
-
h: HtmlBuilder<Message
|
|
1794
|
+
h: HtmlBuilder<Message>
|
|
1512
1795
|
): Html => {
|
|
1513
1796
|
const { model } = info;
|
|
1514
1797
|
|
|
1515
|
-
// NOTE: the panes keep one order in the page, by id, whatever the layout or the arrangement:
|
|
1516
|
-
// a move or a change to tabs changes only where each is anchored, so no pane's element is
|
|
1517
|
-
// taken out and put back, which would drop focus, a terminal's scroll and whatever a Mount
|
|
1518
|
-
// holds inside it. Under tabs the panes behind the focused one are hidden, not removed, and
|
|
1519
|
-
// keep their size, so a terminal sized by its box is not resized as the tabs change.
|
|
1520
1798
|
return h.div(
|
|
1521
1799
|
[h.Class("reel-panes")],
|
|
1522
|
-
Array.map(
|
|
1800
|
+
Array.map(panesInDomOrder, (pane) => {
|
|
1523
1801
|
const isFocused = Option.contains(info.maybeFocusedId, pane.id);
|
|
1524
1802
|
const isHeld = Option.contains(info.maybeCarriedId, pane.id);
|
|
1525
1803
|
const isBehind = info.isTabbed && !isFocused;
|
|
1804
|
+
|
|
1526
1805
|
return h.keyed("div")(
|
|
1527
1806
|
pane.id,
|
|
1528
1807
|
[
|
|
1529
1808
|
h.Class(
|
|
1530
|
-
`reel-pane${isFocused ? " focused" : ""}${isHeld ? " drag-dim" : ""}${isBehind ? " behind" : ""}
|
|
1809
|
+
`reel-pane${isFocused ? " focused" : ""}${isHeld ? " drag-dim" : ""}${isBehind ? " behind" : ""}`
|
|
1531
1810
|
),
|
|
1532
1811
|
h.DataAttribute("reel-pane", paneHook(model, pane.id)),
|
|
1533
1812
|
h.Style({ "--reel-anchor": anchors.get(pane.id) ?? "none" }),
|
|
@@ -1540,15 +1819,16 @@ const paneLayerView = (
|
|
|
1540
1819
|
lead: info.isTabbed ? [] : [gripView(model, pane, h)],
|
|
1541
1820
|
id: `${model.id}-${pane.id}`,
|
|
1542
1821
|
}),
|
|
1543
|
-
]
|
|
1822
|
+
]
|
|
1544
1823
|
);
|
|
1545
|
-
})
|
|
1824
|
+
})
|
|
1546
1825
|
);
|
|
1547
1826
|
};
|
|
1548
1827
|
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1828
|
+
const liftedCopyView = (
|
|
1829
|
+
info: ReelInfo,
|
|
1830
|
+
h: HtmlBuilder<Message>
|
|
1831
|
+
): readonly Html[] => {
|
|
1552
1832
|
const { model, layout } = info;
|
|
1553
1833
|
|
|
1554
1834
|
return Array.fromOption(
|
|
@@ -1568,7 +1848,7 @@ const liftedCopyView = (info: ReelInfo, h: HtmlBuilder<Message>): ReadonlyArray<
|
|
|
1568
1848
|
sourceSelector: `[data-reel-pane="${CSS.escape(paneHook(model, held.paneId))}"]`,
|
|
1569
1849
|
pressX,
|
|
1570
1850
|
pressY,
|
|
1571
|
-
})
|
|
1851
|
+
})
|
|
1572
1852
|
),
|
|
1573
1853
|
],
|
|
1574
1854
|
[
|
|
@@ -1580,51 +1860,56 @@ const liftedCopyView = (info: ReelInfo, h: HtmlBuilder<Message>): ReadonlyArray<
|
|
|
1580
1860
|
[
|
|
1581
1861
|
h.span(
|
|
1582
1862
|
[h.Class("panel-lead")],
|
|
1583
|
-
[
|
|
1863
|
+
[
|
|
1864
|
+
h.span(
|
|
1865
|
+
[h.Class("iconbtn quiet")],
|
|
1866
|
+
[Glyph.view({ name: "grip" }, h)]
|
|
1867
|
+
),
|
|
1868
|
+
]
|
|
1584
1869
|
),
|
|
1585
1870
|
h.h2([], [heldLabel(layout, held)]),
|
|
1586
|
-
]
|
|
1871
|
+
]
|
|
1587
1872
|
),
|
|
1588
|
-
]
|
|
1873
|
+
]
|
|
1589
1874
|
),
|
|
1590
|
-
]
|
|
1875
|
+
]
|
|
1591
1876
|
),
|
|
1592
|
-
() => isCarrying
|
|
1877
|
+
() => isCarrying
|
|
1593
1878
|
),
|
|
1594
|
-
})
|
|
1595
|
-
)
|
|
1879
|
+
})
|
|
1880
|
+
)
|
|
1596
1881
|
);
|
|
1597
1882
|
};
|
|
1598
1883
|
|
|
1599
|
-
/** The tab list under tabs: a tab per pane in reading order, the focused pane's selected. A
|
|
1600
|
-
* press shows its pane and puts the keyboard in it; the side arrows (wrapping), Home and End
|
|
1601
|
-
* select as they move and keep the keyboard on the tabs, only the selected tab being in the
|
|
1602
|
-
* Tab order. A modified arrow is the application's. */
|
|
1603
1884
|
const tabListView = (
|
|
1604
1885
|
info: ReelInfo,
|
|
1605
1886
|
label: string,
|
|
1606
|
-
toTabLeadView: (pane: Pane) =>
|
|
1607
|
-
h: HtmlBuilder<Message
|
|
1887
|
+
toTabLeadView: (pane: Pane) => readonly Html[],
|
|
1888
|
+
h: HtmlBuilder<Message>
|
|
1608
1889
|
): Html => {
|
|
1609
1890
|
const { model, layout } = info;
|
|
1610
1891
|
const panes = readingOrder(layout);
|
|
1892
|
+
|
|
1611
1893
|
const stepTo = (index: number): Option.Option<Message> =>
|
|
1612
|
-
Option.map(
|
|
1613
|
-
|
|
1894
|
+
Option.map(
|
|
1895
|
+
Array.get(panes, (index + panes.length) % panes.length),
|
|
1896
|
+
({ id }) => Message.SteppedTab({ paneId: id })
|
|
1614
1897
|
);
|
|
1898
|
+
|
|
1615
1899
|
const keyOf = (index: number, key: string): Option.Option<Message> =>
|
|
1616
1900
|
Match.value(key).pipe(
|
|
1617
1901
|
Match.when("ArrowLeft", () => stepTo(index - 1)),
|
|
1618
1902
|
Match.when("ArrowRight", () => stepTo(index + 1)),
|
|
1619
1903
|
Match.when("Home", () => stepTo(0)),
|
|
1620
1904
|
Match.when("End", () => stepTo(panes.length - 1)),
|
|
1621
|
-
Match.orElse(() => Option.none())
|
|
1905
|
+
Match.orElse(() => Option.none())
|
|
1622
1906
|
);
|
|
1623
1907
|
|
|
1624
1908
|
return h.div(
|
|
1625
1909
|
[h.Class("nav tabs reel-tabs"), h.Role("tablist"), h.AriaLabel(label)],
|
|
1626
1910
|
Array.map(panes, (pane, index) => {
|
|
1627
1911
|
const isSelected = Option.contains(info.maybeFocusedId, pane.id);
|
|
1912
|
+
|
|
1628
1913
|
return h.keyed("button")(
|
|
1629
1914
|
pane.id,
|
|
1630
1915
|
[
|
|
@@ -1636,22 +1921,24 @@ const tabListView = (
|
|
|
1636
1921
|
h.DataAttribute("reel-tab", tabHook(model, pane.id)),
|
|
1637
1922
|
h.OnClick(Message.PressedTab({ paneId: pane.id })),
|
|
1638
1923
|
h.OnKeyDownPreventDefault((key, modifiers) =>
|
|
1639
|
-
isPlain(modifiers) ? keyOf(index, key) : Option.none()
|
|
1924
|
+
isPlain(modifiers) ? keyOf(index, key) : Option.none()
|
|
1640
1925
|
),
|
|
1641
1926
|
],
|
|
1642
|
-
[
|
|
1927
|
+
[
|
|
1928
|
+
...toTabLeadView(pane),
|
|
1929
|
+
h.span([h.Class("reel-tab-words")], [pane.label]),
|
|
1930
|
+
]
|
|
1643
1931
|
);
|
|
1644
|
-
})
|
|
1932
|
+
})
|
|
1645
1933
|
);
|
|
1646
1934
|
};
|
|
1647
1935
|
|
|
1648
|
-
const NO_TAB_LEAD = ():
|
|
1936
|
+
const NO_TAB_LEAD = (): readonly Html[] => [];
|
|
1649
1937
|
|
|
1650
|
-
/** The layout as it prints, with a dragged splitter's resize shown before it is asked for. */
|
|
1651
1938
|
const previewed = (model: Model, layout: Layout): Layout =>
|
|
1652
1939
|
Option.match(
|
|
1653
1940
|
Option.flatMap(model.maybeResizing, ({ maybeResize }) => maybeResize),
|
|
1654
|
-
{ onNone: () => layout, onSome: (resize) => apply(layout, resize) }
|
|
1941
|
+
{ onNone: () => layout, onSome: (resize) => apply(layout, resize) }
|
|
1655
1942
|
);
|
|
1656
1943
|
|
|
1657
1944
|
/**
|
|
@@ -1673,76 +1960,87 @@ const previewed = (model: Model, layout: Layout): Layout =>
|
|
|
1673
1960
|
* full size where the columns were. Every pane is pinned to it, the focused one shown and the
|
|
1674
1961
|
* others `.behind`, hidden and inert; there are no grips and no splitters.
|
|
1675
1962
|
*/
|
|
1676
|
-
export const view = defineView<Model, Message, ViewInputs>(
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
)
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
maybeCarriedId: carriedIdOf(model),
|
|
1698
|
-
};
|
|
1963
|
+
export const view = defineView<Model, Message, ViewInputs>(
|
|
1964
|
+
(model, viewInputs, h): Html => {
|
|
1965
|
+
const {
|
|
1966
|
+
label,
|
|
1967
|
+
toPaneView,
|
|
1968
|
+
arrangement = "Strip",
|
|
1969
|
+
toTabLeadView = NO_TAB_LEAD,
|
|
1970
|
+
} = viewInputs;
|
|
1971
|
+
|
|
1972
|
+
const isTabbed = arrangement === "Tabs";
|
|
1973
|
+
const layout = previewed(model, viewInputs.layout);
|
|
1974
|
+
|
|
1975
|
+
const panesInDomOrder = stableDomOrder(layout);
|
|
1976
|
+
|
|
1977
|
+
const anchors = new Map(
|
|
1978
|
+
Array.map(
|
|
1979
|
+
panesInDomOrder,
|
|
1980
|
+
(pane, index) =>
|
|
1981
|
+
[pane.id, isTabbed ? STAGE_ANCHOR : anchorName(index)] as const
|
|
1982
|
+
)
|
|
1983
|
+
);
|
|
1699
1984
|
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
: ""
|
|
1710
|
-
}`,
|
|
1711
|
-
),
|
|
1712
|
-
]),
|
|
1713
|
-
...Array.flatMap(layout, (column, index) => columnView(info, anchors, column, index, h)),
|
|
1714
|
-
];
|
|
1985
|
+
const info: ReelInfo = {
|
|
1986
|
+
model,
|
|
1987
|
+
layout,
|
|
1988
|
+
isTabbed,
|
|
1989
|
+
toPaneView,
|
|
1990
|
+
maybeFocusedId: focusedPaneId(model, layout),
|
|
1991
|
+
maybeMark: markOf(model, layout),
|
|
1992
|
+
maybeCarriedId: carriedIdOf(model),
|
|
1993
|
+
};
|
|
1715
1994
|
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
...(isTabbed
|
|
1732
|
-
? [
|
|
1733
|
-
h.div([
|
|
1734
|
-
h.Class("reel-slot reel-stage"),
|
|
1735
|
-
h.Style({ "--reel-anchor": STAGE_ANCHOR }),
|
|
1736
|
-
]),
|
|
1737
|
-
]
|
|
1738
|
-
: strip()),
|
|
1739
|
-
paneLayerView(info, panes, anchors, h),
|
|
1740
|
-
],
|
|
1741
|
-
),
|
|
1742
|
-
],
|
|
1995
|
+
const strip = (): readonly Html[] => [
|
|
1996
|
+
h.keyed("div")("gap:start", [
|
|
1997
|
+
h.Class(
|
|
1998
|
+
`reel-gap${
|
|
1999
|
+
isGapMarked(
|
|
2000
|
+
info,
|
|
2001
|
+
Option.map(Array.head(layout), ({ id }) => id)
|
|
2002
|
+
)
|
|
2003
|
+
? " drop-here"
|
|
2004
|
+
: ""
|
|
2005
|
+
}`
|
|
2006
|
+
),
|
|
2007
|
+
]),
|
|
2008
|
+
...Array.flatMap(layout, (column, index) =>
|
|
2009
|
+
columnView(info, anchors, column, index, h)
|
|
1743
2010
|
),
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
2011
|
+
];
|
|
2012
|
+
|
|
2013
|
+
return h.div(
|
|
2014
|
+
[
|
|
2015
|
+
h.Class(isTabbed ? "reel tabbed" : "reel"),
|
|
2016
|
+
h.Role("group"),
|
|
2017
|
+
h.AriaLabel(label),
|
|
2018
|
+
h.DataAttribute("reel", model.id),
|
|
2019
|
+
],
|
|
2020
|
+
[
|
|
2021
|
+
...(isTabbed ? [tabListView(info, label, toTabLeadView, h)] : []),
|
|
2022
|
+
h.div(
|
|
2023
|
+
[h.Class("reel-view")],
|
|
2024
|
+
[
|
|
2025
|
+
h.div(
|
|
2026
|
+
[h.Class("reel-track")],
|
|
2027
|
+
[
|
|
2028
|
+
...(isTabbed
|
|
2029
|
+
? [
|
|
2030
|
+
h.div([
|
|
2031
|
+
h.Class("reel-slot reel-stage"),
|
|
2032
|
+
h.Style({ "--reel-anchor": STAGE_ANCHOR }),
|
|
2033
|
+
]),
|
|
2034
|
+
]
|
|
2035
|
+
: strip()),
|
|
2036
|
+
paneLayerView(info, panesInDomOrder, anchors, h),
|
|
2037
|
+
]
|
|
2038
|
+
),
|
|
2039
|
+
]
|
|
2040
|
+
),
|
|
2041
|
+
h.p([h.Id(helpId(model)), h.Class("sr-only")], [COPY.gripHelp]),
|
|
2042
|
+
...liftedCopyView(info, h),
|
|
2043
|
+
]
|
|
2044
|
+
);
|
|
2045
|
+
}
|
|
2046
|
+
);
|