@sonny-ui/core 0.1.0-alpha.2 → 0.1.0-alpha.20

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 (242) hide show
  1. package/README.md +187 -40
  2. package/fesm2022/sonny-ui-core.mjs +6642 -268
  3. package/fesm2022/sonny-ui-core.mjs.map +1 -1
  4. package/package.json +8 -5
  5. package/schematics/ng-add/index.js +27 -0
  6. package/schematics/ng-add/schema.json +1 -1
  7. package/schematics/ng-generate/component/index.js +182 -1
  8. package/schematics/ng-generate/component/schema.json +2 -2
  9. package/src/lib/accordion/accordion.directives.spec.ts +173 -0
  10. package/src/lib/accordion/accordion.directives.ts +143 -0
  11. package/src/lib/accordion/index.ts +8 -0
  12. package/src/lib/alert/alert.directives.spec.ts +154 -0
  13. package/src/lib/alert/alert.directives.ts +67 -0
  14. package/src/lib/alert/alert.variants.ts +25 -0
  15. package/src/lib/alert/index.ts +6 -0
  16. package/src/lib/avatar/avatar.component.spec.ts +75 -0
  17. package/src/lib/avatar/avatar.component.ts +43 -0
  18. package/src/lib/avatar/avatar.variants.ts +26 -0
  19. package/src/lib/avatar/index.ts +2 -0
  20. package/src/lib/avatar-group/avatar-group.component.spec.ts +74 -0
  21. package/src/lib/avatar-group/avatar-group.component.ts +88 -0
  22. package/src/lib/avatar-group/index.ts +1 -0
  23. package/src/lib/badge/badge.directive.spec.ts +74 -0
  24. package/src/lib/badge/badge.directive.ts +17 -0
  25. package/src/lib/badge/badge.variants.ts +29 -0
  26. package/src/lib/badge/index.ts +2 -0
  27. package/src/lib/breadcrumb/breadcrumb.directives.spec.ts +80 -0
  28. package/src/lib/breadcrumb/breadcrumb.directives.ts +78 -0
  29. package/src/lib/breadcrumb/index.ts +8 -0
  30. package/src/lib/button/button.directive.spec.ts +92 -0
  31. package/src/lib/button/button.directive.ts +28 -0
  32. package/src/lib/button/button.variants.ts +30 -0
  33. package/src/lib/button/index.ts +2 -0
  34. package/src/lib/button-group/button-group.directive.spec.ts +46 -0
  35. package/src/lib/button-group/button-group.directive.ts +19 -0
  36. package/src/lib/button-group/button-group.variants.ts +18 -0
  37. package/src/lib/button-group/index.ts +2 -0
  38. package/src/lib/calendar/calendar.component.spec.ts +192 -0
  39. package/src/lib/calendar/calendar.component.ts +342 -0
  40. package/src/lib/calendar/calendar.types.ts +24 -0
  41. package/src/lib/calendar/index.ts +7 -0
  42. package/src/lib/card/card.directives.spec.ts +104 -0
  43. package/src/lib/card/card.directives.ts +72 -0
  44. package/src/lib/card/card.variants.ts +28 -0
  45. package/src/lib/card/index.ts +9 -0
  46. package/src/lib/carousel/carousel.directives.spec.ts +85 -0
  47. package/src/lib/carousel/carousel.directives.ts +159 -0
  48. package/src/lib/carousel/index.ts +8 -0
  49. package/src/lib/chat-bubble/chat-bubble.directives.spec.ts +52 -0
  50. package/src/lib/chat-bubble/chat-bubble.directives.ts +96 -0
  51. package/src/lib/chat-bubble/index.ts +11 -0
  52. package/src/lib/checkbox/checkbox.directive.spec.ts +57 -0
  53. package/src/lib/checkbox/checkbox.directive.ts +16 -0
  54. package/src/lib/checkbox/checkbox.variants.ts +19 -0
  55. package/src/lib/checkbox/index.ts +2 -0
  56. package/src/lib/color-picker/color-picker.component.spec.ts +328 -0
  57. package/src/lib/color-picker/color-picker.component.ts +537 -0
  58. package/src/lib/color-picker/color-picker.types.ts +24 -0
  59. package/src/lib/color-picker/color-picker.utils.ts +183 -0
  60. package/src/lib/color-picker/color-picker.variants.ts +17 -0
  61. package/src/lib/color-picker/index.ts +20 -0
  62. package/src/lib/combobox/combobox.component.spec.ts +151 -0
  63. package/src/lib/combobox/combobox.component.ts +264 -0
  64. package/src/lib/combobox/combobox.variants.ts +19 -0
  65. package/src/lib/combobox/index.ts +2 -0
  66. package/src/lib/command-palette/command-palette.component.spec.ts +178 -0
  67. package/src/lib/command-palette/command-palette.component.ts +194 -0
  68. package/src/lib/command-palette/command-palette.service.ts +36 -0
  69. package/src/lib/command-palette/command-palette.types.ts +23 -0
  70. package/src/lib/command-palette/index.ts +7 -0
  71. package/src/lib/data-table/data-table.component.spec.ts +443 -0
  72. package/src/lib/data-table/data-table.component.ts +602 -0
  73. package/src/lib/data-table/data-table.directives.ts +31 -0
  74. package/src/lib/data-table/data-table.types.ts +20 -0
  75. package/src/lib/data-table/index.ts +13 -0
  76. package/src/lib/date-picker/date-picker.component.spec.ts +131 -0
  77. package/src/lib/date-picker/date-picker.component.ts +220 -0
  78. package/src/lib/date-picker/date-picker.variants.ts +17 -0
  79. package/src/lib/date-picker/index.ts +2 -0
  80. package/src/lib/date-range-picker/date-range-picker.component.spec.ts +151 -0
  81. package/src/lib/date-range-picker/date-range-picker.component.ts +340 -0
  82. package/src/lib/date-range-picker/index.ts +1 -0
  83. package/src/lib/diff/diff.component.spec.ts +47 -0
  84. package/src/lib/diff/diff.component.ts +82 -0
  85. package/src/lib/diff/index.ts +1 -0
  86. package/src/lib/divider/divider.component.spec.ts +48 -0
  87. package/src/lib/divider/divider.component.ts +51 -0
  88. package/src/lib/divider/divider.variants.ts +22 -0
  89. package/src/lib/divider/index.ts +2 -0
  90. package/src/lib/dock/dock.directives.spec.ts +85 -0
  91. package/src/lib/dock/dock.directives.ts +81 -0
  92. package/src/lib/dock/index.ts +1 -0
  93. package/src/lib/drawer/drawer.directives.spec.ts +62 -0
  94. package/src/lib/drawer/drawer.directives.ts +80 -0
  95. package/src/lib/drawer/index.ts +8 -0
  96. package/src/lib/dropdown/dropdown.directives.spec.ts +106 -0
  97. package/src/lib/dropdown/dropdown.directives.ts +136 -0
  98. package/src/lib/dropdown/dropdown.variants.ts +27 -0
  99. package/src/lib/dropdown/index.ts +15 -0
  100. package/src/lib/fab/fab.directives.spec.ts +60 -0
  101. package/src/lib/fab/fab.directives.ts +77 -0
  102. package/src/lib/fab/index.ts +8 -0
  103. package/src/lib/fieldset/fieldset.directives.spec.ts +74 -0
  104. package/src/lib/fieldset/fieldset.directives.ts +49 -0
  105. package/src/lib/fieldset/fieldset.variants.ts +15 -0
  106. package/src/lib/fieldset/index.ts +6 -0
  107. package/src/lib/file-input/file-input.component.spec.ts +114 -0
  108. package/src/lib/file-input/file-input.component.ts +155 -0
  109. package/src/lib/file-input/file-input.variants.ts +25 -0
  110. package/src/lib/file-input/index.ts +6 -0
  111. package/src/lib/indicator/index.ts +6 -0
  112. package/src/lib/indicator/indicator.directives.spec.ts +64 -0
  113. package/src/lib/indicator/indicator.directives.ts +59 -0
  114. package/src/lib/input/index.ts +3 -0
  115. package/src/lib/input/input.directive.spec.ts +103 -0
  116. package/src/lib/input/input.directive.ts +25 -0
  117. package/src/lib/input/input.variants.ts +42 -0
  118. package/src/lib/input/label.directive.ts +16 -0
  119. package/src/lib/kbd/index.ts +2 -0
  120. package/src/lib/kbd/kbd.directive.spec.ts +42 -0
  121. package/src/lib/kbd/kbd.directive.ts +18 -0
  122. package/src/lib/kbd/kbd.variants.ts +19 -0
  123. package/src/lib/link/index.ts +2 -0
  124. package/src/lib/link/link.directive.spec.ts +41 -0
  125. package/src/lib/link/link.directive.ts +18 -0
  126. package/src/lib/link/link.variants.ts +20 -0
  127. package/src/lib/list/index.ts +8 -0
  128. package/src/lib/list/list.directives.spec.ts +65 -0
  129. package/src/lib/list/list.directives.ts +81 -0
  130. package/src/lib/loader/index.ts +2 -0
  131. package/src/lib/loader/loader.component.spec.ts +58 -0
  132. package/src/lib/loader/loader.component.ts +47 -0
  133. package/src/lib/loader/loader.variants.ts +21 -0
  134. package/src/lib/modal/dialog-ref.ts +19 -0
  135. package/src/lib/modal/dialog.directives.ts +84 -0
  136. package/src/lib/modal/dialog.service.spec.ts +52 -0
  137. package/src/lib/modal/dialog.service.ts +61 -0
  138. package/src/lib/modal/dialog.types.ts +16 -0
  139. package/src/lib/modal/index.ts +11 -0
  140. package/src/lib/navbar/index.ts +7 -0
  141. package/src/lib/navbar/navbar.directives.spec.ts +59 -0
  142. package/src/lib/navbar/navbar.directives.ts +57 -0
  143. package/src/lib/number-input/index.ts +2 -0
  144. package/src/lib/number-input/number-input.component.spec.ts +151 -0
  145. package/src/lib/number-input/number-input.component.ts +152 -0
  146. package/src/lib/number-input/number-input.variants.ts +17 -0
  147. package/src/lib/otp-input/index.ts +2 -0
  148. package/src/lib/otp-input/otp-input.component.spec.ts +252 -0
  149. package/src/lib/otp-input/otp-input.component.ts +274 -0
  150. package/src/lib/otp-input/otp-input.variants.ts +18 -0
  151. package/src/lib/pagination/index.ts +6 -0
  152. package/src/lib/pagination/pagination.component.spec.ts +59 -0
  153. package/src/lib/pagination/pagination.component.ts +143 -0
  154. package/src/lib/pagination/pagination.variants.ts +31 -0
  155. package/src/lib/popover/index.ts +6 -0
  156. package/src/lib/popover/popover.directives.spec.ts +147 -0
  157. package/src/lib/popover/popover.directives.ts +151 -0
  158. package/src/lib/progress/index.ts +7 -0
  159. package/src/lib/progress/progress.component.spec.ts +117 -0
  160. package/src/lib/progress/progress.component.ts +64 -0
  161. package/src/lib/progress/progress.variants.ts +43 -0
  162. package/src/lib/radial-progress/index.ts +5 -0
  163. package/src/lib/radial-progress/radial-progress.component.spec.ts +41 -0
  164. package/src/lib/radial-progress/radial-progress.component.ts +70 -0
  165. package/src/lib/radio/index.ts +2 -0
  166. package/src/lib/radio/radio.directive.spec.ts +46 -0
  167. package/src/lib/radio/radio.directive.ts +16 -0
  168. package/src/lib/radio/radio.variants.ts +19 -0
  169. package/src/lib/rating/index.ts +2 -0
  170. package/src/lib/rating/rating.component.spec.ts +157 -0
  171. package/src/lib/rating/rating.component.ts +163 -0
  172. package/src/lib/rating/rating.variants.ts +20 -0
  173. package/src/lib/select/index.ts +2 -0
  174. package/src/lib/select/select.component.spec.ts +112 -0
  175. package/src/lib/select/select.component.ts +235 -0
  176. package/src/lib/select/select.variants.ts +19 -0
  177. package/src/lib/sheet/index.ts +10 -0
  178. package/src/lib/sheet/sheet-ref.ts +18 -0
  179. package/src/lib/sheet/sheet.component.spec.ts +67 -0
  180. package/src/lib/sheet/sheet.directives.ts +70 -0
  181. package/src/lib/sheet/sheet.service.ts +100 -0
  182. package/src/lib/sheet/sheet.types.ts +23 -0
  183. package/src/lib/skeleton/index.ts +2 -0
  184. package/src/lib/skeleton/skeleton.directive.spec.ts +63 -0
  185. package/src/lib/skeleton/skeleton.directive.ts +21 -0
  186. package/src/lib/skeleton/skeleton.variants.ts +27 -0
  187. package/src/lib/slider/index.ts +2 -0
  188. package/src/lib/slider/slider.component.spec.ts +104 -0
  189. package/src/lib/slider/slider.component.ts +181 -0
  190. package/src/lib/slider/slider.variants.ts +25 -0
  191. package/src/lib/stat/index.ts +8 -0
  192. package/src/lib/stat/stat.directives.spec.ts +60 -0
  193. package/src/lib/stat/stat.directives.ts +79 -0
  194. package/src/lib/status/index.ts +2 -0
  195. package/src/lib/status/status.directive.spec.ts +43 -0
  196. package/src/lib/status/status.directive.ts +37 -0
  197. package/src/lib/status/status.variants.ts +26 -0
  198. package/src/lib/steps/index.ts +8 -0
  199. package/src/lib/steps/steps.directives.spec.ts +52 -0
  200. package/src/lib/steps/steps.directives.ts +78 -0
  201. package/src/lib/switch/index.ts +2 -0
  202. package/src/lib/switch/switch.component.spec.ts +98 -0
  203. package/src/lib/switch/switch.component.ts +76 -0
  204. package/src/lib/switch/switch.variants.ts +31 -0
  205. package/src/lib/table/index.ts +12 -0
  206. package/src/lib/table/table.directives.spec.ts +111 -0
  207. package/src/lib/table/table.directives.ts +126 -0
  208. package/src/lib/table/table.variants.ts +36 -0
  209. package/src/lib/tabs/index.ts +8 -0
  210. package/src/lib/tabs/tabs.directives.spec.ts +136 -0
  211. package/src/lib/tabs/tabs.directives.ts +126 -0
  212. package/src/lib/tabs/tabs.variants.ts +17 -0
  213. package/src/lib/tag-input/index.ts +2 -0
  214. package/src/lib/tag-input/tag-input.component.spec.ts +190 -0
  215. package/src/lib/tag-input/tag-input.component.ts +172 -0
  216. package/src/lib/tag-input/tag-input.variants.ts +31 -0
  217. package/src/lib/textarea/index.ts +7 -0
  218. package/src/lib/textarea/textarea.directive.spec.ts +84 -0
  219. package/src/lib/textarea/textarea.directive.ts +71 -0
  220. package/src/lib/textarea/textarea.variants.ts +34 -0
  221. package/src/lib/timeline/index.ts +11 -0
  222. package/src/lib/timeline/timeline.directives.spec.ts +55 -0
  223. package/src/lib/timeline/timeline.directives.ts +85 -0
  224. package/src/lib/toast/index.ts +3 -0
  225. package/src/lib/toast/toast.service.spec.ts +71 -0
  226. package/src/lib/toast/toast.service.ts +60 -0
  227. package/src/lib/toast/toast.variants.ts +38 -0
  228. package/src/lib/toast/toaster.component.spec.ts +38 -0
  229. package/src/lib/toast/toaster.component.ts +81 -0
  230. package/src/lib/toggle/index.ts +2 -0
  231. package/src/lib/toggle/toggle.directive.spec.ts +100 -0
  232. package/src/lib/toggle/toggle.directive.ts +61 -0
  233. package/src/lib/toggle/toggle.variants.ts +25 -0
  234. package/src/lib/tooltip/index.ts +2 -0
  235. package/src/lib/tooltip/tooltip.directive.spec.ts +113 -0
  236. package/src/lib/tooltip/tooltip.directive.ts +130 -0
  237. package/src/lib/tooltip/tooltip.variants.ts +20 -0
  238. package/src/lib/validator/index.ts +5 -0
  239. package/src/lib/validator/validator.directives.spec.ts +47 -0
  240. package/src/lib/validator/validator.directives.ts +50 -0
  241. package/src/styles/sonny-theme.css +33 -0
  242. package/types/sonny-ui-core.d.ts +1443 -13
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sonny-ui/core",
3
- "version": "0.1.0-alpha.2",
3
+ "version": "0.1.0-alpha.20",
4
4
  "description": "Angular UI component library inspired by shadcn/ui — signals, zoneless, Tailwind CSS v4",
