@c9up/nebula 0.1.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 (327) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +256 -0
  3. package/dist/adapters/css.d.ts +33 -0
  4. package/dist/adapters/css.js +67 -0
  5. package/dist/adapters/index.d.ts +16 -0
  6. package/dist/adapters/index.js +27 -0
  7. package/dist/adapters/tailwind.d.ts +25 -0
  8. package/dist/adapters/tailwind.js +122 -0
  9. package/dist/adapters/types.d.ts +49 -0
  10. package/dist/adapters/types.js +21 -0
  11. package/dist/adapters/unocss.d.ts +17 -0
  12. package/dist/adapters/unocss.js +107 -0
  13. package/dist/atoms/AspectRatio.d.ts +17 -0
  14. package/dist/atoms/AspectRatio.js +19 -0
  15. package/dist/atoms/Avatar.d.ts +23 -0
  16. package/dist/atoms/Avatar.js +46 -0
  17. package/dist/atoms/Badge.d.ts +25 -0
  18. package/dist/atoms/Badge.js +28 -0
  19. package/dist/atoms/Button.d.ts +58 -0
  20. package/dist/atoms/Button.js +67 -0
  21. package/dist/atoms/Checkbox.d.ts +41 -0
  22. package/dist/atoms/Checkbox.js +47 -0
  23. package/dist/atoms/Input.d.ts +36 -0
  24. package/dist/atoms/Input.js +50 -0
  25. package/dist/atoms/Kbd.d.ts +14 -0
  26. package/dist/atoms/Kbd.js +17 -0
  27. package/dist/atoms/Label.d.ts +24 -0
  28. package/dist/atoms/Label.js +26 -0
  29. package/dist/atoms/Marker.d.ts +42 -0
  30. package/dist/atoms/Marker.js +55 -0
  31. package/dist/atoms/NativeSelect.d.ts +43 -0
  32. package/dist/atoms/NativeSelect.js +81 -0
  33. package/dist/atoms/Progress.d.ts +21 -0
  34. package/dist/atoms/Progress.js +48 -0
  35. package/dist/atoms/ScrollArea.d.ts +28 -0
  36. package/dist/atoms/ScrollArea.js +37 -0
  37. package/dist/atoms/Separator.d.ts +16 -0
  38. package/dist/atoms/Separator.js +21 -0
  39. package/dist/atoms/Skeleton.d.ts +13 -0
  40. package/dist/atoms/Skeleton.js +18 -0
  41. package/dist/atoms/Slider.d.ts +30 -0
  42. package/dist/atoms/Slider.js +40 -0
  43. package/dist/atoms/Spinner.d.ts +17 -0
  44. package/dist/atoms/Spinner.js +20 -0
  45. package/dist/atoms/Switch.d.ts +24 -0
  46. package/dist/atoms/Switch.js +41 -0
  47. package/dist/atoms/Textarea.d.ts +28 -0
  48. package/dist/atoms/Textarea.js +36 -0
  49. package/dist/atoms/Toggle.d.ts +38 -0
  50. package/dist/atoms/Toggle.js +45 -0
  51. package/dist/atoms/index.d.ts +32 -0
  52. package/dist/atoms/index.js +32 -0
  53. package/dist/cli/add.d.ts +44 -0
  54. package/dist/cli/add.js +99 -0
  55. package/dist/cli/index.d.ts +10 -0
  56. package/dist/cli/index.js +10 -0
  57. package/dist/cli/registry.d.ts +31 -0
  58. package/dist/cli/registry.js +83 -0
  59. package/dist/config.d.ts +81 -0
  60. package/dist/config.js +43 -0
  61. package/dist/configure.d.ts +34 -0
  62. package/dist/configure.js +85 -0
  63. package/dist/index.d.ts +41 -0
  64. package/dist/index.js +41 -0
  65. package/dist/lib/children.d.ts +28 -0
  66. package/dist/lib/children.js +27 -0
  67. package/dist/lib/cn.d.ts +13 -0
  68. package/dist/lib/cn.js +13 -0
  69. package/dist/lib/cva.d.ts +83 -0
  70. package/dist/lib/cva.js +178 -0
  71. package/dist/lib/icons.d.ts +44 -0
  72. package/dist/lib/icons.js +79 -0
  73. package/dist/lib/id.d.ts +31 -0
  74. package/dist/lib/id.js +41 -0
  75. package/dist/lib/index.d.ts +12 -0
  76. package/dist/lib/index.js +12 -0
  77. package/dist/lib/motion.d.ts +31 -0
  78. package/dist/lib/motion.js +39 -0
  79. package/dist/lib/props.d.ts +48 -0
  80. package/dist/lib/props.js +59 -0
  81. package/dist/lib/styled.d.ts +31 -0
  82. package/dist/lib/styled.js +39 -0
  83. package/dist/molecules/Accordion.d.ts +35 -0
  84. package/dist/molecules/Accordion.js +117 -0
  85. package/dist/molecules/Alert.d.ts +30 -0
  86. package/dist/molecules/Alert.js +35 -0
  87. package/dist/molecules/Attachment.d.ts +39 -0
  88. package/dist/molecules/Attachment.js +103 -0
  89. package/dist/molecules/Breadcrumb.d.ts +29 -0
  90. package/dist/molecules/Breadcrumb.js +73 -0
  91. package/dist/molecules/Bubble.d.ts +56 -0
  92. package/dist/molecules/Bubble.js +92 -0
  93. package/dist/molecules/ButtonGroup.d.ts +23 -0
  94. package/dist/molecules/ButtonGroup.js +30 -0
  95. package/dist/molecules/Card.d.ts +17 -0
  96. package/dist/molecules/Card.js +17 -0
  97. package/dist/molecules/Collapsible.d.ts +40 -0
  98. package/dist/molecules/Collapsible.js +71 -0
  99. package/dist/molecules/Empty.d.ts +16 -0
  100. package/dist/molecules/Empty.js +16 -0
  101. package/dist/molecules/Field.d.ts +54 -0
  102. package/dist/molecules/Field.js +82 -0
  103. package/dist/molecules/InputGroup.d.ts +33 -0
  104. package/dist/molecules/InputGroup.js +35 -0
  105. package/dist/molecules/InputOTP.d.ts +33 -0
  106. package/dist/molecules/InputOTP.js +140 -0
  107. package/dist/molecules/Item.d.ts +41 -0
  108. package/dist/molecules/Item.js +48 -0
  109. package/dist/molecules/Message.d.ts +43 -0
  110. package/dist/molecules/Message.js +82 -0
  111. package/dist/molecules/Pagination.d.ts +41 -0
  112. package/dist/molecules/Pagination.js +144 -0
  113. package/dist/molecules/RadioGroup.d.ts +32 -0
  114. package/dist/molecules/RadioGroup.js +65 -0
  115. package/dist/molecules/Resizable.d.ts +37 -0
  116. package/dist/molecules/Resizable.js +136 -0
  117. package/dist/molecules/Table.d.ts +37 -0
  118. package/dist/molecules/Table.js +78 -0
  119. package/dist/molecules/Tabs.d.ts +37 -0
  120. package/dist/molecules/Tabs.js +109 -0
  121. package/dist/molecules/ToggleGroup.d.ts +37 -0
  122. package/dist/molecules/ToggleGroup.js +68 -0
  123. package/dist/molecules/Typography.d.ts +26 -0
  124. package/dist/molecules/Typography.js +67 -0
  125. package/dist/molecules/index.d.ts +37 -0
  126. package/dist/molecules/index.js +37 -0
  127. package/dist/organisms/AlertDialog.d.ts +40 -0
  128. package/dist/organisms/AlertDialog.js +104 -0
  129. package/dist/organisms/Calendar.d.ts +96 -0
  130. package/dist/organisms/Calendar.js +353 -0
  131. package/dist/organisms/Carousel.d.ts +29 -0
  132. package/dist/organisms/Carousel.js +128 -0
  133. package/dist/organisms/Chart.d.ts +55 -0
  134. package/dist/organisms/Chart.js +189 -0
  135. package/dist/organisms/Combobox.d.ts +41 -0
  136. package/dist/organisms/Combobox.js +102 -0
  137. package/dist/organisms/Command.d.ts +46 -0
  138. package/dist/organisms/Command.js +171 -0
  139. package/dist/organisms/CommandDialog.d.ts +42 -0
  140. package/dist/organisms/CommandDialog.js +116 -0
  141. package/dist/organisms/ContextMenu.d.ts +29 -0
  142. package/dist/organisms/ContextMenu.js +102 -0
  143. package/dist/organisms/DataTable.d.ts +50 -0
  144. package/dist/organisms/DataTable.js +257 -0
  145. package/dist/organisms/DatePicker.d.ts +34 -0
  146. package/dist/organisms/DatePicker.js +115 -0
  147. package/dist/organisms/DateRangePicker.d.ts +34 -0
  148. package/dist/organisms/DateRangePicker.js +122 -0
  149. package/dist/organisms/Dialog.d.ts +50 -0
  150. package/dist/organisms/Dialog.js +116 -0
  151. package/dist/organisms/Drawer.d.ts +40 -0
  152. package/dist/organisms/Drawer.js +131 -0
  153. package/dist/organisms/DropdownMenu.d.ts +30 -0
  154. package/dist/organisms/DropdownMenu.js +91 -0
  155. package/dist/organisms/Form.d.ts +114 -0
  156. package/dist/organisms/Form.js +151 -0
  157. package/dist/organisms/HoverCard.d.ts +30 -0
  158. package/dist/organisms/HoverCard.js +68 -0
  159. package/dist/organisms/Menubar.d.ts +28 -0
  160. package/dist/organisms/Menubar.js +147 -0
  161. package/dist/organisms/MessageScroller.d.ts +36 -0
  162. package/dist/organisms/MessageScroller.js +124 -0
  163. package/dist/organisms/NavigationMenu.d.ts +41 -0
  164. package/dist/organisms/NavigationMenu.js +139 -0
  165. package/dist/organisms/Popover.d.ts +33 -0
  166. package/dist/organisms/Popover.js +58 -0
  167. package/dist/organisms/Questionnaire.d.ts +74 -0
  168. package/dist/organisms/Questionnaire.js +235 -0
  169. package/dist/organisms/Select.d.ts +47 -0
  170. package/dist/organisms/Select.js +250 -0
  171. package/dist/organisms/Sheet.d.ts +34 -0
  172. package/dist/organisms/Sheet.js +107 -0
  173. package/dist/organisms/Sidebar.d.ts +100 -0
  174. package/dist/organisms/Sidebar.js +228 -0
  175. package/dist/organisms/Toaster.d.ts +67 -0
  176. package/dist/organisms/Toaster.js +189 -0
  177. package/dist/organisms/Tooltip.d.ts +39 -0
  178. package/dist/organisms/Tooltip.js +94 -0
  179. package/dist/organisms/index.d.ts +40 -0
  180. package/dist/organisms/index.js +40 -0
  181. package/dist/primitives/controllable.d.ts +38 -0
  182. package/dist/primitives/controllable.js +43 -0
  183. package/dist/primitives/dismissable.d.ts +53 -0
  184. package/dist/primitives/dismissable.js +158 -0
  185. package/dist/primitives/floating.d.ts +116 -0
  186. package/dist/primitives/floating.js +289 -0
  187. package/dist/primitives/floatingSurface.d.ts +56 -0
  188. package/dist/primitives/floatingSurface.js +142 -0
  189. package/dist/primitives/focusTrap.d.ts +47 -0
  190. package/dist/primitives/focusTrap.js +101 -0
  191. package/dist/primitives/focusable.d.ts +53 -0
  192. package/dist/primitives/focusable.js +109 -0
  193. package/dist/primitives/index.d.ts +27 -0
  194. package/dist/primitives/index.js +27 -0
  195. package/dist/primitives/menu.d.ts +102 -0
  196. package/dist/primitives/menu.js +356 -0
  197. package/dist/primitives/modalSurface.d.ts +54 -0
  198. package/dist/primitives/modalSurface.js +146 -0
  199. package/dist/primitives/portal.d.ts +34 -0
  200. package/dist/primitives/portal.js +42 -0
  201. package/dist/primitives/presence.d.ts +45 -0
  202. package/dist/primitives/presence.js +152 -0
  203. package/dist/primitives/rovingFocus.d.ts +47 -0
  204. package/dist/primitives/rovingFocus.js +176 -0
  205. package/dist/primitives/scrollLock.d.ts +21 -0
  206. package/dist/primitives/scrollLock.js +75 -0
  207. package/dist/primitives/typeahead.d.ts +39 -0
  208. package/dist/primitives/typeahead.js +123 -0
  209. package/dist/templates/AppShell.d.ts +30 -0
  210. package/dist/templates/AppShell.js +42 -0
  211. package/dist/templates/AuthLayout.d.ts +23 -0
  212. package/dist/templates/AuthLayout.js +42 -0
  213. package/dist/templates/SettingsLayout.d.ts +27 -0
  214. package/dist/templates/SettingsLayout.js +42 -0
  215. package/dist/templates/index.d.ts +16 -0
  216. package/dist/templates/index.js +16 -0
  217. package/nebula.css +2 -0
  218. package/package.json +92 -0
  219. package/registry.json +1107 -0
  220. package/src/adapters/css.ts +75 -0
  221. package/src/adapters/index.ts +40 -0
  222. package/src/adapters/tailwind.ts +134 -0
  223. package/src/adapters/types.ts +53 -0
  224. package/src/adapters/unocss.ts +116 -0
  225. package/src/atoms/AspectRatio.ts +28 -0
  226. package/src/atoms/Avatar.ts +67 -0
  227. package/src/atoms/Badge.ts +46 -0
  228. package/src/atoms/Button.ts +96 -0
  229. package/src/atoms/Checkbox.ts +76 -0
  230. package/src/atoms/Input.ts +76 -0
  231. package/src/atoms/Kbd.ts +28 -0
  232. package/src/atoms/Label.ts +38 -0
  233. package/src/atoms/Marker.ts +79 -0
  234. package/src/atoms/NativeSelect.ts +115 -0
  235. package/src/atoms/Progress.ts +64 -0
  236. package/src/atoms/ScrollArea.ts +53 -0
  237. package/src/atoms/Separator.ts +36 -0
  238. package/src/atoms/Skeleton.ts +24 -0
  239. package/src/atoms/Slider.ts +65 -0
  240. package/src/atoms/Spinner.ts +28 -0
  241. package/src/atoms/Switch.ts +56 -0
  242. package/src/atoms/Textarea.ts +58 -0
  243. package/src/atoms/Toggle.ts +67 -0
  244. package/src/atoms/index.ts +62 -0
  245. package/src/cli/add.ts +126 -0
  246. package/src/cli/index.ts +22 -0
  247. package/src/cli/registry.ts +116 -0
  248. package/src/config.ts +102 -0
  249. package/src/configure.ts +127 -0
  250. package/src/index.ts +53 -0
  251. package/src/lib/children.ts +43 -0
  252. package/src/lib/cn.ts +14 -0
  253. package/src/lib/cva.ts +249 -0
  254. package/src/lib/icons.ts +138 -0
  255. package/src/lib/id.ts +44 -0
  256. package/src/lib/index.ts +21 -0
  257. package/src/lib/motion.ts +48 -0
  258. package/src/lib/props.ts +83 -0
  259. package/src/lib/styled.ts +60 -0
  260. package/src/molecules/Accordion.ts +161 -0
  261. package/src/molecules/Alert.ts +58 -0
  262. package/src/molecules/Attachment.ts +132 -0
  263. package/src/molecules/Breadcrumb.ts +107 -0
  264. package/src/molecules/Bubble.ts +134 -0
  265. package/src/molecules/ButtonGroup.ts +55 -0
  266. package/src/molecules/Card.ts +42 -0
  267. package/src/molecules/Collapsible.ts +89 -0
  268. package/src/molecules/Empty.ts +43 -0
  269. package/src/molecules/Field.ts +131 -0
  270. package/src/molecules/InputGroup.ts +62 -0
  271. package/src/molecules/InputOTP.ts +166 -0
  272. package/src/molecules/Item.ts +89 -0
  273. package/src/molecules/Message.ts +127 -0
  274. package/src/molecules/Pagination.ts +197 -0
  275. package/src/molecules/RadioGroup.ts +104 -0
  276. package/src/molecules/Resizable.ts +166 -0
  277. package/src/molecules/Table.ts +118 -0
  278. package/src/molecules/Tabs.ts +148 -0
  279. package/src/molecules/ToggleGroup.ts +109 -0
  280. package/src/molecules/Typography.ts +94 -0
  281. package/src/molecules/index.ts +144 -0
  282. package/src/organisms/AlertDialog.ts +133 -0
  283. package/src/organisms/Calendar.ts +470 -0
  284. package/src/organisms/Carousel.ts +161 -0
  285. package/src/organisms/Chart.ts +257 -0
  286. package/src/organisms/Combobox.ts +140 -0
  287. package/src/organisms/Command.ts +211 -0
  288. package/src/organisms/CommandDialog.ts +149 -0
  289. package/src/organisms/ContextMenu.ts +125 -0
  290. package/src/organisms/DataTable.ts +328 -0
  291. package/src/organisms/DatePicker.ts +141 -0
  292. package/src/organisms/DateRangePicker.ts +149 -0
  293. package/src/organisms/Dialog.ts +162 -0
  294. package/src/organisms/Drawer.ts +167 -0
  295. package/src/organisms/DropdownMenu.ts +112 -0
  296. package/src/organisms/Form.ts +217 -0
  297. package/src/organisms/HoverCard.ts +92 -0
  298. package/src/organisms/Menubar.ts +167 -0
  299. package/src/organisms/MessageScroller.ts +145 -0
  300. package/src/organisms/NavigationMenu.ts +184 -0
  301. package/src/organisms/Popover.ts +84 -0
  302. package/src/organisms/Questionnaire.ts +322 -0
  303. package/src/organisms/Select.ts +286 -0
  304. package/src/organisms/Sheet.ts +144 -0
  305. package/src/organisms/Sidebar.ts +336 -0
  306. package/src/organisms/Toaster.ts +246 -0
  307. package/src/organisms/Tooltip.ts +124 -0
  308. package/src/organisms/index.ts +134 -0
  309. package/src/primitives/controllable.ts +64 -0
  310. package/src/primitives/dismissable.ts +195 -0
  311. package/src/primitives/floating.ts +453 -0
  312. package/src/primitives/floatingSurface.ts +209 -0
  313. package/src/primitives/focusTrap.ts +132 -0
  314. package/src/primitives/focusable.ts +108 -0
  315. package/src/primitives/index.ts +88 -0
  316. package/src/primitives/menu.ts +491 -0
  317. package/src/primitives/modalSurface.ts +199 -0
  318. package/src/primitives/portal.ts +61 -0
  319. package/src/primitives/presence.ts +185 -0
  320. package/src/primitives/rovingFocus.ts +212 -0
  321. package/src/primitives/scrollLock.ts +79 -0
  322. package/src/primitives/typeahead.ts +156 -0
  323. package/src/templates/AppShell.ts +56 -0
  324. package/src/templates/AuthLayout.ts +66 -0
  325. package/src/templates/SettingsLayout.ts +63 -0
  326. package/src/templates/index.ts +21 -0
  327. package/theme.css +151 -0
