@fusion.dev/helix-headless 0.142.1 → 0.144.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (285) hide show
  1. package/custom-elements.json +25381 -1202
  2. package/dist/accordion/item/accordion-item.d.ts +38 -2
  3. package/dist/accordion/item/accordion-item.js +38 -6
  4. package/dist/accordion/root/accordion-root.d.ts +23 -1
  5. package/dist/accordion/root/accordion-root.js +39 -3
  6. package/dist/announcement/root/announcement-root.d.ts +11 -7
  7. package/dist/announcement/root/announcement-root.js +1 -1
  8. package/dist/app-header/root/app-header-root.d.ts +21 -0
  9. package/dist/app-header/root/app-header-root.js +31 -5
  10. package/dist/area-chart/root/area-chart-root.d.ts +12 -4
  11. package/dist/area-chart/root/area-chart-root.js +39 -11
  12. package/dist/avatar/group/avatar-group.d.ts +24 -3
  13. package/dist/avatar/group/avatar-group.js +34 -2
  14. package/dist/avatar/root/avatar-root.d.ts +17 -1
  15. package/dist/avatar/root/avatar-root.js +31 -10
  16. package/dist/badge/root/badge-root.d.ts +12 -0
  17. package/dist/badge/root/badge-root.js +1 -1
  18. package/dist/bar-chart/root/bar-chart-root.d.ts +30 -5
  19. package/dist/bar-chart/root/bar-chart-root.js +58 -21
  20. package/dist/blockquote/root/blockquote-root.d.ts +12 -7
  21. package/dist/blockquote/root/blockquote-root.js +6 -4
  22. package/dist/breadcrumbs/root/breadcrumbs-root.d.ts +9 -3
  23. package/dist/breadcrumbs/root/breadcrumbs-root.js +9 -1
  24. package/dist/button/root/button-root.d.ts +84 -1
  25. package/dist/button/root/button-root.js +81 -3
  26. package/dist/callout/root/callout-root.d.ts +32 -6
  27. package/dist/callout/root/callout-root.js +26 -7
  28. package/dist/canvas/root/canvas-root.d.ts +1 -0
  29. package/dist/canvas/root/canvas-root.js +10 -1
  30. package/dist/card/root/card-root.d.ts +30 -1
  31. package/dist/card/root/card-root.js +38 -5
  32. package/dist/carousel/root/carousel-root.d.ts +47 -5
  33. package/dist/carousel/root/carousel-root.js +53 -21
  34. package/dist/chat/composer/chat-composer.d.ts +13 -11
  35. package/dist/chat/composer/chat-composer.js +6 -12
  36. package/dist/chat/message/chat-message.js +8 -1
  37. package/dist/chat/root/chat-root.d.ts +1 -0
  38. package/dist/chat/root/chat-root.js +2 -1
  39. package/dist/checkbox/root/checkbox-root.d.ts +7 -0
  40. package/dist/checkbox/root/checkbox-root.js +9 -3
  41. package/dist/checkbox-group/root/checkbox-group-root.d.ts +116 -33
  42. package/dist/checkbox-group/root/checkbox-group-root.js +141 -44
  43. package/dist/code/root/code-root.d.ts +1 -1
  44. package/dist/code-block/lines.d.ts +13 -0
  45. package/dist/code-block/lines.js +2 -0
  46. package/dist/code-block/root/code-block-root.d.ts +49 -0
  47. package/dist/code-block/root/code-block-root.js +44 -3
  48. package/dist/color-input/root/color-input-root.d.ts +60 -2
  49. package/dist/color-input/root/color-input-root.js +55 -7
  50. package/dist/color-picker/channels.d.ts +26 -0
  51. package/dist/color-picker/channels.js +84 -0
  52. package/dist/color-picker/root/color-picker-root.d.ts +118 -12
  53. package/dist/color-picker/root/color-picker-root.js +183 -13
  54. package/dist/combobox/root/combobox-root.d.ts +126 -3
  55. package/dist/combobox/root/combobox-root.js +224 -21
  56. package/dist/command/root/command-root.d.ts +47 -10
  57. package/dist/command/root/command-root.js +45 -4
  58. package/dist/copy-button/from.d.ts +22 -0
  59. package/dist/copy-button/from.js +28 -0
  60. package/dist/copy-button/root/copy-button-root.d.ts +48 -7
  61. package/dist/copy-button/root/copy-button-root.js +54 -8
  62. package/dist/data-table/root/data-table-root.d.ts +164 -10
  63. package/dist/data-table/root/data-table-root.js +488 -57
  64. package/dist/date-input/root/date-input-root.d.ts +123 -9
  65. package/dist/date-input/root/date-input-root.js +147 -45
  66. package/dist/date-picker/root/date-picker-root.d.ts +229 -18
  67. package/dist/date-picker/root/date-picker-root.js +342 -46
  68. package/dist/dialog/description.d.ts +9 -0
  69. package/dist/dialog/description.js +14 -0
  70. package/dist/dialog/root/dialog-root.d.ts +101 -10
  71. package/dist/dialog/root/dialog-root.js +83 -4
  72. package/dist/donut-chart/root/donut-chart-root.d.ts +61 -16
  73. package/dist/donut-chart/root/donut-chart-root.js +48 -13
  74. package/dist/drawer/root/drawer-root.d.ts +93 -7
  75. package/dist/drawer/root/drawer-root.js +126 -5
  76. package/dist/drawer/swipe-start.d.ts +9 -0
  77. package/dist/drawer/swipe-start.js +12 -0
  78. package/dist/drilldown/item/drilldown-item.d.ts +16 -13
  79. package/dist/drilldown/item/drilldown-item.js +6 -2
  80. package/dist/drilldown/root/drilldown-root.d.ts +21 -5
  81. package/dist/drilldown/root/drilldown-root.js +26 -10
  82. package/dist/element-events.generated.js +42 -13
  83. package/dist/empty/root/empty-root.d.ts +1 -1
  84. package/dist/file-input/root/file-input-root.d.ts +65 -1
  85. package/dist/file-input/root/file-input-root.js +76 -12
  86. package/dist/file-input/screen.d.ts +35 -0
  87. package/dist/file-input/screen.js +49 -0
  88. package/dist/filter-input/menu/filter-menu.d.ts +9 -0
  89. package/dist/filter-input/menu/filter-menu.js +8 -0
  90. package/dist/filter-input/root/filter-input-root.d.ts +43 -6
  91. package/dist/filter-input/root/filter-input-root.js +89 -10
  92. package/dist/filter-input/suggest.d.ts +17 -0
  93. package/dist/filter-input/suggest.js +23 -0
  94. package/dist/format-date/options.d.ts +33 -0
  95. package/dist/format-date/options.js +42 -0
  96. package/dist/format-date/root/format-date-root.d.ts +62 -3
  97. package/dist/format-date/root/format-date-root.js +78 -37
  98. package/dist/graph/root/graph-root.d.ts +24 -3
  99. package/dist/graph/root/graph-root.js +66 -12
  100. package/dist/heatmap/root/buckets.d.ts +2 -1
  101. package/dist/heatmap/root/buckets.js +5 -1
  102. package/dist/heatmap/root/heatmap-root.d.ts +47 -9
  103. package/dist/heatmap/root/heatmap-root.js +46 -18
  104. package/dist/icon/index.d.ts +2 -0
  105. package/dist/icon/index.js +2 -0
  106. package/dist/icon/registry.d.ts +37 -0
  107. package/dist/icon/registry.js +83 -0
  108. package/dist/icon/root/icon-root.d.ts +53 -6
  109. package/dist/icon/root/icon-root.js +72 -4
  110. package/dist/icon/root/index.d.ts +2 -0
  111. package/dist/icon/root/index.js +2 -0
  112. package/dist/icon/set.d.ts +1 -0
  113. package/dist/icon/set.js +3 -0
  114. package/dist/icon-button/root/icon-button-root.d.ts +1 -1
  115. package/dist/image/root/image-root.d.ts +23 -2
  116. package/dist/image/root/image-root.js +23 -4
  117. package/dist/input/root/input-root.d.ts +62 -9
  118. package/dist/input/root/input-root.js +61 -5
  119. package/dist/kbd/root/kbd-root.d.ts +26 -11
  120. package/dist/kbd/root/kbd-root.js +35 -38
  121. package/dist/kbd/shortcut.d.ts +18 -0
  122. package/dist/kbd/shortcut.js +35 -0
  123. package/dist/legend/hidden-series.d.ts +8 -0
  124. package/dist/legend/hidden-series.js +13 -0
  125. package/dist/legend/root/legend-root.d.ts +63 -0
  126. package/dist/legend/root/legend-root.js +61 -7
  127. package/dist/lightbox/item/lightbox-item.d.ts +17 -1
  128. package/dist/lightbox/item/lightbox-item.js +10 -1
  129. package/dist/lightbox/root/lightbox-root.d.ts +77 -6
  130. package/dist/lightbox/root/lightbox-root.js +116 -5
  131. package/dist/line-chart/root/line-chart-root.d.ts +29 -4
  132. package/dist/line-chart/root/line-chart-root.js +58 -17
  133. package/dist/list/item/list-item.d.ts +11 -5
  134. package/dist/list/item/list-item.js +5 -6
  135. package/dist/listbox/range.d.ts +17 -0
  136. package/dist/listbox/range.js +5 -0
  137. package/dist/listbox/root/listbox-root.d.ts +184 -4
  138. package/dist/listbox/root/listbox-root.js +229 -23
  139. package/dist/loader/busy.d.ts +17 -0
  140. package/dist/loader/busy.js +24 -0
  141. package/dist/loader/root/loader-root.d.ts +37 -0
  142. package/dist/loader/root/loader-root.js +52 -3
  143. package/dist/map/root/map-root.d.ts +19 -4
  144. package/dist/map/root/map-root.js +36 -7
  145. package/dist/megamenu/root/megamenu-root.d.ts +10 -1
  146. package/dist/megamenu/root/megamenu-root.js +10 -1
  147. package/dist/menu/item/menu-item.d.ts +41 -12
  148. package/dist/menu/item/menu-item.js +46 -3
  149. package/dist/menu/root/menu-root.d.ts +32 -2
  150. package/dist/menu/root/menu-root.js +48 -8
  151. package/dist/meter/root/meter-root.d.ts +13 -0
  152. package/dist/meter/root/meter-root.js +24 -5
  153. package/dist/navigation/root/navigation-root.d.ts +10 -2
  154. package/dist/navigation/root/navigation-root.js +13 -2
  155. package/dist/notifications/feed-keys.d.ts +10 -0
  156. package/dist/notifications/feed-keys.js +14 -0
  157. package/dist/notifications/group/notification-group.d.ts +1 -0
  158. package/dist/notifications/notification/notification.d.ts +29 -0
  159. package/dist/notifications/notification/notification.js +51 -3
  160. package/dist/notifications/root/notifications-root.d.ts +49 -0
  161. package/dist/notifications/root/notifications-root.js +76 -2
  162. package/dist/number-input/root/number-input-root.d.ts +109 -7
  163. package/dist/number-input/root/number-input-root.js +109 -21
  164. package/dist/object-inspector/root/object-inspector-root.d.ts +49 -5
  165. package/dist/object-inspector/root/object-inspector-root.js +92 -12
  166. package/dist/option/root/option-root.d.ts +58 -6
  167. package/dist/option/root/option-root.js +35 -5
  168. package/dist/outline/root/outline-root.d.ts +13 -2
  169. package/dist/outline/root/outline-root.js +4 -2
  170. package/dist/pagination/root/pagination-root.d.ts +19 -1
  171. package/dist/pagination/root/pagination-root.js +49 -9
  172. package/dist/pagination/size/pagination-size.d.ts +13 -3
  173. package/dist/pagination/size/pagination-size.js +7 -0
  174. package/dist/pin-input/format.d.ts +7 -0
  175. package/dist/pin-input/format.js +16 -0
  176. package/dist/pin-input/root/pin-input-root.d.ts +37 -0
  177. package/dist/pin-input/root/pin-input-root.js +48 -7
  178. package/dist/popover/root/popover-root.d.ts +78 -3
  179. package/dist/popover/root/popover-root.js +74 -5
  180. package/dist/progress/root/progress-root.d.ts +23 -1
  181. package/dist/progress/root/progress-root.js +40 -10
  182. package/dist/qr-code/export.d.ts +31 -0
  183. package/dist/qr-code/export.js +10 -0
  184. package/dist/qr-code/root/qr-code-root.d.ts +45 -0
  185. package/dist/qr-code/root/qr-code-root.js +78 -3
  186. package/dist/radio/group/radio-group.d.ts +64 -0
  187. package/dist/radio/group/radio-group.js +66 -12
  188. package/dist/radio/root/radio-root.d.ts +8 -5
  189. package/dist/radio/root/radio-root.js +1 -2
  190. package/dist/rating/root/rating-root.d.ts +49 -1
  191. package/dist/rating/root/rating-root.js +69 -10
  192. package/dist/scatter-chart/root/scatter-chart-root.d.ts +17 -3
  193. package/dist/scatter-chart/root/scatter-chart-root.js +40 -14
  194. package/dist/select/root/select-root.d.ts +93 -3
  195. package/dist/select/root/select-root.js +111 -13
  196. package/dist/skeleton/root/skeleton-root.d.ts +39 -3
  197. package/dist/skeleton/root/skeleton-root.js +33 -4
  198. package/dist/skip-link/root/skip-link-root.d.ts +10 -0
  199. package/dist/skip-link/root/skip-link-root.js +15 -1
  200. package/dist/slider/root/slider-root.d.ts +59 -2
  201. package/dist/slider/root/slider-root.js +82 -8
  202. package/dist/sparkline/root/sparkline-root.d.ts +9 -10
  203. package/dist/speed-dial/item/speed-dial-item.d.ts +11 -5
  204. package/dist/speed-dial/item/speed-dial-item.js +7 -2
  205. package/dist/speed-dial/root/speed-dial-root.d.ts +15 -4
  206. package/dist/speed-dial/root/speed-dial-root.js +19 -5
  207. package/dist/splitter/root/splitter-root.d.ts +28 -6
  208. package/dist/splitter/root/splitter-root.js +35 -1
  209. package/dist/stat/root/stat-root.d.ts +9 -1
  210. package/dist/stat/root/stat-root.js +15 -2
  211. package/dist/steps/root/steps-root.js +1 -1
  212. package/dist/steps/step/step.d.ts +1 -0
  213. package/dist/steps/step/step.js +1 -1
  214. package/dist/switch/root/switch-root.d.ts +14 -2
  215. package/dist/switch/root/switch-root.js +7 -1
  216. package/dist/table/cell/table-cell.d.ts +24 -4
  217. package/dist/table/cell/table-cell.js +21 -1
  218. package/dist/table/column/table-column.d.ts +32 -6
  219. package/dist/table/column/table-column.js +36 -6
  220. package/dist/table/root/table-root.d.ts +94 -3
  221. package/dist/table/root/table-root.js +128 -5
  222. package/dist/table/row/table-row.d.ts +7 -0
  223. package/dist/table/row/table-row.js +9 -1
  224. package/dist/tabs/root/tabs-root.d.ts +6 -1
  225. package/dist/tabs/root/tabs-root.js +6 -2
  226. package/dist/tag/group/tag-group.d.ts +107 -0
  227. package/dist/tag/group/tag-group.js +157 -0
  228. package/dist/tag/index.d.ts +1 -0
  229. package/dist/tag/index.js +1 -0
  230. package/dist/tag/root/tag-root.d.ts +83 -1
  231. package/dist/tag/root/tag-root.js +87 -17
  232. package/dist/tag/selection.d.ts +10 -0
  233. package/dist/tag/selection.js +12 -0
  234. package/dist/textarea/grow.d.ts +22 -0
  235. package/dist/textarea/grow.js +20 -0
  236. package/dist/textarea/root/textarea-root.d.ts +13 -0
  237. package/dist/textarea/root/textarea-root.js +10 -2
  238. package/dist/time-input/root/time-input-root.d.ts +71 -6
  239. package/dist/time-input/root/time-input-root.js +110 -44
  240. package/dist/time-picker/root/time-picker-root.d.ts +155 -26
  241. package/dist/time-picker/root/time-picker-root.js +192 -63
  242. package/dist/toast/hotkey.d.ts +22 -0
  243. package/dist/toast/hotkey.js +23 -0
  244. package/dist/toast/item/toast-item.d.ts +16 -1
  245. package/dist/toast/item/toast-item.js +41 -13
  246. package/dist/toast/root/toast-root.d.ts +105 -8
  247. package/dist/toast/root/toast-root.js +209 -4
  248. package/dist/toggle/group/toggle-group.d.ts +95 -16
  249. package/dist/toggle/group/toggle-group.js +99 -13
  250. package/dist/toggle/root/toggle-root.d.ts +26 -11
  251. package/dist/toggle/root/toggle-root.js +14 -6
  252. package/dist/toolbar/root/toolbar-root.d.ts +55 -15
  253. package/dist/toolbar/root/toolbar-root.js +99 -16
  254. package/dist/tooltip/focus-target.d.ts +6 -0
  255. package/dist/tooltip/focus-target.js +9 -0
  256. package/dist/tooltip/root/tooltip-root.d.ts +73 -15
  257. package/dist/tooltip/root/tooltip-root.js +96 -7
  258. package/dist/tour/naming.d.ts +30 -0
  259. package/dist/tour/naming.js +10 -0
  260. package/dist/tour/root/tour-root.d.ts +67 -3
  261. package/dist/tour/root/tour-root.js +105 -17
  262. package/dist/tour/stop/tour-stop.d.ts +65 -3
  263. package/dist/tour/stop/tour-stop.js +61 -11
  264. package/dist/tour/wait.d.ts +11 -0
  265. package/dist/tour/wait.js +19 -0
  266. package/dist/tree/item/tree-item.d.ts +21 -5
  267. package/dist/tree/item/tree-item.js +14 -4
  268. package/dist/tree/root/tree-root.d.ts +29 -5
  269. package/dist/tree/root/tree-root.js +64 -8
  270. package/dist/trend/root/trend-root.d.ts +36 -1
  271. package/dist/trend/root/trend-root.js +41 -15
  272. package/dist/video/root/keys.d.ts +5 -0
  273. package/dist/video/root/keys.js +13 -1
  274. package/dist/video/root/video-root.d.ts +19 -0
  275. package/dist/video/root/video-root.js +48 -4
  276. package/dist/video-playlist/menu/video-playlist-menu.d.ts +20 -2
  277. package/dist/video-playlist/menu/video-playlist-menu.js +27 -5
  278. package/dist/video-playlist/root/video-playlist-root.js +6 -3
  279. package/dist/virtual-list/root/virtual-list-root.d.ts +52 -4
  280. package/dist/virtual-list/root/virtual-list-root.js +103 -21
  281. package/lint.json +1 -1
  282. package/package.json +5 -5
  283. package/types/jsx.d.ts +9140 -1149
  284. package/types/svelte.d.ts +1 -0
  285. package/types/vue.d.ts +2089 -267
