semmet-angular 0.42.0 → 0.43.0

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 (202) hide show
  1. package/README.en.md +2 -315
  2. package/README.md +169 -264
  3. package/package.json +2 -2
  4. package/src/accordion/files/__name@dasherize__/__name@dasherize__.css.template +4 -41
  5. package/src/accordion/schema.json +19 -4
  6. package/src/alert/files/__name@dasherize__/__name@dasherize__.css.template +1 -25
  7. package/src/alert/files/__name@dasherize__/__name@dasherize__.html.template +3 -3
  8. package/src/alert/files/__name@dasherize__/__name@dasherize__.ts.template +4 -1
  9. package/src/alert/schema.json +19 -4
  10. package/src/alert-dialog/files/__name@dasherize__/__name@dasherize__.css.template +3 -56
  11. package/src/alert-dialog/files/__name@dasherize__/__name@dasherize__.html.template +6 -6
  12. package/src/alert-dialog/files/__name@dasherize__/__name@dasherize__.ts.template +7 -1
  13. package/src/alert-dialog/schema.json +19 -4
  14. package/src/avatar/files/__name@dasherize__/__name@dasherize__.css.template +17 -0
  15. package/src/avatar/files/__name@dasherize__/__name@dasherize__.html.template +28 -0
  16. package/src/avatar/files/__name@dasherize__/__name@dasherize__.spec.ts.template +27 -0
  17. package/src/avatar/files/__name@dasherize__/__name@dasherize__.ts.template +35 -0
  18. package/src/avatar/index.d.ts +1 -0
  19. package/src/avatar/index.js +6 -0
  20. package/src/avatar/index.js.map +1 -0
  21. package/src/avatar/index.ts +3 -0
  22. package/src/avatar/schema.d.ts +1 -0
  23. package/src/avatar/schema.js +3 -0
  24. package/src/avatar/schema.js.map +1 -0
  25. package/src/avatar/schema.json +44 -0
  26. package/src/avatar/schema.ts +1 -0
  27. package/src/badge/files/__name@dasherize__/__name@dasherize__.css.template +0 -77
  28. package/src/badge/files/__name@dasherize__/__name@dasherize__.ts.template +2 -5
  29. package/src/badge/schema.json +19 -4
  30. package/src/block/files/__name@dasherize__/__name@dasherize__.css.template +10 -81
  31. package/src/block/files/__name@dasherize__/__name@dasherize__.html.template +33 -25
  32. package/src/block/files/__name@dasherize__/__name@dasherize__.ts.template +41 -10
  33. package/src/block/schema.json +19 -4
  34. package/src/breadcrumb/files/__name@dasherize__/__name@dasherize__.css.template +2 -23
  35. package/src/breadcrumb/files/__name@dasherize__/__name@dasherize__.html.template +4 -4
  36. package/src/breadcrumb/files/__name@dasherize__/__name@dasherize__.ts.template +9 -5
  37. package/src/breadcrumb/schema.json +19 -4
  38. package/src/button/files/__name@dasherize__/__name@dasherize__.css.template +2 -79
  39. package/src/button/files/__name@dasherize__/__name@dasherize__.ts.template +2 -5
  40. package/src/button/schema.json +19 -4
  41. package/src/button-group/files/__name@dasherize__/__name@dasherize__.css.template +2 -70
  42. package/src/button-group/files/__name@dasherize__/__name@dasherize__.ts.template +1 -2
  43. package/src/button-group/schema.json +19 -4
  44. package/src/card/files/__name@dasherize__/__name@dasherize__.css.template +0 -67
  45. package/src/card/files/__name@dasherize__/__name@dasherize__.html.template +10 -55
  46. package/src/card/files/__name@dasherize__/__name@dasherize__.ts.template +2 -45
  47. package/src/card/schema.json +19 -4
  48. package/src/carousel/files/__name@dasherize__/__name@dasherize__.css.template +2 -32
  49. package/src/carousel/files/__name@dasherize__/__name@dasherize__.html.template +4 -4
  50. package/src/carousel/files/__name@dasherize__/__name@dasherize__.ts.template +4 -0
  51. package/src/carousel/schema.json +19 -4
  52. package/src/checkbox/files/__name@dasherize__/__name@dasherize__.css.template +5 -21
  53. package/src/checkbox/schema.json +19 -4
  54. package/src/close-button/files/__name@dasherize__/__name@dasherize__.css.template +9 -47
  55. package/src/close-button/files/__name@dasherize__/__name@dasherize__.ts.template +2 -5
  56. package/src/close-button/schema.json +19 -4
  57. package/src/collection.json +15 -0
  58. package/src/combobox/files/__name@dasherize__/__name@dasherize__.css.template +4 -49
  59. package/src/combobox/files/__name@dasherize__/__name@dasherize__.html.template +2 -2
  60. package/src/combobox/files/__name@dasherize__/__name@dasherize__.ts.template +11 -8
  61. package/src/combobox/schema.json +19 -4
  62. package/src/dialog/files/__name@dasherize__/__name@dasherize__.css.template +3 -45
  63. package/src/dialog/files/__name@dasherize__/__name@dasherize__.html.template +5 -5
  64. package/src/dialog/files/__name@dasherize__/__name@dasherize__.ts.template +6 -1
  65. package/src/dialog/schema.json +19 -4
  66. package/src/disclosure/files/__name@dasherize__/__name@dasherize__.css.template +4 -36
  67. package/src/disclosure/schema.json +19 -4
  68. package/src/form/files/__name@dasherize__/__name@dasherize__.css.template +1 -77
  69. package/src/form/files/__name@dasherize__/__name@dasherize__.html.template +7 -7
  70. package/src/form/files/__name@dasherize__/__name@dasherize__.ts.template +20 -7
  71. package/src/form/schema.json +19 -4
  72. package/src/input/files/__name@dasherize__/__name@dasherize__.css.template +2 -58
  73. package/src/input/schema.json +19 -4
  74. package/src/input-group/files/__name@dasherize__/__name@dasherize__.css.template +2 -68
  75. package/src/input-group/files/__name@dasherize__/__name@dasherize__.html.template +13 -5
  76. package/src/input-group/files/__name@dasherize__/__name@dasherize__.ts.template +21 -6
  77. package/src/input-group/schema.json +19 -4
  78. package/src/landmarks/files/__name@dasherize__/__name@dasherize__.css.template +0 -24
  79. package/src/landmarks/files/__name@dasherize__/__name@dasherize__.html.template +2 -2
  80. package/src/landmarks/files/__name@dasherize__/__name@dasherize__.ts.template +5 -2
  81. package/src/landmarks/schema.json +19 -4
  82. package/src/list-group/files/__name@dasherize__/__name@dasherize__.css.template +0 -123
  83. package/src/list-group/files/__name@dasherize__/__name@dasherize__.e2e-spec.ts.template +8 -9
  84. package/src/list-group/files/__name@dasherize__/__name@dasherize__.html.template +13 -47
  85. package/src/list-group/files/__name@dasherize__/__name@dasherize__.spec.ts.template +46 -24
  86. package/src/list-group/files/__name@dasherize__/__name@dasherize__.ts.template +97 -39
  87. package/src/list-group/schema.json +19 -4
  88. package/src/listbox/files/__name@dasherize__/__name@dasherize__.css.template +3 -37
  89. package/src/listbox/files/__name@dasherize__/__name@dasherize__.html.template +2 -2
  90. package/src/listbox/files/__name@dasherize__/__name@dasherize__.ts.template +3 -1
  91. package/src/listbox/schema.json +19 -4
  92. package/src/menu-button/files/__name@dasherize__/__name@dasherize__.css.template +7 -47
  93. package/src/menu-button/files/__name@dasherize__/__name@dasherize__.html.template +3 -3
  94. package/src/menu-button/files/__name@dasherize__/__name@dasherize__.ts.template +10 -7
  95. package/src/menu-button/schema.json +19 -4
  96. package/src/meter/files/__name@dasherize__/__name@dasherize__.css.template +0 -12
  97. package/src/meter/files/__name@dasherize__/__name@dasherize__.html.template +2 -2
  98. package/src/meter/files/__name@dasherize__/__name@dasherize__.ts.template +3 -1
  99. package/src/meter/schema.json +19 -4
  100. package/src/navbar/files/__name@dasherize__/__name@dasherize__.css.template +6 -62
  101. package/src/navbar/schema.json +19 -4
  102. package/src/navigation-menu/files/__name@dasherize__/__name@dasherize__.css.template +6 -37
  103. package/src/navigation-menu/files/__name@dasherize__/__name@dasherize__.html.template +7 -6
  104. package/src/navigation-menu/files/__name@dasherize__/__name@dasherize__.ts.template +15 -1
  105. package/src/navigation-menu/schema.json +19 -4
  106. package/src/offcanvas/files/__name@dasherize__/__name@dasherize__.css.template +3 -70
  107. package/src/offcanvas/schema.json +19 -4
  108. package/src/pagination/files/__name@dasherize__/__name@dasherize__.css.template +2 -33
  109. package/src/pagination/files/__name@dasherize__/__name@dasherize__.html.template +6 -6
  110. package/src/pagination/files/__name@dasherize__/__name@dasherize__.ts.template +7 -1
  111. package/src/pagination/schema.json +19 -4
  112. package/src/popover/files/__name@dasherize__/__name@dasherize__.css.template +8 -69
  113. package/src/popover/schema.json +19 -4
  114. package/src/progress-bar/files/__name@dasherize__/__name@dasherize__.css.template +1 -31
  115. package/src/progress-bar/files/__name@dasherize__/__name@dasherize__.html.template +3 -3
  116. package/src/progress-bar/files/__name@dasherize__/__name@dasherize__.ts.template +5 -1
  117. package/src/progress-bar/schema.json +19 -4
  118. package/src/radio-group/files/__name@dasherize__/__name@dasherize__.css.template +4 -31
  119. package/src/radio-group/files/__name@dasherize__/__name@dasherize__.html.template +2 -2
  120. package/src/radio-group/files/__name@dasherize__/__name@dasherize__.ts.template +2 -1
  121. package/src/radio-group/schema.json +19 -4
  122. package/src/rating/files/__name@dasherize__/__name@dasherize__.css.template +17 -0
  123. package/src/rating/files/__name@dasherize__/__name@dasherize__.html.template +34 -0
  124. package/src/rating/files/__name@dasherize__/__name@dasherize__.spec.ts.template +38 -0
  125. package/src/rating/files/__name@dasherize__/__name@dasherize__.ts.template +75 -0
  126. package/src/rating/index.d.ts +1 -0
  127. package/src/rating/index.js +6 -0
  128. package/src/rating/index.js.map +1 -0
  129. package/src/rating/index.ts +3 -0
  130. package/src/rating/schema.d.ts +1 -0
  131. package/src/rating/schema.js +3 -0
  132. package/src/rating/schema.js.map +1 -0
  133. package/src/rating/schema.json +44 -0
  134. package/src/rating/schema.ts +1 -0
  135. package/src/select/files/__name@dasherize__/__name@dasherize__.css.template +4 -55
  136. package/src/select/schema.json +19 -4
  137. package/src/skeleton/files/__name@dasherize__/__name@dasherize__.css.template +2 -29
  138. package/src/skeleton/files/__name@dasherize__/__name@dasherize__.ts.template +1 -3
  139. package/src/skeleton/schema.json +19 -4
  140. package/src/skip-link/files/__name@dasherize__/__name@dasherize__.css.template +2 -14
  141. package/src/skip-link/files/__name@dasherize__/__name@dasherize__.html.template +2 -2
  142. package/src/skip-link/files/__name@dasherize__/__name@dasherize__.ts.template +5 -2
  143. package/src/skip-link/schema.json +19 -4
  144. package/src/slider/files/__name@dasherize__/__name@dasherize__.css.template +6 -20
  145. package/src/slider/files/__name@dasherize__/__name@dasherize__.html.template +2 -2
  146. package/src/slider/files/__name@dasherize__/__name@dasherize__.ts.template +3 -1
  147. package/src/slider/schema.json +19 -4
  148. package/src/spinbutton/files/__name@dasherize__/__name@dasherize__.css.template +6 -35
  149. package/src/spinbutton/files/__name@dasherize__/__name@dasherize__.html.template +4 -4
  150. package/src/spinbutton/files/__name@dasherize__/__name@dasherize__.ts.template +5 -1
  151. package/src/spinbutton/schema.json +19 -4
  152. package/src/spinner/files/__name@dasherize__/__name@dasherize__.css.template +0 -43
  153. package/src/spinner/files/__name@dasherize__/__name@dasherize__.ts.template +2 -5
  154. package/src/spinner/schema.json +19 -4
  155. package/src/steps/files/__name@dasherize__/__name@dasherize__.css.template +36 -0
  156. package/src/steps/files/__name@dasherize__/__name@dasherize__.html.template +44 -0
  157. package/src/steps/files/__name@dasherize__/__name@dasherize__.spec.ts.template +35 -0
  158. package/src/steps/files/__name@dasherize__/__name@dasherize__.ts.template +107 -0
  159. package/src/steps/index.d.ts +1 -0
  160. package/src/steps/index.js +6 -0
  161. package/src/steps/index.js.map +1 -0
  162. package/src/steps/index.ts +3 -0
  163. package/src/steps/schema.d.ts +1 -0
  164. package/src/steps/schema.js +3 -0
  165. package/src/steps/schema.js.map +1 -0
  166. package/src/steps/schema.json +44 -0
  167. package/src/steps/schema.ts +1 -0
  168. package/src/switch/files/__name@dasherize__/__name@dasherize__.css.template +7 -22
  169. package/src/switch/schema.json +19 -4
  170. package/src/table/files/__name@dasherize__/__name@dasherize__.css.template +0 -25
  171. package/src/table/files/__name@dasherize__/__name@dasherize__.html.template +3 -3
  172. package/src/table/files/__name@dasherize__/__name@dasherize__.ts.template +3 -0
  173. package/src/table/schema.json +19 -4
  174. package/src/tabs/files/__name@dasherize__/__name@dasherize__.css.template +5 -44
  175. package/src/tabs/files/__name@dasherize__/__name@dasherize__.html.template +2 -2
  176. package/src/tabs/files/__name@dasherize__/__name@dasherize__.ts.template +2 -0
  177. package/src/tabs/schema.json +19 -4
  178. package/src/textarea/files/__name@dasherize__/__name@dasherize__.css.template +2 -59
  179. package/src/textarea/schema.json +19 -4
  180. package/src/toast/files/__name@dasherize__/__name@dasherize__.css.template +1 -35
  181. package/src/toast/files/__name@dasherize__/__name@dasherize__.html.template +4 -4
  182. package/src/toast/files/__name@dasherize__/__name@dasherize__.ts.template +5 -1
  183. package/src/toast/schema.json +19 -4
  184. package/src/toolbar/files/__name@dasherize__/__name@dasherize__.css.template +2 -36
  185. package/src/toolbar/files/__name@dasherize__/__name@dasherize__.html.template +3 -3
  186. package/src/toolbar/files/__name@dasherize__/__name@dasherize__.ts.template +11 -8
  187. package/src/toolbar/schema.json +19 -4
  188. package/src/tooltip/files/__name@dasherize__/__name@dasherize__.css.template +1 -32
  189. package/src/tooltip/schema.json +19 -4
  190. package/src/tree-view/files/__name@dasherize__/__name@dasherize__.css.template +5 -27
  191. package/src/tree-view/files/__name@dasherize__/__name@dasherize__.html.template +3 -3
  192. package/src/tree-view/files/__name@dasherize__/__name@dasherize__.ts.template +16 -13
  193. package/src/tree-view/schema.json +19 -4
  194. package/src/utils/generate-component.js +3 -1
  195. package/src/utils/generate-component.js.map +1 -1
  196. package/src/utils/generate-component.ts +3 -1
  197. package/src/utils/generate-composition.js +0 -1
  198. package/src/utils/generate-composition.js.map +1 -1
  199. package/src/utils/generate-composition.ts +0 -1
  200. package/src/utils/schema-types.d.ts +1 -0
  201. package/src/utils/schema-types.ts +1 -0
  202. package/README.pt-BR.md +0 -330
