semmet-angular 0.4.0 → 0.6.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 (284) hide show
  1. package/README.md +43 -3
  2. package/package.json +1 -1
  3. package/src/accordion/files/__name@dasherize__/__name@dasherize__.css.template +4 -4
  4. package/src/alert/files/__name@dasherize__/__name@dasherize__.css.template +43 -0
  5. package/src/alert/files/__name@dasherize__/__name@dasherize__.html.template +7 -0
  6. package/src/alert/files/__name@dasherize__/__name@dasherize__.ts.template +18 -0
  7. package/src/alert/index.d.ts +1 -0
  8. package/src/alert/index.js +6 -0
  9. package/src/alert/index.js.map +1 -0
  10. package/src/alert/index.ts +3 -0
  11. package/src/alert/schema.d.ts +1 -0
  12. package/src/alert/schema.js +3 -0
  13. package/src/alert/schema.js.map +1 -0
  14. package/src/alert/schema.json +29 -0
  15. package/src/alert/schema.ts +1 -0
  16. package/src/alert-dialog/files/__name@dasherize__/__name@dasherize__.css.template +82 -0
  17. package/src/alert-dialog/files/__name@dasherize__/__name@dasherize__.html.template +20 -0
  18. package/src/alert-dialog/files/__name@dasherize__/__name@dasherize__.ts.template +75 -0
  19. package/src/alert-dialog/index.d.ts +1 -0
  20. package/src/alert-dialog/index.js +6 -0
  21. package/src/alert-dialog/index.js.map +1 -0
  22. package/src/alert-dialog/index.ts +3 -0
  23. package/src/alert-dialog/schema.d.ts +1 -0
  24. package/src/alert-dialog/schema.js +3 -0
  25. package/src/alert-dialog/schema.js.map +1 -0
  26. package/src/alert-dialog/schema.json +29 -0
  27. package/src/alert-dialog/schema.ts +1 -0
  28. package/src/breadcrumb/files/__name@dasherize__/__name@dasherize__.css.template +52 -0
  29. package/src/breadcrumb/files/__name@dasherize__/__name@dasherize__.html.template +9 -0
  30. package/src/breadcrumb/files/__name@dasherize__/__name@dasherize__.ts.template +20 -0
  31. package/src/breadcrumb/index.d.ts +1 -0
  32. package/src/breadcrumb/index.js +6 -0
  33. package/src/breadcrumb/index.js.map +1 -0
  34. package/src/breadcrumb/index.ts +3 -0
  35. package/src/breadcrumb/schema.d.ts +1 -0
  36. package/src/breadcrumb/schema.js +3 -0
  37. package/src/breadcrumb/schema.js.map +1 -0
  38. package/src/breadcrumb/schema.json +29 -0
  39. package/src/breadcrumb/schema.ts +1 -0
  40. package/src/card/files/__name@dasherize__/__name@dasherize__.css.template +49 -0
  41. package/src/card/files/__name@dasherize__/__name@dasherize__.html.template +6 -0
  42. package/src/card/files/__name@dasherize__/__name@dasherize__.ts.template +13 -0
  43. package/src/card/index.d.ts +1 -0
  44. package/src/card/index.js +6 -0
  45. package/src/card/index.js.map +1 -0
  46. package/src/card/index.ts +3 -0
  47. package/src/card/schema.d.ts +1 -0
  48. package/src/card/schema.js +3 -0
  49. package/src/card/schema.js.map +1 -0
  50. package/src/card/schema.json +29 -0
  51. package/src/card/schema.ts +1 -0
  52. package/src/carousel/files/__name@dasherize__/__name@dasherize__.css.template +58 -0
  53. package/src/carousel/files/__name@dasherize__/__name@dasherize__.html.template +10 -0
  54. package/src/carousel/files/__name@dasherize__/__name@dasherize__.ts.template +35 -0
  55. package/src/carousel/index.d.ts +1 -0
  56. package/src/carousel/index.js +6 -0
  57. package/src/carousel/index.js.map +1 -0
  58. package/src/carousel/index.ts +3 -0
  59. package/src/carousel/schema.d.ts +1 -0
  60. package/src/carousel/schema.js +3 -0
  61. package/src/carousel/schema.js.map +1 -0
  62. package/src/carousel/schema.json +29 -0
  63. package/src/carousel/schema.ts +1 -0
  64. package/src/checkbox/files/__name@dasherize__/__name@dasherize__.css.template +62 -0
  65. package/src/checkbox/files/__name@dasherize__/__name@dasherize__.html.template +11 -0
  66. package/src/checkbox/files/__name@dasherize__/__name@dasherize__.ts.template +25 -0
  67. package/src/checkbox/index.d.ts +1 -0
  68. package/src/checkbox/index.js +6 -0
  69. package/src/checkbox/index.js.map +1 -0
  70. package/src/checkbox/index.ts +3 -0
  71. package/src/checkbox/schema.d.ts +1 -0
  72. package/src/checkbox/schema.js +3 -0
  73. package/src/checkbox/schema.js.map +1 -0
  74. package/src/checkbox/schema.json +29 -0
  75. package/src/checkbox/schema.ts +1 -0
  76. package/src/collection.json +115 -0
  77. package/src/combobox/files/__name@dasherize__/__name@dasherize__.css.template +75 -0
  78. package/src/combobox/files/__name@dasherize__/__name@dasherize__.html.template +33 -0
  79. package/src/combobox/files/__name@dasherize__/__name@dasherize__.ts.template +93 -0
  80. package/src/combobox/index.d.ts +1 -0
  81. package/src/combobox/index.js +6 -0
  82. package/src/combobox/index.js.map +1 -0
  83. package/src/combobox/index.ts +3 -0
  84. package/src/combobox/schema.d.ts +1 -0
  85. package/src/combobox/schema.js +3 -0
  86. package/src/combobox/schema.js.map +1 -0
  87. package/src/combobox/schema.json +29 -0
  88. package/src/combobox/schema.ts +1 -0
  89. package/src/dialog/files/__name@dasherize__/__name@dasherize__.css.template +3 -3
  90. package/src/disclosure/files/__name@dasherize__/__name@dasherize__.css.template +4 -4
  91. package/src/landmarks/files/__name@dasherize__/__name@dasherize__.css.template +61 -0
  92. package/src/landmarks/files/__name@dasherize__/__name@dasherize__.html.template +17 -0
  93. package/src/landmarks/files/__name@dasherize__/__name@dasherize__.ts.template +9 -0
  94. package/src/landmarks/index.d.ts +1 -0
  95. package/src/landmarks/index.js +6 -0
  96. package/src/landmarks/index.js.map +1 -0
  97. package/src/landmarks/index.ts +3 -0
  98. package/src/landmarks/schema.d.ts +1 -0
  99. package/src/landmarks/schema.js +3 -0
  100. package/src/landmarks/schema.js.map +1 -0
  101. package/src/landmarks/schema.json +29 -0
  102. package/src/landmarks/schema.ts +1 -0
  103. package/src/listbox/files/__name@dasherize__/__name@dasherize__.css.template +52 -0
  104. package/src/listbox/files/__name@dasherize__/__name@dasherize__.html.template +20 -0
  105. package/src/listbox/files/__name@dasherize__/__name@dasherize__.ts.template +54 -0
  106. package/src/listbox/index.d.ts +1 -0
  107. package/src/listbox/index.js +6 -0
  108. package/src/listbox/index.js.map +1 -0
  109. package/src/listbox/index.ts +3 -0
  110. package/src/listbox/schema.d.ts +1 -0
  111. package/src/listbox/schema.js +3 -0
  112. package/src/listbox/schema.js.map +1 -0
  113. package/src/listbox/schema.json +29 -0
  114. package/src/listbox/schema.ts +1 -0
  115. package/src/menu-button/files/__name@dasherize__/__name@dasherize__.css.template +82 -0
  116. package/src/menu-button/files/__name@dasherize__/__name@dasherize__.html.template +34 -0
  117. package/src/menu-button/files/__name@dasherize__/__name@dasherize__.ts.template +104 -0
  118. package/src/menu-button/index.d.ts +1 -0
  119. package/src/menu-button/index.js +6 -0
  120. package/src/menu-button/index.js.map +1 -0
  121. package/src/menu-button/index.ts +3 -0
  122. package/src/menu-button/schema.d.ts +1 -0
  123. package/src/menu-button/schema.js +3 -0
  124. package/src/menu-button/schema.js.map +1 -0
  125. package/src/menu-button/schema.json +29 -0
  126. package/src/menu-button/schema.ts +1 -0
  127. package/src/meter/files/__name@dasherize__/__name@dasherize__.css.template +22 -0
  128. package/src/meter/files/__name@dasherize__/__name@dasherize__.html.template +5 -0
  129. package/src/meter/files/__name@dasherize__/__name@dasherize__.ts.template +14 -0
  130. package/src/meter/index.d.ts +1 -0
  131. package/src/meter/index.js +6 -0
  132. package/src/meter/index.js.map +1 -0
  133. package/src/meter/index.ts +3 -0
  134. package/src/meter/schema.d.ts +1 -0
  135. package/src/meter/schema.js +3 -0
  136. package/src/meter/schema.js.map +1 -0
  137. package/src/meter/schema.json +29 -0
  138. package/src/meter/schema.ts +1 -0
  139. package/src/navigation-menu/files/__name@dasherize__/__name@dasherize__.css.template +88 -0
  140. package/src/navigation-menu/files/__name@dasherize__/__name@dasherize__.html.template +22 -0
  141. package/src/navigation-menu/files/__name@dasherize__/__name@dasherize__.ts.template +18 -0
  142. package/src/navigation-menu/index.d.ts +1 -0
  143. package/src/navigation-menu/index.js +6 -0
  144. package/src/navigation-menu/index.js.map +1 -0
  145. package/src/navigation-menu/index.ts +3 -0
  146. package/src/navigation-menu/schema.d.ts +1 -0
  147. package/src/navigation-menu/schema.js +3 -0
  148. package/src/navigation-menu/schema.js.map +1 -0
  149. package/src/navigation-menu/schema.json +29 -0
  150. package/src/navigation-menu/schema.ts +1 -0
  151. package/src/pagination/files/__name@dasherize__/__name@dasherize__.css.template +63 -0
  152. package/src/pagination/files/__name@dasherize__/__name@dasherize__.html.template +26 -0
  153. package/src/pagination/files/__name@dasherize__/__name@dasherize__.ts.template +31 -0
  154. package/src/pagination/index.d.ts +1 -0
  155. package/src/pagination/index.js +6 -0
  156. package/src/pagination/index.js.map +1 -0
  157. package/src/pagination/index.ts +3 -0
  158. package/src/pagination/schema.d.ts +1 -0
  159. package/src/pagination/schema.js +3 -0
  160. package/src/pagination/schema.js.map +1 -0
  161. package/src/pagination/schema.json +29 -0
  162. package/src/pagination/schema.ts +1 -0
  163. package/src/progress-bar/files/__name@dasherize__/__name@dasherize__.css.template +53 -0
  164. package/src/progress-bar/files/__name@dasherize__/__name@dasherize__.html.template +6 -0
  165. package/src/progress-bar/files/__name@dasherize__/__name@dasherize__.ts.template +19 -0
  166. package/src/progress-bar/index.d.ts +1 -0
  167. package/src/progress-bar/index.js +6 -0
  168. package/src/progress-bar/index.js.map +1 -0
  169. package/src/progress-bar/index.ts +3 -0
  170. package/src/progress-bar/schema.d.ts +1 -0
  171. package/src/progress-bar/schema.js +3 -0
  172. package/src/progress-bar/schema.js.map +1 -0
  173. package/src/progress-bar/schema.json +29 -0
  174. package/src/progress-bar/schema.ts +1 -0
  175. package/src/radio-group/files/__name@dasherize__/__name@dasherize__.css.template +66 -0
  176. package/src/radio-group/files/__name@dasherize__/__name@dasherize__.html.template +16 -0
  177. package/src/radio-group/files/__name@dasherize__/__name@dasherize__.ts.template +62 -0
  178. package/src/radio-group/index.d.ts +1 -0
  179. package/src/radio-group/index.js +6 -0
  180. package/src/radio-group/index.js.map +1 -0
  181. package/src/radio-group/index.ts +3 -0
  182. package/src/radio-group/schema.d.ts +1 -0
  183. package/src/radio-group/schema.js +3 -0
  184. package/src/radio-group/schema.js.map +1 -0
  185. package/src/radio-group/schema.json +29 -0
  186. package/src/radio-group/schema.ts +1 -0
  187. package/src/skip-link/files/__name@dasherize__/__name@dasherize__.css.template +30 -0
  188. package/src/skip-link/files/__name@dasherize__/__name@dasherize__.html.template +3 -0
  189. package/src/skip-link/files/__name@dasherize__/__name@dasherize__.ts.template +9 -0
  190. package/src/skip-link/index.d.ts +1 -0
  191. package/src/skip-link/index.js +6 -0
  192. package/src/skip-link/index.js.map +1 -0
  193. package/src/skip-link/index.ts +3 -0
  194. package/src/skip-link/schema.d.ts +1 -0
  195. package/src/skip-link/schema.js +3 -0
  196. package/src/skip-link/schema.js.map +1 -0
  197. package/src/skip-link/schema.json +29 -0
  198. package/src/skip-link/schema.ts +1 -0
  199. package/src/slider/files/__name@dasherize__/__name@dasherize__.css.template +54 -0
  200. package/src/slider/files/__name@dasherize__/__name@dasherize__.html.template +16 -0
  201. package/src/slider/files/__name@dasherize__/__name@dasherize__.ts.template +79 -0
  202. package/src/slider/index.d.ts +1 -0
  203. package/src/slider/index.js +6 -0
  204. package/src/slider/index.js.map +1 -0
  205. package/src/slider/index.ts +3 -0
  206. package/src/slider/schema.d.ts +1 -0
  207. package/src/slider/schema.js +3 -0
  208. package/src/slider/schema.js.map +1 -0
  209. package/src/slider/schema.json +29 -0
  210. package/src/slider/schema.ts +1 -0
  211. package/src/spinbutton/files/__name@dasherize__/__name@dasherize__.css.template +64 -0
  212. package/src/spinbutton/files/__name@dasherize__/__name@dasherize__.html.template +19 -0
  213. package/src/spinbutton/files/__name@dasherize__/__name@dasherize__.ts.template +59 -0
  214. package/src/spinbutton/index.d.ts +1 -0
  215. package/src/spinbutton/index.js +6 -0
  216. package/src/spinbutton/index.js.map +1 -0
  217. package/src/spinbutton/index.ts +3 -0
  218. package/src/spinbutton/schema.d.ts +1 -0
  219. package/src/spinbutton/schema.js +3 -0
  220. package/src/spinbutton/schema.js.map +1 -0
  221. package/src/spinbutton/schema.json +29 -0
  222. package/src/spinbutton/schema.ts +1 -0
  223. package/src/switch/files/__name@dasherize__/__name@dasherize__.css.template +68 -0
  224. package/src/switch/files/__name@dasherize__/__name@dasherize__.html.template +4 -0
  225. package/src/switch/files/__name@dasherize__/__name@dasherize__.ts.template +18 -0
  226. package/src/switch/index.d.ts +1 -0
  227. package/src/switch/index.js +6 -0
  228. package/src/switch/index.js.map +1 -0
  229. package/src/switch/index.ts +3 -0
  230. package/src/switch/schema.d.ts +1 -0
  231. package/src/switch/schema.js +3 -0
  232. package/src/switch/schema.js.map +1 -0
  233. package/src/switch/schema.json +29 -0
  234. package/src/switch/schema.ts +1 -0
  235. package/src/table/files/__name@dasherize__/__name@dasherize__.css.template +40 -0
  236. package/src/table/files/__name@dasherize__/__name@dasherize__.html.template +18 -0
  237. package/src/table/files/__name@dasherize__/__name@dasherize__.ts.template +19 -0
  238. package/src/table/index.d.ts +1 -0
  239. package/src/table/index.js +6 -0
  240. package/src/table/index.js.map +1 -0
  241. package/src/table/index.ts +3 -0
  242. package/src/table/schema.d.ts +1 -0
  243. package/src/table/schema.js +3 -0
  244. package/src/table/schema.js.map +1 -0
  245. package/src/table/schema.json +29 -0
  246. package/src/table/schema.ts +1 -0
  247. package/src/tabs/files/__name@dasherize__/__name@dasherize__.css.template +4 -4
  248. package/src/toast/files/__name@dasherize__/__name@dasherize__.css.template +56 -0
  249. package/src/toast/files/__name@dasherize__/__name@dasherize__.html.template +9 -0
  250. package/src/toast/files/__name@dasherize__/__name@dasherize__.ts.template +33 -0
  251. package/src/toast/index.d.ts +1 -0
  252. package/src/toast/index.js +6 -0
  253. package/src/toast/index.js.map +1 -0
  254. package/src/toast/index.ts +3 -0
  255. package/src/toast/schema.d.ts +1 -0
  256. package/src/toast/schema.js +3 -0
  257. package/src/toast/schema.js.map +1 -0
  258. package/src/toast/schema.json +29 -0
  259. package/src/toast/schema.ts +1 -0
  260. package/src/toolbar/files/__name@dasherize__/__name@dasherize__.css.template +48 -0
  261. package/src/toolbar/files/__name@dasherize__/__name@dasherize__.html.template +15 -0
  262. package/src/toolbar/files/__name@dasherize__/__name@dasherize__.ts.template +71 -0
  263. package/src/toolbar/index.d.ts +1 -0
  264. package/src/toolbar/index.js +6 -0
  265. package/src/toolbar/index.js.map +1 -0
  266. package/src/toolbar/index.ts +3 -0
  267. package/src/toolbar/schema.d.ts +1 -0
  268. package/src/toolbar/schema.js +3 -0
  269. package/src/toolbar/schema.js.map +1 -0
  270. package/src/toolbar/schema.json +29 -0
  271. package/src/toolbar/schema.ts +1 -0
  272. package/src/tooltip/files/__name@dasherize__/__name@dasherize__.css.template +2 -2
  273. package/src/tree-view/files/__name@dasherize__/__name@dasherize__.css.template +57 -0
  274. package/src/tree-view/files/__name@dasherize__/__name@dasherize__.html.template +30 -0
  275. package/src/tree-view/files/__name@dasherize__/__name@dasherize__.ts.template +140 -0
  276. package/src/tree-view/index.d.ts +1 -0
  277. package/src/tree-view/index.js +6 -0
  278. package/src/tree-view/index.js.map +1 -0
  279. package/src/tree-view/index.ts +3 -0
  280. package/src/tree-view/schema.d.ts +1 -0
  281. package/src/tree-view/schema.js +3 -0
  282. package/src/tree-view/schema.js.map +1 -0
  283. package/src/tree-view/schema.json +29 -0
  284. package/src/tree-view/schema.ts +1 -0
