@uni-design-system/uni-angular 10.3.0 → 10.4.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 CHANGED
@@ -1,5 +1,23 @@
1
1
  # @uni-design-system/uni-angular
2
2
 
3
+ ## 10.4.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`cb5f08f`](https://github.com/uni-design-system/uni/commit/cb5f08f7bc7f73492688d33388c905941762ea0b) Thanks [@gaenglish](https://github.com/gaenglish)! - Give `uni-dialog` the drawer's three-row layout: a pinned `[uni-dialog-header]`, a scrolling body, and pinned `[uni-dialog-buttons]`.
8
+
9
+ The surface is now a flex column that is `overflow: clip` on both axes, so it is never the scroll container — previously a long form scrolled the dialog's own title and action buttons off the screen. Unlike the drawer, the dialog declares no height and stays sized by its content, growing until it reaches `calc(100dvh - 2 × inset)` and only then scrolling its body.
10
+
11
+ New theme options: `dialog.inset` (gap from the viewport edge before the body scrolls, default `lg`), `dialog.bodyPadding` (pads the scrolling row alone; `dialog.padding` still insets all three rows), and `divider` on `dialogHeader` / `dialogButtons` for a border between a pinned row and the body — all off or unchanged by default, so existing dialogs keep their appearance.
12
+
13
+ `[uni-dialog-header]` gains the shorter `[dialog-header]` alias, matching `[dialog-buttons]`; the long form keeps working. The `defaultCloseButton` now actually floats in the corner — its `position: absolute` was being lost to the icon button's own class, which left it inline at the top of the surface.
14
+
15
+ The drawer's overlay scrim now fades in and out with the panel instead of snapping. Its `::backdrop` had a background and no animation at all, so the dimming appeared and vanished instantly around a panel that took 250ms to slide. A new `drawer.motion` option (default `panel`) times the slide, the scrim's fade and the side panel's width transition together, replacing the hardcoded 250ms literals. The global reduced-motion rule now also reaches `::backdrop`, so both the drawer's and the dialog's scrim honour the preference (WCAG 2.3.3).
16
+
17
+ Dialog and drawer scrims now come from one token. `UniTheme` gains a `backdrops` scale — open and named like `shadows` and `motion` — and both components' `backdrop` option points at a name (`'scrim'`) instead of carrying its own CSS. They had drifted: the dialog washed the page white and blurred it while the drawer dimmed it dark, and a theme that dressed the dialog left the drawer on the library default. A raw style object is still accepted on either option, so a theme that states one keeps working.
18
+
19
+ The dialog's fade now reads the theme's `motion` token too (new `dialog.motion` option, default `panel`), replacing a hardcoded `350ms ease-in`. It shared the drawer's scrim but not its timing, so the same surface arrived at two speeds; both are now 250ms and a theme retimes them together.
20
+
3
21
  ## 10.3.0
4
22
 
5
23
  ### Minor Changes
@@ -2,7 +2,7 @@ import * as i0 from '@angular/core';
2
2
  import { signal, inject, DestroyRef, computed, linkedSignal, resource, Injectable, InjectionToken, input, ChangeDetectionStrategy, Component, ElementRef, Directive, model, afterRenderEffect, Renderer2, output, viewChild, ViewChild, viewChildren, effect, untracked, isDevMode, contentChildren, afterNextRender, forwardRef, booleanAttribute } from '@angular/core';
3
3
  import { injectGlobal, css, keyframes } from '@emotion/css';
4
4
  import { UniThemes, LightTheme, toTypefaces, parseTheme, formatThemeIssues, hydrateTheme, createThemeFromPalette, Z_INDEX, removeInputPlatformStyling, fadeIn, fadeOut, expandDuration, expandFadeIn, collapseFadeOut, HOVER_OR_KEYBOARD_FOCUS, ShapeRadii, generatePalette, emitThemeFile, emitDtcgTokens } from '@uni-design-system/uni-core';
5
- import { NgTemplateOutlet, NgClass, CommonModule } from '@angular/common';
5
+ import { NgTemplateOutlet, NgClass } from '@angular/common';
6
6
 
7
7
  let nextUniqueId = 0;
8
8
  /**
@@ -2042,12 +2042,16 @@ class ThemeService {
2042
2042
  // `?? {}` for themes registered as JSON that predate the motion scale —
2043
2043
  // the validator does not require it, so they must not crash on read.
2044
2044
  motions = computed(() => this.theme().motion ?? {}, ...(ngDevMode ? [{ debugName: "motions" }] : /* istanbul ignore next */ []));
2045
+ /** Same story as `motions`: a JSON theme may predate the backdrops scale. */
2046
+ backdrops = computed(() => this.theme().backdrops ?? {}, ...(ngDevMode ? [{ debugName: "backdrops" }] : /* istanbul ignore next */ []));
2045
2047
  constructor() {
2046
2048
  // Honor the user's reduced-motion preference across every component
2047
2049
  // (WCAG 2.3.3): collapse all animations/transitions to a single frame.
2048
2050
  injectGlobal `
2049
2051
  @media (prefers-reduced-motion: reduce) {
2050
- *, *::before, *::after {
2052
+ /* ::backdrop is not a descendant of anything, so the universal
2053
+ selector alone never reaches the scrim a <dialog> fades in. */
2054
+ *, *::before, *::after, *::backdrop {
2051
2055
  animation-duration: 0.01ms !important;
2052
2056
  animation-iteration-count: 1 !important;
2053
2057
  transition-duration: 0.01ms !important;
@@ -2356,6 +2360,35 @@ class ThemeService {
2356
2360
  return ((token ? motions[token] : undefined) ??
2357
2361
  motions['popup'] ?? { duration: 100, easing: 'linear', scale: 0.8 });
2358
2362
  }
2363
+ warnedBackdrops = new Set();
2364
+ /**
2365
+ * Resolves a named backdrop primitive — the wash a modal surface lays over
2366
+ * the page — so every such surface dims it the same way.
2367
+ *
2368
+ * A raw style object passes straight through: that is the shape the dialog's
2369
+ * and drawer's `backdrop` options took before the scale existed, and a
2370
+ * consumer theme that still states one keeps working.
2371
+ */
2372
+ backdrop(token) {
2373
+ if (!token)
2374
+ return undefined;
2375
+ if (typeof token !== 'string')
2376
+ return token;
2377
+ const backdrops = this.backdrops();
2378
+ const value = backdrops[token];
2379
+ if (value)
2380
+ return value;
2381
+ // The scale is open, so a mistyped name cannot be a compile error. Falling
2382
+ // through to `scrim` still dims the page; saying so once keeps the typo
2383
+ // from hiding behind a backdrop that looks almost right.
2384
+ if ((typeof ngDevMode === 'undefined' || ngDevMode) && !this.warnedBackdrops.has(token)) {
2385
+ this.warnedBackdrops.add(token);
2386
+ console.warn(`[uni] Unknown backdrop token "${token}": the active theme does not define it, ` +
2387
+ `so the shared \`scrim\` is used instead. Add it to the theme's \`backdrops\` ` +
2388
+ `map, or use one of: ${Object.keys(backdrops).join(', ')}.`);
2389
+ }
2390
+ return backdrops['scrim'] ?? { background: 'rgba(0, 0, 0, 0.4)' };
2391
+ }
2359
2392
  radius(size) {
2360
2393
  return !size ? undefined : { borderRadius: this.radii()[size] };
2361
2394
  }
