doom-design-system 0.1.0

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 (111) hide show
  1. package/README.md +50 -0
  2. package/dist/DesignSystemProvider.d.ts +7 -0
  3. package/dist/DesignSystemProvider.js +13 -0
  4. package/dist/components/ActionRow/ActionRow.d.ts +9 -0
  5. package/dist/components/ActionRow/ActionRow.js +47 -0
  6. package/dist/components/ActionRow/index.d.ts +1 -0
  7. package/dist/components/ActionRow/index.js +1 -0
  8. package/dist/components/Badge/Badge.d.ts +8 -0
  9. package/dist/components/Badge/Badge.js +57 -0
  10. package/dist/components/Badge/index.d.ts +1 -0
  11. package/dist/components/Badge/index.js +1 -0
  12. package/dist/components/Button/Button.d.ts +9 -0
  13. package/dist/components/Button/Button.js +110 -0
  14. package/dist/components/Button/index.d.ts +1 -0
  15. package/dist/components/Button/index.js +1 -0
  16. package/dist/components/Card/Card.d.ts +8 -0
  17. package/dist/components/Card/Card.js +28 -0
  18. package/dist/components/Card/index.d.ts +1 -0
  19. package/dist/components/Card/index.js +1 -0
  20. package/dist/components/Dropdown/Dropdown.d.ts +11 -0
  21. package/dist/components/Dropdown/Dropdown.js +47 -0
  22. package/dist/components/Dropdown/index.d.ts +1 -0
  23. package/dist/components/Dropdown/index.js +1 -0
  24. package/dist/components/Form/Form.d.ts +14 -0
  25. package/dist/components/Form/Form.js +24 -0
  26. package/dist/components/Form/index.d.ts +1 -0
  27. package/dist/components/Form/index.js +1 -0
  28. package/dist/components/Icon/index.d.ts +25 -0
  29. package/dist/components/Icon/index.js +41 -0
  30. package/dist/components/Input/Input.d.ts +12 -0
  31. package/dist/components/Input/Input.js +129 -0
  32. package/dist/components/Input/index.d.ts +1 -0
  33. package/dist/components/Input/index.js +1 -0
  34. package/dist/components/Layout/Layout.d.ts +17 -0
  35. package/dist/components/Layout/Layout.js +37 -0
  36. package/dist/components/Layout/index.d.ts +1 -0
  37. package/dist/components/Layout/index.js +1 -0
  38. package/dist/components/Link/Link.d.ts +11 -0
  39. package/dist/components/Link/Link.js +78 -0
  40. package/dist/components/Link/index.d.ts +1 -0
  41. package/dist/components/Link/index.js +1 -0
  42. package/dist/components/Modal/Modal.d.ts +22 -0
  43. package/dist/components/Modal/Modal.js +89 -0
  44. package/dist/components/Modal/index.d.ts +1 -0
  45. package/dist/components/Modal/index.js +1 -0
  46. package/dist/components/Page/Page.d.ts +13 -0
  47. package/dist/components/Page/Page.js +27 -0
  48. package/dist/components/Page/index.d.ts +1 -0
  49. package/dist/components/Page/index.js +1 -0
  50. package/dist/components/Popover/Popover.d.ts +11 -0
  51. package/dist/components/Popover/Popover.js +91 -0
  52. package/dist/components/Popover/index.d.ts +1 -0
  53. package/dist/components/Popover/index.js +1 -0
  54. package/dist/components/ProgressBar/ProgressBar.d.ts +12 -0
  55. package/dist/components/ProgressBar/ProgressBar.js +42 -0
  56. package/dist/components/ProgressBar/index.d.ts +1 -0
  57. package/dist/components/ProgressBar/index.js +1 -0
  58. package/dist/components/Select/Select.d.ts +12 -0
  59. package/dist/components/Select/Select.js +202 -0
  60. package/dist/components/Select/index.d.ts +1 -0
  61. package/dist/components/Select/index.js +1 -0
  62. package/dist/components/Skeleton/Skeleton.d.ts +8 -0
  63. package/dist/components/Skeleton/Skeleton.js +65 -0
  64. package/dist/components/Skeleton/index.d.ts +1 -0
  65. package/dist/components/Skeleton/index.js +1 -0
  66. package/dist/components/SplitButton/SplitButton.d.ts +12 -0
  67. package/dist/components/SplitButton/SplitButton.js +90 -0
  68. package/dist/components/SplitButton/index.d.ts +1 -0
  69. package/dist/components/SplitButton/index.js +1 -0
  70. package/dist/components/Table/Table.d.ts +19 -0
  71. package/dist/components/Table/Table.js +176 -0
  72. package/dist/components/Table/index.d.ts +1 -0
  73. package/dist/components/Table/index.js +1 -0
  74. package/dist/components/Tabs/Tabs.d.ts +34 -0
  75. package/dist/components/Tabs/Tabs.js +94 -0
  76. package/dist/components/Tabs/index.d.ts +1 -0
  77. package/dist/components/Tabs/index.js +1 -0
  78. package/dist/components/Text/Text.d.ts +14 -0
  79. package/dist/components/Text/Text.js +123 -0
  80. package/dist/components/Text/index.d.ts +1 -0
  81. package/dist/components/Text/index.js +1 -0
  82. package/dist/components/Textarea/Textarea.d.ts +3 -0
  83. package/dist/components/Textarea/Textarea.js +30 -0
  84. package/dist/components/Textarea/index.d.ts +1 -0
  85. package/dist/components/Textarea/index.js +1 -0
  86. package/dist/components/Toast/Toast.d.ts +14 -0
  87. package/dist/components/Toast/Toast.js +109 -0
  88. package/dist/components/Toast/index.d.ts +1 -0
  89. package/dist/components/Toast/index.js +1 -0
  90. package/dist/fonts.d.ts +1 -0
  91. package/dist/fonts.js +6 -0
  92. package/dist/index.d.ts +24 -0
  93. package/dist/index.js +24 -0
  94. package/dist/styles/index.d.ts +3 -0
  95. package/dist/styles/index.js +3 -0
  96. package/dist/styles/reset.d.ts +1 -0
  97. package/dist/styles/reset.js +29 -0
  98. package/dist/styles/theme.d.ts +1 -0
  99. package/dist/styles/theme.js +11 -0
  100. package/dist/styles/themes/ThemeProvider.d.ts +13 -0
  101. package/dist/styles/themes/ThemeProvider.js +37 -0
  102. package/dist/styles/themes/actions.d.ts +3 -0
  103. package/dist/styles/themes/actions.js +16 -0
  104. package/dist/styles/themes/definitions.d.ts +211 -0
  105. package/dist/styles/themes/definitions.js +48 -0
  106. package/dist/styles/themes/index.d.ts +3 -0
  107. package/dist/styles/themes/index.js +3 -0
  108. package/dist/styles/utilities.d.ts +1 -0
  109. package/dist/styles/utilities.js +184 -0
  110. package/dist/tsconfig.tsbuildinfo +1 -0
  111. package/package.json +46 -0
