@egose/shadcn-theme-ng 0.5.3 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/README.md +131 -12
  2. package/autocomplete/fesm2022/autocomplete.mjs +14 -4
  3. package/autocomplete/types/autocomplete.d.ts +4 -1
  4. package/checkbox/README.md +6 -2
  5. package/checkbox/fesm2022/checkbox.mjs +11 -7
  6. package/checkbox/types/checkbox.d.ts +6 -4
  7. package/combobox/fesm2022/combobox.mjs +13 -7
  8. package/combobox/types/combobox.d.ts +8 -2
  9. package/data-table/README.md +174 -0
  10. package/data-table/fesm2022/data-table.mjs +713 -0
  11. package/data-table/package.json +25 -0
  12. package/data-table/types/data-table.d.ts +495 -0
  13. package/date-picker/README.md +41 -9
  14. package/date-picker/fesm2022/date-picker.mjs +265 -59
  15. package/date-picker/types/date-picker.d.ts +58 -27
  16. package/dropdown-menu/README.md +2 -0
  17. package/form-autocomplete/README.md +4 -2
  18. package/form-autocomplete/fesm2022/form-autocomplete.mjs +19 -6
  19. package/form-autocomplete/types/form-autocomplete.d.ts +9 -3
  20. package/form-combobox/README.md +4 -2
  21. package/form-combobox/fesm2022/form-combobox.mjs +23 -6
  22. package/form-combobox/types/form-combobox.d.ts +10 -3
  23. package/form-input-otp/README.md +7 -5
  24. package/form-input-otp/fesm2022/form-input-otp.mjs +20 -8
  25. package/form-input-otp/types/form-input-otp.d.ts +9 -3
  26. package/form-searchable-multiselect/README.md +15 -1
  27. package/form-searchable-multiselect/fesm2022/form-searchable-multiselect.mjs +15 -3
  28. package/form-searchable-multiselect/types/form-searchable-multiselect.d.ts +9 -1
  29. package/form-slider/README.md +3 -1
  30. package/form-slider/fesm2022/form-slider.mjs +19 -6
  31. package/form-slider/types/form-slider.d.ts +9 -3
  32. package/form-text-input/fesm2022/form-text-input.mjs +1 -1
  33. package/form-textarea/fesm2022/form-textarea.mjs +1 -1
  34. package/form-toggle/README.md +22 -18
  35. package/form-toggle/fesm2022/form-toggle.mjs +22 -9
  36. package/form-toggle/types/form-toggle.d.ts +6 -2
  37. package/input/README.md +7 -12
  38. package/input/fesm2022/input.mjs +7 -4
  39. package/input/types/input.d.ts +3 -1
  40. package/input-otp/README.md +33 -9
  41. package/input-otp/fesm2022/input-otp.mjs +127 -11
  42. package/input-otp/types/input-otp.d.ts +24 -4
  43. package/layout-simple/fesm2022/layout-simple.mjs +1 -1
  44. package/package.json +6 -1
  45. package/pagination/README.md +21 -12
  46. package/pagination/fesm2022/pagination.mjs +73 -65
  47. package/pagination/types/pagination.d.ts +21 -8
  48. package/phone-input/README.md +16 -0
  49. package/phone-input/fesm2022/phone-input.mjs +42 -4
  50. package/phone-input/types/phone-input.d.ts +5 -2
  51. package/searchable-multiselect/README.md +62 -40
  52. package/searchable-multiselect/fesm2022/searchable-multiselect.mjs +59 -32
  53. package/searchable-multiselect/types/searchable-multiselect.d.ts +23 -6
  54. package/slider/fesm2022/slider.mjs +9 -5
  55. package/slider/types/slider.d.ts +6 -2
  56. package/stepper/README.md +39 -19
  57. package/stepper/fesm2022/stepper.mjs +64 -12
  58. package/stepper/types/stepper.d.ts +12 -1
  59. package/table/README.md +2 -0
  60. package/table/fesm2022/table.mjs +12 -8
  61. package/table/types/table.d.ts +7 -2
package/stepper/README.md CHANGED
@@ -123,20 +123,38 @@ Lazy body (attached only when the step is first selected):
123
123
 
124
124
  ### `HlmStepper` — selector `hlm-stepper` (component, extends `CdkStepper`)
125
125
 
126
- | Input | Type | Default | Description |
127
- | ----------------------- | ------------------------------- | ----------------------- | ---------------------------------------------------------------- |
128
- | `orientation` | forwarded to `CdkStepper` | — | `'horizontal' \| 'vertical'`. |
129
- | `linear` | forwarded to `CdkStepper` | — | Current step must be valid (via `stepControl`) before advancing. |
130
- | `selectedIndex` | forwarded to `CdkStepper` | — | Controlled selected-step index. |
131
- | `labelPosition` | `'end' \| 'bottom'` | `'end'` | Horizontal layout: label beside vs. below the indicator. |
132
- | `headerPosition` | `'top' \| 'bottom'` | `'top'` | Horizontal layout: headers above vs. below the content panel. |
133
- | `indicatorMode` | `'number' \| 'state' \| 'icon'` | from config (`'state'`) | Indicator rendering (see below). |
134
- | `stepperAriaLabel` | `string \| null` | `'Progress'` | `aria-label` for the tablist (ignored when labelledby is set). |
135
- | `stepperAriaLabelledby` | `string \| null` | `null` | `aria-labelledby` for the tablist. |
136
- | `animationsEnabled` | `boolean` | from config (`true`) | Toggle step transitions per instance. |
137
- | `animationDuration` | `number` (ms) | from config (`300`) | Transition duration per instance. |
138
-
139
- `next()` is overridden to `markAllAsTouched()` + `updateValueAndValidity()` on the current `stepControl` first, so linear steppers surface validation errors before denying the transition.
126
+ | Input | Type | Default | Description |
127
+ | ----------------------- | ------------------------------- | ----------------------- | ------------------------------------------------------------------- |
128
+ | `orientation` | forwarded to `CdkStepper` | — | `'horizontal' \| 'vertical'`. |
129
+ | `linear` | forwarded to `CdkStepper` | — | CDK checks preceding steps, honoring optional/completion overrides. |
130
+ | `selectedIndex` | forwarded to `CdkStepper` | — | Controlled selected-step index. |
131
+ | `labelPosition` | `'end' \| 'bottom'` | `'end'` | Horizontal layout: label beside vs. below the indicator. |
132
+ | `headerPosition` | `'top' \| 'bottom'` | `'top'` | Horizontal layout: headers above vs. below the content panel. |
133
+ | `indicatorMode` | `'number' \| 'state' \| 'icon'` | from config (`'state'`) | Indicator rendering (see below). |
134
+ | `stepperAriaLabel` | `string \| null` | `'Progress'` | `aria-label` for the tablist (ignored when labelledby is set). |
135
+ | `stepperAriaLabelledby` | `string \| null` | `null` | `aria-labelledby` for the tablist. |
136
+ | `animationsEnabled` | `boolean` | from config (`true`) | Toggle step transitions per instance. |
137
+ | `animationDuration` | `number` (ms) | from config (`300`) | Transition duration per instance. |
138
+
139
+ `next()` and `button[hlmStepperNext]` call `markAllAsTouched()` + `updateValueAndValidity()` on the current classic reactive-forms `stepControl` before delegating navigation to CDK. This preserves touch/validation feedback even when navigation is denied, and also runs for optional, completed, and non-linear steps. Signal-form Fields are passed through to CDK without this classic-control touch pass.
140
+
141
+ CDK determines eligibility for Next, header selection, and direct index changes:
142
+
143
+ - In linear mode, all preceding required steps must satisfy CDK's interaction and validation rules. Invalid or pending controls block advancement unless their step is optional or explicitly `[completed]="true"`.
144
+ - Optional steps can be skipped while invalid or pending. Explicit completion also permits advancement in those states.
145
+ - Without a `stepControl`, CDK uses `completed` (by default, whether the step was interacted with). Explicit `[completed]="false"` blocks a required control-less step. With a control, CDK uses its validation state; `[completed]="false"` does not veto an otherwise valid, interacted control.
146
+ - Non-linear navigation is not blocked by invalid/pending forms. CDK's backward-navigation `editable` rule still applies.
147
+
148
+ Header/direct selection retains CDK's interaction behavior and does not run Next's form-touch/revalidation pass. Next revalidation can restart a validator attached to the current control, so pending eligibility is evaluated after that pass.
149
+
150
+ Header `aria-disabled`, disabled styling and active state preview the same transition that CDK will attempt, in both orientations:
151
+
152
+ - An unvisited destination is enabled when its predecessors permit entry; the destination's own incomplete/invalid control does not block entry. A completed destination cannot bypass a blocked predecessor.
153
+ - The preview accounts for CDK marking the **current** step interacted on an attempt to leave it. It does not mark steps interacted while rendering. Other unvisited required predecessors still block skipping ahead unless optional or explicitly completed.
154
+ - Backward selection requires the destination's `editable` input and, in linear mode, eligible predecessors **before that destination**. The current step's invalid/pending state does not itself prevent going back.
155
+ - The selected header stays enabled as a no-op, including vertically; selecting it neither collapses the panel nor marks the step interacted.
156
+
157
+ Actual clicks and Enter/Space selection remain delegated to CDK. Disabled headers remain discoverable by keyboard focus; attempted keyboard selection cannot change the selected index, but retains CDK's current-step interaction notification. Header attempts do not touch or revalidate form controls. Classic-form status notifications (including async validator completion) refresh the affordance; Signal Field validity is read reactively.
140
158
 
