orbiq-neural-ui-kit 0.0.4 → 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { input, output, computed, Component, signal, model, effect, ViewChild, Directive, EventEmitter, ContentChild, Output, HostListener, Input, InjectionToken, Optional, Inject, ContentChildren, ViewChildren, inject, Injectable, ViewContainerRef, ElementRef } from '@angular/core';
2
+ import { input, computed, Component, output, signal, model, effect, ViewChild, Directive, EventEmitter, ContentChild, Output, HostListener, Input, InjectionToken, Optional, Inject, ContentChildren, ViewChildren, inject, forwardRef, Injectable, ViewContainerRef, ElementRef } from '@angular/core';
3
3
  import * as i1 from '@angular/common';
4
4
  import { CommonModule } from '@angular/common';
5
5
  import * as i1$1 from '@angular/cdk/overlay';
@@ -20,6 +20,58 @@ import { Editor } from '@tiptap/core';
20
20
  import StarterKit from '@tiptap/starter-kit';
21
21
  import { Placeholder } from '@tiptap/extensions';
22
22
 
23
+ class NeuralIconComponent {
24
+ name = input.required(/* @ts-ignore */
25
+ ...(ngDevMode ? [{ debugName: "name" }] : /* istanbul ignore next */ []));
26
+ isLucideIcon = computed(() => {
27
+ const val = this.name();
28
+ return typeof val === 'string' && val.startsWith('lucide-');
29
+ }, /* @ts-ignore */
30
+ ...(ngDevMode ? [{ debugName: "isLucideIcon" }] : /* istanbul ignore next */ []));
31
+ isEmojiIcon = computed(() => {
32
+ const val = this.name();
33
+ if (typeof val !== 'string')
34
+ return false;
35
+ // Very simple emoji detection
36
+ const emojiRegex = /[\p{Emoji_Presentation}\p{Extended_Pictographic}]/u;
37
+ return emojiRegex.test(val);
38
+ }, /* @ts-ignore */
39
+ ...(ngDevMode ? [{ debugName: "isEmojiIcon" }] : /* istanbul ignore next */ []));
40
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: NeuralIconComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
41
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: NeuralIconComponent, isStandalone: true, selector: "neural-icon", inputs: { name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
42
+ @if (isLucideIcon()) {
43
+ <span [class]="name()" aria-hidden="true"></span>
44
+ } @else if (isEmojiIcon()) {
45
+ <span class="inline-flex items-center justify-center leading-none" aria-hidden="true">
46
+ {{ name() }}
47
+ </span>
48
+ } @else {
49
+ <!-- Fallback or custom SVG component handled by ng-content if not string -->
50
+ <ng-content></ng-content>
51
+ }
52
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }] });
53
+ }
54
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: NeuralIconComponent, decorators: [{
55
+ type: Component,
56
+ args: [{
57
+ selector: 'neural-icon',
58
+ standalone: true,
59
+ imports: [CommonModule],
60
+ template: `
61
+ @if (isLucideIcon()) {
62
+ <span [class]="name()" aria-hidden="true"></span>
63
+ } @else if (isEmojiIcon()) {
64
+ <span class="inline-flex items-center justify-center leading-none" aria-hidden="true">
65
+ {{ name() }}
66
+ </span>
67
+ } @else {
68
+ <!-- Fallback or custom SVG component handled by ng-content if not string -->
69
+ <ng-content></ng-content>
70
+ }
71
+ `
72
+ }]
73
+ }], propDecorators: { name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: true }] }] } });
74
+
23
75
  class NeuralButtonComponent {
24
76
  // Inputs
25
77
  variant = input('subtle', /* @ts-ignore */
@@ -35,6 +87,8 @@ class NeuralButtonComponent {
35
87
  loading = input(false, /* @ts-ignore */
36
88
  ...(ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []));
37
89
  // Modifiers
90
+ icon = input(/* @ts-ignore */
91
+ ...(ngDevMode ? [undefined, { debugName: "icon" }] : /* istanbul ignore next */ []));
38
92
  iconLeft = input(false, /* @ts-ignore */
39
93
  ...(ngDevMode ? [{ debugName: "iconLeft" }] : /* istanbul ignore next */ []));
40
94
  iconRight = input(false, /* @ts-ignore */
@@ -59,6 +113,10 @@ class NeuralButtonComponent {
59
113
  }[this.size()];
60
114
  }, /* @ts-ignore */
61
115
  ...(ngDevMode ? [{ debugName: "spinnerClasses" }] : /* istanbul ignore next */ []));
116
+ iconClasses = computed(() => {
117
+ return this.spinnerClasses();
118
+ }, /* @ts-ignore */
119
+ ...(ngDevMode ? [{ debugName: "iconClasses" }] : /* istanbul ignore next */ []));
62
120
  computedClasses = computed(() => {
63
121
  const v = this.variant();
64
122
  const t = this.theme();
@@ -143,7 +201,7 @@ class NeuralButtonComponent {
143
201
  }, /* @ts-ignore */
144
202
  ...(ngDevMode ? [{ debugName: "computedClasses" }] : /* istanbul ignore next */ []));
145
203
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: NeuralButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
146
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: NeuralButtonComponent, isStandalone: true, selector: "neural-button", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, theme: { classPropertyName: "theme", publicName: "theme", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, iconLeft: { classPropertyName: "iconLeft", publicName: "iconLeft", isSignal: true, isRequired: false, transformFunction: null }, iconRight: { classPropertyName: "iconRight", publicName: "iconRight", isSignal: true, isRequired: false, transformFunction: null }, iconOnly: { classPropertyName: "iconOnly", publicName: "iconOnly", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { clicked: "clicked" }, ngImport: i0, template: `
204
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: NeuralButtonComponent, isStandalone: true, selector: "neural-button", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, theme: { classPropertyName: "theme", publicName: "theme", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, iconLeft: { classPropertyName: "iconLeft", publicName: "iconLeft", isSignal: true, isRequired: false, transformFunction: null }, iconRight: { classPropertyName: "iconRight", publicName: "iconRight", isSignal: true, isRequired: false, transformFunction: null }, iconOnly: { classPropertyName: "iconOnly", publicName: "iconOnly", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { clicked: "clicked" }, ngImport: i0, template: `
147
205
  <button
148
206
  [type]="type()"
149
207
  [disabled]="isDisabled()"
@@ -156,26 +214,36 @@ class NeuralButtonComponent {
156
214
  <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
157
215
  <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
158
216
  </svg>
159
- } @else if (iconLeft()) {
160
- <ng-content select="[left-icon]"></ng-content>
217
+ } @else if (iconLeft() || (icon() && !iconRight() && !iconOnly())) {
218
+ @if (icon()) {
219
+ <neural-icon [name]="icon()!" [class]="iconClasses()"></neural-icon>
220
+ } @else {
221
+ <ng-content select="[left-icon]"></ng-content>
222
+ }
223
+ } @else if (iconOnly() && icon()) {
224
+ <neural-icon [name]="icon()!" [class]="iconClasses()"></neural-icon>
161
225
  }
162
226
 
163
227
  <span class="truncate" [class.sr-only]="iconOnly()">
164
228
  <ng-content></ng-content>
165
229
  </span>
166
230
 
167
- @if (!loading() && iconRight()) {
168
- <ng-content select="[right-icon]"></ng-content>
231
+ @if (!loading() && (iconRight() || (icon() && iconRight() && !iconOnly()))) {
232
+ @if (icon()) {
233
+ <neural-icon [name]="icon()!" [class]="iconClasses()"></neural-icon>
234
+ } @else {
235
+ <ng-content select="[right-icon]"></ng-content>
236
+ }
169
237
  }
170
238
  </button>
171
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }] });
239
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: NeuralIconComponent, selector: "neural-icon", inputs: ["name"] }] });
172
240
  }
