@abuzareal/contour-ui 0.6.0 → 0.6.1

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 CHANGED
@@ -6,6 +6,10 @@ Changes to the published `@abuzareal/contour-ui` package. Version headings refer
6
6
 
7
7
  No changes recorded.
8
8
 
9
+ ## 0.6.1
10
+
11
+ Compatible source corrections; publication is pending. Restore print theme/disclosures on repeated events or unmount, cancel delayed hash alignment after unmount, preserve delimiter-containing scroll-spy IDs, and close an open Combobox on Tab without cancelling native traversal or changing selection. Add hook/helper/optional-entry references, emitted prop/example drift checks, JavaScript onboarding and migration/history material. Correct the open Combobox background hiding with a labelled non-modal popup, keeping Base UI selection/navigation/positioning parts. Strict whole-document accessibility scans now pass in selected Chromium/WebKit fixtures; the unmodified upstream composition remains a separate failing diagnostic. Add visual QA without excluding axe rules. Manual screen-reader checks remain pending; no universal accessibility claim is made.
12
+
9
13
  ## 0.6.0
10
14
 
11
15
  Add allowed-value selection and public adoption material. This heading records source work, not npm publication.
package/COMBOBOX.md CHANGED
@@ -1,4 +1,4 @@
1
- # Combobox — 0.6.0
1
+ # Combobox — 0.6.1
2
2
 
3
3
  Search a list and choose **one allowed value**. Use native SelectField when its simpler platform interaction is sufficient. Combobox is not free-text autocomplete, global search, a command menu, a multi-select, or a virtualized picker. Selection is a string ID or null; query text is never a submitted selection. It needs no provider or consumer-installed foundation package. [Foundation decision](FOUNDATION.md).
4
4
 
@@ -42,7 +42,7 @@ This is local inspection, not persistence. The application's server must validat
42
42
 
43
43
  ## Types and defaults
44
44
 
