- 包声明 type:module 时 .js 产物被 Node 按 ESM 解析:Node 16/18 下 require 报 ERR_REQUIRE_ESM,Node 20+ 拿到 namespace 对象(success/version 等属性 undefined) - dist/metona-toast.cjs.js → .cjs,dist/react.cjs.js → .cjs - 主包 CJS footer 将 default 提升为 module.exports:require() 直接返回 MeToast(兼容 .default / .MeToast / .Met / .Toast / .VERSION 所有用法) - 版本 0.5.1(0.5.0 已发布带问题产物) - 真实消费者验证:CJS/ESM/React 子包四路加载全部正常
80 lines
3.5 KiB
TypeScript
80 lines
3.5 KiB
TypeScript
/**
|
|
* MetonaToast Templates — HTML 模板辅助函数
|
|
* @module templates
|
|
* @version 0.5.1
|
|
* @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);
|
|
};
|