yukit-web 0.0.25 → 0.0.26

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.
@@ -1,23 +1,27 @@
1
1
  import { clsx } from 'clsx';
2
2
  import { twMerge } from 'tailwind-merge';
3
3
  import * as i0 from '@angular/core';
4
- import { input, Directive, forwardRef, inject, ElementRef, booleanAttribute, signal, computed, model, output, ChangeDetectionStrategy, Component, TemplateRef, contentChildren, viewChild, contentChild, Injector, afterNextRender, effect, numberAttribute, linkedSignal, Injectable, runInInjectionContext, DestroyRef } from '@angular/core';
4
+ import { input, Directive, forwardRef, inject, ElementRef, booleanAttribute, signal, computed, model, output, linkedSignal, effect, untracked, ChangeDetectionStrategy, Component, TemplateRef, contentChildren, Injectable, viewChild, contentChild, Injector, afterNextRender, numberAttribute, runInInjectionContext, DestroyRef } from '@angular/core';
5
5
  import { classes, hlm } from 'yukit-web/helm/utils';
6
6
  import { NG_VALUE_ACCESSOR } from '@angular/forms';
7
+ import { toSignal, toObservable, outputFromObservable } from '@angular/core/rxjs-interop';
8
+ import { debounceTime, distinctUntilChanged, filter, startWith, map, skip, switchMap, of, timer } from 'rxjs';
7
9
  import { HlmButton, provideBrnButtonConfig } from 'yukit-web/helm/button';
8
10
  import * as i2 from 'yukit-web/helm/dropdown-menu';
9
11
  import { HlmDropdownMenuTrigger, HlmDropdownMenuCheckboxIndicator, HlmDropdownMenuRadioIndicator, HlmDropdownMenuItemSubIndicator, HlmDropdownMenu, HlmDropdownMenuItem, HlmDropdownMenuCheckbox, HlmDropdownMenuRadio, HlmDropdownMenuLabel, HlmDropdownMenuGroup, HlmDropdownMenuSeparator, HlmDropdownMenuShortcut, HlmDropdownMenuSub, HlmDropdownMenuSubTrigger } from 'yukit-web/helm/dropdown-menu';
10
12
  import { cva } from 'class-variance-authority';
11
13
  import { NgTemplateOutlet } from '@angular/common';
12
14
  import { NgIcon, provideIcons } from '@ng-icons/core';
13
- import { lucideX, lucideChevronRight, lucideChevronLeft, lucideSearch, lucideEyeOff, lucideEye, lucideChevronsUpDown, lucideChevronUp, lucideChevronDown } from '@ng-icons/lucide';
15
+ import { lucideX, lucideChevronRight, lucideChevronLeft, lucideArrowLeft, lucidePlus, lucideSearch, lucideEyeOff, lucideEye, lucideSettings2, lucideDownload, lucideChevronsUpDown, lucideChevronUp, lucideChevronDown, lucideSettings } from '@ng-icons/lucide';
14
16
  import * as i1 from 'yukit-web/helm/badge';
15
17
  import { HlmBadge } from 'yukit-web/helm/badge';
16
18
  import * as i1$1 from 'yukit-web/helm/breadcrumb';
17
19
  import { HlmBreadcrumbImports } from 'yukit-web/helm/breadcrumb';
18
- import { HlmPagination, HlmPaginationContent, HlmPaginationItem, HlmPaginationLink, HlmPaginationEllipsis } from 'yukit-web/helm/pagination';
20
+ import { Router, NavigationEnd, isActive, RouterLink, RouterLinkActive } from '@angular/router';
21
+ import { HlmPagination, HlmPaginationContent, HlmPaginationItem, HlmPaginationEllipsis } from 'yukit-web/helm/pagination';
19
22
  import * as i1$2 from 'yukit-web/helm/combobox';
20
23
  import { HlmComboboxContent, HlmComboboxImports } from 'yukit-web/helm/combobox';
24
+ import { BreakpointObserver } from '@angular/cdk/layout';
21
25
  import { HlmAccordion, HlmAccordionItem, HlmAccordionTrigger, HlmAccordionContent } from 'yukit-web/helm/accordion';
22
26
  import { HlmField, HlmFieldDescription } from 'yukit-web/helm/field';
23
27
  import { HlmInput } from 'yukit-web/helm/input';
@@ -41,52 +45,49 @@ import { HlmCard, HlmCardHeader, HlmCardTitle, HlmCardDescription, HlmCardAction
41
45
  import * as i1$9 from 'yukit-web/helm/empty';
42
46
  import { HlmEmpty, HlmEmptyHeader, HlmEmptyMedia, HlmEmptyTitle, HlmEmptyDescription, HlmEmptyContent } from 'yukit-web/helm/empty';
43
47
  import { CdkContextMenuTrigger, CdkMenuItem, CdkMenuItemCheckbox, CdkMenuItemRadio, CdkMenuTrigger } from '@angular/cdk/menu';
44
- import { outputFromObservable, toObservable, toSignal } from '@angular/core/rxjs-interop';
45
48
  import * as i1$a from 'yukit-web/helm/context-menu';
46
49
  import { HlmContextMenuTrigger } from 'yukit-web/helm/context-menu';
47
50
  import * as i1$b from 'yukit-web/helm/date-picker';
48
51
  import { injectHlmMonthYearPickerConfig, injectHlmDatePickerMultiConfig, injectHlmDateRangePickerConfig, injectHlmDatePickerConfig, HlmDatePickerImports } from 'yukit-web/helm/date-picker';
49
52
  import * as i1$c from 'yukit-web/helm/table';
50
53
  import { HlmTableContainer, HlmTable, HlmTHead, HlmTBody, HlmTFoot, HlmTr, HlmTh, HlmTd, HlmCaption } from 'yukit-web/helm/table';
51
- import { rowSortingFeature, rowSelectionFeature, rowPaginationFeature, columnVisibilityFeature, columnFilteringFeature, sortFns, createPaginatedRowModel, createSortedRowModel, createFilteredRowModel, createCoreRowModel } from '@tanstack/table-core';
52
- import { injectTable, FlexRenderDirective } from '@tanstack/angular-table';
53
- import { skip, switchMap, of, timer } from 'rxjs';
54
- import * as i1$d from 'yukit-web/helm/avatar';
55
- import { HlmAvatarImports } from 'yukit-web/helm/avatar';
56
- import * as i1$e from 'yukit-web/helm/item';
57
- import { HlmItem, HlmItemHeader, HlmItemMedia, HlmItemContent, HlmItemTitle, HlmItemDescription, HlmItemActions, HlmItemFooter, HlmItemGroup, HlmItemSeparator } from 'yukit-web/helm/item';
54
+ import * as i1$e from 'yukit-web/helm/popover';
55
+ import { HlmPopoverImports } from 'yukit-web/helm/popover';
56
+ import * as i1$d from '@spartan-ng/brain/popover';
57
+ import { BrnPopoverTrigger } from '@spartan-ng/brain/popover';
58
58
  import * as i1$f from '@spartan-ng/brain/sheet';
59
59
  import { BrnSheetTrigger, BrnSheetClose } from '@spartan-ng/brain/sheet';
60
60
  import * as i1$g from 'yukit-web/helm/sheet';
61
61
  import { HlmSheet, HlmSheetImports } from 'yukit-web/helm/sheet';
62
- import * as i1$i from 'yukit-web/helm/popover';
63
- import { HlmPopoverImports } from 'yukit-web/helm/popover';
64
- import * as i1$h from '@spartan-ng/brain/popover';
65
- import { BrnPopoverTrigger } from '@spartan-ng/brain/popover';
66
- import * as i1$j from '@spartan-ng/brain/tooltip';
62
+ import * as i1$h from 'yukit-web/helm/tabs';
63
+ import { HlmTabsImports } from 'yukit-web/helm/tabs';
64
+ import { rowSortingFeature, rowSelectionFeature, rowPaginationFeature, columnVisibilityFeature, columnFilteringFeature, sortFns, createPaginatedRowModel, createSortedRowModel, createFilteredRowModel, createCoreRowModel } from '@tanstack/table-core';
65
+ import { injectTable, FlexRenderDirective, flexRenderComponent } from '@tanstack/angular-table';
66
+ import * as i1$i from 'yukit-web/helm/avatar';
67
+ import { HlmAvatarImports } from 'yukit-web/helm/avatar';
68
+ import * as i1$j from 'yukit-web/helm/item';
69
+ import { HlmItem, HlmItemHeader, HlmItemMedia, HlmItemContent, HlmItemTitle, HlmItemDescription, HlmItemActions, HlmItemFooter, HlmItemGroup, HlmItemSeparator } from 'yukit-web/helm/item';
70
+ import * as i1$k from '@spartan-ng/brain/tooltip';
67
71
  import { provideBrnTooltipDefaultOptions, BrnTooltip } from '@spartan-ng/brain/tooltip';
68
72
  import { tooltipPositionVariants, DEFAULT_TOOLTIP_CONTENT_CLASSES, DEFAULT_TOOLTIP_SVG_CLASS } from 'yukit-web/helm/tooltip';
69
73
  import { HlmSpinner } from 'yukit-web/helm/spinner';
70
74
  import { HlmToaster } from 'yukit-web/helm/sonner';
71
75
  export { toast as yuwToast } from '@spartan-ng/brain/sonner';
72
76
  import { HlmAlert, HlmAlertTitle, HlmAlertDescription, HlmAlertAction } from 'yukit-web/helm/alert';
73
- import * as i1$k from '@spartan-ng/brain/dialog';
77
+ import * as i1$l from '@spartan-ng/brain/dialog';
74
78
  import { BrnDialogTrigger, BrnDialogClose } from '@spartan-ng/brain/dialog';
75
- import * as i1$l from 'yukit-web/helm/dialog';
79
+ import * as i1$m from 'yukit-web/helm/dialog';
76
80
  import { HlmDialogImports } from 'yukit-web/helm/dialog';
77
- import * as i1$n from 'yukit-web/helm/alert-dialog';
81
+ import * as i1$o from 'yukit-web/helm/alert-dialog';
78
82
  import { HlmAlertDialogImports } from 'yukit-web/helm/alert-dialog';
79
- import * as i1$m from '@spartan-ng/brain/alert-dialog';
83
+ import * as i1$n from '@spartan-ng/brain/alert-dialog';
80
84
  import { BrnAlertDialogTrigger } from '@spartan-ng/brain/alert-dialog';
81
- import * as i1$o from 'yukit-web/helm/tabs';
82
- import { HlmTabsImports } from 'yukit-web/helm/tabs';
83
85
  import * as i1$p from 'yukit-web/helm/attachment';
84
86
  import { HlmAttachment, HlmAttachmentGroup, HlmAttachmentMedia, HlmAttachmentContent, HlmAttachmentTitle, HlmAttachmentDescription, HlmAttachmentActions, HlmAttachmentAction, HlmAttachmentTrigger } from 'yukit-web/helm/attachment';
85
- import { map, distinctUntilChanged } from 'rxjs/operators';
87
+ import { map as map$1, distinctUntilChanged as distinctUntilChanged$1 } from 'rxjs/operators';
86
88
  import * as i1$q from 'yukit-web/helm/sidebar';
87
89
  import { HlmSidebarService, provideHlmSidebarConfig, HlmSidebarWrapper, HlmSidebarHeader, HlmSidebarContent, HlmSidebarFooter, HlmSidebarGroup, HlmSidebarGroupLabel, HlmSidebarGroupContent, HlmSidebarMenu, HlmSidebarMenuItem, HlmSidebarMenuButton, HlmSidebarMenuBadge, HlmSidebarMenuSub, HlmSidebarMenuSubItem, HlmSidebarMenuSubButton, HlmSidebarSeparator, HlmSidebarRail, HlmSidebarInset, injectHlmSidebarConfig, HlmSidebar, HlmSidebarTrigger } from 'yukit-web/helm/sidebar';
88
90
  export { HlmSidebarService as YuwSidebarService, provideHlmSidebarConfig as provideYuwSidebarConfig } from 'yukit-web/helm/sidebar';
89
- import { Router, isActive, RouterLink, RouterLinkActive } from '@angular/router';
90
91
  import { OverlayContainer } from '@angular/cdk/overlay';
91
92
  import * as i1$r from 'yukit-web/helm/command';
92
93
  import { HlmCommandImports, HlmCommandDialog } from 'yukit-web/helm/command';
@@ -230,43 +231,145 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
230
231
  }], propDecorators: { disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }] } });
231
232
 
232
233
  /**
233
- * Shared surface of the single-value text controls (`yuw-input`, `yuw-password-input`,
234
- * `yuw-textarea`, `yuw-search-input`).
234
+ * Shared surface of every string-valued field that renders helper and error text under itself
235
+ * (`yuw-input-otp` and, through `YuwTextFieldBase`, the four text controls).
235
236
  *
236
- * Owns every input of `YuwTextFieldContract` plus `class` and `committed`, so the four controls
237
- * can't drift apart — the Liskov rule in `AGENTS.md`: same-role components share one input
238
- * contract. Anything only some of them honor (`maxlength`, `size`, `enterPressed`, …) stays on the
239
- * component, never here.
237
+ * Holds only what all of them honor: the value, the control `id` with its generated fallback, the
238
+ * invalid flag, the feedback texts and the `class` passthrough. Anything a subset can't support —
239
+ * `placeholder`, `readonly`, `required`, `name`, `autocomplete`, which `brn-input-otp` doesn't
240
+ * forward to its native input — lives one level down, per the Liskov rule in `AGENTS.md`.
240
241
  *
241
242
  * Subclasses provide `_autoId`, the fallback `id` used when the consumer sets no `inputId`.
242
243
  */
