@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.
- package/CHANGELOG.md +41 -0
- package/LICENSE +21 -0
- package/README.md +32 -3
- package/fesm2022/hyalo-angular-accordion.mjs +230 -0
- package/fesm2022/hyalo-angular-accordion.mjs.map +1 -0
- package/fesm2022/hyalo-angular-button.mjs +203 -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-choice.mjs +788 -0
- package/fesm2022/hyalo-angular-choice.mjs.map +1 -0
- package/fesm2022/hyalo-angular-dialog.mjs +571 -0
- package/fesm2022/hyalo-angular-dialog.mjs.map +1 -0
- package/fesm2022/hyalo-angular-field.mjs +312 -0
- package/fesm2022/hyalo-angular-field.mjs.map +1 -0
- package/fesm2022/hyalo-angular-icon.mjs +343 -0
- package/fesm2022/hyalo-angular-icon.mjs.map +1 -0
- package/fesm2022/hyalo-angular-interaction.mjs +455 -0
- package/fesm2022/hyalo-angular-interaction.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-overlay.mjs +94 -0
- package/fesm2022/hyalo-angular-overlay.mjs.map +1 -0
- package/fesm2022/hyalo-angular-popover-overlay-kit-6wPwnxln.mjs +3 -0
- package/fesm2022/hyalo-angular-popover.mjs +487 -0
- package/fesm2022/hyalo-angular-popover.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 +464 -0
- package/fesm2022/hyalo-angular-select.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-toast.mjs +322 -0
- package/fesm2022/hyalo-angular-toast.mjs.map +1 -0
- package/fesm2022/hyalo-angular.mjs +473 -0
- package/fesm2022/hyalo-angular.mjs.map +1 -0
- package/package.json +133 -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 +36 -0
- package/styles/parts/glass.css +137 -0
- package/styles/parts/motion.css +82 -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 +64 -0
- package/types/hyalo-angular-accordion.d.ts +74 -0
- package/types/hyalo-angular-button.d.ts +88 -0
- package/types/hyalo-angular-card.d.ts +61 -0
- package/types/hyalo-angular-choice.d.ts +259 -0
- package/types/hyalo-angular-dialog.d.ts +170 -0
- package/types/hyalo-angular-field.d.ts +135 -0
- package/types/hyalo-angular-icon.d.ts +122 -0
- package/types/hyalo-angular-interaction.d.ts +131 -0
- package/types/hyalo-angular-navbar.d.ts +110 -0
- package/types/hyalo-angular-overlay.d.ts +31 -0
- package/types/hyalo-angular-popover.d.ts +142 -0
- package/types/hyalo-angular-segmented.d.ts +79 -0
- package/types/hyalo-angular-select.d.ts +130 -0
- package/types/hyalo-angular-tabs.d.ts +102 -0
- package/types/hyalo-angular-theme.d.ts +46 -0
- package/types/hyalo-angular-toast.d.ts +79 -0
- package/types/hyalo-angular.d.ts +345 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `@hyalo/angular` are listed here. The format follows [Keep a Changelog](https://keepachangelog.com), and versions follow [Semantic Versioning](https://semver.org). Until 1.0, a minor version can include breaking changes.
|
|
4
|
+
|
|
5
|
+
## 0.1.0 (unreleased)
|
|
6
|
+
|
|
7
|
+
The first release.
|
|
8
|
+
|
|
9
|
+
### Foundations (`@hyalo/angular`)
|
|
10
|
+
|
|
11
|
+
- `provideHyalo()` for global config, with the material, size and tone axes.
|
|
12
|
+
- `HyFidelity`, which steps the glass down on devices or settings where blur would hurt.
|
|
13
|
+
- `HyMotion` with motion presets, a spring helper and an optional, lazily loaded GSAP.
|
|
14
|
+
- The glass material directive and interaction state.
|
|
15
|
+
|
|
16
|
+
### Components
|
|
17
|
+
|
|
18
|
+
Each one is standalone and has its own entry point.
|
|
19
|
+
|
|
20
|
+
- `@hyalo/angular/accordion`: `hy-accordion` and `hy-accordion-item` on Angular Aria.
|
|
21
|
+
- `@hyalo/angular/button`: `hyButton` for buttons and link buttons, with an inline loading spinner.
|
|
22
|
+
- `@hyalo/angular/card`: `hy-card` with media, header, body and footer slots.
|
|
23
|
+
- `@hyalo/angular/choice`: `hy-checkbox`, `hy-radio-group` with `hy-radio`, and `hy-switch`.
|
|
24
|
+
- `@hyalo/angular/dialog`: the `HyDialog` and `HyDrawer` services, content parts, a confirm helper, side drawers and bottom sheets.
|
|
25
|
+
- `@hyalo/angular/field`: `hy-field` and `hyInput` for text fields, with Signal Forms support.
|
|
26
|
+
- `@hyalo/angular/icon`: `hy-icon` with a name registry and Lucide-compatible data.
|
|
27
|
+
- `@hyalo/angular/interaction`: reveal, tilt, magnetic and ripple directives.
|
|
28
|
+
- `@hyalo/angular/navbar`: `hy-navbar` with a collapsible menu and scroll behaviour.
|
|
29
|
+
- `@hyalo/angular/overlay`: logical placement helpers for CDK overlays.
|
|
30
|
+
- `@hyalo/angular/popover`: `hyTooltip` and `hyPopover`, loading the CDK overlay on first open.
|
|
31
|
+
- `@hyalo/angular/segmented`: `hy-segmented`.
|
|
32
|
+
- `@hyalo/angular/select`: `hy-select` on the Angular Aria combobox and listbox.
|
|
33
|
+
- `@hyalo/angular/tabs`: `hy-tabs` on Angular Aria.
|
|
34
|
+
- `@hyalo/angular/theme`: `HyPalette` for switching palettes at runtime.
|
|
35
|
+
- `@hyalo/angular/toast`: the `HyToaster` service with swipe to dismiss.
|
|
36
|
+
|
|
37
|
+
### Styles
|
|
38
|
+
|
|
39
|
+
- `styles/hyalo.css` with everything, or `styles/hyalo-core.css` plus one file per overlay from `styles/overlays/`.
|
|
40
|
+
- Design tokens, light and dark themes, and component tokens, all in cascade layers.
|
|
41
|
+
- Six on-demand palettes in `styles/palettes/`: aurora, ember, orchid, ocean, rose and graphite.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 HamedRsl
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,32 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="https://raw.githubusercontent.com/HamedRsl/Hyalo/main/.github/assets/hyalo-logo.jpg" alt="Hyalo, Angular UI kit" width="240" />
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
# @hyalo/angular
|
|
6
|
+
|
|
7
|
+
Liquid glass components for Angular, built on Angular Aria and the CDK. Signal based, zoneless, server-render safe, accessible, and ready for RTL.
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
npm install @hyalo/angular @angular/cdk @angular/aria
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Add the stylesheet before your own styles in `angular.json`:
|
|
14
|
+
|
|
15
|
+
```json
|
|
16
|
+
"styles": ["node_modules/@hyalo/angular/styles/hyalo.css", "src/styles.css"]
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
`hyalo.css` includes every overlay's styles. To leave out the ones you don't use, list `hyalo-core.css` plus the files you need from `styles/overlays/` (`select.css`, `popover.css`, `dialog.css`, `toast.css`) instead.
|
|
20
|
+
|
|
21
|
+
Then import the standalone components you need. Each one has its own entry point, so a lazy route only loads what it uses:
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
import { HyButton } from '@hyalo/angular/button';
|
|
25
|
+
import { HY_CARD } from '@hyalo/angular/card';
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
`@hyalo/angular` itself holds the shared foundations, such as `provideHyalo()`, `HyFidelity` and `HyMotion`.
|
|
29
|
+
|
|
30
|
+
Configuration, theming, RTL, motion and the full component list are in the [repository README](https://github.com/HamedRsl/Hyalo#readme).
|
|
31
|
+
|
|
32
|
+
MIT licensed.
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
import * as i0 from "@angular/core";
|
|
2
|
+
import { ChangeDetectionStrategy, Component, booleanAttribute, input, model, numberAttribute } from "@angular/core";
|
|
3
|
+
import * as i1 from "@angular/aria/accordion";
|
|
4
|
+
import { AccordionGroup, AccordionPanel, AccordionTrigger } from "@angular/aria/accordion";
|
|
5
|
+
import { HyIcon } from "@hyalo/angular/icon";
|
|
6
|
+
import * as i2 from "@hyalo/angular";
|
|
7
|
+
import { HyMaterialDirective } from "@hyalo/angular";
|
|
8
|
+
var HyAccordionItem = class HyAccordionItem {
|
|
9
|
+
heading = input("", ...ngDevMode ? [{ debugName: "heading" }] : /* istanbul ignore next */ []);
|
|
10
|
+
headingLevel = input(3, {
|
|
11
|
+
...ngDevMode ? { debugName: "headingLevel" } : /* istanbul ignore next */ {},
|
|
12
|
+
transform: numberAttribute
|
|
13
|
+
});
|
|
14
|
+
expanded = model(false, ...ngDevMode ? [{ debugName: "expanded" }] : /* istanbul ignore next */ []);
|
|
15
|
+
disabled = input(false, {
|
|
16
|
+
...ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {},
|
|
17
|
+
transform: booleanAttribute
|
|
18
|
+
});
|
|
19
|
+
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
20
|
+
minVersion: "12.0.0",
|
|
21
|
+
version: "22.2.3",
|
|
22
|
+
ngImport: i0,
|
|
23
|
+
type: HyAccordionItem,
|
|
24
|
+
deps: [],
|
|
25
|
+
target: i0.ɵɵFactoryTarget.Component
|
|
26
|
+
});
|
|
27
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({
|
|
28
|
+
minVersion: "17.1.0",
|
|
29
|
+
version: "22.2.3",
|
|
30
|
+
type: HyAccordionItem,
|
|
31
|
+
isStandalone: true,
|
|
32
|
+
selector: "hy-accordion-item",
|
|
33
|
+
inputs: {
|
|
34
|
+
heading: {
|
|
35
|
+
classPropertyName: "heading",
|
|
36
|
+
publicName: "heading",
|
|
37
|
+
isSignal: true,
|
|
38
|
+
isRequired: false,
|
|
39
|
+
transformFunction: null
|
|
40
|
+
},
|
|
41
|
+
headingLevel: {
|
|
42
|
+
classPropertyName: "headingLevel",
|
|
43
|
+
publicName: "headingLevel",
|
|
44
|
+
isSignal: true,
|
|
45
|
+
isRequired: false,
|
|
46
|
+
transformFunction: null
|
|
47
|
+
},
|
|
48
|
+
expanded: {
|
|
49
|
+
classPropertyName: "expanded",
|
|
50
|
+
publicName: "expanded",
|
|
51
|
+
isSignal: true,
|
|
52
|
+
isRequired: false,
|
|
53
|
+
transformFunction: null
|
|
54
|
+
},
|
|
55
|
+
disabled: {
|
|
56
|
+
classPropertyName: "disabled",
|
|
57
|
+
publicName: "disabled",
|
|
58
|
+
isSignal: true,
|
|
59
|
+
isRequired: false,
|
|
60
|
+
transformFunction: null
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
outputs: { expanded: "expandedChange" },
|
|
64
|
+
host: {
|
|
65
|
+
properties: { "attr.data-open": "expanded() || null" },
|
|
66
|
+
classAttribute: "hy-accordion-item"
|
|
67
|
+
},
|
|
68
|
+
ngImport: i0,
|
|
69
|
+
template: "<div class=\"hy-accordion__heading\" role=\"heading\" [attr.aria-level]=\"headingLevel()\">\r\n <button\r\n type=\"button\"\r\n class=\"hy-accordion__trigger\"\r\n ngAccordionTrigger\r\n [panel]=\"panel\"\r\n [(expanded)]=\"expanded\"\r\n [disabled]=\"disabled()\"\r\n >\r\n <span class=\"hy-accordion__label\">\r\n {{ heading() }}\r\n <ng-content select=\"[hyAccordionHeading]\" />\r\n </span>\r\n <hy-icon class=\"hy-accordion__chevron\" name=\"chevron-down\" />\r\n </button>\r\n</div>\r\n<div ngAccordionPanel #panel=\"ngAccordionPanel\" class=\"hy-accordion__panel\">\r\n <div class=\"hy-accordion__body\">\r\n <div class=\"hy-accordion__content\"><ng-content /></div>\r\n </div>\r\n</div>\r\n",
|
|
70
|
+
styles: [":host{display:block}:host+:host{border-block-start:1px solid var(--hy-accordion-divider, var(--hy-line))}.hy-accordion__heading{margin:0}.hy-accordion__trigger{display:flex;align-items:center;justify-content:space-between;gap:var(--hy-space-4);inline-size:100%;min-block-size:var(--hy-accordion-trigger-height, 3.5rem);padding:var(--hy-space-3) 0;border:0;background:transparent;color:var(--hy-ink);font:inherit;font-size:var(--hy-step-1);font-weight:580;text-align:start;cursor:pointer}.hy-accordion__trigger:focus-visible{outline:none;border-radius:var(--hy-radius-s);box-shadow:var(--hy-focus-ring)}.hy-accordion__trigger[aria-disabled=true]{opacity:.45;cursor:not-allowed}.hy-accordion__chevron{flex:none;color:var(--hy-ink-3);transition:rotate var(--hy-dur-settle) var(--hy-ease-out)}:host([data-open]) .hy-accordion__chevron{rotate:180deg}.hy-accordion__body{display:grid;grid-template-rows:0fr;transition:grid-template-rows var(--hy-dur-settle) var(--hy-ease-out)}:host([data-open]) .hy-accordion__body{grid-template-rows:1fr}.hy-accordion__content{min-block-size:0;overflow:hidden;color:var(--hy-ink-2)}:host([data-open]) .hy-accordion__content{padding-block-end:var(--hy-space-5)}.hy-accordion__panel[inert] .hy-accordion__content{visibility:hidden;transition:visibility 0s linear var(--hy-dur-settle)}@media print{.hy-accordion__body{grid-template-rows:1fr}.hy-accordion__panel[inert] .hy-accordion__content{visibility:visible}}\n"],
|
|
71
|
+
dependencies: [
|
|
72
|
+
{
|
|
73
|
+
kind: "directive",
|
|
74
|
+
type: AccordionTrigger,
|
|
75
|
+
selector: "[ngAccordionTrigger]",
|
|
76
|
+
inputs: [
|
|
77
|
+
"panel",
|
|
78
|
+
"id",
|
|
79
|
+
"disabled",
|
|
80
|
+
"expanded"
|
|
81
|
+
],
|
|
82
|
+
outputs: ["expandedChange"],
|
|
83
|
+
exportAs: ["ngAccordionTrigger"]
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
kind: "directive",
|
|
87
|
+
type: AccordionPanel,
|
|
88
|
+
selector: "[ngAccordionPanel]",
|
|
89
|
+
inputs: ["id"],
|
|
90
|
+
exportAs: ["ngAccordionPanel"]
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
kind: "component",
|
|
94
|
+
type: HyIcon,
|
|
95
|
+
selector: "hy-icon",
|
|
96
|
+
inputs: [
|
|
97
|
+
"name",
|
|
98
|
+
"icon",
|
|
99
|
+
"label",
|
|
100
|
+
"size",
|
|
101
|
+
"strokeWidth"
|
|
102
|
+
]
|
|
103
|
+
}
|
|
104
|
+
],
|
|
105
|
+
changeDetection: i0.ChangeDetectionStrategy.OnPush
|
|
106
|
+
});
|
|
107
|
+
};
|
|
108
|
+
i0.ɵɵngDeclareClassMetadata({
|
|
109
|
+
minVersion: "12.0.0",
|
|
110
|
+
version: "22.2.3",
|
|
111
|
+
ngImport: i0,
|
|
112
|
+
type: HyAccordionItem,
|
|
113
|
+
decorators: [{
|
|
114
|
+
type: Component,
|
|
115
|
+
args: [{
|
|
116
|
+
selector: "hy-accordion-item",
|
|
117
|
+
imports: [
|
|
118
|
+
AccordionTrigger,
|
|
119
|
+
AccordionPanel,
|
|
120
|
+
HyIcon
|
|
121
|
+
],
|
|
122
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
123
|
+
host: {
|
|
124
|
+
class: "hy-accordion-item",
|
|
125
|
+
"[attr.data-open]": "expanded() || null"
|
|
126
|
+
},
|
|
127
|
+
template: "<div class=\"hy-accordion__heading\" role=\"heading\" [attr.aria-level]=\"headingLevel()\">\r\n <button\r\n type=\"button\"\r\n class=\"hy-accordion__trigger\"\r\n ngAccordionTrigger\r\n [panel]=\"panel\"\r\n [(expanded)]=\"expanded\"\r\n [disabled]=\"disabled()\"\r\n >\r\n <span class=\"hy-accordion__label\">\r\n {{ heading() }}\r\n <ng-content select=\"[hyAccordionHeading]\" />\r\n </span>\r\n <hy-icon class=\"hy-accordion__chevron\" name=\"chevron-down\" />\r\n </button>\r\n</div>\r\n<div ngAccordionPanel #panel=\"ngAccordionPanel\" class=\"hy-accordion__panel\">\r\n <div class=\"hy-accordion__body\">\r\n <div class=\"hy-accordion__content\"><ng-content /></div>\r\n </div>\r\n</div>\r\n",
|
|
128
|
+
styles: [":host{display:block}:host+:host{border-block-start:1px solid var(--hy-accordion-divider, var(--hy-line))}.hy-accordion__heading{margin:0}.hy-accordion__trigger{display:flex;align-items:center;justify-content:space-between;gap:var(--hy-space-4);inline-size:100%;min-block-size:var(--hy-accordion-trigger-height, 3.5rem);padding:var(--hy-space-3) 0;border:0;background:transparent;color:var(--hy-ink);font:inherit;font-size:var(--hy-step-1);font-weight:580;text-align:start;cursor:pointer}.hy-accordion__trigger:focus-visible{outline:none;border-radius:var(--hy-radius-s);box-shadow:var(--hy-focus-ring)}.hy-accordion__trigger[aria-disabled=true]{opacity:.45;cursor:not-allowed}.hy-accordion__chevron{flex:none;color:var(--hy-ink-3);transition:rotate var(--hy-dur-settle) var(--hy-ease-out)}:host([data-open]) .hy-accordion__chevron{rotate:180deg}.hy-accordion__body{display:grid;grid-template-rows:0fr;transition:grid-template-rows var(--hy-dur-settle) var(--hy-ease-out)}:host([data-open]) .hy-accordion__body{grid-template-rows:1fr}.hy-accordion__content{min-block-size:0;overflow:hidden;color:var(--hy-ink-2)}:host([data-open]) .hy-accordion__content{padding-block-end:var(--hy-space-5)}.hy-accordion__panel[inert] .hy-accordion__content{visibility:hidden;transition:visibility 0s linear var(--hy-dur-settle)}@media print{.hy-accordion__body{grid-template-rows:1fr}.hy-accordion__panel[inert] .hy-accordion__content{visibility:visible}}\n"]
|
|
129
|
+
}]
|
|
130
|
+
}],
|
|
131
|
+
propDecorators: {
|
|
132
|
+
heading: [{
|
|
133
|
+
type: i0.Input,
|
|
134
|
+
args: [{
|
|
135
|
+
isSignal: true,
|
|
136
|
+
alias: "heading",
|
|
137
|
+
required: false
|
|
138
|
+
}]
|
|
139
|
+
}],
|
|
140
|
+
headingLevel: [{
|
|
141
|
+
type: i0.Input,
|
|
142
|
+
args: [{
|
|
143
|
+
isSignal: true,
|
|
144
|
+
alias: "headingLevel",
|
|
145
|
+
required: false
|
|
146
|
+
}]
|
|
147
|
+
}],
|
|
148
|
+
expanded: [{
|
|
149
|
+
type: i0.Input,
|
|
150
|
+
args: [{
|
|
151
|
+
isSignal: true,
|
|
152
|
+
alias: "expanded",
|
|
153
|
+
required: false
|
|
154
|
+
}]
|
|
155
|
+
}, {
|
|
156
|
+
type: i0.Output,
|
|
157
|
+
args: ["expandedChange"]
|
|
158
|
+
}],
|
|
159
|
+
disabled: [{
|
|
160
|
+
type: i0.Input,
|
|
161
|
+
args: [{
|
|
162
|
+
isSignal: true,
|
|
163
|
+
alias: "disabled",
|
|
164
|
+
required: false
|
|
165
|
+
}]
|
|
166
|
+
}]
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
var HyAccordion = class HyAccordion {
|
|
170
|
+
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
171
|
+
minVersion: "12.0.0",
|
|
172
|
+
version: "22.2.3",
|
|
173
|
+
ngImport: i0,
|
|
174
|
+
type: HyAccordion,
|
|
175
|
+
deps: [],
|
|
176
|
+
target: i0.ɵɵFactoryTarget.Component
|
|
177
|
+
});
|
|
178
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({
|
|
179
|
+
minVersion: "14.0.0",
|
|
180
|
+
version: "22.2.3",
|
|
181
|
+
type: HyAccordion,
|
|
182
|
+
isStandalone: true,
|
|
183
|
+
selector: "hy-accordion",
|
|
184
|
+
host: { classAttribute: "hy-accordion" },
|
|
185
|
+
hostDirectives: [{
|
|
186
|
+
directive: i1.AccordionGroup,
|
|
187
|
+
inputs: [
|
|
188
|
+
"multiExpandable",
|
|
189
|
+
"multiple",
|
|
190
|
+
"disabled",
|
|
191
|
+
"disabled"
|
|
192
|
+
]
|
|
193
|
+
}, {
|
|
194
|
+
directive: i2.HyMaterialDirective,
|
|
195
|
+
inputs: ["hyMaterial", "material"]
|
|
196
|
+
}],
|
|
197
|
+
ngImport: i0,
|
|
198
|
+
template: `<ng-content />`,
|
|
199
|
+
isInline: true,
|
|
200
|
+
styles: [":host{display:block;border-radius:var(--hy-radius-l);padding-inline:var(--hy-space-5)}\n"],
|
|
201
|
+
changeDetection: i0.ChangeDetectionStrategy.OnPush
|
|
202
|
+
});
|
|
203
|
+
};
|
|
204
|
+
i0.ɵɵngDeclareClassMetadata({
|
|
205
|
+
minVersion: "12.0.0",
|
|
206
|
+
version: "22.2.3",
|
|
207
|
+
ngImport: i0,
|
|
208
|
+
type: HyAccordion,
|
|
209
|
+
decorators: [{
|
|
210
|
+
type: Component,
|
|
211
|
+
args: [{
|
|
212
|
+
selector: "hy-accordion",
|
|
213
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
214
|
+
hostDirectives: [{
|
|
215
|
+
directive: AccordionGroup,
|
|
216
|
+
inputs: ["multiExpandable: multiple", "disabled"]
|
|
217
|
+
}, {
|
|
218
|
+
directive: HyMaterialDirective,
|
|
219
|
+
inputs: ["hyMaterial: material"]
|
|
220
|
+
}],
|
|
221
|
+
host: { class: "hy-accordion" },
|
|
222
|
+
template: `<ng-content />`,
|
|
223
|
+
styles: [":host{display:block;border-radius:var(--hy-radius-l);padding-inline:var(--hy-space-5)}\n"]
|
|
224
|
+
}]
|
|
225
|
+
}]
|
|
226
|
+
});
|
|
227
|
+
const HY_ACCORDION = [HyAccordion, HyAccordionItem];
|
|
228
|
+
export { HY_ACCORDION, HyAccordion, HyAccordionItem };
|
|
229
|
+
|
|
230
|
+
//# sourceMappingURL=hyalo-angular-accordion.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hyalo-angular-accordion.mjs","names":[],"sources":["../../../projects/hyalo/accordion/accordion.ts","../../../projects/hyalo/accordion/accordion-item.html"],"sourcesContent":["import {\r\n ChangeDetectionStrategy,\r\n Component,\r\n booleanAttribute,\r\n input,\r\n model,\r\n numberAttribute,\r\n} from '@angular/core';\r\nimport { AccordionGroup, AccordionPanel, AccordionTrigger } from '@angular/aria/accordion';\r\nimport { HyIcon } from '@hyalo/angular/icon';\r\n\r\nimport { HyMaterialDirective } from '@hyalo/angular';\r\n\r\n/**\r\n * One collapsible section. The panel content stays in the DOM while closed\r\n * (marked `inert`), so in-page search and FAQ structured data still see it.\r\n */\r\n@Component({\r\n selector: 'hy-accordion-item',\r\n imports: [AccordionTrigger, AccordionPanel, HyIcon],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n host: {\r\n class: 'hy-accordion-item',\r\n '[attr.data-open]': 'expanded() || null',\r\n },\r\n templateUrl: './accordion-item.html',\r\n styleUrl: './accordion.css',\r\n})\r\nexport class HyAccordionItem {\r\n /** Text of the header button. */\r\n readonly heading = input('');\r\n /** Heading level of the header, 2 to 6. Pick the one that fits the page outline. */\r\n readonly headingLevel = input(3, { transform: numberAttribute });\r\n /** Whether the section is open. Two-way bindable. */\r\n readonly expanded = model(false);\r\n readonly disabled = input(false, { transform: booleanAttribute });\r\n}\r\n\r\n/**\r\n * A stack of collapsible sections on Angular Aria. Arrow keys move between\r\n * headers, Home and End jump to the ends, Enter or Space toggles.\r\n *\r\n * ```html\r\n * <hy-accordion>\r\n * <hy-accordion-item heading=\"How long does delivery take?\">Three to five working days.</hy-accordion-item>\r\n * <hy-accordion-item heading=\"Can I return it?\">Within 30 days, free of charge.</hy-accordion-item>\r\n * </hy-accordion>\r\n * ```\r\n *\r\n * Only one section is open at a time unless `multiple` is set. Opening and\r\n * closing animate the height with CSS grid, which costs no layout script.\r\n */\r\n@Component({\r\n selector: 'hy-accordion',\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n hostDirectives: [\r\n { directive: AccordionGroup, inputs: ['multiExpandable: multiple', 'disabled'] },\r\n { directive: HyMaterialDirective, inputs: ['hyMaterial: material'] },\r\n ],\r\n host: { class: 'hy-accordion' },\r\n template: `<ng-content />`,\r\n styles: `\r\n :host {\r\n display: block;\r\n border-radius: var(--hy-radius-l);\r\n padding-inline: var(--hy-space-5);\r\n }\r\n `,\r\n})\r\nexport class HyAccordion {}\r\n\r\n/** Everything needed to build an accordion. */\r\nexport const HY_ACCORDION = [HyAccordion, HyAccordionItem] as const;\r\n","<div class=\"hy-accordion__heading\" role=\"heading\" [attr.aria-level]=\"headingLevel()\">\r\n <button\r\n type=\"button\"\r\n class=\"hy-accordion__trigger\"\r\n ngAccordionTrigger\r\n [panel]=\"panel\"\r\n [(expanded)]=\"expanded\"\r\n [disabled]=\"disabled()\"\r\n >\r\n <span class=\"hy-accordion__label\">\r\n {{ heading() }}\r\n <ng-content select=\"[hyAccordionHeading]\" />\r\n </span>\r\n <hy-icon class=\"hy-accordion__chevron\" name=\"chevron-down\" />\r\n </button>\r\n</div>\r\n<div ngAccordionPanel #panel=\"ngAccordionPanel\" class=\"hy-accordion__panel\">\r\n <div class=\"hy-accordion__body\">\r\n <div class=\"hy-accordion__content\"><ng-content /></div>\r\n </div>\r\n</div>\r\n"],"mappings":"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"}
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import * as i0 from "@angular/core";
|
|
2
|
+
import { ChangeDetectionStrategy, Component, ElementRef, booleanAttribute, computed, inject, input } from "@angular/core";
|
|
3
|
+
import * as i1 from "@hyalo/angular";
|
|
4
|
+
import { HY_CONFIG, HyFidelity, HyInteractive } from "@hyalo/angular";
|
|
5
|
+
var HyButton = class HyButton {
|
|
6
|
+
config = inject(HY_CONFIG);
|
|
7
|
+
fidelity = inject(HyFidelity);
|
|
8
|
+
el = inject(ElementRef).nativeElement;
|
|
9
|
+
isButton = this.el.tagName === "BUTTON";
|
|
10
|
+
variant = input("solid", ...ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []);
|
|
11
|
+
size = input(this.config.size, ...ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []);
|
|
12
|
+
tone = input(this.config.tone, ...ngDevMode ? [{ debugName: "tone" }] : /* istanbul ignore next */ []);
|
|
13
|
+
iconOnly = input(false, {
|
|
14
|
+
...ngDevMode ? { debugName: "iconOnly" } : /* istanbul ignore next */ {},
|
|
15
|
+
transform: booleanAttribute
|
|
16
|
+
});
|
|
17
|
+
loading = input(false, {
|
|
18
|
+
...ngDevMode ? { debugName: "loading" } : /* istanbul ignore next */ {},
|
|
19
|
+
transform: booleanAttribute
|
|
20
|
+
});
|
|
21
|
+
disabled = input(false, {
|
|
22
|
+
...ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {},
|
|
23
|
+
transform: booleanAttribute
|
|
24
|
+
});
|
|
25
|
+
material = computed(() => {
|
|
26
|
+
if (this.variant() !== "glass") return null;
|
|
27
|
+
return this.fidelity.tier() === "low" ? "solid" : this.config.material;
|
|
28
|
+
}, ...ngDevMode ? [{ debugName: "material" }] : /* istanbul ignore next */ []);
|
|
29
|
+
blocked = computed(() => this.loading() || !this.isButton && this.disabled(), ...ngDevMode ? [{ debugName: "blocked" }] : /* istanbul ignore next */ []);
|
|
30
|
+
constructor() {
|
|
31
|
+
this.el.addEventListener("click", (event) => {
|
|
32
|
+
if (!this.blocked()) return;
|
|
33
|
+
event.preventDefault();
|
|
34
|
+
event.stopImmediatePropagation();
|
|
35
|
+
}, { capture: true });
|
|
36
|
+
}
|
|
37
|
+
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
38
|
+
minVersion: "12.0.0",
|
|
39
|
+
version: "22.2.3",
|
|
40
|
+
ngImport: i0,
|
|
41
|
+
type: HyButton,
|
|
42
|
+
deps: [],
|
|
43
|
+
target: i0.ɵɵFactoryTarget.Component
|
|
44
|
+
});
|
|
45
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({
|
|
46
|
+
minVersion: "17.0.0",
|
|
47
|
+
version: "22.2.3",
|
|
48
|
+
type: HyButton,
|
|
49
|
+
isStandalone: true,
|
|
50
|
+
selector: "button[hyButton], a[hyButton]",
|
|
51
|
+
inputs: {
|
|
52
|
+
variant: {
|
|
53
|
+
classPropertyName: "variant",
|
|
54
|
+
publicName: "variant",
|
|
55
|
+
isSignal: true,
|
|
56
|
+
isRequired: false,
|
|
57
|
+
transformFunction: null
|
|
58
|
+
},
|
|
59
|
+
size: {
|
|
60
|
+
classPropertyName: "size",
|
|
61
|
+
publicName: "size",
|
|
62
|
+
isSignal: true,
|
|
63
|
+
isRequired: false,
|
|
64
|
+
transformFunction: null
|
|
65
|
+
},
|
|
66
|
+
tone: {
|
|
67
|
+
classPropertyName: "tone",
|
|
68
|
+
publicName: "tone",
|
|
69
|
+
isSignal: true,
|
|
70
|
+
isRequired: false,
|
|
71
|
+
transformFunction: null
|
|
72
|
+
},
|
|
73
|
+
iconOnly: {
|
|
74
|
+
classPropertyName: "iconOnly",
|
|
75
|
+
publicName: "iconOnly",
|
|
76
|
+
isSignal: true,
|
|
77
|
+
isRequired: false,
|
|
78
|
+
transformFunction: null
|
|
79
|
+
},
|
|
80
|
+
loading: {
|
|
81
|
+
classPropertyName: "loading",
|
|
82
|
+
publicName: "loading",
|
|
83
|
+
isSignal: true,
|
|
84
|
+
isRequired: false,
|
|
85
|
+
transformFunction: null
|
|
86
|
+
},
|
|
87
|
+
disabled: {
|
|
88
|
+
classPropertyName: "disabled",
|
|
89
|
+
publicName: "disabled",
|
|
90
|
+
isSignal: true,
|
|
91
|
+
isRequired: false,
|
|
92
|
+
transformFunction: null
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
host: {
|
|
96
|
+
properties: {
|
|
97
|
+
"class.hy-glass": "variant() === \"glass\"",
|
|
98
|
+
"attr.data-material": "material()",
|
|
99
|
+
"attr.data-thickness": "variant() === \"glass\" ? \"thin\" : null",
|
|
100
|
+
"attr.data-variant": "variant()",
|
|
101
|
+
"attr.data-size": "size()",
|
|
102
|
+
"attr.data-tone": "tone()",
|
|
103
|
+
"attr.data-icon-only": "iconOnly() || null",
|
|
104
|
+
"attr.data-loading": "loading() || null",
|
|
105
|
+
"attr.aria-busy": "loading() || null",
|
|
106
|
+
"attr.aria-disabled": "blocked() || null",
|
|
107
|
+
"attr.disabled": "isButton && disabled() ? \"\" : null",
|
|
108
|
+
"attr.tabindex": "!isButton && disabled() ? -1 : null"
|
|
109
|
+
},
|
|
110
|
+
classAttribute: "hy-button"
|
|
111
|
+
},
|
|
112
|
+
hostDirectives: [{ directive: i1.HyInteractive }],
|
|
113
|
+
ngImport: i0,
|
|
114
|
+
template: "<span class=\"hy-button__label\"><ng-content /></span>\r\n@if (loading()) {\r\n <!-- Inline, so a button does not pull in the icon registry. -->\r\n <span class=\"hy-button__spinner\" aria-hidden=\"true\">\r\n <svg viewBox=\"0 0 24 24\"><path d=\"M21 12a9 9 0 1 1-6.219-8.56\" /></svg>\r\n </span>\r\n}\r\n",
|
|
115
|
+
styles: [":host{--_c: var(--hy-primary);--_on: var(--hy-primary-ink);--_h: var(--hy-control-md);--_px: var(--hy-space-4);position:relative;display:inline-flex;align-items:center;justify-content:center;gap:var(--hy-space-2);block-size:var(--_h);min-inline-size:var(--_h);padding-inline:var(--_px);border:1px solid transparent;border-radius:var(--hy-button-radius, var(--hy-radius-pill));font:inherit;font-size:var(--hy-step-0);font-weight:var(--hy-button-font-weight, 560);line-height:1;white-space:nowrap;text-decoration:none;cursor:pointer;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;transition:background-color var(--hy-dur-quick) var(--hy-ease-out),color var(--hy-dur-quick) var(--hy-ease-out),box-shadow var(--hy-dur-quick) var(--hy-ease-out),scale var(--hy-dur-quick) var(--hy-ease-out),translate var(--hy-dur-settle) var(--hy-ease-out),--hy-glow var(--hy-dur-settle) var(--hy-ease-out)}:host([data-size=\"sm\"]){--_h: var(--hy-control-sm);--_px: var(--hy-space-3);font-size:var(--hy-step--1);letter-spacing:var(--hy-tracking-small)}:host([data-size=\"lg\"]){--_h: var(--hy-control-lg);--_px: var(--hy-space-6);font-size:var(--hy-step-1)}:host([data-icon-only]){padding-inline:0;inline-size:var(--_h)}:host([data-tone=\"secondary\"]){--_c: var(--hy-secondary, var(--hy-primary));--_on: var(--hy-secondary-ink, var(--hy-primary-ink))}:host([data-tone=\"neutral\"]){--_c: var(--hy-ink);--_on: var(--hy-bg)}:host([data-tone=\"danger\"]){--_c: var(--hy-danger);--_on: var(--hy-danger-ink)}:host([data-tone=\"success\"]){--_c: var(--hy-success);--_on: var(--hy-bg)}:host([data-tone=\"warning\"]){--_c: var(--hy-warning);--_on: var(--hy-bg)}:host([data-variant=\"solid\"]){background-color:var(--_c);color:var(--_on);box-shadow:inset 0 1px #ffffff38,0 6px 16px -8px color-mix(in srgb,var(--_c) 70%,transparent)}:host([data-variant=\"solid\"][data-hover]){background-color:color-mix(in srgb,var(--_c) 88%,var(--hy-ink))}:host([data-variant=\"glass\"]){color:var(--hy-ink)}:host([data-variant=\"glass\"][data-hover]){--hy-glow: .25}:host([data-variant=\"soft\"]){background-color:color-mix(in srgb,var(--_c) 13%,transparent);color:var(--_c)}:host([data-variant=\"soft\"][data-hover]){background-color:color-mix(in srgb,var(--_c) 20%,transparent)}:host([data-variant=\"ghost\"]){background-color:transparent;color:var(--_c)}:host([data-variant=\"ghost\"][data-hover]){background-color:color-mix(in srgb,var(--_c) 10%,transparent)}:host([data-press]){scale:.97;transition-duration:min(.1s,var(--hy-dur-quick))}:host([data-variant=\"solid\"][data-press]){background-color:color-mix(in srgb,var(--_c) 78%,var(--hy-ink))}:host([data-variant=\"soft\"][data-press]){background-color:color-mix(in srgb,var(--_c) 26%,transparent)}:host([data-variant=\"ghost\"][data-press]){background-color:color-mix(in srgb,var(--_c) 16%,transparent)}:host([data-variant=\"glass\"][data-press]){--hy-glow: .45}:host(:focus-visible){outline:none;box-shadow:var(--hy-focus-ring)}:host(:disabled),:host([aria-disabled=\"true\"]:not([data-loading])){opacity:.45;cursor:not-allowed;pointer-events:none}:host([data-loading]){cursor:progress}.hy-button__label{display:inline-flex;align-items:center;gap:inherit}:host([data-loading]) .hy-button__label{visibility:hidden}.hy-button__spinner{position:absolute;inset:0;display:grid;place-items:center}.hy-button__spinner svg{inline-size:1.25em;block-size:1.25em;fill:none;stroke:currentColor;stroke-width:1.75;stroke-linecap:round;animation:hy-spin .8s linear infinite}@keyframes hy-spin{to{rotate:1turn}}@media(prefers-reduced-motion:reduce){.hy-button__spinner svg{animation-duration:2.4s}}@media(forced-colors:active){:host{border-color:ButtonText}}\n"],
|
|
116
|
+
changeDetection: i0.ChangeDetectionStrategy.OnPush
|
|
117
|
+
});
|
|
118
|
+
};
|
|
119
|
+
i0.ɵɵngDeclareClassMetadata({
|
|
120
|
+
minVersion: "12.0.0",
|
|
121
|
+
version: "22.2.3",
|
|
122
|
+
ngImport: i0,
|
|
123
|
+
type: HyButton,
|
|
124
|
+
decorators: [{
|
|
125
|
+
type: Component,
|
|
126
|
+
args: [{
|
|
127
|
+
selector: "button[hyButton], a[hyButton]",
|
|
128
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
129
|
+
hostDirectives: [HyInteractive],
|
|
130
|
+
host: {
|
|
131
|
+
class: "hy-button",
|
|
132
|
+
"[class.hy-glass]": "variant() === \"glass\"",
|
|
133
|
+
"[attr.data-material]": "material()",
|
|
134
|
+
"[attr.data-thickness]": "variant() === \"glass\" ? \"thin\" : null",
|
|
135
|
+
"[attr.data-variant]": "variant()",
|
|
136
|
+
"[attr.data-size]": "size()",
|
|
137
|
+
"[attr.data-tone]": "tone()",
|
|
138
|
+
"[attr.data-icon-only]": "iconOnly() || null",
|
|
139
|
+
"[attr.data-loading]": "loading() || null",
|
|
140
|
+
"[attr.aria-busy]": "loading() || null",
|
|
141
|
+
"[attr.aria-disabled]": "blocked() || null",
|
|
142
|
+
"[attr.disabled]": "isButton && disabled() ? \"\" : null",
|
|
143
|
+
"[attr.tabindex]": "!isButton && disabled() ? -1 : null"
|
|
144
|
+
},
|
|
145
|
+
template: "<span class=\"hy-button__label\"><ng-content /></span>\r\n@if (loading()) {\r\n <!-- Inline, so a button does not pull in the icon registry. -->\r\n <span class=\"hy-button__spinner\" aria-hidden=\"true\">\r\n <svg viewBox=\"0 0 24 24\"><path d=\"M21 12a9 9 0 1 1-6.219-8.56\" /></svg>\r\n </span>\r\n}\r\n",
|
|
146
|
+
styles: [":host{--_c: var(--hy-primary);--_on: var(--hy-primary-ink);--_h: var(--hy-control-md);--_px: var(--hy-space-4);position:relative;display:inline-flex;align-items:center;justify-content:center;gap:var(--hy-space-2);block-size:var(--_h);min-inline-size:var(--_h);padding-inline:var(--_px);border:1px solid transparent;border-radius:var(--hy-button-radius, var(--hy-radius-pill));font:inherit;font-size:var(--hy-step-0);font-weight:var(--hy-button-font-weight, 560);line-height:1;white-space:nowrap;text-decoration:none;cursor:pointer;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;transition:background-color var(--hy-dur-quick) var(--hy-ease-out),color var(--hy-dur-quick) var(--hy-ease-out),box-shadow var(--hy-dur-quick) var(--hy-ease-out),scale var(--hy-dur-quick) var(--hy-ease-out),translate var(--hy-dur-settle) var(--hy-ease-out),--hy-glow var(--hy-dur-settle) var(--hy-ease-out)}:host([data-size=\"sm\"]){--_h: var(--hy-control-sm);--_px: var(--hy-space-3);font-size:var(--hy-step--1);letter-spacing:var(--hy-tracking-small)}:host([data-size=\"lg\"]){--_h: var(--hy-control-lg);--_px: var(--hy-space-6);font-size:var(--hy-step-1)}:host([data-icon-only]){padding-inline:0;inline-size:var(--_h)}:host([data-tone=\"secondary\"]){--_c: var(--hy-secondary, var(--hy-primary));--_on: var(--hy-secondary-ink, var(--hy-primary-ink))}:host([data-tone=\"neutral\"]){--_c: var(--hy-ink);--_on: var(--hy-bg)}:host([data-tone=\"danger\"]){--_c: var(--hy-danger);--_on: var(--hy-danger-ink)}:host([data-tone=\"success\"]){--_c: var(--hy-success);--_on: var(--hy-bg)}:host([data-tone=\"warning\"]){--_c: var(--hy-warning);--_on: var(--hy-bg)}:host([data-variant=\"solid\"]){background-color:var(--_c);color:var(--_on);box-shadow:inset 0 1px #ffffff38,0 6px 16px -8px color-mix(in srgb,var(--_c) 70%,transparent)}:host([data-variant=\"solid\"][data-hover]){background-color:color-mix(in srgb,var(--_c) 88%,var(--hy-ink))}:host([data-variant=\"glass\"]){color:var(--hy-ink)}:host([data-variant=\"glass\"][data-hover]){--hy-glow: .25}:host([data-variant=\"soft\"]){background-color:color-mix(in srgb,var(--_c) 13%,transparent);color:var(--_c)}:host([data-variant=\"soft\"][data-hover]){background-color:color-mix(in srgb,var(--_c) 20%,transparent)}:host([data-variant=\"ghost\"]){background-color:transparent;color:var(--_c)}:host([data-variant=\"ghost\"][data-hover]){background-color:color-mix(in srgb,var(--_c) 10%,transparent)}:host([data-press]){scale:.97;transition-duration:min(.1s,var(--hy-dur-quick))}:host([data-variant=\"solid\"][data-press]){background-color:color-mix(in srgb,var(--_c) 78%,var(--hy-ink))}:host([data-variant=\"soft\"][data-press]){background-color:color-mix(in srgb,var(--_c) 26%,transparent)}:host([data-variant=\"ghost\"][data-press]){background-color:color-mix(in srgb,var(--_c) 16%,transparent)}:host([data-variant=\"glass\"][data-press]){--hy-glow: .45}:host(:focus-visible){outline:none;box-shadow:var(--hy-focus-ring)}:host(:disabled),:host([aria-disabled=\"true\"]:not([data-loading])){opacity:.45;cursor:not-allowed;pointer-events:none}:host([data-loading]){cursor:progress}.hy-button__label{display:inline-flex;align-items:center;gap:inherit}:host([data-loading]) .hy-button__label{visibility:hidden}.hy-button__spinner{position:absolute;inset:0;display:grid;place-items:center}.hy-button__spinner svg{inline-size:1.25em;block-size:1.25em;fill:none;stroke:currentColor;stroke-width:1.75;stroke-linecap:round;animation:hy-spin .8s linear infinite}@keyframes hy-spin{to{rotate:1turn}}@media(prefers-reduced-motion:reduce){.hy-button__spinner svg{animation-duration:2.4s}}@media(forced-colors:active){:host{border-color:ButtonText}}\n"]
|
|
147
|
+
}]
|
|
148
|
+
}],
|
|
149
|
+
ctorParameters: () => [],
|
|
150
|
+
propDecorators: {
|
|
151
|
+
variant: [{
|
|
152
|
+
type: i0.Input,
|
|
153
|
+
args: [{
|
|
154
|
+
isSignal: true,
|
|
155
|
+
alias: "variant",
|
|
156
|
+
required: false
|
|
157
|
+
}]
|
|
158
|
+
}],
|
|
159
|
+
size: [{
|
|
160
|
+
type: i0.Input,
|
|
161
|
+
args: [{
|
|
162
|
+
isSignal: true,
|
|
163
|
+
alias: "size",
|
|
164
|
+
required: false
|
|
165
|
+
}]
|
|
166
|
+
}],
|
|
167
|
+
tone: [{
|
|
168
|
+
type: i0.Input,
|
|
169
|
+
args: [{
|
|
170
|
+
isSignal: true,
|
|
171
|
+
alias: "tone",
|
|
172
|
+
required: false
|
|
173
|
+
}]
|
|
174
|
+
}],
|
|
175
|
+
iconOnly: [{
|
|
176
|
+
type: i0.Input,
|
|
177
|
+
args: [{
|
|
178
|
+
isSignal: true,
|
|
179
|
+
alias: "iconOnly",
|
|
180
|
+
required: false
|
|
181
|
+
}]
|
|
182
|
+
}],
|
|
183
|
+
loading: [{
|
|
184
|
+
type: i0.Input,
|
|
185
|
+
args: [{
|
|
186
|
+
isSignal: true,
|
|
187
|
+
alias: "loading",
|
|
188
|
+
required: false
|
|
189
|
+
}]
|
|
190
|
+
}],
|
|
191
|
+
disabled: [{
|
|
192
|
+
type: i0.Input,
|
|
193
|
+
args: [{
|
|
194
|
+
isSignal: true,
|
|
195
|
+
alias: "disabled",
|
|
196
|
+
required: false
|
|
197
|
+
}]
|
|
198
|
+
}]
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
export { HyButton };
|
|
202
|
+
|
|
203
|
+
//# sourceMappingURL=hyalo-angular-button.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hyalo-angular-button.mjs","names":[],"sources":["../../../projects/hyalo/button/button.ts","../../../projects/hyalo/button/button.html"],"sourcesContent":["import {\r\n ChangeDetectionStrategy,\r\n Component,\r\n ElementRef,\r\n booleanAttribute,\r\n computed,\r\n inject,\r\n input,\r\n} from '@angular/core';\r\nimport { HY_CONFIG, HyFidelity, HyInteractive, type HySize, type HyTone } from '@hyalo/angular';\r\n\r\n/**\r\n * - `solid`: filled with the tone colour. The main action on a view.\r\n * - `glass`: a glass surface with tone-coloured text.\r\n * - `soft`: a light wash of the tone colour.\r\n * - `ghost`: text only, a surface appears on hover.\r\n */\r\nexport type HyButtonVariant = 'solid' | 'glass' | 'soft' | 'ghost';\r\n\r\n/**\r\n * Button and link button.\r\n *\r\n * ```html\r\n * <button hyButton (click)=\"save()\">Save</button>\r\n * <a hyButton variant=\"glass\" routerLink=\"/pricing\">Pricing</a>\r\n * <button hyButton iconOnly aria-label=\"Close\"><hy-icon name=\"x\" /></button>\r\n * ```\r\n *\r\n * It stays a native `<button>` or `<a>`, so forms, routing and keyboard\r\n * behaviour work as usual. A press dims and shrinks it the moment the\r\n * pointer goes down. Add `hyMagnetic` for the magnetic hover effect, or\r\n * `hyRipple` for a press ripple.\r\n *\r\n * While `loading`, the button keeps its focus and width, sets `aria-busy`\r\n * and ignores clicks. A disabled link gets `aria-disabled` and leaves the\r\n * tab order, since links have no native disabled state.\r\n */\r\n@Component({\r\n // Attribute selector so the host stays a native <button> or <a>.\r\n // eslint-disable-next-line @angular-eslint/component-selector\r\n selector: 'button[hyButton], a[hyButton]',\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n hostDirectives: [HyInteractive],\r\n host: {\r\n class: 'hy-button',\r\n '[class.hy-glass]': 'variant() === \"glass\"',\r\n '[attr.data-material]': 'material()',\r\n // Buttons are small chips of glass, so they get the thinnest material.\r\n '[attr.data-thickness]': 'variant() === \"glass\" ? \"thin\" : null',\r\n '[attr.data-variant]': 'variant()',\r\n '[attr.data-size]': 'size()',\r\n '[attr.data-tone]': 'tone()',\r\n '[attr.data-icon-only]': 'iconOnly() || null',\r\n '[attr.data-loading]': 'loading() || null',\r\n '[attr.aria-busy]': 'loading() || null',\r\n '[attr.aria-disabled]': 'blocked() || null',\r\n '[attr.disabled]': 'isButton && disabled() ? \"\" : null',\r\n '[attr.tabindex]': '!isButton && disabled() ? -1 : null',\r\n },\r\n templateUrl: './button.html',\r\n styleUrl: './button.css',\r\n})\r\nexport class HyButton {\r\n private readonly config = inject(HY_CONFIG);\r\n private readonly fidelity = inject(HyFidelity);\r\n private readonly el = inject<ElementRef<HTMLElement>>(ElementRef).nativeElement;\r\n protected readonly isButton = this.el.tagName === 'BUTTON';\r\n\r\n /** Visual style. */\r\n readonly variant = input<HyButtonVariant>('solid');\r\n /** Height and padding. Defaults to the configured size. */\r\n readonly size = input<HySize>(this.config.size);\r\n /** Colour role. Defaults to the configured tone. */\r\n readonly tone = input<HyTone>(this.config.tone);\r\n /** Square button for a single icon. Give it an `aria-label`. */\r\n readonly iconOnly = input(false, { transform: booleanAttribute });\r\n /** Shows a spinner and blocks clicks without dropping focus. */\r\n readonly loading = input(false, { transform: booleanAttribute });\r\n /** Disables the button. On links this sets `aria-disabled`. */\r\n readonly disabled = input(false, { transform: booleanAttribute });\r\n\r\n /** Glass follows the configured material and goes solid on the low tier. */\r\n protected readonly material = computed(() => {\r\n if (this.variant() !== 'glass') return null;\r\n return this.fidelity.tier() === 'low' ? 'solid' : this.config.material;\r\n });\r\n\r\n /** True when clicks should be ignored. */\r\n protected readonly blocked = computed(\r\n () => this.loading() || (!this.isButton && this.disabled()),\r\n );\r\n\r\n constructor() {\r\n // A capture listener on the element runs before the app's own (click)\r\n // handlers, so a blocked click never reaches them.\r\n this.el.addEventListener(\r\n 'click',\r\n (event) => {\r\n if (!this.blocked()) return;\r\n event.preventDefault();\r\n event.stopImmediatePropagation();\r\n },\r\n { capture: true },\r\n );\r\n }\r\n}\r\n","<span class=\"hy-button__label\"><ng-content /></span>\r\n@if (loading()) {\r\n <!-- Inline, so a button does not pull in the icon registry. -->\r\n <span class=\"hy-button__spinner\" aria-hidden=\"true\">\r\n <svg viewBox=\"0 0 24 24\"><path d=\"M21 12a9 9 0 1 1-6.219-8.56\" /></svg>\r\n </span>\r\n}\r\n"],"mappings":"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"}
|