173
241
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: NeuralButtonComponent, decorators: [{
174
242
  type: Component,
175
243
  args: [{
176
244
  selector: 'neural-button',
177
245
  standalone: true,
178
- imports: [CommonModule],
246
+ imports: [CommonModule, NeuralIconComponent],
179
247
  template: `
180
248
  <button
181
249
  [type]="type()"
@@ -189,21 +257,31 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
189
257
  <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
190
258
  <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
191
259
  </svg>
192
- } @else if (iconLeft()) {
193
- <ng-content select="[left-icon]"></ng-content>
260
+ } @else if (iconLeft() || (icon() && !iconRight() && !iconOnly())) {
261
+ @if (icon()) {
262
+ <neural-icon [name]="icon()!" [class]="iconClasses()"></neural-icon>
263
+ } @else {
264
+ <ng-content select="[left-icon]"></ng-content>
265
+ }
266
+ } @else if (iconOnly() && icon()) {
267
+ <neural-icon [name]="icon()!" [class]="iconClasses()"></neural-icon>
194
268
  }
195
269
 
196
270
  <span class="truncate" [class.sr-only]="iconOnly()">
197
271
  <ng-content></ng-content>
198
272
  </span>
199
273
 
200
- @if (!loading() && iconRight()) {
201
- <ng-content select="[right-icon]"></ng-content>
274
+ @if (!loading() && (iconRight() || (icon() && iconRight() && !iconOnly()))) {
275
+ @if (icon()) {
276
+ <neural-icon [name]="icon()!" [class]="iconClasses()"></neural-icon>
277
+ } @else {
278
+ <ng-content select="[right-icon]"></ng-content>
279
+ }
202
280
  }
203
281
  </button>
204
282
  `
205
283
  }]
206
- }], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], theme: [{ type: i0.Input, args: [{ isSignal: true, alias: "theme", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], iconLeft: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconLeft", required: false }] }], iconRight: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconRight", required: false }] }], iconOnly: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconOnly", required: false }] }], clicked: [{ type: i0.Output, args: ["clicked"] }] } });
284
+ }], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], theme: [{ type: i0.Input, args: [{ isSignal: true, alias: "theme", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], iconLeft: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconLeft", required: false }] }], iconRight: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconRight", required: false }] }], iconOnly: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconOnly", required: false }] }], clicked: [{ type: i0.Output, args: ["clicked"] }] } });
207
285
 
208
286
  class NeuralAlertComponent {
209
287
  title = input(/* @ts-ignore */
@@ -479,7 +557,7 @@ class NeuralAlertComponent {
479
557
  <svg [class]="iconColorClass()" class="size-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 16 16"><path d="M8 1C11.866 1 15 4.13401 15 8C15 11.866 11.866 15 8 15C4.13401 15 1 11.866 1 8C1 4.13401 4.13401 1 8 1ZM10.8535 5.14648C10.6583 4.95122 10.3417 4.95122 10.1465 5.14648L8 7.29297L5.85352 5.14648C5.65825 4.95122 5.34175 4.95122 5.14648 5.14648C4.95122 5.34175 4.95122 5.65825 5.14648 5.85352L7.29297 8L5.14648 10.1465C4.95122 10.3417 4.95122 10.6583 5.14648 10.8535C5.34175 11.0488 5.65825 11.0488 5.85352 10.8535L8 8.70703L10.1465 10.8535C10.3417 11.0488 10.6583 11.0488 10.8535 10.8535C11.0488 10.6583 11.0488 10.3417 10.8535 10.1465L8.70703 8L10.8535 5.85352C11.0488 5.65825 11.0488 5.34175 10.8535 5.14648Z" fill="currentColor"/></svg>
480
558
  }
481
559
  </ng-template>
482
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: NeuralButtonComponent, selector: "neural-button", inputs: ["variant", "theme", "size", "type", "disabled", "loading", "iconLeft", "iconRight", "iconOnly"], outputs: ["clicked"] }] });
560
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: NeuralButtonComponent, selector: "neural-button", inputs: ["variant", "theme", "size", "type", "disabled", "loading", "icon", "iconLeft", "iconRight", "iconOnly"], outputs: ["clicked"] }] });
483
561
  }
