@luzmo/ngx-lucero 2.5.0 → 2.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -86,6 +86,69 @@ Angular 17–19 do not recognize custom elements as anchor-like. On those
86
86
  versions, use `routerLink` without a separate `href` for client-side navigation,
87
87
  or upgrade to Angular 20+ when native link behavior is required.
88
88
 
89
+ ## Template inputs
90
+
91
+ Properties marked with `@templateProperty` accept nested named templates through
92
+ `LuzmoTemplate`. Import both the component and `LuzmoTemplate` into your standalone
93
+ component's `imports` array:
94
+
95
+ ```ts
96
+ import { LuzmoTable, LuzmoTableCell, LuzmoTemplate } from '@luzmo/ngx-lucero';
97
+ ```
98
+
99
+ ```html
100
+ <luzmo-table [items]="rows" [columns]="columns">
101
+ <ng-template luzmoTemplate="row" let-item let-index="index">
102
+ <luzmo-table-cell>{{ index }}: {{ item.name }}</luzmo-table-cell>
103
+ </ng-template>
104
+ <ng-template luzmoTemplate="details" let-item>
105
+ Details: {{ item.name }}
106
+ </ng-template>
107
+ </luzmo-table>
108
+ ```
109
+
110
+ The directive must be a direct content child of the wrapper (Angular `@if` and
111
+ `@for` blocks are supported). Templates inside nested components belong to those
112
+ components. Duplicate or unknown slot names throw an error.
113
+
114
+ Explicit inputs remain supported: `[renderItem]="callbackOrTemplate"` takes
115
+ precedence over the `row` slot. A `null` or `undefined` input falls back to the
116
+ nested template; removing that template restores the component's initial renderer.
117
+
118
+ The table context exposes `$implicit`/`item` and the source `index`. Angular views
119
+ refresh when their declaring component is checked, including bindings, events and
120
+ control flow. Each mounted Lit render location owns one view. Changing templates,
121
+ removing content or destroying the wrapper releases the affected views. Unchanged
122
+ templates retain their views across Angular checks. Temporary Lit disconnection
123
+ releases views; reconnecting creates them again.
124
+
125
+ ### Declaring a template property
126
+
127
+ In a web component, replace the renderer's `@property({ attribute: false })`
128
+ with the shared decorator:
129
+
130
+ ```ts
131
+ @templateProperty({ slot: 'row', context: ['item', 'index'], implicit: 'item' })
132
+ public renderItem: ((item: Item, index: number) => unknown) | undefined;
133
+ ```
134
+
135
+ The optional `slot` names the projected template; without it, the property name
136
+ is used. Slot names must be unique within a component.
137
+
138
+ Import `templateProperty` from the core utilities. Continue calling the renderer
139
+ inside a Lit child expression. The analyzer writes the literal context names and
140
+ implicit argument to the Custom Elements Manifest; the Angular generator uses
141
+ that metadata to produce its input and shared adapter. Neither layer branches on
142
+ a component name. This contract requires the renderer result to reach a Lit child
143
+ expression; it does not apply to callbacks that require a string or a DOM element.
144
+
145
+ The wrappers generate typed `TemplateRef` inputs but do not generate
146
+ component-specific context guards to infer `let-item` inside an `ng-template`,
147
+ including templates marked with the generic `LuzmoTemplate` directive.
148
+ The existing callback API remains typed. Decorator options must be literal
149
+ `slot`, `context` and `implicit` values so the analyzer can read them without executing
150
+ component code.
151
+
89
152
  ## Notes
90
153
 
91
154
  - This package depends on `@luzmo/lucero` for the underlying custom elements.
@@ -18,7 +18,7 @@ export declare class LuzmoActionButton implements OnChanges, ControlValueAccesso
18
18
  holdAffordance?: boolean;
19
19
  /** Whether the Action Button should show in a quiet state */
20
20
  quiet?: boolean;
21
- /** The surface treatment for neutral action buttons. `outline` preserves the standard surface; `fill` uses highlighted neutral surface tokens. Quiet, selected, and static-color appearances take precedence. Other variants retain their existing appearance. */
21
+ /** The surface treatment for neutral and primary action buttons. `outline` preserves the standard surface; `fill` uses highlighted neutral surface tokens. Primary fill uses primary surface and inverse content colors. Quiet, selected, and static-color appearances take precedence. Other variants retain their existing appearance. */
22
22
  treatment?: ActionButtonTreatments;
23
23
  /** The role for the Action Button */
24
24
  role?: string;
@@ -28,7 +28,7 @@ export declare class LuzmoActionButton implements OnChanges, ControlValueAccesso
28
28
  toggles?: boolean;
29
29
  /** The static color variant to use for the action button. */
30
30
  staticColor?: 'white' | 'black';
31
- /** The appearance preset to apply to this action button. - `neutral` (default): the standard action button. - `primary`: a primary-colored outline action button. - `negative`: a destructive tool with negative text and icon colors. - `pill`: a content-width chip using the standard action-button radius. - `accent`: a content-width chip with a soft, primary-tinted theme. */
31
+ /** The appearance preset to apply to this action button. - `neutral` (default): the standard action button. - `primary`: a primary-colored outline or filled action button. - `negative`: a destructive tool with negative text and icon colors. - `pill`: a content-width chip using the standard action-button radius. - `accent`: a content-width chip with a soft, primary-tinted theme. */
32
32
  variant?: ActionButtonVariants;
33
33
  /** The value of the Action Button */
34
34
  value?: string;
