Guide
Updating installed components
Ouro HX components are copied into your project, so they're yours to edit. To take an upstream change, compare first, then decide.
1. Review the change
List the files the registry's current version would change:
npx shadcn@latest add @ouro/sheet --dry-runThen see the difference for each of those files by its path:
npx shadcn@latest add @ouro/sheet --diff src/components/ouro/sheet/sheet.tsxWithout the namespace, use
ourostack/ouro-ui/sheet#v1.2.13in place of@ouro/sheet. A bare--diffwithout a path can stop after the first few unchanged files, before the one you edited.2. Overwrite, then reapply your edits
The CLI replaces files; it doesn't merge. Commit first, so your edits are safe, then overwrite:
npx shadcn@latest add @ouro/sheet --overwritegit diffThe diff shows the upstream change and, mixed in, your own edits being removed. Bring back the ones you still want.
3. Run the tests that came with it
A component's unit tests, stories and end-to-end specs are its optional
-testsitem. If you installed them, update them with the component, then run them before you commit:npx shadcn@latest add @ouro/sheet @ouro/sheet-tests --overwriteTo add them, run the same command without
--overwrite.ouro-testsadds every component's tests.Upgrading from v0.1.0
v0.1.0 installed each component with its tests, and v0.2.0 moves some shared helpers to new files, so update every Ouro component in one go.upgrade-v0.1.0upgrade-v0.2.0 Run the commands in your app's root, the folder with
components.json. They find your folders the way shadcn does, from the aliases incomponents.jsonand thepathsin your tsconfig (npx shadcn@latest infoshows them), so they work in asrc/or anapp/layout as written.What changed, by version
What an app on v0.1.0 has to know beyond these steps.upgrade-test The release notes list every change.upgrade-releases
- **v0.2.0:** each component's tests became an optional
<name>-testsitem, some helpers moved to new files (step 4), and v0.1.0's self-referential theme lines can go (step 2).upgrade-v0.2.0 - **v0.3.0:** sheets and dialogs stack at
--ouro-layer, a z-index of 50 by default, instead of level 0, so an app element at z-index 1 to 49 that used to show above an open sheet or dialog now sits under it.upgrade-v0.3.0 Raise the token in a:rootrule of your own if your app has fixed bars above z-50 (see "Theme" in the README), and drop any portal z-index workaround. A controlledDialogopened by a touch or pen tap focuses its popup instead of its first input, andConfirmDialog'sfinalFocusapplies only after a confirmed action; drop workarounds for either. Every coverage hint is/* istanbul ignore … @preserve */, so a build plugin that kept the hints can go.upgrade-hints A-testsitem sets Vitest to^5. - **v0.3.1:** every component starts with
"use client", so Next.js App Router pages can render them, and the@ouronamespace serves the newest release instead ofmain.upgrade-v0.3.1 - **After v0.7.0:** a required field's
*is drawn with CSS on a new element around the label and is no longer a<span data-ouro-required>inside it, so tests that expected the label text "Email*" now find "Email".upgrade-v0.8.0 The clear, show-password and choose-date buttons in TextField and DatePicker are named by hidden text, notaria-label, so replacebutton[aria-label="…"]selectors with[data-ouro-clear],[data-ouro-show-password]or[data-ouro-choose-date]. The same goes for a file's remove button in FileField ([data-ouro-file-remove]), Combobox's clear and chip remove buttons ([data-ouro-combobox-clear],[data-ouro-combobox-chip-remove]) and NumberField's steppers ([data-ouro-increment],[data-ouro-decrement]). A remove button's hidden text holds the file or item name, so a loosegetByText("pasta.png")now finds it too; pass{ exact: true }.FieldLabel'sclassNamenow goes on the new element around the label, which also carries[data-ouro-required], and a group's labelidis on the inner<span>;style,id,data-*and handlers still go on the<label>. A numericsizeon TextField is now a type error and a development warning; set a width withclassName="w-40".FormErrorsvalues are nowErrorMessages | null | undefined, so code that readserrors.emailasstring | string[]no longer type checks until it handlesnulland React nodes.upgrade-v0.8.0 For action answers, importformErrorsfrom@/lib/ouro/form-answerand passerrors={formErrors(actionData, actionData?.errors)}from the initial render; this replaces the unreleased separateresultprop. It identifies equal new answers while keeping cleared fields masked on pending/client renders and rendering current uncleared messages. Cached/reused answers need{ key: acceptedAnswerKey }, changed on actual acceptance, not submit start. Raw records remain compatible but content-only. Reconstruct the value beside Form after JSON/spread/cloning or server-component transport: only messages serialize, not private identity; a safely transported acceptance key can identify the locally reconstructed answer. On a phone, a Link that is not in running text is now a box at least 44px tall and wide that takes its room in the layout, so a column of links grows; passinlineto a link in a sentence inside your own<div>or<span>.upgrade-link-box A Form's top message element exists only while there is a message. Component roots no longer setm-0, so a parent'sspace-y-*now spaces them; remove any margin you added to work around that.upgrade-v0.8.0 - **v0.8.0:** no component installs
ouro-base; add it once (step 1 does), and later adds leave your stylesheet alone.upgrade-v0.8.0 A component installs only the helpers it imports, one item per file inlib/ouro, and a-testsitem brings the tests of everything its component installs.upgrade-v0.8.0 The-testsitems no longer set a version for Vitest, Storybook or Playwright.upgrade-test-versions The specs importtestandexpectfrome2e/ouro-fixtures.ts, a file of yours (step 1).upgrade-v0.8.0lib/ouro/use-dev-warnings.tsis nowlib/ouro/use-dev-messages.ts(step 4).upgrade-v0.8.0 Earlier releases installed every helper inlib/ourowith any component, and an update deletes nothing: audit references before deleting unused historical helpers and their own tests (step 5).upgrade-v0.8.0OuroProvidernow comes only with the components that render links and withtooltip; your copy stays, and a new app addslib-ouro-providerby name.
- **After v0.8.2:**
ouroTestProjects({ page })also sizes the touch project's Playwright host, preventing Vitest 4 from scaling landscape touch frames.upgrade-touch-host The logical touch viewport still starts at 390x844 with mobile/touch input, but an explicitly enlarged host changes outer-window/screen dimensions and screen orientation; do not treat those as hardware-phone measurements.upgrade-touch-host Withoutpage, the touch host stays 390x844.upgrade-touch-host On Vitest 4, retain a host large enough for every requested test viewport, such as the Testing guide's 1600x1200 example.upgrade-touch-host
- **v1.0.0:** the first stable release keeps the component APIs, theme tokens, defaults and test-tool minimums from v0.8.4.upgrade-v1.0.0 An app already on v0.8.4 needs no component API migration: review the update with
--dry-runand--diff, then overwrite only the items it already uses and reapply its local edits.upgrade-v1.0.0 Runtime components and their optional-testsitems remain separate; keep your app-owned fixtures and test configuration. Apps on older releases still need the applicable migration steps above and below.
- **After v1.0.2:** sheets, and a Menu shown as a bottom sheet, read their shadow from
--ouro-shadow-sheet-<side>, and Checkbox's tick draws over--ouro-duration-draw, both of which only a freshouro-baseadds (step 1 adds it again); without it a sheet draws no shadow and the tick appears at once.upgrade-v1.1.0 Every other shadow reads shadcn's--shadow-*tokens, and headings and overlay titles--font-heading, so a theme that sets them now restyles Ouro too.upgrade-v1.1.0upgrade-theme-tokens
- **After v1.0.1:**
formErrorsnow declares its already-frozen message arrays readonly.upgrade-v1.0.2 Keep mutableFormErrorsandErrorMessagesfor raw builders; annotate returned snapshots asFormErrorValueorReadonlyFormErrors, or let their type infer. Form, EditSheet, fielderrorprops and the normalization helper accept readonly projections. This corrects a false mutation permission, so a snapshot no longer fits a mutable raw-map annotation.upgrade-v1.0.2 TypeScript'sArray.isArraynarrows toany[]and can bypass readonly; unchanged runtime freezing still rejects container mutation, without deeply freezing React nodes.
- **After v1.2.2:**
ButtonacceptsreloadDocumentfor a document request through an internalhref, and its downloads use a plain anchor likeLink's.upgrade-document-download A false or nulldownloadno longer forces document navigation; passreloadDocumentwhen a resource route needs it without a download.upgrade-document-download
- **After v1.2.4:** Select, Menu, Combobox, Popover, Tooltip, HoverCard and NavigationMenu open their popups at the end of
<body>unlessOuroProvideris given aportalContainer, and in development each warns once when it opens outside every landmark of a page with a<main>.upgrade-portal-container To keep popups in a landmark, makeconst popups = useRef<HTMLDivElement>(null), wrap the app in<OuroProvider portalContainer={popups}>and render<div ref={popups} />last inside<main>, outside any element with atransform,filterorcontain, which would clip or move the popups. In a Next.js App Router layout, which is a server component, put the provider and the ref in a small client component. Inside a dialog your app draws itself, wrap its content in<OuroProvider portalContainer={null}>so its popups open where Base UI puts them.upgrade-portal-null Dialogs, sheets and toasts still open at the end of<body>. The landmark warning goes toconsole.warn, so a test that fails on console output fails until the popups are in a landmark. SidebarLayout'sheadernow renders in a<header>, the page's banner, so remove a banner your page draws around SidebarLayout.upgrade-sidebar-header Thetesting/axekit has a newaudit, which fails every violation at any impact and every result axe could not decide unless it measures it, in both color schemes.upgrade-audit Theouro-testingitem now namesaxe-coreamong its devDependencies, so an update adds it to an app that lacks it.upgrade-axe-core
- **After v1.2.8:** the Toaster's Notifications region is no longer a live region: two live regions last inside it say each toast's message and description, the assertive one a
role="alert", so for its first seven seconds a toast's words are in the page twice.upgrade-toast-announcer Find a toast in a test by its role and name,getByRole("dialog", { name: "Saved" }), or"alertdialog"for a destructive toast, not withgetByText, and expect noaria-liveon the region. Dismiss buttons and destructive toasts are no longer hidden from screen readers while the stack is collapsed.upgrade-toast-reachable Thetesting/axekit'sauditnow leaves focus, the selection and every scroll position as it found them, and throws, naming what changed, when its Tab walk closes a popup it cannot open again; audit the page before that popup opens.upgrade-audit-leaves
0. Commit first
--overwritereplaces every Ouro file, including files you edited.upgrade-shadcn-add Commit before you start. Afterwards,git diffshows your own edits being overwritten, so reapply the ones you need.Review the diff of your Tailwind CSS file too, the one
components.jsonnames intailwind.css, because step 1 addsouro-base, the one item that writes there, andshadcn addrewrites more than Ouro's tokens. It adds@custom-variant dark (&:is(.dark *));when the file has no@custom-variant(shadcn@4.21.1 does this for any item with theme variables on Tailwind CSS v4), adds the tokens your file lacks to:root,.darkand@theme inline(among them--input,--radiusand the radius scale, if your theme has none), and collapses blank lines.upgrade-shadcn-css Keep the new lines and step 2's deletions, and revert the rest. After this upgrade no component add opens the file again.upgrade-v0.8.01. Update every Ouro component, with its tests
Update every Ouro component in your app, not only the items you typed: v0.1.0 added each component's dependencies too, so an app that added only
dialogalso hasbuttonandsheet. Each component is one.tsxfile in yourcomponents/ouro/folder (dialog/holdsdialogandconfirm-dialog, andtext/holdstextandheading).upgrade-v0.1.0 Add each one as<name>and<name>-tests, plusouro-base, in one command at the same ref, with--overwrite(without it the CLI stops to ask about each file). For the app that added onlydialog, that isouro-base button button-tests dialog dialog-tests sheet sheet-tests. No component installsouro-baseany more, so this is where your stylesheet gets the tokens added since v0.1.0.upgrade-v0.8.0This command finds the components, prints them and adds them. If it finds none, it stops before adding anythingupgrade-none; run it in the folder with
components.json. If you use the Ouro theme, addourostack/ouro-ui/ouro-theme#v1.2.13to theaddin it.( p() { npx shadcn@latest info --json | node -p "JSON.parse(require('fs').readFileSync(0, 'utf8')).config.resolvedPaths.$1"; }; ouro="$(p components)/ouro"; items=$(find "$ouro" -name '*.tsx' ! -name '*-parts.tsx' ! -name '*.test.tsx' ! -name '*.stories.tsx' 2>/dev/null | sed -E 's|.*/(.*)\.tsx$|\1|' | sort); [ -n "$items" ] || { echo "No Ouro components in $ouro. Run this in the folder with components.json." >&2; exit 1; }; echo "Updating: $(echo "$items" | paste -sd " " -)"; npx shadcn@latest add $(echo "$items" | sed -E 's|.*|ourostack/ouro-ui/&#v1.2.13 ourostack/ouro-ui/&-tests#v1.2.13|') ourostack/ouro-ui/ouro-base#v1.2.13 --overwrite )This keeps the tests v0.1.0 installed, deletes none of your files and adds no component you didn't have. shadcn may print
Skipped N files: (files might be identical, use --overwrite to overwrite)even with--overwrite: those files already equal the release's, so nothing was missed.upgrade-shadcn-add The-testsitems name Vitest, Storybook and Playwright without a version, so the versions in yourpackage.jsonstay as they are. v0.7.0's items still carry versions: after an add at v0.7.0, restore every test-tool version you had pinned (git diff package.json): Vitest and its companions, Playwright and Storybook.upgrade-v0.7.0 The tests need Vitest 4.1.11 or later, Playwright 1.58.1 or later and Storybook 10.2.10 or later; update those yourself if yours are older (the README's "Details" links the Testing page).upgrade-minimums The specs ine2e/ouronow importtestandexpectfrome2e/ouro-fixtures.ts, a file of yours: add it with the one lineexport { expect, test } from "@playwright/test";, or export your own fixtures from it.2. Remove the self-referential theme lines
v0.1.0 wrote a line into
@theme inlinefor each Ouro token that points at itself, such as--ouro-press-scale: var(--ouro-press-scale);, and--color-ouro-backdrop-color: var(--ouro-backdrop-color);.upgrade-self-reference Delete them from your Tailwind CSS file, the onecomponents.jsonnames intailwind.css. The values stay in:rootand.dark. This command finds the file and deletes the lines:perl -i -ne 'print unless /^\s*--(color-)?ouro-[\w-]+:\s*var\(--ouro-[\w-]+\);\s*$/' "$(npx shadcn@latest info --json | node -p "JSON.parse(require('fs').readFileSync(0, 'utf8')).config.resolvedPaths.tailwindCss")"3. Optional: drop Ouro's tests
To keep only the components, delete the files Ouro owns for its tests: the test, type-test and story files in your
components/ouro/andlib/ouro/folders, the test kit inlib/ouro/testingand the specs ine2e/ouro. The command stops if it can't find those folders.( p() { npx shadcn@latest info --json | node -p "JSON.parse(require('fs').readFileSync(0, 'utf8')).config.resolvedPaths.$1"; }; c="$(p components)/ouro"; l="$(p lib)/ouro"; [ -d "$c" ] && [ -d "$l" ] || { echo "No Ouro folders at $c and $l. Run this in the folder with components.json." >&2; exit 1; }; find "$c" "$l" \( -name '*.test.ts' -o -name '*.test.tsx' -o -name '*.test-d.ts' -o -name '*.stories.tsx' \) -delete; find "$l/testing" e2e/ouro -delete )Then remove the
ouroTestProjectsimport and call from your Vitest config. Only if Ouro's tests were the only tests using them, also deletevitest.config.ts,playwright.config.tsand.storybook/, and uninstallvitest,@vitest/browser-playwright,playwright,@playwright/test,storybookand@storybook/react-vitewith your package manager.4. Change imports of moved helpers
If your own code imports these helpers, change the import:
useOuro: fromlib/ouro/ouro-providertolib/ouro/use-ouro.sheetSides,sideWarning,sheetHint,iosBackdropandfooterClass: fromcomponents/ouro/sheet/sheet-partstocomponents/ouro/sheet/sheet-styles.dialogSizesanddialogSizeWarning: fromcomponents/ouro/dialog/dialog-partstocomponents/ouro/dialog/dialog-styles.alignClassesandcheckAlign: fromcomponents/ouro/text/texttocomponents/ouro/text/text-styles.useDevWarnings: fromlib/ouro/use-dev-warningstolib/ouro/use-dev-messages. Delete the oldlib/ouro/use-dev-warnings.ts; nothing imports it after step 1.
5. Delete the helpers nothing imports
Releases before v0.8.0 installed every helper in
lib/ourowith any component.upgrade-v0.8.0 From v0.8.0 a component installs only the helpers it imports, but an update deletes nothing.upgrade-v0.8.0 Remove unused historical helpers rather than excluding them from coverage.Before deleting anything, perform a read-only import/reference audit across the whole app, including scripts, tests, stories and configuration outside
src/. Use the app's actual tsconfig and bundler aliases to resolve references to each helper's full path. Check relative imports, explicit extensions, re-exports and dynamic imports too; an importing file with the same basename is still a different file. A text search forlib/ouro/<name>alone cannot prove a helper is unused.Delete a helper and its own tests only after verifying that no remaining app file or retained Ouro file references it (references from that helper's own tests do not require keeping an otherwise unused helper). Check again after each removal: another historical helper may have been used only by the one you removed. If a reference is unresolved or you cannot verify a file's use, keep it until you can. Keep
ouro-provider.tsxif you mean to use it and have not yet, and retain ambient declarations such asenv.d.tsthat the app's type check needs even without an import.Then type check and build your app. CI runs steps 1 to 3 on a v0.1.0 app, with these commands read from this file (
scripts/install-test.sh upgrade).upgrade-testClaim sources
- upgrade-test: scripts/install-test.sh; scripts/upgrade-note.mjs
verify:testExists(scripts/upgrade-note.test.mjs::the upgrade install test runs the note's commands and copies none)verify:ciJob(install-upgrade) - upgrade-releases: https://github.com/ourostack/ouro-ui/releases; .github/workflows/release.yml; scripts/release-commit.sh
verify:urlOk(https://github.com/ourostack/ouro-ui/releases)verify:fileLine(.github/workflows/release.yml, /scripts\/release-commit\.sh "\$VERSION"/)verify:fileLine(scripts/release-commit.sh, /changes\.mjs assemble/) - upgrade-v0.1.0: https://github.com/ourostack/ouro-ui/releases/tag/v0.1.0
verify:urlOk(https://github.com/ourostack/ouro-ui/releases/tag/v0.1.0) - upgrade-v0.2.0: https://github.com/ourostack/ouro-ui/releases/tag/v0.2.0
verify:urlOk(https://github.com/ourostack/ouro-ui/releases/tag/v0.2.0) - upgrade-v0.3.0: https://github.com/ourostack/ouro-ui/releases/tag/v0.3.0
verify:urlOk(https://github.com/ourostack/ouro-ui/releases/tag/v0.3.0)verify:fileLine(registry/ouro/theme/ouro-base.css, /--ouro-layer: 50;/) - upgrade-v0.3.1: https://github.com/ourostack/ouro-ui/releases/tag/v0.3.1
verify:urlOk(https://github.com/ourostack/ouro-ui/releases/tag/v0.3.1) - upgrade-v0.7.0: https://github.com/ourostack/ouro-ui/releases/tag/v0.7.0
verify:urlOk(https://github.com/ourostack/ouro-ui/releases/tag/v0.7.0) - upgrade-v0.8.0: https://github.com/ourostack/ouro-ui/releases/tag/v0.8.0
verify:urlOk(https://github.com/ourostack/ouro-ui/releases/tag/v0.8.0)verify:testExists(scripts/registry.test.mjs::only ouro-base and ouro-theme touch the app's stylesheet, and no other item installs them)verify:testExists(scripts/registry.test.mjs::each lib helper is its own item, so an item installs only the helpers it imports) - upgrade-v1.0.0: https://github.com/ourostack/ouro-ui/releases/tag/v1.0.0
verify:urlOk(https://github.com/ourostack/ouro-ui/releases/tag/v1.0.0) - upgrade-v1.0.2: https://github.com/ourostack/ouro-ui/releases/tag/v1.0.2
verify:urlOk(https://github.com/ourostack/ouro-ui/releases/tag/v1.0.2)verify:fileLine(registry/ouro/lib/ouro/form-answer.ts, /Snapshot arrays are readonly/) - upgrade-v1.1.0: https://github.com/ourostack/ouro-ui/releases/tag/v1.1.0
verify:urlOk(https://github.com/ourostack/ouro-ui/releases/tag/v1.1.0)verify:fileLine(registry/ouro/theme/ouro-base.css, /--ouro-shadow-sheet-/)verify:fileLine(registry/ouro/theme/ouro-base.css, /--ouro-duration-draw:/) - upgrade-document-download: https://github.com/ourostack/ouro-ui/releases/tag/v1.2.2; registry/ouro/components/ouro/button/button.test.tsx; registry/ouro/components/ouro/link/link.test.tsx
verify:urlOk(https://github.com/ourostack/ouro-ui/releases/tag/v1.2.2)verify:testExists(registry/ouro/components/ouro/button/button.test.tsx::link branch > uses the document for reloadDocument and downloads, retaining router navigation otherwise)verify:testExists(registry/ouro/components/ouro/link/link.test.tsx::Link > treats only a present download as document navigation, including an empty filename) - upgrade-hints: scripts/source-rules.mjs
verify:testExists(scripts/source-rules.test.mjs::every istanbul hint in registry/ carries @preserve, so it survives esbuild in an app) - upgrade-link-box: registry/ouro/components/ouro/link/link.touch.test.tsx
verify:testExists(registry/ouro/components/ouro/link/link.touch.test.tsx::gives a link on its own line a 44px box, centred on its text) - upgrade-touch-host: registry/ouro/lib/ouro/testing/vitest.ts; https://github.com/ourostack/ouro-ui/releases/tag/v0.8.3
verify:urlOk(https://github.com/ourostack/ouro-ui/releases/tag/v0.8.3)verify:testExists(scripts/testing-kit.test.mjs::page sizes every Playwright host while the touch frame keeps its phone viewport and input)verify:testExists(scripts/testing-kit.test.mjs::ouroTestProjects leaves the page size to Vitest unless the app sets one)verify:fileLine(registry/ouro/lib/ouro/testing/vitest.ts, /390x844/)verify:fileLine(docs/guides/testing.md, /1600/) - upgrade-theme-tokens: test/theme-tokens.test.tsx
verify:testExists(test/theme-tokens.test.tsx::standard shadow and font tokens > falls back to the inherited font for headings when the theme names none, and Kbd always keeps it) - upgrade-shadcn-add: https://ui.shadcn.com/docs/cli
verify:urlOk(https://ui.shadcn.com/docs/cli) - upgrade-shadcn-css: https://github.com/shadcn-ui/ui/blob/3502dbcde11d1eaf967a47ac375744dc336641f3/packages/registry/src/utils/updaters/update-css-vars.ts#L91-L124
verify:urlOk(https://github.com/shadcn-ui/ui/blob/3502dbcde11d1eaf967a47ac375744dc336641f3/packages/registry/src/utils/updaters/update-css-vars.ts#L91-L124)verify:testExists(scripts/install-check.test.mjs::a complete install passes, for each variant and stage) - upgrade-minimums: scripts/registry.mts
verify:fileLine(scripts/registry.mts, /vitest: "4\.1\.11"/)verify:fileLine(scripts/registry.mts, /playwright: "1\.58\.1"/)verify:fileLine(scripts/registry.mts, /storybook: "10\.2\.10"/) - upgrade-self-reference: https://github.com/ourostack/ouro-ui/releases/tag/v0.2.0; scripts/install-check.mjs
verify:urlOk(https://github.com/ourostack/ouro-ui/releases/tag/v0.2.0)verify:testExists(scripts/install-check.test.mjs::a token that refers to itself fails) - upgrade-test-versions: test:scripts/registry.test.mjs::devDependencies are named without a version, so the CLI installs it only when the app lacks it and never changes a version the app has
verify:testExists(scripts/registry.test.mjs::devDependencies are named without a version, so the CLI installs it only when the app lacks it and never changes a version the app has) - upgrade-none: UPGRADING.md
verify:fileLine(UPGRADING.md, /\[ -n "\$items" \] \|\| \{ echo "No Ouro components/) - upgrade-portal-container: registry/ouro/lib/ouro/portal-container.test.tsx
verify:testExists(registry/ouro/lib/ouro/portal-container.test.tsx::usePortalContainer > leaves a popup at the end of <body>, Base UI's default, without a portalContainer)verify:testExists(registry/ouro/lib/ouro/portal-container.test.tsx::usePortalContainer > warns once, in development, when a popup opens outside every landmark of a page that has a main) - upgrade-portal-null: registry/ouro/lib/ouro/portal-container.test.tsx
verify:testExists(registry/ouro/lib/ouro/portal-container.test.tsx::usePortalContainer > gives popups Base UI's own place again inside an OuroProvider whose portalContainer is null, as an app's own dialog needs) - upgrade-audit: registry/ouro/lib/ouro/testing/axe.test.ts
verify:testExists(registry/ouro/lib/ouro/testing/axe.test.ts::audit > fails a violation whatever its impact: content outside every landmark is only moderate) - upgrade-axe-core: scripts/registry.test.mjs
verify:testExists(scripts/registry.test.mjs::npm dependencies are pinned to the ranges this repository tests) - upgrade-toast-announcer: registry/ouro/components/ouro/toast/toaster.test.tsx
verify:testExists(registry/ouro/components/ouro/toast/toaster.test.tsx::Toaster > renders an empty Notifications landmark in a portal, which holds its own live regions) - upgrade-audit-leaves: registry/ouro/lib/ouro/testing/axe.test.ts
verify:testExists(registry/ouro/lib/ouro/testing/axe.test.ts::audit > fails, naming what changed, when its Tab walk closes a popup that focus leaving closes, which it cannot open again) - upgrade-toast-reachable: registry/ouro/components/ouro/toast/toaster.test.tsx
verify:testExists(registry/ouro/components/ouro/toast/toaster.test.tsx::toast() > keeps every toast, its action and its dismiss button reachable by a screen reader while the stack rests collapsed)
- **v0.2.0:** each component's tests became an optional
Pin a version
Add a tag to pin a release, so a later release doesn't change what you install:
npx shadcn@latest add ourostack/ouro-ui/sheet#v1.2.13A release tag pins the item and every Ouro dependency it brings (such as
buttonand the helpers inlib/ouro) to the same tag. Any other ref,#<sha>or#<branch>, pins only the item you name: its Ouro dependencies come frommain. The@ouronamespace serves the newest release,v1.2.13. Without a ref, the GitHub address installsmain, which is for contributors and can hold unreleased changes. Releases are listed on GitHub.