Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion BitFun-Installer/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ A fully custom, branded installer for BitFun — built with **Tauri 2 + React**
Instead of relying on the generic NSIS wizard UI from Tauri's built-in bundler, this project provides:

- **100% custom UI** — React-based, with smooth animations, dark theme, and brand consistency
- **Modern experience** — Similar to Discord, Figma, and VS Code installers
- **Modern experience** — Similar to Discord and VS Code installers
- **Full control** — Custom installation logic, right-click context menu, PATH integration
- **Cross-platform potential** — Same codebase can target Windows, macOS, and Linux

Expand Down
11 changes: 11 additions & 0 deletions design-system/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,17 @@ Design Lab exposes an Overview, a searchable component catalog with interactive

`@bitfun/ui/registry` is the component source of truth. Design Lab derives its component navigation, counts, token scopes, and detail routes from that package export; adding Lab copy or a preview cannot publish a component or keep a removed component alive.

The **Patterns** page composes public controls into settings, navigation,
search/actions, device cards, provider configuration, scene toolbars, and nested
command menus. The provider specimen includes an actual modal interaction demo,
model multi-selection/custom values and expandable detail cards. The toolbar
supports tab selection, closing and addition; the command menu supports both
button and right-click entry with nested keyboard and pointer navigation.
These are local interaction previews: they do not call product APIs or save
credentials.
Review these manually in light/dark, high-contrast and density modes; build and
interaction checks do not establish pixel-level visual fidelity.

