semmet-angular 0.42.0 → 0.44.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 (218) hide show
  1. package/README.en.md +2 -315
  2. package/README.md +172 -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 +21 -1
  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/e2e/index.d.ts +2 -0
  69. package/src/e2e/index.js +90 -0
  70. package/src/e2e/index.js.map +1 -0
  71. package/src/e2e/index.ts +106 -0
  72. package/src/e2e/schema.d.ts +2 -0
  73. package/src/e2e/schema.js +3 -0
  74. package/src/e2e/schema.js.map +1 -0
  75. package/src/e2e/schema.json +9 -0
  76. package/src/e2e/schema.ts +1 -0
  77. package/src/form/files/__name@dasherize__/__name@dasherize__.css.template +1 -77
  78. package/src/form/files/__name@dasherize__/__name@dasherize__.html.template +7 -7
  79. package/src/form/files/__name@dasherize__/__name@dasherize__.ts.template +20 -7
  80. package/src/form/schema.json +19 -4
  81. package/src/input/files/__name@dasherize__/__name@dasherize__.css.template +2 -58
  82. package/src/input/schema.json +19 -4
  83. package/src/input-group/files/__name@dasherize__/__name@dasherize__.css.template +2 -68
  84. package/src/input-group/files/__name@dasherize__/__name@dasherize__.html.template +13 -5
  85. package/src/input-group/files/__name@dasherize__/__name@dasherize__.ts.template +21 -6
  86. package/src/input-group/schema.json +19 -4
  87. package/src/landmarks/files/__name@dasherize__/__name@dasherize__.css.template +0 -24
  88. package/src/landmarks/files/__name@dasherize__/__name@dasherize__.html.template +2 -2
  89. package/src/landmarks/files/__name@dasherize__/__name@dasherize__.ts.template +5 -2
  90. package/src/landmarks/schema.json +19 -4
  91. package/src/list-group/files/__name@dasherize__/__name@dasherize__.css.template +0 -123
  92. package/src/list-group/files/__name@dasherize__/__name@dasherize__.e2e-spec.ts.template +8 -9
  93. package/src/list-group/files/__name@dasherize__/__name@dasherize__.html.template +13 -47
  94. package/src/list-group/files/__name@dasherize__/__name@dasherize__.spec.ts.template +46 -24
  95. package/src/list-group/files/__name@dasherize__/__name@dasherize__.ts.template +97 -39
  96. package/src/list-group/schema.json +19 -4
  97. package/src/listbox/files/__name@dasherize__/__name@dasherize__.css.template +3 -37
  98. package/src/listbox/files/__name@dasherize__/__name@dasherize__.html.template +2 -2
  99. package/src/listbox/files/__name@dasherize__/__name@dasherize__.ts.template +3 -1
  100. package/src/listbox/schema.json +19 -4
  101. package/src/menu-button/files/__name@dasherize__/__name@dasherize__.css.template +7 -47
  102. package/src/menu-button/files/__name@dasherize__/__name@dasherize__.html.template +3 -3
  103. package/src/menu-button/files/__name@dasherize__/__name@dasherize__.ts.template +10 -7
  104. package/src/menu-button/schema.json +19 -4
  105. package/src/meter/files/__name@dasherize__/__name@dasherize__.css.template +0 -12
  106. package/src/meter/files/__name@dasherize__/__name@dasherize__.html.template +2 -2
  107. package/src/meter/files/__name@dasherize__/__name@dasherize__.ts.template +3 -1
  108. package/src/meter/schema.json +19 -4
  109. package/src/navbar/files/__name@dasherize__/__name@dasherize__.css.template +6 -62
  110. package/src/navbar/schema.json +19 -4
  111. package/src/navigation-menu/files/__name@dasherize__/__name@dasherize__.css.template +6 -37
  112. package/src/navigation-menu/files/__name@dasherize__/__name@dasherize__.html.template +7 -6
  113. package/src/navigation-menu/files/__name@dasherize__/__name@dasherize__.ts.template +15 -1
  114. package/src/navigation-menu/schema.json +19 -4
  115. package/src/ng-add/index.d.ts +1 -1
  116. package/src/ng-add/index.js +2 -72
  117. package/src/ng-add/index.js.map +1 -1
  118. package/src/ng-add/index.ts +3 -86
  119. package/src/ng-add/schema.d.ts +0 -1
  120. package/src/ng-add/schema.json +0 -5
  121. package/src/ng-add/schema.ts +0 -1
  122. package/src/offcanvas/files/__name@dasherize__/__name@dasherize__.css.template +3 -70
  123. package/src/offcanvas/schema.json +19 -4
  124. package/src/pagination/files/__name@dasherize__/__name@dasherize__.css.template +2 -33
  125. package/src/pagination/files/__name@dasherize__/__name@dasherize__.html.template +6 -6
  126. package/src/pagination/files/__name@dasherize__/__name@dasherize__.ts.template +7 -1
  127. package/src/pagination/schema.json +19 -4
  128. package/src/popover/files/__name@dasherize__/__name@dasherize__.css.template +8 -69
  129. package/src/popover/schema.json +19 -4
  130. package/src/progress-bar/files/__name@dasherize__/__name@dasherize__.css.template +1 -31
  131. package/src/progress-bar/files/__name@dasherize__/__name@dasherize__.html.template +3 -3
  132. package/src/progress-bar/files/__name@dasherize__/__name@dasherize__.ts.template +5 -1
  133. package/src/progress-bar/schema.json +19 -4
  134. package/src/radio-group/files/__name@dasherize__/__name@dasherize__.css.template +4 -31
  135. package/src/radio-group/files/__name@dasherize__/__name@dasherize__.html.template +2 -2
  136. package/src/radio-group/files/__name@dasherize__/__name@dasherize__.ts.template +2 -1
  137. package/src/radio-group/schema.json +19 -4
  138. package/src/rating/files/__name@dasherize__/__name@dasherize__.css.template +17 -0
  139. package/src/rating/files/__name@dasherize__/__name@dasherize__.html.template +34 -0
  140. package/src/rating/files/__name@dasherize__/__name@dasherize__.spec.ts.template +38 -0
  141. package/src/rating/files/__name@dasherize__/__name@dasherize__.ts.template +75 -0
  142. package/src/rating/index.d.ts +1 -0
  143. package/src/rating/index.js +6 -0
  144. package/src/rating/index.js.map +1 -0
  145. package/src/rating/index.ts +3 -0
  146. package/src/rating/schema.d.ts +1 -0
  147. package/src/rating/schema.js +3 -0
  148. package/src/rating/schema.js.map +1 -0
  149. package/src/rating/schema.json +44 -0
  150. package/src/rating/schema.ts +1 -0
  151. package/src/select/files/__name@dasherize__/__name@dasherize__.css.template +4 -55
  152. package/src/select/schema.json +19 -4
  153. package/src/skeleton/files/__name@dasherize__/__name@dasherize__.css.template +2 -29
  154. package/src/skeleton/files/__name@dasherize__/__name@dasherize__.ts.template +1 -3
  155. package/src/skeleton/schema.json +19 -4
  156. package/src/skip-link/files/__name@dasherize__/__name@dasherize__.css.template +2 -14
  157. package/src/skip-link/files/__name@dasherize__/__name@dasherize__.html.template +2 -2
  158. package/src/skip-link/files/__name@dasherize__/__name@dasherize__.ts.template +5 -2
  159. package/src/skip-link/schema.json +19 -4
  160. package/src/slider/files/__name@dasherize__/__name@dasherize__.css.template +6 -20
  161. package/src/slider/files/__name@dasherize__/__name@dasherize__.html.template +2 -2
  162. package/src/slider/files/__name@dasherize__/__name@dasherize__.ts.template +3 -1
  163. package/src/slider/schema.json +19 -4
  164. package/src/spinbutton/files/__name@dasherize__/__name@dasherize__.css.template +6 -35
  165. package/src/spinbutton/files/__name@dasherize__/__name@dasherize__.html.template +4 -4
  166. package/src/spinbutton/files/__name@dasherize__/__name@dasherize__.ts.template +5 -1
  167. package/src/spinbutton/schema.json +19 -4
  168. package/src/spinner/files/__name@dasherize__/__name@dasherize__.css.template +0 -43
  169. package/src/spinner/files/__name@dasherize__/__name@dasherize__.ts.template +2 -5
  170. package/src/spinner/schema.json +19 -4
  171. package/src/steps/files/__name@dasherize__/__name@dasherize__.css.template +36 -0
  172. package/src/steps/files/__name@dasherize__/__name@dasherize__.html.template +44 -0
  173. package/src/steps/files/__name@dasherize__/__name@dasherize__.spec.ts.template +35 -0
  174. package/src/steps/files/__name@dasherize__/__name@dasherize__.ts.template +107 -0
  175. package/src/steps/index.d.ts +1 -0
  176. package/src/steps/index.js +6 -0
  177. package/src/steps/index.js.map +1 -0
  178. package/src/steps/index.ts +3 -0
  179. package/src/steps/schema.d.ts +1 -0
  180. package/src/steps/schema.js +3 -0
  181. package/src/steps/schema.js.map +1 -0
  182. package/src/steps/schema.json +44 -0
  183. package/src/steps/schema.ts +1 -0
  184. package/src/switch/files/__name@dasherize__/__name@dasherize__.css.template +7 -22
  185. package/src/switch/schema.json +19 -4
  186. package/src/table/files/__name@dasherize__/__name@dasherize__.css.template +0 -25
  187. package/src/table/files/__name@dasherize__/__name@dasherize__.html.template +3 -3
  188. package/src/table/files/__name@dasherize__/__name@dasherize__.ts.template +3 -0
  189. package/src/table/schema.json +19 -4
  190. package/src/tabs/files/__name@dasherize__/__name@dasherize__.css.template +5 -44
  191. package/src/tabs/files/__name@dasherize__/__name@dasherize__.html.template +2 -2
  192. package/src/tabs/files/__name@dasherize__/__name@dasherize__.ts.template +2 -0
  193. package/src/tabs/schema.json +19 -4
  194. package/src/textarea/files/__name@dasherize__/__name@dasherize__.css.template +2 -59
  195. package/src/textarea/schema.json +19 -4
  196. package/src/toast/files/__name@dasherize__/__name@dasherize__.css.template +1 -35
  197. package/src/toast/files/__name@dasherize__/__name@dasherize__.html.template +4 -4
  198. package/src/toast/files/__name@dasherize__/__name@dasherize__.ts.template +5 -1
  199. package/src/toast/schema.json +19 -4
  200. package/src/toolbar/files/__name@dasherize__/__name@dasherize__.css.template +2 -36
  201. package/src/toolbar/files/__name@dasherize__/__name@dasherize__.html.template +3 -3
  202. package/src/toolbar/files/__name@dasherize__/__name@dasherize__.ts.template +11 -8
  203. package/src/toolbar/schema.json +19 -4
  204. package/src/tooltip/files/__name@dasherize__/__name@dasherize__.css.template +1 -32
  205. package/src/tooltip/schema.json +19 -4
  206. package/src/tree-view/files/__name@dasherize__/__name@dasherize__.css.template +5 -27
  207. package/src/tree-view/files/__name@dasherize__/__name@dasherize__.html.template +3 -3
  208. package/src/tree-view/files/__name@dasherize__/__name@dasherize__.ts.template +16 -13
  209. package/src/tree-view/schema.json +19 -4
  210. package/src/utils/generate-component.js +3 -1
  211. package/src/utils/generate-component.js.map +1 -1
  212. package/src/utils/generate-component.ts +3 -1
  213. package/src/utils/generate-composition.js +0 -1
  214. package/src/utils/generate-composition.js.map +1 -1
  215. package/src/utils/generate-composition.ts +0 -1
  216. package/src/utils/schema-types.d.ts +1 -0
  217. package/src/utils/schema-types.ts +1 -0
  218. 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 badge 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,133 +1,62 @@
