@fusion.dev/helix-headless 0.143.0 → 0.145.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 (314) hide show
  1. package/custom-elements.json +16990 -1383
  2. package/dist/accordion/item/accordion-item.d.ts +48 -12
  3. package/dist/accordion/item/accordion-item.js +26 -5
  4. package/dist/accordion/root/accordion-root.d.ts +6 -0
  5. package/dist/accordion/root/accordion-root.js +7 -1
  6. package/dist/announcement/root/announcement-root.d.ts +21 -1
  7. package/dist/announcement/root/announcement-root.js +36 -1
  8. package/dist/app-header/root/app-header-root.d.ts +7 -0
  9. package/dist/app-header/root/app-header-root.js +5 -1
  10. package/dist/app-header/sectioning.d.ts +7 -0
  11. package/dist/app-header/sectioning.js +26 -0
  12. package/dist/area-chart/root/area-chart-root.d.ts +12 -4
  13. package/dist/area-chart/root/area-chart-root.js +24 -7
  14. package/dist/avatar/root/avatar-root.d.ts +14 -0
  15. package/dist/avatar/root/avatar-root.js +23 -9
  16. package/dist/badge/root/badge-root.d.ts +11 -7
  17. package/dist/badge/root/badge-root.js +1 -1
  18. package/dist/bar-chart/root/bar-chart-root.d.ts +12 -3
  19. package/dist/bar-chart/root/bar-chart-root.js +17 -10
  20. package/dist/breadcrumbs/root/breadcrumbs-root.d.ts +32 -1
  21. package/dist/breadcrumbs/root/breadcrumbs-root.js +25 -2
  22. package/dist/button/root/button-root.d.ts +47 -1
  23. package/dist/button/root/button-root.js +38 -4
  24. package/dist/callout/root/callout-root.d.ts +18 -1
  25. package/dist/callout/root/callout-root.js +15 -4
  26. package/dist/canvas/root/canvas-root.d.ts +38 -3
  27. package/dist/canvas/root/canvas-root.js +121 -40
  28. package/dist/card/root/card-root.d.ts +30 -1
  29. package/dist/card/root/card-root.js +38 -5
  30. package/dist/carousel/root/carousel-root.d.ts +90 -0
  31. package/dist/carousel/root/carousel-root.js +134 -12
  32. package/dist/chat/composer/chat-composer.d.ts +38 -6
  33. package/dist/chat/composer/chat-composer.js +42 -9
  34. package/dist/chat/message/chat-message.d.ts +32 -1
  35. package/dist/chat/message/chat-message.js +25 -9
  36. package/dist/chat/naming.d.ts +22 -0
  37. package/dist/chat/naming.js +12 -0
  38. package/dist/chat/relative-clock.d.ts +39 -0
  39. package/dist/chat/relative-clock.js +31 -0
  40. package/dist/chat/root/chat-root.d.ts +36 -0
  41. package/dist/chat/root/chat-root.js +24 -1
  42. package/dist/checkbox/root/checkbox-root.js +2 -0
  43. package/dist/checkbox-group/root/checkbox-group-root.d.ts +53 -3
  44. package/dist/checkbox-group/root/checkbox-group-root.js +71 -22
  45. package/dist/code-block/lines.d.ts +13 -0
  46. package/dist/code-block/lines.js +2 -0
  47. package/dist/code-block/root/code-block-root.d.ts +38 -1
  48. package/dist/code-block/root/code-block-root.js +28 -7
  49. package/dist/color-input/root/color-input-root.d.ts +34 -1
  50. package/dist/color-input/root/color-input-root.js +23 -4
  51. package/dist/color-picker/channels.d.ts +26 -0
  52. package/dist/color-picker/channels.js +84 -0
  53. package/dist/color-picker/root/color-picker-root.d.ts +81 -5
  54. package/dist/color-picker/root/color-picker-root.js +103 -10
  55. package/dist/combobox/root/combobox-root.d.ts +38 -3
  56. package/dist/combobox/root/combobox-root.js +64 -2
  57. package/dist/command/root/command-root.d.ts +30 -4
  58. package/dist/command/root/command-root.js +33 -3
  59. package/dist/copy-button/from.d.ts +22 -0
  60. package/dist/copy-button/from.js +28 -0
  61. package/dist/copy-button/root/copy-button-root.d.ts +47 -1
  62. package/dist/copy-button/root/copy-button-root.js +44 -8
  63. package/dist/data-table/root/data-table-root.d.ts +150 -2
  64. package/dist/data-table/root/data-table-root.js +303 -29
  65. package/dist/data-table/tree.d.ts +40 -0
  66. package/dist/data-table/tree.js +55 -0
  67. package/dist/date-input/root/date-input-root.d.ts +73 -4
  68. package/dist/date-input/root/date-input-root.js +93 -43
  69. package/dist/date-picker/root/date-picker-root.d.ts +145 -1
  70. package/dist/date-picker/root/date-picker-root.js +239 -48
  71. package/dist/description-list/item/description-list-item.d.ts +17 -2
  72. package/dist/description-list/item/description-list-item.js +15 -2
  73. package/dist/description-list/root/description-list-root.d.ts +27 -1
  74. package/dist/description-list/root/description-list-root.js +26 -1
  75. package/dist/dialog/description.d.ts +9 -0
  76. package/dist/dialog/description.js +14 -0
  77. package/dist/dialog/root/dialog-root.d.ts +64 -1
  78. package/dist/dialog/root/dialog-root.js +49 -23
  79. package/dist/donut-chart/root/donut-chart-root.d.ts +25 -4
  80. package/dist/donut-chart/root/donut-chart-root.js +21 -6
  81. package/dist/drawer/root/drawer-root.d.ts +63 -2
  82. package/dist/drawer/root/drawer-root.js +95 -19
  83. package/dist/drawer/swipe-start.d.ts +9 -0
  84. package/dist/drawer/swipe-start.js +12 -0
  85. package/dist/drilldown/item/drilldown-item.d.ts +11 -6
  86. package/dist/drilldown/item/drilldown-item.js +8 -5
  87. package/dist/drilldown/root/drilldown-root.d.ts +11 -0
  88. package/dist/drilldown/root/drilldown-root.js +8 -3
  89. package/dist/element-events.generated.js +61 -13
  90. package/dist/empty/root/empty-root.d.ts +1 -1
  91. package/dist/file-input/root/file-input-root.d.ts +47 -0
  92. package/dist/file-input/root/file-input-root.js +60 -22
  93. package/dist/file-input/screen.d.ts +35 -0
  94. package/dist/file-input/screen.js +49 -0
  95. package/dist/filter-input/menu/filter-menu.d.ts +3 -0
  96. package/dist/filter-input/menu/filter-menu.js +8 -4
  97. package/dist/filter-input/root/filter-input-root.d.ts +38 -4
  98. package/dist/filter-input/root/filter-input-root.js +67 -3
  99. package/dist/filter-input/suggest.d.ts +17 -0
  100. package/dist/filter-input/suggest.js +23 -0
  101. package/dist/format-date/options.d.ts +33 -0
  102. package/dist/format-date/options.js +42 -0
  103. package/dist/format-date/root/format-date-root.d.ts +51 -0
  104. package/dist/format-date/root/format-date-root.js +58 -38
  105. package/dist/heatmap/root/heatmap-root.d.ts +23 -6
  106. package/dist/heatmap/root/heatmap-root.js +24 -13
  107. package/dist/icon/index.d.ts +2 -0
  108. package/dist/icon/index.js +2 -0
  109. package/dist/icon/registry.d.ts +37 -0
  110. package/dist/icon/registry.js +83 -0
  111. package/dist/icon/root/icon-root.d.ts +30 -4
  112. package/dist/icon/root/icon-root.js +41 -6
  113. package/dist/icon/root/index.d.ts +2 -0
  114. package/dist/icon/root/index.js +2 -0
  115. package/dist/icon/set.d.ts +1 -0
  116. package/dist/icon/set.js +3 -0
  117. package/dist/image/root/image-root.d.ts +14 -0
  118. package/dist/image/root/image-root.js +23 -2
  119. package/dist/input/root/input-root.d.ts +11 -0
  120. package/dist/input/root/input-root.js +16 -1
  121. package/dist/kbd/root/kbd-root.d.ts +20 -13
  122. package/dist/kbd/root/kbd-root.js +35 -37
  123. package/dist/kbd/shortcut.d.ts +18 -0
  124. package/dist/kbd/shortcut.js +35 -0
  125. package/dist/legend/hidden-series.d.ts +8 -0
  126. package/dist/legend/hidden-series.js +13 -0
  127. package/dist/legend/root/legend-root.d.ts +56 -0
  128. package/dist/legend/root/legend-root.js +54 -5
  129. package/dist/lightbox/item/lightbox-item.d.ts +15 -0
  130. package/dist/lightbox/item/lightbox-item.js +10 -1
  131. package/dist/lightbox/root/lightbox-root.d.ts +61 -1
  132. package/dist/lightbox/root/lightbox-root.js +94 -4
  133. package/dist/line-chart/root/line-chart-root.d.ts +11 -3
  134. package/dist/line-chart/root/line-chart-root.js +19 -5
  135. package/dist/list/item/list-item.d.ts +68 -1
  136. package/dist/list/item/list-item.js +66 -4
  137. package/dist/list/numbering.d.ts +14 -0
  138. package/dist/list/numbering.js +8 -0
  139. package/dist/list/root/list-root.d.ts +106 -9
  140. package/dist/list/root/list-root.js +189 -4
  141. package/dist/list/selection.d.ts +19 -0
  142. package/dist/list/selection.js +21 -0
  143. package/dist/listbox/root/listbox-root.d.ts +74 -3
  144. package/dist/listbox/root/listbox-root.js +86 -9
  145. package/dist/loader/busy.d.ts +17 -0
  146. package/dist/loader/busy.js +24 -0
  147. package/dist/loader/root/loader-root.d.ts +37 -0
  148. package/dist/loader/root/loader-root.js +52 -3
  149. package/dist/map/root/map-root.d.ts +6 -2
  150. package/dist/map/root/map-root.js +5 -2
  151. package/dist/megamenu/root/megamenu-root.d.ts +21 -0
  152. package/dist/megamenu/root/megamenu-root.js +16 -2
  153. package/dist/menu/index.d.ts +1 -0
  154. package/dist/menu/index.js +1 -0
  155. package/dist/menu/item/menu-item.d.ts +38 -11
  156. package/dist/menu/item/menu-item.js +33 -1
  157. package/dist/menu/root/menu-root.d.ts +25 -1
  158. package/dist/menu/root/menu-root.js +63 -6
  159. package/dist/menu/section/menu-section.d.ts +55 -0
  160. package/dist/menu/section/menu-section.js +60 -0
  161. package/dist/meter/root/meter-root.d.ts +7 -0
  162. package/dist/meter/root/meter-root.js +6 -3
  163. package/dist/navigation/root/navigation-root.d.ts +16 -1
  164. package/dist/navigation/root/navigation-root.js +27 -1
  165. package/dist/notifications/feed-keys.d.ts +10 -0
  166. package/dist/notifications/feed-keys.js +14 -0
  167. package/dist/notifications/notification/notification.d.ts +17 -0
  168. package/dist/notifications/notification/notification.js +21 -2
  169. package/dist/notifications/root/notifications-root.d.ts +60 -0
  170. package/dist/notifications/root/notifications-root.js +76 -1
  171. package/dist/number-input/root/number-input-root.d.ts +47 -0
  172. package/dist/number-input/root/number-input-root.js +58 -22
  173. package/dist/object-inspector/root/object-inspector-root.d.ts +98 -16
  174. package/dist/object-inspector/root/object-inspector-root.js +180 -80
  175. package/dist/object-inspector/rows.d.ts +57 -0
  176. package/dist/object-inspector/rows.js +86 -0
  177. package/dist/option/root/option-root.d.ts +54 -5
  178. package/dist/option/root/option-root.js +34 -5
  179. package/dist/outline/levels.d.ts +31 -0
  180. package/dist/outline/levels.js +23 -0
  181. package/dist/outline/root/outline-root.d.ts +68 -3
  182. package/dist/outline/root/outline-root.js +73 -8
  183. package/dist/pagination/size/pagination-size.d.ts +11 -2
  184. package/dist/pagination/size/pagination-size.js +19 -4
  185. package/dist/pin-input/format.d.ts +7 -0
  186. package/dist/pin-input/format.js +16 -0
  187. package/dist/pin-input/root/pin-input-root.d.ts +21 -0
  188. package/dist/pin-input/root/pin-input-root.js +29 -2
  189. package/dist/popover/root/popover-root.d.ts +62 -4
  190. package/dist/popover/root/popover-root.js +53 -5
  191. package/dist/progress/root/progress-root.d.ts +7 -0
  192. package/dist/progress/root/progress-root.js +9 -3
  193. package/dist/qr-code/export.d.ts +31 -0
  194. package/dist/qr-code/export.js +10 -0
  195. package/dist/qr-code/root/qr-code-root.d.ts +26 -0
  196. package/dist/qr-code/root/qr-code-root.js +49 -2
  197. package/dist/radio/group/radio-group.d.ts +17 -0
  198. package/dist/radio/group/radio-group.js +14 -1
  199. package/dist/rating/root/rating-root.d.ts +25 -0
  200. package/dist/rating/root/rating-root.js +46 -4
  201. package/dist/scatter-chart/root/scatter-chart-root.d.ts +17 -3
  202. package/dist/scatter-chart/root/scatter-chart-root.js +25 -7
  203. package/dist/scroll-area/root/scroll-area-root.d.ts +113 -0
  204. package/dist/scroll-area/root/scroll-area-root.js +218 -3
  205. package/dist/scroll-area/scrollbar.d.ts +65 -0
  206. package/dist/scroll-area/scrollbar.js +24 -0
  207. package/dist/select/root/select-root.d.ts +24 -0
  208. package/dist/select/root/select-root.js +21 -7
  209. package/dist/skeleton/root/skeleton-root.d.ts +25 -0
  210. package/dist/skeleton/root/skeleton-root.js +17 -2
  211. package/dist/slider/root/slider-root.d.ts +39 -0
  212. package/dist/slider/root/slider-root.js +45 -9
  213. package/dist/splitter/root/splitter-root.d.ts +13 -0
  214. package/dist/splitter/root/splitter-root.js +20 -2
  215. package/dist/splitter/snap.d.ts +9 -0
  216. package/dist/splitter/snap.js +12 -0
  217. package/dist/stat/root/stat-root.d.ts +2 -0
  218. package/dist/stat/root/stat-root.js +1 -1
  219. package/dist/steps/reach.d.ts +15 -0
  220. package/dist/steps/reach.js +12 -0
  221. package/dist/steps/root/steps-root.d.ts +30 -0
  222. package/dist/steps/root/steps-root.js +53 -0
  223. package/dist/steps/step/step.d.ts +39 -2
  224. package/dist/steps/step/step.js +29 -7
  225. package/dist/switch/root/switch-root.d.ts +12 -2
  226. package/dist/switch/root/switch-root.js +6 -1
  227. package/dist/table/column/table-column.d.ts +11 -0
  228. package/dist/table/column/table-column.js +6 -1
  229. package/dist/table/root/table-root.d.ts +101 -0
  230. package/dist/table/root/table-root.js +166 -5
  231. package/dist/table/row/table-row.d.ts +47 -1
  232. package/dist/table/row/table-row.js +39 -2
  233. package/dist/tabs/panel/tab-panel.d.ts +9 -5
  234. package/dist/tabs/panel/tab-panel.js +3 -4
  235. package/dist/tabs/root/tabs-root.d.ts +25 -1
  236. package/dist/tabs/root/tabs-root.js +21 -3
  237. package/dist/tabs/tab/tab.d.ts +36 -4
  238. package/dist/tabs/tab/tab.js +46 -3
  239. package/dist/tag/group/tag-group.d.ts +107 -0
  240. package/dist/tag/group/tag-group.js +157 -0
  241. package/dist/tag/index.d.ts +1 -0
  242. package/dist/tag/index.js +1 -0
  243. package/dist/tag/root/tag-root.d.ts +60 -0
  244. package/dist/tag/root/tag-root.js +74 -18
  245. package/dist/tag/selection.d.ts +10 -0
  246. package/dist/tag/selection.js +12 -0
  247. package/dist/textarea/grow.d.ts +22 -0
  248. package/dist/textarea/grow.js +20 -0
  249. package/dist/textarea/root/textarea-root.d.ts +9 -0
  250. package/dist/textarea/root/textarea-root.js +9 -1
  251. package/dist/time-input/root/time-input-root.d.ts +44 -5
  252. package/dist/time-input/root/time-input-root.js +69 -39
  253. package/dist/time-picker/root/time-picker-root.d.ts +54 -8
  254. package/dist/time-picker/root/time-picker-root.js +121 -91
  255. package/dist/timeline/group/timeline-group.d.ts +46 -0
  256. package/dist/timeline/group/timeline-group.js +37 -0
  257. package/dist/timeline/index.d.ts +1 -0
  258. package/dist/timeline/index.js +1 -0
  259. package/dist/timeline/root/timeline-root.d.ts +10 -3
  260. package/dist/toast/hotkey.d.ts +22 -0
  261. package/dist/toast/hotkey.js +23 -0
  262. package/dist/toast/item/toast-item.d.ts +26 -18
  263. package/dist/toast/item/toast-item.js +55 -48
  264. package/dist/toast/root/toast-root.d.ts +42 -8
  265. package/dist/toast/root/toast-root.js +64 -4
  266. package/dist/toggle/group/toggle-group.d.ts +57 -15
  267. package/dist/toggle/group/toggle-group.js +69 -9
  268. package/dist/toggle/root/toggle-root.d.ts +12 -1
  269. package/dist/toggle/root/toggle-root.js +11 -3
  270. package/dist/toolbar/root/toolbar-root.d.ts +13 -0
  271. package/dist/toolbar/root/toolbar-root.js +15 -5
  272. package/dist/tooltip/focus-target.d.ts +6 -0
  273. package/dist/tooltip/focus-target.js +9 -0
  274. package/dist/tooltip/root/tooltip-root.d.ts +42 -17
  275. package/dist/tooltip/root/tooltip-root.js +50 -9
  276. package/dist/tour/naming.d.ts +30 -0
  277. package/dist/tour/naming.js +10 -0
  278. package/dist/tour/root/tour-root.d.ts +35 -0
  279. package/dist/tour/root/tour-root.js +56 -5
  280. package/dist/tour/stop/tour-stop.d.ts +53 -8
  281. package/dist/tour/stop/tour-stop.js +45 -15
  282. package/dist/tour/wait.d.ts +11 -0
  283. package/dist/tour/wait.js +19 -0
  284. package/dist/tree/item/tree-item.d.ts +54 -1
  285. package/dist/tree/item/tree-item.js +89 -20
  286. package/dist/tree/root/tree-root.d.ts +37 -0
  287. package/dist/tree/root/tree-root.js +51 -6
  288. package/dist/tree/selection.d.ts +24 -0
  289. package/dist/tree/selection.js +26 -0
  290. package/dist/trend/root/trend-root.d.ts +13 -0
  291. package/dist/trend/root/trend-root.js +14 -9
  292. package/dist/video/media-events.d.ts +49 -0
  293. package/dist/video/media-events.js +39 -0
  294. package/dist/video/root/video-root.d.ts +99 -13
  295. package/dist/video/root/video-root.js +84 -47
  296. package/dist/video-playlist/menu/video-playlist-menu.d.ts +3 -0
  297. package/dist/video-playlist/menu/video-playlist-menu.js +2 -1
  298. package/dist/video-playlist/order.d.ts +41 -0
  299. package/dist/video-playlist/order.js +34 -0
  300. package/dist/video-playlist/root/video-playlist-root.d.ts +70 -2
  301. package/dist/video-playlist/root/video-playlist-root.js +60 -16
  302. package/dist/virtual-list/controls.d.ts +4 -0
  303. package/dist/virtual-list/controls.js +30 -0
  304. package/dist/virtual-list/fill.d.ts +30 -0
  305. package/dist/virtual-list/fill.js +39 -0
  306. package/dist/virtual-list/keys.d.ts +15 -0
  307. package/dist/virtual-list/keys.js +24 -0
  308. package/dist/virtual-list/root/virtual-list-root.d.ts +155 -23
  309. package/dist/virtual-list/root/virtual-list-root.js +175 -34
  310. package/lint.json +1 -1
  311. package/package.json +5 -5
  312. package/types/jsx.d.ts +8871 -1286
  313. package/types/svelte.d.ts +3 -0
  314. package/types/vue.d.ts +1918 -269
