@eagami/ui 5.29.0 → 5.30.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -0
- package/fesm2022/eagami-ui-testing.mjs +42 -0
- package/fesm2022/eagami-ui-testing.mjs.map +1 -0
- package/fesm2022/eagami-ui.mjs +35 -16
- package/fesm2022/eagami-ui.mjs.map +1 -1
- package/package.json +6 -1
- package/testing/package.json +4 -0
- package/types/eagami-ui-testing.d.ts +10 -0
- package/types/eagami-ui.d.ts +16 -2
package/README.md
CHANGED
|
@@ -126,6 +126,17 @@ Every component adheres to WCAG 2.2 Level AA and follows the matching [WAI-ARIA
|
|
|
126
126
|
|
|
127
127
|
The library is SSR-safe and renders on the server (Angular Universal / `@angular/ssr`) without reaching for `window` or `document`. Browser-only work (focus management, the native `<dialog>`, overlay positioning, resize/intersection observers) is deferred to the client via `afterNextRender` and `isPlatformBrowser` guards, so prerendering, streaming SSR, and hydration work with no extra configuration.
|
|
128
128
|
|
|
129
|
+
## Testing
|
|
130
|
+
|
|
131
|
+
jsdom implements `<dialog>` without `showModal()` or `close()`, so a unit test that creates a component holding an open `<ea-dialog>` or `<ea-drawer>` throws before the spec body runs. The `@eagami/ui/testing` entry point ships a shim that fills in the missing methods; it patches only what the runtime lacks, so it is a no-op in real browsers. Call it once from your test setup file:
|
|
132
|
+
|
|
133
|
+
```ts
|
|
134
|
+
// test-setup.ts
|
|
135
|
+
import { installNativeDialogShim } from '@eagami/ui/testing';
|
|
136
|
+
|
|
137
|
+
installNativeDialogShim();
|
|
138
|
+
```
|
|
139
|
+
|
|
129
140
|
## Framework integration
|
|
130
141
|
|
|
131
142
|
`@eagami/ui` is Angular-only, but its design tokens are framework-agnostic. Self-contained copy-and-paste guides and a machine-readable token export are published with the docs and kept in sync with the token source on every release:
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fills in the native `<dialog>` methods jsdom leaves unimplemented, so a spec
|
|
3
|
+
* can create a component that opens an `ea-dialog` or `ea-drawer` without the
|
|
4
|
+
* test runner throwing on `showModal()` or `close()`. Call once from the test
|
|
5
|
+
* setup file. Only missing methods are patched, so a runtime that implements
|
|
6
|
+
* the element keeps its own behavior.
|
|
7
|
+
*/
|
|
8
|
+
function installNativeDialogShim() {
|
|
9
|
+
if (typeof HTMLDialogElement === 'undefined') {
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
const proto = HTMLDialogElement.prototype;
|
|
13
|
+
if (typeof proto.show !== 'function') {
|
|
14
|
+
proto.show = function () {
|
|
15
|
+
this.open = true;
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
if (typeof proto.showModal !== 'function') {
|
|
19
|
+
proto.showModal = function () {
|
|
20
|
+
this.open = true;
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
if (typeof proto.close !== 'function') {
|
|
24
|
+
proto.close = function (returnValue) {
|
|
25
|
+
if (!this.open) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
if (returnValue !== undefined) {
|
|
29
|
+
this.returnValue = returnValue;
|
|
30
|
+
}
|
|
31
|
+
this.open = false;
|
|
32
|
+
this.dispatchEvent(new Event('close'));
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Generated bundle index. Do not edit.
|
|
39
|
+
*/
|
|
40
|
+
|
|
41
|
+
export { installNativeDialogShim };
|
|
42
|
+
//# sourceMappingURL=eagami-ui-testing.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eagami-ui-testing.mjs","sources":["../../../testing/src/native-dialog.ts","../../../testing/src/eagami-ui-testing.ts"],"sourcesContent":["/**\n * Fills in the native `<dialog>` methods jsdom leaves unimplemented, so a spec\n * can create a component that opens an `ea-dialog` or `ea-drawer` without the\n * test runner throwing on `showModal()` or `close()`. Call once from the test\n * setup file. Only missing methods are patched, so a runtime that implements\n * the element keeps its own behavior.\n */\nexport function installNativeDialogShim(): void {\n if (typeof HTMLDialogElement === 'undefined') {\n return;\n }\n const proto = HTMLDialogElement.prototype;\n if (typeof proto.show !== 'function') {\n proto.show = function (this: HTMLDialogElement): void {\n this.open = true;\n };\n }\n if (typeof proto.showModal !== 'function') {\n proto.showModal = function (this: HTMLDialogElement): void {\n this.open = true;\n };\n }\n if (typeof proto.close !== 'function') {\n proto.close = function (this: HTMLDialogElement, returnValue?: string): void {\n if (!this.open) {\n return;\n }\n if (returnValue !== undefined) {\n this.returnValue = returnValue;\n }\n this.open = false;\n this.dispatchEvent(new Event('close'));\n };\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"AAAA;;;;;;AAMG;SACa,uBAAuB,GAAA;AACrC,IAAA,IAAI,OAAO,iBAAiB,KAAK,WAAW,EAAE;QAC5C;IACF;AACA,IAAA,MAAM,KAAK,GAAG,iBAAiB,CAAC,SAAS;AACzC,IAAA,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,UAAU,EAAE;QACpC,KAAK,CAAC,IAAI,GAAG,YAAA;AACX,YAAA,IAAI,CAAC,IAAI,GAAG,IAAI;AAClB,QAAA,CAAC;IACH;AACA,IAAA,IAAI,OAAO,KAAK,CAAC,SAAS,KAAK,UAAU,EAAE;QACzC,KAAK,CAAC,SAAS,GAAG,YAAA;AAChB,YAAA,IAAI,CAAC,IAAI,GAAG,IAAI;AAClB,QAAA,CAAC;IACH;AACA,IAAA,IAAI,OAAO,KAAK,CAAC,KAAK,KAAK,UAAU,EAAE;AACrC,QAAA,KAAK,CAAC,KAAK,GAAG,UAAmC,WAAoB,EAAA;AACnE,YAAA,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;gBACd;YACF;AACA,YAAA,IAAI,WAAW,KAAK,SAAS,EAAE;AAC7B,gBAAA,IAAI,CAAC,WAAW,GAAG,WAAW;YAChC;AACA,YAAA,IAAI,CAAC,IAAI,GAAG,KAAK;YACjB,IAAI,CAAC,aAAa,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;AACxC,QAAA,CAAC;IACH;AACF;;AClCA;;AAEG;;;;"}
|
package/fesm2022/eagami-ui.mjs
CHANGED
|
@@ -4767,6 +4767,12 @@ class PopoverComponent {
|
|
|
4767
4767
|
this.latched = null;
|
|
4768
4768
|
return;
|
|
4769
4769
|
}
|
|
4770
|
+
// The closed state's `display: none` is still on the element: this
|
|
4771
|
+
// effect runs before the binding carrying `surfaceStyle()` reaches it.
|
|
4772
|
+
// `showPopover()` refuses an element with no layout box, and a refused
|
|
4773
|
+
// promotion leaves the surface portaled to `<body>`, outside the modal
|
|
4774
|
+
// and therefore inert, so it is cleared here rather than a frame later.
|
|
4775
|
+
surface.style.removeProperty('display');
|
|
4770
4776
|
// Join the top layer before the first measurement below, so a popover
|
|
4771
4777
|
// opened from inside a modal is not painted behind it. Promoting first
|
|
4772
4778
|
// also gives the surface layout: a `popover` element is `display: none`
|
|
@@ -5954,19 +5960,18 @@ class TooltipDirective {
|
|
|
5954
5960
|
return;
|
|
5955
5961
|
}
|
|
5956
5962
|
const style = getComputedStyle(this.tooltipEl);
|
|
5957
|
-
|
|
5958
|
-
|
|
5963
|
+
/* Whatever the border box holds beyond its content box: padding, borders,
|
|
5964
|
+
and a scrollbar if the height clamp put one there. Summed from the
|
|
5965
|
+
fractional longhands, since WebKit resolves computed `width` to the
|
|
5966
|
+
border box under `box-sizing: border-box`. Only the scrollbar goes
|
|
5967
|
+
through the whole-pixel `offsetWidth - clientWidth`. */
|
|
5968
|
+
const paddings = parseFloat(style.paddingLeft) + parseFloat(style.paddingRight);
|
|
5969
|
+
const borders = parseFloat(style.borderLeftWidth) + parseFloat(style.borderRightWidth);
|
|
5970
|
+
const scrollbar = Math.max(0, this.tooltipEl.offsetWidth - this.tooltipEl.clientWidth - borders);
|
|
5971
|
+
const horizontalChrome = style.boxSizing === 'border-box' ? paddings + borders + scrollbar : scrollbar;
|
|
5972
|
+
if (!Number.isFinite(horizontalChrome)) {
|
|
5959
5973
|
return;
|
|
5960
5974
|
}
|
|
5961
|
-
/* Whatever the border box holds beyond its content box: padding, borders,
|
|
5962
|
-
and a scrollbar if the height clamp put one there. Read as the difference
|
|
5963
|
-
between two fractional widths; `offsetWidth` and `clientWidth` round to
|
|
5964
|
-
whole pixels, and under a page zoom the box sits on fractional ones, so
|
|
5965
|
-
rounded arithmetic pins the bubble a hair narrower than its own text and
|
|
5966
|
-
the last word drops to a second line inside a box sized for one. */
|
|
5967
|
-
const horizontalChrome = style.boxSizing === 'border-box'
|
|
5968
|
-
? this.tooltipEl.getBoundingClientRect().width - contentWidth
|
|
5969
|
-
: 0;
|
|
5970
5975
|
this.renderer.setStyle(this.tooltipEl, 'width', `${Math.ceil(textWidth + horizontalChrome)}px`);
|
|
5971
5976
|
}
|
|
5972
5977
|
/* A scrollable bubble has to be reachable, so leaving the trigger only
|
|
@@ -10713,6 +10718,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImpor
|
|
|
10713
10718
|
* for browser-managed focus trapping, supports backdrop and Escape dismissal,
|
|
10714
10719
|
* and exposes `header`, default, and `footer` content slots. The `open` state
|
|
10715
10720
|
* is a two-way `model()` binding.
|
|
10721
|
+
*
|
|
10722
|
+
* The header is a row that lays its slot content out against the built-in
|
|
10723
|
+
* close button, and it applies the h4 type scale to that content, so a heading
|
|
10724
|
+
* element projected into it should carry `font: inherit`. Panel chrome is
|
|
10725
|
+
* tunable per dialog via `--ea-dialog-inset`, `--ea-dialog-radius`,
|
|
10726
|
+
* `--ea-dialog-max-height`, `--ea-dialog-header-padding`,
|
|
10727
|
+
* `--ea-dialog-body-padding`, and `--ea-dialog-status-padding`; an
|
|
10728
|
+
* edge-to-edge media surface zeroes the inset, radius, and paddings.
|
|
10729
|
+
*
|
|
10730
|
+
* Specs running under jsdom need `installNativeDialogShim()` from
|
|
10731
|
+
* `@eagami/ui/testing` before opening one.
|
|
10716
10732
|
*/
|
|
10717
10733
|
class DialogComponent {
|
|
10718
10734
|
dialogEl = viewChild('dialogEl', /* @ts-ignore */
|
|
@@ -10832,11 +10848,11 @@ class DialogComponent {
|
|
|
10832
10848
|
this.handleClose();
|
|
10833
10849
|
}
|
|
10834
10850
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: DialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
10835
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.2", type: DialogComponent, isStandalone: true, selector: "ea-dialog", inputs: { width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, closeOnBackdrop: { classPropertyName: "closeOnBackdrop", publicName: "closeOnBackdrop", isSignal: true, isRequired: false, transformFunction: null }, closeOnEscape: { classPropertyName: "closeOnEscape", publicName: "closeOnEscape", isSignal: true, isRequired: false, transformFunction: null }, showClose: { classPropertyName: "showClose", publicName: "showClose", isSignal: true, isRequired: false, transformFunction: null }, closeDisabled: { classPropertyName: "closeDisabled", publicName: "closeDisabled", isSignal: true, isRequired: false, transformFunction: null }, manualClose: { classPropertyName: "manualClose", publicName: "manualClose", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "aria-label", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { open: "openChange", opened: "opened", closed: "closed", closeRequested: "closeRequested" }, viewQueries: [{ propertyName: "dialogEl", first: true, predicate: ["dialogEl"], descendants: true, isSignal: true }, { propertyName: "headerEl", first: true, predicate: ["headerEl"], descendants: true, isSignal: true }], ngImport: i0, template: "<dialog\n #dialogEl\n class=\"ea-dialog\"\n [id]=\"id()\"\n [attr.aria-label]=\"ariaLabel() ?? null\"\n [attr.aria-labelledby]=\"!ariaLabel() && hasHeader() ? id() + '-header' : null\"\n (click)=\"handleBackdropClick($event)\"\n (cancel)=\"handleCancel($event)\">\n <div\n class=\"ea-dialog__panel\"\n [ngClass]=\"panelClasses()\">\n @if (showClose()) {\n
|
|
10851
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.2", type: DialogComponent, isStandalone: true, selector: "ea-dialog", inputs: { width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, closeOnBackdrop: { classPropertyName: "closeOnBackdrop", publicName: "closeOnBackdrop", isSignal: true, isRequired: false, transformFunction: null }, closeOnEscape: { classPropertyName: "closeOnEscape", publicName: "closeOnEscape", isSignal: true, isRequired: false, transformFunction: null }, showClose: { classPropertyName: "showClose", publicName: "showClose", isSignal: true, isRequired: false, transformFunction: null }, closeDisabled: { classPropertyName: "closeDisabled", publicName: "closeDisabled", isSignal: true, isRequired: false, transformFunction: null }, manualClose: { classPropertyName: "manualClose", publicName: "manualClose", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "aria-label", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { open: "openChange", opened: "opened", closed: "closed", closeRequested: "closeRequested" }, viewQueries: [{ propertyName: "dialogEl", first: true, predicate: ["dialogEl"], descendants: true, isSignal: true }, { propertyName: "headerEl", first: true, predicate: ["headerEl"], descendants: true, isSignal: true }], ngImport: i0, template: "<dialog\n #dialogEl\n class=\"ea-dialog\"\n [id]=\"id()\"\n [attr.aria-label]=\"ariaLabel() ?? null\"\n [attr.aria-labelledby]=\"!ariaLabel() && hasHeader() ? id() + '-header' : null\"\n (click)=\"handleBackdropClick($event)\"\n (cancel)=\"handleCancel($event)\">\n <div\n class=\"ea-dialog__panel\"\n [ngClass]=\"panelClasses()\">\n <div\n class=\"ea-dialog__header\"\n [class.ea-dialog__header--hidden]=\"!hasHeader() && !showClose()\">\n <div\n #headerEl\n class=\"ea-dialog__header-content\"\n [id]=\"id() + '-header'\">\n <ng-content select=\"[slot=header]\" />\n </div>\n @if (showClose()) {\n <button\n type=\"button\"\n class=\"ea-dialog__close\"\n [attr.aria-label]=\"i18n.messages().dialog.close\"\n [disabled]=\"closeDisabled()\"\n (click)=\"requestClose()\">\n <ea-icon-x />\n </button>\n }\n </div>\n\n <div class=\"ea-dialog__body\">\n <ng-content />\n </div>\n\n <div class=\"ea-dialog__status\">\n <ng-content select=\"[slot=status]\" />\n </div>\n\n <div class=\"ea-dialog__footer\">\n <ng-content select=\"[slot=footer]\" />\n </div>\n </div>\n</dialog>\n", styles: [".ea-dialog{border:none;background:transparent;padding:0;margin:auto;max-width:none;max-height:none;overflow:visible}.ea-dialog::backdrop{background-color:var(--color-bg-overlay)}.ea-dialog__panel{--_ea-dialog-inset: var(--ea-dialog-inset, var(--space-4));position:relative;display:flex;flex-direction:column;width:var(--ea-dialog-size, 32rem);max-width:calc(100vw - 2 * var(--_ea-dialog-inset));max-height:var(--ea-dialog-max-height, 85vh);background-color:var(--ea-dialog-panel-background-color, var(--color-bg-elevated));border-radius:var(--ea-dialog-radius, var(--radius-xl));box-shadow:var(--shadow-2xl);overflow:hidden}@media(forced-colors:active){.ea-dialog__panel{border:1px solid CanvasText}}.ea-dialog__panel--2xs{--ea-dialog-size: 16rem}.ea-dialog__panel--xs{--ea-dialog-size: 20rem}.ea-dialog__panel--sm{--ea-dialog-size: 24rem}.ea-dialog__panel--md{--ea-dialog-size: 32rem}.ea-dialog__panel--lg{--ea-dialog-size: 42rem}.ea-dialog__panel--xl{--ea-dialog-size: 52rem}.ea-dialog__panel--2xl{--ea-dialog-size: 64rem}.ea-dialog__panel--full{width:calc(100vw - 2 * var(--_ea-dialog-inset));height:calc(100vh - 2 * var(--_ea-dialog-inset));max-height:var(--ea-dialog-max-height, calc(100vh - 2 * var(--_ea-dialog-inset)))}.ea-dialog__panel:has(>.ea-dialog__header--hidden)>.ea-dialog__body{--_ea-dialog-body-padding-top: var(--space-5)}.ea-dialog__panel:not(:has(>.ea-dialog__footer:not(:empty)))>.ea-dialog__status{--_ea-dialog-status-padding-bottom: var(--space-5)}.ea-dialog__panel:not(:has(>.ea-dialog__footer:not(:empty),>.ea-dialog__status:not(:empty)))>.ea-dialog__body{--_ea-dialog-body-padding-bottom: var(--space-5)}.ea-dialog__close{position:relative;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:var(--ea-icon-button-size, 1.75em);height:var(--ea-icon-button-size, 1.75em);padding:0;border:none;border-radius:var(--radius-sm);background:none;color:var(--color-text-secondary);cursor:pointer;transition:var(--transition-colors)}.ea-dialog__close>*{font-size:1.25em}.ea-dialog__close:after{content:\"\";position:absolute;top:50%;left:50%;width:max(100%,var(--ea-icon-button-target, 24px));height:max(100%,var(--ea-icon-button-target, 24px));transform:translate(-50%,-50%)}.ea-dialog__close:hover{background-color:var(--color-state-hover);color:var(--color-text-primary)}.ea-dialog__close:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}@media(forced-colors:active){.ea-dialog__close:focus-visible{outline:2px solid Highlight;outline-offset:2px}}.ea-dialog__close:disabled{cursor:not-allowed;opacity:.5}.ea-dialog__header{display:flex;align-items:flex-start;gap:var(--space-3);padding:var(--ea-dialog-header-padding, var(--space-5) var(--space-6) var(--space-3))}.ea-dialog__header--hidden{display:none}.ea-dialog__header-content{flex:1;min-width:0;font-size:var(--ea-dialog-header-font-size, var(--text-h4-size));font-weight:var(--ea-dialog-header-font-weight, var(--text-h4-weight));line-height:var(--text-h4-lh);color:var(--color-text-primary)}.ea-dialog__body{flex:1;padding:var(--ea-dialog-body-padding, var(--_ea-dialog-body-padding-top, var(--space-3)) var(--space-6) var(--_ea-dialog-body-padding-bottom, var(--space-3)));overflow-y:auto;font-size:var(--font-size-sm);line-height:var(--line-height-normal);color:var(--color-text-secondary)}.ea-dialog__status{flex-shrink:0;padding:var(--ea-dialog-status-padding, var(--space-2) var(--space-6) var(--_ea-dialog-status-padding-bottom, var(--space-2)));font-size:var(--font-size-sm);line-height:var(--line-height-normal);color:var(--color-text-secondary)}.ea-dialog__status:empty{display:none}.ea-dialog__footer{display:flex;align-items:center;justify-content:flex-end;gap:var(--space-3);padding:var(--space-3) var(--space-6) var(--space-5)}.ea-dialog__footer>*{display:flex;align-items:center;gap:var(--space-3)}.ea-dialog__footer:empty{display:none}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: XIconComponent, selector: "ea-icon-x" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
10836
10852
|
}
|
|
10837
10853
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: DialogComponent, decorators: [{
|
|
10838
10854
|
type: Component,
|
|
10839
|
-
args: [{ selector: 'ea-dialog', imports: [NgClass, XIconComponent], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<dialog\n #dialogEl\n class=\"ea-dialog\"\n [id]=\"id()\"\n [attr.aria-label]=\"ariaLabel() ?? null\"\n [attr.aria-labelledby]=\"!ariaLabel() && hasHeader() ? id() + '-header' : null\"\n (click)=\"handleBackdropClick($event)\"\n (cancel)=\"handleCancel($event)\">\n <div\n class=\"ea-dialog__panel\"\n [ngClass]=\"panelClasses()\">\n @if (showClose()) {\n
|
|
10855
|
+
args: [{ selector: 'ea-dialog', imports: [NgClass, XIconComponent], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<dialog\n #dialogEl\n class=\"ea-dialog\"\n [id]=\"id()\"\n [attr.aria-label]=\"ariaLabel() ?? null\"\n [attr.aria-labelledby]=\"!ariaLabel() && hasHeader() ? id() + '-header' : null\"\n (click)=\"handleBackdropClick($event)\"\n (cancel)=\"handleCancel($event)\">\n <div\n class=\"ea-dialog__panel\"\n [ngClass]=\"panelClasses()\">\n <div\n class=\"ea-dialog__header\"\n [class.ea-dialog__header--hidden]=\"!hasHeader() && !showClose()\">\n <div\n #headerEl\n class=\"ea-dialog__header-content\"\n [id]=\"id() + '-header'\">\n <ng-content select=\"[slot=header]\" />\n </div>\n @if (showClose()) {\n <button\n type=\"button\"\n class=\"ea-dialog__close\"\n [attr.aria-label]=\"i18n.messages().dialog.close\"\n [disabled]=\"closeDisabled()\"\n (click)=\"requestClose()\">\n <ea-icon-x />\n </button>\n }\n </div>\n\n <div class=\"ea-dialog__body\">\n <ng-content />\n </div>\n\n <div class=\"ea-dialog__status\">\n <ng-content select=\"[slot=status]\" />\n </div>\n\n <div class=\"ea-dialog__footer\">\n <ng-content select=\"[slot=footer]\" />\n </div>\n </div>\n</dialog>\n", styles: [".ea-dialog{border:none;background:transparent;padding:0;margin:auto;max-width:none;max-height:none;overflow:visible}.ea-dialog::backdrop{background-color:var(--color-bg-overlay)}.ea-dialog__panel{--_ea-dialog-inset: var(--ea-dialog-inset, var(--space-4));position:relative;display:flex;flex-direction:column;width:var(--ea-dialog-size, 32rem);max-width:calc(100vw - 2 * var(--_ea-dialog-inset));max-height:var(--ea-dialog-max-height, 85vh);background-color:var(--ea-dialog-panel-background-color, var(--color-bg-elevated));border-radius:var(--ea-dialog-radius, var(--radius-xl));box-shadow:var(--shadow-2xl);overflow:hidden}@media(forced-colors:active){.ea-dialog__panel{border:1px solid CanvasText}}.ea-dialog__panel--2xs{--ea-dialog-size: 16rem}.ea-dialog__panel--xs{--ea-dialog-size: 20rem}.ea-dialog__panel--sm{--ea-dialog-size: 24rem}.ea-dialog__panel--md{--ea-dialog-size: 32rem}.ea-dialog__panel--lg{--ea-dialog-size: 42rem}.ea-dialog__panel--xl{--ea-dialog-size: 52rem}.ea-dialog__panel--2xl{--ea-dialog-size: 64rem}.ea-dialog__panel--full{width:calc(100vw - 2 * var(--_ea-dialog-inset));height:calc(100vh - 2 * var(--_ea-dialog-inset));max-height:var(--ea-dialog-max-height, calc(100vh - 2 * var(--_ea-dialog-inset)))}.ea-dialog__panel:has(>.ea-dialog__header--hidden)>.ea-dialog__body{--_ea-dialog-body-padding-top: var(--space-5)}.ea-dialog__panel:not(:has(>.ea-dialog__footer:not(:empty)))>.ea-dialog__status{--_ea-dialog-status-padding-bottom: var(--space-5)}.ea-dialog__panel:not(:has(>.ea-dialog__footer:not(:empty),>.ea-dialog__status:not(:empty)))>.ea-dialog__body{--_ea-dialog-body-padding-bottom: var(--space-5)}.ea-dialog__close{position:relative;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:var(--ea-icon-button-size, 1.75em);height:var(--ea-icon-button-size, 1.75em);padding:0;border:none;border-radius:var(--radius-sm);background:none;color:var(--color-text-secondary);cursor:pointer;transition:var(--transition-colors)}.ea-dialog__close>*{font-size:1.25em}.ea-dialog__close:after{content:\"\";position:absolute;top:50%;left:50%;width:max(100%,var(--ea-icon-button-target, 24px));height:max(100%,var(--ea-icon-button-target, 24px));transform:translate(-50%,-50%)}.ea-dialog__close:hover{background-color:var(--color-state-hover);color:var(--color-text-primary)}.ea-dialog__close:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}@media(forced-colors:active){.ea-dialog__close:focus-visible{outline:2px solid Highlight;outline-offset:2px}}.ea-dialog__close:disabled{cursor:not-allowed;opacity:.5}.ea-dialog__header{display:flex;align-items:flex-start;gap:var(--space-3);padding:var(--ea-dialog-header-padding, var(--space-5) var(--space-6) var(--space-3))}.ea-dialog__header--hidden{display:none}.ea-dialog__header-content{flex:1;min-width:0;font-size:var(--ea-dialog-header-font-size, var(--text-h4-size));font-weight:var(--ea-dialog-header-font-weight, var(--text-h4-weight));line-height:var(--text-h4-lh);color:var(--color-text-primary)}.ea-dialog__body{flex:1;padding:var(--ea-dialog-body-padding, var(--_ea-dialog-body-padding-top, var(--space-3)) var(--space-6) var(--_ea-dialog-body-padding-bottom, var(--space-3)));overflow-y:auto;font-size:var(--font-size-sm);line-height:var(--line-height-normal);color:var(--color-text-secondary)}.ea-dialog__status{flex-shrink:0;padding:var(--ea-dialog-status-padding, var(--space-2) var(--space-6) var(--_ea-dialog-status-padding-bottom, var(--space-2)));font-size:var(--font-size-sm);line-height:var(--line-height-normal);color:var(--color-text-secondary)}.ea-dialog__status:empty{display:none}.ea-dialog__footer{display:flex;align-items:center;justify-content:flex-end;gap:var(--space-3);padding:var(--space-3) var(--space-6) var(--space-5)}.ea-dialog__footer>*{display:flex;align-items:center;gap:var(--space-3)}.ea-dialog__footer:empty{display:none}\n"] }]
|
|
10840
10856
|
}], ctorParameters: () => [], propDecorators: { dialogEl: [{ type: i0.ViewChild, args: ['dialogEl', { isSignal: true }] }], headerEl: [{ type: i0.ViewChild, args: ['headerEl', { isSignal: true }] }], width: [{ type: i0.Input, args: [{ isSignal: true, alias: "width", required: false }] }], closeOnBackdrop: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnBackdrop", required: false }] }], closeOnEscape: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnEscape", required: false }] }], showClose: [{ type: i0.Input, args: [{ isSignal: true, alias: "showClose", required: false }] }], closeDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeDisabled", required: false }] }], manualClose: [{ type: i0.Input, args: [{ isSignal: true, alias: "manualClose", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-label", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }, { type: i0.Output, args: ["openChange"] }], opened: [{ type: i0.Output, args: ["opened"] }], closed: [{ type: i0.Output, args: ["closed"] }], closeRequested: [{ type: i0.Output, args: ["closeRequested"] }] } });
|
|
10841
10857
|
|
|
10842
10858
|
// The padding side, per position, applied to the push target so its content
|
|
@@ -10858,6 +10874,9 @@ const PUSH_PROPERTIES = Object.values(PUSH_PROPERTY);
|
|
|
10858
10874
|
* Escape dismissal, and exposes `header`, default, and `footer` content
|
|
10859
10875
|
* slots. The `open` state is a two-way `model()` binding. In `push` mode it
|
|
10860
10876
|
* opens non-modally and reflows the page content aside instead of overlaying it.
|
|
10877
|
+
*
|
|
10878
|
+
* Specs running under jsdom need `installNativeDialogShim()` from
|
|
10879
|
+
* `@eagami/ui/testing` before opening one.
|
|
10861
10880
|
*/
|
|
10862
10881
|
class DrawerComponent {
|
|
10863
10882
|
drawerEl = viewChild('drawerEl', /* @ts-ignore */
|
|
@@ -13447,8 +13466,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImpor
|
|
|
13447
13466
|
* accessible name of that button is configurable via `removeLabel` and
|
|
13448
13467
|
* otherwise falls back to the active locale's translation.
|
|
13449
13468
|
*
|
|
13450
|
-
*
|
|
13451
|
-
*
|
|
13469
|
+
* When capped by `maxWidth` (or the `--ea-tag-max-width` custom property),
|
|
13470
|
+
* the projected label ellipsizes rather than widening the chip, revealing its
|
|
13452
13471
|
* full text in a tooltip while it is clipped.
|
|
13453
13472
|
*/
|
|
13454
13473
|
class TagComponent {
|
|
@@ -13471,7 +13490,7 @@ class TagComponent {
|
|
|
13471
13490
|
* has to give way to its container (`'100%'` in a responsive grid cell).
|
|
13472
13491
|
* Also settable in CSS as `--ea-tag-max-width`, which this input overrides.
|
|
13473
13492
|
*/
|
|
13474
|
-
maxWidth = input(
|
|
13493
|
+
maxWidth = input(undefined, /* @ts-ignore */
|
|
13475
13494
|
...(ngDevMode ? [{ debugName: "maxWidth" }] : /* istanbul ignore next */ []));
|
|
13476
13495
|
/**
|
|
13477
13496
|
* Fill colour as a hex value, for a tag carrying a colour of its own (a
|