@@ -9,21 +9,36 @@
9
9
  "name": {
10
10
  "type": "string",
11
11
  "description": "The name for the new component. Used to derive the class name, selector, and file names.",
12
- "$default": { "$source": "argv", "index": 0 },
12
+ "$default": {
13
+ "$source": "argv",
14
+ "index": 0
15
+ },
13
16
  "x-prompt": "What name would you like to use for the accordion component?"
14
17
  },
18
+ "e2e": {
19
+ "type": "boolean",
20
+ "default": false,
21
+ "description": "Generate a Playwright e2e spec for this component. Requires Playwright to be installed/configured in the consuming app."
22
+ },
15
23
  "path": {
16
24
  "type": "string",
17
25
  "format": "path",
18
- "$default": { "$source": "workingDirectory" },
26
+ "$default": {
27
+ "$source": "workingDirectory"
28
+ },
19
29
  "description": "The path where the component files should be created, relative to the workspace root. Defaults to the project's source root.",
20
30
  "visible": false
21
31
  },
22
32
  "project": {
23
33
  "type": "string",
24
34
  "description": "The name of the project to add the component to.",
25
- "$default": { "$source": "projectName" }
35
+ "$default": {
36
+ "$source": "projectName"
37
+ }
26
38
  }
27
39
  },
