@spartan-ng/cli 0.0.1-alpha.715 → 0.0.1-alpha.717

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/package.json +1 -1
  2. package/src/generators/migrate-module-imports/import-map.js +1 -1
  3. package/src/generators/ui/libs/alert-dialog/files/lib/hlm-alert-dialog-cancel.ts.template +1 -4
  4. package/src/generators/ui/libs/autocomplete/files/lib/hlm-autocomplete-search.ts.template +3 -15
  5. package/src/generators/ui/libs/autocomplete/files/lib/hlm-autocomplete.ts.template +3 -15
  6. package/src/generators/ui/libs/avatar/files/lib/hlm-avatar-fallback.ts.template +1 -1
  7. package/src/generators/ui/libs/avatar/files/lib/hlm-avatar-image.ts.template +1 -1
  8. package/src/generators/ui/libs/breadcrumb/files/index.ts.template +0 -5
  9. package/src/generators/ui/libs/calendar/files/lib/hlm-calendar-multi.ts.template +1 -0
  10. package/src/generators/ui/libs/calendar/files/lib/hlm-calendar-range.ts.template +1 -0
  11. package/src/generators/ui/libs/calendar/files/lib/hlm-calendar.ts.template +1 -0
  12. package/src/generators/ui/libs/combobox/files/lib/hlm-combobox-multiple.ts.template +3 -15
  13. package/src/generators/ui/libs/combobox/files/lib/hlm-combobox.ts.template +3 -15
  14. package/src/generators/ui/libs/command/files/lib/hlm-command-dialog.ts.template +2 -2
  15. package/src/generators/ui/libs/command/files/lib/hlm-command-empty.ts.template +1 -1
  16. package/src/generators/ui/libs/command/files/lib/hlm-command-group-label.ts.template +1 -1
  17. package/src/generators/ui/libs/command/files/lib/hlm-command-group.ts.template +1 -1
  18. package/src/generators/ui/libs/command/files/lib/hlm-command-input.ts.template +7 -6
  19. package/src/generators/ui/libs/command/files/lib/hlm-command-item.ts.template +1 -1
  20. package/src/generators/ui/libs/command/files/lib/hlm-command-list.ts.template +1 -1
  21. package/src/generators/ui/libs/command/files/lib/hlm-command-separator.ts.template +1 -1
  22. package/src/generators/ui/libs/command/files/lib/hlm-command-shortcut.ts.template +1 -1
  23. package/src/generators/ui/libs/command/files/lib/hlm-command.ts.template +1 -1
  24. package/src/generators/ui/libs/context-menu/files/lib/hlm-context-menu-trigger.ts.template +3 -0
  25. package/src/generators/ui/libs/date-picker/files/lib/hlm-date-picker-anchor.ts.template +5 -12
  26. package/src/generators/ui/libs/date-picker/files/lib/hlm-date-picker-multi.ts.template +2 -2
  27. package/src/generators/ui/libs/date-picker/files/lib/hlm-date-picker.ts.template +2 -3
  28. package/src/generators/ui/libs/date-picker/files/lib/hlm-date-range-picker.ts.template +2 -2
  29. package/src/generators/ui/libs/dialog/files/lib/hlm-dialog-close.ts.template +1 -1
  30. package/src/generators/ui/libs/dialog/files/lib/hlm-dialog-content.ts.template +8 -1
  31. package/src/generators/ui/libs/drawer/files/lib/hlm-drawer-close.ts.template +1 -1
  32. package/src/generators/ui/libs/dropdown-menu/files/index.ts.template +3 -0
  33. package/src/generators/ui/libs/dropdown-menu/files/lib/hlm-dropdown-menu-checkbox-indicator.ts.template +3 -2
  34. package/src/generators/ui/libs/dropdown-menu/files/lib/hlm-dropdown-menu-checkbox.ts.template +30 -10
  35. package/src/generators/ui/libs/dropdown-menu/files/lib/hlm-dropdown-menu-group.ts.template +1 -3
  36. package/src/generators/ui/libs/dropdown-menu/files/lib/hlm-dropdown-menu-item-sub-indicator.ts.template +2 -2
  37. package/src/generators/ui/libs/dropdown-menu/files/lib/hlm-dropdown-menu-item.ts.template +1 -1
  38. package/src/generators/ui/libs/dropdown-menu/files/lib/hlm-dropdown-menu-label.ts.template +4 -4
  39. package/src/generators/ui/libs/dropdown-menu/files/lib/hlm-dropdown-menu-radio-indicator.ts.template +5 -4
  40. package/src/generators/ui/libs/dropdown-menu/files/lib/hlm-dropdown-menu-radio.ts.template +24 -9
  41. package/src/generators/ui/libs/dropdown-menu/files/lib/hlm-dropdown-menu-separator.ts.template +2 -4
  42. package/src/generators/ui/libs/dropdown-menu/files/lib/hlm-dropdown-menu-shortcut.ts.template +2 -4
  43. package/src/generators/ui/libs/dropdown-menu/files/lib/hlm-dropdown-menu-sub-trigger.ts.template +44 -0
  44. package/src/generators/ui/libs/dropdown-menu/files/lib/hlm-dropdown-menu-sub.ts.template +1 -4
  45. package/src/generators/ui/libs/dropdown-menu/files/lib/hlm-dropdown-menu-trigger.ts.template +1 -3
  46. package/src/generators/ui/libs/dropdown-menu/files/lib/hlm-dropdown-menu.ts.template +1 -1
  47. package/src/generators/ui/libs/input/files/lib/hlm-input.ts.template +1 -0
  48. package/src/generators/ui/libs/navigation-menu/files/lib/hlm-navigation-menu-content.ts.template +10 -3
  49. package/src/generators/ui/libs/navigation-menu/files/lib/hlm-navigation-menu-item.ts.template +4 -1
  50. package/src/generators/ui/libs/navigation-menu/files/lib/hlm-navigation-menu-link.ts.template +4 -4
  51. package/src/generators/ui/libs/navigation-menu/files/lib/hlm-navigation-menu-list.ts.template +4 -1
  52. package/src/generators/ui/libs/navigation-menu/files/lib/hlm-navigation-menu-trigger.ts.template +15 -4
  53. package/src/generators/ui/libs/navigation-menu/files/lib/hlm-navigation-menu.ts.template +6 -1
  54. package/src/generators/ui/libs/popover/files/index.ts.template +15 -1
  55. package/src/generators/ui/libs/popover/files/lib/hlm-popover-content.ts.template +1 -0
  56. package/src/generators/ui/libs/popover/files/lib/hlm-popover-description.ts.template +12 -0
  57. package/src/generators/ui/libs/popover/files/lib/hlm-popover-header.ts.template +12 -0
  58. package/src/generators/ui/libs/popover/files/lib/hlm-popover-title.ts.template +12 -0
  59. package/src/generators/ui/libs/popover/files/lib/hlm-popover-trigger.ts.template +1 -3
  60. package/src/generators/ui/libs/popover/files/lib/hlm-popover.ts.template +2 -11
  61. package/src/generators/ui/libs/progress/files/lib/hlm-progress-indicator.ts.template +5 -1
  62. package/src/generators/ui/libs/progress/files/lib/hlm-progress.ts.template +1 -0
  63. package/src/generators/ui/libs/select/files/lib/hlm-select-multiple.ts.template +3 -15
  64. package/src/generators/ui/libs/select/files/lib/hlm-select.ts.template +3 -15
  65. package/src/generators/ui/libs/sheet/files/lib/hlm-sheet-close.ts.template +1 -1
  66. package/src/generators/ui/libs/switch/files/lib/hlm-switch-thumb.ts.template +1 -0
  67. package/src/generators/ui/libs/switch/files/lib/hlm-switch.ts.template +1 -0
  68. package/src/generators/ui/primitive-deps.js +1 -0
  69. package/src/generators/ui/primitive-deps.js.map +1 -1
  70. package/src/generators/ui/primitives.d.ts +1 -1
  71. package/src/generators/ui/style-luma.css +15 -165
  72. package/src/generators/ui/style-lyra.css +13 -163
  73. package/src/generators/ui/style-maia.css +14 -164
  74. package/src/generators/ui/style-mira.css +13 -163
  75. package/src/generators/ui/style-nova.css +15 -165
  76. package/src/generators/ui/style-vega.css +16 -166
  77. package/src/generators/ui/supported-ui-libraries.json +46 -43
