yukit-web 0.6.0 → 0.6.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 CHANGED
@@ -17,17 +17,16 @@ Angular UI component library for Yurest web applications. Built on [Spartan](htt
17
17
 
18
18
  ## Requirements
19
19
 
20
- | Dependency | Version | Notes |
21
- | :---------------------------------------------------------------- | :------ | :------------------------------- |
22
- | [Angular](https://angular.dev/) | 21+ | Standalone APIs, signal inputs |
23
- | [Tailwind CSS](https://tailwindcss.com/) | v4 | Required — see [Setup](#setup) |
24
- | [`@spartan-ng/brain`](https://spartan.ng) | ^1.3.0 | Headless primitives |
25
- | [`@angular/cdk`](https://material.angular.dev/cdk/categories) | ^21.0.0 | Overlays, a11y |
26
- | [`@ng-icons/core`](https://ng-icons.github.io/ng-icons/) + lucide | ^32.2.0 | Icons |
27
- | [`@tanstack/angular-table`](https://tanstack.com/table) | ^9.0.0 | `<yuw-datatable>` |
28
- | `embla-carousel-angular` | ^21.0.0 | Carousel primitives |
29
- | `ngx-scrollbar` | ^19.1.5 | Scroll areas |
30
- | `d3-scale` + `d3-shape` | ^4 / ^3 | Optional, only for `<yuw-chart>` |
20
+ | Dependency | Version | Notes |
21
+ | :---------------------------------------------------------------- | :------ | :----------------------------- |
22
+ | [Angular](https://angular.dev/) | 21+ | Standalone APIs, signal inputs |
23
+ | [Tailwind CSS](https://tailwindcss.com/) | v4 | Required — see [Setup](#setup) |
24
+ | [`@spartan-ng/brain`](https://spartan.ng) | ^1.3.0 | Headless primitives |
25
+ | [`@angular/cdk`](https://material.angular.dev/cdk/categories) | ^21.0.0 | Overlays, a11y |
26
+ | [`@ng-icons/core`](https://ng-icons.github.io/ng-icons/) + lucide | ^32.2.0 | Icons |
27
+ | [`@tanstack/angular-table`](https://tanstack.com/table) | ^9.0.0 | `<yuw-datatable>` |
28
+ | `embla-carousel-angular` | ^21.0.0 | Carousel primitives |
29
+ | `ngx-scrollbar` | ^19.1.5 | Scroll areas |
31
30
 
32
31
  ## Installation
33
32
 
@@ -45,12 +44,6 @@ npm install -D tailwindcss @tailwindcss/postcss tw-animate-css
45
44
 
46
45
  `tw-animate-css` is required because `@spartan-ng/brain/hlm-tailwind-preset.css` imports it.
47
46
 
48
- Apps that draw [charts](#chart) also install their two geometry packages, which no other component needs:
49
-
50
- ```bash
51
- npm install d3-scale d3-shape
52
- ```
53
-
54
47
  ## Setup
55
48
 
56
49
  `yukit-web` does **not** ship compiled component CSS. Its templates carry Tailwind utility classes,
@@ -170,7 +163,6 @@ behave like any other Tailwind color:
170
163
  | `--warning` / `--warning-foreground` | `bg-warning`, `text-warning-foreground`, … |
171
164
  | `--info` / `--info-foreground` | `bg-info`, `text-info-foreground`, … |
172
165
  | `--destructive-foreground` | `text-destructive-foreground` — Spartan defines only `--destructive` and hardcodes `text-white`; Yurest names a contrast color, so the pair is completed. |
173
- | `--chart-1` … `--chart-8` | `bg-chart-1`, `fill-chart-3`, … — the series palette of [`<yuw-chart>`](#chart), each at least 3:1 against the page in light and dark mode. |
174
166
 
175
167
  To override a token, redefine it in your own `:root` _after_ importing the theme.
176
168
 
@@ -305,7 +297,6 @@ neither source silently overrides the other.
305
297
  | [Empty](#empty) | `[yuwEmpty]` | `YuwEmptyImports` |
306
298
  | [Skeleton](#skeleton) | `[yuwSkeleton]` | `YuwSkeletonDirective` |
307
299
  | [Spinner](#spinner) | `yuw-spinner` | `YuwSpinnerComponent` |
308
- | [Chart](#chart) | `yuw-chart` | `YuwChartComponent` (`yukit-web/chart`) |
309
300
  | **Navigation** | | |
310
301
  | [Accordion](#accordion) | `yuw-accordion` | `YuwAccordionImports` |
311
302
  | [Breadcrumb](#breadcrumb) | `yuw-breadcrumb` | `YuwBreadcrumbComponent` |
@@ -1077,84 +1068,6 @@ The spinner inherits its size from the container's font size — wrap it in `tex
1077
1068
 
1078
1069
  ---
1079
1070
 
1080
- ### Chart
1081
-
1082
- Bar, line, area, pie and donut charts drawn as SVG, modelled on shadcn/ui's chart: a `config` names
1083
- each series, gives it a label and a color token, and the tooltip and legend read the same config.
1084
- It lives in its own entry point, so apps that draw no chart never load it nor its `d3-scale` /
1085
- `d3-shape` peers:
1086
-
1087
- ```ts
1088
- import { YuwChartComponent, type YuwChartConfigDto, yuwChartColorAt } from 'yukit-web/chart';
1089
- ```
1090
-
1091
- ```ts
1092
- protected readonly config: YuwChartConfigDto = {
1093
- food: { label: this.translate('purchases.food'), color: 'chart-1' },
1094
- drinks: { label: this.translate('purchases.drinks'), color: 'chart-2' },
1095
- };
1096
- protected readonly rows = [
1097
- { month: '2026-01-01', food: 4200, drinks: 1800 },
1098
- { month: '2026-02-01', food: 3900, drinks: 1650 },
1099
- ];
1100
- protected readonly euros = (value: number) => this.currency.format(value);
1101
- protected readonly month = (value: unknown) => this.monthFormat.format(new Date(String(value)));
1102
- ```
1103
-
1104
- ```html
1105
- <yuw-chart
1106
- kind="bar-stacked"
1107
- class="h-80"
1108
- ariaLabel="Purchases per month"
1109
- emptyText="No purchases in this period"
1110
- categoryKey="month"
1111
- categoryLabel="Month"
1112
- [config]="config"
1113
- [data]="rows"
1114
- [valueFormat]="euros"
1115
- [categoryFormat]="month"
1116
- />
1117
-
1118
- <yuw-chart kind="donut" ariaLabel="Purchases by provider" emptyText="No purchases" [config]="config" [data]="rows" />
1119
- ```
1120
-
1121
- - **Kinds** (`YuwChartKindDto`): `bar`, `bar-stacked`, `bar-horizontal`, `bar-horizontal-stacked`,
1122
- `line`, `area`, `area-stacked`, `pie`, `donut`. Bars group their series unless the kind is
1123
- stacked. Pie and donut draw one slice per series, summing it across every row, so the rows of a
1124
- stacked bar chart give the donut of its totals; for a distribution, pass one row.
1125
- - **Colors** are the `chart-1` … `chart-8` theme tokens, applied as `var(--chart-n)`, so dark mode
1126
- recolors with no redraw. `yuwChartColorAt(index)` cycles through them for a config built from
1127
- data, such as one series per provider.
1128
- - **Formatting is yours.** `valueFormat` and `categoryFormat` turn numbers and categories into the
1129
- text of axes, tooltips and the accessible table; the library hardcodes no locale or currency.
1130
- - **Missing values** (anything that is not a finite number) are gaps, never zeros.
1131
- - **Size**: the chart fills its root, `h-72` by default; set the height with `class`. It redraws
1132
- when its box resizes and draws nothing on the server, where only the accessible table renders.
1133
- - **Accessibility**: the chart is a named figure (`ariaLabel`, optional `description`) with a
1134
- visually hidden data table. The plot is focusable: the arrow keys, Home and End move the tooltip
1135
- across categories or slices, Escape hides it, and the active one is announced politely.
1136
- Transitions respect `prefers-reduced-motion`.
1137
-
1138
- #### Inputs
1139
-
1140
- | Input | Type | Default |
1141
- | :--------------- | :---------------------------------------------------------- | :---------- |
1142
- | `ariaLabel` | `string` — **required**, the accessible name | — |
1143
- | `config` | `YuwChartConfigDto` — **required** | — |
1144
- | `data` | `YuwChartRowDto[]` — **required** | — |
1145
- | `emptyText` | `string` — **required** | — |
1146
- | `kind` | `YuwChartKindDto` | `'bar'` |
1147
- | `categoryKey` | `string|undefined` — cartesian kinds | `undefined` |
1148
- | `categoryLabel` | `string|undefined` — category column header, for the table | `undefined` |
1149
- | `categoryFormat` | `(category: unknown) => string` — cartesian kinds | `String` |
1150
- | `valueFormat` | `(value: number) => string` | `String` |
1151
- | `description` | `string|undefined` — accessible description | `undefined` |
1152
- | `legend` | `boolean` | `true` |
1153
- | `loading` | `boolean` — renders a skeleton and sets `aria-busy` | `false` |
1154
- | `class` | `string` — merged last onto the root | `''` |
1155
-
1156
- ---
1157
-
1158
1071
  ### Accordion
1159
1072
 
1160
1073
  ```html
@@ -26,6 +26,7 @@ import * as i1$3 from '@spartan-ng/brain/combobox';
26
26
  import { BrnComboboxTrigger, BrnComboboxAnchor, BrnComboboxPopoverTrigger, BrnComboboxMultiple, BrnCombobox } from '@spartan-ng/brain/combobox';
27
27
  import * as i1$4 from 'yukit-web/helm/combobox';
28
28
  import { HlmComboboxContent, HlmComboboxImports } from 'yukit-web/helm/combobox';
29
+ import { BrnAccordionItem } from '@spartan-ng/brain/accordion';
29
30
  import { HlmAccordion, HlmAccordionItem, HlmAccordionTrigger, HlmAccordionContent } from 'yukit-web/helm/accordion';
30
31
  import { HlmField, HlmFieldDescription } from 'yukit-web/helm/field';
31
32
  import { HlmInput } from 'yukit-web/helm/input';
@@ -1442,6 +1443,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
1442
1443
  }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-template #footer>\n <ng-content select=\"[yuwComboboxFooter]\" />\n</ng-template>\n\n<ng-template #itemContent let-option>\n @if (itemTemplate(); as custom) {\n <ng-container\n [ngTemplateOutlet]=\"custom.templateRef\"\n [ngTemplateOutletContext]=\"{\n $implicit: option,\n option: option,\n selected: _selectedValues().has(option.value),\n }\"\n />\n } @else {\n {{ option.label }}\n }\n</ng-template>\n\n@if (multiple()) {\n <hlm-combobox-multiple\n [disabled]=\"_disabled()\"\n [value]=\"_multipleValue()\"\n (valueChange)=\"onValueChange($event)\"\n [(search)]=\"search\"\n [itemToString]=\"_itemToString\"\n (focusout)=\"_onFocusOut($event)\"\n >\n @if (triggerTemplate(); as trigger) {\n <yuw-button\n yuwComboboxTriggerButton\n [color]=\"triggerColor()\"\n [variant]=\"triggerVariant()\"\n [size]=\"triggerSize()\"\n [class]=\"triggerClass()\"\n [ariaLabel]=\"triggerAriaLabel()\"\n [disabled]=\"_disabled()\"\n >\n <ng-container [ngTemplateOutlet]=\"trigger.templateRef\" [ngTemplateOutletContext]=\"_triggerContext()\" />\n </yuw-button>\n } @else {\n <hlm-combobox-chips [forceInvalid]=\"invalid()\" [class]=\"_chipsClass()\">\n @for (chip of _selectedChips(); track chip.value) {\n <hlm-combobox-chip [value]=\"chip.value\">{{ chip.label }}</hlm-combobox-chip>\n }\n <input hlmComboboxChipInput [id]=\"_controlId()\" [placeholder]=\"placeholder() ?? ''\" />\n </hlm-combobox-chips>\n }\n\n <hlm-combobox-content *hlmComboboxPortal [class]=\"_contentClass()\">\n @if (_searchInPanel()) {\n <hlm-combobox-input\n [placeholder]=\"searchPlaceholder() ?? ''\"\n [triggerAriaLabel]=\"triggerAriaLabel()\"\n [showTrigger]=\"false\"\n />\n }\n <div hlmComboboxList>\n @for (option of options(); track option.value) {\n <hlm-combobox-item [value]=\"option.value\" [disabled]=\"option.disabled ?? false\">\n <ng-container [ngTemplateOutlet]=\"itemContent\" [ngTemplateOutletContext]=\"{ $implicit: option }\" />\n </hlm-combobox-item>\n }\n </div>\n <hlm-combobox-empty>{{ emptyText() ?? '' }}</hlm-combobox-empty>\n <ng-container [ngTemplateOutlet]=\"footer\" />\n </hlm-combobox-content>\n </hlm-combobox-multiple>\n} @else {\n <hlm-combobox\n [disabled]=\"_disabled()\"\n [value]=\"_singleValue()\"\n (valueChange)=\"onValueChange($event)\"\n [(search)]=\"search\"\n [itemToString]=\"_itemToString\"\n (focusout)=\"_onFocusOut($event)\"\n >\n @if (triggerTemplate(); as trigger) {\n <yuw-button\n yuwComboboxTriggerButton\n [color]=\"triggerColor()\"\n [variant]=\"triggerVariant()\"\n [size]=\"triggerSize()\"\n [class]=\"triggerClass()\"\n [ariaLabel]=\"triggerAriaLabel()\"\n [disabled]=\"_disabled()\"\n >\n <ng-container [ngTemplateOutlet]=\"trigger.templateRef\" [ngTemplateOutletContext]=\"_triggerContext()\" />\n </yuw-button>\n } @else if (readonlyTrigger()) {\n <hlm-combobox-trigger\n [buttonId]=\"_controlId()\"\n [forceInvalid]=\"invalid()\"\n [class]=\"_triggerClass()\"\n class=\"w-full justify-between items-center\"\n >\n <hlm-combobox-value class=\"min-w-0 truncate\" [placeholder]=\"placeholder() ?? ''\" />\n </hlm-combobox-trigger>\n } @else {\n <hlm-combobox-input\n [inputId]=\"_controlId()\"\n [placeholder]=\"placeholder() ?? ''\"\n [showClear]=\"_clearVisible()\"\n [clearAriaLabel]=\"clearAriaLabel() ?? ''\"\n [triggerAriaLabel]=\"triggerAriaLabel()\"\n [forceInvalid]=\"invalid()\"\n [class]=\"_fieldClass()\"\n />\n }\n\n <hlm-combobox-content *hlmComboboxPortal [class]=\"_contentClass()\">\n @if (_searchInPanel()) {\n <hlm-combobox-input\n [placeholder]=\"searchPlaceholder() ?? ''\"\n [showClear]=\"_clearVisible()\"\n [clearAriaLabel]=\"clearAriaLabel() ?? ''\"\n [triggerAriaLabel]=\"triggerAriaLabel()\"\n [showTrigger]=\"false\"\n />\n }\n <div hlmComboboxList>\n @for (option of options(); track option.value) {\n <hlm-combobox-item [value]=\"option.value\" [disabled]=\"option.disabled ?? false\">\n <ng-container [ngTemplateOutlet]=\"itemContent\" [ngTemplateOutletContext]=\"{ $implicit: option }\" />\n </hlm-combobox-item>\n }\n </div>\n <hlm-combobox-empty>{{ emptyText() ?? '' }}</hlm-combobox-empty>\n <ng-container [ngTemplateOutlet]=\"footer\" />\n </hlm-combobox-content>\n </hlm-combobox>\n}\n" }]
1443
1444
  }], ctorParameters: () => [], propDecorators: { _multipleBox: [{ type: i0.ViewChild, args: [i0.forwardRef(() => BrnComboboxMultiple), { isSignal: true }] }], _panel: [{ type: i0.ViewChild, args: [i0.forwardRef(() => HlmComboboxContent), { ...{ read: ElementRef }, isSignal: true }] }], _singleBox: [{ type: i0.ViewChild, args: [i0.forwardRef(() => BrnCombobox), { isSignal: true }] }], itemTemplate: [{ type: i0.ContentChild, args: [i0.forwardRef(() => YuwComboboxItemDirective), { isSignal: true }] }], triggerTemplate: [{ type: i0.ContentChild, args: [i0.forwardRef(() => YuwComboboxTriggerDirective), { isSignal: true }] }], clearAriaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearAriaLabel", required: false }] }], emptyText: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyText", required: false }] }], inputId: [{ type: i0.Input, args: [{ isSignal: true, alias: "inputId", required: false }] }], invalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalid", required: false }] }], keepValueOnEscape: [{ type: i0.Input, args: [{ isSignal: true, alias: "keepValueOnEscape", required: false }] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: true }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], readonlyTrigger: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonlyTrigger", required: false }] }], search: [{ type: i0.Input, args: [{ isSignal: true, alias: "search", required: false }] }, { type: i0.Output, args: ["searchChange"] }], searchPlaceholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchPlaceholder", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], triggerAriaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "triggerAriaLabel", required: true }] }], triggerClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "triggerClass", required: false }] }], triggerColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "triggerColor", required: false }] }], triggerSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "triggerSize", required: false }] }], triggerVariant: [{ type: i0.Input, args: [{ isSignal: true, alias: "triggerVariant", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }] } });
1444
1445
 
1446
+ /**
1447
+ * Open state of the sheet a piece of content is declared in. `<yuw-sheet>` and `<yuws-form-sheet>` provide it, so
1448
+ * content projected into either can react to the panel opening or closing without knowing which one it sits in.
1449
+ */
1450
+ class YuwSheetOpenState {
1451
+ }
1452
+
1445
1453
  /**
1446
1454
  * Container directive for collapsible accordion items.
1447
1455
  *
@@ -1452,6 +1460,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
1452
1460
  * Direct child items (`yuw-accordion-item`) can be declared statically or rendered dynamically
1453
1461
  * using `@for`.
1454
1462
  *
1463
+ * Inputs:
1464
+ * - `collapseWithSheet`: Inside a `<yuw-sheet>` or `<yuws-form-sheet>`, collapses every item whenever the sheet opens
1465
+ * or closes, so each opening starts folded. Ignored outside a sheet. Default is `false`.
1466
+ *
1455
1467
  * Extends `HlmAccordion` (instead of re-applying `BrnAccordion` and copying the helm's classes
1456
1468
  * by hand) so the helm's `data-slot`, classes and its `BrnAccordion` host directive — including
1457
1469
  * the forwarded `type`/`orientation` inputs — are all inherited. Forwarding those inputs through
@@ -1460,15 +1472,29 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
1460
1472
  * `BrnAccordion`.
1461
1473
  */
1462
1474
  class YuwAccordion extends HlmAccordion {
1463
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwAccordion, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
1464
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwAccordion, isStandalone: true, selector: "yuw-accordion", usesInheritance: true, ngImport: i0 }); }
1475
+ constructor() {
1476
+ super();
1477
+ this._sheet = inject(YuwSheetOpenState, { optional: true });
1478
+ this._items = contentChildren(BrnAccordionItem, { ...(ngDevMode ? { debugName: "_items" } : /* istanbul ignore next */ {}), descendants: true });
1479
+ this.collapseWithSheet = input(false, { ...(ngDevMode ? { debugName: "collapseWithSheet" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
1480
+ effect(() => {
1481
+ const sheet = this._sheet;
1482
+ if (!sheet || !this.collapseWithSheet()) {
1483
+ return;
1484
+ }
1485
+ sheet.open();
1486
+ untracked(() => this._items().forEach((item) => item.close()));
1487
+ });
1488
+ }
1489
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwAccordion, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
1490
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.2.0", version: "21.2.22", type: YuwAccordion, isStandalone: true, selector: "yuw-accordion", inputs: { collapseWithSheet: { classPropertyName: "collapseWithSheet", publicName: "collapseWithSheet", isSignal: true, isRequired: false, transformFunction: null } }, queries: [{ propertyName: "_items", predicate: BrnAccordionItem, descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0 }); }
1465
1491
  }
1466
1492
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwAccordion, decorators: [{
1467
1493
  type: Directive,
1468
1494
  args: [{
1469
1495
  selector: 'yuw-accordion',
1470
1496
  }]
1471
- }] });
1497
+ }], ctorParameters: () => [], propDecorators: { _items: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => BrnAccordionItem), { ...{ descendants: true }, isSignal: true }] }], collapseWithSheet: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapseWithSheet", required: false }] }] } });
1472
1498
 
1473
1499
  /**
1474
1500
  * Directive representing an individual section/item within a `yuw-accordion`.
@@ -1503,20 +1529,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
1503
1529
  * Inputs:
1504
1530
  * - `triggerClass`: Extra classes for the inner trigger `<button>`; the helm merges them last
1505
1531
  * (via tailwind-merge), so they win over its defaults.
1532
+ * - `underline`: Underlines the label on hover, as the helm does. Set `underline="false"` for a header whose content
1533
+ * is more than a line of text. Default is `true`.
1506
1534
  */
1507
1535
  class YuwAccordionTriggerComponent {
1508
1536
  constructor() {
1509
1537
  this.triggerClass = input('', ...(ngDevMode ? [{ debugName: "triggerClass" }] : /* istanbul ignore next */ []));
1538
+ this.underline = input(true, { ...(ngDevMode ? { debugName: "underline" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
1539
+ this._triggerClass = computed(() => cn(!this.underline() && 'hover:no-underline', this.triggerClass()), ...(ngDevMode ? [{ debugName: "_triggerClass" }] : /* istanbul ignore next */ []));
1510
1540
  }
1511
1541
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwAccordionTriggerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1512
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.22", type: YuwAccordionTriggerComponent, isStandalone: true, selector: "yuw-accordion-trigger", inputs: { triggerClass: { classPropertyName: "triggerClass", publicName: "triggerClass", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "contents" }, ngImport: i0, template: "<hlm-accordion-trigger [triggerClass]=\"triggerClass()\">\n <ng-content />\n</hlm-accordion-trigger>\n", dependencies: [{ kind: "component", type: HlmAccordionTrigger, selector: "hlm-accordion-trigger", inputs: ["triggerClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1542
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.22", type: YuwAccordionTriggerComponent, isStandalone: true, selector: "yuw-accordion-trigger", inputs: { triggerClass: { classPropertyName: "triggerClass", publicName: "triggerClass", isSignal: true, isRequired: false, transformFunction: null }, underline: { classPropertyName: "underline", publicName: "underline", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "contents" }, ngImport: i0, template: "<hlm-accordion-trigger [triggerClass]=\"_triggerClass()\">\n <ng-content />\n</hlm-accordion-trigger>\n", dependencies: [{ kind: "component", type: HlmAccordionTrigger, selector: "hlm-accordion-trigger", inputs: ["triggerClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1513
1543
  }
1514
1544
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwAccordionTriggerComponent, decorators: [{
1515
1545
  type: Component,
1516
1546
  args: [{ selector: 'yuw-accordion-trigger', imports: [HlmAccordionTrigger], host: {
1517
1547
  class: 'contents',
1518
- }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<hlm-accordion-trigger [triggerClass]=\"triggerClass()\">\n <ng-content />\n</hlm-accordion-trigger>\n" }]
1519
- }], propDecorators: { triggerClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "triggerClass", required: false }] }] } });
1548
+ }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<hlm-accordion-trigger [triggerClass]=\"_triggerClass()\">\n <ng-content />\n</hlm-accordion-trigger>\n" }]
1549
+ }], propDecorators: { triggerClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "triggerClass", required: false }] }], underline: [{ type: i0.Input, args: [{ isSignal: true, alias: "underline", required: false }] }] } });
1520
1550
 
1521
1551
  /**
1522
1552
  * Collapsible panel container for a `yuw-accordion-item`.
@@ -2006,7 +2036,7 @@ class YuwSheetComponent {
2006
2036
  this.open.set(state === 'open');
2007
2037
  }
2008
2038
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwSheetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2009
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: YuwSheetComponent, isStandalone: true, selector: "yuw-sheet", inputs: { ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, ariaModal: { classPropertyName: "ariaModal", publicName: "ariaModal", isSignal: true, isRequired: false, transformFunction: null }, bodyClass: { classPropertyName: "bodyClass", publicName: "bodyClass", isSignal: true, isRequired: false, transformFunction: null }, closeLabel: { classPropertyName: "closeLabel", publicName: "closeLabel", isSignal: true, isRequired: false, transformFunction: null }, closeOnOutsidePointerEvents: { classPropertyName: "closeOnOutsidePointerEvents", publicName: "closeOnOutsidePointerEvents", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, overlayClass: { classPropertyName: "overlayClass", publicName: "overlayClass", isSignal: true, isRequired: false, transformFunction: null }, panelClass: { classPropertyName: "panelClass", publicName: "panelClass", isSignal: true, isRequired: false, transformFunction: null }, scrollStrategy: { classPropertyName: "scrollStrategy", publicName: "scrollStrategy", isSignal: true, isRequired: false, transformFunction: null }, showTrigger: { classPropertyName: "showTrigger", publicName: "showTrigger", isSignal: true, isRequired: false, transformFunction: null }, side: { classPropertyName: "side", publicName: "side", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, triggerSize: { classPropertyName: "triggerSize", publicName: "triggerSize", isSignal: true, isRequired: false, transformFunction: null }, triggerVariant: { classPropertyName: "triggerVariant", publicName: "triggerVariant", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { open: "openChange" }, host: { classAttribute: "contents" }, providers: [provideIcons({ lucideX })], queries: [{ propertyName: "hasFooter", first: true, predicate: YuwSheetFooterDirective, descendants: true, isSignal: true }, { propertyName: "hasHeader", first: true, predicate: YuwSheetHeaderDirective, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "sheet", first: true, predicate: HlmSheet, descendants: true, isSignal: true }], ngImport: i0, template: "<hlm-sheet\n [side]=\"side()\"\n [state]=\"_sheetState()\"\n [aria-label]=\"ariaLabel()\"\n [aria-modal]=\"ariaModal()\"\n [scrollStrategy]=\"scrollStrategy()\"\n [closeOnOutsidePointerEvents]=\"closeOnOutsidePointerEvents()\"\n (stateChanged)=\"onStateChanged($event)\"\n>\n @if (showTrigger()) {\n <yuw-button yuwSheetTriggerButton [variant]=\"triggerVariant()\" [size]=\"triggerSize()\">\n <ng-content select=\"[yuwSheetTrigger]\" />\n </yuw-button>\n }\n\n <hlm-sheet-content *hlmSheetPortal [showCloseButton]=\"false\" [class]=\"panelClass()\">\n @if (title() || description()) {\n <div hlmSheetHeader>\n @if (title()) {\n <h2 hlmSheetTitle>{{ title() }}</h2>\n }\n @if (description()) {\n <p hlmSheetDescription>{{ description() }}</p>\n }\n </div>\n }\n\n @if (hasHeader()) {\n <div class=\"flex items-start gap-3 px-4 pt-6\">\n <div class=\"min-w-0 flex-1\">\n <ng-content select=\"[yuwSheetHeader]\" />\n </div>\n @if (closeLabel()) {\n <ng-container [ngTemplateOutlet]=\"closeButton\" />\n }\n </div>\n }\n\n <div [class]=\"_bodyClass()\">\n <ng-content />\n </div>\n\n @if (hasFooter()) {\n <div hlmSheetFooter>\n <ng-content select=\"[yuwSheetFooter]\" />\n </div>\n }\n\n @if (closeLabel() && !hasHeader()) {\n <div class=\"absolute inset-e-3 top-3\">\n <ng-container [ngTemplateOutlet]=\"closeButton\" />\n </div>\n }\n\n <ng-template #closeButton>\n <yuw-button yuwSheetClose variant=\"ghost\" size=\"icon-sm\">\n <ng-icon name=\"lucideX\" />\n <span class=\"sr-only\">{{ closeLabel() }}</span>\n </yuw-button>\n </ng-template>\n </hlm-sheet-content>\n</hlm-sheet>\n", dependencies: [{ kind: "component", type: i1$9.HlmSheet, selector: "hlm-sheet", exportAs: ["hlmSheet"] }, { kind: "component", type: i1$9.HlmSheetContent, selector: "hlm-sheet-content", inputs: ["showCloseButton"] }, { kind: "directive", type: i1$9.HlmSheetDescription, selector: "[hlmSheetDescription]" }, { kind: "directive", type: i1$9.HlmSheetFooter, selector: "[hlmSheetFooter],hlm-sheet-footer" }, { kind: "directive", type: i1$9.HlmSheetHeader, selector: "[hlmSheetHeader],hlm-sheet-header" }, { kind: "directive", type: i1$9.HlmSheetPortal, selector: "[hlmSheetPortal]" }, { kind: "directive", type: i1$9.HlmSheetTitle, selector: "[hlmSheetTitle]" }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: YuwButtonComponent, selector: "yuw-button", inputs: ["animationDisabled", "ariaLabel", "color", "disabled", "href", "size", "target", "transparent", "type", "class", "variant", "yuwDropdownMenuTrigger"], outputs: ["clicked"] }, { kind: "directive", type: YuwSheetTriggerDirective, selector: "yuw-button[yuwSheetTriggerButton]" }, { kind: "directive", type: YuwSheetCloseDirective, selector: "yuw-button[yuwSheetClose]" }, { kind: "component", type: NgIcon, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2039
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: YuwSheetComponent, isStandalone: true, selector: "yuw-sheet", inputs: { ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, ariaModal: { classPropertyName: "ariaModal", publicName: "ariaModal", isSignal: true, isRequired: false, transformFunction: null }, bodyClass: { classPropertyName: "bodyClass", publicName: "bodyClass", isSignal: true, isRequired: false, transformFunction: null }, closeLabel: { classPropertyName: "closeLabel", publicName: "closeLabel", isSignal: true, isRequired: false, transformFunction: null }, closeOnOutsidePointerEvents: { classPropertyName: "closeOnOutsidePointerEvents", publicName: "closeOnOutsidePointerEvents", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, overlayClass: { classPropertyName: "overlayClass", publicName: "overlayClass", isSignal: true, isRequired: false, transformFunction: null }, panelClass: { classPropertyName: "panelClass", publicName: "panelClass", isSignal: true, isRequired: false, transformFunction: null }, scrollStrategy: { classPropertyName: "scrollStrategy", publicName: "scrollStrategy", isSignal: true, isRequired: false, transformFunction: null }, showTrigger: { classPropertyName: "showTrigger", publicName: "showTrigger", isSignal: true, isRequired: false, transformFunction: null }, side: { classPropertyName: "side", publicName: "side", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, triggerSize: { classPropertyName: "triggerSize", publicName: "triggerSize", isSignal: true, isRequired: false, transformFunction: null }, triggerVariant: { classPropertyName: "triggerVariant", publicName: "triggerVariant", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { open: "openChange" }, host: { classAttribute: "contents" }, providers: [provideIcons({ lucideX }), { provide: YuwSheetOpenState, useExisting: YuwSheetComponent }], queries: [{ propertyName: "hasFooter", first: true, predicate: YuwSheetFooterDirective, descendants: true, isSignal: true }, { propertyName: "hasHeader", first: true, predicate: YuwSheetHeaderDirective, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "sheet", first: true, predicate: HlmSheet, descendants: true, isSignal: true }], ngImport: i0, template: "<hlm-sheet\n [side]=\"side()\"\n [state]=\"_sheetState()\"\n [aria-label]=\"ariaLabel()\"\n [aria-modal]=\"ariaModal()\"\n [scrollStrategy]=\"scrollStrategy()\"\n [closeOnOutsidePointerEvents]=\"closeOnOutsidePointerEvents()\"\n (stateChanged)=\"onStateChanged($event)\"\n>\n @if (showTrigger()) {\n <yuw-button yuwSheetTriggerButton [variant]=\"triggerVariant()\" [size]=\"triggerSize()\">\n <ng-content select=\"[yuwSheetTrigger]\" />\n </yuw-button>\n }\n\n <hlm-sheet-content *hlmSheetPortal [showCloseButton]=\"false\" [class]=\"panelClass()\">\n @if (title() || description()) {\n <div hlmSheetHeader>\n @if (title()) {\n <h2 hlmSheetTitle>{{ title() }}</h2>\n }\n @if (description()) {\n <p hlmSheetDescription>{{ description() }}</p>\n }\n </div>\n }\n\n @if (hasHeader()) {\n <div class=\"flex items-start gap-3 px-4 pt-6\">\n <div class=\"min-w-0 flex-1\">\n <ng-content select=\"[yuwSheetHeader]\" />\n </div>\n @if (closeLabel()) {\n <ng-container [ngTemplateOutlet]=\"closeButton\" />\n }\n </div>\n }\n\n <div [class]=\"_bodyClass()\">\n <ng-content />\n </div>\n\n @if (hasFooter()) {\n <div hlmSheetFooter>\n <ng-content select=\"[yuwSheetFooter]\" />\n </div>\n }\n\n @if (closeLabel() && !hasHeader()) {\n <div class=\"absolute inset-e-3 top-3\">\n <ng-container [ngTemplateOutlet]=\"closeButton\" />\n </div>\n }\n\n <ng-template #closeButton>\n <yuw-button yuwSheetClose variant=\"ghost\" size=\"icon-sm\">\n <ng-icon name=\"lucideX\" />\n <span class=\"sr-only\">{{ closeLabel() }}</span>\n </yuw-button>\n </ng-template>\n </hlm-sheet-content>\n</hlm-sheet>\n", dependencies: [{ kind: "component", type: i1$9.HlmSheet, selector: "hlm-sheet", exportAs: ["hlmSheet"] }, { kind: "component", type: i1$9.HlmSheetContent, selector: "hlm-sheet-content", inputs: ["showCloseButton"] }, { kind: "directive", type: i1$9.HlmSheetDescription, selector: "[hlmSheetDescription]" }, { kind: "directive", type: i1$9.HlmSheetFooter, selector: "[hlmSheetFooter],hlm-sheet-footer" }, { kind: "directive", type: i1$9.HlmSheetHeader, selector: "[hlmSheetHeader],hlm-sheet-header" }, { kind: "directive", type: i1$9.HlmSheetPortal, selector: "[hlmSheetPortal]" }, { kind: "directive", type: i1$9.HlmSheetTitle, selector: "[hlmSheetTitle]" }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: YuwButtonComponent, selector: "yuw-button", inputs: ["animationDisabled", "ariaLabel", "color", "disabled", "href", "size", "target", "transparent", "type", "class", "variant", "yuwDropdownMenuTrigger"], outputs: ["clicked"] }, { kind: "directive", type: YuwSheetTriggerDirective, selector: "yuw-button[yuwSheetTriggerButton]" }, { kind: "directive", type: YuwSheetCloseDirective, selector: "yuw-button[yuwSheetClose]" }, { kind: "component", type: NgIcon, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2010
2040
  }
2011
2041
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwSheetComponent, decorators: [{
2012
2042
  type: Component,
@@ -2017,7 +2047,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
2017
2047
  YuwSheetTriggerDirective,
2018
2048
  YuwSheetCloseDirective,
2019
2049
  NgIcon,
2020
- ], providers: [provideIcons({ lucideX })], host: {
2050
+ ], providers: [provideIcons({ lucideX }), { provide: YuwSheetOpenState, useExisting: YuwSheetComponent }], host: {
2021
2051
  class: 'contents',
2022
2052
  }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<hlm-sheet\n [side]=\"side()\"\n [state]=\"_sheetState()\"\n [aria-label]=\"ariaLabel()\"\n [aria-modal]=\"ariaModal()\"\n [scrollStrategy]=\"scrollStrategy()\"\n [closeOnOutsidePointerEvents]=\"closeOnOutsidePointerEvents()\"\n (stateChanged)=\"onStateChanged($event)\"\n>\n @if (showTrigger()) {\n <yuw-button yuwSheetTriggerButton [variant]=\"triggerVariant()\" [size]=\"triggerSize()\">\n <ng-content select=\"[yuwSheetTrigger]\" />\n </yuw-button>\n }\n\n <hlm-sheet-content *hlmSheetPortal [showCloseButton]=\"false\" [class]=\"panelClass()\">\n @if (title() || description()) {\n <div hlmSheetHeader>\n @if (title()) {\n <h2 hlmSheetTitle>{{ title() }}</h2>\n }\n @if (description()) {\n <p hlmSheetDescription>{{ description() }}</p>\n }\n </div>\n }\n\n @if (hasHeader()) {\n <div class=\"flex items-start gap-3 px-4 pt-6\">\n <div class=\"min-w-0 flex-1\">\n <ng-content select=\"[yuwSheetHeader]\" />\n </div>\n @if (closeLabel()) {\n <ng-container [ngTemplateOutlet]=\"closeButton\" />\n }\n </div>\n }\n\n <div [class]=\"_bodyClass()\">\n <ng-content />\n </div>\n\n @if (hasFooter()) {\n <div hlmSheetFooter>\n <ng-content select=\"[yuwSheetFooter]\" />\n </div>\n }\n\n @if (closeLabel() && !hasHeader()) {\n <div class=\"absolute inset-e-3 top-3\">\n <ng-container [ngTemplateOutlet]=\"closeButton\" />\n </div>\n }\n\n <ng-template #closeButton>\n <yuw-button yuwSheetClose variant=\"ghost\" size=\"icon-sm\">\n <ng-icon name=\"lucideX\" />\n <span class=\"sr-only\">{{ closeLabel() }}</span>\n </yuw-button>\n </ng-template>\n </hlm-sheet-content>\n</hlm-sheet>\n" }]
2023
2053
  }], ctorParameters: () => [], propDecorators: { hasFooter: [{ type: i0.ContentChild, args: [i0.forwardRef(() => YuwSheetFooterDirective), { isSignal: true }] }], hasHeader: [{ type: i0.ContentChild, args: [i0.forwardRef(() => YuwSheetHeaderDirective), { isSignal: true }] }], sheet: [{ type: i0.ViewChild, args: [i0.forwardRef(() => HlmSheet), { isSignal: true }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], ariaModal: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaModal", required: false }] }], bodyClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "bodyClass", required: false }] }], closeLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeLabel", required: false }] }], closeOnOutsidePointerEvents: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnOutsidePointerEvents", required: false }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }], open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }, { type: i0.Output, args: ["openChange"] }], overlayClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "overlayClass", required: false }] }], panelClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "panelClass", required: false }] }], scrollStrategy: [{ type: i0.Input, args: [{ isSignal: true, alias: "scrollStrategy", required: false }] }], showTrigger: [{ type: i0.Input, args: [{ isSignal: true, alias: "showTrigger", required: false }] }], side: [{ type: i0.Input, args: [{ isSignal: true, alias: "side", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], triggerSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "triggerSize", required: false }] }], triggerVariant: [{ type: i0.Input, args: [{ isSignal: true, alias: "triggerVariant", required: false }] }] } });
@@ -5164,7 +5194,7 @@ const yuwStepIndicatorVariants = cva('flex size-8 shrink-0 items-center justify-
5164
5194
  },
5165
5195
  },
5166
5196
  });
5167
- const yuwStepTriggerVariants = cva('flex items-center gap-3 rounded-md text-left outline-none transition-colors focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-default', {
5197
+ const yuwStepTriggerVariants = cva('flex items-center gap-3 rounded-full text-left outline-none transition-colors focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-default', {
5168
5198
  variants: {
5169
5199
  state: {
5170
5200
  completed: 'text-(--neutrals-element-high)',
@@ -5213,6 +5243,15 @@ const yuwStepVariants = cva('flex', {
5213
5243
  },
5214
5244
  },
5215
5245
  });
5246
+ /** Entrance of a step's panel, sliding in from the side the user moved towards; off for reduced motion. */
5247
+ const yuwStepPanelVariants = cva('min-w-0 flex-1 animate-in fade-in duration-200 motion-reduce:animate-none', {
5248
+ variants: {
5249
+ direction: {
5250
+ forward: 'slide-in-from-right-2',
5251
+ backward: 'slide-in-from-left-2',
5252
+ },
5253
+ },
5254
+ });
5216
5255
 
5217
5256
  const TOOLTIP_POSITION = {
5218
5257
  horizontal: 'top',
@@ -5223,7 +5262,8 @@ const TOOLTIP_POSITION = {
5223
5262
  *
5224
5263
  * Steps come from the `steps` input; each panel is an `<ng-template yuwStepPanel="<id>">` whose id matches a step.
5225
5264
  * A horizontal header that does not fit scrolls sideways (touch, trackpad, mouse wheel or drag), its edges fading out.
5226
- * Only the active panel is rendered, so state that must survive a step change belongs to the parent (a form group).
5265
+ * Only the active panel is rendered, so state that must survive a step change belongs to the parent (a form group). It
5266
+ * slides in from the side the user moved towards, through `tw-animate-css`, which the Spartan preset already requires.
5227
5267
  * Navigation buttons are the consumer's: grab the stepper with a template reference and call `next()` / `previous()`,
5228
5268
  * disabling them with `hasNext()` / `hasPrevious()`.
5229
5269
  *
@@ -5237,6 +5277,10 @@ const TOOLTIP_POSITION = {
5237
5277
  * - `color`: Accent of the active and completed steps (any `YuwColorDto`). Default is `'primary'`.
5238
5278
  * - `class`: Extra classes merged last onto the root element.
5239
5279
  *
5280
+ * Outputs:
5281
+ * - `stepChange`: Emits the step the user moved to (`YuwStepChangeDto`, the step and its index), from the header or
5282
+ * `next()` / `previous()`. Not emitted when the parent sets `activeStep` itself.
5283
+ *
5240
5284
  * Content:
5241
5285
  * - `<ng-template yuwStepIndicator let-state let-step="step" let-index="index">` replaces the number/check inside
5242
5286
  * every indicator.
@@ -5264,9 +5308,11 @@ class YuwStepperComponent {
5264
5308
  this.orientation = input('horizontal', ...(ngDevMode ? [{ debugName: "orientation" }] : /* istanbul ignore next */ []));
5265
5309
  this.steps = input.required(...(ngDevMode ? [{ debugName: "steps" }] : /* istanbul ignore next */ []));
5266
5310
  this.userClass = input('', { ...(ngDevMode ? { debugName: "userClass" } : /* istanbul ignore next */ {}), alias: 'class' });
5311
+ this.stepChange = output();
5267
5312
  this._activePanel = computed(() => {
5268
5313
  const active = this.activeStep();
5269
- return this.panels().find((panel) => panel.stepId() === active)?.templateRef;
5314
+ const panel = this.panels().find((candidate) => candidate.stepId() === active);
5315
+ return panel ? [{ id: active, templateRef: panel.templateRef }] : [];
5270
5316
  }, ...(ngDevMode ? [{ debugName: "_activePanel" }] : /* istanbul ignore next */ []));
5271
5317
  this._activeTriggerId = computed(() => `${this._idPrefix}-${this.activeStep()}`, ...(ngDevMode ? [{ debugName: "_activeTriggerId" }] : /* istanbul ignore next */ []));
5272
5318
  this.activeIndex = computed(() => this.steps().findIndex((step) => step.id === this.activeStep()), ...(ngDevMode ? [{ debugName: "activeIndex" }] : /* istanbul ignore next */ []));
@@ -5283,6 +5329,11 @@ class YuwStepperComponent {
5283
5329
  }, ...(ngDevMode ? [{ debugName: "_items" }] : /* istanbul ignore next */ []));
5284
5330
  this._labelClass = computed(() => (this.iconOnly() ? 'sr-only' : 'flex flex-col'), ...(ngDevMode ? [{ debugName: "_labelClass" }] : /* istanbul ignore next */ []));
5285
5331
  this._listClass = computed(() => yuwStepListVariants({ orientation: this.orientation() }), ...(ngDevMode ? [{ debugName: "_listClass" }] : /* istanbul ignore next */ []));
5332
+ this._panelClass = linkedSignal({ ...(ngDevMode ? { debugName: "_panelClass" } : /* istanbul ignore next */ {}), source: () => this.activeIndex(),
5333
+ computation: (index, previous) => {
5334
+ const direction = previous && index < previous.source ? 'backward' : 'forward';
5335
+ return yuwStepPanelVariants({ direction });
5336
+ } });
5286
5337
  this._rootClass = computed(() => cn(yuwStepperLayoutVariants({ orientation: this.orientation() }), this.userClass()), ...(ngDevMode ? [{ debugName: "_rootClass" }] : /* istanbul ignore next */ []));
5287
5338
  this._stepClass = computed(() => yuwStepVariants({ orientation: this.orientation() }), ...(ngDevMode ? [{ debugName: "_stepClass" }] : /* istanbul ignore next */ []));
5288
5339
  this._tooltipPosition = computed(() => TOOLTIP_POSITION[this.orientation()], ...(ngDevMode ? [{ debugName: "_tooltipPosition" }] : /* istanbul ignore next */ []));
@@ -5301,12 +5352,16 @@ class YuwStepperComponent {
5301
5352
  this._goTo(this._neighbour(-1));
5302
5353
  }
5303
5354
  select(id) {
5304
- this.activeStep.set(id);
5355
+ this._goTo(id);
5305
5356
  }
5306
5357
  _goTo(id) {
5307
- if (id !== undefined) {
5308
- this.activeStep.set(id);
5358
+ const index = this.steps().findIndex((step) => step.id === id);
5359
+ const step = this.steps()[index];
5360
+ if (!step || step.id === this.activeStep()) {
5361
+ return;
5309
5362
  }
5363
+ this.activeStep.set(step.id);
5364
+ this.stepChange.emit({ step, index });
5310
5365
  }
5311
5366
  /** Closest reachable step in `direction`, skipping disabled ones. */
5312
5367
  _neighbour(direction) {
@@ -5338,14 +5393,14 @@ class YuwStepperComponent {
5338
5393
  });
5339
5394
  }
5340
5395
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwStepperComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
5341
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: YuwStepperComponent, isStandalone: true, selector: "yuw-stepper", inputs: { activeStep: { classPropertyName: "activeStep", publicName: "activeStep", isSignal: true, isRequired: true, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, iconOnly: { classPropertyName: "iconOnly", publicName: "iconOnly", isSignal: true, isRequired: false, transformFunction: null }, linear: { classPropertyName: "linear", publicName: "linear", isSignal: true, isRequired: false, transformFunction: null }, orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null }, steps: { classPropertyName: "steps", publicName: "steps", isSignal: true, isRequired: true, transformFunction: null }, userClass: { classPropertyName: "userClass", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { activeStep: "activeStepChange" }, host: { classAttribute: "contents" }, providers: [provideIcons({ lucideCheck })], queries: [{ propertyName: "indicator", first: true, predicate: YuwStepIndicatorDirective, descendants: true, isSignal: true }, { propertyName: "panels", predicate: YuwStepPanelDirective, isSignal: true }], viewQueries: [{ propertyName: "_list", first: true, predicate: ["list"], descendants: true, isSignal: true }], ngImport: i0, template: "<div [class]=\"_rootClass()\">\n <ol #list yuwMouseScrollX [class]=\"_listClass()\" [attr.data-yuw-color]=\"color()\">\n @for (item of _items(); track item.step.id; let last = $last) {\n <li [class]=\"_stepClass()\">\n <button\n type=\"button\"\n [id]=\"item.triggerId\"\n [class]=\"item.triggerClass\"\n [disabled]=\"!item.reachable\"\n [attr.aria-current]=\"item.ariaCurrent\"\n [yuwTooltip]=\"item.step.label\"\n [tooltipDisabled]=\"!iconOnly()\"\n [position]=\"_tooltipPosition()\"\n (click)=\"select(item.step.id)\"\n >\n <span [class]=\"item.indicatorClass\">\n @if (indicator(); as custom) {\n <ng-container [ngTemplateOutlet]=\"custom.templateRef\" [ngTemplateOutletContext]=\"item.context\" />\n } @else if (item.state === 'completed') {\n <ng-icon name=\"lucideCheck\" aria-hidden=\"true\" />\n } @else {\n {{ item.index + 1 }}\n }\n </span>\n <span [class]=\"_labelClass()\">\n <span class=\"text-sm font-medium\">{{ item.step.label }}</span>\n @if (item.step.description) {\n <span class=\"text-xs text-muted-foreground\">{{ item.step.description }}</span>\n }\n </span>\n </button>\n @if (!last) {\n <span [class]=\"item.separatorClass\" aria-hidden=\"true\"></span>\n }\n </li>\n }\n </ol>\n\n @if (_activePanel(); as panel) {\n <div role=\"region\" class=\"min-w-0 flex-1\" [attr.aria-labelledby]=\"_activeTriggerId()\">\n <ng-container [ngTemplateOutlet]=\"panel\" />\n </div>\n }\n</div>\n", dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: NgIcon, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }, { kind: "directive", type: YuwMouseScrollXDirective, selector: "[yuwMouseScrollX]" }, { kind: "directive", type: YuwTooltipDirective, selector: "[yuwTooltip]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
5396
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: YuwStepperComponent, isStandalone: true, selector: "yuw-stepper", inputs: { activeStep: { classPropertyName: "activeStep", publicName: "activeStep", isSignal: true, isRequired: true, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, iconOnly: { classPropertyName: "iconOnly", publicName: "iconOnly", isSignal: true, isRequired: false, transformFunction: null }, linear: { classPropertyName: "linear", publicName: "linear", isSignal: true, isRequired: false, transformFunction: null }, orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null }, steps: { classPropertyName: "steps", publicName: "steps", isSignal: true, isRequired: true, transformFunction: null }, userClass: { classPropertyName: "userClass", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { activeStep: "activeStepChange", stepChange: "stepChange" }, host: { classAttribute: "contents" }, providers: [provideIcons({ lucideCheck })], queries: [{ propertyName: "indicator", first: true, predicate: YuwStepIndicatorDirective, descendants: true, isSignal: true }, { propertyName: "panels", predicate: YuwStepPanelDirective, isSignal: true }], viewQueries: [{ propertyName: "_list", first: true, predicate: ["list"], descendants: true, isSignal: true }], ngImport: i0, template: "<div [class]=\"_rootClass()\">\n <ol #list yuwMouseScrollX [class]=\"_listClass()\" [attr.data-yuw-color]=\"color()\">\n @for (item of _items(); track item.step.id; let last = $last) {\n <li [class]=\"_stepClass()\">\n <button\n type=\"button\"\n [id]=\"item.triggerId\"\n [class]=\"item.triggerClass\"\n [disabled]=\"!item.reachable\"\n [attr.aria-current]=\"item.ariaCurrent\"\n [yuwTooltip]=\"item.step.label\"\n [tooltipDisabled]=\"!iconOnly()\"\n [position]=\"_tooltipPosition()\"\n (click)=\"select(item.step.id)\"\n >\n <span [class]=\"item.indicatorClass\">\n @if (indicator(); as custom) {\n <ng-container [ngTemplateOutlet]=\"custom.templateRef\" [ngTemplateOutletContext]=\"item.context\" />\n } @else if (item.state === 'completed') {\n <ng-icon name=\"lucideCheck\" aria-hidden=\"true\" />\n } @else {\n {{ item.index + 1 }}\n }\n </span>\n <span [class]=\"_labelClass()\">\n <span class=\"text-sm font-medium\">{{ item.step.label }}</span>\n @if (item.step.description) {\n <span class=\"text-xs text-muted-foreground\">{{ item.step.description }}</span>\n }\n </span>\n </button>\n @if (!last) {\n <span [class]=\"item.separatorClass\" aria-hidden=\"true\"></span>\n }\n </li>\n }\n </ol>\n\n @for (panel of _activePanel(); track panel.id) {\n <div role=\"region\" [class]=\"_panelClass()\" [attr.aria-labelledby]=\"_activeTriggerId()\">\n <ng-container [ngTemplateOutlet]=\"panel.templateRef\" />\n </div>\n }\n</div>\n", dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: NgIcon, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }, { kind: "directive", type: YuwMouseScrollXDirective, selector: "[yuwMouseScrollX]" }, { kind: "directive", type: YuwTooltipDirective, selector: "[yuwTooltip]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
5342
5397
  }
5343
5398
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwStepperComponent, decorators: [{
5344
5399
  type: Component,
5345
5400
  args: [{ selector: 'yuw-stepper', imports: [NgTemplateOutlet, NgIcon, YuwMouseScrollXDirective, YuwTooltipDirective], providers: [provideIcons({ lucideCheck })], host: {
5346
5401
  class: 'contents',
5347
- }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [class]=\"_rootClass()\">\n <ol #list yuwMouseScrollX [class]=\"_listClass()\" [attr.data-yuw-color]=\"color()\">\n @for (item of _items(); track item.step.id; let last = $last) {\n <li [class]=\"_stepClass()\">\n <button\n type=\"button\"\n [id]=\"item.triggerId\"\n [class]=\"item.triggerClass\"\n [disabled]=\"!item.reachable\"\n [attr.aria-current]=\"item.ariaCurrent\"\n [yuwTooltip]=\"item.step.label\"\n [tooltipDisabled]=\"!iconOnly()\"\n [position]=\"_tooltipPosition()\"\n (click)=\"select(item.step.id)\"\n >\n <span [class]=\"item.indicatorClass\">\n @if (indicator(); as custom) {\n <ng-container [ngTemplateOutlet]=\"custom.templateRef\" [ngTemplateOutletContext]=\"item.context\" />\n } @else if (item.state === 'completed') {\n <ng-icon name=\"lucideCheck\" aria-hidden=\"true\" />\n } @else {\n {{ item.index + 1 }}\n }\n </span>\n <span [class]=\"_labelClass()\">\n <span class=\"text-sm font-medium\">{{ item.step.label }}</span>\n @if (item.step.description) {\n <span class=\"text-xs text-muted-foreground\">{{ item.step.description }}</span>\n }\n </span>\n </button>\n @if (!last) {\n <span [class]=\"item.separatorClass\" aria-hidden=\"true\"></span>\n }\n </li>\n }\n </ol>\n\n @if (_activePanel(); as panel) {\n <div role=\"region\" class=\"min-w-0 flex-1\" [attr.aria-labelledby]=\"_activeTriggerId()\">\n <ng-container [ngTemplateOutlet]=\"panel\" />\n </div>\n }\n</div>\n" }]
5348
- }], ctorParameters: () => [], propDecorators: { _list: [{ type: i0.ViewChild, args: ['list', { isSignal: true }] }], indicator: [{ type: i0.ContentChild, args: [i0.forwardRef(() => YuwStepIndicatorDirective), { isSignal: true }] }], panels: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => YuwStepPanelDirective), { isSignal: true }] }], activeStep: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeStep", required: true }] }, { type: i0.Output, args: ["activeStepChange"] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], iconOnly: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconOnly", required: false }] }], linear: [{ type: i0.Input, args: [{ isSignal: true, alias: "linear", required: false }] }], orientation: [{ type: i0.Input, args: [{ isSignal: true, alias: "orientation", required: false }] }], steps: [{ type: i0.Input, args: [{ isSignal: true, alias: "steps", required: true }] }], userClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }] } });
5402
+ }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [class]=\"_rootClass()\">\n <ol #list yuwMouseScrollX [class]=\"_listClass()\" [attr.data-yuw-color]=\"color()\">\n @for (item of _items(); track item.step.id; let last = $last) {\n <li [class]=\"_stepClass()\">\n <button\n type=\"button\"\n [id]=\"item.triggerId\"\n [class]=\"item.triggerClass\"\n [disabled]=\"!item.reachable\"\n [attr.aria-current]=\"item.ariaCurrent\"\n [yuwTooltip]=\"item.step.label\"\n [tooltipDisabled]=\"!iconOnly()\"\n [position]=\"_tooltipPosition()\"\n (click)=\"select(item.step.id)\"\n >\n <span [class]=\"item.indicatorClass\">\n @if (indicator(); as custom) {\n <ng-container [ngTemplateOutlet]=\"custom.templateRef\" [ngTemplateOutletContext]=\"item.context\" />\n } @else if (item.state === 'completed') {\n <ng-icon name=\"lucideCheck\" aria-hidden=\"true\" />\n } @else {\n {{ item.index + 1 }}\n }\n </span>\n <span [class]=\"_labelClass()\">\n <span class=\"text-sm font-medium\">{{ item.step.label }}</span>\n @if (item.step.description) {\n <span class=\"text-xs text-muted-foreground\">{{ item.step.description }}</span>\n }\n </span>\n </button>\n @if (!last) {\n <span [class]=\"item.separatorClass\" aria-hidden=\"true\"></span>\n }\n </li>\n }\n </ol>\n\n @for (panel of _activePanel(); track panel.id) {\n <div role=\"region\" [class]=\"_panelClass()\" [attr.aria-labelledby]=\"_activeTriggerId()\">\n <ng-container [ngTemplateOutlet]=\"panel.templateRef\" />\n </div>\n }\n</div>\n" }]
5403
+ }], ctorParameters: () => [], propDecorators: { _list: [{ type: i0.ViewChild, args: ['list', { isSignal: true }] }], indicator: [{ type: i0.ContentChild, args: [i0.forwardRef(() => YuwStepIndicatorDirective), { isSignal: true }] }], panels: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => YuwStepPanelDirective), { isSignal: true }] }], activeStep: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeStep", required: true }] }, { type: i0.Output, args: ["activeStepChange"] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], iconOnly: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconOnly", required: false }] }], linear: [{ type: i0.Input, args: [{ isSignal: true, alias: "linear", required: false }] }], orientation: [{ type: i0.Input, args: [{ isSignal: true, alias: "orientation", required: false }] }], steps: [{ type: i0.Input, args: [{ isSignal: true, alias: "steps", required: true }] }], userClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], stepChange: [{ type: i0.Output, args: ["stepChange"] }] } });
5349
5404
 
5350
5405
  /**
5351
5406
  * Container directive for a single file attachment card.
@@ -7383,11 +7438,17 @@ class YuwsFormSheetComponent {
7383
7438
  }
7384
7439
  }
7385
7440
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwsFormSheetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
7386
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: YuwsFormSheetComponent, isStandalone: true, selector: "yuws-form-sheet", inputs: { backLabel: { classPropertyName: "backLabel", publicName: "backLabel", isSignal: true, isRequired: false, transformFunction: null }, errorMessage: { classPropertyName: "errorMessage", publicName: "errorMessage", isSignal: true, isRequired: false, transformFunction: null }, hideFooter: { classPropertyName: "hideFooter", publicName: "hideFooter", isSignal: true, isRequired: false, transformFunction: null }, labels: { classPropertyName: "labels", publicName: "labels", isSignal: true, isRequired: true, transformFunction: null }, open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: true, transformFunction: null }, panelClass: { classPropertyName: "panelClass", publicName: "panelClass", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, removeDisabled: { classPropertyName: "removeDisabled", publicName: "removeDisabled", isSignal: true, isRequired: false, transformFunction: null }, removeLabel: { classPropertyName: "removeLabel", publicName: "removeLabel", isSignal: true, isRequired: false, transformFunction: null }, restoreLabel: { classPropertyName: "restoreLabel", publicName: "restoreLabel", isSignal: true, isRequired: false, transformFunction: null }, saveDisabled: { classPropertyName: "saveDisabled", publicName: "saveDisabled", isSignal: true, isRequired: false, transformFunction: null }, saving: { classPropertyName: "saving", publicName: "saving", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { open: "openChange", back: "back", remove: "remove", restore: "restore", save: "save" }, providers: [provideIcons({ lucideArchiveRestore, lucideArrowLeft, lucideSave, lucideTrash2, lucideX })], ngImport: i0, template: "<yuw-sheet\n side=\"right\"\n [showTrigger]=\"false\"\n [panelClass]=\"panelClass()\"\n bodyClass=\"scroll-fade-y\"\n [title]=\"backLabel() ? undefined : title()\"\n [closeLabel]=\"backLabel() ? undefined : labels().close\"\n [(open)]=\"open\"\n>\n @if (backLabel(); as label) {\n <div yuwSheetHeader class=\"-ml-2 -mt-3 flex items-center gap-1 pb-3\">\n <yuw-button type=\"button\" variant=\"ghost\" size=\"icon-sm\" [ariaLabel]=\"label\" (clicked)=\"back.emit()\">\n <ng-icon name=\"lucideArrowLeft\" size=\"16\" />\n </yuw-button>\n <h2 class=\"text-base font-medium text-foreground\">{{ title() }}</h2>\n </div>\n }\n\n <ng-content />\n\n <div\n yuwSheetFooter\n class=\"flex flex-wrap items-center justify-between gap-2\"\n [style.display]=\"hideFooter() ? 'none' : null\"\n [attr.aria-busy]=\"saving()\"\n >\n @if (errorMessage(); as message) {\n <p role=\"alert\" class=\"w-full rounded-md bg-destructive/10 px-3 py-2 text-sm text-destructive\">{{ message }}</p>\n }\n\n @if (removeLabel(); as label) {\n <yuw-button\n variant=\"ghost\"\n color=\"destructive\"\n class=\"gap-2\"\n [disabled]=\"removeDisabled() || saving()\"\n (clicked)=\"remove.emit()\"\n >\n <ng-icon name=\"lucideTrash2\" size=\"16\" />\n {{ label }}\n </yuw-button>\n }\n\n <span class=\"ms-auto flex gap-2\">\n <yuw-button variant=\"outline\" (clicked)=\"onCancel()\">\n <ng-icon name=\"lucideX\" size=\"16\" />\n {{ labels().cancel }}\n </yuw-button>\n @if (restoreLabel(); as label) {\n <yuw-button color=\"primary\" [disabled]=\"saving()\" (clicked)=\"restore.emit()\">\n <ng-icon name=\"lucideArchiveRestore\" size=\"16\" />\n {{ label }}\n </yuw-button>\n }\n @if (!readonly()) {\n <yuw-button color=\"primary\" [disabled]=\"saveDisabled() || saving()\" (clicked)=\"save.emit()\">\n <ng-icon name=\"lucideSave\" size=\"16\" />\n {{ labels().save }}\n </yuw-button>\n }\n </span>\n </div>\n</yuw-sheet>\n", dependencies: [{ kind: "component", type: NgIcon, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }, { kind: "component", type: YuwButtonComponent, selector: "yuw-button", inputs: ["animationDisabled", "ariaLabel", "color", "disabled", "href", "size", "target", "transparent", "type", "class", "variant", "yuwDropdownMenuTrigger"], outputs: ["clicked"] }, { kind: "component", type: YuwSheetComponent, selector: "yuw-sheet", inputs: ["ariaLabel", "ariaModal", "bodyClass", "closeLabel", "closeOnOutsidePointerEvents", "description", "open", "overlayClass", "panelClass", "scrollStrategy", "showTrigger", "side", "title", "triggerSize", "triggerVariant"], outputs: ["openChange"] }, { kind: "directive", type: YuwSheetFooterDirective, selector: "[yuwSheetFooter]" }, { kind: "directive", type: YuwSheetHeaderDirective, selector: "[yuwSheetHeader]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
7441
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: YuwsFormSheetComponent, isStandalone: true, selector: "yuws-form-sheet", inputs: { backLabel: { classPropertyName: "backLabel", publicName: "backLabel", isSignal: true, isRequired: false, transformFunction: null }, errorMessage: { classPropertyName: "errorMessage", publicName: "errorMessage", isSignal: true, isRequired: false, transformFunction: null }, hideFooter: { classPropertyName: "hideFooter", publicName: "hideFooter", isSignal: true, isRequired: false, transformFunction: null }, labels: { classPropertyName: "labels", publicName: "labels", isSignal: true, isRequired: true, transformFunction: null }, open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: true, transformFunction: null }, panelClass: { classPropertyName: "panelClass", publicName: "panelClass", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, removeDisabled: { classPropertyName: "removeDisabled", publicName: "removeDisabled", isSignal: true, isRequired: false, transformFunction: null }, removeLabel: { classPropertyName: "removeLabel", publicName: "removeLabel", isSignal: true, isRequired: false, transformFunction: null }, restoreLabel: { classPropertyName: "restoreLabel", publicName: "restoreLabel", isSignal: true, isRequired: false, transformFunction: null }, saveDisabled: { classPropertyName: "saveDisabled", publicName: "saveDisabled", isSignal: true, isRequired: false, transformFunction: null }, saving: { classPropertyName: "saving", publicName: "saving", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { open: "openChange", back: "back", remove: "remove", restore: "restore", save: "save" }, providers: [
7442
+ provideIcons({ lucideArchiveRestore, lucideArrowLeft, lucideSave, lucideTrash2, lucideX }),
7443
+ { provide: YuwSheetOpenState, useExisting: YuwsFormSheetComponent },
7444
+ ], ngImport: i0, template: "<yuw-sheet\n side=\"right\"\n [showTrigger]=\"false\"\n [panelClass]=\"panelClass()\"\n bodyClass=\"scroll-fade-y\"\n [title]=\"backLabel() ? undefined : title()\"\n [closeLabel]=\"backLabel() ? undefined : labels().close\"\n [(open)]=\"open\"\n>\n @if (backLabel(); as label) {\n <div yuwSheetHeader class=\"-ml-2 -mt-3 flex items-center gap-1 pb-3\">\n <yuw-button type=\"button\" variant=\"ghost\" size=\"icon-sm\" [ariaLabel]=\"label\" (clicked)=\"back.emit()\">\n <ng-icon name=\"lucideArrowLeft\" size=\"16\" />\n </yuw-button>\n <h2 class=\"text-base font-medium text-foreground\">{{ title() }}</h2>\n </div>\n }\n\n <ng-content />\n\n <div\n yuwSheetFooter\n class=\"flex flex-wrap items-center justify-between gap-2\"\n [style.display]=\"hideFooter() ? 'none' : null\"\n [attr.aria-busy]=\"saving()\"\n >\n @if (errorMessage(); as message) {\n <p role=\"alert\" class=\"w-full rounded-md bg-destructive/10 px-3 py-2 text-sm text-destructive\">{{ message }}</p>\n }\n\n @if (removeLabel(); as label) {\n <yuw-button\n variant=\"ghost\"\n color=\"destructive\"\n class=\"gap-2\"\n [disabled]=\"removeDisabled() || saving()\"\n (clicked)=\"remove.emit()\"\n >\n <ng-icon name=\"lucideTrash2\" size=\"16\" />\n {{ label }}\n </yuw-button>\n }\n\n <span class=\"ms-auto flex gap-2\">\n <yuw-button variant=\"outline\" (clicked)=\"onCancel()\">\n <ng-icon name=\"lucideX\" size=\"16\" />\n {{ labels().cancel }}\n </yuw-button>\n @if (restoreLabel(); as label) {\n <yuw-button color=\"primary\" [disabled]=\"saving()\" (clicked)=\"restore.emit()\">\n <ng-icon name=\"lucideArchiveRestore\" size=\"16\" />\n {{ label }}\n </yuw-button>\n }\n @if (!readonly()) {\n <yuw-button color=\"primary\" [disabled]=\"saveDisabled() || saving()\" (clicked)=\"save.emit()\">\n <ng-icon name=\"lucideSave\" size=\"16\" />\n {{ labels().save }}\n </yuw-button>\n }\n </span>\n </div>\n</yuw-sheet>\n", dependencies: [{ kind: "component", type: NgIcon, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }, { kind: "component", type: YuwButtonComponent, selector: "yuw-button", inputs: ["animationDisabled", "ariaLabel", "color", "disabled", "href", "size", "target", "transparent", "type", "class", "variant", "yuwDropdownMenuTrigger"], outputs: ["clicked"] }, { kind: "component", type: YuwSheetComponent, selector: "yuw-sheet", inputs: ["ariaLabel", "ariaModal", "bodyClass", "closeLabel", "closeOnOutsidePointerEvents", "description", "open", "overlayClass", "panelClass", "scrollStrategy", "showTrigger", "side", "title", "triggerSize", "triggerVariant"], outputs: ["openChange"] }, { kind: "directive", type: YuwSheetFooterDirective, selector: "[yuwSheetFooter]" }, { kind: "directive", type: YuwSheetHeaderDirective, selector: "[yuwSheetHeader]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
7387
7445
  }
7388
7446
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwsFormSheetComponent, decorators: [{
7389
7447
  type: Component,
7390
- args: [{ selector: 'yuws-form-sheet', changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgIcon, YuwButtonComponent, YuwSheetComponent, YuwSheetFooterDirective, YuwSheetHeaderDirective], providers: [provideIcons({ lucideArchiveRestore, lucideArrowLeft, lucideSave, lucideTrash2, lucideX })], template: "<yuw-sheet\n side=\"right\"\n [showTrigger]=\"false\"\n [panelClass]=\"panelClass()\"\n bodyClass=\"scroll-fade-y\"\n [title]=\"backLabel() ? undefined : title()\"\n [closeLabel]=\"backLabel() ? undefined : labels().close\"\n [(open)]=\"open\"\n>\n @if (backLabel(); as label) {\n <div yuwSheetHeader class=\"-ml-2 -mt-3 flex items-center gap-1 pb-3\">\n <yuw-button type=\"button\" variant=\"ghost\" size=\"icon-sm\" [ariaLabel]=\"label\" (clicked)=\"back.emit()\">\n <ng-icon name=\"lucideArrowLeft\" size=\"16\" />\n </yuw-button>\n <h2 class=\"text-base font-medium text-foreground\">{{ title() }}</h2>\n </div>\n }\n\n <ng-content />\n\n <div\n yuwSheetFooter\n class=\"flex flex-wrap items-center justify-between gap-2\"\n [style.display]=\"hideFooter() ? 'none' : null\"\n [attr.aria-busy]=\"saving()\"\n >\n @if (errorMessage(); as message) {\n <p role=\"alert\" class=\"w-full rounded-md bg-destructive/10 px-3 py-2 text-sm text-destructive\">{{ message }}</p>\n }\n\n @if (removeLabel(); as label) {\n <yuw-button\n variant=\"ghost\"\n color=\"destructive\"\n class=\"gap-2\"\n [disabled]=\"removeDisabled() || saving()\"\n (clicked)=\"remove.emit()\"\n >\n <ng-icon name=\"lucideTrash2\" size=\"16\" />\n {{ label }}\n </yuw-button>\n }\n\n <span class=\"ms-auto flex gap-2\">\n <yuw-button variant=\"outline\" (clicked)=\"onCancel()\">\n <ng-icon name=\"lucideX\" size=\"16\" />\n {{ labels().cancel }}\n </yuw-button>\n @if (restoreLabel(); as label) {\n <yuw-button color=\"primary\" [disabled]=\"saving()\" (clicked)=\"restore.emit()\">\n <ng-icon name=\"lucideArchiveRestore\" size=\"16\" />\n {{ label }}\n </yuw-button>\n }\n @if (!readonly()) {\n <yuw-button color=\"primary\" [disabled]=\"saveDisabled() || saving()\" (clicked)=\"save.emit()\">\n <ng-icon name=\"lucideSave\" size=\"16\" />\n {{ labels().save }}\n </yuw-button>\n }\n </span>\n </div>\n</yuw-sheet>\n" }]
7448
+ args: [{ selector: 'yuws-form-sheet', changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgIcon, YuwButtonComponent, YuwSheetComponent, YuwSheetFooterDirective, YuwSheetHeaderDirective], providers: [
7449
+ provideIcons({ lucideArchiveRestore, lucideArrowLeft, lucideSave, lucideTrash2, lucideX }),
7450
+ { provide: YuwSheetOpenState, useExisting: YuwsFormSheetComponent },
7451
+ ], template: "<yuw-sheet\n side=\"right\"\n [showTrigger]=\"false\"\n [panelClass]=\"panelClass()\"\n bodyClass=\"scroll-fade-y\"\n [title]=\"backLabel() ? undefined : title()\"\n [closeLabel]=\"backLabel() ? undefined : labels().close\"\n [(open)]=\"open\"\n>\n @if (backLabel(); as label) {\n <div yuwSheetHeader class=\"-ml-2 -mt-3 flex items-center gap-1 pb-3\">\n <yuw-button type=\"button\" variant=\"ghost\" size=\"icon-sm\" [ariaLabel]=\"label\" (clicked)=\"back.emit()\">\n <ng-icon name=\"lucideArrowLeft\" size=\"16\" />\n </yuw-button>\n <h2 class=\"text-base font-medium text-foreground\">{{ title() }}</h2>\n </div>\n }\n\n <ng-content />\n\n <div\n yuwSheetFooter\n class=\"flex flex-wrap items-center justify-between gap-2\"\n [style.display]=\"hideFooter() ? 'none' : null\"\n [attr.aria-busy]=\"saving()\"\n >\n @if (errorMessage(); as message) {\n <p role=\"alert\" class=\"w-full rounded-md bg-destructive/10 px-3 py-2 text-sm text-destructive\">{{ message }}</p>\n }\n\n @if (removeLabel(); as label) {\n <yuw-button\n variant=\"ghost\"\n color=\"destructive\"\n class=\"gap-2\"\n [disabled]=\"removeDisabled() || saving()\"\n (clicked)=\"remove.emit()\"\n >\n <ng-icon name=\"lucideTrash2\" size=\"16\" />\n {{ label }}\n </yuw-button>\n }\n\n <span class=\"ms-auto flex gap-2\">\n <yuw-button variant=\"outline\" (clicked)=\"onCancel()\">\n <ng-icon name=\"lucideX\" size=\"16\" />\n {{ labels().cancel }}\n </yuw-button>\n @if (restoreLabel(); as label) {\n <yuw-button color=\"primary\" [disabled]=\"saving()\" (clicked)=\"restore.emit()\">\n <ng-icon name=\"lucideArchiveRestore\" size=\"16\" />\n {{ label }}\n </yuw-button>\n }\n @if (!readonly()) {\n <yuw-button color=\"primary\" [disabled]=\"saveDisabled() || saving()\" (clicked)=\"save.emit()\">\n <ng-icon name=\"lucideSave\" size=\"16\" />\n {{ labels().save }}\n </yuw-button>\n }\n </span>\n </div>\n</yuw-sheet>\n" }]
7391
7452
  }], propDecorators: { backLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "backLabel", required: false }] }], errorMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMessage", required: false }] }], hideFooter: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideFooter", required: false }] }], labels: [{ type: i0.Input, args: [{ isSignal: true, alias: "labels", required: true }] }], open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: true }] }, { type: i0.Output, args: ["openChange"] }], panelClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "panelClass", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], removeDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "removeDisabled", required: false }] }], removeLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "removeLabel", required: false }] }], restoreLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "restoreLabel", required: false }] }], saveDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "saveDisabled", required: false }] }], saving: [{ type: i0.Input, args: [{ isSignal: true, alias: "saving", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: true }] }], back: [{ type: i0.Output, args: ["back"] }], remove: [{ type: i0.Output, args: ["remove"] }], restore: [{ type: i0.Output, args: ["restore"] }], save: [{ type: i0.Output, args: ["save"] }] } });
7392
7453
 
7393
7454
  /**