@@ -0,0 +1,85 @@
1
+ /**
2
+ * `ream configure @c9up/nebula` — the house setup hook.
3
+ *
4
+ * Every package in this workspace is installed the same way: `ream add <pkg>`
5
+ * installs it and dispatches to this hook, which writes the files the package
6
+ * needs through the codemods the CLI hands in. nebula follows that rather than
7
+ * shipping a setup command of its own — one way to install a ream package, not
8
+ * one per package.
9
+ *
10
+ * Pass the adapter through the installer:
11
+ *
12
+ * ream add @c9up/nebula --adapter unocss
13
+ *
14
+ * There is no provider to register. A provider binds runtime services into the
15
+ * container, and nebula has none: its components are client-side templates and
16
+ * its adapters run at build time. An empty provider would be ceremony.
17
+ */
18
+ import { adapterFor, isAdapterName } from "./adapters/index.js";
19
+ import { resolveConfig } from "./config.js";
20
+ function configFile(adapter) {
21
+ return `import { defineConfig } from '@c9up/nebula'
22
+
23
+ /**
24
+ * nebula — component registry and style adapter.
25
+ *
26
+ * Changing \`adapter\` and re-running \`ream configure @c9up/nebula\` swaps the
27
+ * CSS engine. The components themselves are untouched: all three adapters
28
+ * consume the same class names.
29
+ */
30
+ export default defineConfig({
31
+ adapter: '${adapter}',
32
+ paths: {
33
+ // Where \`ream nebula:add\` copies components. The atomic layers live under it.
34
+ components: 'resources/pages',
35
+ css: 'resources/css/app.css',
36
+ output: 'public/app.css',
37
+ },
38
+ })
39
+ `;
40
+ }
41
+ /**
42
+ * Read the adapter from the forwarded flags.
43
+ *
44
+ * An unrecognised name is refused rather than silently defaulted: a typo in
45
+ * `--adapter tailwnid` would otherwise write a Tailwind setup and leave the
46
+ * user hunting for why their UnoCSS config never appeared.
47
+ */
48
+ function adapterFrom(flags) {
49
+ const requested = flags.adapter?.[0];
50
+ if (requested === undefined)
51
+ return "tailwind";
52
+ if (!isAdapterName(requested)) {
53
+ throw new Error(`[@c9up/nebula] unknown adapter "${requested}" — one of tailwind, unocss, css`);
54
+ }
55
+ return requested;
56
+ }
57
+ export async function configure(codemods, flags = {}) {
58
+ const name = adapterFrom(flags);
59
+ const adapter = adapterFor(name);
60
+ const config = resolveConfig({ adapter: name });
61
+ await codemods.writeFile("config/nebula.ts", configFile(name));
62
+ for (const file of adapter.files(config)) {
63
+ await codemods.writeFile(file.path, file.contents);
64
+ }
65
+ // On stderr, and never installed on the user's behalf. nebula declares no
66
+ // CSS dependency at all — the app owns its build tooling, and a UI library
67
+ // quietly adding one to someone's dependency tree is how a tree gets away
68
+ // from them.
69
+ const lines = [
70
+ "",
71
+ "[@c9up/nebula] configured with the " + name + " adapter.",
72
+ ];
73
+ if (adapter.packages.length > 0) {
74
+ lines.push(" Install the engine yourself:", ` pnpm add -D ${adapter.packages.join(" ")}`);
75
+ }
76
+ const commands = adapter.commands(config);
77
+ if (commands === null) {
78
+ lines.push(" No build step — the stylesheet ships prebuilt.");
79
+ }
80
+ else {
81
+ lines.push(" Register the build in config/assets.ts:", ` build: ${commands.build.command} ${commands.build.args.join(" ")}`, ` devServer: ${commands.dev.command} ${commands.dev.args.join(" ")}`);
82
+ }
83
+ lines.push(" Then add components with `ream nebula:add button card` — they are copied", " into your project and are yours to edit.", "");
84
+ process.stderr.write(lines.join("\n"));
85
+ }
@@ -0,0 +1,41 @@
1
+ /**
2
+ * @c9up/nebula — shadcn/ui, ported to Aurora, organised as atomic design.
3
+ *
4
+ * Three things are worth knowing before reading further.
5
+ *
6
+ * **It adds no runtime dependency.** shadcn stands on Radix, `clsx`,
7
+ * `tailwind-merge`, `class-variance-authority`, `lucide-react`,
8
+ * `@floating-ui/dom`, `cmdk`, `sonner`, `recharts`, `@tanstack/react-table` and
9
+ * `react-day-picker`. None of them are React-agnostic, and the workspace had
10
+ * already made the call that `cn` was worth writing by hand rather than
11
+ * installing two packages. So `cva` is reimplemented, the Radix behaviour layer
12
+ * lives in `primitives/`, the placement engine is `primitives/floating.ts`, the
13
+ * icons are inlined, and the date maths is `Date` and `Intl`.
14
+ *
15
+ * **Compound components take data, not children.** shadcn composes through
16
+ * React context — `<Tabs><TabsList><TabsTrigger>`. Aurora has no context, and
17
+ * the workarounds are worse than the problem, so those components take an
18
+ * `items` array and named slots. The rendered markup is unchanged, which means
19
+ * shadcn's CSS and its examples still read across.
20
+ *
21
+ * **The atomic layer is a property of the component.** An atom renders its own
22
+ * markup and composes nothing from nebula; a molecule assembles atoms or owns
23
+ * state spanning several elements; an organism portals, traps focus, or floats;
24
+ * a template is page layout. `nebula add button` knows Button is an atom and
25
+ * puts it in `atoms/` without being told.
26
+ *
27
+ * Import from the layer barrels — `@c9up/nebula/atoms` — or take the source
28
+ * with `nebula add`, which is the mode this library is really built for.
29
+ */
30
+ export * from "./adapters/index.js";
31
+ export * from "./atoms/index.js";
32
+ export { type AdapterName, defaultPaths, defineConfig, isLayer, type Layer, layers, type NebulaConfig, type NebulaPaths, type ResolvedNebulaConfig, resolveConfig, } from "./config.js";
33
+ export { type Child, type Slot, slot } from "./lib/children.js";
34
+ export * from "./lib/icons.js";
35
+ export * from "./lib/index.js";
36
+ export { fadeInOut, slideFrom, zoomInOut } from "./lib/motion.js";
37
+ export { type StyledProps, styledDiv, styledSpan } from "./lib/styled.js";
38
+ export * from "./molecules/index.js";
39
+ export * from "./organisms/index.js";
40
+ export * from "./primitives/index.js";
41
+ export * from "./templates/index.js";
package/dist/index.js ADDED
@@ -0,0 +1,41 @@
1
+ /**
2
+ * @c9up/nebula — shadcn/ui, ported to Aurora, organised as atomic design.
3
+ *
4
+ * Three things are worth knowing before reading further.
5
+ *
6
+ * **It adds no runtime dependency.** shadcn stands on Radix, `clsx`,
7
+ * `tailwind-merge`, `class-variance-authority`, `lucide-react`,
8
+ * `@floating-ui/dom`, `cmdk`, `sonner`, `recharts`, `@tanstack/react-table` and
9
+ * `react-day-picker`. None of them are React-agnostic, and the workspace had
10
+ * already made the call that `cn` was worth writing by hand rather than
11
+ * installing two packages. So `cva` is reimplemented, the Radix behaviour layer
12
+ * lives in `primitives/`, the placement engine is `primitives/floating.ts`, the
13
+ * icons are inlined, and the date maths is `Date` and `Intl`.
14
+ *
15
+ * **Compound components take data, not children.** shadcn composes through
16
+ * React context — `<Tabs><TabsList><TabsTrigger>`. Aurora has no context, and
17
+ * the workarounds are worse than the problem, so those components take an
18
+ * `items` array and named slots. The rendered markup is unchanged, which means
19
+ * shadcn's CSS and its examples still read across.
20
+ *
21
+ * **The atomic layer is a property of the component.** An atom renders its own
22
+ * markup and composes nothing from nebula; a molecule assembles atoms or owns
23
+ * state spanning several elements; an organism portals, traps focus, or floats;
24
+ * a template is page layout. `nebula add button` knows Button is an atom and
25
+ * puts it in `atoms/` without being told.
26
+ *
27
+ * Import from the layer barrels — `@c9up/nebula/atoms` — or take the source
28
+ * with `nebula add`, which is the mode this library is really built for.
29
+ */
30
+ export * from "./adapters/index.js";
31
+ export * from "./atoms/index.js";
32
+ export { defaultPaths, defineConfig, isLayer, layers, resolveConfig, } from "./config.js";
33
+ export { slot } from "./lib/children.js";
34
+ export * from "./lib/icons.js";
35
+ export * from "./lib/index.js";
36
+ export { fadeInOut, slideFrom, zoomInOut } from "./lib/motion.js";
37
+ export { styledDiv, styledSpan } from "./lib/styled.js";
38
+ export * from "./molecules/index.js";
39
+ export * from "./organisms/index.js";
40
+ export * from "./primitives/index.js";
41
+ export * from "./templates/index.js";
@@ -0,0 +1,28 @@
1
+ /**
2
+ * What a component accepts as content.
3
+ *
4
+ * Aurora's renderer already handles the whole union in a text slot: nested
5
+ * templates, raw nodes, primitives, and arrays of any of those, with `null`,
6
+ * `undefined` and `false` rendering nothing. `Child` names that union so a
7
+ * component's props say what they mean instead of falling back to `unknown`,
8
+ * and so passing a value the renderer would silently drop is a type error at
9
+ * the call site rather than a blank space on the page.
10
+ *
11
+ * `Slot` is the reactive form. Content that changes must arrive as an accessor
12
+ * — Aurora never re-renders a component, so a plain value read at setup is
13
+ * frozen for the lifetime of the node.
14
+ */
15
+ import type { TemplateResult } from "@c9up/aurora";
16
+ import type { Reactive } from "./props.js";
17
+ export type Child = TemplateResult | Node | string | number | boolean | null | undefined | readonly Child[];
18
+ /** Content that may be constant or recomputed. */
19
+ export type Slot = Reactive<Child>;
20
+ /**
21
+ * Bind content into a template so it stays live.
22
+ *
23
+ * Returns the accessor form unchanged and wraps a constant in one. Templates
24
+ * should always interpolate `${slot(props.children)}`: handing the renderer a
25
+ * bare value works until a sibling prop makes the content dynamic, at which
26
+ * point the binding quietly stops updating and nothing points at why.
27
+ */
28
+ export declare function slot(content: Slot | undefined): () => Child;
@@ -0,0 +1,27 @@
1
+ /**
2
+ * What a component accepts as content.
3
+ *
4
+ * Aurora's renderer already handles the whole union in a text slot: nested
5
+ * templates, raw nodes, primitives, and arrays of any of those, with `null`,
6
+ * `undefined` and `false` rendering nothing. `Child` names that union so a
7
+ * component's props say what they mean instead of falling back to `unknown`,
8
+ * and so passing a value the renderer would silently drop is a type error at
9
+ * the call site rather than a blank space on the page.
10
+ *
11
+ * `Slot` is the reactive form. Content that changes must arrive as an accessor
12
+ * — Aurora never re-renders a component, so a plain value read at setup is
13
+ * frozen for the lifetime of the node.
14
+ */
15
+ /**
16
+ * Bind content into a template so it stays live.
17
+ *
18
+ * Returns the accessor form unchanged and wraps a constant in one. Templates
19
+ * should always interpolate `${slot(props.children)}`: handing the renderer a
20
+ * bare value works until a sibling prop makes the content dynamic, at which
21
+ * point the binding quietly stops updating and nothing points at why.
22
+ */
23
+ export function slot(content) {
24
+ if (content === undefined)
25
+ return () => null;
26
+ return typeof content === "function" ? content : () => content;
27
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Class composition — re-exported from Aurora rather than reimplemented here.
3
+ *
4
+ * `@c9up/aurora` already ships `clsx` + `tailwind-merge` written from scratch
5
+ * with no dependencies (its `src/cn.ts`, targeting the Tailwind v4 utility
6
+ * set). nebula is a peer of aurora, never a fork of it: one class-merge
7
+ * implementation in the workspace, one place to fix a mis-grouped utility.
8
+ *
9
+ * This module exists so every nebula component imports `./lib/cn.js` and not
10
+ * `@c9up/aurora` directly. That indirection is what lets the registry rewrite
11
+ * a single import line when it copies a component into a host app.
12
+ */
13
+ export { type ClassValue, clsx, cn, twMerge } from "@c9up/aurora";
package/dist/lib/cn.js ADDED
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Class composition — re-exported from Aurora rather than reimplemented here.
3
+ *
4
+ * `@c9up/aurora` already ships `clsx` + `tailwind-merge` written from scratch
5
+ * with no dependencies (its `src/cn.ts`, targeting the Tailwind v4 utility
6
+ * set). nebula is a peer of aurora, never a fork of it: one class-merge
7
+ * implementation in the workspace, one place to fix a mis-grouped utility.
8
+ *
9
+ * This module exists so every nebula component imports `./lib/cn.js` and not
10
+ * `@c9up/aurora` directly. That indirection is what lets the registry rewrite
11
+ * a single import line when it copies a component into a host app.
12
+ */
13
+ export { clsx, cn, twMerge } from "@c9up/aurora";
@@ -0,0 +1,83 @@
1
+ /**
2
+ * `cva` — class-variance-authority, reimplemented from scratch with ZERO
3
+ * dependencies.
4
+ *
5
+ * shadcn/ui is built on two class helpers: `cn` (clsx + tailwind-merge) and
6
+ * `cva` (variant → class-list resolution). Aurora already ships `cn` written
7
+ * from scratch in `@c9up/aurora` (src/cn.ts), so this file is the other half.
8
+ * Between them, nebula pulls in no runtime dependency at all.
9
+ *
10
+ * const button = cva(
11
+ * "inline-flex items-center rounded-md text-sm font-medium",
12
+ * {
13
+ * variants: {
14
+ * variant: { default: "bg-primary text-primary-foreground",
15
+ * ghost: "hover:bg-accent" },
16
+ * size: { sm: "h-8 px-3", lg: "h-10 px-8" },
17
+ * },
18
+ * compoundVariants: [
19
+ * { variant: "ghost", size: "sm", class: "px-2" },
20
+ * ],
21
+ * defaultVariants: { variant: "default", size: "sm" },
22
+ * },
23
+ * )
24
+ *
25
+ * button() // base + default variants
26
+ * button({ variant: "ghost" }) // ghost, still size sm
27
+ * button({ size: "lg", class: "w-full" }) // caller classes win
28
+ *
29
+ * Differences from the upstream package, both deliberate:
30
+ *
31
+ * 1. The result runs through Aurora's `cn`, so a variant that sets `px-2`
32
+ * genuinely overrides a base `px-3` instead of emitting both and leaving
33
+ * the winner to CSS source order. Upstream cva only concatenates; every
34
+ * real shadcn component then wraps the call in `cn(...)` to get here
35
+ * anyway. Doing it inside removes that ceremony from ~50 components.
36
+ * 2. `class` and `className` are both accepted. Aurora templates use `class`;
37
+ * `className` exists only so code pasted over from a React codebase keeps
38
+ * working.
39
+ */
40
+ import { type ClassValue } from "./cn.js";
41
+ /**
42
+ * One variant axis: a variant name mapped to the classes each of its values
43
+ * contributes. `{ size: { sm: "h-8", lg: "h-10" } }` is one axis with two
44
+ * values.
45
+ */
46
+ export type VariantShape = Record<string, Record<string, ClassValue>>;
47
+ /**
48
+ * The value accepted for one axis.
49
+ *
50
+ * An axis keyed by `"true"` / `"false"` is a boolean axis — the caller passes
51
+ * a real `boolean`, not the string. That mapping is what lets
52
+ * `{ disabled: { true: "opacity-50" } }` be driven by `disabled: true`.
53
+ */
54
+ type VariantValue<T> = Extract<keyof T, string> extends "true" | "false" ? boolean : Extract<keyof T, string>;
55
+ /** Props selecting one value per axis. Every axis is optional. */
56
+ export type VariantSelection<V extends VariantShape> = {
57
+ [K in keyof V]?: VariantValue<V[K]> | null | undefined;
58
+ };
59
+ /**
60
+ * A compound rule matches when EVERY axis it names matches. An axis may list
61
+ * several accepted values, in which case any of them matches.
62
+ */
63
+ export type CompoundVariant<V extends VariantShape> = {
64
+ [K in keyof V]?: VariantValue<V[K]> | ReadonlyArray<VariantValue<V[K]>>;
65
+ } & ClassOverrides;
66
+ /** Extra keys every generated function accepts on top of its own axes. */
67
+ export interface ClassOverrides {
68
+ class?: ClassValue;
69
+ className?: ClassValue;
70
+ }
71
+ export interface VariantConfig<V extends VariantShape> {
72
+ variants?: V;
73
+ compoundVariants?: ReadonlyArray<CompoundVariant<V>>;
74
+ defaultVariants?: VariantSelection<V>;
75
+ }
76
+ /** The props a `cva()` result accepts, minus the two class escape hatches. */
77
+ export type VariantProps<F> = F extends (props?: infer P) => string ? Omit<NonNullable<P>, "class" | "className"> : never;
78
+ /**
79
+ * Build a variant resolver. Returns a function from a variant selection to a
80
+ * single, conflict-resolved class string.
81
+ */
82
+ export declare function cva<V extends VariantShape>(base?: ClassValue, config?: VariantConfig<V>): (props?: VariantSelection<V> & ClassOverrides) => string;
83
+ export {};
@@ -0,0 +1,178 @@
1
+ /**
2
+ * `cva` — class-variance-authority, reimplemented from scratch with ZERO
3
+ * dependencies.
4
+ *
5
+ * shadcn/ui is built on two class helpers: `cn` (clsx + tailwind-merge) and
6
+ * `cva` (variant → class-list resolution). Aurora already ships `cn` written
7
+ * from scratch in `@c9up/aurora` (src/cn.ts), so this file is the other half.
8
+ * Between them, nebula pulls in no runtime dependency at all.
9
+ *
10
+ * const button = cva(
11
+ * "inline-flex items-center rounded-md text-sm font-medium",
12
+ * {
13
+ * variants: {
14
+ * variant: { default: "bg-primary text-primary-foreground",
15
+ * ghost: "hover:bg-accent" },
16
+ * size: { sm: "h-8 px-3", lg: "h-10 px-8" },
17
+ * },
18
+ * compoundVariants: [
19
+ * { variant: "ghost", size: "sm", class: "px-2" },
20
+ * ],
21
+ * defaultVariants: { variant: "default", size: "sm" },
22
+ * },
23
+ * )
24
+ *
25
+ * button() // base + default variants
26
+ * button({ variant: "ghost" }) // ghost, still size sm
27
+ * button({ size: "lg", class: "w-full" }) // caller classes win
28
+ *
29
+ * Differences from the upstream package, both deliberate:
30
+ *
31
+ * 1. The result runs through Aurora's `cn`, so a variant that sets `px-2`
32
+ * genuinely overrides a base `px-3` instead of emitting both and leaving
33
+ * the winner to CSS source order. Upstream cva only concatenates; every
34
+ * real shadcn component then wraps the call in `cn(...)` to get here
35
+ * anyway. Doing it inside removes that ceremony from ~50 components.
36
+ * 2. `class` and `className` are both accepted. Aurora templates use `class`;
37
+ * `className` exists only so code pasted over from a React codebase keeps
38
+ * working.
39
+ */
40
+ import { cn } from "./cn.js";
41
+ /**
42
+ * Build a variant resolver. Returns a function from a variant selection to a
43
+ * single, conflict-resolved class string.
44
+ */
45
+ export function cva(base, config) {
46
+ // Widening to the non-generic shapes up front is what keeps the body free
47
+ // of casts: `V` cannot be indexed by a plain `string`, `VariantShape` can.
48
+ const variants = config?.variants ?? {};
49
+ const axes = Object.keys(variants);
50
+ const defaults = toValueMap(config?.defaultVariants);
51
+ const compounds = normaliseCompounds(config?.compoundVariants);
52
+ return (props) => {
53
+ const selection = selectionFor(defaults, props);
54
+ const parts = [base];
55
+ for (const axis of axes) {
56
+ const chosen = selection[axis];
57
+ if (chosen === undefined)
58
+ continue;
59
+ // Indexed by the *string form* of the value, so a boolean axis reaches
60
+ // its `"true"` / `"false"` entry here.
61
+ const classesForValue = variants[axis]?.[chosen];
62
+ if (classesForValue !== undefined)
63
+ parts.push(classesForValue);
64
+ }
65
+ for (const rule of compounds) {
66
+ if (satisfies(rule, selection))
67
+ parts.push(...rule.classes);
68
+ }
69
+ // Caller overrides come last so they win the tailwind-merge pass.
70
+ parts.push(props?.class, props?.className);
71
+ return cn(parts);
72
+ };
73
+ }
74
+ /**
75
+ * Read an object's own enumerable entries with honest `unknown` values.
76
+ *
77
+ * Variant selections are generic mapped types, which TypeScript will not let
78
+ * you index with a plain `string`. Funnelling every read through one helper
79
+ * typed `object → [string, unknown][]` gets the values out without a cast at
80
+ * any call site, and forces each one to narrow before use.
81
+ */
82
+ function entriesOf(source) {
83
+ return Object.entries(source);
84
+ }
85
+ /**
86
+ * Collapse a selection object down to `axis → string value`.
87
+ *
88
+ * Normalising to strings here is what keeps boolean-axis handling in a single
89
+ * place: `true` becomes `"true"`, and every lookup downstream — variant
90
+ * classes and compound matching alike — is a plain string compare.
91
+ */
92
+ function toValueMap(source) {
93
+ const out = {};
94
+ if (!source)
95
+ return out;
96
+ for (const [key, value] of entriesOf(source)) {
97
+ if (isClassKey(key))
98
+ continue;
99
+ if (value === undefined || value === null)
100
+ continue;
101
+ out[key] = String(value);
102
+ }
103
+ return out;
104
+ }
105
+ /**
106
+ * Merge caller props over the defaults.
107
+ *
108
+ * An omitted axis (or an explicit `undefined`) keeps its default; an explicit
109
+ * `null` clears it, which is how upstream cva lets a caller opt out of a
110
+ * default variant entirely.
111
+ */
112
+ function selectionFor(defaults, props) {
113
+ const selection = { ...defaults };
114
+ if (!props)
115
+ return selection;
116
+ for (const [key, value] of entriesOf(props)) {
117
+ if (isClassKey(key))
118
+ continue;
119
+ if (value === undefined)
120
+ continue;
121
+ selection[key] = value === null ? undefined : String(value);
122
+ }
123
+ return selection;
124
+ }
125
+ /** Flatten compound rules once, at construction, rather than on every call. */
126
+ function normaliseCompounds(compounds) {
127
+ if (!compounds)
128
+ return [];
129
+ const out = [];
130
+ for (const rule of compounds) {
131
+ const conditions = [];
132
+ const classes = [];
133
+ for (const [key, value] of entriesOf(rule)) {
134
+ if (isClassKey(key)) {
135
+ if (isClassValue(value))
136
+ classes.push(value);
137
+ continue;
138
+ }
139
+ if (value === undefined || value === null)
140
+ continue;
141
+ const accepted = Array.isArray(value)
142
+ ? value.map((one) => String(one))
143
+ : [String(value)];
144
+ conditions.push([key, accepted]);
145
+ }
146
+ out.push({ conditions, classes });
147
+ }
148
+ return out;
149
+ }
150
+ /** Does every condition of a compound rule hold for this selection? */
151
+ function satisfies(rule, selection) {
152
+ for (const [axis, accepted] of rule.conditions) {
153
+ const actual = selection[axis];
154
+ if (actual === undefined)
155
+ return false;
156
+ if (!accepted.includes(actual))
157
+ return false;
158
+ }
159
+ return true;
160
+ }
161
+ function isClassKey(key) {
162
+ return key === "class" || key === "className";
163
+ }
164
+ /**
165
+ * Narrow a compound rule's `class` / `className` back to `ClassValue`.
166
+ *
167
+ * The value arrives as `unknown` from `entriesOf`; `ClassValue` covers every
168
+ * shape `cn` accepts, so anything that is not a rejected primitive passes
169
+ * through untouched and `cn` does the rest of the work.
170
+ */
171
+ function isClassValue(value) {
172
+ return (typeof value === "string" ||
173
+ typeof value === "number" ||
174
+ typeof value === "boolean" ||
175
+ value === null ||
176
+ value === undefined ||
177
+ typeof value === "object");
178
+ }
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Inline icons.
3
+ *
4
+ * shadcn/ui pulls every glyph from `lucide-react`. nebula cannot: it is a
5
+ * React package, and taking a dependency for fifteen paths would undo the
6
+ * point of writing `cn` and `cva` by hand.
7
+ *
8
+ * So the glyphs the component set actually needs are inlined here, traced from
9
+ * Lucide's own 24×24 grid so they sit correctly next to Lucide icons in an app
10
+ * that also uses the real thing. Nothing else is added — this is not an icon
11
+ * library, and an app wanting a hundred more should install one and pass the
12
+ * markup in as content.
13
+ *
14
+ * `currentColor` throughout and no hardcoded size: an icon inherits the text
15
+ * colour of whatever it sits in, and the `[&_svg]:size-4` rules on Button and
16
+ * friends set the size from the component. That is what lets the same icon
17
+ * work in a button, a menu item and a badge without a variant each.
18
+ */
19
+ import { type TemplateResult } from "@c9up/aurora";
20
+ export interface IconProps {
21
+ class?: string;
22
+ /** Icons are decorative by default; give a label to expose one to a reader. */
23
+ label?: string;
24
+ }
25
+ export declare const CheckIcon: (props?: IconProps) => TemplateResult;
26
+ export declare const MinusIcon: (props?: IconProps) => TemplateResult;
27
+ export declare const XIcon: (props?: IconProps) => TemplateResult;
28
+ export declare const ChevronDownIcon: (props?: IconProps) => TemplateResult;
29
+ export declare const ChevronUpIcon: (props?: IconProps) => TemplateResult;
30
+ export declare const ChevronLeftIcon: (props?: IconProps) => TemplateResult;
31
+ export declare const ChevronRightIcon: (props?: IconProps) => TemplateResult;
32
+ export declare const ChevronsUpDownIcon: (props?: IconProps) => TemplateResult;
33
+ export declare const SearchIcon: (props?: IconProps) => TemplateResult;
34
+ export declare const CircleIcon: (props?: IconProps) => TemplateResult;
35
+ /** Filled dot — the selected marker inside a radio. */
36
+ export declare const DotIcon: (props?: IconProps) => TemplateResult;
37
+ export declare const MoreHorizontalIcon: (props?: IconProps) => TemplateResult;
38
+ export declare const ArrowLeftIcon: (props?: IconProps) => TemplateResult;
39
+ export declare const ArrowRightIcon: (props?: IconProps) => TemplateResult;
40
+ export declare const CalendarIcon: (props?: IconProps) => TemplateResult;
41
+ export declare const PanelLeftIcon: (props?: IconProps) => TemplateResult;
42
+ export declare const GripVerticalIcon: (props?: IconProps) => TemplateResult;
43
+ /** The arc Lucide uses for `loader-circle`; spun by the Spinner's animation. */
44
+ export declare const LoaderIcon: (props?: IconProps) => TemplateResult;
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Inline icons.
3
+ *
4
+ * shadcn/ui pulls every glyph from `lucide-react`. nebula cannot: it is a
5
+ * React package, and taking a dependency for fifteen paths would undo the
6
+ * point of writing `cn` and `cva` by hand.
7
+ *
8
+ * So the glyphs the component set actually needs are inlined here, traced from
9
+ * Lucide's own 24×24 grid so they sit correctly next to Lucide icons in an app
10
+ * that also uses the real thing. Nothing else is added — this is not an icon
11
+ * library, and an app wanting a hundred more should install one and pass the
12
+ * markup in as content.
13
+ *
14
+ * `currentColor` throughout and no hardcoded size: an icon inherits the text
15
+ * colour of whatever it sits in, and the `[&_svg]:size-4` rules on Button and
16
+ * friends set the size from the component. That is what lets the same icon
17
+ * work in a button, a menu item and a badge without a variant each.
18
+ */
19
+ import { html } from "@c9up/aurora";
20
+ /**
21
+ * Wrap path data in a Lucide-shaped `<svg>`.
22
+ *
23
+ * `aria-hidden` unless labelled, because an icon beside its own text label is
24
+ * noise to a screen reader — it reads the glyph's name and then the text. The
25
+ * exceptions are icon-only controls, which pass a label.
26
+ */
27
+ function svg(body, props = {}) {
28
+ return html `<svg
29
+ xmlns="http://www.w3.org/2000/svg"
30
+ viewBox="0 0 24 24"
31
+ fill="none"
32
+ stroke="currentColor"
33
+ stroke-width="2"
34
+ stroke-linecap="round"
35
+ stroke-linejoin="round"
36
+ class="${props.class}"
37
+ aria-hidden="${props.label === undefined ? "true" : undefined}"
38
+ aria-label="${props.label}"
39
+ role="${props.label === undefined ? undefined : "img"}"
40
+ >${body}</svg>`;
41
+ }
42
+ export const CheckIcon = (props) => svg(html `<path d="M20 6 9 17l-5-5" />`, props);
43
+ export const MinusIcon = (props) => svg(html `<path d="M5 12h14" />`, props);
44
+ export const XIcon = (props) => svg(html `<path d="M18 6 6 18" /><path d="m6 6 12 12" />`, props);
45
+ export const ChevronDownIcon = (props) => svg(html `<path d="m6 9 6 6 6-6" />`, props);
46
+ export const ChevronUpIcon = (props) => svg(html `<path d="m18 15-6-6-6 6" />`, props);
47
+ export const ChevronLeftIcon = (props) => svg(html `<path d="m15 18-6-6 6-6" />`, props);
48
+ export const ChevronRightIcon = (props) => svg(html `<path d="m9 18 6-6-6-6" />`, props);
49
+ export const ChevronsUpDownIcon = (props) => svg(html `<path d="m7 15 5 5 5-5" /><path d="m7 9 5-5 5 5" />`, props);
50
+ export const SearchIcon = (props) => svg(html `<circle cx="11" cy="11" r="8" /><path d="m21 21-4.3-4.3" />`, props);
51
+ export const CircleIcon = (props) => svg(html `<circle cx="12" cy="12" r="10" />`, props);
52
+ /** Filled dot — the selected marker inside a radio. */
53
+ export const DotIcon = (props) => svg(html `<circle cx="12" cy="12" r="4" fill="currentColor" stroke="none" />`, props);
54
+ export const MoreHorizontalIcon = (props) => svg(html `<circle cx="12" cy="12" r="1" /><circle cx="19" cy="12" r="1" /><circle
55
+ cx="5"
56
+ cy="12"
57
+ r="1"
58
+ />`, props);
59
+ export const ArrowLeftIcon = (props) => svg(html `<path d="m12 19-7-7 7-7" /><path d="M19 12H5" />`, props);
60
+ export const ArrowRightIcon = (props) => svg(html `<path d="M5 12h14" /><path d="m12 5 7 7-7 7" />`, props);
61
+ export const CalendarIcon = (props) => svg(html `<path d="M8 2v4" /><path d="M16 2v4" /><rect
62
+ width="18"
63
+ height="18"
64
+ x="3"
65
+ y="4"
66
+ rx="2"
67
+ /><path d="M3 10h18" />`, props);
68
+ export const PanelLeftIcon = (props) => svg(html `<rect width="18" height="18" x="3" y="3" rx="2" /><path d="M9 3v18" />`, props);
69
+ export const GripVerticalIcon = (props) => svg(html `<circle cx="9" cy="12" r="1" /><circle cx="9" cy="5" r="1" /><circle
70
+ cx="9"
71
+ cy="19"
72
+ r="1"
73
+ /><circle cx="15" cy="12" r="1" /><circle cx="15" cy="5" r="1" /><circle
74
+ cx="15"
75
+ cy="19"
76
+ r="1"
77
+ />`, props);
78
+ /** The arc Lucide uses for `loader-circle`; spun by the Spinner's animation. */
79
+ export const LoaderIcon = (props) => svg(html `<path d="M21 12a9 9 0 1 1-6.219-8.56" />`, props);