soluid 0.1.2 → 0.1.3

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.
package/README.md CHANGED
@@ -12,7 +12,7 @@ npm install -D soluid
12
12
 
13
13
  ```sh
14
14
  npx soluid init # create soluid.config.json interactively
15
- npx soluid install # install components and CSS
15
+ npx soluid install # download and install components + CSS
16
16
  npx soluid add <component...> # add components to config
17
17
  npx soluid remove <comp...> # remove components from config
18
18
  npx soluid list # list available components
@@ -32,16 +32,18 @@ npx soluid list # list available components
32
32
  }
33
33
  ```
34
34
 
35
+ `cssPath` receives all component CSS concatenated into a single file.
36
+
35
37
  ## Setup
36
38
 
37
- Import CSS in your app's entry point:
39
+ Import CSS in your app entry point:
38
40
 
39
41
  ```tsx
40
42
  // src/index.tsx
41
43
  import "./styles/soluid.css";
42
44
  ```
43
45
 
44
- Theme/density switching:
46
+ Theme and density switching:
45
47
 
46
48
  ```tsx
47
49
  document.documentElement.setAttribute("data-theme", "dark");
@@ -60,6 +62,16 @@ document.documentElement.setAttribute("data-density", "dense");
60
62
  | Navigation | Tabs, Breadcrumb, Pagination, Menu |
61
63
  | Utility | VisuallyHidden, Popover |
62
64
 
63
- ## Primitives (5)
65
+ ## Core Utilities
66
+
67
+ `createFocusTrap`, `createToast`, `createToggle`
68
+
69
+ Installed automatically as dependencies when any component that requires them is added.
70
+
71
+ ## Dev
72
+
73
+ ```sh
74
+ bun run dev
75
+ ```
64
76
 
65
- `createDisclosure`, `createFocusTrap`, `createToggle`, `createToast`, `createPagination`
77
+ Starts the component catalog for local preview.
@@ -1,7 +1,7 @@
1
1
  import * as fs from "node:fs";
2
2
  import * as path from "node:path";
3
3
  import * as readline from "node:readline";
4
- import { CONFIG_FILENAME, DEFAULT_CSS_FILENAME, PROJECT_NAME, findConfigPath, saveConfig } from "../config.js";
4
+ import { CONFIG_FILENAME, DEFAULT_CSS_FILENAME, PROJECT_NAME, fetchLatestComponentsVersion, findConfigPath, saveConfig } from "../config.js";
5
5
  import { allComponentNames } from "../registry.js";
6
6
  function prompt(question, defaultValue) {
7
7
  const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
@@ -36,10 +36,13 @@ export async function init(cwd) {
36
36
  return;
37
37
  }
38
38
  }
39
+ console.log("Fetching latest components version...");
40
+ const componentsVersion = await fetchLatestComponentsVersion();
39
41
  const componentDir = await prompt("Component directory?", "src/components/ui");
40
42
  const cssPath = await prompt("CSS path?", `src/styles/${DEFAULT_CSS_FILENAME}`);
41
43
  const allNames = allComponentNames();
42
44
  const config = {
45
+ componentsVersion,
43
46
  componentDir,
44
47
  alias: "",
45
48
  aliasBase: "src",
@@ -47,7 +50,7 @@ export async function init(cwd) {
47
50
  components: allNames,
48
51
  };
49
52
  saveConfig(cwd, config);
50
- console.log(`\nCreated ${CONFIG_FILENAME} with ${allNames.length} components.`);
53
+ console.log(`\nCreated ${CONFIG_FILENAME} (components v${componentsVersion}, ${allNames.length} components)`);
51
54
  console.log("");
52
55
  console.log("Next steps:");
53
56
  console.log(` 1. Run: npx ${PROJECT_NAME} install`);
@@ -1,18 +1,13 @@
1
1
  import * as fs from "node:fs";
2
- import { createRequire } from "node:module";
3
2
  import * as path from "node:path";
4
3
  import { Readable } from "node:stream";
5
4
  import { pipeline } from "node:stream/promises";
6
5
  import { createGunzip } from "node:zlib";
7
6
  import { Parser } from "tar";
8
- import { CONFIG_FILENAME, DEFAULT_CSS_FILENAME, PROJECT_NAME, loadConfig } from "../config.js";
7
+ import { CONFIG_FILENAME, PROJECT_NAME, RELEASE_URL, loadConfig } from "../config.js";
9
8
  import { collectNpmDeps, registry, resolveDependencies } from "../registry.js";
10
9
  import { rewriteImports } from "../rewrite-imports.js";
11
- const RELEASE_URL = "https://github.com/misebox/soluid/releases/download";
12
- function getVersion() {
13
- const require = createRequire(import.meta.url);
14
- return require("../../package.json").componentsVersion;
15
- }
10
+ const ARCHIVE_PREFIX = "soluid/";
16
11
  function checkRateLimit(res) {
17
12
  const remaining = res.headers.get("X-RateLimit-Remaining");
18
13
  if (remaining !== null && parseInt(remaining, 10) <= 5) {
@@ -52,6 +47,13 @@ async function fetchAndExtract(version) {
52
47
  await pipeline(nodeStream, gunzip, parser);
53
48
  return files;
54
49
  }
50
+ /** Strip the "soluid/" prefix from an archive path for local placement. */
51
+ function stripPrefix(archivePath) {
52
+ if (archivePath.startsWith(ARCHIVE_PREFIX)) {
53
+ return archivePath.slice(ARCHIVE_PREFIX.length);
54
+ }
55
+ return archivePath;
56
+ }
55
57
  export async function install(cwd) {
56
58
  const config = loadConfig(cwd);
57
59
  if (config === null) {
@@ -73,10 +75,11 @@ export async function install(cwd) {
73
75
  const resolved = resolveDependencies(["core", ...config.components]);
74
76
  const npmDeps = collectNpmDeps(resolved);
75
77
  console.log(`Installing ${resolved.length} items (including dependencies):`);
76
- const version = getVersion();
78
+ const version = config.componentsVersion;
77
79
  const archive = await fetchAndExtract(version);
78
80
  const targetRoot = path.resolve(cwd, config.componentDir);
79
81
  let copiedCount = 0;
82
+ const cssChunks = [];
80
83
  for (const name of resolved) {
81
84
  const entry = registry[name];
82
85
  if (!entry)
@@ -87,20 +90,34 @@ export async function install(cwd) {
87
90
  console.warn(` SKIP (not in archive): ${file}`);
88
91
  continue;
89
92
  }
90
- const destPath = file === `core/${DEFAULT_CSS_FILENAME}`
91
- ? path.resolve(cwd, config.cssPath)
92
- : path.join(targetRoot, file);
93
+ const localPath = stripPrefix(file);
94
+ // CSS files: accumulate for concatenation instead of writing individually
95
+ if (file.endsWith(".css")) {
96
+ cssChunks.push(`/* ${localPath} */\n${content}`);
97
+ copiedCount++;
98
+ continue;
99
+ }
100
+ // TS/TSX files: strip prefix and write to componentDir
101
+ const destPath = path.join(targetRoot, localPath);
93
102
  const destDir = path.dirname(destPath);
94
103
  fs.mkdirSync(destDir, { recursive: true });
95
104
  let output = content;
96
105
  if (file.endsWith(".ts") || file.endsWith(".tsx")) {
97
- output = rewriteImports(content, file, config);
106
+ output = rewriteImports(content, localPath, config);
98
107
  }
99
108
  fs.writeFileSync(destPath, output, "utf-8");
100
109
  copiedCount++;
101
110
  }
102
111
  console.log(` + ${name}`);
103
112
  }
113
+ // Write concatenated CSS to cssPath
114
+ if (cssChunks.length > 0) {
115
+ const cssDestPath = path.resolve(cwd, config.cssPath);
116
+ const cssDestDir = path.dirname(cssDestPath);
117
+ fs.mkdirSync(cssDestDir, { recursive: true });
118
+ fs.writeFileSync(cssDestPath, cssChunks.join("\n\n") + "\n", "utf-8");
119
+ console.log(`\nCSS written to ${config.cssPath}`);
120
+ }
104
121
  console.log(`\nCopied ${copiedCount} files to ${config.componentDir}/`);
105
122
  if (npmDeps.length > 0) {
106
123
  console.log("\nRequired npm packages:");
@@ -13,7 +13,12 @@ export function list(cwd, filter) {
13
13
  const entry = registry[name];
14
14
  if (!entry)
15
15
  continue;
16
- const allExist = entry.files.every((file) => fs.existsSync(path.join(targetRoot, file)));
16
+ const allExist = entry.files
17
+ .filter((f) => !f.endsWith(".css"))
18
+ .every((file) => {
19
+ const local = file.startsWith("soluid/") ? file.slice("soluid/".length) : file;
20
+ return fs.existsSync(path.join(targetRoot, local));
21
+ });
17
22
  if (allExist)
18
23
  installed.add(name);
19
24
  }
@@ -28,7 +33,7 @@ export function list(cwd, filter) {
28
33
  continue;
29
34
  if (filter === "not-installed" && installed.has(name))
30
35
  continue;
31
- const cat = entry.category === "primitives" ? "Primitives" : capitalize(entry.category);
36
+ const cat = capitalize(entry.category);
32
37
  if (!categories.has(cat))
33
38
  categories.set(cat, []);
34
39
  const list = categories.get(cat);
package/dist/config.js CHANGED
@@ -3,13 +3,8 @@ import * as path from "node:path";
3
3
  export const PROJECT_NAME = "soluid";
4
4
  export const CONFIG_FILENAME = `${PROJECT_NAME}.config.json`;
5
5
  export const DEFAULT_CSS_FILENAME = `${PROJECT_NAME}.css`;
6
- export const defaultConfig = {
7
- componentDir: "src/components/ui",
8
- alias: "",
9
- aliasBase: "src",
10
- cssPath: `src/styles/${DEFAULT_CSS_FILENAME}`,
11
- components: [],
12
- };
6
+ export const GITHUB_REPO = "misebox/soluid";
7
+ export const RELEASE_URL = `https://github.com/${GITHUB_REPO}/releases/download`;
13
8
  export function findConfigPath(cwd) {
14
9
  return path.join(cwd, CONFIG_FILENAME);
15
10
  }