@@ -1,32 +1,52 @@
1
1
  import { type BooleanInput } from '@angular/cdk/coercion';
2
- import { CdkMenuItemCheckbox } from '@angular/cdk/menu';
2
+ import { CdkMenuItem, CdkMenuItemCheckbox, CdkMenuItemSelectable } from '@angular/cdk/menu';
3
3
  import { Directive, booleanAttribute, inject, input } from '@angular/core';
4
4
  import { classes } from '<%- importAlias %>/utils';
5
5
 
6
+ /** @internal. Use HlmDropdownMenuCheckbox instead. */
6
7
  @Directive({
7
- selector: '[hlmDropdownMenuCheckbox]',
8
+ selector: '[hlmDropdownMenuCheckboxCdk]',
9
+ providers: [
10
+ { provide: CdkMenuItemCheckbox, useExisting: HlmDropdownMenuCheckboxCdk },
11
+ { provide: CdkMenuItemSelectable, useExisting: HlmDropdownMenuCheckboxCdk },
12
+ { provide: CdkMenuItem, useExisting: CdkMenuItemSelectable },
13
+ ],
14
+ })
15
+ export class HlmDropdownMenuCheckboxCdk extends CdkMenuItemCheckbox {
16
+ public readonly keepOpen = input<boolean, BooleanInput>(true, { transform: booleanAttribute });
17
+
18
+ public override trigger(options?: { keepOpen: boolean }) {
19
+ super.trigger({ ...options, keepOpen: this.keepOpen() });
20
+ }
21
+ }
22
+
23
+ @Directive({
24
+ selector: '[hlmDropdownMenuCheckbox],[hlmDropdownMenuCheckboxItem]',
8
25
  hostDirectives: [
9
26
  {
10
- directive: CdkMenuItemCheckbox,
11
- inputs: ['cdkMenuItemDisabled: disabled', 'cdkMenuItemChecked: checked'],
27
+ directive: HlmDropdownMenuCheckboxCdk,
28
+ inputs: ['cdkMenuItemDisabled: disabled', 'cdkMenuItemChecked: checked', 'keepOpen'],
12
29
  outputs: ['cdkMenuItemTriggered: triggered'],
13
30
  },
14
31
  ],
15
32
  host: {
16
33
  'data-slot': 'dropdown-menu-checkbox-item',
17
- '[attr.data-disabled]': 'disabled() ? "" : null',
18
- '[attr.data-checked]': 'checked() ? "" : null',
34
+ '[attr.data-disabled]': '_cdkMenuItem.disabled ? "" : null',
35
+ '[attr.data-checked]': '_cdkMenuItem.checked ? "" : null',
36
+ '[attr.data-inset]': 'inset() ? "" : null',
19
37
  },
20
38
  })
