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.
Files changed (94) hide show
  1. package/README.md +23 -20
  2. package/dist/DesignSystemProvider.d.ts +1 -0
  3. package/dist/DesignSystemProvider.js +3 -4
  4. package/dist/components/Accordion/Accordion.js +5 -63
  5. package/dist/components/Accordion/Accordion.module.css +69 -0
  6. package/dist/components/ActionRow/ActionRow.js +3 -28
  7. package/dist/components/ActionRow/ActionRow.module.css +24 -0
  8. package/dist/components/Alert/Alert.js +3 -58
  9. package/dist/components/Alert/Alert.module.css +77 -0
  10. package/dist/components/Avatar/Avatar.js +3 -45
  11. package/dist/components/Avatar/Avatar.module.css +67 -0
  12. package/dist/components/Badge/Badge.d.ts +1 -1
  13. package/dist/components/Badge/Badge.js +4 -42
  14. package/dist/components/Badge/Badge.module.css +31 -0
  15. package/dist/components/Breadcrumbs/Breadcrumbs.js +6 -38
  16. package/dist/components/Breadcrumbs/Breadcrumbs.module.css +34 -0
  17. package/dist/components/Button/Button.d.ts +1 -1
  18. package/dist/components/Button/Button.js +5 -129
  19. package/dist/components/Button/Button.module.css +112 -0
  20. package/dist/components/Card/Card.d.ts +1 -1
  21. package/dist/components/Card/Card.js +4 -13
  22. package/dist/components/Card/Card.module.css +8 -0
  23. package/dist/components/Drawer/Drawer.js +5 -71
  24. package/dist/components/Drawer/Drawer.module.css +75 -0
  25. package/dist/components/Dropdown/Dropdown.d.ts +2 -1
  26. package/dist/components/Dropdown/Dropdown.js +6 -39
  27. package/dist/components/Dropdown/Dropdown.module.css +33 -0
  28. package/dist/components/Form/Form.d.ts +4 -9
  29. package/dist/components/Form/Form.js +9 -43
  30. package/dist/components/Form/Form.module.css +41 -0
  31. package/dist/components/Input/Input.js +3 -59
  32. package/dist/components/Input/Input.module.css +86 -0
  33. package/dist/components/Label/Label.d.ts +1 -1
  34. package/dist/components/Label/Label.js +4 -23
  35. package/dist/components/Label/Label.module.css +16 -0
  36. package/dist/components/Layout/Layout.d.ts +2 -2
  37. package/dist/components/Layout/Layout.js +5 -20
  38. package/dist/components/Layout/Layout.module.css +7 -0
  39. package/dist/components/Link/Link.d.ts +2 -1
  40. package/dist/components/Link/Link.js +4 -62
  41. package/dist/components/Link/Link.module.css +48 -0
  42. package/dist/components/Modal/Modal.js +9 -52
  43. package/dist/components/Modal/Modal.module.css +57 -0
  44. package/dist/components/Page/Page.js +3 -23
  45. package/dist/components/Page/Page.module.css +23 -0
  46. package/dist/components/Pagination/Pagination.js +4 -42
  47. package/dist/components/Pagination/Pagination.module.css +43 -0
  48. package/dist/components/Popover/Popover.js +21 -26
  49. package/dist/components/Popover/Popover.module.css +19 -0
  50. package/dist/components/ProgressBar/ProgressBar.js +7 -37
  51. package/dist/components/ProgressBar/ProgressBar.module.css +31 -0
  52. package/dist/components/RadioGroup/RadioGroup.js +4 -79
  53. package/dist/components/RadioGroup/RadioGroup.module.css +81 -0
  54. package/dist/components/Select/Select.js +6 -80
  55. package/dist/components/Select/Select.module.css +89 -0
  56. package/dist/components/Sheet/Sheet.js +5 -56
  57. package/dist/components/Sheet/Sheet.module.css +64 -0
  58. package/dist/components/Skeleton/Skeleton.js +4 -49
  59. package/dist/components/Skeleton/Skeleton.module.css +29 -0
  60. package/dist/components/Slider/Slider.js +3 -140
  61. package/dist/components/Slider/Slider.module.css +130 -0
  62. package/dist/components/SplitButton/SplitButton.d.ts +2 -1
  63. package/dist/components/SplitButton/SplitButton.js +6 -82
  64. package/dist/components/SplitButton/SplitButton.module.css +79 -0
  65. package/dist/components/Switch/Switch.js +3 -54
  66. package/dist/components/Switch/Switch.module.css +64 -0
  67. package/dist/components/Table/Table.d.ts +1 -1
  68. package/dist/components/Table/Table.js +13 -109
  69. package/dist/components/Table/Table.module.css +111 -0
  70. package/dist/components/Tabs/Tabs.js +7 -56
  71. package/dist/components/Tabs/Tabs.module.css +65 -0
  72. package/dist/components/Text/Text.js +4 -106
  73. package/dist/components/Text/Text.module.css +123 -0
  74. package/dist/components/Textarea/Textarea.d.ts +1 -1
  75. package/dist/components/Textarea/Textarea.js +16 -20
  76. package/dist/components/Textarea/Textarea.module.css +23 -0
  77. package/dist/components/Toast/Toast.js +3 -67
  78. package/dist/components/Toast/Toast.module.css +87 -0
  79. package/dist/components/Tooltip/Tooltip.js +3 -19
  80. package/dist/components/Tooltip/Tooltip.module.css +17 -0
  81. package/dist/styles/globals.css +999 -0
  82. package/dist/styles/themes/ThemeProvider.js +4 -9
  83. package/dist/tsconfig.tsbuildinfo +1 -1
  84. package/package.json +8 -5
  85. package/dist/styles/index.d.ts +0 -3
  86. package/dist/styles/index.js +0 -3
  87. package/dist/styles/mixins.d.ts +0 -3
  88. package/dist/styles/mixins.js +0 -25
  89. package/dist/styles/reset.d.ts +0 -1
  90. package/dist/styles/reset.js +0 -29
  91. package/dist/styles/theme.d.ts +0 -1
  92. package/dist/styles/theme.js +0 -11
  93. package/dist/styles/utilities.d.ts +0 -1
  94. 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 { useState } from 'react';
