@threadlabs/looma 0.1.16 → 0.1.17

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.
Files changed (121) hide show
  1. package/dist/{chunk-SVINNT3E.js → chunk-OY4D3W4U.js} +29 -29
  2. package/dist/{chunk-G53JEAQK.js → chunk-SZJQ3NPX.js} +6 -3
  3. package/dist/chunk-YHXJC5M5.js +341 -0
  4. package/dist/cjs/loader.cjs.js +1 -1
  5. package/dist/cjs/looma.cjs.js +1 -1
  6. package/dist/cjs/{manager-BOpVXb92.js → manager-C9j3HZay.js} +5 -2
  7. package/dist/cjs/positioning-i0WrCAdF.js +384 -0
  8. package/dist/cjs/ui-affordance-scope.cjs.entry.js +3 -113
  9. package/dist/cjs/ui-context-menu.cjs.entry.js +40 -5
  10. package/dist/cjs/ui-dialog.cjs.entry.js +1 -1
  11. package/dist/cjs/ui-menu.cjs.entry.js +83 -2
  12. package/dist/cjs/ui-popover.cjs.entry.js +43 -3
  13. package/dist/cjs/ui-toast-region.cjs.entry.js +17 -2
  14. package/dist/cjs/ui-tooltip.cjs.entry.js +95 -27
  15. package/dist/cjs/ui-tree-item.cjs.entry.js +1 -1
  16. package/dist/collection/components/ui-context-menu/ui-context-menu.css +17 -4
  17. package/dist/collection/components/ui-context-menu/ui-context-menu.js +38 -3
  18. package/dist/collection/components/ui-menu/ui-menu.css +39 -0
  19. package/dist/collection/components/ui-menu/ui-menu.js +128 -1
  20. package/dist/collection/components/ui-popover/ui-popover.css +31 -0
  21. package/dist/collection/components/ui-popover/ui-popover.js +87 -1
  22. package/dist/collection/components/ui-toast-region/ui-toast-region.css +6 -0
  23. package/dist/collection/components/ui-toast-region/ui-toast-region.js +16 -1
  24. package/dist/collection/components/ui-tooltip/ui-tooltip.css +20 -0
  25. package/dist/collection/components/ui-tooltip/ui-tooltip.js +160 -25
  26. package/dist/collection/components/ui-tree-item/ui-tree-item.css +10 -6
  27. package/dist/collection/input-modality.js +24 -0
  28. package/dist/collection/overlay/manager.js +5 -2
  29. package/dist/collection/overlay/positioning.js +246 -0
  30. package/dist/components/p-CEYIKqYc.js +1 -0
  31. package/dist/components/p-DOulVJT7.js +1 -0
  32. package/dist/components/p-PM9a74r7.js +1 -0
  33. package/dist/components/ui-affordance-scope.js +1 -1
  34. package/dist/components/ui-context-menu.js +1 -1
  35. package/dist/components/ui-dialog.js +1 -1
  36. package/dist/components/ui-menu.js +1 -1
  37. package/dist/components/ui-popover.js +1 -1
  38. package/dist/components/ui-toast-region.js +1 -1
  39. package/dist/components/ui-tooltip.js +1 -1
  40. package/dist/components/ui-tree-item.js +1 -1
  41. package/dist/esm/loader.js +1 -1
  42. package/dist/esm/looma.js +1 -1
  43. package/dist/esm/{manager-CR7f2MQC.js → manager-PM9a74r7.js} +5 -2
  44. package/dist/esm/positioning-Bu0dmLBE.js +379 -0
  45. package/dist/esm/ui-affordance-scope.entry.js +1 -111
  46. package/dist/esm/ui-context-menu.entry.js +40 -5
  47. package/dist/esm/ui-dialog.entry.js +1 -1
  48. package/dist/esm/ui-menu.entry.js +83 -2
  49. package/dist/esm/ui-popover.entry.js +43 -3
  50. package/dist/esm/ui-toast-region.entry.js +17 -2
  51. package/dist/esm/ui-tooltip.entry.js +95 -27
  52. package/dist/esm/ui-tree-item.entry.js +1 -1
  53. package/dist/index.cjs +776 -59
  54. package/dist/index.d.cts +44 -1
  55. package/dist/index.d.ts +44 -1
  56. package/dist/index.js +235 -4
  57. package/dist/looma/looma.esm.js +1 -1
  58. package/dist/looma/{p-c6721aba.entry.js → p-11083743.entry.js} +1 -1
  59. package/dist/looma/p-1674cda4.entry.js +1 -0
  60. package/dist/looma/p-2e6f791e.entry.js +1 -0
  61. package/dist/looma/p-54c41576.entry.js +1 -0
  62. package/dist/looma/p-9194a99d.entry.js +1 -0
  63. package/dist/looma/p-Bu0dmLBE.js +1 -0
  64. package/dist/looma/p-PM9a74r7.js +1 -0
  65. package/dist/looma/p-ba01f45d.entry.js +1 -0
  66. package/dist/looma/p-caa8fc7b.entry.js +1 -0
  67. package/dist/looma/{p-ef9ca2ed.entry.js → p-d01960c2.entry.js} +2 -2
  68. package/dist/types/components/ui-context-menu/ui-context-menu.d.ts +3 -0
  69. package/dist/types/components/ui-menu/ui-menu.d.ts +13 -0
  70. package/dist/types/components/ui-popover/ui-popover.d.ts +9 -0
  71. package/dist/types/components/ui-toast-region/ui-toast-region.d.ts +2 -0
  72. package/dist/types/components/ui-tooltip/ui-tooltip.d.ts +16 -1
  73. package/dist/types/components.d.ts +71 -0
  74. package/dist/types/input-modality.d.ts +6 -0
  75. package/dist/types/overlay/manager.d.ts +3 -0
  76. package/dist/types/overlay/positioning.d.ts +33 -0
  77. package/dist/ui-affordance-scope.entry-X7DTKJGL.js +54 -0
  78. package/dist/{ui-avatar-group.entry-DQDP325O.js → ui-avatar-group.entry-MC34FKAN.js} +1 -1
  79. package/dist/{ui-avatar.entry-WYIDMOFE.js → ui-avatar.entry-OKRQWTQV.js} +1 -1
  80. package/dist/{ui-badge.entry-VGHXPEDT.js → ui-badge.entry-RI7JB7KV.js} +1 -1
  81. package/dist/{ui-button.entry-LKPLOJ22.js → ui-button.entry-PFO5TTPN.js} +1 -1
  82. package/dist/{ui-checkbox.entry-J74HEA22.js → ui-checkbox.entry-UHFWVISP.js} +1 -1
  83. package/dist/{ui-context-menu.entry-MQM2FCLI.js → ui-context-menu.entry-AIXB6U5D.js} +40 -6
  84. package/dist/{ui-dialog.entry-DQMMDO4Z.js → ui-dialog.entry-LPREQH2T.js} +2 -2
  85. package/dist/{ui-disclosure.entry-ONF7UZDC.js → ui-disclosure.entry-7XCUIYVZ.js} +1 -1
  86. package/dist/{ui-floating-action-button.entry-FKTGVC5T.js → ui-floating-action-button.entry-5PNIMUAW.js} +1 -1
  87. package/dist/{ui-form-field.entry-M3ISWQNU.js → ui-form-field.entry-77YW46SM.js} +1 -1
  88. package/dist/{ui-icon-button.entry-AWFIQUHM.js → ui-icon-button.entry-4AD6ALPQ.js} +1 -1
  89. package/dist/{ui-input.entry-JZ6RETMT.js → ui-input.entry-E7E6QDTV.js} +1 -1
  90. package/dist/{ui-menu-item.entry-5MFR5LFL.js → ui-menu-item.entry-H3HFLUB6.js} +1 -1
  91. package/dist/ui-menu.entry-UAKZU4HG.js +184 -0
  92. package/dist/{ui-popover.entry-ELCMKO6Y.js → ui-popover.entry-GVQKX26B.js} +46 -4
  93. package/dist/{ui-radio-group.entry-RJHUPPEM.js → ui-radio-group.entry-MNSR6UEE.js} +1 -1
  94. package/dist/{ui-radio.entry-3VRDPOY4.js → ui-radio.entry-6D4WTI5E.js} +1 -1
  95. package/dist/{ui-search-result-row.entry-J34YPAV7.js → ui-search-result-row.entry-J2TILUH2.js} +1 -1
  96. package/dist/{ui-search-shell.entry-IJ4UUP27.js → ui-search-shell.entry-FSWHEZQF.js} +1 -1
  97. package/dist/{ui-select.entry-C6YD3HQ5.js → ui-select.entry-JRCYYNNW.js} +1 -1
  98. package/dist/{ui-switch.entry-UZDF5QTI.js → ui-switch.entry-YZWMNRP2.js} +1 -1
  99. package/dist/{ui-tabs.entry-YRAKWOMR.js → ui-tabs.entry-F2Y344JY.js} +1 -1
  100. package/dist/{ui-textarea.entry-JLDKFT3K.js → ui-textarea.entry-3EZCUUAK.js} +1 -1
  101. package/dist/{ui-toast-region.entry-GC7C7KXF.js → ui-toast-region.entry-BTV4AW3I.js} +20 -3
  102. package/dist/ui-tooltip.entry-U644CF5U.js +214 -0
  103. package/dist/{ui-top-bar.entry-5W5UA5KV.js → ui-top-bar.entry-FGGOREQR.js} +1 -1
  104. package/dist/{ui-tree-item.entry-3LM7IXIK.js → ui-tree-item.entry-XVMHEONY.js} +2 -2
  105. package/dist/{ui-tree.entry-X4FU42A6.js → ui-tree.entry-4R7DYGAM.js} +1 -1
  106. package/editor.css +3 -4
  107. package/package.json +1 -1
  108. package/tokens.css +14 -2
  109. package/vue/editor/index.js +62 -51
  110. package/dist/components/p-CR7f2MQC.js +0 -1
  111. package/dist/components/p-QiwSQmKJ.js +0 -1
  112. package/dist/looma/p-2ae73d5b.entry.js +0 -1
  113. package/dist/looma/p-3ac2e0d4.entry.js +0 -1
  114. package/dist/looma/p-65c25c94.entry.js +0 -1
  115. package/dist/looma/p-8c09c724.entry.js +0 -1
  116. package/dist/looma/p-95cd639d.entry.js +0 -1
  117. package/dist/looma/p-96f73d07.entry.js +0 -1
  118. package/dist/looma/p-CR7f2MQC.js +0 -1
  119. package/dist/ui-affordance-scope.entry-PFP2TDKO.js +0 -145
  120. package/dist/ui-menu.entry-IOEIDATQ.js +0 -98
  121. package/dist/ui-tooltip.entry-F26XDTYX.js +0 -145
