yukit-web 0.2.8 → 0.3.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.
@@ -15,7 +15,7 @@ import * as i1 from '@spartan-ng/brain/tooltip';
15
15
  import { provideBrnTooltipDefaultOptions, BrnTooltip } from '@spartan-ng/brain/tooltip';
16
16
  import { tooltipPositionVariants, DEFAULT_TOOLTIP_CONTENT_CLASSES, DEFAULT_TOOLTIP_SVG_CLASS } from 'yukit-web/helm/tooltip';
17
17
  import { NgIcon, provideIcons } from '@ng-icons/core';
18
- import { lucideX, lucideChevronRight, lucideChevronLeft, lucideArrowLeft, lucidePlus, lucideSearch, lucideEyeOff, lucideEye, lucideSettings2, lucideList, lucideLayoutGrid, lucideDownload, lucideTrash2, lucidePencil, lucideEllipsis, lucideStar, lucideFilter, lucideChevronsUpDown, lucideChevronUp, lucideChevronDown } from '@ng-icons/lucide';
18
+ import { lucideX, lucideChevronRight, lucideChevronLeft, lucideArrowLeft, lucidePlus, lucideUpload, lucideSearch, lucideEyeOff, lucideEye, lucideSettings2, lucideList, lucideLayoutGrid, lucideDownload, lucideTrash2, lucidePencil, lucideEllipsis, lucideStar, lucideFilter, lucideChevronsUpDown, lucideChevronUp, lucideChevronDown } from '@ng-icons/lucide';
19
19
  import * as i1$1 from 'yukit-web/helm/badge';
20
20
  import { HlmBadge } from 'yukit-web/helm/badge';
21
21
  import * as i1$2 from 'yukit-web/helm/breadcrumb';
@@ -29,46 +29,46 @@ import { BreakpointObserver } from '@angular/cdk/layout';
29
29
  import { HlmAccordion, HlmAccordionItem, HlmAccordionTrigger, HlmAccordionContent } from 'yukit-web/helm/accordion';
30
30
  import { HlmField, HlmFieldDescription } from 'yukit-web/helm/field';
31
31
  import { HlmInput } from 'yukit-web/helm/input';
32
- import * as i1$4 from 'yukit-web/helm/input-group';
32
+ import * as i1$9 from 'yukit-web/helm/input-group';
33
33
  import { HlmInputGroup, HlmInputGroupInput, HlmInputGroupAddon, HlmInputGroupTextarea, HlmInputGroupImports } from 'yukit-web/helm/input-group';
34
34
  import { BrnField } from '@spartan-ng/brain/field';
35
+ import * as i1$4 from 'yukit-web/helm/avatar';
36
+ import { HlmAvatarImports } from 'yukit-web/helm/avatar';
37
+ import * as i1$6 from 'yukit-web/helm/popover';
38
+ import { HlmPopoverImports } from 'yukit-web/helm/popover';
39
+ import * as i1$5 from '@spartan-ng/brain/popover';
40
+ import { BrnPopoverTrigger } from '@spartan-ng/brain/popover';
41
+ import * as i1$7 from '@spartan-ng/brain/sheet';
42
+ import { BrnSheetTrigger, BrnSheetClose } from '@spartan-ng/brain/sheet';
43
+ import * as i1$8 from 'yukit-web/helm/sheet';
44
+ import { HlmSheet, HlmSheetImports } from 'yukit-web/helm/sheet';
35
45
  import { HlmTextarea } from 'yukit-web/helm/textarea';
36
46
  import { BrnInputOtp } from '@spartan-ng/brain/input-otp';
37
- import * as i1$5 from 'yukit-web/helm/input-otp';
47
+ import * as i1$a from 'yukit-web/helm/input-otp';
38
48
  import { HlmInputOtpImports } from 'yukit-web/helm/input-otp';
39
49
  import { HlmLabel } from 'yukit-web/helm/label';
40
50
  import { HlmCheckbox } from 'yukit-web/helm/checkbox';
41
- import * as i1$6 from 'yukit-web/helm/switch';
51
+ import * as i1$b from 'yukit-web/helm/switch';
42
52
  import { HlmSwitchImports } from 'yukit-web/helm/switch';
43
- import * as i1$7 from 'yukit-web/helm/radio-group';
53
+ import * as i1$c from 'yukit-web/helm/radio-group';
44
54
  import { HlmRadioGroupImports } from 'yukit-web/helm/radio-group';
45
- import * as i1$8 from 'yukit-web/helm/skeleton';
55
+ import * as i1$d from 'yukit-web/helm/skeleton';
46
56
  import { HlmSkeleton } from 'yukit-web/helm/skeleton';
47
- import * as i1$9 from 'yukit-web/helm/card';
57
+ import * as i1$e from 'yukit-web/helm/card';
48
58
  import { HlmCard, HlmCardHeader, HlmCardTitle, HlmCardDescription, HlmCardAction, HlmCardContent, HlmCardFooter } from 'yukit-web/helm/card';
49
- import * as i1$a from 'yukit-web/helm/empty';
59
+ import * as i1$f from 'yukit-web/helm/empty';
50
60
  import { HlmEmpty, HlmEmptyHeader, HlmEmptyMedia, HlmEmptyTitle, HlmEmptyDescription, HlmEmptyContent } from 'yukit-web/helm/empty';
51
61
  import { CdkContextMenuTrigger, CdkMenuItem, CdkMenuItemCheckbox, CdkMenuItemRadio, CdkMenuTrigger } from '@angular/cdk/menu';
52
- import * as i1$b from 'yukit-web/helm/context-menu';
62
+ import * as i1$g from 'yukit-web/helm/context-menu';
53
63
  import { HlmContextMenuTrigger } from 'yukit-web/helm/context-menu';
54
- import * as i1$c from 'yukit-web/helm/date-picker';
64
+ import * as i1$h from 'yukit-web/helm/date-picker';
55
65
  import { injectHlmMonthYearPickerConfig, injectHlmDatePickerMultiConfig, injectHlmDateRangePickerConfig, injectHlmDatePickerConfig, HlmDatePickerImports } from 'yukit-web/helm/date-picker';
56
- import * as i1$d from 'yukit-web/helm/table';
66
+ import * as i1$i from 'yukit-web/helm/table';
57
67
  import { HlmTableContainer, HlmTable, HlmTHead, HlmTBody, HlmTFoot, HlmTr, HlmTh, HlmTd, HlmCaption } from 'yukit-web/helm/table';
58
- import * as i1$f from 'yukit-web/helm/popover';
59
- import { HlmPopoverImports } from 'yukit-web/helm/popover';
60
- import * as i1$e from '@spartan-ng/brain/popover';
61
- import { BrnPopoverTrigger } from '@spartan-ng/brain/popover';
62
- import * as i1$g from '@spartan-ng/brain/sheet';
63
- import { BrnSheetTrigger, BrnSheetClose } from '@spartan-ng/brain/sheet';
64
- import * as i1$h from 'yukit-web/helm/sheet';
65
- import { HlmSheet, HlmSheetImports } from 'yukit-web/helm/sheet';
66
- import * as i1$i from 'yukit-web/helm/tabs';
68
+ import * as i1$j from 'yukit-web/helm/tabs';
67
69
  import { HlmTabsImports } from 'yukit-web/helm/tabs';
68
70
  import { rowSortingFeature, rowSelectionFeature, rowPaginationFeature, columnVisibilityFeature, columnFilteringFeature, sortFns, createPaginatedRowModel, createSortedRowModel, createFilteredRowModel, createCoreRowModel } from '@tanstack/table-core';
69
71
  import { injectTable, FlexRenderDirective, flexRenderComponent } from '@tanstack/angular-table';
70
- import * as i1$j from 'yukit-web/helm/avatar';
71
- import { HlmAvatarImports } from 'yukit-web/helm/avatar';
72
72
  import * as i1$k from 'yukit-web/helm/item';
73
73
  import { HlmItem, HlmItemHeader, HlmItemMedia, HlmItemContent, HlmItemTitle, HlmItemDescription, HlmItemActions, HlmItemFooter, HlmItemGroup, HlmItemSeparator } from 'yukit-web/helm/item';
74
74
  import { HlmSpinner } from 'yukit-web/helm/spinner';