@@ -24,3 +19,17 @@ export function saveConfig(cwd, config) {
24
19
  const configPath = findConfigPath(cwd);
25
20
  fs.writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
26
21
  }
22
+ export async function fetchLatestComponentsVersion() {
23
+ const url = `https://api.github.com/repos/${GITHUB_REPO}/releases?per_page=20`;
24
+ const res = await fetch(url);
25
+ if (!res.ok) {
26
+ throw new Error(`Failed to fetch releases: ${res.status}`);
27
+ }
28
+ const releases = await res.json();
29
+ for (const r of releases) {
30
+ if (r.tag_name.startsWith("components-v")) {
31
+ return r.tag_name.replace("components-v", "");
32
+ }
33
+ }
34
+ throw new Error("No components release found");
35
+ }
package/dist/registry.js CHANGED
@@ -1,5 +1,6 @@
1
1
  /**
2
- * Core is always installed. It provides types, utils, CSS tokens, and theme.
2
+ * Core is always installed. It provides types, utils, CSS tokens, theme,
3
+ * and primitive utilities (createFocusTrap, createToast, createToggle).
3
4
  */
4
5
  export const registry = {
5
6
  // --- Core (always installed) ---
@@ -7,81 +8,48 @@ export const registry = {
7
8
  name: "core",
8
9
  category: "core",
9
10
  files: [
10
- "core/types.ts",
11
- "core/utils.ts",
12
- "core/soluid.css",
13
- "core/theme.ts",
11
+ "soluid/core/types.ts",
12
+ "soluid/core/utils.ts",
13
+ "soluid/core/soluid.css",
14
+ "soluid/core/theme.ts",
15
+ "soluid/core/createFocusTrap.ts",
16
+ "soluid/core/createToast.ts",
17
+ "soluid/core/createToggle.ts",
14
18
  ],
15
19
  dependencies: [],
16
- description: "Type definitions, CSS tokens, theme utilities",
17
- },
18
- // --- Primitives ---
19
- "createDisclosure": {
20
- name: "createDisclosure",
21
- category: "primitives",
22
- files: ["primitives/createDisclosure.ts"],
23
- dependencies: ["core"],
24
- description: "Open/close state management with a11y",
25
- },
26
- "createFocusTrap": {
27
- name: "createFocusTrap",
28
- category: "primitives",
29
- files: ["primitives/createFocusTrap.ts"],
30
- dependencies: ["core"],
31
20
  npmDependencies: [
32
21
  "@solid-primitives/active-element",
33
22
  "@solid-primitives/event-listener",
23
+ "@solid-primitives/scheduled",
34
24
  ],
35
- description: "Trap focus within a container element",
36
- },
37
- "createToggle": {
38
- name: "createToggle",
39
- category: "primitives",
40
- files: ["primitives/createToggle.ts"],
41
- dependencies: ["core"],
42
- description: "On/off toggle state with a11y",
43
- },
44
- "createToast": {
45
- name: "createToast",
46
- category: "primitives",
47
- files: ["primitives/createToast.ts"],
48
- dependencies: ["core"],
49
- npmDependencies: ["@solid-primitives/scheduled"],
50
- description: "Toast notification queue management",
51
- },
52
- "createPagination": {
53
- name: "createPagination",
54
- category: "primitives",
55
- files: ["primitives/createPagination.ts"],
56
- dependencies: ["core"],
57
- description: "Page state management",
25
+ description: "Type definitions, CSS tokens, theme utilities, primitives",
58
26
  },
59
27
  // --- Layout ---
60
28
  Stack: {
61
29
  name: "Stack",
62
30
  category: "components",
63
- files: ["components/layout/Stack.tsx", "components/layout/Stack.css"],
31
+ files: ["soluid/Stack.tsx", "soluid/Stack.css"],
64
32
  dependencies: ["core"],
65
33
  description: "Vertical flex layout with gap",
66
34
  },
67
35
  HStack: {
68
36
  name: "HStack",
69
37
  category: "components",
70
- files: ["components/layout/HStack.tsx", "components/layout/HStack.css"],
38
+ files: ["soluid/HStack.tsx", "soluid/HStack.css"],
71
39
  dependencies: ["core"],
72
40
  description: "Horizontal flex layout with gap",
73
41
  },
74
42
  Divider: {
75
43
  name: "Divider",
76
44
  category: "components",
77
- files: ["components/layout/Divider.tsx", "components/layout/Divider.css"],
45
+ files: ["soluid/Divider.tsx", "soluid/Divider.css"],
78
46
  dependencies: ["core"],
79
47
  description: "Horizontal/vertical separator",
80
48
  },
81
49
  Spacer: {
82
50
  name: "Spacer",
83
51
  category: "components",
84
- files: ["components/layout/Spacer.tsx", "components/layout/Spacer.css"],
52
+ files: ["soluid/Spacer.tsx", "soluid/Spacer.css"],
85
53
  dependencies: ["core"],
86
54
  description: "Flex spacer",
87
55
  },
@@ -89,49 +57,46 @@ export const registry = {
89
57
  Button: {
90
58
  name: "Button",
91
59
  category: "components",
92
- files: ["components/general/Button.tsx", "components/general/Button.css"],
60
+ files: ["soluid/Button.tsx", "soluid/Button.css"],
93
61
  dependencies: ["core"],
94
62
  description: "Primary, neutral, danger button with icon and loading",
95
63
  },
96
64
  IconButton: {
97
65
  name: "IconButton",
98
66
  category: "components",
99
- files: [
100
- "components/general/IconButton.tsx",
101
- "components/general/IconButton.css",
102
- ],
67
+ files: ["soluid/IconButton.tsx", "soluid/IconButton.css"],
103
68
  dependencies: ["core"],
104
69
  description: "Icon-only button with aria-label",
105
70
  },
106
71
  Badge: {
107
72
  name: "Badge",
108
73
  category: "components",
109
- files: ["components/general/Badge.tsx", "components/general/Badge.css"],
74
+ files: ["soluid/Badge.tsx", "soluid/Badge.css"],
110
75
  dependencies: ["core"],
111
76
  description: "Status label",
112
77
  },
113
78
  Tag: {
114
79
  name: "Tag",
115
80
  category: "components",
116
- files: ["components/general/Tag.tsx", "components/general/Tag.css"],
81
+ files: ["soluid/Tag.tsx", "soluid/Tag.css"],
117
82
  dependencies: ["core"],
118
83
  description: "Removable label for filters",
119
84
  },
120
85
  Tooltip: {
121
86
  name: "Tooltip",
122
87
  category: "components",
123
- files: ["components/general/Tooltip.tsx"],
88
+ files: ["soluid/Tooltip.tsx", "soluid/Tooltip.css"],
124
89
  dependencies: ["core"],
125
- description: "Tooltip (placeholder)",
90
+ description: "Tooltip",
126
91
  },
127
92
  // --- Form ---
128
93
  FormField: {
129
94
  name: "FormField",
130
95
  category: "components",
131
96
  files: [
132
- "components/form/FormField.tsx",
133
- "components/form/FormField.css",
134
- "components/form/FormFieldContext.ts",
97
+ "soluid/FormField.tsx",
98
+ "soluid/FormField.css",
99
+ "soluid/FormFieldContext.ts",
135
100
  ],
136
101
  dependencies: ["core"],
137
102
  description: "Label + error/hint wrapper for form inputs",
@@ -139,40 +104,28 @@ export const registry = {
139
104
  TextField: {
140
105
  name: "TextField",
141
106
  category: "components",
142
- files: [
143
- "components/form/TextField.tsx",
144
- "components/form/TextField.css",
145
- ],
107
+ files: ["soluid/TextField.tsx", "soluid/TextField.css"],
146
108
  dependencies: ["core", "FormField"],
147
109
  description: "Text input with label/error/hint",
148
110
  },
149
111
  TextArea: {
150
112
  name: "TextArea",
151
113
  category: "components",
152
- files: [
153
- "components/form/TextArea.tsx",
154
- "components/form/TextArea.css",
155
- ],
114
+ files: ["soluid/TextArea.tsx", "soluid/TextArea.css"],
156
115
  dependencies: ["core", "FormField"],
157
116
  description: "Multiline text input",
158
117
  },
159
118
  NumberInput: {
160
119
  name: "NumberInput",
161
120
  category: "components",
162
- files: [
163
- "components/form/NumberInput.tsx",
164
- "components/form/NumberInput.css",
165
- ],
121
+ files: ["soluid/NumberInput.tsx", "soluid/NumberInput.css"],
166
122
  dependencies: ["core", "FormField"],
167
123
  description: "Number input with stepper buttons",
168
124
  },
169
125
  Select: {
170
126
  name: "Select",
171
127
  category: "components",
172
- files: [
173
- "components/form/Select.tsx",
174
- "components/form/Select.css",
175
- ],
128
+ files: ["soluid/Select.tsx", "soluid/Select.css"],
176
129
  dependencies: ["core", "FormField"],
177
130
  description: "Native select dropdown",
178
131
  },
@@ -180,9 +133,9 @@ export const registry = {
180
133
  name: "Checkbox",
181
134
  category: "components",
182
135
  files: [
183
- "components/form/Checkbox.tsx",
184
- "components/form/Checkbox.css",
185
- "components/form/CheckboxGroupContext.ts",
136
+ "soluid/Checkbox.tsx",
137
+ "soluid/Checkbox.css",
138
+ "soluid/CheckboxGroupContext.ts",
186
139
  ],
187
140
  dependencies: ["core"],
188
141
  description: "Checkbox with indeterminate support",
@@ -190,10 +143,7 @@ export const registry = {
190
143
  CheckboxGroup: {
191
144
  name: "CheckboxGroup",
192
145
  category: "components",
193
- files: [
194
- "components/form/CheckboxGroup.tsx",
195
- "components/form/CheckboxGroup.css",
196
- ],
146
+ files: ["soluid/CheckboxGroup.tsx", "soluid/CheckboxGroup.css"],
197
147
  dependencies: ["core", "Checkbox"],
198
148
  description: "Checkbox group with shared state",
199
149
  },
@@ -201,11 +151,11 @@ export const registry = {
201
151
  name: "RadioGroup",
202
152
  category: "components",
203
153
  files: [
204
- "components/form/RadioGroup.tsx",
205
- "components/form/RadioGroup.css",
206
- "components/form/RadioGroupContext.ts",
207
- "components/form/RadioButton.tsx",
208
- "components/form/RadioButton.css",
154
+ "soluid/RadioGroup.tsx",
155
+ "soluid/RadioGroup.css",
156
+ "soluid/RadioGroupContext.ts",
157
+ "soluid/RadioButton.tsx",
158
+ "soluid/RadioButton.css",
209
159
  ],
210
160
  dependencies: ["core"],
211
161
  description: "Radio button group",
@@ -213,52 +163,43 @@ export const registry = {
213
163
  Switch: {
214
164
  name: "Switch",
215
165
  category: "components",
216
- files: [
217
- "components/form/Switch.tsx",
218
- "components/form/Switch.css",
219
- ],
220
- dependencies: ["core", "createToggle"],
166
+ files: ["soluid/Switch.tsx", "soluid/Switch.css"],
167
+ dependencies: ["core"],
221
168
  description: "Toggle switch",
222
169
  },
223
170
  // --- Data Display ---
224
171
  Table: {
225
172
  name: "Table",
226
173
  category: "components",
227
- files: ["components/data/Table.tsx", "components/data/Table.css"],
174
+ files: ["soluid/Table.tsx", "soluid/Table.css"],
228
175
  dependencies: ["core"],
229
176
  description: "Data table with sort, pagination, row selection",
230
177
  },
231
178
  Card: {
232
179
  name: "Card",
233
180
  category: "components",
234
- files: ["components/data/Card.tsx", "components/data/Card.css"],
181
+ files: ["soluid/Card.tsx", "soluid/Card.css"],
235
182
  dependencies: ["core"],
236
183
  description: "Content card with header/body/footer",
237
184
  },
238
185
  DescriptionList: {
239
186
  name: "DescriptionList",
240
187
  category: "components",
241
- files: [
242
- "components/data/DescriptionList.tsx",
243
- "components/data/DescriptionList.css",
244
- ],
188
+ files: ["soluid/DescriptionList.tsx", "soluid/DescriptionList.css"],
245
189
  dependencies: ["core"],
246
190
  description: "Key-value display",
247
191
  },
248
192
  Skeleton: {
249
193
  name: "Skeleton",
250
194
  category: "components",
251
- files: ["components/data/Skeleton.tsx", "components/data/Skeleton.css"],
195
+ files: ["soluid/Skeleton.tsx", "soluid/Skeleton.css"],
252
196
  dependencies: ["core"],
253
197
  description: "Loading placeholder",
254
198
  },
255
199
  EmptyState: {
256
200
  name: "EmptyState",
257
201
  category: "components",
258
- files: [
259
- "components/data/EmptyState.tsx",
260
- "components/data/EmptyState.css",
261
- ],
202
+ files: ["soluid/EmptyState.tsx", "soluid/EmptyState.css"],
262
203
  dependencies: ["core"],
263
204
  description: "Empty data display with action",
264
205
  },
@@ -266,48 +207,42 @@ export const registry = {
266
207
  Dialog: {
267
208
  name: "Dialog",
268
209
  category: "components",
269
- files: ["components/feedback/Dialog.tsx", "components/feedback/Dialog.css"],
270
- dependencies: ["core", "createFocusTrap"],
210
+ files: ["soluid/Dialog.tsx", "soluid/Dialog.css"],
211
+ dependencies: ["core"],
271
212
  description: "Modal dialog with focus trap",
272
213
  },
273
214
  Drawer: {
274
215
  name: "Drawer",
275
216
  category: "components",
276
- files: ["components/feedback/Drawer.tsx", "components/feedback/Drawer.css"],
277
- dependencies: ["core", "createFocusTrap"],
217
+ files: ["soluid/Drawer.tsx", "soluid/Drawer.css"],
218
+ dependencies: ["core"],
278
219
  description: "Side panel with focus trap",
279
220
  },
280
221
  Alert: {
281
222
  name: "Alert",
282
223
  category: "components",
283
- files: ["components/feedback/Alert.tsx", "components/feedback/Alert.css"],
224
+ files: ["soluid/Alert.tsx", "soluid/Alert.css"],
284
225
  dependencies: ["core"],
285
226
  description: "Inline notification",
286
227
  },
287
228
  Toast: {
288
229
  name: "Toast",
289
230
  category: "components",
290
- files: ["components/feedback/Toast.tsx", "components/feedback/Toast.css"],
291
- dependencies: ["core", "createToast"],
231
+ files: ["soluid/Toast.tsx", "soluid/Toast.css"],
232
+ dependencies: ["core"],
292
233
  description: "Toast notification with queue",
293
234
  },
294
235
  Progress: {
295
236
  name: "Progress",
296
237
  category: "components",
297
- files: [
298
- "components/feedback/Progress.tsx",
299
- "components/feedback/Progress.css",
300
- ],
238
+ files: ["soluid/Progress.tsx", "soluid/Progress.css"],
301
239
  dependencies: ["core"],
302
240
  description: "Progress bar",
303
241
  },
304
242
  Spinner: {
305
243
  name: "Spinner",
306
244
  category: "components",
307
- files: [
308
- "components/feedback/Spinner.tsx",
309
- "components/feedback/Spinner.css",
310
- ],
245
+ files: ["soluid/Spinner.tsx", "soluid/Spinner.css"],
311
246
  dependencies: ["core"],
312
247
  description: "Loading spinner",
313
248
  },
@@ -315,34 +250,28 @@ export const registry = {
315
250
  Tabs: {
316
251
  name: "Tabs",
317
252
  category: "components",
318
- files: ["components/navigation/Tabs.tsx", "components/navigation/Tabs.css"],
253
+ files: ["soluid/Tabs.tsx", "soluid/Tabs.css"],
319
254
  dependencies: ["core"],
320
255
  description: "Tab navigation",
321
256
  },
322
257
  Breadcrumb: {
323
258
  name: "Breadcrumb",
324
259
  category: "components",
325
- files: [
326
- "components/navigation/Breadcrumb.tsx",
327
- "components/navigation/Breadcrumb.css",
328
- ],
260
+ files: ["soluid/Breadcrumb.tsx", "soluid/Breadcrumb.css"],
329
261
  dependencies: ["core"],
330
262
  description: "Breadcrumb navigation",
331
263
  },
332
264
  Pagination: {
333
265
  name: "Pagination",
334
266
  category: "components",
335
- files: [
336
- "components/navigation/Pagination.tsx",
337
- "components/navigation/Pagination.css",
338
- ],
267
+ files: ["soluid/Pagination.tsx", "soluid/Pagination.css"],
339
268
  dependencies: ["core"],
340
269
  description: "Page navigation",
341
270
  },
342
271
  Menu: {
343
272
  name: "Menu",
344
273
  category: "components",
345
- files: ["components/navigation/Menu.tsx"],
274
+ files: ["soluid/Menu.tsx"],
346
275
  dependencies: ["core"],
347
276
  description: "Dropdown menu (placeholder)",
348
277
  },
@@ -350,17 +279,14 @@ export const registry = {
350
279
  VisuallyHidden: {
351
280
  name: "VisuallyHidden",
352
281
  category: "components",
353
- files: [
354
- "components/utility/VisuallyHidden.tsx",
355
- "components/utility/VisuallyHidden.css",
356
- ],
282
+ files: ["soluid/VisuallyHidden.tsx", "soluid/VisuallyHidden.css"],
357
283
  dependencies: [],
358
284
  description: "Screen reader only content",
359
285
  },
360
286
  Popover: {
361
287
  name: "Popover",
362
288
  category: "components",
363
- files: ["components/utility/Popover.tsx"],
289
+ files: ["soluid/Popover.tsx"],
364
290
  dependencies: ["core"],
365
291
  description: "Floating element (placeholder)",
366
292
  },
@@ -3,14 +3,13 @@ import * as path from "node:path";
3
3
  * Rewrite internal soluid imports in a template file.
4
4
  *
5
5
  * Template files use relative imports like:
6
- * import { cls } from "../../core/utils"
6
+ * import { cls } from "./core/utils"
7
7
  * import { FormField } from "./FormField"
8
- * import { createFocusTrap } from "../../primitives/createFocusTrap"
9
8
  *
10
9
  * These need to be rewritten to point to the correct location
11
10
  * in the user's project, using either an alias or relative paths.
12
11
  */
13
- export function rewriteImports(content, filePath, // path of this file relative to componentDir (e.g. "components/form/TextField.tsx")
12
+ export function rewriteImports(content, filePath, // path of this file relative to componentDir (e.g. "Button.tsx", "core/types.ts")
14
13
  config) {
15
14
  // Match import statements with relative paths (starting with . or ..)
16
15
  const importRegex = /((?:import|export)\s+(?:type\s+)?(?:\{[^}]*\}|[\w*]+(?:\s*,\s*\{[^}]*\})?)\s+from\s+["'])(\.[^"']+)(["'])/g;
package/package.json CHANGED
@@ -1,7 +1,6 @@
1
1
  {
2
2
  "name": "soluid",
3
- "version": "0.1.2",
4
- "componentsVersion": "0.1.0",
3
+ "version": "0.1.3",
5
4
  "type": "module",
6
5
  "description": "SolidJS Opinionated UI - copy-paste component toolkit",
7
6
  "license": "MIT",
@@ -22,6 +21,9 @@
22
21
  "lint:fix": "oxlint --fix src/ cli/"
23
22
  },
24
23
  "devDependencies": {
24
+ "@solid-primitives/active-element": "^2.1.5",
25
+ "@solid-primitives/event-listener": "^2.4.5",
26
+ "@solid-primitives/scheduled": "^1.5.3",
25
27
  "@types/node": "^20.19.34",
26
28
  "dprint": "^0.52.0",
27
29
  "oxlint": "^1.50.0",