The same entry publishes `ChatComposer`, the shared context-band and
compact/expanded input anatomy used by product composers without importing
their stores, localized menus, editor, model, voice, or host actions.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const descriptionKeys: Readonly<Record<string, MessageKey>> = {
Card: "component.Card.description",
CommandToolCard: "component.CommandToolCard.description",
Composer: "component.Composer.description",
Combobox: "component.Combobox.description",
ConfirmDialog: "component.ConfirmDialog.description",
ContextCompressionToolCard: "component.ContextCompressionToolCard.description",
DefaultToolCard: "component.DefaultToolCard.description",
Expand Down
141 changes: 141 additions & 0 deletions design-system/apps/design-lab/src/i18n/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,49 @@ export const enUSMessages = {
"patterns.device.online": "Online",
"patterns.device.connect": "Connect",
"patterns.device.refresh": "Refresh device status",
"component.Combobox.description": "Searchable, grouped single or multiple selection with custom values, tags and async states.",
"patterns.provider.title": "Provider configuration dialog",
"patterns.provider.description": "Grouped connection fields, searchable multi-selection, custom models, expandable model details, and a fixed action footer.",
"patterns.provider.search": "Search models",
"patterns.provider.empty": "No matching models",
"patterns.provider.loading": "Loading models…",
"patterns.provider.remove": "Remove model",
"patterns.provider.all": "Select all models",
"patterns.provider.add": "Add custom model",
"patterns.provider.custom": "Enter model ID",
"patterns.provider.presets": "Preset models",
"patterns.provider.category": "Model category",
"patterns.provider.general": "General",
"patterns.provider.vision": "Vision",
"patterns.provider.context": "Context window",
"patterns.provider.increase": "Increase context window",
"patterns.provider.decrease": "Decrease context window",
"patterns.provider.reasoning": "Reasoning",
"patterns.provider.preset": "Reasoning preset",
"patterns.provider.presetDescription": "Keep model-specific controls together inside the expanded card.",
"patterns.provider.auto": "Automatic",
"patterns.provider.high": "High",
"patterns.provider.advanced": "Advanced settings",
"patterns.provider.headers": "Custom headers",
"patterns.provider.previewOnly": "Interactive preview only; no network requests or credentials are saved.",
"patterns.provider.saved": "Preview confirmed. No product configuration was changed.",
"patterns.toolbar.title": "Scene tabs and toolbar",
"patterns.toolbar.description": "Scrollable tabs and independent close actions share one bar with change counts and trailing tools.",
"patterns.toolbar.tabs": "Open files",
"patterns.toolbar.search": "Search in file",
"patterns.toolbar.details": "Toggle details",
"patterns.toolbar.panel": "Select, close or add tabs; use the trailing controls to reveal search and details.",
"patterns.toolbar.empty": "No open files. Use the plus button to add a tab.",
"patterns.toolbar.detailsVisible": "Details panel enabled",
"patterns.menu.title": "Nested command menu",
"patterns.menu.description": "Anchored and pointer-positioned menus share navigation, disabled items, checked state, edge flipping and focus return.",
"patterns.menu.hint": "Open with the button or right-click this card. Move across the gap to a submenu.",
"patterns.menu.open": "Open commands",
"patterns.menu.local": "Local terminal",
"patterns.menu.remote": "Remote terminal (unavailable in this preview)",
"patterns.menu.pin": "Pin command",
"patterns.menu.lastAction": "Preview action: {action}",
"patterns.menu.keyboard": "Use arrows, Home/End, Enter and Escape; Tab closes the menu.",
"components.preview.primary": "Primary",
"components.preview.actionCardTitle": "New session",
"components.preview.actionCardDescription": "Start a conversation using the selected assistant",
Expand Down Expand Up @@ -442,6 +485,10 @@ export const enUSMessages = {
"detail.option.completed": "Completed",
"detail.option.expanded": "Expanded",
"detail.option.loading": "Loading",
"detail.option.multiple": "Multiple selection",
"detail.option.searching": "Searching",
"detail.option.custom": "Custom value",
"detail.option.empty": "Empty",
"detail.option.submitting": "Submitting",
"detail.option.none": "None",
"detail.option.chevron": "Chevron",
Expand Down Expand Up @@ -841,6 +888,49 @@ export const zhCNMessages = {
"patterns.device.online": "在线",
"patterns.device.connect": "连接",
"patterns.device.refresh": "刷新设备状态",
"component.Combobox.description": "支持搜索、分组、单选或多选、自定义值、标签及异步状态的选择器。",
"patterns.provider.title": "供应商配置弹窗",
"patterns.provider.description": "组合连接参数、搜索多选、自定义模型、可展开的模型详情和固定底部操作区。",
"patterns.provider.search": "搜索模型",
"patterns.provider.empty": "没有匹配的模型",
"patterns.provider.loading": "正在加载模型…",
"patterns.provider.remove": "移除模型",
"patterns.provider.all": "选择全部模型",
"patterns.provider.add": "添加自定义模型",
"patterns.provider.custom": "输入模型 ID",
"patterns.provider.presets": "预设模型",
"patterns.provider.category": "模型类别",
"patterns.provider.general": "通用",
"patterns.provider.vision": "视觉",
"patterns.provider.context": "上下文窗口",
"patterns.provider.increase": "增大上下文窗口",
"patterns.provider.decrease": "减小上下文窗口",
"patterns.provider.reasoning": "推理能力",
"patterns.provider.preset": "推理预设",
"patterns.provider.presetDescription": "将模型专属设置集中在展开卡片中。",
"patterns.provider.auto": "自动",
"patterns.provider.high": "高",
"patterns.provider.advanced": "高级设置",
"patterns.provider.headers": "自定义请求头",
"patterns.provider.previewOnly": "仅交互预览;不会发送网络请求或保存凭据。",
"patterns.provider.saved": "已确认预览,未修改产品配置。",
"patterns.toolbar.title": "场景标签与工具栏",
"patterns.toolbar.description": "可滚动标签和独立关闭按钮,与变更计数及右侧工具组合成统一顶栏。",
"patterns.toolbar.tabs": "打开的文件",
"patterns.toolbar.search": "在文件中搜索",
"patterns.toolbar.details": "切换详情",
"patterns.toolbar.panel": "选择、关闭或添加标签,使用右侧工具显示搜索和详情。",
"patterns.toolbar.empty": "没有打开的文件,点击加号添加标签。",
"patterns.toolbar.detailsVisible": "已启用详情面板",
"patterns.menu.title": "嵌套命令菜单",
"patterns.menu.description": "锚点菜单和右键菜单共享导航、禁用项、勾选状态、边缘翻转及焦点恢复。",
"patterns.menu.hint": "点击按钮或在此卡片上右键打开,跨过间隙进入子菜单。",
"patterns.menu.open": "打开命令",
"patterns.menu.local": "本地终端",
"patterns.menu.remote": "远程终端(此预览中不可用)",
"patterns.menu.pin": "固定命令",
"patterns.menu.lastAction": "预览操作:{action}",
"patterns.menu.keyboard": "支持方向键、Home/End、Enter 和 Escape,Tab 可关闭菜单。",
"components.preview.primary": "主要操作",
"components.preview.actionCardTitle": "新建会话",
"components.preview.actionCardDescription": "使用所选助手开始对话",
Expand Down Expand Up @@ -1086,6 +1176,10 @@ export const zhCNMessages = {
"detail.option.completed": "已完成",
"detail.option.expanded": "展开",
"detail.option.loading": "加载中",
"detail.option.multiple": "多选",
"detail.option.searching": "搜索中",
"detail.option.custom": "自定义值",
"detail.option.empty": "空选项",
"detail.option.submitting": "提交中",
"detail.option.none": "无",
"detail.option.chevron": "箭头",
Expand Down Expand Up @@ -1287,6 +1381,49 @@ export const zhCNMessages = {

export const zhTWMessages = {
...zhCNMessages,
"component.Combobox.description": "支援搜尋、分組、單選或多選、自訂值、標籤及非同步狀態的選擇器。",
"patterns.provider.title": "供應商設定對話框",
"patterns.provider.description": "組合連線參數、搜尋多選、自訂模型、可展開的模型詳情和固定底部操作區。",
"patterns.provider.search": "搜尋模型",
"patterns.provider.empty": "沒有符合的模型",
"patterns.provider.loading": "正在載入模型…",
"patterns.provider.remove": "移除模型",
"patterns.provider.all": "選擇全部模型",
"patterns.provider.add": "新增自訂模型",
"patterns.provider.custom": "輸入模型 ID",
"patterns.provider.presets": "預設模型",
"patterns.provider.category": "模型類別",
"patterns.provider.general": "通用",
"patterns.provider.vision": "視覺",
"patterns.provider.context": "上下文視窗",
"patterns.provider.increase": "增大上下文視窗",
"patterns.provider.decrease": "縮小上下文視窗",
"patterns.provider.reasoning": "推理能力",
"patterns.provider.preset": "推理預設",
"patterns.provider.presetDescription": "將模型專屬設定集中在展開卡片中。",
"patterns.provider.auto": "自動",
"patterns.provider.high": "高",
"patterns.provider.advanced": "進階設定",
"patterns.provider.headers": "自訂請求標頭",
"patterns.provider.previewOnly": "僅互動預覽;不會傳送網路請求或儲存憑證。",
"patterns.provider.saved": "已確認預覽,未修改產品設定。",
"patterns.toolbar.title": "場景標籤與工具列",
"patterns.toolbar.description": "可捲動標籤和獨立關閉按鈕,與變更計數及右側工具組合成統一頂列。",
"patterns.toolbar.tabs": "開啟的檔案",
"patterns.toolbar.search": "在檔案中搜尋",
"patterns.toolbar.details": "切換詳情",
"patterns.toolbar.panel": "選擇、關閉或新增標籤,使用右側工具顯示搜尋和詳情。",
"patterns.toolbar.empty": "沒有開啟的檔案,點擊加號新增標籤。",
"patterns.toolbar.detailsVisible": "已啟用詳情面板",
"patterns.menu.title": "巢狀命令選單",
"patterns.menu.description": "錨點選單和右鍵選單共用導覽、停用項目、勾選狀態、邊緣翻轉及焦點還原。",
"patterns.menu.hint": "點擊按鈕或在此卡片上按右鍵開啟,跨過間隙進入子選單。",
"patterns.menu.open": "開啟命令",
"patterns.menu.local": "本機終端機",
"patterns.menu.remote": "遠端終端機(此預覽中無法使用)",
"patterns.menu.pin": "釘選命令",
"patterns.menu.lastAction": "預覽操作:{action}",
"patterns.menu.keyboard": "支援方向鍵、Home/End、Enter 和 Escape,Tab 可關閉選單。",
"app.brandSubtitle": "獨立 Design Lab",
"app.closeNavigation": "關閉導覽",
"app.openNavigation": "開啟導覽",
Expand Down Expand Up @@ -1669,6 +1806,10 @@ export const zhTWMessages = {
"detail.option.completed": "已完成",
"detail.option.expanded": "展開",
"detail.option.loading": "載入中",
"detail.option.multiple": "多選",
"detail.option.searching": "搜尋中",
"detail.option.custom": "自訂值",
"detail.option.empty": "空選項",
"detail.option.submitting": "提交中",
"detail.option.none": "無",
"detail.option.chevron": "箭頭",
Expand Down
18 changes: 18 additions & 0 deletions design-system/apps/design-lab/src/pages/ComponentDetailPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import {
CardMedia,
ChangeCount,
Composer,
Combobox,
ComposerContextBar,
ComposerDivider,
ComposerToolbar,
Expand Down Expand Up @@ -88,6 +89,7 @@ import {
type TokenOverrides,
} from "@bitfun/ui";
import type { ComponentMeta } from "@bitfun/ui/registry";
import { NestedMenuPattern } from "./ReferencePatterns";
import { useI18n, type MessageKey } from "../i18n";
import {
getComponentCategoryLabel,
Expand Down Expand Up @@ -162,6 +164,10 @@ const optionLabelKeys: Readonly<Record<string, MessageKey>> = {
left: "detail.option.left",
lg: "detail.option.lg",
loading: "detail.option.loading",
multiple: "detail.option.multiple",
searching: "detail.option.searching",
custom: "detail.option.custom",
empty: "detail.option.empty",
pending: "detail.option.pending",
md: "detail.option.md",
none: "detail.option.none",
Expand Down Expand Up @@ -355,6 +361,8 @@ export function ComponentDetailPage({
return ["default", "with-center", "overflow"] as const;
case "Tooltip":
return ["top", "bottom", "left", "right"] as const;
case "Combobox":
return component.states;
default:
return ["off", "on", "focus-visible", "disabled"] as const;
}
Expand All @@ -364,6 +372,7 @@ export function ComponentDetailPage({
: states;

const codeSample = useMemo(() => {
if (component.name === "Combobox") return 'import { Combobox } from "@bitfun/ui";\n\n<Combobox label="Models" multiple searchable allowCustomValue options={[{ label: "OpenBitFun", value: "openbitfun" }]} />';
if (flowChatPreview) {
return flowChatPreview.codeSample(t);
}
Expand Down Expand Up @@ -776,6 +785,9 @@ export function ComponentDetailPage({
);
}

if (component.name === "Combobox") {
return <Combobox key={state} label={t("components.preview.modalSelectModels")} multiple={state === "multiple"} defaultValue={state === "multiple" ? ["glm-5.2", "openbitfun"] : undefined} defaultOpen={state === "open" || state === "searching"} defaultSearchValue={state === "searching" ? "glm" : ""} allowCustomValue={state === "custom"} disabled={state === "disabled"} error={state === "invalid"} loading={state === "loading"} options={state === "empty" || state === "loading" ? [] : [{ value: "glm-5.2", label: "GLM 5.2", group: "API" }, { value: "openbitfun", label: "OpenBitFun", group: "API" }]} />;
}
if (component.name === "Select") {
return (
<Select
Expand Down Expand Up @@ -1565,6 +1577,11 @@ export function ComponentDetailPage({
</span>
{renderPreview(previewState)}
</div>
) : component.name === "Combobox" ? (
<div className="component-combobox-preview" data-component="combobox">
<span>{t(optionLabelKeys[previewState] ?? "detail.option.default")}</span>
{renderPreview(previewState)}
</div>
) : isFlowChatComponent ? (
<div
className="flow-chat-state-list"
Expand Down Expand Up @@ -1774,6 +1791,7 @@ export function ComponentDetailPage({
))}
</div>
)}
{component.name === "Menu" && <div className="component-menu-interaction"><NestedMenuPattern /></div>}
</ThemeRoot>
</section>

Expand Down
2 changes: 2 additions & 0 deletions design-system/apps/design-lab/src/pages/ComponentsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import {
ChangeCount,
Checkbox,
Composer,
Combobox,
ComposerToolbar,
Disclosure,
Empty,
Expand Down Expand Up @@ -126,6 +127,7 @@ const componentIcons = {

function ComponentCardPreview({ component }: { component: ComponentMeta }) {
const { t } = useI18n();
if (component.name === "Combobox") return <Combobox label={t("components.preview.modalProviderName")} defaultValue="openbitfun" options={[{ value: "openbitfun", label: "OpenBitFun" }, { value: "custom", label: t("components.preview.add") }]} />;
const flowChatPreview = getFlowChatPreviewDefinition(component.name);

if (flowChatPreview) {
Expand Down
10 changes: 10 additions & 0 deletions design-system/apps/design-lab/src/pages/PatternsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import {
type TokenOverrides,
} from "@bitfun/ui";
import { useI18n, type MessageKey } from "../i18n";
import { NestedMenuPattern, ProviderConfigurationPattern, SceneToolbarPattern } from "./ReferencePatterns";

interface PatternsPageProps {
colorScheme: ColorScheme;
Expand Down Expand Up @@ -162,6 +163,15 @@ export function PatternsPage({ colorScheme, contrast, density, tokenOverrides }:
<Button leadingIcon={<Icon name="link" />} size="sm" variant="fill">{t("patterns.device.connect")}</Button>
</Card>
</PatternSection>
<PatternSection description={t("patterns.provider.description")} index="05" title={t("patterns.provider.title")}>
<ProviderConfigurationPattern />
</PatternSection>
<PatternSection description={t("patterns.toolbar.description")} index="06" title={t("patterns.toolbar.title")}>
<SceneToolbarPattern />
</PatternSection>
<PatternSection description={t("patterns.menu.description")} index="07" title={t("patterns.menu.title")}>
<NestedMenuPattern />
</PatternSection>
</main>
</ThemeRoot>
);
Expand Down
Loading
Loading