@@ -0,0 +1,214 @@
1
+ import {
2
+ closeOverlay,
3
+ openOverlay,
4
+ requestTopOverlayClose
5
+ } from "./chunk-SZJQ3NPX.js";
6
+ import {
7
+ createAnchoredSurface
8
+ } from "./chunk-YHXJC5M5.js";
9
+ import {
10
+ dispatchDetail
11
+ } from "./chunk-UL7UIUJZ.js";
12
+ import {
13
+ Host,
14
+ getElement,
15
+ h,
16
+ registerInstance
17
+ } from "./chunk-OY4D3W4U.js";
18
+
19
+ // dist/esm/ui-tooltip.entry.js
20
+ var uiTooltipCss = () => `:host{position:fixed;inset:auto;margin:0;display:inline-block;border:1px solid var(--ui-border-default);border-radius:var(--ui-radius-2);background:var(--ui-surface-elevated);color:var(--ui-text-primary);padding:var(--ui-space-2) var(--ui-space-3);font-size:var(--ui-font-size-sm);box-shadow:var(--ui-shadow-md);opacity:0;transform:translateY(4px);transition:opacity var(--ui-motion-fast) var(--ui-motion-ease), transform var(--ui-motion-fast) var(--ui-motion-ease), display var(--ui-motion-fast) allow-discrete, overlay var(--ui-motion-fast) allow-discrete}:host(:popover-open){opacity:1;transform:translateY(0)}@starting-style{:host(:popover-open){opacity:0;transform:translateY(4px)}}:host([hidden]){display:none !important}@media (prefers-reduced-motion: reduce){:host{transition:none}}`;
21
+ var UITooltip = class {
22
+ constructor(hostRef) {
23
+ registerInstance(this, hostRef);
24
+ }
25
+ get host() {
26
+ return getElement(this);
27
+ }
28
+ for = "";
29
+ open = false;
30
+ defaultOpen = false;
31
+ placement = "top-start";
32
+ /** Pointer hover intent delay in milliseconds. Keyboard focus is immediate. */
33
+ showDelay = 500;
34
+ /** Pointer leave grace period in milliseconds. */
35
+ hideDelay = 100;
36
+ internalOpen = false;
37
+ overlayId = `ui-tooltip-${Math.random().toString(36).slice(2, 11)}`;
38
+ trigger = null;
39
+ surface = null;
40
+ showTimer = null;
41
+ hideTimer = null;
42
+ syncFromProp() {
43
+ this.clearTimers();
44
+ this.internalOpen = this.open;
45
+ }
46
+ resetSurface() {
47
+ this.syncTrigger();
48
+ this.setupSurface();
49
+ this.syncOverlay();
50
+ }
51
+ syncOverlay() {
52
+ if (this.internalOpen) {
53
+ this.surface?.show();
54
+ openOverlay({
55
+ id: this.overlayId,
56
+ modal: false,
57
+ element: this.host,
58
+ relatedElements: this.trigger ? [this.trigger] : void 0,
59
+ dismissible: true,
60
+ requestClose: (reason, trigger) => this.handleRequestClose(reason, trigger)
61
+ });
62
+ } else {
63
+ this.surface?.hide();
64
+ closeOverlay(this.overlayId);
65
+ }
66
+ }
67
+ componentDidLoad() {
68
+ this.syncFromProp();
69
+ this.internalOpen = this.internalOpen || this.defaultOpen;
70
+ this.syncTrigger();
71
+ this.setupSurface();
72
+ this.host.addEventListener("keydown", this.onKeydown);
73
+ this.syncOverlay();
74
+ }
75
+ componentDidUpdate() {
76
+ this.syncTrigger();
77
+ }
78
+ disconnectedCallback() {
79
+ this.clearTimers();
80
+ this.detachTriggerListeners();
81
+ this.surface?.destroy();
82
+ this.surface = null;
83
+ this.host.removeEventListener("keydown", this.onKeydown);
84
+ closeOverlay(this.overlayId);
85
+ }
86
+ syncTrigger() {
87
+ const next = this.for ? this.host.ownerDocument.getElementById(this.for) : this.host.previousElementSibling;
88
+ if (next === this.trigger)
89
+ return;
90
+ this.detachTriggerListeners();
91
+ this.trigger = next;
92
+ this.attachTriggerListeners();
93
+ this.surface?.setAnchor(next);
94
+ }
95
+ setupSurface() {
96
+ this.surface?.destroy();
97
+ this.surface = createAnchoredSurface(this.host, {
98
+ anchor: this.trigger,
99
+ placement: this.placement
100
+ });
101
+ }
102
+ attachTriggerListeners() {
103
+ this.detachTriggerListeners();
104
+ if (!this.trigger)
105
+ return;
106
+ this.trigger.addEventListener("pointerenter", this.onTriggerEnter);
107
+ this.trigger.addEventListener("pointerleave", this.onTriggerLeave);
108
+ this.trigger.addEventListener("focusin", this.onTriggerFocusIn);
109
+ this.trigger.addEventListener("focusout", this.onTriggerFocusOut);
110
+ }
111
+ detachTriggerListeners() {
112
+ if (!this.trigger)
113
+ return;
114
+ this.trigger.removeEventListener("pointerenter", this.onTriggerEnter);
115
+ this.trigger.removeEventListener("pointerleave", this.onTriggerLeave);
116
+ this.trigger.removeEventListener("focusin", this.onTriggerFocusIn);
117
+ this.trigger.removeEventListener("focusout", this.onTriggerFocusOut);
118
+ }
119
+ clearShowTimer() {
120
+ if (this.showTimer === null)
121
+ return;
122
+ clearTimeout(this.showTimer);
123
+ this.showTimer = null;
124
+ }
125
+ clearHideTimer() {
126
+ if (this.hideTimer === null)
127
+ return;
128
+ clearTimeout(this.hideTimer);
129
+ this.hideTimer = null;
130
+ }
131
+ clearTimers() {
132
+ this.clearShowTimer();
133
+ this.clearHideTimer();
134
+ }
135
+ setInteractionOpen(nextOpen, trigger) {
136
+ if (this.internalOpen === nextOpen)
137
+ return;
138
+ this.internalOpen = nextOpen;
139
+ dispatchDetail(this.host, nextOpen ? "open" : "close", {
140
+ open: nextOpen,
141
+ reason: "action",
142
+ trigger
143
+ });
144
+ }
145
+ onTriggerEnter = () => {
146
+ this.clearHideTimer();
147
+ if (this.internalOpen || this.showTimer !== null)
148
+ return;
149
+ this.showTimer = setTimeout(() => {
150
+ this.showTimer = null;
151
+ this.setInteractionOpen(true, "pointer");
152
+ }, Math.max(0, this.showDelay));
153
+ };
154
+ onTriggerLeave = () => {
155
+ this.clearShowTimer();
156
+ if (!this.internalOpen || this.hideTimer !== null)
157
+ return;
158
+ this.hideTimer = setTimeout(() => {
159
+ this.hideTimer = null;
160
+ this.setInteractionOpen(false, "pointer");
161
+ }, Math.max(0, this.hideDelay));
162
+ };
163
+ onTriggerFocusIn = () => {
164
+ this.clearTimers();
165
+ this.setInteractionOpen(true, "keyboard");
166
+ };
167
+ onTriggerFocusOut = (e) => {
168
+ const related = e.relatedTarget;
169
+ if (related && this.host.contains(related))
170
+ return;
171
+ this.clearTimers();
172
+ this.setInteractionOpen(false, "keyboard");
173
+ };
174
+ handleRequestClose(reason, trigger) {
175
+ if (reason === "escape") {
176
+ this.clearTimers();
177
+ this.internalOpen = false;
178
+ dispatchDetail(this.host, "close", {
179
+ open: false,
180
+ reason: "escape",
181
+ trigger
182
+ });
183
+ this.trigger?.focus();
184
+ }
185
+ }
186
+ onKeydown = (e) => {
187
+ if (e.key === "Escape") {
188
+ requestTopOverlayClose("escape", "keyboard");
189
+ }
190
+ };
191
+ render() {
192
+ return h(Host, { key: "4c3890a7371508ede06a5b370d1cec32db25280f", role: "tooltip", hidden: !this.internalOpen, "data-open": this.internalOpen ? "" : void 0, onKeyDown: this.onKeydown }, h("slot", { key: "2e3bcd0dc69b0c3e3376d73dc4efc82e4f4cfaaa" }));
193
+ }
194
+ static get watchers() {
195
+ return {
196
+ "open": [{
197
+ "syncFromProp": 0
198
+ }],
199
+ "for": [{
200
+ "resetSurface": 0
201
+ }],
202
+ "placement": [{
203
+ "resetSurface": 0
204
+ }],
205
+ "internalOpen": [{
206
+ "syncOverlay": 0
207
+ }]
208
+ };
209
+ }
210
+ };
211
+ UITooltip.style = uiTooltipCss();
212
+ export {
213
+ UITooltip as ui_tooltip
214
+ };
@@ -3,7 +3,7 @@ import {
3
3
  getElement,
4
4
  h,
5
5
  registerInstance
6
- } from "./chunk-SVINNT3E.js";
6
+ } from "./chunk-OY4D3W4U.js";
7
7
 
