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 +17 -5
- package/dist/commands/init.js +5 -2
- package/dist/commands/install.js +29 -12
- package/dist/commands/list.js +7 -2
- package/dist/config.js +16 -7
- package/dist/registry.js +59 -133
- package/dist/rewrite-imports.js +2 -3
- package/package.json +4 -2
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
|
|
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
|
|
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
|
|
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
|
-
##
|
|
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
|
-
|
|
77
|
+
Starts the component catalog for local preview.
|
package/dist/commands/init.js
CHANGED
|
@@ -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}
|
|
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`);
|
package/dist/commands/install.js
CHANGED
|
@@ -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,
|
|
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
|
|
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 =
|
|
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
|
|
91
|
-
|
|
92
|
-
|
|
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,
|
|
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:");
|
package/dist/commands/list.js
CHANGED
|
@@ -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
|
|
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 =
|
|
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
|
|
7
|
-
|
|
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,
|
|
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: "
|
|
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: ["
|
|
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: ["
|
|
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: ["
|
|
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: ["
|
|
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: ["
|
|
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: ["
|
|
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: ["
|
|
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: ["
|
|
88
|
+
files: ["soluid/Tooltip.tsx", "soluid/Tooltip.css"],
|
|
124
89
|
dependencies: ["core"],
|
|
125
|
-
description: "Tooltip
|
|
90
|
+
description: "Tooltip",
|
|
126
91
|
},
|
|
127
92
|
// --- Form ---
|
|
128
93
|
FormField: {
|
|
129
94
|
name: "FormField",
|
|
130
95
|
category: "components",
|
|
131
96
|
files: [
|
|
132
|
-
"
|
|
133
|
-
"
|
|
134
|
-
"
|
|
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
|
-
"
|
|
184
|
-
"
|
|
185
|
-
"
|
|
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
|
-
"
|
|
205
|
-
"
|
|
206
|
-
"
|
|
207
|
-
"
|
|
208
|
-
"
|
|
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
|
-
|
|
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: ["
|
|
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: ["
|
|
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: ["
|
|
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: ["
|
|
270
|
-
dependencies: ["core"
|
|
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: ["
|
|
277
|
-
dependencies: ["core"
|
|
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: ["
|
|
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: ["
|
|
291
|
-
dependencies: ["core"
|
|
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: ["
|
|
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: ["
|
|
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: ["
|
|
289
|
+
files: ["soluid/Popover.tsx"],
|
|
364
290
|
dependencies: ["core"],
|
|
365
291
|
description: "Floating element (placeholder)",
|
|
366
292
|
},
|
package/dist/rewrite-imports.js
CHANGED
|
@@ -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 "
|
|
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. "
|
|
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.
|
|
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",
|