@spartan-ng/cli 0.0.1-alpha.484 → 0.0.1-alpha.486

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 (110) hide show
  1. package/package.json +1 -1
  2. package/src/generators/migrate-helm-libraries/schema.json +1 -1
  3. package/src/generators/migrate-icon/schema.json +1 -1
  4. package/src/generators/migrate-radio/schema.json +1 -1
  5. package/src/generators/migrate-select/schema.json +1 -1
  6. package/src/generators/migrate-toggle-group/schema.json +1 -1
  7. package/src/generators/theme/__snapshots__/generator.spec.ts.snap +620 -0
  8. package/src/generators/theme/generator.js +3 -12
  9. package/src/generators/theme/generator.js.map +1 -1
  10. package/src/generators/theme/libs/add-theme-to-application-styles.d.ts +2 -3
  11. package/src/generators/theme/libs/add-theme-to-application-styles.js +14 -2
  12. package/src/generators/theme/libs/add-theme-to-application-styles.js.map +1 -1
  13. package/src/generators/theme/libs/colors.d.ts +14 -0
  14. package/src/generators/theme/libs/colors.js +451 -0
  15. package/src/generators/theme/libs/colors.js.map +1 -0
  16. package/src/generators/ui/libs/ui-accordion-helm/files/lib/hlm-accordion-content.component.ts.template +1 -6
  17. package/src/generators/ui/libs/ui-accordion-helm/files/lib/hlm-accordion-icon.directive.ts.template +4 -1
  18. package/src/generators/ui/libs/ui-accordion-helm/files/lib/hlm-accordion-trigger.directive.ts.template +1 -1
  19. package/src/generators/ui/libs/ui-alert-dialog-helm/files/lib/hlm-alert-dialog-content.component.ts.template +1 -1
  20. package/src/generators/ui/libs/ui-alert-dialog-helm/files/lib/hlm-alert-dialog-description.directive.ts.template +1 -1
  21. package/src/generators/ui/libs/ui-alert-dialog-helm/files/lib/hlm-alert-dialog-footer.component.ts.template +1 -1
  22. package/src/generators/ui/libs/ui-alert-dialog-helm/files/lib/hlm-alert-dialog-header.component.ts.template +1 -1
  23. package/src/generators/ui/libs/ui-alert-dialog-helm/files/lib/hlm-alert-dialog-overlay.directive.ts.template +1 -1
  24. package/src/generators/ui/libs/ui-alert-helm/files/lib/hlm-alert-description.directive.ts.template +6 -7
  25. package/src/generators/ui/libs/ui-alert-helm/files/lib/hlm-alert-title.directive.ts.template +3 -7
  26. package/src/generators/ui/libs/ui-alert-helm/files/lib/hlm-alert.directive.ts.template +5 -4
  27. package/src/generators/ui/libs/ui-avatar-helm/files/lib/fallback/hlm-avatar-fallback.directive.ts.template +3 -18
  28. package/src/generators/ui/libs/ui-avatar-helm/files/lib/hlm-avatar.component.ts.template +1 -18
  29. package/src/generators/ui/libs/ui-avatar-helm/files/lib/image/hlm-avatar-image.directive.ts.template +1 -1
  30. package/src/generators/ui/libs/ui-badge-helm/files/index.ts.template +4 -2
  31. package/src/generators/ui/libs/ui-badge-helm/files/lib/hlm-badge.directive.ts.template +10 -37
  32. package/src/generators/ui/libs/ui-breadcrumb-helm/files/lib/hlm-breadcrumb-ellipsis.component.ts.template +1 -1
  33. package/src/generators/ui/libs/ui-breadcrumb-helm/files/lib/hlm-breadcrumb-link.directive.ts.template +1 -1
  34. package/src/generators/ui/libs/ui-breadcrumb-helm/files/lib/hlm-breadcrumb-list.directive.ts.template +1 -1
  35. package/src/generators/ui/libs/ui-breadcrumb-helm/files/lib/hlm-breadcrumb-separator.component.ts.template +4 -6
  36. package/src/generators/ui/libs/ui-button-helm/files/index.ts.template +1 -2
  37. package/src/generators/ui/libs/ui-button-helm/files/lib/hlm-button.directive.ts.template +14 -11
  38. package/src/generators/ui/libs/ui-calendar-helm/files/lib/hlm-calendar-multi.component.ts.template +3 -3
  39. package/src/generators/ui/libs/ui-calendar-helm/files/lib/hlm-calendar.component.ts.template +6 -6
  40. package/src/generators/ui/libs/ui-card-helm/files/index.ts.template +3 -0
  41. package/src/generators/ui/libs/ui-card-helm/files/lib/hlm-card-action.directive.ts.template +17 -0
  42. package/src/generators/ui/libs/ui-card-helm/files/lib/hlm-card-content.directive.ts.template +1 -8
  43. package/src/generators/ui/libs/ui-card-helm/files/lib/hlm-card-description.directive.ts.template +1 -8
  44. package/src/generators/ui/libs/ui-card-helm/files/lib/hlm-card-footer.directive.ts.template +1 -17
  45. package/src/generators/ui/libs/ui-card-helm/files/lib/hlm-card-header.directive.ts.template +6 -17
  46. package/src/generators/ui/libs/ui-card-helm/files/lib/hlm-card-title.directive.ts.template +1 -8
  47. package/src/generators/ui/libs/ui-card-helm/files/lib/hlm-card.directive.ts.template +4 -7
  48. package/src/generators/ui/libs/ui-checkbox-helm/files/lib/hlm-checkbox.component.ts.template +11 -10
  49. package/src/generators/ui/libs/ui-command-helm/files/lib/hlm-command-dialog.directive.ts.template +1 -1
  50. package/src/generators/ui/libs/ui-command-helm/files/lib/hlm-command-group-label.component.ts.template +1 -1
  51. package/src/generators/ui/libs/ui-command-helm/files/lib/hlm-command-group.component.ts.template +1 -1
  52. package/src/generators/ui/libs/ui-command-helm/files/lib/hlm-command-icon.directive.ts.template +10 -3
  53. package/src/generators/ui/libs/ui-command-helm/files/lib/hlm-command-item.component.ts.template +1 -1
  54. package/src/generators/ui/libs/ui-command-helm/files/lib/hlm-command-list.component.ts.template +1 -1
  55. package/src/generators/ui/libs/ui-command-helm/files/lib/hlm-command-search-input.component.ts.template +1 -1
  56. package/src/generators/ui/libs/ui-command-helm/files/lib/hlm-command-search.component.ts.template +1 -1
  57. package/src/generators/ui/libs/ui-command-helm/files/lib/hlm-command-separator.component.ts.template +1 -1
  58. package/src/generators/ui/libs/ui-command-helm/files/lib/hlm-command-shortcut.component.ts.template +10 -3
  59. package/src/generators/ui/libs/ui-command-helm/files/lib/hlm-command.component.ts.template +1 -4
  60. package/src/generators/ui/libs/ui-date-picker-helm/files/lib/hlm-date-picker-multi.component.ts.template +2 -2
  61. package/src/generators/ui/libs/ui-date-picker-helm/files/lib/hlm-date-picker.component.ts.template +7 -7
  62. package/src/generators/ui/libs/ui-dialog-helm/files/lib/hlm-dialog-overlay.directive.ts.template +1 -1
  63. package/src/generators/ui/libs/ui-form-field-helm/files/lib/hlm-error.directive.ts.template +10 -3
  64. package/src/generators/ui/libs/ui-form-field-helm/files/lib/hlm-form-field.component.ts.template +14 -2
  65. package/src/generators/ui/libs/ui-form-field-helm/files/lib/hlm-hint.directive.ts.template +8 -3
  66. package/src/generators/ui/libs/ui-input-helm/files/index.ts.template +2 -4
  67. package/src/generators/ui/libs/ui-input-helm/files/lib/hlm-input.directive.ts.template +10 -21
  68. package/src/generators/ui/libs/ui-input-otp-helm/files/lib/hlm-input-otp-separator.component.ts.template +4 -4
  69. package/src/generators/ui/libs/ui-input-otp-helm/files/lib/hlm-input-otp-slot.component.ts.template +2 -2
  70. package/src/generators/ui/libs/ui-input-otp-helm/files/lib/hlm-input-otp.directive.ts.template +1 -1
  71. package/src/generators/ui/libs/ui-label-helm/files/lib/hlm-label.directive.ts.template +2 -47
  72. package/src/generators/ui/libs/ui-menu-helm/files/lib/hlm-menu-bar-item.directive.ts.template +1 -1
  73. package/src/generators/ui/libs/ui-menu-helm/files/lib/hlm-menu-bar.component.ts.template +1 -1
  74. package/src/generators/ui/libs/ui-menu-helm/files/lib/hlm-menu-item-sub-indicator.component.ts.template +3 -3
  75. package/src/generators/ui/libs/ui-menu-helm/files/lib/hlm-menu-item.directive.ts.template +16 -19
  76. package/src/generators/ui/libs/ui-menu-helm/files/lib/hlm-menu-label.component.ts.template +9 -9
  77. package/src/generators/ui/libs/ui-menu-helm/files/lib/hlm-menu-separator.component.ts.template +2 -2
  78. package/src/generators/ui/libs/ui-menu-helm/files/lib/hlm-menu-shortcut.component.ts.template +1 -1
  79. package/src/generators/ui/libs/ui-menu-helm/files/lib/hlm-menu.component.ts.template +4 -8
  80. package/src/generators/ui/libs/ui-progress-helm/files/lib/hlm-progress-indicator.directive.ts.template +1 -1
  81. package/src/generators/ui/libs/ui-progress-helm/files/lib/hlm-progress.directive.ts.template +1 -1
  82. package/src/generators/ui/libs/ui-radio-group-helm/files/lib/hlm-radio-group.component.ts.template +2 -1
  83. package/src/generators/ui/libs/ui-radio-group-helm/files/lib/hlm-radio-indicator.component.ts.template +7 -8
  84. package/src/generators/ui/libs/ui-radio-group-helm/files/lib/hlm-radio.component.ts.template +2 -7
  85. package/src/generators/ui/libs/ui-select-helm/files/lib/hlm-select-label.directive.ts.template +1 -1
  86. package/src/generators/ui/libs/ui-select-helm/files/lib/hlm-select-option.component.ts.template +4 -7
  87. package/src/generators/ui/libs/ui-select-helm/files/lib/hlm-select-scroll-down.component.ts.template +10 -3
  88. package/src/generators/ui/libs/ui-select-helm/files/lib/hlm-select-scroll-up.component.ts.template +10 -3
  89. package/src/generators/ui/libs/ui-select-helm/files/lib/hlm-select-trigger.component.ts.template +8 -14
  90. package/src/generators/ui/libs/ui-select-helm/files/lib/hlm-select-value.directive.ts.template +1 -4
  91. package/src/generators/ui/libs/ui-sheet-helm/files/lib/hlm-sheet-close.directive.ts.template +1 -1
  92. package/src/generators/ui/libs/ui-sheet-helm/files/lib/hlm-sheet-content.component.ts.template +5 -5
  93. package/src/generators/ui/libs/ui-sheet-helm/files/lib/hlm-sheet-description.directive.ts.template +1 -1
  94. package/src/generators/ui/libs/ui-sheet-helm/files/lib/hlm-sheet-footer.component.ts.template +1 -3
  95. package/src/generators/ui/libs/ui-sheet-helm/files/lib/hlm-sheet-header.component.ts.template +1 -1
  96. package/src/generators/ui/libs/ui-sheet-helm/files/lib/hlm-sheet-overlay.directive.ts.template +1 -1
  97. package/src/generators/ui/libs/ui-sheet-helm/files/lib/hlm-sheet-title.directive.ts.template +1 -1
  98. package/src/generators/ui/libs/ui-slider-helm/files/lib/hlm-slider.component.ts.template +3 -3
  99. package/src/generators/ui/libs/ui-switch-helm/files/lib/hlm-switch-thumb.directive.ts.template +1 -1
  100. package/src/generators/ui/libs/ui-switch-helm/files/lib/hlm-switch.component.ts.template +1 -2
  101. package/src/generators/ui/libs/ui-tabs-helm/files/lib/hlm-tabs-list.component.ts.template +1 -1
  102. package/src/generators/ui/libs/ui-tabs-helm/files/lib/hlm-tabs-trigger.directive.ts.template +2 -2
  103. package/src/generators/ui/libs/ui-tabs-helm/files/lib/hlm-tabs.component.ts.template +9 -1
  104. package/src/generators/ui/libs/ui-toggle-group-helm/files/lib/hlm-toggle-group.directive.ts.template +8 -8
  105. package/src/generators/ui/libs/ui-toggle-group-helm/files/lib/hlm-toggle-item.directive.ts.template +15 -14
  106. package/src/generators/ui/libs/ui-tooltip-helm/files/lib/hlm-tooltip-trigger.directive.ts.template +2 -2
  107. package/src/generators/ui/supported-ui-libraries.json +47 -47
  108. package/src/generators/theme/libs/supported-theme-generator-map.d.ts +0 -17
  109. package/src/generators/theme/libs/supported-theme-generator-map.js +0 -584
  110. package/src/generators/theme/libs/supported-theme-generator-map.js.map +0 -1