243
- class YuwTextFieldBase extends YuwValueAccessorBase {
244
+ class YuwFieldBase extends YuwValueAccessorBase {
244
245
  constructor() {
245
246
  super(...arguments);
246
- this.autocomplete = input(undefined, ...(ngDevMode ? [{ debugName: "autocomplete" }] : /* istanbul ignore next */ []));
247
247
  this.errorText = input(undefined, ...(ngDevMode ? [{ debugName: "errorText" }] : /* istanbul ignore next */ []));
248
248
  this.helperText = input(undefined, ...(ngDevMode ? [{ debugName: "helperText" }] : /* istanbul ignore next */ []));
249
249
  this.inputId = input(undefined, ...(ngDevMode ? [{ debugName: "inputId" }] : /* istanbul ignore next */ []));
250
250
  this.invalid = input(false, { ...(ngDevMode ? { debugName: "invalid" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
251
- this.name = input(undefined, ...(ngDevMode ? [{ debugName: "name" }] : /* istanbul ignore next */ []));
252
- this.placeholder = input(undefined, ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
253
- this.readonly = input(false, { ...(ngDevMode ? { debugName: "readonly" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
254
- this.required = input(false, { ...(ngDevMode ? { debugName: "required" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
255
251
  this.userClass = input('', { ...(ngDevMode ? { debugName: "userClass" } : /* istanbul ignore next */ {}), alias: 'class' });
256
252
  this.value = model('', ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
257
- this.committed = output();
258
253
  this._inputId = computed(() => this.inputId() ?? this._autoId, ...(ngDevMode ? [{ debugName: "_inputId" }] : /* istanbul ignore next */ []));
259
254
  }
260
255
  _emptyValue() {
261
256
  return '';
262
257
  }
258
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwFieldBase, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
259
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.22", type: YuwFieldBase, isStandalone: true, inputs: { errorText: { classPropertyName: "errorText", publicName: "errorText", 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 }, 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" }, usesInheritance: true, ngImport: i0 }); }
260
+ }
261
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwFieldBase, decorators: [{
262
+ type: Directive,
263
+ args: [{}]
264
+ }], propDecorators: { errorText: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorText", 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 }] }], 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"] }] } });
265
+
266
+ /**
267
+ * Shared surface of the single-value text controls (`yuw-input`, `yuw-password-input`,
268
+ * `yuw-textarea`, `yuw-search-input`).
269
+ *
270
+ * Adds to `YuwFieldBase` the native text-input attributes all four forward, plus `committed`, so
271
+ * the controls can't drift apart — the Liskov rule in `AGENTS.md`: same-role components share one
272
+ * input contract. Anything only some of them honor (`maxlength`, `size`, `enterPressed`, …) stays
273
+ * on the component, never here.
274
+ */
275
+ class YuwTextFieldBase extends YuwFieldBase {
276
+ constructor() {
277
+ super(...arguments);
278
+ this.autocomplete = input(undefined, ...(ngDevMode ? [{ debugName: "autocomplete" }] : /* istanbul ignore next */ []));
279
+ this.name = input(undefined, ...(ngDevMode ? [{ debugName: "name" }] : /* istanbul ignore next */ []));
280
+ this.placeholder = input(undefined, ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
281
+ this.readonly = input(false, { ...(ngDevMode ? { debugName: "readonly" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
282
+ this.required = input(false, { ...(ngDevMode ? { debugName: "required" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
283
+ this.committed = output();
284
+ }
263
285
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwTextFieldBase, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
264
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.22", type: YuwTextFieldBase, isStandalone: true, inputs: { autocomplete: { classPropertyName: "autocomplete", publicName: "autocomplete", isSignal: true, isRequired: false, transformFunction: null }, errorText: { classPropertyName: "errorText", publicName: "errorText", 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 }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", 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", committed: "committed" }, usesInheritance: true, ngImport: i0 }); }
286
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.22", type: YuwTextFieldBase, isStandalone: true, inputs: { autocomplete: { classPropertyName: "autocomplete", publicName: "autocomplete", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { committed: "committed" }, usesInheritance: true, ngImport: i0 }); }
265
287
  }
266
288
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwTextFieldBase, decorators: [{
267
289
  type: Directive,
268
290
  args: [{}]
269
- }], propDecorators: { autocomplete: [{ type: i0.Input, args: [{ isSignal: true, alias: "autocomplete", required: false }] }], errorText: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorText", 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 }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", 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"] }], committed: [{ type: i0.Output, args: ["committed"] }] } });
291
+ }], propDecorators: { autocomplete: [{ type: i0.Input, args: [{ isSignal: true, alias: "autocomplete", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], committed: [{ type: i0.Output, args: ["committed"] }] } });
292
+
293
+ const YUW_DEFAULT_PAGE_SIZE = 20;
294
+ /** `pageIndex` returns to 0 whenever `pageSize` or any of `resetSignals` changes. */
295
+ function createPagination(pageSize, ...resetSignals) {
296
+ return linkedSignal(() => {
297
+ const size = pageSize();
298
+ resetSignals.forEach((resetSignal) => resetSignal());
299
+ return {
300
+ pageIndex: 0,
301
+ pageSize: typeof size === 'string' ? Number(size) : YUW_DEFAULT_PAGE_SIZE,
302
+ };
303
+ });
304
+ }
305
+
306
+ /** Starts with the current value of `source`; must be created in an injection context. */
307
+ function debouncedSignal(source, ms) {
308
+ return toSignal(toObservable(source).pipe(debounceTime(ms), distinctUntilChanged()), {
309
+ initialValue: source(),
310
+ });
311
+ }
312
+
313
+ const PAGE_SIZES = [200, 100, 50, 20, 10];
314
+ const SEARCH_DEBOUNCE_MS = 300;
315
+ /**
316
+ * State of a list paged at the source and the query derived from it. Changing search, filters,
317
+ * sorting or size returns to the first page within the same query; a total below the current page
318
+ * steps back to the last existing one. Must be created in an injection context.
319
+ */
320
+ function createPagedList(options) {
321
+ const initialSize = options.pageSize ?? YUW_DEFAULT_PAGE_SIZE;
322
+ const searchTerm = signal('', ...(ngDevMode ? [{ debugName: "searchTerm" }] : /* istanbul ignore next */ []));
323
+ const pageSize = signal(String(initialSize), ...(ngDevMode ? [{ debugName: "pageSize" }] : /* istanbul ignore next */ []));
324
+ const sorting = signal([], ...(ngDevMode ? [{ debugName: "sorting" }] : /* istanbul ignore next */ []));
325
+ const search = debouncedSignal(searchTerm, SEARCH_DEBOUNCE_MS);
326
+ const pagination = createPagination(pageSize, options.filters, search, sorting);
327
+ const query = computed(() => {
328
+ const { pageIndex, pageSize: limit } = pagination();
329
+ const [sort] = sorting();
330
+ return {
331
+ offset: pageIndex * limit,
332
+ limit,
333
+ search: search().trim(),
334
+ filters: options.filters(),
335
+ sort: sort ? { field: sort.id, direction: sort.desc ? 'desc' : 'asc' } : undefined,
336
+ };
337
+ }, { ...(ngDevMode ? { debugName: "query" } : /* istanbul ignore next */ {}), equal: (left, right) => JSON.stringify(left) === JSON.stringify(right) });
338
+ const totalPages = computed(() => Math.max(1, Math.ceil(options.total() / pagination().pageSize)), ...(ngDevMode ? [{ debugName: "totalPages" }] : /* istanbul ignore next */ []));
339
+ const range = computed(() => {
340
+ const { pageIndex, pageSize: size } = pagination();
341
+ const total = options.total();
342
+ return {
343
+ start: total === 0 ? 0 : pageIndex * size + 1,
344
+ end: Math.min((pageIndex + 1) * size, total),
345
+ total,
346
+ };
347
+ }, ...(ngDevMode ? [{ debugName: "range" }] : /* istanbul ignore next */ []));
348
+ effect(() => {
349
+ const current = query();
350
+ untracked(() => options.load(current));
351
+ });
352
+ effect(() => {
353
+ const lastPageIndex = totalPages() - 1;
354
+ if (untracked(pagination).pageIndex > lastPageIndex && options.total() > 0) {
355
+ pagination.update((state) => ({ ...state, pageIndex: lastPageIndex }));
356
+ }
357
+ });
358
+ return {
359
+ searchTerm,
360
+ pageSize,
361
+ pageSizeOptions: [...new Set([...PAGE_SIZES, initialSize])]
362
+ .sort((left, right) => right - left)
363
+ .map((size) => ({ value: String(size), label: String(size) })),
364
+ sorting,
365
+ pagination,
366
+ query,
367
+ page: computed(() => pagination().pageIndex + 1),
368
+ totalPages,
369
+ range,
370
+ goToPage: (page) => pagination.update((state) => ({ ...state, pageIndex: page - 1 })),
371
+ };
372
+ }
270
373
 
271
374
  /**
272
375
  * yukit-web's own class layer for `<yuw-button>`, applied on top of the helm `buttonVariants()`
@@ -607,6 +710,36 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
607
710
  args: [{ selector: 'yuw-breadcrumb', imports: [...HlmBreadcrumbImports], changeDetection: ChangeDetectionStrategy.OnPush, template: "<nav hlmBreadcrumb [aria-label]=\"ariaLabel()\">\n <ol hlmBreadcrumbList>\n @for (item of items(); track $index; let last = $last) {\n <li hlmBreadcrumbItem>\n @if (last) {\n <span hlmBreadcrumbPage>{{ item.label }}</span>\n } @else if (item.href) {\n <a hlmBreadcrumbLink [link]=\"item.href\">{{ item.label }}</a>\n } @else {\n <span class=\"font-normal\">{{ item.label }}</span>\n }\n </li>\n @if (!last) {\n <li hlmBreadcrumbSeparator>{{ separator() }}</li>\n }\n }\n </ol>\n</nav>\n" }]
608
711
  }], propDecorators: { ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: true }] }], items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: true }] }], separator: [{ type: i0.Input, args: [{ isSignal: true, alias: "separator", required: false }] }] } });
609
712
 
713
+ /**
714
+ * Deepest `data.breadcrumb` along the primary outlet, so a child route overrides its parent. The
715
+ * walk starts at `router.routerState.root` because, as a root service, this is built by whichever
716
+ * routed component asks first, whose own route is not the tree's root.
717
+ */
718
+ class YuwBreadcrumbTrailService {
719
+ constructor() {
720
+ this.router = inject(Router);
721
+ this.crumbs = toSignal(this.router.events.pipe(filter((event) => event instanceof NavigationEnd), startWith(null), map(() => this.resolveDeepestTrail())), { initialValue: [] });
722
+ }
723
+ resolveDeepestTrail() {
724
+ let route = this.router.routerState.root;
725
+ let trail = [];
726
+ while (route) {
727
+ const declared = route.snapshot?.data['breadcrumb'];
728
+ if (declared?.length) {
729
+ trail = declared;
730
+ }
731
+ route = route.firstChild;
732
+ }
733
+ return trail;
734
+ }
735
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwBreadcrumbTrailService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
736
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwBreadcrumbTrailService, providedIn: 'root' }); }
737
+ }
738
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwBreadcrumbTrailService, decorators: [{
739
+ type: Injectable,
740
+ args: [{ providedIn: 'root' }]
741
+ }] });
742
+
610
743
  /**
611
744
  * Pure function on purpose: the page-range math has nothing to do with Angular, so it's testable
612
745
  * in isolation and keeps `pagination.component.ts` limited to wiring inputs/outputs.
@@ -670,14 +803,14 @@ class YuwPaginationComponent {
670
803
  this.page.set(target);
671
804
  }
672
805
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwPaginationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
673
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: YuwPaginationComponent, isStandalone: true, selector: "yuw-pagination", inputs: { ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: true, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, ellipsisSrText: { classPropertyName: "ellipsisSrText", publicName: "ellipsisSrText", isSignal: true, isRequired: true, transformFunction: null }, nextLabel: { classPropertyName: "nextLabel", publicName: "nextLabel", isSignal: true, isRequired: true, transformFunction: null }, page: { classPropertyName: "page", publicName: "page", isSignal: true, isRequired: true, transformFunction: null }, previousLabel: { classPropertyName: "previousLabel", publicName: "previousLabel", isSignal: true, isRequired: true, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, totalPages: { classPropertyName: "totalPages", publicName: "totalPages", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { page: "pageChange" }, host: { properties: { "attr.data-yuw-color": "color()" }, classAttribute: "contents" }, providers: [provideIcons({ lucideChevronLeft, lucideChevronRight })], ngImport: i0, template: "<nav hlmPagination [aria-label]=\"ariaLabel()\">\n <ul hlmPaginationContent>\n <li hlmPaginationItem>\n <button\n type=\"button\"\n hlmPaginationLink\n [size]=\"size()\"\n [disabled]=\"page() <= 1\"\n [attr.aria-label]=\"previousLabel()\"\n (click)=\"goTo(page() - 1)\"\n >\n <ng-icon name=\"lucideChevronLeft\" class=\"rtl:rotate-180\" />\n </button>\n </li>\n\n @for (entry of range(); track $index) {\n <li hlmPaginationItem>\n @if (entry === 'ellipsis') {\n <hlm-pagination-ellipsis [srOnlyText]=\"ellipsisSrText()\" />\n } @else if (entry === page()) {\n <button\n type=\"button\"\n hlmPaginationLink\n isActive\n [size]=\"size()\"\n class=\"border-transparent bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground dark:border-transparent dark:bg-primary dark:hover:bg-primary\"\n (click)=\"goTo(entry)\"\n >\n {{ entry }}\n </button>\n } @else {\n <button type=\"button\" hlmPaginationLink [size]=\"size()\" (click)=\"goTo(entry)\">\n {{ entry }}\n </button>\n }\n </li>\n }\n\n <li hlmPaginationItem>\n <button\n type=\"button\"\n hlmPaginationLink\n [size]=\"size()\"\n [disabled]=\"page() >= totalPages()\"\n [attr.aria-label]=\"nextLabel()\"\n (click)=\"goTo(page() + 1)\"\n >\n <ng-icon name=\"lucideChevronRight\" class=\"rtl:rotate-180\" />\n </button>\n </li>\n </ul>\n</nav>\n", dependencies: [{ kind: "directive", type: HlmPagination, selector: "[hlmPagination],hlm-pagination", inputs: ["aria-label"] }, { kind: "directive", type: HlmPaginationContent, selector: "ul[hlmPaginationContent]" }, { kind: "directive", type: HlmPaginationItem, selector: "li[hlmPaginationItem]" }, { kind: "directive", type: HlmPaginationLink, selector: "[hlmPaginationLink]", inputs: ["isActive", "size", "link"] }, { kind: "component", type: HlmPaginationEllipsis, selector: "hlm-pagination-ellipsis", inputs: ["srOnlyText"] }, { kind: "component", type: NgIcon, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
806
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: YuwPaginationComponent, isStandalone: true, selector: "yuw-pagination", inputs: { ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: true, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, ellipsisSrText: { classPropertyName: "ellipsisSrText", publicName: "ellipsisSrText", isSignal: true, isRequired: true, transformFunction: null }, nextLabel: { classPropertyName: "nextLabel", publicName: "nextLabel", isSignal: true, isRequired: true, transformFunction: null }, page: { classPropertyName: "page", publicName: "page", isSignal: true, isRequired: true, transformFunction: null }, previousLabel: { classPropertyName: "previousLabel", publicName: "previousLabel", isSignal: true, isRequired: true, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, totalPages: { classPropertyName: "totalPages", publicName: "totalPages", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { page: "pageChange" }, host: { properties: { "attr.data-yuw-color": "color()" }, classAttribute: "contents" }, providers: [provideIcons({ lucideChevronLeft, lucideChevronRight })], ngImport: i0, template: "<nav hlmPagination [aria-label]=\"ariaLabel()\">\n <ul hlmPaginationContent>\n <li hlmPaginationItem>\n <yuw-button\n variant=\"ghost\"\n [color]=\"color()\"\n [size]=\"size()\"\n [disabled]=\"page() <= 1\"\n [ariaLabel]=\"previousLabel()\"\n (clicked)=\"goTo(page() - 1)\"\n >\n <ng-icon name=\"lucideChevronLeft\" class=\"rtl:rotate-180\" />\n </yuw-button>\n </li>\n\n @for (entry of range(); track $index) {\n <li hlmPaginationItem>\n @if (entry === 'ellipsis') {\n <hlm-pagination-ellipsis [srOnlyText]=\"ellipsisSrText()\" />\n } @else if (entry === page()) {\n <yuw-button [color]=\"color()\" [size]=\"size()\" aria-current=\"page\" (clicked)=\"goTo(entry)\">\n {{ entry }}\n </yuw-button>\n } @else {\n <yuw-button variant=\"ghost\" [color]=\"color()\" [size]=\"size()\" (clicked)=\"goTo(entry)\">\n {{ entry }}\n </yuw-button>\n }\n </li>\n }\n\n <li hlmPaginationItem>\n <yuw-button\n variant=\"ghost\"\n [color]=\"color()\"\n [size]=\"size()\"\n [disabled]=\"page() >= totalPages()\"\n [ariaLabel]=\"nextLabel()\"\n (clicked)=\"goTo(page() + 1)\"\n >\n <ng-icon name=\"lucideChevronRight\" class=\"rtl:rotate-180\" />\n </yuw-button>\n </li>\n </ul>\n</nav>\n", dependencies: [{ kind: "directive", type: HlmPagination, selector: "[hlmPagination],hlm-pagination", inputs: ["aria-label"] }, { kind: "directive", type: HlmPaginationContent, selector: "ul[hlmPaginationContent]" }, { kind: "directive", type: HlmPaginationItem, selector: "li[hlmPaginationItem]" }, { kind: "component", type: HlmPaginationEllipsis, selector: "hlm-pagination-ellipsis", inputs: ["srOnlyText"] }, { 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 }); }
674
807
  }
675
808
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwPaginationComponent, decorators: [{
676
809
  type: Component,
677
- args: [{ selector: 'yuw-pagination', imports: [HlmPagination, HlmPaginationContent, HlmPaginationItem, HlmPaginationLink, HlmPaginationEllipsis, NgIcon], providers: [provideIcons({ lucideChevronLeft, lucideChevronRight })], host: {
810
+ args: [{ selector: 'yuw-pagination', imports: [HlmPagination, HlmPaginationContent, HlmPaginationItem, HlmPaginationEllipsis, NgIcon, YuwButtonComponent], providers: [provideIcons({ lucideChevronLeft, lucideChevronRight })], host: {
678
811
  class: 'contents',
679
812
  '[attr.data-yuw-color]': 'color()',
680
- }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<nav hlmPagination [aria-label]=\"ariaLabel()\">\n <ul hlmPaginationContent>\n <li hlmPaginationItem>\n <button\n type=\"button\"\n hlmPaginationLink\n [size]=\"size()\"\n [disabled]=\"page() <= 1\"\n [attr.aria-label]=\"previousLabel()\"\n (click)=\"goTo(page() - 1)\"\n >\n <ng-icon name=\"lucideChevronLeft\" class=\"rtl:rotate-180\" />\n </button>\n </li>\n\n @for (entry of range(); track $index) {\n <li hlmPaginationItem>\n @if (entry === 'ellipsis') {\n <hlm-pagination-ellipsis [srOnlyText]=\"ellipsisSrText()\" />\n } @else if (entry === page()) {\n <button\n type=\"button\"\n hlmPaginationLink\n isActive\n [size]=\"size()\"\n class=\"border-transparent bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground dark:border-transparent dark:bg-primary dark:hover:bg-primary\"\n (click)=\"goTo(entry)\"\n >\n {{ entry }}\n </button>\n } @else {\n <button type=\"button\" hlmPaginationLink [size]=\"size()\" (click)=\"goTo(entry)\">\n {{ entry }}\n </button>\n }\n </li>\n }\n\n <li hlmPaginationItem>\n <button\n type=\"button\"\n hlmPaginationLink\n [size]=\"size()\"\n [disabled]=\"page() >= totalPages()\"\n [attr.aria-label]=\"nextLabel()\"\n (click)=\"goTo(page() + 1)\"\n >\n <ng-icon name=\"lucideChevronRight\" class=\"rtl:rotate-180\" />\n </button>\n </li>\n </ul>\n</nav>\n" }]
813
+ }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<nav hlmPagination [aria-label]=\"ariaLabel()\">\n <ul hlmPaginationContent>\n <li hlmPaginationItem>\n <yuw-button\n variant=\"ghost\"\n [color]=\"color()\"\n [size]=\"size()\"\n [disabled]=\"page() <= 1\"\n [ariaLabel]=\"previousLabel()\"\n (clicked)=\"goTo(page() - 1)\"\n >\n <ng-icon name=\"lucideChevronLeft\" class=\"rtl:rotate-180\" />\n </yuw-button>\n </li>\n\n @for (entry of range(); track $index) {\n <li hlmPaginationItem>\n @if (entry === 'ellipsis') {\n <hlm-pagination-ellipsis [srOnlyText]=\"ellipsisSrText()\" />\n } @else if (entry === page()) {\n <yuw-button [color]=\"color()\" [size]=\"size()\" aria-current=\"page\" (clicked)=\"goTo(entry)\">\n {{ entry }}\n </yuw-button>\n } @else {\n <yuw-button variant=\"ghost\" [color]=\"color()\" [size]=\"size()\" (clicked)=\"goTo(entry)\">\n {{ entry }}\n </yuw-button>\n }\n </li>\n }\n\n <li hlmPaginationItem>\n <yuw-button\n variant=\"ghost\"\n [color]=\"color()\"\n [size]=\"size()\"\n [disabled]=\"page() >= totalPages()\"\n [ariaLabel]=\"nextLabel()\"\n (clicked)=\"goTo(page() + 1)\"\n >\n <ng-icon name=\"lucideChevronRight\" class=\"rtl:rotate-180\" />\n </yuw-button>\n </li>\n </ul>\n</nav>\n" }]
681
814
  }], propDecorators: { ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: true }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], ellipsisSrText: [{ type: i0.Input, args: [{ isSignal: true, alias: "ellipsisSrText", required: true }] }], nextLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "nextLabel", required: true }] }], page: [{ type: i0.Input, args: [{ isSignal: true, alias: "page", required: true }] }, { type: i0.Output, args: ["pageChange"] }], previousLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "previousLabel", required: true }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], totalPages: [{ type: i0.Input, args: [{ isSignal: true, alias: "totalPages", required: true }] }] } });
682
815
 
683
816
  /**
@@ -870,6 +1003,74 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
870
1003
  }, 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 [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" }]
871
1004
  }], propDecorators: { _panel: [{ type: i0.ViewChild, args: [i0.forwardRef(() => HlmComboboxContent), { ...{ read: ElementRef }, 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 }] }], 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"] }] } });
872
1005
 
1006
+ /** Page size selector and range message of a `YuwPagedList`; in a datatable it takes the pagination slot. */
1007
+ class YuwPageSizeComponent {
1008
+ constructor() {
1009
+ this.disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
1010
+ this.labels = input.required(...(ngDevMode ? [{ debugName: "labels" }] : /* istanbul ignore next */ []));
1011
+ this.list = input.required(...(ngDevMode ? [{ debugName: "list" }] : /* istanbul ignore next */ []));
1012
+ this.message = computed(() => this.labels().range(this.list().range()), ...(ngDevMode ? [{ debugName: "message" }] : /* istanbul ignore next */ []));
1013
+ }
1014
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwPageSizeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1015
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.22", type: YuwPageSizeComponent, isStandalone: true, selector: "yuw-page-size", inputs: { disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, labels: { classPropertyName: "labels", publicName: "labels", isSignal: true, isRequired: true, transformFunction: null }, list: { classPropertyName: "list", publicName: "list", isSignal: true, isRequired: true, transformFunction: null } }, host: { classAttribute: "flex items-center gap-2" }, ngImport: i0, 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", dependencies: [{ kind: "component", type: YuwComboboxComponent, selector: "yuw-combobox", inputs: ["clearAriaLabel", "emptyText", "inputId", "invalid", "multiple", "options", "placeholder", "readonlyTrigger", "search", "searchPlaceholder", "size", "triggerAriaLabel", "value"], outputs: ["searchChange", "valueChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1016
+ }
1017
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwPageSizeComponent, decorators: [{
1018
+ type: Component,
1019
+ 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" }]
1020
+ }], 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 }] }] } });
1021
+
1022
+ /** Pagination footer for lists without a datatable. A disabled `fieldset` blocks its buttons. */
1023
+ class YuwListPaginationComponent {
1024
+ constructor() {
1025
+ this.disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
1026
+ this.labels = input.required(...(ngDevMode ? [{ debugName: "labels" }] : /* istanbul ignore next */ []));
1027
+ this.list = input.required(...(ngDevMode ? [{ debugName: "list" }] : /* istanbul ignore next */ []));
1028
+ }
1029
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwListPaginationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1030
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.22", type: YuwListPaginationComponent, isStandalone: true, selector: "yuw-list-pagination", inputs: { disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, labels: { classPropertyName: "labels", publicName: "labels", isSignal: true, isRequired: true, transformFunction: null }, list: { classPropertyName: "list", publicName: "list", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<fieldset class=\"flex flex-wrap items-center justify-between gap-3\" [disabled]=\"disabled()\">\n <yuw-page-size [list]=\"list()\" [labels]=\"labels().pageSize\" [disabled]=\"disabled()\" />\n <yuw-pagination\n [page]=\"list().page()\"\n [totalPages]=\"list().totalPages()\"\n [ariaLabel]=\"labels().ariaLabel\"\n [previousLabel]=\"labels().previous\"\n [nextLabel]=\"labels().next\"\n [ellipsisSrText]=\"labels().ellipsis\"\n (pageChange)=\"list().goToPage($event)\"\n />\n</fieldset>\n", dependencies: [{ kind: "component", type: YuwPageSizeComponent, selector: "yuw-page-size", inputs: ["disabled", "labels", "list"] }, { kind: "component", type: YuwPaginationComponent, selector: "yuw-pagination", inputs: ["ariaLabel", "color", "ellipsisSrText", "nextLabel", "page", "previousLabel", "size", "totalPages"], outputs: ["pageChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1031
+ }
1032
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwListPaginationComponent, decorators: [{
1033
+ type: Component,
1034
+ args: [{ selector: 'yuw-list-pagination', changeDetection: ChangeDetectionStrategy.OnPush, imports: [YuwPageSizeComponent, YuwPaginationComponent], template: "<fieldset class=\"flex flex-wrap items-center justify-between gap-3\" [disabled]=\"disabled()\">\n <yuw-page-size [list]=\"list()\" [labels]=\"labels().pageSize\" [disabled]=\"disabled()\" />\n <yuw-pagination\n [page]=\"list().page()\"\n [totalPages]=\"list().totalPages()\"\n [ariaLabel]=\"labels().ariaLabel\"\n [previousLabel]=\"labels().previous\"\n [nextLabel]=\"labels().next\"\n [ellipsisSrText]=\"labels().ellipsis\"\n (pageChange)=\"list().goToPage($event)\"\n />\n</fieldset>\n" }]
1035
+ }], 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 }] }] } });
1036
+
1037
+ const DESKTOP_QUERY = '(min-width: 48rem)';
1038
+ /** True below `md`. Must be called in an injection context. */
1039
+ function injectIsMobile() {
1040
+ const breakpointObserver = inject(BreakpointObserver);
1041
+ return toSignal(breakpointObserver.observe(DESKTOP_QUERY).pipe(map((state) => !state.matches)), {
1042
+ initialValue: !breakpointObserver.isMatched(DESKTOP_QUERY),
1043
+ });
1044
+ }
1045
+
1046
+ /**
1047
+ * Page title, optional description and up to two actions, each rendered when its label is set.
1048
+ * On mobile the primary action shows only its icon, or `primaryMobileLabel`. Icons are `@ng-icons`
1049
+ * names; the consumer registers any beyond `lucidePlus` with `provideIcons`.
1050
+ */
1051
+ class YuwPageHeaderComponent {
1052
+ constructor() {
1053
+ this.backLabel = input(...(ngDevMode ? [undefined, { debugName: "backLabel" }] : /* istanbul ignore next */ []));
1054
+ this.description = input(...(ngDevMode ? [undefined, { debugName: "description" }] : /* istanbul ignore next */ []));
1055
+ this.primaryIcon = input(...(ngDevMode ? [undefined, { debugName: "primaryIcon" }] : /* istanbul ignore next */ []));
1056
+ this.primaryLabel = input(...(ngDevMode ? [undefined, { debugName: "primaryLabel" }] : /* istanbul ignore next */ []));
1057
+ this.primaryMobileLabel = input(...(ngDevMode ? [undefined, { debugName: "primaryMobileLabel" }] : /* istanbul ignore next */ []));
1058
+ this.secondaryIcon = input(...(ngDevMode ? [undefined, { debugName: "secondaryIcon" }] : /* istanbul ignore next */ []));
1059
+ this.secondaryLabel = input(...(ngDevMode ? [undefined, { debugName: "secondaryLabel" }] : /* istanbul ignore next */ []));
1060
+ this.title = input.required(...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
1061
+ this.backClicked = output();
1062
+ this.primaryClicked = output();
1063
+ this.secondaryClicked = output();
1064
+ this.isMobile = injectIsMobile();
1065
+ }
1066
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwPageHeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1067
+ 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 }); }
1068
+ }
1069
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwPageHeaderComponent, decorators: [{
1070
+ type: Component,
1071
+ 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" }]
1072
+ }], 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"] }] } });
1073
+
873
1074
  /**
874
1075
  * Container directive for collapsible accordion items.
875
1076
  *
@@ -1684,32 +1885,22 @@ let nextYuwInputOtpId = 0;
1684
1885
  * <yuw-input-otp formControlName="otpCode" [groupSizes]="[6]" mode="numeric" />
1685
1886
  * ```
1686
1887
  */
