release: v0.2.0 — TypeScript 源码重构
CI / test (18.x) (push) Successful in 9m52s
CI / test (22.x) (push) Canceled after 0s
CI / test (24.x) (push) Canceled after 0s
CI / test (20.x) (push) Canceled after 2m49s

### Changed
- 全部源码从 JavaScript 迁移到 TypeScript (strict mode)
- core.js (1244行) 拆分为 toast.ts + api.ts + templates.ts
- 删除手动维护的 types/index.d.ts,类型从源码自动生成
- 构建工具链: Babel → ts-jest, 新增 @rollup/plugin-typescript
- 新增 rollup-plugin-dts 生成合并 .d.ts

### Added
- tsconfig.json (strict: true)
- src/types.ts 核心类型模块 (39 个导出类型)
- .eslintrc.json (@typescript-eslint)
- .gitea/workflows/ci.yml (Node 18/20/22/24 矩阵)
- CHANGELOG.md

### Aligned with metona-starter
- package.json: type:module, engines≥16, prepublishOnly
- rollup.config.js: dts plugin, port 3001
- jest.config.cjs, build.sh, serve.sh, .gitignore (.npmrc)

### Removed
- babel.config.js, types/ 目录, 所有 src/*.js
This commit is contained in:
tianhao
2026-07-25 11:22:07 +08:00
parent ee2b685f64
commit 9a6cd33d90
36 changed files with 3673 additions and 5473 deletions
+79
View File
@@ -0,0 +1,79 @@
/**
* MetonaToast Templates — HTML 模板辅助函数
* @module templates
* @version 0.2.0
* @description confirm / prompt / progress / action 的 DOM 模板
*/
import { escapeHTML } from './utils.js';
import { t } from './i18n.js';
import type { ActionButton, ConfirmOptions, PromptOptions, ProgressOptions } from './types.js';
/**
* 按钮行模板 — confirm/prompt 共用
*/
export const btnRow = (buttons: string): string => `
<div style="display: flex; gap: 8px; margin-top: 12px;">
${buttons}
</div>`;
/**
* 确认对话框模板
*/
export const confirmHTML = (opts: ConfirmOptions): string => {
const confirmText = opts.confirmText || t('confirm');
const cancelText = opts.cancelText || t('cancel');
const confirmColor = opts.confirmColor || '#10b981';
const cancelColor = opts.cancelColor || '#6b7280';
return btnRow(`
<button class="met-confirm-btn" style="flex:1;padding:8px 16px;border:none;border-radius:6px;background:${confirmColor};color:white;cursor:pointer;font-size:13px">${escapeHTML(confirmText)}</button>
<button class="met-cancel-btn" style="flex:1;padding:8px 16px;border:none;border-radius:6px;background:${cancelColor};color:white;cursor:pointer;font-size:13px">${escapeHTML(cancelText)}</button>
`);
};
/**
* 输入对话框模板
*/
export const promptHTML = (opts: PromptOptions): string => {
const submitText = opts.submitText || t('confirm');
const cancelText = opts.cancelText || t('cancel');
const submitColor = opts.submitColor || '#3b82f6';
const cancelColor = opts.cancelColor || '#6b7280';
return `
<input type="${opts.inputType || 'text'}"
class="met-input"
placeholder="${escapeHTML(opts.placeholder || '')}"
value="${escapeHTML(opts.defaultValue || '')}"
style="width:100%;padding:8px 12px;border:1px solid rgba(0,0,0,0.1);border-radius:6px;font-size:13px;margin-top:8px;background:transparent;color:inherit;box-sizing:border-box">
${btnRow(`
<button class="met-submit-btn" style="flex:1;padding:8px 16px;border:none;border-radius:6px;background:${submitColor};color:white;cursor:pointer;font-size:13px">${escapeHTML(submitText)}</button>
<button class="met-cancel-btn" style="flex:1;padding:8px 16px;border:none;border-radius:6px;background:${cancelColor};color:white;cursor:pointer;font-size:13px">${escapeHTML(cancelText)}</button>
`)}
`;
};
/**
* 进度条模板
*/
export const progressHTML = (opts: ProgressOptions): string => {
const color = opts.progressColor || '#3b82f6';
return `
<div class="met-progress-bar" style="width:100%;height:8px;background:rgba(0,0,0,0.1);border-radius:4px;margin-top:12px;overflow:hidden">
<div class="met-progress-fill" style="width:0%;height:100%;background:${color};border-radius:4px;transition:width 0.3s ease"></div>
</div>
<div class="met-progress-text" style="font-size:12px;opacity:0.7;margin-top:4px;text-align:right">0%</div>
`;
};
/**
* Action Toast 模板
*/
export const actionHTML = (actions: ActionButton[]): string => {
if (!Array.isArray(actions) || actions.length === 0) return '';
const buttons = actions.map((a, i) => {
const bg = a.style?.background || a.color || '#6366f1';
const cls = `met-action-btn-${i}`;
return `<button class="${cls}" style="flex:1;padding:6px 12px;border:none;border-radius:6px;background:${bg};color:white;cursor:pointer;font-size:12px;font-weight:500">${escapeHTML(a.text || '')}</button>`;
}).join('');
return btnRow(buttons);
};