@llui/components 0.4.10 → 0.5.1

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 (243) hide show
  1. package/dist/components/accordion.d.ts +13 -13
  2. package/dist/components/accordion.d.ts.map +1 -1
  3. package/dist/components/accordion.js +9 -9
  4. package/dist/components/accordion.js.map +1 -1
  5. package/dist/components/alert-dialog.d.ts +8 -8
  6. package/dist/components/alert-dialog.d.ts.map +1 -1
  7. package/dist/components/alert-dialog.js +2 -2
  8. package/dist/components/alert-dialog.js.map +1 -1
  9. package/dist/components/angle-slider.d.ts +13 -13
  10. package/dist/components/angle-slider.d.ts.map +1 -1
  11. package/dist/components/angle-slider.js +11 -11
  12. package/dist/components/angle-slider.js.map +1 -1
  13. package/dist/components/async-list.d.ts +7 -7
  14. package/dist/components/async-list.d.ts.map +1 -1
  15. package/dist/components/async-list.js +5 -8
  16. package/dist/components/async-list.js.map +1 -1
  17. package/dist/components/avatar.d.ts +9 -9
  18. package/dist/components/avatar.d.ts.map +1 -1
  19. package/dist/components/avatar.js +7 -7
  20. package/dist/components/avatar.js.map +1 -1
  21. package/dist/components/carousel.d.ts +18 -18
  22. package/dist/components/carousel.d.ts.map +1 -1
  23. package/dist/components/carousel.js +12 -12
  24. package/dist/components/carousel.js.map +1 -1
  25. package/dist/components/cascade-select.d.ts +12 -12
  26. package/dist/components/cascade-select.d.ts.map +1 -1
  27. package/dist/components/cascade-select.js +8 -8
  28. package/dist/components/cascade-select.js.map +1 -1
  29. package/dist/components/checkbox.d.ts +14 -14
  30. package/dist/components/checkbox.d.ts.map +1 -1
  31. package/dist/components/checkbox.js +12 -12
  32. package/dist/components/checkbox.js.map +1 -1
  33. package/dist/components/clipboard.d.ts +8 -8
  34. package/dist/components/clipboard.d.ts.map +1 -1
  35. package/dist/components/clipboard.js +6 -6
  36. package/dist/components/clipboard.js.map +1 -1
  37. package/dist/components/collapsible.d.ts +11 -11
  38. package/dist/components/collapsible.d.ts.map +1 -1
  39. package/dist/components/collapsible.js +9 -9
  40. package/dist/components/collapsible.js.map +1 -1
  41. package/dist/components/color-picker.d.ts +19 -19
  42. package/dist/components/color-picker.d.ts.map +1 -1
  43. package/dist/components/color-picker.js +21 -21
  44. package/dist/components/color-picker.js.map +1 -1
  45. package/dist/components/combobox.d.ts +25 -25
  46. package/dist/components/combobox.d.ts.map +1 -1
  47. package/dist/components/combobox.js +54 -59
  48. package/dist/components/combobox.js.map +1 -1
  49. package/dist/components/context-menu.d.ts +14 -14
  50. package/dist/components/context-menu.d.ts.map +1 -1
  51. package/dist/components/context-menu.js +15 -19
  52. package/dist/components/context-menu.js.map +1 -1
  53. package/dist/components/date-input.d.ts +13 -13
  54. package/dist/components/date-input.d.ts.map +1 -1
  55. package/dist/components/date-input.js +11 -11
  56. package/dist/components/date-input.js.map +1 -1
  57. package/dist/components/date-picker.d.ts +11 -11
  58. package/dist/components/date-picker.d.ts.map +1 -1
  59. package/dist/components/date-picker.js +7 -7
  60. package/dist/components/date-picker.js.map +1 -1
  61. package/dist/components/dialog.d.ts +15 -15
  62. package/dist/components/dialog.d.ts.map +1 -1
  63. package/dist/components/dialog.js +45 -50
  64. package/dist/components/dialog.js.map +1 -1
  65. package/dist/components/drawer.d.ts +13 -13
  66. package/dist/components/drawer.d.ts.map +1 -1
  67. package/dist/components/drawer.js +44 -49
  68. package/dist/components/drawer.js.map +1 -1
  69. package/dist/components/editable.d.ts +11 -11
  70. package/dist/components/editable.d.ts.map +1 -1
  71. package/dist/components/editable.js +9 -9
  72. package/dist/components/editable.js.map +1 -1
  73. package/dist/components/file-upload.d.ts +19 -19
  74. package/dist/components/file-upload.d.ts.map +1 -1
  75. package/dist/components/file-upload.js +14 -14
  76. package/dist/components/file-upload.js.map +1 -1
  77. package/dist/components/floating-panel.d.ts +14 -14
  78. package/dist/components/floating-panel.d.ts.map +1 -1
  79. package/dist/components/floating-panel.js +13 -14
  80. package/dist/components/floating-panel.js.map +1 -1
  81. package/dist/components/form.d.ts +9 -9
  82. package/dist/components/form.d.ts.map +1 -1
  83. package/dist/components/form.js +7 -7
  84. package/dist/components/form.js.map +1 -1
  85. package/dist/components/hover-card.d.ts +9 -9
  86. package/dist/components/hover-card.d.ts.map +1 -1
  87. package/dist/components/hover-card.js +12 -13
  88. package/dist/components/hover-card.js.map +1 -1
  89. package/dist/components/image-cropper.d.ts +8 -8
  90. package/dist/components/image-cropper.d.ts.map +1 -1
  91. package/dist/components/image-cropper.js +7 -8
  92. package/dist/components/image-cropper.js.map +1 -1
  93. package/dist/components/in-view.d.ts +6 -6
  94. package/dist/components/in-view.d.ts.map +1 -1
  95. package/dist/components/in-view.js +2 -2
  96. package/dist/components/in-view.js.map +1 -1
  97. package/dist/components/listbox.d.ts +16 -16
  98. package/dist/components/listbox.d.ts.map +1 -1
  99. package/dist/components/listbox.js +16 -16
  100. package/dist/components/listbox.js.map +1 -1
  101. package/dist/components/marquee.d.ts +8 -8
  102. package/dist/components/marquee.d.ts.map +1 -1
  103. package/dist/components/marquee.js +8 -11
  104. package/dist/components/marquee.js.map +1 -1
  105. package/dist/components/menu.d.ts +15 -15
  106. package/dist/components/menu.d.ts.map +1 -1
  107. package/dist/components/menu.js +16 -17
  108. package/dist/components/menu.js.map +1 -1
  109. package/dist/components/navigation-menu.d.ts +12 -12
  110. package/dist/components/navigation-menu.d.ts.map +1 -1
  111. package/dist/components/navigation-menu.js +8 -8
  112. package/dist/components/navigation-menu.js.map +1 -1
  113. package/dist/components/number-input.d.ts +18 -18
  114. package/dist/components/number-input.d.ts.map +1 -1
  115. package/dist/components/number-input.js +16 -20
  116. package/dist/components/number-input.js.map +1 -1
  117. package/dist/components/pagination.d.ts +13 -13
  118. package/dist/components/pagination.d.ts.map +1 -1
  119. package/dist/components/pagination.js +11 -17
  120. package/dist/components/pagination.js.map +1 -1
  121. package/dist/components/password-input.d.ts +11 -11
  122. package/dist/components/password-input.d.ts.map +1 -1
  123. package/dist/components/password-input.js +11 -11
  124. package/dist/components/password-input.js.map +1 -1
  125. package/dist/components/pin-input.d.ts +9 -9
  126. package/dist/components/pin-input.d.ts.map +1 -1
  127. package/dist/components/pin-input.js +9 -9
  128. package/dist/components/pin-input.js.map +1 -1
  129. package/dist/components/popover.d.ts +11 -11
  130. package/dist/components/popover.d.ts.map +1 -1
  131. package/dist/components/popover.js +61 -60
  132. package/dist/components/popover.js.map +1 -1
  133. package/dist/components/presence.d.ts +7 -5
  134. package/dist/components/presence.d.ts.map +1 -1
  135. package/dist/components/presence.js +5 -3
  136. package/dist/components/presence.js.map +1 -1
  137. package/dist/components/progress.d.ts +14 -14
  138. package/dist/components/progress.d.ts.map +1 -1
  139. package/dist/components/progress.js +12 -12
  140. package/dist/components/progress.js.map +1 -1
  141. package/dist/components/qr-code.d.ts +7 -7
  142. package/dist/components/qr-code.d.ts.map +1 -1
  143. package/dist/components/qr-code.js +7 -7
  144. package/dist/components/qr-code.js.map +1 -1
  145. package/dist/components/radio-group.d.ts +15 -15
  146. package/dist/components/radio-group.d.ts.map +1 -1
  147. package/dist/components/radio-group.js +12 -13
  148. package/dist/components/radio-group.js.map +1 -1
  149. package/dist/components/rating-group.d.ts +13 -13
  150. package/dist/components/rating-group.d.ts.map +1 -1
  151. package/dist/components/rating-group.js +10 -11
  152. package/dist/components/rating-group.js.map +1 -1
  153. package/dist/components/scroll-area.d.ts +10 -10
  154. package/dist/components/scroll-area.d.ts.map +1 -1
  155. package/dist/components/scroll-area.js +10 -15
  156. package/dist/components/scroll-area.js.map +1 -1
  157. package/dist/components/select.d.ts +26 -26
  158. package/dist/components/select.d.ts.map +1 -1
  159. package/dist/components/select.js +29 -33
  160. package/dist/components/select.js.map +1 -1
  161. package/dist/components/signature-pad.d.ts +12 -12
  162. package/dist/components/signature-pad.d.ts.map +1 -1
  163. package/dist/components/signature-pad.js +10 -10
  164. package/dist/components/signature-pad.js.map +1 -1
  165. package/dist/components/slider.d.ts +22 -22
  166. package/dist/components/slider.d.ts.map +1 -1
  167. package/dist/components/slider.js +17 -17
  168. package/dist/components/slider.js.map +1 -1
  169. package/dist/components/sortable.d.ts +11 -11
  170. package/dist/components/sortable.d.ts.map +1 -1
  171. package/dist/components/sortable.js +20 -20
  172. package/dist/components/sortable.js.map +1 -1
  173. package/dist/components/splitter.d.ts +15 -15
  174. package/dist/components/splitter.d.ts.map +1 -1
  175. package/dist/components/splitter.js +15 -15
  176. package/dist/components/splitter.js.map +1 -1
  177. package/dist/components/steps.d.ts +14 -14
  178. package/dist/components/steps.d.ts.map +1 -1
  179. package/dist/components/steps.js +10 -16
  180. package/dist/components/steps.js.map +1 -1
  181. package/dist/components/switch.d.ts +12 -12
  182. package/dist/components/switch.d.ts.map +1 -1
  183. package/dist/components/switch.js +10 -10
  184. package/dist/components/switch.js.map +1 -1
  185. package/dist/components/tabs.d.ts +15 -15
  186. package/dist/components/tabs.d.ts.map +1 -1
  187. package/dist/components/tabs.js +11 -11
  188. package/dist/components/tabs.js.map +1 -1
  189. package/dist/components/tags-input.d.ts +14 -14
  190. package/dist/components/tags-input.d.ts.map +1 -1
  191. package/dist/components/tags-input.js +10 -10
  192. package/dist/components/tags-input.js.map +1 -1
  193. package/dist/components/theme-switch.d.ts +5 -5
  194. package/dist/components/theme-switch.d.ts.map +1 -1
  195. package/dist/components/theme-switch.js +3 -3
  196. package/dist/components/theme-switch.js.map +1 -1
  197. package/dist/components/time-picker.d.ts +19 -19
  198. package/dist/components/time-picker.d.ts.map +1 -1
  199. package/dist/components/time-picker.js +17 -17
  200. package/dist/components/time-picker.js.map +1 -1
  201. package/dist/components/timer.d.ts +10 -10
  202. package/dist/components/timer.d.ts.map +1 -1
  203. package/dist/components/timer.js +8 -8
  204. package/dist/components/timer.js.map +1 -1
  205. package/dist/components/toast.d.ts +8 -8
  206. package/dist/components/toast.d.ts.map +1 -1
  207. package/dist/components/toast.js +4 -4
  208. package/dist/components/toast.js.map +1 -1
  209. package/dist/components/toc.d.ts +12 -12
  210. package/dist/components/toc.d.ts.map +1 -1
  211. package/dist/components/toc.js +8 -8
  212. package/dist/components/toc.js.map +1 -1
  213. package/dist/components/toggle-group.d.ts +13 -13
  214. package/dist/components/toggle-group.d.ts.map +1 -1
  215. package/dist/components/toggle-group.js +9 -9
  216. package/dist/components/toggle-group.js.map +1 -1
  217. package/dist/components/toggle.d.ts +8 -8
  218. package/dist/components/toggle.d.ts.map +1 -1
  219. package/dist/components/toggle.js +6 -6
  220. package/dist/components/toggle.js.map +1 -1
  221. package/dist/components/tooltip.d.ts +10 -10
  222. package/dist/components/tooltip.d.ts.map +1 -1
  223. package/dist/components/tooltip.js +13 -14
  224. package/dist/components/tooltip.js.map +1 -1
  225. package/dist/components/tour.d.ts +7 -7
  226. package/dist/components/tour.d.ts.map +1 -1
  227. package/dist/components/tour.js +5 -5
  228. package/dist/components/tour.js.map +1 -1
  229. package/dist/components/tree-view.d.ts +19 -19
  230. package/dist/components/tree-view.d.ts.map +1 -1
  231. package/dist/components/tree-view.js +23 -23
  232. package/dist/components/tree-view.js.map +1 -1
  233. package/dist/patterns/confirm-dialog.d.ts +4 -4
  234. package/dist/patterns/confirm-dialog.d.ts.map +1 -1
  235. package/dist/patterns/confirm-dialog.js +7 -9
  236. package/dist/patterns/confirm-dialog.js.map +1 -1
  237. package/package.json +3 -3
  238. package/dist/components/enter-view.d.ts +0 -73
  239. package/dist/components/enter-view.d.ts.map +0 -1
  240. package/dist/components/enter-view.js +0 -51
  241. package/dist/utils/validators.d.ts +0 -34
  242. package/dist/utils/validators.d.ts.map +0 -1
  243. package/dist/utils/validators.js +0 -83
