doom-design-system 0.2.1 → 0.3.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/dist/components/ActionRow/ActionRow.module.css +1 -0
- package/dist/components/Alert/Alert.module.css +2 -2
- package/dist/components/Button/Button.module.css +5 -2
- package/dist/components/Checkbox/Checkbox.module.css +1 -1
- package/dist/components/Drawer/Drawer.d.ts +2 -1
- package/dist/components/Drawer/Drawer.js +2 -2
- package/dist/components/Drawer/Drawer.module.css +74 -8
- package/dist/components/Input/Input.module.css +1 -1
- package/dist/components/Modal/Modal.d.ts +2 -1
- package/dist/components/Modal/Modal.js +4 -2
- package/dist/components/Modal/Modal.module.css +56 -7
- package/dist/components/Select/Select.module.css +1 -1
- package/dist/components/Sheet/Sheet.d.ts +3 -1
- package/dist/components/Sheet/Sheet.js +2 -2
- package/dist/components/Sheet/Sheet.module.css +98 -12
- package/dist/components/Slider/Slider.d.ts +4 -4
- package/dist/components/Slider/Slider.js +46 -9
- package/dist/components/Slider/Slider.module.css +60 -68
- package/dist/components/SplitButton/SplitButton.js +1 -1
- package/dist/components/SplitButton/SplitButton.module.css +7 -2
- package/dist/components/Table/Table.d.ts +4 -4
- package/dist/components/Table/Table.js +40 -41
- package/dist/components/Table/Table.module.css +11 -5
- package/dist/components/Textarea/Textarea.module.css +1 -1
- package/dist/styles/globals.css +19 -0
- package/dist/styles/themes/definitions.d.ts +91 -59
- package/dist/styles/themes/definitions.js +5 -67
- package/dist/styles/tokens.d.ts +171 -0
- package/dist/styles/tokens.js +185 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
font-family: var(--font-heading);
|
|
47
47
|
font-weight: 700;
|
|
48
48
|
font-size: var(--text-base);
|
|
49
|
-
color: var(--
|
|
49
|
+
color: var(--on-surface);
|
|
50
50
|
text-transform: uppercase;
|
|
51
51
|
letter-spacing: 0.05em;
|
|
52
52
|
}
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
.description {
|
|
55
55
|
margin: 0;
|
|
56
56
|
font-size: var(--text-sm);
|
|
57
|
-
color: var(--muted
|
|
57
|
+
color: var(--on-surface-muted);
|
|
58
58
|
line-height: 1.5;
|
|
59
59
|
}
|
|
60
60
|
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
transform: translate(-2px, -2px);
|
|
22
22
|
box-shadow: var(--shadow-hover);
|
|
23
23
|
}
|
|
24
|
-
.button:focus {
|
|
24
|
+
.button:focus-visible {
|
|
25
25
|
outline: none;
|
|
26
26
|
box-shadow: 7px 7px 0px 0px var(--btn-focus-shadow);
|
|
27
27
|
transform: translate(-2px, -2px);
|
|
@@ -45,6 +45,7 @@
|
|
|
45
45
|
--btn-focus-shadow: #000000;
|
|
46
46
|
background-color: var(--primary);
|
|
47
47
|
color: var(--primary-foreground);
|
|
48
|
+
border-color: var(--border-strong);
|
|
48
49
|
}
|
|
49
50
|
.primary:hover {
|
|
50
51
|
filter: brightness(1.1);
|
|
@@ -55,6 +56,7 @@
|
|
|
55
56
|
--btn-focus-shadow: #000000;
|
|
56
57
|
background-color: var(--secondary);
|
|
57
58
|
color: var(--secondary-foreground);
|
|
59
|
+
border-color: var(--border-strong);
|
|
58
60
|
}
|
|
59
61
|
.secondary:hover {
|
|
60
62
|
filter: brightness(1.1);
|
|
@@ -65,6 +67,7 @@
|
|
|
65
67
|
--btn-focus-shadow: #000000;
|
|
66
68
|
background-color: var(--success);
|
|
67
69
|
color: var(--success-foreground);
|
|
70
|
+
border-color: var(--border-strong);
|
|
68
71
|
}
|
|
69
72
|
.success:hover {
|
|
70
73
|
filter: brightness(1.1);
|
|
@@ -79,7 +82,7 @@
|
|
|
79
82
|
border-color: transparent;
|
|
80
83
|
box-shadow: none;
|
|
81
84
|
}
|
|
82
|
-
.ghost:hover, .ghost:focus {
|
|
85
|
+
.ghost:hover, .ghost:focus-visible {
|
|
83
86
|
background-color: color-mix(in srgb, var(--primary), transparent 90%);
|
|
84
87
|
color: var(--primary);
|
|
85
88
|
transform: none;
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
.checkboxInput:focus-visible + .checkboxDisplay:focus, .checkboxInput:focus-visible + .checkboxDisplay:focus-visible, .checkboxInput:focus-visible + .checkboxDisplay[aria-expanded=true] {
|
|
21
21
|
outline: none;
|
|
22
22
|
transform: translate(-2px, -2px);
|
|
23
|
-
box-shadow:
|
|
23
|
+
box-shadow: 8px 8px 0px 0px var(--shadow-primary);
|
|
24
24
|
border-color: var(--primary);
|
|
25
25
|
}
|
|
26
26
|
.checkboxInput:focus-visible + .checkboxDisplay {
|
|
@@ -7,6 +7,7 @@ interface DrawerProps {
|
|
|
7
7
|
children: React.ReactNode;
|
|
8
8
|
footer?: React.ReactNode;
|
|
9
9
|
className?: string;
|
|
10
|
+
variant?: "default" | "solid";
|
|
10
11
|
}
|
|
11
|
-
export declare function Drawer({ isOpen, onClose, title, side, children, footer, className, }: DrawerProps): React.ReactPortal | null;
|
|
12
|
+
export declare function Drawer({ isOpen, onClose, title, side, children, footer, className, variant, }: DrawerProps): React.ReactPortal | null;
|
|
12
13
|
export {};
|
|
@@ -6,7 +6,7 @@ import { X } from "lucide-react";
|
|
|
6
6
|
import { Button } from "../Button/Button.js";
|
|
7
7
|
import styles from "./Drawer.module.css";
|
|
8
8
|
import React, { useEffect, useState } from "react";
|
|
9
|
-
export function Drawer({ isOpen, onClose, title, side = "right", children, footer, className, }) {
|
|
9
|
+
export function Drawer({ isOpen, onClose, title, side = "right", children, footer, className, variant = "default", }) {
|
|
10
10
|
const reactId = React.useId();
|
|
11
11
|
const titleId = `drawer-title-${reactId}`;
|
|
12
12
|
const [mounted, setMounted] = useState(false);
|
|
@@ -33,5 +33,5 @@ export function Drawer({ isOpen, onClose, title, side = "right", children, foote
|
|
|
33
33
|
}, [isOpen, onClose]);
|
|
34
34
|
if (!mounted)
|
|
35
35
|
return null;
|
|
36
|
-
return createPortal(_jsxs(_Fragment, { children: [_jsx("div", { className: clsx(styles.overlay, isOpen && styles.isOpen), onClick: onClose, "aria-hidden": "true" }), _jsxs("div", { className: clsx(styles.panel, styles[side], isOpen && styles.isOpen, className), role: "dialog", "aria-modal": "true", "aria-labelledby": title ? titleId : undefined, "aria-label": !title ? "Drawer" : undefined, children: [_jsxs("div", { className: styles.header, children: [title && (_jsx("h2", { id: titleId, className: styles.title, children: title })), _jsx(Button, { variant: "ghost", size: "sm", onClick: onClose, "aria-label": "Close drawer", children: _jsx(X, { size: 24 }) })] }), _jsx("div", { className: styles.content, children: children }), footer && _jsx("div", { className: styles.footer, children: footer })] })] }), document.body);
|
|
36
|
+
return createPortal(_jsxs(_Fragment, { children: [_jsx("div", { className: clsx(styles.overlay, isOpen && styles.isOpen), onClick: onClose, "aria-hidden": "true" }), _jsxs("div", { className: clsx(styles.panel, styles[side], styles[variant], isOpen && styles.isOpen, className), role: "dialog", "aria-modal": "true", "aria-labelledby": title ? titleId : undefined, "aria-label": !title ? "Drawer" : undefined, children: [_jsxs("div", { className: styles.header, children: [title && (_jsx("h2", { id: titleId, className: styles.title, children: title })), _jsx(Button, { variant: "ghost", size: "sm", onClick: onClose, "aria-label": "Close drawer", children: _jsx(X, { size: 24 }) })] }), _jsx("div", { className: styles.content, children: children }), footer && _jsx("div", { className: styles.footer, children: footer })] })] }), document.body);
|
|
37
37
|
}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
visibility: hidden;
|
|
8
8
|
transition: opacity 0.2s ease-in-out, visibility 0.2s ease-in-out;
|
|
9
9
|
pointer-events: none;
|
|
10
|
-
z-index: var(--z-
|
|
10
|
+
z-index: var(--z-overlay);
|
|
11
11
|
}
|
|
12
12
|
.overlay.isOpen {
|
|
13
13
|
opacity: 1;
|
|
@@ -18,26 +18,35 @@
|
|
|
18
18
|
.panel {
|
|
19
19
|
position: fixed;
|
|
20
20
|
background-color: var(--card-bg);
|
|
21
|
-
z-index: var(--z-
|
|
21
|
+
z-index: var(--z-drawer);
|
|
22
22
|
display: flex;
|
|
23
23
|
flex-direction: column;
|
|
24
|
-
transition: transform
|
|
24
|
+
transition: transform var(--duration-normal) var(--ease-in-out), visibility var(--duration-normal) var(--ease-in-out);
|
|
25
25
|
top: 0;
|
|
26
26
|
bottom: 0;
|
|
27
27
|
width: 100%;
|
|
28
28
|
max-width: 400px;
|
|
29
29
|
visibility: hidden;
|
|
30
|
+
border: var(--border-width) solid var(--card-border);
|
|
30
31
|
}
|
|
31
32
|
.panel.left {
|
|
32
33
|
left: 0;
|
|
33
|
-
|
|
34
|
+
/* Remove border on the edge touching the screen */
|
|
35
|
+
border-left: 0;
|
|
36
|
+
/* Standard directional shadow for left-anchored panel */
|
|
37
|
+
/* Bottom-Right shadow for left-anchored elements */
|
|
38
|
+
box-shadow: 8px 8px 0 0 var(--border-strong);
|
|
34
39
|
border-top-right-radius: var(--radius);
|
|
35
40
|
border-bottom-right-radius: var(--radius);
|
|
36
41
|
transform: translateX(calc(-100% - 20px));
|
|
37
42
|
}
|
|
38
43
|
.panel.right {
|
|
39
44
|
right: 0;
|
|
40
|
-
|
|
45
|
+
/* Remove border on the edge touching the screen */
|
|
46
|
+
border-right: 0;
|
|
47
|
+
/* Standard directional shadow for right-anchored panel */
|
|
48
|
+
/* Bottom-Left shadow for right-anchored elements */
|
|
49
|
+
box-shadow: -8px 8px 0 0 var(--border-strong);
|
|
41
50
|
border-top-left-radius: var(--radius);
|
|
42
51
|
border-bottom-left-radius: var(--radius);
|
|
43
52
|
transform: translateX(calc(100% + 20px));
|
|
@@ -46,32 +55,89 @@
|
|
|
46
55
|
visibility: visible;
|
|
47
56
|
transform: translateX(0);
|
|
48
57
|
}
|
|
58
|
+
.panel.solid {
|
|
59
|
+
/*
|
|
60
|
+
SCALABLE CONTEXTUAL REMAPPING
|
|
61
|
+
Save original values then swap semantic tokens to auto-invert content.
|
|
62
|
+
*/
|
|
63
|
+
--solid-bg: var(--primary);
|
|
64
|
+
--solid-fg: var(--primary-foreground);
|
|
65
|
+
background-color: var(--solid-bg);
|
|
66
|
+
color: var(--solid-fg);
|
|
67
|
+
/* Swap Semantics & Remap Content on CHILDREN only */
|
|
68
|
+
}
|
|
69
|
+
.panel.solid > * {
|
|
70
|
+
--primary: var(--solid-fg);
|
|
71
|
+
--primary-foreground: var(--solid-bg);
|
|
72
|
+
--foreground: var(--solid-fg);
|
|
73
|
+
--muted-foreground: var(--solid-fg);
|
|
74
|
+
}
|
|
75
|
+
.panel.solid .header {
|
|
76
|
+
background-color: transparent !important;
|
|
77
|
+
color: var(--solid-fg);
|
|
78
|
+
}
|
|
79
|
+
.panel.solid .header button {
|
|
80
|
+
background-color: var(--error) !important;
|
|
81
|
+
color: var(--error-foreground) !important;
|
|
82
|
+
border-color: var(--border-strong) !important;
|
|
83
|
+
}
|
|
84
|
+
.panel.solid .content {
|
|
85
|
+
background-color: transparent !important;
|
|
86
|
+
}
|
|
87
|
+
.panel.solid .footer {
|
|
88
|
+
background-color: transparent !important;
|
|
89
|
+
}
|
|
49
90
|
|
|
50
91
|
.header {
|
|
51
92
|
padding: var(--spacing-lg);
|
|
52
|
-
|
|
93
|
+
background-color: var(--primary);
|
|
94
|
+
color: var(--primary-foreground);
|
|
95
|
+
border-bottom: var(--border-width) solid var(--border-strong);
|
|
53
96
|
display: flex;
|
|
54
97
|
justify-content: space-between;
|
|
55
98
|
align-items: center;
|
|
99
|
+
flex-shrink: 0;
|
|
100
|
+
/* Match Modal's Close Button Styling */
|
|
101
|
+
}
|
|
102
|
+
.header button {
|
|
103
|
+
background-color: var(--error) !important;
|
|
104
|
+
color: var(--error-foreground) !important;
|
|
105
|
+
border: var(--border-width) solid var(--border-strong) !important;
|
|
106
|
+
box-shadow: var(--shadow-sm) !important;
|
|
107
|
+
}
|
|
108
|
+
.header button:hover {
|
|
109
|
+
background-color: var(--error) !important;
|
|
110
|
+
filter: brightness(1.1);
|
|
111
|
+
transform: translate(-2px, -2px);
|
|
112
|
+
box-shadow: var(--shadow-sm-hover) !important;
|
|
113
|
+
}
|
|
114
|
+
.header button:active {
|
|
115
|
+
transform: translate(2px, 2px);
|
|
116
|
+
box-shadow: var(--shadow-sm-checked) !important;
|
|
56
117
|
}
|
|
57
118
|
|
|
58
119
|
.title {
|
|
59
120
|
margin: 0;
|
|
60
121
|
font-family: var(--font-heading);
|
|
61
122
|
font-size: var(--text-xl);
|
|
62
|
-
font-weight:
|
|
123
|
+
font-weight: 800;
|
|
124
|
+
text-transform: uppercase;
|
|
125
|
+
letter-spacing: 0.05em;
|
|
63
126
|
}
|
|
64
127
|
|
|
65
128
|
.content {
|
|
66
129
|
flex: 1;
|
|
67
130
|
padding: var(--spacing-lg);
|
|
68
131
|
overflow-y: auto;
|
|
132
|
+
background-color: var(--card-bg);
|
|
69
133
|
}
|
|
70
134
|
|
|
71
135
|
.footer {
|
|
72
136
|
padding: var(--spacing-lg);
|
|
73
|
-
border-top: var(--border-width) solid var(--
|
|
137
|
+
border-top: var(--border-width) solid var(--border-strong);
|
|
74
138
|
display: flex;
|
|
75
139
|
justify-content: flex-end;
|
|
76
140
|
gap: var(--spacing-md);
|
|
141
|
+
background-color: var(--card-bg);
|
|
142
|
+
flex-shrink: 0;
|
|
77
143
|
}
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
.input:focus, .input:focus-visible, .input[aria-expanded=true] {
|
|
28
28
|
outline: none;
|
|
29
29
|
transform: translate(-2px, -2px);
|
|
30
|
-
box-shadow:
|
|
30
|
+
box-shadow: 8px 8px 0px 0px var(--shadow-primary);
|
|
31
31
|
border-color: var(--primary);
|
|
32
32
|
}
|
|
33
33
|
.input::placeholder {
|
|
@@ -5,6 +5,7 @@ interface ModalProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "title">
|
|
|
5
5
|
title?: React.ReactNode;
|
|
6
6
|
children: React.ReactNode;
|
|
7
7
|
footer?: React.ReactNode;
|
|
8
|
+
variant?: "default" | "solid";
|
|
8
9
|
}
|
|
9
10
|
interface ModalHeaderProps {
|
|
10
11
|
children: React.ReactNode;
|
|
@@ -20,5 +21,5 @@ export declare function ModalFooter({ children, className, }: {
|
|
|
20
21
|
children: React.ReactNode;
|
|
21
22
|
className?: string;
|
|
22
23
|
}): import("react/jsx-runtime").JSX.Element;
|
|
23
|
-
export declare function Modal({ isOpen, onClose, title, children, footer, className, style, ...props }: ModalProps): React.ReactPortal | null;
|
|
24
|
+
export declare function Modal({ isOpen, onClose, title, children, footer, className, style, variant, ...props }: ModalProps): React.ReactPortal | null;
|
|
24
25
|
export {};
|
|
@@ -21,6 +21,7 @@ import { Stack, Flex } from "../Layout/Layout.js";
|
|
|
21
21
|
import styles from "./Modal.module.css";
|
|
22
22
|
const ModalContext = React.createContext({
|
|
23
23
|
onClose: () => { },
|
|
24
|
+
variant: "default",
|
|
24
25
|
});
|
|
25
26
|
export function ModalHeader({ children, className, id }) {
|
|
26
27
|
const { onClose, titleId } = React.useContext(ModalContext);
|
|
@@ -33,7 +34,7 @@ export function ModalFooter({ children, className, }) {
|
|
|
33
34
|
return (_jsx(Flex, { justify: "flex-end", align: "center", gap: "var(--spacing-md)", className: clsx(styles.footer, className), children: children }));
|
|
34
35
|
}
|
|
35
36
|
export function Modal(_a) {
|
|
36
|
-
var { isOpen, onClose, title, children, footer, className, style } = _a, props = __rest(_a, ["isOpen", "onClose", "title", "children", "footer", "className", "style"]);
|
|
37
|
+
var { isOpen, onClose, title, children, footer, className, style, variant = "default" } = _a, props = __rest(_a, ["isOpen", "onClose", "title", "children", "footer", "className", "style", "variant"]);
|
|
37
38
|
const overlayRef = useRef(null);
|
|
38
39
|
const reactId = useId();
|
|
39
40
|
const titleId = `modal-title-${reactId}`;
|
|
@@ -65,5 +66,6 @@ export function Modal(_a) {
|
|
|
65
66
|
onClose();
|
|
66
67
|
}
|
|
67
68
|
};
|
|
68
|
-
return createPortal(_jsx(ModalContext.Provider, { value: { onClose, titleId }, children: _jsx("div", { className: clsx(styles.overlay, isOpen && styles.isOpen, className), ref: overlayRef, onClick: handleOverlayClick, style: style, children: _jsx("div", { className: styles.contentContainer, children: _jsx("div", Object.assign({ role: "dialog", "aria-modal": "true", "aria-labelledby": title ? titleId :
|
|
69
|
+
return createPortal(_jsx(ModalContext.Provider, { value: { onClose, titleId, variant }, children: _jsx("div", { className: clsx(styles.overlay, isOpen && styles.isOpen, className), ref: overlayRef, onClick: handleOverlayClick, style: style, children: _jsx("div", { className: styles.contentContainer, children: _jsx("div", Object.assign({ role: "dialog", "aria-modal": "true", "aria-labelledby": title ? titleId : props["aria-labelledby"], "aria-label": props["aria-label"] ||
|
|
70
|
+
(!title && !props["aria-labelledby"] ? "Modal Window" : undefined) }, props, { children: _jsx(Card, { className: clsx(styles.modalCard, styles[variant]), style: { padding: 0, overflow: "hidden" }, children: title ? (_jsxs(_Fragment, { children: [_jsx(ModalHeader, { children: title }), _jsxs(Stack, { gap: 0, className: styles.modalContent, children: [_jsx(ModalBody, { children: children }), footer && _jsx(ModalFooter, { children: footer })] })] })) : (children) }) })) }) }) }), document.body);
|
|
69
71
|
}
|
|
@@ -32,12 +32,60 @@
|
|
|
32
32
|
.modalCard {
|
|
33
33
|
background-color: var(--primary);
|
|
34
34
|
}
|
|
35
|
+
.modalCard.solid {
|
|
36
|
+
/*
|
|
37
|
+
SCALABLE CONTEXTUAL REMAPPING
|
|
38
|
+
Save original values then swap semantic tokens to auto-invert content.
|
|
39
|
+
*/
|
|
40
|
+
--solid-bg: var(--primary);
|
|
41
|
+
--solid-fg: var(--primary-foreground);
|
|
42
|
+
--original-border: var(--card-border);
|
|
43
|
+
background-color: var(--solid-bg);
|
|
44
|
+
color: var(--solid-fg);
|
|
45
|
+
/*
|
|
46
|
+
Swap Semantics & Remap Content on CHILDREN only.
|
|
47
|
+
This avoids circular dependency on the container's background-color.
|
|
48
|
+
*/
|
|
49
|
+
}
|
|
50
|
+
.modalCard.solid > * {
|
|
51
|
+
--primary: var(--solid-fg);
|
|
52
|
+
--primary-foreground: var(--solid-bg);
|
|
53
|
+
--foreground: var(--solid-fg);
|
|
54
|
+
--muted-foreground: var(--solid-fg);
|
|
55
|
+
}
|
|
56
|
+
.modalCard.solid .header,
|
|
57
|
+
.modalCard.solid .body,
|
|
58
|
+
.modalCard.solid .footer,
|
|
59
|
+
.modalCard.solid .modalContent {
|
|
60
|
+
background-color: transparent !important;
|
|
61
|
+
color: var(--solid-fg);
|
|
62
|
+
}
|
|
63
|
+
.modalCard.solid {
|
|
64
|
+
/* In solid mode, we need to override the close button to ensure contrast */
|
|
65
|
+
}
|
|
66
|
+
.modalCard.solid .closeButton {
|
|
67
|
+
background-color: var(--error) !important;
|
|
68
|
+
color: var(--error-foreground) !important;
|
|
69
|
+
border-color: var(--border-strong) !important;
|
|
70
|
+
box-shadow: var(--shadow-hard) !important;
|
|
71
|
+
}
|
|
72
|
+
.modalCard.solid .closeButton:hover {
|
|
73
|
+
transform: translate(-2px, -2px);
|
|
74
|
+
box-shadow: var(--shadow-hover) !important;
|
|
75
|
+
}
|
|
76
|
+
.modalCard.solid .closeButton:active {
|
|
77
|
+
transform: translate(2px, 2px);
|
|
78
|
+
box-shadow: none !important;
|
|
79
|
+
}
|
|
35
80
|
|
|
36
81
|
.header {
|
|
37
82
|
padding: var(--spacing-lg);
|
|
38
83
|
background-color: var(--primary);
|
|
39
84
|
color: var(--primary-foreground);
|
|
40
|
-
border-bottom:
|
|
85
|
+
border-bottom: var(--border-width) solid var(--border-strong);
|
|
86
|
+
/* Remap foreground variables so children (like Text) use the correct contrast color */
|
|
87
|
+
--foreground: var(--primary-foreground);
|
|
88
|
+
--muted-foreground: var(--primary-foreground);
|
|
41
89
|
}
|
|
42
90
|
|
|
43
91
|
.headerContent {
|
|
@@ -48,7 +96,7 @@
|
|
|
48
96
|
.closeButton {
|
|
49
97
|
flex-shrink: 0;
|
|
50
98
|
background-color: var(--error) !important;
|
|
51
|
-
color:
|
|
99
|
+
color: var(--error-foreground) !important;
|
|
52
100
|
border: var(--border-width) solid var(--card-border) !important;
|
|
53
101
|
border-radius: var(--radius) !important;
|
|
54
102
|
height: 36px !important;
|
|
@@ -58,18 +106,19 @@
|
|
|
58
106
|
align-items: center;
|
|
59
107
|
justify-content: center;
|
|
60
108
|
padding: 0 !important;
|
|
61
|
-
|
|
109
|
+
/* Use standardized shadow-error mixed with black for depth */
|
|
110
|
+
box-shadow: var(--shadow-hard) !important;
|
|
62
111
|
transition: all 0.2s ease;
|
|
63
112
|
cursor: pointer;
|
|
64
113
|
}
|
|
65
114
|
.closeButton:hover {
|
|
66
115
|
filter: brightness(1.1);
|
|
67
|
-
transform: translate(-
|
|
68
|
-
box-shadow:
|
|
116
|
+
transform: translate(-2px, -2px);
|
|
117
|
+
box-shadow: var(--shadow-hover) !important;
|
|
69
118
|
}
|
|
70
119
|
.closeButton:active {
|
|
71
|
-
transform: translate(
|
|
72
|
-
box-shadow:
|
|
120
|
+
transform: translate(2px, 2px);
|
|
121
|
+
box-shadow: none !important;
|
|
73
122
|
}
|
|
74
123
|
|
|
75
124
|
.modalContent {
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
.trigger:focus, .trigger:focus-visible, .trigger[aria-expanded=true] {
|
|
33
33
|
outline: none;
|
|
34
34
|
transform: translate(-2px, -2px);
|
|
35
|
-
box-shadow:
|
|
35
|
+
box-shadow: 8px 8px 0px 0px var(--shadow-primary);
|
|
36
36
|
border-color: var(--primary);
|
|
37
37
|
}
|
|
38
38
|
|
|
@@ -4,7 +4,9 @@ interface SheetProps {
|
|
|
4
4
|
onClose: () => void;
|
|
5
5
|
title?: string;
|
|
6
6
|
children: React.ReactNode;
|
|
7
|
+
footer?: React.ReactNode;
|
|
8
|
+
variant?: "default" | "solid";
|
|
7
9
|
className?: string;
|
|
8
10
|
}
|
|
9
|
-
export declare function Sheet({ isOpen, onClose, title, children, className, }: SheetProps): React.ReactPortal | null;
|
|
11
|
+
export declare function Sheet({ isOpen, onClose, title, children, footer, variant, className, }: SheetProps): React.ReactPortal | null;
|
|
10
12
|
export {};
|
|
@@ -7,7 +7,7 @@ import { Button } from "../Button/Button.js";
|
|
|
7
7
|
import { Flex } from "../Layout/Layout.js";
|
|
8
8
|
import styles from "./Sheet.module.css";
|
|
9
9
|
import { X } from "lucide-react";
|
|
10
|
-
export function Sheet({ isOpen, onClose, title, children, className, }) {
|
|
10
|
+
export function Sheet({ isOpen, onClose, title, children, footer, variant = "default", className, }) {
|
|
11
11
|
const reactId = React.useId();
|
|
12
12
|
const titleId = `sheet-title-${reactId}`;
|
|
13
13
|
const [mounted, setMounted] = useState(false);
|
|
@@ -34,5 +34,5 @@ export function Sheet({ isOpen, onClose, title, children, className, }) {
|
|
|
34
34
|
}, [isOpen, onClose]);
|
|
35
35
|
if (!mounted)
|
|
36
36
|
return null;
|
|
37
|
-
return createPortal(_jsxs(_Fragment, { children: [_jsx("div", { className: clsx(styles.overlay, isOpen && styles.isOpen), onClick: onClose, "aria-hidden": "true" }), _jsxs("div", { className: clsx(styles.panel, isOpen && styles.isOpen, className), role: "dialog", "aria-modal": "true", "aria-labelledby": title ? titleId : undefined, "aria-label": !title ? "Sheet" : undefined, children: [_jsx("div", { className: styles.handleBar }), _jsxs(Flex, { align: "center", justify: "space-between", className: styles.
|
|
37
|
+
return createPortal(_jsxs(_Fragment, { children: [_jsx("div", { className: clsx(styles.overlay, isOpen && styles.isOpen), onClick: onClose, "aria-hidden": "true" }), _jsxs("div", { className: clsx(styles.panel, styles[variant], isOpen && styles.isOpen, className), role: "dialog", "aria-modal": "true", "aria-labelledby": title ? titleId : undefined, "aria-label": !title ? "Sheet" : undefined, children: [_jsxs("div", { className: styles.header, children: [_jsx("div", { className: styles.handleBar }), _jsxs(Flex, { align: "center", justify: "space-between", className: styles.headerBody, children: [title && (_jsx("h2", { id: titleId, className: styles.title, children: title })), _jsx(Button, { variant: "ghost", size: "sm", onClick: onClose, "aria-label": "Close sheet", children: _jsx(X, { size: 24 }) })] })] }), _jsx("div", { className: styles.content, children: children }), footer && _jsx("div", { className: styles.footer, children: footer })] })] }), document.body);
|
|
38
38
|
}
|
|
@@ -4,12 +4,14 @@
|
|
|
4
4
|
background-color: rgba(0, 0, 0, var(--overlay-opacity));
|
|
5
5
|
backdrop-filter: blur(4px);
|
|
6
6
|
opacity: 0;
|
|
7
|
-
|
|
7
|
+
visibility: hidden;
|
|
8
|
+
transition: opacity 0.2s ease-in-out, visibility 0.2s ease-in-out;
|
|
8
9
|
pointer-events: none;
|
|
9
|
-
z-index: var(--z-
|
|
10
|
+
z-index: var(--z-overlay);
|
|
10
11
|
}
|
|
11
12
|
.overlay.isOpen {
|
|
12
13
|
opacity: 1;
|
|
14
|
+
visibility: visible;
|
|
13
15
|
pointer-events: auto;
|
|
14
16
|
}
|
|
15
17
|
|
|
@@ -25,39 +27,123 @@
|
|
|
25
27
|
border-right: var(--border-width) solid var(--card-border);
|
|
26
28
|
border-top-left-radius: var(--radius);
|
|
27
29
|
border-top-right-radius: var(--radius);
|
|
28
|
-
|
|
30
|
+
/* Brutalist Hard Shadow - Top anchored */
|
|
31
|
+
/* Top-Right heavy shadow */
|
|
32
|
+
box-shadow: 8px -8px 0 0 var(--border-strong);
|
|
29
33
|
display: flex;
|
|
30
34
|
flex-direction: column;
|
|
31
|
-
z-index: var(--z-
|
|
35
|
+
z-index: var(--z-drawer);
|
|
32
36
|
transform: translateY(100%);
|
|
33
|
-
transition: transform
|
|
37
|
+
transition: transform var(--duration-slow) var(--ease-out);
|
|
38
|
+
visibility: hidden;
|
|
34
39
|
}
|
|
35
40
|
.panel.isOpen {
|
|
41
|
+
visibility: visible;
|
|
36
42
|
transform: translateY(0);
|
|
37
43
|
}
|
|
44
|
+
.panel.solid {
|
|
45
|
+
/*
|
|
46
|
+
SCALABLE CONTEXTUAL REMAPPING
|
|
47
|
+
Save original values then swap semantic tokens to auto-invert content.
|
|
48
|
+
*/
|
|
49
|
+
--solid-bg: var(--primary);
|
|
50
|
+
--solid-fg: var(--primary-foreground);
|
|
51
|
+
background-color: var(--solid-bg);
|
|
52
|
+
color: var(--solid-fg);
|
|
53
|
+
/* Swap Semantics & Remap Content on CHILDREN only */
|
|
54
|
+
}
|
|
55
|
+
.panel.solid > * {
|
|
56
|
+
--primary: var(--solid-fg);
|
|
57
|
+
--primary-foreground: var(--solid-bg);
|
|
58
|
+
--foreground: var(--solid-fg);
|
|
59
|
+
--muted-foreground: var(--solid-fg);
|
|
60
|
+
}
|
|
61
|
+
.panel.solid .header {
|
|
62
|
+
background-color: transparent !important;
|
|
63
|
+
color: var(--solid-fg);
|
|
64
|
+
}
|
|
65
|
+
.panel.solid .header button {
|
|
66
|
+
background-color: var(--error) !important;
|
|
67
|
+
color: var(--error-foreground) !important;
|
|
68
|
+
border-color: var(--border-strong) !important;
|
|
69
|
+
}
|
|
70
|
+
.panel.solid .handleBar {
|
|
71
|
+
background-color: var(--solid-fg);
|
|
72
|
+
opacity: 0.8;
|
|
73
|
+
}
|
|
74
|
+
.panel.solid .content {
|
|
75
|
+
background-color: transparent !important;
|
|
76
|
+
}
|
|
77
|
+
.panel.solid .footer {
|
|
78
|
+
background-color: transparent !important;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.header {
|
|
82
|
+
background-color: var(--primary);
|
|
83
|
+
color: var(--primary-foreground);
|
|
84
|
+
border-bottom: var(--border-width) solid var(--border-strong);
|
|
85
|
+
display: flex;
|
|
86
|
+
flex-direction: column;
|
|
87
|
+
flex-shrink: 0;
|
|
88
|
+
}
|
|
38
89
|
|
|
39
90
|
.handleBar {
|
|
40
91
|
width: 48px;
|
|
41
92
|
height: 6px;
|
|
42
93
|
background-color: var(--card-border);
|
|
43
|
-
border-radius:
|
|
44
|
-
margin: 0.75rem auto;
|
|
45
|
-
opacity:
|
|
94
|
+
border-radius: var(--radius-pill);
|
|
95
|
+
margin: 0.75rem auto 0.25rem auto;
|
|
96
|
+
opacity: 1;
|
|
97
|
+
border: var(--border-width) solid var(--border-strong);
|
|
98
|
+
flex-shrink: 0;
|
|
46
99
|
}
|
|
47
100
|
|
|
48
|
-
.
|
|
49
|
-
padding: 0 var(--spacing-lg) var(--spacing-
|
|
101
|
+
.headerBody {
|
|
102
|
+
padding: 0 var(--spacing-lg) var(--spacing-lg) var(--spacing-lg);
|
|
103
|
+
display: flex;
|
|
104
|
+
justify-content: space-between;
|
|
105
|
+
align-items: center;
|
|
106
|
+
/* Match Modal/Drawer's Close Button Styling */
|
|
107
|
+
}
|
|
108
|
+
.headerBody button {
|
|
109
|
+
background-color: var(--error) !important;
|
|
110
|
+
color: var(--error-foreground) !important;
|
|
111
|
+
border: var(--border-width) solid var(--border-strong) !important;
|
|
112
|
+
box-shadow: var(--shadow-sm) !important;
|
|
113
|
+
}
|
|
114
|
+
.headerBody button:hover {
|
|
115
|
+
background-color: var(--error) !important;
|
|
116
|
+
filter: brightness(1.1);
|
|
117
|
+
transform: translate(-2px, -2px);
|
|
118
|
+
box-shadow: var(--shadow-sm-hover) !important;
|
|
119
|
+
}
|
|
120
|
+
.headerBody button:active {
|
|
121
|
+
transform: translate(2px, 2px);
|
|
122
|
+
box-shadow: var(--shadow-sm-checked) !important;
|
|
50
123
|
}
|
|
51
124
|
|
|
52
125
|
.title {
|
|
53
126
|
margin: 0;
|
|
54
127
|
font-family: var(--font-heading);
|
|
55
128
|
font-size: var(--text-xl);
|
|
56
|
-
font-weight:
|
|
129
|
+
font-weight: 800;
|
|
130
|
+
text-transform: uppercase;
|
|
131
|
+
letter-spacing: 0.05em;
|
|
57
132
|
}
|
|
58
133
|
|
|
59
134
|
.content {
|
|
60
135
|
flex: 1;
|
|
61
|
-
padding:
|
|
136
|
+
padding: var(--spacing-lg);
|
|
62
137
|
overflow-y: auto;
|
|
138
|
+
background-color: var(--card-bg);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
.footer {
|
|
142
|
+
padding: var(--spacing-lg);
|
|
143
|
+
border-top: var(--border-width) solid var(--border-strong);
|
|
144
|
+
display: flex;
|
|
145
|
+
justify-content: flex-end;
|
|
146
|
+
gap: var(--spacing-md);
|
|
147
|
+
background-color: var(--card-bg);
|
|
148
|
+
flex-shrink: 0;
|
|
63
149
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
interface SliderProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, "onChange"> {
|
|
2
|
+
interface SliderProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, "onChange" | "value" | "defaultValue"> {
|
|
3
3
|
label?: string;
|
|
4
4
|
showValue?: boolean;
|
|
5
|
-
value?: number;
|
|
6
|
-
defaultValue?: number;
|
|
7
|
-
onChange?: (value: number) => void;
|
|
5
|
+
value?: number | [number, number];
|
|
6
|
+
defaultValue?: number | [number, number];
|
|
7
|
+
onChange?: (value: number | [number, number]) => void;
|
|
8
8
|
}
|
|
9
9
|
export declare function Slider({ label, showValue, value, defaultValue, onChange, min, max, step, className, id, ...props }: SliderProps): import("react/jsx-runtime").JSX.Element;
|
|
10
10
|
export {};
|