45
- [ComboboxProps and ComboboxOption](PUBLIC-API.md) are emitted declarations; inherited native part props remain typed. [Released implementation](https://github.com/abuzareal/contour-ui/blob/v0.6.0/src/components/ui/Combobox.tsx). The ref targets the **visible HTMLInputElement**, including focus, selection and measurement; it does not target the hidden form input or popup.
45
+ [ComboboxProps and ComboboxOption](PUBLIC-API.md) are emitted declarations; inherited native part props remain typed. [Released implementation](https://github.com/abuzareal/contour-ui/blob/v0.6.1/src/components/ui/Combobox.tsx). The ref targets the **visible HTMLInputElement**, including focus, selection and measurement; it does not target the hidden form input or popup.
46
46
 
47
47
  | Props | Contract / default |
48
48
  | ---------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
@@ -82,6 +82,6 @@ Inherited theme and direction travel into portals; collision bounds and long lab
82
82
 
83
83
  Automated Chromium keyboard, touch emulation, synthetic composition, RTL, forced colors, native-dialog and packed React tests are evidence for those fixtures only. Manual screen-reader, physical keyboard/IME and mobile keyboard checks remain separate; no universal accessibility certification is claimed.
84
84
 
85
- **Open-state accessibility review:** the foundation temporarily hides background content from the accessibility tree while the list is active. Static axe checks report `aria-hidden-focus` on that background. Browser regressions verify that Tab/Shift+Tab close the list and restore visibility before focus remains on an outside control. This is retained as a finding requiring manual VoiceOver/NVDA review, not waived as a universal false positive or reported as a zero-finding scan. The [ACT rule's assumptions](https://www.w3.org/WAI/standards-guidelines/act/rules/6cfa84/) explicitly distinguish interactions that change aria-hidden. Do not claim WCAG conformance from these fixtures.
85
+ **Open-state accessibility correction in 0.6.1:** Contour uses a labelled non-modal popup region and listbox, retaining Base UI's public selection/navigation/positioning parts. Opening it no longer hides the surrounding page. Whole-document axe scans pass in the selected Chromium/WebKit fixtures with no excluded rules; Tab and Shift+Tab close it while preserving native traversal. The older Base UI Popup composition's failing diagnostic remains available separately. See [support evidence and limitations](SUPPORT.md); manual VoiceOver/NVDA review remains pending. These fixtures do not establish WCAG conformance.
86
86
 
87
- [Report Combobox 0.6.0](https://github.com/abuzareal/contour-ui/issues/new?template=bug_report.yml&title=Combobox%200.6.0%3A%20&component=Combobox&version=0.6.0), using the [public minimal reproduction](examples/reproduction). Source links for this version resolve when its release tag is published.
87
+ [Report Combobox 0.6.1](https://github.com/abuzareal/contour-ui/issues/new?template=bug_report.yml&title=Combobox%200.6.1%3A%20&component=Combobox&version=0.6.1), using the [public minimal reproduction](examples/reproduction). Source links for this version resolve when its release tag is published.
package/COMPOSITION.md CHANGED
@@ -191,3 +191,7 @@ Anchors have no native disabled state. Render a suitable non-link explanation wh
191
191
  ## Abstraction review
192
192
 
193
193
  Each addition serves a bounded need: native focus/measurement/trigger refs; existing Dialog/Tabs/Popover root/part access; ID-based reorder-safe tab focus; caller handler cancellation. Private helpers implement those lifecycles. No runtime dependency, provider, build/distribution/styling system, generic component-replacement API or blanket polymorphism is introduced. Existing menu disabled items, keyboard opening, typeahead, stable identity and focus return remain covered.
194
+
195
+ ## Version and reproduction
196
+
197
+ Reference version **0.6.1** (candidate until published). [Versioned source](https://github.com/abuzareal/contour-ui/tree/v0.6.1/src) and [emitted type inventory](PUBLIC-API.md) describe this contract; tag links resolve after release. [Report Composition 0.6.1](https://github.com/abuzareal/contour-ui/issues/new?template=bug_report.yml&component=Composition&version=0.6.1), using the [public minimal reproduction](examples/reproduction) and synthetic data.
package/CONTRACTS.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Architecture, scope and compatibility
2
2
 
3
- Contract version **0.6.0**, reviewed 14 October 2026. Contour is an early 0.x React library with typed controls, paper/ink surfaces, a lime accent, light/dark themes, restrained motion and separate optional depth/scene APIs. The [public API and maturity register](PUBLIC-API.md) lists every exported value, type and stylesheet, its maintainer, status, use and limits.
3
+ Contract version **0.6.1**, reviewed 14 October 2026. Contour is an early 0.x React library with typed controls, paper/ink surfaces, a lime accent, light/dark themes, restrained motion and separate optional depth/scene APIs. The [public API and maturity register](PUBLIC-API.md) lists every exported value, type and stylesheet, its maintainer, status, use and limits.
4
4
 
5
5
  ## Intended adoption scope
6
6
 
@@ -43,16 +43,16 @@ Archive bytes, installed dependency bytes, browser JS/CSS, emitted fonts and act
43
43
 
44
44
  ## Environment and validation policy
45
45
 
46
- | Environment | Declared or exercised scope | Limits |
47
- | ----------------------- | ------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------- |
48
- | React/ReactDOM | Peer range above; packed matrix exercises 18.3.1, 19.0.0 and 19.3.0 | Matching pairs required. Other allowed patches are not individually certified. |
49
- | TypeScript | Strict source/fixtures; pinned optional/Next fixtures use 5.9.3; React 18 and 19 declarations compiled | No universal older/newer compiler support claim; JS users need no compiler at runtime. |
50
- | Node | Manifest >=22 for installation/tooling; use 22.12+ or 24+ with current Vite tooling | Browser components do not need Node in the browser. Actual runner versions are recorded per check. |
51
- | ESM/CSS-capable bundler | Packed Vite consumers exercise imports/declarations/CSS/fonts with no optional peers | No CommonJS build or unbundled-browser CSS loader promised. |
52
- | Next.js | Next 16.4.0 / React and ReactDOM 19.3.0, App Router, webpack production build | [NEXTJS.md](NEXTJS.md); other versions, Turbopack, Pages Router and Next Lenis remain unverified. |
53
- | Optional Three | Separate consumers and lazy Next mode; explicit Three/types, WebGL, sized host and static fallback | Experimental API; sampled lifecycle checks do not validate every custom scene/GPU/device. |
54
- | Optional scroll | Separate declaration/build consumer with Lenis and one scroll owner | Caller handles pause/reduced motion; generic Next Lenis integration unverified. |
55
- | Browsers | Playwright Chromium exercises selected native-dialog/reset/graphics/hydration/catalogue journeys | Emulation is not a physical device. Chromium/axe is not Firefox/WebKit/Safari or manual VoiceOver/NVDA verification. |
46
+ | Environment | Declared or exercised scope | Limits |
47
+ | ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
48
+ | React/ReactDOM | Peer range above; packed matrix exercises 18.3.1, 19.0.0 and 19.3.0 | Matching pairs required. Other allowed patches are not individually certified. |
49
+ | TypeScript | Strict source/fixtures; optional/existing Next fixtures use 5.9.3; standalone current Next starter uses 7.0.2; React 18 and 19 declarations compiled | No universal older/newer compiler support claim; JS users need no compiler at runtime. |
50
+ | Node | Manifest >=22 for installation/tooling; use 22.12+ or 24+ with current Vite tooling | Browser components do not need Node in the browser. Actual runner versions are recorded per check. |
51
+ | ESM/CSS-capable bundler | Packed Vite consumers exercise imports/declarations/CSS/fonts with no optional peers | No CommonJS build or unbundled-browser CSS loader promised. |
52
+ | Next.js | Next 16.4.0 / React and ReactDOM 19.3.0, App Router, webpack production build | [NEXTJS.md](NEXTJS.md); other versions, Turbopack, Pages Router and Next Lenis remain unverified. |
53
+ | Optional Three | Separate consumers and lazy Next mode; explicit Three/types, WebGL, sized host and static fallback | Experimental API; sampled lifecycle checks do not validate every custom scene/GPU/device. |
54
+ | Optional scroll | Separate declaration/build consumer with Lenis and one scroll owner | Caller handles pause/reduced motion; generic Next Lenis integration unverified. |
55
+ | Browsers | Selected Chromium and WebKit production fixtures; exact results and known failures in SUPPORT.md | Emulation is not a physical device. Engine emulation is not physical Safari or manual VoiceOver/NVDA; local Firefox launch is blocked. |
56
56
 
57
57
  Release gates use one exact archive: types/lint/build, Node/component tests, native-dialog/graphics browser checks, exports/archive inspection, React matrix, optional consumers, pinned Next core/lazy-Three modes and dependency audit. Catalogue has separate required checks/affected journeys. Record checksum, actual environments and passed/failed/skipped/blocked results. Historical results are dated evidence, not a fresh pass; see [RELEASING.md](RELEASING.md).
58
58
 
package/DOCS.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Public documentation contract and coverage
2
2
 
3
- For Contour 0.6.0, the public package/repository is an independent source of installation, API, recipe and reproduction material. The separate catalogue can describe an older installed release; its visual demos are not proof that this source version is installed there. Catalogue editing and per-component website promotion are separate work.
3
+ For Contour 0.6.1, the public package/repository is an independent source of installation, API, recipe and reproduction material. The separate catalogue can describe an older installed release; its visual demos are not proof that this source version is installed there. Catalogue editing and per-component website promotion are separate work.
4
4
 
5
5
  ## Contract for a promoted guide
6
6
 
@@ -77,4 +77,10 @@ The coverage register below maps public UI components to an explicit shared refe
77
77
 
78
78
  ## Remaining promotion work
79
79
 
80
- The original website per-component pages, search/pattern discovery, legacy URL preservation, generated prop metadata and versioned website archives remain separate work. Existing shared guides must be audited against this contract before each component is promoted. Manual screen-reader/physical device evidence is tracked separately from automated fixture results. This register deliberately leaves those gaps visible.
80
+ The original website per-component pages, search/pattern discovery, legacy URL preservation, full website prop-page generation and versioned website archives remain separate work. A bounded emitted-declaration prototype and drift gate now live in PROP-REFERENCE.md and docs/prop-metadata.json; REFERENCE.md maps all symbols and style/data paths. Existing shared guides must be audited against this contract before each component is promoted. Manual screen-reader/physical device evidence is tracked separately from automated fixture results. This register deliberately leaves those gaps visible.
81
+
82
+ ## Library reference work
83
+
84
+ [HOOKS.md](HOOKS.md), [HELPERS.md](HELPERS.md) and [THREE.md](THREE.md) document non-component contracts and lifecycle ownership. [PROP-REFERENCE.md](PROP-REFERENCE.md) audits the nine historical guides and explains generated versus authored metadata. [MIGRATION.md](MIGRATION.md) preserves version-specific contracts and upgrade/rollback steps; [MODELS.md](MODELS.md) distinguishes package/source/company documentation models. [SUPPORT.md](SUPPORT.md) records automated/manual results and failures. Full PAGE website promotion remains separate.
85
+
86
+ JavaScript and TypeScript onboarding use the same source contract: scripts/build-onboarding.mjs strips types into the shipped JSX example and check:onboarding detects drift. The examples are copied from the actual archive for strict TS/build checks and exercised as independent browser journeys. No private workspace guidance is required to consume them.
package/FORMS.md CHANGED
@@ -92,3 +92,7 @@ Native TextField registration forwards name/onChange/onBlur/ref. RHF submits its
92
92
  The recipe uses useForm defaultValues, RHF field validation/server errors, handleSubmit, controller refs and reset. Its reset command performs native form.reset() first so registered field counters/auto-resize observe the reset, then reset(defaults) updates RHF state. For arbitrary programmatic RHF setValue calls on fields with counters/auto-resize, use Controller and pass the controlled value; direct DOM writes through a registered ref do not dispatch native input events. Its shared submission lifecycle ignores late results after reset/cancel/unmount even if the service disregards AbortSignal. Real services must enforce validation, authentication, authorization, CSRF policy and idempotency/overlap handling at the server boundary. Treat parsed responses as unknown until your adapter validates them; TypeScript alone does not validate network data.
93
93
 
94
94
  References: [React native input ownership](https://react.dev/reference/react-dom/components/input), [native range semantics](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/input/range), [RHF Controller](https://react-hook-form.com/docs/usecontroller/controller), [RHF reset](https://react-hook-form.com/docs/useform/reset), [Radix Switch form contract](https://www.radix-ui.com/primitives/docs/components/switch). These inform bounded contracts; Contour does not add a second interaction foundation or copy their implementation. Native-form checks are scoped Chromium evidence, not cross-browser/screen-reader certification.
95
+
96
+ ## Version and reproduction
97
+
98
+ Reference version **0.6.1** (candidate until published). [Versioned source](https://github.com/abuzareal/contour-ui/tree/v0.6.1/src) and [emitted type inventory](PUBLIC-API.md) describe this contract; tag links resolve after release. [Report Forms 0.6.1](https://github.com/abuzareal/contour-ui/issues/new?template=bug_report.yml&component=Forms&version=0.6.1), using the [public minimal reproduction](examples/reproduction) and synthetic data.
package/FOUNDATION.md CHANGED
@@ -30,6 +30,6 @@ Retain upstream copyright/license notices when redistributing their code. These
30
30
 
31
31
  Primary references: [Base UI Combobox](https://base-ui.com/react/components/combobox), [releases](https://base-ui.com/react/overview/releases), [MIT license](https://github.com/mui/base-ui/blob/master/LICENSE); [Radix Popover](https://www.radix-ui.com/primitives/docs/components/popover), [MIT license](https://github.com/radix-ui/primitives/blob/main/LICENSE), [cmdk](https://github.com/dip/cmdk); [React Aria ComboBox](https://react-aria.adobe.com/ComboBox), [Apache-2.0 license](https://github.com/adobe/react-spectrum/blob/main/LICENSE).
32
32
 
33
- Local open-state axe inspection reports aria-hidden-focus on temporarily hidden background controls. Tab/Shift+Tab/outside-focus behavior must be considered alongside that static result; the raw finding remains recorded and manual AT review is pending. See COMBOBOX.md. The adapter uses the public virtual-anchor and collision-Rect extension points to keep fixed-position coordinates correct under inherited CSS zoom; it does not copy or patch upstream internals.
33
+ In 0.6.1, Contour replaces the Base UI Popup wrapper with its own labelled non-modal region, composed around the public Positioner/List/Item parts. This corrects the observed input-outside-popup background hiding without changing the selection/form contract, removing ARIA or patching private internals. The listbox uses the visible field label; closed popup content is hidden. Contour completes the public Root actions close lifecycle after hiding its non-animated popup so controlled query text returns to the selected label. Whole-document strict axe and keyboard checks pass in selected Chromium/WebKit fixtures. The original unmodified upstream composition remains a separate strict failing diagnostic, documented in SUPPORT.md; manual AT review remains pending. The adapter continues to use public virtual-anchor and collision-Rect extension points to keep fixed-position coordinates correct under inherited CSS zoom.
34
34
 
35
35
  Contour also owns synchronous input activation to avoid an obsolete upstream touch-open timer reopening a selected/closed picker. Public event cancellation/propagation hooks preserve native document observers and caller Escape vetoes. These adapters are regression-tested without exposing upstream event types in Contour props.
@@ -1,11 +1,11 @@
1
- # Adopt Contour — 0.6.0
1
+ # Adopt Contour — 0.6.1
2
2
 
3
3
  Use [the standalone Vite starter](examples/starters/vite), [Next App Router starter](examples/starters/next), or add one component to an existing app. Each folder is public and independent; no private catalogue source, repository aliases, provider stack or application layout is required. Direct dependencies are exact; generate and commit your application's lockfile, then use npm ci. Candidate source requires an archive until its matching version is published.
4
4
 
5
5
  ## Existing application
6
6
 
7
7
  ```sh
8
- npm install --save-exact @abuzareal/contour-ui@0.6.0
8
+ npm install --save-exact @abuzareal/contour-ui@0.6.1
9
9
  ```
10
10
 
11
11
  Install matching react/react-dom versions in the supported ranges (^18.3.1 or ^19.0.0). React 18.3.1, 19.0.0 and 19.3.0 have independent packed consumer checks; a peer range is not a claim of every framework configuration. Native form/overlay APIs are client interactions. Use the library's emitted declarations instead of a copied API from an old catalogue.
@@ -60,4 +60,8 @@ Copy [OptionalSmoothScroll.tsx](examples/optional/OptionalSmoothScroll.tsx) and
60
60
 
61
61
  Supported evidence names the exact pair: Next 16.4.0 App Router, React/React DOM 19.3.0, webpack production build, plus its separate optional lazy Three fixture. Turbopack, Pages Router, Next Lenis, static nonce export and arbitrary third-party modal interoperability are not promoted to supported configurations. Vite starter pins 8.3.2 with React 18.3.1. Server-safe helper imports, client directives, declarations and hydration are checked independently; SSR rendering alone does not prove hydration.
62
62
 
63
- Copy [the public reproduction folder](examples/reproduction), reduce it to the failing interaction, and include exact package/browser versions and keyboard steps. Its [issue link](https://github.com/abuzareal/contour-ui/issues/new?template=bug_report.yml&title=Integration%200.6.0%3A%20&component=Integration&version=0.6.0) contains version/component, not private data. Report only synthetic records and public reproducible source. [Documentation coverage and limits](DOCS.md).
63
+ Copy [the public reproduction folder](examples/reproduction), reduce it to the failing interaction, and include exact package/browser versions and keyboard steps. Its [issue link](https://github.com/abuzareal/contour-ui/issues/new?template=bug_report.yml&title=Integration%200.6.1%3A%20&component=Integration&version=0.6.1) contains version/component, not private data. Report only synthetic records and public reproducible source. [Documentation coverage and limits](DOCS.md).
64
+
65
+ ## JavaScript and TypeScript examples
66
+
67
+ Copy [SettingsForm.jsx](examples/onboarding/SettingsForm.jsx) for a JavaScript React app or [SettingsForm.tsx](examples/onboarding/SettingsForm.tsx) for TypeScript. Render SettingsForm after importing scoped.css; both inspect the same native FormData locally, reset defaults/output and focus the native name input. Neither saves data or needs a provider. The JSX is generated by stripping types from the TSX source, not a second hand-maintained example; it contains no TypeScript syntax. Bring your own React entry/router and server validation. See MIGRATION.md for upgrades and older contracts.
package/HELPERS.md ADDED
@@ -0,0 +1,33 @@
1
+ # Helpers and public types
2
+
3
+ Use direct imports from `@abuzareal/contour-ui`. [PUBLIC-API.md](PUBLIC-API.md) links exact release source/types; [REFERENCE.md](REFERENCE.md) checks complete export coverage. Helpers do not require a provider. Only the pure operations below are server-call safe; importing the module and invoking a browser operation are different contracts.
4
+
5
+ | Helper | Inputs/defaults and result | Boundaries |
6
+ | ----------------- | ------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
7
+ | cx | Variadic string/false/null/undefined; joins truthy parts with spaces. | No class parsing, deduplication, token validation or prefixing. Use for arbitrary consumer strings/IDs only when joining is appropriate. |
8
+ | ccx | Same inputs; deduplicates whitespace-separated names and appends contour-prefixed equivalents for known library classes. | Compatibility class helper, not an ID/ARIA builder. Unknown consumer classes remain unchanged. |
9
+ | buttonClassName | variant="primary", size="md", optional className; returns compatibility/prefixed button classes. | ButtonVariant: primary/accent/secondary/ghost/danger; ButtonSize: sm/md/lg. Styling an anchor does not give it button semantics. |
10
+ | formatIndex | number; String(value).padStart(2,"0"). | 3 → "03", 12 → "12". It does not round, add one, validate finite values, format a locale or normalize negative/fractional inputs. Pass an already chosen index. |
11
+ | fieldDescribedBy | id, optional hint/error; error → id-error, else hint → id-hint, else undefined. | Matches Field's message priority. Does not render an element or preserve arbitrary caller description IDs; callers merge those separately. |
12
+ | nextIndexForKey | key/current/count, orientation="horizontal", direction="ltr"; wrapped index or null. | count<=0 and unrelated keys return null. Home/End choose extremes. RTL reverses horizontal arrows. It does not skip disabled items, focus DOM nodes or validate every numeric input. Caller owns a valid current index/count and disabled-item policy. |
13
+ | safeHref | string or undefined; returns allowed href unchanged or undefined. | Rejects executable/disallowed schemes, including whitespace-obfuscated forms. Relative/hash/protocol-relative and permitted https/http/mailto/tel links are not a trusted-destination allowlist. Validate destination/origin and authorize redirects separately. |
14
+ | storageKeys | openingSeen="aa-opening-seen", theme="aa-theme". | Retained legacy origin-wide keys; not namespaced per application/scope. |
15
+ | readStorage | area="local" or "session", key; string or null. | Browser storage access wrapped in try/catch; blocked/missing/SSR access returns null. It does not parse/validate JSON or distinguish missing from denied. |
16
+ | writeStorage | area/key/string value; boolean success. | False for inaccessible/throwing storage. It does not encrypt data, provide a schema, broadcast an app event or write a server cookie. |
17
+ | motionDisabledFor | Element; boolean. | Browser-only synchronous preference/ancestor check; see HOOKS.md. |
18
+
19
+ ## Public types
20
+
21
+ Section is `{id: string; label: string; title: string; number: number}`. It describes repeated page metadata, not a router, validator or React element. The application supplies stable IDs and valid numbers. CopyStatus, Theme, DismissReason/Options, PanelFocusOptions, FloatingOptions, ToastInput and ToastContextValue are described with their hooks in HOOKS.md. Component Props/item/variant aliases remain in the emitted declarations; they are types, not additional component exports. Generic TableColumn and TabItem must be read with their associated component contracts.
22
+
23
+ Use `import type` for type-only values. Do not deep-import dist files or assume a type-named symbol exists at runtime. Native inherited React props and overloads are retained by the declarations; generated metadata is a discovery aid and does not replace them. No arbitrary polymorphic component or enterprise grid contract is implied by these helpers.
24
+
25
+ ## Data and URL responsibility
26
+
27
+ Read parsed storage/network data as unknown. Validate structures, elements, finite numbers/ranges and IDs before supplying components. A successful storage write is not server persistence. A safe URL scheme is not proof of a safe destination, a permitted server redirect or sanitized remote HTML. React escaping does not authorize data access; server validation and permissions remain at the relevant boundary.
28
+
29
+ The JavaScript onboarding example in [GETTING-STARTED.md](GETTING-STARTED.md) uses the same native form payload contract without requiring TypeScript syntax. Report synthetic reproductions and exact package/browser versions; never include private storage contents or credentials.
30
+
31
+ ## Version and reproduction
32
+
33
+ Reference version **0.6.1** (candidate until published). [Versioned source](https://github.com/abuzareal/contour-ui/tree/v0.6.1/src) and [emitted type inventory](PUBLIC-API.md) describe this contract; tag links resolve after release. [Report Helpers 0.6.1](https://github.com/abuzareal/contour-ui/issues/new?template=bug_report.yml&component=Helpers&version=0.6.1), using the [public minimal reproduction](examples/reproduction) and synthetic data.
package/HOOKS.md ADDED
@@ -0,0 +1,67 @@
1
+ # Hooks and browser lifecycles
2
+
3
+ Reference for the current package manifest version; exact released implementations and emitted types are linked in [PUBLIC-API.md](PUBLIC-API.md). Hooks belong in a React client component. Import from `@abuzareal/contour-ui` unless the optional `/scroll` entry is named explicitly. No general provider is required except useToast. These are executable contracts, not promises of every browser, renderer or application layout.
4
+
5
+ ## Theme
6
+
7
+ `useTheme(animate = true)` returns `{theme, toggle(origin), canToggle}`. Theme is `"light" | "dark"`; toggle accepts an HTMLElement that anchors the reveal. Outside ThemeScope it owns html[data-theme], the existing theme-color meta, local storage key `aa-theme`, and subscriptions to root attributes, storage events and system changes when no stored preference exists. Initial server snapshot is light. Use the pure bootstrap entry before paint rather than hiding arbitrary hydration mismatches. Blocked storage does not prevent a local toggle. Animation respects system reduced motion; unsupported View Transitions fall back to a short class-based transition.
8
+
9
+ Within controlled ThemeScope it reads the scope's theme and invokes onThemeChange; it does not write document preference/storage. Without that callback canToggle is false. ThemeToggle supplies the native button, constant accessible name and aria-pressed state. The hook is not a general persisted settings manager. Independent scopes need scoped CSS. See [STYLING.md](STYLING.md) and the actual hash/nonce starter sources in [GETTING-STARTED.md](GETTING-STARTED.md).
10
+
11
+ `themeBootstrapScript` and `themeColors` are exported from `@abuzareal/contour-ui/theme-bootstrap`, not the core entry. The string reads valid stored light/dark, otherwise system preference, sets root theme and an existing meta; it does not initialize independent scopes. themeColors contains light `#f2f3ee` and dark `#0f100d`. Hash the exact current string or authorize a fresh request nonce; never interpolate user data, reuse a nonce, copy an old hash, or assume a dynamic nonce setup supports static export. The bootstrap module can be imported by a server/config process without browser globals; executing its string is a browser operation.
12
+
13
+ ## Motion
14
+
15
+ `useMotionPreference()` returns a boolean for `(prefers-reduced-motion: reduce)` and subscribes to changes, removing the listener on unmount. It reports system preference only. It does not combine an application pause, stop timers, cancel a network request or control unrelated scenes. The app combines `!reducedMotion && !paused` and owns cleanup of its effects.
16
+
17
+ `motionDisabledFor(element)` synchronously returns true for system reduction or an ancestor `[data-motion="off"]`. It is a browser helper, not a subscription. It uses the current window's media preference and the supplied element's ancestors. CSS motion rules and JavaScript loops have separate responsibilities. Do not call this on the server or infer that merely mounting the preference hook pauses every animation.
18
+
19
+ ## Clipboard
20
+
21
+ `useClipboardCopy(text: string)` returns `{status, copy}`. CopyStatus is `idle | copying | copied | error`. Invoke copy from an explicit user action. It awaits navigator.clipboard.writeText; only a resolved write yields copied. Missing API, insecure context, denial and rejected writes yield error; there is no fabricated fallback success. Feedback returns to idle after 4,000 ms. Changing text resets feedback and invalidates earlier completions; newer calls win, unmount removes reset timers and ignores late writes. A clipboard write itself cannot be cancelled.
22
+
23
+ Render visible feedback or a polite status, and a retry action when appropriate. The hook does not request browser permission in advance or guarantee OS clipboard retention. Do not log secrets or use a toast as the only record of failure.
24
+
25
+ ## Dismissal and mobile menus
26
+
27
+ `useDismiss(containerRef, active, onDismiss, options = {})` returns void. The callback receives DismissReason (`escape | outside`) and the native KeyboardEvent or PointerEvent. The topmost registered layer in that element's owner document dismisses once. Native preventDefault cancellation and ordinary document observers remain meaningful; nested/sibling ordering is described in [OVERLAYS.md](OVERLAYS.md). A render with changed callbacks updates policy without simulating a close. Actual node/document changes rebind registration and unmount removes it.
28
+
29
+ DismissOptions supplies `branches` (owned refs, including trigger/portals), `layerElement` (floating paint-order owner) and `outside` (default true; native modal backdrop handling may own it instead). This hook does not create a trigger, portal, focus trap, accessible name, modal scroll lock or automatic open state. Prefer Dialog/Popover when their complete interaction fits. Custom layer callers own focus entry/return, role/ARIA, state and structural containment. Do not deep-import internal stack helpers.
30
+
31
+ `useMobileMenu(containerRef, toggleButtonRef)` returns readonly `[open, setOpen]`, initially false. It uses dismissal with the trigger as an owned branch; Escape closes and focuses a connected toggle, outside press closes without stealing focus. While open it listens for the container's owner window to transition into `(min-width: 768px)` and closes. It does not supply menu markup, ARIA, a modal trap, routing or a responsive design system. Opening programmatically while already at desktop width is not prohibited by the hook; the app owns viewport-dependent rendering. Match refs to the actual connected nodes and choose native links/buttons for the menu's purpose.
32
+
33
+ PanelFocusOptions is a public type used by built-in floating panels: initialFocus may be a ref or false; onOpenAutoFocus/onCloseAutoFocus receive cancelable events. FloatingOptions covers side/align/offset/collision and portal/container. These types do not expose the internal positioning hook. Use their current declarations; disabling automatic focus transfers responsibility to the application.
34
+
35
+ ## Scroll and navigation
36
+
37
+ `useHeaderScroll(headerRef)` returns `{scrolled, overDark, activeId}`. It samples `main section[id]` and `[data-header-theme='dark']` once when the effect installs. scrolled means scrollY > 20; overDark tests the header-height line against marked areas; activeId is the last listed section whose top is at or above 35% of viewport height. It subscribes to scroll/resize and removes listeners on cleanup. Dynamic section replacement, arbitrary nested scroll containers and router state are not observed automatically. This is a retained page-oriented hook, not a universal app header API.
38
+
39
+ `useScrollSpy(ids: string[])` returns the last supplied existing section above a 30% viewport activation line, or an empty string before any qualifies. Keep unique stable section IDs in visual order. Targets are resolved when the ID sequence changes, not on every DOM mutation. Scroll/resize updates are batched through one animation frame and cleanup cancels it. The serialized sequence preserves IDs containing separators; this patch fixes the prior `|`-joined ambiguity. It does not observe a custom scroll container or change the URL.
40
+
41
+ `useInitialHashScroll()` has no arguments/return value. At mount it decodes the initial hash, finds an existing ID, scrolls to its start and realigns once after document.fonts.ready. Malformed or missing hashes are ignored. Wheel/touchstart/keydown stops the delayed realignment so it cannot override the visitor. Cleanup invalidates font readiness; it cannot scroll a later page after unmount. It does not subscribe to hashchange or wait for a later lazy route to create the target. Native history/focus/routing remain application-owned.
42
+
43
+ ## Idle and print
44
+
45
+ `useIdleTrigger(enabled)` returns false until enabled and an idle callback fires (timeout 1,200 ms), or a 300 ms setTimeout fallback where idle callbacks are unavailable. It cancels the pending callback/timer when disabled or unmounted. Once true it stays true for that hook instance, even if enabled later becomes false. It is a scheduling hint, not a loading indicator, work queue or guarantee that the main thread is free; actual heavy work still needs a bounded/lazy design.
46
+
47
+ `usePrintPreparation()` installs beforeprint/afterprint listeners on the current document/window. It temporarily opens closed details and sets root data-theme to light, then restores the exact original theme attribute and only those disclosures it opened. Repeated beforeprint does not replace the original snapshot; repeated afterprint is harmless. Unmount during print also restores the snapshot and removes listeners. Mount one document owner. This inherited page hook changes all disclosures/root theme; independent ThemeScope values, application state, server printing, PDF layout and unrelated printer dialogs are outside its contract. Use CSS print rules for product layout. This patch fixes the prior absent-theme/repeated-event/unmount restoration defects.
48
+
49
+ ## Toast
50
+
51
+ `useToast()` returns ToastContextValue `{show(toast): void}` and throws outside ToastProvider. ToastInput requires title, accepts message and AlertTone (`neutral | accent | info | success | warning | danger`); neutral is the visual default. The provider requires children and defaults label="Notifications", dismissLabel="Dismiss notification". It renders a polite live region, retains at most the latest three notifications and dismisses each after 5,000 ms while not hovered/focused. Leaving a pause starts a new full timeout, not a remaining-time countdown. Close buttons dismiss individual items. The public command returns no ID and has no update/dismiss/promise/undo API.
52
+
53
+ A toast describes an already established result. Fetching, business validation, persistence and retry remain application-owned. Keep important errors beside the task and use durable state when a message must outlive a temporary notification. ToastContext appears only as a type-level export through the current public re-export surface; it is not a runtime provider escape hatch.
54
+
55
+ ## Optional scroll
56
+
57
+ `useSmoothScroll(enabled)` is imported from `@abuzareal/contour-ui/scroll`. Install the declared Lenis peer and import `lenis/dist/lenis.css` in the application. Enabled creates one Lenis with autoRaf=true, duration=1.05, smoothWheel=true, syncTouch=false and anchors=true; disabling or unmounting destroys that owner. It returns no Lenis instance/commands. It does not read system preference itself. The app must combine pause/reduced motion, keep one active owner, preserve native focus/hash behavior and supply native-scroll fallback until opt-in.
58
+
59
+ The [actual optional recipe](examples/optional/OptionalSmoothScroll.tsx) lazy-loads its owner and stylesheet; core installation has no Lenis requirement. Vite/client integration is exercised; Next Lenis and arbitrary router scroll restoration remain unverified. Three is separate; see [THREE.md](THREE.md).
60
+
61
+ See [REFERENCE.md](REFERENCE.md) for every runtime/type/style export mapping, [HELPERS.md](HELPERS.md) for pure/browser helpers and [SUPPORT.md](SUPPORT.md) for dated evidence. Report hook/version details through [the public reproduction](examples/reproduction); source/version issue paths are in PUBLIC-API.md and GETTING-STARTED.md.
62
+
63
+ Copyable [HookExamples.tsx](examples/reference/HookExamples.tsx) uses these public contracts for clipboard feedback, motion policy, custom nonmodal dismissal, idle scheduling, scoped theme and toast ownership. Copied source compiles in the packed React18/19 consumers. The custom help region deliberately has no modal trap; use Dialog/Popover for their complete focus/portal contracts.
64
+
65
+ ## Version and reproduction
66
+
67
+ Reference version **0.6.1** (candidate until published). [Versioned source](https://github.com/abuzareal/contour-ui/tree/v0.6.1/src) and [emitted type inventory](PUBLIC-API.md) describe this contract; tag links resolve after release. [Report Hooks 0.6.1](https://github.com/abuzareal/contour-ui/issues/new?template=bug_report.yml&component=Hooks&version=0.6.1), using the [public minimal reproduction](examples/reproduction) and synthetic data.
package/MANUAL-QA.md ADDED
@@ -0,0 +1,38 @@
1
+ # Manual screen-reader check guide
2
+
3
+ VoiceOver (Mac) and NVDA (Windows) read a page aloud. These checks need a person to listen: an automated test cannot know whether the spoken name, state or error makes sense. You do not need to share a recording or private data. Use synthetic fixture values only. **No session is claimed as completed by this guide.**
4
+
5
+ ## Prepare the public fixture
6
+
7
+ From a public repository checkout at the exact commit being checked, run npm ci --ignore-scripts, npm run build, then npm run qa:preview. Open http://127.0.0.1:5177 in the browser being checked. Record the package/source commit, OS version, browser version and screen-reader version. These are local fixture results, not production deployment proof. Stop the preview with Ctrl+C afterward.
8
+
9
+ For VoiceOver use Safari on Mac and turn VoiceOver on with Command+F5 (some keyboards also require Fn), or through the Accessibility settings. For NVDA use a Windows machine with NVDA and Firefox. Browser/OS keyboard navigation settings can affect Tab behavior; record the settings rather than changing the application to hide the difference. Consult the screen reader's own help for reading/navigation commands.
10
+
11
+ ## Scenarios to listen to
12
+
13
+ 1. Read the heading and local-only notice. Move to Name: its label, required state and hint should make sense. Change it, submit, inspect the actual visible payload, then reset and check Ada returns.
14
+ 2. Move to Allow updates and Notifications. Check the announced name/checked state, Space activation and FormData omission when unchecked. No fake success or silent data save should be suggested.
15
+ 3. Move to Project. Open the picker, type part of a label, use arrows and select. Confirm the announced field name, expanded/collapsed state, highlighted/selected choice and disabled choice. Test the long translated label and no matches. Typed text must not become an arbitrary submitted ID.
16
+ 4. With the picker open, press Tab and Shift+Tab. Confirm the list closes and the newly focused control is readable, with no dead/hidden keyboard target. Try reading outside the popup with the screen-reader cursor as well as keyboard focus. Record any inaccessible background, duplicate announcements or lost position; do not presume the static finding is harmless.
17
+ 5. Open Confirm settings. Check the title/description, initial Review note focus, Tab containment, Escape close and focus return to the connected previously focused opener. Safari pointer clicks do not necessarily focus buttons; this fixture explicitly focuses its opener before opening. Repeat Project help and its Escape/focus return.
18
+ 6. Repeat relevant controls in dark mode (?theme=dark), narrow width, high browser zoom and RTL (?rtl=1). Distinguish browser zoom from display scaling and CSS zoom. Check long labels/errors do not clip essential controls.
19
+ 7. In actual copied async/confirmation recipes, listen for loading/error/retry and safe cancellation. Confirm destructive success is announced only after a real caller-confirmed result. A failed request should leave a readable persistent error. Record the exact recipe/service fixture used; do not claim these paths from the basic static form alone.
20
+
21
+ ## Result record
22
+
23
+ | Field | Record |
24
+ | ------------------------------------- | ------- |
25
+ | Date, reviewer and synthetic fixture | Pending |
26
+ | Package/source commit/archive | Pending |
27
+ | OS / browser / screen reader versions | Pending |
28
+ | Scenario / exact keyboard steps | Pending |
29
+ | Expected name/state/announcement | Pending |
30
+ | Actual observed announcement/focus | Pending |
31
+ | Pass / fail / blocked / not attempted | Pending |
32
+ | Reproduction / issue / fix / retest | Pending |
33
+
34
+ Mark unattempted scenarios explicitly. A passing session covers only its recorded environment/scenarios. QA-13 and QA-14 remain open until actual results exist; preparing this guide does not close them. Substantive findings need fixes or public limitations, and the strict automated findings remain independently recorded in SUPPORT.md.
35
+
36
+ ## Version and reproduction
37
+
38
+ Reference version **0.6.1** (candidate until published). [Versioned source](https://github.com/abuzareal/contour-ui/tree/v0.6.1/src) and [emitted type inventory](PUBLIC-API.md) describe this contract; tag links resolve after release. [Report Manual accessibility 0.6.1](https://github.com/abuzareal/contour-ui/issues/new?template=bug_report.yml&component=Manual%20accessibility&version=0.6.1), using the [public minimal reproduction](examples/reproduction) and synthetic data.
package/MIGRATION.md ADDED
@@ -0,0 +1,44 @@
1
+ # Upgrades and older contracts
2
+
3
+ Use the exact released package version and its declarations. A Git branch, catalogue label or successful local build does not identify what your application installed. Keep the previous lockfile available, review API/type/style/theme/visual changes, install an exact published version, run the application's checks and compare real form/overlay journeys before deployment. Publishing Contour does not upgrade a consumer.
4
+
5
+ ## Release history access
6
+
7
+ | Version boundary | Inspect the immutable source | Main contract change |
8
+ | ---------------------------- | ----------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
9
+ | 0.2.0 baseline | [README](https://github.com/abuzareal/contour-ui/blob/v0.2.0/README.md) | Earlier native fields and wrapper limits; do not project later ref/form/portal contracts backwards. |
10
+ | 0.2.1 baseline documentation | [README](https://github.com/abuzareal/contour-ui/blob/v0.2.1/README.md) | Explicit architecture, dependency, compatibility and maturity contract. |
11
+ | 0.3.0 API | [README](https://github.com/abuzareal/contour-ui/blob/v0.3.0/README.md) | Native refs/attributes and typed owned parts; inspect the actual released component, not a generic polymorphic API. |
12
+ | 0.4.0 forms | [README](https://github.com/abuzareal/contour-ui/blob/v0.4.0/README.md) | Named custom-control submission, defaults/reset and native/RHF recipes. |
13
+ | 0.5.0 overlays/styles | [README](https://github.com/abuzareal/contour-ui/blob/v0.5.0/README.md) | Default portals/collision/layer semantics and isolated prefixed CSS/theme scope; legacy style paths retained. |
14
+ | 0.6.0 additions | [README](https://github.com/abuzareal/contour-ui/blob/v0.6.0/README.md) | Combobox, semantic Table, application recipes and standalone starters. No general grid/NumberField/PasswordInput export. |
15
+
16
+ An old guide remains tied to its version. To inspect the emitted declarations/CSS of an older version, use `npm pack @abuzareal/contour-ui@VERSION --ignore-scripts` in a disposable directory and inspect the archive without running application code. Tagged source retains authored documentation available at that release; do not invent an older guide URL when it did not exist. No indefinite hosted website archive/SLA is promised. Current website routes and migration of its own installed release are separate catalogue work.
17
+
18
+ ## Refs and forms
19
+
20
+ Before native ref support, some components needed an application-specific wrapper; do not copy that workaround into a current application automatically. The current public targets are documented in COMPOSITION.md and FORMS.md. For example, `const input = useRef<HTMLInputElement>(null)` and `<TextField ref={input} ... />` target the native input; a wrapper div is not the form-registration target. Switch remains a button ref with a backing successful control, not an HTMLInputElement ref.
21
+
22
+ The shipped [ManualSettingsForm-0.3.0.tsx](examples/forms/ManualSettingsForm-0.3.0.tsx) preserves the old application-assembled payload path. [NativeSettingsForm.tsx](examples/forms/NativeSettingsForm.tsx) and [HookFormSettingsForm.tsx](examples/forms/HookFormSettingsForm.tsx) are the current copied-and-tested contracts. Add name/form/value deliberately and verify checked-only omission, required validation, disabled fields, form.reset(), controlled state and error focus. Do not retain both old manually appended values and new named backing controls, producing duplicate submissions. Server validation/authorization remains necessary.
23
+
24
+ ## CSS and theme
25
+
26
+ Before: importing legacy styles.css/reset.css supplies global component/reset rules and unprefixed classes. For an embedded current control, choose scoped.css or selective families and opt into minimal-reset only if required. Legacy paths remain available for an intentional gradual migration; changing imports alone does not port application overrides.
27
+
28
+ Before an override might use `.card .popover-panel`. Default portaled content is no longer a DOM descendant of that card. After migration, attach a scoped application class through the documented panelProps/class hook and style that class; do not depend on private DOM ancestry. `portal={false}` preserves inline placement where supported but restores ancestor clipping constraints. Exercise native-dialog top-layer placement, viewport edges and one-layer Escape in the final app.
29
+
30
+ Before root useTheme/bootstrap owns the whole document and aa-theme preference. After embedding, controlled ThemeScope owns an independent subtree and optional onThemeChange; it needs no document bootstrap. Do not mount document-theme owners merely to style one card. Preserve semantic token names, import order and font choice from STYLING.md; system fonts need no font stylesheet. Review any app-specific aliases before removing old reset/layout assumptions.
31
+
32
+ ## Rollout and rollback
33
+
34
+ 1. Record the application's old package/lock version and affected routes; read the destination release's CHANGELOG, CONTRACTS and limits.
35
+ 2. Install the exact published package with --save-exact; retain a real registry install rather than a workspace link.
36
+ 3. Compile declarations, lint/build and exercise forms, refs, overlays, styling/theme and optional scenes actually used. Verify narrow/long content and keyboard behavior. Compare runtime support with SUPPORT.md.
37
+ 4. Commit manifest/lockfile and required composition changes together. Deploy only with authorization, then verify hosted version/content separately.
38
+ 5. If rollback is needed, restore the previous exact package/lock and compatible application composition together; do not unpublish or overwrite an existing library version.
39
+
40
+ The 0.6.1 work is intended as compatible lifecycle/documentation corrections. Its publication state and support evidence must be checked before installation; a candidate version in source is not an npm release. No universal screen-reader or framework certification is added by these migration instructions.
41
+
42
+ ## Version and reproduction
43
+
44
+ Reference version **0.6.1** (candidate until published). [Versioned source](https://github.com/abuzareal/contour-ui/tree/v0.6.1/src) and [emitted type inventory](PUBLIC-API.md) describe this contract; tag links resolve after release. [Report Migration 0.6.1](https://github.com/abuzareal/contour-ui/issues/new?template=bug_report.yml&component=Migration&version=0.6.1), using the [public minimal reproduction](examples/reproduction) and synthetic data.
package/MODELS.md ADDED
@@ -0,0 +1,18 @@
1
+ # Library models and references
2
+
3
+ Reviewed14 October2026 against the linked primary documentation. This is a distinction between distribution/ownership models, not a ranking or a claim that Contour has equivalent coverage, staffing, accessibility evidence or maintenance guarantees.
4
+
5
+ - **Contour** is an authored TypeScript/React package distributed as ESM JavaScript, declarations and CSS. Vite is tooling for fixtures/catalogues, not a requirement that consumers mount another Vite app. Public primitives/tokens and experimental optional entries remain versioned package contracts; applications own workflows and data.
6
+ - **Radix Primitives** provides unstyled React interaction primitives for building a design system. It is not a ready-made Contour visual theme. Its [official introduction](https://www.radix-ui.com/primitives/docs/overview/introduction) describes accessibility and composition priorities. Source/typed APIs do not make arbitrary adapters automatically interoperable.
7
+ - **shadcn/ui** describes a code distribution platform: its CLI distributes component source into the application, where the adopter owns modifications and update reconciliation. That differs from upgrading an npm component package. See the [official introduction](https://ui.shadcn.com/docs). The original research interpreted the spoken “ChatC” as shadcn/ui; that remains an assumption, not a separate verified product name.
8
+ - **Material UI** is an independent React implementation of Google's Material Design, with prebuilt components and customization. Google's design guidance and the MUI implementation are separate sources. The [MUI overview](https://mui.com/material-ui/getting-started/) and [repository](https://github.com/mui/material-ui) describe that relationship; adopting Material's principles does not require copying its visual identity or claiming all MUI X capabilities belong to the same core scope.
9
+ - **Salt** is J.P. Morgan's open-source React design system for financial services and other products. Its [official glossary](https://www.saltdesignsystem.com/salt/about/glossary) and [repository](https://github.com/jpmorganchase/salt-ds) establish an actual public implementation. Specific private firm themes, company product screens and business workflows are not thereby public reusable assets. Study task clarity, support matrices and contribution boundaries rather than copying a bank's product identity.
10
+ - **Polaris React** is now a deprecated archived implementation, rather than evidence of an actively maintained current React target. Its [official archive](https://github.com/Shopify/polaris-react-archive) and Shopify's [web-component migration guidance](https://shopify.dev/docs/apps/build/app-home/migrate-from-polaris-react) distinguish the older React contract from the current migration direction. An archived reference can explain a historical pattern but needs an explicit maintenance disposition before reuse.
11
+
12
+ Other company design websites can be useful visual/process references without proving an open-source implementation, redistribution license or reusable package. Check the actual repository/package, source license, notices, supported environment and version before adopting code/assets. Public screenshots or tokens are not blanket permission to redistribute a brand. This page does not copy upstream implementation or change Contour's MIT license.
13
+
14
+ The bounded Base UI/Radix+cmdk/React Aria decision, exact versions, licenses and measured tradeoffs remain in [FOUNDATION.md](FOUNDATION.md). Preserve that dated evidence instead of treating a competitor list as a reason to add dependencies. New controls still require a reusable contract and demonstrated need.
15
+
16
+ ## Version and reproduction
17
+
18
+ Reference version **0.6.1** (candidate until published). [Versioned source](https://github.com/abuzareal/contour-ui/tree/v0.6.1/src) and [emitted type inventory](PUBLIC-API.md) describe this contract; tag links resolve after release. [Report Library models 0.6.1](https://github.com/abuzareal/contour-ui/issues/new?template=bug_report.yml&component=Library%20models&version=0.6.1), using the [public minimal reproduction](examples/reproduction) and synthetic data.
package/NEXTJS.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Next.js App Router integration
2
2
 
3
- This guide describes **Contour 0.6.0**. npm 0.1.2 does not include the client directives, native refs or relative Latin font files described here. Check npm for release availability before installing. The fixture pins Next 16.4.0 with React/React DOM 19.3.0, uses the webpack production build, and consumes an npm archive. It does not establish every Next version, Turbopack, Pages Router, scroll entries or hosting platform. A separate optional mode checks a lazy Three.js scene with SSR disabled and disposal on navigation.
3
+ This guide describes **Contour 0.6.1**. npm 0.1.2 does not include the client directives, native refs or relative Latin font files described here. Check npm for release availability before installing. The fixture pins Next 16.4.0 with React/React DOM 19.3.0, uses the webpack production build, and consumes an npm archive. It does not establish every Next version, Turbopack, Pages Router, scroll entries or hosting platform. A separate optional mode checks a lazy Three.js scene with SSR disabled and disposal on navigation.
4
4
 
5
5
  In `app/layout.tsx`, load CSS once:
6
6
 
package/OVERLAYS.md CHANGED
@@ -50,3 +50,7 @@ Production checks cover nested/sibling/portaled layers, native modal portals, to
50
50
  Keep a portal container stable while open. Changing its DOM target can remount the portaled subtree; keep unsaved child state in the owner when container changes are required.
51
51
 
52
52
  Default-open children choose an enclosing native dialog even before its open attribute is set. When Dialog calls showModal in the same commit, these children enter its top layer without an additional click or render.
53
+
54
+ ## Version and reproduction
55
+
56
+ Reference version **0.6.1** (candidate until published). [Versioned source](https://github.com/abuzareal/contour-ui/tree/v0.6.1/src) and [emitted type inventory](PUBLIC-API.md) describe this contract; tag links resolve after release. [Report Overlays 0.6.1](https://github.com/abuzareal/contour-ui/issues/new?template=bug_report.yml&component=Overlays&version=0.6.1), using the [public minimal reproduction](examples/reproduction) and synthetic data.
@@ -0,0 +1,37 @@
1
+ # Emitted prop reference and guide audit
2
+
3
+ The installed package's `.d.ts` files are the full typed API. [PUBLIC-API.md](PUBLIC-API.md) links each released symbol and defining source; [REFERENCE.md](REFERENCE.md) maps every public runtime/type/style entry to maintained guidance. Native inherited React attributes and generic overloads are not replaced by a hand-written short table.
4
+
5
+ ## Generated metadata
6
+
7
+ [docs/prop-metadata.json](docs/prop-metadata.json) is extracted from emitted declarations for Checkbox, SelectField, ProgressBar, TextField, TextArea, Dialog, Tabs, ToastProvider, DropdownMenu, Combobox and Table. It preserves all call signatures, authored/inherited prop names and selected prop types/required flags. Source destructuring initializers supply explicit defaults; missing initializer is not evidence of false, empty string or a browser default. Dependent expressions remain expressions, not evaluated promises. Generic/inherited React types may be verbose; read their emitted declaration for the complete context.
8
+
9
+ Run `npm run check:reference` after build. It fails on removed documented props, changed types/defaults, reference targets and stale generated metadata. `node scripts/check-reference.mjs --write` updates only after reviewing the change. Human behavior, anatomy, form ownership, accessibility and unsupported combinations remain authored. This bounded generator avoids inventing defaults from optional TypeScript properties or flattening an overloaded component into a misleading universal schema. Other component pages remain PAGE promotion work; type discovery is not full-page coverage.
10
+
11
+ ## Nine existing guides: current contract differences
12
+
13
+ The catalogue has its own installed release. Its older release-labelled guides must retain their original meaning until that consumer is upgraded. The current public library references below supplement them; they do not silently relabel old documentation as current.
14
+
15
+ | Component | Current contract and authored reference |
16
+ | ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
17
+ | Checkbox | Native input ref and caller id; descriptions and errors merge with caller aria-describedby. indeterminate=false; application owns checked/mixed relationships. Native successful-control/reset behavior in FORMS.md. |
18
+ | SelectField | Native select ref and native value/defaultValue/onChange; generated or supplied id, external form, controlled reset restoration and merged descriptions. Options are value/label records; placeholder adds a disabled empty option. No searchable/free-text API. FORMS.md. |
19
+ | ProgressBar | Required label; value omitted means indeterminate; finite0–100 supplied by caller means determinate with aria-valuenow and rounded visible percent. tone defaults accent, alternatives success/danger. It does not estimate progress, fetch work, clamp invalid data or accept a native input ref. Unknown totals must remain unknown. |
20
+ | TextField | Native input ref/attributes; label, hint/error, optional leadingIcon/trailing and maxLength counter including0. Controlled/default ownership and external form/reset in FORMS.md; decorative adornments are not labels. |
21
+ | TextArea | Native textarea ref/attributes, visible label/help/error, maxLength counter and controlled/default/reset contracts in FORMS.md. rows defaults to3; autoResize defaults false and, when enabled, measures height from rendered content on input/render/reset. Check constrained containers. It is not a rich-text editor. |
22
+ | Dialog | Native dialog ref, controlled open/onClose, required title/children, optional description/footer; placement=center/left/right. Typed body/footer/close-button parts, focus overrides, dismissal, scroll and native top-layer ownership in OVERLAYS.md. A drawer is this placement composition, not another export. |
23
+ | Tabs | Native div ref and typed list/button/panel parts; default/controlled stable-ID selection, automatic activation and RTL arrows in COMPOSITION.md. No disabled-tab or automatic URL/router contract. |
24
+ | ToastProvider | Children plus translated region/dismiss labels. useToast().show requires provider; latest3 queue, polite region,5s timeout with hover/focus pause. No command ID/update/undo/durable inbox. HOOKS.md. |
25
+ | DropdownMenu | Native trigger props/ref and one custom ref-forwarding button via renderTrigger; controlled/default state, stable item IDs and disabled choices. Portal/collision/native-dialog integration supersedes old local-only geometry; no general submenus. OVERLAYS.md. |
26
+
27
+ The historical nine-guide audit compares the old installed declarations with the current implementation, rather than overwriting older limits. Guide URLs/search and catalogue composition remain deferred. The public component-page contract in DOCS.md still applies before promoting a full page; a row here is a focused audit record, not a claim that every PAGE acceptance item is finished.
28
+
29
+ ## Forms, anatomy and states
30
+
31
+ Native field refs target the actual input/select/textarea; Dialog targets dialog and Tabs targets its root div. ProgressBar and ToastProvider have no native ref contract. DropdownMenu exposes its trigger through triggerProps, not a root forwardRef. Labels, description IDs, aria-invalid, button types and successful controls must stay attached to the correct element. Error takes precedence over hint in Field; loading/service failure is separate application state.
32
+
33
+ Read [FORMS.md](FORMS.md), [COMPOSITION.md](COMPOSITION.md), [OVERLAYS.md](OVERLAYS.md), [COMBOBOX.md](COMBOBOX.md) and [RECIPES.md](RECIPES.md) for actual runnable sources, named/default state, form reset, keyboard/focus and optional parts. Styling and state selectors belong to STYLING.md; version-specific source and issue paths use the public reproduction. Long labels, disabled fields and both themes need final composition checks. RTL/forced-colors coverage is fixture-specific; manual assistive-technology support is recorded in SUPPORT.md rather than inferred from emitted types.
34
+
35
+ ## Version and reproduction
36
+
37
+ Reference version **0.6.1** (candidate until published). [Versioned source](https://github.com/abuzareal/contour-ui/tree/v0.6.1/src) and [emitted type inventory](PUBLIC-API.md) describe this contract; tag links resolve after release. [Report Prop reference 0.6.1](https://github.com/abuzareal/contour-ui/issues/new?template=bug_report.yml&component=Prop%20reference&version=0.6.1), using the [public minimal reproduction](examples/reproduction) and synthetic data.