@@ -10516,6 +10549,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImpo
10516
10549
  * This file exports all public-facing elements of the data-table component.
10517
10550
  */
10518
10551
 
10552
+ /**
10553
+ * Modal dialog on the native `<dialog>` element, laid out as three rows:
10554
+ * an optional `[dialog-header]`, the projected body, an optional
10555
+ * `[dialog-buttons]`.
10556
+ *
10557
+ * **The surface is never the scroll container.** It is a flex column that is
10558
+ * `overflow: clip` on both axes; the header and buttons pin while only the
10559
+ * body row scrolls. Unlike the drawer, which is deliberately viewport-tall,
10560
+ * the dialog stays content-sized: it has no `height`, and grows until it hits
10561
+ * `calc(100dvh - 2 x inset)` — the point at which the body starts to scroll.
10562
+ *
10563
+ * The theme's `padding` insets all three rows (which is what makes the default
10564
+ * header read as a pill floating inside the surface); `bodyPadding` pads the
10565
+ * scrolling row alone.
10566
+ */
10519
10567
  class UniDialogComponent extends BaseComponent {
10520
10568
  elem = inject(ElementRef);
10521
10569
  /** Two-way bindable open state: [(show)]. */
@@ -10536,6 +10584,9 @@ class UniDialogComponent extends BaseComponent {
10536
10584
  hasTitle = signal(false, ...(ngDevMode ? [{ debugName: "hasTitle" }] : /* istanbul ignore next */ []));
10537
10585
  /** Emits true once opened and false once the closing animation finishes. */
10538
10586
  showing = output();
10587
+ headerTemplate = viewChild.required('header');
10588
+ bodyTemplate = viewChild.required('body');
10589
+ footerTemplate = viewChild.required('footer');
10539
10590
  constructor() {
10540
10591
  super();
10541
10592
  effect(() => (this.show() ? this.open() : this.close()));
@@ -10543,24 +10594,73 @@ class UniDialogComponent extends BaseComponent {
10543
10594
  get _dialog() {
10544
10595
  return this.elem.nativeElement;
10545
10596
  }
10546
- className = computed(() => css([
10547
- {
10548
- ...this.theme.radius(this.componentOptions().borderRadius),
10549
- ...this.theme.colorPair(this.componentOptions().color),
10550
- ...this.theme.border(this.componentOptions().border),
10551
- ...this.theme.boxShadow(this.componentOptions().elevation),
10552
- ...this.theme.padding(this.componentOptions().padding || 'none'),
10553
- '&::backdrop': {
10554
- ...this.componentOptions().backdrop,
10555
- },
10556
- '&[open], &::backdrop': {
10557
- animation: `${this.dialogFadeIn} ease-in 350ms`,
10558
- },
10559
- '&[closing], &[closing]::backdrop': {
10560
- animation: `${this.dialogFadeOut} ease-in 350ms`,
10597
+ /**
10598
+ * One timing for the whole move, panel and scrim together — the same `panel`
10599
+ * token the drawer's slide reads, so the two surfaces no longer disagree
10600
+ * about how long arriving takes.
10601
+ */
10602
+ motion = computed(() => this.theme.motion(this.componentOptions().motion ?? 'panel'), ...(ngDevMode ? [{ debugName: "motion" }] : /* istanbul ignore next */ []));
10603
+ /** The gap the surface keeps from the viewport edge before its body scrolls. */
10604
+ inset = computed(() => this.theme.getSpacing(this.componentOptions().inset ?? 'lg'), ...(ngDevMode ? [{ debugName: "inset" }] : /* istanbul ignore next */ []));
10605
+ className = computed(() => {
10606
+ const inset = this.inset();
10607
+ const motion = this.motion();
10608
+ return css([
10609
+ {
10610
+ boxSizing: 'border-box',
10611
+ display: 'flex',
10612
+ flexDirection: 'column',
10613
+ // Both axes, explicitly, and never the shorthand. Setting one axis
10614
+ // alone computes the other to `auto` — which is precisely how a
10615
+ // surface becomes an accidental scroll container.
10616
+ overflowX: 'clip',
10617
+ overflowY: 'clip',
10618
+ // No `height`: the dialog is content-sized right up to this cap, and
10619
+ // only then does the body row start to scroll.
10620
+ maxHeight: `calc(100dvh - ${inset} * 2)`,
10621
+ maxWidth: `calc(100vw - ${inset} * 2)`,
10622
+ ...this.theme.radius(this.componentOptions().borderRadius),
10623
+ ...this.theme.colorPair(this.componentOptions().color),
10624
+ ...this.theme.border(this.componentOptions().border),
10625
+ ...this.theme.boxShadow(this.componentOptions().elevation),
10626
+ ...this.theme.padding(this.componentOptions().padding || 'none'),
10627
+ // The UA stylesheet hides a closed dialog with `display: none`, which
10628
+ // the `display: flex` above would otherwise beat on specificity —
10629
+ // leaving the surface in normal flow behind the page whenever it is
10630
+ // shut. The closing animation still runs: `open` is only removed once
10631
+ // it ends.
10632
+ '&:not([open])': { display: 'none' },
10633
+ // The shared `backdrops` primitive, so the dialog and the drawer dim
10634
+ // the page identically. A raw style object is still honoured.
10635
+ '&::backdrop': {
10636
+ ...this.theme.backdrop(this.componentOptions().backdrop),
10637
+ },
10638
+ '&[open], &::backdrop': {
10639
+ animation: `${this.dialogFadeIn} ${motion.easing} ${motion.duration}ms`,
10640
+ },
10641
+ '&[closing], &[closing]::backdrop': {
10642
+ animation: `${this.dialogFadeOut} ${motion.easing} ${motion.duration}ms`,
10643
+ },
10561
10644
  },
10562
- },
10563
- ]), ...(ngDevMode ? [{ debugName: "className" }] : /* istanbul ignore next */ []));
10645
+ ]);
10646
+ }, ...(ngDevMode ? [{ debugName: "className" }] : /* istanbul ignore next */ []));
10647
+ /** The only scrolling row, and the only one `bodyPadding` touches. */
10648
+ bodyClass = computed(() => css({
10649
+ // Not the drawer's `1 1 auto`: the dialog must not stretch to fill a cap
10650
+ // it has not reached, so the body never grows past its content.
10651
+ flex: '0 1 auto',
10652
+ // What lets this row shrink below its content and scroll, rather than
10653
+ // pushing the buttons off the surface.
10654
+ minHeight: 0,
10655
+ // Defence in depth: a positioned body is the containing block for any
10656
+ // stray absolute descendant, so nothing can re-home into an ancestor and
10657
+ // inflate its scrollHeight.
10658
+ position: 'relative',
10659
+ overflowX: 'hidden',
10660
+ overflowY: 'auto',
10661
+ overscrollBehavior: 'contain',
10662
+ ...this.theme.padding(this.componentOptions().bodyPadding),
10663
+ }), ...(ngDevMode ? [{ debugName: "bodyClass" }] : /* istanbul ignore next */ []));
10564
10664
  backdropClick(event) {
10565
10665
  if (event.target.nodeName === 'DIALOG') {
10566
10666
  this.close();
@@ -10583,10 +10683,18 @@ class UniDialogComponent extends BaseComponent {
10583
10683
  this.showing.emit(false);
10584
10684
  }
10585
10685
  }
10686
+ /**
10687
+ * Doubled selector (`.css-x.css-x`) so these win over the icon button's own
10688
+ * class, which sets `position: relative` and is emitted after this one.
10689
+ * Without it the close never leaves the flow — it used to sit inline at the
10690
+ * top of the surface, and under the flex column it would take a whole row.
10691
+ */
10586
10692
  closeButton = css({
10587
- position: 'absolute',
10588
- right: 12,
10589
- top: 12,
10693
+ '&&': {
10694
+ position: 'absolute',
10695
+ right: 12,
10696
+ top: 12,
10697
+ },
10590
10698
  });
10591
10699
  dialogFadeIn = keyframes({ ...fadeIn });
10592
10700
  dialogFadeOut = keyframes({ ...fadeOut });
@@ -10614,7 +10722,7 @@ class UniDialogComponent extends BaseComponent {
10614
10722
  this.show.set(false);
10615
10723
  }
10616
10724
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: UniDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
10617
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: UniDialogComponent, isStandalone: true, selector: "dialog[uni-dialog]", inputs: { show: { classPropertyName: "show", publicName: "show", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, initialFocus: { classPropertyName: "initialFocus", publicName: "initialFocus", isSignal: true, isRequired: false, transformFunction: null }, defaultCloseButton: { classPropertyName: "defaultCloseButton", publicName: "defaultCloseButton", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { show: "showChange", showing: "showing" }, host: { listeners: { "click": "backdropClick($event)", "cancel": "escapeCancel($event)", "animationend": "closingAnimation($event)" }, properties: { "attr.aria-labelledby": "hasTitle() ? titleId : null", "attr.aria-label": "ariaLabel() ?? null", "class": "className()" } }, providers: [{ provide: COMPONENT_NAME, useValue: 'dialog' }], usesInheritance: true, ngImport: i0, template: `
10725
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: UniDialogComponent, isStandalone: true, selector: "dialog[uni-dialog]", inputs: { show: { classPropertyName: "show", publicName: "show", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, initialFocus: { classPropertyName: "initialFocus", publicName: "initialFocus", isSignal: true, isRequired: false, transformFunction: null }, defaultCloseButton: { classPropertyName: "defaultCloseButton", publicName: "defaultCloseButton", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { show: "showChange", showing: "showing" }, host: { listeners: { "click": "backdropClick($event)", "cancel": "escapeCancel($event)", "animationend": "closingAnimation($event)" }, properties: { "attr.aria-labelledby": "hasTitle() ? titleId : null", "attr.aria-label": "ariaLabel() ?? null", "class": "className()" } }, providers: [{ provide: COMPONENT_NAME, useValue: 'dialog' }], viewQueries: [{ propertyName: "headerTemplate", first: true, predicate: ["header"], descendants: true, isSignal: true }, { propertyName: "bodyTemplate", first: true, predicate: ["body"], descendants: true, isSignal: true }, { propertyName: "footerTemplate", first: true, predicate: ["footer"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: `
10618
10726
  @if (defaultCloseButton()) {
10619
10727
  <button
10620
10728
  icon-button
@@ -10627,14 +10735,24 @@ class UniDialogComponent extends BaseComponent {
10627
10735
  Close
10628
10736
  </button>
10629
10737
  }
10630
- <ng-content></ng-content>
10631
- `, isInline: true, dependencies: [{ kind: "component", type: UniIconButtonComponent, selector: "button[uni-icon-button], button[icon-button]", inputs: ["ariaLabel", "iconName", "symbolName", "variant", "size", "disable", "loading", "opticalSize"] }, { kind: "ngmodule", type: CommonModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
10738
+
10739
+ <!-- One <ng-content> per slot, each parked in a template. Angular claims
10740
+ projected nodes in declaration order, so the catch-all must be declared
10741
+ last — while being rendered between the two pinned rows below. -->
10742
+ <ng-template #header><ng-content select="[uni-dialog-header], [dialog-header]" /></ng-template>
10743
+ <ng-template #footer><ng-content select="[uni-dialog-buttons], [dialog-buttons]" /></ng-template>
10744
+ <ng-template #body><ng-content /></ng-template>
10745
+
10746
+ <ng-container [ngTemplateOutlet]="headerTemplate()" />
10747
+ <div [class]="bodyClass()"><ng-container [ngTemplateOutlet]="bodyTemplate()" /></div>
10748
+ <ng-container [ngTemplateOutlet]="footerTemplate()" />
10749
+ `, isInline: true, dependencies: [{ kind: "component", type: UniIconButtonComponent, selector: "button[uni-icon-button], button[icon-button]", inputs: ["ariaLabel", "iconName", "symbolName", "variant", "size", "disable", "loading", "opticalSize"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
10632
10750
  }
10633
10751
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: UniDialogComponent, decorators: [{
10634
10752
  type: Component,
10635
10753
  args: [{
10636
10754
  selector: 'dialog[uni-dialog]',
10637
- imports: [UniIconButtonComponent, CommonModule],
10755
+ imports: [UniIconButtonComponent, NgTemplateOutlet],
10638
10756
  template: `
10639
10757
  @if (defaultCloseButton()) {
10640
10758
  <button
@@ -10648,7 +10766,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImpo
10648
10766
  Close
10649
10767
  </button>
10650
10768
  }
10651
- <ng-content></ng-content>
10769
+
10770
+ <!-- One <ng-content> per slot, each parked in a template. Angular claims
10771
+ projected nodes in declaration order, so the catch-all must be declared
10772
+ last — while being rendered between the two pinned rows below. -->
10773
+ <ng-template #header><ng-content select="[uni-dialog-header], [dialog-header]" /></ng-template>
10774
+ <ng-template #footer><ng-content select="[uni-dialog-buttons], [dialog-buttons]" /></ng-template>
10775
+ <ng-template #body><ng-content /></ng-template>
10776
+
10777
+ <ng-container [ngTemplateOutlet]="headerTemplate()" />
10778
+ <div [class]="bodyClass()"><ng-container [ngTemplateOutlet]="bodyTemplate()" /></div>
10779
+ <ng-container [ngTemplateOutlet]="footerTemplate()" />
10652
10780
  `,
10653
10781
  providers: [{ provide: COMPONENT_NAME, useValue: 'dialog' }],
10654
10782
  changeDetection: ChangeDetectionStrategy.OnPush,
@@ -10661,7 +10789,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImpo
10661
10789
  '(animationend)': 'closingAnimation($event)',
10662
10790
  },
10663
10791
  }]
10664
- }], ctorParameters: () => [], propDecorators: { show: [{ type: i0.Input, args: [{ isSignal: true, alias: "show", required: false }] }, { type: i0.Output, args: ["showChange"] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], initialFocus: [{ type: i0.Input, args: [{ isSignal: true, alias: "initialFocus", required: false }] }], defaultCloseButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultCloseButton", required: false }] }], showing: [{ type: i0.Output, args: ["showing"] }] } });
10792
+ }], ctorParameters: () => [], propDecorators: { show: [{ type: i0.Input, args: [{ isSignal: true, alias: "show", required: false }] }, { type: i0.Output, args: ["showChange"] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], initialFocus: [{ type: i0.Input, args: [{ isSignal: true, alias: "initialFocus", required: false }] }], defaultCloseButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultCloseButton", required: false }] }], showing: [{ type: i0.Output, args: ["showing"] }], headerTemplate: [{ type: i0.ViewChild, args: ['header', { isSignal: true }] }], bodyTemplate: [{ type: i0.ViewChild, args: ['body', { isSignal: true }] }], footerTemplate: [{ type: i0.ViewChild, args: ['footer', { isSignal: true }] }] } });
10665
10793
 
10666
10794
  class UniDialogButtonsComponent extends BaseComponent {
10667
10795
  dialog = inject(UniDialogComponent, {
@@ -10686,6 +10814,11 @@ class UniDialogButtonsComponent extends BaseComponent {
10686
10814
  justifyContentValue = computed(() => this.justifyContent() ?? this.componentOptions().justifyContent ?? 'center', ...(ngDevMode ? [{ debugName: "justifyContentValue" }] : /* istanbul ignore next */ []));
10687
10815
  gapValue = computed(() => this.componentOptions().gap ?? 'md', ...(ngDevMode ? [{ debugName: "gapValue" }] : /* istanbul ignore next */ []));
10688
10816
  buttonSize = computed(() => this.componentOptions().buttonSize ?? 'lg', ...(ngDevMode ? [{ debugName: "buttonSize" }] : /* istanbul ignore next */ []));
10817
+ /** A pinned row, sized by its content rather than by the body beside it. */
10818
+ hostClass = computed(() => css({
10819
+ flex: 'none',
10820
+ ...this.theme.borderTop(this.componentOptions().divider),
10821
+ }), ...(ngDevMode ? [{ debugName: "hostClass" }] : /* istanbul ignore next */ []));
10689
10822
  className = computed(() => css([
10690
10823
  this.componentTheme().fixed,
10691
10824
  this.componentOptions().stretch && {
@@ -10698,11 +10831,11 @@ class UniDialogButtonsComponent extends BaseComponent {
10698
10831
  this.dialog?.close();
10699
10832
  }
10700
10833
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: UniDialogButtonsComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
10701
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.12", type: UniDialogButtonsComponent, isStandalone: true, selector: "[uni-dialog-buttons], [dialog-buttons]", inputs: { confirmButtonText: { classPropertyName: "confirmButtonText", publicName: "confirmButtonText", isSignal: true, isRequired: false, transformFunction: null }, confirmButtonVariant: { classPropertyName: "confirmButtonVariant", publicName: "confirmButtonVariant", isSignal: true, isRequired: false, transformFunction: null }, cancelButtonText: { classPropertyName: "cancelButtonText", publicName: "cancelButtonText", isSignal: true, isRequired: false, transformFunction: null }, cancelButtonVariant: { classPropertyName: "cancelButtonVariant", publicName: "cancelButtonVariant", isSignal: true, isRequired: false, transformFunction: null }, disableConfirm: { classPropertyName: "disableConfirm", publicName: "disableConfirm", isSignal: true, isRequired: false, transformFunction: null }, padding: { classPropertyName: "padding", publicName: "padding", isSignal: true, isRequired: false, transformFunction: null }, paddingBottom: { classPropertyName: "paddingBottom", publicName: "paddingBottom", isSignal: true, isRequired: false, transformFunction: null }, justifyContent: { classPropertyName: "justifyContent", publicName: "justifyContent", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { confirmed: "confirmed" }, providers: [{ provide: COMPONENT_NAME, useValue: 'dialogButtons' }], usesInheritance: true, ngImport: i0, template: "<div\n row-layout\n [gap]=\"gapValue()\"\n [padding]=\"paddingValue()\"\n [paddingBottom]=\"paddingBottomValue()\"\n [justifyContent]=\"justifyContentValue()\"\n [flexDirection]=\"componentOptions().reverseOrder ? 'row-reverse' : 'row'\"\n [class]=\"className()\"\n>\n <button\n text-button\n [variant]=\"confirmVariant()\"\n [size]=\"buttonSize()\"\n (click)=\"confirmed.emit(); closeDialog()\"\n [disable]=\"disableConfirm()\"\n >\n {{ confirmButtonText() || 'Confirm' }}\n </button>\n <button text-button [variant]=\"cancelVariant()\" [size]=\"buttonSize()\" (click)=\"closeDialog()\">\n {{ cancelButtonText() || 'Cancel' }}\n </button>\n</div>\n", dependencies: [{ kind: "directive", type: UniRowDirective, selector: "[uni-row-layout], [row-layout]", inputs: ["display", "flexDirection", "minWidth"] }, { kind: "component", type: UniButtonComponent, selector: "button[uni-text-button], button[text-button]", inputs: ["disable", "loading", "fullWidth", "symbolLeft", "symbolRight"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
10834
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.12", type: UniDialogButtonsComponent, isStandalone: true, selector: "[uni-dialog-buttons], [dialog-buttons]", inputs: { confirmButtonText: { classPropertyName: "confirmButtonText", publicName: "confirmButtonText", isSignal: true, isRequired: false, transformFunction: null }, confirmButtonVariant: { classPropertyName: "confirmButtonVariant", publicName: "confirmButtonVariant", isSignal: true, isRequired: false, transformFunction: null }, cancelButtonText: { classPropertyName: "cancelButtonText", publicName: "cancelButtonText", isSignal: true, isRequired: false, transformFunction: null }, cancelButtonVariant: { classPropertyName: "cancelButtonVariant", publicName: "cancelButtonVariant", isSignal: true, isRequired: false, transformFunction: null }, disableConfirm: { classPropertyName: "disableConfirm", publicName: "disableConfirm", isSignal: true, isRequired: false, transformFunction: null }, padding: { classPropertyName: "padding", publicName: "padding", isSignal: true, isRequired: false, transformFunction: null }, paddingBottom: { classPropertyName: "paddingBottom", publicName: "paddingBottom", isSignal: true, isRequired: false, transformFunction: null }, justifyContent: { classPropertyName: "justifyContent", publicName: "justifyContent", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { confirmed: "confirmed" }, host: { properties: { "class": "hostClass()" } }, providers: [{ provide: COMPONENT_NAME, useValue: 'dialogButtons' }], usesInheritance: true, ngImport: i0, template: "<div\n row-layout\n [gap]=\"gapValue()\"\n [padding]=\"paddingValue()\"\n [paddingBottom]=\"paddingBottomValue()\"\n [justifyContent]=\"justifyContentValue()\"\n [flexDirection]=\"componentOptions().reverseOrder ? 'row-reverse' : 'row'\"\n [class]=\"className()\"\n>\n <button\n text-button\n [variant]=\"confirmVariant()\"\n [size]=\"buttonSize()\"\n (click)=\"confirmed.emit(); closeDialog()\"\n [disable]=\"disableConfirm()\"\n >\n {{ confirmButtonText() || 'Confirm' }}\n </button>\n <button text-button [variant]=\"cancelVariant()\" [size]=\"buttonSize()\" (click)=\"closeDialog()\">\n {{ cancelButtonText() || 'Cancel' }}\n </button>\n</div>\n", dependencies: [{ kind: "directive", type: UniRowDirective, selector: "[uni-row-layout], [row-layout]", inputs: ["display", "flexDirection", "minWidth"] }, { kind: "component", type: UniButtonComponent, selector: "button[uni-text-button], button[text-button]", inputs: ["disable", "loading", "fullWidth", "symbolLeft", "symbolRight"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
10702
10835
  }
10703
10836
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: UniDialogButtonsComponent, decorators: [{
10704
10837
  type: Component,
10705
- args: [{ selector: '[uni-dialog-buttons], [dialog-buttons]', imports: [UniRowDirective, UniButtonComponent], providers: [{ provide: COMPONENT_NAME, useValue: 'dialogButtons' }], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n row-layout\n [gap]=\"gapValue()\"\n [padding]=\"paddingValue()\"\n [paddingBottom]=\"paddingBottomValue()\"\n [justifyContent]=\"justifyContentValue()\"\n [flexDirection]=\"componentOptions().reverseOrder ? 'row-reverse' : 'row'\"\n [class]=\"className()\"\n>\n <button\n text-button\n [variant]=\"confirmVariant()\"\n [size]=\"buttonSize()\"\n (click)=\"confirmed.emit(); closeDialog()\"\n [disable]=\"disableConfirm()\"\n >\n {{ confirmButtonText() || 'Confirm' }}\n </button>\n <button text-button [variant]=\"cancelVariant()\" [size]=\"buttonSize()\" (click)=\"closeDialog()\">\n {{ cancelButtonText() || 'Cancel' }}\n </button>\n</div>\n" }]
10838
+ args: [{ selector: '[uni-dialog-buttons], [dialog-buttons]', imports: [UniRowDirective, UniButtonComponent], providers: [{ provide: COMPONENT_NAME, useValue: 'dialogButtons' }], changeDetection: ChangeDetectionStrategy.OnPush, host: { '[class]': 'hostClass()' }, template: "<div\n row-layout\n [gap]=\"gapValue()\"\n [padding]=\"paddingValue()\"\n [paddingBottom]=\"paddingBottomValue()\"\n [justifyContent]=\"justifyContentValue()\"\n [flexDirection]=\"componentOptions().reverseOrder ? 'row-reverse' : 'row'\"\n [class]=\"className()\"\n>\n <button\n text-button\n [variant]=\"confirmVariant()\"\n [size]=\"buttonSize()\"\n (click)=\"confirmed.emit(); closeDialog()\"\n [disable]=\"disableConfirm()\"\n >\n {{ confirmButtonText() || 'Confirm' }}\n </button>\n <button text-button [variant]=\"cancelVariant()\" [size]=\"buttonSize()\" (click)=\"closeDialog()\">\n {{ cancelButtonText() || 'Cancel' }}\n </button>\n</div>\n" }]
10706
10839
  }], propDecorators: { confirmButtonText: [{ type: i0.Input, args: [{ isSignal: true, alias: "confirmButtonText", required: false }] }], confirmButtonVariant: [{ type: i0.Input, args: [{ isSignal: true, alias: "confirmButtonVariant", required: false }] }], cancelButtonText: [{ type: i0.Input, args: [{ isSignal: true, alias: "cancelButtonText", required: false }] }], cancelButtonVariant: [{ type: i0.Input, args: [{ isSignal: true, alias: "cancelButtonVariant", required: false }] }], disableConfirm: [{ type: i0.Input, args: [{ isSignal: true, alias: "disableConfirm", required: false }] }], padding: [{ type: i0.Input, args: [{ isSignal: true, alias: "padding", required: false }] }], paddingBottom: [{ type: i0.Input, args: [{ isSignal: true, alias: "paddingBottom", required: false }] }], justifyContent: [{ type: i0.Input, args: [{ isSignal: true, alias: "justifyContent", required: false }] }], confirmed: [{ type: i0.Output, args: ["confirmed"] }] } });
10707
10840
 
10708
10841
  class UniDialogHeaderComponent extends BaseComponent {
@@ -10720,12 +10853,20 @@ class UniDialogHeaderComponent extends BaseComponent {
10720
10853
  closeDialog() {
10721
10854
  this.dialog?.close();
10722
10855
  }
10856
+ /**
10857
+ * A pinned row: it is a flex child of the dialog and must not be sized by
10858
+ * the scrolling body beside it.
10859
+ */
10860
+ className = computed(() => css({
10861
+ flex: 'none',
10862
+ ...this.theme.borderBottom(this.componentOptions().divider),
10863
+ }), ...(ngDevMode ? [{ debugName: "className" }] : /* istanbul ignore next */ []));
10723
10864
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: UniDialogHeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
10724
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: UniDialogHeaderComponent, isStandalone: true, selector: "[uni-dialog-header]", providers: [{ provide: COMPONENT_NAME, useValue: 'dialogHeader' }], usesInheritance: true, ngImport: i0, template: "<div\n row-layout\n [containerColor]=\"componentOptions().color\"\n [borderRadius]=\"componentOptions().borderRadius\"\n [height]=\"componentOptions().height\"\n alignItems=\"center\"\n [paddingHorizontal]=\"componentOptions().paddingHorizontal ?? 'sm'\"\n>\n <!-- Balance spacer: only centered titles need to offset the close button. -->\n @if ((componentOptions().textAlign || 'center') === 'center') {\n <div box-layout [width]=\"26\"></div>\n }\n <div box-layout [grow]=\"1\" [attr.id]=\"titleId\">\n <span uni-text\n [typeface]=\"componentOptions().textRole\"\n [color]=\"componentOptions().textColor\"\n display=\"block\"\n [align]=\"componentOptions().textAlign || 'center'\"\n ><ng-content></ng-content\n ></span>\n </div>\n <button\n icon-button\n [iconName]=\"componentOptions().closeButtonIcon\"\n [symbolName]=\"componentOptions().closeButtonSymbol\"\n variant=\"ghost\"\n (click)=\"closeDialog()\"\n [size]=\"componentOptions().closeButtonSize || 'md'\"\n >\n Close\n </button>\n</div>\n", dependencies: [{ kind: "directive", type: UniBoxDirective, selector: "[uni-box-layout], [box-layout]", inputs: ["containerColor", "backgroundColor", "borderRadius", "borderRadiusLeft", "borderRadiusRight", "borderRadiusTop", "borderRadiusBottom", "padding", "paddingHorizontal", "paddingVertical", "paddingLeft", "paddingRight", "paddingTop", "paddingBottom", "border", "borderTop", "borderBottom", "borderLeft", "borderRight", "dashBorder", "alignSelf", "alignItems", "alignContent", "justifyContent", "grow", "flex", "shrink", "basis", "marginInline", "display", "position", "inset", "height", "minHeight", "maxHeight", "width", "minWidth", "maxWidth", "ignoreDir", "gridArea", "gridColumn", "gridRow", "overflow", "shadow", "gap", "fullWidth", "fullHeight", "flexDirection", "textAlign", "wrapItems", "zIndex"] }, { kind: "component", type: UniIconButtonComponent, selector: "button[uni-icon-button], button[icon-button]", inputs: ["ariaLabel", "iconName", "symbolName", "variant", "size", "disable", "loading", "opticalSize"] }, { kind: "directive", type: UniTextDirective, selector: "[uni-text]", inputs: ["uni-text", "typeface", "color", "display", "align", "nowrap", "maxWidth", "ellipsis"] }, { kind: "directive", type: UniRowDirective, selector: "[uni-row-layout], [row-layout]", inputs: ["display", "flexDirection", "minWidth"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
10865
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: UniDialogHeaderComponent, isStandalone: true, selector: "[uni-dialog-header], [dialog-header]", host: { properties: { "class": "className()" } }, providers: [{ provide: COMPONENT_NAME, useValue: 'dialogHeader' }], usesInheritance: true, ngImport: i0, template: "<div\n row-layout\n [containerColor]=\"componentOptions().color\"\n [borderRadius]=\"componentOptions().borderRadius\"\n [height]=\"componentOptions().height\"\n alignItems=\"center\"\n [paddingHorizontal]=\"componentOptions().paddingHorizontal ?? 'sm'\"\n>\n <!-- Balance spacer: only centered titles need to offset the close button. -->\n @if ((componentOptions().textAlign || 'center') === 'center') {\n <div box-layout [width]=\"26\"></div>\n }\n <div box-layout [grow]=\"1\" [attr.id]=\"titleId\">\n <span uni-text\n [typeface]=\"componentOptions().textRole\"\n [color]=\"componentOptions().textColor\"\n display=\"block\"\n [align]=\"componentOptions().textAlign || 'center'\"\n ><ng-content></ng-content\n ></span>\n </div>\n <button\n icon-button\n [iconName]=\"componentOptions().closeButtonIcon\"\n [symbolName]=\"componentOptions().closeButtonSymbol\"\n variant=\"ghost\"\n (click)=\"closeDialog()\"\n [size]=\"componentOptions().closeButtonSize || 'md'\"\n >\n Close\n </button>\n</div>\n", dependencies: [{ kind: "directive", type: UniBoxDirective, selector: "[uni-box-layout], [box-layout]", inputs: ["containerColor", "backgroundColor", "borderRadius", "borderRadiusLeft", "borderRadiusRight", "borderRadiusTop", "borderRadiusBottom", "padding", "paddingHorizontal", "paddingVertical", "paddingLeft", "paddingRight", "paddingTop", "paddingBottom", "border", "borderTop", "borderBottom", "borderLeft", "borderRight", "dashBorder", "alignSelf", "alignItems", "alignContent", "justifyContent", "grow", "flex", "shrink", "basis", "marginInline", "display", "position", "inset", "height", "minHeight", "maxHeight", "width", "minWidth", "maxWidth", "ignoreDir", "gridArea", "gridColumn", "gridRow", "overflow", "shadow", "gap", "fullWidth", "fullHeight", "flexDirection", "textAlign", "wrapItems", "zIndex"] }, { kind: "component", type: UniIconButtonComponent, selector: "button[uni-icon-button], button[icon-button]", inputs: ["ariaLabel", "iconName", "symbolName", "variant", "size", "disable", "loading", "opticalSize"] }, { kind: "directive", type: UniTextDirective, selector: "[uni-text]", inputs: ["uni-text", "typeface", "color", "display", "align", "nowrap", "maxWidth", "ellipsis"] }, { kind: "directive", type: UniRowDirective, selector: "[uni-row-layout], [row-layout]", inputs: ["display", "flexDirection", "minWidth"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
10725
10866
  }
10726
10867
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: UniDialogHeaderComponent, decorators: [{
10727
10868
  type: Component,
10728
- args: [{ changeDetection: ChangeDetectionStrategy.OnPush, selector: '[uni-dialog-header]', imports: [UniBoxDirective, UniIconButtonComponent, UniTextDirective, UniRowDirective], providers: [{ provide: COMPONENT_NAME, useValue: 'dialogHeader' }], template: "<div\n row-layout\n [containerColor]=\"componentOptions().color\"\n [borderRadius]=\"componentOptions().borderRadius\"\n [height]=\"componentOptions().height\"\n alignItems=\"center\"\n [paddingHorizontal]=\"componentOptions().paddingHorizontal ?? 'sm'\"\n>\n <!-- Balance spacer: only centered titles need to offset the close button. -->\n @if ((componentOptions().textAlign || 'center') === 'center') {\n <div box-layout [width]=\"26\"></div>\n }\n <div box-layout [grow]=\"1\" [attr.id]=\"titleId\">\n <span uni-text\n [typeface]=\"componentOptions().textRole\"\n [color]=\"componentOptions().textColor\"\n display=\"block\"\n [align]=\"componentOptions().textAlign || 'center'\"\n ><ng-content></ng-content\n ></span>\n </div>\n <button\n icon-button\n [iconName]=\"componentOptions().closeButtonIcon\"\n [symbolName]=\"componentOptions().closeButtonSymbol\"\n variant=\"ghost\"\n (click)=\"closeDialog()\"\n [size]=\"componentOptions().closeButtonSize || 'md'\"\n >\n Close\n </button>\n</div>\n" }]
10869
+ args: [{ changeDetection: ChangeDetectionStrategy.OnPush, selector: '[uni-dialog-header], [dialog-header]', imports: [UniBoxDirective, UniIconButtonComponent, UniTextDirective, UniRowDirective], providers: [{ provide: COMPONENT_NAME, useValue: 'dialogHeader' }], host: { '[class]': 'className()' }, template: "<div\n row-layout\n [containerColor]=\"componentOptions().color\"\n [borderRadius]=\"componentOptions().borderRadius\"\n [height]=\"componentOptions().height\"\n alignItems=\"center\"\n [paddingHorizontal]=\"componentOptions().paddingHorizontal ?? 'sm'\"\n>\n <!-- Balance spacer: only centered titles need to offset the close button. -->\n @if ((componentOptions().textAlign || 'center') === 'center') {\n <div box-layout [width]=\"26\"></div>\n }\n <div box-layout [grow]=\"1\" [attr.id]=\"titleId\">\n <span uni-text\n [typeface]=\"componentOptions().textRole\"\n [color]=\"componentOptions().textColor\"\n display=\"block\"\n [align]=\"componentOptions().textAlign || 'center'\"\n ><ng-content></ng-content\n ></span>\n </div>\n <button\n icon-button\n [iconName]=\"componentOptions().closeButtonIcon\"\n [symbolName]=\"componentOptions().closeButtonSymbol\"\n variant=\"ghost\"\n (click)=\"closeDialog()\"\n [size]=\"componentOptions().closeButtonSize || 'md'\"\n >\n Close\n </button>\n</div>\n" }]
10729
10870
  }], ctorParameters: () => [] });
10730
10871
 
10731
10872
  const DRAWER_PANEL = new InjectionToken('uni-drawer-panel');
@@ -10956,6 +11097,15 @@ class UniDrawerComponent extends BaseComponent {
10956
11097
  edge = computed(() => (this.position() === 'start' ? '-100%' : '100%'), ...(ngDevMode ? [{ debugName: "edge" }] : /* istanbul ignore next */ []));
10957
11098
  slideIn = computed(() => keyframes({ from: { transform: `translateX(${this.edge()})` }, to: { transform: 'translateX(0)' } }), ...(ngDevMode ? [{ debugName: "slideIn" }] : /* istanbul ignore next */ []));
10958
11099
  slideOut = computed(() => keyframes({ from: { transform: 'translateX(0)' }, to: { transform: `translateX(${this.edge()})` } }), ...(ngDevMode ? [{ debugName: "slideOut" }] : /* istanbul ignore next */ []));
11100
+ /** The scrim's own fade, so the dimming arrives and leaves with the panel. */
11101
+ scrimIn = keyframes({ ...fadeIn });
11102
+ scrimOut = keyframes({ ...fadeOut });
11103
+ /**
11104
+ * One timing for everything the panel does. The scrim used to snap in and
11105
+ * out around a panel that took 250ms to slide, because `::backdrop` had a
11106
+ * background and no animation at all.
11107
+ */
11108
+ motion = computed(() => this.theme.motion(this.componentOptions().motion ?? 'panel'), ...(ngDevMode ? [{ debugName: "motion" }] : /* istanbul ignore next */ []));
10959
11109
  /** Input wins over the theme option; the literal is the last-resort default. */
10960
11110
  panelWidth = computed(() => this.width() ?? this.componentOptions().width ?? 280, ...(ngDevMode ? [{ debugName: "panelWidth" }] : /* istanbul ignore next */ []));
10961
11111
  showScrim = computed(() => this.scrim() ?? this.componentOptions().scrim ?? true, ...(ngDevMode ? [{ debugName: "showScrim" }] : /* istanbul ignore next */ []));
@@ -10998,13 +11148,14 @@ class UniDrawerComponent extends BaseComponent {
10998
11148
  };
10999
11149
  sideClass = computed(() => {
11000
11150
  const options = this.componentOptions();
11151
+ const motion = this.motion();
11001
11152
  const width = this.panelWidth();
11002
11153
  const start = this.position() === 'start';
11003
11154
  return css({
11004
11155
  ...this.shell,
11005
11156
  height: '100%',
11006
11157
  flex: 'none',
11007
- transition: 'width 0.25s ease, visibility 0.25s',
11158
+ transition: `width ${motion.duration}ms ${motion.easing}, visibility ${motion.duration}ms`,
11008
11159
  ...this.surface(),
11009
11160
  ...(start
11010
11161
  ? this.theme.borderRight(options.divider)
@@ -11016,6 +11167,8 @@ class UniDrawerComponent extends BaseComponent {
11016
11167
  }, ...(ngDevMode ? [{ debugName: "sideClass" }] : /* istanbul ignore next */ []));
11017
11168
  overClass = computed(() => {
11018
11169
  const options = this.componentOptions();
11170
+ const motion = this.motion();
11171
+ const scrim = this.showScrim();
11019
11172
  const start = this.position() === 'start';
11020
11173
  return css({
11021
11174
  ...this.shell,
@@ -11035,9 +11188,25 @@ class UniDrawerComponent extends BaseComponent {
11035
11188
  '&:not([open])': { display: 'none' },
11036
11189
  // `scrim: false` keeps the modality — focus trap, inert page — but stops
11037
11190
  // the drawer dimming what it covers.
11038
- '&::backdrop': this.showScrim() ? { ...options.backdrop } : { background: 'transparent' },
11039
- '&[open]': { animation: `${this.slideIn()} 250ms ease-out` },
11040
- '&[closing]': { animation: `${this.slideOut()} 250ms ease-in` },
11191
+ '&::backdrop': scrim
11192
+ ? { ...this.theme.backdrop(options.backdrop) }
11193
+ : { background: 'transparent' },
11194
+ '&[open]': { animation: `${this.slideIn()} ${motion.duration}ms ${motion.easing}` },
11195
+ '&[closing]': { animation: `${this.slideOut()} ${motion.duration}ms ${motion.easing}` },
11196
+ // Same duration as the slide, so the dimming tracks the panel rather
11197
+ // than snapping. Declared after the `[open]` rules: the two match on
11198
+ // specificity while closing, so source order is what makes the fade-out
11199
+ // win. Nothing to fade when there is no scrim.
11200
+ ...(scrim
11201
+ ? {
11202
+ '&[open]::backdrop': {
11203
+ animation: `${this.scrimIn} ${motion.duration}ms ${motion.easing}`,
11204
+ },
11205
+ '&[closing]::backdrop': {
11206
+ animation: `${this.scrimOut} ${motion.duration}ms ${motion.easing}`,
11207
+ },
11208
+ }
11209
+ : {}),
11041
11210
  });
11042
11211
  }, ...(ngDevMode ? [{ debugName: "overClass" }] : /* istanbul ignore next */ []));
11043
11212
  /** The only scrolling row, and the only padded one. */
@@ -12202,7 +12371,7 @@ class ConfirmationDialogComponent {
12202
12371
  confirmation = input(...(ngDevMode ? [undefined, { debugName: "confirmation" }] : /* istanbul ignore next */ []));
12203
12372
  showing = output();
12204
12373
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: ConfirmationDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
12205
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.12", type: ConfirmationDialogComponent, isStandalone: true, selector: "uni-confirmation-dialog", inputs: { show: { classPropertyName: "show", publicName: "show", isSignal: true, isRequired: false, transformFunction: null }, confirmation: { classPropertyName: "confirmation", publicName: "confirmation", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { showing: "showing" }, ngImport: i0, template: "<dialog uni-dialog [show]=\"show()\" (showing)=\"showing.emit($event)\">\n <div uni-dialog-header>\n {{ confirmation()?.title }}\n </div>\n <div box-layout padding=\"md\">\n <span uni-text>\n {{ confirmation()?.message }}\n </span>\n </div>\n <div\n dialog-buttons\n [confirmButtonText]=\"confirmation()?.actionLabel\"\n (confirmed)=\"confirmation()?.action()\"\n [cancelButtonText]=\"confirmation()?.dismissLabel\"\n ></div>\n</dialog>\n", dependencies: [{ kind: "component", type: UniDialogComponent, selector: "dialog[uni-dialog]", inputs: ["show", "ariaLabel", "initialFocus", "defaultCloseButton"], outputs: ["showChange", "showing"] }, { kind: "component", type: UniDialogHeaderComponent, selector: "[uni-dialog-header]" }, { kind: "directive", type: UniBoxDirective, selector: "[uni-box-layout], [box-layout]", inputs: ["containerColor", "backgroundColor", "borderRadius", "borderRadiusLeft", "borderRadiusRight", "borderRadiusTop", "borderRadiusBottom", "padding", "paddingHorizontal", "paddingVertical", "paddingLeft", "paddingRight", "paddingTop", "paddingBottom", "border", "borderTop", "borderBottom", "borderLeft", "borderRight", "dashBorder", "alignSelf", "alignItems", "alignContent", "justifyContent", "grow", "flex", "shrink", "basis", "marginInline", "display", "position", "inset", "height", "minHeight", "maxHeight", "width", "minWidth", "maxWidth", "ignoreDir", "gridArea", "gridColumn", "gridRow", "overflow", "shadow", "gap", "fullWidth", "fullHeight", "flexDirection", "textAlign", "wrapItems", "zIndex"] }, { kind: "directive", type: UniTextDirective, selector: "[uni-text]", inputs: ["uni-text", "typeface", "color", "display", "align", "nowrap", "maxWidth", "ellipsis"] }, { kind: "component", type: UniDialogButtonsComponent, selector: "[uni-dialog-buttons], [dialog-buttons]", inputs: ["confirmButtonText", "confirmButtonVariant", "cancelButtonText", "cancelButtonVariant", "disableConfirm", "padding", "paddingBottom", "justifyContent"], outputs: ["confirmed"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
12374
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.12", type: ConfirmationDialogComponent, isStandalone: true, selector: "uni-confirmation-dialog", inputs: { show: { classPropertyName: "show", publicName: "show", isSignal: true, isRequired: false, transformFunction: null }, confirmation: { classPropertyName: "confirmation", publicName: "confirmation", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { showing: "showing" }, ngImport: i0, template: "<dialog uni-dialog [show]=\"show()\" (showing)=\"showing.emit($event)\">\n <div dialog-header>\n {{ confirmation()?.title }}\n </div>\n <div box-layout padding=\"md\">\n <span uni-text>\n {{ confirmation()?.message }}\n </span>\n </div>\n <div\n dialog-buttons\n [confirmButtonText]=\"confirmation()?.actionLabel\"\n (confirmed)=\"confirmation()?.action()\"\n [cancelButtonText]=\"confirmation()?.dismissLabel\"\n ></div>\n</dialog>\n", dependencies: [{ kind: "component", type: UniDialogComponent, selector: "dialog[uni-dialog]", inputs: ["show", "ariaLabel", "initialFocus", "defaultCloseButton"], outputs: ["showChange", "showing"] }, { kind: "component", type: UniDialogHeaderComponent, selector: "[uni-dialog-header], [dialog-header]" }, { kind: "directive", type: UniBoxDirective, selector: "[uni-box-layout], [box-layout]", inputs: ["containerColor", "backgroundColor", "borderRadius", "borderRadiusLeft", "borderRadiusRight", "borderRadiusTop", "borderRadiusBottom", "padding", "paddingHorizontal", "paddingVertical", "paddingLeft", "paddingRight", "paddingTop", "paddingBottom", "border", "borderTop", "borderBottom", "borderLeft", "borderRight", "dashBorder", "alignSelf", "alignItems", "alignContent", "justifyContent", "grow", "flex", "shrink", "basis", "marginInline", "display", "position", "inset", "height", "minHeight", "maxHeight", "width", "minWidth", "maxWidth", "ignoreDir", "gridArea", "gridColumn", "gridRow", "overflow", "shadow", "gap", "fullWidth", "fullHeight", "flexDirection", "textAlign", "wrapItems", "zIndex"] }, { kind: "directive", type: UniTextDirective, selector: "[uni-text]", inputs: ["uni-text", "typeface", "color", "display", "align", "nowrap", "maxWidth", "ellipsis"] }, { kind: "component", type: UniDialogButtonsComponent, selector: "[uni-dialog-buttons], [dialog-buttons]", inputs: ["confirmButtonText", "confirmButtonVariant", "cancelButtonText", "cancelButtonVariant", "disableConfirm", "padding", "paddingBottom", "justifyContent"], outputs: ["confirmed"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
12206
12375
  }
12207
12376
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: ConfirmationDialogComponent, decorators: [{
12208
12377
  type: Component,
@@ -12212,7 +12381,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImpo
12212
12381
  UniBoxDirective,
12213
12382
  UniTextDirective,
12214
12383
  UniDialogButtonsComponent,
12215
- ], template: "<dialog uni-dialog [show]=\"show()\" (showing)=\"showing.emit($event)\">\n <div uni-dialog-header>\n {{ confirmation()?.title }}\n </div>\n <div box-layout padding=\"md\">\n <span uni-text>\n {{ confirmation()?.message }}\n </span>\n </div>\n <div\n dialog-buttons\n [confirmButtonText]=\"confirmation()?.actionLabel\"\n (confirmed)=\"confirmation()?.action()\"\n [cancelButtonText]=\"confirmation()?.dismissLabel\"\n ></div>\n</dialog>\n" }]
12384
+ ], template: "<dialog uni-dialog [show]=\"show()\" (showing)=\"showing.emit($event)\">\n <div dialog-header>\n {{ confirmation()?.title }}\n </div>\n <div box-layout padding=\"md\">\n <span uni-text>\n {{ confirmation()?.message }}\n </span>\n </div>\n <div\n dialog-buttons\n [confirmButtonText]=\"confirmation()?.actionLabel\"\n (confirmed)=\"confirmation()?.action()\"\n [cancelButtonText]=\"confirmation()?.dismissLabel\"\n ></div>\n</dialog>\n" }]
12216
12385
  }], propDecorators: { show: [{ type: i0.Input, args: [{ isSignal: true, alias: "show", required: false }] }], confirmation: [{ type: i0.Input, args: [{ isSignal: true, alias: "confirmation", required: false }] }], showing: [{ type: i0.Output, args: ["showing"] }] } });
12217
12386
 
12218
12387
  class UniSnackbarComponent extends BaseComponent {