@@ -1,18 +1,7 @@
1
1
  import { AriaForwardController, HelixElement } from '@fusion.dev/helix-core';
2
2
  import { type PropertyValues, type TemplateResult } from 'lit';
3
3
  import '../../copy-button/index.js';
4
- /** One visible line of the tree: a value, where it sits, and whether it is open. */
5
- interface Row {
6
- branch: boolean;
7
- depth: number;
8
- /** The property name or array index this value is under; absent for the root. */
9
- key?: string;
10
- open: boolean;
11
- path: string;
12
- position: number;
13
- siblings: number;
14
- value: unknown;
15
- }
4
+ import { type Row } from '../rows.js';
16
5
  /**
17
6
  * @summary A structured value shown as a tree, where you can close branches,
18
7
  * see how many entries each holds, and copy any part.
@@ -34,6 +23,22 @@ interface Row {
34
23
  * row. Each row carries its real level, position, and set size, including in
35
24
  * a windowed tree.
36
25
  *
26
+ * `active` is the active row's path, written the way a JSON Pointer writes it:
27
+ * the empty string for the root and `/meta/tags/0` for an entry under it.
28
+ * Moving to another row sends `helix-before-activate`, which you can cancel,
29
+ * and then `helix-activate`, both with the path. Writing `active` moves there
30
+ * and opens the branches around it, and sends nothing. `expanded` holds the
31
+ * open branches by path, and writing it opens those and closes the rest. A row
32
+ * that closes around the active one hands it to the nearest open branch.
33
+ *
34
+ * `filter` narrows the tree to the entries whose key or value holds the text,
35
+ * ignoring case, and the branches that lead to them, which it opens. A matched
36
+ * branch keeps everything under it. Each matched row carries `row-match`, and
37
+ * a screen reader hears how many entries matched from `result-label` and
38
+ * `results-label`. `filterable` adds a field that sets it: typing sends
39
+ * `helix-filter`, which you can cancel, and then `helix-filtered`, and Down
40
+ * moves from the field to the tree.
41
+ *
37
42
  * A new `value` keeps the branches a reader opened or closed, and the active
38
43
  * row, where the new value still has them. A branch the old value did not have
39
44
  * opens to `default-depth`.
@@ -53,13 +58,18 @@ interface Row {
53
58
  * @aliases JSON viewer, Object viewer, Inspector, Data explorer
54
59
  * @documentation https://fusion.dev/helix/components/object-inspector
55
60
  *
61
+ * @event {HelixActivateEvent} helix-activate - The active row moved, by a key or a click. The detail's `value` is its path.
62
+ * @event {HelixBeforeActivateEvent} helix-before-activate - The active row is about to move, with its new path. Cancelable: cancel it to keep the row where it is.
56
63
  * @event {HelixCopyEvent} helix-copy - A value was put on the clipboard, from the copy button or the keyboard.
64
+ * @event {HelixFilterEvent} helix-filter - Text was typed in the filter field, with what it now holds. Cancelable: cancel it to keep the filter as it was.
65
+ * @event {HelixFilteredEvent} helix-filtered - The filter field changed `filter`, which now holds the text.
57
66
  *
58
67
  * @csspart after - The space the rows below the drawn rows would take, when `windowed` is set.
59
68
  * @csspart before - The space the rows above the drawn rows would take, when `windowed` is set.
60
69
  * @csspart boolean - A `true` or `false`.
61
70
  * @csspart copy - The copy button, which copies the active row.
62
71
  * @csspart copy-button - The button inside the copy control.
72
+ * @csspart copy-live - The live region inside the copy button, which says its `pending-label` when the copy becomes pending under focus.
63
73
  * @csspart copy-mark - The clipboard icon, and the confirmation icon that replaces it.
64
74
  * @csspart copy-text - The words on that button, trimmed to their capitals and baseline.
65
75
  * @csspart copy-tooltip - The tooltip, forwarded from the copy button's tooltip.
@@ -77,10 +87,13 @@ interface Row {
77
87
  * @csspart header - The bar that holds the label, when there is one.
78
88
  * @csspart key - A property name or an array index.
79
89
  * @csspart label - The label.
90
+ * @csspart live - How many entries a filter matched, in a region that screen readers announce when it changes. Drawn from the first filter on. Visually hidden in the styled tier.
80
91
  * @csspart null - A `null`.
81
92
  * @csspart number - A number.
82
93
  * @csspart row - One entry, as a tree item.
83
94
  * @csspart row-active - The entry the keyboard is on. Set alongside `row`.
95
+ * @csspart row-match - An entry whose key or value holds the filter. Set alongside `row`.
96
+ * @csspart search-field - The field that sets `filter`, with `filterable`.
84
97
  * @csspart string - A string, in quotes.
85
98
  * @csspart summary - The brackets that stand for a branch's contents.
86
99
  * @csspart toggle - The caret on a branch. It points down when the branch is open and sideways when it is closed.
@@ -89,6 +102,17 @@ interface Row {
89
102
  * @cssproperty --object-inspector-level - How deep a row is, from 0 at the root, for indenting it.
90
103
  */