5
5
  "peerDependencies": {
6
6
  "@angular/common": "^21.0.0",
@@ -33,13 +33,14 @@
33
33
  "type": "git",
34
34
  "url": "https://github.com/coci-dev/sonny-ui.git"
35
35
  },
36
- "homepage": "https://github.com/coci-dev/sonny-ui#readme",
36
+ "homepage": "https://coci-dev.github.io/sonny-ui/",
37
37
  "bugs": {
38
38
  "url": "https://github.com/coci-dev/sonny-ui/issues"
39
39
  },
40
- "module": "fesm2022/sonny-ui-core.mjs",
41
- "typings": "types/sonny-ui-core.d.ts",
42
40
  "exports": {
41
+ "./styles/*": {
42
+ "default": "./src/styles/*"
43
+ },
43
44
  "./package.json": {
44
45
  "default": "./package.json"
45
46
  },
@@ -47,5 +48,7 @@
47
48
  "types": "./types/sonny-ui-core.d.ts",
48
49
  "default": "./fesm2022/sonny-ui-core.mjs"
49
50
  }
50
- }
51
+ },
52
+ "module": "fesm2022/sonny-ui-core.mjs",
53
+ "typings": "types/sonny-ui-core.d.ts"
51
54
  }
@@ -21,6 +21,33 @@ function ngAdd(options) {
21
21
  context.logger.info('Added SonnyUI theme import to styles.css');
22
22
  }
