@threadlabs/looma 0.1.21 → 0.1.23

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 (248) hide show
  1. package/dist/{chunk-FSGGPFID.js → chunk-GDMQKT5F.js} +63 -31
  2. package/dist/{chunk-SZJQ3NPX.js → chunk-TL4FIE7X.js} +4 -8
  3. package/dist/cjs/{index-D07f6BOw.js → index-BHG9Rpil.js} +33 -0
  4. package/dist/cjs/loader.cjs.js +2 -2
  5. package/dist/cjs/looma.cjs.js +2 -2
  6. package/dist/cjs/{manager-C9j3HZay.js → manager-Ce25WRtl.js} +6 -7
  7. package/dist/cjs/ui-affordance-scope.cjs.entry.js +1 -1
  8. package/dist/cjs/ui-avatar-group.cjs.entry.js +1 -1
  9. package/dist/cjs/ui-avatar.cjs.entry.js +1 -1
  10. package/dist/cjs/ui-badge.cjs.entry.js +1 -1
  11. package/dist/cjs/ui-button.cjs.entry.js +16 -5
  12. package/dist/cjs/ui-checkbox.cjs.entry.js +1 -1
  13. package/dist/cjs/ui-combobox.cjs.entry.js +541 -0
  14. package/dist/cjs/ui-context-menu.cjs.entry.js +3 -3
  15. package/dist/cjs/ui-dialog.cjs.entry.js +3 -3
  16. package/dist/cjs/ui-disclosure.cjs.entry.js +2 -2
  17. package/dist/cjs/ui-floating-action-button.cjs.entry.js +2 -2
  18. package/dist/cjs/ui-form-field.cjs.entry.js +3 -3
  19. package/dist/cjs/ui-icon-button.cjs.entry.js +2 -2
  20. package/dist/cjs/ui-input.cjs.entry.js +11 -6
  21. package/dist/cjs/ui-menu-item.cjs.entry.js +2 -2
  22. package/dist/cjs/ui-menu.cjs.entry.js +3 -3
  23. package/dist/cjs/ui-popover.cjs.entry.js +3 -3
  24. package/dist/cjs/ui-radio-group.cjs.entry.js +2 -2
  25. package/dist/cjs/ui-radio.cjs.entry.js +3 -3
  26. package/dist/cjs/ui-search-result-row.cjs.entry.js +2 -2
  27. package/dist/cjs/ui-search-shell.cjs.entry.js +2 -2
  28. package/dist/cjs/ui-select.cjs.entry.js +15 -7
  29. package/dist/cjs/ui-switch.cjs.entry.js +3 -3
  30. package/dist/cjs/ui-tabs.cjs.entry.js +2 -2
  31. package/dist/cjs/ui-textarea.cjs.entry.js +10 -6
  32. package/dist/cjs/ui-toast-region.cjs.entry.js +2 -2
  33. package/dist/cjs/ui-tooltip.cjs.entry.js +52 -16
  34. package/dist/cjs/ui-top-bar.cjs.entry.js +2 -2
  35. package/dist/cjs/ui-tree-item.cjs.entry.js +7 -3
  36. package/dist/cjs/ui-tree.cjs.entry.js +113 -21
  37. package/dist/collection/collection-manifest.json +1 -0
  38. package/dist/collection/components/ui-button/ui-button.css +36 -26
  39. package/dist/collection/components/ui-button/ui-button.js +14 -3
  40. package/dist/collection/components/ui-combobox/ui-combobox.css +24 -0
  41. package/dist/collection/components/ui-combobox/ui-combobox.js +973 -0
  42. package/dist/collection/components/ui-context-menu/ui-context-menu.js +1 -1
  43. package/dist/collection/components/ui-dialog/ui-dialog.js +1 -1
  44. package/dist/collection/components/ui-disclosure/ui-disclosure.js +1 -1
  45. package/dist/collection/components/ui-floating-action-button/ui-floating-action-button.js +1 -1
  46. package/dist/collection/components/ui-form-field/ui-form-field.css +4 -0
  47. package/dist/collection/components/ui-form-field/ui-form-field.js +1 -1
  48. package/dist/collection/components/ui-icon-button/ui-icon-button.js +1 -1
  49. package/dist/collection/components/ui-input/ui-input.css +8 -6
  50. package/dist/collection/components/ui-input/ui-input.js +11 -7
  51. package/dist/collection/components/ui-menu/ui-menu.js +1 -1
  52. package/dist/collection/components/ui-menu-item/ui-menu-item.js +1 -1
  53. package/dist/collection/components/ui-popover/ui-popover.js +1 -1
  54. package/dist/collection/components/ui-radio/ui-radio.js +2 -2
  55. package/dist/collection/components/ui-radio-group/ui-radio-group.js +1 -1
  56. package/dist/collection/components/ui-search-result-row/ui-search-result-row.js +1 -1
  57. package/dist/collection/components/ui-search-shell/ui-search-shell.js +1 -1
  58. package/dist/collection/components/ui-select/ui-select.css +8 -6
  59. package/dist/collection/components/ui-select/ui-select.js +17 -11
  60. package/dist/collection/components/ui-switch/ui-switch.js +2 -2
  61. package/dist/collection/components/ui-tabs/ui-tabs.js +1 -1
  62. package/dist/collection/components/ui-textarea/ui-textarea.css +7 -6
  63. package/dist/collection/components/ui-textarea/ui-textarea.js +10 -7
  64. package/dist/collection/components/ui-toast-region/ui-toast-region.js +1 -1
  65. package/dist/collection/components/ui-tooltip/ui-tooltip.js +102 -15
  66. package/dist/collection/components/ui-top-bar/ui-top-bar.js +1 -1
  67. package/dist/collection/components/ui-tree/ui-tree.js +132 -20
  68. package/dist/collection/components/ui-tree-item/ui-tree-item.js +44 -2
  69. package/dist/collection/field/combobox.js +4 -0
  70. package/dist/collection/field/valibot.js +5 -0
  71. package/dist/collection/field/validation.js +62 -0
  72. package/dist/collection/overlay/manager.js +6 -7
  73. package/dist/components/index.d.ts +2 -0
  74. package/dist/components/index.js +1 -1
  75. package/dist/components/p-Bh_1GxOD.js +1 -0
  76. package/dist/components/p-C-0syqXZ.js +1 -0
  77. package/dist/components/p-CaietZcq.js +1 -0
  78. package/dist/components/p-DHd18bK7.js +1 -0
  79. package/dist/components/ui-affordance-scope.js +1 -1
  80. package/dist/components/ui-avatar-group.js +1 -1
  81. package/dist/components/ui-avatar.js +1 -1
  82. package/dist/components/ui-badge.js +1 -1
  83. package/dist/components/ui-button.js +1 -1
  84. package/dist/components/ui-checkbox.js +1 -1
  85. package/dist/components/ui-combobox.d.ts +11 -0
  86. package/dist/components/ui-combobox.js +1 -0
  87. package/dist/components/ui-context-menu.js +1 -1
  88. package/dist/components/ui-dialog.js +1 -1
  89. package/dist/components/ui-disclosure.js +1 -1
  90. package/dist/components/ui-floating-action-button.js +1 -1
  91. package/dist/components/ui-form-field.js +1 -1
  92. package/dist/components/ui-icon-button.js +1 -1
  93. package/dist/components/ui-input.js +1 -1
  94. package/dist/components/ui-menu-item.js +1 -1
  95. package/dist/components/ui-menu.js +1 -1
  96. package/dist/components/ui-popover.js +1 -1
  97. package/dist/components/ui-radio-group.js +1 -1
  98. package/dist/components/ui-radio.js +1 -1
  99. package/dist/components/ui-search-result-row.js +1 -1
  100. package/dist/components/ui-search-shell.js +1 -1
  101. package/dist/components/ui-select.js +1 -1
  102. package/dist/components/ui-switch.js +1 -1
  103. package/dist/components/ui-tabs.js +1 -1
  104. package/dist/components/ui-textarea.js +1 -1
  105. package/dist/components/ui-toast-region.js +1 -1
  106. package/dist/components/ui-tooltip.js +1 -1
  107. package/dist/components/ui-top-bar.js +1 -1
  108. package/dist/components/ui-tree-item.js +2 -2
  109. package/dist/components/ui-tree.js +1 -1
  110. package/dist/esm/{index-CEeiinfk.js → index-8BGiMGQ0.js} +33 -1
  111. package/dist/esm/loader.js +3 -3
  112. package/dist/esm/looma.js +3 -3
  113. package/dist/esm/{manager-PM9a74r7.js → manager-C-0syqXZ.js} +6 -7
  114. package/dist/esm/ui-affordance-scope.entry.js +1 -1
  115. package/dist/esm/ui-avatar-group.entry.js +1 -1
  116. package/dist/esm/ui-avatar.entry.js +1 -1
  117. package/dist/esm/ui-badge.entry.js +1 -1
  118. package/dist/esm/ui-button.entry.js +16 -5
  119. package/dist/esm/ui-checkbox.entry.js +1 -1
  120. package/dist/esm/ui-combobox.entry.js +539 -0
  121. package/dist/esm/ui-context-menu.entry.js +3 -3
  122. package/dist/esm/ui-dialog.entry.js +3 -3
  123. package/dist/esm/ui-disclosure.entry.js +2 -2
  124. package/dist/esm/ui-floating-action-button.entry.js +2 -2
  125. package/dist/esm/ui-form-field.entry.js +3 -3
  126. package/dist/esm/ui-icon-button.entry.js +2 -2
  127. package/dist/esm/ui-input.entry.js +11 -6
  128. package/dist/esm/ui-menu-item.entry.js +2 -2
  129. package/dist/esm/ui-menu.entry.js +3 -3
  130. package/dist/esm/ui-popover.entry.js +3 -3
  131. package/dist/esm/ui-radio-group.entry.js +2 -2
  132. package/dist/esm/ui-radio.entry.js +3 -3
  133. package/dist/esm/ui-search-result-row.entry.js +2 -2
  134. package/dist/esm/ui-search-shell.entry.js +2 -2
  135. package/dist/esm/ui-select.entry.js +15 -7
  136. package/dist/esm/ui-switch.entry.js +3 -3
  137. package/dist/esm/ui-tabs.entry.js +2 -2
  138. package/dist/esm/ui-textarea.entry.js +10 -6
  139. package/dist/esm/ui-toast-region.entry.js +2 -2
  140. package/dist/esm/ui-tooltip.entry.js +52 -16
  141. package/dist/esm/ui-top-bar.entry.js +2 -2
  142. package/dist/esm/ui-tree-item.entry.js +7 -3
  143. package/dist/esm/ui-tree.entry.js +113 -21
  144. package/dist/index.cjs +911 -135
  145. package/dist/index.d.cts +104 -1
  146. package/dist/index.d.ts +104 -1
  147. package/dist/index.js +62 -8
  148. package/dist/looma/looma.esm.js +1 -1
  149. package/dist/looma/{p-0198bb21.entry.js → p-13347631.entry.js} +1 -1
  150. package/dist/looma/p-14c081cf.entry.js +1 -0
  151. package/dist/looma/{p-0f45c5f0.entry.js → p-25366205.entry.js} +1 -1
  152. package/dist/looma/{p-a9f46811.entry.js → p-2e3aa869.entry.js} +1 -1
  153. package/dist/looma/p-40fe7fee.entry.js +1 -0
  154. package/dist/looma/p-446cda76.entry.js +1 -0
  155. package/dist/looma/p-4fc1b005.entry.js +13 -0
  156. package/dist/looma/p-582973b5.entry.js +1 -0
  157. package/dist/looma/{p-d273b857.entry.js → p-5a87b59d.entry.js} +1 -1
  158. package/dist/looma/{p-2ed7e241.entry.js → p-5da09f47.entry.js} +1 -1
  159. package/dist/looma/{p-7e94d90d.entry.js → p-69a5557b.entry.js} +1 -1
  160. package/dist/looma/p-6a8a4736.entry.js +1 -0
  161. package/dist/looma/{p-caa8fc7b.entry.js → p-6bf4038b.entry.js} +1 -1
  162. package/dist/looma/p-7e0bb7f6.entry.js +1 -0
  163. package/dist/looma/{p-ed5abf6d.entry.js → p-8204fee6.entry.js} +1 -1
  164. package/dist/looma/{p-5ba9d496.entry.js → p-8238e0dc.entry.js} +1 -1
  165. package/dist/looma/p-8BGiMGQ0.js +2 -0
  166. package/dist/looma/{p-051f578c.entry.js → p-8b8840b8.entry.js} +1 -1
  167. package/dist/looma/{p-1674cda4.entry.js → p-99d88efb.entry.js} +1 -1
  168. package/dist/looma/p-C-0syqXZ.js +1 -0
  169. package/dist/looma/p-a27669b1.entry.js +1 -0
  170. package/dist/looma/{p-11083743.entry.js → p-a6ee76b7.entry.js} +1 -1
  171. package/dist/looma/p-a90d2821.entry.js +1 -0
  172. package/dist/looma/{p-2e6f791e.entry.js → p-add36e74.entry.js} +1 -1
  173. package/dist/looma/{p-0584a051.entry.js → p-b6398a6b.entry.js} +1 -1
  174. package/dist/looma/{p-078f9fb8.entry.js → p-d50faaff.entry.js} +1 -1
  175. package/dist/looma/{p-b7aa4488.entry.js → p-d77278ce.entry.js} +1 -1
  176. package/dist/looma/p-d9ec13b7.entry.js +1 -0
  177. package/dist/looma/{p-1681b218.entry.js → p-ecf8005f.entry.js} +1 -1
  178. package/dist/looma/p-ed368426.entry.js +1 -0
  179. package/dist/looma/{p-063f5a89.entry.js → p-f0487ff3.entry.js} +1 -1
  180. package/dist/looma/p-f74e5546.entry.js +1 -0
  181. package/dist/types/components/ui-combobox/ui-combobox.d.ts +93 -0
  182. package/dist/types/components/ui-input/ui-input.d.ts +1 -1
  183. package/dist/types/components/ui-select/ui-select.d.ts +3 -2
  184. package/dist/types/components/ui-textarea/ui-textarea.d.ts +1 -1
  185. package/dist/types/components/ui-tooltip/ui-tooltip.d.ts +18 -1
  186. package/dist/types/components/ui-tree/ui-tree.d.ts +11 -1
  187. package/dist/types/components/ui-tree-item/ui-tree-item.d.ts +4 -0
  188. package/dist/types/components.d.ts +260 -28
  189. package/dist/types/field/combobox.d.ts +46 -0
  190. package/dist/types/field/valibot.d.ts +7 -0
  191. package/dist/types/field/validation.d.ts +56 -0
  192. package/dist/{ui-affordance-scope.entry-Z3H4CM6J.js → ui-affordance-scope.entry-VO4C2MZX.js} +1 -1
  193. package/dist/{ui-avatar-group.entry-ONGVFRD3.js → ui-avatar-group.entry-TAXJRIIU.js} +1 -1
  194. package/dist/{ui-avatar.entry-TBA3IEED.js → ui-avatar.entry-T6FU6ZYM.js} +1 -1
  195. package/dist/{ui-badge.entry-DKBPJ7G7.js → ui-badge.entry-MZFYNBMJ.js} +1 -1
  196. package/dist/ui-button.entry-7UXMUGHN.js +80 -0
  197. package/dist/{ui-checkbox.entry-QJTO2U6Z.js → ui-checkbox.entry-DMZJB3RE.js} +1 -1
  198. package/dist/ui-combobox.entry-ZCTPXEES.js +553 -0
  199. package/dist/{ui-context-menu.entry-CC4VXCEB.js → ui-context-menu.entry-2WMCBGCP.js} +6 -6
  200. package/dist/{ui-dialog.entry-GPJWOH5Z.js → ui-dialog.entry-WO23XOSW.js} +6 -6
  201. package/dist/{ui-disclosure.entry-EGG3HXD4.js → ui-disclosure.entry-USX7OUEW.js} +2 -2
  202. package/dist/{ui-floating-action-button.entry-XUD44HRX.js → ui-floating-action-button.entry-MXDIN7MV.js} +2 -2
  203. package/dist/{ui-form-field.entry-UHLNDUXR.js → ui-form-field.entry-7ZCMEHPY.js} +3 -3
  204. package/dist/{ui-icon-button.entry-6HDCV3E7.js → ui-icon-button.entry-MJUNXHBU.js} +2 -2
  205. package/dist/{ui-input.entry-73QXAVLL.js → ui-input.entry-AWG63YIG.js} +8 -6
  206. package/dist/{ui-menu-item.entry-HCZRSY5Y.js → ui-menu-item.entry-HFTWG62N.js} +2 -2
  207. package/dist/{ui-menu.entry-ASIVAX6M.js → ui-menu.entry-IT3GW5TL.js} +7 -7
  208. package/dist/{ui-popover.entry-WSQ7AEJN.js → ui-popover.entry-ZQQB4N6E.js} +6 -6
  209. package/dist/{ui-radio-group.entry-2N7BEBJW.js → ui-radio-group.entry-V7PCTS7I.js} +2 -2
  210. package/dist/{ui-radio.entry-TOM6HBXP.js → ui-radio.entry-JYH6TQBI.js} +3 -3
  211. package/dist/{ui-search-result-row.entry-KA3P76WE.js → ui-search-result-row.entry-JBNYXXUN.js} +2 -2
  212. package/dist/{ui-search-shell.entry-ERMS7TIH.js → ui-search-shell.entry-TEAWE76O.js} +2 -2
  213. package/dist/{ui-select.entry-KDIM3SWS.js → ui-select.entry-F3A6TE2U.js} +13 -7
  214. package/dist/{ui-switch.entry-VRTB6X4D.js → ui-switch.entry-MJIICMP2.js} +3 -3
  215. package/dist/{ui-tabs.entry-GIAO5W3U.js → ui-tabs.entry-6REFIUHV.js} +2 -2
  216. package/dist/{ui-textarea.entry-T6YH4HVG.js → ui-textarea.entry-OJTXCED7.js} +8 -6
  217. package/dist/{ui-toast-region.entry-DBQCXOPJ.js → ui-toast-region.entry-NOFXLKPS.js} +5 -5
  218. package/dist/{ui-tooltip.entry-VS26OECS.js → ui-tooltip.entry-COWTWVHX.js} +57 -21
  219. package/dist/{ui-top-bar.entry-HGWP6PFQ.js → ui-top-bar.entry-PIAWXJNV.js} +2 -2
  220. package/dist/{ui-tree-item.entry-ZRXUIZDR.js → ui-tree-item.entry-BSEWNL2O.js} +7 -3
  221. package/dist/{ui-tree.entry-TC2SCQJF.js → ui-tree.entry-XYI3ZFAZ.js} +105 -20
  222. package/dist/valibot.d.ts +52 -0
  223. package/dist/valibot.js +7 -0
  224. package/package.json +11 -3
  225. package/styles.css +36 -20
  226. package/theme-high-contrast.css +12 -0
  227. package/tokens.css +23 -0
  228. package/vue/{chunk-5KWCMTXB.js → chunk-JLW23USW.js} +88 -1
  229. package/vue/editor/index.js +1 -1
  230. package/vue/index.d.ts +123 -1
  231. package/vue/index.js +3 -1
  232. package/dist/components/p-CEYIKqYc.js +0 -1
  233. package/dist/components/p-CIA4RyEp.js +0 -1
  234. package/dist/components/p-PM9a74r7.js +0 -1
  235. package/dist/looma/p-34417499.entry.js +0 -1
  236. package/dist/looma/p-4b422d40.entry.js +0 -1
  237. package/dist/looma/p-54722713.entry.js +0 -13
  238. package/dist/looma/p-54c41576.entry.js +0 -1
  239. package/dist/looma/p-5d4713a6.entry.js +0 -1
  240. package/dist/looma/p-624ba086.entry.js +0 -1
  241. package/dist/looma/p-8d5adb17.entry.js +0 -1
  242. package/dist/looma/p-9194a99d.entry.js +0 -1
  243. package/dist/looma/p-CEeiinfk.js +0 -2
  244. package/dist/looma/p-PM9a74r7.js +0 -1
  245. package/dist/looma/p-a33522a2.entry.js +0 -1
  246. package/dist/looma/p-a5127c7d.entry.js +0 -1
  247. package/dist/looma/p-b0431118.entry.js +0 -1
  248. package/dist/ui-button.entry-U2MMIHLY.js +0 -71
