atomsystem 0.4.3 → 0.5.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.
@@ -0,0 +1,220 @@
1
+ import React, { ElementType } from 'react';
2
+
3
+ export interface LayoutProps extends React.HTMLAttributes<HTMLDivElement> {
4
+ as?: ElementType;
5
+ children?: React.ReactNode;
6
+ }
7
+
8
+ export interface LayoutHeaderProps extends React.HTMLAttributes<HTMLElement> {
9
+ sticky?: boolean;
10
+ }
11
+
12
+ export interface LayoutSidebarProps extends React.HTMLAttributes<HTMLElement> {
13
+ width?: 'sm' | 'md' | 'lg';
14
+ }
15
+
16
+ export interface LayoutContentProps extends React.HTMLAttributes<HTMLElement> {}
17
+
18
+ export interface LayoutFooterProps extends React.HTMLAttributes<HTMLElement> {}
19
+
20
+ export interface StackProps extends React.HTMLAttributes<HTMLDivElement> {
21
+ direction?: 'vertical' | 'horizontal';
22
+ gap?: '1' | '2' | '3' | '4' | '6' | '8' | '12';
23
+ align?: 'start' | 'center' | 'end' | 'stretch';
24
+ justify?: 'start' | 'center' | 'end' | 'between' | 'around';
25
+ wrap?: boolean;
26
+ }
27
+
28
+ export interface GridProps extends React.HTMLAttributes<HTMLDivElement> {
29
+ cols?: 1 | 2 | 3 | 4 | 6 | 12;
30
+ gap?: '1' | '2' | '3' | '4' | '6' | '8';
31
+ }
32
+
33
+ export interface SectionProps extends React.HTMLAttributes<HTMLElement> {
34
+ spacing?: 'sm' | 'md' | 'lg' | 'none';
35
+ }
36
+
37
+ const SIDEBAR_WIDTH_MAP = {
38
+ sm: 'w-48 lg:w-56',
39
+ md: 'w-60 lg:w-64',
40
+ lg: 'w-72 lg:w-80',
41
+ };
42
+
43
+ const STACK_GAP_MAP: Record<string, string> = {
44
+ '1': 'gap-[var(--atom-space-1,4px)]',
45
+ '2': 'gap-[var(--atom-space-2,8px)]',
46
+ '3': 'gap-[var(--atom-space-3,12px)]',
47
+ '4': 'gap-[var(--atom-space-4,16px)]',
48
+ '6': 'gap-[var(--atom-space-6,24px)]',
49
+ '8': 'gap-[var(--atom-space-8,32px)]',
50
+ '12': 'gap-[var(--atom-space-12,48px)]',
51
+ };
52
+
53
+ const STACK_ALIGN_MAP = {
54
+ start: 'items-start',
55
+ center: 'items-center',
56
+ end: 'items-end',
57
+ stretch: 'items-stretch',
58
+ };
59
+
60
+ const STACK_JUSTIFY_MAP = {
61
+ start: 'justify-start',
62
+ center: 'justify-center',
63
+ end: 'justify-end',
64
+ between: 'justify-between',
65
+ around: 'justify-around',
66
+ };
67
+
68
+ const GRID_COLS_MAP = {
69
+ 1: 'grid-cols-1',
70
+ 2: 'grid-cols-1 sm:grid-cols-2',
71
+ 3: 'grid-cols-1 sm:grid-cols-2 lg:grid-cols-3',
72
+ 4: 'grid-cols-1 sm:grid-cols-2 lg:grid-cols-4',
73
+ 6: 'grid-cols-2 sm:grid-cols-3 lg:grid-cols-6',
74
+ 12: 'grid-cols-12',
75
+ };
76
+
77
+ const SECTION_SPACING_MAP = {
78
+ none: '',
79
+ sm: 'py-[var(--atom-space-4,16px)] sm:py-[var(--atom-space-6,24px)]',
80
+ md: 'py-[var(--atom-space-8,32px)] sm:py-[var(--atom-space-12,48px)]',
81
+ lg: 'py-[var(--atom-space-12,48px)] sm:py-[var(--atom-space-16,64px)]',
82
+ };
83
+
84
+ const LayoutHeader: React.FC<LayoutHeaderProps> = ({
85
+ sticky = true,
86
+ className = '',
87
+ children,
88
+ ...props
89
+ }) => (
90
+ <header
91
+ className={`${
92
+ sticky ? 'sticky top-0 z-40 backdrop-blur-md bg-(--bg-primary)/90' : ''
93
+ } border-b border-(--border-subtle) transition-colors ${className}`.trim()}
94
+ {...props}
95
+ >
96
+ {children}
97
+ </header>
98
+ );
99
+
100
+ const LayoutSidebar: React.FC<LayoutSidebarProps> = ({
101
+ width = 'md',
102
+ className = '',
103
+ children,
104
+ ...props
105
+ }) => (
106
+ <aside
107
+ className={`shrink-0 border-r border-(--border-subtle) bg-(--bg-primary) transition-colors ${SIDEBAR_WIDTH_MAP[width]} ${className}`.trim()}
108
+ {...props}
109
+ >
110
+ {children}
111
+ </aside>
112
+ );
113
+
114
+ const LayoutContent: React.FC<LayoutContentProps> = ({
115
+ className = '',
116
+ children,
117
+ ...props
118
+ }) => (
119
+ <main className={`flex-1 w-full transition-colors ${className}`.trim()} {...props}>
120
+ {children}
121
+ </main>
122
+ );
123
+
124
+ const LayoutFooter: React.FC<LayoutFooterProps> = ({
125
+ className = '',
126
+ children,
127
+ ...props
128
+ }) => (
129
+ <footer
130
+ className={`border-t border-(--border-subtle) bg-(--bg-primary) transition-colors ${className}`.trim()}
131
+ {...props}
132
+ >
133
+ {children}
134
+ </footer>
135
+ );
136
+
137
+ export const Stack: React.FC<StackProps> = ({
138
+ direction = 'vertical',
139
+ gap = '4',
140
+ align = 'stretch',
141
+ justify = 'start',
142
+ wrap = false,
143
+ className = '',
144
+ children,
145
+ ...props
146
+ }) => {
147
+ const dirClass = direction === 'horizontal' ? 'flex flex-row' : 'flex flex-col';
148
+ const gapClass = STACK_GAP_MAP[gap] || STACK_GAP_MAP['4'];
149
+ const alignClass = STACK_ALIGN_MAP[align] || '';
150
+ const justifyClass = STACK_JUSTIFY_MAP[justify] || '';
151
+ const wrapClass = wrap ? 'flex-wrap' : 'flex-nowrap';
152
+
153
+ return (
154
+ <div
155
+ className={`${dirClass} ${gapClass} ${alignClass} ${justifyClass} ${wrapClass} ${className}`.trim()}
156
+ {...props}
157
+ >
158
+ {children}
159
+ </div>
160
+ );
161
+ };
162
+
163
+ export const Grid: React.FC<GridProps> = ({
164
+ cols = 3,
165
+ gap = '4',
166
+ className = '',
167
+ children,
168
+ ...props
169
+ }) => {
170
+ const colsClass = GRID_COLS_MAP[cols] || GRID_COLS_MAP[3];
171
+ const gapClass = STACK_GAP_MAP[gap] || STACK_GAP_MAP['4'];
172
+ return (
173
+ <div className={`grid ${colsClass} ${gapClass} ${className}`.trim()} {...props}>
174
+ {children}
175
+ </div>
176
+ );
177
+ };
178
+
179
+ export const Section: React.FC<SectionProps> = ({
180
+ spacing = 'md',
181
+ className = '',
182
+ children,
183
+ ...props
184
+ }) => {
185
+ const spacingClass = SECTION_SPACING_MAP[spacing];
186
+ return (
187
+ <section className={`w-full ${spacingClass} ${className}`.trim()} {...props}>
188
+ {children}
189
+ </section>
190
+ );
191
+ };
192
+
193
+ export const Layout: React.FC<LayoutProps> & {
194
+ Header: React.FC<LayoutHeaderProps>;
195
+ Sidebar: React.FC<LayoutSidebarProps>;
196
+ Content: React.FC<LayoutContentProps>;
197
+ Footer: React.FC<LayoutFooterProps>;
198
+ Stack: React.FC<StackProps>;
199
+ Grid: React.FC<GridProps>;
200
+ Section: React.FC<SectionProps>;
201
+ } = ({ as: Component = 'div', className = '', children, ...props }) => {
202
+ return (
203
+ <Component
204
+ className={`min-h-screen bg-(--bg-primary) text-(--text-primary) flex flex-col font-sans transition-colors ${className}`.trim()}
205
+ {...props}
206
+ >
207
+ {children}
208
+ </Component>
209
+ );
210
+ };
211
+
212
+ Layout.Header = LayoutHeader;
213
+ Layout.Sidebar = LayoutSidebar;
214
+ Layout.Content = LayoutContent;
215
+ Layout.Footer = LayoutFooter;
216
+ Layout.Stack = Stack;
217
+ Layout.Grid = Grid;
218
+ Layout.Section = Section;
219
+
220
+ Layout.displayName = 'Layout';
@@ -0,0 +1,39 @@
1
+ 'use client';
2
+
3
+ import React from 'react';
4
+
5
+ export interface SwitchProps {
6
+ checked: boolean;
7
+ onCheckedChange?: (checked: boolean) => void;
8
+ disabled?: boolean;
9
+ className?: string;
10
+ id?: string;
11
+ }
12
+
13
+ export const Switch: React.FC<SwitchProps> = ({
14
+ checked,
15
+ onCheckedChange,
16
+ disabled = false,
17
+ className = '',
18
+ id,
19
+ }) => {
20
+ return (
21
+ <button
22
+ id={id}
23
+ type="button"
24
+ role="switch"
25
+ aria-checked={checked}
26
+ disabled={disabled}
27
+ onClick={() => onCheckedChange?.(!checked)}
28
+ className={`relative inline-flex h-5 w-9 shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none disabled:opacity-40 disabled:cursor-not-allowed ${
29
+ checked ? 'bg-(--accent-primary)' : 'bg-(--bg-secondary) border-(--border-subtle)'
30
+ } ${className}`}
31
+ >
32
+ <span
33
+ className={`pointer-events-none inline-block h-4 w-4 transform rounded-full bg-white shadow-xs ring-0 transition duration-200 ease-in-out ${
34
+ checked ? 'translate-x-4' : 'translate-x-0'
35
+ }`}
36
+ />
37
+ </button>
38
+ );
39
+ };
@@ -0,0 +1,88 @@
1
+ import React from 'react';
2
+
3
+ export interface TableProps extends React.TableHTMLAttributes<HTMLTableElement> {}
4
+
5
+ export const Table = React.forwardRef<HTMLTableElement, TableProps>(
6
+ ({ className = '', children, ...props }, ref) => (
7
+ <div className="w-full overflow-auto rounded-(--radius) border border-(--border-subtle)">
8
+ <table
9
+ ref={ref}
10
+ className={`w-full caption-bottom text-xs text-left ${className}`}
11
+ {...props}
12
+ >
13
+ {children}
14
+ </table>
15
+ </div>
16
+ )
17
+ );
18
+ Table.displayName = 'Table';
19
+
20
+ export const TableHeader = React.forwardRef<
21
+ HTMLTableSectionElement,
22
+ React.HTMLAttributes<HTMLTableSectionElement>
23
+ >(({ className = '', children, ...props }, ref) => (
24
+ <thead
25
+ ref={ref}
26
+ className={`bg-(--bg-secondary)/60 border-b border-(--border-subtle) font-semibold text-(--text-secondary) ${className}`}
27
+ {...props}
28
+ >
29
+ {children}
30
+ </thead>
31
+ ));
32
+ TableHeader.displayName = 'TableHeader';
33
+
34
+ export const TableBody = React.forwardRef<
35
+ HTMLTableSectionElement,
36
+ React.HTMLAttributes<HTMLTableSectionElement>
37
+ >(({ className = '', children, ...props }, ref) => (
38
+ <tbody
39
+ ref={ref}
40
+ className={`divide-y divide-(--border-subtle) bg-(--bg-primary) ${className}`}
41
+ {...props}
42
+ >
43
+ {children}
44
+ </tbody>
45
+ ));
46
+ TableBody.displayName = 'TableBody';
47
+
48
+ export const TableRow = React.forwardRef<
49
+ HTMLTableRowElement,
50
+ React.HTMLAttributes<HTMLTableRowElement>
51
+ >(({ className = '', children, ...props }, ref) => (
52
+ <tr
53
+ ref={ref}
54
+ className={`hover:bg-(--bg-secondary)/40 transition-colors ${className}`}
55
+ {...props}
56
+ >
57
+ {children}
58
+ </tr>
59
+ ));
60
+ TableRow.displayName = 'TableRow';
61
+
62
+ export const TableHead = React.forwardRef<
63
+ HTMLTableCellElement,
64
+ React.ThHTMLAttributes<HTMLTableCellElement>
65
+ >(({ className = '', children, ...props }, ref) => (
66
+ <th
67
+ ref={ref}
68
+ className={`p-3 text-left font-medium text-(--text-secondary) ${className}`}
69
+ {...props}
70
+ >
71
+ {children}
72
+ </th>
73
+ ));
74
+ TableHead.displayName = 'TableHead';
75
+
76
+ export const TableCell = React.forwardRef<
77
+ HTMLTableCellElement,
78
+ React.TdHTMLAttributes<HTMLTableCellElement>
79
+ >(({ className = '', children, ...props }, ref) => (
80
+ <td
81
+ ref={ref}
82
+ className={`p-3 text-(--text-primary) align-middle ${className}`}
83
+ {...props}
84
+ >
85
+ {children}
86
+ </td>
87
+ ));
88
+ TableCell.displayName = 'TableCell';
@@ -0,0 +1,58 @@
1
+ 'use client';
2
+
3
+ import React from 'react';
4
+
5
+ export interface TabsListProps extends React.HTMLAttributes<HTMLDivElement> {}
6
+ export interface TabsTriggerProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
7
+ active?: boolean;
8
+ }
9
+ export interface TabsContentProps extends React.HTMLAttributes<HTMLDivElement> {
10
+ active?: boolean;
11
+ }
12
+
13
+ export const TabsList = React.forwardRef<HTMLDivElement, TabsListProps>(
14
+ ({ className = '', children, ...props }, ref) => (
15
+ <div
16
+ ref={ref}
17
+ className={`inline-flex items-center p-1 rounded-(--radius) bg-(--bg-secondary) text-xs border border-(--border-subtle) ${className}`}
18
+ {...props}
19
+ >
20
+ {children}
21
+ </div>
22
+ )
23
+ );
24
+ TabsList.displayName = 'TabsList';
25
+
26
+ export const TabsTrigger = React.forwardRef<HTMLButtonElement, TabsTriggerProps>(
27
+ ({ active = false, className = '', children, ...props }, ref) => (
28
+ <button
29
+ ref={ref}
30
+ type="button"
31
+ className={`px-3 py-1.5 rounded-(--radius-sm) font-medium text-xs transition-colors ${
32
+ active
33
+ ? 'bg-(--bg-primary) text-(--text-primary) shadow-xs font-semibold'
34
+ : 'text-(--text-secondary) hover:text-(--text-primary)'
35
+ } ${className}`}
36
+ {...props}
37
+ >
38
+ {children}
39
+ </button>
40
+ )
41
+ );
42
+ TabsTrigger.displayName = 'TabsTrigger';
43
+
44
+ export const TabsContent = React.forwardRef<HTMLDivElement, TabsContentProps>(
45
+ ({ active = false, className = '', children, ...props }, ref) => {
46
+ if (!active) return null;
47
+ return (
48
+ <div
49
+ ref={ref}
50
+ className={`p-4 rounded-(--radius) bg-(--bg-primary) border border-(--border-subtle) text-xs ${className}`}
51
+ {...props}
52
+ >
53
+ {children}
54
+ </div>
55
+ );
56
+ }
57
+ );
58
+ TabsContent.displayName = 'TabsContent';
@@ -17,3 +17,8 @@ export * from './Breadcrumb';
17
17
  export * from './Separator';
18
18
  export * from './Textarea';
19
19
  export * from './Tree';
20
+ export * from './Table';
21
+ export * from './Tabs';
22
+ export * from './Switch';
23
+ export * from './Container';
24
+ export * from './Layout';