@enya-learning/nova 0.4.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 (275) hide show
  1. package/Readme.md +418 -0
  2. package/changelog.md +44 -0
  3. package/components.json +23 -0
  4. package/dist/chunks/button-npy7isi3nsvlhf86.js +81 -0
  5. package/dist/chunks/button-npy7isi3nsvlhf86.js.map +1 -0
  6. package/dist/chunks/rolldown-runtime-fifbipqm1abz4ydz.js +30 -0
  7. package/dist/chunks/utils-kyb5nny4y41y7hd8.js +10 -0
  8. package/dist/chunks/utils-kyb5nny4y41y7hd8.js.map +1 -0
  9. package/dist/chunks/vendor-base-ui-efqwzv4oinwg1f0d.js +16049 -0
  10. package/dist/chunks/vendor-base-ui-efqwzv4oinwg1f0d.js.map +1 -0
  11. package/dist/chunks/vendor-styling-eeiy57tyznmxsfky.js +1744 -0
  12. package/dist/chunks/vendor-styling-eeiy57tyznmxsfky.js.map +1 -0
  13. package/dist/components/button.js +6 -0
  14. package/dist/components/enya-logo.js +191 -0
  15. package/dist/components/enya-logo.js.map +1 -0
  16. package/dist/index.js +23499 -0
  17. package/dist/index.js.map +1 -0
  18. package/dist/src/components/accordion/accordion.d.ts +6 -0
  19. package/dist/src/components/accordion/index.d.ts +1 -0
  20. package/dist/src/components/alert/alert.d.ts +10 -0
  21. package/dist/src/components/alert/index.d.ts +1 -0
  22. package/dist/src/components/alert-dialog/alert-dialog.d.ts +18 -0
  23. package/dist/src/components/alert-dialog/index.d.ts +1 -0
  24. package/dist/src/components/aspect-ratio/aspect-ratio.d.ts +4 -0
  25. package/dist/src/components/aspect-ratio/index.d.ts +1 -0
  26. package/dist/src/components/avatar/avatar.d.ts +11 -0
  27. package/dist/src/components/avatar/index.d.ts +1 -0
  28. package/dist/src/components/badge/badge.d.ts +7 -0
  29. package/dist/src/components/badge/index.d.ts +1 -0
  30. package/dist/src/components/breadcrumb/breadcrumb.d.ts +10 -0
  31. package/dist/src/components/breadcrumb/index.d.ts +1 -0
  32. package/dist/src/components/button/button.d.ts +8 -0
  33. package/dist/src/components/button/index.d.ts +1 -0
  34. package/dist/src/components/button-group/button-group.d.ts +10 -0
  35. package/dist/src/components/button-group/index.d.ts +1 -0
  36. package/dist/src/components/calendar/calendar.d.ts +10 -0
  37. package/dist/src/components/calendar/index.d.ts +1 -0
  38. package/dist/src/components/card/card.d.ts +11 -0
  39. package/dist/src/components/card/index.d.ts +1 -0
  40. package/dist/src/components/carousel/carousel.d.ts +28 -0
  41. package/dist/src/components/carousel/index.d.ts +1 -0
  42. package/dist/src/components/chart/chart.d.ts +44 -0
  43. package/dist/src/components/chart/index.d.ts +1 -0
  44. package/dist/src/components/checkbox/checkbox.d.ts +3 -0
  45. package/dist/src/components/checkbox/index.d.ts +1 -0
  46. package/dist/src/components/collapsible/collapsible.d.ts +5 -0
  47. package/dist/src/components/collapsible/index.d.ts +1 -0
  48. package/dist/src/components/combobox/combobox.d.ts +24 -0
  49. package/dist/src/components/combobox/index.d.ts +1 -0
  50. package/dist/src/components/command/command.d.ts +19 -0
  51. package/dist/src/components/command/index.d.ts +1 -0
  52. package/dist/src/components/context-menu/context-menu.d.ts +29 -0
  53. package/dist/src/components/context-menu/index.d.ts +1 -0
  54. package/dist/src/components/dialog/dialog.d.ts +17 -0
  55. package/dist/src/components/dialog/index.d.ts +1 -0
  56. package/dist/src/components/direction/direction.d.ts +1 -0
  57. package/dist/src/components/direction/index.d.ts +1 -0
  58. package/dist/src/components/drawer/drawer.d.ts +13 -0
  59. package/dist/src/components/drawer/index.d.ts +1 -0
  60. package/dist/src/components/dropdown-menu/dropdown-menu.d.ts +29 -0
  61. package/dist/src/components/dropdown-menu/index.d.ts +1 -0
  62. package/dist/src/components/empty/empty.d.ts +11 -0
  63. package/dist/src/components/empty/index.d.ts +1 -0
  64. package/dist/src/components/enya-logo/enya-logo.d.ts +121 -0
  65. package/dist/src/components/enya-logo/index.d.ts +1 -0
  66. package/dist/src/components/field/field.d.ts +24 -0
  67. package/dist/src/components/field/index.d.ts +1 -0
  68. package/dist/src/components/hover-card/hover-card.d.ts +5 -0
  69. package/dist/src/components/hover-card/index.d.ts +1 -0
  70. package/dist/src/components/input/index.d.ts +1 -0
  71. package/dist/src/components/input/input.d.ts +3 -0
  72. package/dist/src/components/input-group/index.d.ts +1 -0
  73. package/dist/src/components/input-group/input-group.d.ts +18 -0
  74. package/dist/src/components/input-otp/index.d.ts +1 -0
  75. package/dist/src/components/input-otp/input-otp.d.ts +11 -0
  76. package/dist/src/components/item/index.d.ts +1 -0
  77. package/dist/src/components/item/item.d.ts +22 -0
  78. package/dist/src/components/kbd/index.d.ts +1 -0
  79. package/dist/src/components/kbd/kbd.d.ts +3 -0
  80. package/dist/src/components/label/index.d.ts +1 -0
  81. package/dist/src/components/label/label.d.ts +3 -0
  82. package/dist/src/components/menubar/index.d.ts +1 -0
  83. package/dist/src/components/menubar/menubar.d.ts +29 -0
  84. package/dist/src/components/native-select/index.d.ts +1 -0
  85. package/dist/src/components/native-select/native-select.d.ts +8 -0
  86. package/dist/src/components/navigation-menu/index.d.ts +1 -0
  87. package/dist/src/components/navigation-menu/navigation-menu.d.ts +11 -0
  88. package/dist/src/components/pagination/index.d.ts +1 -0
  89. package/dist/src/components/pagination/pagination.d.ts +17 -0
  90. package/dist/src/components/popover/index.d.ts +1 -0
  91. package/dist/src/components/popover/popover.d.ts +9 -0
  92. package/dist/src/components/progress/index.d.ts +1 -0
  93. package/dist/src/components/progress/progress.d.ts +7 -0
  94. package/dist/src/components/radio-group/index.d.ts +1 -0
  95. package/dist/src/components/radio-group/radio-group.d.ts +5 -0
  96. package/dist/src/components/resizable/index.d.ts +1 -0
  97. package/dist/src/components/resizable/resizable.d.ts +7 -0
  98. package/dist/src/components/scroll-area/index.d.ts +1 -0
  99. package/dist/src/components/scroll-area/scroll-area.d.ts +4 -0
  100. package/dist/src/components/select/index.d.ts +1 -0
  101. package/dist/src/components/select/select.d.ts +15 -0
  102. package/dist/src/components/separator/index.d.ts +1 -0
  103. package/dist/src/components/separator/separator.d.ts +3 -0
  104. package/dist/src/components/sheet/index.d.ts +1 -0
  105. package/dist/src/components/sheet/sheet.d.ts +14 -0
  106. package/dist/src/components/sidebar/index.d.ts +1 -0
  107. package/dist/src/components/sidebar/sidebar.d.ts +63 -0
  108. package/dist/src/components/skeleton/index.d.ts +1 -0
  109. package/dist/src/components/skeleton/skeleton.d.ts +2 -0
  110. package/dist/src/components/slider/index.d.ts +1 -0
  111. package/dist/src/components/slider/slider.d.ts +3 -0
  112. package/dist/src/components/sonner/index.d.ts +1 -0
  113. package/dist/src/components/sonner/sonner.d.ts +3 -0
  114. package/dist/src/components/spinner/index.d.ts +1 -0
  115. package/dist/src/components/spinner/spinner.d.ts +2 -0
  116. package/dist/src/components/switch/index.d.ts +1 -0
  117. package/dist/src/components/switch/switch.d.ts +5 -0
  118. package/dist/src/components/table/index.d.ts +1 -0
  119. package/dist/src/components/table/table.d.ts +10 -0
  120. package/dist/src/components/tabs/index.d.ts +1 -0
  121. package/dist/src/components/tabs/tabs.d.ts +10 -0
  122. package/dist/src/components/textarea/index.d.ts +1 -0
  123. package/dist/src/components/textarea/textarea.d.ts +3 -0
  124. package/dist/src/components/toggle/index.d.ts +1 -0
  125. package/dist/src/components/toggle/toggle.d.ts +8 -0
  126. package/dist/src/components/toggle-group/index.d.ts +1 -0
  127. package/dist/src/components/toggle-group/toggle-group.d.ts +10 -0
  128. package/dist/src/components/tooltip/index.d.ts +1 -0
  129. package/dist/src/components/tooltip/tooltip.d.ts +6 -0
  130. package/dist/src/hooks/use-mobile.d.ts +1 -0
  131. package/dist/src/index.d.ts +57 -0
  132. package/dist/src/lib/utils.d.ts +2 -0
  133. package/dist/src/utils/index.d.ts +1 -0
  134. package/dist/styles/nova-binding.css +290 -0
  135. package/dist/styles/nova.css +58 -0
  136. package/dist/styles/theme-nova.css +201 -0
  137. package/dist/styles/typography.css +215 -0
  138. package/dist/utils.js +5 -0
  139. package/eslint.config.js +30 -0
  140. package/package.json +94 -0
  141. package/plopfile.mjs +49 -0
  142. package/src/components/.gitkeep +0 -0
  143. package/src/components/accordion/accordion.mdx +83 -0
  144. package/src/components/accordion/accordion.tsx +81 -0
  145. package/src/components/accordion/index.ts +1 -0
  146. package/src/components/alert/alert.tsx +76 -0
  147. package/src/components/alert/index.ts +1 -0
  148. package/src/components/alert-dialog/alert-dialog.tsx +187 -0
  149. package/src/components/alert-dialog/index.ts +1 -0
  150. package/src/components/aspect-ratio/aspect-ratio.tsx +22 -0
  151. package/src/components/aspect-ratio/index.ts +1 -0
  152. package/src/components/avatar/avatar.tsx +107 -0
  153. package/src/components/avatar/index.ts +1 -0
  154. package/src/components/badge/badge.tsx +52 -0
  155. package/src/components/badge/index.ts +1 -0
  156. package/src/components/breadcrumb/breadcrumb.tsx +122 -0
  157. package/src/components/breadcrumb/index.ts +1 -0
  158. package/src/components/button/button.mdx +255 -0
  159. package/src/components/button/button.tsx +59 -0
  160. package/src/components/button/index.ts +1 -0
  161. package/src/components/button-group/button-group.tsx +87 -0
  162. package/src/components/button-group/index.ts +1 -0
  163. package/src/components/calendar/calendar.tsx +228 -0
  164. package/src/components/calendar/index.ts +1 -0
  165. package/src/components/card/card.tsx +100 -0
  166. package/src/components/card/index.ts +1 -0
  167. package/src/components/carousel/carousel.tsx +243 -0
  168. package/src/components/carousel/index.ts +1 -0
  169. package/src/components/chart/chart.tsx +371 -0
  170. package/src/components/chart/index.ts +1 -0
  171. package/src/components/checkbox/checkbox.tsx +28 -0
  172. package/src/components/checkbox/index.ts +1 -0
  173. package/src/components/collapsible/collapsible.tsx +19 -0
  174. package/src/components/collapsible/index.ts +1 -0
  175. package/src/components/combobox/combobox.tsx +298 -0
  176. package/src/components/combobox/index.ts +1 -0
  177. package/src/components/command/command.tsx +193 -0
  178. package/src/components/command/index.ts +1 -0
  179. package/src/components/context-menu/context-menu.tsx +272 -0
  180. package/src/components/context-menu/index.ts +1 -0
  181. package/src/components/dialog/dialog.tsx +157 -0
  182. package/src/components/dialog/index.ts +1 -0
  183. package/src/components/direction/direction.tsx +4 -0
  184. package/src/components/direction/index.ts +1 -0
  185. package/src/components/drawer/drawer.tsx +134 -0
  186. package/src/components/drawer/index.ts +1 -0
  187. package/src/components/dropdown-menu/dropdown-menu.tsx +270 -0
  188. package/src/components/dropdown-menu/index.ts +1 -0
  189. package/src/components/empty/empty.tsx +104 -0
  190. package/src/components/empty/index.ts +1 -0
  191. package/src/components/enya-logo/enya-logo.mdx +174 -0
  192. package/src/components/enya-logo/enya-logo.tsx +383 -0
  193. package/src/components/enya-logo/index.ts +1 -0
  194. package/src/components/field/field.tsx +236 -0
  195. package/src/components/field/index.ts +1 -0
  196. package/src/components/hover-card/hover-card.tsx +51 -0
  197. package/src/components/hover-card/index.ts +1 -0
  198. package/src/components/input/index.ts +1 -0
  199. package/src/components/input/input.tsx +20 -0
  200. package/src/components/input-group/index.ts +1 -0
  201. package/src/components/input-group/input-group.tsx +157 -0
  202. package/src/components/input-otp/index.ts +1 -0
  203. package/src/components/input-otp/input-otp.tsx +84 -0
  204. package/src/components/item/index.ts +1 -0
  205. package/src/components/item/item.tsx +201 -0
  206. package/src/components/kbd/index.ts +1 -0
  207. package/src/components/kbd/kbd.tsx +26 -0
  208. package/src/components/label/index.ts +1 -0
  209. package/src/components/label/label.tsx +20 -0
  210. package/src/components/menubar/index.ts +1 -0
  211. package/src/components/menubar/menubar.tsx +281 -0
  212. package/src/components/native-select/index.ts +1 -0
  213. package/src/components/native-select/native-select.tsx +65 -0
  214. package/src/components/navigation-menu/index.ts +1 -0
  215. package/src/components/navigation-menu/navigation-menu.tsx +171 -0
  216. package/src/components/pagination/index.ts +1 -0
  217. package/src/components/pagination/pagination.tsx +133 -0
  218. package/src/components/popover/index.ts +1 -0
  219. package/src/components/popover/popover.tsx +88 -0
  220. package/src/components/progress/index.ts +1 -0
  221. package/src/components/progress/progress.tsx +83 -0
  222. package/src/components/radio-group/index.ts +1 -0
  223. package/src/components/radio-group/radio-group.tsx +36 -0
  224. package/src/components/resizable/index.ts +1 -0
  225. package/src/components/resizable/resizable.tsx +50 -0
  226. package/src/components/scroll-area/index.ts +1 -0
  227. package/src/components/scroll-area/scroll-area.tsx +53 -0
  228. package/src/components/select/index.ts +1 -0
  229. package/src/components/select/select.tsx +205 -0
  230. package/src/components/separator/index.ts +1 -0
  231. package/src/components/separator/separator.tsx +23 -0
  232. package/src/components/sheet/index.ts +1 -0
  233. package/src/components/sheet/sheet.tsx +137 -0
  234. package/src/components/sidebar/index.ts +1 -0
  235. package/src/components/sidebar/sidebar.tsx +722 -0
  236. package/src/components/skeleton/index.ts +1 -0
  237. package/src/components/skeleton/skeleton.tsx +13 -0
  238. package/src/components/slider/index.ts +1 -0
  239. package/src/components/slider/slider.tsx +52 -0
  240. package/src/components/sonner/index.ts +1 -0
  241. package/src/components/sonner/sonner.tsx +45 -0
  242. package/src/components/spinner/index.ts +1 -0
  243. package/src/components/spinner/spinner.tsx +15 -0
  244. package/src/components/switch/index.ts +1 -0
  245. package/src/components/switch/switch.tsx +30 -0
  246. package/src/components/table/index.ts +1 -0
  247. package/src/components/table/table.tsx +116 -0
  248. package/src/components/tabs/index.ts +1 -0
  249. package/src/components/tabs/tabs.tsx +80 -0
  250. package/src/components/textarea/index.ts +1 -0
  251. package/src/components/textarea/textarea.tsx +18 -0
  252. package/src/components/toggle/index.ts +1 -0
  253. package/src/components/toggle/toggle.tsx +45 -0
  254. package/src/components/toggle-group/index.ts +1 -0
  255. package/src/components/toggle-group/toggle-group.tsx +87 -0
  256. package/src/components/tooltip/index.ts +1 -0
  257. package/src/components/tooltip/tooltip.tsx +64 -0
  258. package/src/eslint/index.js +13 -0
  259. package/src/eslint/no-primitive-colors.js +158 -0
  260. package/src/hooks/use-mobile.ts +21 -0
  261. package/src/index.ts +58 -0
  262. package/src/lib/.gitkeep +0 -0
  263. package/src/lib/utils.ts +6 -0
  264. package/src/styles/globals.css +77 -0
  265. package/src/styles/nova-binding.css +290 -0
  266. package/src/styles/nova.css +58 -0
  267. package/src/styles/theme-nova.css +201 -0
  268. package/src/styles/typography.css +215 -0
  269. package/src/utils/index.ts +1 -0
  270. package/templates/component/component.tsx.hbs +16 -0
  271. package/templates/component/index.ts.hbs +1 -0
  272. package/templates/component/stories.tsx.hbs +13 -0
  273. package/tsconfig.json +18 -0
  274. package/tsconfig.lint.json +14 -0
  275. package/vite.config.ts +101 -0