@@ -1,26 +1,28 @@
1
+ import {
2
+ dispatchDetail
3
+ } from "./chunk-UL7UIUJZ.js";
1
4
  import {
2
5
  closeOverlay,
3
- openOverlay,
4
- requestTopOverlayClose
5
- } from "./chunk-SZJQ3NPX.js";
6
+ openOverlay
7
+ } from "./chunk-TL4FIE7X.js";
6
8
  import {
7
9
  createAnchoredSurface
8
10
  } from "./chunk-YHXJC5M5.js";
9
- import {
10
- dispatchDetail
11
- } from "./chunk-UL7UIUJZ.js";
12
11
  import {
13
12
  Host,
13
+ createEvent,
14
14
  getElement,
15
15
  h,
16
16
  registerInstance
17
- } from "./chunk-FSGGPFID.js";
17
+ } from "./chunk-GDMQKT5F.js";
18
18
 
19
19
  // dist/esm/ui-tooltip.entry.js
20
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
21
  var UITooltip = class {
22
22
  constructor(hostRef) {
23
23
  registerInstance(this, hostRef);
24
+ this.opened = createEvent(this, "open");
25
+ this.closed = createEvent(this, "close");
24
26
  }
25
27
  get host() {
26
28
  return getElement(this);
@@ -33,6 +35,12 @@ var UITooltip = class {
33
35
  showDelay = 500;
34
36
  /** Pointer leave grace period in milliseconds. */
35
37
  hideDelay = 100;
38
+ /** Click or tap pins the description; activate again to dismiss. */
39
+ toggleOnClick = false;
40
+ pinned = false;
41
+ focused = false;
42
+ opened;
43
+ closed;
36
44
  internalOpen = false;
37
45
  overlayId = `ui-tooltip-${Math.random().toString(36).slice(2, 11)}`;
38
46
  trigger = null;
@@ -65,11 +73,14 @@ var UITooltip = class {
65
73
  }
66
74
  }
67
75
  componentDidLoad() {
76
+ if (!this.host.id)
77
+ this.host.id = this.overlayId;
68
78
  this.syncFromProp();
69
79
  this.internalOpen = this.internalOpen || this.defaultOpen;
70
80
  this.syncTrigger();
71
81
  this.setupSurface();
72
- this.host.addEventListener("keydown", this.onKeydown);
82
+ this.host.addEventListener("pointerenter", this.onSurfaceEnter);
83
+ this.host.addEventListener("pointerleave", this.onTriggerLeave);
73
84
  this.syncOverlay();
74
85
  }
75
86
  componentDidUpdate() {
@@ -80,11 +91,12 @@ var UITooltip = class {
80
91
  this.detachTriggerListeners();
81
92
  this.surface?.destroy();
82
93
  this.surface = null;
83
- this.host.removeEventListener("keydown", this.onKeydown);
94
+ this.host.removeEventListener("pointerenter", this.onSurfaceEnter);
95
+ this.host.removeEventListener("pointerleave", this.onTriggerLeave);
84
96
  closeOverlay(this.overlayId);
85
97
  }
86
98
  syncTrigger() {
87
- const next = this.for ? this.host.ownerDocument.getElementById(this.for) : this.host.previousElementSibling;
99
+ const next = this.for ? this.host.getRootNode().getElementById(this.for) : this.host.previousElementSibling;
88
100
  if (next === this.trigger)
89
101
  return;
90
102
  this.detachTriggerListeners();
@@ -103,6 +115,11 @@ var UITooltip = class {
103
115
  this.detachTriggerListeners();
104
116
  if (!this.trigger)
105
117
  return;
118
+ const ids = new Set((this.trigger.getAttribute("aria-describedby") || "").split(/\s+/).filter(Boolean));
119
+ ids.add(this.host.id);
120
+ this.trigger.setAttribute("aria-describedby", [...ids].join(" "));
121
+ this.trigger.addEventListener("click", this.onTriggerClick);
122
+ this.trigger.addEventListener("keydown", this.onTriggerKeydown);
106
123
  this.trigger.addEventListener("pointerenter", this.onTriggerEnter);
107
124
  this.trigger.addEventListener("pointerleave", this.onTriggerLeave);
108
125
  this.trigger.addEventListener("focusin", this.onTriggerFocusIn);
@@ -111,6 +128,13 @@ var UITooltip = class {
111
128
  detachTriggerListeners() {
112
129
  if (!this.trigger)
113
130
  return;
131
+ const ids = (this.trigger.getAttribute("aria-describedby") || "").split(/\s+/).filter((id) => id && id !== this.host.id);
132
+ if (ids.length)
133
+ this.trigger.setAttribute("aria-describedby", ids.join(" "));
134
+ else
135
+ this.trigger.removeAttribute("aria-describedby");
136
+ this.trigger.removeEventListener("click", this.onTriggerClick);
137
+ this.trigger.removeEventListener("keydown", this.onTriggerKeydown);
114
138
  this.trigger.removeEventListener("pointerenter", this.onTriggerEnter);
115
139
  this.trigger.removeEventListener("pointerleave", this.onTriggerLeave);
116
140
  this.trigger.removeEventListener("focusin", this.onTriggerFocusIn);
@@ -142,7 +166,21 @@ var UITooltip = class {
142
166
  trigger
143
167
  });
144
168
  }
145
- onTriggerEnter = () => {
169
+ onSurfaceEnter = () => this.clearHideTimer();
170
+ onTriggerClick = (event) => {
171
+ if (!this.toggleOnClick)
172
+ return;
173
+ this.clearTimers();
174
+ this.pinned = !this.pinned;
175
+ this.setInteractionOpen(this.pinned, event.detail === 0 ? "keyboard" : "pointer");
176
+ };
177
+ onTriggerKeydown = (event) => {
178
+ if (event.key === "Escape")
179
+ this.clearTimers();
180
+ };
181
+ onTriggerEnter = (event) => {
182
+ if (event.pointerType === "touch")
183
+ return;
146
184
  this.clearHideTimer();
147
185
  if (this.internalOpen || this.showTimer !== null)
148
186
  return;
@@ -153,7 +191,7 @@ var UITooltip = class {
153
191
  };
154
192
  onTriggerLeave = () => {
155
193
  this.clearShowTimer();
156
- if (!this.internalOpen || this.hideTimer !== null)
194
+ if (this.focused || this.pinned || !this.internalOpen || this.hideTimer !== null)
157
195
  return;
158
196
  this.hideTimer = setTimeout(() => {
159
197
  this.hideTimer = null;
@@ -161,6 +199,7 @@ var UITooltip = class {
161
199
  }, Math.max(0, this.hideDelay));
162
200
  };
163
201
  onTriggerFocusIn = () => {
202
+ this.focused = true;
164
203
  this.clearTimers();
165
204
  this.setInteractionOpen(true, "keyboard");
166
205
  };
@@ -168,28 +207,25 @@ var UITooltip = class {
168
207
  const related = e.relatedTarget;
169
208
  if (related && this.host.contains(related))
170
209
  return;
210
+ this.focused = false;
211
+ this.pinned = false;
171
212
  this.clearTimers();
172
213
  this.setInteractionOpen(false, "keyboard");
173
214
  };
174
215
  handleRequestClose(reason, trigger) {
175
- if (reason === "escape") {
216
+ if (reason === "escape" || reason === "light-dismiss" && this.toggleOnClick) {
217
+ this.pinned = false;
176
218
  this.clearTimers();
177
219
  this.internalOpen = false;
178
220
  dispatchDetail(this.host, "close", {
179
221
  open: false,
180
- reason: "escape",
222
+ reason,
181
223
  trigger
182
224
  });
183
- this.trigger?.focus();
184
225
  }
185
226
  }
186
- onKeydown = (e) => {
187
- if (e.key === "Escape") {
188
- requestTopOverlayClose("escape", "keyboard");
189
- }
190
- };
191
227
  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" }));
228
+ return h(Host, { key: "b0199c23316a707ae3e1e7c361f2838872f62221", role: "tooltip", hidden: !this.internalOpen, "data-open": this.internalOpen ? "" : void 0 }, h("slot", { key: "d0c7822f2f47848a509bf8e310806edbdb320f02" }));
193
229
  }
194
230
  static get watchers() {
195
231
  return {
@@ -3,7 +3,7 @@ import {
3
3
  getElement,
4
4
  h,
5
5
  registerInstance
6
- } from "./chunk-FSGGPFID.js";
6
+ } from "./chunk-GDMQKT5F.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}}`;
@@ -40,7 +40,7 @@ var UITopBar = class {
40
40
  this.hasActions = slotHasContent(this.actionsSlot);
41
41
  };
42
42
  render() {
43
- return h(Host, { key: "15c840c082724df0ec39ab6ad4e55f99192df5be" }, h("header", { key: "790afaeecdb3e598b8365391f57ee1e2d8ca69a2", class: "top-bar", part: "base" }, h("div", { key: "fab822f5875c7e3b8e267be42c075597d79374fa", class: "top-bar__leading", hidden: !this.hasLeading }, h("slot", { key: "0723013c4b674964e4029442b715daa9eb0036db", name: "leading", ref: (el) => this.leadingSlot = el, onSlotchange: this.syncSlots })), h("div", { key: "77fc006257b7fa6a191191d9969ea66445b8bc3e", class: "top-bar__title" }, h("slot", { key: "e8a07f1f767c1c0fa1244abcf3bb0e697e36a4fe" })), h("div", { key: "bde5cdf797ae898f68eddeab362b8395f89bdf28", class: "top-bar__search", hidden: !this.hasSearch }, h("slot", { key: "8b059d6123e94f3b7e18c15c88828ee9c6436136", name: "search", ref: (el) => this.searchSlot = el, onSlotchange: this.syncSlots })), h("div", { key: "c262446cf29873903530ea3f840de4de9db3de82", class: "top-bar__actions", hidden: !this.hasActions }, h("slot", { key: "f417dbc8cc0115a455a72ce0feb5f32b323ce68f", name: "actions", ref: (el) => this.actionsSlot = el, onSlotchange: this.syncSlots }))));
43
+ return h(Host, { key: "730e45232ab2b86c2ac99dba773f4ca15d7c3c51" }, h("header", { key: "f94f9b4f3f5930fda950895d2eec01d3ec175479", class: "top-bar", part: "base" }, h("div", { key: "038f6a404b0f159b4b826ada73d3c920266354c8", class: "top-bar__leading", hidden: !this.hasLeading }, h("slot", { key: "2d415368310c319eca3f3eb9b2c885ef79bb4107", name: "leading", ref: (el) => this.leadingSlot = el, onSlotchange: this.syncSlots })), h("div", { key: "dfd78b02066a91e9c610e4655a70da704ad65327", class: "top-bar__title" }, h("slot", { key: "499e24a864a31f6e400fd02aab4a3f960c87e572" })), h("div", { key: "5aa94952996487651dffecd2e351548631fa29b6", class: "top-bar__search", hidden: !this.hasSearch }, h("slot", { key: "eddad95f8acf787ee0cead2a46e7961a06375d5c", name: "search", ref: (el) => this.searchSlot = el, onSlotchange: this.syncSlots })), h("div", { key: "dc69d492aa221a8beb888350bf101f8beeceede9", class: "top-bar__actions", hidden: !this.hasActions }, h("slot", { key: "7cde7e062f487da8209738a32415636c7a6b72f0", name: "actions", ref: (el) => this.actionsSlot = el, onSlotchange: this.syncSlots }))));
44
44
  }
45
45
  };
46
46
  UITopBar.style = uiTopBarCss();
@@ -7,7 +7,7 @@ import {
7
7
  getElement,
8
8
  h,
9
9
  registerInstance
10
- } from "./chunk-FSGGPFID.js";
10
+ } from "./chunk-GDMQKT5F.js";
11
11
 
12
12
  // dist/esm/ui-tree-item.entry.js
13
13
  var Bold = [
@@ -299,6 +299,10 @@ var UITreeItem = class {
299
299
  label = "";
300
300
  /** One-based visual and semantic nesting level. */
301
301
  depth = 1;
302
+ /** Application hierarchy depth used for drop constraints. Defaults to visual depth. */
303
+ dropDepth;
304
+ /** Deepest descendant distance, used with the tree's max-depth drop constraint. */
305
+ subtreeDepth;
302
306
  /** Whether this item accepts children and exposes disclosure behavior. */
303
307
  container = false;
304
308
  /** Whether this item participates in pointer drag and drop. */
@@ -360,10 +364,10 @@ var UITreeItem = class {
360
364
  const level = Math.max(1, Math.floor(this.depth));
361
365
  const disclosureLabel = `${this.internalExpanded ? "Collapse" : "Expand"} ${this.label || "item"}`;
362
366
  const dragLabel = `Drag ${this.label || "item"} to reorder`;
363
- return h(Host, { key: "ea8ed538aa3883c87257a25614a066965364693f", role: "treeitem", "aria-level": String(level), "aria-expanded": this.container ? String(this.internalExpanded) : void 0, "aria-selected": String(this.selected), "aria-disabled": this.disabled ? "true" : void 0, "data-container": this.container ? "" : void 0, "data-selected": this.selected ? "" : void 0, "data-disabled": this.disabled ? "" : void 0, "data-drag-type": this.dragType || "item", "data-drop-scope": this.dropScope || void 0, "data-accepts": this.accepts || void 0, tabIndex: this.disabled ? -1 : 0, style: {
367
+ return h(Host, { key: "606f5fdac8a95489d0c62cd7d4918c6d5d0c759e", role: "treeitem", "aria-level": String(level), "aria-expanded": this.container ? String(this.internalExpanded) : void 0, "aria-selected": String(this.selected), "aria-disabled": this.disabled ? "true" : void 0, "data-container": this.container ? "" : void 0, "data-selected": this.selected ? "" : void 0, "data-disabled": this.disabled ? "" : void 0, "data-drag-type": this.dragType || "item", "data-drop-scope": this.dropScope || void 0, "data-accepts": this.accepts || void 0, tabIndex: this.disabled ? -1 : 0, style: {
364
368
  "--ui-tree-item-depth": String(level - 1),
365
369
  "margin-inline-start": level > 1 ? "var(--ui-tree-indent, 16px)" : "0px"
366
- } }, h("div", { key: "740b93aa47e65d8a1cb899d4b9c966d9ad1d456f", class: "row", part: "row", onClick: this.onRowClick }, this.sortable && !this.disabled ? h("button", { class: "drag-handle", part: "drag-handle", type: "button", draggable: true, "aria-label": dragLabel, title: dragLabel }, h("span", { innerHTML: loomaIconMarkup("grip-vertical") })) : null, this.container ? h("button", { class: "disclosure", part: "disclosure", type: "button", "aria-label": disclosureLabel, "aria-expanded": String(this.internalExpanded), disabled: this.disabled, onClick: this.onDisclosureClick, onKeyDown: this.onDisclosureKeydown }, h("span", { class: { "disclosure-icon": true, "disclosure-icon--expanded": this.internalExpanded }, innerHTML: loomaIconMarkup("chevron-down") })) : h("span", { class: "disclosure-spacer", "aria-hidden": "true" }), h("span", { key: "37e1b7f1cdddf623734becef465ffde83d8b86f2", class: "leading", part: "leading" }, h("slot", { key: "0ab3a60c98628f009918d0d720772154912d2709", name: "leading" })), h("span", { key: "defdd343f25a0f4354110e981f3889e1d09c27ee", class: "label", part: "label" }, h("slot", { key: "bde46ccacc1a620348062fc300503c4f1736316b" })), h("span", { key: "caff9ada38c41be90aeb6e331f4c54a51f31d26c", class: "actions", part: "actions" }, h("slot", { key: "e11704d6871445c91eaa29c99302d8b751be69d3", name: "actions" })), h("span", { key: "9efc0e95588f1dd4527dade2b7ff9f2774462c2e", class: "drop-indicator row-drop-indicator", part: "drop-indicator", "aria-hidden": "true" })), this.container ? h("div", { class: "children", part: "children", role: "group", hidden: !this.internalExpanded }, h("slot", { name: "children" })) : null, h("span", { key: "8893ec2c4082bb8af942ef563055a2910d0d4201", class: "drop-indicator subtree-drop-indicator", part: "drop-indicator", "aria-hidden": "true" }));
370
+ } }, h("div", { key: "2b4bb03d4b24ef668f22b08e803f7f43c2d63ae5", class: "row", part: "row", onClick: this.onRowClick }, this.sortable && !this.disabled ? h("button", { class: "drag-handle", part: "drag-handle", type: "button", draggable: true, "aria-label": dragLabel, title: dragLabel }, h("span", { innerHTML: loomaIconMarkup("grip-vertical") })) : null, this.container ? h("button", { class: "disclosure", part: "disclosure", type: "button", "aria-label": disclosureLabel, "aria-expanded": String(this.internalExpanded), disabled: this.disabled, onClick: this.onDisclosureClick, onKeyDown: this.onDisclosureKeydown }, h("span", { class: { "disclosure-icon": true, "disclosure-icon--expanded": this.internalExpanded }, innerHTML: loomaIconMarkup("chevron-down") })) : h("span", { class: "disclosure-spacer", "aria-hidden": "true" }), h("span", { key: "e7b935158e35cdc6518bdd73d54c42dcfa211aee", class: "leading", part: "leading" }, h("slot", { key: "8448462349fd23b8be0fb673fc6e101bf94beaa7", name: "leading" })), h("span", { key: "e0b6338e1ec9ec043446e42c5f03724adf7e1862", class: "label", part: "label" }, h("slot", { key: "ed44e6f2ce3466c28d2b87fc7511399ecc339255" })), h("span", { key: "2aea78227904fe23cfc4b8e14852a4601e3cc34b", class: "actions", part: "actions" }, h("slot", { key: "7c6549008c2a54c3ea6fcdf9e0fdbe445d379922", name: "actions" })), h("span", { key: "05166ba04765bc518d6b95ca7ae5a67c4394d1bf", class: "drop-indicator row-drop-indicator", part: "drop-indicator", "aria-hidden": "true" })), this.container ? h("div", { class: "children", part: "children", role: "group", hidden: !this.internalExpanded }, h("slot", { name: "children" })) : null, h("span", { key: "7381d6e9e2a8f94695f29e73194b1603d79cefb9", class: "drop-indicator subtree-drop-indicator", part: "drop-indicator", "aria-hidden": "true" }));
367
371
  }
368
372
  static get watchers() {
369
373
  return {
@@ -6,7 +6,7 @@ import {
6
6
  getElement,
7
7
  h,
8
8
  registerInstance
9
- } from "./chunk-FSGGPFID.js";
9
+ } from "./chunk-GDMQKT5F.js";
10
10
 
11
11
  // dist/esm/ui-tree.entry.js
12
12
  function classifyDropPosition(rect, clientY, acceptsChildren) {
@@ -62,13 +62,19 @@ var UITree = class {
62
62
  }
63
63
  label = "Tree";
64
64
  hoverExpandDelay = 700;
65
+ /** Maximum resulting item depth accepted by pointer reordering. Zero is unlimited. */
66
+ maxDepth = 0;
65
67
  source = null;
66
68
  target = null;
67
69
  position = null;
70
+ rejectedTarget = null;
71
+ rejectedPosition = null;
72
+ rejection = null;
68
73
  hoverIntent = null;
69
74
  componentDidLoad() {
70
75
  this.hoverIntent = createHoverIntent(this.hoverExpandDelay, this.expandTarget);
71
76
  this.host.addEventListener("dragstart", this.onDragStart);
77
+ this.host.addEventListener("drag", this.onDrag);
72
78
  this.host.addEventListener("dragenter", this.onDragOver);
73
79
  this.host.addEventListener("dragover", this.onDragOver);
74
80
  this.host.addEventListener("dragleave", this.onDragLeave);
@@ -79,6 +85,7 @@ var UITree = class {
79
85
  disconnectedCallback() {
80
86
  this.hoverIntent?.destroy();
81
87
  this.host.removeEventListener("dragstart", this.onDragStart);
88
+ this.host.removeEventListener("drag", this.onDrag);
82
89
  this.host.removeEventListener("dragenter", this.onDragOver);
83
90
  this.host.removeEventListener("dragover", this.onDragOver);
84
91
  this.host.removeEventListener("dragleave", this.onDragLeave);
@@ -126,15 +133,37 @@ var UITree = class {
126
133
  accepts: (item.getAttribute("data-accepts") || item.getAttribute("accepts") || "").split(",").map((value) => value.trim()).filter(Boolean)
127
134
  };
128
135
  }
129
- permitsDrop(source, target, position) {
136
+ constraintDepth(item) {
137
+ if (item.dropDepth !== void 0)
138
+ return item.dropDepth;
139
+ const dropDepth = item.getAttribute("drop-depth");
140
+ if (dropDepth !== null)
141
+ return Number(dropDepth);
142
+ if (item.depth !== void 0)
143
+ return item.depth;
144
+ return Number(item.getAttribute("depth")) || 1;
145
+ }
146
+ dropRejection(source, target, position) {
130
147
  if (source.contains(target))
131
- return false;
148
+ return { reason: "descendant" };
132
149
  const sourceMeta = this.itemMetadata(source);
133
150
  const targetMeta = this.itemMetadata(target);
134
151
  if (position === "inside") {
135
- return this.acceptsChildren(target) && (targetMeta.accepts.length === 0 || targetMeta.accepts.includes(sourceMeta.type));
152
+ if (!this.acceptsChildren(target) || targetMeta.accepts.length > 0 && !targetMeta.accepts.includes(sourceMeta.type)) {
153
+ return { reason: "incompatible" };
154
+ }
155
+ } else if (sourceMeta.type !== targetMeta.type) {
156
+ return { reason: "incompatible" };
136
157
  }
137
- return sourceMeta.type === targetMeta.type;
158
+ const maxDepth = Math.max(0, Math.floor(this.maxDepth));
159
+ if (maxDepth > 0 && source.subtreeDepth !== void 0) {
160
+ const targetDepth = Math.max(0, Math.floor(this.constraintDepth(target)));
161
+ const subtreeDepth = Math.max(0, Math.floor(source.subtreeDepth));
162
+ const resultingDepth = targetDepth + (position === "inside" ? 1 : 0) + subtreeDepth;
163
+ if (resultingDepth > maxDepth)
164
+ return { reason: "max-depth", maxDepth, resultingDepth };
165
+ }
166
+ return null;
138
167
  }
139
168
  clearTarget() {
140
169
  this.target?.removeAttribute("data-drop-position");
@@ -142,10 +171,16 @@ var UITree = class {
142
171
  this.position = null;
143
172
  this.hoverIntent?.cancel();
144
173
  }
174
+ clearRejection() {
175
+ this.rejectedTarget = null;
176
+ this.rejectedPosition = null;
177
+ this.rejection = null;
178
+ }
145
179
  finishDrag() {
146
180
  this.source?.removeAttribute("data-dragging");
147
181
  this.source = null;
148
182
  this.clearTarget();
183
+ this.clearRejection();
149
184
  }
150
185
  expandTarget = (itemId) => {
151
186
  const item = Array.from(this.host.querySelectorAll("ui-tree-item")).find((candidate) => this.itemId(candidate) === itemId);
@@ -176,27 +211,35 @@ var UITree = class {
176
211
  }
177
212
  setElementDragImage(event.dataTransfer, row);
178
213
  };
179
- onDragOver = (event) => {
214
+ updateTarget(target, clientY, dataTransfer) {
180
215
  if (!this.source)
181
- return;
182
- const target = this.itemFromEvent(event);
216
+ return false;
183
217
  if (!target || target === this.source) {
184
218
  this.clearTarget();
185
- return;
219
+ this.clearRejection();
220
+ return false;
186
221
  }
187
222
  const row = this.rowFor(target);
188
223
  if (!row)
189
- return;
190
- const position = classifyDropPosition(row.getBoundingClientRect(), event.clientY, this.acceptsChildren(target));
191
- if (!this.permitsDrop(this.source, target, position)) {
192
- if (event.dataTransfer)
193
- event.dataTransfer.dropEffect = "none";
224
+ return false;
225
+ const position = classifyDropPosition(row.getBoundingClientRect(), clientY, this.acceptsChildren(target));
226
+ const rejection = this.dropRejection(this.source, target, position);
227
+ if (rejection) {
228
+ if (dataTransfer)
229
+ dataTransfer.dropEffect = "none";
194
230
  this.clearTarget();
195
- return;
231
+ if (rejection.reason === "max-depth") {
232
+ this.rejectedTarget = target;
233
+ this.rejectedPosition = position;
234
+ this.rejection = rejection;
235
+ } else {
236
+ this.clearRejection();
237
+ }
238
+ return false;
196
239
  }
197
- event.preventDefault();
198
- if (event.dataTransfer)
199
- event.dataTransfer.dropEffect = "move";
240
+ this.clearRejection();
241
+ if (dataTransfer)
242
+ dataTransfer.dropEffect = "move";
200
243
  if (this.target !== target || this.position !== position) {
201
244
  this.clearTarget();
202
245
  this.target = target;
@@ -208,6 +251,22 @@ var UITree = class {
208
251
  } else {
209
252
  this.hoverIntent?.cancel();
210
253
  }
254
+ return true;
255
+ }
256
+ onDrag = (event) => {
257
+ if (!this.source || event.clientX === 0 && event.clientY === 0)
258
+ return;
259
+ const target = this.itemAtPoint(event.clientX, event.clientY);
260
+ if (target)
261
+ this.updateTarget(target, event.clientY, event.dataTransfer);
262
+ };
263
+ onDragOver = (event) => {
264
+ if (!this.source)
265
+ return;
266
+ const target = this.itemFromEvent(event);
267
+ if (this.updateTarget(target, event.clientY, event.dataTransfer)) {
268
+ event.preventDefault();
269
+ }
211
270
  };
212
271
  onDragLeave = (event) => {
213
272
  if (this.isWithinTree(event.relatedTarget))
@@ -215,12 +274,15 @@ var UITree = class {
215
274
  if (this.itemAtPoint(event.clientX, event.clientY))
216
275
  return;
217
276
  this.clearTarget();
277
+ this.clearRejection();
218
278
  };
219
279
  dispatchReorder(source, target, position) {
220
280
  const sourceId = this.itemId(source);
221
281
  const targetId = this.itemId(target);
222
282
  if (!sourceId || !targetId)
223
283
  return;
284
+ if (position === "inside")
285
+ this.expandTarget(targetId);
224
286
  const sourceMeta = this.itemMetadata(source);
225
287
  const targetMeta = this.itemMetadata(target);
226
288
  dispatchDetail(this.host, "reorder", {
@@ -234,6 +296,21 @@ var UITree = class {
234
296
  trigger: "pointer"
235
297
  });
236
298
  }
299
+ dispatchReorderRejected(source, target, position, rejection) {
300
+ const sourceId = this.itemId(source);
301
+ const targetId = this.itemId(target);
302
+ if (!sourceId || !targetId)
303
+ return;
304
+ dispatchDetail(this.host, "reorder-rejected", {
305
+ sourceId,
306
+ targetId,
307
+ position,
308
+ reason: "max-depth",
309
+ maxDepth: rejection.maxDepth,
310
+ resultingDepth: rejection.resultingDepth,
311
+ trigger: "pointer"
312
+ });
313
+ }
237
314
  onDrop = (event) => {
238
315
  if (!this.source || !this.target || !this.position)
239
316
  return;
@@ -243,13 +320,21 @@ var UITree = class {
243
320
  };
244
321
  onDragEnd = (event) => {
245
322
  if (this.source) {
323
+ if (this.rejectedTarget && this.rejectedPosition && this.rejection) {
324
+ this.dispatchReorderRejected(this.source, this.rejectedTarget, this.rejectedPosition, this.rejection);
325
+ this.finishDrag();
326
+ return;
327
+ }
246
328
  const target = this.itemAtPoint(event.clientX, event.clientY);
247
329
  if (target && target !== this.source) {
248
330
  const row = this.rowFor(target);
249
331
  if (row) {
250
332
  const position = classifyDropPosition(row.getBoundingClientRect(), event.clientY, this.acceptsChildren(target));
251
- if (this.permitsDrop(this.source, target, position)) {
333
+ const rejection = this.dropRejection(this.source, target, position);
334
+ if (!rejection) {
252
335
  this.dispatchReorder(this.source, target, position);
336
+ } else if (rejection.reason === "max-depth") {
337
+ this.dispatchReorderRejected(this.source, target, position, rejection);
253
338
  }
254
339
  }
255
340
  }
@@ -274,7 +359,7 @@ var UITree = class {
274
359
  next.focus();
275
360
  };
276
361
  render() {
277
- return h(Host, { key: "b659635f6acdf09a3618c514f5bdd9bf173f9d98", role: "tree", "aria-label": this.label || "Tree" }, h("slot", { key: "0815f0eb0bfe766dd2f358385af1516fd4328e2e" }));
362
+ return h(Host, { key: "474c2154d2abe3c76eee9c36bf552390089df6e8", role: "tree", "aria-label": this.label || "Tree" }, h("slot", { key: "93aedd02f984dd33b5efc811fef417d1199917bd" }));
278
363
  }
279
364
  };
280
365
  UITree.style = uiTreeCss();
@@ -0,0 +1,52 @@
1
+ import { GenericSchema, GenericSchemaAsync, InferOutput } from 'valibot';
2
+
3
+ /** Structural Standard Schema v1 boundary; no schema-library runtime dependency. */
4
+ interface FieldSchema<Output = unknown> {
5
+ readonly '~standard': {
6
+ readonly version: 1;
7
+ readonly vendor: string;
8
+ readonly validate: (value: unknown) => FieldSchemaResult<Output> | Promise<FieldSchemaResult<Output>>;
9
+ readonly types?: {
10
+ readonly input: unknown;
11
+ readonly output: Output;
12
+ };
13
+ };
14
+ }
15
+ interface FieldIssue {
16
+ readonly message: string;
17
+ readonly path?: ReadonlyArray<PropertyKey | {
18
+ readonly key: PropertyKey;
19
+ }>;
20
+ readonly severity?: 'error' | 'warning';
21
+ }
22
+ type FieldSchemaResult<T = unknown> = {
23
+ readonly value: T;
24
+ readonly issues?: undefined;
25
+ } | {
26
+ readonly issues: readonly FieldIssue[];
27
+ };
28
+ interface FieldRequest<Context = unknown> {
29
+ raw: string;
30
+ value: string | null;
31
+ context: Context;
32
+ signal: AbortSignal;
33
+ }
34
+ interface FieldResult<Output = unknown> {
35
+ output?: Output;
36
+ issues: readonly FieldIssue[];
37
+ }
38
+ interface FieldValidation {
39
+ schema?: FieldSchema;
40
+ parse?: (raw: string, request: FieldRequest) => unknown | Promise<unknown>;
41
+ normalize?: (value: unknown, request: FieldRequest) => unknown | Promise<unknown>;
42
+ validator?: (value: unknown, request: FieldRequest) => Partial<FieldResult> | Promise<Partial<FieldResult>>;
43
+ issues?: readonly FieldIssue[];
44
+ }
45
+
46
+ /** Valibot's Standard Schema implementation preserves async transforms and issue paths.
47
+ * Type-only Valibot imports keep the adapter free of a schema-library runtime. */
48
+ declare function valibotField<T extends GenericSchema | GenericSchemaAsync>(schema: T, options?: Omit<FieldValidation, 'schema'>): FieldValidation & {
49
+ schema: FieldSchema<InferOutput<T>>;
50
+ };
51
+
52
+ export { valibotField };
@@ -0,0 +1,7 @@
1
+ // src/field/valibot.ts
2
+ function valibotField(schema, options = {}) {
3
+ return { ...options, schema };
4
+ }
5
+ export {
6
+ valibotField
7
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@threadlabs/looma",
3
- "version": "0.1.21",
3
+ "version": "0.1.23",
4
4
  "type": "module",
5
5
  "description": "Looma web components, responsive layout primitives, a complete editor, and supported Vue adapters.",
6
6
  "license": "MIT",
@@ -67,7 +67,11 @@
67
67
  "./theme-high-contrast.css": "./theme-high-contrast.css",
68
68
  "./layout.css": "./layout.css",
69
69
  "./styles.css": "./styles.css",
70
- "./editor.css": "./editor.css"
70
+ "./editor.css": "./editor.css",
71
+ "./valibot": {
72
+ "types": "./dist/valibot.d.ts",
73
+ "import": "./dist/valibot.js"
74
+ }
71
75
  },
72
76
  "files": [
73
77
  "dist/",
@@ -101,7 +105,8 @@
101
105
  "@tiptap/core": ">=2 <3",
102
106
  "@tiptap/pm": ">=2 <3",
103
107
  "@tiptap/vue-3": ">=2 <3",
104
- "vue": "^3.5.0"
108
+ "vue": "^3.5.0",
109
+ "valibot": "^1.1.0"
105
110
  },
106
111
  "peerDependenciesMeta": {
107
112
  "@tiptap/core": {
@@ -115,6 +120,9 @@
115
120
  },
116
121
  "vue": {
117
122
  "optional": true
123
+ },
124
+ "valibot": {
125
+ "optional": true
118
126
  }
119
127
  },
120
128
  "engines": {