141
159
  ### `HlmStep` — selector `hlm-step` (component, extends `CdkStep`)
142
160
 
@@ -145,7 +163,9 @@ Lazy body (attached only when the step is first selected):
145
163
  | `label` | forwarded to `CdkStep` | — | Step title (string, or rich template via `hlmStepLabel`). |
146
164
  | `icon` | `string \| null` | `null` | Icon name rendered when `indicatorMode="icon"`. |
147
165
  | `stepControl` | forwarded to `CdkStep` | — | Form group driving `linear` validation. |
148
- | `optional` | forwarded to `CdkStep` | — | Shows an "Optional" caption in the header. |
166
+ | `optional` | forwarded to `CdkStep` | — | Permits skipping in linear mode and shows an "Optional" caption. |
167
+ | `completed` | forwarded to `CdkStep` | — | Explicit completion override; see CDK navigation rules above. |
168
+ | `editable` | forwarded to `CdkStep` | `true` | Allows returning to this step; enforced in linear and non-linear modes. |
149
169
  | `errorMessage` | forwarded to `CdkStep` | — | Header error caption when the step state is `error`. |
150
170
  | `hasError` | forwarded to `CdkStep` | — | Forces the error state (pair with `STEPPER_GLOBAL_OPTIONS` `showError`). |
151
171
  | `tooltip` | `string \| TemplateRef<unknown> \| null` | `null` (falls back to the full string label) | Styled header tooltip override; rich templates allowed. |