@@ -0,0 +1,75 @@
1
+ :host {
2
+ --semmet-color-primary: #18181b;
3
+ --semmet-color-surface: #ffffff;
4
+ --semmet-color-outline: #d4d4d8;
5
+ --semmet-color-on-surface: #18181b;
6
+ --semmet-color-on-surface-variant: #52525b;
7
+ --semmet-radius-sm: 8px;
8
+ --semmet-radius-md: 12px;
9
+ --semmet-elevation-3: 0 8px 24px rgba(20, 24, 23, 0.18), 0 2px 8px rgba(20, 24, 23, 0.1);
10
+ --semmet-motion: 160ms cubic-bezier(0.2, 0, 0, 1);
11
+
12
+ position: relative;
13
+ display: inline-block;
14
+ font-family: Roboto, system-ui, -apple-system, 'Segoe UI', sans-serif;
15
+ font-size: 0.9375rem;
16
+ }
17
+
18
+ label {
19
+ display: block;
20
+ margin-bottom: 0.375rem;
21
+ font-weight: 500;
22
+ color: var(--semmet-color-on-surface);
23
+ }
24
+
25
+ input {
26
+ width: 100%;
27
+ min-width: 14rem;
28
+ font: inherit;
29
+ color: var(--semmet-color-on-surface);
30
+ background: var(--semmet-color-surface);
31
+ border: 1px solid var(--semmet-color-outline);
32
+ border-radius: var(--semmet-radius-sm);
33
+ padding: 0.5rem 0.75rem;
34
+ box-sizing: border-box;
35
+ transition: border-color var(--semmet-motion);
36
+ }
37
+
38
+ input:focus-visible {
39
+ outline: 2px solid var(--semmet-color-primary);
40
+ outline-offset: 1px;
41
+ border-color: var(--semmet-color-primary);
42
+ }
43
+
44
+ ul {
45
+ position: absolute;
46
+ z-index: 1;
47
+ top: 100%;
48
+ left: 0;
49
+ right: 0;
50
+ margin: 0.25rem 0 0;
51
+ padding: 0.375rem;
52
+ list-style: none;
53
+ background: var(--semmet-color-surface);
54
+ border-radius: var(--semmet-radius-md);
55
+ box-shadow: var(--semmet-elevation-3);
56
+ max-height: 12rem;
57
+ overflow-y: auto;
58
+ }
59
+
60
+ [role='option'] {
61
+ padding: 0.5rem 0.75rem;
62
+ border-radius: 6px;
63
+ color: var(--semmet-color-on-surface);
64
+ cursor: pointer;
65
+ transition: background-color var(--semmet-motion);
66
+ }
67
+
68
+ [role='option'][aria-selected='true'] {
69
+ background: color-mix(in srgb, var(--semmet-color-primary) 12%, transparent);
70
+ color: var(--semmet-color-primary);
71
+ }
72
+
73
+ [role='option']:hover {
74
+ background: color-mix(in srgb, var(--semmet-color-on-surface) 6%, transparent);
75
+ }
@@ -0,0 +1,33 @@
1
+ <!-- Semmet Angular: Combobox — https://www.w3.org/WAI/ARIA/apg/patterns/combobox/ -->
2
+ <label [id]="instanceId + '-label'" [for]="instanceId + '-input'">Choose a fruit</label>
3
+ <input
4
+ type="text"
5
+ [id]="instanceId + '-input'"
6
+ role="combobox"
7
+ [attr.aria-expanded]="isOpen()"
8
+ [attr.aria-controls]="instanceId + '-listbox'"
9
+ aria-autocomplete="list"
10
+ [attr.aria-activedescendant]="activeDescendantId()"
11
+ [attr.aria-labelledby]="instanceId + '-label'"
12
+ [value]="query()"
13
+ (input)="onInput($event)"
14
+ (keydown)="handleInputKeydown($event)"
15
+ (focus)="openList()"
16
+ />
17
+ <ul
18
+ role="listbox"
19
+ [id]="instanceId + '-listbox'"
20
+ [attr.aria-labelledby]="instanceId + '-label'"
21
+ [hidden]="!isOpen() || filteredItems().length === 0"
22
+ >
23
+ @for (item of filteredItems(); track item.id; let i = $index) {
24
+ <li
25
+ role="option"
26
+ [id]="instanceId + '-option-' + item.id"
27
+ [attr.aria-selected]="i === activeIndex()"
28
+ (click)="select(item)"
29
+ >
30
+ {{ item.label }}
31
+ </li>
32
+ }
33
+ </ul>
@@ -0,0 +1,93 @@
1
+ import { Component, computed, signal } from '@angular/core';
2
+
3
+ interface <%= classify(name) %>Item {
4
+ id: number;
5
+ label: string;
6
+ }
7
+
8
+ let nextId = 0;
9
+
10
+ @Component({
11
+ selector: '<%= selector %>',
12
+ imports: [],
13
+ templateUrl: './<%= dasherize(name) %>.html',
14
+ styleUrl: './<%= dasherize(name) %>.css',
15
+ })
16
+ export class <%= classify(name) %> {
17
+ protected readonly instanceId = `<%= dasherize(name) %>-${nextId++}`;
18
+ protected readonly items: <%= classify(name) %>Item[] = [
19
+ { id: 1, label: 'Apple' },
20
+ { id: 2, label: 'Banana' },
21
+ { id: 3, label: 'Cherry' },
22
+ ];
23
+
24
+ protected readonly query = signal('');
25
+ protected readonly isOpen = signal(false);
26
+ protected readonly activeIndex = signal(-1);
27
+
28
+ protected readonly filteredItems = computed(() =>
29
+ this.items.filter((item) => item.label.toLowerCase().includes(this.query().toLowerCase()))
30
+ );
31
+
32
+ protected readonly activeDescendantId = computed(() => {
33
+ const active = this.filteredItems()[this.activeIndex()];
34
+ return active ? `${this.instanceId}-option-${active.id}` : null;
35
+ });
36
+
37
+ protected openList(): void {
38
+ this.isOpen.set(true);
39
+ }
40
+
41
+ protected onInput(event: Event): void {
42
+ const value = (event.target as HTMLInputElement).value;
43
+ this.query.set(value);
44
+ this.isOpen.set(true);
45
+ this.activeIndex.set(-1);
46
+ }
47
+
48
+ protected select(item: <%= classify(name) %>Item): void {
49
+ this.query.set(item.label);
50
+ this.isOpen.set(false);
51
+ this.activeIndex.set(-1);
52
+ }
53
+
54
+ protected handleInputKeydown(event: KeyboardEvent): void {
55
+ const options = this.filteredItems();
56
+
57
+ switch (event.key) {
58
+ case 'ArrowDown':
59
+ event.preventDefault();
60
+ this.isOpen.set(true);
61
+ this.activeIndex.update((index) => Math.min(index + 1, options.length - 1));
62
+ break;
63
+ case 'ArrowUp':
64
+ event.preventDefault();
65
+ this.activeIndex.update((index) => Math.max(index - 1, 0));
66
+ break;
67
+ case 'Home':
68
+ if (this.isOpen()) {
69
+ event.preventDefault();
70
+ this.activeIndex.set(0);
71
+ }
72
+ break;
73
+ case 'End':
74
+ if (this.isOpen()) {
75
+ event.preventDefault();
76
+ this.activeIndex.set(options.length - 1);
77
+ }
78
+ break;
79
+ case 'Enter': {
80
+ const active = options[this.activeIndex()];
81
+ if (active) {
82
+ event.preventDefault();
83
+ this.select(active);
84
+ }
85
+ break;
86
+ }
87
+ case 'Escape':
88
+ this.isOpen.set(false);
89
+ this.activeIndex.set(-1);
90
+ break;
91
+ }
92
+ }
93
+ }
@@ -0,0 +1 @@
1
+ export declare const combobox: (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.combobox = void 0;
4
+ const generate_component_1 = require("../utils/generate-component");
5
+ exports.combobox = (0, generate_component_1.createAriaComponentSchematic)();
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":";;;AAAA,oEAA2E;AAE9D,QAAA,QAAQ,GAAG,IAAA,iDAA4B,GAAE,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { createAriaComponentSchematic } from '../utils/generate-component';
2
+
3
+ export const combobox = createAriaComponentSchematic();
@@ -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,29 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema",
3
+ "$id": "SemmetAngularCombobox",
4
+ "title": "Semmet Angular Combobox Options Schema",
5
+ "type": "object",
6
+ "description": "Generates a standalone Angular Combobox component (list autocomplete, active-descendant model) following the W3C ARIA Authoring Practices Guide.",
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": { "$source": "argv", "index": 0 },
13
+ "x-prompt": "What name would you like to use for the combobox component?"
14
+ },
15
+ "path": {
16
+ "type": "string",
17
+ "format": "path",
18
+ "$default": { "$source": "workingDirectory" },
19
+ "description": "The path where the component files should be created, relative to the workspace root. Defaults to the project's source root.",
20
+ "visible": false
21
+ },
22
+ "project": {
23
+ "type": "string",
24
+ "description": "The name of the project to add the component to.",
25
+ "$default": { "$source": "projectName" }
26
+ }
27
+ },
28
+ "required": ["name", "project"]
29
+ }
@@ -0,0 +1 @@
1
+ export { ComponentSchematicOptions as Schema } from '../utils/schema-types';
@@ -1,8 +1,8 @@
1
1
  :host {
2
- --semmet-color-primary: #0d7a72;
2
+ --semmet-color-primary: #18181b;
3
3
  --semmet-color-surface: #ffffff;
4
- --semmet-color-on-surface: #1b201f;
5
- --semmet-color-on-surface-variant: #576260;
4
+ --semmet-color-on-surface: #18181b;
5
+ --semmet-color-on-surface-variant: #52525b;
6
6
  --semmet-color-scrim: rgba(20, 24, 23, 0.45);
7
7
  --semmet-radius-lg: 20px;
8
8
  --semmet-elevation-3: 0 8px 24px rgba(20, 24, 23, 0.18), 0 2px 8px rgba(20, 24, 23, 0.1);
@@ -1,9 +1,9 @@
1
1
  :host {
2
- --semmet-color-primary: #0d7a72;
2
+ --semmet-color-primary: #18181b;
3
3
  --semmet-color-surface: #ffffff;
4
- --semmet-color-outline: #d7dedd;
5
- --semmet-color-on-surface: #1b201f;
6
- --semmet-color-on-surface-variant: #576260;
4
+ --semmet-color-outline: #d4d4d8;
5
+ --semmet-color-on-surface: #18181b;
6
+ --semmet-color-on-surface-variant: #52525b;
7
7
  --semmet-radius-md: 12px;
8
8
  --semmet-elevation-1: 0 1px 2px rgba(20, 24, 23, 0.1), 0 1px 1px rgba(20, 24, 23, 0.06);
9
9
  --semmet-motion: 160ms cubic-bezier(0.2, 0, 0, 1);
@@ -0,0 +1,61 @@
1
+ :host {
2
+ --semmet-color-outline: #d4d4d8;
3
+ --semmet-color-on-surface: #18181b;
4
+ --semmet-color-on-surface-variant: #52525b;
5
+
6
+ display: grid;
7
+ grid-template-columns: 1fr;
8
+ gap: 1.5rem;
9
+ font-family: Roboto, system-ui, -apple-system, 'Segoe UI', sans-serif;
10
+ color: var(--semmet-color-on-surface);
11
+ }
12
+
13
+ header,
14
+ nav,
15
+ footer {
16
+ padding: 1rem 0;
17
+ }
18
+
19
+ header {
20
+ border-bottom: 1px solid var(--semmet-color-outline);
21
+ }
22
+
23
+ footer {
24
+ border-top: 1px solid var(--semmet-color-outline);
25
+ color: var(--semmet-color-on-surface-variant);
26
+ }
27
+
28
+ main {
29
+ min-height: 12rem;
30
+ }
31
+
32
+ @media (min-width: 48rem) {
33
+ :host {
34
+ grid-template-columns: 1fr 16rem;
35
+ grid-template-areas:
36
+ 'header header'
37
+ 'nav nav'
38
+ 'main aside'
39
+ 'footer footer';
40
+ }
41
+
42
+ header {
43
+ grid-area: header;
44
+ }
45
+
46
+ nav {
47
+ grid-area: nav;
48
+ }
49
+
50
+ main {
51
+ grid-area: main;
52
+ }
53
+
54
+ aside {
55
+ grid-area: aside;
56
+ }
57
+
58
+ footer {
59
+ grid-area: footer;
60
+ }
61
+ }
@@ -0,0 +1,17 @@
1
+ <!-- Semmet Angular: Landmarks (Page Skeleton) — https://www.w3.org/WAI/ARIA/apg/practices/landmark-regions/ -->
2
+ <!-- Project content into a region with the matching attribute, e.g. <div header>...</div>. Unmatched content goes to <main>. -->
3
+ <header>
4
+ <ng-content select="[header]"></ng-content>
5
+ </header>
6
+ <nav aria-label="Main">
7
+ <ng-content select="[nav]"></ng-content>
8
+ </nav>
9
+ <main>
10
+ <ng-content></ng-content>
11
+ </main>
12
+ <aside aria-label="Related links">
13
+ <ng-content select="[aside]"></ng-content>
14
+ </aside>
15
+ <footer>
16
+ <ng-content select="[footer]"></ng-content>
17
+ </footer>
@@ -0,0 +1,9 @@
1
+ import { Component } from '@angular/core';
2
+
3
+ @Component({
4
+ selector: '<%= selector %>',
5
+ imports: [],
6
+ templateUrl: './<%= dasherize(name) %>.html',
7
+ styleUrl: './<%= dasherize(name) %>.css',
8
+ })
9
+ export class <%= classify(name) %> {}
@@ -0,0 +1 @@
1
+ export declare const landmarks: (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.landmarks = void 0;
4
+ const generate_component_1 = require("../utils/generate-component");
5
+ exports.landmarks = (0, generate_component_1.createAriaComponentSchematic)();
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":";;;AAAA,oEAA2E;AAE9D,QAAA,SAAS,GAAG,IAAA,iDAA4B,GAAE,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { createAriaComponentSchematic } from '../utils/generate-component';
2
+
3
+ export const landmarks = createAriaComponentSchematic();
@@ -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,29 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema",
3
+ "$id": "SemmetAngularLandmarks",
4
+ "title": "Semmet Angular Landmarks Options Schema",
5
+ "type": "object",
6
+ "description": "Generates a standalone Angular page-skeleton layout component (header/nav/main/aside/footer landmarks with content projection), following W3C ARIA landmark region guidance.",
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": { "$source": "argv", "index": 0 },
13
+ "x-prompt": "What name would you like to use for the layout component?"
14
+ },
15
+ "path": {
16
+ "type": "string",
17
+ "format": "path",
18
+ "$default": { "$source": "workingDirectory" },
19
+ "description": "The path where the component files should be created, relative to the workspace root. Defaults to the project's source root.",
20
+ "visible": false
21
+ },
22
+ "project": {
23
+ "type": "string",
24
+ "description": "The name of the project to add the component to.",
25
+ "$default": { "$source": "projectName" }
26
+ }
27
+ },
28
+ "required": ["name", "project"]
29
+ }
@@ -0,0 +1 @@
1
+ export { ComponentSchematicOptions as Schema } from '../utils/schema-types';
@@ -0,0 +1,52 @@
1
+ :host {
2
+ --semmet-color-primary: #18181b;
3
+ --semmet-color-surface: #ffffff;
4
+ --semmet-color-outline: #d4d4d8;
5
+ --semmet-color-on-surface: #18181b;
6
+ --semmet-radius-sm: 8px;
7
+ --semmet-motion: 160ms cubic-bezier(0.2, 0, 0, 1);
8
+
9
+ display: block;
10
+ font-family: Roboto, system-ui, -apple-system, 'Segoe UI', sans-serif;
11
+ font-size: 0.9375rem;
12
+ }
13
+
14
+ span {
15
+ display: block;
16
+ margin-bottom: 0.5rem;
17
+ font-weight: 500;
18
+ color: var(--semmet-color-on-surface);
19
+ }
20
+
21
+ ul {
22
+ margin: 0;
23
+ padding: 0.375rem;
24
+ list-style: none;
25
+ border: 1px solid var(--semmet-color-outline);
26
+ border-radius: var(--semmet-radius-sm);
27
+ background: var(--semmet-color-surface);
28
+ max-width: 16rem;
29
+ }
30
+
31
+ ul:focus-visible {
32
+ outline: 2px solid var(--semmet-color-primary);
33
+ outline-offset: 1px;
34
+ }
35
+
36
+ [role='option'] {
37
+ padding: 0.5rem 0.75rem;
38
+ border-radius: 6px;
39
+ color: var(--semmet-color-on-surface);
40
+ cursor: pointer;
41
+ transition: background-color var(--semmet-motion);
42
+ }
43
+
44
+ [role='option'][aria-selected='true'] {
45
+ background: color-mix(in srgb, var(--semmet-color-primary) 12%, transparent);
46
+ color: var(--semmet-color-primary);
47
+ font-weight: 500;
48
+ }
49
+
50
+ [role='option']:hover {
51
+ background: color-mix(in srgb, var(--semmet-color-on-surface) 6%, transparent);
52
+ }
@@ -0,0 +1,20 @@
1
+ <!-- Semmet Angular: Listbox — https://www.w3.org/WAI/ARIA/apg/patterns/listbox/ -->
2
+ <span [id]="instanceId + '-label'">Choose an option</span>
3
+ <ul
4
+ role="listbox"
5
+ [attr.aria-labelledby]="instanceId + '-label'"
6
+ [attr.aria-activedescendant]="activeDescendantId()"
7
+ tabindex="0"
8
+ (keydown)="navigateList($event)"
9
+ >
10
+ @for (option of options; track option.id; let i = $index) {
11
+ <li
12
+ role="option"
13
+ [id]="instanceId + '-option-' + option.id"
14
+ [attr.aria-selected]="i === activeIndex()"
15
+ (click)="select(i)"
16
+ >
17
+ {{ option.label }}
18
+ </li>
19
+ }
20
+ </ul>
@@ -0,0 +1,54 @@
1
+ import { Component, computed, signal } from '@angular/core';
2
+
3
+ interface <%= classify(name) %>Option {
4
+ id: number;
5
+ label: string;
6
+ }
7
+
8
+ let nextId = 0;
9
+
10
+ @Component({
11
+ selector: '<%= selector %>',
12
+ imports: [],
13
+ templateUrl: './<%= dasherize(name) %>.html',
14
+ styleUrl: './<%= dasherize(name) %>.css',
15
+ })
16
+ export class <%= classify(name) %> {
17
+ protected readonly instanceId = `<%= dasherize(name) %>-${nextId++}`;
18
+ protected readonly options: <%= classify(name) %>Option[] = [
19
+ { id: 1, label: 'First option' },
20
+ { id: 2, label: 'Second option' },
21
+ ];
22
+
23
+ protected readonly activeIndex = signal(0);
24
+
25
+ protected readonly activeDescendantId = computed(
26
+ () => `${this.instanceId}-option-${this.options[this.activeIndex()].id}`
27
+ );
28
+
29
+ protected select(index: number): void {
30
+ this.activeIndex.set(index);
31
+ }
32
+
33
+ // Up/Down move the active option; Home/End jump to first/last (APG listbox, active-descendant model).
34
+ protected navigateList(event: KeyboardEvent): void {
35
+ switch (event.key) {
36
+ case 'ArrowDown':
37
+ event.preventDefault();
38
+ this.activeIndex.update((index) => Math.min(index + 1, this.options.length - 1));
39
+ break;
40
+ case 'ArrowUp':
41
+ event.preventDefault();
42
+ this.activeIndex.update((index) => Math.max(index - 1, 0));
43
+ break;
44
+ case 'Home':
45
+ event.preventDefault();
46
+ this.activeIndex.set(0);
47
+ break;
48
+ case 'End':
49
+ event.preventDefault();
50
+ this.activeIndex.set(this.options.length - 1);
51
+ break;
52
+ }
53
+ }
54
+ }
@@ -0,0 +1 @@
1
+ export declare const listbox: (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.listbox = void 0;
4
+ const generate_component_1 = require("../utils/generate-component");
5
+ exports.listbox = (0, generate_component_1.createAriaComponentSchematic)();
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":";;;AAAA,oEAA2E;AAE9D,QAAA,OAAO,GAAG,IAAA,iDAA4B,GAAE,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { createAriaComponentSchematic } from '../utils/generate-component';
2
+
3
+ export const listbox = createAriaComponentSchematic();
@@ -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,29 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema",
3
+ "$id": "SemmetAngularListbox",
4
+ "title": "Semmet Angular Listbox Options Schema",
5
+ "type": "object",
6
+ "description": "Generates a standalone Angular Listbox component (active-descendant model) following the W3C ARIA Authoring Practices Guide.",
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": { "$source": "argv", "index": 0 },
13
+ "x-prompt": "What name would you like to use for the listbox component?"
14
+ },
15
+ "path": {
16
+ "type": "string",
17
+ "format": "path",
18
+ "$default": { "$source": "workingDirectory" },
19
+ "description": "The path where the component files should be created, relative to the workspace root. Defaults to the project's source root.",
20
+ "visible": false
21
+ },
22
+ "project": {
23
+ "type": "string",
24
+ "description": "The name of the project to add the component to.",
25
+ "$default": { "$source": "projectName" }
26
+ }
27
+ },
28
+ "required": ["name", "project"]
29
+ }
@@ -0,0 +1 @@
1
+ export { ComponentSchematicOptions as Schema } from '../utils/schema-types';