484
562
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: NeuralAlertComponent, decorators: [{
485
563
  type: Component,
@@ -1821,7 +1899,7 @@ class NeuralDropdownComponent {
1821
1899
  </neural-popover-panel>
1822
1900
  </ng-template>
1823
1901
  </neural-popover>
1824
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i1$2.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "browserUrl", "routerLink"] }, { kind: "component", type: NeuralPopoverComponent, selector: "neural-popover", inputs: ["side", "align", "offset", "bare"], outputs: ["openChange"] }, { kind: "directive", type: NeuralPopoverTriggerDirective, selector: "[neuralPopoverTrigger]" }, { kind: "directive", type: NeuralPopoverContentDirective, selector: "[neuralPopoverContent]" }, { kind: "component", type: NeuralPopoverPanelComponent, selector: "neural-popover-panel" }, { kind: "component", type: NeuralButtonComponent, selector: "neural-button", inputs: ["variant", "theme", "size", "type", "disabled", "loading", "iconLeft", "iconRight", "iconOnly"], outputs: ["clicked"] }] });
1902
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i1$2.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "browserUrl", "routerLink"] }, { kind: "component", type: NeuralPopoverComponent, selector: "neural-popover", inputs: ["side", "align", "offset", "bare"], outputs: ["openChange"] }, { kind: "directive", type: NeuralPopoverTriggerDirective, selector: "[neuralPopoverTrigger]" }, { kind: "directive", type: NeuralPopoverContentDirective, selector: "[neuralPopoverContent]" }, { kind: "component", type: NeuralPopoverPanelComponent, selector: "neural-popover-panel" }, { kind: "component", type: NeuralButtonComponent, selector: "neural-button", inputs: ["variant", "theme", "size", "type", "disabled", "loading", "icon", "iconLeft", "iconRight", "iconOnly"], outputs: ["clicked"] }] });
1825
1903
  }
1826
1904
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: NeuralDropdownComponent, decorators: [{
1827
1905
  type: Component,
@@ -2013,7 +2091,7 @@ class NeuralBreadcrumbsComponent {
2013
2091
  }
2014
2092
  </div>
2015
2093
  </div>
2016
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i1$2.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "browserUrl", "routerLink"] }, { kind: "component", type: NeuralDropdownComponent, selector: "neural-dropdown", inputs: ["options", "side", "align", "offset", "buttonLabel", "hasTriggerSlot"] }, { kind: "component", type: NeuralButtonComponent, selector: "neural-button", inputs: ["variant", "theme", "size", "type", "disabled", "loading", "iconLeft", "iconRight", "iconOnly"], outputs: ["clicked"] }] });
2094
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i1$2.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "browserUrl", "routerLink"] }, { kind: "component", type: NeuralDropdownComponent, selector: "neural-dropdown", inputs: ["options", "side", "align", "offset", "buttonLabel", "hasTriggerSlot"] }, { kind: "component", type: NeuralButtonComponent, selector: "neural-button", inputs: ["variant", "theme", "size", "type", "disabled", "loading", "icon", "iconLeft", "iconRight", "iconOnly"], outputs: ["clicked"] }] });
2017
2095
  }
2018
2096
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: NeuralBreadcrumbsComponent, decorators: [{
2019
2097
  type: Component,
@@ -3695,58 +3773,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
3695
3773
  }]
3696
3774
  }], propDecorators: { valueModel: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueModel", required: false }] }, { type: i0.Output, args: ["valueModelChange"] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], padded: [{ type: i0.Input, args: [{ isSignal: true, alias: "padded", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], controlPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "controlPosition", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], hasLabelSlot: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasLabelSlot", required: false }] }], hasDescriptionSlot: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasDescriptionSlot", required: false }] }] } });
3697
3775
 
3698
- class NeuralIconComponent {
3699
- name = input.required(/* @ts-ignore */
3700
- ...(ngDevMode ? [{ debugName: "name" }] : /* istanbul ignore next */ []));
3701
- isLucideIcon = computed(() => {
3702
- const val = this.name();
3703
- return typeof val === 'string' && val.startsWith('lucide-');
3704
- }, /* @ts-ignore */
3705
- ...(ngDevMode ? [{ debugName: "isLucideIcon" }] : /* istanbul ignore next */ []));
3706
- isEmojiIcon = computed(() => {
3707
- const val = this.name();
3708
- if (typeof val !== 'string')
3709
- return false;
3710
- // Very simple emoji detection
3711
- const emojiRegex = /[\p{Emoji_Presentation}\p{Extended_Pictographic}]/u;
3712
- return emojiRegex.test(val);
3713
- }, /* @ts-ignore */
3714
- ...(ngDevMode ? [{ debugName: "isEmojiIcon" }] : /* istanbul ignore next */ []));
3715
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: NeuralIconComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3716
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: NeuralIconComponent, isStandalone: true, selector: "neural-icon", inputs: { name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
3717
- @if (isLucideIcon()) {
3718
- <span [class]="name()" aria-hidden="true"></span>
3719
- } @else if (isEmojiIcon()) {
3720
- <span class="inline-flex items-center justify-center leading-none" aria-hidden="true">
3721
- {{ name() }}
3722
- </span>
3723
- } @else {
3724
- <!-- Fallback or custom SVG component handled by ng-content if not string -->
3725
- <ng-content></ng-content>
3726
- }
3727
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }] });
3728
- }
3729
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: NeuralIconComponent, decorators: [{
3730
- type: Component,
3731
- args: [{
3732
- selector: 'neural-icon',
3733
- standalone: true,
3734
- imports: [CommonModule],
3735
- template: `
3736
- @if (isLucideIcon()) {
3737
- <span [class]="name()" aria-hidden="true"></span>
3738
- } @else if (isEmojiIcon()) {
3739
- <span class="inline-flex items-center justify-center leading-none" aria-hidden="true">
3740
- {{ name() }}
3741
- </span>
3742
- } @else {
3743
- <!-- Fallback or custom SVG component handled by ng-content if not string -->
3744
- <ng-content></ng-content>
3745
- }
3746
- `
3747
- }]
3748
- }], propDecorators: { name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: true }] }] } });
3749
-
3750
3776
  class NeuralSpinnerComponent {
3751
3777
  size = input(/* @ts-ignore */
3752
3778
  ...(ngDevMode ? [undefined, { debugName: "size" }] : /* istanbul ignore next */ []));
@@ -3921,7 +3947,7 @@ class NeuralDividerComponent {
3921
3947
  } @else {
3922
3948
  <hr class="border-0 border-outline-gray-2" [class]="dividerClasses()" />
3923
3949
  }
3924
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: NeuralButtonComponent, selector: "neural-button", inputs: ["variant", "theme", "size", "type", "disabled", "loading", "iconLeft", "iconRight", "iconOnly"], outputs: ["clicked"] }] });
3950
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: NeuralButtonComponent, selector: "neural-button", inputs: ["variant", "theme", "size", "type", "disabled", "loading", "icon", "iconLeft", "iconRight", "iconOnly"], outputs: ["clicked"] }] });
3925
3951
  }