1687
- class YuwInputOtpComponent extends YuwValueAccessorBase {
1888
+ class YuwInputOtpComponent extends YuwFieldBase {
1688
1889
  constructor() {
1689
1890
  super(...arguments);
1690
1891
  this.autofocus = input(false, { ...(ngDevMode ? { debugName: "autofocus" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
1691
- this.errorText = input(undefined, ...(ngDevMode ? [{ debugName: "errorText" }] : /* istanbul ignore next */ []));
1692
1892
  this.groupSizes = input([6], ...(ngDevMode ? [{ debugName: "groupSizes" }] : /* istanbul ignore next */ []));
1693
- this.helperText = input(undefined, ...(ngDevMode ? [{ debugName: "helperText" }] : /* istanbul ignore next */ []));
1694
- this.inputId = input(undefined, ...(ngDevMode ? [{ debugName: "inputId" }] : /* istanbul ignore next */ []));
1695
- this.invalid = input(false, { ...(ngDevMode ? { debugName: "invalid" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
1696
1893
  this.mode = input('numeric', ...(ngDevMode ? [{ debugName: "mode" }] : /* istanbul ignore next */ []));
1697
1894
  this.size = input('default', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
1698
1895
  this.transformPaste = input((pastedText) => pastedText, ...(ngDevMode ? [{ debugName: "transformPaste" }] : /* istanbul ignore next */ []));
1699
- this.userClass = input('', { ...(ngDevMode ? { debugName: "userClass" } : /* istanbul ignore next */ {}), alias: 'class' });
1700
- this.value = model('', ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
1701
1896
  this.completed = output();
1702
1897
  this.enterPressed = output();
1703
1898
  this._autoId = `yuw-input-otp-${++nextYuwInputOtpId}`;
1704
1899
  this._focusSelectors = ['input'];
1705
1900
  this._classes = computed(() => cn(yuwInputOtpSizeVariants({ size: this.size() }), this.userClass()), ...(ngDevMode ? [{ debugName: "_classes" }] : /* istanbul ignore next */ []));
1706
1901
  this._groups = computed(() => buildInputOtpGroups(this.groupSizes()), ...(ngDevMode ? [{ debugName: "_groups" }] : /* istanbul ignore next */ []));
1707
- this._inputId = computed(() => this.inputId() ?? this._autoId, ...(ngDevMode ? [{ debugName: "_inputId" }] : /* istanbul ignore next */ []));
1708
1902
  this._length = computed(() => totalInputOtpLength(this.groupSizes()), ...(ngDevMode ? [{ debugName: "_length" }] : /* istanbul ignore next */ []));
1709
1903
  }
1710
- _emptyValue() {
1711
- return '';
1712
- }
1713
1904
  onEnterPressed() {
1714
1905
  this.enterPressed.emit();
1715
1906
  }
@@ -1717,14 +1908,14 @@ class YuwInputOtpComponent extends YuwValueAccessorBase {
1717
1908
  this._commit(next);
1718
1909
  }
1719
1910
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwInputOtpComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
1720
- 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 }, errorText: { classPropertyName: "errorText", publicName: "errorText", isSignal: true, isRequired: false, transformFunction: null }, groupSizes: { classPropertyName: "groupSizes", publicName: "groupSizes", 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 }, 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 }, 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", 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$4.HlmInputOtp, selector: "brn-input-otp[hlmInputOtp], brn-input-otp[hlm]" }, { kind: "directive", type: i1$4.HlmInputOtpGroup, selector: "[hlmInputOtpGroup],hlm-input-otp-group" }, { kind: "component", type: i1$4.HlmInputOtpSeparator, selector: "hlm-input-otp-separator" }, { kind: "component", type: i1$4.HlmInputOtpSlot, selector: "hlm-input-otp-slot", inputs: ["index", "forceInvalid"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1911
+ 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$4.HlmInputOtp, selector: "brn-input-otp[hlmInputOtp], brn-input-otp[hlm]" }, { kind: "directive", type: i1$4.HlmInputOtpGroup, selector: "[hlmInputOtpGroup],hlm-input-otp-group" }, { kind: "component", type: i1$4.HlmInputOtpSeparator, selector: "hlm-input-otp-separator" }, { kind: "component", type: i1$4.HlmInputOtpSlot, selector: "hlm-input-otp-slot", inputs: ["index", "forceInvalid"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1721
1912
  }
1722
1913
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwInputOtpComponent, decorators: [{
1723
1914
  type: Component,
1724
1915
  args: [{ selector: 'yuw-input-otp', imports: [HlmField, HlmFieldDescription, YuwFieldFeedbackDirective, BrnInputOtp, ...HlmInputOtpImports], providers: [provideValueAccessor(YuwInputOtpComponent)], host: {
1725
1916
  class: 'contents',
1726
1917
  }, changeDetection: ChangeDetectionStrategy.OnPush, 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" }]
1727
- }], propDecorators: { autofocus: [{ type: i0.Input, args: [{ isSignal: true, alias: "autofocus", required: false }] }], errorText: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorText", required: false }] }], groupSizes: [{ type: i0.Input, args: [{ isSignal: true, alias: "groupSizes", 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 }] }], mode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mode", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], transformPaste: [{ type: i0.Input, args: [{ isSignal: true, alias: "transformPaste", 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"] }], completed: [{ type: i0.Output, args: ["completed"] }], enterPressed: [{ type: i0.Output, args: ["enterPressed"] }] } });
1918
+ }], propDecorators: { autofocus: [{ type: i0.Input, args: [{ isSignal: true, alias: "autofocus", required: false }] }], groupSizes: [{ type: i0.Input, args: [{ isSignal: true, alias: "groupSizes", required: false }] }], mode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mode", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], transformPaste: [{ type: i0.Input, args: [{ isSignal: true, alias: "transformPaste", required: false }] }], completed: [{ type: i0.Output, args: ["completed"] }], enterPressed: [{ type: i0.Output, args: ["enterPressed"] }] } });
1728
1919
 
1729
1920
  /**
1730
1921
  * Form label directive applied directly to a native `<label>` element.
@@ -2038,6 +2229,42 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
2038
2229
  }]
2039
2230
  }] });
2040
2231
 
2232
+ /**
2233
+ * Grid of projected cards, usually `yuw-card-grid-item`s in an `@for`. `loading` shows
2234
+ * `skeletonCount` placeholders shaped by `skeletonClass`; `empty` shows `emptyText`; `columnsClass`
2235
+ * holds the Tailwind column utilities.
2236
+ */
2237
+ class YuwCardGridComponent {
2238
+ constructor() {
2239
+ this.columnsClass = input('grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4', ...(ngDevMode ? [{ debugName: "columnsClass" }] : /* istanbul ignore next */ []));
2240
+ this.empty = input(false, { ...(ngDevMode ? { debugName: "empty" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
2241
+ this.emptyText = input.required(...(ngDevMode ? [{ debugName: "emptyText" }] : /* istanbul ignore next */ []));
2242
+ this.loading = input(false, { ...(ngDevMode ? { debugName: "loading" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
2243
+ this.skeletonClass = input('h-16', ...(ngDevMode ? [{ debugName: "skeletonClass" }] : /* istanbul ignore next */ []));
2244
+ this.skeletonCount = input(12, { ...(ngDevMode ? { debugName: "skeletonCount" } : /* istanbul ignore next */ {}), transform: numberAttribute });
2245
+ this.skeletons = computed(() => Array.from({ length: this.skeletonCount() }, (_, index) => index), ...(ngDevMode ? [{ debugName: "skeletons" }] : /* istanbul ignore next */ []));
2246
+ }
2247
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwCardGridComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2248
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: YuwCardGridComponent, isStandalone: true, selector: "yuw-card-grid", inputs: { columnsClass: { classPropertyName: "columnsClass", publicName: "columnsClass", isSignal: true, isRequired: false, transformFunction: null }, empty: { classPropertyName: "empty", publicName: "empty", isSignal: true, isRequired: false, transformFunction: null }, emptyText: { classPropertyName: "emptyText", publicName: "emptyText", isSignal: true, isRequired: true, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, skeletonClass: { classPropertyName: "skeletonClass", publicName: "skeletonClass", isSignal: true, isRequired: false, transformFunction: null }, skeletonCount: { classPropertyName: "skeletonCount", publicName: "skeletonCount", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, 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", dependencies: [{ kind: "directive", type: YuwSkeletonDirective, selector: "[yuwSkeleton]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2249
+ }
2250
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwCardGridComponent, decorators: [{
2251
+ type: Component,
2252
+ 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" }]
2253
+ }], 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 }] }] } });
2254
+
2255
+ /** While `pending` the card stays hidden in place under a skeleton, so the grid does not jump. */
2256
+ class YuwCardGridItemComponent {
2257
+ constructor() {
2258
+ this.pending = input(false, { ...(ngDevMode ? { debugName: "pending" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
2259
+ }
2260
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwCardGridItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2261
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: YuwCardGridItemComponent, isStandalone: true, selector: "yuw-card-grid-item", inputs: { pending: { classPropertyName: "pending", publicName: "pending", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "relative block" }, ngImport: i0, template: "<div class=\"h-full\" [class.invisible]=\"pending()\">\n <ng-content />\n</div>\n\n@if (pending()) {\n <span yuwSkeleton class=\"absolute inset-0 rounded-xl\"></span>\n}\n", dependencies: [{ kind: "directive", type: YuwSkeletonDirective, selector: "[yuwSkeleton]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2262
+ }
2263
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwCardGridItemComponent, decorators: [{
2264
+ type: Component,
2265
+ args: [{ selector: 'yuw-card-grid-item', changeDetection: ChangeDetectionStrategy.OnPush, imports: [YuwSkeletonDirective], host: { class: 'relative block' }, template: "<div class=\"h-full\" [class.invisible]=\"pending()\">\n <ng-content />\n</div>\n\n@if (pending()) {\n <span yuwSkeleton class=\"absolute inset-0 rounded-xl\"></span>\n}\n" }]
2266
+ }], propDecorators: { pending: [{ type: i0.Input, args: [{ isSignal: true, alias: "pending", required: false }] }] } });
2267
+
2041
2268
  /**
2042
2269
  * Container directive for card components.
2043
2270
  * Accepts optional `size` input (e.g. `'default'` or `'sm'`).
@@ -2842,62 +3069,652 @@ const YuwTableImports = [
2842
3069
  YuwDatatablePaginationDirective,
2843
3070
  ];
2844
3071
 
2845
- const YUW_DATATABLE_FEATURES = {
2846
- columnMeta: {},
2847
- columnFilteringFeature,
2848
- columnVisibilityFeature,
2849
- rowPaginationFeature,
2850
- rowSelectionFeature,
2851
- rowSortingFeature,
2852
- };
2853
-
2854
3072
  /**
2855
- * Default floor for a column that opts into `meta.wrap`, as a Tailwind `min-w-*` class.
3073
+ * Makes a `<yuw-button>` the trigger of the surrounding `<yuw-popover>`.
2856
3074
  *
2857
- * This is the only bound a wrapping column needs. It is what makes the responsive behaviour work:
2858
- * below it the table stops shrinking the column — which would end in a column one word wide — and
2859
- * the table's own width exceeds the container instead, so `YuwTableContainer`'s `overflow-x-auto`
2860
- * scrolls horizontally.
3075
+ * The helm trigger directive's selector only matches a native `button`, so composing the brain
3076
+ * directive here is what lets the popover use `<yuw-button>` rather than a bare `[hlmBtn]` element.
3077
+ * Brain needs three things from its host, all of which `<yuw-button>` provides: the `click` that
3078
+ * bubbles up from the inner button, the `aria-expanded`/`data-state` attributes, and a host box to
3079
+ * anchor the panel against — hence `<yuw-button>`'s `inline-flex` host, since a `display: contents`
3080
+ * host has no rect for the overlay to position from.
2861
3081
  *
2862
- * There is deliberately no maximum. A cap would make a wrapping column break onto several lines
2863
- * while the table still had free space beside it, which reads as broken; letting the column take
2864
- * its share of the row means text wraps only once it genuinely no longer fits.
3082
+ * `data-slot` mirrors the helm directive so the popover stylesheet targets both identically.
2865
3083
  */
2866
- const YUW_DATATABLE_WRAP_MIN_WIDTH = 'min-w-48';
3084
+ class YuwPopoverTriggerDirective {
3085
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwPopoverTriggerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
3086
+ 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$d.BrnPopoverTrigger, inputs: ["id", "id", "brnPopoverTriggerFor", "yuwPopoverTriggerFor", "type", "type"] }], ngImport: i0 }); }
3087
+ }
3088
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwPopoverTriggerDirective, decorators: [{
3089
+ type: Directive,
3090
+ args: [{
3091
+ selector: 'yuw-button[yuwPopoverTriggerFor], yuw-button[yuwPopoverTriggerButton]',
3092
+ hostDirectives: [
3093
+ { directive: BrnPopoverTrigger, inputs: ['id', 'brnPopoverTriggerFor: yuwPopoverTriggerFor', 'type'] },
3094
+ ],
3095
+ host: { 'data-slot': 'popover-trigger' },
3096
+ }]
3097
+ }] });
3098
+
2867
3099
  /**
2868
- * Layout classes the `<table>` needs for `meta.wrap` columns to size correctly.
3100
+ * Popover component for displaying anchored floating overlay panels.
2869
3101
  *
2870
- * `w-full` lets the table fill its container so a wrapping column can spread into the free space
2871
- * instead of wrapping early, and `min-w-max` keeps the table at least as wide as its content
2872
- * demands — which is what lets a wrapping column's floor push the table past the container and
2873
- * hand the overflow to the scroll container. Applied unconditionally: for a table with no wrapping
2874
- * column both halves resolve to the width it already had.
3102
+ * Inputs / Models:
3103
+ * - `open`: Two-way open/closed state (`boolean`). Drive directly via `[(open)]` to open/close programmatically.
3104
+ * - `showTrigger`: Whether to render the trigger button. Set `false` when opening only via `[(open)]`.
3105
+ * - `align`: Panel alignment relative to trigger (`'start'`, `'center'`, `'end'`). Default is `'center'`.
3106
+ * - `sideOffset`: Pixel offset between the trigger and the panel. Default is `4`.
3107
+ * - `sideOffset`: Pixel offset for X sides. Positive px for right, negative for left side.
3108
+ * - `title`: Optional header title text. User-facing text the consuming app is responsible for translating.
3109
+ * - `description`: Optional header description text. User-facing text the consuming app is responsible for translating.
3110
+ * - `panelClass`: Extra classes merged onto the popover panel (e.g. `w-80` to widen it). They win
3111
+ * over the library defaults via `twMerge`.
3112
+ * - `triggerVariant`: Button style variant for the trigger button.
3113
+ * - `triggerColor`: Brand color theme for the trigger button (any `YuwColorDto` value). Default is
3114
+ * `'secondary'`.
3115
+ * - `triggerSize`: Button size for the trigger button.
3116
+ * - `triggerTransparent`: Strips the trigger's background and border in every state (rest, hover,
3117
+ * open), for triggers whose projected content is the whole control — an avatar, a name, a chevron.
3118
+ * - `triggerClass`: Extra classes merged onto the trigger button, last, so they beat both the
3119
+ * variant classes and `triggerTransparent` (e.g. `h-auto p-0` to drop the button's own box).
3120
+ *
3121
+ * The trigger is a `<yuw-button>`; `YuwPopoverTriggerDirective` composes the brain trigger onto it,
3122
+ * so the popover reuses our button component instead of applying `[hlmBtn]` directly.
3123
+ *
3124
+ * Usage:
3125
+ * ```html
3126
+ * <yuw-popover [(open)]="isOpen" title="Notifications" description="You're all caught up.">
3127
+ * <ng-container yuwPopoverTrigger>View Notifications</ng-container>
3128
+ *
3129
+ * <p>Popover content body goes here.</p>
3130
+ * </yuw-popover>
3131
+ * ```
2875
3132
  */
2876
- const DATATABLE_LAYOUT_CLASS = 'w-full min-w-max';
3133
+ class YuwPopoverComponent {
3134
+ constructor() {
3135
+ this.align = input('center', ...(ngDevMode ? [{ debugName: "align" }] : /* istanbul ignore next */ []));
3136
+ this.description = input(undefined, ...(ngDevMode ? [{ debugName: "description" }] : /* istanbul ignore next */ []));
3137
+ this.offsetX = input(0, ...(ngDevMode ? [{ debugName: "offsetX" }] : /* istanbul ignore next */ []));
3138
+ this.open = model(false, ...(ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []));
3139
+ this.panelClass = input(undefined, ...(ngDevMode ? [{ debugName: "panelClass" }] : /* istanbul ignore next */ []));
3140
+ this.showTrigger = input(true, { ...(ngDevMode ? { debugName: "showTrigger" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
3141
+ this.sideOffset = input(4, ...(ngDevMode ? [{ debugName: "sideOffset" }] : /* istanbul ignore next */ []));
3142
+ this.title = input(undefined, ...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
3143
+ this.triggerClass = input('', ...(ngDevMode ? [{ debugName: "triggerClass" }] : /* istanbul ignore next */ []));
3144
+ this.triggerColor = input('secondary', ...(ngDevMode ? [{ debugName: "triggerColor" }] : /* istanbul ignore next */ []));
3145
+ this.triggerSize = input('default', ...(ngDevMode ? [{ debugName: "triggerSize" }] : /* istanbul ignore next */ []));
3146
+ this.triggerTransparent = input(false, { ...(ngDevMode ? { debugName: "triggerTransparent" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
3147
+ this.triggerVariant = input('outline', ...(ngDevMode ? [{ debugName: "triggerVariant" }] : /* istanbul ignore next */ []));
3148
+ this._popoverState = computed(() => (this.open() ? 'open' : 'closed'), ...(ngDevMode ? [{ debugName: "_popoverState" }] : /* istanbul ignore next */ []));
3149
+ }
3150
+ onOpenChange(state) {
3151
+ this.open.set(state === 'open');
3152
+ }
3153
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwPopoverComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3154
+ 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" }, ngImport: i0, template: "<div\n hlmPopover\n [state]=\"_popoverState()\"\n [align]=\"align()\"\n [sideOffset]=\"sideOffset()\"\n [offsetX]=\"offsetX()\"\n (stateChanged)=\"onOpenChange($event)\"\n>\n @if (showTrigger()) {\n <yuw-button\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$e.HlmPopover, selector: "[hlmPopover],hlm-popover" }, { kind: "directive", type: i1$e.HlmPopoverContent, selector: "[hlmPopoverContent],hlm-popover-content" }, { kind: "directive", type: i1$e.HlmPopoverDescription, selector: "[hlmPopoverDescription]" }, { kind: "directive", type: i1$e.HlmPopoverHeader, selector: "[hlmPopoverHeader],hlm-popover-header" }, { kind: "directive", type: i1$e.HlmPopoverPortal, selector: "[hlmPopoverPortal]" }, { kind: "directive", type: i1$e.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 }); }
3155
+ }
3156
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwPopoverComponent, decorators: [{
3157
+ type: Component,
3158
+ args: [{ selector: 'yuw-popover', imports: [...HlmPopoverImports, YuwButtonComponent, YuwPopoverTriggerDirective], host: {
3159
+ class: 'contents',
3160
+ }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n hlmPopover\n [state]=\"_popoverState()\"\n [align]=\"align()\"\n [sideOffset]=\"sideOffset()\"\n [offsetX]=\"offsetX()\"\n (stateChanged)=\"onOpenChange($event)\"\n>\n @if (showTrigger()) {\n <yuw-button\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" }]
3161
+ }], propDecorators: { 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 }] }] } });
3162
+
2877
3163
  /**
2878
- * Class maps for `yuw-datatable`, layered on top of the Hlm table directives' own classes.
2879
- *
2880
- * `DATATABLE_ALIGN_CLASS` is keyed by a column's `meta.align` and shared by header and body cells,
2881
- * so a column declares its alignment once and both honour it; `start` maps to an empty string
2882
- * rather than re-stating what `HlmTh`/`HlmTd` already apply.
3164
+ * Action row of `yuw-list-toolbar`: search, export and column visibility, each rendered only when
3165
+ * its input is set. Below `md` the search collapses into a popover; both widths bind the same
3166
+ * `search` model and carry their own `yuw-search-input` because the popover anchors to the element
3167
+ * holding `yuwPopoverTrigger`.
3168
+ */
3169
+ class YuwListToolbarActionsComponent {
3170
+ constructor() {
3171
+ this.hideableColumns = input(...(ngDevMode ? [undefined, { debugName: "hideableColumns" }] : /* istanbul ignore next */ []));
3172
+ this.isMobile = input.required(...(ngDevMode ? [{ debugName: "isMobile" }] : /* istanbul ignore next */ []));
3173
+ this.labels = input.required(...(ngDevMode ? [{ debugName: "labels" }] : /* istanbul ignore next */ []));
3174
+ this.search = model('', ...(ngDevMode ? [{ debugName: "search" }] : /* istanbul ignore next */ []));
3175
+ this.searchPlaceholder = input(...(ngDevMode ? [undefined, { debugName: "searchPlaceholder" }] : /* istanbul ignore next */ []));
3176
+ this.showExport = input(false, { ...(ngDevMode ? { debugName: "showExport" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
3177
+ this.exported = output();
3178
+ this.hiddenColumnsChange = output();
3179
+ this.searched = output();
3180
+ this.hiddenColumns = signal([], ...(ngDevMode ? [{ debugName: "hiddenColumns" }] : /* istanbul ignore next */ []));
3181
+ this.searchOpen = signal(false, ...(ngDevMode ? [{ debugName: "searchOpen" }] : /* istanbul ignore next */ []));
3182
+ this.settingsOpen = signal(false, ...(ngDevMode ? [{ debugName: "settingsOpen" }] : /* istanbul ignore next */ []));
3183
+ }
3184
+ onHiddenColumnsChange(value) {
3185
+ this.hiddenColumns.set(Array.isArray(value) ? value : value ? [value] : []);
3186
+ this.hiddenColumnsChange.emit(this.hiddenColumns());
3187
+ }
3188
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwListToolbarActionsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3189
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: YuwListToolbarActionsComponent, isStandalone: true, selector: "yuw-list-toolbar-actions", inputs: { hideableColumns: { classPropertyName: "hideableColumns", publicName: "hideableColumns", isSignal: true, isRequired: false, transformFunction: null }, isMobile: { classPropertyName: "isMobile", publicName: "isMobile", isSignal: true, isRequired: true, transformFunction: null }, labels: { classPropertyName: "labels", publicName: "labels", isSignal: true, isRequired: true, transformFunction: null }, search: { classPropertyName: "search", publicName: "search", isSignal: true, isRequired: false, transformFunction: null }, searchPlaceholder: { classPropertyName: "searchPlaceholder", publicName: "searchPlaceholder", isSignal: true, isRequired: false, transformFunction: null }, showExport: { classPropertyName: "showExport", publicName: "showExport", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { search: "searchChange", exported: "exported", hiddenColumnsChange: "hiddenColumnsChange", searched: "searched" }, host: { classAttribute: "flex items-center gap-2" }, providers: [provideIcons({ lucideDownload, lucideSearch, lucideSettings2 })], ngImport: i0, template: "@if (searchPlaceholder(); as placeholder) {\n @if (isMobile()) {\n <yuw-popover\n align=\"center\"\n class=\"mr-5\"\n triggerVariant=\"outline\"\n triggerSize=\"icon\"\n panelClass=\"w-[min(20rem,calc(100vw-2rem))] p-2\"\n [offsetX]=\"-16\"\n [(open)]=\"searchOpen\"\n >\n <span yuwPopoverTrigger class=\"flex items-center\" [attr.aria-label]=\"labels().search.expand\">\n <ng-icon name=\"lucideSearch\" size=\"16\" />\n </span>\n\n <yuw-search-input\n expandedWidth=\"100%\"\n [(value)]=\"search\"\n [placeholder]=\"placeholder\"\n [clearAriaLabel]=\"labels().search.clear\"\n (searched)=\"searched.emit($event)\"\n />\n </yuw-popover>\n } @else {\n <yuw-search-input\n collapseFrom=\"right\"\n expandedWidth=\"18rem\"\n [(value)]=\"search\"\n [placeholder]=\"placeholder\"\n [clearAriaLabel]=\"labels().search.clear\"\n [expandAriaLabel]=\"labels().search.expand\"\n (searched)=\"searched.emit($event)\"\n />\n }\n}\n\n@if (showExport()) {\n <yuw-button variant=\"outline\" class=\"gap-2\" (clicked)=\"exported.emit($event)\">\n <ng-icon name=\"lucideDownload\" size=\"16\" />\n <span class=\"max-md:hidden\">\n {{ labels().export }}\n </span>\n </yuw-button>\n}\n\n@if (hideableColumns(); as columns) {\n <yuw-popover\n align=\"end\"\n panelClass=\"w-auto p-2 dark:border max-w-3xs\"\n triggerVariant=\"outline\"\n triggerSize=\"icon\"\n [(open)]=\"settingsOpen\"\n >\n <span yuwPopoverTrigger class=\"flex items-center\" [attr.aria-label]=\"labels().columns.trigger\">\n <ng-icon name=\"lucideSettings2\" size=\"16\" />\n </span>\n\n <div>\n <yuw-combobox\n multiple\n [options]=\"columns\"\n [value]=\"hiddenColumns()\"\n [placeholder]=\"labels().columns.placeholder\"\n [emptyText]=\"labels().columns.empty\"\n [triggerAriaLabel]=\"labels().columns.toggle\"\n (valueChange)=\"onHiddenColumnsChange($event)\"\n />\n </div>\n </yuw-popover>\n}\n", dependencies: [{ kind: "component", type: NgIcon, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }, { kind: "component", type: YuwButtonComponent, selector: "yuw-button", inputs: ["animationDisabled", "ariaLabel", "color", "disabled", "href", "size", "target", "transparent", "type", "class", "variant", "yuwDropdownMenuTrigger"], outputs: ["clicked"] }, { kind: "component", type: YuwComboboxComponent, selector: "yuw-combobox", inputs: ["clearAriaLabel", "emptyText", "inputId", "invalid", "multiple", "options", "placeholder", "readonlyTrigger", "search", "searchPlaceholder", "size", "triggerAriaLabel", "value"], outputs: ["searchChange", "valueChange"] }, { 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: YuwSearchInputComponent, selector: "yuw-search-input", inputs: ["clearAriaLabel", "collapseFrom", "expandAriaLabel", "expandedWidth", "size", "transparent"], outputs: ["searched"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3190
+ }
3191
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwListToolbarActionsComponent, decorators: [{
3192
+ type: Component,
3193
+ args: [{ selector: 'yuw-list-toolbar-actions', changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgIcon, YuwButtonComponent, YuwComboboxComponent, YuwPopoverComponent, YuwSearchInputComponent], providers: [provideIcons({ lucideDownload, lucideSearch, lucideSettings2 })], host: { class: 'flex items-center gap-2' }, template: "@if (searchPlaceholder(); as placeholder) {\n @if (isMobile()) {\n <yuw-popover\n align=\"center\"\n class=\"mr-5\"\n triggerVariant=\"outline\"\n triggerSize=\"icon\"\n panelClass=\"w-[min(20rem,calc(100vw-2rem))] p-2\"\n [offsetX]=\"-16\"\n [(open)]=\"searchOpen\"\n >\n <span yuwPopoverTrigger class=\"flex items-center\" [attr.aria-label]=\"labels().search.expand\">\n <ng-icon name=\"lucideSearch\" size=\"16\" />\n </span>\n\n <yuw-search-input\n expandedWidth=\"100%\"\n [(value)]=\"search\"\n [placeholder]=\"placeholder\"\n [clearAriaLabel]=\"labels().search.clear\"\n (searched)=\"searched.emit($event)\"\n />\n </yuw-popover>\n } @else {\n <yuw-search-input\n collapseFrom=\"right\"\n expandedWidth=\"18rem\"\n [(value)]=\"search\"\n [placeholder]=\"placeholder\"\n [clearAriaLabel]=\"labels().search.clear\"\n [expandAriaLabel]=\"labels().search.expand\"\n (searched)=\"searched.emit($event)\"\n />\n }\n}\n\n@if (showExport()) {\n <yuw-button variant=\"outline\" class=\"gap-2\" (clicked)=\"exported.emit($event)\">\n <ng-icon name=\"lucideDownload\" size=\"16\" />\n <span class=\"max-md:hidden\">\n {{ labels().export }}\n </span>\n </yuw-button>\n}\n\n@if (hideableColumns(); as columns) {\n <yuw-popover\n align=\"end\"\n panelClass=\"w-auto p-2 dark:border max-w-3xs\"\n triggerVariant=\"outline\"\n triggerSize=\"icon\"\n [(open)]=\"settingsOpen\"\n >\n <span yuwPopoverTrigger class=\"flex items-center\" [attr.aria-label]=\"labels().columns.trigger\">\n <ng-icon name=\"lucideSettings2\" size=\"16\" />\n </span>\n\n <div>\n <yuw-combobox\n multiple\n [options]=\"columns\"\n [value]=\"hiddenColumns()\"\n [placeholder]=\"labels().columns.placeholder\"\n [emptyText]=\"labels().columns.empty\"\n [triggerAriaLabel]=\"labels().columns.toggle\"\n (valueChange)=\"onHiddenColumnsChange($event)\"\n />\n </div>\n </yuw-popover>\n}\n" }]
3194
+ }], propDecorators: { 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 }] }], exported: [{ type: i0.Output, args: ["exported"] }], hiddenColumnsChange: [{ type: i0.Output, args: ["hiddenColumnsChange"] }], searched: [{ type: i0.Output, args: ["searched"] }] } });
3195
+
3196
+ /**
3197
+ * Makes a `<yuw-button>` the trigger of the surrounding `<yuw-sheet>`.
2883
3198
  *
2884
- * The `appearance` maps are split per element because the treatment is not uniform: `card` frames
2885
- * the container so the header tint clips to the radius instead of squaring off against a
2886
- * consumer's wrapper, then drops the header's bottom border, since a rule underneath a filled
2887
- * strip reads as a seam. `default` resolves to an empty string throughout, leaving a table that
2888
- * does not opt in byte-identical to what the Hlm directives render alone.
3199
+ * Mirrors `YuwDialogTriggerDirective`: the helm trigger only matches a native `button`, so the brain
3200
+ * directive is composed here instead, keeping `[hlmBtn]` inside `<yuw-button>`. `side` is forwarded
3201
+ * so a trigger can override which edge the sheet appears from.
2889
3202
  */
2890
- const DATATABLE_ALIGN_CLASS = {
2891
- start: '',
2892
- center: 'text-center',
2893
- end: 'text-end',
2894
- };
2895
- const datatableContainerVariants = cva('', {
2896
- variants: {
2897
- appearance: {
2898
- default: '',
2899
- card: 'scroll-fade-x rounded-(--radius-container-sm) border bg-(--neutrals-surface)',
2900
- },
3203
+ class YuwSheetTriggerDirective {
3204
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwSheetTriggerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
3205
+ 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$f.BrnSheetTrigger, inputs: ["id", "id", "side", "side", "type", "type"] }], ngImport: i0 }); }
3206
+ }
3207
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwSheetTriggerDirective, decorators: [{
3208
+ type: Directive,
3209
+ args: [{
3210
+ selector: 'yuw-button[yuwSheetTriggerButton]',
3211
+ hostDirectives: [{ directive: BrnSheetTrigger, inputs: ['id', 'side', 'type'] }],
3212
+ host: { 'data-slot': 'sheet-trigger' },
3213
+ }]
3214
+ }] });
3215
+ /** Closes the surrounding `<yuw-sheet>` when the host `<yuw-button>` is activated. */
3216
+ class YuwSheetCloseDirective {
3217
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwSheetCloseDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
3218
+ 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$f.BrnSheetClose }], ngImport: i0 }); }
3219
+ }
3220
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwSheetCloseDirective, decorators: [{
3221
+ type: Directive,
3222
+ args: [{
3223
+ selector: 'yuw-button[yuwSheetClose]',
3224
+ hostDirectives: [BrnSheetClose],
3225
+ host: { 'data-slot': 'sheet-close' },
3226
+ }]
3227
+ }] });
3228
+
3229
+ /**
3230
+ * Marks an element as the sheet's footer content, projected into the footer slot.
3231
+ * Its presence is also what makes the footer render at all — without it the sheet
3232
+ * shows no empty footer strip.
3233
+ */
3234
+ class YuwSheetFooterDirective {
3235
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwSheetFooterDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
3236
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwSheetFooterDirective, isStandalone: true, selector: "[yuwSheetFooter]", ngImport: i0 }); }
3237
+ }
3238
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwSheetFooterDirective, decorators: [{
3239
+ type: Directive,
3240
+ args: [{
3241
+ selector: '[yuwSheetFooter]',
3242
+ }]
3243
+ }] });
3244
+
3245
+ 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';
3246
+ /**
3247
+ * Slide-in sheet overlay panel component for side drawers, dialogs, and detail views.
3248
+ *
3249
+ * Accessibility: provide either `title` or `ariaLabel` — a modal panel without an accessible name
3250
+ * is announced as an anonymous dialog by screen readers.
3251
+ *
3252
+ * Inputs / Models:
3253
+ * - `open`: Two-way open/closed state (`boolean`). Drive directly via `[(open)]` to open/close programmatically.
3254
+ * - `showTrigger`: Whether to render the trigger button. Set `false` when opening only via `[(open)]`.
3255
+ * - `side`: Edge of the screen the panel slides in from (`'top'`, `'bottom'`, `'left'`, `'right'`). Default is `'right'`.
3256
+ * - `title`: Optional header title text. User-facing text the consuming app is responsible for translating.
3257
+ * - `description`: Optional header description text. User-facing text the consuming app is responsible for translating.
3258
+ * - `ariaLabel`: Accessible name for the sheet when no visible `title` is rendered. User-facing
3259
+ * text the consuming app is responsible for translating.
3260
+ * - `closeLabel`: Accessible label of the corner close (×) button. When set, the close button
3261
+ * renders and screen readers read this label; when absent there is no close button. User-facing
3262
+ * text the consuming app is responsible for translating.
3263
+ * - `panelClass`: Extra classes merged onto the sheet panel (e.g. `sm:max-w-lg` to widen it).
3264
+ * They win over the library defaults via `twMerge`. Note `twMerge` resolves per variant group, so a
3265
+ * plain utility does not displace a variant-prefixed default — to override `data-[side=left]:w-3/4`
3266
+ * the class has to be `data-[side=left]:w-64`, not `w-64`.
3267
+ * - `overlayClass`: Extra classes for the backdrop, for a sheet that should not dim the whole
3268
+ * viewport. Applied through `setOverlayClass` rather than a template binding: the backdrop lives in
3269
+ * the overlay too, and the helm's own class always wins the `class` input it exposes.
3270
+ * - `scrollStrategy`: What happens to page scroll while open. Defaults to the brain's blocking
3271
+ * strategy; pass `'reposition'` for a panel that should leave the page scrollable.
3272
+ * - `ariaModal`: Whether the sheet claims the rest of the page is hidden. Leave `true` for a real
3273
+ * modal; set `false` when content outside stays visible and usable, so the claim stays honest.
3274
+ * - `closeOnOutsidePointerEvents`: Whether a pointer press outside the panel closes it, backdrop
3275
+ * clicks included. Default is `true`, matching the brain from `@spartan-ng/brain` 1.3.4 on; pass
3276
+ * `false` for a panel that must be dismissed deliberately.
3277
+ * - `triggerVariant`: Button style variant for the trigger button.
3278
+ * - `triggerSize`: Button size for the trigger button.
3279
+ *
3280
+ * Usage:
3281
+ * ```html
3282
+ * <yuw-sheet [(open)]="isOpen" side="right" title="Edit Profile" description="Update your account details." closeLabel="Close">
3283
+ * <ng-container yuwSheetTrigger>Edit Profile</ng-container>
3284
+ *
3285
+ * <p>Sheet form content goes here.</p>
3286
+ *
3287
+ * <div yuwSheetFooter>
3288
+ * <yuw-button (clicked)="save()">Save Changes</yuw-button>
3289
+ * </div>
3290
+ * </yuw-sheet>
3291
+ * ```
3292
+ */
3293
+ class YuwSheetComponent {
3294
+ constructor() {
3295
+ this.hasFooter = contentChild(YuwSheetFooterDirective, ...(ngDevMode ? [{ debugName: "hasFooter" }] : /* istanbul ignore next */ []));
3296
+ this.sheet = viewChild.required(HlmSheet);
3297
+ this.ariaLabel = input(undefined, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
3298
+ this.ariaModal = input(true, { ...(ngDevMode ? { debugName: "ariaModal" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
3299
+ this.closeLabel = input(undefined, ...(ngDevMode ? [{ debugName: "closeLabel" }] : /* istanbul ignore next */ []));
3300
+ this.closeOnOutsidePointerEvents = input(true, { ...(ngDevMode ? { debugName: "closeOnOutsidePointerEvents" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
3301
+ this.description = input(undefined, ...(ngDevMode ? [{ debugName: "description" }] : /* istanbul ignore next */ []));
3302
+ this.open = model(false, ...(ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []));
3303
+ this.overlayClass = input(undefined, ...(ngDevMode ? [{ debugName: "overlayClass" }] : /* istanbul ignore next */ []));
3304
+ this.panelClass = input(undefined, ...(ngDevMode ? [{ debugName: "panelClass" }] : /* istanbul ignore next */ []));
3305
+ this.scrollStrategy = input(null, ...(ngDevMode ? [{ debugName: "scrollStrategy" }] : /* istanbul ignore next */ []));
3306
+ this.showTrigger = input(true, { ...(ngDevMode ? { debugName: "showTrigger" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
3307
+ this.side = input('right', ...(ngDevMode ? [{ debugName: "side" }] : /* istanbul ignore next */ []));
3308
+ this.title = input(undefined, ...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
3309
+ this.triggerSize = input('default', ...(ngDevMode ? [{ debugName: "triggerSize" }] : /* istanbul ignore next */ []));
3310
+ this.triggerVariant = input('outline', ...(ngDevMode ? [{ debugName: "triggerVariant" }] : /* istanbul ignore next */ []));
3311
+ this._sheetState = computed(() => (this.open() ? 'open' : 'closed'), ...(ngDevMode ? [{ debugName: "_sheetState" }] : /* istanbul ignore next */ []));
3312
+ effect(() => {
3313
+ const overlayClass = this.overlayClass();
3314
+ if (overlayClass === undefined)
3315
+ return;
3316
+ this.sheet().setOverlayClass(`${YUW_SHEET_OVERLAY_BASE_CLASS} ${overlayClass}`);
3317
+ });
3318
+ }
3319
+ onStateChanged(state) {
3320
+ this.open.set(state === 'open');
3321
+ }
3322
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwSheetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3323
+ 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$g.HlmSheet, selector: "hlm-sheet", exportAs: ["hlmSheet"] }, { kind: "component", type: i1$g.HlmSheetContent, selector: "hlm-sheet-content", inputs: ["showCloseButton"] }, { kind: "directive", type: i1$g.HlmSheetDescription, selector: "[hlmSheetDescription]" }, { kind: "directive", type: i1$g.HlmSheetFooter, selector: "[hlmSheetFooter],hlm-sheet-footer" }, { kind: "directive", type: i1$g.HlmSheetHeader, selector: "[hlmSheetHeader],hlm-sheet-header" }, { kind: "directive", type: i1$g.HlmSheetPortal, selector: "[hlmSheetPortal]" }, { kind: "directive", type: i1$g.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 }); }
3324
+ }
3325
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwSheetComponent, decorators: [{
3326
+ type: Component,
3327
+ args: [{ selector: 'yuw-sheet', imports: [...HlmSheetImports, YuwButtonComponent, YuwSheetTriggerDirective, YuwSheetCloseDirective, NgIcon], providers: [provideIcons({ lucideX })], host: {
3328
+ class: 'contents',
3329
+ }, 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" }]
3330
+ }], 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 }] }] } });
3331
+ const YuwSheetImports = [YuwSheetComponent, YuwSheetFooterDirective];
3332
+
3333
+ class YuwTabContentDirective {
3334
+ constructor() {
3335
+ this.templateRef = inject(TemplateRef);
3336
+ this.entryId = input.required({ ...(ngDevMode ? { debugName: "entryId" } : /* istanbul ignore next */ {}), alias: 'yuwTabContent' });
3337
+ }
3338
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwTabContentDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
3339
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.22", type: YuwTabContentDirective, isStandalone: true, selector: "ng-template[yuwTabContent]", inputs: { entryId: { classPropertyName: "entryId", publicName: "yuwTabContent", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0 }); }
3340
+ }
3341
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwTabContentDirective, decorators: [{
3342
+ type: Directive,
3343
+ args: [{
3344
+ selector: 'ng-template[yuwTabContent]',
3345
+ }]
3346
+ }], propDecorators: { entryId: [{ type: i0.Input, args: [{ isSignal: true, alias: "yuwTabContent", required: true }] }] } });
3347
+
3348
+ /**
3349
+ * Declares the content of a single `<yuw-tabs>` panel. Apply it to an `<ng-template>` and pass the
3350
+ * id of the tab it belongs to, matching an entry in the `tabs` input.
3351
+ *
3352
+ * Usage:
3353
+ * ```html
3354
+ * <ng-template yuwTabPanel="billing">Contenido de facturación</ng-template>
3355
+ * ```
3356
+ */
3357
+ class YuwTabPanelDirective {
3358
+ constructor() {
3359
+ this.templateRef = inject(TemplateRef);
3360
+ this.tabId = input.required({ ...(ngDevMode ? { debugName: "tabId" } : /* istanbul ignore next */ {}), alias: 'yuwTabPanel' });
3361
+ }
3362
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwTabPanelDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
3363
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.22", type: YuwTabPanelDirective, isStandalone: true, selector: "ng-template[yuwTabPanel]", inputs: { tabId: { classPropertyName: "tabId", publicName: "yuwTabPanel", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0 }); }
3364
+ }
3365
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwTabPanelDirective, decorators: [{
3366
+ type: Directive,
3367
+ args: [{
3368
+ selector: 'ng-template[yuwTabPanel]',
3369
+ }]
3370
+ }], propDecorators: { tabId: [{ type: i0.Input, args: [{ isSignal: true, alias: "yuwTabPanel", required: true }] }] } });
3371
+
3372
+ /**
3373
+ * Size classes for `<yuw-tabs>`, applied to the `hlm-tabs-list`.
3374
+ *
3375
+ * Two things scale, and both have to be written with the helm's own modifier prefixes so
3376
+ * tailwind-merge displaces the helm class rather than leaving it standing:
3377
+ *
3378
+ * - The list height, declared by the helm as `group-data-horizontal/tabs:h-8`. Only the horizontal
3379
+ * orientation has a fixed height; the vertical one is `h-fit` and is left alone.
3380
+ * - The triggers' horizontal padding, reached through a descendant selector. The helm's `px-1.5` is
3381
+ * tight enough that a taller list would look cramped, and the triggers are separate components
3382
+ * with no class passthrough. Their height needs nothing — `h-[calc(100%-1px)]` already tracks the
3383
+ * list.
3384
+ */
3385
+ const yuwTabsSizeVariants = cva('', {
3386
+ variants: {
3387
+ size: {
3388
+ default: 'group-data-horizontal/tabs:h-10 [&_[data-slot=tabs-trigger]]:px-2.5',
3389
+ xs: 'group-data-horizontal/tabs:h-7 [&_[data-slot=tabs-trigger]]:px-1.5',
3390
+ sm: 'group-data-horizontal/tabs:h-9 [&_[data-slot=tabs-trigger]]:px-2',
3391
+ lg: 'group-data-horizontal/tabs:h-11 [&_[data-slot=tabs-trigger]]:px-3',
3392
+ },
3393
+ },
3394
+ defaultVariants: {
3395
+ size: 'default',
3396
+ },
3397
+ });
3398
+
3399
+ /**
3400
+ * Tabbed navigation between sibling panels.
3401
+ *
3402
+ * Triggers come from the `tabs` input; each panel's content is declared by the consumer as an
3403
+ * `<ng-template yuwTabPanel="<id>">` whose id matches a tab. Panels are lazy: a panel's content
3404
+ * is only instantiated the first time its tab becomes active (and stays alive, hidden, after
3405
+ * switching away).
3406
+ *
3407
+ * Inputs / Models:
3408
+ * - `tabs`: The tab definitions (`YuwTabItemDto[]`) rendered as triggers, in order.
3409
+ * - `activeTab`: Two-way id of the selected tab. Drive via `[(activeTab)]` to control it
3410
+ * programmatically; listen to `activeTabChange` to react to activations.
3411
+ * - `size`: Tab-list height, matching the `<yuw-button>` of the same name.
3412
+ * - `variant`: Trigger list style (`'default'` filled, `'line'` underlined). Default is `'default'`.
3413
+ * - `orientation`: Layout direction (`'horizontal'`, `'vertical'`). Default is `'horizontal'`.
3414
+ * - `activationMode`: How keyboard focus activates tabs (`'automatic'` activates on focus,
3415
+ * `'manual'` requires Enter/Space). Default is `'automatic'`.
3416
+ *
3417
+ * Usage:
3418
+ * ```html
3419
+ * <yuw-tabs [tabs]="tabs" [(activeTab)]="selected">
3420
+ * <ng-template yuwTabPanel="general">Contenido general</ng-template>
3421
+ * <ng-template yuwTabPanel="billing">Contenido de facturación</ng-template>
3422
+ * </yuw-tabs>
3423
+ * ```
3424
+ */
3425
+ class YuwTabsComponent {
3426
+ constructor() {
3427
+ this._contents = contentChildren(YuwTabContentDirective, ...(ngDevMode ? [{ debugName: "_contents" }] : /* istanbul ignore next */ []));
3428
+ this.panels = contentChildren(YuwTabPanelDirective, ...(ngDevMode ? [{ debugName: "panels" }] : /* istanbul ignore next */ []));
3429
+ this.activationMode = input('automatic', ...(ngDevMode ? [{ debugName: "activationMode" }] : /* istanbul ignore next */ []));
3430
+ this.activeTab = model.required(...(ngDevMode ? [{ debugName: "activeTab" }] : /* istanbul ignore next */ []));
3431
+ this.orientation = input('horizontal', ...(ngDevMode ? [{ debugName: "orientation" }] : /* istanbul ignore next */ []));
3432
+ this.size = input('default', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
3433
+ this.tabs = input.required(...(ngDevMode ? [{ debugName: "tabs" }] : /* istanbul ignore next */ []));
3434
+ this.userClass = input('', { ...(ngDevMode ? { debugName: "userClass" } : /* istanbul ignore next */ {}), alias: 'class' });
3435
+ this.variant = input('default', ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
3436
+ this._listClass = computed(() => cn(yuwTabsSizeVariants({ size: this.size() }), this.userClass()), ...(ngDevMode ? [{ debugName: "_listClass" }] : /* istanbul ignore next */ []));
3437
+ this._resolved = computed(() => {
3438
+ const templates = new Map(this._contents().map((content) => [content.entryId(), content.templateRef]));
3439
+ const entries = this.tabs();
3440
+ return entries.map((entry) => {
3441
+ return {
3442
+ ...entry,
3443
+ template: templates.get(entry.id),
3444
+ };
3445
+ });
3446
+ }, ...(ngDevMode ? [{ debugName: "_resolved" }] : /* istanbul ignore next */ []));
3447
+ }
3448
+ onTabActivated(tabId) {
3449
+ this.activeTab.set(tabId);
3450
+ }
3451
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwTabsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3452
+ 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$h.HlmTabs, selector: "[hlmTabs],hlm-tabs", inputs: ["tab"] }, { kind: "directive", type: i1$h.HlmTabsList, selector: "[hlmTabsList],hlm-tabs-list", inputs: ["variant"] }, { kind: "directive", type: i1$h.HlmTabsTrigger, selector: "[hlmTabsTrigger]", inputs: ["hlmTabsTrigger"] }, { kind: "directive", type: i1$h.HlmTabsContent, selector: "[hlmTabsContent]", inputs: ["hlmTabsContent"] }, { kind: "directive", type: i1$h.HlmTabsContentLazy, selector: "ng-template[hlmTabsContentLazy]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3453
+ }
3454
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwTabsComponent, decorators: [{
3455
+ type: Component,
3456
+ args: [{ selector: 'yuw-tabs', imports: [NgTemplateOutlet, ...HlmTabsImports], host: {
3457
+ class: 'contents',
3458
+ }, changeDetection: ChangeDetectionStrategy.OnPush, 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" }]
3459
+ }], propDecorators: { _contents: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => YuwTabContentDirective), { isSignal: true }] }], panels: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => YuwTabPanelDirective), { isSignal: true }] }], activationMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "activationMode", required: false }] }], activeTab: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeTab", required: true }] }, { type: i0.Output, args: ["activeTabChange"] }], orientation: [{ type: i0.Input, args: [{ isSignal: true, alias: "orientation", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], tabs: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabs", required: true }] }], userClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }] } });
3460
+
3461
+ /** Number of selected values across every group, not the number of groups. */
3462
+ function countSelectedValues(selection) {
3463
+ return Object.values(selection).reduce((total, entry) => total + (Array.isArray(entry) ? entry.length : 1), 0);
3464
+ }
3465
+ /**
3466
+ * Staged selection behind the filter editor. Picking an option changes the draft, not the applied
3467
+ * selection, so the page does not re-query on every click; only `snapshot()` is committed.
3468
+ */
3469
+ class YuwFilterDraft {
3470
+ clear() {
3471
+ this._entries.set({});
3472
+ }
3473
+ constructor(applied) {
3474
+ this.applied = applied;
3475
+ this._entries = linkedSignal(() => ({ ...this.applied() }), ...(ngDevMode ? [{ debugName: "_entries" }] : /* istanbul ignore next */ []));
3476
+ this.pendingGroupIds = computed(() => {
3477
+ const committed = this.applied();
3478
+ const staged = this._entries();
3479
+ return new Set([...new Set([...Object.keys(committed), ...Object.keys(staged)])].filter((groupId) => !YuwFilterDraft.isSameEntry(committed[groupId], staged[groupId])));
3480
+ }, ...(ngDevMode ? [{ debugName: "pendingGroupIds" }] : /* istanbul ignore next */ []));
3481
+ this.checkedValues = computed(() => Object.fromEntries(Object.entries(this._entries()).map(([groupId, entry]) => [
3482
+ groupId,
3483
+ new Set(Array.isArray(entry) ? entry : [entry]),
3484
+ ])), ...(ngDevMode ? [{ debugName: "checkedValues" }] : /* istanbul ignore next */ []));
3485
+ this.selectedCount = computed(() => countSelectedValues(this._entries()), ...(ngDevMode ? [{ debugName: "selectedCount" }] : /* istanbul ignore next */ []));
3486
+ }
3487
+ reset() {
3488
+ this._entries.set({ ...this.applied() });
3489
+ }
3490
+ snapshot() {
3491
+ return this._entries();
3492
+ }
3493
+ /**
3494
+ * A `single` group behaves like a radio that can also be emptied: checking replaces the held
3495
+ * value, and unchecking only clears the group when it names the value actually held.
3496
+ */
3497
+ toggle(group, value, checked) {
3498
+ if (group.mode === 'multiple') {
3499
+ this._setMultiple(group.id, value, checked);
3500
+ return;
3501
+ }
3502
+ if (checked) {
3503
+ this._setSingle(group.id, value);
3504
+ return;
3505
+ }
3506
+ if (this.checkedValues()[group.id]?.has(value)) {
3507
+ this._setSingle(group.id, undefined);
3508
+ }
3509
+ }
3510
+ _setMultiple(groupId, value, checked) {
3511
+ this._entries.update((entries) => {
3512
+ const entry = entries[groupId];
3513
+ const current = Array.isArray(entry) ? entry : [];
3514
+ const next = checked ? [...current, value] : current.filter((item) => item !== value);
3515
+ return next.length === 0 ? YuwFilterDraft.without(entries, groupId) : { ...entries, [groupId]: next };
3516
+ });
3517
+ }
3518
+ _setSingle(groupId, value) {
3519
+ this._entries.update((entries) => value === undefined ? YuwFilterDraft.without(entries, groupId) : { ...entries, [groupId]: value });
3520
+ }
3521
+ static isSameEntry(applied, staged) {
3522
+ if (Array.isArray(applied) && Array.isArray(staged)) {
3523
+ return applied.length === staged.length && new Set(applied).size === new Set([...applied, ...staged]).size;
3524
+ }
3525
+ return applied === staged;
3526
+ }
3527
+ static without(entries, groupId) {
3528
+ const { [groupId]: _removed, ...rest } = entries;
3529
+ return rest;
3530
+ }
3531
+ }
3532
+
3533
+ /**
3534
+ * Filter control of `yuw-list-toolbar`. From `md` up the editor is a two-pane panel in a popover;
3535
+ * below it, one tab per group in a bottom sheet.
3536
+ *
3537
+ * Each layout keeps its own trigger: the popover anchors to the element holding
3538
+ * `yuwPopoverTrigger`, so it cannot come from a shared `ng-template`. `activeCount` reads the
3539
+ * applied selection, not the draft. Opening the editor discards unapplied draft changes.
3540
+ */
3541
+ class YuwListToolbarFiltersComponent {
3542
+ constructor() {
3543
+ this.disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
3544
+ this.groups = input.required(...(ngDevMode ? [{ debugName: "groups" }] : /* istanbul ignore next */ []));
3545
+ this.idleColor = input.required(...(ngDevMode ? [{ debugName: "idleColor" }] : /* istanbul ignore next */ []));
3546
+ this.isMobile = input.required(...(ngDevMode ? [{ debugName: "isMobile" }] : /* istanbul ignore next */ []));
3547
+ this.labels = input.required(...(ngDevMode ? [{ debugName: "labels" }] : /* istanbul ignore next */ []));
3548
+ this.selection = model({}, ...(ngDevMode ? [{ debugName: "selection" }] : /* istanbul ignore next */ []));
3549
+ this._activeGroupId = signal(null, ...(ngDevMode ? [{ debugName: "_activeGroupId" }] : /* istanbul ignore next */ []));
3550
+ this.draft = new YuwFilterDraft(this.selection);
3551
+ this.open = signal(false, ...(ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []));
3552
+ this.activeCount = computed(() => countSelectedValues(this.selection()), ...(ngDevMode ? [{ debugName: "activeCount" }] : /* istanbul ignore next */ []));
3553
+ this.activeGroup = computed(() => {
3554
+ const groups = this.groups();
3555
+ const id = this._activeGroupId();
3556
+ return groups.find((group) => group.id === id) ?? groups.at(0) ?? null;
3557
+ }, ...(ngDevMode ? [{ debugName: "activeGroup" }] : /* istanbul ignore next */ []));
3558
+ this.hasActive = computed(() => this.activeCount() > 0, ...(ngDevMode ? [{ debugName: "hasActive" }] : /* istanbul ignore next */ []));
3559
+ this.buttons = computed(() => {
3560
+ const active = this.hasActive();
3561
+ const disabled = this.disabled();
3562
+ const { title, clearAll } = this.labels();
3563
+ const entries = [
3564
+ {
3565
+ id: 'filters',
3566
+ label: active ? `${title} : ${this.activeCount()}` : title,
3567
+ variant: active ? 'secondary' : 'outline',
3568
+ disabled,
3569
+ },
3570
+ ];
3571
+ if (active) {
3572
+ entries.push({ id: 'clear', ariaLabel: clearAll, size: 'icon', disabled });
3573
+ }
3574
+ return entries;
3575
+ }, ...(ngDevMode ? [{ debugName: "buttons" }] : /* istanbul ignore next */ []));
3576
+ this.buttonsColor = computed(() => (this.hasActive() ? 'primary' : this.idleColor()), ...(ngDevMode ? [{ debugName: "buttonsColor" }] : /* istanbul ignore next */ []));
3577
+ this.selectedText = computed(() => this.labels().selected(this.draft.selectedCount()), ...(ngDevMode ? [{ debugName: "selectedText" }] : /* istanbul ignore next */ []));
3578
+ this.tabs = computed(() => this.groups().map((group) => ({ id: group.id, label: group.label })), ...(ngDevMode ? [{ debugName: "tabs" }] : /* istanbul ignore next */ []));
3579
+ effect(() => {
3580
+ if (this.open()) {
3581
+ untracked(() => this.draft.reset());
3582
+ }
3583
+ });
3584
+ }
3585
+ onApply() {
3586
+ this.commit(this.draft.snapshot());
3587
+ }
3588
+ onButtonClicked({ id, event }) {
3589
+ if (id === 'clear') {
3590
+ event.stopPropagation();
3591
+ event.preventDefault();
3592
+ this.commit({});
3593
+ return;
3594
+ }
3595
+ if (this.isMobile()) {
3596
+ this.open.set(true);
3597
+ }
3598
+ }
3599
+ onOptionChange(group, value, checked) {
3600
+ this.draft.toggle(group, value, checked);
3601
+ }
3602
+ selectGroup(groupId) {
3603
+ this._activeGroupId.set(groupId);
3604
+ }
3605
+ commit(selection) {
3606
+ this.selection.set(selection);
3607
+ this.open.set(false);
3608
+ }
3609
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwListToolbarFiltersComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3610
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: YuwListToolbarFiltersComponent, isStandalone: true, selector: "yuw-list-toolbar-filters", inputs: { disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, groups: { classPropertyName: "groups", publicName: "groups", isSignal: true, isRequired: true, transformFunction: null }, idleColor: { classPropertyName: "idleColor", publicName: "idleColor", isSignal: true, isRequired: true, transformFunction: null }, isMobile: { classPropertyName: "isMobile", publicName: "isMobile", isSignal: true, isRequired: true, transformFunction: null }, labels: { classPropertyName: "labels", publicName: "labels", isSignal: true, isRequired: true, transformFunction: null }, selection: { classPropertyName: "selection", publicName: "selection", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selection: "selectionChange" }, providers: [provideIcons({ lucideX })], ngImport: i0, template: "<ng-template #options let-group>\n <ul class=\"flex flex-col gap-1\" [attr.aria-label]=\"group.label\">\n @for (option of group.options; track option.value) {\n <li>\n <label\n class=\"flex cursor-pointer items-center justify-between gap-3 rounded-md px-3 py-1 text-sm transition-colors hover:bg-accent/45\"\n [for]=\"`${group.id}-option-${option.value}`\"\n >\n <span class=\"min-w-0 truncate\">{{ option.label }}</span>\n\n <yuw-checkbox\n [inputId]=\"`${group.id}-option-${option.value}`\"\n [checked]=\"draft.checkedValues()[group.id]?.has(option.value) ?? false\"\n [disabled]=\"option.disabled ?? false\"\n [ariaLabel]=\"option.label\"\n (checkedChange)=\"onOptionChange(group, option.value, $event)\"\n />\n </label>\n </li>\n }\n </ul>\n</ng-template>\n\n<ng-template #commitRow>\n @if (selectedText(); as text) {\n <p class=\"text-end text-xs text-muted-foreground pr-2\">{{ text }}</p>\n }\n\n <div class=\"flex justify-end gap-2 pt-3\">\n <yuw-button variant=\"outline\" (clicked)=\"draft.clear()\">\n {{ labels().clear }}\n </yuw-button>\n\n <yuw-button (clicked)=\"onApply()\">\n {{ labels().apply }}\n </yuw-button>\n </div>\n</ng-template>\n\n@if (isMobile()) {\n <yuw-button-group\n variant=\"secondary\"\n [buttons]=\"buttons()\"\n [color]=\"buttonsColor()\"\n [ariaLabel]=\"labels().title\"\n (buttonClicked)=\"onButtonClicked($event)\"\n >\n <ng-template yuwButtonGroupContent=\"clear\">\n <ng-icon name=\"lucideX\" size=\"16\" />\n </ng-template>\n </yuw-button-group>\n\n <yuw-sheet\n side=\"bottom\"\n panelClass=\"max-h-[85svh] overflow-y-auto\"\n [showTrigger]=\"false\"\n [title]=\"labels().title\"\n [closeLabel]=\"labels().close\"\n [(open)]=\"open\"\n >\n <div class=\"flex min-h-0 flex-col gap-3\">\n <yuw-tabs\n class=\"max-w-full justify-start overflow-x-auto overflow-y-hidden scrollbar-none [&::-webkit-scrollbar]:hidden scroll-fade-x\"\n [tabs]=\"tabs()\"\n [activeTab]=\"activeGroup()?.id ?? ''\"\n (activeTabChange)=\"selectGroup($event)\"\n >\n @for (group of groups(); track group.id) {\n <ng-template [yuwTabContent]=\"group.id\">\n <span class=\"flex items-center gap-1.5 whitespace-nowrap\">\n {{ group.label }}\n\n @if (draft.pendingGroupIds().has(group.id)) {\n <yuw-badge\n dot\n color=\"primary\"\n style=\"width: 0.5rem; height: 0.5rem\"\n [attr.aria-label]=\"labels().pending\"\n [attr.title]=\"labels().pending\"\n />\n }\n </span>\n </ng-template>\n\n <ng-template [yuwTabPanel]=\"group.id\">\n <div class=\"max-h-[45svh] overflow-y-auto pt-2\">\n <ng-container [ngTemplateOutlet]=\"options\" [ngTemplateOutletContext]=\"{ $implicit: group }\" />\n </div>\n </ng-template>\n }\n </yuw-tabs>\n\n <div class=\"pb-3\">\n <ng-container [ngTemplateOutlet]=\"commitRow\" />\n </div>\n </div>\n </yuw-sheet>\n} @else {\n <yuw-popover align=\"start\" panelClass=\"w-auto p-2 dark:border\" triggerClass=\"px-0\" triggerTransparent [(open)]=\"open\">\n <yuw-button-group\n yuwPopoverTrigger\n variant=\"secondary\"\n [buttons]=\"buttons()\"\n [color]=\"buttonsColor()\"\n [ariaLabel]=\"labels().title\"\n (buttonClicked)=\"onButtonClicked($event)\"\n >\n <ng-template yuwButtonGroupContent=\"clear\">\n <ng-icon name=\"lucideX\" size=\"16\" />\n </ng-template>\n </yuw-button-group>\n\n <div class=\"flex min-w-0\">\n <ul class=\"flex w-44 shrink-0 flex-col gap-1 pe-2\">\n @for (group of groups(); track group.id) {\n <li>\n <button\n type=\"button\"\n class=\"flex w-full items-center gap-2 rounded-md px-3 py-2 text-start text-sm transition-colors hover:bg-accent/45\"\n [class.bg-accent/45]=\"activeGroup()?.id === group.id\"\n [attr.aria-current]=\"activeGroup()?.id === group.id ? 'true' : null\"\n (click)=\"selectGroup(group.id)\"\n >\n <span class=\"min-w-0 flex-1 truncate\">{{ group.label }}</span>\n\n @if (draft.pendingGroupIds().has(group.id)) {\n <yuw-badge\n dot\n color=\"primary\"\n style=\"width: 0.5rem; height: 0.5rem\"\n [attr.aria-label]=\"labels().pending\"\n [attr.title]=\"labels().pending\"\n />\n }\n </button>\n </li>\n }\n </ul>\n\n @if (activeGroup(); as group) {\n <div class=\"flex min-w-0 flex-1 flex-col gap-3 border-s p-3\">\n <ng-container [ngTemplateOutlet]=\"options\" [ngTemplateOutletContext]=\"{ $implicit: group }\" />\n <ng-container [ngTemplateOutlet]=\"commitRow\" />\n </div>\n }\n </div>\n </yuw-popover>\n}\n", styles: [".scrollbar-none{scrollbar-width:none}\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: "component", type: YuwBadgeComponent, selector: "yuw-badge", inputs: ["color", "dot", "removeLabel", "variant"], outputs: ["removed"] }, { 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: YuwButtonGroupComponent, selector: "yuw-button-group", inputs: ["ariaLabel", "buttons", "color", "orientation", "selectedColor", "selectedVariant", "size", "variant"], outputs: ["buttonClicked"] }, { kind: "directive", type: YuwButtonGroupContentDirective, selector: "ng-template[yuwButtonGroupContent]", inputs: ["yuwButtonGroupContent"] }, { kind: "component", type: YuwCheckboxComponent, selector: "yuw-checkbox", inputs: ["ariaDescribedby", "ariaLabel", "ariaLabelledby", "indeterminate", "inputId", "invalid", "name", "required", "secondary", "checked"], outputs: ["indeterminateChange", "checkedChange"] }, { 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"] }, { kind: "directive", type: YuwTabContentDirective, selector: "ng-template[yuwTabContent]", inputs: ["yuwTabContent"] }, { kind: "directive", type: YuwTabPanelDirective, selector: "ng-template[yuwTabPanel]", inputs: ["yuwTabPanel"] }, { kind: "component", type: YuwTabsComponent, selector: "yuw-tabs", inputs: ["activationMode", "activeTab", "orientation", "size", "tabs", "class", "variant"], outputs: ["activeTabChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3611
+ }
3612
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwListToolbarFiltersComponent, decorators: [{
3613
+ type: Component,
3614
+ args: [{ selector: 'yuw-list-toolbar-filters', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
3615
+ NgTemplateOutlet,
3616
+ NgIcon,
3617
+ YuwBadgeComponent,
3618
+ YuwButtonComponent,
3619
+ YuwButtonGroupComponent,
3620
+ YuwButtonGroupContentDirective,
3621
+ YuwCheckboxComponent,
3622
+ YuwPopoverComponent,
3623
+ YuwSheetComponent,
3624
+ YuwTabContentDirective,
3625
+ YuwTabPanelDirective,
3626
+ YuwTabsComponent,
3627
+ ], providers: [provideIcons({ lucideX })], template: "<ng-template #options let-group>\n <ul class=\"flex flex-col gap-1\" [attr.aria-label]=\"group.label\">\n @for (option of group.options; track option.value) {\n <li>\n <label\n class=\"flex cursor-pointer items-center justify-between gap-3 rounded-md px-3 py-1 text-sm transition-colors hover:bg-accent/45\"\n [for]=\"`${group.id}-option-${option.value}`\"\n >\n <span class=\"min-w-0 truncate\">{{ option.label }}</span>\n\n <yuw-checkbox\n [inputId]=\"`${group.id}-option-${option.value}`\"\n [checked]=\"draft.checkedValues()[group.id]?.has(option.value) ?? false\"\n [disabled]=\"option.disabled ?? false\"\n [ariaLabel]=\"option.label\"\n (checkedChange)=\"onOptionChange(group, option.value, $event)\"\n />\n </label>\n </li>\n }\n </ul>\n</ng-template>\n\n<ng-template #commitRow>\n @if (selectedText(); as text) {\n <p class=\"text-end text-xs text-muted-foreground pr-2\">{{ text }}</p>\n }\n\n <div class=\"flex justify-end gap-2 pt-3\">\n <yuw-button variant=\"outline\" (clicked)=\"draft.clear()\">\n {{ labels().clear }}\n </yuw-button>\n\n <yuw-button (clicked)=\"onApply()\">\n {{ labels().apply }}\n </yuw-button>\n </div>\n</ng-template>\n\n@if (isMobile()) {\n <yuw-button-group\n variant=\"secondary\"\n [buttons]=\"buttons()\"\n [color]=\"buttonsColor()\"\n [ariaLabel]=\"labels().title\"\n (buttonClicked)=\"onButtonClicked($event)\"\n >\n <ng-template yuwButtonGroupContent=\"clear\">\n <ng-icon name=\"lucideX\" size=\"16\" />\n </ng-template>\n </yuw-button-group>\n\n <yuw-sheet\n side=\"bottom\"\n panelClass=\"max-h-[85svh] overflow-y-auto\"\n [showTrigger]=\"false\"\n [title]=\"labels().title\"\n [closeLabel]=\"labels().close\"\n [(open)]=\"open\"\n >\n <div class=\"flex min-h-0 flex-col gap-3\">\n <yuw-tabs\n class=\"max-w-full justify-start overflow-x-auto overflow-y-hidden scrollbar-none [&::-webkit-scrollbar]:hidden scroll-fade-x\"\n [tabs]=\"tabs()\"\n [activeTab]=\"activeGroup()?.id ?? ''\"\n (activeTabChange)=\"selectGroup($event)\"\n >\n @for (group of groups(); track group.id) {\n <ng-template [yuwTabContent]=\"group.id\">\n <span class=\"flex items-center gap-1.5 whitespace-nowrap\">\n {{ group.label }}\n\n @if (draft.pendingGroupIds().has(group.id)) {\n <yuw-badge\n dot\n color=\"primary\"\n style=\"width: 0.5rem; height: 0.5rem\"\n [attr.aria-label]=\"labels().pending\"\n [attr.title]=\"labels().pending\"\n />\n }\n </span>\n </ng-template>\n\n <ng-template [yuwTabPanel]=\"group.id\">\n <div class=\"max-h-[45svh] overflow-y-auto pt-2\">\n <ng-container [ngTemplateOutlet]=\"options\" [ngTemplateOutletContext]=\"{ $implicit: group }\" />\n </div>\n </ng-template>\n }\n </yuw-tabs>\n\n <div class=\"pb-3\">\n <ng-container [ngTemplateOutlet]=\"commitRow\" />\n </div>\n </div>\n </yuw-sheet>\n} @else {\n <yuw-popover align=\"start\" panelClass=\"w-auto p-2 dark:border\" triggerClass=\"px-0\" triggerTransparent [(open)]=\"open\">\n <yuw-button-group\n yuwPopoverTrigger\n variant=\"secondary\"\n [buttons]=\"buttons()\"\n [color]=\"buttonsColor()\"\n [ariaLabel]=\"labels().title\"\n (buttonClicked)=\"onButtonClicked($event)\"\n >\n <ng-template yuwButtonGroupContent=\"clear\">\n <ng-icon name=\"lucideX\" size=\"16\" />\n </ng-template>\n </yuw-button-group>\n\n <div class=\"flex min-w-0\">\n <ul class=\"flex w-44 shrink-0 flex-col gap-1 pe-2\">\n @for (group of groups(); track group.id) {\n <li>\n <button\n type=\"button\"\n class=\"flex w-full items-center gap-2 rounded-md px-3 py-2 text-start text-sm transition-colors hover:bg-accent/45\"\n [class.bg-accent/45]=\"activeGroup()?.id === group.id\"\n [attr.aria-current]=\"activeGroup()?.id === group.id ? 'true' : null\"\n (click)=\"selectGroup(group.id)\"\n >\n <span class=\"min-w-0 flex-1 truncate\">{{ group.label }}</span>\n\n @if (draft.pendingGroupIds().has(group.id)) {\n <yuw-badge\n dot\n color=\"primary\"\n style=\"width: 0.5rem; height: 0.5rem\"\n [attr.aria-label]=\"labels().pending\"\n [attr.title]=\"labels().pending\"\n />\n }\n </button>\n </li>\n }\n </ul>\n\n @if (activeGroup(); as group) {\n <div class=\"flex min-w-0 flex-1 flex-col gap-3 border-s p-3\">\n <ng-container [ngTemplateOutlet]=\"options\" [ngTemplateOutletContext]=\"{ $implicit: group }\" />\n <ng-container [ngTemplateOutlet]=\"commitRow\" />\n </div>\n }\n </div>\n </yuw-popover>\n}\n", styles: [".scrollbar-none{scrollbar-width:none}\n"] }]
3628
+ }], ctorParameters: () => [], propDecorators: { disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], groups: [{ type: i0.Input, args: [{ isSignal: true, alias: "groups", required: true }] }], idleColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "idleColor", required: true }] }], isMobile: [{ type: i0.Input, args: [{ isSignal: true, alias: "isMobile", required: true }] }], labels: [{ type: i0.Input, args: [{ isSignal: true, alias: "labels", required: true }] }], selection: [{ type: i0.Input, args: [{ isSignal: true, alias: "selection", required: false }] }, { type: i0.Output, args: ["selectionChange"] }] } });
3629
+
3630
+ /**
3631
+ * Toolbar of a list page: filters on the leading edge, search, export and column visibility on the
3632
+ * trailing one, and projected content after them.
3633
+ *
3634
+ * Each control renders only when its input is set: `filterGroups`, `searchPlaceholder`,
3635
+ * `showExport`, `hideableColumns`. `labels` holds every text and the consumer translates it;
3636
+ * `idleColor` is the filter trigger tone while nothing is applied.
3637
+ */
3638
+ class YuwListToolbarComponent {
3639
+ constructor() {
3640
+ this.filterGroups = input(...(ngDevMode ? [undefined, { debugName: "filterGroups" }] : /* istanbul ignore next */ []));
3641
+ this.filtersDisabled = input(false, { ...(ngDevMode ? { debugName: "filtersDisabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
3642
+ this.hideableColumns = input(...(ngDevMode ? [undefined, { debugName: "hideableColumns" }] : /* istanbul ignore next */ []));
3643
+ this.idleColor = input('secondary', ...(ngDevMode ? [{ debugName: "idleColor" }] : /* istanbul ignore next */ []));
3644
+ this.labels = input.required(...(ngDevMode ? [{ debugName: "labels" }] : /* istanbul ignore next */ []));
3645
+ this.search = model('', ...(ngDevMode ? [{ debugName: "search" }] : /* istanbul ignore next */ []));
3646
+ this.searchPlaceholder = input(...(ngDevMode ? [undefined, { debugName: "searchPlaceholder" }] : /* istanbul ignore next */ []));
3647
+ this.selection = model({}, ...(ngDevMode ? [{ debugName: "selection" }] : /* istanbul ignore next */ []));
3648
+ this.showExport = input(false, { ...(ngDevMode ? { debugName: "showExport" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
3649
+ this.exported = output();
3650
+ this.hiddenColumnsChange = output();
3651
+ this.searched = output();
3652
+ this.isMobile = injectIsMobile();
3653
+ }
3654
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwListToolbarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3655
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: YuwListToolbarComponent, isStandalone: true, selector: "yuw-list-toolbar", inputs: { filterGroups: { classPropertyName: "filterGroups", publicName: "filterGroups", isSignal: true, isRequired: false, transformFunction: null }, filtersDisabled: { classPropertyName: "filtersDisabled", publicName: "filtersDisabled", isSignal: true, isRequired: false, transformFunction: null }, hideableColumns: { classPropertyName: "hideableColumns", publicName: "hideableColumns", isSignal: true, isRequired: false, transformFunction: null }, idleColor: { classPropertyName: "idleColor", publicName: "idleColor", isSignal: true, isRequired: false, transformFunction: null }, labels: { classPropertyName: "labels", publicName: "labels", isSignal: true, isRequired: true, transformFunction: null }, search: { classPropertyName: "search", publicName: "search", isSignal: true, isRequired: false, transformFunction: null }, searchPlaceholder: { classPropertyName: "searchPlaceholder", publicName: "searchPlaceholder", isSignal: true, isRequired: false, transformFunction: null }, selection: { classPropertyName: "selection", publicName: "selection", isSignal: true, isRequired: false, transformFunction: null }, showExport: { classPropertyName: "showExport", publicName: "showExport", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { search: "searchChange", selection: "selectionChange", exported: "exported", hiddenColumnsChange: "hiddenColumnsChange", searched: "searched" }, host: { classAttribute: "flex flex-wrap items-center justify-between gap-3" }, ngImport: i0, template: "<!-- Filters -->\n<div class=\"flex items-center\">\n @if (filterGroups(); as groups) {\n <yuw-list-toolbar-filters\n [disabled]=\"filtersDisabled()\"\n [groups]=\"groups\"\n [idleColor]=\"idleColor()\"\n [isMobile]=\"isMobile()\"\n [labels]=\"labels().filters\"\n [(selection)]=\"selection\"\n />\n }\n</div>\n\n<!-- Actions -->\n<div class=\"ms-auto flex items-center gap-2\">\n <yuw-list-toolbar-actions\n [hideableColumns]=\"hideableColumns()\"\n [isMobile]=\"isMobile()\"\n [labels]=\"labels()\"\n [searchPlaceholder]=\"searchPlaceholder()\"\n [showExport]=\"showExport()\"\n [(search)]=\"search\"\n (exported)=\"exported.emit($event)\"\n (hiddenColumnsChange)=\"hiddenColumnsChange.emit($event)\"\n (searched)=\"searched.emit($event)\"\n />\n\n <ng-content />\n</div>\n", dependencies: [{ kind: "component", type: YuwListToolbarActionsComponent, selector: "yuw-list-toolbar-actions", inputs: ["hideableColumns", "isMobile", "labels", "search", "searchPlaceholder", "showExport"], outputs: ["searchChange", "exported", "hiddenColumnsChange", "searched"] }, { kind: "component", type: YuwListToolbarFiltersComponent, selector: "yuw-list-toolbar-filters", inputs: ["disabled", "groups", "idleColor", "isMobile", "labels", "selection"], outputs: ["selectionChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3656
+ }
3657
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwListToolbarComponent, decorators: [{
3658
+ type: Component,
3659
+ args: [{ selector: 'yuw-list-toolbar', changeDetection: ChangeDetectionStrategy.OnPush, imports: [YuwListToolbarActionsComponent, YuwListToolbarFiltersComponent], host: { class: 'flex flex-wrap items-center justify-between gap-3' }, template: "<!-- Filters -->\n<div class=\"flex items-center\">\n @if (filterGroups(); as groups) {\n <yuw-list-toolbar-filters\n [disabled]=\"filtersDisabled()\"\n [groups]=\"groups\"\n [idleColor]=\"idleColor()\"\n [isMobile]=\"isMobile()\"\n [labels]=\"labels().filters\"\n [(selection)]=\"selection\"\n />\n }\n</div>\n\n<!-- Actions -->\n<div class=\"ms-auto flex items-center gap-2\">\n <yuw-list-toolbar-actions\n [hideableColumns]=\"hideableColumns()\"\n [isMobile]=\"isMobile()\"\n [labels]=\"labels()\"\n [searchPlaceholder]=\"searchPlaceholder()\"\n [showExport]=\"showExport()\"\n [(search)]=\"search\"\n (exported)=\"exported.emit($event)\"\n (hiddenColumnsChange)=\"hiddenColumnsChange.emit($event)\"\n (searched)=\"searched.emit($event)\"\n />\n\n <ng-content />\n</div>\n" }]
3660
+ }], propDecorators: { filterGroups: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterGroups", required: false }] }], filtersDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "filtersDisabled", required: false }] }], hideableColumns: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideableColumns", required: false }] }], idleColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "idleColor", required: false }] }], 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 }] }], selection: [{ type: i0.Input, args: [{ isSignal: true, alias: "selection", required: false }] }, { type: i0.Output, args: ["selectionChange"] }], showExport: [{ type: i0.Input, args: [{ isSignal: true, alias: "showExport", required: false }] }], exported: [{ type: i0.Output, args: ["exported"] }], hiddenColumnsChange: [{ type: i0.Output, args: ["hiddenColumnsChange"] }], searched: [{ type: i0.Output, args: ["searched"] }] } });
3661
+
3662
+ const YUW_DATATABLE_FEATURES = {
3663
+ columnMeta: {},
3664
+ columnFilteringFeature,
3665
+ columnVisibilityFeature,
3666
+ rowPaginationFeature,
3667
+ rowSelectionFeature,
3668
+ rowSortingFeature,
3669
+ };
3670
+
3671
+ /**
3672
+ * Default floor for a column that opts into `meta.wrap`, as a Tailwind `min-w-*` class.
3673
+ *
3674
+ * This is the only bound a wrapping column needs. It is what makes the responsive behaviour work:
3675
+ * below it the table stops shrinking the column — which would end in a column one word wide — and
3676
+ * the table's own width exceeds the container instead, so `YuwTableContainer`'s `overflow-x-auto`
3677
+ * scrolls horizontally.
3678
+ *
3679
+ * There is deliberately no maximum. A cap would make a wrapping column break onto several lines
3680
+ * while the table still had free space beside it, which reads as broken; letting the column take
3681
+ * its share of the row means text wraps only once it genuinely no longer fits.
3682
+ */
3683
+ const YUW_DATATABLE_WRAP_MIN_WIDTH = 'min-w-48';
3684
+ /**
3685
+ * Layout classes the `<table>` needs for `meta.wrap` columns to size correctly.
3686
+ *
3687
+ * `w-full` lets the table fill its container so a wrapping column can spread into the free space
3688
+ * instead of wrapping early, and `min-w-max` keeps the table at least as wide as its content
3689
+ * demands — which is what lets a wrapping column's floor push the table past the container and
3690
+ * hand the overflow to the scroll container. Applied unconditionally: for a table with no wrapping
3691
+ * column both halves resolve to the width it already had.
3692
+ */
3693
+ const DATATABLE_LAYOUT_CLASS = 'w-full min-w-max';
3694
+ /**
3695
+ * Class maps for `yuw-datatable`, layered on top of the Hlm table directives' own classes.
3696
+ *
3697
+ * `DATATABLE_ALIGN_CLASS` is keyed by a column's `meta.align` and shared by header and body cells,
3698
+ * so a column declares its alignment once and both honour it; `start` maps to an empty string
3699
+ * rather than re-stating what `HlmTh`/`HlmTd` already apply.
3700
+ *
3701
+ * The `appearance` maps are split per element because the treatment is not uniform: `card` frames
3702
+ * the container so the header tint clips to the radius instead of squaring off against a
3703
+ * consumer's wrapper, then drops the header's bottom border, since a rule underneath a filled
3704
+ * strip reads as a seam. `default` resolves to an empty string throughout, leaving a table that
3705
+ * does not opt in byte-identical to what the Hlm directives render alone.
3706
+ */
3707
+ const DATATABLE_ALIGN_CLASS = {
3708
+ start: '',
3709
+ center: 'text-center',
3710
+ end: 'text-end',
3711
+ };
3712
+ const datatableContainerVariants = cva('', {
3713
+ variants: {
3714
+ appearance: {
3715
+ default: '',
3716
+ card: 'scroll-fade-x rounded-(--radius-container-sm) border bg-(--neutrals-surface)',
3717
+ },
2901
3718
  },
2902
3719
  defaultVariants: {
2903
3720
  appearance: 'default',
@@ -3239,6 +4056,42 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
3239
4056
  }]
3240
4057
  }], propDecorators: { checked: [{ type: i0.Input, args: [{ isSignal: true, alias: "checked", required: false }] }], indeterminate: [{ type: i0.Input, args: [{ isSignal: true, alias: "indeterminate", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], onToggle: [{ type: i0.Input, args: [{ isSignal: true, alias: "onToggle", required: false }] }] } });
3241
4058
 
4059
+ /**
4060
+ * Gear button cell that runs `onEdit`, an input because `flexRenderComponent` does not subscribe
4061
+ * outputs. The host stops the click so a clickable row does not fire twice.
4062
+ */
4063
+ class YuwActionsCellComponent {
4064
+ constructor() {
4065
+ this.label = input.required(...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
4066
+ this.onEdit = input(() => undefined, ...(ngDevMode ? [{ debugName: "onEdit" }] : /* istanbul ignore next */ []));
4067
+ }
4068
+ edit() {
4069
+ this.onEdit()();
4070
+ }
4071
+ onHostClick(event) {
4072
+ event.stopPropagation();
4073
+ }
4074
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwActionsCellComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4075
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.22", type: YuwActionsCellComponent, isStandalone: true, selector: "yuw-actions-cell", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, onEdit: { classPropertyName: "onEdit", publicName: "onEdit", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "click": "onHostClick($event)" } }, providers: [provideIcons({ lucideSettings })], ngImport: i0, template: "<yuw-button variant=\"ghost\" size=\"icon\" [ariaLabel]=\"label()\" (clicked)=\"edit()\">\n <ng-icon name=\"lucideSettings\" size=\"16\" />\n</yuw-button>\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 }); }
4076
+ }
4077
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwActionsCellComponent, decorators: [{
4078
+ type: Component,
4079
+ args: [{ selector: 'yuw-actions-cell', changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgIcon, YuwButtonComponent], providers: [provideIcons({ lucideSettings })], host: { '(click)': 'onHostClick($event)' }, template: "<yuw-button variant=\"ghost\" size=\"icon\" [ariaLabel]=\"label()\" (clicked)=\"edit()\">\n <ng-icon name=\"lucideSettings\" size=\"16\" />\n</yuw-button>\n" }]
4080
+ }], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], onEdit: [{ type: i0.Input, args: [{ isSignal: true, alias: "onEdit", required: false }] }] } });
4081
+
4082
+ /** Headerless `actions` column; `label` is the button's accessible name, already translated. */
4083
+ function buildYuwActionsColumn(label, onEdit, cellClass) {
4084
+ return {
4085
+ id: 'actions',
4086
+ header: '',
4087
+ enableSorting: false,
4088
+ meta: cellClass ? { align: 'end', cellClass } : { align: 'end' },
4089
+ cell: ({ row }) => flexRenderComponent(YuwActionsCellComponent, {
4090
+ inputs: { label, onEdit: () => onEdit(row.original) },
4091
+ }),
4092
+ };
4093
+ }
4094
+
3242
4095
  /**
3243
4096
  * Displays a user or entity avatar with optional image, fallback text/initials, status badge, or overlapping group layout.
3244
4097
  *
@@ -3277,7 +4130,7 @@ class YuwAvatarComponent {
3277
4130
  this._isGroup = computed(() => (this.group()?.length ?? 0) > 0, ...(ngDevMode ? [{ debugName: "_isGroup" }] : /* istanbul ignore next */ []));
