shru-design-system 0.1.0 → 0.1.2

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
@@ -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/dist/index.d.mts CHANGED
@@ -4,6 +4,7 @@ import { VariantProps } from 'class-variance-authority';
4
4
  import * as react_jsx_runtime from 'react/jsx-runtime';
5
5
  import * as DialogPrimitive from '@radix-ui/react-dialog';
6
6
  import * as SelectPrimitive from '@radix-ui/react-select';
7
+ import * as TooltipPrimitive from '@radix-ui/react-tooltip';
7
8
 
8
9
  declare const buttonVariants: (props?: ({
9
10
  readonly variant?: "default" | "destructive" | "outline" | "secondary" | "ghost" | "link" | null | undefined;
@@ -52,4 +53,103 @@ declare function SelectSeparator({ className, ...props }: React.ComponentProps<t
52
53
  declare function SelectScrollUpButton({ className, ...props }: React.ComponentProps<typeof SelectPrimitive.ScrollUpButton>): react_jsx_runtime.JSX.Element;
53
54
  declare function SelectScrollDownButton({ className, ...props }: React.ComponentProps<typeof SelectPrimitive.ScrollDownButton>): react_jsx_runtime.JSX.Element;
54
55
 
55
- export { Badge, Button, Modal, ModalClose, ModalContent, ModalDescription, ModalFooter, ModalHeader, ModalOverlay, ModalPortal, ModalTitle, ModalTrigger, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, badgeVariants, buttonVariants };
56
+ declare function TooltipProvider({ delayDuration, ...props }: React.ComponentProps<typeof TooltipPrimitive.Provider>): react_jsx_runtime.JSX.Element;
57
+ declare function Tooltip({ ...props }: React.ComponentProps<typeof TooltipPrimitive.Root>): react_jsx_runtime.JSX.Element;
58
+ declare function TooltipTrigger({ ...props }: React.ComponentProps<typeof TooltipPrimitive.Trigger>): react_jsx_runtime.JSX.Element;
59
+ declare const tooltipSides: readonly ["top", "right", "bottom", "left"];
60
+ declare function TooltipContent({ className, sideOffset, children, side, ...props }: React.ComponentProps<typeof TooltipPrimitive.Content> & {
61
+ side?: typeof tooltipSides[number];
62
+ }): react_jsx_runtime.JSX.Element;
63
+
64
+ interface ThemeToggleProps {
65
+ className?: string;
66
+ position?: "bottom-right" | "bottom-left" | "top-right" | "top-left";
67
+ }
68
+ declare function ThemeToggle({ className, position }: ThemeToggleProps): react_jsx_runtime.JSX.Element;
69
+
70
+ type ThemeSelection = {
71
+ color?: string;
72
+ typography?: string;
73
+ shape?: string;
74
+ density?: string;
75
+ animation?: string;
76
+ custom?: string;
77
+ };
78
+ type ThemeMetadata$1 = {
79
+ name: string;
80
+ file: string;
81
+ icon: string;
82
+ description: string;
83
+ };
84
+ /**
85
+ * Hook for managing design system theme switching
86
+ */
87
+ declare function useTheme(): {
88
+ selectedThemes: ThemeSelection;
89
+ updateTheme: (category: keyof ThemeSelection, themeId: string | undefined) => Promise<void>;
90
+ resetToDefaults: () => Promise<void>;
91
+ isLoading: boolean;
92
+ error: string | null;
93
+ getAvailableThemes: (category: string) => Promise<Record<string, ThemeMetadata$1>>;
94
+ };
95
+
96
+ declare function useThemeToggle(): {
97
+ selectedThemes: ThemeSelection;
98
+ isLoading: boolean;
99
+ getAvailableThemes: (category: string) => Promise<Record<string, ThemeMetadata$1>>;
100
+ isOpen: boolean;
101
+ selectedCategory: string | null;
102
+ themeCategories: any;
103
+ categories: [string, {
104
+ name: string;
105
+ themes: Record<string, any>;
106
+ order?: number;
107
+ }][];
108
+ menuRef: React.RefObject<HTMLDivElement>;
109
+ handleCategoryClick: (categoryKey: string) => void;
110
+ handleThemeSelect: (category: keyof ThemeSelection, themeId: string) => Promise<void>;
111
+ handleBack: () => void;
112
+ toggleMenu: () => void;
113
+ };
114
+
115
+ /**
116
+ * Theme Configuration
117
+ * Registry of all available themes organized by category
118
+ *
119
+ * Base themes are defined here. Additional themes can be discovered dynamically
120
+ * by scanning the /tokens/themes/ directory structure.
121
+ */
122
+ type ThemeMetadata = {
123
+ name: string;
124
+ file: string;
125
+ icon: string;
126
+ description: string;
127
+ };
128
+ type ThemeCategory = {
129
+ name: string;
130
+ order: number;
131
+ themes: Record<string, ThemeMetadata>;
132
+ };
133
+ /**
134
+ * Register a custom theme dynamically
135
+ * Allows users to add themes without modifying the base config
136
+ */
137
+ declare function registerTheme(category: string, themeId: string, metadata: ThemeMetadata): Record<string, ThemeCategory>;
138
+ /**
139
+ * Get merged theme categories (base + discovered)
140
+ */
141
+ declare function getThemeCategories(): Promise<Record<string, ThemeCategory>>;
142
+ /**
143
+ * Get theme file path
144
+ */
145
+ declare function getThemeFilePath(category: string, themeId: string): string | null;
146
+ /**
147
+ * Get all themes for a category
148
+ */
149
+ declare function getThemesForCategory(category: string): Promise<Record<string, ThemeMetadata>>;
150
+ /**
151
+ * Get theme by ID
152
+ */
153
+ declare function getTheme(category: string, themeId: string): Promise<ThemeMetadata | null>;
154
+
155
+ export { Badge, Button, Modal, ModalClose, ModalContent, ModalDescription, ModalFooter, ModalHeader, ModalOverlay, ModalPortal, ModalTitle, ModalTrigger, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, type ThemeMetadata$1 as ThemeMetadata, type ThemeSelection, ThemeToggle, type ThemeToggleProps, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, badgeVariants, buttonVariants, getTheme, getThemeCategories, getThemeFilePath, getThemesForCategory, registerTheme, useTheme, useThemeToggle };
package/dist/index.d.ts CHANGED
@@ -4,6 +4,7 @@ import { VariantProps } from 'class-variance-authority';
4
4
  import * as react_jsx_runtime from 'react/jsx-runtime';
5
5
  import * as DialogPrimitive from '@radix-ui/react-dialog';
6
6
  import * as SelectPrimitive from '@radix-ui/react-select';
7
+ import * as TooltipPrimitive from '@radix-ui/react-tooltip';
7
8
 
8
9
  declare const buttonVariants: (props?: ({
9
10
  readonly variant?: "default" | "destructive" | "outline" | "secondary" | "ghost" | "link" | null | undefined;
@@ -52,4 +53,103 @@ declare function SelectSeparator({ className, ...props }: React.ComponentProps<t
52
53
  declare function SelectScrollUpButton({ className, ...props }: React.ComponentProps<typeof SelectPrimitive.ScrollUpButton>): react_jsx_runtime.JSX.Element;
53
54
  declare function SelectScrollDownButton({ className, ...props }: React.ComponentProps<typeof SelectPrimitive.ScrollDownButton>): react_jsx_runtime.JSX.Element;
54
55
 
55
- export { Badge, Button, Modal, ModalClose, ModalContent, ModalDescription, ModalFooter, ModalHeader, ModalOverlay, ModalPortal, ModalTitle, ModalTrigger, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, badgeVariants, buttonVariants };
56
+ declare function TooltipProvider({ delayDuration, ...props }: React.ComponentProps<typeof TooltipPrimitive.Provider>): react_jsx_runtime.JSX.Element;
57
+ declare function Tooltip({ ...props }: React.ComponentProps<typeof TooltipPrimitive.Root>): react_jsx_runtime.JSX.Element;
58
+ declare function TooltipTrigger({ ...props }: React.ComponentProps<typeof TooltipPrimitive.Trigger>): react_jsx_runtime.JSX.Element;
59
+ declare const tooltipSides: readonly ["top", "right", "bottom", "left"];
60
+ declare function TooltipContent({ className, sideOffset, children, side, ...props }: React.ComponentProps<typeof TooltipPrimitive.Content> & {
61
+ side?: typeof tooltipSides[number];
62
+ }): react_jsx_runtime.JSX.Element;
63
+
64
+ interface ThemeToggleProps {
65
+ className?: string;
66
+ position?: "bottom-right" | "bottom-left" | "top-right" | "top-left";
67
+ }
68
+ declare function ThemeToggle({ className, position }: ThemeToggleProps): react_jsx_runtime.JSX.Element;
69
+
70
+ type ThemeSelection = {
71
+ color?: string;
72
+ typography?: string;
73
+ shape?: string;
74
+ density?: string;
75
+ animation?: string;
76
+ custom?: string;
77
+ };
78
+ type ThemeMetadata$1 = {
79
+ name: string;
80
+ file: string;
81
+ icon: string;
82
+ description: string;
83
+ };
84
+ /**
85
+ * Hook for managing design system theme switching
86
+ */
87
+ declare function useTheme(): {
88
+ selectedThemes: ThemeSelection;
89
+ updateTheme: (category: keyof ThemeSelection, themeId: string | undefined) => Promise<void>;
90
+ resetToDefaults: () => Promise<void>;
91
+ isLoading: boolean;
92
+ error: string | null;
93
+ getAvailableThemes: (category: string) => Promise<Record<string, ThemeMetadata$1>>;
94
+ };
95
+
96
+ declare function useThemeToggle(): {
97
+ selectedThemes: ThemeSelection;
98
+ isLoading: boolean;
99
+ getAvailableThemes: (category: string) => Promise<Record<string, ThemeMetadata$1>>;
100
+ isOpen: boolean;
101
+ selectedCategory: string | null;
102
+ themeCategories: any;
103
+ categories: [string, {
104
+ name: string;
105
+ themes: Record<string, any>;
106
+ order?: number;
107
+ }][];
108
+ menuRef: React.RefObject<HTMLDivElement>;
109
+ handleCategoryClick: (categoryKey: string) => void;
110
+ handleThemeSelect: (category: keyof ThemeSelection, themeId: string) => Promise<void>;
111
+ handleBack: () => void;
112
+ toggleMenu: () => void;
113
+ };
114
+
115
+ /**
116
+ * Theme Configuration
117
+ * Registry of all available themes organized by category
118
+ *
119
+ * Base themes are defined here. Additional themes can be discovered dynamically
120
+ * by scanning the /tokens/themes/ directory structure.
121
+ */
122
+ type ThemeMetadata = {
123
+ name: string;
124
+ file: string;
125
+ icon: string;
126
+ description: string;
127
+ };
128
+ type ThemeCategory = {
129
+ name: string;
130
+ order: number;
131
+ themes: Record<string, ThemeMetadata>;
132
+ };
133
+ /**
134
+ * Register a custom theme dynamically
135
+ * Allows users to add themes without modifying the base config
136
+ */
137
+ declare function registerTheme(category: string, themeId: string, metadata: ThemeMetadata): Record<string, ThemeCategory>;
138
+ /**
139
+ * Get merged theme categories (base + discovered)
140
+ */
141
+ declare function getThemeCategories(): Promise<Record<string, ThemeCategory>>;
142
+ /**
143
+ * Get theme file path
144
+ */
145
+ declare function getThemeFilePath(category: string, themeId: string): string | null;
146
+ /**
147
+ * Get all themes for a category
148
+ */
149
+ declare function getThemesForCategory(category: string): Promise<Record<string, ThemeMetadata>>;
150
+ /**
151
+ * Get theme by ID
152
+ */
153
+ declare function getTheme(category: string, themeId: string): Promise<ThemeMetadata | null>;
154
+
155
+ export { Badge, Button, Modal, ModalClose, ModalContent, ModalDescription, ModalFooter, ModalHeader, ModalOverlay, ModalPortal, ModalTitle, ModalTrigger, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, type ThemeMetadata$1 as ThemeMetadata, type ThemeSelection, ThemeToggle, type ThemeToggleProps, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, badgeVariants, buttonVariants, getTheme, getThemeCategories, getThemeFilePath, getThemesForCategory, registerTheme, useTheme, useThemeToggle };