refactor: migrate legacy wire namespace to wrn
This commit is contained in:
@@ -39,7 +39,7 @@ Legend:
|
||||
| 28 | Performance budgets | configurable route JS/CSS, HTML, image, hydration, and SSR budgets | Implemented |
|
||||
| 29 | Observability | tracer/span APIs, request middleware, Server-Timing, console exporter | Implemented |
|
||||
| 30 | Component architecture | Existing `@wrnexus/ui` inventory retained; syntax metadata supports typed tooling | Existing + hardened |
|
||||
| 31 | Design tokens | Existing `--wire-*` system and theme resolution retained | Existing + hardened |
|
||||
| 31 | Design tokens | Existing `--wrn-*` system and theme resolution retained | Existing + hardened |
|
||||
| 32 | Accessibility | compile-time missing-alt diagnostic plus existing DevToolbar scanning | Implemented |
|
||||
| 33 | Motion/transitions | Existing CSR/lifecycle foundation retained; strategy can be plugin/runtime extended | Foundation / experimental |
|
||||
| 34 | Documentation | language, architecture, upgrade, implementation, test checklist docs | Implemented |
|
||||
|
||||
+32
-32
@@ -29,7 +29,7 @@ single generic runtime (no per‑component bundles). The `.wrn` language compile
|
||||
|
||||
**Part III — Build an app, feature by feature**
|
||||
|
||||
- 10. A page · 11. Layouts · 12. Components & props · 13. Reactivity · 14. Wire UI · 15. Theming · 16. Styles · 17. API routes · 18. Validation (forms + API) · 19. Database · 20. Auth, sessions & CSRF · 21. Middleware · 22. i18n · 23. SEO · 24. Security headers & CORS · 25. Realtime · 26. SSR/CSR data bindings · 27. Optional packages · 28. Config profiles & env · 29. Testing · 30. Build & deploy
|
||||
- 10. A page · 11. Layouts · 12. Components & props · 13. Reactivity · 14. WrNexus UI · 15. Theming · 16. Styles · 17. API routes · 18. Validation (forms + API) · 19. Database · 20. Auth, sessions & CSRF · 21. Middleware · 22. i18n · 23. SEO · 24. Security headers & CORS · 25. Realtime · 26. SSR/CSR data bindings · 27. Optional packages · 28. Config profiles & env · 29. Testing · 30. Build & deploy
|
||||
|
||||
**Part IV — Reference**
|
||||
|
||||
@@ -206,11 +206,11 @@ quoted or bare‑to‑end‑of‑line.
|
||||
|
||||
```
|
||||
style {
|
||||
.box { background: var(--wire-color-surface); border-radius: var(--wire-radius); }
|
||||
.box { background: var(--wrn-color-surface); border-radius: var(--wrn-radius); }
|
||||
}
|
||||
```
|
||||
|
||||
Multiple `style` blocks accumulate. Use theme tokens (`var(--wire-*)`) so styles restyle on theme
|
||||
Multiple `style` blocks accumulate. Use theme tokens (`var(--wrn-*)`) so styles restyle on theme
|
||||
change.
|
||||
|
||||
### `functions { }` — typed helpers
|
||||
@@ -339,8 +339,8 @@ view {
|
||||
```
|
||||
|
||||
There are also framework attributes consumed by **other** runtimes (loaded only when present):
|
||||
`data-wire-theme-toggle`/`data-wire-theme-set` (theme, §15), `data-schema`/`data-error`/
|
||||
`data-success`/`data-redirect` (forms, §18), `data-wire-lang-set`/`data-wire-lang` (i18n, §22),
|
||||
`data-wrn-theme-toggle`/`data-wrn-theme-set` (theme, §15), `data-schema`/`data-error`/
|
||||
`data-success`/`data-redirect` (forms, §18), `data-wrn-lang-set`/`data-wrn-lang` (i18n, §22),
|
||||
`data-room*` (realtime, §25).
|
||||
|
||||
Cross-platform pages can use `data-native-browser="capability"` and
|
||||
@@ -489,11 +489,11 @@ component Demo {
|
||||
The runtime tracks dependencies automatically and re‑renders only what changed. No `new Function`,
|
||||
no `eval` — CSP‑safe.
|
||||
|
||||
## 14. Wire UI
|
||||
## 14. WrNexus UI
|
||||
|
||||
`@wrnexus/ui` ships **24** themed components, auto‑discovered like your own. Mount with
|
||||
`data-component`; every component accepts a `class` prop (appended to the root) and is styled via
|
||||
`--wire-*` tokens + `.wire-*` classes you can override.
|
||||
`--wrn-*` tokens + `.wrn-*` classes you can override.
|
||||
|
||||
**Layout:** `container`, `stack` (`gap`), `hstack` (`gap`, `align`), `grid` (`cols`, `gap`),
|
||||
`spacer`, `divider`, `card`.
|
||||
@@ -514,14 +514,14 @@ Variants: buttons `default|primary|danger|ghost`, sizes `sm|md|lg`; badge/tag/al
|
||||
<div data-component="grid" cols="3" gap="4">…</div>
|
||||
```
|
||||
|
||||
**Override styling**, in priority order: (1) theme tokens `--wire-*`, (2) redefine `.wire-*` in your
|
||||
**Override styling**, in priority order: (1) theme tokens `--wrn-*`, (2) redefine `.wrn-*` in your
|
||||
CSS (loads after `ui.css`), (3) the `class` prop, (4) `wrnexus eject <name>` to copy the component's
|
||||
`.wrn` source into `app/components/` (your copy shadows the library one).
|
||||
|
||||
## 15. Theming
|
||||
|
||||
Themes are flat token maps rendered as `--wire-<key>` CSS variables (server + client). Built‑in
|
||||
`light` and `dark`; the cookie `wire-theme` selects one.
|
||||
Themes are flat token maps rendered as `--wrn-<key>` CSS variables (server + client). Built‑in
|
||||
`light` and `dark`; the cookie `wrn-theme` selects one.
|
||||
|
||||
```ts
|
||||
// wrnexus.config.ts
|
||||
@@ -543,11 +543,11 @@ Built‑in token keys include: `color-scheme`, `color-bg`, `color-surface`, `col
|
||||
Toggle from the view with zero JS:
|
||||
|
||||
```
|
||||
<button data-wire-theme-toggle>Toggle theme</button>
|
||||
<button data-wire-theme-set="light">Light</button>
|
||||
<button data-wrn-theme-toggle>Toggle theme</button>
|
||||
<button data-wrn-theme-set="light">Light</button>
|
||||
```
|
||||
|
||||
The client exposes `window.wireTheme = { get, set, toggle, bind, themes }`.
|
||||
The client exposes `window.wrnTheme = { get, set, toggle, bind, themes }`.
|
||||
|
||||
## 16. Styles
|
||||
|
||||
@@ -634,30 +634,30 @@ export async function POST(ctx: Context): Promise<Response> {
|
||||
`parseEnv(schema, source?)` validates env vars and throws one readable multi‑line error.
|
||||
|
||||
**Client form flow** (zero JS you write). The schema's descriptor is baked into
|
||||
`window.__wireSchemas` by name (filename). Wire a form up with attributes:
|
||||
`window.__wrnSchemas` by name (filename). WrNexus a form up with attributes:
|
||||
|
||||
```
|
||||
<form data-schema="login" method="post" action="/api/login" data-redirect="/dashboard">
|
||||
<div data-component="input" type="email" name="email"></div>
|
||||
<span class="wire-field-error" data-error="email"></span>
|
||||
<span class="wrn-field-error" data-error="email"></span>
|
||||
|
||||
<div data-component="input" type="password" name="password"></div>
|
||||
<span class="wire-field-error" data-error="password"></span>
|
||||
<span class="wrn-field-error" data-error="password"></span>
|
||||
|
||||
<div class="wire-alert wire-alert--success" data-success="Signed in!" hidden></div>
|
||||
<button type="submit" class="wire-btn wire-btn--primary">Sign in</button>
|
||||
<div class="wrn-alert wrn-alert--success" data-success="Signed in!" hidden></div>
|
||||
<button type="submit" class="wrn-btn wrn-btn--primary">Sign in</button>
|
||||
</form>
|
||||
```
|
||||
|
||||
- `data-schema="login"` — picks the descriptor.
|
||||
- `name="…"` — matched to schema fields; validated on `blur` and `submit`.
|
||||
- `data-error="field"` — receives the message; the input gets `aria-invalid` + `.wire-invalid`.
|
||||
- `data-error="field"` — receives the message; the input gets `aria-invalid` + `.wrn-invalid`.
|
||||
- `data-success` — shown on success when there's no redirect.
|
||||
- `data-redirect="/path"` (or `redirect` in the JSON response) — navigates on success.
|
||||
|
||||
On submit it validates client‑side, then POSTs `JSON` with `x-csrf-token` (from the `wire-csrf`
|
||||
On submit it validates client‑side, then POSTs `JSON` with `x-csrf-token` (from the `wrn-csrf`
|
||||
cookie) and `credentials: same-origin`, and re‑surfaces server `errors` into the `data-error`
|
||||
spans. It also dispatches `wire:success` / `wire:error` events. Scaffold: `wrnexus generate schema login`.
|
||||
spans. It also dispatches `wrn:success` / `wrn:error` events. Scaffold: `wrnexus generate schema login`.
|
||||
|
||||
## 19. Database
|
||||
|
||||
@@ -860,9 +860,9 @@ export async function POST(ctx: Context): Promise<Response> {
|
||||
**Guarding:** `requireAuth({ loginPath: "/login" })` as middleware — API/JSON → 401, page nav → 302
|
||||
to `${loginPath}?next=<target>`. Or inline: `if (getUser(ctx) == null) …`.
|
||||
|
||||
**CSRF** (double‑submit): cookie `wire-csrf` (JS‑readable), header `x-csrf-token`. `csrfToken(ctx)`
|
||||
**CSRF** (double‑submit): cookie `wrn-csrf` (JS‑readable), header `x-csrf-token`. `csrfToken(ctx)`
|
||||
returns/creates the token; `verifyCsrf(ctx)` passes GET/HEAD/OPTIONS, else compares header to cookie.
|
||||
The Wire UI form runtime sends the header automatically. Add `csrfProtection()` middleware to enforce
|
||||
The WrNexus UI form runtime sends the header automatically. Add `csrfProtection()` middleware to enforce
|
||||
globally.
|
||||
|
||||
**Sessions:** cookie `wrnexus.sid` (HttpOnly, Lax, Secure on HTTPS), 24h sliding TTL, 256‑bit id.
|
||||
@@ -908,7 +908,7 @@ Core factories and their key options:
|
||||
## 22. i18n
|
||||
|
||||
Opt‑in: add dictionaries under `app/locales/<lang>.json`. Language resolves per request from the
|
||||
`wire-lang` cookie → `Accept-Language` → default.
|
||||
`wrn-lang` cookie → `Accept-Language` → default.
|
||||
|
||||
```json
|
||||
// app/locales/en.json
|
||||
@@ -923,7 +923,7 @@ export const GET = async (ctx: Context) =>
|
||||
```
|
||||
|
||||
Config: `i18n: { default: "en", locales: ["en", "fr"] }` (both optional; inferred from files).
|
||||
Switch language from the view with `data-wire-lang-set="fr"`. Formatting helpers (Intl‑based) are
|
||||
Switch language from the view with `data-wrn-lang-set="fr"`. Formatting helpers (Intl‑based) are
|
||||
exported from `@wrnexus/i18n`: `formatNumber`, `formatCurrency`, `formatDate`, `formatRelativeTime`,
|
||||
`plural`.
|
||||
|
||||
@@ -1021,7 +1021,7 @@ realtime: { scale: true, redisUrl: process.env.REDIS_URL }, // defaults to redis
|
||||
Now `client.room.broadcast(msg)` in one app instance is delivered to subscribers in all the
|
||||
others. Connection‑targeted `send`/`to(id)` stay local (ids are per‑process). Under the hood it's
|
||||
`bridgeRealtime(registry, bus)` from `@wrnexus/core` + the `@wrnexus/pubsub` Redis driver — you can
|
||||
also wire it manually for custom buses.
|
||||
also wrn it manually for custom buses.
|
||||
|
||||
## 26. SSR/CSR data bindings
|
||||
|
||||
@@ -1264,7 +1264,7 @@ wrnexus gateway [--port=3000] [--prod] Serve every workspace a
|
||||
wrnexus generate <type> <name> (alias: g) Scaffold: page | component | api | schema
|
||||
wrnexus generate routes Regenerate app/routes.gen.ts
|
||||
wrnexus generate docker Scaffold Dockerfile + compose
|
||||
wrnexus eject <name...> Copy a Wire UI component into app/components/
|
||||
wrnexus eject <name...> Copy a WrNexus UI component into app/components/
|
||||
wrnexus db new [name] [--from-models] [--db=<name>] Scaffold a migration (optionally from schema.ts)
|
||||
wrnexus db generate [--db=<name>] Regenerate queries.gen.ts from queries/*.sql
|
||||
wrnexus db migrate | rollback | status [--db=<name>] Apply / revert / list migrations
|
||||
@@ -1299,7 +1299,7 @@ const config: AppConfig = {
|
||||
|
||||
theme: {
|
||||
palette: "violet",
|
||||
default: "dark", // theme when no wire-theme cookie
|
||||
default: "dark", // theme when no wrn-theme cookie
|
||||
themes: { light: { "color-primary": "#2563eb" }, dark: { "color-primary": "#6c8cff" } },
|
||||
},
|
||||
|
||||
@@ -1354,8 +1354,8 @@ directive to `false`/`null` to remove it.
|
||||
**Server/compiler:** `data-component` · `data-slot` · `<slot [name]>` · `{expr}` · `{{expr}}` ·
|
||||
`{t:key}` (→ `data-t`) · `@event="stmt"` · `api="binding"`.
|
||||
**Forms:** `data-schema` · `name` · `data-error` · `data-success` · `data-redirect`.
|
||||
**Theme:** `data-wire-theme-toggle` · `data-wire-theme-set="name"`.
|
||||
**i18n:** `data-wire-lang-set="lang"` · `data-wire-lang`.
|
||||
**Theme:** `data-wrn-theme-toggle` · `data-wrn-theme-set="name"`.
|
||||
**i18n:** `data-wrn-lang-set="lang"` · `data-wrn-lang`.
|
||||
**Realtime:** `data-room` · `data-room-user` · `data-room-log` · `data-room-status`
|
||||
(+`data-room-status-class`) · `<template data-room-item="type">` (`%field%`) · `data-room-send` ·
|
||||
`data-room-reset`.
|
||||
@@ -1371,7 +1371,7 @@ directive to `false`/`null` to remove it.
|
||||
(`saveUpload`, `collectUploads`, `sanitizeFilename`); streaming (`streamResponse`, `sse`); realtime
|
||||
(`defineRoom`, `createRealtimeRegistry`, `bridgeRealtime`); errors (`renderError`, `renderNotFound`); headers
|
||||
(`withSecurityHeaders`, CORS); sessions (`setSessionBackend`, `loadSession`); JSX runtime.
|
||||
- `@wrnexus/compiler` — `compileWireFile`, `compile`, `parse`, `generate`, `Lexer`, `ParseError`.
|
||||
- `@wrnexus/compiler` — `compileWrnFile`, `compile`, `parse`, `generate`, `Lexer`, `ParseError`.
|
||||
- `@wrnexus/router` — `buildRouter`, `matchRoute`, `generateRoutesFile`.
|
||||
- `@wrnexus/ssr` — `renderDocument`.
|
||||
- `@wrnexus/csr` — `getReactiveRuntime`, `getNavRuntime`, `getRealtimeRuntime`.
|
||||
@@ -1388,7 +1388,7 @@ directive to `false`/`null` to remove it.
|
||||
`createDb`, `paginate`, `loadRelated`, migrations, query generation; subpaths `/session`,
|
||||
`/sqlite`, `/postgres`, `/mysql`, `/mongo`.
|
||||
- `@wrnexus/dev-server` — `startServer`, `startGateway` (multi-app host router), prod handler.
|
||||
- `@wrnexus/cli` — the `wrnexus` binary; subpath `/workspace` (`WorkspaceConfig`, `startGateway` wiring).
|
||||
- `@wrnexus/cli` — the `wrnexus` binary; subpath `/workspace` (`WorkspaceConfig`, `startGateway` integration).
|
||||
- `@wrnexus/validation` — `v`, `parseBody`, `parseEnv`, `invalid`, `renderSchemasScript`.
|
||||
- `@wrnexus/helpers` — original gateway URL/path/method helpers and `redirectToLogin`.
|
||||
- `@wrnexus/ui` — `uiComponentsDir`, `uiCssPath`, `uiCss`, `uiComponentNames`.
|
||||
|
||||
+1
-1
@@ -131,7 +131,7 @@ duplicate version).
|
||||
## Consume on another machine (needs Bun)
|
||||
|
||||
```bash
|
||||
mkdir my-wire-app && cd my-wire-app
|
||||
mkdir my-wrn-app && cd my-wrn-app
|
||||
|
||||
# Scaffold via the CLI
|
||||
npm i @wrnexus/cli
|
||||
|
||||
+1
-1
@@ -871,7 +871,7 @@ Official enterprise packages should eventually support:
|
||||
- Export and deletion workflows
|
||||
- Consent tracking
|
||||
|
||||
**Status:** Delivered. `@wrnexus/auth` supplies OAuth account linking, passkeys, email/SMS/TOTP/recovery-code MFA, trusted devices, revocable sessions and audited impersonation. `@wrnexus/authz` supplies RBAC, ABAC and composable policy decisions. The separate `@wrnexus/identity` package adds strict OIDC discovery and PKCE authorization, signed-SAML adapter validation with issuer/audience/recipient/expiry/replay enforcement, LDAP and Active Directory synchronization adapters, authenticated bounded SCIM provisioning, scoped API keys and service accounts, approval-gated subject exports/deletions, consent history, retention enforcement and governance audit events. SAML XML-signature and LDAP wire parsing deliberately remain adapter responsibilities so deployments can choose a maintained protocol SDK without placing vendor code in core.
|
||||
**Status:** Delivered. `@wrnexus/auth` supplies OAuth account linking, passkeys, email/SMS/TOTP/recovery-code MFA, trusted devices, revocable sessions and audited impersonation. `@wrnexus/authz` supplies RBAC, ABAC and composable policy decisions. The separate `@wrnexus/identity` package adds strict OIDC discovery and PKCE authorization, signed-SAML adapter validation with issuer/audience/recipient/expiry/replay enforcement, LDAP and Active Directory synchronization adapters, authenticated bounded SCIM provisioning, scoped API keys and service accounts, approval-gated subject exports/deletions, consent history, retention enforcement and governance audit events. SAML XML-signature and LDAP wrn parsing deliberately remain adapter responsibilities so deployments can choose a maintained protocol SDK without placing vendor code in core.
|
||||
|
||||
## 23. AI-Native Development
|
||||
|
||||
|
||||
@@ -83,7 +83,7 @@ Verify before committing:
|
||||
| 28 | Performance budgets | Set deliberately small HTML/JS/CSS/image budgets, then realistic budgets. | Build warns/fails according to policy, then passes with realistic limits. |
|
||||
| 29 | Observability | Enable tracing and `serverTiming`; make a request containing nested spans. | Trace records include duration/status/attributes and response has `Server-Timing`. |
|
||||
| 30 | Component architecture | Render primitives, behavior components, layouts, and product components in light/dark/responsive states. | Props/events/slots/accessibility remain consistent and app overrides still win. |
|
||||
| 31 | Design tokens | Audit `--wire-*` usage and switch themes. | Components use semantic tokens and no required token is undefined. |
|
||||
| 31 | Design tokens | Audit `--wrn-*` usage and switch themes. | Components use semantic tokens and no required token is undefined. |
|
||||
| 32 | Accessibility | Compile missing-alt markup and run toolbar keyboard/focus/ARIA checks. | Compile-time and runtime accessibility findings appear without duplicates or false positives. |
|
||||
| 33 | Motion/transitions | Exercise existing lifecycle/animation behavior with reduced-motion enabled and disabled. | Motion respects user preference and teardown does not leak listeners/timers. |
|
||||
| 34 | Documentation | Follow the language, architecture, upgrade, and this checklist from a clean clone. | Commands/examples match actual APIs and produce the documented result. |
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# WRNexusJS — Security & Power Improvement Plan
|
||||
|
||||
Prepared for WorkRoot · covers `E:\WireJS` (framework v0.8.4)
|
||||
Prepared for WorkRoot · covers `E:\WrNexus` (framework v0.8.4)
|
||||
|
||||
This plan is scoped and sequenced the way the repo's own roadmap docs are (`ROADMAP-V1.md`,
|
||||
`IMPLEMENTATION-ROADMAP-0.8.md`): version-gated phases, one package/file set per item, with
|
||||
|
||||
@@ -9,7 +9,7 @@ definition, and local styles on every component. The core reactive runtime is
|
||||
The §4.1 ownership migration is complete: `ui.css` contains global and
|
||||
cross-cutting primitives only. Shared component foundations are carried by
|
||||
three internal style-only components and render on demand; the former global
|
||||
component families and standalone `wire-next` generation class are absent.
|
||||
component families and standalone `wrn-next` generation class are absent.
|
||||
|
||||
Final validation passed the production, package, example, service, editor,
|
||||
showcase-generation, typecheck, lint, formatting, public-API, visual-contract,
|
||||
@@ -60,7 +60,7 @@ Practical rules:
|
||||
|
||||
- CSS comments in a `style {}` block are `/* */` only. `//` is not a CSS comment
|
||||
and silently swallows the rule that follows it.
|
||||
- Style the component's own BEM classes (`wire-thing`, `wire-thing__part`).
|
||||
- Style the component's own BEM classes (`wrn-thing`, `wrn-thing__part`).
|
||||
Variants are data attributes: `[data-variant="soft"]`, not a class explosion.
|
||||
- No Tailwind utility classes in component markup. See §4.3.
|
||||
|
||||
@@ -141,7 +141,7 @@ positives because most tokens are generated per palette, so any such check must
|
||||
read the **rendered** CSS; and the semantic spread must sit _before_ the
|
||||
primary/secondary palette entries or it overrides them.
|
||||
|
||||
**How to test.** Load a page, then in the console collect every `var(--wire-*)`
|
||||
**How to test.** Load a page, then in the console collect every `var(--wrn-*)`
|
||||
referenced by stylesheet rules and check each against
|
||||
`getComputedStyle(document.documentElement)`. Expect 38 referenced, 0 undefined.
|
||||
|
||||
@@ -197,7 +197,7 @@ builds. It should warn on at least:
|
||||
the event — include the registry keys actually present, which is exactly what
|
||||
would have made §1.1 a five-minute bug.
|
||||
2. A `@binding` naming a function that does not exist in scope.
|
||||
3. A `var(--wire-*)` referenced by a component but absent from the rendered
|
||||
3. A `var(--wrn-*)` referenced by a component but absent from the rendered
|
||||
theme.
|
||||
4. A state write discarded because it happened after the client function
|
||||
returned (see §2.2).
|
||||
@@ -331,9 +331,9 @@ done, what is left, and which disposition each remaining component takes.
|
||||
#### 3.1.1 Already done in 0.8.6 — do not redo
|
||||
|
||||
Fifteen components were fixed. Ten had outputs that were **declared but
|
||||
miswired** — they dispatched a hand-built `CustomEvent` instead of calling
|
||||
incorrectly connected** — they dispatched a hand-built `CustomEvent` instead of calling
|
||||
`output.*`, so the declaration was right and only the emit was wrong. Nothing
|
||||
was added to these; they were rewired:
|
||||
was added to these; they were reconnected:
|
||||
|
||||
> Card, Footer, Breadcrumb, Accordion, alert, Badge, AnnouncementBar,
|
||||
> AvatarGroup, ToggleCount, InputNumber
|
||||
@@ -351,13 +351,13 @@ through `output.*`:
|
||||
| `Timeline` | `select` | item pressed |
|
||||
|
||||
Verified firing in a browser: `SearchBox`, `Marquee`, `List`, `Timeline`, plus
|
||||
all ten rewired components. **`Map` was not verified** — its three outputs were
|
||||
all ten reconnected components. **`Map` was not verified** — its three outputs were
|
||||
converted by the same mechanical change and the build passes, but no Map was on
|
||||
the probe page. Put one on a page and confirm before treating it as done.
|
||||
|
||||
#### 3.1.2 Original remaining work — resolved
|
||||
|
||||
**Original issue.** These were not miswired. All nine were **pure scaffolds**: roughly 25
|
||||
**Original issue.** These were not incorrectly connected. All nine were **pure scaffolds**: roughly 25
|
||||
lines each, zero state, zero functions, no style block, no event handlers. They
|
||||
are markup shells that declare outputs. "Add an emitter" is not the work — there
|
||||
is nothing to emit from.
|
||||
@@ -447,9 +447,9 @@ AdvancedRangeSlider, Chart, Confetti, CopyMarkup, FileUpload, Toast,
|
||||
ToastNotifications, TreeView. Do §3.1 first and this list drops to 19 without
|
||||
any extra work. Do not plan the two items separately.
|
||||
|
||||
Separately, 58 components carried the standalone `wire-next` scaffold class in
|
||||
Separately, 58 components carried the standalone `wrn-next` scaffold class in
|
||||
the original audit; **zero retain it now**. Component-specific BEM identifiers
|
||||
such as `wire-next--alert` remain locally owned implementation details, but no
|
||||
such as `wrn-next--alert` remain locally owned implementation details, but no
|
||||
component is bound to a global stylesheet through the generation artefact.
|
||||
|
||||
**Change.** Rebuild them under §0.1, or remove them. Note that several are
|
||||
@@ -474,10 +474,10 @@ bun run build && gzip -c examples/basic-app/dist/ui.css | wc -c
|
||||
`TextLink` (14), `Map` (12), `SearchBox` (8), `Timeline` (8) still style
|
||||
themselves with utility classes in markup.
|
||||
|
||||
All seven now use local `wire-*` BEM styles. `InputNumber` styles are emitted as
|
||||
All seven now use local `wrn-*` BEM styles. `InputNumber` styles are emitted as
|
||||
component-scoped CSS and therefore do not appear in the global `ui.css` file.
|
||||
|
||||
**Change.** Migrate to `wire-*` BEM classes in the component's own `style {}`
|
||||
**Change.** Migrate to `wrn-*` BEM classes in the component's own `style {}`
|
||||
block, per §0.1. Note this changes the rendered class list, so application CSS
|
||||
selecting on those utilities stops matching — it needs a migration note, exactly
|
||||
as the layout group did in 0.8.6.
|
||||
@@ -512,14 +512,14 @@ whichever behaviour was chosen.
|
||||
every page. Only **42 of 108** components had a local `style {}` block.
|
||||
|
||||
**Result.** The maintained library now has **102 of 102** components with local
|
||||
styles. Built `ui.css` is **15,927 bytes / 3,762 gzipped**. The `.wire-next`,
|
||||
`.wire-btn`, `.wire-dropdown`, `.wire-alert`, `.wire-card`, `.wire-footer`,
|
||||
`.wire-metric-card`, and `.wire-segmented-group` global families are gone.
|
||||
styles. Built `ui.css` is **15,927 bytes / 3,762 gzipped**. The `.wrn-next`,
|
||||
`.wrn-btn`, `.wrn-dropdown`, `.wrn-alert`, `.wrn-card`, `.wrn-footer`,
|
||||
`.wrn-metric-card`, and `.wrn-segmented-group` global families are gone.
|
||||
Reusable field, select, color, and size foundations live in three internal
|
||||
style-only components; the renderer emits and deduplicates them only when a
|
||||
component that needs them renders. An example-app SSR guard verifies that
|
||||
on-demand path, while the UI suite prevents the global families or standalone
|
||||
`wire-next` class from returning.
|
||||
`wrn-next` class from returning.
|
||||
|
||||
**Change.** Done in groups with the visual contract regenerated after each
|
||||
migration.
|
||||
@@ -542,7 +542,7 @@ cannot silently regress.
|
||||
change this session needed a full server restart, which is the single biggest
|
||||
drag on the edit loop.
|
||||
|
||||
**Evidence, and what is _not_ yet proven.** The watcher is wired correctly:
|
||||
**Evidence, and what is _not_ yet proven.** The watcher is connected correctly:
|
||||
`componentDirs` includes `uiComponentsDir()` and is passed as `extraDirs`
|
||||
(`packages/dev-server/src/index.ts:706-723`), external paths arrive absolute
|
||||
(`packages/dev-server/src/watch.ts:104`), and `hotUpdate` calls
|
||||
@@ -706,7 +706,7 @@ context.state.topLinks; ...` — the full state-restore prologue.
|
||||
After hoisting and closure deduplication, the page is **101,253 decoded bytes**;
|
||||
the largest module is **51,946 bytes** with **2.4% duplicated lines**.
|
||||
|
||||
Gzip hides this on the wire, but **parse and compile cost scales with decoded
|
||||
Gzip hides this on the wrn, but **parse and compile cost scales with decoded
|
||||
bytes, not transferred bytes**. Half a megabyte of JavaScript is parsed to run
|
||||
one page.
|
||||
|
||||
@@ -792,7 +792,7 @@ a case-sensitive filesystem the same script produces duplicate files instead.
|
||||
**Change.** Pick one:
|
||||
|
||||
- **Delete it.** `generate-ui-component-reference.mjs` is the maintained
|
||||
generator, it is wired into `release:prepare`, and it works. If this script is
|
||||
generator, it is connected into `release:prepare`, and it works. If this script is
|
||||
redundant, it is a loaded gun in the repo for no benefit.
|
||||
- **Or fix and gate it**: make it write to a temp directory and swap atomically
|
||||
only on success, so a mid-run crash cannot leave a partial library. Then add
|
||||
|
||||
@@ -71,7 +71,7 @@ Versioned, timestamped files with `up`/`down`. Two authoring modes:
|
||||
last applied state and emits the SQL for you to review.
|
||||
|
||||
`wrnexus db migrate` applies pending migrations inside a transaction and records
|
||||
them in a `_wire_migrations` table; `rollback` runs `down`; `status` lists state.
|
||||
them in a `_wrn_migrations` table; `rollback` runs `down`; `status` lists state.
|
||||
Dialect-aware SQL generation for create/alter/index.
|
||||
|
||||
## 5. sqlc-like typed queries (`app/db/queries/*.sql` → generated TS)
|
||||
@@ -130,7 +130,7 @@ A local Artifact/web UI to browse tables + run read-only queries in dev.
|
||||
1. **Core + SQLite adapter** — `@wrnexus/db`, `table()`/`v` model layer, `Driver`
|
||||
interface, `bun:sqlite` adapter, `db.one/all/exec/tx`, result→schema mapping.
|
||||
(SQLite first = zero external service to test against.)
|
||||
2. **Migrations** ✅ done — runner + `_wire_migrations`, `wrnexus db migrate/rollback/status/new`,
|
||||
2. **Migrations** ✅ done — runner + `_wrn_migrations`, `wrnexus db migrate/rollback/status/new`,
|
||||
`.sql` (`-- +up`/`-- +down`) + `--from-models` DDL generation. (Model-diffing beyond the
|
||||
initial CREATE TABLE is a later enhancement; needs topological ordering by FK refs.)
|
||||
3. **sqlc-like generator** ✅ done — `.sql` parsing (`-- name: X :one/:many/:exec`),
|
||||
@@ -144,7 +144,7 @@ A local Artifact/web UI to browse tables + run read-only queries in dev.
|
||||
5. **MongoDB adapter** ✅ built (unverified) — `@wrnexus/db/mongo`: a document
|
||||
collection API (`find/findOne/insert/update/delete/count`) keyed by models, reads
|
||||
coerced through `model.parse`, `_id`→`id`. Lazily imports `mongodb` (optional dep).
|
||||
Not wired into the SQL singleton/migrations/generator (Mongo isn't SQL). Needs
|
||||
Not connected into the SQL singleton/migrations/generator (Mongo isn't SQL). Needs
|
||||
`mongodb` + a server to test.
|
||||
6. **Polish** — ✅ FK-topological ordering in `--from-models` (referenced tables
|
||||
first). Deferred: `db studio` (web UI), richer relations/joins helpers.
|
||||
|
||||
+18
-18
@@ -6,7 +6,7 @@ validation. Built **foundation-first** so each subsystem lands solid and tested.
|
||||
Order (one subsystem per turn):
|
||||
|
||||
1. **Theme system** ✅ done — design tokens, SSR + client, no-flash, overridable.
|
||||
2. **Wire UI** (`@wrnexus/ui`) ✅ done — 17 components + layout primitives as `.wrn`,
|
||||
2. **WrNexus UI** (`@wrnexus/ui`) ✅ done — 17 components + layout primitives as `.wrn`,
|
||||
consuming theme tokens, overridable 4 ways; auto-discovered + `wrnexus eject`.
|
||||
3. **Layout system** ✅ done (folded into turn 2) — layout primitives (Container,
|
||||
Stack, HStack, Grid, Divider, Spacer) + page layouts (`app/layout.wrn` + `<slot>`).
|
||||
@@ -16,13 +16,13 @@ Order (one subsystem per turn):
|
||||
## 4. i18n (done)
|
||||
|
||||
- `@wrnexus/i18n`: locales in `app/locales/<lang>.json` (nested/flat keys, `{param}`
|
||||
interpolation). Per request the lang resolves from the `wire-lang` cookie →
|
||||
interpolation). Per request the lang resolves from the `wrn-lang` cookie →
|
||||
Accept-Language → config default (`wrnexus.config.ts` `i18n.default`).
|
||||
- **Server:** `ctx.lang` + `ctx.t(key, params)` on every request (pages + API).
|
||||
- **Views:** `{t:key}` text sugar compiles to a `<span data-t="key">` marker;
|
||||
`t:<attr>="key"` translates an attribute. `translateHtml` resolves both on the
|
||||
final HTML (after components + layout), and `<html lang>` is set (no flash).
|
||||
- **Switch:** `[data-wire-lang-set="es"]` (or `<select data-wire-lang>`) → the tiny
|
||||
- **Switch:** `[data-wrn-lang-set="es"]` (or `<select data-wrn-lang>`) → the tiny
|
||||
`/__wrnexus/i18n.js` sets the cookie + reloads; injected only when present.
|
||||
- Fallback chain: current lang → default lang → the key itself.
|
||||
|
||||
@@ -37,28 +37,28 @@ password: v.string().min(8) })`). `.parse(data)` runs server-side (coerce + erro
|
||||
parseBody(login, ctx.req)` → 400 `{errors}` or `{value}`. **Form:** `<form
|
||||
data-schema="login">` with `[data-error="field"]` spans.
|
||||
- The framework bakes all descriptors into `/__wrnexus/schemas.js`
|
||||
(`window.__wireSchemas`) and ships an eval-free `/__wrnexus/validate.js` that validates
|
||||
(`window.__wrnSchemas`) and ships an eval-free `/__wrnexus/validate.js` that validates
|
||||
`form[data-schema]` on submit/blur — injected only when a page has `data-schema`.
|
||||
|
||||
## 2 + 5. Wire UI + layout (done)
|
||||
## 2 + 5. WrNexus UI + layout (done)
|
||||
|
||||
- **Distribution:** `@wrnexus/ui` ships `.wrn` components under `components/`; the
|
||||
framework auto-discovers them (router `componentDirs`), app/components shadow by
|
||||
name, and `wrnexus eject <name>` copies one into the app to own it.
|
||||
- **Codegen:** components now bake prop-driven text/attributes server-side
|
||||
(`__wireHtml`/`__wireAttr`) so static components ship zero JS; state-referencing
|
||||
(`__wrnHtml`/`__wrnAttr`) so static components ship zero JS; state-referencing
|
||||
text stays a reactive mustache. Reserved-word props (`class`) get `__p_` refs;
|
||||
attribute `{expr}` enables `variant`/`size`/`class` composition.
|
||||
- **Slots:** `renderComponents` is nesting-aware and fills `<slot>` with mount
|
||||
children — this also powers page layouts (`app/layout.wrn` wraps every page).
|
||||
- **Styles:** one themed stylesheet `/__wrnexus/ui.css` (all `.wire-*` classes use
|
||||
`var(--wire-*)`), linked theme → ui → app so app CSS overrides win.
|
||||
- **Styles:** one themed stylesheet `/__wrnexus/ui.css` (all `.wrn-*` classes use
|
||||
`var(--wrn-*)`), linked theme → ui → app so app CSS overrides win.
|
||||
|
||||
---
|
||||
|
||||
## 1. Theme system (this turn)
|
||||
|
||||
**Tokens.** Kebab-case token keys become `--wire-<key>` CSS custom properties.
|
||||
**Tokens.** Kebab-case token keys become `--wrn-<key>` CSS custom properties.
|
||||
Framework ships default `light` + `dark` token sets (colors, radius, etc.); user
|
||||
config deep-merges over them and may add new themes.
|
||||
|
||||
@@ -79,23 +79,23 @@ and component styles can read/override it:
|
||||
|
||||
```css
|
||||
:root{ /* default theme tokens */ }
|
||||
[data-theme="light"]{ --wire-color-primary:#2563eb; color-scheme:light; ... }
|
||||
[data-theme="dark"]{ --wire-color-primary:#6c8cff; color-scheme:dark; ... }
|
||||
[data-theme="light"]{ --wrn-color-primary:#2563eb; color-scheme:light; ... }
|
||||
[data-theme="dark"]{ --wrn-color-primary:#6c8cff; color-scheme:dark; ... }
|
||||
```
|
||||
|
||||
**SSR (no flash).** Server reads the `wire-theme` cookie (falls back to config
|
||||
**SSR (no flash).** Server reads the `wrn-theme` cookie (falls back to config
|
||||
default) and renders `<html data-theme="…">`, so the correct theme paints on the
|
||||
first byte. The theme name is validated against configured names.
|
||||
|
||||
**Client** (`/__wrnexus/theme.js`, injected only when a page has a toggle):
|
||||
`window.wireTheme.{get,set,toggle}` — sets `data-theme` on `<html>`, persists the
|
||||
`wire-theme` cookie, and binds `[data-wire-theme-toggle]` /
|
||||
`[data-wire-theme-set="name"]` elements so a `.wrn` component can switch themes
|
||||
`window.wrnTheme.{get,set,toggle}` — sets `data-theme` on `<html>`, persists the
|
||||
`wrn-theme` cookie, and binds `[data-wrn-theme-toggle]` /
|
||||
`[data-wrn-theme-set="name"]` elements so a `.wrn` component can switch themes
|
||||
without writing JS.
|
||||
|
||||
**Override.** Users change tokens in config, or redefine any `--wire-*` variable
|
||||
in their own CSS (loaded after theme.css → wins). Wire UI components consume
|
||||
`var(--wire-*)`, so overriding a token restyles every component at once.
|
||||
**Override.** Users change tokens in config, or redefine any `--wrn-*` variable
|
||||
in their own CSS (loaded after theme.css → wins). WrNexus UI components consume
|
||||
`var(--wrn-*)`, so overriding a token restyles every component at once.
|
||||
|
||||
**Integration points:** `@wrnexus/styles` (theme module), `@wrnexus/ssr`
|
||||
(`renderDocument` html attrs), dev runtime/assets, prod server, `wrnexus build`
|
||||
@@ -270,7 +270,7 @@ disclosing policy structure to unauthenticated callers. This becomes opt-in via
|
||||
## Build order
|
||||
|
||||
1. `registry.ts`, `catalog.ts`, `store.ts` (memory), `engine.ts`, extended `guards.ts`.
|
||||
2. Resource-level policies wired to `filterAuthorized`; `audit.ts`.
|
||||
2. Resource-level policies connected to `filterAuthorized`; `audit.ts`.
|
||||
3. `db.ts` adapter, migrations, `wrnexus authz init`, codegen, `wrnexus authz list`.
|
||||
4. `.wrn` view integration (`can()` inside `{#if}`).
|
||||
5. Admin UI components.
|
||||
|
||||
@@ -3227,7 +3227,7 @@ export async function runAuthzCommand(
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 4: Wire it into the CLI**
|
||||
- [ ] **Step 4: WrNexus it into the CLI**
|
||||
|
||||
In `packages/cli/src/index.ts`, add immediately after the `case "db"` block:
|
||||
|
||||
@@ -3257,7 +3257,7 @@ git commit -m "feat(cli): add wrnexus authz list/generate/init"
|
||||
|
||||
---
|
||||
|
||||
## Task 14: Wire the catalog into dev and prod boot
|
||||
## Task 14: WrNexus the catalog into dev and prod boot
|
||||
|
||||
**Files:**
|
||||
|
||||
@@ -3375,7 +3375,7 @@ git commit -m "feat(dev-server): load the authz catalog at boot"
|
||||
|
||||
---
|
||||
|
||||
## Task 15: Example app wiring and documentation
|
||||
## Task 15: Example app integration and documentation
|
||||
|
||||
**Files:**
|
||||
|
||||
|
||||
@@ -418,7 +418,7 @@ export class ServiceError extends Error {
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert to a wire result. The message is replaced unless explicitly
|
||||
* Convert to a wrn result. The message is replaced unless explicitly
|
||||
* exposed: a handler's error text routinely names tables, hosts, or
|
||||
* credentials, and this value crosses an app boundary.
|
||||
*/
|
||||
@@ -1296,7 +1296,7 @@ describe("implement", () => {
|
||||
expect(result).toEqual({ ok: true, value: { sum: 3 } });
|
||||
});
|
||||
|
||||
test("coerces through the schema rather than trusting the wire", async () => {
|
||||
test("coerces through the schema rather than trusting the wrn", async () => {
|
||||
// "3" arrives as a string over JSON from a sloppy caller; the schema coerces.
|
||||
const result = await impl().invoke("add", { a: 1, b: "3" });
|
||||
expect(result).toEqual({ ok: true, value: { sum: 4 } });
|
||||
@@ -1360,7 +1360,7 @@ describe("implement", () => {
|
||||
|
||||
test("a guarded procedure with NO permission checker configured denies", async () => {
|
||||
// Fail closed: a contract that declares a permission must not run
|
||||
// unguarded just because the app forgot to wire a checker.
|
||||
// unguarded just because the app forgot to wrn a checker.
|
||||
const result = await impl(undefined).invoke("guarded", {});
|
||||
expect(result.ok).toBe(false);
|
||||
if (!result.ok) expect(result.code).toBe(RPC_ERROR_CODES.denied);
|
||||
@@ -1439,7 +1439,7 @@ export interface ImplementOptions {
|
||||
/** This app's name, used as the identity token's expected audience. */
|
||||
selfApp: string;
|
||||
/**
|
||||
* Resolve whether the subject holds a permission. Wire this to
|
||||
* Resolve whether the subject holds a permission. WrNexus this to
|
||||
* `@wrnexus/authz`. A procedure that DECLARES a permission but finds no
|
||||
* checker configured is denied — never run unguarded.
|
||||
*/
|
||||
@@ -2345,7 +2345,7 @@ export async function handleRpcRequest(
|
||||
Run: `bun test packages/dev-server/test/rpc-endpoint.test.ts`
|
||||
Expected: PASS, 9 tests
|
||||
|
||||
- [ ] **Step 5: Wire the dispatcher into the request pipeline**
|
||||
- [ ] **Step 5: WrNexus the dispatcher into the request pipeline**
|
||||
|
||||
In `packages/dev-server/src/runtime.ts`, inside the main `fetch` handler, call `handleRpcRequest` BEFORE normal page/API routing and return its result when non-null. Build the `Map<string, ServiceImplementation>` from `router.services` at boot, importing each module's default export. Follow the pattern `loadAppAuthzCatalog` uses for importing discovered modules, including routing hot-reload re-imports through `loadModule`.
|
||||
|
||||
@@ -2411,7 +2411,7 @@ const billing = defineService({
|
||||
},
|
||||
});
|
||||
|
||||
function wire(allowed: boolean) {
|
||||
function wrn(allowed: boolean) {
|
||||
const service = implement(
|
||||
billing,
|
||||
{
|
||||
@@ -2434,7 +2434,7 @@ describe("end to end", () => {
|
||||
const client = serviceClient(billing, {
|
||||
app: "billing",
|
||||
as: { user: { id: "u1" }, tenant: { id: "acme" }, locals: {} } as unknown as Context,
|
||||
transport: wire(true),
|
||||
transport: wrn(true),
|
||||
});
|
||||
expect(await client.createInvoice({ amountCents: 250 })).toEqual({
|
||||
invoiceId: "inv_250",
|
||||
@@ -2448,7 +2448,7 @@ describe("end to end", () => {
|
||||
const client = serviceClient(billing, {
|
||||
app: "billing",
|
||||
as: { user: { id: "u1" }, locals: {} } as unknown as Context,
|
||||
transport: wire(false),
|
||||
transport: wrn(false),
|
||||
});
|
||||
try {
|
||||
await client.createInvoice({ amountCents: 1 });
|
||||
@@ -2459,7 +2459,7 @@ describe("end to end", () => {
|
||||
});
|
||||
|
||||
test("invalid input never reaches the handler", async () => {
|
||||
const client = serviceClient(billing, { app: "billing", transport: wire(true) });
|
||||
const client = serviceClient(billing, { app: "billing", transport: wrn(true) });
|
||||
try {
|
||||
await client.createInvoice({ amountCents: "abc" } as never);
|
||||
throw new Error("should not reach here");
|
||||
|
||||
@@ -1002,8 +1002,8 @@
|
||||
"assertValidAst",
|
||||
"compilationKey",
|
||||
"compile",
|
||||
"compileNativeWireFile",
|
||||
"compileWireFile",
|
||||
"compileNativeWrnFile",
|
||||
"compileWrnFile",
|
||||
"createCompilationCache",
|
||||
"createComponentContract",
|
||||
"createWrnSourceMap",
|
||||
@@ -2620,7 +2620,7 @@
|
||||
"ThemeTokens",
|
||||
"activeThemeCssHref",
|
||||
"auditCssPerformance",
|
||||
"auditWireTokens",
|
||||
"auditWrnTokens",
|
||||
"bundleCss",
|
||||
"contrast",
|
||||
"defineConfig",
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
**Goal:** Ship runtime-owned roving arrow-key focus, then build Nav, Pagination and Stepper as real components on that foundation.
|
||||
|
||||
**Architecture:** One declarative attribute pair (`data-wrn-roving` on a container, `data-wrn-roving-item` on children) implements ARIA roving focus once in the reactive runtime, the same way modal dialog focus already lives there. The three components then declare intent with a single attribute instead of carrying five near-identical `@keydown` handlers. Each component uses a local `style {}` block with `wire-*` classes, declares its `outputs`, and takes props in / reports outputs out with no global state.
|
||||
**Architecture:** One declarative attribute pair (`data-wrn-roving` on a container, `data-wrn-roving-item` on children) implements ARIA roving focus once in the reactive runtime, the same way modal dialog focus already lives there. The three components then declare intent with a single attribute instead of carrying five near-identical `@keydown` handlers. Each component uses a local `style {}` block with `wrn-*` classes, declares its `outputs`, and takes props in / reports outputs out with no global state.
|
||||
|
||||
**Tech Stack:** Bun, TypeScript, `.wrn` components, happy-dom for runtime tests, `@wrnexus/test` (`renderComponent`, `mountHtml`) for component tests.
|
||||
|
||||
@@ -456,10 +456,10 @@ test("pagination renders windowed page numbers and emits change", async () => {
|
||||
siblingCount: 1,
|
||||
});
|
||||
const dom = mountHtml(html);
|
||||
const root = dom.querySelector(".wire-pagination") as HTMLElement;
|
||||
const root = dom.querySelector(".wrn-pagination") as HTMLElement;
|
||||
|
||||
expect(root.getAttribute("role")).toBe("navigation");
|
||||
const current = dom.querySelector('.wire-pagination__page[aria-current="page"]');
|
||||
const current = dom.querySelector('.wrn-pagination__page[aria-current="page"]');
|
||||
expect(current!.textContent!.trim()).toBe("5");
|
||||
expect(root.textContent).toContain("41");
|
||||
expect(root.textContent).toContain("50");
|
||||
@@ -478,7 +478,7 @@ test("pagination survives a non-array or empty dataset", async () => {
|
||||
const source = readFileSync(uiComponentPath("Pagination"), "utf8");
|
||||
const html = await renderComponent(source, { page: 1, pageSize: 10, total: 0 });
|
||||
const dom = mountHtml(html);
|
||||
expect(dom.querySelector(".wire-pagination")).not.toBeNull();
|
||||
expect(dom.querySelector(".wrn-pagination")).not.toBeNull();
|
||||
});
|
||||
```
|
||||
|
||||
@@ -488,7 +488,7 @@ test("pagination survives a non-array or empty dataset", async () => {
|
||||
bun test packages/ui -t "pagination"
|
||||
```
|
||||
|
||||
Expected: FAIL — the scaffold has no `.wire-pagination` class and no page numbers.
|
||||
Expected: FAIL — the scaffold has no `.wrn-pagination` class and no page numbers.
|
||||
|
||||
- [ ] **Step 3: Replace `packages/ui/components/Pagination.wrn`**
|
||||
|
||||
@@ -594,33 +594,33 @@ component Pagination {
|
||||
<nav
|
||||
{...attrs}
|
||||
data-ui-component="Pagination"
|
||||
class='wire-pagination {class}'
|
||||
class='wrn-pagination {class}'
|
||||
data-variant='{variant}'
|
||||
role="navigation"
|
||||
aria-label='{label}'
|
||||
>
|
||||
<p class="wire-pagination__summary" data-show="showSummary">
|
||||
<p class="wrn-pagination__summary" data-show="showSummary">
|
||||
{firstShown()} to {lastShown()} of {total}
|
||||
</p>
|
||||
|
||||
<div class="wire-pagination__controls">
|
||||
<div class="wrn-pagination__controls">
|
||||
<button
|
||||
type="button"
|
||||
class="wire-pagination__step"
|
||||
class="wrn-pagination__step"
|
||||
aria-label='{previousLabel}'
|
||||
@click='goPrevious()'
|
||||
>
|
||||
<span class="wire-pagination__step-icon" aria-hidden="true">‹</span>
|
||||
<span class="wire-pagination__step-label">{previousLabel}</span>
|
||||
<span class="wrn-pagination__step-icon" aria-hidden="true">‹</span>
|
||||
<span class="wrn-pagination__step-label">{previousLabel}</span>
|
||||
</button>
|
||||
|
||||
<ol class="wire-pagination__pages" data-show="variant === 'numbered'">
|
||||
<ol class="wrn-pagination__pages" data-show="variant === 'numbered'">
|
||||
{#each pageNumbers() as entry}
|
||||
<li>
|
||||
<span class="wire-pagination__gap" data-show="entry.gap">{entry.label}</span>
|
||||
<span class="wrn-pagination__gap" data-show="entry.gap">{entry.label}</span>
|
||||
<button
|
||||
type="button"
|
||||
class="wire-pagination__page"
|
||||
class="wrn-pagination__page"
|
||||
data-show="!entry.gap"
|
||||
data-active='{entry.value === currentPage()}'
|
||||
aria-current='{entry.value === currentPage() ? "page" : "false"}'
|
||||
@@ -632,18 +632,18 @@ component Pagination {
|
||||
{/each}
|
||||
</ol>
|
||||
|
||||
<p class="wire-pagination__compact" data-show="variant !== 'numbered'">
|
||||
<p class="wrn-pagination__compact" data-show="variant !== 'numbered'">
|
||||
{currentPage()} / {lastPage()}
|
||||
</p>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
class="wire-pagination__step"
|
||||
class="wrn-pagination__step"
|
||||
aria-label='{nextLabel}'
|
||||
@click='goNext()'
|
||||
>
|
||||
<span class="wire-pagination__step-label">{nextLabel}</span>
|
||||
<span class="wire-pagination__step-icon" aria-hidden="true">›</span>
|
||||
<span class="wrn-pagination__step-label">{nextLabel}</span>
|
||||
<span class="wrn-pagination__step-icon" aria-hidden="true">›</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -652,7 +652,7 @@ component Pagination {
|
||||
}
|
||||
|
||||
style {
|
||||
.wire-pagination {
|
||||
.wrn-pagination {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
@@ -661,20 +661,20 @@ component Pagination {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.wire-pagination__summary {
|
||||
.wrn-pagination__summary {
|
||||
margin: 0;
|
||||
color: var(--wire-color-text-muted);
|
||||
color: var(--wrn-color-text-muted);
|
||||
font-size: 0.82rem;
|
||||
}
|
||||
|
||||
.wire-pagination__controls {
|
||||
.wrn-pagination__controls {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.35rem;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.wire-pagination__pages {
|
||||
.wrn-pagination__pages {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.25rem;
|
||||
@@ -683,8 +683,8 @@ component Pagination {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.wire-pagination__page,
|
||||
.wire-pagination__step {
|
||||
.wrn-pagination__page,
|
||||
.wrn-pagination__step {
|
||||
appearance: none;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
@@ -692,50 +692,50 @@ component Pagination {
|
||||
min-width: 2.25rem;
|
||||
justify-content: center;
|
||||
padding: 0.4rem 0.6rem;
|
||||
border: 1px solid var(--wire-color-border);
|
||||
border-radius: var(--wire-radius-sm);
|
||||
background: var(--wire-color-surface);
|
||||
color: var(--wire-color-text);
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: var(--wrn-radius-sm);
|
||||
background: var(--wrn-color-surface);
|
||||
color: var(--wrn-color-text);
|
||||
font: inherit;
|
||||
font-size: 0.85rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.wire-pagination__page:hover,
|
||||
.wire-pagination__step:hover {
|
||||
background: var(--wire-color-surface-soft);
|
||||
.wrn-pagination__page:hover,
|
||||
.wrn-pagination__step:hover {
|
||||
background: var(--wrn-color-surface-soft);
|
||||
}
|
||||
|
||||
.wire-pagination__page[data-active="true"] {
|
||||
border-color: var(--wire-color-primary);
|
||||
background: var(--wire-color-primary);
|
||||
color: var(--wire-color-primary-contrast);
|
||||
.wrn-pagination__page[data-active="true"] {
|
||||
border-color: var(--wrn-color-primary);
|
||||
background: var(--wrn-color-primary);
|
||||
color: var(--wrn-color-primary-contrast);
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.wire-pagination__gap {
|
||||
.wrn-pagination__gap {
|
||||
padding: 0 0.35rem;
|
||||
color: var(--wire-color-text-muted);
|
||||
color: var(--wrn-color-text-muted);
|
||||
}
|
||||
|
||||
.wire-pagination__compact {
|
||||
.wrn-pagination__compact {
|
||||
margin: 0;
|
||||
padding: 0 0.5rem;
|
||||
color: var(--wire-color-text-muted);
|
||||
color: var(--wrn-color-text-muted);
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
/* Below the small breakpoint the word labels crowd the arrows out. */
|
||||
@media (max-width: 639px) {
|
||||
.wire-pagination {
|
||||
.wrn-pagination {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.wire-pagination__step-label {
|
||||
.wrn-pagination__step-label {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.wire-pagination__summary {
|
||||
.wrn-pagination__summary {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
@@ -816,14 +816,14 @@ test("stepper marks complete, current and upcoming steps", async () => {
|
||||
active: 1,
|
||||
});
|
||||
const dom = mountHtml(html);
|
||||
const items = [...dom.querySelectorAll(".wire-stepper__step")];
|
||||
const items = [...dom.querySelectorAll(".wrn-stepper__step")];
|
||||
|
||||
expect(items).toHaveLength(3);
|
||||
expect(items[0].getAttribute("data-status")).toBe("complete");
|
||||
expect(items[1].getAttribute("data-status")).toBe("current");
|
||||
expect(items[2].getAttribute("data-status")).toBe("upcoming");
|
||||
expect(items[1].getAttribute("aria-current")).toBe("step");
|
||||
expect(dom.querySelector(".wire-stepper")!.tagName.toLowerCase()).toBe("ol");
|
||||
expect(dom.querySelector(".wrn-stepper")!.tagName.toLowerCase()).toBe("ol");
|
||||
});
|
||||
|
||||
test("stepper renders vertically and clamps an out-of-range active index", async () => {
|
||||
@@ -834,9 +834,9 @@ test("stepper renders vertically and clamps an out-of-range active index", async
|
||||
orientation: "vertical",
|
||||
});
|
||||
const dom = mountHtml(html);
|
||||
const root = dom.querySelector(".wire-stepper") as HTMLElement;
|
||||
const root = dom.querySelector(".wrn-stepper") as HTMLElement;
|
||||
expect(root.getAttribute("data-orientation")).toBe("vertical");
|
||||
const items = [...dom.querySelectorAll(".wire-stepper__step")];
|
||||
const items = [...dom.querySelectorAll(".wrn-stepper__step")];
|
||||
expect(items[1].getAttribute("data-status")).toBe("current");
|
||||
});
|
||||
|
||||
@@ -859,7 +859,7 @@ test("clickable stepper opts into roving focus", async () => {
|
||||
bun test packages/ui -t "stepper"
|
||||
```
|
||||
|
||||
Expected: FAIL — the scaffold renders a `<nav>` of anchors with no `.wire-stepper__step`.
|
||||
Expected: FAIL — the scaffold renders a `<nav>` of anchors with no `.wrn-stepper__step`.
|
||||
|
||||
- [ ] **Step 3: Replace `packages/ui/components/Stepper.wrn`**
|
||||
|
||||
@@ -927,7 +927,7 @@ component Stepper {
|
||||
<ol
|
||||
{...attrs}
|
||||
data-ui-component="Stepper"
|
||||
class='wire-stepper {class}'
|
||||
class='wrn-stepper {class}'
|
||||
data-orientation='{orientation}'
|
||||
data-clickable='{clickable}'
|
||||
data-wrn-roving='{clickable ? (orientation === "vertical" ? "vertical" : "horizontal") : ""}'
|
||||
@@ -935,28 +935,28 @@ component Stepper {
|
||||
>
|
||||
{#each stepList() as step, index}
|
||||
<li
|
||||
class="wire-stepper__step"
|
||||
class="wrn-stepper__step"
|
||||
data-status='{statusFor(index)}'
|
||||
aria-current='{statusFor(index) === "current" ? "step" : "false"}'
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
class="wire-stepper__button"
|
||||
class="wrn-stepper__button"
|
||||
data-wrn-roving-item='{clickable}'
|
||||
@click='selectStep(index, step)'
|
||||
>
|
||||
<span class="wire-stepper__marker" aria-hidden="true">
|
||||
<span class='wire-stepper__icon {step.icon}' data-show="step.icon"></span>
|
||||
<span class="wire-stepper__number" data-show="!step.icon">{index + 1}</span>
|
||||
<span class="wrn-stepper__marker" aria-hidden="true">
|
||||
<span class='wrn-stepper__icon {step.icon}' data-show="step.icon"></span>
|
||||
<span class="wrn-stepper__number" data-show="!step.icon">{index + 1}</span>
|
||||
</span>
|
||||
<span class="wire-stepper__body">
|
||||
<span class="wire-stepper__label">{step.label}</span>
|
||||
<span class="wire-stepper__description" data-show="step.description">
|
||||
<span class="wrn-stepper__body">
|
||||
<span class="wrn-stepper__label">{step.label}</span>
|
||||
<span class="wrn-stepper__description" data-show="step.description">
|
||||
{step.description}
|
||||
</span>
|
||||
</span>
|
||||
</button>
|
||||
<span class="wire-stepper__custom">
|
||||
<span class="wrn-stepper__custom">
|
||||
<slot name="step-{index}"></slot>
|
||||
</span>
|
||||
</li>
|
||||
@@ -966,7 +966,7 @@ component Stepper {
|
||||
}
|
||||
|
||||
style {
|
||||
.wire-stepper {
|
||||
.wrn-stepper {
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
margin: 0;
|
||||
@@ -975,11 +975,11 @@ component Stepper {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.wire-stepper[data-orientation="vertical"] {
|
||||
.wrn-stepper[data-orientation="vertical"] {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.wire-stepper__step {
|
||||
.wrn-stepper__step {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1 1 0;
|
||||
@@ -987,7 +987,7 @@ component Stepper {
|
||||
gap: 0.35rem;
|
||||
}
|
||||
|
||||
.wire-stepper__button {
|
||||
.wrn-stepper__button {
|
||||
appearance: none;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -995,7 +995,7 @@ component Stepper {
|
||||
width: 100%;
|
||||
padding: 0.5rem;
|
||||
border: 0;
|
||||
border-radius: var(--wire-radius-sm);
|
||||
border-radius: var(--wrn-radius-sm);
|
||||
background: transparent;
|
||||
color: inherit;
|
||||
font: inherit;
|
||||
@@ -1003,67 +1003,67 @@ component Stepper {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.wire-stepper[data-clickable="true"] .wire-stepper__button {
|
||||
.wrn-stepper[data-clickable="true"] .wrn-stepper__button {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.wire-stepper[data-clickable="true"] .wire-stepper__button:hover {
|
||||
background: var(--wire-color-surface-soft);
|
||||
.wrn-stepper[data-clickable="true"] .wrn-stepper__button:hover {
|
||||
background: var(--wrn-color-surface-soft);
|
||||
}
|
||||
|
||||
.wire-stepper__marker {
|
||||
.wrn-stepper__marker {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex: 0 0 auto;
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
border: 1px solid var(--wire-color-border);
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: 999px;
|
||||
background: var(--wire-color-surface);
|
||||
background: var(--wrn-color-surface);
|
||||
font-size: 0.85rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.wire-stepper__step[data-status="complete"] .wire-stepper__marker {
|
||||
border-color: var(--wire-color-primary);
|
||||
background: var(--wire-color-primary);
|
||||
color: var(--wire-color-primary-contrast);
|
||||
.wrn-stepper__step[data-status="complete"] .wrn-stepper__marker {
|
||||
border-color: var(--wrn-color-primary);
|
||||
background: var(--wrn-color-primary);
|
||||
color: var(--wrn-color-primary-contrast);
|
||||
}
|
||||
|
||||
.wire-stepper__step[data-status="current"] .wire-stepper__marker {
|
||||
border-color: var(--wire-color-primary);
|
||||
color: var(--wire-color-primary);
|
||||
box-shadow: 0 0 0 3px color-mix(in srgb, var(--wire-color-primary) 22%, transparent);
|
||||
.wrn-stepper__step[data-status="current"] .wrn-stepper__marker {
|
||||
border-color: var(--wrn-color-primary);
|
||||
color: var(--wrn-color-primary);
|
||||
box-shadow: 0 0 0 3px color-mix(in srgb, var(--wrn-color-primary) 22%, transparent);
|
||||
}
|
||||
|
||||
.wire-stepper__step[data-status="upcoming"] .wire-stepper__marker {
|
||||
color: var(--wire-color-text-muted);
|
||||
.wrn-stepper__step[data-status="upcoming"] .wrn-stepper__marker {
|
||||
color: var(--wrn-color-text-muted);
|
||||
}
|
||||
|
||||
.wire-stepper__body {
|
||||
.wrn-stepper__body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.wire-stepper__label {
|
||||
.wrn-stepper__label {
|
||||
font-size: 0.9rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.wire-stepper__description {
|
||||
color: var(--wire-color-text-muted);
|
||||
.wrn-stepper__description {
|
||||
color: var(--wrn-color-text-muted);
|
||||
font-size: 0.78rem;
|
||||
}
|
||||
|
||||
.wire-stepper__step[data-status="upcoming"] .wire-stepper__label {
|
||||
color: var(--wire-color-text-muted);
|
||||
.wrn-stepper__step[data-status="upcoming"] .wrn-stepper__label {
|
||||
color: var(--wrn-color-text-muted);
|
||||
}
|
||||
|
||||
/* A horizontal stepper cannot stay side by side on a phone. */
|
||||
@media (max-width: 639px) {
|
||||
.wire-stepper {
|
||||
.wrn-stepper {
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
@@ -1163,11 +1163,11 @@ test("nav renders links, marks the active one, and shows icons and badges", asyn
|
||||
});
|
||||
const dom = mountHtml(html);
|
||||
|
||||
expect(dom.querySelector(".wire-nav")!.getAttribute("role")).toBe("navigation");
|
||||
expect(dom.querySelector(".wrn-nav")!.getAttribute("role")).toBe("navigation");
|
||||
const current = dom.querySelector('[aria-current="page"]');
|
||||
expect(current!.textContent).toContain("Inbox");
|
||||
expect(dom.querySelector(".wire-nav__badge")!.textContent!.trim()).toBe("9");
|
||||
expect(dom.querySelector(".wire-nav__icon")).not.toBeNull();
|
||||
expect(dom.querySelector(".wrn-nav__badge")!.textContent!.trim()).toBe("9");
|
||||
expect(dom.querySelector(".wrn-nav__icon")).not.toBeNull();
|
||||
expect(dom.querySelector('[aria-disabled="true"]')).not.toBeNull();
|
||||
});
|
||||
|
||||
@@ -1194,10 +1194,10 @@ test("nav renders a submenu with a disclosure arrow and opts into roving focus",
|
||||
|
||||
expect(dom.querySelector("[data-wrn-roving]")).not.toBeNull();
|
||||
expect(dom.querySelectorAll("[data-wrn-roving-item]").length).toBeGreaterThan(0);
|
||||
expect(dom.querySelector(".wire-nav__arrow")).not.toBeNull();
|
||||
expect(dom.querySelector(".wire-nav__submenu")).not.toBeNull();
|
||||
expect(dom.querySelector(".wrn-nav__arrow")).not.toBeNull();
|
||||
expect(dom.querySelector(".wrn-nav__submenu")).not.toBeNull();
|
||||
// Third level is rendered, and nothing deeper is attempted.
|
||||
expect(dom.querySelector(".wire-nav__submenu--level3")).not.toBeNull();
|
||||
expect(dom.querySelector(".wrn-nav__submenu--level3")).not.toBeNull();
|
||||
expect(dom.body.innerHTML).toContain("Deep");
|
||||
});
|
||||
|
||||
@@ -1205,8 +1205,8 @@ test("nav renders empty rather than throwing when items is not an array", async
|
||||
const source = readFileSync(uiComponentPath("Nav"), "utf8");
|
||||
const html = await renderComponent(source, { items: "not-an-array", active: "" });
|
||||
const dom = mountHtml(html);
|
||||
expect(dom.querySelector(".wire-nav")).not.toBeNull();
|
||||
expect(dom.querySelectorAll(".wire-nav__link").length).toBe(0);
|
||||
expect(dom.querySelector(".wrn-nav")).not.toBeNull();
|
||||
expect(dom.querySelectorAll(".wrn-nav__link").length).toBe(0);
|
||||
});
|
||||
```
|
||||
|
||||
@@ -1216,7 +1216,7 @@ test("nav renders empty rather than throwing when items is not an array", async
|
||||
bun test packages/ui -t "nav "
|
||||
```
|
||||
|
||||
Expected: FAIL — the scaffold renders bare anchors with no `.wire-nav__link`, no submenu and no roving attributes.
|
||||
Expected: FAIL — the scaffold renders bare anchors with no `.wrn-nav__link`, no submenu and no roving attributes.
|
||||
|
||||
- [ ] **Step 3: Replace `packages/ui/components/Nav.wrn`**
|
||||
|
||||
@@ -1274,7 +1274,7 @@ component Nav {
|
||||
<nav
|
||||
{...attrs}
|
||||
data-ui-component="Nav"
|
||||
class='wire-nav {class}'
|
||||
class='wrn-nav {class}'
|
||||
data-orientation='{orientation}'
|
||||
data-expanded='{expanded}'
|
||||
role="navigation"
|
||||
@@ -1282,24 +1282,24 @@ component Nav {
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
class="wire-nav__toggle"
|
||||
class="wrn-nav__toggle"
|
||||
data-show="collapsible"
|
||||
aria-expanded='{expanded}'
|
||||
aria-label='{toggleLabel}'
|
||||
@click='toggleMenu()'
|
||||
>
|
||||
<span class="wire-nav__toggle-bar" aria-hidden="true"></span>
|
||||
<span class="wire-nav__toggle-text">{toggleLabel}</span>
|
||||
<span class="wrn-nav__toggle-bar" aria-hidden="true"></span>
|
||||
<span class="wrn-nav__toggle-text">{toggleLabel}</span>
|
||||
</button>
|
||||
|
||||
<ul
|
||||
class="wire-nav__list"
|
||||
class="wrn-nav__list"
|
||||
data-wrn-roving='{orientation === "vertical" ? "vertical" : "horizontal"}'
|
||||
>
|
||||
{#each itemList() as item}
|
||||
<li class="wire-nav__item" data-has-children='{childrenOf(item).length > 0}'>
|
||||
<li class="wrn-nav__item" data-has-children='{childrenOf(item).length > 0}'>
|
||||
<a
|
||||
class="wire-nav__link"
|
||||
class="wrn-nav__link"
|
||||
href='{item.href || "#"}'
|
||||
data-wrn-roving-item="true"
|
||||
data-active='{isActive(item)}'
|
||||
@@ -1307,53 +1307,53 @@ component Nav {
|
||||
aria-disabled='{item.disabled ? "true" : "false"}'
|
||||
@click='choose(item)'
|
||||
>
|
||||
<span class='wire-nav__icon {item.icon}' data-show="item.icon" aria-hidden="true"></span>
|
||||
<span class="wire-nav__label">{item.label}</span>
|
||||
<span class="wire-nav__badge" data-show="item.badge">{item.badge}</span>
|
||||
<span class='wrn-nav__icon {item.icon}' data-show="item.icon" aria-hidden="true"></span>
|
||||
<span class="wrn-nav__label">{item.label}</span>
|
||||
<span class="wrn-nav__badge" data-show="item.badge">{item.badge}</span>
|
||||
<span
|
||||
class="wire-nav__arrow"
|
||||
class="wrn-nav__arrow"
|
||||
data-show="childrenOf(item).length > 0"
|
||||
aria-hidden="true"
|
||||
>›</span>
|
||||
</a>
|
||||
|
||||
<ul class="wire-nav__submenu" data-show="childrenOf(item).length > 0">
|
||||
<ul class="wrn-nav__submenu" data-show="childrenOf(item).length > 0">
|
||||
{#each childrenOf(item) as child}
|
||||
<li class="wire-nav__item" data-has-children='{childrenOf(child).length > 0}'>
|
||||
<li class="wrn-nav__item" data-has-children='{childrenOf(child).length > 0}'>
|
||||
<a
|
||||
class="wire-nav__link"
|
||||
class="wrn-nav__link"
|
||||
href='{child.href || "#"}'
|
||||
data-active='{isActive(child)}'
|
||||
aria-current='{isActive(child) ? "page" : "false"}'
|
||||
aria-disabled='{child.disabled ? "true" : "false"}'
|
||||
@click='choose(child)'
|
||||
>
|
||||
<span class='wire-nav__icon {child.icon}' data-show="child.icon" aria-hidden="true"></span>
|
||||
<span class="wire-nav__label">{child.label}</span>
|
||||
<span class="wire-nav__badge" data-show="child.badge">{child.badge}</span>
|
||||
<span class='wrn-nav__icon {child.icon}' data-show="child.icon" aria-hidden="true"></span>
|
||||
<span class="wrn-nav__label">{child.label}</span>
|
||||
<span class="wrn-nav__badge" data-show="child.badge">{child.badge}</span>
|
||||
<span
|
||||
class="wire-nav__arrow"
|
||||
class="wrn-nav__arrow"
|
||||
data-show="childrenOf(child).length > 0"
|
||||
aria-hidden="true"
|
||||
>›</span>
|
||||
</a>
|
||||
|
||||
<ul
|
||||
class="wire-nav__submenu wire-nav__submenu--level3"
|
||||
class="wrn-nav__submenu wrn-nav__submenu--level3"
|
||||
data-show="childrenOf(child).length > 0"
|
||||
>
|
||||
{#each childrenOf(child) as leaf}
|
||||
<li class="wire-nav__item">
|
||||
<li class="wrn-nav__item">
|
||||
<a
|
||||
class="wire-nav__link"
|
||||
class="wrn-nav__link"
|
||||
href='{leaf.href || "#"}'
|
||||
data-active='{isActive(leaf)}'
|
||||
aria-current='{isActive(leaf) ? "page" : "false"}'
|
||||
aria-disabled='{leaf.disabled ? "true" : "false"}'
|
||||
@click='choose(leaf)'
|
||||
>
|
||||
<span class='wire-nav__icon {leaf.icon}' data-show="leaf.icon" aria-hidden="true"></span>
|
||||
<span class="wire-nav__label">{leaf.label}</span>
|
||||
<span class='wrn-nav__icon {leaf.icon}' data-show="leaf.icon" aria-hidden="true"></span>
|
||||
<span class="wrn-nav__label">{leaf.label}</span>
|
||||
</a>
|
||||
</li>
|
||||
{/each}
|
||||
@@ -1370,11 +1370,11 @@ component Nav {
|
||||
}
|
||||
|
||||
style {
|
||||
.wire-nav {
|
||||
.wrn-nav {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.wire-nav__list {
|
||||
.wrn-nav__list {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.25rem;
|
||||
@@ -1383,61 +1383,61 @@ component Nav {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.wire-nav[data-orientation="vertical"] .wire-nav__list {
|
||||
.wrn-nav[data-orientation="vertical"] .wrn-nav__list {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.wire-nav__item {
|
||||
.wrn-nav__item {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.wire-nav__link {
|
||||
.wrn-nav__link {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.45rem;
|
||||
padding: 0.45rem 0.7rem;
|
||||
border-radius: var(--wire-radius-sm);
|
||||
color: var(--wire-color-text-muted);
|
||||
border-radius: var(--wrn-radius-sm);
|
||||
color: var(--wrn-color-text-muted);
|
||||
font-size: 0.9rem;
|
||||
font-weight: 600;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.wire-nav__link:hover {
|
||||
background: var(--wire-color-surface-soft);
|
||||
color: var(--wire-color-text);
|
||||
.wrn-nav__link:hover {
|
||||
background: var(--wrn-color-surface-soft);
|
||||
color: var(--wrn-color-text);
|
||||
}
|
||||
|
||||
.wire-nav__link[data-active="true"] {
|
||||
background: var(--wire-color-primary-soft);
|
||||
color: var(--wire-color-primary);
|
||||
.wrn-nav__link[data-active="true"] {
|
||||
background: var(--wrn-color-primary-soft);
|
||||
color: var(--wrn-color-primary);
|
||||
}
|
||||
|
||||
.wire-nav__link[aria-disabled="true"] {
|
||||
.wrn-nav__link[aria-disabled="true"] {
|
||||
opacity: 0.5;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.wire-nav__badge {
|
||||
.wrn-nav__badge {
|
||||
padding: 0.05rem 0.4rem;
|
||||
border-radius: 999px;
|
||||
background: var(--wire-color-primary-soft);
|
||||
color: var(--wire-color-primary);
|
||||
background: var(--wrn-color-primary-soft);
|
||||
color: var(--wrn-color-primary);
|
||||
font-size: 0.72rem;
|
||||
}
|
||||
|
||||
.wire-nav__arrow {
|
||||
.wrn-nav__arrow {
|
||||
display: inline-block;
|
||||
transition: transform 160ms ease;
|
||||
}
|
||||
|
||||
.wire-nav__item:hover > .wire-nav__link > .wire-nav__arrow,
|
||||
.wire-nav__item:focus-within > .wire-nav__link > .wire-nav__arrow {
|
||||
.wrn-nav__item:hover > .wrn-nav__link > .wrn-nav__arrow,
|
||||
.wrn-nav__item:focus-within > .wrn-nav__link > .wrn-nav__arrow {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
|
||||
.wire-nav__submenu {
|
||||
.wrn-nav__submenu {
|
||||
position: absolute;
|
||||
z-index: 30;
|
||||
top: 100%;
|
||||
@@ -1445,42 +1445,42 @@ component Nav {
|
||||
min-width: 12rem;
|
||||
margin: 0;
|
||||
padding: 0.35rem;
|
||||
border: 1px solid var(--wire-color-border);
|
||||
border-radius: var(--wire-radius-md);
|
||||
background: var(--wire-color-surface);
|
||||
box-shadow: var(--wire-shadow-1);
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: var(--wrn-radius-md);
|
||||
background: var(--wrn-color-surface);
|
||||
box-shadow: var(--wrn-shadow-1);
|
||||
list-style: none;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
transition: opacity 160ms ease;
|
||||
}
|
||||
|
||||
.wire-nav__item:hover > .wire-nav__submenu,
|
||||
.wire-nav__item:focus-within > .wire-nav__submenu {
|
||||
.wrn-nav__item:hover > .wrn-nav__submenu,
|
||||
.wrn-nav__item:focus-within > .wrn-nav__submenu {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.wire-nav__submenu--level3 {
|
||||
.wrn-nav__submenu--level3 {
|
||||
top: 0;
|
||||
left: 100%;
|
||||
}
|
||||
|
||||
.wire-nav__toggle {
|
||||
.wrn-nav__toggle {
|
||||
display: none;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
padding: 0.45rem 0.7rem;
|
||||
border: 1px solid var(--wire-color-border);
|
||||
border-radius: var(--wire-radius-sm);
|
||||
background: var(--wire-color-surface);
|
||||
color: var(--wire-color-text);
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: var(--wrn-radius-sm);
|
||||
background: var(--wrn-color-surface);
|
||||
color: var(--wrn-color-text);
|
||||
font: inherit;
|
||||
font-size: 0.9rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.wire-nav__toggle-bar {
|
||||
.wrn-nav__toggle-bar {
|
||||
width: 1rem;
|
||||
height: 2px;
|
||||
background: currentColor;
|
||||
@@ -1493,21 +1493,21 @@ component Nav {
|
||||
* unreachable on touch.
|
||||
*/
|
||||
@media (max-width: 767px) {
|
||||
.wire-nav__toggle {
|
||||
.wrn-nav__toggle {
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
.wire-nav__list {
|
||||
.wrn-nav__list {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.wire-nav[data-expanded="false"] .wire-nav__list {
|
||||
.wrn-nav[data-expanded="false"] .wrn-nav__list {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.wire-nav__submenu,
|
||||
.wire-nav__submenu--level3 {
|
||||
.wrn-nav__submenu,
|
||||
.wrn-nav__submenu--level3 {
|
||||
position: static;
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
@@ -1656,7 +1656,7 @@ git push
|
||||
|
||||
## Self-Review
|
||||
|
||||
**Spec coverage for phase 1.** Roving focus in the runtime — Task 1. Nav multi-level to depth 3, icons, badges, animated arrows, responsive collapse, `aria-current` — Task 5. Pagination standalone with compact and numbered variants and windowed numbers — Task 3. Stepper horizontal/vertical with indexed named slots and `aria-current="step"` — Task 4. Local `style {}` blocks with `wire-*` classes — Tasks 3, 4, 5. Error handling for non-array `items` and out-of-range `active`/`page` — covered by a test in each of Tasks 3, 4, 5. Showcase profiles and regeneration — Tasks 3–6. Runtime budget check — Tasks 1 and 6.
|
||||
**Spec coverage for phase 1.** Roving focus in the runtime — Task 1. Nav multi-level to depth 3, icons, badges, animated arrows, responsive collapse, `aria-current` — Task 5. Pagination standalone with compact and numbered variants and windowed numbers — Task 3. Stepper horizontal/vertical with indexed named slots and `aria-current="step"` — Task 4. Local `style {}` blocks with `wrn-*` classes — Tasks 3, 4, 5. Error handling for non-array `items` and out-of-range `active`/`page` — covered by a test in each of Tasks 3, 4, 5. Showcase profiles and regeneration — Tasks 3–6. Runtime budget check — Tasks 1 and 6.
|
||||
|
||||
Out of phase 1 by design, carried to later plans: Tabs, Sidebar, MegaMenu (phase 2); Navbar, Breadcrumb, Scrollspy, responsive sweep (phase 3).
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ Stepper has no steps or progress, Pagination has no pages.
|
||||
Of the remaining four, Breadcrumb is genuinely built (323 lines, own style
|
||||
block). Navbar and Sidebar render but have no keyboard handling and keep their
|
||||
styles in `ui.css`. Tabs works but is off-pattern in three ways: it is the only
|
||||
component in the library using Tailwind utility classes rather than `wire-*` +
|
||||
component in the library using Tailwind utility classes rather than `wrn-*` +
|
||||
a local style block, it has no `outputs` block and fires raw `CustomEvent`s via
|
||||
`dispatchEvent`, and it sets a roving `tabindex` with no `@keydown` handler at
|
||||
all — which is worse than having no keyboard support, because the roving
|
||||
@@ -28,7 +28,7 @@ All nine components, delivered in three phases.
|
||||
|
||||
### Styling
|
||||
|
||||
Every navigation component gets a local `style {}` block using `wire-*`
|
||||
Every navigation component gets a local `style {}` block using `wrn-*`
|
||||
classes. This matches DataTable, Toaster, Modal, Drawer, ContextMenu and
|
||||
Breadcrumb — the 22 of 108 components that carry local styles are exactly the
|
||||
recently built ones. Navbar and Sidebar styles move out of `ui.css` as part of
|
||||
@@ -116,7 +116,7 @@ scroll lock rather than duplicating them.
|
||||
| Component | Work |
|
||||
| ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Nav | Build. Flat or multi-level (3 deep), horizontal/vertical, `items[{label,href,value,icon,badge,disabled,items}]`, `aria-current="page"`, roving focus, animated arrows, collapses on mobile. `outputs: select` |
|
||||
| Tabs | Rewrite off Tailwind onto `wire-*` + local styles. Real `outputs {change, select}` replacing raw `dispatchEvent`. Roving + Home/End. `mode="client"\|"url"`. Panel transition. Fix the `<slot>` that renders regardless of active tab |
|
||||
| Tabs | Rewrite off Tailwind onto `wrn-*` + local styles. Real `outputs {change, select}` replacing raw `dispatchEvent`. Roving + Home/End. `mode="client"\|"url"`. Panel transition. Fix the `<slot>` that renders regardless of active tab |
|
||||
| Pagination | Build standalone. `page`/`pageSize`/`total`, compact + numbered styles, windowed page numbers. `outputs: change, previous, next` |
|
||||
| Stepper | Build. `<ol>`/`<li>`, status derived from `active` index, horizontal/vertical, optionally clickable, `aria-current="step"`. Indexed named slots (`data-slot="step-0"`, `step-1`, …) for custom per-step content, falling back to built-in rendering |
|
||||
| MegaMenu | Build. Trigger plus a single-level panel of link columns. Panel marked `data-wrn-anchored` so the existing clamp handles viewport containment. Hover and focus open, Escape closes, click-outside closes |
|
||||
|
||||
@@ -10,7 +10,7 @@ Two problems, in different proportions to the navigation group.
|
||||
**Three components advertise behaviour they do not have.**
|
||||
|
||||
`LayoutSplitter` is the worst component in the library. It declares
|
||||
`resizeStart`, `resize` and `resizeEnd`, so a caller reasonably wires up
|
||||
`resizeStart`, `resize` and `resizeEnd`, so a caller reasonably connects up
|
||||
`@resize` and receives nothing, forever, with no error. It has no pointer
|
||||
handling at all, and its props are `columns`, `gap` and `maxWidth`, copied
|
||||
wholesale from a grid scaffold. `CustomScrollbar` is the same shape: a
|
||||
@@ -22,9 +22,9 @@ genuinely does not need more. It is thin, not dishonest.
|
||||
**Most of the group is built on Tailwind utilities.**
|
||||
|
||||
Seven of the ten use utility classes and `class:` conditionals rather than
|
||||
`wire-*` classes and a local style block. They are theme-aware, because the
|
||||
`wrn-*` classes and a local style block. They are theme-aware, because the
|
||||
utilities carry arbitrary values bound to tokens
|
||||
(`bg-[var(--wire-color-surface-soft)]`), but they depend on Tailwind being
|
||||
(`bg-[var(--wrn-color-surface-soft)]`), but they depend on Tailwind being
|
||||
present and produce a class explosion. `SectionHeader` has 38 such lines.
|
||||
|
||||
A correction that shaped this survey: when Tabs was rewritten it was described
|
||||
@@ -50,7 +50,7 @@ audit rather than a rewrite.
|
||||
|
||||
### Styling
|
||||
|
||||
Every component in scope moves to `wire-*` classes with a local `style {}`
|
||||
Every component in scope moves to `wrn-*` classes with a local `style {}`
|
||||
block and `data-*` attributes for variants, matching PageHeader, DataTable,
|
||||
Toaster and the navigation group.
|
||||
|
||||
@@ -95,7 +95,7 @@ something: `axis`, `thickness`, `thumb`, `track`, `maxHeight`.
|
||||
|
||||
### Kbd
|
||||
|
||||
Left as it is, beyond the `wire-*` migration. It is thin because a `<kbd>`
|
||||
Left as it is, beyond the `wrn-*` migration. It is thin because a `<kbd>`
|
||||
is thin.
|
||||
|
||||
### Runtime budget
|
||||
|
||||
@@ -9,14 +9,14 @@ rebuilt. Numbers come from the source and from a browser, not from estimates.
|
||||
property does not warn — it resolves to nothing — so the styles that used them
|
||||
silently did nothing:
|
||||
|
||||
| Token | Effect while undefined |
|
||||
| ----------------------------- | --------------------------------------------------------- |
|
||||
| `--wire-color-focus` | Focus rings drew with no colour, in 14 components |
|
||||
| `--wire-color-surface-soft` | Every soft surface rendered transparent, in 27 components |
|
||||
| `--wire-color-on-danger` | Text on danger fills had no colour |
|
||||
| `--wire-color-surface-subtle` | Subtle panels rendered transparent |
|
||||
| `--wire-color-input-*` (6) | Input backgrounds, borders and placeholders unstyled |
|
||||
| `*-hover`, `*-contrast` | Missing for info, success, warning and danger |
|
||||
| Token | Effect while undefined |
|
||||
| ---------------------------- | --------------------------------------------------------- |
|
||||
| `--wrn-color-focus` | Focus rings drew with no colour, in 14 components |
|
||||
| `--wrn-color-surface-soft` | Every soft surface rendered transparent, in 27 components |
|
||||
| `--wrn-color-on-danger` | Text on danger fills had no colour |
|
||||
| `--wrn-color-surface-subtle` | Subtle panels rendered transparent |
|
||||
| `--wrn-color-input-*` (6) | Input backgrounds, borders and placeholders unstyled |
|
||||
| `*-hover`, `*-contrast` | Missing for info, success, warning and danger |
|
||||
|
||||
They are derived in the theme now, so they follow the palette and the accent.
|
||||
Verified in a browser: 38 tokens referenced, **0 undefined** (was 10).
|
||||
|
||||
+104
-104
@@ -2,109 +2,109 @@
|
||||
"schemaVersion": 1,
|
||||
"releaseLine": "0.8",
|
||||
"artifacts": {
|
||||
"packages/ui/components/Accordion.wrn": "6532417153592cf60ab437a3b4e500176b14394dd66756d47df087d8c4f863ef",
|
||||
"packages/ui/components/AdvancedSelect.wrn": "c3779c89ce309de8c1e2fbc02a39472fffd6fb10c2b83db0104c6d1135b87082",
|
||||
"packages/ui/components/AnnouncementBar.wrn": "903bfd9421a7350c923ace3315cedc5763fe3e6b7b54b660a0f26281d46a8754",
|
||||
"packages/ui/components/AuthForm.wrn": "bb5ac1ac8d981d490652eba5d4edf3612980470aa8b94bf4995cec1aa2db4bfc",
|
||||
"packages/ui/components/AuthSplitLayout.wrn": "2a04cabb8bf2bda8739e2aba6dcfd29713efa7b51777f99b03dad1645b6ddae1",
|
||||
"packages/ui/components/AvatarGroup.wrn": "737cd929e3bcd9f9b2fe1b602ae17c1fbf584bd8a1949ce36b65427931e27abc",
|
||||
"packages/ui/components/BackToTop.wrn": "b12c56ec8b7aabad68cbdc47f4b3237e2c21a61398f0aa51f9add6229b7357cd",
|
||||
"packages/ui/components/Blockquote.wrn": "70bb7f0da2743a44d38d38daebe09637c2653ccb8454d78a226c034cfece31d6",
|
||||
"packages/ui/components/Breadcrumb.wrn": "5ab85d273ce72e4d5b87907975bb33f0249a34f2f87f01dc0812e827f775eed9",
|
||||
"packages/ui/components/ButtonGroup.wrn": "be6675ae06b9f3285187e04d8d3312cf14cf4d24fe9bc0f78b2f796b6819ff69",
|
||||
"packages/ui/components/CTASection.wrn": "2d2241d4f1018cfd2f8ea1ddd5fa8c8fcb8d1bbb2d4e4498cb9f39ff47a3801c",
|
||||
"packages/ui/components/Card.wrn": "db5f313be0d057dac8c2d693574d15a146296c0aec6e41ec58b96966e45186d5",
|
||||
"packages/ui/components/Carousel.wrn": "72e216882e3d1d744edd0d7697ce5810353a7cc0c386022452546bd959ff351d",
|
||||
"packages/ui/components/Chart.wrn": "d2cedd0e02818d0908708c2d07a495c629fad13fa021a2e035d5023dc5c367de",
|
||||
"packages/ui/components/ChatBubble.wrn": "c7c0ffcf732161330cc7fba79775ac829264b16731c980d3ec0820fc3ac8f9a7",
|
||||
"packages/ui/components/Clipboard.wrn": "03fcfb9786008fd7fb0a7719c3279711253afc5bbb9b0262b805dd553c44da8a",
|
||||
"packages/ui/components/Collapse.wrn": "90220ce36529d2b44bc45b1b265373462b5871a4e492be127f52743fa0619b0b",
|
||||
"packages/ui/components/ColorPicker.wrn": "602752f2ad7f6b092987ccae9c35a0a413a6261d63d6e88f279ee939d0ec4049",
|
||||
"packages/ui/components/Columns.wrn": "e01496aa53025444cc51671efcce40d6d24d86775b2cbb1ee0def1862bb6315d",
|
||||
"packages/ui/components/Combobox.wrn": "78c97205f42f015d22dd58018641bbd6b0d9cba55b1138af5c9d1da8d1095202",
|
||||
"packages/ui/components/Confetti.wrn": "b9aece64735c721c24356122e52ca84602d9f646c7d8be1e0b80d9de3163a501",
|
||||
"packages/ui/components/Container.wrn": "4a0acbb896f4c11714e3925d912b10ef9aeedfa904b4ad8561aa2cbd9a0fdca0",
|
||||
"packages/ui/components/ContextMenu.wrn": "33fb0f60268b12411d66e3031dc0557cb231149e7a8d83340b4b453a6e37cb09",
|
||||
"packages/ui/components/CustomScrollbar.wrn": "fedb2ab06cc2cf9499c130590945ca6971a3edfb60407b6658ef7756e4be9823",
|
||||
"packages/ui/components/DataMap.wrn": "553677298a28cced00c419fe35dff3d989a8b6d829cadad6e563d4a63a02581e",
|
||||
"packages/ui/components/DataTable.wrn": "cfc3bb9110ccd1aa38b85fd74995180b6b82c177d0bbd6dcce99d56c99cc6e5b",
|
||||
"packages/ui/components/DatePicker.wrn": "0c63bc72951961105529c4ebdc1064c22f44d0ce5fc8b813df7554280c7b1ad0",
|
||||
"packages/ui/components/DeviceFrame.wrn": "b76a0c820278ac7df5c07702b5d95e764ce0ebfcf7d4f89a8b629df8ecafee11",
|
||||
"packages/ui/components/Divider.wrn": "f5cc449611022b3d3eedf982ae48f6b1a289db7855cc9b6ea0248dcda807ffb3",
|
||||
"packages/ui/components/DragAndDrop.wrn": "4c01e56b5f7734b50dbff57157e0fbf163667b8e8a8fc50e1907e77a87f69c51",
|
||||
"packages/ui/components/Drawer.wrn": "e6e2778e515361a3475439ab91b6efec3895efab2a4dfdcfb535713f656cc7ed",
|
||||
"packages/ui/components/Dropdown.wrn": "627319de0f555f0f07f80e19a59f9fd52e7f74af7cf2cf9ff09e114678ad9eb8",
|
||||
"packages/ui/components/FeatureCard.wrn": "2a1bfb01cec8a9892d3ff066e48c276fa7c548cb59c15bcd9b4bbf85450a07a2",
|
||||
"packages/ui/components/FeatureGrid.wrn": "3b4539ad3a5f93deb1ff29a98118dd8fa53cce1dd8433f7662d907019c04df37",
|
||||
"packages/ui/components/FeatureIconCard.wrn": "620f66a36ca5c8ad8f2ea09e94dc4471e4146189c42149e9d31db58501281639",
|
||||
"packages/ui/components/FileInput.wrn": "2cc422b2dc9d28b1c7ec8d83aa76ba8ddc2a83eb1d57f940fe320f6c4581c4b8",
|
||||
"packages/ui/components/FileUploadProgress.wrn": "185715b5c9cf6a285cdae2c17b54d4136faf7779c7841ad89e346397f61dad73",
|
||||
"packages/ui/components/Footer.wrn": "71790c99e4b15a62fdaf4b7a65d7016ca427408b62a2b1c7695ef1b39ba29440",
|
||||
"packages/ui/components/Grid.wrn": "d089d8657298b4d33993ba4bf7b581f816c65db513d8e48cf1fdd18da19e05a8",
|
||||
"packages/ui/components/Hero.wrn": "e4e39dcd59c273192c7e4136f6583279e20b0956bcba4cfbc3f6e01a1fade152",
|
||||
"packages/ui/components/HeroActions.wrn": "77f69085db73b946c00aa684d50fb5ae474684e440e81edbccfd8ef5dc357e33",
|
||||
"packages/ui/components/Image.wrn": "8113441bf90ab0d1d8618d477125ad339021f39e853db89d656c72c492e7a20b",
|
||||
"packages/ui/components/InputGroup.wrn": "dc8d9bf4ed4fa7eb1b81c2d7dc443fc4a2cef1f7cd4acceee06618c8d1faa61b",
|
||||
"packages/ui/components/InputNumber.wrn": "0ec020084f3e556d438f8264d61f836cfab4951c52d4df60e4944fb734fb38a9",
|
||||
"packages/ui/components/Kbd.wrn": "5afaabbb15902bd8fb82cb4155cf6cbfff55600927b54d564d27e2dd8b752386",
|
||||
"packages/ui/components/LayoutSplitter.wrn": "6bd6812e364420ed5d3439862116c58d0b011b298679005795bdccdbb7455066",
|
||||
"packages/ui/components/LegendIndicator.wrn": "830a79bcda542b372c8e5164651d2e6f6192beeca73a64fb2e31adb25cb0ee16",
|
||||
"packages/ui/components/Link.wrn": "b986abcc66bc0b1c6296f3ff4e560812e35d89cc680d5251d7a3883e68c1d053",
|
||||
"packages/ui/components/List.wrn": "9bfa9613f388e5b126fc27d505e8165d7aa4a058e72132b755585464e116490e",
|
||||
"packages/ui/components/ListGroup.wrn": "94d1887e74992e0ad8fc204c9b37c2888ed19ee796c62ab04aae34eef1e6c6d0",
|
||||
"packages/ui/components/Map.wrn": "9023a7a188480b24222a3910d26f6926918470369a1ab610f841c31a6120b9aa",
|
||||
"packages/ui/components/MarketingSectionHeader.wrn": "6f89a3b298ea299db686ddf903f92c4fe5d321719213943b16be82ba36c23302",
|
||||
"packages/ui/components/Marquee.wrn": "2a88c8bd8378469add26b0d937adccac4aa9f2c2005393010298e8e4fa89693e",
|
||||
"packages/ui/components/MegaMenu.wrn": "8a9a9b348ca1c5e182914ff55d981a91f47a49c52ef5e5efd8e4cb6e56361a43",
|
||||
"packages/ui/components/MetricCard.wrn": "6451182739298691908f68258c0250cce2a78b0dc27c97115579ece30d7d9f92",
|
||||
"packages/ui/components/MetricGrid.wrn": "6018a98c10628ed240ed236ed916c0ff60994d192c3aadafd10bc876be0f9364",
|
||||
"packages/ui/components/Modal.wrn": "59d4ae9d6dd2700692d9edecfe53ee868e9f864363a4885961d1813cb2bee51f",
|
||||
"packages/ui/components/Nav.wrn": "7dc456b879e9248bde267b986cdcb138b8f3127d98b51e27bc9708129953f5e2",
|
||||
"packages/ui/components/Navbar.wrn": "4f55470827c7a36062db82c495bf646f6bb428b75ba331e5a932e21f940476ea",
|
||||
"packages/ui/components/PageHeader.wrn": "59264dfb26a132fd3eb265c4374f9fcae781f30dd94a087c57e6e8256717cf14",
|
||||
"packages/ui/components/Pagination.wrn": "9ceb74745b159150b015bbbb1974c68e14a7d4b92bd03491cb23b8855aa07983",
|
||||
"packages/ui/components/PinInput.wrn": "dff3c69e2b5b2ee39f97a2c54ec6e36becd46bdc9b636a9ec249201b7d606d5a",
|
||||
"packages/ui/components/Popover.wrn": "f2996f00fad3e35fba2d48e70af17f592854eb73b9e8c6a83526aa78c4e41293",
|
||||
"packages/ui/components/PortalDashboard.wrn": "ed1713879ab6911920d641111885254e747081c54eb64e9305eda23272318e44",
|
||||
"packages/ui/components/PreferenceSwitcher.wrn": "5daf957dd91ab3acd5f2e16d8c717cc7938ef6fa41ea0b60e0561cf06aa146d2",
|
||||
"packages/ui/components/PublicPageShell.wrn": "369b74f65e27227311a2ed73e9ca56c8b60908100d6840a798e8ba5f2c8b1040",
|
||||
"packages/ui/components/RangeSlider.wrn": "97e77a1ba628d43b8585bc27d14167d5743ae8f435398fb7bcead50fe07dfc9b",
|
||||
"packages/ui/components/Rating.wrn": "959063a3a912d5f9247f851ceb882d7df986f8cd6e1893304224a59be6f88481",
|
||||
"packages/ui/components/Scrollspy.wrn": "76d1c17580c8d460f1222ce97585bdcac9779141f2f30d5460c84ff9f75413d8",
|
||||
"packages/ui/components/SearchBox.wrn": "717f7647fabd762f8ed60a7c3306eac3ddb83c0da292a53c76d91886c2b8f94f",
|
||||
"packages/ui/components/Section.wrn": "33eb8a82a2102229c2b1f64cec497e9e8e70b67adab8dbe396be860fccbb699c",
|
||||
"packages/ui/components/SectionHeader.wrn": "8eecf2ea7a93139512260e3d46ca2a1afeb341b8bd46b7c30baa6e2c75e25d10",
|
||||
"packages/ui/components/Sidebar.wrn": "03f1bbce75ca6d50ed940e62df39c539610e89eadd2064fe24abc7d5470f98bf",
|
||||
"packages/ui/components/SplitHero.wrn": "70e843565ff869bcf413b11b6d9830b2e2bd229863a00904596f71e2dff0e76d",
|
||||
"packages/ui/components/StatsBar.wrn": "c7d1df3895f25b6d3a2e1012a18b97592c7f33e65418b880d486f20c2d490686",
|
||||
"packages/ui/components/Stepper.wrn": "df9093e4222ef3250963a8c6fbfec74477242735d23eabe896c29731c54fc14d",
|
||||
"packages/ui/components/StrongPassword.wrn": "a89d82649983e4b251babe69ff85f3f9623ad7c230c7ef74883749e646f43cf4",
|
||||
"packages/ui/components/StyledIcon.wrn": "ef3406d097cc9967f0f7d8d5f66108de4c78b453b47cc0c6627630d455acc9fa",
|
||||
"packages/ui/components/Tabs.wrn": "e38336d28876caa4e97da32a569749e3803b030284a85ce9f35fa788e51cc5b0",
|
||||
"packages/ui/components/TextLink.wrn": "6e18906337cd3d30c2a0122593d249bde8f7cedc697b90ae388e2bd0e8eff3e1",
|
||||
"packages/ui/components/TimePicker.wrn": "3b5bc1c380bb4d3569863ed783a8d8f94f7a5fa8948f4bda54f48b828a15ab52",
|
||||
"packages/ui/components/Timeline.wrn": "686a37ebc62732842846d004491336970db94945bca942f226097d863e159d1c",
|
||||
"packages/ui/components/Toaster.wrn": "288b2b370f65bf823e8d2a6f8c8cf66972332b8174303d33ebe8546d5e1d52c4",
|
||||
"packages/ui/components/ToggleCount.wrn": "a17440af5d52be0ce59655bb61565a89832fe41f950f115da1da0abfaa86dea3",
|
||||
"packages/ui/components/TogglePassword.wrn": "a4546b6825533efc6b010a095583da1664f8b63a28718bfab71609c4136aeeb5",
|
||||
"packages/ui/components/TreeView.wrn": "c354fce9c5e81fed6eec4089dfd2a7f6bb84eb189c94efc88e00251efdc12c0b",
|
||||
"packages/ui/components/Typography.wrn": "1b4d1b91dee0ff522d27c566becc3bc49bd9ec979ae6334e6a15fca5d88eccac",
|
||||
"packages/ui/components/WysiwygEditor.wrn": "5535de685d70514651da061698eafc954c5dfea6de944e0c852c456c2d489df1",
|
||||
"packages/ui/components/alert.wrn": "490a6f5b311b22ca5d630639c831b325b6918b2dd5440a242749f90af59f8b13",
|
||||
"packages/ui/components/avatar.wrn": "78f602b031eb1de2db588dbcb83bbbbb9c52bef2c1c6a4a905276c3ec3e78119",
|
||||
"packages/ui/components/badge.wrn": "7049be83eab9c909f2efc39cbbb5dae4aba3a6be2051b9271b92892a6438ad93",
|
||||
"packages/ui/components/button.wrn": "da1660c671daf2feffe1024203ac1a8bc947beb07691bef595c1552c664b9cde",
|
||||
"packages/ui/components/checkbox.wrn": "6e055207275294fd2390671dfa6c16db2bae692422f38689adad282601d04539",
|
||||
"packages/ui/components/input.wrn": "5c7c2a8e2334e8c2c966a70ec4c4140ddd99a9084b9f7e2de630152bb3f2d8a4",
|
||||
"packages/ui/components/progress.wrn": "61b01ba575d35691e3dfebfcb03ccd1c6b79f1df1c0d41857ec3b01944081a5d",
|
||||
"packages/ui/components/radio.wrn": "f5ec1cab84c0d1b5e75133c44ce2220cd3ae5ad16a72d04c6b92b2482b9bf8b8",
|
||||
"packages/ui/components/select.wrn": "0a15a19f17e3f9565d8370eab1b97f1ec7299c4e248d80d64e63897fe6ff1c0e",
|
||||
"packages/ui/components/skeleton.wrn": "dda95a2c59c6060ab2b9f916eb046fbe74a68b398a051afc0bde41808e059c3a",
|
||||
"packages/ui/components/spinner.wrn": "ffbd28ec6fc017fc94c67778f8966eab2eefa3b47f3f27f064c77dbeb65d84c1",
|
||||
"packages/ui/components/switch.wrn": "9d3892f7a800e0fd98f39c3205eeb96a416f8a1d6834d11678a4c8abf9ee5d71",
|
||||
"packages/ui/components/textarea.wrn": "dc6f079201c06caaa0ca01b65c5efe80ec4a0b50fecac9726ac3e5a8256c4f16",
|
||||
"packages/ui/components/tooltip.wrn": "40028dfbb17f6725c76c2e091af9c30ea4db6aa4dea919d38f53874ea70315d1",
|
||||
"packages/ui/styles/SelectStyles.wrn": "2c45e9c04678aaff76632e908b3c061410be0d6999a54a9203a39a3817d698f2",
|
||||
"packages/ui/ui.css": "b7e2ae796ffbb738451364f63fce13022a81d81207f7e49c7f6220d24c36acd9"
|
||||
"packages/ui/components/Accordion.wrn": "09251f76a2f9385e97eb67e06c0cf868e1771ac5f420647221bec5160287034b",
|
||||
"packages/ui/components/AdvancedSelect.wrn": "b952b894a5b35050fc2f6e43c4182101eeee05c75662e2aca4abfe61512b305b",
|
||||
"packages/ui/components/AnnouncementBar.wrn": "cb66b8d0619ee798a115b43f0ad93fda93dfb46571589e7a9f0a8d65ec3c84c9",
|
||||
"packages/ui/components/AuthForm.wrn": "46a3e1db1c9e69efc52473cbf2fababdcbfe7144e7571469638d2c3addd4d7f0",
|
||||
"packages/ui/components/AuthSplitLayout.wrn": "724938921bc38cc5a0422de69c237b630f099f2df94c66977362b048e4a420a5",
|
||||
"packages/ui/components/AvatarGroup.wrn": "30b702e06a1adff8b9bae32820206020e086a69560cbdcbadb19f04f25951f97",
|
||||
"packages/ui/components/BackToTop.wrn": "5b760ec7941ffd8e58c5dedae1b322ee46e072e927533d7ec077b511a816e436",
|
||||
"packages/ui/components/Blockquote.wrn": "3761bf13babb6eb07ce7392258ee439ef5478064cf589eff63f945b950e00d2e",
|
||||
"packages/ui/components/Breadcrumb.wrn": "9f6c23550ebfc635c36ca8660953775170b4a471c0cd0206b9a7ba760994980a",
|
||||
"packages/ui/components/ButtonGroup.wrn": "fc23565ad56bd8483fcb777d9e02ccba2f9ea476c085754d42503bb83b718f72",
|
||||
"packages/ui/components/CTASection.wrn": "d0665f2aa33eea95e6f84120f739b3dd9c8723c882138bcb1a7f80dcd7909904",
|
||||
"packages/ui/components/Card.wrn": "255912df0668ebcf45b6cc3ffe99a4a3e0bf87376a5d199e3adcdf3610ea79e3",
|
||||
"packages/ui/components/Carousel.wrn": "7ab122bc0ce772346c665b43d62e73c9865a13b97c02ccf5b03d1e3eaea757d6",
|
||||
"packages/ui/components/Chart.wrn": "07bc01247b5a1c2b82c2ba8386b7fcdbf480efead75d52b7da04d471072c7ee4",
|
||||
"packages/ui/components/ChatBubble.wrn": "d71f7d6567d76ac0eb3ecc8e2e567fec12bb3236ea05f4d0a72286abc0b7cbb1",
|
||||
"packages/ui/components/Clipboard.wrn": "5a93f2bae337d7ce364229b796bac673f60dde6dc135f0969f4e106e04854d30",
|
||||
"packages/ui/components/Collapse.wrn": "26df087a61c82f1aa1749785f4c9be654c4f934859c1a47acfcb8cc67eecc75d",
|
||||
"packages/ui/components/ColorPicker.wrn": "557e36adbdee66d8ba9dcdc2446c13f3385a243f2766777feef8504908006c99",
|
||||
"packages/ui/components/Columns.wrn": "8ccd9e53f6799b09f8b996740d12e4e73ee782f6fd3e57595c6c16f788b9b812",
|
||||
"packages/ui/components/Combobox.wrn": "58488dbb60e41dacbf223afdb4a05abdbec53b7f54cd79a0db659add7057b1c1",
|
||||
"packages/ui/components/Confetti.wrn": "0e81426a3ee8aff672385a5466cf96085c25ba17677a2fef432bcddf13f4d58e",
|
||||
"packages/ui/components/Container.wrn": "61c895a9cc0e02d314392e94226bddfae2b8fad074e30a68ba935e6ec9549ea6",
|
||||
"packages/ui/components/ContextMenu.wrn": "1b078b9ac20ce2561167b0e14cec1fc26704c251d7a25021b45e51e1b980946e",
|
||||
"packages/ui/components/CustomScrollbar.wrn": "2a3a2719580c21823d079c92ebb000c7a5a7d9d16e3fa9275b8fb7d4449cb437",
|
||||
"packages/ui/components/DataMap.wrn": "338f0d0a3307289dd0387b7fe7ba631fa0b65b6be8c7b9ee3feb2203306f76a3",
|
||||
"packages/ui/components/DataTable.wrn": "e929fdb4e59613878a03fb6a11e09c42f773c06ca7b20e43ae16a266835f2af4",
|
||||
"packages/ui/components/DatePicker.wrn": "91bcfd3832d3bccc4de5402c0c06209947bde593bad4f869b4c29ee14a5c0bef",
|
||||
"packages/ui/components/DeviceFrame.wrn": "c38d25419ee44b05d7c443cc4e854aeeb7a53a9289e374d71834de2dd2e4d979",
|
||||
"packages/ui/components/Divider.wrn": "bfa36cf16ccd48c996bb0b08a438f1b281ea1811049ed69fc7680925b1eba019",
|
||||
"packages/ui/components/DragAndDrop.wrn": "84305f07d43cdb9eff1f63c19458d88b0aec013424d05a49a2cafbecedc60513",
|
||||
"packages/ui/components/Drawer.wrn": "5692db9a627587951898c2392789ef9dcae1662f19663607171a17d8f4ddb023",
|
||||
"packages/ui/components/Dropdown.wrn": "978367a9dde22448cc664d686e4dd9c579fe8ba0b2cf02d610d95a3501f8dbb0",
|
||||
"packages/ui/components/FeatureCard.wrn": "1bc548c115f924a0c7ade4c557852757083755c60ca0ee747b150a7cca3ebced",
|
||||
"packages/ui/components/FeatureGrid.wrn": "15b5d6f9ddb7e3697682e7247fdf3c2dd080b770335f84ba9fab2692166fe897",
|
||||
"packages/ui/components/FeatureIconCard.wrn": "3b4f3fa62c6729e686886a5b848e26c255766684829cec2b715967b4e73d6f07",
|
||||
"packages/ui/components/FileInput.wrn": "866a292a3280527bf429893469e7c50f7cf38965d8adb37b45a35ede1606d5b8",
|
||||
"packages/ui/components/FileUploadProgress.wrn": "e5da29c562a521cdd6bb50b8f4d217aa1ab981d7b2a2432af47391472f0a8034",
|
||||
"packages/ui/components/Footer.wrn": "6694302f63f44dda3527d97b1bcc3031d51362601835dbe842cb04ba70088758",
|
||||
"packages/ui/components/Grid.wrn": "83d4f5f2656d539538723f5791ba3c238901432e9d8c55c74f068d3eb5a74517",
|
||||
"packages/ui/components/Hero.wrn": "345478b212701817ff57060f87982a987baf01a7179c979768e1cd4218b50900",
|
||||
"packages/ui/components/HeroActions.wrn": "67cd31400ccb6abdbbf16219267dee946b44b064b79f25276d20ceb7d6e8a790",
|
||||
"packages/ui/components/Image.wrn": "361179c478d7674c3b998891a366d73de9514fc6cc8786440c6c50b9ef065357",
|
||||
"packages/ui/components/InputGroup.wrn": "30e9f2e4364542179180b6d6e796002d0ffe1e30305146749874697cde6629ea",
|
||||
"packages/ui/components/InputNumber.wrn": "069195cc483f3f7d6f305d03fbe5a821906a030376fafb6f0d969e4c95b68fd0",
|
||||
"packages/ui/components/Kbd.wrn": "6b402cb93f0fa76bb978d1ba483215f70ec7214b1c5e84b568fa3e26e87ed9d9",
|
||||
"packages/ui/components/LayoutSplitter.wrn": "41d070e801a271552023e4392e4c0f67327c61e2e8eaee5f8b87af254b1d79c1",
|
||||
"packages/ui/components/LegendIndicator.wrn": "b2b75a2a5edc20a326c2047d4c81b9cd3f319292a1eec5f4abd5cbafc0677d71",
|
||||
"packages/ui/components/Link.wrn": "13f9d6b403440f4b3c3a9ce4dbefa0d5570eb30ff93f498e49f18baab3e08c1d",
|
||||
"packages/ui/components/List.wrn": "5bd7d0b12b2f7dbf730db4030c6e20c6617b0933c1341428bbd6bcdab9ab6073",
|
||||
"packages/ui/components/ListGroup.wrn": "eb7eca762101ea873fd6fa2f12f427580130fba3b21c0448a551b0452997dc92",
|
||||
"packages/ui/components/Map.wrn": "3e6d5de5a21dd050c5c65950d6fb2f89af4024e1856a48f055b65b88fcd7b890",
|
||||
"packages/ui/components/MarketingSectionHeader.wrn": "39b79499b77dc1c7d34e4e5ecb45a9ddc6182f78c2a2586671c4fa07f44679ad",
|
||||
"packages/ui/components/Marquee.wrn": "81cd80732be34c8d7e4bf28b00347e1a9273166afdf66589d9f5d5774b69403b",
|
||||
"packages/ui/components/MegaMenu.wrn": "6a6db166259f8f2bd7ac8fbb21dba6d915c4b936d87b19805caa78189f54730a",
|
||||
"packages/ui/components/MetricCard.wrn": "513a6e99be3d9db46d96af9942b51331a0a048b184603e77e814506f0a52bdc5",
|
||||
"packages/ui/components/MetricGrid.wrn": "c71e53249835908833055b553e64a8ee55fdf11ac4605436a9581ebb87a0608b",
|
||||
"packages/ui/components/Modal.wrn": "7fa4b877772736f29f690e24d8742922b310397ef3083f0b78acb67a9f0d14b2",
|
||||
"packages/ui/components/Nav.wrn": "c45b0ecb42250f4b3ede33c8932a025f789dda9ef48dbf332459ae458163e69a",
|
||||
"packages/ui/components/Navbar.wrn": "ed3bb1974b93d52c480af468bdb1c0b253cb9196f3a00602614d3ce1e271a669",
|
||||
"packages/ui/components/PageHeader.wrn": "321cde36ce8d521a57901033d46e8b437f42e558cca27f49ca26f7172aff1d54",
|
||||
"packages/ui/components/Pagination.wrn": "4c7ac4bbda38c791af503f7923a511a958adc01637d286bcaaaa0f00ae8bb0fd",
|
||||
"packages/ui/components/PinInput.wrn": "4dc398456f6392d7925db941debb484c7cb0358ecef527f696fe5ec4800a7602",
|
||||
"packages/ui/components/Popover.wrn": "1246b99b4236bc7109a5d1427d013bb07bbea7a2da4f821517d2545ee0b5c019",
|
||||
"packages/ui/components/PortalDashboard.wrn": "f04171eb1f8cabef06de3c20e4694b766def3407e1e20d2c9aaebc9bb7da03ee",
|
||||
"packages/ui/components/PreferenceSwitcher.wrn": "71fc4b2fd8897dbd2e0795a6a824d76a57a4ce8756a889662f26df28b73c411a",
|
||||
"packages/ui/components/PublicPageShell.wrn": "3d3f25c03d48f3d3d7e3c567e79cb137c7fce1867e054fd6d440fa1d2e961077",
|
||||
"packages/ui/components/RangeSlider.wrn": "bbf646c5d5a89a62986290db811d77b8f635ebcaea9ca2d334b569aa5edc785b",
|
||||
"packages/ui/components/Rating.wrn": "902b55c64e3798f3097f09b1558d1a2372f66d4f760662de085783108ee04587",
|
||||
"packages/ui/components/Scrollspy.wrn": "b9c6400ee92a7c228362610a2051f37bff1d3baba1dbacd66d58397dfda5d856",
|
||||
"packages/ui/components/SearchBox.wrn": "3f88340e0b69c0cd552023c72bd22dc511bc00422d46060097bcf0777e683675",
|
||||
"packages/ui/components/Section.wrn": "45b7a1977c25a6020d5cc8bab2ce9c80730e7ec2d51ad53e8c9f64cd9b5b64cd",
|
||||
"packages/ui/components/SectionHeader.wrn": "aca2df8eb35806096f5b9af466b018e5c22a19422e8665f488380da577a0ceb5",
|
||||
"packages/ui/components/Sidebar.wrn": "e0250a973aea589a4d7dcc8b30dd01f22592bf22ba012e54a672b2a2288d8af6",
|
||||
"packages/ui/components/SplitHero.wrn": "843387dc7b920b3cf6a1b2b785b8653c281982e524479edc2638a89381ff3577",
|
||||
"packages/ui/components/StatsBar.wrn": "c273bd6ca417a0a20e5e6f1214414f678741b73bedd885fea1037575fa8c5b95",
|
||||
"packages/ui/components/Stepper.wrn": "7ec0902acd7cb74b44d490215b6421dae9a41731735ad1e9aec17e8bfc3fa142",
|
||||
"packages/ui/components/StrongPassword.wrn": "d5ea906fafe268b070a26ab551a252c0575d899c9d2b03b337bd047688b85dc5",
|
||||
"packages/ui/components/StyledIcon.wrn": "0874f9a234b053a7c8b9c6983be5d664453a64c4576dff1a049101e249a2866d",
|
||||
"packages/ui/components/Tabs.wrn": "f85214960e62da2fac41228deba511a50c57fd94f2830a8233b75048f6a542e9",
|
||||
"packages/ui/components/TextLink.wrn": "9d561631c5f65a2bcdc59f5c0b166a5dd794a396f42093f2cd26388386f6f954",
|
||||
"packages/ui/components/TimePicker.wrn": "ec0860a4a82a042a65acf9aa81519a5c815b61e0b8080cf6f1c986d26ce7f0e8",
|
||||
"packages/ui/components/Timeline.wrn": "fb553f69763840532eef1c0aafa79013f57411dc5335e7cb7e7c20c5a3753008",
|
||||
"packages/ui/components/Toaster.wrn": "5e4c9b2c1bfd5675a81a32e57684b99393ac7fe45d8420c7409a4e95d47d080c",
|
||||
"packages/ui/components/ToggleCount.wrn": "e577195ee05ddb43cceec47145f6b90c0149f2f17055733d58911fcd02de2c7f",
|
||||
"packages/ui/components/TogglePassword.wrn": "b6176453cb2c586fe88c3db6bdd734ae2b4c95db46d57e0de298dfba3d0dd0c2",
|
||||
"packages/ui/components/TreeView.wrn": "f54d8495730203b923629bcfb167d5ca41236af0101ea2723d33354413555b4b",
|
||||
"packages/ui/components/Typography.wrn": "a3de0febe0ba8640660e7f22babe8ca0e75e1b2882ba7be42f0728add7e05740",
|
||||
"packages/ui/components/WysiwygEditor.wrn": "3f9d1765184581e3c1f335769a9f19969917450258bc95ba076980d99f5610b5",
|
||||
"packages/ui/components/alert.wrn": "d42287e41b918b1e19962e9462ef203002eb5480acac984f115b711e9dbe663d",
|
||||
"packages/ui/components/avatar.wrn": "8bc705e459b13c7f063c57e1506ce540e50fa8ef9020ae85b6e8b6a3579fc5dc",
|
||||
"packages/ui/components/badge.wrn": "e44e33633fb34e897696cd9290f210108e35a3e2dc3b2a4a367411f45c69a1e1",
|
||||
"packages/ui/components/button.wrn": "cba4ccbbd23bb75b3836ec7a53673e40f1e043d18bfcee3d613db96c318f4ba8",
|
||||
"packages/ui/components/checkbox.wrn": "18046396b75d0b9c6bb2bdb09dbff1846c84fb07490f390a25ca7b5367fd2ef4",
|
||||
"packages/ui/components/input.wrn": "a576e5ee2c6d0da963ebb14e8809ddf3ec7333b1eae095d5a4b7fce3ceb1fb55",
|
||||
"packages/ui/components/progress.wrn": "6307a90585197d7aab19a8710b2430f5d4ed27ce77e9b90b1414ea0eed876492",
|
||||
"packages/ui/components/radio.wrn": "09425a78358de5bbd2f47482f313e80065135335b969ce5ccdd5c7cc3ea5232c",
|
||||
"packages/ui/components/select.wrn": "b107b259d228201e9071701370ad1c912ac9a8131f9e0a55834bcc84ef0dd417",
|
||||
"packages/ui/components/skeleton.wrn": "4fc5e0846eeefd7830c038e1789be995c4f9d833aa913ff079eb4863baa65648",
|
||||
"packages/ui/components/spinner.wrn": "2322645da7ef53f7c06035ff071d9a2f6ffe2901ff9338daed84037369367105",
|
||||
"packages/ui/components/switch.wrn": "874504e4828e9db6a570d78984c4d3a76d0ceb39d70baa877649cb3798c82c85",
|
||||
"packages/ui/components/textarea.wrn": "76d432179f2b7790ab9cdd644752928c259e1f496ad89c4db79981b74bbd226f",
|
||||
"packages/ui/components/tooltip.wrn": "f3dfdfa5cd9661fe5e95ef3580eef4c7437c069726421370c2d7328fbe7d840d",
|
||||
"packages/ui/styles/SelectStyles.wrn": "074fe0d67de4ef5e9f9cfe879beb72fd5c83352888687d3a1a4b7722c87af3ca",
|
||||
"packages/ui/ui.css": "9ea591404e9cf675bbf1003e15e9fad00327094ff217dc20733f0fc87c0f4a62"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user