import { Fragment, useMemo, useState, type ReactNode } from 'react' import { Card } from '@astryxdesign/core/Card' import { Center } from '@astryxdesign/core/Center' import { Collapsible, CollapsibleGroup } from '@astryxdesign/core/Collapsible' import { Divider } from '@astryxdesign/core/Divider' import { Grid } from '@astryxdesign/core/Grid' import { Heading } from '@astryxdesign/core/Heading' import { HStack } from '@astryxdesign/core/HStack' import { Icon } from '@astryxdesign/core/Icon' import { Section } from '@astryxdesign/core/Section' import { Text } from '@astryxdesign/core/Text' import { TextInput } from '@astryxdesign/core/TextInput' import { ToggleButton, ToggleButtonGroup } from '@astryxdesign/core/ToggleButton' import { VStack } from '@astryxdesign/core/VStack' import { Blocks, Layers, Search, SlidersHorizontal, } from 'lucide-react' import { Page, PageHeader } from '../components/Page' import { ASTRYX_COMPONENTS, type AstryxComponentGroup } from '../data/astryxComponents' import { ActionsDemo } from '../demos/ActionsDemo' import { ChatDemo } from '../demos/ChatDemo' import { CommandPaletteDemo } from '../demos/CommandPaletteDemo' import { DataDemo } from '../demos/DataDemo' import { DialogsDemo } from '../demos/DialogsDemo' import { FeedbackDemo } from '../demos/FeedbackDemo' import { InputsDemo } from '../demos/InputsDemo' import { LayoutDemo } from '../demos/LayoutDemo' import { MenusDemo } from '../demos/MenusDemo' import { NavigationDemo } from '../demos/NavigationDemo' import { ProvidersDemo } from '../demos/ProvidersDemo' import { SelectionDemo } from '../demos/SelectionDemo' import { SelectorsDemo } from '../demos/SelectorsDemo' import { TypographyDemo } from '../demos/TypographyDemo' interface DemoDefinition { id: string group: AstryxComponentGroup title: string description: string preview: ReactNode components: string[] } const DEMOS: DemoDefinition[] = [ { id: 'actions', group: 'base', title: '操作与链接', description: '按钮、图标按钮、工具栏、切换按钮和链接共享同一套交互状态。', preview: , components: [ 'Button', 'ButtonGroup', 'IconButton', 'ToggleButton', 'ToggleButtonGroup', 'SegmentedControl', 'SegmentedControlItem', 'Link', 'Kbd', 'Toolbar', 'Icon', ], }, { id: 'typography', group: 'base', title: '文字与内容', description: '标题、正文、引用、代码块和分隔线共同建立清晰的内容层级。', preview: , components: [ 'Text', 'Heading', 'Blockquote', 'Code', 'CodeBlock', 'Markdown', 'Citation', 'Token', 'Divider', 'VisuallyHidden', 'Timer', 'Timestamp', ], }, { id: 'layout', group: 'base', title: '布局与卡片', description: '响应式网格、可选卡片和折叠面板组成的真实布局结构。', preview: , components: [ 'Stack', 'HStack', 'VStack', 'Grid', 'GridSpan', 'Center', 'Section', 'Card', 'ClickableCard', 'SelectableCard', 'Collapsible', 'CollapsibleGroup', 'ScrollableArea', 'Layout', 'LayoutHeader', 'LayoutContent', 'LayoutFooter', 'LayoutPanel', 'Outline', 'OverflowList', 'AspectRatio', 'Thumbnail', 'Carousel', 'MediaTheme', ], }, { id: 'data', group: 'base', title: '列表、表格与头像', description: '列表、表格、头像和计数徽标用于呈现结构化数据。', preview: , components: [ 'List', 'ListItem', 'Item', 'MetadataList', 'MetadataListItem', 'Table', 'TableBody', 'TableCell', 'TableFooter', 'TableHeader', 'TableHeaderCell', 'TableRow', 'TableSelectionToolbar', 'TreeList', 'EmptyState', 'Skeleton', 'Spinner', 'Avatar', 'AvatarGroup', 'AvatarGroupOverflow', 'AvatarStatusDot', 'Badge', 'StatusDot', 'NavIcon', ], }, { id: 'providers', group: 'base', title: '主题与全局能力', description: '主题、链接和国际化 Provider 已经在页面中生效。', preview: , components: ['Theme', 'MediaTheme', 'LinkProvider', 'InternationalizationProvider'], }, { id: 'feedback', group: 'base', title: '反馈与状态', description: '用横幅、进度、加载指示和骨架屏表达系统状态。', preview: , components: ['Banner', 'ProgressBar', 'Spinner', 'Skeleton', 'EmptyState'], }, { id: 'navigation', group: 'base', title: '导航与步骤', description: '面包屑、标签页和步骤条帮助用户在层级和流程中定位。', preview: , components: [ 'AppShell', 'TopNav', 'TopNavHeading', 'TopNavItem', 'TopNavMenu', 'TopNavMegaMenu', 'TopNavMegaMenuFeaturedCard', 'TopNavMegaMenuItem', 'SideNav', 'SideNavCollapseButton', 'SideNavHeading', 'SideNavItem', 'SideNavSection', 'MobileNav', 'Breadcrumbs', 'BreadcrumbItem', 'Pagination', 'TabList', 'Tab', 'TabMenu', 'Stepper', 'Step', ], }, { id: 'chat', group: 'base', title: '聊天消息', description: '消息列表、气泡、元数据和时间戳组成的对话界面。', preview: , components: [ 'ChatComposer', 'ChatComposerDrawer', 'ChatComposerInput', 'ChatDictationButton', 'ChatLayout', 'ChatLayoutScrollButton', 'ChatMessage', 'ChatMessageBubble', 'ChatMessageList', 'ChatMessageMetadata', 'ChatSendButton', 'ChatSystemMessage', 'ChatTokenizedText', 'ChatToolCalls', ], }, { id: 'inputs', group: 'form', title: '文本输入与校验', description: '文本、长文本、开关和保存反馈组成的表单输入场景。', preview: , components: [ 'TextInput', 'TextArea', 'NumberInput', 'InputGroup', 'InputGroupText', 'Field', 'FieldLabel', 'FieldStatus', 'FormLayout', 'FileInput', 'PowerSearch', ], }, { id: 'selection', group: 'form', title: '选择控件', description: '复选框、单选框和滑杆展示不同粒度的选择操作。', preview: , components: [ 'CheckboxInput', 'CheckboxList', 'CheckboxListItem', 'RadioList', 'RadioListItem', 'Switch', 'Slider', ], }, { id: 'selectors', group: 'form', title: '选择器与日期', description: '下拉选择、日期输入和更多选择模式集中在同一场景。', preview: , components: [ 'Selector', 'SelectorOption', 'MultiSelector', 'ComplexSelector', 'Typeahead', 'BaseTypeahead', 'TypeaheadItem', 'Tokenizer', 'Calendar', 'DateInput', 'DateRangeInput', 'DateTimeInput', 'TimeInput', ], }, { id: 'dialogs', group: 'overlay', title: '对话框、抽屉与底部面板', description: '点击按钮打开真实弹层,体验遮罩、焦点管理和关闭流程。', preview: , components: [ 'Dialog', 'AlertDialog', 'DialogHeader', 'Drawer', 'DrawerHeader', 'BottomSheet', 'BottomSheetSwitcher', 'Overlay', ], }, { id: 'menus', group: 'overlay', title: '菜单与浮层', description: '下拉菜单、上下文菜单、弹出框、提示和悬停卡片。', preview: , components: [ 'DropdownMenu', 'DropdownMenuCheckboxItem', 'DropdownMenuDivider', 'DropdownMenuGroup', 'DropdownMenuItem', 'DropdownMenuRadioGroup', 'DropdownMenuRadioItem', 'DropdownMenuSubMenu', 'ContextMenu', 'MoreMenu', 'Popover', 'Tooltip', 'HoverCard', ], }, { id: 'command', group: 'overlay', title: '命令面板与通知', description: '命令面板把搜索、分组结果和键盘操作集中在一个浮层里。', preview: , components: [ 'CommandPalette', 'CommandPaletteEmpty', 'CommandPaletteFooter', 'CommandPaletteGroup', 'CommandPaletteInput', 'CommandPaletteItem', 'CommandPaletteList', 'Toast', 'Lightbox', ], }, ] const GROUPS = [ { id: 'base', label: '基础组件', icon: Blocks, description: '布局、排版、内容、操作、反馈、导航和数据展示等通用构建块。', }, { id: 'form', label: '表单组件', icon: SlidersHorizontal, description: '输入、选择、日期、校验和表单布局控件。', }, { id: 'overlay', label: '弹层组件', icon: Layers, description: '对话框、抽屉、菜单、浮层、提示和命令面板。', }, ] as const type Filter = 'all' | AstryxComponentGroup const GROUP_COUNTS = GROUPS.reduce( (counts, group) => { counts[group.id] = ASTRYX_COMPONENTS.filter( (component) => component.group === group.id, ).length return counts }, { base: 0, form: 0, overlay: 0 } as Record, ) function DemoCard({ demo }: { demo: DemoDefinition }) { return (
{demo.preview}
{demo.title} {demo.description} 覆盖组件:{demo.components.join('、')}
) } export function ComponentsPage() { const [filter, setFilter] = useState('all') const [query, setQuery] = useState('') const results = useMemo(() => { const normalized = query.trim().toLowerCase() return DEMOS.filter((demo) => { const matchesGroup = filter === 'all' || demo.group === filter const matchesQuery = normalized.length === 0 || demo.title.toLowerCase().includes(normalized) || demo.description.toLowerCase().includes(normalized) || demo.components.some((name) => name.toLowerCase().includes(normalized)) return matchesGroup && matchesQuery }) }, [filter, query]) const sections = GROUPS.map((group) => ({ ...group, demos: results.filter((demo) => demo.group === group.id), })).filter((group) => group.demos.length > 0) const coveredComponents = new Set(results.flatMap((demo) => demo.components)).size const isFiltering = filter !== 'all' || query.trim().length > 0 return ( 组件名称与 API 保留 Astryx 原始命名;示例中的操作和内容均可直接体验。 基础组件 {GROUP_COUNTS.base} 表单组件 {GROUP_COUNTS.form} 弹层组件 {GROUP_COUNTS.overlay} setFilter((value as Filter | null) ?? 'all')} size="sm"> {GROUPS.map((group) => ( ))} {isFiltering ? `${results.length} 个场景,覆盖 ${coveredComponents} 个组件` : `${DEMOS.length} 个场景,覆盖 ${coveredComponents} 个组件`} {results.length === 0 ? (
没有找到匹配的场景。 试试更宽泛的关键词,或切换回「全部」。
) : ( sections.map((group, index) => ( {index > 0 ? : null} {group.label} {group.demos.length} 个场景 {group.description} {group.demos.map((demo) => ( ))} )) )} 查看完整组件清单}> {GROUPS.map((group) => ( {group.label} {ASTRYX_COMPONENTS.filter( (component) => component.group === group.id, ) .map((component) => component.name) .join('、')} ))} 共收录 {ASTRYX_COMPONENTS.length} 个组件,数据来自 @astryxdesign/core 0.7.2。
) }