@@ -263,7 +283,7 @@ export class DemoResponsive {
263
283
 
264
284
  ### 4. Linear stepper with validation
265
285
 
266
- With `linear`, the current step must be valid before advancing — `HlmStepper.next()` marks the step form touched first:
286
+ With `linear`, required steps normally need valid, non-pending controls before advancing. `HlmStepper.next()` marks the current step form touched first; optional and explicitly completed steps follow the exceptions above:
267
287
 
268
288
  ```ts
269
289
  import { Component, inject } from '@angular/core';
@@ -361,9 +381,9 @@ Steps using `<ng-template hlmStepLabel>` have no string to fall back to — pass
361
381
 
362
382
  - Horizontal headers get `role="tab"` semantics inside a `role="tablist"` (labelled `Progress` by default — override with `stepperAriaLabel` / `stepperAriaLabelledby`); panels get `role="tabpanel"` wired via `aria-labelledby` / `aria-controls`.
363
383
  - Vertical headers use `role="button"` with `aria-expanded` / `aria-current="step"`.
364
- - Keyboard: `HlmStepper` inherits CDK arrow-key navigation (`_onKeydown`). Headers are focusable via roving `tabIndex`.
365
- - Disabled steps (`linear` + not navigable) get `aria-disabled` and `data-disabled` styling — explain in the label why a step is unavailable.
366
- - In `linear` mode, failed validation marks fields touched so screen readers announce the errors.
384
+ - Keyboard: CDK manages roving `tabIndex`, horizontal Left/Right (direction-aware), vertical Up/Down, Home/End, wrapping, and Enter/Space activation. Focus movement does not select a step. Disabled headers can receive keyboard focus so their labels and unavailable state remain discoverable.
385
+ - Headers that CDK cannot select get matching `aria-disabled="true"` and `data-disabled="true"` pointer/opacity styling, including non-editable backward destinations in non-linear mode. Explain in the label why a step is unavailable. Eligible unvisited destinations and the selected header are not disabled.
386
+ - Next marks classic form controls touched so applications can display validation feedback. Associate error text with the relevant controls; touching alone does not guarantee a screen-reader announcement.
367
387
 
368
388
  ## Theming / CSS variables
369
389
 
@@ -1,14 +1,14 @@
1
1
  import * as i0 from '@angular/core';
2
- import { inject, TemplateRef, Directive, ViewContainerRef, DestroyRef, input, booleanAttribute, contentChild, effect, untracked, ChangeDetectionStrategy, Component, InjectionToken, numberAttribute, computed, signal, NgModule } from '@angular/core';
2
+ import { inject, TemplateRef, Directive, ViewContainerRef, DestroyRef, input, booleanAttribute, contentChild, effect, untracked, ChangeDetectionStrategy, Component, InjectionToken, numberAttribute, computed, QueryList, signal, ViewChildren, NgModule } from '@angular/core';
3
3
  import { TemplatePortal, CdkPortalOutlet } from '@angular/cdk/portal';
4
4
  import * as i1 from '@angular/cdk/stepper';
5
5
  import { CdkStepLabel, CdkStep, CdkStepHeader, CdkStepper, CdkStepperModule, CdkStepperNext, CdkStepperPrevious } from '@angular/cdk/stepper';
6
+ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
6
7
  import { NgTemplateOutlet } from '@angular/common';
7
8
  import { NgIcon, provideIcons } from '@ng-icons/core';
8
9
  import { lucideCircleAlert, lucideCheck } from '@ng-icons/lucide';
9
10
  import { buttonVariants } from '@egose/shadcn-theme-ng/button';
10
11
  import { classes, hlm } from '@egose/shadcn-theme-ng/utils';
11
- import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
12
12
  import { HlmTooltip } from '@egose/shadcn-theme-ng/tooltip';
13
13
  import { cva } from 'class-variance-authority';
14
14
  import { tap } from 'rxjs/operators';
@@ -42,6 +42,41 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
42
42
  class HlmStep extends CdkStep {
43
43
  _viewContainerRef = inject(ViewContainerRef);
44
44
  _destroyRef = inject(DestroyRef);
45
+ _hasCompletionOverride = false;
46
+ _controlSubscription;
47
+ ngOnChanges() {
48
+ super.ngOnChanges();
49
+ this._controlSubscription?.unsubscribe();
50
+ const control = this.stepControl;
51
+ if (control && typeof control !== 'function') {
52
+ // Classic form status getters are not reactive template dependencies, unlike Signal Fields.
53
+ this._controlSubscription = control.statusChanges
54
+ .pipe(takeUntilDestroyed(this._destroyRef))
55
+ .subscribe(() => this._stepper._stateChanged());
56
+ }
57
+ }
58
+ get completed() {
59
+ return super.completed;
60
+ }
61
+ set completed(value) {
62
+ // Track input presence through the supported accessor, not CDK's internal override field.
63
+ this._hasCompletionOverride = value != null;
64
+ super.completed = value;
65
+ }
66
+ /** @internal Read-only preview of CDK's predecessor check after leaving the current step. */
67
+ _canExit(leaving) {
68
+ if (this.optional || this.completed) {
69
+ return true;
70
+ }
71
+ const interacted = this.interacted || leaving;
72
+ const control = this.stepControl;
73
+ if (!control) {
74
+ return interacted && !this._hasCompletionOverride;
75
+ }
76
+ const invalid = typeof control === 'function' ? control().invalid() : control.invalid;
77
+ const pending = typeof control === 'function' ? control().pending() : control.pending;
78
+ return interacted && !invalid && !pending;
79
+ }
45
80
  icon = input(null, /* @ts-ignore */
46
81
  ...(ngDevMode ? [{ debugName: "icon" }] : /* istanbul ignore next */ []));
47
82
  /** Styled header tooltip override. Falls back to the full string label when unset. */
@@ -81,7 +116,7 @@ class HlmStep extends CdkStep {
81
116
  provide: CdkStep,
82
117
  useExisting: HlmStep,
83
118
  },
84
- ], queries: [{ propertyName: "stepLabelContent", first: true, predicate: HlmStepLabel, descendants: true, isSignal: true }, { propertyName: "_lazyContent", first: true, predicate: HlmStepContent, descendants: true, isSignal: true }], exportAs: ["hlmStep"], usesInheritance: true, ngImport: i0, template: `
119
+ ], queries: [{ propertyName: "stepLabelContent", first: true, predicate: HlmStepLabel, descendants: true, isSignal: true }, { propertyName: "_lazyContent", first: true, predicate: HlmStepContent, descendants: true, isSignal: true }], exportAs: ["hlmStep"], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: `
85
120
  <ng-template>
86
121
  <ng-content></ng-content>
87
122
  <ng-template [cdkPortalOutlet]="portal"></ng-template>
@@ -244,6 +279,8 @@ const stepTransition = cva('', {
244
279
  });
245
280
  class HlmStepper extends CdkStepper {
246
281
  _config = injectHlmStepperConfig();
282
+ // Headers are rendered in this component's view, not in CDK's projected content query.
283
+ _stepHeader = new QueryList();
247
284
  labelPosition = input('end', /* @ts-ignore */
248
285
  ...(ngDevMode ? [{ debugName: "labelPosition" }] : /* istanbul ignore next */ []));
249
286
  headerPosition = input('top', /* @ts-ignore */
@@ -271,23 +308,35 @@ class HlmStepper extends CdkStepper {
271
308
  }), takeUntilDestroyed())
272
309
  .subscribe();
273
310
  }
311
+ /** Touch and revalidate the current reactive form, then let CDK decide whether navigation is allowed. */
274
312
  next() {
275
313
  const stepControl = this.selected?.stepControl;
276
314
  if (stepControl && typeof stepControl !== 'function') {
277
- // Classic reactive-forms control: surface validation errors before a denied linear transition.
278
- // Signal `Field` controls expose validity through invocation and need no touch pass.
315
+ // Preserve validation feedback for classic controls. Signal Fields are handled by CDK.
279
316
  stepControl.markAllAsTouched();
280
317
  stepControl.updateValueAndValidity();
281
318
  }
282
- const invalid = !!stepControl && (typeof stepControl === 'function' ? stepControl().invalid() : stepControl.invalid);
283
- if (this.linear && invalid) {
284
- return;
285
- }
319
+ // CDK applies optional/completion overrides and checks all preceding controls, including pending ones.
286
320
  super.next();
287
321
  }
288
322
  stepIcon(step) {
289
323
  return step instanceof HlmStep ? step.icon() : null;
290
324
  }
325
+ /** Preview selection without touching forms or marking steps interacted; activation stays with CDK. */
326
+ _isHeaderEnabled(step) {
327
+ const index = step.index();
328
+ if (index === this.selectedIndex) {
329
+ return true;
330
+ }
331
+ if (index < this.selectedIndex && !step.editable) {
332
+ return false;
333
+ }
334
+ return (!this.linear ||
335
+ this.steps
336
+ .toArray()
337
+ .slice(0, index)
338
+ .every((previous) => previous instanceof HlmStep && previous._canExit(previous === this.selected)));
339
+ }
291
340
  _headerTooltip(step) {
292
341
  const override = step instanceof HlmStep ? step.tooltip() : null;
293
342
  if (override === null || override === undefined) {
@@ -327,7 +376,7 @@ class HlmStepper extends CdkStepper {
327
376
  return hlm("ms-4 overflow-hidden ps-6", showConnector && "border-s", this.animationsEnabled() && this.selectedIndex === index && stepTransition({ motion: 'enter-bottom' }));
328
377
  }
329
378
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmStepper, deps: [], target: i0.ɵɵFactoryTarget.Component });
330
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: HlmStepper, isStandalone: true, selector: "hlm-stepper", inputs: { labelPosition: { classPropertyName: "labelPosition", publicName: "labelPosition", isSignal: true, isRequired: false, transformFunction: null }, headerPosition: { classPropertyName: "headerPosition", publicName: "headerPosition", isSignal: true, isRequired: false, transformFunction: null }, indicatorMode: { classPropertyName: "indicatorMode", publicName: "indicatorMode", isSignal: true, isRequired: false, transformFunction: null }, stepperAriaLabel: { classPropertyName: "stepperAriaLabel", publicName: "stepperAriaLabel", isSignal: true, isRequired: false, transformFunction: null }, stepperAriaLabelledby: { classPropertyName: "stepperAriaLabelledby", publicName: "stepperAriaLabelledby", isSignal: true, isRequired: false, transformFunction: null }, animationsEnabled: { classPropertyName: "animationsEnabled", publicName: "animationsEnabled", isSignal: true, isRequired: false, transformFunction: null }, animationDuration: { classPropertyName: "animationDuration", publicName: "animationDuration", isSignal: true, isRequired: false, transformFunction: null } }, providers: [{ provide: CdkStepper, useExisting: HlmStepper }], usesInheritance: true, ngImport: i0, template: "\n @switch (orientation) {\n @case ('horizontal') {\n <div class=\"flex w-full flex-col gap-6\">\n @if (headerPosition() === 'top') {\n <ng-container [ngTemplateOutlet]=\"horizontalStepsTemplate\" [ngTemplateOutletContext]=\"{ steps: steps }\" />\n <ng-container [ngTemplateOutlet]=\"horizontalPanelTemplate\" />\n } @else {\n <ng-container [ngTemplateOutlet]=\"horizontalPanelTemplate\" />\n <ng-container [ngTemplateOutlet]=\"horizontalStepsTemplate\" [ngTemplateOutletContext]=\"{ steps: steps }\" />\n }\n </div>\n }\n\n @case ('vertical') {\n <div class=\"flex w-full flex-col gap-3\">\n @for (step of steps; track step; let i = $index) {\n <div class=\"flex flex-col gap-2\">\n <ng-container [ngTemplateOutlet]=\"stepHeaderTemplate\" [ngTemplateOutletContext]=\"{ step: step }\" />\n\n <div\n [class]=\"_gridContainerClass(selectedIndex === i)\"\n [style.transition-duration.ms]=\"animationDuration()\"\n >\n <section\n [class]=\"_verticalStepClass(!$last, i)\"\n role=\"region\"\n [id]=\"_getStepContentId(i)\"\n [attr.aria-labelledby]=\"_getStepLabelId(i)\"\n >\n <ng-container [ngTemplateOutlet]=\"step.content\" />\n </section>\n </div>\n\n @if (!$last) {\n <div class=\"ms-4 h-6 w-px\" aria-hidden=\"true\">\n <span [class]=\"_connectorClass(step.index())\"></span>\n </div>\n }\n </div>\n }\n </div>\n }\n }\n\n <ng-template #stepHeaderTemplate let-step=\"step\">\n <hlm-step-header\n cdkStepHeader\n class=\"min-w-0\"\n (click)=\"step.select()\"\n (keydown)=\"_onKeydown($event)\"\n [tabIndex]=\"_getFocusIndex() === step.index() ? 0 : -1\"\n [id]=\"_getStepLabelId(step.index())\"\n [attr.role]=\"orientation === 'horizontal' ? 'tab' : 'button'\"\n [attr.aria-posinset]=\"orientation === 'horizontal' ? step.index() + 1 : null\"\n [attr.aria-setsize]=\"orientation === 'horizontal' ? steps.length : null\"\n [attr.aria-selected]=\"orientation === 'horizontal' ? step.isSelected() : null\"\n [attr.aria-current]=\"orientation === 'vertical' && step.isSelected() ? 'step' : null\"\n [attr.aria-expanded]=\"orientation === 'vertical' ? step.isSelected() : null\"\n [attr.aria-controls]=\"_getStepContentId(step.index())\"\n [attr.aria-label]=\"step.ariaLabel || null\"\n [attr.aria-labelledby]=\"!step.ariaLabel && step.ariaLabelledby ? step.ariaLabelledby : null\"\n [attr.aria-disabled]=\"!step.isNavigable() || (orientation === 'vertical' && step.isSelected()) ? 'true' : null\"\n [index]=\"step.index()\"\n [state]=\"step.indicatorType()\"\n [label]=\"step.stepLabelContent() || step.label\"\n [selected]=\"step.isSelected()\"\n [reached]=\"step.index() < selectedIndex\"\n [active]=\"step.isNavigable()\"\n [optional]=\"step.optional\"\n [errorMessage]=\"step.errorMessage\"\n [disabled]=\"linear && !step.isNavigable()\"\n [labelPosition]=\"orientation === 'horizontal' ? labelPosition() : 'end'\"\n [indicatorMode]=\"indicatorMode()\"\n [icon]=\"stepIcon(step)\"\n [hlmTooltip]=\"_headerTooltip(step)\"\n [position]=\"_headerTooltipPosition(step)\"\n [tooltipDisabled]=\"_headerTooltipDisabled(step)\"\n />\n </ng-template>\n\n <ng-template #horizontalStepsTemplate let-steps=\"steps\">\n <ol\n class=\"flex w-full items-center\"\n role=\"tablist\"\n aria-orientation=\"horizontal\"\n [attr.aria-label]=\"stepperAriaLabelledby() ? null : (stepperAriaLabel() ?? null)\"\n [attr.aria-labelledby]=\"stepperAriaLabelledby()\"\n >\n @for (step of steps; track step) {\n <li class=\"flex min-w-0 items-center\">\n <ng-container [ngTemplateOutlet]=\"stepHeaderTemplate\" [ngTemplateOutletContext]=\"{ step: step }\" />\n </li>\n\n @if (!$last) {\n <li class=\"mx-3 flex min-w-8 flex-1 items-center\" aria-hidden=\"true\">\n <span class=\"bg-border relative h-px w-full overflow-hidden rounded\">\n <span\n class=\"bg-primary absolute inset-y-0 inset-s-0 transition-[width] duration-200\"\n [style.width.%]=\"step.index() < selectedIndex ? 100 : 0\"\n ></span>\n </span>\n </li>\n }\n }\n </ol>\n </ng-template>\n\n <ng-template #horizontalPanelTemplate>\n <div class=\"relative min-h-0 overflow-hidden\">\n @for (activeIndex of [selectedIndex]; track activeIndex) {\n <section\n role=\"tabpanel\"\n [id]=\"_getStepContentId(activeIndex)\"\n [attr.aria-labelledby]=\"_getStepLabelId(activeIndex)\"\n [style.animation-duration.ms]=\"animationDuration()\"\n [animate.enter]=\"animationsEnabled() ? _enterAnimationClass() : ''\"\n [animate.leave]=\"animationsEnabled() ? _leaveAnimationClass() : ''\"\n >\n <ng-container [ngTemplateOutlet]=\"steps.get(activeIndex)?.content\" />\n </section>\n }\n </div>\n </ng-template>\n ", isInline: true, dependencies: [{ kind: "ngmodule", type: CdkStepperModule }, { kind: "directive", type: i1.CdkStepHeader, selector: "[cdkStepHeader]" }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: HlmStepHeader, selector: "hlm-step-header", inputs: ["state", "label", "errorMessage", "index", "selected", "reached", "active", "optional", "disabled", "icon", "indicatorMode", "labelPosition"] }, { kind: "directive", type: HlmTooltip, selector: "[hlmTooltip]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
379
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: HlmStepper, isStandalone: true, selector: "hlm-stepper", inputs: { labelPosition: { classPropertyName: "labelPosition", publicName: "labelPosition", isSignal: true, isRequired: false, transformFunction: null }, headerPosition: { classPropertyName: "headerPosition", publicName: "headerPosition", isSignal: true, isRequired: false, transformFunction: null }, indicatorMode: { classPropertyName: "indicatorMode", publicName: "indicatorMode", isSignal: true, isRequired: false, transformFunction: null }, stepperAriaLabel: { classPropertyName: "stepperAriaLabel", publicName: "stepperAriaLabel", isSignal: true, isRequired: false, transformFunction: null }, stepperAriaLabelledby: { classPropertyName: "stepperAriaLabelledby", publicName: "stepperAriaLabelledby", isSignal: true, isRequired: false, transformFunction: null }, animationsEnabled: { classPropertyName: "animationsEnabled", publicName: "animationsEnabled", isSignal: true, isRequired: false, transformFunction: null }, animationDuration: { classPropertyName: "animationDuration", publicName: "animationDuration", isSignal: true, isRequired: false, transformFunction: null } }, providers: [{ provide: CdkStepper, useExisting: HlmStepper }], viewQueries: [{ propertyName: "_stepHeader", predicate: CdkStepHeader, descendants: true }], usesInheritance: true, ngImport: i0, template: "\n @switch (orientation) {\n @case ('horizontal') {\n <div class=\"flex w-full flex-col gap-6\">\n @if (headerPosition() === 'top') {\n <ng-container [ngTemplateOutlet]=\"horizontalStepsTemplate\" [ngTemplateOutletContext]=\"{ steps: steps }\" />\n <ng-container [ngTemplateOutlet]=\"horizontalPanelTemplate\" />\n } @else {\n <ng-container [ngTemplateOutlet]=\"horizontalPanelTemplate\" />\n <ng-container [ngTemplateOutlet]=\"horizontalStepsTemplate\" [ngTemplateOutletContext]=\"{ steps: steps }\" />\n }\n </div>\n }\n\n @case ('vertical') {\n <div class=\"flex w-full flex-col gap-3\">\n @for (step of steps; track step; let i = $index) {\n <div class=\"flex flex-col gap-2\">\n <ng-container [ngTemplateOutlet]=\"stepHeaderTemplate\" [ngTemplateOutletContext]=\"{ step: step }\" />\n\n <div\n [class]=\"_gridContainerClass(selectedIndex === i)\"\n [style.transition-duration.ms]=\"animationDuration()\"\n >\n <section\n [class]=\"_verticalStepClass(!$last, i)\"\n role=\"region\"\n [id]=\"_getStepContentId(i)\"\n [attr.aria-labelledby]=\"_getStepLabelId(i)\"\n >\n <ng-container [ngTemplateOutlet]=\"step.content\" />\n </section>\n </div>\n\n @if (!$last) {\n <div class=\"ms-4 h-6 w-px\" aria-hidden=\"true\">\n <span [class]=\"_connectorClass(step.index())\"></span>\n </div>\n }\n </div>\n }\n </div>\n }\n }\n\n <ng-template #stepHeaderTemplate let-step=\"step\">\n @let enabled = _isHeaderEnabled(step);\n <hlm-step-header\n cdkStepHeader\n class=\"min-w-0\"\n (click)=\"step.select()\"\n (keydown)=\"_onKeydown($event)\"\n [tabIndex]=\"_getFocusIndex() === step.index() ? 0 : -1\"\n [id]=\"_getStepLabelId(step.index())\"\n [attr.role]=\"orientation === 'horizontal' ? 'tab' : 'button'\"\n [attr.aria-posinset]=\"orientation === 'horizontal' ? step.index() + 1 : null\"\n [attr.aria-setsize]=\"orientation === 'horizontal' ? steps.length : null\"\n [attr.aria-selected]=\"orientation === 'horizontal' ? step.isSelected() : null\"\n [attr.aria-current]=\"orientation === 'vertical' && step.isSelected() ? 'step' : null\"\n [attr.aria-expanded]=\"orientation === 'vertical' ? step.isSelected() : null\"\n [attr.aria-controls]=\"_getStepContentId(step.index())\"\n [attr.aria-label]=\"step.ariaLabel || null\"\n [attr.aria-labelledby]=\"!step.ariaLabel && step.ariaLabelledby ? step.ariaLabelledby : null\"\n [attr.aria-disabled]=\"enabled ? null : 'true'\"\n [index]=\"step.index()\"\n [state]=\"step.indicatorType()\"\n [label]=\"step.stepLabelContent() || step.label\"\n [selected]=\"step.isSelected()\"\n [reached]=\"step.index() < selectedIndex\"\n [active]=\"enabled\"\n [optional]=\"step.optional\"\n [errorMessage]=\"step.errorMessage\"\n [disabled]=\"!enabled\"\n [labelPosition]=\"orientation === 'horizontal' ? labelPosition() : 'end'\"\n [indicatorMode]=\"indicatorMode()\"\n [icon]=\"stepIcon(step)\"\n [hlmTooltip]=\"_headerTooltip(step)\"\n [position]=\"_headerTooltipPosition(step)\"\n [tooltipDisabled]=\"_headerTooltipDisabled(step)\"\n />\n </ng-template>\n\n <ng-template #horizontalStepsTemplate let-steps=\"steps\">\n <ol\n class=\"flex w-full items-center\"\n role=\"tablist\"\n aria-orientation=\"horizontal\"\n [attr.aria-label]=\"stepperAriaLabelledby() ? null : (stepperAriaLabel() ?? null)\"\n [attr.aria-labelledby]=\"stepperAriaLabelledby()\"\n >\n @for (step of steps; track step) {\n <li class=\"flex min-w-0 items-center\">\n <ng-container [ngTemplateOutlet]=\"stepHeaderTemplate\" [ngTemplateOutletContext]=\"{ step: step }\" />\n </li>\n\n @if (!$last) {\n <li class=\"mx-3 flex min-w-8 flex-1 items-center\" aria-hidden=\"true\">\n <span class=\"bg-border relative h-px w-full overflow-hidden rounded\">\n <span\n class=\"bg-primary absolute inset-y-0 inset-s-0 transition-[width] duration-200\"\n [style.width.%]=\"step.index() < selectedIndex ? 100 : 0\"\n ></span>\n </span>\n </li>\n }\n }\n </ol>\n </ng-template>\n\n <ng-template #horizontalPanelTemplate>\n <div class=\"relative min-h-0 overflow-hidden\">\n @for (activeIndex of [selectedIndex]; track activeIndex) {\n <section\n role=\"tabpanel\"\n [id]=\"_getStepContentId(activeIndex)\"\n [attr.aria-labelledby]=\"_getStepLabelId(activeIndex)\"\n [style.animation-duration.ms]=\"animationDuration()\"\n [animate.enter]=\"animationsEnabled() ? _enterAnimationClass() : ''\"\n [animate.leave]=\"animationsEnabled() ? _leaveAnimationClass() : ''\"\n >\n <ng-container [ngTemplateOutlet]=\"steps.get(activeIndex)?.content\" />\n </section>\n }\n </div>\n </ng-template>\n ", isInline: true, dependencies: [{ kind: "ngmodule", type: CdkStepperModule }, { kind: "directive", type: i1.CdkStepHeader, selector: "[cdkStepHeader]" }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: HlmStepHeader, selector: "hlm-step-header", inputs: ["state", "label", "errorMessage", "index", "selected", "reached", "active", "optional", "disabled", "icon", "indicatorMode", "labelPosition"] }, { kind: "directive", type: HlmTooltip, selector: "[hlmTooltip]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
331
380
  }
332
381
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmStepper, decorators: [{
333
382
  type: Component,
@@ -336,9 +385,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
336
385
  imports: [CdkStepperModule, NgTemplateOutlet, HlmStepHeader, HlmTooltip],
337
386
  providers: [{ provide: CdkStepper, useExisting: HlmStepper }],
338
387
  changeDetection: ChangeDetectionStrategy.OnPush,
339
- template: "\n @switch (orientation) {\n @case ('horizontal') {\n <div class=\"flex w-full flex-col gap-6\">\n @if (headerPosition() === 'top') {\n <ng-container [ngTemplateOutlet]=\"horizontalStepsTemplate\" [ngTemplateOutletContext]=\"{ steps: steps }\" />\n <ng-container [ngTemplateOutlet]=\"horizontalPanelTemplate\" />\n } @else {\n <ng-container [ngTemplateOutlet]=\"horizontalPanelTemplate\" />\n <ng-container [ngTemplateOutlet]=\"horizontalStepsTemplate\" [ngTemplateOutletContext]=\"{ steps: steps }\" />\n }\n </div>\n }\n\n @case ('vertical') {\n <div class=\"flex w-full flex-col gap-3\">\n @for (step of steps; track step; let i = $index) {\n <div class=\"flex flex-col gap-2\">\n <ng-container [ngTemplateOutlet]=\"stepHeaderTemplate\" [ngTemplateOutletContext]=\"{ step: step }\" />\n\n <div\n [class]=\"_gridContainerClass(selectedIndex === i)\"\n [style.transition-duration.ms]=\"animationDuration()\"\n >\n <section\n [class]=\"_verticalStepClass(!$last, i)\"\n role=\"region\"\n [id]=\"_getStepContentId(i)\"\n [attr.aria-labelledby]=\"_getStepLabelId(i)\"\n >\n <ng-container [ngTemplateOutlet]=\"step.content\" />\n </section>\n </div>\n\n @if (!$last) {\n <div class=\"ms-4 h-6 w-px\" aria-hidden=\"true\">\n <span [class]=\"_connectorClass(step.index())\"></span>\n </div>\n }\n </div>\n }\n </div>\n }\n }\n\n <ng-template #stepHeaderTemplate let-step=\"step\">\n <hlm-step-header\n cdkStepHeader\n class=\"min-w-0\"\n (click)=\"step.select()\"\n (keydown)=\"_onKeydown($event)\"\n [tabIndex]=\"_getFocusIndex() === step.index() ? 0 : -1\"\n [id]=\"_getStepLabelId(step.index())\"\n [attr.role]=\"orientation === 'horizontal' ? 'tab' : 'button'\"\n [attr.aria-posinset]=\"orientation === 'horizontal' ? step.index() + 1 : null\"\n [attr.aria-setsize]=\"orientation === 'horizontal' ? steps.length : null\"\n [attr.aria-selected]=\"orientation === 'horizontal' ? step.isSelected() : null\"\n [attr.aria-current]=\"orientation === 'vertical' && step.isSelected() ? 'step' : null\"\n [attr.aria-expanded]=\"orientation === 'vertical' ? step.isSelected() : null\"\n [attr.aria-controls]=\"_getStepContentId(step.index())\"\n [attr.aria-label]=\"step.ariaLabel || null\"\n [attr.aria-labelledby]=\"!step.ariaLabel && step.ariaLabelledby ? step.ariaLabelledby : null\"\n [attr.aria-disabled]=\"!step.isNavigable() || (orientation === 'vertical' && step.isSelected()) ? 'true' : null\"\n [index]=\"step.index()\"\n [state]=\"step.indicatorType()\"\n [label]=\"step.stepLabelContent() || step.label\"\n [selected]=\"step.isSelected()\"\n [reached]=\"step.index() < selectedIndex\"\n [active]=\"step.isNavigable()\"\n [optional]=\"step.optional\"\n [errorMessage]=\"step.errorMessage\"\n [disabled]=\"linear && !step.isNavigable()\"\n [labelPosition]=\"orientation === 'horizontal' ? labelPosition() : 'end'\"\n [indicatorMode]=\"indicatorMode()\"\n [icon]=\"stepIcon(step)\"\n [hlmTooltip]=\"_headerTooltip(step)\"\n [position]=\"_headerTooltipPosition(step)\"\n [tooltipDisabled]=\"_headerTooltipDisabled(step)\"\n />\n </ng-template>\n\n <ng-template #horizontalStepsTemplate let-steps=\"steps\">\n <ol\n class=\"flex w-full items-center\"\n role=\"tablist\"\n aria-orientation=\"horizontal\"\n [attr.aria-label]=\"stepperAriaLabelledby() ? null : (stepperAriaLabel() ?? null)\"\n [attr.aria-labelledby]=\"stepperAriaLabelledby()\"\n >\n @for (step of steps; track step) {\n <li class=\"flex min-w-0 items-center\">\n <ng-container [ngTemplateOutlet]=\"stepHeaderTemplate\" [ngTemplateOutletContext]=\"{ step: step }\" />\n </li>\n\n @if (!$last) {\n <li class=\"mx-3 flex min-w-8 flex-1 items-center\" aria-hidden=\"true\">\n <span class=\"bg-border relative h-px w-full overflow-hidden rounded\">\n <span\n class=\"bg-primary absolute inset-y-0 inset-s-0 transition-[width] duration-200\"\n [style.width.%]=\"step.index() < selectedIndex ? 100 : 0\"\n ></span>\n </span>\n </li>\n }\n }\n </ol>\n </ng-template>\n\n <ng-template #horizontalPanelTemplate>\n <div class=\"relative min-h-0 overflow-hidden\">\n @for (activeIndex of [selectedIndex]; track activeIndex) {\n <section\n role=\"tabpanel\"\n [id]=\"_getStepContentId(activeIndex)\"\n [attr.aria-labelledby]=\"_getStepLabelId(activeIndex)\"\n [style.animation-duration.ms]=\"animationDuration()\"\n [animate.enter]=\"animationsEnabled() ? _enterAnimationClass() : ''\"\n [animate.leave]=\"animationsEnabled() ? _leaveAnimationClass() : ''\"\n >\n <ng-container [ngTemplateOutlet]=\"steps.get(activeIndex)?.content\" />\n </section>\n }\n </div>\n </ng-template>\n ",
388
+ template: "\n @switch (orientation) {\n @case ('horizontal') {\n <div class=\"flex w-full flex-col gap-6\">\n @if (headerPosition() === 'top') {\n <ng-container [ngTemplateOutlet]=\"horizontalStepsTemplate\" [ngTemplateOutletContext]=\"{ steps: steps }\" />\n <ng-container [ngTemplateOutlet]=\"horizontalPanelTemplate\" />\n } @else {\n <ng-container [ngTemplateOutlet]=\"horizontalPanelTemplate\" />\n <ng-container [ngTemplateOutlet]=\"horizontalStepsTemplate\" [ngTemplateOutletContext]=\"{ steps: steps }\" />\n }\n </div>\n }\n\n @case ('vertical') {\n <div class=\"flex w-full flex-col gap-3\">\n @for (step of steps; track step; let i = $index) {\n <div class=\"flex flex-col gap-2\">\n <ng-container [ngTemplateOutlet]=\"stepHeaderTemplate\" [ngTemplateOutletContext]=\"{ step: step }\" />\n\n <div\n [class]=\"_gridContainerClass(selectedIndex === i)\"\n [style.transition-duration.ms]=\"animationDuration()\"\n >\n <section\n [class]=\"_verticalStepClass(!$last, i)\"\n role=\"region\"\n [id]=\"_getStepContentId(i)\"\n [attr.aria-labelledby]=\"_getStepLabelId(i)\"\n >\n <ng-container [ngTemplateOutlet]=\"step.content\" />\n </section>\n </div>\n\n @if (!$last) {\n <div class=\"ms-4 h-6 w-px\" aria-hidden=\"true\">\n <span [class]=\"_connectorClass(step.index())\"></span>\n </div>\n }\n </div>\n }\n </div>\n }\n }\n\n <ng-template #stepHeaderTemplate let-step=\"step\">\n @let enabled = _isHeaderEnabled(step);\n <hlm-step-header\n cdkStepHeader\n class=\"min-w-0\"\n (click)=\"step.select()\"\n (keydown)=\"_onKeydown($event)\"\n [tabIndex]=\"_getFocusIndex() === step.index() ? 0 : -1\"\n [id]=\"_getStepLabelId(step.index())\"\n [attr.role]=\"orientation === 'horizontal' ? 'tab' : 'button'\"\n [attr.aria-posinset]=\"orientation === 'horizontal' ? step.index() + 1 : null\"\n [attr.aria-setsize]=\"orientation === 'horizontal' ? steps.length : null\"\n [attr.aria-selected]=\"orientation === 'horizontal' ? step.isSelected() : null\"\n [attr.aria-current]=\"orientation === 'vertical' && step.isSelected() ? 'step' : null\"\n [attr.aria-expanded]=\"orientation === 'vertical' ? step.isSelected() : null\"\n [attr.aria-controls]=\"_getStepContentId(step.index())\"\n [attr.aria-label]=\"step.ariaLabel || null\"\n [attr.aria-labelledby]=\"!step.ariaLabel && step.ariaLabelledby ? step.ariaLabelledby : null\"\n [attr.aria-disabled]=\"enabled ? null : 'true'\"\n [index]=\"step.index()\"\n [state]=\"step.indicatorType()\"\n [label]=\"step.stepLabelContent() || step.label\"\n [selected]=\"step.isSelected()\"\n [reached]=\"step.index() < selectedIndex\"\n [active]=\"enabled\"\n [optional]=\"step.optional\"\n [errorMessage]=\"step.errorMessage\"\n [disabled]=\"!enabled\"\n [labelPosition]=\"orientation === 'horizontal' ? labelPosition() : 'end'\"\n [indicatorMode]=\"indicatorMode()\"\n [icon]=\"stepIcon(step)\"\n [hlmTooltip]=\"_headerTooltip(step)\"\n [position]=\"_headerTooltipPosition(step)\"\n [tooltipDisabled]=\"_headerTooltipDisabled(step)\"\n />\n </ng-template>\n\n <ng-template #horizontalStepsTemplate let-steps=\"steps\">\n <ol\n class=\"flex w-full items-center\"\n role=\"tablist\"\n aria-orientation=\"horizontal\"\n [attr.aria-label]=\"stepperAriaLabelledby() ? null : (stepperAriaLabel() ?? null)\"\n [attr.aria-labelledby]=\"stepperAriaLabelledby()\"\n >\n @for (step of steps; track step) {\n <li class=\"flex min-w-0 items-center\">\n <ng-container [ngTemplateOutlet]=\"stepHeaderTemplate\" [ngTemplateOutletContext]=\"{ step: step }\" />\n </li>\n\n @if (!$last) {\n <li class=\"mx-3 flex min-w-8 flex-1 items-center\" aria-hidden=\"true\">\n <span class=\"bg-border relative h-px w-full overflow-hidden rounded\">\n <span\n class=\"bg-primary absolute inset-y-0 inset-s-0 transition-[width] duration-200\"\n [style.width.%]=\"step.index() < selectedIndex ? 100 : 0\"\n ></span>\n </span>\n </li>\n }\n }\n </ol>\n </ng-template>\n\n <ng-template #horizontalPanelTemplate>\n <div class=\"relative min-h-0 overflow-hidden\">\n @for (activeIndex of [selectedIndex]; track activeIndex) {\n <section\n role=\"tabpanel\"\n [id]=\"_getStepContentId(activeIndex)\"\n [attr.aria-labelledby]=\"_getStepLabelId(activeIndex)\"\n [style.animation-duration.ms]=\"animationDuration()\"\n [animate.enter]=\"animationsEnabled() ? _enterAnimationClass() : ''\"\n [animate.leave]=\"animationsEnabled() ? _leaveAnimationClass() : ''\"\n >\n <ng-container [ngTemplateOutlet]=\"steps.get(activeIndex)?.content\" />\n </section>\n }\n </div>\n </ng-template>\n ",
340
389
  }]
341
- }], ctorParameters: () => [], propDecorators: { labelPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "labelPosition", required: false }] }], headerPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "headerPosition", required: false }] }], indicatorMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "indicatorMode", required: false }] }], stepperAriaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "stepperAriaLabel", required: false }] }], stepperAriaLabelledby: [{ type: i0.Input, args: [{ isSignal: true, alias: "stepperAriaLabelledby", required: false }] }], animationsEnabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "animationsEnabled", required: false }] }], animationDuration: [{ type: i0.Input, args: [{ isSignal: true, alias: "animationDuration", required: false }] }] } });
390
+ }], ctorParameters: () => [], propDecorators: { _stepHeader: [{
391
+ type: ViewChildren,
392
+ args: [CdkStepHeader]
393
+ }], labelPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "labelPosition", required: false }] }], headerPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "headerPosition", required: false }] }], indicatorMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "indicatorMode", required: false }] }], stepperAriaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "stepperAriaLabel", required: false }] }], stepperAriaLabelledby: [{ type: i0.Input, args: [{ isSignal: true, alias: "stepperAriaLabelledby", required: false }] }], animationsEnabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "animationsEnabled", required: false }] }], animationDuration: [{ type: i0.Input, args: [{ isSignal: true, alias: "animationDuration", required: false }] }] } });
342
394
 
343
395
  /** Button that moves to the next step in a stepper workflow. */
344
396
  class HlmStepperNext extends CdkStepperNext {
@@ -1,5 +1,5 @@
1
1
  import * as _angular_core from '@angular/core';
2
- import { ValueProvider, TemplateRef } from '@angular/core';
2
+ import { ValueProvider, TemplateRef, QueryList } from '@angular/core';
3
3
  import { TemplatePortal } from '@angular/cdk/portal';
4
4
  import { CdkStepLabel, CdkStep, CdkStepHeader, CdkStepper, CdkStepperNext, CdkStepperPrevious } from '@angular/cdk/stepper';
5
5
 
@@ -23,6 +23,13 @@ declare function injectHlmStepperConfig(): HlmStepperConfig;
23
23
  declare class HlmStep extends CdkStep {
24
24
  private readonly _viewContainerRef;
25
25
  private readonly _destroyRef;
26
+ private _hasCompletionOverride;
27
+ private _controlSubscription?;
28
+ ngOnChanges(): void;
29
+ get completed(): boolean;
30
+ set completed(value: boolean);
31
+ /** @internal Read-only preview of CDK's predecessor check after leaving the current step. */
32
+ _canExit(leaving: boolean): boolean;
26
33
  readonly icon: _angular_core.InputSignal<string | null>;
27
34
  /** Styled header tooltip override. Falls back to the full string label when unset. */
28
35
  readonly tooltip: _angular_core.InputSignal<string | TemplateRef<unknown> | null>;
@@ -77,6 +84,7 @@ declare class HlmStepHeader extends CdkStepHeader {
77
84
 
78
85
  declare class HlmStepper extends CdkStepper {
79
86
  private readonly _config;
87
+ _stepHeader: QueryList<CdkStepHeader>;
80
88
  readonly labelPosition: _angular_core.InputSignal<HlmStepperLabelPosition>;
81
89
  readonly headerPosition: _angular_core.InputSignal<HlmStepperHeaderPosition>;
82
90
  readonly indicatorMode: _angular_core.InputSignal<HlmStepperIndicatorMode>;
@@ -87,8 +95,11 @@ declare class HlmStepper extends CdkStepper {
87
95
  protected readonly _animationDirection: _angular_core.WritableSignal<"forward" | "backward">;
88
96
  protected readonly _hasSelectionChanged: _angular_core.WritableSignal<boolean>;
89
97
  constructor();
98
+ /** Touch and revalidate the current reactive form, then let CDK decide whether navigation is allowed. */
90
99
  next(): void;
91
100
  protected stepIcon(step: CdkStep): string | null;
101
+ /** Preview selection without touching forms or marking steps interacted; activation stays with CDK. */
102
+ protected _isHeaderEnabled(step: HlmStep): boolean;
92
103
  protected _headerTooltip(step: CdkStep): string | TemplateRef<void> | null;
93
104
  protected _headerTooltipPosition(step: CdkStep): HlmStepTooltipPosition;
94
105
  protected _headerTooltipDisabled(step: CdkStep): boolean;
package/table/README.md CHANGED
@@ -130,6 +130,8 @@ There are **no inputs, outputs, or methods** on any table directive. Each direct
130
130
 
131
131
  User `class` attributes on the same element are preserved and merged (the `classes()` helper keeps base classes).
132
132
 
133
+ `HlmTh`/`HlmTd` take a `size` input (`HlmTableSize`: `sm` / `default` / `lg`) scaling density one step down/up: header height `h-8` / `h-10` / `h-12`, cell padding `p-1` / `p-2` / `p-3`.
134
+
133
135
  ## Examples
134
136
 
135
137
  ### 1. Basic invoice table
@@ -1,6 +1,6 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Directive, NgModule } from '@angular/core';
3
- import { classes } from '@egose/shadcn-theme-ng/utils';
2
+ import { Directive, input, NgModule } from '@angular/core';
3
+ import { classes, hlm } from '@egose/shadcn-theme-ng/utils';
4
4
 
5
5
  class HlmTableContainer {
6
6
  constructor() {
@@ -110,11 +110,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
110
110
  * within an HlmTable context.
111
111
  */
112
112
  class HlmTh {
113
+ size = input('default', /* @ts-ignore */
114
+ ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
113
115
  constructor() {
114
- classes(() => "text-foreground h-10 px-2 text-start align-middle font-medium whitespace-nowrap [&:has([role=checkbox])]:pe-0");
116
+ classes(() => hlm("text-foreground h-10 px-2 text-start align-middle font-medium whitespace-nowrap [&:has([role=checkbox])]:pe-0", this.size() === 'sm' ? "h-8" : this.size() === 'lg' ? "h-12" : ''));
115
117
  }
116
118
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmTh, deps: [], target: i0.ɵɵFactoryTarget.Directive });
117
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.1.3", type: HlmTh, isStandalone: true, selector: "th[hlmTh],th[hlmTableHead]", host: { attributes: { "data-slot": "table-head" } }, ngImport: i0 });
119
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.3", type: HlmTh, isStandalone: true, selector: "th[hlmTh],th[hlmTableHead]", inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "data-slot": "table-head" } }, ngImport: i0 });
118
120
  }
119
121
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmTh, decorators: [{
120
122
  type: Directive,
@@ -122,17 +124,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
122
124
  selector: 'th[hlmTh],th[hlmTableHead]',
123
125
  host: { 'data-slot': 'table-head' },
124
126
  }]
125
- }], ctorParameters: () => [] });
127
+ }], ctorParameters: () => [], propDecorators: { size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }] } });
126
128
  /**
127
129
  * Directive to apply Shadcn-like styling to a <td> element
128
130
  * within an HlmTable context.
129
131
  */
130
132
  class HlmTd {
133
+ size = input('default', /* @ts-ignore */
134
+ ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
131
135
  constructor() {
132
- classes(() => "p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pe-0");
136
+ classes(() => hlm("p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pe-0", this.size() === 'sm' ? "p-1" : this.size() === 'lg' ? "p-3" : ''));
133
137
  }
134
138
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmTd, deps: [], target: i0.ɵɵFactoryTarget.Directive });
135
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.1.3", type: HlmTd, isStandalone: true, selector: "td[hlmTd],td[hlmTableCell]", host: { attributes: { "data-slot": "table-cell" } }, ngImport: i0 });
139
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.3", type: HlmTd, isStandalone: true, selector: "td[hlmTd],td[hlmTableCell]", inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "data-slot": "table-cell" } }, ngImport: i0 });
136
140
  }
137
141
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmTd, decorators: [{
138
142
  type: Directive,
@@ -140,7 +144,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
140
144
  selector: 'td[hlmTd],td[hlmTableCell]',
141
145
  host: { 'data-slot': 'table-cell' },
142
146
  }]
143
- }], ctorParameters: () => [] });
147
+ }], ctorParameters: () => [], propDecorators: { size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }] } });
144
148
  /**
145
149
  * Directive to apply Shadcn-like styling to a <caption> element
146
150
  * within an HlmTable context.
@@ -1,5 +1,7 @@
1
1
  import * as i0 from '@angular/core';
2
2
 
3
+ /** Density scale shared by table parts and higher-level components (e.g. data-table). */
4
+ type HlmTableSize = 'sm' | 'default' | 'lg';
3
5
  declare class HlmTableContainer {
4
6
  constructor();
5
7
  static ɵfac: i0.ɵɵFactoryDeclaration<HlmTableContainer, never>;
@@ -54,18 +56,20 @@ declare class HlmTr {
54
56
  * within an HlmTable context.
55
57
  */
56
58
  declare class HlmTh {
59
+ readonly size: i0.InputSignal<HlmTableSize>;
57
60
  constructor();
58
61
  static ɵfac: i0.ɵɵFactoryDeclaration<HlmTh, never>;
59
- static ɵdir: i0.ɵɵDirectiveDeclaration<HlmTh, "th[hlmTh],th[hlmTableHead]", never, {}, {}, never, never, true, never>;
62
+ static ɵdir: i0.ɵɵDirectiveDeclaration<HlmTh, "th[hlmTh],th[hlmTableHead]", never, { "size": { "alias": "size"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
60
63
  }
61
64
  /**
62
65
  * Directive to apply Shadcn-like styling to a <td> element
63
66
  * within an HlmTable context.
64
67
  */
65
68
  declare class HlmTd {
69
+ readonly size: i0.InputSignal<HlmTableSize>;
66
70
  constructor();
67
71
  static ɵfac: i0.ɵɵFactoryDeclaration<HlmTd, never>;
68
- static ɵdir: i0.ɵɵDirectiveDeclaration<HlmTd, "td[hlmTd],td[hlmTableCell]", never, {}, {}, never, never, true, never>;
72
+ static ɵdir: i0.ɵɵDirectiveDeclaration<HlmTd, "td[hlmTd],td[hlmTableCell]", never, { "size": { "alias": "size"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
69
73
  }
70
74
  /**
71
75
  * Directive to apply Shadcn-like styling to a <caption> element
@@ -85,3 +89,4 @@ declare class HlmTableModule {
85
89
  }
86
90
 
87
91
  export { HlmCaption, HlmTBody, HlmTFoot, HlmTHead, HlmTable, HlmTableContainer, HlmTableImports, HlmTableModule, HlmTd, HlmTh, HlmTr };
92
+ export type { HlmTableSize };