@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,131 @@
1
+ import * as i0 from "@angular/core";
2
+ /** Where a revealed element comes from. */
3
+ export type HyRevealFrom = 'up' | 'fade' | 'scale';
4
+ /**
5
+ * Fades and lifts an element in when it scrolls into view.
6
+ *
7
+ * ```html
8
+ * @for (item of items; track item.id; let i = $index) {
9
+ * <article hyReveal [revealDelay]="i * 60">...</article>
10
+ * }
11
+ * ```
12
+ *
13
+ * Content is never hidden by default. The directive only hides an element
14
+ * after hydration, only when it is below the fold, and only when motion is
15
+ * enabled. Elements already on screen are left alone, so server-rendered
16
+ * content does not flash. CSS transitions do the work, so it also runs on the
17
+ * low tier when reduced motion is off.
18
+ *
19
+ * Put it on the glass element itself (`<hy-card hyReveal>`), not on a
20
+ * wrapper around glass. While a wrapper fades, its glass children cannot
21
+ * blur what is behind it, and the blur snaps in when the fade ends.
22
+ */
23
+ export declare class HyReveal {
24
+ private readonly el;
25
+ private readonly motion;
26
+ /** Delay in milliseconds, for staggering. */
27
+ readonly revealDelay: import("@angular/core").InputSignalWithTransform<number, unknown>;
28
+ /** The starting pose. */
29
+ readonly revealFrom: import("@angular/core").InputSignal<HyRevealFrom>;
30
+ /** Reveal again each time the element re-enters the viewport. */
31
+ readonly revealRepeat: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
32
+ constructor();
33
+ static ɵfac: i0.ɵɵFactoryDeclaration<HyReveal, never>;
34
+ static ɵdir: i0.ɵɵDirectiveDeclaration<HyReveal, "[hyReveal]", never, {
35
+ "revealDelay": {
36
+ "alias": "revealDelay";
37
+ "required": false;
38
+ "isSignal": true;
39
+ };
40
+ "revealFrom": {
41
+ "alias": "revealFrom";
42
+ "required": false;
43
+ "isSignal": true;
44
+ };
45
+ "revealRepeat": {
46
+ "alias": "revealRepeat";
47
+ "required": false;
48
+ "isSignal": true;
49
+ };
50
+ }, {}, never, never, true, never>;
51
+ }
52
+ /**
53
+ * Tilts the element toward the cursor and moves a soft glow under it.
54
+ *
55
+ * ```html
56
+ * <hy-card hyTilt [tiltMax]="8">...</hy-card>
57
+ * ```
58
+ *
59
+ * Runs only with a fine pointer, with motion enabled and above the low
60
+ * fidelity tier. The glow uses `--hy-px`, `--hy-py` and `--hy-glow`, which the
61
+ * glass material already reads.
62
+ */
63
+ export declare class HyTilt {
64
+ private readonly el;
65
+ private readonly motion;
66
+ /** Maximum rotation in degrees. */
67
+ readonly tiltMax: import("@angular/core").InputSignalWithTransform<number, unknown>;
68
+ /** Whether to show the pointer glow. */
69
+ readonly tiltGlow: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
70
+ constructor();
71
+ static ɵfac: i0.ɵɵFactoryDeclaration<HyTilt, never>;
72
+ static ɵdir: i0.ɵɵDirectiveDeclaration<HyTilt, "[hyTilt]", never, {
73
+ "tiltMax": {
74
+ "alias": "tiltMax";
75
+ "required": false;
76
+ "isSignal": true;
77
+ };
78
+ "tiltGlow": {
79
+ "alias": "tiltGlow";
80
+ "required": false;
81
+ "isSignal": true;
82
+ };
83
+ }, {}, never, never, true, never>;
84
+ }
85
+ /**
86
+ * Pulls the element a little toward the cursor while it hovers.
87
+ *
88
+ * Uses the `translate` property, so it never fights with a `transform` the
89
+ * element already has.
90
+ */
91
+ export declare class HyMagnetic {
92
+ private readonly el;
93
+ private readonly motion;
94
+ /** How far the element follows the cursor, as a share of the distance. */
95
+ readonly magneticStrength: import("@angular/core").InputSignalWithTransform<number, unknown>;
96
+ /** Upper limit for the offset in pixels. */
97
+ readonly magneticMax: import("@angular/core").InputSignalWithTransform<number, unknown>;
98
+ constructor();
99
+ static ɵfac: i0.ɵɵFactoryDeclaration<HyMagnetic, never>;
100
+ static ɵdir: i0.ɵɵDirectiveDeclaration<HyMagnetic, "[hyMagnetic]", never, {
101
+ "magneticStrength": {
102
+ "alias": "magneticStrength";
103
+ "required": false;
104
+ "isSignal": true;
105
+ };
106
+ "magneticMax": {
107
+ "alias": "magneticMax";
108
+ "required": false;
109
+ "isSignal": true;
110
+ };
111
+ }, {}, never, never, true, never>;
112
+ }
113
+ /**
114
+ * A soft light ripple from the press point. Purely decorative: it is
115
+ * skipped with reduced motion and never affects layout.
116
+ */
117
+ export declare class HyRipple {
118
+ private readonly el;
119
+ private readonly motion;
120
+ /** Turns the ripple off without removing the directive. */
121
+ readonly rippleDisabled: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
122
+ constructor();
123
+ static ɵfac: i0.ɵɵFactoryDeclaration<HyRipple, never>;
124
+ static ɵdir: i0.ɵɵDirectiveDeclaration<HyRipple, "[hyRipple]", never, {
125
+ "rippleDisabled": {
126
+ "alias": "rippleDisabled";
127
+ "required": false;
128
+ "isSignal": true;
129
+ };
130
+ }, {}, never, never, true, never>;
131
+ }
@@ -0,0 +1,110 @@
1
+ import * as i0 from "@angular/core";
2
+ /** The logo or product name, at the start of the bar. */
3
+ export declare class HyNavbarBrand {
4
+ static ɵfac: i0.ɵɵFactoryDeclaration<HyNavbarBrand, never>;
5
+ static ɵdir: i0.ɵɵDirectiveDeclaration<HyNavbarBrand, "[hyNavbarBrand]", never, {}, {}, never, never, true, never>;
6
+ }
7
+ /** Buttons at the end of the bar, such as sign in or a cart. Always visible. */
8
+ export declare class HyNavbarActions {
9
+ static ɵfac: i0.ɵɵFactoryDeclaration<HyNavbarActions, never>;
10
+ static ɵdir: i0.ɵɵDirectiveDeclaration<HyNavbarActions, "[hyNavbarActions]", never, {}, {}, never, never, true, never>;
11
+ }
12
+ /**
13
+ * - `floating`: a detached glass pill with space around it.
14
+ * - `full`: a full-width bar. Once content scrolls under it, a soft fade
15
+ * at its lower edge separates the two instead of a hard line.
16
+ */
17
+ export type HyNavbarAppearance = 'floating' | 'full';
18
+ /**
19
+ * A glass app bar. Links go in the default slot and are wrapped in a
20
+ * `<nav>`. On narrow screens they collapse behind a menu button and open as
21
+ * a panel under the bar. Bind `menuOpen` if you would rather open your own
22
+ * drawer.
23
+ *
24
+ * ```html
25
+ * <hy-navbar label="Main">
26
+ * <a hyNavbarBrand routerLink="/">Atelier</a>
27
+ * <a routerLink="/watches" routerLinkActive="active" ariaCurrentWhenActive="page">Watches</a>
28
+ * <a routerLink="/journal">Journal</a>
29
+ * <div hyNavbarActions><button hyButton size="sm">Book a visit</button></div>
30
+ * </hy-navbar>
31
+ * ```
32
+ *
33
+ * The bar compacts once the page scrolls, and with `hideOnScroll` it slides
34
+ * away while scrolling down and returns on the way up. It never hides while
35
+ * the menu is open or focus is inside it. The collapse point is a container
36
+ * query on the navbar's own width (48rem by default).
37
+ */
38
+ export declare class HyNavbar {
39
+ private readonly toggle;
40
+ protected readonly linksId: string;
41
+ /** Accessible name of the `<nav>` landmark. */
42
+ readonly label: import("@angular/core").InputSignal<string>;
43
+ /** Accessible name of the menu button on narrow screens. */
44
+ readonly menuLabel: import("@angular/core").InputSignal<string>;
45
+ /** Visual style of the bar. */
46
+ readonly appearance: import("@angular/core").InputSignal<HyNavbarAppearance>;
47
+ /** CSS positioning of the navbar. */
48
+ readonly position: import("@angular/core").InputSignal<"sticky" | "fixed" | "static">;
49
+ /** Material of the bar. */
50
+ readonly material: import("@angular/core").InputSignal<"" | "clear" | "frosted" | "tinted" | "solid">;
51
+ /** Slide away while scrolling down. */
52
+ readonly hideOnScroll: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
53
+ /** Scroll distance in pixels after which the bar compacts. */
54
+ readonly scrollThreshold: import("@angular/core").InputSignalWithTransform<number, unknown>;
55
+ /** Whether the collapsed menu is open. Two-way bindable. */
56
+ readonly menuOpen: import("@angular/core").ModelSignal<boolean>;
57
+ protected readonly scrolled: import("@angular/core").WritableSignal<boolean>;
58
+ protected readonly hidden: import("@angular/core").WritableSignal<boolean>;
59
+ constructor();
60
+ /** Closes the collapsed menu. */
61
+ closeMenu(restoreFocus?: boolean): void;
62
+ protected onClick(event: MouseEvent): void;
63
+ static ɵfac: i0.ɵɵFactoryDeclaration<HyNavbar, never>;
64
+ static ɵcmp: i0.ɵɵComponentDeclaration<HyNavbar, "hy-navbar", never, {
65
+ "label": {
66
+ "alias": "label";
67
+ "required": false;
68
+ "isSignal": true;
69
+ };
70
+ "menuLabel": {
71
+ "alias": "menuLabel";
72
+ "required": false;
73
+ "isSignal": true;
74
+ };
75
+ "appearance": {
76
+ "alias": "appearance";
77
+ "required": false;
78
+ "isSignal": true;
79
+ };
80
+ "position": {
81
+ "alias": "position";
82
+ "required": false;
83
+ "isSignal": true;
84
+ };
85
+ "material": {
86
+ "alias": "material";
87
+ "required": false;
88
+ "isSignal": true;
89
+ };
90
+ "hideOnScroll": {
91
+ "alias": "hideOnScroll";
92
+ "required": false;
93
+ "isSignal": true;
94
+ };
95
+ "scrollThreshold": {
96
+ "alias": "scrollThreshold";
97
+ "required": false;
98
+ "isSignal": true;
99
+ };
100
+ "menuOpen": {
101
+ "alias": "menuOpen";
102
+ "required": false;
103
+ "isSignal": true;
104
+ };
105
+ }, {
106
+ "menuOpen": "menuOpenChange";
107
+ }, never, ["[hyNavbarBrand]", "*", "[hyNavbarActions]"], true, never>;
108
+ }
109
+ /** Everything needed to build a navbar. */
110
+ export declare const HY_NAVBAR: readonly [typeof HyNavbar, typeof HyNavbarBrand, typeof HyNavbarActions];
@@ -0,0 +1,31 @@
1
+ import { ConnectedPosition } from "@angular/cdk/overlay";
2
+ /**
3
+ * Where a floating element sits relative to its trigger. `start` and `end`
4
+ * follow the text direction, so `end` is on the right in LTR and on the left
5
+ * in RTL.
6
+ */
7
+ export type HyPlacement = 'top' | 'bottom' | 'start' | 'end';
8
+ /**
9
+ * CDK positions for a placement, with the opposite side as the first
10
+ * fallback when there is no room.
11
+ */
12
+ export declare function hyConnectedPositions(placement: HyPlacement, offset?: number): ConnectedPosition[];
13
+ /** Positions for a dropdown that lines up with the trigger's start edge. */
14
+ export declare function hyDropdownPositions(offset?: number): ConnectedPosition[];
15
+ /**
16
+ * @internal Enter and exit for small overlays (tooltips, popovers, select
17
+ * panels), driven by `data-state` and CSS transitions.
18
+ *
19
+ * Transitions start from the current value, so reopening a panel while it
20
+ * is still fading out simply turns it around, with no jump.
21
+ */
22
+ declare class HyPresence {
23
+ private cancel;
24
+ /** True while an exit is playing. */
25
+ get leaving(): boolean;
26
+ /** Shows a panel that was just attached, or turns a leaving one around. */
27
+ enter(el: HTMLElement): void;
28
+ /** Plays the exit, then calls `done`, unless `enter` turns it around first. */
29
+ leave(el: HTMLElement, done: () => void): void;
30
+ }
31
+ export { HyPresence as ɵHyPresence };
@@ -0,0 +1,142 @@
1
+ import { HyPlacement } from "@hyalo/angular/overlay";
2
+ import * as i0 from "@angular/core";
3
+ import { TemplateRef } from "@angular/core";
4
+ export declare class HyTooltipPanel {
5
+ readonly message: import("@angular/core").WritableSignal<string>;
6
+ static ɵfac: i0.ɵɵFactoryDeclaration<HyTooltipPanel, never>;
7
+ static ɵcmp: i0.ɵɵComponentDeclaration<HyTooltipPanel, "hy-tooltip-panel", never, {}, {}, never, never, true, never>;
8
+ }
9
+ /**
10
+ * A short text hint on hover or keyboard focus.
11
+ *
12
+ * ```html
13
+ * <button hyButton iconOnly aria-label="Copy link" hyTooltip="Copy link">...</button>
14
+ * ```
15
+ *
16
+ * The text is also added to the trigger's `aria-describedby` through a
17
+ * hidden element, so screen readers get it without the visual tooltip. The
18
+ * tooltip stays open while the pointer is over it and closes on Escape, as
19
+ * WCAG 1.4.13 asks. Keep it short and never put interactive content in it;
20
+ * use `hyPopover` for that.
21
+ */
22
+ export declare class HyTooltip {
23
+ private readonly injector;
24
+ private readonly host;
25
+ private readonly describer;
26
+ private overlayRef;
27
+ private position;
28
+ private panel;
29
+ private panelEl;
30
+ private readonly presence;
31
+ private showTimer;
32
+ private hideTimer;
33
+ /** True from show() until hide(), so a late overlay load knows to stop. */
34
+ private wanted;
35
+ private destroyed;
36
+ /** The tooltip text. */
37
+ readonly message: import("@angular/core").InputSignal<string>;
38
+ /** Preferred side. Flips when there is no room. */
39
+ readonly tooltipPlacement: import("@angular/core").InputSignal<HyPlacement>;
40
+ /** Hover delay in milliseconds. Focus shows it right away. */
41
+ readonly tooltipDelay: import("@angular/core").InputSignalWithTransform<number, unknown>;
42
+ readonly tooltipDisabled: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
43
+ constructor();
44
+ protected onPointerEnter(event: PointerEvent): void;
45
+ /** Shows the tooltip after the given delay. */
46
+ show(delay?: number): void;
47
+ /** Starts hiding the tooltip now. It fades out quickly. */
48
+ hide(): void;
49
+ protected scheduleHide(): void;
50
+ private attach;
51
+ static ɵfac: i0.ɵɵFactoryDeclaration<HyTooltip, never>;
52
+ static ɵdir: i0.ɵɵDirectiveDeclaration<HyTooltip, "[hyTooltip]", never, {
53
+ "message": {
54
+ "alias": "hyTooltip";
55
+ "required": false;
56
+ "isSignal": true;
57
+ };
58
+ "tooltipPlacement": {
59
+ "alias": "tooltipPlacement";
60
+ "required": false;
61
+ "isSignal": true;
62
+ };
63
+ "tooltipDelay": {
64
+ "alias": "tooltipDelay";
65
+ "required": false;
66
+ "isSignal": true;
67
+ };
68
+ "tooltipDisabled": {
69
+ "alias": "tooltipDisabled";
70
+ "required": false;
71
+ "isSignal": true;
72
+ };
73
+ }, {}, never, never, true, never>;
74
+ }
75
+ /**
76
+ * A non-modal glass panel anchored to a trigger, for content that does not
77
+ * fit in a tooltip: a short form, a menu of links, details.
78
+ *
79
+ * ```html
80
+ * <button hyButton variant="glass" [hyPopover]="share" popoverLabel="Share">Share</button>
81
+ * <ng-template #share>
82
+ * <a href="...">Copy link</a>
83
+ * </ng-template>
84
+ * ```
85
+ *
86
+ * Click or Enter toggles it. On open, focus moves to the first focusable
87
+ * element inside. Escape closes it and returns focus to the trigger, and so
88
+ * does clicking outside or tabbing out of it.
89
+ */
90
+ export declare class HyPopover {
91
+ private readonly injector;
92
+ private readonly host;
93
+ private readonly viewContainer;
94
+ private readonly focusTraps;
95
+ private readonly fidelity;
96
+ protected readonly panelId: string;
97
+ private overlayRef;
98
+ private position;
99
+ private readonly presence;
100
+ private destroyed;
101
+ /** The content. */
102
+ readonly content: import("@angular/core").InputSignal<TemplateRef<unknown>>;
103
+ /** Accessible name of the panel. */
104
+ readonly popoverLabel: import("@angular/core").InputSignal<string | undefined>;
105
+ /** Preferred side. Flips when there is no room. */
106
+ readonly popoverPlacement: import("@angular/core").InputSignal<HyPlacement>;
107
+ /** Whether the panel is open. Two-way bindable as `[(popoverOpen)]`. */
108
+ readonly open: import("@angular/core").ModelSignal<boolean>;
109
+ constructor();
110
+ toggle(): void;
111
+ /** Closes the panel, optionally moving focus back to the trigger. */
112
+ close(restoreFocus?: boolean): void;
113
+ protected preload(): void;
114
+ private attach;
115
+ private detach;
116
+ private readonly onFocusOut;
117
+ static ɵfac: i0.ɵɵFactoryDeclaration<HyPopover, never>;
118
+ static ɵdir: i0.ɵɵDirectiveDeclaration<HyPopover, "[hyPopover]", ["hyPopover"], {
119
+ "content": {
120
+ "alias": "hyPopover";
121
+ "required": true;
122
+ "isSignal": true;
123
+ };
124
+ "popoverLabel": {
125
+ "alias": "popoverLabel";
126
+ "required": false;
127
+ "isSignal": true;
128
+ };
129
+ "popoverPlacement": {
130
+ "alias": "popoverPlacement";
131
+ "required": false;
132
+ "isSignal": true;
133
+ };
134
+ "open": {
135
+ "alias": "popoverOpen";
136
+ "required": false;
137
+ "isSignal": true;
138
+ };
139
+ }, {
140
+ "open": "popoverOpenChange";
141
+ }, never, never, true, never>;
142
+ }
@@ -0,0 +1,79 @@
1
+ import { FormValueControl } from "@angular/forms/signals";
2
+ import { HySize } from "@hyalo/angular";
3
+ import * as i0 from "@angular/core";
4
+ /** One choice in a segmented control. */
5
+ export interface HySegmentedOption<T> {
6
+ readonly value: T;
7
+ readonly label: string;
8
+ readonly icon?: string;
9
+ readonly disabled?: boolean;
10
+ }
11
+ /**
12
+ * A segmented control: a small set of mutually exclusive choices with the
13
+ * same sliding indicator as tabs. Use it to pick a value (billing period, a
14
+ * view mode). Use tabs when each choice shows a different panel.
15
+ *
16
+ * It is a group of native radio buttons, so arrow keys, form submission and
17
+ * screen readers behave as users expect. Works with Signal Forms through
18
+ * `[formField]`, or with `[(value)]`.
19
+ *
20
+ * ```html
21
+ * <hy-segmented label="Billing" [options]="periods" [(value)]="period" />
22
+ * ```
23
+ */
24
+ export declare class HySegmented<T> implements FormValueControl<T | undefined> {
25
+ protected readonly groupName: string;
26
+ private readonly row;
27
+ private readonly items;
28
+ /** The choices. */
29
+ readonly options: import("@angular/core").InputSignal<readonly HySegmentedOption<T>[]>;
30
+ /** Selected value. Two-way bindable. */
31
+ readonly value: import("@angular/core").ModelSignal<T | undefined>;
32
+ /** Accessible name of the group. */
33
+ readonly label: import("@angular/core").InputSignal<string | undefined>;
34
+ /** Name shared by the radio inputs. Generated when not set. */
35
+ readonly name: import("@angular/core").InputSignal<string>;
36
+ /** Disables every option. */
37
+ readonly disabled: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
38
+ /** Control size. */
39
+ readonly size: import("@angular/core").InputSignal<HySize>;
40
+ /** Emits when focus leaves an option, so forms can mark the field touched. */
41
+ readonly touch: import("@angular/core").OutputEmitterRef<void>;
42
+ protected readonly ready: import("@angular/core").Signal<boolean>;
43
+ static ɵfac: i0.ɵɵFactoryDeclaration<HySegmented<any>, never>;
44
+ static ɵcmp: i0.ɵɵComponentDeclaration<HySegmented<any>, "hy-segmented", never, {
45
+ "options": {
46
+ "alias": "options";
47
+ "required": true;
48
+ "isSignal": true;
49
+ };
50
+ "value": {
51
+ "alias": "value";
52
+ "required": false;
53
+ "isSignal": true;
54
+ };
55
+ "label": {
56
+ "alias": "label";
57
+ "required": false;
58
+ "isSignal": true;
59
+ };
60
+ "name": {
61
+ "alias": "name";
62
+ "required": false;
63
+ "isSignal": true;
64
+ };
65
+ "disabled": {
66
+ "alias": "disabled";
67
+ "required": false;
68
+ "isSignal": true;
69
+ };
70
+ "size": {
71
+ "alias": "size";
72
+ "required": false;
73
+ "isSignal": true;
74
+ };
75
+ }, {
76
+ "value": "valueChange";
77
+ "touch": "touch";
78
+ }, never, never, true, never>;
79
+ }
@@ -0,0 +1,130 @@
1
+ import { FormValueControl } from "@angular/forms/signals";
2
+ import { HyFieldControl } from "@hyalo/angular/field";
3
+ import * as i0 from "@angular/core";
4
+ /** One choice in a select. */
5
+ export interface HySelectOption<T> {
6
+ readonly value: T;
7
+ readonly label: string;
8
+ readonly disabled?: boolean;
9
+ }
10
+ /**
11
+ * A single-choice select with a glass dropdown, built on Angular Aria's
12
+ * combobox and listbox patterns.
13
+ *
14
+ * ```html
15
+ * <hy-field label="Strap">
16
+ * <hy-select [options]="straps" [formField]="form.strap" placeholder="Choose a strap" />
17
+ * </hy-field>
18
+ * ```
19
+ *
20
+ * Focus stays on the trigger while the list is open, and options are
21
+ * announced through `aria-activedescendant`. Arrow keys move, Enter or
22
+ * Space picks, Escape closes, and typing jumps to a matching option.
23
+ *
24
+ * On the low fidelity tier, or with `native`, it renders a real `<select>`
25
+ * instead. That gives the platform picker on phones and costs nothing.
26
+ */
27
+ export declare class HySelect<T> implements FormValueControl<T | undefined>, HyFieldControl {
28
+ private readonly fidelity;
29
+ protected readonly field: import("@hyalo/angular/field").HyFieldContext | null;
30
+ private readonly trigger;
31
+ private readonly overlay;
32
+ private readonly presence;
33
+ /** The choices. */
34
+ readonly options: import("@angular/core").InputSignal<readonly HySelectOption<T>[]>;
35
+ /** Selected value. Two-way bindable and works with `[formField]`. */
36
+ readonly value: import("@angular/core").ModelSignal<T | undefined>;
37
+ /** Text shown while nothing is selected. */
38
+ readonly placeholder: import("@angular/core").InputSignal<string>;
39
+ /** Disables the select. Set automatically by Signal Forms. */
40
+ readonly disabled: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
41
+ /** Marks the field as required. Set automatically by Signal Forms. */
42
+ readonly required: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
43
+ /** Set by Signal Forms. */
44
+ readonly invalid: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
45
+ /** Set by Signal Forms. Only the first message is shown. */
46
+ readonly errors: import("@angular/core").InputSignal<readonly {
47
+ readonly kind: string;
48
+ readonly message?: string;
49
+ }[]>;
50
+ /** Set by Signal Forms. Errors show only after the field is touched. */
51
+ readonly touched: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
52
+ /** Always render a native `<select>`. */
53
+ readonly native: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
54
+ /** Emits when the control loses focus, so forms can mark it touched. */
55
+ readonly touch: import("@angular/core").OutputEmitterRef<void>;
56
+ readonly labelable = true;
57
+ readonly id: import("@angular/core").Signal<string>;
58
+ readonly errorMessage: import("@angular/core").Signal<string | undefined>;
59
+ protected readonly expanded: import("@angular/core").WritableSignal<boolean>;
60
+ /** Stays true while the panel fades out after `expanded` turns false. */
61
+ protected readonly rendered: import("@angular/core").WritableSignal<boolean>;
62
+ protected readonly positions: import("@angular/cdk/overlay").ConnectedPosition[];
63
+ protected readonly panelWidth: import("@angular/core").WritableSignal<number>;
64
+ protected readonly useNative: import("@angular/core").Signal<boolean>;
65
+ protected readonly selectedOption: import("@angular/core").Signal<HySelectOption<T> | undefined>;
66
+ protected readonly listValue: import("@angular/core").Signal<(T & ({} | null))[]>;
67
+ protected readonly showsError: import("@angular/core").Signal<boolean>;
68
+ constructor();
69
+ protected setExpanded(open: boolean): void;
70
+ /** Runs when the overlay attaches a fresh panel. */
71
+ protected onAttach(): void;
72
+ private panelElement;
73
+ protected pick(values: readonly T[]): void;
74
+ /** Closes after a click on an option, including the one already selected. */
75
+ protected onPanelClick(event: MouseEvent): void;
76
+ protected close(): void;
77
+ protected pickNative(event: Event): void;
78
+ protected indexOf(value: T | undefined): number;
79
+ static ɵfac: i0.ɵɵFactoryDeclaration<HySelect<any>, never>;
80
+ static ɵcmp: i0.ɵɵComponentDeclaration<HySelect<any>, "hy-select", never, {
81
+ "options": {
82
+ "alias": "options";
83
+ "required": true;
84
+ "isSignal": true;
85
+ };
86
+ "value": {
87
+ "alias": "value";
88
+ "required": false;
89
+ "isSignal": true;
90
+ };
91
+ "placeholder": {
92
+ "alias": "placeholder";
93
+ "required": false;
94
+ "isSignal": true;
95
+ };
96
+ "disabled": {
97
+ "alias": "disabled";
98
+ "required": false;
99
+ "isSignal": true;
100
+ };
101
+ "required": {
102
+ "alias": "required";
103
+ "required": false;
104
+ "isSignal": true;
105
+ };
106
+ "invalid": {
107
+ "alias": "invalid";
108
+ "required": false;
109
+ "isSignal": true;
110
+ };
111
+ "errors": {
112
+ "alias": "errors";
113
+ "required": false;
114
+ "isSignal": true;
115
+ };
116
+ "touched": {
117
+ "alias": "touched";
118
+ "required": false;
119
+ "isSignal": true;
120
+ };
121
+ "native": {
122
+ "alias": "native";
123
+ "required": false;
124
+ "isSignal": true;
125
+ };
126
+ }, {
127
+ "value": "valueChange";
128
+ "touch": "touch";
129
+ }, never, never, true, never>;
130
+ }