@ng-zen/cli 20.0.0-next.1 → 20.0.0-next.3

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 (53) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/package.json +1 -1
  3. package/schematics/components/files/{input/input.component.spec.ts → avatar/avatar.spec.ts} +6 -6
  4. package/schematics/components/files/avatar/avatar.stories.ts +4 -4
  5. package/schematics/components/files/avatar/{avatar.component.ts → avatar.ts} +3 -3
  6. package/schematics/components/files/avatar/index.ts +1 -1
  7. package/schematics/components/files/button/{button.component.spec.ts → button.spec.ts} +6 -6
  8. package/schematics/components/files/button/button.stories.ts +4 -4
  9. package/schematics/components/files/button/{button.component.ts → button.ts} +3 -3
  10. package/schematics/components/files/button/index.ts +1 -1
  11. package/schematics/components/files/{avatar/avatar.component.spec.ts → checkbox/checkbox.spec.ts} +6 -6
  12. package/schematics/components/files/checkbox/checkbox.stories.ts +4 -4
  13. package/schematics/components/files/checkbox/{checkbox.component.ts → checkbox.ts} +4 -4
  14. package/schematics/components/files/checkbox/index.ts +1 -1
  15. package/schematics/components/files/{switch/switch.component.spec.ts → divider/divider.spec.ts} +6 -6
  16. package/schematics/components/files/divider/divider.stories.ts +4 -4
  17. package/schematics/components/files/divider/{divider.component.ts → divider.ts} +3 -3
  18. package/schematics/components/files/divider/index.ts +1 -1
  19. package/schematics/components/files/icon/icon.spec.ts +23 -0
  20. package/schematics/components/files/icon/icon.stories.ts +15 -5
  21. package/schematics/components/files/icon/icon.ts +79 -0
  22. package/schematics/components/files/icon/index.ts +1 -1
  23. package/schematics/components/files/input/index.ts +1 -1
  24. package/schematics/components/files/input/input.spec.ts +22 -0
  25. package/schematics/components/files/input/input.stories.ts +4 -4
  26. package/schematics/components/files/input/{input.component.ts → input.ts} +4 -4
  27. package/schematics/components/files/skeleton/index.ts +1 -1
  28. package/schematics/components/files/skeleton/skeleton.spec.ts +22 -0
  29. package/schematics/components/files/skeleton/skeleton.stories.ts +3 -3
  30. package/schematics/components/files/skeleton/{skeleton.component.ts → skeleton.ts} +3 -3
  31. package/schematics/components/files/switch/index.ts +1 -1
  32. package/schematics/components/files/switch/switch.spec.ts +22 -0
  33. package/schematics/components/files/switch/switch.stories.ts +4 -4
  34. package/schematics/components/files/switch/{switch.component.ts → switch.ts} +4 -4
  35. package/schematics/components/files/textarea/index.ts +1 -1
  36. package/schematics/components/files/textarea/{textarea.component.spec.ts → textarea.spec.ts} +5 -5
  37. package/schematics/components/files/textarea/textarea.stories.ts +4 -4
  38. package/schematics/components/files/textarea/{textarea.component.ts → textarea.ts} +3 -3
  39. package/schematics/dependency-manager/dependencies.constant.js +0 -1
  40. package/schematics/dependency-manager/dependencies.constant.js.map +1 -1
  41. package/schematics/dependency-manager/dependencies.constant.ts +0 -1
  42. package/schematics/components/files/checkbox/checkbox.component.spec.ts +0 -22
  43. package/schematics/components/files/divider/divider.component.spec.ts +0 -22
  44. package/schematics/components/files/icon/icon.component.ts +0 -35
  45. package/schematics/components/files/skeleton/skeleton.component.spec.ts +0 -22
  46. /package/schematics/components/files/avatar/{avatar.component.scss → avatar.scss} +0 -0
  47. /package/schematics/components/files/button/{button.component.scss → button.scss} +0 -0
  48. /package/schematics/components/files/checkbox/{checkbox.component.scss → checkbox.scss} +0 -0
  49. /package/schematics/components/files/divider/{divider.component.scss → divider.scss} +0 -0
  50. /package/schematics/components/files/input/{input.component.scss → input.scss} +0 -0
  51. /package/schematics/components/files/skeleton/{skeleton.component.scss → skeleton.scss} +0 -0
  52. /package/schematics/components/files/switch/{switch.component.scss → switch.scss} +0 -0
  53. /package/schematics/components/files/textarea/{textarea.component.scss → textarea.scss} +0 -0