28
- "required": ["name", "project"]
40
+ "required": [
41
+ "name",
42
+ "project"
43
+ ]
29
44
  }
@@ -1,46 +1,22 @@
1
1
  :host {
2
- --semmet-color-primary: #18181b;
3
- --semmet-color-on-primary: #ffffff;
4
- --semmet-radius-sm: 8px;
5
- --semmet-space-3xs: 4px;
6
- --semmet-space-2xs: 8px;
7
- --semmet-space-xs: 16px;
8
- --semmet-motion: 160ms cubic-bezier(0.2, 0, 0, 1);
9
-
10
2
  display: block;
11
- font-family: Roboto, system-ui, -apple-system, 'Segoe UI', sans-serif;
12
- font-size: 0.9375rem;
13
3
  }
14
4
 
15
5
  [role='alert'] {
16
6
  display: flex;
17
7
  align-items: center;
18
8
  justify-content: space-between;
19
- gap: var(--semmet-space-xs);
20
- padding: var(--semmet-space-xs);
21
- color: var(--semmet-color-on-primary);
22
- background: var(--semmet-color-primary);
23
- border-radius: var(--semmet-radius-sm);
24
9
  }
25
10
 
26
11
  button {
27
12
  font: inherit;
28
- font-size: 1.125rem;
29
- line-height: 1;
30
13
  color: inherit;
31
14
  background: none;
32
15
  border: none;
33
16
  cursor: pointer;
34
- border-radius: 4px;
35
- padding: var(--semmet-space-3xs) var(--semmet-space-2xs);
36
- transition: background-color var(--semmet-motion);
37
- }
38
-
39
- button:hover {
40
- background: color-mix(in srgb, var(--semmet-color-on-primary) 20%, transparent);
41
17
  }
