@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.
- package/custom-elements.json +9287 -1084
- package/dist/accordion/item/accordion-item.d.ts +43 -21
- package/dist/accordion/item/accordion-item.js +37 -11
- package/dist/accordion/root/accordion-root.d.ts +8 -2
- package/dist/accordion/root/accordion-root.js +6 -8
- package/dist/announcement/root/announcement-root.d.ts +66 -6
- package/dist/announcement/root/announcement-root.js +144 -13
- package/dist/area-chart/root/area-chart-root.d.ts +18 -1
- package/dist/area-chart/root/area-chart-root.js +14 -7
- package/dist/avatar/root/avatar-root.d.ts +31 -1
- package/dist/avatar/root/avatar-root.js +11 -1
- package/dist/badge/count.d.ts +14 -0
- package/dist/badge/count.js +20 -0
- package/dist/badge/root/badge-root.d.ts +57 -6
- package/dist/badge/root/badge-root.js +77 -8
- package/dist/bar-chart/root/bar-chart-root.js +11 -20
- package/dist/bar-chart/stack.d.ts +10 -0
- package/dist/bar-chart/stack.js +8 -0
- package/dist/blockquote/root/blockquote-root.d.ts +66 -8
- package/dist/blockquote/root/blockquote-root.js +85 -8
- package/dist/breadcrumbs/breadcrumb/breadcrumb.d.ts +14 -0
- package/dist/breadcrumbs/breadcrumb/breadcrumb.js +12 -2
- package/dist/breadcrumbs/root/breadcrumbs-root.js +2 -2
- package/dist/button/root/button-root.d.ts +24 -38
- package/dist/button/root/button-root.js +6 -37
- package/dist/button/submitter.d.ts +27 -0
- package/dist/button/submitter.js +25 -0
- package/dist/button-group/arrows.d.ts +14 -0
- package/dist/button-group/arrows.js +10 -0
- package/dist/button-group/root/button-group-root.d.ts +141 -3
- package/dist/button-group/root/button-group-root.js +142 -2
- package/dist/canvas/edge-pan.d.ts +61 -0
- package/dist/canvas/edge-pan.js +63 -0
- package/dist/canvas/node/canvas-node.d.ts +12 -2
- package/dist/canvas/node/canvas-node.js +6 -2
- package/dist/canvas/root/canvas-document.d.ts +10 -0
- package/dist/canvas/root/canvas-document.js +1 -0
- package/dist/canvas/root/canvas-root.d.ts +107 -5
- package/dist/canvas/root/canvas-root.js +140 -36
- package/dist/canvas/snap.d.ts +42 -0
- package/dist/canvas/snap.js +32 -0
- package/dist/card/root/card-root.d.ts +12 -1
- package/dist/card/root/card-root.js +11 -4
- package/dist/carousel/root/carousel-root.d.ts +4 -3
- package/dist/carousel/root/carousel-root.js +2 -6
- package/dist/chat/root/chat-root.d.ts +28 -4
- package/dist/chat/root/chat-root.js +12 -7
- package/dist/checkbox/root/checkbox-root.js +5 -7
- package/dist/checkbox-group/root/checkbox-group-root.d.ts +13 -0
- package/dist/checkbox-group/root/checkbox-group-root.js +16 -7
- package/dist/checkbox-group/select-all.d.ts +9 -4
- package/dist/checkbox-group/select-all.js +1 -1
- package/dist/code-block/root/code-block-root.d.ts +41 -18
- package/dist/code-block/root/code-block-root.js +21 -6
- package/dist/color-input/root/color-input-root.d.ts +11 -0
- package/dist/color-input/root/color-input-root.js +12 -5
- package/dist/color-picker/channels.js +1 -2
- package/dist/color-picker/root/color-picker-root.d.ts +32 -24
- package/dist/color-picker/root/color-picker-root.js +99 -55
- package/dist/color-picker/wheel.d.ts +28 -0
- package/dist/color-picker/wheel.js +15 -0
- package/dist/combobox/root/combobox-root.d.ts +83 -11
- package/dist/combobox/root/combobox-root.js +81 -18
- package/dist/command/root/command-root.d.ts +7 -4
- package/dist/command/root/command-root.js +2 -19
- package/dist/copy-button/root/copy-button-root.d.ts +16 -1
- package/dist/copy-button/root/copy-button-root.js +7 -2
- package/dist/data-table/keys.d.ts +0 -18
- package/dist/data-table/keys.js +1 -11
- package/dist/data-table/root/data-table-root.js +29 -50
- package/dist/date-input/root/date-input-root.d.ts +8 -1
- package/dist/date-input/root/date-input-root.js +8 -5
- package/dist/date-picker/root/date-picker-root.d.ts +14 -9
- package/dist/date-picker/root/date-picker-root.js +21 -16
- package/dist/description-list/item/description-list-item.d.ts +22 -4
- package/dist/description-list/item/description-list-item.js +14 -4
- package/dist/divider/root/divider-root.d.ts +45 -16
- package/dist/divider/root/divider-root.js +28 -4
- package/dist/donut-chart/root/donut-chart-root.js +13 -6
- package/dist/donut-chart/slice-label.d.ts +35 -0
- package/dist/donut-chart/slice-label.js +11 -0
- package/dist/drawer/root/drawer-root.d.ts +4 -2
- package/dist/drawer/root/drawer-root.js +15 -3
- package/dist/drilldown/item/drilldown-item.d.ts +21 -1
- package/dist/drilldown/item/drilldown-item.js +38 -4
- package/dist/drilldown/root/drilldown-root.js +3 -2
- package/dist/element-events.generated.js +5 -1
- package/dist/empty/root/empty-root.d.ts +46 -2
- package/dist/empty/root/empty-root.js +50 -5
- package/dist/file-input/root/file-input-root.d.ts +34 -6
- package/dist/file-input/root/file-input-root.js +55 -21
- package/dist/file-input/status.d.ts +24 -0
- package/dist/file-input/status.js +11 -0
- package/dist/filter-input/chip/filter-chip.d.ts +23 -0
- package/dist/filter-input/chip/filter-chip.js +10 -2
- package/dist/filter-input/root/filter-input-root.d.ts +8 -0
- package/dist/filter-input/root/filter-input-root.js +17 -27
- package/dist/format-date/fields.d.ts +20 -0
- package/dist/format-date/fields.js +14 -0
- package/dist/format-date/options.d.ts +5 -5
- package/dist/format-date/options.js +10 -39
- package/dist/format-date/root/format-date-root.d.ts +53 -4
- package/dist/format-date/root/format-date-root.js +38 -50
- package/dist/graph/root/graph-root.d.ts +23 -5
- package/dist/graph/root/graph-root.js +17 -20
- package/dist/heatmap/root/buckets.d.ts +21 -0
- package/dist/heatmap/root/buckets.js +34 -0
- package/dist/heatmap/root/heatmap-root.d.ts +76 -3
- package/dist/heatmap/root/heatmap-root.js +105 -20
- package/dist/icon/index.d.ts +1 -1
- package/dist/icon/index.js +1 -1
- package/dist/icon/registry.d.ts +26 -1
- package/dist/icon/registry.js +12 -1
- package/dist/icon/root/icon-root.d.ts +13 -0
- package/dist/icon/root/icon-root.js +23 -2
- package/dist/icon/root/index.d.ts +1 -1
- package/dist/icon/root/index.js +1 -1
- package/dist/image/root/image-root.d.ts +20 -0
- package/dist/image/root/image-root.js +6 -1
- package/dist/input/root/input-root.d.ts +23 -2
- package/dist/input/root/input-root.js +12 -8
- package/dist/kbd/root/kbd-root.d.ts +20 -3
- package/dist/kbd/root/kbd-root.js +23 -50
- package/dist/legend/hidden-series.d.ts +10 -2
- package/dist/legend/hidden-series.js +5 -2
- package/dist/legend/root/legend-root.d.ts +25 -7
- package/dist/legend/root/legend-root.js +25 -26
- package/dist/lightbox/root/lightbox-root.d.ts +50 -5
- package/dist/lightbox/root/lightbox-root.js +76 -8
- package/dist/lightbox/zoom.d.ts +2 -0
- package/dist/lightbox/zoom.js +5 -3
- package/dist/line-chart/root/line-chart-root.d.ts +16 -0
- package/dist/line-chart/root/line-chart-root.js +10 -2
- package/dist/list/root/list-root.d.ts +10 -2
- package/dist/list/root/list-root.js +31 -24
- package/dist/list/selection.d.ts +17 -0
- package/dist/list/selection.js +16 -0
- package/dist/listbox/root/listbox-root.d.ts +125 -26
- package/dist/listbox/root/listbox-root.js +156 -166
- package/dist/map/marker/map-marker.d.ts +2 -1
- package/dist/map/root/map-root.d.ts +40 -2
- package/dist/map/root/map-root.js +64 -23
- package/dist/megamenu/hand-over.d.ts +75 -0
- package/dist/megamenu/hand-over.js +67 -0
- package/dist/megamenu/root/megamenu-root.d.ts +38 -14
- package/dist/megamenu/root/megamenu-root.js +29 -50
- package/dist/menu/item/menu-item.js +4 -4
- package/dist/menu/root/menu-root.d.ts +5 -2
- package/dist/meter/root/meter-root.d.ts +42 -0
- package/dist/meter/root/meter-root.js +33 -7
- package/dist/navigation/root/navigation-root.js +5 -8
- package/dist/notifications/group/notification-group.d.ts +8 -1
- package/dist/notifications/group/notification-group.js +12 -6
- package/dist/notifications/notification/notification.d.ts +12 -1
- package/dist/notifications/notification/notification.js +3 -1
- package/dist/notifications/root/notifications-root.d.ts +48 -3
- package/dist/notifications/root/notifications-root.js +36 -6
- package/dist/number-input/grain.d.ts +28 -0
- package/dist/number-input/grain.js +14 -0
- package/dist/number-input/root/number-input-root.d.ts +17 -1
- package/dist/number-input/root/number-input-root.js +29 -18
- package/dist/object-inspector/root/object-inspector-root.d.ts +17 -6
- package/dist/object-inspector/root/object-inspector-root.js +31 -20
- package/dist/option/index.d.ts +1 -0
- package/dist/option/index.js +1 -0
- package/dist/option/separator/option-separator.d.ts +30 -0
- package/dist/option/separator/option-separator.js +21 -0
- package/dist/outline/root/outline-root.d.ts +12 -0
- package/dist/outline/root/outline-root.js +5 -19
- package/dist/pagination/size/pagination-size.d.ts +6 -0
- package/dist/pagination/size/pagination-size.js +5 -3
- package/dist/pin-input/code.d.ts +51 -1
- package/dist/pin-input/code.js +37 -0
- package/dist/pin-input/root/pin-input-root.d.ts +98 -121
- package/dist/pin-input/root/pin-input-root.js +151 -156
- package/dist/popover/hide-outside.js +2 -9
- package/dist/popover/root/popover-root.d.ts +7 -1
- package/dist/popover/root/popover-root.js +9 -1
- package/dist/progress/root/progress-root.d.ts +27 -0
- package/dist/progress/root/progress-root.js +25 -7
- package/dist/qr-code/export.d.ts +19 -0
- package/dist/qr-code/export.js +14 -0
- package/dist/qr-code/name.d.ts +11 -0
- package/dist/qr-code/name.js +7 -0
- package/dist/qr-code/root/qr-code-root.d.ts +31 -9
- package/dist/qr-code/root/qr-code-root.js +29 -17
- package/dist/radio/group/radio-group.d.ts +15 -0
- package/dist/radio/root/radio-root.js +2 -2
- package/dist/rating/root/rating-root.d.ts +22 -9
- package/dist/rating/root/rating-root.js +15 -39
- package/dist/scatter-chart/measures.d.ts +22 -0
- package/dist/scatter-chart/measures.js +11 -0
- package/dist/scatter-chart/root/scatter-chart-root.d.ts +26 -0
- package/dist/scatter-chart/root/scatter-chart-root.js +21 -7
- package/dist/scroll-area/scrollbar.d.ts +0 -8
- package/dist/scroll-area/scrollbar.js +1 -1
- package/dist/select/align.d.ts +47 -0
- package/dist/select/align.js +7 -0
- package/dist/select/root/select-root.d.ts +115 -11
- package/dist/select/root/select-root.js +104 -20
- package/dist/slider/root/slider-root.d.ts +18 -1
- package/dist/slider/root/slider-root.js +22 -0
- package/dist/sparkline/readings.d.ts +30 -12
- package/dist/sparkline/readings.js +32 -15
- package/dist/sparkline/root/sparkline-root.d.ts +46 -3
- package/dist/sparkline/root/sparkline-root.js +60 -21
- package/dist/speed-dial/group/speed-dial-group.d.ts +48 -0
- package/dist/speed-dial/group/speed-dial-group.js +43 -0
- package/dist/speed-dial/index.d.ts +1 -0
- package/dist/speed-dial/index.js +1 -0
- package/dist/speed-dial/item/speed-dial-item.d.ts +27 -2
- package/dist/speed-dial/item/speed-dial-item.js +43 -5
- package/dist/speed-dial/long-press.d.ts +50 -0
- package/dist/speed-dial/long-press.js +48 -0
- package/dist/speed-dial/root/speed-dial-root.d.ts +86 -1
- package/dist/speed-dial/root/speed-dial-root.js +123 -6
- package/dist/splitter/root/splitter-root.d.ts +9 -2
- package/dist/splitter/root/splitter-root.js +18 -3
- package/dist/steps/root/steps-root.d.ts +8 -1
- package/dist/steps/root/steps-root.js +6 -1
- package/dist/steps/step/step.d.ts +1 -0
- package/dist/steps/step/step.js +1 -1
- package/dist/table/cell/table-cell.d.ts +8 -1
- package/dist/table/cell/table-cell.js +6 -2
- package/dist/table/column/table-column.d.ts +6 -0
- package/dist/table/column/table-column.js +5 -1
- package/dist/table/grid-controller.d.ts +117 -0
- package/dist/table/grid-controller.js +293 -0
- package/dist/table/root/table-root.d.ts +47 -3
- package/dist/table/root/table-root.js +93 -29
- package/dist/table/row/table-row.d.ts +36 -0
- package/dist/table/row/table-row.js +52 -2
- package/dist/tabs/root/tabs-root.d.ts +5 -3
- package/dist/tag/group/tag-group.d.ts +16 -4
- package/dist/tag/group/tag-group.js +23 -20
- package/dist/textarea/root/textarea-root.d.ts +14 -2
- package/dist/textarea/root/textarea-root.js +6 -7
- package/dist/time-input/root/time-input-root.d.ts +5 -1
- package/dist/time-input/root/time-input-root.js +10 -7
- package/dist/time-picker/root/time-picker-root.d.ts +12 -14
- package/dist/time-picker/root/time-picker-root.js +18 -23
- package/dist/toast/item/toast-item.d.ts +9 -6
- package/dist/toast/item/toast-item.js +1 -1
- package/dist/toast/root/toast-root.d.ts +40 -4
- package/dist/toast/root/toast-root.js +68 -16
- package/dist/toast/words.d.ts +12 -0
- package/dist/toast/words.js +25 -0
- package/dist/toggle/group/toggle-group.d.ts +29 -5
- package/dist/toggle/group/toggle-group.js +26 -43
- package/dist/toggle/root/toggle-root.js +2 -4
- package/dist/toolbar/root/toolbar-root.d.ts +52 -5
- package/dist/toolbar/root/toolbar-root.js +88 -13
- package/dist/tooltip/root/tooltip-root.d.ts +7 -1
- package/dist/tooltip/root/tooltip-root.js +10 -2
- package/dist/tour/root/tour-root.d.ts +15 -0
- package/dist/tour/root/tour-root.js +20 -1
- package/dist/tour/stop/tour-stop.d.ts +3 -0
- package/dist/tour/stop/tour-stop.js +3 -3
- package/dist/tree/root/tree-root.js +2 -2
- package/dist/trend/figure.d.ts +16 -0
- package/dist/trend/figure.js +8 -0
- package/dist/trend/root/trend-root.d.ts +41 -2
- package/dist/trend/root/trend-root.js +29 -3
- package/dist/video/root/extra-controls.d.ts +12 -0
- package/dist/video/root/extra-controls.js +6 -2
- package/dist/video/root/video-root.d.ts +16 -1
- package/dist/video/root/video-root.js +15 -1
- package/dist/video-playlist/root/video-playlist-root.d.ts +11 -1
- package/dist/video-playlist/root/video-playlist-root.js +3 -0
- package/dist/virtual-list/fill.d.ts +11 -0
- package/dist/virtual-list/fill.js +9 -0
- package/dist/virtual-list/keys.d.ts +16 -7
- package/dist/virtual-list/keys.js +17 -6
- package/dist/virtual-list/plan.d.ts +17 -1
- package/dist/virtual-list/plan.js +13 -2
- package/dist/virtual-list/root/virtual-list-root.d.ts +25 -3
- package/dist/virtual-list/root/virtual-list-root.js +53 -41
- package/lint.json +1 -1
- package/package.json +5 -5
- package/types/jsx.d.ts +4934 -954
- package/types/svelte.d.ts +2 -0
- package/types/vue.d.ts +946 -253
- package/dist/color-picker/swatches.d.ts +0 -12
- package/dist/color-picker/swatches.js +0 -26
- package/dist/rating/steps.d.ts +0 -7
- package/dist/rating/steps.js +0 -9
- package/dist/tooltip/focus-target.d.ts +0 -6
- package/dist/tooltip/focus-target.js +0 -9
package/dist/qr-code/export.js
CHANGED
|
@@ -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, '&').replace(/"/g, '"').replace(/</g, '<');
|
|
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;
|
|
@@ -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
|
|
17
|
-
* code is for
|
|
18
|
-
*
|
|
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
|
-
*
|
|
74
|
-
*
|
|
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
|
|
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
|
|
154
|
-
|
|
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:
|
|
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
|
|
195
|
-
|
|
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(
|
|
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
|
|
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
|
|
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
|
|
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
|
|
176
|
-
/** Whether `
|
|
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
|
-
*
|
|
232
|
+
* The shape for one place, or nothing when the stylesheet is drawing it.
|
|
219
233
|
*
|
|
220
|
-
*
|
|
221
|
-
*
|
|
222
|
-
*
|
|
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
|
|
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.
|
|
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
|
-
|
|
39
|
-
this.
|
|
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.
|
|
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
|
|
171
|
-
|
|
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
|
|
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
|
-
|
|
176
|
+
closest = option.dataset.score;
|
|
195
177
|
}
|
|
196
178
|
}
|
|
197
|
-
return
|
|
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.
|
|
243
|
-
this.
|
|
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
|
|
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.
|
|
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.
|
|
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. */
|