shru-design-system 0.1.0 → 0.1.1

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 (3) hide show
  1. package/README.md +154 -29
  2. package/package.json +8 -3
  3. package/scripts/init.js +305 -0
package/README.md CHANGED
@@ -1,59 +1,184 @@
1
1
  # shru-design-system
2
2
 
3
- A minimal React component library.
3
+ A React component library with atoms and molecules built on Radix UI and Tailwind CSS.
4
4
 
5
- ## Setup
5
+ ## Installation
6
6
 
7
7
  ```bash
8
- npm install
9
- npm run build
8
+ npm install shru-design-system
10
9
  ```
11
10
 
12
- ## Development
11
+ ## Quick Setup
13
12
 
14
- The package is built using `tsup` and outputs both ESM and CJS formats.
13
+ After installation, run the setup script to configure Tailwind CSS:
15
14
 
16
- ## Testing
15
+ ```bash
16
+ npx shru-design-system-init
17
+ ```
18
+
19
+ Or it will run automatically after `npm install` (you can skip this step if it already ran).
20
+
21
+ ## Manual Setup
22
+
23
+ If you prefer to set up manually or the automatic setup didn't work:
17
24
 
18
- A test app is available in the `test/` folder:
25
+ ### 1. Install Tailwind CSS
19
26
 
20
27
  ```bash
21
- cd test
22
- npm install
23
- npm run dev
28
+ npm install -D tailwindcss postcss autoprefixer
29
+ npx tailwindcss init -p
24
30
  ```
25
31
 
26
- The test app installs the package locally using `file:..` and demonstrates the Button component.
27
-
28
- ## Package Structure
32
+ ### 2. Configure Tailwind
33
+
34
+ Update `tailwind.config.js`:
35
+
36
+ ```js
37
+ export default {
38
+ content: [
39
+ "./index.html",
40
+ "./src/**/*.{js,ts,jsx,tsx}",
41
+ "./node_modules/shru-design-system/dist/**/*.{js,mjs}",
42
+ ],
43
+ theme: {
44
+ extend: {
45
+ colors: {
46
+ background: "hsl(var(--background))",
47
+ foreground: "hsl(var(--foreground))",
48
+ primary: {
49
+ DEFAULT: "hsl(var(--primary))",
50
+ foreground: "hsl(var(--primary-foreground))",
51
+ },
52
+ secondary: {
53
+ DEFAULT: "hsl(var(--secondary))",
54
+ foreground: "hsl(var(--secondary-foreground))",
55
+ },
56
+ destructive: {
57
+ DEFAULT: "hsl(var(--destructive))",
58
+ foreground: "hsl(var(--destructive-foreground))",
59
+ },
60
+ muted: {
61
+ DEFAULT: "hsl(var(--muted))",
62
+ foreground: "hsl(var(--muted-foreground))",
63
+ },
64
+ accent: {
65
+ DEFAULT: "hsl(var(--accent))",
66
+ foreground: "hsl(var(--accent-foreground))",
67
+ },
68
+ popover: {
69
+ DEFAULT: "hsl(var(--popover))",
70
+ foreground: "hsl(var(--popover-foreground))",
71
+ },
72
+ border: "hsl(var(--border))",
73
+ input: "hsl(var(--input))",
74
+ ring: "hsl(var(--ring))",
75
+ },
76
+ borderRadius: {
77
+ lg: "var(--radius)",
78
+ md: "calc(var(--radius) - 2px)",
79
+ sm: "calc(var(--radius) - 4px)",
80
+ },
81
+ },
82
+ },
83
+ plugins: [],
84
+ }
85
+ ```
29
86
 
