@olwiba/ui 0.2.21 → 0.2.23

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/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { ClassValue } from 'clsx';
2
2
  import * as react_jsx_runtime from 'react/jsx-runtime';
3
3
  import * as React from 'react';
4
- import React__default, { ReactNode } from 'react';
4
+ import React__default, { ReactNode, HTMLAttributes } from 'react';
5
5
  import { ButtonProps as ButtonProps$1, CardProps as CardProps$1, BadgeProps as BadgeProps$1, InputProps as InputProps$1, TextareaProps as TextareaProps$1, CheckboxProps as CheckboxProps$1, SwitchProps as SwitchProps$1 } from '@olwiba/cn';
6
6
  export { CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Enchanted, EnchantedProps } from '@olwiba/cn';
7
7
  import { LucideIcon } from 'lucide-react';
@@ -247,18 +247,43 @@ type AppShellRenderLink = (props: {
247
247
  children: ReactNode;
248
248
  className?: string;
249
249
  }) => ReactNode;
250
+ /**
251
+ * One step in the header location trail. A bare string is a plain label; give
252
+ * it an `href` to make it walkable. The final crumb is the current route and is
253
+ * never rendered as a link.
254
+ */
255
+ type AppShellBreadcrumb = string | {
256
+ label: string;
257
+ href?: string;
258
+ };
250
259
  interface AppShellProps {
251
260
  brand?: AppShellBrand;
252
261
  navItems?: AppNavItem[];
253
262
  /** Primary CTA rendered above nav (e.g. "New project", "Quick create") */
254
263
  action?: AppShellAction;
255
264
  user?: AppShellUser;
256
- /** Text shown in the top header bar */
265
+ /**
266
+ * Location context shown in the top header bar. This is app chrome, not the
267
+ * page address — the page (or its page pattern) owns the `<h1>`. Repeating
268
+ * the page title here prints the same words twice on every route.
269
+ */
257
270
  pageTitle?: string;
271
+ /**
272
+ * Where the current route sits in the app, e.g.
273
+ * `[{ label: "Admin", href: "/admin" }, "Users"]`. Rendered as a muted trail
274
+ * and preferred over `pageTitle` when supplied.
275
+ */
276
+ breadcrumbs?: AppShellBreadcrumb[];
258
277
  /** Slot rendered at the start of the top header bar, after the sidebar trigger. */
259
278
  headerStart?: ReactNode;
260
279
  /** Slot rendered at the end of the top header bar. */
261
280
  headerEnd?: ReactNode;
281
+ /**
282
+ * App chrome rendered after the page outlet — normally an `AppFooter`. This
283
+ * belongs to the shell, not to a page pattern: otherwise every route
284
+ * re-declares it and height-filling pages fight it for the remaining space.
285
+ */
286
+ footer?: ReactNode;
262
287
  /** Override link rendering for SPA navigation. Defaults to a native <a>. */
263
288
  renderLink?: AppShellRenderLink;
264
289
  children?: ReactNode;
@@ -287,7 +312,7 @@ interface AppShellProps {
287
312
  */
288
313
  contentClassName?: string;
289
314
  }
290
- declare function AppShell({ brand, navItems, action, user, pageTitle, headerStart, headerEnd, renderLink, collapsible, sidebarPosition, side, contentClassName, children, }?: AppShellProps): react_jsx_runtime.JSX.Element;
315
+ declare function AppShell({ brand, navItems, action, user, pageTitle, breadcrumbs, footer, headerStart, headerEnd, renderLink, collapsible, sidebarPosition, side, contentClassName, children, }?: AppShellProps): react_jsx_runtime.JSX.Element;
291
316
 
292
317
  interface AppPageHeroProps {
293
318
  eyebrow?: ReactNode;
@@ -297,6 +322,15 @@ interface AppPageHeroProps {
297
322
  action?: ReactNode;
298
323
  children?: ReactNode;
299
324
  compact?: boolean;
325
+ /**
326
+ * How the address is drawn.
327
+ * - `"card"` (default) — a bordered surface that introduces the route.
328
+ * - `"plain"` — type only. Use when the page content is itself made of
329
+ * surfaces: a second card at the top competes with them instead of
330
+ * introducing them, and pushes the region that actually does something
331
+ * further down the page.
332
+ */
333
+ surface?: 'card' | 'plain';
300
334
  className?: string;
301
335
  }
302
336
  /**
@@ -305,7 +339,25 @@ interface AppPageHeroProps {
305
339
  * Use this when a route needs more visual weight than a simple `PageHeader`,
306
340
  * but still keep product-specific stats, actions, and copy in the consumer.
307
341
  */
308
- declare function AppPageHero({ eyebrow, title, description, icon: Icon, action, children, compact, className, }: AppPageHeroProps): react_jsx_runtime.JSX.Element;
342
+ declare function AppPageHero({ eyebrow, title, description, icon: Icon, action, children, compact, surface, className, }: AppPageHeroProps): react_jsx_runtime.JSX.Element;
343
+
344
+ interface AppFooterProps extends HTMLAttributes<HTMLElement> {
345
+ /** Leading content — a product line, build info, a rotating message. */
346
+ start?: ReactNode;
347
+ /** Trailing content — a status pill, version, or a short link row. */
348
+ end?: ReactNode;
349
+ }
350
+ /**
351
+ * Quiet utility row for signed-in chrome.
352
+ *
353
+ * Pass it to `AppShell`'s `footer` slot: it is app chrome, so it lives beside
354
+ * the page outlet rather than inside a page pattern. Public marketing pages use
355
+ * the full `Footer` instead — this exists so long app pages do not end abruptly.
356
+ *
357
+ * The row owns geometry only. What the slots contain — live status, version,
358
+ * links, product copy — stays with the product.
359
+ */
360
+ declare function AppFooter({ start, end, children, className, ...props }: AppFooterProps): react_jsx_runtime.JSX.Element;
309
361
 
310
362
  interface AuthFormProps {
311
363
  /**
@@ -2096,4 +2148,4 @@ interface UsePaginationReturn {
2096
2148
  }
2097
2149
  declare function usePagination(total: number, pageSize: number): UsePaginationReturn;
2098
2150
 
2099
- export { ActivityFeed, type ActivityFeedItem, type ActivityFeedProps, AnimatedPill, type AnimatedPillProps, AnimatedSwap, type AnimatedSwapEffect, type AnimatedSwapProps, type AnimatedSwapSpec, AppContent, type AppContentProps, AppGrid, AppGridCell, type AppGridCellProps, type AppGridColumns, type AppGridProps, type AppNavItem, AppPageHero, type AppPageHeroProps, AppScreen, AppShell, type AppShellAction, type AppShellBrand, type AppShellProps, type AppShellRenderLink, type AppShellUser, type AuthFormProps, AuthSection, type AuthSectionProps, Badge, type BadgeProps, type BillingInvoice, BillingPanel, type BillingPanelProps, type BillingPaymentMethod, type BillingUsageMetric, BrandColorSwitchMinimal, Button, type ButtonProps, Card, type CardProps, Carousel, type CarouselProps, ChangelogCard, type ChangelogCardProps, type ChangelogHighlight, ChangelogList, type ChangelogListProps, type ChangelogReleaseType, Chart, type ChartProps, type ChartSeries, Checkbox, type CheckboxProps, CommandMenu, type CommandMenuGroup, type CommandMenuItem, type CommandMenuProps, type ComparisonColumn, ComparisonSection, type ComparisonSectionProps, ConfirmDialog, type ConfirmDialogProps, type ConfirmOptions, type ContactInfoItem, ContactSection, type ContactSectionProps, ContextMenu, type ContextMenuDef, type ContextMenuProps, CountUp, type CountUpProps, CountdownTimer, type CountdownTimerProps, CtaSection, type CtaSectionProps, DataTable, type DataTableProps, DataView, type DataViewProps, DevBanner, type DevBannerProps, Dock, type DockItem, type DockProps, EmptyState, type EmptyStateProps, ErrorPage, type ErrorPageProps, FadeIn, type FadeInProps, FaqSection, type FaqSectionProps, FeatureCard, type FeatureCardProps, type FeatureMarqueeItem, type FeatureMarqueeRow, FeatureMarqueeSection, type FeatureMarqueeSectionProps, FeaturesSection, type FeaturesSectionProps, FileUpload, type FileUploadEntry, type FileUploadProps, FlowBracket, type FlowBracketProps, FlowConnector, type FlowConnectorProps, Footer, type FooterProps, FullPageSpinner, GlassCard, type GlassCardProps, Grid, GridItem, type GridItemProps, type GridProps, type GroupedFeatureGroup, GroupedFeaturesSection, type GroupedFeaturesSectionProps, HeroSection, type HeroSectionProps, type Hotkey, ImageCard, type ImageCardProps, Input, type InputProps, LogoStrip, type LogoStripProps, type MarketingSectionSpacing, type MarketingSurface, MarketingSurfaceProvider, MediaCard, type MediaCardProps, ModeSwitchMinimal, Navbar, type NavbarProps, NewsletterSection, type NewsletterSectionProps, type NotificationItem, NotificationToast, type NotificationToastProps, NotificationsPopover, type NotificationsPopoverProps, type NotifyAction, type NotifyOptions, OlwibaUIProvider, type OlwibaUIProviderProps, type OnboardingStep, OnboardingWizard, type OnboardingWizardProps, Overlay, type OverlayProps, type OverlayVariant, PageHeader, type PageHeaderBackButton, type PageHeaderBreadcrumb, type PageHeaderProps, PageTransition, type PageTransitionProps, PhoneFrame, type PhoneFrameProps, type PostAuthor, PostCard, type PostCardProps, PostList, type PostListProps, PricingCard, type PricingCardProps, type PricingFeature, type PricingPlan, PricingSection, type PricingSectionProps, PublicPageFrame, type PublicPageFrameProps, type QualificationColumn, QualificationSection, type QualificationSectionProps, RegisterHotkeys, RootErrorFallback, Section, type SectionProps, SectionTitle, type SectionTitleProps, SettingsSection, type SettingsSectionProps, Sortable, type SortableProps, Spotlight, type SpotlightGroup, type SpotlightItem, type SpotlightProps, Stack, type StackProps, StaggerChildren, type StaggerChildrenProps, StatCard, type StatCardProps, StatsSection, type StatsSectionProps, type StepGroup, type StepItem, StepsSection, type StepsSectionProps, Suspensed, Switch, type SwitchProps, type TeamMember, type TeamMemberRecord, TeamMembersPanel, type TeamMembersPanelProps, TeamSection, type TeamSectionProps, type TechStackItem, TechStackSection, type TechStackSectionProps, TestimonialCard, type TestimonialCardProps, TestimonialsSection, type TestimonialsSectionProps, Textarea, type TextareaProps, ThemeColorUpdater, ThemeSwitchMinimal, type UIMode, Underlay, type UnderlayProps, type UnderlayVariant, UpdateBanner, type UpdateBannerProps, type UpgradeComparisonRow, UpgradePrompt, type UpgradePromptProps, type UseConfirmReturn, type UseControlledOpenReturn, type UsePaginationReturn, type UseViewModeReturn, VersionBanner, type ViewMode, ViewToggle, type ViewToggleProps, cn, marketingSectionSpacing, notify, useConfirm, useControlledOpen, useCopyToClipboard, useDebounce, useIntersectionObserver, useLocalStorage, useMarketingSurface, useMediaQuery, useMounted, useOlwibaUI, usePagination, useScrolledPast, useSectionSurface, useUIMode, useViewMode };
2151
+ export { ActivityFeed, type ActivityFeedItem, type ActivityFeedProps, AnimatedPill, type AnimatedPillProps, AnimatedSwap, type AnimatedSwapEffect, type AnimatedSwapProps, type AnimatedSwapSpec, AppContent, type AppContentProps, AppFooter, type AppFooterProps, AppGrid, AppGridCell, type AppGridCellProps, type AppGridColumns, type AppGridProps, type AppNavItem, AppPageHero, type AppPageHeroProps, AppScreen, AppShell, type AppShellAction, type AppShellBrand, type AppShellBreadcrumb, type AppShellProps, type AppShellRenderLink, type AppShellUser, type AuthFormProps, AuthSection, type AuthSectionProps, Badge, type BadgeProps, type BillingInvoice, BillingPanel, type BillingPanelProps, type BillingPaymentMethod, type BillingUsageMetric, BrandColorSwitchMinimal, Button, type ButtonProps, Card, type CardProps, Carousel, type CarouselProps, ChangelogCard, type ChangelogCardProps, type ChangelogHighlight, ChangelogList, type ChangelogListProps, type ChangelogReleaseType, Chart, type ChartProps, type ChartSeries, Checkbox, type CheckboxProps, CommandMenu, type CommandMenuGroup, type CommandMenuItem, type CommandMenuProps, type ComparisonColumn, ComparisonSection, type ComparisonSectionProps, ConfirmDialog, type ConfirmDialogProps, type ConfirmOptions, type ContactInfoItem, ContactSection, type ContactSectionProps, ContextMenu, type ContextMenuDef, type ContextMenuProps, CountUp, type CountUpProps, CountdownTimer, type CountdownTimerProps, CtaSection, type CtaSectionProps, DataTable, type DataTableProps, DataView, type DataViewProps, DevBanner, type DevBannerProps, Dock, type DockItem, type DockProps, EmptyState, type EmptyStateProps, ErrorPage, type ErrorPageProps, FadeIn, type FadeInProps, FaqSection, type FaqSectionProps, FeatureCard, type FeatureCardProps, type FeatureMarqueeItem, type FeatureMarqueeRow, FeatureMarqueeSection, type FeatureMarqueeSectionProps, FeaturesSection, type FeaturesSectionProps, FileUpload, type FileUploadEntry, type FileUploadProps, FlowBracket, type FlowBracketProps, FlowConnector, type FlowConnectorProps, Footer, type FooterProps, FullPageSpinner, GlassCard, type GlassCardProps, Grid, GridItem, type GridItemProps, type GridProps, type GroupedFeatureGroup, GroupedFeaturesSection, type GroupedFeaturesSectionProps, HeroSection, type HeroSectionProps, type Hotkey, ImageCard, type ImageCardProps, Input, type InputProps, LogoStrip, type LogoStripProps, type MarketingSectionSpacing, type MarketingSurface, MarketingSurfaceProvider, MediaCard, type MediaCardProps, ModeSwitchMinimal, Navbar, type NavbarProps, NewsletterSection, type NewsletterSectionProps, type NotificationItem, NotificationToast, type NotificationToastProps, NotificationsPopover, type NotificationsPopoverProps, type NotifyAction, type NotifyOptions, OlwibaUIProvider, type OlwibaUIProviderProps, type OnboardingStep, OnboardingWizard, type OnboardingWizardProps, Overlay, type OverlayProps, type OverlayVariant, PageHeader, type PageHeaderBackButton, type PageHeaderBreadcrumb, type PageHeaderProps, PageTransition, type PageTransitionProps, PhoneFrame, type PhoneFrameProps, type PostAuthor, PostCard, type PostCardProps, PostList, type PostListProps, PricingCard, type PricingCardProps, type PricingFeature, type PricingPlan, PricingSection, type PricingSectionProps, PublicPageFrame, type PublicPageFrameProps, type QualificationColumn, QualificationSection, type QualificationSectionProps, RegisterHotkeys, RootErrorFallback, Section, type SectionProps, SectionTitle, type SectionTitleProps, SettingsSection, type SettingsSectionProps, Sortable, type SortableProps, Spotlight, type SpotlightGroup, type SpotlightItem, type SpotlightProps, Stack, type StackProps, StaggerChildren, type StaggerChildrenProps, StatCard, type StatCardProps, StatsSection, type StatsSectionProps, type StepGroup, type StepItem, StepsSection, type StepsSectionProps, Suspensed, Switch, type SwitchProps, type TeamMember, type TeamMemberRecord, TeamMembersPanel, type TeamMembersPanelProps, TeamSection, type TeamSectionProps, type TechStackItem, TechStackSection, type TechStackSectionProps, TestimonialCard, type TestimonialCardProps, TestimonialsSection, type TestimonialsSectionProps, Textarea, type TextareaProps, ThemeColorUpdater, ThemeSwitchMinimal, type UIMode, Underlay, type UnderlayProps, type UnderlayVariant, UpdateBanner, type UpdateBannerProps, type UpgradeComparisonRow, UpgradePrompt, type UpgradePromptProps, type UseConfirmReturn, type UseControlledOpenReturn, type UsePaginationReturn, type UseViewModeReturn, VersionBanner, type ViewMode, ViewToggle, type ViewToggleProps, cn, marketingSectionSpacing, notify, useConfirm, useControlledOpen, useCopyToClipboard, useDebounce, useIntersectionObserver, useLocalStorage, useMarketingSurface, useMediaQuery, useMounted, useOlwibaUI, usePagination, useScrolledPast, useSectionSurface, useUIMode, useViewMode };
package/dist/index.js CHANGED
@@ -2,10 +2,10 @@ import { cn } from './chunk-AMWLSHD6.js';
2
2
  export { MdxContent, cn } from './chunk-AMWLSHD6.js';
3
3
  import * as React21 from 'react';
4
4
  import { useRef, useEffect, useState, useCallback } from 'react';
5
- import { Button as Button$1, Card as Card$1, Input as Input$1, Textarea as Textarea$1, Checkbox as Checkbox$1, Switch as Switch$1, useIsMobile, UIVariantProvider, Badge as Badge$1, cn as cn$1, Table, TableHeader, TableRow, TableHead, TableBody, TableCell, Avatar, AvatarImage, AvatarFallback, Select, SelectTrigger, SelectValue, SelectContent, SelectItem, DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, Dialog, DialogTrigger, Progress, useUIVariant, Separator, Accordion, AccordionItem, AccordionTrigger, AccordionContent, Label, Sheet, SheetTrigger, SheetContent, StatusIndicator, CommandDialog, CommandInput, CommandList, CommandEmpty, CommandSeparator, CommandGroup, CommandItem, TooltipProvider, Tooltip, TooltipTrigger, TooltipContent, ContextMenu as ContextMenu$1, ContextMenuTrigger, ContextMenuContent, AlertDialog, AlertDialogContent, AlertDialogHeader, AlertDialogTitle, AlertDialogDescription, AlertDialogFooter, AlertDialogCancel, AlertDialogAction, CommandShortcut, Popover, PopoverTrigger, PopoverContent, Spinner, SidebarProvider, SidebarInset, CardHeader, CardTitle, CardDescription, CardContent, InputOTP, InputOTPGroup, InputOTPSlot, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter, DialogClose, ContextMenuSeparator, ContextMenuLabel, ContextMenuSub, ContextMenuSubTrigger, ContextMenuSubContent, ContextMenuItem, ContextMenuShortcut, useSidebar, Sidebar, SidebarHeader, SidebarMenu, SidebarMenuItem, SidebarContent, SidebarGroup, SidebarGroupContent, SidebarMenuButton, SidebarFooter, SidebarTrigger, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuGroup } from '@olwiba/cn';
5
+ import { Button as Button$1, Card as Card$1, Input as Input$1, Textarea as Textarea$1, Checkbox as Checkbox$1, Switch as Switch$1, useIsMobile, UIVariantProvider, Badge as Badge$1, SidebarProvider, SidebarInset, cn as cn$1, Table, TableHeader, TableRow, TableHead, TableBody, TableCell, Avatar, AvatarImage, AvatarFallback, Select, SelectTrigger, SelectValue, SelectContent, SelectItem, DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, Dialog, DialogTrigger, Progress, useUIVariant, Separator, Accordion, AccordionItem, AccordionTrigger, AccordionContent, Label, Sheet, SheetTrigger, SheetContent, StatusIndicator, CommandDialog, CommandInput, CommandList, CommandEmpty, CommandSeparator, CommandGroup, CommandItem, TooltipProvider, Tooltip, TooltipTrigger, TooltipContent, ContextMenu as ContextMenu$1, ContextMenuTrigger, ContextMenuContent, AlertDialog, AlertDialogContent, AlertDialogHeader, AlertDialogTitle, AlertDialogDescription, AlertDialogFooter, AlertDialogCancel, AlertDialogAction, CommandShortcut, Popover, PopoverTrigger, PopoverContent, Spinner, useSidebar, Sidebar, SidebarHeader, SidebarMenu, SidebarMenuItem, SidebarContent, SidebarGroup, SidebarGroupContent, SidebarMenuButton, SidebarFooter, SidebarTrigger, CardHeader, CardTitle, CardDescription, CardContent, InputOTP, InputOTPGroup, InputOTPSlot, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter, DialogClose, ContextMenuSeparator, ContextMenuLabel, ContextMenuSub, ContextMenuSubTrigger, ContextMenuSubContent, ContextMenuItem, ContextMenuShortcut, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuGroup } from '@olwiba/cn';
6
6
  export { CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Enchanted } from '@olwiba/cn';
7
7
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
8
- import { Search, ArrowUp, ArrowDown, ArrowUpDown, ChevronLeft, ChevronRight, MoreHorizontal, UserPlus, Download, CreditCard, Check, Loader2, ArrowLeft, ArrowUpRight, X, Sparkles, RefreshCw, ArrowRight, Minus, Quote, Star, Twitter, Github, Linkedin, Mail, MessageSquare, ChevronDown, Send, Menu, UploadCloud, File, CheckCircle2, AlertCircle, Bell, Inbox, Activity, TrendingUp, TrendingDown, LayoutGrid, List, Sun, Moon, Palette, AlertTriangle, Rocket, Info, Layers, ShieldCheck, Building2, BirdIcon, MoreVerticalIcon, CreditCardIcon, BellIcon, SettingsIcon, LogOutIcon } from 'lucide-react';
8
+ import { Search, ArrowUp, ArrowDown, ArrowUpDown, ChevronLeft, ChevronRight, MoreHorizontal, UserPlus, Download, CreditCard, Check, Loader2, ArrowLeft, ArrowUpRight, X, Sparkles, RefreshCw, ArrowRight, Minus, Quote, Star, Twitter, Github, Linkedin, Mail, MessageSquare, ChevronDown, Send, Menu, UploadCloud, File, CheckCircle2, AlertCircle, Bell, Inbox, Activity, TrendingUp, TrendingDown, LayoutGrid, List, Sun, Moon, Palette, AlertTriangle, Rocket, Info, Layers, BirdIcon, MoreVerticalIcon, CreditCardIcon, BellIcon, SettingsIcon, LogOutIcon, ShieldCheck, Building2 } from 'lucide-react';
9
9
  import { useReactTable, getPaginationRowModel, getSortedRowModel, getCoreRowModel, flexRender } from '@tanstack/react-table';
10
10
  import { useSensors, useSensor, PointerSensor, KeyboardSensor, DndContext, closestCenter } from '@dnd-kit/core';
11
11
  import { sortableKeyboardCoordinates, SortableContext, rectSortingStrategy, horizontalListSortingStrategy, verticalListSortingStrategy, arrayMove, useSortable } from '@dnd-kit/sortable';
@@ -306,7 +306,7 @@ function NavUser({ user }) {
306
306
  BirdIcon,
307
307
  {
308
308
  "aria-hidden": true,
309
- className: "size-4 drop-shadow-[0_1px_1px_rgb(0_0_0/0.3)]"
309
+ className: "size-5 drop-shadow-[0_1px_1px_rgb(0_0_0/0.3)]"
310
310
  }
311
311
  ) })
312
312
  ] }),
@@ -333,7 +333,7 @@ function NavUser({ user }) {
333
333
  BirdIcon,
334
334
  {
335
335
  "aria-hidden": true,
336
- className: "size-4 drop-shadow-[0_1px_1px_rgb(0_0_0/0.3)]"
336
+ className: "size-5 drop-shadow-[0_1px_1px_rgb(0_0_0/0.3)]"
337
337
  }
338
338
  ) })
339
339
  ] }),
@@ -444,14 +444,50 @@ function ShellSidebar({
444
444
  }
445
445
  function ShellHeader({
446
446
  pageTitle,
447
+ breadcrumbs,
447
448
  headerStart,
448
- headerEnd
449
+ headerEnd,
450
+ renderLink
449
451
  }) {
452
+ const source = breadcrumbs?.length ? breadcrumbs : pageTitle ? [pageTitle] : [];
453
+ const trail = source.map(
454
+ (crumb) => typeof crumb === "string" ? { label: crumb, href: void 0 } : crumb
455
+ );
450
456
  return /* @__PURE__ */ jsx("header", { className: "flex h-12 shrink-0 items-center gap-2 border-b transition-[width,height] ease-linear group-has-data-[collapsible=icon]/sidebar-wrapper:h-12", children: /* @__PURE__ */ jsxs("div", { className: "flex w-full items-center gap-1 px-4 lg:gap-2 lg:px-6", children: [
451
457
  /* @__PURE__ */ jsx(SidebarTrigger, { className: "-ml-1" }),
452
458
  headerStart && /* @__PURE__ */ jsx("div", { className: "flex items-center gap-1", children: headerStart }),
453
- /* @__PURE__ */ jsx(Separator, { orientation: "vertical", className: "mx-2 data-[orientation=vertical]:h-4" }),
454
- /* @__PURE__ */ jsx("h1", { className: "text-base font-medium", children: pageTitle }),
459
+ trail.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
460
+ /* @__PURE__ */ jsx(Separator, { orientation: "vertical", className: "mx-2 data-[orientation=vertical]:h-4" }),
461
+ /* @__PURE__ */ jsx("nav", { "aria-label": "Breadcrumb", className: "flex min-w-0 items-center gap-1.5 text-sm", children: trail.map((crumb, index) => {
462
+ const isCurrent = index === trail.length - 1;
463
+ const isLink = !isCurrent && Boolean(crumb.href);
464
+ return /* @__PURE__ */ jsxs(
465
+ "span",
466
+ {
467
+ className: "flex min-w-0 items-center gap-1.5",
468
+ children: [
469
+ index > 0 && /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "text-muted-foreground/60", children: "/" }),
470
+ isLink ? renderLink({
471
+ href: crumb.href,
472
+ className: "truncate rounded-sm text-muted-foreground transition-colors hover:text-foreground hover:underline underline-offset-4 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
473
+ children: crumb.label
474
+ }) : /* @__PURE__ */ jsx(
475
+ "span",
476
+ {
477
+ "aria-current": isCurrent ? "page" : void 0,
478
+ className: cn$1(
479
+ "truncate",
480
+ isCurrent ? "font-medium text-foreground" : "text-muted-foreground"
481
+ ),
482
+ children: crumb.label
483
+ }
484
+ )
485
+ ]
486
+ },
487
+ `${crumb.label}-${index}`
488
+ );
489
+ }) })
490
+ ] }),
455
491
  headerEnd && /* @__PURE__ */ jsx("div", { className: "ml-auto flex items-center gap-1", children: headerEnd })
456
492
  ] }) });