@@ -128,6 +128,9 @@ function cn(...inputs) {
128
128
  * ```html
129
129
  * <button hlmBtn [size]="size()" [yuwClass]="_btnClass()">Save</button>
130
130
  * ```
131
+ *
132
+ * Inputs:
133
+ * - `yuwClass`: String of CSS classes registered as a replaceable `classes()` source on the host. Default is `''`.
131
134
  */
132
135
  class YuwClassDirective {
133
136
  constructor() {
@@ -179,6 +182,10 @@ function provideValueAccessor(component) {
179
182
  *
180
183
  * They're kept as two separate signals and OR'd together in `_disabled`: disabled by *either*
181
184
  * source means disabled. That's the only combination that never drops a caller's intent.
185
+ *
186
+ * Inputs:
187
+ * - `disabled`: Disables the form control and blocks user interaction. Combined with the disabled
188
+ * state coming from the forms API, so either one disables it. Default is `false`.
182
189
  */
183
190
  class YuwValueAccessorBase {
184
191
  constructor() {
@@ -241,6 +248,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
241
248
  * forward to its native input — lives one level down, per the Liskov rule in `AGENTS.md`.
242
249
  *
243
250
  * Subclasses provide `_autoId`, the fallback `id` used when the consumer sets no `inputId`.
251
+ *
252
+ * Inputs:
253
+ * - `class`: Extra CSS classes merged last onto the field's visual element, so they win over the
254
+ * defaults. Bound through the `class` alias of an internal input. Default is `''`.
255
+ * - `errorText`: Error message shown under the field. Default is `undefined`.
256
+ * - `helperText`: Helper message shown under the field. Default is `undefined`.
257
+ * - `inputId`: ID set on the native input element, for `<label [for]>` matching. Falls back to a
258
+ * generated ID when unset. Default is `undefined`.
259
+ * - `invalid`: Marks the field as invalid. Default is `false`.
260
+ * - `value`: Two-way bound (`[(value)]`) string value of the field. Default is `''`.
261
+ *
262
+ * Outputs:
263
+ * - `valueChange`: Emits the new string whenever `value` changes, enabling two-way binding.
244
264
  */
245
265
  class YuwFieldBase extends YuwValueAccessorBase {
246
266
  constructor() {
@@ -272,6 +292,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
272
292
  * the controls can't drift apart — the Liskov rule in `AGENTS.md`: same-role components share one
273
293
  * input contract. Anything only some of them honor (`maxlength`, `size`, `enterPressed`, …) stays
274
294
  * on the component, never here.
295
+ *
296
+ * Inputs:
297
+ * - `autocomplete`: Native `autocomplete` attribute forwarded to the control. Default is `undefined`.
298
+ * - `name`: Native `name` attribute forwarded to the control. Default is `undefined`.
299
+ * - `placeholder`: Native placeholder text. Default is `undefined`.
300
+ * - `readonly`: Makes the control read-only. Default is `false`.
301
+ * - `required`: Marks the control as required. Default is `false`.
275
302
  */
276
303
  class YuwTextFieldBase extends YuwFieldBase {
277
304
  constructor() {
@@ -430,6 +457,8 @@ const yuwButtonVariants = cva('', {
430
457
  * - `class`: Extra CSS classes merged onto the inner button/anchor; merged last, so they win over the component's own classes.
431
458
  * - `yuwDropdownMenuTrigger`: Optional dropdown menu template reference to trigger.
432
459
  * - `ariaLabel`: Accessible label for screen readers.
460
+ * - `animationDisabled`: Removes the pressed-state translate animation. Default is `false`. It is also
461
+ * forced on when the host carries `aria-haspopup` (e.g. when used as an overlay trigger).
433
462
  *
434
463
  * Outputs:
435
464
  * - `clicked`: Emits MouseEvent on click.
@@ -559,6 +588,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
559
588
  * </ng-template>
560
589
  * </yuw-button-group>
561
590
  * ```
591
+ *
592
+ * Inputs:
593
+ * - `yuwButtonGroupContent`: Required string; id of the button group entry this template renders the content of.
562
594
  */
563
595
  class YuwButtonGroupContentDirective {
564
596
  constructor() {
@@ -698,6 +730,16 @@ const REMOVE_TEXT_CLASS = {
698
730
  * (`variant`), dismissible action (`removeLabel` / `removed`), and a compact dot mode (`dot`)
699
731
  * that renders no content at all.
700
732
  *
733
+ * Inputs:
734
+ * - `color`: Brand color theme (any `YuwColorDto` value). Default is `'primary'`.
735
+ * - `dot`: Renders a compact dot with no content, icon or remove button. Default is `false`.
736
+ * - `removeLabel`: Accessible label for the remove button; the button only renders when this is set. The app supplies
737
+ * and translates it. Default is `undefined`.
738
+ * - `variant`: Helm badge style (`'default'`, `'secondary'`, `'destructive'`, `'outline'`, `'ghost'`, `'link'`). Default is `'default'`.
739
+ *
740
+ * Outputs:
741
+ * - `removed`: Emits when the remove button is clicked.
742
+ *
701
743
  * Usage:
702
744
  * ```html
703
745
  * <yuw-badge color="primary">New</yuw-badge>
@@ -738,6 +780,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
738
780
  * (`aria-current="page"`); intermediate items render as links when they have an `href` and as
739
781
  * plain text otherwise.
740
782
  *
783
+ * Inputs:
784
+ * - `ariaLabel`: Required accessible label for the navigation landmark. The app supplies and translates it.
785
+ * - `items`: Required array of `YuwBreadcrumbItemDto` (`label`, optional `href`) in hierarchy order.
786
+ * - `separator`: Text rendered between items. Default is `'/'`.
787
+ *
741
788
  * Usage:
742
789
  * ```html
743
790
  * <yuw-breadcrumb
@@ -823,6 +870,19 @@ function getPaginationRange(page, totalPages) {
823
870
  * Controls two-way active page state `[(page)]`, accepts total pages (`totalPages`), accessible
824
871
  * previous/next/ellipsis labels, size and color theme.
825
872
  *
873
+ * Inputs:
874
+ * - `ariaLabel`: Required accessible label of the navigation landmark.
875
+ * - `color`: Brand color theme (any `YuwColorDto` value). Default is `'primary'`.
876
+ * - `ellipsisSrText`: Required screen reader text of the ellipsis between page ranges.
877
+ * - `nextLabel`: Required accessible label of the next page button.
878
+ * - `page`: Required two-way (`[(page)]`) active page, 1-based.
879
+ * - `previousLabel`: Required accessible label of the previous page button.
880
+ * - `size`: Button size (`YuwPaginationSizeDto`). Default is `'icon'`.
881
+ * - `totalPages`: Required total number of pages.
882
+ *
883
+ * Outputs:
884
+ * - `page`: Emits the new active page when the user picks one (the output half of `[(page)]`).
885
+ *
826
886
  * Usage:
827
887
  * ```html
828
888
  * <yuw-pagination
@@ -919,6 +979,9 @@ const yuwFieldMinHeightVariants = cva('', {
919
979
  * </ng-template>
920
980
  * </yuw-combobox>
921
981
  * ```
982
+ *
983
+ * Inputs:
984
+ * - `yuwComboboxItemTypeOf`: Optional array of `YuwComboboxOptionDto`; only used to infer the generic data type of the template context for type checking. Default is `undefined`.
922
985
  */
923
986
  class YuwComboboxItemDirective {
924
987
  constructor() {
@@ -1097,7 +1160,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
1097
1160
  }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<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 <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 <hlm-combobox-content *hlmComboboxPortal>\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 </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 (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>\n @if (readonlyTrigger()) {\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 </hlm-combobox-content>\n </hlm-combobox>\n}\n" }]
1098
1161
  }], 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 }] }], 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 }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }] } });
1099
1162
 
1100
- /** Page size selector and range message of a `YuwPagedList`; in a datatable it takes the pagination slot. */
1163
+ /**
1164
+ * Page size selector and range message of a `YuwPagedList`; in a datatable it takes the pagination slot.
1165
+ *
1166
+ * Inputs:
1167
+ * - `disabled`: Disables the page size selector. Default is `false`.
1168
+ * - `labels`: Required `YuwPageSizeLabels` with the selector label, the text for an empty list and the function that builds the range message.
1169
+ * - `list`: Required `YuwPagedList` whose page size is chosen and whose range is shown in the message.
1170
+ */
1101
1171
  class YuwPageSizeComponent {
1102
1172
  constructor() {
1103
1173
  this.disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
@@ -1113,7 +1183,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
1113
1183
  args: [{ selector: 'yuw-page-size', changeDetection: ChangeDetectionStrategy.OnPush, imports: [YuwComboboxComponent], host: { class: 'flex items-center gap-2' }, template: "<yuw-combobox\n readonlyTrigger\n class=\"w-32\"\n [disabled]=\"disabled()\"\n [options]=\"list().pageSizeOptions\"\n [triggerAriaLabel]=\"labels().label\"\n [value]=\"list().pageSize()\"\n [emptyText]=\"labels().empty\"\n (valueChange)=\"list().pageSize.set($event)\"\n/>\n<p class=\"text-sm text-muted-foreground\">{{ message() }}</p>\n" }]
1114
1184
  }], propDecorators: { disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], labels: [{ type: i0.Input, args: [{ isSignal: true, alias: "labels", required: true }] }], list: [{ type: i0.Input, args: [{ isSignal: true, alias: "list", required: true }] }] } });
1115
1185
 
1116
- /** Pagination footer for lists without a datatable. A disabled `fieldset` blocks its buttons. */
1186
+ /**
1187
+ * Pagination footer for lists without a datatable: the page size selector with its range message
1188
+ * and the page navigation, both driven by one `YuwPagedList`. A disabled `fieldset` blocks its buttons.
1189
+ *
1190
+ * Inputs:
1191
+ * - `disabled`: Disables the page size selector and the page buttons. Default is `false`.
1192
+ * - `labels`: Required `YuwListPaginationLabels` with the consumer's text for the page size selector, the navigation aria label and the previous, next and ellipsis texts.
1193
+ * - `list`: Required `YuwPagedList` holding the current page, page size, total pages and range; changes made in the footer are written back to it.
1194
+ */
1117
1195
  class YuwListPaginationComponent {
1118
1196
  constructor() {
1119
1197
  this.disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
@@ -1141,14 +1219,32 @@ function injectIsMobile() {
1141
1219
  * Page title, optional description and up to two actions, each rendered when its label is set.
1142
1220
  * On mobile the primary action shows only its icon, or `primaryMobileLabel`. Icons are `@ng-icons`
1143
1221
  * names; the consumer registers any beyond `lucidePlus` with `provideIcons`.
1222
+ *
1223
+ * Inputs:
1224
+ * - `backLabel`: Text of the back button, which renders only when set; on small screens only its arrow shows.
1225
+ * - `description`: Optional subtitle under the title.
1226
+ * - `primaryDisabled`: Disables the primary action, which stays visible but ignores clicks, e.g. while the list it creates items for is loading.
1227
+ * - `primaryIcon`: Icon name shown in the primary action.
1228
+ * - `primaryLabel`: Text of the primary action, which renders only when set.
1229
+ * - `primaryMobileLabel`: Text the primary action shows on small screens instead of its label.
1230
+ * - `secondaryIcon`: Icon name shown in the secondary action.
1231
+ * - `secondaryLabel`: Text of the secondary action, which renders only when set; hidden on small screens, leaving its icon.
1232
+ * - `title`: Required page title.
1233
+ *
1234
+ * Outputs:
1235
+ * - `backClicked`: Emits the `MouseEvent` of the back button.
1236
+ * - `primaryClicked`: Emits the `MouseEvent` of the primary action.
1237
+ * - `secondaryClicked`: Emits the `MouseEvent` of the secondary action.
1144
1238
  */
1145
1239
  class YuwPageHeaderComponent {
1146
1240
  constructor() {
1147
1241
  this.backLabel = input(...(ngDevMode ? [undefined, { debugName: "backLabel" }] : /* istanbul ignore next */ []));
1148
1242
  this.description = input(...(ngDevMode ? [undefined, { debugName: "description" }] : /* istanbul ignore next */ []));
1243
+ this.primaryDisabled = input(false, { ...(ngDevMode ? { debugName: "primaryDisabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
1149
1244
  this.primaryIcon = input(...(ngDevMode ? [undefined, { debugName: "primaryIcon" }] : /* istanbul ignore next */ []));
1150
1245
  this.primaryLabel = input(...(ngDevMode ? [undefined, { debugName: "primaryLabel" }] : /* istanbul ignore next */ []));
1151
1246
  this.primaryMobileLabel = input(...(ngDevMode ? [undefined, { debugName: "primaryMobileLabel" }] : /* istanbul ignore next */ []));
1247
+ this.secondaryDisabled = input(false, { ...(ngDevMode ? { debugName: "secondaryDisabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
1152
1248
  this.secondaryIcon = input(...(ngDevMode ? [undefined, { debugName: "secondaryIcon" }] : /* istanbul ignore next */ []));
1153
1249
  this.secondaryLabel = input(...(ngDevMode ? [undefined, { debugName: "secondaryLabel" }] : /* istanbul ignore next */ []));
1154
1250
  this.title = input.required(...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
@@ -1158,12 +1254,12 @@ class YuwPageHeaderComponent {
1158
1254
  this.isMobile = injectIsMobile();
1159
1255
  }
1160
1256
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwPageHeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1161
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: YuwPageHeaderComponent, isStandalone: true, selector: "yuw-page-header", inputs: { backLabel: { classPropertyName: "backLabel", publicName: "backLabel", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, primaryIcon: { classPropertyName: "primaryIcon", publicName: "primaryIcon", isSignal: true, isRequired: false, transformFunction: null }, primaryLabel: { classPropertyName: "primaryLabel", publicName: "primaryLabel", isSignal: true, isRequired: false, transformFunction: null }, primaryMobileLabel: { classPropertyName: "primaryMobileLabel", publicName: "primaryMobileLabel", isSignal: true, isRequired: false, transformFunction: null }, secondaryIcon: { classPropertyName: "secondaryIcon", publicName: "secondaryIcon", isSignal: true, isRequired: false, transformFunction: null }, secondaryLabel: { classPropertyName: "secondaryLabel", publicName: "secondaryLabel", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { backClicked: "backClicked", primaryClicked: "primaryClicked", secondaryClicked: "secondaryClicked" }, providers: [provideIcons({ lucidePlus, lucideArrowLeft })], ngImport: i0, template: "<div class=\"flex flex-wrap items-start justify-center gap-4\">\n <div class=\"flex min-w-0 flex-1 flex-col gap-1\">\n <div class=\"flex items-center gap-4\">\n @if (backLabel(); as label) {\n <yuw-button variant=\"outline\" [size]=\"isMobile() ? 'sm' : 'default'\" (clicked)=\"backClicked.emit($event)\">\n <ng-icon name=\"lucideArrowLeft\" size=\"16\" />\n <span class=\"max-sm:hidden\">{{ label }}</span>\n </yuw-button>\n }\n <div class=\"flex flex-col overflow-hidden\">\n <h1 class=\"truncate text-2xl font-semibold text-foreground\">{{ title() }}</h1>\n @if (description()) {\n <p class=\"truncate text-sm text-muted-foreground\">{{ description() }}</p>\n }\n </div>\n </div>\n </div>\n\n @if (primaryLabel() || secondaryLabel()) {\n <div class=\"flex shrink-0 items-center gap-2\">\n @if (secondaryLabel(); as label) {\n <yuw-button\n variant=\"outline\"\n class=\"gap-2\"\n [size]=\"isMobile() ? 'sm' : 'default'\"\n (clicked)=\"secondaryClicked.emit($event)\"\n >\n @if (secondaryIcon(); as icon) {\n <ng-icon [name]=\"icon\" size=\"16\" />\n }\n <span class=\"max-md:hidden\">{{ label }}</span>\n </yuw-button>\n }\n\n @if (primaryLabel(); as label) {\n <yuw-button\n color=\"primary\"\n class=\"gap-2\"\n [size]=\"isMobile() ? 'sm' : 'default'\"\n (clicked)=\"primaryClicked.emit($event)\"\n >\n @if (primaryIcon(); as icon) {\n <ng-icon [name]=\"icon\" size=\"16\" />\n }\n <span class=\"max-sm:hidden\">{{ label }}</span>\n @if (primaryMobileLabel(); as mobileLabel) {\n <span class=\"sm:hidden\">{{ mobileLabel }}</span>\n }\n </yuw-button>\n }\n </div>\n }\n</div>\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"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1257
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: YuwPageHeaderComponent, isStandalone: true, selector: "yuw-page-header", inputs: { backLabel: { classPropertyName: "backLabel", publicName: "backLabel", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, primaryDisabled: { classPropertyName: "primaryDisabled", publicName: "primaryDisabled", isSignal: true, isRequired: false, transformFunction: null }, primaryIcon: { classPropertyName: "primaryIcon", publicName: "primaryIcon", isSignal: true, isRequired: false, transformFunction: null }, primaryLabel: { classPropertyName: "primaryLabel", publicName: "primaryLabel", isSignal: true, isRequired: false, transformFunction: null }, primaryMobileLabel: { classPropertyName: "primaryMobileLabel", publicName: "primaryMobileLabel", isSignal: true, isRequired: false, transformFunction: null }, secondaryDisabled: { classPropertyName: "secondaryDisabled", publicName: "secondaryDisabled", isSignal: true, isRequired: false, transformFunction: null }, secondaryIcon: { classPropertyName: "secondaryIcon", publicName: "secondaryIcon", isSignal: true, isRequired: false, transformFunction: null }, secondaryLabel: { classPropertyName: "secondaryLabel", publicName: "secondaryLabel", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { backClicked: "backClicked", primaryClicked: "primaryClicked", secondaryClicked: "secondaryClicked" }, providers: [provideIcons({ lucidePlus, lucideArrowLeft })], ngImport: i0, template: "<div class=\"flex flex-wrap items-start justify-center gap-4\">\n <div class=\"flex min-w-0 flex-1 flex-col gap-1\">\n <div class=\"flex items-center gap-4\">\n @if (backLabel(); as label) {\n <yuw-button variant=\"outline\" [size]=\"isMobile() ? 'sm' : 'default'\" (clicked)=\"backClicked.emit($event)\">\n <ng-icon name=\"lucideArrowLeft\" size=\"16\" />\n <span class=\"max-sm:hidden\">{{ label }}</span>\n </yuw-button>\n }\n <div class=\"flex flex-col overflow-hidden\">\n <h1 class=\"truncate text-2xl font-semibold text-foreground\">{{ title() }}</h1>\n @if (description()) {\n <p class=\"truncate text-sm text-muted-foreground\">{{ description() }}</p>\n }\n </div>\n </div>\n </div>\n\n @if (primaryLabel() || secondaryLabel()) {\n <div class=\"flex shrink-0 items-center gap-2\">\n @if (secondaryLabel(); as label) {\n <yuw-button\n variant=\"outline\"\n class=\"gap-2\"\n [size]=\"isMobile() ? 'sm' : 'default'\"\n [disabled]=\"secondaryDisabled()\"\n (clicked)=\"secondaryClicked.emit($event)\"\n >\n @if (secondaryIcon(); as icon) {\n <ng-icon [name]=\"icon\" size=\"16\" />\n }\n <span class=\"max-md:hidden\">{{ label }}</span>\n </yuw-button>\n }\n\n @if (primaryLabel(); as label) {\n <yuw-button\n color=\"primary\"\n class=\"gap-2\"\n [disabled]=\"primaryDisabled()\"\n [size]=\"isMobile() ? 'sm' : 'default'\"\n (clicked)=\"primaryClicked.emit($event)\"\n >\n @if (primaryIcon(); as icon) {\n <ng-icon [name]=\"icon\" size=\"16\" />\n }\n <span class=\"max-sm:hidden\">{{ label }}</span>\n @if (primaryMobileLabel(); as mobileLabel) {\n <span class=\"sm:hidden\">{{ mobileLabel }}</span>\n }\n </yuw-button>\n }\n </div>\n }\n</div>\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"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1162
1258
  }
1163
1259
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwPageHeaderComponent, decorators: [{
1164
1260
  type: Component,
1165
- args: [{ selector: 'yuw-page-header', changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgIcon, YuwButtonComponent], providers: [provideIcons({ lucidePlus, lucideArrowLeft })], template: "<div class=\"flex flex-wrap items-start justify-center gap-4\">\n <div class=\"flex min-w-0 flex-1 flex-col gap-1\">\n <div class=\"flex items-center gap-4\">\n @if (backLabel(); as label) {\n <yuw-button variant=\"outline\" [size]=\"isMobile() ? 'sm' : 'default'\" (clicked)=\"backClicked.emit($event)\">\n <ng-icon name=\"lucideArrowLeft\" size=\"16\" />\n <span class=\"max-sm:hidden\">{{ label }}</span>\n </yuw-button>\n }\n <div class=\"flex flex-col overflow-hidden\">\n <h1 class=\"truncate text-2xl font-semibold text-foreground\">{{ title() }}</h1>\n @if (description()) {\n <p class=\"truncate text-sm text-muted-foreground\">{{ description() }}</p>\n }\n </div>\n </div>\n </div>\n\n @if (primaryLabel() || secondaryLabel()) {\n <div class=\"flex shrink-0 items-center gap-2\">\n @if (secondaryLabel(); as label) {\n <yuw-button\n variant=\"outline\"\n class=\"gap-2\"\n [size]=\"isMobile() ? 'sm' : 'default'\"\n (clicked)=\"secondaryClicked.emit($event)\"\n >\n @if (secondaryIcon(); as icon) {\n <ng-icon [name]=\"icon\" size=\"16\" />\n }\n <span class=\"max-md:hidden\">{{ label }}</span>\n </yuw-button>\n }\n\n @if (primaryLabel(); as label) {\n <yuw-button\n color=\"primary\"\n class=\"gap-2\"\n [size]=\"isMobile() ? 'sm' : 'default'\"\n (clicked)=\"primaryClicked.emit($event)\"\n >\n @if (primaryIcon(); as icon) {\n <ng-icon [name]=\"icon\" size=\"16\" />\n }\n <span class=\"max-sm:hidden\">{{ label }}</span>\n @if (primaryMobileLabel(); as mobileLabel) {\n <span class=\"sm:hidden\">{{ mobileLabel }}</span>\n }\n </yuw-button>\n }\n </div>\n }\n</div>\n" }]
1166
- }], propDecorators: { backLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "backLabel", required: false }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }], primaryIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "primaryIcon", required: false }] }], primaryLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "primaryLabel", required: false }] }], primaryMobileLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "primaryMobileLabel", required: false }] }], secondaryIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "secondaryIcon", required: false }] }], secondaryLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "secondaryLabel", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: true }] }], backClicked: [{ type: i0.Output, args: ["backClicked"] }], primaryClicked: [{ type: i0.Output, args: ["primaryClicked"] }], secondaryClicked: [{ type: i0.Output, args: ["secondaryClicked"] }] } });
1261
+ args: [{ selector: 'yuw-page-header', changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgIcon, YuwButtonComponent], providers: [provideIcons({ lucidePlus, lucideArrowLeft })], template: "<div class=\"flex flex-wrap items-start justify-center gap-4\">\n <div class=\"flex min-w-0 flex-1 flex-col gap-1\">\n <div class=\"flex items-center gap-4\">\n @if (backLabel(); as label) {\n <yuw-button variant=\"outline\" [size]=\"isMobile() ? 'sm' : 'default'\" (clicked)=\"backClicked.emit($event)\">\n <ng-icon name=\"lucideArrowLeft\" size=\"16\" />\n <span class=\"max-sm:hidden\">{{ label }}</span>\n </yuw-button>\n }\n <div class=\"flex flex-col overflow-hidden\">\n <h1 class=\"truncate text-2xl font-semibold text-foreground\">{{ title() }}</h1>\n @if (description()) {\n <p class=\"truncate text-sm text-muted-foreground\">{{ description() }}</p>\n }\n </div>\n </div>\n </div>\n\n @if (primaryLabel() || secondaryLabel()) {\n <div class=\"flex shrink-0 items-center gap-2\">\n @if (secondaryLabel(); as label) {\n <yuw-button\n variant=\"outline\"\n class=\"gap-2\"\n [size]=\"isMobile() ? 'sm' : 'default'\"\n [disabled]=\"secondaryDisabled()\"\n (clicked)=\"secondaryClicked.emit($event)\"\n >\n @if (secondaryIcon(); as icon) {\n <ng-icon [name]=\"icon\" size=\"16\" />\n }\n <span class=\"max-md:hidden\">{{ label }}</span>\n </yuw-button>\n }\n\n @if (primaryLabel(); as label) {\n <yuw-button\n color=\"primary\"\n class=\"gap-2\"\n [disabled]=\"primaryDisabled()\"\n [size]=\"isMobile() ? 'sm' : 'default'\"\n (clicked)=\"primaryClicked.emit($event)\"\n >\n @if (primaryIcon(); as icon) {\n <ng-icon [name]=\"icon\" size=\"16\" />\n }\n <span class=\"max-sm:hidden\">{{ label }}</span>\n @if (primaryMobileLabel(); as mobileLabel) {\n <span class=\"sm:hidden\">{{ mobileLabel }}</span>\n }\n </yuw-button>\n }\n </div>\n }\n</div>\n" }]
1262
+ }], propDecorators: { backLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "backLabel", required: false }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }], primaryDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "primaryDisabled", required: false }] }], primaryIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "primaryIcon", required: false }] }], primaryLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "primaryLabel", required: false }] }], primaryMobileLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "primaryMobileLabel", required: false }] }], secondaryDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "secondaryDisabled", required: false }] }], secondaryIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "secondaryIcon", required: false }] }], secondaryLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "secondaryLabel", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: true }] }], backClicked: [{ type: i0.Output, args: ["backClicked"] }], primaryClicked: [{ type: i0.Output, args: ["primaryClicked"] }], secondaryClicked: [{ type: i0.Output, args: ["secondaryClicked"] }] } });
1167
1263
 
1168
1264
  /**
1169
1265
  * Container directive for collapsible accordion items.
@@ -1317,115 +1413,557 @@ const YuwInputAddonImports = [YuwLeftAddonDirective, YuwRightAddonDirective];
1317
1413
  * `ErrorStateMatcher`: invalid and touched or submitted, already blur-gated by the form) or
1318
1414
  * `forcedInvalid`.
1319
1415
  */
1320
- class YuwFieldFeedbackDirective {
1321
- constructor() {
1322
- this._field = inject(BrnField, { self: true });
1323
- this.errorText = input(undefined, ...(ngDevMode ? [{ debugName: "errorText" }] : /* istanbul ignore next */ []));
1324
- this.invalid = input(false, ...(ngDevMode ? [{ debugName: "invalid" }] : /* istanbul ignore next */ []));
1325
- this._blurred = signal(false, ...(ngDevMode ? [{ debugName: "_blurred" }] : /* istanbul ignore next */ []));
1326
- this.errorMessage = computed(() => this.errorText() ?? firstErrorMessage(this._field.errors()), ...(ngDevMode ? [{ debugName: "errorMessage" }] : /* istanbul ignore next */ []));
1327
- this.forcedInvalid = computed(() => this.invalid() && this._blurred(), ...(ngDevMode ? [{ debugName: "forcedInvalid" }] : /* istanbul ignore next */ []));
1328
- this.showError = computed(() => this.errorMessage() !== undefined && (this.forcedInvalid() || !!this._field.controlState()?.spartanInvalid), ...(ngDevMode ? [{ debugName: "showError" }] : /* istanbul ignore next */ []));
1416
+ class YuwFieldFeedbackDirective {
1417
+ constructor() {
1418
+ this._field = inject(BrnField, { self: true });
1419
+ this.errorText = input(undefined, ...(ngDevMode ? [{ debugName: "errorText" }] : /* istanbul ignore next */ []));
1420
+ this.invalid = input(false, ...(ngDevMode ? [{ debugName: "invalid" }] : /* istanbul ignore next */ []));
1421
+ this._blurred = signal(false, ...(ngDevMode ? [{ debugName: "_blurred" }] : /* istanbul ignore next */ []));
1422
+ this.errorMessage = computed(() => this.errorText() ?? firstErrorMessage(this._field.errors()), ...(ngDevMode ? [{ debugName: "errorMessage" }] : /* istanbul ignore next */ []));
1423
+ this.forcedInvalid = computed(() => this.invalid() && this._blurred(), ...(ngDevMode ? [{ debugName: "forcedInvalid" }] : /* istanbul ignore next */ []));
1424
+ this.showError = computed(() => this.errorMessage() !== undefined && (this.forcedInvalid() || !!this._field.controlState()?.spartanInvalid), ...(ngDevMode ? [{ debugName: "showError" }] : /* istanbul ignore next */ []));
1425
+ }
1426
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwFieldFeedbackDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
1427
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.22", type: YuwFieldFeedbackDirective, isStandalone: true, selector: "hlm-field[yuwFieldFeedback]", inputs: { errorText: { classPropertyName: "errorText", publicName: "errorText", isSignal: true, isRequired: false, transformFunction: null }, invalid: { classPropertyName: "invalid", publicName: "invalid", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "focusout": "_blurred.set(true)" } }, exportAs: ["yuwFieldFeedback"], ngImport: i0 }); }
1428
+ }
1429
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwFieldFeedbackDirective, decorators: [{
1430
+ type: Directive,
1431
+ args: [{
1432
+ selector: 'hlm-field[yuwFieldFeedback]',
1433
+ exportAs: 'yuwFieldFeedback',
1434
+ host: {
1435
+ '(focusout)': '_blurred.set(true)',
1436
+ },
1437
+ }]
1438
+ }], propDecorators: { errorText: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorText", required: false }] }], invalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalid", required: false }] }] } });
1439
+ function firstErrorMessage(errors) {
1440
+ return Object.values(errors ?? {}).find((error) => typeof error?.message === 'string')?.message;
1441
+ }
1442
+
1443
+ /** Module-level counter backing each instance's stable fallback `id`. */
1444
+ let nextYuwInputId = 0;
1445
+ /**
1446
+ * Single-line text input control supporting two-way value binding, form controls (`formControlName`, `ngModel`),
1447
+ * validation styling, and left/right addon slots.
1448
+ *
1449
+ * Inputs / Models:
1450
+ * - `value`: Two-way text string.
1451
+ * - `inputId`: `id` applied to the native input, for external `<label for>` association.
1452
+ * - `type`: HTML input type (`'text'`, `'email'`, `'number'`, etc.). Default is `'text'`.
1453
+ * - `size`: Control height (`'default'` 40px, `'xs'` 28px, `'sm'` 36px, `'lg'` 44px), matching the
1454
+ * `<yuw-button>` size of the same name. Default is `'default'`.
1455
+ * - `inputmode`: Virtual keyboard hint (e.g. `'numeric'`).
1456
+ * - `disabled`: Disables input interaction.
1457
+ * - `readonly`: Makes the field read-only.
1458
+ * - `required`: Marks the field as required.
1459
+ * - `invalid`: Forces invalid styling. Applied from the first blur on, so a pristine field is not flagged while typing.
1460
+ * - `helperText`: Hint shown under the field. Replaced by the error while one is displayed.
1461
+ * - `errorText`: Error shown under the field while it is in its error state (form validation or
1462
+ * `invalid`). Overrides the `message` carried by the bound control's validation errors (signal or
1463
+ * reactive forms); required when no such message exists.
1464
+ * - `name`: HTML `name` attribute.
1465
+ * - `autocomplete`: Native `autocomplete` attribute.
1466
+ * - `maxlength`: Hard cap on character count, enforced natively by the browser.
1467
+ * - `placeholder`: Hint text shown inside the empty field.
1468
+ * - `class`: Extra classes merged onto the visual root (the input, or the input group when addons are present).
1469
+ *
1470
+ * Outputs:
1471
+ * - `committed`: Emits the current value on the native `change` event (blur/enter).
1472
+ * - `enterPressed`: Emits (`void`) when the Enter key is pressed while the field is focused.
1473
+ *
1474
+ * Usage:
1475
+ * ```html
1476
+ * <yuw-input [(value)]="username" placeholder="Enter username..." />
1477
+ *
1478
+ * <yuw-input formControlName="email" type="email">
1479
+ * <yuw-left-addon><ng-icon name="lucideMail" /></yuw-left-addon>
1480
+ * </yuw-input>
1481
+ * ```
1482
+ */
1483
+ class YuwInputComponent extends YuwTextFieldBase {
1484
+ constructor() {
1485
+ super(...arguments);
1486
+ this._leftAddons = contentChildren(YuwLeftAddonDirective, ...(ngDevMode ? [{ debugName: "_leftAddons" }] : /* istanbul ignore next */ []));
1487
+ this._rightAddons = contentChildren(YuwRightAddonDirective, ...(ngDevMode ? [{ debugName: "_rightAddons" }] : /* istanbul ignore next */ []));
1488
+ this.inputmode = input(undefined, ...(ngDevMode ? [{ debugName: "inputmode" }] : /* istanbul ignore next */ []));
1489
+ this.maxlength = input(undefined, ...(ngDevMode ? [{ debugName: "maxlength" }] : /* istanbul ignore next */ []));
1490
+ this.size = input('default', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
1491
+ this.type = input('text', ...(ngDevMode ? [{ debugName: "type" }] : /* istanbul ignore next */ []));
1492
+ this.enterPressed = output();
1493
+ this._autoId = `yuw-input-${++nextYuwInputId}`;
1494
+ this._focusSelectors = ['input'];
1495
+ this._classes = computed(() => cn(yuwFieldSizeVariants({ size: this.size() }), this.userClass()), ...(ngDevMode ? [{ debugName: "_classes" }] : /* istanbul ignore next */ []));
1496
+ this._hasLeftAddon = computed(() => this._leftAddons().length > 0, ...(ngDevMode ? [{ debugName: "_hasLeftAddon" }] : /* istanbul ignore next */ []));
1497
+ this._hasRightAddon = computed(() => this._rightAddons().length > 0, ...(ngDevMode ? [{ debugName: "_hasRightAddon" }] : /* istanbul ignore next */ []));
1498
+ this._hasAddons = computed(() => this._hasLeftAddon() || this._hasRightAddon(), ...(ngDevMode ? [{ debugName: "_hasAddons" }] : /* istanbul ignore next */ []));
1499
+ }
1500
+ onChange() {
1501
+ this.committed.emit(this.value());
1502
+ }
1503
+ onEnterPressed() {
1504
+ this.enterPressed.emit();
1505
+ }
1506
+ onInput(event) {
1507
+ this._commit(event.target.value);
1508
+ }
1509
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwInputComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
1510
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: YuwInputComponent, isStandalone: true, selector: "yuw-input", inputs: { inputmode: { classPropertyName: "inputmode", publicName: "inputmode", isSignal: true, isRequired: false, transformFunction: null }, maxlength: { classPropertyName: "maxlength", publicName: "maxlength", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { enterPressed: "enterPressed" }, host: { classAttribute: "contents" }, providers: [provideValueAccessor(YuwInputComponent)], queries: [{ propertyName: "_leftAddons", predicate: YuwLeftAddonDirective, isSignal: true }, { propertyName: "_rightAddons", predicate: YuwRightAddonDirective, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<hlm-field\n yuwFieldFeedback\n #feedback=\"yuwFieldFeedback\"\n class=\"min-w-0 data-[matches-spartan-invalid=true]:text-inherit\"\n [invalid]=\"invalid()\"\n [errorText]=\"errorText()\"\n>\n @if (_hasAddons()) {\n <hlm-input-group [class]=\"_classes()\">\n @if (_hasLeftAddon()) {\n <hlm-input-group-addon align=\"inline-start\">\n <ng-content select=\"yuw-left-addon\" />\n </hlm-input-group-addon>\n }\n\n <input\n hlmInputGroupInput\n [id]=\"_inputId()\"\n [type]=\"type()\"\n [attr.inputmode]=\"inputmode()\"\n [value]=\"value()\"\n [disabled]=\"_disabled()\"\n [readOnly]=\"readonly()\"\n [required]=\"required()\"\n [forceInvalid]=\"feedback.forcedInvalid()\"\n [attr.name]=\"name()\"\n [attr.autocomplete]=\"autocomplete()\"\n [attr.maxlength]=\"maxlength()\"\n [attr.placeholder]=\"placeholder()\"\n (input)=\"onInput($event)\"\n (change)=\"onChange()\"\n (blur)=\"_onBlur()\"\n (keydown.enter)=\"onEnterPressed()\"\n />\n\n @if (_hasRightAddon()) {\n <hlm-input-group-addon align=\"inline-end\">\n <ng-content select=\"yuw-right-addon\" />\n </hlm-input-group-addon>\n }\n </hlm-input-group>\n } @else {\n <input\n hlmInput\n [class]=\"_classes()\"\n [id]=\"_inputId()\"\n [type]=\"type()\"\n [attr.inputmode]=\"inputmode()\"\n [value]=\"value()\"\n [disabled]=\"_disabled()\"\n [readOnly]=\"readonly()\"\n [required]=\"required()\"\n [forceInvalid]=\"feedback.forcedInvalid()\"\n [attr.name]=\"name()\"\n [attr.autocomplete]=\"autocomplete()\"\n [attr.maxlength]=\"maxlength()\"\n [attr.placeholder]=\"placeholder()\"\n (input)=\"onInput($event)\"\n (change)=\"onChange()\"\n (blur)=\"_onBlur()\"\n (keydown.enter)=\"onEnterPressed()\"\n />\n }\n\n @if (feedback.showError()) {\n <hlm-field-description role=\"alert\" class=\"text-destructive\">{{ feedback.errorMessage() }}</hlm-field-description>\n } @else if (helperText(); as helper) {\n <hlm-field-description>{{ helper }}</hlm-field-description>\n }\n</hlm-field>\n", dependencies: [{ kind: "directive", type: HlmField, selector: "[hlmField],hlm-field", inputs: ["orientation"] }, { kind: "directive", type: HlmFieldDescription, selector: "[hlmFieldDescription],hlm-field-description", inputs: ["id"] }, { kind: "directive", type: YuwFieldFeedbackDirective, selector: "hlm-field[yuwFieldFeedback]", inputs: ["errorText", "invalid"], exportAs: ["yuwFieldFeedback"] }, { kind: "directive", type: HlmInput, selector: "[hlmInput]" }, { kind: "directive", type: HlmInputGroup, selector: "[hlmInputGroup],hlm-input-group" }, { kind: "directive", type: HlmInputGroupInput, selector: "input[hlmInputGroupInput]" }, { kind: "directive", type: HlmInputGroupAddon, selector: "[hlmInputGroupAddon],hlm-input-group-addon", inputs: ["align"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1511
+ }
1512
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwInputComponent, decorators: [{
1513
+ type: Component,
1514
+ args: [{ selector: 'yuw-input', imports: [
1515
+ HlmField,
1516
+ HlmFieldDescription,
1517
+ YuwFieldFeedbackDirective,
1518
+ HlmInput,
1519
+ HlmInputGroup,
1520
+ HlmInputGroupInput,
1521
+ HlmInputGroupAddon,
1522
+ ], providers: [provideValueAccessor(YuwInputComponent)], host: {
1523
+ class: 'contents',
1524
+ }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<hlm-field\n yuwFieldFeedback\n #feedback=\"yuwFieldFeedback\"\n class=\"min-w-0 data-[matches-spartan-invalid=true]:text-inherit\"\n [invalid]=\"invalid()\"\n [errorText]=\"errorText()\"\n>\n @if (_hasAddons()) {\n <hlm-input-group [class]=\"_classes()\">\n @if (_hasLeftAddon()) {\n <hlm-input-group-addon align=\"inline-start\">\n <ng-content select=\"yuw-left-addon\" />\n </hlm-input-group-addon>\n }\n\n <input\n hlmInputGroupInput\n [id]=\"_inputId()\"\n [type]=\"type()\"\n [attr.inputmode]=\"inputmode()\"\n [value]=\"value()\"\n [disabled]=\"_disabled()\"\n [readOnly]=\"readonly()\"\n [required]=\"required()\"\n [forceInvalid]=\"feedback.forcedInvalid()\"\n [attr.name]=\"name()\"\n [attr.autocomplete]=\"autocomplete()\"\n [attr.maxlength]=\"maxlength()\"\n [attr.placeholder]=\"placeholder()\"\n (input)=\"onInput($event)\"\n (change)=\"onChange()\"\n (blur)=\"_onBlur()\"\n (keydown.enter)=\"onEnterPressed()\"\n />\n\n @if (_hasRightAddon()) {\n <hlm-input-group-addon align=\"inline-end\">\n <ng-content select=\"yuw-right-addon\" />\n </hlm-input-group-addon>\n }\n </hlm-input-group>\n } @else {\n <input\n hlmInput\n [class]=\"_classes()\"\n [id]=\"_inputId()\"\n [type]=\"type()\"\n [attr.inputmode]=\"inputmode()\"\n [value]=\"value()\"\n [disabled]=\"_disabled()\"\n [readOnly]=\"readonly()\"\n [required]=\"required()\"\n [forceInvalid]=\"feedback.forcedInvalid()\"\n [attr.name]=\"name()\"\n [attr.autocomplete]=\"autocomplete()\"\n [attr.maxlength]=\"maxlength()\"\n [attr.placeholder]=\"placeholder()\"\n (input)=\"onInput($event)\"\n (change)=\"onChange()\"\n (blur)=\"_onBlur()\"\n (keydown.enter)=\"onEnterPressed()\"\n />\n }\n\n @if (feedback.showError()) {\n <hlm-field-description role=\"alert\" class=\"text-destructive\">{{ feedback.errorMessage() }}</hlm-field-description>\n } @else if (helperText(); as helper) {\n <hlm-field-description>{{ helper }}</hlm-field-description>\n }\n</hlm-field>\n" }]
1525
+ }], propDecorators: { _leftAddons: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => YuwLeftAddonDirective), { isSignal: true }] }], _rightAddons: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => YuwRightAddonDirective), { isSignal: true }] }], inputmode: [{ type: i0.Input, args: [{ isSignal: true, alias: "inputmode", required: false }] }], maxlength: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxlength", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], enterPressed: [{ type: i0.Output, args: ["enterPressed"] }] } });
1526
+
1527
+ /**
1528
+ * Displays a user or entity avatar with optional image, fallback text/initials, status badge, or overlapping group layout.
1529
+ *
1530
+ * Inputs:
1531
+ * - `size`: Avatar size (`'default'`, `'sm'`, `'lg'`). Default is `'default'`.
1532
+ * - `src`: Image URL for single-avatar mode. Omit to display fallback text.
1533
+ * - `alt`: Required. Accessible label for single-avatar mode and fallback text. User-facing text —
1534
+ * the consuming app is responsible for providing (and translating) it.
1535
+ * - `fallback`: Fallback text or initials shown when image is loading, unprovided, or fails to load.
1536
+ * - `badge`: Renders a status badge marker on the bottom-right corner (single-avatar mode).
1537
+ * - `group`: Array of item DTOs (`YuwAvatarGroupItemDto[]`) to render as an overlapping avatar group stack.
1538
+ * - `groupCount`: Overflow label string (e.g. `"+5"`) displayed at the end of an avatar group stack.
1539
+ * - `class`: Extra CSS classes merged onto the inner `hlm-avatar` element(s); merged last, so they win.
1540
+ *
1541
+ * Single Avatar Usage:
1542
+ * ```html
1543
+ * <yuw-avatar src="/path/to/user.png" alt="Jane Doe" fallback="JD" />
1544
+ * <yuw-avatar alt="Jane Doe" fallback="JD" badge />
1545
+ * ```
1546
+ *
1547
+ * Avatar Group Usage:
1548
+ * ```html
1549
+ * <yuw-avatar [group]="teamMembers" alt="Team" groupCount="+5" />
1550
+ * ```
1551
+ */
1552
+ class YuwAvatarComponent {
1553
+ constructor() {
1554
+ this.alt = input.required(...(ngDevMode ? [{ debugName: "alt" }] : /* istanbul ignore next */ []));
1555
+ this.badge = input(false, { ...(ngDevMode ? { debugName: "badge" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
1556
+ this.fallback = input(undefined, ...(ngDevMode ? [{ debugName: "fallback" }] : /* istanbul ignore next */ []));
1557
+ this.group = input(undefined, ...(ngDevMode ? [{ debugName: "group" }] : /* istanbul ignore next */ []));
1558
+ this.groupCount = input(undefined, ...(ngDevMode ? [{ debugName: "groupCount" }] : /* istanbul ignore next */ []));
1559
+ this.size = input('default', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
1560
+ this.src = input(undefined, ...(ngDevMode ? [{ debugName: "src" }] : /* istanbul ignore next */ []));
1561
+ this.userClass = input('', { ...(ngDevMode ? { debugName: "userClass" } : /* istanbul ignore next */ {}), alias: 'class' });
1562
+ this._isGroup = computed(() => (this.group()?.length ?? 0) > 0, ...(ngDevMode ? [{ debugName: "_isGroup" }] : /* istanbul ignore next */ []));
1563
+ }
1564
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwAvatarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1565
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: YuwAvatarComponent, isStandalone: true, selector: "yuw-avatar", inputs: { alt: { classPropertyName: "alt", publicName: "alt", isSignal: true, isRequired: true, transformFunction: null }, badge: { classPropertyName: "badge", publicName: "badge", isSignal: true, isRequired: false, transformFunction: null }, fallback: { classPropertyName: "fallback", publicName: "fallback", isSignal: true, isRequired: false, transformFunction: null }, group: { classPropertyName: "group", publicName: "group", isSignal: true, isRequired: false, transformFunction: null }, groupCount: { classPropertyName: "groupCount", publicName: "groupCount", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, src: { classPropertyName: "src", publicName: "src", isSignal: true, isRequired: false, transformFunction: null }, userClass: { classPropertyName: "userClass", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "contents" }, ngImport: i0, template: "<ng-template #avatarBox let-src=\"src\" let-alt=\"alt\" let-fallback=\"fallback\" let-showBadge=\"showBadge\">\n <hlm-avatar [size]=\"size()\" [class]=\"userClass()\">\n @if (src) {\n <img hlmAvatarImage [src]=\"src\" [alt]=\"alt ?? ''\" />\n }\n <span hlmAvatarFallback>{{ fallback }}</span>\n\n @if (showBadge) {\n <span hlmAvatarBadge>\n <ng-content select=\"[yuwAvatarBadgeIcon]\" />\n </span>\n }\n </hlm-avatar>\n</ng-template>\n\n@if (_isGroup()) {\n <div hlmAvatarGroup>\n @for (entry of group(); track entry.alt + '|' + (entry.src ?? '')) {\n <ng-container\n [ngTemplateOutlet]=\"avatarBox\"\n [ngTemplateOutletContext]=\"{ src: entry.src, alt: entry.alt, fallback: entry.fallback, showBadge: false }\"\n />\n }\n\n @if (groupCount()) {\n <span hlmAvatarGroupCount>{{ groupCount() }}</span>\n }\n </div>\n} @else {\n <ng-container\n [ngTemplateOutlet]=\"avatarBox\"\n [ngTemplateOutletContext]=\"{ src: src(), alt: alt(), fallback: fallback(), showBadge: badge() }\"\n />\n}\n", dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: i1$4.HlmAvatar, selector: "hlm-avatar", inputs: ["size"] }, { kind: "directive", type: i1$4.HlmAvatarBadge, selector: "[hlmAvatarBadge],hlm-avatar-badge" }, { kind: "directive", type: i1$4.HlmAvatarFallback, selector: "[hlmAvatarFallback]", exportAs: ["hlmAvatarFallback"] }, { kind: "directive", type: i1$4.HlmAvatarGroup, selector: "[hlmAvatarGroup],hlm-avatar-group" }, { kind: "directive", type: i1$4.HlmAvatarGroupCount, selector: "[hlmAvatarGroupCount],hlm-avatar-group-count" }, { kind: "directive", type: i1$4.HlmAvatarImage, selector: "img[hlmAvatarImage]", exportAs: ["hlmAvatarImage"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1566
+ }
1567
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwAvatarComponent, decorators: [{
1568
+ type: Component,
1569
+ args: [{ selector: 'yuw-avatar', imports: [NgTemplateOutlet, ...HlmAvatarImports], host: {
1570
+ class: 'contents',
1571
+ }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-template #avatarBox let-src=\"src\" let-alt=\"alt\" let-fallback=\"fallback\" let-showBadge=\"showBadge\">\n <hlm-avatar [size]=\"size()\" [class]=\"userClass()\">\n @if (src) {\n <img hlmAvatarImage [src]=\"src\" [alt]=\"alt ?? ''\" />\n }\n <span hlmAvatarFallback>{{ fallback }}</span>\n\n @if (showBadge) {\n <span hlmAvatarBadge>\n <ng-content select=\"[yuwAvatarBadgeIcon]\" />\n </span>\n }\n </hlm-avatar>\n</ng-template>\n\n@if (_isGroup()) {\n <div hlmAvatarGroup>\n @for (entry of group(); track entry.alt + '|' + (entry.src ?? '')) {\n <ng-container\n [ngTemplateOutlet]=\"avatarBox\"\n [ngTemplateOutletContext]=\"{ src: entry.src, alt: entry.alt, fallback: entry.fallback, showBadge: false }\"\n />\n }\n\n @if (groupCount()) {\n <span hlmAvatarGroupCount>{{ groupCount() }}</span>\n }\n </div>\n} @else {\n <ng-container\n [ngTemplateOutlet]=\"avatarBox\"\n [ngTemplateOutletContext]=\"{ src: src(), alt: alt(), fallback: fallback(), showBadge: badge() }\"\n />\n}\n" }]
1572
+ }], propDecorators: { alt: [{ type: i0.Input, args: [{ isSignal: true, alias: "alt", required: true }] }], badge: [{ type: i0.Input, args: [{ isSignal: true, alias: "badge", required: false }] }], fallback: [{ type: i0.Input, args: [{ isSignal: true, alias: "fallback", required: false }] }], group: [{ type: i0.Input, args: [{ isSignal: true, alias: "group", required: false }] }], groupCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "groupCount", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], src: [{ type: i0.Input, args: [{ isSignal: true, alias: "src", required: false }] }], userClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }] } });
1573
+
1574
+ /**
1575
+ * Makes a `<yuw-button>` the trigger of the surrounding `<yuw-popover>`.
1576
+ *
1577
+ * The helm trigger directive's selector only matches a native `button`, so composing the brain
1578
+ * directive here is what lets the popover use `<yuw-button>` rather than a bare `[hlmBtn]` element.
1579
+ * Brain needs three things from its host, all of which `<yuw-button>` provides: the `click` that
1580
+ * bubbles up from the inner button, the `aria-expanded`/`data-state` attributes, and a host box to
1581
+ * anchor the panel against — hence `<yuw-button>`'s `inline-flex` host, since a `display: contents`
1582
+ * host has no rect for the overlay to position from.
1583
+ *
1584
+ * `data-slot` mirrors the helm directive so the popover stylesheet targets both identically.
1585
+ */
1586
+ class YuwPopoverTriggerDirective {
1587
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwPopoverTriggerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
1588
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwPopoverTriggerDirective, isStandalone: true, selector: "yuw-button[yuwPopoverTriggerFor], yuw-button[yuwPopoverTriggerButton]", host: { attributes: { "data-slot": "popover-trigger" } }, hostDirectives: [{ directive: i1$5.BrnPopoverTrigger, inputs: ["id", "id", "brnPopoverTriggerFor", "yuwPopoverTriggerFor", "type", "type"] }], ngImport: i0 }); }
1589
+ }
1590
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwPopoverTriggerDirective, decorators: [{
1591
+ type: Directive,
1592
+ args: [{
1593
+ selector: 'yuw-button[yuwPopoverTriggerFor], yuw-button[yuwPopoverTriggerButton]',
1594
+ hostDirectives: [
1595
+ { directive: BrnPopoverTrigger, inputs: ['id', 'brnPopoverTriggerFor: yuwPopoverTriggerFor', 'type'] },
1596
+ ],
1597
+ host: { 'data-slot': 'popover-trigger' },
1598
+ }]
1599
+ }] });
1600
+
1601
+ /**
1602
+ * Popover component for displaying anchored floating overlay panels.
1603
+ *
1604
+ * Inputs / Models:
1605
+ * - `open`: Two-way open/closed state (`boolean`). Drive directly via `[(open)]` to open/close programmatically.
1606
+ * - `showTrigger`: Whether to render the trigger button. Set `false` when opening only via `[(open)]`.
1607
+ * - `align`: Panel alignment relative to trigger (`'start'`, `'center'`, `'end'`). Default is `'center'`.
1608
+ * - `sideOffset`: Pixel offset between the trigger and the panel. Default is `4`.
1609
+ * - `offsetX`: Pixel offset for X sides. Positive px for right, negative for left side.
1610
+ * - `title`: Optional header title text. User-facing text the consuming app is responsible for translating.
1611
+ * - `description`: Optional header description text. User-facing text the consuming app is responsible for translating.
1612
+ * - `panelClass`: Extra classes merged onto the popover panel (e.g. `w-80` to widen it). They win
1613
+ * over the library defaults via `twMerge`.
1614
+ * - `triggerVariant`: Button style variant for the trigger button.
1615
+ * - `triggerColor`: Brand color theme for the trigger button (any `YuwColorDto` value). Default is
1616
+ * `'neutral'`.
1617
+ * - `triggerSize`: Button size for the trigger button.
1618
+ * - `triggerTransparent`: Strips the trigger's background and border in every state (rest, hover,
1619
+ * open), for triggers whose projected content is the whole control — an avatar, a name, a chevron.
1620
+ * - `triggerClass`: Extra classes merged onto the trigger button, last, so they beat both the
1621
+ * variant classes and `triggerTransparent` (e.g. `h-auto p-0` to drop the button's own box).
1622
+ *
1623
+ * The panel is always anchored to the trigger, including when `open` is set from code without a
1624
+ * click on it; the brain trigger only records its element on click.
1625
+ *
1626
+ * The trigger is a `<yuw-button>`; `YuwPopoverTriggerDirective` composes the brain trigger onto it,
1627
+ * so the popover reuses our button component instead of applying `[hlmBtn]` directly.
1628
+ *
1629
+ * Usage:
1630
+ * ```html
1631
+ * <yuw-popover [(open)]="isOpen" title="Notifications" description="You're all caught up.">
1632
+ * <ng-container yuwPopoverTrigger>View Notifications</ng-container>
1633
+ *
1634
+ * <p>Popover content body goes here.</p>
1635
+ * </yuw-popover>
1636
+ * ```
1637
+ */
1638
+ class YuwPopoverComponent {
1639
+ constructor() {
1640
+ this._trigger = viewChild('trigger', { ...(ngDevMode ? { debugName: "_trigger" } : /* istanbul ignore next */ {}), read: ElementRef });
1641
+ this.align = input('center', ...(ngDevMode ? [{ debugName: "align" }] : /* istanbul ignore next */ []));
1642
+ this.description = input(undefined, ...(ngDevMode ? [{ debugName: "description" }] : /* istanbul ignore next */ []));
1643
+ this.offsetX = input(0, ...(ngDevMode ? [{ debugName: "offsetX" }] : /* istanbul ignore next */ []));
1644
+ this.open = model(false, ...(ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []));
1645
+ this.panelClass = input(undefined, ...(ngDevMode ? [{ debugName: "panelClass" }] : /* istanbul ignore next */ []));
1646
+ this.showTrigger = input(true, { ...(ngDevMode ? { debugName: "showTrigger" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
1647
+ this.sideOffset = input(4, ...(ngDevMode ? [{ debugName: "sideOffset" }] : /* istanbul ignore next */ []));
1648
+ this.title = input(undefined, ...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
1649
+ this.triggerClass = input('', ...(ngDevMode ? [{ debugName: "triggerClass" }] : /* istanbul ignore next */ []));
1650
+ this.triggerColor = input('neutral', ...(ngDevMode ? [{ debugName: "triggerColor" }] : /* istanbul ignore next */ []));
1651
+ this.triggerSize = input('default', ...(ngDevMode ? [{ debugName: "triggerSize" }] : /* istanbul ignore next */ []));
1652
+ this.triggerTransparent = input(false, { ...(ngDevMode ? { debugName: "triggerTransparent" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
1653
+ this.triggerVariant = input('outline', ...(ngDevMode ? [{ debugName: "triggerVariant" }] : /* istanbul ignore next */ []));
1654
+ this._popoverState = computed(() => (this.open() ? 'open' : 'closed'), ...(ngDevMode ? [{ debugName: "_popoverState" }] : /* istanbul ignore next */ []));
1655
+ }
1656
+ onOpenChange(state) {
1657
+ this.open.set(state === 'open');
1658
+ }
1659
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwPopoverComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1660
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: YuwPopoverComponent, isStandalone: true, selector: "yuw-popover", inputs: { align: { classPropertyName: "align", publicName: "align", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, offsetX: { classPropertyName: "offsetX", publicName: "offsetX", isSignal: true, isRequired: false, transformFunction: null }, open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, panelClass: { classPropertyName: "panelClass", publicName: "panelClass", isSignal: true, isRequired: false, transformFunction: null }, showTrigger: { classPropertyName: "showTrigger", publicName: "showTrigger", isSignal: true, isRequired: false, transformFunction: null }, sideOffset: { classPropertyName: "sideOffset", publicName: "sideOffset", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, triggerClass: { classPropertyName: "triggerClass", publicName: "triggerClass", isSignal: true, isRequired: false, transformFunction: null }, triggerColor: { classPropertyName: "triggerColor", publicName: "triggerColor", isSignal: true, isRequired: false, transformFunction: null }, triggerSize: { classPropertyName: "triggerSize", publicName: "triggerSize", isSignal: true, isRequired: false, transformFunction: null }, triggerTransparent: { classPropertyName: "triggerTransparent", publicName: "triggerTransparent", isSignal: true, isRequired: false, transformFunction: null }, triggerVariant: { classPropertyName: "triggerVariant", publicName: "triggerVariant", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { open: "openChange" }, host: { classAttribute: "contents" }, viewQueries: [{ propertyName: "_trigger", first: true, predicate: ["trigger"], descendants: true, read: ElementRef, isSignal: true }], ngImport: i0, template: "<div\n hlmPopover\n [state]=\"_popoverState()\"\n [align]=\"align()\"\n [sideOffset]=\"sideOffset()\"\n [offsetX]=\"offsetX()\"\n [attachTo]=\"_trigger()\"\n (stateChanged)=\"onOpenChange($event)\"\n>\n @if (showTrigger()) {\n <yuw-button\n #trigger\n yuwPopoverTriggerButton\n [color]=\"triggerColor()\"\n [variant]=\"triggerVariant()\"\n [size]=\"triggerSize()\"\n [transparent]=\"triggerTransparent()\"\n [class]=\"triggerClass()\"\n >\n <ng-content select=\"[yuwPopoverTrigger]\" />\n </yuw-button>\n }\n\n <hlm-popover-content *hlmPopoverPortal [class]=\"panelClass()\">\n @if (title() || description()) {\n <div hlmPopoverHeader>\n @if (title()) {\n <p hlmPopoverTitle>{{ title() }}</p>\n }\n @if (description()) {\n <p hlmPopoverDescription>{{ description() }}</p>\n }\n </div>\n }\n\n <ng-content />\n </hlm-popover-content>\n</div>\n", dependencies: [{ kind: "directive", type: i1$6.HlmPopover, selector: "[hlmPopover],hlm-popover" }, { kind: "directive", type: i1$6.HlmPopoverContent, selector: "[hlmPopoverContent],hlm-popover-content" }, { kind: "directive", type: i1$6.HlmPopoverDescription, selector: "[hlmPopoverDescription]" }, { kind: "directive", type: i1$6.HlmPopoverHeader, selector: "[hlmPopoverHeader],hlm-popover-header" }, { kind: "directive", type: i1$6.HlmPopoverPortal, selector: "[hlmPopoverPortal]" }, { kind: "directive", type: i1$6.HlmPopoverTitle, selector: "[hlmPopoverTitle]" }, { 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: YuwPopoverTriggerDirective, selector: "yuw-button[yuwPopoverTriggerFor], yuw-button[yuwPopoverTriggerButton]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1661
+ }
1662
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwPopoverComponent, decorators: [{
1663
+ type: Component,
1664
+ args: [{ selector: 'yuw-popover', imports: [...HlmPopoverImports, YuwButtonComponent, YuwPopoverTriggerDirective], host: {
1665
+ class: 'contents',
1666
+ }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n hlmPopover\n [state]=\"_popoverState()\"\n [align]=\"align()\"\n [sideOffset]=\"sideOffset()\"\n [offsetX]=\"offsetX()\"\n [attachTo]=\"_trigger()\"\n (stateChanged)=\"onOpenChange($event)\"\n>\n @if (showTrigger()) {\n <yuw-button\n #trigger\n yuwPopoverTriggerButton\n [color]=\"triggerColor()\"\n [variant]=\"triggerVariant()\"\n [size]=\"triggerSize()\"\n [transparent]=\"triggerTransparent()\"\n [class]=\"triggerClass()\"\n >\n <ng-content select=\"[yuwPopoverTrigger]\" />\n </yuw-button>\n }\n\n <hlm-popover-content *hlmPopoverPortal [class]=\"panelClass()\">\n @if (title() || description()) {\n <div hlmPopoverHeader>\n @if (title()) {\n <p hlmPopoverTitle>{{ title() }}</p>\n }\n @if (description()) {\n <p hlmPopoverDescription>{{ description() }}</p>\n }\n </div>\n }\n\n <ng-content />\n </hlm-popover-content>\n</div>\n" }]
1667
+ }], propDecorators: { _trigger: [{ type: i0.ViewChild, args: ['trigger', { ...{ read: ElementRef }, isSignal: true }] }], align: [{ type: i0.Input, args: [{ isSignal: true, alias: "align", required: false }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }], offsetX: [{ type: i0.Input, args: [{ isSignal: true, alias: "offsetX", required: false }] }], open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }, { type: i0.Output, args: ["openChange"] }], panelClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "panelClass", required: false }] }], showTrigger: [{ type: i0.Input, args: [{ isSignal: true, alias: "showTrigger", required: false }] }], sideOffset: [{ type: i0.Input, args: [{ isSignal: true, alias: "sideOffset", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], 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 }] }], triggerTransparent: [{ type: i0.Input, args: [{ isSignal: true, alias: "triggerTransparent", required: false }] }], triggerVariant: [{ type: i0.Input, args: [{ isSignal: true, alias: "triggerVariant", required: false }] }] } });
1668
+
1669
+ /**
1670
+ * Makes a `<yuw-button>` the trigger of the surrounding `<yuw-sheet>`.
1671
+ *
1672
+ * Mirrors `YuwDialogTriggerDirective`: the helm trigger only matches a native `button`, so the brain
1673
+ * directive is composed here instead, keeping `[hlmBtn]` inside `<yuw-button>`. `side` is forwarded
1674
+ * so a trigger can override which edge the sheet appears from.
1675
+ */
1676
+ class YuwSheetTriggerDirective {
1677
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwSheetTriggerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
1678
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwSheetTriggerDirective, isStandalone: true, selector: "yuw-button[yuwSheetTriggerButton]", host: { attributes: { "data-slot": "sheet-trigger" } }, hostDirectives: [{ directive: i1$7.BrnSheetTrigger, inputs: ["id", "id", "side", "side", "type", "type"] }], ngImport: i0 }); }
1679
+ }
1680
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwSheetTriggerDirective, decorators: [{
1681
+ type: Directive,
1682
+ args: [{
1683
+ selector: 'yuw-button[yuwSheetTriggerButton]',
1684
+ hostDirectives: [{ directive: BrnSheetTrigger, inputs: ['id', 'side', 'type'] }],
1685
+ host: { 'data-slot': 'sheet-trigger' },
1686
+ }]
1687
+ }] });
1688
+ /** Closes the surrounding `<yuw-sheet>` when the host `<yuw-button>` is activated. */
1689
+ class YuwSheetCloseDirective {
1690
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwSheetCloseDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
1691
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwSheetCloseDirective, isStandalone: true, selector: "yuw-button[yuwSheetClose]", host: { attributes: { "data-slot": "sheet-close" } }, hostDirectives: [{ directive: i1$7.BrnSheetClose }], ngImport: i0 }); }
1692
+ }
1693
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwSheetCloseDirective, decorators: [{
1694
+ type: Directive,
1695
+ args: [{
1696
+ selector: 'yuw-button[yuwSheetClose]',
1697
+ hostDirectives: [BrnSheetClose],
1698
+ host: { 'data-slot': 'sheet-close' },
1699
+ }]
1700
+ }] });
1701
+
1702
+ /**
1703
+ * Marks an element as the sheet's footer content, projected into the footer slot.
1704
+ * Its presence is also what makes the footer render at all — without it the sheet
1705
+ * shows no empty footer strip.
1706
+ */
1707
+ class YuwSheetFooterDirective {
1708
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwSheetFooterDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
1709
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwSheetFooterDirective, isStandalone: true, selector: "[yuwSheetFooter]", ngImport: i0 }); }
1710
+ }
1711
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwSheetFooterDirective, decorators: [{
1712
+ type: Directive,
1713
+ args: [{
1714
+ selector: '[yuwSheetFooter]',
1715
+ }]
1716
+ }] });
1717
+
1718
+ const YUW_SHEET_OVERLAY_BASE_CLASS = 'data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 isolate bg-black/10 duration-100 supports-backdrop-filter:backdrop-blur-xs';
1719
+ /**
1720
+ * Slide-in sheet overlay panel component for side drawers, dialogs, and detail views.
1721
+ *
1722
+ * Accessibility: provide either `title` or `ariaLabel` — a modal panel without an accessible name
1723
+ * is announced as an anonymous dialog by screen readers.
1724
+ *
1725
+ * Inputs / Models:
1726
+ * - `open`: Two-way open/closed state (`boolean`). Drive directly via `[(open)]` to open/close programmatically.
1727
+ * - `showTrigger`: Whether to render the trigger button. Set `false` when opening only via `[(open)]`.
1728
+ * - `side`: Edge of the screen the panel slides in from (`'top'`, `'bottom'`, `'left'`, `'right'`). Default is `'right'`.
1729
+ * - `title`: Optional header title text. User-facing text the consuming app is responsible for translating.
1730
+ * - `description`: Optional header description text. User-facing text the consuming app is responsible for translating.
1731
+ * - `ariaLabel`: Accessible name for the sheet when no visible `title` is rendered. User-facing
1732
+ * text the consuming app is responsible for translating.
1733
+ * - `closeLabel`: Accessible label of the corner close (×) button. When set, the close button
1734
+ * renders and screen readers read this label; when absent there is no close button. User-facing
1735
+ * text the consuming app is responsible for translating.
1736
+ * - `panelClass`: Extra classes merged onto the sheet panel (e.g. `sm:max-w-lg` to widen it).
1737
+ * They win over the library defaults via `twMerge`. Note `twMerge` resolves per variant group, so a
1738
+ * plain utility does not displace a variant-prefixed default — to override `data-[side=left]:w-3/4`
1739
+ * the class has to be `data-[side=left]:w-64`, not `w-64`.
1740
+ * - `overlayClass`: Extra classes for the backdrop, for a sheet that should not dim the whole
1741
+ * viewport. Applied through `setOverlayClass` rather than a template binding: the backdrop lives in
1742
+ * the overlay too, and the helm's own class always wins the `class` input it exposes.
1743
+ * - `scrollStrategy`: What happens to page scroll while open. Defaults to the brain's blocking
1744
+ * strategy; pass `'reposition'` for a panel that should leave the page scrollable.
1745
+ * - `ariaModal`: Whether the sheet claims the rest of the page is hidden. Leave `true` for a real
1746
+ * modal; set `false` when content outside stays visible and usable, so the claim stays honest.
1747
+ * - `closeOnOutsidePointerEvents`: Whether a pointer press outside the panel closes it, backdrop
1748
+ * clicks included. Default is `true`, matching the brain from `@spartan-ng/brain` 1.3.4 on; pass
1749
+ * `false` for a panel that must be dismissed deliberately.
1750
+ * - `triggerVariant`: Button style variant for the trigger button.
1751
+ * - `triggerSize`: Button size for the trigger button.
1752
+ *
1753
+ * Usage:
1754
+ * ```html
1755
+ * <yuw-sheet [(open)]="isOpen" side="right" title="Edit Profile" description="Update your account details." closeLabel="Close">
1756
+ * <ng-container yuwSheetTrigger>Edit Profile</ng-container>
1757
+ *
1758
+ * <p>Sheet form content goes here.</p>
1759
+ *
1760
+ * <div yuwSheetFooter>
1761
+ * <yuw-button (clicked)="save()">Save Changes</yuw-button>
1762
+ * </div>
1763
+ * </yuw-sheet>
1764
+ * ```
1765
+ */
1766
+ class YuwSheetComponent {
1767
+ constructor() {
1768
+ this.hasFooter = contentChild(YuwSheetFooterDirective, ...(ngDevMode ? [{ debugName: "hasFooter" }] : /* istanbul ignore next */ []));
1769
+ this.sheet = viewChild.required(HlmSheet);
1770
+ this.ariaLabel = input(undefined, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
1771
+ this.ariaModal = input(true, { ...(ngDevMode ? { debugName: "ariaModal" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
1772
+ this.closeLabel = input(undefined, ...(ngDevMode ? [{ debugName: "closeLabel" }] : /* istanbul ignore next */ []));
1773
+ this.closeOnOutsidePointerEvents = input(true, { ...(ngDevMode ? { debugName: "closeOnOutsidePointerEvents" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
1774
+ this.description = input(undefined, ...(ngDevMode ? [{ debugName: "description" }] : /* istanbul ignore next */ []));
1775
+ this.open = model(false, ...(ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []));
1776
+ this.overlayClass = input(undefined, ...(ngDevMode ? [{ debugName: "overlayClass" }] : /* istanbul ignore next */ []));
1777
+ this.panelClass = input(undefined, ...(ngDevMode ? [{ debugName: "panelClass" }] : /* istanbul ignore next */ []));
1778
+ this.scrollStrategy = input(null, ...(ngDevMode ? [{ debugName: "scrollStrategy" }] : /* istanbul ignore next */ []));
1779
+ this.showTrigger = input(true, { ...(ngDevMode ? { debugName: "showTrigger" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
1780
+ this.side = input('right', ...(ngDevMode ? [{ debugName: "side" }] : /* istanbul ignore next */ []));
1781
+ this.title = input(undefined, ...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
1782
+ this.triggerSize = input('default', ...(ngDevMode ? [{ debugName: "triggerSize" }] : /* istanbul ignore next */ []));
1783
+ this.triggerVariant = input('outline', ...(ngDevMode ? [{ debugName: "triggerVariant" }] : /* istanbul ignore next */ []));
1784
+ this._sheetState = computed(() => (this.open() ? 'open' : 'closed'), ...(ngDevMode ? [{ debugName: "_sheetState" }] : /* istanbul ignore next */ []));
1785
+ effect(() => {
1786
+ const overlayClass = this.overlayClass();
1787
+ if (overlayClass === undefined)
1788
+ return;
1789
+ this.sheet().setOverlayClass(`${YUW_SHEET_OVERLAY_BASE_CLASS} ${overlayClass}`);
1790
+ });
1791
+ }
1792
+ onStateChanged(state) {
1793
+ this.open.set(state === 'open');
1794
+ }
1795
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwSheetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1796
+ 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 }, 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 }], 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 <div class=\"flex-1 overflow-y-auto px-4\">\n <ng-content />\n </div>\n\n @if (hasFooter()) {\n <div hlmSheetFooter>\n <ng-content select=\"[yuwSheetFooter]\" />\n </div>\n }\n\n @if (closeLabel()) {\n <div class=\"absolute inset-e-3 top-3\">\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 </div>\n }\n </hlm-sheet-content>\n</hlm-sheet>\n", dependencies: [{ kind: "component", type: i1$8.HlmSheet, selector: "hlm-sheet", exportAs: ["hlmSheet"] }, { kind: "component", type: i1$8.HlmSheetContent, selector: "hlm-sheet-content", inputs: ["showCloseButton"] }, { kind: "directive", type: i1$8.HlmSheetDescription, selector: "[hlmSheetDescription]" }, { kind: "directive", type: i1$8.HlmSheetFooter, selector: "[hlmSheetFooter],hlm-sheet-footer" }, { kind: "directive", type: i1$8.HlmSheetHeader, selector: "[hlmSheetHeader],hlm-sheet-header" }, { kind: "directive", type: i1$8.HlmSheetPortal, selector: "[hlmSheetPortal]" }, { kind: "directive", type: i1$8.HlmSheetTitle, selector: "[hlmSheetTitle]" }, { 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 }); }
1797
+ }
1798
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwSheetComponent, decorators: [{
1799
+ type: Component,
1800
+ args: [{ selector: 'yuw-sheet', imports: [...HlmSheetImports, YuwButtonComponent, YuwSheetTriggerDirective, YuwSheetCloseDirective, NgIcon], providers: [provideIcons({ lucideX })], host: {
1801
+ class: 'contents',
1802
+ }, 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 <div class=\"flex-1 overflow-y-auto px-4\">\n <ng-content />\n </div>\n\n @if (hasFooter()) {\n <div hlmSheetFooter>\n <ng-content select=\"[yuwSheetFooter]\" />\n </div>\n }\n\n @if (closeLabel()) {\n <div class=\"absolute inset-e-3 top-3\">\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 </div>\n }\n </hlm-sheet-content>\n</hlm-sheet>\n" }]
1803
+ }], ctorParameters: () => [], propDecorators: { hasFooter: [{ type: i0.ContentChild, args: [i0.forwardRef(() => YuwSheetFooterDirective), { 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 }] }], 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 }] }] } });
1804
+ const YuwSheetImports = [YuwSheetComponent, YuwSheetFooterDirective];
1805
+
1806
+ /** Binary-step unit symbols, which are not user copy and so need no translation. */
1807
+ const UNITS = ['B', 'KB', 'MB', 'GB'];
1808
+ /**
1809
+ * Formats a byte count the way file pickers show it: `512 B`, `1.5 KB`, `1 MB`.
1810
+ *
1811
+ * Uses 1024 steps, no more than one decimal, and stops at `GB`. The decimal mark is always `.`, so
1812
+ * the output is locale-independent.
1813
+ *
1814
+ * @param bytes Size in bytes.
1815
+ * @returns The size with the largest unit that keeps the number at or above 1.
1816
+ */
1817
+ function formatFileSize(bytes) {
1818
+ let value = bytes;
1819
+ let unit = 0;
1820
+ while (value >= 1024 && unit < UNITS.length - 1) {
1821
+ value /= 1024;
1822
+ unit++;
1329
1823
  }
1330
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwFieldFeedbackDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
1331
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.22", type: YuwFieldFeedbackDirective, isStandalone: true, selector: "hlm-field[yuwFieldFeedback]", inputs: { errorText: { classPropertyName: "errorText", publicName: "errorText", isSignal: true, isRequired: false, transformFunction: null }, invalid: { classPropertyName: "invalid", publicName: "invalid", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "focusout": "_blurred.set(true)" } }, exportAs: ["yuwFieldFeedback"], ngImport: i0 }); }
1332
- }
1333
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwFieldFeedbackDirective, decorators: [{
1334
- type: Directive,
1335
- args: [{
1336
- selector: 'hlm-field[yuwFieldFeedback]',
1337
- exportAs: 'yuwFieldFeedback',
1338
- host: {
1339
- '(focusout)': '_blurred.set(true)',
1340
- },
1341
- }]
1342
- }], propDecorators: { errorText: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorText", required: false }] }], invalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalid", required: false }] }] } });
1343
- function firstErrorMessage(errors) {
1344
- return Object.values(errors ?? {}).find((error) => typeof error?.message === 'string')?.message;
1824
+ return `${Number.isInteger(value) ? value : value.toFixed(1)} ${UNITS[unit]}`;
1345
1825
  }
1346
1826
 
1347
1827
  /** Module-level counter backing each instance's stable fallback `id`. */
1348
- let nextYuwInputId = 0;
1828
+ let nextYuwInputFileId = 0;
1349
1829
  /**
1350
- * Single-line text input control supporting two-way value binding, form controls (`formControlName`, `ngModel`),
1351
- * validation styling, and left/right addon slots.
1830
+ * File picker with two layouts, supporting two-way binding, form controls (`formControlName`,
1831
+ * `ngModel`), validation styling and helper/error text.
1832
+ *
1833
+ * `avatar` (default) shows a `yuw-avatar` with the chosen image — or `src` while nothing is chosen —
1834
+ * beside an upload button, like a profile-photo field. `inline` is a full-width outline button with
1835
+ * an upload icon; once a file is chosen, the button is replaced by a single line showing its name, size and a remove icon.
1836
+ * With several files the line reads `countLabel(n)` and opens the list, one removable row each — in
1837
+ * a popover from `md` up and a bottom sheet below it, like the list-toolbar filters.
1838
+ *
1839
+ * Removing never edits the value: the X emits `removed` with the `File` and the consumer decides
1840
+ * (drop it from `value`, confirm first, call an API, …). The native picker always replaces the
1841
+ * previous selection. Because the button is hidden while files are chosen, the consumer must
1842
+ * clear `value` in `removed` for the picker to come back.
1843
+ *
1844
+ * The value is always an array of `File` — empty when nothing is chosen, one item when `multiple`
1845
+ * is off. Writing `[]` (or `null`, e.g. `control.reset()`) clears the native picker too. Setting a
1846
+ * non-empty value programmatically only updates `value`: browsers do not allow scripts to fill a
1847
+ * file input, so the native control keeps showing its last user selection.
1352
1848
  *
1353
1849
  * Inputs / Models:
1354
- * - `value`: Two-way text string.
1355
- * - `inputId`: `id` applied to the native input, for external `<label for>` association.
1356
- * - `type`: HTML input type (`'text'`, `'email'`, `'number'`, etc.). Default is `'text'`.
1357
- * - `size`: Control height (`'default'` 40px, `'xs'` 28px, `'sm'` 36px, `'lg'` 44px), matching the
1358
- * `<yuw-button>` size of the same name. Default is `'default'`.
1359
- * - `inputmode`: Virtual keyboard hint (e.g. `'numeric'`).
1360
- * - `disabled`: Disables input interaction.
1361
- * - `readonly`: Makes the field read-only.
1850
+ * - `value`: Two-way `File[]` selection.
1851
+ * - `variant`: `'avatar'` or `'inline'`. Default is `'avatar'`.
1852
+ * - `uploadLabel`: Text of the upload button. User-facing text — the consuming app provides and
1853
+ * translates it; required, there is no default copy.
1854
+ * - `removeLabel`: Accessible label of each remove icon (`inline` only). Required for `inline`.
1855
+ * - `countLabel`: Builds the text of the multi-file box from the file count, e.g.
1856
+ * `(n) => \`${n} files selected\`` (`inline` with `multiple` only). Required for that case.
1857
+ * - `alt`: Accessible label of the avatar image (`avatar` only), also the source of its fallback.
1858
+ * - `fallback`: Initials shown when there is no image (`avatar` only).
1859
+ * - `src`: Current image shown while no file is chosen (`avatar` only), e.g. the saved photo.
1860
+ * - `accept`: Native `accept` filter (e.g. `'image/*,.pdf'`).
1861
+ * - `multiple`: Allows choosing more than one file; the avatar previews the first. Default is `false`.
1862
+ * - `size`: Height of the controls (`'default'`, `'xs'`, `'sm'`, `'lg'`), matching `<yuw-input>`.
1863
+ * Default is `'default'`.
1864
+ * - `inputId`: `id` applied to the hidden native input.
1865
+ * - `disabled`: Disables the picker and the remove icons.
1362
1866
  * - `required`: Marks the field as required.
1363
- * - `invalid`: Forces invalid styling. Applied from the first blur on, so a pristine field is not flagged while typing.
1867
+ * - `invalid`: Forces invalid styling. Applied from the first blur on.
1364
1868
  * - `helperText`: Hint shown under the field. Replaced by the error while one is displayed.
1365
- * - `errorText`: Error shown under the field while it is in its error state (form validation or
1366
- * `invalid`). Overrides the `message` carried by the bound control's validation errors (signal or
1367
- * reactive forms); required when no such message exists.
1869
+ * - `errorText`: Error shown under the field while it is in its error state. Overrides the `message`
1870
+ * carried by the bound control's validation errors.
1368
1871
  * - `name`: HTML `name` attribute.
1369
- * - `autocomplete`: Native `autocomplete` attribute.
1370
- * - `maxlength`: Hard cap on character count, enforced natively by the browser.
1371
- * - `placeholder`: Hint text shown inside the empty field.
1372
- * - `class`: Extra classes merged onto the visual root (the input, or the input group when addons are present).
1872
+ * - `class`: Extra classes merged last onto the avatar (`avatar`) or the inline stack (`inline`).
1373
1873
  *
1374
1874
  * Outputs:
1375
- * - `committed`: Emits the current value on the native `change` event (blur/enter).
1875
+ * - `removed`: Emits the `File` whose remove icon was pressed (`inline` only).
1376
1876
  *
1377
1877
  * Usage:
1378
1878
  * ```html
1379
- * <yuw-input [(value)]="username" placeholder="Enter username..." />
1380
- *
1381
- * <yuw-input formControlName="email" type="email">
1382
- * <yuw-left-addon><ng-icon name="lucideMail" /></yuw-left-addon>
1383
- * </yuw-input>
1879
+ * <yuw-input-file [(value)]="files" accept="image/*" [src]="family.imageUrl" [alt]="family.name"
1880
+ * [fallback]="initials" uploadLabel="Upload photo" />
1881
+ * <yuw-input-file variant="inline" multiple [(value)]="files" uploadLabel="Upload files"
1882
+ * removeLabel="Remove" [countLabel]="countLabel" (removed)="files.set(files().filter((f) => f !== $event))" />
1384
1883
  * ```
1385
1884
  */
1386
- class YuwInputComponent extends YuwTextFieldBase {
1885
+ class YuwInputFileComponent extends YuwValueAccessorBase {
1387
1886
  constructor() {
1388
- super(...arguments);
1389
- this._leftAddons = contentChildren(YuwLeftAddonDirective, ...(ngDevMode ? [{ debugName: "_leftAddons" }] : /* istanbul ignore next */ []));
1390
- this._rightAddons = contentChildren(YuwRightAddonDirective, ...(ngDevMode ? [{ debugName: "_rightAddons" }] : /* istanbul ignore next */ []));
1391
- this.inputmode = input(undefined, ...(ngDevMode ? [{ debugName: "inputmode" }] : /* istanbul ignore next */ []));
1392
- this.maxlength = input(undefined, ...(ngDevMode ? [{ debugName: "maxlength" }] : /* istanbul ignore next */ []));
1887
+ super();
1888
+ this._native = viewChild('native', ...(ngDevMode ? [{ debugName: "_native" }] : /* istanbul ignore next */ []));
1889
+ this.accept = input(undefined, ...(ngDevMode ? [{ debugName: "accept" }] : /* istanbul ignore next */ []));
1890
+ this.alt = input('', ...(ngDevMode ? [{ debugName: "alt" }] : /* istanbul ignore next */ []));
1891
+ this.countLabel = input(undefined, ...(ngDevMode ? [{ debugName: "countLabel" }] : /* istanbul ignore next */ []));
1892
+ this.errorText = input(undefined, ...(ngDevMode ? [{ debugName: "errorText" }] : /* istanbul ignore next */ []));
1893
+ this.fallback = input(undefined, ...(ngDevMode ? [{ debugName: "fallback" }] : /* istanbul ignore next */ []));
1894
+ this.helperText = input(undefined, ...(ngDevMode ? [{ debugName: "helperText" }] : /* istanbul ignore next */ []));
1895
+ this.inputId = input(undefined, ...(ngDevMode ? [{ debugName: "inputId" }] : /* istanbul ignore next */ []));
1896
+ this.invalid = input(false, { ...(ngDevMode ? { debugName: "invalid" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
1897
+ this.multiple = input(false, { ...(ngDevMode ? { debugName: "multiple" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
1898
+ this.name = input(undefined, ...(ngDevMode ? [{ debugName: "name" }] : /* istanbul ignore next */ []));
1899
+ this.removeLabel = input(undefined, ...(ngDevMode ? [{ debugName: "removeLabel" }] : /* istanbul ignore next */ []));
1900
+ this.required = input(false, { ...(ngDevMode ? { debugName: "required" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
1393
1901
  this.size = input('default', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
1394
- this.type = input('text', ...(ngDevMode ? [{ debugName: "type" }] : /* istanbul ignore next */ []));
1395
- this.enterPressed = output();
1396
- this._autoId = `yuw-input-${++nextYuwInputId}`;
1397
- this._focusSelectors = ['input'];
1398
- this._classes = computed(() => cn(yuwFieldSizeVariants({ size: this.size() }), this.userClass()), ...(ngDevMode ? [{ debugName: "_classes" }] : /* istanbul ignore next */ []));
1399
- this._hasLeftAddon = computed(() => this._leftAddons().length > 0, ...(ngDevMode ? [{ debugName: "_hasLeftAddon" }] : /* istanbul ignore next */ []));
1400
- this._hasRightAddon = computed(() => this._rightAddons().length > 0, ...(ngDevMode ? [{ debugName: "_hasRightAddon" }] : /* istanbul ignore next */ []));
1401
- this._hasAddons = computed(() => this._hasLeftAddon() || this._hasRightAddon(), ...(ngDevMode ? [{ debugName: "_hasAddons" }] : /* istanbul ignore next */ []));
1402
- }
1403
- onChange() {
1404
- this.committed.emit(this.value());
1902
+ this.src = input(undefined, ...(ngDevMode ? [{ debugName: "src" }] : /* istanbul ignore next */ []));
1903
+ this.uploadLabel = input(undefined, ...(ngDevMode ? [{ debugName: "uploadLabel" }] : /* istanbul ignore next */ []));
1904
+ this.userClass = input('', { ...(ngDevMode ? { debugName: "userClass" } : /* istanbul ignore next */ {}), alias: 'class' });
1905
+ this.value = model([], ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
1906
+ this.variant = input('avatar', ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
1907
+ this.removed = output();
1908
+ this._autoId = `yuw-input-file-${++nextYuwInputFileId}`;
1909
+ this._focusSelectors = ['button', 'input'];
1910
+ this._isMobile = injectIsMobile();
1911
+ this._listOpen = signal(false, ...(ngDevMode ? [{ debugName: "_listOpen" }] : /* istanbul ignore next */ []));
1912
+ this._preview = signal(undefined, ...(ngDevMode ? [{ debugName: "_preview" }] : /* istanbul ignore next */ []));
1913
+ this._avatarSrc = computed(() => this._preview() ?? this.src(), ...(ngDevMode ? [{ debugName: "_avatarSrc" }] : /* istanbul ignore next */ []));
1914
+ this._boxClasses = computed(() => cn(yuwFieldSizeVariants({ size: this.size() }), 'flex min-w-0 items-center justify-between gap-2 rounded-lg border border-input bg-transparent ps-2.5 pe-2 text-sm'), ...(ngDevMode ? [{ debugName: "_boxClasses" }] : /* istanbul ignore next */ []));
1915
+ this._countText = computed(() => this.countLabel()?.(this.value().length), ...(ngDevMode ? [{ debugName: "_countText" }] : /* istanbul ignore next */ []));
1916
+ this._entries = computed(() => this.value().map((file) => ({ file, size: formatFileSize(file.size) })), ...(ngDevMode ? [{ debugName: "_entries" }] : /* istanbul ignore next */ []));
1917
+ this._inlineClasses = computed(() => cn('flex min-w-0 flex-col gap-2', this.userClass()), ...(ngDevMode ? [{ debugName: "_inlineClasses" }] : /* istanbul ignore next */ []));
1918
+ this._inputId = computed(() => this.inputId() ?? this._autoId, ...(ngDevMode ? [{ debugName: "_inputId" }] : /* istanbul ignore next */ []));
1919
+ effect(() => {
1920
+ const native = this._native()?.nativeElement;
1921
+ if (native && this.value().length === 0) {
1922
+ native.value = '';
1923
+ }
1924
+ });
1925
+ effect(() => {
1926
+ if (this.value().length < 2 || this._isMobile()) {
1927
+ this._listOpen.set(false);
1928
+ }
1929
+ });
1930
+ effect((onCleanup) => {
1931
+ const file = this.variant() === 'avatar' ? this.value()[0] : undefined;
1932
+ if (!file) {
1933
+ this._preview.set(undefined);
1934
+ return;
1935
+ }
1936
+ const url = URL.createObjectURL(file);
1937
+ this._preview.set(url);
1938
+ onCleanup(() => URL.revokeObjectURL(url));
1939
+ });
1405
1940
  }
1406
- onEnterPressed() {
1407
- this.enterPressed.emit();
1941
+ _emptyValue() {
1942
+ return [];
1408
1943
  }
1409
- onInput(event) {
1410
- this._commit(event.target.value);
1944
+ onChange(event) {
1945
+ this._commit(Array.from(event.target.files ?? []));
1411
1946
  }
1412
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwInputComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
1413
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: YuwInputComponent, isStandalone: true, selector: "yuw-input", inputs: { inputmode: { classPropertyName: "inputmode", publicName: "inputmode", isSignal: true, isRequired: false, transformFunction: null }, maxlength: { classPropertyName: "maxlength", publicName: "maxlength", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { enterPressed: "enterPressed" }, host: { classAttribute: "contents" }, providers: [provideValueAccessor(YuwInputComponent)], queries: [{ propertyName: "_leftAddons", predicate: YuwLeftAddonDirective, isSignal: true }, { propertyName: "_rightAddons", predicate: YuwRightAddonDirective, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<hlm-field\n yuwFieldFeedback\n #feedback=\"yuwFieldFeedback\"\n class=\"min-w-0 data-[matches-spartan-invalid=true]:text-inherit\"\n [invalid]=\"invalid()\"\n [errorText]=\"errorText()\"\n>\n @if (_hasAddons()) {\n <hlm-input-group [class]=\"_classes()\">\n @if (_hasLeftAddon()) {\n <hlm-input-group-addon align=\"inline-start\">\n <ng-content select=\"yuw-left-addon\" />\n </hlm-input-group-addon>\n }\n\n <input\n hlmInputGroupInput\n [id]=\"_inputId()\"\n [type]=\"type()\"\n [attr.inputmode]=\"inputmode()\"\n [value]=\"value()\"\n [disabled]=\"_disabled()\"\n [readOnly]=\"readonly()\"\n [required]=\"required()\"\n [forceInvalid]=\"feedback.forcedInvalid()\"\n [attr.name]=\"name()\"\n [attr.autocomplete]=\"autocomplete()\"\n [attr.maxlength]=\"maxlength()\"\n [attr.placeholder]=\"placeholder()\"\n (input)=\"onInput($event)\"\n (change)=\"onChange()\"\n (blur)=\"_onBlur()\"\n (keydown.enter)=\"onEnterPressed()\"\n />\n\n @if (_hasRightAddon()) {\n <hlm-input-group-addon align=\"inline-end\">\n <ng-content select=\"yuw-right-addon\" />\n </hlm-input-group-addon>\n }\n </hlm-input-group>\n } @else {\n <input\n hlmInput\n [class]=\"_classes()\"\n [id]=\"_inputId()\"\n [type]=\"type()\"\n [attr.inputmode]=\"inputmode()\"\n [value]=\"value()\"\n [disabled]=\"_disabled()\"\n [readOnly]=\"readonly()\"\n [required]=\"required()\"\n [forceInvalid]=\"feedback.forcedInvalid()\"\n [attr.name]=\"name()\"\n [attr.autocomplete]=\"autocomplete()\"\n [attr.maxlength]=\"maxlength()\"\n [attr.placeholder]=\"placeholder()\"\n (input)=\"onInput($event)\"\n (change)=\"onChange()\"\n (blur)=\"_onBlur()\"\n (keydown.enter)=\"onEnterPressed()\"\n />\n }\n\n @if (feedback.showError()) {\n <hlm-field-description role=\"alert\" class=\"text-destructive\">{{ feedback.errorMessage() }}</hlm-field-description>\n } @else if (helperText(); as helper) {\n <hlm-field-description>{{ helper }}</hlm-field-description>\n }\n</hlm-field>\n", dependencies: [{ kind: "directive", type: HlmField, selector: "[hlmField],hlm-field", inputs: ["orientation"] }, { kind: "directive", type: HlmFieldDescription, selector: "[hlmFieldDescription],hlm-field-description", inputs: ["id"] }, { kind: "directive", type: YuwFieldFeedbackDirective, selector: "hlm-field[yuwFieldFeedback]", inputs: ["errorText", "invalid"], exportAs: ["yuwFieldFeedback"] }, { kind: "directive", type: HlmInput, selector: "[hlmInput]" }, { kind: "directive", type: HlmInputGroup, selector: "[hlmInputGroup],hlm-input-group" }, { kind: "directive", type: HlmInputGroupInput, selector: "input[hlmInputGroupInput]" }, { kind: "directive", type: HlmInputGroupAddon, selector: "[hlmInputGroupAddon],hlm-input-group-addon", inputs: ["align"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1947
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwInputFileComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1948
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: YuwInputFileComponent, isStandalone: true, selector: "yuw-input-file", inputs: { accept: { classPropertyName: "accept", publicName: "accept", isSignal: true, isRequired: false, transformFunction: null }, alt: { classPropertyName: "alt", publicName: "alt", isSignal: true, isRequired: false, transformFunction: null }, countLabel: { classPropertyName: "countLabel", publicName: "countLabel", isSignal: true, isRequired: false, transformFunction: null }, errorText: { classPropertyName: "errorText", publicName: "errorText", isSignal: true, isRequired: false, transformFunction: null }, fallback: { classPropertyName: "fallback", publicName: "fallback", isSignal: true, isRequired: false, transformFunction: null }, helperText: { classPropertyName: "helperText", publicName: "helperText", isSignal: true, isRequired: false, transformFunction: null }, inputId: { classPropertyName: "inputId", publicName: "inputId", isSignal: true, isRequired: false, transformFunction: null }, invalid: { classPropertyName: "invalid", publicName: "invalid", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, removeLabel: { classPropertyName: "removeLabel", publicName: "removeLabel", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, src: { classPropertyName: "src", publicName: "src", isSignal: true, isRequired: false, transformFunction: null }, uploadLabel: { classPropertyName: "uploadLabel", publicName: "uploadLabel", isSignal: true, isRequired: false, transformFunction: null }, userClass: { classPropertyName: "userClass", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", removed: "removed" }, host: { classAttribute: "contents" }, providers: [provideValueAccessor(YuwInputFileComponent), provideIcons({ lucideUpload, lucideX })], viewQueries: [{ propertyName: "_native", first: true, predicate: ["native"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<ng-template #fileRow let-entry>\n <span class=\"min-w-0 flex-1 truncate\">{{ entry.file.name }}</span>\n <span class=\"shrink-0 text-muted-foreground\">{{ entry.size }}</span>\n <yuw-button\n variant=\"ghost\"\n size=\"icon-xs\"\n [ariaLabel]=\"removeLabel()\"\n [disabled]=\"_disabled()\"\n (clicked)=\"removed.emit(entry.file)\"\n >\n <ng-icon name=\"lucideX\" size=\"14\" />\n </yuw-button>\n</ng-template>\n\n<hlm-field\n yuwFieldFeedback\n #feedback=\"yuwFieldFeedback\"\n class=\"min-w-0 data-[matches-spartan-invalid=true]:text-inherit\"\n [invalid]=\"invalid()\"\n [errorText]=\"errorText()\"\n>\n <input\n #native\n hlmInput\n hidden\n type=\"file\"\n [id]=\"_inputId()\"\n [attr.accept]=\"accept()\"\n [multiple]=\"multiple()\"\n [disabled]=\"_disabled()\"\n [required]=\"required()\"\n [forceInvalid]=\"feedback.forcedInvalid()\"\n [attr.name]=\"name()\"\n (change)=\"onChange($event)\"\n />\n\n @if (variant() === 'avatar') {\n <div class=\"flex min-w-0 flex-wrap items-center gap-3\">\n <yuw-avatar size=\"lg\" [class]=\"userClass()\" [src]=\"_avatarSrc()\" [alt]=\"alt()\" [fallback]=\"fallback()\" />\n <yuw-button\n type=\"button\"\n variant=\"outline\"\n [size]=\"size()\"\n [disabled]=\"_disabled()\"\n (clicked)=\"native.click()\"\n (focusout)=\"_onBlur()\"\n >\n {{ uploadLabel() }}\n </yuw-button>\n </div>\n } @else {\n <div [class]=\"_inlineClasses()\">\n @if (_entries().length === 0) {\n <yuw-button\n type=\"button\"\n variant=\"outline\"\n color=\"secondary\"\n class=\"w-full\"\n [size]=\"size()\"\n [disabled]=\"_disabled()\"\n (clicked)=\"native.click()\"\n (focusout)=\"_onBlur()\"\n >\n <ng-icon name=\"lucideUpload\" size=\"16\" />\n {{ uploadLabel() }}\n </yuw-button>\n } @else if (_entries().length === 1) {\n <div [class]=\"_boxClasses()\" [class.border-destructive]=\"feedback.showError()\">\n <ng-container [ngTemplateOutlet]=\"fileRow\" [ngTemplateOutletContext]=\"{ $implicit: _entries()[0] }\" />\n </div>\n } @else {\n @if (_isMobile()) {\n <yuw-button\n type=\"button\"\n variant=\"outline\"\n class=\"w-full justify-start font-normal\"\n [size]=\"size()\"\n [disabled]=\"_disabled()\"\n (clicked)=\"_listOpen.set(true)\"\n >\n {{ _countText() }}\n </yuw-button>\n\n <yuw-sheet\n side=\"bottom\"\n panelClass=\"max-h-[85svh] overflow-y-auto\"\n [showTrigger]=\"false\"\n [title]=\"_countText()\"\n [(open)]=\"_listOpen\"\n >\n <ul class=\"flex flex-col gap-1 pb-3\">\n @for (entry of _entries(); track entry.file) {\n <li class=\"flex items-center gap-2 text-sm\">\n <ng-container [ngTemplateOutlet]=\"fileRow\" [ngTemplateOutletContext]=\"{ $implicit: entry }\" />\n </li>\n }\n </ul>\n </yuw-sheet>\n } @else {\n <div class=\"[&_yuw-button]:flex [&_yuw-button]:w-full\">\n <yuw-popover\n align=\"start\"\n panelClass=\"w-80 p-2\"\n triggerVariant=\"outline\"\n triggerClass=\"w-full justify-start font-normal\"\n [triggerSize]=\"size()\"\n [(open)]=\"_listOpen\"\n >\n <span yuwPopoverTrigger>{{ _countText() }}</span>\n\n <ul class=\"flex flex-col gap-1\">\n @for (entry of _entries(); track entry.file) {\n <li class=\"flex items-center gap-2 text-sm\">\n <ng-container [ngTemplateOutlet]=\"fileRow\" [ngTemplateOutletContext]=\"{ $implicit: entry }\" />\n </li>\n }\n </ul>\n </yuw-popover>\n </div>\n }\n }\n </div>\n }\n\n @if (feedback.showError()) {\n <hlm-field-description role=\"alert\" class=\"text-destructive\">{{ feedback.errorMessage() }}</hlm-field-description>\n } @else if (helperText(); as helper) {\n <hlm-field-description>{{ helper }}</hlm-field-description>\n }\n</hlm-field>\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: HlmField, selector: "[hlmField],hlm-field", inputs: ["orientation"] }, { kind: "directive", type: HlmFieldDescription, selector: "[hlmFieldDescription],hlm-field-description", inputs: ["id"] }, { kind: "directive", type: YuwFieldFeedbackDirective, selector: "hlm-field[yuwFieldFeedback]", inputs: ["errorText", "invalid"], exportAs: ["yuwFieldFeedback"] }, { kind: "directive", type: HlmInput, selector: "[hlmInput]" }, { kind: "component", type: YuwAvatarComponent, selector: "yuw-avatar", inputs: ["alt", "badge", "fallback", "group", "groupCount", "size", "src", "class"] }, { 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: YuwPopoverComponent, selector: "yuw-popover", inputs: ["align", "description", "offsetX", "open", "panelClass", "showTrigger", "sideOffset", "title", "triggerClass", "triggerColor", "triggerSize", "triggerTransparent", "triggerVariant"], outputs: ["openChange"] }, { kind: "component", type: YuwSheetComponent, selector: "yuw-sheet", inputs: ["ariaLabel", "ariaModal", "closeLabel", "closeOnOutsidePointerEvents", "description", "open", "overlayClass", "panelClass", "scrollStrategy", "showTrigger", "side", "title", "triggerSize", "triggerVariant"], outputs: ["openChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1414
1949
  }
1415
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwInputComponent, decorators: [{
1950
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwInputFileComponent, decorators: [{
1416
1951
  type: Component,
1417
- args: [{ selector: 'yuw-input', imports: [
1952
+ args: [{ selector: 'yuw-input-file', imports: [
1953
+ NgTemplateOutlet,
1954
+ NgIcon,
1418
1955
  HlmField,
1419
1956
  HlmFieldDescription,
1420
1957
  YuwFieldFeedbackDirective,
1421
1958
  HlmInput,
1422
- HlmInputGroup,
1423
- HlmInputGroupInput,
1424
- HlmInputGroupAddon,
1425
- ], providers: [provideValueAccessor(YuwInputComponent)], host: {
1959
+ YuwAvatarComponent,
1960
+ YuwButtonComponent,
1961
+ YuwPopoverComponent,
1962
+ YuwSheetComponent,
1963
+ ], providers: [provideValueAccessor(YuwInputFileComponent), provideIcons({ lucideUpload, lucideX })], host: {
1426
1964
  class: 'contents',
1427
- }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<hlm-field\n yuwFieldFeedback\n #feedback=\"yuwFieldFeedback\"\n class=\"min-w-0 data-[matches-spartan-invalid=true]:text-inherit\"\n [invalid]=\"invalid()\"\n [errorText]=\"errorText()\"\n>\n @if (_hasAddons()) {\n <hlm-input-group [class]=\"_classes()\">\n @if (_hasLeftAddon()) {\n <hlm-input-group-addon align=\"inline-start\">\n <ng-content select=\"yuw-left-addon\" />\n </hlm-input-group-addon>\n }\n\n <input\n hlmInputGroupInput\n [id]=\"_inputId()\"\n [type]=\"type()\"\n [attr.inputmode]=\"inputmode()\"\n [value]=\"value()\"\n [disabled]=\"_disabled()\"\n [readOnly]=\"readonly()\"\n [required]=\"required()\"\n [forceInvalid]=\"feedback.forcedInvalid()\"\n [attr.name]=\"name()\"\n [attr.autocomplete]=\"autocomplete()\"\n [attr.maxlength]=\"maxlength()\"\n [attr.placeholder]=\"placeholder()\"\n (input)=\"onInput($event)\"\n (change)=\"onChange()\"\n (blur)=\"_onBlur()\"\n (keydown.enter)=\"onEnterPressed()\"\n />\n\n @if (_hasRightAddon()) {\n <hlm-input-group-addon align=\"inline-end\">\n <ng-content select=\"yuw-right-addon\" />\n </hlm-input-group-addon>\n }\n </hlm-input-group>\n } @else {\n <input\n hlmInput\n [class]=\"_classes()\"\n [id]=\"_inputId()\"\n [type]=\"type()\"\n [attr.inputmode]=\"inputmode()\"\n [value]=\"value()\"\n [disabled]=\"_disabled()\"\n [readOnly]=\"readonly()\"\n [required]=\"required()\"\n [forceInvalid]=\"feedback.forcedInvalid()\"\n [attr.name]=\"name()\"\n [attr.autocomplete]=\"autocomplete()\"\n [attr.maxlength]=\"maxlength()\"\n [attr.placeholder]=\"placeholder()\"\n (input)=\"onInput($event)\"\n (change)=\"onChange()\"\n (blur)=\"_onBlur()\"\n (keydown.enter)=\"onEnterPressed()\"\n />\n }\n\n @if (feedback.showError()) {\n <hlm-field-description role=\"alert\" class=\"text-destructive\">{{ feedback.errorMessage() }}</hlm-field-description>\n } @else if (helperText(); as helper) {\n <hlm-field-description>{{ helper }}</hlm-field-description>\n }\n</hlm-field>\n" }]
1428
- }], propDecorators: { _leftAddons: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => YuwLeftAddonDirective), { isSignal: true }] }], _rightAddons: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => YuwRightAddonDirective), { isSignal: true }] }], inputmode: [{ type: i0.Input, args: [{ isSignal: true, alias: "inputmode", required: false }] }], maxlength: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxlength", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], enterPressed: [{ type: i0.Output, args: ["enterPressed"] }] } });
1965
+ }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-template #fileRow let-entry>\n <span class=\"min-w-0 flex-1 truncate\">{{ entry.file.name }}</span>\n <span class=\"shrink-0 text-muted-foreground\">{{ entry.size }}</span>\n <yuw-button\n variant=\"ghost\"\n size=\"icon-xs\"\n [ariaLabel]=\"removeLabel()\"\n [disabled]=\"_disabled()\"\n (clicked)=\"removed.emit(entry.file)\"\n >\n <ng-icon name=\"lucideX\" size=\"14\" />\n </yuw-button>\n</ng-template>\n\n<hlm-field\n yuwFieldFeedback\n #feedback=\"yuwFieldFeedback\"\n class=\"min-w-0 data-[matches-spartan-invalid=true]:text-inherit\"\n [invalid]=\"invalid()\"\n [errorText]=\"errorText()\"\n>\n <input\n #native\n hlmInput\n hidden\n type=\"file\"\n [id]=\"_inputId()\"\n [attr.accept]=\"accept()\"\n [multiple]=\"multiple()\"\n [disabled]=\"_disabled()\"\n [required]=\"required()\"\n [forceInvalid]=\"feedback.forcedInvalid()\"\n [attr.name]=\"name()\"\n (change)=\"onChange($event)\"\n />\n\n @if (variant() === 'avatar') {\n <div class=\"flex min-w-0 flex-wrap items-center gap-3\">\n <yuw-avatar size=\"lg\" [class]=\"userClass()\" [src]=\"_avatarSrc()\" [alt]=\"alt()\" [fallback]=\"fallback()\" />\n <yuw-button\n type=\"button\"\n variant=\"outline\"\n [size]=\"size()\"\n [disabled]=\"_disabled()\"\n (clicked)=\"native.click()\"\n (focusout)=\"_onBlur()\"\n >\n {{ uploadLabel() }}\n </yuw-button>\n </div>\n } @else {\n <div [class]=\"_inlineClasses()\">\n @if (_entries().length === 0) {\n <yuw-button\n type=\"button\"\n variant=\"outline\"\n color=\"secondary\"\n class=\"w-full\"\n [size]=\"size()\"\n [disabled]=\"_disabled()\"\n (clicked)=\"native.click()\"\n (focusout)=\"_onBlur()\"\n >\n <ng-icon name=\"lucideUpload\" size=\"16\" />\n {{ uploadLabel() }}\n </yuw-button>\n } @else if (_entries().length === 1) {\n <div [class]=\"_boxClasses()\" [class.border-destructive]=\"feedback.showError()\">\n <ng-container [ngTemplateOutlet]=\"fileRow\" [ngTemplateOutletContext]=\"{ $implicit: _entries()[0] }\" />\n </div>\n } @else {\n @if (_isMobile()) {\n <yuw-button\n type=\"button\"\n variant=\"outline\"\n class=\"w-full justify-start font-normal\"\n [size]=\"size()\"\n [disabled]=\"_disabled()\"\n (clicked)=\"_listOpen.set(true)\"\n >\n {{ _countText() }}\n </yuw-button>\n\n <yuw-sheet\n side=\"bottom\"\n panelClass=\"max-h-[85svh] overflow-y-auto\"\n [showTrigger]=\"false\"\n [title]=\"_countText()\"\n [(open)]=\"_listOpen\"\n >\n <ul class=\"flex flex-col gap-1 pb-3\">\n @for (entry of _entries(); track entry.file) {\n <li class=\"flex items-center gap-2 text-sm\">\n <ng-container [ngTemplateOutlet]=\"fileRow\" [ngTemplateOutletContext]=\"{ $implicit: entry }\" />\n </li>\n }\n </ul>\n </yuw-sheet>\n } @else {\n <div class=\"[&_yuw-button]:flex [&_yuw-button]:w-full\">\n <yuw-popover\n align=\"start\"\n panelClass=\"w-80 p-2\"\n triggerVariant=\"outline\"\n triggerClass=\"w-full justify-start font-normal\"\n [triggerSize]=\"size()\"\n [(open)]=\"_listOpen\"\n >\n <span yuwPopoverTrigger>{{ _countText() }}</span>\n\n <ul class=\"flex flex-col gap-1\">\n @for (entry of _entries(); track entry.file) {\n <li class=\"flex items-center gap-2 text-sm\">\n <ng-container [ngTemplateOutlet]=\"fileRow\" [ngTemplateOutletContext]=\"{ $implicit: entry }\" />\n </li>\n }\n </ul>\n </yuw-popover>\n </div>\n }\n }\n </div>\n }\n\n @if (feedback.showError()) {\n <hlm-field-description role=\"alert\" class=\"text-destructive\">{{ feedback.errorMessage() }}</hlm-field-description>\n } @else if (helperText(); as helper) {\n <hlm-field-description>{{ helper }}</hlm-field-description>\n }\n</hlm-field>\n" }]
1966
+ }], ctorParameters: () => [], propDecorators: { _native: [{ type: i0.ViewChild, args: ['native', { isSignal: true }] }], accept: [{ type: i0.Input, args: [{ isSignal: true, alias: "accept", required: false }] }], alt: [{ type: i0.Input, args: [{ isSignal: true, alias: "alt", required: false }] }], countLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "countLabel", required: false }] }], errorText: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorText", required: false }] }], fallback: [{ type: i0.Input, args: [{ isSignal: true, alias: "fallback", required: false }] }], helperText: [{ type: i0.Input, args: [{ isSignal: true, alias: "helperText", required: false }] }], inputId: [{ type: i0.Input, args: [{ isSignal: true, alias: "inputId", required: false }] }], invalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalid", required: false }] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], removeLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "removeLabel", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], src: [{ type: i0.Input, args: [{ isSignal: true, alias: "src", required: false }] }], uploadLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "uploadLabel", required: false }] }], userClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], removed: [{ type: i0.Output, args: ["removed"] }] } });
1429
1967
 
1430
1968
  let nextYuwTextareaId = 0;
1431
1969
  /**
@@ -1809,7 +2347,7 @@ class YuwSearchInputComponent extends YuwTextFieldBase {
1809
2347
  this.searched.emit(next);
1810
2348
  }
1811
2349
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwSearchInputComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
1812
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: YuwSearchInputComponent, isStandalone: true, selector: "yuw-search-input", inputs: { clearAriaLabel: { classPropertyName: "clearAriaLabel", publicName: "clearAriaLabel", isSignal: true, isRequired: false, transformFunction: null }, collapseFrom: { classPropertyName: "collapseFrom", publicName: "collapseFrom", isSignal: true, isRequired: false, transformFunction: null }, expandAriaLabel: { classPropertyName: "expandAriaLabel", publicName: "expandAriaLabel", isSignal: true, isRequired: false, transformFunction: null }, expandedWidth: { classPropertyName: "expandedWidth", publicName: "expandedWidth", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, transparent: { classPropertyName: "transparent", publicName: "transparent", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { searched: "searched" }, host: { classAttribute: "contents" }, providers: [provideValueAccessor(YuwSearchInputComponent), provideIcons({ lucideSearch, lucideX })], viewQueries: [{ propertyName: "_input", first: true, predicate: ["searchInput"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<hlm-field\n yuwFieldFeedback\n #feedback=\"yuwFieldFeedback\"\n class=\"min-w-0 data-[matches-spartan-invalid=true]:text-inherit\"\n [invalid]=\"invalid()\"\n [errorText]=\"errorText()\"\n>\n <div [class]=\"_wrapperClasses()\" [style.max-width]=\"_wrapperMaxWidth()\">\n <hlm-input-group [class]=\"_classes()\">\n <hlm-input-group-addon align=\"inline-start\" [class]=\"_iconClasses()\">\n @if (_showExpandButton()) {\n <button\n hlmInputGroupButton\n size=\"icon-sm\"\n [class]=\"_expandButtonClasses()\"\n [attr.aria-label]=\"expandAriaLabel()\"\n [attr.aria-expanded]=\"false\"\n (focus)=\"onExpandFocus($event)\"\n (click)=\"onExpand()\"\n >\n <ng-icon name=\"lucideSearch\" />\n </button>\n } @else {\n <ng-icon name=\"lucideSearch\" />\n }\n </hlm-input-group-addon>\n\n <input\n #searchInput\n hlmInputGroupInput\n [class]=\"_fieldClasses()\"\n [id]=\"_inputId()\"\n type=\"text\"\n inputmode=\"search\"\n [value]=\"value()\"\n [disabled]=\"_disabled()\"\n [readOnly]=\"readonly()\"\n [required]=\"required()\"\n [forceInvalid]=\"feedback.forcedInvalid()\"\n [attr.name]=\"name()\"\n [attr.autocomplete]=\"autocomplete()\"\n [attr.placeholder]=\"placeholder()\"\n [attr.tabindex]=\"expanded() ? null : -1\"\n [attr.aria-hidden]=\"expanded() ? null : true\"\n (input)=\"onInput($event)\"\n (keydown.enter)=\"onEnter()\"\n (keydown.escape)=\"onEscape()\"\n (blur)=\"onBlur()\"\n />\n\n @if (_showClear()) {\n <hlm-input-group-addon align=\"inline-end\">\n <button hlmInputGroupButton size=\"icon-xs\" [attr.aria-label]=\"clearAriaLabel()\" (click)=\"onClear()\">\n <ng-icon name=\"lucideX\" />\n </button>\n </hlm-input-group-addon>\n }\n </hlm-input-group>\n </div>\n\n @if (feedback.showError()) {\n <hlm-field-description role=\"alert\" class=\"text-destructive\">{{ feedback.errorMessage() }}</hlm-field-description>\n } @else if (helperText(); as helper) {\n <hlm-field-description>{{ helper }}</hlm-field-description>\n }\n</hlm-field>\n", dependencies: [{ kind: "directive", type: HlmField, selector: "[hlmField],hlm-field", inputs: ["orientation"] }, { kind: "directive", type: HlmFieldDescription, selector: "[hlmFieldDescription],hlm-field-description", inputs: ["id"] }, { kind: "directive", type: YuwFieldFeedbackDirective, selector: "hlm-field[yuwFieldFeedback]", inputs: ["errorText", "invalid"], exportAs: ["yuwFieldFeedback"] }, { kind: "directive", type: i1$4.HlmInputGroup, selector: "[hlmInputGroup],hlm-input-group" }, { kind: "directive", type: i1$4.HlmInputGroupAddon, selector: "[hlmInputGroupAddon],hlm-input-group-addon", inputs: ["align"] }, { kind: "directive", type: i1$4.HlmInputGroupButton, selector: "button[hlmInputGroupButton]", inputs: ["size", "type"] }, { kind: "directive", type: i1$4.HlmInputGroupInput, selector: "input[hlmInputGroupInput]" }, { kind: "component", type: NgIcon, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2350
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: YuwSearchInputComponent, isStandalone: true, selector: "yuw-search-input", inputs: { clearAriaLabel: { classPropertyName: "clearAriaLabel", publicName: "clearAriaLabel", isSignal: true, isRequired: false, transformFunction: null }, collapseFrom: { classPropertyName: "collapseFrom", publicName: "collapseFrom", isSignal: true, isRequired: false, transformFunction: null }, expandAriaLabel: { classPropertyName: "expandAriaLabel", publicName: "expandAriaLabel", isSignal: true, isRequired: false, transformFunction: null }, expandedWidth: { classPropertyName: "expandedWidth", publicName: "expandedWidth", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, transparent: { classPropertyName: "transparent", publicName: "transparent", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { searched: "searched" }, host: { classAttribute: "contents" }, providers: [provideValueAccessor(YuwSearchInputComponent), provideIcons({ lucideSearch, lucideX })], viewQueries: [{ propertyName: "_input", first: true, predicate: ["searchInput"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<hlm-field\n yuwFieldFeedback\n #feedback=\"yuwFieldFeedback\"\n class=\"min-w-0 data-[matches-spartan-invalid=true]:text-inherit\"\n [invalid]=\"invalid()\"\n [errorText]=\"errorText()\"\n>\n <div [class]=\"_wrapperClasses()\" [style.max-width]=\"_wrapperMaxWidth()\">\n <hlm-input-group [class]=\"_classes()\">\n <hlm-input-group-addon align=\"inline-start\" [class]=\"_iconClasses()\">\n @if (_showExpandButton()) {\n <button\n hlmInputGroupButton\n size=\"icon-sm\"\n [class]=\"_expandButtonClasses()\"\n [attr.aria-label]=\"expandAriaLabel()\"\n [attr.aria-expanded]=\"false\"\n (focus)=\"onExpandFocus($event)\"\n (click)=\"onExpand()\"\n >\n <ng-icon name=\"lucideSearch\" />\n </button>\n } @else {\n <ng-icon name=\"lucideSearch\" />\n }\n </hlm-input-group-addon>\n\n <input\n #searchInput\n hlmInputGroupInput\n [class]=\"_fieldClasses()\"\n [id]=\"_inputId()\"\n type=\"text\"\n inputmode=\"search\"\n [value]=\"value()\"\n [disabled]=\"_disabled()\"\n [readOnly]=\"readonly()\"\n [required]=\"required()\"\n [forceInvalid]=\"feedback.forcedInvalid()\"\n [attr.name]=\"name()\"\n [attr.autocomplete]=\"autocomplete()\"\n [attr.placeholder]=\"placeholder()\"\n [attr.tabindex]=\"expanded() ? null : -1\"\n [attr.aria-hidden]=\"expanded() ? null : true\"\n (input)=\"onInput($event)\"\n (keydown.enter)=\"onEnter()\"\n (keydown.escape)=\"onEscape()\"\n (blur)=\"onBlur()\"\n />\n\n @if (_showClear()) {\n <hlm-input-group-addon align=\"inline-end\">\n <button hlmInputGroupButton size=\"icon-xs\" [attr.aria-label]=\"clearAriaLabel()\" (click)=\"onClear()\">\n <ng-icon name=\"lucideX\" />\n </button>\n </hlm-input-group-addon>\n }\n </hlm-input-group>\n </div>\n\n @if (feedback.showError()) {\n <hlm-field-description role=\"alert\" class=\"text-destructive\">{{ feedback.errorMessage() }}</hlm-field-description>\n } @else if (helperText(); as helper) {\n <hlm-field-description>{{ helper }}</hlm-field-description>\n }\n</hlm-field>\n", dependencies: [{ kind: "directive", type: HlmField, selector: "[hlmField],hlm-field", inputs: ["orientation"] }, { kind: "directive", type: HlmFieldDescription, selector: "[hlmFieldDescription],hlm-field-description", inputs: ["id"] }, { kind: "directive", type: YuwFieldFeedbackDirective, selector: "hlm-field[yuwFieldFeedback]", inputs: ["errorText", "invalid"], exportAs: ["yuwFieldFeedback"] }, { kind: "directive", type: i1$9.HlmInputGroup, selector: "[hlmInputGroup],hlm-input-group" }, { kind: "directive", type: i1$9.HlmInputGroupAddon, selector: "[hlmInputGroupAddon],hlm-input-group-addon", inputs: ["align"] }, { kind: "directive", type: i1$9.HlmInputGroupButton, selector: "button[hlmInputGroupButton]", inputs: ["size", "type"] }, { kind: "directive", type: i1$9.HlmInputGroupInput, selector: "input[hlmInputGroupInput]" }, { kind: "component", type: NgIcon, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1813
2351
  }
1814
2352
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwSearchInputComponent, decorators: [{
1815
2353
  type: Component,
@@ -1852,6 +2390,7 @@ let nextYuwPasswordInputId = 0;
1852
2390
  *
1853
2391
  * Outputs:
1854
2392
  * - `committed`: Emits the current value on the native `change` event (blur/enter).
2393
+ * - `enterPressed`: Emits (`void`) when the Enter key is pressed while the field is focused.
1855
2394
  *
1856
2395
  * Usage:
1857
2396
  * ```html
@@ -1886,7 +2425,7 @@ class YuwPasswordInputComponent extends YuwTextFieldBase {
1886
2425
  this.masked.update((masked) => !masked);
1887
2426
  }
1888
2427
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwPasswordInputComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
1889
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: YuwPasswordInputComponent, isStandalone: true, selector: "yuw-password-input", inputs: { masked: { classPropertyName: "masked", publicName: "masked", isSignal: true, isRequired: false, transformFunction: null }, revealAriaLabel: { classPropertyName: "revealAriaLabel", publicName: "revealAriaLabel", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { masked: "maskedChange", enterPressed: "enterPressed" }, host: { classAttribute: "contents" }, providers: [provideValueAccessor(YuwPasswordInputComponent), provideIcons({ lucideEye, lucideEyeOff })], queries: [{ propertyName: "_leftAddons", predicate: YuwLeftAddonDirective, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<hlm-field\n yuwFieldFeedback\n #feedback=\"yuwFieldFeedback\"\n class=\"min-w-0 data-[matches-spartan-invalid=true]:text-inherit\"\n [invalid]=\"invalid()\"\n [errorText]=\"errorText()\"\n>\n <hlm-input-group [class]=\"_classes()\">\n @if (_hasLeftAddon()) {\n <hlm-input-group-addon align=\"inline-start\">\n <ng-content select=\"yuw-left-addon\" />\n </hlm-input-group-addon>\n }\n\n <input\n hlmInputGroupInput\n [id]=\"_inputId()\"\n [type]=\"_reveal().inputType\"\n [value]=\"value()\"\n [disabled]=\"_disabled()\"\n [readOnly]=\"readonly()\"\n [required]=\"required()\"\n [forceInvalid]=\"feedback.forcedInvalid()\"\n [attr.name]=\"name()\"\n [attr.autocomplete]=\"autocomplete()\"\n [attr.placeholder]=\"placeholder()\"\n (input)=\"onInput($event)\"\n (change)=\"onChange()\"\n (blur)=\"_onBlur()\"\n (keydown.enter)=\"onEnterPressed()\"\n />\n\n @if (revealAriaLabel(); as label) {\n <hlm-input-group-addon align=\"inline-end\">\n <button\n hlmInputGroupButton\n size=\"icon-xs\"\n [disabled]=\"_disabled()\"\n [attr.aria-label]=\"label\"\n [attr.aria-pressed]=\"!_reveal().struck\"\n (click)=\"onToggleReveal()\"\n >\n <ng-icon [name]=\"_reveal().icon\" />\n </button>\n </hlm-input-group-addon>\n }\n </hlm-input-group>\n\n @if (feedback.showError()) {\n <hlm-field-description role=\"alert\" class=\"text-destructive\">{{ feedback.errorMessage() }}</hlm-field-description>\n } @else if (helperText(); as helper) {\n <hlm-field-description>{{ helper }}</hlm-field-description>\n }\n</hlm-field>\n", dependencies: [{ kind: "directive", type: HlmField, selector: "[hlmField],hlm-field", inputs: ["orientation"] }, { kind: "directive", type: HlmFieldDescription, selector: "[hlmFieldDescription],hlm-field-description", inputs: ["id"] }, { kind: "directive", type: YuwFieldFeedbackDirective, selector: "hlm-field[yuwFieldFeedback]", inputs: ["errorText", "invalid"], exportAs: ["yuwFieldFeedback"] }, { kind: "directive", type: i1$4.HlmInputGroup, selector: "[hlmInputGroup],hlm-input-group" }, { kind: "directive", type: i1$4.HlmInputGroupAddon, selector: "[hlmInputGroupAddon],hlm-input-group-addon", inputs: ["align"] }, { kind: "directive", type: i1$4.HlmInputGroupButton, selector: "button[hlmInputGroupButton]", inputs: ["size", "type"] }, { kind: "directive", type: i1$4.HlmInputGroupInput, selector: "input[hlmInputGroupInput]" }, { kind: "component", type: NgIcon, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2428
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: YuwPasswordInputComponent, isStandalone: true, selector: "yuw-password-input", inputs: { masked: { classPropertyName: "masked", publicName: "masked", isSignal: true, isRequired: false, transformFunction: null }, revealAriaLabel: { classPropertyName: "revealAriaLabel", publicName: "revealAriaLabel", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { masked: "maskedChange", enterPressed: "enterPressed" }, host: { classAttribute: "contents" }, providers: [provideValueAccessor(YuwPasswordInputComponent), provideIcons({ lucideEye, lucideEyeOff })], queries: [{ propertyName: "_leftAddons", predicate: YuwLeftAddonDirective, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<hlm-field\n yuwFieldFeedback\n #feedback=\"yuwFieldFeedback\"\n class=\"min-w-0 data-[matches-spartan-invalid=true]:text-inherit\"\n [invalid]=\"invalid()\"\n [errorText]=\"errorText()\"\n>\n <hlm-input-group [class]=\"_classes()\">\n @if (_hasLeftAddon()) {\n <hlm-input-group-addon align=\"inline-start\">\n <ng-content select=\"yuw-left-addon\" />\n </hlm-input-group-addon>\n }\n\n <input\n hlmInputGroupInput\n [id]=\"_inputId()\"\n [type]=\"_reveal().inputType\"\n [value]=\"value()\"\n [disabled]=\"_disabled()\"\n [readOnly]=\"readonly()\"\n [required]=\"required()\"\n [forceInvalid]=\"feedback.forcedInvalid()\"\n [attr.name]=\"name()\"\n [attr.autocomplete]=\"autocomplete()\"\n [attr.placeholder]=\"placeholder()\"\n (input)=\"onInput($event)\"\n (change)=\"onChange()\"\n (blur)=\"_onBlur()\"\n (keydown.enter)=\"onEnterPressed()\"\n />\n\n @if (revealAriaLabel(); as label) {\n <hlm-input-group-addon align=\"inline-end\">\n <button\n hlmInputGroupButton\n size=\"icon-xs\"\n [disabled]=\"_disabled()\"\n [attr.aria-label]=\"label\"\n [attr.aria-pressed]=\"!_reveal().struck\"\n (click)=\"onToggleReveal()\"\n >\n <ng-icon [name]=\"_reveal().icon\" />\n </button>\n </hlm-input-group-addon>\n }\n </hlm-input-group>\n\n @if (feedback.showError()) {\n <hlm-field-description role=\"alert\" class=\"text-destructive\">{{ feedback.errorMessage() }}</hlm-field-description>\n } @else if (helperText(); as helper) {\n <hlm-field-description>{{ helper }}</hlm-field-description>\n }\n</hlm-field>\n", dependencies: [{ kind: "directive", type: HlmField, selector: "[hlmField],hlm-field", inputs: ["orientation"] }, { kind: "directive", type: HlmFieldDescription, selector: "[hlmFieldDescription],hlm-field-description", inputs: ["id"] }, { kind: "directive", type: YuwFieldFeedbackDirective, selector: "hlm-field[yuwFieldFeedback]", inputs: ["errorText", "invalid"], exportAs: ["yuwFieldFeedback"] }, { kind: "directive", type: i1$9.HlmInputGroup, selector: "[hlmInputGroup],hlm-input-group" }, { kind: "directive", type: i1$9.HlmInputGroupAddon, selector: "[hlmInputGroupAddon],hlm-input-group-addon", inputs: ["align"] }, { kind: "directive", type: i1$9.HlmInputGroupButton, selector: "button[hlmInputGroupButton]", inputs: ["size", "type"] }, { kind: "directive", type: i1$9.HlmInputGroupInput, selector: "input[hlmInputGroupInput]" }, { kind: "component", type: NgIcon, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1890
2429
  }
1891
2430
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwPasswordInputComponent, decorators: [{
1892
2431
  type: Component,
@@ -1972,6 +2511,7 @@ let nextYuwInputOtpId = 0;
1972
2511
  *
1973
2512
  * Outputs:
1974
2513
  * - `completed`: Emits the full code string once the final slot is filled (by typing or paste).
2514
+ * - `enterPressed`: Emits (`void`) when the Enter key is pressed while the field is focused.
1975
2515
  *
1976
2516
  * Usage:
1977
2517
  * ```html
@@ -2002,7 +2542,7 @@ class YuwInputOtpComponent extends YuwFieldBase {
2002
2542
  this._commit(next);
2003
2543
  }
2004
2544
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwInputOtpComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
2005
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: YuwInputOtpComponent, isStandalone: true, selector: "yuw-input-otp", inputs: { autofocus: { classPropertyName: "autofocus", publicName: "autofocus", isSignal: true, isRequired: false, transformFunction: null }, groupSizes: { classPropertyName: "groupSizes", publicName: "groupSizes", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, transformPaste: { classPropertyName: "transformPaste", publicName: "transformPaste", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { completed: "completed", enterPressed: "enterPressed" }, host: { classAttribute: "contents" }, providers: [provideValueAccessor(YuwInputOtpComponent)], usesInheritance: true, ngImport: i0, template: "<hlm-field\n yuwFieldFeedback\n #feedback=\"yuwFieldFeedback\"\n class=\"w-fit min-w-0 data-[matches-spartan-invalid=true]:text-inherit\"\n [invalid]=\"invalid()\"\n [errorText]=\"errorText()\"\n>\n <brn-input-otp\n hlmInputOtp\n [class]=\"_classes()\"\n [inputId]=\"_inputId()\"\n [length]=\"_length()\"\n [value]=\"value()\"\n [inputMode]=\"mode()\"\n [disabled]=\"_disabled()\"\n [autofocus]=\"autofocus()\"\n [transformPaste]=\"transformPaste()\"\n inputAutocomplete=\"one-time-code\"\n (valueChange)=\"onValueChange($event)\"\n (focusout)=\"_onBlur()\"\n (completed)=\"completed.emit($event)\"\n (keydown.enter)=\"onEnterPressed()\"\n >\n @for (group of _groups(); track $index) {\n @if (group.precededBySeparator) {\n <hlm-input-otp-separator />\n }\n\n <hlm-input-otp-group>\n @for (index of group.indices; track index) {\n <hlm-input-otp-slot [index]=\"index\" [forceInvalid]=\"feedback.forcedInvalid()\" />\n }\n </hlm-input-otp-group>\n }\n </brn-input-otp>\n\n @if (feedback.showError()) {\n <hlm-field-description role=\"alert\" class=\"text-destructive\">{{ feedback.errorMessage() }}</hlm-field-description>\n } @else if (helperText(); as helper) {\n <hlm-field-description>{{ helper }}</hlm-field-description>\n }\n</hlm-field>\n", dependencies: [{ kind: "directive", type: HlmField, selector: "[hlmField],hlm-field", inputs: ["orientation"] }, { kind: "directive", type: HlmFieldDescription, selector: "[hlmFieldDescription],hlm-field-description", inputs: ["id"] }, { kind: "directive", type: YuwFieldFeedbackDirective, selector: "hlm-field[yuwFieldFeedback]", inputs: ["errorText", "invalid"], exportAs: ["yuwFieldFeedback"] }, { kind: "component", type: BrnInputOtp, selector: "brn-input-otp", inputs: ["hostStyles", "inputId", "inputAutocomplete", "inputStyles", "containerStyles", "disabled", "length", "inputMode", "inputClass", "autofocus", "transformPaste", "value"], outputs: ["valueChange", "completed"] }, { kind: "directive", type: i1$5.HlmInputOtp, selector: "brn-input-otp[hlmInputOtp], brn-input-otp[hlm]" }, { kind: "directive", type: i1$5.HlmInputOtpGroup, selector: "[hlmInputOtpGroup],hlm-input-otp-group" }, { kind: "component", type: i1$5.HlmInputOtpSeparator, selector: "hlm-input-otp-separator" }, { kind: "component", type: i1$5.HlmInputOtpSlot, selector: "hlm-input-otp-slot", inputs: ["index", "forceInvalid"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2545
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: YuwInputOtpComponent, isStandalone: true, selector: "yuw-input-otp", inputs: { autofocus: { classPropertyName: "autofocus", publicName: "autofocus", isSignal: true, isRequired: false, transformFunction: null }, groupSizes: { classPropertyName: "groupSizes", publicName: "groupSizes", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, transformPaste: { classPropertyName: "transformPaste", publicName: "transformPaste", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { completed: "completed", enterPressed: "enterPressed" }, host: { classAttribute: "contents" }, providers: [provideValueAccessor(YuwInputOtpComponent)], usesInheritance: true, ngImport: i0, template: "<hlm-field\n yuwFieldFeedback\n #feedback=\"yuwFieldFeedback\"\n class=\"w-fit min-w-0 data-[matches-spartan-invalid=true]:text-inherit\"\n [invalid]=\"invalid()\"\n [errorText]=\"errorText()\"\n>\n <brn-input-otp\n hlmInputOtp\n [class]=\"_classes()\"\n [inputId]=\"_inputId()\"\n [length]=\"_length()\"\n [value]=\"value()\"\n [inputMode]=\"mode()\"\n [disabled]=\"_disabled()\"\n [autofocus]=\"autofocus()\"\n [transformPaste]=\"transformPaste()\"\n inputAutocomplete=\"one-time-code\"\n (valueChange)=\"onValueChange($event)\"\n (focusout)=\"_onBlur()\"\n (completed)=\"completed.emit($event)\"\n (keydown.enter)=\"onEnterPressed()\"\n >\n @for (group of _groups(); track $index) {\n @if (group.precededBySeparator) {\n <hlm-input-otp-separator />\n }\n\n <hlm-input-otp-group>\n @for (index of group.indices; track index) {\n <hlm-input-otp-slot [index]=\"index\" [forceInvalid]=\"feedback.forcedInvalid()\" />\n }\n </hlm-input-otp-group>\n }\n </brn-input-otp>\n\n @if (feedback.showError()) {\n <hlm-field-description role=\"alert\" class=\"text-destructive\">{{ feedback.errorMessage() }}</hlm-field-description>\n } @else if (helperText(); as helper) {\n <hlm-field-description>{{ helper }}</hlm-field-description>\n }\n</hlm-field>\n", dependencies: [{ kind: "directive", type: HlmField, selector: "[hlmField],hlm-field", inputs: ["orientation"] }, { kind: "directive", type: HlmFieldDescription, selector: "[hlmFieldDescription],hlm-field-description", inputs: ["id"] }, { kind: "directive", type: YuwFieldFeedbackDirective, selector: "hlm-field[yuwFieldFeedback]", inputs: ["errorText", "invalid"], exportAs: ["yuwFieldFeedback"] }, { kind: "component", type: BrnInputOtp, selector: "brn-input-otp", inputs: ["hostStyles", "inputId", "inputAutocomplete", "inputStyles", "containerStyles", "disabled", "length", "inputMode", "inputClass", "autofocus", "transformPaste", "value"], outputs: ["valueChange", "completed"] }, { kind: "directive", type: i1$a.HlmInputOtp, selector: "brn-input-otp[hlmInputOtp], brn-input-otp[hlm]" }, { kind: "directive", type: i1$a.HlmInputOtpGroup, selector: "[hlmInputOtpGroup],hlm-input-otp-group" }, { kind: "component", type: i1$a.HlmInputOtpSeparator, selector: "hlm-input-otp-separator" }, { kind: "component", type: i1$a.HlmInputOtpSlot, selector: "hlm-input-otp-slot", inputs: ["index", "forceInvalid"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2006
2546
  }
2007
2547
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwInputOtpComponent, decorators: [{
2008
2548
  type: Component,
@@ -2043,6 +2583,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
2043
2583
  /**
2044
2584
  * Class map for `yuw-checkbox`, layered on top of `HlmCheckbox`'s own classes.
2045
2585
  *
2586
+ * `cursor-pointer` is unconditional too: `HlmCheckbox` ships `cursor-default`, a utility that beats
2587
+ * the global base-layer pointer rule; its `disabled:cursor-not-allowed` still wins when disabled.
2588
+ *
2046
2589
  * The base indeterminate treatment is unconditional — it's how *every* `yuw-checkbox` renders
2047
2590
  * that state, not a variant — so it lives in the cva base, while `primary` is an opt-in
2048
2591
  * boolean variant layered on top (the secondary color is the default).
@@ -2053,6 +2596,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
2053
2596
  * to the DOM and leaving it to specificity.
2054
2597
  */
2055
2598
  const checkboxVariants = cva([
2599
+ 'cursor-pointer',
2056
2600
  'data-[state=indeterminate]:bg-primary',
2057
2601
  'dark:data-[state=indeterminate]:bg-primary',
2058
2602
  'data-[state=indeterminate]:text-primary-foreground',
@@ -2091,7 +2635,7 @@ const checkboxVariants = cva([
2091
2635
  * projected content, pair it with an external `<label [for]>` via `inputId` or set `ariaLabel`.
2092
2636
  *
2093
2637
  * Inputs / Models:
2094
- * - `value` / `checked`: Two-way boolean state of the checkbox. Default is `false`.
2638
+ * - `checked`: Two-way (`[(checked)]`) boolean checked state, alias of the internal `value` model. Default is `false`.
2095
2639
  * - `indeterminate`: Two-way boolean state for mixed/indeterminate checkbox appearance. Default is `false`.
2096
2640
  * - `disabled`: Disables checkbox interaction.
2097
2641
  * - `required`: Marks checkbox as required.
@@ -2216,6 +2760,8 @@ const yuwSwitchSecondaryClass = [
2216
2760
  * - `disabled`: Disables switch interaction.
2217
2761
  * - `inputId`: HTML `id` for the underlying control, enabling external `<label for="...">` association.
2218
2762
  * - `ariaLabel`: Accessible name for switches with no visible adjacent label.
2763
+ * - `ariaLabelledby`: Id of the element that labels the switch, set as `aria-labelledby` on the control.
2764
+ * - `ariaDescribedby`: Id of the element that describes the switch, set as `aria-describedby` on the control.
2219
2765
  *
2220
2766
  * Usage:
2221
2767
  * ```html
@@ -2244,7 +2790,7 @@ class YuwSwitchComponent extends YuwValueAccessorBase {
2244
2790
  this._commit(checked);
2245
2791
  }
2246
2792
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwSwitchComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
2247
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.22", type: YuwSwitchComponent, isStandalone: true, selector: "yuw-switch", inputs: { ariaDescribedby: { classPropertyName: "ariaDescribedby", publicName: "ariaDescribedby", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, ariaLabelledby: { classPropertyName: "ariaLabelledby", publicName: "ariaLabelledby", isSignal: true, isRequired: false, transformFunction: null }, inputId: { classPropertyName: "inputId", publicName: "inputId", isSignal: true, isRequired: false, transformFunction: null }, primary: { classPropertyName: "primary", publicName: "primary", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "checked", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "checkedChange" }, host: { classAttribute: "contents" }, providers: [provideValueAccessor(YuwSwitchComponent)], usesInheritance: true, ngImport: i0, template: "<label yuwLabel class=\"gap-3\" (focusout)=\"_onBlur()\">\n <hlm-switch\n [checked]=\"value()\"\n [size]=\"_helmSize()\"\n [class]=\"_switchClass()\"\n [disabled]=\"_disabled()\"\n [inputId]=\"inputId() ?? null\"\n [aria-label]=\"ariaLabel() ?? null\"\n [aria-labelledby]=\"ariaLabelledby() ?? null\"\n [aria-describedby]=\"ariaDescribedby() ?? null\"\n (checkedChange)=\"onCheckedChange($event)\"\n />\n <ng-content />\n</label>\n", dependencies: [{ kind: "component", type: i1$6.HlmSwitch, selector: "hlm-switch", inputs: ["class", "checked", "disabled", "size", "inputId", "aria-label", "aria-labelledby", "aria-describedby"], outputs: ["checkedChange"] }, { kind: "directive", type: YuwLabel, selector: "label[yuwLabel]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2793
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.22", type: YuwSwitchComponent, isStandalone: true, selector: "yuw-switch", inputs: { ariaDescribedby: { classPropertyName: "ariaDescribedby", publicName: "ariaDescribedby", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, ariaLabelledby: { classPropertyName: "ariaLabelledby", publicName: "ariaLabelledby", isSignal: true, isRequired: false, transformFunction: null }, inputId: { classPropertyName: "inputId", publicName: "inputId", isSignal: true, isRequired: false, transformFunction: null }, primary: { classPropertyName: "primary", publicName: "primary", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "checked", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "checkedChange" }, host: { classAttribute: "contents" }, providers: [provideValueAccessor(YuwSwitchComponent)], usesInheritance: true, ngImport: i0, template: "<label yuwLabel class=\"gap-3\" (focusout)=\"_onBlur()\">\n <hlm-switch\n [checked]=\"value()\"\n [size]=\"_helmSize()\"\n [class]=\"_switchClass()\"\n [disabled]=\"_disabled()\"\n [inputId]=\"inputId() ?? null\"\n [aria-label]=\"ariaLabel() ?? null\"\n [aria-labelledby]=\"ariaLabelledby() ?? null\"\n [aria-describedby]=\"ariaDescribedby() ?? null\"\n (checkedChange)=\"onCheckedChange($event)\"\n />\n <ng-content />\n</label>\n", dependencies: [{ kind: "component", type: i1$b.HlmSwitch, selector: "hlm-switch", inputs: ["class", "checked", "disabled", "size", "inputId", "aria-label", "aria-labelledby", "aria-describedby"], outputs: ["checkedChange"] }, { kind: "directive", type: YuwLabel, selector: "label[yuwLabel]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2248
2794
  }
2249
2795
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwSwitchComponent, decorators: [{
2250
2796
  type: Component,
@@ -2308,7 +2854,7 @@ class YuwRadioGroupComponent extends YuwValueAccessorBase {
2308
2854
  this._commit(next);
2309
2855
  }
2310
2856
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwRadioGroupComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
2311
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: YuwRadioGroupComponent, isStandalone: true, selector: "yuw-radio-group", inputs: { ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, ariaLabelledby: { classPropertyName: "ariaLabelledby", publicName: "ariaLabelledby", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null }, primary: { classPropertyName: "primary", publicName: "primary", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, userClass: { classPropertyName: "userClass", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, host: { classAttribute: "contents" }, providers: [provideValueAccessor(YuwRadioGroupComponent)], usesInheritance: true, ngImport: i0, template: "<hlm-radio-group\n [class]=\"_groupClass()\"\n [value]=\"value() ?? ''\"\n [disabled]=\"_disabled()\"\n [required]=\"required()\"\n [name]=\"_name()\"\n [attr.aria-label]=\"ariaLabel() ?? null\"\n [attr.aria-labelledby]=\"ariaLabelledby() ?? null\"\n (valueChange)=\"onValueChange($event)\"\n (focusout)=\"_onBlur()\"\n>\n @for (option of options(); track option.value) {\n <label yuwLabel class=\"gap-3\">\n <hlm-radio [value]=\"option.value\" [disabled]=\"option.disabled ?? false\">\n <hlm-radio-indicator indicator />\n </hlm-radio>\n\n {{ option.label }}\n </label>\n }\n</hlm-radio-group>\n", dependencies: [{ kind: "directive", type: i1$7.HlmRadioGroup, selector: "[hlmRadioGroup],hlm-radio-group", inputs: ["class"] }, { kind: "component", type: i1$7.HlmRadio, selector: "hlm-radio", inputs: ["class", "inputId", "aria-label", "aria-labelledby", "aria-describedby", "value", "required", "disabled"], outputs: ["change"] }, { kind: "component", type: i1$7.HlmRadioIndicator, selector: "hlm-radio-indicator" }, { kind: "directive", type: YuwLabel, selector: "label[yuwLabel]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2857
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: YuwRadioGroupComponent, isStandalone: true, selector: "yuw-radio-group", inputs: { ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, ariaLabelledby: { classPropertyName: "ariaLabelledby", publicName: "ariaLabelledby", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null }, primary: { classPropertyName: "primary", publicName: "primary", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, userClass: { classPropertyName: "userClass", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, host: { classAttribute: "contents" }, providers: [provideValueAccessor(YuwRadioGroupComponent)], usesInheritance: true, ngImport: i0, template: "<hlm-radio-group\n [class]=\"_groupClass()\"\n [value]=\"value() ?? ''\"\n [disabled]=\"_disabled()\"\n [required]=\"required()\"\n [name]=\"_name()\"\n [attr.aria-label]=\"ariaLabel() ?? null\"\n [attr.aria-labelledby]=\"ariaLabelledby() ?? null\"\n (valueChange)=\"onValueChange($event)\"\n (focusout)=\"_onBlur()\"\n>\n @for (option of options(); track option.value) {\n <label yuwLabel class=\"gap-3\">\n <hlm-radio [value]=\"option.value\" [disabled]=\"option.disabled ?? false\">\n <hlm-radio-indicator indicator />\n </hlm-radio>\n\n {{ option.label }}\n </label>\n }\n</hlm-radio-group>\n", dependencies: [{ kind: "directive", type: i1$c.HlmRadioGroup, selector: "[hlmRadioGroup],hlm-radio-group", inputs: ["class"] }, { kind: "component", type: i1$c.HlmRadio, selector: "hlm-radio", inputs: ["class", "inputId", "aria-label", "aria-labelledby", "aria-describedby", "value", "required", "disabled"], outputs: ["change"] }, { kind: "component", type: i1$c.HlmRadioIndicator, selector: "hlm-radio-indicator" }, { kind: "directive", type: YuwLabel, selector: "label[yuwLabel]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2312
2858
  }
2313
2859
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwRadioGroupComponent, decorators: [{
2314
2860
  type: Component,
@@ -2330,7 +2876,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
2330
2876
  */
2331
2877
  class YuwSkeletonDirective {
2332
2878
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwSkeletonDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
2333
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwSkeletonDirective, isStandalone: true, selector: "[yuwSkeleton]", host: { attributes: { "aria-hidden": "true" } }, hostDirectives: [{ directive: i1$8.HlmSkeleton }], ngImport: i0 }); }
2879
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwSkeletonDirective, isStandalone: true, selector: "[yuwSkeleton]", host: { attributes: { "aria-hidden": "true" } }, hostDirectives: [{ directive: i1$d.HlmSkeleton }], ngImport: i0 }); }
2334
2880
  }
2335
2881
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwSkeletonDirective, decorators: [{
2336
2882
  type: Directive,
@@ -2348,6 +2894,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
2348
2894
  * `skeletonCount` placeholders shaped by `skeletonClass`; `empty` shows `emptyText`; `columnsClass`
2349
2895
  * holds the Tailwind column utilities.
2350
2896
  *
2897
+ * Inputs:
2898
+ * - `columnsClass`: Tailwind grid column utilities applied to the grid and its skeleton. Default is `'grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4'`.
2899
+ * - `empty`: Shows `emptyText` instead of the projected cards. Default is `false`.
2900
+ * - `emptyText`: Required message shown when `empty` is set. The app supplies and translates it.
2901
+ * - `loading`: Shows `skeletonCount` placeholders instead of the content; takes precedence over `empty`. Default is `false`.
2902
+ * - `skeletonClass`: Extra classes sizing each placeholder, e.g. its height. Default is `'h-16'`.
2903
+ * - `skeletonCount`: Number of placeholders shown while loading. Default is `12`.
2904
+ *
2351
2905
  * `YuwCardGridComponent.COLUMNS` holds the column classes admin lists share per view mode — `list`
2352
2906
  * is one column, `block` grows from one to five, and `tags` packs small tag cards up to six — so every listing lays out its cards the same
2353
2907
  * way: `[columnsClass]="YuwCardGridComponent.COLUMNS[mode]"`.
@@ -2375,7 +2929,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
2375
2929
  args: [{ selector: 'yuw-card-grid', changeDetection: ChangeDetectionStrategy.OnPush, imports: [YuwSkeletonDirective], template: "@if (loading()) {\n <div class=\"grid gap-4\" [class]=\"columnsClass()\">\n @for (skeleton of skeletons(); track skeleton) {\n <span yuwSkeleton class=\"block w-full rounded-xl\" [class]=\"skeletonClass()\"></span>\n }\n </div>\n} @else if (empty()) {\n <p class=\"text-sm text-muted-foreground\">{{ emptyText() }}</p>\n} @else {\n <div class=\"grid gap-4\" [class]=\"columnsClass()\">\n <ng-content />\n </div>\n}\n" }]
2376
2930
  }], propDecorators: { columnsClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "columnsClass", required: false }] }], empty: [{ type: i0.Input, args: [{ isSignal: true, alias: "empty", required: false }] }], emptyText: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyText", required: true }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], skeletonClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "skeletonClass", required: false }] }], skeletonCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "skeletonCount", required: false }] }] } });
2377
2931
 
2378
- /** While `pending` the card stays hidden in place under a skeleton, so the grid does not jump. */
2932
+ /**
2933
+ * While `pending` the card stays hidden in place under a skeleton, so the grid does not jump.
2934
+ *
2935
+ * Inputs:
2936
+ * - `pending`: Hides the projected card and overlays a skeleton while it is loading. Default is `false`.
2937
+ */
2379
2938
  class YuwCardGridItemComponent {
2380
2939
  constructor() {
2381
2940
  this.pending = input(false, { ...(ngDevMode ? { debugName: "pending" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
@@ -2406,7 +2965,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
2406
2965
  */
2407
2966
  class YuwCardDirective {
2408
2967
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwCardDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
2409
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwCardDirective, isStandalone: true, selector: "[yuwCard]", hostDirectives: [{ directive: i1$9.HlmCard, inputs: ["size", "size"] }], ngImport: i0 }); }
2968
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwCardDirective, isStandalone: true, selector: "[yuwCard]", hostDirectives: [{ directive: i1$e.HlmCard, inputs: ["size", "size"] }], ngImport: i0 }); }
2410
2969
  }
2411
2970
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwCardDirective, decorators: [{
2412
2971
  type: Directive,
@@ -2418,7 +2977,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
2418
2977
  /** Header container directive for a card. */
2419
2978
  class YuwCardHeaderDirective {
2420
2979
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwCardHeaderDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
2421
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwCardHeaderDirective, isStandalone: true, selector: "[yuwCardHeader]", hostDirectives: [{ directive: i1$9.HlmCardHeader }], ngImport: i0 }); }
2980
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwCardHeaderDirective, isStandalone: true, selector: "[yuwCardHeader]", hostDirectives: [{ directive: i1$e.HlmCardHeader }], ngImport: i0 }); }
2422
2981
  }
2423
2982
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwCardHeaderDirective, decorators: [{
2424
2983
  type: Directive,
@@ -2430,7 +2989,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
2430
2989
  /** Heading directive for card title text. */
2431
2990
  class YuwCardTitleDirective {
2432
2991
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwCardTitleDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
2433
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwCardTitleDirective, isStandalone: true, selector: "[yuwCardTitle]", hostDirectives: [{ directive: i1$9.HlmCardTitle }], ngImport: i0 }); }
2992
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwCardTitleDirective, isStandalone: true, selector: "[yuwCardTitle]", hostDirectives: [{ directive: i1$e.HlmCardTitle }], ngImport: i0 }); }
2434
2993
  }
2435
2994
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwCardTitleDirective, decorators: [{
2436
2995
  type: Directive,
@@ -2442,7 +3001,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
2442
3001
  /** Subtitle or description directive for card text. */
2443
3002
  class YuwCardDescriptionDirective {
2444
3003
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwCardDescriptionDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
2445
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwCardDescriptionDirective, isStandalone: true, selector: "[yuwCardDescription]", hostDirectives: [{ directive: i1$9.HlmCardDescription }], ngImport: i0 }); }
3004
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwCardDescriptionDirective, isStandalone: true, selector: "[yuwCardDescription]", hostDirectives: [{ directive: i1$e.HlmCardDescription }], ngImport: i0 }); }
2446
3005
  }
2447
3006
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwCardDescriptionDirective, decorators: [{
2448
3007
  type: Directive,
@@ -2454,7 +3013,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
2454
3013
  /** Header action directive for placing top-right controls (e.g. menu button or status badge). */
2455
3014
  class YuwCardActionDirective {
2456
3015
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwCardActionDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
2457
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwCardActionDirective, isStandalone: true, selector: "[yuwCardAction]", hostDirectives: [{ directive: i1$9.HlmCardAction }], ngImport: i0 }); }
3016
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwCardActionDirective, isStandalone: true, selector: "[yuwCardAction]", hostDirectives: [{ directive: i1$e.HlmCardAction }], ngImport: i0 }); }
2458
3017
  }
2459
3018
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwCardActionDirective, decorators: [{
2460
3019
  type: Directive,
@@ -2466,7 +3025,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
2466
3025
  /** Main body container directive for card content. */
2467
3026
  class YuwCardContentDirective {
2468
3027
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwCardContentDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
2469
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwCardContentDirective, isStandalone: true, selector: "[yuwCardContent]", hostDirectives: [{ directive: i1$9.HlmCardContent }], ngImport: i0 }); }
3028
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwCardContentDirective, isStandalone: true, selector: "[yuwCardContent]", hostDirectives: [{ directive: i1$e.HlmCardContent }], ngImport: i0 }); }
2470
3029
  }
2471
3030
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwCardContentDirective, decorators: [{
2472
3031
  type: Directive,
@@ -2478,7 +3037,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
2478
3037
  /** Footer container directive for card action buttons or summary info. */
2479
3038
  class YuwCardFooterDirective {
2480
3039
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwCardFooterDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
2481
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwCardFooterDirective, isStandalone: true, selector: "[yuwCardFooter]", hostDirectives: [{ directive: i1$9.HlmCardFooter }], ngImport: i0 }); }
3040
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwCardFooterDirective, isStandalone: true, selector: "[yuwCardFooter]", hostDirectives: [{ directive: i1$e.HlmCardFooter }], ngImport: i0 }); }
2482
3041
  }
2483
3042
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwCardFooterDirective, decorators: [{
2484
3043
  type: Directive,
@@ -2519,7 +3078,7 @@ const YuwCardImports = [
2519
3078
  */
2520
3079
  class YuwEmptyDirective {
2521
3080
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwEmptyDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
2522
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwEmptyDirective, isStandalone: true, selector: "[yuwEmpty]", hostDirectives: [{ directive: i1$a.HlmEmpty }], ngImport: i0 }); }
3081
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwEmptyDirective, isStandalone: true, selector: "[yuwEmpty]", hostDirectives: [{ directive: i1$f.HlmEmpty }], ngImport: i0 }); }
2523
3082
  }
2524
3083
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwEmptyDirective, decorators: [{
2525
3084
  type: Directive,
@@ -2531,7 +3090,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
2531
3090
  /** Header container directive for empty-state title and media. */
2532
3091
  class YuwEmptyHeaderDirective {
2533
3092
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwEmptyHeaderDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
2534
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwEmptyHeaderDirective, isStandalone: true, selector: "[yuwEmptyHeader]", hostDirectives: [{ directive: i1$a.HlmEmptyHeader }], ngImport: i0 }); }
3093
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwEmptyHeaderDirective, isStandalone: true, selector: "[yuwEmptyHeader]", hostDirectives: [{ directive: i1$f.HlmEmptyHeader }], ngImport: i0 }); }
2535
3094
  }
2536
3095
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwEmptyHeaderDirective, decorators: [{
2537
3096
  type: Directive,
@@ -2543,7 +3102,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
2543
3102
  /** Slot directive for empty-state icons or illustrations. Supports `variant` input. */
2544
3103
  class YuwEmptyMediaDirective {
2545
3104
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwEmptyMediaDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
2546
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwEmptyMediaDirective, isStandalone: true, selector: "[yuwEmptyMedia]", hostDirectives: [{ directive: i1$a.HlmEmptyMedia, inputs: ["variant", "variant"] }], ngImport: i0 }); }
3105
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwEmptyMediaDirective, isStandalone: true, selector: "[yuwEmptyMedia]", hostDirectives: [{ directive: i1$f.HlmEmptyMedia, inputs: ["variant", "variant"] }], ngImport: i0 }); }
2547
3106
  }
2548
3107
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwEmptyMediaDirective, decorators: [{
2549
3108
  type: Directive,
@@ -2555,7 +3114,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
2555
3114
  /** Title heading directive for empty state message. */
2556
3115
  class YuwEmptyTitleDirective {
2557
3116
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwEmptyTitleDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
2558
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwEmptyTitleDirective, isStandalone: true, selector: "[yuwEmptyTitle]", hostDirectives: [{ directive: i1$a.HlmEmptyTitle }], ngImport: i0 }); }
3117
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwEmptyTitleDirective, isStandalone: true, selector: "[yuwEmptyTitle]", hostDirectives: [{ directive: i1$f.HlmEmptyTitle }], ngImport: i0 }); }
2559
3118
  }
2560
3119
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwEmptyTitleDirective, decorators: [{
2561
3120
  type: Directive,
@@ -2567,7 +3126,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
2567
3126
  /** Description paragraph directive explaining the empty state. */
2568
3127
  class YuwEmptyDescriptionDirective {
2569
3128
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwEmptyDescriptionDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
2570
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwEmptyDescriptionDirective, isStandalone: true, selector: "[yuwEmptyDescription]", hostDirectives: [{ directive: i1$a.HlmEmptyDescription }], ngImport: i0 }); }
3129
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwEmptyDescriptionDirective, isStandalone: true, selector: "[yuwEmptyDescription]", hostDirectives: [{ directive: i1$f.HlmEmptyDescription }], ngImport: i0 }); }
2571
3130
  }
2572
3131
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwEmptyDescriptionDirective, decorators: [{
2573
3132
  type: Directive,
@@ -2579,7 +3138,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
2579
3138
  /** Content slot directive for action buttons or call-to-action controls in an empty state. */
2580
3139
  class YuwEmptyContentDirective {
2581
3140
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwEmptyContentDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
2582
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwEmptyContentDirective, isStandalone: true, selector: "[yuwEmptyContent]", hostDirectives: [{ directive: i1$a.HlmEmptyContent }], ngImport: i0 }); }
3141
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwEmptyContentDirective, isStandalone: true, selector: "[yuwEmptyContent]", hostDirectives: [{ directive: i1$f.HlmEmptyContent }], ngImport: i0 }); }
2583
3142
  }
2584
3143
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwEmptyContentDirective, decorators: [{
2585
3144
  type: Directive,
@@ -2700,6 +3259,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
2700
3259
  * </div>
2701
3260
  * </ng-template>
2702
3261
  * ```
3262
+ *
3263
+ * Inputs:
3264
+ * - `yuwContextMenuTrigger`: Required `TemplateRef` of the menu to open on right-click.
3265
+ * - `yuwContextMenuTriggerData`: Optional data made available to the menu template as its context. Default is `undefined`.
2703
3266
  */
2704
3267
  class YuwContextMenuTriggerDirective {
2705
3268
  constructor() {
@@ -2714,7 +3277,7 @@ class YuwContextMenuTriggerDirective {
2714
3277
  });
2715
3278
  }
2716
3279
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwContextMenuTriggerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
2717
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.22", type: YuwContextMenuTriggerDirective, isStandalone: true, selector: "[yuwContextMenuTrigger]", inputs: { menu: { classPropertyName: "menu", publicName: "yuwContextMenuTrigger", isSignal: true, isRequired: true, transformFunction: null }, menuData: { classPropertyName: "menuData", publicName: "yuwContextMenuTriggerData", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { closed: "closed", opened: "opened" }, hostDirectives: [{ directive: i1$b.HlmContextMenuTrigger, inputs: ["disabled", "disabled", "align", "align", "side", "side"] }], ngImport: i0 }); }
3280
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.22", type: YuwContextMenuTriggerDirective, isStandalone: true, selector: "[yuwContextMenuTrigger]", inputs: { menu: { classPropertyName: "menu", publicName: "yuwContextMenuTrigger", isSignal: true, isRequired: true, transformFunction: null }, menuData: { classPropertyName: "menuData", publicName: "yuwContextMenuTriggerData", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { closed: "closed", opened: "opened" }, hostDirectives: [{ directive: i1$g.HlmContextMenuTrigger, inputs: ["disabled", "disabled", "align", "align", "side", "side"] }], ngImport: i0 }); }
2718
3281
  }
2719
3282
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwContextMenuTriggerDirective, decorators: [{
2720
3283
  type: Directive,
@@ -2770,6 +3333,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
2770
3333
  * <yuw-context-menu-checkbox-indicator />
2771
3334
  * </button>
2772
3335
  * ```
3336
+ *
3337
+ * Inputs:
3338
+ * - `checked`: Whether the item is currently checked, which shows the projected indicator. Default is `false`.
3339
+ * - `disabled`: Disables the item so it cannot be triggered. Default is `false`.
2773
3340
  */
2774
3341
  class YuwContextMenuCheckboxDirective {
2775
3342
  constructor() {
@@ -2809,6 +3376,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
2809
3376
  * </button>
2810
3377
  * </div>
2811
3378
  * ```
3379
+ *
3380
+ * Inputs:
3381
+ * - `checked`: Whether the item is the selected option, which shows the projected indicator. Default is `false`.
3382
+ * - `disabled`: Disables the item so it cannot be selected. Default is `false`.
2812
3383
  */
2813
3384
  class YuwContextMenuRadioDirective {
2814
3385
  constructor() {
@@ -2901,6 +3472,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
2901
3472
  * <yuw-context-menu-sub-indicator />
2902
3473
  * </button>
2903
3474
  * ```
3475
+ *
3476
+ * Inputs:
3477
+ * - `yuwContextMenuSubTrigger`: Required `TemplateRef` of the sub-menu this item expands.
2904
3478
  */
2905
3479
  class YuwContextMenuSubTriggerDirective {
2906
3480
  constructor() {
@@ -2957,6 +3531,7 @@ let nextUniqueId = 0;
2957
3531
  * - `align`: Popover alignment relative to trigger (`'start'`, `'center'`, `'end'`). Default is `'start'`.
2958
3532
  * - `buttonId`: HTML `id` for the trigger button, enabling external `<label for="...">`
2959
3533
  * association. When omitted, a unique per-instance id is generated.
3534
+ * - `size`: Trigger button height (`YuwFieldSizeDto`), matching the `<yuw-button>` size of the same name. Default is `'default'`.
2960
3535
  * - `class`: Extra classes merged onto the trigger button (e.g. a width), consumer classes win.
2961
3536
  * - `invalid`: Forces invalid styling.
2962
3537
  * - `formatDate`: Custom date formatter function `(date: Date) => string` for the trigger label.
@@ -3034,7 +3609,7 @@ class YuwDatepickerComponent extends YuwValueAccessorBase {
3034
3609
  this._commit(next);
3035
3610
  }
3036
3611
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwDatepickerComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
3037
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: YuwDatepickerComponent, isStandalone: true, selector: "yuw-datepicker", inputs: { align: { classPropertyName: "align", publicName: "align", isSignal: true, isRequired: false, transformFunction: null }, buttonId: { classPropertyName: "buttonId", publicName: "buttonId", isSignal: true, isRequired: false, transformFunction: null }, captionLayout: { classPropertyName: "captionLayout", publicName: "captionLayout", isSignal: true, isRequired: false, transformFunction: null }, formatDate: { classPropertyName: "formatDate", publicName: "formatDate", isSignal: true, isRequired: false, transformFunction: null }, invalid: { classPropertyName: "invalid", publicName: "invalid", isSignal: true, isRequired: false, transformFunction: null }, maxDate: { classPropertyName: "maxDate", publicName: "maxDate", isSignal: true, isRequired: false, transformFunction: null }, minDate: { classPropertyName: "minDate", publicName: "minDate", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, userClass: { classPropertyName: "userClass", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, host: { classAttribute: "contents" }, providers: [provideValueAccessor(YuwDatepickerComponent)], usesInheritance: true, ngImport: i0, template: "@switch (mode()) {\n @case ('range') {\n <hlm-date-range-picker\n [date]=\"_rangeValue()\"\n [disabled]=\"_disabled()\"\n [minDate]=\"minDate()\"\n [maxDate]=\"maxDate()\"\n [captionLayout]=\"captionLayout()\"\n [align]=\"align()\"\n [formatDates]=\"_formatRange()\"\n (dateChange)=\"onValueChange($event)\"\n (focusout)=\"_onBlur()\"\n >\n <hlm-date-picker-trigger [buttonId]=\"_buttonId()\" [class]=\"_triggerClass()\" [forceInvalid]=\"invalid()\">\n {{ placeholder() ?? '' }}\n </hlm-date-picker-trigger>\n </hlm-date-range-picker>\n }\n @case ('multiple') {\n <hlm-date-picker-multi\n [date]=\"_multipleValue()\"\n [disabled]=\"_disabled()\"\n [minDate]=\"minDate()\"\n [maxDate]=\"maxDate()\"\n [captionLayout]=\"captionLayout()\"\n [align]=\"align()\"\n [formatDates]=\"_formatMulti()\"\n (dateChange)=\"onValueChange($event)\"\n (focusout)=\"_onBlur()\"\n >\n <hlm-date-picker-trigger [buttonId]=\"_buttonId()\" [class]=\"_triggerClass()\" [forceInvalid]=\"invalid()\">\n {{ placeholder() ?? '' }}\n </hlm-date-picker-trigger>\n </hlm-date-picker-multi>\n }\n @case ('monthYear') {\n <hlm-month-year-picker\n [date]=\"_singleValue()\"\n [disabled]=\"_disabled()\"\n [minDate]=\"minDate()\"\n [maxDate]=\"maxDate()\"\n [align]=\"align()\"\n [formatDate]=\"_formatMonthYear()\"\n (dateChange)=\"onValueChange($event)\"\n (focusout)=\"_onBlur()\"\n >\n <hlm-date-picker-trigger [buttonId]=\"_buttonId()\" [class]=\"_triggerClass()\" [forceInvalid]=\"invalid()\">\n {{ placeholder() ?? '' }}\n </hlm-date-picker-trigger>\n </hlm-month-year-picker>\n }\n @default {\n <hlm-date-picker\n [date]=\"_singleValue()\"\n [disabled]=\"_disabled()\"\n [minDate]=\"minDate()\"\n [maxDate]=\"maxDate()\"\n [captionLayout]=\"captionLayout()\"\n [align]=\"align()\"\n [formatDate]=\"_formatSingle()\"\n (dateChange)=\"onValueChange($event)\"\n (focusout)=\"_onBlur()\"\n >\n <hlm-date-picker-trigger [buttonId]=\"_buttonId()\" [class]=\"_triggerClass()\" [forceInvalid]=\"invalid()\">\n {{ placeholder() ?? '' }}\n </hlm-date-picker-trigger>\n </hlm-date-picker>\n }\n}\n", dependencies: [{ kind: "component", type: i1$c.HlmDatePicker, selector: "hlm-date-picker", inputs: ["align", "captionLayout", "minDate", "maxDate", "disabled", "date", "defaultFocusedDate", "autoCloseOnSelect", "formatDate", "transformDate"], outputs: ["dateChange"] }, { kind: "component", type: i1$c.HlmDatePickerMulti, selector: "hlm-date-picker-multi", inputs: ["align", "captionLayout", "minDate", "maxDate", "minSelection", "maxSelection", "disabled", "date", "autoCloseOnMaxSelection", "formatDates", "transformDates"], outputs: ["dateChange"] }, { kind: "component", type: i1$c.HlmDateRangePicker, selector: "hlm-date-range-picker", inputs: ["align", "captionLayout", "minDate", "maxDate", "disabled", "date", "autoCloseOnEndSelection", "formatDates", "transformDates"], outputs: ["dateChange"] }, { kind: "component", type: i1$c.HlmDatePickerTrigger, selector: "hlm-date-picker-trigger", inputs: ["class", "buttonId", "forceInvalid", "variant", "showTrigger"] }, { kind: "component", type: i1$c.HlmMonthYearPicker, selector: "hlm-month-year-picker", inputs: ["align", "minDate", "maxDate", "disabled", "date", "defaultFocusedDate", "autoCloseOnSelect", "formatDate", "transformDate"], outputs: ["dateChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3612
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: YuwDatepickerComponent, isStandalone: true, selector: "yuw-datepicker", inputs: { align: { classPropertyName: "align", publicName: "align", isSignal: true, isRequired: false, transformFunction: null }, buttonId: { classPropertyName: "buttonId", publicName: "buttonId", isSignal: true, isRequired: false, transformFunction: null }, captionLayout: { classPropertyName: "captionLayout", publicName: "captionLayout", isSignal: true, isRequired: false, transformFunction: null }, formatDate: { classPropertyName: "formatDate", publicName: "formatDate", isSignal: true, isRequired: false, transformFunction: null }, invalid: { classPropertyName: "invalid", publicName: "invalid", isSignal: true, isRequired: false, transformFunction: null }, maxDate: { classPropertyName: "maxDate", publicName: "maxDate", isSignal: true, isRequired: false, transformFunction: null }, minDate: { classPropertyName: "minDate", publicName: "minDate", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, userClass: { classPropertyName: "userClass", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, host: { classAttribute: "contents" }, providers: [provideValueAccessor(YuwDatepickerComponent)], usesInheritance: true, ngImport: i0, template: "@switch (mode()) {\n @case ('range') {\n <hlm-date-range-picker\n [date]=\"_rangeValue()\"\n [disabled]=\"_disabled()\"\n [minDate]=\"minDate()\"\n [maxDate]=\"maxDate()\"\n [captionLayout]=\"captionLayout()\"\n [align]=\"align()\"\n [formatDates]=\"_formatRange()\"\n (dateChange)=\"onValueChange($event)\"\n (focusout)=\"_onBlur()\"\n >\n <hlm-date-picker-trigger [buttonId]=\"_buttonId()\" [class]=\"_triggerClass()\" [forceInvalid]=\"invalid()\">\n {{ placeholder() ?? '' }}\n </hlm-date-picker-trigger>\n </hlm-date-range-picker>\n }\n @case ('multiple') {\n <hlm-date-picker-multi\n [date]=\"_multipleValue()\"\n [disabled]=\"_disabled()\"\n [minDate]=\"minDate()\"\n [maxDate]=\"maxDate()\"\n [captionLayout]=\"captionLayout()\"\n [align]=\"align()\"\n [formatDates]=\"_formatMulti()\"\n (dateChange)=\"onValueChange($event)\"\n (focusout)=\"_onBlur()\"\n >\n <hlm-date-picker-trigger [buttonId]=\"_buttonId()\" [class]=\"_triggerClass()\" [forceInvalid]=\"invalid()\">\n {{ placeholder() ?? '' }}\n </hlm-date-picker-trigger>\n </hlm-date-picker-multi>\n }\n @case ('monthYear') {\n <hlm-month-year-picker\n [date]=\"_singleValue()\"\n [disabled]=\"_disabled()\"\n [minDate]=\"minDate()\"\n [maxDate]=\"maxDate()\"\n [align]=\"align()\"\n [formatDate]=\"_formatMonthYear()\"\n (dateChange)=\"onValueChange($event)\"\n (focusout)=\"_onBlur()\"\n >\n <hlm-date-picker-trigger [buttonId]=\"_buttonId()\" [class]=\"_triggerClass()\" [forceInvalid]=\"invalid()\">\n {{ placeholder() ?? '' }}\n </hlm-date-picker-trigger>\n </hlm-month-year-picker>\n }\n @default {\n <hlm-date-picker\n [date]=\"_singleValue()\"\n [disabled]=\"_disabled()\"\n [minDate]=\"minDate()\"\n [maxDate]=\"maxDate()\"\n [captionLayout]=\"captionLayout()\"\n [align]=\"align()\"\n [formatDate]=\"_formatSingle()\"\n (dateChange)=\"onValueChange($event)\"\n (focusout)=\"_onBlur()\"\n >\n <hlm-date-picker-trigger [buttonId]=\"_buttonId()\" [class]=\"_triggerClass()\" [forceInvalid]=\"invalid()\">\n {{ placeholder() ?? '' }}\n </hlm-date-picker-trigger>\n </hlm-date-picker>\n }\n}\n", dependencies: [{ kind: "component", type: i1$h.HlmDatePicker, selector: "hlm-date-picker", inputs: ["align", "captionLayout", "minDate", "maxDate", "disabled", "date", "defaultFocusedDate", "autoCloseOnSelect", "formatDate", "transformDate"], outputs: ["dateChange"] }, { kind: "component", type: i1$h.HlmDatePickerMulti, selector: "hlm-date-picker-multi", inputs: ["align", "captionLayout", "minDate", "maxDate", "minSelection", "maxSelection", "disabled", "date", "autoCloseOnMaxSelection", "formatDates", "transformDates"], outputs: ["dateChange"] }, { kind: "component", type: i1$h.HlmDateRangePicker, selector: "hlm-date-range-picker", inputs: ["align", "captionLayout", "minDate", "maxDate", "disabled", "date", "autoCloseOnEndSelection", "formatDates", "transformDates"], outputs: ["dateChange"] }, { kind: "component", type: i1$h.HlmDatePickerTrigger, selector: "hlm-date-picker-trigger", inputs: ["class", "buttonId", "forceInvalid", "variant", "showTrigger"] }, { kind: "component", type: i1$h.HlmMonthYearPicker, selector: "hlm-month-year-picker", inputs: ["align", "minDate", "maxDate", "disabled", "date", "defaultFocusedDate", "autoCloseOnSelect", "formatDate", "transformDate"], outputs: ["dateChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3038
3613
  }
3039
3614
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwDatepickerComponent, decorators: [{
3040
3615
  type: Component,
@@ -3062,7 +3637,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
3062
3637
  */
3063
3638
  class YuwTableContainerDirective {
3064
3639
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwTableContainerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
3065
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwTableContainerDirective, isStandalone: true, selector: "[yuwTableContainer]", hostDirectives: [{ directive: i1$d.HlmTableContainer }], ngImport: i0 }); }
3640
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwTableContainerDirective, isStandalone: true, selector: "[yuwTableContainer]", hostDirectives: [{ directive: i1$i.HlmTableContainer }], ngImport: i0 }); }
3066
3641
  }
3067
3642
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwTableContainerDirective, decorators: [{
3068
3643
  type: Directive,
@@ -3074,7 +3649,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
3074
3649
  /** Table element styling directive applied to native `<table>`. */
3075
3650
  class YuwTableDirective {
3076
3651
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwTableDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
3077
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwTableDirective, isStandalone: true, selector: "[yuwTable]", hostDirectives: [{ directive: i1$d.HlmTable }], ngImport: i0 }); }
3652
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwTableDirective, isStandalone: true, selector: "[yuwTable]", hostDirectives: [{ directive: i1$i.HlmTable }], ngImport: i0 }); }
3078
3653
  }
3079
3654
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwTableDirective, decorators: [{
3080
3655
  type: Directive,
@@ -3086,7 +3661,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
3086
3661
  /** Table header container directive applied to native `<thead>`. */
3087
3662
  class YuwTHeadDirective {
3088
3663
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwTHeadDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
3089
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwTHeadDirective, isStandalone: true, selector: "[yuwTHead]", hostDirectives: [{ directive: i1$d.HlmTHead }], ngImport: i0 }); }
3664
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwTHeadDirective, isStandalone: true, selector: "[yuwTHead]", hostDirectives: [{ directive: i1$i.HlmTHead }], ngImport: i0 }); }
3090
3665
  }
3091
3666
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwTHeadDirective, decorators: [{
3092
3667
  type: Directive,
@@ -3098,7 +3673,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
3098
3673
  /** Table body container directive applied to native `<tbody>`. */
3099
3674
  class YuwTBodyDirective {
3100
3675
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwTBodyDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
3101
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwTBodyDirective, isStandalone: true, selector: "[yuwTBody]", hostDirectives: [{ directive: i1$d.HlmTBody }], ngImport: i0 }); }
3676
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwTBodyDirective, isStandalone: true, selector: "[yuwTBody]", hostDirectives: [{ directive: i1$i.HlmTBody }], ngImport: i0 }); }
3102
3677
  }
3103
3678
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwTBodyDirective, decorators: [{
3104
3679
  type: Directive,
@@ -3110,7 +3685,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
3110
3685
  /** Table footer container directive applied to native `<tfoot>`. */
3111
3686
  class YuwTFootDirective {
3112
3687
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwTFootDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
3113
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwTFootDirective, isStandalone: true, selector: "[yuwTFoot]", hostDirectives: [{ directive: i1$d.HlmTFoot }], ngImport: i0 }); }
3688
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwTFootDirective, isStandalone: true, selector: "[yuwTFoot]", hostDirectives: [{ directive: i1$i.HlmTFoot }], ngImport: i0 }); }
3114
3689
  }
3115
3690
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwTFootDirective, decorators: [{
3116
3691
  type: Directive,
@@ -3122,7 +3697,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
3122
3697
  /** Table row directive applied to native `<tr>`. */
3123
3698
  class YuwTrDirective {
3124
3699
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwTrDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
3125
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwTrDirective, isStandalone: true, selector: "[yuwTr]", hostDirectives: [{ directive: i1$d.HlmTr }], ngImport: i0 }); }
3700
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwTrDirective, isStandalone: true, selector: "[yuwTr]", hostDirectives: [{ directive: i1$i.HlmTr }], ngImport: i0 }); }
3126
3701
  }
3127
3702
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwTrDirective, decorators: [{
3128
3703
  type: Directive,
@@ -3134,7 +3709,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
3134
3709
  /** Table header cell directive applied to native `<th>`. */
3135
3710
  class YuwThDirective {
3136
3711
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwThDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
3137
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwThDirective, isStandalone: true, selector: "[yuwTh]", hostDirectives: [{ directive: i1$d.HlmTh }], ngImport: i0 }); }
3712
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwThDirective, isStandalone: true, selector: "[yuwTh]", hostDirectives: [{ directive: i1$i.HlmTh }], ngImport: i0 }); }
3138
3713
  }
3139
3714
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwThDirective, decorators: [{
3140
3715
  type: Directive,
@@ -3146,146 +3721,51 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
3146
3721
  /** Table data cell directive applied to native `<td>`. */
3147
3722
  class YuwTdDirective {
3148
3723
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwTdDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
3149
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwTdDirective, isStandalone: true, selector: "[yuwTd]", hostDirectives: [{ directive: i1$d.HlmTd }], ngImport: i0 }); }
3724
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwTdDirective, isStandalone: true, selector: "[yuwTd]", hostDirectives: [{ directive: i1$i.HlmTd }], ngImport: i0 }); }
3150
3725
  }
3151
3726
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwTdDirective, decorators: [{
3152
3727
  type: Directive,
3153
3728
  args: [{
3154
- selector: '[yuwTd]',
3155
- hostDirectives: [HlmTd],
3156
- }]
3157
- }] });
3158
- /** Table caption directive applied to native `<caption>`. */
3159
- class YuwCaptionDirective {
3160
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwCaptionDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
3161
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwCaptionDirective, isStandalone: true, selector: "[yuwCaption]", hostDirectives: [{ directive: i1$d.HlmCaption }], ngImport: i0 }); }
3162
- }
3163
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwCaptionDirective, decorators: [{
3164
- type: Directive,
3165
- args: [{
3166
- selector: '[yuwCaption]',
3167
- hostDirectives: [HlmCaption],
3168
- }]
3169
- }] });
3170
- /** Table custom pagination div content. */
3171
- class YuwDatatablePaginationDirective {
3172
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwDatatablePaginationDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
3173
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwDatatablePaginationDirective, isStandalone: true, selector: "[yuwDatatablePagination]", ngImport: i0 }); }
3174
- }
3175
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwDatatablePaginationDirective, decorators: [{
3176
- type: Directive,
3177
- args: [{
3178
- selector: '[yuwDatatablePagination]',
3179
- }]
3180
- }] });
3181
- /** Every table part, for a consumer's `imports`. */
3182
- const YuwTableImports = [
3183
- YuwTableContainerDirective,
3184
- YuwTableDirective,
3185
- YuwTHeadDirective,
3186
- YuwTBodyDirective,
3187
- YuwTFootDirective,
3188
- YuwTrDirective,
3189
- YuwThDirective,
3190
- YuwTdDirective,
3191
- YuwCaptionDirective,
3192
- YuwDatatablePaginationDirective,
3193
- ];
3194
-
3195
- /**
3196
- * Makes a `<yuw-button>` the trigger of the surrounding `<yuw-popover>`.
3197
- *
3198
- * The helm trigger directive's selector only matches a native `button`, so composing the brain
3199
- * directive here is what lets the popover use `<yuw-button>` rather than a bare `[hlmBtn]` element.
3200
- * Brain needs three things from its host, all of which `<yuw-button>` provides: the `click` that
3201
- * bubbles up from the inner button, the `aria-expanded`/`data-state` attributes, and a host box to
3202
- * anchor the panel against — hence `<yuw-button>`'s `inline-flex` host, since a `display: contents`
3203
- * host has no rect for the overlay to position from.
3204
- *
3205
- * `data-slot` mirrors the helm directive so the popover stylesheet targets both identically.
3206
- */
3207
- class YuwPopoverTriggerDirective {
3208
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwPopoverTriggerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
3209
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwPopoverTriggerDirective, isStandalone: true, selector: "yuw-button[yuwPopoverTriggerFor], yuw-button[yuwPopoverTriggerButton]", host: { attributes: { "data-slot": "popover-trigger" } }, hostDirectives: [{ directive: i1$e.BrnPopoverTrigger, inputs: ["id", "id", "brnPopoverTriggerFor", "yuwPopoverTriggerFor", "type", "type"] }], ngImport: i0 }); }
3210
- }
3211
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwPopoverTriggerDirective, decorators: [{
3212
- type: Directive,
3213
- args: [{
3214
- selector: 'yuw-button[yuwPopoverTriggerFor], yuw-button[yuwPopoverTriggerButton]',
3215
- hostDirectives: [
3216
- { directive: BrnPopoverTrigger, inputs: ['id', 'brnPopoverTriggerFor: yuwPopoverTriggerFor', 'type'] },
3217
- ],
3218
- host: { 'data-slot': 'popover-trigger' },
3219
- }]
3220
- }] });
3221
-
3222
- /**
3223
- * Popover component for displaying anchored floating overlay panels.
3224
- *
3225
- * Inputs / Models:
3226
- * - `open`: Two-way open/closed state (`boolean`). Drive directly via `[(open)]` to open/close programmatically.
3227
- * - `showTrigger`: Whether to render the trigger button. Set `false` when opening only via `[(open)]`.
3228
- * - `align`: Panel alignment relative to trigger (`'start'`, `'center'`, `'end'`). Default is `'center'`.
3229
- * - `sideOffset`: Pixel offset between the trigger and the panel. Default is `4`.
3230
- * - `sideOffset`: Pixel offset for X sides. Positive px for right, negative for left side.
3231
- * - `title`: Optional header title text. User-facing text the consuming app is responsible for translating.
3232
- * - `description`: Optional header description text. User-facing text the consuming app is responsible for translating.
3233
- * - `panelClass`: Extra classes merged onto the popover panel (e.g. `w-80` to widen it). They win
3234
- * over the library defaults via `twMerge`.
3235
- * - `triggerVariant`: Button style variant for the trigger button.
3236
- * - `triggerColor`: Brand color theme for the trigger button (any `YuwColorDto` value). Default is
3237
- * `'neutral'`.
3238
- * - `triggerSize`: Button size for the trigger button.
3239
- * - `triggerTransparent`: Strips the trigger's background and border in every state (rest, hover,
3240
- * open), for triggers whose projected content is the whole control — an avatar, a name, a chevron.
3241
- * - `triggerClass`: Extra classes merged onto the trigger button, last, so they beat both the
3242
- * variant classes and `triggerTransparent` (e.g. `h-auto p-0` to drop the button's own box).
3243
- *
3244
- * The panel is always anchored to the trigger, including when `open` is set from code without a
3245
- * click on it; the brain trigger only records its element on click.
3246
- *
3247
- * The trigger is a `<yuw-button>`; `YuwPopoverTriggerDirective` composes the brain trigger onto it,
3248
- * so the popover reuses our button component instead of applying `[hlmBtn]` directly.
3249
- *
3250
- * Usage:
3251
- * ```html
3252
- * <yuw-popover [(open)]="isOpen" title="Notifications" description="You're all caught up.">
3253
- * <ng-container yuwPopoverTrigger>View Notifications</ng-container>
3254
- *
3255
- * <p>Popover content body goes here.</p>
3256
- * </yuw-popover>
3257
- * ```
3258
- */
3259
- class YuwPopoverComponent {
3260
- constructor() {
3261
- this._trigger = viewChild('trigger', { ...(ngDevMode ? { debugName: "_trigger" } : /* istanbul ignore next */ {}), read: ElementRef });
3262
- this.align = input('center', ...(ngDevMode ? [{ debugName: "align" }] : /* istanbul ignore next */ []));
3263
- this.description = input(undefined, ...(ngDevMode ? [{ debugName: "description" }] : /* istanbul ignore next */ []));
3264
- this.offsetX = input(0, ...(ngDevMode ? [{ debugName: "offsetX" }] : /* istanbul ignore next */ []));
3265
- this.open = model(false, ...(ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []));
3266
- this.panelClass = input(undefined, ...(ngDevMode ? [{ debugName: "panelClass" }] : /* istanbul ignore next */ []));
3267
- this.showTrigger = input(true, { ...(ngDevMode ? { debugName: "showTrigger" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
3268
- this.sideOffset = input(4, ...(ngDevMode ? [{ debugName: "sideOffset" }] : /* istanbul ignore next */ []));
3269
- this.title = input(undefined, ...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
3270
- this.triggerClass = input('', ...(ngDevMode ? [{ debugName: "triggerClass" }] : /* istanbul ignore next */ []));
3271
- this.triggerColor = input('neutral', ...(ngDevMode ? [{ debugName: "triggerColor" }] : /* istanbul ignore next */ []));
3272
- this.triggerSize = input('default', ...(ngDevMode ? [{ debugName: "triggerSize" }] : /* istanbul ignore next */ []));
3273
- this.triggerTransparent = input(false, { ...(ngDevMode ? { debugName: "triggerTransparent" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
3274
- this.triggerVariant = input('outline', ...(ngDevMode ? [{ debugName: "triggerVariant" }] : /* istanbul ignore next */ []));
3275
- this._popoverState = computed(() => (this.open() ? 'open' : 'closed'), ...(ngDevMode ? [{ debugName: "_popoverState" }] : /* istanbul ignore next */ []));
3276
- }
3277
- onOpenChange(state) {
3278
- this.open.set(state === 'open');
3279
- }
3280
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwPopoverComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3281
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: YuwPopoverComponent, isStandalone: true, selector: "yuw-popover", inputs: { align: { classPropertyName: "align", publicName: "align", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, offsetX: { classPropertyName: "offsetX", publicName: "offsetX", isSignal: true, isRequired: false, transformFunction: null }, open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, panelClass: { classPropertyName: "panelClass", publicName: "panelClass", isSignal: true, isRequired: false, transformFunction: null }, showTrigger: { classPropertyName: "showTrigger", publicName: "showTrigger", isSignal: true, isRequired: false, transformFunction: null }, sideOffset: { classPropertyName: "sideOffset", publicName: "sideOffset", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, triggerClass: { classPropertyName: "triggerClass", publicName: "triggerClass", isSignal: true, isRequired: false, transformFunction: null }, triggerColor: { classPropertyName: "triggerColor", publicName: "triggerColor", isSignal: true, isRequired: false, transformFunction: null }, triggerSize: { classPropertyName: "triggerSize", publicName: "triggerSize", isSignal: true, isRequired: false, transformFunction: null }, triggerTransparent: { classPropertyName: "triggerTransparent", publicName: "triggerTransparent", isSignal: true, isRequired: false, transformFunction: null }, triggerVariant: { classPropertyName: "triggerVariant", publicName: "triggerVariant", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { open: "openChange" }, host: { classAttribute: "contents" }, viewQueries: [{ propertyName: "_trigger", first: true, predicate: ["trigger"], descendants: true, read: ElementRef, isSignal: true }], ngImport: i0, template: "<div\n hlmPopover\n [state]=\"_popoverState()\"\n [align]=\"align()\"\n [sideOffset]=\"sideOffset()\"\n [offsetX]=\"offsetX()\"\n [attachTo]=\"_trigger()\"\n (stateChanged)=\"onOpenChange($event)\"\n>\n @if (showTrigger()) {\n <yuw-button\n #trigger\n yuwPopoverTriggerButton\n [color]=\"triggerColor()\"\n [variant]=\"triggerVariant()\"\n [size]=\"triggerSize()\"\n [transparent]=\"triggerTransparent()\"\n [class]=\"triggerClass()\"\n >\n <ng-content select=\"[yuwPopoverTrigger]\" />\n </yuw-button>\n }\n\n <hlm-popover-content *hlmPopoverPortal [class]=\"panelClass()\">\n @if (title() || description()) {\n <div hlmPopoverHeader>\n @if (title()) {\n <p hlmPopoverTitle>{{ title() }}</p>\n }\n @if (description()) {\n <p hlmPopoverDescription>{{ description() }}</p>\n }\n </div>\n }\n\n <ng-content />\n </hlm-popover-content>\n</div>\n", dependencies: [{ kind: "directive", type: i1$f.HlmPopover, selector: "[hlmPopover],hlm-popover" }, { kind: "directive", type: i1$f.HlmPopoverContent, selector: "[hlmPopoverContent],hlm-popover-content" }, { kind: "directive", type: i1$f.HlmPopoverDescription, selector: "[hlmPopoverDescription]" }, { kind: "directive", type: i1$f.HlmPopoverHeader, selector: "[hlmPopoverHeader],hlm-popover-header" }, { kind: "directive", type: i1$f.HlmPopoverPortal, selector: "[hlmPopoverPortal]" }, { kind: "directive", type: i1$f.HlmPopoverTitle, selector: "[hlmPopoverTitle]" }, { 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: YuwPopoverTriggerDirective, selector: "yuw-button[yuwPopoverTriggerFor], yuw-button[yuwPopoverTriggerButton]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3729
+ selector: '[yuwTd]',
3730
+ hostDirectives: [HlmTd],
3731
+ }]
3732
+ }] });
3733
+ /** Table caption directive applied to native `<caption>`. */
3734
+ class YuwCaptionDirective {
3735
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwCaptionDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
3736
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwCaptionDirective, isStandalone: true, selector: "[yuwCaption]", hostDirectives: [{ directive: i1$i.HlmCaption }], ngImport: i0 }); }
3282
3737
  }
3283
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwPopoverComponent, decorators: [{
3284
- type: Component,
3285
- args: [{ selector: 'yuw-popover', imports: [...HlmPopoverImports, YuwButtonComponent, YuwPopoverTriggerDirective], host: {
3286
- class: 'contents',
3287
- }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n hlmPopover\n [state]=\"_popoverState()\"\n [align]=\"align()\"\n [sideOffset]=\"sideOffset()\"\n [offsetX]=\"offsetX()\"\n [attachTo]=\"_trigger()\"\n (stateChanged)=\"onOpenChange($event)\"\n>\n @if (showTrigger()) {\n <yuw-button\n #trigger\n yuwPopoverTriggerButton\n [color]=\"triggerColor()\"\n [variant]=\"triggerVariant()\"\n [size]=\"triggerSize()\"\n [transparent]=\"triggerTransparent()\"\n [class]=\"triggerClass()\"\n >\n <ng-content select=\"[yuwPopoverTrigger]\" />\n </yuw-button>\n }\n\n <hlm-popover-content *hlmPopoverPortal [class]=\"panelClass()\">\n @if (title() || description()) {\n <div hlmPopoverHeader>\n @if (title()) {\n <p hlmPopoverTitle>{{ title() }}</p>\n }\n @if (description()) {\n <p hlmPopoverDescription>{{ description() }}</p>\n }\n </div>\n }\n\n <ng-content />\n </hlm-popover-content>\n</div>\n" }]
3288
- }], propDecorators: { _trigger: [{ type: i0.ViewChild, args: ['trigger', { ...{ read: ElementRef }, isSignal: true }] }], align: [{ type: i0.Input, args: [{ isSignal: true, alias: "align", required: false }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }], offsetX: [{ type: i0.Input, args: [{ isSignal: true, alias: "offsetX", required: false }] }], open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }, { type: i0.Output, args: ["openChange"] }], panelClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "panelClass", required: false }] }], showTrigger: [{ type: i0.Input, args: [{ isSignal: true, alias: "showTrigger", required: false }] }], sideOffset: [{ type: i0.Input, args: [{ isSignal: true, alias: "sideOffset", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], 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 }] }], triggerTransparent: [{ type: i0.Input, args: [{ isSignal: true, alias: "triggerTransparent", required: false }] }], triggerVariant: [{ type: i0.Input, args: [{ isSignal: true, alias: "triggerVariant", required: false }] }] } });
3738
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwCaptionDirective, decorators: [{
3739
+ type: Directive,
3740
+ args: [{
3741
+ selector: '[yuwCaption]',
3742
+ hostDirectives: [HlmCaption],
3743
+ }]
3744
+ }] });
3745
+ /** Table custom pagination div content. */
3746
+ class YuwDatatablePaginationDirective {
3747
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwDatatablePaginationDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
3748
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwDatatablePaginationDirective, isStandalone: true, selector: "[yuwDatatablePagination]", ngImport: i0 }); }
3749
+ }
3750
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwDatatablePaginationDirective, decorators: [{
3751
+ type: Directive,
3752
+ args: [{
3753
+ selector: '[yuwDatatablePagination]',
3754
+ }]
3755
+ }] });
3756
+ /** Every table part, for a consumer's `imports`. */
3757
+ const YuwTableImports = [
3758
+ YuwTableContainerDirective,
3759
+ YuwTableDirective,
3760
+ YuwTHeadDirective,
3761
+ YuwTBodyDirective,
3762
+ YuwTFootDirective,
3763
+ YuwTrDirective,
3764
+ YuwThDirective,
3765
+ YuwTdDirective,
3766
+ YuwCaptionDirective,
3767
+ YuwDatatablePaginationDirective,
3768
+ ];
3289
3769
 
3290
3770
  const VIEW_MODES = ['list', 'block'];
3291
3771
  /**
@@ -3308,6 +3788,20 @@ const INSIDE_COLUMNS_SELECTOR = '.yuw-columns-trigger, hlm-popover-content, hlm-
3308
3788
  * A set `viewMode` adds the list/block switch. The selected entry drops its border so both entries
3309
3789
  * keep the same height, and the entry after it takes back the leading border the group strips, so the
3310
3790
  * seam stays drawn. Consumers get that for free and bind only `viewMode`.
3791
+ *
3792
+ * Inputs:
3793
+ * - `hiddenColumns`: Two-way (`[(hiddenColumns)]`) ids of the columns currently hidden. Default is `[]`.
3794
+ * - `hideableColumns`: Options of the columns the user may hide; the columns button renders only when set.
3795
+ * - `isMobile`: Required flag; below `md` the search collapses into a popover.
3796
+ * - `labels`: Required `YuwListToolbarLabels` with the consumer's text for the controls.
3797
+ * - `search`: Two-way (`[(search)]`) text of the search field, shared by the inline and popover fields. Default is `''`.
3798
+ * - `searchPlaceholder`: Placeholder of the search field; the search renders only when set.
3799
+ * - `showExport`: Renders the export button. Default is `false`.
3800
+ * - `viewMode`: Two-way (`[(viewMode)]`) `YuwViewMode` (`'list'` or `'block'`); the list/block switch renders only when set.
3801
+ *
3802
+ * Outputs:
3803
+ * - `exported`: Emits the `MouseEvent` of the export button click.
3804
+ * - `searched`: Emits the current search text on every keystroke and when it is cleared.
3311
3805
  */
3312
3806
  class YuwListToolbarActionsComponent {
3313
3807
  constructor() {
@@ -3388,142 +3882,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
3388
3882
  }], ctorParameters: () => [], propDecorators: { _columnsCombobox: [{ type: i0.ViewChild, args: [i0.forwardRef(() => YuwComboboxComponent), { isSignal: true }] }], hiddenColumns: [{ type: i0.Input, args: [{ isSignal: true, alias: "hiddenColumns", required: false }] }, { type: i0.Output, args: ["hiddenColumnsChange"] }], hideableColumns: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideableColumns", required: false }] }], isMobile: [{ type: i0.Input, args: [{ isSignal: true, alias: "isMobile", required: true }] }], labels: [{ type: i0.Input, args: [{ isSignal: true, alias: "labels", required: true }] }], 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 }] }], showExport: [{ type: i0.Input, args: [{ isSignal: true, alias: "showExport", required: false }] }], viewMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "viewMode", required: false }] }, { type: i0.Output, args: ["viewModeChange"] }], exported: [{ type: i0.Output, args: ["exported"] }], searched: [{ type: i0.Output, args: ["searched"] }] } });
3389
3883
 
3390
3884
  /**
3391
- * Makes a `<yuw-button>` the trigger of the surrounding `<yuw-sheet>`.
3392
- *
3393
- * Mirrors `YuwDialogTriggerDirective`: the helm trigger only matches a native `button`, so the brain
3394
- * directive is composed here instead, keeping `[hlmBtn]` inside `<yuw-button>`. `side` is forwarded
3395
- * so a trigger can override which edge the sheet appears from.
3396
- */
3397
- class YuwSheetTriggerDirective {
3398
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwSheetTriggerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
3399
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwSheetTriggerDirective, isStandalone: true, selector: "yuw-button[yuwSheetTriggerButton]", host: { attributes: { "data-slot": "sheet-trigger" } }, hostDirectives: [{ directive: i1$g.BrnSheetTrigger, inputs: ["id", "id", "side", "side", "type", "type"] }], ngImport: i0 }); }
3400
- }
3401
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwSheetTriggerDirective, decorators: [{
3402
- type: Directive,
3403
- args: [{
3404
- selector: 'yuw-button[yuwSheetTriggerButton]',
3405
- hostDirectives: [{ directive: BrnSheetTrigger, inputs: ['id', 'side', 'type'] }],
3406
- host: { 'data-slot': 'sheet-trigger' },
3407
- }]
3408
- }] });
3409
- /** Closes the surrounding `<yuw-sheet>` when the host `<yuw-button>` is activated. */
3410
- class YuwSheetCloseDirective {
3411
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwSheetCloseDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
3412
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwSheetCloseDirective, isStandalone: true, selector: "yuw-button[yuwSheetClose]", host: { attributes: { "data-slot": "sheet-close" } }, hostDirectives: [{ directive: i1$g.BrnSheetClose }], ngImport: i0 }); }
3413
- }
3414
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwSheetCloseDirective, decorators: [{
3415
- type: Directive,
3416
- args: [{
3417
- selector: 'yuw-button[yuwSheetClose]',
3418
- hostDirectives: [BrnSheetClose],
3419
- host: { 'data-slot': 'sheet-close' },
3420
- }]
3421
- }] });
3422
-
3423
- /**
3424
- * Marks an element as the sheet's footer content, projected into the footer slot.
3425
- * Its presence is also what makes the footer render at all — without it the sheet
3426
- * shows no empty footer strip.
3427
- */
3428
- class YuwSheetFooterDirective {
3429
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwSheetFooterDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
3430
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwSheetFooterDirective, isStandalone: true, selector: "[yuwSheetFooter]", ngImport: i0 }); }
3431
- }
3432
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwSheetFooterDirective, decorators: [{
3433
- type: Directive,
3434
- args: [{
3435
- selector: '[yuwSheetFooter]',
3436
- }]
3437
- }] });
3438
-
3439
- const YUW_SHEET_OVERLAY_BASE_CLASS = 'data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 isolate bg-black/10 duration-100 supports-backdrop-filter:backdrop-blur-xs';
3440
- /**
3441
- * Slide-in sheet overlay panel component for side drawers, dialogs, and detail views.
3442
- *
3443
- * Accessibility: provide either `title` or `ariaLabel` — a modal panel without an accessible name
3444
- * is announced as an anonymous dialog by screen readers.
3445
- *
3446
- * Inputs / Models:
3447
- * - `open`: Two-way open/closed state (`boolean`). Drive directly via `[(open)]` to open/close programmatically.
3448
- * - `showTrigger`: Whether to render the trigger button. Set `false` when opening only via `[(open)]`.
3449
- * - `side`: Edge of the screen the panel slides in from (`'top'`, `'bottom'`, `'left'`, `'right'`). Default is `'right'`.
3450
- * - `title`: Optional header title text. User-facing text the consuming app is responsible for translating.
3451
- * - `description`: Optional header description text. User-facing text the consuming app is responsible for translating.
3452
- * - `ariaLabel`: Accessible name for the sheet when no visible `title` is rendered. User-facing
3453
- * text the consuming app is responsible for translating.
3454
- * - `closeLabel`: Accessible label of the corner close (×) button. When set, the close button
3455
- * renders and screen readers read this label; when absent there is no close button. User-facing
3456
- * text the consuming app is responsible for translating.
3457
- * - `panelClass`: Extra classes merged onto the sheet panel (e.g. `sm:max-w-lg` to widen it).
3458
- * They win over the library defaults via `twMerge`. Note `twMerge` resolves per variant group, so a
3459
- * plain utility does not displace a variant-prefixed default — to override `data-[side=left]:w-3/4`
3460
- * the class has to be `data-[side=left]:w-64`, not `w-64`.
3461
- * - `overlayClass`: Extra classes for the backdrop, for a sheet that should not dim the whole
3462
- * viewport. Applied through `setOverlayClass` rather than a template binding: the backdrop lives in
3463
- * the overlay too, and the helm's own class always wins the `class` input it exposes.
3464
- * - `scrollStrategy`: What happens to page scroll while open. Defaults to the brain's blocking
3465
- * strategy; pass `'reposition'` for a panel that should leave the page scrollable.
3466
- * - `ariaModal`: Whether the sheet claims the rest of the page is hidden. Leave `true` for a real
3467
- * modal; set `false` when content outside stays visible and usable, so the claim stays honest.
3468
- * - `closeOnOutsidePointerEvents`: Whether a pointer press outside the panel closes it, backdrop
3469
- * clicks included. Default is `true`, matching the brain from `@spartan-ng/brain` 1.3.4 on; pass
3470
- * `false` for a panel that must be dismissed deliberately.
3471
- * - `triggerVariant`: Button style variant for the trigger button.
3472
- * - `triggerSize`: Button size for the trigger button.
3885
+ * Declares the content of a single tab entry. Apply it to an `<ng-template>` and pass the id of the
3886
+ * entry it belongs to; the template is exposed through `templateRef` for the host to render.
3473
3887
  *
3474
- * Usage:
3475
- * ```html
3476
- * <yuw-sheet [(open)]="isOpen" side="right" title="Edit Profile" description="Update your account details." closeLabel="Close">
3477
- * <ng-container yuwSheetTrigger>Edit Profile</ng-container>
3478
- *
3479
- * <p>Sheet form content goes here.</p>
3480
- *
3481
- * <div yuwSheetFooter>
3482
- * <yuw-button (clicked)="save()">Save Changes</yuw-button>
3483
- * </div>
3484
- * </yuw-sheet>
3485
- * ```
3888
+ * Inputs:
3889
+ * - `yuwTabContent`: Required string; id of the tab entry this template is the content of.
3486
3890
  */
3487
- class YuwSheetComponent {
3488
- constructor() {
3489
- this.hasFooter = contentChild(YuwSheetFooterDirective, ...(ngDevMode ? [{ debugName: "hasFooter" }] : /* istanbul ignore next */ []));
3490
- this.sheet = viewChild.required(HlmSheet);
3491
- this.ariaLabel = input(undefined, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
3492
- this.ariaModal = input(true, { ...(ngDevMode ? { debugName: "ariaModal" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
3493
- this.closeLabel = input(undefined, ...(ngDevMode ? [{ debugName: "closeLabel" }] : /* istanbul ignore next */ []));
3494
- this.closeOnOutsidePointerEvents = input(true, { ...(ngDevMode ? { debugName: "closeOnOutsidePointerEvents" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
3495
- this.description = input(undefined, ...(ngDevMode ? [{ debugName: "description" }] : /* istanbul ignore next */ []));
3496
- this.open = model(false, ...(ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []));
3497
- this.overlayClass = input(undefined, ...(ngDevMode ? [{ debugName: "overlayClass" }] : /* istanbul ignore next */ []));
3498
- this.panelClass = input(undefined, ...(ngDevMode ? [{ debugName: "panelClass" }] : /* istanbul ignore next */ []));
3499
- this.scrollStrategy = input(null, ...(ngDevMode ? [{ debugName: "scrollStrategy" }] : /* istanbul ignore next */ []));
3500
- this.showTrigger = input(true, { ...(ngDevMode ? { debugName: "showTrigger" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
3501
- this.side = input('right', ...(ngDevMode ? [{ debugName: "side" }] : /* istanbul ignore next */ []));
3502
- this.title = input(undefined, ...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
3503
- this.triggerSize = input('default', ...(ngDevMode ? [{ debugName: "triggerSize" }] : /* istanbul ignore next */ []));
3504
- this.triggerVariant = input('outline', ...(ngDevMode ? [{ debugName: "triggerVariant" }] : /* istanbul ignore next */ []));
3505
- this._sheetState = computed(() => (this.open() ? 'open' : 'closed'), ...(ngDevMode ? [{ debugName: "_sheetState" }] : /* istanbul ignore next */ []));
3506
- effect(() => {
3507
- const overlayClass = this.overlayClass();
3508
- if (overlayClass === undefined)
3509
- return;
3510
- this.sheet().setOverlayClass(`${YUW_SHEET_OVERLAY_BASE_CLASS} ${overlayClass}`);
3511
- });
3512
- }
3513
- onStateChanged(state) {
3514
- this.open.set(state === 'open');
3515
- }
3516
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwSheetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3517
- 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 }, 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 }], 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 <div class=\"flex-1 overflow-y-auto px-4\">\n <ng-content />\n </div>\n\n @if (hasFooter()) {\n <div hlmSheetFooter>\n <ng-content select=\"[yuwSheetFooter]\" />\n </div>\n }\n\n @if (closeLabel()) {\n <div class=\"absolute inset-e-3 top-3\">\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 </div>\n }\n </hlm-sheet-content>\n</hlm-sheet>\n", dependencies: [{ kind: "component", type: i1$h.HlmSheet, selector: "hlm-sheet", exportAs: ["hlmSheet"] }, { kind: "component", type: i1$h.HlmSheetContent, selector: "hlm-sheet-content", inputs: ["showCloseButton"] }, { kind: "directive", type: i1$h.HlmSheetDescription, selector: "[hlmSheetDescription]" }, { kind: "directive", type: i1$h.HlmSheetFooter, selector: "[hlmSheetFooter],hlm-sheet-footer" }, { kind: "directive", type: i1$h.HlmSheetHeader, selector: "[hlmSheetHeader],hlm-sheet-header" }, { kind: "directive", type: i1$h.HlmSheetPortal, selector: "[hlmSheetPortal]" }, { kind: "directive", type: i1$h.HlmSheetTitle, selector: "[hlmSheetTitle]" }, { 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 }); }
3518
- }
3519
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwSheetComponent, decorators: [{
3520
- type: Component,
3521
- args: [{ selector: 'yuw-sheet', imports: [...HlmSheetImports, YuwButtonComponent, YuwSheetTriggerDirective, YuwSheetCloseDirective, NgIcon], providers: [provideIcons({ lucideX })], host: {
3522
- class: 'contents',
3523
- }, 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 <div class=\"flex-1 overflow-y-auto px-4\">\n <ng-content />\n </div>\n\n @if (hasFooter()) {\n <div hlmSheetFooter>\n <ng-content select=\"[yuwSheetFooter]\" />\n </div>\n }\n\n @if (closeLabel()) {\n <div class=\"absolute inset-e-3 top-3\">\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 </div>\n }\n </hlm-sheet-content>\n</hlm-sheet>\n" }]
3524
- }], ctorParameters: () => [], propDecorators: { hasFooter: [{ type: i0.ContentChild, args: [i0.forwardRef(() => YuwSheetFooterDirective), { 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 }] }], 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 }] }] } });
3525
- const YuwSheetImports = [YuwSheetComponent, YuwSheetFooterDirective];
3526
-
3527
3891
  class YuwTabContentDirective {
3528
3892
  constructor() {
3529
3893
  this.templateRef = inject(TemplateRef);
@@ -3547,6 +3911,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
3547
3911
  * ```html
3548
3912
  * <ng-template yuwTabPanel="billing">Contenido de facturación</ng-template>
3549
3913
  * ```
3914
+ *
3915
+ * Inputs:
3916
+ * - `yuwTabPanel`: Required string; id of the tab, matching an entry in the `tabs` input, that this panel renders for.
3550
3917
  */
3551
3918
  class YuwTabPanelDirective {
3552
3919
  constructor() {
@@ -3607,6 +3974,7 @@ const yuwTabsSizeVariants = cva('', {
3607
3974
  * - `orientation`: Layout direction (`'horizontal'`, `'vertical'`). Default is `'horizontal'`.
3608
3975
  * - `activationMode`: How keyboard focus activates tabs (`'automatic'` activates on focus,
3609
3976
  * `'manual'` requires Enter/Space). Default is `'automatic'`.
3977
+ * - `class`: Extra classes merged onto the tab list, last, so they win over the component's own classes.
3610
3978
  *
3611
3979
  * Usage:
3612
3980
  * ```html
@@ -3643,7 +4011,7 @@ class YuwTabsComponent {
3643
4011
  this.activeTab.set(tabId);
3644
4012
  }
3645
4013
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwTabsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3646
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: YuwTabsComponent, isStandalone: true, selector: "yuw-tabs", inputs: { activationMode: { classPropertyName: "activationMode", publicName: "activationMode", isSignal: true, isRequired: false, transformFunction: null }, activeTab: { classPropertyName: "activeTab", publicName: "activeTab", isSignal: true, isRequired: true, transformFunction: null }, orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, tabs: { classPropertyName: "tabs", publicName: "tabs", isSignal: true, isRequired: true, transformFunction: null }, userClass: { classPropertyName: "userClass", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { activeTab: "activeTabChange" }, host: { classAttribute: "contents" }, queries: [{ propertyName: "_contents", predicate: YuwTabContentDirective, isSignal: true }, { propertyName: "panels", predicate: YuwTabPanelDirective, isSignal: true }], ngImport: i0, template: "<hlm-tabs\n [tab]=\"activeTab()\"\n [orientation]=\"orientation()\"\n [activationMode]=\"activationMode()\"\n (tabActivated)=\"onTabActivated($event)\"\n>\n <hlm-tabs-list [variant]=\"variant()\" [class]=\"_listClass()\">\n @for (tab of _resolved(); track tab.id) {\n <button [hlmTabsTrigger]=\"tab.id\" [disabled]=\"tab.disabled ?? false\">\n @if (tab.template) {\n <ng-container [ngTemplateOutlet]=\"tab.template\" />\n } @else {\n {{ tab.label }}\n }\n </button>\n }\n </hlm-tabs-list>\n\n @for (panel of panels(); track panel.tabId()) {\n <div [hlmTabsContent]=\"panel.tabId()\">\n <ng-template hlmTabsContentLazy>\n <ng-container [ngTemplateOutlet]=\"panel.templateRef\" />\n </ng-template>\n </div>\n }\n</hlm-tabs>\n", dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1$i.HlmTabs, selector: "[hlmTabs],hlm-tabs", inputs: ["tab"] }, { kind: "directive", type: i1$i.HlmTabsList, selector: "[hlmTabsList],hlm-tabs-list", inputs: ["variant"] }, { kind: "directive", type: i1$i.HlmTabsTrigger, selector: "[hlmTabsTrigger]", inputs: ["hlmTabsTrigger"] }, { kind: "directive", type: i1$i.HlmTabsContent, selector: "[hlmTabsContent]", inputs: ["hlmTabsContent"] }, { kind: "directive", type: i1$i.HlmTabsContentLazy, selector: "ng-template[hlmTabsContentLazy]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
4014
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: YuwTabsComponent, isStandalone: true, selector: "yuw-tabs", inputs: { activationMode: { classPropertyName: "activationMode", publicName: "activationMode", isSignal: true, isRequired: false, transformFunction: null }, activeTab: { classPropertyName: "activeTab", publicName: "activeTab", isSignal: true, isRequired: true, transformFunction: null }, orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, tabs: { classPropertyName: "tabs", publicName: "tabs", isSignal: true, isRequired: true, transformFunction: null }, userClass: { classPropertyName: "userClass", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { activeTab: "activeTabChange" }, host: { classAttribute: "contents" }, queries: [{ propertyName: "_contents", predicate: YuwTabContentDirective, isSignal: true }, { propertyName: "panels", predicate: YuwTabPanelDirective, isSignal: true }], ngImport: i0, template: "<hlm-tabs\n [tab]=\"activeTab()\"\n [orientation]=\"orientation()\"\n [activationMode]=\"activationMode()\"\n (tabActivated)=\"onTabActivated($event)\"\n>\n <hlm-tabs-list [variant]=\"variant()\" [class]=\"_listClass()\">\n @for (tab of _resolved(); track tab.id) {\n <button [hlmTabsTrigger]=\"tab.id\" [disabled]=\"tab.disabled ?? false\">\n @if (tab.template) {\n <ng-container [ngTemplateOutlet]=\"tab.template\" />\n } @else {\n {{ tab.label }}\n }\n </button>\n }\n </hlm-tabs-list>\n\n @for (panel of panels(); track panel.tabId()) {\n <div [hlmTabsContent]=\"panel.tabId()\">\n <ng-template hlmTabsContentLazy>\n <ng-container [ngTemplateOutlet]=\"panel.templateRef\" />\n </ng-template>\n </div>\n }\n</hlm-tabs>\n", dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1$j.HlmTabs, selector: "[hlmTabs],hlm-tabs", inputs: ["tab"] }, { kind: "directive", type: i1$j.HlmTabsList, selector: "[hlmTabsList],hlm-tabs-list", inputs: ["variant"] }, { kind: "directive", type: i1$j.HlmTabsTrigger, selector: "[hlmTabsTrigger]", inputs: ["hlmTabsTrigger"] }, { kind: "directive", type: i1$j.HlmTabsContent, selector: "[hlmTabsContent]", inputs: ["hlmTabsContent"] }, { kind: "directive", type: i1$j.HlmTabsContentLazy, selector: "ng-template[hlmTabsContentLazy]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3647
4015
  }
3648
4016
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwTabsComponent, decorators: [{
3649
4017
  type: Component,
@@ -3746,6 +4114,17 @@ function filterSetFormTitle(mode, labels) {
3746
4114
  * name field is seeded from `name` and takes focus once rendered. `titleHidden` drops the heading
3747
4115
  * when the host already shows it. `confirmed` emits the trimmed
3748
4116
  * name; a delete confirmation emits the name it was opened with, so the host decides from `mode`.
4117
+ *
4118
+ * Inputs:
4119
+ * - `labels`: Required `YuwFilterSetLabels` with the consumer's text for the titles, the field, the delete message and the buttons.
4120
+ * - `mode`: Required `'save'`, `'rename'` or `'delete'`; picks the heading and whether the name field or the delete message shows.
4121
+ * - `name`: Name the field is seeded with, and the name of the set being deleted. Default is `''`.
4122
+ * - `titleHidden`: Drops the heading when the host already shows it. Default is `false`.
4123
+ *
4124
+ * Outputs:
4125
+ * - `cancelled`: Emits when the user backs out of the form without confirming.
4126
+ * - `confirmed`: Emits the trimmed name, or the opening name when deleting.
4127
+ * - `deleteRequested`: Emits when the delete shortcut of the rename mode is pressed.
3749
4128
  */
3750
4129
  class YuwListToolbarFilterSetFormComponent {
3751
4130
  constructor() {
@@ -3791,6 +4170,22 @@ const STRETCHED_CELL = 'min-w-0 flex-1 [&>yuw-button]:flex [&>yuw-button]:w-full
3791
4170
  * option emits `picked` and the host applies it. `titleHidden` drops the heading when the host
3792
4171
  * already shows it. `stretchActions` makes edit and delete share the row 50/50 with no gap; without
3793
4172
  * it they keep their natural width. Button texts are consumer data, so they are cropped, not wrapped.
4173
+ *
4174
+ * Inputs:
4175
+ * - `canEdit`: Offers the edit and delete actions for the set matching the applied selection. Default is `false`.
4176
+ * - `canSave`: Offers the action that saves the applied selection as a new set. Default is `false`.
4177
+ * - `labels`: Required `YuwFilterSetLabels` with the consumer's text for the select and the actions.
4178
+ * - `selectedId`: Id of the set shown as selected; `NO_FILTER_SET` means none. Default is `NO_FILTER_SET`.
4179
+ * - `sets`: Required saved sets listed in the select.
4180
+ * - `stretchActions`: Makes the edit and delete buttons share the row 50/50 with no gap. Default is `false`.
4181
+ * - `titleHidden`: Drops the heading when the host already shows it. Default is `false`.
4182
+ *
4183
+ * Outputs:
4184
+ * - `deleteRequested`: Emits when the delete action is pressed.
4185
+ * - `editRequested`: Emits when the edit action is pressed.
4186
+ * - `itemEditRequested`: Emits the id of the set whose three-dots button was pressed.
4187
+ * - `picked`: Emits the id of the chosen option, or `NO_FILTER_SET` for none.
4188
+ * - `saveRequested`: Emits when the save action is pressed.
3794
4189
  */
3795
4190
  class YuwListToolbarFilterSetsComponent {
3796
4191
  constructor() {
@@ -3856,6 +4251,15 @@ const FORM_VIEWS = new Set(['save', 'rename', 'delete']);
3856
4251
  * opened from a button, not when it closes, so it does not flash back while closing. A change of
3857
4252
  * layout closes the panel, since a popover opened from a sheet has no anchor to position against.
3858
4253
  * Persisting is the consumer's job: this component only emits `setSaved`, `setRenamed`, `setDeleted`.
4254
+ *
4255
+ * Inputs:
4256
+ * - `disabled`: Disables every button of the group. Default is `false`.
4257
+ * - `groups`: Required filter groups the editor offers, one pane or tab each.
4258
+ * - `idleColor`: Required tone of the buttons while no filter is applied.
4259
+ * - `isMobile`: Required flag; true opens the panel as a bottom sheet, false as a popover.
4260
+ * - `labels`: Required `YuwListToolbarFilterLabels` with the consumer's text for the panel and its buttons.
4261
+ * - `selection`: Two-way (`[(selection)]`) applied filter selection. Default is `{}`.
4262
+ * - `sets`: Saved filter sets; the sets star renders only when given together with `labels.sets`.
3859
4263
  */
3860
4264
  class YuwListToolbarFiltersComponent {
3861
4265
  constructor() {
@@ -4041,6 +4445,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
4041
4445
  * two-way to it (`viewModeChange` is the click listener); its names come from `labels.viewMode`. Saved filter sets need `filterSets` and `labels.filters.sets`;
4042
4446
  * the toolbar emits `setSaved`, `setRenamed` and `setDeleted` and the consumer persists them. `labels` holds every text and the consumer translates it;
4043
4447
  * `idleColor` is the filter trigger tone while nothing is applied.
4448
+ *
4449
+ * Inputs:
4450
+ * - `filterGroups`: Filter groups the editor offers; the filter control renders only when set.
4451
+ * - `filterSets`: Saved filter sets; together with `labels.filters.sets` it enables the sets star.
4452
+ * - `filtersDisabled`: Disables the filter buttons. Default is `false`.
4453
+ * - `hiddenColumns`: Two-way (`[(hiddenColumns)]`) ids of the columns currently hidden. Default is `[]`.
4454
+ * - `hideableColumns`: Options of the columns the user may hide; the columns button renders only when set.
4455
+ * - `idleColor`: `YuwColorDto` tone of the filter trigger while nothing is applied. Default is `'neutral'`.
4456
+ * - `labels`: Required `YuwListToolbarLabels` with the consumer's translated text for every control.
4457
+ * - `search`: Two-way (`[(search)]`) text of the search field. Default is `''`.
4458
+ * - `searchPlaceholder`: Placeholder of the search field; the search renders only when set.
4459
+ * - `selection`: Two-way (`[(selection)]`) applied filter selection, values keyed by group id. Default is `{}`.
4460
+ * - `showExport`: Renders the export button. Default is `false`.
4461
+ * - `viewMode`: Two-way (`[(viewMode)]`) `YuwViewMode` (`'list'` or `'block'`); the list/block switch renders only when set.
4462
+ *
4463
+ * Outputs:
4464
+ * - `exported`: Emits the `MouseEvent` of the export button click.
4465
+ * - `searched`: Emits the current search text on every keystroke and when it is cleared.
4044
4466
  */
4045
4467
  class YuwListToolbarComponent {
4046
4468
  constructor() {
@@ -4306,7 +4728,6 @@ class YuwDatatableComponent {
4306
4728
  this.selectable = input(false, { ...(ngDevMode ? { debugName: "selectable" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
4307
4729
  this.sortable = input(false, { ...(ngDevMode ? { debugName: "sortable" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
4308
4730
  this.sorting = model([], ...(ngDevMode ? [{ debugName: "sorting" }] : /* istanbul ignore next */ []));
4309
- this.summary = input(false, { ...(ngDevMode ? { debugName: "summary" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
4310
4731
  this.tableClass = input(undefined, ...(ngDevMode ? [{ debugName: "tableClass" }] : /* istanbul ignore next */ []));
4311
4732
  this.totalItems = input(undefined, ...(ngDevMode ? [{ debugName: "totalItems" }] : /* istanbul ignore next */ []));
4312
4733
  this.rowClicked = output();
@@ -4419,20 +4840,30 @@ class YuwDatatableComponent {
4419
4840
  this.rowClicked.emit(row);
4420
4841
  }
4421
4842
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwDatatableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4422
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: YuwDatatableComponent, isStandalone: true, selector: "yuw-datatable", inputs: { appearance: { classPropertyName: "appearance", publicName: "appearance", isSignal: true, isRequired: false, transformFunction: null }, caption: { classPropertyName: "caption", publicName: "caption", isSignal: true, isRequired: false, transformFunction: null }, cellClass: { classPropertyName: "cellClass", publicName: "cellClass", isSignal: true, isRequired: false, transformFunction: null }, columnFilters: { classPropertyName: "columnFilters", publicName: "columnFilters", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, columnVisibility: { classPropertyName: "columnVisibility", publicName: "columnVisibility", isSignal: true, isRequired: false, transformFunction: null }, data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, emptyText: { classPropertyName: "emptyText", publicName: "emptyText", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, loadingRows: { classPropertyName: "loadingRows", publicName: "loadingRows", isSignal: true, isRequired: false, transformFunction: null }, nextPageLabel: { classPropertyName: "nextPageLabel", publicName: "nextPageLabel", isSignal: true, isRequired: true, transformFunction: null }, paginated: { classPropertyName: "paginated", publicName: "paginated", isSignal: true, isRequired: false, transformFunction: null }, pagination: { classPropertyName: "pagination", publicName: "pagination", isSignal: true, isRequired: false, transformFunction: null }, paginationAriaLabel: { classPropertyName: "paginationAriaLabel", publicName: "paginationAriaLabel", isSignal: true, isRequired: true, transformFunction: null }, paginationEllipsisSrText: { classPropertyName: "paginationEllipsisSrText", publicName: "paginationEllipsisSrText", isSignal: true, isRequired: true, transformFunction: null }, previousPageLabel: { classPropertyName: "previousPageLabel", publicName: "previousPageLabel", isSignal: true, isRequired: true, transformFunction: null }, rowClass: { classPropertyName: "rowClass", publicName: "rowClass", isSignal: true, isRequired: false, transformFunction: null }, rowSelection: { classPropertyName: "rowSelection", publicName: "rowSelection", isSignal: true, isRequired: false, transformFunction: null }, selectable: { classPropertyName: "selectable", publicName: "selectable", isSignal: true, isRequired: false, transformFunction: null }, sortable: { classPropertyName: "sortable", publicName: "sortable", isSignal: true, isRequired: false, transformFunction: null }, sorting: { classPropertyName: "sorting", publicName: "sorting", isSignal: true, isRequired: false, transformFunction: null }, summary: { classPropertyName: "summary", publicName: "summary", isSignal: true, isRequired: false, transformFunction: null }, tableClass: { classPropertyName: "tableClass", publicName: "tableClass", isSignal: true, isRequired: false, transformFunction: null }, totalItems: { classPropertyName: "totalItems", publicName: "totalItems", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { columnFilters: "columnFiltersChange", columnVisibility: "columnVisibilityChange", pagination: "paginationChange", rowSelection: "rowSelectionChange", sorting: "sortingChange", rowClicked: "rowClicked", selectedRowsChange: "selectedRowsChange" }, host: { classAttribute: "contents" }, providers: [provideIcons({ lucideChevronDown, lucideChevronUp, lucideChevronsUpDown })], queries: [{ propertyName: "customPagination", first: true, predicate: YuwDatatablePaginationDirective, descendants: true, isSignal: true }], ngImport: i0, template: "<div yuwTableContainer [class]=\"_containerClass()\">\n <table yuwTable [class]=\"_tableClass()\">\n @if (caption()) {\n <caption yuwCaption>{{ caption() }}</caption>\n }\n\n <thead yuwTHead [class]=\"_headClass()\">\n @for (headerGroup of table.getHeaderGroups(); track headerGroup.id) {\n <tr yuwTr [class]=\"_rowClass()\">\n @for (header of headerGroup.headers; track header.id) {\n @let sorted = header.column.getIsSorted();\n @let headerClasses = _cellClasses().get(header.column.id);\n <th\n yuwTh\n scope=\"col\"\n [attr.colspan]=\"header.colSpan\"\n [attr.aria-sort]=\"sorted ? _ariaSort[sorted] : null\"\n [class]=\"headerClasses?.header\"\n >\n @if (!header.isPlaceholder) {\n @if (sortable() && header.column.getCanSort()) {\n <button\n type=\"button\"\n class=\"inline-flex items-center gap-1 select-none hover:text-foreground/80\"\n (click)=\"header.column.toggleSorting()\"\n >\n <ng-container\n *flexRender=\"header.column.columnDef.header; props: header.getContext(); let rendered\"\n >\n {{ rendered }}\n </ng-container>\n\n <ng-icon [name]=\"_sortIcon[sorted || 'none']\" class=\"shrink-0 text-xs\" aria-hidden=\"true\" />\n </button>\n } @else {\n <ng-container *flexRender=\"header.column.columnDef.header; props: header.getContext(); let rendered\">\n {{ rendered }}\n </ng-container>\n }\n }\n </th>\n }\n </tr>\n }\n </thead>\n\n <tbody yuwTBody>\n @if (loading()) {\n @for (row of _skeletonRows(); track row) {\n <tr yuwTr [class]=\"_rowClass()\">\n @for (column of table.getVisibleLeafColumns(); track column.id) {\n <td yuwTd [class]=\"_cellClasses().get(column.id)?.cell\">\n <span yuwSkeleton class=\"block h-4 w-full\"></span>\n </td>\n }\n </tr>\n }\n } @else if (_isEmpty()) {\n <tr yuwTr [class]=\"_rowClass()\">\n <td yuwTd [attr.colspan]=\"_columnCount()\" class=\"h-24 text-center text-muted-foreground\">\n {{ emptyText() ?? '' }}\n </td>\n </tr>\n } @else {\n @for (row of table.getRowModel().rows; track row.id) {\n <tr\n yuwTr\n [class]=\"_rowClasses().get(row.id)\"\n [attr.data-state]=\"row.getIsSelected() ? 'selected' : null\"\n role=\"button\"\n tabindex=\"0\"\n (click)=\"onRowClick(row.original)\"\n (keydown)=\"onRowKeydown($event, row.original)\"\n >\n @for (cell of row.getVisibleCells(); track cell.id) {\n <td yuwTd [class]=\"_cellClasses().get(cell.column.id)?.cell\">\n <ng-container *flexRender=\"cell.column.columnDef.cell; props: cell.getContext(); let rendered\">\n {{ rendered }}\n </ng-container>\n </td>\n }\n </tr>\n }\n }\n </tbody>\n </table>\n</div>\n\n@if (paginated()) {\n <div class=\"flex items-center flex-wrap justify-end gap-4 py-3 px-1 max-lg:justify-center\">\n @if (customPagination()) {\n <ng-content select=\"[yuwDatatablePagination]\" />\n }\n <yuw-pagination\n [page]=\"currentPage()\"\n (pageChange)=\"onPageChange($event)\"\n [totalPages]=\"table.getPageCount() || 1\"\n [previousLabel]=\"previousPageLabel()\"\n [nextLabel]=\"nextPageLabel()\"\n [ellipsisSrText]=\"paginationEllipsisSrText()\"\n [ariaLabel]=\"paginationAriaLabel()\"\n color=\"neutral\"\n size=\"icon-sm\"\n class=\"flex\"\n />\n </div>\n}\n", dependencies: [{ kind: "directive", type: YuwTableContainerDirective, selector: "[yuwTableContainer]" }, { kind: "directive", type: YuwTableDirective, selector: "[yuwTable]" }, { kind: "directive", type: YuwTHeadDirective, selector: "[yuwTHead]" }, { kind: "directive", type: YuwTBodyDirective, selector: "[yuwTBody]" }, { kind: "directive", type: YuwTrDirective, selector: "[yuwTr]" }, { kind: "directive", type: YuwThDirective, selector: "[yuwTh]" }, { kind: "directive", type: YuwTdDirective, selector: "[yuwTd]" }, { kind: "directive", type: YuwCaptionDirective, selector: "[yuwCaption]" }, { kind: "component", type: YuwPaginationComponent, selector: "yuw-pagination", inputs: ["ariaLabel", "color", "ellipsisSrText", "nextLabel", "page", "previousLabel", "size", "totalPages"], outputs: ["pageChange"] }, { kind: "directive", type: YuwSkeletonDirective, selector: "[yuwSkeleton]" }, { kind: "directive", type: FlexRenderDirective, selector: "ng-template[flexRender]", inputs: ["flexRender", "flexRenderProps", "flexRenderInjector"] }, { kind: "component", type: NgIcon, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
4843
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: YuwDatatableComponent, isStandalone: true, selector: "yuw-datatable", inputs: { appearance: { classPropertyName: "appearance", publicName: "appearance", isSignal: true, isRequired: false, transformFunction: null }, caption: { classPropertyName: "caption", publicName: "caption", isSignal: true, isRequired: false, transformFunction: null }, cellClass: { classPropertyName: "cellClass", publicName: "cellClass", isSignal: true, isRequired: false, transformFunction: null }, columnFilters: { classPropertyName: "columnFilters", publicName: "columnFilters", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, columnVisibility: { classPropertyName: "columnVisibility", publicName: "columnVisibility", isSignal: true, isRequired: false, transformFunction: null }, data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, emptyText: { classPropertyName: "emptyText", publicName: "emptyText", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, loadingRows: { classPropertyName: "loadingRows", publicName: "loadingRows", isSignal: true, isRequired: false, transformFunction: null }, nextPageLabel: { classPropertyName: "nextPageLabel", publicName: "nextPageLabel", isSignal: true, isRequired: true, transformFunction: null }, paginated: { classPropertyName: "paginated", publicName: "paginated", isSignal: true, isRequired: false, transformFunction: null }, pagination: { classPropertyName: "pagination", publicName: "pagination", isSignal: true, isRequired: false, transformFunction: null }, paginationAriaLabel: { classPropertyName: "paginationAriaLabel", publicName: "paginationAriaLabel", isSignal: true, isRequired: true, transformFunction: null }, paginationEllipsisSrText: { classPropertyName: "paginationEllipsisSrText", publicName: "paginationEllipsisSrText", isSignal: true, isRequired: true, transformFunction: null }, previousPageLabel: { classPropertyName: "previousPageLabel", publicName: "previousPageLabel", isSignal: true, isRequired: true, transformFunction: null }, rowClass: { classPropertyName: "rowClass", publicName: "rowClass", isSignal: true, isRequired: false, transformFunction: null }, rowSelection: { classPropertyName: "rowSelection", publicName: "rowSelection", isSignal: true, isRequired: false, transformFunction: null }, selectable: { classPropertyName: "selectable", publicName: "selectable", isSignal: true, isRequired: false, transformFunction: null }, sortable: { classPropertyName: "sortable", publicName: "sortable", isSignal: true, isRequired: false, transformFunction: null }, sorting: { classPropertyName: "sorting", publicName: "sorting", isSignal: true, isRequired: false, transformFunction: null }, tableClass: { classPropertyName: "tableClass", publicName: "tableClass", isSignal: true, isRequired: false, transformFunction: null }, totalItems: { classPropertyName: "totalItems", publicName: "totalItems", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { columnFilters: "columnFiltersChange", columnVisibility: "columnVisibilityChange", pagination: "paginationChange", rowSelection: "rowSelectionChange", sorting: "sortingChange", rowClicked: "rowClicked", selectedRowsChange: "selectedRowsChange" }, host: { classAttribute: "contents" }, providers: [provideIcons({ lucideChevronDown, lucideChevronUp, lucideChevronsUpDown })], queries: [{ propertyName: "customPagination", first: true, predicate: YuwDatatablePaginationDirective, descendants: true, isSignal: true }], ngImport: i0, template: "<div yuwTableContainer [class]=\"_containerClass()\">\n <table yuwTable [class]=\"_tableClass()\">\n @if (caption()) {\n <caption yuwCaption>{{ caption() }}</caption>\n }\n\n <thead yuwTHead [class]=\"_headClass()\">\n @for (headerGroup of table.getHeaderGroups(); track headerGroup.id) {\n <tr yuwTr [class]=\"_rowClass()\">\n @for (header of headerGroup.headers; track header.id) {\n @let sorted = header.column.getIsSorted();\n @let headerClasses = _cellClasses().get(header.column.id);\n <th\n yuwTh\n scope=\"col\"\n [attr.colspan]=\"header.colSpan\"\n [attr.aria-sort]=\"sorted ? _ariaSort[sorted] : null\"\n [class]=\"headerClasses?.header\"\n >\n @if (!header.isPlaceholder) {\n @if (sortable() && header.column.getCanSort()) {\n <button\n type=\"button\"\n class=\"inline-flex items-center gap-1 select-none hover:text-foreground/80\"\n (click)=\"header.column.toggleSorting()\"\n >\n <ng-container\n *flexRender=\"header.column.columnDef.header; props: header.getContext(); let rendered\"\n >\n {{ rendered }}\n </ng-container>\n\n <ng-icon [name]=\"_sortIcon[sorted || 'none']\" class=\"shrink-0 text-xs\" aria-hidden=\"true\" />\n </button>\n } @else {\n <ng-container *flexRender=\"header.column.columnDef.header; props: header.getContext(); let rendered\">\n {{ rendered }}\n </ng-container>\n }\n }\n </th>\n }\n </tr>\n }\n </thead>\n\n <tbody yuwTBody>\n @if (loading()) {\n @for (row of _skeletonRows(); track row) {\n <tr yuwTr [class]=\"_rowClass()\">\n @for (column of table.getVisibleLeafColumns(); track column.id) {\n <td yuwTd [class]=\"_cellClasses().get(column.id)?.cell\">\n <span yuwSkeleton class=\"block h-4 w-full\"></span>\n </td>\n }\n </tr>\n }\n } @else if (_isEmpty()) {\n <tr yuwTr [class]=\"_rowClass()\">\n <td yuwTd [attr.colspan]=\"_columnCount()\" class=\"h-24 text-center text-muted-foreground\">\n {{ emptyText() ?? '' }}\n </td>\n </tr>\n } @else {\n @for (row of table.getRowModel().rows; track row.id) {\n <tr\n yuwTr\n [class]=\"_rowClasses().get(row.id)\"\n [attr.data-state]=\"row.getIsSelected() ? 'selected' : null\"\n role=\"button\"\n tabindex=\"0\"\n (click)=\"onRowClick(row.original)\"\n (keydown)=\"onRowKeydown($event, row.original)\"\n >\n @for (cell of row.getVisibleCells(); track cell.id) {\n <td yuwTd [class]=\"_cellClasses().get(cell.column.id)?.cell\">\n <ng-container *flexRender=\"cell.column.columnDef.cell; props: cell.getContext(); let rendered\">\n {{ rendered }}\n </ng-container>\n </td>\n }\n </tr>\n }\n }\n </tbody>\n </table>\n</div>\n\n@if (paginated()) {\n <div class=\"flex items-center flex-wrap justify-end gap-4 py-3 px-1 max-lg:justify-center\">\n @if (customPagination()) {\n <ng-content select=\"[yuwDatatablePagination]\" />\n }\n <yuw-pagination\n [page]=\"currentPage()\"\n (pageChange)=\"onPageChange($event)\"\n [totalPages]=\"table.getPageCount() || 1\"\n [previousLabel]=\"previousPageLabel()\"\n [nextLabel]=\"nextPageLabel()\"\n [ellipsisSrText]=\"paginationEllipsisSrText()\"\n [ariaLabel]=\"paginationAriaLabel()\"\n color=\"neutral\"\n size=\"icon-sm\"\n class=\"flex\"\n />\n </div>\n}\n", dependencies: [{ kind: "directive", type: YuwTableContainerDirective, selector: "[yuwTableContainer]" }, { kind: "directive", type: YuwTableDirective, selector: "[yuwTable]" }, { kind: "directive", type: YuwTHeadDirective, selector: "[yuwTHead]" }, { kind: "directive", type: YuwTBodyDirective, selector: "[yuwTBody]" }, { kind: "directive", type: YuwTrDirective, selector: "[yuwTr]" }, { kind: "directive", type: YuwThDirective, selector: "[yuwTh]" }, { kind: "directive", type: YuwTdDirective, selector: "[yuwTd]" }, { kind: "directive", type: YuwCaptionDirective, selector: "[yuwCaption]" }, { kind: "component", type: YuwPaginationComponent, selector: "yuw-pagination", inputs: ["ariaLabel", "color", "ellipsisSrText", "nextLabel", "page", "previousLabel", "size", "totalPages"], outputs: ["pageChange"] }, { kind: "directive", type: YuwSkeletonDirective, selector: "[yuwSkeleton]" }, { kind: "directive", type: FlexRenderDirective, selector: "ng-template[flexRender]", inputs: ["flexRender", "flexRenderProps", "flexRenderInjector"] }, { kind: "component", type: NgIcon, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
4423
4844
  }
4424
4845
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwDatatableComponent, decorators: [{
4425
4846
  type: Component,
4426
4847
  args: [{ selector: 'yuw-datatable', imports: [...YuwTableImports, YuwPaginationComponent, YuwSkeletonDirective, FlexRenderDirective, NgIcon], providers: [provideIcons({ lucideChevronDown, lucideChevronUp, lucideChevronsUpDown })], host: {
4427
4848
  class: 'contents',
4428
4849
  }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div yuwTableContainer [class]=\"_containerClass()\">\n <table yuwTable [class]=\"_tableClass()\">\n @if (caption()) {\n <caption yuwCaption>{{ caption() }}</caption>\n }\n\n <thead yuwTHead [class]=\"_headClass()\">\n @for (headerGroup of table.getHeaderGroups(); track headerGroup.id) {\n <tr yuwTr [class]=\"_rowClass()\">\n @for (header of headerGroup.headers; track header.id) {\n @let sorted = header.column.getIsSorted();\n @let headerClasses = _cellClasses().get(header.column.id);\n <th\n yuwTh\n scope=\"col\"\n [attr.colspan]=\"header.colSpan\"\n [attr.aria-sort]=\"sorted ? _ariaSort[sorted] : null\"\n [class]=\"headerClasses?.header\"\n >\n @if (!header.isPlaceholder) {\n @if (sortable() && header.column.getCanSort()) {\n <button\n type=\"button\"\n class=\"inline-flex items-center gap-1 select-none hover:text-foreground/80\"\n (click)=\"header.column.toggleSorting()\"\n >\n <ng-container\n *flexRender=\"header.column.columnDef.header; props: header.getContext(); let rendered\"\n >\n {{ rendered }}\n </ng-container>\n\n <ng-icon [name]=\"_sortIcon[sorted || 'none']\" class=\"shrink-0 text-xs\" aria-hidden=\"true\" />\n </button>\n } @else {\n <ng-container *flexRender=\"header.column.columnDef.header; props: header.getContext(); let rendered\">\n {{ rendered }}\n </ng-container>\n }\n }\n </th>\n }\n </tr>\n }\n </thead>\n\n <tbody yuwTBody>\n @if (loading()) {\n @for (row of _skeletonRows(); track row) {\n <tr yuwTr [class]=\"_rowClass()\">\n @for (column of table.getVisibleLeafColumns(); track column.id) {\n <td yuwTd [class]=\"_cellClasses().get(column.id)?.cell\">\n <span yuwSkeleton class=\"block h-4 w-full\"></span>\n </td>\n }\n </tr>\n }\n } @else if (_isEmpty()) {\n <tr yuwTr [class]=\"_rowClass()\">\n <td yuwTd [attr.colspan]=\"_columnCount()\" class=\"h-24 text-center text-muted-foreground\">\n {{ emptyText() ?? '' }}\n </td>\n </tr>\n } @else {\n @for (row of table.getRowModel().rows; track row.id) {\n <tr\n yuwTr\n [class]=\"_rowClasses().get(row.id)\"\n [attr.data-state]=\"row.getIsSelected() ? 'selected' : null\"\n role=\"button\"\n tabindex=\"0\"\n (click)=\"onRowClick(row.original)\"\n (keydown)=\"onRowKeydown($event, row.original)\"\n >\n @for (cell of row.getVisibleCells(); track cell.id) {\n <td yuwTd [class]=\"_cellClasses().get(cell.column.id)?.cell\">\n <ng-container *flexRender=\"cell.column.columnDef.cell; props: cell.getContext(); let rendered\">\n {{ rendered }}\n </ng-container>\n </td>\n }\n </tr>\n }\n }\n </tbody>\n </table>\n</div>\n\n@if (paginated()) {\n <div class=\"flex items-center flex-wrap justify-end gap-4 py-3 px-1 max-lg:justify-center\">\n @if (customPagination()) {\n <ng-content select=\"[yuwDatatablePagination]\" />\n }\n <yuw-pagination\n [page]=\"currentPage()\"\n (pageChange)=\"onPageChange($event)\"\n [totalPages]=\"table.getPageCount() || 1\"\n [previousLabel]=\"previousPageLabel()\"\n [nextLabel]=\"nextPageLabel()\"\n [ellipsisSrText]=\"paginationEllipsisSrText()\"\n [ariaLabel]=\"paginationAriaLabel()\"\n color=\"neutral\"\n size=\"icon-sm\"\n class=\"flex\"\n />\n </div>\n}\n" }]
4429
- }], propDecorators: { customPagination: [{ type: i0.ContentChild, args: [i0.forwardRef(() => YuwDatatablePaginationDirective), { isSignal: true }] }], appearance: [{ type: i0.Input, args: [{ isSignal: true, alias: "appearance", required: false }] }], caption: [{ type: i0.Input, args: [{ isSignal: true, alias: "caption", required: false }] }], cellClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "cellClass", required: false }] }], columnFilters: [{ type: i0.Input, args: [{ isSignal: true, alias: "columnFilters", required: false }] }, { type: i0.Output, args: ["columnFiltersChange"] }], columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: false }] }], columnVisibility: [{ type: i0.Input, args: [{ isSignal: true, alias: "columnVisibility", required: false }] }, { type: i0.Output, args: ["columnVisibilityChange"] }], data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], emptyText: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyText", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], loadingRows: [{ type: i0.Input, args: [{ isSignal: true, alias: "loadingRows", required: false }] }], nextPageLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "nextPageLabel", required: true }] }], paginated: [{ type: i0.Input, args: [{ isSignal: true, alias: "paginated", required: false }] }], pagination: [{ type: i0.Input, args: [{ isSignal: true, alias: "pagination", required: false }] }, { type: i0.Output, args: ["paginationChange"] }], paginationAriaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "paginationAriaLabel", required: true }] }], paginationEllipsisSrText: [{ type: i0.Input, args: [{ isSignal: true, alias: "paginationEllipsisSrText", required: true }] }], previousPageLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "previousPageLabel", required: true }] }], rowClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowClass", required: false }] }], rowSelection: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowSelection", required: false }] }, { type: i0.Output, args: ["rowSelectionChange"] }], selectable: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectable", required: false }] }], sortable: [{ type: i0.Input, args: [{ isSignal: true, alias: "sortable", required: false }] }], sorting: [{ type: i0.Input, args: [{ isSignal: true, alias: "sorting", required: false }] }, { type: i0.Output, args: ["sortingChange"] }], summary: [{ type: i0.Input, args: [{ isSignal: true, alias: "summary", required: false }] }], tableClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "tableClass", required: false }] }], totalItems: [{ type: i0.Input, args: [{ isSignal: true, alias: "totalItems", required: false }] }], rowClicked: [{ type: i0.Output, args: ["rowClicked"] }], selectedRowsChange: [{ type: i0.Output, args: ["selectedRowsChange"] }] } });
4850
+ }], propDecorators: { customPagination: [{ type: i0.ContentChild, args: [i0.forwardRef(() => YuwDatatablePaginationDirective), { isSignal: true }] }], appearance: [{ type: i0.Input, args: [{ isSignal: true, alias: "appearance", required: false }] }], caption: [{ type: i0.Input, args: [{ isSignal: true, alias: "caption", required: false }] }], cellClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "cellClass", required: false }] }], columnFilters: [{ type: i0.Input, args: [{ isSignal: true, alias: "columnFilters", required: false }] }, { type: i0.Output, args: ["columnFiltersChange"] }], columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: false }] }], columnVisibility: [{ type: i0.Input, args: [{ isSignal: true, alias: "columnVisibility", required: false }] }, { type: i0.Output, args: ["columnVisibilityChange"] }], data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], emptyText: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyText", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], loadingRows: [{ type: i0.Input, args: [{ isSignal: true, alias: "loadingRows", required: false }] }], nextPageLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "nextPageLabel", required: true }] }], paginated: [{ type: i0.Input, args: [{ isSignal: true, alias: "paginated", required: false }] }], pagination: [{ type: i0.Input, args: [{ isSignal: true, alias: "pagination", required: false }] }, { type: i0.Output, args: ["paginationChange"] }], paginationAriaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "paginationAriaLabel", required: true }] }], paginationEllipsisSrText: [{ type: i0.Input, args: [{ isSignal: true, alias: "paginationEllipsisSrText", required: true }] }], previousPageLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "previousPageLabel", required: true }] }], rowClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowClass", required: false }] }], rowSelection: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowSelection", required: false }] }, { type: i0.Output, args: ["rowSelectionChange"] }], selectable: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectable", required: false }] }], sortable: [{ type: i0.Input, args: [{ isSignal: true, alias: "sortable", required: false }] }], sorting: [{ type: i0.Input, args: [{ isSignal: true, alias: "sorting", required: false }] }, { type: i0.Output, args: ["sortingChange"] }], tableClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "tableClass", required: false }] }], totalItems: [{ type: i0.Input, args: [{ isSignal: true, alias: "totalItems", required: false }] }], rowClicked: [{ type: i0.Output, args: ["rowClicked"] }], selectedRowsChange: [{ type: i0.Output, args: ["selectedRowsChange"] }] } });
4430
4851
 
4431
4852
  /**
4432
4853
  * Selection checkbox for a datatable cell or header. The host stops the click so neither the
4433
4854
  * checkbox nor the cell around it triggers the row's own action, since `yuw-datatable` emits
4434
4855
  * `rowClicked` from the `<tr>`. `onToggle` is an input because `flexRenderComponent` does not
4435
4856
  * subscribe outputs.
4857
+ *
4858
+ * Renders a single `yuw-checkbox` meant to be used as the `select` display column of `yuw-datatable`
4859
+ * (header for select-all, cell for a single row), wired to TanStack's toggle handlers.
4860
+ *
4861
+ * Inputs:
4862
+ * - `checked`: Whether the checkbox is checked. Default is `false`.
4863
+ * - `indeterminate`: Shows the mixed state, e.g. for a header when only some rows are selected. Default is `false`.
4864
+ * - `label`: Accessible name (`aria-label`) of the checkbox. Default is `'Select row'`; consuming apps should
4865
+ * override it with translated text.
4866
+ * - `onToggle`: Callback run when the checkbox changes. Default is a no-op.
4436
4867
  */
4437
4868
  class YuwDatatableRowSelect {
4438
4869
  constructor() {
@@ -4459,6 +4890,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
4459
4890
  * Pencil button cell that runs `onEdit`, hidden until its row is hovered or keyboard-focused (`yuw-reveal`,
4460
4891
  * see `theme/components/reveal-on-hover.css`); touch devices keep it visible. An input because `flexRenderComponent` does not subscribe
4461
4892
  * outputs. The host stops the click so a clickable row does not fire twice.
4893
+ *
4894
+ * Inputs:
4895
+ * - `label` (required): Accessible name (`aria-label`) of the pencil button. User-facing text the
4896
+ * consuming app is responsible for translating.
4897
+ * - `onEdit`: Callback run when the button is clicked. Default is a no-op.
4462
4898
  */
4463
4899
  class YuwActionsCellComponent {
4464
4900
  constructor() {
@@ -4483,7 +4919,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
4483
4919
  * `actions` column; `label` is the button's accessible name and `header` the optional visible
4484
4920
  * column title, both already translated. Without `header` the column stays headerless.
4485
4921
  */
4486
- function buildYuwActionsColumn(label, onEdit, cellClass, header = '') {
4922
+ function buildYuwActionsColumn(label, onEdit, cellClass = 'w-12', header = '') {
4487
4923
  return {
4488
4924
  id: 'actions',
4489
4925
  header,
@@ -4495,53 +4931,6 @@ function buildYuwActionsColumn(label, onEdit, cellClass, header = '') {
4495
4931
  };
4496
4932
  }
4497
4933
 
4498
- /**
4499
- * Displays a user or entity avatar with optional image, fallback text/initials, status badge, or overlapping group layout.
4500
- *
4501
- * Inputs:
4502
- * - `size`: Avatar size (`'default'`, `'sm'`, `'lg'`). Default is `'default'`.
4503
- * - `src`: Image URL for single-avatar mode. Omit to display fallback text.
4504
- * - `alt`: Required. Accessible label for single-avatar mode and fallback text. User-facing text —
4505
- * the consuming app is responsible for providing (and translating) it.
4506
- * - `fallback`: Fallback text or initials shown when image is loading, unprovided, or fails to load.
4507
- * - `badge`: Renders a status badge marker on the bottom-right corner (single-avatar mode).
4508
- * - `group`: Array of item DTOs (`YuwAvatarGroupItemDto[]`) to render as an overlapping avatar group stack.
4509
- * - `groupCount`: Overflow label string (e.g. `"+5"`) displayed at the end of an avatar group stack.
4510
- * - `class`: Extra CSS classes merged onto the inner `hlm-avatar` element(s); merged last, so they win.
4511
- *
4512
- * Single Avatar Usage:
4513
- * ```html
4514
- * <yuw-avatar src="/path/to/user.png" alt="Jane Doe" fallback="JD" />
4515
- * <yuw-avatar alt="Jane Doe" fallback="JD" badge />
4516
- * ```
4517
- *
4518
- * Avatar Group Usage:
4519
- * ```html
4520
- * <yuw-avatar [group]="teamMembers" alt="Team" groupCount="+5" />
4521
- * ```
4522
- */
4523
- class YuwAvatarComponent {
4524
- constructor() {
4525
- this.alt = input.required(...(ngDevMode ? [{ debugName: "alt" }] : /* istanbul ignore next */ []));
4526
- this.badge = input(false, { ...(ngDevMode ? { debugName: "badge" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
4527
- this.fallback = input(undefined, ...(ngDevMode ? [{ debugName: "fallback" }] : /* istanbul ignore next */ []));
4528
- this.group = input(undefined, ...(ngDevMode ? [{ debugName: "group" }] : /* istanbul ignore next */ []));
4529
- this.groupCount = input(undefined, ...(ngDevMode ? [{ debugName: "groupCount" }] : /* istanbul ignore next */ []));
4530
- this.size = input('default', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
4531
- this.src = input(undefined, ...(ngDevMode ? [{ debugName: "src" }] : /* istanbul ignore next */ []));
4532
- this.userClass = input('', { ...(ngDevMode ? { debugName: "userClass" } : /* istanbul ignore next */ {}), alias: 'class' });
4533
- this._isGroup = computed(() => (this.group()?.length ?? 0) > 0, ...(ngDevMode ? [{ debugName: "_isGroup" }] : /* istanbul ignore next */ []));
4534
- }
4535
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwAvatarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4536
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: YuwAvatarComponent, isStandalone: true, selector: "yuw-avatar", inputs: { alt: { classPropertyName: "alt", publicName: "alt", isSignal: true, isRequired: true, transformFunction: null }, badge: { classPropertyName: "badge", publicName: "badge", isSignal: true, isRequired: false, transformFunction: null }, fallback: { classPropertyName: "fallback", publicName: "fallback", isSignal: true, isRequired: false, transformFunction: null }, group: { classPropertyName: "group", publicName: "group", isSignal: true, isRequired: false, transformFunction: null }, groupCount: { classPropertyName: "groupCount", publicName: "groupCount", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, src: { classPropertyName: "src", publicName: "src", isSignal: true, isRequired: false, transformFunction: null }, userClass: { classPropertyName: "userClass", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "contents" }, ngImport: i0, template: "<ng-template #avatarBox let-src=\"src\" let-alt=\"alt\" let-fallback=\"fallback\" let-showBadge=\"showBadge\">\n <hlm-avatar [size]=\"size()\" [class]=\"userClass()\">\n @if (src) {\n <img hlmAvatarImage [src]=\"src\" [alt]=\"alt ?? ''\" />\n }\n <span hlmAvatarFallback>{{ fallback }}</span>\n\n @if (showBadge) {\n <span hlmAvatarBadge>\n <ng-content select=\"[yuwAvatarBadgeIcon]\" />\n </span>\n }\n </hlm-avatar>\n</ng-template>\n\n@if (_isGroup()) {\n <div hlmAvatarGroup>\n @for (entry of group(); track entry.alt + '|' + (entry.src ?? '')) {\n <ng-container\n [ngTemplateOutlet]=\"avatarBox\"\n [ngTemplateOutletContext]=\"{ src: entry.src, alt: entry.alt, fallback: entry.fallback, showBadge: false }\"\n />\n }\n\n @if (groupCount()) {\n <span hlmAvatarGroupCount>{{ groupCount() }}</span>\n }\n </div>\n} @else {\n <ng-container\n [ngTemplateOutlet]=\"avatarBox\"\n [ngTemplateOutletContext]=\"{ src: src(), alt: alt(), fallback: fallback(), showBadge: badge() }\"\n />\n}\n", dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: i1$j.HlmAvatar, selector: "hlm-avatar", inputs: ["size"] }, { kind: "directive", type: i1$j.HlmAvatarBadge, selector: "[hlmAvatarBadge],hlm-avatar-badge" }, { kind: "directive", type: i1$j.HlmAvatarFallback, selector: "[hlmAvatarFallback]", exportAs: ["hlmAvatarFallback"] }, { kind: "directive", type: i1$j.HlmAvatarGroup, selector: "[hlmAvatarGroup],hlm-avatar-group" }, { kind: "directive", type: i1$j.HlmAvatarGroupCount, selector: "[hlmAvatarGroupCount],hlm-avatar-group-count" }, { kind: "directive", type: i1$j.HlmAvatarImage, selector: "img[hlmAvatarImage]", exportAs: ["hlmAvatarImage"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
4537
- }
4538
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwAvatarComponent, decorators: [{
4539
- type: Component,
4540
- args: [{ selector: 'yuw-avatar', imports: [NgTemplateOutlet, ...HlmAvatarImports], host: {
4541
- class: 'contents',
4542
- }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-template #avatarBox let-src=\"src\" let-alt=\"alt\" let-fallback=\"fallback\" let-showBadge=\"showBadge\">\n <hlm-avatar [size]=\"size()\" [class]=\"userClass()\">\n @if (src) {\n <img hlmAvatarImage [src]=\"src\" [alt]=\"alt ?? ''\" />\n }\n <span hlmAvatarFallback>{{ fallback }}</span>\n\n @if (showBadge) {\n <span hlmAvatarBadge>\n <ng-content select=\"[yuwAvatarBadgeIcon]\" />\n </span>\n }\n </hlm-avatar>\n</ng-template>\n\n@if (_isGroup()) {\n <div hlmAvatarGroup>\n @for (entry of group(); track entry.alt + '|' + (entry.src ?? '')) {\n <ng-container\n [ngTemplateOutlet]=\"avatarBox\"\n [ngTemplateOutletContext]=\"{ src: entry.src, alt: entry.alt, fallback: entry.fallback, showBadge: false }\"\n />\n }\n\n @if (groupCount()) {\n <span hlmAvatarGroupCount>{{ groupCount() }}</span>\n }\n </div>\n} @else {\n <ng-container\n [ngTemplateOutlet]=\"avatarBox\"\n [ngTemplateOutletContext]=\"{ src: src(), alt: alt(), fallback: fallback(), showBadge: badge() }\"\n />\n}\n" }]
4543
- }], propDecorators: { alt: [{ type: i0.Input, args: [{ isSignal: true, alias: "alt", required: true }] }], badge: [{ type: i0.Input, args: [{ isSignal: true, alias: "badge", required: false }] }], fallback: [{ type: i0.Input, args: [{ isSignal: true, alias: "fallback", required: false }] }], group: [{ type: i0.Input, args: [{ isSignal: true, alias: "group", required: false }] }], groupCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "groupCount", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], src: [{ type: i0.Input, args: [{ isSignal: true, alias: "src", required: false }] }], userClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }] } });
4544
-
4545
4934
  /**
4546
4935
  * Container directive for list/row item layout structures.
4547
4936
  * Accepts optional `variant` and `size` inputs.
@@ -4953,6 +5342,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
4953
5342
  * text the consuming app is responsible for translating.
4954
5343
  * - `panelClass`: Extra classes merged onto the dialog panel (e.g. `sm:max-w-lg` to widen it).
4955
5344
  * They win over the library defaults via `twMerge`.
5345
+ * - `triggerColor`: Brand color theme for the trigger button (any `YuwColorDto` value). Default is `'neutral'`.
4956
5346
  * - `triggerVariant`: Button style variant for the trigger button. Default is `'outline'`.
4957
5347
  * - `triggerSize`: Button size for the trigger button.
4958
5348
  *
@@ -5806,6 +6196,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
5806
6196
  * branches and cannot attach a directive conditionally — an attribute selector matches on presence, so
5807
6197
  * the nav applies it to every entry and passes whether that entry actually has an avatar. Its default
5808
6198
  * is `true` so the bare, hand-written form needs no value.
6199
+ *
6200
+ * Inputs:
6201
+ * - `yuwSidebarMenuAvatarButton`: Boolean; whether the avatar geometry class is applied. An empty attribute counts as `true`; `false` applies nothing. Default is `true`.
5809
6202
  */
5810
6203
  class YuwSidebarMenuAvatarButtonDirective {
5811
6204
  constructor() {
@@ -5897,6 +6290,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
5897
6290
  *
5898
6291
  * `label` is the accessible label of the rail button (it has no visible text). User-facing text —
5899
6292
  * the consuming app is responsible for providing it already translated.
6293
+ *
6294
+ * Inputs:
6295
+ * - `label`: Required accessible label (`aria-label`) of the rail button.
5900
6296
  */
5901
6297
  class YuwSidebarRailDirective {
5902
6298
  constructor() {
@@ -6087,6 +6483,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
6087
6483
  * change-detection pass, and `RouterLinkActive` treats that as a changed input and re-runs its
6088
6484
  * subscription. Every entry resolves a tooltip, entries with children included: the submenu opens on
6089
6485
  * click, so hover is free to do what it does for every other rail icon and name the thing.
6486
+ *
6487
+ * Inputs:
6488
+ * - `collapsible`: Collapse mode of the host sidebar (`'offcanvas'`, `'icon'`, `'none'`); the rail submenu form only
6489
+ * applies for `'icon'`. Default is `'offcanvas'`.
6490
+ * - `content`: Required `YuwSidebarContentDto` (groups and their items) to render as the nav tree.
6090
6491
  */
6091
6492
  class YuwSidebarNavComponent {
6092
6493
  constructor() {
@@ -6218,6 +6619,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
6218
6619
  * split across the two refs, which is what broke every subsequent animation. Keeping one instance for
6219
6620
  * the sidebar's lifetime means a swap is only new content inside a live panel; the entry's own fields
6220
6621
  * are read through `_label`/`_children`, which tolerate the null the item holds before the first open.
6622
+ *
6623
+ * Outputs:
6624
+ * - `itemClicked`: Emits `{ id, event }` (`YuwSidebarItemClickDto`) when a child entry of the open submenu is clicked; the submenu closes first.
6221
6625
  */
6222
6626
  class YuwSidebarSubmenuSheetComponent {
6223
6627
  constructor() {
@@ -6628,5 +7032,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
6628
7032
  * Generated bundle index. Do not edit.
6629
7033
  */
6630
7034
 
6631
- export { DATATABLE_ALIGN_CLASS, DATATABLE_LAYOUT_CLASS, DATATABLE_WRAP_CONTENT_CLASS, YUW_DATATABLE_FEATURES, YUW_DATATABLE_WRAP_MIN_WIDTH, YUW_PASSWORD_REVEAL_STATES, YUW_SIDEBAR_RAIL_ICON_SIZE, YUW_SIDEBAR_RAIL_PADDING, YUW_SIDEBAR_RAIL_WIDTH, YuwAccordion, YuwAccordionContentComponent, YuwAccordionImports, YuwAccordionItem, YuwAccordionTriggerComponent, YuwActionsCellComponent, YuwAlertActionDirective, YuwAlertComponent, YuwAlertDescriptionDirective, YuwAlertDialogComponent, YuwAlertDialogMediaDirective, YuwAlertDialogTriggerDirective, YuwAlertImports, YuwAlertTitleDirective, YuwAttachmentActionDirective, YuwAttachmentActionsDirective, YuwAttachmentContentDirective, YuwAttachmentDescriptionDirective, YuwAttachmentDirective, YuwAttachmentGroupDirective, YuwAttachmentMediaDirective, YuwAttachmentTitleDirective, YuwAttachmentTriggerDirective, YuwAvatarComponent, YuwBadgeComponent, YuwBreadcrumbComponent, YuwBreadcrumbTrailService, YuwButtonComponent, YuwButtonGroupComponent, YuwButtonGroupContentDirective, YuwCaptionDirective, YuwCardActionDirective, YuwCardContentDirective, YuwCardDescriptionDirective, YuwCardDirective, YuwCardFooterDirective, YuwCardGridComponent, YuwCardGridItemComponent, YuwCardHeaderDirective, YuwCardImports, YuwCardTitleDirective, YuwCheckboxComponent, YuwClassDirective, YuwComboboxComponent, YuwComboboxItemDirective, YuwCommandComponent, YuwCommandDialogComponent, YuwContextMenuCheckboxDirective, YuwContextMenuCheckboxIndicatorComponent, YuwContextMenuDirective, YuwContextMenuGroupDirective, YuwContextMenuImports, YuwContextMenuItemDirective, YuwContextMenuLabelDirective, YuwContextMenuRadioDirective, YuwContextMenuRadioIndicatorComponent, YuwContextMenuSeparatorDirective, YuwContextMenuShortcutDirective, YuwContextMenuSubDirective, YuwContextMenuSubIndicatorComponent, YuwContextMenuSubTriggerDirective, YuwContextMenuTriggerDirective, YuwDatatableComponent, YuwDatatablePaginationDirective, YuwDatatableRowSelect, YuwDatepickerComponent, YuwDialogCloseDirective, YuwDialogComponent, YuwDialogFooterDirective, YuwDialogImports, YuwDialogTriggerDirective, YuwEmptyContentDirective, YuwEmptyDescriptionDirective, YuwEmptyDirective, YuwEmptyHeaderDirective, YuwEmptyImports, YuwEmptyMediaDirective, YuwEmptyTitleDirective, YuwFieldBase, YuwInputAddonImports, YuwInputComponent, YuwInputOtpComponent, YuwItemActionsDirective, YuwItemContentDirective, YuwItemDescriptionDirective, YuwItemDirective, YuwItemFooterDirective, YuwItemGroupDirective, YuwItemHeaderDirective, YuwItemImports, YuwItemMediaDirective, YuwItemSeparatorDirective, YuwItemTitleDirective, YuwLabel, YuwLeftAddonDirective, YuwListPaginationComponent, YuwListToolbarComponent, YuwPageHeaderComponent, YuwPageSizeComponent, YuwPaginationComponent, YuwPasswordInputComponent, YuwPopoverComponent, YuwPopoverTriggerDirective, YuwRadioGroupComponent, YuwRightAddonDirective, YuwSearchInputComponent, YuwSheetCloseDirective, YuwSheetComponent, YuwSheetFooterDirective, YuwSheetImports, YuwSheetTriggerDirective, YuwSidebarComponent, YuwSidebarContentDirective, YuwSidebarContentExtraDirective, YuwSidebarFooterDirective, YuwSidebarFooterExtraDirective, YuwSidebarGroupContentDirective, YuwSidebarGroupDirective, YuwSidebarGroupLabelDirective, YuwSidebarHeaderDirective, YuwSidebarInsetDirective, YuwSidebarMenuAvatarButtonDirective, YuwSidebarMenuBadgeDirective, YuwSidebarMenuButtonDirective, YuwSidebarMenuDirective, YuwSidebarMenuItemDirective, YuwSidebarMenuSubButtonDirective, YuwSidebarMenuSubDirective, YuwSidebarMenuSubItemDirective, YuwSidebarRailDirective, YuwSidebarRailService, YuwSidebarSeparatorDirective, YuwSidebarSubmenuService, YuwSidebarTriggerComponent, YuwSidebarWrapperDirective, YuwSkeletonDirective, YuwSpinnerComponent, YuwSwitchComponent, YuwTBodyDirective, YuwTFootDirective, YuwTHeadDirective, YuwTabContentDirective, YuwTabPanelDirective, YuwTableContainerDirective, YuwTableDirective, YuwTableImports, YuwTabsComponent, YuwTdDirective, YuwTextFieldBase, YuwTextareaComponent, YuwThDirective, YuwToasterComponent, YuwTooltipDirective, YuwTrDirective, YuwValueAccessorBase, buildInputOtpGroups, buildYuwActionsColumn, cn, createPagedList, datatableCellVariants, datatableContainerVariants, datatableHeadVariants, datatableHeaderCellVariants, datatableRowVariants, getPaginationRange, provideValueAccessor, totalInputOtpLength, yuwCommandDefaultFilter };
7035
+ export { DATATABLE_ALIGN_CLASS, DATATABLE_LAYOUT_CLASS, DATATABLE_WRAP_CONTENT_CLASS, YUW_DATATABLE_FEATURES, YUW_DATATABLE_WRAP_MIN_WIDTH, YUW_PASSWORD_REVEAL_STATES, YUW_SIDEBAR_RAIL_ICON_SIZE, YUW_SIDEBAR_RAIL_PADDING, YUW_SIDEBAR_RAIL_WIDTH, YuwAccordion, YuwAccordionContentComponent, YuwAccordionImports, YuwAccordionItem, YuwAccordionTriggerComponent, YuwActionsCellComponent, YuwAlertActionDirective, YuwAlertComponent, YuwAlertDescriptionDirective, YuwAlertDialogComponent, YuwAlertDialogMediaDirective, YuwAlertDialogTriggerDirective, YuwAlertImports, YuwAlertTitleDirective, YuwAttachmentActionDirective, YuwAttachmentActionsDirective, YuwAttachmentContentDirective, YuwAttachmentDescriptionDirective, YuwAttachmentDirective, YuwAttachmentGroupDirective, YuwAttachmentMediaDirective, YuwAttachmentTitleDirective, YuwAttachmentTriggerDirective, YuwAvatarComponent, YuwBadgeComponent, YuwBreadcrumbComponent, YuwBreadcrumbTrailService, YuwButtonComponent, YuwButtonGroupComponent, YuwButtonGroupContentDirective, YuwCaptionDirective, YuwCardActionDirective, YuwCardContentDirective, YuwCardDescriptionDirective, YuwCardDirective, YuwCardFooterDirective, YuwCardGridComponent, YuwCardGridItemComponent, YuwCardHeaderDirective, YuwCardImports, YuwCardTitleDirective, YuwCheckboxComponent, YuwClassDirective, YuwComboboxComponent, YuwComboboxItemDirective, YuwCommandComponent, YuwCommandDialogComponent, YuwContextMenuCheckboxDirective, YuwContextMenuCheckboxIndicatorComponent, YuwContextMenuDirective, YuwContextMenuGroupDirective, YuwContextMenuImports, YuwContextMenuItemDirective, YuwContextMenuLabelDirective, YuwContextMenuRadioDirective, YuwContextMenuRadioIndicatorComponent, YuwContextMenuSeparatorDirective, YuwContextMenuShortcutDirective, YuwContextMenuSubDirective, YuwContextMenuSubIndicatorComponent, YuwContextMenuSubTriggerDirective, YuwContextMenuTriggerDirective, YuwDatatableComponent, YuwDatatablePaginationDirective, YuwDatatableRowSelect, YuwDatepickerComponent, YuwDialogCloseDirective, YuwDialogComponent, YuwDialogFooterDirective, YuwDialogImports, YuwDialogTriggerDirective, YuwEmptyContentDirective, YuwEmptyDescriptionDirective, YuwEmptyDirective, YuwEmptyHeaderDirective, YuwEmptyImports, YuwEmptyMediaDirective, YuwEmptyTitleDirective, YuwFieldBase, YuwInputAddonImports, YuwInputComponent, YuwInputFileComponent, YuwInputOtpComponent, YuwItemActionsDirective, YuwItemContentDirective, YuwItemDescriptionDirective, YuwItemDirective, YuwItemFooterDirective, YuwItemGroupDirective, YuwItemHeaderDirective, YuwItemImports, YuwItemMediaDirective, YuwItemSeparatorDirective, YuwItemTitleDirective, YuwLabel, YuwLeftAddonDirective, YuwListPaginationComponent, YuwListToolbarComponent, YuwPageHeaderComponent, YuwPageSizeComponent, YuwPaginationComponent, YuwPasswordInputComponent, YuwPopoverComponent, YuwPopoverTriggerDirective, YuwRadioGroupComponent, YuwRightAddonDirective, YuwSearchInputComponent, YuwSheetCloseDirective, YuwSheetComponent, YuwSheetFooterDirective, YuwSheetImports, YuwSheetTriggerDirective, YuwSidebarComponent, YuwSidebarContentDirective, YuwSidebarContentExtraDirective, YuwSidebarFooterDirective, YuwSidebarFooterExtraDirective, YuwSidebarGroupContentDirective, YuwSidebarGroupDirective, YuwSidebarGroupLabelDirective, YuwSidebarHeaderDirective, YuwSidebarInsetDirective, YuwSidebarMenuAvatarButtonDirective, YuwSidebarMenuBadgeDirective, YuwSidebarMenuButtonDirective, YuwSidebarMenuDirective, YuwSidebarMenuItemDirective, YuwSidebarMenuSubButtonDirective, YuwSidebarMenuSubDirective, YuwSidebarMenuSubItemDirective, YuwSidebarRailDirective, YuwSidebarRailService, YuwSidebarSeparatorDirective, YuwSidebarSubmenuService, YuwSidebarTriggerComponent, YuwSidebarWrapperDirective, YuwSkeletonDirective, YuwSpinnerComponent, YuwSwitchComponent, YuwTBodyDirective, YuwTFootDirective, YuwTHeadDirective, YuwTabContentDirective, YuwTabPanelDirective, YuwTableContainerDirective, YuwTableDirective, YuwTableImports, YuwTabsComponent, YuwTdDirective, YuwTextFieldBase, YuwTextareaComponent, YuwThDirective, YuwToasterComponent, YuwTooltipDirective, YuwTrDirective, YuwValueAccessorBase, buildInputOtpGroups, buildYuwActionsColumn, cn, createPagedList, datatableCellVariants, datatableContainerVariants, datatableHeadVariants, datatableHeaderCellVariants, datatableRowVariants, getPaginationRange, provideValueAccessor, totalInputOtpLength, yuwCommandDefaultFilter };
6632
7036
  //# sourceMappingURL=yukit-web.mjs.map