8
8
  // dist/esm/ui-top-bar.entry.js
9
9
  var uiTopBarCss = () => `:host{position:sticky;inset-block-start:0;z-index:var(--ui-top-bar-z-index, 100);display:block}.top-bar{min-block-size:calc(var(--ui-top-bar-height, 56px) + env(safe-area-inset-top));display:flex;align-items:center;gap:var(--ui-top-bar-gap, var(--ui-space-3, 0.75rem));padding-block-start:env(safe-area-inset-top);padding-inline-start:max( var(--ui-top-bar-padding-inline, var(--ui-space-4, 1rem)), env(safe-area-inset-left) );padding-inline-end:max( var(--ui-top-bar-padding-inline, var(--ui-space-4, 1rem)), env(safe-area-inset-right) );background:var(--ui-top-bar-bg, var(--ui-surface, #ffffff));border-block-end:1px solid var(--ui-top-bar-border, var(--ui-border, #e5e7eb))}.top-bar__leading,.top-bar__search,.top-bar__actions{display:flex;align-items:center;flex-shrink:0}.top-bar__actions{gap:var(--ui-top-bar-actions-gap, var(--ui-space-1, 0.25rem))}.top-bar__title{min-inline-size:0;flex:1}[hidden]{display:none}@media (min-width: 768px){:host{display:none}}`;
@@ -7,7 +7,7 @@ import {
7
7
  getElement,
8
8
  h,
9
9
  registerInstance
10
- } from "./chunk-SVINNT3E.js";
10
+ } from "./chunk-OY4D3W4U.js";
11
11
 
12
12
  // dist/esm/ui-tree-item.entry.js
13
13
  var Bold = [
@@ -285,7 +285,7 @@ function loomaIconMarkup(name, className = "looma-icon") {
285
285
  "</svg>"
286
286
  ].join("");
287
287
  }