457
493
  }
@@ -469,7 +505,9 @@ function AppShell({
469
505
  navItems = [],
470
506
  action,
471
507
  user = defaultUser,
472
- pageTitle = "Dashboard",
508
+ pageTitle,
509
+ breadcrumbs,
510
+ footer,
473
511
  headerStart,
474
512
  headerEnd,
475
513
  renderLink = defaultRenderLink,
@@ -500,8 +538,18 @@ function AppShell({
500
538
  }
501
539
  ),
502
540
  /* @__PURE__ */ jsxs(SidebarInset, { className: "overflow-y-auto", children: [
503
- /* @__PURE__ */ jsx(ShellHeader, { pageTitle, headerStart, headerEnd }),
504
- /* @__PURE__ */ jsx("div", { className: contentClassName, children })
541
+ /* @__PURE__ */ jsx(
542
+ ShellHeader,
543
+ {
544
+ pageTitle,
545
+ breadcrumbs,
546
+ headerStart,
547
+ headerEnd,
548
+ renderLink
549
+ }
550
+ ),
551
+ /* @__PURE__ */ jsx("div", { className: cn$1("flex min-h-0 grow shrink-0 flex-col", contentClassName), children }),
552
+ footer && /* @__PURE__ */ jsx("div", { className: "shrink-0", children: footer })
505
553
  ] })
506
554
  ]
507
555
  }