23
23
  }
24
+ // Add provideSonnyUI to app.config.ts
25
+ const configPath = 'src/app/app.config.ts';
26
+ if (tree.exists(configPath)) {
27
+ let configContent = tree.read(configPath).toString('utf-8');
28
+ const theme = options.theme || 'light';
29
+ if (!configContent.includes('provideSonnyUI')) {
30
+ // Add import statement
31
+ const importLine = `import { provideSonnyUI } from '@sonny-ui/core';\n`;
32
+ const lastImportIndex = configContent.lastIndexOf('import ');
33
+ const lastImportEnd = configContent.indexOf('\n', lastImportIndex);
34
+ configContent =
35
+ configContent.slice(0, lastImportEnd + 1) +
36
+ importLine +
37
+ configContent.slice(lastImportEnd + 1);
38
+ // Add provider to providers array
39
+ const providersMatch = configContent.match(/providers\s*:\s*\[/);
40
+ if (providersMatch && providersMatch.index !== undefined) {
41
+ const insertPos = providersMatch.index + providersMatch[0].length;
42
+ configContent =
43
+ configContent.slice(0, insertPos) +
44
+ `\n provideSonnyUI({ defaultTheme: '${theme}' }),` +
45
+ configContent.slice(insertPos);
46
+ }
47
+ tree.overwrite(configPath, configContent);
48
+ context.logger.info('Added provideSonnyUI to app.config.ts');
49
+ }
50
+ }
24
51
  return tree;
25
52
  };
