@fusion.dev/helix-headless 0.146.0 → 0.148.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 (288) hide show
  1. package/custom-elements.json +9287 -1084
  2. package/dist/accordion/item/accordion-item.d.ts +43 -21
  3. package/dist/accordion/item/accordion-item.js +37 -11
  4. package/dist/accordion/root/accordion-root.d.ts +8 -2
  5. package/dist/accordion/root/accordion-root.js +6 -8
  6. package/dist/announcement/root/announcement-root.d.ts +66 -6
  7. package/dist/announcement/root/announcement-root.js +144 -13
  8. package/dist/area-chart/root/area-chart-root.d.ts +18 -1
  9. package/dist/area-chart/root/area-chart-root.js +14 -7
  10. package/dist/avatar/root/avatar-root.d.ts +31 -1
  11. package/dist/avatar/root/avatar-root.js +11 -1
  12. package/dist/badge/count.d.ts +14 -0
  13. package/dist/badge/count.js +20 -0
  14. package/dist/badge/root/badge-root.d.ts +57 -6
  15. package/dist/badge/root/badge-root.js +77 -8
  16. package/dist/bar-chart/root/bar-chart-root.js +11 -20
  17. package/dist/bar-chart/stack.d.ts +10 -0
  18. package/dist/bar-chart/stack.js +8 -0
  19. package/dist/blockquote/root/blockquote-root.d.ts +66 -8
  20. package/dist/blockquote/root/blockquote-root.js +85 -8
  21. package/dist/breadcrumbs/breadcrumb/breadcrumb.d.ts +14 -0
  22. package/dist/breadcrumbs/breadcrumb/breadcrumb.js +12 -2
  23. package/dist/breadcrumbs/root/breadcrumbs-root.js +2 -2
  24. package/dist/button/root/button-root.d.ts +24 -38
  25. package/dist/button/root/button-root.js +6 -37
  26. package/dist/button/submitter.d.ts +27 -0
  27. package/dist/button/submitter.js +25 -0
  28. package/dist/button-group/arrows.d.ts +14 -0
  29. package/dist/button-group/arrows.js +10 -0
  30. package/dist/button-group/root/button-group-root.d.ts +141 -3
  31. package/dist/button-group/root/button-group-root.js +142 -2
  32. package/dist/canvas/edge-pan.d.ts +61 -0
  33. package/dist/canvas/edge-pan.js +63 -0
  34. package/dist/canvas/node/canvas-node.d.ts +12 -2
  35. package/dist/canvas/node/canvas-node.js +6 -2
  36. package/dist/canvas/root/canvas-document.d.ts +10 -0
  37. package/dist/canvas/root/canvas-document.js +1 -0
  38. package/dist/canvas/root/canvas-root.d.ts +107 -5
  39. package/dist/canvas/root/canvas-root.js +140 -36
  40. package/dist/canvas/snap.d.ts +42 -0
  41. package/dist/canvas/snap.js +32 -0
  42. package/dist/card/root/card-root.d.ts +12 -1
  43. package/dist/card/root/card-root.js +11 -4
  44. package/dist/carousel/root/carousel-root.d.ts +4 -3
  45. package/dist/carousel/root/carousel-root.js +2 -6
  46. package/dist/chat/root/chat-root.d.ts +28 -4
  47. package/dist/chat/root/chat-root.js +12 -7
  48. package/dist/checkbox/root/checkbox-root.js +5 -7
  49. package/dist/checkbox-group/root/checkbox-group-root.d.ts +13 -0
  50. package/dist/checkbox-group/root/checkbox-group-root.js +16 -7
  51. package/dist/checkbox-group/select-all.d.ts +9 -4
  52. package/dist/checkbox-group/select-all.js +1 -1
  53. package/dist/code-block/root/code-block-root.d.ts +41 -18
  54. package/dist/code-block/root/code-block-root.js +21 -6
  55. package/dist/color-input/root/color-input-root.d.ts +11 -0
  56. package/dist/color-input/root/color-input-root.js +12 -5
  57. package/dist/color-picker/channels.js +1 -2
  58. package/dist/color-picker/root/color-picker-root.d.ts +32 -24
  59. package/dist/color-picker/root/color-picker-root.js +99 -55
  60. package/dist/color-picker/wheel.d.ts +28 -0
  61. package/dist/color-picker/wheel.js +15 -0
  62. package/dist/combobox/root/combobox-root.d.ts +83 -11
  63. package/dist/combobox/root/combobox-root.js +81 -18
  64. package/dist/command/root/command-root.d.ts +7 -4
  65. package/dist/command/root/command-root.js +2 -19
  66. package/dist/copy-button/root/copy-button-root.d.ts +16 -1
  67. package/dist/copy-button/root/copy-button-root.js +7 -2
  68. package/dist/data-table/keys.d.ts +0 -18
  69. package/dist/data-table/keys.js +1 -11
  70. package/dist/data-table/root/data-table-root.js +29 -50
  71. package/dist/date-input/root/date-input-root.d.ts +8 -1
  72. package/dist/date-input/root/date-input-root.js +8 -5
  73. package/dist/date-picker/root/date-picker-root.d.ts +14 -9
  74. package/dist/date-picker/root/date-picker-root.js +21 -16
  75. package/dist/description-list/item/description-list-item.d.ts +22 -4
  76. package/dist/description-list/item/description-list-item.js +14 -4
  77. package/dist/divider/root/divider-root.d.ts +45 -16
  78. package/dist/divider/root/divider-root.js +28 -4
  79. package/dist/donut-chart/root/donut-chart-root.js +13 -6
  80. package/dist/donut-chart/slice-label.d.ts +35 -0
  81. package/dist/donut-chart/slice-label.js +11 -0
  82. package/dist/drawer/root/drawer-root.d.ts +4 -2
  83. package/dist/drawer/root/drawer-root.js +15 -3
  84. package/dist/drilldown/item/drilldown-item.d.ts +21 -1
  85. package/dist/drilldown/item/drilldown-item.js +38 -4
  86. package/dist/drilldown/root/drilldown-root.js +3 -2
  87. package/dist/element-events.generated.js +5 -1
  88. package/dist/empty/root/empty-root.d.ts +46 -2
  89. package/dist/empty/root/empty-root.js +50 -5
  90. package/dist/file-input/root/file-input-root.d.ts +34 -6
  91. package/dist/file-input/root/file-input-root.js +55 -21
  92. package/dist/file-input/status.d.ts +24 -0
  93. package/dist/file-input/status.js +11 -0
  94. package/dist/filter-input/chip/filter-chip.d.ts +23 -0
  95. package/dist/filter-input/chip/filter-chip.js +10 -2
  96. package/dist/filter-input/root/filter-input-root.d.ts +8 -0
  97. package/dist/filter-input/root/filter-input-root.js +17 -27
  98. package/dist/format-date/fields.d.ts +20 -0
  99. package/dist/format-date/fields.js +14 -0
  100. package/dist/format-date/options.d.ts +5 -5
  101. package/dist/format-date/options.js +10 -39
  102. package/dist/format-date/root/format-date-root.d.ts +53 -4
  103. package/dist/format-date/root/format-date-root.js +38 -50
  104. package/dist/graph/root/graph-root.d.ts +23 -5
  105. package/dist/graph/root/graph-root.js +17 -20
  106. package/dist/heatmap/root/buckets.d.ts +21 -0
  107. package/dist/heatmap/root/buckets.js +34 -0
  108. package/dist/heatmap/root/heatmap-root.d.ts +76 -3
  109. package/dist/heatmap/root/heatmap-root.js +105 -20
  110. package/dist/icon/index.d.ts +1 -1
  111. package/dist/icon/index.js +1 -1
  112. package/dist/icon/registry.d.ts +26 -1
  113. package/dist/icon/registry.js +12 -1
  114. package/dist/icon/root/icon-root.d.ts +13 -0
  115. package/dist/icon/root/icon-root.js +23 -2
  116. package/dist/icon/root/index.d.ts +1 -1
  117. package/dist/icon/root/index.js +1 -1
  118. package/dist/image/root/image-root.d.ts +20 -0
  119. package/dist/image/root/image-root.js +6 -1
  120. package/dist/input/root/input-root.d.ts +23 -2
  121. package/dist/input/root/input-root.js +12 -8
  122. package/dist/kbd/root/kbd-root.d.ts +20 -3
  123. package/dist/kbd/root/kbd-root.js +23 -50
  124. package/dist/legend/hidden-series.d.ts +10 -2
  125. package/dist/legend/hidden-series.js +5 -2
  126. package/dist/legend/root/legend-root.d.ts +25 -7
  127. package/dist/legend/root/legend-root.js +25 -26
  128. package/dist/lightbox/root/lightbox-root.d.ts +50 -5
  129. package/dist/lightbox/root/lightbox-root.js +76 -8
  130. package/dist/lightbox/zoom.d.ts +2 -0
  131. package/dist/lightbox/zoom.js +5 -3
  132. package/dist/line-chart/root/line-chart-root.d.ts +16 -0
  133. package/dist/line-chart/root/line-chart-root.js +10 -2
  134. package/dist/list/root/list-root.d.ts +10 -2
  135. package/dist/list/root/list-root.js +31 -24
  136. package/dist/list/selection.d.ts +17 -0
  137. package/dist/list/selection.js +16 -0
  138. package/dist/listbox/root/listbox-root.d.ts +125 -26
  139. package/dist/listbox/root/listbox-root.js +156 -166
  140. package/dist/map/marker/map-marker.d.ts +2 -1
  141. package/dist/map/root/map-root.d.ts +40 -2
  142. package/dist/map/root/map-root.js +64 -23
  143. package/dist/megamenu/hand-over.d.ts +75 -0
  144. package/dist/megamenu/hand-over.js +67 -0
  145. package/dist/megamenu/root/megamenu-root.d.ts +38 -14
  146. package/dist/megamenu/root/megamenu-root.js +29 -50
  147. package/dist/menu/item/menu-item.js +4 -4
  148. package/dist/menu/root/menu-root.d.ts +5 -2
  149. package/dist/meter/root/meter-root.d.ts +42 -0
  150. package/dist/meter/root/meter-root.js +33 -7
  151. package/dist/navigation/root/navigation-root.js +5 -8
  152. package/dist/notifications/group/notification-group.d.ts +8 -1
  153. package/dist/notifications/group/notification-group.js +12 -6
  154. package/dist/notifications/notification/notification.d.ts +12 -1
  155. package/dist/notifications/notification/notification.js +3 -1
  156. package/dist/notifications/root/notifications-root.d.ts +48 -3
  157. package/dist/notifications/root/notifications-root.js +36 -6
  158. package/dist/number-input/grain.d.ts +28 -0
  159. package/dist/number-input/grain.js +14 -0
  160. package/dist/number-input/root/number-input-root.d.ts +17 -1
  161. package/dist/number-input/root/number-input-root.js +29 -18
  162. package/dist/object-inspector/root/object-inspector-root.d.ts +17 -6
  163. package/dist/object-inspector/root/object-inspector-root.js +31 -20
  164. package/dist/option/index.d.ts +1 -0
  165. package/dist/option/index.js +1 -0
  166. package/dist/option/separator/option-separator.d.ts +30 -0
  167. package/dist/option/separator/option-separator.js +21 -0
  168. package/dist/outline/root/outline-root.d.ts +12 -0
  169. package/dist/outline/root/outline-root.js +5 -19
  170. package/dist/pagination/size/pagination-size.d.ts +6 -0
  171. package/dist/pagination/size/pagination-size.js +5 -3
  172. package/dist/pin-input/code.d.ts +51 -1
  173. package/dist/pin-input/code.js +37 -0
  174. package/dist/pin-input/root/pin-input-root.d.ts +98 -121
  175. package/dist/pin-input/root/pin-input-root.js +151 -156
  176. package/dist/popover/hide-outside.js +2 -9
  177. package/dist/popover/root/popover-root.d.ts +7 -1
  178. package/dist/popover/root/popover-root.js +9 -1
  179. package/dist/progress/root/progress-root.d.ts +27 -0
  180. package/dist/progress/root/progress-root.js +25 -7
  181. package/dist/qr-code/export.d.ts +19 -0
  182. package/dist/qr-code/export.js +14 -0
  183. package/dist/qr-code/name.d.ts +11 -0
  184. package/dist/qr-code/name.js +7 -0
  185. package/dist/qr-code/root/qr-code-root.d.ts +31 -9
  186. package/dist/qr-code/root/qr-code-root.js +29 -17
  187. package/dist/radio/group/radio-group.d.ts +15 -0
  188. package/dist/radio/root/radio-root.js +2 -2
  189. package/dist/rating/root/rating-root.d.ts +22 -9
  190. package/dist/rating/root/rating-root.js +15 -39
  191. package/dist/scatter-chart/measures.d.ts +22 -0
  192. package/dist/scatter-chart/measures.js +11 -0
  193. package/dist/scatter-chart/root/scatter-chart-root.d.ts +26 -0
  194. package/dist/scatter-chart/root/scatter-chart-root.js +21 -7
  195. package/dist/scroll-area/scrollbar.d.ts +0 -8
  196. package/dist/scroll-area/scrollbar.js +1 -1
  197. package/dist/select/align.d.ts +47 -0
  198. package/dist/select/align.js +7 -0
  199. package/dist/select/root/select-root.d.ts +115 -11
  200. package/dist/select/root/select-root.js +104 -20
  201. package/dist/slider/root/slider-root.d.ts +18 -1
  202. package/dist/slider/root/slider-root.js +22 -0
  203. package/dist/sparkline/readings.d.ts +30 -12
  204. package/dist/sparkline/readings.js +32 -15
  205. package/dist/sparkline/root/sparkline-root.d.ts +46 -3
  206. package/dist/sparkline/root/sparkline-root.js +60 -21
  207. package/dist/speed-dial/group/speed-dial-group.d.ts +48 -0
  208. package/dist/speed-dial/group/speed-dial-group.js +43 -0
  209. package/dist/speed-dial/index.d.ts +1 -0
  210. package/dist/speed-dial/index.js +1 -0
  211. package/dist/speed-dial/item/speed-dial-item.d.ts +27 -2
  212. package/dist/speed-dial/item/speed-dial-item.js +43 -5
  213. package/dist/speed-dial/long-press.d.ts +50 -0
  214. package/dist/speed-dial/long-press.js +48 -0
  215. package/dist/speed-dial/root/speed-dial-root.d.ts +86 -1
  216. package/dist/speed-dial/root/speed-dial-root.js +123 -6
  217. package/dist/splitter/root/splitter-root.d.ts +9 -2
  218. package/dist/splitter/root/splitter-root.js +18 -3
  219. package/dist/steps/root/steps-root.d.ts +8 -1
  220. package/dist/steps/root/steps-root.js +6 -1
  221. package/dist/steps/step/step.d.ts +1 -0
  222. package/dist/steps/step/step.js +1 -1
  223. package/dist/table/cell/table-cell.d.ts +8 -1
  224. package/dist/table/cell/table-cell.js +6 -2
  225. package/dist/table/column/table-column.d.ts +6 -0
  226. package/dist/table/column/table-column.js +5 -1
  227. package/dist/table/grid-controller.d.ts +117 -0
  228. package/dist/table/grid-controller.js +293 -0
  229. package/dist/table/root/table-root.d.ts +47 -3
  230. package/dist/table/root/table-root.js +93 -29
  231. package/dist/table/row/table-row.d.ts +36 -0
  232. package/dist/table/row/table-row.js +52 -2
  233. package/dist/tabs/root/tabs-root.d.ts +5 -3
  234. package/dist/tag/group/tag-group.d.ts +16 -4
  235. package/dist/tag/group/tag-group.js +23 -20
  236. package/dist/textarea/root/textarea-root.d.ts +14 -2
  237. package/dist/textarea/root/textarea-root.js +6 -7
  238. package/dist/time-input/root/time-input-root.d.ts +5 -1
  239. package/dist/time-input/root/time-input-root.js +10 -7
  240. package/dist/time-picker/root/time-picker-root.d.ts +12 -14
  241. package/dist/time-picker/root/time-picker-root.js +18 -23
  242. package/dist/toast/item/toast-item.d.ts +9 -6
  243. package/dist/toast/item/toast-item.js +1 -1
  244. package/dist/toast/root/toast-root.d.ts +40 -4
  245. package/dist/toast/root/toast-root.js +68 -16
  246. package/dist/toast/words.d.ts +12 -0
  247. package/dist/toast/words.js +25 -0
  248. package/dist/toggle/group/toggle-group.d.ts +29 -5
  249. package/dist/toggle/group/toggle-group.js +26 -43
  250. package/dist/toggle/root/toggle-root.js +2 -4
  251. package/dist/toolbar/root/toolbar-root.d.ts +52 -5
  252. package/dist/toolbar/root/toolbar-root.js +88 -13
  253. package/dist/tooltip/root/tooltip-root.d.ts +7 -1
  254. package/dist/tooltip/root/tooltip-root.js +10 -2
  255. package/dist/tour/root/tour-root.d.ts +15 -0
  256. package/dist/tour/root/tour-root.js +20 -1
  257. package/dist/tour/stop/tour-stop.d.ts +3 -0
  258. package/dist/tour/stop/tour-stop.js +3 -3
  259. package/dist/tree/root/tree-root.js +2 -2
  260. package/dist/trend/figure.d.ts +16 -0
  261. package/dist/trend/figure.js +8 -0
  262. package/dist/trend/root/trend-root.d.ts +41 -2
  263. package/dist/trend/root/trend-root.js +29 -3
  264. package/dist/video/root/extra-controls.d.ts +12 -0
  265. package/dist/video/root/extra-controls.js +6 -2
  266. package/dist/video/root/video-root.d.ts +16 -1
  267. package/dist/video/root/video-root.js +15 -1
  268. package/dist/video-playlist/root/video-playlist-root.d.ts +11 -1
  269. package/dist/video-playlist/root/video-playlist-root.js +3 -0
  270. package/dist/virtual-list/fill.d.ts +11 -0
  271. package/dist/virtual-list/fill.js +9 -0
  272. package/dist/virtual-list/keys.d.ts +16 -7
  273. package/dist/virtual-list/keys.js +17 -6
  274. package/dist/virtual-list/plan.d.ts +17 -1
  275. package/dist/virtual-list/plan.js +13 -2
  276. package/dist/virtual-list/root/virtual-list-root.d.ts +25 -3
  277. package/dist/virtual-list/root/virtual-list-root.js +53 -41
  278. package/lint.json +1 -1
  279. package/package.json +5 -5
  280. package/types/jsx.d.ts +4934 -954
  281. package/types/svelte.d.ts +2 -0
  282. package/types/vue.d.ts +946 -253
  283. package/dist/color-picker/swatches.d.ts +0 -12
  284. package/dist/color-picker/swatches.js +0 -26
  285. package/dist/rating/steps.d.ts +0 -7
  286. package/dist/rating/steps.js +0 -9
  287. package/dist/tooltip/focus-target.d.ts +0 -6
  288. package/dist/tooltip/focus-target.js +0 -9