@@ -519,49 +567,116 @@ function AppPageHero({
519
567
  action,
520
568
  children,
521
569
  compact = false,
570
+ surface = "card",
522
571
  className
523
572
  }) {
573
+ const isPlain = surface === "plain";
524
574
  return /* @__PURE__ */ jsxs(
525
575
  "section",
526
576
  {
527
577
  className: cn(
528
- "relative overflow-hidden rounded-3xl border bg-card/80 p-5 shadow-sm sm:p-6",
529
- // The glow blobs are decoration, and `::after` is the section's last
530
- // child so with everything on `z-index: auto` it paints above the
531
- // header content and swallows clicks on whatever sits under it. At
532
- // narrow widths the action row stacks below the copy, right into the
533
- // bottom-left blob, which is how a visible button stops responding.
534
- // pointer-events-none keeps them purely visual.
535
- "before:pointer-events-none before:absolute before:-right-16 before:-top-16 before:size-44 before:rounded-full before:bg-primary/15 before:blur-3xl",
536
- "after:pointer-events-none after:absolute after:-bottom-20 after:left-10 after:size-52 after:rounded-full after:bg-primary/10 after:blur-3xl",
578
+ "relative",
579
+ !isPlain && [
580
+ "overflow-hidden border bg-card/80 shadow-sm",
581
+ // Compact is the page-pattern header: same surface and glow, less
582
+ // bulk, so it introduces a route without eating the fold above dense
583
+ // content.
584
+ compact ? "rounded-2xl p-4 sm:p-5" : "rounded-3xl p-5 sm:p-6",
585
+ // The glow blobs are decoration, and `::after` is the section's last
586
+ // child so with everything on `z-index: auto` it paints above the
587
+ // header content and swallows clicks on whatever sits under it. At
588
+ // narrow widths the action row stacks below the copy, right into the
589
+ // bottom-left blob, which is how a visible button stops responding.
590
+ // pointer-events-none keeps them purely visual.
591
+ "before:pointer-events-none before:absolute before:-right-16 before:-top-16 before:rounded-full before:bg-primary/15 before:blur-3xl",
592
+ "after:pointer-events-none after:absolute after:left-10 after:rounded-full after:bg-primary/10 after:blur-3xl",
593
+ compact ? "before:size-32 after:-bottom-16 after:size-40" : "before:size-44 after:-bottom-20 after:size-52"
594
+ ],
537
595
  className
538
596
  ),
539
597
  children: [
540
- /* @__PURE__ */ jsxs("div", { className: "relative flex flex-col gap-5 sm:flex-row sm:items-start sm:justify-between", children: [
541
- /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 gap-4", children: [
542
- Icon && /* @__PURE__ */ jsx("div", { className: "flex size-12 shrink-0 items-center justify-center rounded-2xl border bg-background/70 text-primary shadow-sm", children: /* @__PURE__ */ jsx(Icon, { className: "size-5" }) }),
543
- /* @__PURE__ */ jsxs("div", { className: "min-w-0 space-y-2", children: [
544
- eyebrow && /* @__PURE__ */ jsx("p", { className: "text-xs font-semibold uppercase tracking-[0.24em] text-primary/80", children: eyebrow }),
545
- /* @__PURE__ */ jsx(
546
- "h1",
547
- {
548
- className: cn(
549
- "font-semibold tracking-tight",
550
- compact ? "text-2xl" : "text-3xl sm:text-4xl"
598
+ /* @__PURE__ */ jsxs(
599
+ "div",
600
+ {
601
+ className: cn(
602
+ "relative flex flex-col sm:flex-row sm:items-start sm:justify-between",
603
+ compact ? "gap-3" : "gap-5"
604
+ ),
605
+ children: [
606
+ /* @__PURE__ */ jsxs("div", { className: cn("flex min-w-0 items-start", compact ? "gap-3" : "gap-4"), children: [
607
+ Icon && /* @__PURE__ */ jsx(
608
+ "div",
609
+ {
610
+ className: cn(
611
+ "flex shrink-0 items-center justify-center border bg-background/70 text-primary shadow-sm",
612
+ compact ? "size-10 rounded-xl" : "size-12 rounded-2xl"
613
+ ),
614
+ children: /* @__PURE__ */ jsx(Icon, { className: compact ? "size-4" : "size-5" })
615
+ }
616
+ ),
617
+ /* @__PURE__ */ jsxs("div", { className: cn("min-w-0", compact ? "space-y-1" : "space-y-2"), children: [
618
+ eyebrow && /* @__PURE__ */ jsx(
619
+ "p",
620
+ {
621
+ className: cn(
622
+ "font-semibold uppercase text-primary/80",
623
+ compact ? "text-[11px] tracking-[0.18em]" : "text-xs tracking-[0.24em]"
624
+ ),
625
+ children: eyebrow
626
+ }
551
627
  ),
552
- children: title
553
- }
554
- ),
555
- description && /* @__PURE__ */ jsx("p", { className: "max-w-2xl text-sm leading-6 text-muted-foreground", children: description })
556
- ] })
557
- ] }),
558
- action && /* @__PURE__ */ jsx("div", { className: "relative shrink-0 sm:pt-1", children: action })
559
- ] }),
560
- children && /* @__PURE__ */ jsx("div", { className: "relative mt-5", children })
628
+ /* @__PURE__ */ jsx(
629
+ "h1",
630
+ {
631
+ className: cn(
632
+ // Default leading puts ~4px of half-leading above the cap, so
633
+ // the title reads as sitting low against a top-aligned icon.
634
+ "font-semibold leading-tight tracking-tight",
635
+ compact ? "text-xl sm:text-2xl" : "text-3xl sm:text-4xl"
636
+ ),
637
+ children: title
638
+ }
639
+ ),
640
+ description && // A div, not a p: `description` is a ReactNode, and callers pass
641
+ // multiple paragraphs. Nesting <p> inside <p> is invalid HTML and
642
+ // the parser silently unnests it, which breaks hydration.
643
+ /* @__PURE__ */ jsx(
644
+ "div",
645
+ {
646
+ className: cn(
647
+ "max-w-2xl text-muted-foreground",
648
+ compact ? "text-sm leading-5" : "text-sm leading-6"
649
+ ),
650
+ children: description
651
+ }
652
+ )
653
+ ] })
654
+ ] }),
655
+ action && /* @__PURE__ */ jsx("div", { className: cn("relative shrink-0", !compact && "sm:pt-1"), children: action })
656
+ ]
657
+ }
658
+ ),
659
+ children && /* @__PURE__ */ jsx("div", { className: cn("relative", compact ? "mt-4" : "mt-5"), children })
561
660
  ]
562
661
  }