1
1
  :host {
2
- --semmet-color-primary: #18181b;
3
- --semmet-color-on-surface: #18181b;
4
- --semmet-color-on-surface-variant: #52525b;
5
- --semmet-color-accent: #2563eb;
6
- --semmet-space-3xs: 4px;
7
- --semmet-space-2xs: 8px;
8
- --semmet-space-xs: 16px;
9
- --semmet-space-sm: 24px;
10
- --semmet-space-md: 32px;
11
- --semmet-space-lg: 48px;
12
- --semmet-space-xl: 64px;
13
- --semmet-space-2xl: 80px;
14
- --semmet-space-3xl: 120px;
15
-
16
2
  display: block;
17
- color: var(--semmet-color-on-surface);
18
- font-family: Roboto, system-ui, -apple-system, 'Segoe UI', sans-serif;
19
- font-size: 1rem;
20
- line-height: 1.5;
21
3
  }
22
4
 
23
5
  .semmet-block {
24
6
  display: grid;
25
- gap: var(--semmet-space-lg);
26
- max-width: 72rem;
27
- margin-inline: auto;
28
- margin-block: var(--semmet-space-3xl);
29
- }
30
-
31
- .semmet-block--hero {
32
- min-height: 60vh;
33
- align-content: center;
34
- }
35
-
36
- .semmet-block--header {
37
- max-width: none;
38
- margin-block: 0;
39
- }
40
-
41
- .semmet-block--footer {
42
- max-width: none;
43
- margin-block: var(--semmet-space-3xl) 0;
44
7
  }