288
- var uiTreeItemCss = () => `:host{--ui-tree-indent:16px;--ui-tree-row-min-height:44px;--ui-tree-drop-color:var(--ui-accent-solid);position:relative;display:block;min-inline-size:0;margin-inline-start:calc(var(--ui-tree-item-depth, 0) * var(--ui-tree-indent))}.row{position:relative;display:grid;grid-template-columns:20px auto minmax(0, 1fr) auto;align-items:center;min-block-size:var(--ui-tree-row-min-height);min-inline-size:0;border-radius:var(--ui-radius-md);color:var(--ui-text-secondary);transition:background-color var(--ui-motion-fast) var(--ui-motion-ease), color var(--ui-motion-fast) var(--ui-motion-ease), opacity var(--ui-motion-fast) var(--ui-motion-ease), box-shadow var(--ui-motion-fast) var(--ui-motion-ease)}.row:hover,:host([data-selected]) .row,.row:focus-within{color:var(--ui-text-primary);background:var(--ui-surface-muted)}:host([data-disabled]) .row{opacity:0.55}:host([data-dragging]) .row{opacity:0.42}:host(:focus){outline:none}:host(:focus-visible) .row{box-shadow:0 0 0 2px var(--ui-focus-ring)}:host([data-drop-position='inside']) .row{background:var(--ui-accent-subtle);box-shadow:inset 0 0 0 1px var(--ui-tree-drop-color)}.disclosure,.disclosure-spacer{grid-column:1;grid-row:1;inline-size:20px;block-size:28px}.disclosure{display:grid;place-items:center;padding:0;color:var(--ui-text-muted);background:transparent;border:0;border-radius:var(--ui-radius-sm);cursor:pointer}.disclosure:hover{color:var(--ui-text-primary);background:var(--ui-surface-elevated)}.disclosure-icon{display:block;inline-size:14px;block-size:14px;transform:rotate(-90deg);transition:transform var(--ui-motion-fast) var(--ui-motion-ease)}.disclosure-icon--expanded{transform:rotate(0deg)}.disclosure-icon :is(svg),.drag-handle :is(svg){display:block;inline-size:100%;block-size:100%}.leading{display:none}.leading:has(*){display:inline-grid;place-items:center;grid-column:2;grid-row:1;inline-size:16px;block-size:16px;margin-inline-start:var(--ui-space-1)}.label{grid-column:3;grid-row:1;min-inline-size:0;padding:var(--ui-space-1) var(--ui-space-2)}.actions{grid-column:4;grid-row:1;display:inline-flex;align-items:center;min-inline-size:0}.drag-handle{position:absolute;z-index:2;inset-block-start:50%;inset-inline-start:-22px;inline-size:20px;block-size:32px;display:grid;place-items:center;padding:7px 3px;color:var(--ui-text-muted);background:var(--ui-surface-elevated);border:1px solid transparent;border-radius:var(--ui-radius-sm);cursor:grab;opacity:0;pointer-events:none;transform:translateY(-50%);transition:opacity var(--ui-motion-fast) var(--ui-motion-ease)}.row:hover .drag-handle,.drag-handle:focus-visible,:host([data-dragging]) .drag-handle{opacity:1;pointer-events:auto}.drag-handle:active{cursor:grabbing}.drop-indicator{position:absolute;z-index:3;inset-inline:1px;display:none;block-size:2px;border-radius:999px;background:var(--ui-tree-drop-color);pointer-events:none}.drop-indicator::before,.drop-indicator::after{content:'';position:absolute;inset-block-start:50%;inline-size:7px;block-size:7px;border:2px solid var(--ui-tree-drop-color);border-radius:999px;background:var(--ui-surface-elevated);transform:translateY(-50%)}.drop-indicator::before{inset-inline-start:-1px}.drop-indicator::after{inset-inline-end:-1px}:host([data-drop-position='before']) .drop-indicator{display:block;inset-block-start:-1px}:host([data-drop-position='after']) .drop-indicator{display:block;inset-block-end:-1px}.children[hidden]{display:none}@media (hover: none), (pointer: coarse){.drag-handle{display:none}}@media (prefers-reduced-motion: reduce){.row,.disclosure-icon,.drag-handle{transition:none}}`;
288
+ var uiTreeItemCss = () => `:host{--ui-tree-indent:16px;--ui-tree-row-min-height:32px;--ui-tree-drop-color:var(--ui-accent-solid);position:relative;display:block;min-inline-size:0;margin-inline-start:calc(var(--ui-tree-item-depth, 0) * var(--ui-tree-indent))}.row{position:relative;display:grid;grid-template-columns:20px auto minmax(0, 1fr) auto;align-items:center;min-block-size:var(--ui-tree-row-min-height);min-inline-size:0;font-size:var(--ui-tree-font-size, var(--ui-font-size-ui, 0.9375rem));border-radius:var(--ui-radius-md);color:var(--ui-text-secondary);transition:background-color var(--ui-motion-fast) var(--ui-motion-ease), color var(--ui-motion-fast) var(--ui-motion-ease), opacity var(--ui-motion-fast) var(--ui-motion-ease), box-shadow var(--ui-motion-fast) var(--ui-motion-ease), min-block-size var(--ui-motion-base) var(--ui-motion-ease)}.row:hover,:host([data-selected]) .row,.row:focus-within{color:var(--ui-text-primary);background:var(--ui-surface-muted)}:host([data-disabled]) .row{opacity:0.55}:host([data-dragging]) .row{opacity:0.42}:host(:focus){outline:none}:host(:focus-visible) .row{box-shadow:0 0 0 2px var(--ui-focus-ring)}:host([data-drop-position='inside']) .row{background:var(--ui-accent-subtle);box-shadow:inset 0 0 0 1px var(--ui-tree-drop-color)}.disclosure,.disclosure-spacer{grid-column:1;grid-row:1;inline-size:20px;block-size:28px}.disclosure{display:grid;place-items:center;padding:0;color:var(--ui-text-muted);background:transparent;border:0;border-radius:var(--ui-radius-sm);cursor:pointer}.disclosure:hover{color:var(--ui-text-primary);background:var(--ui-surface-elevated)}.disclosure-icon{display:block;inline-size:14px;block-size:14px;transform:rotate(-90deg);transition:transform var(--ui-motion-fast) var(--ui-motion-ease)}.disclosure-icon--expanded{transform:rotate(0deg)}.disclosure-icon :is(svg),.drag-handle :is(svg){display:block;inline-size:100%;block-size:100%}.leading{display:none}.leading:has(*){display:inline-grid;place-items:center;grid-column:2;grid-row:1;inline-size:16px;block-size:16px;margin-inline-start:var(--ui-space-1)}.label{grid-column:3;grid-row:1;min-inline-size:0;padding:var(--ui-space-1) var(--ui-space-2)}.actions{grid-column:4;grid-row:1;display:inline-flex;align-items:center;min-inline-size:0}.drag-handle{position:absolute;z-index:2;inset-block-start:50%;inset-inline-start:-22px;inline-size:20px;block-size:32px;display:grid;place-items:center;padding:7px 3px;color:var(--ui-text-muted);background:var(--ui-surface-elevated);border:1px solid transparent;border-radius:var(--ui-radius-sm);cursor:grab;opacity:0;pointer-events:none;transform:translateY(-50%);transition:opacity var(--ui-motion-fast) var(--ui-motion-ease)}.row:hover .drag-handle,.drag-handle:focus-visible,:host([data-dragging]) .drag-handle{opacity:1;pointer-events:auto}.drag-handle:active{cursor:grabbing}.drop-indicator{position:absolute;z-index:3;inset-inline:1px;display:none;block-size:2px;border-radius:999px;background:var(--ui-tree-drop-color);pointer-events:none}.drop-indicator::before,.drop-indicator::after{content:'';position:absolute;inset-block-start:50%;inline-size:7px;block-size:7px;border:2px solid var(--ui-tree-drop-color);border-radius:999px;background:var(--ui-surface-elevated);transform:translateY(-50%)}.drop-indicator::before{inset-inline-start:-1px}.drop-indicator::after{inset-inline-end:-1px}:host([data-drop-position='before']) .drop-indicator{display:block;inset-block-start:-1px}:host([data-drop-position='after']) .drop-indicator{display:block;inset-block-end:-1px}.children[hidden]{display:none}:host-context(html[data-ui-input-modality='touch']){--ui-tree-row-min-height:44px}:host-context(html[data-ui-input-modality='touch']) .drag-handle{display:none}@media (prefers-reduced-motion: reduce){.row,.disclosure-icon,.drag-handle{transition:none}}`;
289
289
  var UITreeItem = class {
290
290
  constructor(hostRef) {
291
291
  registerInstance(this, hostRef);
@@ -6,7 +6,7 @@ import {
6
6
  getElement,
7
7
  h,
8
8
  registerInstance
9
- } from "./chunk-SVINNT3E.js";
9
+ } from "./chunk-OY4D3W4U.js";
10
10
 
11
11
  // dist/esm/ui-tree.entry.js
12
12
  function classifyDropPosition(rect, clientY, acceptsChildren) {
package/editor.css CHANGED
@@ -239,10 +239,6 @@
239
239
  stroke-width: var(--ui-editor-toolbar-icon-stroke-width, 1.75);
240
240
  }
241
241
 
242
- .looma-editor__table-picker-anchor {
243
- display: inline-flex;
244
- }
245
-
246
242
  .looma-editor__table-picker-popover,
247
243
  .looma-editor__table-toolbar-shell,
248
244
  .looma-editor__table-menu-shell {
@@ -251,6 +247,9 @@
251
247
 
252
248
  .looma-editor__table-picker-popover {
253
249
  min-width: 220px;
250
+ padding: 0;
251
+ border: 0;
252
+ background: transparent;
254
253
  }
255
254
 
256
255
  .looma-editor__table-toolbar-shell,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@threadlabs/looma",
3
- "version": "0.1.16",
3
+ "version": "0.1.17",
4
4
  "type": "module",
5
5
  "description": "Looma web components, responsive layout primitives, a complete editor, and supported Vue adapters.",
6
6
  "license": "MIT",
package/tokens.css CHANGED
@@ -1,6 +1,16 @@
1
1
  @layer tokens {
2
2
  :root {
3
- --ui-font-stack-system: system-ui, sans-serif;
3
+ --ui-font-stack-system:
4
+ system-ui,
5
+ -apple-system,
6
+ BlinkMacSystemFont,
7
+ "Segoe UI",
8
+ Roboto,
9
+ Helvetica,
10
+ Arial,
11
+ sans-serif,
12
+ "Apple Color Emoji",
13
+ "Segoe UI Emoji";
4
14
  --ui-font-stack-neo-grotesque:
5
15
  Inter,
6
16
  Roboto,
@@ -28,9 +38,11 @@
28
38
  Calibri,
29
39
  source-sans-pro,
30
40
  sans-serif;
31
- --ui-font-family-sans: var(--ui-font-stack-neo-grotesque);
41
+ --ui-font-family-sans: var(--ui-font-stack-system);
32
42
  --ui-font-size-xs: 0.75rem;
33
43
  --ui-font-size-sm: 0.875rem;
44
+ /* Dense interactive text: legible at 15px without body-copy spacing. */
45
+ --ui-font-size-ui: 0.9375rem;
34
46
  --ui-font-size-md: 1rem;
35
47
  --ui-font-size-lg: 1.125rem;
36
48
  --ui-font-size-xl: 1.25rem;
@@ -1,5 +1,6 @@
1
1
  import {
2
2
  IconButton,
3
+ Popover,
3
4
  createAdapterComponent,
4
5
  toHTMLElement
5
6
  } from "../chunk-5KWCMTXB.js";
@@ -104,6 +105,7 @@ var EDITOR_ADAPTER_COMPONENT_TAG_MAP = {
104
105
 
105
106
  // src/editor/LoomaEditor.ts
106
107
  import { BubbleMenu, EditorContent, useEditor } from "@tiptap/vue-3";
108
+ import { TextSelection } from "@tiptap/pm/state";
107
109
  import {
108
110
  defineComponent as defineComponent2,
109
111
  h as h2,
@@ -112,6 +114,7 @@ import {
112
114
  onMounted,
113
115
  reactive,
114
116
  ref,
117
+ useId,
115
118
  watch
116
119
  } from "vue";
117
120
  import {
@@ -125,11 +128,7 @@ import {
125
128
  resolveTableCellAt,
126
129
  shouldShowTextFormattingToolbar
127
130
  } from "@threadlabs/looma/editor";
128
- import {
129
- clampRectToViewport,
130
- getVisualViewportRect,
131
- LOOMA_ICONS
132
- } from "@threadlabs/looma/core";
131
+ import { getVisualViewportRect, LOOMA_ICONS } from "@threadlabs/looma/core";
133
132
 
134
133
  // src/editor/image-delivery.ts
135
134
  import { Extension } from "@tiptap/core";
@@ -388,8 +387,7 @@ var LoomaEditor = defineComponent2({
388
387
  setup(props, { attrs, emit, expose }) {
389
388
  const root = ref(null);
390
389
  const fileInput = ref(null);
391
- const tablePickerAnchor = ref(null);
392
- const tablePickerPopover = ref(null);
390
+ const tablePickerAnchorId = `looma-editor-table-picker-${useId().replace(/[^a-zA-Z0-9_-]/g, "")}`;
393
391
  const tableToolbarShell = ref(null);
394
392
  const tableOverlayShell = ref(null);
395
393
  const tableMenuShell = ref(null);
@@ -398,7 +396,6 @@ var LoomaEditor = defineComponent2({
398
396
  const uploading = ref(false);
399
397
  const failedUpload = ref(null);
400
398
  const tablePickerOpen = ref(false);
401
- const tablePickerStyle = ref({});
402
399
  const mobileToolbarStyle = ref({});
403
400
  const mobile = ref(typeof window !== "undefined" && window.innerWidth <= 767);
404
401
  const editorFocused = ref(false);
@@ -441,6 +438,17 @@ var LoomaEditor = defineComponent2({
441
438
  const imageDelivery = createLoomaImageDeliveryController({
442
439
  resolveAttributes: () => props.resolveImageAttributes
443
440
  });
441
+ let lastFocusedSelection = null;
442
+ const rememberSelection = (instance) => {
443
+ if (!instance.isFocused) return;
444
+ const selection = instance.view.state.selection;
445
+ lastFocusedSelection = {
446
+ bookmark: selection.getBookmark(),
447
+ from: selection.from,
448
+ to: selection.to,
449
+ text: selection instanceof TextSelection
450
+ };
451
+ };
444
452
  const editor = useEditor({
445
453
  extensions: [
446
454
  ...getDefaultEditorExtensions({ placeholder: props.placeholder }),
@@ -451,6 +459,8 @@ var LoomaEditor = defineComponent2({
451
459
  content: props.modelValue,
452
460
  editable: props.editable,
453
461
  onCreate: ({ editor: instance }) => emit("ready", instance),
462
+ onFocus: ({ editor: instance }) => rememberSelection(instance),
463
+ onSelectionUpdate: ({ editor: instance }) => rememberSelection(instance),
454
464
  onUpdate: ({ editor: instance }) => {
455
465
  const value = instance.getJSON();
456
466
  emit("update:modelValue", value);
@@ -465,7 +475,30 @@ var LoomaEditor = defineComponent2({
465
475
  watch(() => props.modelValue, (value) => {
466
476
  const instance = editor.value;
467
477
  if (!instance || sameDocument(instance.getJSON(), value)) return;
468
- instance.commands.setContent(value, false);
478
+ const wasFocused = instance.isFocused;
479
+ const previousSelection = lastFocusedSelection ?? {
480
+ bookmark: instance.view.state.selection.getBookmark(),
481
+ from: instance.view.state.selection.from,
482
+ to: instance.view.state.selection.to,
483
+ text: instance.view.state.selection instanceof TextSelection
484
+ };
485
+ if (!wasFocused) {
486
+ instance.commands.setContent(value, false);
487
+ return;
488
+ }
489
+ instance.chain().setContent(value, false).command(({ tr }) => {
490
+ try {
491
+ tr.setSelection(previousSelection.text ? TextSelection.create(tr.doc, previousSelection.from, previousSelection.to) : previousSelection.bookmark.resolve(tr.doc));
492
+ } catch {
493
+ const max = tr.doc.content.size;
494
+ const from = Math.max(1, Math.min(previousSelection.from, max));
495
+ const to = Math.max(from, Math.min(previousSelection.to, max));
496
+ tr.setSelection(TextSelection.create(tr.doc, from, to));
497
+ }
498
+ return true;
499
+ }).run();
500
+ instance.view.focus();
501
+ rememberSelection(instance);
469
502
  }, { deep: true });
470
503
  const closeTableUi = () => {
471
504
  tableUi.toolbarOpen = false;
@@ -574,38 +607,9 @@ var LoomaEditor = defineComponent2({
574
607
  unbindEditorUi(previous);
575
608
  bindEditorUi(instance);
576
609
  }, { immediate: true });
577
- const updateTablePickerPosition = () => {
578
- const anchor = tablePickerAnchor.value;
579
- if (!anchor) return;
580
- const rect = anchor.getBoundingClientRect();
581
- const viewport = getVisualViewportRect(window);
582
- const width = 220;
583
- const popoverHeight = tablePickerPopover.value?.getBoundingClientRect().height || 300;
584
- const target = {
585
- left: rect.left,
586
- top: rect.bottom + 8,
587
- right: rect.left + width,
588
- bottom: rect.bottom + 8 + popoverHeight,
589
- width,
590
- height: popoverHeight
591
- };
592
- const offset = clampRectToViewport(
593
- target,
594
- viewport,
595
- 12
596
- );
597
- const left = target.left + offset.x;
598
- const top = target.top + offset.y;
599
- tablePickerStyle.value = window.innerWidth <= 767 ? {
600
- position: "fixed",
601
- left: `${left}px`,
602
- top: `${Math.max(viewport.top + 12, viewport.bottom - popoverHeight - 64)}px`
603
- } : { position: "fixed", top: `${top}px`, left: `${left}px` };
604
- };
605
610
  const onViewportChange = () => {
606
611
  updateMobileViewport();
607
612
  updateTableUi();
608
- updateTablePickerPosition();
609
613
  tableUi.menuOpen = false;
610
614
  };
611
615
  const onDocumentPointerDown = (event) => {
@@ -618,9 +622,6 @@ var LoomaEditor = defineComponent2({
618
622
  if (inTableUi) setTimeout(() => {
619
623
  tableInteractionActive = false;
620
624
  }, 0);
621
- if (tablePickerOpen.value && !inElement(tablePickerAnchor.value) && !inElement(tablePickerPopover.value)) {
622
- tablePickerOpen.value = false;
623
- }
624
625
  if ((tableUi.toolbarOpen || tableUi.overlayOpen || tableUi.menuOpen) && !inElement(root.value) && !inTableUi) {
625
626
  closeTableUi();
626
627
  }
@@ -858,12 +859,18 @@ var LoomaEditor = defineComponent2({
858
859
  commandButton("Code block", "braces", instance.isActive("codeBlock"), !instance.can().toggleCodeBlock(), () => instance.chain().focus().toggleCodeBlock().run()),
859
860
  commandButton("Divider", "minus", false, !instance.can().setHorizontalRule(), () => instance.chain().focus().setHorizontalRule().run()),
860
861
  h2("span", { class: "ui-editor-toolbar__divider", "aria-hidden": "true" }),
861
- h2("span", { ref: tablePickerAnchor, class: "looma-editor__table-picker-anchor" }, [
862
- commandButton("Insert table", "table", false, false, () => {
862
+ h2(IconButton, {
863
+ id: tablePickerAnchorId,
864
+ class: "looma-editor__toolbar-button",
865
+ label: "Insert table",
866
+ title: "Insert table",
867
+ size: "sm",
868
+ variant: tablePickerOpen.value ? "solid" : "ghost",
869
+ "aria-expanded": tablePickerOpen.value ? "true" : "false",
870
+ onClick: () => {
863
871
  tablePickerOpen.value = !tablePickerOpen.value;
864
- nextTick(updateTablePickerPosition);
865
- })
866
- ]),
872
+ }
873
+ }, () => loomaIcon("table")),
867
874
  commandButton(uploading.value ? "Uploading image" : "Insert image", "image", false, uploading.value || !props.uploadImage, () => fileInput.value?.click()),
868
875
  h2("span", { class: "ui-editor-toolbar__divider", "aria-hidden": "true" }),
869
876
  commandButton("Undo", "undo", false, !instance.can().undo(), () => instance.chain().focus().undo().run()),
@@ -976,17 +983,21 @@ var LoomaEditor = defineComponent2({
976
983
  loomaIcon("image"),
977
984
  h2("span", "Drop image to upload")
978
985
  ]) : null,
979
- tablePickerOpen.value ? h2("div", {
980
- ref: tablePickerPopover,
986
+ h2(Popover, {
981
987
  class: "looma-editor__table-picker-popover",
982
- style: tablePickerStyle.value
983
- }, [h2(EditorInsertTableGrid, {
988
+ open: tablePickerOpen.value,
989
+ for: tablePickerAnchorId,
990
+ placement: mobile.value ? "top-start" : "bottom-start",
991
+ onClose: () => {
992
+ tablePickerOpen.value = false;
993
+ }
994
+ }, () => [h2(EditorInsertTableGrid, {
984
995
  open: true,
985
996
  onInsertTable: (detail) => {
986
997
  instance?.chain().focus().insertTable(detail).run();
987
998
  tablePickerOpen.value = false;
988
999
  }
989
- })]) : null,
1000
+ })]),
990
1001
  slash.active && slash.items.length > 0 ? h2(EditorSlashMenu, {
991
1002
  open: true,
992
1003
  query: slash.query,
@@ -1 +0,0 @@
1
- const n=[],t="data-ui-scroll-lock";let e=0,o=!1;function c(){if("undefined"==typeof document)return;const n=document.documentElement;if(e>0)return n.setAttribute(t,"true"),void(n.style.overflow="hidden");n.removeAttribute(t),n.style.removeProperty("overflow")}function u(n){return n.dismissible??!0}function i(n){"Escape"===n.key&&a("escape","keyboard")}function d(n){const t=f();if(!t||!u(t))return;const e=n.target;e instanceof Node&&t.element.contains(e)||a("light-dismiss","pointer")}function r(t){s(t.id),n.push(t),t.modal&&(e+=1,c()),o||"undefined"==typeof document||(document.addEventListener("keydown",i),document.addEventListener("pointerdown",d,{capture:!0}),o=!0)}function s(t){const u=n.findIndex((n=>n.id===t));if(u>=0){const[t]=n.splice(u,1);t?.modal&&(e=Math.max(0,e-1),c())}!o||n.length>0||"undefined"==typeof document||(document.removeEventListener("keydown",i),document.removeEventListener("pointerdown",d,{capture:!0}),o=!1)}function f(){return n.at(-1)}function a(n,t){const e=f();return!!e&&!!(u(e)||"escape"!==n&&"light-dismiss"!==n)&&(e.requestClose(n,t),!0)}export{s as c,r as o,a as r}
@@ -1 +0,0 @@
1
- import{p as e,H as t,h as i,c as r,t as a}from"./p-CIA4RyEp.js";import{d as o,e as s}from"./p-JwSoedEO.js";const n=e(class extends t{constructor(e){super(),!1!==e&&this.__registerHost(),this.__attachShadow()}get host(){return this}open=!1;defaultOpen=!1;internalOpen=!1;syncFromProp(){this.internalOpen=this.open}componentDidLoad(){this.syncFromProp(),this.internalOpen=this.internalOpen||this.defaultOpen,this.host.addEventListener("click",this.onItemClick),this.host.addEventListener("keydown",this.onKeydown)}disconnectedCallback(){this.host.removeEventListener("click",this.onItemClick),this.host.removeEventListener("keydown",this.onKeydown)}getItems(){return Array.from(this.host.querySelectorAll("ui-menu-item"))}isItemDisabled(e){return"true"===e.getAttribute("aria-disabled")||e.hasAttribute("disabled")||"true"===e.getAttribute("disabled")||!0===e.disabled}onItemClick=e=>{const t=e.target.closest?.("ui-menu-item");if(!t||t.getRootNode()!==this.host.getRootNode())return;if(this.isItemDisabled(t))return;const i=t.getAttribute("value")??t.getAttribute("data-value")??"";o(this.host,"select",{value:i,trigger:s(e)}),o(this.host,"close",{open:!1,reason:"action",trigger:s(e)}),this.internalOpen=!1};onKeydown=e=>{const i=this.getItems().filter((e=>!this.isItemDisabled(e)));if(0===i.length)return;const r=e.target.closest?.("ui-menu-item"),a=r&&r instanceof t?i.indexOf(r):-1;if("Enter"!==e.key&&" "!==e.key)"ArrowDown"!==e.key&&"ArrowUp"!==e.key||(e.preventDefault(),i["ArrowDown"===e.key?a<0?0:Math.min(a+1,i.length-1):a<=0?i.length-1:a-1].focus());else if(e.preventDefault(),r&&a>=0){const e=r.getAttribute("value")??r.getAttribute("data-value")??"";o(this.host,"select",{value:e,trigger:"keyboard"}),o(this.host,"close",{open:!1,reason:"action",trigger:"keyboard"}),this.internalOpen=!1}};render(){return i(r,{key:"5e463cbbce272c6b6132a839b818deef3e39a532",role:"menu","aria-orientation":"vertical","data-open":this.internalOpen?"":void 0},i("slot",{key:"feea6a21d41a7b27a6270814bcf0b3f3ded394a1"}))}static get watchers(){return{open:[{syncFromProp:0}]}}static get style(){return":host{--ui-menu-viewport-gap:var(--ui-space-2, 0.5rem);display:flex;flex-direction:column;inline-size:max-content;min-inline-size:min(12rem, calc(100vw - (var(--ui-menu-viewport-gap) * 2)));max-inline-size:calc(100vw - (var(--ui-menu-viewport-gap) * 2));padding:var(--ui-space-1);background:var(--ui-surface-elevated);border:1px solid var(--ui-border-default);border-radius:var(--ui-radius-3);box-shadow:var(--ui-shadow-lg)}::slotted(ui-menu-item){display:block;width:100%;padding:var(--ui-space-2) var(--ui-space-3);text-align:left;background:none;border:none;border-radius:var(--ui-radius-2);color:var(--ui-text-primary);font-size:var(--ui-font-size-md);font-weight:var(--ui-font-medium, 500);cursor:pointer;transition:background-color var(--ui-motion-fast) var(--ui-motion-ease), color var(--ui-motion-fast) var(--ui-motion-ease)}::slotted(ui-menu-item:hover:not([aria-disabled='true']):not([disabled])){background:var(--ui-surface-subtle)}::slotted(ui-menu-item[aria-disabled='true']),::slotted(ui-menu-item[disabled]){opacity:0.6;cursor:not-allowed}"}},[769,"ui-menu",{open:[4],defaultOpen:[4,"default-open"],internalOpen:[32]},void 0,{open:[{syncFromProp:0}]}]);function u(){"undefined"!=typeof customElements&&["ui-menu"].forEach((e=>{"ui-menu"===e&&(customElements.get(a(e))||customElements.define(a(e),n))}))}export{n as U,u as d}
@@ -1 +0,0 @@
1
- import{r as t,g as e,h as i,H as s}from"./p-CEeiinfk.js";import{o as n,c as o,r}from"./p-CR7f2MQC.js";import{d as a}from"./p-JwSoedEO.js";const h=class{constructor(e){t(this,e)}get host(){return e(this)}open=!1;defaultOpen=!1;for;internalOpen=!1;overlayId=`ui-context-menu-${Math.random().toString(36).slice(2,11)}`;trigger=null;contextTarget=null;pointerX=0;pointerY=0;syncFromProp(){this.internalOpen=this.open}syncTarget(){this.resolveTargets(),this.attachTargetListeners()}syncOverlay(){this.syncTriggerState(),this.internalOpen?n({id:this.overlayId,modal:!1,element:this.host,dismissible:!0,requestClose:(t,e)=>this.closeMenu(t,e)}):o(this.overlayId)}componentDidLoad(){this.syncFromProp(),this.internalOpen=this.internalOpen||this.defaultOpen,this.resolveTargets(),this.attachTargetListeners(),this.syncTriggerState(),this.syncOverlay()}componentDidUpdate(){this.resolveTargets(),this.attachTargetListeners(),this.syncTriggerState()}disconnectedCallback(){this.detachTargetListeners(),o(this.overlayId)}resolveTargets(){const t=this.trigger,e=this.contextTarget,i=this.host.querySelector('[slot="trigger"]'),s=this.for?document.getElementById(this.for):null;this.trigger=i,this.contextTarget=s??i??this.host.parentElement,t===this.trigger&&e===this.contextTarget||(t?.removeEventListener("click",this.onTriggerClick),t?.removeEventListener("keydown",this.onTriggerKeydown),e?.removeEventListener("contextmenu",this.onContextMenu))}attachTargetListeners(){this.detachTargetListeners(),this.trigger?.addEventListener("click",this.onTriggerClick),this.trigger?.addEventListener("keydown",this.onTriggerKeydown),this.contextTarget?.addEventListener("contextmenu",this.onContextMenu)}detachTargetListeners(){this.trigger?.removeEventListener("click",this.onTriggerClick),this.trigger?.removeEventListener("keydown",this.onTriggerKeydown),this.contextTarget?.removeEventListener("contextmenu",this.onContextMenu)}syncTriggerState(){this.trigger&&(this.trigger.setAttribute("aria-haspopup","menu"),this.trigger.setAttribute("aria-expanded",this.internalOpen?"true":"false"))}getItems(){return Array.from(this.host.querySelectorAll("ui-menu-item")).filter((t=>!this.isItemDisabled(t)))}focusFirstItem(){requestAnimationFrame((()=>this.getItems()[0]?.focus()))}openMenu(t,e,i){this.pointerX=t,this.pointerY=e,this.internalOpen=!0,a(this.host,"open",{open:!0,reason:"action",trigger:i}),this.focusFirstItem()}openFromTrigger(t){if(!this.trigger)return;const e=this.trigger.getBoundingClientRect();this.openMenu(e.left,e.bottom,t)}closeMenu(t,e,i=!0){this.internalOpen&&(this.internalOpen=!1,a(this.host,"close",{open:!1,reason:t,trigger:e}),i&&this.trigger?.focus())}onTriggerClick=t=>{this.internalOpen?this.closeMenu("action",0===t.detail?"keyboard":"pointer"):this.openFromTrigger(0===t.detail?"keyboard":"pointer")};onTriggerKeydown=t=>{"Enter"!==t.key&&" "!==t.key&&"ArrowDown"!==t.key||(t.preventDefault(),this.internalOpen?this.focusFirstItem():this.openFromTrigger("keyboard"))};onContextMenu=t=>{t.preventDefault(),this.openMenu(t.clientX,t.clientY,"pointer")};isItemDisabled(t){return"true"===t.getAttribute("aria-disabled")||t.hasAttribute("disabled")||"true"===t.getAttribute("disabled")||!0===t.disabled}onKeydown=t=>{if(this.internalOpen){if("Escape"===t.key)return t.preventDefault(),void r("escape","keyboard");if("Enter"===t.key||" "===t.key){const e=t.target.closest?.("ui-menu-item");if(!e||this.isItemDisabled(e))return;t.preventDefault();const i=e.getAttribute("value")??e.getAttribute("data-value")??"";a(this.host,"select",{value:i,trigger:"keyboard"}),this.closeMenu("action","keyboard")}}};onItemClick=t=>{const e=t.target.closest?.("ui-menu-item");if(!e||this.isItemDisabled(e))return;const i=e.getAttribute("value")??e.getAttribute("data-value")??"";a(this.host,"select",{value:i,trigger:"pointer"}),this.closeMenu("action","pointer")};render(){return i(s,{key:"79fbca2c89f1d1fd1f4796ad88d2a599e811a3f9","data-open":this.internalOpen?"":void 0,onKeyDown:this.onKeydown,onClick:this.onItemClick},i("slot",{key:"9308cadfa155930e3e46dfb4a69a847ae388958b",name:"trigger"}),i("div",{key:"16cfba2b32444ac9e3cac1f040f81f17fd5db23c",class:"menu","data-open":this.internalOpen?"":void 0,style:{left:`${this.pointerX}px`,top:`${this.pointerY}px`}},i("ui-menu",{key:"59f18e0df3bb1fe85efa8eeca00b336bbde47c70",open:this.internalOpen},i("slot",{key:"5bdbb7773c9c1ae43ec2e05fca9558482815e28a"}))))}static get watchers(){return{open:[{syncFromProp:0}],for:[{syncTarget:0}],internalOpen:[{syncOverlay:0}]}}};h.style=":host{display:contents}.menu{position:fixed;z-index:var(--ui-z-overlay, 1000);min-width:12rem}.menu[data-open]{display:block}.menu:not([data-open]){display:none !important}";export{h as ui_context_menu}
@@ -1 +0,0 @@
1
- import{r as t,g as a,h as i,H as n}from"./p-CEeiinfk.js";function e(t,a){const i=Math.max(a.left-t.x,0,t.x-a.right),n=Math.max(a.top-t.y,0,t.y-a.bottom);return Math.hypot(i,n)}const o=class{constructor(a){t(this,a)}get host(){return a(this)}nearRadius=16;coordinator=null;componentDidLoad(){this.connectCoordinator()}disconnectedCallback(){this.coordinator?.destroy(),this.coordinator=null}connectCoordinator(){this.coordinator?.destroy(),this.coordinator=function(t,a={}){const i=t.ownerDocument.defaultView??window,n=a.pointerTarget??t,o=a.anchorSelector??"[data-ui-affordance]",r=a.nearRadius??16,s=Number.isFinite(r)?Math.max(0,r):16,c=new AbortController;let d=[],l=null,u=null,h=!1;const p=()=>{for(const{element:t}of d)t.hasAttribute("data-ui-proximity")&&t.removeAttribute("data-ui-proximity");t.hasAttribute("data-ui-interaction")&&t.removeAttribute("data-ui-interaction")},f=()=>{d=Array.from(t.querySelectorAll(o)).filter((t=>!t.hasAttribute("disabled")&&"true"!==t.getAttribute("aria-disabled"))).map((t=>({element:t,rect:t.getBoundingClientRect()}))),h=!1},g=()=>{if(l=null,h&&f(),!u)return void p();let a=!1;for(const t of d){const i=e(u,t.rect)<=s;i&&"near"!==t.element.getAttribute("data-ui-proximity")?t.element.setAttribute("data-ui-proximity","near"):!i&&t.element.hasAttribute("data-ui-proximity")&&t.element.removeAttribute("data-ui-proximity"),a||=i}a&&"engaged"!==t.getAttribute("data-ui-interaction")?t.setAttribute("data-ui-interaction","engaged"):!a&&t.hasAttribute("data-ui-interaction")&&t.removeAttribute("data-ui-interaction")},m=()=>{null===l&&(l=i.requestAnimationFrame(g))},b=()=>{h=!0,m()};return n.addEventListener("pointermove",(t=>{u="touch"===t.pointerType?null:{x:t.clientX,y:t.clientY},m()}),{passive:!0,signal:c.signal}),i.addEventListener("resize",b,{passive:!0,signal:c.signal}),i.addEventListener("scroll",b,{passive:!0,capture:!0,signal:c.signal}),i.visualViewport?.addEventListener("resize",b,{passive:!0,signal:c.signal}),i.visualViewport?.addEventListener("scroll",b,{passive:!0,signal:c.signal}),f(),{refresh:b,destroy(){c.abort(),null!==l&&i.cancelAnimationFrame(l),l=null,u=null,p(),d=[]}}}(this.host,{nearRadius:this.nearRadius})}onSlotChange=()=>{this.coordinator?.refresh()};render(){return i(n,{key:"184b0a908494d480ed23aa14b75d4f7b94e5275b"},i("slot",{key:"570e810db588c1514c6fd85985c9bc4532993a2b",onSlotchange:this.onSlotChange}))}static get watchers(){return{nearRadius:[{connectCoordinator:0}]}}};o.style=":host{display:contents;--ui-affordance-scope-engaged:0}:host([data-ui-interaction='engaged']){--ui-affordance-scope-engaged:1}";export{o as ui_affordance_scope}
@@ -1 +0,0 @@
1
- import{r as e,g as i,h as t,H as r}from"./p-CEeiinfk.js";import{d as a,e as o}from"./p-JwSoedEO.js";const s=class{constructor(i){e(this,i)}get host(){return i(this)}open=!1;defaultOpen=!1;internalOpen=!1;syncFromProp(){this.internalOpen=this.open}componentDidLoad(){this.syncFromProp(),this.internalOpen=this.internalOpen||this.defaultOpen,this.host.addEventListener("click",this.onItemClick),this.host.addEventListener("keydown",this.onKeydown)}disconnectedCallback(){this.host.removeEventListener("click",this.onItemClick),this.host.removeEventListener("keydown",this.onKeydown)}getItems(){return Array.from(this.host.querySelectorAll("ui-menu-item"))}isItemDisabled(e){return"true"===e.getAttribute("aria-disabled")||e.hasAttribute("disabled")||"true"===e.getAttribute("disabled")||!0===e.disabled}onItemClick=e=>{const i=e.target.closest?.("ui-menu-item");if(!i||i.getRootNode()!==this.host.getRootNode())return;if(this.isItemDisabled(i))return;const t=i.getAttribute("value")??i.getAttribute("data-value")??"";a(this.host,"select",{value:t,trigger:o(e)}),a(this.host,"close",{open:!1,reason:"action",trigger:o(e)}),this.internalOpen=!1};onKeydown=e=>{const i=this.getItems().filter((e=>!this.isItemDisabled(e)));if(0===i.length)return;const t=e.target.closest?.("ui-menu-item"),r=t&&t instanceof HTMLElement?i.indexOf(t):-1;if("Enter"!==e.key&&" "!==e.key)"ArrowDown"!==e.key&&"ArrowUp"!==e.key||(e.preventDefault(),i["ArrowDown"===e.key?r<0?0:Math.min(r+1,i.length-1):r<=0?i.length-1:r-1].focus());else if(e.preventDefault(),t&&r>=0){const e=t.getAttribute("value")??t.getAttribute("data-value")??"";a(this.host,"select",{value:e,trigger:"keyboard"}),a(this.host,"close",{open:!1,reason:"action",trigger:"keyboard"}),this.internalOpen=!1}};render(){return t(r,{key:"5e463cbbce272c6b6132a839b818deef3e39a532",role:"menu","aria-orientation":"vertical","data-open":this.internalOpen?"":void 0},t("slot",{key:"feea6a21d41a7b27a6270814bcf0b3f3ded394a1"}))}static get watchers(){return{open:[{syncFromProp:0}]}}};s.style=":host{--ui-menu-viewport-gap:var(--ui-space-2, 0.5rem);display:flex;flex-direction:column;inline-size:max-content;min-inline-size:min(12rem, calc(100vw - (var(--ui-menu-viewport-gap) * 2)));max-inline-size:calc(100vw - (var(--ui-menu-viewport-gap) * 2));padding:var(--ui-space-1);background:var(--ui-surface-elevated);border:1px solid var(--ui-border-default);border-radius:var(--ui-radius-3);box-shadow:var(--ui-shadow-lg)}::slotted(ui-menu-item){display:block;width:100%;padding:var(--ui-space-2) var(--ui-space-3);text-align:left;background:none;border:none;border-radius:var(--ui-radius-2);color:var(--ui-text-primary);font-size:var(--ui-font-size-md);font-weight:var(--ui-font-medium, 500);cursor:pointer;transition:background-color var(--ui-motion-fast) var(--ui-motion-ease), color var(--ui-motion-fast) var(--ui-motion-ease)}::slotted(ui-menu-item:hover:not([aria-disabled='true']):not([disabled])){background:var(--ui-surface-subtle)}::slotted(ui-menu-item[aria-disabled='true']),::slotted(ui-menu-item[disabled]){opacity:0.6;cursor:not-allowed}";export{s as ui_menu}
@@ -1 +0,0 @@
1
- import{r as t,g as a,h as e,H as i}from"./p-CEeiinfk.js";import{d as s,e as r}from"./p-JwSoedEO.js";const o=class{constructor(a){t(this,a)}get host(){return a(this)}open=!0;internalOpen=!0;syncFromProp(){this.internalOpen=this.open}componentDidLoad(){this.syncFromProp(),this.host.addEventListener("click",this.onClick)}disconnectedCallback(){this.host.removeEventListener("click",this.onClick)}getToasts(){return Array.from(this.host.querySelectorAll("[data-ui-toast]"))}updateOpenState(){const t=this.getToasts();this.internalOpen=t.length>0}onClick=t=>{const a=t.target.closest?.("[data-ui-toast-dismiss]");if(!a)return;const e=a.closest?.("[data-ui-toast]");if(!e)return;const i=e.id??"";e.setAttribute("aria-hidden","true"),e.remove(),s(this.host,"dismiss",{id:i,reason:"action",trigger:r(t)}),this.updateOpenState(),0===this.getToasts().length&&s(this.host,"close",{open:!1,reason:"action",trigger:r(t)})};render(){return e(i,{key:"0edcce54864ba991b092d004d3b45cf697b9c3ac",role:"region","aria-label":"Notifications","data-open":this.internalOpen?"":void 0},e("slot",{key:"2e30794a05b018fb55c4313c8e17f7262ecee7da"}))}static get watchers(){return{open:[{syncFromProp:0}]}}};o.style=":host{position:fixed;top:calc(var(--ui-space-4) + env(safe-area-inset-top));left:50%;transform:translateX(-50%);z-index:9999;display:grid;gap:var(--ui-space-2);inline-size:min(24rem, calc(100vw - (var(--ui-space-4) * 2)));max-inline-size:100%;pointer-events:none}:host>*{pointer-events:auto}::slotted([data-ui-toast]){display:grid;grid-template-columns:1fr auto;gap:var(--ui-space-2);align-items:start;border:1px solid var(--ui-border-default);border-radius:var(--ui-radius-3);padding:var(--ui-space-3) var(--ui-space-4);background:var(--ui-surface-elevated);color:var(--ui-text-primary);box-shadow:var(--ui-shadow-lg);animation:ui-toast-enter 0.25s var(--ui-motion-ease) forwards}@keyframes ui-toast-enter{from{opacity:0;transform:translateY(-0.5rem)}to{opacity:1;transform:translateY(0)}}::slotted([data-ui-toast][aria-hidden='true']){display:none}::slotted([data-ui-toast-dismiss]){border:0;background:transparent;color:var(--ui-text-secondary);cursor:pointer;font:inherit}";export{o as ui_toast_region}
@@ -1 +0,0 @@
1
- import{r as e,g as o,h as r,H as s}from"./p-CEeiinfk.js";import{o as i,c as a,r as t}from"./p-CR7f2MQC.js";import{d as n}from"./p-JwSoedEO.js";const p=class{constructor(o){e(this,o)}get host(){return o(this)}open=!1;defaultOpen=!1;internalOpen=!1;overlayId=`ui-popover-${Math.random().toString(36).slice(2,11)}`;syncFromProp(){this.internalOpen=this.open}onOpenChange(){this.syncOverlay(),this.internalOpen?n(this.host,"open",{open:!0,reason:"programmatic",trigger:"programmatic"}):n(this.host,"close",{open:!1,reason:"programmatic",trigger:"programmatic"})}syncOverlay(){this.internalOpen?i({id:this.overlayId,modal:!1,element:this.host,dismissible:!0,requestClose:(e,o)=>this.handleRequestClose(e,o)}):a(this.overlayId)}componentDidLoad(){this.syncFromProp(),this.internalOpen=this.internalOpen||this.defaultOpen,this.host.addEventListener("keydown",this.onKeydown),this.syncOverlay()}disconnectedCallback(){this.host.removeEventListener("keydown",this.onKeydown),a(this.overlayId)}componentDidUpdate(){this.syncOverlay()}handleRequestClose(e,o){this.internalOpen=!1,n(this.host,"close",{open:!1,reason:e,trigger:o})}onKeydown=e=>{"Escape"===e.key&&t("escape","keyboard")};render(){return r(s,{key:"67e7f52220db9d997fb11b686d6abcbdf9557a8d","data-open":this.internalOpen?"":void 0,onKeyDown:this.onKeydown},r("slot",{key:"d7c1fa2ab75994fe0a7dd63f8289754c7754c30f"}))}static get watchers(){return{open:[{syncFromProp:0}],internalOpen:[{onOpenChange:0}]}}};p.style=":host{--ui-popover-viewport-gap:var(--ui-space-2, 0.5rem);padding:var(--ui-space-3);background:var(--ui-surface-elevated);border:1px solid var(--ui-border-default);border-radius:var(--ui-radius-3);box-shadow:var(--ui-shadow-lg);max-inline-size:min( 20rem, calc(100vw - (var(--ui-popover-viewport-gap) * 2)) );max-block-size:calc(100dvh - (var(--ui-popover-viewport-gap) * 2));overflow:auto}";export{p as ui_popover}
@@ -1 +0,0 @@
1
- import{r as t,g as i,h as s,H as e}from"./p-CEeiinfk.js";import{o,c as r,r as n}from"./p-CR7f2MQC.js";import{d as h}from"./p-JwSoedEO.js";const a=class{constructor(i){t(this,i)}get host(){return i(this)}for="";open=!1;defaultOpen=!1;internalOpen=!1;overlayId=`ui-tooltip-${Math.random().toString(36).slice(2,11)}`;trigger=null;syncFromProp(){this.internalOpen=this.open}syncOverlay(){this.internalOpen?o({id:this.overlayId,modal:!1,element:this.host,dismissible:!0,requestClose:(t,i)=>this.handleRequestClose(t,i)}):r(this.overlayId)}componentDidLoad(){this.syncFromProp(),this.internalOpen=this.internalOpen||this.defaultOpen,this.resolveTrigger(),this.attachTriggerListeners(),this.host.addEventListener("keydown",this.onKeydown),this.syncOverlay()}componentDidUpdate(){this.resolveTrigger(),this.attachTriggerListeners(),this.syncOverlay()}disconnectedCallback(){this.detachTriggerListeners(),this.host.removeEventListener("keydown",this.onKeydown),r(this.overlayId)}resolveTrigger(){this.trigger=this.for?document.getElementById(this.for):this.host.previousElementSibling}attachTriggerListeners(){this.detachTriggerListeners(),this.trigger&&(this.trigger.addEventListener("pointerenter",this.onTriggerEnter),this.trigger.addEventListener("pointerleave",this.onTriggerLeave),this.trigger.addEventListener("focusin",this.onTriggerFocusIn),this.trigger.addEventListener("focusout",this.onTriggerFocusOut))}detachTriggerListeners(){this.trigger&&(this.trigger.removeEventListener("pointerenter",this.onTriggerEnter),this.trigger.removeEventListener("pointerleave",this.onTriggerLeave),this.trigger.removeEventListener("focusin",this.onTriggerFocusIn),this.trigger.removeEventListener("focusout",this.onTriggerFocusOut))}onTriggerEnter=()=>{this.internalOpen=!0,h(this.host,"open",{open:!0,reason:"action",trigger:"pointer"}),this.syncOverlay()};onTriggerLeave=()=>{this.internalOpen=!1,h(this.host,"close",{open:!1,reason:"action",trigger:"pointer"}),this.syncOverlay()};onTriggerFocusIn=()=>{this.internalOpen=!0,h(this.host,"open",{open:!0,reason:"action",trigger:"keyboard"}),this.syncOverlay()};onTriggerFocusOut=t=>{const i=t.relatedTarget;i&&this.host.contains(i)||(this.internalOpen=!1,h(this.host,"close",{open:!1,reason:"action",trigger:"keyboard"}),this.syncOverlay())};handleRequestClose(t,i){"escape"===t&&(this.internalOpen=!1,h(this.host,"close",{open:!1,reason:"escape",trigger:i}),this.trigger?.focus())}onKeydown=t=>{"Escape"===t.key&&n("escape","keyboard")};render(){return s(e,{key:"64b5f4e7a56cbf5560edc6d7118022a49d5e2786",role:"tooltip",hidden:!this.internalOpen,"data-open":this.internalOpen?"":void 0,onKeyDown:this.onKeydown},s("slot",{key:"cf6f96689021a42a01b782f0e1d0730b5a9aa1f8"}))}static get watchers(){return{open:[{syncFromProp:0}],internalOpen:[{syncOverlay:0}]}}};a.style=":host{display:inline-block;border:1px solid var(--ui-border-default);border-radius:var(--ui-radius-2);background:var(--ui-surface-elevated);color:var(--ui-text-primary);padding:var(--ui-space-2) var(--ui-space-3);font-size:var(--ui-font-size-sm);box-shadow:var(--ui-shadow-md)}:host([hidden]){display:none !important}";export{a as ui_tooltip}
@@ -1 +0,0 @@
1
- const n=[],t="data-ui-scroll-lock";let e=0,o=!1;function c(){if("undefined"==typeof document)return;const n=document.documentElement;if(e>0)return n.setAttribute(t,"true"),void(n.style.overflow="hidden");n.removeAttribute(t),n.style.removeProperty("overflow")}function u(n){return n.dismissible??!0}function i(n){"Escape"===n.key&&a("escape","keyboard")}function d(n){const t=f();if(!t||!u(t))return;const e=n.target;e instanceof Node&&t.element.contains(e)||a("light-dismiss","pointer")}function r(t){s(t.id),n.push(t),t.modal&&(e+=1,c()),o||"undefined"==typeof document||(document.addEventListener("keydown",i),document.addEventListener("pointerdown",d,{capture:!0}),o=!0)}function s(t){const u=n.findIndex((n=>n.id===t));if(u>=0){const[t]=n.splice(u,1);t?.modal&&(e=Math.max(0,e-1),c())}!o||n.length>0||"undefined"==typeof document||(document.removeEventListener("keydown",i),document.removeEventListener("pointerdown",d,{capture:!0}),o=!1)}function f(){return n.at(-1)}function a(n,t){const e=f();return!!e&&!!(u(e)||"escape"!==n&&"light-dismiss"!==n)&&(e.requestClose(n,t),!0)}export{s as c,r as o,a as r}