3278
4131
  }
3279
4132
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwAvatarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3280
- 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$d.HlmAvatar, selector: "hlm-avatar", inputs: ["size"] }, { kind: "directive", type: i1$d.HlmAvatarBadge, selector: "[hlmAvatarBadge],hlm-avatar-badge" }, { kind: "directive", type: i1$d.HlmAvatarFallback, selector: "[hlmAvatarFallback]", exportAs: ["hlmAvatarFallback"] }, { kind: "directive", type: i1$d.HlmAvatarGroup, selector: "[hlmAvatarGroup],hlm-avatar-group" }, { kind: "directive", type: i1$d.HlmAvatarGroupCount, selector: "[hlmAvatarGroupCount],hlm-avatar-group-count" }, { kind: "directive", type: i1$d.HlmAvatarImage, selector: "img[hlmAvatarImage]", exportAs: ["hlmAvatarImage"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
4133
+ 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$i.HlmAvatar, selector: "hlm-avatar", inputs: ["size"] }, { kind: "directive", type: i1$i.HlmAvatarBadge, selector: "[hlmAvatarBadge],hlm-avatar-badge" }, { kind: "directive", type: i1$i.HlmAvatarFallback, selector: "[hlmAvatarFallback]", exportAs: ["hlmAvatarFallback"] }, { kind: "directive", type: i1$i.HlmAvatarGroup, selector: "[hlmAvatarGroup],hlm-avatar-group" }, { kind: "directive", type: i1$i.HlmAvatarGroupCount, selector: "[hlmAvatarGroupCount],hlm-avatar-group-count" }, { kind: "directive", type: i1$i.HlmAvatarImage, selector: "img[hlmAvatarImage]", exportAs: ["hlmAvatarImage"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3281
4134
  }
3282
4135
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwAvatarComponent, decorators: [{
3283
4136
  type: Component,
@@ -3304,7 +4157,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
3304
4157
  */
3305
4158
  class YuwItemDirective {
3306
4159
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwItemDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
3307
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwItemDirective, isStandalone: true, selector: "[yuwItem], yuw-item", hostDirectives: [{ directive: i1$e.HlmItem, inputs: ["variant", "variant", "size", "size"] }], ngImport: i0 }); }
4160
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwItemDirective, isStandalone: true, selector: "[yuwItem], yuw-item", hostDirectives: [{ directive: i1$j.HlmItem, inputs: ["variant", "variant", "size", "size"] }], ngImport: i0 }); }
3308
4161
  }