4
- import styled from '@emotion/styled';
5
- import { Popover } from '../..';
3
+ import clsx from 'clsx';
4
+ import { Popover } from '../Popover/Popover';
6
5
  import { ChevronDown } from 'lucide-react';
7
- const StyledContainer = styled.div `
8
- display: inline-flex;
9
- border: var(--border-width) solid var(--card-border);
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(StyledContainer, { variant: variant, children: [_jsx(StyledMainButton, { onClick: onPrimaryClick, children: primaryLabel }), _jsx(StyledDropdownTrigger, { onClick: () => setIsOpen(!isOpen), children: _jsx(ChevronDown, { size: 16, strokeWidth: 3 }) })] }), content: _jsx(StyledDropdownMenu, { children: items.map((item, index) => (_jsx(StyledDropdownItem, { onClick: () => {
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(SwitchContainer, { disabled: disabled, className: className, children: [_jsx(Input, Object.assign({ type: "checkbox", role: "switch", id: id, ref: ref, checked: checked, onChange: handleChange, disabled: disabled, readOnly: props.readOnly, "aria-checked": checked }, props)), _jsx(Toggle, { checked: checked }), label && _jsx(Label, { children: label })] }));
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,5 +1,5 @@
1
- import React from 'react';
2
1
  import { ColumnDef } from '@tanstack/react-table';
2
+ import React from 'react';
3
3
  interface TableProps<T> {
4
4
  data: T[];
5
5
  columns: ColumnDef<T>[];
@@ -1,104 +1,14 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import React, { useState } from 'react';
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, Select, Flex } from '../..';
8
- import { Pagination } from '../Pagination';
9
- const TableContainer = styled.div `
10
- width: 100%;
11
- border: var(--border-width) solid var(--card-border);
12
- border-radius: var(--radius);
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
- const variantStyles = variant === 'flat' ? {
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(StyledTable, { children: [_jsx("thead", { children: table.getHeaderGroups().map((headerGroup) => (_jsx("tr", { children: headerGroup.headers.map((header) => {
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(Th, { onClick: canSort ? header.column.getToggleSortingHandler() : undefined, style: { width: header.getSize() }, isSortable: canSort, "$density": density, children: _jsxs(Flex, { align: "center", gap: "0.5rem", children: [flexRender(header.column.columnDef.header, header.getContext()), canSort && ((_a = {
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(Tr, { "$striped": striped, style: {
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(Td, { "$density": density, children: flexRender(cell.column.columnDef.cell, cell.getContext()) }, cell.id))) }, row.id));
168
- }) })) : (_jsx("tbody", { children: table.getRowModel().rows.map((row) => (_jsx(Tr, { className: "group", "$striped": striped, children: row.getVisibleCells().map((cell) => (_jsx(Td, { "$density": density, children: flexRender(cell.column.columnDef.cell, cell.getContext()) }, cell.id))) }, row.id))) }))] }), table.getRowModel().rows.length === 0 && (_jsx("div", { style: { padding: '2rem', textAlign: 'center', color: 'var(--muted-foreground)' }, children: "No results found." }))] }), enablePagination && !isVirtual && (_jsx(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) => {
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' },