42
18
 
43
19
  button:focus-visible {
44
- outline: 2px solid var(--semmet-color-on-primary);
20
+ outline: 2px solid currentColor;
45
21
  outline-offset: 2px;
46
22
  }
@@ -3,11 +3,11 @@
3
3
  Usage from a parent component template:
4
4
  Import <%= classify(name) %> in that parent component.
5
5
 
6
- <<%= selector %> />
6
+ <<%= selector %> message="Your changes have been saved." />
7
7
  -->
8
8
  @if (visible()) {
9
9
  <div role="alert" [id]="instanceId">
10
- <span>Your changes have been saved.</span>
11
- <button type="button" (click)="dismiss()" aria-label="Dismiss">×</button>
10
+ <span>{{ message() }}</span>
11
+ <button type="button" (click)="dismiss()" [attr.aria-label]="dismissLabel()">×</button>
12
12
  </div>
13
13
  }
@@ -1,4 +1,4 @@
1
- import { Component, signal } from '@angular/core';
1
+ import { Component, input, signal } from '@angular/core';
2
2
 
3
3
  let nextId = 0;
4
4
 
@@ -12,6 +12,9 @@ export class <%= classify(name) %> {
12
12
  protected readonly instanceId = `<%= dasherize(name) %>-${nextId++}`;
13
13
  protected readonly visible = signal(true);
14
14
 
15
+ readonly message = input('Your changes have been saved.');
16
+ readonly dismissLabel = input('Dismiss');
17
+
15
18
  protected dismiss(): void {
16
19
  this.visible.set(false);
17
20
  }
@@ -9,21 +9,36 @@
9
9
  "name": {
10
10
  "type": "string",
11
11
  "description": "The name for the new component. Used to derive the class name, selector, and file names.",
12
- "$default": { "$source": "argv", "index": 0 },
12
+ "$default": {
13
+ "$source": "argv",
14
+ "index": 0
15
+ },
13
16
  "x-prompt": "What name would you like to use for the alert component?"
14
17
  },
18
+ "e2e": {
19
+ "type": "boolean",
20
+ "default": false,
21
+ "description": "Generate a Playwright e2e spec for this component. Requires Playwright to be installed/configured in the consuming app."
22
+ },
15
23
  "path": {
16
24
  "type": "string",
17
25
  "format": "path",
18
- "$default": { "$source": "workingDirectory" },
26
+ "$default": {
27
+ "$source": "workingDirectory"
28
+ },
19
29
  "description": "The path where the component files should be created, relative to the workspace root. Defaults to the project's source root.",
20
30
  "visible": false
21
31
  },
22
32
  "project": {
23
33
  "type": "string",
24
34
  "description": "The name of the project to add the component to.",
25
- "$default": { "$source": "projectName" }
35
+ "$default": {
36
+ "$source": "projectName"
37
+ }
26
38
  }
27
39
  },
