--- url: https://ooui-react.pages.dev/guide/usage.md --- > For AI agents: the complete documentation index is available at https://ooui-react.pages.dev/llms.txt, the full documentation bundle is available at https://ooui-react.pages.dev/llms-full.txt. # 使用方式 ## 安装 ```sh [npm] npm install ooui-react ``` ```sh [yarn] yarn add ooui-react ``` ```sh [pnpm] pnpm add ooui-react ``` ```sh [bun] bun add ooui-react ``` ```sh [deno] deno add npm:ooui-react ``` 需 React 版本 ≥ 18。 ## 运行环境 - **面向浏览器运行,不支持服务端渲染(SSR)**:浮层组件(`Popup`、`Dropdown` 一类菜单、工具栏弹出面板)在 render 期解析 portal 容器并 `createPortal`,服务端没有 `document` 时直接抛错。用 Next.js 一类同构框架时,把这些组件挡在服务端渲染树之外,或仅在客户端挂载后再渲染。 - **同时提供 ESM 与 CJS 两份产物,二者是独立模块实例**:Node 进程内混用 `import` 与 `require` 加载时,语言消息注册表与 `OOUIProvider` context 互不共享;浏览器打包场景不受影响。 在非 MediaWiki 站点使用时,样式需自行引入 OOUI 的主题 CSS 与 Codex 设计令牌表(oojs-ui 0.54 起令牌表须一并引入)。主题 CSS 二选一:wikimediaui 为当前默认,apex 为遗留主题(两主题下部分状态的观感不同,本组件库输出对两者均有效): ```js import "@wikimedia/codex-design-tokens/dist/theme-wikimedia-ui.css"; // 主题二选一: import "oojs-ui/dist/oojs-ui-wikimediaui.css"; import "oojs-ui/dist/oojs-ui-apex.css"; ``` OOUI 主题的尺寸以 MediaWiki 的正文基准字号 14px 为准,宿主页面应保持一致。 :::tip 本站导航栏提供「示例主题」切换器,可在 wikimediaui 与 apex 下预览全部实时示例;组件库本身不自带样式,切到哪个主题即还原哪个主题下的观感。 ::: ## 在 MediaWiki 站点使用 本组件库开发的初衷就是用于 MediaWiki 站点的用户小工具。如果对产物体积较为敏感,建议[使用 Preact 兼容层](#preact-兼容)代替完整的 React。 使用示例可见[我的萌娘百科工具仓库](https://github.com/BearBin1215/MoegirlPedia): - [`src/gadgets/AdvancedSearch`](https://github.com/BearBin1215/MoegirlPedia/tree/master/src/gadgets/AdvancedSearch) - [`src/gadgets/DynamicRecentChanges`](https://github.com/BearBin1215/MoegirlPedia/tree/master/src/gadgets/DynamicRecentChanges) - [`src/gadgets/FileInspector`](https://github.com/BearBin1215/MoegirlPedia/tree/master/src/gadgets/FileInspector) ### 声明依赖 MediaWiki 站点的 OOUI 样式由其内置的 `oojs-ui` 资源模块提供,运行时通过 `mw.loader.using` 或小工具的 ResourceLoader 定义里引入: ```ts mw.loader.using([ "oojs-ui", // 加载 OOUI 基础样式 "oojs-ui.styles.icons-media", // 加载 OOUI 对应图标组的 CSS ]); ``` 其中图标组的组名见[图标索引](https://ooui-react.pages.dev/components/icon/index.md#%E5%85%A8%E9%83%A8%E5%9B%BE%E6%A0%87)里的分组。 ### 挂载 建议渲染到 `div` 或 `DocumentFragment` 元素,然后插到锚点前后: **index.tsx** ```tsx import React from "react"; import { createRoot } from "react-dom/client"; import App from "./App"; $(async () => { await mw.loader.using(["oojs-ui"]); const fragment = document.createDocumentFragment(); createRoot(fragment).render(); // 例:添加到最近更改列表前 document.querySelector(".mw-changeslist")!.before(fragment); }); ``` **App.tsx** ```tsx import { Button } from "ooui-react"; function App() { return ; } export default App; ``` ## Preact 兼容 本库可在 Preact 兼容层(`preact/compat`)下运行,映射方法参考[官方指南](https://preactjs.com/guide/getting-started/#aliasing-react-to-preact)。 - 版本门槛 Preact ≥ 10.18,10.x 与 11.x 均兼容。 - `react-dom/client` 须映射到 `preact/compat/client`,缺失时命令式 API(confirm / alert / prompt)会缺失 `createRoot` 而报错。 ## 与 AI 协作 本文档站已开启 `llms` 支持,除每页标题下方的复制 Markdown 等入口外,同步发布两份面向 LLM 的纯文本文件: - [llms.txt](https://ooui-react.pages.dev/llms.txt):索引文件,包含文档站各页面的说明和链接 ``` https://ooui-react.pages.dev/llms.txt ``` - [llms-full.txt](https://ooui-react.pages.dev/llms-full.txt):合并了本文档站的全部中文内容 ``` https://ooui-react.pages.dev/llms-full.txt ``` 英文站内容对应 `/en/llms.txt` 与 `/en/llms-full.txt`。引用单页时,在页面地址后追加 `.md` 也可获得该页的纯 Markdown 版本。 可按需将上述链接复制给你的 agent。 --- url: https://ooui-react.pages.dev/guide/ooui.md --- > For AI agents: the complete documentation index is available at https://ooui-react.pages.dev/llms.txt, the full documentation bundle is available at https://ooui-react.pages.dev/llms-full.txt. # OOUI 对照 ooui-react 按 OOUI 的交互语义与 DOM 结构重新实现,样式直接复用原版主题 CSS,但 API 是地道的 React 形态。 无论你熟悉 OOUI、想照着原有的使用经验写新脚本,还是要重写旧的复杂脚本,本页都给出两套 API 的对应关系:先看概念映射,再按原版类名找到对应组件,最后核对能力舍弃与行为差异。 ## 概念映射 原版的命令式 API 在本工程统一改写为声明式 props,规则详见[受控与非受控](https://ooui-react.pages.dev/guide/controlled.md): | 原版 | 本工程 | | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `setValue` / `setDisabled` / `setPage` 等 setter | `value` / `defaultValue` / `onChange` 等受控 props | | `WindowManager.openWindow` / `closeWindow` | Dialog 家族只有必填 `open` prop,关闭意图经 `onEscape` 等回调报出,见[弹窗必须受控](https://ooui-react.pages.dev/guide/controlled.md#%E5%BC%B9%E7%AA%97%E5%BF%85%E9%A1%BB%E5%8F%97%E6%8E%A7) | | `updateState` / `choose` / `toggle` 等事件 | `onChange` / `onChoose` / `onOpenChange` 等回调 props | | `OO.ui.msg` 全局与 `OO.ui.deferMsg` | `OOUIProvider` 的 `messages` 配置与 `useMessage`,见[全局配置](https://ooui-react.pages.dev/guide/configuration.md) | | `OO.ui.isMobile()`(始终返回 `false` 的桩函数) | `OOUIProvider` 的 `isMobile` 配置 | | `OO.ui.HtmlSnippet`(不转义包装类) | 直接写 `ReactNode`;字符串默认转义,要原样输出 HTML 只能自行使用 `dangerouslySetInnerHTML`,并自行承担风险 | | `OO.ui.Theme` 运行时对象(`getElementClasses` 等钩子) | 无。类名由组件按 wikimediaui 语义直接输出,主题样式由站点 CSS 提供;apex 等第三方主题下会多出少量状态类(如选项选中态的 progressive 着色),属已知偏差 | | `ToolFactory` / `ToolGroupToolFactory` 等工厂注册 | 声明式数据:工具栏传 `tools` 数组、内嵌工具组直接给 React 元素,见[工具栏](https://ooui-react.pages.dev/components/toolbar/index.md) | ## 组件寻址与类映射 组件名 = 原版类名去掉 `Widget` 后缀(`ButtonWidget` → `Button`、`TextInputWidget` → `TextInput`)。有几个组件名去掉后缀后不成立,保留原样:`SearchWidget`、`HiddenInputWidget`、`SelectFileInputWidget`、`ButtonMenuSelectWidget`。 原版里一些类不对应独立组件,处理方式如下: | 原版类 | 处理方式 | | ----------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- | | `OO.ui.WindowManager` | 各 Dialog 组件自持开合(受控 `open`),弹窗内容隔离与层叠随组件内置;命令式 `confirm` / `alert` / `prompt` 不需要管理器 | | `OO.ui.ActionWidget` / `ActionSet` / `OO.ui.Error` | 内联进 `ProcessDialog`:动作数组、modes 过滤与错误面板,见[过程弹窗](https://ooui-react.pages.dev/components/process-dialog/index.md) | | `OO.ui.Process` | `onAction` 异步回调编排,多步 `.next()` 链改写为一个 async 函数 | | `OO.ui.OutlineControlsWidget` | 内联进 `BookletLayout` 的大纲面板,见[手册布局](https://ooui-react.pages.dev/components/booklet-layout/index.md) | | `OO.ui.SelectWidget` | [`Select`](https://ooui-react.pages.dev/components/select/index.md) | | `OO.ui.PopupTagMultiselectWidget`(原版已废弃) | 不提供,用 [MenuTagMultiselect](https://ooui-react.pages.dev/components/menu-tag-multiselect/index.md) | | `OO.ui` 宿主环境全局工具(`bind` / `infuse` / `getUserLanguages` / `generateElementId` / `debounce` / `Keys` / `MouseButtons` 等) | 不映射:React 自带的能力、`useId` 与 es-toolkit 已覆盖对应场景 | ## 能力舍弃清单 以下原版能力本工程有意不做,按原版 API 名检索: | 原版能力 | 替代做法 | | -------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | | `TabOption` 的 `href` 链接 | 不支持(原版仅 PHP 端在用),需要链接页签自行组合实现,见[页签选择](https://ooui-react.pages.dev/components/tab-select/index.md) | | `MultilineTextInputWidget` 的 `allowLinebreaks` / `enter` | 始终允许换行;禁止换行由调用方清洗输入值,见[多行输入框](https://ooui-react.pages.dev/components/multiline-text-input/index.md) | | `TagMultiselectWidget` 的 `config.input` / `inputWidget` | 输入框内置,不可替换 | | `LabelWidget` 的 `config.input` | 有 id 的字段用 `htmlFor`,其余统一由 FieldLayout 关联,见[标签](https://ooui-react.pages.dev/components/label/index.md) | | `ActionSet.static.specialFlags` 子类扩展 | 特殊动作固定为 `safe` / `primary`,经 `flags` 声明即可 | | `FieldLayout` 的 `align='inline'` 自动降级 | 不做降级校验,传入 `inline` 前保证字段根元素为内联形态 | | 纯标签选项(Tab / Radio / CheckboxMultioption)的 `flags` | `flags` 只在带图标槽位的选项形态开放,见[选择与选项](https://ooui-react.pages.dev/guide/options.md) | | `OO.ui.isSafeUrl` 自动净化 | 组件不改写 `href` / `action`;来源不可信的 URL 用导出的 `sanitizeUrl` 自行净化(安全责任在调用方与后端),见[按钮](https://ooui-react.pages.dev/components/button/index.md) | ## 行为差异速查 以下是使用行为会与原版**不同**、且不调整就会出错或与预期相反的差异,按组件速查。各组件页有对应细节: | 组件 | 差异 | 详见 | | ------------------------------------- | ---------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- | | `Message` | 关闭按钮只回调 `onClose`、不自行隐藏——漏接回调,消息就关不掉 | [消息](https://ooui-react.pages.dev/components/message/index.md) | | `Dialog`(裸用) | 无内置标题槽位,须自行渲染标题并传 `aria-labelledby`,漏传即无名弹窗 | [对话框](https://ooui-react.pages.dev/components/dialog/index.md) | | `Dialog` 家族 | 始终受控:只有必填 `open`,没有 `defaultOpen` | [受控与非受控](https://ooui-react.pages.dev/guide/controlled.md#%E5%BC%B9%E7%AA%97%E5%BF%85%E9%A1%BB%E5%8F%97%E6%8E%A7) | | `confirm` / `alert` / `prompt` | 原版已有窗口打开时第二层调用静默失效;本工程层叠显示、逐个可交互 | [命令式弹窗](https://ooui-react.pages.dev/components/imperative-dialogs/index.md) | | `prompt` | `textInput.value` 只作初始值,弹窗存活期间不可从外部修改 | [命令式弹窗](https://ooui-react.pages.dev/components/imperative-dialogs/index.md) | | `Toolbar` 工具 | 可见文本与 tooltip 从单个 `title` 拆为 `label` + `title`(`narrowConfig.title` 的值应改传 `label`) | [工具栏](https://ooui-react.pages.dev/components/toolbar/index.md) | | `Toolbar` | 弹出工具不要放进 List / Menu 组内:浮层锚点随面板收起失效,在本工程里会错位到视口左上角 | [工具栏](https://ooui-react.pages.dev/components/toolbar/index.md) | | `TagMultiselect` | 标签标识改为标量 `value`,对象数据改走 `data` 字段按值反查 | [标签输入](https://ooui-react.pages.dev/components/tag-multiselect/index.md) | | `Dropdown` / `ButtonMenuSelectWidget` | 展开态按空格直接选定高亮项(原版空格不被菜单消费、只经按键模拟关闭菜单) | [下拉选择](https://ooui-react.pages.dev/components/dropdown/index.md) | | `Popup` | 滚动引起裁剪变化时会重新判定翻转方向(原版冻结到下次打开),滚动过程中浮层可能跳动 | [浮层](https://ooui-react.pages.dev/components/popup/index.md) | ## 命令式弹窗 `confirm` / `alert` / `prompt` 是独立函数,从任意事件回调里 `await` 即可,弹窗自动继承所在 `OOUIProvider` 的配置(文案、`isMobile`、`dir` 及应用自有 Provider)。与原版共用单例管理器不同,本工程重复调用会层叠显示;返回值与运行时语义见[命令式弹窗](https://ooui-react.pages.dev/components/imperative-dialogs/index.md),配置继承见[全局配置](https://ooui-react.pages.dev/guide/configuration.md#%E5%91%BD%E4%BB%A4%E5%BC%8F%E5%BC%B9%E7%AA%97)。 ## 多语言 `en` 为内建默认基线,另提供 222 种语言包(`ooui-react/locales/<代码>`)按需引入;MediaWiki 站点可直接把 `mw.msg` 接进 `messages` 跟随站点语言。语言清单与接入方式见[文案与国际化](https://ooui-react.pages.dev/guide/configuration.md#%E6%96%87%E6%A1%88%E4%B8%8E%E5%9B%BD%E9%99%85%E5%8C%96)。 ## 完整差异清单 本页只列影响使用的差异。与原版的全部差异(含实现层取舍与论证)见仓库的 [`dev-docs/DEVIATIONS.md`](https://github.com/BearBin1215/ooui-react/blob/main/dev-docs/DEVIATIONS.md)。 --- url: https://ooui-react.pages.dev/guide/basics.md --- > For AI agents: the complete documentation index is available at https://ooui-react.pages.dev/llms.txt, the full documentation bundle is available at https://ooui-react.pages.dev/llms-full.txt. # 通用属性 本页是各组件页的公共前提,说明所有组件共有的属性规则与写入位置。组件特有的属性见对应组件页。 ## 属性透传 组件把本库未声明的属性原样透传到渲染出的根元素,`className`、`id`、`style`、`data-*`、`aria-*`、`onClick` 等可以直接写: ```tsx preview import { Button } from "ooui-react"; function App() { return (
); } export default App; ``` - 如果组件本身会往根元素固定写入同名属性,透传会失效,例如绝大多数组件的 `aria-disabled` 由 `disabled` 参数计算,手动指定无效。 - 原生 `defaultValue` / `defaultChecked` 不随透传写入 DOM。 ## ref 与内部元素 `ref` 指向根元素。要拿到内部元素或往内部元素传入属性,走组件提供的通道: | 通道 | 指向 / 作用 | 提供通道的组件 | | ------------------------------ | ----------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | | `inputRef` | 内部 `` / `