@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,309 @@
|
|
|
1
|
+
import * as i0 from "@angular/core";
|
|
2
|
+
import { ChangeDetectionStrategy, Component, computed, input, model } from "@angular/core";
|
|
3
|
+
import { NgTemplateOutlet } from "@angular/common";
|
|
4
|
+
import { HyField, HyInput } from "@hyalo/angular/field";
|
|
5
|
+
import { HySelect } from "@hyalo/angular/select";
|
|
6
|
+
function encodeFilters(clauses) {
|
|
7
|
+
return JSON.stringify({
|
|
8
|
+
version: 1,
|
|
9
|
+
clauses
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
function decodeFilters(text, codec) {
|
|
13
|
+
const payload = JSON.parse(text);
|
|
14
|
+
if (!payload || typeof payload !== "object" || !("version" in payload) || payload.version !== 1 || !("clauses" in payload) || !Array.isArray(payload.clauses)) throw new Error("Unsupported filter state");
|
|
15
|
+
const ids = /* @__PURE__ */ new Set();
|
|
16
|
+
return payload.clauses.map((value) => {
|
|
17
|
+
if (!isFilterToken(value) || !codec.accepts(value) || ids.has(value.id)) throw new Error("Invalid or unsupported filter clause");
|
|
18
|
+
ids.add(value.id);
|
|
19
|
+
return value;
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
function isFilterToken(value) {
|
|
23
|
+
if (!value || typeof value !== "object" || !("id" in value) || typeof value.id !== "string" || !value.id || !("field" in value) || typeof value.field !== "string" || !value.field || !("operator" in value) || !("value" in value)) return false;
|
|
24
|
+
const data = value.value;
|
|
25
|
+
const scalar = (v) => typeof v === "string" || typeof v === "boolean" || typeof v === "number" && Number.isFinite(v);
|
|
26
|
+
if (value.operator === "eq") return scalar(data);
|
|
27
|
+
if (value.operator === "contains") return typeof data === "string";
|
|
28
|
+
if (value.operator === "in") return Array.isArray(data) && data.every(scalar);
|
|
29
|
+
if (value.operator !== "between") return false;
|
|
30
|
+
if (Array.isArray(data)) return data.length === 2 && data.every((v) => typeof v === "number" && Number.isFinite(v)) && data[0] <= data[1];
|
|
31
|
+
if (!data || typeof data !== "object" || !("timeZone" in data) || typeof data.timeZone !== "string" || !("kind" in data)) return false;
|
|
32
|
+
try {
|
|
33
|
+
new Intl.DateTimeFormat("en", { timeZone: data.timeZone });
|
|
34
|
+
} catch {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
if (data.kind === "preset") return "preset" in data && [
|
|
38
|
+
"24H",
|
|
39
|
+
"7D",
|
|
40
|
+
"30D",
|
|
41
|
+
"1Y"
|
|
42
|
+
].includes(String(data.preset));
|
|
43
|
+
const instant = (v) => typeof v === "string" && /^\d{4}-\d{2}-\d{2}T.*(?:Z|[+-]\d{2}:\d{2})$/.test(v) && Number.isFinite(Date.parse(v));
|
|
44
|
+
return data.kind === "absolute" && "start" in data && "end" in data && instant(data.start) && instant(data.end) && Date.parse(data.start) < Date.parse(data.end);
|
|
45
|
+
}
|
|
46
|
+
function resolveDateRange(value, now) {
|
|
47
|
+
if (!isFilterToken({
|
|
48
|
+
id: "range",
|
|
49
|
+
field: "time",
|
|
50
|
+
operator: "between",
|
|
51
|
+
value
|
|
52
|
+
}) || !Number.isFinite(now.getTime())) throw new Error("Invalid date range");
|
|
53
|
+
if (value.kind === "absolute") return {
|
|
54
|
+
start: value.start,
|
|
55
|
+
end: value.end
|
|
56
|
+
};
|
|
57
|
+
const hours = {
|
|
58
|
+
"24H": 24,
|
|
59
|
+
"7D": 168,
|
|
60
|
+
"30D": 720,
|
|
61
|
+
"1Y": 8760
|
|
62
|
+
}[value.preset];
|
|
63
|
+
return {
|
|
64
|
+
start: (/* @__PURE__ */ new Date(now.getTime() - hours * 36e5)).toISOString(),
|
|
65
|
+
end: now.toISOString()
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
var HyFilterBar = class HyFilterBar {
|
|
69
|
+
fields = input.required(...ngDevMode ? [{ debugName: "fields" }] : /* istanbul ignore next */ []);
|
|
70
|
+
clauses = model([], ...ngDevMode ? [{ debugName: "clauses" }] : /* istanbul ignore next */ []);
|
|
71
|
+
label = input("Filter results", ...ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []);
|
|
72
|
+
clearLabel = input("Clear filters", ...ngDevMode ? [{ debugName: "clearLabel" }] : /* istanbul ignore next */ []);
|
|
73
|
+
removeLabel = input("Remove", ...ngDevMode ? [{ debugName: "removeLabel" }] : /* istanbul ignore next */ []);
|
|
74
|
+
anyLabel = input("Any", ...ngDevMode ? [{ debugName: "anyLabel" }] : /* istanbul ignore next */ []);
|
|
75
|
+
activeLabel = input("Active filters", ...ngDevMode ? [{ debugName: "activeLabel" }] : /* istanbul ignore next */ []);
|
|
76
|
+
view = computed(() => this.clauses().map((clause) => {
|
|
77
|
+
const field = this.fields().find((entry) => entry.field === clause.field);
|
|
78
|
+
return {
|
|
79
|
+
clause,
|
|
80
|
+
label: field?.label ?? clause.field,
|
|
81
|
+
text: field?.format?.(clause) ?? (typeof clause.value === "object" ? JSON.stringify(clause.value) : String(clause.value)),
|
|
82
|
+
editor: field?.editor,
|
|
83
|
+
context: {
|
|
84
|
+
$implicit: clause,
|
|
85
|
+
update: (next) => this.update(next)
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
}), ...ngDevMode ? [{ debugName: "view" }] : /* istanbul ignore next */ []);
|
|
89
|
+
raw(field) {
|
|
90
|
+
const value = this.clauses().find((clause) => clause.field === field)?.value;
|
|
91
|
+
if (typeof value === "object" && value && !Array.isArray(value) && "kind" in value && value.kind === "preset" && "preset" in value) return String(value.preset);
|
|
92
|
+
return typeof value === "string" ? value : "";
|
|
93
|
+
}
|
|
94
|
+
change(field, raw) {
|
|
95
|
+
const existing = this.clauses().find((clause) => clause.field === field.field);
|
|
96
|
+
const next = raw ? field.create(existing?.id ?? `filter-${field.field}`, raw) : null;
|
|
97
|
+
this.clauses.set([...this.clauses().filter((clause) => clause.field !== field.field), ...next ? [next] : []]);
|
|
98
|
+
}
|
|
99
|
+
remove(id) {
|
|
100
|
+
this.clauses.update((items) => items.filter((item) => item.id !== id));
|
|
101
|
+
}
|
|
102
|
+
update(next) {
|
|
103
|
+
this.clauses.update((items) => items.map((item) => item.id === next.id ? next : item));
|
|
104
|
+
}
|
|
105
|
+
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
106
|
+
minVersion: "12.0.0",
|
|
107
|
+
version: "22.2.3",
|
|
108
|
+
ngImport: i0,
|
|
109
|
+
type: HyFilterBar,
|
|
110
|
+
deps: [],
|
|
111
|
+
target: i0.ɵɵFactoryTarget.Component
|
|
112
|
+
});
|
|
113
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({
|
|
114
|
+
minVersion: "17.0.0",
|
|
115
|
+
version: "22.2.3",
|
|
116
|
+
type: HyFilterBar,
|
|
117
|
+
isStandalone: true,
|
|
118
|
+
selector: "hy-filter-bar",
|
|
119
|
+
inputs: {
|
|
120
|
+
fields: {
|
|
121
|
+
classPropertyName: "fields",
|
|
122
|
+
publicName: "fields",
|
|
123
|
+
isSignal: true,
|
|
124
|
+
isRequired: true,
|
|
125
|
+
transformFunction: null
|
|
126
|
+
},
|
|
127
|
+
clauses: {
|
|
128
|
+
classPropertyName: "clauses",
|
|
129
|
+
publicName: "clauses",
|
|
130
|
+
isSignal: true,
|
|
131
|
+
isRequired: false,
|
|
132
|
+
transformFunction: null
|
|
133
|
+
},
|
|
134
|
+
label: {
|
|
135
|
+
classPropertyName: "label",
|
|
136
|
+
publicName: "label",
|
|
137
|
+
isSignal: true,
|
|
138
|
+
isRequired: false,
|
|
139
|
+
transformFunction: null
|
|
140
|
+
},
|
|
141
|
+
clearLabel: {
|
|
142
|
+
classPropertyName: "clearLabel",
|
|
143
|
+
publicName: "clearLabel",
|
|
144
|
+
isSignal: true,
|
|
145
|
+
isRequired: false,
|
|
146
|
+
transformFunction: null
|
|
147
|
+
},
|
|
148
|
+
removeLabel: {
|
|
149
|
+
classPropertyName: "removeLabel",
|
|
150
|
+
publicName: "removeLabel",
|
|
151
|
+
isSignal: true,
|
|
152
|
+
isRequired: false,
|
|
153
|
+
transformFunction: null
|
|
154
|
+
},
|
|
155
|
+
anyLabel: {
|
|
156
|
+
classPropertyName: "anyLabel",
|
|
157
|
+
publicName: "anyLabel",
|
|
158
|
+
isSignal: true,
|
|
159
|
+
isRequired: false,
|
|
160
|
+
transformFunction: null
|
|
161
|
+
},
|
|
162
|
+
activeLabel: {
|
|
163
|
+
classPropertyName: "activeLabel",
|
|
164
|
+
publicName: "activeLabel",
|
|
165
|
+
isSignal: true,
|
|
166
|
+
isRequired: false,
|
|
167
|
+
transformFunction: null
|
|
168
|
+
}
|
|
169
|
+
},
|
|
170
|
+
outputs: { clauses: "clausesChange" },
|
|
171
|
+
ngImport: i0,
|
|
172
|
+
template: "<div class=\"editors\" role=\"group\" [attr.aria-label]=\"label()\">\n @for (field of fields(); track field.field) {\n <hy-field class=\"field\" [label]=\"field.label\">\n @if (field.options; as options) {\n <hy-select\n [options]=\"options\"\n [native]=\"true\"\n [value]=\"raw(field.field)\"\n (valueChange)=\"change(field, $event ?? '')\"\n [placeholder]=\"anyLabel()\"\n />\n } @else {\n <input\n hyInput\n type=\"search\"\n [attr.aria-label]=\"field.label\"\n [value]=\"raw(field.field)\"\n (input)=\"change(field, $any($event.target).value)\"\n />\n }\n </hy-field>\n }\n @if (clauses().length) {\n <button type=\"button\" (click)=\"clauses.set([])\">{{ clearLabel() }}</button>\n }\n <ng-content />\n</div>\n<div class=\"tokens\" role=\"list\" [attr.aria-label]=\"activeLabel()\">\n @for (item of view(); track item.clause.id) {\n <span role=\"listitem\">\n @if (item.editor; as editor) {\n <ng-container [ngTemplateOutlet]=\"editor\" [ngTemplateOutletContext]=\"item.context\" />\n } @else {\n <span>{{ item.label }}: {{ item.text }}</span>\n }\n <button\n type=\"button\"\n [attr.aria-label]=\"removeLabel() + ' ' + item.label\"\n (click)=\"remove(item.clause.id)\"\n >\n ×\n </button>\n </span>\n }\n</div>\n",
|
|
173
|
+
styles: [":host{display:block}.editors,.tokens{display:flex;flex-wrap:wrap;align-items:end;gap:.75rem}.tokens{margin-block-start:.75rem}.field{display:grid;gap:.25rem;font-size:.875rem;min-inline-size:min(12rem,100%);flex:1 1 12rem}button{min-block-size:44px;border:1px solid var(--hy-line);border-radius:var(--hy-radius-s);background:var(--hy-surface-1);color:var(--hy-ink);font:inherit;padding:.5rem .75rem}.tokens>span{display:inline-flex;align-items:center;gap:.5rem;background:var(--hy-surface-2);border-radius:var(--hy-radius-s);padding-inline-start:.75rem}button{cursor:pointer}button:focus-visible{outline:2px solid var(--hy-primary);outline-offset:2px}\n"],
|
|
174
|
+
dependencies: [
|
|
175
|
+
{
|
|
176
|
+
kind: "component",
|
|
177
|
+
type: HySelect,
|
|
178
|
+
selector: "hy-select",
|
|
179
|
+
inputs: [
|
|
180
|
+
"options",
|
|
181
|
+
"value",
|
|
182
|
+
"placeholder",
|
|
183
|
+
"name",
|
|
184
|
+
"optionTemplate",
|
|
185
|
+
"disabled",
|
|
186
|
+
"required",
|
|
187
|
+
"invalid",
|
|
188
|
+
"errors",
|
|
189
|
+
"touched",
|
|
190
|
+
"native"
|
|
191
|
+
],
|
|
192
|
+
outputs: ["valueChange", "touch"]
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
kind: "directive",
|
|
196
|
+
type: NgTemplateOutlet,
|
|
197
|
+
selector: "[ngTemplateOutlet]",
|
|
198
|
+
inputs: [
|
|
199
|
+
"ngTemplateOutletContext",
|
|
200
|
+
"ngTemplateOutlet",
|
|
201
|
+
"ngTemplateOutletInjector"
|
|
202
|
+
]
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
kind: "component",
|
|
206
|
+
type: HyField,
|
|
207
|
+
selector: "hy-field",
|
|
208
|
+
inputs: [
|
|
209
|
+
"label",
|
|
210
|
+
"hint",
|
|
211
|
+
"error",
|
|
212
|
+
"forceError",
|
|
213
|
+
"size"
|
|
214
|
+
]
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
kind: "directive",
|
|
218
|
+
type: HyInput,
|
|
219
|
+
selector: "input[hyInput], textarea[hyInput]"
|
|
220
|
+
}
|
|
221
|
+
],
|
|
222
|
+
changeDetection: i0.ChangeDetectionStrategy.OnPush
|
|
223
|
+
});
|
|
224
|
+
};
|
|
225
|
+
i0.ɵɵngDeclareClassMetadata({
|
|
226
|
+
minVersion: "12.0.0",
|
|
227
|
+
version: "22.2.3",
|
|
228
|
+
ngImport: i0,
|
|
229
|
+
type: HyFilterBar,
|
|
230
|
+
decorators: [{
|
|
231
|
+
type: Component,
|
|
232
|
+
args: [{
|
|
233
|
+
selector: "hy-filter-bar",
|
|
234
|
+
imports: [
|
|
235
|
+
HySelect,
|
|
236
|
+
NgTemplateOutlet,
|
|
237
|
+
HyField,
|
|
238
|
+
HyInput
|
|
239
|
+
],
|
|
240
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
241
|
+
template: "<div class=\"editors\" role=\"group\" [attr.aria-label]=\"label()\">\n @for (field of fields(); track field.field) {\n <hy-field class=\"field\" [label]=\"field.label\">\n @if (field.options; as options) {\n <hy-select\n [options]=\"options\"\n [native]=\"true\"\n [value]=\"raw(field.field)\"\n (valueChange)=\"change(field, $event ?? '')\"\n [placeholder]=\"anyLabel()\"\n />\n } @else {\n <input\n hyInput\n type=\"search\"\n [attr.aria-label]=\"field.label\"\n [value]=\"raw(field.field)\"\n (input)=\"change(field, $any($event.target).value)\"\n />\n }\n </hy-field>\n }\n @if (clauses().length) {\n <button type=\"button\" (click)=\"clauses.set([])\">{{ clearLabel() }}</button>\n }\n <ng-content />\n</div>\n<div class=\"tokens\" role=\"list\" [attr.aria-label]=\"activeLabel()\">\n @for (item of view(); track item.clause.id) {\n <span role=\"listitem\">\n @if (item.editor; as editor) {\n <ng-container [ngTemplateOutlet]=\"editor\" [ngTemplateOutletContext]=\"item.context\" />\n } @else {\n <span>{{ item.label }}: {{ item.text }}</span>\n }\n <button\n type=\"button\"\n [attr.aria-label]=\"removeLabel() + ' ' + item.label\"\n (click)=\"remove(item.clause.id)\"\n >\n ×\n </button>\n </span>\n }\n</div>\n",
|
|
242
|
+
styles: [":host{display:block}.editors,.tokens{display:flex;flex-wrap:wrap;align-items:end;gap:.75rem}.tokens{margin-block-start:.75rem}.field{display:grid;gap:.25rem;font-size:.875rem;min-inline-size:min(12rem,100%);flex:1 1 12rem}button{min-block-size:44px;border:1px solid var(--hy-line);border-radius:var(--hy-radius-s);background:var(--hy-surface-1);color:var(--hy-ink);font:inherit;padding:.5rem .75rem}.tokens>span{display:inline-flex;align-items:center;gap:.5rem;background:var(--hy-surface-2);border-radius:var(--hy-radius-s);padding-inline-start:.75rem}button{cursor:pointer}button:focus-visible{outline:2px solid var(--hy-primary);outline-offset:2px}\n"]
|
|
243
|
+
}]
|
|
244
|
+
}],
|
|
245
|
+
propDecorators: {
|
|
246
|
+
fields: [{
|
|
247
|
+
type: i0.Input,
|
|
248
|
+
args: [{
|
|
249
|
+
isSignal: true,
|
|
250
|
+
alias: "fields",
|
|
251
|
+
required: true
|
|
252
|
+
}]
|
|
253
|
+
}],
|
|
254
|
+
clauses: [{
|
|
255
|
+
type: i0.Input,
|
|
256
|
+
args: [{
|
|
257
|
+
isSignal: true,
|
|
258
|
+
alias: "clauses",
|
|
259
|
+
required: false
|
|
260
|
+
}]
|
|
261
|
+
}, {
|
|
262
|
+
type: i0.Output,
|
|
263
|
+
args: ["clausesChange"]
|
|
264
|
+
}],
|
|
265
|
+
label: [{
|
|
266
|
+
type: i0.Input,
|
|
267
|
+
args: [{
|
|
268
|
+
isSignal: true,
|
|
269
|
+
alias: "label",
|
|
270
|
+
required: false
|
|
271
|
+
}]
|
|
272
|
+
}],
|
|
273
|
+
clearLabel: [{
|
|
274
|
+
type: i0.Input,
|
|
275
|
+
args: [{
|
|
276
|
+
isSignal: true,
|
|
277
|
+
alias: "clearLabel",
|
|
278
|
+
required: false
|
|
279
|
+
}]
|
|
280
|
+
}],
|
|
281
|
+
removeLabel: [{
|
|
282
|
+
type: i0.Input,
|
|
283
|
+
args: [{
|
|
284
|
+
isSignal: true,
|
|
285
|
+
alias: "removeLabel",
|
|
286
|
+
required: false
|
|
287
|
+
}]
|
|
288
|
+
}],
|
|
289
|
+
anyLabel: [{
|
|
290
|
+
type: i0.Input,
|
|
291
|
+
args: [{
|
|
292
|
+
isSignal: true,
|
|
293
|
+
alias: "anyLabel",
|
|
294
|
+
required: false
|
|
295
|
+
}]
|
|
296
|
+
}],
|
|
297
|
+
activeLabel: [{
|
|
298
|
+
type: i0.Input,
|
|
299
|
+
args: [{
|
|
300
|
+
isSignal: true,
|
|
301
|
+
alias: "activeLabel",
|
|
302
|
+
required: false
|
|
303
|
+
}]
|
|
304
|
+
}]
|
|
305
|
+
}
|
|
306
|
+
});
|
|
307
|
+
export { HyFilterBar, decodeFilters, encodeFilters, isFilterToken, resolveDateRange };
|
|
308
|
+
|
|
309
|
+
//# sourceMappingURL=hyalo-angular-filter.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hyalo-angular-filter.mjs","names":[],"sources":["../../../projects/hyalo/filter/state.ts","../../../projects/hyalo/filter/filter.ts","../../../projects/hyalo/filter/filter-bar.html"],"sourcesContent":["export type HyFilterScalar = string | number | boolean;\nexport type HyDatePreset = '24H' | '7D' | '30D' | '1Y';\nexport type HyDateRangeValue =\n | { readonly kind: 'preset'; readonly preset: HyDatePreset; readonly timeZone: string }\n | {\n readonly kind: 'absolute';\n readonly start: string;\n readonly end: string;\n readonly timeZone: string;\n };\nexport type HyFilterRule =\n | { readonly operator: 'eq'; readonly value: HyFilterScalar }\n | { readonly operator: 'in'; readonly value: readonly HyFilterScalar[] }\n | { readonly operator: 'contains'; readonly value: string }\n | { readonly operator: 'between'; readonly value: readonly [number, number] | HyDateRangeValue };\nexport type HyFilterClause<S> = {\n [K in keyof S]: { readonly id: string; readonly field: K } & S[K];\n}[keyof S];\nexport type HyFilterToken = { readonly id: string; readonly field: string } & HyFilterRule;\nexport interface HyFilterCodec<C extends HyFilterToken> {\n readonly accepts: (value: unknown) => value is C;\n}\nexport function encodeFilters<C extends HyFilterToken>(clauses: readonly C[]): string {\n return JSON.stringify({ version: 1, clauses });\n}\nexport function decodeFilters<C extends HyFilterToken>(\n text: string,\n codec: HyFilterCodec<C>,\n): readonly C[] {\n const payload: unknown = JSON.parse(text);\n if (\n !payload ||\n typeof payload !== 'object' ||\n !('version' in payload) ||\n payload.version !== 1 ||\n !('clauses' in payload) ||\n !Array.isArray(payload.clauses)\n )\n throw new Error('Unsupported filter state');\n const ids = new Set<string>();\n return payload.clauses.map((value: unknown) => {\n if (!isFilterToken(value) || !codec.accepts(value) || ids.has(value.id))\n throw new Error('Invalid or unsupported filter clause');\n ids.add(value.id);\n return value;\n });\n}\nexport function isFilterToken(value: unknown): value is HyFilterToken {\n if (\n !value ||\n typeof value !== 'object' ||\n !('id' in value) ||\n typeof value.id !== 'string' ||\n !value.id ||\n !('field' in value) ||\n typeof value.field !== 'string' ||\n !value.field ||\n !('operator' in value) ||\n !('value' in value)\n )\n return false;\n const data = value.value;\n const scalar = (v: unknown): v is HyFilterScalar =>\n typeof v === 'string' ||\n typeof v === 'boolean' ||\n (typeof v === 'number' && Number.isFinite(v));\n if (value.operator === 'eq') return scalar(data);\n if (value.operator === 'contains') return typeof data === 'string';\n if (value.operator === 'in') return Array.isArray(data) && data.every(scalar);\n if (value.operator !== 'between') return false;\n if (Array.isArray(data))\n return (\n data.length === 2 &&\n data.every((v) => typeof v === 'number' && Number.isFinite(v)) &&\n data[0] <= data[1]\n );\n if (\n !data ||\n typeof data !== 'object' ||\n !('timeZone' in data) ||\n typeof data.timeZone !== 'string' ||\n !('kind' in data)\n )\n return false;\n try {\n new Intl.DateTimeFormat('en', { timeZone: data.timeZone });\n } catch {\n return false;\n }\n if (data.kind === 'preset')\n return 'preset' in data && ['24H', '7D', '30D', '1Y'].includes(String(data.preset));\n const instant = (v: unknown): v is string =>\n typeof v === 'string' &&\n /^\\d{4}-\\d{2}-\\d{2}T.*(?:Z|[+-]\\d{2}:\\d{2})$/.test(v) &&\n Number.isFinite(Date.parse(v));\n return (\n data.kind === 'absolute' &&\n 'start' in data &&\n 'end' in data &&\n instant(data.start) &&\n instant(data.end) &&\n Date.parse(data.start) < Date.parse(data.end)\n );\n}\n\n/** Presets are rolling elapsed intervals; both editors use start-inclusive/end-exclusive instants. */\nexport function resolveDateRange(\n value: HyDateRangeValue,\n now: Date,\n): { readonly start: string; readonly end: string } {\n if (\n !isFilterToken({ id: 'range', field: 'time', operator: 'between', value }) ||\n !Number.isFinite(now.getTime())\n )\n throw new Error('Invalid date range');\n if (value.kind === 'absolute') return { start: value.start, end: value.end };\n const hours = { '24H': 24, '7D': 168, '30D': 720, '1Y': 8760 }[value.preset];\n return { start: new Date(now.getTime() - hours * 3600000).toISOString(), end: now.toISOString() };\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n TemplateRef,\n computed,\n input,\n model,\n} from '@angular/core';\nimport { NgTemplateOutlet } from '@angular/common';\nimport { HyField, HyInput } from '@hyalo/angular/field';\nimport { HySelect } from '@hyalo/angular/select';\nimport { type HySelectOption } from '@hyalo/angular/select';\nimport { type HyFilterToken } from './state';\nexport interface HyFilterEditorContext<C> {\n readonly $implicit: C;\n readonly update: (clause: C) => void;\n}\nexport interface HyFilterField<C extends HyFilterToken> {\n readonly field: C['field'];\n readonly label: string;\n readonly options?: readonly HySelectOption<string>[];\n readonly create: (id: string, value: string) => C | null;\n readonly editor?: TemplateRef<HyFilterEditorContext<C>>;\n readonly format?: (clause: C) => string;\n}\n@Component({\n selector: 'hy-filter-bar',\n imports: [HySelect, NgTemplateOutlet, HyField, HyInput],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './filter-bar.html',\n styleUrl: './filter-bar.css',\n})\nexport class HyFilterBar<C extends HyFilterToken> {\n readonly fields = input.required<readonly HyFilterField<C>[]>();\n readonly clauses = model<readonly C[]>([]);\n readonly label = input('Filter results');\n readonly clearLabel = input('Clear filters');\n readonly removeLabel = input('Remove');\n readonly anyLabel = input('Any');\n readonly activeLabel = input('Active filters');\n protected readonly view = computed(() =>\n this.clauses().map((clause) => {\n const field = this.fields().find((entry) => entry.field === clause.field);\n return {\n clause,\n label: field?.label ?? clause.field,\n text:\n field?.format?.(clause) ??\n (typeof clause.value === 'object' ? JSON.stringify(clause.value) : String(clause.value)),\n editor: field?.editor,\n context: { $implicit: clause, update: (next: C) => this.update(next) },\n };\n }),\n );\n protected raw(field: string): string {\n const value = this.clauses().find((clause) => clause.field === field)?.value;\n if (\n typeof value === 'object' &&\n value &&\n !Array.isArray(value) &&\n 'kind' in value &&\n value.kind === 'preset' &&\n 'preset' in value\n )\n return String(value.preset);\n return typeof value === 'string' ? value : '';\n }\n protected change(field: HyFilterField<C>, raw: string): void {\n const existing = this.clauses().find((clause) => clause.field === field.field);\n const next = raw ? field.create(existing?.id ?? `filter-${field.field}`, raw) : null;\n this.clauses.set([\n ...this.clauses().filter((clause) => clause.field !== field.field),\n ...(next ? [next] : []),\n ]);\n }\n protected remove(id: string): void {\n this.clauses.update((items) => items.filter((item) => item.id !== id));\n }\n private update(next: C): void {\n this.clauses.update((items) => items.map((item) => (item.id === next.id ? next : item)));\n }\n}\n","<div class=\"editors\" role=\"group\" [attr.aria-label]=\"label()\">\n @for (field of fields(); track field.field) {\n <hy-field class=\"field\" [label]=\"field.label\">\n @if (field.options; as options) {\n <hy-select\n [options]=\"options\"\n [native]=\"true\"\n [value]=\"raw(field.field)\"\n (valueChange)=\"change(field, $event ?? '')\"\n [placeholder]=\"anyLabel()\"\n />\n } @else {\n <input\n hyInput\n type=\"search\"\n [attr.aria-label]=\"field.label\"\n [value]=\"raw(field.field)\"\n (input)=\"change(field, $any($event.target).value)\"\n />\n }\n </hy-field>\n }\n @if (clauses().length) {\n <button type=\"button\" (click)=\"clauses.set([])\">{{ clearLabel() }}</button>\n }\n <ng-content />\n</div>\n<div class=\"tokens\" role=\"list\" [attr.aria-label]=\"activeLabel()\">\n @for (item of view(); track item.clause.id) {\n <span role=\"listitem\">\n @if (item.editor; as editor) {\n <ng-container [ngTemplateOutlet]=\"editor\" [ngTemplateOutletContext]=\"item.context\" />\n } @else {\n <span>{{ item.label }}: {{ item.text }}</span>\n }\n <button\n type=\"button\"\n [attr.aria-label]=\"removeLabel() + ' ' + item.label\"\n (click)=\"remove(item.clause.id)\"\n >\n ×\n </button>\n </span>\n }\n</div>\n"],"mappings":"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"}
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
import * as i0 from "@angular/core";
|
|
2
|
+
import { ChangeDetectionStrategy, Component, booleanAttribute, computed, inject, input, model, output } from "@angular/core";
|
|
3
|
+
import { HyMotion } from "@hyalo/angular/motion";
|
|
4
|
+
import { HyPopover } from "@hyalo/angular/popover";
|
|
5
|
+
var HyHotspot = class HyHotspot {
|
|
6
|
+
motion = inject(HyMotion);
|
|
7
|
+
label = input.required(...ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []);
|
|
8
|
+
position = input.required(...ngDevMode ? [{ debugName: "position" }] : /* istanbul ignore next */ []);
|
|
9
|
+
disabled = input(false, {
|
|
10
|
+
...ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {},
|
|
11
|
+
transform: booleanAttribute
|
|
12
|
+
});
|
|
13
|
+
description = input("", ...ngDevMode ? [{ debugName: "description" }] : /* istanbul ignore next */ []);
|
|
14
|
+
mode = input("label", ...ngDevMode ? [{ debugName: "mode" }] : /* istanbul ignore next */ []);
|
|
15
|
+
open = model(false, ...ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []);
|
|
16
|
+
placement = input("top", ...ngDevMode ? [{ debugName: "placement" }] : /* istanbul ignore next */ []);
|
|
17
|
+
closeLabel = input("Close details", ...ngDevMode ? [{ debugName: "closeLabel" }] : /* istanbul ignore next */ []);
|
|
18
|
+
activated = output();
|
|
19
|
+
visible = computed(() => this.position().visible !== false && Number.isFinite(this.position().x) && Number.isFinite(this.position().y), ...ngDevMode ? [{ debugName: "visible" }] : /* istanbul ignore next */ []);
|
|
20
|
+
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
21
|
+
minVersion: "12.0.0",
|
|
22
|
+
version: "22.2.3",
|
|
23
|
+
ngImport: i0,
|
|
24
|
+
type: HyHotspot,
|
|
25
|
+
deps: [],
|
|
26
|
+
target: i0.ɵɵFactoryTarget.Component
|
|
27
|
+
});
|
|
28
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({
|
|
29
|
+
minVersion: "17.0.0",
|
|
30
|
+
version: "22.2.3",
|
|
31
|
+
type: HyHotspot,
|
|
32
|
+
isStandalone: true,
|
|
33
|
+
selector: "hy-hotspot",
|
|
34
|
+
inputs: {
|
|
35
|
+
label: {
|
|
36
|
+
classPropertyName: "label",
|
|
37
|
+
publicName: "label",
|
|
38
|
+
isSignal: true,
|
|
39
|
+
isRequired: true,
|
|
40
|
+
transformFunction: null
|
|
41
|
+
},
|
|
42
|
+
position: {
|
|
43
|
+
classPropertyName: "position",
|
|
44
|
+
publicName: "position",
|
|
45
|
+
isSignal: true,
|
|
46
|
+
isRequired: true,
|
|
47
|
+
transformFunction: null
|
|
48
|
+
},
|
|
49
|
+
disabled: {
|
|
50
|
+
classPropertyName: "disabled",
|
|
51
|
+
publicName: "disabled",
|
|
52
|
+
isSignal: true,
|
|
53
|
+
isRequired: false,
|
|
54
|
+
transformFunction: null
|
|
55
|
+
},
|
|
56
|
+
description: {
|
|
57
|
+
classPropertyName: "description",
|
|
58
|
+
publicName: "description",
|
|
59
|
+
isSignal: true,
|
|
60
|
+
isRequired: false,
|
|
61
|
+
transformFunction: null
|
|
62
|
+
},
|
|
63
|
+
mode: {
|
|
64
|
+
classPropertyName: "mode",
|
|
65
|
+
publicName: "mode",
|
|
66
|
+
isSignal: true,
|
|
67
|
+
isRequired: false,
|
|
68
|
+
transformFunction: null
|
|
69
|
+
},
|
|
70
|
+
open: {
|
|
71
|
+
classPropertyName: "open",
|
|
72
|
+
publicName: "open",
|
|
73
|
+
isSignal: true,
|
|
74
|
+
isRequired: false,
|
|
75
|
+
transformFunction: null
|
|
76
|
+
},
|
|
77
|
+
placement: {
|
|
78
|
+
classPropertyName: "placement",
|
|
79
|
+
publicName: "placement",
|
|
80
|
+
isSignal: true,
|
|
81
|
+
isRequired: false,
|
|
82
|
+
transformFunction: null
|
|
83
|
+
},
|
|
84
|
+
closeLabel: {
|
|
85
|
+
classPropertyName: "closeLabel",
|
|
86
|
+
publicName: "closeLabel",
|
|
87
|
+
isSignal: true,
|
|
88
|
+
isRequired: false,
|
|
89
|
+
transformFunction: null
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
outputs: {
|
|
93
|
+
open: "openChange",
|
|
94
|
+
activated: "activated"
|
|
95
|
+
},
|
|
96
|
+
host: { properties: {
|
|
97
|
+
"style.inset-inline-start.%": "position().x",
|
|
98
|
+
"style.inset-block-start.%": "position().y",
|
|
99
|
+
"hidden": "!visible()",
|
|
100
|
+
"attr.data-mode": "mode()",
|
|
101
|
+
"attr.data-open": "open()",
|
|
102
|
+
"attr.data-motion": "motion.enabled()",
|
|
103
|
+
"style.--hy-hotspot-duration": "motion.enabled() ? \"var(--hy-dur-quick)\" : \"0ms\""
|
|
104
|
+
} },
|
|
105
|
+
ngImport: i0,
|
|
106
|
+
template: "@if (description()) {\r\n <button\r\n #popover=\"hyPopover\"\r\n type=\"button\"\r\n [disabled]=\"disabled()\"\r\n [attr.aria-label]=\"label()\"\r\n [hyPopover]=\"details\"\r\n [popoverLabel]=\"label()\"\r\n popoverMaterial=\"solid\"\r\n [popoverPlacement]=\"placement()\"\r\n [(popoverOpen)]=\"open\"\r\n (click)=\"activated.emit()\"\r\n >\r\n <span class=\"dot\" aria-hidden=\"true\"></span><span class=\"label\">{{ label() }}</span>\r\n </button>\r\n <ng-template #details>\r\n <div class=\"details\">\r\n <strong>{{ label() }}</strong>\r\n <p>{{ description() }}</p>\r\n <button class=\"close\" type=\"button\" (click)=\"popover.close()\">{{ closeLabel() }}</button>\r\n </div>\r\n </ng-template>\r\n} @else {\r\n <button\r\n type=\"button\"\r\n [disabled]=\"disabled()\"\r\n [attr.aria-label]=\"label()\"\r\n (click)=\"activated.emit()\"\r\n >\r\n <span class=\"dot\" aria-hidden=\"true\"></span><span class=\"label\">{{ label() }}</span>\r\n </button>\r\n}\r\n",
|
|
107
|
+
styles: [":host{display:block;position:absolute;z-index:1;transform:translate(-50%,-50%)}:host([hidden]){display:none}button{display:flex;align-items:center;gap:var(--hy-space-2);min-block-size:2.75rem;padding:var(--hy-space-2) var(--hy-space-4);border:1px solid var(--hy-line-strong);border-radius:var(--hy-radius-pill);color:var(--hy-ink);background:var(--hy-surface-1);box-shadow:var(--hy-glass-shadow);font:inherit;cursor:pointer;transition:transform var(--hy-hotspot-duration) var(--hy-ease-out),border-color var(--hy-hotspot-duration) ease}button[aria-expanded=true]{border-color:var(--hy-primary)}:host([data-motion=\"true\"]) button:active:not(:disabled){transform:scale(.97)}@media(hover:hover)and (pointer:fine){:host([data-motion=\"true\"]) button:hover:not(:disabled){transform:translateY(-2px)}}:host([data-mode=\"pin\"]) button{inline-size:2.75rem;padding:0;justify-content:center}:host([data-mode=\"pin\"]) .label{position:absolute;inline-size:1px;block-size:1px;overflow:hidden;clip-path:inset(50%)}strong{display:block;color:var(--hy-ink)}.details{display:block;min-inline-size:12rem;max-inline-size:18rem}p{max-inline-size:28ch;margin-block:var(--hy-space-2) var(--hy-space-4);color:var(--hy-ink-2);line-height:var(--hy-leading)}.close{min-block-size:2rem;padding:var(--hy-space-1) var(--hy-space-3);border-radius:var(--hy-radius-s);box-shadow:none;background:var(--hy-primary-wash);color:var(--hy-primary)}button:focus-visible{outline:2px solid var(--hy-primary);outline-offset:4px}button:disabled{opacity:.6;cursor:default}.dot{inline-size:.5rem;block-size:.5rem;border-radius:50%;background:var(--hy-primary)}:host:dir(rtl){transform:translate(50%,-50%)}\n"],
|
|
108
|
+
dependencies: [{
|
|
109
|
+
kind: "directive",
|
|
110
|
+
type: HyPopover,
|
|
111
|
+
selector: "[hyPopover]",
|
|
112
|
+
inputs: [
|
|
113
|
+
"hyPopover",
|
|
114
|
+
"popoverLabel",
|
|
115
|
+
"popoverMaterial",
|
|
116
|
+
"popoverPlacement",
|
|
117
|
+
"popoverOpen"
|
|
118
|
+
],
|
|
119
|
+
outputs: ["popoverOpenChange"],
|
|
120
|
+
exportAs: ["hyPopover"]
|
|
121
|
+
}],
|
|
122
|
+
changeDetection: i0.ChangeDetectionStrategy.OnPush
|
|
123
|
+
});
|
|
124
|
+
};
|
|
125
|
+
i0.ɵɵngDeclareClassMetadata({
|
|
126
|
+
minVersion: "12.0.0",
|
|
127
|
+
version: "22.2.3",
|
|
128
|
+
ngImport: i0,
|
|
129
|
+
type: HyHotspot,
|
|
130
|
+
decorators: [{
|
|
131
|
+
type: Component,
|
|
132
|
+
args: [{
|
|
133
|
+
selector: "hy-hotspot",
|
|
134
|
+
imports: [HyPopover],
|
|
135
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
136
|
+
host: {
|
|
137
|
+
"[style.inset-inline-start.%]": "position().x",
|
|
138
|
+
"[style.inset-block-start.%]": "position().y",
|
|
139
|
+
"[hidden]": "!visible()",
|
|
140
|
+
"[attr.data-mode]": "mode()",
|
|
141
|
+
"[attr.data-open]": "open()",
|
|
142
|
+
"[attr.data-motion]": "motion.enabled()",
|
|
143
|
+
"[style.--hy-hotspot-duration]": "motion.enabled() ? \"var(--hy-dur-quick)\" : \"0ms\""
|
|
144
|
+
},
|
|
145
|
+
template: "@if (description()) {\r\n <button\r\n #popover=\"hyPopover\"\r\n type=\"button\"\r\n [disabled]=\"disabled()\"\r\n [attr.aria-label]=\"label()\"\r\n [hyPopover]=\"details\"\r\n [popoverLabel]=\"label()\"\r\n popoverMaterial=\"solid\"\r\n [popoverPlacement]=\"placement()\"\r\n [(popoverOpen)]=\"open\"\r\n (click)=\"activated.emit()\"\r\n >\r\n <span class=\"dot\" aria-hidden=\"true\"></span><span class=\"label\">{{ label() }}</span>\r\n </button>\r\n <ng-template #details>\r\n <div class=\"details\">\r\n <strong>{{ label() }}</strong>\r\n <p>{{ description() }}</p>\r\n <button class=\"close\" type=\"button\" (click)=\"popover.close()\">{{ closeLabel() }}</button>\r\n </div>\r\n </ng-template>\r\n} @else {\r\n <button\r\n type=\"button\"\r\n [disabled]=\"disabled()\"\r\n [attr.aria-label]=\"label()\"\r\n (click)=\"activated.emit()\"\r\n >\r\n <span class=\"dot\" aria-hidden=\"true\"></span><span class=\"label\">{{ label() }}</span>\r\n </button>\r\n}\r\n",
|
|
146
|
+
styles: [":host{display:block;position:absolute;z-index:1;transform:translate(-50%,-50%)}:host([hidden]){display:none}button{display:flex;align-items:center;gap:var(--hy-space-2);min-block-size:2.75rem;padding:var(--hy-space-2) var(--hy-space-4);border:1px solid var(--hy-line-strong);border-radius:var(--hy-radius-pill);color:var(--hy-ink);background:var(--hy-surface-1);box-shadow:var(--hy-glass-shadow);font:inherit;cursor:pointer;transition:transform var(--hy-hotspot-duration) var(--hy-ease-out),border-color var(--hy-hotspot-duration) ease}button[aria-expanded=true]{border-color:var(--hy-primary)}:host([data-motion=\"true\"]) button:active:not(:disabled){transform:scale(.97)}@media(hover:hover)and (pointer:fine){:host([data-motion=\"true\"]) button:hover:not(:disabled){transform:translateY(-2px)}}:host([data-mode=\"pin\"]) button{inline-size:2.75rem;padding:0;justify-content:center}:host([data-mode=\"pin\"]) .label{position:absolute;inline-size:1px;block-size:1px;overflow:hidden;clip-path:inset(50%)}strong{display:block;color:var(--hy-ink)}.details{display:block;min-inline-size:12rem;max-inline-size:18rem}p{max-inline-size:28ch;margin-block:var(--hy-space-2) var(--hy-space-4);color:var(--hy-ink-2);line-height:var(--hy-leading)}.close{min-block-size:2rem;padding:var(--hy-space-1) var(--hy-space-3);border-radius:var(--hy-radius-s);box-shadow:none;background:var(--hy-primary-wash);color:var(--hy-primary)}button:focus-visible{outline:2px solid var(--hy-primary);outline-offset:4px}button:disabled{opacity:.6;cursor:default}.dot{inline-size:.5rem;block-size:.5rem;border-radius:50%;background:var(--hy-primary)}:host:dir(rtl){transform:translate(50%,-50%)}\n"]
|
|
147
|
+
}]
|
|
148
|
+
}],
|
|
149
|
+
propDecorators: {
|
|
150
|
+
label: [{
|
|
151
|
+
type: i0.Input,
|
|
152
|
+
args: [{
|
|
153
|
+
isSignal: true,
|
|
154
|
+
alias: "label",
|
|
155
|
+
required: true
|
|
156
|
+
}]
|
|
157
|
+
}],
|
|
158
|
+
position: [{
|
|
159
|
+
type: i0.Input,
|
|
160
|
+
args: [{
|
|
161
|
+
isSignal: true,
|
|
162
|
+
alias: "position",
|
|
163
|
+
required: true
|
|
164
|
+
}]
|
|
165
|
+
}],
|
|
166
|
+
disabled: [{
|
|
167
|
+
type: i0.Input,
|
|
168
|
+
args: [{
|
|
169
|
+
isSignal: true,
|
|
170
|
+
alias: "disabled",
|
|
171
|
+
required: false
|
|
172
|
+
}]
|
|
173
|
+
}],
|
|
174
|
+
description: [{
|
|
175
|
+
type: i0.Input,
|
|
176
|
+
args: [{
|
|
177
|
+
isSignal: true,
|
|
178
|
+
alias: "description",
|
|
179
|
+
required: false
|
|
180
|
+
}]
|
|
181
|
+
}],
|
|
182
|
+
mode: [{
|
|
183
|
+
type: i0.Input,
|
|
184
|
+
args: [{
|
|
185
|
+
isSignal: true,
|
|
186
|
+
alias: "mode",
|
|
187
|
+
required: false
|
|
188
|
+
}]
|
|
189
|
+
}],
|
|
190
|
+
open: [{
|
|
191
|
+
type: i0.Input,
|
|
192
|
+
args: [{
|
|
193
|
+
isSignal: true,
|
|
194
|
+
alias: "open",
|
|
195
|
+
required: false
|
|
196
|
+
}]
|
|
197
|
+
}, {
|
|
198
|
+
type: i0.Output,
|
|
199
|
+
args: ["openChange"]
|
|
200
|
+
}],
|
|
201
|
+
placement: [{
|
|
202
|
+
type: i0.Input,
|
|
203
|
+
args: [{
|
|
204
|
+
isSignal: true,
|
|
205
|
+
alias: "placement",
|
|
206
|
+
required: false
|
|
207
|
+
}]
|
|
208
|
+
}],
|
|
209
|
+
closeLabel: [{
|
|
210
|
+
type: i0.Input,
|
|
211
|
+
args: [{
|
|
212
|
+
isSignal: true,
|
|
213
|
+
alias: "closeLabel",
|
|
214
|
+
required: false
|
|
215
|
+
}]
|
|
216
|
+
}],
|
|
217
|
+
activated: [{
|
|
218
|
+
type: i0.Output,
|
|
219
|
+
args: ["activated"]
|
|
220
|
+
}]
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
export { HyHotspot };
|
|
224
|
+
|
|
225
|
+
//# sourceMappingURL=hyalo-angular-hotspot.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hyalo-angular-hotspot.mjs","names":[],"sources":["../../../projects/hyalo/hotspot/hotspot.ts","../../../projects/hyalo/hotspot/hotspot.html"],"sourcesContent":["import {\r\n ChangeDetectionStrategy,\r\n Component,\r\n booleanAttribute,\r\n computed,\r\n input,\r\n inject,\r\n model,\r\n output,\r\n} from '@angular/core';\r\nimport { HyMotion } from '@hyalo/angular/motion';\r\nimport { HyPopover } from '@hyalo/angular/popover';\r\nimport type { HyPlacement } from '@hyalo/angular/overlay';\r\nexport type HyHotspotMode = 'label' | 'pin';\r\nexport interface HyHotspotPosition {\r\n readonly x: number;\r\n readonly y: number;\r\n readonly visible?: boolean;\r\n}\r\n/** Pass screen coordinates from your scene's projection. Position is relative to its frame. */\r\n@Component({\r\n selector: 'hy-hotspot',\r\n imports: [HyPopover],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n host: {\r\n '[style.inset-inline-start.%]': 'position().x',\r\n '[style.inset-block-start.%]': 'position().y',\r\n '[hidden]': '!visible()',\r\n '[attr.data-mode]': 'mode()',\r\n '[attr.data-open]': 'open()',\r\n '[attr.data-motion]': 'motion.enabled()',\r\n '[style.--hy-hotspot-duration]': 'motion.enabled() ? \"var(--hy-dur-quick)\" : \"0ms\"',\r\n },\r\n templateUrl: './hotspot.html',\r\n styleUrl: './hotspot.css',\r\n})\r\nexport class HyHotspot {\r\n protected readonly motion = inject(HyMotion);\r\n readonly label = input.required<string>();\r\n readonly position = input.required<HyHotspotPosition>();\r\n readonly disabled = input(false, { transform: booleanAttribute });\r\n /** Optional detail panel. Without a description this stays a plain action button. */\r\n readonly description = input('');\r\n readonly mode = input<HyHotspotMode>('label');\r\n readonly open = model(false);\r\n readonly placement = input<HyPlacement>('top');\r\n readonly closeLabel = input('Close details');\r\n readonly activated = output<void>();\r\n protected readonly visible = computed(\r\n () =>\r\n this.position().visible !== false &&\r\n Number.isFinite(this.position().x) &&\r\n Number.isFinite(this.position().y),\r\n );\r\n}\r\n","@if (description()) {\r\n <button\r\n #popover=\"hyPopover\"\r\n type=\"button\"\r\n [disabled]=\"disabled()\"\r\n [attr.aria-label]=\"label()\"\r\n [hyPopover]=\"details\"\r\n [popoverLabel]=\"label()\"\r\n popoverMaterial=\"solid\"\r\n [popoverPlacement]=\"placement()\"\r\n [(popoverOpen)]=\"open\"\r\n (click)=\"activated.emit()\"\r\n >\r\n <span class=\"dot\" aria-hidden=\"true\"></span><span class=\"label\">{{ label() }}</span>\r\n </button>\r\n <ng-template #details>\r\n <div class=\"details\">\r\n <strong>{{ label() }}</strong>\r\n <p>{{ description() }}</p>\r\n <button class=\"close\" type=\"button\" (click)=\"popover.close()\">{{ closeLabel() }}</button>\r\n </div>\r\n </ng-template>\r\n} @else {\r\n <button\r\n type=\"button\"\r\n [disabled]=\"disabled()\"\r\n [attr.aria-label]=\"label()\"\r\n (click)=\"activated.emit()\"\r\n >\r\n <span class=\"dot\" aria-hidden=\"true\"></span><span class=\"label\">{{ label() }}</span>\r\n </button>\r\n}\r\n"],"mappings":"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"}
|