28
- "required": ["name", "project"]
40
+ "required": [
41
+ "name",
42
+ "project"
43
+ ]
29
44
  }
@@ -1,59 +1,18 @@
1
- :host {
2
- --semmet-color-primary: #18181b;
3
- --semmet-color-on-primary: #ffffff;
4
- --semmet-color-surface: #ffffff;
5
- --semmet-color-on-surface: #18181b;
6
- --semmet-color-on-surface-variant: #52525b;
7
- --semmet-color-scrim: rgba(20, 24, 23, 0.45);
8
- --semmet-radius-lg: 20px;
9
- --semmet-space-2xs: 8px;
10
- --semmet-space-xs: 16px;
11
- --semmet-space-sm: 24px;
12
- --semmet-target-md: 40px;
13
- --semmet-elevation-3: 0 8px 24px rgba(20, 24, 23, 0.18), 0 2px 8px rgba(20, 24, 23, 0.1);
14
- --semmet-motion: 160ms cubic-bezier(0.2, 0, 0, 1);
15
-
16
- font-family: Roboto, system-ui, -apple-system, 'Segoe UI', sans-serif;
17
- font-size: 0.9375rem;
18
- line-height: 1.5;
19
- }
20
-
21
1
  button {
22
2
  font: inherit;
23
- font-weight: 500;
24
- color: var(--semmet-color-primary);
25
3
  background: none;
26
4
  border: none;
27
- border-radius: 8px;
28
- min-height: var(--semmet-target-md);
29
- padding: var(--semmet-space-2xs) var(--semmet-space-xs);
30
5
  cursor: pointer;
31
- transition: background-color var(--semmet-motion);
32
- }
33
-
34
- button:hover {
35
- background: color-mix(in srgb, var(--semmet-color-primary) 8%, transparent);
36
6
  }
37
7
 
38
8
  button:focus-visible {
39
- outline: 2px solid var(--semmet-color-primary);
9
+ outline: 2px solid currentColor;
40
10
  outline-offset: 2px;
41
11
  }
42
12
 
43
- [role='alertdialog'] button:last-of-type {
44
- color: var(--semmet-color-on-primary);
45
- background: var(--semmet-color-primary);
46
- margin-left: var(--semmet-space-2xs);
47
- }
48
-
49
- [role='alertdialog'] button:last-of-type:hover {
50
- background: color-mix(in srgb, var(--semmet-color-primary) 88%, black);
51
- }
52
-
53
13
  .backdrop {
54
14
  position: fixed;
55
15
  inset: 0;
56
- background: var(--semmet-color-scrim);
57
16
  }
58
17
 
