Doc Page

FAQ

Answers to common integration and contract questions.

Updated: 2026-06-04 · Owner: docs@nake-ui

Is nake-ui A Visual Component Library?

No. nake-ui is headless and unstyled by architecture. It provides behavior, semantics, state reflection, keyboard models, ARIA relationships, schemas, and adapter integration. Product visuals are your responsibility.

If you want a fully branded visual kit after install, use a visual component library or design system. nake-ui sits underneath that layer: it stabilizes how Dialog closes, Menu moves focus, Select participates in forms, and Combobox exposes highlighted options.

Sources: shared/en/faq

Why Use data Attributes?

Public data-* attributes make state inspectable by humans, tests, validators, and agents. They also provide stable styling hooks that do not depend on private implementation details.

Use classes for styling. Use ARIA plus public data-* for semantic truth.

For example, a selected option should not only be .is-active. It should also expose aria-selected, data-selected, or data-highlighted so tests can assert it, assistive technology can understand it, and agents can locate broken state.

Sources: shared/en/faq

Which Adapter Should I Use?

Use the adapter for your host runtime:

  • React app: @nake-ui/adapter-react
  • Plain DOM or custom framework: @nake-ui/adapter-vanilla
  • Vue 3 app: @nake-ui/adapter-vue
  • Solid app: @nake-ui/adapter-solid
  • Svelte app: @nake-ui/adapter-svelte

All five adapters target the same canonical v1 primitive behavior.

Do not mix multiple adapters around the same primitive instance. React wrappers, Vue composables, and Vanilla bindings each own lifecycle and cleanup expectations; mixing them blurs refs, listeners, registrations, and portal ownership.

Sources: shared/en/faq

Can I Use My Own CSS?

Yes. The packages are headless. Optional theme packages are starter skins and examples of public selector usage. Your product can use any styling system as long as it preserves focus visibility, state readability, and accessible contrast.

Prefer selectors based on the public contract:

[data-ui="tabs"][data-slot="trigger"][data-state="active"] {
  border-block-end-color: var(--accent);
}

Avoid making a styling class the semantic truth. Classes can follow state; they should not replace ARIA and data-*.

Sources: shared/en/faq

Can I Wrap Primitive Parts?

Yes, but preserve the slot contract and forwarded props:

  • Keep required ARIA attributes.
  • Forward refs or element handles where the adapter needs them.
  • Preserve data-ui, data-slot, and state attributes.
  • Keep event handlers composed with the adapter handlers.
  • Do not swallow id values used by ARIA links.

After wrapping, inspect the rendered DOM. A common bug is forwarding className while dropping ref, id, aria-controls, onKeyDown, or data-slot. The visual result may look fine while keyboard, SSR, or validation fails.

Sources: shared/en/faq

How Do Controlled And Uncontrolled Modes Differ?

Controlled mode means your app owns the state value and updates it through callbacks. Uncontrolled mode means the primitive owns the internal state after initial defaults.

Behavior should be equivalent. The difference is ownership, not semantics.

In controlled mode, your app must update the controlled prop after the callback fires. Otherwise the click can happen while data-state or aria-selected remains stale. Do not pass value and defaultValue for the same state dimension unless a migration path is explicitly documented.

Sources: shared/en/faq

Why Are Some React Components Not In The v1 Catalog?

The React adapter contains adapter-owned experimental components. The docs catalog only promotes canonical primitives that have core behavior, schemas, specs, adapter coverage, and validation artifacts across the supported route family.

That does not mean other components can never become public. It means their anatomy, state model, keyboard rules, ARIA relationships, validator rules, adapter parity, and examples are not yet stable enough for the canonical catalog.

Sources: shared/en/faq

What Breaks Compatibility?

Compatibility-sensitive changes include:

  • Public data-* attribute names or values.
  • Slot names.
  • Schema fields.
  • Required ARIA relationships.
  • Keyboard behavior.
  • Controlled/uncontrolled callback contracts.
  • Generated docs or agent artifact shape.

Treat these changes like API events with migration notes.

When a public contract must change, use a deprecate -> document -> migrate -> remove path. Keep the old attribute or slot long enough to emit validator warnings and fix suggestions before removing it in a clear version.

Sources: shared/en/faq

Can It Work Without JavaScript?

It depends on the primitive. Disclosure can often degrade more gracefully. Dialog, Menu, Select, and Combobox usually need client activation for focus scope, typeahead, outside dismiss, or active-descendant behavior.

SSR output should still be semantically safe:

  • Initial labels, roles, and ARIA linkage resolve.
  • Initial open/closed or selected state is deterministic.
  • Unactivated markup does not expose the wrong focus target.
  • Client-only measurement does not rewrite the base contract.

Sources: shared/en/faq

Why Do The Docs Mention Agents?

Because one project goal is to make UI contracts readable and repairable by tools. Agent-friendly does not mean exposing internal project operations to end users; it means public DOM, schemas, validators, and examples are clear enough for tools to generate correct code.

Maintainer-facing release checklists, rollback notes, and observability playbooks are internal workbench docs and are not published as user-facing production entries.

Sources: shared/en/faq

Where Should Bugs Be Tested?

Use the narrowest test that catches the bug:

  • Controller state bug: primitive unit test.
  • Adapter render bug: adapter contract test.
  • Cross-adapter behavior bug: parity test.
  • Site docs route bug: site unit/e2e test.
  • Schema/validator bug: schemas or devtools validator tests.

If you are unsure, first write the smallest test that reproduces the bug, then decide whether to move it down to the shared layer. A ref forwarding bug in Vue should stay near Vue; a selection bug in every adapter belongs in the primitive/controller layer.

Sources: shared/en/faq