563
662
  );
564
663
  }
664
+ function AppFooter({ start, end, children, className, ...props }) {
665
+ return /* @__PURE__ */ jsx(
666
+ "footer",
667
+ {
668
+ ...props,
669
+ className: cn(
670
+ "border-t px-4 py-3 text-xs text-muted-foreground sm:px-6",
671
+ className
672
+ ),
673
+ children: /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 items-center justify-between gap-3", children: [
674
+ /* @__PURE__ */ jsx("div", { className: "min-w-0 font-medium text-foreground", children: start ?? children }),
675
+ end && /* @__PURE__ */ jsx("div", { className: "flex shrink-0 items-center gap-2", children: end })
676
+ ] })
677
+ }
678
+ );
679
+ }
565
680
  var defaultRenderLink2 = ({ href, children, className }) => /* @__PURE__ */ jsx("a", { href, className, children });
566
681
  function CenteredAuth({ children, brand, framed, className }) {
567
682
  if (framed) {
@@ -1502,13 +1617,13 @@ function UpdateBanner({
1502
1617
  Card$1,
1503
1618
  {
1504
1619
  className: cn$1(
1505
- "max-w-3xl border-amber-300/60 bg-amber-50 dark:border-amber-700/60 dark:bg-amber-950",
1620
+ "max-w-3xl border-border bg-card text-card-foreground shadow-lg",
1506
1621
  className
1507
1622
  ),
1508
1623
  children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-6 p-4", children: [
1509
1624
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
1510
- /* @__PURE__ */ jsx(Sparkles, { className: "size-5 shrink-0 text-amber-600 dark:text-amber-400", "aria-hidden": "true" }),
1511
- /* @__PURE__ */ jsx("p", { className: "text-sm text-amber-800 dark:text-amber-200", children: message })
1625
+ /* @__PURE__ */ jsx(Sparkles, { className: "size-5 shrink-0 text-primary", "aria-hidden": "true" }),
1626
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-card-foreground", children: message })
1512
1627
  ] }),
1513
1628
  /* @__PURE__ */ jsx(
1514
1629
  Button$1,
@@ -1516,7 +1631,7 @@ function UpdateBanner({
1516
1631
  onClick: handleRefresh,
1517
1632
  disabled: refreshing,
1518
1633
  size: "sm",
1519
- className: "shrink-0 bg-amber-600 text-white hover:bg-amber-700 dark:bg-amber-600 dark:hover:bg-amber-700",
1634
+ className: "shrink-0",
1520
1635
  children: refreshing ? /* @__PURE__ */ jsx(RefreshCw, { className: "size-4 animate-spin" }) : buttonLabel
1521
1636
  }
1522
1637
  )
@@ -5569,6 +5684,6 @@ function usePagination(total, pageSize) {
5569
5684
  return { page, pageSize, totalPages, offset, hasPrev: page > 1, hasNext: page < totalPages, goTo, next, prev };
5570
5685
  }
5571
5686
 
5572
- export { ActivityFeed, AnimatedPill, AnimatedSwap, AppContent, AppGrid, AppGridCell, AppPageHero, AppScreen, AppShell, AuthSection, Badge, BillingPanel, BrandColorSwitchMinimal, Button, Card, Carousel, ChangelogCard, ChangelogList, Chart, Checkbox, CommandMenu, ComparisonSection, ConfirmDialog, ContactSection, ContextMenu, CountUp, CountdownTimer, CtaSection, DataTable, DataView, DevBanner, Dock, EmptyState, ErrorPage, FadeIn, FaqSection, FeatureCard, FeatureMarqueeSection, FeaturesSection, FileUpload, FlowBracket, FlowConnector, Footer, FullPageSpinner, GlassCard, Grid, GridItem, GroupedFeaturesSection, HeroSection, ImageCard, Input, LogoStrip, MarketingSurfaceProvider, MediaCard, ModeSwitchMinimal, Navbar, NewsletterSection, NotificationToast, NotificationsPopover, OlwibaUIProvider, OnboardingWizard, Overlay, PageHeader, PageTransition, PhoneFrame, PostCard, PostList, PricingCard, PricingSection, PublicPageFrame, QualificationSection, RegisterHotkeys, RootErrorFallback, Section, SectionTitle, SettingsSection, Sortable, Spotlight, Stack, StaggerChildren, StatCard, StatsSection, StepsSection, Suspensed, Switch, TeamMembersPanel, TeamSection, TechStackSection, TestimonialCard, TestimonialsSection, Textarea, ThemeColorUpdater, ThemeSwitchMinimal, Underlay, UpdateBanner, UpgradePrompt, VersionBanner, ViewToggle, marketingSectionSpacing, notify, useConfirm, useControlledOpen, useCopyToClipboard, useDebounce, useIntersectionObserver, useLocalStorage, useMarketingSurface, useMediaQuery, useMounted, useOlwibaUI, usePagination, useScrolledPast, useSectionSurface, useUIMode, useViewMode };
5687
+ export { ActivityFeed, AnimatedPill, AnimatedSwap, AppContent, AppFooter, AppGrid, AppGridCell, AppPageHero, AppScreen, AppShell, AuthSection, Badge, BillingPanel, BrandColorSwitchMinimal, Button, Card, Carousel, ChangelogCard, ChangelogList, Chart, Checkbox, CommandMenu, ComparisonSection, ConfirmDialog, ContactSection, ContextMenu, CountUp, CountdownTimer, CtaSection, DataTable, DataView, DevBanner, Dock, EmptyState, ErrorPage, FadeIn, FaqSection, FeatureCard, FeatureMarqueeSection, FeaturesSection, FileUpload, FlowBracket, FlowConnector, Footer, FullPageSpinner, GlassCard, Grid, GridItem, GroupedFeaturesSection, HeroSection, ImageCard, Input, LogoStrip, MarketingSurfaceProvider, MediaCard, ModeSwitchMinimal, Navbar, NewsletterSection, NotificationToast, NotificationsPopover, OlwibaUIProvider, OnboardingWizard, Overlay, PageHeader, PageTransition, PhoneFrame, PostCard, PostList, PricingCard, PricingSection, PublicPageFrame, QualificationSection, RegisterHotkeys, RootErrorFallback, Section, SectionTitle, SettingsSection, Sortable, Spotlight, Stack, StaggerChildren, StatCard, StatsSection, StepsSection, Suspensed, Switch, TeamMembersPanel, TeamSection, TechStackSection, TestimonialCard, TestimonialsSection, Textarea, ThemeColorUpdater, ThemeSwitchMinimal, Underlay, UpdateBanner, UpgradePrompt, VersionBanner, ViewToggle, marketingSectionSpacing, notify, useConfirm, useControlledOpen, useCopyToClipboard, useDebounce, useIntersectionObserver, useLocalStorage, useMarketingSurface, useMediaQuery, useMounted, useOlwibaUI, usePagination, useScrolledPast, useSectionSurface, useUIMode, useViewMode };
5573
5688
  //# sourceMappingURL=index.js.map
5574
5689
  //# sourceMappingURL=index.js.map