59
18
  [role='alertdialog'] {
@@ -63,25 +22,13 @@ button:focus-visible {
63
22
  transform: translate(-50%, -50%);
64
23
  min-width: 22rem;
65
24
  max-width: 90vw;
66
- padding: var(--semmet-space-sm);
67
- border-radius: var(--semmet-radius-lg);
68
- background: var(--semmet-color-surface);
69
- color: var(--semmet-color-on-surface);
70
- box-shadow: var(--semmet-elevation-3);
71
25
  }
72
26
 
73
27
  [role='alertdialog']:focus-visible {
74
- outline: 2px solid var(--semmet-color-primary);
28
+ outline: 2px solid currentColor;
75
29
  outline-offset: 2px;
76
30
  }
77
31
 
78
32
  [role='alertdialog'] h2 {
79
- margin: 0 0 var(--semmet-space-xs);
80
- font-size: 1.25rem;
81
- font-weight: 500;
82
- }
83
-
84
- [role='alertdialog'] > div {
85
- margin-bottom: var(--semmet-space-sm);
86
- color: var(--semmet-color-on-surface-variant);
33
+ margin: 0;
87
34
  }
@@ -3,9 +3,9 @@
3
3
  Usage from a parent component template:
4
4
  Import <%= classify(name) %> in that parent component.
5
5
 
6
- <<%= selector %> />
6
+ <<%= selector %> triggerLabel="Delete item" title="Confirm delete" />
7
7
  -->
8
- <button type="button" (click)="open($event)">Delete item</button>
8
+ <button type="button" (click)="open($event)">{{ triggerLabel() }}</button>
9
9
 
10
10
  @if (isOpen()) {
11
11
  <div class="backdrop" (click)="close()"></div>
@@ -18,9 +18,9 @@ Import <%= classify(name) %> in that parent component.
18
18
  tabindex="-1"
19
19
  (keydown)="handleDialogKeydown($event)"
20
20
  >
21
- <h2 [id]="instanceId + '-title'">Confirm action</h2>
22
- <div [id]="instanceId + '-description'">Are you sure you want to continue? This action cannot be undone.</div>
23
- <button type="button" (click)="close()">Cancel</button>
24
- <button type="button" (click)="close()">Confirm</button>
21
+ <h2 [id]="instanceId + '-title'">{{ title() }}</h2>
22
+ <div [id]="instanceId + '-description'">{{ description() }}</div>
23
+ <button type="button" (click)="close()">{{ cancelLabel() }}</button>
24
+ <button type="button" (click)="close()">{{ confirmLabel() }}</button>
25
25
  </div>
26
26
  }
@@ -1,4 +1,4 @@
1
- import { Component, ElementRef, Injector, afterNextRender, inject, signal, viewChild } from '@angular/core';
1
+ import { Component, ElementRef, Injector, afterNextRender, inject, input, signal, viewChild } from '@angular/core';
2
2
 
3
3
  const FOCUSABLE_SELECTOR =
4
4
  'a[href], button:not([disabled]), textarea:not([disabled]), input:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex="-1"])';
@@ -19,6 +19,12 @@ export class <%= classify(name) %> {
19
19
  protected readonly instanceId = `<%= dasherize(name) %>-${nextId++}`;
20
20
  protected readonly isOpen = signal(false);
21
21
 
22
+ readonly triggerLabel = input('Delete item');
23
+ readonly title = input('Confirm action');
24
+ readonly description = input('Are you sure you want to continue? This action cannot be undone.');
25
+ readonly cancelLabel = input('Cancel');
26
+ readonly confirmLabel = input('Confirm');
27
+
22
28
  protected open(event: MouseEvent): void {
23
29
  this.triggerElement = event.currentTarget as HTMLElement;
24
30
  this.isOpen.set(true);
@@ -9,21 +9,36 @@
9
9
  "name": {
10
10
  "type": "string",
11
11
  "description": "The name for the new component. Used to derive the class name, selector, and file names.",
12
- "$default": { "$source": "argv", "index": 0 },
12
+ "$default": {
13
+ "$source": "argv",
14
+ "index": 0
15
+ },
13
16
  "x-prompt": "What name would you like to use for the alert dialog component?"
14
17
  },
18
+ "e2e": {
19
+ "type": "boolean",
20
+ "default": false,
21
+ "description": "Generate a Playwright e2e spec for this component. Requires Playwright to be installed/configured in the consuming app."
22
+ },
15
23
  "path": {
16
24
  "type": "string",
17
25
  "format": "path",
18
- "$default": { "$source": "workingDirectory" },
26
+ "$default": {
27
+ "$source": "workingDirectory"
28
+ },
19
29
  "description": "The path where the component files should be created, relative to the workspace root. Defaults to the project's source root.",
20
30
  "visible": false
21
31
  },
22
32
  "project": {
23
33
  "type": "string",
24
34
  "description": "The name of the project to add the component to.",
25
- "$default": { "$source": "projectName" }
35
+ "$default": {
36
+ "$source": "projectName"
37
+ }
26
38
  }
27
39
  },
28
- "required": ["name", "project"]
40
+ "required": [
41
+ "name",
42
+ "project"
43
+ ]
29
44
  }
@@ -0,0 +1,17 @@
1
+ :host {
2
+ display: inline-block;
3
+ }
4
+
5
+ .semmet-avatar {
6
+ display: inline-flex;
7
+ align-items: center;
8
+ justify-content: center;
9
+ overflow: hidden;
10
+ }
11
+
12
+ .semmet-avatar__image {
13
+ display: block;
14
+ width: 100%;
15
+ height: 100%;
16
+ object-fit: cover;
17
+ }
@@ -0,0 +1,28 @@
1
+ <!-- Semmet Angular: Avatar - image or initials with decorative and accessible-label modes. -->
2
+ <!--
3
+ Usage from a parent component template:
4
+ Import <%= classify(name) %> in that parent component.
5
+
6
+ <<%= selector %> name="Ada Lovelace" src="/assets/ada.jpg" />
7
+ <<%= selector %> name="Grace Hopper" />
8
+
9
+ <<%= selector %> name="Katherine Johnson">
10
+ <ng-template <%= camelize(name) %>Fallback>
11
+ KJ
12
+ </ng-template>
13
+ </<%= selector %>>
14
+ -->
15
+ <span
16
+ [class]="avatarClasses()"
17
+ [attr.role]="src() ? null : 'img'"
18
+ [attr.aria-label]="src() ? null : accessibleLabel()"
19
+ [attr.aria-hidden]="ariaHidden()"
20
+ >
21
+ @if (src()) {
22
+ <img class="semmet-avatar__image" [src]="src()" [alt]="altText()" />
23
+ } @else if (fallback(); as fallbackSlot) {
24
+ <ng-container [ngTemplateOutlet]="fallbackSlot.templateRef" />
25
+ } @else {
26
+ <span class="semmet-avatar__initials" aria-hidden="true">{{ initials() }}</span>
27
+ }
28
+ </span>
@@ -0,0 +1,27 @@
1
+ import { Component } from '@angular/core';
2
+ import { ComponentFixture, TestBed } from '@angular/core/testing';
3
+ import { <%= classify(name) %> } from './<%= dasherize(name) %>';
4
+
5
+ @Component({
6
+ imports: [<%= classify(name) %>],
7
+ template: `<<%= selector %> name="Ada Lovelace" />`,
8
+ })
9
+ class Host {}
10
+
11
+ describe('<%= classify(name) %>', () => {
12
+ let fixture: ComponentFixture<Host>;
13
+
14
+ beforeEach(async () => {
15
+ await TestBed.configureTestingModule({ imports: [Host] }).compileComponents();
16
+ fixture = TestBed.createComponent(Host);
17
+ fixture.detectChanges();
18
+ });
19
+
20
+ it('renders initials with image semantics when no src is provided', () => {
21
+ const avatar = fixture.nativeElement.querySelector('.semmet-avatar');
22
+
23
+ expect(avatar.getAttribute('role')).toBe('img');
24
+ expect(avatar.getAttribute('aria-label')).toBe('Ada Lovelace');
25
+ expect(avatar.textContent).toContain('AL');
26
+ });
27
+ });
@@ -0,0 +1,35 @@
1
+ import { NgTemplateOutlet } from '@angular/common';
2
+ import { Component, Directive, TemplateRef, booleanAttribute, computed, contentChild, inject, input } from '@angular/core';
3
+
4
+ @Directive({
5
+ selector: 'ng-template[<%= camelize(name) %>Fallback]',
6
+ })
7
+ export class <%= classify(name) %>Fallback {
8
+ readonly templateRef = inject<TemplateRef<unknown>>(TemplateRef);
9
+ }
10
+
11
+ @Component({
12
+ selector: '<%= selector %>',
13
+ imports: [NgTemplateOutlet],
14
+ templateUrl: './<%= dasherize(name) %>.html',
15
+ styleUrl: './<%= dasherize(name) %>.css',
16
+ })
17
+ export class <%= classify(name) %> {
18
+ protected readonly fallback = contentChild(<%= classify(name) %>Fallback);
19
+
20
+ readonly src = input('');
21
+ readonly name = input('Ada Lovelace');
22
+ readonly label = input('');
23
+ readonly decorative = input(false, { transform: booleanAttribute });
24
+ readonly size = input<string>('md');
25
+
26
+ protected readonly avatarClasses = computed(() => `semmet-avatar semmet-avatar--${this.size()}`);
27
+ protected readonly accessibleLabel = computed(() => this.decorative() ? null : this.label() || this.name());
28
+ protected readonly ariaHidden = computed(() => this.decorative() ? 'true' : null);
29
+ protected readonly altText = computed(() => this.decorative() ? '' : this.accessibleLabel() ?? '');
30
+
31
+ protected readonly initials = computed(() => {
32
+ const words = this.name().trim().split(/\s+/).filter(Boolean);
33
+ return words.slice(0, 2).map((word) => word[0]?.toUpperCase() ?? '').join('') || '?';
34
+ });
35
+ }
@@ -0,0 +1 @@
1
+ export declare const avatar: (options: import("./schema").Schema) => import("@angular-devkit/schematics").Rule;
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.avatar = void 0;
4
+ const generate_component_1 = require("../utils/generate-component");
5
+ exports.avatar = (0, generate_component_1.createAriaComponentSchematic)({ includeSharedUnitTest: false });
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":";;;AAAA,oEAA2E;AAE9D,QAAA,MAAM,GAAG,IAAA,iDAA4B,EAAC,EAAE,qBAAqB,EAAE,KAAK,EAAE,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { createAriaComponentSchematic } from '../utils/generate-component';
2
+
3
+ export const avatar = createAriaComponentSchematic({ includeSharedUnitTest: false });
@@ -0,0 +1 @@
1
+ export { ComponentSchematicOptions as Schema } from '../utils/schema-types';
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["schema.ts"],"names":[],"mappings":""}
@@ -0,0 +1,44 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema",
3
+ "$id": "SemmetAngularAvatar",
4
+ "title": "Semmet Angular Avatar Options Schema",
5
+ "type": "object",
6
+ "description": "Generates a standalone Angular Avatar component with image, initials, decorative, and accessible-label modes.",
7
+ "additionalProperties": false,
8
+ "properties": {
9
+ "name": {
10
+ "type": "string",
11
+ "description": "The name for the new component. Used to derive the class name, selector, and file names.",
12
+ "$default": {
13
+ "$source": "argv",
14
+ "index": 0
15
+ },
16
+ "x-prompt": "What name would you like to use for the avatar component?"
17
+ },
18
+ "e2e": {
19
+ "type": "boolean",
20
+ "default": false,
21
+ "description": "Generate a Playwright e2e spec for this component. Requires Playwright to be installed/configured in the consuming app."
22
+ },
23
+ "path": {
24
+ "type": "string",
25
+ "format": "path",
26
+ "$default": {
27
+ "$source": "workingDirectory"
28
+ },
29
+ "description": "The path where the component files should be created, relative to the workspace root. Defaults to the project's source root.",
30
+ "visible": false
31
+ },
32
+ "project": {
33
+ "type": "string",
34
+ "description": "The name of the project to add the component to.",
35
+ "$default": {
36
+ "$source": "projectName"
37
+ }
38
+ }
39
+ },
40
+ "required": [
41
+ "name",
42
+ "project"
43
+ ]
44
+ }
@@ -0,0 +1 @@
1
+ export { ComponentSchematicOptions as Schema } from '../utils/schema-types';
@@ -1,105 +1,28 @@
1
1
  :host {
2
- --semmet-color-primary: #18181b;
3
- --semmet-color-on-primary: #ffffff;
4
- --semmet-color-neutral: #f4f4f5;
5
- --semmet-color-on-neutral: #27272a;
6
- --semmet-color-success: #067647;
7
- --semmet-color-on-success: #ffffff;
8
- --semmet-color-warning: #b54708;
9
- --semmet-color-on-warning: #ffffff;
10
- --semmet-color-danger: #b42318;
11
- --semmet-color-on-danger: #ffffff;
12
- --semmet-color-info: #175cd3;
13
- --semmet-color-on-info: #ffffff;
14
- --semmet-radius-full: 999px;
15
- --semmet-radius-sm: 6px;
16
- --semmet-space-3xs: 4px;
17
- --semmet-space-2xs: 8px;
18
- --semmet-target-sm: 32px;
19
-
20
2
  display: inline-block;
21
- font-family: Roboto, system-ui, -apple-system, 'Segoe UI', sans-serif;
22
3
  }