package/CHANGELOG.md CHANGED
@@ -1,3 +1,15 @@
1
+ ## [20.0.0-next.3](https://github.com/kstepien3/ng-zen/compare/v20.0.0-next.2...v20.0.0-next.3) (2025-07-21)
2
+
3
+ ### 🚀 New Features
4
+
5
+ * **icon:** remove @hugeicons/angular package & improvements ([#248](https://github.com/kstepien3/ng-zen/issues/248)) ([cceabb0](https://github.com/kstepien3/ng-zen/commit/cceabb036f092170da66724d29ffca8ccd702983))
6
+
7
+ ## [20.0.0-next.2](https://github.com/kstepien3/ng-zen/compare/v20.0.0-next.1...v20.0.0-next.2) (2025-07-16)
8
+
9
+ ### 🛠️ Code Refactor
10
+
11
+ * remove suffix from files for Angular v20 compatibility ([#243](https://github.com/kstepien3/ng-zen/issues/243)) ([d26e2f2](https://github.com/kstepien3/ng-zen/commit/d26e2f2faeb052b8f984f82a59e7d95248b2964b))
12
+
1
13
  ## [20.0.0-next.1](https://github.com/kstepien3/ng-zen/compare/v19.4.0...v20.0.0-next.1) (2025-07-15)
2
14
 
3
15
  ### ⚠ BREAKING CHANGES
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ng-zen/cli",
3
- "version": "20.0.0-next.1",
3
+ "version": "20.0.0-next.3",
4
4
  "description": "A CLI tool for generating customizable, modern Angular UI components using schematics.",
5
5
  "license": "BSD-2-Clause",
6
6
  "private": false,
@@ -1,17 +1,17 @@
1
1
  import { ComponentFixture, TestBed } from '@angular/core/testing';
2
2
 
3
- import { ZenInputComponent } from './input.component';
3
+ import { ZenAvatar } from './avatar';
4
4
 
5
- describe('InputComponent', () => {
6
- let component: ZenInputComponent;
7
- let fixture: ComponentFixture<ZenInputComponent>;
5
+ describe('ZenAvatar', () => {
6
+ let component: ZenAvatar;
7
+ let fixture: ComponentFixture<ZenAvatar>;
8
8
 
9
9
  beforeEach(async () => {
10
10
  await TestBed.configureTestingModule({
11
- imports: [ZenInputComponent],
11
+ imports: [ZenAvatar],
12
12
  }).compileComponents();
13
13
 
14
- fixture = TestBed.createComponent(ZenInputComponent);
14
+ fixture = TestBed.createComponent(ZenAvatar);
15
15
  component = fixture.componentInstance;
16
16
  fixture.detectChanges();
17
17
  });
@@ -1,15 +1,15 @@
1
1
  import type { Meta, StoryObj } from '@storybook/angular';
2
2
 
3
- import { ZenAvatarComponent } from './avatar.component';
3
+ import { ZenAvatar } from './avatar';
4
4
 
5
5
  export default {
6
6
  title: 'Components/Avatar',
7
- component: ZenAvatarComponent,
7
+ component: ZenAvatar,
8
8
  tags: ['autodocs'],
9
9
  render: args => ({ props: { ...args } }),
10
- } satisfies Meta<ZenAvatarComponent>;
10
+ } satisfies Meta<ZenAvatar>;
11
11
 
12
- type Story = StoryObj<ZenAvatarComponent>;
12
+ type Story = StoryObj<ZenAvatar>;
13
13
 
14
14
  export const Image: Story = {
15
15
  args: {
@@ -40,15 +40,15 @@ import { ChangeDetectionStrategy, Component, input } from '@angular/core';
40
40
  imports: [NgOptimizedImage],
41
41
  template: `
42
42
  @if (src()) {
43
- <img [alt]="alt()" [ngSrc]="src()" fill onerror="console.log('test')" />
43
+ <img [alt]="alt()" [ngSrc]="src()" fill />
44
44
  } @else {
45
45
  <ng-content />
46
46
  }
47
47
  `,
48
- styleUrl: './avatar.component.scss',
48
+ styleUrl: './avatar.scss',
49
49
  changeDetection: ChangeDetectionStrategy.OnPush,
50
50
  })
51
- export class ZenAvatarComponent {
51
+ export class ZenAvatar {
52
52
  /**
53
53
  * Name of the source image. Image name will be processed by the image loader,
54
54
  * and the final URL will be applied as the src property of the image.
@@ -1 +1 @@
1
- export * from './avatar.component';
1
+ export * from './avatar';
@@ -1,17 +1,17 @@
1
1
  import { ComponentFixture, TestBed } from '@angular/core/testing';
2
2
 
3
- import { ZenButtonComponent } from './button.component';
3
+ import { ZenButton } from './button';
4
4
 
5
- describe('ButtonComponent', () => {
6
- let component: ZenButtonComponent;
7
- let fixture: ComponentFixture<ZenButtonComponent>;
5
+ describe('ZenButton', () => {
6
+ let component: ZenButton;
7
+ let fixture: ComponentFixture<ZenButton>;
8
8
 
9
9
  beforeEach(async () => {
10
10
  await TestBed.configureTestingModule({
11
- imports: [ZenButtonComponent],
11
+ imports: [ZenButton],
12
12
  }).compileComponents();
13
13
 
14
- fixture = TestBed.createComponent(ZenButtonComponent);
14
+ fixture = TestBed.createComponent(ZenButton);
15
15
  component = fixture.componentInstance;
16
16
  fixture.detectChanges();
17
17
  });
@@ -1,15 +1,15 @@
1
1
  import type { Meta, StoryObj } from '@storybook/angular';
2
2
 
3
- import { ZenButtonComponent } from './button.component';
3
+ import { ZenButton } from './button';
4
4
 
5
5
  export default {
6
6
  title: 'Components/Button',
7
- component: ZenButtonComponent,
7
+ component: ZenButton,
8
8
  tags: ['autodocs'],
9
9
  render: args => ({ props: { ...args } }),
10
- } satisfies Meta<ZenButtonComponent>;
10
+ } satisfies Meta<ZenButton>;
11
11
 
12
- type Story = StoryObj<ZenButtonComponent>;
12
+ type Story = StoryObj<ZenButton>;
13
13
 
14
14
  export const Default: Story = {
15
15
  render: () => ({
@@ -1,7 +1,7 @@
1
1
  import { ChangeDetectionStrategy, Component } from '@angular/core';
2
2
 
3
3
  /**
4
- * ZenButtonComponent is a reusable button component designed to provide
4
+ * ZenButton is a reusable button component designed to provide
5
5
  * a consistent and customizable button style across the application.
6
6
  * It can be used with both `<button>` and `<a>` HTML elements by applying
7
7
  * the `zen-button` attribute.
@@ -33,7 +33,7 @@ import { ChangeDetectionStrategy, Component } from '@angular/core';
33
33
  template: `
34
34
  <ng-content />
35
35
  `,
36
- styleUrl: './button.component.scss',
36
+ styleUrl: './button.scss',
37
37
  changeDetection: ChangeDetectionStrategy.OnPush,
38
38
  })
39
- export class ZenButtonComponent {}
39
+ export class ZenButton {}
@@ -1 +1 @@
1
- export * from './button.component';
1
+ export * from './button';
@@ -1,17 +1,17 @@
1
1
  import { ComponentFixture, TestBed } from '@angular/core/testing';
2
2
 
3
- import { ZenAvatarComponent } from './avatar.component';
3
+ import { ZenCheckbox } from './checkbox';
4
4
 
5
- describe('ZenAvatarComponent', () => {
6
- let component: ZenAvatarComponent;
7
- let fixture: ComponentFixture<ZenAvatarComponent>;
5
+ describe('ZenCheckbox', () => {
6
+ let component: ZenCheckbox;
7
+ let fixture: ComponentFixture<ZenCheckbox>;
8
8
 
9
9
  beforeEach(async () => {
10
10
  await TestBed.configureTestingModule({
11
- imports: [ZenAvatarComponent],
11
+ imports: [ZenCheckbox],
12
12
  }).compileComponents();
13
13
 
14
- fixture = TestBed.createComponent(ZenAvatarComponent);
14
+ fixture = TestBed.createComponent(ZenCheckbox);
15
15
  component = fixture.componentInstance;
16
16
  fixture.detectChanges();
17
17
  });
@@ -1,10 +1,10 @@
1
1
  import { Meta, StoryObj } from '@storybook/angular';
2
2
 
3
- import { ZenCheckboxComponent } from './checkbox.component';
3
+ import { ZenCheckbox } from './checkbox';
4
4
 
5
5
  export default {
6
6
  title: 'Components/Checkbox',
7
- component: ZenCheckboxComponent,
7
+ component: ZenCheckbox,
8
8
  tags: ['autodocs'],
9
9
  argTypes: {
10
10
  value: { control: 'boolean' },
@@ -18,9 +18,9 @@ export default {
18
18
  required: false,
19
19
  id: '',
20
20
  },
21
- } satisfies Meta<ZenCheckboxComponent>;
21
+ } satisfies Meta<ZenCheckbox>;
22
22
 
23
- type Story = StoryObj<ZenCheckboxComponent>;
23
+ type Story = StoryObj<ZenCheckbox>;
24
24
 
25
25
  export const Default: Story = {
26
26
  render: args => ({
@@ -2,7 +2,7 @@ import { booleanAttribute, ChangeDetectionStrategy, Component, forwardRef, input
2
2
  import { ControlValueAccessor, FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
3
3
 
4
4
  /**
5
- * ZenCheckboxComponent is a reusable checkbox component designed to provide
5
+ * ZenCheckbox is a reusable checkbox component designed to provide
6
6
  * a consistent and customizable checkbox style across the application.
7
7
  * It supports Angular forms integration and provides two-way data binding
8
8
  * for boolean values.
@@ -51,13 +51,13 @@ import { ControlValueAccessor, FormsModule, NG_VALUE_ACCESSOR } from '@angular/f
51
51
  }
52
52
  <!-- @else { ✕ } -->
53
53
  `,
54
- styleUrls: ['./checkbox.component.scss'],
54
+ styleUrls: ['./checkbox.scss'],
55
55
  changeDetection: ChangeDetectionStrategy.OnPush,
56
56
  imports: [FormsModule],
57
57
  providers: [
58
58
  {
59
59
  provide: NG_VALUE_ACCESSOR,
60
- useExisting: forwardRef(() => ZenCheckboxComponent),
60
+ useExisting: forwardRef(() => ZenCheckbox),
61
61
  multi: true,
62
62
  },
63
63
  ],
@@ -65,7 +65,7 @@ import { ControlValueAccessor, FormsModule, NG_VALUE_ACCESSOR } from '@angular/f
65
65
  '(blur)': 'onTouched()',
66
66
  },
67
67
  })
68
- export class ZenCheckboxComponent implements ControlValueAccessor {
68
+ export class ZenCheckbox implements ControlValueAccessor {
69
69
  /** Holds the current checkbox value. */
70
70
  readonly value = model(false);
71
71
  /** Determines if the checkbox is disabled. */
@@ -1 +1 @@
1
- export * from './checkbox.component';
1
+ export * from './checkbox';
@@ -1,17 +1,17 @@
1
1
  import { ComponentFixture, TestBed } from '@angular/core/testing';
2
2
 
3
- import { ZenSwitchComponent } from './switch.component';
3
+ import { ZenDivider } from './divider';
4
4
 
5
- describe('ZenSwitchComponent', () => {
6
- let component: ZenSwitchComponent;
7
- let fixture: ComponentFixture<ZenSwitchComponent>;
5
+ describe('ZenDivider', () => {
6
+ let component: ZenDivider;
7
+ let fixture: ComponentFixture<ZenDivider>;
8
8
 
9
9
  beforeEach(async () => {
10
10
  await TestBed.configureTestingModule({
11
- imports: [ZenSwitchComponent],
11
+ imports: [ZenDivider],
12
12
  }).compileComponents();
13
13
 
14
- fixture = TestBed.createComponent(ZenSwitchComponent);
14
+ fixture = TestBed.createComponent(ZenDivider);
15
15
  component = fixture.componentInstance;
16
16
  fixture.detectChanges();
17
17
  });
@@ -1,6 +1,6 @@
1
1
  import { Meta, StoryObj } from '@storybook/angular';
2
2
 
3
- import { ZenDividerComponent } from './divider.component';
3
+ import { ZenDivider } from './divider';
4
4
 
5
5
  interface StoryParams {
6
6
  content: string;
@@ -9,7 +9,7 @@ interface StoryParams {
9
9
 
10
10
  export default {
11
11
  title: 'Components/Divider',
12
- component: ZenDividerComponent,
12
+ component: ZenDivider,
13
13
  tags: ['autodocs'],
14
14
  parameters: {
15
15
  layout: 'padded',
@@ -20,9 +20,9 @@ export default {
20
20
  align: { control: 'select', options: ['start', 'center', 'end'] },
21
21
  },
22
22
  args: { content: '', vertical: false, align: 'center' },
23
- } satisfies Meta<ZenDividerComponent & StoryParams>;
23
+ } satisfies Meta<ZenDivider & StoryParams>;
24
24
 
25
- type Story = StoryObj<ZenDividerComponent & StoryParams>;
25
+ type Story = StoryObj<ZenDivider & StoryParams>;
26
26
 
27
27
  export const Default: Story = {
28
28
  render: args => ({
@@ -1,7 +1,7 @@
1
1
  import { ChangeDetectionStrategy, Component, computed, ElementRef, inject, input } from '@angular/core';
2
2
 
3
3
  /**
4
- * ZenDividerComponent is a reusable divider component that provides a simple way to
4
+ * ZenDivider is a reusable divider component that provides a simple way to
5
5
  * separate content sections visually. It supports both horizontal (default) and vertical
6
6
  * orientations and can contain optional content.
7
7
  *
@@ -34,14 +34,14 @@ import { ChangeDetectionStrategy, Component, computed, ElementRef, inject, input
34
34
  @Component({
35
35
  selector: `zen-divider, zen-divider[vertical],`,
36
36
  template: '<ng-content/>',
37
- styleUrl: './divider.component.scss',
37
+ styleUrl: './divider.scss',
38
38
  changeDetection: ChangeDetectionStrategy.OnPush,
39
39
  host: {
40
40
  '[class.has-content]': 'hasContent()',
41
41
  '[class]': '"zen-align-"+align()',
42
42
  },
43
43
  })
44
- export class ZenDividerComponent {
44
+ export class ZenDivider {
45
45
  /**
46
46
  * Controls the alignment of content within the divider.
47
47
  * @default 'center'
@@ -1 +1 @@
1
- export * from './divider.component';
1
+ export * from './divider';
@@ -0,0 +1,23 @@
1
+ import { ComponentFixture, TestBed } from '@angular/core/testing';
2
+
3
+ import { ZenIcon } from './icon';
4
+
5
+ describe('ZenIcon', () => {
6
+ let component: ZenIcon;
7
+ let fixture: ComponentFixture<ZenIcon>;
8
+
9
+ beforeEach(async () => {
10
+ await TestBed.configureTestingModule({
11
+ imports: [ZenIcon],
12
+ }).compileComponents();
13
+
14
+ fixture = TestBed.createComponent(ZenIcon);
15
+ component = fixture.componentInstance;
16
+ fixture.componentRef.setInput('icon', 'Tree02Icon');
17
+ fixture.detectChanges();
18
+ });
19
+
20
+ it('should create', () => {
21
+ expect(component).toBeTruthy();
22
+ });
23
+ });
@@ -1,21 +1,31 @@
1
1
  import { Meta, StoryObj } from '@storybook/angular';
2
2
 
3
- import { ZenIconComponent } from './icon.component';
3
+ import { ZenIcon } from './icon';
4
4
 
5
- type Options = ZenIconComponent;
5
+ type Options = ZenIcon;
6
6
 
7
7
  export default {
8
8
  title: 'Components/Icon',
9
- component: ZenIconComponent,
9
+ component: ZenIcon,
10
10
  tags: ['autodocs'],
11
+ argTypes: {
12
+ size: { control: { type: 'range', min: 12, max: 100, step: 1 }, description: 'Size' },
13
+ strokeWidth: { control: { type: 'range', min: 1, max: 5, step: 0.25 }, description: 'strokeWidth' },
14
+ absoluteStrokeWidth: { control: 'boolean' },
15
+ },
16
+ args: {
17
+ size: 64,
18
+ strokeWidth: 1.5,
19
+ absoluteStrokeWidth: false,
20
+ },
11
21
  } satisfies Meta<Options>;
12
22
 
13
23
  type Story = StoryObj<Options>;
14
24
 
15
25
  export const Default: Story = {
16
- render: () => ({
26
+ render: args => ({
17
27
  template: `
18
- <zen-icon icon="Tree02Icon" [size]="64"/>
28
+ <zen-icon icon="Tree02Icon" [size]="${args.size}" [strokeWidth]="${args.strokeWidth}" ${args.absoluteStrokeWidth ? 'absoluteStrokeWidth' : ''}>
19
29
  `,
20
30
  }),
21
31
  };
@@ -0,0 +1,79 @@
1
+ import { booleanAttribute, ChangeDetectionStrategy, Component, computed, input } from '@angular/core';
2
+ import * as icons from '@hugeicons/core-free-icons';
3
+
4
+ type Icon = keyof typeof icons;
5
+ interface Path {
6
+ d: string | number;
7
+ fill: string | number;
8
+ opacity: string | number;
9
+ fillRule: string | number;
10
+ strokeWidth?: number;
11
+ }
12
+
13
+ /**
14
+ * A reusable Angular component for rendering icons from the Hugeicons library.
15
+ *
16
+ * This component renders an SVG icon from the `@hugeicons/core-free-icons` collection by name.
17
+ * The size, stroke width, and color are configurable through inputs. It dynamically generates the SVG
18
+ * and its paths, providing a flexible and efficient way to use Hugeicons in an Angular application.
19
+ *
20
+ * @example
21
+ * <zen-icon icon="Tree02Icon" />
22
+ *
23
+ * @license {@link https://github.com/hugeicons/angular/blob/main/README.md#license|MIT}
24
+ * @see [Hugeicons](https://hugeicons.com)
25
+ */
26
+ @Component({
27
+ selector: 'zen-icon',
28
+ template: `
29
+ <svg
30
+ [attr.color]="color()"
31
+ [attr.height]="size()"
32
+ [attr.width]="size()"
33
+ fill="none"
34
+ viewBox="0 0 24 24"
35
+ xmlns="http://www.w3.org/2000/svg"
36
+ >
37
+ @for (path of paths(); track path) {
38
+ <path
39
+ [attr.d]="path.d"
40
+ [attr.fill-rule]="path.fillRule"
41
+ [attr.fill]="path.fill"
42
+ [attr.opacity]="path.opacity"
43
+ [attr.stroke-width]="path.strokeWidth"
44
+ [attr.stroke]="'currentColor'"
45
+ />
46
+ }
47
+ </svg>
48
+ `,
49
+ changeDetection: ChangeDetectionStrategy.OnPush,
50
+ })
51
+ export class ZenIcon {
52
+ /** Icon file names from HugeIcons */
53
+ readonly icon = input.required({ transform: (icon: Icon) => icons[icon] });
54
+ readonly size = input<number>(24);
55
+ readonly absoluteStrokeWidth = input<boolean, unknown>(false, { transform: booleanAttribute });
56
+ readonly strokeWidth = input<number>(1.5);
57
+ readonly color = input<string>('currentColor');
58
+
59
+ readonly paths = computed<Path[]>(() => this.updatePaths());
60
+
61
+ private readonly calculatedStrokeWidth = computed(() => this.calculateStrokeWidth());
62
+
63
+ private calculateStrokeWidth(): number {
64
+ if (!this.absoluteStrokeWidth()) return this.strokeWidth();
65
+
66
+ const BASE_SIZE = 24;
67
+ return (this.strokeWidth() * BASE_SIZE) / this.size();
68
+ }
69
+
70
+ private updatePaths(): Path[] {
71
+ return this.icon().map(([, attrs]) => ({
72
+ d: attrs['d'],
73
+ fill: attrs['fill'] ?? 'none',
74
+ opacity: attrs['opacity'],
75
+ fillRule: attrs['fillRule'],
76
+ strokeWidth: this.calculatedStrokeWidth(),
77
+ }));
78
+ }
79
+ }
@@ -1 +1 @@
1
- export * from './icon.component';
1
+ export * from './icon';
@@ -1 +1 @@
1
- export * from './input.component';
1
+ export * from './input';
@@ -0,0 +1,22 @@
1
+ import { ComponentFixture, TestBed } from '@angular/core/testing';
2
+
3
+ import { ZenInput } from './input';
4
+
5
+ describe('ZenInput', () => {
6
+ let component: ZenInput;
7
+ let fixture: ComponentFixture<ZenInput>;
8
+
9
+ beforeEach(async () => {
10
+ await TestBed.configureTestingModule({
11
+ imports: [ZenInput],
12
+ }).compileComponents();
13
+
14
+ fixture = TestBed.createComponent(ZenInput);
15
+ component = fixture.componentInstance;
16
+ fixture.detectChanges();
17
+ });
18
+
19
+ it('should create', () => {
20
+ expect(component).toBeTruthy();
21
+ });
22
+ });
@@ -1,10 +1,10 @@
1
1
  import { Meta, StoryObj } from '@storybook/angular';
2
2
 
3
- import { ZenInputComponent } from './input.component';
3
+ import { ZenInput } from './input';
4
4
 
5
5
  export default {
6
6
  title: 'Components/Input',
7
- component: ZenInputComponent,
7
+ component: ZenInput,
8
8
  tags: ['autodocs'],
9
9
  argTypes: {
10
10
  value: { control: 'text' },
@@ -20,9 +20,9 @@ export default {
20
20
  required: false,
21
21
  id: '',
22
22
  },
23
- } satisfies Meta<ZenInputComponent>;
23
+ } satisfies Meta<ZenInput>;
24
24
 
25
- type Story = StoryObj<ZenInputComponent>;
25
+ type Story = StoryObj<ZenInput>;
26
26
 
27
27
  export const Default: Story = {
28
28
  render: args => ({
@@ -2,7 +2,7 @@ import { booleanAttribute, ChangeDetectionStrategy, Component, forwardRef, input
2
2
  import { ControlValueAccessor, FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
3
3
 
4
4
  /**
5
- * ZenInputComponent is a reusable text input component designed to provide
5
+ * ZenInput is a reusable text input component designed to provide
6
6
  * a consistent and customizable input style across the application.
7
7
  * It supports Angular forms integration and provides two-way data binding.
8
8
  *
@@ -43,18 +43,18 @@ import { ControlValueAccessor, FormsModule, NG_VALUE_ACCESSOR } from '@angular/f
43
43
  (ngModelChange)="onInputChange($event)"
44
44
  />
45
45
  `,
46
- styleUrls: ['./input.component.scss'],
46
+ styleUrls: ['./input.scss'],
47
47
  changeDetection: ChangeDetectionStrategy.OnPush,
48
48
  providers: [
49
49
  {
50
50
  provide: NG_VALUE_ACCESSOR,
51
- useExisting: forwardRef(() => ZenInputComponent),
51
+ useExisting: forwardRef(() => ZenInput),
52
52
  multi: true,
53
53
  },
54
54
  ],
55
55
  imports: [FormsModule],
56
56
  })
57
- export class ZenInputComponent implements ControlValueAccessor {
57
+ export class ZenInput implements ControlValueAccessor {
58
58
  /** Holds the current input value. */
59
59
  readonly value = model('');
60
60
  /** Determines if the input is disabled. */
@@ -1 +1 @@
1
- export * from './skeleton.component';
1
+ export * from './skeleton';
@@ -0,0 +1,22 @@
1
+ import { ComponentFixture, TestBed } from '@angular/core/testing';
2
+
3
+ import { ZenSkeleton } from './skeleton';
4
+
5
+ describe('ZenSkeleton', () => {
6
+ let component: ZenSkeleton;
7
+ let fixture: ComponentFixture<ZenSkeleton>;
8
+
9
+ beforeEach(async () => {
10
+ await TestBed.configureTestingModule({
11
+ imports: [ZenSkeleton],
12
+ }).compileComponents();
13
+
14
+ fixture = TestBed.createComponent(ZenSkeleton);
15
+ component = fixture.componentInstance;
16
+ fixture.detectChanges();
17
+ });
18
+
19
+ it('should create', () => {
20
+ expect(component).toBeTruthy();
21
+ });
22
+ });
@@ -1,6 +1,6 @@
1
1
  import { Meta, StoryObj } from '@storybook/angular';
2
2
 
3
- import { ZenSkeletonComponent } from './skeleton.component';
3
+ import { ZenSkeleton } from './skeleton';
4
4
 
5
5
  interface StoryParams {
6
6
  rounded: boolean;
@@ -8,11 +8,11 @@ interface StoryParams {
8
8
  width: number;
9
9
  }
10
10
 
11
- type StoryType = ZenSkeletonComponent & StoryParams;
11
+ type StoryType = ZenSkeleton & StoryParams;
12
12
 
13
13
  export default {
14
14
  title: 'Components/Skeleton',
15
- component: ZenSkeletonComponent,
15
+ component: ZenSkeleton,
16
16
  tags: ['autodocs'],
17
17
  argTypes: {
18
18
  rounded: { control: { type: 'boolean' } },
@@ -1,7 +1,7 @@
1
1
  import { ChangeDetectionStrategy, Component } from '@angular/core';
2
2
 
3
3
  /**
4
- * ZenInputComponent loader component that displays loading states.
4
+ * ZenInput loader component that displays loading states.
5
5
  *
6
6
  * @example
7
7
  *
@@ -30,7 +30,7 @@ import { ChangeDetectionStrategy, Component } from '@angular/core';
30
30
  @Component({
31
31
  selector: 'zen-skeleton, zen-skeleton[rounded]',
32
32
  template: ``,
33
- styleUrl: './skeleton.component.scss',
33
+ styleUrl: './skeleton.scss',
34
34
  changeDetection: ChangeDetectionStrategy.OnPush,
35
35
  })
36
- export class ZenSkeletonComponent {}
36
+ export class ZenSkeleton {}
@@ -1 +1 @@
1
- export * from './switch.component';
1
+ export * from './switch';
@@ -0,0 +1,22 @@
1
+ import { ComponentFixture, TestBed } from '@angular/core/testing';
2
+
3
+ import { ZenSwitch } from './switch';
4
+
5
+ describe('ZenSwitch', () => {
6
+ let component: ZenSwitch;
7
+ let fixture: ComponentFixture<ZenSwitch>;
8
+
9
+ beforeEach(async () => {
10
+ await TestBed.configureTestingModule({
11
+ imports: [ZenSwitch],
12
+ }).compileComponents();
13
+
14
+ fixture = TestBed.createComponent(ZenSwitch);
15
+ component = fixture.componentInstance;
16
+ fixture.detectChanges();
17
+ });
18
+
19
+ it('should create', () => {
20
+ expect(component).toBeTruthy();
21
+ });
22
+ });
@@ -1,10 +1,10 @@
1
1
  import { Meta, StoryObj } from '@storybook/angular';
2
2
 
3
- import { ZenSwitchComponent } from './switch.component';
3
+ import { ZenSwitch } from './switch';
4
4
 
5
5
  export default {
6
6
  title: 'Components/Switch',
7
- component: ZenSwitchComponent,
7
+ component: ZenSwitch,
8
8
  tags: ['autodocs'],
9
9
  argTypes: {
10
10
  value: { control: 'boolean' },
@@ -14,9 +14,9 @@ export default {
14
14
  value: false,
15
15
  disabled: false,
16
16
  },
17
- } satisfies Meta<ZenSwitchComponent>;
17
+ } satisfies Meta<ZenSwitch>;
18
18
 
19
- type Story = StoryObj<ZenSwitchComponent>;
19
+ type Story = StoryObj<ZenSwitch>;
20
20
 
21
21
  export const Default: Story = {
22
22
  render: args => ({
@@ -2,7 +2,7 @@ import { ChangeDetectionStrategy, Component, forwardRef, model } from '@angular/
2
2
  import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
3
3
 
4
4
  /**
5
- * ZenInputComponent is a reusable text input component designed to provide
5
+ * ZenInput is a reusable text input component designed to provide
6
6
  * a consistent and customizable input style across the application.
7
7
  * It supports Angular forms integration and provides two-way data binding.
8
8
  *
@@ -39,12 +39,12 @@ import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
39
39
  <!-- @if (!value()) { ─ } -->
40
40
  </span>
41
41
  `,
42
- styleUrl: './switch.component.scss',
42
+ styleUrl: './switch.scss',
43
43
  changeDetection: ChangeDetectionStrategy.OnPush,
44
44
  providers: [
45
45
  {
46
46
  provide: NG_VALUE_ACCESSOR,
47
- useExisting: forwardRef(() => ZenSwitchComponent),
47
+ useExisting: forwardRef(() => ZenSwitch),
48
48
  multi: true,
49
49
  },
50
50
  ],
@@ -57,7 +57,7 @@ import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
57
57
  '(keydown)': 'onKeyDown($event)',
58
58
  },
59
59
  })
60
- export class ZenSwitchComponent implements ControlValueAccessor {
60
+ export class ZenSwitch implements ControlValueAccessor {
61
61
  /** Holds the current checkbox value. */
62
62
  readonly value = model(false);
63
63
  /** Determines if the checkbox is disabled. */
@@ -1 +1 @@
1
- export * from './textarea.component';
1
+ export * from './textarea';
@@ -1,17 +1,17 @@
1
1
  import { ComponentFixture, TestBed } from '@angular/core/testing';
2
2
 
3
- import { ZenTextareaComponent } from './textarea.component';
3
+ import { ZenTextarea } from './textarea';
4
4
 
5
5
  describe('ZenTextareaComponent', () => {
6
- let component: ZenTextareaComponent;
7
- let fixture: ComponentFixture<ZenTextareaComponent>;
6
+ let component: ZenTextarea;
7
+ let fixture: ComponentFixture<ZenTextarea>;
8
8
 
9
9
  beforeEach(async () => {
10
10
  await TestBed.configureTestingModule({
11
- imports: [ZenTextareaComponent],
11
+ imports: [ZenTextarea],
12
12
  }).compileComponents();
13
13
 
14
- fixture = TestBed.createComponent(ZenTextareaComponent);
14
+ fixture = TestBed.createComponent(ZenTextarea);
15
15
  component = fixture.componentInstance;
16
16
  fixture.detectChanges();
17
17
  });
@@ -1,6 +1,6 @@
1
1
  import { Meta, StoryObj } from '@storybook/angular';
2
2
 
3
- import { ZenTextareaComponent } from './textarea.component';
3
+ import { ZenTextarea } from './textarea';
4
4
 
5
5
  interface StoryParams {
6
6
  value: string;
@@ -12,7 +12,7 @@ interface StoryParams {
12
12
 
13
13
  export default {
14
14
  title: 'Components/Textarea',
15
- component: ZenTextareaComponent,
15
+ component: ZenTextarea,
16
16
  tags: ['autodocs'],
17
17
  args: {
18
18
  value: '',
@@ -28,9 +28,9 @@ export default {
28
28
  required: { control: 'boolean' },
29
29
  disabled: { control: 'boolean' },
30
30
  },
31
- } satisfies Meta<ZenTextareaComponent & StoryParams>;
31
+ } satisfies Meta<ZenTextarea & StoryParams>;
32
32
 
33
- type Story = StoryObj<ZenTextareaComponent & StoryParams>;
33
+ type Story = StoryObj<ZenTextarea & StoryParams>;
34
34
 
35
35
  export const Default: Story = {
36
36
  render: args => ({
@@ -1,7 +1,7 @@
1
1
  import { ChangeDetectionStrategy, Component } from '@angular/core';
2
2
 
3
3
  /**
4
- * ZenTextareaComponent is a reusable textarea component designed to provide
4
+ * ZenTextarea is a reusable textarea component designed to provide
5
5
  * a consistent and customizable textarea style across the application.
6
6
  * It supports Angular forms integration and provides two-way data binding.
7
7
  *
@@ -32,7 +32,7 @@ import { ChangeDetectionStrategy, Component } from '@angular/core';
32
32
  template: `
33
33
  <ng-content />
34
34
  `,
35
- styleUrls: ['./textarea.component.scss'],
35
+ styleUrls: ['./textarea.scss'],
36
36
  changeDetection: ChangeDetectionStrategy.OnPush,
37
37
  })
38
- export class ZenTextareaComponent {}
38
+ export class ZenTextarea {}
@@ -4,7 +4,6 @@ exports.DEPENDENCIES_CONFIG = void 0;
4
4
  exports.DEPENDENCIES_CONFIG = {
5
5
  icon: {
6
6
  dependencies: {
7
- '@hugeicons/angular': 'latest',
8
7
  '@hugeicons/core-free-icons': 'latest',
9
8
  },
10
9
  },
@@ -1 +1 @@
1
- {"version":3,"file":"dependencies.constant.js","sourceRoot":"","sources":["../../../../../src/schematics/dependency-manager/dependencies.constant.ts"],"names":[],"mappings":";;;AAEa,QAAA,mBAAmB,GAAyB;IACvD,IAAI,EAAE;QACJ,YAAY,EAAE;YACZ,oBAAoB,EAAE,QAAQ;YAC9B,4BAA4B,EAAE,QAAQ;SACvC;KACF;CACF,CAAC","sourcesContent":["import { FilesConfig } from '../../types';\n\nexport const DEPENDENCIES_CONFIG: Partial<FilesConfig> = {\n icon: {\n dependencies: {\n '@hugeicons/angular': 'latest',\n '@hugeicons/core-free-icons': 'latest',\n },\n },\n};\n"]}
1
+ {"version":3,"file":"dependencies.constant.js","sourceRoot":"","sources":["../../../../../src/schematics/dependency-manager/dependencies.constant.ts"],"names":[],"mappings":";;;AAEa,QAAA,mBAAmB,GAAyB;IACvD,IAAI,EAAE;QACJ,YAAY,EAAE;YACZ,4BAA4B,EAAE,QAAQ;SACvC;KACF;CACF,CAAC","sourcesContent":["import { FilesConfig } from '../../types';\n\nexport const DEPENDENCIES_CONFIG: Partial<FilesConfig> = {\n icon: {\n dependencies: {\n '@hugeicons/core-free-icons': 'latest',\n },\n },\n};\n"]}
@@ -3,7 +3,6 @@ import { FilesConfig } from '../../types';
3
3
  export const DEPENDENCIES_CONFIG: Partial<FilesConfig> = {
4
4
  icon: {
5
5
  dependencies: {
6
- '@hugeicons/angular': 'latest',
7
6
  '@hugeicons/core-free-icons': 'latest',
8
7
  },
9
8
  },
@@ -1,22 +0,0 @@
1
- import { ComponentFixture, TestBed } from '@angular/core/testing';
2
-
3
- import { ZenCheckboxComponent } from './checkbox.component';
4
-
5
- describe('ZenCheckboxComponent', () => {
6
- let component: ZenCheckboxComponent;
7
- let fixture: ComponentFixture<ZenCheckboxComponent>;
8
-
9
- beforeEach(async () => {
10
- await TestBed.configureTestingModule({
11
- imports: [ZenCheckboxComponent],
12
- }).compileComponents();
13
-
14
- fixture = TestBed.createComponent(ZenCheckboxComponent);
15
- component = fixture.componentInstance;
16
- fixture.detectChanges();
17
- });
18
-
19
- it('should create', () => {
20
- expect(component).toBeTruthy();
21
- });
22
- });
@@ -1,22 +0,0 @@
1
- import { ComponentFixture, TestBed } from '@angular/core/testing';
2
-
3
- import { ZenDividerComponent } from './divider.component';
4
-
5
- describe('DividerComponent', () => {
6
- let component: ZenDividerComponent;
7
- let fixture: ComponentFixture<ZenDividerComponent>;
8
-
9
- beforeEach(async () => {
10
- await TestBed.configureTestingModule({
11
- imports: [ZenDividerComponent],
12
- }).compileComponents();
13
-
14
- fixture = TestBed.createComponent(ZenDividerComponent);
15
- component = fixture.componentInstance;
16
- fixture.detectChanges();
17
- });
18
-
19
- it('should create', () => {
20
- expect(component).toBeTruthy();
21
- });
22
- });
@@ -1,35 +0,0 @@
1
- import { ChangeDetectionStrategy, Component, input } from '@angular/core';
2
- import { HugeiconsIconComponent } from '@hugeicons/angular';
3
- import * as icons from '@hugeicons/core-free-icons';
4
-
5
- type Icon = keyof typeof icons;
6
-
7
- /**
8
- * A reusable Angular component for rendering icons from the Hugeicons library.
9
- *
10
- * This component acts as a wrapper around the `<hugeicons-icon>` component, allowing you to display any icon from the
11
- * `@hugeicons/core-free-icons` collection by specifying its name. The icon, size, and stroke width are fully configurable
12
- * via inputs.
13
- *
14
- * @example
15
- * <zen-icon icon="Tree02Icon" />
16
- *
17
- * @author Konrad Stępień
18
- * @license {@link https://github.com/kstepien3/ng-zen/blob/master/LICENSE|BSD-2-Clause}
19
- * @see [GitHub](https://github.com/kstepien3/ng-zen)
20
- * @see [Hugeicons](https://hugeicons.com)
21
- */
22
- @Component({
23
- selector: 'zen-icon',
24
- template: `
25
- <hugeicons-icon [icon]="icon()" [size]="size()" [strokeWidth]="strokeWidth()" color="currentColor" />
26
- `,
27
- imports: [HugeiconsIconComponent],
28
- changeDetection: ChangeDetectionStrategy.OnPush,
29
- })
30
- export class ZenIconComponent {
31
- /** Icon file names from HugeIcons */
32
- readonly icon = input.required({ transform: (icon: Icon) => icons[icon] });
33
- readonly size = input<number>(24);
34
- readonly strokeWidth = input<number>(1.5);
35
- }
@@ -1,22 +0,0 @@
1
- import { ComponentFixture, TestBed } from '@angular/core/testing';
2
-
3
- import { ZenSkeletonComponent } from './skeleton.component';
4
-
5
- describe('ZenSkeletonComponent', () => {
6
- let component: ZenSkeletonComponent;
7
- let fixture: ComponentFixture<ZenSkeletonComponent>;
8
-
9
- beforeEach(async () => {
10
- await TestBed.configureTestingModule({
11
- imports: [ZenSkeletonComponent],
12
- }).compileComponents();
13
-
14
- fixture = TestBed.createComponent(ZenSkeletonComponent);
15
- component = fixture.componentInstance;
16
- fixture.detectChanges();
17
- });
18
-
19
- it('should create', () => {
20
- expect(component).toBeTruthy();
21
- });
22
- });