26
53
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "http://json-schema.org/schema",
3
- "id": "SonnyUIAddSchema",
3
+ "$id": "SonnyUIAddSchema",
4
4
  "title": "SonnyUI ng-add schematic",
5
5
  "type": "object",
6
6
  "properties": {
@@ -37,33 +37,66 @@ exports.generateComponent = generateComponent;
37
37
  const path = __importStar(require("path"));
38
38
  const AVAILABLE_COMPONENTS = [
39
39
  'accordion',
40
+ 'alert',
40
41
  'avatar',
41
42
  'badge',
42
43
  'breadcrumb',
43
44
  'button',
44
45
  'button-group',
46
+ 'calendar',
45
47
  'card',
48
+ 'carousel',
49
+ 'chat-bubble',
46
50
  'checkbox',
47
51
  'combobox',
52
+ 'diff',
53
+ 'divider',
54
+ 'dock',
55
+ 'drawer',
56
+ 'dropdown',
57
+ 'fab',
58
+ 'fieldset',
59
+ 'file-input',
60
+ 'indicator',
48
61
  'input',
62
+ 'kbd',
63
+ 'link',
64
+ 'list',
49
65
  'loader',
50
66
  'modal',
67
+ 'navbar',
68
+ 'pagination',
69
+ 'progress',
70
+ 'radial-progress',
51
71
  'radio',
72
+ 'rating',
52
73
  'select',
53
74
  'sheet',
54
75
  'skeleton',
55
76
  'slider',
77
+ 'stat',
78
+ 'status',
79
+ 'steps',
56
80
  'switch',
57
81
  'table',
58
82
  'tabs',
83
+ 'textarea',
84
+ 'timeline',
59
85
  'toast',
60
86
  'toggle',
87
+ 'tooltip',
88
+ 'validator',
61
89
  ];
62
90
  const COMPONENT_FILES = {
63
91
  accordion: [
64
92
  'accordion.directives.ts',
65
93
  'index.ts',
66
94
  ],
95
+ alert: [
96
+ 'alert.directives.ts',
97
+ 'alert.variants.ts',
98
+ 'index.ts',
99
+ ],
67
100
  avatar: [
68
101
  'avatar.component.ts',
69
102
  'avatar.variants.ts',
@@ -88,11 +121,23 @@ const COMPONENT_FILES = {
88
121
  'button-group.variants.ts',
89
122
  'index.ts',
90
123
  ],
124
+ calendar: [
125
+ 'calendar.component.ts',
126
+ 'index.ts',
127
+ ],
91
128
  card: [
92
129
  'card.directives.ts',
93
130
  'card.variants.ts',
94
131
  'index.ts',
95
132
  ],
133
+ carousel: [
134
+ 'carousel.directives.ts',
135
+ 'index.ts',
136
+ ],
137
+ 'chat-bubble': [
138
+ 'chat-bubble.directives.ts',
139
+ 'index.ts',
140
+ ],
96
141
  checkbox: [
97
142
  'checkbox.directive.ts',
98
143
  'checkbox.variants.ts',
@@ -103,12 +148,66 @@ const COMPONENT_FILES = {
103
148
  'combobox.variants.ts',
104
149
  'index.ts',
105
150
  ],
151
+ diff: [
152
+ 'diff.component.ts',
153
+ 'index.ts',
154
+ ],
155
+ divider: [
156
+ 'divider.component.ts',
157
+ 'divider.variants.ts',
158
+ 'index.ts',
159
+ ],
160
+ dock: [
161
+ 'dock.directives.ts',
162
+ 'index.ts',
163
+ ],
164
+ drawer: [
165
+ 'drawer.directives.ts',
166
+ 'index.ts',
167
+ ],
168
+ dropdown: [
169
+ 'dropdown.directives.ts',
170
+ 'dropdown.variants.ts',
171
+ 'index.ts',
172
+ ],
173
+ fab: [
174
+ 'fab.directives.ts',
175
+ 'index.ts',
176
+ ],
177
+ fieldset: [
178
+ 'fieldset.directives.ts',
179
+ 'fieldset.variants.ts',
180
+ 'index.ts',
181
+ ],
182
+ 'file-input': [
183
+ 'file-input.component.ts',
184
+ 'file-input.variants.ts',
185
+ 'index.ts',
186
+ ],
187
+ indicator: [
188
+ 'indicator.directives.ts',
189
+ 'index.ts',
190
+ ],
106
191
  input: [
107
192
  'input.directive.ts',
108
193
  'input.variants.ts',
109
194
  'label.directive.ts',
110
195
  'index.ts',
111
196
  ],
197
+ kbd: [
198
+ 'kbd.directive.ts',
199
+ 'kbd.variants.ts',
200
+ 'index.ts',
201
+ ],
202
+ link: [
203
+ 'link.directive.ts',
204
+ 'link.variants.ts',
205
+ 'index.ts',
206
+ ],
207
+ list: [
208
+ 'list.directives.ts',
209
+ 'index.ts',
210
+ ],
112
211
  loader: [
113
212
  'loader.component.ts',
114
213
  'loader.variants.ts',
@@ -121,11 +220,34 @@ const COMPONENT_FILES = {
121
220
  'dialog.directives.ts',
122
221
  'index.ts',
123
222
  ],
223
+ navbar: [
224
+ 'navbar.directives.ts',
225
+ 'index.ts',
226
+ ],
227
+ pagination: [
228
+ 'pagination.component.ts',
229
+ 'pagination.variants.ts',
230
+ 'index.ts',
231
+ ],
232
+ progress: [
233
+ 'progress.component.ts',
234
+ 'progress.variants.ts',
235
+ 'index.ts',
236
+ ],
237
+ 'radial-progress': [
238
+ 'radial-progress.component.ts',
239
+ 'index.ts',
240
+ ],
124
241
  radio: [
125
242
  'radio.directive.ts',
126
243
  'radio.variants.ts',
127
244
  'index.ts',
128
245
  ],
246
+ rating: [
247
+ 'rating.component.ts',
248
+ 'rating.variants.ts',
249
+ 'index.ts',
250
+ ],
129
251
  select: [
130
252
  'select.component.ts',
131
253
  'select.variants.ts',
@@ -148,6 +270,19 @@ const COMPONENT_FILES = {
148
270
  'slider.variants.ts',
149
271
  'index.ts',
150
272
  ],
273
+ stat: [
274
+ 'stat.directives.ts',
275
+ 'index.ts',
276
+ ],
277
+ status: [
278
+ 'status.directive.ts',
279
+ 'status.variants.ts',
280
+ 'index.ts',
281
+ ],
282
+ steps: [
283
+ 'steps.directives.ts',
284
+ 'index.ts',
285
+ ],
151
286
  switch: [
152
287
  'switch.component.ts',
153
288
  'switch.variants.ts',
@@ -163,6 +298,15 @@ const COMPONENT_FILES = {
163
298
  'tabs.variants.ts',
164
299
  'index.ts',
165
300
  ],
301
+ textarea: [
302
+ 'textarea.directive.ts',
303
+ 'textarea.variants.ts',
304
+ 'index.ts',
305
+ ],
306
+ timeline: [
307
+ 'timeline.directives.ts',
308
+ 'index.ts',
309
+ ],
166
310
  toast: [
167
311
  'toast.service.ts',
168
312
  'toast.variants.ts',
@@ -174,30 +318,67 @@ const COMPONENT_FILES = {
174
318
  'toggle.variants.ts',
175
319
  'index.ts',
176
320
  ],
321
+ tooltip: [
322
+ 'tooltip.directive.ts',
323
+ 'tooltip.variants.ts',
324
+ 'index.ts',
325
+ ],
326
+ validator: [
327
+ 'validator.directives.ts',
328
+ 'index.ts',
329
+ ],
177
330
  };
178
331
  const COMPONENT_SPEC_FILES = {
179
332
  accordion: ['accordion.directives.spec.ts'],
333
+ alert: ['alert.directives.spec.ts'],
180
334
  avatar: ['avatar.component.spec.ts'],
181
335
  badge: ['badge.directive.spec.ts'],
182
336
  breadcrumb: ['breadcrumb.directives.spec.ts'],
183
337
  button: ['button.directive.spec.ts'],
184
338
  'button-group': ['button-group.directive.spec.ts'],
339
+ calendar: ['calendar.component.spec.ts'],
185
340
  card: ['card.directives.spec.ts'],
341
+ carousel: ['carousel.directives.spec.ts'],
342
+ 'chat-bubble': ['chat-bubble.directives.spec.ts'],
186
343
  checkbox: ['checkbox.directive.spec.ts'],
187
344
  combobox: ['combobox.component.spec.ts'],
345
+ diff: ['diff.component.spec.ts'],
346
+ divider: ['divider.component.spec.ts'],
347
+ dock: ['dock.directives.spec.ts'],
348
+ drawer: ['drawer.directives.spec.ts'],
349
+ dropdown: ['dropdown.directives.spec.ts'],
350
+ fab: ['fab.directives.spec.ts'],
351
+ fieldset: ['fieldset.directives.spec.ts'],
352
+ 'file-input': ['file-input.component.spec.ts'],
353
+ indicator: ['indicator.directives.spec.ts'],
188
354
  input: ['input.directive.spec.ts'],
355
+ kbd: ['kbd.directive.spec.ts'],
356
+ link: ['link.directive.spec.ts'],
357
+ list: ['list.directives.spec.ts'],
189
358
  loader: ['loader.component.spec.ts'],
190
359
  modal: ['dialog.service.spec.ts'],
360
+ navbar: ['navbar.directives.spec.ts'],
361
+ pagination: ['pagination.component.spec.ts'],
362
+ progress: ['progress.component.spec.ts'],
363
+ 'radial-progress': ['radial-progress.component.spec.ts'],
191
364
  radio: ['radio.directive.spec.ts'],
365
+ rating: ['rating.component.spec.ts'],
192
366
  select: ['select.component.spec.ts'],
193
367
  sheet: ['sheet.component.spec.ts'],
194
368
  skeleton: ['skeleton.directive.spec.ts'],
195
369
  slider: ['slider.component.spec.ts'],
370
+ stat: ['stat.directives.spec.ts'],
371
+ status: ['status.directive.spec.ts'],
372
+ steps: ['steps.directives.spec.ts'],
196
373
  switch: ['switch.component.spec.ts'],
197
374
  table: ['table.directives.spec.ts'],
198
375
  tabs: ['tabs.directives.spec.ts'],
376
+ textarea: ['textarea.directive.spec.ts'],
377
+ timeline: ['timeline.directives.spec.ts'],
199
378
  toast: ['toast.service.spec.ts'],
200
379
  toggle: ['toggle.directive.spec.ts'],
380
+ tooltip: ['tooltip.directive.spec.ts'],
381
+ validator: ['validator.directives.spec.ts'],
201
382
  };
202
383
  function generateComponent(options) {
203
384
  return (tree, context) => {
@@ -236,7 +417,7 @@ export function cn(...inputs: ClassValue[]): string {
236
417
  const fs = require('fs');
237
418
  let content = fs.readFileSync(sourcePath, 'utf-8');
238
419
  // Rewrite imports to use local cn utility
239
- content = content.replace(/from ['"]\.\.\/core\/utils\/cn['"]/g, `from '../../utils/cn'`);
420
+ content = content.replace(/from ['"]\.\.\/core\/utils\/cn['"]/g, `from '../utils/cn'`);
240
421
  // Rewrite prefix if custom
241
422
  if (options.prefix && options.prefix !== 'sny') {
242
423
  content = content.replace(/sny/g, options.prefix);
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "$schema": "http://json-schema.org/schema",
3
- "id": "SonnyUIGenerateComponentSchema",
3
+ "$id": "SonnyUIGenerateComponentSchema",
4
4
  "title": "SonnyUI component generator (copy-paste style)",
5
5
  "type": "object",
6
6
  "properties": {
7
7
  "name": {
8
8
  "type": "string",
9
- "description": "The component to copy (accordion, avatar, badge, breadcrumb, button, button-group, card, checkbox, combobox, input, loader, modal, radio, select, sheet, skeleton, slider, switch, table, tabs, toast, toggle).",
9
+ "description": "The component to copy (accordion, alert, avatar, badge, breadcrumb, button, button-group, calendar, card, carousel, chat-bubble, checkbox, combobox, diff, divider, dock, drawer, dropdown, fab, fieldset, file-input, indicator, input, kbd, link, list, loader, modal, navbar, pagination, progress, radial-progress, radio, rating, select, sheet, skeleton, slider, stat, status, steps, switch, table, tabs, textarea, timeline, toast, toggle, tooltip, validator).",
10
10
  "$default": {
11
11
  "$source": "argv",
12
12
  "index": 0
@@ -0,0 +1,173 @@
1
+ import { Component, signal, viewChild } from '@angular/core';
2
+ import { TestBed, ComponentFixture } from '@angular/core/testing';
3
+ import {
4
+ SnyAccordionDirective,
5
+ SnyAccordionItemDirective,
6
+ SnyAccordionTriggerDirective,
7
+ SnyAccordionContentDirective,
8
+ } from './accordion.directives';
9
+
10
+ @Component({
11
+ standalone: true,
12
+ imports: [
13
+ SnyAccordionDirective,
14
+ SnyAccordionItemDirective,
15
+ SnyAccordionTriggerDirective,
16
+ SnyAccordionContentDirective,
17
+ ],
18
+ template: `
19
+ <div snyAccordion [multi]="multi()">
20
+ <div snyAccordionItem value="item-1">
21
+ <button snyAccordionTrigger>Item 1</button>
22
+ <div snyAccordionContent><div>Content 1</div></div>
23
+ </div>
24
+ <div snyAccordionItem value="item-2">
25
+ <button snyAccordionTrigger>Item 2</button>
26
+ <div snyAccordionContent><div>Content 2</div></div>
27
+ </div>
28
+ </div>
29
+ `,
30
+ })
31
+ class TestHostComponent {
32
+ multi = signal(false);
33
+ }
34
+
35
+ describe('Accordion Directives', () => {
36
+ let fixture: ComponentFixture<TestHostComponent>;
37
+
38
+ beforeEach(async () => {
39
+ await TestBed.configureTestingModule({
40
+ imports: [TestHostComponent],
41
+ }).compileComponents();
42
+
43
+ fixture = TestBed.createComponent(TestHostComponent);
44
+ fixture.detectChanges();
45
+ });
46
+
47
+ it('should render accordion items', () => {
48
+ const items = fixture.nativeElement.querySelectorAll('[snyAccordionItem]');
49
+ expect(items.length).toBe(2);
50
+ });
51
+
52
+ it('should toggle item on trigger click', () => {
53
+ const trigger = fixture.nativeElement.querySelector('[snyAccordionTrigger]');
54
+ trigger.click();
55
+ fixture.detectChanges();
56
+ expect(trigger.getAttribute('aria-expanded')).toBe('true');
57
+ });
58
+
59
+ it('should close previous item in single mode', () => {
60
+ const triggers = fixture.nativeElement.querySelectorAll('[snyAccordionTrigger]');
61
+ triggers[0].click();
62
+ fixture.detectChanges();
63
+ expect(triggers[0].getAttribute('aria-expanded')).toBe('true');
64
+
65
+ triggers[1].click();
66
+ fixture.detectChanges();
67
+ expect(triggers[0].getAttribute('aria-expanded')).toBe('false');
68
+ expect(triggers[1].getAttribute('aria-expanded')).toBe('true');
69
+ });
70
+
71
+ it('should allow multiple open in multi mode', () => {
72
+ fixture.componentInstance.multi.set(true);
73
+ fixture.detectChanges();
74
+
75
+ const triggers = fixture.nativeElement.querySelectorAll('[snyAccordionTrigger]');
76
+ triggers[0].click();
77
+ fixture.detectChanges();
78
+ triggers[1].click();
79
+ fixture.detectChanges();
80
+
81
+ expect(triggers[0].getAttribute('aria-expanded')).toBe('true');
82
+ expect(triggers[1].getAttribute('aria-expanded')).toBe('true');
83
+ });
84
+
85
+ it('should apply content visibility classes', () => {
86
+ const content = fixture.nativeElement.querySelector('[snyAccordionContent]');
87
+ expect(content.className).toContain('grid-rows-[0fr]');
88
+
89
+ const trigger = fixture.nativeElement.querySelector('[snyAccordionTrigger]');
90
+ trigger.click();
91
+ fixture.detectChanges();
92
+
93
+ expect(content.className).toContain('grid-rows-[1fr]');
94
+ });
95
+
96
+ it('should move focus with ArrowDown', () => {
97
+ const triggers = fixture.nativeElement.querySelectorAll('[snyAccordionTrigger]');
98
+ (triggers[0] as HTMLElement).focus();
99
+ triggers[0].dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowDown', bubbles: true }));
100
+ fixture.detectChanges();
101
+ const updated = fixture.nativeElement.querySelectorAll('[snyAccordionTrigger]');
102
+ expect(document.activeElement).toBe(updated[1]);
103
+ });
104
+
105
+ it('should move focus with ArrowUp', () => {
106
+ const triggers = fixture.nativeElement.querySelectorAll('[snyAccordionTrigger]');
107
+ (triggers[1] as HTMLElement).focus();
108
+ triggers[1].dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowUp', bubbles: true }));
109
+ fixture.detectChanges();
110
+ const updated = fixture.nativeElement.querySelectorAll('[snyAccordionTrigger]');
111
+ expect(document.activeElement).toBe(updated[0]);
112
+ });
113
+
114
+ it('should move focus to first with Home', () => {
115
+ const triggers = fixture.nativeElement.querySelectorAll('[snyAccordionTrigger]');
116
+ (triggers[1] as HTMLElement).focus();
117
+ triggers[1].dispatchEvent(new KeyboardEvent('keydown', { key: 'Home', bubbles: true }));
118
+ fixture.detectChanges();
119
+ const updated = fixture.nativeElement.querySelectorAll('[snyAccordionTrigger]');
120
+ expect(document.activeElement).toBe(updated[0]);
121
+ });
122
+
123
+ it('should move focus to last with End', () => {
124
+ const triggers = fixture.nativeElement.querySelectorAll('[snyAccordionTrigger]');
125
+ (triggers[0] as HTMLElement).focus();
126
+ triggers[0].dispatchEvent(new KeyboardEvent('keydown', { key: 'End', bubbles: true }));
127
+ fixture.detectChanges();
128
+ const updated = fixture.nativeElement.querySelectorAll('[snyAccordionTrigger]');
129
+ expect(document.activeElement).toBe(updated[1]);
130
+ });
131
+ });
132
+
133
+ @Component({
134
+ standalone: true,
135
+ imports: [
136
+ SnyAccordionDirective,
137
+ SnyAccordionItemDirective,
138
+ SnyAccordionTriggerDirective,
139
+ SnyAccordionContentDirective,
140
+ ],
141
+ template: `
142
+ <div snyAccordion #a="snyAccordion">
143
+ <div snyAccordionItem #i="snyAccordionItem" value="item-1">
144
+ <button snyAccordionTrigger>Item 1</button>
145
+ <div snyAccordionContent><div>Content 1</div></div>
146
+ </div>
147
+ </div>
148
+ `,
149
+ })
150
+ class ExportAsHost {
151
+ accordion = viewChild<SnyAccordionDirective>('a');
152
+ item = viewChild<SnyAccordionItemDirective>('i');
153
+ }
154
+
155
+ describe('Accordion exportAs', () => {
156
+ it('should expose snyAccordion via template ref', async () => {
157
+ await TestBed.configureTestingModule({ imports: [ExportAsHost] }).compileComponents();
158
+ const fixture = TestBed.createComponent(ExportAsHost);
159
+ fixture.detectChanges();
160
+ const ref = fixture.componentInstance.accordion();
161
+ expect(ref).toBeTruthy();
162
+ expect(ref!.multi()).toBe(false);
163
+ });
164
+
165
+ it('should expose snyAccordionItem via template ref', async () => {
166
+ await TestBed.configureTestingModule({ imports: [ExportAsHost] }).compileComponents();
167
+ const fixture = TestBed.createComponent(ExportAsHost);
168
+ fixture.detectChanges();
169
+ const ref = fixture.componentInstance.item();
170
+ expect(ref).toBeTruthy();
171
+ expect(ref!.isOpen()).toBe(false);
172
+ });
173
+ });