@tradalab/lyra 1.5.0 → 1.7.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/blocks/index.js +2 -1
- package/dist/blocks/index.js.map +1 -1
- package/dist/{chunk-BEAQYKGM.js → chunk-44WIOUJJ.js} +4 -94
- package/dist/chunk-44WIOUJJ.js.map +1 -0
- package/dist/{chunk-VEWKPOMS.js → chunk-SQA4ILAK.js} +18 -4
- package/dist/chunk-SQA4ILAK.js.map +1 -0
- package/dist/{chunk-5UAFV75V.js → chunk-UPP56S32.js} +147 -18
- package/dist/chunk-UPP56S32.js.map +1 -0
- package/dist/chunk-ZG5ZPKFL.js +98 -0
- package/dist/chunk-ZG5ZPKFL.js.map +1 -0
- package/dist/data-table/index.d.ts +31 -2
- package/dist/data-table/index.js +78 -4
- package/dist/data-table/index.js.map +1 -1
- package/dist/shell/index.d.ts +84 -5
- package/dist/shell/index.js +107 -47
- package/dist/shell/index.js.map +1 -1
- package/dist/ui/index.js +12 -154
- package/dist/ui/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-5UAFV75V.js.map +0 -1
- package/dist/chunk-BEAQYKGM.js.map +0 -1
- package/dist/chunk-VEWKPOMS.js.map +0 -1
package/dist/shell/index.d.ts
CHANGED
|
@@ -203,14 +203,22 @@ interface NavUserThemeLabels {
|
|
|
203
203
|
/** Default English theme-submenu labels — spread + override for i18n. */
|
|
204
204
|
declare const defaultNavUserThemeLabels: NavUserThemeLabels;
|
|
205
205
|
interface NavUserProps {
|
|
206
|
-
/**
|
|
206
|
+
/**
|
|
207
|
+
* Signed-in user. When `null`/`undefined`, renders a guest menu (icon +
|
|
208
|
+
* theme + Sign in) if `onSignIn` is set, otherwise renders nothing.
|
|
209
|
+
*/
|
|
207
210
|
user?: AccountMenuUser | null;
|
|
208
211
|
/** Account-action labels — reuses lyra's {@link AccountMenuLabels}. */
|
|
209
212
|
labels?: Partial<AccountMenuLabels>;
|
|
210
|
-
/** Switch-account handler. Item hidden if omitted. */
|
|
213
|
+
/** Switch-account handler (signed-in only). Item hidden if omitted. */
|
|
211
214
|
onSwitchAccount?: () => void;
|
|
212
|
-
/** Sign-out handler. Item hidden if omitted. */
|
|
215
|
+
/** Sign-out handler (signed-in only). Item hidden if omitted. */
|
|
213
216
|
onSignOut?: () => void;
|
|
217
|
+
/**
|
|
218
|
+
* Sign-in handler (guest only). When set, a null `user` renders the guest
|
|
219
|
+
* menu with a Sign in action instead of rendering nothing.
|
|
220
|
+
*/
|
|
221
|
+
onSignIn?: () => void;
|
|
214
222
|
/** Render the light/dark/system theme submenu. Default `true`. */
|
|
215
223
|
showTheme?: boolean;
|
|
216
224
|
/** Theme-submenu labels. */
|
|
@@ -246,7 +254,7 @@ interface NavUserProps {
|
|
|
246
254
|
* />
|
|
247
255
|
* </SidebarFooter>
|
|
248
256
|
*/
|
|
249
|
-
declare function NavUser({ user, labels, onSwitchAccount, onSignOut, showTheme, themeLabels, children, }: NavUserProps): React.JSX.Element | null;
|
|
257
|
+
declare function NavUser({ user, labels, onSwitchAccount, onSignOut, onSignIn, showTheme, themeLabels, children, }: NavUserProps): React.JSX.Element | null;
|
|
250
258
|
|
|
251
259
|
interface TabItem {
|
|
252
260
|
id: string;
|
|
@@ -311,4 +319,75 @@ interface BreadcrumbsProps extends ComponentProps<typeof Breadcrumb> {
|
|
|
311
319
|
/** Pathname-derived breadcrumbs. Renders nothing on the root route. */
|
|
312
320
|
declare function Breadcrumbs({ separator, labels, ...rest }: BreadcrumbsProps): React.JSX.Element | null;
|
|
313
321
|
|
|
314
|
-
|
|
322
|
+
/** One application in the {@link AppGrid} — rendered as an {@link AppTile}. */
|
|
323
|
+
interface AppGridItem {
|
|
324
|
+
/** Stable React list key. */
|
|
325
|
+
key: string;
|
|
326
|
+
/** Display name. */
|
|
327
|
+
name: string;
|
|
328
|
+
/** Optional tagline shown under the name. */
|
|
329
|
+
description?: string;
|
|
330
|
+
/** Navigation target (usually an absolute cross-app URL). */
|
|
331
|
+
href: string;
|
|
332
|
+
/**
|
|
333
|
+
* Pre-rendered icon element (RSC-serializable), e.g. `<ToolCase />`. Sized by
|
|
334
|
+
* the tile (`[&_svg]:size-7`) — same convention as {@link NavBrandApp}'s icon.
|
|
335
|
+
*/
|
|
336
|
+
icon: ReactNode;
|
|
337
|
+
/**
|
|
338
|
+
* Tailwind class string tinting the icon tile — `text-…` (colors the icon via
|
|
339
|
+
* currentColor) + `bg-…` (tile background). Pass full class strings, not
|
|
340
|
+
* interpolated fragments, so the JIT keeps them.
|
|
341
|
+
*/
|
|
342
|
+
accent?: string;
|
|
343
|
+
/** Opens on a different origin (adds `target="_blank"` + `rel`). */
|
|
344
|
+
external?: boolean;
|
|
345
|
+
}
|
|
346
|
+
interface AppGridProps {
|
|
347
|
+
/** Apps to render — already filtered by the caller. */
|
|
348
|
+
apps: AppGridItem[];
|
|
349
|
+
/** Controlled search value. Pass together with `onQueryChange` to show the search box. */
|
|
350
|
+
query?: string;
|
|
351
|
+
onQueryChange?: (query: string) => void;
|
|
352
|
+
/** Search input placeholder. */
|
|
353
|
+
searchPlaceholder?: string;
|
|
354
|
+
/** Autofocus the search box on mount. Default `false`. */
|
|
355
|
+
autoFocusSearch?: boolean;
|
|
356
|
+
/** Message shown when `apps` is empty. */
|
|
357
|
+
emptyLabel?: string;
|
|
358
|
+
className?: string;
|
|
359
|
+
}
|
|
360
|
+
/** Default English labels — override for i18n. */
|
|
361
|
+
declare const defaultAppGridLabels: {
|
|
362
|
+
searchPlaceholder: string;
|
|
363
|
+
empty: string;
|
|
364
|
+
};
|
|
365
|
+
/**
|
|
366
|
+
* A responsive grid of application tiles with an optional search box — the "app
|
|
367
|
+
* grid" / launcher surface (a portal home / "all apps" page). Presentational:
|
|
368
|
+
* the app owns the registry, i18n, icons, and the filter — pass the already-
|
|
369
|
+
* filtered `apps` plus a controlled `query`. Same app/lyra split as
|
|
370
|
+
* {@link NavBrand} and {@link TabBar}.
|
|
371
|
+
*
|
|
372
|
+
* @example
|
|
373
|
+
* const [q, setQ] = useState("")
|
|
374
|
+
* const filtered = APPS.filter(a => match(a, q))
|
|
375
|
+
* <AppGrid
|
|
376
|
+
* apps={filtered.map(a => ({
|
|
377
|
+
* key: a.slug, name: t(a.slug), description: t(`${a.slug}.desc`),
|
|
378
|
+
* href: a.href, icon: <a.Icon />, accent: a.accent, external: true,
|
|
379
|
+
* }))}
|
|
380
|
+
* query={q} onQueryChange={setQ}
|
|
381
|
+
* searchPlaceholder={t("search")} emptyLabel={t("empty")}
|
|
382
|
+
* />
|
|
383
|
+
*/
|
|
384
|
+
declare function AppGrid({ apps, query, onQueryChange, searchPlaceholder, autoFocusSearch, emptyLabel, className, }: AppGridProps): React.JSX.Element;
|
|
385
|
+
/**
|
|
386
|
+
* A single application tile: the icon in a tinted rounded chip above the name +
|
|
387
|
+
* description. Exported for callers that render their own grid.
|
|
388
|
+
*/
|
|
389
|
+
declare function AppTile({ app }: {
|
|
390
|
+
app: AppGridItem;
|
|
391
|
+
}): React.JSX.Element;
|
|
392
|
+
|
|
393
|
+
export { AppGrid, type AppGridItem, type AppGridProps, AppShell, AppShellBody, AppShellHeader, AppShellMain, type AppShellProps, AppTile, Breadcrumbs, type BreadcrumbsProps, type MatchMode, NavBrand, type NavBrandApp, type NavBrandProps, NavGroup, type NavGroupProps, type NavIcon, NavItem, type NavItemProps, NavSection, type NavSectionProps, NavUser, type NavUserProps, type NavUserThemeLabels, SidebarDock, SidebarPanel, StackedSidebar, TabBar, type TabBarLabels, type TabBarProps, type TabItem, type UseActiveRoute, defaultAppGridLabels, defaultNavBrandAppsLabel, defaultNavUserThemeLabels, defaultTabBarLabels, useActiveRoute };
|
package/dist/shell/index.js
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { SidebarInset, SidebarProvider, Sidebar, SidebarGroup, SidebarGroupLabel, SidebarGroupContent, SidebarMenu, SidebarMenuItem, SidebarMenuButton, useSidebar, defaultAccountMenuLabels, Avatar, AvatarImage, AvatarFallback, initialsOf, ScrollArea, ContextMenu, ContextMenuTrigger, ContextMenuContent, ContextMenuItem, ContextMenuSeparator, ScrollBar, Breadcrumb, BreadcrumbList, BreadcrumbSeparator, BreadcrumbItem, BreadcrumbPage, BreadcrumbLink } from '../chunk-
|
|
2
|
+
import { SidebarInset, SidebarProvider, Sidebar, SidebarGroup, SidebarGroupLabel, SidebarGroupContent, SidebarMenu, SidebarMenuItem, SidebarMenuButton, useSidebar, defaultAccountMenuLabels, Avatar, AvatarImage, AvatarFallback, initialsOf, ScrollArea, ContextMenu, ContextMenuTrigger, ContextMenuContent, ContextMenuItem, ContextMenuSeparator, ScrollBar, Breadcrumb, BreadcrumbList, BreadcrumbSeparator, BreadcrumbItem, BreadcrumbPage, BreadcrumbLink, InputGroup, InputGroupAddon, InputGroupInput } from '../chunk-UPP56S32.js';
|
|
3
3
|
import '../chunk-QYA2HGKW.js';
|
|
4
|
-
import {
|
|
4
|
+
import { Card, CardTitle, CardDescription } from '../chunk-ZG5ZPKFL.js';
|
|
5
|
+
import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuLabel, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuSub, DropdownMenuSubTrigger, DropdownMenuSubContent, DropdownMenuRadioGroup, DropdownMenuRadioItem } from '../chunk-SQA4ILAK.js';
|
|
5
6
|
import { Button } from '../chunk-KFQOYZ64.js';
|
|
6
7
|
import { cn } from '../chunk-XH55BHUU.js';
|
|
7
8
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
8
9
|
import Link from 'next/link';
|
|
9
10
|
import { usePathname } from 'next/navigation';
|
|
10
|
-
import { ChevronsUpDown, Palette, Sun, Moon, Monitor, UserRoundCog, LogOut, Pin, X, PinOff, ListX, Trash2, ChevronDown } from 'lucide-react';
|
|
11
|
+
import { ChevronsUpDown, CircleUser, Palette, Sun, Moon, Monitor, UserRoundCog, LogOut, LogIn, Pin, X, PinOff, ListX, Trash2, ChevronDown, Search } from 'lucide-react';
|
|
11
12
|
import { useTheme } from 'next-themes';
|
|
12
13
|
import { useRef, useEffect, Fragment as Fragment$1 } from 'react';
|
|
13
14
|
|
|
@@ -128,7 +129,7 @@ function NavSection({ label, items }) {
|
|
|
128
129
|
var defaultNavBrandAppsLabel = "Applications";
|
|
129
130
|
function BrandContent({ app }) {
|
|
130
131
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
131
|
-
/* @__PURE__ */ jsx("div", { className: "bg-sidebar-primary text-sidebar-primary-foreground flex aspect-square size-8 items-center justify-center rounded-
|
|
132
|
+
/* @__PURE__ */ jsx("div", { className: "bg-sidebar-primary text-sidebar-primary-foreground flex aspect-square size-8 items-center justify-center rounded-none [&_svg]:size-4", children: app.icon }),
|
|
132
133
|
/* @__PURE__ */ jsxs("div", { className: "grid flex-1 text-left text-sm leading-tight", children: [
|
|
133
134
|
/* @__PURE__ */ jsx("span", { className: "truncate font-semibold", children: app.name }),
|
|
134
135
|
app.description ? /* @__PURE__ */ jsx("span", { className: "text-muted-foreground truncate text-xs", children: app.description }) : null
|
|
@@ -159,14 +160,14 @@ function NavBrand({
|
|
|
159
160
|
/* @__PURE__ */ jsxs(
|
|
160
161
|
DropdownMenuContent,
|
|
161
162
|
{
|
|
162
|
-
className: "w-(--radix-dropdown-menu-trigger-width) min-w-56 rounded-
|
|
163
|
+
className: "w-(--radix-dropdown-menu-trigger-width) min-w-56 rounded-none",
|
|
163
164
|
align: "start",
|
|
164
165
|
side: isMobile ? "bottom" : "right",
|
|
165
166
|
sideOffset: 4,
|
|
166
167
|
children: [
|
|
167
168
|
/* @__PURE__ */ jsx(DropdownMenuLabel, { className: "text-muted-foreground text-xs", children: appsLabel }),
|
|
168
169
|
apps?.map((item) => /* @__PURE__ */ jsx(DropdownMenuItem, { asChild: true, className: "gap-2 p-2", children: /* @__PURE__ */ jsxs("a", { href: item.href, children: [
|
|
169
|
-
/* @__PURE__ */ jsx("div", { className: "flex size-6 items-center justify-center rounded-
|
|
170
|
+
/* @__PURE__ */ jsx("div", { className: "flex size-6 items-center justify-center rounded-none border [&_svg]:size-3.5", children: item.icon }),
|
|
170
171
|
/* @__PURE__ */ jsx("span", { className: "truncate", children: item.name })
|
|
171
172
|
] }) }, item.href)),
|
|
172
173
|
children ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
@@ -194,6 +195,7 @@ function NavUser({
|
|
|
194
195
|
labels,
|
|
195
196
|
onSwitchAccount,
|
|
196
197
|
onSignOut,
|
|
198
|
+
onSignIn,
|
|
197
199
|
showTheme = true,
|
|
198
200
|
themeLabels,
|
|
199
201
|
children
|
|
@@ -202,9 +204,26 @@ function NavUser({
|
|
|
202
204
|
const { theme, setTheme } = useTheme();
|
|
203
205
|
const l = { ...defaultAccountMenuLabels, ...labels };
|
|
204
206
|
const t = { ...defaultNavUserThemeLabels, ...themeLabels };
|
|
205
|
-
if (!user) return null;
|
|
206
|
-
const name = user.name ?? user.email ?? l.account;
|
|
207
|
-
const email = user
|
|
207
|
+
if (!user && !onSignIn) return null;
|
|
208
|
+
const name = user ? user.name ?? user.email ?? l.account : l.guest;
|
|
209
|
+
const email = user?.email ?? "";
|
|
210
|
+
const avatar = /* @__PURE__ */ jsxs(Avatar, { className: "size-8 rounded-lg", children: [
|
|
211
|
+
user?.image ? /* @__PURE__ */ jsx(AvatarImage, { src: user.image, alt: name }) : null,
|
|
212
|
+
/* @__PURE__ */ jsx(AvatarFallback, { className: "rounded-lg", children: user ? initialsOf(name) : /* @__PURE__ */ jsx(CircleUser, { className: "size-4" }) })
|
|
213
|
+
] });
|
|
214
|
+
const themeSubmenu = showTheme ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
215
|
+
/* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
|
|
216
|
+
/* @__PURE__ */ jsxs(DropdownMenuSub, { children: [
|
|
217
|
+
/* @__PURE__ */ jsxs(DropdownMenuSubTrigger, { children: [
|
|
218
|
+
/* @__PURE__ */ jsx(Palette, { className: "mr-2 size-4" }),
|
|
219
|
+
t.theme
|
|
220
|
+
] }),
|
|
221
|
+
/* @__PURE__ */ jsx(DropdownMenuSubContent, { children: /* @__PURE__ */ jsx(DropdownMenuRadioGroup, { value: theme ?? "system", onValueChange: setTheme, children: THEMES.map(({ value, key, icon: Icon }) => /* @__PURE__ */ jsxs(DropdownMenuRadioItem, { value, children: [
|
|
222
|
+
/* @__PURE__ */ jsx(Icon, { className: "mr-2 size-4" }),
|
|
223
|
+
t[key]
|
|
224
|
+
] }, value)) }) })
|
|
225
|
+
] })
|
|
226
|
+
] }) : null;
|
|
208
227
|
return /* @__PURE__ */ jsx(SidebarMenu, { children: /* @__PURE__ */ jsx(SidebarMenuItem, { children: /* @__PURE__ */ jsxs(DropdownMenu, { children: [
|
|
209
228
|
/* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
|
|
210
229
|
SidebarMenuButton,
|
|
@@ -213,10 +232,7 @@ function NavUser({
|
|
|
213
232
|
tooltip: name,
|
|
214
233
|
className: "data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground",
|
|
215
234
|
children: [
|
|
216
|
-
|
|
217
|
-
user.image ? /* @__PURE__ */ jsx(AvatarImage, { src: user.image, alt: name }) : null,
|
|
218
|
-
/* @__PURE__ */ jsx(AvatarFallback, { className: "rounded-lg", children: initialsOf(name) })
|
|
219
|
-
] }),
|
|
235
|
+
avatar,
|
|
220
236
|
/* @__PURE__ */ jsxs("div", { className: "grid flex-1 text-left text-sm leading-tight", children: [
|
|
221
237
|
/* @__PURE__ */ jsx("span", { className: "truncate font-medium", children: name }),
|
|
222
238
|
email ? /* @__PURE__ */ jsx("span", { className: "text-muted-foreground truncate text-xs", children: email }) : null
|
|
@@ -234,48 +250,34 @@ function NavUser({
|
|
|
234
250
|
sideOffset: 4,
|
|
235
251
|
children: [
|
|
236
252
|
/* @__PURE__ */ jsxs(DropdownMenuLabel, { className: "flex items-center gap-2", children: [
|
|
237
|
-
|
|
238
|
-
user.image ? /* @__PURE__ */ jsx(AvatarImage, { src: user.image, alt: name }) : null,
|
|
239
|
-
/* @__PURE__ */ jsx(AvatarFallback, { className: "rounded-lg", children: initialsOf(name) })
|
|
240
|
-
] }),
|
|
253
|
+
avatar,
|
|
241
254
|
/* @__PURE__ */ jsxs("div", { className: "grid flex-1 text-left leading-tight", children: [
|
|
242
255
|
/* @__PURE__ */ jsx("span", { className: "truncate text-sm font-medium", children: name }),
|
|
243
256
|
email ? /* @__PURE__ */ jsx("span", { className: "text-muted-foreground truncate text-xs font-normal", children: email }) : null
|
|
244
257
|
] })
|
|
245
258
|
] }),
|
|
246
|
-
|
|
247
|
-
/* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
|
|
248
|
-
/* @__PURE__ */ jsxs(DropdownMenuSub, { children: [
|
|
249
|
-
/* @__PURE__ */ jsxs(DropdownMenuSubTrigger, { children: [
|
|
250
|
-
/* @__PURE__ */ jsx(Palette, { className: "mr-2 size-4" }),
|
|
251
|
-
t.theme
|
|
252
|
-
] }),
|
|
253
|
-
/* @__PURE__ */ jsx(DropdownMenuSubContent, { children: /* @__PURE__ */ jsx(
|
|
254
|
-
DropdownMenuRadioGroup,
|
|
255
|
-
{
|
|
256
|
-
value: theme ?? "system",
|
|
257
|
-
onValueChange: setTheme,
|
|
258
|
-
children: THEMES.map(({ value, key, icon: Icon }) => /* @__PURE__ */ jsxs(DropdownMenuRadioItem, { value, children: [
|
|
259
|
-
/* @__PURE__ */ jsx(Icon, { className: "mr-2 size-4" }),
|
|
260
|
-
t[key]
|
|
261
|
-
] }, value))
|
|
262
|
-
}
|
|
263
|
-
) })
|
|
264
|
-
] })
|
|
265
|
-
] }) : null,
|
|
259
|
+
themeSubmenu,
|
|
266
260
|
children ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
267
261
|
/* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
|
|
268
262
|
children
|
|
269
263
|
] }) : null,
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
/* @__PURE__ */
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
/* @__PURE__ */
|
|
277
|
-
|
|
278
|
-
|
|
264
|
+
user ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
265
|
+
onSwitchAccount || onSignOut ? /* @__PURE__ */ jsx(DropdownMenuSeparator, {}) : null,
|
|
266
|
+
onSwitchAccount ? /* @__PURE__ */ jsxs(DropdownMenuItem, { onSelect: onSwitchAccount, children: [
|
|
267
|
+
/* @__PURE__ */ jsx(UserRoundCog, { className: "mr-2 size-4" }),
|
|
268
|
+
l.switchAccount
|
|
269
|
+
] }) : null,
|
|
270
|
+
onSignOut ? /* @__PURE__ */ jsxs(DropdownMenuItem, { variant: "destructive", onSelect: onSignOut, children: [
|
|
271
|
+
/* @__PURE__ */ jsx(LogOut, { className: "mr-2 size-4" }),
|
|
272
|
+
l.signOut
|
|
273
|
+
] }) : null
|
|
274
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
275
|
+
/* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
|
|
276
|
+
/* @__PURE__ */ jsxs(DropdownMenuItem, { onSelect: onSignIn, children: [
|
|
277
|
+
/* @__PURE__ */ jsx(LogIn, { className: "mr-2 size-4" }),
|
|
278
|
+
l.signIn
|
|
279
|
+
] })
|
|
280
|
+
] })
|
|
279
281
|
]
|
|
280
282
|
}
|
|
281
283
|
)
|
|
@@ -499,7 +501,65 @@ function Breadcrumbs({ separator, labels, ...rest }) {
|
|
|
499
501
|
] }, href);
|
|
500
502
|
}) }) });
|
|
501
503
|
}
|
|
504
|
+
var defaultAppGridLabels = {
|
|
505
|
+
searchPlaceholder: "Search apps\u2026",
|
|
506
|
+
empty: "No apps found."
|
|
507
|
+
};
|
|
508
|
+
function AppGrid({
|
|
509
|
+
apps,
|
|
510
|
+
query,
|
|
511
|
+
onQueryChange,
|
|
512
|
+
searchPlaceholder = defaultAppGridLabels.searchPlaceholder,
|
|
513
|
+
autoFocusSearch = false,
|
|
514
|
+
emptyLabel = defaultAppGridLabels.empty,
|
|
515
|
+
className
|
|
516
|
+
}) {
|
|
517
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("space-y-8", className), children: [
|
|
518
|
+
onQueryChange ? /* @__PURE__ */ jsxs(InputGroup, { className: "mx-auto h-10 max-w-md", children: [
|
|
519
|
+
/* @__PURE__ */ jsx(InputGroupAddon, { children: /* @__PURE__ */ jsx(Search, {}) }),
|
|
520
|
+
/* @__PURE__ */ jsx(
|
|
521
|
+
InputGroupInput,
|
|
522
|
+
{
|
|
523
|
+
type: "search",
|
|
524
|
+
value: query ?? "",
|
|
525
|
+
onChange: (e) => onQueryChange(e.target.value),
|
|
526
|
+
placeholder: searchPlaceholder,
|
|
527
|
+
"aria-label": searchPlaceholder,
|
|
528
|
+
autoFocus: autoFocusSearch
|
|
529
|
+
}
|
|
530
|
+
)
|
|
531
|
+
] }) : null,
|
|
532
|
+
apps.length === 0 ? /* @__PURE__ */ jsx("p", { className: "text-muted-foreground py-16 text-center text-sm", children: emptyLabel }) : /* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 gap-4 sm:grid-cols-3 lg:grid-cols-4", children: apps.map((app) => /* @__PURE__ */ jsx(AppTile, { app }, app.key)) })
|
|
533
|
+
] });
|
|
534
|
+
}
|
|
535
|
+
function AppTile({ app }) {
|
|
536
|
+
return /* @__PURE__ */ jsx(
|
|
537
|
+
"a",
|
|
538
|
+
{
|
|
539
|
+
href: app.href,
|
|
540
|
+
target: app.external ? "_blank" : void 0,
|
|
541
|
+
rel: app.external ? "noreferrer" : void 0,
|
|
542
|
+
className: "focus-visible:ring-ring group rounded-none outline-none focus-visible:ring-2",
|
|
543
|
+
children: /* @__PURE__ */ jsxs(Card, { className: "h-full items-center gap-4 px-6 py-8 text-center transition-all duration-200 group-hover:-translate-y-0.5 group-hover:shadow-md group-hover:ring-foreground/30", children: [
|
|
544
|
+
/* @__PURE__ */ jsx(
|
|
545
|
+
"div",
|
|
546
|
+
{
|
|
547
|
+
className: cn(
|
|
548
|
+
"flex size-14 items-center justify-center rounded-none ring-1 ring-foreground/5 ring-inset transition-transform duration-200 group-hover:scale-105 [&_svg]:size-7",
|
|
549
|
+
app.accent
|
|
550
|
+
),
|
|
551
|
+
children: app.icon
|
|
552
|
+
}
|
|
553
|
+
),
|
|
554
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
|
|
555
|
+
/* @__PURE__ */ jsx(CardTitle, { children: app.name }),
|
|
556
|
+
app.description ? /* @__PURE__ */ jsx(CardDescription, { className: "line-clamp-2", children: app.description }) : null
|
|
557
|
+
] })
|
|
558
|
+
] })
|
|
559
|
+
}
|
|
560
|
+
);
|
|
561
|
+
}
|
|
502
562
|
|
|
503
|
-
export { AppShell, AppShellBody, AppShellHeader, AppShellMain, Breadcrumbs, NavBrand, NavGroup, NavItem, NavSection, NavUser, SidebarDock, SidebarPanel, StackedSidebar, TabBar, defaultNavBrandAppsLabel, defaultNavUserThemeLabels, defaultTabBarLabels, useActiveRoute };
|
|
563
|
+
export { AppGrid, AppShell, AppShellBody, AppShellHeader, AppShellMain, AppTile, Breadcrumbs, NavBrand, NavGroup, NavItem, NavSection, NavUser, SidebarDock, SidebarPanel, StackedSidebar, TabBar, defaultAppGridLabels, defaultNavBrandAppsLabel, defaultNavUserThemeLabels, defaultTabBarLabels, useActiveRoute };
|
|
504
564
|
//# sourceMappingURL=index.js.map
|
|
505
565
|
//# sourceMappingURL=index.js.map
|