@@ -4,7 +4,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
4
4
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
- import { customElement, HelixElement, HelixSelectEvent } from '@fusion.dev/helix-core';
7
+ import { customElement, followLink, HelixElement, HelixSelectEvent, } from '@fusion.dev/helix-core';
8
8
  import { html, nothing } from 'lit';
9
9
  import { property } from 'lit/decorators.js';
10
10
  export const optionsAmong = (elements) => {
@@ -18,8 +18,13 @@ let HelixHeadlessOption = class HelixHeadlessOption extends HelixElement {
18
18
  this.alternate = '';
19
19
  this.alternateLabel = '';
20
20
  this.disabled = false;
21
+ this.download = false;
22
+ this.href = '';
21
23
  this.label = '';
24
+ this.rel = '';
22
25
  this.selected = false;
26
+ this.target = '';
27
+ this.textValue = '';
23
28
  this.value = '';
24
29
  }
25
30
  get defaultSelected() {
@@ -29,31 +34,41 @@ let HelixHeadlessOption = class HelixHeadlessOption extends HelixElement {
29
34
  this.toggleAttribute('selected', next);
30
35
  }
31
36
  get text() {
37
+ if (this.textValue !== '') {
38
+ return this.textValue;
39
+ }
32
40
  return ([...this.childNodes]
33
41
  .filter((node) => node.nodeType === Node.TEXT_NODE || (node instanceof Element && node.slot === ''))
34
42
  .map((node) => node.textContent ?? '')
35
43
  .join('')
36
44
  .trim() || this.label);
37
45
  }
38
- select() {
46
+ select(modifiers) {
39
47
  if (this.disabled) {
40
48
  return;
41
49
  }
42
- this.dispatchEvent(new HelixSelectEvent({ value: this.value }));
50
+ if (this.href === '') {
51
+ this.dispatchEvent(new HelixSelectEvent({ value: this.value }));
52
+ return;
53
+ }
54
+ if (this.dispatchEvent(new HelixSelectEvent({ href: this.href, value: this.value }))) {
55
+ followLink(this.ownerDocument, this, modifiers);
56
+ }
43
57
  }
44
58
  willUpdate(changed) {
45
59
  super.willUpdate(changed);
46
60
  this.toggleState('selected', this.selected);
61
+ this.toggleState('active', this.active);
47
62
  }
48
63
  render() {
49
64
  this.internals.role = 'option';
50
- this.internals.ariaSelected = String(this.selected);
65
+ this.internals.ariaSelected = this.href === '' ? String(this.selected) : null;
51
66
  this.internals.ariaDisabled = this.disabled ? 'true' : null;
52
67
  this.internals.ariaDescription =
53
68
  this.alternate !== '' && this.alternateLabel !== '' ? this.alternateLabel : null;
54
69
  return html `<div
55
70
  part="item${this.selected ? ' item-selected' : ''}${this.active ? ' item-active' : ''}"
56
- @click=${() => this.select()}
71
+ @click=${(event) => this.select(event)}
57
72
  >
58
73
  <slot name="start"></slot>
59
74
  <span part="text">
@@ -79,12 +94,27 @@ __decorate([
79
94
  __decorate([
80
95
  property({ reflect: true, type: Boolean })
81
96
  ], HelixHeadlessOption.prototype, "disabled", void 0);
97
+ __decorate([
98
+ property({ type: Boolean })
99
+ ], HelixHeadlessOption.prototype, "download", void 0);
100
+ __decorate([
101
+ property()
102
+ ], HelixHeadlessOption.prototype, "href", void 0);
82
103
  __decorate([
83
104
  property()
84
105
  ], HelixHeadlessOption.prototype, "label", void 0);
106
+ __decorate([
107
+ property()
108
+ ], HelixHeadlessOption.prototype, "rel", void 0);
85
109
  __decorate([
86
110
  property({ type: Boolean })
87
111
  ], HelixHeadlessOption.prototype, "selected", void 0);
112
+ __decorate([
113
+ property()
114
+ ], HelixHeadlessOption.prototype, "target", void 0);
115
+ __decorate([
116
+ property({ attribute: 'text-value' })
117
+ ], HelixHeadlessOption.prototype, "textValue", void 0);
88
118
  __decorate([
89
119
  property()
90
120
  ], HelixHeadlessOption.prototype, "value", void 0);
@@ -11,6 +11,10 @@ import { type PropertyValues, type TemplateResult } from 'lit';
11
11
  * render one inside the outline's shadow root, and the hrefs are fragments on
12
12
  * the same page.
13
13
  *
14
+ * Write the anchors flat, with `data-level` for their depth, or nested in
15
+ * lists, `<ul><li><a>`. A screen reader hears a nested list's levels; it hears
16
+ * `data-level` as a flat run of links.
17
+ *
14
18
  * The current section is decided by the headings' positions. An
15
19
  * `IntersectionObserver` with a band near the top fails both ways: when
16
20
  * headings are far apart, none is in the band and no section is marked, and
@@ -22,7 +26,7 @@ import { type PropertyValues, type TemplateResult } from 'lit';
22
26
  * @aliases Table of contents, On this page, Outline
23
27
  * @documentation https://fusion.dev/helix/components/outline
24
28
  *
25
- * @slot - The links, as anchors with fragment hrefs.
29
+ * @slot - The links, as anchors with fragment hrefs, or lists holding them.
26
30
  *
27
31
  * @event {HelixActivateEvent} helix-activate - Fired when the section in view changes, with its id as the value. It reports the scroll position and cannot be prevented.
28
32
  *
@@ -88,7 +92,14 @@ export declare class HelixHeadlessOutline extends HelixElement {
88
92
  */
89
93
  private reading;
90
94
  private observer;
91
- /** The links, in document order. Empty on the server, which has no tree. */
95
+ /**
96
+ * The links, in document order. Empty on the server, which has no tree.
97
+ *
98
+ * **Anchors inside what is slotted count too.** A contents list is written
99
+ * `<ul><li><a>` more often than as a run of anchors, and reading only the
100
+ * anchors assigned to the slot found no sections in it: nothing was marked,
101
+ * nothing was announced, and nothing said why.
102
+ */
92
103
  private get links();
93
104
  /**
94
105
  * What each link points at, paired with the link, skipping anything missing.
@@ -78,8 +78,10 @@ let HelixHeadlessOutline = class HelixHeadlessOutline extends HelixElement {
78
78
  }
79
79
  get links() {
80
80
  const slot = this.renderRoot?.querySelector('slot');
81
- return (slot?.assignedElements({ flatten: true }) ?? []).filter((element) => element instanceof HTMLAnchorElement &&
82
- element.getAttribute('href')?.startsWith('#') === true);
81
+ const fragment = (element) => element instanceof HTMLAnchorElement && element.getAttribute('href')?.startsWith('#') === true;
82
+ return (slot?.assignedElements({ flatten: true }) ?? []).flatMap((element) => fragment(element)
83
+ ? [element]
84
+ : [...element.querySelectorAll('a[href^="#"]')].filter(fragment));
83
85
  }
84
86
  get sections() {
85
87
  return this.links.flatMap((link) => {
@@ -39,7 +39,8 @@ import { type PropertyValues, type TemplateResult } from 'lit';
39
39
  * @slot next-icon - The glyph on the forward-one-page control, usually a caret.
40
40
  * @slot previous-icon - The glyph on the back-one-page control, usually a caret.
41
41
  *
42
- * @event {HelixNavigateEvent} helix-navigate - Fired before the page changes, and cancelable. Canceling it is the only way to stop a page change.
42
+ * @event {HelixActivateEvent} helix-activate - Fired after the page changes, with the new page as a string in `detail.value`. In `href` mode it comes a task after the click, once the page has moved.
43
+ * @event {HelixNavigateEvent} helix-navigate - Fired before the page changes, and cancelable. Canceling it is the only way to stop a page change. `detail.page` is the page asked for, as a number, and `detail.value` is the same page as a string.
43
44
  *
44
45
  * @csspart first - The control that jumps to the first page, under `ends`.
45
46
  * @csspart gap - The control in place of hidden pages, which jumps into them.
@@ -218,6 +219,11 @@ export declare class HelixHeadlessPagination extends HelixElement {
218
219
  private announced;
219
220
  /** The page on show, whoever set it, and `undefined` until somebody has. */
220
221
  private pageState;
222
+ /**
223
+ * The control a reader just used, while it held focus, and whether it was a
224
+ * gap. Read once by the update that follows, which decides where focus goes.
225
+ */
226
+ private used;
221
227
  /** Held across every component asking for the same locale. */
222
228
  private get numbers();
223
229
  /**
@@ -263,6 +269,18 @@ export declare class HelixHeadlessPagination extends HelixElement {
263
269
  * for both shapes rather than two that have to stay in step.
264
270
  */
265
271
  private readonly go;
272
+ private applyPage;
273
+ /**
274
+ * Puts focus back in the row after the control a reader used has gone.
275
+ *
276
+ * A page keeps its own control across a move, because the run is keyed by
277
+ * page, so focus stays on the page that was chosen. A gap points somewhere
278
+ * new once the run moves, and a step control is disabled at the end it
279
+ * reached, so after either of those focus goes to the current page, or in
280
+ * `compact` to the first step control that can still be used. Left alone,
281
+ * focus fell to the top of the document.
282
+ */
283
+ private restoreFocus;
266
284
  protected willUpdate(changed: PropertyValues): void;
267
285
  /**
268
286
  * Says where the reader now is, once they have moved.
@@ -4,10 +4,11 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
4
4
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
- import { customElement, fillTemplate, formatNumbers, HelixElement, HelixNavigateEvent, hostAria, requestChange, } from '@fusion.dev/helix-core';
7
+ import { customElement, deepActiveElement, fillTemplate, formatNumbers, HelixActivateEvent, HelixElement, HelixNavigateEvent, hostAria, requestChange, } from '@fusion.dev/helix-core';
8
8
  import { caretDoubleLeft, caretDoubleRight, caretLeft, caretRight, } from '@fusion.dev/helix-icons';
9
9
  import { html, nothing } from 'lit';
10
10
  import { property, state } from 'lit/decorators.js';
11
+ import { repeat } from 'lit/directives/repeat.js';
11
12
  import { unsafeSVG } from 'lit/directives/unsafe-svg.js';
12
13
  const fill = (template, page, pages, format = String) => fillTemplate(template, { page: format(page), pages: format(pages) });
13
14
  let HelixHeadlessPagination = class HelixHeadlessPagination extends HelixElement {
@@ -34,9 +35,15 @@ let HelixHeadlessPagination = class HelixHeadlessPagination extends HelixElement
34
35
  this.announcement = '';
35
36
  this.announced = undefined;
36
37
  this.pageState = undefined;
37
- this.go = (next, event) => {
38
+ this.used = undefined;
39
+ this.go = (next, event, gap = false) => {
40
+ const control = event.currentTarget;
38
41
  if (!this.request(next)) {
39
42
  event.preventDefault();
43
+ return;
44
+ }
45
+ if (control && deepActiveElement() === control) {
46
+ this.used = { control, gap };
40
47
  }
41
48
  };
42
49
  }
@@ -104,15 +111,43 @@ let HelixHeadlessPagination = class HelixHeadlessPagination extends HelixElement
104
111
  }
105
112
  return requestChange({
106
113
  apply: (page) => {
107
- const previous = this.page;
108
- this.pageState = page;
109
- this.requestUpdate('page', previous);
114
+ if (this.href) {
115
+ setTimeout(() => this.applyPage(page));
116
+ return;
117
+ }
118
+ this.applyPage(page);
110
119
  },
111
- event: (page) => new HelixNavigateEvent({ value: String(page) }),
120
+ event: (page) => new HelixNavigateEvent({ page, value: String(page) }),
112
121
  host: this,
113
122
  next,
114
123
  });
115
124
  }
125
+ applyPage(page) {
126
+ const previous = this.page;
127
+ this.pageState = page;
128
+ this.requestUpdate('page', previous);
129
+ this.dispatchEvent(new HelixActivateEvent({ value: String(page) }));
130
+ }
131
+ restoreFocus() {
132
+ const used = this.used;
133
+ this.used = undefined;
134
+ if (!used) {
135
+ return;
136
+ }
137
+ const { control, gap } = used;
138
+ const usable = (element) => element instanceof HTMLElement &&
139
+ element.isConnected &&
140
+ !element.disabled &&
141
+ element.getAttribute('aria-disabled') !== 'true';
142
+ if (!gap && usable(control)) {
143
+ return;
144
+ }
145
+ const target = [
146
+ this.renderRoot.querySelector('[part~="page-current"]'),
147
+ ...['previous', 'next', 'first', 'last'].map((name) => this.renderRoot.querySelector(`[part="${name}"]`)),
148
+ ].find(usable);
149
+ target?.focus();
150
+ }
116
151
  willUpdate(changed) {
117
152
  super.willUpdate(changed);
118
153
  hostAria(this.internals, { label: this.label, role: 'navigation' });
@@ -120,6 +155,7 @@ let HelixHeadlessPagination = class HelixHeadlessPagination extends HelixElement
120
155
  }
121
156
  updated(changed) {
122
157
  super.updated(changed);
158
+ this.restoreFocus();
123
159
  if (this.announced === undefined) {
124
160
  this.announced = this.page;
125
161
  return;
@@ -163,14 +199,14 @@ let HelixHeadlessPagination = class HelixHeadlessPagination extends HelixElement
163
199
  part="gap"
164
200
  href=${fill(this.href, to, this.count)}
165
201
  aria-label=${name}
166
- @click=${(event) => this.go(to, event)}
202
+ @click=${(event) => this.go(to, event, true)}
167
203
  >&hellip;</a
168
204
  >`
169
205
  : html `<button
170
206
  part="gap"
171
207
  type="button"
172
208
  aria-label=${name}
173
- @click=${(event) => this.go(to, event)}
209
+ @click=${(event) => this.go(to, event, true)}
174
210
  >
175
211
  &hellip;
176
212
  </button>`}
@@ -253,7 +289,11 @@ let HelixHeadlessPagination = class HelixHeadlessPagination extends HelixElement
253
289
  }
254
290
  return html `${this.ends ? this.renderFirst() : nothing}${this.renderPrevious()}
255
291
  <ol part="list" role="list">
256
- ${this.slots.map((slot) => typeof slot === 'number' ? this.renderPage(slot) : this.renderGap(slot))}
292
+ ${repeat(this.slots, (slot) => typeof slot === 'number'
293
+ ? slot
294
+ : slot.from < this.current
295
+ ? 'gap-before'
296
+ : 'gap-after', (slot) => (typeof slot === 'number' ? this.renderPage(slot) : this.renderGap(slot)))}
257
297
  </ol>
258
298
  ${this.renderNext()}${this.ends ? this.renderLast() : nothing}${this.renderLive()}`;
259
299
  }
@@ -23,16 +23,19 @@ import '../../select/index.js';
23
23
  * `ElementInternals.states`.
24
24
  *
25
25
  * `value` is the current size, and `default-value` is the size from the markup.
26
- * Changing it dispatches `helix-before-change`. Re-querying and returning to
27
- * page one is up to you, because only you know whether the current position
28
- * should be kept.
26
+ * Changing it dispatches `helix-before-change`, and then `input` and `change`
27
+ * once the size has moved, as a native `<select>` sends them together.
28
+ * Re-querying and returning to page one is up to you, because only you know
29
+ * whether the current position should be kept.
29
30
  *
30
31
  * @since 0.1.0
31
32
  * @status stable
32
33
  * @aliases Page size, Rows per page
33
34
  * @documentation https://fusion.dev/helix/components/pagination
34
35
  *
36
+ * @event {Event} change - Fired after the size changes.
35
37
  * @event {HelixBeforeChangeEvent} helix-before-change - Fired before the size changes, and cancelable. Canceling it is the only way to stop a size change.
38
+ * @event {Event} input - Fired after the size changes, with `change`.
36
39
  *
37
40
  * @csspart control - The select.
38
41
  * @csspart control-feedback - The message that says what is wrong with the value.
@@ -105,6 +108,13 @@ export declare class HelixHeadlessPaginationSize extends HelixElement {
105
108
  /** The one in force, which is the first offered where nothing named one. */
106
109
  private get current();
107
110
  private readonly handleChange;
111
+ /**
112
+ * The select's own `input` and `change`, stopped so this element is the one
113
+ * voice for a size. `input` is composed, so left alone it crossed this
114
+ * shadow boundary and arrived looking like this element's, with no `change`
115
+ * after it, and a refused size still sent it.
116
+ */
117
+ private readonly stopNative;
108
118
  protected willUpdate(changed: PropertyValues): void;
109
119
  /**
110
120
  * The control itself, which is the whole of this part, behind a seam the styled tier can move.
@@ -29,6 +29,8 @@ let HelixHeadlessPaginationSize = class HelixHeadlessPaginationSize extends Heli
29
29
  const previous = this.value;
30
30
  this.valueState = size;
31
31
  this.requestUpdate('value', previous);
32
+ this.dispatchEvent(new Event('input', { bubbles: true, composed: true }));
33
+ this.dispatchEvent(new Event('change', { bubbles: true, composed: false }));
32
34
  },
33
35
  event: (size) => new HelixBeforeChangeEvent({ value: String(size) }),
34
36
  host: this,
@@ -41,6 +43,9 @@ let HelixHeadlessPaginationSize = class HelixHeadlessPaginationSize extends Heli
41
43
  }
42
44
  });
43
45
  };
46
+ this.stopNative = (event) => {
47
+ event.stopPropagation();
48
+ };
44
49
  }
45
50
  get value() {
46
51
  return this.valueState ?? this.defaultValue;
@@ -83,6 +88,8 @@ let HelixHeadlessPaginationSize = class HelixHeadlessPaginationSize extends Heli
83
88
  label=${this.label}
84
89
  .value=${String(this.current)}
85
90
  @helix-before-change=${this.handleChange}
91
+ @input=${this.stopNative}
92
+ @change=${this.stopNative}
86
93
  >
87
94
  ${this.options.map((size) => html `<${option}
88
95
  part="option"
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Where a `format` puts separators in a row of boxes: for each box, the text
3
+ * drawn after it, or nothing. `#` and `*` stand for a box and anything else is
4
+ * drawn, so `###-###` puts a dash after the third box. Web Awesome's OTP input
5
+ * takes the same shape.
6
+ */
7
+ export declare const separatorsAfter: (format: string, count: number) => string[];
@@ -0,0 +1,16 @@
1
+ export const separatorsAfter = (format, count) => {
2
+ const after = Array.from({ length: count }, () => '');
3
+ let box = -1;
4
+ for (const character of format) {
5
+ if (character === '#' || character === '*') {
6
+ box += 1;
7
+ if (box >= count) {
8
+ break;
9
+ }
10
+ }
11
+ else if (box >= 0 && box < count - 1) {
12
+ after[box] += character;
13
+ }
14
+ }
15
+ return after;
16
+ };
@@ -22,6 +22,12 @@ declare const HelixHeadlessPinInput_base: (new (...args: any[]) => import("@fusi
22
22
  * Only the first cell has `autocomplete="one-time-code"`, because the hint
23
23
  * applies to the whole field.
24
24
  *
25
+ * `autosubmit` submits the form once the last box is filled, through the form's
26
+ * default button where there is one. `format` draws separators between the
27
+ * boxes, such as the dash in `###-###`, as text a screen reader skips. Delete
28
+ * removes the character in the focused box and pulls the rest of the code
29
+ * back, as Backspace removes the one before it.
30
+ *
25
31
  * The row of cells always runs left to right, with `dir="ltr"`, including in
26
32
  * Arabic and Hebrew. The first box is the leftmost, a paste fills to the right,
27
33
  * and the right arrow moves to the next box. The label, hint, and feedback
@@ -33,6 +39,10 @@ declare const HelixHeadlessPinInput_base: (new (...args: any[]) => import("@fusi
33
39
  * @aliases PinField, OTP, One-time code, Verification code, InputPin
34
40
  * @documentation https://fusion.dev/helix/components/pin-input
35
41
  *
42
+ * @slot feedback - The message that says what is wrong, for content richer than a string. It shows while there is a message.
43
+ * @slot hint - Help under the control, for content richer than the `hint` text.
44
+ * @slot label - The label, for content richer than the `label` text.
45
+ *
36
46
  * @event {Event} change - The code was filled, or an edited code lost focus.
37
47
  * @event {HelixBeforeChangeEvent} helix-before-change - The code is about to change. Cancelable.
38
48
  * @event {HelixCompleteEvent} helix-complete - The last box was filled.
@@ -43,11 +53,14 @@ declare const HelixHeadlessPinInput_base: (new (...args: any[]) => import("@fusi
43
53
  * @csspart field - The row of boxes, ordered left to right in every language.
44
54
  * @csspart hint - The help under the boxes, shown while there is no feedback.
45
55
  * @csspart label - The label above the boxes.
56
+ * @csspart separator - The text `format` draws between two boxes.
46
57
  *
47
58
  * @cssstate invalid - The control has an error to show, from the browser's validation or from your `feedback`.
48
59
  */
49
60
  export declare class HelixHeadlessPinInput extends HelixHeadlessPinInput_base {
50
61
  protected readonly aria: AriaForwardController;
62
+ /** @internal The element a missing name is checked on: the row of cells, so the name of one cell does not count as the name of the field. */
63
+ protected get namedControl(): HTMLElement | null;
51
64
  /** Typed or dragged, so every edit is announced. See `announcesInput`. */
52
65
  protected readonly announcesInput = true;
53
66
  /**
@@ -59,10 +72,22 @@ export declare class HelixHeadlessPinInput extends HelixHeadlessPinInput_base {
59
72
  * the same code is one offer made six times.
60
73
  */
61
74
  autocomplete: string;
75
+ /**
76
+ * Whether the form is submitted once the last box is filled, as Web
77
+ * Awesome's `autosubmit` and Radix's `autoSubmit`. Only for a code the field
78
+ * took: a refused last character submits nothing.
79
+ */
80
+ autosubmit: boolean;
62
81
  /**
63
82
  * Accessible name for one box, with `{index}` and `{length}` filled in.
64
83
  */
65
84
  cellLabel: string;
85
+ /**
86
+ * Separators drawn between the boxes: `#` or `*` for a box and anything
87
+ * else as it is written, so `###-###` draws a dash after the third. The
88
+ * separators are hidden from screen readers and are not part of the value.
89
+ */
90
+ format: string;
66
91
  /**
67
92
  * How many characters the code has.
68
93
  */
@@ -150,6 +175,9 @@ export declare class HelixHeadlessPinInput extends HelixHeadlessPinInput_base {
150
175
  * Backspace in an empty box goes back and clears the one it lands in, which
151
176
  * is what makes a code correctable without the reader hunting for the box
152
177
  * they meant. In a full box it does what it always does and is left alone.
178
+ *
179
+ * Home goes to the first box and End to the end of the code, the box after
180
+ * its last character, which is where the caret goes in a single text field.
153
181
  */
154
182
  private readonly handleKeydown;
155
183
  /**
@@ -272,6 +300,15 @@ export declare class HelixHeadlessPinInput extends HelixHeadlessPinInput_base {
272
300
  clear(): void;
273
301
  protected firstUpdated(changed: PropertyValues): void;
274
302
  protected updated(changed: PropertyValues): void;
303
+ /**
304
+ * Enter submits the form, as it does in a native text field.
305
+ *
306
+ * On `keypress`, where the platform runs its own implicit submission, so a
307
+ * consumer who prevents the `keydown` for Enter stops this too.
308
+ */
309
+ private readonly handleKeypress;
310
+ /** @internal A single line of text counts against implicit submission. */
311
+ protected get blocksImplicitSubmission(): boolean;
275
312
  protected render(): TemplateResult;
276
313
  }
277
314
  declare global {
@@ -7,15 +7,18 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
7
7
  import { AriaForwardController, customElement, fillTemplate, HelixCompleteEvent, HelixFormElement, MixinControllerValue, MixinField, } from '@fusion.dev/helix-core';
8
8
  import { html, nothing } from 'lit';
9
9
  import { property } from 'lit/decorators.js';
10
+ import { separatorsAfter } from '../format.js';
10
11
  let HelixHeadlessPinInput = class HelixHeadlessPinInput extends MixinControllerValue(MixinField(HelixFormElement)) {
11
12
  constructor() {
12
13
  super(...arguments);
13
14
  this.aria = new AriaForwardController(this, {
14
- target: () => this.partNamed('cell'),
15
+ target: () => this.partNamed('field'),
15
16
  });
16
17
  this.announcesInput = true;
17
18
  this.autocomplete = 'one-time-code';
19
+ this.autosubmit = false;
18
20
  this.cellLabel = 'Character {index} of {length}';
21
+ this.format = '';
19
22
  this.length = 6;
20
23
  this.mask = false;
21
24
  this.placeholder = '';
@@ -44,7 +47,7 @@ let HelixHeadlessPinInput = class HelixHeadlessPinInput extends MixinControllerV
44
47
  this.handlePaste = (event) => {
45
48
  const cell = event.target;
46
49
  const at = this.cells.indexOf(cell);
47
- if (at === -1) {
50
+ if (at === -1 || this.isDisabled || this.readOnly) {
48
51
  return;
49
52
  }
50
53
  event.preventDefault();
@@ -56,8 +59,22 @@ let HelixHeadlessPinInput = class HelixHeadlessPinInput extends MixinControllerV
56
59
  if (at === -1 || this.isDisabled || this.readOnly) {
57
60
  return;
58
61
  }
59
- const to = at + (event.key === 'ArrowRight' ? 1 : event.key === 'ArrowLeft' ? -1 : 0);
60
- if (event.key === 'Backspace' && cell.value === '' && at > 0) {
62
+ const step = event.key === 'ArrowRight' ? 1 : event.key === 'ArrowLeft' ? -1 : 0;
63
+ const to = event.key === 'Home'
64
+ ? 0
65
+ : event.key === 'End'
66
+ ? Math.min(this.value.length, this.count - 1)
67
+ : at + step;
68
+ if (event.key === 'Delete' && at < this.value.length) {
69
+ const characters = this.characters;
70
+ characters.splice(at, 1);
71
+ this.requestValue(characters.join('').replace(/\s+$/, ''));
72
+ this.updateComplete.then(() => {
73
+ this.paint();
74
+ this.cells[at]?.focus();
75
+ });
76
+ }
77
+ else if (event.key === 'Backspace' && cell.value === '' && at > 0) {
61
78
  const characters = this.characters;
62
79
  characters[at - 1] = '';
63
80
  this.requestValue(characters.join('').replace(/\s+$/, ''));
@@ -95,6 +112,14 @@ let HelixHeadlessPinInput = class HelixHeadlessPinInput extends MixinControllerV
95
112
  this.within = false;
96
113
  this.commit();
97
114
  };
115
+ this.handleKeypress = (event) => {
116
+ if (event.key === 'Enter' && !event.defaultPrevented) {
117
+ this.submitImplicitly();
118
+ }
119
+ };
120
+ }
121
+ get namedControl() {
122
+ return this.partNamed('field');
98
123
  }
99
124
  static { this.shadowRootOptions = {
100
125
  ...HelixFormElement.shadowRootOptions,
@@ -131,14 +156,17 @@ let HelixHeadlessPinInput = class HelixHeadlessPinInput extends MixinControllerV
131
156
  }
132
157
  const next = characters.join('');
133
158
  const filled = Math.min(this.count - 1, start + cleaned.length);
134
- this.requestValue(next);
159
+ const applied = this.requestValue(next);
135
160
  this.updateComplete.then(() => {
136
161
  this.paint();
137
162
  this.cells[filled]?.focus();
138
163
  this.cells[filled]?.select();
139
- if (next.length === this.count) {
164
+ if (applied && this.value === next && next.length === this.count) {
140
165
  this.dispatchEvent(new HelixCompleteEvent({ value: next }));
141
166
  this.commit();
167
+ if (this.autosubmit) {
168
+ this.submitImplicitly();
169
+ }
142
170
  }
143
171
  });
144
172
  }
@@ -198,8 +226,12 @@ let HelixHeadlessPinInput = class HelixHeadlessPinInput extends MixinControllerV
198
226
  this.paint();
199
227
  this.sync();
200
228
  }
229
+ get blocksImplicitSubmission() {
230
+ return true;
231
+ }
201
232
  render() {
202
233
  const characters = this.characters;
234
+ const separators = separatorsAfter(this.format, this.count);
203
235
  return html `${this.renderGroupLabel()}
204
236
  <div
205
237
  dir="ltr"
@@ -224,8 +256,11 @@ let HelixHeadlessPinInput = class HelixHeadlessPinInput extends MixinControllerV
224
256
  @focus=${this.handleFocus}
225
257
  @input=${this.handleInput}
226
258
  @keydown=${this.handleKeydown}
259
+ @keypress=${this.handleKeypress}
227
260
  @paste=${this.handlePaste}
228
- />`)}
261
+ />${separators[at]
262
+ ? html `<span part="separator" aria-hidden="true">${separators[at]}</span>`
263
+ : nothing}`)}
229
264
  </div>
230
265
  ${this.renderHint()}${this.renderFeedback()}`;
231
266
  }
@@ -233,9 +268,15 @@ let HelixHeadlessPinInput = class HelixHeadlessPinInput extends MixinControllerV
233
268
  __decorate([
234
269
  property()
235
270
  ], HelixHeadlessPinInput.prototype, "autocomplete", void 0);
271
+ __decorate([
272
+ property({ type: Boolean })
273
+ ], HelixHeadlessPinInput.prototype, "autosubmit", void 0);
236
274
  __decorate([
237
275
  property({ attribute: 'cell-label' })
238
276
  ], HelixHeadlessPinInput.prototype, "cellLabel", void 0);
277
+ __decorate([
278
+ property()
279
+ ], HelixHeadlessPinInput.prototype, "format", void 0);
239
280
  __decorate([
240
281
  property({ type: Number })
241
282
  ], HelixHeadlessPinInput.prototype, "length", void 0);