23
4
 
24
5
  .semmet-badge {
25
6
  display: inline-flex;
26
7
  align-items: center;
27
8
  justify-content: center;
28
- gap: var(--semmet-space-2xs);
29
- border-radius: var(--semmet-radius-sm);
30
- font-weight: 700;
31
9
  line-height: 1;
32
10
  white-space: nowrap;
33
11
  vertical-align: baseline;
34
12
  }
35
13
 
36
- .semmet-badge--sm {
37
- min-height: 1.25rem;
38
- padding: var(--semmet-space-3xs) var(--semmet-space-2xs);
39
- font-size: 0.6875rem;
40
- }
41
-
42
- .semmet-badge--md {
43
- min-height: 1.5rem;
44
- padding: var(--semmet-space-2xs);
45
- font-size: 0.75rem;
46
- }
47
-
48
- .semmet-badge--lg {
49
- min-height: 1.75rem;
50
- padding: var(--semmet-space-2xs);
51
- font-size: 0.8125rem;
52
- }
53
-
54
- .semmet-badge--pill {
55
- border-radius: var(--semmet-radius-full);
56
- }
57
-
58
14
  .semmet-badge--dot {
59
15
  min-width: auto;
60
- padding-inline-start: var(--semmet-space-2xs);
61
16
  }
