/* 自动生成 — 请勿手改。来源 design/components/ + icons.js 重新生成:node design-pipeline/bundle-components.mjs 运行时依赖:页面全局 React(ui_kits 页先加载 unpkg UMD React)。 导出命名空间:window.DuduDesignSystem_2e0172(组件 15 个)*/ (() => { // design/components/core/Badge.jsx var ddBadgeCss = ` .dd-badge { display: inline-flex; align-items: center; gap: 4px; font-family: var(--font-sans); font-size: var(--text-xs); font-weight: var(--weight-semibold); padding: 2px 10px; border-radius: var(--radius-full); line-height: var(--leading-normal); } .dd-badge--neutral { background: var(--surface-2); color: var(--text-2); } .dd-badge--blue { background: var(--accent-soft); color: var(--accent-text); } .dd-badge--green { background: var(--positive-soft); color: var(--positive); } .dd-badge--orange { background: var(--warning-soft); color: var(--warning); } .dd-badge--red { background: var(--danger-soft); color: var(--danger); } `; if (typeof document !== "undefined" && !document.getElementById("dd-badge-css")) { const s = document.createElement("style"); s.id = "dd-badge-css"; s.textContent = ddBadgeCss; document.head.appendChild(s); } function Badge({ tone = "neutral", children, ...rest }) { return /* @__PURE__ */ React.createElement("span", { className: `dd-badge dd-badge--${tone}`, ...rest }, children); } // design/components/core/Button.jsx var ddButtonCss = ` .dd-btn { display: inline-flex; align-items: center; justify-content: center; gap: 6px; font-family: var(--font-sans); font-weight: var(--weight-medium); border-radius: var(--radius-sm); border: 1px solid transparent; cursor: pointer; white-space: nowrap; user-select: none; transition: background var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out); } .dd-btn:focus-visible { outline: none; box-shadow: var(--focus-ring); } .dd-btn--sm { height: var(--control-sm); padding: 0 12px; font-size: var(--text-sm); } .dd-btn--md { height: var(--control-md); padding: 0 16px; font-size: var(--text-base); } .dd-btn--lg { height: var(--control-lg); padding: 0 20px; font-size: var(--text-md); } .dd-btn--block { width: 100%; } .dd-btn--primary { background: var(--accent); color: var(--text-on-accent); } .dd-btn--primary:hover { background: var(--accent-hover); } .dd-btn--primary:active { background: var(--accent-press); } .dd-btn--secondary { background: var(--surface-card); border-color: var(--border-2); color: var(--text-1); } .dd-btn--secondary:hover { background: var(--surface-2); } .dd-btn--secondary:active { background: var(--surface-3); } .dd-btn--ghost { background: transparent; color: var(--accent-text); } .dd-btn--ghost:hover { background: var(--accent-soft); } .dd-btn--ghost:active { background: var(--accent-soft-2); } .dd-btn--danger { background: var(--danger); color: #fff; } .dd-btn--danger:hover { filter: brightness(0.94); } .dd-btn[disabled] { opacity: 0.45; pointer-events: none; } `; if (typeof document !== "undefined" && !document.getElementById("dd-button-css")) { const s = document.createElement("style"); s.id = "dd-button-css"; s.textContent = ddButtonCss; document.head.appendChild(s); } function Button({ variant = "primary", size = "md", block = false, disabled = false, children, ...rest }) { const cls = `dd-btn dd-btn--${variant} dd-btn--${size}${block ? " dd-btn--block" : ""}`; return /* @__PURE__ */ React.createElement("button", { type: "button", className: cls, disabled, ...rest }, children); } // design/components/core/Card.jsx var ddCardCss = ` .dd-card { background: var(--surface-card); border: 1px solid var(--border-1); border-radius: var(--radius-md); box-shadow: var(--shadow-card); } `; if (typeof document !== "undefined" && !document.getElementById("dd-card-css")) { const s = document.createElement("style"); s.id = "dd-card-css"; s.textContent = ddCardCss; document.head.appendChild(s); } function Card({ padding = "var(--space-5)", style, children, ...rest }) { return /* @__PURE__ */ React.createElement("div", { className: "dd-card", style: { padding, ...style }, ...rest }, children); } // design/icons.js var icons = { /** 麦克风(识别/录音) */ mic: '', /** 对勾(完成/选中) */ check: '', /** 关闭 */ x: '', /** 添加图片(反馈附图) */ imagePlus: '', /** 钥匙(权限引导) */ key: '', /** 下拉箭头(Select 等展开指示) */ chevronDown: '' }; // design/components/core/Icon.jsx function Icon({ name, size = 16, sw = 2, ...rest }) { const body = icons[name]; if (!body) throw new Error(`unknown icon: ${name}\uFF08\u5148\u5728 design/icons.js \u767B\u8BB0\uFF09`); return /* @__PURE__ */ React.createElement( "svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: sw, strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", dangerouslySetInnerHTML: { __html: body }, ...rest } ); } // design/components/core/IconButton.jsx var ddIconBtnCss = ` .dd-iconbtn { display: inline-flex; align-items: center; justify-content: center; border: none; background: transparent; color: var(--text-2); border-radius: var(--radius-sm); cursor: pointer; transition: background var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out); } .dd-iconbtn:hover { background: var(--surface-2); color: var(--text-1); } .dd-iconbtn:active { background: var(--surface-3); } .dd-iconbtn:focus-visible { outline: none; box-shadow: var(--focus-ring); } .dd-iconbtn[disabled] { opacity: 0.45; pointer-events: none; } `; if (typeof document !== "undefined" && !document.getElementById("dd-iconbtn-css")) { const s = document.createElement("style"); s.id = "dd-iconbtn-css"; s.textContent = ddIconBtnCss; document.head.appendChild(s); } function IconButton({ size = 32, label, disabled = false, children, ...rest }) { return /* @__PURE__ */ React.createElement( "button", { type: "button", className: "dd-iconbtn", "aria-label": label, title: label, style: { width: size, height: size }, disabled, ...rest }, children ); } // design/components/core/Kbd.jsx var ddKbdCss = ` .dd-kbd { display: inline-block; background: var(--surface-2); border: 1px solid var(--border-2); border-bottom-width: 2px; border-radius: var(--radius-xs); padding: 1px 7px; font-family: var(--font-mono); font-size: var(--text-xs); color: var(--text-1); line-height: 1.5; } `; if (typeof document !== "undefined" && !document.getElementById("dd-kbd-css")) { const s = document.createElement("style"); s.id = "dd-kbd-css"; s.textContent = ddKbdCss; document.head.appendChild(s); } function Kbd({ children, ...rest }) { return /* @__PURE__ */ React.createElement("kbd", { className: "dd-kbd", ...rest }, children); } function HotkeyCombo({ keys = [], gap = 4 }) { return /* @__PURE__ */ React.createElement("span", { style: { display: "inline-flex", gap, alignItems: "center" } }, keys.map((k, i) => /* @__PURE__ */ React.createElement(Kbd, { key: i }, k))); } // design/components/core/ProgressBar.jsx var ddProgressCss = ` .dd-progress { background: var(--surface-3); border-radius: var(--radius-full); overflow: hidden; } .dd-progress i { display: block; height: 100%; border-radius: var(--radius-full); background: var(--accent); transition: width var(--dur-slow) var(--ease-out); } .dd-progress--warning i { background: var(--warning); } `; if (typeof document !== "undefined" && !document.getElementById("dd-progress-css")) { const s = document.createElement("style"); s.id = "dd-progress-css"; s.textContent = ddProgressCss; document.head.appendChild(s); } function ProgressBar({ value = 0, max = 100, height = 6, warnAt = 0.9, style, ...rest }) { const ratio = Math.min(1, max > 0 ? value / max : 0); const warning = ratio >= warnAt; return /* @__PURE__ */ React.createElement( "div", { className: `dd-progress${warning ? " dd-progress--warning" : ""}`, style: { height, ...style }, role: "progressbar", "aria-valuenow": value, "aria-valuemax": max, ...rest }, /* @__PURE__ */ React.createElement("i", { style: { width: `${ratio * 100}%` } }) ); } // design/components/forms/Input.jsx var ddInputCss = ` .dd-input { display: block; width: 100%; box-sizing: border-box; height: var(--control-md); padding: 0 12px; font-family: var(--font-sans); font-size: var(--text-base); color: var(--text-1); background: var(--surface-card); border: 1px solid var(--border-2); border-radius: var(--radius-sm); transition: border-color var(--dur-fast) var(--ease-out), box-shadow var(--dur-fast) var(--ease-out); } .dd-input::placeholder { color: var(--text-3); } .dd-input:hover { border-color: var(--gray-400); } .dd-input:focus { outline: none; border-color: var(--accent); box-shadow: var(--focus-ring); } .dd-input[disabled] { opacity: 0.45; pointer-events: none; } .dd-input--lg { height: var(--control-lg); font-size: var(--text-md); border-radius: var(--radius-sm); } `; if (typeof document !== "undefined" && !document.getElementById("dd-input-css")) { const s = document.createElement("style"); s.id = "dd-input-css"; s.textContent = ddInputCss; document.head.appendChild(s); } function Input({ size = "md", style, ...rest }) { return /* @__PURE__ */ React.createElement("input", { className: `dd-input${size === "lg" ? " dd-input--lg" : ""}`, style, ...rest }); } // react-shim:react var R = globalThis.React; var useState = R.useState; var useEffect = R.useEffect; var useRef = R.useRef; var useMemo = R.useMemo; var useCallback = R.useCallback; var useContext = R.useContext; var createElement = R.createElement; var Fragment = R.Fragment; // design/components/forms/Select.jsx var ddSelectCss = ` .dd-select { position: relative; display: inline-block; font-family: var(--font-sans); } .dd-select__trigger { display: inline-flex; align-items: center; gap: 6px; height: var(--control-sm); padding: 0 26px 0 10px; border-radius: var(--radius-sm); border: 1px solid var(--border-1); background: var(--surface-card); color: var(--text-1); font-size: var(--text-sm); font-family: inherit; cursor: pointer; transition: background var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out); white-space: nowrap; } .dd-select__trigger:hover { background: var(--surface-2); } .dd-select__trigger:focus-visible { outline: none; box-shadow: var(--focus-ring); } .dd-select__chev { position: absolute; right: 8px; top: 50%; transform: translateY(-50%); pointer-events: none; color: var(--text-3); display: inline-flex; } .dd-select__menu { position: absolute; top: calc(100% + 4px); right: 0; z-index: 60; min-width: 100%; max-width: 300px; padding: 4px; margin: 0; background: var(--surface-card); border: 1px solid var(--border-1); border-radius: var(--radius-md); box-shadow: var(--shadow-menu); list-style: none; } .dd-select__opt { display: flex; align-items: center; gap: 7px; width: 100%; height: 28px; padding: 0 10px 0 8px; border: none; border-radius: var(--radius-sm); background: transparent; color: var(--text-1); font-size: var(--text-sm); font-family: inherit; cursor: pointer; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; text-align: left; } .dd-select__opt:hover { background: var(--surface-2); } .dd-select__opt .dd-select__tick { width: 14px; flex: none; display: inline-flex; color: var(--accent-text); visibility: hidden; } .dd-select__opt[aria-selected="true"] .dd-select__tick { visibility: visible; } `; if (typeof document !== "undefined" && !document.getElementById("dd-select-css")) { const s = document.createElement("style"); s.id = "dd-select-css"; s.textContent = ddSelectCss; document.head.appendChild(s); } function Select({ value, onChange, options = [], placeholder = "\u8BF7\u9009\u62E9", ...rest }) { const [open, setOpen] = useState(false); const rootRef = useRef(null); const items = options.map((o) => typeof o === "string" ? { value: o, label: o } : o); const current = items.find((o) => o.value === value); useEffect(() => { if (!open) return; const onDown = (e) => { if (rootRef.current && !rootRef.current.contains(e.target)) setOpen(false); }; const onKey = (e) => { if (e.key === "Escape") setOpen(false); }; document.addEventListener("mousedown", onDown); document.addEventListener("keydown", onKey); return () => { document.removeEventListener("mousedown", onDown); document.removeEventListener("keydown", onKey); }; }, [open]); return /* @__PURE__ */ React.createElement("span", { className: "dd-select", ref: rootRef, ...rest }, /* @__PURE__ */ React.createElement( "button", { type: "button", className: "dd-select__trigger", "aria-haspopup": "listbox", "aria-expanded": open, onClick: () => setOpen((v) => !v) }, current ? current.label : placeholder ), /* @__PURE__ */ React.createElement("span", { className: "dd-select__chev" }, /* @__PURE__ */ React.createElement(Icon, { name: "chevronDown", size: 13 })), open && /* @__PURE__ */ React.createElement("ul", { className: "dd-select__menu", role: "listbox" }, items.map((o) => /* @__PURE__ */ React.createElement("li", { key: o.value }, /* @__PURE__ */ React.createElement( "button", { type: "button", className: "dd-select__opt", role: "option", "aria-selected": o.value === value, onClick: () => { onChange?.(o.value); setOpen(false); } }, /* @__PURE__ */ React.createElement("span", { className: "dd-select__tick" }, /* @__PURE__ */ React.createElement(Icon, { name: "check", size: 12, sw: 2.5 })), o.label ))))); } // design/components/forms/SettingRow.jsx var ddSettingRowCss = ` .dd-setrow { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 12px 0; border-bottom: 1px solid var(--border-1); font-family: var(--font-sans); font-size: var(--text-base); } .dd-setrow:last-child { border-bottom: none; } .dd-setrow__label { color: var(--text-1); } .dd-setrow__desc { font-size: var(--text-xs); color: var(--text-3); margin-top: 2px; } .dd-setrow__control { display: flex; align-items: center; gap: 8px; color: var(--text-2); font-size: var(--text-sm); } `; if (typeof document !== "undefined" && !document.getElementById("dd-setrow-css")) { const s = document.createElement("style"); s.id = "dd-setrow-css"; s.textContent = ddSettingRowCss; document.head.appendChild(s); } function SettingRow({ label, description, children, ...rest }) { return /* @__PURE__ */ React.createElement("div", { className: "dd-setrow", ...rest }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "dd-setrow__label" }, label), description ? /* @__PURE__ */ React.createElement("div", { className: "dd-setrow__desc" }, description) : null), /* @__PURE__ */ React.createElement("div", { className: "dd-setrow__control" }, children)); } // design/components/forms/Switch.jsx var ddSwitchCss = ` .dd-switch { position: relative; display: inline-block; width: 40px; height: 24px; border-radius: var(--radius-full); background: var(--surface-3); border: none; cursor: pointer; padding: 0; flex: none; transition: background var(--dur-base) var(--ease-out); } .dd-switch::after { content: ''; position: absolute; top: 3px; left: 3px; width: 18px; height: 18px; border-radius: 50%; background: #fff; box-shadow: 0 1px 3px rgba(17,19,26,0.25); /* ds-ignore: \u62C7\u6307\u6295\u5F71\uFF0Cgray-950 \u7684 25% \u6D3E\u751F */ transition: transform var(--dur-base) var(--ease-out); } .dd-switch[aria-checked="true"] { background: var(--accent); } .dd-switch[aria-checked="true"]::after { transform: translateX(16px); } .dd-switch:focus-visible { outline: none; box-shadow: var(--focus-ring); } .dd-switch[disabled] { opacity: 0.45; pointer-events: none; } `; if (typeof document !== "undefined" && !document.getElementById("dd-switch-css")) { const s = document.createElement("style"); s.id = "dd-switch-css"; s.textContent = ddSwitchCss; document.head.appendChild(s); } function Switch({ checked = false, onChange, disabled = false, ...rest }) { return /* @__PURE__ */ React.createElement( "button", { type: "button", role: "switch", className: "dd-switch", "aria-checked": checked ? "true" : "false", disabled, onClick: () => onChange && onChange(!checked), ...rest } ); } // design/components/voice/Waveform.jsx var ddWaveCss = ` .dd-wave { display: inline-flex; align-items: center; gap: 3px; } .dd-wave i { display: block; width: 3px; border-radius: 2px; background: currentColor; } .dd-wave--active i { animation: dd-wave-bounce 0.9s var(--ease-in-out) infinite alternate; } @keyframes dd-wave-bounce { from { transform: scaleY(0.35); } to { transform: scaleY(1); } } @media (prefers-reduced-motion: reduce) { .dd-wave--active i { animation: none; } } `; if (typeof document !== "undefined" && !document.getElementById("dd-wave-css")) { const s = document.createElement("style"); s.id = "dd-wave-css"; s.textContent = ddWaveCss; document.head.appendChild(s); } var DD_WAVE_PATTERN = [0.3, 0.55, 0.85, 0.45, 0.7, 1, 0.4, 0.6, 0.25, 0.8, 0.5, 0.35]; function Waveform({ bars = 12, active = false, height = 26, color = "var(--accent)", style }) { const items = []; for (let i = 0; i < bars; i++) { const h = Math.round(DD_WAVE_PATTERN[i % DD_WAVE_PATTERN.length] * height); items.push(/* @__PURE__ */ React.createElement("i", { key: i, style: { height: Math.max(4, h), animationDelay: `${i % 6 * 0.07}s` } })); } return /* @__PURE__ */ React.createElement( "span", { className: `dd-wave${active ? " dd-wave--active" : ""}`, style: { height, color, ...style }, "aria-hidden": "true" }, items ); } // design/components/voice/MicBar.jsx var ddMicBarCss = ` .dd-micbar { display: flex; align-items: center; justify-content: center; gap: 8px; width: 100%; height: var(--control-xl); border: none; cursor: pointer; border-radius: var(--radius-full); font-family: var(--font-sans); font-size: var(--text-md); font-weight: var(--weight-semibold); user-select: none; -webkit-user-select: none; touch-action: none; transition: background var(--dur-fast) var(--ease-out), transform var(--dur-fast) var(--ease-out); } .dd-micbar--idle { background: var(--accent); color: var(--text-on-accent); } .dd-micbar--idle:active { background: var(--accent-press); } .dd-micbar--recording { background: var(--positive); color: #fff; } .dd-micbar--disabled { background: var(--surface-3); color: var(--text-3); cursor: default; } .dd-micbar--quota { background: var(--warning); color: #fff; } `; if (typeof document !== "undefined" && !document.getElementById("dd-micbar-css")) { const s = document.createElement("style"); s.id = "dd-micbar-css"; s.textContent = ddMicBarCss; document.head.appendChild(s); } function DdMicIcon({ size = 20 }) { return /* @__PURE__ */ React.createElement(Icon, { name: "mic", size }); } var DD_MICBAR_LABELS = { idle: "\u6309\u4F4F\u8BF4\u8BDD", recording: "\u677E\u5F00\u5B8C\u6210 \xB7 \u4E0A\u6ED1\u53D6\u6D88", disabled: "\u6253\u5F00 dudu App \u767B\u5F55", quota: "\u4ECA\u65E5\u8BD5\u7528\u5DF2\u7528\u5B8C\uFF0C\u53BB\u8D2D\u4E70\u65F6\u957F" }; function MicBar({ state = "idle", label, ...rest }) { const text = label || DD_MICBAR_LABELS[state] || DD_MICBAR_LABELS.idle; return /* @__PURE__ */ React.createElement("button", { type: "button", className: `dd-micbar dd-micbar--${state}`, ...rest }, state === "recording" ? /* @__PURE__ */ React.createElement(Waveform, { active: true, bars: 9, height: 18, color: "rgba(255,255,255,0.95)" }) : /* @__PURE__ */ React.createElement(DdMicIcon, null), /* @__PURE__ */ React.createElement("span", null, text)); } // design/components/voice/RecognitionOverlay.jsx var ddOverlayCss = ` .dd-overlay { box-sizing: border-box; width: 340px; background: var(--overlay-bg); color: var(--overlay-text); border-radius: var(--radius-lg); padding: 14px 18px; box-shadow: var(--shadow-overlay); font-family: var(--font-sans); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); } .dd-overlay__status { display: flex; align-items: center; gap: 8px; color: var(--overlay-text-2); font-size: var(--text-base); margin-top: 8px; } .dd-overlay__text { font-size: var(--text-md); line-height: 1.6; margin-top: 8px; min-height: 24px; } .dd-overlay__text .dd-partial { color: var(--overlay-text-2); } .dd-overlay__hint { font-size: 11px; color: var(--overlay-text-3); margin-top: 8px; text-align: right; } `; if (typeof document !== "undefined" && !document.getElementById("dd-overlay-css")) { const s = document.createElement("style"); s.id = "dd-overlay-css"; s.textContent = ddOverlayCss; document.head.appendChild(s); } function RecognitionOverlay({ state = "listening", finalText = "", partialText = "", hint = "\u677E\u5F00 \u2318\u21E7Space \u5B8C\u6210\u8F93\u5165", width = 340, style }) { return /* @__PURE__ */ React.createElement("div", { className: "dd-overlay", style: { width, ...style }, role: "status" }, /* @__PURE__ */ React.createElement(Waveform, { active: true, bars: 12, height: 24, color: "var(--overlay-wave)" }), state === "listening" ? /* @__PURE__ */ React.createElement("div", { className: "dd-overlay__status" }, /* @__PURE__ */ React.createElement(Icon, { name: "mic", size: 16 }), /* @__PURE__ */ React.createElement("span", null, "\u8046\u542C\u4E2D\u2026")) : /* @__PURE__ */ React.createElement("div", { className: "dd-overlay__text" }, finalText, partialText ? /* @__PURE__ */ React.createElement("span", { className: "dd-partial" }, partialText) : null), /* @__PURE__ */ React.createElement("div", { className: "dd-overlay__hint" }, hint)); } // design/_ds_entry.js var ns = globalThis.DuduDesignSystem_2e0172 = globalThis.DuduDesignSystem_2e0172 || {}; Object.assign(ns, { Badge, Button, Card, Icon, IconButton, Kbd, HotkeyCombo, ProgressBar, Input, Select, SettingRow, Switch, MicBar, RecognitionOverlay, Waveform }); })();