91
104
  export declare class HelixHeadlessObjectInspector extends HelixElement {
105
+ /**
106
+ * The active row's path, such as `/meta/tags/0`, and the empty string for the
107
+ * root.
108
+ *
109
+ * Reading gives the row the keys are on. Writing moves there, opening the
110
+ * branches around it, and sends no event, the way a script's write to any
111
+ * current value sends none. A path the value does not hold moves to the
112
+ * nearest branch above it that it does.
113
+ */
114
+ get active(): string;
115
+ set active(path: string);
92
116
  /**
93
117
  * The copy button's accessible name on a row with a key, with the key filled
94
118
  * in as `{name}`.
@@ -108,6 +132,23 @@ export declare class HelixHeadlessObjectInspector extends HelixElement {
108
132
  * wall of text this exists to avoid.
109
133
  */
110
134
  defaultDepth: number;
135
+ /**
136
+ * The open branches, by path, in no set order.
137
+ *
138
+ * Writing opens exactly these and closes every other, keeping the active row
139
+ * where it stays visible. A property, never an attribute.
140
+ */
141
+ get expanded(): string[];
142
+ set expanded(paths: string[]);
143
+ /**
144
+ * Text the tree is narrowed to: the entries whose key or value holds it,
145
+ * ignoring case, and the branches that lead to them. Empty shows everything.
146
+ */
147
+ filter: string;
148
+ /** Whether to show a field that sets `filter`. */
149
+ filterable: boolean;
150
+ /** The filter field's placeholder and accessible name. */
151
+ filterLabel: string;
111
152
  /**
112
153
  * The id of a `<script type="application/json">` holding the value.
113
154
  *
@@ -142,6 +183,13 @@ export declare class HelixHeadlessObjectInspector extends HelixElement {
142
183
  * reach a value.
143
184
  */
144
185
  noCopy: boolean;
186
+ /** What a screen reader hears when a filter matches one entry. `{count}` is the count. */
187
+ resultLabel: string;
188
+ /**
189
+ * What a screen reader hears when a filter matches any other number of
190
+ * entries. `{count}` is the count. The two are chosen by `Intl.PluralRules`.
191
+ */
192
+ resultsLabel: string;
145
193
  /**
146
194
  * The tree's accessible name when `label` is empty and the host names it
147
195
  * with neither `aria-label` nor `aria-labelledby`.
@@ -168,7 +216,18 @@ export declare class HelixHeadlessObjectInspector extends HelixElement {
168
216
  /** Which branches are open, by path. */
169
217
  private opened;
170
218
  /** The row the arrow keys are on, by its place among the visible rows. */
171
- private active;
219
+ private cursor;
220
+ /** A path written to `active` and not yet found among the rows. */
221
+ private wanted;
222
+ /**
223
+ * The branches written to `expanded`, until the next update applies them.
224
+ *
225
+ * Its own field, because a property declared with an accessor is in the
226
+ * first update's changes whether or not anybody wrote it.
227
+ */
228
+ private declared;
229
+ /** The paths the filter matched, or nothing while there is no filter. */
230
+ private found;
172
231
  /** Set by a keyboard move, so the next render brings the active row into view. */
173
232
  private revealing;
174
233
  /** What has been typed toward a key, and when the last letter came. */
@@ -177,6 +236,8 @@ export declare class HelixHeadlessObjectInspector extends HelixElement {
177
236
  private branches;
178
237
  /** Carries a host `aria-label` and `aria-labelledby` to the tree, which is what takes focus. */
179
238
  protected readonly aria: AriaForwardController;
239
+ /** Says how many entries a filter matched. */
240
+ private readonly status;
180
241
  /**
181
242
  * How tall a row is taken to be before it has been drawn, in pixels.
182
243
  *
@@ -192,8 +253,6 @@ export declare class HelixHeadlessObjectInspector extends HelixElement {
192
253
  /** Every visible row, in order, worked out once per change rather than per read. */
193
254
  private rows;
194
255
  private readonly copier;
195
- /** Every visible row, in order, for the tree as it stands. */
196
- private flatten;
197
256
  /**
198
257
  * Opens every branch shallower than `defaultDepth`.
199
258
  *
@@ -204,7 +263,17 @@ export declare class HelixHeadlessObjectInspector extends HelixElement {
204
263
  * place on every update.
205
264
  */
206
265
  private seed;
266
+ /** Opens the branches around each path, where the value has them. */
267
+ private openAround;
207
268
  protected willUpdate(changed: PropertyValues): void;
269
+ /**
270
+ * Where the active row goes once the rows have moved: onto `path` where it
271
+ * is still shown, onto the first match where a filter just hid it, and
272
+ * otherwise onto the nearest branch around it that is.
273
+ */
274
+ private place;
275
+ /** Says how many entries the filter matched, and nothing for an empty one. */
276
+ private tell;
208
277
  protected firstUpdated(changed: PropertyValues): void;
209
278
  protected updated(changed: PropertyValues): void;
210
279
  private load;
@@ -224,6 +293,10 @@ export declare class HelixHeadlessObjectInspector extends HelixElement {
224
293
  /** What copying takes: a branch as indented JSON, a string as itself. */
225
294
  private copyable;
226
295
  private toggle;
296
+ /**
297
+ * Moves the active row, asking first: `helix-before-activate` with the path,
298
+ * then `helix-activate` once it has moved. Returns whether it is there.
299
+ */
227
300
  private move;
228
301
  private readonly handleKeydown;
229
302
  /** Opens every branch at the active row's level under the same parent, as `*` asks. */
@@ -236,7 +309,12 @@ export declare class HelixHeadlessObjectInspector extends HelixElement {
236
309
  * keys that start with it.
237
310
  */
238
311
  private typeahead;
312
+ /** A press opens or closes the row it lands on, once that row is the active one. */
239
313
  private handleRowClick;
314
+ /** Text typed in the filter field, asked for before the tree narrows to it. */
315
+ private readonly handleFilterInput;
316
+ /** Down from the filter field goes to the tree, where the matches are. */
317
+ private readonly handleFilterKeydown;
240
318
  private renderValue;
241
319
  /**
242
320
  * One entry, named for its state where it holds one.
@@ -247,6 +325,11 @@ export declare class HelixHeadlessObjectInspector extends HelixElement {
247
325
  * attribute would be a second spelling with no reader. The name is the one a
248
326
  * consumer can reach, nothing being able to follow `::part()` with an
249
327
  * attribute selector.
328
+ *
329
+ * **`aria-selected="false"` on every row**, because nothing here is chosen.
330
+ * Chromium takes the active descendant of a single-selection tree as selected
331
+ * when no row says otherwise, so every arrow press was also announced as a
332
+ * selection. An explicit false is the one thing that turns that off.
250
333
  */
251
334
  private renderRow;
252
335
  /** The copy button, behind the seam Code Block's uses, so each tier renders its own. */
@@ -258,4 +341,3 @@ declare global {
258
341
  'helix-headless-object-inspector': HelixHeadlessObjectInspector;
259
342
  }
260
343
  }
261
- export {};
@@ -5,22 +5,23 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
7
  var HelixHeadlessObjectInspector_1;
8
- import { AriaForwardController, CopyController, customElement, elementById, fillTemplate, formatNumbers, HelixElement, inlineStep, scrollItemIntoView, searchableById, VirtualizeController, } from '@fusion.dev/helix-core';
8
+ import { AriaForwardController, CopyController, countLabel, customElement, drawStatus, elementById, fillTemplate, formatNumbers, HelixActivateEvent, HelixBeforeActivateEvent, HelixElement, HelixFilterEvent, HelixFilteredEvent, inlineStep, requestChange, StatusController, scrollItemIntoView, searchableById, VirtualizeController, } from '@fusion.dev/helix-core';
9
9
  import { caretDown, caretRight } from '@fusion.dev/helix-icons';
10
10
  import { html, nothing } from 'lit';
11
11
  import { property, state } from 'lit/decorators.js';
12
12
  import { unsafeSVG } from 'lit/directives/unsafe-svg.js';
13
13
  import { html as staticHtml } from 'lit/static-html.js';
14
14
  import '../../copy-button/index.js';
15
- const branchy = (value) => value !== null && typeof value === 'object';
16
- const entries = (value) => Array.isArray(value) ? value.map((item, at) => [String(at), item]) : Object.entries(value);
17
- const child = (path, key) => `${path}/${key.replaceAll('~', '~0').replaceAll('/', '~1')}`;
15
+ import { ancestorsOf, entries, flatten, search, seed } from '../rows.js';
18
16
  let HelixHeadlessObjectInspector = class HelixHeadlessObjectInspector extends HelixElement {
19
17
  constructor() {
20
18
  super(...arguments);
21
19
  this.copyLabel = 'Copy {name}';
22
20
  this.copyValueLabel = 'Copy value';
23
21
  this.defaultDepth = 1;
22
+ this.filter = '';
23
+ this.filterable = false;
24
+ this.filterLabel = 'Filter';
24
25
  this.for = '';
25
26
  this.itemLabel = '{count} item';
26
27
  this.itemsLabel = '{count} items';
@@ -28,12 +29,14 @@ let HelixHeadlessObjectInspector = class HelixHeadlessObjectInspector extends He
28
29
  this.keysLabel = '{count} keys';
29
30
  this.label = '';
30
31
  this.noCopy = false;
32
+ this.resultLabel = '{count} result';
33
+ this.resultsLabel = '{count} results';
31
34
  this.treeLabel = 'Value';
32
35
  this.value = undefined;
33
36
  this.windowed = false;
34
37
  this.read = undefined;
35
38
  this.opened = new Set();
36
- this.active = 0;
39
+ this.cursor = 0;
37
40
  this.revealing = false;
38
41
  this.typed = { at: 0, text: '' };
39
42
  this.branches = new Set();
@@ -41,6 +44,7 @@ let HelixHeadlessObjectInspector = class HelixHeadlessObjectInspector extends He
41
44
  label: true,
42
45
  target: () => this.partNamed('tree'),
43
46
  });
47
+ this.status = new StatusController(this);
44
48
  this.virtualize = new VirtualizeController(this, {
45
49
  container: () => (this.windowed ? this.partNamed('tree') : null),
46
50
  count: () => this.rows.length,
@@ -52,7 +56,7 @@ let HelixHeadlessObjectInspector = class HelixHeadlessObjectInspector extends He
52
56
  this.copier = new CopyController(this);
53
57
  this.handleKeydown = (event) => {
54
58
  const rows = this.rows;
55
- const row = rows[this.active];
59
+ const row = rows[this.cursor];
56
60
  if (!row) {
57
61
  return;
58
62
  }
@@ -66,10 +70,10 @@ let HelixHeadlessObjectInspector = class HelixHeadlessObjectInspector extends He
66
70
  }
67
71
  switch (event.key) {
68
72
  case 'ArrowDown':
69
- this.move(this.active + 1);
73
+ this.move(this.cursor + 1);
70
74
  break;
71
75
  case 'ArrowUp':
72
- this.move(this.active - 1);
76
+ this.move(this.cursor - 1);
73
77
  break;
74
78
  case 'Home':
75
79
  this.move(0);
@@ -84,14 +88,14 @@ let HelixHeadlessObjectInspector = class HelixHeadlessObjectInspector extends He
84
88
  this.toggle(row, true);
85
89
  }
86
90
  else if (row.open) {
87
- this.move(this.active + 1);
91
+ this.move(this.cursor + 1);
88
92
  }
89
93
  }
90
94
  else if (row.open) {
91
95
  this.toggle(row, false);
92
96
  }
93
97
  else {
94
- const parent = rows.findLastIndex((candidate, at) => at < this.active && candidate.depth === row.depth - 1);
98
+ const parent = rows.findLastIndex((candidate, at) => at < this.cursor && candidate.depth === row.depth - 1);
95
99
  if (parent >= 0) {
96
100
  this.move(parent);
97
101
  }
@@ -114,80 +118,123 @@ let HelixHeadlessObjectInspector = class HelixHeadlessObjectInspector extends He
114
118
  }
115
119
  event.preventDefault();
116
120
  };
121
+ this.handleFilterInput = (event) => {
122
+ const field = event.currentTarget;
123
+ const applied = requestChange({
124
+ apply: (value) => {
125
+ this.filter = value;
126
+ },
127
+ event: (value) => new HelixFilterEvent({ value }),
128
+ host: this,
129
+ next: field.value,
130
+ });
131
+ if (applied) {
132
+ this.dispatchEvent(new HelixFilteredEvent({ value: field.value }));
133
+ }
134
+ else {
135
+ field.value = this.filter;
136
+ }
137
+ };
138
+ this.handleFilterKeydown = (event) => {
139
+ if (event.key === 'ArrowDown') {
140
+ event.preventDefault();
141
+ this.partNamed('tree')?.focus();
142
+ }
143
+ };
117
144
  }
118
145
  static { HelixHeadlessObjectInspector_1 = this; }
146
+ get active() {
147
+ return this.wanted ?? this.rows[this.cursor]?.path ?? '';
148
+ }
149
+ set active(path) {
150
+ const previous = this.active;
151
+ this.wanted = path;
152
+ this.requestUpdate('active', previous);
153
+ }
154
+ get expanded() {
155
+ return [...this.opened];
156
+ }
157
+ set expanded(paths) {
158
+ const previous = this.expanded;
159
+ this.declared = new Set(paths);
160
+ this.opened = this.declared;
161
+ this.requestUpdate('expanded', previous);
162
+ }
119
163
  static { this.ESTIMATE = 24; }
120
164
  get root() {
121
165
  return this.value === undefined ? this.read : this.value;
122
166
  }
123
- flatten() {
124
- const rows = [];
125
- if (this.root === undefined) {
126
- return rows;
127
- }
128
- const visit = (value, path, depth, position, siblings, key) => {
129
- const branch = branchy(value);
130
- const open = branch && this.opened.has(path);
131
- rows.push({
132
- branch,
133
- depth,
134
- open,
135
- path,
136
- position,
137
- siblings,
138
- value,
139
- ...(key === undefined ? {} : { key }),
140
- });
141
- if (open) {
142
- const children = entries(value);
143
- children.forEach(([name, item], at) => {
144
- visit(item, child(path, name), depth + 1, at + 1, children.length, name);
145
- });
146
- }
147
- };
148
- visit(this.root, '', 0, 1, 1);
149
- return rows;
150
- }
151
167
  seed(keep) {
152
- const opened = new Set();
153
- const branches = new Set();
154
- const visit = (value, path, depth) => {
155
- if (!branchy(value)) {
156
- return;
157
- }
158
- branches.add(path);
159
- const known = keep && this.branches.has(path);
160
- if (known ? this.opened.has(path) : depth < this.defaultDepth) {
161
- opened.add(path);
162
- }
163
- for (const [name, item] of entries(value)) {
164
- visit(item, child(path, name), depth + 1);
165
- }
166
- };
167
- visit(this.root, '', 0);
168
+ const { branches, opened } = seed(this.root, this.defaultDepth, keep ? this.branches : undefined, this.opened);
168
169
  this.branches = branches;
169
170
  this.opened = opened;
170
171
  if (!keep) {
171
- this.active = 0;
172
+ this.cursor = 0;
172
173
  }
173
174
  }
175
+ openAround(paths) {
176
+ const opened = new Set(this.opened);
177
+ for (const path of paths) {
178
+ for (const above of ancestorsOf(path)) {
179
+ if (this.branches.has(above)) {
180
+ opened.add(above);
181
+ }
182
+ }
183
+ }
184
+ this.opened = opened;
185
+ }
174
186
  willUpdate(changed) {
175
187
  super.willUpdate(changed);
176
188
  if (this.loadedFor !== this.for && searchableById(this) && !this.hydrating) {
177
189
  this.loadedFor = this.for;
178
190
  this.load();
179
191
  }
180
- const was = this.rows[this.active]?.path;
181
- if (changed.has('value') || changed.has('read') || changed.has('defaultDepth')) {
192
+ const was = this.rows[this.cursor]?.path;
193
+ const written = this.declared;
194
+ this.declared = undefined;
195
+ const fresh = changed.has('value') || changed.has('read');
196
+ if (fresh || changed.has('defaultDepth')) {
182
197
  this.seed(!changed.has('defaultDepth'));
183
198
  }
184
- if (changed.has('value') ||
185
- changed.has('read') ||
186
- changed.has('opened') ||
187
- changed.has('defaultDepth')) {
188
- this.rows = this.flatten();
189
- const found = was === undefined ? -1 : this.rows.findIndex((row) => row.path === was);
190
- this.active = found >= 0 ? found : Math.min(this.active, Math.max(0, this.rows.length - 1));
199
+ if (written) {
200
+ this.opened = written;
201
+ }
202
+ if (fresh || changed.has('filter')) {
203
+ this.found = this.filter.trim() === '' ? undefined : search(this.root, this.filter);
204
+ this.openAround(this.found ?? []);
205
+ }
206
+ const wanted = this.root === undefined ? undefined : this.wanted;
207
+ if (wanted !== undefined) {
208
+ this.wanted = undefined;
209
+ this.openAround([wanted]);
210
+ }
211
+ if (fresh ||
212
+ wanted !== undefined ||
213
+ ['active', 'defaultDepth', 'expanded', 'filter', 'opened'].some((name) => changed.has(name))) {
214
+ this.rows = flatten(this.root, this.opened, this.found);
215
+ this.cursor = this.place(wanted ?? was, changed.has('filter'));
216
+ }
217
+ if (changed.has('filter') && this.hasUpdated) {
218
+ this.tell();
219
+ }
220
+ }
221
+ place(path, filtered) {
222
+ const rows = this.rows;
223
+ const at = (one) => rows.findIndex((row) => row.path === one);
224
+ const own = path === undefined ? -1 : at(path);
225
+ if (own >= 0 || path === undefined) {
226
+ return own >= 0 ? own : Math.min(this.cursor, Math.max(0, rows.length - 1));
227
+ }
228
+ const match = filtered ? rows.findIndex((row) => row.match) : -1;
229
+ const around = ancestorsOf(path)
230
+ .reverse()
231
+ .map(at)
232
+ .find((one) => one >= 0);
233
+ return match >= 0 ? match : (around ?? 0);
234
+ }
235
+ tell() {
236
+ if (this.found) {
237
+ this.status.say(countLabel(this.found.size, this.resultLabel, this.resultsLabel, this.lang));
191
238
  }
192
239
  }
193
240
  firstUpdated(changed) {
@@ -215,7 +262,7 @@ let HelixHeadlessObjectInspector = class HelixHeadlessObjectInspector extends He
215
262
  }
216
263
  reveal(attempts = 8) {
217
264
  const tree = this.partNamed('tree');
218
- const row = tree?.querySelector(`[data-index="${this.active}"]`);
265
+ const row = tree?.querySelector(`[data-index="${this.cursor}"]`);
219
266
  if (row) {
220
267
  scrollItemIntoView(row);
221
268
  return;
@@ -227,8 +274,8 @@ let HelixHeadlessObjectInspector = class HelixHeadlessObjectInspector extends He
227
274
  return;
228
275
  }
229
276
  const height = first.offsetHeight || HelixHeadlessObjectInspector_1.ESTIMATE;
230
- const from = Number(this.active > Number(last.dataset.index) ? last.dataset.index : first.dataset.index);
231
- tree.scrollTop += (this.active - from) * height;
277
+ const from = Number(this.cursor > Number(last.dataset.index) ? last.dataset.index : first.dataset.index);
278
+ tree.scrollTop += (this.cursor - from) * height;
232
279
  this.virtualize.measure();
233
280
  void this.updateComplete.then(() => this.reveal(attempts - 1));
234
281
  }
@@ -252,9 +299,27 @@ let HelixHeadlessObjectInspector = class HelixHeadlessObjectInspector extends He
252
299
  this.opened = opened;
253
300
  }
254
301
  move(to) {
255
- const last = this.rows.length - 1;
256
- this.active = Math.max(0, Math.min(to, last));
302
+ const at = Math.max(0, Math.min(to, this.rows.length - 1));
303
+ const path = this.rows[at]?.path;
304
+ if (path === undefined) {
305
+ return false;
306
+ }
307
+ if (at !== this.cursor) {
308
+ const moved = requestChange({
309
+ apply: () => {
310
+ this.cursor = at;
311
+ },
312
+ event: (value) => new HelixBeforeActivateEvent({ value }),
313
+ host: this,
314
+ next: path,
315
+ });
316
+ if (!moved) {
317
+ return false;
318
+ }
319
+ this.dispatchEvent(new HelixActivateEvent({ value: path }));
320
+ }
257
321
  this.revealing = true;
322
+ return true;
258
323
  }
259
324
  openSiblings(row) {
260
325
  const parent = row.path.slice(0, row.path.lastIndexOf('/'));
@@ -275,7 +340,7 @@ let HelixHeadlessObjectInspector = class HelixHeadlessObjectInspector extends He
275
340
  const wanted = text.toLocaleLowerCase();
276
341
  const repeated = [...wanted].every((one) => one === wanted[0]);
277
342
  const rows = this.rows;
278
- const start = wanted.length === 1 || repeated ? this.active + 1 : this.active;
343
+ const start = wanted.length === 1 || repeated ? this.cursor + 1 : this.cursor;
279
344
  for (let step = 0; step < rows.length; step += 1) {
280
345
  const at = (start + step) % rows.length;
281
346
  const key = rows[at]?.key?.toLocaleLowerCase();
@@ -286,8 +351,7 @@ let HelixHeadlessObjectInspector = class HelixHeadlessObjectInspector extends He
286
351
  }
287
352
  }
288
353
  handleRowClick(index, row) {
289
- this.active = index;
290
- if (row.branch) {
354
+ if (this.move(index) && row.branch) {
291
355
  this.toggle(row);
292
356
  }
293
357
  }
@@ -324,14 +388,15 @@ let HelixHeadlessObjectInspector = class HelixHeadlessObjectInspector extends He
324
388
  return html `<span part="string" dir="ltr">${String(value)}</span>`;
325
389
  }
326
390
  renderRow(row, index) {
327
- const active = index === this.active;
391
+ const active = index === this.cursor;
328
392
  return html `<div
329
- part="row${active ? ' row-active' : ''}"
393
+ part="row${active ? ' row-active' : ''}${row.match ? ' row-match' : ''}"
330
394
  role="treeitem"
331
395
  id=${`row-${index}`}
332
396
  data-index=${index}
333
397
  aria-level=${row.depth + 1}
334
398
  aria-posinset=${row.position}
399
+ aria-selected="false"
335
400
  aria-setsize=${row.siblings}
336
401
  aria-expanded=${row.branch ? String(row.open) : nothing}
337
402
  style=${`--object-inspector-level: ${row.depth}`}
@@ -353,7 +418,7 @@ let HelixHeadlessObjectInspector = class HelixHeadlessObjectInspector extends He
353
418
  renderCopyButton(row) {
354
419
  return staticHtml `<${this.tag('copy-button')}
355
420
  part="copy"
356
- exportparts="button: copy-button, text: copy-text, mark: copy-mark, tooltip: copy-tooltip,
421
+ exportparts="button: copy-button, live: copy-live, text: copy-text, mark: copy-mark, tooltip: copy-tooltip,
357
422
  tooltip-arrow: copy-tooltip-arrow, tooltip-arrow-bottom: copy-tooltip-arrow-bottom,
358
423
  tooltip-arrow-left: copy-tooltip-arrow-left, tooltip-arrow-right: copy-tooltip-arrow-right,
359
424
  tooltip-arrow-top: copy-tooltip-arrow-top, tooltip-bottom: copy-tooltip-bottom,
@@ -368,15 +433,28 @@ let HelixHeadlessObjectInspector = class HelixHeadlessObjectInspector extends He
368
433
  ? this.virtualize.window
369
434
  : { after: 0, before: 0, first: 0, last: rows.length };
370
435
  const shown = rows.slice(first, last);
371
- return html `${this.label ? html `<div part="header"><span part="label">${this.label}</span></div>` : nothing}
436
+ return html `${this.label ? html `<div part="header"><span part="label">${this.label}</span></div>` : nothing}${this.filterable
437
+ ? html `<input
438
+ part="search-field"
439
+ type="search"
440
+ spellcheck="false"
441
+ .value=${this.filter}
442
+ placeholder=${this.filterLabel}
443
+ aria-label=${this.filterLabel}
444
+ aria-controls="tree"
445
+ @input=${this.handleFilterInput}
446
+ @keydown=${this.handleFilterKeydown}
447
+ />`
448
+ : nothing}
372
449
  <div part="frame">
373
450
  <div
374
451
  part="tree"
452
+ id="tree"
375
453
  role="tree"
376
454
  tabindex="0"
377
455
  ?data-scroller=${this.windowed}
378
456
  aria-label=${this.label || this.treeLabel}
379
- aria-activedescendant=${rows.length > 0 ? `row-${this.active}` : nothing}
457
+ aria-activedescendant=${rows.length > 0 ? `row-${this.cursor}` : nothing}
380
458
  @keydown=${this.handleKeydown}
381
459
  @scroll=${() => this.virtualize.measure()}
382
460
  >
@@ -384,10 +462,14 @@ let HelixHeadlessObjectInspector = class HelixHeadlessObjectInspector extends He
384
462
  ${shown.map((row, at) => this.renderRow(row, first + at))}
385
463
  ${this.windowed ? html `<div part="after" role="presentation" style="block-size: ${after}px"></div>` : nothing}
386
464
  </div>
387
- ${this.noCopy ? nothing : this.renderCopyButton(rows[this.active])}
388
- </div>`;
465
+ ${this.noCopy ? nothing : this.renderCopyButton(rows[this.cursor])}
466
+ </div>
467
+ ${drawStatus(this.status)}`;
389
468
  }
390
469
  };
470
+ __decorate([
471
+ property()
472
+ ], HelixHeadlessObjectInspector.prototype, "active", null);
391
473
  __decorate([
392
474
  property({ attribute: 'copy-label' })
393
475
  ], HelixHeadlessObjectInspector.prototype, "copyLabel", void 0);
@@ -397,6 +479,18 @@ __decorate([
397
479
  __decorate([
398
480
  property({ attribute: 'default-depth', type: Number })
399
481
  ], HelixHeadlessObjectInspector.prototype, "defaultDepth", void 0);
482
+ __decorate([
483
+ property({ attribute: false })
484
+ ], HelixHeadlessObjectInspector.prototype, "expanded", null);
485
+ __decorate([
486
+ property()
487
+ ], HelixHeadlessObjectInspector.prototype, "filter", void 0);
488
+ __decorate([
489
+ property({ type: Boolean })
490
+ ], HelixHeadlessObjectInspector.prototype, "filterable", void 0);
491
+ __decorate([
492
+ property({ attribute: 'filter-label' })
493
+ ], HelixHeadlessObjectInspector.prototype, "filterLabel", void 0);
400
494
  __decorate([
401
495
  property()
402
496
  ], HelixHeadlessObjectInspector.prototype, "for", void 0);
@@ -418,6 +512,12 @@ __decorate([
418
512
  __decorate([
419
513
  property({ attribute: 'no-copy', type: Boolean })
420
514
  ], HelixHeadlessObjectInspector.prototype, "noCopy", void 0);
515
+ __decorate([
516
+ property({ attribute: 'result-label' })
517
+ ], HelixHeadlessObjectInspector.prototype, "resultLabel", void 0);
518
+ __decorate([
519
+ property({ attribute: 'results-label' })
520
+ ], HelixHeadlessObjectInspector.prototype, "resultsLabel", void 0);
421
521
  __decorate([
422
522
  property({ attribute: 'tree-label' })
423
523
  ], HelixHeadlessObjectInspector.prototype, "treeLabel", void 0);
@@ -435,7 +535,7 @@ __decorate([
435
535
  ], HelixHeadlessObjectInspector.prototype, "opened", void 0);
436
536
  __decorate([
437
537
  state()
438
- ], HelixHeadlessObjectInspector.prototype, "active", void 0);
538
+ ], HelixHeadlessObjectInspector.prototype, "cursor", void 0);
439
539
  HelixHeadlessObjectInspector = HelixHeadlessObjectInspector_1 = __decorate([
440
540
  customElement('helix-headless-object-inspector')
441
541
  ], HelixHeadlessObjectInspector);