yukit-web 0.2.7 → 0.2.9

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.
@@ -128,6 +128,9 @@ function cn(...inputs) {
128
128
  * ```html
129
129
  * <button hlmBtn [size]="size()" [yuwClass]="_btnClass()">Save</button>
130
130
  * ```
131
+ *
132
+ * Inputs:
133
+ * - `yuwClass`: String of CSS classes registered as a replaceable `classes()` source on the host. Default is `''`.
131
134
  */
132
135
  class YuwClassDirective {
133
136
  constructor() {
@@ -179,6 +182,10 @@ function provideValueAccessor(component) {
179
182
  *
180
183
  * They're kept as two separate signals and OR'd together in `_disabled`: disabled by *either*
181
184
  * source means disabled. That's the only combination that never drops a caller's intent.
185
+ *
186
+ * Inputs:
187
+ * - `disabled`: Disables the form control and blocks user interaction. Combined with the disabled
188
+ * state coming from the forms API, so either one disables it. Default is `false`.
182
189
  */
183
190
  class YuwValueAccessorBase {
184
191
  constructor() {
@@ -241,6 +248,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
241
248
  * forward to its native input — lives one level down, per the Liskov rule in `AGENTS.md`.
242
249
  *
243
250
  * Subclasses provide `_autoId`, the fallback `id` used when the consumer sets no `inputId`.
251
+ *
252
+ * Inputs:
253
+ * - `class`: Extra CSS classes merged last onto the field's visual element, so they win over the
254
+ * defaults. Bound through the `class` alias of an internal input. Default is `''`.
255
+ * - `errorText`: Error message shown under the field. Default is `undefined`.
256
+ * - `helperText`: Helper message shown under the field. Default is `undefined`.
257
+ * - `inputId`: ID set on the native input element, for `<label [for]>` matching. Falls back to a
258
+ * generated ID when unset. Default is `undefined`.
259
+ * - `invalid`: Marks the field as invalid. Default is `false`.
260
+ * - `value`: Two-way bound (`[(value)]`) string value of the field. Default is `''`.
261
+ *
262
+ * Outputs:
263
+ * - `valueChange`: Emits the new string whenever `value` changes, enabling two-way binding.
244
264
  */
245
265
  class YuwFieldBase extends YuwValueAccessorBase {
246
266
  constructor() {
@@ -272,6 +292,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
272
292
  * the controls can't drift apart — the Liskov rule in `AGENTS.md`: same-role components share one
273
293
  * input contract. Anything only some of them honor (`maxlength`, `size`, `enterPressed`, …) stays
274
294
  * on the component, never here.
295
+ *
296
+ * Inputs:
297
+ * - `autocomplete`: Native `autocomplete` attribute forwarded to the control. Default is `undefined`.
298
+ * - `name`: Native `name` attribute forwarded to the control. Default is `undefined`.
299
+ * - `placeholder`: Native placeholder text. Default is `undefined`.
300
+ * - `readonly`: Makes the control read-only. Default is `false`.
301
+ * - `required`: Marks the control as required. Default is `false`.
275
302
  */
276
303
  class YuwTextFieldBase extends YuwFieldBase {
277
304
  constructor() {
@@ -430,6 +457,8 @@ const yuwButtonVariants = cva('', {
430
457
  * - `class`: Extra CSS classes merged onto the inner button/anchor; merged last, so they win over the component's own classes.
431
458
  * - `yuwDropdownMenuTrigger`: Optional dropdown menu template reference to trigger.
432
459
  * - `ariaLabel`: Accessible label for screen readers.
460
+ * - `animationDisabled`: Removes the pressed-state translate animation. Default is `false`. It is also
461
+ * forced on when the host carries `aria-haspopup` (e.g. when used as an overlay trigger).
433
462
  *
434
463
  * Outputs:
435
464
  * - `clicked`: Emits MouseEvent on click.
@@ -559,6 +588,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
559
588
  * </ng-template>
560
589
  * </yuw-button-group>
561
590
  * ```
591
+ *
592
+ * Inputs:
593
+ * - `yuwButtonGroupContent`: Required string; id of the button group entry this template renders the content of.
562
594
  */
563
595
  class YuwButtonGroupContentDirective {
564
596
  constructor() {
@@ -698,6 +730,16 @@ const REMOVE_TEXT_CLASS = {
698
730
  * (`variant`), dismissible action (`removeLabel` / `removed`), and a compact dot mode (`dot`)
699
731
  * that renders no content at all.
700
732
  *
733
+ * Inputs:
734
+ * - `color`: Brand color theme (any `YuwColorDto` value). Default is `'primary'`.
735
+ * - `dot`: Renders a compact dot with no content, icon or remove button. Default is `false`.
736
+ * - `removeLabel`: Accessible label for the remove button; the button only renders when this is set. The app supplies
737
+ * and translates it. Default is `undefined`.
738
+ * - `variant`: Helm badge style (`'default'`, `'secondary'`, `'destructive'`, `'outline'`, `'ghost'`, `'link'`). Default is `'default'`.
739
+ *
740
+ * Outputs:
741
+ * - `removed`: Emits when the remove button is clicked.
742
+ *
701
743
  * Usage:
702
744
  * ```html
703
745
  * <yuw-badge color="primary">New</yuw-badge>
@@ -738,6 +780,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
738
780
  * (`aria-current="page"`); intermediate items render as links when they have an `href` and as
739
781
  * plain text otherwise.
740
782
  *
783
+ * Inputs:
784
+ * - `ariaLabel`: Required accessible label for the navigation landmark. The app supplies and translates it.
785
+ * - `items`: Required array of `YuwBreadcrumbItemDto` (`label`, optional `href`) in hierarchy order.
786
+ * - `separator`: Text rendered between items. Default is `'/'`.
787
+ *
741
788
  * Usage:
742
789
  * ```html
743
790
  * <yuw-breadcrumb
@@ -823,6 +870,19 @@ function getPaginationRange(page, totalPages) {
823
870
  * Controls two-way active page state `[(page)]`, accepts total pages (`totalPages`), accessible
824
871
  * previous/next/ellipsis labels, size and color theme.
825
872
  *
873
+ * Inputs:
874
+ * - `ariaLabel`: Required accessible label of the navigation landmark.
875
+ * - `color`: Brand color theme (any `YuwColorDto` value). Default is `'primary'`.
876
+ * - `ellipsisSrText`: Required screen reader text of the ellipsis between page ranges.
877
+ * - `nextLabel`: Required accessible label of the next page button.
878
+ * - `page`: Required two-way (`[(page)]`) active page, 1-based.
879
+ * - `previousLabel`: Required accessible label of the previous page button.
880
+ * - `size`: Button size (`YuwPaginationSizeDto`). Default is `'icon'`.
881
+ * - `totalPages`: Required total number of pages.
882
+ *
883
+ * Outputs:
884
+ * - `page`: Emits the new active page when the user picks one (the output half of `[(page)]`).
885
+ *
826
886
  * Usage:
827
887
  * ```html
828
888
  * <yuw-pagination
@@ -919,6 +979,9 @@ const yuwFieldMinHeightVariants = cva('', {
919
979
  * </ng-template>
920
980
  * </yuw-combobox>
921
981
  * ```
982
+ *
983
+ * Inputs:
984
+ * - `yuwComboboxItemTypeOf`: Optional array of `YuwComboboxOptionDto`; only used to infer the generic data type of the template context for type checking. Default is `undefined`.
922
985
  */
923
986
  class YuwComboboxItemDirective {
924
987
  constructor() {
@@ -1097,7 +1160,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
1097
1160
  }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-template #itemContent let-option>\n @if (itemTemplate(); as custom) {\n <ng-container\n [ngTemplateOutlet]=\"custom.templateRef\"\n [ngTemplateOutletContext]=\"{\n $implicit: option,\n option: option,\n selected: _selectedValues().has(option.value),\n }\"\n />\n } @else {\n {{ option.label }}\n }\n</ng-template>\n\n@if (multiple()) {\n <hlm-combobox-multiple\n [disabled]=\"_disabled()\"\n [value]=\"_multipleValue()\"\n (valueChange)=\"onValueChange($event)\"\n [(search)]=\"search\"\n [itemToString]=\"_itemToString\"\n (focusout)=\"_onFocusOut($event)\"\n >\n <hlm-combobox-chips [forceInvalid]=\"invalid()\" [class]=\"_chipsClass()\">\n @for (chip of _selectedChips(); track chip.value) {\n <hlm-combobox-chip [value]=\"chip.value\">{{ chip.label }}</hlm-combobox-chip>\n }\n <input hlmComboboxChipInput [id]=\"_controlId()\" [placeholder]=\"placeholder() ?? ''\" />\n </hlm-combobox-chips>\n\n <hlm-combobox-content *hlmComboboxPortal>\n <div hlmComboboxList>\n @for (option of options(); track option.value) {\n <hlm-combobox-item [value]=\"option.value\" [disabled]=\"option.disabled ?? false\">\n <ng-container [ngTemplateOutlet]=\"itemContent\" [ngTemplateOutletContext]=\"{ $implicit: option }\" />\n </hlm-combobox-item>\n }\n </div>\n <hlm-combobox-empty>{{ emptyText() ?? '' }}</hlm-combobox-empty>\n </hlm-combobox-content>\n </hlm-combobox-multiple>\n} @else {\n <hlm-combobox\n [disabled]=\"_disabled()\"\n [value]=\"_singleValue()\"\n (valueChange)=\"onValueChange($event)\"\n [(search)]=\"search\"\n [itemToString]=\"_itemToString\"\n (focusout)=\"_onFocusOut($event)\"\n >\n @if (readonlyTrigger()) {\n <hlm-combobox-trigger\n [buttonId]=\"_controlId()\"\n [forceInvalid]=\"invalid()\"\n [class]=\"_triggerClass()\"\n class=\"w-full justify-between items-center\"\n >\n <hlm-combobox-value class=\"min-w-0 truncate\" [placeholder]=\"placeholder() ?? ''\" />\n </hlm-combobox-trigger>\n } @else {\n <hlm-combobox-input\n [inputId]=\"_controlId()\"\n [placeholder]=\"placeholder() ?? ''\"\n [showClear]=\"_clearVisible()\"\n [clearAriaLabel]=\"clearAriaLabel() ?? ''\"\n [triggerAriaLabel]=\"triggerAriaLabel()\"\n [forceInvalid]=\"invalid()\"\n [class]=\"_fieldClass()\"\n />\n }\n\n <hlm-combobox-content *hlmComboboxPortal>\n @if (readonlyTrigger()) {\n <hlm-combobox-input\n [placeholder]=\"searchPlaceholder() ?? ''\"\n [showClear]=\"_clearVisible()\"\n [clearAriaLabel]=\"clearAriaLabel() ?? ''\"\n [triggerAriaLabel]=\"triggerAriaLabel()\"\n [showTrigger]=\"false\"\n />\n }\n <div hlmComboboxList>\n @for (option of options(); track option.value) {\n <hlm-combobox-item [value]=\"option.value\" [disabled]=\"option.disabled ?? false\">\n <ng-container [ngTemplateOutlet]=\"itemContent\" [ngTemplateOutletContext]=\"{ $implicit: option }\" />\n </hlm-combobox-item>\n }\n </div>\n <hlm-combobox-empty>{{ emptyText() ?? '' }}</hlm-combobox-empty>\n </hlm-combobox-content>\n </hlm-combobox>\n}\n" }]
1098
1161
  }], ctorParameters: () => [], propDecorators: { _multipleBox: [{ type: i0.ViewChild, args: [i0.forwardRef(() => BrnComboboxMultiple), { isSignal: true }] }], _panel: [{ type: i0.ViewChild, args: [i0.forwardRef(() => HlmComboboxContent), { ...{ read: ElementRef }, isSignal: true }] }], _singleBox: [{ type: i0.ViewChild, args: [i0.forwardRef(() => BrnCombobox), { isSignal: true }] }], itemTemplate: [{ type: i0.ContentChild, args: [i0.forwardRef(() => YuwComboboxItemDirective), { isSignal: true }] }], clearAriaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearAriaLabel", required: false }] }], emptyText: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyText", required: false }] }], inputId: [{ type: i0.Input, args: [{ isSignal: true, alias: "inputId", required: false }] }], invalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalid", required: false }] }], keepValueOnEscape: [{ type: i0.Input, args: [{ isSignal: true, alias: "keepValueOnEscape", required: false }] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: true }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], readonlyTrigger: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonlyTrigger", required: false }] }], search: [{ type: i0.Input, args: [{ isSignal: true, alias: "search", required: false }] }, { type: i0.Output, args: ["searchChange"] }], searchPlaceholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchPlaceholder", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], triggerAriaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "triggerAriaLabel", required: true }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }] } });
1099
1162
 
1100
- /** Page size selector and range message of a `YuwPagedList`; in a datatable it takes the pagination slot. */
1163
+ /**
1164
+ * Page size selector and range message of a `YuwPagedList`; in a datatable it takes the pagination slot.
1165
+ *
1166
+ * Inputs:
1167
+ * - `disabled`: Disables the page size selector. Default is `false`.
1168
+ * - `labels`: Required `YuwPageSizeLabels` with the selector label, the text for an empty list and the function that builds the range message.
1169
+ * - `list`: Required `YuwPagedList` whose page size is chosen and whose range is shown in the message.
1170
+ */
1101
1171
  class YuwPageSizeComponent {
1102
1172
  constructor() {
1103
1173
  this.disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
@@ -1113,7 +1183,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
1113
1183
  args: [{ selector: 'yuw-page-size', changeDetection: ChangeDetectionStrategy.OnPush, imports: [YuwComboboxComponent], host: { class: 'flex items-center gap-2' }, template: "<yuw-combobox\n readonlyTrigger\n class=\"w-32\"\n [disabled]=\"disabled()\"\n [options]=\"list().pageSizeOptions\"\n [triggerAriaLabel]=\"labels().label\"\n [value]=\"list().pageSize()\"\n [emptyText]=\"labels().empty\"\n (valueChange)=\"list().pageSize.set($event)\"\n/>\n<p class=\"text-sm text-muted-foreground\">{{ message() }}</p>\n" }]
1114
1184
  }], propDecorators: { disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], labels: [{ type: i0.Input, args: [{ isSignal: true, alias: "labels", required: true }] }], list: [{ type: i0.Input, args: [{ isSignal: true, alias: "list", required: true }] }] } });
1115
1185
 
1116
- /** Pagination footer for lists without a datatable. A disabled `fieldset` blocks its buttons. */
1186
+ /**
1187
+ * Pagination footer for lists without a datatable: the page size selector with its range message
1188
+ * and the page navigation, both driven by one `YuwPagedList`. A disabled `fieldset` blocks its buttons.
1189
+ *
1190
+ * Inputs:
1191
+ * - `disabled`: Disables the page size selector and the page buttons. Default is `false`.
1192
+ * - `labels`: Required `YuwListPaginationLabels` with the consumer's text for the page size selector, the navigation aria label and the previous, next and ellipsis texts.
1193
+ * - `list`: Required `YuwPagedList` holding the current page, page size, total pages and range; changes made in the footer are written back to it.
1194
+ */
1117
1195
  class YuwListPaginationComponent {
1118
1196
  constructor() {
1119
1197
  this.disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
@@ -1141,14 +1219,32 @@ function injectIsMobile() {
1141
1219
  * Page title, optional description and up to two actions, each rendered when its label is set.
1142
1220
  * On mobile the primary action shows only its icon, or `primaryMobileLabel`. Icons are `@ng-icons`
1143
1221
  * names; the consumer registers any beyond `lucidePlus` with `provideIcons`.
1222
+ *
1223
+ * Inputs:
1224
+ * - `backLabel`: Text of the back button, which renders only when set; on small screens only its arrow shows.
1225
+ * - `description`: Optional subtitle under the title.
1226
+ * - `primaryDisabled`: Disables the primary action, which stays visible but ignores clicks, e.g. while the list it creates items for is loading.
1227
+ * - `primaryIcon`: Icon name shown in the primary action.
1228
+ * - `primaryLabel`: Text of the primary action, which renders only when set.
1229
+ * - `primaryMobileLabel`: Text the primary action shows on small screens instead of its label.
1230
+ * - `secondaryIcon`: Icon name shown in the secondary action.
1231
+ * - `secondaryLabel`: Text of the secondary action, which renders only when set; hidden on small screens, leaving its icon.
1232
+ * - `title`: Required page title.
1233
+ *
1234
+ * Outputs:
1235
+ * - `backClicked`: Emits the `MouseEvent` of the back button.
1236
+ * - `primaryClicked`: Emits the `MouseEvent` of the primary action.
1237
+ * - `secondaryClicked`: Emits the `MouseEvent` of the secondary action.
1144
1238
  */
1145
1239
  class YuwPageHeaderComponent {
1146
1240
  constructor() {
1147
1241
  this.backLabel = input(...(ngDevMode ? [undefined, { debugName: "backLabel" }] : /* istanbul ignore next */ []));
1148
1242
  this.description = input(...(ngDevMode ? [undefined, { debugName: "description" }] : /* istanbul ignore next */ []));
1243
+ this.primaryDisabled = input(false, { ...(ngDevMode ? { debugName: "primaryDisabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
1149
1244
  this.primaryIcon = input(...(ngDevMode ? [undefined, { debugName: "primaryIcon" }] : /* istanbul ignore next */ []));
1150
1245
  this.primaryLabel = input(...(ngDevMode ? [undefined, { debugName: "primaryLabel" }] : /* istanbul ignore next */ []));
1151
1246
  this.primaryMobileLabel = input(...(ngDevMode ? [undefined, { debugName: "primaryMobileLabel" }] : /* istanbul ignore next */ []));
1247
+ this.secondaryDisabled = input(false, { ...(ngDevMode ? { debugName: "secondaryDisabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
1152
1248
  this.secondaryIcon = input(...(ngDevMode ? [undefined, { debugName: "secondaryIcon" }] : /* istanbul ignore next */ []));
1153
1249
  this.secondaryLabel = input(...(ngDevMode ? [undefined, { debugName: "secondaryLabel" }] : /* istanbul ignore next */ []));
1154
1250
  this.title = input.required(...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
@@ -1158,12 +1254,12 @@ class YuwPageHeaderComponent {
1158
1254
  this.isMobile = injectIsMobile();
1159
1255
  }
1160
1256
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwPageHeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1161
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: YuwPageHeaderComponent, isStandalone: true, selector: "yuw-page-header", inputs: { backLabel: { classPropertyName: "backLabel", publicName: "backLabel", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, primaryIcon: { classPropertyName: "primaryIcon", publicName: "primaryIcon", isSignal: true, isRequired: false, transformFunction: null }, primaryLabel: { classPropertyName: "primaryLabel", publicName: "primaryLabel", isSignal: true, isRequired: false, transformFunction: null }, primaryMobileLabel: { classPropertyName: "primaryMobileLabel", publicName: "primaryMobileLabel", isSignal: true, isRequired: false, transformFunction: null }, secondaryIcon: { classPropertyName: "secondaryIcon", publicName: "secondaryIcon", isSignal: true, isRequired: false, transformFunction: null }, secondaryLabel: { classPropertyName: "secondaryLabel", publicName: "secondaryLabel", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { backClicked: "backClicked", primaryClicked: "primaryClicked", secondaryClicked: "secondaryClicked" }, providers: [provideIcons({ lucidePlus, lucideArrowLeft })], ngImport: i0, template: "<div class=\"flex flex-wrap items-start justify-center gap-4\">\n <div class=\"flex min-w-0 flex-1 flex-col gap-1\">\n <div class=\"flex items-center gap-4\">\n @if (backLabel(); as label) {\n <yuw-button variant=\"outline\" [size]=\"isMobile() ? 'sm' : 'default'\" (clicked)=\"backClicked.emit($event)\">\n <ng-icon name=\"lucideArrowLeft\" size=\"16\" />\n <span class=\"max-sm:hidden\">{{ label }}</span>\n </yuw-button>\n }\n <div class=\"flex flex-col overflow-hidden\">\n <h1 class=\"truncate text-2xl font-semibold text-foreground\">{{ title() }}</h1>\n @if (description()) {\n <p class=\"truncate text-sm text-muted-foreground\">{{ description() }}</p>\n }\n </div>\n </div>\n </div>\n\n @if (primaryLabel() || secondaryLabel()) {\n <div class=\"flex shrink-0 items-center gap-2\">\n @if (secondaryLabel(); as label) {\n <yuw-button\n variant=\"outline\"\n class=\"gap-2\"\n [size]=\"isMobile() ? 'sm' : 'default'\"\n (clicked)=\"secondaryClicked.emit($event)\"\n >\n @if (secondaryIcon(); as icon) {\n <ng-icon [name]=\"icon\" size=\"16\" />\n }\n <span class=\"max-md:hidden\">{{ label }}</span>\n </yuw-button>\n }\n\n @if (primaryLabel(); as label) {\n <yuw-button\n color=\"primary\"\n class=\"gap-2\"\n [size]=\"isMobile() ? 'sm' : 'default'\"\n (clicked)=\"primaryClicked.emit($event)\"\n >\n @if (primaryIcon(); as icon) {\n <ng-icon [name]=\"icon\" size=\"16\" />\n }\n <span class=\"max-sm:hidden\">{{ label }}</span>\n @if (primaryMobileLabel(); as mobileLabel) {\n <span class=\"sm:hidden\">{{ mobileLabel }}</span>\n }\n </yuw-button>\n }\n </div>\n }\n</div>\n", dependencies: [{ kind: "component", type: NgIcon, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }, { kind: "component", type: YuwButtonComponent, selector: "yuw-button", inputs: ["animationDisabled", "ariaLabel", "color", "disabled", "href", "size", "target", "transparent", "type", "class", "variant", "yuwDropdownMenuTrigger"], outputs: ["clicked"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1257
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: YuwPageHeaderComponent, isStandalone: true, selector: "yuw-page-header", inputs: { backLabel: { classPropertyName: "backLabel", publicName: "backLabel", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, primaryDisabled: { classPropertyName: "primaryDisabled", publicName: "primaryDisabled", isSignal: true, isRequired: false, transformFunction: null }, primaryIcon: { classPropertyName: "primaryIcon", publicName: "primaryIcon", isSignal: true, isRequired: false, transformFunction: null }, primaryLabel: { classPropertyName: "primaryLabel", publicName: "primaryLabel", isSignal: true, isRequired: false, transformFunction: null }, primaryMobileLabel: { classPropertyName: "primaryMobileLabel", publicName: "primaryMobileLabel", isSignal: true, isRequired: false, transformFunction: null }, secondaryDisabled: { classPropertyName: "secondaryDisabled", publicName: "secondaryDisabled", isSignal: true, isRequired: false, transformFunction: null }, secondaryIcon: { classPropertyName: "secondaryIcon", publicName: "secondaryIcon", isSignal: true, isRequired: false, transformFunction: null }, secondaryLabel: { classPropertyName: "secondaryLabel", publicName: "secondaryLabel", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { backClicked: "backClicked", primaryClicked: "primaryClicked", secondaryClicked: "secondaryClicked" }, providers: [provideIcons({ lucidePlus, lucideArrowLeft })], ngImport: i0, template: "<div class=\"flex flex-wrap items-start justify-center gap-4\">\n <div class=\"flex min-w-0 flex-1 flex-col gap-1\">\n <div class=\"flex items-center gap-4\">\n @if (backLabel(); as label) {\n <yuw-button variant=\"outline\" [size]=\"isMobile() ? 'sm' : 'default'\" (clicked)=\"backClicked.emit($event)\">\n <ng-icon name=\"lucideArrowLeft\" size=\"16\" />\n <span class=\"max-sm:hidden\">{{ label }}</span>\n </yuw-button>\n }\n <div class=\"flex flex-col overflow-hidden\">\n <h1 class=\"truncate text-2xl font-semibold text-foreground\">{{ title() }}</h1>\n @if (description()) {\n <p class=\"truncate text-sm text-muted-foreground\">{{ description() }}</p>\n }\n </div>\n </div>\n </div>\n\n @if (primaryLabel() || secondaryLabel()) {\n <div class=\"flex shrink-0 items-center gap-2\">\n @if (secondaryLabel(); as label) {\n <yuw-button\n variant=\"outline\"\n class=\"gap-2\"\n [size]=\"isMobile() ? 'sm' : 'default'\"\n [disabled]=\"secondaryDisabled()\"\n (clicked)=\"secondaryClicked.emit($event)\"\n >\n @if (secondaryIcon(); as icon) {\n <ng-icon [name]=\"icon\" size=\"16\" />\n }\n <span class=\"max-md:hidden\">{{ label }}</span>\n </yuw-button>\n }\n\n @if (primaryLabel(); as label) {\n <yuw-button\n color=\"primary\"\n class=\"gap-2\"\n [disabled]=\"primaryDisabled()\"\n [size]=\"isMobile() ? 'sm' : 'default'\"\n (clicked)=\"primaryClicked.emit($event)\"\n >\n @if (primaryIcon(); as icon) {\n <ng-icon [name]=\"icon\" size=\"16\" />\n }\n <span class=\"max-sm:hidden\">{{ label }}</span>\n @if (primaryMobileLabel(); as mobileLabel) {\n <span class=\"sm:hidden\">{{ mobileLabel }}</span>\n }\n </yuw-button>\n }\n </div>\n }\n</div>\n", dependencies: [{ kind: "component", type: NgIcon, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }, { kind: "component", type: YuwButtonComponent, selector: "yuw-button", inputs: ["animationDisabled", "ariaLabel", "color", "disabled", "href", "size", "target", "transparent", "type", "class", "variant", "yuwDropdownMenuTrigger"], outputs: ["clicked"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1162
1258
  }
1163
1259
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwPageHeaderComponent, decorators: [{
1164
1260
  type: Component,
1165
- args: [{ selector: 'yuw-page-header', changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgIcon, YuwButtonComponent], providers: [provideIcons({ lucidePlus, lucideArrowLeft })], template: "<div class=\"flex flex-wrap items-start justify-center gap-4\">\n <div class=\"flex min-w-0 flex-1 flex-col gap-1\">\n <div class=\"flex items-center gap-4\">\n @if (backLabel(); as label) {\n <yuw-button variant=\"outline\" [size]=\"isMobile() ? 'sm' : 'default'\" (clicked)=\"backClicked.emit($event)\">\n <ng-icon name=\"lucideArrowLeft\" size=\"16\" />\n <span class=\"max-sm:hidden\">{{ label }}</span>\n </yuw-button>\n }\n <div class=\"flex flex-col overflow-hidden\">\n <h1 class=\"truncate text-2xl font-semibold text-foreground\">{{ title() }}</h1>\n @if (description()) {\n <p class=\"truncate text-sm text-muted-foreground\">{{ description() }}</p>\n }\n </div>\n </div>\n </div>\n\n @if (primaryLabel() || secondaryLabel()) {\n <div class=\"flex shrink-0 items-center gap-2\">\n @if (secondaryLabel(); as label) {\n <yuw-button\n variant=\"outline\"\n class=\"gap-2\"\n [size]=\"isMobile() ? 'sm' : 'default'\"\n (clicked)=\"secondaryClicked.emit($event)\"\n >\n @if (secondaryIcon(); as icon) {\n <ng-icon [name]=\"icon\" size=\"16\" />\n }\n <span class=\"max-md:hidden\">{{ label }}</span>\n </yuw-button>\n }\n\n @if (primaryLabel(); as label) {\n <yuw-button\n color=\"primary\"\n class=\"gap-2\"\n [size]=\"isMobile() ? 'sm' : 'default'\"\n (clicked)=\"primaryClicked.emit($event)\"\n >\n @if (primaryIcon(); as icon) {\n <ng-icon [name]=\"icon\" size=\"16\" />\n }\n <span class=\"max-sm:hidden\">{{ label }}</span>\n @if (primaryMobileLabel(); as mobileLabel) {\n <span class=\"sm:hidden\">{{ mobileLabel }}</span>\n }\n </yuw-button>\n }\n </div>\n }\n</div>\n" }]
1166
- }], propDecorators: { backLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "backLabel", required: false }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }], primaryIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "primaryIcon", required: false }] }], primaryLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "primaryLabel", required: false }] }], primaryMobileLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "primaryMobileLabel", required: false }] }], secondaryIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "secondaryIcon", required: false }] }], secondaryLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "secondaryLabel", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: true }] }], backClicked: [{ type: i0.Output, args: ["backClicked"] }], primaryClicked: [{ type: i0.Output, args: ["primaryClicked"] }], secondaryClicked: [{ type: i0.Output, args: ["secondaryClicked"] }] } });
1261
+ args: [{ selector: 'yuw-page-header', changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgIcon, YuwButtonComponent], providers: [provideIcons({ lucidePlus, lucideArrowLeft })], template: "<div class=\"flex flex-wrap items-start justify-center gap-4\">\n <div class=\"flex min-w-0 flex-1 flex-col gap-1\">\n <div class=\"flex items-center gap-4\">\n @if (backLabel(); as label) {\n <yuw-button variant=\"outline\" [size]=\"isMobile() ? 'sm' : 'default'\" (clicked)=\"backClicked.emit($event)\">\n <ng-icon name=\"lucideArrowLeft\" size=\"16\" />\n <span class=\"max-sm:hidden\">{{ label }}</span>\n </yuw-button>\n }\n <div class=\"flex flex-col overflow-hidden\">\n <h1 class=\"truncate text-2xl font-semibold text-foreground\">{{ title() }}</h1>\n @if (description()) {\n <p class=\"truncate text-sm text-muted-foreground\">{{ description() }}</p>\n }\n </div>\n </div>\n </div>\n\n @if (primaryLabel() || secondaryLabel()) {\n <div class=\"flex shrink-0 items-center gap-2\">\n @if (secondaryLabel(); as label) {\n <yuw-button\n variant=\"outline\"\n class=\"gap-2\"\n [size]=\"isMobile() ? 'sm' : 'default'\"\n [disabled]=\"secondaryDisabled()\"\n (clicked)=\"secondaryClicked.emit($event)\"\n >\n @if (secondaryIcon(); as icon) {\n <ng-icon [name]=\"icon\" size=\"16\" />\n }\n <span class=\"max-md:hidden\">{{ label }}</span>\n </yuw-button>\n }\n\n @if (primaryLabel(); as label) {\n <yuw-button\n color=\"primary\"\n class=\"gap-2\"\n [disabled]=\"primaryDisabled()\"\n [size]=\"isMobile() ? 'sm' : 'default'\"\n (clicked)=\"primaryClicked.emit($event)\"\n >\n @if (primaryIcon(); as icon) {\n <ng-icon [name]=\"icon\" size=\"16\" />\n }\n <span class=\"max-sm:hidden\">{{ label }}</span>\n @if (primaryMobileLabel(); as mobileLabel) {\n <span class=\"sm:hidden\">{{ mobileLabel }}</span>\n }\n </yuw-button>\n }\n </div>\n }\n</div>\n" }]
1262
+ }], propDecorators: { backLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "backLabel", required: false }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }], primaryDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "primaryDisabled", required: false }] }], primaryIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "primaryIcon", required: false }] }], primaryLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "primaryLabel", required: false }] }], primaryMobileLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "primaryMobileLabel", required: false }] }], secondaryDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "secondaryDisabled", required: false }] }], secondaryIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "secondaryIcon", required: false }] }], secondaryLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "secondaryLabel", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: true }] }], backClicked: [{ type: i0.Output, args: ["backClicked"] }], primaryClicked: [{ type: i0.Output, args: ["primaryClicked"] }], secondaryClicked: [{ type: i0.Output, args: ["secondaryClicked"] }] } });
1167
1263
 
1168
1264
  /**
1169
1265
  * Container directive for collapsible accordion items.
@@ -1373,6 +1469,7 @@ let nextYuwInputId = 0;
1373
1469
  *
1374
1470
  * Outputs:
1375
1471
  * - `committed`: Emits the current value on the native `change` event (blur/enter).
1472
+ * - `enterPressed`: Emits (`void`) when the Enter key is pressed while the field is focused.
1376
1473
  *
1377
1474
  * Usage:
1378
1475
  * ```html
@@ -1852,6 +1949,7 @@ let nextYuwPasswordInputId = 0;
1852
1949
  *
1853
1950
  * Outputs:
1854
1951
  * - `committed`: Emits the current value on the native `change` event (blur/enter).
1952
+ * - `enterPressed`: Emits (`void`) when the Enter key is pressed while the field is focused.
1855
1953
  *
1856
1954
  * Usage:
1857
1955
  * ```html
@@ -1972,6 +2070,7 @@ let nextYuwInputOtpId = 0;
1972
2070
  *
1973
2071
  * Outputs:
1974
2072
  * - `completed`: Emits the full code string once the final slot is filled (by typing or paste).
2073
+ * - `enterPressed`: Emits (`void`) when the Enter key is pressed while the field is focused.
1975
2074
  *
1976
2075
  * Usage:
1977
2076
  * ```html
@@ -2043,6 +2142,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
2043
2142
  /**
2044
2143
  * Class map for `yuw-checkbox`, layered on top of `HlmCheckbox`'s own classes.
2045
2144
  *
2145
+ * `cursor-pointer` is unconditional too: `HlmCheckbox` ships `cursor-default`, a utility that beats
2146
+ * the global base-layer pointer rule; its `disabled:cursor-not-allowed` still wins when disabled.
2147
+ *
2046
2148
  * The base indeterminate treatment is unconditional — it's how *every* `yuw-checkbox` renders
2047
2149
  * that state, not a variant — so it lives in the cva base, while `primary` is an opt-in
2048
2150
  * boolean variant layered on top (the secondary color is the default).
@@ -2053,6 +2155,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
2053
2155
  * to the DOM and leaving it to specificity.
2054
2156
  */
2055
2157
  const checkboxVariants = cva([
2158
+ 'cursor-pointer',
2056
2159
  'data-[state=indeterminate]:bg-primary',
2057
2160
  'dark:data-[state=indeterminate]:bg-primary',
2058
2161
  'data-[state=indeterminate]:text-primary-foreground',
@@ -2091,7 +2194,7 @@ const checkboxVariants = cva([
2091
2194
  * projected content, pair it with an external `<label [for]>` via `inputId` or set `ariaLabel`.
2092
2195
  *
2093
2196
  * Inputs / Models:
2094
- * - `value` / `checked`: Two-way boolean state of the checkbox. Default is `false`.
2197
+ * - `checked`: Two-way (`[(checked)]`) boolean checked state, alias of the internal `value` model. Default is `false`.
2095
2198
  * - `indeterminate`: Two-way boolean state for mixed/indeterminate checkbox appearance. Default is `false`.
2096
2199
  * - `disabled`: Disables checkbox interaction.
2097
2200
  * - `required`: Marks checkbox as required.
@@ -2216,6 +2319,8 @@ const yuwSwitchSecondaryClass = [
2216
2319
  * - `disabled`: Disables switch interaction.
2217
2320
  * - `inputId`: HTML `id` for the underlying control, enabling external `<label for="...">` association.
2218
2321
  * - `ariaLabel`: Accessible name for switches with no visible adjacent label.
2322
+ * - `ariaLabelledby`: Id of the element that labels the switch, set as `aria-labelledby` on the control.
2323
+ * - `ariaDescribedby`: Id of the element that describes the switch, set as `aria-describedby` on the control.
2219
2324
  *
2220
2325
  * Usage:
2221
2326
  * ```html
@@ -2348,6 +2453,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
2348
2453
  * `skeletonCount` placeholders shaped by `skeletonClass`; `empty` shows `emptyText`; `columnsClass`
2349
2454
  * holds the Tailwind column utilities.
2350
2455
  *
2456
+ * Inputs:
2457
+ * - `columnsClass`: Tailwind grid column utilities applied to the grid and its skeleton. Default is `'grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4'`.
2458
+ * - `empty`: Shows `emptyText` instead of the projected cards. Default is `false`.
2459
+ * - `emptyText`: Required message shown when `empty` is set. The app supplies and translates it.
2460
+ * - `loading`: Shows `skeletonCount` placeholders instead of the content; takes precedence over `empty`. Default is `false`.
2461
+ * - `skeletonClass`: Extra classes sizing each placeholder, e.g. its height. Default is `'h-16'`.
2462
+ * - `skeletonCount`: Number of placeholders shown while loading. Default is `12`.
2463
+ *
2351
2464
  * `YuwCardGridComponent.COLUMNS` holds the column classes admin lists share per view mode — `list`
2352
2465
  * is one column, `block` grows from one to five, and `tags` packs small tag cards up to six — so every listing lays out its cards the same
2353
2466
  * way: `[columnsClass]="YuwCardGridComponent.COLUMNS[mode]"`.
@@ -2375,7 +2488,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
2375
2488
  args: [{ selector: 'yuw-card-grid', changeDetection: ChangeDetectionStrategy.OnPush, imports: [YuwSkeletonDirective], template: "@if (loading()) {\n <div class=\"grid gap-4\" [class]=\"columnsClass()\">\n @for (skeleton of skeletons(); track skeleton) {\n <span yuwSkeleton class=\"block w-full rounded-xl\" [class]=\"skeletonClass()\"></span>\n }\n </div>\n} @else if (empty()) {\n <p class=\"text-sm text-muted-foreground\">{{ emptyText() }}</p>\n} @else {\n <div class=\"grid gap-4\" [class]=\"columnsClass()\">\n <ng-content />\n </div>\n}\n" }]
2376
2489
  }], propDecorators: { columnsClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "columnsClass", required: false }] }], empty: [{ type: i0.Input, args: [{ isSignal: true, alias: "empty", required: false }] }], emptyText: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyText", required: true }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], skeletonClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "skeletonClass", required: false }] }], skeletonCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "skeletonCount", required: false }] }] } });
2377
2490
 
2378
- /** While `pending` the card stays hidden in place under a skeleton, so the grid does not jump. */
2491
+ /**
2492
+ * While `pending` the card stays hidden in place under a skeleton, so the grid does not jump.
2493
+ *
2494
+ * Inputs:
2495
+ * - `pending`: Hides the projected card and overlays a skeleton while it is loading. Default is `false`.
2496
+ */
2379
2497
  class YuwCardGridItemComponent {
2380
2498
  constructor() {
2381
2499
  this.pending = input(false, { ...(ngDevMode ? { debugName: "pending" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
@@ -2700,6 +2818,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
2700
2818
  * </div>
2701
2819
  * </ng-template>
2702
2820
  * ```
2821
+ *
2822
+ * Inputs:
2823
+ * - `yuwContextMenuTrigger`: Required `TemplateRef` of the menu to open on right-click.
2824
+ * - `yuwContextMenuTriggerData`: Optional data made available to the menu template as its context. Default is `undefined`.
2703
2825
  */
2704
2826
  class YuwContextMenuTriggerDirective {
2705
2827
  constructor() {
@@ -2770,6 +2892,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
2770
2892
  * <yuw-context-menu-checkbox-indicator />
2771
2893
  * </button>
2772
2894
  * ```
2895
+ *
2896
+ * Inputs:
2897
+ * - `checked`: Whether the item is currently checked, which shows the projected indicator. Default is `false`.
2898
+ * - `disabled`: Disables the item so it cannot be triggered. Default is `false`.
2773
2899
  */
2774
2900
  class YuwContextMenuCheckboxDirective {
2775
2901
  constructor() {
@@ -2809,6 +2935,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
2809
2935
  * </button>
2810
2936
  * </div>
2811
2937
  * ```
2938
+ *
2939
+ * Inputs:
2940
+ * - `checked`: Whether the item is the selected option, which shows the projected indicator. Default is `false`.
2941
+ * - `disabled`: Disables the item so it cannot be selected. Default is `false`.
2812
2942
  */
2813
2943
  class YuwContextMenuRadioDirective {
2814
2944
  constructor() {
@@ -2901,6 +3031,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
2901
3031
  * <yuw-context-menu-sub-indicator />
2902
3032
  * </button>
2903
3033
  * ```
3034
+ *
3035
+ * Inputs:
3036
+ * - `yuwContextMenuSubTrigger`: Required `TemplateRef` of the sub-menu this item expands.
2904
3037
  */
2905
3038
  class YuwContextMenuSubTriggerDirective {
2906
3039
  constructor() {
@@ -2957,6 +3090,7 @@ let nextUniqueId = 0;
2957
3090
  * - `align`: Popover alignment relative to trigger (`'start'`, `'center'`, `'end'`). Default is `'start'`.
2958
3091
  * - `buttonId`: HTML `id` for the trigger button, enabling external `<label for="...">`
2959
3092
  * association. When omitted, a unique per-instance id is generated.
3093
+ * - `size`: Trigger button height (`YuwFieldSizeDto`), matching the `<yuw-button>` size of the same name. Default is `'default'`.
2960
3094
  * - `class`: Extra classes merged onto the trigger button (e.g. a width), consumer classes win.
2961
3095
  * - `invalid`: Forces invalid styling.
2962
3096
  * - `formatDate`: Custom date formatter function `(date: Date) => string` for the trigger label.
@@ -3227,7 +3361,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
3227
3361
  * - `showTrigger`: Whether to render the trigger button. Set `false` when opening only via `[(open)]`.
3228
3362
  * - `align`: Panel alignment relative to trigger (`'start'`, `'center'`, `'end'`). Default is `'center'`.
3229
3363
  * - `sideOffset`: Pixel offset between the trigger and the panel. Default is `4`.
3230
- * - `sideOffset`: Pixel offset for X sides. Positive px for right, negative for left side.
3364
+ * - `offsetX`: Pixel offset for X sides. Positive px for right, negative for left side.
3231
3365
  * - `title`: Optional header title text. User-facing text the consuming app is responsible for translating.
3232
3366
  * - `description`: Optional header description text. User-facing text the consuming app is responsible for translating.
3233
3367
  * - `panelClass`: Extra classes merged onto the popover panel (e.g. `w-80` to widen it). They win
@@ -3308,6 +3442,20 @@ const INSIDE_COLUMNS_SELECTOR = '.yuw-columns-trigger, hlm-popover-content, hlm-
3308
3442
  * A set `viewMode` adds the list/block switch. The selected entry drops its border so both entries
3309
3443
  * keep the same height, and the entry after it takes back the leading border the group strips, so the
3310
3444
  * seam stays drawn. Consumers get that for free and bind only `viewMode`.
3445
+ *
3446
+ * Inputs:
3447
+ * - `hiddenColumns`: Two-way (`[(hiddenColumns)]`) ids of the columns currently hidden. Default is `[]`.
3448
+ * - `hideableColumns`: Options of the columns the user may hide; the columns button renders only when set.
3449
+ * - `isMobile`: Required flag; below `md` the search collapses into a popover.
3450
+ * - `labels`: Required `YuwListToolbarLabels` with the consumer's text for the controls.
3451
+ * - `search`: Two-way (`[(search)]`) text of the search field, shared by the inline and popover fields. Default is `''`.
3452
+ * - `searchPlaceholder`: Placeholder of the search field; the search renders only when set.
3453
+ * - `showExport`: Renders the export button. Default is `false`.
3454
+ * - `viewMode`: Two-way (`[(viewMode)]`) `YuwViewMode` (`'list'` or `'block'`); the list/block switch renders only when set.
3455
+ *
3456
+ * Outputs:
3457
+ * - `exported`: Emits the `MouseEvent` of the export button click.
3458
+ * - `searched`: Emits the current search text on every keystroke and when it is cleared.
3311
3459
  */
3312
3460
  class YuwListToolbarActionsComponent {
3313
3461
  constructor() {
@@ -3524,6 +3672,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
3524
3672
  }], ctorParameters: () => [], propDecorators: { hasFooter: [{ type: i0.ContentChild, args: [i0.forwardRef(() => YuwSheetFooterDirective), { isSignal: true }] }], sheet: [{ type: i0.ViewChild, args: [i0.forwardRef(() => HlmSheet), { isSignal: true }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], ariaModal: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaModal", required: false }] }], closeLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeLabel", required: false }] }], closeOnOutsidePointerEvents: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnOutsidePointerEvents", required: false }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }], open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }, { type: i0.Output, args: ["openChange"] }], overlayClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "overlayClass", required: false }] }], panelClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "panelClass", required: false }] }], scrollStrategy: [{ type: i0.Input, args: [{ isSignal: true, alias: "scrollStrategy", required: false }] }], showTrigger: [{ type: i0.Input, args: [{ isSignal: true, alias: "showTrigger", required: false }] }], side: [{ type: i0.Input, args: [{ isSignal: true, alias: "side", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], triggerSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "triggerSize", required: false }] }], triggerVariant: [{ type: i0.Input, args: [{ isSignal: true, alias: "triggerVariant", required: false }] }] } });
3525
3673
  const YuwSheetImports = [YuwSheetComponent, YuwSheetFooterDirective];
3526
3674
 
3675
+ /**
3676
+ * Declares the content of a single tab entry. Apply it to an `<ng-template>` and pass the id of the
3677
+ * entry it belongs to; the template is exposed through `templateRef` for the host to render.
3678
+ *
3679
+ * Inputs:
3680
+ * - `yuwTabContent`: Required string; id of the tab entry this template is the content of.
3681
+ */
3527
3682
  class YuwTabContentDirective {
3528
3683
  constructor() {
3529
3684
  this.templateRef = inject(TemplateRef);
@@ -3547,6 +3702,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
3547
3702
  * ```html
3548
3703
  * <ng-template yuwTabPanel="billing">Contenido de facturación</ng-template>
3549
3704
  * ```
3705
+ *
3706
+ * Inputs:
3707
+ * - `yuwTabPanel`: Required string; id of the tab, matching an entry in the `tabs` input, that this panel renders for.
3550
3708
  */
3551
3709
  class YuwTabPanelDirective {
3552
3710
  constructor() {
@@ -3607,6 +3765,7 @@ const yuwTabsSizeVariants = cva('', {
3607
3765
  * - `orientation`: Layout direction (`'horizontal'`, `'vertical'`). Default is `'horizontal'`.
3608
3766
  * - `activationMode`: How keyboard focus activates tabs (`'automatic'` activates on focus,
3609
3767
  * `'manual'` requires Enter/Space). Default is `'automatic'`.
3768
+ * - `class`: Extra classes merged onto the tab list, last, so they win over the component's own classes.
3610
3769
  *
3611
3770
  * Usage:
3612
3771
  * ```html
@@ -3746,6 +3905,17 @@ function filterSetFormTitle(mode, labels) {
3746
3905
  * name field is seeded from `name` and takes focus once rendered. `titleHidden` drops the heading
3747
3906
  * when the host already shows it. `confirmed` emits the trimmed
3748
3907
  * name; a delete confirmation emits the name it was opened with, so the host decides from `mode`.
3908
+ *
3909
+ * Inputs:
3910
+ * - `labels`: Required `YuwFilterSetLabels` with the consumer's text for the titles, the field, the delete message and the buttons.
3911
+ * - `mode`: Required `'save'`, `'rename'` or `'delete'`; picks the heading and whether the name field or the delete message shows.
3912
+ * - `name`: Name the field is seeded with, and the name of the set being deleted. Default is `''`.
3913
+ * - `titleHidden`: Drops the heading when the host already shows it. Default is `false`.
3914
+ *
3915
+ * Outputs:
3916
+ * - `cancelled`: Emits when the user backs out of the form without confirming.
3917
+ * - `confirmed`: Emits the trimmed name, or the opening name when deleting.
3918
+ * - `deleteRequested`: Emits when the delete shortcut of the rename mode is pressed.
3749
3919
  */
3750
3920
  class YuwListToolbarFilterSetFormComponent {
3751
3921
  constructor() {
@@ -3791,6 +3961,22 @@ const STRETCHED_CELL = 'min-w-0 flex-1 [&>yuw-button]:flex [&>yuw-button]:w-full
3791
3961
  * option emits `picked` and the host applies it. `titleHidden` drops the heading when the host
3792
3962
  * already shows it. `stretchActions` makes edit and delete share the row 50/50 with no gap; without
3793
3963
  * it they keep their natural width. Button texts are consumer data, so they are cropped, not wrapped.
3964
+ *
3965
+ * Inputs:
3966
+ * - `canEdit`: Offers the edit and delete actions for the set matching the applied selection. Default is `false`.
3967
+ * - `canSave`: Offers the action that saves the applied selection as a new set. Default is `false`.
3968
+ * - `labels`: Required `YuwFilterSetLabels` with the consumer's text for the select and the actions.
3969
+ * - `selectedId`: Id of the set shown as selected; `NO_FILTER_SET` means none. Default is `NO_FILTER_SET`.
3970
+ * - `sets`: Required saved sets listed in the select.
3971
+ * - `stretchActions`: Makes the edit and delete buttons share the row 50/50 with no gap. Default is `false`.
3972
+ * - `titleHidden`: Drops the heading when the host already shows it. Default is `false`.
3973
+ *
3974
+ * Outputs:
3975
+ * - `deleteRequested`: Emits when the delete action is pressed.
3976
+ * - `editRequested`: Emits when the edit action is pressed.
3977
+ * - `itemEditRequested`: Emits the id of the set whose three-dots button was pressed.
3978
+ * - `picked`: Emits the id of the chosen option, or `NO_FILTER_SET` for none.
3979
+ * - `saveRequested`: Emits when the save action is pressed.
3794
3980
  */
3795
3981
  class YuwListToolbarFilterSetsComponent {
3796
3982
  constructor() {
@@ -3856,6 +4042,15 @@ const FORM_VIEWS = new Set(['save', 'rename', 'delete']);
3856
4042
  * opened from a button, not when it closes, so it does not flash back while closing. A change of
3857
4043
  * layout closes the panel, since a popover opened from a sheet has no anchor to position against.
3858
4044
  * Persisting is the consumer's job: this component only emits `setSaved`, `setRenamed`, `setDeleted`.
4045
+ *
4046
+ * Inputs:
4047
+ * - `disabled`: Disables every button of the group. Default is `false`.
4048
+ * - `groups`: Required filter groups the editor offers, one pane or tab each.
4049
+ * - `idleColor`: Required tone of the buttons while no filter is applied.
4050
+ * - `isMobile`: Required flag; true opens the panel as a bottom sheet, false as a popover.
4051
+ * - `labels`: Required `YuwListToolbarFilterLabels` with the consumer's text for the panel and its buttons.
4052
+ * - `selection`: Two-way (`[(selection)]`) applied filter selection. Default is `{}`.
4053
+ * - `sets`: Saved filter sets; the sets star renders only when given together with `labels.sets`.
3859
4054
  */
3860
4055
  class YuwListToolbarFiltersComponent {
3861
4056
  constructor() {
@@ -4041,6 +4236,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
4041
4236
  * two-way to it (`viewModeChange` is the click listener); its names come from `labels.viewMode`. Saved filter sets need `filterSets` and `labels.filters.sets`;
4042
4237
  * the toolbar emits `setSaved`, `setRenamed` and `setDeleted` and the consumer persists them. `labels` holds every text and the consumer translates it;
4043
4238
  * `idleColor` is the filter trigger tone while nothing is applied.
4239
+ *
4240
+ * Inputs:
4241
+ * - `filterGroups`: Filter groups the editor offers; the filter control renders only when set.
4242
+ * - `filterSets`: Saved filter sets; together with `labels.filters.sets` it enables the sets star.
4243
+ * - `filtersDisabled`: Disables the filter buttons. Default is `false`.
4244
+ * - `hiddenColumns`: Two-way (`[(hiddenColumns)]`) ids of the columns currently hidden. Default is `[]`.
4245
+ * - `hideableColumns`: Options of the columns the user may hide; the columns button renders only when set.
4246
+ * - `idleColor`: `YuwColorDto` tone of the filter trigger while nothing is applied. Default is `'neutral'`.
4247
+ * - `labels`: Required `YuwListToolbarLabels` with the consumer's translated text for every control.
4248
+ * - `search`: Two-way (`[(search)]`) text of the search field. Default is `''`.
4249
+ * - `searchPlaceholder`: Placeholder of the search field; the search renders only when set.
4250
+ * - `selection`: Two-way (`[(selection)]`) applied filter selection, values keyed by group id. Default is `{}`.
4251
+ * - `showExport`: Renders the export button. Default is `false`.
4252
+ * - `viewMode`: Two-way (`[(viewMode)]`) `YuwViewMode` (`'list'` or `'block'`); the list/block switch renders only when set.
4253
+ *
4254
+ * Outputs:
4255
+ * - `exported`: Emits the `MouseEvent` of the export button click.
4256
+ * - `searched`: Emits the current search text on every keystroke and when it is cleared.
4044
4257
  */
4045
4258
  class YuwListToolbarComponent {
4046
4259
  constructor() {
@@ -4147,7 +4360,7 @@ const datatableHeaderCellVariants = cva('', {
4147
4360
  variants: {
4148
4361
  appearance: {
4149
4362
  default: '',
4150
- card: 'h-12 px-4 text-xs font-normal tracking-wider uppercase text-(--neutrals-element-mid)',
4363
+ card: 'h-12 px-4 text-xs font-normal text-(--neutrals-element-mid)',
4151
4364
  },
4152
4365
  },
4153
4366
  defaultVariants: {
@@ -4224,7 +4437,7 @@ const DATATABLE_WRAP_CONTENT_CLASS = 'whitespace-normal max-w-0';
4224
4437
  * `(row, index) => string | undefined` callback to vary them per row (`YuwDatatableRowClass`).
4225
4438
  * - `appearance`: Visual treatment (`YuwDatatableAppearanceDto`). Default is `'default'` —
4226
4439
  * Spartan's plain table. `'card'` frames the table in its own rounded bordered surface with a
4227
- * tinted uppercase header strip and taller rows; the consumer needs no wrapper of its own.
4440
+ * tinted header strip and taller rows; the consumer needs no wrapper of its own.
4228
4441
  *
4229
4442
  * Per-column, through TanStack's `meta` (see `YuwDatatableColumnMeta`). Every class-valued entry
4230
4443
  * takes Tailwind classes, so a column can size itself per breakpoint (`'w-40 lg:w-64'`). They are
@@ -4306,7 +4519,6 @@ class YuwDatatableComponent {
4306
4519
  this.selectable = input(false, { ...(ngDevMode ? { debugName: "selectable" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
4307
4520
  this.sortable = input(false, { ...(ngDevMode ? { debugName: "sortable" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
4308
4521
  this.sorting = model([], ...(ngDevMode ? [{ debugName: "sorting" }] : /* istanbul ignore next */ []));
4309
- this.summary = input(false, { ...(ngDevMode ? { debugName: "summary" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
4310
4522
  this.tableClass = input(undefined, ...(ngDevMode ? [{ debugName: "tableClass" }] : /* istanbul ignore next */ []));
4311
4523
  this.totalItems = input(undefined, ...(ngDevMode ? [{ debugName: "totalItems" }] : /* istanbul ignore next */ []));
4312
4524
  this.rowClicked = output();
@@ -4419,20 +4631,30 @@ class YuwDatatableComponent {
4419
4631
  this.rowClicked.emit(row);
4420
4632
  }
4421
4633
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwDatatableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4422
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: YuwDatatableComponent, isStandalone: true, selector: "yuw-datatable", inputs: { appearance: { classPropertyName: "appearance", publicName: "appearance", isSignal: true, isRequired: false, transformFunction: null }, caption: { classPropertyName: "caption", publicName: "caption", isSignal: true, isRequired: false, transformFunction: null }, cellClass: { classPropertyName: "cellClass", publicName: "cellClass", isSignal: true, isRequired: false, transformFunction: null }, columnFilters: { classPropertyName: "columnFilters", publicName: "columnFilters", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, columnVisibility: { classPropertyName: "columnVisibility", publicName: "columnVisibility", isSignal: true, isRequired: false, transformFunction: null }, data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, emptyText: { classPropertyName: "emptyText", publicName: "emptyText", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, loadingRows: { classPropertyName: "loadingRows", publicName: "loadingRows", isSignal: true, isRequired: false, transformFunction: null }, nextPageLabel: { classPropertyName: "nextPageLabel", publicName: "nextPageLabel", isSignal: true, isRequired: true, transformFunction: null }, paginated: { classPropertyName: "paginated", publicName: "paginated", isSignal: true, isRequired: false, transformFunction: null }, pagination: { classPropertyName: "pagination", publicName: "pagination", isSignal: true, isRequired: false, transformFunction: null }, paginationAriaLabel: { classPropertyName: "paginationAriaLabel", publicName: "paginationAriaLabel", isSignal: true, isRequired: true, transformFunction: null }, paginationEllipsisSrText: { classPropertyName: "paginationEllipsisSrText", publicName: "paginationEllipsisSrText", isSignal: true, isRequired: true, transformFunction: null }, previousPageLabel: { classPropertyName: "previousPageLabel", publicName: "previousPageLabel", isSignal: true, isRequired: true, transformFunction: null }, rowClass: { classPropertyName: "rowClass", publicName: "rowClass", isSignal: true, isRequired: false, transformFunction: null }, rowSelection: { classPropertyName: "rowSelection", publicName: "rowSelection", isSignal: true, isRequired: false, transformFunction: null }, selectable: { classPropertyName: "selectable", publicName: "selectable", isSignal: true, isRequired: false, transformFunction: null }, sortable: { classPropertyName: "sortable", publicName: "sortable", isSignal: true, isRequired: false, transformFunction: null }, sorting: { classPropertyName: "sorting", publicName: "sorting", isSignal: true, isRequired: false, transformFunction: null }, summary: { classPropertyName: "summary", publicName: "summary", isSignal: true, isRequired: false, transformFunction: null }, tableClass: { classPropertyName: "tableClass", publicName: "tableClass", isSignal: true, isRequired: false, transformFunction: null }, totalItems: { classPropertyName: "totalItems", publicName: "totalItems", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { columnFilters: "columnFiltersChange", columnVisibility: "columnVisibilityChange", pagination: "paginationChange", rowSelection: "rowSelectionChange", sorting: "sortingChange", rowClicked: "rowClicked", selectedRowsChange: "selectedRowsChange" }, host: { classAttribute: "contents" }, providers: [provideIcons({ lucideChevronDown, lucideChevronUp, lucideChevronsUpDown })], queries: [{ propertyName: "customPagination", first: true, predicate: YuwDatatablePaginationDirective, descendants: true, isSignal: true }], ngImport: i0, template: "<div yuwTableContainer [class]=\"_containerClass()\">\n <table yuwTable [class]=\"_tableClass()\">\n @if (caption()) {\n <caption yuwCaption>{{ caption() }}</caption>\n }\n\n <thead yuwTHead [class]=\"_headClass()\">\n @for (headerGroup of table.getHeaderGroups(); track headerGroup.id) {\n <tr yuwTr [class]=\"_rowClass()\">\n @for (header of headerGroup.headers; track header.id) {\n @let sorted = header.column.getIsSorted();\n @let headerClasses = _cellClasses().get(header.column.id);\n <th\n yuwTh\n scope=\"col\"\n [attr.colspan]=\"header.colSpan\"\n [attr.aria-sort]=\"sorted ? _ariaSort[sorted] : null\"\n [class]=\"headerClasses?.header\"\n >\n @if (!header.isPlaceholder) {\n @if (sortable() && header.column.getCanSort()) {\n <button\n type=\"button\"\n class=\"inline-flex items-center gap-1 select-none hover:text-foreground/80\"\n (click)=\"header.column.toggleSorting()\"\n >\n <ng-container\n *flexRender=\"header.column.columnDef.header; props: header.getContext(); let rendered\"\n >\n {{ rendered }}\n </ng-container>\n\n <ng-icon [name]=\"_sortIcon[sorted || 'none']\" class=\"shrink-0 text-xs\" aria-hidden=\"true\" />\n </button>\n } @else {\n <ng-container *flexRender=\"header.column.columnDef.header; props: header.getContext(); let rendered\">\n {{ rendered }}\n </ng-container>\n }\n }\n </th>\n }\n </tr>\n }\n </thead>\n\n <tbody yuwTBody>\n @if (loading()) {\n @for (row of _skeletonRows(); track row) {\n <tr yuwTr [class]=\"_rowClass()\">\n @for (column of table.getVisibleLeafColumns(); track column.id) {\n <td yuwTd [class]=\"_cellClasses().get(column.id)?.cell\">\n <span yuwSkeleton class=\"block h-4 w-full\"></span>\n </td>\n }\n </tr>\n }\n } @else if (_isEmpty()) {\n <tr yuwTr [class]=\"_rowClass()\">\n <td yuwTd [attr.colspan]=\"_columnCount()\" class=\"h-24 text-center text-muted-foreground\">\n {{ emptyText() ?? '' }}\n </td>\n </tr>\n } @else {\n @for (row of table.getRowModel().rows; track row.id) {\n <tr\n yuwTr\n [class]=\"_rowClasses().get(row.id)\"\n [attr.data-state]=\"row.getIsSelected() ? 'selected' : null\"\n role=\"button\"\n tabindex=\"0\"\n (click)=\"onRowClick(row.original)\"\n (keydown)=\"onRowKeydown($event, row.original)\"\n >\n @for (cell of row.getVisibleCells(); track cell.id) {\n <td yuwTd [class]=\"_cellClasses().get(cell.column.id)?.cell\">\n <ng-container *flexRender=\"cell.column.columnDef.cell; props: cell.getContext(); let rendered\">\n {{ rendered }}\n </ng-container>\n </td>\n }\n </tr>\n }\n }\n </tbody>\n </table>\n</div>\n\n@if (paginated()) {\n <div class=\"flex items-center flex-wrap justify-end gap-4 py-3 px-1 max-lg:justify-center\">\n @if (customPagination()) {\n <ng-content select=\"[yuwDatatablePagination]\" />\n }\n <yuw-pagination\n [page]=\"currentPage()\"\n (pageChange)=\"onPageChange($event)\"\n [totalPages]=\"table.getPageCount() || 1\"\n [previousLabel]=\"previousPageLabel()\"\n [nextLabel]=\"nextPageLabel()\"\n [ellipsisSrText]=\"paginationEllipsisSrText()\"\n [ariaLabel]=\"paginationAriaLabel()\"\n color=\"neutral\"\n size=\"icon-sm\"\n class=\"flex\"\n />\n </div>\n}\n", dependencies: [{ kind: "directive", type: YuwTableContainerDirective, selector: "[yuwTableContainer]" }, { kind: "directive", type: YuwTableDirective, selector: "[yuwTable]" }, { kind: "directive", type: YuwTHeadDirective, selector: "[yuwTHead]" }, { kind: "directive", type: YuwTBodyDirective, selector: "[yuwTBody]" }, { kind: "directive", type: YuwTrDirective, selector: "[yuwTr]" }, { kind: "directive", type: YuwThDirective, selector: "[yuwTh]" }, { kind: "directive", type: YuwTdDirective, selector: "[yuwTd]" }, { kind: "directive", type: YuwCaptionDirective, selector: "[yuwCaption]" }, { kind: "component", type: YuwPaginationComponent, selector: "yuw-pagination", inputs: ["ariaLabel", "color", "ellipsisSrText", "nextLabel", "page", "previousLabel", "size", "totalPages"], outputs: ["pageChange"] }, { kind: "directive", type: YuwSkeletonDirective, selector: "[yuwSkeleton]" }, { kind: "directive", type: FlexRenderDirective, selector: "ng-template[flexRender]", inputs: ["flexRender", "flexRenderProps", "flexRenderInjector"] }, { kind: "component", type: NgIcon, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
4634
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: YuwDatatableComponent, isStandalone: true, selector: "yuw-datatable", inputs: { appearance: { classPropertyName: "appearance", publicName: "appearance", isSignal: true, isRequired: false, transformFunction: null }, caption: { classPropertyName: "caption", publicName: "caption", isSignal: true, isRequired: false, transformFunction: null }, cellClass: { classPropertyName: "cellClass", publicName: "cellClass", isSignal: true, isRequired: false, transformFunction: null }, columnFilters: { classPropertyName: "columnFilters", publicName: "columnFilters", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, columnVisibility: { classPropertyName: "columnVisibility", publicName: "columnVisibility", isSignal: true, isRequired: false, transformFunction: null }, data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, emptyText: { classPropertyName: "emptyText", publicName: "emptyText", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, loadingRows: { classPropertyName: "loadingRows", publicName: "loadingRows", isSignal: true, isRequired: false, transformFunction: null }, nextPageLabel: { classPropertyName: "nextPageLabel", publicName: "nextPageLabel", isSignal: true, isRequired: true, transformFunction: null }, paginated: { classPropertyName: "paginated", publicName: "paginated", isSignal: true, isRequired: false, transformFunction: null }, pagination: { classPropertyName: "pagination", publicName: "pagination", isSignal: true, isRequired: false, transformFunction: null }, paginationAriaLabel: { classPropertyName: "paginationAriaLabel", publicName: "paginationAriaLabel", isSignal: true, isRequired: true, transformFunction: null }, paginationEllipsisSrText: { classPropertyName: "paginationEllipsisSrText", publicName: "paginationEllipsisSrText", isSignal: true, isRequired: true, transformFunction: null }, previousPageLabel: { classPropertyName: "previousPageLabel", publicName: "previousPageLabel", isSignal: true, isRequired: true, transformFunction: null }, rowClass: { classPropertyName: "rowClass", publicName: "rowClass", isSignal: true, isRequired: false, transformFunction: null }, rowSelection: { classPropertyName: "rowSelection", publicName: "rowSelection", isSignal: true, isRequired: false, transformFunction: null }, selectable: { classPropertyName: "selectable", publicName: "selectable", isSignal: true, isRequired: false, transformFunction: null }, sortable: { classPropertyName: "sortable", publicName: "sortable", isSignal: true, isRequired: false, transformFunction: null }, sorting: { classPropertyName: "sorting", publicName: "sorting", isSignal: true, isRequired: false, transformFunction: null }, tableClass: { classPropertyName: "tableClass", publicName: "tableClass", isSignal: true, isRequired: false, transformFunction: null }, totalItems: { classPropertyName: "totalItems", publicName: "totalItems", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { columnFilters: "columnFiltersChange", columnVisibility: "columnVisibilityChange", pagination: "paginationChange", rowSelection: "rowSelectionChange", sorting: "sortingChange", rowClicked: "rowClicked", selectedRowsChange: "selectedRowsChange" }, host: { classAttribute: "contents" }, providers: [provideIcons({ lucideChevronDown, lucideChevronUp, lucideChevronsUpDown })], queries: [{ propertyName: "customPagination", first: true, predicate: YuwDatatablePaginationDirective, descendants: true, isSignal: true }], ngImport: i0, template: "<div yuwTableContainer [class]=\"_containerClass()\">\n <table yuwTable [class]=\"_tableClass()\">\n @if (caption()) {\n <caption yuwCaption>{{ caption() }}</caption>\n }\n\n <thead yuwTHead [class]=\"_headClass()\">\n @for (headerGroup of table.getHeaderGroups(); track headerGroup.id) {\n <tr yuwTr [class]=\"_rowClass()\">\n @for (header of headerGroup.headers; track header.id) {\n @let sorted = header.column.getIsSorted();\n @let headerClasses = _cellClasses().get(header.column.id);\n <th\n yuwTh\n scope=\"col\"\n [attr.colspan]=\"header.colSpan\"\n [attr.aria-sort]=\"sorted ? _ariaSort[sorted] : null\"\n [class]=\"headerClasses?.header\"\n >\n @if (!header.isPlaceholder) {\n @if (sortable() && header.column.getCanSort()) {\n <button\n type=\"button\"\n class=\"inline-flex items-center gap-1 select-none hover:text-foreground/80\"\n (click)=\"header.column.toggleSorting()\"\n >\n <ng-container\n *flexRender=\"header.column.columnDef.header; props: header.getContext(); let rendered\"\n >\n {{ rendered }}\n </ng-container>\n\n <ng-icon [name]=\"_sortIcon[sorted || 'none']\" class=\"shrink-0 text-xs\" aria-hidden=\"true\" />\n </button>\n } @else {\n <ng-container *flexRender=\"header.column.columnDef.header; props: header.getContext(); let rendered\">\n {{ rendered }}\n </ng-container>\n }\n }\n </th>\n }\n </tr>\n }\n </thead>\n\n <tbody yuwTBody>\n @if (loading()) {\n @for (row of _skeletonRows(); track row) {\n <tr yuwTr [class]=\"_rowClass()\">\n @for (column of table.getVisibleLeafColumns(); track column.id) {\n <td yuwTd [class]=\"_cellClasses().get(column.id)?.cell\">\n <span yuwSkeleton class=\"block h-4 w-full\"></span>\n </td>\n }\n </tr>\n }\n } @else if (_isEmpty()) {\n <tr yuwTr [class]=\"_rowClass()\">\n <td yuwTd [attr.colspan]=\"_columnCount()\" class=\"h-24 text-center text-muted-foreground\">\n {{ emptyText() ?? '' }}\n </td>\n </tr>\n } @else {\n @for (row of table.getRowModel().rows; track row.id) {\n <tr\n yuwTr\n [class]=\"_rowClasses().get(row.id)\"\n [attr.data-state]=\"row.getIsSelected() ? 'selected' : null\"\n role=\"button\"\n tabindex=\"0\"\n (click)=\"onRowClick(row.original)\"\n (keydown)=\"onRowKeydown($event, row.original)\"\n >\n @for (cell of row.getVisibleCells(); track cell.id) {\n <td yuwTd [class]=\"_cellClasses().get(cell.column.id)?.cell\">\n <ng-container *flexRender=\"cell.column.columnDef.cell; props: cell.getContext(); let rendered\">\n {{ rendered }}\n </ng-container>\n </td>\n }\n </tr>\n }\n }\n </tbody>\n </table>\n</div>\n\n@if (paginated()) {\n <div class=\"flex items-center flex-wrap justify-end gap-4 py-3 px-1 max-lg:justify-center\">\n @if (customPagination()) {\n <ng-content select=\"[yuwDatatablePagination]\" />\n }\n <yuw-pagination\n [page]=\"currentPage()\"\n (pageChange)=\"onPageChange($event)\"\n [totalPages]=\"table.getPageCount() || 1\"\n [previousLabel]=\"previousPageLabel()\"\n [nextLabel]=\"nextPageLabel()\"\n [ellipsisSrText]=\"paginationEllipsisSrText()\"\n [ariaLabel]=\"paginationAriaLabel()\"\n color=\"neutral\"\n size=\"icon-sm\"\n class=\"flex\"\n />\n </div>\n}\n", dependencies: [{ kind: "directive", type: YuwTableContainerDirective, selector: "[yuwTableContainer]" }, { kind: "directive", type: YuwTableDirective, selector: "[yuwTable]" }, { kind: "directive", type: YuwTHeadDirective, selector: "[yuwTHead]" }, { kind: "directive", type: YuwTBodyDirective, selector: "[yuwTBody]" }, { kind: "directive", type: YuwTrDirective, selector: "[yuwTr]" }, { kind: "directive", type: YuwThDirective, selector: "[yuwTh]" }, { kind: "directive", type: YuwTdDirective, selector: "[yuwTd]" }, { kind: "directive", type: YuwCaptionDirective, selector: "[yuwCaption]" }, { kind: "component", type: YuwPaginationComponent, selector: "yuw-pagination", inputs: ["ariaLabel", "color", "ellipsisSrText", "nextLabel", "page", "previousLabel", "size", "totalPages"], outputs: ["pageChange"] }, { kind: "directive", type: YuwSkeletonDirective, selector: "[yuwSkeleton]" }, { kind: "directive", type: FlexRenderDirective, selector: "ng-template[flexRender]", inputs: ["flexRender", "flexRenderProps", "flexRenderInjector"] }, { kind: "component", type: NgIcon, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
4423
4635
  }
4424
4636
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: YuwDatatableComponent, decorators: [{
4425
4637
  type: Component,
4426
4638
  args: [{ selector: 'yuw-datatable', imports: [...YuwTableImports, YuwPaginationComponent, YuwSkeletonDirective, FlexRenderDirective, NgIcon], providers: [provideIcons({ lucideChevronDown, lucideChevronUp, lucideChevronsUpDown })], host: {
4427
4639
  class: 'contents',
4428
4640
  }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div yuwTableContainer [class]=\"_containerClass()\">\n <table yuwTable [class]=\"_tableClass()\">\n @if (caption()) {\n <caption yuwCaption>{{ caption() }}</caption>\n }\n\n <thead yuwTHead [class]=\"_headClass()\">\n @for (headerGroup of table.getHeaderGroups(); track headerGroup.id) {\n <tr yuwTr [class]=\"_rowClass()\">\n @for (header of headerGroup.headers; track header.id) {\n @let sorted = header.column.getIsSorted();\n @let headerClasses = _cellClasses().get(header.column.id);\n <th\n yuwTh\n scope=\"col\"\n [attr.colspan]=\"header.colSpan\"\n [attr.aria-sort]=\"sorted ? _ariaSort[sorted] : null\"\n [class]=\"headerClasses?.header\"\n >\n @if (!header.isPlaceholder) {\n @if (sortable() && header.column.getCanSort()) {\n <button\n type=\"button\"\n class=\"inline-flex items-center gap-1 select-none hover:text-foreground/80\"\n (click)=\"header.column.toggleSorting()\"\n >\n <ng-container\n *flexRender=\"header.column.columnDef.header; props: header.getContext(); let rendered\"\n >\n {{ rendered }}\n </ng-container>\n\n <ng-icon [name]=\"_sortIcon[sorted || 'none']\" class=\"shrink-0 text-xs\" aria-hidden=\"true\" />\n </button>\n } @else {\n <ng-container *flexRender=\"header.column.columnDef.header; props: header.getContext(); let rendered\">\n {{ rendered }}\n </ng-container>\n }\n }\n </th>\n }\n </tr>\n }\n </thead>\n\n <tbody yuwTBody>\n @if (loading()) {\n @for (row of _skeletonRows(); track row) {\n <tr yuwTr [class]=\"_rowClass()\">\n @for (column of table.getVisibleLeafColumns(); track column.id) {\n <td yuwTd [class]=\"_cellClasses().get(column.id)?.cell\">\n <span yuwSkeleton class=\"block h-4 w-full\"></span>\n </td>\n }\n </tr>\n }\n } @else if (_isEmpty()) {\n <tr yuwTr [class]=\"_rowClass()\">\n <td yuwTd [attr.colspan]=\"_columnCount()\" class=\"h-24 text-center text-muted-foreground\">\n {{ emptyText() ?? '' }}\n </td>\n </tr>\n } @else {\n @for (row of table.getRowModel().rows; track row.id) {\n <tr\n yuwTr\n [class]=\"_rowClasses().get(row.id)\"\n [attr.data-state]=\"row.getIsSelected() ? 'selected' : null\"\n role=\"button\"\n tabindex=\"0\"\n (click)=\"onRowClick(row.original)\"\n (keydown)=\"onRowKeydown($event, row.original)\"\n >\n @for (cell of row.getVisibleCells(); track cell.id) {\n <td yuwTd [class]=\"_cellClasses().get(cell.column.id)?.cell\">\n <ng-container *flexRender=\"cell.column.columnDef.cell; props: cell.getContext(); let rendered\">\n {{ rendered }}\n </ng-container>\n </td>\n }\n </tr>\n }\n }\n </tbody>\n </table>\n</div>\n\n@if (paginated()) {\n <div class=\"flex items-center flex-wrap justify-end gap-4 py-3 px-1 max-lg:justify-center\">\n @if (customPagination()) {\n <ng-content select=\"[yuwDatatablePagination]\" />\n }\n <yuw-pagination\n [page]=\"currentPage()\"\n (pageChange)=\"onPageChange($event)\"\n [totalPages]=\"table.getPageCount() || 1\"\n [previousLabel]=\"previousPageLabel()\"\n [nextLabel]=\"nextPageLabel()\"\n [ellipsisSrText]=\"paginationEllipsisSrText()\"\n [ariaLabel]=\"paginationAriaLabel()\"\n color=\"neutral\"\n size=\"icon-sm\"\n class=\"flex\"\n />\n </div>\n}\n" }]
4429
- }], propDecorators: { customPagination: [{ type: i0.ContentChild, args: [i0.forwardRef(() => YuwDatatablePaginationDirective), { isSignal: true }] }], appearance: [{ type: i0.Input, args: [{ isSignal: true, alias: "appearance", required: false }] }], caption: [{ type: i0.Input, args: [{ isSignal: true, alias: "caption", required: false }] }], cellClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "cellClass", required: false }] }], columnFilters: [{ type: i0.Input, args: [{ isSignal: true, alias: "columnFilters", required: false }] }, { type: i0.Output, args: ["columnFiltersChange"] }], columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: false }] }], columnVisibility: [{ type: i0.Input, args: [{ isSignal: true, alias: "columnVisibility", required: false }] }, { type: i0.Output, args: ["columnVisibilityChange"] }], data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], emptyText: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyText", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], loadingRows: [{ type: i0.Input, args: [{ isSignal: true, alias: "loadingRows", required: false }] }], nextPageLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "nextPageLabel", required: true }] }], paginated: [{ type: i0.Input, args: [{ isSignal: true, alias: "paginated", required: false }] }], pagination: [{ type: i0.Input, args: [{ isSignal: true, alias: "pagination", required: false }] }, { type: i0.Output, args: ["paginationChange"] }], paginationAriaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "paginationAriaLabel", required: true }] }], paginationEllipsisSrText: [{ type: i0.Input, args: [{ isSignal: true, alias: "paginationEllipsisSrText", required: true }] }], previousPageLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "previousPageLabel", required: true }] }], rowClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowClass", required: false }] }], rowSelection: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowSelection", required: false }] }, { type: i0.Output, args: ["rowSelectionChange"] }], selectable: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectable", required: false }] }], sortable: [{ type: i0.Input, args: [{ isSignal: true, alias: "sortable", required: false }] }], sorting: [{ type: i0.Input, args: [{ isSignal: true, alias: "sorting", required: false }] }, { type: i0.Output, args: ["sortingChange"] }], summary: [{ type: i0.Input, args: [{ isSignal: true, alias: "summary", required: false }] }], tableClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "tableClass", required: false }] }], totalItems: [{ type: i0.Input, args: [{ isSignal: true, alias: "totalItems", required: false }] }], rowClicked: [{ type: i0.Output, args: ["rowClicked"] }], selectedRowsChange: [{ type: i0.Output, args: ["selectedRowsChange"] }] } });
4641
+ }], propDecorators: { customPagination: [{ type: i0.ContentChild, args: [i0.forwardRef(() => YuwDatatablePaginationDirective), { isSignal: true }] }], appearance: [{ type: i0.Input, args: [{ isSignal: true, alias: "appearance", required: false }] }], caption: [{ type: i0.Input, args: [{ isSignal: true, alias: "caption", required: false }] }], cellClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "cellClass", required: false }] }], columnFilters: [{ type: i0.Input, args: [{ isSignal: true, alias: "columnFilters", required: false }] }, { type: i0.Output, args: ["columnFiltersChange"] }], columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: false }] }], columnVisibility: [{ type: i0.Input, args: [{ isSignal: true, alias: "columnVisibility", required: false }] }, { type: i0.Output, args: ["columnVisibilityChange"] }], data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], emptyText: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyText", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], loadingRows: [{ type: i0.Input, args: [{ isSignal: true, alias: "loadingRows", required: false }] }], nextPageLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "nextPageLabel", required: true }] }], paginated: [{ type: i0.Input, args: [{ isSignal: true, alias: "paginated", required: false }] }], pagination: [{ type: i0.Input, args: [{ isSignal: true, alias: "pagination", required: false }] }, { type: i0.Output, args: ["paginationChange"] }], paginationAriaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "paginationAriaLabel", required: true }] }], paginationEllipsisSrText: [{ type: i0.Input, args: [{ isSignal: true, alias: "paginationEllipsisSrText", required: true }] }], previousPageLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "previousPageLabel", required: true }] }], rowClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowClass", required: false }] }], rowSelection: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowSelection", required: false }] }, { type: i0.Output, args: ["rowSelectionChange"] }], selectable: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectable", required: false }] }], sortable: [{ type: i0.Input, args: [{ isSignal: true, alias: "sortable", required: false }] }], sorting: [{ type: i0.Input, args: [{ isSignal: true, alias: "sorting", required: false }] }, { type: i0.Output, args: ["sortingChange"] }], tableClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "tableClass", required: false }] }], totalItems: [{ type: i0.Input, args: [{ isSignal: true, alias: "totalItems", required: false }] }], rowClicked: [{ type: i0.Output, args: ["rowClicked"] }], selectedRowsChange: [{ type: i0.Output, args: ["selectedRowsChange"] }] } });
4430
4642
 
4431
4643
  /**
4432
4644
  * Selection checkbox for a datatable cell or header. The host stops the click so neither the
4433
4645
  * checkbox nor the cell around it triggers the row's own action, since `yuw-datatable` emits
4434
4646
  * `rowClicked` from the `<tr>`. `onToggle` is an input because `flexRenderComponent` does not
4435
4647
  * subscribe outputs.
4648
+ *
4649
+ * Renders a single `yuw-checkbox` meant to be used as the `select` display column of `yuw-datatable`
4650
+ * (header for select-all, cell for a single row), wired to TanStack's toggle handlers.
4651
+ *
4652
+ * Inputs:
4653
+ * - `checked`: Whether the checkbox is checked. Default is `false`.
4654
+ * - `indeterminate`: Shows the mixed state, e.g. for a header when only some rows are selected. Default is `false`.
4655
+ * - `label`: Accessible name (`aria-label`) of the checkbox. Default is `'Select row'`; consuming apps should
4656
+ * override it with translated text.
4657
+ * - `onToggle`: Callback run when the checkbox changes. Default is a no-op.
4436
4658
  */
4437
4659
  class YuwDatatableRowSelect {
4438
4660
  constructor() {
@@ -4459,6 +4681,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
4459
4681
  * Pencil button cell that runs `onEdit`, hidden until its row is hovered or keyboard-focused (`yuw-reveal`,
4460
4682
  * see `theme/components/reveal-on-hover.css`); touch devices keep it visible. An input because `flexRenderComponent` does not subscribe
4461
4683
  * outputs. The host stops the click so a clickable row does not fire twice.
4684
+ *
4685
+ * Inputs:
4686
+ * - `label` (required): Accessible name (`aria-label`) of the pencil button. User-facing text the
4687
+ * consuming app is responsible for translating.
4688
+ * - `onEdit`: Callback run when the button is clicked. Default is a no-op.
4462
4689
  */
4463
4690
  class YuwActionsCellComponent {
4464
4691
  constructor() {
@@ -4483,7 +4710,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
4483
4710
  * `actions` column; `label` is the button's accessible name and `header` the optional visible
4484
4711
  * column title, both already translated. Without `header` the column stays headerless.
4485
4712
  */
4486
- function buildYuwActionsColumn(label, onEdit, cellClass, header = '') {
4713
+ function buildYuwActionsColumn(label, onEdit, cellClass = 'w-12', header = '') {
4487
4714
  return {
4488
4715
  id: 'actions',
4489
4716
  header,
@@ -4953,6 +5180,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
4953
5180
  * text the consuming app is responsible for translating.
4954
5181
  * - `panelClass`: Extra classes merged onto the dialog panel (e.g. `sm:max-w-lg` to widen it).
4955
5182
  * They win over the library defaults via `twMerge`.
5183
+ * - `triggerColor`: Brand color theme for the trigger button (any `YuwColorDto` value). Default is `'neutral'`.
4956
5184
  * - `triggerVariant`: Button style variant for the trigger button. Default is `'outline'`.
4957
5185
  * - `triggerSize`: Button size for the trigger button.
4958
5186
  *
@@ -5806,6 +6034,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
5806
6034
  * branches and cannot attach a directive conditionally — an attribute selector matches on presence, so
5807
6035
  * the nav applies it to every entry and passes whether that entry actually has an avatar. Its default
5808
6036
  * is `true` so the bare, hand-written form needs no value.
6037
+ *
6038
+ * Inputs:
6039
+ * - `yuwSidebarMenuAvatarButton`: Boolean; whether the avatar geometry class is applied. An empty attribute counts as `true`; `false` applies nothing. Default is `true`.
5809
6040
  */
5810
6041
  class YuwSidebarMenuAvatarButtonDirective {
5811
6042
  constructor() {
@@ -5897,6 +6128,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
5897
6128
  *
5898
6129
  * `label` is the accessible label of the rail button (it has no visible text). User-facing text —
5899
6130
  * the consuming app is responsible for providing it already translated.
6131
+ *
6132
+ * Inputs:
6133
+ * - `label`: Required accessible label (`aria-label`) of the rail button.
5900
6134
  */
5901
6135
  class YuwSidebarRailDirective {
5902
6136
  constructor() {
@@ -6087,6 +6321,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
6087
6321
  * change-detection pass, and `RouterLinkActive` treats that as a changed input and re-runs its
6088
6322
  * subscription. Every entry resolves a tooltip, entries with children included: the submenu opens on
6089
6323
  * click, so hover is free to do what it does for every other rail icon and name the thing.
6324
+ *
6325
+ * Inputs:
6326
+ * - `collapsible`: Collapse mode of the host sidebar (`'offcanvas'`, `'icon'`, `'none'`); the rail submenu form only
6327
+ * applies for `'icon'`. Default is `'offcanvas'`.
6328
+ * - `content`: Required `YuwSidebarContentDto` (groups and their items) to render as the nav tree.
6090
6329
  */
6091
6330
  class YuwSidebarNavComponent {
6092
6331
  constructor() {
@@ -6218,6 +6457,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
6218
6457
  * split across the two refs, which is what broke every subsequent animation. Keeping one instance for
6219
6458
  * the sidebar's lifetime means a swap is only new content inside a live panel; the entry's own fields
6220
6459
  * are read through `_label`/`_children`, which tolerate the null the item holds before the first open.
6460
+ *
6461
+ * Outputs:
6462
+ * - `itemClicked`: Emits `{ id, event }` (`YuwSidebarItemClickDto`) when a child entry of the open submenu is clicked; the submenu closes first.
6221
6463
  */
6222
6464
  class YuwSidebarSubmenuSheetComponent {
6223
6465
  constructor() {