45
8
 
46
9
  .semmet-block__header {
47
10
  display: grid;
48
- gap: var(--semmet-space-xs);
49
- max-width: 44rem;
50
11
  }
51
12
 
52
13
  .semmet-block__eyebrow {
53
14
  margin: 0;
54
- color: var(--semmet-color-accent);
55
- font-size: 0.8125rem;
56
- font-weight: 700;
57
- letter-spacing: 0;
58
- text-transform: uppercase;
59
15
  }
60
16
 
61
17
  h1,
62
18
  h2 {
63
19
  margin: 0;
64
- color: var(--semmet-color-primary);
65
- font-size: 2.5rem;
66
- line-height: 1.05;
67
- font-weight: 700;
68
20
  }
69
21
 
70
22
  .semmet-block__summary {
71
23
  margin: 0;
72
- color: var(--semmet-color-on-surface-variant);
73
- font-size: 1.125rem;
74
24
  }
75
25
 
76
26
  .semmet-block__grid {
77
27
  display: grid;
78
28
  grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
79
- gap: var(--semmet-space-md);
80
29
  }
81
30
 
82
31
  .semmet-block__stack {
83
32
  display: grid;
84
- gap: var(--semmet-space-sm);
85
33
  }
86
34
 
87
35
  .semmet-block__stats {
88
36
  display: grid;
89
37
  grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
90
- gap: var(--semmet-space-md);
91
38
  margin: 0;
92
39
  }
