@hyalo/angular 0.0.0-stage → 0.3.1
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/CHANGELOG.md +95 -0
- package/LICENSE +21 -0
- package/README.md +45 -2
- package/fesm2022/hyalo-angular-accordion.mjs +230 -0
- package/fesm2022/hyalo-angular-accordion.mjs.map +1 -0
- package/fesm2022/hyalo-angular-alert.mjs +171 -0
- package/fesm2022/hyalo-angular-alert.mjs.map +1 -0
- package/fesm2022/hyalo-angular-aspect-ratio.mjs +64 -0
- package/fesm2022/hyalo-angular-aspect-ratio.mjs.map +1 -0
- package/fesm2022/hyalo-angular-avatar.mjs +169 -0
- package/fesm2022/hyalo-angular-avatar.mjs.map +1 -0
- package/fesm2022/hyalo-angular-badge.mjs +268 -0
- package/fesm2022/hyalo-angular-badge.mjs.map +1 -0
- package/fesm2022/hyalo-angular-bento.mjs +132 -0
- package/fesm2022/hyalo-angular-bento.mjs.map +1 -0
- package/fesm2022/hyalo-angular-blocks.mjs +985 -0
- package/fesm2022/hyalo-angular-blocks.mjs.map +1 -0
- package/fesm2022/hyalo-angular-border-beam.mjs +73 -0
- package/fesm2022/hyalo-angular-border-beam.mjs.map +1 -0
- package/fesm2022/hyalo-angular-breadcrumb.mjs +77 -0
- package/fesm2022/hyalo-angular-breadcrumb.mjs.map +1 -0
- package/fesm2022/hyalo-angular-button-group.mjs +90 -0
- package/fesm2022/hyalo-angular-button-group.mjs.map +1 -0
- package/fesm2022/hyalo-angular-button.mjs +204 -0
- package/fesm2022/hyalo-angular-button.mjs.map +1 -0
- package/fesm2022/hyalo-angular-card.mjs +221 -0
- package/fesm2022/hyalo-angular-card.mjs.map +1 -0
- package/fesm2022/hyalo-angular-carousel.mjs +709 -0
- package/fesm2022/hyalo-angular-carousel.mjs.map +1 -0
- package/fesm2022/hyalo-angular-chapter-nav.mjs +336 -0
- package/fesm2022/hyalo-angular-chapter-nav.mjs.map +1 -0
- package/fesm2022/hyalo-angular-chart-engine-DSJop6He.mjs +5 -0
- package/fesm2022/hyalo-angular-chart-engine-DSJop6He.mjs.map +1 -0
- package/fesm2022/hyalo-angular-chart.mjs +391 -0
- package/fesm2022/hyalo-angular-chart.mjs.map +1 -0
- package/fesm2022/hyalo-angular-choice.mjs +789 -0
- package/fesm2022/hyalo-angular-choice.mjs.map +1 -0
- package/fesm2022/hyalo-angular-code-block-highlight-B20d5C76.mjs +40 -0
- package/fesm2022/hyalo-angular-code-block-highlight-B20d5C76.mjs.map +1 -0
- package/fesm2022/hyalo-angular-code-block.mjs +161 -0
- package/fesm2022/hyalo-angular-code-block.mjs.map +1 -0
- package/fesm2022/hyalo-angular-command.mjs +193 -0
- package/fesm2022/hyalo-angular-command.mjs.map +1 -0
- package/fesm2022/hyalo-angular-copy.mjs +138 -0
- package/fesm2022/hyalo-angular-copy.mjs.map +1 -0
- package/fesm2022/hyalo-angular-core.mjs +424 -0
- package/fesm2022/hyalo-angular-core.mjs.map +1 -0
- package/fesm2022/hyalo-angular-description-list.mjs +57 -0
- package/fesm2022/hyalo-angular-description-list.mjs.map +1 -0
- package/fesm2022/hyalo-angular-dialog.mjs +600 -0
- package/fesm2022/hyalo-angular-dialog.mjs.map +1 -0
- package/fesm2022/hyalo-angular-divider.mjs +66 -0
- package/fesm2022/hyalo-angular-divider.mjs.map +1 -0
- package/fesm2022/hyalo-angular-empty-state.mjs +123 -0
- package/fesm2022/hyalo-angular-empty-state.mjs.map +1 -0
- package/fesm2022/hyalo-angular-field.mjs +344 -0
- package/fesm2022/hyalo-angular-field.mjs.map +1 -0
- package/fesm2022/hyalo-angular-filter.mjs +309 -0
- package/fesm2022/hyalo-angular-filter.mjs.map +1 -0
- package/fesm2022/hyalo-angular-hotspot.mjs +225 -0
- package/fesm2022/hyalo-angular-hotspot.mjs.map +1 -0
- package/fesm2022/hyalo-angular-hover-card.mjs +233 -0
- package/fesm2022/hyalo-angular-hover-card.mjs.map +1 -0
- package/fesm2022/hyalo-angular-icon.mjs +385 -0
- package/fesm2022/hyalo-angular-icon.mjs.map +1 -0
- package/fesm2022/hyalo-angular-image-compare.mjs +168 -0
- package/fesm2022/hyalo-angular-image-compare.mjs.map +1 -0
- package/fesm2022/hyalo-angular-interaction.mjs +446 -0
- package/fesm2022/hyalo-angular-interaction.mjs.map +1 -0
- package/fesm2022/hyalo-angular-kbd.mjs +41 -0
- package/fesm2022/hyalo-angular-kbd.mjs.map +1 -0
- package/fesm2022/hyalo-angular-lightbox.mjs +228 -0
- package/fesm2022/hyalo-angular-lightbox.mjs.map +1 -0
- package/fesm2022/hyalo-angular-link.mjs +42 -0
- package/fesm2022/hyalo-angular-link.mjs.map +1 -0
- package/fesm2022/hyalo-angular-list.mjs +131 -0
- package/fesm2022/hyalo-angular-list.mjs.map +1 -0
- package/fesm2022/hyalo-angular-marquee.mjs +197 -0
- package/fesm2022/hyalo-angular-marquee.mjs.map +1 -0
- package/fesm2022/hyalo-angular-menu.mjs +423 -0
- package/fesm2022/hyalo-angular-menu.mjs.map +1 -0
- package/fesm2022/hyalo-angular-mesh.mjs +126 -0
- package/fesm2022/hyalo-angular-mesh.mjs.map +1 -0
- package/fesm2022/hyalo-angular-motion.mjs +620 -0
- package/fesm2022/hyalo-angular-motion.mjs.map +1 -0
- package/fesm2022/hyalo-angular-navbar.mjs +343 -0
- package/fesm2022/hyalo-angular-navbar.mjs.map +1 -0
- package/fesm2022/hyalo-angular-navigation-menu.mjs +222 -0
- package/fesm2022/hyalo-angular-navigation-menu.mjs.map +1 -0
- package/fesm2022/hyalo-angular-number-ticker.mjs +174 -0
- package/fesm2022/hyalo-angular-number-ticker.mjs.map +1 -0
- package/fesm2022/hyalo-angular-overlay.mjs +163 -0
- package/fesm2022/hyalo-angular-overlay.mjs.map +1 -0
- package/fesm2022/hyalo-angular-pagination.mjs +187 -0
- package/fesm2022/hyalo-angular-pagination.mjs.map +1 -0
- package/fesm2022/hyalo-angular-popover-overlay-kit-6wPwnxln.mjs +3 -0
- package/fesm2022/hyalo-angular-popover.mjs +516 -0
- package/fesm2022/hyalo-angular-popover.mjs.map +1 -0
- package/fesm2022/hyalo-angular-progress.mjs +209 -0
- package/fesm2022/hyalo-angular-progress.mjs.map +1 -0
- package/fesm2022/hyalo-angular-progressive-blur.mjs +73 -0
- package/fesm2022/hyalo-angular-progressive-blur.mjs.map +1 -0
- package/fesm2022/hyalo-angular-refraction-renderer-5ZA-kfsA.mjs +186 -0
- package/fesm2022/hyalo-angular-refraction-renderer-5ZA-kfsA.mjs.map +1 -0
- package/fesm2022/hyalo-angular-refraction.mjs +178 -0
- package/fesm2022/hyalo-angular-refraction.mjs.map +1 -0
- package/fesm2022/hyalo-angular-scroll-area.mjs +93 -0
- package/fesm2022/hyalo-angular-scroll-area.mjs.map +1 -0
- package/fesm2022/hyalo-angular-scroll-to-top.mjs +127 -0
- package/fesm2022/hyalo-angular-scroll-to-top.mjs.map +1 -0
- package/fesm2022/hyalo-angular-segmented.mjs +223 -0
- package/fesm2022/hyalo-angular-segmented.mjs.map +1 -0
- package/fesm2022/hyalo-angular-select.mjs +561 -0
- package/fesm2022/hyalo-angular-select.mjs.map +1 -0
- package/fesm2022/hyalo-angular-sidebar.mjs +241 -0
- package/fesm2022/hyalo-angular-sidebar.mjs.map +1 -0
- package/fesm2022/hyalo-angular-skeleton.mjs +131 -0
- package/fesm2022/hyalo-angular-skeleton.mjs.map +1 -0
- package/fesm2022/hyalo-angular-sparkline.mjs +110 -0
- package/fesm2022/hyalo-angular-sparkline.mjs.map +1 -0
- package/fesm2022/hyalo-angular-split-text.mjs +126 -0
- package/fesm2022/hyalo-angular-split-text.mjs.map +1 -0
- package/fesm2022/hyalo-angular-stat.mjs +193 -0
- package/fesm2022/hyalo-angular-stat.mjs.map +1 -0
- package/fesm2022/hyalo-angular-stepper.mjs +254 -0
- package/fesm2022/hyalo-angular-stepper.mjs.map +1 -0
- package/fesm2022/hyalo-angular-table.mjs +335 -0
- package/fesm2022/hyalo-angular-table.mjs.map +1 -0
- package/fesm2022/hyalo-angular-tabs.mjs +324 -0
- package/fesm2022/hyalo-angular-tabs.mjs.map +1 -0
- package/fesm2022/hyalo-angular-theme.mjs +94 -0
- package/fesm2022/hyalo-angular-theme.mjs.map +1 -0
- package/fesm2022/hyalo-angular-timeline.mjs +157 -0
- package/fesm2022/hyalo-angular-timeline.mjs.map +1 -0
- package/fesm2022/hyalo-angular-toast.mjs +323 -0
- package/fesm2022/hyalo-angular-toast.mjs.map +1 -0
- package/fesm2022/hyalo-angular.mjs +2 -0
- package/package.json +329 -3
- package/styles/hyalo-core.css +25 -0
- package/styles/hyalo.css +17 -0
- package/styles/overlays/dialog.css +9 -0
- package/styles/overlays/popover.css +9 -0
- package/styles/overlays/select.css +9 -0
- package/styles/overlays/toast.css +8 -0
- package/styles/palettes/aurora.css +47 -0
- package/styles/palettes/ember.css +47 -0
- package/styles/palettes/graphite.css +47 -0
- package/styles/palettes/ocean.css +47 -0
- package/styles/palettes/orchid.css +47 -0
- package/styles/palettes/rose.css +47 -0
- package/styles/parts/card.css +49 -0
- package/styles/parts/dialog.css +116 -0
- package/styles/parts/drawer.css +124 -0
- package/styles/parts/field.css +44 -0
- package/styles/parts/glass.css +139 -0
- package/styles/parts/motion.css +101 -0
- package/styles/parts/navbar.css +55 -0
- package/styles/parts/popover.css +27 -0
- package/styles/parts/presence.css +55 -0
- package/styles/parts/reset.css +42 -0
- package/styles/parts/select.css +46 -0
- package/styles/parts/themes.css +105 -0
- package/styles/parts/toast.css +128 -0
- package/styles/parts/tokens.css +151 -0
- package/styles/parts/typography.css +81 -0
- package/types/hyalo-angular-accordion.d.ts +74 -0
- package/types/hyalo-angular-alert.d.ts +47 -0
- package/types/hyalo-angular-aspect-ratio.d.ts +13 -0
- package/types/hyalo-angular-avatar.d.ts +39 -0
- package/types/hyalo-angular-badge.d.ts +82 -0
- package/types/hyalo-angular-bento.d.ts +25 -0
- package/types/hyalo-angular-blocks.d.ts +272 -0
- package/types/hyalo-angular-border-beam.d.ts +15 -0
- package/types/hyalo-angular-breadcrumb.d.ts +22 -0
- package/types/hyalo-angular-button-group.d.ts +19 -0
- package/types/hyalo-angular-button.d.ts +89 -0
- package/types/hyalo-angular-card.d.ts +61 -0
- package/types/hyalo-angular-carousel.d.ts +147 -0
- package/types/hyalo-angular-chapter-nav.d.ts +79 -0
- package/types/hyalo-angular-chart.d.ts +90 -0
- package/types/hyalo-angular-choice.d.ts +259 -0
- package/types/hyalo-angular-code-block.d.ts +46 -0
- package/types/hyalo-angular-command.d.ts +41 -0
- package/types/hyalo-angular-copy.d.ts +39 -0
- package/types/hyalo-angular-core.d.ts +210 -0
- package/types/hyalo-angular-description-list.d.ts +16 -0
- package/types/hyalo-angular-dialog.d.ts +171 -0
- package/types/hyalo-angular-divider.d.ts +12 -0
- package/types/hyalo-angular-empty-state.d.ts +30 -0
- package/types/hyalo-angular-field.d.ts +141 -0
- package/types/hyalo-angular-filter.d.ts +122 -0
- package/types/hyalo-angular-hotspot.d.ts +70 -0
- package/types/hyalo-angular-hover-card.d.ts +47 -0
- package/types/hyalo-angular-icon.d.ts +122 -0
- package/types/hyalo-angular-image-compare.d.ts +55 -0
- package/types/hyalo-angular-interaction.d.ts +131 -0
- package/types/hyalo-angular-kbd.d.ts +5 -0
- package/types/hyalo-angular-lightbox.d.ts +67 -0
- package/types/hyalo-angular-link.d.ts +5 -0
- package/types/hyalo-angular-list.d.ts +30 -0
- package/types/hyalo-angular-marquee.d.ts +48 -0
- package/types/hyalo-angular-menu.d.ts +105 -0
- package/types/hyalo-angular-mesh.d.ts +36 -0
- package/types/hyalo-angular-motion.d.ts +218 -0
- package/types/hyalo-angular-navbar.d.ts +110 -0
- package/types/hyalo-angular-navigation-menu.d.ts +47 -0
- package/types/hyalo-angular-number-ticker.d.ts +52 -0
- package/types/hyalo-angular-overlay.d.ts +40 -0
- package/types/hyalo-angular-pagination.d.ts +59 -0
- package/types/hyalo-angular-popover.d.ts +152 -0
- package/types/hyalo-angular-progress.d.ts +46 -0
- package/types/hyalo-angular-progressive-blur.d.ts +14 -0
- package/types/hyalo-angular-refraction.d.ts +46 -0
- package/types/hyalo-angular-scroll-area.d.ts +18 -0
- package/types/hyalo-angular-scroll-to-top.d.ts +31 -0
- package/types/hyalo-angular-segmented.d.ts +79 -0
- package/types/hyalo-angular-select.d.ts +176 -0
- package/types/hyalo-angular-sidebar.d.ts +57 -0
- package/types/hyalo-angular-skeleton.d.ts +34 -0
- package/types/hyalo-angular-sparkline.d.ts +19 -0
- package/types/hyalo-angular-split-text.d.ts +24 -0
- package/types/hyalo-angular-stat.d.ts +56 -0
- package/types/hyalo-angular-stepper.d.ts +63 -0
- package/types/hyalo-angular-table.d.ts +125 -0
- package/types/hyalo-angular-tabs.d.ts +102 -0
- package/types/hyalo-angular-theme.d.ts +46 -0
- package/types/hyalo-angular-timeline.d.ts +36 -0
- package/types/hyalo-angular-toast.d.ts +79 -0
- package/types/hyalo-angular.d.ts +2 -0
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
import { DOCUMENT } from "@angular/common";
|
|
2
|
+
import * as i0 from "@angular/core";
|
|
3
|
+
import { ChangeDetectionStrategy, Component, ElementRef, inject, input, signal } from "@angular/core";
|
|
4
|
+
import { injectId } from "@hyalo/angular/core";
|
|
5
|
+
import { HyIcon } from "@hyalo/angular/icon";
|
|
6
|
+
import { CdkConnectedOverlay, CdkOverlayOrigin } from "@angular/cdk/overlay";
|
|
7
|
+
var HyNavigationMenu = class HyNavigationMenu {
|
|
8
|
+
items = input.required(...ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []);
|
|
9
|
+
label = input("Main navigation", ...ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []);
|
|
10
|
+
open = signal(null, ...ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []);
|
|
11
|
+
id = injectId("navigation");
|
|
12
|
+
host = inject(ElementRef);
|
|
13
|
+
document = inject(DOCUMENT);
|
|
14
|
+
trigger = null;
|
|
15
|
+
positions = [{
|
|
16
|
+
originX: "start",
|
|
17
|
+
originY: "bottom",
|
|
18
|
+
overlayX: "start",
|
|
19
|
+
overlayY: "top",
|
|
20
|
+
offsetY: 8
|
|
21
|
+
}, {
|
|
22
|
+
originX: "start",
|
|
23
|
+
originY: "top",
|
|
24
|
+
overlayX: "start",
|
|
25
|
+
overlayY: "bottom",
|
|
26
|
+
offsetY: -8
|
|
27
|
+
}];
|
|
28
|
+
outside(event) {
|
|
29
|
+
if (!this.host.nativeElement.contains(event.target)) this.open.set(null);
|
|
30
|
+
}
|
|
31
|
+
panel() {
|
|
32
|
+
return this.open() ? this.document.getElementById(this.id + "-" + this.open()) : null;
|
|
33
|
+
}
|
|
34
|
+
enterPanel(event) {
|
|
35
|
+
if (event.key !== "Tab" || event.shiftKey || !this.open()) return;
|
|
36
|
+
const first = this.panel()?.querySelector("a[href]");
|
|
37
|
+
if (first) {
|
|
38
|
+
event.preventDefault();
|
|
39
|
+
first.focus();
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
panelKeydown(event) {
|
|
43
|
+
if (event.key === "Escape") {
|
|
44
|
+
this.escape(event);
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
if (event.key !== "Tab") return;
|
|
48
|
+
const links = [...this.panel()?.querySelectorAll("a[href]") ?? []];
|
|
49
|
+
if (event.shiftKey && event.target === links[0]) {
|
|
50
|
+
event.preventDefault();
|
|
51
|
+
this.trigger?.focus();
|
|
52
|
+
} else if (!event.shiftKey && event.target === links[links.length - 1]) {
|
|
53
|
+
const targets = [...this.document.querySelectorAll("a[href],button:not(:disabled),input:not(:disabled),select:not(:disabled),textarea:not(:disabled),[tabindex=\"0\"]")].filter((el) => !el.closest("[hidden],[inert]") && el.getClientRects().length > 0);
|
|
54
|
+
const next = this.trigger ? targets[targets.indexOf(this.trigger) + 1] : void 0;
|
|
55
|
+
if (next) {
|
|
56
|
+
event.preventDefault();
|
|
57
|
+
this.open.set(null);
|
|
58
|
+
next.focus();
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
toggle(id, event) {
|
|
63
|
+
this.trigger = event.currentTarget;
|
|
64
|
+
this.open.update((value) => value === id ? null : id);
|
|
65
|
+
}
|
|
66
|
+
escape(event) {
|
|
67
|
+
if (this.open()) {
|
|
68
|
+
event.preventDefault();
|
|
69
|
+
event.stopPropagation();
|
|
70
|
+
this.open.set(null);
|
|
71
|
+
this.trigger?.focus();
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
focusOut(event) {
|
|
75
|
+
if (event.relatedTarget && !this.host.nativeElement.contains(event.relatedTarget) && !this.panel()?.contains(event.relatedTarget)) this.open.set(null);
|
|
76
|
+
}
|
|
77
|
+
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
78
|
+
minVersion: "12.0.0",
|
|
79
|
+
version: "22.2.3",
|
|
80
|
+
ngImport: i0,
|
|
81
|
+
type: HyNavigationMenu,
|
|
82
|
+
deps: [],
|
|
83
|
+
target: i0.ɵɵFactoryTarget.Component
|
|
84
|
+
});
|
|
85
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({
|
|
86
|
+
minVersion: "17.0.0",
|
|
87
|
+
version: "22.2.3",
|
|
88
|
+
type: HyNavigationMenu,
|
|
89
|
+
isStandalone: true,
|
|
90
|
+
selector: "hy-navigation-menu",
|
|
91
|
+
inputs: {
|
|
92
|
+
items: {
|
|
93
|
+
classPropertyName: "items",
|
|
94
|
+
publicName: "items",
|
|
95
|
+
isSignal: true,
|
|
96
|
+
isRequired: true,
|
|
97
|
+
transformFunction: null
|
|
98
|
+
},
|
|
99
|
+
label: {
|
|
100
|
+
classPropertyName: "label",
|
|
101
|
+
publicName: "label",
|
|
102
|
+
isSignal: true,
|
|
103
|
+
isRequired: false,
|
|
104
|
+
transformFunction: null
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
host: { listeners: {
|
|
108
|
+
"keydown.escape": "escape($event)",
|
|
109
|
+
"focusout": "focusOut($event)"
|
|
110
|
+
} },
|
|
111
|
+
ngImport: i0,
|
|
112
|
+
template: "<nav cdkOverlayOrigin #origin=\"cdkOverlayOrigin\" [attr.aria-label]=\"label()\">\n <ul>\n @for (item of items(); track item.id) {\n <li>\n @if (item.sections?.length) {\n <button\n type=\"button\"\n [id]=\"id + '-' + item.id + '-trigger'\"\n [attr.aria-expanded]=\"open() === item.id\"\n [attr.aria-controls]=\"id + '-' + item.id\"\n (click)=\"toggle(item.id, $event)\"\n (keydown)=\"enterPanel($event)\"\n >\n {{ item.label }}<hy-icon class=\"chevron\" name=\"chevron-down\" size=\"1rem\" />\n </button>\n <ng-template\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"origin\"\n [cdkConnectedOverlayOpen]=\"open() === item.id\"\n [cdkConnectedOverlayPositions]=\"positions\"\n [cdkConnectedOverlayPush]=\"true\"\n [cdkConnectedOverlayViewportMargin]=\"16\"\n (overlayOutsideClick)=\"outside($event)\"\n >\n <div\n class=\"panel\"\n tabindex=\"-1\"\n role=\"region\"\n (keydown)=\"panelKeydown($event)\"\n (focusout)=\"focusOut($event)\"\n [id]=\"id + '-' + item.id\"\n [attr.aria-labelledby]=\"id + '-' + item.id + '-trigger'\"\n >\n @for (section of item.sections; track $index) {\n <section>\n <h3>{{ section.label }}</h3>\n <ul>\n @for (link of section.links; track $index) {\n <li>\n <a [href]=\"link.href\" (click)=\"open.set(null)\"\n ><strong>{{ link.label }}</strong>\n @if (link.description) {\n <span>{{ link.description }}</span>\n }\n </a>\n </li>\n }\n </ul>\n </section>\n }\n </div>\n </ng-template>\n } @else {\n <a [href]=\"item.href\">{{ item.label }}</a>\n }\n </li>\n }\n </ul>\n</nav>\n",
|
|
113
|
+
styles: [":host{display:block;position:relative;color:var(--hy-ink)}ul{list-style:none;margin:0;padding:0}nav>ul{display:flex;align-items:center;flex-wrap:wrap;gap:.25rem}a,button{display:flex;align-items:center;gap:.5rem;padding:.75rem 1rem;min-block-size:44px;box-sizing:border-box;font:inherit;color:inherit;background:transparent;border:0;border-radius:var(--hy-radius-s);text-decoration:none;cursor:pointer}a:hover,button:hover,button[aria-expanded=true]{background:var(--hy-primary-wash)}.panel{inline-size:min(40rem,calc(100vw - 2rem));box-sizing:border-box;color:var(--hy-ink);display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,12rem),1fr));gap:1rem;padding:1.25rem;border:1px solid var(--hy-line-strong);border-radius:var(--hy-radius-l);background:var(--hy-surface-1);box-shadow:var(--hy-glass-shadow);max-block-size:65dvh;overflow:auto}.panel h3{font-size:.75rem;color:var(--hy-ink-3);margin:0 0 .5rem;padding-inline:1rem}.panel a{display:block}.panel strong{font-size:.875rem}.panel span{display:block;color:var(--hy-ink-2);font-size:.8125rem;margin-block-start:.25rem}:is(button,a,input):focus-visible{outline:2px solid var(--hy-primary);outline-offset:3px}.chevron{color:var(--hy-ink-3);transition:rotate var(--hy-dur-quick) var(--hy-ease-out)}button[aria-expanded=true] .chevron{rotate:180deg}@media(prefers-reduced-motion:reduce){.chevron{transition:none}}\n"],
|
|
114
|
+
dependencies: [
|
|
115
|
+
{
|
|
116
|
+
kind: "component",
|
|
117
|
+
type: HyIcon,
|
|
118
|
+
selector: "hy-icon",
|
|
119
|
+
inputs: [
|
|
120
|
+
"name",
|
|
121
|
+
"icon",
|
|
122
|
+
"label",
|
|
123
|
+
"size",
|
|
124
|
+
"strokeWidth"
|
|
125
|
+
]
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
kind: "directive",
|
|
129
|
+
type: CdkConnectedOverlay,
|
|
130
|
+
selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]",
|
|
131
|
+
inputs: [
|
|
132
|
+
"cdkConnectedOverlayOrigin",
|
|
133
|
+
"cdkConnectedOverlayPositions",
|
|
134
|
+
"cdkConnectedOverlayPositionStrategy",
|
|
135
|
+
"cdkConnectedOverlayOffsetX",
|
|
136
|
+
"cdkConnectedOverlayOffsetY",
|
|
137
|
+
"cdkConnectedOverlayWidth",
|
|
138
|
+
"cdkConnectedOverlayHeight",
|
|
139
|
+
"cdkConnectedOverlayMinWidth",
|
|
140
|
+
"cdkConnectedOverlayMinHeight",
|
|
141
|
+
"cdkConnectedOverlayBackdropClass",
|
|
142
|
+
"cdkConnectedOverlayPanelClass",
|
|
143
|
+
"cdkConnectedOverlayViewportMargin",
|
|
144
|
+
"cdkConnectedOverlayScrollStrategy",
|
|
145
|
+
"cdkConnectedOverlayOpen",
|
|
146
|
+
"cdkConnectedOverlayDisableClose",
|
|
147
|
+
"cdkConnectedOverlayTransformOriginOn",
|
|
148
|
+
"cdkConnectedOverlayHasBackdrop",
|
|
149
|
+
"cdkConnectedOverlayLockPosition",
|
|
150
|
+
"cdkConnectedOverlayFlexibleDimensions",
|
|
151
|
+
"cdkConnectedOverlayGrowAfterOpen",
|
|
152
|
+
"cdkConnectedOverlayPush",
|
|
153
|
+
"cdkConnectedOverlayDisposeOnNavigation",
|
|
154
|
+
"cdkConnectedOverlayUsePopover",
|
|
155
|
+
"cdkConnectedOverlayMatchWidth",
|
|
156
|
+
"cdkConnectedOverlay"
|
|
157
|
+
],
|
|
158
|
+
outputs: [
|
|
159
|
+
"backdropClick",
|
|
160
|
+
"positionChange",
|
|
161
|
+
"attach",
|
|
162
|
+
"detach",
|
|
163
|
+
"overlayKeydown",
|
|
164
|
+
"overlayOutsideClick"
|
|
165
|
+
],
|
|
166
|
+
exportAs: ["cdkConnectedOverlay"]
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
kind: "directive",
|
|
170
|
+
type: CdkOverlayOrigin,
|
|
171
|
+
selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]",
|
|
172
|
+
exportAs: ["cdkOverlayOrigin"]
|
|
173
|
+
}
|
|
174
|
+
],
|
|
175
|
+
changeDetection: i0.ChangeDetectionStrategy.OnPush
|
|
176
|
+
});
|
|
177
|
+
};
|
|
178
|
+
i0.ɵɵngDeclareClassMetadata({
|
|
179
|
+
minVersion: "12.0.0",
|
|
180
|
+
version: "22.2.3",
|
|
181
|
+
ngImport: i0,
|
|
182
|
+
type: HyNavigationMenu,
|
|
183
|
+
decorators: [{
|
|
184
|
+
type: Component,
|
|
185
|
+
args: [{
|
|
186
|
+
selector: "hy-navigation-menu",
|
|
187
|
+
imports: [
|
|
188
|
+
HyIcon,
|
|
189
|
+
CdkConnectedOverlay,
|
|
190
|
+
CdkOverlayOrigin
|
|
191
|
+
],
|
|
192
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
193
|
+
host: {
|
|
194
|
+
"(keydown.escape)": "escape($event)",
|
|
195
|
+
"(focusout)": "focusOut($event)"
|
|
196
|
+
},
|
|
197
|
+
template: "<nav cdkOverlayOrigin #origin=\"cdkOverlayOrigin\" [attr.aria-label]=\"label()\">\n <ul>\n @for (item of items(); track item.id) {\n <li>\n @if (item.sections?.length) {\n <button\n type=\"button\"\n [id]=\"id + '-' + item.id + '-trigger'\"\n [attr.aria-expanded]=\"open() === item.id\"\n [attr.aria-controls]=\"id + '-' + item.id\"\n (click)=\"toggle(item.id, $event)\"\n (keydown)=\"enterPanel($event)\"\n >\n {{ item.label }}<hy-icon class=\"chevron\" name=\"chevron-down\" size=\"1rem\" />\n </button>\n <ng-template\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"origin\"\n [cdkConnectedOverlayOpen]=\"open() === item.id\"\n [cdkConnectedOverlayPositions]=\"positions\"\n [cdkConnectedOverlayPush]=\"true\"\n [cdkConnectedOverlayViewportMargin]=\"16\"\n (overlayOutsideClick)=\"outside($event)\"\n >\n <div\n class=\"panel\"\n tabindex=\"-1\"\n role=\"region\"\n (keydown)=\"panelKeydown($event)\"\n (focusout)=\"focusOut($event)\"\n [id]=\"id + '-' + item.id\"\n [attr.aria-labelledby]=\"id + '-' + item.id + '-trigger'\"\n >\n @for (section of item.sections; track $index) {\n <section>\n <h3>{{ section.label }}</h3>\n <ul>\n @for (link of section.links; track $index) {\n <li>\n <a [href]=\"link.href\" (click)=\"open.set(null)\"\n ><strong>{{ link.label }}</strong>\n @if (link.description) {\n <span>{{ link.description }}</span>\n }\n </a>\n </li>\n }\n </ul>\n </section>\n }\n </div>\n </ng-template>\n } @else {\n <a [href]=\"item.href\">{{ item.label }}</a>\n }\n </li>\n }\n </ul>\n</nav>\n",
|
|
198
|
+
styles: [":host{display:block;position:relative;color:var(--hy-ink)}ul{list-style:none;margin:0;padding:0}nav>ul{display:flex;align-items:center;flex-wrap:wrap;gap:.25rem}a,button{display:flex;align-items:center;gap:.5rem;padding:.75rem 1rem;min-block-size:44px;box-sizing:border-box;font:inherit;color:inherit;background:transparent;border:0;border-radius:var(--hy-radius-s);text-decoration:none;cursor:pointer}a:hover,button:hover,button[aria-expanded=true]{background:var(--hy-primary-wash)}.panel{inline-size:min(40rem,calc(100vw - 2rem));box-sizing:border-box;color:var(--hy-ink);display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,12rem),1fr));gap:1rem;padding:1.25rem;border:1px solid var(--hy-line-strong);border-radius:var(--hy-radius-l);background:var(--hy-surface-1);box-shadow:var(--hy-glass-shadow);max-block-size:65dvh;overflow:auto}.panel h3{font-size:.75rem;color:var(--hy-ink-3);margin:0 0 .5rem;padding-inline:1rem}.panel a{display:block}.panel strong{font-size:.875rem}.panel span{display:block;color:var(--hy-ink-2);font-size:.8125rem;margin-block-start:.25rem}:is(button,a,input):focus-visible{outline:2px solid var(--hy-primary);outline-offset:3px}.chevron{color:var(--hy-ink-3);transition:rotate var(--hy-dur-quick) var(--hy-ease-out)}button[aria-expanded=true] .chevron{rotate:180deg}@media(prefers-reduced-motion:reduce){.chevron{transition:none}}\n"]
|
|
199
|
+
}]
|
|
200
|
+
}],
|
|
201
|
+
propDecorators: {
|
|
202
|
+
items: [{
|
|
203
|
+
type: i0.Input,
|
|
204
|
+
args: [{
|
|
205
|
+
isSignal: true,
|
|
206
|
+
alias: "items",
|
|
207
|
+
required: true
|
|
208
|
+
}]
|
|
209
|
+
}],
|
|
210
|
+
label: [{
|
|
211
|
+
type: i0.Input,
|
|
212
|
+
args: [{
|
|
213
|
+
isSignal: true,
|
|
214
|
+
alias: "label",
|
|
215
|
+
required: false
|
|
216
|
+
}]
|
|
217
|
+
}]
|
|
218
|
+
}
|
|
219
|
+
});
|
|
220
|
+
export { HyNavigationMenu };
|
|
221
|
+
|
|
222
|
+
//# sourceMappingURL=hyalo-angular-navigation-menu.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hyalo-angular-navigation-menu.mjs","names":[],"sources":["../../../projects/hyalo/navigation-menu/navigation-menu.ts","../../../projects/hyalo/navigation-menu/navigation-menu.html"],"sourcesContent":["import { DOCUMENT } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n inject,\n input,\n signal,\n} from '@angular/core';\nimport { injectId } from '@hyalo/angular/core';\nimport { HyIcon } from '@hyalo/angular/icon';\nimport {\n CdkConnectedOverlay,\n CdkOverlayOrigin,\n type ConnectedPosition,\n} from '@angular/cdk/overlay';\nexport interface HyNavigationLink {\n readonly label: string;\n readonly href: string;\n readonly description?: string;\n}\nexport interface HyNavigationSection {\n readonly label: string;\n readonly links: readonly HyNavigationLink[];\n}\nexport interface HyNavigationItem {\n readonly id: string;\n readonly label: string;\n readonly href?: string;\n readonly sections?: readonly HyNavigationSection[];\n}\n@Component({\n selector: 'hy-navigation-menu',\n imports: [HyIcon, CdkConnectedOverlay, CdkOverlayOrigin],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './navigation-menu.html',\n styleUrl: './navigation-menu.css',\n host: { '(keydown.escape)': 'escape($event)', '(focusout)': 'focusOut($event)' },\n})\nexport class HyNavigationMenu {\n readonly items = input.required<readonly HyNavigationItem[]>();\n readonly label = input('Main navigation');\n readonly open = signal<string | null>(null);\n protected readonly id = injectId('navigation');\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly document = inject(DOCUMENT);\n private trigger: HTMLElement | null = null;\n protected readonly positions: ConnectedPosition[] = [\n { originX: 'start', originY: 'bottom', overlayX: 'start', overlayY: 'top', offsetY: 8 },\n { originX: 'start', originY: 'top', overlayX: 'start', overlayY: 'bottom', offsetY: -8 },\n ];\n protected outside(event: MouseEvent): void {\n if (!this.host.nativeElement.contains(event.target as Node)) this.open.set(null);\n }\n private panel(): HTMLElement | null {\n return this.open() ? this.document.getElementById(this.id + '-' + this.open()) : null;\n }\n protected enterPanel(event: KeyboardEvent): void {\n if (event.key !== 'Tab' || event.shiftKey || !this.open()) return;\n const first = this.panel()?.querySelector<HTMLAnchorElement>('a[href]');\n if (first) {\n event.preventDefault();\n first.focus();\n }\n }\n protected panelKeydown(event: KeyboardEvent): void {\n if (event.key === 'Escape') {\n this.escape(event);\n return;\n }\n if (event.key !== 'Tab') return;\n const links = [...(this.panel()?.querySelectorAll<HTMLAnchorElement>('a[href]') ?? [])];\n if (event.shiftKey && event.target === links[0]) {\n event.preventDefault();\n this.trigger?.focus();\n } else if (!event.shiftKey && event.target === links[links.length - 1]) {\n const targets = [\n ...this.document.querySelectorAll<HTMLElement>(\n 'a[href],button:not(:disabled),input:not(:disabled),select:not(:disabled),textarea:not(:disabled),[tabindex=\"0\"]',\n ),\n ].filter((el) => !el.closest('[hidden],[inert]') && el.getClientRects().length > 0);\n const next = this.trigger ? targets[targets.indexOf(this.trigger) + 1] : undefined;\n if (next) {\n event.preventDefault();\n this.open.set(null);\n next.focus();\n }\n }\n }\n toggle(id: string, event: Event): void {\n this.trigger = event.currentTarget as HTMLElement;\n this.open.update((value) => (value === id ? null : id));\n }\n escape(event: Event): void {\n if (this.open()) {\n event.preventDefault();\n event.stopPropagation();\n this.open.set(null);\n this.trigger?.focus();\n }\n }\n focusOut(event: FocusEvent): void {\n if (\n event.relatedTarget &&\n !this.host.nativeElement.contains(event.relatedTarget as Node) &&\n !this.panel()?.contains(event.relatedTarget as Node)\n )\n this.open.set(null);\n }\n}\n","<nav cdkOverlayOrigin #origin=\"cdkOverlayOrigin\" [attr.aria-label]=\"label()\">\n <ul>\n @for (item of items(); track item.id) {\n <li>\n @if (item.sections?.length) {\n <button\n type=\"button\"\n [id]=\"id + '-' + item.id + '-trigger'\"\n [attr.aria-expanded]=\"open() === item.id\"\n [attr.aria-controls]=\"id + '-' + item.id\"\n (click)=\"toggle(item.id, $event)\"\n (keydown)=\"enterPanel($event)\"\n >\n {{ item.label }}<hy-icon class=\"chevron\" name=\"chevron-down\" size=\"1rem\" />\n </button>\n <ng-template\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"origin\"\n [cdkConnectedOverlayOpen]=\"open() === item.id\"\n [cdkConnectedOverlayPositions]=\"positions\"\n [cdkConnectedOverlayPush]=\"true\"\n [cdkConnectedOverlayViewportMargin]=\"16\"\n (overlayOutsideClick)=\"outside($event)\"\n >\n <div\n class=\"panel\"\n tabindex=\"-1\"\n role=\"region\"\n (keydown)=\"panelKeydown($event)\"\n (focusout)=\"focusOut($event)\"\n [id]=\"id + '-' + item.id\"\n [attr.aria-labelledby]=\"id + '-' + item.id + '-trigger'\"\n >\n @for (section of item.sections; track $index) {\n <section>\n <h3>{{ section.label }}</h3>\n <ul>\n @for (link of section.links; track $index) {\n <li>\n <a [href]=\"link.href\" (click)=\"open.set(null)\"\n ><strong>{{ link.label }}</strong>\n @if (link.description) {\n <span>{{ link.description }}</span>\n }\n </a>\n </li>\n }\n </ul>\n </section>\n }\n </div>\n </ng-template>\n } @else {\n <a [href]=\"item.href\">{{ item.label }}</a>\n }\n </li>\n }\n </ul>\n</nav>\n"],"mappings":"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"}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import * as i0 from "@angular/core";
|
|
2
|
+
import { ChangeDetectionStrategy, Component, DestroyRef, Injector, afterNextRender, booleanAttribute, computed, effect, inject, input, signal, untracked } from "@angular/core";
|
|
3
|
+
import { HyLocale } from "@hyalo/angular/core";
|
|
4
|
+
import { HyMotion, HySpring, injectHyVisibility } from "@hyalo/angular/motion";
|
|
5
|
+
var HyNumberTicker = class HyNumberTicker {
|
|
6
|
+
value = input.required(...ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []);
|
|
7
|
+
locale = input(...ngDevMode ? [void 0, { debugName: "locale" }] : /* istanbul ignore next */ []);
|
|
8
|
+
globalLocale = inject(HyLocale);
|
|
9
|
+
effectiveLocale = computed(() => this.locale() ?? this.globalLocale.locale(), ...ngDevMode ? [{ debugName: "effectiveLocale" }] : /* istanbul ignore next */ []);
|
|
10
|
+
format = input({ maximumFractionDigits: 0 }, ...ngDevMode ? [{ debugName: "format" }] : /* istanbul ignore next */ []);
|
|
11
|
+
animate = input(false, {
|
|
12
|
+
...ngDevMode ? { debugName: "animate" } : /* istanbul ignore next */ {},
|
|
13
|
+
transform: booleanAttribute
|
|
14
|
+
});
|
|
15
|
+
prefix = input("", ...ngDevMode ? [{ debugName: "prefix" }] : /* istanbul ignore next */ []);
|
|
16
|
+
suffix = input("", ...ngDevMode ? [{ debugName: "suffix" }] : /* istanbul ignore next */ []);
|
|
17
|
+
target = computed(() => Number.isFinite(this.value()) ? this.value() : 0, ...ngDevMode ? [{ debugName: "target" }] : /* istanbul ignore next */ []);
|
|
18
|
+
live = signal(null, ...ngDevMode ? [{ debugName: "live" }] : /* istanbul ignore next */ []);
|
|
19
|
+
formatter = computed(() => new Intl.NumberFormat(this.effectiveLocale(), this.format()), ...ngDevMode ? [{ debugName: "formatter" }] : /* istanbul ignore next */ []);
|
|
20
|
+
formatted = computed(() => this.prefix() + this.formatter().format(this.live() ?? this.target()) + this.suffix(), ...ngDevMode ? [{ debugName: "formatted" }] : /* istanbul ignore next */ []);
|
|
21
|
+
accessible = computed(() => this.prefix() + this.formatter().format(this.target()) + this.suffix(), ...ngDevMode ? [{ debugName: "accessible" }] : /* istanbul ignore next */ []);
|
|
22
|
+
motion = inject(HyMotion);
|
|
23
|
+
visible = injectHyVisibility();
|
|
24
|
+
constructor() {
|
|
25
|
+
const injector = inject(Injector), destroy = inject(DestroyRef);
|
|
26
|
+
let spring;
|
|
27
|
+
afterNextRender(() => {
|
|
28
|
+
const active = spring = new HySpring(this.target(), (value) => this.live.set(value));
|
|
29
|
+
effect(() => {
|
|
30
|
+
const target = this.target(), enabled = this.animate() && this.visible() && this.motion.enabled();
|
|
31
|
+
untracked(() => {
|
|
32
|
+
if (enabled) active.to(target);
|
|
33
|
+
else active.set(target);
|
|
34
|
+
});
|
|
35
|
+
}, { injector });
|
|
36
|
+
});
|
|
37
|
+
destroy.onDestroy(() => spring?.stop());
|
|
38
|
+
}
|
|
39
|
+
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
40
|
+
minVersion: "12.0.0",
|
|
41
|
+
version: "22.2.3",
|
|
42
|
+
ngImport: i0,
|
|
43
|
+
type: HyNumberTicker,
|
|
44
|
+
deps: [],
|
|
45
|
+
target: i0.ɵɵFactoryTarget.Component
|
|
46
|
+
});
|
|
47
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({
|
|
48
|
+
minVersion: "17.1.0",
|
|
49
|
+
version: "22.2.3",
|
|
50
|
+
type: HyNumberTicker,
|
|
51
|
+
isStandalone: true,
|
|
52
|
+
selector: "hy-number-ticker",
|
|
53
|
+
inputs: {
|
|
54
|
+
value: {
|
|
55
|
+
classPropertyName: "value",
|
|
56
|
+
publicName: "value",
|
|
57
|
+
isSignal: true,
|
|
58
|
+
isRequired: true,
|
|
59
|
+
transformFunction: null
|
|
60
|
+
},
|
|
61
|
+
locale: {
|
|
62
|
+
classPropertyName: "locale",
|
|
63
|
+
publicName: "locale",
|
|
64
|
+
isSignal: true,
|
|
65
|
+
isRequired: false,
|
|
66
|
+
transformFunction: null
|
|
67
|
+
},
|
|
68
|
+
format: {
|
|
69
|
+
classPropertyName: "format",
|
|
70
|
+
publicName: "format",
|
|
71
|
+
isSignal: true,
|
|
72
|
+
isRequired: false,
|
|
73
|
+
transformFunction: null
|
|
74
|
+
},
|
|
75
|
+
animate: {
|
|
76
|
+
classPropertyName: "animate",
|
|
77
|
+
publicName: "animate",
|
|
78
|
+
isSignal: true,
|
|
79
|
+
isRequired: false,
|
|
80
|
+
transformFunction: null
|
|
81
|
+
},
|
|
82
|
+
prefix: {
|
|
83
|
+
classPropertyName: "prefix",
|
|
84
|
+
publicName: "prefix",
|
|
85
|
+
isSignal: true,
|
|
86
|
+
isRequired: false,
|
|
87
|
+
transformFunction: null
|
|
88
|
+
},
|
|
89
|
+
suffix: {
|
|
90
|
+
classPropertyName: "suffix",
|
|
91
|
+
publicName: "suffix",
|
|
92
|
+
isSignal: true,
|
|
93
|
+
isRequired: false,
|
|
94
|
+
transformFunction: null
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
ngImport: i0,
|
|
98
|
+
template: `<span aria-hidden="true">{{ formatted() }}</span
|
|
99
|
+
><span class="sr">{{ accessible() }}</span>`,
|
|
100
|
+
isInline: true,
|
|
101
|
+
styles: [":host{font-variant-numeric:tabular-nums}.sr{position:absolute;inline-size:1px;block-size:1px;clip-path:inset(50%);overflow:hidden}\n"],
|
|
102
|
+
changeDetection: i0.ChangeDetectionStrategy.OnPush
|
|
103
|
+
});
|
|
104
|
+
};
|
|
105
|
+
i0.ɵɵngDeclareClassMetadata({
|
|
106
|
+
minVersion: "12.0.0",
|
|
107
|
+
version: "22.2.3",
|
|
108
|
+
ngImport: i0,
|
|
109
|
+
type: HyNumberTicker,
|
|
110
|
+
decorators: [{
|
|
111
|
+
type: Component,
|
|
112
|
+
args: [{
|
|
113
|
+
selector: "hy-number-ticker",
|
|
114
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
115
|
+
template: `<span aria-hidden="true">{{ formatted() }}</span
|
|
116
|
+
><span class="sr">{{ accessible() }}</span>`,
|
|
117
|
+
styles: [":host{font-variant-numeric:tabular-nums}.sr{position:absolute;inline-size:1px;block-size:1px;clip-path:inset(50%);overflow:hidden}\n"]
|
|
118
|
+
}]
|
|
119
|
+
}],
|
|
120
|
+
ctorParameters: () => [],
|
|
121
|
+
propDecorators: {
|
|
122
|
+
value: [{
|
|
123
|
+
type: i0.Input,
|
|
124
|
+
args: [{
|
|
125
|
+
isSignal: true,
|
|
126
|
+
alias: "value",
|
|
127
|
+
required: true
|
|
128
|
+
}]
|
|
129
|
+
}],
|
|
130
|
+
locale: [{
|
|
131
|
+
type: i0.Input,
|
|
132
|
+
args: [{
|
|
133
|
+
isSignal: true,
|
|
134
|
+
alias: "locale",
|
|
135
|
+
required: false
|
|
136
|
+
}]
|
|
137
|
+
}],
|
|
138
|
+
format: [{
|
|
139
|
+
type: i0.Input,
|
|
140
|
+
args: [{
|
|
141
|
+
isSignal: true,
|
|
142
|
+
alias: "format",
|
|
143
|
+
required: false
|
|
144
|
+
}]
|
|
145
|
+
}],
|
|
146
|
+
animate: [{
|
|
147
|
+
type: i0.Input,
|
|
148
|
+
args: [{
|
|
149
|
+
isSignal: true,
|
|
150
|
+
alias: "animate",
|
|
151
|
+
required: false
|
|
152
|
+
}]
|
|
153
|
+
}],
|
|
154
|
+
prefix: [{
|
|
155
|
+
type: i0.Input,
|
|
156
|
+
args: [{
|
|
157
|
+
isSignal: true,
|
|
158
|
+
alias: "prefix",
|
|
159
|
+
required: false
|
|
160
|
+
}]
|
|
161
|
+
}],
|
|
162
|
+
suffix: [{
|
|
163
|
+
type: i0.Input,
|
|
164
|
+
args: [{
|
|
165
|
+
isSignal: true,
|
|
166
|
+
alias: "suffix",
|
|
167
|
+
required: false
|
|
168
|
+
}]
|
|
169
|
+
}]
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
export { HyNumberTicker };
|
|
173
|
+
|
|
174
|
+
//# sourceMappingURL=hyalo-angular-number-ticker.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hyalo-angular-number-ticker.mjs","names":[],"sources":["../../../projects/hyalo/number-ticker/number-ticker.ts"],"sourcesContent":["import { booleanAttribute } from '@angular/core';\nimport { HyLocale } from '@hyalo/angular/core';\nimport {\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n Injector,\n afterNextRender,\n computed,\n effect,\n inject,\n input,\n signal,\n untracked,\n} from '@angular/core';\nimport { HyMotion, HySpring, injectHyVisibility } from '@hyalo/angular/motion';\n@Component({\n selector: 'hy-number-ticker',\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `<span aria-hidden=\"true\">{{ formatted() }}</span\n ><span class=\"sr\">{{ accessible() }}</span>`,\n styleUrl: './number-ticker.css',\n})\nexport class HyNumberTicker {\n readonly value = input.required<number>();\n readonly locale = input<string>();\n private readonly globalLocale = inject(HyLocale);\n private readonly effectiveLocale = computed(() => this.locale() ?? this.globalLocale.locale());\n readonly format = input<Intl.NumberFormatOptions>({ maximumFractionDigits: 0 });\n readonly animate = input(false, { transform: booleanAttribute });\n readonly prefix = input('');\n readonly suffix = input('');\n private readonly target = computed(() => (Number.isFinite(this.value()) ? this.value() : 0));\n private readonly live = signal<number | null>(null);\n private readonly formatter = computed(\n () => new Intl.NumberFormat(this.effectiveLocale(), this.format()),\n );\n readonly formatted = computed(\n () => this.prefix() + this.formatter().format(this.live() ?? this.target()) + this.suffix(),\n );\n readonly accessible = computed(\n () => this.prefix() + this.formatter().format(this.target()) + this.suffix(),\n );\n private readonly motion = inject(HyMotion);\n private readonly visible = injectHyVisibility();\n constructor() {\n const injector = inject(Injector),\n destroy = inject(DestroyRef);\n let spring: HySpring | undefined;\n afterNextRender(() => {\n const active = (spring = new HySpring(this.target(), (value) => this.live.set(value)));\n effect(\n () => {\n const target = this.target(),\n enabled = this.animate() && this.visible() && this.motion.enabled();\n untracked(() => {\n if (enabled) active.to(target);\n else active.set(target);\n });\n },\n { injector },\n );\n });\n destroy.onDestroy(() => spring?.stop());\n }\n}\n"],"mappings":";;;;AAuBA,IAAa,iBAAb,MAAa,eAAc;CAChB,QAAQ,MAAM,SAAkB,GAAA,YAAA,CAAA,EAAA,WAAA,QAAA,CAAA,+BAAA,CAAA,CAAA;CAChC,SAAS,MAAe,GAAA,YAAA,CAAA,QAAA,EAAA,WAAA,SAAA,CAAA,+BAAA,CAAA,CAAA;CAChB,eAAe,OAAO,QAAQ;CAC9B,kBAAkB,eAAe,KAAK,OAAM,KAAM,KAAK,aAAa,OAAM,GAAG,GAAA,YAAA,CAAA,EAAA,WAAA,kBAAA,CAAA,+BAAA,CAAA,CAAA;CACrF,SAAS,MAAgC,EAAE,uBAAuB,EAAC,GAAG,GAAA,YAAA,CAAA,EAAA,WAAA,SAAA,CAAA,+BAAA,CAAA,CAAA;CACtE,UAAU,MAAM,OAAK;EAAA,GAAA,YAAA,EAAA,WAAA,UAAA,+BAAA,CAAA;EAAI,WAAW;CAAgB,CAAA;CACpD,SAAS,MAAM,IAAG,GAAA,YAAA,CAAA,EAAA,WAAA,SAAA,CAAA,+BAAA,CAAA,CAAA;CAClB,SAAS,MAAM,IAAG,GAAA,YAAA,CAAA,EAAA,WAAA,SAAA,CAAA,+BAAA,CAAA,CAAA;CACV,SAAS,eAAgB,OAAO,SAAS,KAAK,MAAK,CAAE,IAAI,KAAK,MAAK,IAAK,GAAG,GAAA,YAAA,CAAA,EAAA,WAAA,SAAA,CAAA,+BAAA,CAAA,CAAA;CAC3E,OAAO,OAAsB,MAAK,GAAA,YAAA,CAAA,EAAA,WAAA,OAAA,CAAA,+BAAA,CAAA,CAAA;CAClC,YAAY,eACrB,IAAI,KAAK,aAAa,KAAK,gBAAe,GAAI,KAAK,OAAM,CAAE,GAClE,GAAA,YAAA,CAAA,EAAA,WAAA,YAAA,CAAA,+BAAA,CAAA,CAAA;CACQ,YAAY,eACb,KAAK,OAAM,IAAK,KAAK,UAAS,CAAE,CAAC,OAAO,KAAK,KAAI,KAAM,KAAK,OAAM,CAAE,IAAI,KAAK,OAAM,GAC1F,GAAA,YAAA,CAAA,EAAA,WAAA,YAAA,CAAA,+BAAA,CAAA,CAAA;CACQ,aAAa,eACd,KAAK,OAAM,IAAK,KAAK,UAAS,CAAE,CAAC,OAAO,KAAK,OAAM,CAAE,IAAI,KAAK,OAAM,GAC3E,GAAA,YAAA,CAAA,EAAA,WAAA,aAAA,CAAA,+BAAA,CAAA,CAAA;CACgB,SAAS,OAAO,QAAQ;CACxB,UAAU,mBAAkB;CAC7C,cAAA;EACE,MAAM,WAAW,OAAO,QAAQ,GAC9B,UAAU,OAAO,UAAU;EAC7B,IAAI;EACJ,sBAAqB;GACnB,MAAM,SAAU,SAAS,IAAI,SAAS,KAAK,OAAM,IAAK,UAAU,KAAK,KAAK,IAAI,KAAK,CAAC;GACpF,aACO;IACH,MAAM,SAAS,KAAK,OAAM,GACxB,UAAU,KAAK,QAAO,KAAM,KAAK,QAAO,KAAM,KAAK,OAAO,QAAO;IACnE,gBAAe;KACb,IAAI,SAAS,OAAO,GAAG,MAAM;UACxB,OAAO,IAAI,MAAM;IACxB,CAAC;GACH,GACA,EAAE,SAAQ,CAAE;EAEhB,CAAC;EACD,QAAQ,gBAAgB,QAAQ,KAAI,CAAE;CACxC;CAzCW,OAAA,OAAA,GAAA,mBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAAc,MAAA,CAAA;EAAA,QAAA,GAAA,gBAAA;CAAA,CAAA;CAAd,OAAA,OAAA,GAAA,qBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,MAAA;EAAc,cAAA;EAAA,UAAA;EAAA,QAAA;GAAA,OAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,QAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,QAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,SAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,QAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,QAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;EAAA;EAAA,UAAA;EAAA,UAJf;;EACoC,UAAA;EAAA,QAAA,CAAA,sIAAA;EAAA,iBAAA,GAAA,wBAAA;CAAA,CAAA;;AAGnC,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAc,YAAA,CAAA;EAP1B,MAAA;EACW,MAAA,CAAA;GAAA,UAAA;GAAkB,iBACX,wBAAwB;GAAM,UACrC;;GACoC,QAAA,CAAA,sIAAA;EAAA,CAAA"}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { MOTION } from "@hyalo/angular/motion";
|
|
2
|
+
const OPPOSITE = {
|
|
3
|
+
top: "bottom",
|
|
4
|
+
bottom: "top",
|
|
5
|
+
start: "end",
|
|
6
|
+
end: "start"
|
|
7
|
+
};
|
|
8
|
+
function position(placement, offset) {
|
|
9
|
+
switch (placement) {
|
|
10
|
+
case "top": return {
|
|
11
|
+
originX: "center",
|
|
12
|
+
originY: "top",
|
|
13
|
+
overlayX: "center",
|
|
14
|
+
overlayY: "bottom",
|
|
15
|
+
offsetY: -offset
|
|
16
|
+
};
|
|
17
|
+
case "bottom": return {
|
|
18
|
+
originX: "center",
|
|
19
|
+
originY: "bottom",
|
|
20
|
+
overlayX: "center",
|
|
21
|
+
overlayY: "top",
|
|
22
|
+
offsetY: offset
|
|
23
|
+
};
|
|
24
|
+
case "start": return {
|
|
25
|
+
originX: "start",
|
|
26
|
+
originY: "center",
|
|
27
|
+
overlayX: "end",
|
|
28
|
+
overlayY: "center",
|
|
29
|
+
offsetX: -offset
|
|
30
|
+
};
|
|
31
|
+
case "end": return {
|
|
32
|
+
originX: "end",
|
|
33
|
+
originY: "center",
|
|
34
|
+
overlayX: "start",
|
|
35
|
+
overlayY: "center",
|
|
36
|
+
offsetX: offset
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
function hyConnectedPositions(placement, offset = 8) {
|
|
41
|
+
return [position(placement, offset), position(OPPOSITE[placement], offset)];
|
|
42
|
+
}
|
|
43
|
+
function hyDropdownPositions(offset = 6) {
|
|
44
|
+
return [{
|
|
45
|
+
originX: "start",
|
|
46
|
+
originY: "bottom",
|
|
47
|
+
overlayX: "start",
|
|
48
|
+
overlayY: "top",
|
|
49
|
+
offsetY: offset
|
|
50
|
+
}, {
|
|
51
|
+
originX: "start",
|
|
52
|
+
originY: "top",
|
|
53
|
+
overlayX: "start",
|
|
54
|
+
overlayY: "bottom",
|
|
55
|
+
offsetY: -offset
|
|
56
|
+
}];
|
|
57
|
+
}
|
|
58
|
+
var HyPresence = class {
|
|
59
|
+
cancel = null;
|
|
60
|
+
get leaving() {
|
|
61
|
+
return this.cancel !== null;
|
|
62
|
+
}
|
|
63
|
+
enter(el) {
|
|
64
|
+
if (this.cancel) this.cancel();
|
|
65
|
+
else {
|
|
66
|
+
el.dataset["state"] = "closed";
|
|
67
|
+
el.offsetWidth;
|
|
68
|
+
}
|
|
69
|
+
el.dataset["state"] = "open";
|
|
70
|
+
}
|
|
71
|
+
leave(el, done) {
|
|
72
|
+
if (this.cancel) return;
|
|
73
|
+
el.dataset["state"] = "closing";
|
|
74
|
+
const stop = () => {
|
|
75
|
+
el.removeEventListener("transitionend", onEnd);
|
|
76
|
+
clearTimeout(timer);
|
|
77
|
+
this.cancel = null;
|
|
78
|
+
};
|
|
79
|
+
const onEnd = (event) => {
|
|
80
|
+
if (event.target !== el || event.propertyName !== "opacity") return;
|
|
81
|
+
stop();
|
|
82
|
+
done();
|
|
83
|
+
};
|
|
84
|
+
const timer = setTimeout(() => {
|
|
85
|
+
stop();
|
|
86
|
+
done();
|
|
87
|
+
}, MOTION.quick.duration * 1e3 + 80);
|
|
88
|
+
el.addEventListener("transitionend", onEnd);
|
|
89
|
+
this.cancel = stop;
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
function triangle(p, a, b, c) {
|
|
93
|
+
const side = (u, v, w) => (u.x - w.x) * (v.y - w.y) - (v.x - w.x) * (u.y - w.y);
|
|
94
|
+
const d = [
|
|
95
|
+
side(p, a, b),
|
|
96
|
+
side(p, b, c),
|
|
97
|
+
side(p, c, a)
|
|
98
|
+
];
|
|
99
|
+
return !(d.some((v) => v < 0) && d.some((v) => v > 0));
|
|
100
|
+
}
|
|
101
|
+
var HyHoverIntent = class {
|
|
102
|
+
document;
|
|
103
|
+
timer;
|
|
104
|
+
abort;
|
|
105
|
+
constructor(document) {
|
|
106
|
+
this.document = document;
|
|
107
|
+
}
|
|
108
|
+
cancel() {
|
|
109
|
+
clearTimeout(this.timer);
|
|
110
|
+
this.abort?.abort();
|
|
111
|
+
this.abort = void 0;
|
|
112
|
+
}
|
|
113
|
+
leave(event, target, close) {
|
|
114
|
+
this.cancel();
|
|
115
|
+
const finish = () => {
|
|
116
|
+
this.cancel();
|
|
117
|
+
close();
|
|
118
|
+
};
|
|
119
|
+
this.timer = setTimeout(finish, 150);
|
|
120
|
+
if (!event || !target || event.pointerType === "touch") return;
|
|
121
|
+
const bounds = target.getBoundingClientRect(), start = {
|
|
122
|
+
x: event.clientX,
|
|
123
|
+
y: event.clientY
|
|
124
|
+
};
|
|
125
|
+
const dx = (bounds.left + bounds.right) / 2 - start.x, dy = (bounds.top + bounds.bottom) / 2 - start.y;
|
|
126
|
+
const horizontal = Math.abs(dx) / Math.max(1, bounds.width) > Math.abs(dy) / Math.max(1, bounds.height);
|
|
127
|
+
const edge = horizontal ? dx > 0 ? bounds.left : bounds.right : dy > 0 ? bounds.top : bounds.bottom;
|
|
128
|
+
const a = horizontal ? {
|
|
129
|
+
x: edge,
|
|
130
|
+
y: bounds.top - 8
|
|
131
|
+
} : {
|
|
132
|
+
x: bounds.left - 8,
|
|
133
|
+
y: edge
|
|
134
|
+
};
|
|
135
|
+
const b = horizontal ? {
|
|
136
|
+
x: edge,
|
|
137
|
+
y: bounds.bottom + 8
|
|
138
|
+
} : {
|
|
139
|
+
x: bounds.right + 8,
|
|
140
|
+
y: edge
|
|
141
|
+
};
|
|
142
|
+
const deadline = performance.now() + 500;
|
|
143
|
+
this.abort = new AbortController();
|
|
144
|
+
this.document.addEventListener("pointermove", (move) => {
|
|
145
|
+
if (performance.now() >= deadline) {
|
|
146
|
+
finish();
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
if (!triangle({
|
|
150
|
+
x: move.clientX,
|
|
151
|
+
y: move.clientY
|
|
152
|
+
}, start, a, b)) return;
|
|
153
|
+
clearTimeout(this.timer);
|
|
154
|
+
this.timer = setTimeout(finish, Math.min(150, deadline - performance.now()));
|
|
155
|
+
}, {
|
|
156
|
+
passive: true,
|
|
157
|
+
signal: this.abort.signal
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
export { HyHoverIntent, hyConnectedPositions, hyDropdownPositions, HyPresence as ɵHyPresence };
|
|
162
|
+
|
|
163
|
+
//# sourceMappingURL=hyalo-angular-overlay.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hyalo-angular-overlay.mjs","names":[],"sources":["../../../projects/hyalo/overlay/positions.ts","../../../projects/hyalo/overlay/presence.ts","../../../projects/hyalo/overlay/hover-intent.ts"],"sourcesContent":["import type { ConnectedPosition } from '@angular/cdk/overlay';\r\n\r\n/**\r\n * Where a floating element sits relative to its trigger. `start` and `end`\r\n * follow the text direction, so `end` is on the right in LTR and on the left\r\n * in RTL.\r\n */\r\nexport type HyPlacement = 'top' | 'bottom' | 'start' | 'end';\r\n\r\nconst OPPOSITE: Record<HyPlacement, HyPlacement> = {\r\n top: 'bottom',\r\n bottom: 'top',\r\n start: 'end',\r\n end: 'start',\r\n};\r\n\r\nfunction position(placement: HyPlacement, offset: number): ConnectedPosition {\r\n switch (placement) {\r\n case 'top':\r\n return {\r\n originX: 'center',\r\n originY: 'top',\r\n overlayX: 'center',\r\n overlayY: 'bottom',\r\n offsetY: -offset,\r\n };\r\n case 'bottom':\r\n return {\r\n originX: 'center',\r\n originY: 'bottom',\r\n overlayX: 'center',\r\n overlayY: 'top',\r\n offsetY: offset,\r\n };\r\n case 'start':\r\n return {\r\n originX: 'start',\r\n originY: 'center',\r\n overlayX: 'end',\r\n overlayY: 'center',\r\n offsetX: -offset,\r\n };\r\n case 'end':\r\n return {\r\n originX: 'end',\r\n originY: 'center',\r\n overlayX: 'start',\r\n overlayY: 'center',\r\n offsetX: offset,\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * CDK positions for a placement, with the opposite side as the first\r\n * fallback when there is no room.\r\n */\r\nexport function hyConnectedPositions(placement: HyPlacement, offset = 8): ConnectedPosition[] {\r\n return [position(placement, offset), position(OPPOSITE[placement], offset)];\r\n}\r\n\r\n/** Positions for a dropdown that lines up with the trigger's start edge. */\r\nexport function hyDropdownPositions(offset = 6): ConnectedPosition[] {\r\n return [\r\n { originX: 'start', originY: 'bottom', overlayX: 'start', overlayY: 'top', offsetY: offset },\r\n { originX: 'start', originY: 'top', overlayX: 'start', overlayY: 'bottom', offsetY: -offset },\r\n ];\r\n}\r\n","import { MOTION } from '@hyalo/angular/motion';\r\n\r\n/**\r\n * @internal Enter and exit for small overlays (tooltips, popovers, select\r\n * panels), driven by `data-state` and CSS transitions.\r\n *\r\n * Transitions start from the current value, so reopening a panel while it\r\n * is still fading out simply turns it around, with no jump.\r\n */\r\nexport class HyPresence {\r\n private cancel: (() => void) | null = null;\r\n\r\n /** True while an exit is playing. */\r\n get leaving(): boolean {\r\n return this.cancel !== null;\r\n }\r\n\r\n /** Shows a panel that was just attached, or turns a leaving one around. */\r\n enter(el: HTMLElement): void {\r\n if (this.cancel) {\r\n this.cancel();\r\n } else {\r\n el.dataset['state'] = 'closed';\r\n // Commit the closed pose so the change to open transitions.\r\n void el.offsetWidth;\r\n }\r\n el.dataset['state'] = 'open';\r\n }\r\n\r\n /** Plays the exit, then calls `done`, unless `enter` turns it around first. */\r\n leave(el: HTMLElement, done: () => void): void {\r\n if (this.cancel) return;\r\n el.dataset['state'] = 'closing';\r\n const stop = (): void => {\r\n el.removeEventListener('transitionend', onEnd);\r\n clearTimeout(timer);\r\n this.cancel = null;\r\n };\r\n const onEnd = (event: TransitionEvent): void => {\r\n if (event.target !== el || event.propertyName !== 'opacity') return;\r\n stop();\r\n done();\r\n };\r\n // A safety net for when transitionend never comes, as with no transition.\r\n const timer = setTimeout(\r\n () => {\r\n stop();\r\n done();\r\n },\r\n MOTION.quick.duration * 1000 + 80,\r\n );\r\n el.addEventListener('transitionend', onEnd);\r\n this.cancel = stop;\r\n }\r\n}\r\n","interface Point {\r\n x: number;\r\n y: number;\r\n}\r\nfunction triangle(p: Point, a: Point, b: Point, c: Point): boolean {\r\n const side = (u: Point, v: Point, w: Point): number =>\r\n (u.x - w.x) * (v.y - w.y) - (v.x - w.x) * (u.y - w.y);\r\n const d = [side(p, a, b), side(p, b, c), side(p, c, a)];\r\n return !(d.some((v) => v < 0) && d.some((v) => v > 0));\r\n}\r\n/** Bounded pointer grace; keyboard dismissal never waits for the corridor. */\r\nexport class HyHoverIntent {\r\n private timer?: ReturnType<typeof setTimeout>;\r\n private abort?: AbortController;\r\n constructor(private readonly document: Document) {}\r\n cancel(): void {\r\n clearTimeout(this.timer);\r\n this.abort?.abort();\r\n this.abort = undefined;\r\n }\r\n leave(event: PointerEvent | undefined, target: HTMLElement | undefined, close: () => void): void {\r\n this.cancel();\r\n const finish = (): void => {\r\n this.cancel();\r\n close();\r\n };\r\n this.timer = setTimeout(finish, 150);\r\n if (!event || !target || event.pointerType === 'touch') return;\r\n const bounds = target.getBoundingClientRect(),\r\n start = { x: event.clientX, y: event.clientY };\r\n const dx = (bounds.left + bounds.right) / 2 - start.x,\r\n dy = (bounds.top + bounds.bottom) / 2 - start.y;\r\n const horizontal =\r\n Math.abs(dx) / Math.max(1, bounds.width) > Math.abs(dy) / Math.max(1, bounds.height);\r\n const edge = horizontal\r\n ? dx > 0\r\n ? bounds.left\r\n : bounds.right\r\n : dy > 0\r\n ? bounds.top\r\n : bounds.bottom;\r\n const a = horizontal ? { x: edge, y: bounds.top - 8 } : { x: bounds.left - 8, y: edge };\r\n const b = horizontal ? { x: edge, y: bounds.bottom + 8 } : { x: bounds.right + 8, y: edge };\r\n const deadline = performance.now() + 500;\r\n this.abort = new AbortController();\r\n this.document.addEventListener(\r\n 'pointermove',\r\n (move) => {\r\n if (performance.now() >= deadline) {\r\n finish();\r\n return;\r\n }\r\n if (!triangle({ x: move.clientX, y: move.clientY }, start, a, b)) return;\r\n clearTimeout(this.timer);\r\n this.timer = setTimeout(finish, Math.min(150, deadline - performance.now()));\r\n },\r\n { passive: true, signal: this.abort.signal },\r\n );\r\n }\r\n}\r\n"],"mappings":"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"}
|