@aereamart/design-system 0.3.6 → 0.4.2
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/cn.d.ts +2 -1
- package/dist/cn.js +4 -2
- package/dist/hooks/use-mobile.d.ts +1 -0
- package/dist/hooks/use-mobile.js +15 -0
- package/dist/index.d.ts +48 -37
- package/dist/index.js +48 -37
- package/dist/ui/accordion.d.ts +7 -0
- package/dist/ui/accordion.js +17 -0
- package/dist/ui/alert-dialog.d.ts +18 -0
- package/dist/ui/alert-dialog.js +42 -0
- package/dist/ui/alert.d.ts +9 -0
- package/dist/ui/alert.js +24 -0
- package/dist/ui/aspect-ratio.d.ts +3 -0
- package/dist/ui/aspect-ratio.js +6 -0
- package/dist/ui/avatar.d.ts +11 -0
- package/dist/ui/avatar.js +23 -0
- package/dist/ui/badge.d.ts +9 -0
- package/dist/ui/badge.js +24 -0
- package/dist/ui/breadcrumb.d.ts +11 -0
- package/dist/ui/breadcrumb.js +27 -0
- package/dist/ui/button.d.ts +10 -0
- package/dist/ui/button.js +35 -0
- package/dist/ui/calendar.d.ts +8 -0
- package/dist/ui/calendar.js +75 -0
- package/dist/ui/card.d.ts +9 -0
- package/dist/ui/card.js +24 -0
- package/dist/ui/carousel.d.ts +19 -0
- package/dist/ui/carousel.js +91 -0
- package/dist/ui/chart.d.ts +44 -0
- package/dist/ui/chart.js +132 -0
- package/dist/ui/checkbox.d.ts +4 -0
- package/dist/ui/checkbox.js +8 -0
- package/dist/ui/collapsible.d.ts +5 -0
- package/dist/ui/collapsible.js +13 -0
- package/dist/ui/command.d.ts +18 -0
- package/dist/ui/command.js +34 -0
- package/dist/ui/context-menu.d.ts +25 -0
- package/dist/ui/context-menu.js +51 -0
- package/dist/ui/dialog.d.ts +17 -0
- package/dist/ui/dialog.js +36 -0
- package/dist/ui/drawer.d.ts +13 -0
- package/dist/ui/drawer.js +35 -0
- package/dist/ui/dropdown-menu.d.ts +25 -0
- package/dist/ui/dropdown-menu.js +50 -0
- package/dist/ui/form.d.ts +24 -0
- package/dist/ui/form.js +58 -0
- package/dist/ui/hover-card.d.ts +6 -0
- package/dist/ui/hover-card.js +13 -0
- package/dist/ui/input-otp.d.ts +11 -0
- package/dist/ui/input-otp.js +21 -0
- package/dist/ui/input.d.ts +3 -0
- package/dist/ui/input.js +6 -0
- package/dist/ui/label.d.ts +4 -0
- package/dist/ui/label.js +8 -0
- package/dist/ui/menubar.d.ts +26 -0
- package/dist/ui/menubar.js +53 -0
- package/dist/ui/navigation-menu.d.ts +14 -0
- package/dist/ui/navigation-menu.js +31 -0
- package/dist/ui/pagination.d.ts +13 -0
- package/dist/ui/pagination.js +29 -0
- package/dist/ui/popover.d.ts +10 -0
- package/dist/ui/popover.js +26 -0
- package/dist/ui/progress.d.ts +4 -0
- package/dist/ui/progress.js +7 -0
- package/dist/ui/radio-group.d.ts +5 -0
- package/dist/ui/radio-group.js +12 -0
- package/dist/ui/resizable.d.ts +7 -0
- package/dist/ui/resizable.js +14 -0
- package/dist/ui/scroll-area.d.ts +5 -0
- package/dist/ui/scroll-area.js +12 -0
- package/dist/ui/select.d.ts +15 -0
- package/dist/ui/select.js +38 -0
- package/dist/ui/separator.d.ts +4 -0
- package/dist/ui/separator.js +7 -0
- package/dist/ui/sheet.d.ts +14 -0
- package/dist/ui/sheet.js +40 -0
- package/dist/ui/sidebar.d.ts +69 -0
- package/dist/ui/sidebar.js +211 -0
- package/dist/ui/skeleton.d.ts +2 -0
- package/dist/ui/skeleton.js +6 -0
- package/dist/ui/slider.d.ts +4 -0
- package/dist/ui/slider.js +13 -0
- package/dist/ui/sonner.d.ts +3 -0
- package/dist/ui/sonner.js +21 -0
- package/dist/ui/switch.d.ts +6 -0
- package/dist/ui/switch.js +7 -0
- package/dist/ui/table.d.ts +10 -0
- package/dist/ui/table.js +28 -0
- package/dist/ui/tabs.d.ts +11 -0
- package/dist/ui/tabs.js +28 -0
- package/dist/ui/textarea.d.ts +3 -0
- package/dist/ui/textarea.js +6 -0
- package/dist/ui/toggle-group.d.ts +9 -0
- package/dist/ui/toggle-group.js +22 -0
- package/dist/ui/toggle.d.ts +9 -0
- package/dist/ui/toggle.js +26 -0
- package/dist/ui/tooltip.d.ts +7 -0
- package/dist/ui/tooltip.js +16 -0
- package/package.json +28 -4
- package/src/cn.ts +5 -2
- package/src/hooks/use-mobile.ts +19 -0
- package/src/index.css +158 -0
- package/src/index.ts +48 -37
- package/src/ui/accordion.tsx +63 -0
- package/src/ui/alert-dialog.tsx +196 -0
- package/src/ui/alert.tsx +65 -0
- package/src/ui/aspect-ratio.tsx +9 -0
- package/src/ui/avatar.tsx +108 -0
- package/src/ui/badge.tsx +47 -0
- package/src/ui/breadcrumb.tsx +108 -0
- package/src/ui/button.tsx +63 -0
- package/src/ui/calendar.tsx +218 -0
- package/src/ui/card.tsx +91 -0
- package/src/ui/carousel.tsx +241 -0
- package/src/ui/chart.tsx +371 -0
- package/src/ui/checkbox.tsx +29 -0
- package/src/ui/collapsible.tsx +33 -0
- package/src/ui/command.tsx +184 -0
- package/src/ui/context-menu.tsx +251 -0
- package/src/ui/dialog.tsx +156 -0
- package/src/ui/drawer.tsx +134 -0
- package/src/ui/dropdown-menu.tsx +254 -0
- package/src/ui/form.tsx +165 -0
- package/src/ui/hover-card.tsx +41 -0
- package/src/ui/input-otp.tsx +76 -0
- package/src/ui/input.tsx +20 -0
- package/src/ui/label.tsx +23 -0
- package/src/ui/menubar.tsx +273 -0
- package/src/ui/navigation-menu.tsx +167 -0
- package/src/ui/pagination.tsx +127 -0
- package/src/ui/popover.tsx +88 -0
- package/src/ui/progress.tsx +28 -0
- package/src/ui/radio-group.tsx +44 -0
- package/src/ui/resizable.tsx +50 -0
- package/src/ui/scroll-area.tsx +55 -0
- package/src/ui/select.tsx +189 -0
- package/src/ui/separator.tsx +25 -0
- package/src/ui/sheet.tsx +142 -0
- package/src/ui/sidebar.tsx +724 -0
- package/src/ui/skeleton.tsx +13 -0
- package/src/ui/slider.tsx +60 -0
- package/src/ui/sonner.tsx +40 -0
- package/src/ui/switch.tsx +32 -0
- package/src/ui/table.tsx +115 -0
- package/src/ui/tabs.tsx +88 -0
- package/src/ui/textarea.tsx +17 -0
- package/src/ui/toggle-group.tsx +83 -0
- package/src/ui/toggle.tsx +46 -0
- package/src/ui/tooltip.tsx +54 -0
- package/dist/Accordion.d.ts +0 -10
- package/dist/Accordion.js +0 -12
- package/dist/AlertBanner.d.ts +0 -9
- package/dist/AlertBanner.js +0 -21
- package/dist/AppBar.d.ts +0 -7
- package/dist/AppBar.js +0 -5
- package/dist/Avatar.d.ts +0 -6
- package/dist/Avatar.js +0 -20
- package/dist/Badge.d.ts +0 -6
- package/dist/Badge.js +0 -11
- package/dist/BottomSheet.d.ts +0 -8
- package/dist/BottomSheet.js +0 -24
- package/dist/Breadcrumb.d.ts +0 -8
- package/dist/Breadcrumb.js +0 -9
- package/dist/Button.d.ts +0 -9
- package/dist/Button.js +0 -18
- package/dist/Card.d.ts +0 -7
- package/dist/Card.js +0 -6
- package/dist/Checkbox.d.ts +0 -5
- package/dist/Checkbox.js +0 -5
- package/dist/Chip.d.ts +0 -7
- package/dist/Chip.js +0 -15
- package/dist/DataTable.d.ts +0 -15
- package/dist/DataTable.js +0 -7
- package/dist/DatePicker.d.ts +0 -5
- package/dist/DatePicker.js +0 -11
- package/dist/Divider.d.ts +0 -5
- package/dist/Divider.js +0 -11
- package/dist/Drawer.d.ts +0 -10
- package/dist/Drawer.js +0 -24
- package/dist/EmptyState.d.ts +0 -7
- package/dist/EmptyState.js +0 -6
- package/dist/Input.d.ts +0 -5
- package/dist/Input.js +0 -7
- package/dist/Link.d.ts +0 -4
- package/dist/Link.js +0 -6
- package/dist/Menu.d.ts +0 -14
- package/dist/Menu.js +0 -29
- package/dist/Modal.d.ts +0 -9
- package/dist/Modal.js +0 -24
- package/dist/NavigationBar.d.ts +0 -14
- package/dist/NavigationBar.js +0 -22
- package/dist/Pagination.d.ts +0 -7
- package/dist/Pagination.js +0 -24
- package/dist/Popover.d.ts +0 -7
- package/dist/Popover.js +0 -9
- package/dist/Progress.d.ts +0 -8
- package/dist/Progress.js +0 -15
- package/dist/Radio.d.ts +0 -15
- package/dist/Radio.js +0 -8
- package/dist/SegmentedControl.d.ts +0 -13
- package/dist/SegmentedControl.js +0 -18
- package/dist/Select.d.ts +0 -5
- package/dist/Select.js +0 -7
- package/dist/Sidebar.d.ts +0 -16
- package/dist/Sidebar.js +0 -19
- package/dist/Slider.d.ts +0 -5
- package/dist/Slider.js +0 -5
- package/dist/Snackbar.d.ts +0 -12
- package/dist/Snackbar.js +0 -20
- package/dist/Spinner.d.ts +0 -3
- package/dist/Spinner.js +0 -5
- package/dist/Switch.d.ts +0 -4
- package/dist/Switch.js +0 -5
- package/dist/Tabs.d.ts +0 -14
- package/dist/Tabs.js +0 -24
- package/dist/Tag.d.ts +0 -6
- package/dist/Tag.js +0 -11
- package/dist/Textarea.d.ts +0 -5
- package/dist/Textarea.js +0 -7
- package/dist/Tooltip.d.ts +0 -7
- package/dist/Tooltip.js +0 -5
- package/dist/TreeView.d.ts +0 -12
- package/dist/TreeView.js +0 -34
- package/src/Accordion.tsx +0 -58
- package/src/AlertBanner.tsx +0 -62
- package/src/AppBar.tsx +0 -29
- package/src/Avatar.tsx +0 -42
- package/src/Badge.tsx +0 -27
- package/src/BottomSheet.tsx +0 -60
- package/src/Breadcrumb.tsx +0 -48
- package/src/Button.tsx +0 -54
- package/src/Card.tsx +0 -39
- package/src/Checkbox.tsx +0 -31
- package/src/Chip.tsx +0 -44
- package/src/DataTable.tsx +0 -64
- package/src/DatePicker.tsx +0 -44
- package/src/Divider.tsx +0 -33
- package/src/Drawer.tsx +0 -71
- package/src/EmptyState.tsx +0 -37
- package/src/Input.tsx +0 -30
- package/src/Link.tsx +0 -22
- package/src/Menu.tsx +0 -73
- package/src/Modal.tsx +0 -62
- package/src/NavigationBar.tsx +0 -68
- package/src/Pagination.tsx +0 -69
- package/src/Popover.tsx +0 -34
- package/src/Progress.tsx +0 -53
- package/src/Radio.tsx +0 -49
- package/src/SegmentedControl.tsx +0 -63
- package/src/Select.tsx +0 -32
- package/src/Sidebar.tsx +0 -73
- package/src/Slider.tsx +0 -33
- package/src/Snackbar.tsx +0 -72
- package/src/Spinner.tsx +0 -19
- package/src/Switch.tsx +0 -40
- package/src/Tabs.tsx +0 -77
- package/src/Tag.tsx +0 -29
- package/src/Textarea.tsx +0 -30
- package/src/Tooltip.tsx +0 -25
- package/src/TreeView.tsx +0 -105
package/dist/Sidebar.js
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useState } from 'react';
|
|
3
|
-
import { cn } from './cn';
|
|
4
|
-
export function Sidebar({ items, value, defaultValue, onChange, header, footer, className, ...props }) {
|
|
5
|
-
const controlled = value !== undefined;
|
|
6
|
-
const [active, setActive] = useState(defaultValue);
|
|
7
|
-
return (_jsxs("nav", { className: cn('flex w-64 flex-col gap-2 rounded-xl border border-slate-200 bg-white p-3', className), ...props, children: [header && _jsx("div", { className: "border-b border-slate-100 pb-2", children: header }), _jsx("ul", { className: "flex-1 space-y-0.5", children: items.map(item => {
|
|
8
|
-
const isActive = controlled ? value === item.value : active === item.value;
|
|
9
|
-
return (_jsx("li", { children: _jsxs("button", { type: "button", disabled: item.disabled, onClick: () => {
|
|
10
|
-
if (!controlled)
|
|
11
|
-
setActive(item.value);
|
|
12
|
-
onChange?.(item.value);
|
|
13
|
-
}, className: cn('flex w-full items-center gap-2.5 rounded-lg px-3 py-2 text-left text-sm font-medium transition-colors', 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-lime-500/40 disabled:cursor-not-allowed', item.disabled
|
|
14
|
-
? 'cursor-not-allowed text-slate-300'
|
|
15
|
-
: isActive
|
|
16
|
-
? 'bg-lime-600 text-white'
|
|
17
|
-
: 'text-slate-700 hover:bg-lime-50 hover:text-lime-800'), children: [item.icon, _jsx("span", { className: "flex-1 truncate", children: item.label }), item.badge] }) }, item.value));
|
|
18
|
-
}) }), footer && _jsx("div", { className: "border-t border-slate-100 pt-2", children: footer })] }));
|
|
19
|
-
}
|
package/dist/Slider.d.ts
DELETED
package/dist/Slider.js
DELETED
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { cn } from './cn';
|
|
3
|
-
export function Slider({ label, valueLabel, id, className, ...props }) {
|
|
4
|
-
return (_jsxs("div", { className: cn('w-full max-w-md', className), children: [(label || valueLabel) && (_jsxs("div", { className: "mb-2 flex items-center justify-between", children: [label && (_jsx("label", { htmlFor: id, className: "text-sm font-medium text-slate-700", children: label })), valueLabel && (_jsx("span", { className: "text-sm font-semibold tabular-nums text-slate-600", children: valueLabel }))] })), _jsx("input", { id: id, type: "range", className: "h-2 w-full cursor-pointer appearance-none rounded-full bg-slate-200 accent-lime-600 focus:outline-none focus:ring-2 focus:ring-lime-500/40", ...props })] }));
|
|
5
|
-
}
|
package/dist/Snackbar.d.ts
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
type SnackbarTone = 'success' | 'error' | 'warning' | 'info';
|
|
2
|
-
export interface SnackbarProps {
|
|
3
|
-
open?: boolean;
|
|
4
|
-
tone?: SnackbarTone;
|
|
5
|
-
message: string;
|
|
6
|
-
actionLabel?: string;
|
|
7
|
-
onAction?: () => void;
|
|
8
|
-
onClose?: () => void;
|
|
9
|
-
className?: string;
|
|
10
|
-
}
|
|
11
|
-
export declare function Snackbar({ open, tone, message, actionLabel, onAction, onClose, className, }: SnackbarProps): import("react").JSX.Element | null;
|
|
12
|
-
export {};
|
package/dist/Snackbar.js
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { CheckCircle2, XCircle, AlertTriangle, Info, X } from 'lucide-react';
|
|
3
|
-
import { cn } from './cn';
|
|
4
|
-
const toneIcon = {
|
|
5
|
-
success: _jsx(CheckCircle2, { className: "h-5 w-5 shrink-0" }),
|
|
6
|
-
error: _jsx(XCircle, { className: "h-5 w-5 shrink-0" }),
|
|
7
|
-
warning: _jsx(AlertTriangle, { className: "h-5 w-5 shrink-0" }),
|
|
8
|
-
info: _jsx(Info, { className: "h-5 w-5 shrink-0" }),
|
|
9
|
-
};
|
|
10
|
-
const toneText = {
|
|
11
|
-
success: 'text-lime-600',
|
|
12
|
-
error: 'text-red-600',
|
|
13
|
-
warning: 'text-purple-600',
|
|
14
|
-
info: 'text-sky-600',
|
|
15
|
-
};
|
|
16
|
-
export function Snackbar({ open = true, tone = 'info', message, actionLabel, onAction, onClose, className, }) {
|
|
17
|
-
if (!open)
|
|
18
|
-
return null;
|
|
19
|
-
return (_jsxs("div", { role: "status", "aria-live": "polite", className: cn('pointer-events-auto flex items-center gap-3 rounded-xl border border-slate-200 bg-white px-4 py-3 shadow-lg', className), children: [_jsx("span", { className: toneText[tone], children: toneIcon[tone] }), _jsx("p", { className: "min-w-0 flex-1 text-sm font-medium text-slate-800", children: message }), actionLabel && (_jsx("button", { type: "button", onClick: onAction, className: "shrink-0 text-sm font-semibold text-lime-700 hover:text-lime-800 hover:underline", children: actionLabel })), onClose && (_jsx("button", { type: "button", "aria-label": "Close", onClick: onClose, className: "shrink-0 rounded-full p-1 text-slate-400 hover:bg-slate-100", children: _jsx(X, { className: "h-4 w-4" }) }))] }));
|
|
20
|
-
}
|
package/dist/Spinner.d.ts
DELETED
package/dist/Spinner.js
DELETED
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { cn } from './cn';
|
|
3
|
-
export function Spinner({ className }) {
|
|
4
|
-
return (_jsxs("svg", { className: cn('h-5 w-5 animate-spin text-current', 'inline-flex shrink-0', className), viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: [_jsx("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }), _jsx("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 0 1 8-8v4a4 4 0 0 0-4 4H4z" })] }));
|
|
5
|
-
}
|
package/dist/Switch.d.ts
DELETED
package/dist/Switch.js
DELETED
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { cn } from './cn';
|
|
3
|
-
export function Switch({ label, id, className, checked, onChange, ...props }) {
|
|
4
|
-
return (_jsxs("label", { htmlFor: id, className: cn('inline-flex cursor-pointer items-center gap-3', className), children: [_jsx("input", { id: id, type: "checkbox", role: "switch", checked: checked, onChange: onChange, className: "sr-only", ...props }), _jsx("span", { "aria-hidden": "true", className: cn('relative inline-flex h-6 w-11 shrink-0 items-center rounded-full transition-colors', checked ? 'bg-lime-600' : 'bg-slate-300'), children: _jsx("span", { className: cn('inline-block h-4 w-4 transform rounded-full bg-white shadow transition-transform', checked ? 'translate-x-6' : 'translate-x-1') }) }), label && _jsx("span", { className: "text-sm font-medium text-slate-700", children: label })] }));
|
|
5
|
-
}
|
package/dist/Tabs.d.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
export interface Tab<T extends string | number> {
|
|
2
|
-
value: T;
|
|
3
|
-
label: string;
|
|
4
|
-
disabled?: boolean;
|
|
5
|
-
}
|
|
6
|
-
export interface TabsProps<T extends string | number> {
|
|
7
|
-
tabs: Tab<T>[];
|
|
8
|
-
value?: T;
|
|
9
|
-
defaultValue?: T;
|
|
10
|
-
onChange?: (value: T) => void;
|
|
11
|
-
variant?: 'underline' | 'pill';
|
|
12
|
-
className?: string;
|
|
13
|
-
}
|
|
14
|
-
export declare function Tabs<T extends string | number>({ tabs, value, defaultValue, onChange, variant, className, }: TabsProps<T>): import("react").JSX.Element;
|
package/dist/Tabs.js
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { useState } from 'react';
|
|
3
|
-
import { cn } from './cn';
|
|
4
|
-
export function Tabs({ tabs, value, defaultValue, onChange, variant = 'underline', className, }) {
|
|
5
|
-
const isControlled = value !== undefined;
|
|
6
|
-
const [inner, setInner] = useState(defaultValue);
|
|
7
|
-
const active = isControlled ? value : inner;
|
|
8
|
-
return (_jsx("div", { role: "tablist", className: cn(variant === 'underline'
|
|
9
|
-
? 'flex gap-1 border-b border-slate-200'
|
|
10
|
-
: 'inline-flex items-center gap-1 rounded-lg border border-slate-200 bg-white p-1', className), children: tabs.map(tab => {
|
|
11
|
-
const selected = active === tab.value;
|
|
12
|
-
return (_jsx("button", { type: "button", role: "tab", "aria-selected": selected, disabled: tab.disabled, onClick: () => {
|
|
13
|
-
if (!isControlled)
|
|
14
|
-
setInner(tab.value);
|
|
15
|
-
onChange?.(tab.value);
|
|
16
|
-
}, className: cn('px-4 py-2 text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-lime-500/40 disabled:opacity-50', variant === 'underline'
|
|
17
|
-
? cn('-mb-px border-b-2', selected
|
|
18
|
-
? 'border-lime-600 text-lime-700'
|
|
19
|
-
: 'border-transparent text-slate-500 hover:border-slate-300 hover:text-slate-900')
|
|
20
|
-
: cn('rounded-md', selected
|
|
21
|
-
? 'bg-lime-600 text-white'
|
|
22
|
-
: 'text-slate-600 hover:bg-slate-100 hover:text-slate-900')), children: tab.label }, String(tab.value)));
|
|
23
|
-
}) }));
|
|
24
|
-
}
|
package/dist/Tag.d.ts
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
type TagTone = 'primary' | 'accent' | 'neutral' | 'danger';
|
|
2
|
-
export interface TagProps extends React.HTMLAttributes<HTMLSpanElement> {
|
|
3
|
-
tone?: TagTone;
|
|
4
|
-
}
|
|
5
|
-
export declare function Tag({ tone, className, children, ...props }: TagProps): import("react").JSX.Element;
|
|
6
|
-
export {};
|
package/dist/Tag.js
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { cn } from './cn';
|
|
3
|
-
const toneClasses = {
|
|
4
|
-
primary: 'border-lime-300 bg-white text-lime-800',
|
|
5
|
-
accent: 'border-purple-300 bg-white text-purple-900',
|
|
6
|
-
neutral: 'border-slate-300 bg-white text-slate-700',
|
|
7
|
-
danger: 'border-red-300 bg-white text-red-800',
|
|
8
|
-
};
|
|
9
|
-
export function Tag({ tone = 'neutral', className, children, ...props }) {
|
|
10
|
-
return (_jsx("span", { className: cn('inline-flex items-center gap-1 rounded-md border px-2 py-0.5 text-xs font-semibold', toneClasses[tone], className), ...props, children: children }));
|
|
11
|
-
}
|
package/dist/Textarea.d.ts
DELETED
package/dist/Textarea.js
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { cn } from './cn';
|
|
3
|
-
export function Textarea({ label, error, className, id, ...props }) {
|
|
4
|
-
return (_jsxs("div", { className: "w-full", children: [label && (_jsx("label", { htmlFor: id, className: "mb-1 block text-sm font-medium text-slate-700", children: label })), _jsx("textarea", { id: id, className: cn('w-full rounded-lg border bg-white px-4 py-2.5 text-sm text-slate-900 placeholder:text-slate-500 focus:outline-none focus:ring-2', error
|
|
5
|
-
? 'border-red-600 focus:border-red-600 focus:ring-red-500/30'
|
|
6
|
-
: 'border-slate-500 focus:border-lime-600 focus:ring-lime-500/30', className), ...props }), error && _jsx("p", { className: "mt-1 text-xs text-red-600", children: error })] }));
|
|
7
|
-
}
|
package/dist/Tooltip.d.ts
DELETED
package/dist/Tooltip.js
DELETED
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { cn } from './cn';
|
|
3
|
-
export function Tooltip({ content, side = 'top', children, className }) {
|
|
4
|
-
return (_jsxs("span", { className: cn('group relative inline-flex', className), children: [children, _jsx("span", { role: "tooltip", className: cn('pointer-events-none absolute left-1/2 z-50 w-max max-w-xs -translate-x-1/2 rounded-lg bg-slate-900 px-3 py-1.5 text-xs font-medium text-white opacity-0 shadow-lg transition-opacity duration-200 group-hover:opacity-100 group-focus-within:opacity-100', side === 'top' ? 'bottom-full mb-2' : 'top-full mt-2'), children: content })] }));
|
|
5
|
-
}
|
package/dist/TreeView.d.ts
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
export interface TreeNode {
|
|
2
|
-
id: string;
|
|
3
|
-
label: string;
|
|
4
|
-
children?: TreeNode[];
|
|
5
|
-
}
|
|
6
|
-
export interface TreeViewProps {
|
|
7
|
-
nodes: TreeNode[];
|
|
8
|
-
defaultExpanded?: string[];
|
|
9
|
-
defaultAllExpanded?: boolean;
|
|
10
|
-
className?: string;
|
|
11
|
-
}
|
|
12
|
-
export declare function TreeView({ nodes, defaultExpanded, defaultAllExpanded, className }: TreeViewProps): import("react").JSX.Element;
|
package/dist/TreeView.js
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useId, useState } from 'react';
|
|
3
|
-
import { ChevronRight } from 'lucide-react';
|
|
4
|
-
import { cn } from './cn';
|
|
5
|
-
function Node({ node, depth, expanded, onToggle, }) {
|
|
6
|
-
const hasChildren = !!node.children?.length;
|
|
7
|
-
const isOpen = expanded.has(node.id);
|
|
8
|
-
return (_jsxs("li", { children: [_jsx("div", { className: cn('flex items-center gap-1.5 rounded-lg py-1.5 pr-2'), children: _jsxs("button", { type: "button", "aria-expanded": hasChildren ? isOpen : undefined, onClick: () => hasChildren && onToggle(node.id), className: cn('inline-flex w-full items-center gap-1.5 rounded-lg py-1.5 pr-2 text-left text-sm font-medium transition-colors', 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-lime-500/40', 'hover:bg-slate-100'), style: { paddingLeft: `${8 + depth * 24}px` }, children: [hasChildren ? (_jsx(ChevronRight, { className: cn('h-4 w-4 shrink-0 text-slate-400 transition-transform', isOpen && 'rotate-90') })) : (_jsx("span", { className: "ml-4 h-4 w-4 shrink-0", "aria-hidden": "true" })), _jsx("span", { className: cn(isOpen && 'font-semibold text-slate-900'), children: node.label })] }) }), hasChildren && isOpen && (_jsx("ul", { role: "group", children: node.children.map(child => (_jsx(Node, { node: child, depth: depth + 1, expanded: expanded, onToggle: onToggle }, child.id))) }))] }));
|
|
9
|
-
}
|
|
10
|
-
export function TreeView({ nodes, defaultExpanded = [], defaultAllExpanded = false, className }) {
|
|
11
|
-
const [expanded, setExpanded] = useState(() => {
|
|
12
|
-
if (defaultAllExpanded) {
|
|
13
|
-
const all = new Set();
|
|
14
|
-
const walk = (list) => list.forEach(n => {
|
|
15
|
-
all.add(n.id);
|
|
16
|
-
if (n.children)
|
|
17
|
-
walk(n.children);
|
|
18
|
-
});
|
|
19
|
-
walk(nodes);
|
|
20
|
-
return all;
|
|
21
|
-
}
|
|
22
|
-
return new Set(defaultExpanded);
|
|
23
|
-
});
|
|
24
|
-
const labelId = useId();
|
|
25
|
-
const toggle = (id) => setExpanded(prev => {
|
|
26
|
-
const next = new Set(prev);
|
|
27
|
-
if (next.has(id))
|
|
28
|
-
next.delete(id);
|
|
29
|
-
else
|
|
30
|
-
next.add(id);
|
|
31
|
-
return next;
|
|
32
|
-
});
|
|
33
|
-
return (_jsxs("ul", { role: "tree", "aria-label": "Tree", "aria-labelledby": labelId, className: cn('space-y-0.5', className), children: [_jsx("span", { id: labelId, className: "sr-only", children: "Tree view" }), nodes.map(node => (_jsx(Node, { node: node, depth: 0, expanded: expanded, onToggle: toggle }, node.id)))] }));
|
|
34
|
-
}
|
package/src/Accordion.tsx
DELETED
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import { useState } from 'react';
|
|
2
|
-
import { ChevronDown } from 'lucide-react';
|
|
3
|
-
import { cn } from './cn';
|
|
4
|
-
|
|
5
|
-
export interface AccordionItem {
|
|
6
|
-
title: string;
|
|
7
|
-
content: React.ReactNode;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export interface AccordionProps {
|
|
11
|
-
items: AccordionItem[];
|
|
12
|
-
defaultOpen?: number | null;
|
|
13
|
-
className?: string;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export function Accordion({ items, defaultOpen = null, className }: AccordionProps) {
|
|
17
|
-
const [open, setOpen] = useState<number | null>(defaultOpen);
|
|
18
|
-
|
|
19
|
-
return (
|
|
20
|
-
<div
|
|
21
|
-
className={cn(
|
|
22
|
-
'divide-y divide-slate-200 overflow-hidden rounded-xl border border-slate-200 bg-white',
|
|
23
|
-
className
|
|
24
|
-
)}
|
|
25
|
-
>
|
|
26
|
-
{items.map((item, i) => {
|
|
27
|
-
const isOpen = open === i;
|
|
28
|
-
const uid = `accordion-${i}`;
|
|
29
|
-
return (
|
|
30
|
-
<div key={uid}>
|
|
31
|
-
<button
|
|
32
|
-
type="button"
|
|
33
|
-
aria-expanded={isOpen}
|
|
34
|
-
aria-controls={`${uid}-panel`}
|
|
35
|
-
onClick={() => setOpen(isOpen ? null : i)}
|
|
36
|
-
className="flex w-full items-center justify-between gap-4 px-5 py-4 text-left text-sm font-semibold text-slate-900 transition-colors hover:bg-slate-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-lime-500/40"
|
|
37
|
-
>
|
|
38
|
-
{item.title}
|
|
39
|
-
<ChevronDown
|
|
40
|
-
aria-hidden="true"
|
|
41
|
-
className={cn('h-4 w-4 shrink-0 text-slate-400 transition-transform', isOpen && 'rotate-180')}
|
|
42
|
-
/>
|
|
43
|
-
</button>
|
|
44
|
-
{isOpen && (
|
|
45
|
-
<div
|
|
46
|
-
id={`${uid}-panel`}
|
|
47
|
-
role="region"
|
|
48
|
-
className="border-t border-slate-100 px-5 py-4 text-sm leading-relaxed text-slate-600"
|
|
49
|
-
>
|
|
50
|
-
{item.content}
|
|
51
|
-
</div>
|
|
52
|
-
)}
|
|
53
|
-
</div>
|
|
54
|
-
);
|
|
55
|
-
})}
|
|
56
|
-
</div>
|
|
57
|
-
);
|
|
58
|
-
}
|
package/src/AlertBanner.tsx
DELETED
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
import { Info, AlertTriangle, CheckCircle2, XCircle, X } from 'lucide-react';
|
|
2
|
-
import { useState } from 'react';
|
|
3
|
-
import { cn } from './cn';
|
|
4
|
-
|
|
5
|
-
type AlertTone = 'info' | 'primary' | 'accent' | 'danger' | 'neutral';
|
|
6
|
-
|
|
7
|
-
export interface AlertBannerProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
8
|
-
tone?: AlertTone;
|
|
9
|
-
title?: string;
|
|
10
|
-
dismissible?: boolean;
|
|
11
|
-
onDismiss?: () => void;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
const toneRecord: Record<AlertTone, { wrap: string; icon: React.ReactNode; label: string }> = {
|
|
15
|
-
info: { wrap: 'border-sky-300 bg-sky-50 text-sky-900', icon: <Info className="h-4 w-4" />, label: 'Info' },
|
|
16
|
-
primary: { wrap: 'border-lime-300 bg-lime-50 text-lime-900', icon: <CheckCircle2 className="h-4 w-4" />, label: 'Success' },
|
|
17
|
-
accent: { wrap: 'border-purple-300 bg-purple-50 text-purple-900', icon: <AlertTriangle className="h-4 w-4" />, label: 'Warning' },
|
|
18
|
-
danger: { wrap: 'border-red-300 bg-red-50 text-red-900', icon: <XCircle className="h-4 w-4" />, label: 'Error' },
|
|
19
|
-
neutral: { wrap: 'border-slate-300 bg-slate-50 text-slate-800', icon: <Info className="h-4 w-4" />, label: 'Notice' },
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
export function AlertBanner({
|
|
23
|
-
tone = 'primary',
|
|
24
|
-
title,
|
|
25
|
-
dismissible = false,
|
|
26
|
-
onDismiss,
|
|
27
|
-
className,
|
|
28
|
-
children,
|
|
29
|
-
...props
|
|
30
|
-
}: AlertBannerProps) {
|
|
31
|
-
const [hidden, setHidden] = useState(false);
|
|
32
|
-
if (hidden) return null;
|
|
33
|
-
const t = toneRecord[tone];
|
|
34
|
-
return (
|
|
35
|
-
<div
|
|
36
|
-
role="alert"
|
|
37
|
-
className={cn('flex items-start gap-3 rounded-lg border px-4 py-3 text-sm', t.wrap, className)}
|
|
38
|
-
{...props}
|
|
39
|
-
>
|
|
40
|
-
<span className="mt-0.5 shrink-0" aria-label={t.label}>
|
|
41
|
-
{t.icon}
|
|
42
|
-
</span>
|
|
43
|
-
<div className="min-w-0 flex-1">
|
|
44
|
-
{title && <p className="font-bold">{title}</p>}
|
|
45
|
-
<div className={cn(title && 'mt-0.5 text-sm opacity-90')}>{children}</div>
|
|
46
|
-
</div>
|
|
47
|
-
{dismissible && (
|
|
48
|
-
<button
|
|
49
|
-
type="button"
|
|
50
|
-
aria-label="Dismiss"
|
|
51
|
-
onClick={() => {
|
|
52
|
-
setHidden(true);
|
|
53
|
-
onDismiss?.();
|
|
54
|
-
}}
|
|
55
|
-
className="-mr-1 -mt-1 shrink-0 rounded-full p-1 hover:bg-black/10 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-current"
|
|
56
|
-
>
|
|
57
|
-
<X aria-hidden="true" className="h-4 w-4" />
|
|
58
|
-
</button>
|
|
59
|
-
)}
|
|
60
|
-
</div>
|
|
61
|
-
);
|
|
62
|
-
}
|
package/src/AppBar.tsx
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { cn } from './cn';
|
|
2
|
-
|
|
3
|
-
export interface AppBarProps extends React.HTMLAttributes<HTMLElement> {
|
|
4
|
-
title: string;
|
|
5
|
-
subtitle?: string;
|
|
6
|
-
leading?: React.ReactNode;
|
|
7
|
-
actions?: React.ReactNode;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export function AppBar({ title, subtitle, leading, actions, className, ...props }: AppBarProps) {
|
|
11
|
-
return (
|
|
12
|
-
<header
|
|
13
|
-
className={cn(
|
|
14
|
-
'flex items-center justify-between gap-4 border-b border-slate-200 bg-white px-6 py-4',
|
|
15
|
-
className
|
|
16
|
-
)}
|
|
17
|
-
{...props}
|
|
18
|
-
>
|
|
19
|
-
<div className="flex min-w-0 items-center gap-3">
|
|
20
|
-
{leading}
|
|
21
|
-
<div className="min-w-0">
|
|
22
|
-
<h1 className="truncate text-lg font-bold text-slate-900">{title}</h1>
|
|
23
|
-
{subtitle && <p className="truncate text-sm text-slate-500">{subtitle}</p>}
|
|
24
|
-
</div>
|
|
25
|
-
</div>
|
|
26
|
-
{actions && <div className="flex shrink-0 items-center gap-2">{actions}</div>}
|
|
27
|
-
</header>
|
|
28
|
-
);
|
|
29
|
-
}
|
package/src/Avatar.tsx
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import { cn } from './cn';
|
|
2
|
-
|
|
3
|
-
export interface AvatarProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
4
|
-
src?: string;
|
|
5
|
-
name?: string;
|
|
6
|
-
size?: 'sm' | 'md' | 'lg';
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
const sizeClasses: Record<NonNullable<AvatarProps['size']>, string> = {
|
|
10
|
-
sm: 'h-8 w-8 text-xs',
|
|
11
|
-
md: 'h-10 w-10 text-sm',
|
|
12
|
-
lg: 'h-14 w-14 text-lg',
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
function initials(name?: string): string {
|
|
16
|
-
if (!name) return '?';
|
|
17
|
-
return name
|
|
18
|
-
.split(/\s+/)
|
|
19
|
-
.filter(Boolean)
|
|
20
|
-
.slice(0, 2)
|
|
21
|
-
.map(w => w[0]?.toUpperCase() ?? '')
|
|
22
|
-
.join('') || '?';
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export function Avatar({ src, name, size = 'md', className, ...props }: AvatarProps) {
|
|
26
|
-
return (
|
|
27
|
-
<div
|
|
28
|
-
className={cn(
|
|
29
|
-
'inline-flex shrink-0 select-none items-center justify-center overflow-hidden rounded-full bg-lime-100 font-semibold text-lime-800',
|
|
30
|
-
sizeClasses[size],
|
|
31
|
-
className
|
|
32
|
-
)}
|
|
33
|
-
{...props}
|
|
34
|
-
>
|
|
35
|
-
{src ? (
|
|
36
|
-
<img src={src} alt={name ?? ''} className="h-full w-full object-cover" />
|
|
37
|
-
) : (
|
|
38
|
-
<span aria-hidden="true">{initials(name)}</span>
|
|
39
|
-
)}
|
|
40
|
-
</div>
|
|
41
|
-
);
|
|
42
|
-
}
|
package/src/Badge.tsx
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { cn } from './cn';
|
|
2
|
-
|
|
3
|
-
type BadgeVariant = 'danger' | 'primary' | 'accent' | 'neutral';
|
|
4
|
-
|
|
5
|
-
export interface BadgeProps extends React.HTMLAttributes<HTMLSpanElement> {
|
|
6
|
-
variant?: BadgeVariant;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
const variantClasses: Record<BadgeVariant, string> = {
|
|
10
|
-
danger: 'bg-red-100 text-red-800',
|
|
11
|
-
primary: 'bg-lime-100 text-lime-800',
|
|
12
|
-
accent: 'bg-purple-100 text-purple-900',
|
|
13
|
-
neutral: 'bg-slate-200 text-slate-700',
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
export function Badge({ variant = 'danger', className, ...props }: BadgeProps) {
|
|
17
|
-
return (
|
|
18
|
-
<span
|
|
19
|
-
className={cn(
|
|
20
|
-
'inline-flex items-center justify-center rounded-full text-[10px] font-bold leading-none',
|
|
21
|
-
variantClasses[variant],
|
|
22
|
-
className
|
|
23
|
-
)}
|
|
24
|
-
{...props}
|
|
25
|
-
/>
|
|
26
|
-
);
|
|
27
|
-
}
|
package/src/BottomSheet.tsx
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import { useEffect } from 'react';
|
|
2
|
-
import { createPortal } from 'react-dom';
|
|
3
|
-
import { X } from 'lucide-react';
|
|
4
|
-
import { cn } from './cn';
|
|
5
|
-
|
|
6
|
-
export interface BottomSheetProps {
|
|
7
|
-
open: boolean;
|
|
8
|
-
onClose: () => void;
|
|
9
|
-
title?: string;
|
|
10
|
-
children?: React.ReactNode;
|
|
11
|
-
className?: string;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export function BottomSheet({ open, onClose, title, children, className }: BottomSheetProps) {
|
|
15
|
-
useEffect(() => {
|
|
16
|
-
if (!open) return;
|
|
17
|
-
const onKey = (e: KeyboardEvent) => {
|
|
18
|
-
if (e.key === 'Escape') onClose();
|
|
19
|
-
};
|
|
20
|
-
document.body.style.overflow = 'hidden';
|
|
21
|
-
document.addEventListener('keydown', onKey);
|
|
22
|
-
return () => {
|
|
23
|
-
document.body.style.overflow = '';
|
|
24
|
-
document.removeEventListener('keydown', onKey);
|
|
25
|
-
};
|
|
26
|
-
}, [open, onClose]);
|
|
27
|
-
|
|
28
|
-
if (!open) return null;
|
|
29
|
-
|
|
30
|
-
return createPortal(
|
|
31
|
-
<div className="fixed inset-0 z-50 flex items-end justify-center">
|
|
32
|
-
<div className="absolute inset-0 bg-black/50" onClick={onClose} aria-hidden="true" />
|
|
33
|
-
<section
|
|
34
|
-
role="dialog"
|
|
35
|
-
aria-modal="true"
|
|
36
|
-
aria-label={title}
|
|
37
|
-
className={cn(
|
|
38
|
-
'relative w-full max-w-lg rounded-t-2xl bg-white p-6 shadow-xl',
|
|
39
|
-
className
|
|
40
|
-
)}
|
|
41
|
-
>
|
|
42
|
-
<div aria-hidden="true" className="mx-auto mb-4 h-1 w-10 rounded-full bg-slate-200" />
|
|
43
|
-
{title && (
|
|
44
|
-
<div className="mb-2 flex items-center justify-between">
|
|
45
|
-
<h2 className="text-lg font-bold text-slate-900">{title}</h2>
|
|
46
|
-
<button
|
|
47
|
-
onClick={onClose}
|
|
48
|
-
className="rounded-lg p-1 text-slate-400 hover:bg-slate-100"
|
|
49
|
-
aria-label="Close"
|
|
50
|
-
>
|
|
51
|
-
<X className="h-5 w-5" />
|
|
52
|
-
</button>
|
|
53
|
-
</div>
|
|
54
|
-
)}
|
|
55
|
-
{children}
|
|
56
|
-
</section>
|
|
57
|
-
</div>,
|
|
58
|
-
document.body
|
|
59
|
-
);
|
|
60
|
-
}
|
package/src/Breadcrumb.tsx
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import { ChevronRight } from 'lucide-react';
|
|
2
|
-
import { cn } from './cn';
|
|
3
|
-
|
|
4
|
-
export interface Crumb {
|
|
5
|
-
label: string;
|
|
6
|
-
href?: string;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export interface BreadcrumbProps extends React.HTMLAttributes<HTMLElement> {
|
|
10
|
-
items: Crumb[];
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export function Breadcrumb({ items, className, ...props }: BreadcrumbProps) {
|
|
14
|
-
return (
|
|
15
|
-
<nav aria-label="Breadcrumb" className={className} {...props}>
|
|
16
|
-
<ol className="flex flex-wrap items-center gap-1.5 text-sm">
|
|
17
|
-
{items.map((item, i) => {
|
|
18
|
-
const last = i === items.length - 1;
|
|
19
|
-
return (
|
|
20
|
-
<li key={`${item.label}-${i}`} className="flex items-center gap-1.5">
|
|
21
|
-
{i > 0 && (
|
|
22
|
-
<ChevronRight aria-hidden="true" className="h-3.5 w-3.5 text-slate-400" />
|
|
23
|
-
)}
|
|
24
|
-
{last || !item.href ? (
|
|
25
|
-
<span
|
|
26
|
-
aria-current={last ? 'page' : undefined}
|
|
27
|
-
className={cn(
|
|
28
|
-
'font-medium',
|
|
29
|
-
last ? 'text-slate-900' : 'text-slate-500'
|
|
30
|
-
)}
|
|
31
|
-
>
|
|
32
|
-
{item.label}
|
|
33
|
-
</span>
|
|
34
|
-
) : (
|
|
35
|
-
<a
|
|
36
|
-
href={item.href}
|
|
37
|
-
className="font-medium text-lime-700 hover:text-lime-800 hover:underline"
|
|
38
|
-
>
|
|
39
|
-
{item.label}
|
|
40
|
-
</a>
|
|
41
|
-
)}
|
|
42
|
-
</li>
|
|
43
|
-
);
|
|
44
|
-
})}
|
|
45
|
-
</ol>
|
|
46
|
-
</nav>
|
|
47
|
-
);
|
|
48
|
-
}
|
package/src/Button.tsx
DELETED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import { cn } from './cn';
|
|
2
|
-
import { Spinner } from './Spinner';
|
|
3
|
-
|
|
4
|
-
type ButtonVariant = 'primary' | 'secondary' | 'danger' | 'ghost';
|
|
5
|
-
type ButtonSize = 'sm' | 'md' | 'lg' | 'full';
|
|
6
|
-
|
|
7
|
-
export interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
|
8
|
-
variant?: ButtonVariant;
|
|
9
|
-
size?: ButtonSize;
|
|
10
|
-
loading?: boolean;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
const variantClasses: Record<ButtonVariant, string> = {
|
|
14
|
-
primary:
|
|
15
|
-
'bg-lime-600 text-white hover:bg-lime-700 focus-visible:ring-lime-500/40',
|
|
16
|
-
secondary:
|
|
17
|
-
'border border-slate-300 bg-white text-slate-700 hover:bg-slate-50 focus-visible:ring-slate-400/40',
|
|
18
|
-
danger: 'bg-red-600 text-white hover:bg-red-700 focus-visible:ring-red-500/40',
|
|
19
|
-
ghost:
|
|
20
|
-
'bg-transparent text-slate-600 hover:bg-slate-100 focus-visible:ring-slate-400/40',
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
const sizeClasses: Record<ButtonSize, string> = {
|
|
24
|
-
sm: 'px-3 py-1.5 text-xs',
|
|
25
|
-
md: 'px-4 py-2.5 text-sm',
|
|
26
|
-
lg: 'px-6 py-3 text-base',
|
|
27
|
-
full: 'w-full px-4 py-2.5 text-sm',
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
export function Button({
|
|
31
|
-
variant = 'primary',
|
|
32
|
-
size = 'md',
|
|
33
|
-
loading = false,
|
|
34
|
-
className,
|
|
35
|
-
disabled,
|
|
36
|
-
children,
|
|
37
|
-
...props
|
|
38
|
-
}: ButtonProps) {
|
|
39
|
-
return (
|
|
40
|
-
<button
|
|
41
|
-
className={cn(
|
|
42
|
-
'inline-flex items-center justify-center gap-2 rounded-lg font-semibold transition-colors focus-visible:outline-none focus-visible:ring-2 disabled:cursor-not-allowed disabled:opacity-50',
|
|
43
|
-
variantClasses[variant],
|
|
44
|
-
sizeClasses[size],
|
|
45
|
-
className
|
|
46
|
-
)}
|
|
47
|
-
disabled={disabled || loading}
|
|
48
|
-
{...props}
|
|
49
|
-
>
|
|
50
|
-
{loading && <Spinner className="h-4 w-4" />}
|
|
51
|
-
{children}
|
|
52
|
-
</button>
|
|
53
|
-
);
|
|
54
|
-
}
|