@wzrhine/react 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +80 -0
- package/LICENSE +21 -0
- package/README.md +37 -3
- package/dist/advanced.css +398 -0
- package/dist/archive.css +704 -0
- package/dist/command.css +671 -0
- package/dist/components/Accordion.d.ts +82 -0
- package/dist/components/Accordion.d.ts.map +1 -0
- package/dist/components/Accordion.js +19 -0
- package/dist/components/Accordion.js.map +1 -0
- package/dist/components/Alert.d.ts +60 -0
- package/dist/components/Alert.d.ts.map +1 -0
- package/dist/components/Alert.js +29 -0
- package/dist/components/Alert.js.map +1 -0
- package/dist/components/AlertDialog.d.ts +41 -0
- package/dist/components/AlertDialog.d.ts.map +1 -0
- package/dist/components/AlertDialog.js +101 -0
- package/dist/components/AlertDialog.js.map +1 -0
- package/dist/components/ArchiveCard.d.ts +58 -0
- package/dist/components/ArchiveCard.d.ts.map +1 -0
- package/dist/components/ArchiveCard.js +40 -0
- package/dist/components/ArchiveCard.js.map +1 -0
- package/dist/components/Breadcrumb.d.ts +48 -0
- package/dist/components/Breadcrumb.d.ts.map +1 -0
- package/dist/components/Breadcrumb.js +55 -0
- package/dist/components/Breadcrumb.js.map +1 -0
- package/dist/components/Button.d.ts +30 -0
- package/dist/components/Button.d.ts.map +1 -0
- package/dist/components/Button.js +24 -0
- package/dist/components/Button.js.map +1 -0
- package/dist/components/Checkbox.d.ts +81 -0
- package/dist/components/Checkbox.d.ts.map +1 -0
- package/dist/components/Checkbox.js +34 -0
- package/dist/components/Checkbox.js.map +1 -0
- package/dist/components/Collapsible.d.ts +47 -0
- package/dist/components/Collapsible.d.ts.map +1 -0
- package/dist/components/Collapsible.js +12 -0
- package/dist/components/Collapsible.js.map +1 -0
- package/dist/components/Combobox.d.ts +74 -0
- package/dist/components/Combobox.d.ts.map +1 -0
- package/dist/components/Combobox.js +61 -0
- package/dist/components/Combobox.js.map +1 -0
- package/dist/components/CommandPalette.d.ts +77 -0
- package/dist/components/CommandPalette.d.ts.map +1 -0
- package/dist/components/CommandPalette.js +150 -0
- package/dist/components/CommandPalette.js.map +1 -0
- package/dist/components/ContextMenu.d.ts +31 -0
- package/dist/components/ContextMenu.d.ts.map +1 -0
- package/dist/components/ContextMenu.js +25 -0
- package/dist/components/ContextMenu.js.map +1 -0
- package/dist/components/DataTable.d.ts +83 -0
- package/dist/components/DataTable.d.ts.map +1 -0
- package/dist/components/DataTable.js +97 -0
- package/dist/components/DataTable.js.map +1 -0
- package/dist/components/Dialog.d.ts +45 -0
- package/dist/components/Dialog.d.ts.map +1 -0
- package/dist/components/Dialog.js +46 -0
- package/dist/components/Dialog.js.map +1 -0
- package/dist/components/Drawer.d.ts +56 -0
- package/dist/components/Drawer.d.ts.map +1 -0
- package/dist/components/Drawer.js +92 -0
- package/dist/components/Drawer.js.map +1 -0
- package/dist/components/EmptyState.d.ts +39 -0
- package/dist/components/EmptyState.d.ts.map +1 -0
- package/dist/components/EmptyState.js +19 -0
- package/dist/components/EmptyState.js.map +1 -0
- package/dist/components/Field.d.ts +37 -0
- package/dist/components/Field.d.ts.map +1 -0
- package/dist/components/Field.js +12 -0
- package/dist/components/Field.js.map +1 -0
- package/dist/components/Fieldset.d.ts +24 -0
- package/dist/components/Fieldset.d.ts.map +1 -0
- package/dist/components/Fieldset.js +17 -0
- package/dist/components/Fieldset.js.map +1 -0
- package/dist/components/FileDropZone.d.ts +60 -0
- package/dist/components/FileDropZone.d.ts.map +1 -0
- package/dist/components/FileDropZone.js +121 -0
- package/dist/components/FileDropZone.js.map +1 -0
- package/dist/components/Form.d.ts +21 -0
- package/dist/components/Form.d.ts.map +1 -0
- package/dist/components/Form.js +20 -0
- package/dist/components/Form.js.map +1 -0
- package/dist/components/IconButton.d.ts +25 -0
- package/dist/components/IconButton.d.ts.map +1 -0
- package/dist/components/IconButton.js +14 -0
- package/dist/components/IconButton.js.map +1 -0
- package/dist/components/Input.d.ts +24 -0
- package/dist/components/Input.d.ts.map +1 -0
- package/dist/components/Input.js +15 -0
- package/dist/components/Input.js.map +1 -0
- package/dist/components/Menu.d.ts +66 -0
- package/dist/components/Menu.d.ts.map +1 -0
- package/dist/components/Menu.js +34 -0
- package/dist/components/Menu.js.map +1 -0
- package/dist/components/MetadataList.d.ts +51 -0
- package/dist/components/MetadataList.d.ts.map +1 -0
- package/dist/components/MetadataList.js +25 -0
- package/dist/components/MetadataList.js.map +1 -0
- package/dist/components/NumberField.d.ts +52 -0
- package/dist/components/NumberField.d.ts.map +1 -0
- package/dist/components/NumberField.js +21 -0
- package/dist/components/NumberField.js.map +1 -0
- package/dist/components/Pagination.d.ts +40 -0
- package/dist/components/Pagination.d.ts.map +1 -0
- package/dist/components/Pagination.js +64 -0
- package/dist/components/Pagination.js.map +1 -0
- package/dist/components/Popover.d.ts +44 -0
- package/dist/components/Popover.d.ts.map +1 -0
- package/dist/components/Popover.js +14 -0
- package/dist/components/Popover.js.map +1 -0
- package/dist/components/Progress.d.ts +57 -0
- package/dist/components/Progress.d.ts.map +1 -0
- package/dist/components/Progress.js +31 -0
- package/dist/components/Progress.js.map +1 -0
- package/dist/components/Radio.d.ts +61 -0
- package/dist/components/Radio.d.ts.map +1 -0
- package/dist/components/Radio.js +18 -0
- package/dist/components/Radio.js.map +1 -0
- package/dist/components/RecordHeader.d.ts +53 -0
- package/dist/components/RecordHeader.d.ts.map +1 -0
- package/dist/components/RecordHeader.js +19 -0
- package/dist/components/RecordHeader.js.map +1 -0
- package/dist/components/ScrollArea.d.ts +55 -0
- package/dist/components/ScrollArea.d.ts.map +1 -0
- package/dist/components/ScrollArea.js +63 -0
- package/dist/components/ScrollArea.js.map +1 -0
- package/dist/components/Select.d.ts +39 -0
- package/dist/components/Select.d.ts.map +1 -0
- package/dist/components/Select.js +24 -0
- package/dist/components/Select.js.map +1 -0
- package/dist/components/Separator.d.ts +26 -0
- package/dist/components/Separator.d.ts.map +1 -0
- package/dist/components/Separator.js +22 -0
- package/dist/components/Separator.js.map +1 -0
- package/dist/components/Skeleton.d.ts +31 -0
- package/dist/components/Skeleton.d.ts.map +1 -0
- package/dist/components/Skeleton.js +17 -0
- package/dist/components/Skeleton.js.map +1 -0
- package/dist/components/Slider.d.ts +65 -0
- package/dist/components/Slider.d.ts.map +1 -0
- package/dist/components/Slider.js +30 -0
- package/dist/components/Slider.js.map +1 -0
- package/dist/components/Spinner.d.ts +23 -0
- package/dist/components/Spinner.d.ts.map +1 -0
- package/dist/components/Spinner.js +13 -0
- package/dist/components/Spinner.js.map +1 -0
- package/dist/components/SplitButton.d.ts +59 -0
- package/dist/components/SplitButton.d.ts.map +1 -0
- package/dist/components/SplitButton.js +30 -0
- package/dist/components/SplitButton.js.map +1 -0
- package/dist/components/Stat.d.ts +53 -0
- package/dist/components/Stat.d.ts.map +1 -0
- package/dist/components/Stat.js +23 -0
- package/dist/components/Stat.js.map +1 -0
- package/dist/components/StatusBadge.d.ts +19 -0
- package/dist/components/StatusBadge.d.ts.map +1 -0
- package/dist/components/StatusBadge.js +8 -0
- package/dist/components/StatusBadge.js.map +1 -0
- package/dist/components/StatusIndicator.d.ts +29 -0
- package/dist/components/StatusIndicator.d.ts.map +1 -0
- package/dist/components/StatusIndicator.js +8 -0
- package/dist/components/StatusIndicator.js.map +1 -0
- package/dist/components/Surface.d.ts +29 -0
- package/dist/components/Surface.d.ts.map +1 -0
- package/dist/components/Surface.js +8 -0
- package/dist/components/Surface.js.map +1 -0
- package/dist/components/Switch.d.ts +22 -0
- package/dist/components/Switch.d.ts.map +1 -0
- package/dist/components/Switch.js +11 -0
- package/dist/components/Switch.js.map +1 -0
- package/dist/components/Tabs.d.ts +45 -0
- package/dist/components/Tabs.d.ts.map +1 -0
- package/dist/components/Tabs.js +49 -0
- package/dist/components/Tabs.js.map +1 -0
- package/dist/components/Text.d.ts +33 -0
- package/dist/components/Text.d.ts.map +1 -0
- package/dist/components/Text.js +21 -0
- package/dist/components/Text.js.map +1 -0
- package/dist/components/Textarea.d.ts +54 -0
- package/dist/components/Textarea.d.ts.map +1 -0
- package/dist/components/Textarea.js +31 -0
- package/dist/components/Textarea.js.map +1 -0
- package/dist/components/Timeline.d.ts +35 -0
- package/dist/components/Timeline.d.ts.map +1 -0
- package/dist/components/Timeline.js +13 -0
- package/dist/components/Timeline.js.map +1 -0
- package/dist/components/Toast.d.ts +67 -0
- package/dist/components/Toast.d.ts.map +1 -0
- package/dist/components/Toast.js +94 -0
- package/dist/components/Toast.js.map +1 -0
- package/dist/components/Tooltip.d.ts +26 -0
- package/dist/components/Tooltip.d.ts.map +1 -0
- package/dist/components/Tooltip.js +15 -0
- package/dist/components/Tooltip.js.map +1 -0
- package/dist/components/VisuallyHidden.d.ts +17 -0
- package/dist/components/VisuallyHidden.d.ts.map +1 -0
- package/dist/components/VisuallyHidden.js +12 -0
- package/dist/components/VisuallyHidden.js.map +1 -0
- package/dist/components/fieldParts.d.ts +17 -0
- package/dist/components/fieldParts.d.ts.map +1 -0
- package/dist/components/fieldParts.js +22 -0
- package/dist/components/fieldParts.js.map +1 -0
- package/dist/components/meter-utils.d.ts +15 -0
- package/dist/components/meter-utils.d.ts.map +1 -0
- package/dist/components/meter-utils.js +15 -0
- package/dist/components/meter-utils.js.map +1 -0
- package/dist/components/pagination-utils.d.ts +10 -0
- package/dist/components/pagination-utils.d.ts.map +1 -0
- package/dist/components/pagination-utils.js +36 -0
- package/dist/components/pagination-utils.js.map +1 -0
- package/dist/components.css +632 -0
- package/dist/data.css +600 -0
- package/dist/disclosure.css +93 -0
- package/dist/drawer.css +226 -0
- package/dist/feedback.css +454 -0
- package/dist/forms.css +516 -0
- package/dist/index.d.ts +117 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +61 -0
- package/dist/index.js.map +1 -0
- package/dist/motion/lifecycle.d.ts +44 -0
- package/dist/motion/lifecycle.d.ts.map +1 -0
- package/dist/motion/lifecycle.js +73 -0
- package/dist/motion/lifecycle.js.map +1 -0
- package/dist/motion/presence.d.ts +69 -0
- package/dist/motion/presence.d.ts.map +1 -0
- package/dist/motion/presence.js +103 -0
- package/dist/motion/presence.js.map +1 -0
- package/dist/motion/presets.d.ts +63 -0
- package/dist/motion/presets.d.ts.map +1 -0
- package/dist/motion/presets.js +30 -0
- package/dist/motion/presets.js.map +1 -0
- package/dist/motion/resolve.d.ts +31 -0
- package/dist/motion/resolve.d.ts.map +1 -0
- package/dist/motion/resolve.js +40 -0
- package/dist/motion/resolve.js.map +1 -0
- package/dist/motion/useRhineMotion.d.ts +19 -0
- package/dist/motion/useRhineMotion.d.ts.map +1 -0
- package/dist/motion/useRhineMotion.js +19 -0
- package/dist/motion/useRhineMotion.js.map +1 -0
- package/dist/motion/visibility.d.ts +6 -0
- package/dist/motion/visibility.d.ts.map +1 -0
- package/dist/motion/visibility.js +31 -0
- package/dist/motion/visibility.js.map +1 -0
- package/dist/overlays.css +465 -0
- package/dist/provider/RhineProvider.d.ts +65 -0
- package/dist/provider/RhineProvider.d.ts.map +1 -0
- package/dist/provider/RhineProvider.js +26 -0
- package/dist/provider/RhineProvider.js.map +1 -0
- package/dist/provider/messages.d.ts +190 -0
- package/dist/provider/messages.d.ts.map +1 -0
- package/dist/provider/messages.js +160 -0
- package/dist/provider/messages.js.map +1 -0
- package/dist/provider/portal.d.ts +17 -0
- package/dist/provider/portal.d.ts.map +1 -0
- package/dist/provider/portal.js +20 -0
- package/dist/provider/portal.js.map +1 -0
- package/dist/reset.css +45 -0
- package/dist/split.css +159 -0
- package/dist/status.css +353 -0
- package/dist/utils/cx.d.ts +2 -0
- package/dist/utils/cx.d.ts.map +1 -0
- package/dist/utils/cx.js +4 -0
- package/dist/utils/cx.js.map +1 -0
- package/package.json +62 -3
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# Changelog · @wzrhine/react
|
|
2
|
+
|
|
3
|
+
格式参考 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.1.0/),版本号遵循 [SemVer](https://semver.org/lang/zh-CN/)。`0.x` 阶段允许破坏性变更,但都会在这里写明,并附迁移说明(COMPONENTS.md「API 稳定政策」)。
|
|
4
|
+
|
|
5
|
+
## [Unreleased]
|
|
6
|
+
|
|
7
|
+
(暂无)
|
|
8
|
+
|
|
9
|
+
## [0.1.0] - 2026-10-12
|
|
10
|
+
|
|
11
|
+
首次发布(截至 M12 的全部变更)。
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
- **M1-A**:`Button`(primary / accent / secondary / ghost,sm / md / lg,loading 保持焦点并阻止重复提交)、`Surface`、`StatusBadge`;`motion/presets` 与 `useRhineMotion()`。
|
|
15
|
+
- **M1-B**:`Text`、`IconButton`(必须提供 `label` 或 `aria-labelledby`)、`Field`、`Input`。交互底座为 Base UI 1.8.0(ADR-0001)。
|
|
16
|
+
- **M2-A**:`RhineProvider`(主题作用域、弹层挂载点、减动策略、Tooltip 延迟)、`Tabs` / `TabList` / `Tab` / `TabPanel`、`Tooltip`、`Dialog` / `DialogClose`、`Select`。
|
|
17
|
+
- **M2-B**:`Popover` / `PopoverClose`、`Menu` 及其子项、`useToast` / `ToastViewport` / `ToastProvider`。`RhineProvider` 默认挂载通知队列。
|
|
18
|
+
- **M3**:`RecordHeader`、`MetadataList`、`ArchiveCard`、`StatusIndicator`、`Timeline`、`DataTable`。字段为空时自动隐藏,组件不会编造数据。
|
|
19
|
+
- **M5**:通过 `dist/` 发布 ESM 与 `.d.ts`;`publishConfig.exports` 提供 `.`、`./styles.css`、`./package.json`。
|
|
20
|
+
- **M7**:表单控件 `Textarea`(计数、自动增高)、`Checkbox`(含 indeterminate)、`CheckboxGroup`、`RadioGroup` / `Radio`、`Switch`、`Fieldset`、`Form`(提交时统一校验、聚焦第一个错误、`errors` 显示服务端错误),以及 `Separator`、`VisuallyHidden`。样式在新的 `forms.css` 中,由 `styles.css` 引入,无需额外导入。
|
|
21
|
+
- **M8**:`Pagination`(受控 / 非受控,当前页 `aria-current` 且可聚焦,`busy` 时保持焦点,窄容器紧凑模式)、`Breadcrumb`(折叠中间项、`renderLink` 接入路由)、`Progress`(含不确定态)、`Meter`(`low` / `high` / `optimum` 阈值,状态以文字表达)、`Stat`;辅助函数 `paginate`、`getPaginationItems`、`getMeterState`。`DataTable` 新增 `status`(loading / error)、`onRetry`、`emptyAction`、`pagination`,翻页保留调用方的选中集合。样式在 `data.css`,由 `styles.css` 引入。见 ADR-0005。
|
|
22
|
+
- **M9**:`AlertDialog`(`role="alertdialog"`,初始焦点在取消按钮;`onConfirm` 可返回 Promise,等待中不可取消,失败时保持打开并以 `role="alert"` 提示)、`Drawer` / `DrawerClose`(侧边面板,窄于 40rem 时为底部弹出,可滑动关闭)、`Alert`(`live` 显式选择 off / polite / assertive)、`Callout`(`role="note"`)、`EmptyState`、`Skeleton`、`Spinner`。`Dialog` 新增 `onCloseRequest(reason)` 关闭保护;`DataTable` 新增 `emptyDescription`;`ToastOptions` 新增 `id`(同 id 原地更新并重新计时)与 `action.keepOpen`,`ToastApi` 新增 `promise()`。样式在 `drawer.css`、`status.css`,由 `styles.css` 引入。见 ADR-0006。
|
|
23
|
+
- **M10(ADR-0007)**:Motion Core。`MotionPresence`(`fade` / `panel` / `rise` 预设,中途反向、隐藏后卸载)、`RhineMotionGroup` / `RhineMotionItem`(每项 24ms 错峰,总延迟上限 120ms,减动时无错峰无位移);`resolveMotion` 与 `useRhineMotion().resolve(kind, name)`:按属性类型减动(颜色 / 透明度保留不超过 120ms 的淡入,位移 / 布局直接到位,循环停止);`MotionSpeed` / `useMotionSpeed`(仅用于审查慢放);`useMotionLifecycle`(start / pause / resume / stop,页面隐藏、离开视口、减动时暂停并给出原因);`usePageVisible` / `useInViewport`(全库唯一的可见性来源);`useLatestGuard`(过期异步结果守卫);`transition.showcase` 预设(700ms,每个时长 token 现在都有同名预设)。`ArchiveCard` 新增可选 `motion="identity"` 与 `ArchiveIdentity`:记录编号从卡片连续移动到详情(`scene`,减动时直接切换),默认关闭。
|
|
24
|
+
|
|
25
|
+
- **M9.5(ADR-0008、ADR-0009)**:默认文案表 `RhineMessages` 与 `zhCN`(内置默认,逐字不变)/ `enUS`(参考译文)、`useRhineMessages()`、`RhineMessagesProvider`;`RhineProvider` 新增 `messages`、`locale`(数字格式,默认 `zh-CN`)与 `lang`(写到 `.rl-theme` 根元素)。此前无法覆盖的内置文字现在都可覆盖:DataTable 全选 / 行选择 / 已选摘要、Toast 关闭按钮与通知视口名称、Field「(可选)」、MetadataList「未记录」、Textarea 计数、Stat 的加载与方向文字、Meter 读屏值。`Progress` / `Meter` 新增 `locale` 属性。优先级:组件属性 > 最近 Provider 的 `messages` > `zhCN`。见 [locale.md](../../docs/components/locale.md)。
|
|
26
|
+
|
|
27
|
+
- **M12(ADR-0010)**:Collapsible(Base UI,高度过渡可中断)、Accordion / AccordionItem(`headingLevel`、单 / 多开)、Slider(刻度标签作为读屏值、范围滑块 `thumbLabels`)、NumberField(Field 语义、本地化格式、`aria-roledescription` 可覆盖)、ContextMenu(复用 Menu 部件;右键、长按、Shift+F10 / ContextMenu 键)、Combobox(分组、异步搜索、`filter={null}`、表单值)、CommandPalette(分组、`<mark>` 高亮、快捷键 `hotkey`、禁用原因;异步模式 `query` / `onQueryChange` / `loading`,命令 `meta` / `icon`)、FileDropZone(`accept` / `maxSize` / `maxFiles` 校验、拒绝原因 polite 播报)、SplitButton、ScrollArea(Base UI scroll-area,可聚焦 region,forced-colors 下保留原生滚动条)。`useRhineLocale` 改为公开导出。见 [advanced.md](../../docs/components/advanced.md)、[command.md](../../docs/components/command.md)。
|
|
28
|
+
|
|
29
|
+
### Changed(M12,非破坏性)
|
|
30
|
+
- `RhineMessages` 新增命名空间(见 UPGRADING 第 13 条);`size-budget.json` 中 react-full / react-css 预算上调([SIZE.md](../../docs/development/SIZE.md))。
|
|
31
|
+
|
|
32
|
+
### Fixed(M12)
|
|
33
|
+
- ContextMenu:Firefox 不会为聚焦元素派发 `contextmenu`,现在显式处理 Shift+F10 / ContextMenu 键。
|
|
34
|
+
|
|
35
|
+
### Changed(M9.5)
|
|
36
|
+
- **破坏性(声明层面,ADR-0008)**:peer `react` / `react-dom` 由 `^18.2.0 || ^19.0.0` 收窄为 `^19.0.0`。React 18 项目安装时会收到 peer 冲突提示;此前也未正式支持 React 18。
|
|
37
|
+
- 迁移:升级到 React 19。
|
|
38
|
+
- 运行时使用 React 的模块在产物首行带 `'use client'`,Next.js App Router 的服务端组件可以直接导入组件,不再需要包装文件;需要函数 props 的组件(如 DataTable)仍要放在使用者自己的 `'use client'` 文件中。
|
|
39
|
+
- `paginate`、`getPaginationItems`、`getMeterState` 移到不带指令的纯模块,服务端组件可以直接调用;从入口导入的写法不变。
|
|
40
|
+
- 默认文案改为从文案表读取,默认输出逐字不变(既有单测、SSR 示例与视觉基线保证);组件源码中不再出现中文字面量(package-boundary 测试)。
|
|
41
|
+
|
|
42
|
+
### Changed
|
|
43
|
+
- **破坏性(M1-A,ADR-0003)**:`variant="primary"` 由橙底改为深墨底;橙色信号改用新增的 `variant="accent"`。
|
|
44
|
+
- 迁移:原本需要橙色强调的按钮改为 `variant="accent"`;其余不用改。
|
|
45
|
+
- **破坏性(M1-A,ADR-0002)**:入口不再自动引入 CSS。
|
|
46
|
+
- 迁移:在应用入口显式导入 `@wzrhine/tokens/styles.css` 和 `@wzrhine/react/styles.css`。
|
|
47
|
+
- **M2-B**:Popover、Menu、Select、Tooltip 改为 fixed 定位,打开浮层时不再导致页面滚动。
|
|
48
|
+
- **M7 前**:交互底座 Base UI 1.8.0 → 1.9.0(ADR-0001 修订)。上游修复覆盖本项目全部包裹模块(Menu focus guard、Popover/Tooltip 过渡完成判定、Select 大列表性能、Tabs 函数值、Toast 计时器、Field `defaultValue` 告警等),传递依赖 `@base-ui/utils` 0.4.0 → 0.5.0。公开 API 无变化(`api:check` 无漂移),对使用者无需任何改动。
|
|
49
|
+
|
|
50
|
+
### Changed(M9)
|
|
51
|
+
- **行为变化**:点击 Toast 的操作按钮后,默认关闭该通知(此前保持打开)。
|
|
52
|
+
- 迁移:需要旧行为时传 `action: { label, onClick, keepOpen: true }`。
|
|
53
|
+
- 带操作且未指定 `timeout` 的 Toast 至少停留 10 秒(`max(toastTimeout, 10000)`;`toastTimeout=0` 时仍为 0)。
|
|
54
|
+
- `ToastProvider` 由 Base UI Provider 的别名改为包装组件,属性不变。
|
|
55
|
+
- `Button` 的加载指示、`DataTable` 的首次加载骨架与空状态、`Stat` 的加载骨架改由 `Spinner` / `Skeleton` / `EmptyState` 渲染。原有类名保留,外观不变(既有视觉基线组件区域零差异);元素额外带 `rl-spinner` / `rl-skeleton` / `rl-empty` 类。
|
|
56
|
+
|
|
57
|
+
### Changed(M10,非破坏性)
|
|
58
|
+
- `useRhineMotion()` 返回值增加 `speed` 与 `resolve`;`get(name)` 行为不变(减动时一律 `instant`)。
|
|
59
|
+
- 减动下的淡入回退不再受 `MotionSpeed` 慢放影响,始终不超过 `fast`。
|
|
60
|
+
|
|
61
|
+
### Changed(M8,非破坏性)
|
|
62
|
+
- `RecordHeader` 的位置路径改由 `Breadcrumb` 渲染(`maxItems={0}`,从不折叠)。外观不变(既有视觉基线零像素差异),结构与语义不变;`<nav class="rl-record__trail">` 现在同时带 `rl-breadcrumb` 类,内部元素带 `rl-breadcrumb__*` 类。`RecordTrailItem` 改为 `BreadcrumbItem` 的类型别名。
|
|
63
|
+
- 迁移:若用精确的 `class="rl-record__trail"` 字符串匹配服务端 HTML,或在样式里写了 `.rl-record__trail li` 等后代选择器,请改为匹配类名本身或改用 `.rl-breadcrumb__*`。
|
|
64
|
+
- `DataTable` 不传新属性时渲染结果与之前完全相同(单测断言);空状态文字改为在单元格中居中(此前因选择器特异性实际左对齐)。
|
|
65
|
+
|
|
66
|
+
### Changed(M7,非破坏性)
|
|
67
|
+
- `Field` 与新控件共用标签和错误部件,DOM 与外观不变(31 张既有视觉基线中组件区域零像素差异)。放在 `Form` 内并设置了 `name` 的 `Field` 会显示 `errors` 中对应的服务端错误。
|
|
68
|
+
|
|
69
|
+
### Fixed
|
|
70
|
+
- **M2-B**:`RhineProvider` 首次渲染时弹层可能挂到 `<body>`、拿不到主题的问题。
|
|
71
|
+
- **M3**:DataTable 视觉隐藏的表头会撑宽页面;窄容器中单元格被压成一字一行。
|
|
72
|
+
- **M6**:宿主页面的全局元素样式会改变组件外观,包括 `button` 的大写和字距、`table / th / td` 的边框和内距、`h2` 字体,以及在组件样式**之后**加载的 `* { box-sizing: content-box }`。新增 `reset.css`(由 `styles.css` 首先引入),只在 `rl-` 类上复位这些属性;组件根节点的 `box-sizing` 改为类级选择器。宿主自身样式不受影响(`examples/host-embed` 的 E2E 双向验证)。
|
|
73
|
+
- 迁移:通常无需改动。若曾借助宿主全局规则调整组件外观,请改为给组件传 `className`。
|
|
74
|
+
- **M6**:DataTable 渲染单元格时把 `key` 展开进 JSX,React 19 在开发模式与 SSR 中会输出告警。
|
|
75
|
+
|
|
76
|
+
### Requirements
|
|
77
|
+
- peer:`react` / `react-dom` ^19(M9.5 起),`motion` ^12。
|
|
78
|
+
- 所有弹层组件必须放在 `RhineProvider` 内。
|
|
79
|
+
|
|
80
|
+
升级步骤见 [UPGRADING.md](https://github.com/BaiZhi967/WzRhineLab-UI/blob/main/docs/development/UPGRADING.md)。
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 WhiteZhi
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,37 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
# @wzrhine/react
|
|
2
|
+
|
|
3
|
+
面向科研、档案类界面的 React 组件库:可访问性优先,交互底座为 Base UI,动效使用 `motion/react`,视觉全部由 `--rl-*` tokens 决定。
|
|
4
|
+
|
|
5
|
+
> 原创设计,非官方项目。MIT 许可证;`0.x` 阶段 API 可能调整。
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
pnpm add @wzrhine/react @wzrhine/tokens react react-dom motion
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
```tsx
|
|
12
|
+
import '@wzrhine/tokens/styles.css';
|
|
13
|
+
import '@wzrhine/react/styles.css';
|
|
14
|
+
import { Button, Field, Input, RhineProvider } from '@wzrhine/react';
|
|
15
|
+
|
|
16
|
+
export function App() {
|
|
17
|
+
return (
|
|
18
|
+
<RhineProvider theme="light">
|
|
19
|
+
<Field label="记录编号" description="格式 ARC-0000。">
|
|
20
|
+
<Input mono />
|
|
21
|
+
</Field>
|
|
22
|
+
<Button>保存记录</Button>
|
|
23
|
+
</RhineProvider>
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
- 入口没有 CSS 副作用:样式需要按上面的方式显式导入(ADR-0002)。
|
|
29
|
+
- Dialog、AlertDialog、Drawer、Select、Tooltip、Popover、Menu、Toast 必须放在 `RhineProvider` 内,才能继承主题和减动设置。
|
|
30
|
+
- 组件:Button、IconButton、Surface、StatusBadge、Text、Separator、VisuallyHidden、Field、Input、Textarea、Checkbox、CheckboxGroup、RadioGroup、Radio、Switch、Fieldset、Form、Tabs、Tooltip、Dialog、Select、Popover、Menu、Toast、RecordHeader、MetadataList、ArchiveCard、StatusIndicator、Timeline、DataTable,以及 Pagination、Breadcrumb、Progress、Meter、Stat,以及 AlertDialog、Drawer、Alert、Callout、EmptyState、Skeleton、Spinner。
|
|
31
|
+
- Motion Core(ADR-0007):动效预设 `transition` / `duration` / `ease`,`useRhineMotion()`(`reduced`、`resolve(kind, name)` 按属性类型减动),`MotionPresence`、`RhineMotionGroup` / `RhineMotionItem`,`useMotionLifecycle`、`usePageVisible`、`useInViewport`、`useLatestGuard`;`ArchiveCard motion="identity"` 与 `ArchiveIdentity`。见 [MOTION-PATTERNS.md](https://github.com/BaiZhi967/WzRhineLab-UI/blob/main/docs/design/MOTION-PATTERNS.md)。
|
|
32
|
+
|
|
33
|
+
文档:
|
|
34
|
+
- 组件说明:[docs/components](https://github.com/BaiZhi967/WzRhineLab-UI/blob/main/docs/components)
|
|
35
|
+
- API 参考(自动生成):[docs/api/react.md](https://github.com/BaiZhi967/WzRhineLab-UI/blob/main/docs/api/react.md)
|
|
36
|
+
- 变更记录与迁移:[CHANGELOG.md](./CHANGELOG.md)
|
|
37
|
+
- 许可证:[MIT](./LICENSE)
|
|
@@ -0,0 +1,398 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* WzRhineLab UI · advanced interaction (ADR-0010 §2): Accordion, Slider, NumberField, ContextMenu.
|
|
3
|
+
* Imported by components.css; tokens only. Accordion height follows the Collapsible recipe:
|
|
4
|
+
* Base UI writes `--accordion-panel-height`, a CSS transition reads it, so a toggle mid-flight
|
|
5
|
+
* reverses from the current height. Reduced motion zeroes the duration tokens (instant).
|
|
6
|
+
* The slider has no position transition: Base UI writes thumb / indicator positions while dragging.
|
|
7
|
+
* ContextMenu reuses the Menu classes (feedback.css) for identical styling.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
:is(.rl-accordion, .rl-slider, .rl-number-field) {
|
|
11
|
+
box-sizing: border-box;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
:where(.rl-accordion, .rl-slider, .rl-number-field) *,
|
|
15
|
+
:where(.rl-accordion, .rl-slider, .rl-number-field) *::before,
|
|
16
|
+
:where(.rl-accordion, .rl-slider, .rl-number-field) *::after {
|
|
17
|
+
box-sizing: border-box;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/* ---------- Accordion ---------- */
|
|
21
|
+
.rl-accordion {
|
|
22
|
+
display: grid;
|
|
23
|
+
min-width: 0;
|
|
24
|
+
border-top: var(--rl-border-width) solid var(--rl-border-default);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.rl-accordion__item {
|
|
28
|
+
min-width: 0;
|
|
29
|
+
border-bottom: var(--rl-border-width) solid var(--rl-border-default);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.rl-accordion__header {
|
|
33
|
+
margin: 0;
|
|
34
|
+
font: inherit;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.rl-accordion__trigger {
|
|
38
|
+
display: flex;
|
|
39
|
+
align-items: center;
|
|
40
|
+
gap: var(--rl-space-3);
|
|
41
|
+
width: 100%;
|
|
42
|
+
min-height: var(--rl-control-height-md);
|
|
43
|
+
margin: 0;
|
|
44
|
+
padding: var(--rl-space-2) var(--rl-space-2);
|
|
45
|
+
border: 0;
|
|
46
|
+
border-radius: var(--rl-radius-xs);
|
|
47
|
+
background: transparent;
|
|
48
|
+
color: var(--rl-fg-primary);
|
|
49
|
+
font: var(--rl-type-label);
|
|
50
|
+
text-align: start;
|
|
51
|
+
cursor: pointer;
|
|
52
|
+
transition: background-color var(--rl-motion-fast) var(--rl-ease-out);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
@media (hover: hover) {
|
|
56
|
+
.rl-accordion__trigger:not([data-disabled]):hover {
|
|
57
|
+
background: var(--rl-bg-hover);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.rl-accordion__trigger:focus-visible {
|
|
62
|
+
outline: var(--rl-focus-ring);
|
|
63
|
+
outline-offset: calc(var(--rl-focus-width) * -1);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.rl-accordion__trigger[data-disabled] {
|
|
67
|
+
color: var(--rl-fg-disabled);
|
|
68
|
+
cursor: not-allowed;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.rl-accordion__title {
|
|
72
|
+
flex: 1 1 auto;
|
|
73
|
+
min-width: 0;
|
|
74
|
+
overflow-wrap: anywhere;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.rl-accordion__meta {
|
|
78
|
+
flex: none;
|
|
79
|
+
max-width: 40%;
|
|
80
|
+
font: var(--rl-type-mono);
|
|
81
|
+
letter-spacing: var(--rl-tracking-mono);
|
|
82
|
+
color: var(--rl-fg-muted);
|
|
83
|
+
overflow-wrap: anywhere;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.rl-accordion__trigger[data-disabled] .rl-accordion__meta {
|
|
87
|
+
color: var(--rl-fg-disabled);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
.rl-accordion__chevron {
|
|
91
|
+
flex: none;
|
|
92
|
+
width: var(--rl-icon-size-md);
|
|
93
|
+
height: var(--rl-icon-size-md);
|
|
94
|
+
fill: none;
|
|
95
|
+
stroke: currentColor;
|
|
96
|
+
stroke-width: 1.75;
|
|
97
|
+
stroke-linecap: round;
|
|
98
|
+
stroke-linejoin: round;
|
|
99
|
+
color: var(--rl-fg-muted);
|
|
100
|
+
transition: rotate var(--rl-motion-fast) var(--rl-ease-out);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.rl-accordion__trigger[data-panel-open] .rl-accordion__chevron {
|
|
104
|
+
rotate: 180deg;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.rl-accordion__panel {
|
|
108
|
+
height: var(--accordion-panel-height);
|
|
109
|
+
overflow: hidden;
|
|
110
|
+
transition:
|
|
111
|
+
height var(--rl-motion-base) var(--rl-ease-out),
|
|
112
|
+
opacity var(--rl-motion-base) var(--rl-ease-out);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
.rl-accordion__panel[data-starting-style],
|
|
116
|
+
.rl-accordion__panel[data-ending-style] {
|
|
117
|
+
height: 0;
|
|
118
|
+
opacity: 0;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
.rl-accordion__content {
|
|
122
|
+
min-width: 0;
|
|
123
|
+
padding: 0 var(--rl-space-2) var(--rl-space-4);
|
|
124
|
+
font: var(--rl-type-body-sm);
|
|
125
|
+
color: var(--rl-fg-primary);
|
|
126
|
+
overflow-wrap: break-word;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/* ---------- Slider ---------- */
|
|
130
|
+
.rl-slider {
|
|
131
|
+
--rl-slider-track-height: var(--rl-space-1);
|
|
132
|
+
--rl-slider-thumb-size: var(--rl-icon-size-lg);
|
|
133
|
+
|
|
134
|
+
display: grid;
|
|
135
|
+
gap: var(--rl-space-2);
|
|
136
|
+
width: 100%;
|
|
137
|
+
min-width: 0;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
.rl-slider__header {
|
|
141
|
+
display: flex;
|
|
142
|
+
flex-wrap: wrap;
|
|
143
|
+
align-items: baseline;
|
|
144
|
+
justify-content: space-between;
|
|
145
|
+
gap: var(--rl-space-1) var(--rl-space-3);
|
|
146
|
+
min-width: 0;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
.rl-slider__label {
|
|
150
|
+
min-width: 0;
|
|
151
|
+
font: var(--rl-type-label);
|
|
152
|
+
color: var(--rl-fg-primary);
|
|
153
|
+
overflow-wrap: anywhere;
|
|
154
|
+
cursor: default;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
.rl-slider__value {
|
|
158
|
+
font: var(--rl-type-mono);
|
|
159
|
+
letter-spacing: var(--rl-tracking-mono);
|
|
160
|
+
color: var(--rl-fg-muted);
|
|
161
|
+
font-variant-numeric: tabular-nums;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
.rl-slider__control {
|
|
165
|
+
position: relative;
|
|
166
|
+
display: grid;
|
|
167
|
+
/* Row 1: a control-height hit area around the thin track; row 2 (implicit): marks. */
|
|
168
|
+
grid-template-rows: var(--rl-control-height-sm);
|
|
169
|
+
align-items: center;
|
|
170
|
+
/* Half a thumb of inset keeps thumbs at min / max inside the component box. */
|
|
171
|
+
margin: 0 calc(var(--rl-slider-thumb-size) / 2);
|
|
172
|
+
touch-action: none;
|
|
173
|
+
user-select: none;
|
|
174
|
+
cursor: pointer;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
.rl-slider__track {
|
|
178
|
+
position: relative;
|
|
179
|
+
height: var(--rl-slider-track-height);
|
|
180
|
+
border-radius: var(--rl-radius-round);
|
|
181
|
+
background: var(--rl-bg-subtle);
|
|
182
|
+
box-shadow: inset 0 0 0 var(--rl-border-width) var(--rl-border-strong);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
.rl-slider__indicator {
|
|
186
|
+
height: 100%;
|
|
187
|
+
border-radius: inherit;
|
|
188
|
+
background: var(--rl-bg-inverse);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
.rl-slider__thumb {
|
|
192
|
+
width: var(--rl-slider-thumb-size);
|
|
193
|
+
height: var(--rl-slider-thumb-size);
|
|
194
|
+
border: var(--rl-border-width-strong) solid var(--rl-bg-inverse);
|
|
195
|
+
border-radius: var(--rl-radius-round);
|
|
196
|
+
background: var(--rl-bg-surface);
|
|
197
|
+
box-shadow: var(--rl-shadow-raised);
|
|
198
|
+
transition:
|
|
199
|
+
border-color var(--rl-motion-fast) var(--rl-ease-out),
|
|
200
|
+
background-color var(--rl-motion-fast) var(--rl-ease-out);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
.rl-slider__thumb:has(:focus-visible) {
|
|
204
|
+
outline: var(--rl-focus-ring);
|
|
205
|
+
outline-offset: var(--rl-focus-offset);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
.rl-slider__thumb[data-dragging] {
|
|
209
|
+
background: var(--rl-bg-pressed);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
.rl-slider__marks {
|
|
213
|
+
position: relative;
|
|
214
|
+
height: var(--rl-space-2);
|
|
215
|
+
pointer-events: none;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
.rl-slider[data-has-marks] .rl-slider__marks {
|
|
219
|
+
/* Room for one line of tick labels below the ticks. */
|
|
220
|
+
height: calc(var(--rl-space-2) + var(--rl-space-6));
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
.rl-slider__mark {
|
|
224
|
+
position: absolute;
|
|
225
|
+
top: 0;
|
|
226
|
+
inset-inline-start: var(--rl-slider-mark-position);
|
|
227
|
+
display: grid;
|
|
228
|
+
justify-items: center;
|
|
229
|
+
gap: var(--rl-space-1);
|
|
230
|
+
translate: -50% 0;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
.rl-slider__tick {
|
|
234
|
+
width: var(--rl-border-width);
|
|
235
|
+
height: var(--rl-space-2);
|
|
236
|
+
background: var(--rl-border-strong);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
.rl-slider__mark-label {
|
|
240
|
+
font: var(--rl-type-meta);
|
|
241
|
+
color: var(--rl-fg-muted);
|
|
242
|
+
white-space: nowrap;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/* Edge labels align inward so they never overflow a narrow container. */
|
|
246
|
+
.rl-slider__mark[data-edge='start'] .rl-slider__mark-label {
|
|
247
|
+
translate: calc(50% - var(--rl-slider-thumb-size) / 2) 0;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
.rl-slider__mark[data-edge='end'] .rl-slider__mark-label {
|
|
251
|
+
translate: calc(-50% + var(--rl-slider-thumb-size) / 2) 0;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
.rl-slider__description {
|
|
255
|
+
margin: 0;
|
|
256
|
+
font: var(--rl-type-meta);
|
|
257
|
+
color: var(--rl-fg-muted);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
.rl-slider[data-disabled] .rl-slider__control {
|
|
261
|
+
cursor: not-allowed;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
.rl-slider[data-disabled] .rl-slider__label,
|
|
265
|
+
.rl-slider[data-disabled] .rl-slider__mark-label {
|
|
266
|
+
color: var(--rl-fg-muted);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
.rl-slider[data-disabled] .rl-slider__track {
|
|
270
|
+
background: var(--rl-bg-disabled);
|
|
271
|
+
box-shadow: inset 0 0 0 var(--rl-border-width) var(--rl-border-default);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
.rl-slider[data-disabled] .rl-slider__indicator {
|
|
275
|
+
background: var(--rl-fg-disabled);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
.rl-slider[data-disabled] .rl-slider__thumb {
|
|
279
|
+
border-color: var(--rl-fg-disabled);
|
|
280
|
+
background: var(--rl-bg-disabled);
|
|
281
|
+
box-shadow: none;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/* ---------- NumberField ---------- */
|
|
285
|
+
.rl-number-field__root {
|
|
286
|
+
min-width: 0;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
.rl-number-field__group {
|
|
290
|
+
/* Steppers sit flush inside the input frame. */
|
|
291
|
+
gap: 0;
|
|
292
|
+
padding: 0;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
.rl-number-field__input {
|
|
296
|
+
padding: 0 var(--rl-input-padding-x);
|
|
297
|
+
text-align: center;
|
|
298
|
+
font-variant-numeric: tabular-nums;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
.rl-number-field__unit {
|
|
302
|
+
padding-inline-end: var(--rl-input-padding-x);
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
.rl-number-field__stepper {
|
|
306
|
+
display: inline-grid;
|
|
307
|
+
place-items: center;
|
|
308
|
+
flex: none;
|
|
309
|
+
width: calc(var(--rl-input-height) - var(--rl-border-width) * 2);
|
|
310
|
+
height: calc(var(--rl-input-height) - var(--rl-border-width) * 2);
|
|
311
|
+
margin: 0;
|
|
312
|
+
padding: 0;
|
|
313
|
+
border: 0;
|
|
314
|
+
background: transparent;
|
|
315
|
+
color: var(--rl-fg-primary);
|
|
316
|
+
cursor: pointer;
|
|
317
|
+
transition: background-color var(--rl-motion-fast) var(--rl-ease-out);
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
.rl-number-field__stepper[data-position='start'] {
|
|
321
|
+
border-inline-end: var(--rl-border-width) solid var(--rl-border-default);
|
|
322
|
+
border-start-start-radius: calc(var(--rl-radius-md) - var(--rl-border-width));
|
|
323
|
+
border-end-start-radius: calc(var(--rl-radius-md) - var(--rl-border-width));
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
.rl-number-field__stepper[data-position='end'] {
|
|
327
|
+
border-inline-start: var(--rl-border-width) solid var(--rl-border-default);
|
|
328
|
+
border-start-end-radius: calc(var(--rl-radius-md) - var(--rl-border-width));
|
|
329
|
+
border-end-end-radius: calc(var(--rl-radius-md) - var(--rl-border-width));
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
.rl-number-field__stepper > svg {
|
|
333
|
+
width: var(--rl-icon-size-md);
|
|
334
|
+
height: var(--rl-icon-size-md);
|
|
335
|
+
fill: none;
|
|
336
|
+
stroke: currentColor;
|
|
337
|
+
stroke-width: 1.75;
|
|
338
|
+
stroke-linecap: round;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
@media (hover: hover) {
|
|
342
|
+
.rl-number-field__stepper:not(:disabled, [aria-disabled='true']):hover {
|
|
343
|
+
background: var(--rl-bg-hover);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
.rl-number-field__stepper:not(:disabled, [aria-disabled='true']):active {
|
|
348
|
+
background: var(--rl-bg-pressed);
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
.rl-number-field__stepper:is(:disabled, [aria-disabled='true']) {
|
|
352
|
+
color: var(--rl-fg-disabled);
|
|
353
|
+
cursor: not-allowed;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
/* ---------- ContextMenu ---------- */
|
|
357
|
+
.rl-context-menu__trigger {
|
|
358
|
+
-webkit-touch-callout: none;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
.rl-context-menu__trigger:focus-visible {
|
|
362
|
+
outline: var(--rl-focus-ring);
|
|
363
|
+
outline-offset: var(--rl-focus-offset);
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
.rl-context-menu__trigger[data-popup-open] {
|
|
367
|
+
background-color: var(--rl-bg-hover);
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
/* ---------- Reduced motion ---------- */
|
|
371
|
+
.rl-theme[data-rl-motion='reduce'] :is(.rl-accordion__panel, .rl-accordion__chevron) {
|
|
372
|
+
transition: none;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
@media (prefers-reduced-motion: reduce) {
|
|
376
|
+
:is(.rl-accordion__panel, .rl-accordion__chevron) {
|
|
377
|
+
transition: none;
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
/* ---------- Forced colours (Windows High Contrast) ---------- */
|
|
382
|
+
@media (forced-colors: active) {
|
|
383
|
+
.rl-accordion,
|
|
384
|
+
.rl-accordion__item { border-color: CanvasText; }
|
|
385
|
+
.rl-accordion__trigger:focus-visible,
|
|
386
|
+
.rl-slider__thumb:has(:focus-visible),
|
|
387
|
+
.rl-context-menu__trigger:focus-visible { outline-color: Highlight; }
|
|
388
|
+
.rl-accordion__trigger[data-disabled] { color: GrayText; }
|
|
389
|
+
.rl-slider__track { background: Canvas; box-shadow: inset 0 0 0 var(--rl-border-width) CanvasText; }
|
|
390
|
+
.rl-slider__indicator { background: Highlight; }
|
|
391
|
+
.rl-slider__thumb { border-color: ButtonText; background: ButtonFace; }
|
|
392
|
+
.rl-slider__tick { background: CanvasText; }
|
|
393
|
+
.rl-slider[data-disabled] .rl-slider__indicator { background: GrayText; }
|
|
394
|
+
.rl-slider[data-disabled] .rl-slider__thumb { border-color: GrayText; }
|
|
395
|
+
.rl-number-field__stepper { color: ButtonText; }
|
|
396
|
+
.rl-number-field__stepper:is(:disabled, [aria-disabled='true']) { color: GrayText; }
|
|
397
|
+
.rl-number-field__stepper[data-position] { border-color: FieldText; }
|
|
398
|
+
}
|