87
+ ### 3. Add CSS Variables
88
+
89
+ Create or update `src/index.css`:
90
+
91
+ ```css
92
+ @tailwind base;
93
+ @tailwind components;
94
+ @tailwind utilities;
95
+
96
+ @layer base {
97
+ :root {
98
+ --background: 0 0% 100%;
99
+ --foreground: 222.2 84% 4.9%;
100
+ --primary: 222.2 47.4% 11.2%;
101
+ --primary-foreground: 210 40% 98%;
102
+ --secondary: 210 40% 96.1%;
103
+ --secondary-foreground: 222.2 47.4% 11.2%;
104
+ --destructive: 0 84.2% 60.2%;
105
+ --destructive-foreground: 210 40% 98%;
106
+ --muted: 210 40% 96.1%;
107
+ --muted-foreground: 215.4 16.3% 46.9%;
108
+ --accent: 210 40% 96.1%;
109
+ --accent-foreground: 222.2 47.4% 11.2%;
110
+ --popover: 0 0% 100%;
111
+ --popover-foreground: 222.2 84% 4.9%;
112
+ --border: 214.3 31.8% 91.4%;
113
+ --input: 214.3 31.8% 91.4%;
114
+ --ring: 222.2 84% 4.9%;
115
+ --radius: 0.5rem;
116
+ }
117
+
118
+ * {
119
+ border-color: hsl(var(--border));
120
+ }
121
+
122
+ body {
123
+ background-color: hsl(var(--background));
124
+ color: hsl(var(--foreground));
125
+ }
126
+ }
30
127
  ```
31
- .
32
- ├── src/
33
- │ ├── Button.tsx # Button component
34
- │ └── index.ts # Package exports
35
- ├── dist/ # Built output (ESM + CJS)
36
- ├── test/ # Test application
37
- └── package.json # Package configuration
128
+
129
+ ### 4. Import CSS
130
+
131
+ Import the CSS file in your entry point (e.g., `src/main.tsx`):
132
+
133
+ ```tsx
134
+ import './index.css'
38
135
  ```
39
136
 
40
137
  ## Usage
41
138
 
42
139
  ```tsx
43
- import { Button } from 'shru-design-system'
140
+ import { Button, Badge, Modal, Select } from 'shru-design-system'
44
141
 
45
142
  function App() {
46
143
  return (
47
- <Button variant="primary" size="md">
48
- Click me
49
- </Button>
144
+ <div>
145
+ <Button variant="default">Click me</Button>
146
+ <Badge>New</Badge>
147
+
148
+ <Modal>
149
+ <ModalTrigger asChild>
150
+ <Button>Open Modal</Button>
151
+ </ModalTrigger>
152
+ <ModalContent>
153
+ <ModalHeader>
154
+ <ModalTitle>Hello</ModalTitle>
155
+ <ModalDescription>This is a modal</ModalDescription>
156
+ </ModalHeader>
157
+ </ModalContent>
158
+ </Modal>
159
+ </div>
50
160
  )
51
161
  }
52
162
  ```
53
163
 
54
- ## Button Props
164
+ ## Components
165
+
166
+ ### Atoms
167
+ - **Button** - Versatile button with multiple variants and sizes
168
+ - **Badge** - Small status indicators
169
+
170
+ ### Molecules
171
+ - **Modal** - Dialog component with overlay
172
+ - **Select** - Dropdown select component
173
+
174
+ ## Peer Dependencies
175
+
176
+ Make sure to install these peer dependencies:
177
+
178
+ ```bash
179
+ npm install @radix-ui/react-slot @radix-ui/react-dialog @radix-ui/react-select class-variance-authority clsx tailwind-merge lucide-react
180
+ ```
55
181
 
56
- - `variant`: "primary" | "secondary" | "outline" (default: "primary")
57
- - `size`: "sm" | "md" | "lg" (default: "md")
58
- - All standard HTML button attributes are supported
182
+ ## License
59
183
 