21
39
  export class HlmDropdownMenuCheckbox {
22
- private readonly _cdkMenuItem = inject(CdkMenuItemCheckbox);
23
- public readonly checked = input<boolean, BooleanInput>(this._cdkMenuItem.checked, { transform: booleanAttribute });
24
- public readonly disabled = input<boolean, BooleanInput>(this._cdkMenuItem.disabled, { transform: booleanAttribute });
40
+ protected readonly _cdkMenuItem = inject(HlmDropdownMenuCheckboxCdk);
41
+
42
+ public readonly inset = input<boolean, BooleanInput>(false, {
43
+ transform: booleanAttribute,
44
+ });
25
45
 
26
46
  constructor() {
27
47
  classes(
28
48
  () =>
29
- 'hover:bg-accent hover:text-accent-foreground focus-visible:bg-accent focus-visible:text-accent-foreground group relative flex w-full cursor-default items-center rounded-sm py-1.5 pr-2 pl-8 text-sm transition-colors outline-none select-none has-[>hlm-dropdown-menu-checkbox-indicator:last-child]:ps-2 has-[>hlm-dropdown-menu-checkbox-indicator:last-child]:pe-8 data-[disabled]:pointer-events-none data-[disabled]:opacity-50 has-[>hlm-dropdown-menu-checkbox-indicator:last-child]:[&>hlm-dropdown-menu-checkbox-indicator]:start-auto has-[>hlm-dropdown-menu-checkbox-indicator:last-child]:[&>hlm-dropdown-menu-checkbox-indicator]:end-2',
49
+ 'spartan-dropdown-menu-checkbox-item group/dropdown-menu-checkbox relative flex w-full cursor-default items-center outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 [&_ng-icon]:pointer-events-none [&_ng-icon]:shrink-0',
30
50
  );
31
51
  }
32
52
  }
@@ -5,9 +5,7 @@ import { classes } from '<%- importAlias %>/utils';
5
5
  @Directive({
6
6
  selector: '[hlmDropdownMenuGroup],hlm-dropdown-menu-group',
7
7
  hostDirectives: [CdkMenuGroup],
8
- host: {
9
- 'data-slot': 'dropdown-menu-group',
10
- },
8
+ host: { 'data-slot': 'dropdown-menu-group' },
11
9
  })
12
10
  export class HlmDropdownMenuGroup {
13
11
  constructor() {
@@ -9,11 +9,11 @@ import { classes } from '<%- importAlias %>/utils';
9
9
  providers: [provideIcons({ lucideChevronRight })],
10
10
  changeDetection: ChangeDetectionStrategy.OnPush,
11
11
  template: `
12
- <ng-icon name="lucideChevronRight" class="text-base rtl:rotate-180" />
12
+ <ng-icon name="lucideChevronRight" class="text-[calc(var(--spacing)*4)] rtl:rotate-180" />
13
13
  `,
14
14
  })
15
15
  export class HlmDropdownMenuItemSubIndicator {
16
16
  constructor() {
17
- classes(() => 'ms-auto size-4');
17
+ classes(() => 'ms-auto flex items-center justify-center');
18
18
  }
19
19
  }
@@ -34,7 +34,7 @@ export class HlmDropdownMenuItem {
34
34
  constructor() {
35
35
  classes(
36
36
  () =>
37
- "hover:bg-accent focus-visible:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[ng-icon]:!text-destructive [&_ng-icon:not([class*='text-'])]:text-muted-foreground relative flex w-full cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_ng-icon]:pointer-events-none [&_ng-icon]:shrink-0 [&_svg:not([class*='text-'])]:text-base",
37
+ 'spartan-dropdown-menu-item group/dropdown-menu-item relative flex w-full cursor-default items-center outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 [&_ng-icon]:pointer-events-none [&_ng-icon]:shrink-0',
38
38
  );
39
39
  }
40
40
  }
@@ -10,11 +10,11 @@ import { classes } from '<%- importAlias %>/utils';
10
10
  },
11
11
  })
12
12
  export class HlmDropdownMenuLabel {
13
- constructor() {
14
- classes(() => 'block px-2 py-1.5 text-sm font-medium data-[inset]:pl-8');
15
- }
16
-
17
13
  public readonly inset = input<boolean, BooleanInput>(false, {
18
14
  transform: booleanAttribute,
19
15
  });
16
+
17
+ constructor() {
18
+ classes(() => 'spartan-dropdown-menu-label block');
19
+ }
20
20
  }
@@ -1,22 +1,23 @@
1
1
  import { ChangeDetectionStrategy, Component } from '@angular/core';
