@adea-ai/ui 0.84.0 → 0.85.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/README.md +79 -0
  2. package/dist/NOTICE +26 -0
  3. package/dist/components/composites/catalog-browser/catalog-browser-group.d.ts +20 -0
  4. package/dist/components/composites/catalog-browser/catalog-browser-group.d.ts.map +1 -0
  5. package/dist/components/composites/catalog-browser/catalog-browser-group.js +195 -0
  6. package/dist/components/composites/catalog-browser/catalog-browser-group.js.map +1 -0
  7. package/dist/components/composites/catalog-browser/catalog-browser.d.ts +3 -0
  8. package/dist/components/composites/catalog-browser/catalog-browser.d.ts.map +1 -0
  9. package/dist/components/composites/catalog-browser/catalog-browser.js +378 -0
  10. package/dist/components/composites/catalog-browser/catalog-browser.js.map +1 -0
  11. package/dist/components/composites/catalog-browser/catalog-detail.d.ts +21 -0
  12. package/dist/components/composites/catalog-browser/catalog-detail.d.ts.map +1 -0
  13. package/dist/components/composites/catalog-browser/catalog-detail.js +92 -0
  14. package/dist/components/composites/catalog-browser/catalog-detail.js.map +1 -0
  15. package/dist/components/composites/catalog-browser/catalog-types.d.ts +78 -0
  16. package/dist/components/composites/catalog-browser/catalog-types.d.ts.map +1 -0
  17. package/dist/components/composites/catalog-browser/index.d.ts +4 -0
  18. package/dist/components/composites/catalog-browser/index.d.ts.map +1 -0
  19. package/dist/components/composites/catalog-browser/index.js +3 -0
  20. package/dist/index.d.ts +1 -0
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/index.js +4 -2
  23. package/dist/r/catalog-browser.json +47 -0
  24. package/dist/r/registry.json +47 -0
  25. package/dist/r/src/components/composites/catalog-browser/catalog-browser-group.tsx +148 -0
  26. package/dist/r/src/components/composites/catalog-browser/catalog-browser.tsx +258 -0
  27. package/dist/r/src/components/composites/catalog-browser/catalog-detail.tsx +64 -0
  28. package/dist/r/src/components/composites/catalog-browser/catalog-types.ts +83 -0
  29. package/dist/r/src/components/composites/catalog-browser/index.ts +10 -0
  30. package/package.json +1 -1
  31. package/registry.json +47 -0
  32. package/src/components/composites/catalog-browser/catalog-browser-group.tsx +148 -0
  33. package/src/components/composites/catalog-browser/catalog-browser.tsx +258 -0
  34. package/src/components/composites/catalog-browser/catalog-detail.tsx +64 -0
  35. package/src/components/composites/catalog-browser/catalog-types.ts +83 -0
  36. package/src/components/composites/catalog-browser/index.ts +10 -0
  37. package/src/index.ts +1 -0
package/dist/index.d.ts CHANGED
@@ -86,6 +86,7 @@ export * from './components/conversation';
86
86
  export * from './components/theme';
87
87
  export * from './components/composites/account-menu';
88
88
  export * from './components/composites/action-button';
89
+ export * from './components/composites/catalog-browser';
89
90
  export * from './components/composites/list-row';
90
91
  export * from './components/composites/settings';
91
92
  export * from './components/composites/stat';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -91,6 +91,9 @@ import { AppearancePanel } from "./components/theme/appearance-panel.js";
91
91
  import { ThemeToggle } from "./components/theme/theme-toggle.js";
92
92
  import { AccountMenu } from "./components/composites/account-menu/account-menu.js";
93
93
  import { ActionButton } from "./components/composites/action-button/action-button.js";
94
+ import { keyedRows } from "./lib/keyed-rows.js";
95
+ import { CatalogBrowser } from "./components/composites/catalog-browser/catalog-browser.js";
96
+ import { CatalogDetail, CatalogDetailSection } from "./components/composites/catalog-browser/catalog-detail.js";
94
97
  import { ListGroup, ListRow } from "./components/composites/list-row/list-row.js";
95
98
  import { SettingsField, SettingsPage, SettingsRow, SettingsSection } from "./components/composites/settings/settings.js";
96
99
  import { PropertyList, PropertyRow, PropertyTerm, PropertyValue, Stat, StatGroup } from "./components/composites/stat/stat.js";
@@ -99,5 +102,4 @@ import { AppearanceEditor, AppearancePopover } from "./components/composites/app
99
102
  import { formatBytes, formatReleaseDate, plainTextFromMarkdown } from "./lib/version-notes.js";
100
103
  import { UpdateDialog } from "./components/composites/update-dialog/update-dialog.js";
101
104
  import { WorkspaceMark } from "./components/composites/workspace-mark/workspace-mark.js";