3309
4162
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwItemDirective, decorators: [{
3310
4163
  type: Directive,
@@ -3316,7 +4169,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
3316
4169
  /** Header slot directive for an item container. */
3317
4170
  class YuwItemHeaderDirective {
3318
4171
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwItemHeaderDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
3319
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwItemHeaderDirective, isStandalone: true, selector: "[yuwItemHeader], yuw-item-header", hostDirectives: [{ directive: i1$e.HlmItemHeader }], ngImport: i0 }); }
4172
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwItemHeaderDirective, isStandalone: true, selector: "[yuwItemHeader], yuw-item-header", hostDirectives: [{ directive: i1$j.HlmItemHeader }], ngImport: i0 }); }
3320
4173
  }
3321
4174
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwItemHeaderDirective, decorators: [{
3322
4175
  type: Directive,
@@ -3328,7 +4181,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
3328
4181
  /** Leading media slot directive (for icons, avatars, or images) at the start of an item. Supports `variant` (`'default'`, `'icon'`, `'image'`). */
3329
4182
  class YuwItemMediaDirective {
3330
4183
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwItemMediaDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
3331
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwItemMediaDirective, isStandalone: true, selector: "[yuwItemMedia], yuw-item-media", hostDirectives: [{ directive: i1$e.HlmItemMedia, inputs: ["variant", "variant"] }], ngImport: i0 }); }
4184
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwItemMediaDirective, isStandalone: true, selector: "[yuwItemMedia], yuw-item-media", hostDirectives: [{ directive: i1$j.HlmItemMedia, inputs: ["variant", "variant"] }], ngImport: i0 }); }
3332
4185
  }
