doom-design-system 0.1.6 → 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -20
- package/dist/DesignSystemProvider.d.ts +1 -0
- package/dist/DesignSystemProvider.js +3 -4
- package/dist/components/Accordion/Accordion.js +5 -63
- package/dist/components/Accordion/Accordion.module.css +69 -0
- package/dist/components/ActionRow/ActionRow.js +3 -28
- package/dist/components/ActionRow/ActionRow.module.css +24 -0
- package/dist/components/Alert/Alert.js +3 -58
- package/dist/components/Alert/Alert.module.css +77 -0
- package/dist/components/Avatar/Avatar.js +3 -45
- package/dist/components/Avatar/Avatar.module.css +67 -0
- package/dist/components/Badge/Badge.d.ts +1 -1
- package/dist/components/Badge/Badge.js +4 -42
- package/dist/components/Badge/Badge.module.css +31 -0
- package/dist/components/Breadcrumbs/Breadcrumbs.js +6 -38
- package/dist/components/Breadcrumbs/Breadcrumbs.module.css +34 -0
- package/dist/components/Button/Button.d.ts +1 -1
- package/dist/components/Button/Button.js +5 -129
- package/dist/components/Button/Button.module.css +112 -0
- package/dist/components/Card/Card.d.ts +1 -1
- package/dist/components/Card/Card.js +4 -13
- package/dist/components/Card/Card.module.css +8 -0
- package/dist/components/Drawer/Drawer.js +5 -71
- package/dist/components/Drawer/Drawer.module.css +75 -0
- package/dist/components/Dropdown/Dropdown.d.ts +2 -1
- package/dist/components/Dropdown/Dropdown.js +6 -39
- package/dist/components/Dropdown/Dropdown.module.css +33 -0
- package/dist/components/Form/Form.d.ts +4 -9
- package/dist/components/Form/Form.js +9 -43
- package/dist/components/Form/Form.module.css +41 -0
- package/dist/components/Input/Input.js +3 -59
- package/dist/components/Input/Input.module.css +86 -0
- package/dist/components/Label/Label.d.ts +1 -1
- package/dist/components/Label/Label.js +4 -23
- package/dist/components/Label/Label.module.css +16 -0
- package/dist/components/Layout/Layout.d.ts +2 -2
- package/dist/components/Layout/Layout.js +5 -20
- package/dist/components/Layout/Layout.module.css +7 -0
- package/dist/components/Link/Link.d.ts +2 -1
- package/dist/components/Link/Link.js +4 -62
- package/dist/components/Link/Link.module.css +48 -0
- package/dist/components/Modal/Modal.js +9 -52
- package/dist/components/Modal/Modal.module.css +57 -0
- package/dist/components/Page/Page.js +3 -23
- package/dist/components/Page/Page.module.css +23 -0
- package/dist/components/Pagination/Pagination.js +4 -42
- package/dist/components/Pagination/Pagination.module.css +43 -0
- package/dist/components/Popover/Popover.js +21 -26
- package/dist/components/Popover/Popover.module.css +19 -0
- package/dist/components/ProgressBar/ProgressBar.js +7 -37
- package/dist/components/ProgressBar/ProgressBar.module.css +31 -0
- package/dist/components/RadioGroup/RadioGroup.js +4 -79
- package/dist/components/RadioGroup/RadioGroup.module.css +81 -0
- package/dist/components/Select/Select.js +6 -80
- package/dist/components/Select/Select.module.css +89 -0
- package/dist/components/Sheet/Sheet.js +5 -56
- package/dist/components/Sheet/Sheet.module.css +64 -0
- package/dist/components/Skeleton/Skeleton.js +4 -49
- package/dist/components/Skeleton/Skeleton.module.css +29 -0
- package/dist/components/Slider/Slider.js +3 -140
- package/dist/components/Slider/Slider.module.css +130 -0
- package/dist/components/SplitButton/SplitButton.d.ts +2 -1
- package/dist/components/SplitButton/SplitButton.js +6 -82
- package/dist/components/SplitButton/SplitButton.module.css +79 -0
- package/dist/components/Switch/Switch.js +3 -54
- package/dist/components/Switch/Switch.module.css +64 -0
- package/dist/components/Table/Table.d.ts +1 -1
- package/dist/components/Table/Table.js +13 -109
- package/dist/components/Table/Table.module.css +111 -0
- package/dist/components/Tabs/Tabs.js +7 -56
- package/dist/components/Tabs/Tabs.module.css +65 -0
- package/dist/components/Text/Text.js +4 -106
- package/dist/components/Text/Text.module.css +123 -0
- package/dist/components/Textarea/Textarea.d.ts +1 -1
- package/dist/components/Textarea/Textarea.js +16 -20
- package/dist/components/Textarea/Textarea.module.css +23 -0
- package/dist/components/Toast/Toast.js +3 -67
- package/dist/components/Toast/Toast.module.css +87 -0
- package/dist/components/Tooltip/Tooltip.js +3 -19
- package/dist/components/Tooltip/Tooltip.module.css +17 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/styles/globals.css +999 -0
- package/dist/styles/themes/ThemeProvider.js +4 -9
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +8 -5
- package/dist/styles/index.d.ts +0 -3
- package/dist/styles/index.js +0 -3
- package/dist/styles/mixins.d.ts +0 -3
- package/dist/styles/mixins.js +0 -25
- package/dist/styles/reset.d.ts +0 -1
- package/dist/styles/reset.js +0 -29
- package/dist/styles/theme.d.ts +0 -1
- package/dist/styles/theme.js +0 -11
- package/dist/styles/utilities.d.ts +0 -1
- package/dist/styles/utilities.js +0 -184
package/README.md
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
# Doom Design System
|
|
2
2
|
|
|
3
|
-
A modern, premium, neubrutalist and comic book inspired design system built with React and
|
|
3
|
+
A modern, premium, neubrutalist and comic book inspired design system built with React and SASS Modules.
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
7
|
- 🎨 **Distinctive Aesthetic**: Bold, high-contrast, and playful design.
|
|
8
|
-
-
|
|
9
|
-
-
|
|
8
|
+
- 🚀 **Server Components Ready**: Fully compatible with Next.js App Router and React Server Components (RSC) with zero-runtime CSS.
|
|
9
|
+
- 🧩 **Framework Agnostic**: Works with any React framework (Next.js, Vite, Remix).
|
|
10
|
+
- 🌙 **Theming**: Built-in dark mode and theming support via CSS Variables.
|
|
10
11
|
- ♿ **Accessible**: Built with accessibility in mind.
|
|
11
12
|
- 📦 **TypeScript**: Fully typed for excellent developer experience.
|
|
12
13
|
|
|
@@ -20,36 +21,39 @@ npm install doom-design-system
|
|
|
20
21
|
|
|
21
22
|
### 2. Install Peer Dependencies
|
|
22
23
|
|
|
23
|
-
This library
|
|
24
|
+
This library requires just `react` and `lucide-react`.
|
|
24
25
|
|
|
25
26
|
```bash
|
|
26
|
-
npm install
|
|
27
|
+
npm install lucide-react
|
|
27
28
|
```
|
|
28
29
|
|
|
29
30
|
## Usage
|
|
30
31
|
|
|
31
32
|
### 1. Setup Provider
|
|
32
33
|
|
|
33
|
-
Wrap your application with the `DesignSystemProvider` to ensure all styles and themes are applied correctly.
|
|
34
|
+
Wrap your application with the `DesignSystemProvider` to ensure all styles and themes are applied correctly. It injects the necessary global CSS and theme variables.
|
|
34
35
|
|
|
35
36
|
```tsx
|
|
36
37
|
import { DesignSystemProvider } from 'doom-design-system';
|
|
37
38
|
import { Montserrat } from 'next/font/google';
|
|
38
39
|
|
|
40
|
+
// Optional: Use a custom google font
|
|
39
41
|
const montserrat = Montserrat({ subsets: ['latin'] });
|
|
40
42
|
|
|
41
|
-
export default function
|
|
43
|
+
export default function RootLayout({ children }) {
|
|
42
44
|
return (
|
|
43
|
-
<
|
|
44
|
-
<
|
|
45
|
-
|
|
45
|
+
<html lang="en">
|
|
46
|
+
<DesignSystemProvider withBody fontClassName={montserrat.className}>
|
|
47
|
+
{children}
|
|
48
|
+
</DesignSystemProvider>
|
|
49
|
+
</html>
|
|
46
50
|
);
|
|
47
51
|
}
|
|
48
52
|
```
|
|
49
53
|
|
|
50
54
|
### 2. Use Components
|
|
51
55
|
|
|
52
|
-
Import and use components in your application
|
|
56
|
+
Import and use components in your application. They are now fully tree-shakeable and lightweight.
|
|
53
57
|
|
|
54
58
|
```tsx
|
|
55
59
|
import { Button, Card, Text, Link } from 'doom-design-system';
|
|
@@ -71,14 +75,11 @@ function MyComponent() {
|
|
|
71
75
|
|
|
72
76
|
### 3. Theming
|
|
73
77
|
|
|
74
|
-
You can control the theme using the `DesignSystemProvider
|
|
78
|
+
The Design System uses CSS Variables for theming. You can control the theme using the `DesignSystemProvider`.
|
|
75
79
|
|
|
76
80
|
```tsx
|
|
77
|
-
<DesignSystemProvider
|
|
78
|
-
|
|
79
|
-
onThemeChange={(theme) => console.log(`Theme changed to ${theme}`)}
|
|
80
|
-
>
|
|
81
|
-
{/* ... */}
|
|
81
|
+
<DesignSystemProvider initialTheme="doom" >
|
|
82
|
+
{/* The entire app will be themed automatically */}
|
|
82
83
|
</DesignSystemProvider>
|
|
83
84
|
```
|
|
84
85
|
|
|
@@ -87,6 +88,8 @@ You can control the theme using the `DesignSystemProvider` or the `useTheme` hoo
|
|
|
87
88
|
This library requires the following peer dependencies:
|
|
88
89
|
|
|
89
90
|
- React >= 19
|
|
90
|
-
-
|
|
91
|
-
|
|
92
|
-
|
|
91
|
+
- lucide-react (for icons)
|
|
92
|
+
|
|
93
|
+
## Architecture
|
|
94
|
+
|
|
95
|
+
This system uses **CSS Modules** (`.module.scss`) for component styling, ensuring styles are locally scoped and avoid collisions. It uses **SASS** for mixins and shared logic at build time. All styles are compiled to standard CSS during the build, making it extremely fast and lightweight.
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { jsx as _jsx
|
|
3
|
-
import
|
|
4
|
-
import { resetStyles, utilityStyles } from './styles';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import './styles/globals.css';
|
|
5
4
|
import { ThemeProvider } from './styles/themes';
|
|
6
5
|
export function DesignSystemProvider({ children, initialTheme = 'default', withBody = false, className = '', fontClassName = '' }) {
|
|
7
|
-
const content = (
|
|
6
|
+
const content = (_jsx(ThemeProvider, { initialTheme: initialTheme, children: children }));
|
|
8
7
|
const combinedClassName = `${fontClassName} ${className}`.trim();
|
|
9
8
|
if (withBody) {
|
|
10
9
|
return (_jsx("body", { className: combinedClassName, children: content }));
|
|
@@ -1,69 +1,11 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import
|
|
4
|
-
import styled from '@emotion/styled';
|
|
3
|
+
import clsx from 'clsx';
|
|
5
4
|
import { ChevronDown } from 'lucide-react';
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
flex-direction: column;
|
|
9
|
-
border: var(--border-width) solid var(--card-border);
|
|
10
|
-
border-radius: var(--radius);
|
|
11
|
-
background-color: var(--card-bg);
|
|
12
|
-
overflow: hidden;
|
|
13
|
-
`;
|
|
14
|
-
const Item = styled.div `
|
|
15
|
-
border-bottom: var(--border-width) solid var(--card-border);
|
|
16
|
-
&:last-child {
|
|
17
|
-
border-bottom: none;
|
|
18
|
-
}
|
|
19
|
-
`;
|
|
20
|
-
const Header = styled.h3 `
|
|
21
|
-
display: flex;
|
|
22
|
-
margin: 0;
|
|
23
|
-
`;
|
|
24
|
-
const Trigger = styled.button `
|
|
25
|
-
all: unset;
|
|
26
|
-
flex: 1;
|
|
27
|
-
display: flex;
|
|
28
|
-
align-items: center;
|
|
29
|
-
justify-content: space-between;
|
|
30
|
-
padding: var(--spacing-md);
|
|
31
|
-
font-family: var(--font-heading);
|
|
32
|
-
font-weight: 700;
|
|
33
|
-
font-size: var(--text-base);
|
|
34
|
-
background-color: var(--card-bg);
|
|
35
|
-
color: var(--foreground);
|
|
36
|
-
cursor: pointer;
|
|
37
|
-
transition: background-color 0.2s ease;
|
|
38
|
-
|
|
39
|
-
&:hover {
|
|
40
|
-
background-color: color-mix(in srgb, var(--primary) 25%, transparent);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
&:focus-visible {
|
|
44
|
-
outline: 2px solid var(--primary);
|
|
45
|
-
z-index: 1;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
& > svg {
|
|
49
|
-
transition: transform 0.2s ease;
|
|
50
|
-
transform: ${props => props.isOpen ? 'rotate(180deg)' : 'rotate(0deg)'};
|
|
51
|
-
}
|
|
52
|
-
`;
|
|
53
|
-
const ContentWrapper = styled.div `
|
|
54
|
-
height: ${props => props.isOpen ? 'auto' : '0'};
|
|
55
|
-
overflow: hidden;
|
|
56
|
-
display: ${props => props.isOpen ? 'block' : 'none'};
|
|
57
|
-
`;
|
|
58
|
-
const ContentBody = styled.div `
|
|
59
|
-
padding: var(--spacing-md);
|
|
60
|
-
padding-top: 0;
|
|
61
|
-
font-size: var(--text-base);
|
|
62
|
-
color: var(--muted-foreground);
|
|
63
|
-
line-height: 1.6;
|
|
64
|
-
`;
|
|
5
|
+
import styles from './Accordion.module.css';
|
|
6
|
+
import React, { useState } from 'react';
|
|
65
7
|
export function AccordionItem({ value, trigger, children, isOpen, onToggle }) {
|
|
66
|
-
return (_jsxs(
|
|
8
|
+
return (_jsxs("div", { className: styles.item, children: [_jsx("h3", { className: styles.header, children: _jsxs("button", { className: styles.trigger, type: "button", onClick: onToggle, "aria-expanded": isOpen, children: [trigger, _jsx(ChevronDown, { size: 20, strokeWidth: 2.5, className: styles.icon })] }) }), _jsx("div", { className: styles.contentWrapper, "aria-hidden": !isOpen, role: "region", children: _jsx("div", { className: styles.contentBody, children: children }) })] }));
|
|
67
9
|
}
|
|
68
10
|
export function Accordion({ type = 'single', children, defaultValue, className }) {
|
|
69
11
|
const [value, setValue] = useState(defaultValue || (type === 'multiple' ? [] : ''));
|
|
@@ -81,7 +23,7 @@ export function Accordion({ type = 'single', children, defaultValue, className }
|
|
|
81
23
|
});
|
|
82
24
|
}
|
|
83
25
|
};
|
|
84
|
-
return (_jsx(
|
|
26
|
+
return (_jsx("div", { className: clsx(styles.root, className), children: React.Children.map(children, (child) => {
|
|
85
27
|
if (!React.isValidElement(child))
|
|
86
28
|
return null;
|
|
87
29
|
const itemValue = child.props.value;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
.root {
|
|
2
|
+
display: flex;
|
|
3
|
+
flex-direction: column;
|
|
4
|
+
border: var(--border-width) solid var(--card-border);
|
|
5
|
+
border-radius: var(--radius);
|
|
6
|
+
background-color: var(--card-bg);
|
|
7
|
+
overflow: hidden;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.item {
|
|
11
|
+
border-bottom: var(--border-width) solid var(--card-border);
|
|
12
|
+
}
|
|
13
|
+
.item:last-child {
|
|
14
|
+
border-bottom: none;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.header {
|
|
18
|
+
display: flex;
|
|
19
|
+
margin: 0;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.trigger {
|
|
23
|
+
all: unset;
|
|
24
|
+
flex: 1;
|
|
25
|
+
display: flex;
|
|
26
|
+
align-items: center;
|
|
27
|
+
justify-content: space-between;
|
|
28
|
+
padding: var(--spacing-md);
|
|
29
|
+
font-family: var(--font-heading);
|
|
30
|
+
font-weight: 700;
|
|
31
|
+
font-size: var(--text-base);
|
|
32
|
+
background-color: var(--card-bg);
|
|
33
|
+
color: var(--foreground);
|
|
34
|
+
cursor: pointer;
|
|
35
|
+
transition: background-color 0.2s ease;
|
|
36
|
+
}
|
|
37
|
+
.trigger:hover {
|
|
38
|
+
background-color: color-mix(in srgb, var(--primary) 25%, transparent);
|
|
39
|
+
}
|
|
40
|
+
.trigger:focus-visible {
|
|
41
|
+
outline: 2px solid var(--primary);
|
|
42
|
+
position: relative;
|
|
43
|
+
z-index: 1;
|
|
44
|
+
}
|
|
45
|
+
.trigger .icon {
|
|
46
|
+
transition: transform 0.2s ease;
|
|
47
|
+
transform: rotate(0deg);
|
|
48
|
+
}
|
|
49
|
+
.trigger[aria-expanded=true] .icon {
|
|
50
|
+
transform: rotate(180deg);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.contentWrapper {
|
|
54
|
+
height: 0;
|
|
55
|
+
overflow: hidden;
|
|
56
|
+
display: none;
|
|
57
|
+
}
|
|
58
|
+
.contentWrapper[aria-hidden=false] {
|
|
59
|
+
height: auto;
|
|
60
|
+
display: block;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.contentBody {
|
|
64
|
+
padding: var(--spacing-md);
|
|
65
|
+
padding-top: 0;
|
|
66
|
+
font-size: var(--text-base);
|
|
67
|
+
color: var(--muted-foreground);
|
|
68
|
+
line-height: 1.6;
|
|
69
|
+
}
|
|
@@ -11,37 +11,12 @@ 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 styled from '@emotion/styled';
|
|
15
14
|
import { Text } from '../Text/Text';
|
|
16
15
|
import { Flex } from '../Layout/Layout';
|
|
17
16
|
import { ChevronRight } from 'lucide-react';
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
padding: 1.5rem;
|
|
21
|
-
cursor: pointer;
|
|
22
|
-
transition: background-color 0.2s ease;
|
|
23
|
-
border-bottom: var(--border-width) solid var(--card-border);
|
|
24
|
-
|
|
25
|
-
&:last-child {
|
|
26
|
-
border-bottom: none;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
&:hover {
|
|
30
|
-
background-color: rgba(var(--muted-rgb, 113, 128, 150), 0.1);
|
|
31
|
-
}
|
|
32
|
-
`;
|
|
33
|
-
const IconWrapper = styled.div `
|
|
34
|
-
width: 48px;
|
|
35
|
-
height: 48px;
|
|
36
|
-
background: var(--primary);
|
|
37
|
-
color: var(--primary-foreground);
|
|
38
|
-
display: flex;
|
|
39
|
-
align-items: center;
|
|
40
|
-
justify-content: center;
|
|
41
|
-
border-radius: var(--radius);
|
|
42
|
-
flex-shrink: 0;
|
|
43
|
-
`;
|
|
17
|
+
import clsx from 'clsx';
|
|
18
|
+
import styles from './ActionRow.module.css';
|
|
44
19
|
export function ActionRow(_a) {
|
|
45
20
|
var { icon, title, description, onClick, className } = _a, props = __rest(_a, ["icon", "title", "description", "onClick", "className"]);
|
|
46
|
-
return (_jsxs(
|
|
21
|
+
return (_jsxs(Flex, Object.assign({ align: "center", gap: "1.5rem", onClick: onClick, className: clsx(styles.actionRow, className) }, props, { children: [_jsx("div", { className: styles.iconWrapper, children: icon }), _jsxs(Flex, { direction: "column", gap: "0.25rem", style: { flex: 1 }, children: [_jsx(Text, { variant: "h6", weight: "bold", children: title }), description && (_jsx(Text, { color: "muted", variant: "small", children: description }))] }), _jsx(ChevronRight, { size: 20, strokeWidth: 2.5, style: { color: 'var(--muted-foreground)' } })] })));
|
|
47
22
|
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
.actionRow {
|
|
2
|
+
padding: 1.5rem;
|
|
3
|
+
cursor: pointer;
|
|
4
|
+
transition: background-color 0.2s ease;
|
|
5
|
+
border-bottom: var(--border-width) solid var(--card-border);
|
|
6
|
+
}
|
|
7
|
+
.actionRow:last-child {
|
|
8
|
+
border-bottom: none;
|
|
9
|
+
}
|
|
10
|
+
.actionRow:hover {
|
|
11
|
+
background-color: rgba(var(--muted-rgb, 113, 128, 150), 0.1);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.iconWrapper {
|
|
15
|
+
width: 48px;
|
|
16
|
+
height: 48px;
|
|
17
|
+
background: var(--primary);
|
|
18
|
+
color: var(--primary-foreground);
|
|
19
|
+
display: flex;
|
|
20
|
+
align-items: center;
|
|
21
|
+
justify-content: center;
|
|
22
|
+
border-radius: var(--radius);
|
|
23
|
+
flex-shrink: 0;
|
|
24
|
+
}
|
|
@@ -1,63 +1,8 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import
|
|
4
|
-
import { css } from '@emotion/react';
|
|
3
|
+
import clsx from 'clsx';
|
|
5
4
|
import { AlertCircle, CheckCircle, Info, XCircle } from 'lucide-react';
|
|
6
|
-
|
|
7
|
-
display: flex;
|
|
8
|
-
align-items: flex-start;
|
|
9
|
-
gap: 0.75rem;
|
|
10
|
-
padding: var(--spacing-md);
|
|
11
|
-
width: 100%;
|
|
12
|
-
border: var(--border-width) solid var(--card-border);
|
|
13
|
-
border-radius: var(--radius);
|
|
14
|
-
background-color: var(--card-bg);
|
|
15
|
-
box-shadow: var(--shadow-sm); /* Subtle depth, not full hard shadow usually */
|
|
16
|
-
position: relative;
|
|
17
|
-
overflow: hidden;
|
|
18
|
-
|
|
19
|
-
/* Left accent border */
|
|
20
|
-
&::before {
|
|
21
|
-
content: '';
|
|
22
|
-
position: absolute;
|
|
23
|
-
top: 0;
|
|
24
|
-
left: 0;
|
|
25
|
-
bottom: 0;
|
|
26
|
-
width: 6px;
|
|
27
|
-
background-color: ${props => `var(--${props.variant})`};
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
${props => props.variant === 'info' && css `
|
|
31
|
-
/* Info Styles */
|
|
32
|
-
`}
|
|
33
|
-
`;
|
|
34
|
-
const Content = styled.div `
|
|
35
|
-
display: flex;
|
|
36
|
-
flex-direction: column;
|
|
37
|
-
gap: 0.25rem;
|
|
38
|
-
flex: 1;
|
|
39
|
-
`;
|
|
40
|
-
const Title = styled.h5 `
|
|
41
|
-
margin: 0;
|
|
42
|
-
font-family: var(--font-heading);
|
|
43
|
-
font-weight: 700;
|
|
44
|
-
font-size: var(--text-base);
|
|
45
|
-
color: var(--foreground);
|
|
46
|
-
text-transform: uppercase;
|
|
47
|
-
letter-spacing: 0.05em;
|
|
48
|
-
`;
|
|
49
|
-
const Description = styled.p `
|
|
50
|
-
margin: 0;
|
|
51
|
-
font-size: var(--text-sm);
|
|
52
|
-
color: var(--muted-foreground);
|
|
53
|
-
line-height: 1.5;
|
|
54
|
-
`;
|
|
55
|
-
const IconWrapper = styled.div `
|
|
56
|
-
color: ${props => `var(--${props.variant})`};
|
|
57
|
-
display: flex;
|
|
58
|
-
align-items: center;
|
|
59
|
-
flex-shrink: 0;
|
|
60
|
-
`;
|
|
5
|
+
import styles from './Alert.module.css';
|
|
61
6
|
const icons = {
|
|
62
7
|
info: Info,
|
|
63
8
|
success: CheckCircle,
|
|
@@ -66,5 +11,5 @@ const icons = {
|
|
|
66
11
|
};
|
|
67
12
|
export function Alert({ variant = 'info', title, description, icon, className }) {
|
|
68
13
|
const IconComponent = icons[variant];
|
|
69
|
-
return (_jsxs(
|
|
14
|
+
return (_jsxs("div", { className: clsx(styles.alert, styles[variant], className), role: "alert", children: [_jsx("div", { className: clsx(styles.iconWrapper, styles[variant]), children: icon || _jsx(IconComponent, { size: 20, strokeWidth: 2.5 }) }), _jsxs("div", { className: styles.content, children: [_jsx("h5", { className: styles.title, children: title }), description && _jsx("p", { className: styles.description, children: description })] })] }));
|
|
70
15
|
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
.alert {
|
|
2
|
+
display: flex;
|
|
3
|
+
align-items: flex-start;
|
|
4
|
+
gap: 0.75rem;
|
|
5
|
+
padding: var(--spacing-md);
|
|
6
|
+
width: 100%;
|
|
7
|
+
border: var(--border-width) solid var(--card-border);
|
|
8
|
+
border-radius: var(--radius);
|
|
9
|
+
background-color: var(--card-bg);
|
|
10
|
+
box-shadow: var(--shadow-sm); /* Subtle depth, not full hard shadow usually */
|
|
11
|
+
position: relative;
|
|
12
|
+
overflow: hidden;
|
|
13
|
+
/* Left accent border */
|
|
14
|
+
}
|
|
15
|
+
.alert::before {
|
|
16
|
+
content: "";
|
|
17
|
+
position: absolute;
|
|
18
|
+
top: 0;
|
|
19
|
+
left: 0;
|
|
20
|
+
bottom: 0;
|
|
21
|
+
width: 6px;
|
|
22
|
+
background-color: var(--primary); /* Default fallback */
|
|
23
|
+
}
|
|
24
|
+
.alert.info::before {
|
|
25
|
+
background-color: var(--info, var(--primary));
|
|
26
|
+
}
|
|
27
|
+
.alert.success::before {
|
|
28
|
+
background-color: var(--success);
|
|
29
|
+
}
|
|
30
|
+
.alert.warning::before {
|
|
31
|
+
background-color: var(--warning);
|
|
32
|
+
}
|
|
33
|
+
.alert.error::before {
|
|
34
|
+
background-color: var(--error);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.content {
|
|
38
|
+
display: flex;
|
|
39
|
+
flex-direction: column;
|
|
40
|
+
gap: 0.25rem;
|
|
41
|
+
flex: 1;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.title {
|
|
45
|
+
margin: 0;
|
|
46
|
+
font-family: var(--font-heading);
|
|
47
|
+
font-weight: 700;
|
|
48
|
+
font-size: var(--text-base);
|
|
49
|
+
color: var(--foreground);
|
|
50
|
+
text-transform: uppercase;
|
|
51
|
+
letter-spacing: 0.05em;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.description {
|
|
55
|
+
margin: 0;
|
|
56
|
+
font-size: var(--text-sm);
|
|
57
|
+
color: var(--muted-foreground);
|
|
58
|
+
line-height: 1.5;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.iconWrapper {
|
|
62
|
+
display: flex;
|
|
63
|
+
align-items: center;
|
|
64
|
+
flex-shrink: 0;
|
|
65
|
+
}
|
|
66
|
+
.iconWrapper.info {
|
|
67
|
+
color: var(--info, var(--primary));
|
|
68
|
+
}
|
|
69
|
+
.iconWrapper.success {
|
|
70
|
+
color: var(--success);
|
|
71
|
+
}
|
|
72
|
+
.iconWrapper.warning {
|
|
73
|
+
color: var(--warning);
|
|
74
|
+
}
|
|
75
|
+
.iconWrapper.error {
|
|
76
|
+
color: var(--error);
|
|
77
|
+
}
|
|
@@ -1,51 +1,9 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
3
|
import { useState } from 'react';
|
|
4
|
-
import
|
|
5
|
-
|
|
6
|
-
sm: '32px',
|
|
7
|
-
md: '48px',
|
|
8
|
-
lg: '64px',
|
|
9
|
-
xl: '96px',
|
|
10
|
-
};
|
|
11
|
-
const fontSizeMap = {
|
|
12
|
-
sm: 'var(--text-xs)',
|
|
13
|
-
md: 'var(--text-base)',
|
|
14
|
-
lg: 'var(--text-lg)',
|
|
15
|
-
xl: 'var(--text-2xl)',
|
|
16
|
-
};
|
|
17
|
-
const AvatarContainer = styled.div `
|
|
18
|
-
position: relative;
|
|
19
|
-
width: ${props => sizeMap[props.size]};
|
|
20
|
-
height: ${props => sizeMap[props.size]};
|
|
21
|
-
border: var(--border-width) solid var(--card-border);
|
|
22
|
-
border-radius: ${props => props.shape === 'circle' ? '50%' : 'var(--radius)'};
|
|
23
|
-
overflow: hidden;
|
|
24
|
-
background-color: var(--card-bg); /* Fallback bg */
|
|
25
|
-
display: flex;
|
|
26
|
-
align-items: center;
|
|
27
|
-
justify-content: center;
|
|
28
|
-
flex-shrink: 0;
|
|
29
|
-
`;
|
|
30
|
-
const AvatarImage = styled.img `
|
|
31
|
-
width: 100%;
|
|
32
|
-
height: 100%;
|
|
33
|
-
object-fit: cover;
|
|
34
|
-
`;
|
|
35
|
-
const Fallback = styled.span `
|
|
36
|
-
font-family: var(--font-heading);
|
|
37
|
-
font-weight: 700;
|
|
38
|
-
font-size: ${props => fontSizeMap[props.size]};
|
|
39
|
-
color: var(--primary-foreground);
|
|
40
|
-
background-color: var(--primary);
|
|
41
|
-
width: 100%;
|
|
42
|
-
height: 100%;
|
|
43
|
-
display: flex;
|
|
44
|
-
align-items: center;
|
|
45
|
-
justify-content: center;
|
|
46
|
-
text-transform: uppercase;
|
|
47
|
-
`;
|
|
4
|
+
import clsx from 'clsx';
|
|
5
|
+
import styles from './Avatar.module.css';
|
|
48
6
|
export function Avatar({ src, alt = 'Avatar', fallback, size = 'md', shape = 'circle', className }) {
|
|
49
7
|
const [hasError, setHasError] = useState(false);
|
|
50
|
-
return (_jsx(
|
|
8
|
+
return (_jsx("div", { className: clsx(styles.avatar, styles[size], styles[shape], className), children: src && !hasError ? (_jsx("img", { src: src, alt: alt, className: styles.image, onError: () => setHasError(true) })) : (_jsx("span", { className: clsx(styles.fallback, styles[size]), children: typeof fallback === 'string' ? fallback.slice(0, 2) : fallback })) }));
|
|
51
9
|
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
.avatar {
|
|
2
|
+
position: relative;
|
|
3
|
+
border: var(--border-width) solid var(--card-border);
|
|
4
|
+
overflow: hidden;
|
|
5
|
+
background-color: var(--card-bg); /* Fallback bg */
|
|
6
|
+
display: flex;
|
|
7
|
+
align-items: center;
|
|
8
|
+
justify-content: center;
|
|
9
|
+
flex-shrink: 0;
|
|
10
|
+
}
|
|
11
|
+
.avatar.circle {
|
|
12
|
+
border-radius: 50%;
|
|
13
|
+
}
|
|
14
|
+
.avatar.square {
|
|
15
|
+
border-radius: var(--radius);
|
|
16
|
+
}
|
|
17
|
+
.avatar {
|
|
18
|
+
/* Sizes */
|
|
19
|
+
}
|
|
20
|
+
.avatar.sm {
|
|
21
|
+
width: 32px;
|
|
22
|
+
height: 32px;
|
|
23
|
+
}
|
|
24
|
+
.avatar.md {
|
|
25
|
+
width: 48px;
|
|
26
|
+
height: 48px;
|
|
27
|
+
}
|
|
28
|
+
.avatar.lg {
|
|
29
|
+
width: 64px;
|
|
30
|
+
height: 64px;
|
|
31
|
+
}
|
|
32
|
+
.avatar.xl {
|
|
33
|
+
width: 96px;
|
|
34
|
+
height: 96px;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.image {
|
|
38
|
+
width: 100%;
|
|
39
|
+
height: 100%;
|
|
40
|
+
object-fit: cover;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.fallback {
|
|
44
|
+
font-family: var(--font-heading);
|
|
45
|
+
font-weight: 700;
|
|
46
|
+
color: var(--primary-foreground);
|
|
47
|
+
background-color: var(--primary);
|
|
48
|
+
width: 100%;
|
|
49
|
+
height: 100%;
|
|
50
|
+
display: flex;
|
|
51
|
+
align-items: center;
|
|
52
|
+
justify-content: center;
|
|
53
|
+
text-transform: uppercase;
|
|
54
|
+
/* Font sizes mapped to parent sizes */
|
|
55
|
+
}
|
|
56
|
+
.fallback.sm {
|
|
57
|
+
font-size: var(--text-xs);
|
|
58
|
+
}
|
|
59
|
+
.fallback.md {
|
|
60
|
+
font-size: var(--text-base);
|
|
61
|
+
}
|
|
62
|
+
.fallback.lg {
|
|
63
|
+
font-size: var(--text-lg);
|
|
64
|
+
}
|
|
65
|
+
.fallback.xl {
|
|
66
|
+
font-size: var(--text-2xl);
|
|
67
|
+
}
|
|
@@ -4,5 +4,5 @@ interface BadgeProps extends React.HTMLAttributes<HTMLSpanElement> {
|
|
|
4
4
|
variant?: BadgeVariant;
|
|
5
5
|
children: React.ReactNode;
|
|
6
6
|
}
|
|
7
|
-
export declare function Badge({ variant, children, ...props }: BadgeProps): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export declare function Badge({ variant, children, className, ...props }: BadgeProps): import("react/jsx-runtime").JSX.Element;
|
|
8
8
|
export {};
|
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
'use client';
|
|
3
|
-
'use client';
|
|
4
2
|
var __rest = (this && this.__rest) || function (s, e) {
|
|
5
3
|
var t = {};
|
|
6
4
|
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
@@ -13,45 +11,9 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
13
11
|
return t;
|
|
14
12
|
};
|
|
15
13
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
16
|
-
import
|
|
17
|
-
import
|
|
18
|
-
const StyledBadge = styled.span `
|
|
19
|
-
display: inline-flex;
|
|
20
|
-
align-items: center;
|
|
21
|
-
padding: 0.25rem 0.75rem;
|
|
22
|
-
border-radius: var(--radius-pill);
|
|
23
|
-
font-size: 0.75rem;
|
|
24
|
-
font-weight: 700;
|
|
25
|
-
text-transform: uppercase;
|
|
26
|
-
border: 2px solid var(--card-border);
|
|
27
|
-
box-shadow: 2px 2px 0px 0px var(--card-border);
|
|
28
|
-
|
|
29
|
-
${props => props.variant === 'primary' && css `
|
|
30
|
-
background-color: var(--primary);
|
|
31
|
-
color: var(--primary-foreground);
|
|
32
|
-
`}
|
|
33
|
-
|
|
34
|
-
${props => props.variant === 'success' && css `
|
|
35
|
-
background-color: var(--success);
|
|
36
|
-
color: var(--card-bg);
|
|
37
|
-
`}
|
|
38
|
-
|
|
39
|
-
${props => props.variant === 'warning' && css `
|
|
40
|
-
background-color: var(--warning);
|
|
41
|
-
color: var(--card-bg);
|
|
42
|
-
`}
|
|
43
|
-
|
|
44
|
-
${props => props.variant === 'error' && css `
|
|
45
|
-
background-color: var(--error);
|
|
46
|
-
color: var(--card-bg);
|
|
47
|
-
`}
|
|
48
|
-
|
|
49
|
-
${props => props.variant === 'secondary' && css `
|
|
50
|
-
background-color: var(--secondary);
|
|
51
|
-
color: var(--secondary-foreground);
|
|
52
|
-
`}
|
|
53
|
-
`;
|
|
14
|
+
import clsx from 'clsx';
|
|
15
|
+
import styles from './Badge.module.css';
|
|
54
16
|
export function Badge(_a) {
|
|
55
|
-
var { variant = 'primary', children } = _a, props = __rest(_a, ["variant", "children"]);
|
|
56
|
-
return (_jsx(
|
|
17
|
+
var { variant = 'primary', children, className } = _a, props = __rest(_a, ["variant", "children", "className"]);
|
|
18
|
+
return (_jsx("span", Object.assign({ className: clsx(styles.badge, styles[variant], className) }, props, { children: children })));
|
|
57
19
|
}
|