@@ -0,0 +1,215 @@
1
+ /* Geist-style typography utilities.
2
+ Each class pre-sets font-size, line-height, letter-spacing, and font-weight.
3
+ All classes work with Tailwind variants: md:text-heading-32, hover:text-label-14, etc. */
4
+
5
+ /* ─── Headings ─────────────────────────────────────────────────────────────── */
6
+
7
+ @utility text-heading-72 {
8
+ font-size: 4.5rem;
9
+ line-height: 4.5rem;
10
+ letter-spacing: -0.02em;
11
+ font-weight: 600;
12
+ }
13
+
14
+ @utility text-heading-64 {
15
+ font-size: 4rem;
16
+ line-height: 4rem;
17
+ letter-spacing: -0.02em;
18
+ font-weight: 600;
19
+ }
20
+
21
+ @utility text-heading-56 {
22
+ font-size: 3.5rem;
23
+ line-height: 3.5rem;
24
+ letter-spacing: -0.02em;
25
+ font-weight: 600;
26
+ }
27
+
28
+ @utility text-heading-48 {
29
+ font-size: 3rem;
30
+ line-height: 3.5rem;
31
+ letter-spacing: -0.02em;
32
+ font-weight: 600;
33
+ }
34
+
35
+ @utility text-heading-40 {
36
+ font-size: 2.5rem;
37
+ line-height: 3rem;
38
+ letter-spacing: -0.02em;
39
+ font-weight: 600;
40
+ }
41
+
42
+ @utility text-heading-32 {
43
+ font-size: 2rem;
44
+ line-height: 2.5rem;
45
+ letter-spacing: -0.02em;
46
+ font-weight: 600;
47
+ }
48
+
49
+ @utility text-heading-24 {
50
+ font-size: 1.5rem;
51
+ line-height: 2rem;
52
+ letter-spacing: -0.02em;
53
+ font-weight: 600;
54
+ }
55
+
56
+ @utility text-heading-20 {
57
+ font-size: 1.25rem;
58
+ line-height: 1.625;
59
+ letter-spacing: -0.02em;
60
+ font-weight: 600;
61
+ }
62
+
63
+ @utility text-heading-16 {
64
+ font-size: 1rem;
65
+ line-height: 1.5;
66
+ letter-spacing: -0.02em;
67
+ font-weight: 600;
68
+ }
69
+
70
+ @utility text-heading-14 {
71
+ font-size: 0.875rem;
72
+ line-height: 1.25;
73
+ font-weight: 600;
74
+ }
75
+
76
+ /* ─── Buttons ──────────────────────────────────────────────────────────────── */
77
+
78
+ @utility text-button-16 {
79
+ font-size: 1rem;
80
+ line-height: 1.5;
81
+ letter-spacing: -0.01em;
82
+ font-weight: 500;
83
+ }
84
+
85
+ @utility text-button-14 {
86
+ font-size: 0.875rem;
87
+ line-height: 1.4286;
88
+ letter-spacing: -0.01em;
89
+ font-weight: 500;
90
+ }
91
+
92
+ @utility text-button-12 {
93
+ font-size: 0.75rem;
94
+ line-height: 1.3333;
95
+ letter-spacing: 0;
96
+ font-weight: 500;
97
+ }
98
+
99
+ /* ─── Labels ───────────────────────────────────────────────────────────────── */
100
+
101
+ @utility text-label-20 {
102
+ font-size: 1.25rem;
103
+ line-height: 1.4;
104
+ letter-spacing: -0.01em;
105
+ font-weight: 500;
106
+ }
107
+
108
+ @utility text-label-18 {
109
+ font-size: 1.125rem;
110
+ line-height: 1.3333;
111
+ letter-spacing: -0.01em;
112
+ font-weight: 500;
113
+ }
114
+
115
+ @utility text-label-16 {
116
+ font-size: 1rem;
117
+ line-height: 1.5;
118
+ letter-spacing: -0.01em;
119
+ font-weight: 500;
120
+ }
121
+
122
+ @utility text-label-14 {
123
+ font-size: 0.875rem;
124
+ line-height: 1.4286;
125
+ letter-spacing: -0.01em;
126
+ font-weight: 500;
127
+ }
128
+
129
+ @utility text-label-14-mono {
130
+ font-size: 0.875rem;
131
+ line-height: 1.4286;
132
+ letter-spacing: 0;
133
+ font-weight: 500;
134
+ font-family: var(--font-mono);
135
+ }
136
+
137
+ @utility text-label-13 {
138
+ font-size: 0.8125rem;
139
+ line-height: 1.2308;
140
+ letter-spacing: 0;
141
+ font-weight: 500;
142
+ }
143
+
144
+ @utility text-label-13-mono {
145
+ font-size: 0.8125rem;
146
+ line-height: 1.2308;
147
+ letter-spacing: 0;
148
+ font-weight: 500;
149
+ font-family: var(--font-mono);
150
+ }
151
+
152
+ @utility text-label-12 {
153
+ font-size: 0.75rem;
154
+ line-height: 1.3333;
155
+ letter-spacing: 0;
156
+ font-weight: 500;
157
+ }
158
+
159
+ @utility text-label-12-mono {
160
+ font-size: 0.75rem;
161
+ line-height: 1.3333;
162
+ letter-spacing: 0;
163
+ font-weight: 500;
164
+ font-family: var(--font-mono);
165
+ }
166
+
167
+ /* ─── Copy ─────────────────────────────────────────────────────────────────── */
168
+
169
+ @utility text-copy-24 {
170
+ font-size: 1.5rem;
171
+ line-height: 1.6667;
172
+ font-weight: 400;
173
+ }
174
+
175
+ @utility text-copy-20 {
176
+ font-size: 1.25rem;
177
+ line-height: 1.6;
178
+ font-weight: 400;
179
+ }
180
+
181
+ @utility text-copy-18 {
182
+ font-size: 1.125rem;
183
+ line-height: 1.5556;
184
+ font-weight: 400;
185
+ }
186
+
187
+ @utility text-copy-16 {
188
+ font-size: 1rem;
189
+ line-height: 1.625;
190
+ font-weight: 400;
191
+ }
192
+
193
+ @utility text-copy-14 {
194
+ font-size: 0.875rem;
195
+ line-height: 1.7143;
196
+ font-weight: 400;
197
+ }
198
+
199
+ @utility text-copy-13 {
200
+ font-size: 0.8125rem;
201
+ line-height: 1.5385;
202
+ font-weight: 400;
203
+ }
204
+
205
+ @utility text-copy-13-mono {
206
+ font-size: 0.8125rem;
207
+ line-height: 1.5385;
208
+ font-weight: 400;
209
+ font-family: var(--font-mono);
210
+ }
211
+ @utility text-copy-12 {
212
+ font-size: 0.75rem;
213
+ line-height: 150%;
214
+ font-weight: 400;
215
+ }
package/dist/utils.js ADDED
@@ -0,0 +1,5 @@
1
+ "use client";
2
+ import { t as e } from "./chunks/utils-kyb5nny4y41y7hd8.js";
3
+ export {
4
+ e as cn
5
+ };
@@ -0,0 +1,30 @@
1
+ import js from "@eslint/js"
2
+ import globals from "globals"
3
+ import reactHooks from "eslint-plugin-react-hooks"
4
+ import reactRefresh from "eslint-plugin-react-refresh"
5
+ import tseslint from "typescript-eslint"
6
+ import { defineConfig, globalIgnores } from "eslint/config"
7
+ import eslintConfigPrettier from "eslint-config-prettier"
8
+ import novaPlugin from "./src/eslint/index.js"
9
+
10
+ export default defineConfig([
11
+ globalIgnores(["dist"]),
12
+ {
13
+ files: ["**/*.{ts,tsx}"],
14
+ extends: [
15
+ js.configs.recommended,
16
+ tseslint.configs.recommended,
17
+ reactHooks.configs.flat.recommended,
18
+ reactRefresh.configs.vite,
19
+ eslintConfigPrettier,
20
+ ],
21
+ plugins: { nova: novaPlugin },
22
+ languageOptions: {
23
+ globals: globals.browser,
24
+ },
25
+ rules: {
26
+ "react-refresh/only-export-components": "off",
27
+ "nova/no-primitive-colors": "error",
28
+ },
29
+ },
30
+ ])
package/package.json ADDED
@@ -0,0 +1,94 @@
1
+ {
2
+ "name": "@enya-learning/nova",
3
+ "version": "0.4.0",
4
+ "type": "module",
5
+ "private": false,
6
+ "publishConfig": {
7
+ "access": "public"
8
+ },
9
+ "dependencies": {
10
+ "@base-ui/react": "^1.5.0",
11
+ "@fontsource-variable/geist-mono": "^5.2.8",
12
+ "@fontsource-variable/inter": "^5.2.8",
13
+ "class-variance-authority": "^0.7.1",
14
+ "clsx": "^2.1.1",
15
+ "cmdk": "^1.1.1",
16
+ "date-fns": "^4.4.0",
17
+ "embla-carousel-react": "^8.6.0",
18
+ "input-otp": "^1.4.2",
19
+ "next-themes": "^0.4.6",
20
+ "react-day-picker": "^10.0.1",
21
+ "react-resizable-panels": "^4.11.2",
22
+ "recharts": "3.8.0",
23
+ "sonner": "^2.0.7",
24
+ "tailwind-merge": "^3.6.0",
25
+ "tw-animate-css": "^1.4.0",
26
+ "vaul": "^1.1.2",
27
+ "zod": "^4.4.3"
28
+ },
29
+ "peerDependencies": {
30
+ "lucide-react": "^1.17.0",
31
+ "react": "^19.2.6",
32
+ "react-dom": "^19.2.6"
33
+ },
34
+ "devDependencies": {
35
+ "@eslint/js": "^10",
36
+ "@storybook/addon-a11y": "^10.4.2",
37
+ "@storybook/addon-docs": "^10.4.2",
38
+ "@storybook/addon-themes": "^10.4.2",
39
+ "@storybook/react": "^10.4.2",
40
+ "@storybook/react-vite": "^10.4.2",
41
+ "@tailwindcss/vite": "^4",
42
+ "@turbo/gen": "^2.9.15",
43
+ "@types/node": "^24",
44
+ "@types/react": "^19",
45
+ "@types/react-dom": "^19",
46
+ "@vitejs/plugin-react": "^6.0.2",
47
+ "@vitest/ui": "^4.1.8",
48
+ "eslint": "^10",
49
+ "eslint-plugin-react-hooks": "^7.1.1",
50
+ "eslint-plugin-react-refresh": "^0.5.2",
51
+ "globals": "^17",
52
+ "plop": "^4.0.0",
53
+ "react-docgen-typescript": "^2.4.0",
54
+ "shadcn": "^4.10.0",
55
+ "storybook": "^10.4.2",
56
+ "tailwindcss": "^4",
57
+ "tsx": "^4.22.4",
58
+ "typescript": "~6",
59
+ "typescript-eslint": "^8",
60
+ "vite": "^8.0.16",
61
+ "vite-plugin-dts": "^5.0.2",
62
+ "vitest": "^4.1.8"
63
+ },
64
+ "exports": {
65
+ ".": "./src/index.ts",
66
+ "./styles/tailwind": "./src/styles/nova.css",
67
+ "./styles": "./src/styles/nova.css",
68
+ "./globals.css": "./src/styles/globals.css",
69
+ "./lib/*": "./src/lib/*.ts",
70
+ "./components/*": "./src/components/*/index.ts",
71
+ "./hooks/*": "./src/hooks/*.ts",
72
+ "./utils": "./src/utils/index.ts",
73
+ "./eslint": "./src/eslint/index.js"
74
+ },
75
+ "main": "./src/index.ts",
76
+ "types": "./src/index.ts",
77
+ "sideEffects": [
78
+ "*.css"
79
+ ],
80
+ "scripts": {
81
+ "build": "vite build --mode production && tsx scripts/css-build.ts",
82
+ "dev": "vite build --watch --mode development",
83
+ "clean": "rm -rf dist",
84
+ "lint": "eslint",
85
+ "format": "prettier --write \"**/*.{ts,tsx}\" --ignore-path ../../.prettierignore",
86
+ "typecheck": "tsc --noEmit",
87
+ "test": "vitest run",
88
+ "test:watch": "vitest",
89
+ "storybook": "storybook dev -p 6006",
90
+ "storybook:build": "storybook build",
91
+ "generate-docs": "tsx scripts/generate-docs.ts",
92
+ "new-component": "plop component"
93
+ }
94
+ }
package/plopfile.mjs ADDED
@@ -0,0 +1,49 @@
1
+ export default function (plop) {
2
+ plop.setGenerator("component", {
3
+ description: "Scaffold a new Nova component",
4
+ prompts: [
5
+ {
6
+ type: "input",
7
+ name: "name",
8
+ message: "Component name (e.g. Button, DatePicker):",
9
+ validate: (value) =>
10
+ value.trim().length > 0 ? true : "Component name is required",
11
+ },
12
+ ],
13
+ actions: [
14
+ {
15
+ type: "add",
16
+ path: "src/components/{{kebabCase name}}/{{kebabCase name}}.tsx",
17
+ templateFile: "templates/component/component.tsx.hbs",
18
+ },
19
+ {
20
+ type: "add",
21
+ path: "src/components/{{kebabCase name}}/index.ts",
22
+ templateFile: "templates/component/index.ts.hbs",
23
+ },
24
+ {
25
+ type: "add",
26
+ path: "src/components/{{kebabCase name}}/{{kebabCase name}}.stories.tsx",
27
+ templateFile: "templates/component/stories.tsx.hbs",
28
+ },
29
+ {
30
+ type: "modify",
31
+ path: "src/index.ts",
32
+ pattern: /(export \* from "\.\/utils")/,
33
+ template: 'export * from "./components/{{kebabCase name}}"\n$1',
34
+ },
35
+ {
36
+ type: "modify",
37
+ path: "vite.config.ts",
38
+ pattern: / \/\/ ADD_COMPONENT_ENTRY_HERE/,
39
+ template: [
40
+ ' "components/{{kebabCase name}}": resolve(',
41
+ " __dirname,",
42
+ ' "src/components/{{kebabCase name}}/index.ts"',
43
+ " ),",
44
+ " // ADD_COMPONENT_ENTRY_HERE",
45
+ ].join("\n"),
46
+ },
47
+ ],
48
+ })
49
+ }
File without changes
@@ -0,0 +1,83 @@
1
+ ---
2
+ title: Accordion
3
+ description: A vertically stacked set of interactive headings that each reveal a section of content.
4
+ ---
5
+
6
+ import { Meta, Canvas, Controls } from '@storybook/blocks';
7
+ import * as AccordionStories from './accordion.stories';
8
+
9
+ <Meta of={AccordionStories} />
10
+
11
+ # Accordion
12
+
13
+ A vertically stacked set of interactive headings that each reveal a section of content. Follows the WAI-ARIA Disclosure pattern.
14
+
15
+ ## Usage
16
+
17
+ ```tsx
18
+ import {
19
+ Accordion,
20
+ AccordionContent,
21
+ AccordionItem,
22
+ AccordionTrigger,
23
+ } from "@enya-learning/nova/components/accordion";
24
+
25
+ export default function Example() {
26
+ return (
27
+ <Accordion className="w-80">
28
+ <AccordionItem value="item-1">
29
+ <AccordionTrigger>Is it accessible?</AccordionTrigger>
30
+ <AccordionContent>Yes. It adheres to the WAI-ARIA design pattern.</AccordionContent>
31
+ </AccordionItem>
32
+ </Accordion>
33
+ );
34
+ }
35
+ ```
36
+
37
+ ## Examples
38
+
39
+ ### Single (default)
40
+
41
+ Only one item can be open at a time. Opening a new item collapses the previous one.
42
+
43
+ ```tsx
44
+ <Accordion className="w-80">
45
+ <AccordionItem value="item-1">
46
+ <AccordionTrigger>Is it accessible?</AccordionTrigger>
47
+ <AccordionContent>Yes. It adheres to the WAI-ARIA design pattern.</AccordionContent>
48
+ </AccordionItem>
49
+ <AccordionItem value="item-2">
50
+ <AccordionTrigger>Is it styled?</AccordionTrigger>
51
+ <AccordionContent>Yes. It comes with default styles that match the other components.</AccordionContent>
52
+ </AccordionItem>
53
+ <AccordionItem value="item-3">
54
+ <AccordionTrigger>Is it animated?</AccordionTrigger>
55
+ <AccordionContent>Yes. It's animated by default, but you can disable it if you prefer.</AccordionContent>
56
+ </AccordionItem>
57
+ </Accordion>
58
+ ```
59
+
60
+ <Canvas of={AccordionStories.Single} />
61
+
62
+ ### Multiple
63
+
64
+ Add `multiple` to allow multiple items to be open simultaneously.
65
+
66
+ ```tsx
67
+ <Accordion multiple className="w-80">
68
+ <AccordionItem value="item-1">
69
+ <AccordionTrigger>Section one</AccordionTrigger>
70
+ <AccordionContent>Content for the first section. Multiple can be open at once.</AccordionContent>
71
+ </AccordionItem>
72
+ <AccordionItem value="item-2">
73
+ <AccordionTrigger>Section two</AccordionTrigger>
74
+ <AccordionContent>Content for the second section.</AccordionContent>
75
+ </AccordionItem>
76
+ </Accordion>
77
+ ```
78
+
79
+ <Canvas of={AccordionStories.Multiple} />
80
+
81
+ ## API Reference
82
+
83
+ <Controls of={AccordionStories.Single} />
@@ -0,0 +1,81 @@
1
+ import { Accordion as AccordionPrimitive } from "@base-ui/react/accordion"
2
+
3
+ import { cn } from "../../lib/utils"
4
+ import { ChevronDownIcon, ChevronUpIcon } from "lucide-react"
5
+
6
+ function Accordion({ className, ...props }: AccordionPrimitive.Root.Props) {
7
+ return (
8
+ <AccordionPrimitive.Root
9
+ data-slot="accordion"
10
+ className={cn(
11
+ "flex w-full flex-col overflow-hidden rounded-2xl border",
12
+ className
13
+ )}
14
+ {...props}
15
+ />
16
+ )
17
+ }
18
+
19
+ function AccordionItem({ className, ...props }: AccordionPrimitive.Item.Props) {
20
+ return (
21
+ <AccordionPrimitive.Item
22
+ data-slot="accordion-item"
23
+ className={cn("not-last:border-b data-open:bg-muted/50", className)}
24
+ {...props}
25
+ />
26
+ )
27
+ }
28
+
29
+ function AccordionTrigger({
30
+ className,
31
+ children,
32
+ ...props
33
+ }: AccordionPrimitive.Trigger.Props) {
34
+ return (
35
+ <AccordionPrimitive.Header className="flex">
36
+ <AccordionPrimitive.Trigger
37
+ data-slot="accordion-trigger"
38
+ className={cn(
39
+ "group/accordion-trigger relative flex flex-1 items-start justify-between gap-6 border border-transparent p-4 text-start text-sm font-medium transition-all outline-none hover:underline aria-disabled:pointer-events-none aria-disabled:opacity-50 **:data-[slot=accordion-trigger-icon]:ms-auto **:data-[slot=accordion-trigger-icon]:size-4 **:data-[slot=accordion-trigger-icon]:text-muted-foreground",
40
+ className
41
+ )}
42
+ {...props}
43
+ >
44
+ {children}
45
+ <ChevronDownIcon
46
+ data-slot="accordion-trigger-icon"
47
+ className="pointer-events-none shrink-0 group-aria-expanded/accordion-trigger:hidden"
48
+ />
49
+ <ChevronUpIcon
50
+ data-slot="accordion-trigger-icon"
51
+ className="pointer-events-none hidden shrink-0 group-aria-expanded/accordion-trigger:inline"
52
+ />
53
+ </AccordionPrimitive.Trigger>
54
+ </AccordionPrimitive.Header>
55
+ )
56
+ }
57
+
58
+ function AccordionContent({
59
+ className,
60
+ children,
61
+ ...props
62
+ }: AccordionPrimitive.Panel.Props) {
63
+ return (
64
+ <AccordionPrimitive.Panel
65
+ data-slot="accordion-content"
66
+ className="overflow-hidden px-4 text-sm data-open:animate-accordion-down data-closed:animate-accordion-up"
67
+ {...props}
68
+ >
69
+ <div
70
+ className={cn(
71
+ "h-(--accordion-panel-height) pt-0 pb-4 data-ending-style:h-0 data-starting-style:h-0 [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground [&_p:not(:last-child)]:mb-4",
72
+ className
73
+ )}
74
+ >
75
+ {children}
76
+ </div>
77
+ </AccordionPrimitive.Panel>
78
+ )
79
+ }
80
+
81
+ export { Accordion, AccordionItem, AccordionTrigger, AccordionContent }
@@ -0,0 +1 @@
1
+ export * from "./accordion"
@@ -0,0 +1,76 @@
1
+ import * as React from "react"
2
+ import { cva, type VariantProps } from "class-variance-authority"
3
+
4
+ import { cn } from "../../lib/utils"
5
+
6
+ const alertVariants = cva(
7
+ "group/alert relative grid w-full gap-0.5 rounded-lg border px-4 py-3 text-start text-sm has-data-[slot=alert-action]:relative has-data-[slot=alert-action]:pe-18 has-[>svg]:grid-cols-[auto_1fr] has-[>svg]:gap-x-2.5 *:[svg]:row-span-2 *:[svg]:translate-y-0.5 *:[svg]:text-current *:[svg:not([class*='size-'])]:size-4",
8
+ {
9
+ variants: {
10
+ variant: {
11
+ default: "bg-card text-card-foreground",
12
+ destructive:
13
+ "bg-card text-destructive *:data-[slot=alert-description]:text-destructive/90 *:[svg]:text-current",
14
+ },
15
+ },
16
+ defaultVariants: {
17
+ variant: "default",
18
+ },
19
+ }
20
+ )
21
+
22
+ function Alert({
23
+ className,
24
+ variant,
25
+ ...props
26
+ }: React.ComponentProps<"div"> & VariantProps<typeof alertVariants>) {
27
+ return (
28
+ <div
29
+ data-slot="alert"
30
+ role="alert"
31
+ className={cn(alertVariants({ variant }), className)}
32
+ {...props}
33
+ />
34
+ )
35
+ }
36
+
37
+ function AlertTitle({ className, ...props }: React.ComponentProps<"div">) {
38
+ return (
39
+ <div
40
+ data-slot="alert-title"
41
+ className={cn(
42
+ "font-medium group-has-[>svg]/alert:col-start-2 [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground",
43
+ className
44
+ )}
45
+ {...props}
46
+ />
47
+ )
48
+ }
49
+
50
+ function AlertDescription({
51
+ className,
52
+ ...props
53
+ }: React.ComponentProps<"div">) {
54
+ return (
55
+ <div
56
+ data-slot="alert-description"
57
+ className={cn(
58
+ "text-sm text-balance text-muted-foreground md:text-pretty [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground [&_p:not(:last-child)]:mb-4",
59
+ className
60
+ )}
61
+ {...props}
62
+ />
63
+ )
64
+ }
65
+
66
+ function AlertAction({ className, ...props }: React.ComponentProps<"div">) {
67
+ return (
68
+ <div
69
+ data-slot="alert-action"
70
+ className={cn("absolute end-3 top-2.5", className)}
71
+ {...props}
72
+ />
73
+ )
74
+ }
75
+
76
+ export { Alert, AlertTitle, AlertDescription, AlertAction }
@@ -0,0 +1 @@
1
+ export * from "./alert"