@@ -25,7 +25,7 @@ export class LuzmoActionButton {
25
25
  holdAffordance;
26
26
  /** Whether the Action Button should show in a quiet state */
27
27
  quiet;
28
- /** The surface treatment for neutral action buttons. `outline` preserves the standard surface; `fill` uses highlighted neutral surface tokens. Quiet, selected, and static-color appearances take precedence. Other variants retain their existing appearance. */
28
+ /** The surface treatment for neutral and primary action buttons. `outline` preserves the standard surface; `fill` uses highlighted neutral surface tokens. Primary fill uses primary surface and inverse content colors. Quiet, selected, and static-color appearances take precedence. Other variants retain their existing appearance. */
29
29
  treatment;
30
30
  /** The role for the Action Button */
31
31
  role;
@@ -35,7 +35,7 @@ export class LuzmoActionButton {
35
35
  toggles;
36
36
  /** The static color variant to use for the action button. */
37
37
  staticColor;
38
- /** The appearance preset to apply to this action button. - `neutral` (default): the standard action button. - `primary`: a primary-colored outline action button. - `negative`: a destructive tool with negative text and icon colors. - `pill`: a content-width chip using the standard action-button radius. - `accent`: a content-width chip with a soft, primary-tinted theme. */
38
+ /** The appearance preset to apply to this action button. - `neutral` (default): the standard action button. - `primary`: a primary-colored outline or filled action button. - `negative`: a destructive tool with negative text and icon colors. - `pill`: a content-width chip using the standard action-button radius. - `accent`: a content-width chip with a soft, primary-tinted theme. */
39
39
  variant;
40
40
  /** The value of the Action Button */
41
41
  value;
@@ -1,8 +1,9 @@
1
1
  import { OnChanges, SimpleChanges } from '@angular/core';
2
2
  import { ControlValueAccessor } from '@angular/forms';
3
3
  import '@luzmo/lucero/action-menu';
4
- import type { LuzmoActionMenu as LuzmoActionMenuHostElement } from '@luzmo/lucero/action-menu';
4
+ import type { LuzmoActionMenu as LuzmoActionMenuHostElement, ActionButtonTreatments, ActionButtonVariants } from '@luzmo/lucero/action-menu';
5
5
  import * as i0 from "@angular/core";
6
+ export type { ActionButtonTreatments, ActionButtonVariants } from '@luzmo/lucero/action-menu';
6
7
  export declare class LuzmoActionMenu implements OnChanges, ControlValueAccessor {
7
8
  private readonly elementRef;
8
9
  private readonly renderer;
@@ -13,6 +14,10 @@ export declare class LuzmoActionMenu implements OnChanges, ControlValueAccessor
13
14
  get nativeElement(): LuzmoActionMenuHostElement;
14
15
  selects?: never | 'single';
15
16
  staticColor?: 'white' | 'black';
17
+ /** The appearance preset for the trigger, independent of the menu variant. When omitted, the trigger uses its neutral variant. */
18
+ buttonVariant?: ActionButtonVariants;
19
+ /** The surface treatment for the trigger, including primary filled actions. When omitted, the trigger uses its outline treatment. */
20
+ buttonTreatment?: ActionButtonTreatments;
16
21
  handleSlottableRequest?: unknown;
17
22
  managePresenceObservedSlot?: unknown;
18
23
  size?: ('xxs' | 'xs' | 's' | 'm' | 'l' | 'xl' | 'xxl');
@@ -76,7 +81,7 @@ export declare class LuzmoActionMenu implements OnChanges, ControlValueAccessor
76
81
  toggle(target?: boolean): void;
77
82
  close(): void;
78
83
  static ɵfac: i0.ɵɵFactoryDeclaration<LuzmoActionMenu, never>;
79
- static ɵcmp: i0.ɵɵComponentDeclaration<LuzmoActionMenu, "luzmo-action-menu", ["luzmoActionMenu"], { "selects": { "alias": "selects"; "required": false; }; "staticColor": { "alias": "staticColor"; "required": false; }; "handleSlottableRequest": { "alias": "handleSlottableRequest"; "required": false; }; "managePresenceObservedSlot": { "alias": "managePresenceObservedSlot"; "required": false; }; "size": { "alias": "size"; "required": false; }; "appliedLabel": { "alias": "appliedLabel"; "required": false; }; "button": { "alias": "button"; "required": false; }; "disabled": { "alias": "disabled"; "required": false; }; "focused": { "alias": "focused"; "required": false; }; "icons": { "alias": "icons"; "required": false; }; "variant": { "alias": "variant"; "required": false; }; "invalid": { "alias": "invalid"; "required": false; }; "pending": { "alias": "pending"; "required": false; }; "pendingLabel": { "alias": "pendingLabel"; "required": false; }; "label": { "alias": "label"; "required": false; }; "open": { "alias": "open"; "required": false; }; "readonly": { "alias": "readonly"; "required": false; }; "labelAlignment": { "alias": "labelAlignment"; "required": false; }; "optionsMenu": { "alias": "optionsMenu"; "required": false; }; "overlayElement": { "alias": "overlayElement"; "required": false; }; "placement": { "alias": "placement"; "required": false; }; "quiet": { "alias": "quiet"; "required": false; }; "value": { "alias": "value"; "required": false; }; "selectedItem": { "alias": "selectedItem"; "required": false; }; "dependencyManager": { "alias": "dependencyManager"; "required": false; }; "isMobile": { "alias": "isMobile"; "required": false; }; "isTouchDevice": { "alias": "isTouchDevice"; "required": false; }; "strategy": { "alias": "strategy"; "required": false; }; "pendingStateController": { "alias": "pendingStateController"; "required": false; }; "applyFocusElementLabel": { "alias": "applyFocusElementLabel"; "required": false; }; "tabIndex": { "alias": "tabIndex"; "required": false; }; }, { "changeEvent": "changeEvent"; "scrollEvent": "scrollEvent"; "keydownEvent": "keydownEvent"; }, never, ["*"], true, never>;
84
+ static ɵcmp: i0.ɵɵComponentDeclaration<LuzmoActionMenu, "luzmo-action-menu", ["luzmoActionMenu"], { "selects": { "alias": "selects"; "required": false; }; "staticColor": { "alias": "staticColor"; "required": false; }; "buttonVariant": { "alias": "buttonVariant"; "required": false; }; "buttonTreatment": { "alias": "buttonTreatment"; "required": false; }; "handleSlottableRequest": { "alias": "handleSlottableRequest"; "required": false; }; "managePresenceObservedSlot": { "alias": "managePresenceObservedSlot"; "required": false; }; "size": { "alias": "size"; "required": false; }; "appliedLabel": { "alias": "appliedLabel"; "required": false; }; "button": { "alias": "button"; "required": false; }; "disabled": { "alias": "disabled"; "required": false; }; "focused": { "alias": "focused"; "required": false; }; "icons": { "alias": "icons"; "required": false; }; "variant": { "alias": "variant"; "required": false; }; "invalid": { "alias": "invalid"; "required": false; }; "pending": { "alias": "pending"; "required": false; }; "pendingLabel": { "alias": "pendingLabel"; "required": false; }; "label": { "alias": "label"; "required": false; }; "open": { "alias": "open"; "required": false; }; "readonly": { "alias": "readonly"; "required": false; }; "labelAlignment": { "alias": "labelAlignment"; "required": false; }; "optionsMenu": { "alias": "optionsMenu"; "required": false; }; "overlayElement": { "alias": "overlayElement"; "required": false; }; "placement": { "alias": "placement"; "required": false; }; "quiet": { "alias": "quiet"; "required": false; }; "value": { "alias": "value"; "required": false; }; "selectedItem": { "alias": "selectedItem"; "required": false; }; "dependencyManager": { "alias": "dependencyManager"; "required": false; }; "isMobile": { "alias": "isMobile"; "required": false; }; "isTouchDevice": { "alias": "isTouchDevice"; "required": false; }; "strategy": { "alias": "strategy"; "required": false; }; "pendingStateController": { "alias": "pendingStateController"; "required": false; }; "applyFocusElementLabel": { "alias": "applyFocusElementLabel"; "required": false; }; "tabIndex": { "alias": "tabIndex"; "required": false; }; }, { "changeEvent": "changeEvent"; "scrollEvent": "scrollEvent"; "keydownEvent": "keydownEvent"; }, never, ["*"], true, never>;
80
85
  }
81
86
  /** The underlying custom element type for LuzmoActionMenu */
82
87
  export type LuzmoActionMenuElement = LuzmoActionMenuHostElement;
@@ -24,6 +24,10 @@ export class LuzmoActionMenu {
24
24
  }
25
25
  selects;
26
26
  staticColor;
27
+ /** The appearance preset for the trigger, independent of the menu variant. When omitted, the trigger uses its neutral variant. */
28
+ buttonVariant;
29
+ /** The surface treatment for the trigger, including primary filled actions. When omitted, the trigger uses its outline treatment. */
30
+ buttonTreatment;
27
31
  handleSlottableRequest;
28
32
  managePresenceObservedSlot;
29
33
  size;
@@ -82,6 +86,12 @@ export class LuzmoActionMenu {
82
86
  case 'staticColor':
83
87
  this.setHostProperty('staticColor', changes['staticColor'].currentValue);
84
88
  break;
89
+ case 'buttonVariant':
90
+ this.setHostProperty('buttonVariant', changes['buttonVariant'].currentValue);
91
+ break;
92
+ case 'buttonTreatment':
93
+ this.setHostProperty('buttonTreatment', changes['buttonTreatment'].currentValue);
94
+ break;
85
95
  case 'handleSlottableRequest':
86
96
  this.setHostProperty('handleSlottableRequest', changes['handleSlottableRequest'].currentValue);
87
97
  break;
@@ -249,7 +259,7 @@ export class LuzmoActionMenu {
249
259
  return this.host.close();
250
260
  }
251
261
  static ɵfac = function LuzmoActionMenu_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || LuzmoActionMenu)(); };
252
- static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: LuzmoActionMenu, selectors: [["luzmo-action-menu"]], inputs: { selects: "selects", staticColor: "staticColor", handleSlottableRequest: "handleSlottableRequest", managePresenceObservedSlot: "managePresenceObservedSlot", size: "size", appliedLabel: "appliedLabel", button: "button", disabled: "disabled", focused: "focused", icons: "icons", variant: "variant", invalid: "invalid", pending: "pending", pendingLabel: "pendingLabel", label: "label", open: "open", readonly: "readonly", labelAlignment: "labelAlignment", optionsMenu: "optionsMenu", overlayElement: "overlayElement", placement: "placement", quiet: "quiet", value: "value", selectedItem: "selectedItem", dependencyManager: "dependencyManager", isMobile: "isMobile", isTouchDevice: "isTouchDevice", strategy: "strategy", pendingStateController: "pendingStateController", applyFocusElementLabel: "applyFocusElementLabel", tabIndex: "tabIndex" }, outputs: { changeEvent: "changeEvent", scrollEvent: "scrollEvent", keydownEvent: "keydownEvent" }, exportAs: ["luzmoActionMenu"], features: [i0.ɵɵProvidersFeature([
262
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: LuzmoActionMenu, selectors: [["luzmo-action-menu"]], inputs: { selects: "selects", staticColor: "staticColor", buttonVariant: "buttonVariant", buttonTreatment: "buttonTreatment", handleSlottableRequest: "handleSlottableRequest", managePresenceObservedSlot: "managePresenceObservedSlot", size: "size", appliedLabel: "appliedLabel", button: "button", disabled: "disabled", focused: "focused", icons: "icons", variant: "variant", invalid: "invalid", pending: "pending", pendingLabel: "pendingLabel", label: "label", open: "open", readonly: "readonly", labelAlignment: "labelAlignment", optionsMenu: "optionsMenu", overlayElement: "overlayElement", placement: "placement", quiet: "quiet", value: "value", selectedItem: "selectedItem", dependencyManager: "dependencyManager", isMobile: "isMobile", isTouchDevice: "isTouchDevice", strategy: "strategy", pendingStateController: "pendingStateController", applyFocusElementLabel: "applyFocusElementLabel", tabIndex: "tabIndex" }, outputs: { changeEvent: "changeEvent", scrollEvent: "scrollEvent", keydownEvent: "keydownEvent" }, exportAs: ["luzmoActionMenu"], features: [i0.ɵɵProvidersFeature([
253
263
  {
254
264
  provide: NG_VALUE_ACCESSOR,
255
265
  useExisting: forwardRef(() => LuzmoActionMenu),
@@ -282,6 +292,12 @@ export class LuzmoActionMenu {
282
292
  }], staticColor: [{
283
293
  type: Input,
284
294
  args: [{ alias: 'staticColor' }]
295
+ }], buttonVariant: [{
296
+ type: Input,
297
+ args: [{ alias: 'buttonVariant' }]
298
+ }], buttonTreatment: [{
299
+ type: Input,
300
+ args: [{ alias: 'buttonTreatment' }]
285
301
  }], handleSlottableRequest: [{
286
302
  type: Input,
287
303
  args: [{ alias: 'handleSlottableRequest' }]
@@ -370,4 +386,4 @@ export class LuzmoActionMenu {
370
386
  type: Input,
371
387
  args: [{ alias: 'tabIndex' }]
372
388
  }], changeEvent: [{ type: i0.Output, args: ["changeEvent"] }], scrollEvent: [{ type: i0.Output, args: ["scrollEvent"] }], keydownEvent: [{ type: i0.Output, args: ["keydownEvent"] }] }); })();
373
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(LuzmoActionMenu, { className: "LuzmoActionMenu", filePath: "components/action-menu.ts", lineNumber: 29 }); })();
389
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(LuzmoActionMenu, { className: "LuzmoActionMenu", filePath: "components/action-menu.ts", lineNumber: 30 }); })();
@@ -19,7 +19,6 @@ export declare class LuzmoProgressSteps implements OnChanges {
19
19
  collapsed?: boolean;
20
20
  /** 'detailed' (default): the history lists main steps with their substeps - 'compact': the history lists main steps only */
21
21
  displayMode?: ProgressStepsDisplayMode;
22
- condensed?: boolean;
23
22
  /** Visible and announced copy. Partial overrides are merged over the English defaults. `{{count}}` is replaced in the count labels. */
24
23
  labels?: Partial<ProgressStepsLabels>;
25
24
  /** Disables the shimmer and transitions. */
@@ -42,7 +41,7 @@ export declare class LuzmoProgressSteps implements OnChanges {
42
41
  private setHostProperty;
43
42
  private bindEvents;
44
43
  static ɵfac: i0.ɵɵFactoryDeclaration<LuzmoProgressSteps, never>;
45
- static ɵcmp: i0.ɵɵComponentDeclaration<LuzmoProgressSteps, "luzmo-progress-steps", ["luzmoProgressSteps"], { "progress": { "alias": "progress"; "required": false; }; "locale": { "alias": "locale"; "required": false; }; "collapsed": { "alias": "collapsed"; "required": false; }; "displayMode": { "alias": "displayMode"; "required": false; }; "condensed": { "alias": "condensed"; "required": false; }; "labels": { "alias": "labels"; "required": false; }; "noAnimate": { "alias": "noAnimate"; "required": false; }; "open": { "alias": "open"; "required": false; }; "size": { "alias": "size"; "required": false; }; }, { "luzmoStepExpanded": "luzmo-step-expanded"; "luzmoStepCollapsed": "luzmo-step-collapsed"; }, never, ["*"], true, never>;
44
+ static ɵcmp: i0.ɵɵComponentDeclaration<LuzmoProgressSteps, "luzmo-progress-steps", ["luzmoProgressSteps"], { "progress": { "alias": "progress"; "required": false; }; "locale": { "alias": "locale"; "required": false; }; "collapsed": { "alias": "collapsed"; "required": false; }; "displayMode": { "alias": "displayMode"; "required": false; }; "labels": { "alias": "labels"; "required": false; }; "noAnimate": { "alias": "noAnimate"; "required": false; }; "open": { "alias": "open"; "required": false; }; "size": { "alias": "size"; "required": false; }; }, { "luzmoStepExpanded": "luzmo-step-expanded"; "luzmoStepCollapsed": "luzmo-step-collapsed"; }, never, ["*"], true, never>;
46
45
  }
47
46
  /** The underlying custom element type for LuzmoProgressSteps */
48
47
  export type LuzmoProgressStepsElement = LuzmoProgressStepsHostElement;
@@ -23,7 +23,6 @@ export class LuzmoProgressSteps {
23
23
  collapsed;
24
24
  /** 'detailed' (default): the history lists main steps with their substeps - 'compact': the history lists main steps only */
25
25
  displayMode;
26
- condensed;
27
26
  /** Visible and announced copy. Partial overrides are merged over the English defaults. `{{count}}` is replaced in the count labels. */
28
27
  labels;
29
28
  /** Disables the shimmer and transitions. */
@@ -58,9 +57,6 @@ export class LuzmoProgressSteps {
58
57
  case 'displayMode':
59
58
  this.setHostProperty('displayMode', changes['displayMode'].currentValue);
60
59
  break;
61
- case 'condensed':
62
- this.setHostProperty('condensed', changes['condensed'].currentValue);
63
- break;
64
60
  case 'labels':
65
61
  this.setHostProperty('labels', changes['labels'].currentValue);
66
62
  break;
@@ -96,7 +92,7 @@ export class LuzmoProgressSteps {
96
92
  }));
97
93
  }
