@ broberg/ ui- controls- core
这个 无头逻辑 在庄园的本土控制替代之后——
自定义 <select>采枣者 模式者 土司者 克里斯蒂安的
"从来没有本土对话或形式控制"规则授权. 纯类型脚本, 0
JSX,零道岔. 反应( R)@broberg/ui-controls-react)和预告
(单位:千美元)@broberg/ui-controls-preact适配器在顶上渲染;这是拥有部分
两者必须行为一致.
npm i @broberg/ui-controls-core
日历
import { buildMonthGrid, ymd, parseYmd, isInRange, monthLabel, normalizeYmd } from "@broberg/ui-controls-core";
buildMonthGrid(2026, 7); // 42 Monday-first cells, padded → [{date,day,inMonth}, …]
monthLabel(2026, 7, "da-DK"); // "juli 2026" (locale-delegated, no baked-in names)
isInRange("2026-07-04", "2026-07-01", "2026-07-31"); // true
// Typed-input normalisation — disambiguates strictly by the 4-digit year:
normalizeYmd("03-04-2025"); // "2025-04-03" (3 April, never April-03)
normalizeYmd("2025-04-03"); // "2025-04-03"
normalizeYmd("3.4.2025"); // "2025-04-03"
选择键盘压缩器
import { selectKeyReducer } from "@broberg/ui-controls-core";
let state = { open: false, highlighted: -1 };
const { state: next, intent } = selectKeyReducer(state, event.key, options.length);
// intent: "open" | "close" | { type: "select", index } | "none"
// ArrowDown/Up wrap; Enter/Space select the highlight (or open); Escape closes.
0.3.0 — 选入:没有露出武装,第一箭头为当前值(F016.10).
selectKeyReducer(state, event.key, options.length, { armOnOpen: false, currentIndex: selectedIndex });
armOnOpen: false——在闭接器上输入/空间打开 无 突出显示, 因此Enter 之后的意外打开会选择无; Enter 只选择箭头键后.currentIndex——第一个箭头落在已经被选中的选项上,而不是跳到第一个/最后一个,因此一个按键从不移动两个位置. 外出值被忽略.
无选项(或 {}缩写完全为0.2.4——按每张键×国×分大小的逐字记录.
外部单击/ 滚动/ 调整大小
import { makeOutsideClickHandler } from "@broberg/ui-controls-core";
const handle = makeOutsideClickHandler(() => [triggerEl, menuEl], () => setOpen(false));
handle.attach(); // closes on a pointerdown outside all els, or on ancestor scroll / resize
handle.detach(); // (a fixed-position portal would otherwise drift from its trigger)
敬酒队列
import { ToastQueue } from "@broberg/ui-controls-core";
const toasts = new ToastQueue({ maxVisible: 4, defaultDuration: 4000 });
const id = toasts.push({ message: "Saved", kind: "success" }); // auto-dismisses; 0 = sticky
toasts.dismiss(id);
toasts.subscribe((items) => render(items)); // items: { id, message, kind, duration }[]
决定性( monotic ids, no) Math.random编号 :Date.now所以这是微不足道的
可检验和SSR安全。 盖子在 maxVisible丢掉最老的.
许可证
麻省理工学院的一部分 @broberg/* 共享库存.