@spartan-ng/cli 0.0.1-alpha.451 → 0.0.1-alpha.453

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spartan-ng/cli",
3
- "version": "0.0.1-alpha.451",
3
+ "version": "0.0.1-alpha.453",
4
4
  "type": "commonjs",
5
5
  "dependencies": {
6
6
  "@nx/angular": ">=20.0.0",
@@ -1,4 +1,17 @@
1
- import { booleanAttribute, Component, computed, input, output } from '@angular/core';
1
+ import { DOCUMENT, isPlatformBrowser } from '@angular/common';
2
+ import {
3
+ booleanAttribute,
4
+ Component,
5
+ computed,
6
+ effect,
7
+ ElementRef,
8
+ inject,
9
+ input,
10
+ output,
11
+ PLATFORM_ID,
12
+ Renderer2,
13
+ signal,
14
+ } from '@angular/core';
2
15
  import { hlm } from '@spartan-ng/brain/core';
3
16
  import { BrnRadioChange, BrnRadioComponent } from '@spartan-ng/brain/radio-group';
4
17
  import { ClassValue } from 'clsx';
@@ -24,6 +37,11 @@ import { ClassValue } from 'clsx';
24
37
  `,
25
38
  })
26
39
  export class HlmRadioComponent<T = unknown> {
40
+ private readonly _document = inject(DOCUMENT);
41
+ private readonly _renderer = inject(Renderer2);
42
+ private readonly _elementRef = inject(ElementRef);
43
+ private readonly _isBrowser = isPlatformBrowser(inject(PLATFORM_ID));
44
+
27
45
  public readonly userClass = input<ClassValue>('', { alias: 'class' });
28
46
  protected _computedClass = computed(() =>
29
47
  hlm(
@@ -55,8 +73,30 @@ export class HlmRadioComponent<T = unknown> {
55
73
  /** Whether the checkbox is disabled. */
56
74
  public readonly disabled = input(false, { transform: booleanAttribute });
57
75
 
76
+ protected readonly state = computed(() => {
77
+ const id = this.id();
78
+ return {
79
+ disabled: signal(this.disabled()),
80
+ id: id ? id : null,
81
+ };
82
+ });
58
83
  /**
59
84
  * Event emitted when the checked state of this radio button changes.
60
85
  */
61
86
  public readonly change = output<BrnRadioChange<T>>();
87
+
88
+ constructor() {
89
+ effect(() => {
90
+ const state = this.state();
91
+ const isDisabled = state.disabled();
92
+
93
+ if (!this._elementRef.nativeElement || !this._isBrowser) return;
94
+
95
+ const labelElement =
96
+ this._elementRef.nativeElement.closest('label') ?? this._document.querySelector(`label[for="${state.id}"]`);
97
+
98
+ if (!labelElement) return;
99
+ this._renderer.setAttribute(labelElement, 'data-disabled', isDisabled ? 'true' : 'false');
100
+ });
101
+ }
62
102
  }
@@ -5,7 +5,7 @@
5
5
  "@angular/core": ">=19.0.0",
6
6
  "@ng-icons/core": ">=29.0.0",
7
7
  "@ng-icons/lucide": ">=29.0.0",
8
- "@spartan-ng/brain": "0.0.1-alpha.451",
8
+ "@spartan-ng/brain": "0.0.1-alpha.453",
9
9
  "@spartan-ng/ui-icon-helm": "0.0.1-alpha.381",
10
10
  "clsx": "^2.1.1"
11
11
  }
@@ -14,7 +14,7 @@
14
14
  "internalName": "ui-alert-helm",
15
15
  "peerDependencies": {
16
16
  "@angular/core": ">=19.0.0",
17
- "@spartan-ng/brain": "0.0.1-alpha.451",
17
+ "@spartan-ng/brain": "0.0.1-alpha.453",
18
18
  "@spartan-ng/ui-icon-helm": "0.0.1-alpha.381",
19
19
  "class-variance-authority": "^0.7.0",
20
20
  "clsx": "^2.1.1"
@@ -24,7 +24,7 @@
24
24
  "internalName": "ui-alert-dialog-helm",
25
25
  "peerDependencies": {
26
26
  "@angular/core": ">=19.0.0",
27
- "@spartan-ng/brain": "0.0.1-alpha.451",
27
+ "@spartan-ng/brain": "0.0.1-alpha.453",
28
28
  "@spartan-ng/ui-button-helm": "0.0.1-alpha.381",
29
29
  "clsx": "^2.1.1"
30
30
  }
@@ -34,7 +34,7 @@
34
34
  "peerDependencies": {
35
35
  "@angular/cdk": ">=19.0.0",
36
36
  "@angular/core": ">=19.0.0",
37
- "@spartan-ng/brain": "0.0.1-alpha.451",
37
+ "@spartan-ng/brain": "0.0.1-alpha.453",
38
38
  "clsx": "^2.1.1"
39
39
  }
40
40
  },
@@ -42,7 +42,7 @@
42
42
  "internalName": "ui-avatar-helm",
43
43
  "peerDependencies": {
44
44
  "@angular/core": ">=19.0.0",
45
- "@spartan-ng/brain": "0.0.1-alpha.451",
45
+ "@spartan-ng/brain": "0.0.1-alpha.453",
46
46
  "class-variance-authority": "^0.7.0",
47
47
  "clsx": "^2.1.1"
48
48
  }
@@ -52,7 +52,7 @@
52
52
  "peerDependencies": {
53
53
  "@angular/cdk": ">=19.0.0",
54
54
  "@angular/core": ">=19.0.0",
55
- "@spartan-ng/brain": "0.0.1-alpha.451",
55
+ "@spartan-ng/brain": "0.0.1-alpha.453",
56
56
  "class-variance-authority": "^0.7.0",
57
57
  "clsx": "^2.1.1"
58
58
  }
@@ -64,7 +64,7 @@
64
64
  "@angular/router": ">=19.0.0",
65
65
  "@ng-icons/core": ">=29.0.0",
66
66
  "@ng-icons/lucide": ">=29.0.0",
67
- "@spartan-ng/brain": "0.0.1-alpha.451",
67
+ "@spartan-ng/brain": "0.0.1-alpha.453",
68
68
  "@spartan-ng/ui-icon-helm": "0.0.1-alpha.381",
69
69
  "clsx": "^2.1.1"
70
70
  }
@@ -73,7 +73,7 @@
73
73
  "internalName": "ui-button-helm",
74
74
  "peerDependencies": {
75
75
  "@angular/core": ">=19.0.0",
76
- "@spartan-ng/brain": "0.0.1-alpha.451",
76
+ "@spartan-ng/brain": "0.0.1-alpha.453",
77
77
  "class-variance-authority": "^0.7.0",
78
78
  "clsx": "^2.1.1"
79
79
  }
@@ -85,7 +85,7 @@
85
85
  "@angular/core": ">=19.0.0",
86
86
  "@ng-icons/core": ">=29.0.0",
87
87
  "@ng-icons/lucide": ">=29.0.0",
88
- "@spartan-ng/brain": "0.0.1-alpha.451",
88
+ "@spartan-ng/brain": "0.0.1-alpha.453",
89
89
  "@spartan-ng/ui-button-helm": "0.0.1-alpha.381",
90
90
  "@spartan-ng/ui-icon-helm": "0.0.1-alpha.381",
91
91
  "clsx": "^2.1.1"
@@ -95,7 +95,7 @@
95
95
  "internalName": "ui-card-helm",
96
96
  "peerDependencies": {
97
97
  "@angular/core": ">=19.0.0",
98
- "@spartan-ng/brain": "0.0.1-alpha.451",
98
+ "@spartan-ng/brain": "0.0.1-alpha.453",
99
99
  "class-variance-authority": "^0.7.0",
100
100
  "clsx": "^2.1.1"
101
101
  }
@@ -105,7 +105,7 @@
105
105
  "peerDependencies": {
106
106
  "@angular/cdk": ">=19.0.0",
107
107
  "@angular/core": ">=19.0.0",
108
- "@spartan-ng/brain": "0.0.1-alpha.451",
108
+ "@spartan-ng/brain": "0.0.1-alpha.453",
109
109
  "@spartan-ng/ui-button-helm": "0.0.1-alpha.381",
110
110
  "@spartan-ng/ui-icon-helm": "0.0.1-alpha.381",
111
111
  "clsx": "^2.1.1"
@@ -119,7 +119,7 @@
119
119
  "@angular/forms": ">=19.0.0",
120
120
  "@ng-icons/core": ">=29.0.0",
121
121
  "@ng-icons/lucide": ">=29.0.0",
122
- "@spartan-ng/brain": "0.0.1-alpha.451",
122
+ "@spartan-ng/brain": "0.0.1-alpha.453",
123
123
  "@spartan-ng/ui-calendar-helm": "0.0.1-alpha.381",
124
124
  "@spartan-ng/ui-icon-helm": "0.0.1-alpha.381",
125
125
  "@spartan-ng/ui-popover-helm": "0.0.1-alpha.381",
@@ -134,7 +134,7 @@
134
134
  "@angular/core": ">=19.0.0",
135
135
  "@ng-icons/core": ">=29.0.0",
136
136
  "@ng-icons/lucide": ">=29.0.0",
137
- "@spartan-ng/brain": "0.0.1-alpha.451",
137
+ "@spartan-ng/brain": "0.0.1-alpha.453",
138
138
  "@spartan-ng/ui-icon-helm": "0.0.1-alpha.381",
139
139
  "clsx": "^2.1.1"
140
140
  }
@@ -150,7 +150,7 @@
150
150
  "peerDependencies": {
151
151
  "@angular/core": ">=19.0.0",
152
152
  "@angular/forms": ">=19.0.0",
153
- "@spartan-ng/brain": "0.0.1-alpha.451",
153
+ "@spartan-ng/brain": "0.0.1-alpha.453",
154
154
  "class-variance-authority": "^0.7.0",
155
155
  "clsx": "^2.1.1"
156
156
  }
@@ -159,7 +159,7 @@
159
159
  "internalName": "ui-label-helm",
160
160
  "peerDependencies": {
161
161
  "@angular/core": ">=19.0.0",
162
- "@spartan-ng/brain": "0.0.1-alpha.451",
162
+ "@spartan-ng/brain": "0.0.1-alpha.453",
163
163
  "class-variance-authority": "^0.7.0",
164
164
  "clsx": "^2.1.1"
165
165
  }
@@ -170,7 +170,7 @@
170
170
  "@angular/core": ">=19.0.0",
171
171
  "@ng-icons/core": ">=29.0.0",
172
172
  "@ng-icons/lucide": ">=29.0.0",
173
- "@spartan-ng/brain": "0.0.1-alpha.451",
173
+ "@spartan-ng/brain": "0.0.1-alpha.453",
174
174
  "@spartan-ng/ui-icon-helm": "0.0.1-alpha.381",
175
175
  "class-variance-authority": "^0.7.0",
176
176
  "clsx": "^2.1.1"
@@ -180,7 +180,7 @@
180
180
  "internalName": "ui-popover-helm",
181
181
  "peerDependencies": {
182
182
  "@angular/core": ">=19.0.0",
183
- "@spartan-ng/brain": "0.0.1-alpha.451",
183
+ "@spartan-ng/brain": "0.0.1-alpha.453",
184
184
  "clsx": "^2.1.1"
185
185
  }
186
186
  },
@@ -188,15 +188,16 @@
188
188
  "internalName": "ui-progress-helm",
189
189
  "peerDependencies": {
190
190
  "@angular/core": ">=19.0.0",
191
- "@spartan-ng/brain": "0.0.1-alpha.451",
191
+ "@spartan-ng/brain": "0.0.1-alpha.453",
192
192
  "clsx": "^2.1.1"
193
193
  }
194
194
  },
195
195
  "radiogroup": {
196
196
  "internalName": "ui-radio-group-helm",
197
197
  "peerDependencies": {
198
+ "@angular/common": ">=19.0.0",
198
199
  "@angular/core": ">=19.0.0",
199
- "@spartan-ng/brain": "0.0.1-alpha.451",
200
+ "@spartan-ng/brain": "0.0.1-alpha.453",
200
201
  "clsx": "^2.1.1"
201
202
  }
202
203
  },
@@ -204,7 +205,7 @@
204
205
  "internalName": "ui-scroll-area-helm",
205
206
  "peerDependencies": {
206
207
  "@angular/core": ">=19.0.0",
207
- "@spartan-ng/brain": "0.0.1-alpha.451",
208
+ "@spartan-ng/brain": "0.0.1-alpha.453",
208
209
  "clsx": "^2.1.1",
209
210
  "ngx-scrollbar": ">=16.0.0"
210
211
  }
@@ -213,7 +214,7 @@
213
214
  "internalName": "ui-separator-helm",
214
215
  "peerDependencies": {
215
216
  "@angular/core": ">=19.0.0",
216
- "@spartan-ng/brain": "0.0.1-alpha.451",
217
+ "@spartan-ng/brain": "0.0.1-alpha.453",
217
218
  "clsx": "^2.1.1"
218
219
  }
219
220
  },
@@ -223,7 +224,7 @@
223
224
  "@angular/core": ">=19.0.0",
224
225
  "@ng-icons/core": ">=29.0.0",
225
226
  "@ng-icons/lucide": ">=29.0.0",
226
- "@spartan-ng/brain": "0.0.1-alpha.451",
227
+ "@spartan-ng/brain": "0.0.1-alpha.453",
227
228
  "@spartan-ng/ui-icon-helm": "0.0.1-alpha.381",
228
229
  "class-variance-authority": "^0.7.0",
229
230
  "clsx": "^2.1.1"
@@ -233,7 +234,7 @@
233
234
  "internalName": "ui-skeleton-helm",
234
235
  "peerDependencies": {
235
236
  "@angular/core": ">=19.0.0",
236
- "@spartan-ng/brain": "0.0.1-alpha.451",
237
+ "@spartan-ng/brain": "0.0.1-alpha.453",
237
238
  "clsx": "^2.1.1"
238
239
  }
239
240
  },
@@ -241,7 +242,7 @@
241
242
  "internalName": "ui-spinner-helm",
242
243
  "peerDependencies": {
243
244
  "@angular/core": ">=19.0.0",
244
- "@spartan-ng/brain": "0.0.1-alpha.451",
245
+ "@spartan-ng/brain": "0.0.1-alpha.453",
245
246
  "class-variance-authority": "^0.7.0",
246
247
  "clsx": "^2.1.1"
247
248
  }
@@ -252,7 +253,7 @@
252
253
  "@angular/cdk": ">=19.0.0",
253
254
  "@angular/core": ">=19.0.0",
254
255
  "@angular/forms": ">=19.0.0",
255
- "@spartan-ng/brain": "0.0.1-alpha.451",
256
+ "@spartan-ng/brain": "0.0.1-alpha.453",
256
257
  "clsx": "^2.1.1"
257
258
  }
258
259
  },
@@ -263,7 +264,7 @@
263
264
  "@angular/core": ">=19.0.0",
264
265
  "@ng-icons/core": ">=29.0.0",
265
266
  "@ng-icons/lucide": ">=29.0.0",
266
- "@spartan-ng/brain": "0.0.1-alpha.451",
267
+ "@spartan-ng/brain": "0.0.1-alpha.453",
267
268
  "@spartan-ng/ui-button-helm": "0.0.1-alpha.381",
268
269
  "@spartan-ng/ui-icon-helm": "0.0.1-alpha.381",
269
270
  "class-variance-authority": "^0.7.0",
@@ -274,7 +275,7 @@
274
275
  "internalName": "ui-toggle-helm",
275
276
  "peerDependencies": {
276
277
  "@angular/core": ">=19.0.0",
277
- "@spartan-ng/brain": "0.0.1-alpha.451",
278
+ "@spartan-ng/brain": "0.0.1-alpha.453",
278
279
  "class-variance-authority": "^0.7.0",
279
280
  "clsx": "^2.1.1"
280
281
  }
@@ -292,7 +293,7 @@
292
293
  "internalName": "ui-typography-helm",
293
294
  "peerDependencies": {
294
295
  "@angular/core": ">=19.0.0",
295
- "@spartan-ng/brain": "0.0.1-alpha.451",
296
+ "@spartan-ng/brain": "0.0.1-alpha.453",
296
297
  "clsx": "^2.1.1"
297
298
  }
298
299
  },
@@ -301,7 +302,7 @@
301
302
  "peerDependencies": {
302
303
  "@angular/common": ">=19.0.0",
303
304
  "@angular/core": ">=19.0.0",
304
- "@spartan-ng/brain": "0.0.1-alpha.451",
305
+ "@spartan-ng/brain": "0.0.1-alpha.453",
305
306
  "clsx": "^2.1.1"
306
307
  }
307
308
  },
@@ -309,7 +310,7 @@
309
310
  "internalName": "ui-hover-card-helm",
310
311
  "peerDependencies": {
311
312
  "@angular/core": ">=19.0.0",
312
- "@spartan-ng/brain": "0.0.1-alpha.451",
313
+ "@spartan-ng/brain": "0.0.1-alpha.453",
313
314
  "clsx": "^2.1.1"
314
315
  }
315
316
  },
@@ -320,7 +321,7 @@
320
321
  "@angular/forms": ">=19.0.0",
321
322
  "@ng-icons/core": ">=29.0.0",
322
323
  "@ng-icons/lucide": ">=29.0.0",
323
- "@spartan-ng/brain": "0.0.1-alpha.451",
324
+ "@spartan-ng/brain": "0.0.1-alpha.453",
324
325
  "@spartan-ng/ui-icon-helm": "0.0.1-alpha.381",
325
326
  "clsx": "^2.1.1"
326
327
  }
@@ -329,7 +330,7 @@
329
330
  "internalName": "ui-tooltip-helm",
330
331
  "peerDependencies": {
331
332
  "@angular/core": ">=19.0.0",
332
- "@spartan-ng/brain": "0.0.1-alpha.451"
333
+ "@spartan-ng/brain": "0.0.1-alpha.453"
333
334
  }
334
335
  },
335
336
  "pagination": {
@@ -341,7 +342,7 @@
341
342
  "@angular/router": ">=19.0.0",
342
343
  "@ng-icons/core": ">=29.0.0",
343
344
  "@ng-icons/lucide": ">=29.0.0",
344
- "@spartan-ng/brain": "0.0.1-alpha.451",
345
+ "@spartan-ng/brain": "0.0.1-alpha.453",
345
346
  "@spartan-ng/ui-button-helm": "0.0.1-alpha.381",
346
347
  "@spartan-ng/ui-icon-helm": "0.0.1-alpha.381",
347
348
  "@spartan-ng/ui-select-helm": "0.0.1-alpha.381",
@@ -355,7 +356,7 @@
355
356
  "@angular/core": ">=19.0.0",
356
357
  "@ng-icons/core": ">=29.0.0",
357
358
  "@ng-icons/lucide": ">=29.0.0",
358
- "@spartan-ng/brain": "0.0.1-alpha.451",
359
+ "@spartan-ng/brain": "0.0.1-alpha.453",
359
360
  "@spartan-ng/ui-button-helm": "0.0.1-alpha.381",
360
361
  "@spartan-ng/ui-icon-helm": "0.0.1-alpha.381",
361
362
  "clsx": "^2.1.1",
@@ -368,7 +369,7 @@
368
369
  "@angular/core": ">=19.0.0",
369
370
  "@ng-icons/core": ">=29.0.0",
370
371
  "@ng-icons/lucide": ">=29.0.0",
371
- "@spartan-ng/brain": "0.0.1-alpha.451",
372
+ "@spartan-ng/brain": "0.0.1-alpha.453",
372
373
  "@spartan-ng/ui-icon-helm": "0.0.1-alpha.381",
373
374
  "class-variance-authority": "^0.7.0",
374
375
  "clsx": "^2.1.1"
@@ -389,14 +390,14 @@
389
390
  "internalName": "ui-form-field-helm",
390
391
  "peerDependencies": {
391
392
  "@angular/core": ">=19.0.0",
392
- "@spartan-ng/brain": "0.0.1-alpha.451"
393
+ "@spartan-ng/brain": "0.0.1-alpha.453"
393
394
  }
394
395
  },
395
396
  "slider": {
396
397
  "internalName": "ui-slider-helm",
397
398
  "peerDependencies": {
398
399
  "@angular/core": ">=19.0.0",
399
- "@spartan-ng/brain": "0.0.1-alpha.451",
400
+ "@spartan-ng/brain": "0.0.1-alpha.453",
400
401
  "clsx": "^2.1.1"
401
402
  }
402
403
  },
@@ -404,7 +405,7 @@
404
405
  "internalName": "ui-toggle-group-helm",
405
406
  "peerDependencies": {
406
407
  "@angular/core": ">=18.0.0",
407
- "@spartan-ng/brain": "0.0.1-alpha.451",
408
+ "@spartan-ng/brain": "0.0.1-alpha.453",
408
409
  "class-variance-authority": "^0.7.0",
409
410
  "clsx": "^2.1.1"
410
411
  }
@@ -416,7 +417,7 @@
416
417
  "@angular/core": ">=19.0.0",
417
418
  "@ng-icons/core": "29.10.0",
418
419
  "@ng-icons/lucide": "30.3.0",
419
- "@spartan-ng/brain": "0.0.1-alpha.451",
420
+ "@spartan-ng/brain": "0.0.1-alpha.453",
420
421
  "@spartan-ng/ui-icon-helm": "0.0.1-alpha.381",
421
422
  "clsx": "^2.1.1"
422
423
  }
@@ -1,74 +0,0 @@
1
- import { Component } from '@angular/core';
2
- import { type ComponentFixture, TestBed } from '@angular/core/testing';
3
- import { HlmAspectRatioDirective } from './helm-aspect-ratio.directive';
4
-
5
- @Component({
6
- selector: 'hlm-mock',
7
- standalone: true,
8
- imports: [HlmAspectRatioDirective],
9
- template: `
10
- <div [hlmAspectRatio]="ratio">
11
- <img
12
- alt="Sample image"
13
- src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAApgAAAKYB3X3/OAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAANCSURBVEiJtZZPbBtFFMZ/M7ubXdtdb1xSFyeilBapySVU8h8OoFaooFSqiihIVIpQBKci6KEg9Q6H9kovIHoCIVQJJCKE1ENFjnAgcaSGC6rEnxBwA04Tx43t2FnvDAfjkNibxgHxnWb2e/u992bee7tCa00YFsffekFY+nUzFtjW0LrvjRXrCDIAaPLlW0nHL0SsZtVoaF98mLrx3pdhOqLtYPHChahZcYYO7KvPFxvRl5XPp1sN3adWiD1ZAqD6XYK1b/dvE5IWryTt2udLFedwc1+9kLp+vbbpoDh+6TklxBeAi9TL0taeWpdmZzQDry0AcO+jQ12RyohqqoYoo8RDwJrU+qXkjWtfi8Xxt58BdQuwQs9qC/afLwCw8tnQbqYAPsgxE1S6F3EAIXux2oQFKm0ihMsOF71dHYx+f3NND68ghCu1YIoePPQN1pGRABkJ6Bus96CutRZMydTl+TvuiRW1m3n0eDl0vRPcEysqdXn+jsQPsrHMquGeXEaY4Yk4wxWcY5V/9scqOMOVUFthatyTy8QyqwZ+kDURKoMWxNKr2EeqVKcTNOajqKoBgOE28U4tdQl5p5bwCw7BWquaZSzAPlwjlithJtp3pTImSqQRrb2Z8PHGigD4RZuNX6JYj6wj7O4TFLbCO/Mn/m8R+h6rYSUb3ekokRY6f/YukArN979jcW+V/S8g0eT/N3VN3kTqWbQ428m9/8k0P/1aIhF36PccEl6EhOcAUCrXKZXXWS3XKd2vc/TRBG9O5ELC17MmWubD2nKhUKZa26Ba2+D3P+4/MNCFwg59oWVeYhkzgN/JDR8deKBoD7Y+ljEjGZ0sosXVTvbc6RHirr2reNy1OXd6pJsQ+gqjk8VWFYmHrwBzW/n+uMPFiRwHB2I7ih8ciHFxIkd/3Omk5tCDV1t+2nNu5sxxpDFNx+huNhVT3/zMDz8usXC3ddaHBj1GHj/As08fwTS7Kt1HBTmyN29vdwAw+/wbwLVOJ3uAD1wi/dUH7Qei66PfyuRj4Ik9is+hglfbkbfR3cnZm7chlUWLdwmprtCohX4HUtlOcQjLYCu+fzGJH2QRKvP3UNz8bWk1qMxjGTOMThZ3kvgLI5AzFfo379UAAAAASUVORK5CYII="
14
- />
15
- </div>
16
- `,
17
- })
18
- class MockComponent {
19
- public ratio: number | undefined = 16 / 9;
20
- }
21
-
22
- describe('HelmAspectRatioDirective', () => {
23
- let component: MockComponent;
24
- let fixture: ComponentFixture<MockComponent>;
25
-
26
- beforeEach(() => {
27
- fixture = TestBed.createComponent(MockComponent);
28
- component = fixture.componentInstance;
29
- });
30
-
31
- it('should compile', () => {
32
- expect(component).toBeTruthy();
33
- });
34
-
35
- it('should show the image', () => {
36
- fixture.detectChanges();
37
- const img = fixture.nativeElement.querySelector('img');
38
- expect(img).toBeTruthy();
39
- });
40
-
41
- it('should have the correct aspect ratio', () => {
42
- fixture.detectChanges();
43
- const div = fixture.nativeElement.querySelector('div');
44
- expect(div.style.paddingBottom).toEqual(`${100 / (component.ratio || 1)}%`);
45
- });
46
-
47
- it('should default to an aspect ratio of 1', () => {
48
- component.ratio = undefined;
49
- fixture.detectChanges();
50
- const div = fixture.nativeElement.querySelector('div');
51
- expect(div.style.paddingBottom).toEqual('100%');
52
- });
53
-
54
- it('should fallback to an aspect ratio of 1 if the ratio is 0', () => {
55
- component.ratio = 0;
56
- fixture.detectChanges();
57
- const div = fixture.nativeElement.querySelector('div');
58
- expect(div.style.paddingBottom).toEqual('100%');
59
- });
60
-
61
- it('should fallback to an aspect ratio of 1 if the ratio is negative', () => {
62
- component.ratio = -1;
63
- fixture.detectChanges();
64
- const div = fixture.nativeElement.querySelector('div');
65
- expect(div.style.paddingBottom).toEqual('100%');
66
- });
67
-
68
- it('should add the correct styles to the image', () => {
69
- fixture.detectChanges();
70
-
71
- const img = fixture.nativeElement.querySelector('img') as HTMLImageElement;
72
- expect(img.classList.toString()).toBe('absolute w-full h-full object-cover');
73
- });
74
- });
@@ -1,70 +0,0 @@
1
- import { Component, PLATFORM_ID } from '@angular/core';
2
- import { type ComponentFixture, TestBed, fakeAsync } from '@angular/core/testing';
3
- import { hexColorFor, isBright } from '@spartan-ng/brain/avatar';
4
- import { HlmAvatarFallbackDirective } from './hlm-avatar-fallback.directive';
5
-
6
- @Component({
7
- selector: 'hlm-mock',
8
- standalone: true,
9
- imports: [HlmAvatarFallbackDirective],
10
- template: `
11
- <span hlmAvatarFallback [class]="userCls" [autoColor]="autoColor">fallback2</span>
12
- `,
13
- })
14
- class HlmMockComponent {
15
- public userCls = '';
16
- public autoColor = false;
17
- }
18
-
19
- describe('HlmAvatarFallbackDirective', () => {
20
- let component: HlmMockComponent;
21
- let fixture: ComponentFixture<HlmMockComponent>;
22
-
23
- beforeEach(() => {
24
- fixture = TestBed.overrideProvider(PLATFORM_ID, { useValue: 'browser' }).createComponent(HlmMockComponent);
25
- component = fixture.componentInstance;
26
- });
27
-
28
- it('should compile', () => {
29
- expect(component).toBeTruthy();
30
- });
31
-
32
- it('should contain the default classes if no inputs are provided', () => {
33
- fixture.detectChanges();
34
- expect(fixture.nativeElement.querySelector('span').className).toBe(
35
- 'bg-muted flex h-full items-center justify-center rounded-full w-full',
36
- );
37
- });
38
-
39
- it('should add any user defined classes', async () => {
40
- component.userCls = 'test-class';
41
-
42
- fixture.detectChanges();
43
- expect(fixture.nativeElement.querySelector('span').className).toContain('test-class');
44
- });
45
- it('should merge bg-destructive correctly when set as user defined class, therefore removing bg-muted', async () => {
46
- component.userCls = 'bg-destructive ';
47
-
48
- fixture.detectChanges();
49
- expect(fixture.nativeElement.querySelector('span').className).toContain('bg-destructive');
50
- });
51
-
52
- describe('autoColor', () => {
53
- beforeEach(() => {
54
- component.autoColor = true;
55
- fixture.detectChanges();
56
- });
57
-
58
- it('should remove the bg-muted class from the component', fakeAsync(() => {
59
- fixture.detectChanges();
60
- expect(fixture.nativeElement.querySelector('span').className).not.toContain('bg-muted');
61
- }));
62
-
63
- it('should remove add a text color class and hex backgroundColor style depending on its content', () => {
64
- const hex = hexColorFor('fallback2');
65
- const textCls = isBright(hex) ? 'text-black' : 'text-white';
66
- expect(fixture.nativeElement.querySelector('span').className).toContain(textCls);
67
- expect(fixture.nativeElement.querySelector('span').style.backgroundColor).toBe('rgb(144, 53, 149)');
68
- });
69
- });
70
- });
@@ -1,65 +0,0 @@
1
- import { Component, Input } from '@angular/core';
2
- import { type ComponentFixture, TestBed } from '@angular/core/testing';
3
- import { BrnAvatarFallbackDirective, BrnAvatarImageDirective } from '@spartan-ng/brain/avatar';
4
- import { HlmAvatarComponent } from './hlm-avatar.component';
5
-
6
- @Component({
7
- selector: 'hlm-mock',
8
- imports: [BrnAvatarImageDirective, BrnAvatarFallbackDirective, HlmAvatarComponent],
9
- template: `
10
- <hlm-avatar [class]="class" id="fallbackOnly">
11
- <span brnAvatarFallback>fallback</span>
12
- </hlm-avatar>
13
- `,
14
- standalone: true,
15
- })
16
- class MockComponent {
17
- @Input() public class = '';
18
- }
19
-
20
- describe('HlmAvatarComponent', () => {
21
- let component: HlmAvatarComponent;
22
- let fixture: ComponentFixture<HlmAvatarComponent>;
23
-
24
- beforeEach(() => {
25
- fixture = TestBed.createComponent(HlmAvatarComponent);
26
- component = fixture.componentInstance;
27
- });
28
-
29
- it('should compile', () => {
30
- expect(component).toBeTruthy();
31
- });
32
-
33
- it('should add the default classes if no inputs are provided', () => {
34
- fixture.detectChanges();
35
- expect(fixture.nativeElement.className).toBe('flex h-10 overflow-hidden relative rounded-full shrink-0 w-10');
36
- });
37
-
38
- it('should add any user defined classes', () => {
39
- const mockFixture = TestBed.createComponent(MockComponent);
40
- mockFixture.componentRef.setInput('class', 'test-class');
41
- mockFixture.detectChanges();
42
- const avatar = mockFixture.nativeElement.querySelector('hlm-avatar');
43
- expect(avatar.className).toContain('test-class');
44
- });
45
-
46
- it('should change the size when the variant is changed', () => {
47
- fixture.componentRef.setInput('variant', 'small');
48
- fixture.detectChanges();
49
- expect(fixture.nativeElement.className).toContain('h-6');
50
- expect(fixture.nativeElement.className).toContain('w-6');
51
- expect(fixture.nativeElement.className).toContain('text-xs');
52
-
53
- fixture.componentRef.setInput('variant', 'large');
54
- fixture.detectChanges();
55
- expect(fixture.nativeElement.className).toContain('h-14');
56
- expect(fixture.nativeElement.className).toContain('w-14');
57
- expect(fixture.nativeElement.className).toContain('text-lg');
58
- });
59
-
60
- it('should support brn directives', () => {
61
- const mockFixture = TestBed.createComponent(MockComponent);
62
- mockFixture.detectChanges();
63
- expect(mockFixture.nativeElement.querySelector('span').textContent).toBe('fallback');
64
- });
65
- });
@@ -1,44 +0,0 @@
1
- import { Component } from '@angular/core';
2
- import { type ComponentFixture, TestBed } from '@angular/core/testing';
3
- import { HlmAvatarImageDirective } from './hlm-avatar-image.directive';
4
-
5
- @Component({
6
- selector: 'hlm-mock',
7
- standalone: true,
8
- imports: [HlmAvatarImageDirective],
9
- template: `
10
- <img hlmAvatarImage alt="Avatar image" [class]="userCls" />
11
- `,
12
- })
13
- class HlmMockComponent {
14
- public userCls = '';
15
- }
16
-
17
- describe('HlmAvatarImageDirective', () => {
18
- let component: HlmMockComponent;
19
- let fixture: ComponentFixture<HlmMockComponent>;
20
-
21
- beforeEach(() => {
22
- fixture = TestBed.createComponent(HlmMockComponent);
23
- component = fixture.componentInstance;
24
- });
25
-
26
- it('should compile', () => {
27
- expect(component).toBeTruthy();
28
- });
29
-
30
- it('should add the default classes if no inputs are provided', () => {
31
- fixture.detectChanges();
32
- expect(fixture.nativeElement.querySelector('img').className).toBe('aspect-square h-full object-cover w-full');
33
- });
34
-
35
- it('should add any user defined classes', async () => {
36
- component.userCls = 'test-class';
37
- fixture.detectChanges();
38
-
39
- // fallback uses Promise.resolve().then() so we need to wait for the next tick
40
- setTimeout(() => {
41
- expect(fixture.nativeElement.querySelector('img').className).toContain('test-class');
42
- });
43
- });
44
- });
@@ -1,136 +0,0 @@
1
- /* eslint-disable @angular-eslint/component-class-suffix */
2
- /* eslint-disable @angular-eslint/component-selector */
3
- import { Component } from '@angular/core';
4
- import { FormControl, ReactiveFormsModule, Validators } from '@angular/forms';
5
- import { render, screen } from '@testing-library/angular';
6
- import userEvent from '@testing-library/user-event';
7
-
8
- import { HlmInputDirective } from '@spartan-ng/ui-input-helm';
9
-
10
- import { ErrorStateMatcher, ShowOnDirtyErrorStateMatcher } from '@spartan-ng/brain/forms';
11
- import { HlmErrorDirective } from './hlm-error.directive';
12
- import { HlmFormFieldComponent } from './hlm-form-field.component';
13
- import { HlmHintDirective } from './hlm-hint.directive';
14
-
15
- const DIRECTIVES = [HlmFormFieldComponent, HlmErrorDirective, HlmHintDirective, HlmInputDirective];
16
-
17
- @Component({
18
- standalone: true,
19
- selector: 'single-form-field-example',
20
- imports: [ReactiveFormsModule, ...DIRECTIVES],
21
- template: `
22
- <hlm-form-field>
23
- <input
24
- data-testid="hlm-input"
25
- aria-label="Your Name"
26
- [formControl]="name"
27
- class="w-80"
28
- hlmInput
29
- type="text"
30
- placeholder="Your Name"
31
- />
32
- <hlm-error data-testid="hlm-error">Your name is required</hlm-error>
33
- <hlm-hint data-testid="hlm-hint">This is your public display name.</hlm-hint>
34
- </hlm-form-field>
35
- `,
36
- })
37
- class SingleFormFieldMock {
38
- public name = new FormControl('', Validators.required);
39
- }
40
-
41
- @Component({
42
- standalone: true,
43
- selector: 'single-form-field-dirty-example',
44
- imports: [ReactiveFormsModule, ...DIRECTIVES],
45
- template: `
46
- <hlm-form-field>
47
- <input
48
- data-testid="hlm-input"
49
- aria-label="Your Name"
50
- [formControl]="name"
51
- class="w-80"
52
- hlmInput
53
- type="text"
54
- placeholder="Your Name"
55
- />
56
- <hlm-error data-testid="hlm-error">Your name is required</hlm-error>
57
- <hlm-hint data-testid="hlm-hint">This is your public display name.</hlm-hint>
58
- </hlm-form-field>
59
- `,
60
- providers: [{ provide: ErrorStateMatcher, useClass: ShowOnDirtyErrorStateMatcher }],
61
- })
62
- class SingleFormFieldDirtyMock {
63
- public name = new FormControl('', Validators.required);
64
- }
65
-
66
- describe('Hlm Form Field Component', () => {
67
- const TEXT_HINT = 'This is your public display name.';
68
- const TEXT_ERROR = 'Your name is required';
69
-
70
- const setupFormField = async () => {
71
- const { fixture } = await render(SingleFormFieldMock);
72
- return {
73
- user: userEvent.setup(),
74
- fixture,
75
- hint: screen.getByTestId('hlm-hint'),
76
- error: () => screen.queryByTestId('hlm-error'),
77
- trigger: screen.getByTestId('hlm-input'),
78
- };
79
- };
80
-
81
- const setupFormFieldWithErrorStateDirty = async () => {
82
- const { fixture } = await render(SingleFormFieldDirtyMock);
83
- return {
84
- user: userEvent.setup(),
85
- fixture,
86
- hint: screen.getByTestId('hlm-hint'),
87
- error: () => screen.queryByTestId('hlm-error'),
88
- trigger: screen.getByTestId('hlm-input'),
89
- };
90
- };
91
-
92
- describe('SingleFormField', () => {
93
- it('should show the hint if the errorState is false', async () => {
94
- const { hint } = await setupFormField();
95
-
96
- expect(hint.textContent).toBe(TEXT_HINT);
97
- });
98
-
99
- it('should show the error if the errorState is true', async () => {
100
- const { user, error, trigger } = await setupFormField();
101
-
102
- expect(error()).toBeNull();
103
-
104
- await user.click(trigger);
105
-
106
- await user.click(document.body);
107
-
108
- expect(screen.queryByTestId('hlm-hint')).toBeNull();
109
- expect(error()?.textContent?.trim()).toBe(TEXT_ERROR);
110
- });
111
- });
112
-
113
- describe('SingleFormFieldDirty', () => {
114
- it('should not display the error if the input does not have the dirty state due to the ErrorStateMatcher', async () => {
115
- const { error, user, trigger } = await setupFormFieldWithErrorStateDirty();
116
-
117
- await user.click(trigger);
118
-
119
- await user.click(document.body);
120
-
121
- expect(error()).toBeNull();
122
- });
123
-
124
- it('should display the error if the input has the dirty state due to the ErrorStateMatcher', async () => {
125
- const { error, user, trigger } = await setupFormFieldWithErrorStateDirty();
126
-
127
- await user.click(trigger);
128
- await user.type(trigger, 'a');
129
- await user.clear(trigger);
130
-
131
- await user.click(document.body);
132
-
133
- expect(error()?.textContent?.trim()).toBe(TEXT_ERROR);
134
- });
135
- });
136
- });
@@ -1,66 +0,0 @@
1
- import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
2
- import { By } from '@angular/platform-browser';
3
- import { NgIcon, provideIcons } from '@ng-icons/core';
4
- import { lucideCheck } from '@ng-icons/lucide';
5
- import { type RenderResult, render } from '@testing-library/angular';
6
- import { HlmIconDirective } from './hlm-icon.directive';
7
-
8
- @Component({
9
- selector: 'hlm-mock',
10
- standalone: true,
11
- changeDetection: ChangeDetectionStrategy.OnPush,
12
- imports: [HlmIconDirective, NgIcon],
13
- providers: [provideIcons({ lucideCheck })],
14
- template: `
15
- <ng-icon hlm class="test" name="lucideCheck" [size]="size" color="red" strokeWidth="2" />
16
- `,
17
- })
18
- class HlmMockComponent {
19
- @Input() public size = 'base';
20
- }
21
-
22
- describe('HlmIconDirective', () => {
23
- let r: RenderResult<HlmMockComponent>;
24
- let icon: HTMLElement;
25
-
26
- beforeEach(async () => {
27
- r = await render(HlmMockComponent);
28
- icon = r.container.querySelector('ng-icon')!;
29
- });
30
-
31
- it('should add the xs size', async () => {
32
- await r.rerender({ componentInputs: { size: 'xs' } });
33
- r.fixture.detectChanges();
34
- expect(icon.getAttribute('style')).toContain('--ng-icon__size: 12px');
35
- });
36
-
37
- it('should add the sm size', async () => {
38
- await r.rerender({ componentInputs: { size: 'sm' } });
39
- r.fixture.detectChanges();
40
- expect(icon.getAttribute('style')).toContain('--ng-icon__size: 16px');
41
- });
42
-
43
- it('should add the base size', () => {
44
- expect(icon.getAttribute('style')).toContain('--ng-icon__size: 24px');
45
- });
46
-
47
- it('should add the lg size', async () => {
48
- await r.rerender({ componentInputs: { size: 'lg' } });
49
- r.fixture.detectChanges();
50
- expect(icon.getAttribute('style')).toContain('--ng-icon__size: 32px');
51
- });
52
-
53
- it('should add the xl size', async () => {
54
- await r.rerender({ componentInputs: { size: 'xl' } });
55
- r.fixture.detectChanges();
56
- expect(icon.getAttribute('style')).toContain('--ng-icon__size: 48px');
57
- });
58
-
59
- it('should forward the size property if the size is not a pre-defined size', async () => {
60
- await r.rerender({ componentInputs: { size: '2rem' } });
61
- r.fixture.detectChanges();
62
- const debugEl = r.fixture.debugElement.query(By.directive(NgIcon));
63
- expect(debugEl.componentInstance.size()).toBe('2rem');
64
- expect(icon.getAttribute('style')).toContain('--ng-icon__size: 2rem');
65
- });
66
- });
@@ -1,27 +0,0 @@
1
- import { Component, Input } from '@angular/core';
2
- import { FormsModule } from '@angular/forms';
3
- import { HlmSwitchComponent } from './hlm-switch.component';
4
- @Component({
5
- selector: 'hlm-switch-ng-model',
6
- template: `
7
- <!-- eslint-disable-next-line @angular-eslint/template/label-has-associated-control -->
8
- <label class="flex items-center" hlmLabel>
9
- test switch
10
- <hlm-switch [(ngModel)]="switchValue" id="testSwitchForm" (changed)="handleChange($event)" />
11
- </label>
12
-
13
- <p data-testid="switchValue">{{ switchValue }}</p>
14
- <p data-testid="changedValue">{{ changedValueTo }}</p>
15
- `,
16
- imports: [HlmSwitchComponent, FormsModule],
17
- })
18
- export class SwitchFormComponent {
19
- @Input()
20
- public switchValue = false;
21
-
22
- protected changedValueTo: boolean | undefined;
23
-
24
- handleChange(value: boolean) {
25
- this.changedValueTo = value;
26
- }
27
- }