@spartan-ng/cli 0.0.1-alpha.608 → 0.0.1-alpha.610

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 (20) hide show
  1. package/package.json +1 -1
  2. package/src/generators/ui/libs/autocomplete/files/index.ts.template +18 -4
  3. package/src/generators/ui/libs/autocomplete/files/lib/hlm-autocomplete-content.ts.template +16 -0
  4. package/src/generators/ui/libs/autocomplete/files/lib/hlm-autocomplete-empty.ts.template +10 -2
  5. package/src/generators/ui/libs/autocomplete/files/lib/hlm-autocomplete-group.ts.template +6 -8
  6. package/src/generators/ui/libs/autocomplete/files/lib/hlm-autocomplete-input.ts.template +64 -0
  7. package/src/generators/ui/libs/autocomplete/files/lib/hlm-autocomplete-item.ts.template +27 -11
  8. package/src/generators/ui/libs/autocomplete/files/lib/hlm-autocomplete-label.ts.template +16 -0
  9. package/src/generators/ui/libs/autocomplete/files/lib/hlm-autocomplete-list.ts.template +9 -8
  10. package/src/generators/ui/libs/autocomplete/files/lib/hlm-autocomplete-search.ts.template +38 -0
  11. package/src/generators/ui/libs/autocomplete/files/lib/hlm-autocomplete-separator.ts.template +16 -0
  12. package/src/generators/ui/libs/autocomplete/files/lib/hlm-autocomplete-status.ts.template +16 -0
  13. package/src/generators/ui/libs/autocomplete/files/lib/hlm-autocomplete.ts.template +33 -352
  14. package/src/generators/ui/libs/resizable/files/lib/hlm-resizable-handle.ts.template +5 -12
  15. package/src/generators/ui/libs/sidebar/files/lib/hlm-sidebar.ts.template +1 -1
  16. package/src/generators/ui/primitive-deps.js +1 -1
  17. package/src/generators/ui/primitive-deps.js.map +1 -1
  18. package/src/generators/ui/supported-ui-libraries.json +40 -45
  19. package/src/generators/ui/libs/autocomplete/files/lib/hlm-autocomplete-trigger.ts.template +0 -32
  20. package/src/generators/ui/libs/autocomplete/files/lib/hlm-autocomplete.token.ts.template +0 -35
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spartan-ng/cli",
3
- "version": "0.0.1-alpha.608",
3
+ "version": "0.0.1-alpha.610",
4
4
  "type": "commonjs",