@@ -0,0 +1,202 @@
1
+ 'use client';
2
+ var __rest = (this && this.__rest) || function (s, e) {
3
+ var t = {};
4
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
5
+ t[p] = s[p];
6
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
7
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
8
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
9
+ t[p[i]] = s[p[i]];
10
+ }
11
+ return t;
12
+ };
13
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
14
+ import { useState, useRef, useEffect, useId } from 'react';
15
+ import styled from '@emotion/styled';
16
+ import { Text, Popover } from '../..';
17
+ import { Check, ChevronDown } from 'lucide-react';
18
+ const SelectContainer = styled.div `
19
+ display: flex;
20
+ flex-direction: column;
21
+ width: 100%;
22
+ position: relative;
23
+ `;
24
+ const SelectTrigger = styled.button `
25
+ width: 100%;
26
+ background: var(--card-bg);
27
+ border: var(--border-width) solid var(--card-border);
28
+ color: var(--foreground);
29
+ padding: 0.75rem 1rem;
30
+ font-size: var(--text-base);
31
+ cursor: pointer;
32
+ box-shadow: var(--shadow-hard);
33
+ border-radius: var(--radius);
34
+ display: flex;
35
+ justify-content: space-between;
36
+ align-items: center;
37
+ font-weight: 700;
38
+ text-transform: uppercase;
39
+ letter-spacing: 0.05em;
40
+ transition: all 0.1s ease;
41
+ min-height: 42px;
42
+
43
+ &:hover {
44
+ transform: translate(-2px, -2px);
45
+ box-shadow: var(--shadow-hover);
46
+ }
47
+
48
+ &:focus {
49
+ outline: none;
50
+ transform: translate(-2px, -2px);
51
+ box-shadow: var(--shadow-hover);
52
+ border-color: var(--primary);
53
+ }
54
+
55
+ &[aria-expanded="true"] {
56
+ transform: translate(-2px, -2px);
57
+ box-shadow: var(--shadow-hover);
58
+ border-color: var(--primary);
59
+ }
60
+ `;
61
+ const OptionsList = styled.ul `
62
+ background: var(--card-bg);
63
+ border: var(--border-width) solid var(--primary);
64
+ border-radius: var(--radius);
65
+ box-shadow: var(--shadow-hover);
66
+ min-width: 200px;
67
+ max-height: 300px;
68
+ overflow-y: auto;
69
+ display: flex;
70
+ flex-direction: column;
71
+ gap: 0.25rem;
72
+ padding: 0.25rem;
73
+ margin: 0;
74
+ list-style: none;
75
+ `;
76
+ const OptionItem = styled.li `
77
+ text-align: left;
78
+ padding: 0.75rem 1rem;
79
+ background: ${props => props.isSelected ? 'var(--primary)' : (props.isHighlighted ? 'color-mix(in srgb, var(--primary), transparent 85%)' : 'transparent')};
80
+ border: none;
81
+ border-radius: calc(var(--radius) - 2px);
82
+ color: ${props => props.isSelected ? 'var(--primary-foreground)' : (props.isHighlighted ? 'var(--primary)' : 'var(--foreground)')};
83
+ cursor: pointer;
84
+ font-size: var(--text-base);
85
+ font-weight: ${props => props.isSelected ? '700' : '400'};
86
+ transition: all 0.1s ease;
87
+ width: 100%;
88
+ display: flex;
89
+ align-items: center;
90
+ justify-content: space-between;
91
+ user-select: none;
92
+
93
+ &:hover {
94
+ background-color: color-mix(in srgb, var(--primary), transparent 85%);
95
+ color: var(--primary);
96
+ }
97
+
98
+ ${props => props.isSelected && `
99
+ &:hover {
100
+ background-color: var(--primary);
101
+ color: var(--primary-foreground);
102
+ filter: brightness(1.1);
103
+ }
104
+ `}
105
+ `;
106
+ export function Select(_a) {
107
+ var _b;
108
+ var { options, className, label, style, value, defaultValue, onChange, placeholder, id, required, disabled, name, form, autoFocus } = _a, props = __rest(_a, ["options", "className", "label", "style", "value", "defaultValue", "onChange", "placeholder", "id", "required", "disabled", "name", "form", "autoFocus"]);
109
+ const [isOpen, setIsOpen] = useState(false);
110
+ const [internalValue, setInternalValue] = useState(defaultValue || '');
111
+ const [highlightedIndex, setHighlightedIndex] = useState(-1);
112
+ const reactId = useId();
113
+ const triggerRef = useRef(null);
114
+ const listboxId = id ? `${id}-listbox` : `select-listbox-${reactId}`;
115
+ const labelId = id ? `${id}-label` : `select-label-${reactId}`;
116
+ const currentValue = value !== undefined ? value : internalValue;
117
+ const selectedOption = options.find(opt => String(opt.value) === String(currentValue));
118
+ // Reset highlighted index when opening
119
+ useEffect(() => {
120
+ if (isOpen) {
121
+ const index = options.findIndex(opt => String(opt.value) === String(currentValue));
122
+ setHighlightedIndex(index >= 0 ? index : 0);
123
+ }
124
+ }, [isOpen, currentValue, options]);
125
+ const handleSelect = (newValue) => {
126
+ var _a;
127
+ if (value === undefined) {
128
+ setInternalValue(newValue);
129
+ }
130
+ if (onChange) {
131
+ const syntheticEvent = {
132
+ target: { value: newValue, name: name },
133
+ currentTarget: { value: newValue, name: name },
134
+ preventDefault: () => { },
135
+ stopPropagation: () => { },
136
+ };
137
+ onChange(syntheticEvent);
138
+ }
139
+ setIsOpen(false);
140
+ (_a = triggerRef.current) === null || _a === void 0 ? void 0 : _a.focus();
141
+ };
142
+ const handleKeyDown = (e) => {
143
+ var _a;
144
+ switch (e.key) {
145
+ case 'Enter':
146
+ case ' ':
147
+ e.preventDefault();
148
+ if (isOpen) {
149
+ if (highlightedIndex >= 0 && highlightedIndex < options.length) {
150
+ handleSelect(options[highlightedIndex].value);
151
+ }
152
+ }
153
+ else {
154
+ setIsOpen(true);
155
+ }
156
+ break;
157
+ case 'ArrowDown':
158
+ e.preventDefault();
159
+ if (!isOpen) {
160
+ setIsOpen(true);
161
+ }
162
+ else {
163
+ setHighlightedIndex(prev => (prev < options.length - 1 ? prev + 1 : 0));
164
+ }
165
+ break;
166
+ case 'ArrowUp':
167
+ e.preventDefault();
168
+ if (!isOpen) {
169
+ setIsOpen(true);
170
+ }
171
+ else {
172
+ setHighlightedIndex(prev => (prev > 0 ? prev - 1 : options.length - 1));
173
+ }
174
+ break;
175
+ case 'Escape':
176
+ if (isOpen) {
177
+ e.preventDefault();
178
+ setIsOpen(false);
179
+ (_a = triggerRef.current) === null || _a === void 0 ? void 0 : _a.focus();
180
+ }
181
+ break;
182
+ case 'Tab':
183
+ if (isOpen) {
184
+ setIsOpen(false);
185
+ }
186
+ break;
187
+ }
188
+ };
189
+ return (_jsxs(SelectContainer, { className: className, style: style, children: [label && (_jsx(Text, { as: "label", id: labelId, variant: "small", weight: "bold", color: "muted", className: "mb-1 block", htmlFor: id, children: label })), _jsx(Popover, { isOpen: isOpen, onClose: () => setIsOpen(false), placement: "bottom-start", trigger: _jsxs(SelectTrigger, Object.assign({ ref: triggerRef, type: "button", id: id, onClick: () => setIsOpen(!isOpen), onKeyDown: handleKeyDown, "aria-haspopup": "listbox", "aria-expanded": isOpen, "aria-controls": listboxId, "aria-labelledby": label ? labelId : undefined, disabled: disabled, autoFocus: autoFocus }, props, { children: [_jsx("span", { children: selectedOption ? selectedOption.label : (placeholder || 'Select...') }), _jsx(ChevronDown, { size: 16, strokeWidth: 2.5, style: { marginLeft: '0.5rem' } })] })), content: _jsx(OptionsList, { id: listboxId, role: "listbox", "aria-labelledby": label ? labelId : undefined, style: { width: (_b = triggerRef.current) === null || _b === void 0 ? void 0 : _b.offsetWidth }, children: options.map((opt, index) => {
190
+ const isSelected = String(opt.value) === String(currentValue);
191
+ const isHighlighted = index === highlightedIndex;
192
+ return (_jsxs(OptionItem, { id: `${listboxId}-option-${index}`, role: "option", "aria-selected": isSelected, isSelected: isSelected, isHighlighted: isHighlighted, onClick: () => handleSelect(opt.value), onMouseEnter: () => setHighlightedIndex(index), children: [_jsx("span", { children: opt.label }), isSelected && _jsx(Check, { size: 14, strokeWidth: 3 })] }, opt.value));
193
+ }) }) }), _jsx("input", { type: "text", name: name, value: currentValue, required: required, form: form, tabIndex: -1, readOnly: true, style: {
194
+ opacity: 0,
195
+ height: '1px',
196
+ width: '1px',
197
+ position: 'absolute',
198
+ bottom: 0,
199
+ left: 0,
200
+ pointerEvents: 'none',
201
+ } })] }));
202
+ }
@@ -0,0 +1 @@
1
+ export * from './Select';
@@ -0,0 +1 @@
1
+ export * from './Select';
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ interface SkeletonProps extends React.HTMLAttributes<HTMLDivElement> {
3
+ width?: string;
4
+ height?: string;
5
+ variant?: 'text' | 'circular' | 'rectangular';
6
+ }
7
+ export declare function Skeleton({ width, height, variant, className, style, ...props }: SkeletonProps): import("react/jsx-runtime").JSX.Element;
8
+ export {};
@@ -0,0 +1,65 @@
1
+ 'use client';
2
+ var __rest = (this && this.__rest) || function (s, e) {
3
+ var t = {};
4
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
5
+ t[p] = s[p];
6
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
7
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
8
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
9
+ t[p[i]] = s[p[i]];
10
+ }
11
+ return t;
12
+ };
13
+ import { jsx as _jsx } from "react/jsx-runtime";
14
+ import styled from '@emotion/styled';
15
+ import { keyframes } from '@emotion/react';
16
+ const shimmer = keyframes `
17
+ 0% {
18
+ background-position: -200% 0;
19
+ }
20
+ 100% {
21
+ background-position: 200% 0;
22
+ }
23
+ `;
24
+ const StyledSkeleton = styled.div `
25
+ background: linear-gradient(
26
+ 90deg,
27
+ rgba(0, 0, 0, 0.06) 25%,
28
+ rgba(0, 0, 0, 0.12) 37%,
29
+ rgba(0, 0, 0, 0.06) 63%
30
+ );
31
+ background-size: 200% 100%;
32
+ animation: ${shimmer} 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
33
+
34
+ /* Dimensions */
35
+ width: ${props => props.$width || '100%'};
36
+ height: ${props => props.$height || 'auto'};
37
+
38
+ /* Variant Styles */
39
+ ${props => {
40
+ switch (props.$variant) {
41
+ case 'circular':
42
+ return `
43
+ border-radius: 50%;
44
+ height: ${props.$height || props.$width || '3rem'};
45
+ width: ${props.$width || props.$height || '3rem'};
46
+ `;
47
+ case 'text':
48
+ return `
49
+ height: ${props.$height || '1em'};
50
+ border-radius: var(--radius);
51
+ margin-bottom: 0.5rem;
52
+ `;
53
+ case 'rectangular':
54
+ default:
55
+ return `
56
+ height: ${props.$height || '10rem'};
57
+ border-radius: var(--radius);
58
+ `;
59
+ }
60
+ }}
61
+ `;
62
+ export function Skeleton(_a) {
63
+ var { width, height, variant = 'rectangular', className, style } = _a, props = __rest(_a, ["width", "height", "variant", "className", "style"]);
64
+ return (_jsx(StyledSkeleton, Object.assign({ "$width": width, "$height": height, "$variant": variant, className: className, style: style }, props)));
65
+ }
@@ -0,0 +1 @@
1
+ export * from './Skeleton';
@@ -0,0 +1 @@
1
+ export * from './Skeleton';
@@ -0,0 +1,12 @@
1
+ interface SplitButtonItem {
2
+ label: string;
3
+ onClick: () => void;
4
+ }
5
+ interface SplitButtonProps {
6
+ primaryLabel: string;
7
+ onPrimaryClick: () => void;
8
+ items: SplitButtonItem[];
9
+ variant?: 'primary' | 'secondary';
10
+ }
11
+ export declare function SplitButton({ primaryLabel, onPrimaryClick, items, variant }: SplitButtonProps): import("react/jsx-runtime").JSX.Element;
12
+ export {};
@@ -0,0 +1,90 @@
1
+ 'use client';
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 '../..';
6
+ 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' }) {
85
+ 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: () => {
87
+ item.onClick();
88
+ setIsOpen(false);
89
+ }, children: item.label }, index))) }) }));
90
+ }
@@ -0,0 +1 @@
1
+ export * from './SplitButton';
@@ -0,0 +1 @@
1
+ export * from './SplitButton';
@@ -0,0 +1,19 @@
1
+ import React from 'react';
2
+ import { ColumnDef } from '@tanstack/react-table';
3
+ interface TableProps<T> {
4
+ data: T[];
5
+ columns: ColumnDef<T>[];
6
+ enablePagination?: boolean;
7
+ enableFiltering?: boolean;
8
+ enableSorting?: boolean;
9
+ pageSize?: number;
10
+ height?: string | number;
11
+ className?: string;
12
+ style?: React.CSSProperties;
13
+ variant?: 'default' | 'flat';
14
+ density?: 'compact' | 'standard' | 'relaxed';
15
+ toolbarContent?: React.ReactNode;
16
+ striped?: boolean;
17
+ }
18
+ export declare function Table<T>({ data, columns, enablePagination, enableFiltering, enableSorting, pageSize, height, className, style, variant, density, toolbarContent, striped, }: TableProps<T>): import("react/jsx-runtime").JSX.Element;
19
+ export {};
@@ -0,0 +1,176 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import React, { useState } from 'react';
4
+ import styled from '@emotion/styled';
5
+ import { useReactTable, getCoreRowModel, getSortedRowModel, getPaginationRowModel, getFilteredRowModel, flexRender, } from '@tanstack/react-table';
6
+ import { useVirtualizer } from '@tanstack/react-virtual';
7
+ import { Button, Input, Select, Flex, Text } from '../..';
8
+ // --- Styled Components ---
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: 1rem;
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: 1rem;
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
+ `;
102
+ export function Table({ data, columns, enablePagination = true, enableFiltering = true, enableSorting = true, pageSize = 10, height, className, style, variant = 'default', density = 'standard', toolbarContent, striped = false, }) {
103
+ const [sorting, setSorting] = useState([]);
104
+ const [globalFilter, setGlobalFilter] = useState('');
105
+ const [pagination, setPagination] = useState({
106
+ pageIndex: 0,
107
+ pageSize: pageSize,
108
+ });
109
+ const table = useReactTable({
110
+ data,
111
+ columns,
112
+ state: {
113
+ sorting,
114
+ globalFilter,
115
+ pagination,
116
+ },
117
+ enableSorting, // Pass this to useReactTable
118
+ onSortingChange: setSorting,
119
+ onGlobalFilterChange: setGlobalFilter,
120
+ onPaginationChange: setPagination,
121
+ getCoreRowModel: getCoreRowModel(),
122
+ getSortedRowModel: getSortedRowModel(), // Always provide the model, enableSorting controls if it's used
123
+ getPaginationRowModel: enablePagination ? getPaginationRowModel() : undefined,
124
+ getFilteredRowModel: enableFiltering ? getFilteredRowModel() : undefined,
125
+ });
126
+ // Virtualization Logic (Simplified for rows)
127
+ const parentRef = React.useRef(null);
128
+ const { rows } = table.getRowModel();
129
+ const rowVirtualizer = useVirtualizer({
130
+ count: rows.length,
131
+ getScrollElement: () => parentRef.current,
132
+ estimateSize: () => 50, // Estimate row height
133
+ overscan: 5,
134
+ });
135
+ 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: {
143
+ height: height ? height : 'auto',
144
+ overflowY: height ? 'auto' : 'visible',
145
+ overflowX: 'auto',
146
+ width: '100%'
147
+ }, children: [_jsxs(StyledTable, { children: [_jsx("thead", { children: table.getHeaderGroups().map((headerGroup) => (_jsx("tr", { children: headerGroup.headers.map((header) => {
148
+ var _a;
149
+ 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 = {
151
+ asc: ' ▲',
152
+ desc: ' ▼',
153
+ }[header.column.getIsSorted()]) !== null && _a !== void 0 ? _a : null)] }) }, header.id));
154
+ }) }, headerGroup.id))) }), isVirtual ? (_jsx("tbody", { style: {
155
+ height: `${rowVirtualizer.getTotalSize()}px`,
156
+ width: '100%',
157
+ position: 'relative',
158
+ }, children: rowVirtualizer.getVirtualItems().map((virtualRow) => {
159
+ const row = rows[virtualRow.index];
160
+ return (_jsx(Tr, { "$striped": striped, style: {
161
+ position: 'absolute',
162
+ top: 0,
163
+ left: 0,
164
+ width: '100%',
165
+ height: `${virtualRow.size}px`,
166
+ 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 && (_jsxs(PaginationContainer, { children: [_jsxs(Flex, { gap: "1rem", align: "center", children: [_jsxs(Text, { color: "muted", className: "min-w-fit", children: ["Page ", table.getState().pagination.pageIndex + 1, " of", ' ', table.getPageCount()] }), _jsx(Select, { value: table.getState().pagination.pageSize, onChange: (e) => {
169
+ table.setPageSize(Number(e.target.value));
170
+ }, options: [
171
+ { value: 10, label: '10 rows' },
172
+ { value: 20, label: '20 rows' },
173
+ { value: 50, label: '50 rows' },
174
+ { value: 100, label: '100 rows' },
175
+ ] })] }), _jsxs(Flex, { gap: "0.5rem", children: [_jsx(Button, { variant: "secondary", size: "sm", onClick: () => table.previousPage(), disabled: !table.getCanPreviousPage(), children: "Previous" }), _jsx(Button, { variant: "secondary", size: "sm", onClick: () => table.nextPage(), disabled: !table.getCanNextPage(), children: "Next" })] })] }))] }));
176
+ }
@@ -0,0 +1 @@
1
+ export * from './Table';
@@ -0,0 +1 @@
1
+ export * from './Table';
@@ -0,0 +1,34 @@
1
+ import React from 'react';
2
+ interface TabsProps {
3
+ defaultValue?: string;
4
+ value?: string;
5
+ onValueChange?: (value: string) => void;
6
+ children: React.ReactNode;
7
+ className?: string;
8
+ }
9
+ export declare function Tabs({ defaultValue, value, onValueChange, children, className }: TabsProps): import("react/jsx-runtime").JSX.Element;
10
+ interface TabsListProps {
11
+ children: React.ReactNode;
12
+ className?: string;
13
+ }
14
+ export declare function TabsList({ children, className }: TabsListProps): import("react/jsx-runtime").JSX.Element;
15
+ interface TabsTriggerProps {
16
+ value: string;
17
+ children: React.ReactNode;
18
+ className?: string;
19
+ onClick?: () => void;
20
+ }
21
+ export declare function TabsTrigger({ value, children, className, onClick }: TabsTriggerProps): import("react/jsx-runtime").JSX.Element;
22
+ interface TabsBodyProps {
23
+ children: React.ReactNode;
24
+ className?: string;
25
+ style?: React.CSSProperties;
26
+ }
27
+ export declare function TabsBody({ children, className, style }: TabsBodyProps): import("react/jsx-runtime").JSX.Element;
28
+ interface TabsContentProps {
29
+ value: string;
30
+ children: React.ReactNode;
31
+ className?: string;
32
+ }
33
+ export declare function TabsContent({ value, children, className }: TabsContentProps): import("react/jsx-runtime").JSX.Element | null;
34
+ export {};