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.
- package/README.md +50 -0
- package/dist/DesignSystemProvider.d.ts +7 -0
- package/dist/DesignSystemProvider.js +13 -0
- package/dist/components/ActionRow/ActionRow.d.ts +9 -0
- package/dist/components/ActionRow/ActionRow.js +47 -0
- package/dist/components/ActionRow/index.d.ts +1 -0
- package/dist/components/ActionRow/index.js +1 -0
- package/dist/components/Badge/Badge.d.ts +8 -0
- package/dist/components/Badge/Badge.js +57 -0
- package/dist/components/Badge/index.d.ts +1 -0
- package/dist/components/Badge/index.js +1 -0
- package/dist/components/Button/Button.d.ts +9 -0
- package/dist/components/Button/Button.js +110 -0
- package/dist/components/Button/index.d.ts +1 -0
- package/dist/components/Button/index.js +1 -0
- package/dist/components/Card/Card.d.ts +8 -0
- package/dist/components/Card/Card.js +28 -0
- package/dist/components/Card/index.d.ts +1 -0
- package/dist/components/Card/index.js +1 -0
- package/dist/components/Dropdown/Dropdown.d.ts +11 -0
- package/dist/components/Dropdown/Dropdown.js +47 -0
- package/dist/components/Dropdown/index.d.ts +1 -0
- package/dist/components/Dropdown/index.js +1 -0
- package/dist/components/Form/Form.d.ts +14 -0
- package/dist/components/Form/Form.js +24 -0
- package/dist/components/Form/index.d.ts +1 -0
- package/dist/components/Form/index.js +1 -0
- package/dist/components/Icon/index.d.ts +25 -0
- package/dist/components/Icon/index.js +41 -0
- package/dist/components/Input/Input.d.ts +12 -0
- package/dist/components/Input/Input.js +129 -0
- package/dist/components/Input/index.d.ts +1 -0
- package/dist/components/Input/index.js +1 -0
- package/dist/components/Layout/Layout.d.ts +17 -0
- package/dist/components/Layout/Layout.js +37 -0
- package/dist/components/Layout/index.d.ts +1 -0
- package/dist/components/Layout/index.js +1 -0
- package/dist/components/Link/Link.d.ts +11 -0
- package/dist/components/Link/Link.js +78 -0
- package/dist/components/Link/index.d.ts +1 -0
- package/dist/components/Link/index.js +1 -0
- package/dist/components/Modal/Modal.d.ts +22 -0
- package/dist/components/Modal/Modal.js +89 -0
- package/dist/components/Modal/index.d.ts +1 -0
- package/dist/components/Modal/index.js +1 -0
- package/dist/components/Page/Page.d.ts +13 -0
- package/dist/components/Page/Page.js +27 -0
- package/dist/components/Page/index.d.ts +1 -0
- package/dist/components/Page/index.js +1 -0
- package/dist/components/Popover/Popover.d.ts +11 -0
- package/dist/components/Popover/Popover.js +91 -0
- package/dist/components/Popover/index.d.ts +1 -0
- package/dist/components/Popover/index.js +1 -0
- package/dist/components/ProgressBar/ProgressBar.d.ts +12 -0
- package/dist/components/ProgressBar/ProgressBar.js +42 -0
- package/dist/components/ProgressBar/index.d.ts +1 -0
- package/dist/components/ProgressBar/index.js +1 -0
- package/dist/components/Select/Select.d.ts +12 -0
- package/dist/components/Select/Select.js +202 -0
- package/dist/components/Select/index.d.ts +1 -0
- package/dist/components/Select/index.js +1 -0
- package/dist/components/Skeleton/Skeleton.d.ts +8 -0
- package/dist/components/Skeleton/Skeleton.js +65 -0
- package/dist/components/Skeleton/index.d.ts +1 -0
- package/dist/components/Skeleton/index.js +1 -0
- package/dist/components/SplitButton/SplitButton.d.ts +12 -0
- package/dist/components/SplitButton/SplitButton.js +90 -0
- package/dist/components/SplitButton/index.d.ts +1 -0
- package/dist/components/SplitButton/index.js +1 -0
- package/dist/components/Table/Table.d.ts +19 -0
- package/dist/components/Table/Table.js +176 -0
- package/dist/components/Table/index.d.ts +1 -0
- package/dist/components/Table/index.js +1 -0
- package/dist/components/Tabs/Tabs.d.ts +34 -0
- package/dist/components/Tabs/Tabs.js +94 -0
- package/dist/components/Tabs/index.d.ts +1 -0
- package/dist/components/Tabs/index.js +1 -0
- package/dist/components/Text/Text.d.ts +14 -0
- package/dist/components/Text/Text.js +123 -0
- package/dist/components/Text/index.d.ts +1 -0
- package/dist/components/Text/index.js +1 -0
- package/dist/components/Textarea/Textarea.d.ts +3 -0
- package/dist/components/Textarea/Textarea.js +30 -0
- package/dist/components/Textarea/index.d.ts +1 -0
- package/dist/components/Textarea/index.js +1 -0
- package/dist/components/Toast/Toast.d.ts +14 -0
- package/dist/components/Toast/Toast.js +109 -0
- package/dist/components/Toast/index.d.ts +1 -0
- package/dist/components/Toast/index.js +1 -0
- package/dist/fonts.d.ts +1 -0
- package/dist/fonts.js +6 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.js +24 -0
- package/dist/styles/index.d.ts +3 -0
- package/dist/styles/index.js +3 -0
- package/dist/styles/reset.d.ts +1 -0
- package/dist/styles/reset.js +29 -0
- package/dist/styles/theme.d.ts +1 -0
- package/dist/styles/theme.js +11 -0
- package/dist/styles/themes/ThemeProvider.d.ts +13 -0
- package/dist/styles/themes/ThemeProvider.js +37 -0
- package/dist/styles/themes/actions.d.ts +3 -0
- package/dist/styles/themes/actions.js +16 -0
- package/dist/styles/themes/definitions.d.ts +211 -0
- package/dist/styles/themes/definitions.js +48 -0
- package/dist/styles/themes/index.d.ts +3 -0
- package/dist/styles/themes/index.js +3 -0
- package/dist/styles/utilities.d.ts +1 -0
- package/dist/styles/utilities.js +184 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +46 -0
|
@@ -0,0 +1,129 @@
|
|
|
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 } from 'react';
|
|
15
|
+
import styled from '@emotion/styled';
|
|
16
|
+
import { Text } from '../..';
|
|
17
|
+
const InputContainer = styled.div `
|
|
18
|
+
display: flex;
|
|
19
|
+
flex-direction: column;
|
|
20
|
+
width: 100%;
|
|
21
|
+
`;
|
|
22
|
+
const InputWrapper = styled.div `
|
|
23
|
+
position: relative;
|
|
24
|
+
display: flex;
|
|
25
|
+
align-items: center;
|
|
26
|
+
width: 100%;
|
|
27
|
+
`;
|
|
28
|
+
const StyledInput = styled.input `
|
|
29
|
+
width: 100%;
|
|
30
|
+
padding: 0.75rem 1rem;
|
|
31
|
+
padding-left: ${props => props.hasStartAdornment ? '2rem' : '1rem'};
|
|
32
|
+
padding-right: ${props => props.hasEndAdornment ? '2rem' : '1rem'};
|
|
33
|
+
font-size: var(--text-base);
|
|
34
|
+
background: var(--card-bg);
|
|
35
|
+
color: var(--foreground);
|
|
36
|
+
border: var(--border-width) solid ${props => props.isError ? 'var(--error)' : 'var(--card-border)'};
|
|
37
|
+
border-radius: var(--radius);
|
|
38
|
+
box-shadow: var(--shadow-hard);
|
|
39
|
+
outline: none;
|
|
40
|
+
transition: all 0.1s ease;
|
|
41
|
+
|
|
42
|
+
&:focus {
|
|
43
|
+
box-shadow: var(--shadow-hover);
|
|
44
|
+
transform: translate(-2px, -2px);
|
|
45
|
+
border-color: ${props => props.isError ? 'var(--error)' : 'var(--primary)'};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
&::placeholder {
|
|
49
|
+
color: var(--muted);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
&::-webkit-calendar-picker-indicator {
|
|
53
|
+
background-color: var(--muted-foreground);
|
|
54
|
+
cursor: pointer;
|
|
55
|
+
mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4' width='18' height='18' rx='2' ry='2'%3E%3C/rect%3E%3Cline x1='16' y1='2' x2='16' y2='6'%3E%3C/line%3E%3Cline x1='8' y1='2' x2='8' y2='6'%3E%3C/line%3E%3Cline x1='3' y1='10' x2='21' y2='10'%3E%3C/line%3E%3C/svg%3E");
|
|
56
|
+
-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4' width='18' height='18' rx='2' ry='2'%3E%3C/rect%3E%3Cline x1='16' y1='2' x2='16' y2='6'%3E%3C/line%3E%3Cline x1='8' y1='2' x2='8' y2='6'%3E%3C/line%3E%3Cline x1='3' y1='10' x2='21' y2='10'%3E%3C/line%3E%3C/svg%3E");
|
|
57
|
+
mask-repeat: no-repeat;
|
|
58
|
+
-webkit-mask-repeat: no-repeat;
|
|
59
|
+
mask-position: center;
|
|
60
|
+
-webkit-mask-position: center;
|
|
61
|
+
mask-size: contain;
|
|
62
|
+
-webkit-mask-size: contain;
|
|
63
|
+
transition: background-color 0.2s;
|
|
64
|
+
width: 1em;
|
|
65
|
+
height: 1em;
|
|
66
|
+
|
|
67
|
+
&:hover {
|
|
68
|
+
background-color: var(--foreground);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
&[type="time"]::-webkit-calendar-picker-indicator {
|
|
73
|
+
mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cpolyline points='12 6 12 12 16 14'%3E%3C/polyline%3E%3C/svg%3E");
|
|
74
|
+
-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cpolyline points='12 6 12 12 16 14'%3E%3C/polyline%3E%3C/svg%3E");
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
&::-webkit-search-cancel-button {
|
|
78
|
+
-webkit-appearance: none;
|
|
79
|
+
background-color: var(--muted-foreground);
|
|
80
|
+
cursor: pointer;
|
|
81
|
+
mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cline x1='18' y1='6' x2='6' y2='18'%3E%3C/line%3E%3Cline x1='6' y1='6' x2='18' y2='18'%3E%3C/line%3E%3C/svg%3E");
|
|
82
|
+
-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cline x1='18' y1='6' x2='6' y2='18'%3E%3C/line%3E%3Cline x1='6' y1='6' x2='18' y2='18'%3E%3C/line%3E%3C/svg%3E");
|
|
83
|
+
mask-repeat: no-repeat;
|
|
84
|
+
-webkit-mask-repeat: no-repeat;
|
|
85
|
+
mask-position: center;
|
|
86
|
+
-webkit-mask-position: center;
|
|
87
|
+
mask-size: contain;
|
|
88
|
+
-webkit-mask-size: contain;
|
|
89
|
+
transition: background-color 0.2s;
|
|
90
|
+
width: 1em;
|
|
91
|
+
height: 1em;
|
|
92
|
+
|
|
93
|
+
&:hover {
|
|
94
|
+
background-color: var(--foreground);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
`;
|
|
98
|
+
const Adornment = styled.span `
|
|
99
|
+
position: absolute;
|
|
100
|
+
${props => props.position === 'start' ? 'left: 0.75rem;' : 'right: 0.75rem;'}
|
|
101
|
+
color: var(--muted-foreground);
|
|
102
|
+
font-size: 0.875rem;
|
|
103
|
+
pointer-events: none;
|
|
104
|
+
z-index: 1;
|
|
105
|
+
`;
|
|
106
|
+
export function Input(_a) {
|
|
107
|
+
var { label, error: errorProp, helperText, startAdornment, endAdornment, style, className, format, validate, onBlur, onFocus, value } = _a, props = __rest(_a, ["label", "error", "helperText", "startAdornment", "endAdornment", "style", "className", "format", "validate", "onBlur", "onFocus", "value"]);
|
|
108
|
+
const [isFocused, setIsFocused] = useState(false);
|
|
109
|
+
const [internalError, setInternalError] = useState(undefined);
|
|
110
|
+
const error = errorProp || internalError;
|
|
111
|
+
const handleBlur = (e) => {
|
|
112
|
+
setIsFocused(false);
|
|
113
|
+
if (validate) {
|
|
114
|
+
setInternalError(validate(e.target.value));
|
|
115
|
+
}
|
|
116
|
+
if (onBlur)
|
|
117
|
+
onBlur(e);
|
|
118
|
+
};
|
|
119
|
+
const handleFocus = (e) => {
|
|
120
|
+
setIsFocused(true);
|
|
121
|
+
if (onFocus)
|
|
122
|
+
onFocus(e);
|
|
123
|
+
};
|
|
124
|
+
// Use formatted value when not focused, otherwise raw value
|
|
125
|
+
const displayValue = (!isFocused && format && value !== undefined)
|
|
126
|
+
? format(value)
|
|
127
|
+
: value;
|
|
128
|
+
return (_jsxs(InputContainer, { style: style, className: className, children: [label && (_jsx(Text, { as: "label", variant: "small", weight: "bold", color: "muted", className: "mb-1 block", children: label })), _jsxs(InputWrapper, { children: [startAdornment && _jsx(Adornment, { position: "start", children: startAdornment }), _jsx(StyledInput, Object.assign({}, props, { value: displayValue, hasStartAdornment: !!startAdornment, hasEndAdornment: !!endAdornment, isError: !!error, onBlur: handleBlur, onFocus: handleFocus })), endAdornment && _jsx(Adornment, { position: "end", children: endAdornment })] }), error && (_jsx(Text, { variant: "caption", color: "error", className: "mt-1", children: error })), !error && helperText && (_jsx(Text, { variant: "caption", color: "muted", className: "mt-1", children: helperText }))] }));
|
|
129
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './Input';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './Input';
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
interface GridProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
3
|
+
children: React.ReactNode;
|
|
4
|
+
columns?: string;
|
|
5
|
+
gap?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function Grid({ children, columns, gap, ...props }: GridProps): import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
interface FlexProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
9
|
+
children: React.ReactNode;
|
|
10
|
+
direction?: 'row' | 'column';
|
|
11
|
+
justify?: 'flex-start' | 'flex-end' | 'center' | 'space-between' | 'space-around';
|
|
12
|
+
align?: 'flex-start' | 'flex-end' | 'center' | 'stretch' | 'baseline';
|
|
13
|
+
gap?: string;
|
|
14
|
+
wrap?: boolean;
|
|
15
|
+
}
|
|
16
|
+
export declare function Flex({ children, direction, justify, align, gap, wrap, ...props }: FlexProps): import("react/jsx-runtime").JSX.Element;
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
'use client';
|
|
3
|
+
'use client';
|
|
4
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
5
|
+
var t = {};
|
|
6
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
7
|
+
t[p] = s[p];
|
|
8
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
9
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
10
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
11
|
+
t[p[i]] = s[p[i]];
|
|
12
|
+
}
|
|
13
|
+
return t;
|
|
14
|
+
};
|
|
15
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
16
|
+
import styled from '@emotion/styled';
|
|
17
|
+
const StyledGrid = styled.div `
|
|
18
|
+
display: grid;
|
|
19
|
+
grid-template-columns: ${props => props.columns};
|
|
20
|
+
gap: ${props => props.gap};
|
|
21
|
+
`;
|
|
22
|
+
export function Grid(_a) {
|
|
23
|
+
var { children, columns = '1fr', gap = '1rem' } = _a, props = __rest(_a, ["children", "columns", "gap"]);
|
|
24
|
+
return (_jsx(StyledGrid, Object.assign({ columns: columns, gap: gap }, props, { children: children })));
|
|
25
|
+
}
|
|
26
|
+
const StyledFlex = styled.div `
|
|
27
|
+
display: flex;
|
|
28
|
+
flex-direction: ${props => props.direction};
|
|
29
|
+
justify-content: ${props => props.justify};
|
|
30
|
+
align-items: ${props => props.align};
|
|
31
|
+
gap: ${props => props.gap};
|
|
32
|
+
flex-wrap: ${props => props.$wrap ? 'wrap' : 'nowrap'};
|
|
33
|
+
`;
|
|
34
|
+
export function Flex(_a) {
|
|
35
|
+
var { children, direction = 'row', justify = 'flex-start', align = 'stretch', gap = '0', wrap = false } = _a, props = __rest(_a, ["children", "direction", "justify", "align", "gap", "wrap"]);
|
|
36
|
+
return (_jsx(StyledFlex, Object.assign({ direction: direction, justify: justify, align: align, gap: gap, "$wrap": wrap }, props, { children: children })));
|
|
37
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './Layout';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './Layout';
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { LinkProps as NextLinkProps } from 'next/link';
|
|
3
|
+
export type LinkVariant = 'default' | 'button' | 'subtle';
|
|
4
|
+
interface LinkProps extends NextLinkProps {
|
|
5
|
+
children: React.ReactNode;
|
|
6
|
+
className?: string;
|
|
7
|
+
variant?: LinkVariant;
|
|
8
|
+
style?: React.CSSProperties;
|
|
9
|
+
}
|
|
10
|
+
export declare function Link({ children, variant, prefetch, ...props }: LinkProps): import("react/jsx-runtime").JSX.Element;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,78 @@
|
|
|
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 NextLink from 'next/link';
|
|
15
|
+
import styled from '@emotion/styled';
|
|
16
|
+
import { css } from '@emotion/react';
|
|
17
|
+
const StyledLink = styled(NextLink) `
|
|
18
|
+
display: inline-flex;
|
|
19
|
+
align-items: center;
|
|
20
|
+
justify-content: center;
|
|
21
|
+
font-weight: 700;
|
|
22
|
+
text-decoration: none;
|
|
23
|
+
transition: all 0.15s ease;
|
|
24
|
+
cursor: pointer;
|
|
25
|
+
|
|
26
|
+
/* Default Variant */
|
|
27
|
+
${props => (!props.variant || props.variant === 'default') && css `
|
|
28
|
+
color: var(--foreground);
|
|
29
|
+
border-bottom: 2px solid transparent;
|
|
30
|
+
|
|
31
|
+
&:hover {
|
|
32
|
+
color: var(--primary);
|
|
33
|
+
border-bottom-color: var(--primary);
|
|
34
|
+
transform: translateY(-1px);
|
|
35
|
+
}
|
|
36
|
+
`}
|
|
37
|
+
|
|
38
|
+
/* Subtle Variant */
|
|
39
|
+
${props => props.variant === 'subtle' && css `
|
|
40
|
+
color: var(--muted-foreground);
|
|
41
|
+
font-size: 0.875rem;
|
|
42
|
+
text-transform: uppercase;
|
|
43
|
+
letter-spacing: 0.05em;
|
|
44
|
+
|
|
45
|
+
&:hover {
|
|
46
|
+
color: var(--foreground);
|
|
47
|
+
text-decoration: underline;
|
|
48
|
+
}
|
|
49
|
+
`}
|
|
50
|
+
|
|
51
|
+
/* Button-like Variant */
|
|
52
|
+
${props => props.variant === 'button' && css `
|
|
53
|
+
background-color: var(--primary);
|
|
54
|
+
color: var(--primary-foreground);
|
|
55
|
+
border: var(--border-width) solid var(--card-border);
|
|
56
|
+
border-radius: var(--radius);
|
|
57
|
+
padding: 0.75rem 1.5rem;
|
|
58
|
+
text-transform: uppercase;
|
|
59
|
+
letter-spacing: 0.05em;
|
|
60
|
+
box-shadow: var(--shadow-hover);
|
|
61
|
+
font-size: 0.75rem;
|
|
62
|
+
|
|
63
|
+
&:hover {
|
|
64
|
+
filter: brightness(1.1);
|
|
65
|
+
transform: translate(-2px, -2px);
|
|
66
|
+
box-shadow: var(--shadow-hover);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
&:active {
|
|
70
|
+
transform: translate(0, 0);
|
|
71
|
+
box-shadow: none;
|
|
72
|
+
}
|
|
73
|
+
`}
|
|
74
|
+
`;
|
|
75
|
+
export function Link(_a) {
|
|
76
|
+
var { children, variant = 'default', prefetch } = _a, props = __rest(_a, ["children", "variant", "prefetch"]);
|
|
77
|
+
return (_jsx(StyledLink, Object.assign({ variant: variant, prefetch: prefetch }, props, { children: children })));
|
|
78
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './Link';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './Link';
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
interface ModalProps {
|
|
3
|
+
isOpen: boolean;
|
|
4
|
+
onClose: () => void;
|
|
5
|
+
title?: string;
|
|
6
|
+
children: React.ReactNode;
|
|
7
|
+
footer?: React.ReactNode;
|
|
8
|
+
}
|
|
9
|
+
export declare function ModalHeader({ children, className }: {
|
|
10
|
+
children: React.ReactNode;
|
|
11
|
+
className?: string;
|
|
12
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
13
|
+
export declare function ModalBody({ children, className }: {
|
|
14
|
+
children: React.ReactNode;
|
|
15
|
+
className?: string;
|
|
16
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
17
|
+
export declare function ModalFooter({ children, className }: {
|
|
18
|
+
children: React.ReactNode;
|
|
19
|
+
className?: string;
|
|
20
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
21
|
+
export declare function Modal({ isOpen, onClose, title, children, footer }: ModalProps): React.ReactPortal | null;
|
|
22
|
+
export {};
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import React, { useEffect, useRef } from 'react';
|
|
4
|
+
import { createPortal } from 'react-dom';
|
|
5
|
+
import { X } from 'lucide-react';
|
|
6
|
+
import styled from '@emotion/styled';
|
|
7
|
+
import { Card, Button, Flex } from '../..';
|
|
8
|
+
const ModalContext = React.createContext({ onClose: () => { } });
|
|
9
|
+
const Overlay = styled.div `
|
|
10
|
+
position: fixed;
|
|
11
|
+
inset: 0;
|
|
12
|
+
z-index: 50;
|
|
13
|
+
display: flex;
|
|
14
|
+
align-items: center;
|
|
15
|
+
justify-content: center;
|
|
16
|
+
padding: 1rem;
|
|
17
|
+
backdrop-filter: blur(4px);
|
|
18
|
+
background-color: rgba(0, 0, 0, 0.5);
|
|
19
|
+
animation: fadeIn 0.2s ease-out;
|
|
20
|
+
|
|
21
|
+
@keyframes fadeIn {
|
|
22
|
+
from { opacity: 0; }
|
|
23
|
+
to { opacity: 1; }
|
|
24
|
+
}
|
|
25
|
+
`;
|
|
26
|
+
const ContentContainer = styled.div `
|
|
27
|
+
width: 100%;
|
|
28
|
+
max-width: 28rem;
|
|
29
|
+
animation: slideUp 0.3s ease-out;
|
|
30
|
+
|
|
31
|
+
@keyframes slideUp {
|
|
32
|
+
from { transform: translateY(20px); opacity: 0; }
|
|
33
|
+
to { transform: translateY(0); opacity: 1; }
|
|
34
|
+
}
|
|
35
|
+
`;
|
|
36
|
+
const StyledHeader = styled(Flex) `
|
|
37
|
+
padding: 1.5rem;
|
|
38
|
+
border-bottom: var(--border-width) solid var(--card-border);
|
|
39
|
+
background: var(--background);
|
|
40
|
+
|
|
41
|
+
h2 {
|
|
42
|
+
font-size: 1.25rem;
|
|
43
|
+
font-weight: bold;
|
|
44
|
+
margin: 0;
|
|
45
|
+
}
|
|
46
|
+
`;
|
|
47
|
+
const StyledBody = styled.div `
|
|
48
|
+
padding: 1.5rem;
|
|
49
|
+
`;
|
|
50
|
+
const StyledFooter = styled.div `
|
|
51
|
+
padding: 1.5rem;
|
|
52
|
+
border-top: var(--border-width) solid var(--card-border);
|
|
53
|
+
background: var(--background);
|
|
54
|
+
`;
|
|
55
|
+
export function ModalHeader({ children, className }) {
|
|
56
|
+
const { onClose } = React.useContext(ModalContext);
|
|
57
|
+
return (_jsxs(StyledHeader, { justify: "space-between", align: "center", className: className, children: [_jsx("h2", { children: children }), _jsx(Button, { variant: "ghost", size: "sm", onClick: onClose, children: _jsx(X, { size: 20, strokeWidth: 2.5 }) })] }));
|
|
58
|
+
}
|
|
59
|
+
export function ModalBody({ children, className }) {
|
|
60
|
+
return (_jsx(StyledBody, { className: className, children: children }));
|
|
61
|
+
}
|
|
62
|
+
export function ModalFooter({ children, className }) {
|
|
63
|
+
return (_jsx(StyledFooter, { className: className, children: children }));
|
|
64
|
+
}
|
|
65
|
+
export function Modal({ isOpen, onClose, title, children, footer }) {
|
|
66
|
+
const overlayRef = useRef(null);
|
|
67
|
+
useEffect(() => {
|
|
68
|
+
const handleEscape = (e) => {
|
|
69
|
+
if (e.key === 'Escape')
|
|
70
|
+
onClose();
|
|
71
|
+
};
|
|
72
|
+
if (isOpen) {
|
|
73
|
+
document.addEventListener('keydown', handleEscape);
|
|
74
|
+
document.body.style.overflow = 'hidden';
|
|
75
|
+
}
|
|
76
|
+
return () => {
|
|
77
|
+
document.removeEventListener('keydown', handleEscape);
|
|
78
|
+
document.body.style.overflow = 'unset';
|
|
79
|
+
};
|
|
80
|
+
}, [isOpen, onClose]);
|
|
81
|
+
if (!isOpen)
|
|
82
|
+
return null;
|
|
83
|
+
const handleOverlayClick = (e) => {
|
|
84
|
+
if (e.target === overlayRef.current) {
|
|
85
|
+
onClose();
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
return createPortal(_jsx(ModalContext.Provider, { value: { onClose }, children: _jsx(Overlay, { ref: overlayRef, onClick: handleOverlayClick, children: _jsx(ContentContainer, { children: _jsx(Card, { style: { padding: 0, overflow: 'hidden' }, children: title ? (_jsxs(_Fragment, { children: [_jsx(ModalHeader, { children: title }), _jsx(ModalBody, { children: children }), footer && _jsx(ModalFooter, { children: footer })] })) : (children) }) }) }) }), document.body);
|
|
89
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './Modal';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './Modal';
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
interface PageProps {
|
|
3
|
+
children: React.ReactNode;
|
|
4
|
+
/**
|
|
5
|
+
* 'default': Constrained width (65vw) with standard padding.
|
|
6
|
+
* 'fullWidth': Spans the entire viewport width with no default padding.
|
|
7
|
+
*/
|
|
8
|
+
variant?: 'default' | 'fullWidth';
|
|
9
|
+
className?: string;
|
|
10
|
+
style?: React.CSSProperties;
|
|
11
|
+
}
|
|
12
|
+
export declare function Page({ children, variant, className, style }: PageProps): import("react/jsx-runtime").JSX.Element;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import styled from '@emotion/styled';
|
|
4
|
+
const PageContainer = styled.main `
|
|
5
|
+
flex: 1;
|
|
6
|
+
width: 100%;
|
|
7
|
+
|
|
8
|
+
/* Variant Styles */
|
|
9
|
+
${props => props.variant === 'default' ? `
|
|
10
|
+
width: 90%;
|
|
11
|
+
max-width: 1920px;
|
|
12
|
+
margin: 0 auto;
|
|
13
|
+
padding: 2rem 1rem;
|
|
14
|
+
|
|
15
|
+
@media (max-width: 1024px) {
|
|
16
|
+
width: 95%;
|
|
17
|
+
padding: 1rem;
|
|
18
|
+
}
|
|
19
|
+
` : `
|
|
20
|
+
max-width: 100%;
|
|
21
|
+
margin: 0;
|
|
22
|
+
padding: 0;
|
|
23
|
+
`}
|
|
24
|
+
`;
|
|
25
|
+
export function Page({ children, variant = 'default', className, style }) {
|
|
26
|
+
return (_jsx(PageContainer, { variant: variant, className: className, style: style, children: children }));
|
|
27
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './Page';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './Page';
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
interface PopoverProps {
|
|
3
|
+
trigger: React.ReactNode;
|
|
4
|
+
content: React.ReactNode;
|
|
5
|
+
isOpen: boolean;
|
|
6
|
+
onClose: () => void;
|
|
7
|
+
placement?: 'bottom-start' | 'bottom-end' | 'bottom-center';
|
|
8
|
+
offset?: number;
|
|
9
|
+
}
|
|
10
|
+
export declare function Popover({ trigger, content, isOpen, onClose, placement, offset }: PopoverProps): import("react/jsx-runtime").JSX.Element;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { useState, useRef, useEffect, useCallback } from 'react';
|
|
4
|
+
import { createPortal } from 'react-dom';
|
|
5
|
+
export function Popover({ trigger, content, isOpen, onClose, placement = 'bottom-start', offset = 8 }) {
|
|
6
|
+
const triggerRef = useRef(null);
|
|
7
|
+
const contentRef = useRef(null);
|
|
8
|
+
const [position, setPosition] = useState({ top: 0, left: 0 });
|
|
9
|
+
const [transformOrigin, setTransformOrigin] = useState('top left');
|
|
10
|
+
const updatePosition = useCallback(() => {
|
|
11
|
+
if (!isOpen || !triggerRef.current || !contentRef.current)
|
|
12
|
+
return;
|
|
13
|
+
const triggerRect = triggerRef.current.getBoundingClientRect();
|
|
14
|
+
const contentRect = contentRef.current.getBoundingClientRect();
|
|
15
|
+
const viewportWidth = window.innerWidth;
|
|
16
|
+
const viewportHeight = window.innerHeight;
|
|
17
|
+
let top = triggerRect.bottom + offset;
|
|
18
|
+
let left = triggerRect.left;
|
|
19
|
+
let origin = 'top left';
|
|
20
|
+
// Vertical positioning (flip if not enough space below)
|
|
21
|
+
if (top + contentRect.height > viewportHeight && triggerRect.top > contentRect.height) {
|
|
22
|
+
top = triggerRect.top - contentRect.height - offset;
|
|
23
|
+
origin = 'bottom';
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
origin = 'top';
|
|
27
|
+
}
|
|
28
|
+
// Horizontal positioning
|
|
29
|
+
if (placement === 'bottom-start') {
|
|
30
|
+
left = triggerRect.left;
|
|
31
|
+
}
|
|
32
|
+
else if (placement === 'bottom-end') {
|
|
33
|
+
left = triggerRect.right - contentRect.width;
|
|
34
|
+
}
|
|
35
|
+
else if (placement === 'bottom-center') {
|
|
36
|
+
left = triggerRect.left + (triggerRect.width / 2) - (contentRect.width / 2);
|
|
37
|
+
}
|
|
38
|
+
// Edge detection (keep within viewport)
|
|
39
|
+
if (left + contentRect.width > viewportWidth - 16) {
|
|
40
|
+
left = viewportWidth - contentRect.width - 16; // 16px padding from right edge
|
|
41
|
+
if (origin.includes('left'))
|
|
42
|
+
origin = origin.replace('left', 'right');
|
|
43
|
+
}
|
|
44
|
+
if (left < 16) {
|
|
45
|
+
left = 16; // 16px padding from left edge
|
|
46
|
+
if (origin.includes('right'))
|
|
47
|
+
origin = origin.replace('right', 'left');
|
|
48
|
+
}
|
|
49
|
+
setPosition({ top, left });
|
|
50
|
+
setTransformOrigin(origin);
|
|
51
|
+
}, [isOpen, placement, offset]);
|
|
52
|
+
useEffect(() => {
|
|
53
|
+
if (isOpen) {
|
|
54
|
+
updatePosition();
|
|
55
|
+
window.addEventListener('resize', updatePosition);
|
|
56
|
+
window.addEventListener('scroll', updatePosition, true);
|
|
57
|
+
}
|
|
58
|
+
return () => {
|
|
59
|
+
window.removeEventListener('resize', updatePosition);
|
|
60
|
+
window.removeEventListener('scroll', updatePosition, true);
|
|
61
|
+
};
|
|
62
|
+
}, [isOpen, updatePosition]);
|
|
63
|
+
// Handle click outside
|
|
64
|
+
useEffect(() => {
|
|
65
|
+
if (!isOpen)
|
|
66
|
+
return;
|
|
67
|
+
function handleClickOutside(event) {
|
|
68
|
+
if (triggerRef.current &&
|
|
69
|
+
!triggerRef.current.contains(event.target) &&
|
|
70
|
+
contentRef.current &&
|
|
71
|
+
!contentRef.current.contains(event.target)) {
|
|
72
|
+
onClose();
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
document.addEventListener('mousedown', handleClickOutside);
|
|
76
|
+
return () => document.removeEventListener('mousedown', handleClickOutside);
|
|
77
|
+
}, [isOpen, onClose]);
|
|
78
|
+
return (_jsxs(_Fragment, { children: [_jsx("div", { ref: triggerRef, style: { display: 'inline-block' }, children: trigger }), isOpen && typeof document !== 'undefined' && createPortal(_jsxs("div", { ref: contentRef, style: {
|
|
79
|
+
position: 'fixed',
|
|
80
|
+
top: position.top,
|
|
81
|
+
left: position.left,
|
|
82
|
+
zIndex: 9999, // High z-index to ensure it's on top
|
|
83
|
+
transformOrigin: transformOrigin,
|
|
84
|
+
animation: 'popoverScale 0.1s ease-out',
|
|
85
|
+
}, children: [content, _jsx("style", { jsx: true, global: true, children: `
|
|
86
|
+
@keyframes popoverScale {
|
|
87
|
+
from { opacity: 0; transform: scale(0.95); }
|
|
88
|
+
to { opacity: 1; transform: scale(1); }
|
|
89
|
+
}
|
|
90
|
+
` })] }), document.body)] }));
|
|
91
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './Popover';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './Popover';
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
interface ProgressBarProps {
|
|
3
|
+
value: number;
|
|
4
|
+
max?: number;
|
|
5
|
+
height?: string | number;
|
|
6
|
+
color?: string;
|
|
7
|
+
showStripes?: boolean;
|
|
8
|
+
className?: string;
|
|
9
|
+
style?: React.CSSProperties;
|
|
10
|
+
}
|
|
11
|
+
export declare function ProgressBar({ value, max, height, color, showStripes, className, style }: ProgressBarProps): import("react/jsx-runtime").JSX.Element;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import styled from '@emotion/styled';
|
|
4
|
+
const StyledContainer = styled.div `
|
|
5
|
+
height: ${props => typeof props.height === 'number' ? `${props.height}px` : props.height};
|
|
6
|
+
width: 100%;
|
|
7
|
+
background: var(--card-bg);
|
|
8
|
+
border-radius: var(--radius);
|
|
9
|
+
overflow: hidden;
|
|
10
|
+
border: var(--border-width) solid var(--card-border);
|
|
11
|
+
position: relative;
|
|
12
|
+
`;
|
|
13
|
+
const StyledFill = styled.div `
|
|
14
|
+
height: 100%;
|
|
15
|
+
width: ${props => props.percentage}%;
|
|
16
|
+
background: ${props => props.color};
|
|
17
|
+
border-right: ${props => props.percentage < 100 ? `var(--border-width) solid var(--card-border)` : 'none'};
|
|
18
|
+
transition: width 0.5s ease-out;
|
|
19
|
+
`;
|
|
20
|
+
const StyledStripes = styled.div `
|
|
21
|
+
position: absolute;
|
|
22
|
+
top: 0;
|
|
23
|
+
left: 0;
|
|
24
|
+
right: 0;
|
|
25
|
+
bottom: 0;
|
|
26
|
+
background-image: linear-gradient(
|
|
27
|
+
45deg,
|
|
28
|
+
rgba(0, 0, 0, 0.05) 25%,
|
|
29
|
+
transparent 25%,
|
|
30
|
+
transparent 50%,
|
|
31
|
+
rgba(0, 0, 0, 0.05) 50%,
|
|
32
|
+
rgba(0, 0, 0, 0.05) 75%,
|
|
33
|
+
transparent 75%,
|
|
34
|
+
transparent
|
|
35
|
+
);
|
|
36
|
+
background-size: 20px 20px;
|
|
37
|
+
pointer-events: none;
|
|
38
|
+
`;
|
|
39
|
+
export function ProgressBar({ value, max = 100, height = '24px', color = 'var(--primary)', showStripes = true, className, style }) {
|
|
40
|
+
const percentage = Math.min(Math.max((value / max) * 100, 0), 100);
|
|
41
|
+
return (_jsxs(StyledContainer, { height: height, className: className, style: style, children: [_jsx(StyledFill, { percentage: percentage, color: color }), showStripes && _jsx(StyledStripes, {})] }));
|
|
42
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './ProgressBar';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './ProgressBar';
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
interface SelectProps extends Omit<React.SelectHTMLAttributes<HTMLSelectElement>, 'onChange'> {
|
|
3
|
+
options: {
|
|
4
|
+
value: string | number;
|
|
5
|
+
label: string;
|
|
6
|
+
}[];
|
|
7
|
+
label?: string;
|
|
8
|
+
onChange?: (e: React.ChangeEvent<HTMLSelectElement>) => void;
|
|
9
|
+
placeholder?: string;
|
|
10
|
+
}
|
|
11
|
+
export declare function Select({ options, className, label, style, value, defaultValue, onChange, placeholder, id, required, disabled, name, form, autoFocus, ...props }: SelectProps): import("react/jsx-runtime").JSX.Element;
|
|
12
|
+
export {};
|