@@ -3,13 +3,10 @@ import { hlm } from '@spartan-ng/brain/core';
3
3
  import { type VariantProps, cva } from 'class-variance-authority';
4
4
  import type { ClassValue } from 'clsx';
5
5
 
6
- export const cardVariants = cva(
7
- 'rounded-lg border border-border bg-card focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-card-foreground shadow-sm',
8
- {
9
- variants: {},
10
- defaultVariants: {},
11
- },
12
- );
6
+ export const cardVariants = cva('bg-card text-card-foreground flex flex-col gap-6 rounded-xl border py-6 shadow-sm', {
7
+ variants: {},
8
+ defaultVariants: {},
9
+ });
13
10
  export type CardVariants = VariantProps<typeof cardVariants>;
14
11
 
15
12
  @Directive({
@@ -1,3 +1,4 @@
1
+ import { BooleanInput } from '@angular/cdk/coercion';
1
2
  import {
2
3
  ChangeDetectionStrategy,
3
4
  Component,
@@ -41,15 +42,20 @@ export const HLM_CHECKBOX_VALUE_ACCESSOR = {
41
42
  (changed)="_handleChange()"
42
43
  (touched)="_onTouched?.()"
43
44
  >
44
- <ng-icon [class]="_computedIconClass()" hlm size="sm" name="lucideCheck" />
45
+ @if (checked()) {
46
+ <span class="flex items-center justify-center text-current transition-none">
47
+ <ng-icon hlm size="14px" name="lucideCheck" />
48
+ </span>
49
+ }
45
50
  </brn-checkbox>
46
51
  `,
47
52
  host: {
48
- class: 'contents',
53
+ class: 'contents peer',
49
54
  '[attr.id]': 'null',
50
55
  '[attr.aria-label]': 'null',
51
56
  '[attr.aria-labelledby]': 'null',
52
57
  '[attr.aria-describedby]': 'null',
58
+ '[attr.data-disabled]': 'state().disabled() ? "" : null',
53
59
  },
54
60
  providers: [HLM_CHECKBOX_VALUE_ACCESSOR],
55
61
  viewProviders: [provideIcons({ lucideCheck })],
@@ -60,17 +66,12 @@ export class HlmCheckboxComponent implements ControlValueAccessor {
60
66
 
61
67
  protected readonly _computedClass = computed(() =>
62
68
  hlm(
63
- 'group inline-flex border border-foreground shrink-0 cursor-pointer items-center rounded-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring' +
64
- ' focus-visible:ring-offset-2 focus-visible:ring-offset-background data-[state=checked]:text-background data-[state=checked]:bg-primary data-[state=unchecked]:bg-background',
69
+ 'peer border-input dark:bg-input/30 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground dark:data-[state=checked]:bg-primary data-[state=checked]:border-primary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive size-4 shrink-0 rounded-[4px] border shadow-xs transition-shadow outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 cursor-default',
65
70
  this.userClass(),
66
71
  this.state().disabled() ? 'cursor-not-allowed opacity-50' : '',
67
72
  ),
68
73
  );
69
74
 
70
- protected readonly _computedIconClass = computed(() =>
71
- hlm('leading-none group-data-[state=unchecked]:opacity-0', this.checked() === 'indeterminate' ? 'opacity-50' : ''),
72
- );
73
-
74
75
  /** Used to set the id on the underlying brn element. */
75
76
  public readonly id = input<string | null>(null);
76
77
 
@@ -90,10 +91,10 @@ export class HlmCheckboxComponent implements ControlValueAccessor {
90
91
  public readonly name = input<string | null>(null);
91
92
 
92
93
  /** Whether the checkbox is required. */
93
- public readonly required = input(false, { transform: booleanAttribute });
94
+ public readonly required = input<boolean, BooleanInput>(false, { transform: booleanAttribute });
94
95
 
95
96
  /** Whether the checkbox is disabled. */
96
- public readonly disabled = input(false, { transform: booleanAttribute });
97
+ public readonly disabled = input<boolean, BooleanInput>(false, { transform: booleanAttribute });
97
98
 
98
99
  protected readonly state = computed(() => ({
99
100
  disabled: signal(this.disabled()),
@@ -21,7 +21,7 @@ export class HlmCommandDialogDirective {
21
21
  public readonly userClass = input<ClassValue>('', { alias: 'class' });
22
22
  protected _computedClass = computed(() =>
23
23
  hlm(
24
- '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-[state=closed]:slide-out-to-top-[2%] data-[state=open]:slide-in-from-top-[2%]',
24
+ '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-[state=closed]:slide-out-to-top-[2%] data-[state=open]:slide-in-from-top-[2%]',
25
25
  this.userClass(),
26
26
  ),
27
27
  );
@@ -16,6 +16,6 @@ export class HlmCommandGroupLabelComponent {
16
16
 
17
17
  /*** The styles to apply */
18
18
  protected readonly _computedClass = computed(() =>
19
- hlm('font-medium px-2 py-1.5 text-muted-foreground text-xs', this.userClass()),
19
+ hlm('text-muted-foreground px-2 py-1.5 text-xs font-medium', this.userClass()),
20
20
  );
21
21
  }
@@ -22,6 +22,6 @@ export class HlmCommandGroupComponent {
22
22
 
23
23
  /*** The styles to apply */
24
24
  protected readonly _computedClass = computed(() =>
25
- hlm('flex flex-col overflow-hidden p-1 text-foreground data-[hidden]:hidden', this.userClass()),
25
+ hlm('text-foreground overflow-hidden p-1 block data-[hidden]:hidden', this.userClass()),
26
26
  );
27
27
  }
@@ -1,11 +1,18 @@
1
- import { Directive } from '@angular/core';
1
+ import { computed, Directive, input } from '@angular/core';
2
+ import { hlm } from '@spartan-ng/brain/core';
2
3
  import { provideHlmIconConfig } from '@spartan-ng/helm/icon';
4
+ import { ClassValue } from 'clsx';
3
5
 
4
6
  @Directive({
5
7
  selector: '[hlmCommandIcon]',
6
8
  host: {
7
- class: 'inline-flex mr-2 w-4 h-4',
9
+ '[class]': '_computedClass()',
8
10
  },
9
11
  providers: [provideHlmIconConfig({ size: 'sm' })],
10
12
  })
11
- export class HlmCommandIconDirective {}
13
+ export class HlmCommandIconDirective {
14
+ public readonly userClass = input<ClassValue>('', { alias: 'class' });
15
+ protected readonly _computedClass = computed(() =>
16
+ hlm('text-muted-foreground pointer-events-none shrink-0', this.userClass()),
17
+ );
18
+ }
@@ -38,7 +38,7 @@ export class HlmCommandItemComponent {
38
38
  /*** The styles to apply */
39
39
  protected readonly _computedClass = computed(() =>
40
40
  hlm(
41
- 'text-start aria-selected:bg-accent aria-selected:text-accent-foreground cursor-default disabled:opacity-50 disabled:pointer-events-none hover:bg-accent/50 items-center outline-none px-2 py-1.5 relative flex rounded-sm select-none text-sm data-[hidden]:hidden',
41
+ 'data-[selected]:bg-accent data-[selected=true]:text-accent-foreground [&>ng-icon]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&>ng-icon]:pointer-events-none [&>ng-icon]:shrink-0 [&>ng-icon]:text-base w-full',
42
42
  this.userClass(),
43
43
  ),
44
44
  );
@@ -22,6 +22,6 @@ export class HlmCommandListComponent {
22
22
 
23
23
  /** The styles to apply */
24
24
  protected readonly _computedClass = computed(() =>
25
- hlm('max-h-[300px] overflow-x-hidden overflow-y-auto', this.userClass()),
25
+ hlm('flex flex-col max-h-[300px] scroll-py-1 overflow-x-hidden overflow-y-auto', this.userClass()),
26
26
  );
27
27
  }
@@ -18,7 +18,7 @@ export class HlmCommandSearchInputComponent {
18
18
  /*** The styles to apply */
19
19
  protected readonly _computedClass = computed(() =>
20
20
  hlm(
21
- 'bg-transparent disabled:cursor-not-allowed disabled:opacity-50 h-11 outline-none placeholder:text-muted-foreground py-3 text-sm w-full',
21
+ 'placeholder:text-muted-foreground flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-none disabled:cursor-not-allowed disabled:opacity-50',
22
22
  this.userClass(),
23
23
  ),
24
24
  );
@@ -19,6 +19,6 @@ export class HlmCommandSearchComponent {
19
19
 
20
20
  /*** The styles to apply */
21
21
  protected readonly _computedClass = computed(() =>
22
- hlm('relative [&_ng-icon]:flex-none border-b border-border flex items-center px-3 space-x-2', this.userClass()),
22
+ hlm('flex h-9 items-center gap-2 border-b px-3 [&>_ng-icon]:flex-none [&>_ng-icon]:opacity-50', this.userClass()),
23
23
  );
24
24
  }
@@ -15,5 +15,5 @@ export class HlmCommandSeparatorComponent {
15
15
  public readonly userClass = input<string>('', { alias: 'class' });
16
16
 
17
17
  /*** The styles to apply */
18
- protected readonly _computedClass = computed(() => hlm('h-px block w-full border-b border-border', this.userClass()));
18
+ protected readonly _computedClass = computed(() => hlm('bg-border -mx-1 h-px', this.userClass()));
19
19
  }
@@ -1,11 +1,18 @@
1
- import { ChangeDetectionStrategy, Component } from '@angular/core';
1
+ import { ChangeDetectionStrategy, Component, computed, input } from '@angular/core';
2
+ import { hlm } from '@spartan-ng/brain/core';
3
+ import { ClassValue } from 'clsx';
2
4
 
3
5
  @Component({
4
6
  selector: 'hlm-command-shortcut',
5
7
  template: '<ng-content />',
6
8
  host: {
7
- class: 'font-light ml-auto opacity-60 text-xs tracking-widest',
9
+ '[class]': '_computedClass()',
8
10
  },
9
11
  changeDetection: ChangeDetectionStrategy.OnPush,
10
12
  })
11
- export class HlmCommandShortcutComponent {}
13
+ export class HlmCommandShortcutComponent {
14
+ public readonly userClass = input<ClassValue>('', { alias: 'class' });
15
+ protected readonly _computedClass = computed(() =>
16
+ hlm('text-muted-foreground ml-auto text-xs tracking-widest', this.userClass()),
17
+ );
18
+ }
@@ -25,9 +25,6 @@ export class HlmCommandComponent {
25
25
 
26
26
  /*** The styles to apply */
27
27
  protected readonly _computedClass = computed(() =>
28
- hlm(
29
- 'w-96 bg-popover border border-border flex flex-col h-full overflow-hidden rounded-md text-popover-foreground',
30
- this.userClass(),
31
- ),
28
+ hlm('bg-popover text-popover-foreground flex h-full w-full flex-col overflow-hidden rounded-md', this.userClass()),
32
29
  );
33
30
  }
@@ -11,7 +11,7 @@ import {
11
11
  output,
12
12
  signal,
13
13
  } from '@angular/core';
14
- import { NG_VALUE_ACCESSOR } from '@angular/forms';
14
+ import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
15
15
  import { NgIcon, provideIcons } from '@ng-icons/core';
16
16
  import { lucideCalendar } from '@ng-icons/lucide';
17
17
  import { hlm } from '@spartan-ng/brain/core';
@@ -75,7 +75,7 @@ export const HLM_DATE_PICKER_MUTLI_VALUE_ACCESSOR = {
75
75
  },
76
76
  changeDetection: ChangeDetectionStrategy.OnPush,
77
77
  })
78
- export class HlmDatePickerMultiComponent<T> {
78
+ export class HlmDatePickerMultiComponent<T> implements ControlValueAccessor {
79
79
  private readonly _config = injectHlmDatePickerMultiConfig<T>();
80
80
 
81
81
  public readonly userClass = input<ClassValue>('', { alias: 'class' });
@@ -10,9 +10,9 @@ import {
10
10
  output,
11
11
  signal,
12
12
  } from '@angular/core';
13
- import { NG_VALUE_ACCESSOR } from '@angular/forms';
13
+ import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
14
14
  import { NgIcon, provideIcons } from '@ng-icons/core';
15
- import { lucideCalendar } from '@ng-icons/lucide';
15
+ import { lucideChevronDown } from '@ng-icons/lucide';
16
16
  import { hlm } from '@spartan-ng/brain/core';
17
17
  import { BrnDialogState } from '@spartan-ng/brain/dialog';
18
18
  import { type ChangeFn, type TouchFn } from '@spartan-ng/brain/forms';
@@ -40,12 +40,10 @@ export const HLM_DATE_PICKER_VALUE_ACCESSOR = {
40
40
  HlmPopoverContentDirective,
41
41
  HlmCalendarComponent,
42
42
  ],
43
- providers: [HLM_DATE_PICKER_VALUE_ACCESSOR, provideIcons({ lucideCalendar })],
43
+ providers: [HLM_DATE_PICKER_VALUE_ACCESSOR, provideIcons({ lucideChevronDown })],
44
44
  template: `
45
45
  <brn-popover sideOffset="5" [state]="popoverState()" (stateChanged)="popoverState.set($event)">
46
46
  <button type="button" [class]="_computedClass()" [disabled]="state().disabled()" brnPopoverTrigger>
47
- <ng-icon hlm size="sm" name="lucideCalendar" />
48
-
49
47
  <span class="truncate">
50
48
  @if (formattedDate(); as formattedDate) {
51
49
  {{ formattedDate }}
@@ -53,6 +51,8 @@ export const HLM_DATE_PICKER_VALUE_ACCESSOR = {
53
51
  <ng-content />
54
52
  }
55
53
  </span>
54
+
55
+ <ng-icon hlm size="sm" name="lucideChevronDown" />
56
56
  </button>
57
57
 
58
58
  <div hlmPopoverContent class="w-auto p-0" *brnPopoverContent="let ctx">
@@ -72,13 +72,13 @@ export const HLM_DATE_PICKER_VALUE_ACCESSOR = {
72
72
  },
73
73
  changeDetection: ChangeDetectionStrategy.OnPush,
74
74
  })
75
- export class HlmDatePickerComponent<T> {
75
+ export class HlmDatePickerComponent<T> implements ControlValueAccessor {
76
76
  private readonly _config = injectHlmDatePickerConfig<T>();
77
77
 
78
78
  public readonly userClass = input<ClassValue>('', { alias: 'class' });
79
79
  protected readonly _computedClass = computed(() =>
80
80
  hlm(
81
- 'inline-flex items-center gap-2 whitespace-nowrap rounded-md text-sm ring-offset-background transition-colors border border-input bg-background hover:bg-accent hover:text-accent-foreground h-10 px-4 py-2 w-[280px] justify-start text-left font-normal',
81
+ 'inline-flex items-center gap-2 whitespace-nowrap rounded-md text-sm transition-all disabled:pointer-events-none disabled:opacity-50 ring-offset-background transition-colors border border-input bg-background hover:bg-accent dark:bg-input/30 dark:hover:bg-input/50 hover:text-accent-foreground h-9 px-3 py-2 w-[280px] justify-start text-left font-normal cursor-default justify-between',
82
82
  'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',
83
83
  'disabled:pointer-events-none disabled:opacity-50',
84
84
  '[&_ng-icon]:pointer-events-none [&_ng-icon]:shrink-0',
@@ -3,7 +3,7 @@ import { hlm, injectCustomClassSettable } from '@spartan-ng/brain/core';
3
3
  import type { ClassValue } from 'clsx';
4
4
 
5
5
  export const hlmDialogOverlayClass =
6
- 'bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0';
6
+ 'bg-black/50 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0';
7
7
 
8
8
  @Directive({
9
9
  selector: '[hlmDialogOverlay],brn-dialog-overlay[hlm]',
@@ -1,10 +1,17 @@
1
- import { Directive } from '@angular/core';
1
+ import { computed, Directive, input } from '@angular/core';
2
+ import { hlm } from '@spartan-ng/brain/core';
3
+ import { ClassValue } from 'clsx';
2
4
 
3
5
  @Directive({
4
6
  // eslint-disable-next-line @angular-eslint/directive-selector
5
7
  selector: 'hlm-error',
6
8
  host: {
7
- class: 'block text-destructive text-sm font-medium',
9
+ '[class]': '_computedClass()',
8
10
  },
9
11
  })
10
- export class HlmErrorDirective {}
12
+ export class HlmErrorDirective {
13
+ public readonly userClass = input<ClassValue>('', { alias: 'class' });
14
+ protected readonly _computedClass = computed(() =>
15
+ hlm('block text-destructive text-sm font-medium', this.userClass()),
16
+ );
17
+ }
@@ -1,5 +1,15 @@
1
- import { ChangeDetectionStrategy, Component, computed, contentChild, contentChildren, effect } from '@angular/core';
1
+ import {
2
+ ChangeDetectionStrategy,
3
+ Component,
4
+ computed,
5
+ contentChild,
6
+ contentChildren,
7
+ effect,
8
+ input,
9
+ } from '@angular/core';
10
+ import { hlm } from '@spartan-ng/brain/core';
2
11
  import { BrnFormFieldControl } from '@spartan-ng/brain/form-field';
12
+ import { ClassValue } from 'clsx';
3
13
  import { HlmErrorDirective } from './hlm-error.directive';
4
14
 
5
15
  @Component({
@@ -17,11 +27,13 @@ import { HlmErrorDirective } from './hlm-error.directive';
17
27
  }
18
28
  `,
19
29
  host: {
20
- class: 'space-y-2 block',
30
+ '[class]': '_computedClass()',
21
31
  },
22
32
  changeDetection: ChangeDetectionStrategy.OnPush,
23
33
  })
24
34
  export class HlmFormFieldComponent {
35
+ public readonly userClass = input<ClassValue>('', { alias: 'class' });
36
+ protected readonly _computedClass = computed(() => hlm('space-y-2 block', this.userClass()));
25
37
  public readonly control = contentChild(BrnFormFieldControl);
26
38
 
27
39
  public readonly errorChildren = contentChildren(HlmErrorDirective);
@@ -1,10 +1,15 @@
1
- import { Directive } from '@angular/core';
1
+ import { computed, Directive, input } from '@angular/core';
2
+ import { hlm } from '@spartan-ng/brain/core';
3
+ import { ClassValue } from 'clsx';
2
4
 
3
5
  @Directive({
4
6
  // eslint-disable-next-line @angular-eslint/directive-selector
5
7
  selector: 'hlm-hint',
6
8
  host: {
7
- class: 'block text-sm text-muted-foreground',
9
+ '[class]': '_computedClass()',
8
10
  },
9
11
  })
10
- export class HlmHintDirective {}
12
+ export class HlmHintDirective {
13
+ public readonly userClass = input<ClassValue>('', { alias: 'class' });
14
+ protected readonly _computedClass = computed(() => hlm('block text-sm text-muted-foreground', this.userClass()));
15
+ }
@@ -1,12 +1,10 @@
1
1
  import { NgModule } from '@angular/core';
2
- import { HlmInputErrorDirective } from './lib/hlm-input-error.directive';
3
2
  import { HlmInputDirective } from './lib/hlm-input.directive';
4
3
 
5
- export * from './lib/hlm-input-error.directive';
6
4
  export * from './lib/hlm-input.directive';
7
5
 
8
6
  @NgModule({
9
- imports: [HlmInputDirective, HlmInputErrorDirective],
10
- exports: [HlmInputDirective, HlmInputErrorDirective],
7
+ imports: [HlmInputDirective],
8
+ exports: [HlmInputDirective],
11
9
  })
12
10
  export class HlmInputModule {}
@@ -1,39 +1,32 @@
1
1
  import {
2
+ computed,
2
3
  Directive,
3
4
  type DoCheck,
4
- Injector,
5
- computed,
6
5
  effect,
7
6
  forwardRef,
8
7
  inject,
8
+ Injector,
9
9
  input,
10
- signal,
10
+ linkedSignal,
11
11
  untracked,
12
12
  } from '@angular/core';
13
13
  import { FormGroupDirective, NgControl, NgForm } from '@angular/forms';
14
14
  import { hlm } from '@spartan-ng/brain/core';
15
15
  import { BrnFormFieldControl } from '@spartan-ng/brain/form-field';
16
16
  import { ErrorStateMatcher, ErrorStateTracker } from '@spartan-ng/brain/forms';
17
-
18
- import { type VariantProps, cva } from 'class-variance-authority';
17
+ import { cva, VariantProps } from 'class-variance-authority';
19
18
  import type { ClassValue } from 'clsx';
20
19
 
21
20
  export const inputVariants = cva(
22
- 'flex rounded-md border font-normal border-input bg-transparent text-base md:text-sm ring-offset-background file:border-0 file:text-foreground file:bg-transparent file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50',
21
+ 'file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input flex h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]',
23
22
  {
24
23
  variants: {
25
- size: {
26
- default: 'h-10 py-2 px-4 file:max-md:py-0',
27
- sm: 'h-9 px-3 file:md:py-2 file:max-md:py-1.5',
28
- lg: 'h-11 px-8 file:md:py-3 file:max-md:py-2.5',
29
- },
30
24
  error: {
31
- auto: '[&.ng-invalid.ng-touched]:text-destructive [&.ng-invalid.ng-touched]:border-destructive [&.ng-invalid.ng-touched]:focus-visible:ring-destructive',
32
- true: 'text-destructive border-destructive focus-visible:ring-destructive',
25
+ auto: '[&.ng-invalid.ng-touched]:text-destructive/20 dark:[&.ng-invalid.ng-touched]:text-destructive/40 [&.ng-invalid.ng-touched]:border-destructive [&.ng-invalid.ng-touched]:focus-visible:ring-destructive',
26
+ true: 'text-destructive/20 dark:text-destructive/40 border-destructive focus-visible:ring-destructive',
33
27
  },
34
28
  },
35
29
  defaultVariants: {
36
- size: 'default',
37
30
  error: 'auto',
38
31
  },
39
32
  },
@@ -53,17 +46,13 @@ type InputVariants = VariantProps<typeof inputVariants>;
53
46
  ],
54
47
  })
55
48
  export class HlmInputDirective implements BrnFormFieldControl, DoCheck {
56
- public readonly size = input<InputVariants['size']>('default');
57
-
58
49
  public readonly error = input<InputVariants['error']>('auto');
59
50
 
60
- protected readonly state = computed(() => ({
61
- error: signal(this.error()),
62
- }));
51
+ protected readonly state = linkedSignal(() => ({ error: this.error() }));
63
52
 
64
53
  public readonly userClass = input<ClassValue>('', { alias: 'class' });
65
54
  protected readonly _computedClass = computed(() =>
66
- hlm(inputVariants({ size: this.size(), error: this.state().error() }), this.userClass()),
55
+ hlm(inputVariants({ error: this.state().error }), this.userClass()),
67
56
  );
68
57
 
69
58
  private readonly _injector = inject(Injector);
@@ -103,6 +92,6 @@ export class HlmInputDirective implements BrnFormFieldControl, DoCheck {
103
92
  }
104
93
 
105
94
  setError(error: InputVariants['error']) {
106
- this.state().error.set(error);
95
+ this.state.set({ error });
107
96
  }
108
97
  }
@@ -1,6 +1,6 @@
1
1
  import { ChangeDetectionStrategy, Component, computed, input } from '@angular/core';
2
2
  import { NgIcon, provideIcons } from '@ng-icons/core';
3
- import { lucideDot } from '@ng-icons/lucide';
3
+ import { lucideMinus } from '@ng-icons/lucide';
4
4
  import { hlm } from '@spartan-ng/brain/core';
5
5
  import { HlmIconDirective } from '@spartan-ng/helm/icon';
6
6
  import { type ClassValue } from 'clsx';
@@ -8,9 +8,9 @@ import { type ClassValue } from 'clsx';
8
8
  @Component({
9
9
  selector: 'hlm-input-otp-separator',
10
10
  imports: [HlmIconDirective, NgIcon],
11
- providers: [provideIcons({ lucideDot })],
11
+ providers: [provideIcons({ lucideMinus })],
12
12
  template: `
13
- <ng-icon hlm name="lucideDot" />
13
+ <ng-icon hlm name="lucideMinus" />
14
14
  `,
15
15
  host: {
16
16
  role: 'separator',
@@ -19,7 +19,7 @@ import { type ClassValue } from 'clsx';
19
19
  changeDetection: ChangeDetectionStrategy.OnPush,
20
20
  })
21
21
  export class HlmInputOtpSeparatorComponent {
22
- public readonly userClass = input<ClassValue>('', { alias: 'class' });
22
+ public readonly userClass = input<ClassValue>('inline-flex', { alias: 'class' });
23
23
 
24
24
  protected readonly _computedClass = computed(() => hlm(this.userClass()));
25
25
  }
@@ -26,8 +26,8 @@ export class HlmInputOtpSlotComponent {
26
26
 
27
27
  protected readonly _computedClass = computed(() =>
28
28
  hlm(
29
- 'relative flex h-10 w-10 items-center justify-center border-y border-r border-input text-sm transition-all first:rounded-l-md first:border-l last:rounded-r-md',
30
- 'has-[brn-input-otp-slot[data-active="true"]]:z-10 has-[brn-input-otp-slot[data-active="true"]]:ring-2 has-[brn-input-otp-slot[data-active="true"]]:ring-ring has-[brn-input-otp-slot[data-active="true"]]:ring-offset-background',
29
+ 'dark:bg-input/30 border-input relative flex h-9 w-9 items-center justify-center border-y border-r text-sm shadow-xs transition-all outline-none first:rounded-l-md first:border-l last:rounded-r-md',
30
+ 'has-[brn-input-otp-slot[data-active="true"]]:border-ring has-[brn-input-otp-slot[data-active="true"]]:z-10 has-[brn-input-otp-slot[data-active="true"]]:ring-[3px] has-[brn-input-otp-slot[data-active="true"]]:ring-ring/50',
31
31
  this.userClass(),
32
32
  ),
33
33
  );
@@ -12,6 +12,6 @@ export class HlmInputOtpDirective {
12
12
  public readonly userClass = input<ClassValue>('', { alias: 'class' });
13
13
 
14
14
  protected readonly _computedClass = computed(() =>
15
- hlm('flex items-center gap-2 has-[:disabled]:opacity-50', this.userClass()),
15
+ hlm('flex items-center gap-2 has-disabled:opacity-50', this.userClass()),
16
16
  );
17
17
  }
@@ -1,34 +1,8 @@
1
- import { Directive, computed, inject, input, signal } from '@angular/core';
1
+ import { Directive, computed, input } from '@angular/core';
2
2
  import { hlm } from '@spartan-ng/brain/core';
3
3
  import { BrnLabelDirective } from '@spartan-ng/brain/label';
4
- import { type VariantProps, cva } from 'class-variance-authority';
5
4
  import type { ClassValue } from 'clsx';
6
5
 
7
- export const labelVariants = cva(
8
- 'text-sm font-medium leading-none [&>[hlmInput]]:my-1 [&:has([hlmInput]:disabled)]:cursor-not-allowed [&:has([hlmInput]:disabled)]:opacity-70',
9
- {
10
- variants: {
11
- variant: {
12
- default: '',
13
- },
14
- error: {
15
- auto: '[&:has([hlmInput].ng-invalid.ng-touched)]:text-destructive',
16
- true: 'text-destructive',
17
- },
18
- disabled: {
19
- auto: '[&:has([hlmInput]:disabled)]:opacity-70',
20
- true: 'opacity-70',
21
- false: '',
22
- },
23
- },
24
- defaultVariants: {
25
- variant: 'default',
26
- error: 'auto',
27
- },
28
- },
29
- );
30
- export type LabelVariants = VariantProps<typeof labelVariants>;
31
-
32
6
  @Directive({
33
7
  selector: '[hlmLabel]',
34
8
  hostDirectives: [
@@ -42,31 +16,12 @@ export type LabelVariants = VariantProps<typeof labelVariants>;
42
16
  },
43
17
  })
44
18
  export class HlmLabelDirective {
45
- private readonly _brn = inject(BrnLabelDirective, { host: true });
46
-
47
19
  public readonly userClass = input<ClassValue>('', { alias: 'class' });
48
20
 
49
- public readonly variant = input<LabelVariants['variant']>('default');
50
-
51
- public readonly error = input<LabelVariants['error']>('auto');
52
-
53
- protected readonly state = computed(() => ({
54
- error: signal(this.error()),
55
- }));
56
-
57
21
  protected readonly _computedClass = computed(() =>
58
22
  hlm(
59
- labelVariants({
60
- variant: this.variant(),
61
- error: this.state().error(),
62
- disabled: this._brn?.dataDisabled() ?? 'auto',
63
- }),
64
- '[&.ng-invalid.ng-touched]:text-destructive',
23
+ 'flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50 peer-data-[disabled]:cursor-not-allowed peer-data-[disabled]:opacity-50',
65
24
  this.userClass(),
66
25
  ),
67
26
  );
68
-
69
- setError(error: LabelVariants['error']): void {
70
- this.state().error.set(error);
71
- }
72
27
  }
@@ -14,7 +14,7 @@ export class HlmMenuBarItemDirective {
14
14
  public readonly userClass = input<ClassValue>('', { alias: 'class' });
15
15
  protected _computedClass = computed(() =>
16
16
  hlm(
17
- 'flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent focus:text-accent-foreground aria-expanded:bg-accent aria-expanded:text-accent-foreground',
17
+ 'focus:bg-accent focus:text-accent-foreground aria-expanded:bg-accent aria-expanded:text-accent-foreground flex items-center rounded-sm px-2 py-1 text-sm font-medium outline-none select-none',
18
18
  this.userClass(),
19
19
  ),
20
20
  );
@@ -15,6 +15,6 @@ import type { ClassValue } from 'clsx';
15
15
  export class HlmMenuBarComponent {
16
16
  public readonly userClass = input<ClassValue>('', { alias: 'class' });
17
17
  protected _computedClass = computed(() =>
18
- hlm('border-border flex h-10 items-center space-x-1 rounded-md border bg-background p-1', this.userClass()),
18
+ hlm('bg-background flex h-9 items-center gap-1 rounded-md border p-1 shadow-xs', this.userClass()),
19
19
  );
20
20
  }
@@ -3,14 +3,14 @@ import { NgIcon, provideIcons } from '@ng-icons/core';
3
3
  import { lucideChevronRight } from '@ng-icons/lucide';
4
4
  import { hlm } from '@spartan-ng/brain/core';
5
5
  import { HlmIconDirective } from '@spartan-ng/helm/icon';
6
- import type { ClassValue } from 'clsx';
6
+ import { ClassValue } from 'clsx';
7
7
 
8
8
  @Component({
9
9
  selector: 'hlm-menu-item-sub-indicator',
10
10
  providers: [provideIcons({ lucideChevronRight })],
11
11
  imports: [NgIcon, HlmIconDirective],
12
12
  template: `
13
- <ng-icon hlm size="none" class="h-full w-full" name="lucideChevronRight" />
13
+ <ng-icon hlm size="sm" name="lucideChevronRight" class="text-popover-foreground" />
14
14
  `,
15
15
  host: {
16
16
  '[class]': '_computedClass()',
@@ -19,5 +19,5 @@ import type { ClassValue } from 'clsx';
19
19
  })
20
20
  export class HlmMenuItemSubIndicatorComponent {
21
21
  public readonly userClass = input<ClassValue>('', { alias: 'class' });
22
- protected _computedClass = computed(() => hlm('inline-block ml-auto h-4 w-4', this.userClass()));
22
+ protected readonly _computedClass = computed(() => hlm('ml-auto size-4', this.userClass()));
23
23
  }