@threadlabs/looma 0.2.5 → 0.2.7
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/dist/chunk-3HMMDK27.js +2914 -0
- package/dist/chunk-3K45IWIJ.js +4733 -0
- package/dist/chunk-MLKGABMK.js +9 -0
- package/dist/declarative-generated.cjs +135 -0
- package/dist/declarative-generated.d.cts +10 -0
- package/dist/declarative-generated.d.ts +10 -0
- package/dist/declarative-generated.js +111 -0
- package/dist/declarative.cjs +2942 -0
- package/dist/declarative.d.cts +27 -0
- package/dist/declarative.d.ts +27 -0
- package/dist/declarative.js +13 -0
- package/dist/index.cjs +7478 -6457
- package/dist/index.d.cts +4 -58
- package/dist/index.d.ts +4 -58
- package/dist/index.js +15 -27
- package/dist/loader.cjs +7652 -0
- package/dist/loader.d.cts +4 -0
- package/dist/loader.d.ts +4 -0
- package/dist/loader.js +16 -0
- package/dist/valibot.cjs +31 -0
- package/dist/valibot.d.cts +10 -0
- package/dist/valibot.d.ts +1 -43
- package/dist/valibot.js +2 -0
- package/dist/{types/field/validation.d.ts → validation-bxcou-l-.d.cts} +13 -11
- package/dist/validation-bxcou-l-.d.ts +58 -0
- package/editor/{chunk-B5WVJOPV.js → chunk-BXICJBWS.js} +118 -8
- package/editor/{chunk-ZOUKEZ77.js → chunk-JK53ENSG.js} +8 -21
- package/editor/chunk-WI7ZA44X.js +2558 -0
- package/editor/extensions/index.d.ts +11 -2
- package/editor/extensions/index.js +9 -7
- package/editor/index.d.ts +1 -1
- package/editor/index.js +10 -8
- package/editor/ui.js +2 -2
- package/editor.css +32 -0
- package/layout/index.cjs +466 -400
- package/layout/index.d.cts +1 -2
- package/layout/index.d.ts +1 -2
- package/layout/index.js +471 -395
- package/package.json +14 -5
- package/vue/chunk-4DPYH3IT.js +3538 -0
- package/vue/editor/index.d.ts +17 -7
- package/vue/editor/index.js +53 -35
- package/vue/index.d.ts +48 -31
- package/vue/index.js +1 -1
- package/dist/chunk-24OTMNIU.js +0 -1617
- package/dist/chunk-D5WRORG6.js +0 -366
- package/dist/chunk-HNFCGIBP.js +0 -8
- package/dist/chunk-NB6DBRXQ.js +0 -323
- package/dist/chunk-OF57X5AR.js +0 -10
- package/dist/chunk-TL4FIE7X.js +0 -93
- package/dist/chunk-UL7UIUJZ.js +0 -20
- package/dist/cjs/app-globals-V2Kpy_OQ.js +0 -5
- package/dist/cjs/controlled-state-BFya8rAX.js +0 -9
- package/dist/cjs/events-TcQIzpNv.js +0 -19
- package/dist/cjs/icons-BAdjrnhS.js +0 -680
- package/dist/cjs/id-CYbKpaYr.js +0 -9
- package/dist/cjs/index-BHG9Rpil.js +0 -1602
- package/dist/cjs/index.cjs.js +0 -2
- package/dist/cjs/loader.cjs.js +0 -13
- package/dist/cjs/looma.cjs.js +0 -25
- package/dist/cjs/manager-Ce25WRtl.js +0 -95
- package/dist/cjs/positioning-CCR6ifPj.js +0 -426
- package/dist/cjs/ui-affordance-scope.cjs.entry.js +0 -43
- package/dist/cjs/ui-avatar-group.cjs.entry.js +0 -43
- package/dist/cjs/ui-avatar.cjs.entry.js +0 -50
- package/dist/cjs/ui-badge.cjs.entry.js +0 -19
- package/dist/cjs/ui-button.cjs.entry.js +0 -75
- package/dist/cjs/ui-callout.cjs.entry.js +0 -27
- package/dist/cjs/ui-checkbox.cjs.entry.js +0 -97
- package/dist/cjs/ui-chip_2.cjs.entry.js +0 -258
- package/dist/cjs/ui-combobox.cjs.entry.js +0 -708
- package/dist/cjs/ui-context-menu.cjs.entry.js +0 -239
- package/dist/cjs/ui-dialog.cjs.entry.js +0 -131
- package/dist/cjs/ui-disclosure.cjs.entry.js +0 -112
- package/dist/cjs/ui-editable.cjs.entry.js +0 -100
- package/dist/cjs/ui-floating-action-button.cjs.entry.js +0 -20
- package/dist/cjs/ui-form-field.cjs.entry.js +0 -114
- package/dist/cjs/ui-icon-button.cjs.entry.js +0 -23
- package/dist/cjs/ui-input.cjs.entry.js +0 -106
- package/dist/cjs/ui-menu-item.cjs.entry.js +0 -19
- package/dist/cjs/ui-menu.cjs.entry.js +0 -182
- package/dist/cjs/ui-popover.cjs.entry.js +0 -135
- package/dist/cjs/ui-radio-group.cjs.entry.js +0 -134
- package/dist/cjs/ui-radio.cjs.entry.js +0 -94
- package/dist/cjs/ui-search-result-row.cjs.entry.js +0 -47
- package/dist/cjs/ui-search-shell.cjs.entry.js +0 -39
- package/dist/cjs/ui-select.cjs.entry.js +0 -108
- package/dist/cjs/ui-switch.cjs.entry.js +0 -74
- package/dist/cjs/ui-tabs.cjs.entry.js +0 -118
- package/dist/cjs/ui-textarea.cjs.entry.js +0 -110
- package/dist/cjs/ui-toast-region.cjs.entry.js +0 -93
- package/dist/cjs/ui-top-bar.cjs.entry.js +0 -43
- package/dist/cjs/ui-tree-item.cjs.entry.js +0 -135
- package/dist/cjs/ui-tree.cjs.entry.js +0 -500
- package/dist/collection/collection-manifest.json +0 -45
- package/dist/collection/components/ui-affordance-scope/ui-affordance-scope.css +0 -8
- package/dist/collection/components/ui-affordance-scope/ui-affordance-scope.js +0 -70
- package/dist/collection/components/ui-avatar/ui-avatar.css +0 -35
- package/dist/collection/components/ui-avatar/ui-avatar.js +0 -130
- package/dist/collection/components/ui-avatar-group/ui-avatar-group.css +0 -32
- package/dist/collection/components/ui-avatar-group/ui-avatar-group.js +0 -95
- package/dist/collection/components/ui-badge/ui-badge.css +0 -90
- package/dist/collection/components/ui-badge/ui-badge.js +0 -62
- package/dist/collection/components/ui-button/ui-button.css +0 -121
- package/dist/collection/components/ui-button/ui-button.js +0 -141
- package/dist/collection/components/ui-callout/ui-callout.css +0 -74
- package/dist/collection/components/ui-callout/ui-callout.js +0 -59
- package/dist/collection/components/ui-checkbox/ui-checkbox.css +0 -24
- package/dist/collection/components/ui-checkbox/ui-checkbox.js +0 -228
- package/dist/collection/components/ui-chip/ui-chip.css +0 -57
- package/dist/collection/components/ui-chip/ui-chip.js +0 -67
- package/dist/collection/components/ui-combobox/ui-combobox.css +0 -47
- package/dist/collection/components/ui-combobox/ui-combobox.js +0 -1295
- package/dist/collection/components/ui-context-menu/ui-context-menu.css +0 -34
- package/dist/collection/components/ui-context-menu/ui-context-menu.js +0 -311
- package/dist/collection/components/ui-dialog/ui-dialog.css +0 -72
- package/dist/collection/components/ui-dialog/ui-dialog.js +0 -242
- package/dist/collection/components/ui-disclosure/ui-disclosure.css +0 -7
- package/dist/collection/components/ui-disclosure/ui-disclosure.js +0 -184
- package/dist/collection/components/ui-editable/ui-editable.css +0 -2
- package/dist/collection/components/ui-editable/ui-editable.js +0 -196
- package/dist/collection/components/ui-floating-action-button/ui-floating-action-button.css +0 -73
- package/dist/collection/components/ui-floating-action-button/ui-floating-action-button.js +0 -85
- package/dist/collection/components/ui-form-field/ui-form-field.css +0 -25
- package/dist/collection/components/ui-form-field/ui-form-field.js +0 -180
- package/dist/collection/components/ui-icon-button/ui-icon-button.css +0 -145
- package/dist/collection/components/ui-icon-button/ui-icon-button.js +0 -128
- package/dist/collection/components/ui-input/ui-input.css +0 -48
- package/dist/collection/components/ui-input/ui-input.js +0 -217
- package/dist/collection/components/ui-menu/ui-menu.css +0 -73
- package/dist/collection/components/ui-menu/ui-menu.js +0 -280
- package/dist/collection/components/ui-menu-item/ui-menu-item.css +0 -32
- package/dist/collection/components/ui-menu-item/ui-menu-item.js +0 -64
- package/dist/collection/components/ui-popover/ui-popover.css +0 -58
- package/dist/collection/components/ui-popover/ui-popover.js +0 -232
- package/dist/collection/components/ui-radio/ui-radio.css +0 -22
- package/dist/collection/components/ui-radio/ui-radio.js +0 -226
- package/dist/collection/components/ui-radio-group/ui-radio-group.css +0 -10
- package/dist/collection/components/ui-radio-group/ui-radio-group.js +0 -247
- package/dist/collection/components/ui-search-result-row/ui-search-result-row.css +0 -80
- package/dist/collection/components/ui-search-result-row/ui-search-result-row.js +0 -100
- package/dist/collection/components/ui-search-shell/ui-search-shell.css +0 -63
- package/dist/collection/components/ui-search-shell/ui-search-shell.js +0 -46
- package/dist/collection/components/ui-select/ui-select.css +0 -64
- package/dist/collection/components/ui-select/ui-select.js +0 -218
- package/dist/collection/components/ui-switch/ui-switch.css +0 -63
- package/dist/collection/components/ui-switch/ui-switch.js +0 -185
- package/dist/collection/components/ui-tabs/ui-tabs.css +0 -68
- package/dist/collection/components/ui-tabs/ui-tabs.js +0 -190
- package/dist/collection/components/ui-textarea/ui-textarea.css +0 -49
- package/dist/collection/components/ui-textarea/ui-textarea.js +0 -241
- package/dist/collection/components/ui-toast-region/ui-toast-region.css +0 -59
- package/dist/collection/components/ui-toast-region/ui-toast-region.js +0 -126
- package/dist/collection/components/ui-tooltip/ui-tooltip.css +0 -43
- package/dist/collection/components/ui-tooltip/ui-tooltip.js +0 -430
- package/dist/collection/components/ui-top-bar/ui-top-bar.css +0 -51
- package/dist/collection/components/ui-top-bar/ui-top-bar.js +0 -52
- package/dist/collection/components/ui-tree/ui-tree.css +0 -12
- package/dist/collection/components/ui-tree/ui-tree.js +0 -515
- package/dist/collection/components/ui-tree-item/ui-tree-item.css +0 -217
- package/dist/collection/components/ui-tree-item/ui-tree-item.js +0 -406
- package/dist/collection/field/combobox.js +0 -4
- package/dist/collection/field/editable.js +0 -1
- package/dist/collection/field/multi-combobox.js +0 -1
- package/dist/collection/field/valibot.js +0 -5
- package/dist/collection/field/validation.js +0 -62
- package/dist/collection/icons.js +0 -71
- package/dist/collection/input-modality.js +0 -24
- package/dist/collection/overlay/manager.js +0 -92
- package/dist/collection/overlay/positioning.js +0 -424
- package/dist/collection/utils/controlled-state.js +0 -4
- package/dist/collection/utils/drag-drop.js +0 -51
- package/dist/collection/utils/events.js +0 -13
- package/dist/collection/utils/id.js +0 -5
- package/dist/collection/utils/initials.js +0 -11
- package/dist/components/index.d.ts +0 -102
- package/dist/components/index.js +0 -1
- package/dist/components/p-6SWSrfmW.js +0 -1
- package/dist/components/p-B_DaIVEY.js +0 -1
- package/dist/components/p-Bh_1GxOD.js +0 -1
- package/dist/components/p-BnGhGgTH.js +0 -1
- package/dist/components/p-BzaB_bXo.js +0 -1
- package/dist/components/p-C-0syqXZ.js +0 -1
- package/dist/components/p-CoFximGM.js +0 -13
- package/dist/components/p-JwSoedEO.js +0 -1
- package/dist/components/p-Vc4ExHFc.js +0 -1
- package/dist/components/p-hgBUJRDa.js +0 -1
- package/dist/components/ui-affordance-scope.d.ts +0 -11
- package/dist/components/ui-affordance-scope.js +0 -1
- package/dist/components/ui-avatar-group.d.ts +0 -11
- package/dist/components/ui-avatar-group.js +0 -1
- package/dist/components/ui-avatar.d.ts +0 -11
- package/dist/components/ui-avatar.js +0 -1
- package/dist/components/ui-badge.d.ts +0 -11
- package/dist/components/ui-badge.js +0 -1
- package/dist/components/ui-button.d.ts +0 -11
- package/dist/components/ui-button.js +0 -1
- package/dist/components/ui-callout.d.ts +0 -11
- package/dist/components/ui-callout.js +0 -1
- package/dist/components/ui-checkbox.d.ts +0 -11
- package/dist/components/ui-checkbox.js +0 -1
- package/dist/components/ui-chip.d.ts +0 -11
- package/dist/components/ui-chip.js +0 -1
- package/dist/components/ui-combobox.d.ts +0 -11
- package/dist/components/ui-combobox.js +0 -1
- package/dist/components/ui-context-menu.d.ts +0 -11
- package/dist/components/ui-context-menu.js +0 -1
- package/dist/components/ui-dialog.d.ts +0 -11
- package/dist/components/ui-dialog.js +0 -1
- package/dist/components/ui-disclosure.d.ts +0 -11
- package/dist/components/ui-disclosure.js +0 -1
- package/dist/components/ui-editable.d.ts +0 -11
- package/dist/components/ui-editable.js +0 -1
- package/dist/components/ui-floating-action-button.d.ts +0 -11
- package/dist/components/ui-floating-action-button.js +0 -1
- package/dist/components/ui-form-field.d.ts +0 -11
- package/dist/components/ui-form-field.js +0 -1
- package/dist/components/ui-icon-button.d.ts +0 -11
- package/dist/components/ui-icon-button.js +0 -1
- package/dist/components/ui-input.d.ts +0 -11
- package/dist/components/ui-input.js +0 -1
- package/dist/components/ui-menu-item.d.ts +0 -11
- package/dist/components/ui-menu-item.js +0 -1
- package/dist/components/ui-menu.d.ts +0 -11
- package/dist/components/ui-menu.js +0 -1
- package/dist/components/ui-popover.d.ts +0 -11
- package/dist/components/ui-popover.js +0 -1
- package/dist/components/ui-radio-group.d.ts +0 -11
- package/dist/components/ui-radio-group.js +0 -1
- package/dist/components/ui-radio.d.ts +0 -11
- package/dist/components/ui-radio.js +0 -1
- package/dist/components/ui-search-result-row.d.ts +0 -11
- package/dist/components/ui-search-result-row.js +0 -1
- package/dist/components/ui-search-shell.d.ts +0 -11
- package/dist/components/ui-search-shell.js +0 -1
- package/dist/components/ui-select.d.ts +0 -11
- package/dist/components/ui-select.js +0 -1
- package/dist/components/ui-switch.d.ts +0 -11
- package/dist/components/ui-switch.js +0 -1
- package/dist/components/ui-tabs.d.ts +0 -11
- package/dist/components/ui-tabs.js +0 -1
- package/dist/components/ui-textarea.d.ts +0 -11
- package/dist/components/ui-textarea.js +0 -1
- package/dist/components/ui-toast-region.d.ts +0 -11
- package/dist/components/ui-toast-region.js +0 -1
- package/dist/components/ui-tooltip.d.ts +0 -11
- package/dist/components/ui-tooltip.js +0 -1
- package/dist/components/ui-top-bar.d.ts +0 -11
- package/dist/components/ui-top-bar.js +0 -1
- package/dist/components/ui-tree-item.d.ts +0 -11
- package/dist/components/ui-tree-item.js +0 -1
- package/dist/components/ui-tree.d.ts +0 -11
- package/dist/components/ui-tree.js +0 -1
- package/dist/esm/app-globals-DQuL1Twl.js +0 -3
- package/dist/esm/controlled-state-BnGhGgTH.js +0 -6
- package/dist/esm/events-JwSoedEO.js +0 -15
- package/dist/esm/icons-CoFximGM.js +0 -678
- package/dist/esm/id-hgBUJRDa.js +0 -7
- package/dist/esm/index-8BGiMGQ0.js +0 -1593
- package/dist/esm/index.js +0 -1
- package/dist/esm/loader.js +0 -11
- package/dist/esm/looma.js +0 -21
- package/dist/esm/manager-C-0syqXZ.js +0 -91
- package/dist/esm/positioning-ZOr-2PSe.js +0 -421
- package/dist/esm/ui-affordance-scope.entry.js +0 -41
- package/dist/esm/ui-avatar-group.entry.js +0 -41
- package/dist/esm/ui-avatar.entry.js +0 -48
- package/dist/esm/ui-badge.entry.js +0 -17
- package/dist/esm/ui-button.entry.js +0 -73
- package/dist/esm/ui-callout.entry.js +0 -25
- package/dist/esm/ui-checkbox.entry.js +0 -95
- package/dist/esm/ui-chip_2.entry.js +0 -255
- package/dist/esm/ui-combobox.entry.js +0 -706
- package/dist/esm/ui-context-menu.entry.js +0 -237
- package/dist/esm/ui-dialog.entry.js +0 -129
- package/dist/esm/ui-disclosure.entry.js +0 -110
- package/dist/esm/ui-editable.entry.js +0 -98
- package/dist/esm/ui-floating-action-button.entry.js +0 -18
- package/dist/esm/ui-form-field.entry.js +0 -112
- package/dist/esm/ui-icon-button.entry.js +0 -21
- package/dist/esm/ui-input.entry.js +0 -104
- package/dist/esm/ui-menu-item.entry.js +0 -17
- package/dist/esm/ui-menu.entry.js +0 -180
- package/dist/esm/ui-popover.entry.js +0 -133
- package/dist/esm/ui-radio-group.entry.js +0 -132
- package/dist/esm/ui-radio.entry.js +0 -92
- package/dist/esm/ui-search-result-row.entry.js +0 -45
- package/dist/esm/ui-search-shell.entry.js +0 -37
- package/dist/esm/ui-select.entry.js +0 -106
- package/dist/esm/ui-switch.entry.js +0 -72
- package/dist/esm/ui-tabs.entry.js +0 -116
- package/dist/esm/ui-textarea.entry.js +0 -108
- package/dist/esm/ui-toast-region.entry.js +0 -91
- package/dist/esm/ui-top-bar.entry.js +0 -41
- package/dist/esm/ui-tree-item.entry.js +0 -133
- package/dist/esm/ui-tree.entry.js +0 -498
- package/dist/index.cjs.js +0 -1
- package/dist/looma/index.esm.js +0 -0
- package/dist/looma/looma.esm.js +0 -1
- package/dist/looma/p-08f80207.entry.js +0 -1
- package/dist/looma/p-0b5b8d9e.entry.js +0 -1
- package/dist/looma/p-1249a806.entry.js +0 -1
- package/dist/looma/p-16e0669d.entry.js +0 -1
- package/dist/looma/p-1c00670f.entry.js +0 -1
- package/dist/looma/p-1c5a7522.entry.js +0 -1
- package/dist/looma/p-22842f8c.entry.js +0 -1
- package/dist/looma/p-2915d5c0.entry.js +0 -1
- package/dist/looma/p-3b2961a6.entry.js +0 -1
- package/dist/looma/p-3f60f4c8.entry.js +0 -1
- package/dist/looma/p-424d6719.entry.js +0 -1
- package/dist/looma/p-4caccfce.entry.js +0 -1
- package/dist/looma/p-5fdcee1d.entry.js +0 -1
- package/dist/looma/p-6d8b99ee.entry.js +0 -1
- package/dist/looma/p-6f20d470.entry.js +0 -1
- package/dist/looma/p-7c0b5364.entry.js +0 -1
- package/dist/looma/p-8BGiMGQ0.js +0 -2
- package/dist/looma/p-8bdd9495.entry.js +0 -1
- package/dist/looma/p-99116a72.entry.js +0 -1
- package/dist/looma/p-9cfbf722.entry.js +0 -1
- package/dist/looma/p-9d2662ca.entry.js +0 -1
- package/dist/looma/p-9ff2fa19.entry.js +0 -1
- package/dist/looma/p-BnGhGgTH.js +0 -1
- package/dist/looma/p-C-0syqXZ.js +0 -1
- package/dist/looma/p-CoFximGM.js +0 -13
- package/dist/looma/p-DQuL1Twl.js +0 -1
- package/dist/looma/p-JwSoedEO.js +0 -1
- package/dist/looma/p-ZOr-2PSe.js +0 -1
- package/dist/looma/p-a2dd4c6c.entry.js +0 -1
- package/dist/looma/p-add67e4c.entry.js +0 -1
- package/dist/looma/p-b6ede6bb.entry.js +0 -1
- package/dist/looma/p-b76e2111.entry.js +0 -1
- package/dist/looma/p-ca2a54fd.entry.js +0 -1
- package/dist/looma/p-d372b0db.entry.js +0 -1
- package/dist/looma/p-d4825822.entry.js +0 -1
- package/dist/looma/p-d56571a2.entry.js +0 -1
- package/dist/looma/p-d5c3954f.entry.js +0 -1
- package/dist/looma/p-e604e906.entry.js +0 -1
- package/dist/looma/p-f1f7c5cb.entry.js +0 -1
- package/dist/looma/p-hgBUJRDa.js +0 -1
- package/dist/types/components/ui-affordance-scope/ui-affordance-scope.d.ts +0 -11
- package/dist/types/components/ui-avatar/ui-avatar.d.ts +0 -11
- package/dist/types/components/ui-avatar-group/ui-avatar-group.d.ts +0 -11
- package/dist/types/components/ui-badge/ui-badge.d.ts +0 -5
- package/dist/types/components/ui-button/ui-button.d.ts +0 -13
- package/dist/types/components/ui-callout/ui-callout.d.ts +0 -6
- package/dist/types/components/ui-checkbox/ui-checkbox.d.ts +0 -20
- package/dist/types/components/ui-chip/ui-chip.d.ts +0 -8
- package/dist/types/components/ui-combobox/ui-combobox.d.ts +0 -128
- package/dist/types/components/ui-context-menu/ui-context-menu.d.ts +0 -43
- package/dist/types/components/ui-dialog/ui-dialog.d.ts +0 -27
- package/dist/types/components/ui-disclosure/ui-disclosure.d.ts +0 -21
- package/dist/types/components/ui-editable/ui-editable.d.ts +0 -24
- package/dist/types/components/ui-floating-action-button/ui-floating-action-button.d.ts +0 -6
- package/dist/types/components/ui-form-field/ui-form-field.d.ts +0 -18
- package/dist/types/components/ui-icon-button/ui-icon-button.d.ts +0 -9
- package/dist/types/components/ui-input/ui-input.d.ts +0 -19
- package/dist/types/components/ui-menu/ui-menu.d.ts +0 -28
- package/dist/types/components/ui-menu-item/ui-menu-item.d.ts +0 -5
- package/dist/types/components/ui-popover/ui-popover.d.ts +0 -26
- package/dist/types/components/ui-radio/ui-radio.d.ts +0 -20
- package/dist/types/components/ui-radio-group/ui-radio-group.d.ts +0 -21
- package/dist/types/components/ui-search-result-row/ui-search-result-row.d.ts +0 -15
- package/dist/types/components/ui-search-shell/ui-search-shell.d.ts +0 -9
- package/dist/types/components/ui-select/ui-select.d.ts +0 -20
- package/dist/types/components/ui-switch/ui-switch.d.ts +0 -16
- package/dist/types/components/ui-tabs/ui-tabs.d.ts +0 -18
- package/dist/types/components/ui-textarea/ui-textarea.d.ts +0 -20
- package/dist/types/components/ui-toast-region/ui-toast-region.d.ts +0 -16
- package/dist/types/components/ui-tooltip/ui-tooltip.d.ts +0 -57
- package/dist/types/components/ui-top-bar/ui-top-bar.d.ts +0 -12
- package/dist/types/components/ui-tree/ui-tree.d.ts +0 -53
- package/dist/types/components/ui-tree-item/ui-tree-item.d.ts +0 -44
- package/dist/types/components.d.ts +0 -1889
- package/dist/types/field/combobox.d.ts +0 -46
- package/dist/types/field/editable.d.ts +0 -5
- package/dist/types/field/multi-combobox.d.ts +0 -11
- package/dist/types/field/valibot.d.ts +0 -7
- package/dist/types/icons.d.ts +0 -53
- package/dist/types/input-modality.d.ts +0 -6
- package/dist/types/overlay/manager.d.ts +0 -17
- package/dist/types/overlay/positioning.d.ts +0 -74
- package/dist/types/stencil-public-runtime.d.ts +0 -1860
- package/dist/types/utils/controlled-state.d.ts +0 -4
- package/dist/types/utils/drag-drop.d.ts +0 -15
- package/dist/types/utils/events.d.ts +0 -4
- package/dist/types/utils/id.d.ts +0 -1
- package/dist/types/utils/initials.d.ts +0 -1
- package/dist/ui-affordance-scope.entry-L6TIXYOP.js +0 -54
- package/dist/ui-avatar-group.entry-TCAA6P72.js +0 -51
- package/dist/ui-avatar.entry-52DQ7VXA.js +0 -51
- package/dist/ui-badge.entry-2XCAA6LL.js +0 -22
- package/dist/ui-button.entry-MNFBMNSX.js +0 -83
- package/dist/ui-callout.entry-SSHT5TH2.js +0 -32
- package/dist/ui-checkbox.entry-LOWIWIWI.js +0 -111
- package/dist/ui-chip_2.entry-BIMTSF6C.js +0 -272
- package/dist/ui-combobox.entry-25Z4MN7N.js +0 -717
- package/dist/ui-context-menu.entry-YZDL5Y4M.js +0 -248
- package/dist/ui-dialog.entry-HIXZX5AB.js +0 -146
- package/dist/ui-disclosure.entry-2JZHZNDQ.js +0 -126
- package/dist/ui-editable.entry-U3VR3XPT.js +0 -110
- package/dist/ui-floating-action-button.entry-6S3QN3KJ.js +0 -23
- package/dist/ui-form-field.entry-GQOSMLHT.js +0 -120
- package/dist/ui-icon-button.entry-QJXKVDM6.js +0 -26
- package/dist/ui-input.entry-UWMQ6JMP.js +0 -114
- package/dist/ui-menu-item.entry-NHNZKKJS.js +0 -22
- package/dist/ui-menu.entry-D53RUJND.js +0 -192
- package/dist/ui-popover.entry-7ZSIWCFQ.js +0 -152
- package/dist/ui-radio-group.entry-37MSYIH4.js +0 -142
- package/dist/ui-radio.entry-7YGCDHXT.js +0 -108
- package/dist/ui-search-result-row.entry-6FCCLGAS.js +0 -50
- package/dist/ui-search-shell.entry-HSBEXPER.js +0 -41
- package/dist/ui-select.entry-GIDIAYRD.js +0 -117
- package/dist/ui-switch.entry-MYAL6XPC.js +0 -87
- package/dist/ui-tabs.entry-R4TEXQSD.js +0 -128
- package/dist/ui-textarea.entry-FW32JNDV.js +0 -119
- package/dist/ui-toast-region.entry-BTMFPKZF.js +0 -104
- package/dist/ui-top-bar.entry-5DQGJF3B.js +0 -49
- package/dist/ui-tree-item.entry-ADT7DSOS.js +0 -145
- package/dist/ui-tree.entry-7PYQ5RIN.js +0 -470
- package/editor/chunk-64GLF274.js +0 -1271
- package/layout/index.css +0 -387
- package/loader/cdn.js +0 -1
- package/loader/index.cjs.js +0 -1
- package/loader/index.d.ts +0 -24
- package/loader/index.es2017.js +0 -1
- package/loader/index.js +0 -2
- package/vue/chunk-ROMBQS2L.js +0 -352
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
/** Formatting is additive: every original character must survive in order.
|
|
2
|
-
* Normalization belongs to submitted output, never the visible editing buffer. */
|
|
3
|
-
export function formatEditingValue(raw, selection, format) {
|
|
4
|
-
const unchanged = { display: raw, selection };
|
|
5
|
-
if (!format)
|
|
6
|
-
return unchanged;
|
|
7
|
-
let result;
|
|
8
|
-
try {
|
|
9
|
-
result = format(raw, selection);
|
|
10
|
-
}
|
|
11
|
-
catch {
|
|
12
|
-
return unchanged;
|
|
13
|
-
}
|
|
14
|
-
if (!result)
|
|
15
|
-
return unchanged;
|
|
16
|
-
const characters = Array.from(raw);
|
|
17
|
-
let cursor = 0;
|
|
18
|
-
for (const character of result.display)
|
|
19
|
-
if (character === characters[cursor])
|
|
20
|
-
cursor += 1;
|
|
21
|
-
if (!Number.isInteger(result.selection.start) || !Number.isInteger(result.selection.end) || cursor !== characters.length || result.selection.start < 0 || result.selection.end < result.selection.start
|
|
22
|
-
|| result.selection.end > result.display.length)
|
|
23
|
-
return unchanged;
|
|
24
|
-
return result;
|
|
25
|
-
}
|
|
26
|
-
export async function validateField(request, config) {
|
|
27
|
-
let output = request.raw;
|
|
28
|
-
let issues = [];
|
|
29
|
-
const check = () => request.signal.throwIfAborted();
|
|
30
|
-
try {
|
|
31
|
-
check();
|
|
32
|
-
if (config.parse)
|
|
33
|
-
output = await config.parse(request.raw, request);
|
|
34
|
-
check();
|
|
35
|
-
if (config.schema) {
|
|
36
|
-
const result = await config.schema['~standard'].validate(output);
|
|
37
|
-
check();
|
|
38
|
-
if (result.issues)
|
|
39
|
-
issues = result.issues;
|
|
40
|
-
else if ('value' in result)
|
|
41
|
-
output = result.value;
|
|
42
|
-
}
|
|
43
|
-
if (!issues.some(issue => issue.severity !== 'warning')) {
|
|
44
|
-
if (config.normalize)
|
|
45
|
-
output = await config.normalize(output, request);
|
|
46
|
-
check();
|
|
47
|
-
if (config.validator) {
|
|
48
|
-
const result = await config.validator(output, request);
|
|
49
|
-
check();
|
|
50
|
-
issues = [...issues, ...(result.issues ?? [])];
|
|
51
|
-
if ('output' in result)
|
|
52
|
-
output = result.output;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
catch (error) {
|
|
57
|
-
check();
|
|
58
|
-
issues = [{ message: error instanceof Error ? error.message : 'Unable to validate this value.' }];
|
|
59
|
-
}
|
|
60
|
-
issues = [...issues, ...(config.issues ?? [])];
|
|
61
|
-
return { output: issues.some(issue => issue.severity !== 'warning') ? undefined : output, issues };
|
|
62
|
-
}
|
package/dist/collection/icons.js
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import { AlignCenter, AlignLeft, AlignRight, Bold, Braces, ChevronDown, ChevronLeft, CodeXml, CircleCheck, CircleX, Columns3, Ellipsis, Eraser, GripHorizontal, GripVertical, Heading1, Heading2, Heading3, Highlighter, Image, Info, Italic, List, ListOrdered, ListTodo, Merge, NotebookPen, Minus, PaintBucket, PanelBottom, PanelLeft, PanelRight, PanelTop, Pilcrow, Plus, Quote, Redo2, Rows3, Split, Strikethrough, Table2, Trash2, TriangleAlert, Underline, Undo2, } from "lucide";
|
|
2
|
-
/** The opinionated Lucide set used by Looma's shipped interaction surfaces. */
|
|
3
|
-
export const LOOMA_ICONS = {
|
|
4
|
-
'align-center': AlignCenter,
|
|
5
|
-
'align-left': AlignLeft,
|
|
6
|
-
'align-right': AlignRight,
|
|
7
|
-
bold: Bold,
|
|
8
|
-
braces: Braces,
|
|
9
|
-
'circle-check': CircleCheck,
|
|
10
|
-
'circle-x': CircleX,
|
|
11
|
-
'chevron-down': ChevronDown,
|
|
12
|
-
'chevron-left': ChevronLeft,
|
|
13
|
-
'code-xml': CodeXml,
|
|
14
|
-
columns: Columns3,
|
|
15
|
-
ellipsis: Ellipsis,
|
|
16
|
-
eraser: Eraser,
|
|
17
|
-
'grip-horizontal': GripHorizontal,
|
|
18
|
-
'grip-vertical': GripVertical,
|
|
19
|
-
'heading-1': Heading1,
|
|
20
|
-
'heading-2': Heading2,
|
|
21
|
-
'heading-3': Heading3,
|
|
22
|
-
highlighter: Highlighter,
|
|
23
|
-
image: Image,
|
|
24
|
-
info: Info,
|
|
25
|
-
italic: Italic,
|
|
26
|
-
list: List,
|
|
27
|
-
'list-ordered': ListOrdered,
|
|
28
|
-
'list-todo': ListTodo,
|
|
29
|
-
merge: Merge,
|
|
30
|
-
'notebook-pen': NotebookPen,
|
|
31
|
-
minus: Minus,
|
|
32
|
-
'paint-bucket': PaintBucket,
|
|
33
|
-
'panel-bottom': PanelBottom,
|
|
34
|
-
'panel-left': PanelLeft,
|
|
35
|
-
'panel-right': PanelRight,
|
|
36
|
-
'panel-top': PanelTop,
|
|
37
|
-
pilcrow: Pilcrow,
|
|
38
|
-
plus: Plus,
|
|
39
|
-
quote: Quote,
|
|
40
|
-
redo: Redo2,
|
|
41
|
-
rows: Rows3,
|
|
42
|
-
split: Split,
|
|
43
|
-
strikethrough: Strikethrough,
|
|
44
|
-
table: Table2,
|
|
45
|
-
trash: Trash2,
|
|
46
|
-
'triangle-alert': TriangleAlert,
|
|
47
|
-
underline: Underline,
|
|
48
|
-
undo: Undo2,
|
|
49
|
-
};
|
|
50
|
-
function serializeAttributes(attributes) {
|
|
51
|
-
return Object.entries(attributes)
|
|
52
|
-
.map(([name, value]) => ` ${name}="${escapeAttribute(value)}"`)
|
|
53
|
-
.join('');
|
|
54
|
-
}
|
|
55
|
-
function escapeAttribute(value) {
|
|
56
|
-
return String(value).replaceAll('&', '&').replaceAll('"', '"');
|
|
57
|
-
}
|
|
58
|
-
function serializeIconNode(node) {
|
|
59
|
-
const [tag, attributes] = node;
|
|
60
|
-
return `<${tag}${serializeAttributes(attributes)}></${tag}>`;
|
|
61
|
-
}
|
|
62
|
-
/** Creates consistent, currentColor-driven SVG markup for framework-neutral components. */
|
|
63
|
-
export function loomaIconMarkup(name, className = 'looma-icon') {
|
|
64
|
-
return [
|
|
65
|
-
`<svg class="${escapeAttribute(className)}" data-looma-icon="${name}" aria-hidden="true" focusable="false"`,
|
|
66
|
-
' viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"',
|
|
67
|
-
' stroke-linecap="round" stroke-linejoin="round">',
|
|
68
|
-
LOOMA_ICONS[name].map(serializeIconNode).join(''),
|
|
69
|
-
'</svg>',
|
|
70
|
-
].join('');
|
|
71
|
-
}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
const initializedDocuments = new WeakSet();
|
|
2
|
-
/**
|
|
3
|
-
* Reflects real touch use instead of guessing from device capability media
|
|
4
|
-
* queries. Hybrid devices therefore keep compact pointer affordances until the
|
|
5
|
-
* user actually touches the interface.
|
|
6
|
-
*/
|
|
7
|
-
export function initializeInputModality(owner = document) {
|
|
8
|
-
if (initializedDocuments.has(owner))
|
|
9
|
-
return;
|
|
10
|
-
initializedDocuments.add(owner);
|
|
11
|
-
const markTouch = () => {
|
|
12
|
-
if (owner.documentElement.getAttribute("data-ui-input-modality") === "touch")
|
|
13
|
-
return;
|
|
14
|
-
owner.documentElement.setAttribute("data-ui-input-modality", "touch");
|
|
15
|
-
owner.dispatchEvent(new CustomEvent("ui-input-modality-change", {
|
|
16
|
-
detail: { modality: "touch" },
|
|
17
|
-
}));
|
|
18
|
-
};
|
|
19
|
-
owner.addEventListener("pointerdown", (event) => {
|
|
20
|
-
if (event.pointerType === "touch")
|
|
21
|
-
markTouch();
|
|
22
|
-
}, { capture: true, passive: true });
|
|
23
|
-
owner.addEventListener("touchstart", markTouch, { capture: true, passive: true });
|
|
24
|
-
}
|
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
const stack = [];
|
|
2
|
-
const scrollLockAttribute = "data-ui-scroll-lock";
|
|
3
|
-
let modalCount = 0;
|
|
4
|
-
let listenersAttached = false;
|
|
5
|
-
function syncScrollLock() {
|
|
6
|
-
if (typeof document === "undefined") {
|
|
7
|
-
return;
|
|
8
|
-
}
|
|
9
|
-
const root = document.documentElement;
|
|
10
|
-
if (modalCount > 0) {
|
|
11
|
-
root.setAttribute(scrollLockAttribute, "true");
|
|
12
|
-
root.style.overflow = "hidden";
|
|
13
|
-
return;
|
|
14
|
-
}
|
|
15
|
-
root.removeAttribute(scrollLockAttribute);
|
|
16
|
-
root.style.removeProperty("overflow");
|
|
17
|
-
}
|
|
18
|
-
function getOverlayDismissible(record) {
|
|
19
|
-
return record.dismissible ?? true;
|
|
20
|
-
}
|
|
21
|
-
function handleEscape(event) {
|
|
22
|
-
if (event.key !== "Escape") {
|
|
23
|
-
return;
|
|
24
|
-
}
|
|
25
|
-
requestTopOverlayClose("escape", "keyboard");
|
|
26
|
-
}
|
|
27
|
-
function handleLightDismiss(event) {
|
|
28
|
-
const top = getTopOverlay();
|
|
29
|
-
if (!top || !getOverlayDismissible(top)) {
|
|
30
|
-
return;
|
|
31
|
-
}
|
|
32
|
-
// A document listener sees a shadow host as event.target. Use the composed
|
|
33
|
-
// path so connected controls inside a field remain inside the overlay boundary.
|
|
34
|
-
const boundary = [top.element, ...(top.relatedElements ?? [])];
|
|
35
|
-
if (event.composedPath().some(target => target instanceof Node
|
|
36
|
-
&& boundary.some(element => element.contains(target))))
|
|
37
|
-
return;
|
|
38
|
-
requestTopOverlayClose("light-dismiss", "pointer");
|
|
39
|
-
}
|
|
40
|
-
function ensureListeners() {
|
|
41
|
-
if (listenersAttached || typeof document === "undefined") {
|
|
42
|
-
return;
|
|
43
|
-
}
|
|
44
|
-
document.addEventListener("keydown", handleEscape);
|
|
45
|
-
document.addEventListener("pointerdown", handleLightDismiss, { capture: true });
|
|
46
|
-
listenersAttached = true;
|
|
47
|
-
}
|
|
48
|
-
function removeListenersIfIdle() {
|
|
49
|
-
if (!listenersAttached || stack.length > 0 || typeof document === "undefined") {
|
|
50
|
-
return;
|
|
51
|
-
}
|
|
52
|
-
document.removeEventListener("keydown", handleEscape);
|
|
53
|
-
document.removeEventListener("pointerdown", handleLightDismiss, { capture: true });
|
|
54
|
-
listenersAttached = false;
|
|
55
|
-
}
|
|
56
|
-
export function openOverlay(record) {
|
|
57
|
-
closeOverlay(record.id);
|
|
58
|
-
stack.push(record);
|
|
59
|
-
if (record.modal) {
|
|
60
|
-
modalCount += 1;
|
|
61
|
-
syncScrollLock();
|
|
62
|
-
}
|
|
63
|
-
ensureListeners();
|
|
64
|
-
}
|
|
65
|
-
export function closeOverlay(id) {
|
|
66
|
-
const index = stack.findIndex((record) => record.id === id);
|
|
67
|
-
if (index >= 0) {
|
|
68
|
-
const [record] = stack.splice(index, 1);
|
|
69
|
-
if (record?.modal) {
|
|
70
|
-
modalCount = Math.max(0, modalCount - 1);
|
|
71
|
-
syncScrollLock();
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
removeListenersIfIdle();
|
|
75
|
-
}
|
|
76
|
-
export function getTopOverlay() {
|
|
77
|
-
return stack.at(-1);
|
|
78
|
-
}
|
|
79
|
-
export function isTopOverlay(id) {
|
|
80
|
-
return getTopOverlay()?.id === id;
|
|
81
|
-
}
|
|
82
|
-
export function requestTopOverlayClose(reason, trigger) {
|
|
83
|
-
const top = getTopOverlay();
|
|
84
|
-
if (!top) {
|
|
85
|
-
return false;
|
|
86
|
-
}
|
|
87
|
-
if (!getOverlayDismissible(top) && (reason === "escape" || reason === "light-dismiss")) {
|
|
88
|
-
return false;
|
|
89
|
-
}
|
|
90
|
-
top.requestClose(reason, trigger);
|
|
91
|
-
return true;
|
|
92
|
-
}
|
|
@@ -1,424 +0,0 @@
|
|
|
1
|
-
export const DEFAULT_AFFORDANCE_NEAR_RADIUS = 16;
|
|
2
|
-
let anchorSequence = 0;
|
|
3
|
-
const anchorBindings = new WeakMap();
|
|
4
|
-
function bindAnchorName(anchor, name) {
|
|
5
|
-
const binding = anchorBindings.get(anchor) ?? {
|
|
6
|
-
original: anchor.style.getPropertyValue("anchor-name"),
|
|
7
|
-
names: new Set(),
|
|
8
|
-
};
|
|
9
|
-
binding.names.add(name);
|
|
10
|
-
anchorBindings.set(anchor, binding);
|
|
11
|
-
const values = [binding.original, ...binding.names].filter(Boolean);
|
|
12
|
-
anchor.style.setProperty("anchor-name", values.join(", "));
|
|
13
|
-
}
|
|
14
|
-
function unbindAnchorName(anchor, name) {
|
|
15
|
-
const binding = anchorBindings.get(anchor);
|
|
16
|
-
if (!binding)
|
|
17
|
-
return;
|
|
18
|
-
binding.names.delete(name);
|
|
19
|
-
if (binding.names.size) {
|
|
20
|
-
const values = [binding.original, ...binding.names].filter(Boolean);
|
|
21
|
-
anchor.style.setProperty("anchor-name", values.join(", "));
|
|
22
|
-
return;
|
|
23
|
-
}
|
|
24
|
-
if (binding.original)
|
|
25
|
-
anchor.style.setProperty("anchor-name", binding.original);
|
|
26
|
-
else
|
|
27
|
-
anchor.style.removeProperty("anchor-name");
|
|
28
|
-
anchorBindings.delete(anchor);
|
|
29
|
-
}
|
|
30
|
-
function supportsAnchorPositioning(owner) {
|
|
31
|
-
const css = owner.CSS;
|
|
32
|
-
return typeof css?.supports === "function"
|
|
33
|
-
&& css.supports("anchor-name: --ui-anchor-test")
|
|
34
|
-
&& css.supports("position-anchor: --ui-anchor-test")
|
|
35
|
-
&& css.supports("top: anchor(bottom)");
|
|
36
|
-
}
|
|
37
|
-
function topLayerOpen(surface) {
|
|
38
|
-
try {
|
|
39
|
-
return surface.matches(":popover-open");
|
|
40
|
-
}
|
|
41
|
-
catch {
|
|
42
|
-
return !surface.hidden;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
function showInTopLayer(surface) {
|
|
46
|
-
surface.setAttribute("popover", "manual");
|
|
47
|
-
surface.hidden = false;
|
|
48
|
-
if (typeof surface.showPopover === "function" && !topLayerOpen(surface)) {
|
|
49
|
-
try {
|
|
50
|
-
surface.showPopover();
|
|
51
|
-
}
|
|
52
|
-
catch {
|
|
53
|
-
// A disconnected or already-transitioning surface still receives the
|
|
54
|
-
// fixed-position fallback below and will be retried on the next sync.
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
function hideFromTopLayer(surface) {
|
|
59
|
-
if (typeof surface.hidePopover === "function" && topLayerOpen(surface)) {
|
|
60
|
-
try {
|
|
61
|
-
surface.hidePopover();
|
|
62
|
-
}
|
|
63
|
-
catch {
|
|
64
|
-
// The surface may have been disconnected between state and DOM updates.
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
surface.hidden = true;
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* Places unanchored floating UI, such as a toast region, in the browser top
|
|
71
|
-
* layer. Its viewport position remains CSS-owned; the controller only provides
|
|
72
|
-
* the native Popover API boundary and its no-Popover fallback.
|
|
73
|
-
*/
|
|
74
|
-
export function createViewportSurface(surface) {
|
|
75
|
-
surface.setAttribute("popover", "manual");
|
|
76
|
-
surface.dataset.uiPositioning = "viewport";
|
|
77
|
-
return {
|
|
78
|
-
show() {
|
|
79
|
-
showInTopLayer(surface);
|
|
80
|
-
},
|
|
81
|
-
hide() {
|
|
82
|
-
hideFromTopLayer(surface);
|
|
83
|
-
},
|
|
84
|
-
destroy() {
|
|
85
|
-
hideFromTopLayer(surface);
|
|
86
|
-
},
|
|
87
|
-
};
|
|
88
|
-
}
|
|
89
|
-
function fallbackPosition(surface, anchor, placement, gap, viewportGap, surfaceRect = surface.getBoundingClientRect()) {
|
|
90
|
-
const owner = surface.ownerDocument.defaultView ?? window;
|
|
91
|
-
const viewport = getVisualViewportRect(owner);
|
|
92
|
-
const preferTop = placement.startsWith("top");
|
|
93
|
-
const preferEnd = placement.endsWith("end");
|
|
94
|
-
const spaceBelow = viewport.bottom - anchor.bottom - viewportGap;
|
|
95
|
-
const spaceAbove = anchor.top - viewport.top - viewportGap;
|
|
96
|
-
const useTop = preferTop
|
|
97
|
-
? !(spaceAbove < surfaceRect.height + gap && spaceBelow > spaceAbove)
|
|
98
|
-
: spaceBelow < surfaceRect.height + gap && spaceAbove > spaceBelow;
|
|
99
|
-
const unclampedTop = useTop
|
|
100
|
-
? anchor.top - surfaceRect.height - gap
|
|
101
|
-
: anchor.bottom + gap;
|
|
102
|
-
const unclampedLeft = preferEnd
|
|
103
|
-
? anchor.right - surfaceRect.width
|
|
104
|
-
: anchor.left;
|
|
105
|
-
const shifted = clampRectToViewport({
|
|
106
|
-
left: unclampedLeft,
|
|
107
|
-
top: unclampedTop,
|
|
108
|
-
right: unclampedLeft + surfaceRect.width,
|
|
109
|
-
bottom: unclampedTop + surfaceRect.height,
|
|
110
|
-
width: surfaceRect.width,
|
|
111
|
-
height: surfaceRect.height,
|
|
112
|
-
}, viewport, viewportGap);
|
|
113
|
-
surface.style.left = `${Math.round(unclampedLeft + shifted.x)}px`;
|
|
114
|
-
surface.style.top = `${Math.round(unclampedTop + shifted.y)}px`;
|
|
115
|
-
surface.style.right = "auto";
|
|
116
|
-
surface.style.bottom = "auto";
|
|
117
|
-
}
|
|
118
|
-
/**
|
|
119
|
-
* One lightweight positioning controller for Looma floating UI. Native
|
|
120
|
-
* Popover provides the top layer and CSS Anchor Positioning follows a named
|
|
121
|
-
* element. Browsers without Anchor Positioning use the same flip/shift
|
|
122
|
-
* geometry through scroll/resize listeners that exist only while open.
|
|
123
|
-
*/
|
|
124
|
-
export function createAnchoredSurface(surface, options = {}) {
|
|
125
|
-
const owner = surface.ownerDocument.defaultView ?? window;
|
|
126
|
-
const placement = options.placement ?? "bottom-start";
|
|
127
|
-
const gap = Math.max(0, options.gap ?? 4);
|
|
128
|
-
const viewportGap = Math.max(0, options.viewportGap ?? 8);
|
|
129
|
-
const nativeAnchor = supportsAnchorPositioning(owner);
|
|
130
|
-
const anchorName = `--ui-anchor-${++anchorSequence}`;
|
|
131
|
-
let anchor = options.anchor ?? null;
|
|
132
|
-
let point = null;
|
|
133
|
-
let open = false;
|
|
134
|
-
let frame = null;
|
|
135
|
-
let listenerAbort = null;
|
|
136
|
-
let sizeObserver = null;
|
|
137
|
-
// The surface can enter the top layer before its content has laid out (a
|
|
138
|
-
// menu's items, a tooltip's text), so its measured size is briefly zero or
|
|
139
|
-
// stale and the viewport clamp would run against the wrong geometry. Re-run
|
|
140
|
-
// positioning whenever the surface's own size settles.
|
|
141
|
-
const ResizeObserverImpl = owner.ResizeObserver;
|
|
142
|
-
const observeSurfaceSize = () => {
|
|
143
|
-
if (sizeObserver || typeof ResizeObserverImpl !== "function")
|
|
144
|
-
return;
|
|
145
|
-
sizeObserver = new ResizeObserverImpl(() => schedule());
|
|
146
|
-
sizeObserver.observe(surface);
|
|
147
|
-
};
|
|
148
|
-
const stopObservingSurfaceSize = () => {
|
|
149
|
-
sizeObserver?.disconnect();
|
|
150
|
-
sizeObserver = null;
|
|
151
|
-
};
|
|
152
|
-
surface.setAttribute("popover", "manual");
|
|
153
|
-
surface.dataset.uiPositioning = nativeAnchor ? "anchor" : "fallback";
|
|
154
|
-
surface.style.position = "fixed";
|
|
155
|
-
surface.style.margin = "0";
|
|
156
|
-
const bindAnchor = (next) => {
|
|
157
|
-
if (anchor)
|
|
158
|
-
unbindAnchorName(anchor, anchorName);
|
|
159
|
-
anchor = next;
|
|
160
|
-
if (!anchor) {
|
|
161
|
-
surface.style.removeProperty("position-anchor");
|
|
162
|
-
return;
|
|
163
|
-
}
|
|
164
|
-
bindAnchorName(anchor, anchorName);
|
|
165
|
-
surface.style.setProperty("position-anchor", anchorName);
|
|
166
|
-
};
|
|
167
|
-
const positionNative = () => {
|
|
168
|
-
const blockEnd = placement.startsWith("bottom");
|
|
169
|
-
const inlineEnd = placement.endsWith("end");
|
|
170
|
-
surface.style.top = blockEnd ? `calc(anchor(bottom) + ${gap}px)` : "auto";
|
|
171
|
-
surface.style.bottom = blockEnd ? "auto" : `calc(anchor(top) + ${gap}px)`;
|
|
172
|
-
surface.style.left = inlineEnd ? "auto" : "anchor(left)";
|
|
173
|
-
surface.style.right = inlineEnd ? "anchor(right)" : "auto";
|
|
174
|
-
surface.style.setProperty("position-try-fallbacks", "flip-block, flip-inline");
|
|
175
|
-
};
|
|
176
|
-
const position = () => {
|
|
177
|
-
frame = null;
|
|
178
|
-
if (!open)
|
|
179
|
-
return;
|
|
180
|
-
if (point) {
|
|
181
|
-
fallbackPosition(surface, {
|
|
182
|
-
left: point.x,
|
|
183
|
-
right: point.x,
|
|
184
|
-
top: point.y,
|
|
185
|
-
bottom: point.y,
|
|
186
|
-
width: 0,
|
|
187
|
-
height: 0,
|
|
188
|
-
}, "bottom-start", gap, viewportGap);
|
|
189
|
-
return;
|
|
190
|
-
}
|
|
191
|
-
if (!anchor)
|
|
192
|
-
return;
|
|
193
|
-
let surfaceRect;
|
|
194
|
-
if (nativeAnchor) {
|
|
195
|
-
positionNative();
|
|
196
|
-
const viewport = getVisualViewportRect(owner);
|
|
197
|
-
surfaceRect = surface.getBoundingClientRect();
|
|
198
|
-
// The surface can be measured before it paints (its first frames in the
|
|
199
|
-
// top layer, or while slow content/fonts settle), reporting a zero size.
|
|
200
|
-
// The pixel fallback below would then place it at `anchor - 0`, i.e. off
|
|
201
|
-
// the anchored edge, and leave it stranded there. Trust native anchor
|
|
202
|
-
// placement — which does not depend on our measurement — until the
|
|
203
|
-
// surface has real geometry; the scheduled re-run and ResizeObserver
|
|
204
|
-
// re-position once it does.
|
|
205
|
-
if (surfaceRect.width === 0 || surfaceRect.height === 0)
|
|
206
|
-
return;
|
|
207
|
-
const shift = clampRectToViewport(surfaceRect, viewport, viewportGap);
|
|
208
|
-
if (shift.x === 0 && shift.y === 0)
|
|
209
|
-
return;
|
|
210
|
-
}
|
|
211
|
-
fallbackPosition(surface, anchor.getBoundingClientRect(), placement, gap, viewportGap, surfaceRect);
|
|
212
|
-
};
|
|
213
|
-
const schedule = () => {
|
|
214
|
-
if (!open || frame !== null)
|
|
215
|
-
return;
|
|
216
|
-
frame = owner.requestAnimationFrame(position);
|
|
217
|
-
};
|
|
218
|
-
const syncFallbackListeners = () => {
|
|
219
|
-
// Native anchor positioning handles ordinary placement, but the shared
|
|
220
|
-
// controller still owns viewport containment when neither side can fit.
|
|
221
|
-
const needsListeners = open && (point !== null || anchor !== null);
|
|
222
|
-
if (!needsListeners) {
|
|
223
|
-
listenerAbort?.abort();
|
|
224
|
-
listenerAbort = null;
|
|
225
|
-
return;
|
|
226
|
-
}
|
|
227
|
-
if (listenerAbort)
|
|
228
|
-
return;
|
|
229
|
-
listenerAbort = new AbortController();
|
|
230
|
-
const signal = listenerAbort.signal;
|
|
231
|
-
owner.addEventListener("resize", schedule, { passive: true, signal });
|
|
232
|
-
owner.addEventListener("scroll", schedule, { passive: true, capture: true, signal });
|
|
233
|
-
owner.visualViewport?.addEventListener("resize", schedule, { passive: true, signal });
|
|
234
|
-
owner.visualViewport?.addEventListener("scroll", schedule, { passive: true, signal });
|
|
235
|
-
};
|
|
236
|
-
bindAnchor(anchor);
|
|
237
|
-
return {
|
|
238
|
-
setAnchor(next) {
|
|
239
|
-
point = null;
|
|
240
|
-
bindAnchor(next);
|
|
241
|
-
syncFallbackListeners();
|
|
242
|
-
schedule();
|
|
243
|
-
},
|
|
244
|
-
show() {
|
|
245
|
-
point = null;
|
|
246
|
-
open = true;
|
|
247
|
-
syncFallbackListeners();
|
|
248
|
-
showInTopLayer(surface);
|
|
249
|
-
position();
|
|
250
|
-
// The surface has just entered the top layer and may not be laid out yet,
|
|
251
|
-
// so the first position() can measure a zero/stale size and skip the
|
|
252
|
-
// viewport clamp. Re-position on the next frame, and keep re-positioning
|
|
253
|
-
// while the surface's own size settles as its content renders.
|
|
254
|
-
schedule();
|
|
255
|
-
observeSurfaceSize();
|
|
256
|
-
},
|
|
257
|
-
showAtPoint(nextPoint) {
|
|
258
|
-
point = nextPoint;
|
|
259
|
-
open = true;
|
|
260
|
-
syncFallbackListeners();
|
|
261
|
-
showInTopLayer(surface);
|
|
262
|
-
position();
|
|
263
|
-
schedule();
|
|
264
|
-
observeSurfaceSize();
|
|
265
|
-
},
|
|
266
|
-
hide() {
|
|
267
|
-
open = false;
|
|
268
|
-
point = null;
|
|
269
|
-
syncFallbackListeners();
|
|
270
|
-
stopObservingSurfaceSize();
|
|
271
|
-
if (frame !== null)
|
|
272
|
-
owner.cancelAnimationFrame(frame);
|
|
273
|
-
frame = null;
|
|
274
|
-
hideFromTopLayer(surface);
|
|
275
|
-
},
|
|
276
|
-
refresh: schedule,
|
|
277
|
-
destroy() {
|
|
278
|
-
open = false;
|
|
279
|
-
listenerAbort?.abort();
|
|
280
|
-
listenerAbort = null;
|
|
281
|
-
stopObservingSurfaceSize();
|
|
282
|
-
if (frame !== null)
|
|
283
|
-
owner.cancelAnimationFrame(frame);
|
|
284
|
-
frame = null;
|
|
285
|
-
hideFromTopLayer(surface);
|
|
286
|
-
bindAnchor(null);
|
|
287
|
-
},
|
|
288
|
-
};
|
|
289
|
-
}
|
|
290
|
-
export function getVisualViewportRect(owner = window) {
|
|
291
|
-
const viewport = owner.visualViewport;
|
|
292
|
-
const left = viewport?.offsetLeft ?? 0;
|
|
293
|
-
const top = viewport?.offsetTop ?? 0;
|
|
294
|
-
const width = viewport?.width ?? owner.innerWidth;
|
|
295
|
-
const height = viewport?.height ?? owner.innerHeight;
|
|
296
|
-
return {
|
|
297
|
-
left,
|
|
298
|
-
top,
|
|
299
|
-
right: left + width,
|
|
300
|
-
bottom: top + height,
|
|
301
|
-
width,
|
|
302
|
-
height,
|
|
303
|
-
};
|
|
304
|
-
}
|
|
305
|
-
export function clampRectToViewport(rect, viewport = getVisualViewportRect(), gutter = 0) {
|
|
306
|
-
const availableWidth = Math.max(0, viewport.width - (gutter * 2));
|
|
307
|
-
const availableHeight = Math.max(0, viewport.height - (gutter * 2));
|
|
308
|
-
const targetLeft = rect.width > availableWidth
|
|
309
|
-
? viewport.left + gutter
|
|
310
|
-
: Math.min(Math.max(rect.left, viewport.left + gutter), viewport.right - gutter - rect.width);
|
|
311
|
-
const targetTop = rect.height > availableHeight
|
|
312
|
-
? viewport.top + gutter
|
|
313
|
-
: Math.min(Math.max(rect.top, viewport.top + gutter), viewport.bottom - gutter - rect.height);
|
|
314
|
-
return { x: targetLeft - rect.left, y: targetTop - rect.top };
|
|
315
|
-
}
|
|
316
|
-
export function distanceFromPointToRect(point, rect) {
|
|
317
|
-
const dx = Math.max(rect.left - point.x, 0, point.x - rect.right);
|
|
318
|
-
const dy = Math.max(rect.top - point.y, 0, point.y - rect.bottom);
|
|
319
|
-
return Math.hypot(dx, dy);
|
|
320
|
-
}
|
|
321
|
-
/**
|
|
322
|
-
* Coordinates anticipatory UI within one interaction scope.
|
|
323
|
-
*
|
|
324
|
-
* The coordinator deliberately owns one pointer listener and one animation-frame
|
|
325
|
-
* update for the whole scope. Anchors remain the only hit-testable controls; the
|
|
326
|
-
* reflected state is presentation-only, so overlapping near regions do not steal
|
|
327
|
-
* pointer input from each other or from surrounding content.
|
|
328
|
-
*/
|
|
329
|
-
export function createProximityCoordinator(scope, options = {}) {
|
|
330
|
-
const owner = scope.ownerDocument.defaultView ?? window;
|
|
331
|
-
const pointerTarget = options.pointerTarget ?? scope;
|
|
332
|
-
const anchorSelector = options.anchorSelector ?? "[data-ui-affordance]";
|
|
333
|
-
const configuredRadius = options.nearRadius ?? DEFAULT_AFFORDANCE_NEAR_RADIUS;
|
|
334
|
-
const nearRadius = Number.isFinite(configuredRadius)
|
|
335
|
-
? Math.max(0, configuredRadius)
|
|
336
|
-
: DEFAULT_AFFORDANCE_NEAR_RADIUS;
|
|
337
|
-
const abort = new AbortController();
|
|
338
|
-
let anchors = [];
|
|
339
|
-
let frame = null;
|
|
340
|
-
let point = null;
|
|
341
|
-
let geometryDirty = false;
|
|
342
|
-
const clear = () => {
|
|
343
|
-
for (const { element } of anchors) {
|
|
344
|
-
if (element.hasAttribute("data-ui-proximity")) {
|
|
345
|
-
element.removeAttribute("data-ui-proximity");
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
if (scope.hasAttribute("data-ui-interaction")) {
|
|
349
|
-
scope.removeAttribute("data-ui-interaction");
|
|
350
|
-
}
|
|
351
|
-
};
|
|
352
|
-
const measure = () => {
|
|
353
|
-
anchors = Array.from(scope.querySelectorAll(anchorSelector))
|
|
354
|
-
.filter((element) => !element.hasAttribute("disabled") && element.getAttribute("aria-disabled") !== "true")
|
|
355
|
-
.map((element) => ({ element, rect: element.getBoundingClientRect() }));
|
|
356
|
-
geometryDirty = false;
|
|
357
|
-
};
|
|
358
|
-
const update = () => {
|
|
359
|
-
frame = null;
|
|
360
|
-
if (geometryDirty)
|
|
361
|
-
measure();
|
|
362
|
-
if (!point) {
|
|
363
|
-
clear();
|
|
364
|
-
return;
|
|
365
|
-
}
|
|
366
|
-
let engaged = false;
|
|
367
|
-
for (const anchor of anchors) {
|
|
368
|
-
const near = distanceFromPointToRect(point, anchor.rect) <= nearRadius;
|
|
369
|
-
if (near && anchor.element.getAttribute("data-ui-proximity") !== "near") {
|
|
370
|
-
anchor.element.setAttribute("data-ui-proximity", "near");
|
|
371
|
-
}
|
|
372
|
-
else if (!near && anchor.element.hasAttribute("data-ui-proximity")) {
|
|
373
|
-
anchor.element.removeAttribute("data-ui-proximity");
|
|
374
|
-
}
|
|
375
|
-
engaged ||= near;
|
|
376
|
-
}
|
|
377
|
-
if (engaged && scope.getAttribute("data-ui-interaction") !== "engaged") {
|
|
378
|
-
scope.setAttribute("data-ui-interaction", "engaged");
|
|
379
|
-
}
|
|
380
|
-
else if (!engaged && scope.hasAttribute("data-ui-interaction")) {
|
|
381
|
-
scope.removeAttribute("data-ui-interaction");
|
|
382
|
-
}
|
|
383
|
-
};
|
|
384
|
-
const schedule = () => {
|
|
385
|
-
if (frame !== null)
|
|
386
|
-
return;
|
|
387
|
-
frame = owner.requestAnimationFrame(update);
|
|
388
|
-
};
|
|
389
|
-
const onPointerMove = (event) => {
|
|
390
|
-
const pointer = event;
|
|
391
|
-
if (pointer.pointerType === "touch") {
|
|
392
|
-
point = null;
|
|
393
|
-
}
|
|
394
|
-
else {
|
|
395
|
-
point = { x: pointer.clientX, y: pointer.clientY };
|
|
396
|
-
}
|
|
397
|
-
schedule();
|
|
398
|
-
};
|
|
399
|
-
const invalidate = () => {
|
|
400
|
-
geometryDirty = true;
|
|
401
|
-
schedule();
|
|
402
|
-
};
|
|
403
|
-
pointerTarget.addEventListener("pointermove", onPointerMove, {
|
|
404
|
-
passive: true,
|
|
405
|
-
signal: abort.signal,
|
|
406
|
-
});
|
|
407
|
-
owner.addEventListener("resize", invalidate, { passive: true, signal: abort.signal });
|
|
408
|
-
owner.addEventListener("scroll", invalidate, { passive: true, capture: true, signal: abort.signal });
|
|
409
|
-
owner.visualViewport?.addEventListener("resize", invalidate, { passive: true, signal: abort.signal });
|
|
410
|
-
owner.visualViewport?.addEventListener("scroll", invalidate, { passive: true, signal: abort.signal });
|
|
411
|
-
measure();
|
|
412
|
-
return {
|
|
413
|
-
refresh: invalidate,
|
|
414
|
-
destroy() {
|
|
415
|
-
abort.abort();
|
|
416
|
-
if (frame !== null)
|
|
417
|
-
owner.cancelAnimationFrame(frame);
|
|
418
|
-
frame = null;
|
|
419
|
-
point = null;
|
|
420
|
-
clear();
|
|
421
|
-
anchors = [];
|
|
422
|
-
},
|
|
423
|
-
};
|
|
424
|
-
}
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
/** A state prop is controlled only when the consumer supplies a value. */
|
|
2
|
-
export const isControlled = (value) => value !== undefined;
|
|
3
|
-
/** Defaults apply only when a corresponding controlled prop is omitted. */
|
|
4
|
-
export const controlledOrDefault = (value, defaultValue) => value === undefined ? defaultValue : value;
|