3333
4186
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwItemMediaDirective, decorators: [{
3334
4187
  type: Directive,
@@ -3340,7 +4193,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
3340
4193
  /** Main text content container directive for an item. */
3341
4194
  class YuwItemContentDirective {
3342
4195
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwItemContentDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
3343
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwItemContentDirective, isStandalone: true, selector: "[yuwItemContent], yuw-item-content", hostDirectives: [{ directive: i1$e.HlmItemContent }], ngImport: i0 }); }
4196
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwItemContentDirective, isStandalone: true, selector: "[yuwItemContent], yuw-item-content", hostDirectives: [{ directive: i1$j.HlmItemContent }], ngImport: i0 }); }
3344
4197
  }
3345
4198
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwItemContentDirective, decorators: [{
3346
4199
  type: Directive,
@@ -3352,7 +4205,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
3352
4205
  /** Title heading directive for an item. */
3353
4206
  class YuwItemTitleDirective {
3354
4207
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwItemTitleDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
3355
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwItemTitleDirective, isStandalone: true, selector: "[yuwItemTitle], yuw-item-title", hostDirectives: [{ directive: i1$e.HlmItemTitle }], ngImport: i0 }); }
4208
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwItemTitleDirective, isStandalone: true, selector: "[yuwItemTitle], yuw-item-title", hostDirectives: [{ directive: i1$j.HlmItemTitle }], ngImport: i0 }); }
3356
4209
  }
3357
4210
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwItemTitleDirective, decorators: [{
3358
4211
  type: Directive,
@@ -3364,7 +4217,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
3364
4217
  /** Subtitle or description paragraph directive for an item. */
3365
4218
  class YuwItemDescriptionDirective {
3366
4219
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwItemDescriptionDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
3367
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwItemDescriptionDirective, isStandalone: true, selector: "[yuwItemDescription], yuw-item-description", hostDirectives: [{ directive: i1$e.HlmItemDescription }], ngImport: i0 }); }
4220
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwItemDescriptionDirective, isStandalone: true, selector: "[yuwItemDescription], yuw-item-description", hostDirectives: [{ directive: i1$j.HlmItemDescription }], ngImport: i0 }); }
3368
4221
  }
3369
4222
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwItemDescriptionDirective, decorators: [{
3370
4223
  type: Directive,
@@ -3376,7 +4229,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
3376
4229
  /** Trailing action controls slot directive (for buttons, switches, or menu triggers) at the end of an item. */
3377
4230
  class YuwItemActionsDirective {
3378
4231
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwItemActionsDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
3379
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwItemActionsDirective, isStandalone: true, selector: "[yuwItemActions], yuw-item-actions", hostDirectives: [{ directive: i1$e.HlmItemActions }], ngImport: i0 }); }
4232
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwItemActionsDirective, isStandalone: true, selector: "[yuwItemActions], yuw-item-actions", hostDirectives: [{ directive: i1$j.HlmItemActions }], ngImport: i0 }); }
3380
4233
  }
3381
4234
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwItemActionsDirective, decorators: [{
3382
4235
  type: Directive,
@@ -3388,286 +4241,58 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
3388
4241
  /** Footer slot directive for an item. */
3389
4242
  class YuwItemFooterDirective {
3390
4243
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwItemFooterDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
3391
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwItemFooterDirective, isStandalone: true, selector: "[yuwItemFooter], yuw-item-footer", hostDirectives: [{ directive: i1$e.HlmItemFooter }], ngImport: i0 }); }
3392
- }
3393
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwItemFooterDirective, decorators: [{
3394
- type: Directive,
3395
- args: [{
3396
- selector: '[yuwItemFooter], yuw-item-footer',
3397
- hostDirectives: [HlmItemFooter],
3398
- }]
3399
- }] });
3400
- /** Container directive for grouping multiple item rows together into a list card or bordered group. */
3401
- class YuwItemGroupDirective {
3402
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwItemGroupDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
3403
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwItemGroupDirective, isStandalone: true, selector: "[yuwItemGroup], yuw-item-group", hostDirectives: [{ directive: i1$e.HlmItemGroup }], ngImport: i0 }); }
3404
- }
3405
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwItemGroupDirective, decorators: [{
3406
- type: Directive,
3407
- args: [{
3408
- selector: '[yuwItemGroup], yuw-item-group',
3409
- hostDirectives: [HlmItemGroup],
3410
- }]
3411
- }] });
3412
- /**
3413
- * Visual separator line between items inside a group. Accepts `orientation` (`'horizontal'` or
3414
- * `'vertical'`), reaching the underlying `BrnSeparator`, which owns the `role`,
3415
- * `aria-orientation` and `data-orientation` attributes. Extends `HlmItemSeparator` (instead of
3416
- * composing it via `hostDirectives`) because `orientation` is re-exposed by the helm from
3417
- * `BrnSeparator` through its own `hostDirectives`, and host-directive forwarding is not
3418
- * transitive (NG2017).
3419
- */
3420
- class YuwItemSeparatorDirective extends HlmItemSeparator {
3421
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwItemSeparatorDirective, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
3422
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwItemSeparatorDirective, isStandalone: true, selector: "[yuwItemSeparator], yuw-item-separator", usesInheritance: true, ngImport: i0 }); }
3423
- }
3424
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwItemSeparatorDirective, decorators: [{
3425
- type: Directive,
3426
- args: [{
3427
- selector: '[yuwItemSeparator], yuw-item-separator',
3428
- }]
3429
- }] });
3430
- /** Every item part, for a consumer's `imports`. */
3431
- const YuwItemImports = [
3432
- YuwItemDirective,
3433
- YuwItemHeaderDirective,
3434
- YuwItemMediaDirective,
3435
- YuwItemContentDirective,
3436
- YuwItemTitleDirective,
3437
- YuwItemDescriptionDirective,
3438
- YuwItemActionsDirective,
3439
- YuwItemFooterDirective,
3440
- YuwItemGroupDirective,
3441
- YuwItemSeparatorDirective,
3442
- ];
3443
-
3444
- /**
3445
- * Makes a `<yuw-button>` the trigger of the surrounding `<yuw-sheet>`.
3446
- *
3447
- * Mirrors `YuwDialogTriggerDirective`: the helm trigger only matches a native `button`, so the brain
3448
- * directive is composed here instead, keeping `[hlmBtn]` inside `<yuw-button>`. `side` is forwarded
3449
- * so a trigger can override which edge the sheet appears from.
3450
- */
3451
- class YuwSheetTriggerDirective {
3452
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwSheetTriggerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
3453
- 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$f.BrnSheetTrigger, inputs: ["id", "id", "side", "side", "type", "type"] }], ngImport: i0 }); }
3454
- }
3455
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwSheetTriggerDirective, decorators: [{
3456
- type: Directive,
3457
- args: [{
3458
- selector: 'yuw-button[yuwSheetTriggerButton]',
3459
- hostDirectives: [{ directive: BrnSheetTrigger, inputs: ['id', 'side', 'type'] }],
3460
- host: { 'data-slot': 'sheet-trigger' },
3461
- }]
3462
- }] });
3463
- /** Closes the surrounding `<yuw-sheet>` when the host `<yuw-button>` is activated. */
3464
- class YuwSheetCloseDirective {
3465
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwSheetCloseDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
3466
- 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$f.BrnSheetClose }], ngImport: i0 }); }
3467
- }
3468
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwSheetCloseDirective, decorators: [{
3469
- type: Directive,
3470
- args: [{
3471
- selector: 'yuw-button[yuwSheetClose]',
3472
- hostDirectives: [BrnSheetClose],
3473
- host: { 'data-slot': 'sheet-close' },
3474
- }]
3475
- }] });
3476
-
3477
- /**
3478
- * Marks an element as the sheet's footer content, projected into the footer slot.
3479
- * Its presence is also what makes the footer render at all — without it the sheet
3480
- * shows no empty footer strip.
3481
- */
3482
- class YuwSheetFooterDirective {
3483
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwSheetFooterDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
3484
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwSheetFooterDirective, isStandalone: true, selector: "[yuwSheetFooter]", ngImport: i0 }); }
3485
- }
3486
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwSheetFooterDirective, decorators: [{
3487
- type: Directive,
3488
- args: [{
3489
- selector: '[yuwSheetFooter]',
3490
- }]
3491
- }] });
3492
-
3493
- 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';
3494
- /**
3495
- * Slide-in sheet overlay panel component for side drawers, dialogs, and detail views.
3496
- *
3497
- * Accessibility: provide either `title` or `ariaLabel` — a modal panel without an accessible name
3498
- * is announced as an anonymous dialog by screen readers.
3499
- *
3500
- * Inputs / Models:
3501
- * - `open`: Two-way open/closed state (`boolean`). Drive directly via `[(open)]` to open/close programmatically.
3502
- * - `showTrigger`: Whether to render the trigger button. Set `false` when opening only via `[(open)]`.
3503
- * - `side`: Edge of the screen the panel slides in from (`'top'`, `'bottom'`, `'left'`, `'right'`). Default is `'right'`.
3504
- * - `title`: Optional header title text. User-facing text the consuming app is responsible for translating.
3505
- * - `description`: Optional header description text. User-facing text the consuming app is responsible for translating.
3506
- * - `ariaLabel`: Accessible name for the sheet when no visible `title` is rendered. User-facing
3507
- * text the consuming app is responsible for translating.
3508
- * - `closeLabel`: Accessible label of the corner close (×) button. When set, the close button
3509
- * renders and screen readers read this label; when absent there is no close button. User-facing
3510
- * text the consuming app is responsible for translating.
3511
- * - `panelClass`: Extra classes merged onto the sheet panel (e.g. `sm:max-w-lg` to widen it).
3512
- * They win over the library defaults via `twMerge`. Note `twMerge` resolves per variant group, so a
3513
- * plain utility does not displace a variant-prefixed default — to override `data-[side=left]:w-3/4`
3514
- * the class has to be `data-[side=left]:w-64`, not `w-64`.
3515
- * - `overlayClass`: Extra classes for the backdrop, for a sheet that should not dim the whole
3516
- * viewport. Applied through `setOverlayClass` rather than a template binding: the backdrop lives in
3517
- * the overlay too, and the helm's own class always wins the `class` input it exposes.
3518
- * - `scrollStrategy`: What happens to page scroll while open. Defaults to the brain's blocking
3519
- * strategy; pass `'reposition'` for a panel that should leave the page scrollable.
3520
- * - `ariaModal`: Whether the sheet claims the rest of the page is hidden. Leave `true` for a real
3521
- * modal; set `false` when content outside stays visible and usable, so the claim stays honest.
3522
- * - `closeOnOutsidePointerEvents`: Whether a pointer press outside the panel closes it, backdrop
3523
- * clicks included. Default is `true`, matching the brain from `@spartan-ng/brain` 1.3.4 on; pass
3524
- * `false` for a panel that must be dismissed deliberately.
3525
- * - `triggerVariant`: Button style variant for the trigger button.
3526
- * - `triggerSize`: Button size for the trigger button.
3527
- *
3528
- * Usage:
3529
- * ```html
3530
- * <yuw-sheet [(open)]="isOpen" side="right" title="Edit Profile" description="Update your account details." closeLabel="Close">
3531
- * <ng-container yuwSheetTrigger>Edit Profile</ng-container>
3532
- *
3533
- * <p>Sheet form content goes here.</p>
3534
- *
3535
- * <div yuwSheetFooter>
3536
- * <yuw-button (clicked)="save()">Save Changes</yuw-button>
3537
- * </div>
3538
- * </yuw-sheet>
3539
- * ```
3540
- */
3541
- class YuwSheetComponent {
3542
- constructor() {
3543
- this.hasFooter = contentChild(YuwSheetFooterDirective, ...(ngDevMode ? [{ debugName: "hasFooter" }] : /* istanbul ignore next */ []));
3544
- this.sheet = viewChild.required(HlmSheet);
3545
- this.ariaLabel = input(undefined, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
3546
- this.ariaModal = input(true, { ...(ngDevMode ? { debugName: "ariaModal" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
3547
- this.closeLabel = input(undefined, ...(ngDevMode ? [{ debugName: "closeLabel" }] : /* istanbul ignore next */ []));
3548
- this.closeOnOutsidePointerEvents = input(true, { ...(ngDevMode ? { debugName: "closeOnOutsidePointerEvents" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
3549
- this.description = input(undefined, ...(ngDevMode ? [{ debugName: "description" }] : /* istanbul ignore next */ []));
3550
- this.open = model(false, ...(ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []));
3551
- this.overlayClass = input(undefined, ...(ngDevMode ? [{ debugName: "overlayClass" }] : /* istanbul ignore next */ []));
3552
- this.panelClass = input(undefined, ...(ngDevMode ? [{ debugName: "panelClass" }] : /* istanbul ignore next */ []));
3553
- this.scrollStrategy = input(null, ...(ngDevMode ? [{ debugName: "scrollStrategy" }] : /* istanbul ignore next */ []));
3554
- this.showTrigger = input(true, { ...(ngDevMode ? { debugName: "showTrigger" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
3555
- this.side = input('right', ...(ngDevMode ? [{ debugName: "side" }] : /* istanbul ignore next */ []));
3556
- this.title = input(undefined, ...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
3557
- this.triggerSize = input('default', ...(ngDevMode ? [{ debugName: "triggerSize" }] : /* istanbul ignore next */ []));
3558
- this.triggerVariant = input('outline', ...(ngDevMode ? [{ debugName: "triggerVariant" }] : /* istanbul ignore next */ []));
3559
- this._sheetState = computed(() => (this.open() ? 'open' : 'closed'), ...(ngDevMode ? [{ debugName: "_sheetState" }] : /* istanbul ignore next */ []));
3560
- effect(() => {
3561
- const overlayClass = this.overlayClass();
3562
- if (overlayClass === undefined)
3563
- return;
3564
- this.sheet().setOverlayClass(`${YUW_SHEET_OVERLAY_BASE_CLASS} ${overlayClass}`);
3565
- });
3566
- }
3567
- onStateChanged(state) {
3568
- this.open.set(state === 'open');
3569
- }
3570
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwSheetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3571
- 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$g.HlmSheet, selector: "hlm-sheet", exportAs: ["hlmSheet"] }, { kind: "component", type: i1$g.HlmSheetContent, selector: "hlm-sheet-content", inputs: ["showCloseButton"] }, { kind: "directive", type: i1$g.HlmSheetDescription, selector: "[hlmSheetDescription]" }, { kind: "directive", type: i1$g.HlmSheetFooter, selector: "[hlmSheetFooter],hlm-sheet-footer" }, { kind: "directive", type: i1$g.HlmSheetHeader, selector: "[hlmSheetHeader],hlm-sheet-header" }, { kind: "directive", type: i1$g.HlmSheetPortal, selector: "[hlmSheetPortal]" }, { kind: "directive", type: i1$g.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 }); }
4244
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwItemFooterDirective, isStandalone: true, selector: "[yuwItemFooter], yuw-item-footer", hostDirectives: [{ directive: i1$j.HlmItemFooter }], ngImport: i0 }); }
3572
4245
  }
3573
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwSheetComponent, decorators: [{
3574
- type: Component,
3575
- args: [{ selector: 'yuw-sheet', imports: [...HlmSheetImports, YuwButtonComponent, YuwSheetTriggerDirective, YuwSheetCloseDirective, NgIcon], providers: [provideIcons({ lucideX })], host: {
3576
- class: 'contents',
3577
- }, 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" }]
3578
- }], 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 }] }] } });
3579
- const YuwSheetImports = [YuwSheetComponent, YuwSheetFooterDirective];
3580
-
3581
- /**
3582
- * Makes a `<yuw-button>` the trigger of the surrounding `<yuw-popover>`.
3583
- *
3584
- * The helm trigger directive's selector only matches a native `button`, so composing the brain
3585
- * directive here is what lets the popover use `<yuw-button>` rather than a bare `[hlmBtn]` element.
3586
- * Brain needs three things from its host, all of which `<yuw-button>` provides: the `click` that
3587
- * bubbles up from the inner button, the `aria-expanded`/`data-state` attributes, and a host box to
3588
- * anchor the panel against — hence `<yuw-button>`'s `inline-flex` host, since a `display: contents`
3589
- * host has no rect for the overlay to position from.
3590
- *
3591
- * `data-slot` mirrors the helm directive so the popover stylesheet targets both identically.
3592
- */
3593
- class YuwPopoverTriggerDirective {
3594
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwPopoverTriggerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
3595
- 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$h.BrnPopoverTrigger, inputs: ["id", "id", "brnPopoverTriggerFor", "yuwPopoverTriggerFor", "type", "type"] }], ngImport: i0 }); }
4246
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwItemFooterDirective, decorators: [{
4247
+ type: Directive,
4248
+ args: [{
4249
+ selector: '[yuwItemFooter], yuw-item-footer',
4250
+ hostDirectives: [HlmItemFooter],
4251
+ }]
4252
+ }] });
4253
+ /** Container directive for grouping multiple item rows together into a list card or bordered group. */
4254
+ class YuwItemGroupDirective {
4255
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwItemGroupDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
4256
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwItemGroupDirective, isStandalone: true, selector: "[yuwItemGroup], yuw-item-group", hostDirectives: [{ directive: i1$j.HlmItemGroup }], ngImport: i0 }); }
3596
4257
  }