102
- import { keyedRows } from "./lib/keyed-rows.js";
103
- export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, AccountMenu, ActionButton, Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, AppShell, AppShellBody, AppShellContent, AppShellMain, AppearanceEditor, AppearancePanel, AppearancePopover, AspectRatio, AttachmentCard, Avatar, AvatarFallback, AvatarImage, Badge, Board, BoardCardBody, BoardCardTitle, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbSeparator, BusySendButton, Button, ButtonGroup, ButtonGroupSeparator, ButtonGroupText, CalendarSurface, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, ChatComposer, Checkbox, CheckboxDescription, CheckboxLabel, CodeBlock, Collapsible, CollapsibleContent, CollapsibleTrigger, Combobox, ComboboxClear, ComboboxContent, ComboboxControl, ComboboxInput, ComboboxItem, ComboboxSection, ComboboxTrigger, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandLoading, CommandSeparator, CommandShortcut, ComposerAttachmentButton, ComposerHint, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, ConversationAvatar, ConversationSurface, DatePicker, DetailPanel, DetailPanelBody, DetailPanelField, DetailPanelHeader, DetailPanelSection, Dialog, DialogClose, DialogCloseButton, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DiffBlock, DiffSummary, Drawer, DrawerBody, DrawerCloseButton, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle, EntityIcon, Field, FieldDescription, FieldError, FieldInput, FieldLabel, FieldLegend, FieldSeparator, FieldSet, FieldTextArea, HoverCard, HoverCardContent, HoverCardTrigger, InlineCode, Input, InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, InputOtp, InputOtpCaret, Item, ItemDescription, ItemEmpty, ItemGroup, ItemGroupEntry, ItemTitle, Kbd, KbdGroup, Label, ListGroup, ListRow, MAX_LAYOUT_DEPTH, MAX_LAYOUT_LEAVES, MAX_SPLIT_RATIO, MIN_SPLIT_RATIO, Menubar, MenubarCheckboxItem, MenubarContent, MenubarGroup, MenubarItem, MenubarLabel, MenubarMenu, MenubarRadioGroup, MenubarRadioItem, MenubarSeparator, MenubarSub, MenubarSubContent, MenubarSubTrigger, MenubarTrigger, MessageBody, MessageComposer, MessageDayDivider, MessageGroup, MessageRow, ModalDialog, Motion, NativeSelect, NavigationMenu, NavigationMenuContent, NavigationMenuGroup, NavigationMenuGroupLabel, NavigationMenuItem, NavigationMenuMenu, NavigationMenuSeparator, NavigationMenuTrigger, NavigationMenuViewport, OrbitItem, OrbitLayout, PASTE_THRESHOLD_CHARS, PASTE_THRESHOLD_LINES, PASTE_TOKEN_REGEX, Page, PageHeader, PageHeaderActions, PageHeaderContent, PageHeaderDescription, PageHeaderTitle, PageSection, Pagination, PaginationEllipsis, PaginationItem, PaginationNext, PaginationPrevious, PalettePreview, Panel, PanelActions, PanelBody, PanelCard, PanelDescription, PanelFooter, PanelHeader, PanelPlaceholder, PanelTitle, PanelToolbar, Popover, PopoverAnchor, PopoverCloseButton, PopoverContent, PopoverDescription, PopoverTitle, PopoverTrigger, Presence, Progress, PropertyList, PropertyRow, PropertyTerm, PropertyValue, RadioGroup, RadioGroupItem, ResizableHandle, ResizablePanel, ResizablePanelGroup, ScrollArea, Select, SelectChevronsUpDown, SelectContent, SelectItem, SelectLabel, SelectSection, SelectTrigger, SelectValue, Separator, SettingsField, SettingsPage, SettingsRow, SettingsSection, Sheet, SheetBody, SheetCloseButton, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger, SideRail, SideRailButton, SideRailContent, SideRailFooter, SideRailHeader, SideRailItem, SideRailSection, SidebarNav, SidebarNavButton, SidebarNavContent, SidebarNavFooter, SidebarNavHeader, SidebarNavItem, SidebarNavResizeHandle, SidebarNavSection, SidebarNavTitle, Skeleton, Slider, Spinner, SplitLayout, Stat, StatGroup, StatusBar, StatusBarItem, StatusBarSpacer, StatusChip, StatusList, Switch, SwitchDescription, SwitchLabel, TALL_CODE_BLOCK_PX, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableNumericCell, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, ThemeMiniature, ThemeMiniatureSplit, ThemePicker, ThemePreview, ThemeProvider, ThemeSwatch, ThemeToggle, ThreadPanel, Toaster, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, TopBar, TopBarBreadcrumb, TopBarPill, TopBarSearch, TopBarSection, TopBarTitle, TranscriptComposition, UpdateDialog, VirtualWindow, WorkspaceMark, accentPresets, alertVariants, allTokens, badgeVariants, boardCardTitleVariants, builtinThemes, buttonVariants, closePane, cn, colorTokens, computeLayoutFrames, contrastRatio, controlInteractive, controlSize, controlSizeIcon, controlSizes, countLeaves, countLines, createLayoutState, cva, defaultDarkThemeId, defaultLightThemeId, defaultThemeSelection, densityTokens, designTokens, diffLineVariants, diffStats, diffTargetPath, elevationTokens, entityIconVariants, expandAll, findTokenRanges, focusPane, fontOptions, formatBytes, formatReleaseDate, formatToken, initialsFrom, inlineScriptLiteral, isPasteBlock, itemVariants, keyedRows, layoutDepth, listLeaves, monogram, motionTokens, movePane, neighborLeaf, nextSeq, normalizeLayout, parseDiff, plainTextFromMarkdown, pruneBlocks, radiusTokens, recollapsePastes, remapCarriedBlocks, resizeSplit, resolvedDensity, sheetVariants, shouldCollapse, sidebarNavItemClass, sidebarNavItemStateClass, splitPane, statusDotVariants, stripTrailingBlankLines, surfaceInteractive, swapPanes, themeById, themeCssVariables, themeFamilies, themeScript, themesForAppearance, toast, toaster, toggleVariants, tokenRangeAt, transcriptDisclosureKey, typographyTokens, undoClosePane, undocumentedTokenAliases, useSideRail, useTheme, validateTheme, validateThemeRegistry, zIndexTokens };
105
+ export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, AccountMenu, ActionButton, Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, AppShell, AppShellBody, AppShellContent, AppShellMain, AppearanceEditor, AppearancePanel, AppearancePopover, AspectRatio, AttachmentCard, Avatar, AvatarFallback, AvatarImage, Badge, Board, BoardCardBody, BoardCardTitle, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbSeparator, BusySendButton, Button, ButtonGroup, ButtonGroupSeparator, ButtonGroupText, CalendarSurface, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, CatalogBrowser, CatalogDetail, CatalogDetailSection, ChatComposer, Checkbox, CheckboxDescription, CheckboxLabel, CodeBlock, Collapsible, CollapsibleContent, CollapsibleTrigger, Combobox, ComboboxClear, ComboboxContent, ComboboxControl, ComboboxInput, ComboboxItem, ComboboxSection, ComboboxTrigger, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandLoading, CommandSeparator, CommandShortcut, ComposerAttachmentButton, ComposerHint, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, ConversationAvatar, ConversationSurface, DatePicker, DetailPanel, DetailPanelBody, DetailPanelField, DetailPanelHeader, DetailPanelSection, Dialog, DialogClose, DialogCloseButton, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DiffBlock, DiffSummary, Drawer, DrawerBody, DrawerCloseButton, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle, EntityIcon, Field, FieldDescription, FieldError, FieldInput, FieldLabel, FieldLegend, FieldSeparator, FieldSet, FieldTextArea, HoverCard, HoverCardContent, HoverCardTrigger, InlineCode, Input, InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, InputOtp, InputOtpCaret, Item, ItemDescription, ItemEmpty, ItemGroup, ItemGroupEntry, ItemTitle, Kbd, KbdGroup, Label, ListGroup, ListRow, MAX_LAYOUT_DEPTH, MAX_LAYOUT_LEAVES, MAX_SPLIT_RATIO, MIN_SPLIT_RATIO, Menubar, MenubarCheckboxItem, MenubarContent, MenubarGroup, MenubarItem, MenubarLabel, MenubarMenu, MenubarRadioGroup, MenubarRadioItem, MenubarSeparator, MenubarSub, MenubarSubContent, MenubarSubTrigger, MenubarTrigger, MessageBody, MessageComposer, MessageDayDivider, MessageGroup, MessageRow, ModalDialog, Motion, NativeSelect, NavigationMenu, NavigationMenuContent, NavigationMenuGroup, NavigationMenuGroupLabel, NavigationMenuItem, NavigationMenuMenu, NavigationMenuSeparator, NavigationMenuTrigger, NavigationMenuViewport, OrbitItem, OrbitLayout, PASTE_THRESHOLD_CHARS, PASTE_THRESHOLD_LINES, PASTE_TOKEN_REGEX, Page, PageHeader, PageHeaderActions, PageHeaderContent, PageHeaderDescription, PageHeaderTitle, PageSection, Pagination, PaginationEllipsis, PaginationItem, PaginationNext, PaginationPrevious, PalettePreview, Panel, PanelActions, PanelBody, PanelCard, PanelDescription, PanelFooter, PanelHeader, PanelPlaceholder, PanelTitle, PanelToolbar, Popover, PopoverAnchor, PopoverCloseButton, PopoverContent, PopoverDescription, PopoverTitle, PopoverTrigger, Presence, Progress, PropertyList, PropertyRow, PropertyTerm, PropertyValue, RadioGroup, RadioGroupItem, ResizableHandle, ResizablePanel, ResizablePanelGroup, ScrollArea, Select, SelectChevronsUpDown, SelectContent, SelectItem, SelectLabel, SelectSection, SelectTrigger, SelectValue, Separator, SettingsField, SettingsPage, SettingsRow, SettingsSection, Sheet, SheetBody, SheetCloseButton, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger, SideRail, SideRailButton, SideRailContent, SideRailFooter, SideRailHeader, SideRailItem, SideRailSection, SidebarNav, SidebarNavButton, SidebarNavContent, SidebarNavFooter, SidebarNavHeader, SidebarNavItem, SidebarNavResizeHandle, SidebarNavSection, SidebarNavTitle, Skeleton, Slider, Spinner, SplitLayout, Stat, StatGroup, StatusBar, StatusBarItem, StatusBarSpacer, StatusChip, StatusList, Switch, SwitchDescription, SwitchLabel, TALL_CODE_BLOCK_PX, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableNumericCell, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, ThemeMiniature, ThemeMiniatureSplit, ThemePicker, ThemePreview, ThemeProvider, ThemeSwatch, ThemeToggle, ThreadPanel, Toaster, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, TopBar, TopBarBreadcrumb, TopBarPill, TopBarSearch, TopBarSection, TopBarTitle, TranscriptComposition, UpdateDialog, VirtualWindow, WorkspaceMark, accentPresets, alertVariants, allTokens, badgeVariants, boardCardTitleVariants, builtinThemes, buttonVariants, closePane, cn, colorTokens, computeLayoutFrames, contrastRatio, controlInteractive, controlSize, controlSizeIcon, controlSizes, countLeaves, countLines, createLayoutState, cva, defaultDarkThemeId, defaultLightThemeId, defaultThemeSelection, densityTokens, designTokens, diffLineVariants, diffStats, diffTargetPath, elevationTokens, entityIconVariants, expandAll, findTokenRanges, focusPane, fontOptions, formatBytes, formatReleaseDate, formatToken, initialsFrom, inlineScriptLiteral, isPasteBlock, itemVariants, keyedRows, layoutDepth, listLeaves, monogram, motionTokens, movePane, neighborLeaf, nextSeq, normalizeLayout, parseDiff, plainTextFromMarkdown, pruneBlocks, radiusTokens, recollapsePastes, remapCarriedBlocks, resizeSplit, resolvedDensity, sheetVariants, shouldCollapse, sidebarNavItemClass, sidebarNavItemStateClass, splitPane, statusDotVariants, stripTrailingBlankLines, surfaceInteractive, swapPanes, themeById, themeCssVariables, themeFamilies, themeScript, themesForAppearance, toast, toaster, toggleVariants, tokenRangeAt, transcriptDisclosureKey, typographyTokens, undoClosePane, undocumentedTokenAliases, useSideRail, useTheme, validateTheme, validateThemeRegistry, zIndexTokens };
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "catalog-browser",
3
+ "type": "registry:ui",
4
+ "title": "Catalog Browser",
5
+ "description": "",
6
+ "dependencies": [
7
+ "lucide-solid@^1.48.0"
8
+ ],
9
+ "registryDependencies": [
10
+ "@adea-ai/ui/badge",
11
+ "@adea-ai/ui/button",
12
+ "@adea-ai/ui/card",
13
+ "@adea-ai/ui/empty",
14
+ "@adea-ai/ui/input-group",
15
+ "@adea-ai/ui/scroll-area",
16
+ "@adea-ai/ui/skeleton",
17
+ "@adea-ai/ui/tabs",
18
+ "lib"
19
+ ],
20
+ "files": [
21
+ {
22
+ "path": "src/components/composites/catalog-browser/catalog-browser-group.tsx",
23
+ "type": "registry:ui",
24
+ "target": "components/composites/catalog-browser/catalog-browser-group.tsx"
25
+ },
26
+ {
27
+ "path": "src/components/composites/catalog-browser/catalog-browser.tsx",
28
+ "type": "registry:ui",
29
+ "target": "components/composites/catalog-browser/catalog-browser.tsx"
30
+ },
31
+ {
32
+ "path": "src/components/composites/catalog-browser/catalog-detail.tsx",
33
+ "type": "registry:ui",
34
+ "target": "components/composites/catalog-browser/catalog-detail.tsx"
35
+ },
36
+ {
37
+ "path": "src/components/composites/catalog-browser/catalog-types.ts",
38
+ "type": "registry:ui",
39
+ "target": "components/composites/catalog-browser/catalog-types.ts"
40
+ },
41
+ {
42
+ "path": "src/components/composites/catalog-browser/index.ts",
43
+ "type": "registry:ui",
44
+ "target": "components/composites/catalog-browser/index.ts"
45
+ }
46
+ ]
47
+ }
@@ -1792,6 +1792,53 @@
1792
1792
  }