2
2
  import { NgIcon, provideIcons } from '@ng-icons/core';
3
- import { lucideCircle } from '@ng-icons/lucide';
3
+ import { lucideCheck } from '@ng-icons/lucide';
4
4
  import { classes } from '<%- importAlias %>/utils';
5
5
 
6
6
  @Component({
7
7
  selector: 'hlm-dropdown-menu-radio-indicator',
8
8
  imports: [NgIcon],
9
- providers: [provideIcons({ lucideCircle })],
9
+ providers: [provideIcons({ lucideCheck })],
10
10
  changeDetection: ChangeDetectionStrategy.OnPush,
11
+ host: { 'data-slot': 'dropdown-menu-radio-item-indicator' },
11
12
  template: `
12
- <ng-icon name="lucideCircle" class="text-[0.5rem] *:[svg]:fill-current" />
13
+ <ng-icon name="lucideCheck" />
13
14
  `,
14
15
  })
15
16
  export class HlmDropdownMenuRadioIndicator {
16
17
  constructor() {
17
18
  classes(
18
19
  () =>
19
- 'pointer-events-none absolute start-2 flex size-3.5 items-center justify-center opacity-0 group-data-[checked]:opacity-100',
20
+ 'spartan-dropdown-menu-item-indicator pointer-events-none opacity-0 group-data-checked/dropdown-menu-radio:opacity-100',
20
21
  );
21
22
  }
22
23
  }
@@ -1,32 +1,47 @@
1
1
  import { type BooleanInput } from '@angular/cdk/coercion';
2
- import { CdkMenuItemRadio } from '@angular/cdk/menu';
2
+ import { CdkMenuItem, CdkMenuItemRadio, CdkMenuItemSelectable } from '@angular/cdk/menu';
3
3
  import { Directive, booleanAttribute, inject, input } from '@angular/core';
4
4
  import { classes } from '<%- importAlias %>/utils';
5
5
 
6
+ /** @internal. Use HlmDropdownMenuRadio instead. */
7
+ @Directive({
8
+ selector: '[hlmDropdownMenuRadioCdk]',
9
+ providers: [
10
+ { provide: CdkMenuItemRadio, useExisting: HlmDropdownMenuRadioCdk },
11
+ { provide: CdkMenuItemSelectable, useExisting: HlmDropdownMenuRadioCdk },
12
+ { provide: CdkMenuItem, useExisting: CdkMenuItemSelectable },
13
+ ],
14
+ })
15
+ export class HlmDropdownMenuRadioCdk extends CdkMenuItemRadio {
16
+ public readonly keepOpen = input<boolean, BooleanInput>(true, { transform: booleanAttribute });
17
+
18
+ public override trigger(options?: { keepOpen: boolean }) {
19
+ super.trigger({ ...options, keepOpen: this.keepOpen() });
20
+ }
21
+ }
22
+
6
23
  @Directive({
7
24
  selector: '[hlmDropdownMenuRadio]',
8
25
  hostDirectives: [
9
26
  {
10
- directive: CdkMenuItemRadio,
11
- inputs: ['cdkMenuItemDisabled: disabled', 'cdkMenuItemChecked: checked'],
27
+ directive: HlmDropdownMenuRadioCdk,
28
+ inputs: ['cdkMenuItemDisabled: disabled', 'cdkMenuItemChecked: checked', 'keepOpen'],
12
29
  outputs: ['cdkMenuItemTriggered: triggered'],
13
30
  },
14
31
  ],
15
32
  host: {
16
33
  'data-slot': 'dropdown-menu-radio-item',
17
- '[attr.data-disabled]': 'disabled() ? "" : null',
18
- '[attr.data-checked]': 'checked() ? "" : null',
34
+ '[attr.data-disabled]': '_cdkMenuItem.disabled ? "" : null',
35
+ '[attr.data-checked]': '_cdkMenuItem.checked ? "" : null',
19
36
  },
20
37
  })
21
38
  export class HlmDropdownMenuRadio {
22
- private readonly _cdkMenuItem = inject(CdkMenuItemRadio);
23
- public readonly checked = input<boolean, BooleanInput>(this._cdkMenuItem.checked, { transform: booleanAttribute });
24
- public readonly disabled = input<boolean, BooleanInput>(this._cdkMenuItem.disabled, { transform: booleanAttribute });
39
+ protected readonly _cdkMenuItem = inject(HlmDropdownMenuRadioCdk);
25
40
 
26
41
  constructor() {
27
42
  classes(
28
43
  () =>
29
- 'hover:bg-accent hover:text-accent-foreground focus-visible:bg-accent focus-visible:text-accent-foreground group relative flex w-full cursor-default items-center rounded-sm py-1.5 ps-8 pe-2 text-sm transition-colors outline-none select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
44
+ 'spartan-dropdown-menu-radio-item group/dropdown-menu-radio relative flex w-full cursor-default items-center outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 [&_ng-icon]:pointer-events-none [&_ng-icon]:shrink-0',
30
45
  );
31
46
  }
32
47
  }
@@ -3,12 +3,10 @@ import { classes } from '<%- importAlias %>/utils';
3
3
 
4
4
  @Directive({
5
5
  selector: '[hlmDropdownMenuSeparator],hlm-dropdown-menu-separator',
6
- host: {
7
- 'data-slot': 'dropdown-menu-separator',
8
- },
6
+ host: { 'data-slot': 'dropdown-menu-separator' },
9
7
  })
