@broberg/ui-controls-core

中文文档
0.3.0发布于 2026/10/25MITTypeScriptESM + CJS零依赖构建来源已验证近 30 天下载 1.6万

Headless logic for the estate's native-control replacements (Christian's no-native-dialogs/controls rule): Monday-first calendar math + DD-MM-YYYY/YYYY-MM-DD normalisation, a select keyboard-navigation reducer, an outside-click/scroll/resize handler, and

原始使用文档
文档目录5 节
  1. Calendar
  2. Select keyboard reducer
  3. Outside-click / scroll / resize
  4. Toast queue
  5. License

@broberg/ui-controls-core

The headless logic behind the estate's native-control replacements — the custom <select>, the date picker, the modal, the toast — that Christian's "never native dialogs or form controls" rule mandates. Pure TypeScript, zero JSX, zero deps. The React (@broberg/ui-controls-react) and Preact (@broberg/ui-controls-preact) adapters render on top; this owns the parts that must behave identically across both.

npm i @broberg/ui-controls-core

Calendar

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"

Select keyboard reducer

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 — opt-in: nothing armed on open, first arrow on the current value (F016.10).

selectKeyReducer(state, event.key, options.length, { armOnOpen: false, currentIndex: selectedIndex });
  • armOnOpen: false — Enter/Space on a closed picker opens it with nothing highlighted, so an accidental open followed by Enter chooses nothing; Enter only selects after an arrow key.
  • currentIndex — the first arrow lands on the option that is already selected instead of jumping to the first/last one, so one press never moves two places. Out-of-range values are ignored.

Without options (or with {}) the reducer is exactly 0.2.4 — asserted against a verbatim copy over every key × state × size.

Outside-click / scroll / resize

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)

Toast queue

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 }[]

Deterministic (monotonic ids, no Math.random/Date.now) so it's trivially testable and SSR-safe. Caps at maxVisible, dropping the oldest.

License

MIT · part of the @broberg/* shared inventory.

版本与发布记录

@broberg/ui-controls-core 共发布 6 个版本,首次发布于 2026/07/12;过去 12 个月发布了 6 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.3.0latest2026/10/2514 天前
0.2.42026/10/2316 天前
0.2.32026/09/101 个月前
0.2.22026/09/101 个月前
0.1.12026/08/292 个月前
0.1.02026/07/123 个月前

关于 @broberg/ui-controls-core 的常见问题

@broberg/ui-controls-core 是什么?

Headless logic for the estate's native-control replacements (Christian's no-native-dialogs/controls rule): Monday-first calendar math + DD-MM-YYYY/YYYY-MM-DD normalisation, a select keyboard-navigation reducer, an outside-click/scroll/resize handler, and

如何安装 @broberg/ui-controls-core?

在项目目录运行 npm install @broberg/ui-controls-core,或使用 pnpm add / yarn add / bun add。

@broberg/ui-controls-core 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@broberg/ui-controls-core 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@broberg/ui-controls-core 可以商用吗?

@broberg/ui-controls-core 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@broberg/ui-controls-core 的下载量有多少?

根据 npm 官方下载统计,@broberg/ui-controls-core 在 2026/10/09 – 2026/11/07 这 30 天内被下载 16,279 次,日均约 543 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@broberg/ui-controls-core 还在维护吗?

最新版本 0.3.0 发布于 2026/10/25(14 天前);至今共发布 6 个版本,其中过去 12 个月发布了 6 个;首次发布于 2026/07/12。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。