@hyalo/angular 0.1.0 → 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 -41
- package/README.md +46 -32
- package/fesm2022/hyalo-angular-accordion.mjs +6 -6
- package/fesm2022/hyalo-angular-accordion.mjs.map +1 -1
- 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 +4 -3
- package/fesm2022/hyalo-angular-button.mjs.map +1 -1
- package/fesm2022/hyalo-angular-card.mjs +2 -2
- package/fesm2022/hyalo-angular-card.mjs.map +1 -1
- 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 +2 -1
- package/fesm2022/hyalo-angular-choice.mjs.map +1 -1
- 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 +51 -22
- package/fesm2022/hyalo-angular-dialog.mjs.map +1 -1
- 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 +41 -9
- package/fesm2022/hyalo-angular-field.mjs.map +1 -1
- 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 +42 -0
- package/fesm2022/hyalo-angular-icon.mjs.map +1 -1
- 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 +32 -41
- package/fesm2022/hyalo-angular-interaction.mjs.map +1 -1
- 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 +1 -1
- package/fesm2022/hyalo-angular-navbar.mjs.map +1 -1
- 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 +71 -2
- package/fesm2022/hyalo-angular-overlay.mjs.map +1 -1
- package/fesm2022/hyalo-angular-pagination.mjs +187 -0
- package/fesm2022/hyalo-angular-pagination.mjs.map +1 -0
- package/fesm2022/hyalo-angular-popover.mjs +34 -5
- package/fesm2022/hyalo-angular-popover.mjs.map +1 -1
- 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 +1 -1
- package/fesm2022/hyalo-angular-segmented.mjs.map +1 -1
- package/fesm2022/hyalo-angular-select.mjs +112 -15
- package/fesm2022/hyalo-angular-select.mjs.map +1 -1
- 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 +1 -1
- package/fesm2022/hyalo-angular-tabs.mjs.map +1 -1
- package/fesm2022/hyalo-angular-theme.mjs +1 -1
- package/fesm2022/hyalo-angular-theme.mjs.map +1 -1
- package/fesm2022/hyalo-angular-timeline.mjs +157 -0
- package/fesm2022/hyalo-angular-timeline.mjs.map +1 -0
- package/fesm2022/hyalo-angular-toast.mjs +2 -1
- package/fesm2022/hyalo-angular-toast.mjs.map +1 -1
- package/fesm2022/hyalo-angular.mjs +2 -473
- package/package.json +198 -2
- package/styles/parts/field.css +44 -36
- package/styles/parts/glass.css +2 -0
- package/styles/parts/motion.css +19 -0
- package/styles/parts/typography.css +17 -0
- package/types/hyalo-angular-accordion.d.ts +1 -1
- 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 +4 -3
- package/types/hyalo-angular-card.d.ts +1 -1
- 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-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 +2 -1
- 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 +10 -4
- 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-image-compare.d.ts +55 -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-navigation-menu.d.ts +47 -0
- package/types/hyalo-angular-number-ticker.d.ts +52 -0
- package/types/hyalo-angular-overlay.d.ts +9 -0
- package/types/hyalo-angular-pagination.d.ts +59 -0
- package/types/hyalo-angular-popover.d.ts +10 -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 +1 -1
- package/types/hyalo-angular-select.d.ts +49 -3
- 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-timeline.d.ts +36 -0
- package/types/hyalo-angular.d.ts +2 -345
- package/fesm2022/hyalo-angular.mjs.map +0 -1
|
@@ -0,0 +1,391 @@
|
|
|
1
|
+
import { HyFidelity, HyLocale } from "@hyalo/angular/core";
|
|
2
|
+
import { CdkConnectedOverlay, CdkOverlayOrigin } from "@angular/cdk/overlay";
|
|
3
|
+
import { DOCUMENT } from "@angular/common";
|
|
4
|
+
import * as i0 from "@angular/core";
|
|
5
|
+
import { ChangeDetectionStrategy, Component, DestroyRef, ElementRef, InjectionToken, afterNextRender, afterRenderEffect, computed, inject, input, signal, untracked, viewChild } from "@angular/core";
|
|
6
|
+
let engine;
|
|
7
|
+
const loadEngine = () => engine ??= import("./hyalo-angular-chart-engine-DSJop6He.mjs").catch((error) => {
|
|
8
|
+
engine = void 0;
|
|
9
|
+
throw error;
|
|
10
|
+
});
|
|
11
|
+
const HY_CHART_LOADER = new InjectionToken("HY_CHART_LOADER", {
|
|
12
|
+
providedIn: "root",
|
|
13
|
+
factory: () => loadEngine
|
|
14
|
+
});
|
|
15
|
+
var HyChart = class HyChart {
|
|
16
|
+
data = input.required(...ngDevMode ? [{ debugName: "data" }] : /* istanbul ignore next */ []);
|
|
17
|
+
type = input("line", ...ngDevMode ? [{ debugName: "type" }] : /* istanbul ignore next */ []);
|
|
18
|
+
label = input.required(...ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []);
|
|
19
|
+
summary = input("", ...ngDevMode ? [{ debugName: "summary" }] : /* istanbul ignore next */ []);
|
|
20
|
+
locale = input(...ngDevMode ? [void 0, { debugName: "locale" }] : /* istanbul ignore next */ []);
|
|
21
|
+
globalLocale = inject(HyLocale);
|
|
22
|
+
effectiveLocale = computed(() => this.locale() ?? this.globalLocale.locale(), ...ngDevMode ? [{ debugName: "effectiveLocale" }] : /* istanbul ignore next */ []);
|
|
23
|
+
tableLabel = input("View chart data", ...ngDevMode ? [{ debugName: "tableLabel" }] : /* istanbul ignore next */ []);
|
|
24
|
+
error = signal(false, ...ngDevMode ? [{ debugName: "error" }] : /* istanbul ignore next */ []);
|
|
25
|
+
tooltip = signal(null, ...ngDevMode ? [{ debugName: "tooltip" }] : /* istanbul ignore next */ []);
|
|
26
|
+
tooltipPositions = [{
|
|
27
|
+
originX: "start",
|
|
28
|
+
originY: "top",
|
|
29
|
+
overlayX: "start",
|
|
30
|
+
overlayY: "bottom"
|
|
31
|
+
}];
|
|
32
|
+
fidelity = inject(HyFidelity);
|
|
33
|
+
fidelityTier = this.fidelity.tier;
|
|
34
|
+
visible = signal(false, ...ngDevMode ? [{ debugName: "visible" }] : /* istanbul ignore next */ []);
|
|
35
|
+
theme = signal(0, ...ngDevMode ? [{ debugName: "theme" }] : /* istanbul ignore next */ []);
|
|
36
|
+
canvas = viewChild("canvas", ...ngDevMode ? [{ debugName: "canvas" }] : /* istanbul ignore next */ []);
|
|
37
|
+
palette = viewChild("palette", ...ngDevMode ? [{ debugName: "palette" }] : /* istanbul ignore next */ []);
|
|
38
|
+
document = inject(DOCUMENT);
|
|
39
|
+
load = inject(HY_CHART_LOADER);
|
|
40
|
+
host = inject(ElementRef);
|
|
41
|
+
chart;
|
|
42
|
+
generation = 0;
|
|
43
|
+
destroyed = false;
|
|
44
|
+
formatter = computed(() => new Intl.NumberFormat(this.effectiveLocale()), ...ngDevMode ? [{ debugName: "formatter" }] : /* istanbul ignore next */ []);
|
|
45
|
+
rows = computed(() => this.data().labels.map((label, index) => ({
|
|
46
|
+
label,
|
|
47
|
+
values: this.data().series.map((series) => {
|
|
48
|
+
const value = series.values[index];
|
|
49
|
+
return value == null || !Number.isFinite(value) ? "–" : this.formatter().format(value);
|
|
50
|
+
})
|
|
51
|
+
})), ...ngDevMode ? [{ debugName: "rows" }] : /* istanbul ignore next */ []);
|
|
52
|
+
constructor() {
|
|
53
|
+
let observer, mutation;
|
|
54
|
+
let media;
|
|
55
|
+
const changed = () => this.theme.update((value) => value + 1);
|
|
56
|
+
afterNextRender(() => {
|
|
57
|
+
if (typeof IntersectionObserver === "undefined") this.visible.set(true);
|
|
58
|
+
else {
|
|
59
|
+
observer = new IntersectionObserver((entries) => this.visible.set(entries.some((entry) => entry.isIntersecting)), { rootMargin: "150px" });
|
|
60
|
+
observer.observe(this.host.nativeElement);
|
|
61
|
+
}
|
|
62
|
+
mutation = new MutationObserver(changed);
|
|
63
|
+
for (let element = this.host.nativeElement; element; element = element.parentElement) mutation.observe(element, {
|
|
64
|
+
attributes: true,
|
|
65
|
+
attributeFilter: [
|
|
66
|
+
"class",
|
|
67
|
+
"style",
|
|
68
|
+
"dir",
|
|
69
|
+
"lang",
|
|
70
|
+
"data-hy-theme",
|
|
71
|
+
"data-hy-palette",
|
|
72
|
+
"data-hy-fidelity"
|
|
73
|
+
]
|
|
74
|
+
});
|
|
75
|
+
media = this.document.defaultView?.matchMedia("(prefers-color-scheme: dark)");
|
|
76
|
+
media?.addEventListener("change", changed);
|
|
77
|
+
});
|
|
78
|
+
afterRenderEffect(() => {
|
|
79
|
+
const data = this.data(), type = this.type(), locale = this.effectiveLocale();
|
|
80
|
+
this.theme();
|
|
81
|
+
this.fidelity.tier();
|
|
82
|
+
if (!this.visible()) return;
|
|
83
|
+
untracked(() => void this.render(data, type, locale));
|
|
84
|
+
});
|
|
85
|
+
inject(DestroyRef).onDestroy(() => {
|
|
86
|
+
this.destroyed = true;
|
|
87
|
+
this.generation++;
|
|
88
|
+
observer?.disconnect();
|
|
89
|
+
mutation?.disconnect();
|
|
90
|
+
media?.removeEventListener("change", changed);
|
|
91
|
+
this.tooltip.set(null);
|
|
92
|
+
this.chart?.destroy();
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
retry() {
|
|
96
|
+
this.theme.update((value) => value + 1);
|
|
97
|
+
}
|
|
98
|
+
async render(data, type, locale) {
|
|
99
|
+
const generation = ++this.generation;
|
|
100
|
+
try {
|
|
101
|
+
const kit = await this.load();
|
|
102
|
+
if (this.destroyed || generation !== this.generation) return;
|
|
103
|
+
const canvas = this.canvas()?.nativeElement, palette = this.palette()?.nativeElement, view = this.document.defaultView;
|
|
104
|
+
if (!canvas || !palette || !view) return;
|
|
105
|
+
const colors = [...palette.children].map((element) => view.getComputedStyle(element).color);
|
|
106
|
+
const ink = view.getComputedStyle(palette).color, border = view.getComputedStyle(palette).borderBlockStartColor;
|
|
107
|
+
const rtl = view.getComputedStyle(this.host.nativeElement).direction === "rtl";
|
|
108
|
+
const datasets = data.series.map((series, index) => ({
|
|
109
|
+
label: series.label,
|
|
110
|
+
data: data.labels.map((_, i) => {
|
|
111
|
+
const value = series.values[i];
|
|
112
|
+
return value != null && Number.isFinite(value) ? value : null;
|
|
113
|
+
}),
|
|
114
|
+
borderColor: colors[index % colors.length],
|
|
115
|
+
backgroundColor: type === "doughnut" ? data.labels.map((_, i) => colors[i % colors.length]) : type === "area" ? (context) => {
|
|
116
|
+
const area = context.chart.chartArea;
|
|
117
|
+
if (!area) return colors[index % colors.length];
|
|
118
|
+
const gradient = context.chart.ctx.createLinearGradient(0, area.top, 0, area.bottom);
|
|
119
|
+
const color = colors[index % colors.length] ?? "transparent";
|
|
120
|
+
gradient.addColorStop(0, color);
|
|
121
|
+
gradient.addColorStop(1, "transparent");
|
|
122
|
+
return gradient;
|
|
123
|
+
} : colors[index % colors.length],
|
|
124
|
+
borderWidth: 2,
|
|
125
|
+
pointRadius: 2,
|
|
126
|
+
tension: .25,
|
|
127
|
+
fill: type === "area"
|
|
128
|
+
}));
|
|
129
|
+
this.tooltip.set(null);
|
|
130
|
+
this.chart?.destroy();
|
|
131
|
+
this.chart = void 0;
|
|
132
|
+
this.chart = new kit.Chart(canvas, {
|
|
133
|
+
type: type === "area" ? "line" : type,
|
|
134
|
+
data: {
|
|
135
|
+
labels: [...data.labels],
|
|
136
|
+
datasets
|
|
137
|
+
},
|
|
138
|
+
options: {
|
|
139
|
+
responsive: true,
|
|
140
|
+
maintainAspectRatio: false,
|
|
141
|
+
animation: false,
|
|
142
|
+
locale,
|
|
143
|
+
plugins: {
|
|
144
|
+
legend: {
|
|
145
|
+
display: data.series.length > 1 || type === "doughnut",
|
|
146
|
+
rtl,
|
|
147
|
+
textDirection: rtl ? "rtl" : "ltr",
|
|
148
|
+
labels: {
|
|
149
|
+
color: ink,
|
|
150
|
+
usePointStyle: true
|
|
151
|
+
}
|
|
152
|
+
},
|
|
153
|
+
tooltip: {
|
|
154
|
+
enabled: false,
|
|
155
|
+
external: ({ tooltip }) => {
|
|
156
|
+
if (!tooltip.opacity) {
|
|
157
|
+
this.tooltip.set(null);
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
this.tooltip.set({
|
|
161
|
+
x: tooltip.caretX,
|
|
162
|
+
y: tooltip.caretY - 8,
|
|
163
|
+
title: tooltip.title?.join(" ") ?? "",
|
|
164
|
+
lines: tooltip.dataPoints.map((point) => `${point.dataset.label ?? ""}: ${point.formattedValue}`)
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
},
|
|
169
|
+
...type === "doughnut" ? {} : { scales: {
|
|
170
|
+
x: {
|
|
171
|
+
ticks: {
|
|
172
|
+
color: ink,
|
|
173
|
+
maxRotation: 0,
|
|
174
|
+
autoSkip: true
|
|
175
|
+
},
|
|
176
|
+
grid: { display: false }
|
|
177
|
+
},
|
|
178
|
+
y: {
|
|
179
|
+
ticks: { color: ink },
|
|
180
|
+
grid: { color: border },
|
|
181
|
+
beginAtZero: true
|
|
182
|
+
}
|
|
183
|
+
} }
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
this.error.set(false);
|
|
187
|
+
} catch {
|
|
188
|
+
if (!this.destroyed && generation === this.generation) this.error.set(true);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
192
|
+
minVersion: "12.0.0",
|
|
193
|
+
version: "22.2.3",
|
|
194
|
+
ngImport: i0,
|
|
195
|
+
type: HyChart,
|
|
196
|
+
deps: [],
|
|
197
|
+
target: i0.ɵɵFactoryTarget.Component
|
|
198
|
+
});
|
|
199
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({
|
|
200
|
+
minVersion: "17.0.0",
|
|
201
|
+
version: "22.2.3",
|
|
202
|
+
type: HyChart,
|
|
203
|
+
isStandalone: true,
|
|
204
|
+
selector: "hy-chart",
|
|
205
|
+
inputs: {
|
|
206
|
+
data: {
|
|
207
|
+
classPropertyName: "data",
|
|
208
|
+
publicName: "data",
|
|
209
|
+
isSignal: true,
|
|
210
|
+
isRequired: true,
|
|
211
|
+
transformFunction: null
|
|
212
|
+
},
|
|
213
|
+
type: {
|
|
214
|
+
classPropertyName: "type",
|
|
215
|
+
publicName: "type",
|
|
216
|
+
isSignal: true,
|
|
217
|
+
isRequired: false,
|
|
218
|
+
transformFunction: null
|
|
219
|
+
},
|
|
220
|
+
label: {
|
|
221
|
+
classPropertyName: "label",
|
|
222
|
+
publicName: "label",
|
|
223
|
+
isSignal: true,
|
|
224
|
+
isRequired: true,
|
|
225
|
+
transformFunction: null
|
|
226
|
+
},
|
|
227
|
+
summary: {
|
|
228
|
+
classPropertyName: "summary",
|
|
229
|
+
publicName: "summary",
|
|
230
|
+
isSignal: true,
|
|
231
|
+
isRequired: false,
|
|
232
|
+
transformFunction: null
|
|
233
|
+
},
|
|
234
|
+
locale: {
|
|
235
|
+
classPropertyName: "locale",
|
|
236
|
+
publicName: "locale",
|
|
237
|
+
isSignal: true,
|
|
238
|
+
isRequired: false,
|
|
239
|
+
transformFunction: null
|
|
240
|
+
},
|
|
241
|
+
tableLabel: {
|
|
242
|
+
classPropertyName: "tableLabel",
|
|
243
|
+
publicName: "tableLabel",
|
|
244
|
+
isSignal: true,
|
|
245
|
+
isRequired: false,
|
|
246
|
+
transformFunction: null
|
|
247
|
+
}
|
|
248
|
+
},
|
|
249
|
+
viewQueries: [{
|
|
250
|
+
propertyName: "canvas",
|
|
251
|
+
first: true,
|
|
252
|
+
predicate: ["canvas"],
|
|
253
|
+
descendants: true,
|
|
254
|
+
isSignal: true
|
|
255
|
+
}, {
|
|
256
|
+
propertyName: "palette",
|
|
257
|
+
first: true,
|
|
258
|
+
predicate: ["palette"],
|
|
259
|
+
descendants: true,
|
|
260
|
+
isSignal: true
|
|
261
|
+
}],
|
|
262
|
+
ngImport: i0,
|
|
263
|
+
template: "<figure>\r\n <figcaption>\r\n <strong>{{ label() }}</strong>\r\n @if (summary()) {\r\n <p>{{ summary() }}</p>\r\n }\r\n </figcaption>\r\n <div #palette class=\"palette\" aria-hidden=\"true\"><i></i><i></i><i></i><i></i><i></i></div>\r\n <div class=\"plot\" cdkOverlayOrigin #origin=\"cdkOverlayOrigin\">\r\n <canvas #canvas role=\"img\" [attr.aria-label]=\"label()\">{{ summary() }}</canvas>\r\n @if (error()) {\r\n <div class=\"fallback\">\r\n <p>Chart unavailable. The data is available below.</p>\r\n <button type=\"button\" (click)=\"retry()\">Retry chart</button>\r\n </div>\r\n }\r\n </div>\r\n <details>\r\n <summary>{{ tableLabel() }}</summary>\r\n <div class=\"table\" tabindex=\"0\" role=\"region\" [attr.aria-label]=\"label() + ' data'\">\r\n <table>\r\n <caption>\r\n {{\r\n label()\r\n }}\r\n </caption>\r\n <thead>\r\n <tr>\r\n <th scope=\"col\">Label</th>\r\n @for (series of data().series; track $index) {\r\n <th scope=\"col\">{{ series.label }}</th>\r\n }\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @for (row of rows(); track $index) {\r\n <tr>\r\n <th scope=\"row\">{{ row.label }}</th>\r\n @for (value of row.values; track $index) {\r\n <td>{{ value }}</td>\r\n }\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n </div>\r\n </details>\r\n <ng-template\r\n cdkConnectedOverlay\r\n [cdkConnectedOverlayOrigin]=\"origin\"\r\n [cdkConnectedOverlayOpen]=\"!!tooltip()\"\r\n [cdkConnectedOverlayPositions]=\"tooltipPositions\"\r\n [cdkConnectedOverlayOffsetX]=\"tooltip()?.x ?? 0\"\r\n [cdkConnectedOverlayOffsetY]=\"tooltip()?.y ?? 0\"\r\n >\r\n @if (tooltip(); as tip) {\r\n <div\r\n class=\"chart-tooltip hy-glass\"\r\n [attr.data-material]=\"fidelityTier() === 'low' ? 'solid' : 'frosted'\"\r\n role=\"tooltip\"\r\n >\r\n <strong>{{ tip.title }}</strong>\r\n @for (line of tip.lines; track $index) {\r\n <div>{{ line }}</div>\r\n }\r\n </div>\r\n }\r\n </ng-template>\r\n</figure>\r\n",
|
|
264
|
+
styles: [":host{display:block;min-inline-size:0;color:var(--hy-ink)}figure{margin:0;padding:1.25rem;border:1px solid var(--hy-line);border-radius:var(--hy-radius-l);background:var(--hy-surface-1)}figcaption p{margin:.25rem 0 0;font-size:.875rem;color:var(--hy-ink-2)}.plot{position:relative;block-size:var(--hy-chart-height, 17rem);margin-block:1rem}canvas{display:block;max-inline-size:100%}.palette{position:absolute;inline-size:0;block-size:0;overflow:hidden;color:var(--hy-ink-2);border-block-start:1px solid var(--hy-line)}i:nth-child(1){color:var(--hy-primary)}i:nth-child(2){color:var(--hy-success)}i:nth-child(3){color:var(--hy-warning)}i:nth-child(4){color:var(--hy-danger)}i:nth-child(5){color:var(--hy-ink-3)}summary{min-block-size:44px;align-content:center;cursor:pointer;font-size:.8125rem;color:var(--hy-ink-2)}.table{overflow:auto}table{inline-size:100%;border-collapse:collapse;font-size:.8125rem;text-align:start}caption{text-align:start;padding-block:1rem}td,th{padding:.75rem;border-block-end:1px solid var(--hy-line)}.fallback{position:absolute;inset:0;display:grid;place-content:center;text-align:center;background:var(--hy-surface-1);padding:1rem}button{min-block-size:44px;background:var(--hy-surface-2);color:var(--hy-ink);border:1px solid var(--hy-line);border-radius:var(--hy-radius-s);cursor:pointer}summary:focus-visible,button:focus-visible{outline:2px solid var(--hy-primary);outline-offset:3px}.chart-tooltip{pointer-events:none;padding:.75rem 1rem;border-radius:var(--hy-radius-m);color:var(--hy-ink);font-family:var(--hy-font);max-inline-size:22rem}\n"],
|
|
265
|
+
dependencies: [{
|
|
266
|
+
kind: "directive",
|
|
267
|
+
type: CdkConnectedOverlay,
|
|
268
|
+
selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]",
|
|
269
|
+
inputs: [
|
|
270
|
+
"cdkConnectedOverlayOrigin",
|
|
271
|
+
"cdkConnectedOverlayPositions",
|
|
272
|
+
"cdkConnectedOverlayPositionStrategy",
|
|
273
|
+
"cdkConnectedOverlayOffsetX",
|
|
274
|
+
"cdkConnectedOverlayOffsetY",
|
|
275
|
+
"cdkConnectedOverlayWidth",
|
|
276
|
+
"cdkConnectedOverlayHeight",
|
|
277
|
+
"cdkConnectedOverlayMinWidth",
|
|
278
|
+
"cdkConnectedOverlayMinHeight",
|
|
279
|
+
"cdkConnectedOverlayBackdropClass",
|
|
280
|
+
"cdkConnectedOverlayPanelClass",
|
|
281
|
+
"cdkConnectedOverlayViewportMargin",
|
|
282
|
+
"cdkConnectedOverlayScrollStrategy",
|
|
283
|
+
"cdkConnectedOverlayOpen",
|
|
284
|
+
"cdkConnectedOverlayDisableClose",
|
|
285
|
+
"cdkConnectedOverlayTransformOriginOn",
|
|
286
|
+
"cdkConnectedOverlayHasBackdrop",
|
|
287
|
+
"cdkConnectedOverlayLockPosition",
|
|
288
|
+
"cdkConnectedOverlayFlexibleDimensions",
|
|
289
|
+
"cdkConnectedOverlayGrowAfterOpen",
|
|
290
|
+
"cdkConnectedOverlayPush",
|
|
291
|
+
"cdkConnectedOverlayDisposeOnNavigation",
|
|
292
|
+
"cdkConnectedOverlayUsePopover",
|
|
293
|
+
"cdkConnectedOverlayMatchWidth",
|
|
294
|
+
"cdkConnectedOverlay"
|
|
295
|
+
],
|
|
296
|
+
outputs: [
|
|
297
|
+
"backdropClick",
|
|
298
|
+
"positionChange",
|
|
299
|
+
"attach",
|
|
300
|
+
"detach",
|
|
301
|
+
"overlayKeydown",
|
|
302
|
+
"overlayOutsideClick"
|
|
303
|
+
],
|
|
304
|
+
exportAs: ["cdkConnectedOverlay"]
|
|
305
|
+
}, {
|
|
306
|
+
kind: "directive",
|
|
307
|
+
type: CdkOverlayOrigin,
|
|
308
|
+
selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]",
|
|
309
|
+
exportAs: ["cdkOverlayOrigin"]
|
|
310
|
+
}],
|
|
311
|
+
changeDetection: i0.ChangeDetectionStrategy.OnPush
|
|
312
|
+
});
|
|
313
|
+
};
|
|
314
|
+
i0.ɵɵngDeclareClassMetadata({
|
|
315
|
+
minVersion: "12.0.0",
|
|
316
|
+
version: "22.2.3",
|
|
317
|
+
ngImport: i0,
|
|
318
|
+
type: HyChart,
|
|
319
|
+
decorators: [{
|
|
320
|
+
type: Component,
|
|
321
|
+
args: [{
|
|
322
|
+
selector: "hy-chart",
|
|
323
|
+
imports: [CdkConnectedOverlay, CdkOverlayOrigin],
|
|
324
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
325
|
+
template: "<figure>\r\n <figcaption>\r\n <strong>{{ label() }}</strong>\r\n @if (summary()) {\r\n <p>{{ summary() }}</p>\r\n }\r\n </figcaption>\r\n <div #palette class=\"palette\" aria-hidden=\"true\"><i></i><i></i><i></i><i></i><i></i></div>\r\n <div class=\"plot\" cdkOverlayOrigin #origin=\"cdkOverlayOrigin\">\r\n <canvas #canvas role=\"img\" [attr.aria-label]=\"label()\">{{ summary() }}</canvas>\r\n @if (error()) {\r\n <div class=\"fallback\">\r\n <p>Chart unavailable. The data is available below.</p>\r\n <button type=\"button\" (click)=\"retry()\">Retry chart</button>\r\n </div>\r\n }\r\n </div>\r\n <details>\r\n <summary>{{ tableLabel() }}</summary>\r\n <div class=\"table\" tabindex=\"0\" role=\"region\" [attr.aria-label]=\"label() + ' data'\">\r\n <table>\r\n <caption>\r\n {{\r\n label()\r\n }}\r\n </caption>\r\n <thead>\r\n <tr>\r\n <th scope=\"col\">Label</th>\r\n @for (series of data().series; track $index) {\r\n <th scope=\"col\">{{ series.label }}</th>\r\n }\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @for (row of rows(); track $index) {\r\n <tr>\r\n <th scope=\"row\">{{ row.label }}</th>\r\n @for (value of row.values; track $index) {\r\n <td>{{ value }}</td>\r\n }\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n </div>\r\n </details>\r\n <ng-template\r\n cdkConnectedOverlay\r\n [cdkConnectedOverlayOrigin]=\"origin\"\r\n [cdkConnectedOverlayOpen]=\"!!tooltip()\"\r\n [cdkConnectedOverlayPositions]=\"tooltipPositions\"\r\n [cdkConnectedOverlayOffsetX]=\"tooltip()?.x ?? 0\"\r\n [cdkConnectedOverlayOffsetY]=\"tooltip()?.y ?? 0\"\r\n >\r\n @if (tooltip(); as tip) {\r\n <div\r\n class=\"chart-tooltip hy-glass\"\r\n [attr.data-material]=\"fidelityTier() === 'low' ? 'solid' : 'frosted'\"\r\n role=\"tooltip\"\r\n >\r\n <strong>{{ tip.title }}</strong>\r\n @for (line of tip.lines; track $index) {\r\n <div>{{ line }}</div>\r\n }\r\n </div>\r\n }\r\n </ng-template>\r\n</figure>\r\n",
|
|
326
|
+
styles: [":host{display:block;min-inline-size:0;color:var(--hy-ink)}figure{margin:0;padding:1.25rem;border:1px solid var(--hy-line);border-radius:var(--hy-radius-l);background:var(--hy-surface-1)}figcaption p{margin:.25rem 0 0;font-size:.875rem;color:var(--hy-ink-2)}.plot{position:relative;block-size:var(--hy-chart-height, 17rem);margin-block:1rem}canvas{display:block;max-inline-size:100%}.palette{position:absolute;inline-size:0;block-size:0;overflow:hidden;color:var(--hy-ink-2);border-block-start:1px solid var(--hy-line)}i:nth-child(1){color:var(--hy-primary)}i:nth-child(2){color:var(--hy-success)}i:nth-child(3){color:var(--hy-warning)}i:nth-child(4){color:var(--hy-danger)}i:nth-child(5){color:var(--hy-ink-3)}summary{min-block-size:44px;align-content:center;cursor:pointer;font-size:.8125rem;color:var(--hy-ink-2)}.table{overflow:auto}table{inline-size:100%;border-collapse:collapse;font-size:.8125rem;text-align:start}caption{text-align:start;padding-block:1rem}td,th{padding:.75rem;border-block-end:1px solid var(--hy-line)}.fallback{position:absolute;inset:0;display:grid;place-content:center;text-align:center;background:var(--hy-surface-1);padding:1rem}button{min-block-size:44px;background:var(--hy-surface-2);color:var(--hy-ink);border:1px solid var(--hy-line);border-radius:var(--hy-radius-s);cursor:pointer}summary:focus-visible,button:focus-visible{outline:2px solid var(--hy-primary);outline-offset:3px}.chart-tooltip{pointer-events:none;padding:.75rem 1rem;border-radius:var(--hy-radius-m);color:var(--hy-ink);font-family:var(--hy-font);max-inline-size:22rem}\n"]
|
|
327
|
+
}]
|
|
328
|
+
}],
|
|
329
|
+
ctorParameters: () => [],
|
|
330
|
+
propDecorators: {
|
|
331
|
+
data: [{
|
|
332
|
+
type: i0.Input,
|
|
333
|
+
args: [{
|
|
334
|
+
isSignal: true,
|
|
335
|
+
alias: "data",
|
|
336
|
+
required: true
|
|
337
|
+
}]
|
|
338
|
+
}],
|
|
339
|
+
type: [{
|
|
340
|
+
type: i0.Input,
|
|
341
|
+
args: [{
|
|
342
|
+
isSignal: true,
|
|
343
|
+
alias: "type",
|
|
344
|
+
required: false
|
|
345
|
+
}]
|
|
346
|
+
}],
|
|
347
|
+
label: [{
|
|
348
|
+
type: i0.Input,
|
|
349
|
+
args: [{
|
|
350
|
+
isSignal: true,
|
|
351
|
+
alias: "label",
|
|
352
|
+
required: true
|
|
353
|
+
}]
|
|
354
|
+
}],
|
|
355
|
+
summary: [{
|
|
356
|
+
type: i0.Input,
|
|
357
|
+
args: [{
|
|
358
|
+
isSignal: true,
|
|
359
|
+
alias: "summary",
|
|
360
|
+
required: false
|
|
361
|
+
}]
|
|
362
|
+
}],
|
|
363
|
+
locale: [{
|
|
364
|
+
type: i0.Input,
|
|
365
|
+
args: [{
|
|
366
|
+
isSignal: true,
|
|
367
|
+
alias: "locale",
|
|
368
|
+
required: false
|
|
369
|
+
}]
|
|
370
|
+
}],
|
|
371
|
+
tableLabel: [{
|
|
372
|
+
type: i0.Input,
|
|
373
|
+
args: [{
|
|
374
|
+
isSignal: true,
|
|
375
|
+
alias: "tableLabel",
|
|
376
|
+
required: false
|
|
377
|
+
}]
|
|
378
|
+
}],
|
|
379
|
+
canvas: [{
|
|
380
|
+
type: i0.ViewChild,
|
|
381
|
+
args: ["canvas", { isSignal: true }]
|
|
382
|
+
}],
|
|
383
|
+
palette: [{
|
|
384
|
+
type: i0.ViewChild,
|
|
385
|
+
args: ["palette", { isSignal: true }]
|
|
386
|
+
}]
|
|
387
|
+
}
|
|
388
|
+
});
|
|
389
|
+
export { HY_CHART_LOADER, HyChart };
|
|
390
|
+
|
|
391
|
+
//# sourceMappingURL=hyalo-angular-chart.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hyalo-angular-chart.mjs","names":[],"sources":["../../../projects/hyalo/chart/chart.ts","../../../projects/hyalo/chart/chart.html"],"sourcesContent":["import { HyLocale } from '@hyalo/angular/core';\r\nimport {\r\n CdkConnectedOverlay,\r\n CdkOverlayOrigin,\r\n type ConnectedPosition,\r\n} from '@angular/cdk/overlay';\r\nimport { HyFidelity } from '@hyalo/angular/core';\r\nimport { DOCUMENT } from '@angular/common';\r\nimport {\r\n ChangeDetectionStrategy,\r\n Component,\r\n DestroyRef,\r\n ElementRef,\r\n InjectionToken,\r\n afterNextRender,\r\n afterRenderEffect,\r\n computed,\r\n inject,\r\n input,\r\n signal,\r\n untracked,\r\n viewChild,\r\n} from '@angular/core';\r\nimport type { Chart } from 'chart.js';\r\nexport interface HyChartSeries {\r\n readonly label: string;\r\n readonly values: readonly (number | null)[];\r\n}\r\nexport interface HyChartData {\r\n readonly labels: readonly string[];\r\n readonly series: readonly HyChartSeries[];\r\n}\r\nexport type HyChartType = 'line' | 'area' | 'bar' | 'doughnut';\r\nlet engine: Promise<typeof import('./engine')> | undefined;\r\nconst loadEngine = (): Promise<typeof import('./engine')> =>\r\n (engine ??= import('./engine').catch((error: unknown) => {\r\n engine = undefined;\r\n throw error;\r\n }));\r\n/** Override to provide a compatible Chart.js loader, for example from a shared app chunk. */\r\nexport const HY_CHART_LOADER = new InjectionToken<() => Promise<typeof import('./engine')>>(\r\n 'HY_CHART_LOADER',\r\n { providedIn: 'root', factory: () => loadEngine },\r\n);\r\n@Component({\r\n selector: 'hy-chart',\r\n imports: [CdkConnectedOverlay, CdkOverlayOrigin],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './chart.html',\r\n styleUrl: './chart.css',\r\n})\r\nexport class HyChart {\r\n readonly data = input.required<HyChartData>();\r\n readonly type = input<HyChartType>('line');\r\n readonly label = input.required<string>();\r\n readonly summary = input('');\r\n readonly locale = input<string>();\r\n private readonly globalLocale = inject(HyLocale);\r\n private readonly effectiveLocale = computed(() => this.locale() ?? this.globalLocale.locale());\r\n readonly tableLabel = input('View chart data');\r\n protected readonly error = signal(false);\r\n protected readonly tooltip = signal<{\r\n x: number;\r\n y: number;\r\n title: string;\r\n lines: readonly string[];\r\n } | null>(null);\r\n protected readonly tooltipPositions: ConnectedPosition[] = [\r\n { originX: 'start', originY: 'top', overlayX: 'start', overlayY: 'bottom' },\r\n ];\r\n private readonly fidelity = inject(HyFidelity);\r\n protected readonly fidelityTier = this.fidelity.tier;\r\n private readonly visible = signal(false);\r\n private readonly theme = signal(0);\r\n private readonly canvas = viewChild<ElementRef<HTMLCanvasElement>>('canvas');\r\n private readonly palette = viewChild<ElementRef<HTMLElement>>('palette');\r\n private readonly document = inject(DOCUMENT);\r\n private readonly load = inject(HY_CHART_LOADER);\r\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\r\n private chart: Chart | undefined;\r\n private generation = 0;\r\n private destroyed = false;\r\n private readonly formatter = computed(() => new Intl.NumberFormat(this.effectiveLocale()));\r\n readonly rows = computed(() =>\r\n this.data().labels.map((label, index) => ({\r\n label,\r\n values: this.data().series.map((series) => {\r\n const value = series.values[index];\r\n return value == null || !Number.isFinite(value) ? '–' : this.formatter().format(value);\r\n }),\r\n })),\r\n );\r\n constructor() {\r\n let observer: IntersectionObserver | undefined, mutation: MutationObserver | undefined;\r\n let media: MediaQueryList | undefined;\r\n const changed = (): void => this.theme.update((value) => value + 1);\r\n afterNextRender(() => {\r\n if (typeof IntersectionObserver === 'undefined') this.visible.set(true);\r\n else {\r\n observer = new IntersectionObserver(\r\n (entries) => this.visible.set(entries.some((entry) => entry.isIntersecting)),\r\n { rootMargin: '150px' },\r\n );\r\n observer.observe(this.host.nativeElement);\r\n }\r\n mutation = new MutationObserver(changed);\r\n for (\r\n let element: HTMLElement | null = this.host.nativeElement;\r\n element;\r\n element = element.parentElement\r\n ) {\r\n mutation.observe(element, {\r\n attributes: true,\r\n attributeFilter: [\r\n 'class',\r\n 'style',\r\n 'dir',\r\n 'lang',\r\n 'data-hy-theme',\r\n 'data-hy-palette',\r\n 'data-hy-fidelity',\r\n ],\r\n });\r\n }\r\n media = this.document.defaultView?.matchMedia('(prefers-color-scheme: dark)');\r\n media?.addEventListener('change', changed);\r\n });\r\n afterRenderEffect(() => {\r\n const data = this.data(),\r\n type = this.type(),\r\n locale = this.effectiveLocale();\r\n this.theme();\r\n this.fidelity.tier();\r\n if (!this.visible()) return;\r\n untracked(() => void this.render(data, type, locale));\r\n });\r\n inject(DestroyRef).onDestroy(() => {\r\n this.destroyed = true;\r\n this.generation++;\r\n observer?.disconnect();\r\n mutation?.disconnect();\r\n media?.removeEventListener('change', changed);\r\n this.tooltip.set(null);\r\n this.chart?.destroy();\r\n });\r\n }\r\n protected retry(): void {\r\n this.theme.update((value) => value + 1);\r\n }\r\n private async render(data: HyChartData, type: HyChartType, locale: string): Promise<void> {\r\n const generation = ++this.generation;\r\n try {\r\n const kit = await this.load();\r\n if (this.destroyed || generation !== this.generation) return;\r\n const canvas = this.canvas()?.nativeElement,\r\n palette = this.palette()?.nativeElement,\r\n view = this.document.defaultView;\r\n if (!canvas || !palette || !view) return;\r\n const colors = [...palette.children].map((element) => view.getComputedStyle(element).color);\r\n const ink = view.getComputedStyle(palette).color,\r\n border = view.getComputedStyle(palette).borderBlockStartColor;\r\n const rtl = view.getComputedStyle(this.host.nativeElement).direction === 'rtl';\r\n const datasets = data.series.map((series, index) => ({\r\n label: series.label,\r\n data: data.labels.map((_, i) => {\r\n const value = series.values[i];\r\n return value != null && Number.isFinite(value) ? value : null;\r\n }),\r\n borderColor: colors[index % colors.length],\r\n backgroundColor:\r\n type === 'doughnut'\r\n ? data.labels.map((_, i) => colors[i % colors.length])\r\n : type === 'area'\r\n ? (context: { chart: Chart }) => {\r\n const area = context.chart.chartArea;\r\n if (!area) return colors[index % colors.length];\r\n const gradient = context.chart.ctx.createLinearGradient(\r\n 0,\r\n area.top,\r\n 0,\r\n area.bottom,\r\n );\r\n const color = colors[index % colors.length] ?? 'transparent';\r\n gradient.addColorStop(0, color);\r\n gradient.addColorStop(1, 'transparent');\r\n return gradient;\r\n }\r\n : colors[index % colors.length],\r\n borderWidth: 2,\r\n pointRadius: 2,\r\n tension: 0.25,\r\n fill: type === 'area',\r\n }));\r\n this.tooltip.set(null);\r\n this.chart?.destroy();\r\n this.chart = undefined;\r\n this.chart = new kit.Chart(canvas, {\r\n type: type === 'area' ? 'line' : type,\r\n data: { labels: [...data.labels], datasets },\r\n options: {\r\n responsive: true,\r\n maintainAspectRatio: false,\r\n animation: false,\r\n locale,\r\n plugins: {\r\n legend: {\r\n display: data.series.length > 1 || type === 'doughnut',\r\n rtl,\r\n textDirection: rtl ? 'rtl' : 'ltr',\r\n labels: { color: ink, usePointStyle: true },\r\n },\r\n tooltip: {\r\n enabled: false,\r\n external: ({ tooltip }) => {\r\n if (!tooltip.opacity) {\r\n this.tooltip.set(null);\r\n return;\r\n }\r\n this.tooltip.set({\r\n x: tooltip.caretX,\r\n y: tooltip.caretY - 8,\r\n title: tooltip.title?.join(' ') ?? '',\r\n lines: tooltip.dataPoints.map(\r\n (point) => `${point.dataset.label ?? ''}: ${point.formattedValue}`,\r\n ),\r\n });\r\n },\r\n },\r\n },\r\n ...(type === 'doughnut'\r\n ? {}\r\n : {\r\n scales: {\r\n x: {\r\n ticks: { color: ink, maxRotation: 0, autoSkip: true },\r\n grid: { display: false },\r\n },\r\n y: { ticks: { color: ink }, grid: { color: border }, beginAtZero: true },\r\n },\r\n }),\r\n },\r\n });\r\n this.error.set(false);\r\n } catch {\r\n if (!this.destroyed && generation === this.generation) this.error.set(true);\r\n }\r\n }\r\n}\r\n","<figure>\r\n <figcaption>\r\n <strong>{{ label() }}</strong>\r\n @if (summary()) {\r\n <p>{{ summary() }}</p>\r\n }\r\n </figcaption>\r\n <div #palette class=\"palette\" aria-hidden=\"true\"><i></i><i></i><i></i><i></i><i></i></div>\r\n <div class=\"plot\" cdkOverlayOrigin #origin=\"cdkOverlayOrigin\">\r\n <canvas #canvas role=\"img\" [attr.aria-label]=\"label()\">{{ summary() }}</canvas>\r\n @if (error()) {\r\n <div class=\"fallback\">\r\n <p>Chart unavailable. The data is available below.</p>\r\n <button type=\"button\" (click)=\"retry()\">Retry chart</button>\r\n </div>\r\n }\r\n </div>\r\n <details>\r\n <summary>{{ tableLabel() }}</summary>\r\n <div class=\"table\" tabindex=\"0\" role=\"region\" [attr.aria-label]=\"label() + ' data'\">\r\n <table>\r\n <caption>\r\n {{\r\n label()\r\n }}\r\n </caption>\r\n <thead>\r\n <tr>\r\n <th scope=\"col\">Label</th>\r\n @for (series of data().series; track $index) {\r\n <th scope=\"col\">{{ series.label }}</th>\r\n }\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @for (row of rows(); track $index) {\r\n <tr>\r\n <th scope=\"row\">{{ row.label }}</th>\r\n @for (value of row.values; track $index) {\r\n <td>{{ value }}</td>\r\n }\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n </div>\r\n </details>\r\n <ng-template\r\n cdkConnectedOverlay\r\n [cdkConnectedOverlayOrigin]=\"origin\"\r\n [cdkConnectedOverlayOpen]=\"!!tooltip()\"\r\n [cdkConnectedOverlayPositions]=\"tooltipPositions\"\r\n [cdkConnectedOverlayOffsetX]=\"tooltip()?.x ?? 0\"\r\n [cdkConnectedOverlayOffsetY]=\"tooltip()?.y ?? 0\"\r\n >\r\n @if (tooltip(); as tip) {\r\n <div\r\n class=\"chart-tooltip hy-glass\"\r\n [attr.data-material]=\"fidelityTier() === 'low' ? 'solid' : 'frosted'\"\r\n role=\"tooltip\"\r\n >\r\n <strong>{{ tip.title }}</strong>\r\n @for (line of tip.lines; track $index) {\r\n <div>{{ line }}</div>\r\n }\r\n </div>\r\n }\r\n </ng-template>\r\n</figure>\r\n"],"mappings":"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"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import * as i0 from "@angular/core";
|
|
2
2
|
import { ChangeDetectionStrategy, Component, booleanAttribute, computed, inject, input, model, output, signal } from "@angular/core";
|
|
3
|
-
import { injectId
|
|
3
|
+
import { injectId } from "@hyalo/angular/core";
|
|
4
4
|
import { HyIcon } from "@hyalo/angular/icon";
|
|
5
|
+
import { rubberband } from "@hyalo/angular/motion";
|
|
5
6
|
var HyCheckbox = class HyCheckbox {
|
|
6
7
|
descriptionId = injectId("checkbox-desc");
|
|
7
8
|
checked = model(false, ...ngDevMode ? [{ debugName: "checked" }] : /* istanbul ignore next */ []);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hyalo-angular-choice.mjs","names":[],"sources":["../../../projects/hyalo/choice/checkbox.ts","../../../projects/hyalo/choice/checkbox.html","../../../projects/hyalo/choice/radio.ts","../../../projects/hyalo/choice/radio-group.html","../../../projects/hyalo/choice/radio.html","../../../projects/hyalo/choice/switch.ts","../../../projects/hyalo/choice/switch.html"],"sourcesContent":["import {\r\n ChangeDetectionStrategy,\r\n Component,\r\n booleanAttribute,\r\n input,\r\n model,\r\n output,\r\n} from '@angular/core';\r\nimport type { FormCheckboxControl } from '@angular/forms/signals';\r\nimport { injectId } from '@hyalo/angular';\r\n\r\nimport { HyIcon } from '@hyalo/angular/icon';\r\n\r\n/**\r\n * A checkbox with a label. It wraps a real `<input type=\"checkbox\">`, so\r\n * Space toggles it, clicking the label works and forms see it.\r\n *\r\n * ```html\r\n * <hy-checkbox [formField]=\"form.terms\">I accept the terms</hy-checkbox>\r\n * <hy-checkbox [(checked)]=\"all\" [indeterminate]=\"some\">Select all</hy-checkbox>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'hy-checkbox',\r\n imports: [HyIcon],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n host: {\r\n class: 'hy-choice hy-checkbox',\r\n '[attr.data-checked]': 'checked() || null',\r\n '[attr.data-indeterminate]': 'indeterminate() || null',\r\n '[attr.data-disabled]': 'disabled() || null',\r\n '[attr.data-invalid]': '(invalid() && touched()) || null',\r\n },\r\n templateUrl: './checkbox.html',\r\n styleUrl: './choice.css',\r\n})\r\nexport class HyCheckbox implements FormCheckboxControl {\r\n protected readonly descriptionId = injectId('checkbox-desc');\r\n\r\n /** Whether the box is checked. Two-way bindable and works with `[formField]`. */\r\n readonly checked = model(false);\r\n /** Shows a dash for a partly selected group. Cleared when the user toggles. */\r\n readonly indeterminate = model(false);\r\n /** Secondary text under the label. */\r\n readonly description = input<string>();\r\n readonly name = input('');\r\n readonly disabled = input(false, { transform: booleanAttribute });\r\n readonly required = input(false, { transform: booleanAttribute });\r\n readonly invalid = input(false, { transform: booleanAttribute });\r\n readonly touched = input(false, { transform: booleanAttribute });\r\n /** Emits when focus leaves the checkbox. */\r\n readonly touch = output<void>();\r\n\r\n protected onChange(event: Event): void {\r\n this.indeterminate.set(false);\r\n this.checked.set((event.target as HTMLInputElement).checked);\r\n }\r\n}\r\n","<label class=\"hy-choice__row\">\r\n <span class=\"hy-choice__control hy-checkbox__box\">\r\n <input\r\n type=\"checkbox\"\r\n class=\"hy-choice__input\"\r\n [name]=\"name()\"\r\n [checked]=\"checked()\"\r\n [indeterminate]=\"indeterminate()\"\r\n [disabled]=\"disabled()\"\r\n [required]=\"required()\"\r\n [attr.aria-invalid]=\"(invalid() && touched()) || null\"\r\n [attr.aria-describedby]=\"description() ? descriptionId : null\"\r\n (change)=\"onChange($event)\"\r\n (blur)=\"touch.emit()\"\r\n />\r\n <hy-icon\r\n class=\"hy-checkbox__mark\"\r\n [name]=\"indeterminate() ? 'minus' : 'check'\"\r\n [strokeWidth]=\"2.5\"\r\n />\r\n </span>\r\n <span class=\"hy-choice__label\"><ng-content /></span>\r\n</label>\r\n@if (description()) {\r\n <p class=\"hy-choice__description\" [id]=\"descriptionId\">{{ description() }}</p>\r\n}\r\n","import {\r\n ChangeDetectionStrategy,\r\n Component,\r\n booleanAttribute,\r\n computed,\r\n inject,\r\n input,\r\n model,\r\n output,\r\n} from '@angular/core';\r\nimport type { FormValueControl } from '@angular/forms/signals';\r\nimport { injectId } from '@hyalo/angular';\r\n\r\n/**\r\n * A group of radio buttons. Holds the value; the radios inside only say\r\n * which value they stand for.\r\n *\r\n * ```html\r\n * <hy-radio-group label=\"Delivery\" [formField]=\"form.delivery\">\r\n * <hy-radio value=\"standard\" description=\"3 to 5 days\">Standard</hy-radio>\r\n * <hy-radio value=\"express\">Express</hy-radio>\r\n * </hy-radio-group>\r\n * ```\r\n *\r\n * The radios are native inputs sharing one name, so arrow keys move the\r\n * selection the way the platform does, including in RTL.\r\n */\r\n@Component({\r\n selector: 'hy-radio-group',\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n host: {\r\n class: 'hy-radio-group',\r\n role: 'radiogroup',\r\n '[attr.aria-labelledby]': 'label() ? labelId : null',\r\n '[attr.aria-invalid]': 'showsError() || null',\r\n '[attr.aria-required]': 'required() || null',\r\n '[attr.data-orientation]': 'orientation()',\r\n },\r\n templateUrl: './radio-group.html',\r\n styleUrl: './choice.css',\r\n})\r\nexport class HyRadioGroup<T> implements FormValueControl<T | undefined> {\r\n protected readonly labelId = injectId('radio-label');\r\n private readonly generatedName = injectId('radio');\r\n\r\n /** Selected value. Two-way bindable and works with `[formField]`. */\r\n readonly value = model<T | undefined>(undefined);\r\n /** Visible group label. */\r\n readonly label = input<string>();\r\n /** Shared input name. Generated when not set. */\r\n readonly name = input('');\r\n readonly orientation = input<'vertical' | 'horizontal'>('vertical');\r\n readonly disabled = input(false, { transform: booleanAttribute });\r\n readonly required = input(false, { transform: booleanAttribute });\r\n readonly invalid = input(false, { transform: booleanAttribute });\r\n readonly touched = input(false, { transform: booleanAttribute });\r\n readonly errors = input<readonly { readonly kind: string; readonly message?: string }[]>([]);\r\n /** Emits when focus leaves a radio. */\r\n readonly touch = output<void>();\r\n\r\n readonly groupName = computed(() => this.name() || this.generatedName);\r\n protected readonly showsError = computed(() => this.invalid() && this.touched());\r\n protected readonly errorMessage = computed(() => {\r\n const first = this.errors()[0];\r\n return first ? (first.message ?? first.kind) : '';\r\n });\r\n}\r\n\r\n/** One option inside a `hy-radio-group`. */\r\n@Component({\r\n selector: 'hy-radio',\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n host: {\r\n class: 'hy-choice hy-radio',\r\n '[attr.data-checked]': 'checked() || null',\r\n '[attr.data-disabled]': 'isDisabled() || null',\r\n },\r\n templateUrl: './radio.html',\r\n styleUrl: './choice.css',\r\n})\r\nexport class HyRadio<T> {\r\n protected readonly group = inject<HyRadioGroup<T>>(HyRadioGroup);\r\n protected readonly descriptionId = injectId('radio-desc');\r\n\r\n /** The value this radio selects. */\r\n readonly value = input.required<T>();\r\n /** Secondary text under the label. */\r\n readonly description = input<string>();\r\n readonly disabled = input(false, { transform: booleanAttribute });\r\n\r\n protected readonly checked = computed(() => this.group.value() === this.value());\r\n protected readonly isDisabled = computed(() => this.disabled() || this.group.disabled());\r\n}\r\n","@if (label()) {\r\n <span class=\"hy-radio-group__label\" [id]=\"labelId\">{{ label() }}</span>\r\n}\r\n<div class=\"hy-radio-group__items\"><ng-content /></div>\r\n@if (showsError()) {\r\n <p class=\"hy-choice__error\">{{ errorMessage() }}</p>\r\n}\r\n","<label class=\"hy-choice__row\">\r\n <span class=\"hy-choice__control hy-radio__circle\">\r\n <input\r\n type=\"radio\"\r\n class=\"hy-choice__input\"\r\n [name]=\"group.groupName()\"\r\n [checked]=\"checked()\"\r\n [disabled]=\"isDisabled()\"\r\n [attr.aria-describedby]=\"description() ? descriptionId : null\"\r\n (change)=\"group.value.set(value())\"\r\n (blur)=\"group.touch.emit()\"\r\n />\r\n <span class=\"hy-radio__dot\" aria-hidden=\"true\"></span>\r\n </span>\r\n <span class=\"hy-choice__label\"><ng-content /></span>\r\n</label>\r\n@if (description()) {\r\n <p class=\"hy-choice__description\" [id]=\"descriptionId\">{{ description() }}</p>\r\n}\r\n","import {\r\n ChangeDetectionStrategy,\r\n Component,\r\n booleanAttribute,\r\n input,\r\n model,\r\n output,\r\n signal,\r\n} from '@angular/core';\r\nimport type { FormCheckboxControl } from '@angular/forms/signals';\r\nimport { injectId, rubberband } from '@hyalo/angular';\r\n\r\n/** Movement before a press on the track turns into a drag, in px. */\r\nconst SLOP = 4;\r\n/** Track padding on each side, in px. Matches choice.css. */\r\nconst TRACK_PADDING = 2;\r\n/** Width of the pressed thumb, in rem. Matches choice.css. */\r\nconst PRESSED_THUMB = 1.5;\r\n\r\n/**\r\n * An on/off switch for settings that apply right away. For choices that\r\n * are submitted with a form, a checkbox is usually clearer.\r\n *\r\n * It is a native checkbox with `role=\"switch\"`, so screen readers say\r\n * \"on\" and \"off\" and Space toggles it. The thumb can also be dragged: it\r\n * follows the pointer, and lands on whichever side it is let go nearer.\r\n *\r\n * ```html\r\n * <hy-switch [(checked)]=\"notifications\">Email notifications</hy-switch>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'hy-switch',\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n host: {\r\n class: 'hy-choice hy-switch',\r\n '[attr.data-checked]': 'checked() || null',\r\n '[attr.data-disabled]': 'disabled() || null',\r\n },\r\n templateUrl: './switch.html',\r\n styleUrl: './choice.css',\r\n})\r\nexport class HySwitch implements FormCheckboxControl {\r\n protected readonly descriptionId = injectId('switch-desc');\r\n /** Physical thumb offset in px while it is dragged, otherwise null. */\r\n protected readonly drag = signal<number | null>(null);\r\n private press: { x: number; from: number; travel: number; dir: number; pos: number } | null =\r\n null;\r\n /** Where a finished drag landed, until the click it causes is handled. */\r\n private landed: boolean | null = null;\r\n\r\n /** Whether the switch is on. Two-way bindable and works with `[formField]`. */\r\n readonly checked = model(false);\r\n /** Secondary text under the label. */\r\n readonly description = input<string>();\r\n readonly name = input('');\r\n readonly disabled = input(false, { transform: booleanAttribute });\r\n readonly required = input(false, { transform: booleanAttribute });\r\n /** Emits when focus leaves the switch. */\r\n readonly touch = output<void>();\r\n\r\n protected onChange(event: Event): void {\r\n this.checked.set((event.target as HTMLInputElement).checked);\r\n }\r\n\r\n protected onDown(event: PointerEvent): void {\r\n if (this.disabled() || event.button !== 0) return;\r\n const track = event.currentTarget as HTMLElement;\r\n const rem = parseFloat(getComputedStyle(track.ownerDocument.documentElement).fontSize) || 16;\r\n const travel = track.clientWidth - 2 * TRACK_PADDING - PRESSED_THUMB * rem;\r\n this.press = {\r\n x: event.clientX,\r\n from: this.checked() ? travel : 0,\r\n travel,\r\n dir: getComputedStyle(track).direction === 'rtl' ? -1 : 1,\r\n pos: this.checked() ? travel : 0,\r\n };\r\n }\r\n\r\n protected onMove(event: PointerEvent): void {\r\n const press = this.press;\r\n if (!press) return;\r\n const moved = (event.clientX - press.x) * press.dir;\r\n if (this.drag() === null) {\r\n if (Math.abs(moved) < SLOP) return;\r\n try {\r\n (event.currentTarget as HTMLElement).setPointerCapture(event.pointerId);\r\n } catch {\r\n // The pointer is already gone; the drag still ends on pointerup.\r\n }\r\n }\r\n // Past either end the thumb resists instead of stopping dead.\r\n const raw = press.from + moved;\r\n const over = raw < 0 ? raw : raw > press.travel ? raw - press.travel : 0;\r\n press.pos = Math.min(Math.max(raw, 0), press.travel) + rubberband(over, press.travel);\r\n this.drag.set(press.pos * press.dir);\r\n }\r\n\r\n protected onUp(cancelled = false): void {\r\n const press = this.press;\r\n this.press = null;\r\n if (!press || this.drag() === null) return;\r\n this.drag.set(null);\r\n // Decided in logical position, so it is the same in both directions.\r\n const on = press.pos > press.travel / 2;\r\n if (cancelled) {\r\n this.checked.set(on);\r\n return;\r\n }\r\n // The release also clicks the label. That click applies the drag\r\n // instead of toggling; if no click comes, apply it anyway.\r\n this.landed = on;\r\n setTimeout(() => {\r\n if (this.landed === null) return;\r\n this.checked.set(this.landed);\r\n this.landed = null;\r\n });\r\n }\r\n\r\n protected onClick(event: MouseEvent): void {\r\n if (this.landed === null) return;\r\n event.preventDefault();\r\n this.checked.set(this.landed);\r\n this.landed = null;\r\n }\r\n}\r\n","<label class=\"hy-choice__row\">\r\n <span\r\n class=\"hy-choice__control hy-switch__track\"\r\n (pointerdown)=\"onDown($event)\"\r\n (pointermove)=\"onMove($event)\"\r\n (pointerup)=\"onUp()\"\r\n (pointercancel)=\"onUp(true)\"\r\n >\r\n <input\r\n type=\"checkbox\"\r\n role=\"switch\"\r\n class=\"hy-choice__input\"\r\n [name]=\"name()\"\r\n [checked]=\"checked()\"\r\n [disabled]=\"disabled()\"\r\n [required]=\"required()\"\r\n [attr.aria-checked]=\"checked()\"\r\n [attr.aria-describedby]=\"description() ? descriptionId : null\"\r\n (click)=\"onClick($event)\"\r\n (change)=\"onChange($event)\"\r\n (blur)=\"touch.emit()\"\r\n />\r\n <span\r\n class=\"hy-switch__thumb\"\r\n aria-hidden=\"true\"\r\n [attr.data-dragging]=\"drag() === null ? null : ''\"\r\n [style.--_drag.px]=\"drag()\"\r\n ></span>\r\n </span>\r\n <span class=\"hy-choice__label\"><ng-content /></span>\r\n</label>\r\n@if (description()) {\r\n <p class=\"hy-choice__description\" [id]=\"descriptionId\">{{ description() }}</p>\r\n}\r\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"hyalo-angular-choice.mjs","names":[],"sources":["../../../projects/hyalo/choice/checkbox.ts","../../../projects/hyalo/choice/checkbox.html","../../../projects/hyalo/choice/radio.ts","../../../projects/hyalo/choice/radio-group.html","../../../projects/hyalo/choice/radio.html","../../../projects/hyalo/choice/switch.ts","../../../projects/hyalo/choice/switch.html"],"sourcesContent":["import {\r\n ChangeDetectionStrategy,\r\n Component,\r\n booleanAttribute,\r\n input,\r\n model,\r\n output,\r\n} from '@angular/core';\r\nimport type { FormCheckboxControl } from '@angular/forms/signals';\r\nimport { injectId } from '@hyalo/angular/core';\r\n\r\nimport { HyIcon } from '@hyalo/angular/icon';\r\n\r\n/**\r\n * A checkbox with a label. It wraps a real `<input type=\"checkbox\">`, so\r\n * Space toggles it, clicking the label works and forms see it.\r\n *\r\n * ```html\r\n * <hy-checkbox [formField]=\"form.terms\">I accept the terms</hy-checkbox>\r\n * <hy-checkbox [(checked)]=\"all\" [indeterminate]=\"some\">Select all</hy-checkbox>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'hy-checkbox',\r\n imports: [HyIcon],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n host: {\r\n class: 'hy-choice hy-checkbox',\r\n '[attr.data-checked]': 'checked() || null',\r\n '[attr.data-indeterminate]': 'indeterminate() || null',\r\n '[attr.data-disabled]': 'disabled() || null',\r\n '[attr.data-invalid]': '(invalid() && touched()) || null',\r\n },\r\n templateUrl: './checkbox.html',\r\n styleUrl: './choice.css',\r\n})\r\nexport class HyCheckbox implements FormCheckboxControl {\r\n protected readonly descriptionId = injectId('checkbox-desc');\r\n\r\n /** Whether the box is checked. Two-way bindable and works with `[formField]`. */\r\n readonly checked = model(false);\r\n /** Shows a dash for a partly selected group. Cleared when the user toggles. */\r\n readonly indeterminate = model(false);\r\n /** Secondary text under the label. */\r\n readonly description = input<string>();\r\n readonly name = input('');\r\n readonly disabled = input(false, { transform: booleanAttribute });\r\n readonly required = input(false, { transform: booleanAttribute });\r\n readonly invalid = input(false, { transform: booleanAttribute });\r\n readonly touched = input(false, { transform: booleanAttribute });\r\n /** Emits when focus leaves the checkbox. */\r\n readonly touch = output<void>();\r\n\r\n protected onChange(event: Event): void {\r\n this.indeterminate.set(false);\r\n this.checked.set((event.target as HTMLInputElement).checked);\r\n }\r\n}\r\n","<label class=\"hy-choice__row\">\r\n <span class=\"hy-choice__control hy-checkbox__box\">\r\n <input\r\n type=\"checkbox\"\r\n class=\"hy-choice__input\"\r\n [name]=\"name()\"\r\n [checked]=\"checked()\"\r\n [indeterminate]=\"indeterminate()\"\r\n [disabled]=\"disabled()\"\r\n [required]=\"required()\"\r\n [attr.aria-invalid]=\"(invalid() && touched()) || null\"\r\n [attr.aria-describedby]=\"description() ? descriptionId : null\"\r\n (change)=\"onChange($event)\"\r\n (blur)=\"touch.emit()\"\r\n />\r\n <hy-icon\r\n class=\"hy-checkbox__mark\"\r\n [name]=\"indeterminate() ? 'minus' : 'check'\"\r\n [strokeWidth]=\"2.5\"\r\n />\r\n </span>\r\n <span class=\"hy-choice__label\"><ng-content /></span>\r\n</label>\r\n@if (description()) {\r\n <p class=\"hy-choice__description\" [id]=\"descriptionId\">{{ description() }}</p>\r\n}\r\n","import {\r\n ChangeDetectionStrategy,\r\n Component,\r\n booleanAttribute,\r\n computed,\r\n inject,\r\n input,\r\n model,\r\n output,\r\n} from '@angular/core';\r\nimport type { FormValueControl } from '@angular/forms/signals';\r\nimport { injectId } from '@hyalo/angular/core';\r\n\r\n/**\r\n * A group of radio buttons. Holds the value; the radios inside only say\r\n * which value they stand for.\r\n *\r\n * ```html\r\n * <hy-radio-group label=\"Delivery\" [formField]=\"form.delivery\">\r\n * <hy-radio value=\"standard\" description=\"3 to 5 days\">Standard</hy-radio>\r\n * <hy-radio value=\"express\">Express</hy-radio>\r\n * </hy-radio-group>\r\n * ```\r\n *\r\n * The radios are native inputs sharing one name, so arrow keys move the\r\n * selection the way the platform does, including in RTL.\r\n */\r\n@Component({\r\n selector: 'hy-radio-group',\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n host: {\r\n class: 'hy-radio-group',\r\n role: 'radiogroup',\r\n '[attr.aria-labelledby]': 'label() ? labelId : null',\r\n '[attr.aria-invalid]': 'showsError() || null',\r\n '[attr.aria-required]': 'required() || null',\r\n '[attr.data-orientation]': 'orientation()',\r\n },\r\n templateUrl: './radio-group.html',\r\n styleUrl: './choice.css',\r\n})\r\nexport class HyRadioGroup<T> implements FormValueControl<T | undefined> {\r\n protected readonly labelId = injectId('radio-label');\r\n private readonly generatedName = injectId('radio');\r\n\r\n /** Selected value. Two-way bindable and works with `[formField]`. */\r\n readonly value = model<T | undefined>(undefined);\r\n /** Visible group label. */\r\n readonly label = input<string>();\r\n /** Shared input name. Generated when not set. */\r\n readonly name = input('');\r\n readonly orientation = input<'vertical' | 'horizontal'>('vertical');\r\n readonly disabled = input(false, { transform: booleanAttribute });\r\n readonly required = input(false, { transform: booleanAttribute });\r\n readonly invalid = input(false, { transform: booleanAttribute });\r\n readonly touched = input(false, { transform: booleanAttribute });\r\n readonly errors = input<readonly { readonly kind: string; readonly message?: string }[]>([]);\r\n /** Emits when focus leaves a radio. */\r\n readonly touch = output<void>();\r\n\r\n readonly groupName = computed(() => this.name() || this.generatedName);\r\n protected readonly showsError = computed(() => this.invalid() && this.touched());\r\n protected readonly errorMessage = computed(() => {\r\n const first = this.errors()[0];\r\n return first ? (first.message ?? first.kind) : '';\r\n });\r\n}\r\n\r\n/** One option inside a `hy-radio-group`. */\r\n@Component({\r\n selector: 'hy-radio',\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n host: {\r\n class: 'hy-choice hy-radio',\r\n '[attr.data-checked]': 'checked() || null',\r\n '[attr.data-disabled]': 'isDisabled() || null',\r\n },\r\n templateUrl: './radio.html',\r\n styleUrl: './choice.css',\r\n})\r\nexport class HyRadio<T> {\r\n protected readonly group = inject<HyRadioGroup<T>>(HyRadioGroup);\r\n protected readonly descriptionId = injectId('radio-desc');\r\n\r\n /** The value this radio selects. */\r\n readonly value = input.required<T>();\r\n /** Secondary text under the label. */\r\n readonly description = input<string>();\r\n readonly disabled = input(false, { transform: booleanAttribute });\r\n\r\n protected readonly checked = computed(() => this.group.value() === this.value());\r\n protected readonly isDisabled = computed(() => this.disabled() || this.group.disabled());\r\n}\r\n","@if (label()) {\r\n <span class=\"hy-radio-group__label\" [id]=\"labelId\">{{ label() }}</span>\r\n}\r\n<div class=\"hy-radio-group__items\"><ng-content /></div>\r\n@if (showsError()) {\r\n <p class=\"hy-choice__error\">{{ errorMessage() }}</p>\r\n}\r\n","<label class=\"hy-choice__row\">\r\n <span class=\"hy-choice__control hy-radio__circle\">\r\n <input\r\n type=\"radio\"\r\n class=\"hy-choice__input\"\r\n [name]=\"group.groupName()\"\r\n [checked]=\"checked()\"\r\n [disabled]=\"isDisabled()\"\r\n [attr.aria-describedby]=\"description() ? descriptionId : null\"\r\n (change)=\"group.value.set(value())\"\r\n (blur)=\"group.touch.emit()\"\r\n />\r\n <span class=\"hy-radio__dot\" aria-hidden=\"true\"></span>\r\n </span>\r\n <span class=\"hy-choice__label\"><ng-content /></span>\r\n</label>\r\n@if (description()) {\r\n <p class=\"hy-choice__description\" [id]=\"descriptionId\">{{ description() }}</p>\r\n}\r\n","import {\r\n ChangeDetectionStrategy,\r\n Component,\r\n booleanAttribute,\r\n input,\r\n model,\r\n output,\r\n signal,\r\n} from '@angular/core';\r\nimport type { FormCheckboxControl } from '@angular/forms/signals';\r\nimport { injectId } from '@hyalo/angular/core';\r\nimport { rubberband } from '@hyalo/angular/motion';\r\n\r\n/** Movement before a press on the track turns into a drag, in px. */\r\nconst SLOP = 4;\r\n/** Track padding on each side, in px. Matches choice.css. */\r\nconst TRACK_PADDING = 2;\r\n/** Width of the pressed thumb, in rem. Matches choice.css. */\r\nconst PRESSED_THUMB = 1.5;\r\n\r\n/**\r\n * An on/off switch for settings that apply right away. For choices that\r\n * are submitted with a form, a checkbox is usually clearer.\r\n *\r\n * It is a native checkbox with `role=\"switch\"`, so screen readers say\r\n * \"on\" and \"off\" and Space toggles it. The thumb can also be dragged: it\r\n * follows the pointer, and lands on whichever side it is let go nearer.\r\n *\r\n * ```html\r\n * <hy-switch [(checked)]=\"notifications\">Email notifications</hy-switch>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'hy-switch',\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n host: {\r\n class: 'hy-choice hy-switch',\r\n '[attr.data-checked]': 'checked() || null',\r\n '[attr.data-disabled]': 'disabled() || null',\r\n },\r\n templateUrl: './switch.html',\r\n styleUrl: './choice.css',\r\n})\r\nexport class HySwitch implements FormCheckboxControl {\r\n protected readonly descriptionId = injectId('switch-desc');\r\n /** Physical thumb offset in px while it is dragged, otherwise null. */\r\n protected readonly drag = signal<number | null>(null);\r\n private press: { x: number; from: number; travel: number; dir: number; pos: number } | null =\r\n null;\r\n /** Where a finished drag landed, until the click it causes is handled. */\r\n private landed: boolean | null = null;\r\n\r\n /** Whether the switch is on. Two-way bindable and works with `[formField]`. */\r\n readonly checked = model(false);\r\n /** Secondary text under the label. */\r\n readonly description = input<string>();\r\n readonly name = input('');\r\n readonly disabled = input(false, { transform: booleanAttribute });\r\n readonly required = input(false, { transform: booleanAttribute });\r\n /** Emits when focus leaves the switch. */\r\n readonly touch = output<void>();\r\n\r\n protected onChange(event: Event): void {\r\n this.checked.set((event.target as HTMLInputElement).checked);\r\n }\r\n\r\n protected onDown(event: PointerEvent): void {\r\n if (this.disabled() || event.button !== 0) return;\r\n const track = event.currentTarget as HTMLElement;\r\n const rem = parseFloat(getComputedStyle(track.ownerDocument.documentElement).fontSize) || 16;\r\n const travel = track.clientWidth - 2 * TRACK_PADDING - PRESSED_THUMB * rem;\r\n this.press = {\r\n x: event.clientX,\r\n from: this.checked() ? travel : 0,\r\n travel,\r\n dir: getComputedStyle(track).direction === 'rtl' ? -1 : 1,\r\n pos: this.checked() ? travel : 0,\r\n };\r\n }\r\n\r\n protected onMove(event: PointerEvent): void {\r\n const press = this.press;\r\n if (!press) return;\r\n const moved = (event.clientX - press.x) * press.dir;\r\n if (this.drag() === null) {\r\n if (Math.abs(moved) < SLOP) return;\r\n try {\r\n (event.currentTarget as HTMLElement).setPointerCapture(event.pointerId);\r\n } catch {\r\n // The pointer is already gone; the drag still ends on pointerup.\r\n }\r\n }\r\n // Past either end the thumb resists instead of stopping dead.\r\n const raw = press.from + moved;\r\n const over = raw < 0 ? raw : raw > press.travel ? raw - press.travel : 0;\r\n press.pos = Math.min(Math.max(raw, 0), press.travel) + rubberband(over, press.travel);\r\n this.drag.set(press.pos * press.dir);\r\n }\r\n\r\n protected onUp(cancelled = false): void {\r\n const press = this.press;\r\n this.press = null;\r\n if (!press || this.drag() === null) return;\r\n this.drag.set(null);\r\n // Decided in logical position, so it is the same in both directions.\r\n const on = press.pos > press.travel / 2;\r\n if (cancelled) {\r\n this.checked.set(on);\r\n return;\r\n }\r\n // The release also clicks the label. That click applies the drag\r\n // instead of toggling; if no click comes, apply it anyway.\r\n this.landed = on;\r\n setTimeout(() => {\r\n if (this.landed === null) return;\r\n this.checked.set(this.landed);\r\n this.landed = null;\r\n });\r\n }\r\n\r\n protected onClick(event: MouseEvent): void {\r\n if (this.landed === null) return;\r\n event.preventDefault();\r\n this.checked.set(this.landed);\r\n this.landed = null;\r\n }\r\n}\r\n","<label class=\"hy-choice__row\">\r\n <span\r\n class=\"hy-choice__control hy-switch__track\"\r\n (pointerdown)=\"onDown($event)\"\r\n (pointermove)=\"onMove($event)\"\r\n (pointerup)=\"onUp()\"\r\n (pointercancel)=\"onUp(true)\"\r\n >\r\n <input\r\n type=\"checkbox\"\r\n role=\"switch\"\r\n class=\"hy-choice__input\"\r\n [name]=\"name()\"\r\n [checked]=\"checked()\"\r\n [disabled]=\"disabled()\"\r\n [required]=\"required()\"\r\n [attr.aria-checked]=\"checked()\"\r\n [attr.aria-describedby]=\"description() ? descriptionId : null\"\r\n (click)=\"onClick($event)\"\r\n (change)=\"onChange($event)\"\r\n (blur)=\"touch.emit()\"\r\n />\r\n <span\r\n class=\"hy-switch__thumb\"\r\n aria-hidden=\"true\"\r\n [attr.data-dragging]=\"drag() === null ? null : ''\"\r\n [style.--_drag.px]=\"drag()\"\r\n ></span>\r\n </span>\r\n <span class=\"hy-choice__label\"><ng-content /></span>\r\n</label>\r\n@if (description()) {\r\n <p class=\"hy-choice__description\" [id]=\"descriptionId\">{{ description() }}</p>\r\n}\r\n"],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import hljs from "highlight.js/lib/core";
|
|
2
|
+
const languages = {
|
|
3
|
+
typescript: () => import("highlight.js/lib/languages/typescript"),
|
|
4
|
+
javascript: () => import("highlight.js/lib/languages/javascript"),
|
|
5
|
+
css: () => import("highlight.js/lib/languages/css"),
|
|
6
|
+
html: () => import("highlight.js/lib/languages/xml"),
|
|
7
|
+
json: () => import("highlight.js/lib/languages/json"),
|
|
8
|
+
bash: () => import("highlight.js/lib/languages/bash")
|
|
9
|
+
};
|
|
10
|
+
const pending = /* @__PURE__ */ new Map();
|
|
11
|
+
async function highlight(code, language) {
|
|
12
|
+
const name = {
|
|
13
|
+
ts: "typescript",
|
|
14
|
+
js: "javascript",
|
|
15
|
+
xml: "html",
|
|
16
|
+
sh: "bash"
|
|
17
|
+
}[language] ?? language;
|
|
18
|
+
if (!(name in languages)) return null;
|
|
19
|
+
let ready = pending.get(name);
|
|
20
|
+
if (!ready) {
|
|
21
|
+
const load = languages[name];
|
|
22
|
+
ready = load().then((module) => {
|
|
23
|
+
hljs.registerLanguage(name, module.default);
|
|
24
|
+
});
|
|
25
|
+
pending.set(name, ready);
|
|
26
|
+
}
|
|
27
|
+
try {
|
|
28
|
+
await ready;
|
|
29
|
+
return hljs.highlight(code, {
|
|
30
|
+
language: name,
|
|
31
|
+
ignoreIllegals: true
|
|
32
|
+
}).value;
|
|
33
|
+
} catch {
|
|
34
|
+
pending.delete(name);
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
export { highlight };
|
|
39
|
+
|
|
40
|
+
//# sourceMappingURL=hyalo-angular-code-block-highlight-B20d5C76.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hyalo-angular-code-block-highlight-B20d5C76.mjs","names":[],"sources":["../../../projects/hyalo/code-block/highlight.ts"],"sourcesContent":["import hljs from 'highlight.js/lib/core';\r\nconst languages = {\r\n typescript: () => import('highlight.js/lib/languages/typescript'),\r\n javascript: () => import('highlight.js/lib/languages/javascript'),\r\n css: () => import('highlight.js/lib/languages/css'),\r\n html: () => import('highlight.js/lib/languages/xml'),\r\n json: () => import('highlight.js/lib/languages/json'),\r\n bash: () => import('highlight.js/lib/languages/bash'),\r\n};\r\nconst pending = new Map<string, Promise<void>>();\r\nexport async function highlight(code: string, language: string): Promise<string | null> {\r\n const name =\r\n ({ ts: 'typescript', js: 'javascript', xml: 'html', sh: 'bash' } as Record<string, string>)[\r\n language\r\n ] ?? language;\r\n if (!(name in languages)) return null;\r\n let ready = pending.get(name);\r\n if (!ready) {\r\n const load = languages[name as keyof typeof languages];\r\n ready = load().then((module) => {\r\n hljs.registerLanguage(name, module.default);\r\n });\r\n pending.set(name, ready);\r\n }\r\n try {\r\n await ready;\r\n return hljs.highlight(code, { language: name, ignoreIllegals: true }).value;\r\n } catch {\r\n pending.delete(name);\r\n return null;\r\n }\r\n}\r\n"],"mappings":";AACA,MAAM,YAAY;CAChB,kBAAkB,OAAO;CACzB,kBAAkB,OAAO;CACzB,WAAW,OAAO;CAClB,YAAY,OAAO;CACnB,YAAY,OAAO;CACnB,YAAY,OAAO;AACpB;AACD,MAAM,0BAAU,IAAI,IAAG;AACvB,eAAsB,UAAU,MAAc,UAAgB;CAC5D,MAAM,OACH;EAAE,IAAI;EAAc,IAAI;EAAc,KAAK;EAAQ,IAAI;CAAM,EAC5D,aACG;CACP,IAAI,EAAE,QAAQ,YAAY,OAAO;CACjC,IAAI,QAAQ,QAAQ,IAAI,IAAI;CAC5B,IAAI,CAAC,OAAO;EACV,MAAM,OAAO,UAAU;EACvB,QAAQ,KAAI,CAAE,CAAC,MAAM,WAAU;GAC7B,KAAK,iBAAiB,MAAM,OAAO,OAAO;EAC5C,CAAC;EACD,QAAQ,IAAI,MAAM,KAAK;CACzB;CACA,IAAI;EACF,MAAM;EACN,OAAO,KAAK,UAAU,MAAM;GAAE,UAAU;GAAM,gBAAgB;EAAI,CAAE,CAAC,CAAC;CACxE,QAAQ;EACN,QAAQ,OAAO,IAAI;EACnB,OAAO;CACT;AACF"}
|