Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
94d61fc
test(design-system): align component contract checks
kev1n77 Aug 29, 2026
a214a59
feat(design-system): add reference patterns and disclosure
kev1n77 Aug 29, 2026
6549d5b
feat(design-system): add core form controls
kev1n77 Aug 29, 2026
316ba6b
refactor(settings): adopt design-system form controls
kev1n77 Aug 29, 2026
264952a
refactor(web-ui): migrate legacy form controls
kev1n77 Aug 29, 2026
a8012e7
feat(design-system): add alert and avatar primitives
kev1n77 Aug 29, 2026
d0a3265
refactor(web-ui): migrate alert and avatar primitives
kev1n77 Aug 29, 2026
acd3b31
refactor(peer-device): adopt action item rows
kev1n77 Aug 29, 2026
6af78d2
refactor(web-ui): migrate language and refresh controls
kev1n77 Aug 29, 2026
bf958e7
feat(design-system): add empty state primitive
kev1n77 Aug 29, 2026
bfd5688
refactor(canvas): adopt design-system primitives
kev1n77 Aug 29, 2026
ccdeb23
refactor(web-ui): migrate native select controls
kev1n77 Aug 29, 2026
d1bcdc2
refactor(web-ui): adopt design-system textareas
kev1n77 Aug 29, 2026
d00382f
refactor(web-ui): adopt design-system search fields
kev1n77 Aug 29, 2026
655ae0e
refactor(web-ui): migrate native form controls
kev1n77 Aug 29, 2026
dbd02c5
feat(design-system): add radio control
kev1n77 Aug 29, 2026
f6f7452
refactor(settings): adopt design-system radio
kev1n77 Aug 29, 2026
634ea47
refactor(web-ui): migrate inline text inputs
kev1n77 Aug 29, 2026
9d5489b
feat(design-system): extend number input attributes
kev1n77 Aug 29, 2026
520d68a
refactor(settings): adopt number input stepper
kev1n77 Aug 29, 2026
fd7fb04
refactor(navigation): adopt design-system actions
kev1n77 Aug 29, 2026
f64d5d5
refactor(component-library): retire legacy icon button
kev1n77 Aug 29, 2026
a177450
feat(design-system): resize controlled textareas
kev1n77 Aug 29, 2026
2db976f
refactor(profile): adopt auto-resizing textarea
kev1n77 Aug 29, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions design-system/apps/design-lab/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
MousePointerClick,
Palette,
PanelTop,
PanelsTopLeft,
Search,
Settings2,
SquareTerminal,
Expand Down Expand Up @@ -49,6 +50,7 @@ import { ComponentsPage } from "./pages/ComponentsPage";
import { ComponentDetailPage } from "./pages/ComponentDetailPage";
import { GettingStartedPage } from "./pages/GettingStartedPage";
import { ResourcesPage } from "./pages/ResourcesPage";
import { PatternsPage } from "./pages/PatternsPage";
import { ColorsPage } from "./pages/ColorsPage";
import {
colorTokenCatalog,
Expand All @@ -72,6 +74,7 @@ type LabRoute =
| { page: "overview" }
| { page: "getting-started" }
| { page: "components" }
| { page: "patterns" }
| { page: "flow-chat" }
| { page: "colors" }
| { page: "resources" }
Expand Down Expand Up @@ -129,6 +132,9 @@ function parseRoute(hash: string): LabRoute {
if (route === "components") {
return { page: "components" };
}
if (route === "patterns") {
return { page: "patterns" };
}
if (route === "flow-chat") {
return { page: "flow-chat" };
}
Expand Down Expand Up @@ -215,6 +221,13 @@ export function App() {
label: t("nav.components"),
route: { page: "components" },
},
{
detail: t("search.patternsDetail"),
icon: PanelsTopLeft,
keywords: `patterns recipes settings navigation search device ${t("nav.patterns")}`,
label: t("nav.patterns"),
route: { page: "patterns" },
},
{
detail: t("search.flowChatDetail", { count: flowChatComponents.length }),
icon: SquareTerminal,
Expand Down Expand Up @@ -456,6 +469,17 @@ export function App() {
<Blocks aria-hidden="true" size={17} />
<span>{t("nav.components")}</span>
</a>
<a
aria-current={route.page === "patterns" ? "page" : undefined}
href="#patterns"
onClick={(event) => {
event.preventDefault();
navigate({ page: "patterns" });
}}
>
<PanelsTopLeft aria-hidden="true" size={17} />
<span>{t("nav.patterns")}</span>
</a>
<div className="lab-component-links">
{standardComponents.map((component) => {
const Icon = componentIcons[component.name] ?? Blocks;
Expand Down Expand Up @@ -701,6 +725,15 @@ export function App() {
/>
)}

{route.page === "patterns" && (
<PatternsPage
colorScheme={colorScheme}
contrast={contrast}
density={density}
tokenOverrides={tokenOverrides}
/>
)}

{route.page === "flow-chat" && (
<ComponentsPage
category="flow-chat"
Expand Down
88 changes: 88 additions & 0 deletions design-system/apps/design-lab/src/i18n/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export const enUSMessages = {
"nav.colors": "Colors",
"nav.library": "Library",
"nav.components": "Components",
"nav.patterns": "Patterns",
"nav.flowChat": "FlowChat",
"nav.docs": "Docs",
"nav.resources": "Resources",
Expand All @@ -24,6 +25,7 @@ export const enUSMessages = {
"search.tokensDetail": "{count} editable contracts",
"search.colorsDetail": "{count} semantic color tokens and real reference scales",
"search.componentsDetail": "{count} registered components",
"search.patternsDetail": "Reference compositions assembled from public components",
"search.flowChatDetail": "{count} shared templates and standard tool-card specimens",
"search.resourcesDetail": "Package documentation and release policy",
"search.componentDetail": "{category}",
Expand Down Expand Up @@ -64,6 +66,7 @@ export const enUSMessages = {
"component.CommandToolCard.description": "A prominent command view with controlled output disclosure, process metadata, and capability-driven actions.",
"component.Composer.description": "A composable message editor shell with independent context, editor, and action regions.",
"component.ConfirmDialog.description": "A semantic confirmation dialog with optional preview content, destructive emphasis, and async actions.",
"component.Disclosure.description": "Reveals supporting content with controlled or uncontrolled state, accessible relationships, and independent header actions.",
"component.ContextCompressionToolCard.description": "A prominent context-compression result with one compact length-and-ratio summary, plus progress and failure states.",
"component.DefaultToolCard.description": "The ambient fallback for an unregistered tool summary, sanitized input, result, and confirmation state.",
"component.DirectoryListToolCard.description": "An ambient directory-list card with structured metadata and file results.",
Expand Down Expand Up @@ -153,6 +156,47 @@ export const enUSMessages = {
"resources.boundaryKicker": "Dependency direction",
"resources.boundaryTitle": "Tokens → theme → components → Design Lab",
"resources.boundaryDescription": "Design Lab is an authoring and inspection surface. Public packages remain independent from its routes, state, and locale catalog.",
"patterns.kicker": "Recipes",
"patterns.title": "Product patterns from the reference design.",
"patterns.description": "Reusable settings, navigation, command-search, and device compositions built only from public design-system contracts.",
"patterns.settings.title": "Settings form",
"patterns.settings.description": "A 216-pixel navigation companion, clear page hierarchy, and compact grouped fields mirror the reference settings surface.",
"patterns.settings.language": "Interface language",
"patterns.settings.languageDescription": "Choose the language used throughout the interface.",
"patterns.settings.theme": "Appearance",
"patterns.settings.themeDescription": "Follow the system or choose a fixed color scheme.",
"patterns.settings.system": "System",
"patterns.settings.pointer": "Pointer glow",
"patterns.settings.pointerDescription": "Highlight interactive targets while the pointer moves.",
"patterns.settings.fontSize": "Font size",
"patterns.settings.fontSizeDescription": "Adjust the density of interface text and controls.",
"patterns.navigation.title": "Application navigation",
"patterns.navigation.description": "Compact 30-pixel rows, grouped destinations, disclosure, search, and persistent device status.",
"patterns.navigation.search": "Search navigation",
"patterns.navigation.workspace": "Workspace",
"patterns.navigation.projects": "Projects",
"patterns.navigation.tools": "Development tools",
"patterns.navigation.status": "Keep primary navigation quiet; reveal secondary destinations only when they are needed.",
"patterns.search.title": "Search and quick actions",
"patterns.search.description": "One searchable surface combines scope selection, common actions, and recent resources.",
"patterns.search.searchPlaceholder": "Search files, commands, and actions",
"patterns.search.all": "All",
"patterns.search.files": "Files",
"patterns.search.commands": "Commands",
"patterns.search.recent": "Recent resources",
"patterns.actions.newProject": "New project",
"patterns.actions.newProjectDescription": "Create a workspace from a template.",
"patterns.actions.openFiles": "Open files",
"patterns.actions.openFilesDescription": "Choose one or more local files.",
"patterns.actions.openBrowser": "Open browser",
"patterns.actions.openBrowserDescription": "Inspect a web page inside the workspace.",
"patterns.actions.openTerminal": "Open terminal",
"patterns.actions.openTerminalDescription": "Start a shell in the active workspace.",
"patterns.device.title": "Connected device card",
"patterns.device.description": "A compact status-and-action card for local and remote product surfaces.",
"patterns.device.online": "Online",
"patterns.device.connect": "Connect",
"patterns.device.refresh": "Refresh device status",
"components.preview.primary": "Primary",
"components.preview.actionCardTitle": "New session",
"components.preview.actionCardDescription": "Start a conversation using the selected assistant",
Expand Down Expand Up @@ -613,6 +657,7 @@ export const zhCNMessages = {
"nav.colors": "Colors",
"nav.library": "组件库",
"nav.components": "组件",
"nav.patterns": "模式",
"nav.flowChat": "FlowChat",
"nav.docs": "文档",
"nav.resources": "资源",
Expand All @@ -624,6 +669,7 @@ export const zhCNMessages = {
"search.tokensDetail": "{count} 个可编辑契约",
"search.colorsDetail": "{count} 个语义颜色 Token 与真实基础色阶",
"search.componentsDetail": "{count} 个已注册组件",
"search.patternsDetail": "由公开组件组合而成的参考界面模式",
"search.flowChatDetail": "{count} 个通用模板及标准工具卡片样例",
"search.resourcesDetail": "包文档与发布策略",
"search.componentDetail": "{category}",
Expand Down Expand Up @@ -664,6 +710,7 @@ export const zhCNMessages = {
"component.CommandToolCard.description": "关注型命令视图,统一承载受控输出展开、进程元数据与能力驱动的操作。",
"component.Composer.description": "可组合的消息编辑外壳,提供彼此独立的上下文、编辑和操作区域。",
"component.ConfirmDialog.description": "支持可选预览、危险操作强调和异步操作的语义化确认对话框。",
"component.Disclosure.description": "以受控或非受控状态展开辅助内容,并提供可访问关系和独立标题操作。",
"component.ContextCompressionToolCard.description": "关注型上下文压缩结果,以一条紧凑信息呈现压缩后长度与压缩比例,并保留处理和失败状态。",
"component.DefaultToolCard.description": "未注册工具的低关注兜底卡片,统一承载摘要、净化后的输入、结果与确认状态。",
"component.DirectoryListToolCard.description": "带结构化元数据和文件结果的低关注目录列表卡片。",
Expand Down Expand Up @@ -753,6 +800,47 @@ export const zhCNMessages = {
"resources.boundaryKicker": "依赖方向",
"resources.boundaryTitle": "Token → 主题 → 组件 → Design Lab",
"resources.boundaryDescription": "Design Lab 是创作与检查界面,公共包继续与它的路由、状态和语言目录保持独立。",
"patterns.kicker": "组合范式",
"patterns.title": "来自参考设计的产品模式。",
"patterns.description": "仅使用公开设计系统契约构建的设置、导航、命令搜索和设备组合。",
"patterns.settings.title": "设置表单",
"patterns.settings.description": "216 像素导航搭档、清晰页面层级与紧凑分组字段复现参考设置界面。",
"patterns.settings.language": "界面语言",
"patterns.settings.languageDescription": "选择整个界面使用的语言。",
"patterns.settings.theme": "外观",
"patterns.settings.themeDescription": "跟随系统或选择固定配色模式。",
"patterns.settings.system": "跟随系统",
"patterns.settings.pointer": "指针光效",
"patterns.settings.pointerDescription": "指针移动时突出显示可交互目标。",
"patterns.settings.fontSize": "字体大小",
"patterns.settings.fontSizeDescription": "调整界面文字和控件的密度。",
"patterns.navigation.title": "应用导航",
"patterns.navigation.description": "紧凑的 30 像素行、分组目标、展开区域、搜索与常驻设备状态。",
"patterns.navigation.search": "搜索导航",
"patterns.navigation.workspace": "工作区",
"patterns.navigation.projects": "项目",
"patterns.navigation.tools": "开发工具",
"patterns.navigation.status": "保持主导航安静,只在需要时展开次要目标。",
"patterns.search.title": "搜索与快捷操作",
"patterns.search.description": "在一个可搜索界面中组合范围选择、常用操作和最近资源。",
"patterns.search.searchPlaceholder": "搜索文件、命令和操作",
"patterns.search.all": "全部",
"patterns.search.files": "文件",
"patterns.search.commands": "命令",
"patterns.search.recent": "最近资源",
"patterns.actions.newProject": "新建项目",
"patterns.actions.newProjectDescription": "从模板创建工作区。",
"patterns.actions.openFiles": "打开文件",
"patterns.actions.openFilesDescription": "选择一个或多个本地文件。",
"patterns.actions.openBrowser": "打开浏览器",
"patterns.actions.openBrowserDescription": "在工作区内检查网页。",
"patterns.actions.openTerminal": "打开终端",
"patterns.actions.openTerminalDescription": "在当前工作区启动 Shell。",
"patterns.device.title": "已连接设备卡片",
"patterns.device.description": "适用于本地和远端产品界面的紧凑状态操作卡片。",
"patterns.device.online": "在线",
"patterns.device.connect": "连接",
"patterns.device.refresh": "刷新设备状态",
"components.preview.primary": "主要操作",
"components.preview.actionCardTitle": "新建会话",
"components.preview.actionCardDescription": "使用所选助手开始对话",
Expand Down
23 changes: 23 additions & 0 deletions design-system/apps/design-lab/src/pages/ComponentDetailPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import {
ComposerDivider,
ComposerToolbar,
ConfirmDialog,
Disclosure,
Field,
FieldGroup,
FieldRow,
Expand Down Expand Up @@ -271,6 +272,8 @@ export function ComponentDetailPage({
const [previewState, setPreviewState] = useState(
component.name === "Card"
? "raised"
: component.name === "Disclosure"
? "open"
: component.name === "Composer"
? "with-context"
: component.name === "Switch"
Expand Down Expand Up @@ -335,6 +338,8 @@ export function ComponentDetailPage({
return ["default"] as const;
case "FieldGroup":
return ["subtle", "plain", "divided"] as const;
case "Disclosure":
return ["closed", "open", "hover", "focus-visible", "disabled"] as const;
case "Menu":
return ["default", "scrolling", "focus-within", "disabled-item", "checked-item"] as const;
case "NavigationPanel":
Expand Down Expand Up @@ -472,6 +477,10 @@ export function ComponentDetailPage({
if (component.name === "StatusPill") {
return `import { Icon, StatusPill } from "@bitfun/ui";\n\n<StatusPill leading={<Icon name="circle" />} tone="${previewState}">\n Ask\n</StatusPill>`;
}
if (component.name === "Disclosure") {
const stateProps = previewState === "open" ? " defaultOpen" : previewState === "disabled" ? " disabled" : "";
return `import { Disclosure } from "@bitfun/ui";\n\n<Disclosure summary="${t("components.preview.appearance")}"${stateProps}>\n ${t("components.preview.appearanceDescription")}\n</Disclosure>`;
}
if (component.name === "NavigationPanel") {
return `import { IconButton, NavigationPanel, NavigationPanelItem, NavigationPanelSection, SearchField } from "@bitfun/ui";\nimport { Monitor, Search, Settings } from "lucide-react";\n\n<NavigationPanel\n aria-label="${t("components.preview.navigationPanelLabel")}"\n footer={<>\n <NavigationPanelItem leading={<Monitor />}>${t("components.preview.navigationPanelDevice")}</NavigationPanelItem>\n <IconButton aria-label="${t("components.preview.settings")}" icon={<Settings />} />\n </>}\n header={<SearchField aria-label="${t("components.preview.searchLabel")}" leadingIcon={<Search />} />}\n scrollbarVisibility="${navigationPanelShowScrollbar ? "auto" : "hidden"}"\n>\n <NavigationPanelSection title="${t("components.preview.navigationPanelSectionTitle")}">\n <NavigationPanelItem selected>${t("components.preview.menuItemOne")}</NavigationPanelItem>\n <NavigationPanelItem>${t("components.preview.menuItemTwo")}</NavigationPanelItem>\n </NavigationPanelSection>\n</NavigationPanel>`;
}
Expand Down Expand Up @@ -718,6 +727,20 @@ export function ComponentDetailPage({
return <Icon name={iconName} size={iconSize} tone={iconTone} />;
}

if (component.name === "Disclosure") {
return (
<Disclosure
data-bf-preview-state={state === "hover" || state === "focus-visible" ? state : undefined}
defaultOpen={state === "open"}
disabled={state === "disabled"}
key={state}
summary={t("components.preview.appearance")}
>
{t("components.preview.appearanceDescription")}
</Disclosure>
);
}

if (component.name === "ActionCard") {
return (
<ActionCard
Expand Down
Loading
Loading