10
8
  export class HlmDropdownMenuSeparator {
11
9
  constructor() {
12
- classes(() => 'bg-border -mx-1 my-1 block h-px');
10
+ classes(() => 'spartan-dropdown-menu-separator block');
13
11
  }
14
12
  }
@@ -3,12 +3,10 @@ import { classes } from '<%- importAlias %>/utils';
3
3
 
4
4
  @Directive({
5
5
  selector: '[hlmDropdownMenuShortcut],hlm-dropdown-menu-shortcut',
6
- host: {
7
- 'data-slot': 'dropdown-menu-shortcut',
8
- },
6
+ host: { 'data-slot': 'dropdown-menu-shortcut' },
9
7
  })
10
8
  export class HlmDropdownMenuShortcut {
11
9
  constructor() {
12
- classes(() => 'text-muted-foreground ml-auto text-xs tracking-widest');
10
+ classes(() => 'spartan-dropdown-menu-shortcut');
13
11
  }
14
12
  }
@@ -0,0 +1,44 @@
1
+ import { CdkMenuTrigger } from '@angular/cdk/menu';
2
+ import { computed, Directive, effect, inject, input } from '@angular/core';
3
+ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
4
+ import { createMenuPosition, type MenuAlign, type MenuSide } from '@spartan-ng/brain/core';
5
+ import { classes } from '<%- importAlias %>/utils';
6
+ import { injectHlmDropdownMenuConfig } from './hlm-dropdown-menu-token';
7
+
8
+ @Directive({
9
+ selector: '[hlmDropdownMenuSubTrigger]',
10
+ hostDirectives: [
11
+ {
12
+ directive: CdkMenuTrigger,
13
+ inputs: ['cdkMenuTriggerFor: hlmDropdownMenuSubTrigger', 'cdkMenuTriggerData: hlmDropdownMenuTriggerData'],
14
+ outputs: ['cdkMenuOpened: hlmDropdownMenuSubOpened', 'cdkMenuClosed: hlmDropdownMenuSubClosed'],
15
+ },
16
+ ],
17
+ host: { 'data-slot': 'dropdown-menu-sub-trigger' },
18
+ })
19
+ export class HlmDropdownMenuSubTrigger {
20
+ private readonly _cdkTrigger = inject(CdkMenuTrigger, { host: true });
21
+ private readonly _config = injectHlmDropdownMenuConfig();
22
+
23
+ public readonly align = input<MenuAlign>(this._config.align);
24
+ public readonly side = input<MenuSide>(this._config.side);
25
+
26
+ private readonly _menuPosition = computed(() => createMenuPosition(this.align(), this.side()));
27
+
28
+ constructor() {
29
+ this._cdkTrigger.opened.pipe(takeUntilDestroyed()).subscribe(() =>
30
+ setTimeout(
31
+ () =>
32
+ // eslint-disable-next-line
33
+ ((this._cdkTrigger as any)._spartanLastPosition = // eslint-disable-next-line
34
+ (this._cdkTrigger as any).overlayRef._positionStrategy._lastPosition),
35
+ ),
36
+ );
37
+
38
+ effect(() => {
39
+ this._cdkTrigger.menuPosition = this._menuPosition();
40
+ });
41
+
42
+ classes(() => 'aria-expanded:bg-accent aria-expanded:text-accent-foreground');
43
+ }
44
+ }
@@ -24,10 +24,7 @@ export class HlmDropdownMenuSub {
24
24
  // TODO: figure out a way for us to know the host is about to be closed. might not be possible with CDK
25
25
  this._host.closed.pipe(takeUntilDestroyed()).subscribe(() => this._state.set('closed'));
26
26
 
27
- classes(
28
- () =>
29
- 'bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[8rem] origin-top overflow-hidden rounded-md border p-1 shadow-lg',
30
- );
27
+ classes(() => 'spartan-dropdown-menu-sub-content w-auto');
31
28
  }
32
29
 
33
30
  private setSideWithDarkMagic() {
@@ -13,9 +13,7 @@ import { injectHlmDropdownMenuConfig } from './hlm-dropdown-menu-token';
13
13
  outputs: ['cdkMenuOpened: hlmDropdownMenuOpened', 'cdkMenuClosed: hlmDropdownMenuClosed'],
14
14
  },
15
15
  ],
16
- host: {
17
- 'data-slot': 'dropdown-menu-trigger',
18
- },
16
+ host: { 'data-slot': 'dropdown-menu-trigger' },
19
17
  })
