feat(design+desktop): Select 真相源组件 + 设置窗口无边框(12A 实测反馈)
Select 组件(用户拍板:下拉框全端共用一个真相源): - design/components/forms/Select.jsx:自绘下拉——触发器同 Input (control-sm/radius-sm/border-1 + chevronDown),弹层同菜单 (radius-md/shadow-menu、选中项前置对勾、hover surface-2), 外点/Esc 收起;登记簿加卡;icons.js 新增 chevronDown 并登记 icon-map - 原型 SettingsTray 与桌面 SettingsApp 同步换用(替换原生 select—— 其系统弹层样式/位置不可控,即 12A 截图问题) 原型组件运行时可再生(修复单源缺口): - design-pipeline/bundle-components.mjs:用 desktop 现成 esbuild 重建 _ds_bundle.js(此前为 Claude 导出产物、仓库内无法再生,组件一改即 过期);import 'react' 经全局 shim,命名空间不变;已实测原型页正常 - _ds_bundle.js 重建(15 个组件,含 Select/Icon) 设置窗口无边框: - tauri.conf settings 窗口 titleBarStyle=Overlay + hiddenTitle, 系统红绿灯悬浮左上;SettingsApp 自绘顶条(surface-2 + 下边框 + data-tauri-drag-region 可拖拽),对齐原型 MacWindow 规格 合并 feat/design-truth-source(真相源与闸体系)进本分支 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* bundle-components.mjs — 重建 design/_ds_bundle.js(原型页组件运行时)
|
||||
*
|
||||
* ui_kits 预览页经 <script src="../../_ds_bundle.js"> 消费组件;该文件原为
|
||||
* Claude 设计导出产物、仓库内无法再生,组件源码一改即过期。本脚本用
|
||||
* desktop 现成的 esbuild(不新增依赖)从 design/components/ 重新打包:
|
||||
* - JSX → React.createElement(运行时用页面全局 React,unpkg UMD)
|
||||
* - import 'react' → 全局 React shim(组件源码保持 ESM 规范,vite 侧不受影响)
|
||||
* - 导出统一挂到 window.DuduDesignSystem_2e0172(与原命名空间一致)
|
||||
*
|
||||
* 用法:node design-pipeline/bundle-components.mjs
|
||||
* 组件源码(components/ icons.js)变更后须重跑并提交产物。
|
||||
*/
|
||||
|
||||
import { readFileSync, readdirSync, statSync, writeFileSync } from 'node:fs';
|
||||
import { resolve, dirname, join, relative } from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { createRequire } from 'node:module';
|
||||
|
||||
const __dir = dirname(fileURLToPath(import.meta.url));
|
||||
const DESIGN = resolve(__dir, '../design');
|
||||
const require = createRequire(resolve(__dir, '../desktop/package.json'));
|
||||
const esbuild = require('esbuild');
|
||||
|
||||
// 收集全部组件导出(export function/const 大写开头)
|
||||
function walk(dir, out = []) {
|
||||
for (const name of readdirSync(dir)) {
|
||||
const p = join(dir, name);
|
||||
if (statSync(p).isDirectory()) walk(p, out);
|
||||
else if (name.endsWith('.jsx')) out.push(p);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
const imports = [];
|
||||
const names = [];
|
||||
for (const f of walk(join(DESIGN, 'components'))) {
|
||||
const src = readFileSync(f, 'utf8');
|
||||
const exported = [...src.matchAll(/export\s+(?:function|const)\s+([A-Z]\w+)/g)].map((m) => m[1]);
|
||||
if (!exported.length) continue;
|
||||
imports.push(`import { ${exported.join(', ')} } from './${relative(DESIGN, f)}';`);
|
||||
names.push(...exported);
|
||||
}
|
||||
|
||||
const entry = `${imports.join('\n')}
|
||||
const ns = (globalThis.DuduDesignSystem_2e0172 = globalThis.DuduDesignSystem_2e0172 || {});
|
||||
Object.assign(ns, { ${names.join(', ')} });
|
||||
`;
|
||||
|
||||
// import 'react' → 页面全局 React(unpkg UMD)
|
||||
const reactShim = {
|
||||
name: 'react-global-shim',
|
||||
setup(build) {
|
||||
build.onResolve({ filter: /^react$/ }, () => ({ path: 'react', namespace: 'react-shim' }));
|
||||
build.onLoad({ filter: /.*/, namespace: 'react-shim' }, () => ({
|
||||
contents: `const R = globalThis.React;
|
||||
export default R;
|
||||
export const useState = R.useState, useEffect = R.useEffect, useRef = R.useRef,
|
||||
useMemo = R.useMemo, useCallback = R.useCallback, useContext = R.useContext,
|
||||
createElement = R.createElement, Fragment = R.Fragment;`,
|
||||
loader: 'js',
|
||||
}));
|
||||
},
|
||||
};
|
||||
|
||||
const result = await esbuild.build({
|
||||
stdin: { contents: entry, resolveDir: DESIGN, loader: 'js', sourcefile: '_ds_entry.js' },
|
||||
bundle: true,
|
||||
format: 'iife',
|
||||
jsx: 'transform',
|
||||
jsxFactory: 'React.createElement',
|
||||
jsxFragment: 'React.Fragment',
|
||||
plugins: [reactShim],
|
||||
write: false,
|
||||
banner: {
|
||||
js: `/* 自动生成 — 请勿手改。来源 design/components/ + icons.js
|
||||
重新生成:node design-pipeline/bundle-components.mjs
|
||||
运行时依赖:页面全局 React(ui_kits 页先加载 unpkg UMD React)。
|
||||
导出命名空间:window.DuduDesignSystem_2e0172(组件 ${names.length} 个)*/`,
|
||||
},
|
||||
});
|
||||
|
||||
writeFileSync(join(DESIGN, '_ds_bundle.js'), result.outputFiles[0].text, 'utf8');
|
||||
console.log(`✅ design/_ds_bundle.js(${names.length} 个组件:${names.join(', ')})`);
|
||||
Reference in New Issue
Block a user