Files
WRNexusJSDoc/app/pages/packages/ui.wrn
T

119 lines
22 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
page wrnexusui {
seo {
title = "@wrnexus/ui"
description = "Themeable server-rendered UI components and CSS."
}
view {
<div class="docs-shell">
<a href="#main" class="skip-link">Skip to content</a>
<header class="topbar">
<a class="brand" href="/"><span>W</span> WRNexusJS</a>
<nav aria-label="Primary"><a href="/getting-started">Get started</a><a href="/packages">Packages</a><a href="https://component.wrnexusjs.dev/">Components</a><a href="/language">Language</a><a href="/architecture">Architecture</a></nav>
<div class="topbar-actions"><a class="preview-pill" href="/access">Private preview · v0.8.7</a><button data-wire-theme-toggle class="theme-button" aria-label="Toggle color theme" title="Toggle color theme">◐</button></div>
</header>
<div class="mobile-doc-nav"><details><summary>Browse documentation</summary><nav><a href="/getting-started">Get started</a><a href="/packages">Packages</a><a href="https://component.wrnexusjs.dev/">Components</a><a href="/language">Language</a><a href="/architecture">Architecture</a><a href="/tutorial">Tutorial</a><a href="/guides/project-structure">Guides</a><a href="/examples">Examples</a><a href="/search">Search</a></nav></details></div>
<main id="main" class="portal-main docs-layout docs-layout--navigation"><aside class="docs-section-menu" aria-label="Documentation sections"><nav>
<section><strong>Get started</strong><a href="/getting-started">Quick start</a><a href="/tutorial">Tutorial</a><a href="/guides/full-stack-auth-demo">Auth dashboard demo</a><a href="/guides/configuration-and-profiles">Configuration</a></section>
<section><strong>Build</strong><a href="/guides/pages-and-components">Pages and components</a><a href="/guides/routing">Routing</a><a href="/guides/server-data">Server data</a><a href="/guides/forms-and-validation">Forms and validation</a><a href="/guides/database">Database</a></section>
<section><strong>Auth and security</strong><a href="/guides/authentication">Authentication</a><a href="/guides/authorization">Authorization</a><a href="/guides/security">Application security</a><a href="/security">Security policy</a></section>
<section><strong>Reference</strong><a href="/packages">Packages overview</a><a href="/packages/cli">CLI</a><a href="/language">.wrn language</a><a href="https://component.wrnexusjs.dev/">Components</a><a href="/examples">Examples</a></section>
<section class="package-menu"><strong>Packages</strong><a href="/packages/ai">@wrnexus/ai</a><a href="/packages/auth">@wrnexus/auth</a><a href="/packages/authz">@wrnexus/authz</a><a href="/packages/benchmark">@wrnexus/benchmark</a><a href="/packages/cache">@wrnexus/cache</a><a href="/packages/captcha">@wrnexus/captcha</a><a href="/packages/cli">@wrnexus/cli</a><a href="/packages/compiler">@wrnexus/compiler</a><a href="/packages/content">@wrnexus/content</a><a href="/packages/core">@wrnexus/core</a><a href="/packages/csr">@wrnexus/csr</a><a href="/packages/db">@wrnexus/db</a><a href="/packages/dev-server">@wrnexus/dev-server</a><a href="/packages/dev-toolbar">@wrnexus/dev-toolbar</a><a href="/packages/encryption">@wrnexus/encryption</a><a href="/packages/graphql">@wrnexus/graphql</a><a href="/packages/helpers">@wrnexus/helpers</a><a href="/packages/i18n">@wrnexus/i18n</a><a href="/packages/identity">@wrnexus/identity</a><a href="/packages/image">@wrnexus/image</a><a href="/packages/jwt">@wrnexus/jwt</a><a href="/packages/language-server">@wrnexus/language-server</a><a href="/packages/mcp">@wrnexus/mcp</a><a href="/packages/mobile">@wrnexus/mobile</a><a href="/packages/native">@wrnexus/native</a><a href="/packages/oauth">@wrnexus/oauth</a><a href="/packages/observability">@wrnexus/observability</a><a href="/packages/playground">@wrnexus/playground</a><a href="/packages/plugin">@wrnexus/plugin</a><a href="/packages/pubsub">@wrnexus/pubsub</a><a href="/packages/pwa">@wrnexus/pwa</a><a href="/packages/queue">@wrnexus/queue</a><a href="/packages/reactive">@wrnexus/reactive</a><a href="/packages/realtime">@wrnexus/realtime</a><a href="/packages/router">@wrnexus/router</a><a href="/packages/security">@wrnexus/security</a><a href="/packages/ssr">@wrnexus/ssr</a><a href="/packages/store">@wrnexus/store</a><a href="/packages/styles">@wrnexus/styles</a><a href="/packages/syntax">@wrnexus/syntax</a><a href="/packages/test">@wrnexus/test</a><a href="/packages/tracking">@wrnexus/tracking</a><a href="/packages/typecheck">@wrnexus/typecheck</a><a href="/packages/ui">@wrnexus/ui</a><a href="/packages/uploader">@wrnexus/uploader</a><a href="/packages/validation">@wrnexus/validation</a></section>
</nav></aside><div class="docs-reading-column">
<article class="documentation prose standalone package-document"><nav class="breadcrumbs" aria-label="Breadcrumb"><a href="/">Home</a><span>/</span><a href="/packages">Packages</a><span>/</span><span aria-current="page">@wrnexus/ui</span></nav><section class="doc-intro"><span class="eyebrow">Frontend · Package reference</span><h1>@wrnexus/ui</h1><p>Themeable server-rendered UI components and CSS.</p><div class="doc-meta"><span>v0.8.7</span><span>Private registry</span><span>Frontend</span></div><section id="access" class="access-callout"><h2>Install the package</h2><p>After WorkRoot approves private registry access, install the release-aligned package:</p><pre><code>bun add @wrnexus/ui@0.8.7</code><button type="button" class="copy-button" aria-label="Copy installation command">Copy</button></pre><p><a href="/access">Request preview access</a>. Never put registry tokens in source control.</p></section></section><section id="guide"><blockquote>First-party Wire UI component library — a set of themeable <code>.wrn</code> components plus a single tokenized stylesheet.</blockquote>
<p>Part of the <strong>WRNexusJS</strong> framework — an SSR-first, Bun-native full-stack web framework.</p>
<h3 id="overview">Overview</h3>
<p><code>@wrnexus/ui</code> ships a library of server-rendered <code>.wrn</code> components (layout, form controls, and feedback UI) together with one themeable stylesheet, <code>ui.css</code>. The components are <strong>auto-discovered</strong> by the framework router — you don't import them in code. Once the package's component directory is on the router's scan path, you mount any component in a page with <code>data-component=&quot;&lt;name&gt;&quot;</code>. Every visual is driven by <code>var(--wire-*)</code> theme tokens, so components restyle instantly when the theme changes. The tiny JS surface (<code>src/index.ts</code>) exists only so the toolchain (CLI build + dev server) can locate the component directory and stylesheet.</p>
<p>The complete PDF-aligned catalog currently contains <strong>85 components</strong>. The generated <code>COMPONENTS.md</code> and <code>component-reference.json</code> files document every mount name, prop, inferred type, default/required status, slot, event, category, and source file directly from the packaged <code>.wrn</code> source.</p>
<pre data-language="bash"><code>bun add @wrnexus/ui</code></pre>
<blockquote>Private package — the machine must be authenticated to the <code>wrnexus</code> npm org</blockquote>
<blockquote>(a read token in <code>~/.npmrc</code>). Requires <strong>Bun</strong> (Node is not supported).</blockquote>
<p>In practice you rarely install this directly: <code>@wrnexus/cli</code> and <code>@wrnexus/dev-server</code> already depend on it and wire it into the router for you (see [Auto-discovery](#auto-discovery)).</p>
<h3 id="components">Components</h3>
<p>Components live as <code>.wrn</code> files under <code>packages/ui/components/</code>. The canonical mount name comes from the component declaration (for example, <code>component Button</code> mounts as <code>data-component=&quot;Button&quot;</code>). Component lookup is case-insensitive, so existing lowercase mounts continue to work. Each component accepts a <code>class</code> prop (appended to its root element), and most render their body from either a named prop or the default slot.</p>
<h4 id="layout">Layout</h4>
<div class="table-wrap"><table>
<thead><tr><th>Name</th><th>Purpose</th><th>Key props</th></tr></thead>
<tbody><tr><td><code>container</code></td><td>Max-width centered content wrapper</td><td><code>class</code></td></tr><tr><td><code>stack</code></td><td>Vertical column with gap</td><td><code>gap</code> (08)</td></tr><tr><td><code>hstack</code></td><td>Horizontal row with gap</td><td><code>gap</code> (08)</td></tr><tr><td><code>grid</code></td><td>CSS grid container</td><td>see source</td></tr><tr><td><code>divider</code></td><td>Horizontal rule</td><td><code>class</code></td></tr><tr><td><code>spacer</code></td><td>Flexible/empty spacing element</td><td>see source</td></tr></tbody></table></div>
<h4 id="core-feedback">Core / feedback</h4>
<div class="table-wrap"><table>
<thead><tr><th>Name</th><th>Purpose</th><th>Key props</th></tr></thead>
<tbody><tr><td><code>button</code></td><td>Button</td><td><code>label</code>, <code>variant</code> (<code>default</code>\</td><td><code>primary</code>\</td><td><code>danger</code>\</td><td><code>ghost</code>), <code>size</code> (<code>sm</code>\</td><td><code>md</code>\</td><td><code>lg</code>), <code>type</code></td></tr><tr><td><code>input</code></td><td>Text input</td><td>see source</td></tr><tr><td><code>textarea</code></td><td>Multi-line input</td><td>see source</td></tr><tr><td><code>checkbox</code></td><td>Checkbox</td><td>see source</td></tr><tr><td><code>badge</code></td><td>Small status badge</td><td><code>label</code>, <code>variant</code></td></tr><tr><td><code>alert</code></td><td>Callout box</td><td><code>variant</code> (<code>info</code>\</td><td><code>success</code>\</td><td><code>danger</code>\</td><td><code>warning</code>), <code>title</code>, <code>message</code></td></tr><tr><td><code>card</code></td><td>Padded, bordered surface</td><td><code>class</code></td></tr><tr><td><code>avatar</code></td><td>User avatar</td><td>see source</td></tr><tr><td><code>spinner</code></td><td>Loading indicator</td><td>see source</td></tr><tr><td><code>disclosure</code></td><td>Expandable details/summary</td><td>see source</td></tr><tr><td><code>theme-toggle</code></td><td>Theme switch button (binds <code>data-wire-theme-toggle</code>)</td><td><code>label</code></td></tr></tbody></table></div>
<h4 id="additional-controls-data-display">Additional controls &amp; data display</h4>
<p>Also shipped: <code>select</code>, <code>radio</code>, <code>switch</code>, <code>progress</code>, <code>tag</code>, <code>skeleton</code>, <code>tooltip</code>, <code>table</code>, <code>FAQAccordion</code>, <code>AnnouncementBar</code>, and <code>BackToTop</code>.</p>
<p>The PDF-defined minimum release and essential build-first set also includes typed typography, form primitives, loading actions, combobox and multi-select, time/date-time and recurring schedule controls, confirmation dialogs, data tables, filters, desktop/mobile navigation, mega menus, marketing/product/legal page shells, product and metric cards, FAQ composition, pricing comparison, SDK tabs, legal navigation, and cookie preferences.</p>
<p><code>Seo</code> and <code>StructuredData</code> remain framework/page concerns rather than body components: use the native page <code>seo &#123; ... &#125;</code> block and document-head APIs so metadata is emitted in <code>&lt;head&gt;</code> instead of invalid component markup.</p>
<p>The authoritative, always-current list is <code>uiComponentNames()</code> (below), which reads the component directory at runtime.</p>
<p>For the full catalog, see [<code>COMPONENTS.md</code>](./COMPONENTS.md). The machine-readable equivalent is exported as <code>@wrnexus/ui/component-reference.json</code>.</p>
<h3 id="api">API</h3>
<p>The JS module (<code>@wrnexus/ui</code>) exposes five helpers used by the build tooling to locate the component assets. There is no component code to import — the components are <code>.wrn</code> files rendered server-side.</p>
<div class="table-wrap"><table>
<thead><tr><th>Export</th><th>Signature</th><th>Returns</th></tr></thead>
<tbody><tr><td><code>uiComponentsDir</code></td><td><code>() =&gt; string</code></td><td>Absolute path to the <code>.wrn</code> component directory (feed to <code>buildRouter</code>'s <code>componentDirs</code>).</td></tr><tr><td><code>uiCssPath</code></td><td><code>() =&gt; string</code></td><td>Absolute path to <code>ui.css</code>.</td></tr><tr><td><code>uiCss</code></td><td><code>() =&gt; string</code></td><td>The <code>ui.css</code> file contents (all <code>.wire-*</code> classes, themed via tokens).</td></tr><tr><td><code>uiComponentNames</code></td><td><code>() =&gt; string[]</code></td><td>Sorted list of declared built-in component names.</td></tr><tr><td><code>uiComponentPath</code></td><td><code>(name: string) =&gt; string</code></td><td>Absolute source path for a declared component name or case-insensitive alias.</td></tr></tbody></table></div>
<h4 id="ui-css-asset-export"><code>./ui.css</code> asset export</h4>
<p><code>package.json</code> also exposes the raw stylesheet as a subpath asset:</p>
<pre data-language="json"><code>&quot;exports&quot;: &#123;
&quot;.&quot;: &quot;./src/index.ts&quot;,
&quot;./ui.css&quot;: &quot;./ui.css&quot;
&#125;</code></pre>
<p>The framework serves this stylesheet once at <code>/__wrnexus/ui.css</code>, so pages get all component styles from a single request.</p>
<h4 id="component-styles-and-motion">Component styles and motion</h4>
<p>Components own their BEM styles in local <code>style &#123;&#125;</code> blocks and do not require a Tailwind scan. <code>ui.css</code> supplies only global tokens, resets, and shared primitives. Applications can still use Tailwind independently in their own source files.</p>
<p>The shared stylesheet gives all component boundaries consistent, GPU-friendly entry and interaction motion. Override <code>--wire-motion-fast</code>, <code>--wire-motion-base</code>, <code>--wire-motion-slow</code>, <code>--wire-ease-standard</code>, or <code>--wire-ease-emphasized</code> to tune it. Hover lift is limited to precise pointing devices and <code>prefers-reduced-motion</code> is honored automatically.</p>
<h4 id="using-the-selected-theme-in-application-ui">Using the selected theme in application UI</h4>
<p>The active theme and palette are not limited to <code>@wrnexus/ui</code> components. The framework exposes the resolved values as semantic CSS custom properties, so pages and custom <code>.wrn</code> components can use the same contract:</p>
<pre data-language="css"><code>.account-card &#123;
background: var(--wire-color-surface);
color: var(--wire-color-text);
border: 1px solid var(--wire-color-border);
&#125;
.account-card__action &#123;
background: var(--wire-color-primary);
color: var(--wire-color-primary-contrast);
&#125;</code></pre>
<p>Stable no-spacing helper classes are also available: <code>wire-bg-page</code>, <code>wire-bg-surface</code>, <code>wire-bg-surface-2</code>, <code>wire-bg-primary</code>, <code>wire-bg-secondary</code>, <code>wire-text</code>, <code>wire-text-muted</code>, <code>wire-text-primary</code>, <code>wire-text-success</code>, <code>wire-text-warning</code>, <code>wire-text-danger</code>, and <code>wire-border</code>.</p>
<p>Tailwind-authored custom markup can continue using the palette families already used by packaged components. <code>indigo-*</code> and <code>violet-*</code> resolve to primary, <code>blue-*</code> to info, <code>emerald-*</code>/<code>green-*</code> to success, <code>amber-*</code> to warning, and <code>red-*</code>/<code>rose-*</code> to danger. These aliases live at <code>:root</code>, so they work outside a <code>[data-component]</code> boundary too.</p>
<h3 id="usage">Usage</h3>
<h4 id="auto-discovery">Auto-discovery</h4>
<p>The router scans extra <code>componentDirs</code> (in addition to the app's own <code>app/components</code>) and keys components by name. Library dirs are scanned <strong>first</strong> and <code>app/components</code> <strong>last</strong>, so an app component of the same name shadows the library's. The CLI build (<code>@wrnexus/cli</code>) and dev server (<code>@wrnexus/dev-server</code>) both wire the UI directory in for you:</p>
<pre data-language="ts"><code>import &#123; buildRouter &#125; from &quot;@wrnexus/router&quot;;
import &#123; uiComponentsDir &#125; from &quot;@wrnexus/ui&quot;;
const router = buildRouter(appDir, &#123; componentDirs: [uiComponentsDir()] &#125;);</code></pre>
<h4 id="mounting-components-in-a-page">Mounting components in a page</h4>
<p>Once discovered, mount any component by name via <code>data-component</code>. Quoted attributes (other than <code>data-component</code>) become string props:</p>
<pre data-language="html"><code>&lt;div data-component=&quot;card&quot;&gt;
&lt;div data-component=&quot;badge&quot; label=&quot;New&quot;&gt;&lt;/div&gt;
&lt;button data-component=&quot;button&quot; label=&quot;Save&quot; variant=&quot;primary&quot; size=&quot;lg&quot;&gt;&lt;/button&gt;
&lt;div data-component=&quot;alert&quot; variant=&quot;success&quot; title=&quot;Done&quot; message=&quot;Saved.&quot;&gt;&lt;/div&gt;
&lt;/div&gt;</code></pre>
<h3 id="overrides">Overrides</h3>
<p>Ways to customize the components, in increasing order of power:</p>
<p>1. <strong>Theme tokens</strong> — override CSS custom properties such as <code>--wire-color-primary</code>, <code>--wire-color-surface</code>, <code>--wire-radius-sm</code>, etc. Every component style resolves through <code>var(--wire-*)</code>, so changing a token restyles everything instantly (including across theme switches). 2. <strong>App CSS</strong> — redefine a <code>.wire-*</code> class in your own stylesheet, which is loaded after <code>ui.css</code> and therefore wins. 3. <strong><code>class</code> prop</strong> — pass a <code>class</code> prop to a component; it is appended to the component's root element, letting you add per-instance classes without touching the base styles. 4. <strong><code>wrnexus eject &lt;name&gt;</code></strong> — copy the component's <code>.wrn</code> source into your <code>app/components</code>, where (because app components shadow library ones) you fully own and can edit it. Use <code>uiComponentNames()</code> for the list of ejectable names.</p>
<h3 id="requirements-notes">Requirements / Notes</h3>
<ul>
<li><strong>Bun-only</strong> — the package uses standard fs/path/url APIs but is published and</li>
<p>consumed within the Bun-native WRNexusJS toolchain (Node is not supported).</p>
<li>Peer packages: components are discovered and rendered by</li>
<p>[<code>@wrnexus/router</code>](../router) (via <code>componentDirs</code>) and served by [<code>@wrnexus/dev-server</code>](../dev-server) / built by [<code>@wrnexus/cli</code>](../cli).</p>
<li>Depends on [<code>@wrnexus/core</code>](../core) (<code>dependencies</code>).</li>
<li><code>theme-toggle</code> relies on the framework's theme runtime, which binds the</li>
<p><code>data-wire-theme-toggle</code> attribute — no per-component JS is required.</p>
</ul></section><section id="api" class="api"><h2>Complete TypeScript API</h2><p>Generated from the exact installed package declarations.</p><pre data-language="typescript"><code>
export &#123; &#125;
</code></pre></section><section id="examples" class="examples"><h2>Examples</h2><p>Copy-ready examples from the installed package documentation.</p><div class="example-grid"><article class="example-card"><h3>Auto-discovery</h3><pre data-language="ts"><code>import &#123; buildRouter &#125; from &quot;@wrnexus/router&quot;;
import &#123; uiComponentsDir &#125; from &quot;@wrnexus/ui&quot;;
const router = buildRouter(appDir, &#123; componentDirs: [uiComponentsDir()] &#125;);</code></pre></article><article class="example-card"><h3>Mounting components in a page</h3><pre data-language="html"><code>&lt;div data-component=&quot;card&quot;&gt;
&lt;div data-component=&quot;badge&quot; label=&quot;New&quot;&gt;&lt;/div&gt;
&lt;button data-component=&quot;button&quot; label=&quot;Save&quot; variant=&quot;primary&quot; size=&quot;lg&quot;&gt;&lt;/button&gt;
&lt;div data-component=&quot;alert&quot; variant=&quot;success&quot; title=&quot;Done&quot; message=&quot;Saved.&quot;&gt;&lt;/div&gt;
&lt;/div&gt;</code></pre></article></div></section><section class="prose component-catalog-callout"><h2>Explore the component library</h2><p>Browse interactive examples and complete component usage in the dedicated WRNexusJS component showcase.</p><p><a class="primary" href="https://component.wrnexusjs.dev/">Browse all 102 components →</a></p></section></article></div>
<aside class="on-this-page"><h2>On this page</h2><nav><a class="toc-level-2" href="#guide">Guide</a><a class="toc-level-3" href="#overview">Overview</a><a class="toc-level-3" href="#components">Components</a><a class="toc-level-4" href="#layout">Layout</a><a class="toc-level-4" href="#core-feedback">Core / feedback</a><a class="toc-level-4" href="#additional-controls-data-display">Additional controls &amp; data display</a><a class="toc-level-3" href="#api">API</a><a class="toc-level-4" href="#ui-css-asset-export">./ui.css asset export</a><a class="toc-level-4" href="#component-styles-and-motion">Component styles and motion</a><a class="toc-level-4" href="#using-the-selected-theme-in-application-ui">Using the selected theme in application UI</a><a class="toc-level-3" href="#usage">Usage</a><a class="toc-level-4" href="#auto-discovery">Auto-discovery</a><a class="toc-level-4" href="#mounting-components-in-a-page">Mounting components in a page</a><a class="toc-level-3" href="#overrides">Overrides</a><a class="toc-level-3" href="#requirements-notes">Requirements / Notes</a><a class="toc-level-2" href="#api">Complete API</a><a class="toc-level-2" href="#examples">Examples</a></nav></aside>
</main>
<footer><div class="footer-brand"><span class="footer-mark" aria-hidden="true">W</span><p><strong>WRNexusJS 0.8.7</strong><span>Complete API documentation generated from installed package declarations.</span></p></div><nav aria-label="Footer"><a href="/packages">All packages</a><a href="/getting-started">Get started</a><a href="/security">Security</a><a href="/support">Support</a><a href="/llms.txt">AI guide</a></nav><p class="footer-meta">Private Developer Preview · Bun-native</p></footer>
</div>
}
}