3926
3952
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: NeuralDividerComponent, decorators: [{
3927
3953
  type: Component,
@@ -4433,7 +4459,7 @@ class NeuralDialogComponent {
4433
4459
  </div>
4434
4460
  </div>
4435
4461
  </ng-template>
4436
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: DialogModule }, { kind: "component", type: NeuralButtonComponent, selector: "neural-button", inputs: ["variant", "theme", "size", "type", "disabled", "loading", "iconLeft", "iconRight", "iconOnly"], outputs: ["clicked"] }] });
4462
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: DialogModule }, { kind: "component", type: NeuralButtonComponent, selector: "neural-button", inputs: ["variant", "theme", "size", "type", "disabled", "loading", "icon", "iconLeft", "iconRight", "iconOnly"], outputs: ["clicked"] }] });
4437
4463
  }
4438
4464
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: NeuralDialogComponent, decorators: [{
4439
4465
  type: Component,
@@ -5908,106 +5934,129 @@ class NeuralSidebarItemComponent {
5908
5934
  ...(ngDevMode ? [{ debugName: "active" }] : /* istanbul ignore next */ []));
5909
5935
  suffix = input('', /* @ts-ignore */
5910
5936
  ...(ngDevMode ? [{ debugName: "suffix" }] : /* istanbul ignore next */ []));
5937
+ children = input([], /* @ts-ignore */
5938
+ ...(ngDevMode ? [{ debugName: "children" }] : /* istanbul ignore next */ []));
5911
5939
  hasPrefixSlot = input(false, /* @ts-ignore */
5912
5940
  ...(ngDevMode ? [{ debugName: "hasPrefixSlot" }] : /* istanbul ignore next */ []));
5913
5941
  hasDefaultSlot = input(false, /* @ts-ignore */
5914
5942
  ...(ngDevMode ? [{ debugName: "hasDefaultSlot" }] : /* istanbul ignore next */ []));
5915
5943
  hasSuffixSlot = input(false, /* @ts-ignore */
5916
5944
  ...(ngDevMode ? [{ debugName: "hasSuffixSlot" }] : /* istanbul ignore next */ []));
5945
+ isExpanded = signal(false, /* @ts-ignore */
5946
+ ...(ngDevMode ? [{ debugName: "isExpanded" }] : /* istanbul ignore next */ []));
5917
5947
  router = inject(Router, { optional: true });
5918
5948
  sidebar = inject(NeuralSidebarComponent, { optional: true });
5919
5949
  isCollapsed = computed(() => {
5920
5950
  return this.sidebar ? this.sidebar.shouldCollapse() : false;
5921
5951
  }, /* @ts-ignore */
5922
5952
  ...(ngDevMode ? [{ debugName: "isCollapsed" }] : /* istanbul ignore next */ []));
5953
+ hasChildren = computed(() => {
5954
+ return this.children() && this.children().length > 0;
5955
+ }, /* @ts-ignore */
5956
+ ...(ngDevMode ? [{ debugName: "hasChildren" }] : /* istanbul ignore next */ []));
5923
5957
  tooltipText = computed(() => this.label(), /* @ts-ignore */
5924
5958
  ...(ngDevMode ? [{ debugName: "tooltipText" }] : /* istanbul ignore next */ []));
5925
5959
  resolvedActive = computed(() => {
5926
5960
  if (this.active() !== undefined)
5927
5961
  return this.active();
5962
+ // Check if any child is active
5963
+ if (this.hasChildren()) {
5964
+ return this.children().some(child => {
5965
+ if (child.active)
5966
+ return true;
5967
+ if (child.to && this.router) {
5968
+ return this.router.isActive(child.to, { paths: 'exact', queryParams: 'ignored', fragment: 'ignored', matrixParams: 'ignored' });
5969
+ }
5970
+ return false;
5971
+ });
5972
+ }
5928
5973
  if (!this.to() || !this.router)
5929
5974
  return false;
5930
5975
  return this.router.isActive(this.to(), { paths: 'exact', queryParams: 'ignored', fragment: 'ignored', matrixParams: 'ignored' });
5931
5976
  }, /* @ts-ignore */
5932
5977
  ...(ngDevMode ? [{ debugName: "resolvedActive" }] : /* istanbul ignore next */ []));
5933
5978
  handleClick(event) {
5934
- // optional click handler
5979
+ if (this.hasChildren()) {
5980
+ event.preventDefault();
5981
+ this.isExpanded.set(!this.isExpanded());
5982
+ }
5935
5983
  }
5936
5984
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: NeuralSidebarItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
5937
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: NeuralSidebarItemComponent, isStandalone: true, selector: "neural-sidebar-item", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, to: { classPropertyName: "to", publicName: "to", isSignal: true, isRequired: false, transformFunction: null }, active: { classPropertyName: "active", publicName: "active", isSignal: true, isRequired: false, transformFunction: null }, suffix: { classPropertyName: "suffix", publicName: "suffix", isSignal: true, isRequired: false, transformFunction: null }, hasPrefixSlot: { classPropertyName: "hasPrefixSlot", publicName: "hasPrefixSlot", isSignal: true, isRequired: false, transformFunction: null }, hasDefaultSlot: { classPropertyName: "hasDefaultSlot", publicName: "hasDefaultSlot", isSignal: true, isRequired: false, transformFunction: null }, hasSuffixSlot: { classPropertyName: "hasSuffixSlot", publicName: "hasSuffixSlot", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
5938
- <div
5939
- data-slot="sidebar-item"
5940
- [attr.data-state]="resolvedActive() ? 'active' : 'inactive'"
5941
- class="group/sidebar-item flex h-7 items-center rounded-4 transition"
5942
- [class]="
5943
- resolvedActive()
5944
- ? 'bg-surface-elevation-3 text-ink-gray-8 shadow-sm'
5945
- : 'text-ink-gray-6 hover:bg-surface-gray-2'
5946
- "
5947
- >
5948
- @if (to()) {
5949
- <a
5950
- [routerLink]="to()"
5951
- routerLinkActive="active"
5952
- #rla="routerLinkActive"
5953
- [attr.aria-label]="tooltipText() || undefined"
5954
- [attr.aria-current]="resolvedActive() ? 'page' : undefined"
5955
- class="flex h-full min-w-0 flex-1 items-center rounded-4 pl-2 focus-visible:ring-0 focus-visible:focus-ring"
5956
- (click)="handleClick($event)"
5957
- >
5958
- <span class="grid shrink-0 place-items-center">
5959
- <ng-content select="[prefix]"></ng-content>
5960
- @if (!hasPrefixSlot() && icon()) {
5961
- <span [class]="icon() + ' size-4'"></span>
5962
- }
5963
- </span>
5964
- <span
5965
- class="min-w-0 flex-1 transition-all ease-in-out"
5966
- [class]="
5967
- isCollapsed()
5968
- ? 'ml-0 w-0 overflow-hidden opacity-0'
5969
- : 'ml-2 w-auto opacity-100'
5970
- "
5985
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: NeuralSidebarItemComponent, isStandalone: true, selector: "neural-sidebar-item", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, to: { classPropertyName: "to", publicName: "to", isSignal: true, isRequired: false, transformFunction: null }, active: { classPropertyName: "active", publicName: "active", isSignal: true, isRequired: false, transformFunction: null }, suffix: { classPropertyName: "suffix", publicName: "suffix", isSignal: true, isRequired: false, transformFunction: null }, children: { classPropertyName: "children", publicName: "children", isSignal: true, isRequired: false, transformFunction: null }, hasPrefixSlot: { classPropertyName: "hasPrefixSlot", publicName: "hasPrefixSlot", isSignal: true, isRequired: false, transformFunction: null }, hasDefaultSlot: { classPropertyName: "hasDefaultSlot", publicName: "hasDefaultSlot", isSignal: true, isRequired: false, transformFunction: null }, hasSuffixSlot: { classPropertyName: "hasSuffixSlot", publicName: "hasSuffixSlot", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
5986
+ <div class="flex flex-col">
5987
+ <div
5988
+ data-slot="sidebar-item"
5989
+ [attr.data-state]="resolvedActive() ? 'active' : 'inactive'"
5990
+ class="group/sidebar-item flex h-8 items-center rounded-4 transition-colors cursor-pointer"
5991
+ [class]="
5992
+ resolvedActive()
5993
+ ? 'bg-surface-gray-3 text-ink-gray-9 font-medium'
5994
+ : 'text-ink-gray-7 hover:bg-surface-gray-2'
5995
+ "
5996
+ >
5997
+ @if (to() && !hasChildren()) {
5998
+ <a
5999
+ [routerLink]="to()"
6000
+ routerLinkActive="active"
6001
+ #rla="routerLinkActive"
6002
+ [attr.aria-label]="tooltipText() || undefined"
6003
+ [attr.aria-current]="resolvedActive() ? 'page' : undefined"
6004
+ class="flex h-full min-w-0 flex-1 items-center rounded-4 pl-2 focus-visible:ring-0 focus-visible:focus-ring"
6005
+ (click)="handleClick($event)"
5971
6006
  >
5972
- <span class="flex min-w-0 items-center">
5973
- <ng-content></ng-content>
5974
- @if (!hasDefaultSlot() && label()) {
5975
- <span class="truncate text-sm">{{ label() }}</span>
5976
- }
5977
- </span>
5978
- </span>
5979
- </a>
5980
- } @else {
5981
- <button
5982
- type="button"
5983
- [attr.aria-label]="tooltipText() || undefined"
5984
- class="flex h-full text-left min-w-0 flex-1 items-center rounded-4 pl-2 focus-visible:ring-0 focus-visible:focus-ring"
5985
- (click)="handleClick($event)"
5986
- >
5987
- <span class="grid shrink-0 place-items-center">
5988
- <ng-content select="[prefix]"></ng-content>
5989
- @if (!hasPrefixSlot() && icon()) {
5990
- <span [class]="icon() + ' size-4'"></span>
5991
- }
5992
- </span>
5993
- <span
5994
- class="min-w-0 flex-1 transition-all ease-in-out"
5995
- [class]="
5996
- isCollapsed()
5997
- ? 'ml-0 w-0 overflow-hidden opacity-0'
5998
- : 'ml-2 w-auto opacity-100'
5999
- "
6007
+ <ng-container *ngTemplateOutlet="itemContent"></ng-container>
6008
+ </a>
6009
+ } @else {
6010
+ <button
6011
+ type="button"
6012
+ [attr.aria-label]="tooltipText() || undefined"
6013
+ class="flex h-full text-left min-w-0 flex-1 items-center rounded-4 pl-2 focus-visible:ring-0 focus-visible:focus-ring"
6014
+ (click)="handleClick($event)"
6000
6015
  >
6001
- <span class="flex min-w-0 items-center">
6002
- <ng-content></ng-content>
6003
- @if (!hasDefaultSlot() && label()) {
6004
- <span class="truncate text-sm">{{ label() }}</span>
6005
- }
6006
- </span>
6007
- </span>
6008
- </button>
6016
+ <ng-container *ngTemplateOutlet="itemContent"></ng-container>
6017
+ </button>
6018
+ }
6019
+ </div>
6020
+
6021
+ <!-- Nested Children -->
6022
+ @if (hasChildren() && !isCollapsed() && isExpanded()) {
6023
+ <div class="flex flex-col pl-6 mt-0.5 space-y-0.5">
6024
+ @for (child of children(); track child.label) {
6025
+ <neural-sidebar-item
6026
+ [label]="child.label"
6027
+ [icon]="child.icon || ''"
6028
+ [to]="child.to"
6029
+ [active]="child.active"
6030
+ [children]="child.children || []">
6031
+ </neural-sidebar-item>
6032
+ }
6033
+ </div>
6009
6034
  }
6010
-
6035
+ </div>
6036
+
6037
+ <!-- Content Template to avoid duplication -->
6038
+ <ng-template #itemContent>
6039
+ <span class="grid shrink-0 place-items-center">
6040
+ <ng-content select="[prefix]"></ng-content>
6041
+ @if (!hasPrefixSlot() && icon()) {
6042
+ <span [class]="icon() + ' size-4.5'"></span>
6043
+ }
6044
+ </span>
6045
+ <span
6046
+ class="min-w-0 flex-1 transition-all ease-in-out"
6047
+ [class]="
6048
+ isCollapsed()
6049
+ ? 'ml-0 w-0 overflow-hidden opacity-0'
6050
+ : 'ml-2 w-auto opacity-100'
6051
+ "
6052
+ >
6053
+ <span class="flex min-w-0 items-center">
6054
+ <ng-content></ng-content>
6055
+ @if (!hasDefaultSlot() && label()) {
6056
+ <span class="truncate text-[13px] tracking-wide">{{ label() }}</span>
6057
+ }
6058
+ </span>
6059
+ </span>
6011
6060
  <div
6012
6061
  data-slot="sidebar-item-suffix"
6013
6062
  class="flex shrink-0 items-center transition-all ease-in-out"
@@ -6015,92 +6064,98 @@ class NeuralSidebarItemComponent {
6015
6064
  >
6016
6065
  <ng-content select="[suffix]"></ng-content>
6017
6066
  @if (!hasSuffixSlot() && suffix()) {
6018
- <span class="mr-2 text-sm text-ink-gray-4">{{ suffix() }}</span>
6067
+ <span class="mr-2 text-xs text-ink-gray-4">{{ suffix() }}</span>
6068
+ }
6069
+ @if (hasChildren()) {
6070
+ <span class="mr-2 transition-transform duration-200" [class.rotate-90]="isExpanded()">
6071
+ <span class="lucide-chevron-right size-3.5 text-ink-gray-4 group-hover/sidebar-item:text-ink-gray-6"></span>
6072
+ </span>
6019
6073
  }
6020
6074
  </div>
6021
- </div>
6022
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i1$2.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "browserUrl", "routerLink"] }, { kind: "directive", type: i1$2.RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }] });
6075
+ </ng-template>
6076
+ `, isInline: true, dependencies: [{ kind: "component", type: i0.forwardRef(() => NeuralSidebarItemComponent), selector: "neural-sidebar-item", inputs: ["label", "icon", "to", "active", "suffix", "children", "hasPrefixSlot", "hasDefaultSlot", "hasSuffixSlot"] }, { kind: "ngmodule", type: i0.forwardRef(() => CommonModule) }, { kind: "directive", type: i0.forwardRef(() => i1.NgTemplateOutlet), selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: i0.forwardRef(() => RouterModule) }, { kind: "directive", type: i0.forwardRef(() => i1$2.RouterLink), selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "browserUrl", "routerLink"] }, { kind: "directive", type: i0.forwardRef(() => i1$2.RouterLinkActive), selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }] });
6023
6077
  }
6024
6078
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: NeuralSidebarItemComponent, decorators: [{
6025
6079
  type: Component,
6026
6080
  args: [{
6027
6081
  selector: 'neural-sidebar-item',
6028
6082
  standalone: true,
6029
- imports: [CommonModule, RouterModule],
6083
+ imports: [CommonModule, RouterModule, forwardRef(() => NeuralSidebarItemComponent)],
6030
6084
  template: `
6031
- <div
6032
- data-slot="sidebar-item"
6033
- [attr.data-state]="resolvedActive() ? 'active' : 'inactive'"
6034
- class="group/sidebar-item flex h-7 items-center rounded-4 transition"
6035
- [class]="
6036
- resolvedActive()
6037
- ? 'bg-surface-elevation-3 text-ink-gray-8 shadow-sm'
6038
- : 'text-ink-gray-6 hover:bg-surface-gray-2'
6039
- "
6040
- >
6041
- @if (to()) {
6042
- <a
6043
- [routerLink]="to()"
6044
- routerLinkActive="active"
6045
- #rla="routerLinkActive"
6046
- [attr.aria-label]="tooltipText() || undefined"
6047
- [attr.aria-current]="resolvedActive() ? 'page' : undefined"
6048
- class="flex h-full min-w-0 flex-1 items-center rounded-4 pl-2 focus-visible:ring-0 focus-visible:focus-ring"
6049
- (click)="handleClick($event)"
6050
- >
6051
- <span class="grid shrink-0 place-items-center">
6052
- <ng-content select="[prefix]"></ng-content>
6053
- @if (!hasPrefixSlot() && icon()) {
6054
- <span [class]="icon() + ' size-4'"></span>
6055
- }
6056
- </span>
6057
- <span
6058
- class="min-w-0 flex-1 transition-all ease-in-out"
6059
- [class]="
6060
- isCollapsed()
6061
- ? 'ml-0 w-0 overflow-hidden opacity-0'
6062
- : 'ml-2 w-auto opacity-100'
6063
- "
6085
+ <div class="flex flex-col">
6086
+ <div
6087
+ data-slot="sidebar-item"
6088
+ [attr.data-state]="resolvedActive() ? 'active' : 'inactive'"
6089
+ class="group/sidebar-item flex h-8 items-center rounded-4 transition-colors cursor-pointer"
6090
+ [class]="
6091
+ resolvedActive()
6092
+ ? 'bg-surface-gray-3 text-ink-gray-9 font-medium'
6093
+ : 'text-ink-gray-7 hover:bg-surface-gray-2'
6094
+ "
6095
+ >
6096
+ @if (to() && !hasChildren()) {
6097
+ <a
6098
+ [routerLink]="to()"
6099
+ routerLinkActive="active"
6100
+ #rla="routerLinkActive"
6101
+ [attr.aria-label]="tooltipText() || undefined"
6102
+ [attr.aria-current]="resolvedActive() ? 'page' : undefined"
6103
+ class="flex h-full min-w-0 flex-1 items-center rounded-4 pl-2 focus-visible:ring-0 focus-visible:focus-ring"
6104
+ (click)="handleClick($event)"
6064
6105
  >
6065
- <span class="flex min-w-0 items-center">
6066
- <ng-content></ng-content>
6067
- @if (!hasDefaultSlot() && label()) {
6068
- <span class="truncate text-sm">{{ label() }}</span>
6069
- }
6070
- </span>
6071
- </span>
6072
- </a>
6073
- } @else {
6074
- <button
6075
- type="button"
6076
- [attr.aria-label]="tooltipText() || undefined"
6077
- class="flex h-full text-left min-w-0 flex-1 items-center rounded-4 pl-2 focus-visible:ring-0 focus-visible:focus-ring"
6078
- (click)="handleClick($event)"
6079
- >
6080
- <span class="grid shrink-0 place-items-center">
6081
- <ng-content select="[prefix]"></ng-content>
6082
- @if (!hasPrefixSlot() && icon()) {
6083
- <span [class]="icon() + ' size-4'"></span>
6084
- }
6085
- </span>
6086
- <span
6087
- class="min-w-0 flex-1 transition-all ease-in-out"
6088
- [class]="
6089
- isCollapsed()
6090
- ? 'ml-0 w-0 overflow-hidden opacity-0'
6091
- : 'ml-2 w-auto opacity-100'
6092
- "
6106
+ <ng-container *ngTemplateOutlet="itemContent"></ng-container>
6107
+ </a>
6108
+ } @else {
6109
+ <button
6110
+ type="button"
6111
+ [attr.aria-label]="tooltipText() || undefined"
6112
+ class="flex h-full text-left min-w-0 flex-1 items-center rounded-4 pl-2 focus-visible:ring-0 focus-visible:focus-ring"
6113
+ (click)="handleClick($event)"
6093
6114
  >
6094
- <span class="flex min-w-0 items-center">
6095
- <ng-content></ng-content>
6096
- @if (!hasDefaultSlot() && label()) {
6097
- <span class="truncate text-sm">{{ label() }}</span>
6098
- }
6099
- </span>
6100
- </span>
6101
- </button>
6115
+ <ng-container *ngTemplateOutlet="itemContent"></ng-container>
6116
+ </button>
6117
+ }
6118
+ </div>
6119
+
6120
+ <!-- Nested Children -->
6121
+ @if (hasChildren() && !isCollapsed() && isExpanded()) {
6122
+ <div class="flex flex-col pl-6 mt-0.5 space-y-0.5">
6123
+ @for (child of children(); track child.label) {
6124
+ <neural-sidebar-item
6125
+ [label]="child.label"
6126
+ [icon]="child.icon || ''"
6127
+ [to]="child.to"
6128
+ [active]="child.active"
6129
+ [children]="child.children || []">
6130
+ </neural-sidebar-item>
6131
+ }
6132
+ </div>
6102
6133
  }
6103
-
6134
+ </div>
6135
+
6136
+ <!-- Content Template to avoid duplication -->
6137
+ <ng-template #itemContent>
6138
+ <span class="grid shrink-0 place-items-center">
6139
+ <ng-content select="[prefix]"></ng-content>
6140
+ @if (!hasPrefixSlot() && icon()) {
6141
+ <span [class]="icon() + ' size-4.5'"></span>
6142
+ }
6143
+ </span>
6144
+ <span
6145
+ class="min-w-0 flex-1 transition-all ease-in-out"
6146
+ [class]="
6147
+ isCollapsed()
6148
+ ? 'ml-0 w-0 overflow-hidden opacity-0'
6149
+ : 'ml-2 w-auto opacity-100'
6150
+ "
6151
+ >
6152
+ <span class="flex min-w-0 items-center">
6153
+ <ng-content></ng-content>
6154
+ @if (!hasDefaultSlot() && label()) {
6155
+ <span class="truncate text-[13px] tracking-wide">{{ label() }}</span>
6156
+ }
6157
+ </span>
6158
+ </span>
6104
6159
  <div
6105
6160
  data-slot="sidebar-item-suffix"
6106
6161
  class="flex shrink-0 items-center transition-all ease-in-out"
@@ -6108,13 +6163,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
6108
6163
  >
6109
6164
  <ng-content select="[suffix]"></ng-content>
6110
6165
  @if (!hasSuffixSlot() && suffix()) {
6111
- <span class="mr-2 text-sm text-ink-gray-4">{{ suffix() }}</span>
6166
+ <span class="mr-2 text-xs text-ink-gray-4">{{ suffix() }}</span>
6167
+ }
6168
+ @if (hasChildren()) {
6169
+ <span class="mr-2 transition-transform duration-200" [class.rotate-90]="isExpanded()">
6170
+ <span class="lucide-chevron-right size-3.5 text-ink-gray-4 group-hover/sidebar-item:text-ink-gray-6"></span>
6171
+ </span>
6112
6172
  }
6113
6173
  </div>
6114
- </div>
6174
+ </ng-template>
6115
6175
  `
6116
6176
  }]
6117
- }], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], to: [{ type: i0.Input, args: [{ isSignal: true, alias: "to", required: false }] }], active: [{ type: i0.Input, args: [{ isSignal: true, alias: "active", required: false }] }], suffix: [{ type: i0.Input, args: [{ isSignal: true, alias: "suffix", required: false }] }], hasPrefixSlot: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasPrefixSlot", required: false }] }], hasDefaultSlot: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasDefaultSlot", required: false }] }], hasSuffixSlot: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasSuffixSlot", required: false }] }] } });
6177
+ }], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], to: [{ type: i0.Input, args: [{ isSignal: true, alias: "to", required: false }] }], active: [{ type: i0.Input, args: [{ isSignal: true, alias: "active", required: false }] }], suffix: [{ type: i0.Input, args: [{ isSignal: true, alias: "suffix", required: false }] }], children: [{ type: i0.Input, args: [{ isSignal: true, alias: "children", required: false }] }], hasPrefixSlot: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasPrefixSlot", required: false }] }], hasDefaultSlot: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasDefaultSlot", required: false }] }], hasSuffixSlot: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasSuffixSlot", required: false }] }] } });
6118
6178
 
6119
6179
  class ToastService {
6120
6180
  overlay;
@@ -7358,7 +7418,7 @@ class NeuralFileUploaderComponent {
7358
7418
  </div>
7359
7419
  }
7360
7420
  </div>
7361
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: NeuralButtonComponent, selector: "neural-button", inputs: ["variant", "theme", "size", "type", "disabled", "loading", "iconLeft", "iconRight", "iconOnly"], outputs: ["clicked"] }, { kind: "component", type: NeuralErrorMessageComponent, selector: "neural-error-message", inputs: ["message"] }] });
7421
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: NeuralButtonComponent, selector: "neural-button", inputs: ["variant", "theme", "size", "type", "disabled", "loading", "icon", "iconLeft", "iconRight", "iconOnly"], outputs: ["clicked"] }, { kind: "component", type: NeuralErrorMessageComponent, selector: "neural-error-message", inputs: ["message"] }] });
7362
7422
  }
7363
7423
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: NeuralFileUploaderComponent, decorators: [{
7364
7424
  type: Component,
@@ -8779,13 +8839,34 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
8779
8839
  }] });
8780
8840
 
8781
8841
  class NeuralPageHeaderComponent {
8842
+ title = input('', /* @ts-ignore */
8843
+ ...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
8844
+ subtitle = input('', /* @ts-ignore */
8845
+ ...(ngDevMode ? [{ debugName: "subtitle" }] : /* istanbul ignore next */ []));
8782
8846
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: NeuralPageHeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
8783
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.4", type: NeuralPageHeaderComponent, isStandalone: true, selector: "neural-page-header", ngImport: i0, template: `
8784
- <header
8785
- class="z-10 flex min-h-12 flex-col justify-center border-b border-outline-gray-2 bg-surface-base px-3 sm:px-5"
8786
- >
8847
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: NeuralPageHeaderComponent, isStandalone: true, selector: "neural-page-header", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, subtitle: { classPropertyName: "subtitle", publicName: "subtitle", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
8848
+ <header class="z-10 flex min-h-[56px] flex-col justify-center border-b border-outline-gray-2 bg-surface-base px-4 sm:px-6">
8787
8849
  <div class="flex items-center justify-between">
8788
- <ng-content></ng-content>
8850
+
8851
+ <!-- Left Side (Title & Slots) -->
8852
+ <div class="flex items-center gap-3">
8853
+ <ng-content select="[left]"></ng-content>
8854
+
8855
+ <div class="flex flex-col">
8856
+ @if (title()) {
8857
+ <h2 class="text-base font-semibold text-ink-gray-9 tracking-tight">{{ title() }}</h2>
8858
+ }
8859
+ @if (subtitle()) {
8860
+ <span class="text-xs text-ink-gray-5">{{ subtitle() }}</span>
8861
+ }
8862
+ </div>
8863
+ </div>
8864
+
8865
+ <!-- Right Side (Actions & Slots) -->
8866
+ <div class="flex items-center gap-2">
8867
+ <ng-content select="[right]"></ng-content>
8868
+ </div>
8869
+
8789
8870
  </div>
8790
8871
  </header>
8791
8872
  `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }] });
@@ -8797,16 +8878,33 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
8797
8878
  standalone: true,
8798
8879
  imports: [CommonModule],
8799
8880
  template: `
8800
- <header
8801
- class="z-10 flex min-h-12 flex-col justify-center border-b border-outline-gray-2 bg-surface-base px-3 sm:px-5"
8802
- >
8881
+ <header class="z-10 flex min-h-[56px] flex-col justify-center border-b border-outline-gray-2 bg-surface-base px-4 sm:px-6">
8803
8882
  <div class="flex items-center justify-between">
8804
- <ng-content></ng-content>
8883
+
8884
+ <!-- Left Side (Title & Slots) -->
8885
+ <div class="flex items-center gap-3">
8886
+ <ng-content select="[left]"></ng-content>
8887
+
8888
+ <div class="flex flex-col">
8889
+ @if (title()) {
8890
+ <h2 class="text-base font-semibold text-ink-gray-9 tracking-tight">{{ title() }}</h2>
8891
+ }
8892
+ @if (subtitle()) {
8893
+ <span class="text-xs text-ink-gray-5">{{ subtitle() }}</span>
8894
+ }
8895
+ </div>
8896
+ </div>
8897
+
8898
+ <!-- Right Side (Actions & Slots) -->
8899
+ <div class="flex items-center gap-2">
8900
+ <ng-content select="[right]"></ng-content>
8901
+ </div>
8902
+
8805
8903
  </div>
8806
8904
  </header>
8807
8905
  `
8808
8906
  }]
8809
- }] });
8907
+ }], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], subtitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "subtitle", required: false }] }] } });
8810
8908
 
8811
8909
  class NeuralRailComponent {
8812
8910
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: NeuralRailComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
@@ -12327,7 +12425,7 @@ class NeuralListViewComponent {
12327
12425
  @if (rows().length) {
12328
12426
  @for (row of rows(); track row[rowKey()]) {
12329
12427
  <div
12330
- class="flex border-b border-outline-gray-1 hover:bg-surface-gray-1 transition-colors duration-100 cursor-pointer"
12428
+ class="flex border-b border-outline-gray-1 hover:bg-surface-gray-2 transition-colors duration-100 cursor-pointer"
12331
12429
  [style.height.px]="resolvedOptions().rowHeight || 40"
12332
12430
  [class.bg-surface-gray-2]="isSelected(row)"
12333
12431
  (click)="onRowClick(row)"
@@ -12336,7 +12434,7 @@ class NeuralListViewComponent {
12336
12434
  <div class="flex w-9 shrink-0 items-center justify-center p-2">
12337
12435
  <input
12338
12436
  type="checkbox"
12339
- class="rounded border-outline-gray-3"
12437
+ class="form-checkbox"
12340
12438
  [checked]="isSelected(row)"
12341
12439
  (change)="$event.stopPropagation(); toggleRow(row)"
12342
12440
  />
@@ -12428,7 +12526,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
12428
12526
  @if (rows().length) {
12429
12527
  @for (row of rows(); track row[rowKey()]) {
12430
12528
  <div
12431
- class="flex border-b border-outline-gray-1 hover:bg-surface-gray-1 transition-colors duration-100 cursor-pointer"
12529
+ class="flex border-b border-outline-gray-1 hover:bg-surface-gray-2 transition-colors duration-100 cursor-pointer"
12432
12530
  [style.height.px]="resolvedOptions().rowHeight || 40"
12433
12531
  [class.bg-surface-gray-2]="isSelected(row)"
12434
12532
  (click)="onRowClick(row)"
@@ -12437,7 +12535,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
12437
12535
  <div class="flex w-9 shrink-0 items-center justify-center p-2">
12438
12536
  <input
12439
12537
  type="checkbox"
12440
- class="rounded border-outline-gray-3"
12538
+ class="form-checkbox"
12441
12539
  [checked]="isSelected(row)"
12442
12540
  (change)="$event.stopPropagation(); toggleRow(row)"
12443
12541
  />