20
18
  export class HlmDropdownMenuTrigger {
21
19
  private readonly _cdkTrigger = inject(CdkMenuTrigger, { host: true });
@@ -25,7 +25,7 @@ export class HlmDropdownMenu {
25
25
  constructor() {
26
26
  classes(
27
27
  () =>
28
- 'bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 my-[--spacing(var(--side-offset))] min-w-[8rem] origin-top overflow-x-hidden overflow-y-auto rounded-md border p-1 shadow-md',
28
+ 'spartan-dropdown-menu-content my-[--spacing(var(--side-offset))] overflow-x-hidden overflow-y-auto outline-none',
29
29
  );
30
30
 
31
31
  this.setSideWithDarkMagic();
@@ -6,6 +6,7 @@ import { classes } from '<%- importAlias %>/utils';
6
6
  @Directive({
7
7
  selector: '[hlmInput]',
8
8
  hostDirectives: [{ directive: BrnInput, inputs: ['id', 'forceInvalid'] }, BrnFieldControlDescribedBy],
9
+ host: { 'data-slot': 'input' },
9
10
  })
10
11
  export class HlmInput {
11
12
  constructor() {
@@ -1,17 +1,24 @@
1
- import { Directive } from '@angular/core';
1
+ import { type NumberInput } from '@angular/cdk/coercion';
2
+ import { Directive, input, numberAttribute } from '@angular/core';
2
3
  import { classes } from '<%- importAlias %>/utils';
3
4
 
4
5
  @Directive({
5
6
  selector: '[hlmNavigationMenuContent],hlm-navigation-menu-content',
6
- host: { 'data-slot': 'navigation-menu-content' },
7
+ host: {
8
+ 'data-slot': 'navigation-menu-content',
9
+ '[style.--nav-offset]': 'navOffset()',
10
+ },
7
11
  })
8
12
  export class HlmNavigationMenuContent {
13
+ public readonly navOffset = input<number, NumberInput>(1.5, { transform: numberAttribute });
14
+
9
15
  constructor() {
10
16
  classes(() => [
11
17
  'data-[motion^=from-]:animate-in data-[motion^=to-]:animate-out data-[motion^=from-]:fade-in data-[motion^=to-]:fade-out top-0 left-0 w-full p-2 pr-2.5 md:w-auto',
12
18
  'data-[orientation=horizontal]:data-[motion=from-end]:slide-in-from-right-52 data-[orientation=horizontal]:data-[motion=from-start]:slide-in-from-left-52 data-[orientation=horizontal]:data-[motion=to-end]:slide-out-to-right-52 data-[orientation=horizontal]:data-[motion=to-start]:slide-out-to-left-52',
13
19
  'data-[orientation=vertical]:data-[motion=from-end]:slide-in-from-bottom-52 data-[orientation=vertical]:data-[motion=from-start]:slide-in-from-top-52 data-[orientation=vertical]:data-[motion=to-end]:slide-out-to-bottom-52 data-[orientation=vertical]:data-[motion=to-start]:slide-out-to-top-52',
14
- 'bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=open]:fade-in-0 data-[state=closed]:fade-out-0 top-full overflow-hidden rounded-md border shadow duration-200 data-[orientation=horizontal]:mt-1.5 data-[orientation=vertical]:mx-1.5 **:data-[slot=navigation-menu-link]:focus:ring-0 **:data-[slot=navigation-menu-link]:focus:outline-none',
20
+ 'data-[orientation=horizontal]:mt-[--spacing(var(--nav-offset))] data-[orientation=vertical]:mx-[--spacing(var(--nav-offset))]',
21
+ 'spartan-navigation-menu-popup block',
15
22
  ]);
16
23
  }
17
24
  }
@@ -5,9 +5,12 @@ import { classes } from '<%- importAlias %>/utils';
5
5
  @Directive({
6
6
  selector: 'li[hlmNavigationMenuItem]',
7
7
  hostDirectives: [{ directive: BrnNavigationMenuItem, inputs: ['id'] }],
8
+ host: {
9
+ 'data-slot': 'navigation-menu-item',
10
+ },
8
11
  })
9
12
  export class HlmNavigationMenuItem {
10
13
  constructor() {
11
- classes(() => 'relative');
14
+ classes(() => 'relative has-[:focus]:z-10 data-active:z-10');
12
15
  }
13
16
  }
@@ -5,12 +5,12 @@ import { classes } from '<%- importAlias %>/utils';
5
5
  @Directive({
6
6
  selector: 'a[hlmNavigationMenuLink]',
7
7
  hostDirectives: [{ directive: BrnNavigationMenuLink, inputs: ['active'] }],
8
+ host: {
9
+ 'data-slot': 'navigation-menu-link',
10
+ },
8
11
  })
9
12
  export class HlmNavigationMenuLink {
10
13
  constructor() {
11
- classes(() => [
12
- 'data-[active=true]:focus:bg-accent data-[active=true]:hover:bg-accent data-[active=true]:bg-accent/50 data-[active=true]:text-accent-foreground hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground focus-visible:ring-ring/50 [&_ng-icon:not([class*="text-"])]:text-muted-foreground flex flex-col gap-1 rounded-sm p-2 text-sm transition-all outline-none focus-visible:ring-[3px] focus-visible:outline-1 [&_ng-icon:not([class*="text-"])]:text-base',
13
- 'data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50',
14
- ]);
14
+ classes(() => 'spartan-navigation-menu-link');
15
15
  }
16
16
  }
@@ -9,11 +9,14 @@ import { classes } from '<%- importAlias %>/utils';
9
9
  directive: BrnNavigationMenuList,
10
10
  },
11
11
  ],
12
+ host: {
13
+ 'data-slot': 'navigation-menu-list',
14
+ },
12
15
  })
13
16
  export class HlmNavigationMenuList {
14
17
  constructor() {
15
18
  classes(() => [
16
- 'group flex flex-1 list-none items-center justify-center gap-0',
19
+ 'spartan-navigation-menu-list group flex flex-1 list-none items-center justify-center',
17
20
  'data-[orientation=vertical]:flex-col',
18
21
  ]);
19
22
  }
@@ -1,16 +1,27 @@
1
- import { Directive } from '@angular/core';
1
+ import { ChangeDetectionStrategy, Component } from '@angular/core';
2
+ import { NgIcon, provideIcons } from '@ng-icons/core';
3
+ import { lucideChevronDown } from '@ng-icons/lucide';
2
4
  import { BrnNavigationMenuTrigger } from '@spartan-ng/brain/navigation-menu';
3
5
  import { classes } from '<%- importAlias %>/utils';
4
6
 
5
- @Directive({
7
+ @Component({
8
+ // eslint-disable-next-line @angular-eslint/component-selector
6
9
  selector: 'button[hlmNavigationMenuTrigger]',
7
- hostDirectives: [BrnNavigationMenuTrigger],
10
+ imports: [NgIcon],
11
+ providers: [provideIcons({ lucideChevronDown })],
12
+ changeDetection: ChangeDetectionStrategy.OnPush,
13
+ hostDirectives: [{ directive: BrnNavigationMenuTrigger, inputs: ['align'] }],
14
+ host: { 'data-slot': 'navigation-menu-trigger' },
15
+ template: `
16
+ <ng-content />
17
+ <ng-icon name="lucideChevronDown" class="spartan-navigation-menu-trigger-icon" />
18
+ `,
8
19
  })
9
20
  export class HlmNavigationMenuTrigger {
10
21
  constructor() {
11
22
  classes(
12
23
  () =>
13
- 'bg-background hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground data-[state=open]:hover:bg-accent data-[state=open]:text-accent-foreground data-[state=open]:focus:bg-accent data-[state=open]:bg-accent/50 focus-visible:ring-ring/50 group inline-flex h-9 w-max items-center justify-center rounded-md px-4 py-2 text-sm font-medium transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:outline-1 disabled:pointer-events-none disabled:opacity-50',
24
+ 'spartan-navigation-menu-trigger group/navigation-menu-trigger inline-flex h-9 w-max items-center justify-center outline-none disabled:pointer-events-none',
14
25
  );
15
26
  }
16
27
  }
@@ -11,9 +11,14 @@ import { classes } from '<%- importAlias %>/utils';
11
11
  outputs: ['valueChange'],
12
12
  },
13
13
  ],
14
+ host: {
15
+ 'data-slot': 'navigation-menu',
16
+ },
14
17
  })
