@mesob/ui 0.0.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/components/accordion.d.ts +10 -0
- package/dist/components/accordion.js +74 -0
- package/dist/components/accordion.js.map +1 -0
- package/dist/components/alert-dialog.d.ts +17 -0
- package/dist/components/alert-dialog.js +187 -0
- package/dist/components/alert-dialog.js.map +1 -0
- package/dist/components/alert.d.ts +13 -0
- package/dist/components/alert.js +74 -0
- package/dist/components/alert.js.map +1 -0
- package/dist/components/animated-tabs.d.ts +26 -0
- package/dist/components/animated-tabs.js +290 -0
- package/dist/components/animated-tabs.js.map +1 -0
- package/dist/components/aspect-ratio.d.ts +6 -0
- package/dist/components/aspect-ratio.js +14 -0
- package/dist/components/aspect-ratio.js.map +1 -0
- package/dist/components/avatar.d.ts +9 -0
- package/dist/components/avatar.js +63 -0
- package/dist/components/avatar.js.map +1 -0
- package/dist/components/badge.d.ts +13 -0
- package/dist/components/badge.js +48 -0
- package/dist/components/badge.js.map +1 -0
- package/dist/components/breadcrumb.d.ts +14 -0
- package/dist/components/breadcrumb.js +110 -0
- package/dist/components/breadcrumb.js.map +1 -0
- package/dist/components/button-group.d.ts +17 -0
- package/dist/components/button-group.js +106 -0
- package/dist/components/button-group.js.map +1 -0
- package/dist/components/button.d.ts +14 -0
- package/dist/components/button.js +60 -0
- package/dist/components/button.js.map +1 -0
- package/dist/components/calendar.d.ts +13 -0
- package/dist/components/calendar.js +254 -0
- package/dist/components/calendar.js.map +1 -0
- package/dist/components/card.d.ts +12 -0
- package/dist/components/card.js +98 -0
- package/dist/components/card.js.map +1 -0
- package/dist/components/carousel.d.ts +24 -0
- package/dist/components/carousel.js +260 -0
- package/dist/components/carousel.js.map +1 -0
- package/dist/components/chart.d.ts +43 -0
- package/dist/components/chart.js +261 -0
- package/dist/components/chart.js.map +1 -0
- package/dist/components/checkbox.d.ts +7 -0
- package/dist/components/checkbox.js +41 -0
- package/dist/components/checkbox.js.map +1 -0
- package/dist/components/collapsible.d.ts +8 -0
- package/dist/components/collapsible.js +38 -0
- package/dist/components/collapsible.js.map +1 -0
- package/dist/components/command.d.ts +22 -0
- package/dist/components/command.js +281 -0
- package/dist/components/command.js.map +1 -0
- package/dist/components/context-menu.d.ts +28 -0
- package/dist/components/context-menu.js +233 -0
- package/dist/components/context-menu.js.map +1 -0
- package/dist/components/data-table/index.d.ts +46 -0
- package/dist/components/data-table/index.js +639 -0
- package/dist/components/data-table/index.js.map +1 -0
- package/dist/components/dialog.d.ts +18 -0
- package/dist/components/dialog.js +146 -0
- package/dist/components/dialog.js.map +1 -0
- package/dist/components/drawer.d.ts +16 -0
- package/dist/components/drawer.js +138 -0
- package/dist/components/drawer.js.map +1 -0
- package/dist/components/dropdown-menu.d.ts +28 -0
- package/dist/components/dropdown-menu.js +241 -0
- package/dist/components/dropdown-menu.js.map +1 -0
- package/dist/components/empty.d.ts +15 -0
- package/dist/components/empty.js +110 -0
- package/dist/components/empty.js.map +1 -0
- package/dist/components/entity/index.d.ts +160 -0
- package/dist/components/entity/index.js +1671 -0
- package/dist/components/entity/index.js.map +1 -0
- package/dist/components/field.d.ts +30 -0
- package/dist/components/field.js +279 -0
- package/dist/components/field.js.map +1 -0
- package/dist/components/form.d.ts +28 -0
- package/dist/components/form.js +150 -0
- package/dist/components/form.js.map +1 -0
- package/dist/components/hover-card.d.ts +9 -0
- package/dist/components/hover-card.js +48 -0
- package/dist/components/hover-card.js.map +1 -0
- package/dist/components/input-group.d.ts +20 -0
- package/dist/components/input-group.js +257 -0
- package/dist/components/input-group.js.map +1 -0
- package/dist/components/input-otp.d.ts +14 -0
- package/dist/components/input-otp.js +76 -0
- package/dist/components/input-otp.js.map +1 -0
- package/dist/components/input.d.ts +6 -0
- package/dist/components/input.js +29 -0
- package/dist/components/input.js.map +1 -0
- package/dist/components/item.d.ts +28 -0
- package/dist/components/item.js +220 -0
- package/dist/components/item.js.map +1 -0
- package/dist/components/jiret-logo.d.ts +13 -0
- package/dist/components/jiret-logo.js +80 -0
- package/dist/components/jiret-logo.js.map +1 -0
- package/dist/components/kbd.d.ts +6 -0
- package/dist/components/kbd.js +39 -0
- package/dist/components/kbd.js.map +1 -0
- package/dist/components/label.d.ts +7 -0
- package/dist/components/label.js +32 -0
- package/dist/components/label.js.map +1 -0
- package/dist/components/menubar.d.ts +29 -0
- package/dist/components/menubar.js +261 -0
- package/dist/components/menubar.js.map +1 -0
- package/dist/components/navigation-menu.d.ts +18 -0
- package/dist/components/navigation-menu.js +178 -0
- package/dist/components/navigation-menu.js.map +1 -0
- package/dist/components/pagination.d.ts +18 -0
- package/dist/components/pagination.js +160 -0
- package/dist/components/pagination.js.map +1 -0
- package/dist/components/popover.d.ts +10 -0
- package/dist/components/popover.js +54 -0
- package/dist/components/popover.js.map +1 -0
- package/dist/components/powered-by.d.ts +5 -0
- package/dist/components/powered-by.js +98 -0
- package/dist/components/powered-by.js.map +1 -0
- package/dist/components/progress.d.ts +7 -0
- package/dist/components/progress.js +41 -0
- package/dist/components/progress.js.map +1 -0
- package/dist/components/radio-group.d.ts +8 -0
- package/dist/components/radio-group.js +55 -0
- package/dist/components/radio-group.js.map +1 -0
- package/dist/components/resizable.d.ts +11 -0
- package/dist/components/resizable.js +58 -0
- package/dist/components/resizable.js.map +1 -0
- package/dist/components/scroll-area.d.ts +8 -0
- package/dist/components/scroll-area.js +70 -0
- package/dist/components/scroll-area.js.map +1 -0
- package/dist/components/section/index.d.ts +14 -0
- package/dist/components/section/index.js +139 -0
- package/dist/components/section/index.js.map +1 -0
- package/dist/components/select.d.ts +18 -0
- package/dist/components/select.js +181 -0
- package/dist/components/select.js.map +1 -0
- package/dist/components/separator.d.ts +7 -0
- package/dist/components/separator.js +36 -0
- package/dist/components/separator.js.map +1 -0
- package/dist/components/sheet.d.ts +16 -0
- package/dist/components/sheet.js +136 -0
- package/dist/components/sheet.js.map +1 -0
- package/dist/components/sidebar.d.ts +75 -0
- package/dist/components/sidebar.js +909 -0
- package/dist/components/sidebar.js.map +1 -0
- package/dist/components/skeleton.d.ts +5 -0
- package/dist/components/skeleton.js +23 -0
- package/dist/components/skeleton.js.map +1 -0
- package/dist/components/slider.d.ts +7 -0
- package/dist/components/slider.js +76 -0
- package/dist/components/slider.js.map +1 -0
- package/dist/components/sonner.d.ts +6 -0
- package/dist/components/sonner.js +41 -0
- package/dist/components/sonner.js.map +1 -0
- package/dist/components/spinner.d.ts +6 -0
- package/dist/components/spinner.js +28 -0
- package/dist/components/spinner.js.map +1 -0
- package/dist/components/spotlight-search.d.ts +25 -0
- package/dist/components/spotlight-search.js +387 -0
- package/dist/components/spotlight-search.js.map +1 -0
- package/dist/components/switch.d.ts +7 -0
- package/dist/components/switch.js +41 -0
- package/dist/components/switch.js.map +1 -0
- package/dist/components/table.d.ts +13 -0
- package/dist/components/table.js +124 -0
- package/dist/components/table.js.map +1 -0
- package/dist/components/tabs.d.ts +10 -0
- package/dist/components/tabs.js +77 -0
- package/dist/components/tabs.js.map +1 -0
- package/dist/components/textarea.d.ts +6 -0
- package/dist/components/textarea.js +26 -0
- package/dist/components/textarea.js.map +1 -0
- package/dist/components/theme-toggle.d.ts +8 -0
- package/dist/components/theme-toggle.js +86 -0
- package/dist/components/theme-toggle.js.map +1 -0
- package/dist/components/toggle-group.d.ts +14 -0
- package/dist/components/toggle-group.js +102 -0
- package/dist/components/toggle-group.js.map +1 -0
- package/dist/components/toggle.d.ts +13 -0
- package/dist/components/toggle.js +53 -0
- package/dist/components/toggle.js.map +1 -0
- package/dist/components/tooltip.d.ts +10 -0
- package/dist/components/tooltip.js +65 -0
- package/dist/components/tooltip.js.map +1 -0
- package/dist/hooks/use-mobile.d.ts +3 -0
- package/dist/hooks/use-mobile.js +22 -0
- package/dist/hooks/use-mobile.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/utils.d.ts +5 -0
- package/dist/lib/utils.js +10 -0
- package/dist/lib/utils.js.map +1 -0
- package/package.json +123 -0
- package/src/styles/globals.css +125 -0
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
// src/lib/utils.ts
|
|
4
|
+
import { clsx } from "clsx";
|
|
5
|
+
import { twMerge } from "tailwind-merge";
|
|
6
|
+
function cn(...inputs) {
|
|
7
|
+
return twMerge(clsx(inputs));
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
// src/components/animated-tabs.tsx
|
|
11
|
+
import { IconChevronDown } from "@tabler/icons-react";
|
|
12
|
+
import { motion } from "motion/react";
|
|
13
|
+
import { useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
14
|
+
|
|
15
|
+
// src/components/dropdown-menu.tsx
|
|
16
|
+
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
|
|
17
|
+
import { IconCheck, IconChevronRight, IconCircle } from "@tabler/icons-react";
|
|
18
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
19
|
+
function DropdownMenu({
|
|
20
|
+
...props
|
|
21
|
+
}) {
|
|
22
|
+
return /* @__PURE__ */ jsx(DropdownMenuPrimitive.Root, { "data-slot": "dropdown-menu", ...props });
|
|
23
|
+
}
|
|
24
|
+
function DropdownMenuTrigger({
|
|
25
|
+
...props
|
|
26
|
+
}) {
|
|
27
|
+
return /* @__PURE__ */ jsx(
|
|
28
|
+
DropdownMenuPrimitive.Trigger,
|
|
29
|
+
{
|
|
30
|
+
"data-slot": "dropdown-menu-trigger",
|
|
31
|
+
...props
|
|
32
|
+
}
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
function DropdownMenuContent({
|
|
36
|
+
className,
|
|
37
|
+
sideOffset = 4,
|
|
38
|
+
...props
|
|
39
|
+
}) {
|
|
40
|
+
return /* @__PURE__ */ jsx(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ jsx(
|
|
41
|
+
DropdownMenuPrimitive.Content,
|
|
42
|
+
{
|
|
43
|
+
"data-slot": "dropdown-menu-content",
|
|
44
|
+
sideOffset,
|
|
45
|
+
className: cn(
|
|
46
|
+
"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 max-h-(--radix-dropdown-menu-content-available-height) min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border p-1 shadow-md",
|
|
47
|
+
className
|
|
48
|
+
),
|
|
49
|
+
...props
|
|
50
|
+
}
|
|
51
|
+
) });
|
|
52
|
+
}
|
|
53
|
+
function DropdownMenuItem({
|
|
54
|
+
className,
|
|
55
|
+
inset,
|
|
56
|
+
variant = "default",
|
|
57
|
+
...props
|
|
58
|
+
}) {
|
|
59
|
+
return /* @__PURE__ */ jsx(
|
|
60
|
+
DropdownMenuPrimitive.Item,
|
|
61
|
+
{
|
|
62
|
+
"data-slot": "dropdown-menu-item",
|
|
63
|
+
"data-inset": inset,
|
|
64
|
+
"data-variant": variant,
|
|
65
|
+
className: cn(
|
|
66
|
+
"focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
67
|
+
className
|
|
68
|
+
),
|
|
69
|
+
...props
|
|
70
|
+
}
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// src/components/animated-tabs.tsx
|
|
75
|
+
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
76
|
+
function AnimatedTabs({
|
|
77
|
+
tabs,
|
|
78
|
+
activeTab: controlledActiveTab,
|
|
79
|
+
defaultTab,
|
|
80
|
+
onTabChange,
|
|
81
|
+
className,
|
|
82
|
+
linkComponent: LinkComponent
|
|
83
|
+
}) {
|
|
84
|
+
const [internalActiveTab, setInternalActiveTab] = useState(
|
|
85
|
+
defaultTab ?? tabs[0]?.value ?? ""
|
|
86
|
+
);
|
|
87
|
+
const activeTab = controlledActiveTab ?? internalActiveTab;
|
|
88
|
+
const [visibleTabs, setVisibleTabs] = useState(tabs);
|
|
89
|
+
const [overflowTabs, setOverflowTabs] = useState([]);
|
|
90
|
+
const containerRef = useRef(null);
|
|
91
|
+
const tabsListRef = useRef(null);
|
|
92
|
+
const dropdownTriggerRef = useRef(null);
|
|
93
|
+
const tabRefs = useRef([]);
|
|
94
|
+
const [underlineStyle, setUnderlineStyle] = useState({ left: 0, width: 0 });
|
|
95
|
+
const handleTabChange = (newValue) => {
|
|
96
|
+
if (!controlledActiveTab) {
|
|
97
|
+
setInternalActiveTab(newValue);
|
|
98
|
+
}
|
|
99
|
+
onTabChange?.(newValue);
|
|
100
|
+
};
|
|
101
|
+
useLayoutEffect(() => {
|
|
102
|
+
const updateTabs = () => {
|
|
103
|
+
if (!containerRef.current) {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
if (!tabsListRef.current) {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
const containerWidth = containerRef.current.offsetWidth;
|
|
110
|
+
const dropdownWidth = 80;
|
|
111
|
+
const padding = 16;
|
|
112
|
+
const availableWidth = containerWidth - padding;
|
|
113
|
+
let totalWidth = 0;
|
|
114
|
+
const visible = [];
|
|
115
|
+
const overflow = [];
|
|
116
|
+
let hasOverflow = false;
|
|
117
|
+
for (const [i, tab] of tabs.entries()) {
|
|
118
|
+
const tabEl = tabRefs.current[i];
|
|
119
|
+
if (!tabEl || tabEl.offsetWidth === 0) {
|
|
120
|
+
if (hasOverflow) {
|
|
121
|
+
overflow.push(tab);
|
|
122
|
+
} else {
|
|
123
|
+
visible.push(tab);
|
|
124
|
+
}
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
const tabWidth = tabEl.scrollWidth || tabEl.offsetWidth;
|
|
128
|
+
const wouldFitWithoutDropdown = totalWidth + tabWidth <= availableWidth;
|
|
129
|
+
const wouldFitWithDropdown = totalWidth + tabWidth + dropdownWidth <= availableWidth;
|
|
130
|
+
if (!hasOverflow && wouldFitWithoutDropdown) {
|
|
131
|
+
visible.push(tab);
|
|
132
|
+
totalWidth += tabWidth;
|
|
133
|
+
} else if (!hasOverflow && wouldFitWithDropdown) {
|
|
134
|
+
visible.push(tab);
|
|
135
|
+
totalWidth += tabWidth;
|
|
136
|
+
hasOverflow = true;
|
|
137
|
+
} else {
|
|
138
|
+
hasOverflow = true;
|
|
139
|
+
overflow.push(tab);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
setVisibleTabs(visible);
|
|
143
|
+
setOverflowTabs(overflow);
|
|
144
|
+
};
|
|
145
|
+
const timeoutId = setTimeout(updateTabs, 100);
|
|
146
|
+
const resizeObserver = new ResizeObserver(() => {
|
|
147
|
+
setTimeout(updateTabs, 0);
|
|
148
|
+
});
|
|
149
|
+
if (containerRef.current) {
|
|
150
|
+
resizeObserver.observe(containerRef.current);
|
|
151
|
+
}
|
|
152
|
+
if (tabsListRef.current) {
|
|
153
|
+
resizeObserver.observe(tabsListRef.current);
|
|
154
|
+
}
|
|
155
|
+
window.addEventListener("resize", updateTabs);
|
|
156
|
+
return () => {
|
|
157
|
+
clearTimeout(timeoutId);
|
|
158
|
+
resizeObserver.disconnect();
|
|
159
|
+
window.removeEventListener("resize", updateTabs);
|
|
160
|
+
};
|
|
161
|
+
}, [tabs]);
|
|
162
|
+
useLayoutEffect(() => {
|
|
163
|
+
const updateUnderline = () => {
|
|
164
|
+
const isInOverflow = overflowTabs.some((tab) => tab.value === activeTab);
|
|
165
|
+
if (isInOverflow && dropdownTriggerRef.current) {
|
|
166
|
+
const { offsetLeft, offsetWidth } = dropdownTriggerRef.current;
|
|
167
|
+
setUnderlineStyle({
|
|
168
|
+
left: offsetLeft,
|
|
169
|
+
width: offsetWidth
|
|
170
|
+
});
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
const activeTabIndex = tabs.findIndex((tab) => tab.value === activeTab);
|
|
174
|
+
const activeTabElement = tabRefs.current[activeTabIndex];
|
|
175
|
+
if (activeTabElement && visibleTabs.some((tab) => tab.value === activeTab)) {
|
|
176
|
+
const { offsetLeft, offsetWidth } = activeTabElement;
|
|
177
|
+
setUnderlineStyle({
|
|
178
|
+
left: offsetLeft,
|
|
179
|
+
width: offsetWidth
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
updateUnderline();
|
|
184
|
+
}, [activeTab, visibleTabs, overflowTabs, tabs]);
|
|
185
|
+
const activeTabData = useMemo(
|
|
186
|
+
() => tabs.find((tab) => tab.value === activeTab),
|
|
187
|
+
[tabs, activeTab]
|
|
188
|
+
);
|
|
189
|
+
const renderTab = (tab, originalIndex) => {
|
|
190
|
+
const isActive = activeTab === tab.value;
|
|
191
|
+
const tabClassName = cn(
|
|
192
|
+
"relative z-10 px-4 py-3 text-sm font-medium transition-all duration-200",
|
|
193
|
+
"hover:bg-muted/60 rounded-t-md",
|
|
194
|
+
isActive ? "text-primary" : "text-muted-foreground hover:text-foreground"
|
|
195
|
+
);
|
|
196
|
+
const setRef = (el) => {
|
|
197
|
+
if (originalIndex >= 0) {
|
|
198
|
+
tabRefs.current[originalIndex] = el;
|
|
199
|
+
}
|
|
200
|
+
};
|
|
201
|
+
if (tab.href && LinkComponent) {
|
|
202
|
+
return /* @__PURE__ */ jsx2(
|
|
203
|
+
LinkComponent,
|
|
204
|
+
{
|
|
205
|
+
href: tab.href,
|
|
206
|
+
className: tabClassName,
|
|
207
|
+
ref: setRef,
|
|
208
|
+
children: tab.name
|
|
209
|
+
},
|
|
210
|
+
tab.value
|
|
211
|
+
);
|
|
212
|
+
}
|
|
213
|
+
return /* @__PURE__ */ jsx2(
|
|
214
|
+
"button",
|
|
215
|
+
{
|
|
216
|
+
type: "button",
|
|
217
|
+
ref: setRef,
|
|
218
|
+
onClick: () => handleTabChange(tab.value),
|
|
219
|
+
className: tabClassName,
|
|
220
|
+
children: tab.name
|
|
221
|
+
},
|
|
222
|
+
tab.value
|
|
223
|
+
);
|
|
224
|
+
};
|
|
225
|
+
const renderDropdownItem = (tab) => {
|
|
226
|
+
const isActive = activeTab === tab.value;
|
|
227
|
+
const itemClassName = cn(
|
|
228
|
+
"cursor-pointer",
|
|
229
|
+
isActive && "bg-accent font-medium"
|
|
230
|
+
);
|
|
231
|
+
if (tab.href && LinkComponent) {
|
|
232
|
+
return /* @__PURE__ */ jsx2(DropdownMenuItem, { asChild: true, className: itemClassName, children: /* @__PURE__ */ jsx2(LinkComponent, { href: tab.href, children: tab.name }) }, tab.value);
|
|
233
|
+
}
|
|
234
|
+
return /* @__PURE__ */ jsx2(
|
|
235
|
+
DropdownMenuItem,
|
|
236
|
+
{
|
|
237
|
+
onClick: () => handleTabChange(tab.value),
|
|
238
|
+
className: itemClassName,
|
|
239
|
+
children: tab.name
|
|
240
|
+
},
|
|
241
|
+
tab.value
|
|
242
|
+
);
|
|
243
|
+
};
|
|
244
|
+
return /* @__PURE__ */ jsxs2("div", { className: cn("flex flex-col", className), children: [
|
|
245
|
+
/* @__PURE__ */ jsx2("div", { ref: containerRef, className: "w-full", children: /* @__PURE__ */ jsxs2("div", { ref: tabsListRef, className: "relative flex items-center", children: [
|
|
246
|
+
visibleTabs.map((tab) => {
|
|
247
|
+
const originalIndex = tabs.findIndex((t) => t.value === tab.value);
|
|
248
|
+
return renderTab(tab, originalIndex);
|
|
249
|
+
}),
|
|
250
|
+
overflowTabs.length > 0 && /* @__PURE__ */ jsxs2(DropdownMenu, { children: [
|
|
251
|
+
/* @__PURE__ */ jsxs2(
|
|
252
|
+
DropdownMenuTrigger,
|
|
253
|
+
{
|
|
254
|
+
ref: dropdownTriggerRef,
|
|
255
|
+
className: cn(
|
|
256
|
+
"relative z-10 flex items-center gap-1 px-4 py-3 text-sm font-medium transition-all duration-200",
|
|
257
|
+
"hover:bg-muted/60 rounded-t-md",
|
|
258
|
+
overflowTabs.some((tab) => tab.value === activeTab) ? "text-primary" : "text-muted-foreground hover:text-foreground"
|
|
259
|
+
),
|
|
260
|
+
children: [
|
|
261
|
+
"More",
|
|
262
|
+
/* @__PURE__ */ jsx2(IconChevronDown, { className: "h-4 w-4" })
|
|
263
|
+
]
|
|
264
|
+
}
|
|
265
|
+
),
|
|
266
|
+
/* @__PURE__ */ jsx2(DropdownMenuContent, { align: "start", className: "min-w-40", children: overflowTabs.map(renderDropdownItem) })
|
|
267
|
+
] }),
|
|
268
|
+
/* @__PURE__ */ jsx2(
|
|
269
|
+
motion.div,
|
|
270
|
+
{
|
|
271
|
+
className: "absolute bottom-0 left-0 z-20 h-0.5 bg-primary",
|
|
272
|
+
animate: {
|
|
273
|
+
left: underlineStyle.left,
|
|
274
|
+
width: underlineStyle.width
|
|
275
|
+
},
|
|
276
|
+
transition: {
|
|
277
|
+
type: "spring",
|
|
278
|
+
stiffness: 400,
|
|
279
|
+
damping: 40
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
)
|
|
283
|
+
] }) }),
|
|
284
|
+
activeTabData?.content && /* @__PURE__ */ jsx2("div", { className: "flex-1", children: activeTabData.content })
|
|
285
|
+
] });
|
|
286
|
+
}
|
|
287
|
+
export {
|
|
288
|
+
AnimatedTabs
|
|
289
|
+
};
|
|
290
|
+
//# sourceMappingURL=animated-tabs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/lib/utils.ts","../../src/components/animated-tabs.tsx","../../src/components/dropdown-menu.tsx"],"sourcesContent":["import { type ClassValue, clsx } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","'use client';\n\nimport { cn } from '@mesob/ui/lib/utils';\nimport { IconChevronDown } from '@tabler/icons-react';\nimport { motion } from 'motion/react';\nimport type { ComponentType, ReactNode } from 'react';\nimport { useLayoutEffect, useMemo, useRef, useState } from 'react';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from './dropdown-menu';\n\nexport type AnimatedTabItem = {\n name: string;\n value: string;\n href?: string;\n content?: ReactNode;\n};\n\ntype LinkComponentProps = {\n href: string;\n className?: string;\n children: ReactNode;\n ref?: React.Ref<HTMLAnchorElement>;\n};\n\ntype AnimatedTabsProps = {\n tabs: AnimatedTabItem[];\n activeTab?: string;\n defaultTab?: string;\n onTabChange?: (value: string) => void;\n className?: string;\n linkComponent?: ComponentType<LinkComponentProps>;\n};\n\nexport function AnimatedTabs({\n tabs,\n activeTab: controlledActiveTab,\n defaultTab,\n onTabChange,\n className,\n linkComponent: LinkComponent,\n}: AnimatedTabsProps) {\n const [internalActiveTab, setInternalActiveTab] = useState(\n defaultTab ?? tabs[0]?.value ?? '',\n );\n const activeTab = controlledActiveTab ?? internalActiveTab;\n\n const [visibleTabs, setVisibleTabs] = useState<AnimatedTabItem[]>(tabs);\n const [overflowTabs, setOverflowTabs] = useState<AnimatedTabItem[]>([]);\n const containerRef = useRef<HTMLDivElement>(null);\n const tabsListRef = useRef<HTMLDivElement>(null);\n const dropdownTriggerRef = useRef<HTMLButtonElement>(null);\n const tabRefs = useRef<(HTMLElement | null)[]>([]);\n const [underlineStyle, setUnderlineStyle] = useState({ left: 0, width: 0 });\n\n const handleTabChange = (newValue: string) => {\n if (!controlledActiveTab) {\n setInternalActiveTab(newValue);\n }\n onTabChange?.(newValue);\n };\n\n useLayoutEffect(() => {\n const updateTabs = () => {\n if (!containerRef.current) {\n return;\n }\n if (!tabsListRef.current) {\n return;\n }\n\n const containerWidth = containerRef.current.offsetWidth;\n const dropdownWidth = 80;\n const padding = 16;\n const availableWidth = containerWidth - padding;\n\n let totalWidth = 0;\n const visible: AnimatedTabItem[] = [];\n const overflow: AnimatedTabItem[] = [];\n let hasOverflow = false;\n\n for (const [i, tab] of tabs.entries()) {\n const tabEl = tabRefs.current[i];\n\n if (!tabEl || tabEl.offsetWidth === 0) {\n if (hasOverflow) {\n overflow.push(tab);\n } else {\n visible.push(tab);\n }\n continue;\n }\n\n const tabWidth = tabEl.scrollWidth || tabEl.offsetWidth;\n const wouldFitWithoutDropdown = totalWidth + tabWidth <= availableWidth;\n const wouldFitWithDropdown =\n totalWidth + tabWidth + dropdownWidth <= availableWidth;\n\n if (!hasOverflow && wouldFitWithoutDropdown) {\n visible.push(tab);\n totalWidth += tabWidth;\n } else if (!hasOverflow && wouldFitWithDropdown) {\n visible.push(tab);\n totalWidth += tabWidth;\n hasOverflow = true;\n } else {\n hasOverflow = true;\n overflow.push(tab);\n }\n }\n\n setVisibleTabs(visible);\n setOverflowTabs(overflow);\n };\n\n const timeoutId = setTimeout(updateTabs, 100);\n\n const resizeObserver = new ResizeObserver(() => {\n setTimeout(updateTabs, 0);\n });\n\n if (containerRef.current) {\n resizeObserver.observe(containerRef.current);\n }\n\n if (tabsListRef.current) {\n resizeObserver.observe(tabsListRef.current);\n }\n\n window.addEventListener('resize', updateTabs);\n\n return () => {\n clearTimeout(timeoutId);\n resizeObserver.disconnect();\n window.removeEventListener('resize', updateTabs);\n };\n }, [tabs]);\n\n useLayoutEffect(() => {\n const updateUnderline = () => {\n const isInOverflow = overflowTabs.some((tab) => tab.value === activeTab);\n\n if (isInOverflow && dropdownTriggerRef.current) {\n const { offsetLeft, offsetWidth } = dropdownTriggerRef.current;\n setUnderlineStyle({\n left: offsetLeft,\n width: offsetWidth,\n });\n return;\n }\n\n const activeTabIndex = tabs.findIndex((tab) => tab.value === activeTab);\n const activeTabElement = tabRefs.current[activeTabIndex];\n\n if (\n activeTabElement &&\n visibleTabs.some((tab) => tab.value === activeTab)\n ) {\n const { offsetLeft, offsetWidth } = activeTabElement;\n setUnderlineStyle({\n left: offsetLeft,\n width: offsetWidth,\n });\n }\n };\n\n updateUnderline();\n }, [activeTab, visibleTabs, overflowTabs, tabs]);\n\n const activeTabData = useMemo(\n () => tabs.find((tab) => tab.value === activeTab),\n [tabs, activeTab],\n );\n\n const renderTab = (tab: AnimatedTabItem, originalIndex: number) => {\n const isActive = activeTab === tab.value;\n\n const tabClassName = cn(\n 'relative z-10 px-4 py-3 text-sm font-medium transition-all duration-200',\n 'hover:bg-muted/60 rounded-t-md',\n isActive ? 'text-primary' : 'text-muted-foreground hover:text-foreground',\n );\n\n const setRef = (el: HTMLElement | null) => {\n if (originalIndex >= 0) {\n tabRefs.current[originalIndex] = el;\n }\n };\n\n if (tab.href && LinkComponent) {\n return (\n <LinkComponent\n key={tab.value}\n href={tab.href}\n className={tabClassName}\n ref={setRef as React.Ref<HTMLAnchorElement>}\n >\n {tab.name}\n </LinkComponent>\n );\n }\n\n return (\n <button\n key={tab.value}\n type=\"button\"\n ref={setRef}\n onClick={() => handleTabChange(tab.value)}\n className={tabClassName}\n >\n {tab.name}\n </button>\n );\n };\n\n const renderDropdownItem = (tab: AnimatedTabItem) => {\n const isActive = activeTab === tab.value;\n const itemClassName = cn(\n 'cursor-pointer',\n isActive && 'bg-accent font-medium',\n );\n\n if (tab.href && LinkComponent) {\n return (\n <DropdownMenuItem key={tab.value} asChild className={itemClassName}>\n <LinkComponent href={tab.href}>{tab.name}</LinkComponent>\n </DropdownMenuItem>\n );\n }\n\n return (\n <DropdownMenuItem\n key={tab.value}\n onClick={() => handleTabChange(tab.value)}\n className={itemClassName}\n >\n {tab.name}\n </DropdownMenuItem>\n );\n };\n\n return (\n <div className={cn('flex flex-col', className)}>\n <div ref={containerRef} className=\"w-full\">\n <div ref={tabsListRef} className=\"relative flex items-center\">\n {visibleTabs.map((tab) => {\n const originalIndex = tabs.findIndex((t) => t.value === tab.value);\n return renderTab(tab, originalIndex);\n })}\n\n {overflowTabs.length > 0 && (\n <DropdownMenu>\n <DropdownMenuTrigger\n ref={dropdownTriggerRef}\n className={cn(\n 'relative z-10 flex items-center gap-1 px-4 py-3 text-sm font-medium transition-all duration-200',\n 'hover:bg-muted/60 rounded-t-md',\n overflowTabs.some((tab) => tab.value === activeTab)\n ? 'text-primary'\n : 'text-muted-foreground hover:text-foreground',\n )}\n >\n More\n <IconChevronDown className=\"h-4 w-4\" />\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"start\" className=\"min-w-40\">\n {overflowTabs.map(renderDropdownItem)}\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n\n <motion.div\n className=\"absolute bottom-0 left-0 z-20 h-0.5 bg-primary\"\n animate={{\n left: underlineStyle.left,\n width: underlineStyle.width,\n }}\n transition={{\n type: 'spring',\n stiffness: 400,\n damping: 40,\n }}\n />\n </div>\n </div>\n\n {activeTabData?.content && (\n <div className=\"flex-1\">{activeTabData.content}</div>\n )}\n </div>\n );\n}\n","'use client';\n\nimport { cn } from '@mesob/ui/lib/utils';\nimport * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';\nimport { IconCheck, IconChevronRight, IconCircle } from '@tabler/icons-react';\nimport type * as React from 'react';\n\nfunction DropdownMenu({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Root>) {\n return <DropdownMenuPrimitive.Root data-slot=\"dropdown-menu\" {...props} />;\n}\n\nfunction DropdownMenuPortal({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Portal>) {\n return (\n <DropdownMenuPrimitive.Portal data-slot=\"dropdown-menu-portal\" {...props} />\n );\n}\n\nfunction DropdownMenuTrigger({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>) {\n return (\n <DropdownMenuPrimitive.Trigger\n data-slot=\"dropdown-menu-trigger\"\n {...props}\n />\n );\n}\n\nfunction DropdownMenuContent({\n className,\n sideOffset = 4,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Content>) {\n return (\n <DropdownMenuPrimitive.Portal>\n <DropdownMenuPrimitive.Content\n data-slot=\"dropdown-menu-content\"\n sideOffset={sideOffset}\n className={cn(\n 'bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 max-h-(--radix-dropdown-menu-content-available-height) min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border p-1 shadow-md',\n className,\n )}\n {...props}\n />\n </DropdownMenuPrimitive.Portal>\n );\n}\n\nfunction DropdownMenuGroup({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Group>) {\n return (\n <DropdownMenuPrimitive.Group data-slot=\"dropdown-menu-group\" {...props} />\n );\n}\n\nfunction DropdownMenuItem({\n className,\n inset,\n variant = 'default',\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Item> & {\n inset?: boolean;\n variant?: 'default' | 'destructive';\n}) {\n return (\n <DropdownMenuPrimitive.Item\n data-slot=\"dropdown-menu-item\"\n data-inset={inset}\n data-variant={variant}\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction DropdownMenuCheckboxItem({\n className,\n children,\n checked,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem>) {\n return (\n <DropdownMenuPrimitive.CheckboxItem\n data-slot=\"dropdown-menu-checkbox-item\"\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className,\n )}\n checked={checked}\n {...props}\n >\n <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n <DropdownMenuPrimitive.ItemIndicator>\n <IconCheck className=\"size-4\" />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.CheckboxItem>\n );\n}\n\nfunction DropdownMenuRadioGroup({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioGroup>) {\n return (\n <DropdownMenuPrimitive.RadioGroup\n data-slot=\"dropdown-menu-radio-group\"\n {...props}\n />\n );\n}\n\nfunction DropdownMenuRadioItem({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem>) {\n return (\n <DropdownMenuPrimitive.RadioItem\n data-slot=\"dropdown-menu-radio-item\"\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className,\n )}\n {...props}\n >\n <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n <DropdownMenuPrimitive.ItemIndicator>\n <IconCircle className=\"size-2 fill-current\" />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.RadioItem>\n );\n}\n\nfunction DropdownMenuLabel({\n className,\n inset,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Label> & {\n inset?: boolean;\n}) {\n return (\n <DropdownMenuPrimitive.Label\n data-slot=\"dropdown-menu-label\"\n data-inset={inset}\n className={cn(\n 'px-2 py-1.5 text-sm font-medium data-[inset]:pl-8',\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction DropdownMenuSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Separator>) {\n return (\n <DropdownMenuPrimitive.Separator\n data-slot=\"dropdown-menu-separator\"\n className={cn('bg-border -mx-1 my-1 h-px', className)}\n {...props}\n />\n );\n}\n\nfunction DropdownMenuShortcut({\n className,\n ...props\n}: React.ComponentProps<'span'>) {\n return (\n <span\n data-slot=\"dropdown-menu-shortcut\"\n className={cn(\n 'text-muted-foreground ml-auto text-xs tracking-widest',\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction DropdownMenuSub({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Sub>) {\n return <DropdownMenuPrimitive.Sub data-slot=\"dropdown-menu-sub\" {...props} />;\n}\n\nfunction DropdownMenuSubTrigger({\n className,\n inset,\n children,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.SubTrigger> & {\n inset?: boolean;\n}) {\n return (\n <DropdownMenuPrimitive.SubTrigger\n data-slot=\"dropdown-menu-sub-trigger\"\n data-inset={inset}\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className,\n )}\n {...props}\n >\n {children}\n <IconChevronRight className=\"ml-auto size-4\" />\n </DropdownMenuPrimitive.SubTrigger>\n );\n}\n\nfunction DropdownMenuSubContent({\n className,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.SubContent>) {\n return (\n <DropdownMenuPrimitive.SubContent\n data-slot=\"dropdown-menu-sub-content\"\n className={cn(\n 'bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-hidden rounded-md border p-1 shadow-lg',\n className,\n )}\n {...props}\n />\n );\n}\n\nexport {\n DropdownMenu,\n DropdownMenuPortal,\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuLabel,\n DropdownMenuItem,\n DropdownMenuCheckboxItem,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuSeparator,\n DropdownMenuShortcut,\n DropdownMenuSub,\n DropdownMenuSubTrigger,\n DropdownMenuSubContent,\n};\n"],"mappings":"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","names":["jsx","jsxs"]}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import * as AspectRatioPrimitive from '@radix-ui/react-aspect-ratio';
|
|
3
|
+
|
|
4
|
+
declare function AspectRatio({ ...props }: React.ComponentProps<typeof AspectRatioPrimitive.Root>): react_jsx_runtime.JSX.Element;
|
|
5
|
+
|
|
6
|
+
export { AspectRatio };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
// src/components/aspect-ratio.tsx
|
|
4
|
+
import * as AspectRatioPrimitive from "@radix-ui/react-aspect-ratio";
|
|
5
|
+
import { jsx } from "react/jsx-runtime";
|
|
6
|
+
function AspectRatio({
|
|
7
|
+
...props
|
|
8
|
+
}) {
|
|
9
|
+
return /* @__PURE__ */ jsx(AspectRatioPrimitive.Root, { "data-slot": "aspect-ratio", ...props });
|
|
10
|
+
}
|
|
11
|
+
export {
|
|
12
|
+
AspectRatio
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=aspect-ratio.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/aspect-ratio.tsx"],"sourcesContent":["'use client';\n\nimport * as AspectRatioPrimitive from '@radix-ui/react-aspect-ratio';\n\nfunction AspectRatio({\n ...props\n}: React.ComponentProps<typeof AspectRatioPrimitive.Root>) {\n return <AspectRatioPrimitive.Root data-slot=\"aspect-ratio\" {...props} />;\n}\n\nexport { AspectRatio };\n"],"mappings":";;;AAEA,YAAY,0BAA0B;AAK7B;AAHT,SAAS,YAAY;AAAA,EACnB,GAAG;AACL,GAA2D;AACzD,SAAO,oBAAsB,2BAArB,EAA0B,aAAU,gBAAgB,GAAG,OAAO;AACxE;","names":[]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import * as AvatarPrimitive from '@radix-ui/react-avatar';
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
|
|
5
|
+
declare function Avatar({ className, ...props }: React.ComponentProps<typeof AvatarPrimitive.Root>): react_jsx_runtime.JSX.Element;
|
|
6
|
+
declare function AvatarImage({ className, ...props }: React.ComponentProps<typeof AvatarPrimitive.Image>): react_jsx_runtime.JSX.Element;
|
|
7
|
+
declare function AvatarFallback({ className, ...props }: React.ComponentProps<typeof AvatarPrimitive.Fallback>): react_jsx_runtime.JSX.Element;
|
|
8
|
+
|
|
9
|
+
export { Avatar, AvatarFallback, AvatarImage };
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
// src/lib/utils.ts
|
|
4
|
+
import { clsx } from "clsx";
|
|
5
|
+
import { twMerge } from "tailwind-merge";
|
|
6
|
+
function cn(...inputs) {
|
|
7
|
+
return twMerge(clsx(inputs));
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
// src/components/avatar.tsx
|
|
11
|
+
import * as AvatarPrimitive from "@radix-ui/react-avatar";
|
|
12
|
+
import { jsx } from "react/jsx-runtime";
|
|
13
|
+
function Avatar({
|
|
14
|
+
className,
|
|
15
|
+
...props
|
|
16
|
+
}) {
|
|
17
|
+
return /* @__PURE__ */ jsx(
|
|
18
|
+
AvatarPrimitive.Root,
|
|
19
|
+
{
|
|
20
|
+
"data-slot": "avatar",
|
|
21
|
+
className: cn(
|
|
22
|
+
"relative flex size-8 shrink-0 overflow-hidden rounded-full",
|
|
23
|
+
className
|
|
24
|
+
),
|
|
25
|
+
...props
|
|
26
|
+
}
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
function AvatarImage({
|
|
30
|
+
className,
|
|
31
|
+
...props
|
|
32
|
+
}) {
|
|
33
|
+
return /* @__PURE__ */ jsx(
|
|
34
|
+
AvatarPrimitive.Image,
|
|
35
|
+
{
|
|
36
|
+
"data-slot": "avatar-image",
|
|
37
|
+
className: cn("aspect-square size-full", className),
|
|
38
|
+
...props
|
|
39
|
+
}
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
function AvatarFallback({
|
|
43
|
+
className,
|
|
44
|
+
...props
|
|
45
|
+
}) {
|
|
46
|
+
return /* @__PURE__ */ jsx(
|
|
47
|
+
AvatarPrimitive.Fallback,
|
|
48
|
+
{
|
|
49
|
+
"data-slot": "avatar-fallback",
|
|
50
|
+
className: cn(
|
|
51
|
+
"bg-muted flex size-full items-center justify-center rounded-full",
|
|
52
|
+
className
|
|
53
|
+
),
|
|
54
|
+
...props
|
|
55
|
+
}
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
export {
|
|
59
|
+
Avatar,
|
|
60
|
+
AvatarFallback,
|
|
61
|
+
AvatarImage
|
|
62
|
+
};
|
|
63
|
+
//# sourceMappingURL=avatar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/lib/utils.ts","../../src/components/avatar.tsx"],"sourcesContent":["import { type ClassValue, clsx } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","'use client';\n\nimport { cn } from '@mesob/ui/lib/utils';\nimport * as AvatarPrimitive from '@radix-ui/react-avatar';\nimport type * as React from 'react';\n\nfunction Avatar({\n className,\n ...props\n}: React.ComponentProps<typeof AvatarPrimitive.Root>) {\n return (\n <AvatarPrimitive.Root\n data-slot=\"avatar\"\n className={cn(\n 'relative flex size-8 shrink-0 overflow-hidden rounded-full',\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction AvatarImage({\n className,\n ...props\n}: React.ComponentProps<typeof AvatarPrimitive.Image>) {\n return (\n <AvatarPrimitive.Image\n data-slot=\"avatar-image\"\n className={cn('aspect-square size-full', className)}\n {...props}\n />\n );\n}\n\nfunction AvatarFallback({\n className,\n ...props\n}: React.ComponentProps<typeof AvatarPrimitive.Fallback>) {\n return (\n <AvatarPrimitive.Fallback\n data-slot=\"avatar-fallback\"\n className={cn(\n 'bg-muted flex size-full items-center justify-center rounded-full',\n className,\n )}\n {...props}\n />\n );\n}\n\nexport { Avatar, AvatarImage, AvatarFallback };\n"],"mappings":";;;AAAA,SAA0B,YAAY;AACtC,SAAS,eAAe;AAEjB,SAAS,MAAM,QAAsB;AAC1C,SAAO,QAAQ,KAAK,MAAM,CAAC;AAC7B;;;ACFA,YAAY,qBAAqB;AAQ7B;AALJ,SAAS,OAAO;AAAA,EACd;AAAA,EACA,GAAG;AACL,GAAsD;AACpD,SACE;AAAA,IAAiB;AAAA,IAAhB;AAAA,MACC,aAAU;AAAA,MACV,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;AAEA,SAAS,YAAY;AAAA,EACnB;AAAA,EACA,GAAG;AACL,GAAuD;AACrD,SACE;AAAA,IAAiB;AAAA,IAAhB;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,2BAA2B,SAAS;AAAA,MACjD,GAAG;AAAA;AAAA,EACN;AAEJ;AAEA,SAAS,eAAe;AAAA,EACtB;AAAA,EACA,GAAG;AACL,GAA0D;AACxD,SACE;AAAA,IAAiB;AAAA,IAAhB;AAAA,MACC,aAAU;AAAA,MACV,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;","names":[]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import * as class_variance_authority_types from 'class-variance-authority/types';
|
|
3
|
+
import { VariantProps } from 'class-variance-authority';
|
|
4
|
+
import * as React from 'react';
|
|
5
|
+
|
|
6
|
+
declare const badgeVariants: (props?: ({
|
|
7
|
+
variant?: "default" | "destructive" | "outline" | "secondary" | null | undefined;
|
|
8
|
+
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
9
|
+
declare function Badge({ className, variant, asChild, ...props }: React.ComponentProps<'span'> & VariantProps<typeof badgeVariants> & {
|
|
10
|
+
asChild?: boolean;
|
|
11
|
+
}): react_jsx_runtime.JSX.Element;
|
|
12
|
+
|
|
13
|
+
export { Badge, badgeVariants };
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
// src/lib/utils.ts
|
|
2
|
+
import { clsx } from "clsx";
|
|
3
|
+
import { twMerge } from "tailwind-merge";
|
|
4
|
+
function cn(...inputs) {
|
|
5
|
+
return twMerge(clsx(inputs));
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
// src/components/badge.tsx
|
|
9
|
+
import { Slot } from "@radix-ui/react-slot";
|
|
10
|
+
import { cva } from "class-variance-authority";
|
|
11
|
+
import { jsx } from "react/jsx-runtime";
|
|
12
|
+
var badgeVariants = cva(
|
|
13
|
+
"inline-flex items-center justify-center rounded-full border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden",
|
|
14
|
+
{
|
|
15
|
+
variants: {
|
|
16
|
+
variant: {
|
|
17
|
+
default: "border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90",
|
|
18
|
+
secondary: "border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90",
|
|
19
|
+
destructive: "border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
|
|
20
|
+
outline: "text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground"
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
defaultVariants: {
|
|
24
|
+
variant: "default"
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
);
|
|
28
|
+
function Badge({
|
|
29
|
+
className,
|
|
30
|
+
variant,
|
|
31
|
+
asChild = false,
|
|
32
|
+
...props
|
|
33
|
+
}) {
|
|
34
|
+
const Comp = asChild ? Slot : "span";
|
|
35
|
+
return /* @__PURE__ */ jsx(
|
|
36
|
+
Comp,
|
|
37
|
+
{
|
|
38
|
+
"data-slot": "badge",
|
|
39
|
+
className: cn(badgeVariants({ variant }), className),
|
|
40
|
+
...props
|
|
41
|
+
}
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
export {
|
|
45
|
+
Badge,
|
|
46
|
+
badgeVariants
|
|
47
|
+
};
|
|
48
|
+
//# sourceMappingURL=badge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/lib/utils.ts","../../src/components/badge.tsx"],"sourcesContent":["import { type ClassValue, clsx } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","import { cn } from '@mesob/ui/lib/utils';\nimport { Slot } from '@radix-ui/react-slot';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport type * as React from 'react';\n\nconst badgeVariants = cva(\n 'inline-flex items-center justify-center rounded-full border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden',\n {\n variants: {\n variant: {\n default:\n 'border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90',\n secondary:\n 'border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90',\n destructive:\n 'border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60',\n outline:\n 'text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground',\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n },\n);\n\nfunction Badge({\n className,\n variant,\n asChild = false,\n ...props\n}: React.ComponentProps<'span'> &\n VariantProps<typeof badgeVariants> & { asChild?: boolean }) {\n const Comp = asChild ? Slot : 'span';\n\n return (\n <Comp\n data-slot=\"badge\"\n className={cn(badgeVariants({ variant }), className)}\n {...props}\n />\n );\n}\n\nexport { Badge, badgeVariants };\n"],"mappings":";AAAA,SAA0B,YAAY;AACtC,SAAS,eAAe;AAEjB,SAAS,MAAM,QAAsB;AAC1C,SAAO,QAAQ,KAAK,MAAM,CAAC;AAC7B;;;ACJA,SAAS,YAAY;AACrB,SAAS,WAA8B;AAkCnC;AA/BJ,IAAM,gBAAgB;AAAA,EACpB;AAAA,EACA;AAAA,IACE,UAAU;AAAA,MACR,SAAS;AAAA,QACP,SACE;AAAA,QACF,WACE;AAAA,QACF,aACE;AAAA,QACF,SACE;AAAA,MACJ;AAAA,IACF;AAAA,IACA,iBAAiB;AAAA,MACf,SAAS;AAAA,IACX;AAAA,EACF;AACF;AAEA,SAAS,MAAM;AAAA,EACb;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV,GAAG;AACL,GAC8D;AAC5D,QAAM,OAAO,UAAU,OAAO;AAE9B,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,cAAc,EAAE,QAAQ,CAAC,GAAG,SAAS;AAAA,MAClD,GAAG;AAAA;AAAA,EACN;AAEJ;","names":[]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
|
|
4
|
+
declare function Breadcrumb({ ...props }: React.ComponentProps<'nav'>): react_jsx_runtime.JSX.Element;
|
|
5
|
+
declare function BreadcrumbList({ className, ...props }: React.ComponentProps<'ol'>): react_jsx_runtime.JSX.Element;
|
|
6
|
+
declare function BreadcrumbItem({ className, ...props }: React.ComponentProps<'li'>): react_jsx_runtime.JSX.Element;
|
|
7
|
+
declare function BreadcrumbLink({ asChild, className, ...props }: React.ComponentProps<'a'> & {
|
|
8
|
+
asChild?: boolean;
|
|
9
|
+
}): react_jsx_runtime.JSX.Element;
|
|
10
|
+
declare function BreadcrumbPage({ className, ...props }: React.ComponentProps<'span'>): react_jsx_runtime.JSX.Element;
|
|
11
|
+
declare function BreadcrumbSeparator({ children, className, ...props }: React.ComponentProps<'li'>): react_jsx_runtime.JSX.Element;
|
|
12
|
+
declare function BreadcrumbEllipsis({ className, ...props }: React.ComponentProps<'span'>): react_jsx_runtime.JSX.Element;
|
|
13
|
+
|
|
14
|
+
export { Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator };
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
// src/lib/utils.ts
|
|
2
|
+
import { clsx } from "clsx";
|
|
3
|
+
import { twMerge } from "tailwind-merge";
|
|
4
|
+
function cn(...inputs) {
|
|
5
|
+
return twMerge(clsx(inputs));
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
// src/components/breadcrumb.tsx
|
|
9
|
+
import { Slot } from "@radix-ui/react-slot";
|
|
10
|
+
import { IconChevronRight, IconDots } from "@tabler/icons-react";
|
|
11
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
12
|
+
function Breadcrumb({ ...props }) {
|
|
13
|
+
return /* @__PURE__ */ jsx("nav", { "aria-label": "breadcrumb", "data-slot": "breadcrumb", ...props });
|
|
14
|
+
}
|
|
15
|
+
function BreadcrumbList({ className, ...props }) {
|
|
16
|
+
return /* @__PURE__ */ jsx(
|
|
17
|
+
"ol",
|
|
18
|
+
{
|
|
19
|
+
"data-slot": "breadcrumb-list",
|
|
20
|
+
className: cn(
|
|
21
|
+
"text-muted-foreground flex flex-wrap items-center gap-1.5 text-sm break-words sm:gap-2.5",
|
|
22
|
+
className
|
|
23
|
+
),
|
|
24
|
+
...props
|
|
25
|
+
}
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
function BreadcrumbItem({ className, ...props }) {
|
|
29
|
+
return /* @__PURE__ */ jsx(
|
|
30
|
+
"li",
|
|
31
|
+
{
|
|
32
|
+
"data-slot": "breadcrumb-item",
|
|
33
|
+
className: cn("inline-flex items-center gap-1.5", className),
|
|
34
|
+
...props
|
|
35
|
+
}
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
function BreadcrumbLink({
|
|
39
|
+
asChild,
|
|
40
|
+
className,
|
|
41
|
+
...props
|
|
42
|
+
}) {
|
|
43
|
+
const Comp = asChild ? Slot : "a";
|
|
44
|
+
return /* @__PURE__ */ jsx(
|
|
45
|
+
Comp,
|
|
46
|
+
{
|
|
47
|
+
"data-slot": "breadcrumb-link",
|
|
48
|
+
className: cn("hover:text-foreground transition-colors", className),
|
|
49
|
+
...props
|
|
50
|
+
}
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
function BreadcrumbPage({ className, ...props }) {
|
|
54
|
+
return /* @__PURE__ */ jsx(
|
|
55
|
+
"span",
|
|
56
|
+
{
|
|
57
|
+
"data-slot": "breadcrumb-page",
|
|
58
|
+
"aria-disabled": "true",
|
|
59
|
+
"aria-current": "page",
|
|
60
|
+
className: cn("text-foreground font-normal", className),
|
|
61
|
+
...props
|
|
62
|
+
}
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
function BreadcrumbSeparator({
|
|
66
|
+
children,
|
|
67
|
+
className,
|
|
68
|
+
...props
|
|
69
|
+
}) {
|
|
70
|
+
return /* @__PURE__ */ jsx(
|
|
71
|
+
"li",
|
|
72
|
+
{
|
|
73
|
+
"data-slot": "breadcrumb-separator",
|
|
74
|
+
role: "presentation",
|
|
75
|
+
"aria-hidden": "true",
|
|
76
|
+
className: cn("[&>svg]:size-3.5", className),
|
|
77
|
+
...props,
|
|
78
|
+
children: children ?? /* @__PURE__ */ jsx(IconChevronRight, {})
|
|
79
|
+
}
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
function BreadcrumbEllipsis({
|
|
83
|
+
className,
|
|
84
|
+
...props
|
|
85
|
+
}) {
|
|
86
|
+
return /* @__PURE__ */ jsxs(
|
|
87
|
+
"span",
|
|
88
|
+
{
|
|
89
|
+
"data-slot": "breadcrumb-ellipsis",
|
|
90
|
+
role: "presentation",
|
|
91
|
+
"aria-hidden": "true",
|
|
92
|
+
className: cn("flex size-9 items-center justify-center", className),
|
|
93
|
+
...props,
|
|
94
|
+
children: [
|
|
95
|
+
/* @__PURE__ */ jsx(IconDots, { className: "size-4" }),
|
|
96
|
+
/* @__PURE__ */ jsx("span", { className: "sr-only", children: "More" })
|
|
97
|
+
]
|
|
98
|
+
}
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
export {
|
|
102
|
+
Breadcrumb,
|
|
103
|
+
BreadcrumbEllipsis,
|
|
104
|
+
BreadcrumbItem,
|
|
105
|
+
BreadcrumbLink,
|
|
106
|
+
BreadcrumbList,
|
|
107
|
+
BreadcrumbPage,
|
|
108
|
+
BreadcrumbSeparator
|
|
109
|
+
};
|
|
110
|
+
//# sourceMappingURL=breadcrumb.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/lib/utils.ts","../../src/components/breadcrumb.tsx"],"sourcesContent":["import { type ClassValue, clsx } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","import { cn } from '@mesob/ui/lib/utils';\nimport { Slot } from '@radix-ui/react-slot';\nimport { IconChevronRight, IconDots } from '@tabler/icons-react';\nimport type * as React from 'react';\n\nfunction Breadcrumb({ ...props }: React.ComponentProps<'nav'>) {\n return <nav aria-label=\"breadcrumb\" data-slot=\"breadcrumb\" {...props} />;\n}\n\nfunction BreadcrumbList({ className, ...props }: React.ComponentProps<'ol'>) {\n return (\n <ol\n data-slot=\"breadcrumb-list\"\n className={cn(\n 'text-muted-foreground flex flex-wrap items-center gap-1.5 text-sm break-words sm:gap-2.5',\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction BreadcrumbItem({ className, ...props }: React.ComponentProps<'li'>) {\n return (\n <li\n data-slot=\"breadcrumb-item\"\n className={cn('inline-flex items-center gap-1.5', className)}\n {...props}\n />\n );\n}\n\nfunction BreadcrumbLink({\n asChild,\n className,\n ...props\n}: React.ComponentProps<'a'> & {\n asChild?: boolean;\n}) {\n const Comp = asChild ? Slot : 'a';\n\n return (\n <Comp\n data-slot=\"breadcrumb-link\"\n className={cn('hover:text-foreground transition-colors', className)}\n {...props}\n />\n );\n}\n\nfunction BreadcrumbPage({ className, ...props }: React.ComponentProps<'span'>) {\n return (\n <span\n data-slot=\"breadcrumb-page\"\n aria-disabled=\"true\"\n aria-current=\"page\"\n className={cn('text-foreground font-normal', className)}\n {...props}\n />\n );\n}\n\nfunction BreadcrumbSeparator({\n children,\n className,\n ...props\n}: React.ComponentProps<'li'>) {\n return (\n <li\n data-slot=\"breadcrumb-separator\"\n role=\"presentation\"\n aria-hidden=\"true\"\n className={cn('[&>svg]:size-3.5', className)}\n {...props}\n >\n {children ?? <IconChevronRight />}\n </li>\n );\n}\n\nfunction BreadcrumbEllipsis({\n className,\n ...props\n}: React.ComponentProps<'span'>) {\n return (\n <span\n data-slot=\"breadcrumb-ellipsis\"\n role=\"presentation\"\n aria-hidden=\"true\"\n className={cn('flex size-9 items-center justify-center', className)}\n {...props}\n >\n <IconDots className=\"size-4\" />\n <span className=\"sr-only\">More</span>\n </span>\n );\n}\n\nexport {\n Breadcrumb,\n BreadcrumbList,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbPage,\n BreadcrumbSeparator,\n BreadcrumbEllipsis,\n};\n"],"mappings":";AAAA,SAA0B,YAAY;AACtC,SAAS,eAAe;AAEjB,SAAS,MAAM,QAAsB;AAC1C,SAAO,QAAQ,KAAK,MAAM,CAAC;AAC7B;;;ACJA,SAAS,YAAY;AACrB,SAAS,kBAAkB,gBAAgB;AAIlC,cA+EL,YA/EK;AADT,SAAS,WAAW,EAAE,GAAG,MAAM,GAAgC;AAC7D,SAAO,oBAAC,SAAI,cAAW,cAAa,aAAU,cAAc,GAAG,OAAO;AACxE;AAEA,SAAS,eAAe,EAAE,WAAW,GAAG,MAAM,GAA+B;AAC3E,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;AAEA,SAAS,eAAe,EAAE,WAAW,GAAG,MAAM,GAA+B;AAC3E,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,oCAAoC,SAAS;AAAA,MAC1D,GAAG;AAAA;AAAA,EACN;AAEJ;AAEA,SAAS,eAAe;AAAA,EACtB;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAEG;AACD,QAAM,OAAO,UAAU,OAAO;AAE9B,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,2CAA2C,SAAS;AAAA,MACjE,GAAG;AAAA;AAAA,EACN;AAEJ;AAEA,SAAS,eAAe,EAAE,WAAW,GAAG,MAAM,GAAiC;AAC7E,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,iBAAc;AAAA,MACd,gBAAa;AAAA,MACb,WAAW,GAAG,+BAA+B,SAAS;AAAA,MACrD,GAAG;AAAA;AAAA,EACN;AAEJ;AAEA,SAAS,oBAAoB;AAAA,EAC3B;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAA+B;AAC7B,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,MAAK;AAAA,MACL,eAAY;AAAA,MACZ,WAAW,GAAG,oBAAoB,SAAS;AAAA,MAC1C,GAAG;AAAA,MAEH,sBAAY,oBAAC,oBAAiB;AAAA;AAAA,EACjC;AAEJ;AAEA,SAAS,mBAAmB;AAAA,EAC1B;AAAA,EACA,GAAG;AACL,GAAiC;AAC/B,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,MAAK;AAAA,MACL,eAAY;AAAA,MACZ,WAAW,GAAG,2CAA2C,SAAS;AAAA,MACjE,GAAG;AAAA,MAEJ;AAAA,4BAAC,YAAS,WAAU,UAAS;AAAA,QAC7B,oBAAC,UAAK,WAAU,WAAU,kBAAI;AAAA;AAAA;AAAA,EAChC;AAEJ;","names":[]}
|