98
94
  static ɵfac = function LuzmoProgressSteps_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || LuzmoProgressSteps)(); };
99
- static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: LuzmoProgressSteps, selectors: [["luzmo-progress-steps"]], inputs: { progress: "progress", locale: "locale", collapsed: "collapsed", displayMode: "displayMode", condensed: "condensed", labels: "labels", noAnimate: "noAnimate", open: "open", size: "size" }, outputs: { luzmoStepExpanded: "luzmo-step-expanded", luzmoStepCollapsed: "luzmo-step-collapsed" }, exportAs: ["luzmoProgressSteps"], features: [i0.ɵɵNgOnChangesFeature], ngContentSelectors: _c0, decls: 1, vars: 0, template: function LuzmoProgressSteps_Template(rf, ctx) { if (rf & 1) {
95
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: LuzmoProgressSteps, selectors: [["luzmo-progress-steps"]], inputs: { progress: "progress", locale: "locale", collapsed: "collapsed", displayMode: "displayMode", labels: "labels", noAnimate: "noAnimate", open: "open", size: "size" }, outputs: { luzmoStepExpanded: "luzmo-step-expanded", luzmoStepCollapsed: "luzmo-step-collapsed" }, exportAs: ["luzmoProgressSteps"], features: [i0.ɵɵNgOnChangesFeature], ngContentSelectors: _c0, decls: 1, vars: 0, template: function LuzmoProgressSteps_Template(rf, ctx) { if (rf & 1) {
100
96
  i0.ɵɵprojectionDef();
101
97
  i0.ɵɵprojection(0);
102
98
  } }, encapsulation: 2 });