93
40
 
94
41
  .semmet-block__stats div {
95
42
  display: grid;
96
- gap: var(--semmet-space-2xs);
97
43
  }
98
44
 
99
- .semmet-block__stats dt {
100
- color: var(--semmet-color-primary);
101
- font-size: 2rem;
102
- font-weight: 700;
103
- line-height: 1.1;
45
+ .semmet-block__footer-brand {
46
+ display: grid;
104
47
  }
105
48
 
106
- .semmet-block__stats dd {
107
- color: var(--semmet-color-on-surface-variant);
49
+ .semmet-block__footer-nav {
50
+ display: grid;
51
+ grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
108
52
  }
109
53
 
110
- dd {
54
+ .semmet-block__footer-nav ul {
111
55
  margin: 0;
56
+ padding: 0;
57
+ list-style: none;
112
58
  }
113
59
 
114
- @media (max-width: 48rem) {
115
- .semmet-block {
116
- gap: var(--semmet-space-md);
117
- margin-block: var(--semmet-space-xl);
118
- }
119
-
120
- .semmet-block--header {
121
- margin-block: 0;
122
- }
123
-
124
- .semmet-block--footer {
125
- margin-block: var(--semmet-space-xl) 0;
126
- }
127
-
128
- .semmet-block__grid,
129
- .semmet-block__stack,
130
- .semmet-block__stats {
131
- gap: var(--semmet-space-sm);
132
- }
60
+ dd {
61
+ margin: 0;
133
62
  }
@@ -1,4 +1,5 @@
1
1
  <!-- Semmet Angular: Block / Composition - accessible section scaffold. -->
2
+ <!-- Semmet Angular: starter scaffold. Edit or replace this markup freely; it is generated application code, not a Semmet runtime API. -->
2
3
  <!--
3
4
  Usage from a parent component template:
4
5
  Import <%= classify(name) %> in that parent component.
@@ -23,13 +24,9 @@ Import <%= classify(name) %> in that parent component.
23
24
  </header>
24
25
  <div class="semmet-block__grid">
25
26
  @for (item of items; track item.title) {
26
- <<%= supportSelector %> linkLabel="">
27
- <ng-template <%= camelize(supportName) %>Title>
28
- {{ item.title }}
29
- </ng-template>
30
- <ng-template <%= camelize(supportName) %>Description>
31
- <p>{{ item.text }}</p>
32
- </ng-template>
27
+ <<%= supportSelector %>>
28
+ <h3 <%= camelize(supportName) %>Heading>{{ item.title }}</h3>
29
+ <p>{{ item.text }}</p>
33
30
  </<%= supportSelector %>>
34
31
  }
35
32
  </div>
@@ -95,7 +92,14 @@ Import <%= classify(name) %> in that parent component.
95
92
  <h2 id="<%= dasherize(name) %>-title">{{ title }}</h2>
96
93
  <p class="semmet-block__summary">{{ summary }}</p>
97
94
  </header>
98
- <<%= supportSelector %> />
95
+ <ul <%= camelize(supportName) %> [activeId]="items[0].title" label="<%= classify(kind) %>">
96
+ @for (item of items; track item.title) {
97
+ <li <%= camelize(supportName) %>Item [value]="item.title">
98
+ <h3>{{ item.title }}</h3>
99
+ <p>{{ item.text }}</p>
100
+ </li>
101
+ }
102
+ </ul>
99
103
  </section>
100
104
  <% } else if (kind === 'section-alert') { %>
101
105
  <section class="semmet-block" aria-labelledby="<%= dasherize(name) %>-title">
@@ -144,14 +148,24 @@ Import <%= classify(name) %> in that parent component.
144
148
  </header>
145
149
  <% } else if (kind === 'footer-navigation') { %>
146
150
  <footer class="semmet-block semmet-block--footer">
147
- <<%= supportSelector %>>
148
- <ng-template <%= camelize(supportName) %>Brand>
149
- {{ title }}
150
- </ng-template>
151
- <ng-template <%= camelize(supportName) %>Actions>
152
- <a href="#main-content">Back to content</a>
153
- </ng-template>
154
- </<%= supportSelector %>>
151
+ <div class="semmet-block__footer-brand">
152
+ <p>{{ title }}</p>
153
+ <a href="#main-content">Back to content</a>
154
+ </div>
155
+ <nav class="semmet-block__footer-nav" aria-label="Footer navigation">
156
+ @for (group of footerGroups; track group.title) {
157
+ <section aria-labelledby="<%= dasherize(name) %>-footer-{{ $index }}">
158
+ <h2 id="<%= dasherize(name) %>-footer-{{ $index }}">{{ group.title }}</h2>
159
+ <ul>
160
+ @for (link of group.links; track link.href) {
161
+ <li>
162
+ <a [href]="link.href">{{ link.label }}</a>
163
+ </li>
164
+ }
165
+ </ul>
166
+ </section>
167
+ }
168
+ </nav>
155
169
  </footer>
156
170
  <% } else if (kind === 'section-pricing') { %>
157
171
  <section class="semmet-block" aria-labelledby="<%= dasherize(name) %>-title">
@@ -163,15 +177,9 @@ Import <%= classify(name) %> in that parent component.
163
177
  <div class="semmet-block__grid">
164
178
  @for (item of items; track item.title) {
165
179
  <<%= supportSelector %>>
166
- <ng-template <%= camelize(supportName) %>Title>
167
- {{ item.title }}
168
- </ng-template>
169
- <ng-template <%= camelize(supportName) %>Description>
170
- <p>{{ item.text }}</p>
171
- </ng-template>
172
- <ng-template <%= camelize(supportName) %>Actions>
173
- <a href="/contact">Choose plan</a>
174
- </ng-template>
180
+ <h3 <%= camelize(supportName) %>Heading>{{ item.title }}</h3>
181
+ <p>{{ item.text }}</p>
182
+ <a href="/contact">Choose plan</a>
175
183
  </<%= supportSelector %>>
176
184
  }
177
185
  </div>
@@ -1,11 +1,6 @@
1
1
  import { Component } from '@angular/core';
2
2
  <% if (usesSupportingComponent) { %><% if (supportVariable === 'card') { %>import {
3
3
  <%= classify(supportName) %>,
4
- <% if (usesCardActions) { %>
5
- <%= classify(supportName) %>Actions,
6
- <% } %>
7
- <%= classify(supportName) %>Description,
8
- <%= classify(supportName) %>Title,
9
4
  } from './<%= dasherize(supportName) %>/<%= dasherize(supportName) %>';
10
5
  <% } else if (supportVariable === 'accordion') { %>import {
11
6
  <%= classify(supportName) %>,
@@ -28,6 +23,10 @@ import { Component } from '@angular/core';
28
23
  <%= classify(supportName) %>,
29
24
  <%= classify(supportName) %>Slide,
30
25
  } from './<%= dasherize(supportName) %>/<%= dasherize(supportName) %>';
26
+ <% } else if (supportVariable === 'listGroup') { %>import {
27
+ <%= classify(supportName) %>,
28
+ <%= classify(supportName) %>Item,
29
+ } from './<%= dasherize(supportName) %>/<%= dasherize(supportName) %>';
31
30
  <% } else { %>import { <%= classify(supportName) %> } from './<%= dasherize(supportName) %>/<%= dasherize(supportName) %>';
32
31
  <% } %><% } %>
33
32
 
@@ -36,16 +35,19 @@ interface <%= classify(name) %>Item {
36
35
  text: string;
37
36
  }
38
37
 
38
+ interface <%= classify(name) %>FooterGroup {
39
+ title: string;
40
+ links: readonly {
41
+ label: string;
42
+ href: string;
43
+ }[];
44
+ }
45
+
39
46
  @Component({
40
47
  selector: '<%= selector %>',
41
48
  imports: [<% if (usesSupportingComponent) { %>
42
49
  <%= classify(supportName) %>,
43
50
  <% if (supportVariable === 'card') { %>
44
- <% if (usesCardActions) { %>
45
- <%= classify(supportName) %>Actions,
46
- <% } %>
47
- <%= classify(supportName) %>Description,
48
- <%= classify(supportName) %>Title,
49
51
  <% } else if (supportVariable === 'accordion') { %>
50
52
  <%= classify(supportName) %>Item,
51
53
  <% } else if (supportVariable === 'table') { %>
@@ -57,6 +59,8 @@ interface <%= classify(name) %>Item {
57
59
  <%= classify(supportName) %>Item,
58
60
  <% } else if (supportVariable === 'carousel') { %>
59
61
  <%= classify(supportName) %>Slide,
62
+ <% } else if (supportVariable === 'listGroup') { %>
63
+ <%= classify(supportName) %>Item,
60
64
  <% } %>
61
65
  <% } %>],
62
66
  templateUrl: './<%= dasherize(name) %>.html',
@@ -83,4 +87,31 @@ export class <%= classify(name) %> {
83
87
  text: 'Replace placeholder content with product components, inputs, outputs, and signals.',
84
88
  },
85
89
  ];
90
+
91
+ protected readonly footerGroups: readonly <%= classify(name) %>FooterGroup[] = [
92
+ {
93
+ title: 'Product',
94
+ links: [
95
+ { label: 'Overview', href: '/product' },
96
+ { label: 'Accessibility', href: '/accessibility' },
97
+ { label: 'Pricing', href: '/pricing' },
98
+ ],
99
+ },
100
+ {
101
+ title: 'Resources',
102
+ links: [
103
+ { label: 'Docs', href: '/docs' },
104
+ { label: 'Guides', href: '/guides' },
105
+ { label: 'Changelog', href: '/changelog' },
106
+ ],
107
+ },
108
+ {
109
+ title: 'Company',
110
+ links: [
111
+ { label: 'About', href: '/about' },
112
+ { label: 'Contact', href: '/contact' },
113
+ { label: 'Privacy', href: '/privacy' },
114
+ ],
115
+ },
116
+ ];
86
117
  }
@@ -9,9 +9,17 @@
9
9
  "name": {
10
10
  "type": "string",
11
11
  "description": "The name for the new block 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 block 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
  "kind": {
16
24
  "type": "string",
17
25
  "description": "The composition block pattern to generate. Defaults to the positional name when it matches a known block kind.",
@@ -37,15 +45,22 @@
37
45
  "path": {
38
46
  "type": "string",
39
47
  "format": "path",
40
- "$default": { "$source": "workingDirectory" },
48
+ "$default": {
49
+ "$source": "workingDirectory"
50
+ },
41
51
  "description": "The path where the block files should be created, relative to the workspace root. Defaults to the project's source root.",
42
52
  "visible": false
43
53
  },
44
54
  "project": {
45
55
  "type": "string",
46
56
  "description": "The name of the project to add the block to.",
47
- "$default": { "$source": "projectName" }
57
+ "$default": {
58
+ "$source": "projectName"
59
+ }
48
60
  }
49
61
  },
50
- "required": ["name", "project"]
62
+ "required": [
63
+ "name",
64
+ "project"
65
+ ]
51
66
  }
@@ -1,20 +1,11 @@
1
1
  :host {
2
- --semmet-color-primary: #18181b;
3
- --semmet-color-on-surface: #18181b;
4
- --semmet-color-on-surface-variant: #52525b;
5
- --semmet-space-2xs: 8px;
6
- --semmet-motion: 160ms cubic-bezier(0.2, 0, 0, 1);
7
-
8
2
  display: block;
9
- font-family: Roboto, system-ui, -apple-system, 'Segoe UI', sans-serif;
10
- font-size: 0.9375rem;
11
3
  }
12
4
 
13
5
  ol {
14
6
  display: flex;
15
7
  flex-wrap: wrap;
16
8
  align-items: center;
17
- gap: var(--semmet-space-2xs);
18
9
  margin: 0;
19
10
  padding: 0;
20
11
  list-style: none;
@@ -23,8 +14,6 @@ ol {
23
14
  li {
24
15
  display: flex;
25
16
  align-items: center;
26
- gap: var(--semmet-space-2xs);
27
- color: var(--semmet-color-on-surface-variant);
28
17
  }
29
18
 
30
19
  li:not(:last-child)::after {
@@ -33,21 +22,11 @@ li:not(:last-child)::after {
33
22
  }
34
23
 
35
24
  a {
36
- color: var(--semmet-color-primary);
25
+ color: inherit;
37
26
  text-decoration: none;
38
- border-radius: 4px;
39
- }
40
-
41
- a:hover {
42
- text-decoration: underline;
43
27
  }
44
28
 
45
29
  a:focus-visible {
46
- outline: 2px solid var(--semmet-color-primary);
30
+ outline: 2px solid currentColor;
47
31
  outline-offset: 2px;
48
32
  }
49
-
50
- li[aria-current='page'] {
51
- color: var(--semmet-color-on-surface);
52
- font-weight: 500;
53
- }
@@ -3,13 +3,13 @@
3
3
  Usage from a parent component template:
4
4
  Import <%= classify(name) %> in that parent component.
5
5
 
6
- <<%= selector %> />
6
+ <<%= selector %> label="Breadcrumb" currentPageLabel="Current page" [items]="breadcrumbItems" />
7
7
  -->
8
- <nav aria-label="Breadcrumb">
8
+ <nav [attr.aria-label]="label()">
9
9
  <ol>
10
- @for (item of items; track item.id) {
10
+ @for (item of items(); track item.id) {
11
11
  <li><a [href]="item.href">{{ item.label }}</a></li>
12
12
  }
13
- <li aria-current="page">Current page</li>
13
+ <li aria-current="page">{{ currentPageLabel() }}</li>
14
14
  </ol>
15
15
  </nav>
@@ -1,4 +1,4 @@
1
- import { Component } from '@angular/core';
1
+ import { Component, input } from '@angular/core';
2
2
 
3
3
  interface <%= classify(name) %>Item {
4
4
  id: number;
@@ -6,6 +6,11 @@ interface <%= classify(name) %>Item {
6
6
  href: string;
7
7
  }
8
8
 
9
+ const DEFAULT_ITEMS: readonly <%= classify(name) %>Item[] = [
10
+ { id: 1, label: 'Home', href: '/' },
11
+ { id: 2, label: 'Category', href: '/category' },
12
+ ];
13
+
9
14
  @Component({
10
15
  selector: '<%= selector %>',
11
16
  imports: [],
@@ -13,8 +18,7 @@ interface <%= classify(name) %>Item {
13
18
  styleUrl: './<%= dasherize(name) %>.css',
14
19
  })
15
20
  export class <%= classify(name) %> {
16
- protected readonly items: <%= classify(name) %>Item[] = [
17
- { id: 1, label: 'Home', href: '/' },
18
- { id: 2, label: 'Category', href: '/category' },
19
- ];
21
+ readonly label = input('Breadcrumb');
22
+ readonly currentPageLabel = input('Current page');
23
+ readonly items = input<readonly <%= classify(name) %>Item[]>(DEFAULT_ITEMS);
20
24
  }
@@ -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 breadcrumb 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,93 +1,16 @@
1
1
  :host {
2
- --semmet-color-primary: #18181b;
3
- --semmet-color-on-primary: #ffffff;
4
- --semmet-color-danger: #b42318;
5
- --semmet-color-on-danger: #ffffff;
6
- --semmet-color-surface: #ffffff;
7
- --semmet-color-outline: #d4d4d8;
8
- --semmet-color-on-surface: #18181b;
9
- --semmet-color-on-surface-variant: #52525b;
10
- --semmet-radius-sm: 8px;
11
- --semmet-space-2xs: 8px;
12
- --semmet-space-xs: 16px;
13
- --semmet-space-sm: 24px;
14
- --semmet-target-sm: 32px;
15
- --semmet-target-md: 40px;
16
- --semmet-target-lg: 48px;
17
- --semmet-motion: 160ms cubic-bezier(0.2, 0, 0, 1);
18
-
19
2
  display: inline-block;
20
- font-family: Roboto, system-ui, -apple-system, 'Segoe UI', sans-serif;
21
- font-size: 0.9375rem;
22
3
  }
23
4
 
24
5
  .semmet-button {
25
6
  display: inline-flex;
26
7
  align-items: center;
27
8
  justify-content: center;
28
- gap: var(--semmet-space-2xs);
29
- min-width: 2.75rem;
30
- border: 1px solid transparent;
31
- border-radius: var(--semmet-radius-sm);
9
+ gap: 0.5em;
32
10
  font: inherit;
33
- font-weight: 600;
34
- line-height: 1.2;
35
11
  text-decoration: none;
36
- white-space: nowrap;
37
12
  cursor: pointer;
38
13
  user-select: none;
39
- transition:
40
- background-color var(--semmet-motion),
41
- border-color var(--semmet-motion),
42
- color var(--semmet-motion),
43
- transform var(--semmet-motion);
44
- }
45
-
46
- .semmet-button--sm {
47
- min-height: var(--semmet-target-sm);
48
- padding: var(--semmet-space-2xs) var(--semmet-space-xs);
49
- font-size: 0.875rem;
50
- }
51
-
52
- .semmet-button--md {
53
- min-height: var(--semmet-target-md);
54
- padding: var(--semmet-space-2xs) var(--semmet-space-xs);
55
- }
56
-
57
- .semmet-button--lg {
58
- min-height: var(--semmet-target-lg);
59
- padding: var(--semmet-space-xs) var(--semmet-space-sm);
60
- font-size: 1rem;
61
- }
62
-
63
- .semmet-button--primary {
64
- color: var(--semmet-color-on-primary);
65
- background: var(--semmet-color-primary);
66
- }
67
-
68
- .semmet-button--secondary {
69
- color: var(--semmet-color-on-surface);
70
- background: var(--semmet-color-surface);
71
- border-color: var(--semmet-color-outline);
72
- }
73
-
74
- .semmet-button--danger {
75
- color: var(--semmet-color-on-danger);
76
- background: var(--semmet-color-danger);
77
- }
78
-
79
- .semmet-button--ghost {
80
- color: var(--semmet-color-on-surface);
81
- background: transparent;
82
- border-color: transparent;
83
- }
84
-
85
- .semmet-button:hover:not(:disabled) {
86
- transform: translateY(-1px);
87
- }
88
-
89
- .semmet-button:active:not(:disabled) {
90
- transform: translateY(0);
91
14
  }
92
15
 
93
16
  .semmet-button:disabled {
@@ -96,7 +19,7 @@
96
19
  }
97
20
 
98
21
  .semmet-button:focus-visible {
99
- outline: 2px solid var(--semmet-color-primary);
22
+ outline: 2px solid currentColor;
100
23
  outline-offset: 2px;
101
24
  }
102
25
 
@@ -1,9 +1,6 @@
1
1
  import { NgTemplateOutlet } from '@angular/common';
2
2
  import { Component, Directive, TemplateRef, computed, contentChild, inject, input, output } from '@angular/core';
3
3
 
4
- type <%= classify(name) %>Variant = 'primary' | 'secondary' | 'danger' | 'ghost';
5
- type <%= classify(name) %>Size = 'sm' | 'md' | 'lg';
6
-
7
4
  let nextId = 0;
8
5
 
9
6
  @Directive({
@@ -40,8 +37,8 @@ export class <%= classify(name) %> {
40
37
  protected readonly instanceId = `<%= dasherize(name) %>-${nextId++}`;
41
38
 
42
39
  readonly label = input('Continue');
43
- readonly variant = input<<%= classify(name) %>Variant>('primary');
44
- readonly size = input<<%= classify(name) %>Size>('md');
40
+ readonly variant = input<string>('primary');
41
+ readonly size = input<string>('md');
45
42
  readonly disabled = input(false);
46
43
  readonly busy = input(false);
47
44
  readonly pressed = input<boolean | null>(null);