@hyalo/angular 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/CHANGELOG.md +41 -0
  2. package/LICENSE +21 -0
  3. package/README.md +32 -3
  4. package/fesm2022/hyalo-angular-accordion.mjs +230 -0
  5. package/fesm2022/hyalo-angular-accordion.mjs.map +1 -0
  6. package/fesm2022/hyalo-angular-button.mjs +203 -0
  7. package/fesm2022/hyalo-angular-button.mjs.map +1 -0
  8. package/fesm2022/hyalo-angular-card.mjs +221 -0
  9. package/fesm2022/hyalo-angular-card.mjs.map +1 -0
  10. package/fesm2022/hyalo-angular-choice.mjs +788 -0
  11. package/fesm2022/hyalo-angular-choice.mjs.map +1 -0
  12. package/fesm2022/hyalo-angular-dialog.mjs +571 -0
  13. package/fesm2022/hyalo-angular-dialog.mjs.map +1 -0
  14. package/fesm2022/hyalo-angular-field.mjs +312 -0
  15. package/fesm2022/hyalo-angular-field.mjs.map +1 -0
  16. package/fesm2022/hyalo-angular-icon.mjs +343 -0
  17. package/fesm2022/hyalo-angular-icon.mjs.map +1 -0
  18. package/fesm2022/hyalo-angular-interaction.mjs +455 -0
  19. package/fesm2022/hyalo-angular-interaction.mjs.map +1 -0
  20. package/fesm2022/hyalo-angular-navbar.mjs +343 -0
  21. package/fesm2022/hyalo-angular-navbar.mjs.map +1 -0
  22. package/fesm2022/hyalo-angular-overlay.mjs +94 -0
  23. package/fesm2022/hyalo-angular-overlay.mjs.map +1 -0
  24. package/fesm2022/hyalo-angular-popover-overlay-kit-6wPwnxln.mjs +3 -0
  25. package/fesm2022/hyalo-angular-popover.mjs +487 -0
  26. package/fesm2022/hyalo-angular-popover.mjs.map +1 -0
  27. package/fesm2022/hyalo-angular-segmented.mjs +223 -0
  28. package/fesm2022/hyalo-angular-segmented.mjs.map +1 -0
  29. package/fesm2022/hyalo-angular-select.mjs +464 -0
  30. package/fesm2022/hyalo-angular-select.mjs.map +1 -0
  31. package/fesm2022/hyalo-angular-tabs.mjs +324 -0
  32. package/fesm2022/hyalo-angular-tabs.mjs.map +1 -0
  33. package/fesm2022/hyalo-angular-theme.mjs +94 -0
  34. package/fesm2022/hyalo-angular-theme.mjs.map +1 -0
  35. package/fesm2022/hyalo-angular-toast.mjs +322 -0
  36. package/fesm2022/hyalo-angular-toast.mjs.map +1 -0
  37. package/fesm2022/hyalo-angular.mjs +473 -0
  38. package/fesm2022/hyalo-angular.mjs.map +1 -0
  39. package/package.json +133 -3
  40. package/styles/hyalo-core.css +25 -0
  41. package/styles/hyalo.css +17 -0
  42. package/styles/overlays/dialog.css +9 -0
  43. package/styles/overlays/popover.css +9 -0
  44. package/styles/overlays/select.css +9 -0
  45. package/styles/overlays/toast.css +8 -0
  46. package/styles/palettes/aurora.css +47 -0
  47. package/styles/palettes/ember.css +47 -0
  48. package/styles/palettes/graphite.css +47 -0
  49. package/styles/palettes/ocean.css +47 -0
  50. package/styles/palettes/orchid.css +47 -0
  51. package/styles/palettes/rose.css +47 -0
  52. package/styles/parts/card.css +49 -0
  53. package/styles/parts/dialog.css +116 -0
  54. package/styles/parts/drawer.css +124 -0
  55. package/styles/parts/field.css +36 -0
  56. package/styles/parts/glass.css +137 -0
  57. package/styles/parts/motion.css +82 -0
  58. package/styles/parts/navbar.css +55 -0
  59. package/styles/parts/popover.css +27 -0
  60. package/styles/parts/presence.css +55 -0
  61. package/styles/parts/reset.css +42 -0
  62. package/styles/parts/select.css +46 -0
  63. package/styles/parts/themes.css +105 -0
  64. package/styles/parts/toast.css +128 -0
  65. package/styles/parts/tokens.css +151 -0
  66. package/styles/parts/typography.css +64 -0
  67. package/types/hyalo-angular-accordion.d.ts +74 -0
  68. package/types/hyalo-angular-button.d.ts +88 -0
  69. package/types/hyalo-angular-card.d.ts +61 -0
  70. package/types/hyalo-angular-choice.d.ts +259 -0
  71. package/types/hyalo-angular-dialog.d.ts +170 -0
  72. package/types/hyalo-angular-field.d.ts +135 -0
  73. package/types/hyalo-angular-icon.d.ts +122 -0
  74. package/types/hyalo-angular-interaction.d.ts +131 -0
  75. package/types/hyalo-angular-navbar.d.ts +110 -0
  76. package/types/hyalo-angular-overlay.d.ts +31 -0
  77. package/types/hyalo-angular-popover.d.ts +142 -0
  78. package/types/hyalo-angular-segmented.d.ts +79 -0
  79. package/types/hyalo-angular-select.d.ts +130 -0
  80. package/types/hyalo-angular-tabs.d.ts +102 -0
  81. package/types/hyalo-angular-theme.d.ts +46 -0
  82. package/types/hyalo-angular-toast.d.ts +79 -0
  83. package/types/hyalo-angular.d.ts +345 -0