15
18
  export class HlmNavigationMenu {
16
19
  constructor() {
17
- classes(() => 'group/navigation-menu relative flex max-w-max flex-1 items-center justify-center');
20
+ classes(
21
+ () => 'spartan-navigation-menu group/navigation-menu relative flex max-w-max flex-1 items-center justify-center',
22
+ );
18
23
  }
19
24
  }
@@ -1,11 +1,25 @@
1
1
  import { HlmPopover } from './lib/hlm-popover';
2
2
  import { HlmPopoverContent } from './lib/hlm-popover-content';
3
+ import { HlmPopoverDescription } from './lib/hlm-popover-description';
4
+ import { HlmPopoverHeader } from './lib/hlm-popover-header';
3
5
  import { HlmPopoverPortal } from './lib/hlm-popover-portal';
6
+ import { HlmPopoverTitle } from './lib/hlm-popover-title';
4
7
  import { HlmPopoverTrigger } from './lib/hlm-popover-trigger';
5
8
 
6
9
  export * from './lib/hlm-popover';
7
10
  export * from './lib/hlm-popover-content';
11
+ export * from './lib/hlm-popover-description';
12
+ export * from './lib/hlm-popover-header';
8
13
  export * from './lib/hlm-popover-portal';
14
+ export * from './lib/hlm-popover-title';
9
15
  export * from './lib/hlm-popover-trigger';
10
16
 
11
- export const HlmPopoverImports = [HlmPopover, HlmPopoverContent, HlmPopoverPortal, HlmPopoverTrigger] as const;
17
+ export const HlmPopoverImports = [
18
+ HlmPopover,
19
+ HlmPopoverContent,
20
+ HlmPopoverDescription,
21
+ HlmPopoverHeader,
22
+ HlmPopoverPortal,
23
+ HlmPopoverTitle,
24
+ HlmPopoverTrigger,
25
+ ] as const;
@@ -4,6 +4,7 @@ import { classes } from '<%- importAlias %>/utils';
4
4
 
5
5
  @Directive({
6
6
  selector: '[hlmPopoverContent],hlm-popover-content',
7
+ host: { 'data-slot': 'popover-content' },
7
8
  })
