@alfakit/react 0.1.7 → 0.1.9
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/CHANGELOG.md +16 -0
- package/dist/components/actions/action-modals.js +1 -1
- package/dist/components/actions/action-modals.js.map +1 -1
- package/dist/components/form/form-block.d.ts.map +1 -1
- package/dist/components/form/form-block.js +6 -3
- package/dist/components/form/form-block.js.map +1 -1
- package/dist/components/panel/app-sidebar.js +3 -3
- package/dist/components/panel/app-sidebar.js.map +1 -1
- package/dist/components/panel/bottom-nav.js +2 -2
- package/dist/components/panel/bottom-nav.js.map +1 -1
- package/dist/components/panel/keyboard-shortcuts.js +1 -1
- package/dist/components/panel/keyboard-shortcuts.js.map +1 -1
- package/dist/components/panel/locale-switcher.d.ts.map +1 -1
- package/dist/components/panel/locale-switcher.js +2 -1
- package/dist/components/panel/locale-switcher.js.map +1 -1
- package/dist/components/ui/tooltip.d.ts.map +1 -1
- package/dist/components/ui/tooltip.js +1 -1
- package/dist/components/ui/tooltip.js.map +1 -1
- package/dist/eject-manifest.json +4 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/layouts/top-nav-layout.js +3 -3
- package/dist/layouts/top-nav-layout.js.map +1 -1
- package/dist/standalone/alfakit-component.js +17 -7
- package/dist/standalone/alfakit-component.js.map +1 -1
- package/dist/standalone.css +10 -6
- package/dist/starter-kit/index.d.ts +2 -2
- package/dist/starter-kit/index.js +2 -2
- package/dist/starter-kit/starter-kit.d.ts.map +1 -1
- package/dist/starter-kit/starter-kit.js +7 -2
- package/dist/starter-kit/starter-kit.js.map +1 -1
- package/dist/starter-kit/widgets-loaded.js +74 -13
- package/dist/starter-kit/widgets-loaded.js.map +1 -1
- package/dist/starter-kit/widgets-triggers.js +34 -3
- package/dist/starter-kit/widgets-triggers.js.map +1 -1
- package/dist/starter-kit/widgets.d.ts +11 -2
- package/dist/starter-kit/widgets.d.ts.map +1 -1
- package/dist/starter-kit/widgets.js +20 -2
- package/dist/starter-kit/widgets.js.map +1 -1
- package/package.json +2 -2
- package/src/components/actions/action-modals.tsx +2 -0
- package/src/components/form/form-block.tsx +15 -2
- package/src/components/panel/app-sidebar.tsx +3 -3
- package/src/components/panel/bottom-nav.tsx +2 -2
- package/src/components/panel/keyboard-shortcuts.tsx +1 -1
- package/src/components/panel/locale-switcher.tsx +2 -1
- package/src/components/ui/tooltip.tsx +10 -1
- package/src/layouts/top-nav-layout.tsx +3 -3
- package/src/standalone/alfakit-component.tsx +11 -1
- package/src/starter-kit/index.ts +1 -0
- package/src/starter-kit/starter-kit.tsx +9 -1
- package/src/starter-kit/widgets-loaded.tsx +86 -10
- package/src/starter-kit/widgets-triggers.tsx +41 -1
- package/src/starter-kit/widgets.tsx +33 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tooltip.js","names":["TooltipPrimitive","Tooltip"],"sources":["../../../src/components/ui/tooltip.tsx"],"sourcesContent":["import { Direction, Tooltip as TooltipPrimitive } from 'radix-ui'\nimport type { ComponentProps } from 'react'\nimport { cn } from '../../lib/utils'\n\nfunction TooltipProvider({\n delayDuration = 0,\n ...props\n}: ComponentProps<typeof TooltipPrimitive.Provider>) {\n return (\n <TooltipPrimitive.Provider\n data-slot=\"tooltip-provider\"\n delayDuration={delayDuration}\n {...props}\n />\n )\n}\n\nfunction Tooltip({ ...props }: ComponentProps<typeof TooltipPrimitive.Root>) {\n return <TooltipPrimitive.Root data-slot=\"tooltip\" {...props} />\n}\n\nfunction TooltipTrigger({ ...props }: ComponentProps<typeof TooltipPrimitive.Trigger>) {\n return <TooltipPrimitive.Trigger data-slot
|
|
1
|
+
{"version":3,"file":"tooltip.js","names":["TooltipPrimitive","Tooltip"],"sources":["../../../src/components/ui/tooltip.tsx"],"sourcesContent":["import { Direction, Tooltip as TooltipPrimitive } from 'radix-ui'\nimport type { ComponentProps } from 'react'\nimport { cn } from '../../lib/utils'\n\nfunction TooltipProvider({\n delayDuration = 0,\n ...props\n}: ComponentProps<typeof TooltipPrimitive.Provider>) {\n return (\n <TooltipPrimitive.Provider\n data-slot=\"tooltip-provider\"\n delayDuration={delayDuration}\n {...props}\n />\n )\n}\n\nfunction Tooltip({ ...props }: ComponentProps<typeof TooltipPrimitive.Root>) {\n return <TooltipPrimitive.Root data-slot=\"tooltip\" {...props} />\n}\n\nfunction TooltipTrigger({ ...props }: ComponentProps<typeof TooltipPrimitive.Trigger>) {\n // With asChild the child keeps its own data-slot (an action's `button`, which the\n // button-shape and touch-target CSS select).\n // (The key must be left out, not set to undefined: Slot passes it on and the child's own\n // `{...props}` would erase its data-slot.)\n return (\n <TooltipPrimitive.Trigger\n {...(props.asChild ? {} : { 'data-slot': 'tooltip-trigger' })}\n {...props}\n />\n )\n}\n\nfunction TooltipContent({\n className,\n sideOffset = 4,\n children,\n ...props\n}: ComponentProps<typeof TooltipPrimitive.Content>) {\n // Portaled outside Alfakit's root: carry the reading direction (starter kit pages and\n // standalone components leave <html dir> to the host).\n const dir = Direction.useDirection()\n return (\n <TooltipPrimitive.Portal>\n <TooltipPrimitive.Content\n dir={dir}\n data-slot=\"tooltip-content\"\n sideOffset={sideOffset}\n className={cn(\n 'bg-foreground text-background animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-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 w-fit origin-(--radix-tooltip-content-transform-origin) rounded-md px-3 py-1.5 text-xs text-balance',\n className,\n )}\n {...props}\n >\n {children}\n <TooltipPrimitive.Arrow className=\"bg-foreground fill-foreground z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]\" />\n </TooltipPrimitive.Content>\n </TooltipPrimitive.Portal>\n )\n}\n\nexport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger }\n"],"mappings":";;;;AAIA,SAAS,gBAAgB,EACvB,gBAAgB,GAChB,GAAG,SACgD;CACnD,OACE,oBAACA,QAAiB,UAAlB;EACE,aAAU;EACK;EACf,GAAI;CACL,CAAA;AAEL;AAEA,SAASC,UAAQ,EAAE,GAAG,SAAuD;CAC3E,OAAO,oBAACD,QAAiB,MAAlB;EAAuB,aAAU;EAAU,GAAI;CAAQ,CAAA;AAChE;AAEA,SAAS,eAAe,EAAE,GAAG,SAA0D;CAKrF,OACE,oBAACA,QAAiB,SAAlB;EACE,GAAK,MAAM,UAAU,CAAC,IAAI,EAAE,aAAa,kBAAkB;EAC3D,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,eAAe,EACtB,WACA,aAAa,GACb,UACA,GAAG,SAC+C;CAGlD,MAAM,MAAM,UAAU,aAAa;CACnC,OACE,oBAACA,QAAiB,QAAlB,EAAA,UACE,qBAACA,QAAiB,SAAlB;EACO;EACL,aAAU;EACE;EACZ,WAAW,GACT,qaACA,SACF;EACA,GAAI;EARN,UAAA,CAUG,UACD,oBAACA,QAAiB,OAAlB,EAAwB,WAAU,qGAAsG,CAAA,CAChH;CACH,CAAA,EAAA,CAAA;AAE7B"}
|
package/dist/eject-manifest.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"package": "@alfakit/react",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.9",
|
|
4
4
|
"adapter": "react",
|
|
5
|
-
"generatedAt": "2026-10-
|
|
5
|
+
"generatedAt": "2026-10-25T05:35:46.937Z",
|
|
6
6
|
"components": {
|
|
7
7
|
"TextInput": {
|
|
8
8
|
"file": "src/components/fields/text-input.tsx",
|
|
@@ -921,6 +921,7 @@
|
|
|
921
921
|
},
|
|
922
922
|
"src/starter-kit/widgets.tsx": {
|
|
923
923
|
"AlfakitCopilot": "AlfakitCopilot",
|
|
924
|
+
"AlfakitLanguageSwitcher": "AlfakitLanguageSwitcher",
|
|
924
925
|
"AlfakitNotifications": "AlfakitNotifications",
|
|
925
926
|
"AlfakitSearch": "AlfakitSearch",
|
|
926
927
|
"AlfakitTenantSwitcher": "AlfakitTenantSwitcher",
|
|
@@ -937,6 +938,7 @@
|
|
|
937
938
|
"StarterKitLayout": "StarterKitLayout",
|
|
938
939
|
"StarterKitPageOptions": "StarterKitPageOptions",
|
|
939
940
|
"AlfakitCopilot": "AlfakitCopilot",
|
|
941
|
+
"AlfakitLanguageSwitcher": "AlfakitLanguageSwitcher",
|
|
940
942
|
"AlfakitNotifications": "AlfakitNotifications",
|
|
941
943
|
"AlfakitSearch": "AlfakitSearch",
|
|
942
944
|
"AlfakitTenantSwitcher": "AlfakitTenantSwitcher",
|
package/dist/index.d.ts
CHANGED
|
@@ -148,7 +148,7 @@ import "./standalone/index.js";
|
|
|
148
148
|
import { AlfakitWidgets, AlfakitWidgetsProps } from "./starter-kit/dashboard-widgets.js";
|
|
149
149
|
import { AlfakitNavigation, useAlfakitNavigation } from "./starter-kit/navigation.js";
|
|
150
150
|
import { AlfakitStarterKitRoot, StarterKitContentLayout, StarterKitLayout, StarterKitPageOptions, createStarterKitPage } from "./starter-kit/starter-kit.js";
|
|
151
|
-
import { AlfakitCopilot, AlfakitHeaderWidgetProps, AlfakitNotifications, AlfakitSearch, AlfakitTenantSwitcher } from "./starter-kit/widgets.js";
|
|
151
|
+
import { AlfakitCopilot, AlfakitHeaderWidgetProps, AlfakitLanguageSwitcher, AlfakitNotifications, AlfakitSearch, AlfakitTenantSwitcher } from "./starter-kit/widgets.js";
|
|
152
152
|
import "./starter-kit/index.js";
|
|
153
153
|
import { Alert, AlertDescription, AlertTitle } from "./components/ui/alert.js";
|
|
154
154
|
import { Avatar, AvatarFallback, AvatarImage } from "./components/ui/avatar.js";
|
|
@@ -180,4 +180,4 @@ import { Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, Tabl
|
|
|
180
180
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from "./components/ui/tabs.js";
|
|
181
181
|
import { Textarea } from "./components/ui/textarea.js";
|
|
182
182
|
export * from "@alfakit/core";
|
|
183
|
-
export { ActionButton, ActionGroupMenu, ActionList, ActionModals, AiCopilot, AiStream, Alert, AlertDescription, AlertTitle, AlfakitAnalytics, AlfakitComponent, type AlfakitComponentProps, type AlfakitContextValue, AlfakitCopilot, type AlfakitHeaderWidgetProps, type AlfakitNavigation, AlfakitNotifications, AlfakitPage, AlfakitProvider, AlfakitSearch, AlfakitStarterKitRoot, AlfakitTenantSwitcher, AlfakitToaster, type AlfakitToasterProps, AlfakitWidgets, type AlfakitWidgetsProps, AnalyticsBreakdown, type AnyComponent, AppLayout, AppPage, AppSidebar, AuthLayout, Avatar, AvatarFallback, AvatarImage, Badge, BlankLayout, BottomNav, Brand, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Breadcrumbs, BuilderField, Button, CMS_BLOCK_COMPONENTS, Calendar, CalendarWidget, CallToActionBlock, CalloutComponent, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, ChartWidget, Checkbox, CheckboxField, CheckboxListField, CmsBlockHeading, type CmsBlockProps, CmsBlocks, type CmsContextValue, CmsFooter, CmsHead, CmsHeader, CmsImage, CmsLanguageSwitcher, CmsLinkButton, CmsLivePreview, CmsMenuList, CmsNav, CmsPage, CmsProvider, CodeEditorField, CodeEntryComponent, Collapsible, CollapsibleContent, CollapsibleTrigger, ColorEntryComponent, ColorPickerField, ColumnManager, ColumnsBlock, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, ConflictBanner, ContentBlockRenderer, ContentLayout, ContentLayoutSort, type CreateAlfakitOptions, CustomizableWidgetGrid, DataTable, DatePickerField, DebugPanel, DebugPanelSlot, DebugTreeNode, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, type DiscoveredComponents, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, EmbedBlock, EmptyStateComponent, EntryPlaceholder, EntryWrapper, FaqBlock, FeaturesBlock, type FieldBinding, FieldWrapper, FieldsetComponent, FileManager, FileManagerPickerField, FileUploadField, FilterIndicators, FlashToasts, FlexComponent, FormBlock, FormProvider, FormattedText, FullscreenLayout, type FullscreenLayoutProps, FusedGroupComponent, GalleryBlock, GlobalSearch, GridComponent, HelpdeskChat, type HelpdeskChatProps, HelpdeskInbox, HeroBlock, HiddenField, HtmlComponent, Icon, IconComponent, IconEntryComponent, IconPickerField, ImageBlock, ImageComponent, ImageEntryComponent, ImpersonationBanner, Input, Kanban, KeyValueEntryComponent, KeyValueField, KeyboardShortcuts, Label, LazyPlaceholder, LiveRecordsPill, LocaleSubMenu, LocaleSwitcher, MixedContent, ModalTableSelectField, MoneyInputField, NotificationActionButton, NotificationsMenu, OneTimeCodeInputField, PageActionProvider, PageBlock, type PageBlockProps, PageContent, PageForm, PageHeader, PageInfolist, type PageMethodBinding, type PageMethodMap, type PageMethodsBinding, PageShell, PageTable, PageWidgets, PlaceholderComponent, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, PwaManager, PwaMenuItems, QueryBuilderRulesField, RadioField, RadioGroup, RadioGroupItem, RealtimeNotifications, RecordCell, RecordPresence, RecordVersionsComponent, RenderComponent, RepeatableEntryComponent, RepeaterField, RichEditorField, RichTextBlock, SchemaChildren, SchemaRenderer, ScrollArea, ScrollBar, SectionBlock, SectionComponent, Select, SelectContent, SelectField, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger, ShortcutKeys, ShortcutsOverlay, Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, SignInLink, Skeleton, SliderField, Slot, Spinner, Spreadsheet, type StandaloneContextValue, StandaloneProvider, StarterKitContentLayout, type StarterKitLayout, type StarterKitPageOptions, StatsOverviewWidget, Switch, Table, TableBody, TableCaption, TableCell, TableCellContent, TableFilters, TableFooter, TableHead, TableHeader, TablePagination, TableRow, TableViews, Tabs, TabsComponent, TabsContent, TabsList, TabsTrigger, TagsInputField, TenantMenu, TestimonialsBlock, TextComponent, TextEntryComponent, TextInputField, Textarea, TextareaField, ThemeToggle, Toaster, ToggleButtonsField, ToggleField, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, TopNavLayout, Topbar, TopbarLocaleSwitcher, TranslationManager, Tree, UndoButton, UnorderedListComponent, type UsePageMethodOptions, UserAvatar, UserMenu, ViewComponent, ViewEntryComponent, type VirtualListBinding, WidgetGrid, WidgetRenderer, WizardComponent, badgeColorClasses, badgeVariants, buttonVariants, cn, colorClass, configureAlfakit, createAlfakit, createDefaultRegistry, createStarterKitPage, cssColor, discoverComponents, discoveredComponent, extraProps, ghostButtonColorClasses, iconBackgroundColorClasses, iconSizeClasses, installPwa, outlineButtonColorClasses, panelLayouts, parseStyle, showToast, solidButtonColorClasses, switchOffColorClasses, switchOnColorClasses, textColorClasses, useActionRunner, useAlfakit, useAlfakitNavigation, useAlfakitProps, useAppPage, useChoice, useCms, useDirection, useField, useFormState, useFormStore, useFormatter, useHydrated, useIsMobile, useLiveProps, useLiveUpdates, useLocalization, useOptionalAlfakit, useOptionalFormStore, usePageActionContext, usePageBlock, usePageForm, usePageMethod, usePageMethods, usePageSchema, usePanel, usePollComponent, useRegistry, useReloadProps, useSchemaComponentContext, useScrollToErroredItem, useShortcut, useSidebar, useStandalone, useStore, useStoreSelector, useT, useVirtualList };
|
|
183
|
+
export { ActionButton, ActionGroupMenu, ActionList, ActionModals, AiCopilot, AiStream, Alert, AlertDescription, AlertTitle, AlfakitAnalytics, AlfakitComponent, type AlfakitComponentProps, type AlfakitContextValue, AlfakitCopilot, type AlfakitHeaderWidgetProps, AlfakitLanguageSwitcher, type AlfakitNavigation, AlfakitNotifications, AlfakitPage, AlfakitProvider, AlfakitSearch, AlfakitStarterKitRoot, AlfakitTenantSwitcher, AlfakitToaster, type AlfakitToasterProps, AlfakitWidgets, type AlfakitWidgetsProps, AnalyticsBreakdown, type AnyComponent, AppLayout, AppPage, AppSidebar, AuthLayout, Avatar, AvatarFallback, AvatarImage, Badge, BlankLayout, BottomNav, Brand, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Breadcrumbs, BuilderField, Button, CMS_BLOCK_COMPONENTS, Calendar, CalendarWidget, CallToActionBlock, CalloutComponent, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, ChartWidget, Checkbox, CheckboxField, CheckboxListField, CmsBlockHeading, type CmsBlockProps, CmsBlocks, type CmsContextValue, CmsFooter, CmsHead, CmsHeader, CmsImage, CmsLanguageSwitcher, CmsLinkButton, CmsLivePreview, CmsMenuList, CmsNav, CmsPage, CmsProvider, CodeEditorField, CodeEntryComponent, Collapsible, CollapsibleContent, CollapsibleTrigger, ColorEntryComponent, ColorPickerField, ColumnManager, ColumnsBlock, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, ConflictBanner, ContentBlockRenderer, ContentLayout, ContentLayoutSort, type CreateAlfakitOptions, CustomizableWidgetGrid, DataTable, DatePickerField, DebugPanel, DebugPanelSlot, DebugTreeNode, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, type DiscoveredComponents, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, EmbedBlock, EmptyStateComponent, EntryPlaceholder, EntryWrapper, FaqBlock, FeaturesBlock, type FieldBinding, FieldWrapper, FieldsetComponent, FileManager, FileManagerPickerField, FileUploadField, FilterIndicators, FlashToasts, FlexComponent, FormBlock, FormProvider, FormattedText, FullscreenLayout, type FullscreenLayoutProps, FusedGroupComponent, GalleryBlock, GlobalSearch, GridComponent, HelpdeskChat, type HelpdeskChatProps, HelpdeskInbox, HeroBlock, HiddenField, HtmlComponent, Icon, IconComponent, IconEntryComponent, IconPickerField, ImageBlock, ImageComponent, ImageEntryComponent, ImpersonationBanner, Input, Kanban, KeyValueEntryComponent, KeyValueField, KeyboardShortcuts, Label, LazyPlaceholder, LiveRecordsPill, LocaleSubMenu, LocaleSwitcher, MixedContent, ModalTableSelectField, MoneyInputField, NotificationActionButton, NotificationsMenu, OneTimeCodeInputField, PageActionProvider, PageBlock, type PageBlockProps, PageContent, PageForm, PageHeader, PageInfolist, type PageMethodBinding, type PageMethodMap, type PageMethodsBinding, PageShell, PageTable, PageWidgets, PlaceholderComponent, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, PwaManager, PwaMenuItems, QueryBuilderRulesField, RadioField, RadioGroup, RadioGroupItem, RealtimeNotifications, RecordCell, RecordPresence, RecordVersionsComponent, RenderComponent, RepeatableEntryComponent, RepeaterField, RichEditorField, RichTextBlock, SchemaChildren, SchemaRenderer, ScrollArea, ScrollBar, SectionBlock, SectionComponent, Select, SelectContent, SelectField, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger, ShortcutKeys, ShortcutsOverlay, Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, SignInLink, Skeleton, SliderField, Slot, Spinner, Spreadsheet, type StandaloneContextValue, StandaloneProvider, StarterKitContentLayout, type StarterKitLayout, type StarterKitPageOptions, StatsOverviewWidget, Switch, Table, TableBody, TableCaption, TableCell, TableCellContent, TableFilters, TableFooter, TableHead, TableHeader, TablePagination, TableRow, TableViews, Tabs, TabsComponent, TabsContent, TabsList, TabsTrigger, TagsInputField, TenantMenu, TestimonialsBlock, TextComponent, TextEntryComponent, TextInputField, Textarea, TextareaField, ThemeToggle, Toaster, ToggleButtonsField, ToggleField, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, TopNavLayout, Topbar, TopbarLocaleSwitcher, TranslationManager, Tree, UndoButton, UnorderedListComponent, type UsePageMethodOptions, UserAvatar, UserMenu, ViewComponent, ViewEntryComponent, type VirtualListBinding, WidgetGrid, WidgetRenderer, WizardComponent, badgeColorClasses, badgeVariants, buttonVariants, cn, colorClass, configureAlfakit, createAlfakit, createDefaultRegistry, createStarterKitPage, cssColor, discoverComponents, discoveredComponent, extraProps, ghostButtonColorClasses, iconBackgroundColorClasses, iconSizeClasses, installPwa, outlineButtonColorClasses, panelLayouts, parseStyle, showToast, solidButtonColorClasses, switchOffColorClasses, switchOnColorClasses, textColorClasses, useActionRunner, useAlfakit, useAlfakitNavigation, useAlfakitProps, useAppPage, useChoice, useCms, useDirection, useField, useFormState, useFormStore, useFormatter, useHydrated, useIsMobile, useLiveProps, useLiveUpdates, useLocalization, useOptionalAlfakit, useOptionalFormStore, usePageActionContext, usePageBlock, usePageForm, usePageMethod, usePageMethods, usePageSchema, usePanel, usePollComponent, useRegistry, useReloadProps, useSchemaComponentContext, useScrollToErroredItem, useShortcut, useSidebar, useStandalone, useStore, useStoreSelector, useT, useVirtualList };
|
package/dist/index.js
CHANGED
|
@@ -157,8 +157,8 @@ import { AlfakitComponent } from "./standalone/alfakit-component.js";
|
|
|
157
157
|
import { AlfakitWidgets } from "./starter-kit/dashboard-widgets.js";
|
|
158
158
|
import { useAlfakitNavigation } from "./starter-kit/navigation.js";
|
|
159
159
|
import { AlfakitStarterKitRoot, StarterKitContentLayout, createStarterKitPage } from "./starter-kit/starter-kit.js";
|
|
160
|
-
import { AlfakitCopilot, AlfakitNotifications, AlfakitSearch, AlfakitTenantSwitcher } from "./starter-kit/widgets.js";
|
|
160
|
+
import { AlfakitCopilot, AlfakitLanguageSwitcher, AlfakitNotifications, AlfakitSearch, AlfakitTenantSwitcher } from "./starter-kit/widgets.js";
|
|
161
161
|
import { Alert, AlertDescription, AlertTitle } from "./components/ui/alert.js";
|
|
162
162
|
import { Calendar } from "./components/ui/calendar.js";
|
|
163
163
|
export * from "@alfakit/core";
|
|
164
|
-
export { ActionButton, ActionGroupMenu, ActionList, ActionModals, AiCopilot, AiStream, Alert, AlertDescription, AlertTitle, AlfakitAnalytics, AlfakitComponent, AlfakitCopilot, AlfakitNotifications, AlfakitPage, AlfakitProvider, AlfakitSearch, AlfakitStarterKitRoot, AlfakitTenantSwitcher, AlfakitToaster, AlfakitWidgets, AnalyticsBreakdown, AppLayout, AppPage, AppSidebar, AuthLayout, Avatar, AvatarFallback, AvatarImage, Badge, BlankLayout, BottomNav, Brand, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Breadcrumbs, BuilderField, Button, CMS_BLOCK_COMPONENTS, Calendar, CalendarWidget, CallToActionBlock, CalloutComponent, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, ChartWidget, Checkbox, CheckboxField, CheckboxListField, CmsBlockHeading, CmsBlocks, CmsFooter, CmsHead, CmsHeader, CmsImage, CmsLanguageSwitcher, CmsLinkButton, CmsLivePreview, CmsMenuList, CmsNav, CmsPage, CmsProvider, CodeEditorField, CodeEntryComponent, Collapsible, CollapsibleContent, CollapsibleTrigger, ColorEntryComponent, ColorPickerField, ColumnManager, ColumnsBlock, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, ConflictBanner, ContentBlockRenderer, ContentLayout, ContentLayoutSort, CustomizableWidgetGrid, DataTable, DatePickerField, DebugPanel, DebugPanelSlot, DebugTreeNode, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, EmbedBlock, EmptyStateComponent, EntryPlaceholder, EntryWrapper, FaqBlock, FeaturesBlock, FieldWrapper, FieldsetComponent, FileManager, FileManagerPickerField, FileUploadField, FilterIndicators, FlashToasts, FlexComponent, FormBlock, FormProvider, FormattedText, FullscreenLayout, FusedGroupComponent, GalleryBlock, GlobalSearch, GridComponent, HelpdeskChat, HelpdeskInbox, HeroBlock, HiddenField, HtmlComponent, Icon, IconComponent, IconEntryComponent, IconPickerField, ImageBlock, ImageComponent, ImageEntryComponent, ImpersonationBanner, Input, Kanban, KeyValueEntryComponent, KeyValueField, KeyboardShortcuts, Label, LazyPlaceholder, LiveRecordsPill, LocaleSubMenu, LocaleSwitcher, MixedContent, ModalTableSelectField, MoneyInputField, NotificationActionButton, NotificationsMenu, OneTimeCodeInputField, PageActionProvider, PageBlock, PageContent, PageForm, PageHeader, PageInfolist, PageShell, PageTable, PageWidgets, PlaceholderComponent, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, PwaManager, PwaMenuItems, QueryBuilderRulesField, RadioField, RadioGroup, RadioGroupItem, RealtimeNotifications, RecordCell, RecordPresence, RecordVersionsComponent, RenderComponent, RepeatableEntryComponent, RepeaterField, RichEditorField, RichTextBlock, SchemaChildren, SchemaRenderer, ScrollArea, ScrollBar, SectionBlock, SectionComponent, Select, SelectContent, SelectField, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger, ShortcutKeys, ShortcutsOverlay, Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, SignInLink, Skeleton, SliderField, Slot, Spinner, Spreadsheet, StandaloneProvider, StarterKitContentLayout, StatsOverviewWidget, Switch, Table, TableBody, TableCaption, TableCell, TableCellContent, TableFilters, TableFooter, TableHead, TableHeader, TablePagination, TableRow, TableViews, Tabs, TabsComponent, TabsContent, TabsList, TabsTrigger, TagsInputField, TenantMenu, TestimonialsBlock, TextComponent, TextEntryComponent, TextInputField, Textarea, TextareaField, ThemeToggle, Toaster, ToggleButtonsField, ToggleField, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, TopNavLayout, Topbar, TopbarLocaleSwitcher, TranslationManager, Tree, UndoButton, UnorderedListComponent, UserAvatar, UserMenu, ViewComponent, ViewEntryComponent, WidgetGrid, WidgetRenderer, WizardComponent, badgeColorClasses, badgeVariants, buttonVariants, cn, colorClass, configureAlfakit, createAlfakit, createDefaultRegistry, createStarterKitPage, cssColor, discoverComponents, discoveredComponent, extraProps, ghostButtonColorClasses, iconBackgroundColorClasses, iconSizeClasses, installPwa, outlineButtonColorClasses, panelLayouts, parseStyle, showToast, solidButtonColorClasses, switchOffColorClasses, switchOnColorClasses, textColorClasses, useActionRunner, useAlfakit, useAlfakitNavigation, useAlfakitProps, useAppPage, useChoice, useCms, useDirection, useField, useFormState, useFormStore, useFormatter, useHydrated, useIsMobile, useLiveProps, useLiveUpdates, useLocalization, useOptionalAlfakit, useOptionalFormStore, usePageActionContext, usePageBlock, usePageForm, usePageMethod, usePageMethods, usePageSchema, usePanel, usePollComponent, useRegistry, useReloadProps, useSchemaComponentContext, useScrollToErroredItem, useShortcut, useSidebar, useStandalone, useStore, useStoreSelector, useT, useVirtualList };
|
|
164
|
+
export { ActionButton, ActionGroupMenu, ActionList, ActionModals, AiCopilot, AiStream, Alert, AlertDescription, AlertTitle, AlfakitAnalytics, AlfakitComponent, AlfakitCopilot, AlfakitLanguageSwitcher, AlfakitNotifications, AlfakitPage, AlfakitProvider, AlfakitSearch, AlfakitStarterKitRoot, AlfakitTenantSwitcher, AlfakitToaster, AlfakitWidgets, AnalyticsBreakdown, AppLayout, AppPage, AppSidebar, AuthLayout, Avatar, AvatarFallback, AvatarImage, Badge, BlankLayout, BottomNav, Brand, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Breadcrumbs, BuilderField, Button, CMS_BLOCK_COMPONENTS, Calendar, CalendarWidget, CallToActionBlock, CalloutComponent, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, ChartWidget, Checkbox, CheckboxField, CheckboxListField, CmsBlockHeading, CmsBlocks, CmsFooter, CmsHead, CmsHeader, CmsImage, CmsLanguageSwitcher, CmsLinkButton, CmsLivePreview, CmsMenuList, CmsNav, CmsPage, CmsProvider, CodeEditorField, CodeEntryComponent, Collapsible, CollapsibleContent, CollapsibleTrigger, ColorEntryComponent, ColorPickerField, ColumnManager, ColumnsBlock, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, ConflictBanner, ContentBlockRenderer, ContentLayout, ContentLayoutSort, CustomizableWidgetGrid, DataTable, DatePickerField, DebugPanel, DebugPanelSlot, DebugTreeNode, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, EmbedBlock, EmptyStateComponent, EntryPlaceholder, EntryWrapper, FaqBlock, FeaturesBlock, FieldWrapper, FieldsetComponent, FileManager, FileManagerPickerField, FileUploadField, FilterIndicators, FlashToasts, FlexComponent, FormBlock, FormProvider, FormattedText, FullscreenLayout, FusedGroupComponent, GalleryBlock, GlobalSearch, GridComponent, HelpdeskChat, HelpdeskInbox, HeroBlock, HiddenField, HtmlComponent, Icon, IconComponent, IconEntryComponent, IconPickerField, ImageBlock, ImageComponent, ImageEntryComponent, ImpersonationBanner, Input, Kanban, KeyValueEntryComponent, KeyValueField, KeyboardShortcuts, Label, LazyPlaceholder, LiveRecordsPill, LocaleSubMenu, LocaleSwitcher, MixedContent, ModalTableSelectField, MoneyInputField, NotificationActionButton, NotificationsMenu, OneTimeCodeInputField, PageActionProvider, PageBlock, PageContent, PageForm, PageHeader, PageInfolist, PageShell, PageTable, PageWidgets, PlaceholderComponent, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, PwaManager, PwaMenuItems, QueryBuilderRulesField, RadioField, RadioGroup, RadioGroupItem, RealtimeNotifications, RecordCell, RecordPresence, RecordVersionsComponent, RenderComponent, RepeatableEntryComponent, RepeaterField, RichEditorField, RichTextBlock, SchemaChildren, SchemaRenderer, ScrollArea, ScrollBar, SectionBlock, SectionComponent, Select, SelectContent, SelectField, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger, ShortcutKeys, ShortcutsOverlay, Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, SignInLink, Skeleton, SliderField, Slot, Spinner, Spreadsheet, StandaloneProvider, StarterKitContentLayout, StatsOverviewWidget, Switch, Table, TableBody, TableCaption, TableCell, TableCellContent, TableFilters, TableFooter, TableHead, TableHeader, TablePagination, TableRow, TableViews, Tabs, TabsComponent, TabsContent, TabsList, TabsTrigger, TagsInputField, TenantMenu, TestimonialsBlock, TextComponent, TextEntryComponent, TextInputField, Textarea, TextareaField, ThemeToggle, Toaster, ToggleButtonsField, ToggleField, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, TopNavLayout, Topbar, TopbarLocaleSwitcher, TranslationManager, Tree, UndoButton, UnorderedListComponent, UserAvatar, UserMenu, ViewComponent, ViewEntryComponent, WidgetGrid, WidgetRenderer, WizardComponent, badgeColorClasses, badgeVariants, buttonVariants, cn, colorClass, configureAlfakit, createAlfakit, createDefaultRegistry, createStarterKitPage, cssColor, discoverComponents, discoveredComponent, extraProps, ghostButtonColorClasses, iconBackgroundColorClasses, iconSizeClasses, installPwa, outlineButtonColorClasses, panelLayouts, parseStyle, showToast, solidButtonColorClasses, switchOffColorClasses, switchOnColorClasses, textColorClasses, useActionRunner, useAlfakit, useAlfakitNavigation, useAlfakitProps, useAppPage, useChoice, useCms, useDirection, useField, useFormState, useFormStore, useFormatter, useHydrated, useIsMobile, useLiveProps, useLiveUpdates, useLocalization, useOptionalAlfakit, useOptionalFormStore, usePageActionContext, usePageBlock, usePageForm, usePageMethod, usePageMethods, usePageSchema, usePanel, usePollComponent, useRegistry, useReloadProps, useSchemaComponentContext, useScrollToErroredItem, useShortcut, useSidebar, useStandalone, useStore, useStoreSelector, useT, useVirtualList };
|
|
@@ -76,7 +76,7 @@ function TopNavMenu({ label, icon, items, active, attributes }) {
|
|
|
76
76
|
href: item.url ?? "#",
|
|
77
77
|
children: [item.icon && /* @__PURE__ */ jsx(Icon, { name: item.icon }), /* @__PURE__ */ jsx(NavLabel, { item })]
|
|
78
78
|
})
|
|
79
|
-
}, item.label))
|
|
79
|
+
}, item.url ?? item.label))
|
|
80
80
|
})] });
|
|
81
81
|
}
|
|
82
82
|
function TopNavGroup({ group }) {
|
|
@@ -88,7 +88,7 @@ function TopNavGroup({ group }) {
|
|
|
88
88
|
extraTopbarAttributes: void 0
|
|
89
89
|
} })
|
|
90
90
|
});
|
|
91
|
-
if (!group.label) return /* @__PURE__ */ jsx(Fragment$1, { children: group.items.map((item) => /* @__PURE__ */ jsx(TopNavLink, { item }, item.label)) });
|
|
91
|
+
if (!group.label) return /* @__PURE__ */ jsx(Fragment$1, { children: group.items.map((item) => /* @__PURE__ */ jsx(TopNavLink, { item }, item.url ?? item.label)) });
|
|
92
92
|
return /* @__PURE__ */ jsx(TopNavMenu, {
|
|
93
93
|
label: group.label,
|
|
94
94
|
icon: group.icon,
|
|
@@ -112,7 +112,7 @@ function MobileNav({ onNavigate }) {
|
|
|
112
112
|
"data-active": item.active ? "true" : void 0,
|
|
113
113
|
className: "hover:bg-accent data-[active=true]:bg-accent flex items-center gap-2 rounded-md px-2 py-2 font-medium [&_svg]:size-4",
|
|
114
114
|
children: [item.icon && /* @__PURE__ */ jsx(Icon, { name: item.icon }), /* @__PURE__ */ jsx(NavLabel, { item })]
|
|
115
|
-
}, item.label))]
|
|
115
|
+
}, item.url ?? item.label))]
|
|
116
116
|
}, group.label ?? index))
|
|
117
117
|
});
|
|
118
118
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"top-nav-layout.js","names":[],"sources":["../../src/layouts/top-nav-layout.tsx"],"sourcesContent":["import {\n PREFETCH_CACHE_FOR,\n hasMobilePreset,\n type BreadcrumbSchema,\n type NavigationGroupSchema,\n type NavigationItemSchema,\n type Width,\n} from '@alfakit/core'\nimport { Link } from '@inertiajs/react'\nimport { ChevronDownIcon, MenuIcon } from 'lucide-react'\nimport { createElement, useState, type ReactNode } from 'react'\nimport { NotificationsMenu } from '../components/notifications/notifications-menu'\nimport { BottomNav } from '../components/panel/bottom-nav'\nimport { Brand } from '../components/panel/brand'\nimport { DebugPanelSlot } from '../components/panel/debug-panel-slot'\nimport { GlobalSearch } from '../components/panel/global-search'\nimport { TopbarLocaleSwitcher } from '../components/panel/locale-switcher'\nimport { NavLabel } from '../components/panel/nav-label'\nimport { Slot } from '../components/panel/slot'\nimport { TenantMenu } from '../components/panel/tenant-menu'\nimport { ThemeToggle } from '../components/panel/theme-toggle'\nimport { Breadcrumbs } from '../components/panel/topbar'\nimport { UserMenu } from '../components/panel/user-menu'\nimport { Button } from '../components/ui/button'\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '../components/ui/dropdown-menu'\nimport { Sheet, SheetContent, SheetHeader, SheetTitle, SheetTrigger } from '../components/ui/sheet'\nimport { useDirection, usePanel, useRegistry, useT } from '../context'\nimport { extraProps } from '../lib/attributes'\nimport { Icon } from '../lib/icons'\nimport { NewTabHint } from '../lib/new-tab-hint'\nimport { cn } from '../lib/utils'\nimport { MAX_WIDTHS } from './max-widths'\n\nexport interface TopNavLayoutProps {\n children: ReactNode\n breadcrumbs?: BreadcrumbSchema[]\n maxContentWidth?: Width | string\n}\n\nconst isActive = (item: NavigationItemSchema): boolean =>\n Boolean(item.active || item.children?.some(isActive))\n\nfunction TopNavLink({ item }: { item: NavigationItemSchema }) {\n const className =\n 'text-muted-foreground hover:text-foreground hover:bg-accent data-[active=true]:bg-accent data-[active=true]:text-foreground inline-flex h-9 shrink-0 items-center gap-2 rounded-md px-3 text-sm font-medium transition-colors [&_svg]:size-4'\n\n if (item.children && item.children.length > 0) {\n return (\n <TopNavMenu\n label={<NavLabel item={item} />}\n icon={item.icon}\n items={item.children}\n active={isActive(item)}\n attributes={item.extraAttributes}\n />\n )\n }\n\n return item.openInNewTab ? (\n <a\n // `NavigationItem::extraAttributes()`; `class` is merged with the link's own.\n {...extraProps(item.extraAttributes, className)}\n href={item.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n data-slot=\"topnav-link\"\n >\n {item.icon && <Icon name={item.icon} />}\n <NavLabel item={item} />\n <NewTabHint />\n </a>\n ) : (\n <Link\n {...extraProps(item.extraAttributes, className)}\n href={item.url ?? '#'}\n prefetch\n cacheFor={PREFETCH_CACHE_FOR}\n data-slot=\"topnav-link\"\n data-active={item.active ? 'true' : undefined}\n >\n {item.icon && <Icon name={item.icon} />}\n <NavLabel item={item} />\n </Link>\n )\n}\n\nfunction TopNavMenu({\n label,\n icon,\n items,\n active,\n attributes,\n}: {\n label: ReactNode\n icon?: string\n items: NavigationItemSchema[]\n active: boolean\n attributes?: NavigationItemSchema['extraAttributes']\n}) {\n return (\n <DropdownMenu>\n <DropdownMenuTrigger\n {...extraProps(\n attributes,\n 'text-muted-foreground hover:text-foreground hover:bg-accent data-[active=true]:bg-accent data-[active=true]:text-foreground data-[state=open]:text-foreground inline-flex h-9 shrink-0 items-center gap-1.5 rounded-md px-3 text-sm font-medium transition-colors outline-none [&_svg]:size-4',\n )}\n data-slot=\"topnav-link\"\n data-active={active ? 'true' : undefined}\n >\n {icon && <Icon name={icon} />}\n {label}\n <ChevronDownIcon className=\"opacity-60\" />\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"start\" className=\"min-w-48\">\n {items.map((item) => (\n <DropdownMenuItem key={item.label} asChild>\n <Link\n {...extraProps(item.extraAttributes, cn('w-full', item.active && 'font-medium'))}\n href={item.url ?? '#'}\n >\n {item.icon && <Icon name={item.icon} />}\n <NavLabel item={item} />\n </Link>\n </DropdownMenuItem>\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n )\n}\n\nfunction TopNavGroup({ group }: { group: NavigationGroupSchema }) {\n // `NavigationGroup::extraTopbarAttributes()` wrap the group; `class` is merged.\n if (group.extraTopbarAttributes) {\n return (\n <div\n data-slot=\"topnav-group\"\n {...extraProps(group.extraTopbarAttributes, 'flex shrink-0 items-center gap-1')}\n >\n <TopNavGroup group={{ ...group, extraTopbarAttributes: undefined }} />\n </div>\n )\n }\n\n if (!group.label) {\n return (\n <>\n {group.items.map((item) => (\n <TopNavLink key={item.label} item={item} />\n ))}\n </>\n )\n }\n\n return (\n <TopNavMenu\n label={group.label}\n icon={group.icon}\n items={group.items}\n active={group.items.some(isActive)}\n />\n )\n}\n\n/** Vertical navigation for the mobile drawer. */\nfunction MobileNav({ onNavigate }: { onNavigate: () => void }) {\n const panel = usePanel()\n\n return (\n <nav className=\"flex flex-col gap-4 overflow-y-auto p-4 text-sm\">\n {panel.navigation.map((group, index) => (\n <div key={group.label ?? index} className=\"flex flex-col gap-1\">\n {group.label && (\n <p className=\"text-muted-foreground px-2 text-xs font-medium\">{group.label}</p>\n )}\n {group.items\n .flatMap((item) => [item, ...(item.children ?? [])])\n .map((item) => (\n <Link\n key={item.label}\n href={item.url ?? '#'}\n onClick={onNavigate}\n data-active={item.active ? 'true' : undefined}\n className=\"hover:bg-accent data-[active=true]:bg-accent flex items-center gap-2 rounded-md px-2 py-2 font-medium [&_svg]:size-4\"\n >\n {item.icon && <Icon name={item.icon} />}\n <NavLabel item={item} />\n </Link>\n ))}\n </div>\n ))}\n </nav>\n )\n}\n\n/**\n * Navigation across the top instead of a sidebar (`layout: 'topbar'`). Ungrouped items are\n * links; labelled groups and items with children open as dropdowns.\n */\nexport function TopNavLayout({ children, breadcrumbs, maxContentWidth }: TopNavLayoutProps) {\n const panel = usePanel()\n const t = useT()\n const direction = useDirection()\n const registry = useRegistry()\n const [open, setOpen] = useState(false)\n const width = MAX_WIDTHS[maxContentWidth ?? panel.maxContentWidth ?? '7xl'] ?? 'max-w-7xl'\n const Bottom = registry.resolve('panel:bottom-nav') ?? BottomNav\n\n return (\n <div data-slot=\"topnav-layout\" className=\"bg-background flex min-h-svh flex-col\">\n <Slot name=\"body.start\" />\n <Slot name=\"layout.start\" />\n <Slot name=\"topbar.before\" />\n <header\n data-slot=\"topbar\"\n className=\"bg-background/90 supports-[backdrop-filter]:bg-background/70 sticky top-0 z-30 border-b backdrop-blur\"\n >\n <div className={cn('mx-auto flex h-14 w-full items-center gap-3 px-4 md:px-6', width)}>\n <Sheet open={open} onOpenChange={setOpen}>\n <SheetTrigger asChild>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n className=\"md:hidden\"\n aria-label={t('toggle_sidebar', {}, 'Toggle sidebar')}\n >\n <Icon name=\"alfakit::panels.topbar.open-sidebar-button\" fallback={MenuIcon} />\n </Button>\n </SheetTrigger>\n <SheetContent side={direction === 'rtl' ? 'right' : 'left'} className=\"w-72 p-0\">\n <SheetHeader className=\"border-b\">\n <SheetTitle asChild>\n <div>\n <Brand />\n </div>\n </SheetTitle>\n </SheetHeader>\n <MobileNav onNavigate={() => setOpen(false)} />\n </SheetContent>\n </Sheet>\n <Slot name=\"topbar.logo.before\" />\n <Brand className=\"me-2 shrink-0\" />\n <Slot name=\"topbar.logo.after\" />\n {panel.tenancy?.current && <Slot name=\"tenant-menu.before\" />}\n <TenantMenu variant=\"topbar\" />\n {panel.tenancy?.current && <Slot name=\"tenant-menu.after\" />}\n <nav\n data-slot=\"topnav\"\n aria-label={t('navigation', {}, 'Navigation')}\n className=\"hidden min-w-0 flex-1 items-center gap-1 self-stretch overflow-x-auto md:flex\"\n >\n {panel.navigation.map((group, index) => (\n <TopNavGroup key={group.label ?? `group-${index}`} group={group} />\n ))}\n </nav>\n <Slot name=\"topbar.start\" />\n <div className=\"ms-auto flex shrink-0 items-center gap-1\">\n <Slot name=\"topbar.end\" />\n <GlobalSearch />\n <NotificationsMenu />\n <TopbarLocaleSwitcher />\n <ThemeToggle />\n <DebugPanelSlot />\n <UserMenu variant=\"topbar\" />\n </div>\n </div>\n </header>\n <Slot name=\"topbar.after\" />\n <Slot name=\"content.before\" />\n <main\n data-slot=\"content\"\n className={cn('mx-auto flex w-full min-w-0 flex-1 flex-col gap-6 p-4 md:p-6', width)}\n >\n {panel.breadcrumbs && breadcrumbs && breadcrumbs.length > 0 && (\n <Breadcrumbs items={breadcrumbs} />\n )}\n <Slot name=\"content.start\" />\n {children}\n <Slot name=\"content.end\" />\n </main>\n <Slot name=\"content.after\" />\n <Slot name=\"footer\" />\n {hasMobilePreset(panel) && createElement(Bottom)}\n <Slot name=\"layout.end\" />\n <Slot name=\"body.end\" />\n </div>\n )\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"top-nav-layout.js","names":[],"sources":["../../src/layouts/top-nav-layout.tsx"],"sourcesContent":["import {\n PREFETCH_CACHE_FOR,\n hasMobilePreset,\n type BreadcrumbSchema,\n type NavigationGroupSchema,\n type NavigationItemSchema,\n type Width,\n} from '@alfakit/core'\nimport { Link } from '@inertiajs/react'\nimport { ChevronDownIcon, MenuIcon } from 'lucide-react'\nimport { createElement, useState, type ReactNode } from 'react'\nimport { NotificationsMenu } from '../components/notifications/notifications-menu'\nimport { BottomNav } from '../components/panel/bottom-nav'\nimport { Brand } from '../components/panel/brand'\nimport { DebugPanelSlot } from '../components/panel/debug-panel-slot'\nimport { GlobalSearch } from '../components/panel/global-search'\nimport { TopbarLocaleSwitcher } from '../components/panel/locale-switcher'\nimport { NavLabel } from '../components/panel/nav-label'\nimport { Slot } from '../components/panel/slot'\nimport { TenantMenu } from '../components/panel/tenant-menu'\nimport { ThemeToggle } from '../components/panel/theme-toggle'\nimport { Breadcrumbs } from '../components/panel/topbar'\nimport { UserMenu } from '../components/panel/user-menu'\nimport { Button } from '../components/ui/button'\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '../components/ui/dropdown-menu'\nimport { Sheet, SheetContent, SheetHeader, SheetTitle, SheetTrigger } from '../components/ui/sheet'\nimport { useDirection, usePanel, useRegistry, useT } from '../context'\nimport { extraProps } from '../lib/attributes'\nimport { Icon } from '../lib/icons'\nimport { NewTabHint } from '../lib/new-tab-hint'\nimport { cn } from '../lib/utils'\nimport { MAX_WIDTHS } from './max-widths'\n\nexport interface TopNavLayoutProps {\n children: ReactNode\n breadcrumbs?: BreadcrumbSchema[]\n maxContentWidth?: Width | string\n}\n\nconst isActive = (item: NavigationItemSchema): boolean =>\n Boolean(item.active || item.children?.some(isActive))\n\nfunction TopNavLink({ item }: { item: NavigationItemSchema }) {\n const className =\n 'text-muted-foreground hover:text-foreground hover:bg-accent data-[active=true]:bg-accent data-[active=true]:text-foreground inline-flex h-9 shrink-0 items-center gap-2 rounded-md px-3 text-sm font-medium transition-colors [&_svg]:size-4'\n\n if (item.children && item.children.length > 0) {\n return (\n <TopNavMenu\n label={<NavLabel item={item} />}\n icon={item.icon}\n items={item.children}\n active={isActive(item)}\n attributes={item.extraAttributes}\n />\n )\n }\n\n return item.openInNewTab ? (\n <a\n // `NavigationItem::extraAttributes()`; `class` is merged with the link's own.\n {...extraProps(item.extraAttributes, className)}\n href={item.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n data-slot=\"topnav-link\"\n >\n {item.icon && <Icon name={item.icon} />}\n <NavLabel item={item} />\n <NewTabHint />\n </a>\n ) : (\n <Link\n {...extraProps(item.extraAttributes, className)}\n href={item.url ?? '#'}\n prefetch\n cacheFor={PREFETCH_CACHE_FOR}\n data-slot=\"topnav-link\"\n data-active={item.active ? 'true' : undefined}\n >\n {item.icon && <Icon name={item.icon} />}\n <NavLabel item={item} />\n </Link>\n )\n}\n\nfunction TopNavMenu({\n label,\n icon,\n items,\n active,\n attributes,\n}: {\n label: ReactNode\n icon?: string\n items: NavigationItemSchema[]\n active: boolean\n attributes?: NavigationItemSchema['extraAttributes']\n}) {\n return (\n <DropdownMenu>\n <DropdownMenuTrigger\n {...extraProps(\n attributes,\n 'text-muted-foreground hover:text-foreground hover:bg-accent data-[active=true]:bg-accent data-[active=true]:text-foreground data-[state=open]:text-foreground inline-flex h-9 shrink-0 items-center gap-1.5 rounded-md px-3 text-sm font-medium transition-colors outline-none [&_svg]:size-4',\n )}\n data-slot=\"topnav-link\"\n data-active={active ? 'true' : undefined}\n >\n {icon && <Icon name={icon} />}\n {label}\n <ChevronDownIcon className=\"opacity-60\" />\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"start\" className=\"min-w-48\">\n {items.map((item) => (\n <DropdownMenuItem key={item.url ?? item.label} asChild>\n <Link\n {...extraProps(item.extraAttributes, cn('w-full', item.active && 'font-medium'))}\n href={item.url ?? '#'}\n >\n {item.icon && <Icon name={item.icon} />}\n <NavLabel item={item} />\n </Link>\n </DropdownMenuItem>\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n )\n}\n\nfunction TopNavGroup({ group }: { group: NavigationGroupSchema }) {\n // `NavigationGroup::extraTopbarAttributes()` wrap the group; `class` is merged.\n if (group.extraTopbarAttributes) {\n return (\n <div\n data-slot=\"topnav-group\"\n {...extraProps(group.extraTopbarAttributes, 'flex shrink-0 items-center gap-1')}\n >\n <TopNavGroup group={{ ...group, extraTopbarAttributes: undefined }} />\n </div>\n )\n }\n\n if (!group.label) {\n return (\n <>\n {group.items.map((item) => (\n <TopNavLink key={item.url ?? item.label} item={item} />\n ))}\n </>\n )\n }\n\n return (\n <TopNavMenu\n label={group.label}\n icon={group.icon}\n items={group.items}\n active={group.items.some(isActive)}\n />\n )\n}\n\n/** Vertical navigation for the mobile drawer. */\nfunction MobileNav({ onNavigate }: { onNavigate: () => void }) {\n const panel = usePanel()\n\n return (\n <nav className=\"flex flex-col gap-4 overflow-y-auto p-4 text-sm\">\n {panel.navigation.map((group, index) => (\n <div key={group.label ?? index} className=\"flex flex-col gap-1\">\n {group.label && (\n <p className=\"text-muted-foreground px-2 text-xs font-medium\">{group.label}</p>\n )}\n {group.items\n .flatMap((item) => [item, ...(item.children ?? [])])\n .map((item) => (\n <Link\n key={item.url ?? item.label}\n href={item.url ?? '#'}\n onClick={onNavigate}\n data-active={item.active ? 'true' : undefined}\n className=\"hover:bg-accent data-[active=true]:bg-accent flex items-center gap-2 rounded-md px-2 py-2 font-medium [&_svg]:size-4\"\n >\n {item.icon && <Icon name={item.icon} />}\n <NavLabel item={item} />\n </Link>\n ))}\n </div>\n ))}\n </nav>\n )\n}\n\n/**\n * Navigation across the top instead of a sidebar (`layout: 'topbar'`). Ungrouped items are\n * links; labelled groups and items with children open as dropdowns.\n */\nexport function TopNavLayout({ children, breadcrumbs, maxContentWidth }: TopNavLayoutProps) {\n const panel = usePanel()\n const t = useT()\n const direction = useDirection()\n const registry = useRegistry()\n const [open, setOpen] = useState(false)\n const width = MAX_WIDTHS[maxContentWidth ?? panel.maxContentWidth ?? '7xl'] ?? 'max-w-7xl'\n const Bottom = registry.resolve('panel:bottom-nav') ?? BottomNav\n\n return (\n <div data-slot=\"topnav-layout\" className=\"bg-background flex min-h-svh flex-col\">\n <Slot name=\"body.start\" />\n <Slot name=\"layout.start\" />\n <Slot name=\"topbar.before\" />\n <header\n data-slot=\"topbar\"\n className=\"bg-background/90 supports-[backdrop-filter]:bg-background/70 sticky top-0 z-30 border-b backdrop-blur\"\n >\n <div className={cn('mx-auto flex h-14 w-full items-center gap-3 px-4 md:px-6', width)}>\n <Sheet open={open} onOpenChange={setOpen}>\n <SheetTrigger asChild>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n className=\"md:hidden\"\n aria-label={t('toggle_sidebar', {}, 'Toggle sidebar')}\n >\n <Icon name=\"alfakit::panels.topbar.open-sidebar-button\" fallback={MenuIcon} />\n </Button>\n </SheetTrigger>\n <SheetContent side={direction === 'rtl' ? 'right' : 'left'} className=\"w-72 p-0\">\n <SheetHeader className=\"border-b\">\n <SheetTitle asChild>\n <div>\n <Brand />\n </div>\n </SheetTitle>\n </SheetHeader>\n <MobileNav onNavigate={() => setOpen(false)} />\n </SheetContent>\n </Sheet>\n <Slot name=\"topbar.logo.before\" />\n <Brand className=\"me-2 shrink-0\" />\n <Slot name=\"topbar.logo.after\" />\n {panel.tenancy?.current && <Slot name=\"tenant-menu.before\" />}\n <TenantMenu variant=\"topbar\" />\n {panel.tenancy?.current && <Slot name=\"tenant-menu.after\" />}\n <nav\n data-slot=\"topnav\"\n aria-label={t('navigation', {}, 'Navigation')}\n className=\"hidden min-w-0 flex-1 items-center gap-1 self-stretch overflow-x-auto md:flex\"\n >\n {panel.navigation.map((group, index) => (\n <TopNavGroup key={group.label ?? `group-${index}`} group={group} />\n ))}\n </nav>\n <Slot name=\"topbar.start\" />\n <div className=\"ms-auto flex shrink-0 items-center gap-1\">\n <Slot name=\"topbar.end\" />\n <GlobalSearch />\n <NotificationsMenu />\n <TopbarLocaleSwitcher />\n <ThemeToggle />\n <DebugPanelSlot />\n <UserMenu variant=\"topbar\" />\n </div>\n </div>\n </header>\n <Slot name=\"topbar.after\" />\n <Slot name=\"content.before\" />\n <main\n data-slot=\"content\"\n className={cn('mx-auto flex w-full min-w-0 flex-1 flex-col gap-6 p-4 md:p-6', width)}\n >\n {panel.breadcrumbs && breadcrumbs && breadcrumbs.length > 0 && (\n <Breadcrumbs items={breadcrumbs} />\n )}\n <Slot name=\"content.start\" />\n {children}\n <Slot name=\"content.end\" />\n </main>\n <Slot name=\"content.after\" />\n <Slot name=\"footer\" />\n {hasMobilePreset(panel) && createElement(Bottom)}\n <Slot name=\"layout.end\" />\n <Slot name=\"body.end\" />\n </div>\n )\n}\n"],"mappings":"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"}
|
|
@@ -33,12 +33,19 @@ function AlfakitComponent({ component, components, className, header, footer, ch
|
|
|
33
33
|
const context = useMemo(() => {
|
|
34
34
|
const poll = (target, interval) => state.poll(target, interval);
|
|
35
35
|
const refresh = (targets) => state.refresh(targets);
|
|
36
|
-
if (parent)
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
36
|
+
if (parent) {
|
|
37
|
+
const own = createStandaloneContext({
|
|
38
|
+
action: component.endpoints.action,
|
|
39
|
+
modal: component.endpoints.modal
|
|
40
|
+
}, components, poll);
|
|
41
|
+
return {
|
|
42
|
+
...parent,
|
|
43
|
+
actions: own.actions,
|
|
44
|
+
registry: createStandaloneRegistry(components, parent.registry),
|
|
45
|
+
poll,
|
|
46
|
+
refresh
|
|
47
|
+
};
|
|
48
|
+
}
|
|
42
49
|
return {
|
|
43
50
|
...createStandaloneContext({
|
|
44
51
|
action: component.endpoints.action,
|
|
@@ -124,7 +131,10 @@ function AlfakitComponent({ component, components, className, header, footer, ch
|
|
|
124
131
|
]
|
|
125
132
|
}),
|
|
126
133
|
/* @__PURE__ */ jsx(ActionModals, {}),
|
|
127
|
-
ownsToaster && /* @__PURE__ */ jsx(AlfakitToaster, {
|
|
134
|
+
ownsToaster && /* @__PURE__ */ jsx(AlfakitToaster, {
|
|
135
|
+
claimed: true,
|
|
136
|
+
dir: direction
|
|
137
|
+
})
|
|
128
138
|
]
|
|
129
139
|
});
|
|
130
140
|
return /* @__PURE__ */ jsx(AlfakitProvider, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"alfakit-component.js","names":[],"sources":["../../src/standalone/alfakit-component.tsx"],"sourcesContent":["import {\n StandaloneComponentState,\n findStandalonePropName,\n registerStandaloneProp,\n standalonePanelSchema,\n type ContentBlock,\n type StandaloneComponentSchema,\n} from '@alfakit/core'\nimport { usePage } from '@inertiajs/react'\nimport { Direction } from 'radix-ui'\nimport { useEffect, useMemo, useState, type ReactNode } from 'react'\nimport { PageActionProvider } from '../components/actions/action-context'\nimport { ActionList } from '../components/actions/action-list'\nimport { ActionModals } from '../components/actions/action-modals'\nimport { TooltipProvider } from '../components/ui/tooltip'\nimport {\n AlfakitProvider,\n StandaloneProvider,\n useOptionalAlfakit,\n type AlfakitContextValue,\n type AnyComponent,\n} from '../context'\nimport { cn } from '../lib/utils'\nimport { ContentBlockRenderer } from '../pages/page'\nimport { AlfakitToaster } from './alfakit-toaster'\nimport {\n claimToaster,\n createStandaloneContext,\n createStandaloneRegistry,\n ensureStandaloneRuntime,\n hasToaster,\n} from './runtime'\n\nexport interface AlfakitComponentProps {\n /** The payload: `ContactForm::make()` passed as an Inertia prop. */\n component: StandaloneComponentSchema\n /** Renderer overrides for this instance (`{ TextInput: MyInput }`), on top of `configureAlfakit()`. */\n components?: Record<string, AnyComponent>\n className?: string\n /** Rendered above the content blocks (after the heading and actions). */\n header?: ReactNode\n /** Rendered below the content blocks. */\n footer?: ReactNode\n /** Render each content block yourself (e.g. to lay a form and a table side by side). */\n children?: (blocks: ContentBlock[], render: (block: ContentBlock) => ReactNode) => ReactNode\n}\n\n/**\n * Renders an Alfakit component outside a panel: a form, table, infolist, widgets or any mix\n * (`AlfaSix\\Alfakit\\Standalone\\*`) in any Inertia page of the application. Needs no\n * `createAlfakit()` and no panel layout: it provides its own translator, registry, action\n * runner and modals, and inherits the application's shadcn tokens.\n *\n * ```tsx\n * <AlfakitComponent component={orders} className=\"max-w-4xl\" />\n * ```\n */\nexport function AlfakitComponent({\n component,\n components,\n className,\n header,\n footer,\n children,\n}: AlfakitComponentProps) {\n const parent = useOptionalAlfakit()\n const props = useOptionalPageProps()\n const [, setVersion] = useState(0)\n // The registry overrides are an object literal in JSX: compare them by their keys.\n const overrideKeys = Object.keys(components ?? {}).join(',')\n\n // Lazy and polled schemas of this component, merged into the page it renders.\n const state = useMemo(\n () => new StandaloneComponentState(component, () => setVersion((value) => value + 1)),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [],\n )\n state.setComponent(component)\n\n const context = useMemo<AlfakitContextValue>(() => {\n const poll = (target: string, interval: string | number | null | undefined) =>\n state.poll(target, interval)\n const refresh = (targets: string[]) => state.refresh(targets)\n\n if (parent) {\n return {\n ...parent,\n registry: createStandaloneRegistry(components, parent.registry),\n poll,\n refresh,\n }\n }\n\n return {\n ...createStandaloneContext(\n { action: component.endpoints.action, modal: component.endpoints.modal },\n components,\n poll,\n ),\n refresh,\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [parent, state, overrideKeys])\n\n // Endpoints follow the latest payload (they change per locale or path).\n context.actions.setEndpoints({\n action: component.endpoints.action,\n modal: component.endpoints.modal,\n })\n\n // Inside `createAlfakit()` the panel feeds the shared translator; on a page without the\n // `alfakit` prop (the rest of the app) the component's own translations apply.\n const ownsTranslator = !parent || !props?.alfakit\n\n if (ownsTranslator) {\n context.translator.setTranslations(component.translations ?? {})\n context.translator.setLocale(component.localization?.tag ?? 'en')\n }\n\n const panel = useMemo(() => standalonePanelSchema(component), [component])\n const page = state.page\n const direction = component.localization?.direction ?? 'ltr'\n\n useEffect(() => {\n ensureStandaloneRuntime()\n }, [])\n\n // Partial reloads (sorting, paging, inline edits) request this component's own prop.\n const propName = findStandalonePropName(props, component)\n\n useEffect(() => registerStandaloneProp(propName ?? null), [propName])\n\n useEffect(() => {\n void state.loadLazy(component)\n // The token identifies a new payload.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [state, component.token])\n\n // Toasts: use the layout's <AlfakitToaster /> when there is one, else the first component\n // on the page renders one (checked after every component's effects ran).\n const [ownsToaster, setOwnsToaster] = useState(false)\n\n useEffect(() => {\n if (parent) return\n\n let release: (() => void) | null = null\n let cancelled = false\n\n queueMicrotask(() => {\n if (cancelled || hasToaster()) return\n\n release = claimToaster()\n setOwnsToaster(true)\n })\n\n return () => {\n cancelled = true\n release?.()\n }\n }, [parent])\n\n const render = (block: ContentBlock) => <ContentBlockRenderer key={block.key} block={block} />\n const actionContext = useMemo(\n () => ({ token: component.token, component: 'page' }),\n [component.token],\n )\n\n const body = (\n <PageActionProvider value={actionContext}>\n <div\n data-slot=\"standalone\"\n data-alfakit-component={component.class}\n dir={direction}\n className={cn('flex flex-col gap-6', className)}\n >\n {(page.heading || page.headerActions?.length) && (\n <header\n data-slot=\"page-header\"\n className=\"flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between\"\n >\n <div className=\"min-w-0\">\n {page.heading && (\n <h2 className=\"text-xl font-semibold tracking-tight\">{page.heading}</h2>\n )}\n {page.subheading && (\n <p className=\"text-muted-foreground mt-1 text-sm\">{page.subheading}</p>\n )}\n </div>\n {page.headerActions && page.headerActions.length > 0 && (\n <ActionList\n actions={page.headerActions}\n context={actionContext}\n align=\"end\"\n className=\"max-w-full shrink-0\"\n />\n )}\n </header>\n )}\n {header}\n {children ? children(page.content, render) : page.content.map(render)}\n {footer}\n </div>\n <ActionModals />\n {ownsToaster && <AlfakitToaster claimed />}\n </PageActionProvider>\n )\n\n return (\n <AlfakitProvider value={context}>\n <StandaloneProvider value={{ panel, page }}>\n {parent ? (\n body\n ) : (\n <Direction.Provider dir={direction}>\n <TooltipProvider delayDuration={0}>{body}</TooltipProvider>\n </Direction.Provider>\n )}\n </StandaloneProvider>\n </AlfakitProvider>\n )\n}\n\n/**\n * The host page's Inertia props, or undefined when rendered outside an Inertia app (a\n * component test, Storybook, a plain server render): partial reloads then reload every prop.\n */\nfunction useOptionalPageProps(): Record<string, unknown> | undefined {\n try {\n return usePage().props as Record<string, unknown>\n } catch {\n return undefined\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"alfakit-component.js","names":[],"sources":["../../src/standalone/alfakit-component.tsx"],"sourcesContent":["import {\n StandaloneComponentState,\n findStandalonePropName,\n registerStandaloneProp,\n standalonePanelSchema,\n type ContentBlock,\n type StandaloneComponentSchema,\n} from '@alfakit/core'\nimport { usePage } from '@inertiajs/react'\nimport { Direction } from 'radix-ui'\nimport { useEffect, useMemo, useState, type ReactNode } from 'react'\nimport { PageActionProvider } from '../components/actions/action-context'\nimport { ActionList } from '../components/actions/action-list'\nimport { ActionModals } from '../components/actions/action-modals'\nimport { TooltipProvider } from '../components/ui/tooltip'\nimport {\n AlfakitProvider,\n StandaloneProvider,\n useOptionalAlfakit,\n type AlfakitContextValue,\n type AnyComponent,\n} from '../context'\nimport { cn } from '../lib/utils'\nimport { ContentBlockRenderer } from '../pages/page'\nimport { AlfakitToaster } from './alfakit-toaster'\nimport {\n claimToaster,\n createStandaloneContext,\n createStandaloneRegistry,\n ensureStandaloneRuntime,\n hasToaster,\n} from './runtime'\n\nexport interface AlfakitComponentProps {\n /** The payload: `ContactForm::make()` passed as an Inertia prop. */\n component: StandaloneComponentSchema\n /** Renderer overrides for this instance (`{ TextInput: MyInput }`), on top of `configureAlfakit()`. */\n components?: Record<string, AnyComponent>\n className?: string\n /** Rendered above the content blocks (after the heading and actions). */\n header?: ReactNode\n /** Rendered below the content blocks. */\n footer?: ReactNode\n /** Render each content block yourself (e.g. to lay a form and a table side by side). */\n children?: (blocks: ContentBlock[], render: (block: ContentBlock) => ReactNode) => ReactNode\n}\n\n/**\n * Renders an Alfakit component outside a panel: a form, table, infolist, widgets or any mix\n * (`AlfaSix\\Alfakit\\Standalone\\*`) in any Inertia page of the application. Needs no\n * `createAlfakit()` and no panel layout: it provides its own translator, registry, action\n * runner and modals, and inherits the application's shadcn tokens.\n *\n * ```tsx\n * <AlfakitComponent component={orders} className=\"max-w-4xl\" />\n * ```\n */\nexport function AlfakitComponent({\n component,\n components,\n className,\n header,\n footer,\n children,\n}: AlfakitComponentProps) {\n const parent = useOptionalAlfakit()\n const props = useOptionalPageProps()\n const [, setVersion] = useState(0)\n // The registry overrides are an object literal in JSX: compare them by their keys.\n const overrideKeys = Object.keys(components ?? {}).join(',')\n\n // Lazy and polled schemas of this component, merged into the page it renders.\n const state = useMemo(\n () => new StandaloneComponentState(component, () => setVersion((value) => value + 1)),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [],\n )\n state.setComponent(component)\n\n const context = useMemo<AlfakitContextValue>(() => {\n const poll = (target: string, interval: string | number | null | undefined) =>\n state.poll(target, interval)\n const refresh = (targets: string[]) => state.refresh(targets)\n\n if (parent) {\n // Inside a panel page: the panel's registry and translator, but this component's own\n // action runner, so its actions post to its own endpoints with its own token (sharing\n // the panel's runner sent them to the panel's endpoint: 403).\n const own = createStandaloneContext(\n { action: component.endpoints.action, modal: component.endpoints.modal },\n components,\n poll,\n )\n\n return {\n ...parent,\n actions: own.actions,\n registry: createStandaloneRegistry(components, parent.registry),\n poll,\n refresh,\n }\n }\n\n return {\n ...createStandaloneContext(\n { action: component.endpoints.action, modal: component.endpoints.modal },\n components,\n poll,\n ),\n refresh,\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [parent, state, overrideKeys])\n\n // Endpoints follow the latest payload (they change per locale or path).\n context.actions.setEndpoints({\n action: component.endpoints.action,\n modal: component.endpoints.modal,\n })\n\n // Inside `createAlfakit()` the panel feeds the shared translator; on a page without the\n // `alfakit` prop (the rest of the app) the component's own translations apply.\n const ownsTranslator = !parent || !props?.alfakit\n\n if (ownsTranslator) {\n context.translator.setTranslations(component.translations ?? {})\n context.translator.setLocale(component.localization?.tag ?? 'en')\n }\n\n const panel = useMemo(() => standalonePanelSchema(component), [component])\n const page = state.page\n const direction = component.localization?.direction ?? 'ltr'\n\n useEffect(() => {\n ensureStandaloneRuntime()\n }, [])\n\n // Partial reloads (sorting, paging, inline edits) request this component's own prop.\n const propName = findStandalonePropName(props, component)\n\n useEffect(() => registerStandaloneProp(propName ?? null), [propName])\n\n useEffect(() => {\n void state.loadLazy(component)\n // The token identifies a new payload.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [state, component.token])\n\n // Toasts: use the layout's <AlfakitToaster /> when there is one, else the first component\n // on the page renders one (checked after every component's effects ran).\n const [ownsToaster, setOwnsToaster] = useState(false)\n\n useEffect(() => {\n if (parent) return\n\n let release: (() => void) | null = null\n let cancelled = false\n\n queueMicrotask(() => {\n if (cancelled || hasToaster()) return\n\n release = claimToaster()\n setOwnsToaster(true)\n })\n\n return () => {\n cancelled = true\n release?.()\n }\n }, [parent])\n\n const render = (block: ContentBlock) => <ContentBlockRenderer key={block.key} block={block} />\n const actionContext = useMemo(\n () => ({ token: component.token, component: 'page' }),\n [component.token],\n )\n\n const body = (\n <PageActionProvider value={actionContext}>\n <div\n data-slot=\"standalone\"\n data-alfakit-component={component.class}\n dir={direction}\n className={cn('flex flex-col gap-6', className)}\n >\n {(page.heading || page.headerActions?.length) && (\n <header\n data-slot=\"page-header\"\n className=\"flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between\"\n >\n <div className=\"min-w-0\">\n {page.heading && (\n <h2 className=\"text-xl font-semibold tracking-tight\">{page.heading}</h2>\n )}\n {page.subheading && (\n <p className=\"text-muted-foreground mt-1 text-sm\">{page.subheading}</p>\n )}\n </div>\n {page.headerActions && page.headerActions.length > 0 && (\n <ActionList\n actions={page.headerActions}\n context={actionContext}\n align=\"end\"\n className=\"max-w-full shrink-0\"\n />\n )}\n </header>\n )}\n {header}\n {children ? children(page.content, render) : page.content.map(render)}\n {footer}\n </div>\n <ActionModals />\n {ownsToaster && <AlfakitToaster claimed dir={direction} />}\n </PageActionProvider>\n )\n\n return (\n <AlfakitProvider value={context}>\n <StandaloneProvider value={{ panel, page }}>\n {parent ? (\n body\n ) : (\n <Direction.Provider dir={direction}>\n <TooltipProvider delayDuration={0}>{body}</TooltipProvider>\n </Direction.Provider>\n )}\n </StandaloneProvider>\n </AlfakitProvider>\n )\n}\n\n/**\n * The host page's Inertia props, or undefined when rendered outside an Inertia app (a\n * component test, Storybook, a plain server render): partial reloads then reload every prop.\n */\nfunction useOptionalPageProps(): Record<string, unknown> | undefined {\n try {\n return usePage().props as Record<string, unknown>\n } catch {\n return undefined\n }\n}\n"],"mappings":"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"}
|
package/dist/standalone.css
CHANGED
|
@@ -54,19 +54,23 @@
|
|
|
54
54
|
--color-gray: var(--muted-foreground);
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
+
/* The same status tokens as the panel's styles.css (WCAG AA under their foregrounds). */
|
|
57
58
|
:root {
|
|
58
|
-
--success: var(--alfakit-success, oklch(0.
|
|
59
|
-
--success-foreground: oklch(0.985 0 0);
|
|
60
|
-
--warning: var(--alfakit-warning, oklch(0.
|
|
61
|
-
--warning-foreground: oklch(0.
|
|
62
|
-
--info: var(--alfakit-info, oklch(0.
|
|
63
|
-
--info-foreground: oklch(0.985 0 0);
|
|
59
|
+
--success: var(--alfakit-success, oklch(0.48 0.14 150.5));
|
|
60
|
+
--success-foreground: var(--alfakit-success-foreground, oklch(0.985 0 0));
|
|
61
|
+
--warning: var(--alfakit-warning, oklch(0.52 0.15 48));
|
|
62
|
+
--warning-foreground: var(--alfakit-warning-foreground, oklch(0.985 0 0));
|
|
63
|
+
--info: var(--alfakit-info, oklch(0.51 0.24 263.5));
|
|
64
|
+
--info-foreground: var(--alfakit-info-foreground, oklch(0.985 0 0));
|
|
64
65
|
}
|
|
65
66
|
|
|
66
67
|
.dark {
|
|
67
68
|
--success: var(--alfakit-success, oklch(0.723 0.219 149.579));
|
|
69
|
+
--success-foreground: var(--alfakit-success-foreground, oklch(0.145 0 0));
|
|
68
70
|
--warning: var(--alfakit-warning, oklch(0.828 0.189 84.429));
|
|
71
|
+
--warning-foreground: var(--alfakit-warning-foreground, oklch(0.145 0 0));
|
|
69
72
|
--info: var(--alfakit-info, oklch(0.707 0.165 254.624));
|
|
73
|
+
--info-foreground: var(--alfakit-info-foreground, oklch(0.145 0 0));
|
|
70
74
|
}
|
|
71
75
|
|
|
72
76
|
/*
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AlfakitWidgets, AlfakitWidgetsProps } from "./dashboard-widgets.js";
|
|
2
2
|
import { AlfakitNavigation, useAlfakitNavigation } from "./navigation.js";
|
|
3
3
|
import { AlfakitStarterKitRoot, StarterKitContentLayout, StarterKitLayout, StarterKitPageOptions, createStarterKitPage } from "./starter-kit.js";
|
|
4
|
-
import { AlfakitCopilot, AlfakitHeaderWidgetProps, AlfakitNotifications, AlfakitSearch, AlfakitTenantSwitcher } from "./widgets.js";
|
|
5
|
-
export { AlfakitCopilot, type AlfakitHeaderWidgetProps, type AlfakitNavigation, AlfakitNotifications, AlfakitSearch, AlfakitStarterKitRoot, AlfakitTenantSwitcher, AlfakitWidgets, type AlfakitWidgetsProps, StarterKitContentLayout, type StarterKitLayout, type StarterKitPageOptions, createStarterKitPage, useAlfakitNavigation };
|
|
4
|
+
import { AlfakitCopilot, AlfakitHeaderWidgetProps, AlfakitLanguageSwitcher, AlfakitNotifications, AlfakitSearch, AlfakitTenantSwitcher } from "./widgets.js";
|
|
5
|
+
export { AlfakitCopilot, type AlfakitHeaderWidgetProps, AlfakitLanguageSwitcher, type AlfakitNavigation, AlfakitNotifications, AlfakitSearch, AlfakitStarterKitRoot, AlfakitTenantSwitcher, AlfakitWidgets, type AlfakitWidgetsProps, StarterKitContentLayout, type StarterKitLayout, type StarterKitPageOptions, createStarterKitPage, useAlfakitNavigation };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AlfakitWidgets } from "./dashboard-widgets.js";
|
|
2
2
|
import { useAlfakitNavigation } from "./navigation.js";
|
|
3
3
|
import { AlfakitStarterKitRoot, StarterKitContentLayout, createStarterKitPage } from "./starter-kit.js";
|
|
4
|
-
import { AlfakitCopilot, AlfakitNotifications, AlfakitSearch, AlfakitTenantSwitcher } from "./widgets.js";
|
|
5
|
-
export { AlfakitCopilot, AlfakitNotifications, AlfakitSearch, AlfakitStarterKitRoot, AlfakitTenantSwitcher, AlfakitWidgets, StarterKitContentLayout, createStarterKitPage, useAlfakitNavigation };
|
|
4
|
+
import { AlfakitCopilot, AlfakitLanguageSwitcher, AlfakitNotifications, AlfakitSearch, AlfakitTenantSwitcher } from "./widgets.js";
|
|
5
|
+
export { AlfakitCopilot, AlfakitLanguageSwitcher, AlfakitNotifications, AlfakitSearch, AlfakitStarterKitRoot, AlfakitTenantSwitcher, AlfakitWidgets, StarterKitContentLayout, createStarterKitPage, useAlfakitNavigation };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"starter-kit.d.ts","names":[],"sources":["../../src/starter-kit/starter-kit.tsx"],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"starter-kit.d.ts","names":[],"sources":["../../src/starter-kit/starter-kit.tsx"],"mappings":";;;;;;YAsCY,mBAAmB;EAC7B,cAAc;EACd,UAAU;;iBAGK,8BAA8B,KAC7C,eAAe;;;;;;EAQf,SAAS;;;;;;EAMT,WAAW,eAAe;;;;;;;wBAQZ,0BAA0B,UAAU,mBAAmB,iCAAc,IAAA;;;;;;wBAuErE,wBACd,SACA;EAEA,UAAU;EACV,WAAW;oBACZ,IAAA;;;;;;;;;;;;;;wBAmEe,qBAAqB,UAAS;;EAYL,OAAA,OAAA,qCAAuB"}
|
|
@@ -6,6 +6,7 @@ import { createDefaultRegistry } from "../registry.js";
|
|
|
6
6
|
import { setToasterId, showToast } from "../components/notifications/flash-toasts.js";
|
|
7
7
|
import { Slot } from "../components/panel/slot.js";
|
|
8
8
|
import { AlfakitPage } from "../pages/page.js";
|
|
9
|
+
import { DebugPanelSlot } from "../components/panel/debug-panel-slot.js";
|
|
9
10
|
import { MAX_WIDTHS } from "../layouts/max-widths.js";
|
|
10
11
|
import { AuthLayout } from "../layouts/auth-layout.js";
|
|
11
12
|
import { AlfakitRoot } from "../create-alfakit.js";
|
|
@@ -95,9 +96,13 @@ function AlfakitStarterKitRoot({ options, children }) {
|
|
|
95
96
|
dir: panel?.localization?.direction ?? "ltr",
|
|
96
97
|
lang: panel?.localization?.tag,
|
|
97
98
|
className: "contents",
|
|
98
|
-
children: /* @__PURE__ */
|
|
99
|
+
children: /* @__PURE__ */ jsxs(AlfakitRoot, {
|
|
99
100
|
toasterId: STARTER_KIT_TOASTER_ID,
|
|
100
|
-
children
|
|
101
|
+
children: [children, /* @__PURE__ */ jsx("div", {
|
|
102
|
+
"data-slot": "starter-kit-debug-panel",
|
|
103
|
+
className: "fixed end-16 bottom-4 z-40",
|
|
104
|
+
children: /* @__PURE__ */ jsx(DebugPanelSlot, {})
|
|
105
|
+
})]
|
|
101
106
|
})
|
|
102
107
|
})
|
|
103
108
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"starter-kit.js","names":[],"sources":["../../src/starter-kit/starter-kit.tsx"],"sourcesContent":["import {\n ActionRunner,\n STARTER_KIT_TOASTER_ID,\n Translator,\n configureCharts,\n installStarterKitRuntime,\n registerRichEditorExtensions,\n resolveRequestErrorNotification,\n starterKitBreadcrumbsFromProps,\n syncStarterKitPage,\n usesStarterKitHostLayout,\n type AlfakitOptions,\n type AlfakitPageProps,\n type StarterKitBreadcrumb,\n} from '@alfakit/core'\nimport { usePage } from '@inertiajs/react'\nimport { useEffect, useState, type ComponentType, type ReactNode } from 'react'\nimport { setToasterId, showToast } from '../components/notifications/flash-toasts'\nimport { Slot } from '../components/panel/slot'\nimport {\n AlfakitProvider,\n useAlfakitProps,\n type AlfakitContextValue,\n type AnyComponent,\n} from '../context'\nimport { AlfakitRoot } from '../create-alfakit'\nimport type { AppLayoutProps } from '../layouts/app-layout'\nimport { AuthLayout } from '../layouts/auth-layout'\nimport { lazyPanelLayouts } from '../layouts/lazy-layouts'\nimport { MAX_WIDTHS } from '../layouts/max-widths'\nimport { discoverComponents } from '../lib/discovery'\nimport { preloadIcons } from '../lib/icons'\nimport { cn } from '../lib/utils'\nimport { AlfakitPage } from '../pages/page'\nimport { createDefaultRegistry } from '../registry'\n\n/** The host's layout, as the starter kits' `AppLayout` takes its props. */\nexport type StarterKitLayout = ComponentType<{\n breadcrumbs?: StarterKitBreadcrumb[]\n children: ReactNode\n}>\n\nexport interface StarterKitPageOptions extends Pick<\n AlfakitOptions<AnyComponent>,\n 'components' | 'pages' | 'chartFormatters' | 'chartPlugins' | 'richEditorExtensions'\n> {\n /**\n * The host layout Alfakit pages render in, usually the starter kit's `AppLayout`\n * (`@/layouts/app-layout`). It receives the page's breadcrumbs as `{ title, href }`.\n * `null` renders the pages without a host layout.\n */\n layout?: StarterKitLayout | null\n /**\n * Auto-registered custom components, as for `createAlfakit({ discover })`: pass\n * `import.meta.glob('../../alfakit/{fields,columns,entries,widgets,pages,components,blocks}/**\\/*.tsx')`\n * from `resources/js/pages/Alfakit/Page.tsx` and every file there registers under its name.\n */\n discover?: AlfakitOptions<AnyComponent>['discover']\n}\n\n/**\n * The content area of an Alfakit page inside the host layout: what `layout:app` renders in\n * starter kit mode instead of Alfakit's sidebar and top bar. Replace it with\n * `createStarterKitPage({ components: { 'layout:app': MyContent } })`.\n */\nexport function StarterKitContentLayout({ children, maxContentWidth }: AppLayoutProps) {\n const props = useAlfakitProps()\n // The host's pages fill the content area, so starter kit pages default to the full width.\n const width = maxContentWidth ?? props.alfakit.maxContentWidth ?? 'full'\n\n return (\n <div\n data-slot=\"content\"\n data-alfakit-embedded=\"\"\n className={cn(\n 'mx-auto flex w-full min-w-0 flex-1 flex-col gap-6 p-4 md:p-6',\n MAX_WIDTHS[width] ?? 'max-w-full',\n )}\n >\n <Slot name=\"content.start\" />\n {children}\n <Slot name=\"content.end\" />\n </div>\n )\n}\n\n// One context for the browser session (it survives navigations between host and Alfakit\n// pages); a server render builds one per request so concurrent renders never share a locale.\nlet browserContext: AlfakitContextValue | null = null\n\nfunction createStarterKitContext(options: StarterKitPageOptions): AlfakitContextValue {\n // The host's layout replaces the panel's. Auth pages (invitations, tenant registration)\n // keep the panel's card; the fullscreen layout loads on demand.\n // Auto-registered files sit between the built-ins and the explicit `components` / `pages`.\n const discovered = discoverComponents(options.discover)\n const registry = createDefaultRegistry()\n .registerMany(lazyPanelLayouts)\n .register('layout:auth', AuthLayout)\n .register('layout:app', StarterKitContentLayout)\n .registerMany(discovered.components)\n .registerMany(options.components ?? {})\n const translator = new Translator()\n\n return {\n registry,\n pages: { 'Alfakit/Page': AlfakitPage, ...discovered.pages, ...options.pages },\n translator,\n actions: new ActionRunner({\n endpoints: { action: '', modal: '' },\n // A failed action request is a toast, never a silent no-op.\n onError: (error) => {\n const notification = resolveRequestErrorNotification(\n error,\n null,\n (key, replacements, fallback) => translator.t(key, replacements, fallback),\n )\n\n if (notification) showToast(notification)\n },\n }),\n }\n}\n\nfunction starterKitContext(options: StarterKitPageOptions): AlfakitContextValue {\n if (typeof window === 'undefined') return createStarterKitContext(options)\n\n browserContext ??= createStarterKitContext(options)\n\n return browserContext\n}\n\n/**\n * The Inertia layout around every Alfakit page in starter kit mode, inside the host layout:\n * Alfakit's context, modals, toasts and the reading direction. It stays mounted while the\n * user moves between Alfakit pages.\n */\nexport function AlfakitStarterKitRoot({\n options,\n children,\n}: {\n options?: StarterKitPageOptions\n children?: ReactNode\n}) {\n const [context] = useState(() => starterKitContext(options ?? {}))\n const props = usePage<AlfakitPageProps>().props\n const panel = props.alfakit\n\n // Endpoints and error notifications follow the open page.\n if (panel) {\n context.actions.setEndpoints({\n action: panel.endpoints.action ?? '',\n modal: panel.endpoints.modal ?? '',\n })\n }\n\n useEffect(() => {\n syncStarterKitPage(props)\n }, [props])\n\n useEffect(() => {\n installStarterKitRuntime(\n (notification) => showToast(notification),\n (key, replacements, fallback) => context.translator.t(key, replacements, fallback),\n )\n setToasterId(STARTER_KIT_TOASTER_ID)\n\n return () => {\n // A host page is open: its errors and toasts are the host's again.\n syncStarterKitPage(null)\n setToasterId(undefined)\n }\n }, [context])\n\n return (\n <AlfakitProvider value={context}>\n {/* The reading direction and language of Alfakit's content only: the host layout around\n it (sidebar, header) and the app's own pages keep the document's. */}\n <div\n data-slot=\"starter-kit-root\"\n dir={panel?.localization?.direction ?? 'ltr'}\n lang={panel?.localization?.tag}\n className=\"contents\"\n >\n <AlfakitRoot toasterId={STARTER_KIT_TOASTER_ID}>{children}</AlfakitRoot>\n </div>\n </AlfakitProvider>\n )\n}\n\n/**\n * The page component for `Alfakit/Page` in a starter kit app: the host's\n * `resources/js/pages/Alfakit/Page.tsx` (written by `alfakit:install --starter-kit`) exports it,\n * so Inertia's page resolution, the root view's page preload and SSR all find it like any\n * other host page.\n *\n * ```tsx\n * import { createStarterKitPage } from '@alfakit/react'\n * import AppLayout from '@/layouts/app-layout'\n *\n * export default createStarterKitPage({ layout: AppLayout })\n * ```\n */\nexport function createStarterKitPage(options: StarterKitPageOptions = {}) {\n // Panel pages draw named icons: fetch `lucide-react/dynamic` with the page.\n preloadIcons()\n // `'js:name'` chart option callbacks, Chart.js plugins and rich editor extensions.\n configureCharts(options)\n registerRichEditorExtensions(options.richEditorExtensions ?? {})\n\n function AlfakitStarterKitPage() {\n return <AlfakitPage />\n }\n\n // A layout callback: the host layout (with the page's breadcrumbs), then Alfakit's root.\n AlfakitStarterKitPage.layout = (props: Record<string, unknown>) => [\n ...(options.layout && usesStarterKitHostLayout(props)\n ? [[options.layout, { breadcrumbs: starterKitBreadcrumbsFromProps(props) }] as const]\n : []),\n [AlfakitStarterKitRoot, { options }] as const,\n ]\n\n return AlfakitStarterKitPage\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAiEA,SAAgB,wBAAwB,EAAE,UAAU,mBAAmC;CACrF,MAAM,QAAQ,gBAAgB;CAE9B,MAAM,QAAQ,mBAAmB,MAAM,QAAQ,mBAAmB;CAElE,OACE,qBAAC,OAAD;EACE,aAAU;EACV,yBAAsB;EACtB,WAAW,GACT,gEACA,WAAW,UAAU,YACvB;EANF,UAAA;GAQE,oBAAC,MAAD,EAAM,MAAK,gBAAiB,CAAA;GAC3B;GACD,oBAAC,MAAD,EAAM,MAAK,cAAe,CAAA;EACvB;;AAET;AAIA,IAAI,iBAA6C;AAEjD,SAAS,wBAAwB,SAAqD;CAIpF,MAAM,aAAa,mBAAmB,QAAQ,QAAQ;CACtD,MAAM,WAAW,sBAAsB,CAAC,CACrC,aAAa,gBAAgB,CAAC,CAC9B,SAAS,eAAe,UAAU,CAAC,CACnC,SAAS,cAAc,uBAAuB,CAAC,CAC/C,aAAa,WAAW,UAAU,CAAC,CACnC,aAAa,QAAQ,cAAc,CAAC,CAAC;CACxC,MAAM,aAAa,IAAI,WAAW;CAElC,OAAO;EACL;EACA,OAAO;GAAE,gBAAgB;GAAa,GAAG,WAAW;GAAO,GAAG,QAAQ;EAAM;EAC5E;EACA,SAAS,IAAI,aAAa;GACxB,WAAW;IAAE,QAAQ;IAAI,OAAO;GAAG;GAEnC,UAAU,UAAU;IAClB,MAAM,eAAe,gCACnB,OACA,OACC,KAAK,cAAc,aAAa,WAAW,EAAE,KAAK,cAAc,QAAQ,CAC3E;IAEA,IAAI,cAAc,UAAU,YAAY;GAC1C;EACF,CAAC;CACH;AACF;AAEA,SAAS,kBAAkB,SAAqD;CAC9E,IAAI,OAAO,WAAW,aAAa,OAAO,wBAAwB,OAAO;CAEzE,mBAAmB,wBAAwB,OAAO;CAElD,OAAO;AACT;;;;;;AAOA,SAAgB,sBAAsB,EACpC,SACA,YAIC;CACD,MAAM,CAAC,WAAW,eAAe,kBAAkB,WAAW,CAAC,CAAC,CAAC;CACjE,MAAM,QAAQ,QAA0B,CAAC,CAAC;CAC1C,MAAM,QAAQ,MAAM;CAGpB,IAAI,OACF,QAAQ,QAAQ,aAAa;EAC3B,QAAQ,MAAM,UAAU,UAAU;EAClC,OAAO,MAAM,UAAU,SAAS;CAClC,CAAC;CAGH,gBAAgB;EACd,mBAAmB,KAAK;CAC1B,GAAG,CAAC,KAAK,CAAC;CAEV,gBAAgB;EACd,0BACG,iBAAiB,UAAU,YAAY,IACvC,KAAK,cAAc,aAAa,QAAQ,WAAW,EAAE,KAAK,cAAc,QAAQ,CACnF;EACA,aAAa,sBAAsB;EAEnC,aAAa;GAEX,mBAAmB,IAAI;GACvB,aAAa,KAAA,CAAS;EACxB;CACF,GAAG,CAAC,OAAO,CAAC;CAEZ,OACE,oBAAC,iBAAD;EAAiB,OAAO;EAGtB,UAAA,oBAAC,OAAD;GACE,aAAU;GACV,KAAK,OAAO,cAAc,aAAa;GACvC,MAAM,OAAO,cAAc;GAC3B,WAAU;GAEV,UAAA,oBAAC,aAAD;IAAa,WAAW;IAAyB;GAAsB,CAAA;EACpE,CAAA;CACU,CAAA;AAErB;;;;;;;;;;;;;;AAeA,SAAgB,qBAAqB,UAAiC,CAAC,GAAG;CAExE,aAAa;CAEb,gBAAgB,OAAO;CACvB,6BAA6B,QAAQ,wBAAwB,CAAC,CAAC;CAE/D,SAAS,wBAAwB;EAC/B,OAAO,oBAAC,aAAD,CAAc,CAAA;CACvB;CAGA,sBAAsB,UAAU,UAAmC,CACjE,GAAI,QAAQ,UAAU,yBAAyB,KAAK,IAChD,CAAC,CAAC,QAAQ,QAAQ,EAAE,aAAa,+BAA+B,KAAK,EAAE,CAAC,CAAU,IAClF,CAAC,GACL,CAAC,uBAAuB,EAAE,QAAQ,CAAC,CACrC;CAEA,OAAO;AACT"}
|
|
1
|
+
{"version":3,"file":"starter-kit.js","names":[],"sources":["../../src/starter-kit/starter-kit.tsx"],"sourcesContent":["import {\n ActionRunner,\n STARTER_KIT_TOASTER_ID,\n Translator,\n configureCharts,\n installStarterKitRuntime,\n registerRichEditorExtensions,\n resolveRequestErrorNotification,\n starterKitBreadcrumbsFromProps,\n syncStarterKitPage,\n usesStarterKitHostLayout,\n type AlfakitOptions,\n type AlfakitPageProps,\n type StarterKitBreadcrumb,\n} from '@alfakit/core'\nimport { usePage } from '@inertiajs/react'\nimport { useEffect, useState, type ComponentType, type ReactNode } from 'react'\nimport { setToasterId, showToast } from '../components/notifications/flash-toasts'\nimport { DebugPanelSlot } from '../components/panel/debug-panel-slot'\nimport { Slot } from '../components/panel/slot'\nimport {\n AlfakitProvider,\n useAlfakitProps,\n type AlfakitContextValue,\n type AnyComponent,\n} from '../context'\nimport { AlfakitRoot } from '../create-alfakit'\nimport type { AppLayoutProps } from '../layouts/app-layout'\nimport { AuthLayout } from '../layouts/auth-layout'\nimport { lazyPanelLayouts } from '../layouts/lazy-layouts'\nimport { MAX_WIDTHS } from '../layouts/max-widths'\nimport { discoverComponents } from '../lib/discovery'\nimport { preloadIcons } from '../lib/icons'\nimport { cn } from '../lib/utils'\nimport { AlfakitPage } from '../pages/page'\nimport { createDefaultRegistry } from '../registry'\n\n/** The host's layout, as the starter kits' `AppLayout` takes its props. */\nexport type StarterKitLayout = ComponentType<{\n breadcrumbs?: StarterKitBreadcrumb[]\n children: ReactNode\n}>\n\nexport interface StarterKitPageOptions extends Pick<\n AlfakitOptions<AnyComponent>,\n 'components' | 'pages' | 'chartFormatters' | 'chartPlugins' | 'richEditorExtensions'\n> {\n /**\n * The host layout Alfakit pages render in, usually the starter kit's `AppLayout`\n * (`@/layouts/app-layout`). It receives the page's breadcrumbs as `{ title, href }`.\n * `null` renders the pages without a host layout.\n */\n layout?: StarterKitLayout | null\n /**\n * Auto-registered custom components, as for `createAlfakit({ discover })`: pass\n * `import.meta.glob('../../alfakit/{fields,columns,entries,widgets,pages,components,blocks}/**\\/*.tsx')`\n * from `resources/js/pages/Alfakit/Page.tsx` and every file there registers under its name.\n */\n discover?: AlfakitOptions<AnyComponent>['discover']\n}\n\n/**\n * The content area of an Alfakit page inside the host layout: what `layout:app` renders in\n * starter kit mode instead of Alfakit's sidebar and top bar. Replace it with\n * `createStarterKitPage({ components: { 'layout:app': MyContent } })`.\n */\nexport function StarterKitContentLayout({ children, maxContentWidth }: AppLayoutProps) {\n const props = useAlfakitProps()\n // The host's pages fill the content area, so starter kit pages default to the full width.\n const width = maxContentWidth ?? props.alfakit.maxContentWidth ?? 'full'\n\n return (\n <div\n data-slot=\"content\"\n data-alfakit-embedded=\"\"\n className={cn(\n 'mx-auto flex w-full min-w-0 flex-1 flex-col gap-6 p-4 md:p-6',\n MAX_WIDTHS[width] ?? 'max-w-full',\n )}\n >\n <Slot name=\"content.start\" />\n {children}\n <Slot name=\"content.end\" />\n </div>\n )\n}\n\n// One context for the browser session (it survives navigations between host and Alfakit\n// pages); a server render builds one per request so concurrent renders never share a locale.\nlet browserContext: AlfakitContextValue | null = null\n\nfunction createStarterKitContext(options: StarterKitPageOptions): AlfakitContextValue {\n // The host's layout replaces the panel's. Auth pages (invitations, tenant registration)\n // keep the panel's card; the fullscreen layout loads on demand.\n // Auto-registered files sit between the built-ins and the explicit `components` / `pages`.\n const discovered = discoverComponents(options.discover)\n const registry = createDefaultRegistry()\n .registerMany(lazyPanelLayouts)\n .register('layout:auth', AuthLayout)\n .register('layout:app', StarterKitContentLayout)\n .registerMany(discovered.components)\n .registerMany(options.components ?? {})\n const translator = new Translator()\n\n return {\n registry,\n pages: { 'Alfakit/Page': AlfakitPage, ...discovered.pages, ...options.pages },\n translator,\n actions: new ActionRunner({\n endpoints: { action: '', modal: '' },\n // A failed action request is a toast, never a silent no-op.\n onError: (error) => {\n const notification = resolveRequestErrorNotification(\n error,\n null,\n (key, replacements, fallback) => translator.t(key, replacements, fallback),\n )\n\n if (notification) showToast(notification)\n },\n }),\n }\n}\n\nfunction starterKitContext(options: StarterKitPageOptions): AlfakitContextValue {\n if (typeof window === 'undefined') return createStarterKitContext(options)\n\n browserContext ??= createStarterKitContext(options)\n\n return browserContext\n}\n\n/**\n * The Inertia layout around every Alfakit page in starter kit mode, inside the host layout:\n * Alfakit's context, modals, toasts and the reading direction. It stays mounted while the\n * user moves between Alfakit pages.\n */\nexport function AlfakitStarterKitRoot({\n options,\n children,\n}: {\n options?: StarterKitPageOptions\n children?: ReactNode\n}) {\n const [context] = useState(() => starterKitContext(options ?? {}))\n const props = usePage<AlfakitPageProps>().props\n const panel = props.alfakit\n\n // Endpoints and error notifications follow the open page.\n if (panel) {\n context.actions.setEndpoints({\n action: panel.endpoints.action ?? '',\n modal: panel.endpoints.modal ?? '',\n })\n }\n\n useEffect(() => {\n syncStarterKitPage(props)\n }, [props])\n\n useEffect(() => {\n installStarterKitRuntime(\n (notification) => showToast(notification),\n (key, replacements, fallback) => context.translator.t(key, replacements, fallback),\n )\n setToasterId(STARTER_KIT_TOASTER_ID)\n\n return () => {\n // A host page is open: its errors and toasts are the host's again.\n syncStarterKitPage(null)\n setToasterId(undefined)\n }\n }, [context])\n\n return (\n <AlfakitProvider value={context}>\n {/* The reading direction and language of Alfakit's content only: the host layout around\n it (sidebar, header) and the app's own pages keep the document's. */}\n <div\n data-slot=\"starter-kit-root\"\n dir={panel?.localization?.direction ?? 'ltr'}\n lang={panel?.localization?.tag}\n className=\"contents\"\n >\n <AlfakitRoot toasterId={STARTER_KIT_TOASTER_ID}>\n {children}\n {/* The debug panel's button lives in AlfaKit's top bar, which a starter kit doesn't\n render: float it in the corner instead (nothing without `alfakitDebug`). */}\n <div data-slot=\"starter-kit-debug-panel\" className=\"fixed end-16 bottom-4 z-40\">\n <DebugPanelSlot />\n </div>\n </AlfakitRoot>\n </div>\n </AlfakitProvider>\n )\n}\n\n/**\n * The page component for `Alfakit/Page` in a starter kit app: the host's\n * `resources/js/pages/Alfakit/Page.tsx` (written by `alfakit:install --starter-kit`) exports it,\n * so Inertia's page resolution, the root view's page preload and SSR all find it like any\n * other host page.\n *\n * ```tsx\n * import { createStarterKitPage } from '@alfakit/react'\n * import AppLayout from '@/layouts/app-layout'\n *\n * export default createStarterKitPage({ layout: AppLayout })\n * ```\n */\nexport function createStarterKitPage(options: StarterKitPageOptions = {}) {\n // Panel pages draw named icons: fetch `lucide-react/dynamic` with the page.\n preloadIcons()\n // `'js:name'` chart option callbacks, Chart.js plugins and rich editor extensions.\n configureCharts(options)\n registerRichEditorExtensions(options.richEditorExtensions ?? {})\n\n function AlfakitStarterKitPage() {\n return <AlfakitPage />\n }\n\n // A layout callback: the host layout (with the page's breadcrumbs), then Alfakit's root.\n AlfakitStarterKitPage.layout = (props: Record<string, unknown>) => [\n ...(options.layout && usesStarterKitHostLayout(props)\n ? [[options.layout, { breadcrumbs: starterKitBreadcrumbsFromProps(props) }] as const]\n : []),\n [AlfakitStarterKitRoot, { options }] as const,\n ]\n\n return AlfakitStarterKitPage\n}\n"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AlfakitProvider, StandaloneProvider, useT } from "../context.js";
|
|
1
|
+
import { AlfakitProvider, StandaloneProvider, useLocalization, useT } from "../context.js";
|
|
2
2
|
import { Icon } from "../lib/icons.js";
|
|
3
3
|
import { DropdownMenu as DropdownMenu$1, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger } from "../components/ui/dropdown-menu.js";
|
|
4
4
|
import { TooltipProvider } from "../components/ui/tooltip.js";
|
|
@@ -9,18 +9,19 @@ import { NotificationsMenu } from "../components/notifications/notifications-men
|
|
|
9
9
|
import { RealtimeNotifications } from "../components/notifications/realtime-notifications.js";
|
|
10
10
|
import { GlobalSearch } from "../components/panel/global-search.js";
|
|
11
11
|
import { TenantMenu } from "../components/panel/tenant-menu.js";
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
12
|
+
import { LocaleOptions } from "../components/panel/locale-switcher.js";
|
|
13
|
+
import { CopilotTrigger, LanguageSwitcherTrigger, NotificationsTrigger, SearchTrigger, TenantSwitcherTrigger, languageTriggerClasses } from "./widgets-triggers.js";
|
|
14
|
+
import { ActionRunner, ComponentRegistry, Translator, initials, isAlfakitPage, loadStarterKitPanel, loadedStarterKitPanel, openRequestedStarterKitSearch, showsLanguageSwitcher, starterKitCopilot, starterKitPanelLocale, starterKitWidgetsPage, starterKitWidgetsPanel, takeRequestedStarterKitCopilot, takeRequestedStarterKitLanguages, tenantNameText } from "@alfakit/core";
|
|
14
15
|
import { router, usePage } from "@inertiajs/react";
|
|
15
|
-
import { useEffect, useMemo, useState } from "react";
|
|
16
|
+
import { useEffect, useMemo, useRef, useState } from "react";
|
|
16
17
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
17
18
|
import { Direction } from "radix-ui";
|
|
18
|
-
import { ChevronsUpDownIcon, PlusIcon } from "lucide-react";
|
|
19
|
+
import { ChevronsUpDownIcon, LanguagesIcon, PlusIcon } from "lucide-react";
|
|
19
20
|
//#region src/starter-kit/widgets-loaded.tsx
|
|
20
21
|
/**
|
|
21
22
|
* The loaded header components of starter kit mode: the panel's own search palette,
|
|
22
|
-
* notifications menu and
|
|
23
|
-
* from `widgets.endpoint`. This module only loads in the browser.
|
|
23
|
+
* notifications menu, tenant menu and language menu, rendered outside Alfakit pages with
|
|
24
|
+
* the panel data from `widgets.endpoint`. This module only loads in the browser.
|
|
24
25
|
*/
|
|
25
26
|
let widgetsContext = null;
|
|
26
27
|
function useWidgetsContext(panel) {
|
|
@@ -37,18 +38,24 @@ function useWidgetsContext(panel) {
|
|
|
37
38
|
widgetsContext.translator.setLocale(panel.localization?.tag ?? "en");
|
|
38
39
|
return widgetsContext;
|
|
39
40
|
}
|
|
40
|
-
/**
|
|
41
|
+
/**
|
|
42
|
+
* The panel the components render with, once its data has loaded (null until then). It is
|
|
43
|
+
* loaded per endpoint (a tenant switch) and language (a language switch), so the components
|
|
44
|
+
* follow a switch instead of keeping the old language's strings.
|
|
45
|
+
*/
|
|
41
46
|
function useWidgetsPanel(source) {
|
|
42
47
|
const endpoint = source.widgets.endpoint;
|
|
43
|
-
const
|
|
44
|
-
const
|
|
48
|
+
const locale = starterKitPanelLocale(source);
|
|
49
|
+
const [loaded, setLoaded] = useState(() => loadedStarterKitPanel(endpoint, locale));
|
|
50
|
+
const current = loaded && (locale === void 0 || loaded.localization?.code === locale) ? loaded : null;
|
|
51
|
+
const base = loadedStarterKitPanel(endpoint, locale) ?? current;
|
|
45
52
|
useEffect(() => {
|
|
46
53
|
let active = true;
|
|
47
|
-
loadStarterKitPanel(endpoint).then((panel) => active && setLoaded(panel), () => {});
|
|
54
|
+
loadStarterKitPanel(endpoint, locale).then((panel) => active && setLoaded(panel), () => {});
|
|
48
55
|
return () => {
|
|
49
56
|
active = false;
|
|
50
57
|
};
|
|
51
|
-
}, [endpoint]);
|
|
58
|
+
}, [endpoint, locale]);
|
|
52
59
|
const { navigation, widgets } = source;
|
|
53
60
|
return useMemo(() => base ? starterKitWidgetsPanel(base, {
|
|
54
61
|
navigation,
|
|
@@ -125,6 +132,60 @@ function LoadedCopilot({ source }) {
|
|
|
125
132
|
})
|
|
126
133
|
});
|
|
127
134
|
}
|
|
135
|
+
/**
|
|
136
|
+
* The panel's language menu (its languages in their own names, `LocaleOptions`): picking
|
|
137
|
+
* one posts to the panel's locale endpoint and reloads the page in it. Nothing without a
|
|
138
|
+
* language switcher with two or more languages.
|
|
139
|
+
*/
|
|
140
|
+
function LoadedLanguageSwitcher({ source }) {
|
|
141
|
+
const panel = useWidgetsPanel(source);
|
|
142
|
+
if (!panel) return /* @__PURE__ */ jsx(LanguageSwitcherTrigger, { source });
|
|
143
|
+
if (!showsLanguageSwitcher(panel.localization, "auth")) return null;
|
|
144
|
+
return /* @__PURE__ */ jsx(WidgetShell, {
|
|
145
|
+
panel,
|
|
146
|
+
children: /* @__PURE__ */ jsx(LanguageMenu, {})
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
function LanguageMenu() {
|
|
150
|
+
const t = useT();
|
|
151
|
+
const localization = useLocalization();
|
|
152
|
+
const [open, setOpen] = useState(false);
|
|
153
|
+
const requested = useRef(null);
|
|
154
|
+
useEffect(() => {
|
|
155
|
+
requested.current ??= takeRequestedStarterKitLanguages();
|
|
156
|
+
if (!requested.current) return;
|
|
157
|
+
const frame = requestAnimationFrame(() => setOpen(true));
|
|
158
|
+
return () => cancelAnimationFrame(frame);
|
|
159
|
+
}, []);
|
|
160
|
+
const label = t("change_language", {}, "Change language");
|
|
161
|
+
return /* @__PURE__ */ jsxs(DropdownMenu$1, {
|
|
162
|
+
open,
|
|
163
|
+
onOpenChange: setOpen,
|
|
164
|
+
children: [/* @__PURE__ */ jsx(DropdownMenuTrigger, {
|
|
165
|
+
asChild: true,
|
|
166
|
+
children: /* @__PURE__ */ jsxs("button", {
|
|
167
|
+
type: "button",
|
|
168
|
+
"data-slot": "language-switcher-trigger",
|
|
169
|
+
"aria-label": label,
|
|
170
|
+
title: label,
|
|
171
|
+
className: languageTriggerClasses,
|
|
172
|
+
children: [/* @__PURE__ */ jsx(LanguagesIcon, {
|
|
173
|
+
className: "size-4",
|
|
174
|
+
"aria-hidden": "true"
|
|
175
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
176
|
+
lang: localization.tag,
|
|
177
|
+
dir: localization.direction,
|
|
178
|
+
className: "hidden sm:inline",
|
|
179
|
+
children: localization.label
|
|
180
|
+
})]
|
|
181
|
+
})
|
|
182
|
+
}), /* @__PURE__ */ jsx(DropdownMenuContent, {
|
|
183
|
+
align: "end",
|
|
184
|
+
className: "min-w-40",
|
|
185
|
+
children: /* @__PURE__ */ jsx(LocaleOptions, {})
|
|
186
|
+
})]
|
|
187
|
+
});
|
|
188
|
+
}
|
|
128
189
|
/** The user's tenants on a page outside the panel (no current tenant). */
|
|
129
190
|
function TenantChooser({ panel }) {
|
|
130
191
|
const t = useT();
|
|
@@ -183,6 +244,6 @@ function TenantChooser({ panel }) {
|
|
|
183
244
|
})] });
|
|
184
245
|
}
|
|
185
246
|
//#endregion
|
|
186
|
-
export { LoadedCopilot, LoadedNotifications, LoadedSearch, LoadedTenantSwitcher };
|
|
247
|
+
export { LoadedCopilot, LoadedLanguageSwitcher, LoadedNotifications, LoadedSearch, LoadedTenantSwitcher };
|
|
187
248
|
|
|
188
249
|
//# sourceMappingURL=widgets-loaded.js.map
|