For AI agents: the complete documentation index is available at /ooui-react/en/llms.txt, the full documentation bundle is available at /ooui-react/en/llms-full.txt, and this page is available as Markdown at /ooui-react/en/guide/ooui.md.
  • English
  • Coming from OOUI

    ooui-react reimplements OOUI's interaction semantics and DOM contract while reusing the original theme CSS, but its API is idiomatic React.

    Whether you know OOUI and want to lean on that experience in a new script, or are rewriting an old, complex OOUI script, this page maps the two APIs: start with the mental model mapping, locate components by their original class names, then check the dropped capabilities and behavioral differences.

    Mental model mapping

    The original imperative API is uniformly expressed as declarative props in this library; see Controlled and uncontrolled for the rules:

    Originalooui-react
    setValue / setDisabled / setPage settersControlled props such as value / defaultValue / onChange
    WindowManager.openWindow / closeWindowThe Dialog family takes a required open prop only; close intent is reported via onEscape and other callbacks, see Dialogs must be controlled
    updateState / choose / toggle eventsCallback props such as onChange / onChoose / onOpenChange
    OO.ui.msg global and OO.ui.deferMsgThe messages config and useMessage of OOUIProvider, see Global configuration
    OO.ui.isMobile() (stub that always returns false)The isMobile config of OOUIProvider
    OO.ui.HtmlSnippet (raw-output wrapper)Write ReactNode directly; strings are escaped by default, and there is no dedicated wrapper for raw HTML — use dangerouslySetInnerHTML yourself and own the risk
    OO.ui.Theme runtime object (getElementClasses hooks)None. Class names are emitted by components following wikimediaui semantics; theme styles come from site CSS. Under third-party themes such as apex a few state classes appear that the original would not output (e.g. progressive coloring on selected options) — a known deviation
    ToolFactory / ToolGroupToolFactory registrationDeclarative data: pass a tools array to the toolbar and nest tool groups as React elements, see Toolbar

    Locating components and classes

    Component names = original class names minus the Widget suffix (ButtonWidget → Button, TextInputWidget → TextInput). Four names do not survive the suffix removal and keep their original form: SearchWidget, HiddenInputWidget, SelectFileInputWidget, ButtonMenuSelectWidget.

    Some original classes do not map to standalone components:

    Original classWhere it went
    OO.ui.WindowManagerEach Dialog component owns its open/close state (controlled open); content isolation and stacking are built in. Imperative confirm / alert / prompt need no manager
    OO.ui.ActionWidget / ActionSet / OO.ui.ErrorInlined into ProcessDialog: the action array, mode filtering and the error panel, see Process dialog
    OO.ui.ProcessThe onAction async callback; rewrite .next() chains as one async function
    OO.ui.OutlineControlsWidgetInlined into BookletLayout's outline panel, see Booklet layout
    OO.ui.SelectWidgetSelect
    OO.ui.PopupTagMultiselectWidget (deprecated upstream)Not provided; use MenuTagMultiselect
    OO.ui host-environment utilities (bind / infuse / getUserLanguages / generateElementId / debounce etc.)Not mapped: React capabilities, useId and es-toolkit cover these scenarios

    Dropped capabilities

    The following original capabilities are intentionally not implemented, indexed by original API name:

    Original capabilityWhat to do instead
    href on TabOptionNot supported (the original only used it from PHP); compose link tabs yourself, see Tab select
    allowLinebreaks / enter on MultilineTextInputWidgetLine breaks are always allowed; strip them yourself when you need to forbid them, see Multiline text input
    config.input / inputWidget on TagMultiselectWidgetThe input is built in and cannot be replaced
    config.input on LabelWidgetUse htmlFor for fields with an id, otherwise let FieldLayout wire the association, see Label
    ActionSet.static.specialFlags subclass overrideSpecial actions are fixed to safe / primary; declare them via flags
    align='inline' downgrade check on FieldLayoutNo automatic downgrade; make sure the field root element is inline before passing inline
    flags on plain-label options (Tab / Radio / CheckboxMultioption)flags is only available on option forms with icon slots, see Selections and options
    Automatic URL sanitizing (OO.ui.isSafeUrl)Components never rewrite href / action; sanitize untrusted URLs yourself with the exported sanitizeUrl (the responsibility is on the caller and the backend), see Button

    Behavioral differences at a glance

    These behaviors differ from the original in ways that will break or surprise you if unaddressed, indexed by component. Details live on each component page:

    ComponentDifferenceDetails
    MessageThe close button only calls onClose and does not hide itself — if you ignore the callback the message cannot be dismissedMessage
    Bare DialogNo built-in title slot; render the title yourself and pass aria-labelledby, otherwise you get an unnamed dialogDialog
    Dialog familyAlways controlled: a required open prop, no defaultOpenControlled and uncontrolled
    confirm / alert / promptThe original silently drops the second call while a window is open; this library stacks them, each independently interactiveImperative dialogs
    prompttextInput.value is initial-only; it cannot be changed externally while the dialog is aliveImperative dialogs
    Toolbar toolsVisible text and tooltip split from one title key into label + title (pass the old narrowConfig.title value as label)Toolbar
    ToolbarDo not put popup tools inside List / Menu groups: the popup anchor dies with the collapsed panel and ends up misplaced at the viewport's top-left cornerToolbar
    TagMultiselectTag identity is a scalar value; carry objects via the data field and look them up by valueTag multiselect
    Dropdown / ButtonMenuSelectWidgetSpace selects the highlighted option while open (the original ignored Space and only closed the menu via key-press click emulation)Dropdown
    PopupRe-evaluates the flip direction when scrolling changes clipping (the original freezes it until reopened); the popup may jump while scrollingPopup

    Imperative dialogs

    confirm / alert / prompt are standalone functions you can await from any event handler; the dialogs inherit the enclosing OOUIProvider configuration (messages, isMobile, dir and your own providers). Unlike the original's shared singleton manager, repeated calls stack. See Imperative dialogs for the runtime semantics and Global configuration for config inheritance.

    Localization

    en is the built-in default baseline; 25 more language packs (ooui-react/locales/<code>) are available as optional imports. On a MediaWiki site you can wire mw.msg into messages to follow the site language. See Messages and i18n for the language list and setup.

    Full deviation ledger

    This page lists only the differences that affect usage. The complete ledger (including implementation-level trade-offs and rationale) lives in the repository's dev-docs/DEVIATIONS.md.