@@ -122,9 +118,6 @@ export class LuzmoProgressSteps {
122
118
  }], displayMode: [{
123
119
  type: Input,
124
120
  args: [{ alias: 'displayMode' }]
125
- }], condensed: [{
126
- type: Input,
127
- args: [{ alias: 'condensed' }]
128
121
  }], labels: [{
129
122
  type: Input,
130
123
  args: [{ alias: 'labels' }]
@@ -1,4 +1,4 @@
1
- import { OnChanges, SimpleChanges } from '@angular/core';
1
+ import { OnChanges, SimpleChanges, TemplateRef } from '@angular/core';
2
2
  import '@luzmo/lucero/table';
3
3
  import type { LuzmoTable as LuzmoTableHostElement } from '@luzmo/lucero/table';
4
4
  import * as i0 from "@angular/core";
@@ -8,6 +8,10 @@ export declare class LuzmoTable implements OnChanges {
8
8
  private readonly destroyRef;
9
9
  private readonly host;
10
10
  private readonly listenerCleanup;
11
+ private projectedTemplates?;
12
+ private readonly templateValues;
13
+ private readonly templateDefaults;
14
+ private readonly templateInputs;
11
15
  /** The underlying custom element instance. Use to call imperative methods. */
12
16
  get nativeElement(): LuzmoTableHostElement;
13
17
  role?: string;
@@ -32,11 +36,19 @@ export declare class LuzmoTable implements OnChanges {
32
36
  /** Accessible name of a data-mode row checkbox. Defaults to the first column's text, then `labels.selectRow`. */
33
37
  itemLabel?: unknown;
34
38
  /** Cell content of a data-mode row. Return `luzmo-table-cell` elements. */
35
- renderItem?: unknown;
39
+ renderItem?: LuzmoTableHostElement['renderItem'] | TemplateRef<{
40
+ item: Parameters<NonNullable<LuzmoTableHostElement['renderItem']>>[0];
41
+ index: Parameters<NonNullable<LuzmoTableHostElement['renderItem']>>[1];
42
+ $implicit: Parameters<NonNullable<LuzmoTableHostElement['renderItem']>>[0];
43
+ }> | null;
36
44
  /** Expanded row values. Setting `renderDetails` enables data-mode disclosure. */
37
45
  expanded?: string[];
38
46
  /** Details content of a data-mode row. Its presence enables row disclosure for every non-information row. */
39
- renderDetails?: unknown;
47
+ renderDetails?: LuzmoTableHostElement['renderDetails'] | TemplateRef<{
48
+ item: Parameters<NonNullable<LuzmoTableHostElement['renderDetails']>>[0];
49
+ index: Parameters<NonNullable<LuzmoTableHostElement['renderDetails']>>[1];
50
+ $implicit: Parameters<NonNullable<LuzmoTableHostElement['renderDetails']>>[0];
51
+ }> | null;
40
52
  /** Resized column widths, in pixels, keyed by column id. A resize updates this map without changing `columns`. */
41
53
  columnWidths?: Record<string, number>;
42
54
  /** Data-mode columns, used when no `luzmo-table-head` is slotted. */
@@ -58,6 +70,8 @@ export declare class LuzmoTable implements OnChanges {
58
70
  readonly luzmoRangeChanged: import("@angular/core").OutputEmitterRef<CustomEvent<unknown>>;
59
71
  constructor();
60
72
  ngOnChanges(changes: SimpleChanges): void;
73
+ ngAfterContentChecked(): void;
74
+ private updateTemplateInputs;
61
75
  /**
62
76
  * Forward a wrapper @Input to the underlying host element via Renderer2 so
63
77
  * the wrapper stays compatible with non-DOM Angular platforms (SSR, tests).
@@ -69,7 +83,7 @@ export declare class LuzmoTable implements OnChanges {
69
83
  /** Moves focus to the grid's current cell. */
70
84
  focus(options?: FocusOptions): void;
71
85
  static ɵfac: i0.ɵɵFactoryDeclaration<LuzmoTable, never>;
72
- static ɵcmp: i0.ɵɵComponentDeclaration<LuzmoTable, "luzmo-table", ["luzmoTable"], { "role": { "alias": "role"; "required": false; }; "density": { "alias": "density"; "required": false; }; "emphasized": { "alias": "emphasized"; "required": false; }; "quiet": { "alias": "quiet"; "required": false; }; "scroller": { "alias": "scroller"; "required": false; }; "selects": { "alias": "selects"; "required": false; }; "selected": { "alias": "selected"; "required": false; }; "selectAllLabel": { "alias": "selectAllLabel"; "required": false; }; "items": { "alias": "items"; "required": false; }; "itemValue": { "alias": "itemValue"; "required": false; }; "itemLabel": { "alias": "itemLabel"; "required": false; }; "renderItem": { "alias": "renderItem"; "required": false; }; "expanded": { "alias": "expanded"; "required": false; }; "renderDetails": { "alias": "renderDetails"; "required": false; }; "columnWidths": { "alias": "columnWidths"; "required": false; }; "columns": { "alias": "columns"; "required": false; }; "virtualized": { "alias": "virtualized"; "required": false; }; "labels": { "alias": "labels"; "required": false; }; "size": { "alias": "size"; "required": false; }; }, { "changeEvent": "changeEvent"; "luzmoTableSorted": "luzmo-table-sorted"; "luzmoTableRowToggle": "luzmo-table-row-toggle"; "luzmoColumnResized": "luzmo-column-resized"; "luzmoRangeChanged": "luzmo-range-changed"; }, never, ["*"], true, never>;
86
+ static ɵcmp: i0.ɵɵComponentDeclaration<LuzmoTable, "luzmo-table", ["luzmoTable"], { "role": { "alias": "role"; "required": false; }; "density": { "alias": "density"; "required": false; }; "emphasized": { "alias": "emphasized"; "required": false; }; "quiet": { "alias": "quiet"; "required": false; }; "scroller": { "alias": "scroller"; "required": false; }; "selects": { "alias": "selects"; "required": false; }; "selected": { "alias": "selected"; "required": false; }; "selectAllLabel": { "alias": "selectAllLabel"; "required": false; }; "items": { "alias": "items"; "required": false; }; "itemValue": { "alias": "itemValue"; "required": false; }; "itemLabel": { "alias": "itemLabel"; "required": false; }; "renderItem": { "alias": "renderItem"; "required": false; }; "expanded": { "alias": "expanded"; "required": false; }; "renderDetails": { "alias": "renderDetails"; "required": false; }; "columnWidths": { "alias": "columnWidths"; "required": false; }; "columns": { "alias": "columns"; "required": false; }; "virtualized": { "alias": "virtualized"; "required": false; }; "labels": { "alias": "labels"; "required": false; }; "size": { "alias": "size"; "required": false; }; }, { "changeEvent": "changeEvent"; "luzmoTableSorted": "luzmo-table-sorted"; "luzmoTableRowToggle": "luzmo-table-row-toggle"; "luzmoColumnResized": "luzmo-column-resized"; "luzmoRangeChanged": "luzmo-range-changed"; }, ["projectedTemplates"], ["*"], true, never>;
73
87
  }
74
88
  /** The underlying custom element type for LuzmoTable */
75
89
  export type LuzmoTableElement = LuzmoTableHostElement;
@@ -1,5 +1,7 @@
1
- import { ChangeDetectionStrategy, Component, DestroyRef, ElementRef, inject, Input, output, Renderer2 } from '@angular/core';
1
+ import { ApplicationRef, ChangeDetectionStrategy, Component, ContentChildren, DestroyRef, ElementRef, inject, Input, output, Renderer2 } from '@angular/core';
2
2
  import '@luzmo/lucero/table';
3
+ import { AngularTemplateInput } from './template-input.js';
4
+ import { LuzmoTemplate, collectTemplateSlots } from './template.js';
3
5
  import * as i0 from "@angular/core";
4
6
  const _c0 = ["*"];
5
7
  /**
@@ -13,6 +15,16 @@ export class LuzmoTable {
13
15
  destroyRef = inject(DestroyRef);
14
16
  host = this.elementRef.nativeElement;
15
17
  listenerCleanup = [];
18
+ projectedTemplates;
19
+ templateValues = new Map();
20
+ templateDefaults = {
21
+ renderItem: this.host.renderItem,
22
+ renderDetails: this.host.renderDetails
23
+ };
24
+ templateInputs = {
25
+ renderItem: new AngularTemplateInput(inject(ApplicationRef)),
26
+ renderDetails: new AngularTemplateInput(inject(ApplicationRef))
27
+ };
16
28
  /** The underlying custom element instance. Use to call imperative methods. */
17
29
  get nativeElement() {
18
30
  return this.host;
@@ -66,6 +78,8 @@ export class LuzmoTable {
66
78
  constructor() {
67
79
  this.bindEvents();
68
80
  this.destroyRef.onDestroy(() => {
81
+ for (const input of Object.values(this.templateInputs))
82
+ input.destroy();
69
83
  for (const cleanup of this.listenerCleanup) {
70
84
  cleanup();
71
85
  }
@@ -107,15 +121,9 @@ export class LuzmoTable {
107
121
  case 'itemLabel':
108
122
  this.setHostProperty('itemLabel', changes['itemLabel'].currentValue);
109
123
  break;
110
- case 'renderItem':
111
- this.setHostProperty('renderItem', changes['renderItem'].currentValue);
112
- break;
113
124
  case 'expanded':
114
125
  this.setHostProperty('expanded', changes['expanded'].currentValue);
115
126
  break;
116
- case 'renderDetails':
117
- this.setHostProperty('renderDetails', changes['renderDetails'].currentValue);
118
- break;
119
127
  case 'columnWidths':
120
128
  this.setHostProperty('columnWidths', changes['columnWidths'].currentValue);
121
129
  break;
@@ -135,6 +143,27 @@ export class LuzmoTable {
135
143
  break;
136
144
  }
137
145
  }
146
+ this.updateTemplateInputs();
147
+ }
148
+ ngAfterContentChecked() {
149
+ this.updateTemplateInputs();
150
+ }
151
+ updateTemplateInputs() {
152
+ const slots = collectTemplateSlots(this.projectedTemplates ?? [], ["row", "details"]);
153
+ {
154
+ const value = this.renderItem ?? slots.get("row") ?? this.templateDefaults.renderItem;
155
+ if (!this.templateValues.has('renderItem') || this.templateValues.get('renderItem') !== value) {
156
+ this.setHostProperty('renderItem', this.templateInputs.renderItem.set(value, { "context": ["item", "index"], "implicit": "item", "slot": "row" }));
157
+ this.templateValues.set('renderItem', value);
158
+ }
159
+ }
160
+ {
161
+ const value = this.renderDetails ?? slots.get("details") ?? this.templateDefaults.renderDetails;
162
+ if (!this.templateValues.has('renderDetails') || this.templateValues.get('renderDetails') !== value) {
163
+ this.setHostProperty('renderDetails', this.templateInputs.renderDetails.set(value, { "context": ["item", "index"], "implicit": "item", "slot": "details" }));
164
+ this.templateValues.set('renderDetails', value);
165
+ }
166
+ }
138
167
  }
139
168
  /**
140
169
  * Forward a wrapper @Input to the underlying host element via Renderer2 so
@@ -167,7 +196,12 @@ export class LuzmoTable {
167
196
  return this.host.focus(options);
168
197
  }
169
198
  static ɵfac = function LuzmoTable_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || LuzmoTable)(); };
170
- static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: LuzmoTable, selectors: [["luzmo-table"]], inputs: { role: "role", density: "density", emphasized: "emphasized", quiet: "quiet", scroller: "scroller", selects: "selects", selected: "selected", selectAllLabel: "selectAllLabel", items: "items", itemValue: "itemValue", itemLabel: "itemLabel", renderItem: "renderItem", expanded: "expanded", renderDetails: "renderDetails", columnWidths: "columnWidths", columns: "columns", virtualized: "virtualized", labels: "labels", size: "size" }, outputs: { changeEvent: "changeEvent", luzmoTableSorted: "luzmo-table-sorted", luzmoTableRowToggle: "luzmo-table-row-toggle", luzmoColumnResized: "luzmo-column-resized", luzmoRangeChanged: "luzmo-range-changed" }, exportAs: ["luzmoTable"], features: [i0.ɵɵNgOnChangesFeature], ngContentSelectors: _c0, decls: 1, vars: 0, template: function LuzmoTable_Template(rf, ctx) { if (rf & 1) {
199
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: LuzmoTable, selectors: [["luzmo-table"]], contentQueries: function LuzmoTable_ContentQueries(rf, ctx, dirIndex) { if (rf & 1) {
200
+ i0.ɵɵcontentQuery(dirIndex, LuzmoTemplate, 4);
201
+ } if (rf & 2) {
202
+ let _t;
203
+ i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.projectedTemplates = _t);
204
+ } }, inputs: { role: "role", density: "density", emphasized: "emphasized", quiet: "quiet", scroller: "scroller", selects: "selects", selected: "selected", selectAllLabel: "selectAllLabel", items: "items", itemValue: "itemValue", itemLabel: "itemLabel", renderItem: "renderItem", expanded: "expanded", renderDetails: "renderDetails", columnWidths: "columnWidths", columns: "columns", virtualized: "virtualized", labels: "labels", size: "size" }, outputs: { changeEvent: "changeEvent", luzmoTableSorted: "luzmo-table-sorted", luzmoTableRowToggle: "luzmo-table-row-toggle", luzmoColumnResized: "luzmo-column-resized", luzmoRangeChanged: "luzmo-range-changed" }, exportAs: ["luzmoTable"], features: [i0.ɵɵNgOnChangesFeature], ngContentSelectors: _c0, decls: 1, vars: 0, template: function LuzmoTable_Template(rf, ctx) { if (rf & 1) {
171
205
  i0.ɵɵprojectionDef();
172
206
  i0.ɵɵprojection(0);
173
207
  } }, encapsulation: 2 });
@@ -181,7 +215,10 @@ export class LuzmoTable {
181
215
  changeDetection: ChangeDetectionStrategy.OnPush,
182
216
  template: '<ng-content />'
183
217
  }]
184
- }], () => [], { role: [{
218
+ }], () => [], { projectedTemplates: [{
219
+ type: ContentChildren,
220
+ args: [LuzmoTemplate, { descendants: false }]
221
+ }], role: [{
185
222
  type: Input,
186
223
  args: [{ alias: 'role' }]
187
224
  }], density: [{
@@ -239,4 +276,4 @@ export class LuzmoTable {
239
276
  type: Input,
240
277
  args: [{ alias: 'size' }]
241
278
  }], changeEvent: [{ type: i0.Output, args: ["changeEvent"] }], luzmoTableSorted: [{ type: i0.Output, args: ["luzmo-table-sorted"] }], luzmoTableRowToggle: [{ type: i0.Output, args: ["luzmo-table-row-toggle"] }], luzmoColumnResized: [{ type: i0.Output, args: ["luzmo-column-resized"] }], luzmoRangeChanged: [{ type: i0.Output, args: ["luzmo-range-changed"] }] }); })();
242
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(LuzmoTable, { className: "LuzmoTable", filePath: "components/table.ts", lineNumber: 17 }); })();
279
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(LuzmoTable, { className: "LuzmoTable", filePath: "components/table.ts", lineNumber: 19 }); })();
@@ -0,0 +1,11 @@
1
+ import { ApplicationRef } from '@angular/core';
2
+ import { type TemplatePropertyOptions } from '@luzmo/lucero/utils';
3
+ export declare class AngularTemplateInput {
4
+ private readonly application;
5
+ private readonly views;
6
+ private generation;
7
+ constructor(application: ApplicationRef);
8
+ set(value: unknown, options: TemplatePropertyOptions): unknown;
9
+ destroy(): void;
10
+ private release;
11
+ }
@@ -0,0 +1,56 @@
1
+ import { TemplateRef } from '@angular/core';
2
+ import { createTemplateRenderer } from '@luzmo/lucero/utils';
3
+ export class AngularTemplateInput {
4
+ application;
5
+ views = new Set();
6
+ generation = 0;
7
+ constructor(application) {
8
+ this.application = application;
9
+ }
10
+ set(value, options) {
11
+ this.destroy();
12
+ if (!(value instanceof TemplateRef))
13
+ return value;
14
+ const generation = this.generation;
15
+ return createTemplateRenderer((args) => {
16
+ if (generation !== this.generation) {
17
+ return { nodes: [], update() { }, destroy() { } };
18
+ }
19
+ const context = Object.fromEntries(options.context.map((name, index) => [name, args[index]]));
20
+ context['$implicit'] = context[options.implicit];
21
+ const view = value.createEmbeddedView(context);
22
+ this.views.add(view);
23
+ try {
24
+ this.application.attachView(view);
25
+ view.detectChanges();
26
+ }
27
+ catch (error) {
28
+ this.release(view);
29
+ throw error;
30
+ }
31
+ return {
32
+ nodes: view.rootNodes,
33
+ update: (next) => {
34
+ if (view.destroyed)
35
+ return;
36
+ for (const [index, name] of options.context.entries())
37
+ view.context[name] = next[index];
38
+ view.context['$implicit'] = view.context[options.implicit];
39
+ view.detectChanges();
40
+ },
41
+ destroy: () => this.release(view)
42
+ };
43
+ });
44
+ }
45
+ destroy() {
46
+ this.generation++;
47
+ for (const view of this.views)
48
+ this.release(view);
49
+ }
50
+ release(view) {
51
+ if (!this.views.delete(view))
52
+ return;
53
+ this.application.detachView(view);
54
+ view.destroy();
55
+ }
56
+ }
@@ -0,0 +1,10 @@
1
+ import { TemplateRef } from '@angular/core';
2
+ import * as i0 from "@angular/core";
3
+ /** A named template consumed by its direct parent Lucero wrapper. */
4
+ export declare class LuzmoTemplate {
5
+ luzmoTemplate: string;
6
+ readonly template: TemplateRef<any>;
7
+ static ɵfac: i0.ɵɵFactoryDeclaration<LuzmoTemplate, never>;
8
+ static ɵdir: i0.ɵɵDirectiveDeclaration<LuzmoTemplate, "ng-template[luzmoTemplate]", never, { "luzmoTemplate": { "alias": "luzmoTemplate"; "required": true; }; }, {}, never, never, true, never>;
9
+ }
10
+ export declare function collectTemplateSlots(templates: Iterable<LuzmoTemplate>, names: readonly string[]): Map<string, TemplateRef<unknown>>;
@@ -0,0 +1,30 @@
1
+ import { Directive, Input, TemplateRef, inject } from '@angular/core';
2
+ import * as i0 from "@angular/core";
3
+ /** A named template consumed by its direct parent Lucero wrapper. */
4
+ export class LuzmoTemplate {
5
+ luzmoTemplate;
6
+ template = inject(TemplateRef);
7
+ static ɵfac = function LuzmoTemplate_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || LuzmoTemplate)(); };
8
+ static ɵdir = /*@__PURE__*/ i0.ɵɵdefineDirective({ type: LuzmoTemplate, selectors: [["ng-template", "luzmoTemplate", ""]], inputs: { luzmoTemplate: "luzmoTemplate" } });
9
+ }
10
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(LuzmoTemplate, [{
11
+ type: Directive,
12
+ args: [{ selector: 'ng-template[luzmoTemplate]', standalone: true }]
13
+ }], null, { luzmoTemplate: [{
14
+ type: Input,
15
+ args: [{ required: true }]
16
+ }] }); })();
17
+ export function collectTemplateSlots(templates, names) {
18
+ const slots = new Map();
19
+ for (const directive of templates) {
20
+ const name = directive.luzmoTemplate;
21
+ if (!names.includes(name)) {
22
+ throw new Error(`Unknown Lucero template slot: ${name}. Expected: ${names.join(', ')}.`);
23
+ }
24
+ if (slots.has(name)) {
25
+ throw new Error(`Duplicate Lucero template slot: ${name}.`);
26
+ }
27
+ slots.set(name, directive.template);
28
+ }
29
+ return slots;
30
+ }
package/esm/index.d.ts CHANGED
@@ -170,6 +170,7 @@ export { LuzmoToast, type LuzmoToastElement } from './components/toast.js';
170
170
  export { LuzmoTooltip, type LuzmoTooltipElement } from './components/tooltip.js';
171
171
  export { LuzmoTopNav, type LuzmoTopNavElement } from './components/top-nav.js';
172
172
  export { LuzmoTopNavItem, type LuzmoTopNavItemElement } from './components/top-nav-item.js';
173
+ export { LuzmoTemplate } from './components/template.js';
173
174
  export declare const LUZMO_ANGULAR_COMPONENTS: readonly [typeof LuzmoAccordion, typeof LuzmoAccordionItem, typeof LuzmoActionBar, typeof LuzmoActionButton, typeof LuzmoActionGroup, typeof LuzmoActionMenu, typeof LuzmoAvatar, typeof LuzmoBadge, typeof LuzmoButton, typeof LuzmoButtonGroup, typeof LuzmoCalendar, typeof LuzmoChatMessage, typeof LuzmoChatMessageGroup, typeof LuzmoCheckbox, typeof LuzmoClearButton, typeof LuzmoCloseButton, typeof LuzmoColorArea, typeof LuzmoColorField, typeof LuzmoColorHandle, typeof LuzmoColorLoupe, typeof LuzmoColorMenu, typeof LuzmoColorPalette, typeof LuzmoColorPaletteGroup, typeof LuzmoColorPicker, typeof LuzmoColorSlider, typeof LuzmoDateRangePicker, typeof LuzmoDateTimePicker, typeof LuzmoDivider, typeof LuzmoFieldGroup, typeof LuzmoFieldLabel, typeof LuzmoHelpText, typeof LuzmoIcon, typeof LuzmoInfieldButton, typeof LuzmoLabel, typeof LuzmoMenu, typeof LuzmoMenuDivider, typeof LuzmoMenuGroup, typeof LuzmoMenuItem, typeof LuzmoMultiLanguageField, typeof LuzmoNotice, typeof LuzmoNumberField, typeof LuzmoOption, typeof LuzmoOptions, typeof LuzmoOptionsDivider, typeof LuzmoOverlay, typeof LuzmoOverlayTrigger, typeof LuzmoPicker, typeof LuzmoPickerButton, typeof LuzmoPopover, typeof LuzmoProgressBar, typeof LuzmoProgressCircle, typeof LuzmoProgressSteps, typeof LuzmoPromptBox, typeof LuzmoQuestionBox, typeof LuzmoRadio, typeof LuzmoRadioGroup, typeof LuzmoSearch, typeof LuzmoSelect, typeof LuzmoSkeletonLoader, typeof LuzmoSlider, typeof LuzmoSliderHandle, typeof LuzmoSplitView, typeof LuzmoStatusLight, typeof LuzmoSwatch, typeof LuzmoSwatchGroup, typeof LuzmoSwitch, typeof LuzmoTab, typeof LuzmoTabPanel, typeof LuzmoTable, typeof LuzmoTableBody, typeof LuzmoTableCell, typeof LuzmoTableCheckboxCell, typeof LuzmoTableDisclosureCell, typeof LuzmoTableHead, typeof LuzmoTableHeadCell, typeof LuzmoTableRow, typeof LuzmoTableRowDetails, typeof LuzmoTabs, typeof LuzmoTabsOverflow, typeof LuzmoTag, typeof LuzmoTags, typeof LuzmoTextField, typeof LuzmoToast, typeof LuzmoTooltip, typeof LuzmoTopNav, typeof LuzmoTopNavItem];
174
175
  export declare const LUZMO_ANGULAR_COMPONENT_NAMES: readonly ["LuzmoAccordion", "LuzmoAccordionItem", "LuzmoActionBar", "LuzmoActionButton", "LuzmoActionGroup", "LuzmoActionMenu", "LuzmoAvatar", "LuzmoBadge", "LuzmoButton", "LuzmoButtonGroup", "LuzmoCalendar", "LuzmoChatMessage", "LuzmoChatMessageGroup", "LuzmoCheckbox", "LuzmoClearButton", "LuzmoCloseButton", "LuzmoColorArea", "LuzmoColorField", "LuzmoColorHandle", "LuzmoColorLoupe", "LuzmoColorMenu", "LuzmoColorPalette", "LuzmoColorPaletteGroup", "LuzmoColorPicker", "LuzmoColorSlider", "LuzmoDateRangePicker", "LuzmoDateTimePicker", "LuzmoDivider", "LuzmoFieldGroup", "LuzmoFieldLabel", "LuzmoHelpText", "LuzmoIcon", "LuzmoInfieldButton", "LuzmoLabel", "LuzmoMenu", "LuzmoMenuDivider", "LuzmoMenuGroup", "LuzmoMenuItem", "LuzmoMultiLanguageField", "LuzmoNotice", "LuzmoNumberField", "LuzmoOption", "LuzmoOptions", "LuzmoOptionsDivider", "LuzmoOverlay", "LuzmoOverlayTrigger", "LuzmoPicker", "LuzmoPickerButton", "LuzmoPopover", "LuzmoProgressBar", "LuzmoProgressCircle", "LuzmoProgressSteps", "LuzmoPromptBox", "LuzmoQuestionBox", "LuzmoRadio", "LuzmoRadioGroup", "LuzmoSearch", "LuzmoSelect", "LuzmoSkeletonLoader", "LuzmoSlider", "LuzmoSliderHandle", "LuzmoSplitView", "LuzmoStatusLight", "LuzmoSwatch", "LuzmoSwatchGroup", "LuzmoSwitch", "LuzmoTab", "LuzmoTabPanel", "LuzmoTable", "LuzmoTableBody", "LuzmoTableCell", "LuzmoTableCheckboxCell", "LuzmoTableDisclosureCell", "LuzmoTableHead", "LuzmoTableHeadCell", "LuzmoTableRow", "LuzmoTableRowDetails", "LuzmoTabs", "LuzmoTabsOverflow", "LuzmoTag", "LuzmoTags", "LuzmoTextField", "LuzmoToast", "LuzmoTooltip", "LuzmoTopNav", "LuzmoTopNavItem"];
175
176
  export type LuzmoAngularComponentName = (typeof LUZMO_ANGULAR_COMPONENT_NAMES)[number];
package/esm/index.js CHANGED
@@ -171,6 +171,7 @@ export { LuzmoToast } from './components/toast.js';
171
171
  export { LuzmoTooltip } from './components/tooltip.js';
172
172
  export { LuzmoTopNav } from './components/top-nav.js';
173
173
  export { LuzmoTopNavItem } from './components/top-nav-item.js';
174
+ export { LuzmoTemplate } from './components/template.js';
174
175
  export const LUZMO_ANGULAR_COMPONENTS = [
175
176
  LuzmoAccordion,
176
177
  LuzmoAccordionItem,
package/package.json CHANGED
@@ -29,9 +29,9 @@
29
29
  "peerDependencies": {
30
30
  "@angular/core": "^17.3.0 || ^18.0.0 || ^19.0.0 || ^20.0.0 || ^21.0.0 || ^22.0.0",
31
31
  "@angular/forms": "^17.3.0 || ^18.0.0 || ^19.0.0 || ^20.0.0 || ^21.0.0 || ^22.0.0",
32
- "@luzmo/lucero": "2.5.0"
32
+ "@luzmo/lucero": "2.5.1"
33
33
  },
34
- "version": "2.5.0",
34
+ "version": "2.5.1",
35
35
  "peerDependenciesMeta": {
36
36
  "@angular/forms": {
37
37
  "optional": true