@fusion.dev/helix-headless 0.144.0 → 0.146.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 +15195 -4240
- package/dist/accordion/item/accordion-item.d.ts +62 -12
- package/dist/accordion/item/accordion-item.js +41 -10
- package/dist/accordion/root/accordion-root.d.ts +14 -5
- package/dist/accordion/root/accordion-root.js +7 -1
- package/dist/announcement/root/announcement-root.d.ts +24 -3
- package/dist/announcement/root/announcement-root.js +39 -2
- package/dist/app-header/root/app-header-root.d.ts +12 -0
- package/dist/app-header/root/app-header-root.js +13 -1
- package/dist/app-header/sectioning.d.ts +9 -0
- package/dist/app-header/sectioning.js +27 -0
- package/dist/avatar/group/avatar-group.d.ts +20 -14
- package/dist/avatar/group/avatar-group.js +17 -19
- package/dist/badge/root/badge-root.d.ts +3 -1
- package/dist/badge/root/badge-root.js +2 -2
- package/dist/bar-chart/root/bar-chart-root.d.ts +18 -1
- package/dist/bar-chart/root/bar-chart-root.js +52 -15
- package/dist/bar-chart/stack.d.ts +15 -0
- package/dist/bar-chart/stack.js +19 -0
- package/dist/breadcrumbs/root/breadcrumbs-root.d.ts +57 -1
- package/dist/breadcrumbs/root/breadcrumbs-root.js +73 -3
- package/dist/button/root/button-root.d.ts +26 -0
- package/dist/button/root/button-root.js +38 -18
- package/dist/button-group/root/button-group-root.d.ts +2 -1
- package/dist/button-group/root/button-group-root.js +5 -1
- package/dist/canvas/node/canvas-node.d.ts +4 -3
- package/dist/canvas/node/canvas-node.js +3 -2
- package/dist/canvas/root/canvas-root.d.ts +38 -3
- package/dist/canvas/root/canvas-root.js +123 -42
- package/dist/card/root/card-root.d.ts +24 -3
- package/dist/card/root/card-root.js +20 -8
- package/dist/carousel/root/carousel-root.d.ts +133 -4
- package/dist/carousel/root/carousel-root.js +174 -24
- package/dist/carousel/stops.d.ts +20 -0
- package/dist/carousel/stops.js +30 -0
- package/dist/chat/composer/chat-composer.d.ts +38 -6
- package/dist/chat/composer/chat-composer.js +42 -9
- package/dist/chat/message/chat-message.d.ts +32 -1
- package/dist/chat/message/chat-message.js +27 -10
- package/dist/chat/naming.d.ts +26 -0
- package/dist/chat/naming.js +14 -0
- package/dist/chat/root/chat-root.d.ts +58 -0
- package/dist/chat/root/chat-root.js +43 -3
- package/dist/checkbox/root/checkbox-root.d.ts +20 -0
- package/dist/checkbox/root/checkbox-root.js +14 -1
- package/dist/checkbox-group/root/checkbox-group-root.d.ts +8 -2
- package/dist/checkbox-group/root/checkbox-group-root.js +12 -10
- package/dist/checkbox-group/select-all.d.ts +27 -0
- package/dist/checkbox-group/select-all.js +12 -0
- package/dist/code-block/highlight.d.ts +15 -0
- package/dist/code-block/highlight.js +4 -0
- package/dist/code-block/root/code-block-root.d.ts +57 -2
- package/dist/code-block/root/code-block-root.js +63 -8
- package/dist/color-input/root/color-input-root.d.ts +3 -0
- package/dist/color-input/root/color-input-root.js +6 -3
- package/dist/color-picker/root/color-picker-root.d.ts +33 -4
- package/dist/color-picker/root/color-picker-root.js +80 -21
- package/dist/color-picker/swatches.d.ts +12 -0
- package/dist/color-picker/swatches.js +26 -0
- package/dist/combobox/root/combobox-root.d.ts +43 -0
- package/dist/combobox/root/combobox-root.js +79 -15
- package/dist/command/root/command-root.d.ts +16 -1
- package/dist/command/root/command-root.js +22 -4
- package/dist/copy-button/root/copy-button-root.d.ts +26 -1
- package/dist/copy-button/root/copy-button-root.js +12 -5
- package/dist/data-table/index.d.ts +1 -1
- package/dist/data-table/index.js +1 -1
- package/dist/data-table/keys.d.ts +24 -0
- package/dist/data-table/keys.js +24 -0
- package/dist/data-table/root/data-table-root.d.ts +170 -13
- package/dist/data-table/root/data-table-root.js +294 -52
- package/dist/data-table/tree.d.ts +55 -0
- package/dist/data-table/tree.js +54 -0
- package/dist/date-input/root/date-input-root.d.ts +3 -1
- package/dist/date-input/root/date-input-root.js +18 -7
- package/dist/date-picker/root/date-picker-root.js +12 -6
- package/dist/description-list/item/description-list-item.d.ts +17 -2
- package/dist/description-list/item/description-list-item.js +15 -2
- package/dist/description-list/root/description-list-root.d.ts +27 -1
- package/dist/description-list/root/description-list-root.js +26 -1
- package/dist/dialog/description.js +15 -1
- package/dist/dialog/root/dialog-root.d.ts +8 -2
- package/dist/dialog/root/dialog-root.js +16 -1
- package/dist/divider/root/divider-root.d.ts +3 -0
- package/dist/divider/root/divider-root.js +2 -1
- package/dist/donut-chart/root/donut-chart-root.d.ts +31 -0
- package/dist/donut-chart/root/donut-chart-root.js +48 -1
- package/dist/drawer/reveal.d.ts +8 -0
- package/dist/drawer/reveal.js +1 -0
- package/dist/drawer/root/drawer-root.d.ts +59 -0
- package/dist/drawer/root/drawer-root.js +63 -4
- package/dist/drilldown/item/drilldown-item.d.ts +11 -6
- package/dist/drilldown/item/drilldown-item.js +8 -5
- package/dist/drilldown/root/drilldown-root.d.ts +29 -0
- package/dist/drilldown/root/drilldown-root.js +28 -5
- package/dist/element-events.generated.js +83 -12
- package/dist/empty/root/empty-root.d.ts +3 -1
- package/dist/empty/root/empty-root.js +3 -2
- package/dist/file-input/root/file-input-root.d.ts +69 -6
- package/dist/file-input/root/file-input-root.js +82 -19
- package/dist/file-input/screen.d.ts +2 -1
- package/dist/filter-input/menu/filter-menu.d.ts +5 -0
- package/dist/filter-input/menu/filter-menu.js +16 -4
- package/dist/filter-input/root/filter-input-root.d.ts +30 -6
- package/dist/filter-input/root/filter-input-root.js +1 -1
- package/dist/filter-input/suggest.d.ts +28 -3
- package/dist/filter-input/suggest.js +18 -8
- package/dist/format-date/root/format-date-root.d.ts +9 -16
- package/dist/format-date/root/format-date-root.js +10 -27
- package/dist/heatmap/root/heatmap-root.d.ts +24 -13
- package/dist/heatmap/root/heatmap-root.js +34 -12
- package/dist/icon/root/icon-root.d.ts +12 -1
- package/dist/icon/root/icon-root.js +21 -10
- package/dist/icon/settle.d.ts +7 -0
- package/dist/icon/settle.js +10 -0
- package/dist/icon-button/root/icon-button-root.d.ts +2 -0
- package/dist/image/root/image-root.d.ts +5 -1
- package/dist/image/root/image-root.js +10 -2
- package/dist/input/root/input-root.d.ts +13 -3
- package/dist/input/root/input-root.js +12 -3
- package/dist/kbd/root/kbd-root.d.ts +35 -1
- package/dist/kbd/root/kbd-root.js +23 -4
- package/dist/legend/root/legend-root.d.ts +55 -8
- package/dist/legend/root/legend-root.js +55 -13
- package/dist/lightbox/root/lightbox-root.d.ts +49 -6
- package/dist/lightbox/root/lightbox-root.js +86 -19
- package/dist/lightbox/zoom-controller.d.ts +59 -0
- package/dist/lightbox/zoom-controller.js +128 -0
- package/dist/lightbox/zoom.d.ts +22 -0
- package/dist/lightbox/zoom.js +16 -0
- package/dist/line-chart/root/line-chart-root.d.ts +22 -1
- package/dist/line-chart/root/line-chart-root.js +21 -1
- package/dist/list/item/list-item.d.ts +70 -1
- package/dist/list/item/list-item.js +77 -6
- package/dist/list/numbering.d.ts +14 -0
- package/dist/list/numbering.js +8 -0
- package/dist/list/root/list-root.d.ts +155 -9
- package/dist/list/root/list-root.js +246 -4
- package/dist/list/selection.d.ts +49 -0
- package/dist/list/selection.js +30 -0
- package/dist/listbox/root/listbox-root.d.ts +37 -1
- package/dist/listbox/root/listbox-root.js +49 -4
- package/dist/loader/busy.d.ts +10 -0
- package/dist/loader/busy.js +11 -0
- package/dist/loader/root/loader-root.d.ts +9 -2
- package/dist/loader/root/loader-root.js +23 -3
- package/dist/map/root/map-root.d.ts +6 -2
- package/dist/map/root/map-root.js +5 -2
- package/dist/megamenu/root/megamenu-root.d.ts +62 -0
- package/dist/megamenu/root/megamenu-root.js +90 -5
- package/dist/menu/index.d.ts +1 -0
- package/dist/menu/index.js +1 -0
- package/dist/menu/item/menu-item.d.ts +87 -11
- package/dist/menu/item/menu-item.js +78 -22
- package/dist/menu/root/menu-root.d.ts +39 -1
- package/dist/menu/root/menu-root.js +65 -8
- package/dist/menu/section/menu-section.d.ts +55 -0
- package/dist/menu/section/menu-section.js +60 -0
- package/dist/meter/root/meter-root.d.ts +20 -1
- package/dist/meter/root/meter-root.js +11 -15
- package/dist/navigation/root/navigation-root.d.ts +18 -2
- package/dist/navigation/root/navigation-root.js +29 -3
- package/dist/notifications/root/notifications-root.d.ts +25 -0
- package/dist/notifications/root/notifications-root.js +33 -5
- package/dist/number-input/root/number-input-root.d.ts +17 -8
- package/dist/number-input/root/number-input-root.js +2 -7
- package/dist/object-inspector/root/object-inspector-root.d.ts +161 -32
- package/dist/object-inspector/root/object-inspector-root.js +264 -123
- package/dist/object-inspector/rows.d.ts +75 -0
- package/dist/object-inspector/rows.js +119 -0
- package/dist/option/root/option-root.d.ts +5 -3
- package/dist/outline/levels.d.ts +31 -0
- package/dist/outline/levels.js +23 -0
- package/dist/outline/root/outline-root.d.ts +86 -3
- package/dist/outline/root/outline-root.js +95 -12
- package/dist/pagination/size/pagination-size.d.ts +12 -2
- package/dist/pagination/size/pagination-size.js +20 -5
- package/dist/pin-input/code.d.ts +10 -0
- package/dist/pin-input/code.js +13 -0
- package/dist/pin-input/root/pin-input-root.d.ts +25 -1
- package/dist/pin-input/root/pin-input-root.js +10 -11
- package/dist/popover/hide-outside.d.ts +14 -0
- package/dist/popover/hide-outside.js +41 -0
- package/dist/popover/root/popover-root.d.ts +57 -7
- package/dist/popover/root/popover-root.js +58 -3
- package/dist/progress/root/progress-root.d.ts +20 -0
- package/dist/progress/root/progress-root.js +15 -15
- package/dist/qr-code/export.d.ts +26 -1
- package/dist/qr-code/export.js +14 -0
- package/dist/qr-code/root/qr-code-root.d.ts +19 -5
- package/dist/qr-code/root/qr-code-root.js +58 -9
- package/dist/quote/marks.d.ts +8 -0
- package/dist/quote/marks.js +5 -0
- package/dist/quote/root/quote-root.d.ts +14 -2
- package/dist/quote/root/quote-root.js +23 -1
- package/dist/radio/group/radio-group.d.ts +4 -10
- package/dist/radio/group/radio-group.js +5 -10
- package/dist/radio/root/radio-root.d.ts +6 -2
- package/dist/radio/root/radio-root.js +6 -1
- package/dist/rating/root/rating-root.d.ts +10 -5
- package/dist/rating/root/rating-root.js +32 -8
- package/dist/rating/steps.d.ts +7 -0
- package/dist/rating/steps.js +9 -0
- package/dist/scatter-chart/fit.d.ts +15 -0
- package/dist/scatter-chart/fit.js +35 -0
- package/dist/scatter-chart/root/scatter-chart-root.d.ts +21 -1
- package/dist/scatter-chart/root/scatter-chart-root.js +30 -17
- package/dist/scroll-area/root/scroll-area-root.d.ts +84 -0
- package/dist/scroll-area/root/scroll-area-root.js +106 -7
- package/dist/scroll-area/scrollbar-controller.d.ts +111 -0
- package/dist/scroll-area/scrollbar-controller.js +172 -0
- package/dist/scroll-area/scrollbar.d.ts +92 -0
- package/dist/scroll-area/scrollbar.js +33 -0
- package/dist/select/root/select-root.d.ts +15 -0
- package/dist/select/root/select-root.js +18 -6
- package/dist/skeleton/root/skeleton-root.d.ts +3 -0
- package/dist/skeleton/root/skeleton-root.js +4 -2
- package/dist/skip-link/root/skip-link-root.js +2 -2
- package/dist/slider/root/slider-root.d.ts +41 -4
- package/dist/slider/root/slider-root.js +23 -3
- package/dist/sparkline/readings.d.ts +18 -0
- package/dist/sparkline/readings.js +19 -0
- package/dist/sparkline/root/sparkline-root.d.ts +78 -7
- package/dist/sparkline/root/sparkline-root.js +118 -23
- package/dist/speed-dial/root/speed-dial-root.js +2 -2
- package/dist/splitter/root/splitter-root.d.ts +20 -12
- package/dist/splitter/root/splitter-root.js +226 -203
- package/dist/splitter/snap.d.ts +9 -0
- package/dist/splitter/snap.js +12 -0
- package/dist/stat/root/stat-root.d.ts +14 -5
- package/dist/stat/root/stat-root.js +21 -5
- package/dist/steps/reach.d.ts +20 -0
- package/dist/steps/reach.js +15 -0
- package/dist/steps/root/steps-root.d.ts +76 -0
- package/dist/steps/root/steps-root.js +93 -1
- package/dist/steps/step/step.d.ts +45 -2
- package/dist/steps/step/step.js +33 -6
- package/dist/switch/root/switch-root.d.ts +10 -0
- package/dist/table/column/table-column.d.ts +11 -10
- package/dist/table/column/table-column.js +8 -19
- package/dist/table/root/table-root.d.ts +126 -4
- package/dist/table/root/table-root.js +156 -6
- package/dist/table/row/table-row.d.ts +47 -1
- package/dist/table/row/table-row.js +39 -2
- package/dist/tabs/panel/tab-panel.d.ts +22 -5
- package/dist/tabs/panel/tab-panel.js +34 -6
- package/dist/tabs/root/tabs-root.d.ts +37 -1
- package/dist/tabs/root/tabs-root.js +22 -4
- package/dist/tabs/tab/tab.d.ts +41 -4
- package/dist/tabs/tab/tab.js +49 -3
- package/dist/tag/group/tag-group.d.ts +31 -4
- package/dist/tag/group/tag-group.js +46 -7
- package/dist/tag/root/tag-root.js +9 -2
- package/dist/textarea/root/textarea-root.d.ts +28 -1
- package/dist/textarea/root/textarea-root.js +40 -1
- package/dist/time-input/root/time-input-root.d.ts +5 -1
- package/dist/time-input/root/time-input-root.js +16 -8
- package/dist/time-picker/root/time-picker-root.d.ts +18 -4
- package/dist/time-picker/root/time-picker-root.js +7 -10
- package/dist/time-picker/wheel-name.d.ts +9 -0
- package/dist/time-picker/wheel-name.js +15 -0
- package/dist/timeline/group/timeline-group.d.ts +46 -0
- package/dist/timeline/group/timeline-group.js +37 -0
- package/dist/timeline/index.d.ts +1 -0
- package/dist/timeline/index.js +1 -0
- package/dist/timeline/root/timeline-root.d.ts +10 -3
- package/dist/toast/item/toast-item.d.ts +24 -18
- package/dist/toast/item/toast-item.js +36 -40
- package/dist/toast/root/toast-root.d.ts +6 -0
- package/dist/toast/root/toast-root.js +16 -1
- package/dist/toggle/group/toggle-group.d.ts +24 -3
- package/dist/toggle/group/toggle-group.js +34 -5
- package/dist/toolbar/root/toolbar-root.d.ts +13 -0
- package/dist/toolbar/root/toolbar-root.js +15 -5
- package/dist/tooltip/root/tooltip-root.d.ts +13 -2
- package/dist/tooltip/root/tooltip-root.js +9 -1
- package/dist/tour/back.d.ts +10 -0
- package/dist/tour/back.js +8 -0
- package/dist/tour/root/tour-root.d.ts +30 -2
- package/dist/tour/root/tour-root.js +34 -8
- package/dist/tree/item/tree-item.d.ts +61 -4
- package/dist/tree/item/tree-item.js +92 -20
- package/dist/tree/root/tree-root.d.ts +58 -0
- package/dist/tree/root/tree-root.js +80 -16
- package/dist/tree/selection.d.ts +24 -0
- package/dist/tree/selection.js +13 -0
- package/dist/trend/root/trend-root.d.ts +43 -18
- package/dist/trend/root/trend-root.js +31 -6
- package/dist/video/media-events.d.ts +44 -0
- package/dist/video/media-events.js +35 -0
- package/dist/video/root/video-root.d.ts +117 -18
- package/dist/video/root/video-root.js +93 -47
- package/dist/video-playlist/menu/video-playlist-menu.d.ts +5 -0
- package/dist/video-playlist/menu/video-playlist-menu.js +3 -1
- package/dist/video-playlist/order.d.ts +41 -0
- package/dist/video-playlist/order.js +34 -0
- package/dist/video-playlist/root/video-playlist-root.d.ts +77 -3
- package/dist/video-playlist/root/video-playlist-root.js +60 -16
- package/dist/virtual-list/controls.d.ts +4 -0
- package/dist/virtual-list/controls.js +30 -0
- package/dist/virtual-list/fill.d.ts +22 -0
- package/dist/virtual-list/fill.js +23 -0
- package/dist/virtual-list/keys.d.ts +15 -0
- package/dist/virtual-list/keys.js +24 -0
- package/dist/virtual-list/plan.d.ts +49 -0
- package/dist/virtual-list/plan.js +16 -0
- package/dist/virtual-list/root/virtual-list-root.d.ts +259 -26
- package/dist/virtual-list/root/virtual-list-root.js +333 -49
- package/lint.json +1 -1
- package/package.json +8 -8
- package/types/jsx.d.ts +8113 -1394
- package/types/svelte.d.ts +2 -0
- package/types/vue.d.ts +1678 -353
- package/dist/data-table/root/order.d.ts +0 -141
- package/dist/data-table/root/order.js +0 -76
- package/dist/listbox/range.d.ts +0 -17
- package/dist/listbox/range.js +0 -5
- package/dist/tag/selection.d.ts +0 -10
- package/dist/tag/selection.js +0 -12
|
@@ -4,20 +4,23 @@ 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 { CommandController, customElement, deepActiveElement, deepContains, FullscreenController, fillTemplate, HelixElement, hostAria, IdleController, inlineStep, isRtl, keyClaimed, lockScroll, MixinControllerActive, MixinControllerOpen, resolveActiveItem, SwipeController, swipeStep, unlockScroll, whenHydrated, } from '@fusion.dev/helix-core';
|
|
8
|
-
import { caretLeft, caretRight
|
|
7
|
+
import { CommandController, customElement, deepActiveElement, deepContains, drawDismiss, drawDismissGlyph, FullscreenController, fillTemplate, HelixElement, hostAria, IdleController, inlineStep, isRtl, keyClaimed, lockScroll, MixinControllerActive, MixinControllerOpen, resolveActiveItem, SwipeController, swipeStep, unlockScroll, whenHydrated, } from '@fusion.dev/helix-core';
|
|
8
|
+
import { caretLeft, caretRight } from '@fusion.dev/helix-icons';
|
|
9
9
|
import { html, nothing } from 'lit';
|
|
10
10
|
import { property, state } from 'lit/decorators.js';
|
|
11
11
|
import { unsafeSVG } from 'lit/directives/unsafe-svg.js';
|
|
12
12
|
import { HelixHeadlessLightboxItem } from '../item/lightbox-item.js';
|
|
13
|
+
import { ZoomController } from '../zoom-controller.js';
|
|
13
14
|
let HelixHeadlessLightbox = class HelixHeadlessLightbox extends MixinControllerActive(MixinControllerOpen(HelixElement)) {
|
|
14
15
|
constructor() {
|
|
15
16
|
super(...arguments);
|
|
16
17
|
this.controls = false;
|
|
18
|
+
this.counter = false;
|
|
17
19
|
this.dismissLabel = 'Close';
|
|
18
20
|
this.idleDelay = 0;
|
|
19
21
|
this.label = '';
|
|
20
22
|
this.loop = false;
|
|
23
|
+
this.maxZoom = 1;
|
|
21
24
|
this.nextLabel = 'Next';
|
|
22
25
|
this.previousLabel = 'Previous';
|
|
23
26
|
this.slideLabel = '{index} of {count}';
|
|
@@ -27,8 +30,11 @@ let HelixHeadlessLightbox = class HelixHeadlessLightbox extends MixinControllerA
|
|
|
27
30
|
this.filled = false;
|
|
28
31
|
this.announcement = '';
|
|
29
32
|
this.swipes = new SwipeController(this, {
|
|
30
|
-
axis: () => (this.open ? 'x' : undefined),
|
|
33
|
+
axis: () => (this.open && !this.zoomer.engaged ? 'x' : undefined),
|
|
31
34
|
end: (dx, _dy, vx) => {
|
|
35
|
+
if (this.zoomer.pinched) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
32
38
|
const width = this.partNamed('viewport')?.getBoundingClientRect().width ?? 0;
|
|
33
39
|
const step = swipeStep(dx, vx, width, isRtl(this));
|
|
34
40
|
if (step !== 0) {
|
|
@@ -39,6 +45,11 @@ let HelixHeadlessLightbox = class HelixHeadlessLightbox extends MixinControllerA
|
|
|
39
45
|
start: (_target, event) => event.pointerType !== 'mouse',
|
|
40
46
|
surface: () => this.dialog,
|
|
41
47
|
});
|
|
48
|
+
this.zoomer = new ZoomController(this, {
|
|
49
|
+
max: () => (this.open ? this.maxZoom : 1),
|
|
50
|
+
onChange: (scale, pan) => this.drawZoom(scale, pan),
|
|
51
|
+
surface: () => this.partNamed('viewport'),
|
|
52
|
+
});
|
|
42
53
|
this.fullscreen = new FullscreenController(this, (full) => {
|
|
43
54
|
this.filled = full;
|
|
44
55
|
});
|
|
@@ -70,6 +81,10 @@ let HelixHeadlessLightbox = class HelixHeadlessLightbox extends MixinControllerA
|
|
|
70
81
|
if (keyClaimed(event) || event.altKey || event.ctrlKey || event.metaKey) {
|
|
71
82
|
return;
|
|
72
83
|
}
|
|
84
|
+
if (this.zoomKey(event.key)) {
|
|
85
|
+
event.preventDefault();
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
73
88
|
const along = inlineStep(this, event.key);
|
|
74
89
|
if (along === 1 || event.key === 'ArrowDown') {
|
|
75
90
|
event.preventDefault();
|
|
@@ -103,6 +118,18 @@ let HelixHeadlessLightbox = class HelixHeadlessLightbox extends MixinControllerA
|
|
|
103
118
|
this.requestOpen(false);
|
|
104
119
|
};
|
|
105
120
|
}
|
|
121
|
+
drawZoom(scale, pan) {
|
|
122
|
+
const viewport = this.partNamed('viewport');
|
|
123
|
+
const zoomed = scale > 1;
|
|
124
|
+
viewport?.style.setProperty('--lightbox-zoom', zoomed ? String(scale) : '');
|
|
125
|
+
viewport?.style.setProperty('--lightbox-pan-x', zoomed ? `${Math.round(pan.x)}px` : '');
|
|
126
|
+
viewport?.style.setProperty('--lightbox-pan-y', zoomed ? `${Math.round(pan.y)}px` : '');
|
|
127
|
+
this.toggleState('zoomed', zoomed);
|
|
128
|
+
this.idle.stir();
|
|
129
|
+
}
|
|
130
|
+
zoomTo(scale) {
|
|
131
|
+
this.zoomer.zoomTo(scale);
|
|
132
|
+
}
|
|
106
133
|
chromeHasFocus() {
|
|
107
134
|
const active = deepActiveElement();
|
|
108
135
|
const own = this.shadowRoot?.activeElement?.matches('[part="previous"], [part="next"], [part="dismiss"]');
|
|
@@ -147,6 +174,25 @@ let HelixHeadlessLightbox = class HelixHeadlessLightbox extends MixinControllerA
|
|
|
147
174
|
this.requestActive(target.value);
|
|
148
175
|
}
|
|
149
176
|
}
|
|
177
|
+
zoomKey(key) {
|
|
178
|
+
if (this.maxZoom <= 1) {
|
|
179
|
+
return false;
|
|
180
|
+
}
|
|
181
|
+
const scale = this.zoomer.scale;
|
|
182
|
+
if (key === '+' || key === '=') {
|
|
183
|
+
this.zoomer.zoomTo(scale * 1.5);
|
|
184
|
+
}
|
|
185
|
+
else if (key === '-') {
|
|
186
|
+
this.zoomer.zoomTo(scale / 1.5);
|
|
187
|
+
}
|
|
188
|
+
else if (key === '0') {
|
|
189
|
+
this.zoomer.reset();
|
|
190
|
+
}
|
|
191
|
+
else {
|
|
192
|
+
return false;
|
|
193
|
+
}
|
|
194
|
+
return true;
|
|
195
|
+
}
|
|
150
196
|
toEnd(at) {
|
|
151
197
|
const target = this.items[at];
|
|
152
198
|
if (target && target !== this.shown) {
|
|
@@ -161,6 +207,10 @@ let HelixHeadlessLightbox = class HelixHeadlessLightbox extends MixinControllerA
|
|
|
161
207
|
hostAria(this.internals, { label: this.label });
|
|
162
208
|
this.toggleState('fullscreen', this.filled);
|
|
163
209
|
this.toggleState('idle', this.resting);
|
|
210
|
+
this.toggleState('zoomable', this.maxZoom > 1);
|
|
211
|
+
if (changed.has('active') || (changed.has('open') && !this.open)) {
|
|
212
|
+
this.zoomer.reset();
|
|
213
|
+
}
|
|
164
214
|
this.say(changed);
|
|
165
215
|
}
|
|
166
216
|
disconnectedCallback() {
|
|
@@ -230,6 +280,17 @@ let HelixHeadlessLightbox = class HelixHeadlessLightbox extends MixinControllerA
|
|
|
230
280
|
label: current.label,
|
|
231
281
|
});
|
|
232
282
|
}
|
|
283
|
+
place() {
|
|
284
|
+
const items = this.items;
|
|
285
|
+
const current = resolveActiveItem(this.active, items);
|
|
286
|
+
return current
|
|
287
|
+
? fillTemplate(this.statusLabel, {
|
|
288
|
+
count: items.length,
|
|
289
|
+
index: items.indexOf(current) + 1,
|
|
290
|
+
label: current.label,
|
|
291
|
+
})
|
|
292
|
+
: '';
|
|
293
|
+
}
|
|
233
294
|
render() {
|
|
234
295
|
return html `<dialog
|
|
235
296
|
part="dialog"
|
|
@@ -250,6 +311,7 @@ let HelixHeadlessLightbox = class HelixHeadlessLightbox extends MixinControllerA
|
|
|
250
311
|
</div>
|
|
251
312
|
<slot name="footer"></slot>
|
|
252
313
|
${this.controls ? this.renderControls() : nothing}
|
|
314
|
+
${this.counter ? html `<span part="counter" aria-hidden="true">${this.place()}</span>` : nothing}
|
|
253
315
|
<span part="live" role="status" aria-live="polite">${this.announcement || nothing}</span>
|
|
254
316
|
</dialog>`;
|
|
255
317
|
}
|
|
@@ -261,9 +323,11 @@ let HelixHeadlessLightbox = class HelixHeadlessLightbox extends MixinControllerA
|
|
|
261
323
|
aria-disabled=${this.atEnd(-1) ? 'true' : nothing}
|
|
262
324
|
@click=${() => this.previous()}
|
|
263
325
|
>
|
|
264
|
-
<
|
|
265
|
-
|
|
266
|
-
|
|
326
|
+
<slot name="previous-icon">
|
|
327
|
+
<svg part="previous-mark" data-mirror fill="currentColor" viewBox=${caretLeft.viewBox} aria-hidden="true">
|
|
328
|
+
${unsafeSVG(caretLeft.content)}
|
|
329
|
+
</svg>
|
|
330
|
+
</slot>
|
|
267
331
|
</button>
|
|
268
332
|
<button
|
|
269
333
|
part="next"
|
|
@@ -272,25 +336,25 @@ let HelixHeadlessLightbox = class HelixHeadlessLightbox extends MixinControllerA
|
|
|
272
336
|
aria-disabled=${this.atEnd(1) ? 'true' : nothing}
|
|
273
337
|
@click=${() => this.next()}
|
|
274
338
|
>
|
|
275
|
-
<
|
|
276
|
-
|
|
277
|
-
|
|
339
|
+
<slot name="next-icon">
|
|
340
|
+
<svg part="next-mark" data-mirror fill="currentColor" viewBox=${caretRight.viewBox} aria-hidden="true">
|
|
341
|
+
${unsafeSVG(caretRight.content)}
|
|
342
|
+
</svg>
|
|
343
|
+
</slot>
|
|
278
344
|
</button>
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
>
|
|
285
|
-
<svg part="dismiss-mark" fill="currentColor" viewBox=${x.viewBox} aria-hidden="true">
|
|
286
|
-
${unsafeSVG(x.content)}
|
|
287
|
-
</svg>
|
|
288
|
-
</button>`;
|
|
345
|
+
${drawDismiss({
|
|
346
|
+
label: this.dismissLabel,
|
|
347
|
+
mark: html `<slot name="dismiss-icon">${drawDismissGlyph()}</slot>`,
|
|
348
|
+
onDismiss: () => this.close(),
|
|
349
|
+
})}`;
|
|
289
350
|
}
|
|
290
351
|
};
|
|
291
352
|
__decorate([
|
|
292
353
|
property({ reflect: true, type: Boolean })
|
|
293
354
|
], HelixHeadlessLightbox.prototype, "controls", void 0);
|
|
355
|
+
__decorate([
|
|
356
|
+
property({ reflect: true, type: Boolean })
|
|
357
|
+
], HelixHeadlessLightbox.prototype, "counter", void 0);
|
|
294
358
|
__decorate([
|
|
295
359
|
property({ attribute: 'dismiss-label' })
|
|
296
360
|
], HelixHeadlessLightbox.prototype, "dismissLabel", void 0);
|
|
@@ -303,6 +367,9 @@ __decorate([
|
|
|
303
367
|
__decorate([
|
|
304
368
|
property({ reflect: true, type: Boolean })
|
|
305
369
|
], HelixHeadlessLightbox.prototype, "loop", void 0);
|
|
370
|
+
__decorate([
|
|
371
|
+
property({ attribute: 'max-zoom', type: Number })
|
|
372
|
+
], HelixHeadlessLightbox.prototype, "maxZoom", void 0);
|
|
306
373
|
__decorate([
|
|
307
374
|
property({ attribute: 'next-label' })
|
|
308
375
|
], HelixHeadlessLightbox.prototype, "nextLabel", void 0);
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { ReactiveController, ReactiveControllerHost } from 'lit';
|
|
2
|
+
import { type Offset } from './zoom.js';
|
|
3
|
+
export interface ZoomOptions {
|
|
4
|
+
/** The most the item may grow, as a scale. 1 or less turns zooming off. */
|
|
5
|
+
max: () => number;
|
|
6
|
+
/** Told every time the scale or the position changes. */
|
|
7
|
+
onChange: (scale: number, pan: Offset) => void;
|
|
8
|
+
/** The box the item is shown in, which presses must land in and the item scales from the middle of. */
|
|
9
|
+
surface: () => HTMLElement | null | undefined;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Pinch, double press and drag to zoom into the item a viewer shows, and to
|
|
13
|
+
* move about it once zoomed.
|
|
14
|
+
*
|
|
15
|
+
* Two fingers scale the item about the point between them. A double press, a
|
|
16
|
+
* double click or a double tap, zooms all the way in about the point pressed,
|
|
17
|
+
* and back out again. One pointer dragged across a zoomed item moves it, never
|
|
18
|
+
* so far that an edge comes inside the box. What it reports is a scale and an
|
|
19
|
+
* offset from the middle of the box; drawing them is the caller's.
|
|
20
|
+
*/
|
|
21
|
+
export declare class ZoomController implements ReactiveController {
|
|
22
|
+
private readonly host;
|
|
23
|
+
private readonly options;
|
|
24
|
+
/** The pointers down on the box, where each one is now. */
|
|
25
|
+
private readonly pointers;
|
|
26
|
+
/** What the gesture under way started from. */
|
|
27
|
+
private from;
|
|
28
|
+
/** The scale, 1 at rest. */
|
|
29
|
+
scale: number;
|
|
30
|
+
/** How far the item is moved from the middle of the box, in pixels. */
|
|
31
|
+
pan: Offset;
|
|
32
|
+
/**
|
|
33
|
+
* Whether two fingers have been down since the last gesture began, so a
|
|
34
|
+
* swipe that started with the first of them can be told it was a pinch.
|
|
35
|
+
*/
|
|
36
|
+
pinched: boolean;
|
|
37
|
+
constructor(host: ReactiveControllerHost & HTMLElement, options: ZoomOptions);
|
|
38
|
+
/** Whether the item is zoomed, or two fingers are on it: either way, a drag is not a swipe. */
|
|
39
|
+
get engaged(): boolean;
|
|
40
|
+
hostConnected(): void;
|
|
41
|
+
hostDisconnected(): void;
|
|
42
|
+
/** Zooms to `scale` about the middle of the box, held to the range. */
|
|
43
|
+
zoomTo(scale: number, at?: Offset): void;
|
|
44
|
+
/** Back to the item at its own size, in the middle. */
|
|
45
|
+
reset(): void;
|
|
46
|
+
private set;
|
|
47
|
+
/** A point on the page, measured from the middle of the box. */
|
|
48
|
+
private offset;
|
|
49
|
+
/** Whether a press landed in the box, through slotted content as well. */
|
|
50
|
+
private inside;
|
|
51
|
+
/** Starts over from where every pointer down is now. */
|
|
52
|
+
private begin;
|
|
53
|
+
private readonly handleDown;
|
|
54
|
+
private readonly handleMove;
|
|
55
|
+
private readonly handleUp;
|
|
56
|
+
/** A double press zooms all the way in about the point, or back out. */
|
|
57
|
+
private readonly handleDouble;
|
|
58
|
+
private release;
|
|
59
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { between, clampPan, clampScale, spread, zoomAt } from './zoom.js';
|
|
2
|
+
export class ZoomController {
|
|
3
|
+
constructor(host, options) {
|
|
4
|
+
this.pointers = new Map();
|
|
5
|
+
this.scale = 1;
|
|
6
|
+
this.pan = { x: 0, y: 0 };
|
|
7
|
+
this.pinched = false;
|
|
8
|
+
this.handleDown = (event) => {
|
|
9
|
+
if (this.options.max() <= 1 || event.button !== 0 || !this.inside(event)) {
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
if (this.pointers.size === 0) {
|
|
13
|
+
this.pinched = false;
|
|
14
|
+
window.addEventListener('pointermove', this.handleMove);
|
|
15
|
+
window.addEventListener('pointerup', this.handleUp);
|
|
16
|
+
window.addEventListener('pointercancel', this.handleUp);
|
|
17
|
+
}
|
|
18
|
+
this.pointers.set(event.pointerId, this.offset(event));
|
|
19
|
+
if (this.pointers.size > 1) {
|
|
20
|
+
this.pinched = true;
|
|
21
|
+
}
|
|
22
|
+
this.begin();
|
|
23
|
+
};
|
|
24
|
+
this.handleMove = (event) => {
|
|
25
|
+
const from = this.from;
|
|
26
|
+
if (!from || !this.pointers.has(event.pointerId)) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
this.pointers.set(event.pointerId, this.offset(event));
|
|
30
|
+
const [a, b] = [...this.pointers.values()];
|
|
31
|
+
if (a && b && from.spread > 0) {
|
|
32
|
+
const at = between(a, b);
|
|
33
|
+
const scale = clampScale((from.scale * spread(a, b)) / from.spread, this.options.max());
|
|
34
|
+
const about = zoomAt(from.at, from.scale, scale, from.pan);
|
|
35
|
+
this.set(scale, { x: about.x + at.x - from.at.x, y: about.y + at.y - from.at.y });
|
|
36
|
+
}
|
|
37
|
+
else if (a && this.scale > 1) {
|
|
38
|
+
this.set(this.scale, { x: from.pan.x + a.x - from.at.x, y: from.pan.y + a.y - from.at.y });
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
this.handleUp = (event) => {
|
|
42
|
+
if (!this.pointers.delete(event.pointerId)) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
if (this.pointers.size === 0) {
|
|
46
|
+
this.release();
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
this.begin();
|
|
50
|
+
};
|
|
51
|
+
this.handleDouble = (event) => {
|
|
52
|
+
if (this.options.max() <= 1 || !this.inside(event)) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
if (this.scale > 1) {
|
|
56
|
+
this.reset();
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
this.zoomTo(this.options.max(), this.offset(event));
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
this.host = host;
|
|
63
|
+
this.options = options;
|
|
64
|
+
host.addController(this);
|
|
65
|
+
}
|
|
66
|
+
get engaged() {
|
|
67
|
+
return this.scale > 1 || this.pointers.size > 1;
|
|
68
|
+
}
|
|
69
|
+
hostConnected() {
|
|
70
|
+
this.host.addEventListener('pointerdown', this.handleDown);
|
|
71
|
+
this.host.addEventListener('dblclick', this.handleDouble);
|
|
72
|
+
}
|
|
73
|
+
hostDisconnected() {
|
|
74
|
+
this.host.removeEventListener('pointerdown', this.handleDown);
|
|
75
|
+
this.host.removeEventListener('dblclick', this.handleDouble);
|
|
76
|
+
this.release();
|
|
77
|
+
}
|
|
78
|
+
zoomTo(scale, at = { x: 0, y: 0 }) {
|
|
79
|
+
const next = clampScale(scale, this.options.max());
|
|
80
|
+
this.set(next, zoomAt(at, this.scale, next, this.pan));
|
|
81
|
+
}
|
|
82
|
+
reset() {
|
|
83
|
+
if (this.scale !== 1 || this.pan.x !== 0 || this.pan.y !== 0) {
|
|
84
|
+
this.set(1, { x: 0, y: 0 });
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
set(scale, pan) {
|
|
88
|
+
const box = this.options.surface()?.getBoundingClientRect();
|
|
89
|
+
const held = clampPan(pan, scale, box?.width ?? 0, box?.height ?? 0);
|
|
90
|
+
if (scale === this.scale && held.x === this.pan.x && held.y === this.pan.y) {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
this.scale = scale;
|
|
94
|
+
this.pan = held;
|
|
95
|
+
this.options.onChange(scale, held);
|
|
96
|
+
}
|
|
97
|
+
offset(event) {
|
|
98
|
+
const box = this.options.surface()?.getBoundingClientRect();
|
|
99
|
+
return {
|
|
100
|
+
x: event.clientX - (box ? box.left + box.width / 2 : 0),
|
|
101
|
+
y: event.clientY - (box ? box.top + box.height / 2 : 0),
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
inside(event) {
|
|
105
|
+
const surface = this.options.surface();
|
|
106
|
+
return surface !== null && surface !== undefined && event.composedPath().includes(surface);
|
|
107
|
+
}
|
|
108
|
+
begin() {
|
|
109
|
+
const [a, b] = [...this.pointers.values()];
|
|
110
|
+
if (!a) {
|
|
111
|
+
this.from = undefined;
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
this.from = {
|
|
115
|
+
at: b ? between(a, b) : a,
|
|
116
|
+
pan: { ...this.pan },
|
|
117
|
+
scale: this.scale,
|
|
118
|
+
spread: b ? spread(a, b) : 0,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
release() {
|
|
122
|
+
window.removeEventListener('pointermove', this.handleMove);
|
|
123
|
+
window.removeEventListener('pointerup', this.handleUp);
|
|
124
|
+
window.removeEventListener('pointercancel', this.handleUp);
|
|
125
|
+
this.pointers.clear();
|
|
126
|
+
this.from = undefined;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/** A distance from the middle of the viewer, or a point measured from it, in pixels. */
|
|
2
|
+
export interface Offset {
|
|
3
|
+
x: number;
|
|
4
|
+
y: number;
|
|
5
|
+
}
|
|
6
|
+
/** A scale held between 1, the item at its own size, and `max`. */
|
|
7
|
+
export declare const clampScale: (scale: number, max: number) => number;
|
|
8
|
+
/**
|
|
9
|
+
* How far a zoomed item may move, kept so its edges never come inside the
|
|
10
|
+
* viewer's: at a scale of 2 in a box 400 wide, 200 either way.
|
|
11
|
+
*/
|
|
12
|
+
export declare const clampPan: (pan: Offset, scale: number, width: number, height: number) => Offset;
|
|
13
|
+
/**
|
|
14
|
+
* Where the item moves to as its scale goes from `from` to `to`, so the point
|
|
15
|
+
* under `at` stays under it. Both are measured from the middle of the viewer,
|
|
16
|
+
* which is where the item scales from.
|
|
17
|
+
*/
|
|
18
|
+
export declare const zoomAt: (at: Offset, from: number, to: number, pan: Offset) => Offset;
|
|
19
|
+
/** The distance between two fingers. */
|
|
20
|
+
export declare const spread: (a: Offset, b: Offset) => number;
|
|
21
|
+
/** The point halfway between two fingers. */
|
|
22
|
+
export declare const between: (a: Offset, b: Offset) => Offset;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
const clamp = (value, low, high) => Math.min(Math.max(value, low), high) || 0;
|
|
2
|
+
export const clampScale = (scale, max) => clamp(scale, 1, Math.max(max, 1));
|
|
3
|
+
export const clampPan = (pan, scale, width, height) => {
|
|
4
|
+
const x = ((scale - 1) * width) / 2;
|
|
5
|
+
const y = ((scale - 1) * height) / 2;
|
|
6
|
+
return { x: clamp(pan.x, -x, x), y: clamp(pan.y, -y, y) };
|
|
7
|
+
};
|
|
8
|
+
export const zoomAt = (at, from, to, pan) => ({
|
|
9
|
+
x: at.x - ((at.x - pan.x) * to) / from,
|
|
10
|
+
y: at.y - ((at.y - pan.y) * to) / from,
|
|
11
|
+
});
|
|
12
|
+
export const spread = (a, b) => Math.hypot(a.x - b.x, a.y - b.y);
|
|
13
|
+
export const between = (a, b) => ({
|
|
14
|
+
x: (a.x + b.x) / 2,
|
|
15
|
+
y: (a.y + b.y) / 2,
|
|
16
|
+
});
|
|
@@ -49,6 +49,8 @@ declare const HelixHeadlessLineChart_base: typeof HelixElement & (new (...args:
|
|
|
49
49
|
* @csspart line - The line for one series.
|
|
50
50
|
* @csspart live - The readout: a polite live region that says the reading the keys moved to. Hide it visually.
|
|
51
51
|
* @csspart mark - The invisible point the tooltip is anchored to.
|
|
52
|
+
* @csspart marker - The mark on one reading, under `markers`, and on a reading with a blank on either side. Placed with `inset-inline-start` and `inset-block-start`, and carries its series color as `--chart-series`.
|
|
53
|
+
* @csspart marker-lone - A `marker` on a reading with a blank on either side, which no line reaches. Set alongside `marker`.
|
|
52
54
|
* @csspart plot - The drawing, which takes focus to be read by key.
|
|
53
55
|
* @csspart summary - The chart's name and each series' latest reading, written as a sentence for screen readers. Hide it visually.
|
|
54
56
|
* @csspart svg - The drawing surface the lines and areas sit on.
|
|
@@ -138,6 +140,15 @@ export declare class HelixHeadlessLineChart extends HelixHeadlessLineChart_base
|
|
|
138
140
|
protected get rulesValue(): boolean;
|
|
139
141
|
/** Whether each reading is ruled, which only two values ask for. */
|
|
140
142
|
protected get rulesCategory(): boolean;
|
|
143
|
+
/**
|
|
144
|
+
* Draws a mark on every reading, the `marker` part, so a reader sees where
|
|
145
|
+
* the readings are, as well as the line between them.
|
|
146
|
+
*
|
|
147
|
+
* Absent draws none, except on a reading with a blank on either side: it
|
|
148
|
+
* has no line to be part of, so it takes a mark, the `marker` part with
|
|
149
|
+
* `marker-lone` beside it, or it would not be drawn at all.
|
|
150
|
+
*/
|
|
151
|
+
markers: boolean;
|
|
141
152
|
/**
|
|
142
153
|
* The shape of the mark on each series' last reading.
|
|
143
154
|
*
|
|
@@ -200,7 +211,8 @@ export declare class HelixHeadlessLineChart extends HelixHeadlessLineChart_base
|
|
|
200
211
|
* The latest, because where a series ended is the question a line over time
|
|
201
212
|
* is asked first, which is what `AreaChart` gives too. Each series' own last
|
|
202
213
|
* reading, so a series with a blank in the last row still says where it was.
|
|
203
|
-
* Written the way the table writes it, such as `$128k` for `128000`.
|
|
214
|
+
* Written the way the table writes it, such as `$128k` for `128000`. A
|
|
215
|
+
* series a legend hid is not drawn and is not said.
|
|
204
216
|
*/
|
|
205
217
|
protected renderSummary(series: Series[]): TemplateResult;
|
|
206
218
|
/**
|
|
@@ -255,6 +267,15 @@ export declare class HelixHeadlessLineChart extends HelixHeadlessLineChart_base
|
|
|
255
267
|
x: number;
|
|
256
268
|
y: number;
|
|
257
269
|
}>): TemplateResult | typeof nothing;
|
|
270
|
+
/**
|
|
271
|
+
* The marks on the readings: every one under `markers`, and otherwise only
|
|
272
|
+
* a reading no line reaches, which has a blank on either side.
|
|
273
|
+
*
|
|
274
|
+
* Elements beside the drawing, as the termini are, so a mark is round in a
|
|
275
|
+
* drawing `preserveAspectRatio="none"` stretches. Placed from the inline
|
|
276
|
+
* start, as the drawing is mirrored.
|
|
277
|
+
*/
|
|
278
|
+
protected renderMarkers(series: Series[], x: (value: number) => number, y: (value: number) => number): TemplateResult | typeof nothing;
|
|
258
279
|
/**
|
|
259
280
|
* One series, its wash first so the line is drawn over its own fill.
|
|
260
281
|
*
|
|
@@ -12,6 +12,7 @@ let HelixHeadlessLineChart = class HelixHeadlessLineChart extends MixinChartSour
|
|
|
12
12
|
constructor() {
|
|
13
13
|
super(...arguments);
|
|
14
14
|
this.area = false;
|
|
15
|
+
this.markers = false;
|
|
15
16
|
this.zero = false;
|
|
16
17
|
}
|
|
17
18
|
get rulesValue() {
|
|
@@ -62,7 +63,7 @@ let HelixHeadlessLineChart = class HelixHeadlessLineChart extends MixinChartSour
|
|
|
62
63
|
const columns = this.plottedColumns;
|
|
63
64
|
const latest = series.flatMap((one, depth) => {
|
|
64
65
|
const last = one.points.at(-1);
|
|
65
|
-
if (last === undefined) {
|
|
66
|
+
if (last === undefined || !this.showsSeries(one.name)) {
|
|
66
67
|
return [];
|
|
67
68
|
}
|
|
68
69
|
const text = rows[last.at]?.cells[columns[depth] ?? -1]?.text ?? String(last.value);
|
|
@@ -109,6 +110,7 @@ let HelixHeadlessLineChart = class HelixHeadlessLineChart extends MixinChartSour
|
|
|
109
110
|
${series.map((one, depth) => this.renderSeries(one, depth, x, y))}
|
|
110
111
|
</svg>
|
|
111
112
|
${this.renderTermini(ends)}
|
|
113
|
+
${this.renderMarkers(series, x, y)}
|
|
112
114
|
${this.renderTooltip()}
|
|
113
115
|
</div>`;
|
|
114
116
|
}
|
|
@@ -149,6 +151,21 @@ let HelixHeadlessLineChart = class HelixHeadlessLineChart extends MixinChartSour
|
|
|
149
151
|
style=${`--chart-series: var(--chart-series-${end.index}); --chart-terminus-x: ${end.x}%; --chart-terminus-y: ${end.y}%`}
|
|
150
152
|
></span>`)}`;
|
|
151
153
|
}
|
|
154
|
+
renderMarkers(series, x, y) {
|
|
155
|
+
const marks = series.flatMap((one, depth) => this.showsSeries(one.name)
|
|
156
|
+
? unbroken(one).flatMap((run) => run.length > 1 && !this.markers
|
|
157
|
+
? []
|
|
158
|
+
: run.map((point) => ({ depth, lone: run.length === 1, point })))
|
|
159
|
+
: []);
|
|
160
|
+
if (marks.length === 0) {
|
|
161
|
+
return nothing;
|
|
162
|
+
}
|
|
163
|
+
return html `${marks.map(({ depth, lone, point }) => html `<span
|
|
164
|
+
aria-hidden="true"
|
|
165
|
+
part="marker${lone ? ' marker-lone' : ''}"
|
|
166
|
+
style=${`--chart-series: var(--chart-series-${seriesIndex(depth)}); inset-inline-start: ${(x(point.at) / PLOT_WIDTH) * 100}%; inset-block-start: ${(y(point.value) / PLOT_HEIGHT) * 100}%`}
|
|
167
|
+
></span>`)}`;
|
|
168
|
+
}
|
|
152
169
|
renderSeries(one, depth, x, y) {
|
|
153
170
|
if (!this.showsSeries(one.name)) {
|
|
154
171
|
return html `${nothing}`;
|
|
@@ -221,6 +238,9 @@ __decorate([
|
|
|
221
238
|
__decorate([
|
|
222
239
|
property()
|
|
223
240
|
], HelixHeadlessLineChart.prototype, "gridlines", void 0);
|
|
241
|
+
__decorate([
|
|
242
|
+
property({ reflect: true, type: Boolean })
|
|
243
|
+
], HelixHeadlessLineChart.prototype, "markers", void 0);
|
|
224
244
|
__decorate([
|
|
225
245
|
property({ reflect: true })
|
|
226
246
|
], HelixHeadlessLineChart.prototype, "terminus", void 0);
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { HelixElement } from '@fusion.dev/helix-core';
|
|
2
2
|
import { nothing, type PropertyValues, type TemplateResult } from 'lit';
|
|
3
|
+
/** The values `current` takes, which are `aria-current`'s. */
|
|
4
|
+
export type ListItemCurrent = 'date' | 'location' | 'page' | 'step' | 'time' | 'true';
|
|
3
5
|
/**
|
|
4
6
|
* @summary One row of a list.
|
|
5
7
|
*
|
|
@@ -25,6 +27,14 @@ import { nothing, type PropertyValues, type TemplateResult } from 'lit';
|
|
|
25
27
|
* **For a row that holds controls and is not a destination, use
|
|
26
28
|
* `data-list-item`.** With `href` unset, the row is not a link.
|
|
27
29
|
*
|
|
30
|
+
* `current` marks the row a reader is on, such as the page in a list of
|
|
31
|
+
* pages, with `aria-current` on its link, or on the row where it has none.
|
|
32
|
+
*
|
|
33
|
+
* **In a list with `selection-mode`, the row is a row of a grid.** The list
|
|
34
|
+
* gives it its role, its place in the one tab stop and, where the list
|
|
35
|
+
* selects, whether it is selected. Its link leaves the tab order there, and
|
|
36
|
+
* Enter follows it from the row.
|
|
37
|
+
*
|
|
28
38
|
* @since 0.1.0
|
|
29
39
|
* @status stable
|
|
30
40
|
* @aliases Row, Entry
|
|
@@ -35,10 +45,38 @@ import { nothing, type PropertyValues, type TemplateResult } from 'lit';
|
|
|
35
45
|
* @slot end - Trailing content.
|
|
36
46
|
* @slot start - Leading content, usually an icon or an avatar.
|
|
37
47
|
*
|
|
48
|
+
* @event {HelixActionEvent} helix-action - The reader pressed Enter on the row, or pressed the row in a list that selects nothing, in a list with `selection-mode`. Read the row from `target`. A row with `href` follows its link instead.
|
|
49
|
+
*
|
|
38
50
|
* @csspart link - The link, when the row has `href`. It holds every region except `end`.
|
|
39
|
-
* @csspart row - The row's layout. It sits inside the host so the host can carry a list marker.
|
|
51
|
+
* @csspart row - The row's layout. It sits inside the host so the host can carry a list marker. In a list with `selection-mode` it is the grid cell that takes focus.
|
|
52
|
+
* @csspart row-current - Added to `row` while the row is `current`.
|
|
53
|
+
*
|
|
54
|
+
* @cssstate selected - The row is selected, in a list that selects.
|
|
40
55
|
*/
|
|
41
56
|
export declare class HelixHeadlessListItem extends HelixElement {
|
|
57
|
+
/**
|
|
58
|
+
* Marks the row a reader is on: `page` for the page they are reading, `step`,
|
|
59
|
+
* `location`, `date` or `time` for those, and written bare for the current
|
|
60
|
+
* one of a set. It is `aria-current` on the row's link, or on the row where
|
|
61
|
+
* it has none.
|
|
62
|
+
*
|
|
63
|
+
* Not reflected, as a state never is. `row-current` is the part a
|
|
64
|
+
* stylesheet draws it from.
|
|
65
|
+
*/
|
|
66
|
+
current?: ListItemCurrent;
|
|
67
|
+
/**
|
|
68
|
+
* Takes the row out of reach in a list with `selection-mode`: the arrow keys
|
|
69
|
+
* pass over it and it cannot be selected or acted on.
|
|
70
|
+
*/
|
|
71
|
+
disabled: boolean;
|
|
72
|
+
/**
|
|
73
|
+
* Whether the row holds its list's tab stop.
|
|
74
|
+
*
|
|
75
|
+
* Written by a list with `selection-mode` on every row it holds, and unset
|
|
76
|
+
* otherwise, which is how a row knows it is a row of a grid. No attribute:
|
|
77
|
+
* it is coordination between elements, as `Tag.focusable` is.
|
|
78
|
+
*/
|
|
79
|
+
focusable?: boolean | undefined;
|
|
42
80
|
/**
|
|
43
81
|
* The URL the row links to. Leave it empty for a row that is not a link.
|
|
44
82
|
*
|
|
@@ -52,10 +90,41 @@ export declare class HelixHeadlessListItem extends HelixElement {
|
|
|
52
90
|
* `target`, for the reason `Tree.Item` gives.
|
|
53
91
|
*/
|
|
54
92
|
rel: string;
|
|
93
|
+
/**
|
|
94
|
+
* Whether the row is selected, in a list that selects.
|
|
95
|
+
*
|
|
96
|
+
* Written by the list from its own `value`, and unset where nothing can be
|
|
97
|
+
* selected, which keeps `aria-selected` off a list that does not select.
|
|
98
|
+
*/
|
|
99
|
+
selected?: boolean | undefined;
|
|
55
100
|
/**
|
|
56
101
|
* Where the link opens. Use it for a row that leaves the site.
|
|
57
102
|
*/
|
|
58
103
|
target: string;
|
|
104
|
+
/**
|
|
105
|
+
* What the row stands for in its list's `value`.
|
|
106
|
+
*
|
|
107
|
+
* Absent is the row's own words.
|
|
108
|
+
*/
|
|
109
|
+
value: string;
|
|
110
|
+
/** The row's words, or none where the children are not known yet. */
|
|
111
|
+
get words(): string;
|
|
112
|
+
/** Whether something is slotted into `description`, or false where the children are not known yet. */
|
|
113
|
+
private get described();
|
|
114
|
+
/** Whether a list with `selection-mode` holds this row, which makes it a row of a grid. */
|
|
115
|
+
private get grouped();
|
|
116
|
+
/** @internal The cell a list with `selection-mode` moves focus to. */
|
|
117
|
+
get cell(): HTMLElement | null;
|
|
118
|
+
/**
|
|
119
|
+
* @internal The controls in the `end` slot, in order, which Left and Right
|
|
120
|
+
* move between in a list with `selection-mode`. Disabled ones are passed
|
|
121
|
+
* over.
|
|
122
|
+
*/
|
|
123
|
+
get controls(): HTMLElement[];
|
|
124
|
+
/** Moves focus to the row's cell, in a list with `selection-mode`. */
|
|
125
|
+
focusItem(): void;
|
|
126
|
+
/** @internal Follows the row's link, as a press on it would. Called by the list on Enter. */
|
|
127
|
+
follow(): void;
|
|
59
128
|
protected willUpdate(changed: PropertyValues): void;
|
|
60
129
|
/**
|
|
61
130
|
* The cell before the row's content, which this tier leaves empty.
|