3597
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwPopoverTriggerDirective, decorators: [{
4258
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwItemGroupDirective, decorators: [{
3598
4259
  type: Directive,
3599
4260
  args: [{
3600
- selector: 'yuw-button[yuwPopoverTriggerFor], yuw-button[yuwPopoverTriggerButton]',
3601
- hostDirectives: [
3602
- { directive: BrnPopoverTrigger, inputs: ['id', 'brnPopoverTriggerFor: yuwPopoverTriggerFor', 'type'] },
3603
- ],
3604
- host: { 'data-slot': 'popover-trigger' },
4261
+ selector: '[yuwItemGroup], yuw-item-group',
4262
+ hostDirectives: [HlmItemGroup],
3605
4263
  }]
3606
4264
  }] });
3607
-
3608
4265
  /**
3609
- * Popover component for displaying anchored floating overlay panels.
3610
- *
3611
- * Inputs / Models:
3612
- * - `open`: Two-way open/closed state (`boolean`). Drive directly via `[(open)]` to open/close programmatically.
3613
- * - `showTrigger`: Whether to render the trigger button. Set `false` when opening only via `[(open)]`.
3614
- * - `align`: Panel alignment relative to trigger (`'start'`, `'center'`, `'end'`). Default is `'center'`.
3615
- * - `sideOffset`: Pixel offset between the trigger and the panel. Default is `4`.
3616
- * - `sideOffset`: Pixel offset for X sides. Positive px for right, negative for left side.
3617
- * - `title`: Optional header title text. User-facing text the consuming app is responsible for translating.
3618
- * - `description`: Optional header description text. User-facing text the consuming app is responsible for translating.
3619
- * - `panelClass`: Extra classes merged onto the popover panel (e.g. `w-80` to widen it). They win
3620
- * over the library defaults via `twMerge`.
3621
- * - `triggerVariant`: Button style variant for the trigger button.
3622
- * - `triggerColor`: Brand color theme for the trigger button (any `YuwColorDto` value). Default is
3623
- * `'secondary'`.
3624
- * - `triggerSize`: Button size for the trigger button.
3625
- * - `triggerTransparent`: Strips the trigger's background and border in every state (rest, hover,
3626
- * open), for triggers whose projected content is the whole control — an avatar, a name, a chevron.
3627
- * - `triggerClass`: Extra classes merged onto the trigger button, last, so they beat both the
3628
- * variant classes and `triggerTransparent` (e.g. `h-auto p-0` to drop the button's own box).
3629
- *
3630
- * The trigger is a `<yuw-button>`; `YuwPopoverTriggerDirective` composes the brain trigger onto it,
3631
- * so the popover reuses our button component instead of applying `[hlmBtn]` directly.
3632
- *
3633
- * Usage:
3634
- * ```html
3635
- * <yuw-popover [(open)]="isOpen" title="Notifications" description="You're all caught up.">
3636
- * <ng-container yuwPopoverTrigger>View Notifications</ng-container>
3637
- *
3638
- * <p>Popover content body goes here.</p>
3639
- * </yuw-popover>
3640
- * ```
4266
+ * Visual separator line between items inside a group. Accepts `orientation` (`'horizontal'` or
4267
+ * `'vertical'`), reaching the underlying `BrnSeparator`, which owns the `role`,
4268
+ * `aria-orientation` and `data-orientation` attributes. Extends `HlmItemSeparator` (instead of
4269
+ * composing it via `hostDirectives`) because `orientation` is re-exposed by the helm from
4270
+ * `BrnSeparator` through its own `hostDirectives`, and host-directive forwarding is not
4271
+ * transitive (NG2017).
3641
4272
  */
3642
- class YuwPopoverComponent {
3643
- constructor() {
3644
- this.align = input('center', ...(ngDevMode ? [{ debugName: "align" }] : /* istanbul ignore next */ []));
3645
- this.description = input(undefined, ...(ngDevMode ? [{ debugName: "description" }] : /* istanbul ignore next */ []));
3646
- this.offsetX = input(0, ...(ngDevMode ? [{ debugName: "offsetX" }] : /* istanbul ignore next */ []));
3647
- this.open = model(false, ...(ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []));
3648
- this.panelClass = input(undefined, ...(ngDevMode ? [{ debugName: "panelClass" }] : /* istanbul ignore next */ []));
3649
- this.showTrigger = input(true, { ...(ngDevMode ? { debugName: "showTrigger" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
3650
- this.sideOffset = input(4, ...(ngDevMode ? [{ debugName: "sideOffset" }] : /* istanbul ignore next */ []));
3651
- this.title = input(undefined, ...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
3652
- this.triggerClass = input('', ...(ngDevMode ? [{ debugName: "triggerClass" }] : /* istanbul ignore next */ []));
3653
- this.triggerColor = input('secondary', ...(ngDevMode ? [{ debugName: "triggerColor" }] : /* istanbul ignore next */ []));
3654
- this.triggerSize = input('default', ...(ngDevMode ? [{ debugName: "triggerSize" }] : /* istanbul ignore next */ []));
3655
- this.triggerTransparent = input(false, { ...(ngDevMode ? { debugName: "triggerTransparent" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
3656
- this.triggerVariant = input('outline', ...(ngDevMode ? [{ debugName: "triggerVariant" }] : /* istanbul ignore next */ []));
3657
- this._popoverState = computed(() => (this.open() ? 'open' : 'closed'), ...(ngDevMode ? [{ debugName: "_popoverState" }] : /* istanbul ignore next */ []));
3658
- }
3659
- onOpenChange(state) {
3660
- this.open.set(state === 'open');
3661
- }
3662
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwPopoverComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3663
- 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" }, ngImport: i0, template: "<div\n hlmPopover\n [state]=\"_popoverState()\"\n [align]=\"align()\"\n [sideOffset]=\"sideOffset()\"\n [offsetX]=\"offsetX()\"\n (stateChanged)=\"onOpenChange($event)\"\n>\n @if (showTrigger()) {\n <yuw-button\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$i.HlmPopover, selector: "[hlmPopover],hlm-popover" }, { kind: "directive", type: i1$i.HlmPopoverContent, selector: "[hlmPopoverContent],hlm-popover-content" }, { kind: "directive", type: i1$i.HlmPopoverDescription, selector: "[hlmPopoverDescription]" }, { kind: "directive", type: i1$i.HlmPopoverHeader, selector: "[hlmPopoverHeader],hlm-popover-header" }, { kind: "directive", type: i1$i.HlmPopoverPortal, selector: "[hlmPopoverPortal]" }, { kind: "directive", type: i1$i.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 }); }
4273
+ class YuwItemSeparatorDirective extends HlmItemSeparator {
4274
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwItemSeparatorDirective, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
4275
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwItemSeparatorDirective, isStandalone: true, selector: "[yuwItemSeparator], yuw-item-separator", usesInheritance: true, ngImport: i0 }); }
3664
4276
  }
3665
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwPopoverComponent, decorators: [{
3666
- type: Component,
3667
- args: [{ selector: 'yuw-popover', imports: [...HlmPopoverImports, YuwButtonComponent, YuwPopoverTriggerDirective], host: {
3668
- class: 'contents',
3669
- }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n hlmPopover\n [state]=\"_popoverState()\"\n [align]=\"align()\"\n [sideOffset]=\"sideOffset()\"\n [offsetX]=\"offsetX()\"\n (stateChanged)=\"onOpenChange($event)\"\n>\n @if (showTrigger()) {\n <yuw-button\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" }]
3670
- }], propDecorators: { 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 }] }] } });
4277
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwItemSeparatorDirective, decorators: [{
4278
+ type: Directive,
4279
+ args: [{
4280
+ selector: '[yuwItemSeparator], yuw-item-separator',
4281
+ }]
4282
+ }] });
4283
+ /** Every item part, for a consumer's `imports`. */
4284
+ const YuwItemImports = [
4285
+ YuwItemDirective,
4286
+ YuwItemHeaderDirective,
4287
+ YuwItemMediaDirective,
4288
+ YuwItemContentDirective,
4289
+ YuwItemTitleDirective,
4290
+ YuwItemDescriptionDirective,
4291
+ YuwItemActionsDirective,
4292
+ YuwItemFooterDirective,
4293
+ YuwItemGroupDirective,
4294
+ YuwItemSeparatorDirective,
4295
+ ];
3671
4296
 
3672
4297
  /**
3673
4298
  * Tooltip directive applied directly to the element that should show a hint on hover/focus.
@@ -3696,7 +4321,7 @@ class YuwTooltipDirective {
3696
4321
  tooltipContentClasses: DEFAULT_TOOLTIP_CONTENT_CLASSES,
3697
4322
  arrowClasses: (position) => hlm(tooltipPositionVariants({ position })),
3698
4323
  }),
3699
- ], hostDirectives: [{ directive: i1$j.BrnTooltip, inputs: ["brnTooltip", "yuwTooltip", "position", "position", "hideDelay", "hideDelay", "showDelay", "showDelay", "tooltipDisabled", "tooltipDisabled"] }], ngImport: i0 }); }
4324
+ ], hostDirectives: [{ directive: i1$k.BrnTooltip, inputs: ["brnTooltip", "yuwTooltip", "position", "position", "hideDelay", "hideDelay", "showDelay", "showDelay", "tooltipDisabled", "tooltipDisabled"] }], ngImport: i0 }); }
3700
4325
  }
3701
4326
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwTooltipDirective, decorators: [{
3702
4327
  type: Directive,
@@ -3916,7 +4541,7 @@ const YuwAlertImports = [
3916
4541
  */
3917
4542
  class YuwDialogTriggerDirective {
3918
4543
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwDialogTriggerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
3919
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwDialogTriggerDirective, isStandalone: true, selector: "yuw-button[yuwDialogTriggerFor], yuw-button[yuwDialogTriggerButton]", host: { attributes: { "data-slot": "dialog-trigger" } }, hostDirectives: [{ directive: i1$k.BrnDialogTrigger, inputs: ["id", "id", "brnDialogTriggerFor", "yuwDialogTriggerFor", "type", "type"] }], ngImport: i0 }); }
4544
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwDialogTriggerDirective, isStandalone: true, selector: "yuw-button[yuwDialogTriggerFor], yuw-button[yuwDialogTriggerButton]", host: { attributes: { "data-slot": "dialog-trigger" } }, hostDirectives: [{ directive: i1$l.BrnDialogTrigger, inputs: ["id", "id", "brnDialogTriggerFor", "yuwDialogTriggerFor", "type", "type"] }], ngImport: i0 }); }
3920
4545
  }
3921
4546
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwDialogTriggerDirective, decorators: [{
3922
4547
  type: Directive,
@@ -3929,7 +4554,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
3929
4554
  /** Closes the surrounding `<yuw-dialog>` when the host `<yuw-button>` is activated. */
3930
4555
  class YuwDialogCloseDirective {
3931
4556
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwDialogCloseDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
3932
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwDialogCloseDirective, isStandalone: true, selector: "yuw-button[yuwDialogClose]", host: { attributes: { "data-slot": "dialog-close" } }, hostDirectives: [{ directive: i1$k.BrnDialogClose }], ngImport: i0 }); }
4557
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwDialogCloseDirective, isStandalone: true, selector: "yuw-button[yuwDialogClose]", host: { attributes: { "data-slot": "dialog-close" } }, hostDirectives: [{ directive: i1$l.BrnDialogClose }], ngImport: i0 }); }
3933
4558
  }