@@ -0,0 +1,487 @@
1
+ import { AriaDescriber, FocusTrapFactory } from "@angular/cdk/a11y";
2
+ import * as i0 from "@angular/core";
3
+ import { ChangeDetectionStrategy, Component, DestroyRef, Directive, ElementRef, Injector, ViewContainerRef, booleanAttribute, effect, inject, input, model, numberAttribute, signal, untracked } from "@angular/core";
4
+ import { hyConnectedPositions, ɵHyPresence } from "@hyalo/angular/overlay";
5
+ import { HyFidelity, injectId } from "@hyalo/angular";
6
+ let kit;
7
+ function loadOverlay() {
8
+ kit ??= import("./hyalo-angular-popover-overlay-kit-6wPwnxln.mjs").catch((error) => {
9
+ kit = void 0;
10
+ throw error;
11
+ });
12
+ return kit;
13
+ }
14
+ var HyTooltipPanel = class HyTooltipPanel {
15
+ message = signal("", ...ngDevMode ? [{ debugName: "message" }] : /* istanbul ignore next */ []);
16
+ static ɵfac = i0.ɵɵngDeclareFactory({
17
+ minVersion: "12.0.0",
18
+ version: "22.2.3",
19
+ ngImport: i0,
20
+ type: HyTooltipPanel,
21
+ deps: [],
22
+ target: i0.ɵɵFactoryTarget.Component
23
+ });
24
+ static ɵcmp = i0.ɵɵngDeclareComponent({
25
+ minVersion: "14.0.0",
26
+ version: "22.2.3",
27
+ type: HyTooltipPanel,
28
+ isStandalone: true,
29
+ selector: "hy-tooltip-panel",
30
+ host: {
31
+ attributes: { "aria-hidden": "true" },
32
+ classAttribute: "hy-tooltip"
33
+ },
34
+ ngImport: i0,
35
+ template: `{{ message() }}`,
36
+ isInline: true,
37
+ changeDetection: i0.ChangeDetectionStrategy.OnPush
38
+ });
39
+ };
40
+ i0.ɵɵngDeclareClassMetadata({
41
+ minVersion: "12.0.0",
42
+ version: "22.2.3",
43
+ ngImport: i0,
44
+ type: HyTooltipPanel,
45
+ decorators: [{
46
+ type: Component,
47
+ args: [{
48
+ selector: "hy-tooltip-panel",
49
+ changeDetection: ChangeDetectionStrategy.OnPush,
50
+ host: {
51
+ class: "hy-tooltip",
52
+ "aria-hidden": "true"
53
+ },
54
+ template: `{{ message() }}`
55
+ }]
56
+ }]
57
+ });
58
+ var HyTooltip = class HyTooltip {
59
+ injector = inject(Injector);
60
+ host = inject(ElementRef);
61
+ describer = inject(AriaDescriber);
62
+ overlayRef = null;
63
+ position = null;
64
+ panel = null;
65
+ panelEl = null;
66
+ presence = new ɵHyPresence();
67
+ showTimer;
68
+ hideTimer;
69
+ wanted = false;
70
+ destroyed = false;
71
+ message = input("", {
72
+ ...ngDevMode ? { debugName: "message" } : /* istanbul ignore next */ {},
73
+ alias: "hyTooltip"
74
+ });
75
+ tooltipPlacement = input("top", ...ngDevMode ? [{ debugName: "tooltipPlacement" }] : /* istanbul ignore next */ []);
76
+ tooltipDelay = input(400, {
77
+ ...ngDevMode ? { debugName: "tooltipDelay" } : /* istanbul ignore next */ {},
78
+ transform: numberAttribute
79
+ });
80
+ tooltipDisabled = input(false, {
81
+ ...ngDevMode ? { debugName: "tooltipDisabled" } : /* istanbul ignore next */ {},
82
+ transform: booleanAttribute
83
+ });
84
+ constructor() {
85
+ let described = "";
86
+ effect(() => {
87
+ const message = this.message();
88
+ if (described) this.describer.removeDescription(this.host.nativeElement, described);
89
+ if (message) this.describer.describe(this.host.nativeElement, message);
90
+ described = message;
91
+ if (this.panel) this.panel.message.set(message);
92
+ });
93
+ inject(DestroyRef).onDestroy(() => {
94
+ this.destroyed = true;
95
+ clearTimeout(this.showTimer);
96
+ clearTimeout(this.hideTimer);
97
+ if (described) this.describer.removeDescription(this.host.nativeElement, described);
98
+ this.overlayRef?.dispose();
99
+ });
100
+ }
101
+ onPointerEnter(event) {
102
+ if (event.pointerType !== "touch") this.show(this.tooltipDelay());
103
+ }
104
+ show(delay = this.tooltipDelay()) {
105
+ if (this.tooltipDisabled() || !this.message()) return;
106
+ clearTimeout(this.hideTimer);
107
+ clearTimeout(this.showTimer);
108
+ this.wanted = true;
109
+ loadOverlay().catch(() => void 0);
110
+ this.showTimer = setTimeout(() => void this.attach(), delay);
111
+ }
112
+ hide() {
113
+ this.wanted = false;
114
+ clearTimeout(this.showTimer);
115
+ clearTimeout(this.hideTimer);
116
+ const ref = this.overlayRef;
117
+ if (!ref?.hasAttached() || !this.panelEl) return;
118
+ this.presence.leave(this.panelEl, () => ref.detach());
119
+ }
120
+ scheduleHide() {
121
+ clearTimeout(this.showTimer);
122
+ this.hideTimer = setTimeout(() => this.hide(), 120);
123
+ }
124
+ async attach() {
125
+ const kit = await loadOverlay().catch(() => null);
126
+ if (!kit || !this.wanted || this.destroyed) return;
127
+ const { ComponentPortal, createFlexibleConnectedPositionStrategy, createOverlayRef, createRepositionScrollStrategy } = kit;
128
+ if (!this.overlayRef) {
129
+ this.position = createFlexibleConnectedPositionStrategy(this.injector, this.host).withFlexibleDimensions(false).withViewportMargin(8).withTransformOriginOn(".hy-tooltip");
130
+ this.overlayRef = createOverlayRef(this.injector, {
131
+ positionStrategy: this.position,
132
+ scrollStrategy: createRepositionScrollStrategy(this.injector),
133
+ panelClass: "hy-tooltip-pane"
134
+ });
135
+ this.overlayRef.overlayElement.addEventListener("pointerenter", () => clearTimeout(this.hideTimer));
136
+ this.overlayRef.overlayElement.addEventListener("pointerleave", () => this.scheduleHide());
137
+ }
138
+ if (this.overlayRef.hasAttached()) {
139
+ if (this.presence.leaving && this.panelEl) this.presence.enter(this.panelEl);
140
+ return;
141
+ }
142
+ this.position?.withPositions(hyConnectedPositions(this.tooltipPlacement()));
143
+ const ref = this.overlayRef.attach(new ComponentPortal(HyTooltipPanel, null, this.injector));
144
+ this.panel = ref.instance;
145
+ this.panel.message.set(this.message());
146
+ const el = ref.location.nativeElement;
147
+ this.panelEl = el;
148
+ this.presence.enter(el);
149
+ ref.onDestroy(() => {
150
+ this.panel = null;
151
+ this.panelEl = null;
152
+ });
153
+ }
154
+ static ɵfac = i0.ɵɵngDeclareFactory({
155
+ minVersion: "12.0.0",
156
+ version: "22.2.3",
157
+ ngImport: i0,
158
+ type: HyTooltip,
159
+ deps: [],
160
+ target: i0.ɵɵFactoryTarget.Directive
161
+ });
162
+ static ɵdir = i0.ɵɵngDeclareDirective({
163
+ minVersion: "17.1.0",
164
+ version: "22.2.3",
165
+ type: HyTooltip,
166
+ isStandalone: true,
167
+ selector: "[hyTooltip]",
168
+ inputs: {
169
+ message: {
170
+ classPropertyName: "message",
171
+ publicName: "hyTooltip",
172
+ isSignal: true,
173
+ isRequired: false,
174
+ transformFunction: null
175
+ },
176
+ tooltipPlacement: {
177
+ classPropertyName: "tooltipPlacement",
178
+ publicName: "tooltipPlacement",
179
+ isSignal: true,
180
+ isRequired: false,
181
+ transformFunction: null
182
+ },
183
+ tooltipDelay: {
184
+ classPropertyName: "tooltipDelay",
185
+ publicName: "tooltipDelay",
186
+ isSignal: true,
187
+ isRequired: false,
188
+ transformFunction: null
189
+ },
190
+ tooltipDisabled: {
191
+ classPropertyName: "tooltipDisabled",
192
+ publicName: "tooltipDisabled",
193
+ isSignal: true,
194
+ isRequired: false,
195
+ transformFunction: null
196
+ }
197
+ },
198
+ host: { listeners: {
199
+ "pointerenter": "onPointerEnter($event)",
200
+ "pointerleave": "scheduleHide()",
201
+ "focusin": "show(0)",
202
+ "focusout": "hide()",
203
+ "keydown.escape": "hide()"
204
+ } },
205
+ ngImport: i0
206
+ });
207
+ };
208
+ i0.ɵɵngDeclareClassMetadata({
209
+ minVersion: "12.0.0",
210
+ version: "22.2.3",
211
+ ngImport: i0,
212
+ type: HyTooltip,
213
+ decorators: [{
214
+ type: Directive,
215
+ args: [{
216
+ selector: "[hyTooltip]",
217
+ host: {
218
+ "(pointerenter)": "onPointerEnter($event)",
219
+ "(pointerleave)": "scheduleHide()",
220
+ "(focusin)": "show(0)",
221
+ "(focusout)": "hide()",
222
+ "(keydown.escape)": "hide()"
223
+ }
224
+ }]
225
+ }],
226
+ ctorParameters: () => [],
227
+ propDecorators: {
228
+ message: [{
229
+ type: i0.Input,
230
+ args: [{
231
+ isSignal: true,
232
+ alias: "hyTooltip",
233
+ required: false
234
+ }]
235
+ }],
236
+ tooltipPlacement: [{
237
+ type: i0.Input,
238
+ args: [{
239
+ isSignal: true,
240
+ alias: "tooltipPlacement",
241
+ required: false
242
+ }]
243
+ }],
244
+ tooltipDelay: [{
245
+ type: i0.Input,
246
+ args: [{
247
+ isSignal: true,
248
+ alias: "tooltipDelay",
249
+ required: false
250
+ }]
251
+ }],
252
+ tooltipDisabled: [{
253
+ type: i0.Input,
254
+ args: [{
255
+ isSignal: true,
256
+ alias: "tooltipDisabled",
257
+ required: false
258
+ }]
259
+ }]
260
+ }
261
+ });
262
+ var HyPopover = class HyPopover {
263
+ injector = inject(Injector);
264
+ host = inject(ElementRef);
265
+ viewContainer = inject(ViewContainerRef);
266
+ focusTraps = inject(FocusTrapFactory);
267
+ fidelity = inject(HyFidelity);
268
+ panelId = injectId("popover");
269
+ overlayRef = null;
270
+ position = null;
271
+ presence = new ɵHyPresence();
272
+ destroyed = false;
273
+ content = input.required({
274
+ ...ngDevMode ? { debugName: "content" } : /* istanbul ignore next */ {},
275
+ alias: "hyPopover"
276
+ });
277
+ popoverLabel = input(...ngDevMode ? [void 0, { debugName: "popoverLabel" }] : /* istanbul ignore next */ []);
278
+ popoverPlacement = input("bottom", ...ngDevMode ? [{ debugName: "popoverPlacement" }] : /* istanbul ignore next */ []);
279
+ open = model(false, {
280
+ ...ngDevMode ? { debugName: "open" } : /* istanbul ignore next */ {},
281
+ alias: "popoverOpen"
282
+ });
283
+ constructor() {
284
+ effect(() => {
285
+ const open = this.open();
286
+ untracked(() => open ? void this.attach() : this.detach());
287
+ });
288
+ inject(DestroyRef).onDestroy(() => {
289
+ this.destroyed = true;
290
+ this.overlayRef?.dispose();
291
+ });
292
+ }
293
+ toggle() {
294
+ this.open.update((v) => !v);
295
+ }
296
+ close(restoreFocus = true) {
297
+ if (!this.open()) return;
298
+ this.open.set(false);
299
+ if (restoreFocus) this.host.nativeElement.focus();
300
+ }
301
+ preload() {
302
+ loadOverlay().catch(() => void 0);
303
+ }
304
+ async attach() {
305
+ const kit = await loadOverlay().catch(() => null);
306
+ if (this.destroyed) return;
307
+ if (!kit) {
308
+ this.open.set(false);
309
+ return;
310
+ }
311
+ if (!this.open()) return;
312
+ const { TemplatePortal, createFlexibleConnectedPositionStrategy, createOverlayRef, createRepositionScrollStrategy } = kit;
313
+ if (!this.overlayRef) {
314
+ this.position = createFlexibleConnectedPositionStrategy(this.injector, this.host).withViewportMargin(12).withPush(true).withTransformOriginOn(".hy-popover");
315
+ this.overlayRef = createOverlayRef(this.injector, {
316
+ positionStrategy: this.position,
317
+ scrollStrategy: createRepositionScrollStrategy(this.injector),
318
+ panelClass: "hy-popover-pane"
319
+ });
320
+ this.overlayRef.keydownEvents().subscribe((event) => {
321
+ if (event.key === "Escape") {
322
+ event.preventDefault();
323
+ this.close();
324
+ }
325
+ });
326
+ this.overlayRef.outsidePointerEvents().subscribe((event) => {
327
+ if (!this.host.nativeElement.contains(event.target)) this.close(false);
328
+ });
329
+ }
330
+ if (this.overlayRef.hasAttached()) {
331
+ if (this.presence.leaving) this.presence.enter(this.overlayRef.overlayElement);
332
+ return;
333
+ }
334
+ this.position?.withPositions(hyConnectedPositions(this.popoverPlacement(), 10));
335
+ this.overlayRef.attach(new TemplatePortal(this.content(), this.viewContainer));
336
+ const pane = this.overlayRef.overlayElement;
337
+ pane.id = this.panelId;
338
+ pane.setAttribute("role", "dialog");
339
+ const label = this.popoverLabel();
340
+ if (label) pane.setAttribute("aria-label", label);
341
+ else pane.removeAttribute("aria-label");
342
+ pane.classList.add("hy-glass", "hy-popover");
343
+ pane.dataset["material"] = this.fidelity.tier() === "low" ? "solid" : "frosted";
344
+ pane.addEventListener("focusout", this.onFocusOut);
345
+ this.presence.enter(pane);
346
+ const trap = this.focusTraps.create(pane);
347
+ trap.focusFirstTabbableElementWhenReady().then((found) => {
348
+ if (!found) {
349
+ pane.tabIndex = -1;
350
+ pane.focus();
351
+ }
352
+ trap.destroy();
353
+ });
354
+ }
355
+ detach() {
356
+ const ref = this.overlayRef;
357
+ if (!ref?.hasAttached()) return;
358
+ ref.overlayElement.removeEventListener("focusout", this.onFocusOut);
359
+ this.presence.leave(ref.overlayElement, () => ref.detach());
360
+ }
361
+ onFocusOut = (event) => {
362
+ const next = event.relatedTarget;
363
+ if (next && !this.overlayRef?.overlayElement.contains(next) && next !== this.host.nativeElement) this.close(false);
364
+ };
365
+ static ɵfac = i0.ɵɵngDeclareFactory({
366
+ minVersion: "12.0.0",
367
+ version: "22.2.3",
368
+ ngImport: i0,
369
+ type: HyPopover,
370
+ deps: [],
371
+ target: i0.ɵɵFactoryTarget.Directive
372
+ });
373
+ static ɵdir = i0.ɵɵngDeclareDirective({
374
+ minVersion: "17.1.0",
375
+ version: "22.2.3",
376
+ type: HyPopover,
377
+ isStandalone: true,
378
+ selector: "[hyPopover]",
379
+ inputs: {
380
+ content: {
381
+ classPropertyName: "content",
382
+ publicName: "hyPopover",
383
+ isSignal: true,
384
+ isRequired: true,
385
+ transformFunction: null
386
+ },
387
+ popoverLabel: {
388
+ classPropertyName: "popoverLabel",
389
+ publicName: "popoverLabel",
390
+ isSignal: true,
391
+ isRequired: false,
392
+ transformFunction: null
393
+ },
394
+ popoverPlacement: {
395
+ classPropertyName: "popoverPlacement",
396
+ publicName: "popoverPlacement",
397
+ isSignal: true,
398
+ isRequired: false,
399
+ transformFunction: null
400
+ },
401
+ open: {
402
+ classPropertyName: "open",
403
+ publicName: "popoverOpen",
404
+ isSignal: true,
405
+ isRequired: false,
406
+ transformFunction: null
407
+ }
408
+ },
409
+ outputs: { open: "popoverOpenChange" },
410
+ host: {
411
+ attributes: { "aria-haspopup": "dialog" },
412
+ listeners: {
413
+ "click": "toggle()",
414
+ "pointerenter": "preload()",
415
+ "focusin": "preload()"
416
+ },
417
+ properties: {
418
+ "attr.aria-expanded": "open()",
419
+ "attr.aria-controls": "open() ? panelId : null"
420
+ }
421
+ },
422
+ exportAs: ["hyPopover"],
423
+ ngImport: i0
424
+ });
425
+ };
426
+ i0.ɵɵngDeclareClassMetadata({
427
+ minVersion: "12.0.0",
428
+ version: "22.2.3",
429
+ ngImport: i0,
430
+ type: HyPopover,
431
+ decorators: [{
432
+ type: Directive,
433
+ args: [{
434
+ selector: "[hyPopover]",
435
+ exportAs: "hyPopover",
436
+ host: {
437
+ "aria-haspopup": "dialog",
438
+ "[attr.aria-expanded]": "open()",
439
+ "[attr.aria-controls]": "open() ? panelId : null",
440
+ "(click)": "toggle()",
441
+ "(pointerenter)": "preload()",
442
+ "(focusin)": "preload()"
443
+ }
444
+ }]
445
+ }],
446
+ ctorParameters: () => [],
447
+ propDecorators: {
448
+ content: [{
449
+ type: i0.Input,
450
+ args: [{
451
+ isSignal: true,
452
+ alias: "hyPopover",
453
+ required: true
454
+ }]
455
+ }],
456
+ popoverLabel: [{
457
+ type: i0.Input,
458
+ args: [{
459
+ isSignal: true,
460
+ alias: "popoverLabel",
461
+ required: false
462
+ }]
463
+ }],
464
+ popoverPlacement: [{
465
+ type: i0.Input,
466
+ args: [{
467
+ isSignal: true,
468
+ alias: "popoverPlacement",
469
+ required: false
470
+ }]
471
+ }],
472
+ open: [{
473
+ type: i0.Input,
474
+ args: [{
475
+ isSignal: true,
476
+ alias: "popoverOpen",
477
+ required: false
478
+ }]
479
+ }, {
480
+ type: i0.Output,
481
+ args: ["popoverOpenChange"]
482
+ }]
483
+ }
484
+ });
485
+ export { HyPopover, HyTooltip, HyTooltipPanel };
486
+
487
+ //# sourceMappingURL=hyalo-angular-popover.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hyalo-angular-popover.mjs","names":["HyPresence","HyPresence"],"sources":["../../../projects/hyalo/popover/load-overlay.ts","../../../projects/hyalo/popover/tooltip.ts","../../../projects/hyalo/popover/popover.ts"],"sourcesContent":["/**\r\n * @internal Loads the overlay code the first time a tooltip or popover is\r\n * about to open. A page full of triggers then costs nothing until someone\r\n * hovers or clicks one, and the import resolves to the same module when the\r\n * app already uses the overlay elsewhere.\r\n */\r\nexport type HyOverlayKit = typeof import('./overlay-kit');\r\n\r\nlet kit: Promise<HyOverlayKit> | undefined;\r\n\r\n/** @internal */\r\nexport function loadOverlay(): Promise<HyOverlayKit> {\r\n kit ??= import('./overlay-kit').catch((error: unknown) => {\r\n // A failed chunk load should not stick; the next open tries again.\r\n kit = undefined;\r\n throw error;\r\n });\r\n return kit;\r\n}\r\n","import { AriaDescriber } from '@angular/cdk/a11y';\r\nimport type { FlexibleConnectedPositionStrategy, OverlayRef } from '@angular/cdk/overlay';\r\nimport {\r\n ChangeDetectionStrategy,\r\n Component,\r\n DestroyRef,\r\n Directive,\r\n ElementRef,\r\n Injector,\r\n booleanAttribute,\r\n effect,\r\n inject,\r\n input,\r\n numberAttribute,\r\n signal,\r\n} from '@angular/core';\r\nimport {\r\n hyConnectedPositions,\r\n type HyPlacement,\r\n ɵHyPresence as HyPresence,\r\n} from '@hyalo/angular/overlay';\r\nimport { loadOverlay } from './load-overlay';\r\n\r\n@Component({\r\n selector: 'hy-tooltip-panel',\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n host: { class: 'hy-tooltip', 'aria-hidden': 'true' },\r\n template: `{{ message() }}`,\r\n})\r\nexport class HyTooltipPanel {\r\n readonly message = signal('');\r\n}\r\n\r\n/**\r\n * A short text hint on hover or keyboard focus.\r\n *\r\n * ```html\r\n * <button hyButton iconOnly aria-label=\"Copy link\" hyTooltip=\"Copy link\">...</button>\r\n * ```\r\n *\r\n * The text is also added to the trigger's `aria-describedby` through a\r\n * hidden element, so screen readers get it without the visual tooltip. The\r\n * tooltip stays open while the pointer is over it and closes on Escape, as\r\n * WCAG 1.4.13 asks. Keep it short and never put interactive content in it;\r\n * use `hyPopover` for that.\r\n */\r\n@Directive({\r\n selector: '[hyTooltip]',\r\n host: {\r\n '(pointerenter)': 'onPointerEnter($event)',\r\n '(pointerleave)': 'scheduleHide()',\r\n '(focusin)': 'show(0)',\r\n '(focusout)': 'hide()',\r\n '(keydown.escape)': 'hide()',\r\n },\r\n})\r\nexport class HyTooltip {\r\n private readonly injector = inject(Injector);\r\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\r\n private readonly describer = inject(AriaDescriber);\r\n private overlayRef: OverlayRef | null = null;\r\n private position: FlexibleConnectedPositionStrategy | null = null;\r\n private panel: HyTooltipPanel | null = null;\r\n private panelEl: HTMLElement | null = null;\r\n private readonly presence = new HyPresence();\r\n private showTimer: ReturnType<typeof setTimeout> | undefined;\r\n private hideTimer: ReturnType<typeof setTimeout> | undefined;\r\n /** True from show() until hide(), so a late overlay load knows to stop. */\r\n private wanted = false;\r\n private destroyed = false;\r\n\r\n /** The tooltip text. */\r\n readonly message = input('', { alias: 'hyTooltip' });\r\n /** Preferred side. Flips when there is no room. */\r\n readonly tooltipPlacement = input<HyPlacement>('top');\r\n /** Hover delay in milliseconds. Focus shows it right away. */\r\n readonly tooltipDelay = input(400, { transform: numberAttribute });\r\n readonly tooltipDisabled = input(false, { transform: booleanAttribute });\r\n\r\n constructor() {\r\n let described = '';\r\n effect(() => {\r\n const message = this.message();\r\n if (described) this.describer.removeDescription(this.host.nativeElement, described);\r\n if (message) this.describer.describe(this.host.nativeElement, message);\r\n described = message;\r\n if (this.panel) this.panel.message.set(message);\r\n });\r\n inject(DestroyRef).onDestroy(() => {\r\n this.destroyed = true;\r\n clearTimeout(this.showTimer);\r\n clearTimeout(this.hideTimer);\r\n if (described) this.describer.removeDescription(this.host.nativeElement, described);\r\n this.overlayRef?.dispose();\r\n });\r\n }\r\n\r\n protected onPointerEnter(event: PointerEvent): void {\r\n if (event.pointerType !== 'touch') this.show(this.tooltipDelay());\r\n }\r\n\r\n /** Shows the tooltip after the given delay. */\r\n show(delay = this.tooltipDelay()): void {\r\n if (this.tooltipDisabled() || !this.message()) return;\r\n clearTimeout(this.hideTimer);\r\n clearTimeout(this.showTimer);\r\n this.wanted = true;\r\n // Load during the hover delay, so the tooltip is ready when it ends.\r\n loadOverlay().catch(() => undefined);\r\n this.showTimer = setTimeout(() => void this.attach(), delay);\r\n }\r\n\r\n /** Starts hiding the tooltip now. It fades out quickly. */\r\n hide(): void {\r\n this.wanted = false;\r\n clearTimeout(this.showTimer);\r\n clearTimeout(this.hideTimer);\r\n const ref = this.overlayRef;\r\n if (!ref?.hasAttached() || !this.panelEl) return;\r\n this.presence.leave(this.panelEl, () => ref.detach());\r\n }\r\n\r\n protected scheduleHide(): void {\r\n clearTimeout(this.showTimer);\r\n this.hideTimer = setTimeout(() => this.hide(), 120);\r\n }\r\n\r\n private async attach(): Promise<void> {\r\n const kit = await loadOverlay().catch(() => null);\r\n if (!kit || !this.wanted || this.destroyed) return;\r\n const {\r\n ComponentPortal,\r\n createFlexibleConnectedPositionStrategy,\r\n createOverlayRef,\r\n createRepositionScrollStrategy,\r\n } = kit;\r\n if (!this.overlayRef) {\r\n this.position = createFlexibleConnectedPositionStrategy(this.injector, this.host)\r\n .withFlexibleDimensions(false)\r\n .withViewportMargin(8)\r\n .withTransformOriginOn('.hy-tooltip');\r\n this.overlayRef = createOverlayRef(this.injector, {\r\n positionStrategy: this.position,\r\n scrollStrategy: createRepositionScrollStrategy(this.injector),\r\n panelClass: 'hy-tooltip-pane',\r\n });\r\n // Hovering the tooltip itself keeps it open.\r\n this.overlayRef.overlayElement.addEventListener('pointerenter', () =>\r\n clearTimeout(this.hideTimer),\r\n );\r\n this.overlayRef.overlayElement.addEventListener('pointerleave', () => this.scheduleHide());\r\n }\r\n if (this.overlayRef.hasAttached()) {\r\n if (this.presence.leaving && this.panelEl) this.presence.enter(this.panelEl);\r\n return;\r\n }\r\n // Read on every show, so a changed placement applies next time.\r\n this.position?.withPositions(hyConnectedPositions(this.tooltipPlacement()));\r\n const ref = this.overlayRef.attach(new ComponentPortal(HyTooltipPanel, null, this.injector));\r\n this.panel = ref.instance;\r\n this.panel.message.set(this.message());\r\n const el = ref.location.nativeElement as HTMLElement;\r\n this.panelEl = el;\r\n this.presence.enter(el);\r\n ref.onDestroy(() => {\r\n this.panel = null;\r\n this.panelEl = null;\r\n });\r\n }\r\n}\r\n","import { FocusTrapFactory } from '@angular/cdk/a11y';\r\nimport type { FlexibleConnectedPositionStrategy, OverlayRef } from '@angular/cdk/overlay';\r\nimport {\r\n DestroyRef,\r\n Directive,\r\n ElementRef,\r\n Injector,\r\n TemplateRef,\r\n ViewContainerRef,\r\n inject,\r\n input,\r\n model,\r\n effect,\r\n untracked,\r\n} from '@angular/core';\r\nimport { HyFidelity, injectId } from '@hyalo/angular';\r\nimport {\r\n hyConnectedPositions,\r\n type HyPlacement,\r\n ɵHyPresence as HyPresence,\r\n} from '@hyalo/angular/overlay';\r\nimport { loadOverlay } from './load-overlay';\r\n\r\n/**\r\n * A non-modal glass panel anchored to a trigger, for content that does not\r\n * fit in a tooltip: a short form, a menu of links, details.\r\n *\r\n * ```html\r\n * <button hyButton variant=\"glass\" [hyPopover]=\"share\" popoverLabel=\"Share\">Share</button>\r\n * <ng-template #share>\r\n * <a href=\"...\">Copy link</a>\r\n * </ng-template>\r\n * ```\r\n *\r\n * Click or Enter toggles it. On open, focus moves to the first focusable\r\n * element inside. Escape closes it and returns focus to the trigger, and so\r\n * does clicking outside or tabbing out of it.\r\n */\r\n@Directive({\r\n selector: '[hyPopover]',\r\n exportAs: 'hyPopover',\r\n host: {\r\n 'aria-haspopup': 'dialog',\r\n '[attr.aria-expanded]': 'open()',\r\n '[attr.aria-controls]': 'open() ? panelId : null',\r\n '(click)': 'toggle()',\r\n // Fetch the overlay code as soon as the user heads for the trigger.\r\n '(pointerenter)': 'preload()',\r\n '(focusin)': 'preload()',\r\n },\r\n})\r\nexport class HyPopover {\r\n private readonly injector = inject(Injector);\r\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\r\n private readonly viewContainer = inject(ViewContainerRef);\r\n private readonly focusTraps = inject(FocusTrapFactory);\r\n private readonly fidelity = inject(HyFidelity);\r\n protected readonly panelId = injectId('popover');\r\n private overlayRef: OverlayRef | null = null;\r\n private position: FlexibleConnectedPositionStrategy | null = null;\r\n private readonly presence = new HyPresence();\r\n private destroyed = false;\r\n\r\n /** The content. */\r\n readonly content = input.required<TemplateRef<unknown>>({ alias: 'hyPopover' });\r\n /** Accessible name of the panel. */\r\n readonly popoverLabel = input<string>();\r\n /** Preferred side. Flips when there is no room. */\r\n readonly popoverPlacement = input<HyPlacement>('bottom');\r\n /** Whether the panel is open. Two-way bindable as `[(popoverOpen)]`. */\r\n readonly open = model(false, { alias: 'popoverOpen' });\r\n\r\n constructor() {\r\n effect(() => {\r\n const open = this.open();\r\n untracked(() => (open ? void this.attach() : this.detach()));\r\n });\r\n inject(DestroyRef).onDestroy(() => {\r\n this.destroyed = true;\r\n this.overlayRef?.dispose();\r\n });\r\n }\r\n\r\n toggle(): void {\r\n this.open.update((v) => !v);\r\n }\r\n\r\n /** Closes the panel, optionally moving focus back to the trigger. */\r\n close(restoreFocus = true): void {\r\n if (!this.open()) return;\r\n this.open.set(false);\r\n if (restoreFocus) this.host.nativeElement.focus();\r\n }\r\n\r\n protected preload(): void {\r\n loadOverlay().catch(() => undefined);\r\n }\r\n\r\n private async attach(): Promise<void> {\r\n const kit = await loadOverlay().catch(() => null);\r\n if (this.destroyed) return;\r\n if (!kit) {\r\n // Without the overlay code there is no panel, so do not claim one.\r\n this.open.set(false);\r\n return;\r\n }\r\n // It may have been closed again while the code loaded.\r\n if (!this.open()) return;\r\n const {\r\n TemplatePortal,\r\n createFlexibleConnectedPositionStrategy,\r\n createOverlayRef,\r\n createRepositionScrollStrategy,\r\n } = kit;\r\n if (!this.overlayRef) {\r\n this.position = createFlexibleConnectedPositionStrategy(this.injector, this.host)\r\n .withViewportMargin(12)\r\n .withPush(true)\r\n // The panel grows out of its trigger, not out of its own centre.\r\n .withTransformOriginOn('.hy-popover');\r\n this.overlayRef = createOverlayRef(this.injector, {\r\n positionStrategy: this.position,\r\n scrollStrategy: createRepositionScrollStrategy(this.injector),\r\n panelClass: 'hy-popover-pane',\r\n });\r\n this.overlayRef.keydownEvents().subscribe((event) => {\r\n if (event.key === 'Escape') {\r\n event.preventDefault();\r\n this.close();\r\n }\r\n });\r\n this.overlayRef.outsidePointerEvents().subscribe((event) => {\r\n if (!this.host.nativeElement.contains(event.target as Node)) this.close(false);\r\n });\r\n }\r\n if (this.overlayRef.hasAttached()) {\r\n // Reopened while fading out: turn the exit around.\r\n if (this.presence.leaving) this.presence.enter(this.overlayRef.overlayElement);\r\n return;\r\n }\r\n // Read on every open, so a changed placement applies next time.\r\n this.position?.withPositions(hyConnectedPositions(this.popoverPlacement(), 10));\r\n this.overlayRef.attach(new TemplatePortal(this.content(), this.viewContainer));\r\n\r\n const pane = this.overlayRef.overlayElement;\r\n pane.id = this.panelId;\r\n pane.setAttribute('role', 'dialog');\r\n const label = this.popoverLabel();\r\n if (label) pane.setAttribute('aria-label', label);\r\n else pane.removeAttribute('aria-label');\r\n pane.classList.add('hy-glass', 'hy-popover');\r\n pane.dataset['material'] = this.fidelity.tier() === 'low' ? 'solid' : 'frosted';\r\n pane.addEventListener('focusout', this.onFocusOut);\r\n this.presence.enter(pane);\r\n\r\n const trap = this.focusTraps.create(pane);\r\n void trap.focusFirstTabbableElementWhenReady().then((found) => {\r\n if (!found) {\r\n pane.tabIndex = -1;\r\n pane.focus();\r\n }\r\n trap.destroy();\r\n });\r\n }\r\n\r\n private detach(): void {\r\n const ref = this.overlayRef;\r\n if (!ref?.hasAttached()) return;\r\n ref.overlayElement.removeEventListener('focusout', this.onFocusOut);\r\n this.presence.leave(ref.overlayElement, () => ref.detach());\r\n }\r\n\r\n private readonly onFocusOut = (event: FocusEvent): void => {\r\n const next = event.relatedTarget as Node | null;\r\n if (\r\n next &&\r\n !this.overlayRef?.overlayElement.contains(next) &&\r\n next !== this.host.nativeElement\r\n ) {\r\n this.close(false);\r\n }\r\n };\r\n}\r\n"],"mappings":"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"}