5
5
  "dependencies": {
6
6
  "@angular/core": ">=19.0.0",
@@ -1,23 +1,37 @@
1
1
  import { HlmAutocomplete } from './lib/hlm-autocomplete';
2
+ import { HlmAutocompleteContent } from './lib/hlm-autocomplete-content';
2
3
  import { HlmAutocompleteEmpty } from './lib/hlm-autocomplete-empty';
3
4
  import { HlmAutocompleteGroup } from './lib/hlm-autocomplete-group';
5
+ import { HlmAutocompleteInput } from './lib/hlm-autocomplete-input';
4
6
  import { HlmAutocompleteItem } from './lib/hlm-autocomplete-item';
7
+ import { HlmAutocompleteLabel } from './lib/hlm-autocomplete-label';
5
8
  import { HlmAutocompleteList } from './lib/hlm-autocomplete-list';
6
- import { HlmAutocompleteTrigger } from './lib/hlm-autocomplete-trigger';
9
+ import { HlmAutocompleteSearch } from './lib/hlm-autocomplete-search';
10
+ import { HlmAutocompleteSeparator } from './lib/hlm-autocomplete-separator';
11
+ import { HlmAutocompleteStatus } from './lib/hlm-autocomplete-status';
7
12
 
8
13
  export * from './lib/hlm-autocomplete';
14
+ export * from './lib/hlm-autocomplete-content';
9
15
  export * from './lib/hlm-autocomplete-empty';
10
16
  export * from './lib/hlm-autocomplete-group';
17
+ export * from './lib/hlm-autocomplete-input';
11
18
  export * from './lib/hlm-autocomplete-item';
19
+ export * from './lib/hlm-autocomplete-label';
12
20
  export * from './lib/hlm-autocomplete-list';
13
- export * from './lib/hlm-autocomplete-trigger';
14
- export * from './lib/hlm-autocomplete.token';
21
+ export * from './lib/hlm-autocomplete-search';
22
+ export * from './lib/hlm-autocomplete-separator';
23
+ export * from './lib/hlm-autocomplete-status';
15
24
 
16
25
  export const HlmAutocompleteImports = [
17
26
  HlmAutocomplete,
27
+ HlmAutocompleteContent,
18
28
  HlmAutocompleteEmpty,
19
29
  HlmAutocompleteGroup,
30
+ HlmAutocompleteInput,
20
31
  HlmAutocompleteItem,
32
+ HlmAutocompleteLabel,
21
33
  HlmAutocompleteList,
22
- HlmAutocompleteTrigger,
34
+ HlmAutocompleteSearch,
35
+ HlmAutocompleteSeparator,
36
+ HlmAutocompleteStatus,
23
37
  ] as const;
@@ -0,0 +1,16 @@
1
+ import { Directive } from '@angular/core';
2
+ import { BrnAutocompleteContent } from '@spartan-ng/brain/autocomplete';
3
+ import { classes } from '<%- importAlias %>/utils';
4
+
5
+ @Directive({
6
+ selector: '[hlmAutocompleteContent]',
7
+ hostDirectives: [BrnAutocompleteContent],
8
+ })
9
+ export class HlmAutocompleteContent {
10
+ constructor() {
11
+ classes(
12
+ () =>
13
+ 'group/autocomplete-content bg-popover text-popover-foreground data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-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 ring-foreground/10 max-h-72 w-(--brn-autocomplete-width) min-w-36 overflow-hidden rounded-md p-0 shadow-md ring-1 duration-100',
14
+ );
15
+ }
16
+ }
@@ -1,11 +1,19 @@
1
1
  import { Directive } from '@angular/core';
2
+ import { BrnAutocompleteEmpty } from '@spartan-ng/brain/autocomplete';
2
3
  import { classes } from '<%- importAlias %>/utils';
3
4
 
4
5
  @Directive({
5
- selector: '[hlmAutocompleteEmpty]',
6
+ selector: '[hlmAutocompleteEmpty],hlm-autocomplete-empty',
7
+ hostDirectives: [BrnAutocompleteEmpty],
8
+ host: {
9
+ 'data-slot': 'autocomplete-empty',
10
+ },
6
11
  })
7
12
  export class HlmAutocompleteEmpty {
8
13
  constructor() {
9
- classes(() => 'py-6 text-center text-sm');
14
+ classes(
15
+ () =>
16
+ 'text-muted-foreground hidden w-full items-center justify-center gap-2 py-2 text-center text-sm group-data-empty/autocomplete-content:flex',
17
+ );
10
18
  }
11
19
  }
@@ -3,16 +3,14 @@ import { BrnAutocompleteGroup } from '@spartan-ng/brain/autocomplete';
3
3
  import { classes } from '<%- importAlias %>/utils';
4
4
 
5
5
  @Directive({
6
- selector: '[hlmAutocompleteGroup],hlm-autocomplete-group',
7
- hostDirectives: [
8
- {
9
- directive: BrnAutocompleteGroup,
10
- inputs: ['id'],
11
- },
12
- ],
6
+ selector: '[hlmAutocompleteGroup]',
7
+ hostDirectives: [BrnAutocompleteGroup],
8
+ host: {
9
+ 'data-slot': 'autocomplete-group',
10
+ },
13
11
  })
14
12
  export class HlmAutocompleteGroup {
15
13
  constructor() {
16
- classes(() => 'text-foreground block overflow-hidden p-1');
14
+ classes(() => 'data-hidden:hidden');
17
15
  }
18
16
  }
@@ -0,0 +1,64 @@
1
+ import { BooleanInput } from '@angular/cdk/coercion';
2
+ import { booleanAttribute, ChangeDetectionStrategy, Component, input } from '@angular/core';
3
+ import { NgIcon, provideIcons } from '@ng-icons/core';
4
+ import { lucideSearch, lucideX } from '@ng-icons/lucide';
5
+ import {
6
+ BrnAutocompleteAnchor,
7
+ BrnAutocompleteClear,
8
+ BrnAutocompleteInput,
9
+ BrnAutocompleteInputWrapper,
10
+ } from '@spartan-ng/brain/autocomplete';
11
+ import { HlmInputGroupImports } from '<%- importAlias %>/input-group';
12
+
13
+ @Component({
14
+ selector: 'hlm-autocomplete-input',
15
+ imports: [HlmInputGroupImports, NgIcon, BrnAutocompleteAnchor, BrnAutocompleteClear, BrnAutocompleteInput],
16
+ providers: [provideIcons({ lucideSearch, lucideX })],
17
+ changeDetection: ChangeDetectionStrategy.OnPush,
18
+ hostDirectives: [BrnAutocompleteInputWrapper],
19
+ template: `
20
+ <hlm-input-group brnAutocompleteAnchor class="w-auto">
21
+ <input
22
+ brnAutocompleteInput
23
+ #autocompleteInput="brnAutocompleteInput"
24
+ hlmInputGroupInput
25
+ [placeholder]="placeholder()"
26
+ [attr.aria-invalid]="ariaInvalid() ? 'true' : null"
27
+ />
28
+
29
+ @if (showSearch()) {
30
+ <hlm-input-group-addon>
31
+ <ng-icon name="lucideSearch" [class.opacity-50]="autocompleteInput.disabled()" />
32
+ </hlm-input-group-addon>
33
+ }
34
+
35
+ @if (showClear()) {
36
+ <hlm-input-group-addon align="inline-end">
37
+ <button
38
+ *brnAutocompleteClear
39
+ hlmInputGroupButton
40
+ data-slot="autocomplete-clear"
41
+ [disabled]="autocompleteInput.disabled()"
42
+ size="icon-xs"
43
+ variant="ghost"
44
+ >
45
+ <ng-icon name="lucideX" />
46
+ </button>
47
+ </hlm-input-group-addon>
48
+ }
49
+ <ng-content />
50
+ </hlm-input-group>
51
+ `,
52
+ })
53
+ export class HlmAutocompleteInput {
54
+ public readonly placeholder = input<string>('');
55
+
56
+ public readonly showSearch = input<boolean, BooleanInput>(true, { transform: booleanAttribute });
57
+ public readonly showClear = input<boolean, BooleanInput>(false, { transform: booleanAttribute });
58
+
59
+ // TODO input and input-group styles need to support aria-invalid directly
60
+ public readonly ariaInvalid = input<boolean, BooleanInput>(false, {
61
+ transform: booleanAttribute,
62
+ alias: 'aria-invalid',
63
+ });
64
+ }
@@ -1,22 +1,38 @@
1
- import { Directive } from '@angular/core';
1
+ import { ChangeDetectionStrategy, Component, inject } from '@angular/core';
2
+ import { NgIcon, provideIcons } from '@ng-icons/core';
3
+ import { lucideCheck } from '@ng-icons/lucide';
2
4
  import { BrnAutocompleteItem } from '@spartan-ng/brain/autocomplete';
3
5
  import { classes } from '<%- importAlias %>/utils';
4
6
 
5
- @Directive({
6
- selector: 'button[hlmAutocompleteItem],button[hlm-autocomplete-item]',
7
- hostDirectives: [
8
- {
9
- directive: BrnAutocompleteItem,
10
- inputs: ['value', 'disabled', 'id'],
11
- outputs: ['selected'],
12
- },
13
- ],
7
+ @Component({
8
+ selector: 'hlm-autocomplete-item',
9
+ imports: [NgIcon],
10
+ providers: [provideIcons({ lucideCheck })],
11
+ changeDetection: ChangeDetectionStrategy.OnPush,
12
+ hostDirectives: [{ directive: BrnAutocompleteItem, inputs: ['id', 'disabled', 'value'] }],
13
+ host: {
14
+ 'data-slot': 'autocomplete-item',
15
+ },
16
+ template: `
17
+ <ng-content />
18
+ @if (_active()) {
19
+ <ng-icon
20
+ name="lucideCheck"
21
+ class="pointer-events-none absolute right-2 flex size-4 items-center justify-center"
22
+ aria-hidden="true"
23
+ />
24
+ }
25
+ `,
14
26
  })
15
27
  export class HlmAutocompleteItem {
28
+ private readonly _brnAutocompleteItem = inject(BrnAutocompleteItem);
29
+
30
+ protected readonly _active = this._brnAutocompleteItem.active;
31
+
16
32
  constructor() {
17
33
  classes(
18
34
  () =>
19
- `data-[selected]:bg-accent data-[selected=true]:text-accent-foreground [&>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-start text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[hidden]:hidden [&>ng-icon]:pointer-events-none [&>ng-icon]:shrink-0 [&>ng-icon:not([class*='text-'])]:text-base`,
35
+ `data-highlighted:bg-accent data-highlighted:text-accent-foreground not-data-[variant=destructive]:data-highlighted:**:text-accent-foreground relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none data-hidden:hidden data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_ng-icon]:pointer-events-none [&_ng-icon]:shrink-0 [&_ng-icon:not([class*='text-'])]:text-base`,
20
36
  );
21
37
  }
22
38
  }
@@ -0,0 +1,16 @@
1
+ import { Directive } from '@angular/core';
2
+ import { BrnAutocompleteLabel } from '@spartan-ng/brain/autocomplete';
3
+ import { classes } from '<%- importAlias %>/utils';
4
+
5
+ @Directive({
6
+ selector: '[hlmAutocompleteLabel]',
7
+ hostDirectives: [{ directive: BrnAutocompleteLabel, inputs: ['id'] }],
8
+ host: {
9
+ 'data-slot': 'autocomplete-label',
10
+ },
11
+ })
12
+ export class HlmAutocompleteLabel {
13
+ constructor() {
14
+ classes(() => 'text-muted-foreground px-2 py-1.5 text-xs');
15
+ }
16
+ }
@@ -3,16 +3,17 @@ import { BrnAutocompleteList } from '@spartan-ng/brain/autocomplete';
3
3
  import { classes } from '<%- importAlias %>/utils';
4
4
 
5
5
  @Directive({
6
- selector: '[hlmAutocompleteList],hlm-autocomplete-list',
7
- hostDirectives: [
8
- {
9
- directive: BrnAutocompleteList,
10
- inputs: ['id'],
11
- },
12
- ],
6
+ selector: '[hlmAutocompleteList]',
7
+ hostDirectives: [{ directive: BrnAutocompleteList, inputs: ['id'] }],
8
+ host: {
9
+ 'data-slot': 'autocomplete-list',
10
+ },
13
11
  })
14
12
  export class HlmAutocompleteList {
15
13
  constructor() {
16
- classes(() => 'block max-h-60 overflow-x-hidden overflow-y-auto');
14
+ classes(
15
+ () =>
16
+ 'no-scrollbar max-h-[calc(--spacing(72)---spacing(9))] scroll-py-1 overflow-y-auto overscroll-contain p-1 data-empty:p-0',
17
+ );
17
18
  }
18
19
  }
@@ -0,0 +1,38 @@
1
+ import { Directive } from '@angular/core';
2
+ import { BrnAutocompleteSearch } from '@spartan-ng/brain/autocomplete';
3
+ import { provideBrnDialogDefaultOptions } from '@spartan-ng/brain/dialog';
4
+ import { BrnPopover, provideBrnPopoverConfig } from '@spartan-ng/brain/popover';
5
+ import { classes } from '<%- importAlias %>/utils';
6
+
7
+ @Directive({
8
+ selector: '[hlmAutocompleteSearch],hlm-autocomplete-search',
9
+ providers: [
10
+ provideBrnPopoverConfig({
11
+ align: 'start',
12
+ sideOffset: 6,
13
+ }),
14
+ provideBrnDialogDefaultOptions({
15
+ autoFocus: 'first-heading',
16
+ }),
17
+ ],
18
+ hostDirectives: [
19
+ {
20
+ directive: BrnAutocompleteSearch,
21
+ inputs: ['disabled', 'value', 'search', 'itemToString'],
22
+ outputs: ['valueChange', 'searchChange'],
23
+ },
24
+ {
25
+ directive: BrnPopover,
26
+ inputs: ['align', 'autoFocus', 'closeDelay', 'closeOnOutsidePointerEvents', 'sideOffset', 'state', 'offsetX'],
27
+ outputs: ['stateChanged', 'closed'],
28
+ },
29
+ ],
30
+ host: {
31
+ 'data-slot': 'autocomplete',
32
+ },
33
+ })
34
+ export class HlmAutocompleteSearch {
35
+ constructor() {
36
+ classes(() => 'block');
37
+ }
38
+ }
@@ -0,0 +1,16 @@
1
+ import { Directive } from '@angular/core';
2
+ import { BrnAutocompleteSeparator } from '@spartan-ng/brain/autocomplete';
3
+ import { classes } from '<%- importAlias %>/utils';
4
+
5
+ @Directive({
6
+ selector: '[hlmAutocompleteSeparator]',
7
+ hostDirectives: [{ directive: BrnAutocompleteSeparator, inputs: ['orientation'] }],
8
+ host: {
9
+ 'data-slot': 'autocomplete-separator',
10
+ },
11
+ })
12
+ export class HlmAutocompleteSeparator {
13
+ constructor() {
14
+ classes(() => 'bg-border -mx-1 my-1 h-px');
15
+ }
16
+ }
@@ -0,0 +1,16 @@
1
+ import { Directive } from '@angular/core';
2
+ import { BrnAutocompleteStatus } from '@spartan-ng/brain/autocomplete';
3
+ import { classes } from '<%- importAlias %>/utils';
4
+
5
+ @Directive({
6
+ selector: '[hlmAutocompleteStatus],hlm-autocomplete-status',
7
+ hostDirectives: [BrnAutocompleteStatus],
8
+ host: {
9
+ 'data-slot': 'autocomplete-status',
10
+ },
11
+ })
12
+ export class HlmAutocompleteStatus {
13
+ constructor() {
14
+ classes(() => 'text-muted-foreground flex w-full items-center justify-center gap-2 px-3 py-2 text-center text-sm');
15
+ }
16
+ }
@@ -1,357 +1,38 @@
1
- import type { BooleanInput } from '@angular/cdk/coercion';
2
- import { NgTemplateOutlet } from '@angular/common';
3
- import {
4
- booleanAttribute,
5
- ChangeDetectionStrategy,
6
- Component,
7
- computed,
8
- effect,
9
- ElementRef,
10
- forwardRef,
11
- inject,
12
- input,
13
- linkedSignal,
14
- model,
15
- output,
16
- type TemplateRef,
17
- viewChild,
18
- } from '@angular/core';
19
- import { type ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
20
- import { provideIcons } from '@ng-icons/core';
21
- import { lucideChevronDown, lucideCircleX, lucideSearch } from '@ng-icons/lucide';
22
- import { BrnAutocomplete, BrnAutocompleteImports } from '@spartan-ng/brain/autocomplete';
23
- import { debouncedSignal } from '@spartan-ng/brain/core';
24
- import type { ChangeFn, TouchFn } from '@spartan-ng/brain/forms';
25
- import { BrnPopoverImports } from '@spartan-ng/brain/popover';
26
- import { HlmIconImports } from '<%- importAlias %>/icon';
27
- import { HlmPopoverImports } from '<%- importAlias %>/popover';
28
- import { classes, hlm } from '<%- importAlias %>/utils';
29
- import type { ClassValue } from 'clsx';
30
- import { HlmAutocompleteEmpty } from './hlm-autocomplete-empty';
31
- import { HlmAutocompleteGroup } from './hlm-autocomplete-group';
32
- import { HlmAutocompleteItem } from './hlm-autocomplete-item';
33
- import { HlmAutocompleteList } from './hlm-autocomplete-list';
34
-
35
- import { HlmInputGroupImports } from '<%- importAlias %>/input-group';
36
- import { HlmAutocompleteTrigger } from './hlm-autocomplete-trigger';
37
- import { injectHlmAutocompleteConfig } from './hlm-autocomplete.token';
38
-
39
- export const HLM_AUTOCOMPLETE_VALUE_ACCESSOR = {
40
- provide: NG_VALUE_ACCESSOR,
41
- useExisting: forwardRef(() => HlmAutocomplete),
42
- multi: true,
43
- };
44
-
45
- @Component({
46
- selector: 'hlm-autocomplete',
47
- imports: [
48
- NgTemplateOutlet,
49
- BrnAutocompleteImports,
50
- HlmAutocompleteEmpty,
51
- HlmAutocompleteGroup,
52
- HlmAutocompleteItem,
53
- HlmAutocompleteList,
54
- HlmAutocompleteTrigger,
55
- BrnPopoverImports,
56
- HlmPopoverImports,
57
- HlmIconImports,
58
- HlmInputGroupImports,
1
+ import { Directive } from '@angular/core';
2
+ import { BrnAutocomplete } from '@spartan-ng/brain/autocomplete';
3
+ import { provideBrnDialogDefaultOptions } from '@spartan-ng/brain/dialog';
4
+ import { BrnPopover, provideBrnPopoverConfig } from '@spartan-ng/brain/popover';
5
+ import { classes } from '<%- importAlias %>/utils';
6
+
7
+ @Directive({
8
+ selector: '[hlmAutocomplete],hlm-autocomplete',
9
+ providers: [
10
+ provideBrnPopoverConfig({
11
+ align: 'start',
12
+ sideOffset: 6,
13
+ }),
14
+ provideBrnDialogDefaultOptions({
15
+ autoFocus: 'first-heading',
16
+ }),
59
17
  ],
60
- providers: [HLM_AUTOCOMPLETE_VALUE_ACCESSOR, provideIcons({ lucideSearch, lucideChevronDown, lucideCircleX })],
61
- changeDetection: ChangeDetectionStrategy.OnPush,
62
- template: `
63
- @let transformer = transformOptionToValue();
64
- <hlm-popover
65
- #popover
66
- align="start"
67
- autoFocus="first-heading"
68
- sideOffset="5"
69
- closeDelay="100"
70
- closeOnOutsidePointerEvents="true"
71
- (closed)="_closed()"
72
- >
73
- <div brnAutocomplete (selectionCleared)="_selectionCleared()">
74
- <div
75
- hlmInputGroup
76
- hlmAutocompleteTrigger
77
- [class]="_computedAutocompleteSearchClass()"
78
- [disabledTrigger]="!_search() || _disabled()"
79
- >
80
- <input
81
- #input
82
- brnAutocompleteSearchInput
83
- hlmInputGroupInput
84
- type="text"
85
- autocomplete="off"
86
- [id]="inputId()"
87
- [class]="_computedAutocompleteInputClass()"
88
- [placeholder]="searchPlaceholderText()"
89
- [disabled]="_disabled()"
90
- [value]="search()"
91
- (input)="_searchChanged($event)"
92
- />
93
- <div hlmInputGroupAddon>
94
- <ng-icon name="lucideSearch" />
95
- </div>
96
- <div hlmInputGroupAddon align="inline-end">
97
- @if (showClearBtn() && value() !== undefined) {
98
- <button
99
- hlmInputGroupButton
100
- type="button"
101
- tabindex="-1"
102
- aria-label="clear"
103
- [disabled]="_disabled()"
104
- (click)="_selectionCleared()"
105
- size="icon-xs"
106
- >
107
- <ng-icon name="lucideCircleX" />
108
- </button>
109
- }
110
-
111
- <button
112
- hlmInputGroupButton
113
- type="button"
114
- tabindex="-1"
115
- [attr.aria-label]="ariaLabelToggleButton()"
116
- [disabled]="_disabled()"
117
- (click)="_toggleOptions()"
118
- size="icon-xs"
119
- >
120
- <ng-icon name="lucideChevronDown" />
121
- </button>
122
- </div>
123
- </div>
124
-
125
- <div
126
- *brnPopoverContent="let ctx"
127
- hlmPopoverContent
128
- class="p-0"
129
- [style.width.px]="_elementRef.nativeElement.offsetWidth"
130
- >
131
- <hlm-autocomplete-list
132
- [class]="_computedAutocompleteListClass()"
133
- [class.hidden]="filteredOptions().length === 0"
134
- >
135
- <hlm-autocomplete-group>
136
- @for (option of filteredOptions(); track option) {
137
- <button
138
- hlm-autocomplete-item
139
- [class]="_computedAutocompleteItemClass()"
140
- [value]="transformer ? transformer(option) : option"
141
- (selected)="_optionSelected(option)"
142
- >
143
- @if (optionTemplate(); as optionTemplate) {
144
- <ng-container *ngTemplateOutlet="optionTemplate; context: { $implicit: option }" />
145
- } @else {
146
- {{ transformOptionToString()(option) }}
147
- }
148
- </button>
149
- }
150
- </hlm-autocomplete-group>
151
- </hlm-autocomplete-list>
152
-
153
- <div *brnAutocompleteEmpty hlmAutocompleteEmpty [class]="_computedAutocompleteEmptyClass()">
154
- @if (loading()) {
155
- <ng-content select="[loading]">{{ loadingText() }}</ng-content>
156
- } @else {
157
- <ng-content select="[empty]">{{ emptyText() }}</ng-content>
158
- }
159
- </div>
160
- </div>
161
- </div>
162
- </hlm-popover>
163
- `,
18
+ hostDirectives: [
19
+ {
20
+ directive: BrnAutocomplete,
21
+ inputs: ['disabled', 'value', 'search', 'itemToString', 'isItemEqualToValue'],
22
+ outputs: ['valueChange', 'searchChange'],
23
+ },
24
+ {
25
+ directive: BrnPopover,
26
+ inputs: ['align', 'autoFocus', 'closeDelay', 'closeOnOutsidePointerEvents', 'sideOffset', 'state', 'offsetX'],
27
+ outputs: ['stateChanged', 'closed'],
28
+ },
29
+ ],
30
+ host: {
31
+ 'data-slot': 'autocomplete',
32
+ },
164
33
  })
165
- export class HlmAutocomplete<T, V = T> implements ControlValueAccessor {
166
- private static _id = 0;
167
- private readonly _config = injectHlmAutocompleteConfig<T, V>();
168
-
169
- private readonly _brnAutocomplete = viewChild.required(BrnAutocomplete);
170
-
171
- private readonly _inputRef = viewChild.required('input', { read: ElementRef });
172
-
173
- protected readonly _elementRef = inject(ElementRef<HTMLElement>);
174
-
175
- /** Custom class for the autocomplete search container. */
176
- public readonly autocompleteSearchClass = input<ClassValue>('');
177
- protected readonly _computedAutocompleteSearchClass = computed(() => hlm(this.autocompleteSearchClass()));
178
-
179
- /** Custom class for the autocomplete input. */
180
- public readonly autocompleteInputClass = input<ClassValue>('');
181
- protected readonly _computedAutocompleteInputClass = computed(() => hlm(this.autocompleteInputClass()));
182
-
183
- /** Custom class for the autocomplete list. */
184
- public readonly autocompleteListClass = input<ClassValue>('');
185
- protected readonly _computedAutocompleteListClass = computed(() => hlm(this.autocompleteListClass()));
186
-
187
- /** Custom class for each autocomplete item. */
188
- public readonly autocompleteItemClass = input<ClassValue>('');
189
- protected readonly _computedAutocompleteItemClass = computed(() => hlm(this.autocompleteItemClass()));
190
-
191
- /** Custom class for the empty and loading state container. */
192
- public readonly autocompleteEmptyClass = input<ClassValue>('');
193
- protected readonly _computedAutocompleteEmptyClass = computed(() => hlm(this.autocompleteEmptyClass()));
194
-
195
- /** The list of filtered options to display in the autocomplete. */
196
- public readonly filteredOptions = input<T[]>([]);
197
-
198
- /** The selected value. */
199
- public readonly value = model<T | V>();
200
-
201
- /** Debounce time in milliseconds for the search input. */
202
- public readonly debounceTime = input<number>(this._config.debounceTime);
203
-
204
- /** The search query. */
205
- public readonly search = model<string>('');
206
-
207
- /** Debounced search query. */
208
- protected readonly _search = debouncedSignal(this.search, this.debounceTime());
209
-
210
- /** Function to transform an option value to a search string. Defaults to identity function for strings. */
211
- public readonly transformValueToSearch = input<(option: T) => string>(this._config.transformValueToSearch);
212
-
213
- /** Whether selection of an option is required. */
214
- public readonly requireSelection = input<boolean, BooleanInput>(this._config.requireSelection, {
215
- transform: booleanAttribute,
216
- });
217
-
218
- /** Function to transform an option value to a display string. Defaults to identity function for strings. */
219
- public readonly transformOptionToString = input<(option: T) => string>(this._config.transformOptionToString);
220
-
221
- /** Function to transform the object to the value. */
222
- public readonly transformOptionToValue = input<((option: T) => V) | undefined>(this._config.transformOptionToValue);
223
-
224
- /** Function to display the selected value as a string. */
225
- public readonly displayWith = input<((value: V) => string) | undefined>(undefined);
226
-
227
- /** Computed function to get the display value for the selected option. */
228
- protected readonly _displaySearchValue = computed(() => {
229
- const displayWith = this.displayWith();
230
- if (displayWith) {
231
- return displayWith;
232
- } else {
233
- return this.transformValueToSearch();
234
- }
235
- });
236
-
237
- /** Optional template for rendering each option. */
238
- public readonly optionTemplate = input<TemplateRef<HlmAutocompleteOption<T>>>();
239
-
240
- /** Whether the autocomplete is in a loading state. */
241
- public readonly loading = input<boolean, BooleanInput>(false, { transform: booleanAttribute });
242
-
243
- /** Whether to show the clear button when a option is selected. */
244
- public readonly showClearBtn = input<boolean, BooleanInput>(this._config.showClearBtn, {
245
- transform: booleanAttribute,
246
- });
247
-
248
- /** Placeholder text for the input field. */
249
- public readonly searchPlaceholderText = input<string>('Select an option');
250
-
251
- /** Text to display when loading options. */
252
- public readonly loadingText = input<string>('Loading options...');
253
-
254
- /** Text to display when no options are found. */
255
- public readonly emptyText = input<string>('No options found');
256
-
257
- /** Aria label for the toggle button. */
258
- public readonly ariaLabelToggleButton = input<string>('Toggle options');
259
-
260
- /** The id of the input field. */
261
- public readonly inputId = input<string>(`hlm-autocomplete-input-${++HlmAutocomplete._id}`);
262
-
263
- /** Whether the autocomplete is disabled. */
264
- public readonly disabled = input<boolean, BooleanInput>(false, { transform: booleanAttribute });
265
-
266
- protected readonly _disabled = linkedSignal(() => this.disabled());
267
-
268
- /** Emitted when the selected value changes. */
269
- public readonly valueChange = output<T | V | null>();
270
-
271
- /** Emitted when the search query changes. */
272
- public readonly searchChange = output<string>();
273
-
274
- protected _onChange?: ChangeFn<T | V | null>;
275
- protected _onTouched?: TouchFn;
276
-
34
+ export class HlmAutocomplete {
277
35
  constructor() {
278
- classes(() => 'block w-full');
279
- effect(() => {
280
- const search = this._search();
281
- this.searchChange.emit(search);
282
- });
36
+ classes(() => 'block');
283
37
  }
284
-
285
- protected _searchChanged(event: Event) {
286
- const value = (event.target as HTMLInputElement).value;
287
- this.search.set(value ?? '');
288
-
289
- if (!this._brnAutocomplete().isExpanded() && value.length > 0) {
290
- this._brnAutocomplete().open();
291
- }
292
- }
293
-
294
- /** Toggle the options panel */
295
- protected _toggleOptions() {
296
- if (this._search() || this.filteredOptions().length > 0) {
297
- // only toggle if there's a search term or options to show
298
- this._brnAutocomplete().toggle();
299
- }
300
-
301
- this._inputRef().nativeElement.focus();
302
- }
303
-
304
- /** Clear the current selection and search input */
305
- protected _selectionCleared() {
306
- this.value.set(undefined);
307
- this._onChange?.(null);
308
- this.valueChange.emit(null);
309
- this.search.set('');
310
- }
311
-
312
- protected _optionSelected(option: T) {
313
- const transformer = this.transformOptionToValue();
314
-
315
- const value = transformer ? transformer(option) : option;
316
-
317
- this.value.set(value);
318
- this._onChange?.(value);
319
- this.valueChange.emit(value);
320
-
321
- const searchValue = this._displaySearchValue()(value as any);
322
- this.search.set(searchValue ?? '');
323
- this._brnAutocomplete().close();
324
- }
325
-
326
- /** CONTROL VALUE ACCESSOR */
327
- public writeValue(value: T | V | null): void {
328
- this.value.set(value ? value : undefined);
329
-
330
- const searchValue = value ? this._displaySearchValue()(value as any) : '';
331
- this.search.set(searchValue);
332
- }
333
-
334
- public registerOnChange(fn: ChangeFn<T | V | null>): void {
335
- this._onChange = fn;
336
- }
337
-
338
- public registerOnTouched(fn: TouchFn): void {
339
- this._onTouched = fn;
340
- }
341
-
342
- public setDisabledState(isDisabled: boolean): void {
343
- this._disabled.set(isDisabled);
344
- }
345
-
346
- protected _closed() {
347
- if (this.requireSelection()) {
348
- const value = this.value();
349
- const searchValue = value ? this._displaySearchValue()(value as any) : '';
350
- this.search.set(searchValue ?? '');
351
- }
352
- }
353
- }
354
-
355
- export interface HlmAutocompleteOption<T> {
356
- $implicit: T;
357
38
  }
@@ -1,15 +1,10 @@
1
1
  import { ChangeDetectionStrategy, Component, inject } from '@angular/core';
2
- import { NgIcon, provideIcons } from '@ng-icons/core';
3
- import { lucideGripVertical } from '@ng-icons/lucide';
4
2
  import { BrnResizableHandle } from '@spartan-ng/brain/resizable';
5
- import { HlmIcon } from '<%- importAlias %>/icon';
6
3
  import { classes } from '<%- importAlias %>/utils';
7
4
 
8
5
  @Component({
9
6
  selector: 'hlm-resizable-handle',
10
7
  exportAs: 'hlmResizableHandle',
11
- imports: [NgIcon, HlmIcon],
12
- providers: [provideIcons({ lucideGripVertical })],
13
8
  changeDetection: ChangeDetectionStrategy.OnPush,
14
9
  hostDirectives: [{ directive: BrnResizableHandle, inputs: ['withHandle', 'disabled'] }],
15
10
  host: {
@@ -17,9 +12,7 @@ import { classes } from '<%- importAlias %>/utils';
17
12
  },
18
13
  template: `
19
14
  @if (_brnResizableHandle.withHandle()) {
20
- <div class="bg-border z-10 flex h-4 w-3 items-center justify-center rounded-sm border">
21
- <ng-icon hlm name="lucideGripVertical" size="10px" />
22
- </div>
15
+ <div class="bg-border z-10 flex h-6 w-1 shrink-0 rounded-lg"></div>
23
16
  }
24
17
  `,
25
18
  })
@@ -27,9 +20,9 @@ export class HlmResizableHandle {
27
20
  protected readonly _brnResizableHandle = inject(BrnResizableHandle);
28
21
 
29
22
  constructor() {
30
- classes(
31
- () =>
32
- 'bg-border focus-visible:ring-ring relative flex w-px items-center justify-center after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:ring-1 focus-visible:ring-offset-1 focus-visible:outline-none data-[panel-group-direction=horizontal]:hover:cursor-ew-resize data-[panel-group-direction=vertical]:h-px data-[panel-group-direction=vertical]:w-full data-[panel-group-direction=vertical]:after:left-0 data-[panel-group-direction=vertical]:after:h-1 data-[panel-group-direction=vertical]:after:w-full data-[panel-group-direction=vertical]:after:translate-x-0 data-[panel-group-direction=vertical]:after:-translate-y-1/2 data-[panel-group-direction=vertical]:hover:cursor-ns-resize [&[data-panel-group-direction=vertical]>div]:rotate-90',
33
- );
23
+ classes(() => [
24
+ 'bg-border focus-visible:ring-ring relative flex w-px items-center justify-center after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:ring-1 focus-visible:ring-offset-1 focus-visible:outline-hidden data-[panel-group-direction=vertical]:h-px data-[panel-group-direction=vertical]:w-full data-[panel-group-direction=vertical]:after:left-0 data-[panel-group-direction=vertical]:after:h-1 data-[panel-group-direction=vertical]:after:w-full data-[panel-group-direction=vertical]:after:translate-x-0 data-[panel-group-direction=vertical]:after:-translate-y-1/2 [&[data-panel-group-direction=vertical]>div]:rotate-90',
25
+ 'data-[panel-group-direction=horizontal]:hover:cursor-ew-resize data-[panel-group-direction=vertical]:hover:cursor-ns-resize',
26
+ ]);
34
27
  }
35
28
  }
@@ -36,7 +36,7 @@ import { injectHlmSidebarConfig } from './hlm-sidebar.token';
36
36
  data-slot="sidebar"
37
37
  data-sidebar="sidebar"
38
38
  data-mobile="true"
39
- class="bg-sidebar text-sidebar-foreground h-screen w-[var(--sidebar-width)] p-0 [&>button]:hidden"
39
+ class="bg-sidebar text-sidebar-foreground h-svh w-[var(--sidebar-width)] p-0 [&>button]:hidden"
40
40
  [style.--sidebar-width]="sidebarWidthMobile()"
41
41
  >
42
42
  <div class="flex h-full w-full flex-col">
@@ -40,7 +40,7 @@ exports.primitiveDependencies = {
40
40
  popover: ['utils'],
41
41
  progress: ['utils'],
42
42
  'radio-group': ['utils'],
43
- resizable: ['utils', 'icon'],
43
+ resizable: ['utils'],
44
44
  'scroll-area': ['utils'],
45
45
  select: ['utils', 'icon'],
46
46
  separator: ['utils'],
@@ -1 +1 @@
1
- {"version":3,"file":"primitive-deps.js","sourceRoot":"","sources":["../../../../../../libs/cli/src/generators/ui/primitive-deps.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"primitive-deps.js","sourceRoot":"","sources":["../../../../../../libs/cli/src/generators/ui/primitive-deps.ts"],"names":[],"mappings":";;;AAEa,QAAA,qBAAqB,GAAmC;IACpE,SAAS,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC;IAC5B,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,CAAC,OAAO,EAAE,QAAQ,CAAC;IACnC,cAAc,EAAE,CAAC,OAAO,CAAC;IACzB,YAAY,EAAE,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,aAAa,CAAC;IACzD,MAAM,EAAE,CAAC,OAAO,CAAC;IACjB,KAAK,EAAE,CAAC,OAAO,CAAC;IAChB,UAAU,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC;IAC7B,MAAM,EAAE,CAAC,OAAO,CAAC;IACjB,cAAc,EAAE,CAAC,OAAO,EAAE,QAAQ,CAAC;IACnC,QAAQ,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC;IAC/C,IAAI,EAAE,CAAC,OAAO,CAAC;IACf,QAAQ,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC;IACrC,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC;IAC3B,WAAW,EAAE,CAAC,OAAO,CAAC;IACtB,QAAQ,EAAE,CAAC,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,CAAC;IACpD,OAAO,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC;IACpC,cAAc,EAAE,CAAC,OAAO,EAAE,eAAe,CAAC;IAC1C,aAAa,EAAE,CAAC,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,CAAC;IACvD,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC;IAClC,KAAK,EAAE,CAAC,OAAO,CAAC;IAChB,KAAK,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,WAAW,CAAC;IACtC,YAAY,EAAE,CAAC,OAAO,CAAC;IACvB,YAAY,EAAE,CAAC,OAAO,CAAC;IACvB,IAAI,EAAE,EAAE;IACR,KAAK,EAAE,CAAC,OAAO,CAAC;IAChB,aAAa,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,CAAC;IACvD,WAAW,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC;IAC9B,IAAI,EAAE,CAAC,OAAO,EAAE,WAAW,CAAC;IAC5B,GAAG,EAAE,CAAC,OAAO,CAAC;IACd,KAAK,EAAE,CAAC,OAAO,CAAC;IAChB,OAAO,EAAE,CAAC,OAAO,EAAE,eAAe,CAAC;IACnC,iBAAiB,EAAE,CAAC,OAAO,CAAC;IAC5B,UAAU,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC;IACjD,OAAO,EAAE,CAAC,OAAO,CAAC;IAClB,QAAQ,EAAE,CAAC,OAAO,CAAC;IACnB,aAAa,EAAE,CAAC,OAAO,CAAC;IACxB,SAAS,EAAE,CAAC,OAAO,CAAC;IACpB,aAAa,EAAE,CAAC,OAAO,CAAC;IACxB,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,SAAS,EAAE,CAAC,OAAO,CAAC;IACpB,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,CAAC;IAC1F,QAAQ,EAAE,CAAC,OAAO,CAAC;IACnB,MAAM,EAAE,CAAC,OAAO,CAAC;IACjB,MAAM,EAAE,CAAC,OAAO,CAAC;IACjB,OAAO,EAAE,CAAC,OAAO,CAAC;IAClB,MAAM,EAAE,CAAC,OAAO,CAAC;IACjB,KAAK,EAAE,CAAC,OAAO,CAAC;IAChB,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,CAAC,OAAO,CAAC;IACnB,MAAM,EAAE,CAAC,OAAO,CAAC;IACjB,cAAc,EAAE,CAAC,OAAO,EAAE,QAAQ,CAAC;IACnC,OAAO,EAAE,EAAE;IACX,UAAU,EAAE,CAAC,OAAO,CAAC;IACrB,KAAK,EAAE,EAAE;CACT,CAAC;AAEK,MAAM,sBAAsB,GAAG,CAAC,UAAuB,EAAe,EAAE;IAC9E,MAAM,mBAAmB,GAAG,IAAI,GAAG,EAAa,CAAC;IAEjD,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACpC,MAAM,IAAI,GAAG,6BAAqB,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;QACpD,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACxB,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC/B,2FAA2F;gBAC3F,mBAAmB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;gBAC7B,IAAA,8BAAsB,EAAC,CAAC,GAAG,CAAC,CAAC;qBAC3B,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,mBAAmB,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;qBAC7F,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YAC9C,CAAC;QACF,CAAC;IACF,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;AACxC,CAAC,CAAC;AAjBW,QAAA,sBAAsB,0BAiBjC"}
@@ -3,7 +3,7 @@
3
3
  "name": "accordion",
4
4
  "peerDependencies": {
5
5
  "@angular/core": ">=20.0.0 <22.0.0",
6
- "@spartan-ng/brain": "0.0.1-alpha.608",
6
+ "@spartan-ng/brain": "0.0.1-alpha.610",
7
7
  "@ng-icons/core": ">=32.0.0 <34.0.0",
8
8
  "@ng-icons/lucide": ">=32.0.0 <34.0.0"
9
9
  }
@@ -19,7 +19,7 @@
19
19
  "name": "alert-dialog",
20
20
  "peerDependencies": {
21
21
  "@angular/core": ">=20.0.0 <22.0.0",
22
- "@spartan-ng/brain": "0.0.1-alpha.608",
22
+ "@spartan-ng/brain": "0.0.1-alpha.610",
23
23
  "clsx": "^2.1.1"
24
24
  }
25
25
  },
@@ -34,20 +34,17 @@
34
34
  "name": "autocomplete",
35
35
  "peerDependencies": {
36
36
  "@angular/core": ">=20.0.0 <22.0.0",
37
- "@spartan-ng/brain": "0.0.1-alpha.608",
37
+ "@spartan-ng/brain": "0.0.1-alpha.610",
38
38
  "@angular/cdk": ">=20.0.0 <22.0.0",
39
- "@angular/common": ">=20.0.0 <22.0.0",
40
- "@angular/forms": ">=20.0.0 <22.0.0",
41
39
  "@ng-icons/core": ">=32.0.0 <34.0.0",
42
- "@ng-icons/lucide": ">=32.0.0 <34.0.0",
43
- "clsx": "^2.1.1"
40
+ "@ng-icons/lucide": ">=32.0.0 <34.0.0"
44
41
  }
45
42
  },
46
43
  "avatar": {
47
44
  "name": "avatar",
48
45
  "peerDependencies": {
49
46
  "@angular/core": ">=20.0.0 <22.0.0",
50
- "@spartan-ng/brain": "0.0.1-alpha.608"
47
+ "@spartan-ng/brain": "0.0.1-alpha.610"
51
48
  }
52
49
  },
53
50
  "badge": {
@@ -71,7 +68,7 @@
71
68
  "name": "button",
72
69
  "peerDependencies": {
73
70
  "@angular/core": ">=20.0.0 <22.0.0",
74
- "@spartan-ng/brain": "0.0.1-alpha.608",
71
+ "@spartan-ng/brain": "0.0.1-alpha.610",
75
72
  "class-variance-authority": "^0.7.0",
76
73
  "clsx": "^2.1.1"
77
74
  }
@@ -80,7 +77,7 @@
80
77
  "name": "button-group",
81
78
  "peerDependencies": {
82
79
  "@angular/core": ">=20.0.0 <22.0.0",
83
- "@spartan-ng/brain": "0.0.1-alpha.608",
80
+ "@spartan-ng/brain": "0.0.1-alpha.610",
84
81
  "class-variance-authority": "^0.7.0"
85
82
  }
86
83
  },
@@ -92,7 +89,7 @@
92
89
  "@angular/core": ">=20.0.0 <22.0.0",
93
90
  "@ng-icons/core": ">=32.0.0 <34.0.0",
94
91
  "@ng-icons/lucide": ">=32.0.0 <34.0.0",
95
- "@spartan-ng/brain": "0.0.1-alpha.608",
92
+ "@spartan-ng/brain": "0.0.1-alpha.610",
96
93
  "clsx": "^2.1.1"
97
94
  }
98
95
  },
@@ -121,7 +118,7 @@
121
118
  "@angular/cdk": ">=20.0.0 <22.0.0",
122
119
  "@ng-icons/core": ">=32.0.0 <34.0.0",
123
120
  "@ng-icons/lucide": ">=32.0.0 <34.0.0",
124
- "@spartan-ng/brain": "0.0.1-alpha.608",
121
+ "@spartan-ng/brain": "0.0.1-alpha.610",
125
122
  "clsx": "^2.1.1"
126
123
  }
127
124
  },
@@ -129,14 +126,14 @@
129
126
  "name": "collapsible",
130
127
  "peerDependencies": {
131
128
  "@angular/core": ">=20.0.0 <22.0.0",
132
- "@spartan-ng/brain": "0.0.1-alpha.608"
129
+ "@spartan-ng/brain": "0.0.1-alpha.610"
133
130
  }
134
131
  },
135
132
  "combobox": {
136
133
  "name": "combobox",
137
134
  "peerDependencies": {
138
135
  "@angular/core": ">=20.0.0 <22.0.0",
139
- "@spartan-ng/brain": "0.0.1-alpha.608",
136
+ "@spartan-ng/brain": "0.0.1-alpha.610",
140
137
  "@angular/cdk": ">=20.0.0 <22.0.0",
141
138
  "@ng-icons/core": ">=32.0.0 <34.0.0",
142
139
  "@ng-icons/lucide": ">=32.0.0 <34.0.0",
@@ -147,14 +144,14 @@
147
144
  "name": "command",
148
145
  "peerDependencies": {
149
146
  "@angular/core": ">=20.0.0 <22.0.0",
150
- "@spartan-ng/brain": "0.0.1-alpha.608"
147
+ "@spartan-ng/brain": "0.0.1-alpha.610"
151
148
  }
152
149
  },
153
150
  "context-menu": {
154
151
  "name": "context-menu",
155
152
  "peerDependencies": {
156
153
  "@angular/core": ">=20.0.0 <22.0.0",
157
- "@spartan-ng/brain": "0.0.1-alpha.608",
154
+ "@spartan-ng/brain": "0.0.1-alpha.610",
158
155
  "@angular/cdk": ">=20.0.0 <22.0.0",
159
156
  "rxjs": "^7.8.0"
160
157
  }
@@ -167,7 +164,7 @@
167
164
  "@angular/forms": ">=20.0.0 <22.0.0",
168
165
  "@ng-icons/core": ">=32.0.0 <34.0.0",
169
166
  "@ng-icons/lucide": ">=32.0.0 <34.0.0",
170
- "@spartan-ng/brain": "0.0.1-alpha.608",
167
+ "@spartan-ng/brain": "0.0.1-alpha.610",
171
168
  "clsx": "^2.1.1"
172
169
  }
173
170
  },
@@ -175,7 +172,7 @@
175
172
  "name": "dialog",
176
173
  "peerDependencies": {
177
174
  "@angular/core": ">=20.0.0 <22.0.0",
178
- "@spartan-ng/brain": "0.0.1-alpha.608",
175
+ "@spartan-ng/brain": "0.0.1-alpha.610",
179
176
  "@angular/cdk": ">=20.0.0 <22.0.0",
180
177
  "@angular/common": ">=20.0.0 <22.0.0",
181
178
  "@ng-icons/core": ">=32.0.0 <34.0.0",
@@ -191,7 +188,7 @@
191
188
  "@ng-icons/lucide": ">=32.0.0 <34.0.0",
192
189
  "@angular/cdk": ">=20.0.0 <22.0.0",
193
190
  "rxjs": "^7.8.0",
194
- "@spartan-ng/brain": "0.0.1-alpha.608"
191
+ "@spartan-ng/brain": "0.0.1-alpha.610"
195
192
  }
196
193
  },
197
194
  "empty": {
@@ -214,14 +211,14 @@
214
211
  "peerDependencies": {
215
212
  "@angular/core": ">=20.0.0 <22.0.0",
216
213
  "@angular/forms": ">=20.0.0 <22.0.0",
217
- "@spartan-ng/brain": "0.0.1-alpha.608"
214
+ "@spartan-ng/brain": "0.0.1-alpha.610"
218
215
  }
219
216
  },
220
217
  "hover-card": {
221
218
  "name": "hover-card",
222
219
  "peerDependencies": {
223
220
  "@angular/core": ">=20.0.0 <22.0.0",
224
- "@spartan-ng/brain": "0.0.1-alpha.608"
221
+ "@spartan-ng/brain": "0.0.1-alpha.610"
225
222
  }
226
223
  },
227
224
  "icon": {
@@ -237,7 +234,7 @@
237
234
  "peerDependencies": {
238
235
  "@angular/core": ">=20.0.0 <22.0.0",
239
236
  "@angular/forms": ">=20.0.0 <22.0.0",
240
- "@spartan-ng/brain": "0.0.1-alpha.608",
237
+ "@spartan-ng/brain": "0.0.1-alpha.610",
241
238
  "class-variance-authority": "^0.7.0",
242
239
  "clsx": "^2.1.1"
243
240
  }
@@ -256,7 +253,7 @@
256
253
  "@ng-icons/core": ">=32.0.0 <34.0.0",
257
254
  "@ng-icons/lucide": ">=32.0.0 <34.0.0",
258
255
  "@angular/cdk": ">=20.0.0 <22.0.0",
259
- "@spartan-ng/brain": "0.0.1-alpha.608"
256
+ "@spartan-ng/brain": "0.0.1-alpha.610"
260
257
  }
261
258
  },
262
259
  "item": {
@@ -264,7 +261,7 @@
264
261
  "peerDependencies": {
265
262
  "@angular/core": ">=20.0.0 <22.0.0",
266
263
  "class-variance-authority": "^0.7.0",
267
- "@spartan-ng/brain": "0.0.1-alpha.608"
264
+ "@spartan-ng/brain": "0.0.1-alpha.610"
268
265
  }
269
266
  },
270
267
  "kbd": {
@@ -277,14 +274,14 @@
277
274
  "name": "label",
278
275
  "peerDependencies": {
279
276
  "@angular/core": ">=20.0.0 <22.0.0",
280
- "@spartan-ng/brain": "0.0.1-alpha.608"
277
+ "@spartan-ng/brain": "0.0.1-alpha.610"
281
278
  }
282
279
  },
283
280
  "menubar": {
284
281
  "name": "menubar",
285
282
  "peerDependencies": {
286
283
  "@angular/core": ">=20.0.0 <22.0.0",
287
- "@spartan-ng/brain": "0.0.1-alpha.608",
284
+ "@spartan-ng/brain": "0.0.1-alpha.610",
288
285
  "@angular/cdk": ">=20.0.0 <22.0.0",
289
286
  "rxjs": "^7.8.0"
290
287
  }
@@ -293,7 +290,7 @@
293
290
  "name": "navigation-menu",
294
291
  "peerDependencies": {
295
292
  "@angular/core": ">=20.0.0 <22.0.0",
296
- "@spartan-ng/brain": "0.0.1-alpha.608"
293
+ "@spartan-ng/brain": "0.0.1-alpha.610"
297
294
  }
298
295
  },
299
296
  "pagination": {
@@ -302,7 +299,7 @@
302
299
  "@angular/cdk": ">=20.0.0 <22.0.0",
303
300
  "@angular/core": ">=20.0.0 <22.0.0",
304
301
  "@angular/forms": ">=20.0.0 <22.0.0",
305
- "@spartan-ng/brain": "0.0.1-alpha.608",
302
+ "@spartan-ng/brain": "0.0.1-alpha.610",
306
303
  "@ng-icons/core": ">=32.0.0 <34.0.0",
307
304
  "@ng-icons/lucide": ">=32.0.0 <34.0.0",
308
305
  "@angular/router": ">=20.0.0 <22.0.0"
@@ -312,21 +309,21 @@
312
309
  "name": "popover",
313
310
  "peerDependencies": {
314
311
  "@angular/core": ">=20.0.0 <22.0.0",
315
- "@spartan-ng/brain": "0.0.1-alpha.608"
312
+ "@spartan-ng/brain": "0.0.1-alpha.610"
316
313
  }
317
314
  },
318
315
  "progress": {
319
316
  "name": "progress",
320
317
  "peerDependencies": {
321
318
  "@angular/core": ">=20.0.0 <22.0.0",
322
- "@spartan-ng/brain": "0.0.1-alpha.608"
319
+ "@spartan-ng/brain": "0.0.1-alpha.610"
323
320
  }
324
321
  },
325
322
  "radio-group": {
326
323
  "name": "radio-group",
327
324
  "peerDependencies": {
328
325
  "@angular/core": ">=20.0.0 <22.0.0",
329
- "@spartan-ng/brain": "0.0.1-alpha.608",
326
+ "@spartan-ng/brain": "0.0.1-alpha.610",
330
327
  "@angular/cdk": ">=20.0.0 <22.0.0",
331
328
  "@angular/common": ">=20.0.0 <22.0.0",
332
329
  "clsx": "^2.1.1"
@@ -336,9 +333,7 @@
336
333
  "name": "resizable",
337
334
  "peerDependencies": {
338
335
  "@angular/core": ">=20.0.0 <22.0.0",
339
- "@spartan-ng/brain": "0.0.1-alpha.608",
340
- "@ng-icons/core": ">=32.0.0 <34.0.0",
341
- "@ng-icons/lucide": ">=32.0.0 <34.0.0"
336
+ "@spartan-ng/brain": "0.0.1-alpha.610"
342
337
  }
343
338
  },
344
339
  "scroll-area": {
@@ -352,7 +347,7 @@
352
347
  "peerDependencies": {
353
348
  "@angular/cdk": ">=20.0.0 <22.0.0",
354
349
  "@angular/core": ">=20.0.0 <22.0.0",
355
- "@spartan-ng/brain": "0.0.1-alpha.608",
350
+ "@spartan-ng/brain": "0.0.1-alpha.610",
356
351
  "@ng-icons/core": ">=32.0.0 <34.0.0",
357
352
  "@ng-icons/lucide": ">=32.0.0 <34.0.0",
358
353
  "class-variance-authority": "^0.7.0",
@@ -363,14 +358,14 @@
363
358
  "name": "separator",
364
359
  "peerDependencies": {
365
360
  "@angular/core": ">=20.0.0 <22.0.0",
366
- "@spartan-ng/brain": "0.0.1-alpha.608"
361
+ "@spartan-ng/brain": "0.0.1-alpha.610"
367
362
  }
368
363
  },
369
364
  "sheet": {
370
365
  "name": "sheet",
371
366
  "peerDependencies": {
372
367
  "@angular/core": ">=20.0.0 <22.0.0",
373
- "@spartan-ng/brain": "0.0.1-alpha.608",
368
+ "@spartan-ng/brain": "0.0.1-alpha.610",
374
369
  "@ng-icons/core": ">=32.0.0 <34.0.0",
375
370
  "@ng-icons/lucide": ">=32.0.0 <34.0.0",
376
371
  "class-variance-authority": "^0.7.0",
@@ -382,7 +377,7 @@
382
377
  "peerDependencies": {
383
378
  "@angular/core": ">=20.0.0 <22.0.0",
384
379
  "@angular/cdk": ">=20.0.0 <22.0.0",
385
- "@spartan-ng/brain": "0.0.1-alpha.608",
380
+ "@spartan-ng/brain": "0.0.1-alpha.610",
386
381
  "class-variance-authority": "^0.7.0",
387
382
  "@ng-icons/core": ">=32.0.0 <34.0.0",
388
383
  "@ng-icons/lucide": ">=32.0.0 <34.0.0",
@@ -400,7 +395,7 @@
400
395
  "name": "slider",
401
396
  "peerDependencies": {
402
397
  "@angular/core": ">=20.0.0 <22.0.0",
403
- "@spartan-ng/brain": "0.0.1-alpha.608"
398
+ "@spartan-ng/brain": "0.0.1-alpha.610"
404
399
  }
405
400
  },
406
401
  "sonner": {
@@ -425,7 +420,7 @@
425
420
  "@angular/core": ">=20.0.0 <22.0.0",
426
421
  "@angular/cdk": ">=20.0.0 <22.0.0",
427
422
  "@angular/forms": ">=20.0.0 <22.0.0",
428
- "@spartan-ng/brain": "0.0.1-alpha.608",
423
+ "@spartan-ng/brain": "0.0.1-alpha.610",
429
424
  "clsx": "^2.1.1"
430
425
  }
431
426
  },
@@ -439,7 +434,7 @@
439
434
  "name": "tabs",
440
435
  "peerDependencies": {
441
436
  "@angular/core": ">=20.0.0 <22.0.0",
442
- "@spartan-ng/brain": "0.0.1-alpha.608",
437
+ "@spartan-ng/brain": "0.0.1-alpha.610",
443
438
  "class-variance-authority": "^0.7.0",
444
439
  "@angular/cdk": ">=20.0.0 <22.0.0",
445
440
  "@ng-icons/core": ">=32.0.0 <34.0.0",
@@ -453,7 +448,7 @@
453
448
  "peerDependencies": {
454
449
  "@angular/core": ">=20.0.0 <22.0.0",
455
450
  "@angular/forms": ">=20.0.0 <22.0.0",
456
- "@spartan-ng/brain": "0.0.1-alpha.608",
451
+ "@spartan-ng/brain": "0.0.1-alpha.610",
457
452
  "class-variance-authority": "^0.7.0",
458
453
  "clsx": "^2.1.1"
459
454
  }
@@ -462,7 +457,7 @@
462
457
  "name": "toggle",
463
458
  "peerDependencies": {
464
459
  "@angular/core": ">=20.0.0 <22.0.0",
465
- "@spartan-ng/brain": "0.0.1-alpha.608",
460
+ "@spartan-ng/brain": "0.0.1-alpha.610",
466
461
  "class-variance-authority": "^0.7.0"
467
462
  }
468
463
  },
@@ -470,7 +465,7 @@
470
465
  "name": "toggle-group",
471
466
  "peerDependencies": {
472
467
  "@angular/core": ">=20.0.0 <22.0.0",
473
- "@spartan-ng/brain": "0.0.1-alpha.608",
468
+ "@spartan-ng/brain": "0.0.1-alpha.610",
474
469
  "@angular/cdk": ">=20.0.0 <22.0.0"
475
470
  }
476
471
  },
@@ -478,7 +473,7 @@
478
473
  "name": "tooltip",
479
474
  "peerDependencies": {
480
475
  "@angular/core": ">=20.0.0 <22.0.0",
481
- "@spartan-ng/brain": "0.0.1-alpha.608"
476
+ "@spartan-ng/brain": "0.0.1-alpha.610"
482
477
  }
483
478
  },
484
479
  "typography": {
@@ -1,32 +0,0 @@
1
- import type { BooleanInput } from '@angular/cdk/coercion';
2
- import { booleanAttribute, Directive, ElementRef, inject, input } from '@angular/core';
3
- import { BrnDialog } from '@spartan-ng/brain/dialog';
4
-
5
- @Directive({
6
- selector: '[hlmAutocompleteTrigger]',
7
- host: {
8
- '(click)': 'open()',
9
- },
10
- })
11
- export class HlmAutocompleteTrigger {
12
- private readonly _host = inject(ElementRef, { host: true });
13
-
14
- private readonly _brnDialog = inject(BrnDialog, { optional: true });
15
-
16
- /** Whether the trigger is disabled. */
17
- public readonly disabledTrigger = input<boolean, BooleanInput>(false, {
18
- transform: booleanAttribute,
19
- });
20
-
21
- constructor() {
22
- if (!this._brnDialog) return;
23
-
24
- this._brnDialog.mutableAttachTo.set(this._host.nativeElement);
25
- }
26
-
27
- open() {
28
- if (this.disabledTrigger()) return;
29
-
30
- this._brnDialog?.open();
31
- }
32
- }
@@ -1,35 +0,0 @@
1
- import { inject, InjectionToken, type ValueProvider } from '@angular/core';
2
-
3
- export type TransformValueToString<T> = (option: T) => string;
4
-
5
- export interface HlmAutocompleteConfig<T, V = T> {
6
- transformValueToSearch: TransformValueToString<T>;
7
- transformOptionToString: TransformValueToString<T>;
8
- transformOptionToValue: ((option: T) => V) | undefined;
9
- requireSelection: boolean;
10
- showClearBtn: boolean;
11
- debounceTime: number;
12
- }
13
-
14
- function getDefaultConfig<T, V = T>(): HlmAutocompleteConfig<T, V> {
15
- return {
16
- transformValueToSearch: (option: T) => (typeof option === 'string' ? option : String(option)),
17
- transformOptionToString: (option: T) => (typeof option === 'string' ? option : String(option)),
18
- transformOptionToValue: undefined,
19
- requireSelection: false,
20
- showClearBtn: false,
21
- debounceTime: 150,
22
- };
23
- }
24
-
25
- const HlmAutocompleteConfigToken = new InjectionToken<HlmAutocompleteConfig<unknown, unknown>>('HlmAutocompleteConfig');
26
-
27
- export function provideHlmAutocompleteConfig<T, V = T>(config: Partial<HlmAutocompleteConfig<T, V>>): ValueProvider {
28
- return { provide: HlmAutocompleteConfigToken, useValue: { ...getDefaultConfig(), ...config } };
29
- }
30
-
31
- export function injectHlmAutocompleteConfig<T, V = T>(): HlmAutocompleteConfig<T, V> {
32
- return (
33
- (inject(HlmAutocompleteConfigToken, { optional: true }) as HlmAutocompleteConfig<T, V> | null) ?? getDefaultConfig()
34
- );
35
- }