62
17
 
63
18
  .semmet-badge--dot:has(.semmet-badge__dot):not(:has(.semmet-badge__label)) {
64
19
  width: 0.75rem;
65
20
  min-height: 0.75rem;
66
21
  padding: 0;
67
- border-radius: var(--semmet-radius-full);
68
22
  }
69
23
 
70
24
  .semmet-badge__dot {
71
25
  width: 0.5em;
72
26
  height: 0.5em;
73
- border-radius: var(--semmet-radius-full);
74
27
  background: currentColor;
75
28
  }
76
-
77
- .semmet-badge--neutral {
78
- color: var(--semmet-color-on-neutral);
79
- background: var(--semmet-color-neutral);
80
- }
81
-
82
- .semmet-badge--primary {
83
- color: var(--semmet-color-on-primary);
84
- background: var(--semmet-color-primary);
85
- }
86
-
87
- .semmet-badge--success {
88
- color: var(--semmet-color-on-success);
89
- background: var(--semmet-color-success);
90
- }
91
-
92
- .semmet-badge--warning {
93
- color: var(--semmet-color-on-warning);
94
- background: var(--semmet-color-warning);
95
- }
96
-
97
- .semmet-badge--danger {
98
- color: var(--semmet-color-on-danger);
99
- background: var(--semmet-color-danger);
100
- }
101
-
102
- .semmet-badge--info {
103
- color: var(--semmet-color-on-info);
104
- background: var(--semmet-color-info);
105
- }
@@ -1,9 +1,6 @@
1
1
  import { NgTemplateOutlet } from '@angular/common';
2
2
  import { Component, Directive, TemplateRef, booleanAttribute, computed, contentChild, inject, input } from '@angular/core';
3
3
 
4
- type <%= classify(name) %>Variant = 'neutral' | 'primary' | 'success' | 'warning' | 'danger' | 'info';
5
- type <%= classify(name) %>Size = 'sm' | 'md' | 'lg';
6
-
7
4
  let nextId = 0;
8
5
 
9
6
  @Directive({
@@ -24,8 +21,8 @@ export class <%= classify(name) %> {
24
21
  protected readonly instanceId = `<%= dasherize(name) %>-${nextId++}`;
25
22
 
26
23
  readonly label = input('Badge');
27
- readonly variant = input<<%= classify(name) %>Variant>('neutral');
28
- readonly size = input<<%= classify(name) %>Size>('md');
24
+ readonly variant = input<string>('neutral');
25
+ readonly size = input<string>('md');
29
26
  readonly pill = input(false, { transform: booleanAttribute });
30
27
  readonly dot = input(false, { transform: booleanAttribute });
31
28
  readonly decorative = input(false, { transform: booleanAttribute });