@pichetch08/trip-ui 0.1.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 +46 -0
- package/dist/accordion.d.ts +18 -0
- package/dist/accordion.js +76 -0
- package/dist/agreement-modal.d.ts +16 -0
- package/dist/agreement-modal.js +67 -0
- package/dist/alert.d.ts +13 -0
- package/dist/alert.js +47 -0
- package/dist/auth-hero.d.ts +7 -0
- package/dist/auth-hero.js +63 -0
- package/dist/avatar.d.ts +21 -0
- package/dist/avatar.js +114 -0
- package/dist/badge.d.ts +13 -0
- package/dist/badge.js +36 -0
- package/dist/banner.d.ts +14 -0
- package/dist/banner.js +57 -0
- package/dist/breadcrumb.d.ts +15 -0
- package/dist/breadcrumb.js +37 -0
- package/dist/button.d.ts +15 -0
- package/dist/button.js +81 -0
- package/dist/card.d.ts +30 -0
- package/dist/card.js +66 -0
- package/dist/change-summary-modal.d.ts +35 -0
- package/dist/change-summary-modal.js +128 -0
- package/dist/channel-badge.d.ts +8 -0
- package/dist/channel-badge.js +17 -0
- package/dist/checkbox.d.ts +28 -0
- package/dist/checkbox.js +108 -0
- package/dist/chunk-ORMEWXMH.js +37 -0
- package/dist/color-picker.d.ts +15 -0
- package/dist/color-picker.js +159 -0
- package/dist/confirm-dialog.d.ts +23 -0
- package/dist/confirm-dialog.js +108 -0
- package/dist/copy-button.d.ts +13 -0
- package/dist/copy-button.js +69 -0
- package/dist/dashed-add-button.d.ts +8 -0
- package/dist/dashed-add-button.js +24 -0
- package/dist/data-table.d.ts +27 -0
- package/dist/data-table.js +152 -0
- package/dist/date-picker.d.ts +19 -0
- package/dist/date-picker.js +234 -0
- package/dist/date-range-picker.d.ts +25 -0
- package/dist/date-range-picker.js +456 -0
- package/dist/dev-auto-fill.d.ts +12 -0
- package/dist/dev-auto-fill.js +22 -0
- package/dist/divider.d.ts +10 -0
- package/dist/divider.js +44 -0
- package/dist/drawer.d.ts +16 -0
- package/dist/drawer.js +111 -0
- package/dist/dropdown-menu.d.ts +20 -0
- package/dist/dropdown-menu.js +94 -0
- package/dist/empty-state.d.ts +13 -0
- package/dist/empty-state.js +24 -0
- package/dist/file-upload.d.ts +32 -0
- package/dist/file-upload.js +212 -0
- package/dist/filter-tabs.d.ts +16 -0
- package/dist/filter-tabs.js +30 -0
- package/dist/footer-action-bar.d.ts +21 -0
- package/dist/footer-action-bar.js +95 -0
- package/dist/form-input.d.ts +16 -0
- package/dist/form-input.js +58 -0
- package/dist/form-textarea.d.ts +13 -0
- package/dist/form-textarea.js +41 -0
- package/dist/icon-button.d.ts +12 -0
- package/dist/icon-button.js +54 -0
- package/dist/icon-picker.d.ts +15 -0
- package/dist/icon-picker.js +311 -0
- package/dist/icon-wrapper.d.ts +15 -0
- package/dist/icon-wrapper.js +52 -0
- package/dist/image-upload.d.ts +24 -0
- package/dist/image-upload.js +122 -0
- package/dist/index.d.ts +71 -0
- package/dist/index.js +155 -0
- package/dist/kbd.d.ts +15 -0
- package/dist/kbd.js +27 -0
- package/dist/mobile-preview.d.ts +36 -0
- package/dist/mobile-preview.js +167 -0
- package/dist/modal.d.ts +19 -0
- package/dist/modal.js +110 -0
- package/dist/multi-select.d.ts +30 -0
- package/dist/multi-select.js +261 -0
- package/dist/number-input.d.ts +21 -0
- package/dist/number-input.js +129 -0
- package/dist/otp-input.d.ts +13 -0
- package/dist/otp-input.js +114 -0
- package/dist/page-header.d.ts +15 -0
- package/dist/page-header.js +43 -0
- package/dist/page-state.d.ts +14 -0
- package/dist/page-state.js +29 -0
- package/dist/pagination.d.ts +20 -0
- package/dist/pagination.js +87 -0
- package/dist/popover.d.ts +11 -0
- package/dist/popover.js +70 -0
- package/dist/preview-drawer.d.ts +33 -0
- package/dist/preview-drawer.js +74 -0
- package/dist/progress-bar.d.ts +15 -0
- package/dist/progress-bar.js +56 -0
- package/dist/qr-code-display.d.ts +10 -0
- package/dist/qr-code-display.js +43 -0
- package/dist/radio-group.d.ts +19 -0
- package/dist/radio-group.js +78 -0
- package/dist/rating.d.ts +12 -0
- package/dist/rating.js +123 -0
- package/dist/rich-editor.d.ts +13 -0
- package/dist/rich-editor.js +97 -0
- package/dist/search-bar.d.ts +14 -0
- package/dist/search-bar.js +64 -0
- package/dist/section-header.d.ts +12 -0
- package/dist/section-header.js +41 -0
- package/dist/segmented-control.d.ts +24 -0
- package/dist/segmented-control.js +38 -0
- package/dist/select-picker.d.ts +24 -0
- package/dist/select-picker.js +157 -0
- package/dist/skeleton.d.ts +14 -0
- package/dist/skeleton.js +53 -0
- package/dist/slider.d.ts +17 -0
- package/dist/slider.js +151 -0
- package/dist/spinner.d.ts +13 -0
- package/dist/spinner.js +38 -0
- package/dist/stat-card.d.ts +20 -0
- package/dist/stat-card.js +87 -0
- package/dist/stats-summary.d.ts +13 -0
- package/dist/stats-summary.js +28 -0
- package/dist/status-badge.d.ts +19 -0
- package/dist/status-badge.js +41 -0
- package/dist/stepper.d.ts +12 -0
- package/dist/stepper.js +89 -0
- package/dist/tabs.d.ts +18 -0
- package/dist/tabs.js +70 -0
- package/dist/tag.d.ts +23 -0
- package/dist/tag.js +158 -0
- package/dist/time-picker.d.ts +19 -0
- package/dist/time-picker.js +222 -0
- package/dist/timeline.d.ts +15 -0
- package/dist/timeline.js +49 -0
- package/dist/toast.d.ts +18 -0
- package/dist/toast.js +108 -0
- package/dist/toggle-switch.d.ts +12 -0
- package/dist/toggle-switch.js +34 -0
- package/dist/tooltip.d.ts +9 -0
- package/dist/tooltip.js +69 -0
- package/dist/trip-day-map-lazy.d.ts +15 -0
- package/dist/trip-day-map-lazy.js +16 -0
- package/dist/trip-day-map.d.ts +15 -0
- package/dist/trip-day-map.js +62 -0
- package/package.json +73 -0
package/dist/slider.js
ADDED
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import "./chunk-ORMEWXMH.js";
|
|
3
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4
|
+
import { useRef } from "react";
|
|
5
|
+
function Slider({
|
|
6
|
+
value,
|
|
7
|
+
onChange,
|
|
8
|
+
min = 0,
|
|
9
|
+
max = 100,
|
|
10
|
+
step = 1,
|
|
11
|
+
label,
|
|
12
|
+
showValue = false,
|
|
13
|
+
formatValue,
|
|
14
|
+
disabled = false,
|
|
15
|
+
minRangeLabel = "Minimum value",
|
|
16
|
+
maxRangeLabel = "Maximum value",
|
|
17
|
+
valueLabel
|
|
18
|
+
}) {
|
|
19
|
+
var _a;
|
|
20
|
+
const isRange = Array.isArray(value);
|
|
21
|
+
const fmt = formatValue != null ? formatValue : ((v) => String(v));
|
|
22
|
+
const rangeContainerRef = useRef(null);
|
|
23
|
+
if (isRange) {
|
|
24
|
+
const [low, high] = value;
|
|
25
|
+
const lowPct = (low - min) / (max - min) * 100;
|
|
26
|
+
const highPct = (high - min) / (max - min) * 100;
|
|
27
|
+
const handleLowChange = (e) => {
|
|
28
|
+
const next = Math.min(Number(e.target.value), high - step);
|
|
29
|
+
onChange([next, high]);
|
|
30
|
+
};
|
|
31
|
+
const handleHighChange = (e) => {
|
|
32
|
+
const next = Math.max(Number(e.target.value), low + step);
|
|
33
|
+
onChange([low, next]);
|
|
34
|
+
};
|
|
35
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
|
|
36
|
+
(label || showValue) && /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
37
|
+
label && /* @__PURE__ */ jsx("span", { className: "text-sm font-semibold text-on-surface", children: label }),
|
|
38
|
+
showValue && /* @__PURE__ */ jsxs("span", { className: "text-sm font-bold text-primary", children: [
|
|
39
|
+
fmt(low),
|
|
40
|
+
" \u2013 ",
|
|
41
|
+
fmt(high)
|
|
42
|
+
] })
|
|
43
|
+
] }),
|
|
44
|
+
/* @__PURE__ */ jsxs("div", { className: "relative h-2 my-3", ref: rangeContainerRef, children: [
|
|
45
|
+
/* @__PURE__ */ jsx("div", { className: "absolute inset-0 rounded-full bg-surface-container-high" }),
|
|
46
|
+
/* @__PURE__ */ jsx(
|
|
47
|
+
"div",
|
|
48
|
+
{
|
|
49
|
+
className: "absolute top-0 h-2 rounded-full bg-primary",
|
|
50
|
+
style: { left: `${lowPct}%`, right: `${100 - highPct}%` }
|
|
51
|
+
}
|
|
52
|
+
),
|
|
53
|
+
/* @__PURE__ */ jsx(
|
|
54
|
+
"input",
|
|
55
|
+
{
|
|
56
|
+
type: "range",
|
|
57
|
+
min,
|
|
58
|
+
max,
|
|
59
|
+
step,
|
|
60
|
+
value: low,
|
|
61
|
+
disabled,
|
|
62
|
+
onChange: handleLowChange,
|
|
63
|
+
"aria-label": minRangeLabel,
|
|
64
|
+
className: "peer/low absolute w-full h-2 opacity-0 cursor-pointer disabled:cursor-not-allowed",
|
|
65
|
+
style: { zIndex: low > max - (max - min) / 2 ? 5 : 3 }
|
|
66
|
+
}
|
|
67
|
+
),
|
|
68
|
+
/* @__PURE__ */ jsx(
|
|
69
|
+
"input",
|
|
70
|
+
{
|
|
71
|
+
type: "range",
|
|
72
|
+
min,
|
|
73
|
+
max,
|
|
74
|
+
step,
|
|
75
|
+
value: high,
|
|
76
|
+
disabled,
|
|
77
|
+
onChange: handleHighChange,
|
|
78
|
+
"aria-label": maxRangeLabel,
|
|
79
|
+
className: "peer/high absolute w-full h-2 opacity-0 cursor-pointer disabled:cursor-not-allowed",
|
|
80
|
+
style: { zIndex: 4 }
|
|
81
|
+
}
|
|
82
|
+
),
|
|
83
|
+
/* @__PURE__ */ jsx(
|
|
84
|
+
"div",
|
|
85
|
+
{
|
|
86
|
+
className: "absolute top-1/2 -translate-y-1/2 w-4 h-4 rounded-full bg-white border-2 border-primary shadow pointer-events-none peer-focus-visible/low:ring-2 peer-focus-visible/low:ring-primary/30",
|
|
87
|
+
style: { left: `calc(${lowPct}% - 8px)` }
|
|
88
|
+
}
|
|
89
|
+
),
|
|
90
|
+
/* @__PURE__ */ jsx(
|
|
91
|
+
"div",
|
|
92
|
+
{
|
|
93
|
+
className: "absolute top-1/2 -translate-y-1/2 w-4 h-4 rounded-full bg-white border-2 border-primary shadow pointer-events-none peer-focus-visible/high:ring-2 peer-focus-visible/high:ring-primary/30",
|
|
94
|
+
style: { left: `calc(${highPct}% - 8px)` }
|
|
95
|
+
}
|
|
96
|
+
)
|
|
97
|
+
] }),
|
|
98
|
+
/* @__PURE__ */ jsxs("div", { className: "flex justify-between", children: [
|
|
99
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs text-on-surface-variant", children: fmt(min) }),
|
|
100
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs text-on-surface-variant", children: fmt(max) })
|
|
101
|
+
] })
|
|
102
|
+
] });
|
|
103
|
+
}
|
|
104
|
+
const single = value;
|
|
105
|
+
const pct = (single - min) / (max - min) * 100;
|
|
106
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
|
|
107
|
+
(label || showValue) && /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
108
|
+
label && /* @__PURE__ */ jsx("span", { className: "text-sm font-semibold text-on-surface", children: label }),
|
|
109
|
+
showValue && /* @__PURE__ */ jsx("span", { className: "text-sm font-bold text-primary", children: fmt(single) })
|
|
110
|
+
] }),
|
|
111
|
+
/* @__PURE__ */ jsxs("div", { className: "relative h-2 my-3", children: [
|
|
112
|
+
/* @__PURE__ */ jsx("div", { className: "absolute inset-0 rounded-full bg-surface-container-high" }),
|
|
113
|
+
/* @__PURE__ */ jsx(
|
|
114
|
+
"div",
|
|
115
|
+
{
|
|
116
|
+
className: "absolute top-0 left-0 h-2 rounded-full bg-primary",
|
|
117
|
+
style: { width: `${pct}%` }
|
|
118
|
+
}
|
|
119
|
+
),
|
|
120
|
+
/* @__PURE__ */ jsx(
|
|
121
|
+
"input",
|
|
122
|
+
{
|
|
123
|
+
type: "range",
|
|
124
|
+
min,
|
|
125
|
+
max,
|
|
126
|
+
step,
|
|
127
|
+
value: single,
|
|
128
|
+
disabled,
|
|
129
|
+
onChange: (e) => onChange(Number(e.target.value)),
|
|
130
|
+
"aria-label": (_a = valueLabel != null ? valueLabel : label) != null ? _a : "Value",
|
|
131
|
+
className: "peer absolute w-full h-2 opacity-0 cursor-pointer disabled:cursor-not-allowed",
|
|
132
|
+
style: { zIndex: 3 }
|
|
133
|
+
}
|
|
134
|
+
),
|
|
135
|
+
/* @__PURE__ */ jsx(
|
|
136
|
+
"div",
|
|
137
|
+
{
|
|
138
|
+
className: "absolute top-1/2 -translate-y-1/2 w-4 h-4 rounded-full bg-white border-2 border-primary shadow pointer-events-none peer-focus-visible:ring-2 peer-focus-visible:ring-primary/30",
|
|
139
|
+
style: { left: `calc(${pct}% - 8px)` }
|
|
140
|
+
}
|
|
141
|
+
)
|
|
142
|
+
] }),
|
|
143
|
+
/* @__PURE__ */ jsxs("div", { className: "flex justify-between", children: [
|
|
144
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs text-on-surface-variant", children: fmt(min) }),
|
|
145
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs text-on-surface-variant", children: fmt(max) })
|
|
146
|
+
] })
|
|
147
|
+
] });
|
|
148
|
+
}
|
|
149
|
+
export {
|
|
150
|
+
Slider
|
|
151
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
interface SpinnerProps {
|
|
2
|
+
size?: "xs" | "sm" | "md" | "lg";
|
|
3
|
+
color?: "primary" | "white" | "current";
|
|
4
|
+
className?: string;
|
|
5
|
+
loadingAriaLabel?: string;
|
|
6
|
+
}
|
|
7
|
+
declare function Spinner({ size, color, className, loadingAriaLabel, }: SpinnerProps): React.ReactNode;
|
|
8
|
+
interface FullPageSpinnerProps {
|
|
9
|
+
message?: string;
|
|
10
|
+
}
|
|
11
|
+
declare function FullPageSpinner({ message }: FullPageSpinnerProps): React.ReactNode;
|
|
12
|
+
|
|
13
|
+
export { FullPageSpinner, Spinner };
|
package/dist/spinner.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import "./chunk-ORMEWXMH.js";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
const SIZE_CLASSES = {
|
|
4
|
+
xs: "w-3 h-3 border-2",
|
|
5
|
+
sm: "w-4 h-4 border-2",
|
|
6
|
+
md: "w-6 h-6 border-2",
|
|
7
|
+
lg: "w-8 h-8 border-[3px]"
|
|
8
|
+
};
|
|
9
|
+
const COLOR_CLASSES = {
|
|
10
|
+
primary: "border-primary/20 border-t-primary",
|
|
11
|
+
white: "border-white/20 border-t-white",
|
|
12
|
+
current: "border-current/20 border-t-current"
|
|
13
|
+
};
|
|
14
|
+
function Spinner({
|
|
15
|
+
size = "md",
|
|
16
|
+
color = "primary",
|
|
17
|
+
className = "",
|
|
18
|
+
loadingAriaLabel = "Loading"
|
|
19
|
+
}) {
|
|
20
|
+
return /* @__PURE__ */ jsx(
|
|
21
|
+
"span",
|
|
22
|
+
{
|
|
23
|
+
role: "status",
|
|
24
|
+
"aria-label": loadingAriaLabel,
|
|
25
|
+
className: `inline-block rounded-full animate-spin ${SIZE_CLASSES[size]} ${COLOR_CLASSES[color]} ${className}`
|
|
26
|
+
}
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
function FullPageSpinner({ message }) {
|
|
30
|
+
return /* @__PURE__ */ jsxs("div", { className: "fixed inset-0 flex flex-col items-center justify-center gap-3 bg-white/80 backdrop-blur-sm z-50", children: [
|
|
31
|
+
/* @__PURE__ */ jsx(Spinner, { size: "lg", color: "primary" }),
|
|
32
|
+
message && /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-on-surface-variant", children: message })
|
|
33
|
+
] });
|
|
34
|
+
}
|
|
35
|
+
export {
|
|
36
|
+
FullPageSpinner,
|
|
37
|
+
Spinner
|
|
38
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { AppColor } from './icon-wrapper.js';
|
|
2
|
+
|
|
3
|
+
/** @deprecated use AppColor */
|
|
4
|
+
type StatCardTone = AppColor;
|
|
5
|
+
interface StatCardProps {
|
|
6
|
+
icon: string;
|
|
7
|
+
iconColor?: AppColor;
|
|
8
|
+
iconGradient?: string;
|
|
9
|
+
title: string;
|
|
10
|
+
value: string | number;
|
|
11
|
+
subtitle?: string;
|
|
12
|
+
limit?: number;
|
|
13
|
+
suffix?: string;
|
|
14
|
+
variant?: "default" | "pastel" | "hero" | "compact";
|
|
15
|
+
tone?: AppColor;
|
|
16
|
+
children?: React.ReactNode;
|
|
17
|
+
}
|
|
18
|
+
declare function StatCard({ icon, iconColor, iconGradient, title, value, subtitle, limit, suffix, variant, tone, children, }: StatCardProps): React.ReactNode;
|
|
19
|
+
|
|
20
|
+
export { StatCard, type StatCardTone };
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import "./chunk-ORMEWXMH.js";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { IconWrapper, appColorFg } from "./icon-wrapper";
|
|
4
|
+
const TONE_BG = {
|
|
5
|
+
primary: "bg-primary-container",
|
|
6
|
+
emerald: "bg-emerald-50",
|
|
7
|
+
amber: "bg-amber-50",
|
|
8
|
+
rose: "bg-rose-50",
|
|
9
|
+
red: "bg-red-50",
|
|
10
|
+
violet: "bg-violet-50",
|
|
11
|
+
blue: "bg-blue-50",
|
|
12
|
+
slate: "bg-slate-100",
|
|
13
|
+
cyan: "bg-cyan-50"
|
|
14
|
+
};
|
|
15
|
+
function StatCard({
|
|
16
|
+
icon,
|
|
17
|
+
iconColor = "primary",
|
|
18
|
+
iconGradient = "from-blue-100 to-blue-50",
|
|
19
|
+
title,
|
|
20
|
+
value,
|
|
21
|
+
subtitle,
|
|
22
|
+
limit,
|
|
23
|
+
suffix,
|
|
24
|
+
variant = "default",
|
|
25
|
+
tone = "primary",
|
|
26
|
+
children
|
|
27
|
+
}) {
|
|
28
|
+
if (variant === "compact") {
|
|
29
|
+
return /* @__PURE__ */ jsxs("div", { className: "bg-white rounded-lg border border-outline-variant/50 px-4 py-3 flex items-center gap-3", children: [
|
|
30
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: `material-symbols-outlined text-lg ${appColorFg[tone]} opacity-50`, style: { fontVariationSettings: "'FILL' 1" }, children: icon }),
|
|
31
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
32
|
+
/* @__PURE__ */ jsx("p", { className: "text-lg font-black text-on-surface leading-none tabular-nums", children: value }),
|
|
33
|
+
/* @__PURE__ */ jsx("p", { className: "text-[11px] text-on-surface-variant mt-0.5", children: title })
|
|
34
|
+
] })
|
|
35
|
+
] });
|
|
36
|
+
}
|
|
37
|
+
if (variant === "hero") {
|
|
38
|
+
return /* @__PURE__ */ jsxs("div", { className: "bg-white p-6 rounded-2xl border border-surface-container-high shadow-sm flex flex-col justify-center text-center space-y-3", children: [
|
|
39
|
+
/* @__PURE__ */ jsx("div", { className: `w-14 h-14 mx-auto flex items-center justify-center rounded-2xl ${TONE_BG[tone]}`, children: /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: `material-symbols-outlined text-2xl ${appColorFg[tone]}`, style: { fontVariationSettings: "'FILL' 1" }, children: icon }) }),
|
|
40
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
41
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs uppercase tracking-widest font-bold text-outline", children: title }),
|
|
42
|
+
/* @__PURE__ */ jsx("p", { className: "text-2xl md:text-3xl font-black text-on-surface mt-2", children: value }),
|
|
43
|
+
subtitle && /* @__PURE__ */ jsx("p", { className: "text-xs text-on-surface-variant mt-1", children: subtitle })
|
|
44
|
+
] }),
|
|
45
|
+
children
|
|
46
|
+
] });
|
|
47
|
+
}
|
|
48
|
+
if (variant === "pastel") {
|
|
49
|
+
return /* @__PURE__ */ jsxs("div", { className: "bg-white rounded-3xl border border-outline-variant/50 p-5 md:p-6 flex items-center gap-4 hover:shadow-md transition-shadow", children: [
|
|
50
|
+
/* @__PURE__ */ jsx("div", { className: `w-11 h-11 rounded-2xl bg-linear-to-br ${iconGradient} flex items-center justify-center shrink-0`, children: /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: `material-symbols-outlined ${appColorFg[iconColor]}`, style: { fontVariationSettings: "'FILL' 1" }, children: icon }) }),
|
|
51
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
|
|
52
|
+
/* @__PURE__ */ jsx("p", { className: "text-[10px] uppercase tracking-widest font-bold text-on-surface-variant", children: title }),
|
|
53
|
+
/* @__PURE__ */ jsx("p", { className: "text-2xl md:text-3xl font-black text-on-surface mt-0.5", children: value }),
|
|
54
|
+
children
|
|
55
|
+
] })
|
|
56
|
+
] });
|
|
57
|
+
}
|
|
58
|
+
const pct = limit ? Math.round(Number(value) / limit * 100) : 0;
|
|
59
|
+
return /* @__PURE__ */ jsxs("div", { className: "bg-white rounded-2xl p-6 border border-outline-variant/10 shadow-sm hover:shadow-md transition-shadow", children: [
|
|
60
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 mb-4", children: [
|
|
61
|
+
/* @__PURE__ */ jsx(IconWrapper, { icon, color: iconColor, size: "md" }),
|
|
62
|
+
/* @__PURE__ */ jsx("h3", { className: "font-semibold text-on-surface", children: title })
|
|
63
|
+
] }),
|
|
64
|
+
/* @__PURE__ */ jsxs("p", { className: "text-2xl font-bold text-on-surface", children: [
|
|
65
|
+
value,
|
|
66
|
+
limit != null && /* @__PURE__ */ jsxs("span", { className: "text-sm font-normal text-on-surface-variant", children: [
|
|
67
|
+
" / ",
|
|
68
|
+
limit
|
|
69
|
+
] }),
|
|
70
|
+
suffix && /* @__PURE__ */ jsxs("span", { className: "text-sm font-normal text-on-surface-variant", children: [
|
|
71
|
+
" ",
|
|
72
|
+
suffix
|
|
73
|
+
] })
|
|
74
|
+
] }),
|
|
75
|
+
limit != null && /* @__PURE__ */ jsx("div", { className: "h-2 rounded-full bg-slate-100 mt-3", children: /* @__PURE__ */ jsx(
|
|
76
|
+
"div",
|
|
77
|
+
{
|
|
78
|
+
className: "h-full rounded-full bg-primary transition-[width] duration-500",
|
|
79
|
+
style: { width: `${Math.min(pct, 100)}%` }
|
|
80
|
+
}
|
|
81
|
+
) }),
|
|
82
|
+
children
|
|
83
|
+
] });
|
|
84
|
+
}
|
|
85
|
+
export {
|
|
86
|
+
StatCard
|
|
87
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
interface StatItem {
|
|
2
|
+
value: string | number;
|
|
3
|
+
label: string;
|
|
4
|
+
icon?: string;
|
|
5
|
+
}
|
|
6
|
+
interface StatsSummaryProps {
|
|
7
|
+
stats: StatItem[];
|
|
8
|
+
columns?: 2 | 3 | 4;
|
|
9
|
+
className?: string;
|
|
10
|
+
}
|
|
11
|
+
declare function StatsSummary({ stats, columns, className, }: StatsSummaryProps): React.ReactNode;
|
|
12
|
+
|
|
13
|
+
export { StatsSummary };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import "./chunk-ORMEWXMH.js";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
const COLS = {
|
|
4
|
+
2: "grid-cols-2",
|
|
5
|
+
3: "grid-cols-3",
|
|
6
|
+
4: "grid-cols-4"
|
|
7
|
+
};
|
|
8
|
+
function StatsSummary({
|
|
9
|
+
stats,
|
|
10
|
+
columns = 3,
|
|
11
|
+
className = ""
|
|
12
|
+
}) {
|
|
13
|
+
return /* @__PURE__ */ jsx("div", { className: `grid ${COLS[columns]} ${className}`, children: stats.map((stat, i) => /* @__PURE__ */ jsxs(
|
|
14
|
+
"div",
|
|
15
|
+
{
|
|
16
|
+
className: `text-center px-4 py-2 ${i > 0 ? "border-l border-outline-variant/30" : ""}`,
|
|
17
|
+
children: [
|
|
18
|
+
stat.icon && /* @__PURE__ */ jsx("span", { className: "material-symbols-outlined text-base text-on-surface-variant mb-0.5 block", "aria-hidden": "true", children: stat.icon }),
|
|
19
|
+
/* @__PURE__ */ jsx("p", { className: "text-2xl font-black text-on-surface tabular-nums leading-tight", children: stat.value }),
|
|
20
|
+
/* @__PURE__ */ jsx("p", { className: "text-[10px] text-on-surface-variant font-semibold uppercase tracking-wide mt-0.5", children: stat.label })
|
|
21
|
+
]
|
|
22
|
+
},
|
|
23
|
+
stat.label
|
|
24
|
+
)) });
|
|
25
|
+
}
|
|
26
|
+
export {
|
|
27
|
+
StatsSummary
|
|
28
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { AppColor } from './icon-wrapper.js';
|
|
2
|
+
|
|
3
|
+
/** @deprecated use AppColor */
|
|
4
|
+
type StatusTone = AppColor;
|
|
5
|
+
interface StatusConfig {
|
|
6
|
+
label: string;
|
|
7
|
+
tone?: AppColor;
|
|
8
|
+
/** Raw class override — use only when named tones don't cover the case */
|
|
9
|
+
cls?: string;
|
|
10
|
+
}
|
|
11
|
+
interface StatusBadgeProps {
|
|
12
|
+
status: string;
|
|
13
|
+
config?: Record<string, StatusConfig>;
|
|
14
|
+
variant?: "pill" | "dot";
|
|
15
|
+
className?: string;
|
|
16
|
+
}
|
|
17
|
+
declare function StatusBadge({ status, config, variant, className }: StatusBadgeProps): React.ReactNode;
|
|
18
|
+
|
|
19
|
+
export { StatusBadge, type StatusConfig, type StatusTone };
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import "./chunk-ORMEWXMH.js";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { appColorFg } from "./icon-wrapper";
|
|
4
|
+
const PILL_BG = {
|
|
5
|
+
primary: "bg-primary-container",
|
|
6
|
+
emerald: "bg-emerald-100",
|
|
7
|
+
amber: "bg-amber-100",
|
|
8
|
+
rose: "bg-rose-100",
|
|
9
|
+
red: "bg-red-100",
|
|
10
|
+
violet: "bg-violet-100",
|
|
11
|
+
blue: "bg-blue-100",
|
|
12
|
+
slate: "bg-surface-container",
|
|
13
|
+
cyan: "bg-cyan-100"
|
|
14
|
+
};
|
|
15
|
+
const DOT_COLOR = {
|
|
16
|
+
primary: "bg-primary",
|
|
17
|
+
emerald: "bg-emerald-500",
|
|
18
|
+
amber: "bg-amber-500",
|
|
19
|
+
rose: "bg-rose-500",
|
|
20
|
+
red: "bg-red-500",
|
|
21
|
+
violet: "bg-violet-500",
|
|
22
|
+
blue: "bg-blue-500",
|
|
23
|
+
slate: "bg-outline",
|
|
24
|
+
cyan: "bg-cyan-500"
|
|
25
|
+
};
|
|
26
|
+
function StatusBadge({ status, config = {}, variant = "pill", className = "" }) {
|
|
27
|
+
var _a, _b, _c;
|
|
28
|
+
const c = (_a = config[status]) != null ? _a : { label: status, tone: "slate" };
|
|
29
|
+
const tone = (_b = c.tone) != null ? _b : "slate";
|
|
30
|
+
if (variant === "dot") {
|
|
31
|
+
return /* @__PURE__ */ jsxs("span", { className: `inline-flex items-center gap-1.5 text-xs font-semibold ${appColorFg[tone]} ${className}`, children: [
|
|
32
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: `w-1.5 h-1.5 rounded-full ${DOT_COLOR[tone]}` }),
|
|
33
|
+
c.label
|
|
34
|
+
] });
|
|
35
|
+
}
|
|
36
|
+
const pillClass = (_c = c.cls) != null ? _c : `${PILL_BG[tone]} ${appColorFg[tone]}`;
|
|
37
|
+
return /* @__PURE__ */ jsx("span", { className: `px-2 py-0.5 rounded text-[10px] font-bold uppercase tracking-widest ${pillClass} ${className}`, children: c.label });
|
|
38
|
+
}
|
|
39
|
+
export {
|
|
40
|
+
StatusBadge
|
|
41
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
interface StepItem {
|
|
2
|
+
label: string;
|
|
3
|
+
description?: string;
|
|
4
|
+
}
|
|
5
|
+
interface StepperProps {
|
|
6
|
+
steps: StepItem[];
|
|
7
|
+
currentStep: number;
|
|
8
|
+
orientation?: "horizontal" | "vertical";
|
|
9
|
+
}
|
|
10
|
+
declare function Stepper({ steps, currentStep, orientation, }: StepperProps): React.ReactNode;
|
|
11
|
+
|
|
12
|
+
export { type StepItem, Stepper };
|
package/dist/stepper.js
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import "./chunk-ORMEWXMH.js";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
function Stepper({
|
|
4
|
+
steps,
|
|
5
|
+
currentStep,
|
|
6
|
+
orientation = "horizontal"
|
|
7
|
+
}) {
|
|
8
|
+
if (orientation === "vertical") {
|
|
9
|
+
return /* @__PURE__ */ jsx("ol", { className: "flex flex-col", "aria-label": "Steps", children: steps.map((step, index) => {
|
|
10
|
+
const isCompleted = index < currentStep;
|
|
11
|
+
const isCurrent = index === currentStep;
|
|
12
|
+
return /* @__PURE__ */ jsxs("li", { className: "flex gap-3", "aria-current": isCurrent ? "step" : void 0, children: [
|
|
13
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center", children: [
|
|
14
|
+
/* @__PURE__ */ jsx(
|
|
15
|
+
"div",
|
|
16
|
+
{
|
|
17
|
+
className: `w-8 h-8 rounded-full flex items-center justify-center text-xs font-bold shrink-0 ${isCompleted ? "bg-emerald-500 text-white" : isCurrent ? "bg-primary text-on-primary shadow-lg" : "bg-surface-container-high text-on-surface-variant"}`,
|
|
18
|
+
children: isCompleted ? /* @__PURE__ */ jsx(
|
|
19
|
+
"span",
|
|
20
|
+
{
|
|
21
|
+
className: "material-symbols-outlined text-base",
|
|
22
|
+
style: { fontVariationSettings: "'FILL' 1", fontSize: "16px" },
|
|
23
|
+
children: "check"
|
|
24
|
+
}
|
|
25
|
+
) : /* @__PURE__ */ jsx("span", { children: index + 1 })
|
|
26
|
+
}
|
|
27
|
+
),
|
|
28
|
+
index < steps.length - 1 && /* @__PURE__ */ jsx(
|
|
29
|
+
"div",
|
|
30
|
+
{
|
|
31
|
+
className: `w-0.5 h-8 ml-0 mt-1 ${isCompleted ? "bg-emerald-500" : "bg-outline-variant/30"}`
|
|
32
|
+
}
|
|
33
|
+
)
|
|
34
|
+
] }),
|
|
35
|
+
/* @__PURE__ */ jsxs("div", { className: `pb-6 ${index === steps.length - 1 ? "pb-0" : ""}`, children: [
|
|
36
|
+
/* @__PURE__ */ jsx(
|
|
37
|
+
"p",
|
|
38
|
+
{
|
|
39
|
+
className: `text-xs font-semibold leading-8 ${isCurrent ? "text-primary" : isCompleted ? "text-emerald-600" : "text-on-surface-variant"}`,
|
|
40
|
+
children: step.label
|
|
41
|
+
}
|
|
42
|
+
),
|
|
43
|
+
step.description && /* @__PURE__ */ jsx("p", { className: "text-[10px] text-on-surface-variant -mt-1", children: step.description })
|
|
44
|
+
] })
|
|
45
|
+
] }, index);
|
|
46
|
+
}) });
|
|
47
|
+
}
|
|
48
|
+
return /* @__PURE__ */ jsx("ol", { className: "flex items-center w-full", "aria-label": "Steps", children: steps.map((step, index) => {
|
|
49
|
+
const isCompleted = index < currentStep;
|
|
50
|
+
const isCurrent = index === currentStep;
|
|
51
|
+
return /* @__PURE__ */ jsxs("li", { className: "flex items-center flex-1 last:flex-none", "aria-current": isCurrent ? "step" : void 0, children: [
|
|
52
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-1.5", children: [
|
|
53
|
+
/* @__PURE__ */ jsx(
|
|
54
|
+
"div",
|
|
55
|
+
{
|
|
56
|
+
className: `w-8 h-8 rounded-full flex items-center justify-center text-xs font-bold shrink-0 ${isCompleted ? "bg-emerald-500 text-white" : isCurrent ? "bg-primary text-on-primary shadow-lg" : "bg-surface-container-high text-on-surface-variant"}`,
|
|
57
|
+
children: isCompleted ? /* @__PURE__ */ jsx(
|
|
58
|
+
"span",
|
|
59
|
+
{
|
|
60
|
+
className: "material-symbols-outlined text-base",
|
|
61
|
+
style: { fontVariationSettings: "'FILL' 1", fontSize: "16px" },
|
|
62
|
+
children: "check"
|
|
63
|
+
}
|
|
64
|
+
) : /* @__PURE__ */ jsx("span", { children: index + 1 })
|
|
65
|
+
}
|
|
66
|
+
),
|
|
67
|
+
/* @__PURE__ */ jsxs("div", { className: "text-center", children: [
|
|
68
|
+
/* @__PURE__ */ jsx(
|
|
69
|
+
"p",
|
|
70
|
+
{
|
|
71
|
+
className: `text-xs font-semibold ${isCurrent ? "text-primary" : isCompleted ? "text-emerald-600" : "text-on-surface-variant"}`,
|
|
72
|
+
children: step.label
|
|
73
|
+
}
|
|
74
|
+
),
|
|
75
|
+
step.description && /* @__PURE__ */ jsx("p", { className: "text-[10px] text-on-surface-variant", children: step.description })
|
|
76
|
+
] })
|
|
77
|
+
] }),
|
|
78
|
+
index < steps.length - 1 && /* @__PURE__ */ jsx(
|
|
79
|
+
"div",
|
|
80
|
+
{
|
|
81
|
+
className: `h-0.5 flex-1 mx-2 mb-6 ${isCompleted ? "bg-emerald-500" : "bg-outline-variant/30"}`
|
|
82
|
+
}
|
|
83
|
+
)
|
|
84
|
+
] }, index);
|
|
85
|
+
}) });
|
|
86
|
+
}
|
|
87
|
+
export {
|
|
88
|
+
Stepper
|
|
89
|
+
};
|
package/dist/tabs.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
|
|
3
|
+
interface TabItem {
|
|
4
|
+
id: string;
|
|
5
|
+
label: string;
|
|
6
|
+
icon?: string;
|
|
7
|
+
badge?: string | number;
|
|
8
|
+
disabled?: boolean;
|
|
9
|
+
}
|
|
10
|
+
interface TabsProps {
|
|
11
|
+
items: TabItem[];
|
|
12
|
+
value: string;
|
|
13
|
+
onChange: (id: string) => void;
|
|
14
|
+
variant?: "line" | "pill";
|
|
15
|
+
}
|
|
16
|
+
declare function Tabs({ items, value, onChange, variant, }: TabsProps): react_jsx_runtime.JSX.Element;
|
|
17
|
+
|
|
18
|
+
export { type TabItem, Tabs };
|
package/dist/tabs.js
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import "./chunk-ORMEWXMH.js";
|
|
3
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4
|
+
function Tabs({
|
|
5
|
+
items,
|
|
6
|
+
value,
|
|
7
|
+
onChange,
|
|
8
|
+
variant = "line"
|
|
9
|
+
}) {
|
|
10
|
+
if (variant === "pill") {
|
|
11
|
+
return /* @__PURE__ */ jsx(
|
|
12
|
+
"div",
|
|
13
|
+
{
|
|
14
|
+
role: "tablist",
|
|
15
|
+
className: "flex gap-2 p-1 bg-surface-container rounded-xl",
|
|
16
|
+
children: items.map((item) => {
|
|
17
|
+
const isActive = value === item.id;
|
|
18
|
+
return /* @__PURE__ */ jsxs(
|
|
19
|
+
"button",
|
|
20
|
+
{
|
|
21
|
+
role: "tab",
|
|
22
|
+
type: "button",
|
|
23
|
+
"aria-selected": isActive,
|
|
24
|
+
disabled: item.disabled,
|
|
25
|
+
onClick: () => !item.disabled && onChange(item.id),
|
|
26
|
+
className: `flex items-center gap-1.5 px-4 py-2 text-sm font-semibold transition-colors duration-200 rounded-lg focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/30 ${item.disabled ? "opacity-40 cursor-not-allowed" : "active:scale-[0.98]"} ${isActive ? "bg-surface shadow-sm text-on-surface" : "text-on-surface-variant hover:text-on-surface"}`,
|
|
27
|
+
children: [
|
|
28
|
+
item.icon && /* @__PURE__ */ jsx("span", { className: "material-symbols-outlined text-base", "aria-hidden": "true", children: item.icon }),
|
|
29
|
+
/* @__PURE__ */ jsx("span", { children: item.label }),
|
|
30
|
+
item.badge !== void 0 && /* @__PURE__ */ jsx("span", { className: "ml-0.5 bg-surface-container-high text-on-surface-variant text-xs font-medium px-1.5 py-0.5 rounded-full", children: item.badge })
|
|
31
|
+
]
|
|
32
|
+
},
|
|
33
|
+
item.id
|
|
34
|
+
);
|
|
35
|
+
})
|
|
36
|
+
}
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
return /* @__PURE__ */ jsx(
|
|
40
|
+
"div",
|
|
41
|
+
{
|
|
42
|
+
role: "tablist",
|
|
43
|
+
className: "flex border-b border-outline-variant/30 overflow-x-auto",
|
|
44
|
+
children: items.map((item) => {
|
|
45
|
+
const isActive = value === item.id;
|
|
46
|
+
return /* @__PURE__ */ jsxs(
|
|
47
|
+
"button",
|
|
48
|
+
{
|
|
49
|
+
role: "tab",
|
|
50
|
+
type: "button",
|
|
51
|
+
"aria-selected": isActive,
|
|
52
|
+
disabled: item.disabled,
|
|
53
|
+
onClick: () => !item.disabled && onChange(item.id),
|
|
54
|
+
className: `flex items-center gap-1.5 px-4 py-3 text-sm font-semibold transition-colors duration-200 relative whitespace-nowrap focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/30 ${item.disabled ? "opacity-40 cursor-not-allowed" : ""} ${isActive ? "text-primary" : "text-on-surface-variant hover:text-on-surface"}`,
|
|
55
|
+
children: [
|
|
56
|
+
item.icon && /* @__PURE__ */ jsx("span", { className: "material-symbols-outlined text-base", "aria-hidden": "true", children: item.icon }),
|
|
57
|
+
/* @__PURE__ */ jsx("span", { children: item.label }),
|
|
58
|
+
item.badge !== void 0 && /* @__PURE__ */ jsx("span", { className: "ml-0.5 bg-surface-container text-on-surface-variant text-xs font-medium px-1.5 py-0.5 rounded-full", children: item.badge }),
|
|
59
|
+
isActive && /* @__PURE__ */ jsx("span", { className: "absolute bottom-0 left-0 right-0 h-0.5 bg-primary rounded-full" })
|
|
60
|
+
]
|
|
61
|
+
},
|
|
62
|
+
item.id
|
|
63
|
+
);
|
|
64
|
+
})
|
|
65
|
+
}
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
export {
|
|
69
|
+
Tabs
|
|
70
|
+
};
|
package/dist/tag.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
|
|
3
|
+
type AppColor = "primary" | "emerald" | "amber" | "rose" | "red" | "violet" | "blue" | "slate" | "cyan";
|
|
4
|
+
interface TagProps {
|
|
5
|
+
label: string;
|
|
6
|
+
onRemove?: () => void;
|
|
7
|
+
color?: AppColor;
|
|
8
|
+
size?: "sm" | "md";
|
|
9
|
+
icon?: string;
|
|
10
|
+
selected?: boolean;
|
|
11
|
+
onClick?: () => void;
|
|
12
|
+
}
|
|
13
|
+
declare function Tag({ label, onRemove, color, size, icon, selected, onClick, }: TagProps): react_jsx_runtime.JSX.Element;
|
|
14
|
+
interface TagGroupProps {
|
|
15
|
+
value: string[];
|
|
16
|
+
onChange: (tags: string[]) => void;
|
|
17
|
+
placeholder?: string;
|
|
18
|
+
label?: string;
|
|
19
|
+
maxTags?: number;
|
|
20
|
+
}
|
|
21
|
+
declare function TagGroup({ value, onChange, placeholder, label, maxTags, }: TagGroupProps): react_jsx_runtime.JSX.Element;
|
|
22
|
+
|
|
23
|
+
export { type AppColor, Tag, TagGroup };
|