doom-design-system 0.1.7 → 0.1.8
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 +23 -20
- package/dist/DesignSystemProvider.d.ts +1 -0
- package/dist/DesignSystemProvider.js +3 -4
- package/dist/components/Accordion/Accordion.js +5 -63
- package/dist/components/Accordion/Accordion.module.css +69 -0
- package/dist/components/ActionRow/ActionRow.js +3 -28
- package/dist/components/ActionRow/ActionRow.module.css +24 -0
- package/dist/components/Alert/Alert.js +3 -58
- package/dist/components/Alert/Alert.module.css +77 -0
- package/dist/components/Avatar/Avatar.js +3 -45
- package/dist/components/Avatar/Avatar.module.css +67 -0
- package/dist/components/Badge/Badge.d.ts +1 -1
- package/dist/components/Badge/Badge.js +4 -42
- package/dist/components/Badge/Badge.module.css +31 -0
- package/dist/components/Breadcrumbs/Breadcrumbs.js +6 -38
- package/dist/components/Breadcrumbs/Breadcrumbs.module.css +34 -0
- package/dist/components/Button/Button.d.ts +1 -1
- package/dist/components/Button/Button.js +5 -129
- package/dist/components/Button/Button.module.css +112 -0
- package/dist/components/Card/Card.d.ts +1 -1
- package/dist/components/Card/Card.js +4 -13
- package/dist/components/Card/Card.module.css +8 -0
- package/dist/components/Drawer/Drawer.js +5 -71
- package/dist/components/Drawer/Drawer.module.css +75 -0
- package/dist/components/Dropdown/Dropdown.d.ts +2 -1
- package/dist/components/Dropdown/Dropdown.js +6 -39
- package/dist/components/Dropdown/Dropdown.module.css +33 -0
- package/dist/components/Form/Form.d.ts +4 -9
- package/dist/components/Form/Form.js +9 -43
- package/dist/components/Form/Form.module.css +41 -0
- package/dist/components/Input/Input.js +3 -59
- package/dist/components/Input/Input.module.css +86 -0
- package/dist/components/Label/Label.d.ts +1 -1
- package/dist/components/Label/Label.js +4 -23
- package/dist/components/Label/Label.module.css +16 -0
- package/dist/components/Layout/Layout.d.ts +2 -2
- package/dist/components/Layout/Layout.js +5 -20
- package/dist/components/Layout/Layout.module.css +7 -0
- package/dist/components/Link/Link.d.ts +2 -1
- package/dist/components/Link/Link.js +4 -62
- package/dist/components/Link/Link.module.css +48 -0
- package/dist/components/Modal/Modal.js +9 -52
- package/dist/components/Modal/Modal.module.css +57 -0
- package/dist/components/Page/Page.js +3 -23
- package/dist/components/Page/Page.module.css +23 -0
- package/dist/components/Pagination/Pagination.js +4 -42
- package/dist/components/Pagination/Pagination.module.css +43 -0
- package/dist/components/Popover/Popover.js +21 -26
- package/dist/components/Popover/Popover.module.css +19 -0
- package/dist/components/ProgressBar/ProgressBar.js +7 -37
- package/dist/components/ProgressBar/ProgressBar.module.css +31 -0
- package/dist/components/RadioGroup/RadioGroup.js +4 -79
- package/dist/components/RadioGroup/RadioGroup.module.css +81 -0
- package/dist/components/Select/Select.js +6 -80
- package/dist/components/Select/Select.module.css +89 -0
- package/dist/components/Sheet/Sheet.js +5 -56
- package/dist/components/Sheet/Sheet.module.css +64 -0
- package/dist/components/Skeleton/Skeleton.js +4 -49
- package/dist/components/Skeleton/Skeleton.module.css +29 -0
- package/dist/components/Slider/Slider.js +3 -140
- package/dist/components/Slider/Slider.module.css +130 -0
- package/dist/components/SplitButton/SplitButton.d.ts +2 -1
- package/dist/components/SplitButton/SplitButton.js +6 -82
- package/dist/components/SplitButton/SplitButton.module.css +79 -0
- package/dist/components/Switch/Switch.js +3 -54
- package/dist/components/Switch/Switch.module.css +64 -0
- package/dist/components/Table/Table.d.ts +1 -1
- package/dist/components/Table/Table.js +13 -109
- package/dist/components/Table/Table.module.css +111 -0
- package/dist/components/Tabs/Tabs.js +7 -56
- package/dist/components/Tabs/Tabs.module.css +65 -0
- package/dist/components/Text/Text.js +4 -106
- package/dist/components/Text/Text.module.css +123 -0
- package/dist/components/Textarea/Textarea.d.ts +1 -1
- package/dist/components/Textarea/Textarea.js +16 -20
- package/dist/components/Textarea/Textarea.module.css +23 -0
- package/dist/components/Toast/Toast.js +3 -67
- package/dist/components/Toast/Toast.module.css +87 -0
- package/dist/components/Tooltip/Tooltip.js +3 -19
- package/dist/components/Tooltip/Tooltip.module.css +17 -0
- package/dist/styles/globals.css +999 -0
- package/dist/styles/themes/ThemeProvider.js +4 -9
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +8 -5
- package/dist/styles/index.d.ts +0 -3
- package/dist/styles/index.js +0 -3
- package/dist/styles/mixins.d.ts +0 -3
- package/dist/styles/mixins.js +0 -25
- package/dist/styles/reset.d.ts +0 -1
- package/dist/styles/reset.js +0 -29
- package/dist/styles/theme.d.ts +0 -1
- package/dist/styles/theme.js +0 -11
- package/dist/styles/utilities.d.ts +0 -1
- package/dist/styles/utilities.js +0 -184
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
.container {
|
|
2
|
+
display: flex;
|
|
3
|
+
flex-direction: column;
|
|
4
|
+
gap: 0.75rem;
|
|
5
|
+
width: 100%;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.labelRow {
|
|
9
|
+
display: flex;
|
|
10
|
+
justify-content: space-between;
|
|
11
|
+
align-items: center;
|
|
12
|
+
font-family: var(--font-heading);
|
|
13
|
+
font-weight: 600;
|
|
14
|
+
font-size: var(--text-sm);
|
|
15
|
+
color: var(--foreground);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.valueDisplay {
|
|
19
|
+
font-family: var(--font-mono, monospace);
|
|
20
|
+
font-weight: 700;
|
|
21
|
+
color: var(--primary);
|
|
22
|
+
font-size: var(--text-base);
|
|
23
|
+
min-width: 3ch;
|
|
24
|
+
text-align: right;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.trackWrapper {
|
|
28
|
+
position: relative;
|
|
29
|
+
width: 100%;
|
|
30
|
+
height: 8px;
|
|
31
|
+
border-radius: 999px;
|
|
32
|
+
background: var(--muted);
|
|
33
|
+
overflow: visible;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.progressFill {
|
|
37
|
+
position: absolute;
|
|
38
|
+
left: 0;
|
|
39
|
+
top: 0;
|
|
40
|
+
height: 100%;
|
|
41
|
+
width: var(--percentage, 0%);
|
|
42
|
+
background: var(--primary);
|
|
43
|
+
border-radius: 999px;
|
|
44
|
+
z-index: 1;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.rangeInput {
|
|
48
|
+
appearance: none;
|
|
49
|
+
-webkit-appearance: none;
|
|
50
|
+
position: absolute;
|
|
51
|
+
top: 0;
|
|
52
|
+
left: 0;
|
|
53
|
+
width: 100%;
|
|
54
|
+
height: 100%;
|
|
55
|
+
background: transparent;
|
|
56
|
+
cursor: pointer;
|
|
57
|
+
margin: 0;
|
|
58
|
+
z-index: 10;
|
|
59
|
+
}
|
|
60
|
+
.rangeInput::-webkit-slider-runnable-track {
|
|
61
|
+
width: 100%;
|
|
62
|
+
height: 8px;
|
|
63
|
+
background: transparent;
|
|
64
|
+
border: none;
|
|
65
|
+
}
|
|
66
|
+
.rangeInput::-moz-range-track {
|
|
67
|
+
width: 100%;
|
|
68
|
+
height: 8px;
|
|
69
|
+
background: transparent;
|
|
70
|
+
border: none;
|
|
71
|
+
}
|
|
72
|
+
.rangeInput::-webkit-slider-thumb {
|
|
73
|
+
-webkit-appearance: none;
|
|
74
|
+
height: 20px;
|
|
75
|
+
width: 20px;
|
|
76
|
+
background: var(--primary);
|
|
77
|
+
border: 3px solid var(--background);
|
|
78
|
+
border-radius: 50%;
|
|
79
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2), 0 0 0 1px var(--card-border);
|
|
80
|
+
transition: all 0.15s cubic-bezier(0.4, 0, 0.2, 1);
|
|
81
|
+
margin-top: -6px;
|
|
82
|
+
}
|
|
83
|
+
.rangeInput::-moz-range-thumb {
|
|
84
|
+
height: 20px;
|
|
85
|
+
width: 20px;
|
|
86
|
+
background: var(--primary);
|
|
87
|
+
border: 3px solid var(--background);
|
|
88
|
+
border-radius: 50%;
|
|
89
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2), 0 0 0 1px var(--card-border);
|
|
90
|
+
transition: all 0.15s cubic-bezier(0.4, 0, 0.2, 1);
|
|
91
|
+
}
|
|
92
|
+
.rangeInput:hover::-webkit-slider-thumb {
|
|
93
|
+
transform: scale(1.15);
|
|
94
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25), 0 0 0 4px color-mix(in srgb, var(--primary) 20%, transparent);
|
|
95
|
+
}
|
|
96
|
+
.rangeInput:hover::-moz-range-thumb {
|
|
97
|
+
transform: scale(1.15);
|
|
98
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25), 0 0 0 4px color-mix(in srgb, var(--primary) 20%, transparent);
|
|
99
|
+
}
|
|
100
|
+
.rangeInput:active::-webkit-slider-thumb {
|
|
101
|
+
transform: scale(1.05);
|
|
102
|
+
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3), 0 0 0 6px color-mix(in srgb, var(--primary) 25%, transparent);
|
|
103
|
+
}
|
|
104
|
+
.rangeInput:active::-moz-range-thumb {
|
|
105
|
+
transform: scale(1.05);
|
|
106
|
+
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3), 0 0 0 6px color-mix(in srgb, var(--primary) 25%, transparent);
|
|
107
|
+
}
|
|
108
|
+
.rangeInput:focus {
|
|
109
|
+
outline: none;
|
|
110
|
+
}
|
|
111
|
+
.rangeInput:focus-visible::-webkit-slider-thumb {
|
|
112
|
+
outline: 2px solid var(--primary);
|
|
113
|
+
outline-offset: 2px;
|
|
114
|
+
}
|
|
115
|
+
.rangeInput:focus-visible::-moz-range-thumb {
|
|
116
|
+
outline: 2px solid var(--primary);
|
|
117
|
+
outline-offset: 2px;
|
|
118
|
+
}
|
|
119
|
+
.rangeInput:disabled {
|
|
120
|
+
cursor: not-allowed;
|
|
121
|
+
opacity: 0.5;
|
|
122
|
+
}
|
|
123
|
+
.rangeInput:disabled::-webkit-slider-thumb {
|
|
124
|
+
background: var(--muted-foreground);
|
|
125
|
+
cursor: not-allowed;
|
|
126
|
+
}
|
|
127
|
+
.rangeInput:disabled::-moz-range-thumb {
|
|
128
|
+
background: var(--muted-foreground);
|
|
129
|
+
cursor: not-allowed;
|
|
130
|
+
}
|
|
@@ -7,6 +7,7 @@ interface SplitButtonProps {
|
|
|
7
7
|
onPrimaryClick: () => void;
|
|
8
8
|
items: SplitButtonItem[];
|
|
9
9
|
variant?: 'primary' | 'secondary';
|
|
10
|
+
className?: string;
|
|
10
11
|
}
|
|
11
|
-
export declare function SplitButton({ primaryLabel, onPrimaryClick, items, variant }: SplitButtonProps): import("react/jsx-runtime").JSX.Element;
|
|
12
|
+
export declare function SplitButton({ primaryLabel, onPrimaryClick, items, variant, className }: SplitButtonProps): import("react/jsx-runtime").JSX.Element;
|
|
12
13
|
export {};
|
|
@@ -1,89 +1,13 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import { Popover } from '../..';
|
|
3
|
+
import clsx from 'clsx';
|
|
4
|
+
import { Popover } from '../Popover/Popover';
|
|
6
5
|
import { ChevronDown } from 'lucide-react';
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
border-radius: var(--radius);
|
|
11
|
-
box-shadow: var(--shadow-hard);
|
|
12
|
-
background-color: ${props => props.variant === 'primary' ? 'var(--primary)' : 'var(--secondary)'};
|
|
13
|
-
color: ${props => props.variant === 'primary' ? 'var(--primary-foreground)' : 'var(--secondary-foreground)'};
|
|
14
|
-
transition: all 0.1s ease;
|
|
15
|
-
&:hover {
|
|
16
|
-
transform: translate(-2px, -2px);
|
|
17
|
-
box-shadow: var(--shadow-hover);
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
&[aria-expanded="true"] {
|
|
21
|
-
transform: translate(-2px, -2px);
|
|
22
|
-
box-shadow: var(--shadow-hover);
|
|
23
|
-
}
|
|
24
|
-
`;
|
|
25
|
-
const StyledMainButton = styled.button `
|
|
26
|
-
border: none;
|
|
27
|
-
background: transparent;
|
|
28
|
-
color: inherit;
|
|
29
|
-
padding: 0.75rem 1rem;
|
|
30
|
-
padding-right: 0.75rem;
|
|
31
|
-
font-weight: 700;
|
|
32
|
-
font-size: var(--text-base);
|
|
33
|
-
text-transform: uppercase;
|
|
34
|
-
letter-spacing: 0.05em;
|
|
35
|
-
cursor: pointer;
|
|
36
|
-
border-right: 2px solid rgba(0,0,0,0.2);
|
|
37
|
-
|
|
38
|
-
&:hover {
|
|
39
|
-
background-color: rgba(0,0,0,0.25);
|
|
40
|
-
}
|
|
41
|
-
`;
|
|
42
|
-
const StyledDropdownTrigger = styled.button `
|
|
43
|
-
border: none;
|
|
44
|
-
background: transparent;
|
|
45
|
-
color: inherit;
|
|
46
|
-
padding: 0.75rem 0.75rem;
|
|
47
|
-
cursor: pointer;
|
|
48
|
-
display: flex;
|
|
49
|
-
align-items: center;
|
|
50
|
-
|
|
51
|
-
&:hover {
|
|
52
|
-
background-color: rgba(0,0,0,0.25);
|
|
53
|
-
}
|
|
54
|
-
`;
|
|
55
|
-
const StyledDropdownMenu = styled.div `
|
|
56
|
-
background: var(--card-bg);
|
|
57
|
-
border: var(--border-width) solid var(--primary);
|
|
58
|
-
border-radius: var(--radius);
|
|
59
|
-
box-shadow: var(--shadow-hover);
|
|
60
|
-
min-width: 200px;
|
|
61
|
-
overflow: hidden;
|
|
62
|
-
display: flex;
|
|
63
|
-
flex-direction: column;
|
|
64
|
-
gap: 0.25rem;
|
|
65
|
-
padding: 0.25rem;
|
|
66
|
-
`;
|
|
67
|
-
const StyledDropdownItem = styled.button `
|
|
68
|
-
text-align: left;
|
|
69
|
-
padding: 0.75rem 1rem;
|
|
70
|
-
background: transparent;
|
|
71
|
-
border: none;
|
|
72
|
-
color: var(--foreground);
|
|
73
|
-
cursor: pointer;
|
|
74
|
-
border-radius: calc(var(--radius) - 2px);
|
|
75
|
-
font-size: var(--text-base);
|
|
76
|
-
font-weight: 600;
|
|
77
|
-
transition: background-color 0.2s;
|
|
78
|
-
|
|
79
|
-
&:hover {
|
|
80
|
-
background-color: color-mix(in srgb, var(--primary), transparent 85%);
|
|
81
|
-
color: var(--primary);
|
|
82
|
-
}
|
|
83
|
-
`;
|
|
84
|
-
export function SplitButton({ primaryLabel, onPrimaryClick, items, variant = 'primary' }) {
|
|
6
|
+
import styles from './SplitButton.module.css';
|
|
7
|
+
import { useState } from 'react';
|
|
8
|
+
export function SplitButton({ primaryLabel, onPrimaryClick, items, variant = 'primary', className }) {
|
|
85
9
|
const [isOpen, setIsOpen] = useState(false);
|
|
86
|
-
return (_jsx(Popover, { isOpen: isOpen, onClose: () => setIsOpen(false), placement: "bottom-end", trigger: _jsxs(
|
|
10
|
+
return (_jsx(Popover, { isOpen: isOpen, onClose: () => setIsOpen(false), placement: "bottom-end", trigger: _jsxs("div", { className: clsx(styles.container, styles[variant], className), "aria-expanded": isOpen, children: [_jsx("button", { className: styles.mainButton, onClick: onPrimaryClick, children: primaryLabel }), _jsx("button", { className: styles.dropdownTrigger, onClick: () => setIsOpen(!isOpen), children: _jsx(ChevronDown, { size: 16, strokeWidth: 3 }) })] }), content: _jsx("div", { className: styles.menu, children: items.map((item, index) => (_jsx("button", { className: styles.item, onClick: () => {
|
|
87
11
|
item.onClick();
|
|
88
12
|
setIsOpen(false);
|
|
89
13
|
}, children: item.label }, index))) }) }));
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
.container {
|
|
2
|
+
display: inline-flex;
|
|
3
|
+
border: var(--border-width) solid var(--card-border);
|
|
4
|
+
border-radius: var(--radius);
|
|
5
|
+
box-shadow: var(--shadow-hard);
|
|
6
|
+
transition: all 0.1s ease;
|
|
7
|
+
}
|
|
8
|
+
.container.primary {
|
|
9
|
+
background-color: var(--primary);
|
|
10
|
+
color: var(--primary-foreground);
|
|
11
|
+
}
|
|
12
|
+
.container.secondary {
|
|
13
|
+
background-color: var(--secondary);
|
|
14
|
+
color: var(--secondary-foreground);
|
|
15
|
+
}
|
|
16
|
+
.container:hover, .container[aria-expanded=true] {
|
|
17
|
+
transform: translate(-2px, -2px);
|
|
18
|
+
box-shadow: var(--shadow-hover);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.mainButton {
|
|
22
|
+
border: none;
|
|
23
|
+
background: transparent;
|
|
24
|
+
color: inherit;
|
|
25
|
+
padding: 0.75rem 1rem;
|
|
26
|
+
padding-right: 0.75rem;
|
|
27
|
+
font-weight: 700;
|
|
28
|
+
font-size: var(--text-base);
|
|
29
|
+
text-transform: uppercase;
|
|
30
|
+
letter-spacing: 0.05em;
|
|
31
|
+
cursor: pointer;
|
|
32
|
+
border-right: 2px solid rgba(0, 0, 0, 0.2);
|
|
33
|
+
}
|
|
34
|
+
.mainButton:hover {
|
|
35
|
+
background-color: rgba(0, 0, 0, 0.25);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.dropdownTrigger {
|
|
39
|
+
border: none;
|
|
40
|
+
background: transparent;
|
|
41
|
+
color: inherit;
|
|
42
|
+
padding: 0.75rem 0.75rem;
|
|
43
|
+
cursor: pointer;
|
|
44
|
+
display: flex;
|
|
45
|
+
align-items: center;
|
|
46
|
+
}
|
|
47
|
+
.dropdownTrigger:hover {
|
|
48
|
+
background-color: rgba(0, 0, 0, 0.25);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.menu {
|
|
52
|
+
background: var(--card-bg);
|
|
53
|
+
border: var(--border-width) solid var(--primary);
|
|
54
|
+
border-radius: var(--radius);
|
|
55
|
+
box-shadow: var(--shadow-hover);
|
|
56
|
+
min-width: 200px;
|
|
57
|
+
overflow: hidden;
|
|
58
|
+
display: flex;
|
|
59
|
+
flex-direction: column;
|
|
60
|
+
gap: 0.25rem;
|
|
61
|
+
padding: 0.25rem;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.item {
|
|
65
|
+
text-align: left;
|
|
66
|
+
padding: 0.75rem 1rem;
|
|
67
|
+
background: transparent;
|
|
68
|
+
border: none;
|
|
69
|
+
color: var(--foreground);
|
|
70
|
+
cursor: pointer;
|
|
71
|
+
border-radius: calc(var(--radius) - 2px);
|
|
72
|
+
font-size: var(--text-base);
|
|
73
|
+
font-weight: 600;
|
|
74
|
+
transition: background-color 0.2s;
|
|
75
|
+
}
|
|
76
|
+
.item:hover {
|
|
77
|
+
background-color: color-mix(in srgb, var(--primary), transparent 85%);
|
|
78
|
+
color: var(--primary);
|
|
79
|
+
}
|
|
@@ -11,60 +11,9 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
11
11
|
return t;
|
|
12
12
|
};
|
|
13
13
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
14
|
+
import clsx from 'clsx';
|
|
15
|
+
import styles from './Switch.module.css';
|
|
14
16
|
import React from 'react';
|
|
15
|
-
import styled from '@emotion/styled';
|
|
16
|
-
const SwitchContainer = styled.label `
|
|
17
|
-
display: inline-flex;
|
|
18
|
-
align-items: center;
|
|
19
|
-
gap: 1rem;
|
|
20
|
-
cursor: ${props => props.disabled ? 'not-allowed' : 'pointer'};
|
|
21
|
-
opacity: ${props => props.disabled ? 0.6 : 1};
|
|
22
|
-
user-select: none;
|
|
23
|
-
`;
|
|
24
|
-
const Input = styled.input `
|
|
25
|
-
position: absolute;
|
|
26
|
-
width: 1px;
|
|
27
|
-
height: 1px;
|
|
28
|
-
padding: 0;
|
|
29
|
-
margin: -1px;
|
|
30
|
-
overflow: hidden;
|
|
31
|
-
clip: rect(0, 0, 0, 0);
|
|
32
|
-
white-space: nowrap;
|
|
33
|
-
border: 0;
|
|
34
|
-
`;
|
|
35
|
-
const Toggle = styled.div `
|
|
36
|
-
position: relative;
|
|
37
|
-
width: 58px;
|
|
38
|
-
height: 32px;
|
|
39
|
-
background-color: ${props => props.checked ? 'var(--primary)' : 'var(--card-bg)'};
|
|
40
|
-
border: var(--border-width) solid var(--card-border);
|
|
41
|
-
border-radius: var(--radius-pill);
|
|
42
|
-
transition: background-color var(--duration-normal) var(--ease-in-out), transform var(--duration-fast) var(--ease-out), box-shadow var(--duration-fast) var(--ease-out);
|
|
43
|
-
box-shadow: var(--shadow-sm);
|
|
44
|
-
box-sizing: border-box;
|
|
45
|
-
|
|
46
|
-
&::after {
|
|
47
|
-
content: '';
|
|
48
|
-
display: block;
|
|
49
|
-
position: absolute;
|
|
50
|
-
top: 50%;
|
|
51
|
-
left: 4px;
|
|
52
|
-
width: 24px;
|
|
53
|
-
height: 24px;
|
|
54
|
-
background-color: ${props => props.checked ? 'var(--primary-foreground)' : 'var(--muted)'};
|
|
55
|
-
border: var(--border-width) solid var(--card-border);
|
|
56
|
-
border-radius: 50%;
|
|
57
|
-
transform: translateY(-50%) translateX(${props => props.checked ? '20px' : '0'});
|
|
58
|
-
transition: transform var(--duration-normal) var(--ease-in-out), background-color var(--duration-normal) var(--ease-in-out);
|
|
59
|
-
box-sizing: border-box;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
`;
|
|
63
|
-
const Label = styled.span `
|
|
64
|
-
font-family: var(--font-heading);
|
|
65
|
-
font-weight: 600;
|
|
66
|
-
color: var(--foreground);
|
|
67
|
-
`;
|
|
68
17
|
export const Switch = React.forwardRef((_a, ref) => {
|
|
69
18
|
var { checked = false, onChange, disabled, label, id, className } = _a, props = __rest(_a, ["checked", "onChange", "disabled", "label", "id", "className"]);
|
|
70
19
|
const handleChange = (e) => {
|
|
@@ -72,6 +21,6 @@ export const Switch = React.forwardRef((_a, ref) => {
|
|
|
72
21
|
return;
|
|
73
22
|
onChange === null || onChange === void 0 ? void 0 : onChange(e.target.checked);
|
|
74
23
|
};
|
|
75
|
-
return (_jsxs(
|
|
24
|
+
return (_jsxs("label", { className: clsx(styles.switchContainer, disabled && styles.disabled, className), children: [_jsx("input", Object.assign({ className: styles.input, type: "checkbox", role: "switch", id: id, ref: ref, checked: checked, onChange: handleChange, disabled: disabled, readOnly: props.readOnly, "aria-checked": checked }, props)), _jsx("div", { className: clsx(styles.toggle, checked && styles.checked) }), label && _jsx("span", { className: styles.label, children: label })] }));
|
|
76
25
|
});
|
|
77
26
|
Switch.displayName = 'Switch';
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
.switchContainer {
|
|
2
|
+
display: inline-flex;
|
|
3
|
+
align-items: center;
|
|
4
|
+
gap: 1rem;
|
|
5
|
+
cursor: pointer;
|
|
6
|
+
opacity: 1;
|
|
7
|
+
user-select: none;
|
|
8
|
+
}
|
|
9
|
+
.switchContainer.disabled {
|
|
10
|
+
cursor: not-allowed;
|
|
11
|
+
opacity: 0.6;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.input {
|
|
15
|
+
position: absolute;
|
|
16
|
+
width: 1px;
|
|
17
|
+
height: 1px;
|
|
18
|
+
padding: 0;
|
|
19
|
+
margin: -1px;
|
|
20
|
+
overflow: hidden;
|
|
21
|
+
clip: rect(0, 0, 0, 0);
|
|
22
|
+
white-space: nowrap;
|
|
23
|
+
border: 0;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.toggle {
|
|
27
|
+
position: relative;
|
|
28
|
+
width: 58px;
|
|
29
|
+
height: 32px;
|
|
30
|
+
background-color: var(--card-bg);
|
|
31
|
+
border: var(--border-width) solid var(--card-border);
|
|
32
|
+
border-radius: var(--radius-pill);
|
|
33
|
+
transition: background-color var(--duration-normal) var(--ease-in-out), transform var(--duration-fast) var(--ease-out), box-shadow var(--duration-fast) var(--ease-out);
|
|
34
|
+
box-shadow: var(--shadow-sm);
|
|
35
|
+
box-sizing: border-box;
|
|
36
|
+
}
|
|
37
|
+
.toggle::after {
|
|
38
|
+
content: "";
|
|
39
|
+
display: block;
|
|
40
|
+
position: absolute;
|
|
41
|
+
top: 50%;
|
|
42
|
+
left: 4px;
|
|
43
|
+
width: 24px;
|
|
44
|
+
height: 24px;
|
|
45
|
+
background-color: var(--muted);
|
|
46
|
+
border: var(--border-width) solid var(--card-border);
|
|
47
|
+
border-radius: 50%;
|
|
48
|
+
transform: translateY(-50%) translateX(0);
|
|
49
|
+
transition: transform var(--duration-normal) var(--ease-in-out), background-color var(--duration-normal) var(--ease-in-out);
|
|
50
|
+
box-sizing: border-box;
|
|
51
|
+
}
|
|
52
|
+
.toggle.checked {
|
|
53
|
+
background-color: var(--primary);
|
|
54
|
+
}
|
|
55
|
+
.toggle.checked::after {
|
|
56
|
+
background-color: var(--primary-foreground);
|
|
57
|
+
transform: translateY(-50%) translateX(20px);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.label {
|
|
61
|
+
font-family: var(--font-heading);
|
|
62
|
+
font-weight: 600;
|
|
63
|
+
color: var(--foreground);
|
|
64
|
+
}
|
|
@@ -1,104 +1,14 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import
|
|
4
|
-
import styled from '@emotion/styled';
|
|
3
|
+
import clsx from 'clsx';
|
|
5
4
|
import { useReactTable, getCoreRowModel, getSortedRowModel, getPaginationRowModel, getFilteredRowModel, flexRender, } from '@tanstack/react-table';
|
|
6
5
|
import { useVirtualizer } from '@tanstack/react-virtual';
|
|
7
|
-
import { Input
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
background: var(--card-bg);
|
|
14
|
-
box-shadow: var(--shadow-hard);
|
|
15
|
-
overflow: hidden;
|
|
16
|
-
display: flex;
|
|
17
|
-
flex-direction: column;
|
|
18
|
-
`;
|
|
19
|
-
const Toolbar = styled.div `
|
|
20
|
-
padding: var(--spacing-md);
|
|
21
|
-
border-bottom: var(--border-width) solid var(--card-border);
|
|
22
|
-
background: var(--background);
|
|
23
|
-
display: flex;
|
|
24
|
-
justify-content: space-between;
|
|
25
|
-
align-items: center;
|
|
26
|
-
gap: 1rem;
|
|
27
|
-
`;
|
|
28
|
-
const StyledTable = styled.table `
|
|
29
|
-
width: 100%;
|
|
30
|
-
border-collapse: collapse;
|
|
31
|
-
font-size: var(--text-base);
|
|
32
|
-
`;
|
|
33
|
-
const getDensityPadding = (density = 'standard') => {
|
|
34
|
-
switch (density) {
|
|
35
|
-
case 'compact': return '0.5rem 1rem';
|
|
36
|
-
case 'relaxed': return '1.5rem 1rem';
|
|
37
|
-
case 'standard':
|
|
38
|
-
default: return '1rem';
|
|
39
|
-
}
|
|
40
|
-
};
|
|
41
|
-
const Th = styled.th `
|
|
42
|
-
text-align: left;
|
|
43
|
-
padding: ${props => getDensityPadding(props.$density)};
|
|
44
|
-
background: var(--secondary);
|
|
45
|
-
border-bottom: var(--border-width) solid var(--card-border);
|
|
46
|
-
font-weight: 700;
|
|
47
|
-
text-transform: uppercase;
|
|
48
|
-
letter-spacing: 0.05em;
|
|
49
|
-
cursor: ${props => props.isSortable ? 'pointer' : 'default'};
|
|
50
|
-
user-select: none;
|
|
51
|
-
white-space: nowrap;
|
|
52
|
-
color: var(--secondary-foreground);
|
|
53
|
-
|
|
54
|
-
${props => props.isSortable && `
|
|
55
|
-
&:hover {
|
|
56
|
-
filter: brightness(0.95);
|
|
57
|
-
color: var(--secondary-foreground);
|
|
58
|
-
}
|
|
59
|
-
`}
|
|
60
|
-
`;
|
|
61
|
-
const Td = styled.td `
|
|
62
|
-
padding: ${props => getDensityPadding(props.$density)};
|
|
63
|
-
border-bottom: 1px solid var(--card-border);
|
|
64
|
-
color: var(--foreground);
|
|
65
|
-
`;
|
|
66
|
-
const Tr = styled.tr `
|
|
67
|
-
&:last-child td {
|
|
68
|
-
border-bottom: none;
|
|
69
|
-
}
|
|
70
|
-
&:hover {
|
|
71
|
-
background-color: rgba(var(--muted-rgb, 113, 128, 150), 0.1);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
${props => props.$striped && `
|
|
75
|
-
&:nth-of-type(even) {
|
|
76
|
-
background-color: rgba(var(--muted-rgb, 113, 128, 150), 0.05);
|
|
77
|
-
}
|
|
78
|
-
&:hover {
|
|
79
|
-
background-color: rgba(var(--muted-rgb, 113, 128, 150), 0.15);
|
|
80
|
-
}
|
|
81
|
-
`}
|
|
82
|
-
|
|
83
|
-
/* Hide actions by default */
|
|
84
|
-
& .row-actions {
|
|
85
|
-
opacity: 0;
|
|
86
|
-
transition: opacity 0.2s ease-in-out;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/* Show actions on hover */
|
|
90
|
-
&:hover .row-actions {
|
|
91
|
-
opacity: 1;
|
|
92
|
-
}
|
|
93
|
-
`;
|
|
94
|
-
const PaginationContainer = styled.div `
|
|
95
|
-
padding: var(--spacing-md);
|
|
96
|
-
border-top: var(--border-width) solid var(--card-border);
|
|
97
|
-
background: var(--background);
|
|
98
|
-
display: flex;
|
|
99
|
-
justify-content: space-between;
|
|
100
|
-
align-items: center;
|
|
101
|
-
`;
|
|
6
|
+
import { Input } from '../Input/Input';
|
|
7
|
+
import { Select } from '../Select/Select';
|
|
8
|
+
import { Flex } from '../Layout/Layout';
|
|
9
|
+
import { Pagination } from '../Pagination/Pagination';
|
|
10
|
+
import styles from './Table.module.css';
|
|
11
|
+
import React, { useState } from 'react';
|
|
102
12
|
export function Table({ data, columns, enablePagination = true, enableFiltering = true, enableSorting = true, pageSize = 10, height, className, style, variant = 'default', density = 'standard', toolbarContent, striped = false, }) {
|
|
103
13
|
const [sorting, setSorting] = useState([]);
|
|
104
14
|
const [globalFilter, setGlobalFilter] = useState('');
|
|
@@ -133,21 +43,15 @@ export function Table({ data, columns, enablePagination = true, enableFiltering
|
|
|
133
43
|
overscan: 5,
|
|
134
44
|
});
|
|
135
45
|
const isVirtual = !!height;
|
|
136
|
-
|
|
137
|
-
border: 'none',
|
|
138
|
-
boxShadow: 'none',
|
|
139
|
-
background: 'transparent',
|
|
140
|
-
borderRadius: 0,
|
|
141
|
-
} : {};
|
|
142
|
-
return (_jsxs(TableContainer, { className: className, style: Object.assign(Object.assign({}, variantStyles), style), children: [enableFiltering && (_jsxs(Toolbar, { children: [_jsx("div", { style: { width: '300px' }, children: _jsx(Input, { placeholder: "Search...", value: globalFilter !== null && globalFilter !== void 0 ? globalFilter : '', onChange: (e) => setGlobalFilter(e.target.value) }) }), toolbarContent && (_jsx(Flex, { gap: "1rem", align: "center", children: toolbarContent }))] })), _jsxs("div", { ref: parentRef, style: {
|
|
46
|
+
return (_jsxs("div", { className: clsx(styles.container, variant === 'flat' && styles.flat, className), style: style, children: [enableFiltering && (_jsxs("div", { className: styles.toolbar, children: [_jsx("div", { style: { width: '300px' }, children: _jsx(Input, { placeholder: "Search...", value: globalFilter !== null && globalFilter !== void 0 ? globalFilter : '', onChange: (e) => setGlobalFilter(e.target.value) }) }), toolbarContent && (_jsx(Flex, { gap: "1rem", align: "center", children: toolbarContent }))] })), _jsxs("div", { ref: parentRef, style: {
|
|
143
47
|
height: height ? height : 'auto',
|
|
144
48
|
overflowY: height ? 'auto' : 'visible',
|
|
145
49
|
overflowX: 'auto',
|
|
146
50
|
width: '100%'
|
|
147
|
-
}, children: [_jsxs(
|
|
51
|
+
}, children: [_jsxs("table", { className: styles.table, children: [_jsx("thead", { children: table.getHeaderGroups().map((headerGroup) => (_jsx("tr", { children: headerGroup.headers.map((header) => {
|
|
148
52
|
var _a;
|
|
149
53
|
const canSort = header.column.getCanSort();
|
|
150
|
-
return (_jsx(
|
|
54
|
+
return (_jsx("th", { onClick: canSort ? header.column.getToggleSortingHandler() : undefined, style: { width: header.getSize() }, className: clsx(styles.th, styles[density], canSort && styles.sortable), children: _jsxs("div", { className: styles.headerContent, children: [flexRender(header.column.columnDef.header, header.getContext()), canSort && ((_a = {
|
|
151
55
|
asc: ' ▲',
|
|
152
56
|
desc: ' ▼',
|
|
153
57
|
}[header.column.getIsSorted()]) !== null && _a !== void 0 ? _a : null)] }) }, header.id));
|
|
@@ -157,15 +61,15 @@ export function Table({ data, columns, enablePagination = true, enableFiltering
|
|
|
157
61
|
position: 'relative',
|
|
158
62
|
}, children: rowVirtualizer.getVirtualItems().map((virtualRow) => {
|
|
159
63
|
const row = rows[virtualRow.index];
|
|
160
|
-
return (_jsx(
|
|
64
|
+
return (_jsx("tr", { className: clsx(styles.tr, striped && styles.striped), style: {
|
|
161
65
|
position: 'absolute',
|
|
162
66
|
top: 0,
|
|
163
67
|
left: 0,
|
|
164
68
|
width: '100%',
|
|
165
69
|
height: `${virtualRow.size}px`,
|
|
166
70
|
transform: `translateY(${virtualRow.start}px)`,
|
|
167
|
-
}, children: row.getVisibleCells().map((cell) => (_jsx(
|
|
168
|
-
}) })) : (_jsx("tbody", { children: table.getRowModel().rows.map((row) => (_jsx(
|
|
71
|
+
}, children: row.getVisibleCells().map((cell) => (_jsx("td", { className: clsx(styles.td, styles[density]), children: flexRender(cell.column.columnDef.cell, cell.getContext()) }, cell.id))) }, row.id));
|
|
72
|
+
}) })) : (_jsx("tbody", { children: table.getRowModel().rows.map((row) => (_jsx("tr", { className: clsx(styles.tr, striped && styles.striped, 'group'), children: row.getVisibleCells().map((cell) => (_jsx("td", { className: clsx(styles.td, styles[density]), children: flexRender(cell.column.columnDef.cell, cell.getContext()) }, cell.id))) }, row.id))) }))] }), table.getRowModel().rows.length === 0 && (_jsx("div", { className: styles.noResults, children: "No results found." }))] }), enablePagination && !isVirtual && (_jsx("div", { className: styles.paginationContainer, children: _jsxs(Flex, { gap: "1rem", align: "center", style: { width: '100%', justifyContent: 'space-between' }, children: [_jsx("div", { style: { flexShrink: 0 }, children: _jsx(Select, { value: table.getState().pagination.pageSize, onChange: (e) => {
|
|
169
73
|
table.setPageSize(Number(e.target.value));
|
|
170
74
|
}, options: [
|
|
171
75
|
{ value: 10, label: '10 rows' },
|