@@ -1 +1 @@
1
- {"version":3,"file":"pin-input.d.ts","sourceRoot":"","sources":["../../src/components/pin-input.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"pin-input.d.ts","sourceRoot":"","sources":["../../src/components/pin-input.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,WAAW,CAAA;AAI7C;;;;GAIG;AAEH,MAAM,MAAM,OAAO,GAAG,SAAS,GAAG,cAAc,GAAG,YAAY,CAAA;AAE/D,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,EAAE,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,OAAO,CAAA;IACb,IAAI,EAAE,OAAO,CAAA;IACb,QAAQ,EAAE,OAAO,CAAA;IACjB,YAAY,EAAE,MAAM,CAAA;CACrB;AAED,MAAM,MAAM,WAAW;AACrB,0FAA0F;AACxF;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE;AACpD,oEAAoE;GAClE;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE;AACtC,iBAAiB;GACf;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE;AAClC,mCAAmC;GACjC;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE;AACnB,iBAAiB;GACf;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAA;AAExC,MAAM,WAAW,YAAY;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;CAClB;AAED,wBAAgB,IAAI,CAAC,IAAI,GAAE,YAAiB,GAAG,aAAa,CAW3D;AAUD,wBAAgB,MAAM,CAAC,KAAK,EAAE,aAAa,EAAE,GAAG,EAAE,WAAW,GAAG,CAAC,aAAa,EAAE,KAAK,EAAE,CAAC,CAqCvF;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAExD;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,aAAa,GAAG,MAAM,CAErD;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE;QACJ,IAAI,EAAE,OAAO,CAAA;QACb,iBAAiB,EAAE,MAAM,CAAA;QACzB,YAAY,EAAE,WAAW,CAAA;QACzB,WAAW,EAAE,MAAM,CAAA;QACnB,eAAe,EAAE,MAAM,CAAC,EAAE,GAAG,SAAS,CAAC,CAAA;KACxC,CAAA;IACD,KAAK,EAAE;QACL,EAAE,EAAE,MAAM,CAAA;QACV,YAAY,EAAE,WAAW,CAAA;QACzB,WAAW,EAAE,OAAO,CAAA;KACrB,CAAA;IACD,4CAA4C;IAC5C,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK;QACxB,IAAI,EAAE,MAAM,CAAC,MAAM,GAAG,UAAU,CAAC,CAAA;QACjC,SAAS,EAAE,MAAM,CAAC,SAAS,GAAG,MAAM,CAAC,CAAA;QACrC,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,CAAA;QACvB,SAAS,EAAE,CAAC,CAAA;QACZ,YAAY,EAAE,KAAK,CAAA;QACnB,YAAY,EAAE,MAAM,CAAA;QACpB,QAAQ,EAAE,MAAM,CAAC,OAAO,CAAC,CAAA;QACzB,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,CAAA;QACrB,YAAY,EAAE,WAAW,CAAA;QACzB,WAAW,EAAE,OAAO,CAAA;QACpB,YAAY,EAAE,MAAM,CAAA;QACpB,OAAO,EAAE,CAAC,CAAC,EAAE,KAAK,KAAK,IAAI,CAAA;QAC3B,SAAS,EAAE,CAAC,CAAC,EAAE,aAAa,KAAK,IAAI,CAAA;QACrC,OAAO,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,IAAI,CAAA;QAChC,OAAO,EAAE,CAAC,CAAC,EAAE,cAAc,KAAK,IAAI,CAAA;KACrC,CAAA;CACF;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAA;IACV,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAA;IACtC,+EAA+E;IAC/E,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,EAAE,GAAG,IAAI,CAAA;CAC9C;AAED,wBAAgB,OAAO,CACrB,KAAK,EAAE,MAAM,CAAC,aAAa,CAAC,EAC5B,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,EACvB,IAAI,EAAE,cAAc,GACnB,aAAa,CAmEf;AAED,eAAO,MAAM,QAAQ;;;;;;CAAkD,CAAA"}
@@ -70,7 +70,7 @@ export function isComplete(state) {
70
70
  export function getValue(state) {
71
71
  return state.values.join('');
72
72
  }
73
- export function connect(get, send, opts) {
73
+ export function connect(state, send, opts) {
74
74
  const labelId = `${opts.id}:label`;
75
75
  const inputLabel = opts.inputLabel ?? en.pinInput.input;
76
76
  const validate = opts.validate;
@@ -80,7 +80,7 @@ export function connect(get, send, opts) {
80
80
  'aria-labelledby': labelId,
81
81
  'data-scope': 'pin-input',
82
82
  'data-part': 'root',
83
- 'data-disabled': (s) => (get(s).disabled ? '' : undefined),
83
+ 'data-disabled': state.map((s) => (s.disabled ? '' : undefined)),
84
84
  },
85
85
  label: {
86
86
  id: labelId,
@@ -88,10 +88,10 @@ export function connect(get, send, opts) {
88
88
  'data-part': 'label',
89
89
  },
90
90
  input: (index) => ({
91
- type: (s) => (get(s).mask ? 'password' : 'text'),
92
- inputMode: (s) => (get(s).type === 'numeric' ? 'numeric' : 'text'),
93
- pattern: (s) => {
94
- switch (get(s).type) {
91
+ type: state.map((s) => (s.mask ? 'password' : 'text')),
92
+ inputMode: state.map((s) => (s.type === 'numeric' ? 'numeric' : 'text')),
93
+ pattern: state.map((s) => {
94
+ switch (s.type) {
95
95
  case 'numeric':
96
96
  return '[0-9]*';
97
97
  case 'alphabetic':
@@ -99,12 +99,12 @@ export function connect(get, send, opts) {
99
99
  case 'alphanumeric':
100
100
  return '[a-zA-Z0-9]*';
101
101
  }
102
- },
102
+ }),
103
103
  maxLength: 1,
104
104
  autoComplete: 'off',
105
105
  'aria-label': inputLabel(index),
106
- disabled: (s) => get(s).disabled,
107
- value: (s) => get(s).values[index] ?? '',
106
+ disabled: state.map((s) => s.disabled),
107
+ value: state.map((s) => s.values[index] ?? ''),
108
108
  'data-scope': 'pin-input',
109
109
  'data-part': 'input',
110
110
  'data-index': String(index),
@@ -1 +1 @@
1
- {"version":3,"file":"pin-input.js","sourceRoot":"","sources":["../../src/components/pin-input.ts"],"names":[],"mappings":"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","sourcesContent":["import { tagSend } from '@llui/dom'\nimport type { Send } from '@llui/dom'\nimport { flipArrow } from '../utils/direction.js'\nimport { en } from '../locale.js'\n\n/**\n * Pin input — a sequence of single-character fields for OTP codes, etc.\n * Auto-advances on input, handles backspace to previous field, supports\n * paste-to-fill across multiple fields.\n */\n\nexport type PinType = 'numeric' | 'alphanumeric' | 'alphabetic'\n\nexport interface PinInputState {\n values: string[]\n length: number\n type: PinType\n mask: boolean\n disabled: boolean\n focusedIndex: number\n}\n\nexport type PinInputMsg =\n /** @intent(\"Set the character at a given field index (auto-advances focus on accept)\") */\n | { type: 'setValue'; index: number; value: string }\n /** @intent(\"Replace every field at once (typically from paste)\") */\n | { type: 'setAll'; values: string[] }\n /** @humanOnly */\n | { type: 'focus'; index: number }\n /** @intent(\"Clear every field\") */\n | { type: 'clear' }\n /** @humanOnly */\n | { type: 'backspace'; index: number }\n\nexport interface PinInputInit {\n length?: number\n type?: PinType\n mask?: boolean\n disabled?: boolean\n values?: string[]\n}\n\nexport function init(opts: PinInputInit = {}): PinInputState {\n const length = opts.length ?? 4\n const values = opts.values ?? new Array<string>(length).fill('')\n return {\n values,\n length,\n type: opts.type ?? 'numeric',\n mask: opts.mask ?? false,\n disabled: opts.disabled ?? false,\n focusedIndex: 0,\n }\n}\n\nfunction sanitize(char: string, type: PinType): string {\n if (char.length !== 1) return ''\n if (type === 'numeric' && !/\\d/.test(char)) return ''\n if (type === 'alphabetic' && !/[a-zA-Z]/.test(char)) return ''\n if (type === 'alphanumeric' && !/[a-zA-Z0-9]/.test(char)) return ''\n return char\n}\n\nexport function update(state: PinInputState, msg: PinInputMsg): [PinInputState, never[]] {\n if (state.disabled) return [state, []]\n switch (msg.type) {\n case 'setValue': {\n const char = sanitize(msg.value.slice(-1), state.type)\n if (!char && msg.value !== '') return [state, []]\n const values = [...state.values]\n values[msg.index] = char\n // Auto-advance\n const nextIndex = char ? Math.min(msg.index + 1, state.length - 1) : msg.index\n return [{ ...state, values, focusedIndex: nextIndex }, []]\n }\n case 'setAll': {\n const values = new Array<string>(state.length).fill('')\n for (let i = 0; i < Math.min(msg.values.length, state.length); i++) {\n values[i] = sanitize(msg.values[i]!, state.type)\n }\n const lastFilled = values.findIndex((v) => v === '')\n const focusedIndex = lastFilled === -1 ? state.length - 1 : lastFilled\n return [{ ...state, values, focusedIndex }, []]\n }\n case 'focus':\n return [{ ...state, focusedIndex: Math.max(0, Math.min(msg.index, state.length - 1)) }, []]\n case 'clear':\n return [{ ...state, values: new Array<string>(state.length).fill(''), focusedIndex: 0 }, []]\n case 'backspace': {\n const values = [...state.values]\n if (values[msg.index]) {\n values[msg.index] = ''\n return [{ ...state, values }, []]\n }\n // Field is empty — move focus back and clear prior\n const prev = Math.max(0, msg.index - 1)\n values[prev] = ''\n return [{ ...state, values, focusedIndex: prev }, []]\n }\n }\n}\n\nexport function isComplete(state: PinInputState): boolean {\n return state.values.every((v) => v !== '')\n}\n\nexport function getValue(state: PinInputState): string {\n return state.values.join('')\n}\n\nexport interface PinInputParts<S> {\n root: {\n role: 'group'\n 'aria-labelledby': string\n 'data-scope': 'pin-input'\n 'data-part': 'root'\n 'data-disabled': (s: S) => '' | undefined\n }\n label: {\n id: string\n 'data-scope': 'pin-input'\n 'data-part': 'label'\n }\n /** Props for the input at a given index. */\n input: (index: number) => {\n type: (s: S) => 'text' | 'password'\n inputMode: (s: S) => 'numeric' | 'text'\n pattern: (s: S) => string\n maxLength: 1\n autoComplete: 'off'\n 'aria-label': string\n disabled: (s: S) => boolean\n value: (s: S) => string\n 'data-scope': 'pin-input'\n 'data-part': 'input'\n 'data-index': string\n onInput: (e: Event) => void\n onKeyDown: (e: KeyboardEvent) => void\n onFocus: (e: FocusEvent) => void\n onPaste: (e: ClipboardEvent) => void\n }\n}\n\nexport interface ConnectOptions {\n id: string\n inputLabel?: (index: number) => string\n /** Validate each character before setting. Non-empty array blocks setDigit. */\n validate?: (value: string) => string[] | null\n}\n\nexport function connect<S>(\n get: (s: S) => PinInputState,\n send: Send<PinInputMsg>,\n opts: ConnectOptions,\n): PinInputParts<S> {\n const labelId = `${opts.id}:label`\n const inputLabel = opts.inputLabel ?? en.pinInput.input\n const validate = opts.validate\n\n return {\n root: {\n role: 'group',\n 'aria-labelledby': labelId,\n 'data-scope': 'pin-input',\n 'data-part': 'root',\n 'data-disabled': (s) => (get(s).disabled ? '' : undefined),\n },\n label: {\n id: labelId,\n 'data-scope': 'pin-input',\n 'data-part': 'label',\n },\n input: (index: number) => ({\n type: (s) => (get(s).mask ? 'password' : 'text'),\n inputMode: (s) => (get(s).type === 'numeric' ? 'numeric' : 'text'),\n pattern: (s) => {\n switch (get(s).type) {\n case 'numeric':\n return '[0-9]*'\n case 'alphabetic':\n return '[a-zA-Z]*'\n case 'alphanumeric':\n return '[a-zA-Z0-9]*'\n }\n },\n maxLength: 1,\n autoComplete: 'off',\n 'aria-label': inputLabel(index),\n disabled: (s) => get(s).disabled,\n value: (s) => get(s).values[index] ?? '',\n 'data-scope': 'pin-input',\n 'data-part': 'input',\n 'data-index': String(index),\n onInput: tagSend(send, ['setValue'], (e) => {\n const value = (e.target as HTMLInputElement).value\n if (validate && value !== '') {\n const errors = validate(value.slice(-1))\n if (errors && errors.length > 0) return\n }\n send({ type: 'setValue', index, value })\n }),\n onKeyDown: tagSend(send, ['backspace', 'focus'], (e) => {\n const key = flipArrow(e.key, e.currentTarget as Element)\n if (key === 'Backspace') {\n send({ type: 'backspace', index })\n } else if (key === 'ArrowLeft') {\n e.preventDefault()\n send({ type: 'focus', index: index - 1 })\n } else if (key === 'ArrowRight') {\n e.preventDefault()\n send({ type: 'focus', index: index + 1 })\n }\n }),\n onFocus: tagSend(send, ['focus'], () => send({ type: 'focus', index })),\n onPaste: tagSend(send, ['setAll'], (e) => {\n e.preventDefault()\n const text = e.clipboardData?.getData('text') ?? ''\n send({ type: 'setAll', values: text.split('') })\n }),\n }),\n }\n}\n\nexport const pinInput = { init, update, connect, isComplete, getValue }\n"]}
1
+ {"version":3,"file":"pin-input.js","sourceRoot":"","sources":["../../src/components/pin-input.ts"],"names":[],"mappings":"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","sourcesContent":["import { tagSend } from '@llui/dom'\nimport type { Send, Signal } from '@llui/dom'\nimport { flipArrow } from '../utils/direction.js'\nimport { en } from '../locale.js'\n\n/**\n * Pin input — a sequence of single-character fields for OTP codes, etc.\n * Auto-advances on input, handles backspace to previous field, supports\n * paste-to-fill across multiple fields.\n */\n\nexport type PinType = 'numeric' | 'alphanumeric' | 'alphabetic'\n\nexport interface PinInputState {\n values: string[]\n length: number\n type: PinType\n mask: boolean\n disabled: boolean\n focusedIndex: number\n}\n\nexport type PinInputMsg =\n /** @intent(\"Set the character at a given field index (auto-advances focus on accept)\") */\n | { type: 'setValue'; index: number; value: string }\n /** @intent(\"Replace every field at once (typically from paste)\") */\n | { type: 'setAll'; values: string[] }\n /** @humanOnly */\n | { type: 'focus'; index: number }\n /** @intent(\"Clear every field\") */\n | { type: 'clear' }\n /** @humanOnly */\n | { type: 'backspace'; index: number }\n\nexport interface PinInputInit {\n length?: number\n type?: PinType\n mask?: boolean\n disabled?: boolean\n values?: string[]\n}\n\nexport function init(opts: PinInputInit = {}): PinInputState {\n const length = opts.length ?? 4\n const values = opts.values ?? new Array<string>(length).fill('')\n return {\n values,\n length,\n type: opts.type ?? 'numeric',\n mask: opts.mask ?? false,\n disabled: opts.disabled ?? false,\n focusedIndex: 0,\n }\n}\n\nfunction sanitize(char: string, type: PinType): string {\n if (char.length !== 1) return ''\n if (type === 'numeric' && !/\\d/.test(char)) return ''\n if (type === 'alphabetic' && !/[a-zA-Z]/.test(char)) return ''\n if (type === 'alphanumeric' && !/[a-zA-Z0-9]/.test(char)) return ''\n return char\n}\n\nexport function update(state: PinInputState, msg: PinInputMsg): [PinInputState, never[]] {\n if (state.disabled) return [state, []]\n switch (msg.type) {\n case 'setValue': {\n const char = sanitize(msg.value.slice(-1), state.type)\n if (!char && msg.value !== '') return [state, []]\n const values = [...state.values]\n values[msg.index] = char\n // Auto-advance\n const nextIndex = char ? Math.min(msg.index + 1, state.length - 1) : msg.index\n return [{ ...state, values, focusedIndex: nextIndex }, []]\n }\n case 'setAll': {\n const values = new Array<string>(state.length).fill('')\n for (let i = 0; i < Math.min(msg.values.length, state.length); i++) {\n values[i] = sanitize(msg.values[i]!, state.type)\n }\n const lastFilled = values.findIndex((v) => v === '')\n const focusedIndex = lastFilled === -1 ? state.length - 1 : lastFilled\n return [{ ...state, values, focusedIndex }, []]\n }\n case 'focus':\n return [{ ...state, focusedIndex: Math.max(0, Math.min(msg.index, state.length - 1)) }, []]\n case 'clear':\n return [{ ...state, values: new Array<string>(state.length).fill(''), focusedIndex: 0 }, []]\n case 'backspace': {\n const values = [...state.values]\n if (values[msg.index]) {\n values[msg.index] = ''\n return [{ ...state, values }, []]\n }\n // Field is empty — move focus back and clear prior\n const prev = Math.max(0, msg.index - 1)\n values[prev] = ''\n return [{ ...state, values, focusedIndex: prev }, []]\n }\n }\n}\n\nexport function isComplete(state: PinInputState): boolean {\n return state.values.every((v) => v !== '')\n}\n\nexport function getValue(state: PinInputState): string {\n return state.values.join('')\n}\n\nexport interface PinInputParts {\n root: {\n role: 'group'\n 'aria-labelledby': string\n 'data-scope': 'pin-input'\n 'data-part': 'root'\n 'data-disabled': Signal<'' | undefined>\n }\n label: {\n id: string\n 'data-scope': 'pin-input'\n 'data-part': 'label'\n }\n /** Props for the input at a given index. */\n input: (index: number) => {\n type: Signal<'text' | 'password'>\n inputMode: Signal<'numeric' | 'text'>\n pattern: Signal<string>\n maxLength: 1\n autoComplete: 'off'\n 'aria-label': string\n disabled: Signal<boolean>\n value: Signal<string>\n 'data-scope': 'pin-input'\n 'data-part': 'input'\n 'data-index': string\n onInput: (e: Event) => void\n onKeyDown: (e: KeyboardEvent) => void\n onFocus: (e: FocusEvent) => void\n onPaste: (e: ClipboardEvent) => void\n }\n}\n\nexport interface ConnectOptions {\n id: string\n inputLabel?: (index: number) => string\n /** Validate each character before setting. Non-empty array blocks setDigit. */\n validate?: (value: string) => string[] | null\n}\n\nexport function connect(\n state: Signal<PinInputState>,\n send: Send<PinInputMsg>,\n opts: ConnectOptions,\n): PinInputParts {\n const labelId = `${opts.id}:label`\n const inputLabel = opts.inputLabel ?? en.pinInput.input\n const validate = opts.validate\n\n return {\n root: {\n role: 'group',\n 'aria-labelledby': labelId,\n 'data-scope': 'pin-input',\n 'data-part': 'root',\n 'data-disabled': state.map((s) => (s.disabled ? '' : undefined)),\n },\n label: {\n id: labelId,\n 'data-scope': 'pin-input',\n 'data-part': 'label',\n },\n input: (index: number) => ({\n type: state.map((s) => (s.mask ? 'password' : 'text')),\n inputMode: state.map((s) => (s.type === 'numeric' ? 'numeric' : 'text')),\n pattern: state.map((s) => {\n switch (s.type) {\n case 'numeric':\n return '[0-9]*'\n case 'alphabetic':\n return '[a-zA-Z]*'\n case 'alphanumeric':\n return '[a-zA-Z0-9]*'\n }\n }),\n maxLength: 1,\n autoComplete: 'off',\n 'aria-label': inputLabel(index),\n disabled: state.map((s) => s.disabled),\n value: state.map((s) => s.values[index] ?? ''),\n 'data-scope': 'pin-input',\n 'data-part': 'input',\n 'data-index': String(index),\n onInput: tagSend(send, ['setValue'], (e) => {\n const value = (e.target as HTMLInputElement).value\n if (validate && value !== '') {\n const errors = validate(value.slice(-1))\n if (errors && errors.length > 0) return\n }\n send({ type: 'setValue', index, value })\n }),\n onKeyDown: tagSend(send, ['backspace', 'focus'], (e) => {\n const key = flipArrow(e.key, e.currentTarget as Element)\n if (key === 'Backspace') {\n send({ type: 'backspace', index })\n } else if (key === 'ArrowLeft') {\n e.preventDefault()\n send({ type: 'focus', index: index - 1 })\n } else if (key === 'ArrowRight') {\n e.preventDefault()\n send({ type: 'focus', index: index + 1 })\n }\n }),\n onFocus: tagSend(send, ['focus'], () => send({ type: 'focus', index })),\n onPaste: tagSend(send, ['setAll'], (e) => {\n e.preventDefault()\n const text = e.clipboardData?.getData('text') ?? ''\n send({ type: 'setAll', values: text.split('') })\n }),\n }),\n }\n}\n\nexport const pinInput = { init, update, connect, isComplete, getValue }\n"]}
@@ -1,4 +1,4 @@
1
- import type { Send, TransitionOptions } from '@llui/dom';
1
+ import type { Send, Signal, TransitionOptions } from '@llui/dom';
2
2
  import { type Placement } from '../utils/floating.js';
3
3
  /**
4
4
  * Popover — click-triggered, non-modal floating overlay anchored to its
@@ -33,14 +33,14 @@ export interface PopoverInit {
33
33
  }
34
34
  export declare function init(opts?: PopoverInit): PopoverState;
35
35
  export declare function update(state: PopoverState, msg: PopoverMsg): [PopoverState, never[]];
36
- export interface PopoverParts<S> {
36
+ export interface PopoverParts {
37
37
  trigger: {
38
38
  type: 'button';
39
39
  'aria-haspopup': 'dialog';
40
- 'aria-expanded': (s: S) => boolean;
40
+ 'aria-expanded': Signal<boolean>;
41
41
  'aria-controls': string;
42
42
  id: string;
43
- 'data-state': (s: S) => 'open' | 'closed';
43
+ 'data-state': Signal<'open' | 'closed'>;
44
44
  'data-scope': 'popover';
45
45
  'data-part': 'trigger';
46
46
  onClick: (e: MouseEvent) => void;
@@ -55,7 +55,7 @@ export interface PopoverParts<S> {
55
55
  id: string;
56
56
  'aria-labelledby': string;
57
57
  tabIndex: -1;
58
- 'data-state': (s: S) => 'open' | 'closed';
58
+ 'data-state': Signal<'open' | 'closed'>;
59
59
  'data-scope': 'popover';
60
60
  'data-part': 'content';
61
61
  };
@@ -75,7 +75,7 @@ export interface PopoverParts<S> {
75
75
  };
76
76
  closeTrigger: {
77
77
  type: 'button';
78
- 'aria-label': string | ((s: S) => string);
78
+ 'aria-label': string;
79
79
  'data-scope': 'popover';
80
80
  'data-part': 'close-trigger';
81
81
  onClick: (e: MouseEvent) => void;
@@ -85,11 +85,11 @@ export interface ConnectOptions {
85
85
  id: string;
86
86
  closeLabel?: string;
87
87
  }
88
- export declare function connect<S>(get: (s: S) => PopoverState, send: Send<PopoverMsg>, opts: ConnectOptions): PopoverParts<S>;
89
- export interface OverlayOptions<S> {
90
- get: (s: S) => PopoverState;
88
+ export declare function connect(state: Signal<PopoverState>, send: Send<PopoverMsg>, opts: ConnectOptions): PopoverParts;
89
+ export interface OverlayOptions {
90
+ state: Signal<PopoverState>;
91
91
  send: Send<PopoverMsg>;
92
- parts: PopoverParts<S>;
92
+ parts: PopoverParts;
93
93
  content: () => Node[];
94
94
  /** Placement preference — bottom | top | right | left with -start/-end variants. */
95
95
  placement?: Placement;
@@ -114,7 +114,7 @@ export interface OverlayOptions<S> {
114
114
  /** Arrow element selector within content (optional). */
115
115
  arrowSelector?: string;
116
116
  }
117
- export declare function overlay<S>(opts: OverlayOptions<S>): Node[];
117
+ export declare function overlay(opts: OverlayOptions): Node[];
118
118
  export declare const popover: {
119
119
  init: typeof init;
120
120
  update: typeof update;
@@ -1 +1 @@
1
- {"version":3,"file":"popover.d.ts","sourceRoot":"","sources":["../../src/components/popover.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"popover.d.ts","sourceRoot":"","sources":["../../src/components/popover.ts"],"names":[],"mappings":"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"}
@@ -18,22 +18,22 @@ export function update(state, msg) {
18
18
  return [{ ...state, open: msg.open }, []];
19
19
  }
20
20
  }
21
- export function connect(get, send, opts) {
21
+ export function connect(state, send, opts) {
22
22
  const locale = useContext(LocaleContext);
23
23
  const base = opts.id;
24
24
  const triggerId = `${base}:trigger`;
25
25
  const contentId = `${base}:content`;
26
26
  const titleId = `${base}:title`;
27
27
  const descId = `${base}:description`;
28
- const closeLabel = opts.closeLabel ?? ((s) => locale(s).popover.close);
28
+ const closeLabel = opts.closeLabel ?? locale.popover.close;
29
29
  return {
30
30
  trigger: {
31
31
  type: 'button',
32
32
  'aria-haspopup': 'dialog',
33
- 'aria-expanded': (s) => get(s).open,
33
+ 'aria-expanded': state.map((st) => st.open),
34
34
  'aria-controls': contentId,
35
35
  id: triggerId,
36
- 'data-state': (s) => (get(s).open ? 'open' : 'closed'),
36
+ 'data-state': state.map((st) => (st.open ? 'open' : 'closed')),
37
37
  'data-scope': 'popover',
38
38
  'data-part': 'trigger',
39
39
  onClick: tagSend(send, ['toggle'], () => send({ type: 'toggle' })),
@@ -48,7 +48,7 @@ export function connect(get, send, opts) {
48
48
  id: contentId,
49
49
  'aria-labelledby': titleId,
50
50
  tabIndex: -1,
51
- 'data-state': (s) => (get(s).open ? 'open' : 'closed'),
51
+ 'data-state': state.map((st) => (st.open ? 'open' : 'closed')),
52
52
  'data-scope': 'popover',
53
53
  'data-part': 'content',
54
54
  },
@@ -76,7 +76,7 @@ export function connect(get, send, opts) {
76
76
  };
77
77
  }
78
78
  export function overlay(opts) {
79
- const target = opts.target ?? 'body';
79
+ const rawTarget = opts.target ?? 'body';
80
80
  const placement = opts.placement ?? 'bottom';
81
81
  const offset = opts.offset ?? 8;
82
82
  const flip = opts.flip !== false;
@@ -88,62 +88,63 @@ export function overlay(opts) {
88
88
  const parts = opts.parts;
89
89
  const contentId = parts.content.id;
90
90
  const triggerId = parts.trigger.id;
91
- return show({
92
- when: (s) => opts.get(s).open,
93
- render: () => portal({
94
- target,
95
- render: () => {
96
- onMount(() => {
97
- const contentEl = document.getElementById(contentId);
98
- const triggerEl = document.getElementById(triggerId);
99
- if (!contentEl || !triggerEl)
100
- return;
101
- const cleanups = [];
102
- // Position content relative to trigger
103
- const positioner = contentEl.closest('[data-part="positioner"]');
104
- const floatingEl = positioner ?? contentEl;
105
- const arrow = opts.arrowSelector
106
- ? contentEl.querySelector(opts.arrowSelector)
107
- : null;
108
- cleanups.push(attachFloating({
109
- anchor: triggerEl,
110
- floating: floatingEl,
111
- placement,
112
- offset,
113
- flip,
114
- shift,
115
- arrow: arrow ?? undefined,
116
- }));
117
- if (trapFocus) {
118
- cleanups.push(pushFocusTrap({
119
- container: contentEl,
120
- restoreFocus,
91
+ return [
92
+ show(opts.state.map((st) => st.open), () => {
93
+ const targetEl = typeof rawTarget === 'string'
94
+ ? (document.querySelector(rawTarget) ?? document.body)
95
+ : rawTarget;
96
+ return [
97
+ portal(() => {
98
+ onMount(() => {
99
+ const contentEl = document.getElementById(contentId);
100
+ const triggerEl = document.getElementById(triggerId);
101
+ if (!contentEl || !triggerEl)
102
+ return;
103
+ const cleanups = [];
104
+ // Position content relative to trigger
105
+ const positioner = contentEl.closest('[data-part="positioner"]');
106
+ const floatingEl = positioner ?? contentEl;
107
+ const arrow = opts.arrowSelector
108
+ ? contentEl.querySelector(opts.arrowSelector)
109
+ : null;
110
+ cleanups.push(attachFloating({
111
+ anchor: triggerEl,
112
+ floating: floatingEl,
113
+ placement,
114
+ offset,
115
+ flip,
116
+ shift,
117
+ arrow: arrow ?? undefined,
121
118
  }));
122
- }
123
- if (closeOnEscape || closeOnOutsideClick) {
124
- cleanups.push(pushDismissable({
125
- element: contentEl,
126
- ignore: () => [triggerEl],
127
- disableEscape: !closeOnEscape,
128
- disableOutside: !closeOnOutsideClick,
129
- onDismiss: () => {
130
- opts.send({ type: 'close' });
131
- if (restoreFocus)
132
- triggerEl.focus();
133
- },
134
- }));
135
- }
136
- return () => {
137
- for (let i = cleanups.length - 1; i >= 0; i--)
138
- cleanups[i]();
139
- };
140
- });
141
- return [div(parts.positioner, opts.content())];
142
- },
119
+ if (trapFocus) {
120
+ cleanups.push(pushFocusTrap({
121
+ container: contentEl,
122
+ restoreFocus,
123
+ }));
124
+ }
125
+ if (closeOnEscape || closeOnOutsideClick) {
126
+ cleanups.push(pushDismissable({
127
+ element: contentEl,
128
+ ignore: () => [triggerEl],
129
+ disableEscape: !closeOnEscape,
130
+ disableOutside: !closeOnOutsideClick,
131
+ onDismiss: () => {
132
+ opts.send({ type: 'close' });
133
+ if (restoreFocus)
134
+ triggerEl.focus();
135
+ },
136
+ }));
137
+ }
138
+ return () => {
139
+ for (let i = cleanups.length - 1; i >= 0; i--)
140
+ cleanups[i]();
141
+ };
142
+ });
143
+ return [div(parts.positioner, opts.content())];
144
+ }, targetEl),
145
+ ];
143
146
  }),
144
- enter: opts.transition?.enter,
145
- leave: opts.transition?.leave,
146
- });
147
+ ];
147
148
  }
148
149
  export const popover = { init, update, connect, overlay };
149
150
  //# sourceMappingURL=popover.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"popover.js","sourceRoot":"","sources":["../../src/components/popover.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Send, TransitionOptions } from '@llui/dom'\nimport { show, portal, onMount, div, useContext, tagSend } from '@llui/dom'\nimport { LocaleContext } from '../locale.js'\nimport type { Locale } from '../locale.js'\nimport { pushDismissable } from '../utils/dismissable.js'\nimport { pushFocusTrap } from '../utils/focus-trap.js'\nimport { attachFloating, type Placement } from '../utils/floating.js'\n\n/**\n * Popover — click-triggered, non-modal floating overlay anchored to its\n * trigger. Use for menus, date pickers, color pickers, filters, etc.\n *\n * Like dialog, has a pure state machine + a view helper (`overlay()`) that\n * wires floating-ui positioning, dismissable, and optional focus trapping.\n */\n\nexport interface PopoverState {\n open: boolean\n}\n\nexport type PopoverMsg =\n /** @intent(\"Open the popover\") */\n | { type: 'open' }\n /** @intent(\"Close the popover\") */\n | { type: 'close' }\n /** @intent(\"Toggle the popover open/closed\") */\n | { type: 'toggle' }\n /** @intent(\"Set the popover's open state to a specific value\") */\n | { type: 'setOpen'; open: boolean }\n\nexport interface PopoverInit {\n open?: boolean\n}\n\nexport function init(opts: PopoverInit = {}): PopoverState {\n return { open: opts.open ?? false }\n}\n\nexport function update(state: PopoverState, msg: PopoverMsg): [PopoverState, never[]] {\n switch (msg.type) {\n case 'open':\n return [{ ...state, open: true }, []]\n case 'close':\n return [{ ...state, open: false }, []]\n case 'toggle':\n return [{ ...state, open: !state.open }, []]\n case 'setOpen':\n return [{ ...state, open: msg.open }, []]\n }\n}\n\nexport interface PopoverParts<S> {\n trigger: {\n type: 'button'\n 'aria-haspopup': 'dialog'\n 'aria-expanded': (s: S) => boolean\n 'aria-controls': string\n id: string\n 'data-state': (s: S) => 'open' | 'closed'\n 'data-scope': 'popover'\n 'data-part': 'trigger'\n onClick: (e: MouseEvent) => void\n }\n positioner: {\n 'data-scope': 'popover'\n 'data-part': 'positioner'\n style: string\n }\n content: {\n role: 'dialog'\n id: string\n 'aria-labelledby': string\n tabIndex: -1\n 'data-state': (s: S) => 'open' | 'closed'\n 'data-scope': 'popover'\n 'data-part': 'content'\n }\n title: {\n id: string\n 'data-scope': 'popover'\n 'data-part': 'title'\n }\n description: {\n id: string\n 'data-scope': 'popover'\n 'data-part': 'description'\n }\n arrow: {\n 'data-scope': 'popover'\n 'data-part': 'arrow'\n }\n closeTrigger: {\n type: 'button'\n 'aria-label': string | ((s: S) => string)\n 'data-scope': 'popover'\n 'data-part': 'close-trigger'\n onClick: (e: MouseEvent) => void\n }\n}\n\nexport interface ConnectOptions {\n id: string\n closeLabel?: string\n}\n\nexport function connect<S>(\n get: (s: S) => PopoverState,\n send: Send<PopoverMsg>,\n opts: ConnectOptions,\n): PopoverParts<S> {\n const locale = useContext<S, Locale>(LocaleContext)\n const base = opts.id\n const triggerId = `${base}:trigger`\n const contentId = `${base}:content`\n const titleId = `${base}:title`\n const descId = `${base}:description`\n const closeLabel: string | ((s: S) => string) =\n opts.closeLabel ?? ((s: S) => locale(s).popover.close)\n\n return {\n trigger: {\n type: 'button',\n 'aria-haspopup': 'dialog',\n 'aria-expanded': (s) => get(s).open,\n 'aria-controls': contentId,\n id: triggerId,\n 'data-state': (s) => (get(s).open ? 'open' : 'closed'),\n 'data-scope': 'popover',\n 'data-part': 'trigger',\n onClick: tagSend(send, ['toggle'], () => send({ type: 'toggle' })),\n },\n positioner: {\n 'data-scope': 'popover',\n 'data-part': 'positioner',\n style: 'position:absolute;top:0;left:0;',\n },\n content: {\n role: 'dialog',\n id: contentId,\n 'aria-labelledby': titleId,\n tabIndex: -1,\n 'data-state': (s) => (get(s).open ? 'open' : 'closed'),\n 'data-scope': 'popover',\n 'data-part': 'content',\n },\n title: {\n id: titleId,\n 'data-scope': 'popover',\n 'data-part': 'title',\n },\n description: {\n id: descId,\n 'data-scope': 'popover',\n 'data-part': 'description',\n },\n arrow: {\n 'data-scope': 'popover',\n 'data-part': 'arrow',\n },\n closeTrigger: {\n type: 'button',\n 'aria-label': closeLabel,\n 'data-scope': 'popover',\n 'data-part': 'close-trigger',\n onClick: tagSend(send, ['close'], () => send({ type: 'close' })),\n },\n }\n}\n\nexport interface OverlayOptions<S> {\n get: (s: S) => PopoverState\n send: Send<PopoverMsg>\n parts: PopoverParts<S>\n content: () => Node[]\n /** Placement preference — bottom | top | right | left with -start/-end variants. */\n placement?: Placement\n /** Offset between trigger and content, px (default: 8). */\n offset?: number\n /** Auto-flip to opposite side (default: true). */\n flip?: boolean\n /** Shift to keep in viewport (default: true). */\n shift?: boolean\n /** Optional transition. */\n transition?: TransitionOptions\n /** Close on Escape (default: true). */\n closeOnEscape?: boolean\n /** Close on outside click (default: true). */\n closeOnOutsideClick?: boolean\n /** Trap focus inside popover while open (default: false — non-modal). */\n trapFocus?: boolean\n /** Restore focus to trigger on close (default: true). */\n restoreFocus?: boolean\n /** Portal target (default: 'body'). */\n target?: string | HTMLElement\n /** Arrow element selector within content (optional). */\n arrowSelector?: string\n}\n\nexport function overlay<S>(opts: OverlayOptions<S>): Node[] {\n const target = opts.target ?? 'body'\n const placement = opts.placement ?? 'bottom'\n const offset = opts.offset ?? 8\n const flip = opts.flip !== false\n const shift = opts.shift !== false\n const closeOnEscape = opts.closeOnEscape !== false\n const closeOnOutsideClick = opts.closeOnOutsideClick !== false\n const trapFocus = opts.trapFocus === true\n const restoreFocus = opts.restoreFocus !== false\n const parts = opts.parts\n const contentId = parts.content.id\n const triggerId = parts.trigger.id\n\n return show<S, PopoverMsg>({\n when: (s) => opts.get(s).open,\n render: () =>\n portal({\n target,\n render: () => {\n onMount(() => {\n const contentEl = document.getElementById(contentId)\n const triggerEl = document.getElementById(triggerId)\n if (!contentEl || !triggerEl) return\n\n const cleanups: Array<() => void> = []\n\n // Position content relative to trigger\n const positioner = contentEl.closest('[data-part=\"positioner\"]') as HTMLElement | null\n const floatingEl = positioner ?? contentEl\n const arrow = opts.arrowSelector\n ? (contentEl.querySelector(opts.arrowSelector) as HTMLElement | null)\n : null\n cleanups.push(\n attachFloating({\n anchor: triggerEl,\n floating: floatingEl,\n placement,\n offset,\n flip,\n shift,\n arrow: arrow ?? undefined,\n }),\n )\n\n if (trapFocus) {\n cleanups.push(\n pushFocusTrap({\n container: contentEl,\n restoreFocus,\n }),\n )\n }\n\n if (closeOnEscape || closeOnOutsideClick) {\n cleanups.push(\n pushDismissable({\n element: contentEl,\n ignore: () => [triggerEl],\n disableEscape: !closeOnEscape,\n disableOutside: !closeOnOutsideClick,\n onDismiss: () => {\n opts.send({ type: 'close' })\n if (restoreFocus) triggerEl.focus()\n },\n }),\n )\n }\n\n return () => {\n for (let i = cleanups.length - 1; i >= 0; i--) cleanups[i]!()\n }\n })\n return [div(parts.positioner, opts.content())]\n },\n }),\n enter: opts.transition?.enter,\n leave: opts.transition?.leave,\n })\n}\n\nexport const popover = { init, update, connect, overlay }\n"]}
1
+ {"version":3,"file":"popover.js","sourceRoot":"","sources":["../../src/components/popover.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Send, Signal, TransitionOptions } from '@llui/dom'\nimport { show, portal, onMount, div, useContext, tagSend } from '@llui/dom'\nimport { LocaleContext } from '../locale.js'\nimport { pushDismissable } from '../utils/dismissable.js'\nimport { pushFocusTrap } from '../utils/focus-trap.js'\nimport { attachFloating, type Placement } from '../utils/floating.js'\n\n/**\n * Popover — click-triggered, non-modal floating overlay anchored to its\n * trigger. Use for menus, date pickers, color pickers, filters, etc.\n *\n * Like dialog, has a pure state machine + a view helper (`overlay()`) that\n * wires floating-ui positioning, dismissable, and optional focus trapping.\n */\n\nexport interface PopoverState {\n open: boolean\n}\n\nexport type PopoverMsg =\n /** @intent(\"Open the popover\") */\n | { type: 'open' }\n /** @intent(\"Close the popover\") */\n | { type: 'close' }\n /** @intent(\"Toggle the popover open/closed\") */\n | { type: 'toggle' }\n /** @intent(\"Set the popover's open state to a specific value\") */\n | { type: 'setOpen'; open: boolean }\n\nexport interface PopoverInit {\n open?: boolean\n}\n\nexport function init(opts: PopoverInit = {}): PopoverState {\n return { open: opts.open ?? false }\n}\n\nexport function update(state: PopoverState, msg: PopoverMsg): [PopoverState, never[]] {\n switch (msg.type) {\n case 'open':\n return [{ ...state, open: true }, []]\n case 'close':\n return [{ ...state, open: false }, []]\n case 'toggle':\n return [{ ...state, open: !state.open }, []]\n case 'setOpen':\n return [{ ...state, open: msg.open }, []]\n }\n}\n\nexport interface PopoverParts {\n trigger: {\n type: 'button'\n 'aria-haspopup': 'dialog'\n 'aria-expanded': Signal<boolean>\n 'aria-controls': string\n id: string\n 'data-state': Signal<'open' | 'closed'>\n 'data-scope': 'popover'\n 'data-part': 'trigger'\n onClick: (e: MouseEvent) => void\n }\n positioner: {\n 'data-scope': 'popover'\n 'data-part': 'positioner'\n style: string\n }\n content: {\n role: 'dialog'\n id: string\n 'aria-labelledby': string\n tabIndex: -1\n 'data-state': Signal<'open' | 'closed'>\n 'data-scope': 'popover'\n 'data-part': 'content'\n }\n title: {\n id: string\n 'data-scope': 'popover'\n 'data-part': 'title'\n }\n description: {\n id: string\n 'data-scope': 'popover'\n 'data-part': 'description'\n }\n arrow: {\n 'data-scope': 'popover'\n 'data-part': 'arrow'\n }\n closeTrigger: {\n type: 'button'\n 'aria-label': string\n 'data-scope': 'popover'\n 'data-part': 'close-trigger'\n onClick: (e: MouseEvent) => void\n }\n}\n\nexport interface ConnectOptions {\n id: string\n closeLabel?: string\n}\n\nexport function connect(\n state: Signal<PopoverState>,\n send: Send<PopoverMsg>,\n opts: ConnectOptions,\n): PopoverParts {\n const locale = useContext(LocaleContext)\n const base = opts.id\n const triggerId = `${base}:trigger`\n const contentId = `${base}:content`\n const titleId = `${base}:title`\n const descId = `${base}:description`\n const closeLabel = opts.closeLabel ?? locale.popover.close\n\n return {\n trigger: {\n type: 'button',\n 'aria-haspopup': 'dialog',\n 'aria-expanded': state.map((st) => st.open),\n 'aria-controls': contentId,\n id: triggerId,\n 'data-state': state.map((st) => (st.open ? 'open' : 'closed')),\n 'data-scope': 'popover',\n 'data-part': 'trigger',\n onClick: tagSend(send, ['toggle'], () => send({ type: 'toggle' })),\n },\n positioner: {\n 'data-scope': 'popover',\n 'data-part': 'positioner',\n style: 'position:absolute;top:0;left:0;',\n },\n content: {\n role: 'dialog',\n id: contentId,\n 'aria-labelledby': titleId,\n tabIndex: -1,\n 'data-state': state.map((st) => (st.open ? 'open' : 'closed')),\n 'data-scope': 'popover',\n 'data-part': 'content',\n },\n title: {\n id: titleId,\n 'data-scope': 'popover',\n 'data-part': 'title',\n },\n description: {\n id: descId,\n 'data-scope': 'popover',\n 'data-part': 'description',\n },\n arrow: {\n 'data-scope': 'popover',\n 'data-part': 'arrow',\n },\n closeTrigger: {\n type: 'button',\n 'aria-label': closeLabel,\n 'data-scope': 'popover',\n 'data-part': 'close-trigger',\n onClick: tagSend(send, ['close'], () => send({ type: 'close' })),\n },\n }\n}\n\nexport interface OverlayOptions {\n state: Signal<PopoverState>\n send: Send<PopoverMsg>\n parts: PopoverParts\n content: () => Node[]\n /** Placement preference — bottom | top | right | left with -start/-end variants. */\n placement?: Placement\n /** Offset between trigger and content, px (default: 8). */\n offset?: number\n /** Auto-flip to opposite side (default: true). */\n flip?: boolean\n /** Shift to keep in viewport (default: true). */\n shift?: boolean\n /** Optional transition. */\n transition?: TransitionOptions\n /** Close on Escape (default: true). */\n closeOnEscape?: boolean\n /** Close on outside click (default: true). */\n closeOnOutsideClick?: boolean\n /** Trap focus inside popover while open (default: false — non-modal). */\n trapFocus?: boolean\n /** Restore focus to trigger on close (default: true). */\n restoreFocus?: boolean\n /** Portal target (default: 'body'). */\n target?: string | HTMLElement\n /** Arrow element selector within content (optional). */\n arrowSelector?: string\n}\n\nexport function overlay(opts: OverlayOptions): Node[] {\n const rawTarget = opts.target ?? 'body'\n const placement = opts.placement ?? 'bottom'\n const offset = opts.offset ?? 8\n const flip = opts.flip !== false\n const shift = opts.shift !== false\n const closeOnEscape = opts.closeOnEscape !== false\n const closeOnOutsideClick = opts.closeOnOutsideClick !== false\n const trapFocus = opts.trapFocus === true\n const restoreFocus = opts.restoreFocus !== false\n const parts = opts.parts\n const contentId = parts.content.id\n const triggerId = parts.trigger.id\n\n return [\n show(\n opts.state.map((st) => st.open),\n () => {\n const targetEl =\n typeof rawTarget === 'string'\n ? (document.querySelector(rawTarget) ?? document.body)\n : rawTarget\n return [\n portal(() => {\n onMount(() => {\n const contentEl = document.getElementById(contentId)\n const triggerEl = document.getElementById(triggerId)\n if (!contentEl || !triggerEl) return\n\n const cleanups: Array<() => void> = []\n\n // Position content relative to trigger\n const positioner = contentEl.closest('[data-part=\"positioner\"]') as HTMLElement | null\n const floatingEl = positioner ?? contentEl\n const arrow = opts.arrowSelector\n ? (contentEl.querySelector(opts.arrowSelector) as HTMLElement | null)\n : null\n cleanups.push(\n attachFloating({\n anchor: triggerEl,\n floating: floatingEl,\n placement,\n offset,\n flip,\n shift,\n arrow: arrow ?? undefined,\n }),\n )\n\n if (trapFocus) {\n cleanups.push(\n pushFocusTrap({\n container: contentEl,\n restoreFocus,\n }),\n )\n }\n\n if (closeOnEscape || closeOnOutsideClick) {\n cleanups.push(\n pushDismissable({\n element: contentEl,\n ignore: () => [triggerEl],\n disableEscape: !closeOnEscape,\n disableOutside: !closeOnOutsideClick,\n onDismiss: () => {\n opts.send({ type: 'close' })\n if (restoreFocus) triggerEl.focus()\n },\n }),\n )\n }\n\n return () => {\n for (let i = cleanups.length - 1; i >= 0; i--) cleanups[i]!()\n }\n })\n return [div(parts.positioner, opts.content())]\n }, targetEl),\n ]\n },\n ),\n ]\n}\n\nexport const popover = { init, update, connect, overlay }\n"]}
@@ -1,4 +1,4 @@
1
- import type { Send } from '@llui/dom';
1
+ import type { Send, Signal } from '@llui/dom';
2
2
  /**
3
3
  * Presence — track mount/unmount lifecycle with exit-delay support.
4
4
  *
@@ -59,17 +59,19 @@ export declare function isMounted(state: PresenceState): boolean;
59
59
  /** Whether the element is visible (not running an exit animation). */
60
60
  export declare function isVisible(state: PresenceState): boolean;
61
61
  export declare function isAnimating(state: PresenceState): boolean;
62
- export interface PresenceParts<S> {
62
+ export interface PresenceParts {
63
63
  root: {
64
64
  'data-scope': 'presence';
65
65
  'data-part': 'root';
66
- 'data-state': (s: S) => PresenceStatus;
67
- hidden: (s: S) => boolean;
66
+ 'data-state': Signal<PresenceStatus>;
67
+ hidden: Signal<boolean>;
68
68
  onAnimationEnd: (e: AnimationEvent) => void;
69
69
  onTransitionEnd: (e: TransitionEvent) => void;
70
70
  };
71
71
  }
72
- export declare function connect<S>(get: (s: S) => PresenceState, send: Send<PresenceMsg>): PresenceParts<S>;
72
+ /** Signal-surface connect: takes the component's `presence` state slice as a
73
+ * Signal and returns reactive (handle-based) props for spreading into a view. */
74
+ export declare function connect(state: Signal<PresenceState>, send: Send<PresenceMsg>): PresenceParts;
73
75
  export declare const presence: {
74
76
  init: typeof init;
75
77
  update: typeof update;
@@ -1 +1 @@
1
- {"version":3,"file":"presence.d.ts","sourceRoot":"","sources":["../../src/components/presence.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAErC;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAAA;AAEtE,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,cAAc,CAAA;IACtB,aAAa,EAAE,OAAO,CAAA;CACvB;AAED,MAAM,MAAM,WAAW;AACrB,qFAAqF;AACnF;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE;AAClB,kFAAkF;GAChF;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE;AACnB,uDAAuD;GACrD;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE;AACpB,iBAAiB;GACf;IAAE,IAAI,EAAE,cAAc,CAAA;CAAE;AAC1B,iFAAiF;GAC/E;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAAA;AAE5C,MAAM,WAAW,YAAY;IAC3B,0EAA0E;IAC1E,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,8FAA8F;IAC9F,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB;AAED,wBAAgB,IAAI,CAAC,IAAI,GAAE,YAAiB,GAAG,aAAa,CAK3D;AAED,wBAAgB,MAAM,CAAC,KAAK,EAAE,aAAa,EAAE,GAAG,EAAE,WAAW,GAAG,CAAC,aAAa,EAAE,KAAK,EAAE,CAAC,CAmBvF;AAED,0DAA0D;AAC1D,wBAAgB,SAAS,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAGvD;AAED,sEAAsE;AACtE,wBAAgB,SAAS,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAEvD;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAEzD;AAED,MAAM,WAAW,aAAa,CAAC,CAAC;IAC9B,IAAI,EAAE;QACJ,YAAY,EAAE,UAAU,CAAA;QACxB,WAAW,EAAE,MAAM,CAAA;QACnB,YAAY,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,cAAc,CAAA;QACtC,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,OAAO,CAAA;QACzB,cAAc,EAAE,CAAC,CAAC,EAAE,cAAc,KAAK,IAAI,CAAA;QAC3C,eAAe,EAAE,CAAC,CAAC,EAAE,eAAe,KAAK,IAAI,CAAA;KAC9C,CAAA;CACF;AAED,wBAAgB,OAAO,CAAC,CAAC,EACvB,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,aAAa,EAC5B,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,GACtB,aAAa,CAAC,CAAC,CAAC,CAYlB;AAED,eAAO,MAAM,QAAQ;;;;;;;CAA+D,CAAA"}
1
+ {"version":3,"file":"presence.d.ts","sourceRoot":"","sources":["../../src/components/presence.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,WAAW,CAAA;AAE7C;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAAA;AAEtE,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,cAAc,CAAA;IACtB,aAAa,EAAE,OAAO,CAAA;CACvB;AAED,MAAM,MAAM,WAAW;AACrB,qFAAqF;AACnF;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE;AAClB,kFAAkF;GAChF;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE;AACnB,uDAAuD;GACrD;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE;AACpB,iBAAiB;GACf;IAAE,IAAI,EAAE,cAAc,CAAA;CAAE;AAC1B,iFAAiF;GAC/E;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAAA;AAE5C,MAAM,WAAW,YAAY;IAC3B,0EAA0E;IAC1E,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,8FAA8F;IAC9F,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB;AAED,wBAAgB,IAAI,CAAC,IAAI,GAAE,YAAiB,GAAG,aAAa,CAK3D;AAED,wBAAgB,MAAM,CAAC,KAAK,EAAE,aAAa,EAAE,GAAG,EAAE,WAAW,GAAG,CAAC,aAAa,EAAE,KAAK,EAAE,CAAC,CAmBvF;AAED,0DAA0D;AAC1D,wBAAgB,SAAS,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAGvD;AAED,sEAAsE;AACtE,wBAAgB,SAAS,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAEvD;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAEzD;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE;QACJ,YAAY,EAAE,UAAU,CAAA;QACxB,WAAW,EAAE,MAAM,CAAA;QACnB,YAAY,EAAE,MAAM,CAAC,cAAc,CAAC,CAAA;QACpC,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,CAAA;QACvB,cAAc,EAAE,CAAC,CAAC,EAAE,cAAc,KAAK,IAAI,CAAA;QAC3C,eAAe,EAAE,CAAC,CAAC,EAAE,eAAe,KAAK,IAAI,CAAA;KAC9C,CAAA;CACF;AAED;iFACiF;AACjF,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,aAAa,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,GAAG,aAAa,CAY5F;AAED,eAAO,MAAM,QAAQ;;;;;;;CAA+D,CAAA"}
@@ -41,14 +41,16 @@ export function isVisible(state) {
41
41
  export function isAnimating(state) {
42
42
  return state.status === 'opening' || state.status === 'closing';
43
43
  }
44
- export function connect(get, send) {
44
+ /** Signal-surface connect: takes the component's `presence` state slice as a
45
+ * Signal and returns reactive (handle-based) props for spreading into a view. */
46
+ export function connect(state, send) {
45
47
  const onEnd = () => send({ type: 'animationEnd' });
46
48
  return {
47
49
  root: {
48
50
  'data-scope': 'presence',
49
51
  'data-part': 'root',
50
- 'data-state': (s) => get(s).status,
51
- hidden: (s) => (get(s).status === 'closed' && !get(s).unmountOnExit ? true : false),
52
+ 'data-state': state.map((s) => s.status),
53
+ hidden: state.map((s) => s.status === 'closed' && !s.unmountOnExit),
52
54
  onAnimationEnd: onEnd,
53
55
  onTransitionEnd: onEnd,
54
56
  },
@@ -1 +1 @@
1
- {"version":3,"file":"presence.js","sourceRoot":"","sources":["../../src/components/presence.ts"],"names":[],"mappings":"AAiDA,MAAM,UAAU,IAAI,CAAC,OAAqB,EAAE;IAC1C,OAAO;QACL,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ;QACxC,aAAa,EAAE,IAAI,CAAC,aAAa,IAAI,IAAI;KAC1C,CAAA;AACH,CAAC;AAED,MAAM,UAAU,MAAM,CAAC,KAAoB,EAAE,GAAgB;IAC3D,QAAQ,GAAG,CAAC,IAAI,EAAE,CAAC;QACjB,KAAK,MAAM;YACT,IAAI,KAAK,CAAC,MAAM,KAAK,MAAM,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS;gBAAE,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA;YAC7E,OAAO,CAAC,EAAE,GAAG,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,CAAA;QAC9C,KAAK,OAAO;YACV,IAAI,KAAK,CAAC,MAAM,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS;gBAAE,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA;YAC/E,OAAO,CAAC,EAAE,GAAG,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,CAAA;QAC9C,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,KAAK,MAAM,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,CAAA;YACrE,OAAO,MAAM,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAA;QAC5D,CAAC;QACD,KAAK,cAAc;YACjB,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS;gBAAE,OAAO,CAAC,EAAE,GAAG,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAA;YACzE,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS;gBAAE,OAAO,CAAC,EAAE,GAAG,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAA;YAC3E,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA;QACpB,KAAK,YAAY;YACf,OAAO,CAAC,EAAE,GAAG,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAA;IACtE,CAAC;AACH,CAAC;AAED,0DAA0D;AAC1D,MAAM,UAAU,SAAS,CAAC,KAAoB;IAC5C,IAAI,CAAC,KAAK,CAAC,aAAa;QAAE,OAAO,IAAI,CAAA;IACrC,OAAO,KAAK,CAAC,MAAM,KAAK,QAAQ,CAAA;AAClC,CAAC;AAED,sEAAsE;AACtE,MAAM,UAAU,SAAS,CAAC,KAAoB;IAC5C,OAAO,KAAK,CAAC,MAAM,KAAK,MAAM,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,CAAA;AAC9D,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAoB;IAC9C,OAAO,KAAK,CAAC,MAAM,KAAK,SAAS,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,CAAA;AACjE,CAAC;AAaD,MAAM,UAAU,OAAO,CACrB,GAA4B,EAC5B,IAAuB;IAEvB,MAAM,KAAK,GAAG,GAAS,EAAE,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC,CAAA;IACxD,OAAO;QACL,IAAI,EAAE;YACJ,YAAY,EAAE,UAAU;YACxB,WAAW,EAAE,MAAM;YACnB,YAAY,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM;YAClC,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,QAAQ,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC;YACnF,cAAc,EAAE,KAAK;YACrB,eAAe,EAAE,KAAK;SACvB;KACF,CAAA;AACH,CAAC;AAED,MAAM,CAAC,MAAM,QAAQ,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,CAAA","sourcesContent":["import type { Send } from '@llui/dom'\n\n/**\n * Presence — track mount/unmount lifecycle with exit-delay support.\n *\n * In many components (dialogs, tooltips, menus) the consumer wants to:\n * 1. close the overlay (fire exit animation)\n * 2. keep it mounted long enough for the animation to finish\n * 3. unmount it\n *\n * LLui already provides `@llui/transitions` for most of this, but a\n * presence machine is useful when you want to coordinate multiple\n * elements or expose state outside the transition primitive.\n *\n * State flow:\n * closed → (open) → opening → open\n * open → (close) → closing → closed\n *\n * The consumer fires `animationEnd` to advance past opening/closing.\n * If `unmountOnExit` is true, `closed` means \"safe to remove from DOM\";\n * otherwise the element stays mounted even when closed (display:none).\n */\n\nexport type PresenceStatus = 'closed' | 'opening' | 'open' | 'closing'\n\nexport interface PresenceState {\n status: PresenceStatus\n unmountOnExit: boolean\n}\n\nexport type PresenceMsg =\n /** @intent(\"Begin opening the element (closed → opening, plays enter animation)\") */\n | { type: 'open' }\n /** @intent(\"Begin closing the element (open → closing, plays exit animation)\") */\n | { type: 'close' }\n /** @intent(\"Toggle between open and closed states\") */\n | { type: 'toggle' }\n /** @humanOnly */\n | { type: 'animationEnd' }\n /** @intent(\"Set the desired presence directly (true = open, false = closed)\") */\n | { type: 'setPresent'; present: boolean }\n\nexport interface PresenceInit {\n /** Initial presence — true starts in 'open', false starts in 'closed'. */\n present?: boolean\n /** Whether 'closed' means \"unmount\" (true) or \"hidden but mounted\" (false). Default: true. */\n unmountOnExit?: boolean\n}\n\nexport function init(opts: PresenceInit = {}): PresenceState {\n return {\n status: opts.present ? 'open' : 'closed',\n unmountOnExit: opts.unmountOnExit ?? true,\n }\n}\n\nexport function update(state: PresenceState, msg: PresenceMsg): [PresenceState, never[]] {\n switch (msg.type) {\n case 'open':\n if (state.status === 'open' || state.status === 'opening') return [state, []]\n return [{ ...state, status: 'opening' }, []]\n case 'close':\n if (state.status === 'closed' || state.status === 'closing') return [state, []]\n return [{ ...state, status: 'closing' }, []]\n case 'toggle': {\n const present = state.status === 'open' || state.status === 'opening'\n return update(state, { type: present ? 'close' : 'open' })\n }\n case 'animationEnd':\n if (state.status === 'opening') return [{ ...state, status: 'open' }, []]\n if (state.status === 'closing') return [{ ...state, status: 'closed' }, []]\n return [state, []]\n case 'setPresent':\n return [{ ...state, status: msg.present ? 'open' : 'closed' }, []]\n }\n}\n\n/** Whether the element should be in the DOM (mounted). */\nexport function isMounted(state: PresenceState): boolean {\n if (!state.unmountOnExit) return true\n return state.status !== 'closed'\n}\n\n/** Whether the element is visible (not running an exit animation). */\nexport function isVisible(state: PresenceState): boolean {\n return state.status === 'open' || state.status === 'opening'\n}\n\nexport function isAnimating(state: PresenceState): boolean {\n return state.status === 'opening' || state.status === 'closing'\n}\n\nexport interface PresenceParts<S> {\n root: {\n 'data-scope': 'presence'\n 'data-part': 'root'\n 'data-state': (s: S) => PresenceStatus\n hidden: (s: S) => boolean\n onAnimationEnd: (e: AnimationEvent) => void\n onTransitionEnd: (e: TransitionEvent) => void\n }\n}\n\nexport function connect<S>(\n get: (s: S) => PresenceState,\n send: Send<PresenceMsg>,\n): PresenceParts<S> {\n const onEnd = (): void => send({ type: 'animationEnd' })\n return {\n root: {\n 'data-scope': 'presence',\n 'data-part': 'root',\n 'data-state': (s) => get(s).status,\n hidden: (s) => (get(s).status === 'closed' && !get(s).unmountOnExit ? true : false),\n onAnimationEnd: onEnd,\n onTransitionEnd: onEnd,\n },\n }\n}\n\nexport const presence = { init, update, connect, isMounted, isVisible, isAnimating }\n"]}
1
+ {"version":3,"file":"presence.js","sourceRoot":"","sources":["../../src/components/presence.ts"],"names":[],"mappings":"AAiDA,MAAM,UAAU,IAAI,CAAC,OAAqB,EAAE;IAC1C,OAAO;QACL,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ;QACxC,aAAa,EAAE,IAAI,CAAC,aAAa,IAAI,IAAI;KAC1C,CAAA;AACH,CAAC;AAED,MAAM,UAAU,MAAM,CAAC,KAAoB,EAAE,GAAgB;IAC3D,QAAQ,GAAG,CAAC,IAAI,EAAE,CAAC;QACjB,KAAK,MAAM;YACT,IAAI,KAAK,CAAC,MAAM,KAAK,MAAM,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS;gBAAE,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA;YAC7E,OAAO,CAAC,EAAE,GAAG,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,CAAA;QAC9C,KAAK,OAAO;YACV,IAAI,KAAK,CAAC,MAAM,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS;gBAAE,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA;YAC/E,OAAO,CAAC,EAAE,GAAG,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,CAAA;QAC9C,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,KAAK,MAAM,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,CAAA;YACrE,OAAO,MAAM,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAA;QAC5D,CAAC;QACD,KAAK,cAAc;YACjB,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS;gBAAE,OAAO,CAAC,EAAE,GAAG,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAA;YACzE,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS;gBAAE,OAAO,CAAC,EAAE,GAAG,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAA;YAC3E,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA;QACpB,KAAK,YAAY;YACf,OAAO,CAAC,EAAE,GAAG,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAA;IACtE,CAAC;AACH,CAAC;AAED,0DAA0D;AAC1D,MAAM,UAAU,SAAS,CAAC,KAAoB;IAC5C,IAAI,CAAC,KAAK,CAAC,aAAa;QAAE,OAAO,IAAI,CAAA;IACrC,OAAO,KAAK,CAAC,MAAM,KAAK,QAAQ,CAAA;AAClC,CAAC;AAED,sEAAsE;AACtE,MAAM,UAAU,SAAS,CAAC,KAAoB;IAC5C,OAAO,KAAK,CAAC,MAAM,KAAK,MAAM,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,CAAA;AAC9D,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAoB;IAC9C,OAAO,KAAK,CAAC,MAAM,KAAK,SAAS,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,CAAA;AACjE,CAAC;AAaD;iFACiF;AACjF,MAAM,UAAU,OAAO,CAAC,KAA4B,EAAE,IAAuB;IAC3E,MAAM,KAAK,GAAG,GAAS,EAAE,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC,CAAA;IACxD,OAAO;QACL,IAAI,EAAE;YACJ,YAAY,EAAE,UAAU;YACxB,WAAW,EAAE,MAAM;YACnB,YAAY,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;YACxC,MAAM,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,QAAQ,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC;YACnE,cAAc,EAAE,KAAK;YACrB,eAAe,EAAE,KAAK;SACvB;KACF,CAAA;AACH,CAAC;AAED,MAAM,CAAC,MAAM,QAAQ,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,CAAA","sourcesContent":["import type { Send, Signal } from '@llui/dom'\n\n/**\n * Presence — track mount/unmount lifecycle with exit-delay support.\n *\n * In many components (dialogs, tooltips, menus) the consumer wants to:\n * 1. close the overlay (fire exit animation)\n * 2. keep it mounted long enough for the animation to finish\n * 3. unmount it\n *\n * LLui already provides `@llui/transitions` for most of this, but a\n * presence machine is useful when you want to coordinate multiple\n * elements or expose state outside the transition primitive.\n *\n * State flow:\n * closed → (open) → opening → open\n * open → (close) → closing → closed\n *\n * The consumer fires `animationEnd` to advance past opening/closing.\n * If `unmountOnExit` is true, `closed` means \"safe to remove from DOM\";\n * otherwise the element stays mounted even when closed (display:none).\n */\n\nexport type PresenceStatus = 'closed' | 'opening' | 'open' | 'closing'\n\nexport interface PresenceState {\n status: PresenceStatus\n unmountOnExit: boolean\n}\n\nexport type PresenceMsg =\n /** @intent(\"Begin opening the element (closed → opening, plays enter animation)\") */\n | { type: 'open' }\n /** @intent(\"Begin closing the element (open → closing, plays exit animation)\") */\n | { type: 'close' }\n /** @intent(\"Toggle between open and closed states\") */\n | { type: 'toggle' }\n /** @humanOnly */\n | { type: 'animationEnd' }\n /** @intent(\"Set the desired presence directly (true = open, false = closed)\") */\n | { type: 'setPresent'; present: boolean }\n\nexport interface PresenceInit {\n /** Initial presence — true starts in 'open', false starts in 'closed'. */\n present?: boolean\n /** Whether 'closed' means \"unmount\" (true) or \"hidden but mounted\" (false). Default: true. */\n unmountOnExit?: boolean\n}\n\nexport function init(opts: PresenceInit = {}): PresenceState {\n return {\n status: opts.present ? 'open' : 'closed',\n unmountOnExit: opts.unmountOnExit ?? true,\n }\n}\n\nexport function update(state: PresenceState, msg: PresenceMsg): [PresenceState, never[]] {\n switch (msg.type) {\n case 'open':\n if (state.status === 'open' || state.status === 'opening') return [state, []]\n return [{ ...state, status: 'opening' }, []]\n case 'close':\n if (state.status === 'closed' || state.status === 'closing') return [state, []]\n return [{ ...state, status: 'closing' }, []]\n case 'toggle': {\n const present = state.status === 'open' || state.status === 'opening'\n return update(state, { type: present ? 'close' : 'open' })\n }\n case 'animationEnd':\n if (state.status === 'opening') return [{ ...state, status: 'open' }, []]\n if (state.status === 'closing') return [{ ...state, status: 'closed' }, []]\n return [state, []]\n case 'setPresent':\n return [{ ...state, status: msg.present ? 'open' : 'closed' }, []]\n }\n}\n\n/** Whether the element should be in the DOM (mounted). */\nexport function isMounted(state: PresenceState): boolean {\n if (!state.unmountOnExit) return true\n return state.status !== 'closed'\n}\n\n/** Whether the element is visible (not running an exit animation). */\nexport function isVisible(state: PresenceState): boolean {\n return state.status === 'open' || state.status === 'opening'\n}\n\nexport function isAnimating(state: PresenceState): boolean {\n return state.status === 'opening' || state.status === 'closing'\n}\n\nexport interface PresenceParts {\n root: {\n 'data-scope': 'presence'\n 'data-part': 'root'\n 'data-state': Signal<PresenceStatus>\n hidden: Signal<boolean>\n onAnimationEnd: (e: AnimationEvent) => void\n onTransitionEnd: (e: TransitionEvent) => void\n }\n}\n\n/** Signal-surface connect: takes the component's `presence` state slice as a\n * Signal and returns reactive (handle-based) props for spreading into a view. */\nexport function connect(state: Signal<PresenceState>, send: Send<PresenceMsg>): PresenceParts {\n const onEnd = (): void => send({ type: 'animationEnd' })\n return {\n root: {\n 'data-scope': 'presence',\n 'data-part': 'root',\n 'data-state': state.map((s) => s.status),\n hidden: state.map((s) => s.status === 'closed' && !s.unmountOnExit),\n onAnimationEnd: onEnd,\n onTransitionEnd: onEnd,\n },\n }\n}\n\nexport const presence = { init, update, connect, isMounted, isVisible, isAnimating }\n"]}