init: @ui-arch 私人组件库 monorepo
- core/table-core: Headless 表格内核(排序/筛选/分页/选择插件 + 冒烟 9 项) - core/frame: signal/computed/effect + hyperscript 微框架(零依赖) - skin/ui: 16 个 DOM 组件(含自绘 select、滑动指示条 tabs、行选择 dataTable、form 表单校验) - design/tokens: --ua-* 设计令牌(light/dark) - tools/cli: ua 命令行(index/list/info/docs/style/mcp)+ MCP 注册表服务 - apps: demo 演示站(esbuild 单文件)+ docs 双轨文档(人类版 + llms-full.txt)
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
import { effect, h } from '@ui-arch/frame';
|
||||
import type { RadioGroupProps } from './types.js';
|
||||
|
||||
/*** 单选组:value 信号双向绑定,options 同组互斥,name 固定保证原生互斥行为 ***/
|
||||
export function radioGroup(props: RadioGroupProps): HTMLElement {
|
||||
const groupName = `ua-radio-${Math.random().toString(36).slice(2, 8)}`; // 组内唯一 name
|
||||
const radios: HTMLInputElement[] = [];
|
||||
for (const opt of props.options) {
|
||||
const input = h('input', { type: 'radio', name: groupName, class: 'ua-radio' }) as HTMLInputElement;
|
||||
input.value = opt.value;
|
||||
radios.push(input);
|
||||
input.addEventListener('change', () => {
|
||||
if (props.value) props.value(input.value); // 用户选择写回信号
|
||||
props.onChange?.(input.value);
|
||||
});
|
||||
}
|
||||
if (props.value) {
|
||||
const value = props.value;
|
||||
effect(() => {
|
||||
for (const input of radios) input.checked = input.value === value(); // 外部变化同步勾选态
|
||||
});
|
||||
}
|
||||
const rows = props.options.map((opt, i) => h('label', { class: 'ua-check-row' }, radios[i], opt.label));
|
||||
return h('div', { class: 'ua-radio-group' }, ...rows);
|
||||
}
|
||||
Reference in New Issue
Block a user