Skip to main content

ranui

Use when building UI with the ranui web-component library (elements like `<r-button>`, `<r-modal>`, `<r-select>`, `<r-input>`, `<r-message>`) or its fluent DOM builder (`ranui/builder` — Div/View/Span/signal/createEffect/EventManager). Covers common import examples, conventions, accessibility, and where the authoritative API and export references live.

Informations de source

Dépôt
chaxus/ran
Dernière activité de la source
17 octobre 2026 à 06:37
Langue détectée de SKILL.md
anglais
Étoiles
270
Forks
23

Options d'installation

Le prompt qui vérifie d'abord la source est sélectionné par défaut. Vous pouvez passer à une commande directe ou télécharger une copie locale.

Vérifiez les fichiers source

Lisez SKILL.md et les fichiers associés affichés par SkillsMP avant de décider de l'installer.

Affichage de SKILL.md

SKILL.md
Instructions source · Aperçu en lecture seule
name
ranui
description
Use when building UI with the ranui web-component library (elements like `<r-button>`, `<r-modal>`, `<r-select>`, `<r-input>`, `<r-message>`) or its fluent DOM builder (`ranui/builder` — Div/View/Span/signal/createEffect/EventManager). Covers common import examples, conventions, accessibility, and where the authoritative API and export references live.
# ranui — web component library Framework-agnostic Web Components (Custom Elements + Shadow DOM). Works in React, Vue, Svelte, Solid, or plain JS. Each element is `<r-*>` and is used like native HTML. Styling crosses the shadow boundary via **CSS variables**, **`::part()`**, or the per-instance **`sheet`** attribute (escape hatch). ## Authoritative reference (read these for exact APIs — don't guess) When `ranui` is installed in a project, its docs ship inside the package: - **`node_modules/ranui/docs/COMPONENTS.md`** — generated per-element API: every element's attributes, typed properties, events (with `detail` shape), slots, and `::part()` names. This is the source of truth for props/events. Regenerated in the source repo via `npm run doc:api`. - **`node_modules/ranui/docs/DESIGN.md`** — design system rules (color states, spacing, motion, accessibility §7, pre-ship checklist). - **`node_modules/ranui/docs/INTERFACE_GUIDE.md`** — short decision-to-owner index. - **`node_modules/ranui/docs/INTERACTION.md`** — observable input, focus, keyboard, drafts, feedback, progress and recovery; read for behavior changes. - **`node_modules/ranui/docs/WORKFLOW_PATTERNS.md`** — optional batch/queue, settings, account/data and revision recipes. Load only for a relevant task; these are host responsibilities, not additional library APIs. Visual craft remains in DESIGN. - **`node_modules/ranui/docs/style-tokens-public.md`** — the CSS variable (theming token) catalog. If a generated contract omits a detail, check the element's declaration through the installed package's `exports` → `types` target before inspecting repository source. **`node_modules/ranui/docs/CODING.md`** and **`node_modules/ranui/CLAUDE.md`** also ship with the package: engineering rules and the detailed implementation reference (architecture, builder, LESS conventions, testing). Source copies live in `packages/ranui`. ## Import map Start with the host's existing controls, framework and theme authority; a small fix does not require a new component or state layer. Read only applicable owner sections, then stop when the supported contract, patch and evidence are clear. Foundation declarations ship in the installed package’s `dist/ranui.css`; component overrides are in the generated token catalog. Minimal bootstrap (once in the host entry): ```ts import 'ranui/style'; // foundation tokens and shared styles import 'ranui/button'; import 'ranui/input'; ``` Add `import 'ranui/fonts'` only when the host wants bundled Geist fonts. If the host opts into ranui's persisted light/dark/system mode, use `import { initTheme } from 'ranui/theme'` and call `initTheme()` once. Preserve an existing host theme authority; do not add a switch or another persistence owner merely to use the components. Per-component, tree-shakeable side-effect imports register the custom element: ```ts import 'ranui/button'; // then use <r-button> import 'ranui/modal'; import 'ranui/select'; import 'ranui/input'; import 'ranui/message'; // also exposes an imperative message API import 'ranui/checkbox'; ``` Common element subpaths (examples, not a complete inventory): `button icon image input message skeleton tab tabpane radar modal select progress player popover dropdown content loading colorpicker math checkbox card router route link`. For all supported subpaths, read `exports` in the installed `node_modules/ranui/package.json`; use COMPONENTS.md for element contracts. The fluent DOM builder + reactivity (no custom-element registration): ```ts import { Div, View, Span, Label, ButtonBuilder, signal, createEffect, EventManager, Style } from 'ranui/builder'; ``` Consumer SSR rendering helpers are public exports: ```ts import { HTMLElementSSR, RanElement, h, renderToString } from 'ranui/ssr'; ``` Streaming rendering uses `ranui/ssr-stream`; types use `ranui/typings`. `defineSSR` is an internal registration helper at `@/utils/ssr-registry` in the ranui source checkout. It is not exported from `ranui/ssr` or a consumer registration subpath. ## Elements at a glance - **Forms**: `r-input`, `r-checkbox`, `r-select` (+ `r-option`, `r-dropdown-item` as options). The three field elements are **form-associated custom elements** (`attachInternals()` + `ElementInternals.setFormValue()`) — their values are collected by `new FormData(form)` when they're real descendants of a native `<form>`, same as any native field — no wrapper component required. Use `serializeForm(form)` (from `ranui`) to turn a submit into a plain object. `r-button`'s `type` chooses visual appearance, not native form submission. Use a native `<button type="submit">` when submit semantics are needed, or explicitly call `form.requestSubmit()` from the host action; do not assume `type="submit"` on `r-button` submits. `r-colorpicker` is not form-associated: read its `value` / `change` event (`detail.value`) and explicitly include it in the host's submitted data when needed. - **Feedback/overlay**: `r-message` (toasts), `r-modal`, `r-popover`, `r-loading`, `r-skeleton`, `r-progress`. - **Layout/content**: `r-card`, `r-section`, `r-tab`/`r-tabs`, `r-icon`, `r-img`, `r-link`, `r-math`, `r-player`, `r-radar`. - **Routing**: `r-router`, `r-route`, `r-link` (history/hash SPA routing). - **Streaming transcript**: `r-conversation` — renders an append-only event log. Register each kind of content as a view (`match`/`start`/`update` fold state, `mount`/`patch` render it) **before the first `push`**; it throws afterwards. Bottom-follow is on by default and does not fight the reader; `pinnedchange` drives a "jump to latest" button. Use `<r-markdown>` as the prose row — its `mode="streaming"` already closes half-streamed markdown. Projection and cadence: `ranuts/conversation`. - **Tool calls**: `r-tool-card` — set `call` / `result` / `status` from a **declared intent** (`generic` / `terminal` / `diff`), never markup. Views must be pure functions of the call's arguments, because they are recomputed on replay; an unrecognised card degrades to `generic` instead of throwing. - **Chain of thought**: `r-reasoning` — expands while `streaming` is set, collapses when it clears, and **stops following once the reader opens or closes it themselves** (setting `open` from script counts). Feed `content` from `ranuts/stream`'s `reasoning-delta` blocks. - **Attachments**: `r-attachments` — holds the files staged with a message, previews them, validates, and owns its object URLs (revoked on detach/clear/disconnect). It does not collect files: call `add(files)` from paste, drop or a picker. Removal is `detach(id)`, because `remove()` already means "take yourself out of the document". Rejections are reported, never silent. - **Dictation**: `r-voice-button` — a microphone button over `ranuts`' `createSpeechRecognizer`. It reports the **whole capture so far** on each `voiceresult` (interim results are revised), so remember the text already in the box at `voicestart` and concatenate once. It never sends, hides itself where the API is absent, and only `denied`/`failed` are worth surfacing — `noSpeech`/`aborted` are routine. ## Builder + reactivity (from `ranui/builder`) - `Div()/View('r-x')/Span()/...` — chainable: `.class()`, `.attr()`, `.part()`, `.role()`, `.text()`, `.children(...)`, `.on(event, handler)`, `.build()`. - `signal(initial)` → `[getter, setter]`; `createEffect(fn)` re-runs `fn` when the signals it reads change (returns a disposer). - `EventManager` — `.on(target, type, handler)` with `.abort()` to remove all listeners at once (use in `disconnectedCallback`). ## Usage example Declarative — use elements like native HTML (after importing the subpath): ```html <r-select value="a"> <r-option value="a">Apple</r-option> <r-option value="b">Banana</r-option> </r-select> <r-input label="Email" name="email"></r-input> ``` Imperative — create, configure, and wire events (event `detail` shapes are in COMPONENTS.md, e.g. `r-select change → { value, label }`): ```ts import 'ranui/select'; import message from 'ranui/message'; const sel = document.createElement('r-select'); sel.setAttribute('value', 'a'); sel.addEventListener('change', (e) => console.log((e as CustomEvent).detail.value)); document.body.append(sel); message.success('Saved'); // imperative toast API: info | success | warning | error | toast ``` Builder + reactivity — compose DOM with signals (great for framework-free views): ```ts import { Div, ButtonBuilder, signal, createEffect } from 'ranui/builder'; const [count, setCount] = signal(0); const label = Div().build(); createEffect(() => { label.textContent = `Count: ${count()}`; }); // re-runs on change const btn = ButtonBuilder() .text('inc') .on('click', () => setCount(count() + 1)) .build(); document.body.append(label, btn); ``` ## Accessibility (already built in — rely on it, don't re-implement) - `r-message` toasts announce via an `aria-live` region (errors = assertive `alert`). - `r-checkbox`/`r-input`/`r-select` are form-associated and labelled; checkbox is keyboard-toggleable (Space/Enter) with `role=checkbox`/`aria-checked`. - `r-tabs` follows the WAI-ARIA tabs pattern (roles + roving tabindex + arrow keys). - `r-colorpicker` sliders are `role=slider` with arrow-key adjustment; the swatch opens via Enter/Space. - All components honour `prefers-reduced-motion`. For custom UI you build, follow DESIGN.md §7 (keyboard nav, visible focus, ARIA). ## Conventions & gotchas - In the ranui source checkout, component authors register with the internal `defineSSR('r-name', Component)` helper (keeps SSR working). Consumers register shipped elements through their public side-effect imports; the internal helper is not an installed-package API. - Shadow DOM isolates styles: external `<label for>` / `aria-labelledby` do NOT cross into a component's shadow root — use the component's own `label` attribute/slot. - Component CSS uses CSS variables with dark-safe fallbacks; theme via tokens, not by reaching into shadow internals. - Prefer subpath imports (`ranui/button`), never `ranui/dist/...` or internal `@/...`.
Voir sur GitHub