@thecodecodex/design-system 0.1.0 → 0.2.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 +64 -2
- package/dist/components/AppShell.d.ts +32 -0
- package/dist/components/AppShell.js +28 -0
- package/dist/components/Button.d.ts +10 -0
- package/dist/components/Button.js +20 -0
- package/dist/components/ChipToggles.d.ts +11 -0
- package/dist/components/ChipToggles.js +9 -0
- package/dist/components/ConfirmDialog.d.ts +14 -0
- package/dist/components/ConfirmDialog.js +10 -0
- package/dist/components/CopyButton.d.ts +10 -0
- package/dist/components/CopyButton.js +12 -0
- package/dist/components/DataGrid.d.ts +15 -0
- package/dist/components/DataGrid.js +54 -0
- package/dist/components/Dialog.d.ts +15 -0
- package/dist/components/Dialog.js +26 -0
- package/dist/components/Disclosure.d.ts +25 -0
- package/dist/components/Disclosure.js +12 -0
- package/dist/components/LogView.d.ts +14 -0
- package/dist/components/LogView.js +36 -0
- package/dist/components/Markdown.d.ts +4 -0
- package/dist/components/Markdown.js +119 -0
- package/dist/components/Meter.d.ts +7 -0
- package/dist/components/Meter.js +7 -0
- package/dist/components/Notice.d.ts +9 -0
- package/dist/components/Notice.js +19 -0
- package/dist/components/PageHeader.d.ts +7 -0
- package/dist/components/PageHeader.js +5 -0
- package/dist/components/Popover.d.ts +16 -0
- package/dist/components/Popover.js +31 -0
- package/dist/components/SearchField.d.ts +8 -0
- package/dist/components/SearchField.js +8 -0
- package/dist/components/SectionPanel.d.ts +13 -0
- package/dist/components/SectionPanel.js +9 -0
- package/dist/components/Segmented.d.ts +12 -6
- package/dist/components/Segmented.js +7 -3
- package/dist/components/Stat.d.ts +12 -0
- package/dist/components/Stat.js +7 -0
- package/dist/components/StatusTag.d.ts +15 -0
- package/dist/components/StatusTag.js +28 -0
- package/dist/components/Tabs.d.ts +12 -0
- package/dist/components/Tabs.js +12 -0
- package/dist/components/ThemeMenu.d.ts +4 -0
- package/dist/components/ThemeMenu.js +52 -0
- package/dist/components/Toast.d.ts +5 -0
- package/dist/components/Toast.js +6 -0
- package/dist/components/icons.d.ts +19 -0
- package/dist/components/icons.js +17 -0
- package/dist/components/index.d.ts +21 -0
- package/dist/components/index.js +21 -0
- package/dist/components/labels.d.ts +42 -0
- package/dist/components/labels.js +34 -0
- package/package.json +24 -9
- package/src/styles/base.css +1 -37
- package/src/styles/content.css +39 -0
- package/src/styles/index.css +1 -0
- package/src/styles/raw.d.ts +5 -0
- package/src/styles/themes.css +30 -0
- package/src/styles/themes.test.ts +25 -0
- package/src/styles/tokens.css +10 -0
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
export type NoticeTone = "ok" | "warn" | "danger" | "info";
|
|
3
|
+
export default function Notice({ tone, title, children, role, className }: {
|
|
4
|
+
tone?: NoticeTone;
|
|
5
|
+
title?: ReactNode;
|
|
6
|
+
children?: ReactNode;
|
|
7
|
+
role?: "status" | "alert";
|
|
8
|
+
className?: string;
|
|
9
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
const STYLE = {
|
|
3
|
+
ok: { box: "bg-ok-soft border-ok", icon: "text-ok" },
|
|
4
|
+
warn: { box: "bg-warn-soft border-warn", icon: "text-warn" },
|
|
5
|
+
danger: { box: "bg-danger-soft border-danger", icon: "text-danger" },
|
|
6
|
+
info: { box: "bg-info-soft border-info", icon: "text-info" },
|
|
7
|
+
};
|
|
8
|
+
// Ícones (stroke, 24×24) por tom: check, triângulo, octógono, "i"
|
|
9
|
+
const ICON = {
|
|
10
|
+
ok: _jsxs(_Fragment, { children: [_jsx("circle", { cx: "12", cy: "12", r: "9" }), _jsx("path", { d: "m8.5 12 2.5 2.5 4.5-5" })] }),
|
|
11
|
+
warn: _jsxs(_Fragment, { children: [_jsx("path", { d: "m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3" }), _jsx("path", { d: "M12 9v4M12 17h.01" })] }),
|
|
12
|
+
danger: _jsxs(_Fragment, { children: [_jsx("path", { d: "M7.86 2h8.28L22 7.86v8.28L16.14 22H7.86L2 16.14V7.86z" }), _jsx("path", { d: "M12 8v4M12 16h.01" })] }),
|
|
13
|
+
info: _jsxs(_Fragment, { children: [_jsx("circle", { cx: "12", cy: "12", r: "9" }), _jsx("path", { d: "M12 16v-4M12 8h.01" })] }),
|
|
14
|
+
};
|
|
15
|
+
// Faixa de aviso/resultado: fundo suave do tom, borda e ícone; o texto fica na cor do tema
|
|
16
|
+
export default function Notice({ tone = "info", title, children, role, className = "" }) {
|
|
17
|
+
const { box, icon } = STYLE[tone];
|
|
18
|
+
return (_jsxs("div", { role: role, className: `flex items-start gap-3 rounded-[14px] border-[1.5px] px-4 py-3 text-sm leading-relaxed text-text-primary ${box} ${className}`, children: [_jsx("svg", { "aria-hidden": "true", width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className: `mt-0.5 shrink-0 ${icon}`, children: ICON[tone] }), _jsxs("div", { className: "min-w-0 flex-1 space-y-1", children: [title && _jsx("div", { className: "font-bold", children: title }), children] })] }));
|
|
19
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
// Título da tela (Roboto 900, caixa alta) + descrição + ações à direita
|
|
3
|
+
export default function PageHeader({ title, description, actions, eyebrow }) {
|
|
4
|
+
return (_jsxs("div", { className: "flex flex-wrap items-end justify-between gap-x-6 gap-y-4", children: [_jsxs("div", { className: "flex min-w-0 flex-col gap-2.5", children: [eyebrow && _jsx("span", { className: "font-mono text-[13px] font-semibold text-btn-primary", children: eyebrow }), _jsx("h1", { className: "m-0 font-display text-[clamp(1.75rem,3.5vw,2.5rem)] font-black uppercase leading-none", children: title }), description && _jsx("p", { className: "m-0 max-w-3xl text-[15px] leading-relaxed text-text-secondary", children: description })] }), actions && _jsx("div", { className: "flex flex-wrap items-center gap-2", children: actions })] }));
|
|
5
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
export default function Popover({ trigger, triggerLabel, triggerClass, role, panelLabel, align, width, children }: {
|
|
3
|
+
trigger: ReactNode;
|
|
4
|
+
triggerLabel?: string;
|
|
5
|
+
triggerClass?: string;
|
|
6
|
+
role?: "dialog" | "menu";
|
|
7
|
+
panelLabel: string;
|
|
8
|
+
align?: "left" | "right";
|
|
9
|
+
width?: string;
|
|
10
|
+
children: (close: () => void) => ReactNode;
|
|
11
|
+
}): import("react").JSX.Element;
|
|
12
|
+
export declare function MenuItem({ onSelect, danger, children }: {
|
|
13
|
+
onSelect: () => void;
|
|
14
|
+
danger?: boolean;
|
|
15
|
+
children: ReactNode;
|
|
16
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect, useRef, useState } from "react";
|
|
4
|
+
// Botão que abre um painel ancorado (menu, seletor): fecha com Esc, clique fora ou pela função `close`
|
|
5
|
+
export default function Popover({ trigger, triggerLabel, triggerClass, role = "dialog", panelLabel, align = "right", width = "w-[320px]", children }) {
|
|
6
|
+
const [open, setOpen] = useState(false);
|
|
7
|
+
const root = useRef(null);
|
|
8
|
+
useEffect(() => {
|
|
9
|
+
if (!open)
|
|
10
|
+
return;
|
|
11
|
+
const outside = (e) => {
|
|
12
|
+
if (root.current && !root.current.contains(e.target))
|
|
13
|
+
setOpen(false);
|
|
14
|
+
};
|
|
15
|
+
const esc = (e) => {
|
|
16
|
+
if (e.key === "Escape")
|
|
17
|
+
setOpen(false);
|
|
18
|
+
};
|
|
19
|
+
document.addEventListener("mousedown", outside);
|
|
20
|
+
document.addEventListener("keydown", esc);
|
|
21
|
+
return () => {
|
|
22
|
+
document.removeEventListener("mousedown", outside);
|
|
23
|
+
document.removeEventListener("keydown", esc);
|
|
24
|
+
};
|
|
25
|
+
}, [open]);
|
|
26
|
+
return (_jsxs("div", { ref: root, className: "relative", children: [_jsx("button", { type: "button", onClick: () => setOpen(!open), "aria-haspopup": role, "aria-expanded": open, "aria-label": triggerLabel, className: triggerClass ?? "inline-flex min-h-11 items-center gap-2 whitespace-nowrap rounded-[10px] border-2 border-border bg-surface px-3.5 text-sm font-bold text-text-primary hover:border-contrast", children: trigger }), open && (_jsx("div", { role: role, "aria-label": panelLabel, className: `absolute z-40 mt-2 ${width} max-w-[calc(100vw-32px)] rounded-[14px] border-2 border-border bg-surface p-2 text-text-primary shadow-[4px_4px_0_var(--border)] ${align === "right" ? "right-0" : "left-0"}`, children: children(() => setOpen(false)) }))] }));
|
|
27
|
+
}
|
|
28
|
+
// Item de menu dentro do Popover (role="menu")
|
|
29
|
+
export function MenuItem({ onSelect, danger = false, children }) {
|
|
30
|
+
return (_jsx("button", { type: "button", role: "menuitem", onClick: onSelect, className: `flex min-h-10 w-full items-center gap-2 rounded-[8px] px-3 text-left text-sm font-semibold hover:bg-inset ${danger ? "text-danger" : "text-text-primary"}`, children: children }));
|
|
31
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export default function SearchField({ label, value, onValue, placeholder, size, className }: {
|
|
2
|
+
label: string;
|
|
3
|
+
value: string;
|
|
4
|
+
onValue: (value: string) => void;
|
|
5
|
+
placeholder?: string;
|
|
6
|
+
size?: "md" | "sm";
|
|
7
|
+
className?: string;
|
|
8
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { Icon } from "./icons.js";
|
|
4
|
+
import { onTextInput } from "./textInput.js";
|
|
5
|
+
// Busca com ícone: o rótulo é lido por leitores de tela e vira o placeholder quando não há outro
|
|
6
|
+
export default function SearchField({ label, value, onValue, placeholder, size = "md", className = "" }) {
|
|
7
|
+
return (_jsxs("label", { className: `flex items-center gap-2 rounded-[10px] border-2 border-border bg-surface px-3 focus-within:border-contrast ${size === "md" ? "min-h-11" : "min-h-9"} ${className}`, children: [_jsx("span", { className: "sr-only", children: label }), _jsx(Icon, { name: "search", size: size === "md" ? 16 : 14, className: "text-text-secondary" }), _jsx("input", { type: "search", value: value, placeholder: placeholder ?? label, className: `min-w-0 flex-1 bg-transparent outline-none ${size === "md" ? "text-sm" : "text-[13px]"}`, ...onTextInput(onValue) })] }));
|
|
8
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
interface Props {
|
|
3
|
+
title?: ReactNode;
|
|
4
|
+
count?: number;
|
|
5
|
+
actions?: ReactNode;
|
|
6
|
+
bodyClass?: string;
|
|
7
|
+
className?: string;
|
|
8
|
+
id?: string;
|
|
9
|
+
children?: ReactNode;
|
|
10
|
+
}
|
|
11
|
+
export default function Panel({ title, count, actions, bodyClass, className, id, children }: Props): import("react").JSX.Element;
|
|
12
|
+
export declare const panelRows = "flex flex-col [&>*+*]:border-t-[1.5px] [&>*+*]:border-soft";
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { panel, panelHeader } from "./panel.js";
|
|
3
|
+
// Painel com faixa de título opcional: superfície com borda suave sobre o fundo da página
|
|
4
|
+
export default function Panel({ title, count, actions, bodyClass = "p-5 sm:p-6", className = "", id, children }) {
|
|
5
|
+
const titleId = id ? `${id}-title` : undefined;
|
|
6
|
+
return (_jsxs("section", { id: id, "aria-labelledby": title ? titleId : undefined, className: `${panel} min-w-0 ${className}`, children: [title && (_jsxs("div", { className: `${panelHeader} flex-wrap justify-between`, children: [_jsxs("h2", { id: titleId, className: "m-0 text-sm font-extrabold", children: [title, count !== undefined && _jsx("span", { className: "ml-2 font-mono font-semibold normal-case tracking-normal text-text-secondary", children: count })] }), actions && _jsx("div", { className: "flex flex-wrap items-center gap-2 font-body font-bold normal-case tracking-normal", children: actions })] })), children !== undefined && _jsx("div", { className: bodyClass, children: children })] }));
|
|
7
|
+
}
|
|
8
|
+
// Linhas de uma lista dentro de um painel: divisória suave entre itens
|
|
9
|
+
export const panelRows = "flex flex-col [&>*+*]:border-t-[1.5px] [&>*+*]:border-soft";
|
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
import type { ReactNode } from "react";
|
|
2
|
+
interface Option<T> {
|
|
3
|
+
value: T;
|
|
4
|
+
label: ReactNode;
|
|
5
|
+
description?: ReactNode;
|
|
6
|
+
tone?: "danger";
|
|
7
|
+
}
|
|
2
8
|
interface Props<T extends string | number> {
|
|
3
9
|
label: ReactNode;
|
|
4
10
|
value: T;
|
|
5
|
-
options:
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
11
|
+
options: Option<T>[];
|
|
12
|
+
onValue: (value: NoInfer<T>) => void;
|
|
13
|
+
hideLabel?: boolean;
|
|
14
|
+
size?: "md" | "sm";
|
|
15
|
+
disabled?: boolean;
|
|
10
16
|
}
|
|
11
|
-
export default function Segmented<T extends string | number>({ label, value, options, onValue }: Props<T>): import("react").JSX.Element;
|
|
17
|
+
export default function Segmented<T extends string | number>({ label, value, options, onValue, hideLabel, size, disabled }: Props<T>): import("react").JSX.Element;
|
|
12
18
|
export {};
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
// Grupo de opções exclusivas (radio) com cara de botões
|
|
4
|
-
export default function Segmented({ label, value, options, onValue }) {
|
|
5
|
-
return (_jsxs("fieldset", { className: "flex flex-col gap-1.5", children: [_jsx("legend", { className: "mb-1.5 text-sm font-semibold", children: label }), _jsx("div", { className: "flex flex-wrap gap-2", children: options.map((option) => {
|
|
4
|
+
export default function Segmented({ label, value, options, onValue, hideLabel = false, size = "md", disabled = false }) {
|
|
5
|
+
return (_jsxs("fieldset", { className: "flex min-w-0 flex-col gap-1.5", disabled: disabled, children: [_jsx("legend", { className: hideLabel ? "sr-only" : "mb-1.5 text-sm font-semibold", children: label }), _jsx("div", { className: "flex flex-wrap gap-2", children: options.map((option) => {
|
|
6
6
|
const active = option.value === value;
|
|
7
|
-
|
|
7
|
+
const danger = option.tone === "danger";
|
|
8
|
+
const colors = active
|
|
9
|
+
? danger ? "border-danger bg-danger text-bg-primary" : "border-border bg-text-primary text-bg-primary"
|
|
10
|
+
: danger ? "border-danger bg-bg-primary text-danger hover:bg-danger-soft" : "border-border bg-bg-primary hover:border-contrast";
|
|
11
|
+
return (_jsxs("label", { className: `inline-flex cursor-pointer flex-col justify-center rounded-[10px] border-2 font-bold has-[:disabled]:cursor-default has-[:disabled]:opacity-60 has-[:focus-visible]:outline-3 has-[:focus-visible]:outline-contrast ${size === "md" ? "min-h-11 px-3.5 text-sm" : "min-h-9 px-3 text-[13px]"} ${option.description ? "items-start py-2 text-left" : "items-center"} ${colors}`, children: [_jsx("input", { type: "radio", className: "sr-only", checked: active, onChange: () => onValue(option.value) }), option.label, option.description && _jsx("span", { className: `text-xs font-normal ${active ? "opacity-80" : "text-text-secondary"}`, children: option.description })] }, String(option.value)));
|
|
8
12
|
}) })] }));
|
|
9
13
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
import type { StatusTone } from "./StatusTag.js";
|
|
3
|
+
export default function Stat({ label, value, hint, tone, emphasis, mono, aside, className }: {
|
|
4
|
+
label: ReactNode;
|
|
5
|
+
value: ReactNode;
|
|
6
|
+
hint?: ReactNode;
|
|
7
|
+
tone?: StatusTone;
|
|
8
|
+
emphasis?: boolean;
|
|
9
|
+
mono?: boolean;
|
|
10
|
+
aside?: ReactNode;
|
|
11
|
+
className?: string;
|
|
12
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
const VALUE = { ok: "text-ok", warn: "text-warn", danger: "text-danger", info: "text-info", neutral: "" };
|
|
3
|
+
const BORDER = { ok: "border-ok", warn: "border-warn", danger: "border-danger", info: "border-info", neutral: "border-border" };
|
|
4
|
+
// Número-resumo: rótulo, valor grande (Roboto 900) e dica. emphasis destaca a borda no tom
|
|
5
|
+
export default function Stat({ label, value, hint, tone = "neutral", emphasis = false, mono = false, aside, className = "" }) {
|
|
6
|
+
return (_jsxs("div", { className: `flex items-center justify-between gap-3 rounded-[20px] bg-surface p-5 ${emphasis ? `border-2 ${BORDER[tone]}` : "border-[1.5px] border-soft"} ${className}`, children: [_jsxs("div", { className: "flex min-w-0 flex-col gap-1.5", children: [_jsx("span", { className: "text-[13px] text-text-secondary", children: label }), _jsx("span", { className: `${mono ? "font-mono text-xl font-semibold" : "font-display text-[34px] font-black leading-none"} ${VALUE[tone]}`, children: value }), hint && _jsx("span", { className: "text-xs text-text-secondary", children: hint })] }), aside] }));
|
|
7
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
export type StatusTone = "ok" | "warn" | "danger" | "info" | "neutral";
|
|
3
|
+
export declare function StatusMark({ tone, className }: {
|
|
4
|
+
tone: StatusTone;
|
|
5
|
+
className?: string;
|
|
6
|
+
}): import("react").JSX.Element;
|
|
7
|
+
export declare function StatusDot({ on, className }: {
|
|
8
|
+
on: boolean;
|
|
9
|
+
className?: string;
|
|
10
|
+
}): import("react").JSX.Element;
|
|
11
|
+
export default function StatusTag({ tone, children, className }: {
|
|
12
|
+
tone: StatusTone;
|
|
13
|
+
children: ReactNode;
|
|
14
|
+
className?: string;
|
|
15
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
const COLOR = {
|
|
3
|
+
ok: "text-ok",
|
|
4
|
+
warn: "text-warn",
|
|
5
|
+
danger: "text-danger",
|
|
6
|
+
info: "text-info",
|
|
7
|
+
neutral: "text-text-secondary",
|
|
8
|
+
};
|
|
9
|
+
// Marcador de forma por tom (círculo, triângulo, quadrado, anel): o status não depende só da cor.
|
|
10
|
+
// Herda a cor do texto (bg-current).
|
|
11
|
+
export function StatusMark({ tone, className = "" }) {
|
|
12
|
+
if (tone === "warn") {
|
|
13
|
+
return _jsx("span", { "aria-hidden": "true", className: `inline-block h-0 w-0 border-x-[4px] border-b-[7px] border-x-transparent border-b-current ${className}` });
|
|
14
|
+
}
|
|
15
|
+
if (tone === "danger")
|
|
16
|
+
return _jsx("span", { "aria-hidden": "true", className: `inline-block h-[7px] w-[7px] rounded-[2px] bg-current ${className}` });
|
|
17
|
+
if (tone === "neutral")
|
|
18
|
+
return _jsx("span", { "aria-hidden": "true", className: `inline-block h-[7px] w-[7px] rounded-full border-[1.5px] border-current ${className}` });
|
|
19
|
+
return _jsx("span", { "aria-hidden": "true", className: `inline-block h-[7px] w-[7px] rounded-full bg-current ${className}` });
|
|
20
|
+
}
|
|
21
|
+
// Ponto de ligado/desligado: cheio quando ligado, vazado quando desligado
|
|
22
|
+
export function StatusDot({ on, className = "" }) {
|
|
23
|
+
return _jsx("span", { "aria-hidden": "true", className: `inline-block h-2.5 w-2.5 shrink-0 rounded-full ${on ? "bg-ok" : "border-2 border-danger"} ${className}` });
|
|
24
|
+
}
|
|
25
|
+
// Selo de status: contorno na cor do tom, caixa alta, marcador de forma
|
|
26
|
+
export default function StatusTag({ tone, children, className = "" }) {
|
|
27
|
+
return (_jsxs("span", { className: `inline-flex items-center gap-1.5 whitespace-nowrap rounded-md border-[1.5px] border-current px-2 py-0.5 text-xs font-bold uppercase tracking-[0.06em] ${COLOR[tone]} ${className}`, children: [_jsx(StatusMark, { tone: tone }), children] }));
|
|
28
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
export default function Tabs<T extends string>({ label, items, value, onValue, variant, className }: {
|
|
3
|
+
label: string;
|
|
4
|
+
items: {
|
|
5
|
+
id: T;
|
|
6
|
+
label: ReactNode;
|
|
7
|
+
}[];
|
|
8
|
+
value: T;
|
|
9
|
+
onValue: (id: NoInfer<T>) => void;
|
|
10
|
+
variant?: "buttons" | "underline";
|
|
11
|
+
className?: string;
|
|
12
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
// Lista de abas. "buttons": botões com contorno (visões de uma tela) · "underline": sublinhado de contraste (arquivos, seções)
|
|
4
|
+
export default function Tabs({ label, items, value, onValue, variant = "buttons", className = "" }) {
|
|
5
|
+
return (_jsx("div", { role: "tablist", "aria-label": label, className: `flex flex-wrap ${variant === "buttons" ? "gap-2" : "gap-1"} ${className}`, children: items.map((item) => {
|
|
6
|
+
const active = item.id === value;
|
|
7
|
+
const style = variant === "buttons"
|
|
8
|
+
? `min-h-11 rounded-[10px] border-2 border-border px-4 text-sm ${active ? "bg-text-primary text-bg-primary" : "bg-surface text-text-primary hover:border-contrast"}`
|
|
9
|
+
: `min-h-11 px-2.5 text-[13px] ${active ? "text-text-primary shadow-[inset_0_-3px_0_var(--contrast)]" : "text-text-secondary hover:text-text-primary"}`;
|
|
10
|
+
return (_jsx("button", { type: "button", role: "tab", "aria-selected": active, onClick: () => onValue(item.id), className: `inline-flex items-center font-bold ${style}`, children: item.label }, item.id));
|
|
11
|
+
}) }));
|
|
12
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect, useState } from "react";
|
|
4
|
+
import { currentTheme, readPreference, setPreference, watchTheme } from "../theme/theme.js";
|
|
5
|
+
import { Icon } from "./icons.js";
|
|
6
|
+
import { themeMenuLabels } from "./labels.js";
|
|
7
|
+
import Popover from "./Popover.js";
|
|
8
|
+
// Amostra de cada tema: fundo e acento (valores de themes.css)
|
|
9
|
+
const SWATCH = {
|
|
10
|
+
claro: ["#ffffff", "#0e7490"],
|
|
11
|
+
papel: ["#f6f1e7", "#9a3412"],
|
|
12
|
+
crepusculo: ["#262130", "#f2a65a"],
|
|
13
|
+
escuro: ["#12151e", "#2dfdfd"],
|
|
14
|
+
contraste: ["#000000", "#ffe500"],
|
|
15
|
+
};
|
|
16
|
+
const OPTIONS = ["auto", "sistema", "claro", "papel", "crepusculo", "escuro", "contraste"];
|
|
17
|
+
// watchTheme registra timers e listeners globais: uma vez por aba, mesmo com o menu remontando a cada página
|
|
18
|
+
let watching = false;
|
|
19
|
+
const ICON_PROPS = { "aria-hidden": true, width: 13, height: 13, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round" };
|
|
20
|
+
function Swatch({ preference }) {
|
|
21
|
+
if (preference === "auto" || preference === "sistema") {
|
|
22
|
+
return (_jsx("span", { className: "flex h-[22px] w-[22px] shrink-0 items-center justify-center rounded-md border-[1.5px] border-border", children: preference === "auto"
|
|
23
|
+
? _jsxs("svg", { ...ICON_PROPS, children: [_jsx("circle", { cx: "12", cy: "12", r: "9" }), _jsx("path", { d: "M12 7v5l3 2" })] })
|
|
24
|
+
: _jsxs("svg", { ...ICON_PROPS, children: [_jsx("rect", { x: "3", y: "4", width: "18", height: "12", rx: "2" }), _jsx("path", { d: "M8 20h8M12 16v4" })] }) }));
|
|
25
|
+
}
|
|
26
|
+
const [ground, accent] = SWATCH[preference];
|
|
27
|
+
return _jsx("span", { "aria-hidden": "true", className: "h-[22px] w-[22px] shrink-0 rounded-md border-[1.5px] border-border", style: { background: `linear-gradient(135deg, ${ground} 55%, ${accent} 55%)` } });
|
|
28
|
+
}
|
|
29
|
+
// Botão "Tema" para cabeçalhos de apps React: Auto (por horário), Sistema e os 5 temas
|
|
30
|
+
export default function ThemeMenu({ labels }) {
|
|
31
|
+
const text = { ...themeMenuLabels, ...labels, names: { ...themeMenuLabels.names, ...labels?.names } };
|
|
32
|
+
const [preference, setPref] = useState("auto");
|
|
33
|
+
useEffect(() => {
|
|
34
|
+
setPref(readPreference());
|
|
35
|
+
if (!watching) {
|
|
36
|
+
watching = true;
|
|
37
|
+
watchTheme();
|
|
38
|
+
}
|
|
39
|
+
const onChange = (e) => setPref(e.detail.preference);
|
|
40
|
+
document.addEventListener("themechange", onChange);
|
|
41
|
+
return () => document.removeEventListener("themechange", onChange);
|
|
42
|
+
}, []);
|
|
43
|
+
const hint = (p) => p === "auto" ? text.autoHint.replace("{tema}", text.names[currentTheme("auto")]) : p === "sistema" ? text.systemHint : null;
|
|
44
|
+
return (_jsx(Popover, { role: "menu", panelLabel: text.title, width: "w-[280px]", trigger: _jsxs(_Fragment, { children: [_jsxs("svg", { "aria-hidden": "true", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [_jsx("circle", { cx: "12", cy: "12", r: "9" }), _jsx("path", { d: "M12 3a9 9 0 0 1 0 18z", fill: "currentColor" })] }), _jsx("span", { className: "hidden sm:inline", children: text.names[preference] }), _jsxs("span", { className: "sr-only sm:hidden", children: [text.title, ": ", text.names[preference]] }), _jsx(Icon, { name: "chevronDown", size: 14, className: "text-text-secondary" })] }), children: (close) => (_jsxs(_Fragment, { children: [_jsx("div", { className: "px-2.5 pb-1.5 pt-1 font-display text-xs font-extrabold uppercase tracking-[0.08em] text-text-secondary", children: text.title }), OPTIONS.map((p) => {
|
|
45
|
+
const active = p === preference;
|
|
46
|
+
return (_jsxs("button", { type: "button", role: "menuitemradio", "aria-checked": active, onClick: () => {
|
|
47
|
+
setPreference(p);
|
|
48
|
+
setPref(p);
|
|
49
|
+
close();
|
|
50
|
+
}, className: `flex w-full items-center gap-3 rounded-[10px] px-2.5 py-2 text-left text-sm ${active ? "bg-inset" : "hover:bg-inset"}`, children: [_jsx(Swatch, { preference: p }), _jsxs("span", { className: "flex min-w-0 flex-1 flex-col", children: [_jsx("span", { className: "font-semibold", children: text.names[p] }), hint(p) && _jsx("span", { className: "text-xs text-text-secondary", children: hint(p) })] }), active && _jsx(Icon, { name: "check" })] }, p));
|
|
51
|
+
})] })) }));
|
|
52
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
// Aviso flutuante no canto inferior direito; quem usa controla quando some
|
|
3
|
+
export default function Toast({ tone = "ok", children }) {
|
|
4
|
+
const color = { ok: "border-ok text-ok", danger: "border-danger text-danger", info: "border-info text-info" }[tone];
|
|
5
|
+
return (_jsx("div", { role: "status", className: `fixed bottom-12 right-5 z-50 flex max-w-[calc(100vw-40px)] items-center gap-2 rounded-[14px] border-2 bg-surface px-4 py-3 text-sm font-semibold shadow-[4px_4px_0_var(--border)] ${color}`, children: children }));
|
|
6
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
declare const PATHS: {
|
|
2
|
+
search: import("react").JSX.Element;
|
|
3
|
+
copy: import("react").JSX.Element;
|
|
4
|
+
check: import("react").JSX.Element;
|
|
5
|
+
download: import("react").JSX.Element;
|
|
6
|
+
close: import("react").JSX.Element;
|
|
7
|
+
chevronLeft: import("react").JSX.Element;
|
|
8
|
+
chevronRight: import("react").JSX.Element;
|
|
9
|
+
chevronDown: import("react").JSX.Element;
|
|
10
|
+
arrowLeft: import("react").JSX.Element;
|
|
11
|
+
arrowRight: import("react").JSX.Element;
|
|
12
|
+
};
|
|
13
|
+
export type IconName = keyof typeof PATHS;
|
|
14
|
+
export declare function Icon({ name, size, className }: {
|
|
15
|
+
name: IconName;
|
|
16
|
+
size?: number;
|
|
17
|
+
className?: string;
|
|
18
|
+
}): import("react").JSX.Element;
|
|
19
|
+
export {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
// Ícones de traço (24×24) usados pelos componentes: o pacote não depende de biblioteca de ícones
|
|
3
|
+
const PATHS = {
|
|
4
|
+
search: _jsxs(_Fragment, { children: [_jsx("circle", { cx: "11", cy: "11", r: "7" }), _jsx("path", { d: "m20 20-3.5-3.5" })] }),
|
|
5
|
+
copy: _jsxs(_Fragment, { children: [_jsx("rect", { x: "9", y: "9", width: "12", height: "12", rx: "2" }), _jsx("path", { d: "M5 15V5a2 2 0 0 1 2-2h10" })] }),
|
|
6
|
+
check: _jsx("path", { d: "M20 6 9 17l-5-5" }),
|
|
7
|
+
download: _jsxs(_Fragment, { children: [_jsx("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }), _jsx("path", { d: "m7 10 5 5 5-5" }), _jsx("path", { d: "M12 15V3" })] }),
|
|
8
|
+
close: _jsx("path", { d: "M18 6 6 18M6 6l12 12" }),
|
|
9
|
+
chevronLeft: _jsx("path", { d: "m15 18-6-6 6-6" }),
|
|
10
|
+
chevronRight: _jsx("path", { d: "m9 18 6-6-6-6" }),
|
|
11
|
+
chevronDown: _jsx("path", { d: "m6 9 6 6 6-6" }),
|
|
12
|
+
arrowLeft: _jsx("path", { d: "M19 12H5m7 7-7-7 7-7" }),
|
|
13
|
+
arrowRight: _jsx("path", { d: "M5 12h14m-7-7 7 7-7 7" }),
|
|
14
|
+
};
|
|
15
|
+
export function Icon({ name, size = 16, className = "" }) {
|
|
16
|
+
return (_jsx("svg", { "aria-hidden": "true", width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className: `shrink-0 ${className}`, children: PATHS[name] }));
|
|
17
|
+
}
|
|
@@ -1,15 +1,36 @@
|
|
|
1
|
+
export { default as AppShell, navLinkClass, type LinkProps, type NavGroup, type NavItem } from "./AppShell.js";
|
|
1
2
|
export { default as Badge } from "./Badge.js";
|
|
3
|
+
export { default as Button, buttonClass, type ButtonSize, type ButtonVariant } from "./Button.js";
|
|
2
4
|
export { default as Checkbox } from "./Checkbox.js";
|
|
5
|
+
export { default as ChipToggles } from "./ChipToggles.js";
|
|
6
|
+
export { default as ConfirmDialog } from "./ConfirmDialog.js";
|
|
7
|
+
export { default as CopyButton } from "./CopyButton.js";
|
|
8
|
+
export { default as DataGrid } from "./DataGrid.js";
|
|
3
9
|
export { default as DataTable, type DataTableRow } from "./DataTable.js";
|
|
10
|
+
export { default as Dialog } from "./Dialog.js";
|
|
11
|
+
export { default as Disclosure } from "./Disclosure.js";
|
|
4
12
|
export { default as KeyValue } from "./KeyValue.js";
|
|
13
|
+
export { default as LogView, type LogTone } from "./LogView.js";
|
|
14
|
+
export { default as Markdown } from "./Markdown.js";
|
|
15
|
+
export { default as Meter } from "./Meter.js";
|
|
16
|
+
export { default as Notice, type NoticeTone } from "./Notice.js";
|
|
5
17
|
export { default as NumberField } from "./NumberField.js";
|
|
18
|
+
export { default as PageHeader } from "./PageHeader.js";
|
|
19
|
+
export { default as Panel, panelRows } from "./SectionPanel.js";
|
|
20
|
+
export { default as Popover, MenuItem } from "./Popover.js";
|
|
6
21
|
export { default as OutputList } from "./OutputList.js";
|
|
7
22
|
export { default as ParamGroup } from "./ParamGroup.js";
|
|
8
23
|
export { default as Presets } from "./Presets.js";
|
|
9
24
|
export { default as RangeField } from "./RangeField.js";
|
|
25
|
+
export { default as SearchField } from "./SearchField.js";
|
|
10
26
|
export { default as Segmented } from "./Segmented.js";
|
|
27
|
+
export { default as Stat } from "./Stat.js";
|
|
28
|
+
export { default as StatusTag, StatusDot, StatusMark, type StatusTone } from "./StatusTag.js";
|
|
11
29
|
export { default as Stepper } from "./Stepper.js";
|
|
30
|
+
export { default as Tabs } from "./Tabs.js";
|
|
12
31
|
export { default as TextField } from "./TextField.js";
|
|
32
|
+
export { default as ThemeMenu } from "./ThemeMenu.js";
|
|
33
|
+
export { default as Toast } from "./Toast.js";
|
|
13
34
|
export { default as ToolShell } from "./ToolShell.js";
|
|
14
35
|
export { panel, panelHeader } from "./panel.js";
|
|
15
36
|
export { useCopy } from "./useCopy.js";
|
package/dist/components/index.js
CHANGED
|
@@ -1,15 +1,36 @@
|
|
|
1
|
+
export { default as AppShell, navLinkClass } from "./AppShell.js";
|
|
1
2
|
export { default as Badge } from "./Badge.js";
|
|
3
|
+
export { default as Button, buttonClass } from "./Button.js";
|
|
2
4
|
export { default as Checkbox } from "./Checkbox.js";
|
|
5
|
+
export { default as ChipToggles } from "./ChipToggles.js";
|
|
6
|
+
export { default as ConfirmDialog } from "./ConfirmDialog.js";
|
|
7
|
+
export { default as CopyButton } from "./CopyButton.js";
|
|
8
|
+
export { default as DataGrid } from "./DataGrid.js";
|
|
3
9
|
export { default as DataTable } from "./DataTable.js";
|
|
10
|
+
export { default as Dialog } from "./Dialog.js";
|
|
11
|
+
export { default as Disclosure } from "./Disclosure.js";
|
|
4
12
|
export { default as KeyValue } from "./KeyValue.js";
|
|
13
|
+
export { default as LogView } from "./LogView.js";
|
|
14
|
+
export { default as Markdown } from "./Markdown.js";
|
|
15
|
+
export { default as Meter } from "./Meter.js";
|
|
16
|
+
export { default as Notice } from "./Notice.js";
|
|
5
17
|
export { default as NumberField } from "./NumberField.js";
|
|
18
|
+
export { default as PageHeader } from "./PageHeader.js";
|
|
19
|
+
export { default as Panel, panelRows } from "./SectionPanel.js";
|
|
20
|
+
export { default as Popover, MenuItem } from "./Popover.js";
|
|
6
21
|
export { default as OutputList } from "./OutputList.js";
|
|
7
22
|
export { default as ParamGroup } from "./ParamGroup.js";
|
|
8
23
|
export { default as Presets } from "./Presets.js";
|
|
9
24
|
export { default as RangeField } from "./RangeField.js";
|
|
25
|
+
export { default as SearchField } from "./SearchField.js";
|
|
10
26
|
export { default as Segmented } from "./Segmented.js";
|
|
27
|
+
export { default as Stat } from "./Stat.js";
|
|
28
|
+
export { default as StatusTag, StatusDot, StatusMark } from "./StatusTag.js";
|
|
11
29
|
export { default as Stepper } from "./Stepper.js";
|
|
30
|
+
export { default as Tabs } from "./Tabs.js";
|
|
12
31
|
export { default as TextField } from "./TextField.js";
|
|
32
|
+
export { default as ThemeMenu } from "./ThemeMenu.js";
|
|
33
|
+
export { default as Toast } from "./Toast.js";
|
|
13
34
|
export { default as ToolShell } from "./ToolShell.js";
|
|
14
35
|
export { panel, panelHeader } from "./panel.js";
|
|
15
36
|
export { useCopy } from "./useCopy.js";
|
|
@@ -18,3 +18,45 @@ export interface ToolShellLabels {
|
|
|
18
18
|
export declare const copyLabels: CopyLabels;
|
|
19
19
|
export declare const outputListLabels: OutputListLabels;
|
|
20
20
|
export declare const toolShellLabels: ToolShellLabels;
|
|
21
|
+
export interface DialogLabels {
|
|
22
|
+
close: string;
|
|
23
|
+
}
|
|
24
|
+
export declare const dialogLabels: DialogLabels;
|
|
25
|
+
export interface ThemeMenuLabels {
|
|
26
|
+
title: string;
|
|
27
|
+
names: Record<"auto" | "sistema" | "claro" | "papel" | "crepusculo" | "escuro" | "contraste", string>;
|
|
28
|
+
autoHint: string;
|
|
29
|
+
systemHint: string;
|
|
30
|
+
}
|
|
31
|
+
export declare const themeMenuLabels: ThemeMenuLabels;
|
|
32
|
+
export interface AppShellLabels {
|
|
33
|
+
nav: string;
|
|
34
|
+
collapse: string;
|
|
35
|
+
expand: string;
|
|
36
|
+
}
|
|
37
|
+
export declare const appShellLabels: AppShellLabels;
|
|
38
|
+
export interface LogViewLabels extends CopyLabels {
|
|
39
|
+
download: string;
|
|
40
|
+
}
|
|
41
|
+
export declare const logViewLabels: LogViewLabels;
|
|
42
|
+
export interface DataGridLabels {
|
|
43
|
+
title: string;
|
|
44
|
+
filter: string;
|
|
45
|
+
rows: string;
|
|
46
|
+
oneRow: string;
|
|
47
|
+
csv: string;
|
|
48
|
+
json: string;
|
|
49
|
+
copied: string;
|
|
50
|
+
close: string;
|
|
51
|
+
page: string;
|
|
52
|
+
previous: string;
|
|
53
|
+
next: string;
|
|
54
|
+
noColumns: string;
|
|
55
|
+
empty: string;
|
|
56
|
+
truncated: string;
|
|
57
|
+
}
|
|
58
|
+
export declare const dataGridLabels: DataGridLabels;
|
|
59
|
+
export interface ConfirmDialogLabels {
|
|
60
|
+
cancel: string;
|
|
61
|
+
}
|
|
62
|
+
export declare const confirmDialogLabels: ConfirmDialogLabels;
|
|
@@ -9,3 +9,37 @@ export const toolShellLabels = {
|
|
|
9
9
|
howCode: "Ver o código ↗",
|
|
10
10
|
private: "Processado no seu navegador; nada é enviado.",
|
|
11
11
|
};
|
|
12
|
+
export const dialogLabels = { close: "Fechar" };
|
|
13
|
+
export const themeMenuLabels = {
|
|
14
|
+
title: "Tema",
|
|
15
|
+
names: {
|
|
16
|
+
auto: "Auto",
|
|
17
|
+
sistema: "Sistema",
|
|
18
|
+
claro: "Claro",
|
|
19
|
+
papel: "Papel",
|
|
20
|
+
crepusculo: "Crepúsculo",
|
|
21
|
+
escuro: "Escuro",
|
|
22
|
+
contraste: "Alto contraste",
|
|
23
|
+
},
|
|
24
|
+
autoHint: "muda conforme o horário · agora: {tema}",
|
|
25
|
+
systemHint: "segue o sistema operacional",
|
|
26
|
+
};
|
|
27
|
+
export const appShellLabels = { nav: "Navegação", collapse: "Recolher menu", expand: "Expandir menu" };
|
|
28
|
+
export const logViewLabels = { ...copyLabels, download: "Baixar" };
|
|
29
|
+
export const dataGridLabels = {
|
|
30
|
+
title: "Resultado",
|
|
31
|
+
filter: "Filtrar nesta lista",
|
|
32
|
+
rows: "{n} registros",
|
|
33
|
+
oneRow: "1 registro",
|
|
34
|
+
csv: "CSV",
|
|
35
|
+
json: "JSON",
|
|
36
|
+
copied: "Copiado!",
|
|
37
|
+
close: "Fechar resultado",
|
|
38
|
+
page: "Página {page} de {pages}",
|
|
39
|
+
previous: "Página anterior",
|
|
40
|
+
next: "Próxima página",
|
|
41
|
+
noColumns: "Comando executado. Nenhuma coluna retornada.",
|
|
42
|
+
empty: "Nenhum registro encontrado.",
|
|
43
|
+
truncated: "Truncado no limite",
|
|
44
|
+
};
|
|
45
|
+
export const confirmDialogLabels = { cancel: "Cancelar" };
|
package/package.json
CHANGED
|
@@ -1,25 +1,40 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thecodecodex/design-system",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Design system do thecodecodex.com: tokens e temas para Tailwind CSS v4 e componentes React",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Douglas Capeletti",
|
|
7
|
-
"homepage": "https://github.com/thecodecodex/system
|
|
7
|
+
"homepage": "https://github.com/thecodecodex/design-system#readme",
|
|
8
8
|
"repository": {
|
|
9
9
|
"type": "git",
|
|
10
|
-
"url": "git+https://github.com/thecodecodex/system
|
|
10
|
+
"url": "git+https://github.com/thecodecodex/design-system.git"
|
|
11
11
|
},
|
|
12
|
-
"bugs": "https://github.com/thecodecodex/system
|
|
13
|
-
"keywords": [
|
|
12
|
+
"bugs": "https://github.com/thecodecodex/design-system/issues",
|
|
13
|
+
"keywords": [
|
|
14
|
+
"design-system",
|
|
15
|
+
"tailwindcss",
|
|
16
|
+
"react",
|
|
17
|
+
"preact",
|
|
18
|
+
"themes"
|
|
19
|
+
],
|
|
14
20
|
"type": "module",
|
|
15
|
-
"sideEffects": [
|
|
21
|
+
"sideEffects": [
|
|
22
|
+
"**/*.css"
|
|
23
|
+
],
|
|
16
24
|
"exports": {
|
|
17
|
-
".": {
|
|
18
|
-
|
|
25
|
+
".": {
|
|
26
|
+
"types": "./dist/components/index.d.ts",
|
|
27
|
+
"default": "./dist/components/index.js"
|
|
28
|
+
},
|
|
29
|
+
"./theme": {
|
|
30
|
+
"types": "./dist/theme/index.d.ts",
|
|
31
|
+
"default": "./dist/theme/index.js"
|
|
32
|
+
},
|
|
19
33
|
"./styles.css": "./src/styles/index.css",
|
|
20
34
|
"./tokens.css": "./src/styles/tokens.css",
|
|
21
35
|
"./themes.css": "./src/styles/themes.css",
|
|
22
|
-
"./base.css": "./src/styles/base.css"
|
|
36
|
+
"./base.css": "./src/styles/base.css",
|
|
37
|
+
"./content.css": "./src/styles/content.css"
|
|
23
38
|
},
|
|
24
39
|
"files": [
|
|
25
40
|
"dist",
|