@@ -1,3 +1,17 @@
1
+ export const boxIn = (rect, area, box) => {
2
+ const scale = box / area.width;
3
+ return [
4
+ (rect.left - area.left) * scale,
5
+ (rect.top - area.top) * scale,
6
+ rect.width * scale,
7
+ rect.height * scale,
8
+ ];
9
+ };
10
+ export const logoBox = (rect, area, box) => {
11
+ const frame = boxIn(rect, area, box);
12
+ const [x, y, width, height] = frame;
13
+ return x < 0 || y < 0 || x + width > box || y + height > box ? undefined : frame;
14
+ };
1
15
  const attribute = (value) => value.replace(/&/g, '&amp;').replace(/"/g, '&quot;').replace(/</g, '&lt;');
2
16
  const unit = (value) => String(Math.round(value * 100) / 100);
3
17
  const placed = ([x, y, width, height]) => `x="${unit(x)}" y="${unit(y)}" width="${unit(width)}" height="${unit(height)}"`;
@@ -0,0 +1,11 @@
1
+ /**
2
+ * The name a code is read by: its `label`, or with none, the word for a code,
3
+ * followed by the value where the value is a web address.
4
+ *
5
+ * **A value that is no web address is never read out.** A code that sets up
6
+ * an authenticator (`otpauth://…?secret=…`) or joins a network
7
+ * (`WIFI:…;P:…;;`) carries a secret in its value, and the value as the name
8
+ * read that secret aloud to anyone in earshot. A web address is what a
9
+ * sighted reader gets by scanning, so it is said after the word.
10
+ */
11
+ export declare const qrName: (label: string, value: string, word: string) => string;
@@ -0,0 +1,7 @@
1
+ export const qrName = (label, value, word) => {
2
+ if (label.trim() !== '') {
3
+ return label;
4
+ }
5
+ const address = value.trim();
6
+ return /^https?:\/\/\S+$/iu.test(address) ? `${word}, ${address}` : word;
7
+ };
@@ -13,9 +13,12 @@ export type QrStyle = 'dots' | 'rounded' | 'square';
13
13
  * thousand modules, and an element for each would be a thousand nodes for one
14
14
  * image.
15
15
  *
16
- * The element has `role="img"` and an accessible name. Set the name to what the
17
- * code is for. When you pass no name, the value is the name. Most codes hold a
18
- * URL, and a URL read aloud gives the destination.
16
+ * The element has `role="img"` and an accessible name. Set `label` to what
17
+ * the code is for, such as "Open the menu". With no `label`, a code is named
18
+ * by `code-label`, "QR code", followed by its value where the value is a web
19
+ * address, which a URL read aloud makes a destination. Any other value is
20
+ * never read out: a code that sets up an authenticator or joins a network
21
+ * carries a secret in it.
19
22
  *
20
23
  * The quiet zone of four modules is required by the specification, and a
21
24
  * scanner rejects a code cropped to its edge. It is drawn inside the `viewBox`,
@@ -24,7 +27,8 @@ export type QrStyle = 'dots' | 'rounded' | 'square';
24
27
  * `correction` sets how much of the code can be lost. At `H` a code can lose
25
28
  * thirty percent and still scan, so a mark in the center slot is safe. At `L`
26
29
  * the same mark makes the code unscannable. The default is `M`, and `H` when the
27
- * `logo` slot is filled.
30
+ * `logo` slot is filled. A code that holds a logo at a `correction` below `H`
31
+ * warns once with the kind `unscannable-logo`.
28
32
  *
29
33
  * A higher level holds fewer characters, so a value that fits at `M` can be too
30
34
  * long once a logo raises the level to `H`. A value too long for the level
@@ -34,7 +38,8 @@ export type QrStyle = 'dots' | 'rounded' | 'square';
34
38
  * `toSvg()`, `toPng()` and `download()` give the drawn code as a file of its
35
39
  * own, in the colors it is drawn in, with a slotted image or SVG logo where
36
40
  * it sits, for a page that offers it to save or print, as Zag's download
37
- * trigger does.
41
+ * trigger does. `download()` saves an SVG for a name ending in `.svg`, and a
42
+ * PNG for any other.
38
43
  *
39
44
  * @since 0.1.0
40
45
  * @status stable
@@ -56,6 +61,11 @@ export type QrStyle = 'dots' | 'rounded' | 'square';
56
61
  * @cssstate overflow - The value is too long for a code at the correction level, so the fallback shows.
57
62
  */
58
63
  export declare class HelixHeadlessQrCode extends HelixElement {
64
+ /**
65
+ * The words a code with no `label` is named by, followed by its value where
66
+ * the value is a web address.
67
+ */
68
+ codeLabel: string;
59
69
  /**
60
70
  * The error correction level, which sets how much of the code can be lost
61
71
  * and still scan.
@@ -68,10 +78,13 @@ export declare class HelixHeadlessQrCode extends HelixElement {
68
78
  */
69
79
  correction?: QrCorrection;
70
80
  /**
71
- * The image's accessible name.
81
+ * The image's accessible name: what the code is for, such as "Open the
82
+ * menu".
72
83
  *
73
- * Falling back to the value is deliberate: a code almost always holds a URL,
74
- * and a URL is a better name than "QR code" for a reader who cannot see it.
84
+ * Absent names it by `code-label` and, for a web address, the address,
85
+ * which is what a reader who cannot scan it needs. Any other value is left
86
+ * out of the name, since it may hold a secret, such as an authenticator's
87
+ * key or a network's password.
75
88
  */
76
89
  label: string;
77
90
  /**
@@ -100,6 +113,14 @@ export declare class HelixHeadlessQrCode extends HelixElement {
100
113
  protected firstUpdated(changed: PropertyValues): void;
101
114
  /** The level actually used, which the slot can raise. */
102
115
  private get level();
116
+ /** Whether this code has warned that its logo may keep it from scanning. */
117
+ private toldLogo;
118
+ /**
119
+ * Warns once when a logo covers a code whose level was set below `H`, where
120
+ * the cover can take more than the level can lose. A level the code chose
121
+ * itself is `H` already.
122
+ */
123
+ private auditLogo;
103
124
  /** The value and level that did not fit, so `error` fires once for each. */
104
125
  private overflowed;
105
126
  /**
@@ -137,7 +158,8 @@ export declare class HelixHeadlessQrCode extends HelixElement {
137
158
  */
138
159
  toPng(size?: number): Promise<Blob | null>;
139
160
  /**
140
- * Saves the code as a PNG named `filename`, `size` pixels square.
161
+ * Saves the code as a file named `filename`, `size` pixels square: an SVG
162
+ * where the name ends in `.svg`, and a PNG otherwise.
141
163
  *
142
164
  * Call it from a press, since a browser lets a page start a download only
143
165
  * in answer to one. Does nothing where no code is drawn.
@@ -4,11 +4,12 @@ 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, rgbOf } from '@fusion.dev/helix-core';
7
+ import { customElement, HelixElement, reportRuntime, rgbOf, slotFilled, } from '@fusion.dev/helix-core';
8
8
  import { html, nothing, svg, } from 'lit';
9
9
  import { property } from 'lit/decorators.js';
10
10
  import { encode } from 'uqr';
11
- import { qrSvg } from '../export.js';
11
+ import { boxIn, logoBox, qrSvg } from '../export.js';
12
+ import { qrName } from '../name.js';
12
13
  const QUIET = 4;
13
14
  const pixelsOf = (image) => {
14
15
  try {
@@ -76,9 +77,11 @@ const pathFor = (matrix, style, only = 'all') => {
76
77
  let HelixHeadlessQrCode = class HelixHeadlessQrCode extends HelixElement {
77
78
  constructor() {
78
79
  super(...arguments);
80
+ this.codeLabel = 'QR code';
79
81
  this.label = '';
80
82
  this.value = '';
81
83
  this.logo = false;
84
+ this.toldLogo = false;
82
85
  this.overflowed = '';
83
86
  }
84
87
  willUpdate(changed) {
@@ -94,6 +97,17 @@ let HelixHeadlessQrCode = class HelixHeadlessQrCode extends HelixElement {
94
97
  get level() {
95
98
  return this.correction ?? (this.logo ? 'H' : 'M');
96
99
  }
100
+ auditLogo() {
101
+ if (this.toldLogo || !this.logo || (this.correction ?? 'H') === 'H') {
102
+ return;
103
+ }
104
+ this.toldLogo = true;
105
+ reportRuntime({
106
+ kind: 'unscannable-logo',
107
+ message: `<${this.localName}> holds a logo at correction "${this.correction}", which may keep it from scanning. Set \`correction\` to "H", or leave it unset.`,
108
+ tag: this.localName,
109
+ });
110
+ }
97
111
  encoded() {
98
112
  try {
99
113
  return encode(this.value, { border: 0, ecc: this.level });
@@ -107,6 +121,7 @@ let HelixHeadlessQrCode = class HelixHeadlessQrCode extends HelixElement {
107
121
  }
108
122
  updated(changed) {
109
123
  super.updated(changed);
124
+ this.auditLogo();
110
125
  const key = `${this.level}:${this.value}`;
111
126
  const overflow = this.value !== '' && this.encoded() === undefined;
112
127
  this.toggleState('overflow', overflow);
@@ -150,15 +165,8 @@ let HelixHeadlessQrCode = class HelixHeadlessQrCode extends HelixElement {
150
165
  if (!holder || holder.hidden || !mark || area.width === 0) {
151
166
  return undefined;
152
167
  }
153
- const scale = box / area.width;
154
- const at = (rect) => [
155
- (rect.left - area.left) * scale,
156
- (rect.top - area.top) * scale,
157
- rect.width * scale,
158
- rect.height * scale,
159
- ];
160
- const frame = at(holder.getBoundingClientRect());
161
- if (frame[0] < 0 || frame[1] < 0 || frame[0] + frame[2] > box || frame[1] + frame[3] > box) {
168
+ const frame = logoBox(holder.getBoundingClientRect(), area, box);
169
+ if (!frame) {
162
170
  return undefined;
163
171
  }
164
172
  const fill = getComputedStyle(holder).backgroundColor;
@@ -166,7 +174,7 @@ let HelixHeadlessQrCode = class HelixHeadlessQrCode extends HelixElement {
166
174
  const logo = {
167
175
  frame,
168
176
  ground: ground ? background : rgbOf(fill),
169
- mark: at(mark.getBoundingClientRect()),
177
+ mark: boxIn(mark.getBoundingClientRect(), area, box),
170
178
  };
171
179
  if (mark instanceof HTMLImageElement) {
172
180
  return { ...logo, href: pixelsOf(mark) };
@@ -191,11 +199,12 @@ let HelixHeadlessQrCode = class HelixHeadlessQrCode extends HelixElement {
191
199
  return new Promise((resolve) => canvas.toBlob(resolve, 'image/png'));
192
200
  }
193
201
  async download(filename = 'qr-code.png', size = 512) {
194
- const png = await this.toPng(size);
195
- if (!png) {
202
+ const svg = /\.svg$/i.test(filename) ? this.toSvg(size) : '';
203
+ const file = svg ? new Blob([svg], { type: 'image/svg+xml' }) : await this.toPng(size);
204
+ if (!file) {
196
205
  return;
197
206
  }
198
- const url = URL.createObjectURL(png);
207
+ const url = URL.createObjectURL(file);
199
208
  const link = document.createElement('a');
200
209
  link.href = url;
201
210
  link.download = filename;
@@ -215,7 +224,7 @@ let HelixHeadlessQrCode = class HelixHeadlessQrCode extends HelixElement {
215
224
  viewBox="0 0 ${box} ${box}"
216
225
  xmlns="http://www.w3.org/2000/svg"
217
226
  role="img"
218
- aria-label=${this.label || this.value}
227
+ aria-label=${qrName(this.label, this.value, this.codeLabel)}
219
228
  shape-rendering="crispEdges"
220
229
  >
221
230
  <path
@@ -240,7 +249,7 @@ let HelixHeadlessQrCode = class HelixHeadlessQrCode extends HelixElement {
240
249
  <slot
241
250
  name="logo"
242
251
  @slotchange=${(event) => {
243
- const next = event.target.assignedNodes().length > 0;
252
+ const next = slotFilled(event.target);
244
253
  if (next !== this.logo) {
245
254
  this.logo = next;
246
255
  this.requestUpdate();
@@ -250,6 +259,9 @@ let HelixHeadlessQrCode = class HelixHeadlessQrCode extends HelixElement {
250
259
  </span>`;
251
260
  }
252
261
  };
262
+ __decorate([
263
+ property({ attribute: 'code-label' })
264
+ ], HelixHeadlessQrCode.prototype, "codeLabel", void 0);
253
265
  __decorate([
254
266
  property({ attribute: 'correction' })
255
267
  ], HelixHeadlessQrCode.prototype, "correction", void 0);
@@ -30,6 +30,21 @@ declare const HelixHeadlessRadioGroup_base: (new (...args: any[]) => import("@fu
30
30
  * `helix-select`. A native radio sends `input` and `change` in the same task as
31
31
  * the click.
32
32
  *
33
+ * **Keyboard.** The group is one tab stop: the chosen radio, or the first that
34
+ * can be chosen.
35
+ *
36
+ * | Key | What it does |
37
+ * |---|---|
38
+ * | Right, Down | Chooses the next radio, from the last back to the first. |
39
+ * | Left, Up | Chooses the radio before, from the first round to the last. |
40
+ * | Home, End | Chooses the first or the last radio. |
41
+ * | Space, Enter | Chooses the focused radio. |
42
+ *
43
+ * Left and Right swap on a right-to-left page, and a disabled radio is passed
44
+ * over. Under `readonly` the arrows move focus and choose nothing. The group
45
+ * is a `radiogroup` named by `label`, and each radio is a `role="radio"`
46
+ * button with `aria-checked`.
47
+ *
33
48
  * @since 0.1.0
34
49
  * @status stable
35
50
  * @aliases RadioButtons, Choice group
@@ -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, HostClickController, MixinSelectableItem, } from '@fusion.dev/helix-core';
7
+ import { customElement, HelixElement, HostClickController, MixinSelectableItem, slotFilled, } from '@fusion.dev/helix-core';
8
8
  import { html } from 'lit';
9
9
  import { property } from 'lit/decorators.js';
10
10
  let HelixHeadlessRadio = class HelixHeadlessRadio extends MixinSelectableItem(HelixElement) {
@@ -35,7 +35,7 @@ let HelixHeadlessRadio = class HelixHeadlessRadio extends MixinSelectableItem(He
35
35
  <span part="box" aria-hidden="true"
36
36
  ><slot
37
37
  name="indicator"
38
- @slotchange=${(event) => this.toggleState('has-indicator', event.target.assignedNodes().length > 0)}
38
+ @slotchange=${(event) => this.toggleState('has-indicator', slotFilled(event.target))}
39
39
  ></slot
40
40
  ></span>
41
41
  <slot name="icon"></slot>
@@ -18,6 +18,20 @@ declare const HelixHeadlessRating_base: (new (...args: any[]) => import("@fusion
18
18
  * With `clearable`, pressing the chosen score again, or Backspace or Delete on
19
19
  * the marks, takes the rating back to unrated and sends `helix-clear`.
20
20
  *
21
+ * **Keyboard.** The marks are one tab stop, on the chosen score or the first.
22
+ *
23
+ * | Key | What it does |
24
+ * |---|---|
25
+ * | Right, Down | Chooses the next score up, and stops at the highest. |
26
+ * | Left, Up | Chooses the next score down, and stops at the lowest. |
27
+ * | Home, End | Chooses the lowest or the highest score. |
28
+ * | Space, Enter | Chooses the focused score, or clears it under `clearable` when it is already chosen. |
29
+ * | Backspace, Delete | Clears the rating, under `clearable`. |
30
+ *
31
+ * Left and Right swap on a right-to-left page. The marks are a `radiogroup`
32
+ * named by `label`, and each score is a `radio` named by `option-label`, such
33
+ * as "3 out of 5". A read-only rating is one `img` named by its score.
34
+ *
21
35
  * @since 0.1.0
22
36
  * @status stable
23
37
  * @category forms
@@ -172,8 +186,8 @@ export declare class HelixHeadlessRating extends HelixHeadlessRating_base {
172
186
  * each of its own options. Anything past the first slotted element is
173
187
  * ignored.
174
188
  */
175
- private markSource;
176
- /** Whether `markSource` has had its first answer from the children. */
189
+ private readonly mark;
190
+ /** Whether `mark` has had its first answer from the children. */
177
191
  private markRead;
178
192
  /**
179
193
  * What the pointer is over, which is shown instead of the score while it is.
@@ -215,18 +229,17 @@ export declare class HelixHeadlessRating extends HelixHeadlessRating_base {
215
229
  /** The pointer drawing a score, while one is. */
216
230
  private dragging;
217
231
  /**
218
- * One clone per place a mark goes, kept so a render does not remake them.
232
+ * The shape for one place, or nothing when the stylesheet is drawing it.
219
233
  *
220
- * A drag renders on every pointer move, and handing Lit a fresh node each
221
- * time would swap every mark in the row on every frame of a gesture whose
222
- * whole point is that only the fill moves.
234
+ * One copy per place, kept so a render does not remake them: a drag renders
235
+ * on every pointer move, and handing Lit a fresh node each time would swap
236
+ * every mark in the row on every frame of a gesture whose whole point is
237
+ * that only the fill moves.
223
238
  */
224
- private readonly clones;
225
- /** The shape for one place, or nothing when the stylesheet is drawing it. */
226
239
  private markFor;
227
240
  private readonly handleMarkSlot;
228
241
  /** The element slotted into `empty-mark`, which the track copies. */
229
- private emptySource;
242
+ private readonly empty;
230
243
  /**
231
244
  * The step under a point on the row, or the nearest one to it.
232
245
  *
@@ -4,10 +4,9 @@ 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 { AriaForwardController, valueAsNumber as asNumber, customElement, fillTemplate, numberAsValue as fromNumber, HelixClearEvent, HelixFormElement, HelixPreviewEvent, KeyboardNavigationController, MixinControllerValue, MixinField, reportRuntime, } from '@fusion.dev/helix-core';
7
+ import { AriaForwardController, valueAsNumber as asNumber, customElement, fillTemplate, numberAsValue as fromNumber, HelixClearEvent, HelixFormElement, HelixPreviewEvent, KeyboardNavigationController, MixinControllerValue, MixinField, nearest, reportRuntime, SlottedGlyph, } from '@fusion.dev/helix-core';
8
8
  import { html, nothing } from 'lit';
9
9
  import { property, state } from 'lit/decorators.js';
10
- import { nearestStep } from '../steps.js';
11
10
  let HelixHeadlessRating = class HelixHeadlessRating extends MixinControllerValue(MixinField(HelixFormElement)) {
12
11
  constructor() {
13
12
  super(...arguments);
@@ -23,7 +22,7 @@ let HelixHeadlessRating = class HelixHeadlessRating extends MixinControllerValue
23
22
  this.aria = new AriaForwardController(this, {
24
23
  target: () => this.partNamed('marks'),
25
24
  });
26
- this.markSource = undefined;
25
+ this.mark = new SlottedGlyph();
27
26
  this.markRead = false;
28
27
  this.previewing = undefined;
29
28
  this.keys = new KeyboardNavigationController(this, {
@@ -32,19 +31,12 @@ let HelixHeadlessRating = class HelixHeadlessRating extends MixinControllerValue
32
31
  wrap: false,
33
32
  });
34
33
  this.dragging = undefined;
35
- this.clones = new Map();
36
34
  this.handleMarkSlot = (event) => {
37
35
  const slot = event.target;
38
- const source = slot.assignedElements({ flatten: true })[0];
39
- this.clones.clear();
40
- if (slot.name === 'empty-mark') {
41
- this.emptySource = source;
42
- }
43
- else {
44
- this.markSource = source;
45
- }
36
+ (slot.name === 'empty-mark' ? this.empty : this.mark).read(slot);
37
+ this.requestUpdate();
46
38
  };
47
- this.emptySource = undefined;
39
+ this.empty = new SlottedGlyph();
48
40
  this.handleDragStart = (event) => {
49
41
  if (this.isDisabled || this.readOnly || event.button !== 0) {
50
42
  return;
@@ -167,21 +159,11 @@ let HelixHeadlessRating = class HelixHeadlessRating extends MixinControllerValue
167
159
  }));
168
160
  }
169
161
  markFor(layer, index) {
170
- const source = layer === 'track' ? (this.emptySource ?? this.markSource) : this.markSource;
171
- if (!source) {
172
- return undefined;
173
- }
174
- const key = `${layer}:${index}`;
175
- const held = this.clones.get(key);
176
- if (held) {
177
- return held;
178
- }
179
- const clone = source.cloneNode(true);
180
- this.clones.set(key, clone);
181
- return clone;
162
+ const glyph = layer === 'track' && this.empty.slotted ? this.empty : this.mark;
163
+ return glyph.copyFor(`${layer}:${index}`);
182
164
  }
183
165
  scoreAt(clientX) {
184
- let nearest;
166
+ let closest;
185
167
  let best = Number.POSITIVE_INFINITY;
186
168
  for (const option of this.renderRoot?.querySelectorAll('[part="option"]') ?? []) {
187
169
  const box = option.getBoundingClientRect();
@@ -191,10 +173,10 @@ let HelixHeadlessRating = class HelixHeadlessRating extends MixinControllerValue
191
173
  const away = clientX < box.left ? box.left - clientX : clientX - box.right;
192
174
  if (away < best) {
193
175
  best = away;
194
- nearest = option.dataset.score;
176
+ closest = option.dataset.score;
195
177
  }
196
178
  }
197
- return nearest;
179
+ return closest;
198
180
  }
199
181
  clearsAt(score) {
200
182
  return this.clearable && this.value !== '' && Number(score) === Number(this.value);
@@ -239,8 +221,8 @@ let HelixHeadlessRating = class HelixHeadlessRating extends MixinControllerValue
239
221
  super.willUpdate(changed);
240
222
  if (!this.markRead && this.childrenKnown) {
241
223
  this.markRead = true;
242
- this.markSource = this.knownChildren.find((child) => child.slot === 'mark');
243
- this.emptySource = this.knownChildren.find((child) => child.slot === 'empty-mark');
224
+ this.mark.take(this.knownChildren.find((child) => child.slot === 'mark'));
225
+ this.empty.take(this.knownChildren.find((child) => child.slot === 'empty-mark'));
244
226
  }
245
227
  }
246
228
  firstUpdated(changed) {
@@ -255,7 +237,7 @@ let HelixHeadlessRating = class HelixHeadlessRating extends MixinControllerValue
255
237
  if (!answered) {
256
238
  return first;
257
239
  }
258
- return nearestStep(this.steps, this.score) ?? first;
240
+ return nearest(this.steps, this.score) ?? first;
259
241
  }
260
242
  render() {
261
243
  const showing = this.previewing ?? this.score;
@@ -276,7 +258,7 @@ let HelixHeadlessRating = class HelixHeadlessRating extends MixinControllerValue
276
258
  aria-describedby=${this.describedBy ?? nothing}
277
259
  aria-invalid=${this.invalidity ?? nothing}
278
260
  aria-required=${this.required && !this.readOnly ? 'true' : nothing}
279
- data-slotted=${this.markSource ? '' : nothing}
261
+ data-slotted=${this.mark.slotted ? '' : nothing}
280
262
  style=${`--rating-full: ${Math.floor(showing)}; --rating-part: ${showing - Math.floor(showing)}; --rating-steps: ${this.positions.length}`}
281
263
  @pointercancel=${this.handleDragCancel}
282
264
  @keydown=${this.handleClearKey}
@@ -299,7 +281,7 @@ let HelixHeadlessRating = class HelixHeadlessRating extends MixinControllerValue
299
281
  <span
300
282
  part="track"
301
283
  aria-hidden="true"
302
- data-slotted=${this.emptySource ? '' : nothing}
284
+ data-slotted=${this.empty.slotted ? '' : nothing}
303
285
  >${marksIn('track')}</span
304
286
  >
305
287
  <span
@@ -367,15 +349,9 @@ __decorate([
367
349
  __decorate([
368
350
  property({ attribute: 'value-text' })
369
351
  ], HelixHeadlessRating.prototype, "valueText", void 0);
370
- __decorate([
371
- state()
372
- ], HelixHeadlessRating.prototype, "markSource", void 0);
373
352
  __decorate([
374
353
  state()
375
354
  ], HelixHeadlessRating.prototype, "previewing", void 0);
376
- __decorate([
377
- state()
378
- ], HelixHeadlessRating.prototype, "emptySource", void 0);
379
355
  HelixHeadlessRating = __decorate([
380
356
  customElement('helix-headless-rating')
381
357
  ], HelixHeadlessRating);
@@ -0,0 +1,22 @@
1
+ /** The numeric columns by what they measure. */
2
+ export interface Measures {
3
+ /** The column across, the first one that is not the size. */
4
+ across: number | undefined;
5
+ /** The column `size-by` names, which sizes the points. */
6
+ size: number | undefined;
7
+ /** Every other column, each a series up. */
8
+ ups: number[];
9
+ }
10
+ /**
11
+ * The numeric columns by what they measure: the column whose heading
12
+ * `sizeBy` names as the size, by its series key, then the first of the rest
13
+ * across and every other one up.
14
+ */
15
+ export declare const measuresOf: (columns: readonly number[], name: (column: number) => string, sizeBy: string) => Measures;
16
+ /**
17
+ * Each row's point size from its reading in the size column, by area, so a
18
+ * point twice the measure is twice the ink: the square root of its share of
19
+ * the largest. A size below zero is none, and a row with no size, or a column
20
+ * whose largest is not above zero, has no weight.
21
+ */
22
+ export declare const bubbleWeights: (sizes: readonly (number | undefined)[]) => (number | undefined)[];
@@ -0,0 +1,11 @@
1
+ import { seriesKey } from '@fusion.dev/helix-core';
2
+ export const measuresOf = (columns, name, sizeBy) => {
3
+ const key = seriesKey(sizeBy);
4
+ const size = key === '' ? undefined : columns.find((column) => seriesKey(name(column)) === key);
5
+ const [across, ...ups] = columns.filter((column) => column !== size);
6
+ return { across, size, ups };
7
+ };
8
+ export const bubbleWeights = (sizes) => {
9
+ const largest = Math.max(0, ...sizes.map((one) => one ?? 0));
10
+ return sizes.map((one) => one === undefined || largest <= 0 ? undefined : Math.sqrt(Math.max(0, one) / largest));
11
+ };
@@ -1,10 +1,16 @@
1
1
  import { HelixElement } from '@fusion.dev/helix-core';
2
2
  import { nothing, type TemplateResult } from 'lit';
3
3
  import '../../tooltip/index.js';
4
+ import { type Measures } from '../measures.js';
4
5
  /** One row drawn as a point: which row, which series, and where, in percent of the plot. */
5
6
  export interface ScatterPoint {
6
7
  depth: number;
7
8
  row: number;
9
+ /**
10
+ * How large the point is drawn under `size-by`, from 0 to 1: the square root
11
+ * of its share of the largest size, so its area follows the measure.
12
+ */
13
+ weight?: number | undefined;
8
14
  x: number;
9
15
  y: number;
10
16
  }
@@ -35,6 +41,11 @@ declare const HelixHeadlessScatterChart_base: typeof HelixElement & (new (...arg
35
41
  * `trend` draws each series' line of best fit, by least squares, across the
36
42
  * plot in the series' color.
37
43
  *
44
+ * **`size-by` names a third measure, drawn as each point's size**, as a bubble
45
+ * chart does: `size-by="Population"` takes that column out of the series and
46
+ * gives each point an area in proportion to its row's number there. The
47
+ * tooltip and the table still say the number.
48
+ *
38
49
  * The summary gives each series' correlation coefficient and its number of
39
50
  * points. The table has every number, and the drawing is hidden from screen
40
51
  * readers.
@@ -94,6 +105,7 @@ declare const HelixHeadlessScatterChart_base: typeof HelixElement & (new (...arg
94
105
  * @csspart y-name - The name of the vertical measure.
95
106
  * @csspart y-tick - One labeled value on the vertical axis.
96
107
  *
108
+ * @cssproperty --chart-point-weight - How large a point is drawn under `size-by`, from 0 to 1, by area. The component writes it, and the stylesheet that sizes the point reads it.
97
109
  * @cssproperty --chart-point-x - A point's horizontal position, as a percentage. The component writes it.
98
110
  * @cssproperty --chart-point-y - A point's vertical position, as a percentage from the top. The component writes it.
99
111
  * @cssproperty --chart-tick - A tick's position along its axis, as a percentage. The component writes it.
@@ -116,6 +128,15 @@ export declare class HelixHeadlessScatterChart extends HelixHeadlessScatterChart
116
128
  * The word the summary uses for a row when it counts them.
117
129
  */
118
130
  pointsLabel: string;
131
+ /**
132
+ * The heading of a column whose numbers size the points, such as
133
+ * `Population`, which makes the chart a bubble chart.
134
+ *
135
+ * That column is then a measure and no series: it draws no points of its
136
+ * own, and each point's area follows its row's number in it. Absent, every
137
+ * point is one size.
138
+ */
139
+ sizeBy: string;
119
140
  /**
120
141
  * Draws each series' line of best fit across the plot, by least squares, in
121
142
  * the series' color: the regression line a reader would otherwise draw by
@@ -148,6 +169,11 @@ export declare class HelixHeadlessScatterChart extends HelixHeadlessScatterChart
148
169
  * which is where a reader is told what it is.
149
170
  */
150
171
  seriesOf(cell: number): number | undefined;
172
+ /**
173
+ * The numeric columns by what they measure: the first across, the column
174
+ * `size-by` names as the size, and every other one up, as a series.
175
+ */
176
+ protected get measures(): Measures;
151
177
  /** Whether the levels across are ruled. */
152
178
  protected get rulesX(): boolean;
153
179
  /** Whether the levels up are ruled. */