184
+ MIT
package/package.json CHANGED
@@ -1,13 +1,17 @@
1
1
  {
2
2
  "name": "shru-design-system",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "A React component library with atoms and molecules built on Radix UI and Tailwind CSS",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
7
7
  "types": "dist/index.d.ts",
8
8
  "files": [
9
- "dist"
9
+ "dist",
10
+ "scripts"
10
11
  ],
12
+ "bin": {
13
+ "shru-design-system-init": "./scripts/init.js"
14
+ },
11
15
  "exports": {
12
16
  ".": {
13
17
  "types": "./dist/index.d.ts",
@@ -17,7 +21,8 @@
17
21
  },
18
22
  "scripts": {
19
23
  "build": "tsup src/index.ts --dts --format esm,cjs",
20
- "prepublishOnly": "npm run build"
24
+ "prepublishOnly": "npm run build",
25
+ "postinstall": "node scripts/init.js || true"
21
26
  },
22
27
  "peerDependencies": {
23
28
  "react": ">=18",
@@ -0,0 +1,305 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * shru-design-system init script
5
+ * Sets up Tailwind CSS and required configuration
6
+ */
7
+
8
+ const fs = require('fs');
9
+ const path = require('path');
10
+ const { execSync } = require('child_process');
11
+
12
+ const colors = {
13
+ reset: '\x1b[0m',
14
+ green: '\x1b[32m',
15
+ yellow: '\x1b[33m',
16
+ blue: '\x1b[34m',
17
+ red: '\x1b[31m',
18
+ };
19
+
20
+ function log(message, color = 'reset') {
21
+ console.log(`${colors[color]}${message}${colors.reset}`);
22
+ }
23
+
24
+ function checkPackageInstalled(packageName) {
25
+ try {
26
+ require.resolve(packageName);
27
+ return true;
28
+ } catch {
29
+ return false;
30
+ }
31
+ }
32
+
33
+ function installPackage(packageName, isDev = true) {
34
+ log(`Installing ${packageName}...`, 'blue');
35
+ try {
36
+ execSync(`npm install ${isDev ? '-D' : ''} ${packageName}`, { stdio: 'inherit' });
37
+ return true;
38
+ } catch (error) {
39
+ log(`Failed to install ${packageName}`, 'red');
40
+ return false;
41
+ }
42
+ }
43
+
44
+ function createTailwindConfig() {
45
+ const configPath = path.join(process.cwd(), 'tailwind.config.js');
46
+
47
+ if (fs.existsSync(configPath)) {
48
+ log('tailwind.config.js already exists. Updating it...', 'yellow');
49
+ const existing = fs.readFileSync(configPath, 'utf8');
50
+
51
+ // Check if our config is already there
52
+ if (existing.includes('shru-design-system')) {
53
+ log('Configuration already includes shru-design-system setup.', 'green');
54
+ return;
55
+ }
56
+
57
+ // Try to merge (basic approach - user might need to do this manually)
58
+ log('Please manually merge the Tailwind config. See docs for details.', 'yellow');
59
+ return;
60
+ }
61
+
62
+ const config = `/** @type {import('tailwindcss').Config} */
63
+ export default {
64
+ content: [
65
+ "./index.html",
66
+ "./src/**/*.{js,ts,jsx,tsx}",
67
+ "./node_modules/shru-design-system/dist/**/*.{js,mjs}",
68
+ ],
69
+ theme: {
70
+ extend: {
71
+ colors: {
72
+ background: "hsl(var(--background))",
73
+ foreground: "hsl(var(--foreground))",
74
+ primary: {
75
+ DEFAULT: "hsl(var(--primary))",
76
+ foreground: "hsl(var(--primary-foreground))",
77
+ },
78
+ secondary: {
79
+ DEFAULT: "hsl(var(--secondary))",
80
+ foreground: "hsl(var(--secondary-foreground))",
81
+ },
82
+ destructive: {
83
+ DEFAULT: "hsl(var(--destructive))",
84
+ foreground: "hsl(var(--destructive-foreground))",
85
+ },
86
+ muted: {
87
+ DEFAULT: "hsl(var(--muted))",
88
+ foreground: "hsl(var(--muted-foreground))",
89
+ },
90
+ accent: {
91
+ DEFAULT: "hsl(var(--accent))",
92
+ foreground: "hsl(var(--accent-foreground))",
93
+ },
94
+ popover: {
95
+ DEFAULT: "hsl(var(--popover))",
96
+ foreground: "hsl(var(--popover-foreground))",
97
+ },
98
+ border: "hsl(var(--border))",
99
+ input: "hsl(var(--input))",
100
+ ring: "hsl(var(--ring))",
101
+ },
102
+ borderRadius: {
103
+ lg: "var(--radius)",
104
+ md: "calc(var(--radius) - 2px)",
105
+ sm: "calc(var(--radius) - 4px)",
106
+ },
107
+ },
108
+ },
109
+ plugins: [],
110
+ }
111
+ `;
112
+
113
+ fs.writeFileSync(configPath, config);
114
+ log('Created tailwind.config.js', 'green');
115
+ }
116
+
117
+ function createPostCSSConfig() {
118
+ const configPath = path.join(process.cwd(), 'postcss.config.js');
119
+
120
+ if (fs.existsSync(configPath)) {
121
+ log('postcss.config.js already exists. Skipping...', 'yellow');
122
+ return;
123
+ }
124
+
125
+ const config = `export default {
126
+ plugins: {
127
+ tailwindcss: {},
128
+ autoprefixer: {},
129
+ },
130
+ }
131
+ `;
132
+
133
+ fs.writeFileSync(configPath, config);
134
+ log('Created postcss.config.js', 'green');
135
+ }
136
+
137
+ function createCSSFile() {
138
+ const cssPath = path.join(process.cwd(), 'src', 'index.css');
139
+ const cssDir = path.dirname(cssPath);
140
+
141
+ // Create src directory if it doesn't exist
142
+ if (!fs.existsSync(cssDir)) {
143
+ fs.mkdirSync(cssDir, { recursive: true });
144
+ }
145
+
146
+ if (fs.existsSync(cssPath)) {
147
+ log('src/index.css already exists. Checking if variables are defined...', 'yellow');
148
+ const existing = fs.readFileSync(cssPath, 'utf8');
149
+
150
+ if (existing.includes('--primary')) {
151
+ log('CSS variables already defined.', 'green');
152
+ return;
153
+ }
154
+
155
+ // Append to existing file
156
+ const cssVars = `
157
+
158
+ /* shru-design-system CSS variables */
159
+ @layer base {
160
+ :root {
161
+ --background: 0 0% 100%;
162
+ --foreground: 222.2 84% 4.9%;
163
+ --primary: 222.2 47.4% 11.2%;
164
+ --primary-foreground: 210 40% 98%;
165
+ --secondary: 210 40% 96.1%;
166
+ --secondary-foreground: 222.2 47.4% 11.2%;
167
+ --destructive: 0 84.2% 60.2%;
168
+ --destructive-foreground: 210 40% 98%;
169
+ --muted: 210 40% 96.1%;
170
+ --muted-foreground: 215.4 16.3% 46.9%;
171
+ --accent: 210 40% 96.1%;
172
+ --accent-foreground: 222.2 47.4% 11.2%;
173
+ --popover: 0 0% 100%;
174
+ --popover-foreground: 222.2 84% 4.9%;
175
+ --border: 214.3 31.8% 91.4%;
176
+ --input: 214.3 31.8% 91.4%;
177
+ --ring: 222.2 84% 4.9%;
178
+ --radius: 0.5rem;
179
+ }
180
+
181
+ * {
182
+ border-color: hsl(var(--border));
183
+ }
184
+
185
+ body {
186
+ background-color: hsl(var(--background));
187
+ color: hsl(var(--foreground));
188
+ }
189
+ }
190
+ `;
191
+ fs.appendFileSync(cssPath, cssVars);
192
+ log('Added CSS variables to existing index.css', 'green');
193
+ return;
194
+ }
195
+
196
+ const css = `@tailwind base;
197
+ @tailwind components;
198
+ @tailwind utilities;
199
+
200
+ @layer base {
201
+ :root {
202
+ --background: 0 0% 100%;
203
+ --foreground: 222.2 84% 4.9%;
204
+ --primary: 222.2 47.4% 11.2%;
205
+ --primary-foreground: 210 40% 98%;
206
+ --secondary: 210 40% 96.1%;
207
+ --secondary-foreground: 222.2 47.4% 11.2%;
208
+ --destructive: 0 84.2% 60.2%;
209
+ --destructive-foreground: 210 40% 98%;
210
+ --muted: 210 40% 96.1%;
211
+ --muted-foreground: 215.4 16.3% 46.9%;
212
+ --accent: 210 40% 96.1%;
213
+ --accent-foreground: 222.2 47.4% 11.2%;
214
+ --popover: 0 0% 100%;
215
+ --popover-foreground: 222.2 84% 4.9%;
216
+ --border: 214.3 31.8% 91.4%;
217
+ --input: 214.3 31.8% 91.4%;
218
+ --ring: 222.2 84% 4.9%;
219
+ --radius: 0.5rem;
220
+ }
221
+
222
+ * {
223
+ border-color: hsl(var(--border));
224
+ }
225
+
226
+ body {
227
+ background-color: hsl(var(--background));
228
+ color: hsl(var(--foreground));
229
+ }
230
+ }
231
+ `;
232
+
233
+ fs.writeFileSync(cssPath, css);
234
+ log('Created src/index.css', 'green');
235
+ }
236
+
237
+ function checkMainFile() {
238
+ const possiblePaths = [
239
+ path.join(process.cwd(), 'src', 'main.tsx'),
240
+ path.join(process.cwd(), 'src', 'main.ts'),
241
+ path.join(process.cwd(), 'src', 'index.tsx'),
242
+ path.join(process.cwd(), 'src', 'index.ts'),
243
+ path.join(process.cwd(), 'src', 'App.tsx'),
244
+ ];
245
+
246
+ for (const filePath of possiblePaths) {
247
+ if (fs.existsSync(filePath)) {
248
+ const content = fs.readFileSync(filePath, 'utf8');
249
+ if (!content.includes("index.css") && !content.includes("'./index.css'")) {
250
+ log(`\n⚠️ Don't forget to import the CSS file in your entry point:`, 'yellow');
251
+ log(` import './index.css'`, 'blue');
252
+ log(` Add this to: ${filePath}\n`, 'yellow');
253
+ } else {
254
+ log('CSS import found in entry file.', 'green');
255
+ }
256
+ return;
257
+ }
258
+ }
259
+
260
+ log('\n⚠️ Could not find entry file. Please manually import:', 'yellow');
261
+ log(" import './index.css'", 'blue');
262
+ }
263
+
264
+ // Main execution
265
+ function main() {
266
+ log('\n🚀 Setting up shru-design-system...\n', 'blue');
267
+
268
+ // Check and install Tailwind
269
+ if (!checkPackageInstalled('tailwindcss')) {
270
+ log('Tailwind CSS not found. Installing...', 'yellow');
271
+ if (!installPackage('tailwindcss@^3.4.0')) {
272
+ log('Failed to install Tailwind CSS. Please install manually.', 'red');
273
+ process.exit(1);
274
+ }
275
+ } else {
276
+ log('Tailwind CSS already installed.', 'green');
277
+ }
278
+
279
+ // Check and install PostCSS
280
+ if (!checkPackageInstalled('postcss')) {
281
+ installPackage('postcss');
282
+ }
283
+
284
+ // Check and install Autoprefixer
285
+ if (!checkPackageInstalled('autoprefixer')) {
286
+ installPackage('autoprefixer');
287
+ }
288
+
289
+ // Create configuration files
290
+ createTailwindConfig();
291
+ createPostCSSConfig();
292
+ createCSSFile();
293
+ checkMainFile();
294
+
295
+ log('\n✅ Setup complete!', 'green');
296
+ log('\nNext steps:', 'blue');
297
+ log('1. Make sure to import the CSS file in your entry point:', 'yellow');
298
+ log(" import './index.css'", 'blue');
299
+ log('2. Start using components:', 'yellow');
300
+ log(" import { Button } from 'shru-design-system'", 'blue');
301
+ log('\n');
302
+ }
303
+
304
+ main();
305
+