shru-design-system 0.0.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.
package/README.md ADDED
@@ -0,0 +1,131 @@
1
+ # Design System Repository
2
+
3
+ A comprehensive design system with 72+ reusable components and a theme management library. This monorepo contains both a Next.js showcase application and publishable npm libraries.
4
+
5
+ ## Purpose
6
+
7
+ A design system with 72+ reusable components and a theme management library. Includes both a Next.js showcase application and publishable npm libraries.
8
+
9
+ ## Key Features
10
+
11
+ ### Design System Components
12
+ - **72+ Components** organized by category (atoms, molecules, layout, primitives)
13
+ - **Radix UI Based** - Accessible, unstyled primitives with custom styling
14
+ - **Tailwind CSS** - Utility-first styling with CSS variables
15
+ - **TypeScript** - Full type definitions for all components
16
+ - **Component Showcases** - Live, interactive examples for every component
17
+
18
+ ### Theme System
19
+ - **Token-based Theming** with multi-category support (color, typography, shape, density, animation)
20
+ - **Reusable Library** - Theme toggle component and utilities published as `@shru/design-system`
21
+ - **Zero CSS Imports** - CSS variables generated and injected automatically
22
+ - **Dynamic Theme Switching** - Runtime theme composition and application
23
+ - **Modular Architecture** - Clean separation of UI, hooks, config, and utilities
24
+
25
+ ### Architecture
26
+ - **Module-based Structure** - Clean separation of UI, hooks, config, and utils
27
+ - **Centralized Exports** - Clean import paths with `index.ts` files
28
+ - **Atomic Design** - Components organized by complexity and purpose
29
+
30
+ ## Installation
31
+
32
+ ```bash
33
+ npm install @shru/design-system
34
+ # or
35
+ pnpm add @shru/design-system
36
+ ```
37
+
38
+ ## Quick Start
39
+
40
+ ```tsx
41
+ // 1. Import CSS (required)
42
+ import '@shru/design-system/styles'
43
+
44
+ // 2. Import component
45
+ import { ThemeToggle } from '@shru/design-system'
46
+
47
+ function App() {
48
+ return <ThemeToggle position="bottom-right" />
49
+ }
50
+ ```
51
+
52
+ **Note:** You must import the CSS file - it contains Tailwind setup and base CSS variables. The theme system will dynamically override variables at runtime.
53
+
54
+ See [USAGE.md](./USAGE.md) for complete usage guide.
55
+
56
+ ## Build Process
57
+
58
+ ```bash
59
+ # Build the library
60
+ npm run build:lib
61
+ # Generates: dist/index.js (ESM), dist/index.cjs (CJS), dist/index.d.ts (types)
62
+
63
+ # Run the showcase app
64
+ npm run dev
65
+ # Visit: http://localhost:3000/design-system
66
+ ```
67
+
68
+ ## Project Structure
69
+
70
+ ```
71
+ .
72
+ ├── apps/
73
+ │ └── design-system/ # Next.js showcase application
74
+ │ ├── app/ # Routes (minimal)
75
+ │ ├── src/design-system/ # Component library & themes
76
+ │ ├── config/ # App configuration
77
+ │ ├── hooks/ # App-level hooks
78
+ │ ├── lib/ # Shared utilities
79
+ │ └── public/tokens/ # Design tokens (symlinked to src/tokens)
80
+ ├── src/ # Reusable library code
81
+ │ ├── tokens/ # Design tokens (JSON files)
82
+ │ └── index.ts # Library entry point (re-exports from app's theme system)
83
+ ├── dist/ # Built library files (generated)
84
+ └── package.json # Root package config
85
+ ```
86
+
87
+ ## Documentation
88
+
89
+ ### Getting Started
90
+ - **[USAGE.md](./USAGE.md)** - Complete usage guide: setup, theme toggle, components, how it works
91
+ - **[CURSOR_PROMPT.md](./CURSOR_PROMPT.md)** - Ready-to-use Cursor prompt for integrating the library
92
+
93
+ ### Advanced Topics
94
+ - **[TOKEN_EXTENSION.md](./TOKEN_EXTENSION.md)** - Extending themes with custom token files
95
+ - **[COMPONENT_DEPENDENCIES.md](./COMPONENT_DEPENDENCIES.md)** - Complete dependencies reference
96
+
97
+ ### Contributing & Development
98
+ - **[CONTRIBUTING.md](./CONTRIBUTING.md)** - Contribution guidelines and development workflow
99
+ - **[apps/design-system/ARCHITECTURE.md](./apps/design-system/ARCHITECTURE.md)** - Architecture overview
100
+ - **[apps/design-system/src/design-system/components/README.md](./apps/design-system/src/design-system/components/README.md)** - Adding components
101
+ - **[apps/design-system/src/design-system/themes/README.md](./apps/design-system/src/design-system/themes/README.md)** - Theme system internals
102
+
103
+ ## Contributing
104
+
105
+ ### Getting Started
106
+
107
+ 1. **Clone and install:**
108
+ ```bash
109
+ git clone <repo-url>
110
+ npm install
111
+ ```
112
+
113
+ 2. **Run the showcase:**
114
+ ```bash
115
+ npm run dev
116
+ ```
117
+
118
+ 3. **Make changes:**
119
+ - **Adding a component**: See [Component System Docs](./apps/design-system/src/design-system/components/README.md#how-to-add-a-component)
120
+ - **Adding a theme**: See [Theme System Docs](./apps/design-system/src/design-system/themes/README.md#how-to-add-a-new-theme)
121
+ - **Library changes**: Edit `src/`, then run `npm run build:lib`
122
+
123
+ ### Development Workflow
124
+
125
+ 1. Make changes in appropriate module (`components/`, `themes/`, etc.)
126
+ 2. Test in the showcase app (`npm run dev`)
127
+ 3. If changing library code (`src/`), rebuild: `npm run build:lib`
128
+
129
+ ## License
130
+
131
+ MIT
@@ -0,0 +1,350 @@
1
+ @import "tailwindcss";
2
+ @import "tw-animate-css";
3
+ /* refer: https://tailwindcss.com/docs/theme */
4
+
5
+ @custom-variant dark (&:is(.dark *));
6
+
7
+ @custom-variant fixed (&:is(.layout-fixed *));
8
+
9
+ @theme inline {
10
+ --breakpoint-3xl: 1600px;
11
+ --breakpoint-4xl: 2000px;
12
+ --font-sans: var(--font-sans);
13
+ --font-mono: var(--font-mono);
14
+ --radius-sm: calc(var(--radius) - 4px);
15
+ --radius-md: calc(var(--radius) - 2px);
16
+ --radius-lg: var(--radius);
17
+ --radius-xl: calc(var(--radius) + 4px);
18
+ --color-background: var(--background);
19
+ --color-foreground: var(--foreground);
20
+ --color-card: var(--card);
21
+ --color-card-foreground: var(--card-foreground);
22
+ --color-popover: var(--popover);
23
+ --color-popover-foreground: var(--popover-foreground);
24
+ --color-primary: var(--primary);
25
+ --color-primary-foreground: var(--primary-foreground);
26
+ --color-secondary: var(--secondary);
27
+ --color-secondary-foreground: var(--secondary-foreground);
28
+ --color-muted: var(--muted);
29
+ --color-muted-foreground: var(--muted-foreground);
30
+ --color-accent: var(--accent);
31
+ --color-accent-foreground: var(--accent-foreground);
32
+ --color-destructive: var(--destructive);
33
+ --color-border: var(--border);
34
+ --color-input: var(--input);
35
+ --color-ring: var(--ring);
36
+ --color-chart-1: var(--chart-1);
37
+ --color-chart-2: var(--chart-2);
38
+ --color-chart-3: var(--chart-3);
39
+ --color-chart-4: var(--chart-4);
40
+ --color-chart-5: var(--chart-5);
41
+ --color-sidebar: var(--sidebar);
42
+ --color-sidebar-foreground: var(--sidebar-foreground);
43
+ --color-sidebar-primary: var(--sidebar-primary);
44
+ --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
45
+ --color-sidebar-accent: var(--sidebar-accent);
46
+ --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
47
+ --color-sidebar-border: var(--sidebar-border);
48
+ --color-sidebar-ring: var(--sidebar-ring);
49
+ --color-surface: var(--surface);
50
+ --color-surface-foreground: var(--surface-foreground);
51
+ --color-code: var(--code);
52
+ --color-code-foreground: var(--code-foreground);
53
+ --color-code-highlight: var(--code-highlight);
54
+ --color-code-number: var(--code-number);
55
+ --color-selection: var(--selection);
56
+ --color-selection-foreground: var(--selection-foreground);
57
+ --color-skeleton: var(--skeleton);
58
+ }
59
+
60
+ :root {
61
+ --radius: 0.625rem;
62
+ --background: oklch(1 0 0);
63
+ --foreground: oklch(0.145 0 0);
64
+ --card: oklch(1 0 0);
65
+ --card-foreground: oklch(0.145 0 0);
66
+ --popover: oklch(1 0 0);
67
+ --popover-foreground: oklch(0.145 0 0);
68
+ --primary: oklch(0.205 0 0);
69
+ --primary-foreground: oklch(0.985 0 0);
70
+ --secondary: oklch(0.97 0 0);
71
+ --secondary-foreground: oklch(0.205 0 0);
72
+ --muted: oklch(0.97 0 0);
73
+ --muted-foreground: oklch(0.556 0 0);
74
+ --accent: oklch(0.97 0 0);
75
+ --accent-foreground: oklch(0.205 0 0);
76
+ --destructive: oklch(0.577 0.245 27.325);
77
+ --border: oklch(0.922 0 0);
78
+ --input: oklch(0.922 0 0);
79
+ --ring: oklch(0.708 0 0);
80
+ --chart-1: var(--color-blue-300);
81
+ --chart-2: var(--color-blue-500);
82
+ --chart-3: var(--color-blue-600);
83
+ --chart-4: var(--color-blue-700);
84
+ --chart-5: var(--color-blue-800);
85
+ --sidebar: oklch(0.985 0 0);
86
+ --sidebar-foreground: oklch(0.145 0 0);
87
+ --sidebar-primary: oklch(0.205 0 0);
88
+ --sidebar-primary-foreground: oklch(0.985 0 0);
89
+ --sidebar-accent: oklch(0.97 0 0);
90
+ --sidebar-accent-foreground: oklch(0.205 0 0);
91
+ --sidebar-border: oklch(0.922 0 0);
92
+ --sidebar-ring: oklch(0.708 0 0);
93
+ --surface: oklch(0.98 0 0);
94
+ --surface-foreground: var(--foreground);
95
+ --code: var(--surface);
96
+ --code-foreground: var(--surface-foreground);
97
+ --code-highlight: oklch(0.96 0 0);
98
+ --code-number: oklch(0.56 0 0);
99
+ --selection: oklch(0.145 0 0);
100
+ --selection-foreground: oklch(1 0 0);
101
+ --skeleton: oklch(0.92 0 0);
102
+ }
103
+
104
+ .dark {
105
+ --background: oklch(0.145 0 0);
106
+ --foreground: oklch(0.985 0 0);
107
+ --card: oklch(0.205 0 0);
108
+ --card-foreground: oklch(0.985 0 0);
109
+ --popover: oklch(0.269 0 0);
110
+ --popover-foreground: oklch(0.985 0 0);
111
+ --primary: oklch(0.922 0 0);
112
+ --primary-foreground: oklch(0.205 0 0);
113
+ --secondary: oklch(0.269 0 0);
114
+ --secondary-foreground: oklch(0.985 0 0);
115
+ --muted: oklch(0.269 0 0);
116
+ --muted-foreground: oklch(0.708 0 0);
117
+ --accent: oklch(0.371 0 0);
118
+ --accent-foreground: oklch(0.985 0 0);
119
+ --destructive: oklch(0.704 0.191 22.216);
120
+ --border: oklch(1 0 0 / 10%);
121
+ --input: oklch(1 0 0 / 15%);
122
+ --ring: oklch(0.556 0 0);
123
+ --chart-1: var(--color-blue-300);
124
+ --chart-2: var(--color-blue-500);
125
+ --chart-3: var(--color-blue-600);
126
+ --chart-4: var(--color-blue-700);
127
+ --chart-5: var(--color-blue-800);
128
+ --sidebar: oklch(0.205 0 0);
129
+ --sidebar-foreground: oklch(0.985 0 0);
130
+ --sidebar-primary: oklch(0.488 0.243 264.376);
131
+ --sidebar-primary-foreground: oklch(0.985 0 0);
132
+ --sidebar-accent: oklch(0.269 0 0);
133
+ --sidebar-accent-foreground: oklch(0.985 0 0);
134
+ --sidebar-border: oklch(1 0 0 / 10%);
135
+ --sidebar-ring: oklch(0.439 0 0);
136
+ --surface: oklch(0.2 0 0);
137
+ --surface-foreground: oklch(0.708 0 0);
138
+ --code: var(--surface);
139
+ --code-foreground: var(--surface-foreground);
140
+ --code-highlight: oklch(0.27 0 0);
141
+ --code-number: oklch(0.72 0 0);
142
+ --selection: oklch(0.922 0 0);
143
+ --selection-foreground: oklch(0.205 0 0);
144
+ --skeleton: oklch(0.32 0 0);
145
+ }
146
+
147
+ @layer base {
148
+ * {
149
+ @apply border-border outline-ring/50;
150
+ }
151
+ ::selection {
152
+ @apply bg-selection text-selection-foreground;
153
+ }
154
+ html {
155
+ @apply overscroll-none scroll-smooth;
156
+ }
157
+ body {
158
+ @apply bg-background text-foreground;
159
+ font-synthesis-weight: none;
160
+ text-rendering: optimizeLegibility;
161
+ }
162
+
163
+ [data-slot="layout"] {
164
+ @apply 3xl:p-2 3xl:fixed:p-0 overscroll-none;
165
+ }
166
+
167
+ @supports (font: -apple-system-body) and (-webkit-appearance: none) {
168
+ [data-wrapper] {
169
+ @apply min-[1800px]:border-t;
170
+ }
171
+ }
172
+
173
+ a:active,
174
+ button:active {
175
+ @apply opacity-60 md:opacity-100;
176
+ }
177
+ }
178
+
179
+ @utility border-grid {
180
+ @apply border-border/50 dark:border-border;
181
+ }
182
+
183
+ @utility section-soft {
184
+ @apply from-background to-surface/40 dark:bg-background 3xl:fixed:bg-none bg-gradient-to-b;
185
+ }
186
+
187
+ @utility theme-container {
188
+ @apply font-sans;
189
+ }
190
+
191
+ @utility container-wrapper {
192
+ @apply 3xl:fixed:max-w-[calc(var(--breakpoint-2xl)+2rem)] mx-auto w-full px-2;
193
+ }
194
+
195
+ @utility container {
196
+ @apply 3xl:max-w-screen-2xl mx-auto max-w-[1400px] px-4 lg:px-8;
197
+ }
198
+
199
+ @utility no-scrollbar {
200
+ -ms-overflow-style: none;
201
+ scrollbar-width: none;
202
+
203
+ &::-webkit-scrollbar {
204
+ display: none;
205
+ }
206
+ }
207
+
208
+ @utility border-ghost {
209
+ @apply after:border-border relative after:absolute after:inset-0 after:border after:mix-blend-darken dark:after:mix-blend-lighten;
210
+ }
211
+
212
+ @utility step {
213
+ counter-increment: step;
214
+ @apply relative;
215
+
216
+ &:before {
217
+ @apply text-muted-foreground right-0 mr-2 hidden size-7 items-center justify-center rounded-full text-center -indent-px font-mono text-sm font-medium md:absolute;
218
+ content: counter(step);
219
+ }
220
+ }
221
+
222
+ @utility extend-touch-target {
223
+ @media (pointer: coarse) {
224
+ @apply relative touch-manipulation after:absolute after:-inset-2;
225
+ }
226
+ }
227
+
228
+ @layer components {
229
+ .steps {
230
+ &:first-child {
231
+ @apply !mt-0;
232
+ }
233
+
234
+ &:first-child > h3:first-child {
235
+ @apply !mt-0;
236
+ }
237
+
238
+ > h3 {
239
+ @apply !mt-16;
240
+ }
241
+
242
+ > h3 + p {
243
+ @apply !mt-2;
244
+ }
245
+ }
246
+
247
+ [data-rehype-pretty-code-figure] {
248
+ background-color: var(--color-code);
249
+ color: var(--color-code-foreground);
250
+ border-radius: var(--radius-lg);
251
+ border-width: 0px;
252
+ border-color: var(--border);
253
+ margin-top: calc(var(--spacing) * 6);
254
+ overflow: hidden;
255
+ font-size: var(--text-sm);
256
+ outline: none;
257
+ position: relative;
258
+ @apply -mx-1 md:-mx-1;
259
+
260
+ &:has([data-rehype-pretty-code-title]) [data-slot="copy-button"] {
261
+ top: calc(var(--spacing) * 1.5) !important;
262
+ }
263
+ }
264
+
265
+ [data-rehype-pretty-code-title] {
266
+ border-bottom: color-mix(in oklab, var(--border) 30%, transparent);
267
+ border-bottom-width: 1px;
268
+ border-bottom-style: solid;
269
+ padding-block: calc(var(--spacing) * 2.5);
270
+ padding-inline: calc(var(--spacing) * 4);
271
+ font-size: var(--text-sm);
272
+ font-family: var(--font-mono);
273
+ color: var(--color-code-foreground);
274
+ }
275
+
276
+ [data-line-numbers] {
277
+ display: grid;
278
+ min-width: 100%;
279
+ white-space: pre;
280
+ border: 0;
281
+ background: transparent;
282
+ padding: 0;
283
+ counter-reset: line;
284
+ box-decoration-break: clone;
285
+ }
286
+
287
+ [data-line-numbers] [data-line]::before {
288
+ font-size: var(--text-sm);
289
+ counter-increment: line;
290
+ content: counter(line);
291
+ display: inline-block;
292
+ width: calc(var(--spacing) * 16);
293
+ padding-right: calc(var(--spacing) * 6);
294
+ text-align: right;
295
+ color: var(--color-code-number);
296
+ background-color: var(--color-code);
297
+ position: sticky;
298
+ left: 0;
299
+ }
300
+
301
+ [data-line-numbers] [data-highlighted-line][data-line]::before {
302
+ background-color: var(--color-code-highlight);
303
+ }
304
+
305
+ [data-line] {
306
+ padding-top: calc(var(--spacing) * 0.5);
307
+ padding-bottom: calc(var(--spacing) * 0.5);
308
+ min-height: calc(var(--spacing) * 1);
309
+ width: 100%;
310
+ display: inline-block;
311
+ }
312
+
313
+ [data-line] span {
314
+ color: var(--shiki-light);
315
+
316
+ @variant dark {
317
+ color: var(--shiki-dark) !important;
318
+ }
319
+ }
320
+
321
+ [data-highlighted-line],
322
+ [data-highlighted-chars] {
323
+ position: relative;
324
+ background-color: var(--color-code-highlight);
325
+ }
326
+
327
+ [data-highlighted-line] {
328
+ &:after {
329
+ position: absolute;
330
+ top: 0;
331
+ left: 0;
332
+ width: 2px;
333
+ height: 100%;
334
+ content: "";
335
+ background-color: color-mix(
336
+ in oklab,
337
+ var(--muted-foreground) 50%,
338
+ transparent
339
+ );
340
+ }
341
+ }
342
+
343
+ [data-highlighted-chars] {
344
+ border-radius: var(--radius-sm);
345
+ padding-inline: 0.3rem;
346
+ padding-block: 0.1rem;
347
+ font-family: var(--font-mono);
348
+ font-size: 0.8rem;
349
+ }
350
+ }