@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
@@ -11,7 +11,7 @@ export class HlmAlertDialogOverlayDirective {
11
11
  public readonly userClass = input<ClassValue>('', { alias: 'class' });
12
12
  protected readonly _computedClass = computed(() =>
13
13
  hlm(
14
- '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',
14
+ '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',
15
15
  this.userClass(),
16
16
  ),
17
17
  );
@@ -1,13 +1,7 @@
1
1
  import { Directive, computed, input } from '@angular/core';
2
2
  import { hlm } from '@spartan-ng/brain/core';
3
- import { type VariantProps, cva } from 'class-variance-authority';
4
3
  import type { ClassValue } from 'clsx';
5
4
 
6
- export const alertDescriptionVariants = cva('text-sm [&_p]:leading-relaxed', {
7
- variants: {},
8
- });
9
- export type AlertDescriptionVariants = VariantProps<typeof alertDescriptionVariants>;
10
-
11
5
  @Directive({
12
6
  selector: '[hlmAlertDesc],[hlmAlertDescription]',
13
7
  host: {
@@ -16,5 +10,10 @@ export type AlertDescriptionVariants = VariantProps<typeof alertDescriptionVaria
16
10
  })
17
11
  export class HlmAlertDescriptionDirective {
18
12
  public readonly userClass = input<ClassValue>('', { alias: 'class' });
19
- protected readonly _computedClass = computed(() => hlm(alertDescriptionVariants(), this.userClass()));
13
+ protected readonly _computedClass = computed(() =>
14
+ hlm(
15
+ 'text-muted-foreground col-start-2 grid justify-items-start gap-1 text-sm [&_p]:leading-relaxed',
16
+ this.userClass(),
17
+ ),
18
+ );
20
19
  }
@@ -1,13 +1,7 @@
1
1
  import { Directive, computed, input } from '@angular/core';
2
2
  import { hlm } from '@spartan-ng/brain/core';
3
- import { type VariantProps, cva } from 'class-variance-authority';
4
3
  import type { ClassValue } from 'clsx';
5
4
 
6
- export const alertTitleVariants = cva('mb-1 font-medium leading-none tracking-tight', {
7
- variants: {},
8
- });
9
- export type AlertTitleVariants = VariantProps<typeof alertTitleVariants>;
10
-
11
5
  @Directive({
12
6
  selector: '[hlmAlertTitle]',
13
7
  host: {
@@ -16,5 +10,7 @@ export type AlertTitleVariants = VariantProps<typeof alertTitleVariants>;
16
10
  })
17
11
  export class HlmAlertTitleDirective {
18
12
  public readonly userClass = input<ClassValue>('', { alias: 'class' });
19
- protected readonly _computedClass = computed(() => hlm(alertTitleVariants(), this.userClass()));
13
+ protected readonly _computedClass = computed(() =>
14
+ hlm('col-start-2 line-clamp-1 min-h-4 font-medium tracking-tight', this.userClass()),
15
+ );
20
16
  }
@@ -3,14 +3,14 @@ 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 alertVariants = cva(
7
- 'relative w-full rounded-lg border border-border p-4 [&>[hlmAlertIcon]]:absolute [&>[hlmAlertIcon]]:text-foreground [&>[hlmAlertIcon]]:left-4 [&>[hlmAlertIcon]]:top-4 [&>[hlmAlertIcon]+div]:translate-y-[-3px] [&>[hlmAlertIcon]~*]:pl-7',
6
+ const alertVariants = cva(
7
+ 'relative w-full rounded-lg border px-4 py-3 text-sm grid has-[>[hlmAlertIcon]]:grid-cols-[calc(var(--spacing)*4)_1fr] grid-cols-[0_1fr] has-[>[hlmAlertIcon]]:gap-x-3 gap-y-0.5 items-start [&>[hlmAlertIcon]]:size-4 [&>[hlmAlertIcon]]:translate-y-0.5 [&>[hlmAlertIcon]]:text-current',
8
8
  {
9
9
  variants: {
10
10
  variant: {
11
- default: 'bg-background text-foreground',
11
+ default: 'bg-card text-card-foreground',
12
12
  destructive:
13
- 'text-destructive border-destructive/50 dark:border-destructive [&>[hlmAlertIcon]]:text-destructive',
13
+ 'text-destructive bg-card [&>[hlmAlertIcon]]:text-current [&>[hlmAlertDescription]]:text-destructive/90 [&>[hlmAlertDesc]]:text-destructive/90',
14
14
  },
15
15
  },
16
16
  defaultVariants: {
@@ -18,6 +18,7 @@ export const alertVariants = cva(
18
18
  },
19
19
  },
20
20
  );
21
+
21
22
  export type AlertVariants = VariantProps<typeof alertVariants>;
22
23
 
23
24
  @Directive({
@@ -1,5 +1,5 @@
1
1
  import { Directive, computed, inject } from '@angular/core';
2
- import { BrnAvatarFallbackDirective, hexColorFor, isBright } from '@spartan-ng/brain/avatar';
2
+ import { BrnAvatarFallbackDirective } from '@spartan-ng/brain/avatar';
3
3
  import { hlm } from '@spartan-ng/brain/core';
4
4
 
5
5
  @Directive({
@@ -8,32 +8,17 @@ import { hlm } from '@spartan-ng/brain/core';
8
8
  hostDirectives: [
9
9
  {
10
10
  directive: BrnAvatarFallbackDirective,
11
- inputs: ['class:class', 'autoColor:autoColor'],
11
+ inputs: ['class'],
12
12
  },
13
13
  ],
14
14
  host: {
15
15
  '[class]': '_computedClass()',
16
- '[style.backgroundColor]': "_hex() || ''",
17
16
  },
18
17
  })
19
18
  export class HlmAvatarFallbackDirective {
20
19
  private readonly _brn = inject(BrnAvatarFallbackDirective);
21
- protected readonly _hex = computed(() => {
22
- if (!this._brn.autoColor() || !this._brn.getTextContent()) return;
23
- return hexColorFor(this._brn.getTextContent());
24
- });
25
-
26
- private readonly _autoColorTextCls = computed(() => {
27
- const hex = this._hex();
28
- if (!hex) return;
29
- return `${isBright(hex) ? 'text-black' : 'text-white'}`;
30
- });
31
20
 
32
21
  protected readonly _computedClass = computed(() => {
33
- return hlm(
34
- 'flex h-full w-full items-center justify-center rounded-full',
35
- this._autoColorTextCls() ?? 'bg-muted',
36
- this._brn?.userClass(),
37
- );
22
+ return hlm('bg-muted flex size-full items-center justify-center rounded-full', this._brn?.userClass());
38
23
  });
39
24
  }
@@ -1,24 +1,8 @@
1
1
  import { ChangeDetectionStrategy, Component, ViewEncapsulation, computed, input } from '@angular/core';
2
2
  import { BrnAvatarComponent } from '@spartan-ng/brain/avatar';
3
3
  import { hlm } from '@spartan-ng/brain/core';
4
- import { type VariantProps, cva } from 'class-variance-authority';
5
4
  import type { ClassValue } from 'clsx';
6
5
 
7
- export const avatarVariants = cva('relative flex shrink-0 overflow-hidden rounded-full', {
8
- variants: {
9
- variant: {
10
- small: 'h-6 w-6 text-xs',
11
- medium: 'h-10 w-10',
12
- large: 'h-14 w-14 text-lg',
13
- },
14
- },
15
- defaultVariants: {
16
- variant: 'medium',
17
- },
18
- });
19
-
20
- export type AvatarVariants = VariantProps<typeof avatarVariants>;
21
-
22
6
  @Component({
23
7
  selector: 'hlm-avatar',
24
8
  changeDetection: ChangeDetectionStrategy.OnPush,
@@ -36,9 +20,8 @@ export type AvatarVariants = VariantProps<typeof avatarVariants>;
36
20
  })
37
21
  export class HlmAvatarComponent extends BrnAvatarComponent {
38
22
  public readonly userClass = input<ClassValue>('', { alias: 'class' });
39
- public readonly variant = input<AvatarVariants['variant']>('medium');
40
23
 
41
24
  protected readonly _computedClass = computed(() =>
42
- hlm(avatarVariants({ variant: this.variant() }), this.userClass()),
25
+ hlm('relative flex shrink-0 overflow-hidden rounded-full size-8', this.userClass()),
43
26
  );
44
27
  }
@@ -15,5 +15,5 @@ export class HlmAvatarImageDirective {
15
15
  public canShow = inject(BrnAvatarImageDirective).canShow;
16
16
 
17
17
  public readonly userClass = input<ClassValue>('', { alias: 'class' });
18
- protected _computedClass = computed(() => hlm('aspect-square object-cover h-full w-full', this.userClass()));
18
+ protected _computedClass = computed(() => hlm('aspect-square size-full', this.userClass()));
19
19
  }
@@ -3,8 +3,10 @@ import { HlmBadgeDirective } from './lib/hlm-badge.directive';
3
3
 
4
4
  export * from './lib/hlm-badge.directive';
5
5
 
6
+ export const HlmBadgeImports = [HlmBadgeDirective] as const;
7
+
6
8
  @NgModule({
7
- imports: [HlmBadgeDirective],
8
- exports: [HlmBadgeDirective],
9
+ imports: [...HlmBadgeImports],
10
+ exports: [...HlmBadgeImports],
9
11
  })
10
12
  export class HlmBadgeModule {}
@@ -1,49 +1,26 @@
1
- import type { BooleanInput } from '@angular/cdk/coercion';
2
- import { Directive, booleanAttribute, computed, input } from '@angular/core';
1
+ import { Directive, computed, input } from '@angular/core';
3
2
  import { hlm } from '@spartan-ng/brain/core';
4
3
  import { type VariantProps, cva } from 'class-variance-authority';
5
4
  import type { ClassValue } from 'clsx';
6
5
 
7
- export const badgeVariants = cva(
8
- 'inline-flex items-center border rounded-full px-2.5 py-0.5 font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2',
6
+ const badgeVariants = cva(
7
+ 'inline-flex items-center justify-center rounded-md border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden',
9
8
  {
10
9
  variants: {
11
10
  variant: {
12
- default: 'bg-primary border-transparent text-primary-foreground',
13
- secondary: 'bg-secondary border-transparent text-secondary-foreground',
14
- destructive: 'bg-destructive border-transparent text-destructive-foreground',
15
- outline: 'text-foreground border-border',
11
+ default: 'border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90',
12
+ secondary: 'border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90',
13
+ destructive:
14
+ 'border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60',
15
+ outline: 'text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground',
16
16
  },
17
- size: {
18
- default: 'text-xs',
19
- lg: 'text-sm',
20
- },
21
- static: { true: '', false: '' },
22
17
  },
23
- compoundVariants: [
24
- {
25
- variant: 'default',
26
- static: false,
27
- class: 'hover:bg-primary/80',
28
- },
29
- {
30
- variant: 'secondary',
31
- static: false,
32
- class: 'hover:bg-secondary/80',
33
- },
34
- {
35
- variant: 'destructive',
36
- static: false,
37
- class: 'hover:bg-destructive/80',
38
- },
39
- ],
40
18
  defaultVariants: {
41
19
  variant: 'default',
42
- size: 'default',
43
- static: false,
44
20
  },
45
21
  },
46
22
  );
23
+
47
24
  export type BadgeVariants = VariantProps<typeof badgeVariants>;
48
25
 
49
26
  @Directive({
@@ -53,12 +30,8 @@ export type BadgeVariants = VariantProps<typeof badgeVariants>;
53
30
  },
54
31
  })
55
32
  export class HlmBadgeDirective {
56
- protected readonly _computedClass = computed(() =>
57
- hlm(badgeVariants({ variant: this.variant(), size: this.size(), static: this.static() }), this.userClass()),
58
- );
33
+ protected readonly _computedClass = computed(() => hlm(badgeVariants({ variant: this.variant() }), this.userClass()));
59
34
 
60
35
  public readonly userClass = input<ClassValue>('', { alias: 'class' });
61
36
  public readonly variant = input<BadgeVariants['variant']>('default');
62
- public readonly static = input<BadgeVariants['static'], BooleanInput>(false, { transform: booleanAttribute });
63
- public readonly size = input<BadgeVariants['size']>('default');
64
37
  }
@@ -20,5 +20,5 @@ import type { ClassValue } from 'clsx';
20
20
  export class HlmBreadcrumbEllipsisComponent {
21
21
  public readonly userClass = input<ClassValue>('', { alias: 'class' });
22
22
 
23
- protected readonly _computedClass = computed(() => hlm('flex h-9 w-9 items-center justify-center', this.userClass()));
23
+ protected readonly _computedClass = computed(() => hlm('flex size-9 items-center justify-center', this.userClass()));
24
24
  }
@@ -31,5 +31,5 @@ export class HlmBreadcrumbLinkDirective {
31
31
  public readonly userClass = input<ClassValue>('', { alias: 'class' });
32
32
  public readonly link = input<RouterLink['routerLink']>();
33
33
 
34
- protected readonly _computedClass = computed(() => hlm('transition-colors hover:text-foreground', this.userClass()));
34
+ protected readonly _computedClass = computed(() => hlm('hover:text-foreground transition-colors', this.userClass()));
35
35
  }
@@ -12,6 +12,6 @@ export class HlmBreadcrumbListDirective {
12
12
  public readonly userClass = input<ClassValue>('', { alias: 'class' });
13
13
 
14
14
  protected readonly _computedClass = computed(() =>
15
- hlm('flex flex-wrap items-center gap-1.5 break-words text-sm text-muted-foreground sm:gap-2.5', this.userClass()),
15
+ hlm('text-muted-foreground flex flex-wrap items-center gap-1.5 text-sm break-words sm:gap-2.5', this.userClass()),
16
16
  );
17
17
  }
@@ -2,7 +2,7 @@ import { ChangeDetectionStrategy, Component, computed, input } from '@angular/co
2
2
  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
- import type { ClassValue } from 'clsx';
5
+ import { ClassValue } from 'clsx';
6
6
 
7
7
  @Component({
8
8
  // eslint-disable-next-line @angular-eslint/component-selector
@@ -11,12 +11,12 @@ import type { ClassValue } from 'clsx';
11
11
  providers: [provideIcons({ lucideChevronRight })],
12
12
  host: {
13
13
  role: 'presentation',
14
+ 'aria-hidden': 'true',
14
15
  '[class]': '_computedClass()',
15
- '[attr.aria-hidden]': 'true',
16
16
  },
17
17
  template: `
18
18
  <ng-content>
19
- <ng-icon name="lucideChevronRight" />
19
+ <ng-icon class="flex" size="14px" name="lucideChevronRight" />
20
20
  </ng-content>
21
21
  `,
22
22
  changeDetection: ChangeDetectionStrategy.OnPush,
@@ -24,7 +24,5 @@ import type { ClassValue } from 'clsx';
24
24
  export class HlmBreadcrumbSeparatorComponent {
25
25
  public readonly userClass = input<ClassValue>('', { alias: 'class' });
26
26
 
27
- protected readonly _computedClass = computed(() =>
28
- hlm('[&>ng-icon]:text-[14px] [&>ng-icon]:flex!', this.userClass()),
29
- );
27
+ protected readonly _computedClass = computed(() => hlm('size-3.5', this.userClass()));
30
28
  }
@@ -1,8 +1,7 @@
1
1
  import { NgModule } from '@angular/core';
2
2
  import { HlmButtonDirective } from './lib/hlm-button.directive';
3
- export * from './lib/hlm-button.token';
4
-
5
3
  export * from './lib/hlm-button.directive';
4
+ export * from './lib/hlm-button.token';
6
5
 
7
6
  @NgModule({
8
7
  imports: [HlmButtonDirective],
@@ -5,22 +5,24 @@ import type { ClassValue } from 'clsx';
5
5
  import { injectBrnButtonConfig } from './hlm-button.token';
6
6
 
7
7
  export const buttonVariants = cva(
8
- 'inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:opacity-50 disabled:pointer-events-none ring-offset-background',
8
+ 'inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_ng-icon]:pointer-events-none shrink-0 [&_ng-icon]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive cursor-default',
9
9
  {
10
10
  variants: {
11
11
  variant: {
12
- default: 'bg-primary text-primary-foreground hover:bg-primary/90',
13
- destructive: 'bg-destructive text-destructive-foreground hover:bg-destructive/90',
14
- outline: 'border border-input hover:bg-accent hover:text-accent-foreground',
15
- secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80',
16
- ghost: 'hover:bg-accent hover:text-accent-foreground',
17
- link: 'underline-offset-4 hover:underline text-primary',
12
+ default: 'bg-primary text-primary-foreground shadow-xs hover:bg-primary/90',
13
+ destructive:
14
+ 'bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60',
15
+ outline:
16
+ 'border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50',
17
+ secondary: 'bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80',
18
+ ghost: 'hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50',
19
+ link: 'text-primary underline-offset-4 hover:underline',
18
20
  },
19
21
  size: {
20
- default: 'h-10 py-2 px-4',
21
- sm: 'h-9 px-3 rounded-md',
22
- lg: 'h-11 px-8 rounded-md',
23
- icon: 'h-10 w-10',
22
+ default: 'h-9 px-4 py-2 has-[>ng-icon]:px-3',
23
+ sm: 'h-8 rounded-md gap-1.5 px-3 has-[>ng-icon]:px-2.5',
24
+ lg: 'h-10 rounded-md px-6 has-[>ng-icon]:px-4',
25
+ icon: 'size-9',
24
26
  },
25
27
  },
26
28
  defaultVariants: {
@@ -29,6 +31,7 @@ export const buttonVariants = cva(
29
31
  },
30
32
  },
31
33
  );
34
+
32
35
  export type ButtonVariants = VariantProps<typeof buttonVariants>;
33
36
 
34
37
  @Directive({
@@ -92,7 +92,7 @@ import type { ClassValue } from 'clsx';
92
92
  <th
93
93
  *brnCalendarWeekday="let weekday"
94
94
  scope="col"
95
- class="text-muted-foreground w-9 rounded-md text-[0.8rem] font-normal"
95
+ class="text-muted-foreground w-8 rounded-md text-[0.8rem] font-normal"
96
96
  [attr.aria-label]="i18n.labelWeekday(weekday)"
97
97
  >
98
98
  {{ i18n.formatWeekdayName(weekday) }}
@@ -105,7 +105,7 @@ import type { ClassValue } from 'clsx';
105
105
  @for (date of week; track dateAdapter.getTime(date)) {
106
106
  <td
107
107
  brnCalendarCell
108
- class="data-[selected]:data-[outside]:bg-accent/50 data-[selected]:bg-accent relative h-9 w-9 p-0 text-center text-sm focus-within:relative focus-within:z-20 first:data-[selected]:rounded-l-md last:data-[selected]:rounded-r-md [&:has([aria-selected].day-range-end)]:rounded-r-md"
108
+ class="data-[selected]:data-[outside]:bg-accent/50 data-[selected]:bg-accent relative h-8 w-8 p-0 text-center text-sm focus-within:relative focus-within:z-20 first:data-[selected]:rounded-l-md last:data-[selected]:rounded-r-md [&:has([aria-selected].day-range-end)]:rounded-r-md"
109
109
  >
110
110
  <button brnCalendarCellButton [date]="date" [class]="btnClass">
111
111
  {{ dateAdapter.getDate(date) }}
@@ -179,7 +179,7 @@ export class HlmCalendarMultiComponent<T> {
179
179
 
180
180
  protected readonly btnClass = hlm(
181
181
  buttonVariants({ variant: 'ghost' }),
182
- 'h-9 w-9 p-0 font-normal aria-selected:opacity-100',
182
+ 'size-8 p-0 font-normal aria-selected:opacity-100',
183
183
  'data-[outside]:text-muted-foreground data-[outside]:opacity-50 data-[outside]:aria-selected:bg-accent/50 data-[outside]:aria-selected:text-muted-foreground data-[outside]:aria-selected:opacity-30',
184
184
  'data-[today]:bg-accent data-[today]:text-accent-foreground',
185
185
  'data-[selected]:bg-primary data-[selected]:text-primary-foreground data-[selected]:hover:bg-primary data-[selected]:hover:text-primary-foreground data-[selected]:focus:bg-primary data-[selected]:focus:text-primary-foreground',
@@ -69,14 +69,14 @@ import type { ClassValue } from 'clsx';
69
69
  <div class="flex items-center space-x-1">
70
70
  <button
71
71
  brnCalendarPreviousButton
72
- class="ring-offset-background focus-visible:ring-ring border-input hover:bg-accent hover:text-accent-foreground absolute left-1 inline-flex h-7 w-7 items-center justify-center whitespace-nowrap rounded-md border bg-transparent p-0 text-sm font-medium opacity-50 transition-colors hover:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50"
72
+ class="focus-visible:ring-ring hover:bg-accent hover:text-accent-foreground text-popover-foreground absolute left-1 inline-flex size-8 items-center justify-center whitespace-nowrap rounded-md bg-transparent p-0 text-sm font-medium transition-colors hover:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50"
73
73
  >
74
74
  <ng-icon hlm name="lucideChevronLeft" size="sm" />
75
75
  </button>
76
76
 
77
77
  <button
78
78
  brnCalendarNextButton
79
- class="ring-offset-background focus-visible:ring-ring border-input hover:bg-accent hover:text-accent-foreground absolute right-1 inline-flex h-7 w-7 items-center justify-center whitespace-nowrap rounded-md border bg-transparent p-0 text-sm font-medium opacity-50 transition-colors hover:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50"
79
+ class="focus-visible:ring-ring hover:bg-accent hover:text-accent-foreground text-popover-foreground absolute right-1 inline-flex size-8 items-center justify-center whitespace-nowrap rounded-md bg-transparent p-0 text-sm font-medium transition-colors hover:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50"
80
80
  >
81
81
  <ng-icon hlm name="lucideChevronRight" size="sm" />
82
82
  </button>
@@ -90,7 +90,7 @@ import type { ClassValue } from 'clsx';
90
90
  <th
91
91
  *brnCalendarWeekday="let weekday"
92
92
  scope="col"
93
- class="text-muted-foreground w-9 rounded-md text-[0.8rem] font-normal"
93
+ class="text-muted-foreground w-8 rounded-md text-[0.8rem] font-normal"
94
94
  [attr.aria-label]="i18n.labelWeekday(weekday)"
95
95
  >
96
96
  {{ i18n.formatWeekdayName(weekday) }}
@@ -103,7 +103,7 @@ import type { ClassValue } from 'clsx';
103
103
  @for (date of week; track dateAdapter.getTime(date)) {
104
104
  <td
105
105
  brnCalendarCell
106
- class="data-[selected]:data-[outside]:bg-accent/50 data-[selected]:bg-accent relative h-9 w-9 p-0 text-center text-sm focus-within:relative focus-within:z-20 first:data-[selected]:rounded-l-md last:data-[selected]:rounded-r-md [&:has([aria-selected].day-range-end)]:rounded-r-md"
106
+ class="data-[selected]:data-[outside]:bg-accent/50 data-[selected]:bg-accent relative size-8 p-0 text-center text-sm focus-within:relative focus-within:z-20 first:data-[selected]:rounded-l-md last:data-[selected]:rounded-r-md [&:has([aria-selected].day-range-end)]:rounded-r-md"
107
107
  >
108
108
  <button brnCalendarCellButton [date]="date" [class]="btnClass">
109
109
  {{ dateAdapter.getDate(date) }}
@@ -167,10 +167,10 @@ export class HlmCalendarComponent<T> {
167
167
 
168
168
  protected readonly btnClass = hlm(
169
169
  buttonVariants({ variant: 'ghost' }),
170
- 'h-9 w-9 p-0 font-normal aria-selected:opacity-100',
170
+ 'size-8 p-0 font-normal aria-selected:opacity-100',
171
171
  'data-[outside]:text-muted-foreground data-[outside]:opacity-50 data-[outside]:aria-selected:bg-accent/50 data-[outside]:aria-selected:text-muted-foreground data-[outside]:aria-selected:opacity-30',
172
172
  'data-[today]:bg-accent data-[today]:text-accent-foreground',
173
- 'data-[selected]:bg-primary data-[selected]:text-primary-foreground data-[selected]:hover:bg-primary data-[selected]:hover:text-primary-foreground data-[selected]:focus:bg-primary data-[selected]:focus:text-primary-foreground',
173
+ 'data-[selected]:bg-primary data-[selected]:text-primary-foreground data-[selected]:hover:bg-primary dark:hover:text-accent-foreground data-[selected]:focus:bg-primary data-[selected]:focus:text-primary-foreground',
174
174
  'data-[disabled]:text-muted-foreground data-[disabled]:opacity-50',
175
175
  );
176
176
  }
@@ -1,5 +1,6 @@
1
1
  import { NgModule } from '@angular/core';
2
2
 
3
+ import { HlmCardActionDirective } from './lib/hlm-card-action.directive';
3
4
  import { HlmCardContentDirective } from './lib/hlm-card-content.directive';
4
5
  import { HlmCardDescriptionDirective } from './lib/hlm-card-description.directive';
5
6
  import { HlmCardFooterDirective } from './lib/hlm-card-footer.directive';
@@ -7,6 +8,7 @@ import { HlmCardHeaderDirective } from './lib/hlm-card-header.directive';
7
8
  import { HlmCardTitleDirective } from './lib/hlm-card-title.directive';
8
9
  import { HlmCardDirective } from './lib/hlm-card.directive';
9
10
 
11
+ export * from './lib/hlm-card-action.directive';
10
12
  export * from './lib/hlm-card-content.directive';
11
13
  export * from './lib/hlm-card-description.directive';
12
14
  export * from './lib/hlm-card-footer.directive';
@@ -21,6 +23,7 @@ export const HlmCardImports = [
21
23
  HlmCardTitleDirective,
22
24
  HlmCardDescriptionDirective,
23
25
  HlmCardContentDirective,
26
+ HlmCardActionDirective,
24
27
  ] as const;
25
28
 
26
29
  @NgModule({
@@ -0,0 +1,17 @@
1
+ import { Directive, computed, input } from '@angular/core';
2
+ import { hlm } from '@spartan-ng/brain/core';
3
+ import type { ClassValue } from 'clsx';
4
+
5
+ @Directive({
6
+ selector: '[hlmCardAction]',
7
+ standalone: true,
8
+ host: {
9
+ '[class]': '_computedClass()',
10
+ },
11
+ })
12
+ export class HlmCardActionDirective {
13
+ public readonly userClass = input<ClassValue>('', { alias: 'class' });
14
+ protected readonly _computedClass = computed(() =>
15
+ hlm('col-start-2 row-span-2 row-start-1 self-start justify-self-end', this.userClass()),
16
+ );
17
+ }
@@ -1,14 +1,7 @@
1
1
  import { Directive, computed, input } from '@angular/core';
2
2
  import { hlm } from '@spartan-ng/brain/core';
3
- import { type VariantProps, cva } from 'class-variance-authority';
4
3
  import type { ClassValue } from 'clsx';
5
4
 
6
- export const cardContentVariants = cva('p-6 pt-0', {
7
- variants: {},
8
- defaultVariants: {},
9
- });
10
- export type CardContentVariants = VariantProps<typeof cardContentVariants>;
11
-
12
5
  @Directive({
13
6
  selector: '[hlmCardContent]',
14
7
  host: {
@@ -17,5 +10,5 @@ export type CardContentVariants = VariantProps<typeof cardContentVariants>;
17
10
  })
18
11
  export class HlmCardContentDirective {
19
12
  public readonly userClass = input<ClassValue>('', { alias: 'class' });
20
- protected _computedClass = computed(() => hlm(cardContentVariants(), this.userClass()));
13
+ protected readonly _computedClass = computed(() => hlm('px-6', this.userClass()));
21
14
  }
@@ -1,14 +1,7 @@
1
1
  import { Directive, computed, input } from '@angular/core';
2
2
  import { hlm } from '@spartan-ng/brain/core';
3
- import { type VariantProps, cva } from 'class-variance-authority';
4
3
  import type { ClassValue } from 'clsx';
5
4
 
6
- export const cardDescriptionVariants = cva('text-sm text-muted-foreground', {
7
- variants: {},
8
- defaultVariants: {},
9
- });
10
- export type CardDescriptionVariants = VariantProps<typeof cardDescriptionVariants>;
11
-
12
5
  @Directive({
13
6
  selector: '[hlmCardDescription]',
14
7
  host: {
@@ -17,5 +10,5 @@ export type CardDescriptionVariants = VariantProps<typeof cardDescriptionVariant
17
10
  })
18
11
  export class HlmCardDescriptionDirective {
19
12
  public readonly userClass = input<ClassValue>('', { alias: 'class' });
20
- protected _computedClass = computed(() => hlm(cardDescriptionVariants(), this.userClass()));
13
+ protected readonly _computedClass = computed(() => hlm('text-muted-foreground text-sm', this.userClass()));
21
14
  }
@@ -1,21 +1,7 @@
1
1
  import { Directive, computed, input } from '@angular/core';
2
2
  import { hlm } from '@spartan-ng/brain/core';
3
- import { type VariantProps, cva } from 'class-variance-authority';
4
3
  import type { ClassValue } from 'clsx';
5
4
 
6
- export const cardFooterVariants = cva('flex p-6 pt-0', {
7
- variants: {
8
- direction: {
9
- row: 'flex-row items-center space-x-1.5',
10
- column: 'flex-col space-y-1.5',
11
- },
12
- },
13
- defaultVariants: {
14
- direction: 'row',
15
- },
16
- });
17
- export type CardFooterVariants = VariantProps<typeof cardFooterVariants>;
18
-
19
5
  @Directive({
20
6
  selector: '[hlmCardFooter]',
21
7
  host: {
@@ -24,7 +10,5 @@ export type CardFooterVariants = VariantProps<typeof cardFooterVariants>;
24
10
  })
25
11
  export class HlmCardFooterDirective {
26
12
  public readonly userClass = input<ClassValue>('', { alias: 'class' });
27
- protected _computedClass = computed(() => hlm(cardFooterVariants({ direction: this.direction() }), this.userClass()));
28
-
29
- public readonly direction = input<CardFooterVariants['direction']>('row');
13
+ protected readonly _computedClass = computed(() => hlm('flex items-center px-6 [.border-t]:pt-6', this.userClass()));
30
14
  }
@@ -1,21 +1,7 @@
1
1
  import { Directive, computed, input } from '@angular/core';
2
2
  import { hlm } from '@spartan-ng/brain/core';
3
- import { type VariantProps, cva } from 'class-variance-authority';
4
3
  import type { ClassValue } from 'clsx';
5
4
 
6
- export const cardHeaderVariants = cva('flex p-6', {
7
- variants: {
8
- direction: {
9
- row: 'flex-row items-center space-x-1.5',
10
- column: 'flex-col space-y-1.5',
11
- },
12
- },
13
- defaultVariants: {
14
- direction: 'column',
15
- },
16
- });
17
- export type CardHeaderVariants = VariantProps<typeof cardHeaderVariants>;
18
-
19
5
  @Directive({
20
6
  selector: '[hlmCardHeader]',
21
7
  host: {
@@ -24,7 +10,10 @@ export type CardHeaderVariants = VariantProps<typeof cardHeaderVariants>;
24
10
  })
25
11
  export class HlmCardHeaderDirective {
26
12
  public readonly userClass = input<ClassValue>('', { alias: 'class' });
27
- protected _computedClass = computed(() => hlm(cardHeaderVariants({ direction: this.direction() }), this.userClass()));
28
-
29
- public readonly direction = input<CardHeaderVariants['direction']>('column');
13
+ protected readonly _computedClass = computed(() =>
14
+ hlm(
15
+ '@container/card-header grid auto-rows-min grid-rows-[auto_auto] items-start gap-1.5 px-6 has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-6',
16
+ this.userClass(),
17
+ ),
18
+ );
30
19
  }
@@ -1,14 +1,7 @@
1
1
  import { Directive, computed, input } from '@angular/core';
2
2
  import { hlm } from '@spartan-ng/brain/core';
3
- import { type VariantProps, cva } from 'class-variance-authority';
4
3
  import type { ClassValue } from 'clsx';
5
4
 
6
- export const cardTitleVariants = cva('text-lg font-semibold leading-none tracking-tight', {
7
- variants: {},
8
- defaultVariants: {},
9
- });
10
- export type CardTitleVariants = VariantProps<typeof cardTitleVariants>;
11
-
12
5
  @Directive({
13
6
  selector: '[hlmCardTitle]',
14
7
  host: {
@@ -17,5 +10,5 @@ export type CardTitleVariants = VariantProps<typeof cardTitleVariants>;
17
10
  })
18
11
  export class HlmCardTitleDirective {
19
12
  public readonly userClass = input<ClassValue>('', { alias: 'class' });
20
- protected _computedClass = computed(() => hlm(cardTitleVariants(), this.userClass()));
13
+ protected readonly _computedClass = computed(() => hlm('leading-none font-semibold', this.userClass()));
21
14
  }