@system-ui-js/chameleon
v0.3.0
Published
React 组件库 - Chameleon
Readme
Chameleon
一个使用 TypeScript + Vite + React 构建的 React 组件库,集成 ESLint、Prettier 与 Jest。
Chameleon 是一个纯组件库,提供可主题化的 UI 组件。 主题以 CSS 变量形式应用,不依赖系统导向 API。
快速开始
- 安装依赖:yarn
- 本地开发:
yarn dev(Expo Web 预览,默认端口5673) - 代码检查与格式化:yarn lint / yarn lint:fix / yarn format
- 运行测试:yarn test
- 构建组件库:
yarn build(Vite 库产物输出到dist/) - 导出 Web 预览:
yarn build:web(Expo Web 静态导出到dist-web/) - 兼容旧 Vite 夹具:
yarn dev:vite
目录结构
./
├── src/
│ ├── components/ # 组件源码
│ ├── types/ # 类型声明
│ ├── theme/ # 主题定义与 CSS 变量
│ ├── dev/ # Expo Web 预览页面与 Vite 兼容夹具
│ └── index.ts # 库导出入口
├── tests/ # 测试文件
├── dist/ # 构建产物 (自动生成)
└── .github/workflows/ # CI/CDExpo Web 预览基线
- 默认浏览器预览入口已切换为 Expo Web:
yarn dev会启动 Metro,并通过根App.tsx按路径分发到组件目录页或 Playwright harness。 - 旧的 HTML 夹具链路仍可通过
yarn dev:vite使用,便于在 Expo 迁移过程中排查差异。 - SCSS 兼容策略:保留现有
.scss直引模式,并在metro.config.cjs中显式启用 CSS;由于 Expo Web 对 Sass 仅提供部分支持,当前约束是继续使用已有的单文件 SCSS,不新增复杂的@import/@forward依赖链。 className兼容策略:现有 DOM 组件与 catalog/harness 中的className写法保持不变,由 Expo Web 的浏览器渲染链路直接承接。- React Native 宿主边界:窗口 / 拖拽链首批组件(
CSlider、CSplitArea、CIconContainer、CWidget、CWindow、CWindowManager、CWindowTitle、CStartBar)以及轻量宿主组件(CButton、CButtonGroup、CButtonSeparator、CScrollArea、CStatusBar、CStatusBarItem、Themewrapper、CWindowBody)已切到react-nativeprimitives,并通过 Expo Web 与 Jest mock 在浏览器环境运行;其余组件仍沿用当前 DOM + SCSS 方案,后续继续收敛。
发布与使用
- 作为库发布后,以
@system-ui-js/chameleon安装并在代码中导入组件使用。
yarn add @system-ui-js/chameleonimport { CButton, CRadio, CRadioGroup, CSelect } from '@system-ui-js/chameleon';
const sizeOptions = [
{ label: 'Small', value: 'small' },
{ label: 'Medium', value: 'medium' },
{ label: 'Large', value: 'large' },
] as const;
export function Demo() {
return (
<>
<CButton>Default</CButton>
<CButton variant="primary">Primary</CButton>
<CRadioGroup name="fruit" defaultValue="apple">
<CRadio value="apple">Apple</CRadio>
<CRadio value="orange">Orange</CRadio>
</CRadioGroup>
<CSelect options={sizeOptions} placeholder="Select a size" />
</>
);
}Theming
Chameleon 通过 Theme 组件和组件的 theme prop 提供主题化能力。
Theme 组件
从包入口导入 Theme,使用 name 属性指定主题(接受完整 className):
import { CButton, Theme } from '@system-ui-js/chameleon';
<Theme name="cm-theme--win98">
<CButton>Themed Button</CButton>
</Theme>;Theme 组件会提供主题 Context,并渲染一个带对应 className 的 wrapper DOM。
Theme 不支持嵌套。若只需为单个组件覆盖主题,使用该组件的 theme prop。
组件 theme prop
组件支持 theme?: string prop,接受完整 className:
import { CButton } from '@system-ui-js/chameleon';
<CButton theme="cm-theme--win98">Win98 Button</CButton>;主题定义
库默认导出三套兼容旧系统 API 的主题定义:
defaultThemeDefinition→systemType: 'default',className: 'cm-theme--default'win98ThemeDefinition→systemType: 'windows',className: 'cm-theme--win98'winXpThemeDefinition→systemType: 'windows',className: 'cm-theme--winxp'
如果你需要不带 systemType 的纯主题定义,也可以使用:
pureDefaultThemeDefinitionpureWin98ThemeDefinitionpureWinXpThemeDefinition
Window Component
CWindow 是一个可拖拽、可缩放的独立窗口组件,不依赖任何系统管理器。
CWindow 不会隐式注入标题栏,使用时需要显式组合 CWindowTitle。
import { CWindow, CWindowBody, CWindowTitle } from '@system-ui-js/chameleon';
<CWindow x={24} y={24} width={320} height={220}>
<CWindowTitle>My Window</CWindowTitle>
<CWindowBody>Window body</CWindowBody>
</CWindow>;拖动 CWindowTitle 会移动所属 CWindow,内容区域不会触发窗口移动。
Border resize
CWindow 默认支持 8 方向边框缩放(N/S/E/W/NE/NW/SE/SW),可通过 resizable 与 resizeOptions 配置:
<CWindow
x={24}
y={24}
width={320}
height={220}
resizable
resizeOptions={{
edgeWidth: 4,
minContentWidth: 1,
minContentHeight: 1,
maxContentWidth: 640,
maxContentHeight: 480,
}}
>
<CWindowTitle>Resizable Window</CWindowTitle>
<CWindowBody>Window body</CWindowBody>
</CWindow>resizable:是否启用边框缩放,默认trueresizeOptions.edgeWidth:边框拖动热区宽度,默认4resizeOptions.minContentWidth/minContentHeight:最小内容尺寸,默认1resizeOptions.maxContentWidth/maxContentHeight:可选最大内容尺寸