1793
1793
  ]
1794
1794
  },
1795
+ {
1796
+ "name": "catalog-browser",
1797
+ "type": "registry:ui",
1798
+ "title": "Catalog Browser",
1799
+ "description": "",
1800
+ "dependencies": [
1801
+ "lucide-solid@^1.48.0"
1802
+ ],
1803
+ "registryDependencies": [
1804
+ "@adea-ai/ui/badge",
1805
+ "@adea-ai/ui/button",
1806
+ "@adea-ai/ui/card",
1807
+ "@adea-ai/ui/empty",
1808
+ "@adea-ai/ui/input-group",
1809
+ "@adea-ai/ui/scroll-area",
1810
+ "@adea-ai/ui/skeleton",
1811
+ "@adea-ai/ui/tabs",
1812
+ "lib"
1813
+ ],
1814
+ "files": [
1815
+ {
1816
+ "path": "src/components/composites/catalog-browser/catalog-browser-group.tsx",
1817
+ "type": "registry:ui",
1818
+ "target": "components/composites/catalog-browser/catalog-browser-group.tsx"
1819
+ },
1820
+ {
1821
+ "path": "src/components/composites/catalog-browser/catalog-browser.tsx",
1822
+ "type": "registry:ui",
1823
+ "target": "components/composites/catalog-browser/catalog-browser.tsx"
1824
+ },
1825
+ {
1826
+ "path": "src/components/composites/catalog-browser/catalog-detail.tsx",
1827
+ "type": "registry:ui",
1828
+ "target": "components/composites/catalog-browser/catalog-detail.tsx"
1829
+ },
1830
+ {
1831
+ "path": "src/components/composites/catalog-browser/catalog-types.ts",
1832
+ "type": "registry:ui",
1833
+ "target": "components/composites/catalog-browser/catalog-types.ts"
1834
+ },
1835
+ {
1836
+ "path": "src/components/composites/catalog-browser/index.ts",
1837
+ "type": "registry:ui",
1838
+ "target": "components/composites/catalog-browser/index.ts"
1839
+ }
1840
+ ]
1841
+ },
1795
1842
  {
1796
1843
  "name": "list-row",
1797
1844
  "type": "registry:ui",
@@ -0,0 +1,148 @@
1
+ import { createUniqueId, For, onCleanup, Show, type JSX } from 'solid-js'
2
+ import { ChevronDown, ChevronRight, ChevronUp } from 'lucide-solid'
3
+ import { keyedRows } from '../../../lib/keyed-rows'
4
+ import { Badge } from '../../ui/badge'
5
+ import { Button } from '../../ui/button'
6
+ import { Skeleton } from '../../ui/skeleton'
7
+ import type { CatalogBrowserEntry, CatalogBrowserGroup as CatalogGroup } from './catalog-types'
8
+
9
+ export function CatalogLoadingState(props: { label: string }) {
10
+ return (
11
+ <div
12
+ class="grid min-w-0 grid-cols-1 gap-3 md:grid-cols-2"
13
+ aria-busy="true"
14
+ aria-label={props.label}
15
+ >
16
+ <For each={[0, 1, 2, 3, 4, 5, 6]}>
17
+ {() => (
18
+ <div class="flex min-w-0 items-center gap-3 rounded-xl border border-border p-3">
19
+ <Skeleton class="size-9 shrink-0" />
20
+ <div class="grid min-w-0 flex-1 gap-2">
21
+ <Skeleton class="h-4 w-2/5" />
22
+ <Skeleton class="h-3 w-4/5" />
23
+ <Skeleton class="h-3 w-3/5" />
24
+ </div>
25
+ </div>
26
+ )}
27
+ </For>
28
+ </div>
29
+ )
30
+ }
31
+
32
+ function CatalogBrowserRow<Value>(props: {
33
+ entry: CatalogBrowserEntry<Value>
34
+ groupId: string
35
+ installedLabel: string
36
+ publishedByLabel: (publisher: string) => string
37
+ disabled: boolean
38
+ renderIcon: (value: Value) => JSX.Element
39
+ onSelect: (entry: CatalogBrowserEntry<Value>, key: string) => void
40
+ onRef: (key: string, element: HTMLButtonElement | undefined) => void
41
+ }) {
42
+ const key = JSON.stringify([props.groupId, props.entry.id])
43
+ let element: HTMLButtonElement | undefined
44
+ onCleanup(() => {
45
+ if (element) props.onRef(key, undefined)
46
+ })
47
+
48
+ return (
49
+ <Button
50
+ ref={(node) => {
51
+ element = node
52
+ props.onRef(key, node)
53
+ }}
54
+ data-catalog-entry-id={props.entry.id}
55
+ variant="outline"
56
+ size="lg"
57
+ class="h-auto min-h-row-lg w-full min-w-0 justify-start gap-3 whitespace-normal"
58
+ disabled={props.disabled}
59
+ onClick={() => props.onSelect(props.entry, key)}
60
+ >
61
+ <span class="shrink-0">{props.renderIcon(props.entry.value)}</span>
62
+ <span class="flex min-w-0 flex-1 flex-col gap-1 text-left">
63
+ <span class="flex min-w-0 flex-wrap items-center gap-2">
64
+ <strong class="min-w-0 truncate">{props.entry.name}</strong>
65
+ <Show when={props.entry.installed}>
66
+ <Badge variant="secondary">{props.installedLabel}</Badge>
67
+ </Show>
68
+ </span>
69
+ <span class="text-muted-foreground line-clamp-2 text-xs">{props.entry.description}</span>
70
+ <span class="text-muted-foreground truncate text-2xs">
71
+ {props.publishedByLabel(props.entry.publisher)} · {props.entry.category}
72
+ </span>
73
+ </span>
74
+ <ChevronRight aria-hidden="true" />
75
+ </Button>
76
+ )
77
+ }
78
+
79
+ export function CatalogBrowserGroup<Value>(props: {
80
+ group: CatalogGroup<Value>
81
+ expanded: boolean
82
+ previewCount: number
83
+ disabled: boolean
84
+ installedLabel: string
85
+ publishedByLabel: (publisher: string) => string
86
+ showMoreLabel: (entries: readonly CatalogBrowserEntry<Value>[], remainingCount: number) => string
87
+ showLessLabel: string
88
+ renderIcon: (value: Value) => JSX.Element
89
+ onSelect: (entry: CatalogBrowserEntry<Value>, key: string) => void
90
+ onRef: (key: string, element: HTMLButtonElement | undefined) => void
91
+ onToggle: (id: string) => void
92
+ }) {
93
+ const headingId = `catalog-browser-group-${createUniqueId()}`
94
+ const listId = `catalog-browser-items-${createUniqueId()}`
95
+ const hidden = () => props.group.entries.slice(props.previewCount)
96
+ const preview = () =>
97
+ props.expanded ? props.group.entries : props.group.entries.slice(0, props.previewCount)
98
+ const rows = keyedRows(preview, (entry) => entry.id)
99
+
100
+ return (
101
+ <section class="grid min-w-0 gap-2" aria-labelledby={headingId}>
102
+ <header class="flex min-w-0 items-center gap-2">
103
+ <h3 id={headingId} class="min-w-0 flex-1 truncate text-sm font-semibold">
104
+ {props.group.label}
105
+ </h3>
106
+ <Badge variant="outline">{props.group.entries.length}</Badge>
107
+ </header>
108
+ <div id={listId} class="grid min-w-0 grid-cols-1 gap-2 md:grid-cols-2">
109
+ <For each={rows()}>
110
+ {(row) => (
111
+ <CatalogBrowserRow
112
+ entry={row.item()}
113
+ groupId={props.group.id}
114
+ installedLabel={props.installedLabel}
115
+ publishedByLabel={props.publishedByLabel}
116
+ disabled={props.disabled}
117
+ renderIcon={props.renderIcon}
118
+ onSelect={props.onSelect}
119
+ onRef={props.onRef}
120
+ />
121
+ )}
122
+ </For>
123
+ </div>
124
+ <Show when={hidden().length > 0}>
125
+ <Button
126
+ variant="ghost"
127
+ size="lg"
128
+ disabled={props.disabled}
129
+ aria-expanded={props.expanded}
130
+ aria-controls={listId}
131
+ onClick={() => props.onToggle(props.group.id)}
132
+ >
133
+ <Show
134
+ when={props.expanded}
135
+ fallback={
136
+ <>
137
+ {props.showMoreLabel(hidden(), hidden().length)}{' '}
138
+ <ChevronDown data-icon="inline-end" aria-hidden="true" />
139
+ </>
140
+ }
141
+ >
142
+ {props.showLessLabel} <ChevronUp data-icon="inline-end" aria-hidden="true" />
143
+ </Show>
144
+ </Button>
145
+ </Show>
146
+ </section>
147
+ )
148
+ }
@@ -0,0 +1,258 @@
1
+ import { createEffect, createMemo, createSignal, For, onCleanup, Show } from 'solid-js'
2
+ import { ArrowLeft, Blocks, Search } from 'lucide-solid'
3
+ import { keyedRows } from '../../../lib/keyed-rows'
4
+ import { Button } from '../../ui/button'
5
+ import {
6
+ Empty,
7
+ EmptyContent,
8
+ EmptyDescription,
9
+ EmptyHeader,
10
+ EmptyMedia,
11
+ EmptyTitle,
12
+ } from '../../ui/empty'
13
+ import { InputGroup, InputGroupAddon, InputGroupInput } from '../../ui/input-group'
14
+ import { Tabs, TabsContent, TabsList, TabsTrigger } from '../../ui/tabs'
15
+ import { ScrollArea } from '../../ui/scroll-area'
16
+ import { cn } from '../../../lib/utils'
17
+ import { CatalogBrowserGroup, CatalogLoadingState } from './catalog-browser-group'
18
+ import type { CatalogBrowserProps } from './catalog-types'
19
+
20
+ export function CatalogBrowser<Value>(props: CatalogBrowserProps<Value>) {
21
+ const [expandedGroups, setExpandedGroups] = createSignal<ReadonlySet<string>>(new Set())
22
+ const [returnKey, setReturnKey] = createSignal<string>()
23
+ const [lastSelectedId, setLastSelectedId] = createSignal<string>()
24
+ const rowRefs = new Map<string, HTMLButtonElement>()
25
+ let searchInput: HTMLInputElement | undefined
26
+ let backButton: HTMLButtonElement | undefined
27
+
28
+ const selectedTab = createMemo(() => props.tabs.find((tab) => tab.id === props.tab))
29
+ const supplemental = () => selectedTab()?.kind === 'supplemental'
30
+ const selected = createMemo(() => {
31
+ const id = props.selectedId
32
+ return id && !supplemental() ? props.entries.find((entry) => entry.id === id) : undefined
33
+ })
34
+ const groupRows = keyedRows(
35
+ () => props.groups,
36
+ (group) => group.id
37
+ )
38
+ const [wide, setWide] = createSignal(
39
+ typeof window === 'undefined' || window.matchMedia('(min-width: 48rem)').matches
40
+ )
41
+ const updateWide = (event: MediaQueryListEvent) => setWide(event.matches)
42
+
43
+ createEffect(() => {
44
+ if (typeof window === 'undefined') return
45
+ const query = window.matchMedia('(min-width: 48rem)')
46
+ query.addEventListener('change', updateWide)
47
+ onCleanup(() => query.removeEventListener('change', updateWide))
48
+ })
49
+
50
+ createEffect(() => {
51
+ const open = props.open
52
+ const selectedId = props.selectedId
53
+ const selectedEntry = selected()
54
+ if (!open) {
55
+ setExpandedGroups(new Set<string>())
56
+ setLastSelectedId(undefined)
57
+ setReturnKey(undefined)
58
+ return
59
+ }
60
+ if (selectedId && selectedEntry) {
61
+ const previous = lastSelectedId()
62
+ setLastSelectedId(selectedId)
63
+ if (selectedId !== previous) {
64
+ window.requestAnimationFrame(() => {
65
+ if (props.open && props.selectedId === selectedId) backButton?.focus()
66
+ })
67
+ }
68
+ return
69
+ }
70
+ const previous = lastSelectedId()
71
+ if (!previous) return
72
+ const key = returnKey()
73
+ setLastSelectedId(undefined)
74
+ setReturnKey(undefined)
75
+ window.requestAnimationFrame(() => {
76
+ if (!props.open || props.selectedId) return
77
+ const row = key ? rowRefs.get(key) : undefined
78
+ if (row?.isConnected) row.focus()
79
+ else searchInput?.focus()
80
+ })
81
+ })
82
+
83
+ const registerRow = (key: string, element: HTMLButtonElement | undefined) => {
84
+ if (element) rowRefs.set(key, element)
85
+ else rowRefs.delete(key)
86
+ }
87
+ const selectEntry = (key: string, value: Value) => {
88
+ setReturnKey(key)
89
+ props.onSelect(value)
90
+ }
91
+ const toggleGroup = (id: string) => {
92
+ setExpandedGroups((current) => {
93
+ const next = new Set(current)
94
+ if (next.has(id)) next.delete(id)
95
+ else next.add(id)
96
+ return next
97
+ })
98
+ }
99
+ const previewCount = () => (wide() ? 6 : 3)
100
+ const countLabel = () =>
101
+ props.status === 'loading' ? props.loadingLabel : props.resultLabel(props.resultCount)
102
+ const supplementalContent = () => props.renderSupplementalView?.(props.tab)
103
+
104
+ return (
105
+ <div class={cn('flex min-h-0 min-w-0 flex-1 flex-col', props.class)}>
106
+ <Show
107
+ when={selected()}
108
+ fallback={
109
+ <Tabs
110
+ class="flex min-h-0 min-w-0 flex-1 flex-col gap-0"
111
+ value={props.tab}
112
+ onChange={(value) => value && props.onTabChange(value)}
113
+ >
114
+ <TabsList aria-label={props.tabsLabel} class="ms-auto max-w-full flex-wrap px-4 pt-2">
115
+ <For each={props.tabs}>
116
+ {(tab) => <TabsTrigger value={tab.id}>{tab.label}</TabsTrigger>}
117
+ </For>
118
+ </TabsList>
119
+ <TabsContent value={props.tab} class="flex min-h-0 min-w-0 flex-1 flex-col gap-3">
120
+ <Show
121
+ when={supplemental()}
122
+ fallback={
123
+ <>
124
+ <Show when={props.installError}>
125
+ {(message) => (
126
+ <p class="text-destructive px-4 pt-2 text-sm" role="alert">
127
+ {message()}
128
+ </p>
129
+ )}
130
+ </Show>
131
+ <div class="flex min-w-0 shrink-0 flex-wrap items-center gap-2 px-4 pt-2">
132
+ {props.filterControl}
133
+ <InputGroup class="min-w-0 flex-1 sm:max-w-md">
134
+ <InputGroupAddon>
135
+ <Search aria-hidden="true" />
136
+ </InputGroupAddon>
137
+ <InputGroupInput
138
+ ref={(element) => (searchInput = element)}
139
+ type="search"
140
+ aria-label={props.searchLabel}
141
+ placeholder={props.searchPlaceholder}
142
+ value={props.query}
143
+ onInput={(event) => props.onQueryChange(event.currentTarget.value)}
144
+ />
145
+ </InputGroup>
146
+ <span class="text-muted-foreground ms-auto text-sm" role="status">
147
+ {countLabel()}
148
+ </span>
149
+ </div>
150
+ <ScrollArea
151
+ role="region"
152
+ aria-label={props.resultsRegionLabel}
153
+ orientation="vertical"
154
+ class="flex min-h-0 min-w-0 flex-1 flex-col gap-5 px-4 pb-4"
155
+ >
156
+ <Show when={props.status === 'error'}>
157
+ <Empty
158
+ class="min-h-0 min-w-0 flex-1"
159
+ role={props.catalogError.role ?? 'alert'}
160
+ >
161
+ <EmptyHeader>
162
+ <EmptyMedia variant="icon">
163
+ <Blocks aria-hidden="true" />
164
+ </EmptyMedia>
165
+ <EmptyTitle>{props.catalogError.title}</EmptyTitle>
166
+ <EmptyDescription>{props.catalogError.description}</EmptyDescription>
167
+ </EmptyHeader>
168
+ <Show when={props.catalogErrorAction}>
169
+ <EmptyContent>{props.catalogErrorAction}</EmptyContent>
170
+ </Show>
171
+ </Empty>
172
+ </Show>
173
+ <Show when={props.status === 'loading'}>
174
+ <CatalogLoadingState label={props.loadingLabel} />
175
+ </Show>
176
+ <Show when={props.status === 'ready'}>
177
+ <Show
178
+ when={props.resultCount > 0}
179
+ fallback={
180
+ <Empty class="min-h-0 min-w-0 flex-1" role="status">
181
+ <EmptyHeader>
182
+ <EmptyMedia variant="icon">
183
+ <Blocks aria-hidden="true" />
184
+ </EmptyMedia>
185
+ <EmptyTitle>{props.emptyState.title}</EmptyTitle>
186
+ <EmptyDescription>{props.emptyState.description}</EmptyDescription>
187
+ </EmptyHeader>
188
+ <Show when={props.emptyStateAction}>
189
+ <EmptyContent>{props.emptyStateAction}</EmptyContent>
190
+ </Show>
191
+ </Empty>
192
+ }
193
+ >
194
+ <div class="grid min-w-0 gap-5">
195
+ <For each={groupRows()}>
196
+ {(row) => (
197
+ <CatalogBrowserGroup
198
+ group={row.item()}
199
+ expanded={expandedGroups().has(row.item().id)}
200
+ previewCount={previewCount()}
201
+ disabled={props.interactionDisabled ?? false}
202
+ installedLabel={props.installedLabel}
203
+ publishedByLabel={props.publishedByLabel}
204
+ showMoreLabel={props.showMoreLabel}
205
+ showLessLabel={props.showLessLabel}
206
+ renderIcon={props.renderIcon}
207
+ onSelect={(entry, key) => selectEntry(key, entry.value)}
208
+ onRef={registerRow}
209
+ onToggle={toggleGroup}
210
+ />
211
+ )}
212
+ </For>
213
+ </div>
214
+ </Show>
215
+ </Show>
216
+ <For each={props.notices ?? []}>
217
+ {(notice) => (
218
+ <p class="text-muted-foreground text-sm" role={notice.role}>
219
+ {notice.message}
220
+ </p>
221
+ )}
222
+ </For>
223
+ </ScrollArea>
224
+ </>
225
+ }
226
+ >
227
+ {supplementalContent()}
228
+ </Show>
229
+ </TabsContent>
230
+ </Tabs>
231
+ }
232
+ >
233
+ {(entry) => (
234
+ <div class="flex min-h-0 min-w-0 flex-1 flex-col gap-3" data-catalog-browser-detail>
235
+ <Button
236
+ ref={(element) => (backButton = element)}
237
+ variant="ghost"
238
+ size="sm"
239
+ onClick={() => props.onBack()}
240
+ class="mx-4 mt-2 self-start"
241
+ >
242
+ <ArrowLeft data-icon="inline-start" aria-hidden="true" />
243
+ {props.backLabel}
244
+ </Button>
245
+ <ScrollArea
246
+ role="region"
247
+ aria-label={props.detailRegionLabel}
248
+ orientation="vertical"
249
+ class="min-h-0 min-w-0 flex-1 px-4 pb-4"
250
+ >
251
+ {props.renderDetail(entry().value)}
252
+ </ScrollArea>
253
+ </div>
254
+ )}
255
+ </Show>
256
+ </div>
257
+ )
258
+ }
@@ -0,0 +1,64 @@
1
+ import { createUniqueId, Show, type JSX } from 'solid-js'
2
+ import { Badge } from '../../ui/badge'
3
+ import { Card, CardContent, CardFooter, CardHeader } from '../../ui/card'
4
+
5
+ /** Shared item summary and action frame for catalog-owned detail content. */
6
+ export function CatalogDetail(props: {
7
+ title: string
8
+ description: string
9
+ category: string
10
+ publisher: string
11
+ publishedByLabel: (publisher: string) => string
12
+ leading?: JSX.Element
13
+ eyebrow?: string
14
+ badges?: JSX.Element
15
+ action?: JSX.Element
16
+ status?: JSX.Element
17
+ children?: JSX.Element
18
+ }) {
19
+ return (
20
+ <article class="grid min-w-0 gap-4" data-catalog-detail>
21
+ <Card>
22
+ <CardHeader class="flex-row items-start gap-3">
23
+ <Show when={props.leading}>
24
+ <span class="shrink-0">{props.leading}</span>
25
+ </Show>
26
+ <div class="grid min-w-0 gap-1.5">
27
+ <div class="flex min-w-0 flex-wrap items-center gap-1.5">
28
+ <Show when={props.eyebrow}>
29
+ <Badge variant="outline">{props.eyebrow}</Badge>
30
+ </Show>
31
+ <Badge variant="secondary">{props.category}</Badge>
32
+ {props.badges}
33
+ </div>
34
+ <h2 class="text-base leading-tight font-semibold tracking-tight">{props.title}</h2>
35
+ <p class="text-muted-foreground text-sm">{props.description}</p>
36
+ <p class="text-muted-foreground text-xs">{props.publishedByLabel(props.publisher)}</p>
37
+ </div>
38
+ </CardHeader>
39
+ <CardFooter class="flex-wrap justify-between gap-3">
40
+ {props.action}
41
+ {props.status}
42
+ </CardFooter>
43
+ </Card>
44
+ <div class="grid min-w-0 gap-3">{props.children}</div>
45
+ </article>
46
+ )
47
+ }
48
+
49
+ /** A shared surface and heading for host-specific fields, permissions, and copy. */
50
+ export function CatalogDetailSection(props: { title: string; children?: JSX.Element }) {
51
+ const headingId = `catalog-detail-section-${createUniqueId()}`
52
+ return (
53
+ <section class="min-w-0" aria-labelledby={headingId}>
54
+ <Card>
55
+ <CardHeader>
56
+ <h3 id={headingId} class="text-sm font-semibold tracking-tight">
57
+ {props.title}
58
+ </h3>
59
+ </CardHeader>
60
+ <CardContent class="grid min-w-0 gap-3">{props.children}</CardContent>
61
+ </Card>
62
+ </section>
63
+ )
64
+ }