@mesob/ui 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/app-breadcrumbs.d.ts +34 -0
- package/dist/components/app-breadcrumbs.js +177 -0
- package/dist/components/app-breadcrumbs.js.map +1 -0
- package/dist/components/app-header-actions.d.ts +39 -0
- package/dist/components/app-header-actions.js +629 -0
- package/dist/components/app-header-actions.js.map +1 -0
- package/dist/components/app-sidebar.d.ts +24 -0
- package/dist/components/app-sidebar.js +669 -0
- package/dist/components/app-sidebar.js.map +1 -0
- package/dist/components/data-table/index.d.ts +9 -2
- package/dist/components/data-table/index.js +276 -101
- package/dist/components/data-table/index.js.map +1 -1
- package/dist/components/entity/index.d.ts +85 -9
- package/dist/components/entity/index.js +424 -304
- package/dist/components/entity/index.js.map +1 -1
- package/dist/components/input-group.d.ts +1 -1
- package/dist/components/link.d.ts +12 -0
- package/dist/components/link.js +51 -0
- package/dist/components/link.js.map +1 -0
- package/dist/components/mesob-context.d.ts +34 -0
- package/dist/components/mesob-context.js +53 -0
- package/dist/components/mesob-context.js.map +1 -0
- package/dist/components/page/index.d.ts +46 -0
- package/dist/components/page/index.js +197 -0
- package/dist/components/page/index.js.map +1 -0
- package/dist/components/powered-by.d.ts +4 -1
- package/dist/components/powered-by.js +28 -12
- package/dist/components/powered-by.js.map +1 -1
- package/dist/components/shell.d.ts +13 -0
- package/dist/components/shell.js +545 -0
- package/dist/components/shell.js.map +1 -0
- package/dist/components/sidebar.d.ts +4 -0
- package/dist/components/sidebar.js +37 -8
- package/dist/components/sidebar.js.map +1 -1
- package/dist/components/table.js +1 -1
- package/dist/components/table.js.map +1 -1
- package/dist/components/tooltip.d.ts +1 -1
- package/dist/components/tooltip.js +2 -1
- package/dist/components/tooltip.js.map +1 -1
- package/dist/hooks/use-router.d.ts +7 -0
- package/dist/hooks/use-router.js +36 -0
- package/dist/hooks/use-router.js.map +1 -0
- package/dist/hooks/use-translation.d.ts +5 -0
- package/dist/hooks/use-translation.js +41 -0
- package/dist/hooks/use-translation.js.map +1 -0
- package/package.json +7 -1
- package/src/styles/globals.css +4 -0
|
@@ -0,0 +1,629 @@
|
|
|
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
|
+
|
|
59
|
+
// src/components/button.tsx
|
|
60
|
+
import { Slot } from "@radix-ui/react-slot";
|
|
61
|
+
import { cva } from "class-variance-authority";
|
|
62
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
63
|
+
var buttonVariants = cva(
|
|
64
|
+
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-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",
|
|
65
|
+
{
|
|
66
|
+
variants: {
|
|
67
|
+
variant: {
|
|
68
|
+
default: "bg-primary text-primary-foreground hover:bg-primary/90",
|
|
69
|
+
destructive: "bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
|
|
70
|
+
outline: "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
|
|
71
|
+
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
|
72
|
+
ghost: "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
|
|
73
|
+
link: "text-primary underline-offset-4 hover:underline"
|
|
74
|
+
},
|
|
75
|
+
size: {
|
|
76
|
+
default: "h-9 px-4 py-2 has-[>svg]:px-3",
|
|
77
|
+
sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
|
|
78
|
+
lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
|
|
79
|
+
icon: "size-9",
|
|
80
|
+
"icon-sm": "size-8",
|
|
81
|
+
"icon-lg": "size-10"
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
defaultVariants: {
|
|
85
|
+
variant: "default",
|
|
86
|
+
size: "default"
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
);
|
|
90
|
+
function Button({
|
|
91
|
+
className,
|
|
92
|
+
variant,
|
|
93
|
+
size,
|
|
94
|
+
asChild = false,
|
|
95
|
+
...props
|
|
96
|
+
}) {
|
|
97
|
+
const Comp = asChild ? Slot : "button";
|
|
98
|
+
return /* @__PURE__ */ jsx2(
|
|
99
|
+
Comp,
|
|
100
|
+
{
|
|
101
|
+
"data-slot": "button",
|
|
102
|
+
className: cn(buttonVariants({ variant, size, className })),
|
|
103
|
+
...props
|
|
104
|
+
}
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// src/components/dropdown-menu.tsx
|
|
109
|
+
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
|
|
110
|
+
import { IconCheck, IconChevronRight, IconCircle } from "@tabler/icons-react";
|
|
111
|
+
import { jsx as jsx3, jsxs } from "react/jsx-runtime";
|
|
112
|
+
function DropdownMenu({
|
|
113
|
+
...props
|
|
114
|
+
}) {
|
|
115
|
+
return /* @__PURE__ */ jsx3(DropdownMenuPrimitive.Root, { "data-slot": "dropdown-menu", ...props });
|
|
116
|
+
}
|
|
117
|
+
function DropdownMenuTrigger({
|
|
118
|
+
...props
|
|
119
|
+
}) {
|
|
120
|
+
return /* @__PURE__ */ jsx3(
|
|
121
|
+
DropdownMenuPrimitive.Trigger,
|
|
122
|
+
{
|
|
123
|
+
"data-slot": "dropdown-menu-trigger",
|
|
124
|
+
...props
|
|
125
|
+
}
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
function DropdownMenuContent({
|
|
129
|
+
className,
|
|
130
|
+
sideOffset = 4,
|
|
131
|
+
...props
|
|
132
|
+
}) {
|
|
133
|
+
return /* @__PURE__ */ jsx3(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ jsx3(
|
|
134
|
+
DropdownMenuPrimitive.Content,
|
|
135
|
+
{
|
|
136
|
+
"data-slot": "dropdown-menu-content",
|
|
137
|
+
sideOffset,
|
|
138
|
+
className: cn(
|
|
139
|
+
"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",
|
|
140
|
+
className
|
|
141
|
+
),
|
|
142
|
+
...props
|
|
143
|
+
}
|
|
144
|
+
) });
|
|
145
|
+
}
|
|
146
|
+
function DropdownMenuItem({
|
|
147
|
+
className,
|
|
148
|
+
inset,
|
|
149
|
+
variant = "default",
|
|
150
|
+
...props
|
|
151
|
+
}) {
|
|
152
|
+
return /* @__PURE__ */ jsx3(
|
|
153
|
+
DropdownMenuPrimitive.Item,
|
|
154
|
+
{
|
|
155
|
+
"data-slot": "dropdown-menu-item",
|
|
156
|
+
"data-inset": inset,
|
|
157
|
+
"data-variant": variant,
|
|
158
|
+
className: cn(
|
|
159
|
+
"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",
|
|
160
|
+
className
|
|
161
|
+
),
|
|
162
|
+
...props
|
|
163
|
+
}
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
function DropdownMenuSeparator({
|
|
167
|
+
className,
|
|
168
|
+
...props
|
|
169
|
+
}) {
|
|
170
|
+
return /* @__PURE__ */ jsx3(
|
|
171
|
+
DropdownMenuPrimitive.Separator,
|
|
172
|
+
{
|
|
173
|
+
"data-slot": "dropdown-menu-separator",
|
|
174
|
+
className: cn("bg-border -mx-1 my-1 h-px", className),
|
|
175
|
+
...props
|
|
176
|
+
}
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// src/components/tooltip.tsx
|
|
181
|
+
import * as TooltipPrimitive from "@radix-ui/react-tooltip";
|
|
182
|
+
import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
183
|
+
|
|
184
|
+
// src/components/mesob-context.tsx
|
|
185
|
+
import {
|
|
186
|
+
createContext,
|
|
187
|
+
useContext,
|
|
188
|
+
useMemo
|
|
189
|
+
} from "react";
|
|
190
|
+
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
191
|
+
var MesobContext = createContext(null);
|
|
192
|
+
function useMesob() {
|
|
193
|
+
return useContext(MesobContext);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// src/components/link.tsx
|
|
197
|
+
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
198
|
+
function Link({
|
|
199
|
+
href,
|
|
200
|
+
children,
|
|
201
|
+
className,
|
|
202
|
+
onClick,
|
|
203
|
+
...props
|
|
204
|
+
}) {
|
|
205
|
+
const mesob = useMesob();
|
|
206
|
+
const LinkComponent = mesob?.linkComponent ?? "a";
|
|
207
|
+
if (LinkComponent === "a") {
|
|
208
|
+
return /* @__PURE__ */ jsx6("a", { href, className, onClick, ...props, children });
|
|
209
|
+
}
|
|
210
|
+
return /* @__PURE__ */ jsx6(
|
|
211
|
+
LinkComponent,
|
|
212
|
+
{
|
|
213
|
+
href,
|
|
214
|
+
className,
|
|
215
|
+
onClick,
|
|
216
|
+
...props,
|
|
217
|
+
children
|
|
218
|
+
}
|
|
219
|
+
);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// src/components/dialog.tsx
|
|
223
|
+
import * as DialogPrimitive from "@radix-ui/react-dialog";
|
|
224
|
+
import { IconX } from "@tabler/icons-react";
|
|
225
|
+
import { jsx as jsx7, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
226
|
+
function Dialog({
|
|
227
|
+
...props
|
|
228
|
+
}) {
|
|
229
|
+
return /* @__PURE__ */ jsx7(DialogPrimitive.Root, { "data-slot": "dialog", ...props });
|
|
230
|
+
}
|
|
231
|
+
function DialogPortal({
|
|
232
|
+
...props
|
|
233
|
+
}) {
|
|
234
|
+
return /* @__PURE__ */ jsx7(DialogPrimitive.Portal, { "data-slot": "dialog-portal", ...props });
|
|
235
|
+
}
|
|
236
|
+
function DialogOverlay({
|
|
237
|
+
className,
|
|
238
|
+
...props
|
|
239
|
+
}) {
|
|
240
|
+
return /* @__PURE__ */ jsx7(
|
|
241
|
+
DialogPrimitive.Overlay,
|
|
242
|
+
{
|
|
243
|
+
"data-slot": "dialog-overlay",
|
|
244
|
+
className: cn(
|
|
245
|
+
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50",
|
|
246
|
+
className
|
|
247
|
+
),
|
|
248
|
+
...props
|
|
249
|
+
}
|
|
250
|
+
);
|
|
251
|
+
}
|
|
252
|
+
function DialogContent({
|
|
253
|
+
className,
|
|
254
|
+
children,
|
|
255
|
+
showCloseButton = true,
|
|
256
|
+
...props
|
|
257
|
+
}) {
|
|
258
|
+
return /* @__PURE__ */ jsxs3(DialogPortal, { "data-slot": "dialog-portal", children: [
|
|
259
|
+
/* @__PURE__ */ jsx7(DialogOverlay, {}),
|
|
260
|
+
/* @__PURE__ */ jsxs3(
|
|
261
|
+
DialogPrimitive.Content,
|
|
262
|
+
{
|
|
263
|
+
"data-slot": "dialog-content",
|
|
264
|
+
className: cn(
|
|
265
|
+
"bg-background 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 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg",
|
|
266
|
+
className
|
|
267
|
+
),
|
|
268
|
+
...props,
|
|
269
|
+
children: [
|
|
270
|
+
children,
|
|
271
|
+
showCloseButton && /* @__PURE__ */ jsxs3(
|
|
272
|
+
DialogPrimitive.Close,
|
|
273
|
+
{
|
|
274
|
+
"data-slot": "dialog-close",
|
|
275
|
+
className: "ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
276
|
+
children: [
|
|
277
|
+
/* @__PURE__ */ jsx7(IconX, {}),
|
|
278
|
+
/* @__PURE__ */ jsx7("span", { className: "sr-only", children: "Close" })
|
|
279
|
+
]
|
|
280
|
+
}
|
|
281
|
+
)
|
|
282
|
+
]
|
|
283
|
+
}
|
|
284
|
+
)
|
|
285
|
+
] });
|
|
286
|
+
}
|
|
287
|
+
function DialogHeader({ className, ...props }) {
|
|
288
|
+
return /* @__PURE__ */ jsx7(
|
|
289
|
+
"div",
|
|
290
|
+
{
|
|
291
|
+
"data-slot": "dialog-header",
|
|
292
|
+
className: cn("flex flex-col gap-2 text-center sm:text-left", className),
|
|
293
|
+
...props
|
|
294
|
+
}
|
|
295
|
+
);
|
|
296
|
+
}
|
|
297
|
+
function DialogTitle({
|
|
298
|
+
className,
|
|
299
|
+
...props
|
|
300
|
+
}) {
|
|
301
|
+
return /* @__PURE__ */ jsx7(
|
|
302
|
+
DialogPrimitive.Title,
|
|
303
|
+
{
|
|
304
|
+
"data-slot": "dialog-title",
|
|
305
|
+
className: cn("text-lg leading-none font-semibold", className),
|
|
306
|
+
...props
|
|
307
|
+
}
|
|
308
|
+
);
|
|
309
|
+
}
|
|
310
|
+
function DialogDescription({
|
|
311
|
+
className,
|
|
312
|
+
...props
|
|
313
|
+
}) {
|
|
314
|
+
return /* @__PURE__ */ jsx7(
|
|
315
|
+
DialogPrimitive.Description,
|
|
316
|
+
{
|
|
317
|
+
"data-slot": "dialog-description",
|
|
318
|
+
className: cn("text-muted-foreground text-sm", className),
|
|
319
|
+
...props
|
|
320
|
+
}
|
|
321
|
+
);
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
// src/components/command.tsx
|
|
325
|
+
import { IconSearch } from "@tabler/icons-react";
|
|
326
|
+
import { Command as CommandPrimitive } from "cmdk";
|
|
327
|
+
import { jsx as jsx8, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
328
|
+
function Command({
|
|
329
|
+
className,
|
|
330
|
+
...props
|
|
331
|
+
}) {
|
|
332
|
+
return /* @__PURE__ */ jsx8(
|
|
333
|
+
CommandPrimitive,
|
|
334
|
+
{
|
|
335
|
+
"data-slot": "command",
|
|
336
|
+
className: cn(
|
|
337
|
+
"bg-popover text-popover-foreground flex h-full w-full flex-col overflow-hidden rounded-md",
|
|
338
|
+
className
|
|
339
|
+
),
|
|
340
|
+
...props
|
|
341
|
+
}
|
|
342
|
+
);
|
|
343
|
+
}
|
|
344
|
+
function CommandDialog({
|
|
345
|
+
title = "Command Palette",
|
|
346
|
+
description = "Search for a command to run...",
|
|
347
|
+
children,
|
|
348
|
+
className,
|
|
349
|
+
showCloseButton = true,
|
|
350
|
+
...props
|
|
351
|
+
}) {
|
|
352
|
+
return /* @__PURE__ */ jsxs4(Dialog, { ...props, children: [
|
|
353
|
+
/* @__PURE__ */ jsxs4(DialogHeader, { className: "sr-only", children: [
|
|
354
|
+
/* @__PURE__ */ jsx8(DialogTitle, { children: title }),
|
|
355
|
+
/* @__PURE__ */ jsx8(DialogDescription, { children: description })
|
|
356
|
+
] }),
|
|
357
|
+
/* @__PURE__ */ jsx8(
|
|
358
|
+
DialogContent,
|
|
359
|
+
{
|
|
360
|
+
className: cn("overflow-hidden p-0", className),
|
|
361
|
+
showCloseButton,
|
|
362
|
+
children: /* @__PURE__ */ jsx8(Command, { className: "[&_[cmdk-group-heading]]:text-muted-foreground **:data-[slot=command-input-wrapper]:h-12 [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group]]:px-2 [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5", children })
|
|
363
|
+
}
|
|
364
|
+
)
|
|
365
|
+
] });
|
|
366
|
+
}
|
|
367
|
+
function CommandInput({
|
|
368
|
+
className,
|
|
369
|
+
...props
|
|
370
|
+
}) {
|
|
371
|
+
return /* @__PURE__ */ jsxs4(
|
|
372
|
+
"div",
|
|
373
|
+
{
|
|
374
|
+
"data-slot": "command-input-wrapper",
|
|
375
|
+
className: "flex h-9 items-center gap-2 border-b px-3",
|
|
376
|
+
children: [
|
|
377
|
+
/* @__PURE__ */ jsx8(IconSearch, { className: "size-4 shrink-0 opacity-50" }),
|
|
378
|
+
/* @__PURE__ */ jsx8(
|
|
379
|
+
CommandPrimitive.Input,
|
|
380
|
+
{
|
|
381
|
+
"data-slot": "command-input",
|
|
382
|
+
className: cn(
|
|
383
|
+
"placeholder:text-muted-foreground flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-hidden disabled:cursor-not-allowed disabled:opacity-50",
|
|
384
|
+
className
|
|
385
|
+
),
|
|
386
|
+
...props
|
|
387
|
+
}
|
|
388
|
+
)
|
|
389
|
+
]
|
|
390
|
+
}
|
|
391
|
+
);
|
|
392
|
+
}
|
|
393
|
+
function CommandList({
|
|
394
|
+
className,
|
|
395
|
+
...props
|
|
396
|
+
}) {
|
|
397
|
+
return /* @__PURE__ */ jsx8(
|
|
398
|
+
CommandPrimitive.List,
|
|
399
|
+
{
|
|
400
|
+
"data-slot": "command-list",
|
|
401
|
+
className: cn(
|
|
402
|
+
"max-h-[300px] scroll-py-1 overflow-x-hidden overflow-y-auto",
|
|
403
|
+
className
|
|
404
|
+
),
|
|
405
|
+
...props
|
|
406
|
+
}
|
|
407
|
+
);
|
|
408
|
+
}
|
|
409
|
+
function CommandEmpty({
|
|
410
|
+
...props
|
|
411
|
+
}) {
|
|
412
|
+
return /* @__PURE__ */ jsx8(
|
|
413
|
+
CommandPrimitive.Empty,
|
|
414
|
+
{
|
|
415
|
+
"data-slot": "command-empty",
|
|
416
|
+
className: "py-6 text-center text-sm",
|
|
417
|
+
...props
|
|
418
|
+
}
|
|
419
|
+
);
|
|
420
|
+
}
|
|
421
|
+
function CommandGroup({
|
|
422
|
+
className,
|
|
423
|
+
...props
|
|
424
|
+
}) {
|
|
425
|
+
return /* @__PURE__ */ jsx8(
|
|
426
|
+
CommandPrimitive.Group,
|
|
427
|
+
{
|
|
428
|
+
"data-slot": "command-group",
|
|
429
|
+
className: cn(
|
|
430
|
+
"text-foreground [&_[cmdk-group-heading]]:text-muted-foreground overflow-hidden p-1 [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium",
|
|
431
|
+
className
|
|
432
|
+
),
|
|
433
|
+
...props
|
|
434
|
+
}
|
|
435
|
+
);
|
|
436
|
+
}
|
|
437
|
+
function CommandSeparator({
|
|
438
|
+
className,
|
|
439
|
+
...props
|
|
440
|
+
}) {
|
|
441
|
+
return /* @__PURE__ */ jsx8(
|
|
442
|
+
CommandPrimitive.Separator,
|
|
443
|
+
{
|
|
444
|
+
"data-slot": "command-separator",
|
|
445
|
+
className: cn("bg-border -mx-1 h-px", className),
|
|
446
|
+
...props
|
|
447
|
+
}
|
|
448
|
+
);
|
|
449
|
+
}
|
|
450
|
+
function CommandItem({
|
|
451
|
+
className,
|
|
452
|
+
...props
|
|
453
|
+
}) {
|
|
454
|
+
return /* @__PURE__ */ jsx8(
|
|
455
|
+
CommandPrimitive.Item,
|
|
456
|
+
{
|
|
457
|
+
"data-slot": "command-item",
|
|
458
|
+
className: cn(
|
|
459
|
+
"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground [&_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=true]:pointer-events-none data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
460
|
+
className
|
|
461
|
+
),
|
|
462
|
+
...props
|
|
463
|
+
}
|
|
464
|
+
);
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
// src/components/spotlight-search.tsx
|
|
468
|
+
import { IconSearch as IconSearch2 } from "@tabler/icons-react";
|
|
469
|
+
import * as React from "react";
|
|
470
|
+
import { Fragment as Fragment2, jsx as jsx9, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
471
|
+
function SpotlightSearch({
|
|
472
|
+
groups = [],
|
|
473
|
+
placeholder = "Search...",
|
|
474
|
+
emptyMessage = "No results found.",
|
|
475
|
+
className,
|
|
476
|
+
triggerClassName,
|
|
477
|
+
onSearch
|
|
478
|
+
}) {
|
|
479
|
+
const [open, setOpen] = React.useState(false);
|
|
480
|
+
React.useEffect(() => {
|
|
481
|
+
const down = (e) => {
|
|
482
|
+
if (e.key === "k" && (e.metaKey || e.ctrlKey)) {
|
|
483
|
+
e.preventDefault();
|
|
484
|
+
setOpen((open2) => !open2);
|
|
485
|
+
}
|
|
486
|
+
};
|
|
487
|
+
document.addEventListener("keydown", down);
|
|
488
|
+
return () => document.removeEventListener("keydown", down);
|
|
489
|
+
}, []);
|
|
490
|
+
return /* @__PURE__ */ jsxs5(Fragment2, { children: [
|
|
491
|
+
/* @__PURE__ */ jsxs5(
|
|
492
|
+
Button,
|
|
493
|
+
{
|
|
494
|
+
variant: "outline",
|
|
495
|
+
className: cn(
|
|
496
|
+
"relative h-9 w-9 p-0 xl:h-9 xl:w-60 xl:justify-start xl:px-3 xl:py-2",
|
|
497
|
+
triggerClassName
|
|
498
|
+
),
|
|
499
|
+
onClick: () => setOpen(true),
|
|
500
|
+
children: [
|
|
501
|
+
/* @__PURE__ */ jsx9(IconSearch2, { className: "h-4 w-4 xl:mr-2" }),
|
|
502
|
+
/* @__PURE__ */ jsx9("span", { className: "hidden xl:inline-flex", children: "Search..." }),
|
|
503
|
+
/* @__PURE__ */ jsxs5("kbd", { className: "pointer-events-none absolute right-1.5 top-1/2 hidden h-5 -translate-y-1/2 select-none items-center gap-1 rounded border bg-muted px-1.5 font-mono text-[10px] font-medium opacity-100 xl:flex", children: [
|
|
504
|
+
/* @__PURE__ */ jsx9("span", { className: "text-xs", children: "\u2318" }),
|
|
505
|
+
"K"
|
|
506
|
+
] })
|
|
507
|
+
]
|
|
508
|
+
}
|
|
509
|
+
),
|
|
510
|
+
/* @__PURE__ */ jsxs5(
|
|
511
|
+
CommandDialog,
|
|
512
|
+
{
|
|
513
|
+
open,
|
|
514
|
+
onOpenChange: setOpen,
|
|
515
|
+
title: "Search",
|
|
516
|
+
description: "Search for pages, actions, and more",
|
|
517
|
+
showCloseButton: false,
|
|
518
|
+
className,
|
|
519
|
+
children: [
|
|
520
|
+
/* @__PURE__ */ jsx9(CommandInput, { placeholder, onValueChange: onSearch }),
|
|
521
|
+
/* @__PURE__ */ jsxs5(CommandList, { children: [
|
|
522
|
+
/* @__PURE__ */ jsx9(CommandEmpty, { children: emptyMessage }),
|
|
523
|
+
groups.map((group, index) => /* @__PURE__ */ jsxs5(React.Fragment, { children: [
|
|
524
|
+
index > 0 && /* @__PURE__ */ jsx9(CommandSeparator, {}),
|
|
525
|
+
/* @__PURE__ */ jsx9(CommandGroup, { heading: group.heading, children: group.items.map((item) => /* @__PURE__ */ jsxs5(
|
|
526
|
+
CommandItem,
|
|
527
|
+
{
|
|
528
|
+
onSelect: () => {
|
|
529
|
+
item.onSelect?.();
|
|
530
|
+
setOpen(false);
|
|
531
|
+
},
|
|
532
|
+
children: [
|
|
533
|
+
item.icon,
|
|
534
|
+
/* @__PURE__ */ jsx9("span", { children: item.title }),
|
|
535
|
+
item.shortcut && /* @__PURE__ */ jsx9("kbd", { className: "pointer-events-none ml-auto hidden h-5 select-none items-center gap-1 rounded border bg-muted px-1.5 font-mono text-[10px] font-medium opacity-100 sm:flex", children: item.shortcut })
|
|
536
|
+
]
|
|
537
|
+
},
|
|
538
|
+
item.id
|
|
539
|
+
)) })
|
|
540
|
+
] }, group.heading))
|
|
541
|
+
] })
|
|
542
|
+
]
|
|
543
|
+
}
|
|
544
|
+
)
|
|
545
|
+
] });
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
// src/components/app-header-actions.tsx
|
|
549
|
+
import { IconBell, IconLogout } from "@tabler/icons-react";
|
|
550
|
+
import { Fragment as Fragment3, jsx as jsx10, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
551
|
+
function AppHeaderActions({
|
|
552
|
+
user,
|
|
553
|
+
onLogout,
|
|
554
|
+
isLoggingOut = false,
|
|
555
|
+
searchGroups = [],
|
|
556
|
+
menuItems = [],
|
|
557
|
+
topMenuItems = [],
|
|
558
|
+
actions,
|
|
559
|
+
accountMenuFooter
|
|
560
|
+
}) {
|
|
561
|
+
const initials = user?.fullName?.split(" ").map((n) => n[0]).join("").toUpperCase().slice(0, 2) || "U";
|
|
562
|
+
const displayName = user?.fullName ?? "Account";
|
|
563
|
+
const displaySubtext = user?.email ?? user?.phone ?? user?.handle ?? "";
|
|
564
|
+
return /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-2", children: [
|
|
565
|
+
/* @__PURE__ */ jsx10(SpotlightSearch, { groups: searchGroups }),
|
|
566
|
+
actions,
|
|
567
|
+
/* @__PURE__ */ jsx10(Button, { variant: "ghost", size: "icon", className: "relative", children: /* @__PURE__ */ jsx10(IconBell, { className: "size-5" }) }),
|
|
568
|
+
/* @__PURE__ */ jsxs6(DropdownMenu, { children: [
|
|
569
|
+
/* @__PURE__ */ jsx10(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs6(Button, { variant: "ghost", className: "flex items-center gap-2 px-2", children: [
|
|
570
|
+
/* @__PURE__ */ jsxs6(Avatar, { className: "size-8", children: [
|
|
571
|
+
/* @__PURE__ */ jsx10(AvatarImage, { src: user?.image ?? void 0 }),
|
|
572
|
+
/* @__PURE__ */ jsx10(AvatarFallback, { className: "text-xs", children: initials })
|
|
573
|
+
] }),
|
|
574
|
+
/* @__PURE__ */ jsxs6("div", { className: "hidden flex-col items-start text-left md:flex", children: [
|
|
575
|
+
/* @__PURE__ */ jsx10("span", { className: "text-sm font-medium", children: displayName }),
|
|
576
|
+
/* @__PURE__ */ jsx10("span", { className: "text-xs text-muted-foreground", children: displaySubtext })
|
|
577
|
+
] })
|
|
578
|
+
] }) }),
|
|
579
|
+
/* @__PURE__ */ jsxs6(DropdownMenuContent, { align: "end", className: "w-56", children: [
|
|
580
|
+
topMenuItems.map((item) => /* @__PURE__ */ jsx10(
|
|
581
|
+
DropdownMenuItem,
|
|
582
|
+
{
|
|
583
|
+
onClick: item.onClick,
|
|
584
|
+
variant: item.variant,
|
|
585
|
+
asChild: item.href ? true : void 0,
|
|
586
|
+
children: item.href ? /* @__PURE__ */ jsxs6(Link, { href: item.href, onClick: item.onClick, children: [
|
|
587
|
+
item.icon && /* @__PURE__ */ jsx10("span", { className: "mr-2", children: item.icon }),
|
|
588
|
+
item.label
|
|
589
|
+
] }) : /* @__PURE__ */ jsxs6(Fragment3, { children: [
|
|
590
|
+
item.icon && /* @__PURE__ */ jsx10("span", { className: "mr-2", children: item.icon }),
|
|
591
|
+
item.label
|
|
592
|
+
] })
|
|
593
|
+
},
|
|
594
|
+
item.href ?? item.label
|
|
595
|
+
)),
|
|
596
|
+
topMenuItems.length > 0 && menuItems.length > 0 && /* @__PURE__ */ jsx10(DropdownMenuSeparator, {}),
|
|
597
|
+
menuItems.map((item) => /* @__PURE__ */ jsx10(
|
|
598
|
+
DropdownMenuItem,
|
|
599
|
+
{
|
|
600
|
+
onClick: item.onClick,
|
|
601
|
+
variant: item.variant,
|
|
602
|
+
asChild: item.href ? true : void 0,
|
|
603
|
+
children: item.href ? /* @__PURE__ */ jsxs6(Link, { href: item.href, onClick: item.onClick, children: [
|
|
604
|
+
item.icon && /* @__PURE__ */ jsx10("span", { className: "mr-2", children: item.icon }),
|
|
605
|
+
item.label
|
|
606
|
+
] }) : /* @__PURE__ */ jsxs6(Fragment3, { children: [
|
|
607
|
+
item.icon && /* @__PURE__ */ jsx10("span", { className: "mr-2", children: item.icon }),
|
|
608
|
+
item.label
|
|
609
|
+
] })
|
|
610
|
+
},
|
|
611
|
+
item.href ?? item.label
|
|
612
|
+
)),
|
|
613
|
+
accountMenuFooter && (topMenuItems.length > 0 || menuItems.length > 0) && /* @__PURE__ */ jsx10(DropdownMenuSeparator, {}),
|
|
614
|
+
accountMenuFooter,
|
|
615
|
+
onLogout && /* @__PURE__ */ jsxs6(Fragment3, { children: [
|
|
616
|
+
(topMenuItems.length > 0 || menuItems.length > 0 || accountMenuFooter) && /* @__PURE__ */ jsx10(DropdownMenuSeparator, {}),
|
|
617
|
+
/* @__PURE__ */ jsxs6(DropdownMenuItem, { onClick: onLogout, variant: "destructive", children: [
|
|
618
|
+
isLoggingOut ? /* @__PURE__ */ jsx10("span", { className: "mr-2", children: "..." }) : /* @__PURE__ */ jsx10(IconLogout, { className: "mr-2 size-4" }),
|
|
619
|
+
"Log out"
|
|
620
|
+
] })
|
|
621
|
+
] })
|
|
622
|
+
] })
|
|
623
|
+
] })
|
|
624
|
+
] });
|
|
625
|
+
}
|
|
626
|
+
export {
|
|
627
|
+
AppHeaderActions
|
|
628
|
+
};
|
|
629
|
+
//# sourceMappingURL=app-header-actions.js.map
|