doom-design-system 0.3.4 → 0.4.1
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.d.ts +1 -1
- package/dist/components/ActionRow/ActionRow.js +7 -7
- package/dist/components/Avatar/Avatar.js +2 -1
- package/dist/components/Badge/Badge.d.ts +3 -1
- package/dist/components/Badge/Badge.js +2 -2
- package/dist/components/Badge/Badge.module.css +15 -3
- package/dist/components/FileUpload/FileUpload.js +7 -8
- package/dist/components/FileUpload/FileUpload.module.css +0 -5
- package/dist/components/Image/Image.d.ts +8 -0
- package/dist/components/Image/Image.js +91 -0
- package/dist/components/Image/Image.module.css +55 -0
- package/dist/components/Image/index.d.ts +1 -0
- package/dist/components/Image/index.js +1 -0
- package/dist/components/Layout/Layout.d.ts +16 -2
- package/dist/components/Layout/Layout.js +24 -7
- package/dist/components/Link/Link.d.ts +6 -3
- package/dist/components/Link/Link.js +27 -6
- package/dist/components/Link/Link.module.css +10 -1
- package/dist/components/Modal/Modal.js +1 -1
- package/dist/components/Slat/Slat.js +1 -1
- package/dist/components/Table/Table.js +2 -2
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
"use client";
|
|
2
2
|
var __rest = (this && this.__rest) || function (s, e) {
|
|
3
3
|
var t = {};
|
|
4
4
|
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
@@ -11,12 +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 { Text } from
|
|
15
|
-
import { Flex } from
|
|
16
|
-
import { ChevronRight } from
|
|
17
|
-
import clsx from
|
|
18
|
-
import styles from
|
|
14
|
+
import { Text } from "../Text/Text.js";
|
|
15
|
+
import { Flex } from "../Layout/Layout.js";
|
|
16
|
+
import { ChevronRight } from "lucide-react";
|
|
17
|
+
import clsx from "clsx";
|
|
18
|
+
import styles from "./ActionRow.module.css";
|
|
19
19
|
export function ActionRow(_a) {
|
|
20
20
|
var { icon, title, description, onClick, className } = _a, props = __rest(_a, ["icon", "title", "description", "onClick", "className"]);
|
|
21
|
-
return (_jsxs(Flex, Object.assign({ align: "center", gap:
|
|
21
|
+
return (_jsxs(Flex, Object.assign({ align: "center", gap: 6, onClick: onClick, className: clsx(styles.actionRow, className) }, props, { children: [_jsx("div", { className: styles.iconWrapper, children: icon }), _jsxs(Flex, { direction: "column", gap: 1, 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)" } })] })));
|
|
22
22
|
}
|
|
@@ -3,7 +3,8 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
3
3
|
import { useState } from "react";
|
|
4
4
|
import clsx from "clsx";
|
|
5
5
|
import styles from "./Avatar.module.css";
|
|
6
|
+
import { Image } from "../Image/Image.js";
|
|
6
7
|
export function Avatar({ src, alt = "Avatar", fallback, size = "md", shape = "square", className, }) {
|
|
7
8
|
const [hasError, setHasError] = useState(false);
|
|
8
|
-
return (_jsx("div", { className: clsx(styles.avatar, styles[size], styles[shape], className), children: src && !hasError ? (_jsx(
|
|
9
|
+
return (_jsx("div", { className: clsx(styles.avatar, styles[size], styles[shape], className), children: src && !hasError ? (_jsx(Image, { src: src, alt: alt, className: styles.image, onError: () => setHasError(true), fit: "cover", rounded: false })) : (_jsx("span", { className: clsx(styles.fallback, styles[size]), children: typeof fallback === "string" ? fallback.slice(0, 2) : fallback })) }));
|
|
9
10
|
}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
type BadgeVariant = "primary" | "success" | "warning" | "error" | "secondary" | "outline";
|
|
3
|
+
type BadgeSize = "sm" | "md" | "lg";
|
|
3
4
|
interface BadgeProps extends React.HTMLAttributes<HTMLSpanElement> {
|
|
4
5
|
variant?: BadgeVariant;
|
|
6
|
+
size?: BadgeSize;
|
|
5
7
|
children: React.ReactNode;
|
|
6
8
|
}
|
|
7
|
-
export declare function Badge({ variant, children, className, ...props }: BadgeProps): import("react/jsx-runtime").JSX.Element;
|
|
9
|
+
export declare function Badge({ variant, size, children, className, ...props }: BadgeProps): import("react/jsx-runtime").JSX.Element;
|
|
8
10
|
export {};
|
|
@@ -14,6 +14,6 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
14
14
|
import clsx from "clsx";
|
|
15
15
|
import styles from "./Badge.module.css";
|
|
16
16
|
export function Badge(_a) {
|
|
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 })));
|
|
17
|
+
var { variant = "primary", size = "md", children, className } = _a, props = __rest(_a, ["variant", "size", "children", "className"]);
|
|
18
|
+
return (_jsx("span", Object.assign({ className: clsx(styles.badge, styles[variant], styles[size], className) }, props, { children: children })));
|
|
19
19
|
}
|
|
@@ -1,13 +1,25 @@
|
|
|
1
1
|
.badge {
|
|
2
2
|
display: inline-flex;
|
|
3
3
|
align-items: center;
|
|
4
|
-
|
|
5
|
-
border-radius: var(--radius
|
|
6
|
-
font-size: 0.75rem;
|
|
4
|
+
justify-content: center;
|
|
5
|
+
border-radius: var(--radius);
|
|
7
6
|
font-weight: 700;
|
|
8
7
|
text-transform: uppercase;
|
|
9
8
|
border: 2px solid var(--card-border);
|
|
10
9
|
box-shadow: 2px 2px 0px 0px var(--card-border);
|
|
10
|
+
line-height: 1;
|
|
11
|
+
}
|
|
12
|
+
.badge.sm {
|
|
13
|
+
padding: 0.2rem 0.6rem;
|
|
14
|
+
font-size: 0.7rem;
|
|
15
|
+
}
|
|
16
|
+
.badge.md {
|
|
17
|
+
padding: 0.25rem 0.75rem;
|
|
18
|
+
font-size: 0.75rem;
|
|
19
|
+
}
|
|
20
|
+
.badge.lg {
|
|
21
|
+
padding: 0.375rem 1rem;
|
|
22
|
+
font-size: 0.875rem;
|
|
11
23
|
}
|
|
12
24
|
.badge.primary {
|
|
13
25
|
background-color: var(--primary);
|
|
@@ -8,7 +8,7 @@ import { Stack, Flex, Switcher } from "../Layout/Layout.js";
|
|
|
8
8
|
import { Badge } from "../Badge/Badge.js";
|
|
9
9
|
import { Slat } from "../Slat/Slat.js";
|
|
10
10
|
import { Upload, File as FileIcon, FileImage, FileVideo, FileAudio, FileCode, FileArchive, FileText, FileSpreadsheet, Asterisk, X, } from "lucide-react";
|
|
11
|
-
import {
|
|
11
|
+
import { Image } from "../Image/Image.js";
|
|
12
12
|
import clsx from "clsx";
|
|
13
13
|
var Status;
|
|
14
14
|
(function (Status) {
|
|
@@ -189,7 +189,7 @@ export const FileUpload = ({ label, helperText, accept, maxSize, multiple = fals
|
|
|
189
189
|
}) }, handleDragHandlers, { children: [_jsxs(Switcher, { threshold: "xxs", className: clsx(styles.header, {
|
|
190
190
|
[styles.errorHeader]: status === Status.Error,
|
|
191
191
|
[styles.disabledHeader]: disabled,
|
|
192
|
-
}), justify: "space-between", align: "center", gap:
|
|
192
|
+
}), justify: "space-between", align: "center", gap: 2, children: [_jsx("div", { className: styles.headerContent, children: _jsxs(Text, { className: styles.headerTitle, id: "upload-title", children: [label || "Upload Files", required && (_jsx("span", { className: styles.requiredMark, children: _jsx(Asterisk, { size: 14, "aria-label": "required" }) }))] }) }), _jsx(Badge, { variant: status === Status.Error
|
|
193
193
|
? "error"
|
|
194
194
|
: status === Status.HasFiles
|
|
195
195
|
? "success"
|
|
@@ -216,9 +216,9 @@ export const FileUpload = ({ label, helperText, accept, maxSize, multiple = fals
|
|
|
216
216
|
e.preventDefault();
|
|
217
217
|
handleClick();
|
|
218
218
|
}
|
|
219
|
-
}, role: "button", tabIndex: disabled ? -1 : 0, children: _jsxs(Stack, { gap:
|
|
219
|
+
}, role: "button", tabIndex: disabled ? -1 : 0, children: _jsxs(Stack, { gap: 4, align: "center", children: [_jsx("div", { className: styles.voidIconWrapper, "aria-hidden": "true", children: _jsx(Upload, { className: styles.icon, size: 48, strokeWidth: 2 }) }), _jsxs(Stack, { gap: 1, align: "center", children: [_jsx(Text, { weight: "bold", className: styles.voidText, children: isDragging || isActive || forceActive
|
|
220
220
|
? "Drop files now"
|
|
221
|
-
: "Drag and drop files" }), _jsx(Text, { variant: "small", className: styles.secondary, children: "or click to browse" })] }), helperText && (_jsx(Text, { variant: "small", className: styles.helperText, id: "upload-helper", children: helperText })), displayError && (_jsx(Text, { variant: "small", className: styles.errorText, id: "upload-error", children: displayError }))] }) })) : (_jsxs(Flex, { direction: "column", justify: "space-between", gap:
|
|
221
|
+
: "Drag and drop files" }), _jsx(Text, { variant: "small", className: styles.secondary, children: "or click to browse" })] }), helperText && (_jsx(Text, { variant: "small", className: styles.helperText, id: "upload-helper", children: helperText })), displayError && (_jsx(Text, { variant: "small", className: styles.errorText, id: "upload-error", children: displayError }))] }) })) : (_jsxs(Flex, { direction: "column", justify: "space-between", gap: 4, className: styles.fileList, children: [_jsx(Stack, { gap: 2, children: files.map((file, index) => {
|
|
222
222
|
const previewUrl = previews[file.name];
|
|
223
223
|
return (_jsx(Slat, { label: file.name, secondaryLabel: formatFileSize(file.size), prependContent: previewUrl ? (_jsx(PreviewImage, { src: previewUrl, alt: file.name })) : (getFileIcon(file.name)), appendContent: _jsx(Button, { type: "button", variant: "danger", size: "sm", onClick: (e) => {
|
|
224
224
|
e.stopPropagation();
|
|
@@ -231,8 +231,7 @@ export const FileUpload = ({ label, helperText, accept, maxSize, multiple = fals
|
|
|
231
231
|
}, children: "UPLOAD MORE FILES" }))] }))] })] })));
|
|
232
232
|
};
|
|
233
233
|
const PreviewImage = ({ src, alt }) => {
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
.replace(/[-_]/g, " ") || "File preview", className: clsx(styles.previewImg, { [styles.loaded]: loaded }), onLoad: () => setLoaded(true), style: loaded ? {} : { position: "absolute", opacity: 0 } })] }));
|
|
234
|
+
return (_jsx("div", { className: styles.previewWrapper, children: _jsx(Image, { src: src, alt: alt
|
|
235
|
+
.replace(/\.(jpg|jpeg|png|gif|webp|svg)$/i, "")
|
|
236
|
+
.replace(/[-_]/g, " ") || "File preview", className: styles.previewImg, fit: "cover", rounded: false }) }));
|
|
238
237
|
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
export interface ImageProps extends React.ImgHTMLAttributes<HTMLImageElement> {
|
|
3
|
+
fit?: "cover" | "contain" | "fill" | "none" | "scale-down";
|
|
4
|
+
fallbackSrc?: string;
|
|
5
|
+
aspectRatio?: string | number;
|
|
6
|
+
rounded?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export declare function Image({ src, alt, className, fit, style, onLoad, onError, fallbackSrc, aspectRatio, rounded, width, height, ...props }: ImageProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,91 @@
|
|
|
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 React, { useState, useEffect, useCallback } from "react";
|
|
15
|
+
import clsx from "clsx";
|
|
16
|
+
import styles from "./Image.module.css";
|
|
17
|
+
import { Skeleton } from "../Skeleton/Skeleton.js";
|
|
18
|
+
export function Image(_a) {
|
|
19
|
+
var { src, alt, className, fit, style, onLoad, onError, fallbackSrc, aspectRatio, rounded = true, width, height } = _a, props = __rest(_a, ["src", "alt", "className", "fit", "style", "onLoad", "onError", "fallbackSrc", "aspectRatio", "rounded", "width", "height"]);
|
|
20
|
+
const [status, setStatus] = useState("loading");
|
|
21
|
+
const [showSkeleton, setShowSkeleton] = useState(true);
|
|
22
|
+
// Helper to extract intrinsic numeric value and convert to CSS
|
|
23
|
+
const toCssValue = (val) => {
|
|
24
|
+
if (val === undefined || val === null)
|
|
25
|
+
return undefined;
|
|
26
|
+
if (typeof val === "number")
|
|
27
|
+
return `${val}px`;
|
|
28
|
+
return val;
|
|
29
|
+
};
|
|
30
|
+
const getIntrinsicSize = (val) => {
|
|
31
|
+
if (typeof val === "number")
|
|
32
|
+
return val;
|
|
33
|
+
if (typeof val === "string" && !val.endsWith("%")) {
|
|
34
|
+
const parsed = parseFloat(val);
|
|
35
|
+
return isNaN(parsed) ? undefined : parsed;
|
|
36
|
+
}
|
|
37
|
+
return undefined;
|
|
38
|
+
};
|
|
39
|
+
const computedAspectRatio = React.useMemo(() => {
|
|
40
|
+
if (aspectRatio)
|
|
41
|
+
return aspectRatio;
|
|
42
|
+
const w = getIntrinsicSize(width);
|
|
43
|
+
const h = getIntrinsicSize(height);
|
|
44
|
+
return w && h ? `${w} / ${h}` : undefined;
|
|
45
|
+
}, [aspectRatio, width, height]);
|
|
46
|
+
// Reset state when source changes
|
|
47
|
+
useEffect(() => {
|
|
48
|
+
setStatus("loading");
|
|
49
|
+
setShowSkeleton(true);
|
|
50
|
+
}, [src]);
|
|
51
|
+
// When loaded, keep skeleton for a moment to allow cross-fade
|
|
52
|
+
useEffect(() => {
|
|
53
|
+
if (status === "loaded") {
|
|
54
|
+
const timer = setTimeout(() => {
|
|
55
|
+
setShowSkeleton(false);
|
|
56
|
+
}, 500); // 500ms delay to allow image to fade in completely
|
|
57
|
+
return () => clearTimeout(timer);
|
|
58
|
+
}
|
|
59
|
+
}, [status]);
|
|
60
|
+
const handleLoad = useCallback(async (e) => {
|
|
61
|
+
onLoad === null || onLoad === void 0 ? void 0 : onLoad(e);
|
|
62
|
+
const img = e.currentTarget;
|
|
63
|
+
try {
|
|
64
|
+
if (img.decode) {
|
|
65
|
+
await img.decode();
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
// ignore decode errors (e.g. invalid image data)
|
|
70
|
+
}
|
|
71
|
+
finally {
|
|
72
|
+
setStatus("loaded");
|
|
73
|
+
}
|
|
74
|
+
}, [onLoad]);
|
|
75
|
+
const handleError = useCallback((e) => {
|
|
76
|
+
if (fallbackSrc && status !== "error") {
|
|
77
|
+
// Prevents infinite loop if fallback also fails
|
|
78
|
+
if (e.currentTarget.src !== fallbackSrc) {
|
|
79
|
+
e.currentTarget.src = fallbackSrc;
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
setStatus("error");
|
|
84
|
+
setShowSkeleton(false); // Remove skeleton immediately on error to show broken image icon or alt
|
|
85
|
+
onError === null || onError === void 0 ? void 0 : onError(e);
|
|
86
|
+
}, [fallbackSrc, status, onError]);
|
|
87
|
+
return (_jsxs("div", { className: clsx(styles.wrapper, rounded && styles.rounded, className), style: Object.assign({ aspectRatio: computedAspectRatio, width: toCssValue(width), height: toCssValue(height) }, style), children: [_jsx("div", { className: clsx(styles.skeletonLayer, status === "loaded" && styles.fadeOut), "aria-hidden": "true", children: showSkeleton && (_jsx(Skeleton, { style: {
|
|
88
|
+
width: "100%",
|
|
89
|
+
height: "100%",
|
|
90
|
+
} })) }), _jsx("img", Object.assign({ src: src, alt: alt, className: clsx(styles.image, fit && styles[`fit-${fit}`], status === "loaded" ? styles.visible : styles.hidden), onLoad: handleLoad, onError: handleError, width: width, height: height }, props))] }));
|
|
91
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
.image {
|
|
2
|
+
display: block;
|
|
3
|
+
width: 100%;
|
|
4
|
+
height: 100%;
|
|
5
|
+
opacity: 0;
|
|
6
|
+
transition: opacity 0.5s ease-in-out;
|
|
7
|
+
background-color: transparent;
|
|
8
|
+
}
|
|
9
|
+
.image.visible {
|
|
10
|
+
opacity: 1;
|
|
11
|
+
}
|
|
12
|
+
.image.hidden {
|
|
13
|
+
opacity: 0;
|
|
14
|
+
}
|
|
15
|
+
.image.fit-cover {
|
|
16
|
+
object-fit: cover;
|
|
17
|
+
}
|
|
18
|
+
.image.fit-contain {
|
|
19
|
+
object-fit: contain;
|
|
20
|
+
}
|
|
21
|
+
.image.fit-fill {
|
|
22
|
+
object-fit: fill;
|
|
23
|
+
}
|
|
24
|
+
.image.fit-none {
|
|
25
|
+
object-fit: none;
|
|
26
|
+
}
|
|
27
|
+
.image.fit-scale-down {
|
|
28
|
+
object-fit: scale-down;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.wrapper {
|
|
32
|
+
position: relative;
|
|
33
|
+
display: block;
|
|
34
|
+
overflow: hidden;
|
|
35
|
+
background-color: var(--surface-accent);
|
|
36
|
+
isolation: isolate;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.skeletonLayer {
|
|
40
|
+
position: absolute;
|
|
41
|
+
inset: 0;
|
|
42
|
+
width: 100%;
|
|
43
|
+
height: 100%;
|
|
44
|
+
z-index: 1;
|
|
45
|
+
pointer-events: none;
|
|
46
|
+
transition: opacity 0.5s ease-in-out;
|
|
47
|
+
opacity: 1;
|
|
48
|
+
}
|
|
49
|
+
.skeletonLayer.fadeOut {
|
|
50
|
+
opacity: 0;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.rounded {
|
|
54
|
+
border-radius: var(--radius);
|
|
55
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./Image";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./Image.js";
|
|
@@ -1,18 +1,32 @@
|
|
|
1
1
|
import React, { ElementType } from "react";
|
|
2
|
+
declare const SPACING_MAP: {
|
|
3
|
+
readonly 0: "0";
|
|
4
|
+
readonly 1: "0.25rem";
|
|
5
|
+
readonly 2: "0.5rem";
|
|
6
|
+
readonly 3: "0.75rem";
|
|
7
|
+
readonly 4: "1rem";
|
|
8
|
+
readonly 5: "1.25rem";
|
|
9
|
+
readonly 6: "1.5rem";
|
|
10
|
+
readonly 8: "2rem";
|
|
11
|
+
readonly 10: "2.5rem";
|
|
12
|
+
readonly 12: "3rem";
|
|
13
|
+
readonly 16: "4rem";
|
|
14
|
+
};
|
|
15
|
+
export type Spacing = keyof typeof SPACING_MAP;
|
|
2
16
|
interface LayoutProps extends React.HTMLAttributes<HTMLElement> {
|
|
3
17
|
children?: React.ReactNode;
|
|
4
18
|
as?: ElementType;
|
|
5
19
|
}
|
|
6
20
|
export interface GridProps extends LayoutProps {
|
|
7
21
|
columns?: string | number;
|
|
8
|
-
gap?:
|
|
22
|
+
gap?: Spacing;
|
|
9
23
|
}
|
|
10
24
|
export declare function Grid({ children, columns, gap, className, style, as: Component, ...props }: GridProps): import("react/jsx-runtime").JSX.Element;
|
|
11
25
|
export interface FlexProps extends LayoutProps {
|
|
12
26
|
direction?: "row" | "column" | "row-reverse" | "column-reverse";
|
|
13
27
|
justify?: "flex-start" | "flex-end" | "center" | "space-between" | "space-around" | "space-evenly";
|
|
14
28
|
align?: "flex-start" | "flex-end" | "center" | "stretch" | "baseline";
|
|
15
|
-
gap?:
|
|
29
|
+
gap?: Spacing;
|
|
16
30
|
wrap?: boolean | "wrap" | "nowrap" | "wrap-reverse";
|
|
17
31
|
}
|
|
18
32
|
export declare function Flex({ children, direction, justify, align, gap, wrap, className, style, as: Component, ...props }: FlexProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -13,20 +13,37 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
13
13
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
14
14
|
import clsx from "clsx";
|
|
15
15
|
import styles from "./Layout.module.css";
|
|
16
|
+
// --- Tokens ---
|
|
17
|
+
const SPACING_MAP = {
|
|
18
|
+
0: "0",
|
|
19
|
+
1: "0.25rem",
|
|
20
|
+
2: "0.5rem",
|
|
21
|
+
3: "0.75rem",
|
|
22
|
+
4: "1rem",
|
|
23
|
+
5: "1.25rem",
|
|
24
|
+
6: "1.5rem",
|
|
25
|
+
8: "2rem",
|
|
26
|
+
10: "2.5rem",
|
|
27
|
+
12: "3rem",
|
|
28
|
+
16: "4rem",
|
|
29
|
+
};
|
|
30
|
+
function resolveGap(gap) {
|
|
31
|
+
if (gap === undefined)
|
|
32
|
+
return undefined;
|
|
33
|
+
return SPACING_MAP[gap];
|
|
34
|
+
}
|
|
16
35
|
export function Grid(_a) {
|
|
17
|
-
var { children, columns = "1fr", gap =
|
|
36
|
+
var { children, columns = "1fr", gap = 4, className, style, as: Component = "div" } = _a, props = __rest(_a, ["children", "columns", "gap", "className", "style", "as"]);
|
|
18
37
|
const gridTemplateColumns = typeof columns === "number" ? `repeat(${columns}, 1fr)` : columns;
|
|
19
|
-
return (_jsx(Component, Object.assign({ className: clsx(styles.grid, className), style: Object.assign({ gridTemplateColumns,
|
|
20
|
-
gap }, style) }, props, { children: children })));
|
|
38
|
+
return (_jsx(Component, Object.assign({ className: clsx(styles.grid, className), style: Object.assign({ gridTemplateColumns, gap: resolveGap(gap) }, style) }, props, { children: children })));
|
|
21
39
|
}
|
|
22
40
|
export function Flex(_a) {
|
|
23
|
-
var { children, direction = "row", justify = "flex-start", align = "stretch", gap =
|
|
41
|
+
var { children, direction = "row", justify = "flex-start", align = "stretch", gap = 0, wrap = false, className, style, as: Component = "div" } = _a, props = __rest(_a, ["children", "direction", "justify", "align", "gap", "wrap", "className", "style", "as"]);
|
|
24
42
|
const flexWrap = typeof wrap === "boolean" ? (wrap ? "wrap" : "nowrap") : wrap;
|
|
25
|
-
return (_jsx(Component, Object.assign({ className: clsx(styles.flex, className), style: Object.assign({ flexDirection: direction, justifyContent: justify, alignItems: align, gap,
|
|
26
|
-
flexWrap }, style) }, props, { children: children })));
|
|
43
|
+
return (_jsx(Component, Object.assign({ className: clsx(styles.flex, className), style: Object.assign({ flexDirection: direction, justifyContent: justify, alignItems: align, gap: resolveGap(gap), flexWrap }, style) }, props, { children: children })));
|
|
27
44
|
}
|
|
28
45
|
export function Stack(_a) {
|
|
29
|
-
var { children, direction = "column", gap =
|
|
46
|
+
var { children, direction = "column", gap = 4, align = "stretch" } = _a, props = __rest(_a, ["children", "direction", "gap", "align"]);
|
|
30
47
|
return (_jsx(Flex, Object.assign({ direction: direction, gap: gap, align: align }, props, { children: children })));
|
|
31
48
|
}
|
|
32
49
|
export function Switcher(_a) {
|
|
@@ -1,9 +1,12 @@
|
|
|
1
|
-
import React from
|
|
2
|
-
export type LinkVariant =
|
|
1
|
+
import React from "react";
|
|
2
|
+
export type LinkVariant = "default" | "button" | "subtle";
|
|
3
3
|
interface LinkProps extends React.AnchorHTMLAttributes<HTMLAnchorElement> {
|
|
4
4
|
children: React.ReactNode;
|
|
5
5
|
variant?: LinkVariant;
|
|
6
|
+
prefetch?: boolean;
|
|
7
|
+
isExternal?: boolean;
|
|
8
|
+
disabled?: boolean;
|
|
6
9
|
className?: string;
|
|
7
10
|
}
|
|
8
|
-
export declare function Link({ children, variant, className, ...props }: LinkProps): import("react/jsx-runtime").JSX.Element;
|
|
11
|
+
export declare function Link({ children, variant, prefetch, isExternal, disabled, className, onClick, onMouseEnter, ...props }: LinkProps): import("react/jsx-runtime").JSX.Element;
|
|
9
12
|
export {};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
"use client";
|
|
2
2
|
var __rest = (this && this.__rest) || function (s, e) {
|
|
3
3
|
var t = {};
|
|
4
4
|
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
@@ -10,10 +10,31 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
10
10
|
}
|
|
11
11
|
return t;
|
|
12
12
|
};
|
|
13
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
14
|
-
import clsx from
|
|
15
|
-
import styles from
|
|
13
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
14
|
+
import clsx from "clsx";
|
|
15
|
+
import styles from "./Link.module.css";
|
|
16
|
+
import React from "react";
|
|
17
|
+
import { ExternalLink } from "lucide-react";
|
|
16
18
|
export function Link(_a) {
|
|
17
|
-
var { children, variant =
|
|
18
|
-
|
|
19
|
+
var { children, variant = "default", prefetch, isExternal, disabled, className, onClick, onMouseEnter } = _a, props = __rest(_a, ["children", "variant", "prefetch", "isExternal", "disabled", "className", "onClick", "onMouseEnter"]);
|
|
20
|
+
const [shouldPrefetch, setShouldPrefetch] = React.useState(false);
|
|
21
|
+
const handleMouseEnter = (e) => {
|
|
22
|
+
if (disabled)
|
|
23
|
+
return;
|
|
24
|
+
if (prefetch && !shouldPrefetch) {
|
|
25
|
+
setShouldPrefetch(true);
|
|
26
|
+
}
|
|
27
|
+
onMouseEnter === null || onMouseEnter === void 0 ? void 0 : onMouseEnter(e);
|
|
28
|
+
};
|
|
29
|
+
const handleClick = (e) => {
|
|
30
|
+
if (disabled) {
|
|
31
|
+
e.preventDefault();
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
onClick === null || onClick === void 0 ? void 0 : onClick(e);
|
|
35
|
+
};
|
|
36
|
+
const externalProps = isExternal
|
|
37
|
+
? { target: "_blank", rel: "noopener noreferrer" }
|
|
38
|
+
: {};
|
|
39
|
+
return (_jsxs("a", Object.assign({ className: clsx(styles.link, styles[variant], disabled && styles.disabled, className), onMouseEnter: handleMouseEnter, onClick: handleClick, "aria-disabled": disabled }, externalProps, props, { children: [children, isExternal && _jsx(ExternalLink, { size: 14, className: "ml-1" }), shouldPrefetch && props.href && (_jsx("link", { rel: "prefetch", href: props.href, as: "document" }))] })));
|
|
19
40
|
}
|
|
@@ -2,10 +2,19 @@
|
|
|
2
2
|
display: inline-flex;
|
|
3
3
|
align-items: center;
|
|
4
4
|
justify-content: center;
|
|
5
|
-
font-weight: 700;
|
|
6
5
|
text-decoration: none;
|
|
7
6
|
transition: all 0.2s ease-in-out;
|
|
8
7
|
cursor: pointer;
|
|
8
|
+
outline: none;
|
|
9
|
+
}
|
|
10
|
+
.link:focus-visible {
|
|
11
|
+
outline: revert;
|
|
12
|
+
}
|
|
13
|
+
.link.disabled {
|
|
14
|
+
pointer-events: none;
|
|
15
|
+
opacity: 0.5;
|
|
16
|
+
text-decoration: none;
|
|
17
|
+
cursor: not-allowed;
|
|
9
18
|
}
|
|
10
19
|
.link.default {
|
|
11
20
|
color: var(--primary);
|
|
@@ -31,7 +31,7 @@ export function ModalBody({ children, className, }) {
|
|
|
31
31
|
return _jsx("div", { className: clsx(styles.body, className), children: children });
|
|
32
32
|
}
|
|
33
33
|
export function ModalFooter({ children, className, }) {
|
|
34
|
-
return (_jsx(Flex, { justify: "flex-end", align: "center", gap:
|
|
34
|
+
return (_jsx(Flex, { justify: "flex-end", align: "center", gap: 4, className: clsx(styles.footer, className), children: children }));
|
|
35
35
|
}
|
|
36
36
|
export function Modal(_a) {
|
|
37
37
|
var { isOpen, onClose, title, children, footer, className, style, variant = "default" } = _a, props = __rest(_a, ["isOpen", "onClose", "title", "children", "footer", "className", "style", "variant"]);
|
|
@@ -22,6 +22,6 @@ export const Slat = React.forwardRef((_a, ref) => {
|
|
|
22
22
|
e.preventDefault();
|
|
23
23
|
onClick(e);
|
|
24
24
|
}
|
|
25
|
-
} }, props, { children: _jsxs(Flex, { justify: "space-between", align: "center", gap:
|
|
25
|
+
} }, props, { children: _jsxs(Flex, { justify: "space-between", align: "center", gap: 2, children: [_jsxs(Flex, { gap: 2, align: "center", style: { flex: 1, minWidth: 0 }, children: [prependContent && (_jsx("div", { className: styles.prepend, children: prependContent })), _jsxs(Stack, { gap: 0, style: { flex: 1, minWidth: 0 }, children: [_jsx(Text, { className: styles.label, children: label }), secondaryLabel && (_jsx(Text, { variant: "small", className: styles.secondaryLabel, children: secondaryLabel }))] })] }), _jsx(Flex, { align: "center", gap: 2, children: appendContent && (_jsx("div", { className: styles.append, children: appendContent })) })] }) })));
|
|
26
26
|
});
|
|
27
27
|
Slat.displayName = "Slat";
|
|
@@ -45,7 +45,7 @@ export function Table({ data, columns, enablePagination = true, enableFiltering
|
|
|
45
45
|
overscan: 5,
|
|
46
46
|
});
|
|
47
47
|
const isVirtual = !!height;
|
|
48
|
-
return (_jsxs("div", { className: clsx(styles.container, variant === "flat" && styles.flat, className), style: style, children: [enableFiltering && (_jsxs("div", { className: styles.toolbar, children: [_jsx("div", { style: { width: "300px" }, children: _jsx(Input, { placeholder: "Search...", value: globalFilter !== null && globalFilter !== void 0 ? globalFilter : "", onChange: (e) => setGlobalFilter(e.target.value) }) }), toolbarContent && (_jsx(Flex, { gap:
|
|
48
|
+
return (_jsxs("div", { className: clsx(styles.container, variant === "flat" && styles.flat, className), style: style, children: [enableFiltering && (_jsxs("div", { className: styles.toolbar, children: [_jsx("div", { style: { width: "300px" }, children: _jsx(Input, { placeholder: "Search...", value: globalFilter !== null && globalFilter !== void 0 ? globalFilter : "", onChange: (e) => setGlobalFilter(e.target.value) }) }), toolbarContent && (_jsx(Flex, { gap: 4, align: "center", children: toolbarContent }))] })), _jsxs("div", { ref: parentRef, tabIndex: 0, style: {
|
|
49
49
|
height: height ? height : "auto",
|
|
50
50
|
overflowY: height ? "auto" : "visible",
|
|
51
51
|
overflowX: "auto",
|
|
@@ -68,7 +68,7 @@ export function Table({ data, columns, enablePagination = true, enableFiltering
|
|
|
68
68
|
}), rowVirtualizer.getVirtualItems().length > 0 && (_jsx("tr", { style: {
|
|
69
69
|
height: `${rowVirtualizer.getTotalSize() -
|
|
70
70
|
rowVirtualizer.getVirtualItems()[rowVirtualizer.getVirtualItems().length - 1].end}px`,
|
|
71
|
-
}, children: _jsx("td", { colSpan: columns.length, style: { border: 0, padding: 0 } }) }))] })) : (_jsx("tbody", { children: table.getRowModel().rows.map((row) => (_jsx("tr", { className: clsx(styles.tr, striped && styles.striped, "group"), children: row.getVisibleCells().map((cell) => (_jsx("td", { className: clsx(styles.td, styles[density]), children: flexRender(cell.column.columnDef.cell, cell.getContext()) }, cell.id))) }, row.id))) }))] }), table.getRowModel().rows.length === 0 && (_jsx("div", { className: styles.noResults, children: "No results found." }))] }), enablePagination && !isVirtual && (_jsx("div", { className: styles.paginationContainer, children: _jsxs(Flex, { gap:
|
|
71
|
+
}, children: _jsx("td", { colSpan: columns.length, style: { border: 0, padding: 0 } }) }))] })) : (_jsx("tbody", { children: table.getRowModel().rows.map((row) => (_jsx("tr", { className: clsx(styles.tr, striped && styles.striped, "group"), children: row.getVisibleCells().map((cell) => (_jsx("td", { className: clsx(styles.td, styles[density]), children: flexRender(cell.column.columnDef.cell, cell.getContext()) }, cell.id))) }, row.id))) }))] }), table.getRowModel().rows.length === 0 && (_jsx("div", { className: styles.noResults, children: "No results found." }))] }), enablePagination && !isVirtual && (_jsx("div", { className: styles.paginationContainer, children: _jsxs(Flex, { gap: 4, align: "center", style: { width: "100%", justifyContent: "space-between" }, children: [_jsx("div", { style: { flexShrink: 0 }, children: _jsx(Select, { value: table.getState().pagination.pageSize, onChange: (e) => {
|
|
72
72
|
table.setPageSize(Number(e.target.value));
|
|
73
73
|
}, options: [
|
|
74
74
|
{ value: 10, label: "10 rows" },
|
package/dist/index.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ export * from "./components/Card";
|
|
|
4
4
|
export * from "./components/Dropdown";
|
|
5
5
|
export * from "./components/Form";
|
|
6
6
|
export * from "./components/Input";
|
|
7
|
+
export * from "./components/Image";
|
|
7
8
|
export * from "./components/Layout";
|
|
8
9
|
export * from "./components/Link";
|
|
9
10
|
export * from "./components/Modal";
|
package/dist/index.js
CHANGED
|
@@ -4,6 +4,7 @@ export * from "./components/Card/index.js";
|
|
|
4
4
|
export * from "./components/Dropdown/index.js";
|
|
5
5
|
export * from "./components/Form/index.js";
|
|
6
6
|
export * from "./components/Input/index.js";
|
|
7
|
+
export * from "./components/Image/index.js";
|
|
7
8
|
export * from "./components/Layout/index.js";
|
|
8
9
|
export * from "./components/Link/index.js";
|
|
9
10
|
export * from "./components/Modal/index.js";
|