3934
4559
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwDialogCloseDirective, decorators: [{
3935
4560
  type: Directive,
@@ -4016,7 +4641,7 @@ class YuwDialogComponent {
4016
4641
  this.open.set(state === 'open');
4017
4642
  }
4018
4643
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4019
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: YuwDialogComponent, isStandalone: true, selector: "yuw-dialog", inputs: { ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, closeLabel: { classPropertyName: "closeLabel", publicName: "closeLabel", 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 }, panelClass: { classPropertyName: "panelClass", publicName: "panelClass", isSignal: true, isRequired: false, transformFunction: null }, showTrigger: { classPropertyName: "showTrigger", publicName: "showTrigger", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", 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 }, 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: YuwDialogFooterDirective, descendants: true, isSignal: true }], ngImport: i0, template: "<hlm-dialog [state]=\"_dialogState()\" [aria-label]=\"ariaLabel()\" (stateChanged)=\"onStateChanged($event)\">\n @if (showTrigger()) {\n <yuw-button yuwDialogTriggerButton [color]=\"triggerColor()\" [variant]=\"triggerVariant()\" [size]=\"triggerSize()\">\n <ng-content select=\"[yuwDialogTrigger]\" />\n </yuw-button>\n }\n\n <hlm-dialog-content\n *hlmDialogPortal\n [showCloseButton]=\"false\"\n class=\"flex max-h-[calc(100dvh-2rem)] flex-col\"\n [class]=\"panelClass()\"\n >\n @if (title() || description()) {\n <div hlmDialogHeader>\n @if (title()) {\n <h2 hlmDialogTitle>{{ title() }}</h2>\n }\n @if (description()) {\n <p hlmDialogDescription>{{ description() }}</p>\n }\n </div>\n }\n\n <div class=\"flex-1 overflow-y-auto\">\n <ng-content />\n </div>\n\n @if (hasFooter()) {\n <div hlmDialogFooter>\n <ng-content select=\"[yuwDialogFooter]\" />\n </div>\n }\n\n @if (closeLabel()) {\n <div class=\"absolute inset-e-2 top-1.5\">\n <yuw-button yuwDialogClose 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-dialog-content>\n</hlm-dialog>\n", dependencies: [{ kind: "component", type: i1$l.HlmDialog, selector: "hlm-dialog", exportAs: ["hlmDialog"] }, { kind: "component", type: i1$l.HlmDialogContent, selector: "hlm-dialog-content", inputs: ["showCloseButton"] }, { kind: "directive", type: i1$l.HlmDialogDescription, selector: "[hlmDialogDescription]" }, { kind: "directive", type: i1$l.HlmDialogFooter, selector: "[hlmDialogFooter],hlm-dialog-footer" }, { kind: "directive", type: i1$l.HlmDialogHeader, selector: "[hlmDialogHeader],hlm-dialog-header" }, { kind: "directive", type: i1$l.HlmDialogPortal, selector: "[hlmDialogPortal]" }, { kind: "directive", type: i1$l.HlmDialogTitle, selector: "[hlmDialogTitle]" }, { 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: YuwDialogTriggerDirective, selector: "yuw-button[yuwDialogTriggerFor], yuw-button[yuwDialogTriggerButton]" }, { kind: "directive", type: YuwDialogCloseDirective, selector: "yuw-button[yuwDialogClose]" }, { kind: "component", type: NgIcon, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
4644
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: YuwDialogComponent, isStandalone: true, selector: "yuw-dialog", inputs: { ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, closeLabel: { classPropertyName: "closeLabel", publicName: "closeLabel", 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 }, panelClass: { classPropertyName: "panelClass", publicName: "panelClass", isSignal: true, isRequired: false, transformFunction: null }, showTrigger: { classPropertyName: "showTrigger", publicName: "showTrigger", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", 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 }, 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: YuwDialogFooterDirective, descendants: true, isSignal: true }], ngImport: i0, template: "<hlm-dialog [state]=\"_dialogState()\" [aria-label]=\"ariaLabel()\" (stateChanged)=\"onStateChanged($event)\">\n @if (showTrigger()) {\n <yuw-button yuwDialogTriggerButton [color]=\"triggerColor()\" [variant]=\"triggerVariant()\" [size]=\"triggerSize()\">\n <ng-content select=\"[yuwDialogTrigger]\" />\n </yuw-button>\n }\n\n <hlm-dialog-content\n *hlmDialogPortal\n [showCloseButton]=\"false\"\n class=\"flex max-h-[calc(100dvh-2rem)] flex-col\"\n [class]=\"panelClass()\"\n >\n @if (title() || description()) {\n <div hlmDialogHeader>\n @if (title()) {\n <h2 hlmDialogTitle>{{ title() }}</h2>\n }\n @if (description()) {\n <p hlmDialogDescription>{{ description() }}</p>\n }\n </div>\n }\n\n <div class=\"flex-1 overflow-y-auto\">\n <ng-content />\n </div>\n\n @if (hasFooter()) {\n <div hlmDialogFooter>\n <ng-content select=\"[yuwDialogFooter]\" />\n </div>\n }\n\n @if (closeLabel()) {\n <div class=\"absolute inset-e-2 top-1.5\">\n <yuw-button yuwDialogClose 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-dialog-content>\n</hlm-dialog>\n", dependencies: [{ kind: "component", type: i1$m.HlmDialog, selector: "hlm-dialog", exportAs: ["hlmDialog"] }, { kind: "component", type: i1$m.HlmDialogContent, selector: "hlm-dialog-content", inputs: ["showCloseButton"] }, { kind: "directive", type: i1$m.HlmDialogDescription, selector: "[hlmDialogDescription]" }, { kind: "directive", type: i1$m.HlmDialogFooter, selector: "[hlmDialogFooter],hlm-dialog-footer" }, { kind: "directive", type: i1$m.HlmDialogHeader, selector: "[hlmDialogHeader],hlm-dialog-header" }, { kind: "directive", type: i1$m.HlmDialogPortal, selector: "[hlmDialogPortal]" }, { kind: "directive", type: i1$m.HlmDialogTitle, selector: "[hlmDialogTitle]" }, { 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: YuwDialogTriggerDirective, selector: "yuw-button[yuwDialogTriggerFor], yuw-button[yuwDialogTriggerButton]" }, { kind: "directive", type: YuwDialogCloseDirective, selector: "yuw-button[yuwDialogClose]" }, { kind: "component", type: NgIcon, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
4020
4645
  }
4021
4646
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwDialogComponent, decorators: [{
4022
4647
  type: Component,
@@ -4034,7 +4659,7 @@ const YuwDialogImports = [YuwDialogComponent, YuwDialogFooterDirective];
4034
4659
  */
4035
4660
  class YuwAlertDialogTriggerDirective {
4036
4661
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwAlertDialogTriggerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
4037
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwAlertDialogTriggerDirective, isStandalone: true, selector: "yuw-button[yuwAlertDialogTriggerFor], yuw-button[yuwAlertDialogTriggerButton]", host: { attributes: { "data-slot": "alert-dialog-trigger" } }, hostDirectives: [{ directive: i1$m.BrnAlertDialogTrigger, inputs: ["id", "id", "brnAlertDialogTriggerFor", "yuwAlertDialogTriggerFor", "type", "type"] }], ngImport: i0 }); }
4662
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: YuwAlertDialogTriggerDirective, isStandalone: true, selector: "yuw-button[yuwAlertDialogTriggerFor], yuw-button[yuwAlertDialogTriggerButton]", host: { attributes: { "data-slot": "alert-dialog-trigger" } }, hostDirectives: [{ directive: i1$n.BrnAlertDialogTrigger, inputs: ["id", "id", "brnAlertDialogTriggerFor", "yuwAlertDialogTriggerFor", "type", "type"] }], ngImport: i0 }); }
4038
4663
  }
4039
4664
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwAlertDialogTriggerDirective, decorators: [{
4040
4665
  type: Directive,
@@ -4123,7 +4748,7 @@ class YuwAlertDialogComponent {
4123
4748
  this.open.set(state === 'open');
4124
4749
  }
4125
4750
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwAlertDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4126
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: YuwAlertDialogComponent, isStandalone: true, selector: "yuw-alert-dialog", inputs: { cancelLabel: { classPropertyName: "cancelLabel", publicName: "cancelLabel", isSignal: true, isRequired: true, transformFunction: null }, confirmLabel: { classPropertyName: "confirmLabel", publicName: "confirmLabel", isSignal: true, isRequired: true, transformFunction: null }, confirmVariant: { classPropertyName: "confirmVariant", publicName: "confirmVariant", 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 }, showTrigger: { classPropertyName: "showTrigger", publicName: "showTrigger", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: true, 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", cancelled: "cancelled", confirmed: "confirmed" }, host: { classAttribute: "contents" }, queries: [{ propertyName: "hasMedia", first: true, predicate: YuwAlertDialogMediaDirective, descendants: true, isSignal: true }], ngImport: i0, template: "<hlm-alert-dialog [state]=\"_dialogState()\" (stateChanged)=\"onStateChanged($event)\">\n @if (showTrigger()) {\n <yuw-button yuwAlertDialogTriggerButton [variant]=\"triggerVariant()\" [size]=\"triggerSize()\">\n <ng-content select=\"[yuwAlertDialogTrigger]\" />\n </yuw-button>\n }\n\n <hlm-alert-dialog-content *hlmAlertDialogPortal [size]=\"size()\">\n <div hlmAlertDialogHeader>\n @if (hasMedia()) {\n <div hlmAlertDialogMedia>\n <ng-content select=\"[yuwAlertDialogMedia]\" />\n </div>\n }\n\n <h2 hlmAlertDialogTitle>{{ title() }}</h2>\n\n @if (description()) {\n <p hlmAlertDialogDescription>{{ description() }}</p>\n }\n </div>\n\n <ng-content />\n\n <div hlmAlertDialogFooter>\n <button hlmAlertDialogCancel (click)=\"cancelled.emit()\">{{ cancelLabel() }}</button>\n <button hlmAlertDialogAction [variant]=\"confirmVariant()\" (click)=\"confirmed.emit()\">\n {{ confirmLabel() }}\n </button>\n </div>\n </hlm-alert-dialog-content>\n</hlm-alert-dialog>\n", dependencies: [{ kind: "component", type: i1$n.HlmAlertDialog, selector: "hlm-alert-dialog", exportAs: ["hlmAlertDialog"] }, { kind: "directive", type: i1$n.HlmAlertDialogAction, selector: "button[hlmAlertDialogAction]", inputs: ["type"] }, { kind: "directive", type: i1$n.HlmAlertDialogCancel, selector: "button[hlmAlertDialogCancel]", inputs: ["type"] }, { kind: "directive", type: i1$n.HlmAlertDialogContent, selector: "[hlmAlertDialogContent],hlm-alert-dialog-content", inputs: ["size"] }, { kind: "directive", type: i1$n.HlmAlertDialogDescription, selector: "[hlmAlertDialogDescription]" }, { kind: "directive", type: i1$n.HlmAlertDialogFooter, selector: "[hlmAlertDialogFooter],hlm-alert-dialog-footer" }, { kind: "directive", type: i1$n.HlmAlertDialogHeader, selector: "[hlmAlertDialogHeader],hlm-alert-dialog-header" }, { kind: "directive", type: i1$n.HlmAlertDialogMedia, selector: "[hlmAlertDialogMedia],hlm-alert-dialog-media" }, { kind: "directive", type: i1$n.HlmAlertDialogPortal, selector: "[hlmAlertDialogPortal]" }, { kind: "directive", type: i1$n.HlmAlertDialogTitle, selector: "[hlmAlertDialogTitle]" }, { 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: YuwAlertDialogTriggerDirective, selector: "yuw-button[yuwAlertDialogTriggerFor], yuw-button[yuwAlertDialogTriggerButton]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
4751
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: YuwAlertDialogComponent, isStandalone: true, selector: "yuw-alert-dialog", inputs: { cancelLabel: { classPropertyName: "cancelLabel", publicName: "cancelLabel", isSignal: true, isRequired: true, transformFunction: null }, confirmLabel: { classPropertyName: "confirmLabel", publicName: "confirmLabel", isSignal: true, isRequired: true, transformFunction: null }, confirmVariant: { classPropertyName: "confirmVariant", publicName: "confirmVariant", 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 }, showTrigger: { classPropertyName: "showTrigger", publicName: "showTrigger", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: true, 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", cancelled: "cancelled", confirmed: "confirmed" }, host: { classAttribute: "contents" }, queries: [{ propertyName: "hasMedia", first: true, predicate: YuwAlertDialogMediaDirective, descendants: true, isSignal: true }], ngImport: i0, template: "<hlm-alert-dialog [state]=\"_dialogState()\" (stateChanged)=\"onStateChanged($event)\">\n @if (showTrigger()) {\n <yuw-button yuwAlertDialogTriggerButton [variant]=\"triggerVariant()\" [size]=\"triggerSize()\">\n <ng-content select=\"[yuwAlertDialogTrigger]\" />\n </yuw-button>\n }\n\n <hlm-alert-dialog-content *hlmAlertDialogPortal [size]=\"size()\">\n <div hlmAlertDialogHeader>\n @if (hasMedia()) {\n <div hlmAlertDialogMedia>\n <ng-content select=\"[yuwAlertDialogMedia]\" />\n </div>\n }\n\n <h2 hlmAlertDialogTitle>{{ title() }}</h2>\n\n @if (description()) {\n <p hlmAlertDialogDescription>{{ description() }}</p>\n }\n </div>\n\n <ng-content />\n\n <div hlmAlertDialogFooter>\n <button hlmAlertDialogCancel (click)=\"cancelled.emit()\">{{ cancelLabel() }}</button>\n <button hlmAlertDialogAction [variant]=\"confirmVariant()\" (click)=\"confirmed.emit()\">\n {{ confirmLabel() }}\n </button>\n </div>\n </hlm-alert-dialog-content>\n</hlm-alert-dialog>\n", dependencies: [{ kind: "component", type: i1$o.HlmAlertDialog, selector: "hlm-alert-dialog", exportAs: ["hlmAlertDialog"] }, { kind: "directive", type: i1$o.HlmAlertDialogAction, selector: "button[hlmAlertDialogAction]", inputs: ["type"] }, { kind: "directive", type: i1$o.HlmAlertDialogCancel, selector: "button[hlmAlertDialogCancel]", inputs: ["type"] }, { kind: "directive", type: i1$o.HlmAlertDialogContent, selector: "[hlmAlertDialogContent],hlm-alert-dialog-content", inputs: ["size"] }, { kind: "directive", type: i1$o.HlmAlertDialogDescription, selector: "[hlmAlertDialogDescription]" }, { kind: "directive", type: i1$o.HlmAlertDialogFooter, selector: "[hlmAlertDialogFooter],hlm-alert-dialog-footer" }, { kind: "directive", type: i1$o.HlmAlertDialogHeader, selector: "[hlmAlertDialogHeader],hlm-alert-dialog-header" }, { kind: "directive", type: i1$o.HlmAlertDialogMedia, selector: "[hlmAlertDialogMedia],hlm-alert-dialog-media" }, { kind: "directive", type: i1$o.HlmAlertDialogPortal, selector: "[hlmAlertDialogPortal]" }, { kind: "directive", type: i1$o.HlmAlertDialogTitle, selector: "[hlmAlertDialogTitle]" }, { 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: YuwAlertDialogTriggerDirective, selector: "yuw-button[yuwAlertDialogTriggerFor], yuw-button[yuwAlertDialogTriggerButton]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
4127
4752
  }
4128
4753
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwAlertDialogComponent, decorators: [{
4129
4754
  type: Component,
@@ -4132,134 +4757,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
4132
4757
  }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<hlm-alert-dialog [state]=\"_dialogState()\" (stateChanged)=\"onStateChanged($event)\">\n @if (showTrigger()) {\n <yuw-button yuwAlertDialogTriggerButton [variant]=\"triggerVariant()\" [size]=\"triggerSize()\">\n <ng-content select=\"[yuwAlertDialogTrigger]\" />\n </yuw-button>\n }\n\n <hlm-alert-dialog-content *hlmAlertDialogPortal [size]=\"size()\">\n <div hlmAlertDialogHeader>\n @if (hasMedia()) {\n <div hlmAlertDialogMedia>\n <ng-content select=\"[yuwAlertDialogMedia]\" />\n </div>\n }\n\n <h2 hlmAlertDialogTitle>{{ title() }}</h2>\n\n @if (description()) {\n <p hlmAlertDialogDescription>{{ description() }}</p>\n }\n </div>\n\n <ng-content />\n\n <div hlmAlertDialogFooter>\n <button hlmAlertDialogCancel (click)=\"cancelled.emit()\">{{ cancelLabel() }}</button>\n <button hlmAlertDialogAction [variant]=\"confirmVariant()\" (click)=\"confirmed.emit()\">\n {{ confirmLabel() }}\n </button>\n </div>\n </hlm-alert-dialog-content>\n</hlm-alert-dialog>\n" }]
4133
4758
  }], propDecorators: { hasMedia: [{ type: i0.ContentChild, args: [i0.forwardRef(() => YuwAlertDialogMediaDirective), { isSignal: true }] }], cancelLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "cancelLabel", required: true }] }], confirmLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "confirmLabel", required: true }] }], confirmVariant: [{ type: i0.Input, args: [{ isSignal: true, alias: "confirmVariant", 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"] }], showTrigger: [{ type: i0.Input, args: [{ isSignal: true, alias: "showTrigger", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: true }] }], triggerSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "triggerSize", required: false }] }], triggerVariant: [{ type: i0.Input, args: [{ isSignal: true, alias: "triggerVariant", required: false }] }], cancelled: [{ type: i0.Output, args: ["cancelled"] }], confirmed: [{ type: i0.Output, args: ["confirmed"] }] } });
4134
4759
 
4135
- /**
4136
- * Size classes for `<yuw-tabs>`, applied to the `hlm-tabs-list`.
4137
- *
4138
- * Two things scale, and both have to be written with the helm's own modifier prefixes so
4139
- * tailwind-merge displaces the helm class rather than leaving it standing:
4140
- *
4141
- * - The list height, declared by the helm as `group-data-horizontal/tabs:h-8`. Only the horizontal
4142
- * orientation has a fixed height; the vertical one is `h-fit` and is left alone.
4143
- * - The triggers' horizontal padding, reached through a descendant selector. The helm's `px-1.5` is
4144
- * tight enough that a taller list would look cramped, and the triggers are separate components
4145
- * with no class passthrough. Their height needs nothing — `h-[calc(100%-1px)]` already tracks the
4146
- * list.
4147
- */
4148
- const yuwTabsSizeVariants = cva('', {
4149
- variants: {
4150
- size: {
4151
- default: 'group-data-horizontal/tabs:h-10 [&_[data-slot=tabs-trigger]]:px-2.5',
4152
- xs: 'group-data-horizontal/tabs:h-7 [&_[data-slot=tabs-trigger]]:px-1.5',
4153
- sm: 'group-data-horizontal/tabs:h-9 [&_[data-slot=tabs-trigger]]:px-2',
4154
- lg: 'group-data-horizontal/tabs:h-11 [&_[data-slot=tabs-trigger]]:px-3',
4155
- },
4156
- },
4157
- defaultVariants: {
4158
- size: 'default',
4159
- },
4160
- });
4161
-
4162
- /**
4163
- * Declares the content of a single `<yuw-tabs>` panel. Apply it to an `<ng-template>` and pass the
4164
- * id of the tab it belongs to, matching an entry in the `tabs` input.
4165
- *
4166
- * Usage:
4167
- * ```html
4168
- * <ng-template yuwTabPanel="billing">Contenido de facturación</ng-template>
4169
- * ```
4170
- */
4171
- class YuwTabPanelDirective {
4172
- constructor() {
4173
- this.templateRef = inject(TemplateRef);
4174
- this.tabId = input.required({ ...(ngDevMode ? { debugName: "tabId" } : /* istanbul ignore next */ {}), alias: 'yuwTabPanel' });
4175
- }
4176
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwTabPanelDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
4177
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.22", type: YuwTabPanelDirective, isStandalone: true, selector: "ng-template[yuwTabPanel]", inputs: { tabId: { classPropertyName: "tabId", publicName: "yuwTabPanel", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0 }); }
4178
- }
4179
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwTabPanelDirective, decorators: [{
4180
- type: Directive,
4181
- args: [{
4182
- selector: 'ng-template[yuwTabPanel]',
4183
- }]
4184
- }], propDecorators: { tabId: [{ type: i0.Input, args: [{ isSignal: true, alias: "yuwTabPanel", required: true }] }] } });
4185
-
4186
- class YuwTabContentDirective {
4187
- constructor() {
4188
- this.templateRef = inject(TemplateRef);
4189
- this.entryId = input.required({ ...(ngDevMode ? { debugName: "entryId" } : /* istanbul ignore next */ {}), alias: 'yuwTabContent' });
4190
- }
4191
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwTabContentDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
4192
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.22", type: YuwTabContentDirective, isStandalone: true, selector: "ng-template[yuwTabContent]", inputs: { entryId: { classPropertyName: "entryId", publicName: "yuwTabContent", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0 }); }
4193
- }
4194
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwTabContentDirective, decorators: [{
4195
- type: Directive,
4196
- args: [{
4197
- selector: 'ng-template[yuwTabContent]',
4198
- }]
4199
- }], propDecorators: { entryId: [{ type: i0.Input, args: [{ isSignal: true, alias: "yuwTabContent", required: true }] }] } });
4200
-
4201
- /**
4202
- * Tabbed navigation between sibling panels.
4203
- *
4204
- * Triggers come from the `tabs` input; each panel's content is declared by the consumer as an
4205
- * `<ng-template yuwTabPanel="<id>">` whose id matches a tab. Panels are lazy: a panel's content
4206
- * is only instantiated the first time its tab becomes active (and stays alive, hidden, after
4207
- * switching away).
4208
- *
4209
- * Inputs / Models:
4210
- * - `tabs`: The tab definitions (`YuwTabItemDto[]`) rendered as triggers, in order.
4211
- * - `activeTab`: Two-way id of the selected tab. Drive via `[(activeTab)]` to control it
4212
- * programmatically; listen to `activeTabChange` to react to activations.
4213
- * - `size`: Tab-list height, matching the `<yuw-button>` of the same name.
4214
- * - `variant`: Trigger list style (`'default'` filled, `'line'` underlined). Default is `'default'`.
4215
- * - `orientation`: Layout direction (`'horizontal'`, `'vertical'`). Default is `'horizontal'`.
4216
- * - `activationMode`: How keyboard focus activates tabs (`'automatic'` activates on focus,
4217
- * `'manual'` requires Enter/Space). Default is `'automatic'`.
4218
- *
4219
- * Usage:
4220
- * ```html
4221
- * <yuw-tabs [tabs]="tabs" [(activeTab)]="selected">
4222
- * <ng-template yuwTabPanel="general">Contenido general</ng-template>
4223
- * <ng-template yuwTabPanel="billing">Contenido de facturación</ng-template>
4224
- * </yuw-tabs>
4225
- * ```
4226
- */
4227
- class YuwTabsComponent {
4228
- constructor() {
4229
- this._contents = contentChildren(YuwTabContentDirective, ...(ngDevMode ? [{ debugName: "_contents" }] : /* istanbul ignore next */ []));
4230
- this.panels = contentChildren(YuwTabPanelDirective, ...(ngDevMode ? [{ debugName: "panels" }] : /* istanbul ignore next */ []));
4231
- this.activationMode = input('automatic', ...(ngDevMode ? [{ debugName: "activationMode" }] : /* istanbul ignore next */ []));
4232
- this.activeTab = model.required(...(ngDevMode ? [{ debugName: "activeTab" }] : /* istanbul ignore next */ []));
4233
- this.orientation = input('horizontal', ...(ngDevMode ? [{ debugName: "orientation" }] : /* istanbul ignore next */ []));
4234
- this.size = input('default', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
4235
- this.tabs = input.required(...(ngDevMode ? [{ debugName: "tabs" }] : /* istanbul ignore next */ []));
4236
- this.userClass = input('', { ...(ngDevMode ? { debugName: "userClass" } : /* istanbul ignore next */ {}), alias: 'class' });
4237
- this.variant = input('default', ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
4238
- this._listClass = computed(() => cn(yuwTabsSizeVariants({ size: this.size() }), this.userClass()), ...(ngDevMode ? [{ debugName: "_listClass" }] : /* istanbul ignore next */ []));
4239
- this._resolved = computed(() => {
4240
- const templates = new Map(this._contents().map((content) => [content.entryId(), content.templateRef]));
4241
- const entries = this.tabs();
4242
- return entries.map((entry) => {
4243
- return {
4244
- ...entry,
4245
- template: templates.get(entry.id),
4246
- };
4247
- });
4248
- }, ...(ngDevMode ? [{ debugName: "_resolved" }] : /* istanbul ignore next */ []));
4249
- }
4250
- onTabActivated(tabId) {
4251
- this.activeTab.set(tabId);
4252
- }
4253
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwTabsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4254
- 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$o.HlmTabs, selector: "[hlmTabs],hlm-tabs", inputs: ["tab"] }, { kind: "directive", type: i1$o.HlmTabsList, selector: "[hlmTabsList],hlm-tabs-list", inputs: ["variant"] }, { kind: "directive", type: i1$o.HlmTabsTrigger, selector: "[hlmTabsTrigger]", inputs: ["hlmTabsTrigger"] }, { kind: "directive", type: i1$o.HlmTabsContent, selector: "[hlmTabsContent]", inputs: ["hlmTabsContent"] }, { kind: "directive", type: i1$o.HlmTabsContentLazy, selector: "ng-template[hlmTabsContentLazy]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
4255
- }
4256
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwTabsComponent, decorators: [{
4257
- type: Component,
4258
- args: [{ selector: 'yuw-tabs', imports: [NgTemplateOutlet, ...HlmTabsImports], host: {
4259
- class: 'contents',
4260
- }, changeDetection: ChangeDetectionStrategy.OnPush, 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" }]
4261
- }], propDecorators: { _contents: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => YuwTabContentDirective), { isSignal: true }] }], panels: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => YuwTabPanelDirective), { isSignal: true }] }], activationMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "activationMode", required: false }] }], activeTab: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeTab", required: true }] }, { type: i0.Output, args: ["activeTabChange"] }], orientation: [{ type: i0.Input, args: [{ isSignal: true, alias: "orientation", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], tabs: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabs", required: true }] }], userClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }] } });
4262
-
4263
4760
  /**
4264
4761
  * Container directive for a single file attachment card.
4265
4762
  *
@@ -4614,8 +5111,8 @@ class YuwSidebarRailService {
4614
5111
  this.sidebar = inject(HlmSidebarService);
4615
5112
  this.collapsed = computed(() => (this.sidebar.isMobile() ? !this.sidebar.openMobile() : !this.sidebar.open()), ...(ngDevMode ? [{ debugName: "collapsed" }] : /* istanbul ignore next */ []));
4616
5113
  this.collapsed$ = toObservable(this.collapsed);
4617
- this.railPending = toSignal(this.collapsed$.pipe(switchMap((collapsed) => (collapsed ? of(true) : timer(YUW_SIDEBAR_TRANSITION_MS).pipe(map(() => false))))), { initialValue: false });
4618
- this.railSettled = toSignal(this.collapsed$.pipe(switchMap((collapsed) => (collapsed ? timer(YUW_SIDEBAR_TRANSITION_MS).pipe(map(() => true)) : of(false)))), { initialValue: false });
5114
+ this.railPending = toSignal(this.collapsed$.pipe(switchMap((collapsed) => (collapsed ? of(true) : timer(YUW_SIDEBAR_TRANSITION_MS).pipe(map$1(() => false))))), { initialValue: false });
5115
+ this.railSettled = toSignal(this.collapsed$.pipe(switchMap((collapsed) => (collapsed ? timer(YUW_SIDEBAR_TRANSITION_MS).pipe(map$1(() => true)) : of(false)))), { initialValue: false });
4619
5116
  }
4620
5117
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwSidebarRailService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
4621
5118
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwSidebarRailService, providedIn: 'root' }); }
@@ -5538,8 +6035,8 @@ class YuwSidebarComponent {
5538
6035
  this.sidebarWidthMobile = input(this.config.sidebarWidthMobile, ...(ngDevMode ? [{ debugName: "sidebarWidthMobile" }] : /* istanbul ignore next */ []));
5539
6036
  this.variant = input('sidebar', ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
5540
6037
  this.itemClicked = output();
5541
- this.collapsedChange = outputFromObservable(toObservable(this._rail.collapsed).pipe(distinctUntilChanged()));
5542
- this.railSettledChange = outputFromObservable(toObservable(this._rail.railSettled).pipe(distinctUntilChanged()));
6038
+ this.collapsedChange = outputFromObservable(toObservable(this._rail.collapsed).pipe(distinctUntilChanged$1()));
6039
+ this.railSettledChange = outputFromObservable(toObservable(this._rail.railSettled).pipe(distinctUntilChanged$1()));
5543
6040
  this._containerClass = computed(() => `${yuwSidebarContainerClass} ${this.sidebarContainerClass()}`, ...(ngDevMode ? [{ debugName: "_containerClass" }] : /* istanbul ignore next */ []));
5544
6041
  this._isRail = computed(() => this.collapsible() === 'icon' && this._rail.railSettled(), ...(ngDevMode ? [{ debugName: "_isRail" }] : /* istanbul ignore next */ []));
5545
6042
  }
@@ -5775,5 +6272,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
5775
6272
  * Generated bundle index. Do not edit.
5776
6273
  */
5777
6274
 
5778
- 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, YuwAlertActionDirective, YuwAlertComponent, YuwAlertDescriptionDirective, YuwAlertDialogComponent, YuwAlertDialogMediaDirective, YuwAlertDialogTriggerDirective, YuwAlertImports, YuwAlertTitleDirective, YuwAttachmentActionDirective, YuwAttachmentActionsDirective, YuwAttachmentContentDirective, YuwAttachmentDescriptionDirective, YuwAttachmentDirective, YuwAttachmentGroupDirective, YuwAttachmentMediaDirective, YuwAttachmentTitleDirective, YuwAttachmentTriggerDirective, YuwAvatarComponent, YuwBadgeComponent, YuwBreadcrumbComponent, YuwButtonComponent, YuwButtonGroupComponent, YuwButtonGroupContentDirective, YuwCaptionDirective, YuwCardActionDirective, YuwCardContentDirective, YuwCardDescriptionDirective, YuwCardDirective, YuwCardFooterDirective, 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, YuwInputAddonImports, YuwInputComponent, YuwInputOtpComponent, YuwItemActionsDirective, YuwItemContentDirective, YuwItemDescriptionDirective, YuwItemDirective, YuwItemFooterDirective, YuwItemGroupDirective, YuwItemHeaderDirective, YuwItemImports, YuwItemMediaDirective, YuwItemSeparatorDirective, YuwItemTitleDirective, YuwLabel, YuwLeftAddonDirective, 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, cn, datatableCellVariants, datatableContainerVariants, datatableHeadVariants, datatableHeaderCellVariants, datatableRowVariants, getPaginationRange, provideValueAccessor, totalInputOtpLength, yuwCommandDefaultFilter };
6275
+ 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 };
5779
6276
  //# sourceMappingURL=yukit-web.mjs.map