8
9
  export class HlmPopoverContent {
9
10
  private readonly _stateProvider = injectExposesStateProvider({ host: true });
@@ -0,0 +1,12 @@
1
+ import { Directive } from '@angular/core';
2
+ import { classes } from '<%- importAlias %>/utils';
3
+
4
+ @Directive({
5
+ selector: '[hlmPopoverDescription]',
6
+ host: { 'data-slot': 'popover-description' },
7
+ })
8
+ export class HlmPopoverDescription {
9
+ constructor() {
10
+ classes(() => 'spartan-popover-description');
11
+ }
12
+ }
@@ -0,0 +1,12 @@
1
+ import { Directive } from '@angular/core';
2
+ import { classes } from '<%- importAlias %>/utils';
3
+
4
+ @Directive({
5
+ selector: '[hlmPopoverHeader],hlm-popover-header',
6
+ host: { 'data-slot': 'popover-header' },
7
+ })
8
+ export class HlmPopoverHeader {
9
+ constructor() {
10
+ classes(() => 'spartan-popover-header');
11
+ }
12
+ }
@@ -0,0 +1,12 @@
1
+ import { Directive } from '@angular/core';
2
+ import { classes } from '<%- importAlias %>/utils';
3
+
4
+ @Directive({
5
+ selector: '[hlmPopoverTitle]',
6
+ host: { 'data-slot': 'popover-title' },
7
+ })
8
+ export class HlmPopoverTitle {
9
+ constructor() {
10
+ classes(() => 'spartan-popover-title');
11
+ }
12
+ }
@@ -6,8 +6,6 @@ import { BrnPopoverTrigger } from '@spartan-ng/brain/popover';
6
6
  hostDirectives: [
7
7
  { directive: BrnPopoverTrigger, inputs: ['id', 'brnPopoverTriggerFor: hlmPopoverTriggerFor', 'type'] },
8
8
  ],
9
- host: {
10
- 'data-slot': 'popover-trigger',
11
- },
9
+ host: { 'data-slot': 'popover-trigger' },
12
10
  })
13
11
  export class HlmPopoverTrigger {}
@@ -6,19 +6,10 @@ import { BrnPopover } from '@spartan-ng/brain/popover';
6
6
  hostDirectives: [
7
7
  {
8
8
  directive: BrnPopover,
9
- inputs: [
10
- 'align',
11
- 'autoFocus',
12
- 'attachTo',
13
- 'closeDelay',
14
- 'closeOnOutsidePointerEvents',
15
- 'offsetX',
16
- 'restoreFocus',
17
- 'sideOffset',
18
- 'state',
19
- ],
9
+ inputs: ['align', 'attachTo', 'autoFocus', 'closeOnOutsidePointerEvents', 'offsetX', 'sideOffset', 'state'],
20
10
  outputs: ['stateChanged', 'closed'],
21
11
  },
22
12
  ],
13
+ host: { 'data-slot': 'popover' },
23
14
  })
24
15
  export class HlmPopover {}
@@ -6,7 +6,11 @@ import { classes } from '<%- importAlias %>/utils';
6
6
  @Directive({
7
7
  selector: '[hlmProgressIndicator],hlm-progress-indicator',
8
8
  hostDirectives: [BrnProgressIndicator],
9
- host: { '[class.animate-indeterminate]': '_indeterminate()', '[style.transform]': '_transform()' },
9
+ host: {
10
+ 'data-slot': 'progress-indicator',
11
+ '[class.animate-indeterminate]': '_indeterminate()',
12
+ '[style.transform]': '_transform()',
13
+ },
10
14
  })
11
15
  export class HlmProgressIndicator {
12
16
  private readonly _progress = injectBrnProgress();
@@ -5,6 +5,7 @@ import { classes } from '<%- importAlias %>/utils';
5
5
  @Directive({
6
6
  selector: 'hlm-progress,[hlmProgress]',
7
7
  hostDirectives: [{ directive: BrnProgress, inputs: ['value', 'max', 'getValueLabel'] }],
8
+ host: { 'data-slot': 'progress' },
8
9
  })
9
10
  export class HlmProgress {
10
11
  constructor() {
@@ -1,6 +1,5 @@
1
1
  import { Directive } from '@angular/core';
2
- import { provideBrnDialogDefaultOptions } from '@spartan-ng/brain/dialog';
3
- import { BrnPopover, provideBrnPopoverConfig } from '@spartan-ng/brain/popover';
2
+ import { BrnPopover, provideBrnPopoverConfig, provideBrnPopoverDefaultOptions } from '@spartan-ng/brain/popover';
4
3
  import { BrnSelectMultiple } from '@spartan-ng/brain/select';
5
4
  import { classes } from '<%- importAlias %>/utils';
6
5
 
@@ -11,9 +10,7 @@ import { classes } from '<%- importAlias %>/utils';
11
10
  align: 'start',
12
11
  sideOffset: 6,
13
12
  }),
14
- provideBrnDialogDefaultOptions({
15
- autoFocus: 'first-heading',
16
- }),
13
+ provideBrnPopoverDefaultOptions({ role: null }),
17
14
  ],
18
15
  hostDirectives: [
19
16
  {
@@ -23,16 +20,7 @@ import { classes } from '<%- importAlias %>/utils';
23
20
  },
24
21
  {
25
22
  directive: BrnPopover,
26
- inputs: [
27
- 'align',
28
- 'autoFocus',
29
- 'closeDelay',
30
- 'closeOnOutsidePointerEvents',
31
- 'sideOffset',
32
- 'state',
33
- 'offsetX',
34
- 'restoreFocus',
35
- ],
23
+ inputs: ['align', 'closeOnOutsidePointerEvents', 'sideOffset', 'state', 'offsetX'],
36
24
  outputs: ['stateChanged', 'closed'],
37
25
  },
38
26
  ],