refactor: migrate legacy wire namespace to wrn
This commit is contained in:
+2
-2
@@ -4,7 +4,7 @@ dist/
|
||||
**/.wrnexus/**
|
||||
**/.wrnexus-*/**
|
||||
.publish/
|
||||
**/.wirefw/
|
||||
**/.wrnfw/
|
||||
coverage/
|
||||
bun.lock
|
||||
bun.lockb
|
||||
@@ -14,7 +14,7 @@ bun.lockb
|
||||
**/*.gen.ts
|
||||
**/*.generated.d.ts
|
||||
|
||||
# Bundled .wire compiler for the VS Code extension (generated)
|
||||
# Bundled .wrn compiler for the VS Code extension (generated)
|
||||
editors/vscode/src/compiler.cjs
|
||||
editors/vscode/src/language-server.cjs
|
||||
editors/vscode/src/extension.bundle.cjs
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@wrnexus/ai",
|
||||
"version": "0.8.8",
|
||||
"version": "0.8.9",
|
||||
"type": "module",
|
||||
"description": "Zero-dependency Claude (Anthropic) client for WrNexus apps.",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@wrnexus/authz",
|
||||
"version": "0.8.8",
|
||||
"version": "0.8.9",
|
||||
"type": "module",
|
||||
"description": "@wrnexus/authz — part of the WrNexus framework.",
|
||||
"license": "MIT",
|
||||
@@ -41,8 +41,8 @@
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@wrnexus/core": "^0.8.8",
|
||||
"@wrnexus/db": "^0.8.8"
|
||||
"@wrnexus/core": "^0.8.9",
|
||||
"@wrnexus/db": "^0.8.9"
|
||||
},
|
||||
"files": [
|
||||
"dist",
|
||||
|
||||
@@ -79,7 +79,7 @@ Every command accepts an optional `[app-dir]` (defaults to `.`). Commands that r
|
||||
| `wrnexus generate docker` | Scaffold `Dockerfile`, `.dockerignore`, and `docker-compose.yml`. |
|
||||
| `wrnexus generate mobile` | Scaffold a Capacitor shell for iOS and Android. |
|
||||
| `wrnexus mobile add <package...>` | Install Capacitor plugins and sync native projects. |
|
||||
| `wrnexus eject <name...>` | Copy Wire UI component `.wrn` sources into `app/components/`. |
|
||||
| `wrnexus eject <name...>` | Copy WrNexus UI component `.wrn` sources into `app/components/`. |
|
||||
| `wrnexus db <cmd>` | Database migrations and tooling (see [db](#wrnexus-db)). |
|
||||
| `wrnexus test [app-dir] [--watch]` | Run the app's tests via `bun test` (defaults to the `test` profile). |
|
||||
| `wrnexus profiles [app-dir]` | List config profiles and their `.env` files, marking the active one. |
|
||||
@@ -179,7 +179,7 @@ WrNexus response pages.
|
||||
|
||||
### `wrnexus eject`
|
||||
|
||||
Copies a Wire UI component's `.wrn` source out of `@wrnexus/ui` into `app/components/`, so the app owns and can edit it (the app copy shadows the library one by name). Run with no names to list available components. It skips components that already exist in the app.
|
||||
Copies a WrNexus UI component's `.wrn` source out of `@wrnexus/ui` into `app/components/`, so the app owns and can edit it (the app copy shadows the library one by name). Run with no names to list available components. It skips components that already exist in the app.
|
||||
|
||||
```bash
|
||||
wrnexus eject button card modal
|
||||
@@ -322,5 +322,5 @@ export default config;
|
||||
## Requirements / Notes
|
||||
|
||||
- **Bun-only.** The CLI runs on Bun, spawns the Bun binary for the dev child and `bun test`, and the production build uses `Bun.build`. Node is not supported.
|
||||
- Orchestrates the rest of the framework: `@wrnexus/dev-server` (dev/prod server + gateway), `@wrnexus/router` (route + typed-routes codegen), `@wrnexus/compiler` (`.wrn` → `.ts`), `@wrnexus/db` (migrations, typed queries), `@wrnexus/styles` (config, profiles, `.env`, themes, styles), `@wrnexus/ui` (ejectable Wire UI components), `@wrnexus/validation`, `@wrnexus/csr`, and `@wrnexus/i18n`.
|
||||
- Orchestrates the rest of the framework: `@wrnexus/dev-server` (dev/prod server + gateway), `@wrnexus/router` (route + typed-routes codegen), `@wrnexus/compiler` (`.wrn` → `.ts`), `@wrnexus/db` (migrations, typed queries), `@wrnexus/styles` (config, profiles, `.env`, themes, styles), `@wrnexus/ui` (ejectable WrNexus UI components), `@wrnexus/validation`, `@wrnexus/csr`, and `@wrnexus/i18n`.
|
||||
- Reads `wrnexus.config.ts` for `db` / `databases`, `theme`, `styles`, `seo`, `security`, `i18n`, and `profiles`, and `wrnexus.workspace.ts` for the gateway.
|
||||
|
||||
+12
-12
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@wrnexus/cli",
|
||||
"version": "0.8.8",
|
||||
"version": "0.8.17",
|
||||
"type": "module",
|
||||
"description": "@wrnexus/cli — part of the WrNexus framework.",
|
||||
"license": "MIT",
|
||||
@@ -44,19 +44,19 @@
|
||||
"wrnexus": "./dist/index.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@wrnexus/core": "^0.8.8",
|
||||
"@wrnexus/router": "^0.8.8",
|
||||
"@wrnexus/csr": "^0.8.8",
|
||||
"@wrnexus/compiler": "^0.8.8",
|
||||
"@wrnexus/styles": "^0.8.8",
|
||||
"@wrnexus/dev-server": "^0.8.8",
|
||||
"@wrnexus/ui": "^0.8.8",
|
||||
"@wrnexus/validation": "^0.8.8",
|
||||
"@wrnexus/i18n": "^0.8.8",
|
||||
"@wrnexus/core": "^0.8.9",
|
||||
"@wrnexus/router": "^0.8.9",
|
||||
"@wrnexus/csr": "^0.8.16",
|
||||
"@wrnexus/compiler": "^0.8.9",
|
||||
"@wrnexus/styles": "^0.8.10",
|
||||
"@wrnexus/dev-server": "^0.8.16",
|
||||
"@wrnexus/ui": "^0.8.12",
|
||||
"@wrnexus/validation": "^0.8.9",
|
||||
"@wrnexus/i18n": "^0.8.9",
|
||||
"@wrnexus/mcp": "^0.8.8",
|
||||
"@wrnexus/playground": "^0.8.8",
|
||||
"@wrnexus/db": "^0.8.8",
|
||||
"@wrnexus/authz": "^0.8.8",
|
||||
"@wrnexus/db": "^0.8.9",
|
||||
"@wrnexus/authz": "^0.8.9",
|
||||
"@wrnexus/plugin": "^0.8.8",
|
||||
"@wrnexus/syntax": "^0.8.8",
|
||||
"@wrnexus/typecheck": "^0.8.8",
|
||||
|
||||
@@ -69,7 +69,7 @@ bun add @wrnexus/compiler
|
||||
|
||||
All exports come from the package root (`@wrnexus/compiler`).
|
||||
|
||||
### `compileWireFile(source: string): string`
|
||||
### `compileWrnFile(source: string): string`
|
||||
|
||||
Compile `.wrn` source to a TypeScript module string. Throws `ParseError` on invalid input. The output is prefixed with a `// compiled from .wrn` comment.
|
||||
|
||||
@@ -115,10 +115,10 @@ class Lexer {
|
||||
|
||||
### Errors
|
||||
|
||||
| Class | Thrown by | Meaning |
|
||||
| ------------ | ------------------------------------------------- | --------------------------------------------------------------- |
|
||||
| `ParseError` | `parse`, `compile`, `compileWireFile`, `generate` | Invalid `.wrn` grammar or (rewrapped) lex failure. |
|
||||
| `LexError` | `Lexer` | Unexpected character / unterminated string / unbalanced braces. |
|
||||
| Class | Thrown by | Meaning |
|
||||
| ------------ | ------------------------------------------------ | --------------------------------------------------------------- |
|
||||
| `ParseError` | `parse`, `compile`, `compileWrnFile`, `generate` | Invalid `.wrn` grammar or (rewrapped) lex failure. |
|
||||
| `LexError` | `Lexer` | Unexpected character / unterminated string / unbalanced braces. |
|
||||
|
||||
### AST types
|
||||
|
||||
@@ -143,9 +143,9 @@ Exported type-only symbols describing the parsed tree:
|
||||
Compile a page:
|
||||
|
||||
```ts
|
||||
import { compileWireFile } from "@wrnexus/compiler";
|
||||
import { compileWrnFile } from "@wrnexus/compiler";
|
||||
|
||||
const ts = compileWireFile(`
|
||||
const ts = compileWrnFile(`
|
||||
page Home {
|
||||
state count = 0
|
||||
seo { title = "Home" description = "Welcome" }
|
||||
@@ -214,4 +214,4 @@ A file opens with `page <Name>` or `component <Name>` followed by a `{ ... }` bo
|
||||
## Requirements / Notes
|
||||
|
||||
- Pure TypeScript with no runtime dependencies; runs under **Bun** as part of the WrNexus toolchain (Node is not supported).
|
||||
- Generated modules target WrNexus runtime primitives (`data-scope`, `data-text`, `data-on-*`, `data-for`, `data-component`, `__wrnexus*`/`__wire*` helpers) — consume the output within a WrNexus app, e.g. via `@wrnexus/core`'s dev loader.
|
||||
- Generated modules target WrNexus runtime primitives (`data-scope`, `data-text`, `data-on-*`, `data-for`, `data-component`, `__wrnexus*`/`__wrn*` helpers) — consume the output within a WrNexus app, e.g. via `@wrnexus/core`'s dev loader.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@wrnexus/compiler",
|
||||
"version": "0.8.8",
|
||||
"version": "0.8.9",
|
||||
"type": "module",
|
||||
"description": "@wrnexus/compiler — part of the WrNexus framework.",
|
||||
"license": "MIT",
|
||||
@@ -37,10 +37,10 @@
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@wrnexus/csr": "^0.8.8",
|
||||
"@wrnexus/csr": "^0.8.16",
|
||||
"@wrnexus/syntax": "^0.8.8",
|
||||
"@wrnexus/store": "^0.8.8",
|
||||
"@wrnexus/validation": "^0.8.8"
|
||||
"@wrnexus/validation": "^0.8.9"
|
||||
},
|
||||
"files": [
|
||||
"dist",
|
||||
|
||||
@@ -37,7 +37,7 @@ The `Context` (`ctx`) is the single value passed to middleware and handlers.
|
||||
| `Context` | type | Per-request object: `req`, `url`, `lang`, `t`, `params`, `locals`, `user?`, `ip?`, `cookies`, `session`, `localStorage`. |
|
||||
| `Next` | type | `() => Promise<Response> \| Response` — invokes the next middleware/handler. |
|
||||
| `Middleware` | type | `(ctx, next) => Promise<Response> \| Response`. Return `next()` to continue, or a `Response` to short-circuit. |
|
||||
| `createContext(req, url)` | fn | Build a fresh `Context` for an incoming request (wires up cookies, session, localStorage snapshot). |
|
||||
| `createContext(req, url)` | fn | Build a fresh `Context` for an incoming request (connects up cookies, session, localStorage snapshot). |
|
||||
| `withContextHeaders(ctx, res)` | fn | Apply accumulated headers (e.g. `Set-Cookie`) from the context onto a response. |
|
||||
| `PageComponent` | type | `(ctx) => string \| Promise<string>` — a page module's default export. |
|
||||
| `PageMeta` / `SeoConfig` | type | `<head>` metadata: `title`, `description`, `canonical`, `robots`, `image`, `twitterCard`, `themeColor`, … |
|
||||
@@ -70,15 +70,15 @@ cookie-backed `SessionStore`.
|
||||
|
||||
### CSRF — `@wrnexus/core`
|
||||
|
||||
Double-submit cookie pattern: a readable `wire-csrf` cookie is echoed in an
|
||||
Double-submit cookie pattern: a readable `wrn-csrf` cookie is echoed in an
|
||||
`x-csrf-token` header on unsafe requests.
|
||||
|
||||
| Export | Signature | Notes |
|
||||
| ----------------------------- | -------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
|
||||
| `csrfToken(ctx)` | `(Context) => string` | Ensures the CSRF cookie exists and returns its token. |
|
||||
| `verifyCsrf(ctx)` | `(Context) => boolean` | Safe methods (GET/HEAD/OPTIONS) pass; otherwise header/`ctx.locals._csrf` must match the cookie (constant-time). |
|
||||
| `csrfProtection()` | `() => Middleware` | 403s unsafe requests with a missing/mismatched token. |
|
||||
| `CSRF_COOKIE` / `CSRF_HEADER` | `"wire-csrf"` / `"x-csrf-token"` | Cookie & header names. |
|
||||
| Export | Signature | Notes |
|
||||
| ----------------------------- | ------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
|
||||
| `csrfToken(ctx)` | `(Context) => string` | Ensures the CSRF cookie exists and returns its token. |
|
||||
| `verifyCsrf(ctx)` | `(Context) => boolean` | Safe methods (GET/HEAD/OPTIONS) pass; otherwise header/`ctx.locals._csrf` must match the cookie (constant-time). |
|
||||
| `csrfProtection()` | `() => Middleware` | 403s unsafe requests with a missing/mismatched token. |
|
||||
| `CSRF_COOKIE` / `CSRF_HEADER` | `"wrn-csrf"` / `"x-csrf-token"` | Cookie & header names. |
|
||||
|
||||
### Rate limiting — `@wrnexus/core`
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@wrnexus/core",
|
||||
"version": "0.8.8",
|
||||
"version": "0.8.9",
|
||||
"type": "module",
|
||||
"description": "@wrnexus/core — part of the WrNexus framework.",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -111,11 +111,11 @@ Intercepts same-origin `<a>` clicks, fetches the target page, and swaps the `#ap
|
||||
|
||||
Connects to `/realtime/<name>` over WebSocket (`ws`/`wss` chosen from `location.protocol`). Two usage modes.
|
||||
|
||||
Programmatic API via `window.wire`:
|
||||
Programmatic API via `window.wrn`:
|
||||
|
||||
```ts
|
||||
wire.room(name): Room // open (or reuse) a room connection
|
||||
wire.bindRooms(root?) // (re)bind declarative [data-room] containers
|
||||
wrn.room(name): Room // open (or reuse) a room connection
|
||||
wrn.bindRooms(root?) // (re)bind declarative [data-room] containers
|
||||
|
||||
interface Room {
|
||||
name: string;
|
||||
@@ -211,7 +211,7 @@ A realtime chat, fully declarative:
|
||||
Or drive a room from code:
|
||||
|
||||
```ts
|
||||
const room = wire.room("lobby");
|
||||
const room = wrn.room("lobby");
|
||||
room.on("chat", (msg) => console.log(msg.user, msg.text));
|
||||
room.send({ type: "chat", user: "ada", text: "hi" });
|
||||
```
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@wrnexus/csr",
|
||||
"version": "0.8.8",
|
||||
"version": "0.8.16",
|
||||
"type": "module",
|
||||
"description": "@wrnexus/csr — part of the WrNexus framework.",
|
||||
"license": "MIT",
|
||||
@@ -37,7 +37,7 @@
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@wrnexus/core": "^0.8.8"
|
||||
"@wrnexus/core": "^0.8.9"
|
||||
},
|
||||
"files": [
|
||||
"dist",
|
||||
|
||||
@@ -128,7 +128,7 @@ const events = await getDb("analytics").all("SELECT * FROM hits");
|
||||
|
||||
Migrations are `.sql` files (in e.g. `app/db/migrations`), each split into
|
||||
`-- +up` and `-- +down` sections. A file with no markers is treated entirely as
|
||||
`up`. Applied names are recorded in a `_wire_migrations` table so each runs once.
|
||||
`up`. Applied names are recorded in a `_wrn_migrations` table so each runs once.
|
||||
|
||||
- `parseMigration(name, content)` → `Migration` (`{ name, up, down }`).
|
||||
- `loadMigrations(dir)` — parse all `.sql` files, sorted by filename.
|
||||
@@ -249,7 +249,7 @@ SQL driver — use `@wrnexus/db/mongo` directly.
|
||||
- **Bun-only.** Uses `bun:sqlite` (SQLite adapter + session store) and `Bun.SQL`
|
||||
(Postgres/MySQL). Migrations/scaffolding use `node:fs`/`node:path`.
|
||||
- Works with `@wrnexus/core` — `sqliteSessionStore` implements its
|
||||
`SessionBackend`; `getDb`/`setDb` are wired by the WrNexus runtime from
|
||||
`SessionBackend`; `getDb`/`setDb` are connected by the WrNexus runtime from
|
||||
`wrnexus.config.ts`.
|
||||
- The `mongodb` npm package is an optional, lazily-imported peer — install it
|
||||
only if you use `@wrnexus/db/mongo`. The core package stays dependency-free.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@wrnexus/db",
|
||||
"version": "0.8.8",
|
||||
"version": "0.8.9",
|
||||
"type": "module",
|
||||
"description": "Typed database drivers, migrations, instrumentation, repositories, pagination, and transaction helpers.",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -6,7 +6,7 @@ Part of the **WrNexus** framework — an SSR-first, Bun-native full-stack web fr
|
||||
|
||||
## Overview
|
||||
|
||||
This package is the server runtime that powers a WrNexus app in both development and production. A single **request runtime** (`createHandlers`) owns HTTP/WebSocket dispatch and SSR document assembly; it knows nothing about _how_ modules and assets are produced, so the dev and prod entry points wire in different backends: dev uses dynamic module loading plus on-the-fly bundling and injects a live-reload client; prod uses a static, pre-built manifest with cache-immutable assets. The package also ships a multi-app **gateway** (route several apps by `Host` header behind one port) and a portable `node:http` adapter for WinterCG hosts. It is entirely server-side and Bun-native (`Bun.serve`, `Bun.file`, `Bun.gzipSync`).
|
||||
This package is the server runtime that powers a WrNexus app in both development and production. A single **request runtime** (`createHandlers`) owns HTTP/WebSocket dispatch and SSR document assembly; it knows nothing about _how_ modules and assets are produced, so the dev and prod entry points wrn in different backends: dev uses dynamic module loading plus on-the-fly bundling and injects a live-reload client; prod uses a static, pre-built manifest with cache-immutable assets. The package also ships a multi-app **gateway** (route several apps by `Host` header behind one port) and a portable `node:http` adapter for WinterCG hosts. It is entirely server-side and Bun-native (`Bun.serve`, `Bun.file`, `Bun.gzipSync`).
|
||||
|
||||
## Installation
|
||||
|
||||
@@ -21,16 +21,16 @@ bun add @wrnexus/dev-server
|
||||
|
||||
### Main entry (`@wrnexus/dev-server`)
|
||||
|
||||
| Export | Kind | Purpose |
|
||||
| --------------------------------------------------------- | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `startServer(opts: ServeOptions)` | `Promise<RunningServer>` | Start the dev server on `Bun.serve`: builds the router, connects/migrates databases, wires assets + HMR, and starts the file watcher. |
|
||||
| `createHandlers(deps: RuntimeDeps)` | `Handlers` | The shared request runtime (fetch + websocket handlers). Re-exported from `runtime.ts`. |
|
||||
| `createProductionServer(manifest, opts)` | `Bun.Server` | Start the production server from a precompiled manifest. |
|
||||
| `createProductionHandlers(manifest, opts)` | `Handlers` | Build the portable prod fetch/websocket handlers with no server bound (the deployment-adapter seam). |
|
||||
| `startGateway(opts: GatewayOptions)` | `Promise<RunningGateway>` | Boot multiple apps as child processes and route by `Host`. |
|
||||
| `toRequest`, `writeResponse`, `nodeListener`, `serveNode` | functions | `node:http` ↔ WinterCG `Request`/`Response` adapter. |
|
||||
| `RESTART_EXIT_CODE` | `number` (`97`) | Exit code the dev child uses to ask the supervisor for a fresh process. |
|
||||
| `STYLES_HREF`, `HMR_CLIENT_JS` | constants | The global stylesheet URL and the inline HMR client script. |
|
||||
| Export | Kind | Purpose |
|
||||
| --------------------------------------------------------- | ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `startServer(opts: ServeOptions)` | `Promise<RunningServer>` | Start the dev server on `Bun.serve`: builds the router, connects/migrates databases, connects assets + HMR, and starts the file watcher. |
|
||||
| `createHandlers(deps: RuntimeDeps)` | `Handlers` | The shared request runtime (fetch + websocket handlers). Re-exported from `runtime.ts`. |
|
||||
| `createProductionServer(manifest, opts)` | `Bun.Server` | Start the production server from a precompiled manifest. |
|
||||
| `createProductionHandlers(manifest, opts)` | `Handlers` | Build the portable prod fetch/websocket handlers with no server bound (the deployment-adapter seam). |
|
||||
| `startGateway(opts: GatewayOptions)` | `Promise<RunningGateway>` | Boot multiple apps as child processes and route by `Host`. |
|
||||
| `toRequest`, `writeResponse`, `nodeListener`, `serveNode` | functions | `node:http` ↔ WinterCG `Request`/`Response` adapter. |
|
||||
| `RESTART_EXIT_CODE` | `number` (`97`) | Exit code the dev child uses to ask the supervisor for a fresh process. |
|
||||
| `STYLES_HREF`, `HMR_CLIENT_JS` | constants | The global stylesheet URL and the inline HMR client script. |
|
||||
|
||||
Exported types: `ServeOptions`, `RunningServer`, `RuntimeDeps`, `AssetServer`, `WsData`, `GatewayApp`, `GatewayOptions`, `GatewayAuth`, `GatewaySecurity`, `RunningGateway`, `FetchHandler`.
|
||||
|
||||
@@ -85,7 +85,7 @@ interface RuntimeDeps {
|
||||
getMiddleware(): Promise<Middleware[]>;
|
||||
assets: AssetServer; // serves /__wrnexus/* (islands, reactive, hmr)
|
||||
hasStyles?: boolean; // inject the global stylesheet link
|
||||
hasUi?: boolean; // inject the Wire UI stylesheet (/__wrnexus/ui.css)
|
||||
hasUi?: boolean; // inject the WrNexus UI stylesheet (/__wrnexus/ui.css)
|
||||
theme?: ResolvedTheme; // enables /__wrnexus/theme.css + <html data-theme>
|
||||
i18n?: ResolvedI18n; // enables ctx.t, <html lang>, {t:key} markers
|
||||
inlineStyles?: string; // inline small prod stylesheets into <head>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@wrnexus/dev-server",
|
||||
"version": "0.8.8",
|
||||
"version": "0.8.16",
|
||||
"type": "module",
|
||||
"description": "@wrnexus/dev-server — part of the WrNexus framework.",
|
||||
"license": "MIT",
|
||||
@@ -41,21 +41,21 @@
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@wrnexus/authz": "^0.8.8",
|
||||
"@wrnexus/rpc": "^0.8.8",
|
||||
"@wrnexus/core": "^0.8.8",
|
||||
"@wrnexus/dev-toolbar": "^0.8.8",
|
||||
"@wrnexus/router": "^0.8.8",
|
||||
"@wrnexus/ssr": "^0.8.8",
|
||||
"@wrnexus/csr": "^0.8.8",
|
||||
"@wrnexus/compiler": "^0.8.8",
|
||||
"@wrnexus/styles": "^0.8.8",
|
||||
"@wrnexus/ui": "^0.8.8",
|
||||
"@wrnexus/validation": "^0.8.8",
|
||||
"@wrnexus/i18n": "^0.8.8",
|
||||
"@wrnexus/db": "^0.8.8",
|
||||
"@wrnexus/pubsub": "^0.8.8",
|
||||
"@wrnexus/uploader": "^0.8.8",
|
||||
"@wrnexus/authz": "^0.8.9",
|
||||
"@wrnexus/rpc": "^0.8.9",
|
||||
"@wrnexus/core": "^0.8.9",
|
||||
"@wrnexus/dev-toolbar": "^0.8.9",
|
||||
"@wrnexus/router": "^0.8.9",
|
||||
"@wrnexus/ssr": "^0.8.9",
|
||||
"@wrnexus/csr": "^0.8.16",
|
||||
"@wrnexus/compiler": "^0.8.9",
|
||||
"@wrnexus/styles": "^0.8.10",
|
||||
"@wrnexus/ui": "^0.8.12",
|
||||
"@wrnexus/validation": "^0.8.9",
|
||||
"@wrnexus/i18n": "^0.8.9",
|
||||
"@wrnexus/db": "^0.8.9",
|
||||
"@wrnexus/pubsub": "^0.8.9",
|
||||
"@wrnexus/uploader": "^0.8.9",
|
||||
"@wrnexus/plugin": "^0.8.8",
|
||||
"@wrnexus/store": "^0.8.8",
|
||||
"@wrnexus/security": "^0.8.8",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@wrnexus/dev-toolbar",
|
||||
"version": "0.8.8",
|
||||
"version": "0.8.9",
|
||||
"type": "module",
|
||||
"description": "@wrnexus/dev-toolbar — part of the WrNexus framework.",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
# @wrnexus/encryption
|
||||
|
||||
Authenticated encryption, hashing, HMAC, key rotation, and optional encrypted HTTP exchanges for WRNexusJS.
|
||||
|
||||
## Core helpers
|
||||
|
||||
- `generateKey()` — random 256-bit AES key encoded as base64.
|
||||
- `deriveKey(password, salt)` — PBKDF2-derived AES key.
|
||||
- `encrypt(plaintext, key)` / `decrypt(payload, key)` — AES-256-GCM.
|
||||
- `sha256(data)` — SHA-256 digest.
|
||||
- `hmacSign(data, secret)` / `hmacVerify(...)` — HMAC-SHA256.
|
||||
- `createKeyring(keys)` — active/previous key management.
|
||||
- `seal()` / `open()` — versioned ciphertext with key ID.
|
||||
|
||||
## Encrypted HTTP envelope
|
||||
|
||||
```ts
|
||||
import {
|
||||
createEncryptedRequest,
|
||||
createKeyring,
|
||||
createMemoryReplayStore,
|
||||
decryptEncryptedResponse,
|
||||
encryptedExchange,
|
||||
} from "@wrnexus/encryption";
|
||||
|
||||
const keyring = createKeyring([{ id: "2026-08", secret: process.env.API_BODY_KEY!, active: true }]);
|
||||
|
||||
const replayStore = createMemoryReplayStore();
|
||||
|
||||
// Server middleware.
|
||||
app.use(
|
||||
encryptedExchange({
|
||||
keyring,
|
||||
replayStore,
|
||||
maxAgeMs: 60_000,
|
||||
maxBodyBytes: 1_048_576,
|
||||
}),
|
||||
);
|
||||
|
||||
// Controlled service/native client.
|
||||
const request = await createEncryptedRequest(
|
||||
"https://api.example.com/private/report",
|
||||
{ reportId: "report-1" },
|
||||
{ method: "POST", keyring },
|
||||
);
|
||||
const response = await fetch(request);
|
||||
const result = await decryptEncryptedResponse(response, request, { keyring });
|
||||
```
|
||||
|
||||
The envelope binds authenticated ciphertext to:
|
||||
|
||||
- HTTP method
|
||||
- URL path and query
|
||||
- request ID
|
||||
- timestamp and expiry window
|
||||
- encryption key ID
|
||||
- optional replay-store consumption
|
||||
|
||||
`encryptedBody()` decrypts request bodies only. `encryptedExchange()` also encrypts successful downstream responses while allowing application exceptions to propagate normally. `encryptedFetch()` provides a convenient controlled-client call.
|
||||
|
||||
## Security boundary
|
||||
|
||||
Encrypted HTTP bodies **do not replace TLS/HTTPS**. Always use HTTPS.
|
||||
|
||||
This layer is appropriate for service-to-service traffic, native/mobile applications, controlled agents, and selected fields protected with server-managed keys. It cannot conceal data from an end user when browser JavaScript receives the decryption key. Never ship a long-lived server encryption key to a browser.
|
||||
|
||||
Use a shared replay store such as Redis in multi-instance deployments. The memory replay store is process-local.
|
||||
@@ -1,46 +0,0 @@
|
||||
{
|
||||
"name": "@wrnexus/encryption",
|
||||
"version": "0.8.8",
|
||||
"type": "module",
|
||||
"description": "Authenticated encryption, key rotation, hashing, and optional application-layer encrypted HTTP envelopes.",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://git.workroot.in/WorkRoot/WRNexusJS.git",
|
||||
"directory": "packages/encryption"
|
||||
},
|
||||
"homepage": "https://wrnexusjs.dev/packages/encryption",
|
||||
"bugs": {
|
||||
"url": "https://git.workroot.in/WorkRoot/WRNexusJS/issues"
|
||||
},
|
||||
"keywords": [
|
||||
"wrnexus",
|
||||
"bun",
|
||||
"typescript",
|
||||
"encryption"
|
||||
],
|
||||
"sideEffects": false,
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
"engines": {
|
||||
"bun": ">=1.3.0"
|
||||
},
|
||||
"publishConfig": {
|
||||
"registry": "https://registry.npmjs.org/",
|
||||
"access": "restricted"
|
||||
},
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"import": "./dist/index.js"
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@wrnexus/core": "^0.8.8"
|
||||
},
|
||||
"files": [
|
||||
"dist",
|
||||
"README.md"
|
||||
]
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
# @wrnexus/helpers
|
||||
|
||||
Safe convenience helpers for common WrNexus application flows. The package uses
|
||||
standard `Context`, `URL`, and `Response` values and has no runtime dependency beyond
|
||||
`@wrnexus/core`.
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
bun add @wrnexus/helpers
|
||||
```
|
||||
|
||||
The package is private, so the machine must be authenticated to the `wrnexus` npm
|
||||
organization.
|
||||
|
||||
## Usage
|
||||
|
||||
### Redirect an unauthenticated forward-auth request
|
||||
|
||||
The gateway calls an SSO verifier on a different URL from the original application.
|
||||
These helpers reconstruct the original URL from the gateway headers and safely place it
|
||||
in the login redirect:
|
||||
|
||||
```ts
|
||||
import type { Context } from "@wrnexus/core";
|
||||
import { redirectToLogin } from "@wrnexus/helpers";
|
||||
|
||||
export const GET = async (ctx: Context) => {
|
||||
if (await hasValidSession(ctx)) {
|
||||
return new Response(null, { status: 204 });
|
||||
}
|
||||
|
||||
return redirectToLogin(ctx, "/login", {
|
||||
allowedHosts: ["admin.localhost:3000", "reports.localhost:3000"],
|
||||
});
|
||||
};
|
||||
```
|
||||
|
||||
This creates a response such as:
|
||||
|
||||
```text
|
||||
Location: http://sso.localhost:3000/login?returnTo=http%3A%2F%2Fadmin.localhost%3A3000%2F
|
||||
```
|
||||
|
||||
Always list the application hosts that are valid redirect destinations. Forwarded host
|
||||
headers are rejected when `allowedHosts` is absent or does not match, preventing an open
|
||||
redirect.
|
||||
|
||||
The SSO hostname is the login destination, not an `allowedHosts` entry. For example,
|
||||
when protecting `admin.localhost:3000`, keep `admin.localhost:3000` in the allowlist even
|
||||
though the verifier runs at `sso.localhost:3000`. WRNexus preserves both hosts across a
|
||||
nested gateway request.
|
||||
|
||||
### Support dynamic tenant domains
|
||||
|
||||
```ts
|
||||
import type { Context } from "@wrnexus/core";
|
||||
import { getOriginalRequestOrigin, redirectToLogin } from "@wrnexus/helpers";
|
||||
|
||||
export const GET = async (ctx: Context) => {
|
||||
const allowedHosts = (host: string) => host === "example.test" || host.endsWith(".example.test");
|
||||
|
||||
console.info("Authentication requested by", getOriginalRequestOrigin(ctx, { allowedHosts }));
|
||||
return redirectToLogin(ctx, "https://auth.example.test/login", {
|
||||
allowedHosts,
|
||||
returnToParam: "continue",
|
||||
status: 303,
|
||||
});
|
||||
};
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
- `getOriginalRequestUrl(ctx, options): URL` — reconstruct the gateway URL.
|
||||
- `getOriginalRequestOrigin(ctx, options): string` — return only its origin.
|
||||
- `getOriginalRequestPath(ctx): string` — return its path and query string.
|
||||
- `getOriginalRequestMethod(ctx): string` — return its HTTP method.
|
||||
- `redirectToLogin(ctx, loginUrl, options): Response` — create a login redirect with an
|
||||
encoded `returnTo` parameter.
|
||||
|
||||
For direct requests without gateway headers, URL helpers use `ctx.url`.
|
||||
@@ -1,46 +0,0 @@
|
||||
{
|
||||
"name": "@wrnexus/helpers",
|
||||
"version": "0.8.8",
|
||||
"type": "module",
|
||||
"description": "Safe convenience helpers for WrNexus request contexts and common application flows.",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://git.workroot.in/WorkRoot/WRNexusJS.git",
|
||||
"directory": "packages/helpers"
|
||||
},
|
||||
"homepage": "https://wrnexusjs.dev/packages/helpers",
|
||||
"bugs": {
|
||||
"url": "https://git.workroot.in/WorkRoot/WRNexusJS/issues"
|
||||
},
|
||||
"keywords": [
|
||||
"wrnexus",
|
||||
"bun",
|
||||
"typescript",
|
||||
"helpers"
|
||||
],
|
||||
"sideEffects": false,
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
"engines": {
|
||||
"bun": ">=1.3.0"
|
||||
},
|
||||
"publishConfig": {
|
||||
"registry": "https://registry.npmjs.org/",
|
||||
"access": "restricted"
|
||||
},
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"import": "./dist/index.js"
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@wrnexus/core": "^0.8.8"
|
||||
},
|
||||
"files": [
|
||||
"dist",
|
||||
"README.md"
|
||||
]
|
||||
}
|
||||
@@ -22,7 +22,7 @@ const i18n = resolveI18n(loadLocales("app/locales", { strict: true }), {
|
||||
default: "en",
|
||||
locales: ["en", "mr", "hi"],
|
||||
fallbacks: { "mr-IN": ["mr", "en"] },
|
||||
cookie: { name: "wire-lang", sameSite: "Lax", secure: true },
|
||||
cookie: { name: "wrn-lang", sameSite: "Lax", secure: true },
|
||||
});
|
||||
|
||||
const lang = resolveLang(i18n, cookieValue, request.headers.get("accept-language"));
|
||||
@@ -57,7 +57,7 @@ Enable `i18nPlugin()` to use:
|
||||
- `<LanguageSwitcher />`
|
||||
- `<LocaleStatus />`
|
||||
|
||||
`LanguageSwitcher` renders a native `select[data-wire-lang]`. The packaged runtime validates the
|
||||
`LanguageSwitcher` renders a native `select[data-wrn-lang]`. The packaged runtime validates the
|
||||
selection against the configured locales, writes the configured language cookie, updates the
|
||||
document `lang`/`dir` attributes, emits `wrnexus:language-change`, and reloads so the next SSR
|
||||
request uses the same cookie. No application-owned browser script is required.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@wrnexus/i18n",
|
||||
"version": "0.8.8",
|
||||
"version": "0.8.9",
|
||||
"type": "module",
|
||||
"description": "Locale loading, fallback resolution, SSR/browser translations, formatters, and WRNexusJS language components.",
|
||||
"license": "MIT",
|
||||
@@ -42,9 +42,9 @@
|
||||
"./components/*": "./components/*"
|
||||
},
|
||||
"dependencies": {
|
||||
"@wrnexus/core": "^0.8.8",
|
||||
"@wrnexus/core": "^0.8.9",
|
||||
"@wrnexus/plugin": "^0.8.8",
|
||||
"@wrnexus/ui": "^0.8.8"
|
||||
"@wrnexus/ui": "^0.8.12"
|
||||
},
|
||||
"wrnexus": {
|
||||
"plugin": {
|
||||
|
||||
@@ -1,191 +0,0 @@
|
||||
# @wrnexus/jwt
|
||||
|
||||
> Dependency-free JSON Web Tokens (HS256) via Web Crypto, plus a bearer-token auth middleware for WrNexus.
|
||||
|
||||
Part of the **WrNexus** framework — an SSR-first, Bun-native full-stack web framework.
|
||||
|
||||
## Overview
|
||||
|
||||
`@wrnexus/jwt` signs and verifies stateless JSON Web Tokens using the **HS256**
|
||||
(HMAC-SHA-256) algorithm. It has no runtime dependencies — signing and
|
||||
verification are implemented directly on the standard **Web Crypto** API
|
||||
(`crypto.subtle`), which Bun provides natively. It runs server-side and pairs
|
||||
with the session-based auth in `@wrnexus/core`, giving you a stateless option
|
||||
for API and mobile clients. Reach for it when you need bearer-token auth rather
|
||||
than cookie sessions.
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
bun add @wrnexus/jwt
|
||||
```
|
||||
|
||||
> Private package — the machine must be authenticated to the `wrnexus` npm org
|
||||
> (a read token in `~/.npmrc`). Requires **Bun** (Node is not supported).
|
||||
|
||||
## API
|
||||
|
||||
Single entry point (`@wrnexus/jwt`). All functions are async and return Promises.
|
||||
|
||||
| Export | Kind | Description |
|
||||
| --------------------------------------- | --------- | --------------------------------------------------------------- |
|
||||
| `signJwt(payload, secret, options?)` | function | Sign claims into an HS256 token string. |
|
||||
| `verifyJwt<T>(token, secret, options?)` | function | Verify a token and return its claims, or throw. |
|
||||
| `jwtAuth(options)` | function | Middleware that verifies a bearer JWT and sets `ctx.user`. |
|
||||
| `JwtError` | class | Error thrown on any signature/payload/expiry failure. |
|
||||
| `JwtClaims` | interface | Claims shape (`sub`, `iat`, `exp`, `nbf`, plus arbitrary keys). |
|
||||
| `SignOptions` | interface | Options for `signJwt`. |
|
||||
| `JwtAuthOptions` | interface | Options for `jwtAuth`. |
|
||||
|
||||
### `signJwt(payload, secret, options?)`
|
||||
|
||||
```ts
|
||||
function signJwt(payload: JwtClaims, secret: string, options?: SignOptions): Promise<string>;
|
||||
```
|
||||
|
||||
Signs `payload` with `secret` using HS256 and returns the encoded token
|
||||
(`header.body.signature`). An `iat` (issued-at) claim is always added.
|
||||
|
||||
`SignOptions`:
|
||||
|
||||
- `expiresIn?: number` — seconds until expiry; sets the `exp` claim.
|
||||
- `now?: number` — override the issued-at time (seconds), useful for testing.
|
||||
|
||||
### `verifyJwt<T>(token, secret, options?)`
|
||||
|
||||
```ts
|
||||
function verifyJwt<T extends JwtClaims = JwtClaims>(
|
||||
token: string,
|
||||
secret: string,
|
||||
options?: { now?: number },
|
||||
): Promise<T>;
|
||||
```
|
||||
|
||||
Verifies the HS256 signature and returns the decoded claims typed as `T`.
|
||||
Throws `JwtError` when the token is malformed, the signature is invalid, the
|
||||
payload is not valid JSON, the token is expired (`exp`), or not yet valid
|
||||
(`nbf`). Pass `now` (seconds) to override the reference time for the `exp`/`nbf`
|
||||
checks.
|
||||
|
||||
### `jwtAuth(options)`
|
||||
|
||||
```ts
|
||||
function jwtAuth(options: JwtAuthOptions): Middleware;
|
||||
```
|
||||
|
||||
Returns a WrNexus `Middleware` that reads a token, verifies it, and assigns the
|
||||
claims to `ctx.user`.
|
||||
|
||||
`JwtAuthOptions`:
|
||||
|
||||
- `secret: string` — the HMAC secret used to verify tokens.
|
||||
- `getToken?: (ctx: Context) => string | undefined` — how to extract the token.
|
||||
Defaults to reading `Authorization: Bearer <token>`.
|
||||
- `required?: boolean` — when `true` (default), a missing or invalid token
|
||||
responds with `401 { ok: false, error: "Unauthorized" }`. When `false`,
|
||||
requests pass through and `ctx.user` is only set if a valid token is present.
|
||||
|
||||
## Usage
|
||||
|
||||
```ts
|
||||
import { signJwt, verifyJwt, jwtAuth, JwtError } from "@wrnexus/jwt";
|
||||
|
||||
const secret = process.env.JWT_SECRET!;
|
||||
|
||||
// Sign a token that expires in one hour
|
||||
const token = await signJwt({ sub: user.id, role: "admin" }, secret, {
|
||||
expiresIn: 3600,
|
||||
});
|
||||
|
||||
// Verify it later
|
||||
try {
|
||||
const claims = await verifyJwt<{ sub: string; role: string }>(token, secret);
|
||||
console.log(claims.sub, claims.role);
|
||||
} catch (err) {
|
||||
if (err instanceof JwtError) {
|
||||
// invalid signature, expired, malformed, etc.
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Protecting routes with the middleware:
|
||||
|
||||
```ts
|
||||
import { jwtAuth } from "@wrnexus/jwt";
|
||||
|
||||
// Require a valid bearer token; ctx.user holds the verified claims
|
||||
app.use(jwtAuth({ secret: process.env.JWT_SECRET! }));
|
||||
|
||||
// Optional auth — populate ctx.user when present, but don't 401
|
||||
app.use(jwtAuth({ secret: process.env.JWT_SECRET!, required: false }));
|
||||
```
|
||||
|
||||
## Requirements / Notes
|
||||
|
||||
- **Bun-only.** Uses the standard Web Crypto API (`crypto.subtle.importKey`,
|
||||
`sign`, `verify`) plus `btoa`/`atob` and `TextEncoder`/`TextDecoder` — all
|
||||
provided by Bun. No third-party crypto dependency.
|
||||
- **Algorithm:** HS256 (HMAC with SHA-256) only. Asymmetric algorithms (RS/ES)
|
||||
are not supported.
|
||||
- Integrates with [`@wrnexus/core`](../core) for `Context`, `Middleware`, and
|
||||
`ctx.user`; it complements the framework's cookie/session auth with a
|
||||
stateless bearer-token flow for API and mobile clients.
|
||||
|
||||
## Access, refresh, scope, and cookie helpers
|
||||
|
||||
```ts
|
||||
import {
|
||||
createAccessToken,
|
||||
createRefreshToken,
|
||||
verifyAccessToken,
|
||||
verifyRefreshToken,
|
||||
extractBearerToken,
|
||||
requireScopes,
|
||||
jwtCookie,
|
||||
} from "@wrnexus/jwt";
|
||||
```
|
||||
|
||||
The helpers add explicit `type: "access" | "refresh"` claims, scope checks, refresh-token family metadata, no-store token responses, and secure cookie defaults. `__Host-` cookies are rejected unless they use `Path=/` and `Secure`; `SameSite=None` is rejected without `Secure`.
|
||||
|
||||
## 0.8 helper kit
|
||||
|
||||
```ts
|
||||
import {
|
||||
createTokenPair,
|
||||
verifyAccessToken,
|
||||
verifyRefreshToken,
|
||||
extractBearerToken,
|
||||
readJwtCookie,
|
||||
jwtCookie,
|
||||
clearJwtCookie,
|
||||
requireScopes,
|
||||
} from "@wrnexus/jwt";
|
||||
|
||||
const pair = await createTokenPair(user.id, {
|
||||
accessSecret: process.env.JWT_ACCESS_SECRET!,
|
||||
refreshSecret: process.env.JWT_REFRESH_SECRET!,
|
||||
scopes: ["profile:read"],
|
||||
family: sessionFamily,
|
||||
});
|
||||
```
|
||||
|
||||
The helper kit validates `__Host-` cookie invariants, cookie names and paths, `SameSite=None` security, typed access/refresh token types, scope requirements, and no-store token responses.
|
||||
In addition to local HS256 secrets/keyrings, the package verifies standards-based
|
||||
RS256 tokens through bounded remote JWKS caches:
|
||||
|
||||
```ts
|
||||
import { createRemoteJwks, verifyJwtWithJwks } from "@wrnexus/jwt";
|
||||
|
||||
const jwks = createRemoteJwks("https://issuer.example/.well-known/jwks.json");
|
||||
const claims = await verifyJwtWithJwks(token, jwks, {
|
||||
issuer: "https://issuer.example",
|
||||
audience: "my-api",
|
||||
maxAge: 300,
|
||||
});
|
||||
```
|
||||
|
||||
JWKS URLs must use HTTPS. Responses have key-count/byte limits, accept only
|
||||
RS256 signing RSA keys, deduplicate concurrent refreshes, cache imported public
|
||||
keys, and force an immediate refresh for an unknown `kid` so issuer rotation
|
||||
does not wait for cache expiry. Never use decoded-but-unverified claims for an
|
||||
authorization decision.
|
||||
@@ -1,46 +0,0 @@
|
||||
{
|
||||
"name": "@wrnexus/jwt",
|
||||
"version": "0.8.8",
|
||||
"type": "module",
|
||||
"description": "HS256 JSON Web Tokens, key rotation, access/refresh helpers, scopes, cookies, and auth middleware.",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://git.workroot.in/WorkRoot/WRNexusJS.git",
|
||||
"directory": "packages/jwt"
|
||||
},
|
||||
"homepage": "https://wrnexusjs.dev/packages/jwt",
|
||||
"bugs": {
|
||||
"url": "https://git.workroot.in/WorkRoot/WRNexusJS/issues"
|
||||
},
|
||||
"keywords": [
|
||||
"wrnexus",
|
||||
"bun",
|
||||
"typescript",
|
||||
"jwt"
|
||||
],
|
||||
"sideEffects": false,
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
"engines": {
|
||||
"bun": ">=1.3.0"
|
||||
},
|
||||
"publishConfig": {
|
||||
"registry": "https://registry.npmjs.org/",
|
||||
"access": "restricted"
|
||||
},
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"import": "./dist/index.js"
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@wrnexus/core": "^0.8.8"
|
||||
},
|
||||
"files": [
|
||||
"dist",
|
||||
"README.md"
|
||||
]
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
# @wrnexus/mobile
|
||||
|
||||
> SSR-safe access to Capacitor plugins from WRNexusJS browser code.
|
||||
|
||||
## Overview
|
||||
|
||||
`@wrnexus/mobile` keeps optional native imports out of server rendering while giving
|
||||
browser-owned modules one consistent registry for Capacitor plugins. During SSR,
|
||||
`mobile.isNative()` is `false` and `mobile.platform()` is `"web"`.
|
||||
|
||||
## Installation
|
||||
|
||||
Install a plugin through the WRNexusJS CLI so the web and native projects stay aligned:
|
||||
|
||||
```bash
|
||||
wrnexus mobile add @capacitor/camera @capacitor/haptics
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### Register and invoke a Capacitor plugin
|
||||
|
||||
Import Capacitor packages only from browser-owned code, never from API routes or SSR
|
||||
helpers.
|
||||
|
||||
```ts
|
||||
import { Camera, CameraResultType } from "@capacitor/camera";
|
||||
import { mobile } from "@wrnexus/mobile";
|
||||
|
||||
mobile.registerPlugin("Camera", Camera);
|
||||
|
||||
export async function takePhoto() {
|
||||
if (!mobile.isNative()) return null;
|
||||
return mobile.invoke("Camera", "getPhoto", {
|
||||
quality: 85,
|
||||
resultType: CameraResultType.Uri,
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
### Provide a browser fallback
|
||||
|
||||
`whenNative` runs the first callback only in a Capacitor WebView and can return a
|
||||
web/SSR-safe fallback everywhere else.
|
||||
|
||||
```ts
|
||||
import { Haptics, ImpactStyle } from "@capacitor/haptics";
|
||||
import { mobile } from "@wrnexus/mobile";
|
||||
|
||||
mobile.registerPlugin("Haptics", Haptics);
|
||||
|
||||
export const confirmAction = () =>
|
||||
mobile.whenNative(
|
||||
() => mobile.invoke("Haptics", "impact", { style: ImpactStyle.Medium }),
|
||||
() => navigator.vibrate?.(30),
|
||||
);
|
||||
```
|
||||
|
||||
### Read an optional plugin without throwing
|
||||
|
||||
```ts
|
||||
import type { NetworkPlugin } from "@capacitor/network";
|
||||
import { mobile } from "@wrnexus/mobile";
|
||||
|
||||
const network = mobile.plugin<NetworkPlugin>("Network");
|
||||
const status = network ? await network.getStatus() : { connected: true, connectionType: "unknown" };
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
- `registerPlugin(name, instance)` registers a browser-imported plugin.
|
||||
- `plugin(name)` returns a plugin or `undefined`; `requirePlugin(name)` throws when absent.
|
||||
- `invoke(plugin, method, options?)` calls a registered method and returns its result.
|
||||
- `whenNative(native, fallback?)` selects native behavior without breaking SSR.
|
||||
- `isNative()` and `platform()` report the current Capacitor environment.
|
||||
|
||||
Unavailable required plugins throw `MobileUnavailableError` with an actionable message.
|
||||
|
||||
The package also provides portable application-facing primitives:
|
||||
|
||||
- `listenDeepLinks` normalizes initial and live links with an allowed-scheme list.
|
||||
- `PushNotifications` performs permission gating and validates registrations.
|
||||
- `SecureStorage` namespaces and validates keys over an application-supplied encrypted
|
||||
Keychain/Keystore adapter; it does not mislabel browser `localStorage` as secure.
|
||||
- `OfflineQueue` persists bounded sync batches through a pluggable durable store.
|
||||
|
||||
## Requirements / Notes
|
||||
|
||||
- Capacitor plugin imports must remain in browser-owned modules.
|
||||
- `@wrnexus/mobile` re-exports `native` from `@wrnexus/native` for applications that
|
||||
prefer the higher-level cross-platform capability API.
|
||||
@@ -1,46 +0,0 @@
|
||||
{
|
||||
"name": "@wrnexus/mobile",
|
||||
"version": "0.8.8",
|
||||
"type": "module",
|
||||
"description": "@wrnexus/mobile — part of the WrNexus framework.",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://git.workroot.in/WorkRoot/WRNexusJS.git",
|
||||
"directory": "packages/mobile"
|
||||
},
|
||||
"homepage": "https://wrnexusjs.dev/packages/mobile",
|
||||
"bugs": {
|
||||
"url": "https://git.workroot.in/WorkRoot/WRNexusJS/issues"
|
||||
},
|
||||
"keywords": [
|
||||
"wrnexus",
|
||||
"bun",
|
||||
"typescript",
|
||||
"mobile"
|
||||
],
|
||||
"sideEffects": false,
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
"engines": {
|
||||
"bun": ">=1.3.0"
|
||||
},
|
||||
"publishConfig": {
|
||||
"registry": "https://registry.npmjs.org/",
|
||||
"access": "restricted"
|
||||
},
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"import": "./dist/index.js"
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@wrnexus/native": "^0.8.8"
|
||||
},
|
||||
"files": [
|
||||
"dist",
|
||||
"README.md"
|
||||
]
|
||||
}
|
||||
@@ -1,88 +0,0 @@
|
||||
# @wrnexus/native
|
||||
|
||||
> Cross-platform capabilities for browsers, Capacitor WebViews, and compiled native apps.
|
||||
|
||||
## Overview
|
||||
|
||||
`@wrnexus/native` exposes capabilities by name so application code can ask what the
|
||||
current platform supports before presenting an action. Browser capabilities use Web
|
||||
APIs; mobile capabilities use installed Capacitor plugins. `platform()` returns
|
||||
`"server"` during SSR, `"browser"` on the web, and the Capacitor platform in a native
|
||||
WebView.
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
bun add @wrnexus/native
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### Share a page when the platform supports it
|
||||
|
||||
```ts
|
||||
import { native } from "@wrnexus/native";
|
||||
|
||||
export async function shareCurrentPage() {
|
||||
if (!native.supports("share")) return false;
|
||||
await native.run("share", {
|
||||
title: document.title,
|
||||
url: location.href,
|
||||
});
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
### Register an application-specific capability
|
||||
|
||||
`register` returns an unregister function, which is useful for tests and temporary
|
||||
feature modules.
|
||||
|
||||
```ts
|
||||
import { native } from "@wrnexus/native";
|
||||
|
||||
const unregister = native.register("orders.scan", {
|
||||
browser: {
|
||||
supported: () => typeof window !== "undefined",
|
||||
run: async ({ orderId }: { orderId: string }) => {
|
||||
const code = window.prompt(`Scan code for order ${orderId}`);
|
||||
return { code };
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const result = await native.run<{ code: string | null }>("orders.scan", { orderId: "ord_42" });
|
||||
unregister();
|
||||
```
|
||||
|
||||
### Target browser or mobile behavior explicitly
|
||||
|
||||
```ts
|
||||
import { native } from "@wrnexus/native";
|
||||
|
||||
const canUseMobileCamera = native.supports("camera", "mobile");
|
||||
const position = await native.run(
|
||||
"geolocation",
|
||||
{ enableHighAccuracy: true },
|
||||
{ target: "browser" },
|
||||
);
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
- `supports(name, target?)` checks availability without running the capability.
|
||||
- `run(name, options?, runOptions?)` executes it or rejects with `NativeUnavailableError`.
|
||||
- `register(name, capability)` adds or overrides a capability and returns cleanup.
|
||||
- `registered()` lists capability names; `clearRegistry()` resets the registry.
|
||||
- `isMobile()` and `platform()` report the current target safely during SSR.
|
||||
|
||||
Built-ins include `camera`, `clipboard.write`, `share`, `geolocation`, `network`,
|
||||
`haptics`, storage, filesystem, notifications, and device information.
|
||||
|
||||
`defineNativeManifest` declares required capabilities and typed permissions, while
|
||||
`PermissionManager` normalizes permission query/request flows across platform adapters.
|
||||
|
||||
## Requirements / Notes
|
||||
|
||||
Use `supports()` before showing optional controls. Mobile capabilities require their
|
||||
matching Capacitor plugins to be installed and registered by the application.
|
||||
@@ -1,51 +0,0 @@
|
||||
{
|
||||
"name": "@wrnexus/native",
|
||||
"version": "0.8.8",
|
||||
"type": "module",
|
||||
"description": "@wrnexus/native — part of the WrNexus framework.",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://git.workroot.in/WorkRoot/WRNexusJS.git",
|
||||
"directory": "packages/native"
|
||||
},
|
||||
"homepage": "https://wrnexusjs.dev/packages/native",
|
||||
"bugs": {
|
||||
"url": "https://git.workroot.in/WorkRoot/WRNexusJS/issues"
|
||||
},
|
||||
"keywords": [
|
||||
"wrnexus",
|
||||
"bun",
|
||||
"typescript",
|
||||
"native"
|
||||
],
|
||||
"sideEffects": false,
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
"engines": {
|
||||
"bun": ">=1.3.0"
|
||||
},
|
||||
"publishConfig": {
|
||||
"registry": "https://registry.npmjs.org/",
|
||||
"access": "restricted"
|
||||
},
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"import": "./dist/index.js"
|
||||
},
|
||||
"./browser": {
|
||||
"types": "./dist/browser.d.ts",
|
||||
"import": "./dist/browser.js"
|
||||
},
|
||||
"./mobile": {
|
||||
"types": "./dist/mobile.d.ts",
|
||||
"import": "./dist/mobile.js"
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
"dist",
|
||||
"README.md"
|
||||
]
|
||||
}
|
||||
@@ -1,217 +0,0 @@
|
||||
# @wrnexus/oauth
|
||||
|
||||
> Dependency-free OAuth 2.0 sign-in for any provider, with PKCE and presets for Google, GitHub, and Discord.
|
||||
|
||||
Part of the **WrNexus** framework — an SSR-first, Bun-native full-stack web framework.
|
||||
|
||||
## Overview
|
||||
|
||||
`@wrnexus/oauth` implements the OAuth 2.0 Authorization Code flow (with PKCE) for
|
||||
server-side sign-in. It ships ready-made provider presets and a `defineProvider`
|
||||
helper for custom providers, then gives you two flow functions — `startAuth`
|
||||
(build the redirect) and `completeAuth` (exchange the code and fetch the user's
|
||||
profile). It has no runtime dependencies: it uses the platform `fetch` and
|
||||
WebCrypto only. Pairs naturally with `@wrnexus/core`'s `logIn` to establish a
|
||||
session once you have a normalized profile.
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
bun add @wrnexus/oauth
|
||||
```
|
||||
|
||||
> Private package — the machine must be authenticated to the `wrnexus` npm org
|
||||
> (a read token in `~/.npmrc`). Requires **Bun** (Node is not supported).
|
||||
|
||||
## API
|
||||
|
||||
### Providers
|
||||
|
||||
Each preset takes `ProviderCredentials` and returns an `OAuthProvider`.
|
||||
|
||||
```ts
|
||||
interface ProviderCredentials {
|
||||
clientId: string;
|
||||
clientSecret: string;
|
||||
scopes?: string[]; // override the preset's default scopes
|
||||
}
|
||||
```
|
||||
|
||||
| Export | Default scopes | Notes |
|
||||
| ------------------------ | ---------------------------- | ------------------------------------------------------------------ |
|
||||
| `google(creds)` | `openid`, `email`, `profile` | Sets `access_type: offline` for refresh tokens. |
|
||||
| `github(creds)` | `read:user`, `user:email` | Maps `name` (falls back to `login`) and `avatar_url`. |
|
||||
| `discord(creds)` | `identify`, `email` | Builds the avatar CDN URL from the user id + hash. |
|
||||
| `defineProvider(config)` | — | Pass a full `OAuthProvider` to define a custom OAuth 2.0 provider. |
|
||||
|
||||
An `OAuthProvider` describes the endpoints, scopes, credentials, optional extra
|
||||
authorize params, and a `mapProfile` normalizer:
|
||||
|
||||
```ts
|
||||
interface OAuthProvider {
|
||||
name: string;
|
||||
authorizeUrl: string;
|
||||
tokenUrl: string;
|
||||
userInfoUrl: string;
|
||||
scopes: string[];
|
||||
clientId: string;
|
||||
clientSecret: string;
|
||||
authorizeParams?: Record<string, string>; // e.g. access_type, prompt
|
||||
mapProfile: (raw: Record<string, unknown>) => OAuthProfile;
|
||||
}
|
||||
```
|
||||
|
||||
### Flow
|
||||
|
||||
#### `startAuth(provider, options): Promise<StartAuthResult>`
|
||||
|
||||
Builds the authorize redirect URL with a generated PKCE challenge and CSRF
|
||||
`state`. Store the returned `state` and `verifier` (session/cookie), then 302 the
|
||||
user to `url`.
|
||||
|
||||
```ts
|
||||
interface StartAuthOptions {
|
||||
redirectUri: string;
|
||||
state?: string; // reuse a state instead of generating one
|
||||
params?: Record<string, string>; // extra authorize params, merged last
|
||||
}
|
||||
|
||||
interface StartAuthResult {
|
||||
url: string; // authorize URL to redirect to
|
||||
state: string; // CSRF state — verify on callback
|
||||
verifier: string; // PKCE code verifier — pass to completeAuth
|
||||
}
|
||||
```
|
||||
|
||||
#### `completeAuth(provider, options): Promise<{ tokens, profile }>`
|
||||
|
||||
On the callback: exchanges the authorization `code` for tokens, then fetches and
|
||||
normalizes the user profile. Convenience wrapper over `exchangeCode` +
|
||||
`fetchProfile`.
|
||||
|
||||
```ts
|
||||
interface CompleteAuthOptions {
|
||||
code: string;
|
||||
redirectUri: string;
|
||||
verifier?: string; // the PKCE verifier from startAuth
|
||||
fetch?: typeof fetch; // inject a fetch implementation (tests)
|
||||
}
|
||||
```
|
||||
|
||||
#### Lower-level helpers
|
||||
|
||||
| Export | Signature | Purpose |
|
||||
| ---------------------------------------- | ------------------------- | --------------------------------------------------------------- |
|
||||
| `exchangeCode(provider, options)` | `→ Promise<OAuthTokens>` | Exchange an authorization code for tokens. |
|
||||
| `fetchProfile(provider, tokens, fetch?)` | `→ Promise<OAuthProfile>` | Fetch + normalize the user's profile. |
|
||||
| `randomToken(bytes?)` | `→ string` | Random URL-safe token (default 32 bytes) for `state`/verifiers. |
|
||||
|
||||
### Types
|
||||
|
||||
```ts
|
||||
interface OAuthTokens {
|
||||
access_token: string;
|
||||
token_type?: string;
|
||||
refresh_token?: string;
|
||||
expires_in?: number;
|
||||
id_token?: string;
|
||||
scope?: string;
|
||||
}
|
||||
|
||||
interface OAuthProfile {
|
||||
id: string;
|
||||
email?: string;
|
||||
name?: string;
|
||||
avatar?: string;
|
||||
raw: Record<string, unknown>;
|
||||
}
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```ts
|
||||
import { google, startAuth, completeAuth } from "@wrnexus/oauth";
|
||||
import { logIn } from "@wrnexus/core";
|
||||
|
||||
const provider = google({
|
||||
clientId: process.env.GOOGLE_CLIENT_ID!,
|
||||
clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
|
||||
});
|
||||
|
||||
const redirectUri = "https://example.com/auth/callback";
|
||||
|
||||
// 1. Kick off sign-in: redirect the user to the provider.
|
||||
async function beginLogin(ctx) {
|
||||
const { url, state, verifier } = await startAuth(provider, { redirectUri });
|
||||
// Persist state + verifier in the session, then redirect.
|
||||
ctx.session.set("oauth_state", state);
|
||||
ctx.session.set("oauth_verifier", verifier);
|
||||
return Response.redirect(url, 302);
|
||||
}
|
||||
|
||||
// 2. Handle the callback.
|
||||
async function handleCallback(ctx, code: string, state: string) {
|
||||
if (state !== ctx.session.get("oauth_state")) throw new Error("bad state");
|
||||
|
||||
const { profile } = await completeAuth(provider, {
|
||||
code,
|
||||
redirectUri,
|
||||
verifier: ctx.session.get("oauth_verifier"),
|
||||
});
|
||||
|
||||
logIn(ctx, { id: profile.id, email: profile.email });
|
||||
}
|
||||
```
|
||||
|
||||
Custom provider with `defineProvider`:
|
||||
|
||||
```ts
|
||||
import { defineProvider, startAuth } from "@wrnexus/oauth";
|
||||
|
||||
const gitlab = defineProvider({
|
||||
name: "gitlab",
|
||||
authorizeUrl: "https://gitlab.com/oauth/authorize",
|
||||
tokenUrl: "https://gitlab.com/oauth/token",
|
||||
userInfoUrl: "https://gitlab.com/api/v4/user",
|
||||
scopes: ["read_user"],
|
||||
clientId: process.env.GITLAB_CLIENT_ID!,
|
||||
clientSecret: process.env.GITLAB_CLIENT_SECRET!,
|
||||
mapProfile: (raw) => ({
|
||||
id: String(raw.id),
|
||||
email: raw.email as string | undefined,
|
||||
name: raw.name as string | undefined,
|
||||
avatar: raw.avatar_url as string | undefined,
|
||||
raw,
|
||||
}),
|
||||
});
|
||||
```
|
||||
|
||||
## Requirements / Notes
|
||||
|
||||
- **Bun-only.** Relies on the global `fetch` and WebCrypto (`crypto.getRandomValues`,
|
||||
`crypto.subtle.digest`) — no other runtime dependencies.
|
||||
- The flow is stateless by design: you are responsible for storing `state` and
|
||||
`verifier` between `startAuth` and `completeAuth` (session or signed cookie).
|
||||
- Pairs with [`@wrnexus/core`](../core) — feed the normalized `OAuthProfile` into
|
||||
`logIn` to establish a session.
|
||||
OIDC integrations can combine strict discovery with the rotating JWKS verifier:
|
||||
|
||||
```ts
|
||||
import { createRemoteJwks } from "@wrnexus/jwt";
|
||||
import { discoverOidc, verifyOidcIdToken } from "@wrnexus/oauth";
|
||||
|
||||
const metadata = await discoverOidc("https://issuer.example");
|
||||
const jwks = createRemoteJwks(metadata.jwks_uri);
|
||||
const claims = await verifyOidcIdToken(idToken, {
|
||||
issuer: metadata.issuer,
|
||||
clientId: "client-id",
|
||||
jwks,
|
||||
nonce: expectedNonce,
|
||||
accessToken,
|
||||
});
|
||||
```
|
||||
|
||||
Discovery requires an exact normalized issuer and HTTPS endpoints without URL
|
||||
credentials/fragments. ID-token verification checks the RS256 signature,
|
||||
expiry/not-before, issuer, audience, required OIDC claims, nonce, multi-audience
|
||||
`azp`, optional token age, and optional `at_hash` binding.
|
||||
@@ -1,46 +0,0 @@
|
||||
{
|
||||
"name": "@wrnexus/oauth",
|
||||
"version": "0.8.8",
|
||||
"type": "module",
|
||||
"description": "@wrnexus/oauth — part of the WrNexus framework.",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://git.workroot.in/WorkRoot/WRNexusJS.git",
|
||||
"directory": "packages/oauth"
|
||||
},
|
||||
"homepage": "https://wrnexusjs.dev/packages/oauth",
|
||||
"bugs": {
|
||||
"url": "https://git.workroot.in/WorkRoot/WRNexusJS/issues"
|
||||
},
|
||||
"keywords": [
|
||||
"wrnexus",
|
||||
"bun",
|
||||
"typescript",
|
||||
"oauth"
|
||||
],
|
||||
"sideEffects": false,
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
"engines": {
|
||||
"bun": ">=1.3.0"
|
||||
},
|
||||
"publishConfig": {
|
||||
"registry": "https://registry.npmjs.org/",
|
||||
"access": "restricted"
|
||||
},
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"import": "./dist/index.js"
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@wrnexus/jwt": "^0.8.8"
|
||||
},
|
||||
"files": [
|
||||
"dist",
|
||||
"README.md"
|
||||
]
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
# @wrnexus/plugin
|
||||
|
||||
## Least-privilege package permissions
|
||||
|
||||
Package manifests declare every framework capability they register:
|
||||
|
||||
```json
|
||||
{
|
||||
"wrnexus": {
|
||||
"permissions": ["routes", "migrations"],
|
||||
"routes": [{ "kind": "api", "path": "/api/example", "entry": "./route.ts" }]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Applications can enable fail-closed grants:
|
||||
|
||||
```ts
|
||||
export default {
|
||||
pluginPermissions: {
|
||||
enforce: true,
|
||||
grants: { "example-plugin": ["routes"] },
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
Discovery rejects used-but-undeclared capabilities with
|
||||
`WRN-PLUGIN-PERMISSION-UNDECLARED` and ungranted capabilities with
|
||||
`WRN-PLUGIN-PERMISSION-DENIED`. Permissions cover components, browser runtime,
|
||||
assets, styles, routes, middleware, migrations, config, transforms,
|
||||
diagnostics/tooling, and server/build hooks.
|
||||
|
||||
## Compatibility matrices
|
||||
|
||||
Manifests can add `compatibility: { bunMin: "1.3.0", os: ["linux",
|
||||
"darwin"] }` alongside `runtimes` and `requires`. Use
|
||||
`testPluginCompatibility(manifest, targets)` in a package test to exercise the
|
||||
complete support matrix. Runtime discovery enforces the same Bun minimum, OS,
|
||||
runtime, and capability declarations used by the test kit.
|
||||
|
||||
Deterministic WRNexusJS plugin contracts for configuration, AST/code transforms,
|
||||
diagnostics, development servers, production builds, and DevToolbar extensions.
|
||||
|
||||
Use `definePlugin()` and declare `enforce`, `before`, or `after` when ordering matters.
|
||||
Duplicate names and dependency cycles are rejected.
|
||||
|
||||
## Complete lifecycle and contributions
|
||||
|
||||
Plugins may implement `setup`, `configure`, `configResolved`, `transformAst`,
|
||||
`transformCode`, `diagnostics`, `routes`, `configureServer`, `buildStart`,
|
||||
`buildEnd`, `render`, `deploy`, `shutdown`, and `hmrUpdate`. The runner preserves
|
||||
resolved plugin order for every hook and executes `setup` exactly once.
|
||||
|
||||
In addition to components, routes, middleware, assets, styles, runtimes, and
|
||||
migrations, plugins can contribute `directives`, `cliCommands`,
|
||||
`virtualModules`, `deploymentAdapters`, `configSchemas`, `documentation`, and
|
||||
`typeDefinitions`. Names are collision checked. Configuration schemas run after
|
||||
configuration resolution, CLI commands are callable as normal `wrnexus`
|
||||
commands, directives participate in AST transformation, and production builds
|
||||
materialize virtual modules and invoke matching contributed adapters.
|
||||
@@ -1,58 +0,0 @@
|
||||
{
|
||||
"name": "@wrnexus/plugin",
|
||||
"version": "0.8.8",
|
||||
"type": "module",
|
||||
"description": "@wrnexus/plugin — part of the WrNexus framework.",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://git.workroot.in/WorkRoot/WRNexusJS.git",
|
||||
"directory": "packages/plugin"
|
||||
},
|
||||
"homepage": "https://wrnexusjs.dev/packages/plugin",
|
||||
"bugs": {
|
||||
"url": "https://git.workroot.in/WorkRoot/WRNexusJS/issues"
|
||||
},
|
||||
"keywords": [
|
||||
"wrnexus",
|
||||
"bun",
|
||||
"typescript",
|
||||
"plugin"
|
||||
],
|
||||
"sideEffects": false,
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
"engines": {
|
||||
"bun": ">=1.3.0"
|
||||
},
|
||||
"publishConfig": {
|
||||
"registry": "https://registry.npmjs.org/",
|
||||
"access": "restricted"
|
||||
},
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"import": "./dist/index.js"
|
||||
},
|
||||
"./types": {
|
||||
"types": "./dist/types.d.ts",
|
||||
"import": "./dist/types.js"
|
||||
},
|
||||
"./manifest": {
|
||||
"types": "./dist/manifest.d.ts",
|
||||
"import": "./dist/manifest.js"
|
||||
},
|
||||
"./discovery": {
|
||||
"types": "./dist/discovery.d.ts",
|
||||
"import": "./dist/discovery.js"
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@wrnexus/syntax": "^0.8.8"
|
||||
},
|
||||
"files": [
|
||||
"dist",
|
||||
"README.md"
|
||||
]
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@wrnexus/pubsub",
|
||||
"version": "0.8.8",
|
||||
"version": "0.8.9",
|
||||
"type": "module",
|
||||
"description": "@wrnexus/pubsub — part of the WrNexus framework.",
|
||||
"license": "MIT",
|
||||
@@ -45,8 +45,8 @@
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@wrnexus/core": "^0.8.8",
|
||||
"@wrnexus/rpc": "^0.8.8"
|
||||
"@wrnexus/core": "^0.8.9",
|
||||
"@wrnexus/rpc": "^0.8.9"
|
||||
},
|
||||
"files": [
|
||||
"dist",
|
||||
|
||||
@@ -1,211 +0,0 @@
|
||||
# @wrnexus/queue
|
||||
|
||||
> A background job queue with delays, retries + exponential backoff, recurring jobs, and concurrent workers.
|
||||
|
||||
Part of the **WrNexus** framework — an SSR-first, Bun-native full-stack web framework.
|
||||
|
||||
## Overview
|
||||
|
||||
`@wrnexus/queue` is a server-side in-process job queue. You register named
|
||||
workers, enqueue jobs (optionally delayed or recurring), and let the queue poll
|
||||
and run them on a timer — with per-job retry limits and doubling backoff between
|
||||
attempts. The default store lives in memory; the design allows a pluggable driver
|
||||
to back it with Redis/SQL for durability across restarts. Reach for it when you
|
||||
need to defer work (emails, webhooks, cleanup) off the request path without a
|
||||
heavyweight external broker. Tests can drive it deterministically via `drain()`.
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
bun add @wrnexus/queue
|
||||
```
|
||||
|
||||
> Private package — the machine must be authenticated to the `wrnexus` npm org
|
||||
> (a read token in `~/.npmrc`). Requires **Bun** (Node is not supported).
|
||||
|
||||
## API
|
||||
|
||||
The package exports a single factory plus its supporting types.
|
||||
|
||||
### `createQueue(options?): Queue`
|
||||
|
||||
Creates a new queue instance.
|
||||
|
||||
```ts
|
||||
function createQueue(options?: QueueOptions): Queue;
|
||||
```
|
||||
|
||||
#### `QueueOptions`
|
||||
|
||||
| Option | Type | Default | Description |
|
||||
| ------------- | ------------------------------------ | ---------- | -------------------------------------------------------- |
|
||||
| `maxAttempts` | `number` | `3` | Default max attempts per job before it is dead-lettered. |
|
||||
| `backoffMs` | `number` | `1000` | Base retry backoff in ms; doubles per attempt. |
|
||||
| `pollMs` | `number` | `250` | Poll interval used once `start()` is called (ms). |
|
||||
| `onFailed` | `(job: Job, error: unknown) => void` | — | Called when a job exhausts its attempts. |
|
||||
| `concurrency` | `number` | unlimited | Maximum jobs claimed by one `drain()` call. |
|
||||
| `capacity` | `number` | unlimited | Maximum queued plus active jobs before adds reject. |
|
||||
| `now` | `() => number` | `Date.now` | Clock injection for deterministic tests. |
|
||||
|
||||
### `Queue`
|
||||
|
||||
The object returned by `createQueue`.
|
||||
|
||||
| Method | Signature | Description |
|
||||
| ---------- | -------------------------------------------------------------- | -------------------------------------------------------------- |
|
||||
| `add` | `add<T>(name, data: T, options?: AddOptions): Promise<Job<T>>` | Enqueue a job under a worker name. Returns the created job. |
|
||||
| `process` | `process<T>(name, handler: JobHandler<T>): void` | Register the worker that runs jobs of the given name. |
|
||||
| `drain` | `drain(now?: number): Promise<number>` | Run every job whose `runAt ≤ now`, once. Returns how many ran. |
|
||||
| `start` | `start(): void` | Begin polling every `pollMs`. No-op if already started. |
|
||||
| `stop` | `stop(): void` | Stop the poll timer. |
|
||||
| `shutdown` | `shutdown({ force? }): Promise<void>` | Stop accepting jobs and await active work; force aborts it. |
|
||||
| `size` | `size(): number` | Number of jobs currently queued. |
|
||||
| `get/list` | `get(id)` / `list(name?)` | Inspect defensive copies of pending jobs. |
|
||||
| `cancel` | `cancel(id): boolean` | Remove queued work or abort an active handler. |
|
||||
| `failed` | `failed(): Job[]` | Inspect exhausted jobs in the dead-letter collection. |
|
||||
| `retry` | `retry(id): Promise<boolean>` | Reset and requeue a dead-lettered job. |
|
||||
|
||||
#### `AddOptions`
|
||||
|
||||
| Option | Type | Description |
|
||||
| ---------------- | -------- | -------------------------------------------------------------------------- |
|
||||
| `delayMs` | `number` | Delay before the job becomes runnable (ms). |
|
||||
| `maxAttempts` | `number` | Max attempts before dead-lettering. Defaults to the queue's `maxAttempts`. |
|
||||
| `repeat` | `number` | Re-enqueue this job this many ms after each successful run (recurring). |
|
||||
| `priority` | `number` | Higher values are selected first among due jobs. |
|
||||
| `idempotencyKey` | `string` | Return the matching pending job instead of enqueueing a duplicate. |
|
||||
|
||||
#### `JobHandler<T>`
|
||||
|
||||
```ts
|
||||
type JobHandler<T = unknown> = (
|
||||
job: Job<T>,
|
||||
context: { signal: AbortSignal },
|
||||
) => void | Promise<void>;
|
||||
```
|
||||
|
||||
#### `Job<T>`
|
||||
|
||||
```ts
|
||||
interface Job<T = unknown> {
|
||||
id: string; // e.g. "job_1"
|
||||
name: string;
|
||||
data: T;
|
||||
attempts: number;
|
||||
maxAttempts: number;
|
||||
runAt: number; // epoch ms; job runs when now ≥ runAt
|
||||
repeat?: number; // if set, re-enqueue this many ms after each success
|
||||
}
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
Register workers, enqueue jobs, then start the poller:
|
||||
|
||||
```ts
|
||||
import { createQueue } from "@wrnexus/queue";
|
||||
|
||||
const queue = createQueue({ maxAttempts: 3, backoffMs: 1000 });
|
||||
|
||||
// Register a worker for the "email" job name.
|
||||
queue.process<{ to: string }>("email", async (job) => {
|
||||
await send(job.data.to);
|
||||
});
|
||||
|
||||
// Enqueue a delayed job with up to 3 attempts.
|
||||
await queue.add("email", { to: "a@b.com" }, { delayMs: 5000, maxAttempts: 3 });
|
||||
|
||||
queue.start(); // begin polling; queue.stop() to halt
|
||||
```
|
||||
|
||||
Use `context.signal` in network/database calls so forced shutdown and active
|
||||
cancellation finish promptly. For process termination, prefer
|
||||
`await queue.shutdown()`; use `{ force: true }` only after your grace period.
|
||||
|
||||
### Durable queue
|
||||
|
||||
`createDurableQueue({ store })` retains jobs until their handler succeeds and
|
||||
supports atomic leases when a driver implements `QueueStore.claim`. It exposes
|
||||
the same cancellation/shutdown behavior plus `list`, `failed`, and `retry`.
|
||||
The included `memoryQueueStore()` is useful for tests; production Redis/SQL
|
||||
drivers should make `claim()` atomic to prevent two workers executing one job.
|
||||
|
||||
### Recurring jobs
|
||||
|
||||
Pass `repeat` to re-enqueue a job a fixed interval after each successful run:
|
||||
|
||||
```ts
|
||||
queue.process("heartbeat", async () => ping());
|
||||
await queue.add("heartbeat", {}, { repeat: 60_000 }); // runs ~every minute
|
||||
```
|
||||
|
||||
### Handling permanent failures
|
||||
|
||||
When a job's `attempts` reaches `maxAttempts`, it is dropped and `onFailed`
|
||||
fires instead of retrying:
|
||||
|
||||
```ts
|
||||
const queue = createQueue({
|
||||
onFailed: (job, error) => {
|
||||
console.error(`job ${job.id} (${job.name}) gave up`, error);
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
### Deterministic testing
|
||||
|
||||
Instead of `start()`, inject a clock and drive the queue with `drain()`:
|
||||
|
||||
```ts
|
||||
let clock = 0;
|
||||
const queue = createQueue({ now: () => clock });
|
||||
|
||||
queue.process("task", async () => {
|
||||
/* ... */
|
||||
});
|
||||
await queue.add("task", {}, { delayMs: 5000 });
|
||||
|
||||
clock = 5000;
|
||||
const ran = await queue.drain(); // => 1
|
||||
```
|
||||
|
||||
### Durable workflows and approvals
|
||||
|
||||
`createWorkflowEngine(store)` executes dependency-ordered steps and persists every transition,
|
||||
result, progress update, failure, cancellation, and approval record. Approval steps pause safely
|
||||
and can resume after a process restart because the snapshot lives in the supplied `WorkflowStore`.
|
||||
|
||||
```ts
|
||||
const workflow = defineDurableWorkflow({
|
||||
name: "publish-report",
|
||||
steps: [
|
||||
{ name: "build", run: buildReport },
|
||||
{ name: "approve", dependsOn: ["build"], approval: true, run: (report) => report },
|
||||
{ name: "publish", dependsOn: ["approve"], run: publishReport },
|
||||
],
|
||||
});
|
||||
|
||||
const run = await engine.start(workflow, input);
|
||||
await engine.approve(workflow, run.id, "approve", currentUser.id);
|
||||
```
|
||||
|
||||
Use `memoryWorkflowStore()` for tests. Production stores implement the small `get`, `put`, and
|
||||
`list` contract using the same transactional database or durable service as the application.
|
||||
|
||||
## Retry & backoff behavior
|
||||
|
||||
- On a thrown handler error, the job is retried while `attempts < maxAttempts`.
|
||||
- The next `runAt` is set to `now + backoffMs * 2^(attempts - 1)` (exponential
|
||||
backoff): with `backoffMs: 1000` the delays are 1s, 2s, 4s, …
|
||||
- A job whose worker name has no registered handler stays queued until one is
|
||||
registered (it is not counted as runnable by `drain`).
|
||||
- `drain` is re-entrant-safe: overlapping calls are skipped while one is running.
|
||||
|
||||
## Requirements / Notes
|
||||
|
||||
- **Bun-only** runtime (Node is not supported), consistent with the rest of the
|
||||
WrNexus framework. The queue itself relies only on standard timers
|
||||
(`setInterval`/`clearInterval`) and has no runtime dependencies.
|
||||
- The default store is in-process, so queued jobs do not survive a restart; a
|
||||
pluggable driver is intended for backing it with Redis/SQL for durability.
|
||||
- Works alongside `@wrnexus/core` for offloading work from the request path.
|
||||
@@ -1,47 +0,0 @@
|
||||
{
|
||||
"name": "@wrnexus/queue",
|
||||
"version": "0.8.8",
|
||||
"type": "module",
|
||||
"description": "@wrnexus/queue — part of the WrNexus framework.",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://git.workroot.in/WorkRoot/WRNexusJS.git",
|
||||
"directory": "packages/queue"
|
||||
},
|
||||
"homepage": "https://wrnexusjs.dev/packages/queue",
|
||||
"bugs": {
|
||||
"url": "https://git.workroot.in/WorkRoot/WRNexusJS/issues"
|
||||
},
|
||||
"keywords": [
|
||||
"wrnexus",
|
||||
"bun",
|
||||
"typescript",
|
||||
"queue"
|
||||
],
|
||||
"sideEffects": false,
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
"engines": {
|
||||
"bun": ">=1.3.0"
|
||||
},
|
||||
"publishConfig": {
|
||||
"registry": "https://registry.npmjs.org/",
|
||||
"access": "restricted"
|
||||
},
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"import": "./dist/index.js"
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@wrnexus/core": "^0.8.8",
|
||||
"@wrnexus/rpc": "^0.8.8"
|
||||
},
|
||||
"files": [
|
||||
"dist",
|
||||
"README.md"
|
||||
]
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
# @wrnexus/reactive
|
||||
|
||||
> Tiny, type-safe reactive primitives (signals) with zero dependencies.
|
||||
|
||||
Part of the **WrNexus** framework — an SSR-first, Bun-native full-stack web framework.
|
||||
|
||||
## Overview
|
||||
|
||||
`@wrnexus/reactive` is the seed of WrNexus's reactivity layer: a minimal `signal`
|
||||
primitive that holds a value, notifies subscribers when it changes, and hands back
|
||||
an unsubscribe function. It is deliberately small and framework-agnostic — it powers
|
||||
nothing on its own, but is shaped so client islands (and later the `.wrn` compiler's
|
||||
`state` blocks) can build reactive bindings on top of it. Reach for it when you need
|
||||
observable state without pulling in a full reactivity library.
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
bun add @wrnexus/reactive
|
||||
```
|
||||
|
||||
> Private package — the machine must be authenticated to the `wrnexus` npm org
|
||||
> (a read token in `~/.npmrc`). Requires **Bun** (Node is not supported).
|
||||
|
||||
## API
|
||||
|
||||
The package has a single entry point (`.`) exporting one function and three types.
|
||||
|
||||
### `signal<T>(initial: T): Signal<T>`
|
||||
|
||||
Creates a reactive signal seeded with `initial`. Returns a `Signal<T>`:
|
||||
|
||||
| Member | Signature | Description |
|
||||
| ----------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------- |
|
||||
| `get` | `(): T` | Read the current value. |
|
||||
| `set` | `(next: T): void` | Write a new value. Subscribers run **only when the value actually changes** (compared with `Object.is`). |
|
||||
| `update` | `(fn: (current: T) => T): void` | Apply a function to the current value; equivalent to `set(fn(get()))`. |
|
||||
| `subscribe` | `(fn: Subscriber<T>): Unsubscribe` | Register a subscriber; returns a function that removes it. |
|
||||
|
||||
### Types
|
||||
|
||||
```ts
|
||||
type Subscriber<T> = (value: T) => void;
|
||||
type Unsubscribe = () => void;
|
||||
|
||||
interface Signal<T> {
|
||||
get(): T;
|
||||
set(next: T): void;
|
||||
update(fn: (current: T) => T): void;
|
||||
subscribe(fn: Subscriber<T>): Unsubscribe;
|
||||
}
|
||||
```
|
||||
|
||||
Notes on semantics:
|
||||
|
||||
- **No-op updates are skipped.** `set` compares the incoming value to the current
|
||||
one with `Object.is`; identical values do not notify subscribers.
|
||||
- **Safe unsubscribe during notification.** Subscribers are iterated over a copy of
|
||||
the subscriber set, so a subscriber may call its own (or another's) unsubscribe
|
||||
while a notification is in flight.
|
||||
|
||||
## Usage
|
||||
|
||||
```ts
|
||||
import { signal } from "@wrnexus/reactive";
|
||||
|
||||
const count = signal(0);
|
||||
|
||||
count.get(); // 0
|
||||
|
||||
// Subscribe; the returned function unsubscribes.
|
||||
const off = count.subscribe((value) => {
|
||||
console.log("count is now", value);
|
||||
});
|
||||
|
||||
count.set(1); // logs: count is now 1
|
||||
count.set(1); // no-op — value unchanged, no notification
|
||||
count.update((n) => n + 1); // logs: count is now 2
|
||||
|
||||
off(); // stop listening
|
||||
count.set(3); // nothing logged
|
||||
```
|
||||
|
||||
Typed signals infer `T` from the initial value, or can be annotated explicitly:
|
||||
|
||||
```ts
|
||||
import { signal, type Signal } from "@wrnexus/reactive";
|
||||
|
||||
const user: Signal<{ name: string } | null> = signal(null);
|
||||
user.set({ name: "Ada" });
|
||||
```
|
||||
|
||||
## Requirements / Notes
|
||||
|
||||
- **Bun-only.** Distributed as TypeScript source (`main`/`exports` point at
|
||||
`src/index.ts`); consume it under Bun, which runs `.ts` directly.
|
||||
- **Zero dependencies.** The only runtime API used is the standard `Object.is`.
|
||||
- Foundational primitive for WrNexus client islands and the forthcoming `.wrn`
|
||||
compiler `state` blocks.
|
||||
@@ -1,43 +0,0 @@
|
||||
{
|
||||
"name": "@wrnexus/reactive",
|
||||
"version": "0.8.8",
|
||||
"type": "module",
|
||||
"description": "@wrnexus/reactive — part of the WrNexus framework.",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://git.workroot.in/WorkRoot/WRNexusJS.git",
|
||||
"directory": "packages/reactive"
|
||||
},
|
||||
"homepage": "https://wrnexusjs.dev/packages/reactive",
|
||||
"bugs": {
|
||||
"url": "https://git.workroot.in/WorkRoot/WRNexusJS/issues"
|
||||
},
|
||||
"keywords": [
|
||||
"wrnexus",
|
||||
"bun",
|
||||
"typescript",
|
||||
"reactive"
|
||||
],
|
||||
"sideEffects": false,
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
"engines": {
|
||||
"bun": ">=1.3.0"
|
||||
},
|
||||
"publishConfig": {
|
||||
"registry": "https://registry.npmjs.org/",
|
||||
"access": "restricted"
|
||||
},
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"import": "./dist/index.js"
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
"dist",
|
||||
"README.md"
|
||||
]
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@wrnexus/router",
|
||||
"version": "0.8.8",
|
||||
"version": "0.8.9",
|
||||
"type": "module",
|
||||
"description": "@wrnexus/router — part of the WrNexus framework.",
|
||||
"license": "MIT",
|
||||
@@ -37,8 +37,8 @@
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@wrnexus/compiler": "^0.8.8",
|
||||
"@wrnexus/core": "^0.8.8"
|
||||
"@wrnexus/compiler": "^0.8.9",
|
||||
"@wrnexus/core": "^0.8.9"
|
||||
},
|
||||
"files": [
|
||||
"dist",
|
||||
|
||||
@@ -89,7 +89,7 @@ const html = renderDocument({
|
||||
},
|
||||
url: new URL("https://acme.example/about"),
|
||||
body: "<h1>About Us</h1>",
|
||||
scripts: ["/_wire/runtime.js", "/_wire/islands/about.js"],
|
||||
scripts: ["/_wrn/runtime.js", "/_wrn/islands/about.js"],
|
||||
htmlAttrs: ' data-theme="dark"',
|
||||
});
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@wrnexus/ssr",
|
||||
"version": "0.8.8",
|
||||
"version": "0.8.9",
|
||||
"type": "module",
|
||||
"description": "@wrnexus/ssr — part of the WrNexus framework.",
|
||||
"license": "MIT",
|
||||
@@ -45,7 +45,7 @@
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@wrnexus/core": "^0.8.8",
|
||||
"@wrnexus/core": "^0.8.9",
|
||||
"@wrnexus/store": "^0.8.8",
|
||||
"@wrnexus/security": "^0.8.8"
|
||||
},
|
||||
|
||||
+13
-13
@@ -21,7 +21,7 @@ other arrays intentionally replace earlier values. Cycles and missing/invalid
|
||||
entries fail with stable `WRN-CONFIG-LAYER-*` diagnostics. `wrnexus config
|
||||
--explain` lists every resolved layer source.
|
||||
|
||||
> Global CSS bundling, the `--wire-*` design-token theme system, and the `wrnexus.config.ts` app-config loader for WrNexus apps.
|
||||
> Global CSS bundling, the `--wrn-*` design-token theme system, and the `wrnexus.config.ts` app-config loader for WrNexus apps.
|
||||
|
||||
Part of the **WrNexus** framework — an SSR-first, Bun-native full-stack web framework.
|
||||
|
||||
@@ -30,7 +30,7 @@ Part of the **WrNexus** framework — an SSR-first, Bun-native full-stack web fr
|
||||
This package owns three server-side concerns that shape every page a WrNexus app renders:
|
||||
|
||||
1. **Global stylesheet pipeline** — finds `app/styles/global.css` (or aggregates `app/styles/*.css`), bundles it with Bun's CSS bundler (which resolves `@import`, including from `node_modules`), and produces one stylesheet that is `<link>`ed into every page's `<head>`. Because it is a plain global sheet, it styles server-rendered markup and hydrated client islands identically. A custom `process` hook lets you swap in Tailwind / PostCSS / Sass.
|
||||
2. **Theme system** — design tokens exposed as CSS custom properties (`--wire-<key>`), with built-in `light`/`dark` sets, deep-merged user overrides, an SSR `<html data-theme>` render (no flash), and a tiny client runtime to toggle/persist the choice.
|
||||
2. **Theme system** — design tokens exposed as CSS custom properties (`--wrn-<key>`), with built-in `light`/`dark` sets, deep-merged user overrides, an SSR `<html data-theme>` render (no flash), and a tiny client runtime to toggle/persist the choice.
|
||||
3. **App config** — loads `wrnexus.config.ts` (the `AppConfig` type), applies named profile overrides, and loads the `.env` cascade.
|
||||
|
||||
It runs server-side / at build time. Reach for it when configuring an app, defining themes, or customising how global CSS is produced.
|
||||
@@ -111,7 +111,7 @@ interface StyleProcessContext {
|
||||
| Export | Type / Signature | Purpose |
|
||||
| -------------------- | -------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `DEFAULT_THEMES` | `Record<string, ThemeTokens>` | Built-in `light` and `dark` token maps. |
|
||||
| `THEME_COOKIE` | `"wire-theme"` | Cookie the resolved theme is read from / persisted to. |
|
||||
| `THEME_COOKIE` | `"wrn-theme"` | Cookie the resolved theme is read from / persisted to. |
|
||||
| `THEME_CSS_HREF` | `"/__wrnexus/theme.css"` | URL the generated theme stylesheet is served at. |
|
||||
| `THEME_JS_HREF` | `"/__wrnexus/theme.js"` | URL the client theme runtime is served at. |
|
||||
| `resolveThemeConfig` | `(config?: ThemeConfig) => ResolvedTheme` | Deep-merge the user's `theme` config over the defaults; pick the default theme (config's `default` if valid, else `dark`, else the first). |
|
||||
@@ -119,7 +119,7 @@ interface StyleProcessContext {
|
||||
| `renderThemeCss` | `(theme: ResolvedTheme) => string` | Generate the theme stylesheet: a `:root{…}` default plus one `[data-theme="<name>"]{…}` block per theme. |
|
||||
| `renderThemeRuntime` | `(theme: ResolvedTheme) => string` | Generate the client runtime (see below). |
|
||||
|
||||
Tokens are emitted as `--wire-<key>` custom properties, **except** the reserved key `color-scheme`, which is emitted as the native `color-scheme` CSS property so form controls and scrollbars match the theme.
|
||||
Tokens are emitted as `--wrn-<key>` custom properties, **except** the reserved key `color-scheme`, which is emitted as the native `color-scheme` CSS property so form controls and scrollbars match the theme.
|
||||
|
||||
`ThemeConfig` / `ThemeTokens` / `ResolvedTheme`:
|
||||
|
||||
@@ -164,7 +164,7 @@ theme: {
|
||||
}
|
||||
```
|
||||
|
||||
The client runtime (`renderThemeRuntime`) exposes `window.wireTheme` with `{ get, set, toggle, bind, themes }`, wires up any `[data-wire-theme-toggle]` and `[data-wire-theme-set]` elements on load, and persists the choice to the `wire-theme` cookie (`max-age` 1 year, `samesite=lax`). `toggle()` cycles through the configured theme names in order.
|
||||
The client runtime (`renderThemeRuntime`) exposes `window.wrnTheme` with `{ get, set, toggle, bind, themes }`, connects up any `[data-wrn-theme-toggle]` and `[data-wrn-theme-set]` elements on load, and persists the choice to the `wrn-theme` cookie (`max-age` 1 year, `samesite=lax`). `toggle()` cycles through the configured theme names in order.
|
||||
|
||||
## Usage
|
||||
|
||||
@@ -252,17 +252,17 @@ In templates, consume tokens via the custom properties:
|
||||
|
||||
```css
|
||||
.card {
|
||||
background: var(--wire-color-surface);
|
||||
color: var(--wire-color-text);
|
||||
border: 1px solid var(--wire-color-border);
|
||||
border-radius: var(--wire-radius);
|
||||
box-shadow: var(--wire-shadow-1);
|
||||
background: var(--wrn-color-surface);
|
||||
color: var(--wrn-color-text);
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: var(--wrn-radius);
|
||||
box-shadow: var(--wrn-shadow-1);
|
||||
}
|
||||
```
|
||||
|
||||
```html
|
||||
<button data-wire-theme-toggle>Toggle theme</button>
|
||||
<button data-wire-theme-set="brand">Brand theme</button>
|
||||
<button data-wrn-theme-toggle>Toggle theme</button>
|
||||
<button data-wrn-theme-set="brand">Brand theme</button>
|
||||
```
|
||||
|
||||
## Requirements / Notes
|
||||
@@ -270,4 +270,4 @@ In templates, consume tokens via the custom properties:
|
||||
- **Bun-only.** `bundleCss` uses `Bun.build`'s CSS bundler for `@import` resolution, nesting, and minification. Node is not supported.
|
||||
- Config and env loading use `node:fs` / `node:path` / `node:url` and read from `process.env`.
|
||||
- Peer package: `@wrnexus/core` supplies the `SeoConfig` and `SecurityConfig` types referenced by `AppConfig`.
|
||||
- The bundled global stylesheet, the theme stylesheet (`THEME_CSS_HREF`), and the theme runtime (`THEME_JS_HREF`) are wired into pages by the framework's server; this package only produces their contents.
|
||||
- The bundled global stylesheet, the theme stylesheet (`THEME_CSS_HREF`), and the theme runtime (`THEME_JS_HREF`) are connected into pages by the framework's server; this package only produces their contents.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@wrnexus/styles",
|
||||
"version": "0.8.8",
|
||||
"version": "0.8.10",
|
||||
"type": "module",
|
||||
"description": "@wrnexus/styles — part of the WrNexus framework.",
|
||||
"license": "MIT",
|
||||
@@ -37,8 +37,8 @@
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@wrnexus/uploader": "^0.8.8",
|
||||
"@wrnexus/core": "^0.8.8",
|
||||
"@wrnexus/uploader": "^0.8.9",
|
||||
"@wrnexus/core": "^0.8.9",
|
||||
"@wrnexus/plugin": "^0.8.8"
|
||||
},
|
||||
"files": [
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
# @wrnexus/syntax
|
||||
|
||||
Canonical WRN lexer, parser, AST, language metadata, source positions, and stable
|
||||
diagnostics. Framework tooling should import this package instead of implementing a
|
||||
separate `.wrn` parser.
|
||||
|
||||
See `docs/WRN-LANGUAGE-SPEC-1.0.md` in the WRNexusJS repository.
|
||||
@@ -1,67 +0,0 @@
|
||||
{
|
||||
"name": "@wrnexus/syntax",
|
||||
"version": "0.8.8",
|
||||
"type": "module",
|
||||
"description": "@wrnexus/syntax — part of the WrNexus framework.",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://git.workroot.in/WorkRoot/WRNexusJS.git",
|
||||
"directory": "packages/syntax"
|
||||
},
|
||||
"homepage": "https://wrnexusjs.dev/packages/syntax",
|
||||
"bugs": {
|
||||
"url": "https://git.workroot.in/WorkRoot/WRNexusJS/issues"
|
||||
},
|
||||
"keywords": [
|
||||
"wrnexus",
|
||||
"bun",
|
||||
"typescript",
|
||||
"syntax"
|
||||
],
|
||||
"sideEffects": false,
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
"engines": {
|
||||
"bun": ">=1.3.0"
|
||||
},
|
||||
"publishConfig": {
|
||||
"registry": "https://registry.npmjs.org/",
|
||||
"access": "restricted"
|
||||
},
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"import": "./dist/index.js"
|
||||
},
|
||||
"./parser": {
|
||||
"types": "./dist/parser.d.ts",
|
||||
"import": "./dist/parser.js"
|
||||
},
|
||||
"./tokenizer": {
|
||||
"types": "./dist/tokenizer.d.ts",
|
||||
"import": "./dist/tokenizer.js"
|
||||
},
|
||||
"./types": {
|
||||
"types": "./dist/types.d.ts",
|
||||
"import": "./dist/types.js"
|
||||
},
|
||||
"./diagnostics": {
|
||||
"types": "./dist/diagnostics.d.ts",
|
||||
"import": "./dist/diagnostics.js"
|
||||
},
|
||||
"./spec": {
|
||||
"types": "./dist/spec.d.ts",
|
||||
"import": "./dist/spec.js"
|
||||
},
|
||||
"./formatter": {
|
||||
"types": "./dist/formatter.d.ts",
|
||||
"import": "./dist/formatter.js"
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
"dist",
|
||||
"README.md"
|
||||
]
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@wrnexus/test",
|
||||
"version": "0.8.8",
|
||||
"version": "0.8.9",
|
||||
"type": "module",
|
||||
"description": "@wrnexus/test — part of the WrNexus framework.",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -1,128 +0,0 @@
|
||||
# @wrnexus/tracking
|
||||
|
||||
> Error tracking for WrNexus apps: capture exceptions manually or via middleware and fan them out to pluggable sinks.
|
||||
|
||||
Part of the **WrNexus** framework — an SSR-first, Bun-native full-stack web framework.
|
||||
|
||||
## Overview
|
||||
|
||||
`@wrnexus/tracking` is a small, server-side error-capture layer. You create a
|
||||
tracker with one or more **sinks**, then feed it errors — either manually with
|
||||
`tracker.capture(err, context)` or automatically by mounting `tracker.middleware()`
|
||||
in your request pipeline. A `consoleSink` is included; forwarding to Sentry,
|
||||
Datadog, or any other backend is just a matter of writing a tiny sink. Reach for
|
||||
it when you want a single, sink-agnostic place to route application errors. Sinks
|
||||
run best-effort — a throwing sink never breaks the request.
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
bun add @wrnexus/tracking
|
||||
```
|
||||
|
||||
> Private package — the machine must be authenticated to the `wrnexus` npm org
|
||||
> (a read token in `~/.npmrc`). Requires **Bun** (Node is not supported).
|
||||
|
||||
## API
|
||||
|
||||
### `createTracker(options?): Tracker`
|
||||
|
||||
Creates a tracker. `TrackerOptions`:
|
||||
|
||||
| Option | Type | Description |
|
||||
| ------------ | ------------------------------------------- | --------------------------------------------------------------------------- |
|
||||
| `sinks` | `ErrorSink[]` | Initial sinks to fan events out to. Defaults to `[]`. |
|
||||
| `now` | `() => number` | Clock used for `event.timestamp` (epoch ms). Defaults to `Date.now`. |
|
||||
| `beforeSend` | `(event: ErrorEvent) => ErrorEvent \| null` | Scrub/enrich an event before it reaches any sink. Return `null` to drop it. |
|
||||
|
||||
The returned `Tracker`:
|
||||
|
||||
| Member | Signature | Description |
|
||||
| ------------ | ---------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `capture` | `(error: unknown, context?: Record<string, unknown>) => Promise<void>` | Normalizes any thrown value into an `Error`, builds an `ErrorEvent`, runs `beforeSend`, then dispatches to all sinks. Non-`Error` values are wrapped in an `Error` named `NonError`. |
|
||||
| `addSink` | `(sink: ErrorSink) => void` | Registers an additional sink at runtime. |
|
||||
| `middleware` | `() => Middleware` | Returns a WrNexus `Middleware` that captures any error thrown downstream, then re-throws it so the framework's error handler still produces the response. |
|
||||
|
||||
The middleware attaches this context to captured events:
|
||||
|
||||
```ts
|
||||
{ method: ctx.req.method, path: ctx.url.pathname, requestId: ctx.locals.requestId }
|
||||
```
|
||||
|
||||
### `consoleSink: ErrorSink`
|
||||
|
||||
A built-in sink that logs a compact one-line message via `console.error`, e.g.
|
||||
`[error] TypeError: cannot read x {"userId":42}`.
|
||||
|
||||
### Types
|
||||
|
||||
```ts
|
||||
interface ErrorEvent {
|
||||
error: Error;
|
||||
context: Record<string, unknown>; // request info, user id, tags…
|
||||
timestamp: number; // epoch ms
|
||||
}
|
||||
|
||||
interface ErrorSink {
|
||||
name?: string;
|
||||
capture(event: ErrorEvent): void | Promise<void>;
|
||||
}
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
Manual capture:
|
||||
|
||||
```ts
|
||||
import { createTracker, consoleSink } from "@wrnexus/tracking";
|
||||
|
||||
const tracker = createTracker({ sinks: [consoleSink] });
|
||||
|
||||
try {
|
||||
await doWork();
|
||||
} catch (err) {
|
||||
await tracker.capture(err, { userId: 42, op: "doWork" });
|
||||
throw err;
|
||||
}
|
||||
```
|
||||
|
||||
As request middleware:
|
||||
|
||||
```ts
|
||||
import { createTracker, consoleSink } from "@wrnexus/tracking";
|
||||
|
||||
const tracker = createTracker({ sinks: [consoleSink] });
|
||||
|
||||
app.use(tracker.middleware()); // captures + re-throws downstream errors
|
||||
```
|
||||
|
||||
A custom sink with `beforeSend` scrubbing:
|
||||
|
||||
```ts
|
||||
import { createTracker, type ErrorSink } from "@wrnexus/tracking";
|
||||
|
||||
const sentrySink: ErrorSink = {
|
||||
name: "sentry",
|
||||
async capture(event) {
|
||||
await Sentry.captureException(event.error, { extra: event.context });
|
||||
},
|
||||
};
|
||||
|
||||
const tracker = createTracker({
|
||||
sinks: [sentrySink],
|
||||
beforeSend(event) {
|
||||
delete event.context.password; // scrub secrets
|
||||
return event; // return null to drop the event entirely
|
||||
},
|
||||
});
|
||||
|
||||
tracker.addSink(anotherSink); // add more sinks later
|
||||
```
|
||||
|
||||
## Requirements / Notes
|
||||
|
||||
- Runs on **Bun** only (Node is not supported).
|
||||
- Peer package: [`@wrnexus/core`](../core) — the `Context` and `Middleware` types
|
||||
used by `tracker.middleware()` come from there.
|
||||
- Sink dispatch is fire-and-forget-safe: all sinks run via `Promise.all`, and a
|
||||
sink that throws is swallowed so it can never break the app.
|
||||
@@ -1,43 +0,0 @@
|
||||
{
|
||||
"name": "@wrnexus/tracking",
|
||||
"version": "0.8.8",
|
||||
"type": "module",
|
||||
"description": "@wrnexus/tracking — part of the WrNexus framework.",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://git.workroot.in/WorkRoot/WRNexusJS.git",
|
||||
"directory": "packages/tracking"
|
||||
},
|
||||
"homepage": "https://wrnexusjs.dev/packages/tracking",
|
||||
"bugs": {
|
||||
"url": "https://git.workroot.in/WorkRoot/WRNexusJS/issues"
|
||||
},
|
||||
"keywords": [
|
||||
"wrnexus",
|
||||
"bun",
|
||||
"typescript",
|
||||
"tracking"
|
||||
],
|
||||
"sideEffects": false,
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
"engines": {
|
||||
"bun": ">=1.3.0"
|
||||
},
|
||||
"publishConfig": {
|
||||
"registry": "https://registry.npmjs.org/",
|
||||
"access": "restricted"
|
||||
},
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"import": "./dist/index.js"
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
"dist",
|
||||
"README.md"
|
||||
]
|
||||
}
|
||||
+35
-35
@@ -1,6 +1,6 @@
|
||||
# @wrnexus/ui
|
||||
|
||||
> First-party Wire UI component library — a set of themeable `.wrn` components plus a single tokenized stylesheet.
|
||||
> First-party WrNexus UI component library — a set of themeable `.wrn` components plus a single tokenized stylesheet.
|
||||
|
||||
Part of the **WrNexus** framework — an SSR-first, Bun-native full-stack web framework.
|
||||
|
||||
@@ -11,7 +11,7 @@ controls, and feedback UI) together with one themeable stylesheet, `ui.css`. The
|
||||
components are **auto-discovered** by the framework router — you don't import them
|
||||
in code. Once the package's component directory is on the router's scan path, you
|
||||
mount any component in a page with `data-component="<name>"`. Every visual is
|
||||
driven by `var(--wire-*)` theme tokens, so components restyle instantly when the
|
||||
driven by `var(--wrn-*)` theme tokens, so components restyle instantly when the
|
||||
theme changes. The tiny JS surface (`src/index.ts`) exists only so the toolchain
|
||||
(CLI build + dev server) can locate the component directory and stylesheet.
|
||||
|
||||
@@ -30,7 +30,7 @@ bun add @wrnexus/ui
|
||||
> (a read token in `~/.npmrc`). Requires **Bun** (Node is not supported).
|
||||
|
||||
In practice you rarely install this directly: `@wrnexus/cli` and
|
||||
`@wrnexus/dev-server` already depend on it and wire it into the router for you
|
||||
`@wrnexus/dev-server` already depend on it and wrn it into the router for you
|
||||
(see [Auto-discovery](#auto-discovery)).
|
||||
|
||||
## Components
|
||||
@@ -54,19 +54,19 @@ element), and most render their body from either a named prop or the default slo
|
||||
|
||||
### Core / feedback
|
||||
|
||||
| Name | Purpose | Key props |
|
||||
| -------------- | ---------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
|
||||
| `button` | Button | `label`, `variant` (`default`\|`primary`\|`danger`\|`ghost`), `size` (`sm`\|`md`\|`lg`), `type` |
|
||||
| `input` | Text input | see source |
|
||||
| `textarea` | Multi-line input | see source |
|
||||
| `checkbox` | Checkbox | see source |
|
||||
| `badge` | Small status badge | `label`, `variant` |
|
||||
| `alert` | Callout box | `variant` (`info`\|`success`\|`danger`\|`warning`), `title`, `message` |
|
||||
| `card` | Padded, bordered surface | `class` |
|
||||
| `avatar` | User avatar | see source |
|
||||
| `spinner` | Loading indicator | see source |
|
||||
| `disclosure` | Expandable details/summary | see source |
|
||||
| `theme-toggle` | Theme switch button (binds `data-wire-theme-toggle`) | `label` |
|
||||
| Name | Purpose | Key props |
|
||||
| -------------- | --------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
|
||||
| `button` | Button | `label`, `variant` (`default`\|`primary`\|`danger`\|`ghost`), `size` (`sm`\|`md`\|`lg`), `type` |
|
||||
| `input` | Text input | see source |
|
||||
| `textarea` | Multi-line input | see source |
|
||||
| `checkbox` | Checkbox | see source |
|
||||
| `badge` | Small status badge | `label`, `variant` |
|
||||
| `alert` | Callout box | `variant` (`info`\|`success`\|`danger`\|`warning`), `title`, `message` |
|
||||
| `card` | Padded, bordered surface | `class` |
|
||||
| `avatar` | User avatar | see source |
|
||||
| `spinner` | Loading indicator | see source |
|
||||
| `disclosure` | Expandable details/summary | see source |
|
||||
| `theme-toggle` | Theme switch button (binds `data-wrn-theme-toggle`) | `label` |
|
||||
|
||||
### Additional controls & data display
|
||||
|
||||
@@ -100,7 +100,7 @@ are `.wrn` files rendered server-side.
|
||||
| ------------------ | -------------------------- | ------------------------------------------------------------------------------------------ |
|
||||
| `uiComponentsDir` | `() => string` | Absolute path to the `.wrn` component directory (feed to `buildRouter`'s `componentDirs`). |
|
||||
| `uiCssPath` | `() => string` | Absolute path to `ui.css`. |
|
||||
| `uiCss` | `() => string` | The `ui.css` file contents (all `.wire-*` classes, themed via tokens). |
|
||||
| `uiCss` | `() => string` | The `ui.css` file contents (all `.wrn-*` classes, themed via tokens). |
|
||||
| `uiComponentNames` | `() => string[]` | Sorted list of declared built-in component names. |
|
||||
| `uiComponentPath` | `(name: string) => string` | Absolute source path for a declared component name or case-insensitive alias. |
|
||||
|
||||
@@ -126,9 +126,9 @@ primitives. Applications can still use Tailwind independently in their own
|
||||
source files.
|
||||
|
||||
The shared stylesheet gives all component boundaries consistent, GPU-friendly
|
||||
entry and interaction motion. Override `--wire-motion-fast`,
|
||||
`--wire-motion-base`, `--wire-motion-slow`, `--wire-ease-standard`, or
|
||||
`--wire-ease-emphasized` to tune it. Hover lift is limited to precise pointing
|
||||
entry and interaction motion. Override `--wrn-motion-fast`,
|
||||
`--wrn-motion-base`, `--wrn-motion-slow`, `--wrn-ease-standard`, or
|
||||
`--wrn-ease-emphasized` to tune it. Hover lift is limited to precise pointing
|
||||
devices and `prefers-reduced-motion` is honored automatically.
|
||||
|
||||
### Using the selected theme in application UI
|
||||
@@ -139,21 +139,21 @@ pages and custom `.wrn` components can use the same contract:
|
||||
|
||||
```css
|
||||
.account-card {
|
||||
background: var(--wire-color-surface);
|
||||
color: var(--wire-color-text);
|
||||
border: 1px solid var(--wire-color-border);
|
||||
background: var(--wrn-color-surface);
|
||||
color: var(--wrn-color-text);
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
}
|
||||
|
||||
.account-card__action {
|
||||
background: var(--wire-color-primary);
|
||||
color: var(--wire-color-primary-contrast);
|
||||
background: var(--wrn-color-primary);
|
||||
color: var(--wrn-color-primary-contrast);
|
||||
}
|
||||
```
|
||||
|
||||
Stable no-spacing helper classes are also available: `wire-bg-page`,
|
||||
`wire-bg-surface`, `wire-bg-surface-2`, `wire-bg-primary`, `wire-bg-secondary`,
|
||||
`wire-text`, `wire-text-muted`, `wire-text-primary`, `wire-text-success`,
|
||||
`wire-text-warning`, `wire-text-danger`, and `wire-border`.
|
||||
Stable no-spacing helper classes are also available: `wrn-bg-page`,
|
||||
`wrn-bg-surface`, `wrn-bg-surface-2`, `wrn-bg-primary`, `wrn-bg-secondary`,
|
||||
`wrn-text`, `wrn-text-muted`, `wrn-text-primary`, `wrn-text-success`,
|
||||
`wrn-text-warning`, `wrn-text-danger`, and `wrn-border`.
|
||||
|
||||
Tailwind-authored custom markup can continue using the palette families already
|
||||
used by packaged components. `indigo-*` and `violet-*` resolve to primary,
|
||||
@@ -169,7 +169,7 @@ The router scans extra `componentDirs` (in addition to the app's own
|
||||
`app/components`) and keys components by name. Library dirs are scanned **first**
|
||||
and `app/components` **last**, so an app component of the same name shadows the
|
||||
library's. The CLI build (`@wrnexus/cli`) and dev server (`@wrnexus/dev-server`)
|
||||
both wire the UI directory in for you:
|
||||
both wrn the UI directory in for you:
|
||||
|
||||
```ts
|
||||
import { buildRouter } from "@wrnexus/router";
|
||||
@@ -195,11 +195,11 @@ attributes (other than `data-component`) become string props:
|
||||
|
||||
Ways to customize the components, in increasing order of power:
|
||||
|
||||
1. **Theme tokens** — override CSS custom properties such as `--wire-color-primary`,
|
||||
`--wire-color-surface`, `--wire-radius-sm`, etc. Every component style resolves
|
||||
through `var(--wire-*)`, so changing a token restyles everything instantly
|
||||
1. **Theme tokens** — override CSS custom properties such as `--wrn-color-primary`,
|
||||
`--wrn-color-surface`, `--wrn-radius-sm`, etc. Every component style resolves
|
||||
through `var(--wrn-*)`, so changing a token restyles everything instantly
|
||||
(including across theme switches).
|
||||
2. **App CSS** — redefine a `.wire-*` class in your own stylesheet, which is loaded
|
||||
2. **App CSS** — redefine a `.wrn-*` class in your own stylesheet, which is loaded
|
||||
after `ui.css` and therefore wins.
|
||||
3. **`class` prop** — pass a `class` prop to a component; it is appended to the
|
||||
component's root element, letting you add per-instance classes without touching
|
||||
@@ -217,4 +217,4 @@ Ways to customize the components, in increasing order of power:
|
||||
[`@wrnexus/dev-server`](../dev-server) / built by [`@wrnexus/cli`](../cli).
|
||||
- Depends on [`@wrnexus/core`](../core) (`dependencies`).
|
||||
- `theme-toggle` relies on the framework's theme runtime, which binds the
|
||||
`data-wire-theme-toggle` attribute — no per-component JS is required.
|
||||
`data-wrn-theme-toggle` attribute — no per-component JS is required.
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import ComponentBaseStyles from "../styles/ComponentBaseStyles.wrn"
|
||||
|
||||
component Accordion {
|
||||
outputs {
|
||||
change(payload: { value?: string | number | boolean | null; values?: Array<string | number | boolean | null | object>; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | string | number | boolean | null)
|
||||
@@ -105,15 +103,15 @@ component Accordion {
|
||||
data-variant="{variant}"
|
||||
data-indicator="{indicator}"
|
||||
data-multiple="{allowsMultiple() ? 'true' : 'false'}"
|
||||
class="wire-component wire-component--color-{color} wire-component--size-{size} wire-next--accordion wire-next--accordion-{variant} {bordered ? 'wire-next--accordion-bordered' : ''} {separated ? 'wire-next--accordion-separated' : ''} {flush ? 'wire-next--accordion-flush' : ''} {disabled ? 'wire-next--disabled' : ''} {class}"
|
||||
class="wrn-component wrn-component--color-{color} wrn-component--size-{size} wrn-next--accordion wrn-next--accordion-{variant} {bordered ? 'wrn-next--accordion-bordered' : ''} {separated ? 'wrn-next--accordion-separated' : ''} {flush ? 'wrn-next--accordion-flush' : ''} {disabled ? 'wrn-next--disabled' : ''} {class}"
|
||||
>
|
||||
{#each items as item, index}
|
||||
<section
|
||||
class="wire-next__accordion-item"
|
||||
class="wrn-next__accordion-item"
|
||||
data-open="{isOpen(itemValue(item, index)) ? 'true' : 'false'}"
|
||||
data-disabled="{disabled || item.disabled ? 'true' : 'false'}"
|
||||
>
|
||||
<h3 class="wire-next__accordion-heading">
|
||||
<h3 class="wrn-next__accordion-heading">
|
||||
<button
|
||||
type="button"
|
||||
id="{id}-trigger-{index}"
|
||||
@@ -123,7 +121,7 @@ component Accordion {
|
||||
@click="toggleItem(event, itemValue(item, index), item)"
|
||||
>
|
||||
{#if showIndicator && indicatorPosition === "start"}
|
||||
<span class="wire-next__accordion-indicator" aria-hidden="true">
|
||||
<span class="wrn-next__accordion-indicator" aria-hidden="true">
|
||||
{#if indicator === "chevron"}
|
||||
<span class="icon-[lucide--chevron-down]"></span>
|
||||
{:else}
|
||||
@@ -133,7 +131,7 @@ component Accordion {
|
||||
{/if}
|
||||
<span>{item.label || item.title}</span>
|
||||
{#if showIndicator && indicatorPosition === "end"}
|
||||
<span class="wire-next__accordion-indicator" aria-hidden="true">
|
||||
<span class="wrn-next__accordion-indicator" aria-hidden="true">
|
||||
{#if indicator === "chevron"}
|
||||
<span class="icon-[lucide--chevron-down]"></span>
|
||||
{:else}
|
||||
@@ -146,23 +144,23 @@ component Accordion {
|
||||
|
||||
<div
|
||||
id="{id}-panel-{index}"
|
||||
class="wire-next__accordion-panel"
|
||||
class="wrn-next__accordion-panel"
|
||||
role="region"
|
||||
aria-labelledby="{id}-trigger-{index}"
|
||||
aria-hidden="{isOpen(itemValue(item, index)) ? 'false' : 'true'}"
|
||||
>
|
||||
<div>
|
||||
<div class="wire-next__accordion-content {contentItalic ? 'wire-next__accordion-content-italic' : ''}">
|
||||
<div class="wrn-next__accordion-content {contentItalic ? 'wrn-next__accordion-content-italic' : ''}">
|
||||
{#if item.content}<p>{item.content}</p>{/if}
|
||||
|
||||
{#if item.children && item.children.length > 0}
|
||||
<div class="wire-next__accordion-nested">
|
||||
<div class="wrn-next__accordion-nested">
|
||||
{#each item.children as child, childIndex}
|
||||
<section
|
||||
class="wire-next__accordion-item"
|
||||
class="wrn-next__accordion-item"
|
||||
data-open="{isOpen(nestedValue(item, index, child, childIndex)) ? 'true' : 'false'}"
|
||||
>
|
||||
<h4 class="wire-next__accordion-heading">
|
||||
<h4 class="wrn-next__accordion-heading">
|
||||
<button
|
||||
type="button"
|
||||
id="{id}-trigger-{index}-{childIndex}"
|
||||
@@ -172,7 +170,7 @@ component Accordion {
|
||||
@click="toggleItem(event, nestedValue(item, index, child, childIndex), child)"
|
||||
>
|
||||
{#if showIndicator}
|
||||
<span class="wire-next__accordion-indicator" aria-hidden="true">
|
||||
<span class="wrn-next__accordion-indicator" aria-hidden="true">
|
||||
{#if indicator === "chevron"}
|
||||
<span class="icon-[lucide--chevron-down]"></span>
|
||||
{:else}
|
||||
@@ -185,13 +183,13 @@ component Accordion {
|
||||
</h4>
|
||||
<div
|
||||
id="{id}-panel-{index}-{childIndex}"
|
||||
class="wire-next__accordion-panel"
|
||||
class="wrn-next__accordion-panel"
|
||||
role="region"
|
||||
aria-labelledby="{id}-trigger-{index}-{childIndex}"
|
||||
aria-hidden="{isOpen(nestedValue(item, index, child, childIndex)) ? 'false' : 'true'}"
|
||||
>
|
||||
<div>
|
||||
<div class="wire-next__accordion-content {contentItalic ? 'wire-next__accordion-content-italic' : ''}">
|
||||
<div class="wrn-next__accordion-content {contentItalic ? 'wrn-next__accordion-content-italic' : ''}">
|
||||
<p>{child.content}</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -206,27 +204,26 @@ component Accordion {
|
||||
</section>
|
||||
{/each}
|
||||
</div>
|
||||
<ComponentBaseStyles hidden />
|
||||
}
|
||||
|
||||
style {
|
||||
.wire-next--accordion {
|
||||
--wire-accordion-accent: var(--wire-component-color);
|
||||
.wrn-next--accordion {
|
||||
--wrn-accordion-accent: var(--wrn-component-color);
|
||||
display: grid;
|
||||
width: 100%;
|
||||
color: var(--wire-color-text);
|
||||
color: var(--wrn-color-text);
|
||||
}
|
||||
|
||||
.wire-next__accordion-item {
|
||||
.wrn-next__accordion-item {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.wire-next__accordion-heading {
|
||||
.wrn-next__accordion-heading {
|
||||
margin: 0;
|
||||
font: inherit;
|
||||
}
|
||||
|
||||
.wire-next__accordion-heading > button {
|
||||
.wrn-next__accordion-heading > button {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
align-items: center;
|
||||
@@ -234,7 +231,7 @@ component Accordion {
|
||||
padding: 0.85rem 0;
|
||||
border: 0;
|
||||
background: transparent;
|
||||
color: var(--wire-color-text);
|
||||
color: var(--wrn-color-text);
|
||||
font: inherit;
|
||||
font-size: 0.88rem;
|
||||
font-weight: 700;
|
||||
@@ -242,171 +239,240 @@ component Accordion {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.wire-next__accordion-heading > button > span:not(.wire-next__accordion-indicator) {
|
||||
.wrn-next__accordion-heading > button > span:not(.wrn-next__accordion-indicator) {
|
||||
min-width: 0;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.wire-next__accordion-heading > button:focus-visible {
|
||||
border-radius: var(--wire-radius-sm);
|
||||
outline: 2px solid var(--wire-accordion-accent);
|
||||
.wrn-next__accordion-heading > button:focus-visible {
|
||||
border-radius: var(--wrn-radius-sm);
|
||||
outline: 2px solid var(--wrn-accordion-accent);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
.wire-next__accordion-heading > button:disabled {
|
||||
.wrn-next__accordion-heading > button:disabled {
|
||||
cursor: not-allowed;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.wire-next__accordion-indicator {
|
||||
.wrn-next__accordion-indicator {
|
||||
display: inline-flex;
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
flex: 0 0 1rem;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: var(--wire-color-muted);
|
||||
color: var(--wrn-color-muted);
|
||||
font-size: 1rem;
|
||||
font-weight: 500;
|
||||
line-height: 1;
|
||||
transition:
|
||||
color var(--wire-motion-fast) var(--wire-ease-standard),
|
||||
transform var(--wire-motion-fast) var(--wire-ease-standard);
|
||||
color var(--wrn-motion-fast) var(--wrn-ease-standard),
|
||||
transform var(--wrn-motion-fast) var(--wrn-ease-standard);
|
||||
}
|
||||
|
||||
.wire-next__accordion-indicator > span {
|
||||
.wrn-next__accordion-indicator > span {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.wire-next__accordion-indicator > [class*="icon-["] {
|
||||
.wrn-next__accordion-indicator > [class*="icon-["] {
|
||||
width: 0.95rem;
|
||||
height: 0.95rem;
|
||||
}
|
||||
|
||||
.wire-next__accordion-item[data-open="true"]
|
||||
> .wire-next__accordion-heading
|
||||
.wire-next__accordion-indicator {
|
||||
color: var(--wire-accordion-accent);
|
||||
.wrn-next__accordion-item[data-open="true"]
|
||||
> .wrn-next__accordion-heading
|
||||
.wrn-next__accordion-indicator {
|
||||
color: var(--wrn-accordion-accent);
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
|
||||
.wire-next--accordion[data-indicator="chevron"]
|
||||
.wire-next__accordion-item[data-open="true"]
|
||||
> .wire-next__accordion-heading
|
||||
.wire-next__accordion-indicator {
|
||||
.wrn-next--accordion[data-indicator="chevron"]
|
||||
.wrn-next__accordion-item[data-open="true"]
|
||||
> .wrn-next__accordion-heading
|
||||
.wrn-next__accordion-indicator {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
.wire-next__accordion-item[data-open="true"] > .wire-next__accordion-heading > button {
|
||||
color: var(--wire-accordion-accent);
|
||||
.wrn-next__accordion-item[data-open="true"] > .wrn-next__accordion-heading > button {
|
||||
color: var(--wrn-accordion-accent);
|
||||
}
|
||||
|
||||
.wire-next__accordion-panel {
|
||||
.wrn-next__accordion-panel {
|
||||
display: grid;
|
||||
grid-template-rows: 0fr;
|
||||
opacity: 0;
|
||||
transition:
|
||||
grid-template-rows var(--wire-motion-base) var(--wire-ease-standard),
|
||||
opacity var(--wire-motion-fast) var(--wire-ease-standard);
|
||||
grid-template-rows var(--wrn-motion-base) var(--wrn-ease-standard),
|
||||
opacity var(--wrn-motion-fast) var(--wrn-ease-standard);
|
||||
}
|
||||
|
||||
.wire-next__accordion-item[data-open="true"] > .wire-next__accordion-panel {
|
||||
.wrn-next__accordion-item[data-open="true"] > .wrn-next__accordion-panel {
|
||||
grid-template-rows: 1fr;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.wire-next__accordion-panel > div {
|
||||
.wrn-next__accordion-panel > div {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.wire-next__accordion-content {
|
||||
.wrn-next__accordion-content {
|
||||
padding: 0 0 1rem 1.75rem;
|
||||
color: var(--wire-color-muted);
|
||||
color: var(--wrn-color-muted);
|
||||
font-size: 0.86rem;
|
||||
line-height: 1.65;
|
||||
}
|
||||
|
||||
.wire-next__accordion-content > p {
|
||||
.wrn-next__accordion-content > p {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.wire-next__accordion-content-italic > p::first-line {
|
||||
.wrn-next__accordion-content-italic > p::first-line {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.wire-next__accordion-nested {
|
||||
.wrn-next__accordion-nested {
|
||||
display: grid;
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
|
||||
.wire-next__accordion-nested .wire-next__accordion-content {
|
||||
.wrn-next__accordion-nested .wrn-next__accordion-content {
|
||||
padding-left: 1.5rem;
|
||||
}
|
||||
|
||||
.wire-next--accordion-bordered {
|
||||
.wrn-next--accordion-bordered {
|
||||
overflow: hidden;
|
||||
border: 1px solid var(--wire-color-border);
|
||||
border-radius: var(--wire-radius-md);
|
||||
background: var(--wire-color-surface);
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: var(--wrn-radius-md);
|
||||
background: var(--wrn-color-surface);
|
||||
}
|
||||
|
||||
.wire-next--accordion-bordered > .wire-next__accordion-item + .wire-next__accordion-item {
|
||||
border-top: 1px solid var(--wire-color-border);
|
||||
.wrn-next--accordion-bordered > .wrn-next__accordion-item + .wrn-next__accordion-item {
|
||||
border-top: 1px solid var(--wrn-color-border);
|
||||
}
|
||||
|
||||
.wire-next--accordion-bordered
|
||||
> .wire-next__accordion-item
|
||||
> .wire-next__accordion-heading
|
||||
.wrn-next--accordion-bordered
|
||||
> .wrn-next__accordion-item
|
||||
> .wrn-next__accordion-heading
|
||||
> button {
|
||||
padding-inline: 1rem;
|
||||
}
|
||||
|
||||
.wire-next--accordion-bordered
|
||||
> .wire-next__accordion-item
|
||||
> .wire-next__accordion-panel
|
||||
.wire-next__accordion-content {
|
||||
.wrn-next--accordion-bordered
|
||||
> .wrn-next__accordion-item
|
||||
> .wrn-next__accordion-panel
|
||||
.wrn-next__accordion-content {
|
||||
padding-inline: 1rem;
|
||||
}
|
||||
|
||||
.wire-next--accordion-separated {
|
||||
.wrn-next--accordion-separated {
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.wire-next--accordion-separated > .wire-next__accordion-item {
|
||||
.wrn-next--accordion-separated > .wrn-next__accordion-item {
|
||||
overflow: hidden;
|
||||
border: 1px solid transparent;
|
||||
border-radius: var(--wire-radius-md);
|
||||
background: var(--wire-color-surface-2);
|
||||
border-radius: var(--wrn-radius-md);
|
||||
background: var(--wrn-color-surface-2);
|
||||
}
|
||||
|
||||
.wire-next--accordion-separated > .wire-next__accordion-item[data-open="true"] {
|
||||
border-color: var(--wire-color-border);
|
||||
.wrn-next--accordion-separated > .wrn-next__accordion-item[data-open="true"] {
|
||||
border-color: var(--wrn-color-border);
|
||||
}
|
||||
|
||||
.wire-next--accordion-separated
|
||||
> .wire-next__accordion-item
|
||||
> .wire-next__accordion-heading
|
||||
.wrn-next--accordion-separated
|
||||
> .wrn-next__accordion-item
|
||||
> .wrn-next__accordion-heading
|
||||
> button,
|
||||
.wire-next--accordion-separated
|
||||
> .wire-next__accordion-item
|
||||
> .wire-next__accordion-panel
|
||||
.wire-next__accordion-content {
|
||||
.wrn-next--accordion-separated
|
||||
> .wrn-next__accordion-item
|
||||
> .wrn-next__accordion-panel
|
||||
.wrn-next__accordion-content {
|
||||
padding-inline: 1rem;
|
||||
}
|
||||
|
||||
.wire-next--accordion-flush {
|
||||
.wrn-next--accordion-flush {
|
||||
border-radius: 0;
|
||||
background: transparent;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.wire-next__accordion-panel,
|
||||
.wire-next__accordion-indicator {
|
||||
.wrn-next__accordion-panel,
|
||||
.wrn-next__accordion-indicator {
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* Shared component foundation. */
|
||||
|
||||
.wrn-component {
|
||||
--wrn-component-color: var(--wrn-color-primary);
|
||||
--wrn-component-scale: 1;
|
||||
margin: 0;
|
||||
color: var(--wrn-color-text);
|
||||
font-family: var(--wrn-font-sans, inherit);
|
||||
}
|
||||
|
||||
.wrn-component--color-primary {
|
||||
--wrn-component-color: var(--wrn-color-primary);
|
||||
}
|
||||
|
||||
.wrn-component--color-secondary {
|
||||
--wrn-component-color: var(--wrn-color-secondary);
|
||||
}
|
||||
|
||||
.wrn-component--color-success {
|
||||
--wrn-component-color: var(--wrn-color-success);
|
||||
}
|
||||
|
||||
.wrn-component--color-warning {
|
||||
--wrn-component-color: var(--wrn-color-warning);
|
||||
}
|
||||
|
||||
.wrn-component--color-danger {
|
||||
--wrn-component-color: var(--wrn-color-danger);
|
||||
}
|
||||
|
||||
.wrn-component--color-info {
|
||||
--wrn-component-color: var(--wrn-color-info);
|
||||
}
|
||||
|
||||
.wrn-component--size-xs {
|
||||
--wrn-component-scale: 0.78;
|
||||
}
|
||||
|
||||
.wrn-component--size-sm {
|
||||
--wrn-component-scale: 0.88;
|
||||
}
|
||||
|
||||
.wrn-component--size-default,
|
||||
.wrn-component--size-md {
|
||||
--wrn-component-scale: 1;
|
||||
}
|
||||
|
||||
.wrn-component--size-lg {
|
||||
--wrn-component-scale: 1.14;
|
||||
}
|
||||
|
||||
.wrn-component--size-xl {
|
||||
--wrn-component-scale: 1.28;
|
||||
}
|
||||
|
||||
.wrn-component:not(.wrn-btn) {
|
||||
font-size: calc(1em * var(--wrn-component-scale));
|
||||
}
|
||||
|
||||
.wrn-component :is(a, button, input, select, textarea):focus-visible {
|
||||
outline-color: var(--wrn-component-color);
|
||||
}
|
||||
|
||||
.wrn-component p {
|
||||
margin: 0;
|
||||
color: var(--wrn-color-muted);
|
||||
line-height: 1.6;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import SelectStyles from "../styles/SelectStyles.wrn"
|
||||
|
||||
import ComponentBaseStyles from "../styles/ComponentBaseStyles.wrn"
|
||||
|
||||
component AdvancedSelect {
|
||||
outputs {
|
||||
search(payload: { value?: string | number | boolean | null; values?: Array<string | number | boolean | null | object>; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | string | number | boolean | null)
|
||||
@@ -257,7 +255,7 @@ component AdvancedSelect {
|
||||
|
||||
view {
|
||||
<div
|
||||
class="wire-component wire-component--color-{color} wire-component--size-{size} wire-next--advanced-select {open ? 'wire-next--open' : ''} {fixed ? 'wire-next--advanced-select-fixed' : ''} {invalid ? 'wire-next--invalid' : ''} {disabled ? 'wire-next--disabled' : ''} {class}"
|
||||
class="wrn-component wrn-component--color-{color} wrn-component--size-{size} wrn-next--advanced-select {open ? 'wrn-next--open' : ''} {fixed ? 'wrn-next--advanced-select-fixed' : ''} {invalid ? 'wrn-next--invalid' : ''} {disabled ? 'wrn-next--disabled' : ''} {class}"
|
||||
data-placement="{placement}"
|
||||
data-search-mode="{searchMode}"
|
||||
data-remote="{remote ? 'true' : 'false'}"
|
||||
@@ -270,17 +268,17 @@ component AdvancedSelect {
|
||||
data-wrn-select
|
||||
@focusout="if (!event.currentTarget.contains(event.relatedTarget)) { open = false }"
|
||||
>
|
||||
<div class="wire-next__row">
|
||||
<div class="wrn-next__row">
|
||||
<label id="{name}-label" for="{name}-trigger">{label}</label>
|
||||
<small data-show="showCounter" data-text="counterText()">{counterText()}</small>
|
||||
</div>
|
||||
|
||||
<div class="wire-next__select-control">
|
||||
<div class="wrn-next__select-control">
|
||||
<button
|
||||
{...attrs}
|
||||
id="{name}-trigger"
|
||||
type="button"
|
||||
class="wire-next__select-trigger"
|
||||
class="wrn-next__select-trigger"
|
||||
role="combobox"
|
||||
aria-haspopup="listbox"
|
||||
aria-expanded="{open}"
|
||||
@@ -291,7 +289,7 @@ component AdvancedSelect {
|
||||
@click="toggle()"
|
||||
@keydown="handleKeydown(event)"
|
||||
>
|
||||
<span class="wire-next__select-value">
|
||||
<span class="wrn-next__select-value">
|
||||
<span data-show="!multiple" data-text="triggerText()">{triggerText()}</span>
|
||||
<span
|
||||
data-show="multiple && selectedTemplate === 'count' && selectedCount() > 0"
|
||||
@@ -302,7 +300,7 @@ component AdvancedSelect {
|
||||
data-text="selectedText()"
|
||||
>{selectedText()}</span>
|
||||
<span
|
||||
class="wire-next__select-tags"
|
||||
class="wrn-next__select-tags"
|
||||
aria-label="{selectedOptionsLabel}"
|
||||
data-show="multiple && selectedTemplate !== 'count' && selectedTemplate !== 'text' && selectedCount() > 0"
|
||||
>
|
||||
@@ -310,25 +308,25 @@ component AdvancedSelect {
|
||||
<span data-show="isSelected(option)">
|
||||
{#if optionTemplate === "icon" && option.icon}<i class="{option.icon}" aria-hidden="true"></i>{/if}
|
||||
{#if optionTemplate === "avatar" && option.avatar}<img src="{option.avatar}" alt="" />{/if}
|
||||
{#if optionTemplate === "color" && option.color}<i class="wire-next__color-dot" style="--option-color: {option.color}"></i>{/if}
|
||||
{#if optionTemplate === "color" && option.color}<i class="wrn-next__color-dot" style="--option-color: {option.color}"></i>{/if}
|
||||
{option.label}
|
||||
</span>
|
||||
{/each}
|
||||
</span>
|
||||
<span data-show="multiple && selectedCount() === 0">
|
||||
{#if placeholderIcon}<i class="{placeholderIcon}" aria-hidden="true"></i>{/if}
|
||||
<span class="wire-next__placeholder">{placeholder}</span>
|
||||
<span class="wrn-next__placeholder">{placeholder}</span>
|
||||
</span>
|
||||
</span>
|
||||
<span
|
||||
class="wire-next__select-chevron icon-[lucide--chevrons-up-down]"
|
||||
class="wrn-next__select-chevron icon-[lucide--chevrons-up-down]"
|
||||
aria-hidden="true"
|
||||
></span>
|
||||
</button>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
class="wire-next__clear-select"
|
||||
class="wrn-next__clear-select"
|
||||
data-show="clearable && allowEmpty && selectedCount() > 0 && !disabled"
|
||||
aria-label="{clearLabel}"
|
||||
title="{clearLabel}"
|
||||
@@ -339,14 +337,14 @@ component AdvancedSelect {
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="wire-next__select-dropdown {fixed ? 'wire-next__select-dropdown--fixed' : ''}"
|
||||
class="wrn-next__select-dropdown {fixed ? 'wrn-next__select-dropdown--fixed' : ''}"
|
||||
data-show="open"
|
||||
style="{open ? '' : 'display: none'}"
|
||||
>
|
||||
{#if searchable}
|
||||
<label class="wire-next__select-search">
|
||||
<span class="wire-visually-hidden">{searchPlaceholder}</span>
|
||||
<span class="wire-next__search-icon" aria-hidden="true">⌕</span>
|
||||
<label class="wrn-next__select-search">
|
||||
<span class="wrn-visually-hidden">{searchPlaceholder}</span>
|
||||
<span class="wrn-next__search-icon" aria-hidden="true">⌕</span>
|
||||
<input
|
||||
type="search"
|
||||
value="{query}"
|
||||
@@ -359,28 +357,28 @@ component AdvancedSelect {
|
||||
{/if}
|
||||
|
||||
<div
|
||||
class="wire-next__select-message"
|
||||
class="wrn-next__select-message"
|
||||
data-show="remote && query.length !== 0 && query.length < minSearchLength"
|
||||
>Enter at least {minSearchLength} characters.</div>
|
||||
<div class="wire-next__select-message" data-show="loading" role="status">
|
||||
<i class="wire-spinner wire-spinner--inline" aria-hidden="true"></i>
|
||||
<div class="wrn-next__select-message" data-show="loading" role="status">
|
||||
<i class="wrn-spinner wrn-spinner--inline" aria-hidden="true"></i>
|
||||
{loadingLabel}
|
||||
</div>
|
||||
<div
|
||||
id="{name}-listbox"
|
||||
class="wire-next__select-list"
|
||||
class="wrn-next__select-list"
|
||||
data-show="(!remote || (query.length === 0 && remoteAutoLoad) || query.length >= minSearchLength) && !loading"
|
||||
role="listbox"
|
||||
aria-multiselectable="{multiple}"
|
||||
>
|
||||
{#each groups as group}
|
||||
{#if visibleOptions(group.options || []).length}
|
||||
<div class="wire-next__option-group" role="group" aria-label="{group.label}">
|
||||
<div class="wire-next__group-label">{group.label}</div>
|
||||
<div class="wrn-next__option-group" role="group" aria-label="{group.label}">
|
||||
<div class="wrn-next__group-label">{group.label}</div>
|
||||
{#each group.options || [] as option}
|
||||
<button
|
||||
type="button"
|
||||
class="wire-next__select-option {isSelected(option) ? 'wire-next__select-option--selected' : ''} {optionIndex(option) === activeIndex ? 'wire-next__select-option--active' : ''}"
|
||||
class="wrn-next__select-option {isSelected(option) ? 'wrn-next__select-option--selected' : ''} {optionIndex(option) === activeIndex ? 'wrn-next__select-option--active' : ''}"
|
||||
data-option-value="{option.value}"
|
||||
data-show="matches(option)"
|
||||
role="option"
|
||||
@@ -391,10 +389,10 @@ component AdvancedSelect {
|
||||
>
|
||||
{#if optionTemplate === "icon" && option.icon}<i class="{option.icon}" aria-hidden="true"></i>{/if}
|
||||
{#if optionTemplate === "avatar" && option.avatar}<img src="{option.avatar}" alt="" />{/if}
|
||||
{#if optionTemplate === "color" && option.color}<i class="wire-next__color-dot" style="--option-color: {option.color}"></i>{/if}
|
||||
{#if optionTemplate === "color" && option.color}<i class="wrn-next__color-dot" style="--option-color: {option.color}"></i>{/if}
|
||||
<span><strong>{option.label}</strong>{#if option.description}<small>{option.description}</small>{/if}</span>
|
||||
<i
|
||||
class="wire-next__check icon-[lucide--check]"
|
||||
class="wrn-next__check icon-[lucide--check]"
|
||||
data-show="isSelected(option)"
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
@@ -407,7 +405,7 @@ component AdvancedSelect {
|
||||
{#each options as option}
|
||||
<button
|
||||
type="button"
|
||||
class="wire-next__select-option {isSelected(option) ? 'wire-next__select-option--selected' : ''} {optionIndex(option) === activeIndex ? 'wire-next__select-option--active' : ''}"
|
||||
class="wrn-next__select-option {isSelected(option) ? 'wrn-next__select-option--selected' : ''} {optionIndex(option) === activeIndex ? 'wrn-next__select-option--active' : ''}"
|
||||
data-option-value="{option.value}"
|
||||
data-show="matches(option)"
|
||||
role="option"
|
||||
@@ -418,10 +416,10 @@ component AdvancedSelect {
|
||||
>
|
||||
{#if optionTemplate === "icon" && option.icon}<i class="{option.icon}" aria-hidden="true"></i>{/if}
|
||||
{#if optionTemplate === "avatar" && option.avatar}<img src="{option.avatar}" alt="" />{/if}
|
||||
{#if optionTemplate === "color" && option.color}<i class="wire-next__color-dot" style="--option-color: {option.color}"></i>{/if}
|
||||
{#if optionTemplate === "color" && option.color}<i class="wrn-next__color-dot" style="--option-color: {option.color}"></i>{/if}
|
||||
<span><strong>{option.label}</strong>{#if option.description}<small>{option.description}</small>{/if}</span>
|
||||
<i
|
||||
class="wire-next__check icon-[lucide--check]"
|
||||
class="wrn-next__check icon-[lucide--check]"
|
||||
data-show="isSelected(option)"
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
@@ -429,16 +427,16 @@ component AdvancedSelect {
|
||||
{/each}
|
||||
|
||||
{#if !loading && !flatVisibleOptions().length}
|
||||
<div class="wire-next__select-message">{emptyLabel}</div>
|
||||
<div class="wrn-next__select-message">{emptyLabel}</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
{#if tags && query && !allOptions().some((option) => option.label.toLowerCase() === query.toLowerCase())}
|
||||
<button type="button" class="wire-next__create-option">{createLabel} “{query}”</button>
|
||||
<button type="button" class="wrn-next__create-option">{createLabel} “{query}”</button>
|
||||
{/if}
|
||||
<button
|
||||
type="button"
|
||||
class="wire-next__load-more"
|
||||
class="wrn-next__load-more"
|
||||
data-wrn-select-load-more
|
||||
data-show="infinite && hasMore"
|
||||
>{loadMoreLabel}</button>
|
||||
@@ -455,68 +453,136 @@ component AdvancedSelect {
|
||||
{#if helpText && !validationMessage}<small id="{name}-help">{helpText}</small>{/if}
|
||||
<small
|
||||
id="{name}-validation"
|
||||
class="wire-next__validation"
|
||||
class="wrn-next__validation"
|
||||
data-error="{name}"
|
||||
>{validationMessage}</small>
|
||||
</div>
|
||||
<SelectStyles hidden />
|
||||
<ComponentBaseStyles hidden />
|
||||
}
|
||||
|
||||
style {
|
||||
.wire-next__row {
|
||||
.wrn-next__row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.wire-next__select-search {
|
||||
.wrn-next__select-search {
|
||||
position: relative;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.wire-next__select-search input {
|
||||
.wrn-next__select-search input {
|
||||
padding-left: 2.25em;
|
||||
}
|
||||
|
||||
.wire-next__select-tags {
|
||||
.wrn-next__select-tags {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.4rem;
|
||||
}
|
||||
|
||||
.wire-next__select-tags > span {
|
||||
.wrn-next__select-tags > span {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.35rem;
|
||||
padding: 0.3rem 0.55rem;
|
||||
border-radius: 999px;
|
||||
color: var(--wire-component-color);
|
||||
background: color-mix(in srgb, var(--wire-component-color) 12%, transparent);
|
||||
color: var(--wrn-component-color);
|
||||
background: color-mix(in srgb, var(--wrn-component-color) 12%, transparent);
|
||||
font-size: 0.75em;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.wire-next__select-tags img {
|
||||
.wrn-next__select-tags img {
|
||||
width: 1.25rem;
|
||||
height: 1.25rem;
|
||||
border-radius: 50%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.wire-next__select-value {
|
||||
.wrn-next__select-value {
|
||||
display: flex;
|
||||
min-width: 0;
|
||||
align-items: center;
|
||||
gap: 0.55em;
|
||||
}
|
||||
|
||||
.wire-next__placeholder {
|
||||
.wrn-next__placeholder {
|
||||
overflow: hidden;
|
||||
color: var(--wire-color-muted);
|
||||
color: var(--wrn-color-muted);
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* Shared component foundation. */
|
||||
|
||||
.wrn-component {
|
||||
--wrn-component-color: var(--wrn-color-primary);
|
||||
--wrn-component-scale: 1;
|
||||
margin: 0;
|
||||
color: var(--wrn-color-text);
|
||||
font-family: var(--wrn-font-sans, inherit);
|
||||
}
|
||||
|
||||
.wrn-component--color-primary {
|
||||
--wrn-component-color: var(--wrn-color-primary);
|
||||
}
|
||||
|
||||
.wrn-component--color-secondary {
|
||||
--wrn-component-color: var(--wrn-color-secondary);
|
||||
}
|
||||
|
||||
.wrn-component--color-success {
|
||||
--wrn-component-color: var(--wrn-color-success);
|
||||
}
|
||||
|
||||
.wrn-component--color-warning {
|
||||
--wrn-component-color: var(--wrn-color-warning);
|
||||
}
|
||||
|
||||
.wrn-component--color-danger {
|
||||
--wrn-component-color: var(--wrn-color-danger);
|
||||
}
|
||||
|
||||
.wrn-component--color-info {
|
||||
--wrn-component-color: var(--wrn-color-info);
|
||||
}
|
||||
|
||||
.wrn-component--size-xs {
|
||||
--wrn-component-scale: 0.78;
|
||||
}
|
||||
|
||||
.wrn-component--size-sm {
|
||||
--wrn-component-scale: 0.88;
|
||||
}
|
||||
|
||||
.wrn-component--size-default,
|
||||
.wrn-component--size-md {
|
||||
--wrn-component-scale: 1;
|
||||
}
|
||||
|
||||
.wrn-component--size-lg {
|
||||
--wrn-component-scale: 1.14;
|
||||
}
|
||||
|
||||
.wrn-component--size-xl {
|
||||
--wrn-component-scale: 1.28;
|
||||
}
|
||||
|
||||
.wrn-component:not(.wrn-btn) {
|
||||
font-size: calc(1em * var(--wrn-component-scale));
|
||||
}
|
||||
|
||||
.wrn-component :is(a, button, input, select, textarea):focus-visible {
|
||||
outline-color: var(--wrn-component-color);
|
||||
}
|
||||
|
||||
.wrn-component p {
|
||||
margin: 0;
|
||||
color: var(--wrn-color-muted);
|
||||
line-height: 1.6;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import ComponentBaseStyles from "../styles/ComponentBaseStyles.wrn"
|
||||
|
||||
component AvatarGroup {
|
||||
outputs {
|
||||
overflow(payload: { sourceEvent?: Event; value: string | number | boolean | null | object; [key: string]: string | number | boolean | null | object } | string | number | boolean | null | object[])
|
||||
@@ -45,21 +43,21 @@ component AvatarGroup {
|
||||
view {
|
||||
<div
|
||||
{...attrs}
|
||||
class="wire-component wire-next--avatar-group {class}"
|
||||
class="wrn-component wrn-next--avatar-group {class}"
|
||||
data-wrn-avatar-group
|
||||
data-layout="{layout}"
|
||||
data-shape="{shape}"
|
||||
data-size="{size}"
|
||||
style="--wire-avatar-group-columns:{columns}; --wire-avatar-group-ring:{borderColor || 'var(--wire-color-bg)'}"
|
||||
style="--wrn-avatar-group-columns:{columns}; --wrn-avatar-group-ring:{borderColor || 'var(--wrn-color-bg)'}"
|
||||
role="group"
|
||||
aria-label="Avatar group"
|
||||
>
|
||||
<div
|
||||
class="wire-next__avatar-group-members"
|
||||
class="wrn-next__avatar-group-members"
|
||||
>
|
||||
{#each visibleMembers() as item}
|
||||
<span
|
||||
class="wire-next__avatar-group-member"
|
||||
class="wrn-next__avatar-group-member"
|
||||
data-size="{item.size || size}"
|
||||
data-shape="{item.shape || shape}"
|
||||
data-color="{item.color || color}"
|
||||
@@ -68,7 +66,7 @@ component AvatarGroup {
|
||||
aria-label="{item.name || item.alt || item.initials || 'Group member'}"
|
||||
>
|
||||
<span
|
||||
class="wire-next__avatar-group-avatar"
|
||||
class="wrn-next__avatar-group-avatar"
|
||||
>
|
||||
{#if item.src}
|
||||
<img
|
||||
@@ -93,7 +91,7 @@ component AvatarGroup {
|
||||
|
||||
{#if showTooltips && (item.tooltip || item.name)}
|
||||
<span
|
||||
class="wire-next__avatar-group-tooltip"
|
||||
class="wrn-next__avatar-group-tooltip"
|
||||
role="tooltip"
|
||||
>
|
||||
{item.tooltip || item.name}
|
||||
@@ -104,11 +102,11 @@ component AvatarGroup {
|
||||
|
||||
{#if hiddenMembers().length > 0}
|
||||
<span
|
||||
class="wire-next__avatar-group-overflow"
|
||||
class="wrn-next__avatar-group-overflow"
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
class="wire-next__avatar-group-overflow-button"
|
||||
class="wrn-next__avatar-group-overflow-button"
|
||||
aria-label="{overflowLabel}"
|
||||
aria-expanded="{overflowOpen ? 'true' : 'false'}"
|
||||
@click="toggleOverflow(event)"
|
||||
@@ -117,18 +115,18 @@ component AvatarGroup {
|
||||
</button>
|
||||
|
||||
<span
|
||||
class="wire-next__avatar-group-menu"
|
||||
class="wrn-next__avatar-group-menu"
|
||||
role="menu"
|
||||
data-show="overflowOpen"
|
||||
aria-hidden="{overflowOpen ? 'false' : 'true'}"
|
||||
>
|
||||
{#each hiddenMembers() as item}
|
||||
<span
|
||||
class="wire-next__avatar-group-menu-item"
|
||||
class="wrn-next__avatar-group-menu-item"
|
||||
role="menuitem"
|
||||
>
|
||||
<span
|
||||
class="wire-next__avatar-group-menu-avatar"
|
||||
class="wrn-next__avatar-group-menu-avatar"
|
||||
>
|
||||
{#if item.src}
|
||||
<img
|
||||
@@ -148,144 +146,143 @@ component AvatarGroup {
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
<ComponentBaseStyles hidden />
|
||||
}
|
||||
|
||||
style {
|
||||
/* --- Avatar group -------------------------------------------------------- */
|
||||
.wire-next--avatar-group {
|
||||
--wire-avatar-group-size: 3rem;
|
||||
.wrn-next--avatar-group {
|
||||
--wrn-avatar-group-size: 3rem;
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
width: fit-content;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.wire-next--avatar-group[data-size="xs"] {
|
||||
--wire-avatar-group-size: 1.75rem;
|
||||
.wrn-next--avatar-group[data-size="xs"] {
|
||||
--wrn-avatar-group-size: 1.75rem;
|
||||
}
|
||||
|
||||
.wire-next--avatar-group[data-size="sm"] {
|
||||
--wire-avatar-group-size: 2.25rem;
|
||||
.wrn-next--avatar-group[data-size="sm"] {
|
||||
--wrn-avatar-group-size: 2.25rem;
|
||||
}
|
||||
|
||||
.wire-next--avatar-group[data-size="md"],
|
||||
.wire-next--avatar-group[data-size="default"] {
|
||||
--wire-avatar-group-size: 3rem;
|
||||
.wrn-next--avatar-group[data-size="md"],
|
||||
.wrn-next--avatar-group[data-size="default"] {
|
||||
--wrn-avatar-group-size: 3rem;
|
||||
}
|
||||
|
||||
.wire-next--avatar-group[data-size="lg"] {
|
||||
--wire-avatar-group-size: 4rem;
|
||||
.wrn-next--avatar-group[data-size="lg"] {
|
||||
--wrn-avatar-group-size: 4rem;
|
||||
}
|
||||
|
||||
.wire-next--avatar-group[data-size="xl"] {
|
||||
--wire-avatar-group-size: 5rem;
|
||||
.wrn-next--avatar-group[data-size="xl"] {
|
||||
--wrn-avatar-group-size: 5rem;
|
||||
}
|
||||
|
||||
.wire-next__avatar-group-members {
|
||||
.wrn-next__avatar-group-members {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.wire-next--avatar-group[data-layout="stack"] .wire-next__avatar-group-member,
|
||||
.wire-next--avatar-group[data-layout="stack"] .wire-next__avatar-group-overflow {
|
||||
margin-left: calc(var(--wire-avatar-group-size) * -0.22);
|
||||
.wrn-next--avatar-group[data-layout="stack"] .wrn-next__avatar-group-member,
|
||||
.wrn-next--avatar-group[data-layout="stack"] .wrn-next__avatar-group-overflow {
|
||||
margin-left: calc(var(--wrn-avatar-group-size) * -0.22);
|
||||
}
|
||||
|
||||
.wire-next--avatar-group[data-layout="stack"] :first-child {
|
||||
.wrn-next--avatar-group[data-layout="stack"] :first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.wire-next--avatar-group[data-layout="grid"] .wire-next__avatar-group-members {
|
||||
.wrn-next--avatar-group[data-layout="grid"] .wrn-next__avatar-group-members {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(var(--wire-avatar-group-columns), var(--wire-avatar-group-size));
|
||||
grid-template-columns: repeat(var(--wrn-avatar-group-columns), var(--wrn-avatar-group-size));
|
||||
gap: 0.65rem;
|
||||
}
|
||||
|
||||
.wire-next__avatar-group-member,
|
||||
.wire-next__avatar-group-overflow {
|
||||
--wire-avatar-group-color: var(--wire-color-primary);
|
||||
.wrn-next__avatar-group-member,
|
||||
.wrn-next__avatar-group-overflow {
|
||||
--wrn-avatar-group-color: var(--wrn-color-primary);
|
||||
position: relative;
|
||||
display: inline-grid;
|
||||
width: var(--wire-avatar-group-size);
|
||||
height: var(--wire-avatar-group-size);
|
||||
width: var(--wrn-avatar-group-size);
|
||||
height: var(--wrn-avatar-group-size);
|
||||
flex: none;
|
||||
place-items: center;
|
||||
border-radius: 999px;
|
||||
outline: none;
|
||||
transition:
|
||||
z-index var(--wire-motion-fast),
|
||||
transform var(--wire-motion-base) var(--wire-ease-emphasized);
|
||||
z-index var(--wrn-motion-fast),
|
||||
transform var(--wrn-motion-base) var(--wrn-ease-emphasized);
|
||||
}
|
||||
|
||||
.wire-next__avatar-group-member[data-color="secondary"] {
|
||||
--wire-avatar-group-color: #737373;
|
||||
.wrn-next__avatar-group-member[data-color="secondary"] {
|
||||
--wrn-avatar-group-color: #737373;
|
||||
}
|
||||
|
||||
.wire-next__avatar-group-member[data-color="success"] {
|
||||
--wire-avatar-group-color: var(--wire-color-success);
|
||||
.wrn-next__avatar-group-member[data-color="success"] {
|
||||
--wrn-avatar-group-color: var(--wrn-color-success);
|
||||
}
|
||||
|
||||
.wire-next__avatar-group-member[data-color="info"] {
|
||||
--wire-avatar-group-color: var(--wire-color-info);
|
||||
.wrn-next__avatar-group-member[data-color="info"] {
|
||||
--wrn-avatar-group-color: var(--wrn-color-info);
|
||||
}
|
||||
|
||||
.wire-next__avatar-group-member[data-color="warning"] {
|
||||
--wire-avatar-group-color: var(--wire-color-warning);
|
||||
.wrn-next__avatar-group-member[data-color="warning"] {
|
||||
--wrn-avatar-group-color: var(--wrn-color-warning);
|
||||
}
|
||||
|
||||
.wire-next__avatar-group-member[data-color="danger"] {
|
||||
--wire-avatar-group-color: var(--wire-color-danger);
|
||||
.wrn-next__avatar-group-member[data-color="danger"] {
|
||||
--wrn-avatar-group-color: var(--wrn-color-danger);
|
||||
}
|
||||
|
||||
.wire-next__avatar-group-member[data-shape="rounded"] {
|
||||
border-radius: calc(var(--wire-radius-sm, 0.5rem) * 0.72);
|
||||
.wrn-next__avatar-group-member[data-shape="rounded"] {
|
||||
border-radius: calc(var(--wrn-radius-sm, 0.5rem) * 0.72);
|
||||
}
|
||||
|
||||
.wire-next__avatar-group-avatar,
|
||||
.wire-next__avatar-group-overflow-button {
|
||||
.wrn-next__avatar-group-avatar,
|
||||
.wrn-next__avatar-group-overflow-button {
|
||||
display: grid;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
place-items: center;
|
||||
color: white;
|
||||
border: 2px solid var(--wire-avatar-group-ring);
|
||||
border: 2px solid var(--wrn-avatar-group-ring);
|
||||
border-radius: inherit;
|
||||
background: var(--wire-avatar-group-color, var(--wire-color-primary));
|
||||
background: var(--wrn-avatar-group-color, var(--wrn-color-primary));
|
||||
box-shadow: 0 5px 14px rgb(0 0 0 / 0.16);
|
||||
font: inherit;
|
||||
font-size: calc(var(--wire-avatar-group-size) * 0.3);
|
||||
font-size: calc(var(--wrn-avatar-group-size) * 0.3);
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.wire-next__avatar-group-avatar img,
|
||||
.wire-next__avatar-group-menu-avatar img {
|
||||
.wrn-next__avatar-group-avatar img,
|
||||
.wrn-next__avatar-group-menu-avatar img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.wire-next__avatar-group-overflow-button {
|
||||
.wrn-next__avatar-group-overflow-button {
|
||||
cursor: pointer;
|
||||
color: var(--wire-color-text);
|
||||
background: var(--wire-color-surface-2);
|
||||
color: var(--wrn-color-text);
|
||||
background: var(--wrn-color-surface-2);
|
||||
}
|
||||
|
||||
.wire-next__avatar-group-member:hover,
|
||||
.wire-next__avatar-group-member:focus-visible,
|
||||
.wire-next__avatar-group-overflow:focus-within {
|
||||
.wrn-next__avatar-group-member:hover,
|
||||
.wrn-next__avatar-group-member:focus-visible,
|
||||
.wrn-next__avatar-group-overflow:focus-within {
|
||||
z-index: 5;
|
||||
transform: translateY(-3px);
|
||||
}
|
||||
|
||||
.wire-next__avatar-group-member:focus-visible,
|
||||
.wire-next__avatar-group-overflow-button:focus-visible {
|
||||
outline: 2px solid var(--wire-color-primary);
|
||||
.wrn-next__avatar-group-member:focus-visible,
|
||||
.wrn-next__avatar-group-overflow-button:focus-visible {
|
||||
outline: 2px solid var(--wrn-color-primary);
|
||||
outline-offset: 3px;
|
||||
}
|
||||
|
||||
.wire-next__avatar-group-tooltip {
|
||||
.wrn-next__avatar-group-tooltip {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
bottom: calc(100% + 0.65rem);
|
||||
@@ -293,9 +290,9 @@ component AvatarGroup {
|
||||
width: max-content;
|
||||
max-width: 14rem;
|
||||
padding: 0.4rem 0.6rem;
|
||||
color: var(--wire-color-bg);
|
||||
color: var(--wrn-color-bg);
|
||||
border-radius: 0.4rem;
|
||||
background: var(--wire-color-text);
|
||||
background: var(--wrn-color-text);
|
||||
box-shadow: 0 8px 22px rgb(0 0 0 / 0.22);
|
||||
font-size: 0.75rem;
|
||||
font-weight: 650;
|
||||
@@ -303,17 +300,17 @@ component AvatarGroup {
|
||||
opacity: 0;
|
||||
transform: translate(-50%, 0.25rem);
|
||||
transition:
|
||||
opacity var(--wire-motion-fast),
|
||||
transform var(--wire-motion-fast);
|
||||
opacity var(--wrn-motion-fast),
|
||||
transform var(--wrn-motion-fast);
|
||||
}
|
||||
|
||||
.wire-next__avatar-group-member:hover .wire-next__avatar-group-tooltip,
|
||||
.wire-next__avatar-group-member:focus-visible .wire-next__avatar-group-tooltip {
|
||||
.wrn-next__avatar-group-member:hover .wrn-next__avatar-group-tooltip,
|
||||
.wrn-next__avatar-group-member:focus-visible .wrn-next__avatar-group-tooltip {
|
||||
opacity: 1;
|
||||
transform: translate(-50%, 0);
|
||||
}
|
||||
|
||||
.wire-next__avatar-group-menu {
|
||||
.wrn-next__avatar-group-menu {
|
||||
position: absolute;
|
||||
top: calc(100% + 0.65rem);
|
||||
right: 0;
|
||||
@@ -323,14 +320,14 @@ component AvatarGroup {
|
||||
min-width: 12rem;
|
||||
gap: 0.25rem;
|
||||
padding: 0.45rem;
|
||||
color: var(--wire-color-text);
|
||||
border: 1px solid var(--wire-color-border);
|
||||
border-radius: var(--wire-radius-sm, 0.5rem);
|
||||
background: var(--wire-color-surface);
|
||||
color: var(--wrn-color-text);
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: var(--wrn-radius-sm, 0.5rem);
|
||||
background: var(--wrn-color-surface);
|
||||
box-shadow: 0 16px 38px rgb(0 0 0 / 0.22);
|
||||
}
|
||||
|
||||
.wire-next__avatar-group-menu-item {
|
||||
.wrn-next__avatar-group-menu-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.6rem;
|
||||
@@ -339,11 +336,11 @@ component AvatarGroup {
|
||||
font-size: 0.82rem;
|
||||
}
|
||||
|
||||
.wire-next__avatar-group-menu-item:hover {
|
||||
background: var(--wire-color-surface-2);
|
||||
.wrn-next__avatar-group-menu-item:hover {
|
||||
background: var(--wrn-color-surface-2);
|
||||
}
|
||||
|
||||
.wire-next__avatar-group-menu-avatar {
|
||||
.wrn-next__avatar-group-menu-avatar {
|
||||
display: grid;
|
||||
width: 1.75rem;
|
||||
height: 1.75rem;
|
||||
@@ -351,9 +348,78 @@ component AvatarGroup {
|
||||
flex: none;
|
||||
place-items: center;
|
||||
border-radius: 999px;
|
||||
background: var(--wire-color-surface-2);
|
||||
background: var(--wrn-color-surface-2);
|
||||
font-size: 0.65rem;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
/* Shared component foundation. */
|
||||
|
||||
.wrn-component {
|
||||
--wrn-component-color: var(--wrn-color-primary);
|
||||
--wrn-component-scale: 1;
|
||||
margin: 0;
|
||||
color: var(--wrn-color-text);
|
||||
font-family: var(--wrn-font-sans, inherit);
|
||||
}
|
||||
|
||||
.wrn-component--color-primary {
|
||||
--wrn-component-color: var(--wrn-color-primary);
|
||||
}
|
||||
|
||||
.wrn-component--color-secondary {
|
||||
--wrn-component-color: var(--wrn-color-secondary);
|
||||
}
|
||||
|
||||
.wrn-component--color-success {
|
||||
--wrn-component-color: var(--wrn-color-success);
|
||||
}
|
||||
|
||||
.wrn-component--color-warning {
|
||||
--wrn-component-color: var(--wrn-color-warning);
|
||||
}
|
||||
|
||||
.wrn-component--color-danger {
|
||||
--wrn-component-color: var(--wrn-color-danger);
|
||||
}
|
||||
|
||||
.wrn-component--color-info {
|
||||
--wrn-component-color: var(--wrn-color-info);
|
||||
}
|
||||
|
||||
.wrn-component--size-xs {
|
||||
--wrn-component-scale: 0.78;
|
||||
}
|
||||
|
||||
.wrn-component--size-sm {
|
||||
--wrn-component-scale: 0.88;
|
||||
}
|
||||
|
||||
.wrn-component--size-default,
|
||||
.wrn-component--size-md {
|
||||
--wrn-component-scale: 1;
|
||||
}
|
||||
|
||||
.wrn-component--size-lg {
|
||||
--wrn-component-scale: 1.14;
|
||||
}
|
||||
|
||||
.wrn-component--size-xl {
|
||||
--wrn-component-scale: 1.28;
|
||||
}
|
||||
|
||||
.wrn-component:not(.wrn-btn) {
|
||||
font-size: calc(1em * var(--wrn-component-scale));
|
||||
}
|
||||
|
||||
.wrn-component :is(a, button, input, select, textarea):focus-visible {
|
||||
outline-color: var(--wrn-component-color);
|
||||
}
|
||||
|
||||
.wrn-component p {
|
||||
margin: 0;
|
||||
color: var(--wrn-color-muted);
|
||||
line-height: 1.6;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import ComponentBaseStyles from "../styles/ComponentBaseStyles.wrn"
|
||||
|
||||
component Blockquote {
|
||||
props {
|
||||
quote: string = "I just wanted to say that I'm very happy with my purchase so far. The documentation is outstanding - clear and detailed."
|
||||
@@ -20,7 +18,7 @@ component Blockquote {
|
||||
view {
|
||||
<figure
|
||||
{...attrs}
|
||||
class="wire-component wire-next--blockquote wire-component--color-{color} wire-component--size-{size} {class}"
|
||||
class="wrn-component wrn-next--blockquote wrn-component--color-{color} wrn-component--size-{size} {class}"
|
||||
data-size="{size}"
|
||||
data-color="{color}"
|
||||
data-align="{align}"
|
||||
@@ -29,10 +27,10 @@ component Blockquote {
|
||||
>
|
||||
<blockquote cite="{citationUrl}">
|
||||
{#if quoteMark}
|
||||
<span class="wire-next__blockquote-mark" aria-hidden="true">“</span>
|
||||
<span class="wrn-next__blockquote-mark" aria-hidden="true">“</span>
|
||||
{/if}
|
||||
|
||||
<div class="wire-next__blockquote-copy">
|
||||
<div class="wrn-next__blockquote-copy">
|
||||
{#if quote}
|
||||
<p>{quote}</p>
|
||||
{:else}
|
||||
@@ -42,17 +40,17 @@ component Blockquote {
|
||||
</blockquote>
|
||||
|
||||
{#if citation || citationTitle || avatarSrc}
|
||||
<figcaption class="wire-next__blockquote-citation">
|
||||
<figcaption class="wrn-next__blockquote-citation">
|
||||
{#if avatarSrc}
|
||||
<img
|
||||
class="wire-next__blockquote-avatar"
|
||||
class="wrn-next__blockquote-avatar"
|
||||
src="{avatarSrc}"
|
||||
alt="{avatarAlt}"
|
||||
loading="lazy"
|
||||
/>
|
||||
{/if}
|
||||
|
||||
<span class="wire-next__blockquote-attribution">
|
||||
<span class="wrn-next__blockquote-attribution">
|
||||
{#if citation}
|
||||
{#if citationUrl}
|
||||
<cite><a href="{citationUrl}">{citation}</a></cite>
|
||||
@@ -65,63 +63,62 @@ component Blockquote {
|
||||
</figcaption>
|
||||
{/if}
|
||||
</figure>
|
||||
<ComponentBaseStyles hidden />
|
||||
}
|
||||
|
||||
style {
|
||||
.wire-next--blockquote {
|
||||
--wire-blockquote-color: var(--wire-component-color, var(--wire-color-primary));
|
||||
--wire-blockquote-font-size: 1.125rem;
|
||||
--wire-blockquote-mark-size: 4.25rem;
|
||||
.wrn-next--blockquote {
|
||||
--wrn-blockquote-color: var(--wrn-component-color, var(--wrn-color-primary));
|
||||
--wrn-blockquote-font-size: 1.125rem;
|
||||
--wrn-blockquote-mark-size: 4.25rem;
|
||||
display: grid;
|
||||
gap: 1.25rem;
|
||||
width: 100%;
|
||||
color: var(--wire-color-text);
|
||||
color: var(--wrn-color-text);
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.wire-next--blockquote[data-size="xs"] {
|
||||
--wire-blockquote-font-size: 0.875rem;
|
||||
--wire-blockquote-mark-size: 3rem;
|
||||
.wrn-next--blockquote[data-size="xs"] {
|
||||
--wrn-blockquote-font-size: 0.875rem;
|
||||
--wrn-blockquote-mark-size: 3rem;
|
||||
}
|
||||
|
||||
.wire-next--blockquote[data-size="sm"] {
|
||||
--wire-blockquote-font-size: 1rem;
|
||||
--wire-blockquote-mark-size: 3.5rem;
|
||||
.wrn-next--blockquote[data-size="sm"] {
|
||||
--wrn-blockquote-font-size: 1rem;
|
||||
--wrn-blockquote-mark-size: 3.5rem;
|
||||
}
|
||||
|
||||
.wire-next--blockquote[data-size="md"],
|
||||
.wire-next--blockquote[data-size="default"] {
|
||||
--wire-blockquote-font-size: 1.125rem;
|
||||
.wrn-next--blockquote[data-size="md"],
|
||||
.wrn-next--blockquote[data-size="default"] {
|
||||
--wrn-blockquote-font-size: 1.125rem;
|
||||
}
|
||||
|
||||
.wire-next--blockquote[data-size="lg"] {
|
||||
--wire-blockquote-font-size: clamp(1.35rem, 2.4vw, 1.75rem);
|
||||
--wire-blockquote-mark-size: 5rem;
|
||||
.wrn-next--blockquote[data-size="lg"] {
|
||||
--wrn-blockquote-font-size: clamp(1.35rem, 2.4vw, 1.75rem);
|
||||
--wrn-blockquote-mark-size: 5rem;
|
||||
}
|
||||
|
||||
.wire-next--blockquote[data-size="xl"] {
|
||||
--wire-blockquote-font-size: clamp(1.65rem, 3vw, 2.25rem);
|
||||
--wire-blockquote-mark-size: 5.75rem;
|
||||
.wrn-next--blockquote[data-size="xl"] {
|
||||
--wrn-blockquote-font-size: clamp(1.65rem, 3vw, 2.25rem);
|
||||
--wrn-blockquote-mark-size: 5.75rem;
|
||||
}
|
||||
|
||||
.wire-next--blockquote > blockquote {
|
||||
.wrn-next--blockquote > blockquote {
|
||||
position: relative;
|
||||
display: block;
|
||||
min-width: 0;
|
||||
margin: 0;
|
||||
padding-top: calc(var(--wire-blockquote-mark-size) * 0.78);
|
||||
padding-top: calc(var(--wrn-blockquote-mark-size) * 0.78);
|
||||
}
|
||||
|
||||
.wire-next__blockquote-mark {
|
||||
.wrn-next__blockquote-mark {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
inset-inline: 0;
|
||||
display: block;
|
||||
width: 100%;
|
||||
color: color-mix(in srgb, var(--wire-blockquote-color) 28%, var(--wire-color-text));
|
||||
color: color-mix(in srgb, var(--wrn-blockquote-color) 28%, var(--wrn-color-text));
|
||||
font-family: Georgia, "Times New Roman", serif;
|
||||
font-size: var(--wire-blockquote-mark-size);
|
||||
font-size: var(--wrn-blockquote-mark-size);
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
line-height: 0.8;
|
||||
@@ -129,145 +126,214 @@ component Blockquote {
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.wire-next__blockquote-copy {
|
||||
.wrn-next__blockquote-copy {
|
||||
min-width: 0;
|
||||
font-family: Georgia, "Times New Roman", serif;
|
||||
font-size: var(--wire-blockquote-font-size);
|
||||
font-size: var(--wrn-blockquote-font-size);
|
||||
line-height: 1.55;
|
||||
text-wrap: pretty;
|
||||
}
|
||||
|
||||
.wire-next--blockquote[data-italic="true"] .wire-next__blockquote-copy {
|
||||
.wrn-next--blockquote[data-italic="true"] .wrn-next__blockquote-copy {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.wire-next__blockquote-copy > :first-child {
|
||||
.wrn-next__blockquote-copy > :first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.wire-next__blockquote-copy > :last-child {
|
||||
.wrn-next__blockquote-copy > :last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.wire-next__blockquote-citation {
|
||||
.wrn-next__blockquote-citation {
|
||||
display: inline-flex;
|
||||
gap: 0.75rem;
|
||||
align-items: center;
|
||||
width: fit-content;
|
||||
margin-inline-start: 0;
|
||||
color: var(--wire-color-muted);
|
||||
color: var(--wrn-color-muted);
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.35;
|
||||
}
|
||||
|
||||
.wire-next__blockquote-avatar {
|
||||
.wrn-next__blockquote-avatar {
|
||||
width: 2.5rem;
|
||||
height: 2.5rem;
|
||||
flex: 0 0 auto;
|
||||
border: 2px solid color-mix(in srgb, var(--wire-blockquote-color) 35%, transparent);
|
||||
border: 2px solid color-mix(in srgb, var(--wrn-blockquote-color) 35%, transparent);
|
||||
border-radius: 999px;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.wire-next__blockquote-attribution {
|
||||
.wrn-next__blockquote-attribution {
|
||||
display: grid;
|
||||
gap: 0.15rem;
|
||||
}
|
||||
|
||||
.wire-next__blockquote-attribution cite {
|
||||
color: var(--wire-color-text);
|
||||
.wrn-next__blockquote-attribution cite {
|
||||
color: var(--wrn-color-text);
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.wire-next__blockquote-attribution a {
|
||||
.wrn-next__blockquote-attribution a {
|
||||
color: inherit;
|
||||
text-decoration-color: color-mix(in srgb, var(--wire-blockquote-color) 55%, transparent);
|
||||
text-decoration-color: color-mix(in srgb, var(--wrn-blockquote-color) 55%, transparent);
|
||||
text-underline-offset: 0.2em;
|
||||
}
|
||||
|
||||
.wire-next__blockquote-attribution a:hover {
|
||||
color: var(--wire-blockquote-color);
|
||||
.wrn-next__blockquote-attribution a:hover {
|
||||
color: var(--wrn-blockquote-color);
|
||||
}
|
||||
|
||||
.wire-next--blockquote[data-align="center"] {
|
||||
.wrn-next--blockquote[data-align="center"] {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.wire-next--blockquote[data-align="right"],
|
||||
.wire-next--blockquote[data-align="end"] {
|
||||
.wrn-next--blockquote[data-align="right"],
|
||||
.wrn-next--blockquote[data-align="end"] {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.wire-next--blockquote[data-align="center"] > blockquote,
|
||||
.wire-next--blockquote[data-align="right"] > blockquote,
|
||||
.wire-next--blockquote[data-align="end"] > blockquote {
|
||||
.wrn-next--blockquote[data-align="center"] > blockquote,
|
||||
.wrn-next--blockquote[data-align="right"] > blockquote,
|
||||
.wrn-next--blockquote[data-align="end"] > blockquote {
|
||||
text-align: inherit;
|
||||
}
|
||||
|
||||
.wire-next--blockquote[data-align="center"] .wire-next__blockquote-mark {
|
||||
.wrn-next--blockquote[data-align="center"] .wrn-next__blockquote-mark {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.wire-next--blockquote[data-align="right"] .wire-next__blockquote-mark,
|
||||
.wire-next--blockquote[data-align="end"] .wire-next__blockquote-mark {
|
||||
.wrn-next--blockquote[data-align="right"] .wrn-next__blockquote-mark,
|
||||
.wrn-next--blockquote[data-align="end"] .wrn-next__blockquote-mark {
|
||||
text-align: end;
|
||||
}
|
||||
|
||||
.wire-next--blockquote[data-align="center"] .wire-next__blockquote-citation {
|
||||
.wrn-next--blockquote[data-align="center"] .wrn-next__blockquote-citation {
|
||||
margin-inline: auto;
|
||||
}
|
||||
|
||||
.wire-next--blockquote[data-align="right"] .wire-next__blockquote-citation,
|
||||
.wire-next--blockquote[data-align="end"] .wire-next__blockquote-citation {
|
||||
.wrn-next--blockquote[data-align="right"] .wrn-next__blockquote-citation,
|
||||
.wrn-next--blockquote[data-align="end"] .wrn-next__blockquote-citation {
|
||||
margin-inline-start: auto;
|
||||
}
|
||||
|
||||
.wire-next--blockquote[data-variant="bordered"],
|
||||
.wire-next--blockquote[data-variant="border"],
|
||||
.wire-next--blockquote[data-variant="left-border"] {
|
||||
.wrn-next--blockquote[data-variant="bordered"],
|
||||
.wrn-next--blockquote[data-variant="border"],
|
||||
.wrn-next--blockquote[data-variant="left-border"] {
|
||||
padding-inline-start: 1.5rem;
|
||||
border-inline-start: 4px solid var(--wire-blockquote-color);
|
||||
border-inline-start: 4px solid var(--wrn-blockquote-color);
|
||||
}
|
||||
|
||||
.wire-next--blockquote[data-variant="bordered"] .wire-next__blockquote-mark,
|
||||
.wire-next--blockquote[data-variant="border"] .wire-next__blockquote-mark,
|
||||
.wire-next--blockquote[data-variant="left-border"] .wire-next__blockquote-mark {
|
||||
.wrn-next--blockquote[data-variant="bordered"] .wrn-next__blockquote-mark,
|
||||
.wrn-next--blockquote[data-variant="border"] .wrn-next__blockquote-mark,
|
||||
.wrn-next--blockquote[data-variant="left-border"] .wrn-next__blockquote-mark {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.wire-next--blockquote[data-variant="bordered"] > blockquote,
|
||||
.wire-next--blockquote[data-variant="border"] > blockquote,
|
||||
.wire-next--blockquote[data-variant="left-border"] > blockquote {
|
||||
.wrn-next--blockquote[data-variant="bordered"] > blockquote,
|
||||
.wrn-next--blockquote[data-variant="border"] > blockquote,
|
||||
.wrn-next--blockquote[data-variant="left-border"] > blockquote {
|
||||
display: block;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.wire-next--blockquote[data-variant="bordered"] .wire-next__blockquote-copy,
|
||||
.wire-next--blockquote[data-variant="border"] .wire-next__blockquote-copy,
|
||||
.wire-next--blockquote[data-variant="left-border"] .wire-next__blockquote-copy {
|
||||
.wrn-next--blockquote[data-variant="bordered"] .wrn-next__blockquote-copy,
|
||||
.wrn-next--blockquote[data-variant="border"] .wrn-next__blockquote-copy,
|
||||
.wrn-next--blockquote[data-variant="left-border"] .wrn-next__blockquote-copy {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.wire-next--blockquote[data-variant="bordered"] .wire-next__blockquote-citation,
|
||||
.wire-next--blockquote[data-variant="border"] .wire-next__blockquote-citation,
|
||||
.wire-next--blockquote[data-variant="left-border"] .wire-next__blockquote-citation {
|
||||
.wrn-next--blockquote[data-variant="bordered"] .wrn-next__blockquote-citation,
|
||||
.wrn-next--blockquote[data-variant="border"] .wrn-next__blockquote-citation,
|
||||
.wrn-next--blockquote[data-variant="left-border"] .wrn-next__blockquote-citation {
|
||||
margin-inline-start: 0;
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.wire-next--blockquote {
|
||||
--wire-blockquote-mark-size: 3.25rem;
|
||||
--wire-blockquote-font-size: 1rem;
|
||||
.wrn-next--blockquote {
|
||||
--wrn-blockquote-mark-size: 3.25rem;
|
||||
--wrn-blockquote-font-size: 1rem;
|
||||
gap: 1rem;
|
||||
}
|
||||
.wire-next--blockquote[data-size="lg"],
|
||||
.wire-next--blockquote[data-size="xl"] {
|
||||
--wire-blockquote-font-size: 1.25rem;
|
||||
.wrn-next--blockquote[data-size="lg"],
|
||||
.wrn-next--blockquote[data-size="xl"] {
|
||||
--wrn-blockquote-font-size: 1.25rem;
|
||||
}
|
||||
.wire-next__blockquote-citation {
|
||||
.wrn-next__blockquote-citation {
|
||||
margin-inline-start: 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Shared component foundation. */
|
||||
|
||||
.wrn-component {
|
||||
--wrn-component-color: var(--wrn-color-primary);
|
||||
--wrn-component-scale: 1;
|
||||
margin: 0;
|
||||
color: var(--wrn-color-text);
|
||||
font-family: var(--wrn-font-sans, inherit);
|
||||
}
|
||||
|
||||
.wrn-component--color-primary {
|
||||
--wrn-component-color: var(--wrn-color-primary);
|
||||
}
|
||||
|
||||
.wrn-component--color-secondary {
|
||||
--wrn-component-color: var(--wrn-color-secondary);
|
||||
}
|
||||
|
||||
.wrn-component--color-success {
|
||||
--wrn-component-color: var(--wrn-color-success);
|
||||
}
|
||||
|
||||
.wrn-component--color-warning {
|
||||
--wrn-component-color: var(--wrn-color-warning);
|
||||
}
|
||||
|
||||
.wrn-component--color-danger {
|
||||
--wrn-component-color: var(--wrn-color-danger);
|
||||
}
|
||||
|
||||
.wrn-component--color-info {
|
||||
--wrn-component-color: var(--wrn-color-info);
|
||||
}
|
||||
|
||||
.wrn-component--size-xs {
|
||||
--wrn-component-scale: 0.78;
|
||||
}
|
||||
|
||||
.wrn-component--size-sm {
|
||||
--wrn-component-scale: 0.88;
|
||||
}
|
||||
|
||||
.wrn-component--size-default,
|
||||
.wrn-component--size-md {
|
||||
--wrn-component-scale: 1;
|
||||
}
|
||||
|
||||
.wrn-component--size-lg {
|
||||
--wrn-component-scale: 1.14;
|
||||
}
|
||||
|
||||
.wrn-component--size-xl {
|
||||
--wrn-component-scale: 1.28;
|
||||
}
|
||||
|
||||
.wrn-component:not(.wrn-btn) {
|
||||
font-size: calc(1em * var(--wrn-component-scale));
|
||||
}
|
||||
|
||||
.wrn-component :is(a, button, input, select, textarea):focus-visible {
|
||||
outline-color: var(--wrn-component-color);
|
||||
}
|
||||
|
||||
.wrn-component p {
|
||||
margin: 0;
|
||||
color: var(--wrn-color-muted);
|
||||
line-height: 1.6;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,34 +26,34 @@ label: string = "Breadcrumb"
|
||||
data-color='{color}'
|
||||
data-variant='{variant}'
|
||||
aria-label='{label}'
|
||||
class='wire-breadcrumb {class}'
|
||||
class='wrn-breadcrumb {class}'
|
||||
>
|
||||
<ol class="wire-breadcrumb__list">
|
||||
<ol class="wrn-breadcrumb__list">
|
||||
{#if showHome}
|
||||
<li class="wire-breadcrumb__item wire-breadcrumb__item--home">
|
||||
<li class="wrn-breadcrumb__item wrn-breadcrumb__item--home">
|
||||
<a
|
||||
href='{homeHref || "/"}'
|
||||
class="wire-breadcrumb__link wire-breadcrumb__home"
|
||||
class="wrn-breadcrumb__link wrn-breadcrumb__home"
|
||||
@click='output.select({ item: { label: homeLabel, href: homeHref || "/", value: "home" }, itemIndex: -1 })'
|
||||
>
|
||||
{#if homeIcon === "icon-[lucide--house]"}
|
||||
<span class="icon-[lucide--house] wire-breadcrumb__icon" aria-hidden="true"></span>
|
||||
<span class="icon-[lucide--house] wrn-breadcrumb__icon" aria-hidden="true"></span>
|
||||
{:else if homeIcon}
|
||||
<span class='{homeIcon} wire-breadcrumb__icon' aria-hidden="true"></span>
|
||||
<span class='{homeIcon} wrn-breadcrumb__icon' aria-hidden="true"></span>
|
||||
{/if}
|
||||
|
||||
<span class="wire-breadcrumb__home-label">{homeLabel}</span>
|
||||
<span class="wrn-breadcrumb__home-label">{homeLabel}</span>
|
||||
</a>
|
||||
</li>
|
||||
{/if}
|
||||
|
||||
{#each items as item, itemIndex}
|
||||
<li
|
||||
class="wire-breadcrumb__item"
|
||||
class="wrn-breadcrumb__item"
|
||||
data-current='{item.active || item.current || (active && active === (item.value || item.label || item.title)) || (!active && itemIndex === items.length - 1) ? "true" : "false"}'
|
||||
>
|
||||
{#if showHome || itemIndex > 0}
|
||||
<span class="wire-breadcrumb__separator" aria-hidden="true">
|
||||
<span class="wrn-breadcrumb__separator" aria-hidden="true">
|
||||
{#if separator === "slash"}
|
||||
<span>/</span>
|
||||
{:else if separator === "dot"}
|
||||
@@ -61,7 +61,7 @@ label: string = "Breadcrumb"
|
||||
{:else if separator === "arrow"}
|
||||
<span>→</span>
|
||||
{:else}
|
||||
<span class="icon-[lucide--chevron-right] wire-breadcrumb__separator-icon"></span>
|
||||
<span class="icon-[lucide--chevron-right] wrn-breadcrumb__separator-icon"></span>
|
||||
{/if}
|
||||
</span>
|
||||
{/if}
|
||||
@@ -71,30 +71,30 @@ label: string = "Breadcrumb"
|
||||
href='{item.href}'
|
||||
target='{item.target || ""}'
|
||||
rel='{item.external ? "noopener noreferrer" : (item.rel || "")}'
|
||||
class="wire-breadcrumb__link"
|
||||
class="wrn-breadcrumb__link"
|
||||
@click='output.select({ item: item, itemIndex: itemIndex })'
|
||||
>
|
||||
{#if item.icon}
|
||||
<span class='{item.icon} wire-breadcrumb__icon' aria-hidden="true"></span>
|
||||
<span class='{item.icon} wrn-breadcrumb__icon' aria-hidden="true"></span>
|
||||
{/if}
|
||||
|
||||
<span class="wire-breadcrumb__label">{item.label || item.title}</span>
|
||||
<span class="wrn-breadcrumb__label">{item.label || item.title}</span>
|
||||
|
||||
{#if item.external}
|
||||
<span class="icon-[lucide--arrow-up-right] wire-breadcrumb__external" aria-hidden="true"></span>
|
||||
<span class="icon-[lucide--arrow-up-right] wrn-breadcrumb__external" aria-hidden="true"></span>
|
||||
{/if}
|
||||
</a>
|
||||
{:else}
|
||||
<span
|
||||
class="wire-breadcrumb__current"
|
||||
class="wrn-breadcrumb__current"
|
||||
aria-current='{item.active || item.current || (active && active === (item.value || item.label || item.title)) || (!active && itemIndex === items.length - 1) ? "page" : "false"}'
|
||||
aria-disabled='{item.disabled ? "true" : "false"}'
|
||||
>
|
||||
{#if item.icon}
|
||||
<span class='{item.icon} wire-breadcrumb__icon' aria-hidden="true"></span>
|
||||
<span class='{item.icon} wrn-breadcrumb__icon' aria-hidden="true"></span>
|
||||
{/if}
|
||||
|
||||
<span class="wire-breadcrumb__label">{item.label || item.title}</span>
|
||||
<span class="wrn-breadcrumb__label">{item.label || item.title}</span>
|
||||
</span>
|
||||
{/if}
|
||||
</li>
|
||||
@@ -104,52 +104,52 @@ label: string = "Breadcrumb"
|
||||
}
|
||||
|
||||
style {
|
||||
.wire-breadcrumb {
|
||||
--breadcrumb-accent: var(--wire-color-primary);
|
||||
--breadcrumb-soft: var(--wire-color-primary-soft);
|
||||
--breadcrumb-muted: var(--wire-color-primary-muted);
|
||||
--breadcrumb-text: var(--wire-color-primary-text);
|
||||
.wrn-breadcrumb {
|
||||
--breadcrumb-accent: var(--wrn-color-primary);
|
||||
--breadcrumb-soft: var(--wrn-color-primary-soft);
|
||||
--breadcrumb-muted: var(--wrn-color-primary-muted);
|
||||
--breadcrumb-text: var(--wrn-color-primary-text);
|
||||
|
||||
min-width: 0;
|
||||
color: var(--wire-color-text-muted);
|
||||
color: var(--wrn-color-text-muted);
|
||||
}
|
||||
|
||||
.wire-breadcrumb[data-color="secondary"] {
|
||||
--breadcrumb-accent: var(--wire-color-secondary);
|
||||
--breadcrumb-soft: var(--wire-color-secondary-soft);
|
||||
--breadcrumb-muted: var(--wire-color-secondary-muted);
|
||||
--breadcrumb-text: var(--wire-color-secondary-text);
|
||||
.wrn-breadcrumb[data-color="secondary"] {
|
||||
--breadcrumb-accent: var(--wrn-color-secondary);
|
||||
--breadcrumb-soft: var(--wrn-color-secondary-soft);
|
||||
--breadcrumb-muted: var(--wrn-color-secondary-muted);
|
||||
--breadcrumb-text: var(--wrn-color-secondary-text);
|
||||
}
|
||||
|
||||
.wire-breadcrumb[data-color="info"] {
|
||||
--breadcrumb-accent: var(--wire-color-info);
|
||||
--breadcrumb-soft: var(--wire-color-info-soft);
|
||||
--breadcrumb-muted: var(--wire-color-info-muted);
|
||||
--breadcrumb-text: var(--wire-color-info-text);
|
||||
.wrn-breadcrumb[data-color="info"] {
|
||||
--breadcrumb-accent: var(--wrn-color-info);
|
||||
--breadcrumb-soft: var(--wrn-color-info-soft);
|
||||
--breadcrumb-muted: var(--wrn-color-info-muted);
|
||||
--breadcrumb-text: var(--wrn-color-info-text);
|
||||
}
|
||||
|
||||
.wire-breadcrumb[data-color="success"] {
|
||||
--breadcrumb-accent: var(--wire-color-success);
|
||||
--breadcrumb-soft: var(--wire-color-success-soft);
|
||||
--breadcrumb-muted: var(--wire-color-success-muted);
|
||||
--breadcrumb-text: var(--wire-color-success-text);
|
||||
.wrn-breadcrumb[data-color="success"] {
|
||||
--breadcrumb-accent: var(--wrn-color-success);
|
||||
--breadcrumb-soft: var(--wrn-color-success-soft);
|
||||
--breadcrumb-muted: var(--wrn-color-success-muted);
|
||||
--breadcrumb-text: var(--wrn-color-success-text);
|
||||
}
|
||||
|
||||
.wire-breadcrumb[data-color="warning"] {
|
||||
--breadcrumb-accent: var(--wire-color-warning);
|
||||
--breadcrumb-soft: var(--wire-color-warning-soft);
|
||||
--breadcrumb-muted: var(--wire-color-warning-muted);
|
||||
--breadcrumb-text: var(--wire-color-warning-text);
|
||||
.wrn-breadcrumb[data-color="warning"] {
|
||||
--breadcrumb-accent: var(--wrn-color-warning);
|
||||
--breadcrumb-soft: var(--wrn-color-warning-soft);
|
||||
--breadcrumb-muted: var(--wrn-color-warning-muted);
|
||||
--breadcrumb-text: var(--wrn-color-warning-text);
|
||||
}
|
||||
|
||||
.wire-breadcrumb[data-color="danger"] {
|
||||
--breadcrumb-accent: var(--wire-color-danger);
|
||||
--breadcrumb-soft: var(--wire-color-danger-soft);
|
||||
--breadcrumb-muted: var(--wire-color-danger-muted);
|
||||
--breadcrumb-text: var(--wire-color-danger-text);
|
||||
.wrn-breadcrumb[data-color="danger"] {
|
||||
--breadcrumb-accent: var(--wrn-color-danger);
|
||||
--breadcrumb-soft: var(--wrn-color-danger-soft);
|
||||
--breadcrumb-muted: var(--wrn-color-danger-muted);
|
||||
--breadcrumb-text: var(--wrn-color-danger-text);
|
||||
}
|
||||
|
||||
.wire-breadcrumb[data-variant="soft"] {
|
||||
.wrn-breadcrumb[data-variant="soft"] {
|
||||
width: fit-content;
|
||||
max-width: 100%;
|
||||
padding: 0.45rem 0.65rem;
|
||||
@@ -158,21 +158,21 @@ label: string = "Breadcrumb"
|
||||
border-radius: 0.75rem;
|
||||
}
|
||||
|
||||
.wire-breadcrumb[data-variant="outline"] {
|
||||
.wrn-breadcrumb[data-variant="outline"] {
|
||||
width: fit-content;
|
||||
max-width: 100%;
|
||||
padding: 0.45rem 0.65rem;
|
||||
background: var(--wire-color-surface-raised);
|
||||
border: 1px solid var(--wire-color-border);
|
||||
background: var(--wrn-color-surface-raised);
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: 0.75rem;
|
||||
box-shadow: var(--wire-shadow-sm);
|
||||
box-shadow: var(--wrn-shadow-sm);
|
||||
}
|
||||
|
||||
.wire-breadcrumb[data-variant="contrast"] {
|
||||
.wrn-breadcrumb[data-variant="contrast"] {
|
||||
color: rgba(255, 255, 255, 0.78);
|
||||
}
|
||||
|
||||
.wire-breadcrumb__list {
|
||||
.wrn-breadcrumb__list {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0;
|
||||
@@ -185,34 +185,34 @@ label: string = "Breadcrumb"
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.wire-breadcrumb__list::-webkit-scrollbar {
|
||||
.wrn-breadcrumb__list::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.wire-breadcrumb__item {
|
||||
.wrn-breadcrumb__item {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
min-width: 0;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.wire-breadcrumb__separator {
|
||||
.wrn-breadcrumb__separator {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-inline: 0.45rem;
|
||||
color: var(--wire-color-text-subtle);
|
||||
color: var(--wrn-color-text-subtle);
|
||||
font-size: 0.75rem;
|
||||
opacity: 0.72;
|
||||
}
|
||||
|
||||
.wire-breadcrumb__separator-icon {
|
||||
.wrn-breadcrumb__separator-icon {
|
||||
width: 0.9rem;
|
||||
height: 0.9rem;
|
||||
}
|
||||
|
||||
.wire-breadcrumb__link,
|
||||
.wire-breadcrumb__current {
|
||||
.wrn-breadcrumb__link,
|
||||
.wrn-breadcrumb__current {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.4rem;
|
||||
@@ -225,97 +225,97 @@ label: string = "Breadcrumb"
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.wire-breadcrumb[data-size="sm"] .wire-breadcrumb__link,
|
||||
.wire-breadcrumb[data-size="sm"] .wire-breadcrumb__current {
|
||||
.wrn-breadcrumb[data-size="sm"] .wrn-breadcrumb__link,
|
||||
.wrn-breadcrumb[data-size="sm"] .wrn-breadcrumb__current {
|
||||
min-height: 1.75rem;
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
|
||||
.wire-breadcrumb[data-size="lg"] .wire-breadcrumb__link,
|
||||
.wire-breadcrumb[data-size="lg"] .wire-breadcrumb__current {
|
||||
.wrn-breadcrumb[data-size="lg"] .wrn-breadcrumb__link,
|
||||
.wrn-breadcrumb[data-size="lg"] .wrn-breadcrumb__current {
|
||||
min-height: 2.25rem;
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
|
||||
.wire-breadcrumb__link {
|
||||
color: var(--wire-color-text-muted);
|
||||
.wrn-breadcrumb__link {
|
||||
color: var(--wrn-color-text-muted);
|
||||
font-weight: 600;
|
||||
transition:
|
||||
color 160ms ease,
|
||||
background 160ms ease;
|
||||
}
|
||||
|
||||
.wire-breadcrumb__link:hover {
|
||||
.wrn-breadcrumb__link:hover {
|
||||
color: var(--breadcrumb-accent);
|
||||
background: var(--breadcrumb-soft);
|
||||
}
|
||||
|
||||
.wire-breadcrumb__link:focus-visible {
|
||||
.wrn-breadcrumb__link:focus-visible {
|
||||
color: var(--breadcrumb-accent);
|
||||
outline: 2px solid var(--breadcrumb-accent);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
.wire-breadcrumb__current {
|
||||
.wrn-breadcrumb__current {
|
||||
max-width: 22rem;
|
||||
color: var(--wire-color-text);
|
||||
color: var(--wrn-color-text);
|
||||
font-weight: 750;
|
||||
}
|
||||
|
||||
.wire-breadcrumb__item[data-current="true"] .wire-breadcrumb__current {
|
||||
.wrn-breadcrumb__item[data-current="true"] .wrn-breadcrumb__current {
|
||||
color: var(--breadcrumb-text);
|
||||
background: var(--breadcrumb-soft);
|
||||
}
|
||||
|
||||
.wire-breadcrumb__current[aria-disabled="true"] {
|
||||
.wrn-breadcrumb__current[aria-disabled="true"] {
|
||||
opacity: 0.58;
|
||||
}
|
||||
|
||||
.wire-breadcrumb__icon,
|
||||
.wire-breadcrumb__external {
|
||||
.wrn-breadcrumb__icon,
|
||||
.wrn-breadcrumb__external {
|
||||
flex: 0 0 auto;
|
||||
width: 0.95rem;
|
||||
height: 0.95rem;
|
||||
}
|
||||
|
||||
.wire-breadcrumb__home {
|
||||
.wrn-breadcrumb__home {
|
||||
color: var(--breadcrumb-accent);
|
||||
}
|
||||
|
||||
.wire-breadcrumb__label {
|
||||
.wrn-breadcrumb__label {
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.wire-breadcrumb[data-variant="contrast"] .wire-breadcrumb__link,
|
||||
.wire-breadcrumb[data-variant="contrast"] .wire-breadcrumb__current,
|
||||
.wire-breadcrumb[data-variant="contrast"] .wire-breadcrumb__home {
|
||||
.wrn-breadcrumb[data-variant="contrast"] .wrn-breadcrumb__link,
|
||||
.wrn-breadcrumb[data-variant="contrast"] .wrn-breadcrumb__current,
|
||||
.wrn-breadcrumb[data-variant="contrast"] .wrn-breadcrumb__home {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.wire-breadcrumb[data-variant="contrast"] .wire-breadcrumb__link:hover,
|
||||
.wire-breadcrumb[data-variant="contrast"] .wire-breadcrumb__item[data-current="true"] .wire-breadcrumb__current {
|
||||
.wrn-breadcrumb[data-variant="contrast"] .wrn-breadcrumb__link:hover,
|
||||
.wrn-breadcrumb[data-variant="contrast"] .wrn-breadcrumb__item[data-current="true"] .wrn-breadcrumb__current {
|
||||
color: #ffffff;
|
||||
background: rgba(255, 255, 255, 0.12);
|
||||
}
|
||||
|
||||
.wire-breadcrumb[data-variant="contrast"] .wire-breadcrumb__separator {
|
||||
.wrn-breadcrumb[data-variant="contrast"] .wrn-breadcrumb__separator {
|
||||
color: rgba(255, 255, 255, 0.62);
|
||||
}
|
||||
|
||||
@media (max-width: 639px) {
|
||||
.wire-breadcrumb__home-label {
|
||||
.wrn-breadcrumb__home-label {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.wire-breadcrumb__current {
|
||||
.wrn-breadcrumb__current {
|
||||
max-width: 13rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.wire-breadcrumb__link {
|
||||
.wrn-breadcrumb__link {
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import ComponentBaseStyles from "../styles/ComponentBaseStyles.wrn"
|
||||
|
||||
component ButtonGroup {
|
||||
outputs {
|
||||
click(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||
@@ -56,7 +54,7 @@ items: unknown[] = []
|
||||
view {
|
||||
<div
|
||||
{...attrs}
|
||||
class="wire-component wire-next--button-group {class}"
|
||||
class="wrn-component wrn-next--button-group {class}"
|
||||
role="{toolbar ? 'toolbar' : 'group'}"
|
||||
aria-label="{ariaLabel}"
|
||||
aria-orientation="{orientation}"
|
||||
@@ -73,7 +71,7 @@ items: unknown[] = []
|
||||
{#each items as item, index}
|
||||
<button
|
||||
type="{item.type || 'button'}"
|
||||
class="wire-btn wire-btn--variant-{item.variant || variant} wire-btn--color-{item.color || color} wire-btn--size-{item.size || size}"
|
||||
class="wrn-btn wrn-btn--variant-{item.variant || variant} wrn-btn--color-{item.color || color} wrn-btn--size-{item.size || size}"
|
||||
disabled="{disabled || item.disabled}"
|
||||
aria-label="{item.ariaLabel || item.label}"
|
||||
aria-pressed="{selectable ? (selectedValue === (item.value || item.label || String(index)) ? 'true' : 'false') : ''}"
|
||||
@@ -82,19 +80,18 @@ items: unknown[] = []
|
||||
@click="selectItem(item, index)"
|
||||
>
|
||||
{#if item.icon}
|
||||
<span class="wire-btn__icon {item.icon}" aria-hidden="true"></span>
|
||||
<span class="wrn-btn__icon {item.icon}" aria-hidden="true"></span>
|
||||
{/if}
|
||||
<span class="wire-btn__label">{item.label}</span>
|
||||
<span class="wrn-btn__label">{item.label}</span>
|
||||
</button>
|
||||
{/each}
|
||||
{/if}
|
||||
<slot />
|
||||
</div>
|
||||
<ComponentBaseStyles hidden />
|
||||
}
|
||||
|
||||
style {
|
||||
.wire-next--button-group {
|
||||
.wrn-next--button-group {
|
||||
display: inline-flex;
|
||||
align-items: stretch;
|
||||
width: fit-content;
|
||||
@@ -102,138 +99,206 @@ items: unknown[] = []
|
||||
isolation: isolate;
|
||||
}
|
||||
|
||||
.wire-next--button-group[data-orientation="vertical"] {
|
||||
.wrn-next--button-group[data-orientation="vertical"] {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.wire-next--button-group[data-attached="false"] {
|
||||
.wrn-next--button-group[data-attached="false"] {
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.wire-next--button-group[data-disabled="true"] {
|
||||
.wrn-next--button-group[data-disabled="true"] {
|
||||
cursor: not-allowed;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.wire-next--button-group[data-attached="true"] > :is(.wire-btn, .wire-action) {
|
||||
.wrn-next--button-group[data-attached="true"] > :is(.wrn-btn, .wrn-action) {
|
||||
position: relative;
|
||||
margin: 0;
|
||||
}
|
||||
.wire-next--button-group[data-attached="true"] > .wire-action {
|
||||
.wrn-next--button-group[data-attached="true"] > .wrn-action {
|
||||
display: flex;
|
||||
}
|
||||
.wire-next--button-group[data-attached="true"] > :is(.wire-btn, .wire-action) :is(.wire-btn) {
|
||||
.wrn-next--button-group[data-attached="true"] > :is(.wrn-btn, .wrn-action) :is(.wrn-btn) {
|
||||
height: 100%;
|
||||
}
|
||||
.wire-next--button-group[data-attached="true"][data-orientation="horizontal"]
|
||||
> :is(.wire-btn, .wire-action):not(:first-child) {
|
||||
.wrn-next--button-group[data-attached="true"][data-orientation="horizontal"]
|
||||
> :is(.wrn-btn, .wrn-action):not(:first-child) {
|
||||
margin-inline-start: -1px;
|
||||
}
|
||||
.wire-next--button-group[data-attached="true"][data-orientation="horizontal"]
|
||||
> .wire-btn:not(:first-child):not(:last-child),
|
||||
.wire-next--button-group[data-attached="true"][data-orientation="horizontal"]
|
||||
> .wire-action:not(:first-child):not(:last-child)
|
||||
> .wire-btn {
|
||||
.wrn-next--button-group[data-attached="true"][data-orientation="horizontal"]
|
||||
> .wrn-btn:not(:first-child):not(:last-child),
|
||||
.wrn-next--button-group[data-attached="true"][data-orientation="horizontal"]
|
||||
> .wrn-action:not(:first-child):not(:last-child)
|
||||
> .wrn-btn {
|
||||
border-radius: 0;
|
||||
}
|
||||
.wire-next--button-group[data-attached="true"][data-orientation="horizontal"]
|
||||
> .wire-btn:first-child:not(:last-child),
|
||||
.wire-next--button-group[data-attached="true"][data-orientation="horizontal"]
|
||||
> .wire-action:first-child:not(:last-child)
|
||||
> .wire-btn {
|
||||
.wrn-next--button-group[data-attached="true"][data-orientation="horizontal"]
|
||||
> .wrn-btn:first-child:not(:last-child),
|
||||
.wrn-next--button-group[data-attached="true"][data-orientation="horizontal"]
|
||||
> .wrn-action:first-child:not(:last-child)
|
||||
> .wrn-btn {
|
||||
border-start-end-radius: 0;
|
||||
border-end-end-radius: 0;
|
||||
}
|
||||
.wire-next--button-group[data-attached="true"][data-orientation="horizontal"]
|
||||
> .wire-btn:last-child:not(:first-child),
|
||||
.wire-next--button-group[data-attached="true"][data-orientation="horizontal"]
|
||||
> .wire-action:last-child:not(:first-child)
|
||||
> .wire-btn {
|
||||
.wrn-next--button-group[data-attached="true"][data-orientation="horizontal"]
|
||||
> .wrn-btn:last-child:not(:first-child),
|
||||
.wrn-next--button-group[data-attached="true"][data-orientation="horizontal"]
|
||||
> .wrn-action:last-child:not(:first-child)
|
||||
> .wrn-btn {
|
||||
border-start-start-radius: 0;
|
||||
border-end-start-radius: 0;
|
||||
}
|
||||
.wire-next--button-group[data-attached="true"][data-orientation="vertical"]
|
||||
> :is(.wire-btn, .wire-action):not(:first-child) {
|
||||
.wrn-next--button-group[data-attached="true"][data-orientation="vertical"]
|
||||
> :is(.wrn-btn, .wrn-action):not(:first-child) {
|
||||
margin-top: -1px;
|
||||
}
|
||||
.wire-next--button-group[data-attached="true"][data-orientation="vertical"]
|
||||
> .wire-btn:not(:first-child):not(:last-child),
|
||||
.wire-next--button-group[data-attached="true"][data-orientation="vertical"]
|
||||
> .wire-action:not(:first-child):not(:last-child)
|
||||
> .wire-btn {
|
||||
.wrn-next--button-group[data-attached="true"][data-orientation="vertical"]
|
||||
> .wrn-btn:not(:first-child):not(:last-child),
|
||||
.wrn-next--button-group[data-attached="true"][data-orientation="vertical"]
|
||||
> .wrn-action:not(:first-child):not(:last-child)
|
||||
> .wrn-btn {
|
||||
border-radius: 0;
|
||||
}
|
||||
.wire-next--button-group[data-attached="true"][data-orientation="vertical"]
|
||||
> .wire-btn:first-child:not(:last-child),
|
||||
.wire-next--button-group[data-attached="true"][data-orientation="vertical"]
|
||||
> .wire-action:first-child:not(:last-child)
|
||||
> .wire-btn {
|
||||
.wrn-next--button-group[data-attached="true"][data-orientation="vertical"]
|
||||
> .wrn-btn:first-child:not(:last-child),
|
||||
.wrn-next--button-group[data-attached="true"][data-orientation="vertical"]
|
||||
> .wrn-action:first-child:not(:last-child)
|
||||
> .wrn-btn {
|
||||
border-end-start-radius: 0;
|
||||
border-end-end-radius: 0;
|
||||
}
|
||||
.wire-next--button-group[data-attached="true"][data-orientation="vertical"]
|
||||
> .wire-btn:last-child:not(:first-child),
|
||||
.wire-next--button-group[data-attached="true"][data-orientation="vertical"]
|
||||
> .wire-action:last-child:not(:first-child)
|
||||
> .wire-btn {
|
||||
.wrn-next--button-group[data-attached="true"][data-orientation="vertical"]
|
||||
> .wrn-btn:last-child:not(:first-child),
|
||||
.wrn-next--button-group[data-attached="true"][data-orientation="vertical"]
|
||||
> .wrn-action:last-child:not(:first-child)
|
||||
> .wrn-btn {
|
||||
border-start-start-radius: 0;
|
||||
border-start-end-radius: 0;
|
||||
}
|
||||
.wire-next--button-group > :is(.wire-btn, .wire-action):focus-within,
|
||||
.wire-next--button-group > .wire-btn:focus-visible {
|
||||
.wrn-next--button-group > :is(.wrn-btn, .wrn-action):focus-within,
|
||||
.wrn-next--button-group > .wrn-btn:focus-visible {
|
||||
z-index: 2;
|
||||
}
|
||||
.wire-next--button-group[data-selectable="true"] > .wire-btn[data-selected="true"] {
|
||||
.wrn-next--button-group[data-selectable="true"] > .wrn-btn[data-selected="true"] {
|
||||
z-index: 1;
|
||||
border-color: var(--wire-component-color);
|
||||
background: color-mix(in srgb, var(--wire-component-color) 16%, var(--wire-color-surface));
|
||||
color: var(--wire-component-color);
|
||||
border-color: var(--wrn-component-color);
|
||||
background: color-mix(in srgb, var(--wrn-component-color) 16%, var(--wrn-color-surface));
|
||||
color: var(--wrn-component-color);
|
||||
}
|
||||
@media (max-width: 480px) {
|
||||
.wire-next--button-group[data-responsive="true"] > :is(.wire-btn, .wire-action) {
|
||||
.wrn-next--button-group[data-responsive="true"] > :is(.wrn-btn, .wrn-action) {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.wire-next--button-group[data-responsive="true"] > .wire-action > .wire-btn {
|
||||
.wrn-next--button-group[data-responsive="true"] > .wrn-action > .wrn-btn {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.wire-next--button-group[data-responsive="true"][data-attached="true"]
|
||||
> :is(.wire-btn, .wire-action) {
|
||||
.wrn-next--button-group[data-responsive="true"][data-attached="true"]
|
||||
> :is(.wrn-btn, .wrn-action) {
|
||||
margin-top: -1px;
|
||||
margin-inline-start: 0;
|
||||
}
|
||||
|
||||
.wire-next--button-group[data-responsive="true"][data-attached="true"]
|
||||
> :is(.wire-btn, .wire-action):first-child {
|
||||
.wrn-next--button-group[data-responsive="true"][data-attached="true"]
|
||||
> :is(.wrn-btn, .wrn-action):first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.wire-next--button-group[data-responsive="true"][data-attached="true"] > .wire-btn,
|
||||
.wire-next--button-group[data-responsive="true"][data-attached="true"]
|
||||
> .wire-action
|
||||
> .wire-btn {
|
||||
.wrn-next--button-group[data-responsive="true"][data-attached="true"] > .wrn-btn,
|
||||
.wrn-next--button-group[data-responsive="true"][data-attached="true"]
|
||||
> .wrn-action
|
||||
> .wrn-btn {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.wire-next--button-group[data-responsive="true"][data-attached="true"] > .wire-btn:first-child,
|
||||
.wire-next--button-group[data-responsive="true"][data-attached="true"]
|
||||
> .wire-action:first-child
|
||||
> .wire-btn {
|
||||
border-start-start-radius: var(--wire-radius-sm);
|
||||
border-start-end-radius: var(--wire-radius-sm);
|
||||
.wrn-next--button-group[data-responsive="true"][data-attached="true"] > .wrn-btn:first-child,
|
||||
.wrn-next--button-group[data-responsive="true"][data-attached="true"]
|
||||
> .wrn-action:first-child
|
||||
> .wrn-btn {
|
||||
border-start-start-radius: var(--wrn-radius-sm);
|
||||
border-start-end-radius: var(--wrn-radius-sm);
|
||||
}
|
||||
|
||||
.wire-next--button-group[data-responsive="true"][data-attached="true"] > .wire-btn:last-child,
|
||||
.wire-next--button-group[data-responsive="true"][data-attached="true"]
|
||||
> .wire-action:last-child
|
||||
> .wire-btn {
|
||||
border-end-start-radius: var(--wire-radius-sm);
|
||||
border-end-end-radius: var(--wire-radius-sm);
|
||||
.wrn-next--button-group[data-responsive="true"][data-attached="true"] > .wrn-btn:last-child,
|
||||
.wrn-next--button-group[data-responsive="true"][data-attached="true"]
|
||||
> .wrn-action:last-child
|
||||
> .wrn-btn {
|
||||
border-end-start-radius: var(--wrn-radius-sm);
|
||||
border-end-end-radius: var(--wrn-radius-sm);
|
||||
}
|
||||
}
|
||||
|
||||
/* Shared component foundation. */
|
||||
|
||||
.wrn-component {
|
||||
--wrn-component-color: var(--wrn-color-primary);
|
||||
--wrn-component-scale: 1;
|
||||
margin: 0;
|
||||
color: var(--wrn-color-text);
|
||||
font-family: var(--wrn-font-sans, inherit);
|
||||
}
|
||||
|
||||
.wrn-component--color-primary {
|
||||
--wrn-component-color: var(--wrn-color-primary);
|
||||
}
|
||||
|
||||
.wrn-component--color-secondary {
|
||||
--wrn-component-color: var(--wrn-color-secondary);
|
||||
}
|
||||
|
||||
.wrn-component--color-success {
|
||||
--wrn-component-color: var(--wrn-color-success);
|
||||
}
|
||||
|
||||
.wrn-component--color-warning {
|
||||
--wrn-component-color: var(--wrn-color-warning);
|
||||
}
|
||||
|
||||
.wrn-component--color-danger {
|
||||
--wrn-component-color: var(--wrn-color-danger);
|
||||
}
|
||||
|
||||
.wrn-component--color-info {
|
||||
--wrn-component-color: var(--wrn-color-info);
|
||||
}
|
||||
|
||||
.wrn-component--size-xs {
|
||||
--wrn-component-scale: 0.78;
|
||||
}
|
||||
|
||||
.wrn-component--size-sm {
|
||||
--wrn-component-scale: 0.88;
|
||||
}
|
||||
|
||||
.wrn-component--size-default,
|
||||
.wrn-component--size-md {
|
||||
--wrn-component-scale: 1;
|
||||
}
|
||||
|
||||
.wrn-component--size-lg {
|
||||
--wrn-component-scale: 1.14;
|
||||
}
|
||||
|
||||
.wrn-component--size-xl {
|
||||
--wrn-component-scale: 1.28;
|
||||
}
|
||||
|
||||
.wrn-component:not(.wrn-btn) {
|
||||
font-size: calc(1em * var(--wrn-component-scale));
|
||||
}
|
||||
|
||||
.wrn-component :is(a, button, input, select, textarea):focus-visible {
|
||||
outline-color: var(--wrn-component-color);
|
||||
}
|
||||
|
||||
.wrn-component p {
|
||||
margin: 0;
|
||||
color: var(--wrn-color-muted);
|
||||
line-height: 1.6;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+194
-128
@@ -1,5 +1,3 @@
|
||||
import ComponentBaseStyles from "../styles/ComponentBaseStyles.wrn"
|
||||
|
||||
// Interactive, hydration-safe content carousel.
|
||||
component Carousel {
|
||||
outputs {
|
||||
@@ -81,7 +79,7 @@ component Carousel {
|
||||
if (!sourceEvent || !sourceEvent.currentTarget) {
|
||||
return
|
||||
}
|
||||
root = sourceEvent.currentTarget.closest(".wire-next--carousel")
|
||||
root = sourceEvent.currentTarget.closest(".wrn-next--carousel")
|
||||
if (root) {
|
||||
carouselRoot = root
|
||||
}
|
||||
@@ -94,8 +92,8 @@ component Carousel {
|
||||
return
|
||||
}
|
||||
if (isSnap) {
|
||||
viewport = root.querySelector(".wire-next__carousel-viewport")
|
||||
slides = root.querySelectorAll(".wire-next__carousel-slide")
|
||||
viewport = root.querySelector(".wrn-next__carousel-viewport")
|
||||
slides = root.querySelectorAll(".wrn-next__carousel-slide")
|
||||
slide = slides[index]
|
||||
if (viewport && slide) {
|
||||
viewport.scrollTo({
|
||||
@@ -104,7 +102,7 @@ component Carousel {
|
||||
})
|
||||
}
|
||||
}
|
||||
thumbnails = root.querySelectorAll(".wire-next__carousel-thumbnails button")
|
||||
thumbnails = root.querySelectorAll(".wrn-next__carousel-thumbnails button")
|
||||
if (thumbnails[index]) {
|
||||
thumbnail = thumbnails[index]
|
||||
rail = thumbnail.parentElement
|
||||
@@ -122,7 +120,7 @@ component Carousel {
|
||||
}
|
||||
rememberRoot(sourceEvent)
|
||||
viewport = sourceEvent.currentTarget
|
||||
slides = viewport.querySelectorAll(".wire-next__carousel-slide")
|
||||
slides = viewport.querySelectorAll(".wrn-next__carousel-slide")
|
||||
viewportCenter = viewport.scrollLeft + viewport.clientWidth / 2
|
||||
closestIndex = currentIndex
|
||||
closestDistance = 1000000000
|
||||
@@ -144,7 +142,7 @@ component Carousel {
|
||||
item: items[currentIndex],
|
||||
reason: "snap"
|
||||
})
|
||||
slides = carouselRoot.querySelectorAll(".wire-next__carousel-thumbnails button")
|
||||
slides = carouselRoot.querySelectorAll(".wrn-next__carousel-thumbnails button")
|
||||
slide = slides[currentIndex]
|
||||
if (slide) {
|
||||
viewport = slide.parentElement
|
||||
@@ -318,7 +316,7 @@ component Carousel {
|
||||
view {
|
||||
<section
|
||||
{...attrs}
|
||||
class="wire-component wire-next--carousel wire-component--color-{color} wire-component--size-{size} wire-next--variant-{variant} {class}"
|
||||
class="wrn-component wrn-next--carousel wrn-component--color-{color} wrn-component--size-{size} wrn-next--variant-{variant} {class}"
|
||||
data-rtl="{isRTL}"
|
||||
data-centered="{isCentered}"
|
||||
data-draggable="{isDraggable && !isSnap}"
|
||||
@@ -337,15 +335,15 @@ component Carousel {
|
||||
@focusout="startAutoplay()"
|
||||
>
|
||||
{#if title || description}
|
||||
<header class="wire-next__carousel-header">
|
||||
<header class="wrn-next__carousel-header">
|
||||
{#if title}<h3>{title}</h3>{/if}
|
||||
{#if description}<p>{description}</p>{/if}
|
||||
</header>
|
||||
{/if}
|
||||
|
||||
<div class="wire-next__carousel-layout">
|
||||
<div class="wrn-next__carousel-layout">
|
||||
{#if thumbnails === "vertical"}
|
||||
<div class="wire-next__carousel-thumbnails" aria-label="Choose a slide">
|
||||
<div class="wrn-next__carousel-thumbnails" aria-label="Choose a slide">
|
||||
{#each items as item, index}
|
||||
<button
|
||||
type="button"
|
||||
@@ -361,10 +359,10 @@ component Carousel {
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<div class="wire-next__carousel-main">
|
||||
<div class="wire-next__carousel-stage">
|
||||
<div class="wrn-next__carousel-main">
|
||||
<div class="wrn-next__carousel-stage">
|
||||
<div
|
||||
class="wire-next__carousel-viewport"
|
||||
class="wrn-next__carousel-viewport"
|
||||
tabindex="0"
|
||||
@scroll="handleSnapScroll(event)"
|
||||
@pointerdown="beginDrag(event)"
|
||||
@@ -374,12 +372,12 @@ component Carousel {
|
||||
@lostpointercapture="cancelDrag()"
|
||||
>
|
||||
<div
|
||||
class="wire-next__carousel-track"
|
||||
style="--wire-carousel-index: {currentIndex}; --wire-carousel-per-view: {slidesPerView}; --wire-carousel-gap: {gap}; --wire-carousel-drag-offset: {dragOffset}px"
|
||||
class="wrn-next__carousel-track"
|
||||
style="--wrn-carousel-index: {currentIndex}; --wrn-carousel-per-view: {slidesPerView}; --wrn-carousel-gap: {gap}; --wrn-carousel-drag-offset: {dragOffset}px"
|
||||
>
|
||||
{#each items as item, index}
|
||||
<article
|
||||
class="wire-next__carousel-slide"
|
||||
class="wrn-next__carousel-slide"
|
||||
data-active="{index === currentIndex}"
|
||||
role="group"
|
||||
aria-roledescription="slide"
|
||||
@@ -389,7 +387,7 @@ component Carousel {
|
||||
{#if item.imageSrc}
|
||||
<img src="{item.imageSrc}" alt="{item.imageAlt || item.title || ''}" />
|
||||
{/if}
|
||||
<div class="wire-next__carousel-slide-content">
|
||||
<div class="wrn-next__carousel-slide-content">
|
||||
{#if item.eyebrow}<span>{item.eyebrow}</span>{/if}
|
||||
{#if item.title || item.label}<h4>{item.title || item.label}</h4>{/if}
|
||||
{#if item.description}<p>{item.description}</p>{/if}
|
||||
@@ -404,7 +402,7 @@ component Carousel {
|
||||
</div>
|
||||
|
||||
<button
|
||||
class="wire-next__carousel-control wire-next__carousel-control--previous"
|
||||
class="wrn-next__carousel-control wrn-next__carousel-control--previous"
|
||||
type="button"
|
||||
aria-label="Previous slide"
|
||||
disabled="{!isInfiniteLoop && currentIndex === 0}"
|
||||
@@ -413,7 +411,7 @@ component Carousel {
|
||||
<span class="icon-[lucide--chevron-left]" aria-hidden="true"></span>
|
||||
</button>
|
||||
<button
|
||||
class="wire-next__carousel-control wire-next__carousel-control--next"
|
||||
class="wrn-next__carousel-control wrn-next__carousel-control--next"
|
||||
type="button"
|
||||
aria-label="Next slide"
|
||||
disabled="{!isInfiniteLoop && currentIndex === maximumIndex()}"
|
||||
@@ -423,14 +421,14 @@ component Carousel {
|
||||
</button>
|
||||
|
||||
{#if showCounter}
|
||||
<output class="wire-next__carousel-counter" aria-live="polite">
|
||||
<output class="wrn-next__carousel-counter" aria-live="polite">
|
||||
{currentIndex + 1} / {items.length}
|
||||
</output>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
{#if showPagination}
|
||||
<div class="wire-next__carousel-pagination" aria-label="Choose a slide">
|
||||
<div class="wrn-next__carousel-pagination" aria-label="Choose a slide">
|
||||
{#each items as item, index}
|
||||
<button
|
||||
type="button"
|
||||
@@ -444,7 +442,7 @@ component Carousel {
|
||||
{/if}
|
||||
|
||||
{#if thumbnails === "horizontal"}
|
||||
<div class="wire-next__carousel-thumbnails" aria-label="Choose a slide">
|
||||
<div class="wrn-next__carousel-thumbnails" aria-label="Choose a slide">
|
||||
{#each items as item, index}
|
||||
<button
|
||||
type="button"
|
||||
@@ -462,145 +460,144 @@ component Carousel {
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<ComponentBaseStyles hidden />
|
||||
}
|
||||
|
||||
style {
|
||||
.wire-next--carousel {
|
||||
--wire-carousel-color: var(--wire-component-color, var(--wire-color-primary));
|
||||
.wrn-next--carousel {
|
||||
--wrn-carousel-color: var(--wrn-component-color, var(--wrn-color-primary));
|
||||
display: grid;
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
gap: 1rem;
|
||||
padding: 1rem;
|
||||
border: 1px solid var(--wire-color-border);
|
||||
border-radius: var(--wire-radius-md);
|
||||
color: var(--wire-color-text);
|
||||
background: var(--wire-color-surface);
|
||||
box-shadow: var(--wire-shadow-1);
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: var(--wrn-radius-md);
|
||||
color: var(--wrn-color-text);
|
||||
background: var(--wrn-color-surface);
|
||||
box-shadow: var(--wrn-shadow-1);
|
||||
}
|
||||
|
||||
.wire-next__carousel-header h3,
|
||||
.wire-next__carousel-header p {
|
||||
.wrn-next__carousel-header h3,
|
||||
.wrn-next__carousel-header p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.wire-next__carousel-header p {
|
||||
.wrn-next__carousel-header p {
|
||||
margin-top: 0.35rem;
|
||||
color: var(--wire-color-text-muted);
|
||||
color: var(--wrn-color-text-muted);
|
||||
}
|
||||
|
||||
.wire-next__carousel-layout {
|
||||
.wrn-next__carousel-layout {
|
||||
display: flex;
|
||||
min-width: 0;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
|
||||
.wire-next__carousel-main {
|
||||
.wrn-next__carousel-main {
|
||||
display: grid;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
|
||||
.wire-next__carousel-stage {
|
||||
.wrn-next__carousel-stage {
|
||||
position: relative;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.wire-next__carousel-viewport {
|
||||
.wrn-next__carousel-viewport {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
min-width: 0;
|
||||
border: 1px solid var(--wire-color-border);
|
||||
border-radius: var(--wire-radius-md);
|
||||
background: var(--wire-color-surface-subtle, var(--wire-color-surface));
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: var(--wrn-radius-md);
|
||||
background: var(--wrn-color-surface-subtle, var(--wrn-color-surface));
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.wire-next__carousel-viewport:focus-visible {
|
||||
box-shadow: 0 0 0 3px color-mix(in srgb, var(--wire-carousel-color) 30%, transparent);
|
||||
.wrn-next__carousel-viewport:focus-visible {
|
||||
box-shadow: 0 0 0 3px color-mix(in srgb, var(--wrn-carousel-color) 30%, transparent);
|
||||
}
|
||||
|
||||
.wire-next__carousel-track {
|
||||
.wrn-next__carousel-track {
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
gap: var(--wire-carousel-gap);
|
||||
gap: var(--wrn-carousel-gap);
|
||||
transform: translateX(
|
||||
calc(
|
||||
var(--wire-carousel-index) * -1 *
|
||||
var(--wrn-carousel-index) * -1 *
|
||||
(
|
||||
(100% - (var(--wire-carousel-per-view) - 1) * var(--wire-carousel-gap)) /
|
||||
var(--wire-carousel-per-view) + var(--wire-carousel-gap)
|
||||
(100% - (var(--wrn-carousel-per-view) - 1) * var(--wrn-carousel-gap)) /
|
||||
var(--wrn-carousel-per-view) + var(--wrn-carousel-gap)
|
||||
)
|
||||
)
|
||||
);
|
||||
transition: transform var(--wire-motion-base) var(--wire-ease-emphasized);
|
||||
translate: var(--wire-carousel-drag-offset, 0) 0;
|
||||
transition: transform var(--wrn-motion-base) var(--wrn-ease-emphasized);
|
||||
translate: var(--wrn-carousel-drag-offset, 0) 0;
|
||||
will-change: transform;
|
||||
}
|
||||
|
||||
.wire-next--carousel[data-dragging="true"] .wire-next__carousel-track {
|
||||
.wrn-next--carousel[data-dragging="true"] .wrn-next__carousel-track {
|
||||
transition: none;
|
||||
}
|
||||
|
||||
.wire-next--carousel[data-rtl="true"] .wire-next__carousel-track {
|
||||
.wrn-next--carousel[data-rtl="true"] .wrn-next__carousel-track {
|
||||
transform: translateX(
|
||||
calc(
|
||||
var(--wire-carousel-index) *
|
||||
var(--wrn-carousel-index) *
|
||||
(
|
||||
(100% - (var(--wire-carousel-per-view) - 1) * var(--wire-carousel-gap)) /
|
||||
var(--wire-carousel-per-view) + var(--wire-carousel-gap)
|
||||
(100% - (var(--wrn-carousel-per-view) - 1) * var(--wrn-carousel-gap)) /
|
||||
var(--wrn-carousel-per-view) + var(--wrn-carousel-gap)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
.wire-next__carousel-slide {
|
||||
.wrn-next__carousel-slide {
|
||||
position: relative;
|
||||
display: grid;
|
||||
flex: 0 0
|
||||
calc(
|
||||
(100% - (var(--wire-carousel-per-view) - 1) * var(--wire-carousel-gap)) /
|
||||
var(--wire-carousel-per-view)
|
||||
(100% - (var(--wrn-carousel-per-view) - 1) * var(--wrn-carousel-gap)) /
|
||||
var(--wrn-carousel-per-view)
|
||||
);
|
||||
overflow: hidden;
|
||||
min-width: 0;
|
||||
min-height: 20rem;
|
||||
place-items: center;
|
||||
background: var(--wire-color-surface-raised, var(--wire-color-surface));
|
||||
background: var(--wrn-color-surface-raised, var(--wrn-color-surface));
|
||||
}
|
||||
|
||||
.wire-next--carousel[data-auto-height="true"] .wire-next__carousel-slide {
|
||||
.wrn-next--carousel[data-auto-height="true"] .wrn-next__carousel-slide {
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.wire-next--carousel[data-centered="true"] .wire-next__carousel-slide {
|
||||
.wrn-next--carousel[data-centered="true"] .wrn-next__carousel-slide {
|
||||
flex-basis: min(78%, 32rem);
|
||||
}
|
||||
|
||||
.wire-next--carousel[data-centered="true"] .wire-next__carousel-track {
|
||||
.wrn-next--carousel[data-centered="true"] .wrn-next__carousel-track {
|
||||
box-sizing: border-box;
|
||||
transform: translateX(
|
||||
calc(var(--wire-carousel-index) * -1 * (min(78%, 32rem) + var(--wire-carousel-gap)))
|
||||
calc(var(--wrn-carousel-index) * -1 * (min(78%, 32rem) + var(--wrn-carousel-gap)))
|
||||
);
|
||||
}
|
||||
|
||||
.wire-next--carousel[data-centered="true"] .wire-next__carousel-slide:first-child {
|
||||
.wrn-next--carousel[data-centered="true"] .wrn-next__carousel-slide:first-child {
|
||||
margin-inline-start: calc((100% - min(78%, 32rem)) / 2);
|
||||
}
|
||||
|
||||
.wire-next--carousel[data-centered="true"] .wire-next__carousel-slide:last-child {
|
||||
.wrn-next--carousel[data-centered="true"] .wrn-next__carousel-slide:last-child {
|
||||
margin-inline-end: calc((100% - min(78%, 32rem)) / 2);
|
||||
}
|
||||
|
||||
.wire-next--carousel[data-centered="true"][data-rtl="true"] .wire-next__carousel-track {
|
||||
.wrn-next--carousel[data-centered="true"][data-rtl="true"] .wrn-next__carousel-track {
|
||||
transform: translateX(
|
||||
calc(var(--wire-carousel-index) * (min(78%, 32rem) + var(--wire-carousel-gap)))
|
||||
calc(var(--wrn-carousel-index) * (min(78%, 32rem) + var(--wrn-carousel-gap)))
|
||||
);
|
||||
}
|
||||
|
||||
.wire-next__carousel-slide > img {
|
||||
.wrn-next__carousel-slide > img {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
@@ -608,7 +605,7 @@ component Carousel {
|
||||
inset: 0;
|
||||
}
|
||||
|
||||
.wire-next__carousel-slide-content {
|
||||
.wrn-next__carousel-slide-content {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
width: min(100%, 38rem);
|
||||
@@ -616,21 +613,21 @@ component Carousel {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.wire-next__carousel-slide-content h4,
|
||||
.wire-next__carousel-slide-content p {
|
||||
.wrn-next__carousel-slide-content h4,
|
||||
.wrn-next__carousel-slide-content p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.wire-next__carousel-slide-content h4 {
|
||||
.wrn-next__carousel-slide-content h4 {
|
||||
font-size: clamp(1.5rem, 4vw, 2.4rem);
|
||||
}
|
||||
|
||||
.wire-next__carousel-slide-content p {
|
||||
.wrn-next__carousel-slide-content p {
|
||||
margin-top: 0.65rem;
|
||||
color: var(--wire-color-text-muted);
|
||||
color: var(--wrn-color-text-muted);
|
||||
}
|
||||
|
||||
.wire-next__carousel-control {
|
||||
.wrn-next__carousel-control {
|
||||
position: absolute;
|
||||
z-index: 3;
|
||||
top: 50%;
|
||||
@@ -638,46 +635,46 @@ component Carousel {
|
||||
width: 2.75rem;
|
||||
min-height: 2.75rem;
|
||||
padding: 0;
|
||||
border: 1px solid color-mix(in srgb, var(--wire-color-border) 70%, transparent);
|
||||
border: 1px solid color-mix(in srgb, var(--wrn-color-border) 70%, transparent);
|
||||
border-radius: 999px;
|
||||
background: color-mix(in srgb, var(--wire-color-text) 76%, transparent);
|
||||
color: var(--wire-color-surface);
|
||||
background: color-mix(in srgb, var(--wrn-color-text) 76%, transparent);
|
||||
color: var(--wrn-color-surface);
|
||||
cursor: pointer;
|
||||
place-items: center;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
.wire-next__carousel-control:focus-visible,
|
||||
.wire-next__carousel-pagination button:focus-visible,
|
||||
.wire-next__carousel-thumbnails button:focus-visible {
|
||||
outline: 2px solid var(--wire-carousel-color);
|
||||
.wrn-next__carousel-control:focus-visible,
|
||||
.wrn-next__carousel-pagination button:focus-visible,
|
||||
.wrn-next__carousel-thumbnails button:focus-visible {
|
||||
outline: 2px solid var(--wrn-carousel-color);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
.wire-next__carousel-control:disabled {
|
||||
.wrn-next__carousel-control:disabled {
|
||||
cursor: not-allowed;
|
||||
opacity: 0.35;
|
||||
}
|
||||
|
||||
.wire-next__carousel-control--previous {
|
||||
.wrn-next__carousel-control--previous {
|
||||
left: 1rem;
|
||||
}
|
||||
|
||||
.wire-next__carousel-control--next {
|
||||
.wrn-next__carousel-control--next {
|
||||
right: 1rem;
|
||||
}
|
||||
|
||||
.wire-next--carousel[data-rtl="true"] .wire-next__carousel-control--previous {
|
||||
.wrn-next--carousel[data-rtl="true"] .wrn-next__carousel-control--previous {
|
||||
right: 1rem;
|
||||
left: auto;
|
||||
}
|
||||
|
||||
.wire-next--carousel[data-rtl="true"] .wire-next__carousel-control--next {
|
||||
.wrn-next--carousel[data-rtl="true"] .wrn-next__carousel-control--next {
|
||||
right: auto;
|
||||
left: 1rem;
|
||||
}
|
||||
|
||||
.wire-next__carousel-pagination {
|
||||
.wrn-next__carousel-pagination {
|
||||
display: flex;
|
||||
min-height: 1.5rem;
|
||||
align-items: center;
|
||||
@@ -685,148 +682,217 @@ component Carousel {
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.wire-next__carousel-pagination button {
|
||||
.wrn-next__carousel-pagination button {
|
||||
width: 0.65rem;
|
||||
min-height: 0.65rem;
|
||||
padding: 0;
|
||||
border: 1px solid var(--wire-color-text-muted);
|
||||
border: 1px solid var(--wrn-color-text-muted);
|
||||
border-radius: 999px;
|
||||
background: transparent;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.wire-next__carousel-pagination button[data-active="true"] {
|
||||
border-color: var(--wire-carousel-color);
|
||||
background: var(--wire-carousel-color);
|
||||
.wrn-next__carousel-pagination button[data-active="true"] {
|
||||
border-color: var(--wrn-carousel-color);
|
||||
background: var(--wrn-carousel-color);
|
||||
}
|
||||
|
||||
.wire-next__carousel-counter {
|
||||
.wrn-next__carousel-counter {
|
||||
position: absolute;
|
||||
z-index: 3;
|
||||
bottom: 0.8rem;
|
||||
left: 50%;
|
||||
padding: 0.25rem 0.65rem;
|
||||
border-radius: 999px;
|
||||
background: color-mix(in srgb, var(--wire-color-text) 82%, transparent);
|
||||
color: var(--wire-color-surface);
|
||||
background: color-mix(in srgb, var(--wrn-color-text) 82%, transparent);
|
||||
color: var(--wrn-color-surface);
|
||||
font-weight: 700;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
|
||||
.wire-next__carousel-thumbnails {
|
||||
.wrn-next__carousel-thumbnails {
|
||||
display: flex;
|
||||
overflow: auto;
|
||||
gap: 0.55rem;
|
||||
scrollbar-width: thin;
|
||||
}
|
||||
|
||||
.wire-next__carousel-thumbnails button {
|
||||
.wrn-next__carousel-thumbnails button {
|
||||
display: grid;
|
||||
flex: 0 0 8.5rem;
|
||||
min-height: 3.75rem;
|
||||
overflow: hidden;
|
||||
padding: 0;
|
||||
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);
|
||||
cursor: pointer;
|
||||
place-items: center;
|
||||
}
|
||||
|
||||
.wire-next__carousel-thumbnails button[data-active="true"] {
|
||||
border-color: var(--wire-carousel-color);
|
||||
box-shadow: inset 0 0 0 1px var(--wire-carousel-color);
|
||||
.wrn-next__carousel-thumbnails button[data-active="true"] {
|
||||
border-color: var(--wrn-carousel-color);
|
||||
box-shadow: inset 0 0 0 1px var(--wrn-carousel-color);
|
||||
}
|
||||
|
||||
.wire-next__carousel-thumbnails img {
|
||||
.wrn-next__carousel-thumbnails img {
|
||||
width: 100%;
|
||||
height: 4rem;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.wire-next__carousel-thumbnails span {
|
||||
.wrn-next__carousel-thumbnails span {
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
.wire-next--carousel[data-thumbnails="vertical"] .wire-next__carousel-thumbnails {
|
||||
.wrn-next--carousel[data-thumbnails="vertical"] .wrn-next__carousel-thumbnails {
|
||||
flex: 0 0 9rem;
|
||||
flex-direction: column;
|
||||
max-height: 28rem;
|
||||
}
|
||||
|
||||
.wire-next--carousel[data-thumbnails="vertical"] .wire-next__carousel-thumbnails button {
|
||||
.wrn-next--carousel[data-thumbnails="vertical"] .wrn-next__carousel-thumbnails button {
|
||||
flex-basis: 7.5rem;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.wire-next--carousel[data-draggable="true"] .wire-next__carousel-viewport {
|
||||
.wrn-next--carousel[data-draggable="true"] .wrn-next__carousel-viewport {
|
||||
cursor: grab;
|
||||
touch-action: pan-y;
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
|
||||
.wire-next--carousel[data-draggable="true"] .wire-next__carousel-viewport:active {
|
||||
.wrn-next--carousel[data-draggable="true"] .wrn-next__carousel-viewport:active {
|
||||
cursor: grabbing;
|
||||
}
|
||||
|
||||
.wire-next--carousel[data-draggable="true"] img,
|
||||
.wire-next--carousel[data-draggable="true"] a {
|
||||
.wrn-next--carousel[data-draggable="true"] img,
|
||||
.wrn-next--carousel[data-draggable="true"] a {
|
||||
-webkit-user-drag: none;
|
||||
}
|
||||
|
||||
.wire-next--carousel[data-snap="true"] .wire-next__carousel-viewport {
|
||||
.wrn-next--carousel[data-snap="true"] .wrn-next__carousel-viewport {
|
||||
overflow-x: auto;
|
||||
scroll-behavior: smooth;
|
||||
scroll-snap-type: x mandatory;
|
||||
scrollbar-width: thin;
|
||||
}
|
||||
|
||||
.wire-next--carousel[data-snap="true"] .wire-next__carousel-track {
|
||||
--wire-carousel-snap-slide: calc(
|
||||
(100% - (var(--wire-carousel-per-view) - 1) * var(--wire-carousel-gap)) /
|
||||
var(--wire-carousel-per-view)
|
||||
.wrn-next--carousel[data-snap="true"] .wrn-next__carousel-track {
|
||||
--wrn-carousel-snap-slide: calc(
|
||||
(100% - (var(--wrn-carousel-per-view) - 1) * var(--wrn-carousel-gap)) /
|
||||
var(--wrn-carousel-per-view)
|
||||
);
|
||||
display: grid;
|
||||
width: 100%;
|
||||
min-width: 100%;
|
||||
box-sizing: content-box;
|
||||
grid-auto-columns: var(--wire-carousel-snap-slide);
|
||||
grid-auto-columns: var(--wrn-carousel-snap-slide);
|
||||
grid-auto-flow: column;
|
||||
padding-inline: calc((100% - var(--wire-carousel-snap-slide)) / 2);
|
||||
padding-inline: calc((100% - var(--wrn-carousel-snap-slide)) / 2);
|
||||
transform: none;
|
||||
}
|
||||
|
||||
.wire-next--carousel[data-snap="true"] .wire-next__carousel-slide {
|
||||
.wrn-next--carousel[data-snap="true"] .wrn-next__carousel-slide {
|
||||
width: auto;
|
||||
min-width: 0;
|
||||
scroll-snap-align: center;
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.wire-next__carousel-slide {
|
||||
.wrn-next__carousel-slide {
|
||||
flex-basis: 100%;
|
||||
min-height: 16rem;
|
||||
}
|
||||
.wire-next--carousel[data-thumbnails="vertical"] .wire-next__carousel-layout {
|
||||
.wrn-next--carousel[data-thumbnails="vertical"] .wrn-next__carousel-layout {
|
||||
flex-direction: column-reverse;
|
||||
}
|
||||
.wire-next--carousel[data-thumbnails="vertical"] .wire-next__carousel-thumbnails {
|
||||
.wrn-next--carousel[data-thumbnails="vertical"] .wrn-next__carousel-thumbnails {
|
||||
flex: auto;
|
||||
flex-direction: row;
|
||||
max-height: none;
|
||||
}
|
||||
.wire-next--carousel[data-thumbnails="vertical"] .wire-next__carousel-thumbnails button {
|
||||
.wrn-next--carousel[data-thumbnails="vertical"] .wrn-next__carousel-thumbnails button {
|
||||
flex-basis: 8.5rem;
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.wire-next__carousel-track {
|
||||
.wrn-next__carousel-track {
|
||||
transition-duration: 0.01ms;
|
||||
}
|
||||
}
|
||||
|
||||
/* Shared component foundation. */
|
||||
|
||||
.wrn-component {
|
||||
--wrn-component-color: var(--wrn-color-primary);
|
||||
--wrn-component-scale: 1;
|
||||
margin: 0;
|
||||
color: var(--wrn-color-text);
|
||||
font-family: var(--wrn-font-sans, inherit);
|
||||
}
|
||||
|
||||
.wrn-component--color-primary {
|
||||
--wrn-component-color: var(--wrn-color-primary);
|
||||
}
|
||||
|
||||
.wrn-component--color-secondary {
|
||||
--wrn-component-color: var(--wrn-color-secondary);
|
||||
}
|
||||
|
||||
.wrn-component--color-success {
|
||||
--wrn-component-color: var(--wrn-color-success);
|
||||
}
|
||||
|
||||
.wrn-component--color-warning {
|
||||
--wrn-component-color: var(--wrn-color-warning);
|
||||
}
|
||||
|
||||
.wrn-component--color-danger {
|
||||
--wrn-component-color: var(--wrn-color-danger);
|
||||
}
|
||||
|
||||
.wrn-component--color-info {
|
||||
--wrn-component-color: var(--wrn-color-info);
|
||||
}
|
||||
|
||||
.wrn-component--size-xs {
|
||||
--wrn-component-scale: 0.78;
|
||||
}
|
||||
|
||||
.wrn-component--size-sm {
|
||||
--wrn-component-scale: 0.88;
|
||||
}
|
||||
|
||||
.wrn-component--size-default,
|
||||
.wrn-component--size-md {
|
||||
--wrn-component-scale: 1;
|
||||
}
|
||||
|
||||
.wrn-component--size-lg {
|
||||
--wrn-component-scale: 1.14;
|
||||
}
|
||||
|
||||
.wrn-component--size-xl {
|
||||
--wrn-component-scale: 1.28;
|
||||
}
|
||||
|
||||
.wrn-component:not(.wrn-btn) {
|
||||
font-size: calc(1em * var(--wrn-component-scale));
|
||||
}
|
||||
|
||||
.wrn-component :is(a, button, input, select, textarea):focus-visible {
|
||||
outline-color: var(--wrn-component-color);
|
||||
}
|
||||
|
||||
.wrn-component p {
|
||||
margin: 0;
|
||||
color: var(--wrn-color-muted);
|
||||
line-height: 1.6;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,31 +51,31 @@ component Chart {
|
||||
}
|
||||
|
||||
view {
|
||||
<figure {...attrs} data-ui-component="Chart" data-variant='{variant}' class='wire-chart {class}'>
|
||||
<figure {...attrs} data-ui-component="Chart" data-variant='{variant}' class='wrn-chart {class}'>
|
||||
{#if title || description}
|
||||
<figcaption class="wire-chart__header">
|
||||
<figcaption class="wrn-chart__header">
|
||||
{#if title}<strong>{title}</strong>{/if}
|
||||
{#if description}<span>{description}</span>{/if}
|
||||
</figcaption>
|
||||
{/if}
|
||||
<svg class="wire-chart__plot" viewBox="0 0 100 100" role="img" aria-label='{title}' style='height:{height}px'>
|
||||
<line x1="8" y1="84" x2="96" y2="84" class="wire-chart__axis" />
|
||||
<svg class="wrn-chart__plot" viewBox="0 0 100 100" role="img" aria-label='{title}' style='height:{height}px'>
|
||||
<line x1="8" y1="84" x2="96" y2="84" class="wrn-chart__axis" />
|
||||
{#each items as item, index}
|
||||
<g data-hidden='{isHidden(index) ? "true" : "false"}'>
|
||||
<rect
|
||||
x='{barX(index)}' y='{barY(item)}' width='{barWidth()}' height='{barHeight(item)}'
|
||||
rx="1.5" class="wire-chart__bar" role="button" tabindex="0"
|
||||
rx="1.5" class="wrn-chart__bar" role="button" tabindex="0"
|
||||
aria-label='{item[labelKey] + ": " + numericValue(item)}'
|
||||
@click='selectPoint(item, index, event)'
|
||||
@keydown='if (event.key === "Enter" || event.key === " ") { event.preventDefault(); selectPoint(item, index, event) }'
|
||||
/>
|
||||
{#if showValues}<text x='{barX(index) + barWidth() / 2}' y='{barY(item) - 3}' class="wire-chart__value">{numericValue(item)}</text>{/if}
|
||||
<text x='{barX(index) + barWidth() / 2}' y="94" class="wire-chart__label">{item[labelKey]}</text>
|
||||
{#if showValues}<text x='{barX(index) + barWidth() / 2}' y='{barY(item) - 3}' class="wrn-chart__value">{numericValue(item)}</text>{/if}
|
||||
<text x='{barX(index) + barWidth() / 2}' y="94" class="wrn-chart__label">{item[labelKey]}</text>
|
||||
</g>
|
||||
{/each}
|
||||
</svg>
|
||||
{#if showLegend}
|
||||
<div class="wire-chart__legend" aria-label="Chart legend">
|
||||
<div class="wrn-chart__legend" aria-label="Chart legend">
|
||||
{#each items as item, index}
|
||||
<button type="button" aria-pressed='{isHidden(index) ? "false" : "true"}' @click='toggleLegend(item, index, event)'>
|
||||
<span aria-hidden="true"></span>{item[labelKey]}
|
||||
@@ -88,20 +88,20 @@ component Chart {
|
||||
}
|
||||
|
||||
style {
|
||||
.wire-chart { display: grid; gap: 1rem; min-width: 0; margin: 0; padding: 1rem; border: 1px solid var(--wire-color-border); border-radius: var(--wire-radius); color: var(--wire-color-text); background: var(--wire-color-surface); box-shadow: var(--wire-shadow-1); }
|
||||
.wire-chart__header { display: grid; gap: 0.2rem; }
|
||||
.wire-chart__header > span { color: var(--wire-color-muted); font-size: 0.8rem; }
|
||||
.wire-chart__plot { display: block; width: 100%; min-height: 12rem; overflow: visible; }
|
||||
.wire-chart__axis { stroke: var(--wire-color-border); stroke-width: 0.5; }
|
||||
.wire-chart__bar { fill: var(--wire-color-primary); cursor: pointer; transition: opacity var(--wire-motion-fast), transform var(--wire-motion-fast); transform-box: fill-box; transform-origin: bottom; }
|
||||
.wire-chart__bar:hover { opacity: 0.82; transform: scaleY(1.02); }
|
||||
.wire-chart__bar:focus-visible { outline: 1.5px solid var(--wire-color-focus); outline-offset: 1px; }
|
||||
.wire-chart__plot g[data-hidden="true"] { opacity: 0.18; pointer-events: none; }
|
||||
.wire-chart__value, .wire-chart__label { fill: var(--wire-color-text); font-size: 3.5px; text-anchor: middle; }
|
||||
.wire-chart__label { fill: var(--wire-color-muted); }
|
||||
.wire-chart__legend { display: flex; flex-wrap: wrap; gap: 0.5rem; }
|
||||
.wire-chart__legend button { display: inline-flex; align-items: center; gap: 0.35rem; padding: 0.3rem 0.5rem; border: 1px solid var(--wire-color-border); border-radius: 999px; color: var(--wire-color-text); background: transparent; font: inherit; font-size: 0.75rem; cursor: pointer; }
|
||||
.wire-chart__legend button > span { width: 0.65rem; height: 0.65rem; border-radius: 0.2rem; background: var(--wire-color-primary); }
|
||||
.wire-chart__legend button[aria-pressed="false"] { opacity: 0.5; }
|
||||
.wrn-chart { display: grid; gap: 1rem; min-width: 0; margin: 0; padding: 1rem; border: 1px solid var(--wrn-color-border); border-radius: var(--wrn-radius); color: var(--wrn-color-text); background: var(--wrn-color-surface); box-shadow: var(--wrn-shadow-1); }
|
||||
.wrn-chart__header { display: grid; gap: 0.2rem; }
|
||||
.wrn-chart__header > span { color: var(--wrn-color-muted); font-size: 0.8rem; }
|
||||
.wrn-chart__plot { display: block; width: 100%; min-height: 12rem; overflow: visible; }
|
||||
.wrn-chart__axis { stroke: var(--wrn-color-border); stroke-width: 0.5; }
|
||||
.wrn-chart__bar { fill: var(--wrn-color-primary); cursor: pointer; transition: opacity var(--wrn-motion-fast), transform var(--wrn-motion-fast); transform-box: fill-box; transform-origin: bottom; }
|
||||
.wrn-chart__bar:hover { opacity: 0.82; transform: scaleY(1.02); }
|
||||
.wrn-chart__bar:focus-visible { outline: 1.5px solid var(--wrn-color-focus); outline-offset: 1px; }
|
||||
.wrn-chart__plot g[data-hidden="true"] { opacity: 0.18; pointer-events: none; }
|
||||
.wrn-chart__value, .wrn-chart__label { fill: var(--wrn-color-text); font-size: 3.5px; text-anchor: middle; }
|
||||
.wrn-chart__label { fill: var(--wrn-color-muted); }
|
||||
.wrn-chart__legend { display: flex; flex-wrap: wrap; gap: 0.5rem; }
|
||||
.wrn-chart__legend button { display: inline-flex; align-items: center; gap: 0.35rem; padding: 0.3rem 0.5rem; border: 1px solid var(--wrn-color-border); border-radius: 999px; color: var(--wrn-color-text); background: transparent; font: inherit; font-size: 0.75rem; cursor: pointer; }
|
||||
.wrn-chart__legend button > span { width: 0.65rem; height: 0.65rem; border-radius: 0.2rem; background: var(--wrn-color-primary); }
|
||||
.wrn-chart__legend button[aria-pressed="false"] { opacity: 0.5; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import ComponentBaseStyles from "../styles/ComponentBaseStyles.wrn"
|
||||
|
||||
component ChatBubble {
|
||||
outputs {
|
||||
action(payload: { action: boolean; item: string | number | boolean | null | object; index: number })
|
||||
@@ -66,31 +64,31 @@ component ChatBubble {
|
||||
view {
|
||||
<section
|
||||
{...attrs}
|
||||
class="wire-component wire-component--color-{color} wire-component--size-{size} wire-next--chat-bubble wire-next--variant-{variant} {class}"
|
||||
class="wrn-component wrn-component--color-{color} wrn-component--size-{size} wrn-next--chat-bubble wrn-next--variant-{variant} {class}"
|
||||
data-one-sided="{oneSided}"
|
||||
role="log"
|
||||
aria-label="{ariaLabel}"
|
||||
aria-live="polite"
|
||||
>
|
||||
{#if title || description}
|
||||
<header class="wire-next__chat-header">
|
||||
<header class="wrn-next__chat-header">
|
||||
{#if title}<h3>{title}</h3>{/if}
|
||||
{#if description}<p>{description}</p>{/if}
|
||||
</header>
|
||||
{/if}
|
||||
|
||||
{#if items.length}
|
||||
<div class="wire-next__chat-thread">
|
||||
<div class="wrn-next__chat-thread">
|
||||
{#each items as item, index}
|
||||
<article
|
||||
class="wire-next__chat-message"
|
||||
class="wrn-next__chat-message"
|
||||
data-direction="{messageDirection(item)}"
|
||||
aria-label="{messageDirection(item) === 'outgoing' ? 'Sent message' : 'Received message'}"
|
||||
>
|
||||
<div class="wire-next__chat-row">
|
||||
<div class="wrn-next__chat-row">
|
||||
{#if showAvatars && (item.avatarSrc || item.avatarFallback)}
|
||||
<button
|
||||
class="wire-next__chat-avatar"
|
||||
class="wrn-next__chat-avatar"
|
||||
type="button"
|
||||
aria-label="{item.avatarLabel || item.author || 'Message author'}"
|
||||
@click="selectAvatar(event, item, index)"
|
||||
@@ -104,7 +102,7 @@ component ChatBubble {
|
||||
{/if}
|
||||
|
||||
<div
|
||||
class="wire-next__chat-content"
|
||||
class="wrn-next__chat-content"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
@click="selectMessage(item, index)"
|
||||
@@ -131,7 +129,7 @@ component ChatBubble {
|
||||
</div>
|
||||
|
||||
{#if showMetadata && (item.timestamp || item.status || item.actionLabel)}
|
||||
<footer class="wire-next__chat-meta" data-tone="{item.statusTone || 'muted'}">
|
||||
<footer class="wrn-next__chat-meta" data-tone="{item.statusTone || 'muted'}">
|
||||
{#if item.statusIcon}<span class="{item.statusIcon}" aria-hidden="true"></span>{/if}
|
||||
{#if item.status}<span>{item.status}</span>{/if}
|
||||
{#if item.timestamp}<time datetime="{item.datetime || ''}">{item.timestamp}</time>{/if}
|
||||
@@ -148,48 +146,47 @@ component ChatBubble {
|
||||
{/if}
|
||||
<slot />
|
||||
</section>
|
||||
<ComponentBaseStyles hidden />
|
||||
}
|
||||
|
||||
style {
|
||||
.wire-next--chat-bubble.wire-component--size-sm {
|
||||
--wire-chat-padding: 0.75rem;
|
||||
.wrn-next--chat-bubble.wrn-component--size-sm {
|
||||
--wrn-chat-padding: 0.75rem;
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
.wire-next--chat-bubble.wire-component--size-lg {
|
||||
--wire-chat-padding: 1.25rem;
|
||||
.wrn-next--chat-bubble.wrn-component--size-lg {
|
||||
--wrn-chat-padding: 1.25rem;
|
||||
font-size: 1.0625rem;
|
||||
}
|
||||
|
||||
.wire-next--chat-bubble {
|
||||
--wire-chat-color: var(--wire-component-color, var(--wire-color-primary));
|
||||
--wire-chat-padding: 1rem;
|
||||
.wrn-next--chat-bubble {
|
||||
--wrn-chat-color: var(--wrn-component-color, var(--wrn-color-primary));
|
||||
--wrn-chat-padding: 1rem;
|
||||
display: grid;
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
gap: 1rem;
|
||||
color: var(--wire-color-text);
|
||||
color: var(--wrn-color-text);
|
||||
}
|
||||
|
||||
.wire-next__chat-header h3,
|
||||
.wire-next__chat-header p,
|
||||
.wire-next__chat-content h4,
|
||||
.wire-next__chat-content p {
|
||||
.wrn-next__chat-header h3,
|
||||
.wrn-next__chat-header p,
|
||||
.wrn-next__chat-content h4,
|
||||
.wrn-next__chat-content p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.wire-next__chat-header p {
|
||||
.wrn-next__chat-header p {
|
||||
margin-top: 0.35rem;
|
||||
color: var(--wire-color-text-muted);
|
||||
color: var(--wrn-color-text-muted);
|
||||
}
|
||||
|
||||
.wire-next__chat-thread {
|
||||
.wrn-next__chat-thread {
|
||||
display: grid;
|
||||
min-width: 0;
|
||||
gap: 1.25rem;
|
||||
}
|
||||
|
||||
.wire-next__chat-message {
|
||||
.wrn-next__chat-message {
|
||||
display: grid;
|
||||
width: min(78%, 34rem);
|
||||
min-width: 0;
|
||||
@@ -197,134 +194,134 @@ component ChatBubble {
|
||||
gap: 0.4rem;
|
||||
}
|
||||
|
||||
.wire-next__chat-message[data-direction="outgoing"] {
|
||||
.wrn-next__chat-message[data-direction="outgoing"] {
|
||||
justify-self: end;
|
||||
}
|
||||
|
||||
.wire-next--chat-bubble[data-one-sided="true"] .wire-next__chat-message {
|
||||
.wrn-next--chat-bubble[data-one-sided="true"] .wrn-next__chat-message {
|
||||
justify-self: start;
|
||||
}
|
||||
|
||||
.wire-next__chat-row {
|
||||
.wrn-next__chat-row {
|
||||
display: flex;
|
||||
min-width: 0;
|
||||
align-items: flex-start;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
|
||||
.wire-next__chat-message[data-direction="outgoing"] .wire-next__chat-row {
|
||||
.wrn-next__chat-message[data-direction="outgoing"] .wrn-next__chat-row {
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
|
||||
.wire-next--chat-bubble[data-one-sided="true"]
|
||||
.wire-next__chat-message[data-direction="outgoing"]
|
||||
.wire-next__chat-row {
|
||||
.wrn-next--chat-bubble[data-one-sided="true"]
|
||||
.wrn-next__chat-message[data-direction="outgoing"]
|
||||
.wrn-next__chat-row {
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.wire-next__chat-content {
|
||||
.wrn-next__chat-content {
|
||||
min-width: 0;
|
||||
padding: var(--wire-chat-padding);
|
||||
border: 1px solid var(--wire-color-border);
|
||||
padding: var(--wrn-chat-padding);
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: 1rem;
|
||||
background: var(--wire-color-surface-raised, var(--wire-color-surface));
|
||||
color: var(--wire-color-text);
|
||||
background: var(--wrn-color-surface-raised, var(--wrn-color-surface));
|
||||
color: var(--wrn-color-text);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.wire-next__chat-content:focus-visible {
|
||||
outline: 2px solid var(--wire-chat-color);
|
||||
.wrn-next__chat-content:focus-visible {
|
||||
outline: 2px solid var(--wrn-chat-color);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
.wire-next__chat-message[data-direction="outgoing"] .wire-next__chat-content {
|
||||
border-color: var(--wire-chat-color);
|
||||
background: var(--wire-chat-color);
|
||||
color: var(--wire-color-primary-contrast, #fff);
|
||||
.wrn-next__chat-message[data-direction="outgoing"] .wrn-next__chat-content {
|
||||
border-color: var(--wrn-chat-color);
|
||||
background: var(--wrn-chat-color);
|
||||
color: var(--wrn-color-primary-contrast, #fff);
|
||||
}
|
||||
|
||||
.wire-next__chat-message[data-direction="outgoing"] .wire-next__chat-content :is(h4, p, li, span) {
|
||||
.wrn-next__chat-message[data-direction="outgoing"] .wrn-next__chat-content :is(h4, p, li, span) {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.wire-next__chat-content h4 {
|
||||
.wrn-next__chat-content h4 {
|
||||
margin-bottom: 0.65rem;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
.wire-next__chat-content p + p,
|
||||
.wire-next__chat-content p + nav {
|
||||
.wrn-next__chat-content p + p,
|
||||
.wrn-next__chat-content p + nav {
|
||||
margin-top: 0.75rem;
|
||||
}
|
||||
|
||||
.wire-next__chat-content ul {
|
||||
.wrn-next__chat-content ul {
|
||||
display: grid;
|
||||
margin: 0.55rem 0 0;
|
||||
padding-inline-start: 1.25rem;
|
||||
gap: 0.35rem;
|
||||
}
|
||||
|
||||
.wire-next__chat-content nav {
|
||||
.wrn-next__chat-content nav {
|
||||
display: grid;
|
||||
margin-top: 0.75rem;
|
||||
gap: 0.3rem;
|
||||
}
|
||||
|
||||
.wire-next__chat-content a {
|
||||
color: var(--wire-chat-color);
|
||||
.wrn-next__chat-content a {
|
||||
color: var(--wrn-chat-color);
|
||||
font-weight: 650;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.wire-next__chat-message[data-direction="outgoing"] .wire-next__chat-content a {
|
||||
.wrn-next__chat-message[data-direction="outgoing"] .wrn-next__chat-content a {
|
||||
color: inherit;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.wire-next__chat-avatar {
|
||||
.wrn-next__chat-avatar {
|
||||
display: grid;
|
||||
flex: 0 0 2.5rem;
|
||||
width: 2.5rem;
|
||||
min-height: 2.5rem;
|
||||
overflow: hidden;
|
||||
padding: 0;
|
||||
border: 1px solid var(--wire-color-border);
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: 999px;
|
||||
background: var(--wire-color-surface-raised, var(--wire-color-surface));
|
||||
color: var(--wire-color-text);
|
||||
background: var(--wrn-color-surface-raised, var(--wrn-color-surface));
|
||||
color: var(--wrn-color-text);
|
||||
cursor: pointer;
|
||||
place-items: center;
|
||||
}
|
||||
|
||||
.wire-next__chat-avatar img {
|
||||
.wrn-next__chat-avatar img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.wire-next__chat-avatar:focus-visible {
|
||||
outline: 2px solid var(--wire-chat-color);
|
||||
.wrn-next__chat-avatar:focus-visible {
|
||||
outline: 2px solid var(--wrn-chat-color);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
.wire-next__chat-meta {
|
||||
.wrn-next__chat-meta {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.3rem;
|
||||
padding-inline: calc(2.5rem + 0.75rem);
|
||||
color: var(--wire-color-text-muted);
|
||||
color: var(--wrn-color-text-muted);
|
||||
font-size: 0.78em;
|
||||
}
|
||||
|
||||
.wire-next__chat-message[data-direction="outgoing"] .wire-next__chat-meta {
|
||||
.wrn-next__chat-message[data-direction="outgoing"] .wrn-next__chat-meta {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.wire-next__chat-meta[data-tone="danger"] {
|
||||
color: var(--wire-color-danger);
|
||||
.wrn-next__chat-meta[data-tone="danger"] {
|
||||
color: var(--wrn-color-danger);
|
||||
}
|
||||
|
||||
.wire-next__chat-meta button {
|
||||
.wrn-next__chat-meta button {
|
||||
padding: 0;
|
||||
border: 0;
|
||||
background: transparent;
|
||||
@@ -336,17 +333,86 @@ component ChatBubble {
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.wire-next__chat-message {
|
||||
.wrn-next__chat-message {
|
||||
width: min(92%, 34rem);
|
||||
}
|
||||
.wire-next__chat-avatar {
|
||||
.wrn-next__chat-avatar {
|
||||
flex-basis: 2rem;
|
||||
width: 2rem;
|
||||
min-height: 2rem;
|
||||
}
|
||||
.wire-next__chat-meta {
|
||||
.wrn-next__chat-meta {
|
||||
padding-inline: 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Shared component foundation. */
|
||||
|
||||
.wrn-component {
|
||||
--wrn-component-color: var(--wrn-color-primary);
|
||||
--wrn-component-scale: 1;
|
||||
margin: 0;
|
||||
color: var(--wrn-color-text);
|
||||
font-family: var(--wrn-font-sans, inherit);
|
||||
}
|
||||
|
||||
.wrn-component--color-primary {
|
||||
--wrn-component-color: var(--wrn-color-primary);
|
||||
}
|
||||
|
||||
.wrn-component--color-secondary {
|
||||
--wrn-component-color: var(--wrn-color-secondary);
|
||||
}
|
||||
|
||||
.wrn-component--color-success {
|
||||
--wrn-component-color: var(--wrn-color-success);
|
||||
}
|
||||
|
||||
.wrn-component--color-warning {
|
||||
--wrn-component-color: var(--wrn-color-warning);
|
||||
}
|
||||
|
||||
.wrn-component--color-danger {
|
||||
--wrn-component-color: var(--wrn-color-danger);
|
||||
}
|
||||
|
||||
.wrn-component--color-info {
|
||||
--wrn-component-color: var(--wrn-color-info);
|
||||
}
|
||||
|
||||
.wrn-component--size-xs {
|
||||
--wrn-component-scale: 0.78;
|
||||
}
|
||||
|
||||
.wrn-component--size-sm {
|
||||
--wrn-component-scale: 0.88;
|
||||
}
|
||||
|
||||
.wrn-component--size-default,
|
||||
.wrn-component--size-md {
|
||||
--wrn-component-scale: 1;
|
||||
}
|
||||
|
||||
.wrn-component--size-lg {
|
||||
--wrn-component-scale: 1.14;
|
||||
}
|
||||
|
||||
.wrn-component--size-xl {
|
||||
--wrn-component-scale: 1.28;
|
||||
}
|
||||
|
||||
.wrn-component:not(.wrn-btn) {
|
||||
font-size: calc(1em * var(--wrn-component-scale));
|
||||
}
|
||||
|
||||
.wrn-component :is(a, button, input, select, textarea):focus-visible {
|
||||
outline-color: var(--wrn-component-color);
|
||||
}
|
||||
|
||||
.wrn-component p {
|
||||
margin: 0;
|
||||
color: var(--wrn-color-muted);
|
||||
line-height: 1.6;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,25 +54,25 @@ component Clipboard {
|
||||
data-status='{status}'
|
||||
data-size='{size}'
|
||||
data-color='{color}'
|
||||
class='wire-clipboard {class}'
|
||||
class='wrn-clipboard {class}'
|
||||
>
|
||||
{#if title}<strong class="wire-clipboard__title">{title}</strong>{/if}
|
||||
{#if description}<p class="wire-clipboard__description">{description}</p>{/if}
|
||||
<div class="wire-clipboard__control">
|
||||
{#if title}<strong class="wrn-clipboard__title">{title}</strong>{/if}
|
||||
{#if description}<p class="wrn-clipboard__description">{description}</p>{/if}
|
||||
<div class="wrn-clipboard__control">
|
||||
{#if code}
|
||||
<code class="wire-clipboard__value">{value}</code>
|
||||
<code class="wrn-clipboard__value">{value}</code>
|
||||
{:else}
|
||||
<span class="wire-clipboard__value">{value}</span>
|
||||
<span class="wrn-clipboard__value">{value}</span>
|
||||
{/if}
|
||||
<button
|
||||
type="button"
|
||||
class="wire-clipboard__button"
|
||||
class="wrn-clipboard__button"
|
||||
disabled='{disabled}'
|
||||
aria-label='{status === "success" ? copiedLabel : status === "error" ? errorLabel : label}'
|
||||
@click='copyValue(event)'
|
||||
>
|
||||
<span class="icon-[lucide--copy] wire-clipboard__icon" data-show='status !== "success"' aria-hidden="true"></span>
|
||||
<span class="icon-[lucide--check] wire-clipboard__icon" data-show='status === "success"' aria-hidden="true"></span>
|
||||
<span class="icon-[lucide--copy] wrn-clipboard__icon" data-show='status !== "success"' aria-hidden="true"></span>
|
||||
<span class="icon-[lucide--check] wrn-clipboard__icon" data-show='status === "success"' aria-hidden="true"></span>
|
||||
<span>{status === "success" ? copiedLabel : status === "error" ? errorLabel : label}</span>
|
||||
</button>
|
||||
</div>
|
||||
@@ -81,17 +81,17 @@ component Clipboard {
|
||||
}
|
||||
|
||||
style {
|
||||
.wire-clipboard { display: grid; gap: 0.5rem; color: var(--wire-color-text); }
|
||||
.wire-clipboard__title { font-size: 0.875rem; }
|
||||
.wire-clipboard__description { margin: 0; color: var(--wire-color-muted); font-size: 0.8rem; }
|
||||
.wire-clipboard__control { display: flex; min-width: 0; align-items: stretch; overflow: hidden; border: 1px solid var(--wire-color-border); border-radius: var(--wire-radius); background: var(--wire-color-surface); box-shadow: var(--wire-shadow-1); }
|
||||
.wire-clipboard__value { min-width: 0; flex: 1; overflow: auto; padding: 0.7rem 0.85rem; color: var(--wire-color-text); background: var(--wire-color-surface-2); font: inherit; font-family: var(--wire-font-mono, ui-monospace, monospace); white-space: nowrap; }
|
||||
.wire-clipboard__button { display: inline-flex; align-items: center; gap: 0.4rem; padding: 0.6rem 0.85rem; border: 0; border-left: 1px solid var(--wire-color-border); color: var(--wire-color-primary); background: transparent; font: inherit; font-size: 0.8rem; font-weight: 700; cursor: pointer; }
|
||||
.wire-clipboard__button:hover { background: var(--wire-color-primary-soft); }
|
||||
.wire-clipboard__button:focus-visible { outline: 2px solid var(--wire-color-focus); outline-offset: -3px; }
|
||||
.wire-clipboard__button:disabled { cursor: not-allowed; opacity: 0.55; }
|
||||
.wire-clipboard[data-status="success"] .wire-clipboard__button { color: var(--wire-color-success); }
|
||||
.wire-clipboard[data-status="error"] .wire-clipboard__button { color: var(--wire-color-danger); }
|
||||
.wire-clipboard__icon { width: 1rem; height: 1rem; flex: none; }
|
||||
.wrn-clipboard { display: grid; gap: 0.5rem; color: var(--wrn-color-text); }
|
||||
.wrn-clipboard__title { font-size: 0.875rem; }
|
||||
.wrn-clipboard__description { margin: 0; color: var(--wrn-color-muted); font-size: 0.8rem; }
|
||||
.wrn-clipboard__control { display: flex; min-width: 0; align-items: stretch; overflow: hidden; border: 1px solid var(--wrn-color-border); border-radius: var(--wrn-radius); background: var(--wrn-color-surface); box-shadow: var(--wrn-shadow-1); }
|
||||
.wrn-clipboard__value { min-width: 0; flex: 1; overflow: auto; padding: 0.7rem 0.85rem; color: var(--wrn-color-text); background: var(--wrn-color-surface-2); font: inherit; font-family: var(--wrn-font-mono, ui-monospace, monospace); white-space: nowrap; }
|
||||
.wrn-clipboard__button { display: inline-flex; align-items: center; gap: 0.4rem; padding: 0.6rem 0.85rem; border: 0; border-left: 1px solid var(--wrn-color-border); color: var(--wrn-color-primary); background: transparent; font: inherit; font-size: 0.8rem; font-weight: 700; cursor: pointer; }
|
||||
.wrn-clipboard__button:hover { background: var(--wrn-color-primary-soft); }
|
||||
.wrn-clipboard__button:focus-visible { outline: 2px solid var(--wrn-color-focus); outline-offset: -3px; }
|
||||
.wrn-clipboard__button:disabled { cursor: not-allowed; opacity: 0.55; }
|
||||
.wrn-clipboard[data-status="success"] .wrn-clipboard__button { color: var(--wrn-color-success); }
|
||||
.wrn-clipboard[data-status="error"] .wrn-clipboard__button { color: var(--wrn-color-danger); }
|
||||
.wrn-clipboard__icon { width: 1rem; height: 1rem; flex: none; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import ComponentBaseStyles from "../styles/ComponentBaseStyles.wrn"
|
||||
|
||||
component Collapse {
|
||||
outputs {
|
||||
toggle(payload: { index: number; item: string | number | boolean | null | object; open: boolean; openIndexes: number[] })
|
||||
@@ -53,18 +51,18 @@ size: string = "default"
|
||||
view {
|
||||
<section
|
||||
{...attrs}
|
||||
class="wire-component wire-component--color-{color} wire-component--size-{size} wire-next--collapse {class}"
|
||||
class="wrn-component wrn-component--color-{color} wrn-component--size-{size} wrn-next--collapse {class}"
|
||||
data-mode="{mode}"
|
||||
aria-label="{ariaLabel}"
|
||||
>
|
||||
{#each items as item, index}
|
||||
<article class="wire-next__collapse-item" data-open="{isOpen(index)}">
|
||||
<article class="wrn-next__collapse-item" data-open="{isOpen(index)}">
|
||||
{#if mode === "inline" && item.preview}
|
||||
<p class="wire-next__collapse-preview">{item.preview}</p>
|
||||
<p class="wrn-next__collapse-preview">{item.preview}</p>
|
||||
{/if}
|
||||
|
||||
<button
|
||||
class="wire-next__collapse-trigger"
|
||||
class="wrn-next__collapse-trigger"
|
||||
type="button"
|
||||
aria-expanded="{isOpen(index) ? 'true' : 'false'}"
|
||||
aria-controls="{item.id || 'collapse-panel-' + index}"
|
||||
@@ -72,17 +70,17 @@ size: string = "default"
|
||||
@click="toggleItem(index, item)"
|
||||
>
|
||||
<span>{isOpen(index) ? (item.closeLabel || "Read less") : item.label}</span>
|
||||
<span class="icon-[lucide--chevron-down] wire-next__collapse-chevron" aria-hidden="true"></span>
|
||||
<span class="icon-[lucide--chevron-down] wrn-next__collapse-chevron" aria-hidden="true"></span>
|
||||
</button>
|
||||
|
||||
<div
|
||||
id="{item.id || 'collapse-panel-' + index}"
|
||||
class="wire-next__collapse-panel"
|
||||
class="wrn-next__collapse-panel"
|
||||
data-open="{isOpen(index)}"
|
||||
aria-hidden="{isOpen(index) ? 'false' : 'true'}"
|
||||
inert="{!isOpen(index)}"
|
||||
>
|
||||
<div class="wire-next__collapse-content">
|
||||
<div class="wrn-next__collapse-content">
|
||||
{#if item.title}<h4>{item.title}</h4>{/if}
|
||||
{#if item.content}<p>{item.content}</p>{/if}
|
||||
{#if item.links && item.links.length}
|
||||
@@ -96,133 +94,132 @@ size: string = "default"
|
||||
{/each}
|
||||
<slot />
|
||||
</section>
|
||||
<ComponentBaseStyles hidden />
|
||||
}
|
||||
|
||||
style {
|
||||
.wire-next--collapse.wire-component--size-sm {
|
||||
.wrn-next--collapse.wrn-component--size-sm {
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
.wire-next--collapse.wire-component--size-lg {
|
||||
.wrn-next--collapse.wrn-component--size-lg {
|
||||
font-size: 1.0625rem;
|
||||
}
|
||||
|
||||
.wire-next--collapse {
|
||||
--wire-collapse-color: var(--wire-component-color, var(--wire-color-primary));
|
||||
.wrn-next--collapse {
|
||||
--wrn-collapse-color: var(--wrn-component-color, var(--wrn-color-primary));
|
||||
display: grid;
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
gap: 0.75rem;
|
||||
color: var(--wire-color-text);
|
||||
color: var(--wrn-color-text);
|
||||
}
|
||||
|
||||
.wire-next__collapse-item {
|
||||
.wrn-next__collapse-item {
|
||||
display: grid;
|
||||
min-width: 0;
|
||||
justify-items: start;
|
||||
gap: 0;
|
||||
}
|
||||
|
||||
.wire-next__collapse-trigger {
|
||||
.wrn-next__collapse-trigger {
|
||||
display: inline-flex;
|
||||
min-height: 2.75rem;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 0.55rem;
|
||||
padding: 0.7rem 1rem;
|
||||
border: 1px solid var(--wire-collapse-color);
|
||||
border-radius: var(--wire-radius-sm);
|
||||
background: var(--wire-collapse-color);
|
||||
color: var(--wire-color-primary-contrast, #fff);
|
||||
border: 1px solid var(--wrn-collapse-color);
|
||||
border-radius: var(--wrn-radius-sm);
|
||||
background: var(--wrn-collapse-color);
|
||||
color: var(--wrn-color-primary-contrast, #fff);
|
||||
font: inherit;
|
||||
font-weight: 700;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.wire-next__collapse-trigger:focus-visible {
|
||||
outline: 2px solid var(--wire-collapse-color);
|
||||
.wrn-next__collapse-trigger:focus-visible {
|
||||
outline: 2px solid var(--wrn-collapse-color);
|
||||
outline-offset: 3px;
|
||||
}
|
||||
|
||||
.wire-next__collapse-trigger:disabled {
|
||||
.wrn-next__collapse-trigger:disabled {
|
||||
cursor: not-allowed;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.wire-next__collapse-chevron {
|
||||
transition: transform var(--wire-motion-fast) var(--wire-ease-standard);
|
||||
.wrn-next__collapse-chevron {
|
||||
transition: transform var(--wrn-motion-fast) var(--wrn-ease-standard);
|
||||
}
|
||||
|
||||
.wire-next__collapse-item[data-open="true"] .wire-next__collapse-chevron {
|
||||
.wrn-next__collapse-item[data-open="true"] .wrn-next__collapse-chevron {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
.wire-next__collapse-panel {
|
||||
.wrn-next__collapse-panel {
|
||||
width: min(100%, 42rem);
|
||||
max-height: 0;
|
||||
overflow: hidden;
|
||||
margin-top: 0;
|
||||
opacity: 0;
|
||||
transition:
|
||||
max-height 350ms var(--wire-ease-emphasized),
|
||||
margin-top 300ms var(--wire-ease-emphasized),
|
||||
opacity 200ms var(--wire-ease-standard);
|
||||
max-height 350ms var(--wrn-ease-emphasized),
|
||||
margin-top 300ms var(--wrn-ease-emphasized),
|
||||
opacity 200ms var(--wrn-ease-standard);
|
||||
}
|
||||
|
||||
.wire-next__collapse-panel[data-open="true"] {
|
||||
.wrn-next__collapse-panel[data-open="true"] {
|
||||
max-height: 40rem;
|
||||
margin-top: 0.75rem;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.wire-next__collapse-content {
|
||||
.wrn-next__collapse-content {
|
||||
display: grid;
|
||||
overflow: hidden;
|
||||
min-height: 0;
|
||||
gap: 0.65rem;
|
||||
padding: 1rem;
|
||||
border: 1px solid var(--wire-color-border);
|
||||
border-radius: var(--wire-radius-md);
|
||||
background: var(--wire-color-surface-raised, var(--wire-color-surface));
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: var(--wrn-radius-md);
|
||||
background: var(--wrn-color-surface-raised, var(--wrn-color-surface));
|
||||
}
|
||||
|
||||
.wire-next__collapse-content h4,
|
||||
.wire-next__collapse-content p,
|
||||
.wire-next__collapse-preview {
|
||||
.wrn-next__collapse-content h4,
|
||||
.wrn-next__collapse-content p,
|
||||
.wrn-next__collapse-preview {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.wire-next__collapse-content nav {
|
||||
.wrn-next__collapse-content nav {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
|
||||
.wire-next__collapse-content a {
|
||||
color: var(--wire-collapse-color);
|
||||
.wrn-next__collapse-content a {
|
||||
color: var(--wrn-collapse-color);
|
||||
font-weight: 650;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.wire-next--collapse[data-mode="inline"] .wire-next__collapse-item {
|
||||
.wrn-next--collapse[data-mode="inline"] .wrn-next__collapse-item {
|
||||
gap: 0;
|
||||
}
|
||||
|
||||
.wire-next--collapse[data-mode="inline"] .wire-next__collapse-preview {
|
||||
.wrn-next--collapse[data-mode="inline"] .wrn-next__collapse-preview {
|
||||
order: 1;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.wire-next--collapse[data-mode="inline"] .wire-next__collapse-panel {
|
||||
.wrn-next--collapse[data-mode="inline"] .wrn-next__collapse-panel {
|
||||
order: 2;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.wire-next--collapse[data-mode="inline"] .wire-next__collapse-panel[data-open="true"] {
|
||||
.wrn-next--collapse[data-mode="inline"] .wrn-next__collapse-panel[data-open="true"] {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.wire-next--collapse[data-mode="inline"] .wire-next__collapse-trigger {
|
||||
.wrn-next--collapse[data-mode="inline"] .wrn-next__collapse-trigger {
|
||||
order: 3;
|
||||
margin-top: 0.5rem;
|
||||
min-height: auto;
|
||||
@@ -230,20 +227,89 @@ size: string = "default"
|
||||
border: 0;
|
||||
border-radius: 0;
|
||||
background: transparent;
|
||||
color: var(--wire-collapse-color);
|
||||
color: var(--wrn-collapse-color);
|
||||
}
|
||||
|
||||
.wire-next--collapse[data-mode="inline"] .wire-next__collapse-content {
|
||||
.wrn-next--collapse[data-mode="inline"] .wrn-next__collapse-content {
|
||||
padding: 0;
|
||||
border: 0;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.wire-next__collapse-chevron,
|
||||
.wire-next__collapse-panel {
|
||||
.wrn-next__collapse-chevron,
|
||||
.wrn-next__collapse-panel {
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* Shared component foundation. */
|
||||
|
||||
.wrn-component {
|
||||
--wrn-component-color: var(--wrn-color-primary);
|
||||
--wrn-component-scale: 1;
|
||||
margin: 0;
|
||||
color: var(--wrn-color-text);
|
||||
font-family: var(--wrn-font-sans, inherit);
|
||||
}
|
||||
|
||||
.wrn-component--color-primary {
|
||||
--wrn-component-color: var(--wrn-color-primary);
|
||||
}
|
||||
|
||||
.wrn-component--color-secondary {
|
||||
--wrn-component-color: var(--wrn-color-secondary);
|
||||
}
|
||||
|
||||
.wrn-component--color-success {
|
||||
--wrn-component-color: var(--wrn-color-success);
|
||||
}
|
||||
|
||||
.wrn-component--color-warning {
|
||||
--wrn-component-color: var(--wrn-color-warning);
|
||||
}
|
||||
|
||||
.wrn-component--color-danger {
|
||||
--wrn-component-color: var(--wrn-color-danger);
|
||||
}
|
||||
|
||||
.wrn-component--color-info {
|
||||
--wrn-component-color: var(--wrn-color-info);
|
||||
}
|
||||
|
||||
.wrn-component--size-xs {
|
||||
--wrn-component-scale: 0.78;
|
||||
}
|
||||
|
||||
.wrn-component--size-sm {
|
||||
--wrn-component-scale: 0.88;
|
||||
}
|
||||
|
||||
.wrn-component--size-default,
|
||||
.wrn-component--size-md {
|
||||
--wrn-component-scale: 1;
|
||||
}
|
||||
|
||||
.wrn-component--size-lg {
|
||||
--wrn-component-scale: 1.14;
|
||||
}
|
||||
|
||||
.wrn-component--size-xl {
|
||||
--wrn-component-scale: 1.28;
|
||||
}
|
||||
|
||||
.wrn-component:not(.wrn-btn) {
|
||||
font-size: calc(1em * var(--wrn-component-scale));
|
||||
}
|
||||
|
||||
.wrn-component :is(a, button, input, select, textarea):focus-visible {
|
||||
outline-color: var(--wrn-component-color);
|
||||
}
|
||||
|
||||
.wrn-component p {
|
||||
margin: 0;
|
||||
color: var(--wrn-color-muted);
|
||||
line-height: 1.6;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
import FieldStyles from "../styles/FieldStyles.wrn"
|
||||
|
||||
import ComponentBaseStyles from "../styles/ComponentBaseStyles.wrn"
|
||||
|
||||
component ColorPicker {
|
||||
outputs {
|
||||
input(payload: { value?: string | number | boolean | null; values?: Array<string | number | boolean | null | object>; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | string | number | boolean | null)
|
||||
@@ -36,19 +32,576 @@ component ColorPicker {
|
||||
client function preventReadonly(sourceEvent) { if (readonly) sourceEvent.preventDefault() }
|
||||
}
|
||||
view {
|
||||
<div {...attrs} class="wire-component wire-component--color-{color} wire-component--size-{size} wire-next--field wire-component--color-picker {class}" data-variant="{variant}" data-inline="{inline}" data-invalid="{error ? 'true' : 'false'}">
|
||||
<div class="wire-next__field-heading"><label class="{hiddenLabel ? 'wire-next__sr-only' : ''}" for="{id || name}">{label}</label>{#if cornerHint}<span class="wire-next__field-hint">{cornerHint}</span>{/if}</div>
|
||||
<div class="wire-next__color-control" data-icon-position="{iconPosition}">{#if icon}<span class="{icon}" aria-hidden="true"></span>{/if}<input id="{id || name}" type="color" name="{name}" value="{value}" disabled="{disabled}" required="{required}" readonly="{readonly}" aria-invalid="{error ? 'true' : 'false'}" @click="preventReadonly(event)" @input="emitField('input', event)" @change="emitField('change', event)" @focus="emitField('focus', event)" @blur="emitField('blur', event)" /><output>{value}</output></div>
|
||||
{#if helperText}<small class="wire-next__field-help">{helperText}</small>{/if}<small class="wire-next__field-error" data-error="{name}">{error}</small>
|
||||
<div {...attrs} class="wrn-component wrn-component--color-{color} wrn-component--size-{size} wrn-next--field wrn-component--color-picker {class}" data-variant="{variant}" data-inline="{inline}" data-invalid="{error ? 'true' : 'false'}">
|
||||
<div class="wrn-next__field-heading"><label class="{hiddenLabel ? 'wrn-next__sr-only' : ''}" for="{id || name}">{label}</label>{#if cornerHint}<span class="wrn-next__field-hint">{cornerHint}</span>{/if}</div>
|
||||
<div class="wrn-next__color-control" data-icon-position="{iconPosition}">{#if icon}<span class="{icon}" aria-hidden="true"></span>{/if}<input id="{id || name}" type="color" name="{name}" value="{value}" disabled="{disabled}" required="{required}" readonly="{readonly}" aria-invalid="{error ? 'true' : 'false'}" @click="preventReadonly(event)" @input="emitField('input', event)" @change="emitField('change', event)" @focus="emitField('focus', event)" @blur="emitField('blur', event)" /><output>{value}</output></div>
|
||||
{#if helperText}<small class="wrn-next__field-help">{helperText}</small>{/if}<small class="wrn-next__field-error" data-error="{name}">{error}</small>
|
||||
</div>
|
||||
<FieldStyles hidden />
|
||||
<ComponentBaseStyles hidden />
|
||||
}
|
||||
|
||||
style {
|
||||
.wire-next__color-control input[type="color"] {
|
||||
.wrn-next__color-control input[type="color"] {
|
||||
width: 3rem;
|
||||
padding: 0.2rem;
|
||||
}
|
||||
|
||||
/* Shared component foundation. */
|
||||
|
||||
.wrn-component {
|
||||
--wrn-component-color: var(--wrn-color-primary);
|
||||
--wrn-component-scale: 1;
|
||||
margin: 0;
|
||||
color: var(--wrn-color-text);
|
||||
font-family: var(--wrn-font-sans, inherit);
|
||||
}
|
||||
|
||||
.wrn-component--color-primary {
|
||||
--wrn-component-color: var(--wrn-color-primary);
|
||||
}
|
||||
|
||||
.wrn-component--color-secondary {
|
||||
--wrn-component-color: var(--wrn-color-secondary);
|
||||
}
|
||||
|
||||
.wrn-component--color-success {
|
||||
--wrn-component-color: var(--wrn-color-success);
|
||||
}
|
||||
|
||||
.wrn-component--color-warning {
|
||||
--wrn-component-color: var(--wrn-color-warning);
|
||||
}
|
||||
|
||||
.wrn-component--color-danger {
|
||||
--wrn-component-color: var(--wrn-color-danger);
|
||||
}
|
||||
|
||||
.wrn-component--color-info {
|
||||
--wrn-component-color: var(--wrn-color-info);
|
||||
}
|
||||
|
||||
.wrn-component--size-xs {
|
||||
--wrn-component-scale: 0.78;
|
||||
}
|
||||
|
||||
.wrn-component--size-sm {
|
||||
--wrn-component-scale: 0.88;
|
||||
}
|
||||
|
||||
.wrn-component--size-default,
|
||||
.wrn-component--size-md {
|
||||
--wrn-component-scale: 1;
|
||||
}
|
||||
|
||||
.wrn-component--size-lg {
|
||||
--wrn-component-scale: 1.14;
|
||||
}
|
||||
|
||||
.wrn-component--size-xl {
|
||||
--wrn-component-scale: 1.28;
|
||||
}
|
||||
|
||||
.wrn-component:not(.wrn-btn) {
|
||||
font-size: calc(1em * var(--wrn-component-scale));
|
||||
}
|
||||
|
||||
.wrn-component :is(a, button, input, select, textarea):focus-visible {
|
||||
outline-color: var(--wrn-component-color);
|
||||
}
|
||||
|
||||
.wrn-component p {
|
||||
margin: 0;
|
||||
color: var(--wrn-color-muted);
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
/* Shared field foundation. */
|
||||
|
||||
/* Validation states set by the browser validation runtime. */
|
||||
.wrn-invalid {
|
||||
border-color: var(--wrn-color-danger) !important;
|
||||
}
|
||||
|
||||
.wrn-field-error {
|
||||
display: block;
|
||||
min-height: 1em;
|
||||
margin-top: 0.25rem;
|
||||
color: var(--wrn-color-danger);
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
.wrn-next--choice {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.55rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.wrn-next--choice input {
|
||||
width: 1.1rem;
|
||||
height: 1.1rem;
|
||||
accent-color: var(--wrn-color-primary);
|
||||
}
|
||||
|
||||
.wrn-next--field {
|
||||
display: grid;
|
||||
width: min(100%, 28rem);
|
||||
gap: 0.4rem;
|
||||
font-size: 0.78rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
.wrn-next--field :where(input, textarea, select) {
|
||||
width: 100%;
|
||||
min-height: 2.65rem;
|
||||
padding: 0.6rem 0.7rem;
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: 0.6rem;
|
||||
outline: 0;
|
||||
color: var(--wrn-color-text);
|
||||
background: var(--wrn-color-bg);
|
||||
font: inherit;
|
||||
font-weight: 500;
|
||||
}
|
||||
.wrn-auth-form form > .wrn-next--field,
|
||||
.wrn-auth-form form > .wrn-field {
|
||||
width: 100%;
|
||||
max-width: none;
|
||||
}
|
||||
.wrn-auth-form__submit > .wrn-btn {
|
||||
width: 100%;
|
||||
min-height: 3rem;
|
||||
border-radius: 0.75rem;
|
||||
box-shadow: 0 0.8rem 1.8rem color-mix(in srgb, var(--wrn-btn-color) 20%, transparent);
|
||||
}
|
||||
.wrn-next--field :where(input, textarea, select):focus-visible {
|
||||
border-color: var(--wrn-color-primary);
|
||||
box-shadow: 0 0 0 3px color-mix(in srgb, var(--wrn-color-primary) 16%, transparent);
|
||||
}
|
||||
.wrn-next--field textarea {
|
||||
resize: vertical;
|
||||
}
|
||||
.wrn-next--field,
|
||||
.wrn-next--choice-field {
|
||||
--wrn-field-color: var(--wrn-component-color, var(--wrn-color-primary));
|
||||
width: min(100%, 34rem);
|
||||
min-width: 0;
|
||||
color: var(--wrn-color-text);
|
||||
font-size: 0.8125rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
.wrn-next--field.wrn-next--size-sm,
|
||||
.wrn-next--choice-field.wrn-next--size-sm {
|
||||
font-size: 0.8125rem;
|
||||
}
|
||||
.wrn-next--field.wrn-next--size-lg,
|
||||
.wrn-next--choice-field.wrn-next--size-lg {
|
||||
font-size: 1rem;
|
||||
}
|
||||
.wrn-next__field-heading {
|
||||
display: flex;
|
||||
min-width: 0;
|
||||
align-items: baseline;
|
||||
justify-content: space-between;
|
||||
gap: 1rem;
|
||||
}
|
||||
.wrn-next__field-heading label {
|
||||
color: var(--wrn-color-text);
|
||||
font-weight: 600;
|
||||
}
|
||||
.wrn-next__field-hint,
|
||||
.wrn-next__field-help {
|
||||
color: var(--wrn-color-muted);
|
||||
font-size: 0.82em;
|
||||
font-weight: 500;
|
||||
}
|
||||
.wrn-next__field-control {
|
||||
position: relative;
|
||||
min-width: 0;
|
||||
}
|
||||
.wrn-next__field-control > :is(input, textarea, select) {
|
||||
padding-inline: 0.85rem;
|
||||
border-color: var(--wrn-color-border);
|
||||
border-radius: var(--wrn-radius-sm);
|
||||
background: var(--wrn-color-surface);
|
||||
font-size: 0.8125rem;
|
||||
}
|
||||
.wrn-next__field-control[data-icon-position="start"] > :is(input, textarea, select) {
|
||||
padding-inline-start: 2.5rem;
|
||||
}
|
||||
.wrn-next__field-control[data-icon-position="end"] > :is(input, textarea, select) {
|
||||
padding-inline-end: 2.5rem;
|
||||
}
|
||||
.wrn-next__field-icon {
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
top: 50%;
|
||||
left: 0.85rem;
|
||||
color: var(--wrn-color-muted);
|
||||
pointer-events: none;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
.wrn-next__field-control[data-icon-position="end"] > .wrn-next__field-icon {
|
||||
right: 0.85rem;
|
||||
left: auto;
|
||||
}
|
||||
.wrn-next--field[data-variant="outlined"]
|
||||
.wrn-next__field-control
|
||||
> :is(input, textarea, select) {
|
||||
border-width: 2px;
|
||||
}
|
||||
.wrn-next--field[data-variant="underline"]
|
||||
.wrn-next__field-control
|
||||
> :is(input, textarea, select) {
|
||||
padding-inline: 0;
|
||||
border-width: 0 0 1px;
|
||||
border-radius: 0;
|
||||
background: transparent;
|
||||
box-shadow: none;
|
||||
}
|
||||
.wrn-next--field[data-variant="pill"] .wrn-next__field-control > :is(input, select) {
|
||||
border-radius: 999px;
|
||||
padding-inline: 1.15rem;
|
||||
}
|
||||
.wrn-next--field[data-variant="ghost"] .wrn-next__field-control > :is(input, textarea, select) {
|
||||
border-color: transparent;
|
||||
background: color-mix(in srgb, var(--wrn-field-color) 8%, var(--wrn-color-surface));
|
||||
}
|
||||
.wrn-next__field-floating-label {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 0.85rem;
|
||||
color: var(--wrn-color-muted);
|
||||
pointer-events: none;
|
||||
transform: translateY(-50%);
|
||||
transition: 150ms ease;
|
||||
}
|
||||
.wrn-next--textarea .wrn-next__field-floating-label {
|
||||
top: 1.35rem;
|
||||
}
|
||||
.wrn-next--field[data-floating="true"] .wrn-next__field-control > :is(input, textarea, select) {
|
||||
padding-top: 1.2rem;
|
||||
padding-bottom: 0.3rem;
|
||||
}
|
||||
.wrn-next--field[data-floating="true"] .wrn-next__field-heading > label {
|
||||
position: absolute !important;
|
||||
width: 1px !important;
|
||||
height: 1px !important;
|
||||
overflow: hidden !important;
|
||||
margin: -1px !important;
|
||||
clip: rect(0, 0, 0, 0) !important;
|
||||
white-space: nowrap !important;
|
||||
}
|
||||
.wrn-next--field[data-floating="true"]
|
||||
.wrn-next__field-heading:not(:has(.wrn-next__field-hint)) {
|
||||
display: none;
|
||||
}
|
||||
.wrn-next--field[data-floating="true"]
|
||||
.wrn-next__field-control
|
||||
> :is(input, textarea):is(:focus, :not(:placeholder-shown))
|
||||
+ .wrn-next__field-floating-label {
|
||||
top: 0.42rem;
|
||||
font-size: 0.7em;
|
||||
transform: none;
|
||||
}
|
||||
.wrn-next__field-error {
|
||||
min-height: 1em;
|
||||
color: var(--wrn-color-danger);
|
||||
font-size: 0.82em;
|
||||
font-weight: 600;
|
||||
}
|
||||
.wrn-next__field-error:empty {
|
||||
display: none;
|
||||
}
|
||||
.wrn-next--field[data-invalid="true"] :is(input, textarea, select),
|
||||
.wrn-next--choice-field[data-invalid="true"] input {
|
||||
border-color: var(--wrn-color-danger);
|
||||
}
|
||||
.wrn-next--field :is(input, textarea, select):disabled,
|
||||
.wrn-next--choice-field input:disabled {
|
||||
cursor: not-allowed;
|
||||
opacity: 0.58;
|
||||
}
|
||||
.wrn-next--field :is(input, textarea, select):read-only {
|
||||
background: var(--wrn-color-surface-2);
|
||||
}
|
||||
.wrn-next--field[data-inline="true"],
|
||||
.wrn-next--choice-field[data-inline="true"] {
|
||||
display: grid;
|
||||
width: 100%;
|
||||
max-width: none;
|
||||
grid-template-columns: minmax(7rem, max-content) minmax(12rem, 20rem) minmax(10rem, 1fr);
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
.wrn-next--field[data-inline="true"] .wrn-next__field-heading,
|
||||
.wrn-next--choice-field[data-inline="true"] .wrn-next__field-heading {
|
||||
min-height: 2.65rem;
|
||||
align-items: center;
|
||||
}
|
||||
.wrn-next--field[data-inline="true"] .wrn-next__field-heading {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
.wrn-next--field[data-inline="true"] .wrn-next__field-help,
|
||||
.wrn-next--choice-field[data-inline="true"] .wrn-next__field-help {
|
||||
display: flex;
|
||||
min-height: 2.65rem;
|
||||
align-items: center;
|
||||
}
|
||||
.wrn-next--choice-field[data-inline="true"] {
|
||||
grid-template-columns: minmax(12rem, 20rem) minmax(10rem, 1fr);
|
||||
}
|
||||
.wrn-next--choice-field[data-inline="true"] .wrn-next__field-heading:empty {
|
||||
display: none;
|
||||
}
|
||||
.wrn-next--field[data-inline="true"] .wrn-next__field-error,
|
||||
.wrn-next--choice-field[data-inline="true"] .wrn-next__field-error {
|
||||
grid-column: 2 / -1;
|
||||
}
|
||||
.wrn-next__sr-only {
|
||||
position: absolute !important;
|
||||
width: 1px !important;
|
||||
height: 1px !important;
|
||||
overflow: hidden !important;
|
||||
padding: 0 !important;
|
||||
border: 0 !important;
|
||||
margin: -1px !important;
|
||||
clip: rect(0, 0, 0, 0) !important;
|
||||
white-space: nowrap !important;
|
||||
}
|
||||
.wrn-next__choice-field {
|
||||
display: grid;
|
||||
width: 100%;
|
||||
max-width: none;
|
||||
gap: 0.4rem;
|
||||
}
|
||||
.wrn-next__choice {
|
||||
display: flex;
|
||||
min-width: 0;
|
||||
align-items: center;
|
||||
gap: 0.65rem;
|
||||
color: var(--wrn-color-text);
|
||||
width: 100%;
|
||||
font-size: 0.75rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
.wrn-next__checkbox-content > .wrn-next__choice {
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
align-items: flex-start;
|
||||
}
|
||||
.wrn-next__choice input {
|
||||
flex: 0 0 auto;
|
||||
margin: 0;
|
||||
accent-color: var(--wrn-field-color);
|
||||
}
|
||||
.wrn-next__choice-copy {
|
||||
display: grid;
|
||||
min-width: 0;
|
||||
gap: 0.15rem;
|
||||
line-height: 1.35;
|
||||
}
|
||||
.wrn-next__choice-copy small {
|
||||
color: var(--wrn-color-muted);
|
||||
font-weight: 500;
|
||||
}
|
||||
.wrn-next__radio-group,
|
||||
.wrn-next__checkbox-group {
|
||||
display: grid;
|
||||
min-width: 0;
|
||||
gap: 0.65rem;
|
||||
}
|
||||
.wrn-next--radio-field[data-orientation="horizontal"] .wrn-next__radio-group,
|
||||
.wrn-next--checkbox-field[data-orientation="horizontal"] .wrn-next__checkbox-group {
|
||||
grid-template-columns: repeat(auto-fit, minmax(8rem, max-content));
|
||||
align-items: stretch;
|
||||
}
|
||||
.wrn-next--radio-field[data-card="true"] .wrn-next__radio-group,
|
||||
.wrn-next--checkbox-field[data-card="true"] .wrn-next__checkbox-group {
|
||||
grid-template-columns: repeat(auto-fit, minmax(min(100%, 12rem), 1fr));
|
||||
}
|
||||
.wrn-next--radio-field[data-card="true"] .wrn-next--radio,
|
||||
.wrn-next--checkbox-field[data-card="true"] .wrn-next--checkbox {
|
||||
min-height: 4.5rem;
|
||||
padding: 0.85rem;
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: var(--wrn-radius-sm);
|
||||
background: var(--wrn-color-surface);
|
||||
}
|
||||
.wrn-next--radio-field[data-card="true"] .wrn-next--radio:has(input:checked),
|
||||
.wrn-next--checkbox-field[data-card="true"] .wrn-next--checkbox:has(input:checked) {
|
||||
border-color: var(--wrn-field-color);
|
||||
box-shadow: 0 0 0 1px var(--wrn-field-color);
|
||||
}
|
||||
.wrn-next--radio-field[data-list="true"] .wrn-next--radio,
|
||||
.wrn-next--checkbox-field[data-list="true"] .wrn-next--checkbox {
|
||||
padding-block: 0.75rem;
|
||||
border-bottom: 1px solid var(--wrn-color-border);
|
||||
}
|
||||
.wrn-next--radio-field[data-right-aligned="true"] .wrn-next--radio,
|
||||
.wrn-next--checkbox-field[data-right-aligned="true"] .wrn-next--checkbox {
|
||||
justify-content: space-between;
|
||||
}
|
||||
.wrn-next--radio-field[data-right-aligned="true"] .wrn-next--radio input,
|
||||
.wrn-next--checkbox-field[data-right-aligned="true"] .wrn-next--checkbox input {
|
||||
order: 2;
|
||||
}
|
||||
.wrn-next--radio-field[data-right-aligned="true"] .wrn-next__choice-copy,
|
||||
.wrn-next--checkbox-field[data-right-aligned="true"] .wrn-next__choice-copy {
|
||||
order: 1;
|
||||
}
|
||||
.wrn-next__choice[data-variant="outlined"],
|
||||
.wrn-next__choice[data-variant="floating"] {
|
||||
padding: 0.65rem 0.8rem;
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: var(--wrn-radius-sm);
|
||||
}
|
||||
.wrn-next__choice[data-variant="pill"] {
|
||||
padding: 0.65rem 1rem;
|
||||
border-radius: 999px;
|
||||
background: color-mix(in srgb, var(--wrn-field-color) 9%, var(--wrn-color-surface));
|
||||
}
|
||||
.wrn-next__choice[data-variant="ghost"] {
|
||||
padding: 0.65rem 0.8rem;
|
||||
border-radius: var(--wrn-radius-sm);
|
||||
background: color-mix(in srgb, var(--wrn-field-color) 7%, transparent);
|
||||
}
|
||||
.wrn-next__choice[data-variant="underline"] {
|
||||
padding-block: 0.5rem;
|
||||
border-bottom: 1px solid var(--wrn-color-border);
|
||||
}
|
||||
.wrn-next--select .wrn-next__field-control {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.wrn-next__color-control,
|
||||
.wrn-next__range-control,
|
||||
.wrn-next__input-group-control,
|
||||
.wrn-next__file-control {
|
||||
display: flex;
|
||||
min-width: 0;
|
||||
align-items: center;
|
||||
gap: 0.65rem;
|
||||
}
|
||||
.wrn-next__picker-control,
|
||||
.wrn-next--time-picker .wrn-next__field-control {
|
||||
position: relative;
|
||||
display: flex;
|
||||
min-width: 0;
|
||||
align-items: center;
|
||||
}
|
||||
.wrn-next__picker-control > button:first-of-type,
|
||||
.wrn-next__time-trigger {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
min-height: 2.65rem;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 0.75rem;
|
||||
padding: 0.7rem 0.85rem;
|
||||
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;
|
||||
text-align: left;
|
||||
}
|
||||
.wrn-next__calendar,
|
||||
.wrn-next__time-panel {
|
||||
z-index: 20;
|
||||
display: grid;
|
||||
width: min(100%, 22rem);
|
||||
gap: 0.75rem;
|
||||
padding: 0.85rem;
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: var(--wrn-radius-md);
|
||||
background: var(--wrn-color-surface);
|
||||
box-shadow: var(--wrn-shadow-3);
|
||||
}
|
||||
.wrn-next--date-picker[data-expanded="false"] .wrn-next__calendar,
|
||||
.wrn-next--time-picker[data-expanded="false"] .wrn-next__time-panel {
|
||||
display: none;
|
||||
}
|
||||
.wrn-next__calendar button,
|
||||
.wrn-next__time-panel button {
|
||||
min-height: 2.25rem;
|
||||
border: 0;
|
||||
border-radius: var(--wrn-radius-sm);
|
||||
background: transparent;
|
||||
color: inherit;
|
||||
}
|
||||
.wrn-next__calendar-weekdays,
|
||||
.wrn-next__calendar-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(7, 1fr);
|
||||
gap: 0.2rem;
|
||||
text-align: center;
|
||||
}
|
||||
.wrn-next__calendar-weekdays {
|
||||
color: var(--wrn-color-muted);
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
.wrn-next__calendar-grid button:hover,
|
||||
.wrn-next__time-panel button:hover {
|
||||
background: var(--wrn-color-surface-2);
|
||||
}
|
||||
.wrn-next__calendar-grid button[aria-pressed="true"],
|
||||
.wrn-next__time-panel button[aria-pressed="true"] {
|
||||
background: var(--wrn-field-color);
|
||||
color: var(--wrn-color-primary-contrast, #fff);
|
||||
}
|
||||
.wrn-next__time-period {
|
||||
display: flex;
|
||||
gap: 0.35rem;
|
||||
}
|
||||
.wrn-next--file-upload-progress .wrn-next__row,
|
||||
.wrn-next__upload-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
.wrn-next--file-upload-progress .wrn-next__row > span {
|
||||
display: grid;
|
||||
min-width: 0;
|
||||
}
|
||||
.wrn-next--field[data-variant="underline"]
|
||||
:is(.wrn-next__input-group-control, .wrn-next__file-control, .wrn-next__color-control) {
|
||||
border-width: 0 0 1px;
|
||||
border-radius: 0;
|
||||
background: transparent;
|
||||
}
|
||||
.wrn-next--field[data-variant="outlined"]
|
||||
:is(.wrn-next__input-group-control, .wrn-next__file-control) {
|
||||
border-width: 2px;
|
||||
}
|
||||
.wrn-next--field[data-variant="pill"]
|
||||
:is(.wrn-next__input-group-control, .wrn-next__file-control) {
|
||||
border-radius: 999px;
|
||||
}
|
||||
.wrn-next--field[data-variant="ghost"]
|
||||
:is(.wrn-next__input-group-control, .wrn-next__file-control, .wrn-next__color-control) {
|
||||
border-color: transparent;
|
||||
background: color-mix(in srgb, var(--wrn-field-color) 8%, var(--wrn-color-surface));
|
||||
}
|
||||
@media (max-width: 640px) {
|
||||
.wrn-next--field[data-inline="true"],
|
||||
.wrn-next--choice-field[data-inline="true"] {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.wrn-next--field[data-inline="true"] .wrn-next__field-error,
|
||||
.wrn-next--choice-field[data-inline="true"] .wrn-next__field-error {
|
||||
grid-column: auto;
|
||||
}
|
||||
}
|
||||
.wrn-next--toggle-password:has(input.wrn-invalid) .wrn-next__password-control > input,
|
||||
.wrn-next--toggle-password.wrn-next--invalid .wrn-next__password-control > input {
|
||||
border-color: var(--wrn-color-danger);
|
||||
box-shadow: 0 0 0 3px color-mix(in srgb, var(--wrn-color-danger) 14%, transparent);
|
||||
}
|
||||
.wrn-next--strong-password.wrn-next--invalid input,
|
||||
.wrn-next--strong-password input.wrn-invalid {
|
||||
border-color: var(--wrn-color-danger);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ component Columns {
|
||||
<div
|
||||
{...attrs}
|
||||
data-ui-component="Columns"
|
||||
class='wire-columns {class}'
|
||||
class='wrn-columns {class}'
|
||||
data-size='{size}'
|
||||
data-color='{color}'
|
||||
data-gap='{gap}'
|
||||
@@ -44,7 +44,7 @@ component Columns {
|
||||
}
|
||||
|
||||
style {
|
||||
.wire-columns {
|
||||
.wrn-columns {
|
||||
--columns-gap: 1.5rem;
|
||||
display: grid;
|
||||
width: 100%;
|
||||
@@ -54,35 +54,35 @@ component Columns {
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
.wire-columns[data-max-width="md"] {
|
||||
.wrn-columns[data-max-width="md"] {
|
||||
max-width: 48rem;
|
||||
}
|
||||
|
||||
.wire-columns[data-max-width="lg"] {
|
||||
.wrn-columns[data-max-width="lg"] {
|
||||
max-width: 64rem;
|
||||
}
|
||||
|
||||
.wire-columns[data-max-width="xl"] {
|
||||
.wrn-columns[data-max-width="xl"] {
|
||||
max-width: 80rem;
|
||||
}
|
||||
|
||||
.wire-columns[data-max-width="2xl"] {
|
||||
.wrn-columns[data-max-width="2xl"] {
|
||||
max-width: 96rem;
|
||||
}
|
||||
|
||||
.wire-columns[data-max-width="full"] {
|
||||
.wrn-columns[data-max-width="full"] {
|
||||
max-width: none;
|
||||
}
|
||||
|
||||
.wire-columns[data-gap="sm"] {
|
||||
.wrn-columns[data-gap="sm"] {
|
||||
--columns-gap: 0.75rem;
|
||||
}
|
||||
|
||||
.wire-columns[data-gap="lg"] {
|
||||
.wrn-columns[data-gap="lg"] {
|
||||
--columns-gap: 2.5rem;
|
||||
}
|
||||
|
||||
.wire-columns[data-gap="xl"] {
|
||||
.wrn-columns[data-gap="xl"] {
|
||||
--columns-gap: 3.5rem;
|
||||
}
|
||||
|
||||
@@ -91,17 +91,17 @@ component Columns {
|
||||
* is worth keeping single-column for longer than a card deck is.
|
||||
*/
|
||||
@media (min-width: 768px) {
|
||||
.wire-columns:not([data-columns="1"]) {
|
||||
.wrn-columns:not([data-columns="1"]) {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
.wire-columns[data-columns="3"] {
|
||||
.wrn-columns[data-columns="3"] {
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.wire-columns[data-columns="4"] {
|
||||
.wrn-columns[data-columns="4"] {
|
||||
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import SelectStyles from "../styles/SelectStyles.wrn"
|
||||
|
||||
import ComponentBaseStyles from "../styles/ComponentBaseStyles.wrn"
|
||||
|
||||
component ComboBox {
|
||||
outputs {
|
||||
search(payload: { value?: string | number | boolean | null; values?: Array<string | number | boolean | null | object>; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | string | number | boolean | null)
|
||||
@@ -229,7 +227,7 @@ component ComboBox {
|
||||
|
||||
view {
|
||||
<div
|
||||
class="wire-component wire-component--color-{color} wire-component--size-{size} wire-next--advanced-select wire-next--combobox {open ? 'wire-next--open' : ''} {fixed ? 'wire-next--advanced-select-fixed' : ''} {invalid ? 'wire-next--invalid' : ''} {disabled ? 'wire-next--disabled' : ''} {class}"
|
||||
class="wrn-component wrn-component--color-{color} wrn-component--size-{size} wrn-next--advanced-select wrn-next--combobox {open ? 'wrn-next--open' : ''} {fixed ? 'wrn-next--advanced-select-fixed' : ''} {invalid ? 'wrn-next--invalid' : ''} {disabled ? 'wrn-next--disabled' : ''} {class}"
|
||||
data-placement="{placement}"
|
||||
data-search-mode="{searchMode}"
|
||||
data-remote="{remote ? 'true' : 'false'}"
|
||||
@@ -245,12 +243,12 @@ component ComboBox {
|
||||
>
|
||||
<label id="{name}-label" for="{name}-input">{label}</label>
|
||||
|
||||
<div class="wire-next__select-control wire-next__combobox-control">
|
||||
<span class="wire-next__search-icon icon-[lucide--search]" aria-hidden="true"></span>
|
||||
<div class="wrn-next__select-control wrn-next__combobox-control">
|
||||
<span class="wrn-next__search-icon icon-[lucide--search]" aria-hidden="true"></span>
|
||||
<input
|
||||
{...attrs}
|
||||
id="{name}-input"
|
||||
class="wire-next__select-trigger wire-next__combobox-input"
|
||||
class="wrn-next__select-trigger wrn-next__combobox-input"
|
||||
type="text"
|
||||
role="combobox"
|
||||
name="{allowCustomValue ? name : ''}"
|
||||
@@ -273,7 +271,7 @@ component ComboBox {
|
||||
|
||||
<button
|
||||
type="button"
|
||||
class="wire-next__clear-select"
|
||||
class="wrn-next__clear-select"
|
||||
data-show="clearable && inputText() && !disabled"
|
||||
aria-label="{clearLabel}"
|
||||
title="{clearLabel}"
|
||||
@@ -283,44 +281,44 @@ component ComboBox {
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="wire-next__combobox-toggle"
|
||||
class="wrn-next__combobox-toggle"
|
||||
aria-label="{toggleLabel}"
|
||||
tabindex="-1"
|
||||
disabled="{disabled}"
|
||||
@click="toggle()"
|
||||
>
|
||||
<span class="wire-next__select-chevron icon-[lucide--chevrons-up-down]" aria-hidden="true"></span>
|
||||
<span class="wrn-next__select-chevron icon-[lucide--chevrons-up-down]" aria-hidden="true"></span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="wire-next__select-dropdown {fixed ? 'wire-next__select-dropdown--fixed' : ''}"
|
||||
class="wrn-next__select-dropdown {fixed ? 'wrn-next__select-dropdown--fixed' : ''}"
|
||||
data-show="shouldShowDropdown()"
|
||||
style="{shouldShowDropdown() ? '' : 'display: none'}"
|
||||
>
|
||||
<div
|
||||
class="wire-next__select-message"
|
||||
class="wrn-next__select-message"
|
||||
data-show="remote && query.length !== 0 && query.length < minSearchLength"
|
||||
>Enter at least {minSearchLength} characters.</div>
|
||||
<div class="wire-next__select-message" data-show="loading" role="status">
|
||||
<i class="wire-spinner wire-spinner--inline" aria-hidden="true"></i>
|
||||
<div class="wrn-next__select-message" data-show="loading" role="status">
|
||||
<i class="wrn-spinner wrn-spinner--inline" aria-hidden="true"></i>
|
||||
{loadingLabel}
|
||||
</div>
|
||||
|
||||
<div
|
||||
id="{name}-listbox"
|
||||
class="wire-next__select-list"
|
||||
class="wrn-next__select-list"
|
||||
data-show="(!remote || (query.length === 0 && remoteAutoLoad) || query.length >= minSearchLength) && !loading"
|
||||
role="listbox"
|
||||
>
|
||||
{#each groups as group}
|
||||
{#if visibleOptions(group.options || []).length}
|
||||
<div class="wire-next__option-group" role="group" aria-label="{group.label}">
|
||||
<div class="wire-next__group-label">{group.label}</div>
|
||||
<div class="wrn-next__option-group" role="group" aria-label="{group.label}">
|
||||
<div class="wrn-next__group-label">{group.label}</div>
|
||||
{#each group.options || [] as option}
|
||||
<button
|
||||
type="button"
|
||||
class="wire-next__select-option {isSelected(option) ? 'wire-next__select-option--selected' : ''} {optionIndex(option) === activeIndex ? 'wire-next__select-option--active' : ''}"
|
||||
class="wrn-next__select-option {isSelected(option) ? 'wrn-next__select-option--selected' : ''} {optionIndex(option) === activeIndex ? 'wrn-next__select-option--active' : ''}"
|
||||
data-option-value="{option.value}"
|
||||
data-show="matches(option)"
|
||||
role="option"
|
||||
@@ -332,9 +330,9 @@ component ComboBox {
|
||||
>
|
||||
{#if optionTemplate === "icon" && option.icon}<i class="{option.icon}" aria-hidden="true"></i>{/if}
|
||||
{#if optionTemplate === "avatar" && option.avatar}<img src="{option.avatar}" alt="" />{/if}
|
||||
{#if optionTemplate === "color" && option.color}<i class="wire-next__color-dot" style="--option-color: {option.color}"></i>{/if}
|
||||
{#if optionTemplate === "color" && option.color}<i class="wrn-next__color-dot" style="--option-color: {option.color}"></i>{/if}
|
||||
<span><strong>{option.label}</strong>{#if option.description}<small>{option.description}</small>{/if}</span>
|
||||
<i class="wire-next__check icon-[lucide--check]" data-show="isSelected(option)" aria-hidden="true"></i>
|
||||
<i class="wrn-next__check icon-[lucide--check]" data-show="isSelected(option)" aria-hidden="true"></i>
|
||||
</button>
|
||||
{/each}
|
||||
</div>
|
||||
@@ -344,7 +342,7 @@ component ComboBox {
|
||||
{#each options as option}
|
||||
<button
|
||||
type="button"
|
||||
class="wire-next__select-option {isSelected(option) ? 'wire-next__select-option--selected' : ''} {optionIndex(option) === activeIndex ? 'wire-next__select-option--active' : ''}"
|
||||
class="wrn-next__select-option {isSelected(option) ? 'wrn-next__select-option--selected' : ''} {optionIndex(option) === activeIndex ? 'wrn-next__select-option--active' : ''}"
|
||||
data-option-value="{option.value}"
|
||||
data-show="matches(option)"
|
||||
role="option"
|
||||
@@ -356,16 +354,16 @@ component ComboBox {
|
||||
>
|
||||
{#if optionTemplate === "icon" && option.icon}<i class="{option.icon}" aria-hidden="true"></i>{/if}
|
||||
{#if optionTemplate === "avatar" && option.avatar}<img src="{option.avatar}" alt="" />{/if}
|
||||
{#if optionTemplate === "color" && option.color}<i class="wire-next__color-dot" style="--option-color: {option.color}"></i>{/if}
|
||||
{#if optionTemplate === "color" && option.color}<i class="wrn-next__color-dot" style="--option-color: {option.color}"></i>{/if}
|
||||
<span><strong>{option.label}</strong>{#if option.description}<small>{option.description}</small>{/if}</span>
|
||||
<i class="wire-next__check icon-[lucide--check]" data-show="isSelected(option)" aria-hidden="true"></i>
|
||||
<i class="wrn-next__check icon-[lucide--check]" data-show="isSelected(option)" aria-hidden="true"></i>
|
||||
</button>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
class="wire-next__load-more"
|
||||
class="wrn-next__load-more"
|
||||
data-wrn-select-load-more
|
||||
data-show="infinite && hasMore"
|
||||
>{loadMoreLabel}</button>
|
||||
@@ -385,16 +383,15 @@ component ComboBox {
|
||||
{#if helpText && !validationMessage}<small id="{name}-help">{helpText}</small>{/if}
|
||||
<small
|
||||
id="{name}-validation"
|
||||
class="wire-next__validation"
|
||||
class="wrn-next__validation"
|
||||
data-error="{name}"
|
||||
>{validationMessage}</small>
|
||||
</div>
|
||||
<SelectStyles hidden />
|
||||
<ComponentBaseStyles hidden />
|
||||
}
|
||||
|
||||
style {
|
||||
.wire-next__combobox-toggle {
|
||||
.wrn-next__combobox-toggle {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 0;
|
||||
@@ -405,16 +402,85 @@ component ComboBox {
|
||||
padding: 0;
|
||||
place-items: center;
|
||||
border: 0;
|
||||
color: var(--wire-color-muted);
|
||||
color: var(--wrn-color-muted);
|
||||
background: transparent;
|
||||
cursor: pointer;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
.wire-next--combobox .wire-next__combobox-input {
|
||||
.wrn-next--combobox .wrn-next__combobox-input {
|
||||
padding-right: 5.25em;
|
||||
padding-left: 2.5em;
|
||||
cursor: text;
|
||||
}
|
||||
|
||||
/* Shared component foundation. */
|
||||
|
||||
.wrn-component {
|
||||
--wrn-component-color: var(--wrn-color-primary);
|
||||
--wrn-component-scale: 1;
|
||||
margin: 0;
|
||||
color: var(--wrn-color-text);
|
||||
font-family: var(--wrn-font-sans, inherit);
|
||||
}
|
||||
|
||||
.wrn-component--color-primary {
|
||||
--wrn-component-color: var(--wrn-color-primary);
|
||||
}
|
||||
|
||||
.wrn-component--color-secondary {
|
||||
--wrn-component-color: var(--wrn-color-secondary);
|
||||
}
|
||||
|
||||
.wrn-component--color-success {
|
||||
--wrn-component-color: var(--wrn-color-success);
|
||||
}
|
||||
|
||||
.wrn-component--color-warning {
|
||||
--wrn-component-color: var(--wrn-color-warning);
|
||||
}
|
||||
|
||||
.wrn-component--color-danger {
|
||||
--wrn-component-color: var(--wrn-color-danger);
|
||||
}
|
||||
|
||||
.wrn-component--color-info {
|
||||
--wrn-component-color: var(--wrn-color-info);
|
||||
}
|
||||
|
||||
.wrn-component--size-xs {
|
||||
--wrn-component-scale: 0.78;
|
||||
}
|
||||
|
||||
.wrn-component--size-sm {
|
||||
--wrn-component-scale: 0.88;
|
||||
}
|
||||
|
||||
.wrn-component--size-default,
|
||||
.wrn-component--size-md {
|
||||
--wrn-component-scale: 1;
|
||||
}
|
||||
|
||||
.wrn-component--size-lg {
|
||||
--wrn-component-scale: 1.14;
|
||||
}
|
||||
|
||||
.wrn-component--size-xl {
|
||||
--wrn-component-scale: 1.28;
|
||||
}
|
||||
|
||||
.wrn-component:not(.wrn-btn) {
|
||||
font-size: calc(1em * var(--wrn-component-scale));
|
||||
}
|
||||
|
||||
.wrn-component :is(a, button, input, select, textarea):focus-visible {
|
||||
outline-color: var(--wrn-component-color);
|
||||
}
|
||||
|
||||
.wrn-component p {
|
||||
margin: 0;
|
||||
color: var(--wrn-color-muted);
|
||||
line-height: 1.6;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ component Confetti {
|
||||
functions {
|
||||
shared function pieces() { return Array.from({ length: Math.max(1, Math.min(60, count)) }) }
|
||||
shared function pieceStyle(index) {
|
||||
return "--wire-confetti-index:" + index + ";--wire-confetti-x:" + ((index * 37) % 100) + ";--wire-confetti-delay:" + ((index * 29) % 240) + "ms;"
|
||||
return "--wrn-confetti-index:" + index + ";--wrn-confetti-x:" + ((index * 37) % 100) + ";--wrn-confetti-delay:" + ((index * 29) % 240) + "ms;"
|
||||
}
|
||||
client function finish(sourceEvent) {
|
||||
running = false
|
||||
@@ -41,11 +41,11 @@ component Confetti {
|
||||
}
|
||||
|
||||
view {
|
||||
<div {...attrs} data-ui-component="Confetti" data-running='{running ? "true" : "false"}' class='wire-confetti {class}' style='--wire-confetti-duration:{duration}ms'>
|
||||
<button type="button" class="wire-confetti__trigger" disabled='{disabled}' @click='start(event)'>
|
||||
<div {...attrs} data-ui-component="Confetti" data-running='{running ? "true" : "false"}' class='wrn-confetti {class}' style='--wrn-confetti-duration:{duration}ms'>
|
||||
<button type="button" class="wrn-confetti__trigger" disabled='{disabled}' @click='start(event)'>
|
||||
<span class="icon-[lucide--party-popper]" aria-hidden="true"></span><span>{label}</span>
|
||||
</button>
|
||||
<div class="wire-confetti__burst" aria-hidden="true">
|
||||
<div class="wrn-confetti__burst" aria-hidden="true">
|
||||
{#each pieces() as piece, index}<i style='{pieceStyle(index)}'></i>{/each}
|
||||
</div>
|
||||
<slot />
|
||||
@@ -53,20 +53,20 @@ component Confetti {
|
||||
}
|
||||
|
||||
style {
|
||||
.wire-confetti { position: relative; display: inline-flex; }
|
||||
.wire-confetti__trigger { display: inline-flex; min-height: 2.5rem; align-items: center; gap: 0.5rem; padding: 0.55rem 0.85rem; border: 1px solid var(--wire-color-primary); border-radius: var(--wire-radius); color: var(--wire-color-on-primary); background: var(--wire-color-primary); font: inherit; font-weight: 700; cursor: pointer; }
|
||||
.wire-confetti__trigger > span:first-child { width: 1rem; height: 1rem; }
|
||||
.wire-confetti__trigger:focus-visible { outline: 2px solid var(--wire-color-focus); outline-offset: 2px; }
|
||||
.wire-confetti__trigger:disabled { cursor: not-allowed; opacity: 0.55; }
|
||||
.wire-confetti__burst { position: absolute; inset: 50% 0 auto; height: 0; pointer-events: none; }
|
||||
.wire-confetti__burst > i { position: absolute; left: calc(var(--wire-confetti-x) * 1%); width: 0.45rem; height: 0.7rem; border-radius: 0.1rem; opacity: 0; background: hsl(calc(var(--wire-confetti-index) * 47deg) 80% 55%); transform: translate(-50%, 0) rotate(calc(var(--wire-confetti-index) * 23deg)); }
|
||||
.wire-confetti[data-running="true"] .wire-confetti__burst > i { animation: wire-confetti-burst var(--wire-confetti-duration) cubic-bezier(0.2, 0.7, 0.2, 1) var(--wire-confetti-delay) both; }
|
||||
@keyframes wire-confetti-burst {
|
||||
.wrn-confetti { position: relative; display: inline-flex; }
|
||||
.wrn-confetti__trigger { display: inline-flex; min-height: 2.5rem; align-items: center; gap: 0.5rem; padding: 0.55rem 0.85rem; border: 1px solid var(--wrn-color-primary); border-radius: var(--wrn-radius); color: var(--wrn-color-on-primary); background: var(--wrn-color-primary); font: inherit; font-weight: 700; cursor: pointer; }
|
||||
.wrn-confetti__trigger > span:first-child { width: 1rem; height: 1rem; }
|
||||
.wrn-confetti__trigger:focus-visible { outline: 2px solid var(--wrn-color-focus); outline-offset: 2px; }
|
||||
.wrn-confetti__trigger:disabled { cursor: not-allowed; opacity: 0.55; }
|
||||
.wrn-confetti__burst { position: absolute; inset: 50% 0 auto; height: 0; pointer-events: none; }
|
||||
.wrn-confetti__burst > i { position: absolute; left: calc(var(--wrn-confetti-x) * 1%); width: 0.45rem; height: 0.7rem; border-radius: 0.1rem; opacity: 0; background: hsl(calc(var(--wrn-confetti-index) * 47deg) 80% 55%); transform: translate(-50%, 0) rotate(calc(var(--wrn-confetti-index) * 23deg)); }
|
||||
.wrn-confetti[data-running="true"] .wrn-confetti__burst > i { animation: wrn-confetti-burst var(--wrn-confetti-duration) cubic-bezier(0.2, 0.7, 0.2, 1) var(--wrn-confetti-delay) both; }
|
||||
@keyframes wrn-confetti-burst {
|
||||
0% { opacity: 1; transform: translate(-50%, 0) rotate(0); }
|
||||
100% { opacity: 0; transform: translate(calc(-50% + (var(--wire-confetti-x) - 50) * 0.9px), 9rem) rotate(540deg); }
|
||||
100% { opacity: 0; transform: translate(calc(-50% + (var(--wrn-confetti-x) - 50) * 0.9px), 9rem) rotate(540deg); }
|
||||
}
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.wire-confetti[data-running="true"] .wire-confetti__burst > i { animation-duration: 1ms; animation-delay: 0ms; }
|
||||
.wrn-confetti[data-running="true"] .wrn-confetti__burst > i { animation-duration: 1ms; animation-delay: 0ms; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,7 +102,7 @@ component ContextMenu {
|
||||
}
|
||||
|
||||
client function moveFocus(sourceEvent, direction) {
|
||||
const root = sourceEvent.currentTarget.closest(".wire-context-menu") || sourceEvent.currentTarget
|
||||
const root = sourceEvent.currentTarget.closest(".wrn-context-menu") || sourceEvent.currentTarget
|
||||
const options = [...root.querySelectorAll("[data-context-menu-item]:not([disabled])")]
|
||||
if (!options.length) {
|
||||
return
|
||||
@@ -137,12 +137,12 @@ component ContextMenu {
|
||||
data-size='{size}'
|
||||
data-color='{color}'
|
||||
data-variant='{variant}'
|
||||
class='wire-context-menu {class}'
|
||||
style='--wire-context-x:{positionX}px;--wire-context-y:{positionY}px;--wire-context-min-width:{minWidth};--wire-context-max-width:{maxWidth};'
|
||||
class='wrn-context-menu {class}'
|
||||
style='--wrn-context-x:{positionX}px;--wrn-context-y:{positionY}px;--wrn-context-min-width:{minWidth};--wrn-context-max-width:{maxWidth};'
|
||||
@keydown='handleKeydown(event)'
|
||||
>
|
||||
<div
|
||||
class="wire-context-menu__trigger"
|
||||
class="wrn-context-menu__trigger"
|
||||
tabindex='{disabled ? "-1" : "0"}'
|
||||
aria-haspopup="menu"
|
||||
aria-expanded='{open || visible ? "true" : "false"}'
|
||||
@@ -156,7 +156,7 @@ component ContextMenu {
|
||||
{#if closeOnOutside}
|
||||
<button
|
||||
type="button"
|
||||
class="wire-context-menu__dismiss-layer"
|
||||
class="wrn-context-menu__dismiss-layer"
|
||||
data-show='{open || visible}'
|
||||
aria-label="Close context menu"
|
||||
@click='hideMenu("outside", event)'
|
||||
@@ -164,14 +164,14 @@ component ContextMenu {
|
||||
{/if}
|
||||
|
||||
<div
|
||||
class="wire-context-menu__panel"
|
||||
class="wrn-context-menu__panel"
|
||||
data-wrn-anchored="true"
|
||||
data-show='{open || visible}'
|
||||
role="menu"
|
||||
aria-label='{label}'
|
||||
>
|
||||
{#if title || description}
|
||||
<div class="wire-context-menu__header">
|
||||
<div class="wrn-context-menu__header">
|
||||
{#if title}
|
||||
<strong>{title}</strong>
|
||||
{/if}
|
||||
@@ -183,12 +183,12 @@ component ContextMenu {
|
||||
|
||||
<slot name="header"></slot>
|
||||
|
||||
<div class="wire-context-menu__items">
|
||||
<div class="wrn-context-menu__items">
|
||||
{#each items as item, itemIndex}
|
||||
{#if item.type === "divider"}
|
||||
<div class="wire-context-menu__divider" role="separator"></div>
|
||||
<div class="wrn-context-menu__divider" role="separator"></div>
|
||||
{:else if item.type === "header"}
|
||||
<div class="wire-context-menu__section-label">{item.label || item.title}</div>
|
||||
<div class="wrn-context-menu__section-label">{item.label || item.title}</div>
|
||||
{:else if item.href}
|
||||
<a
|
||||
href='{item.href}'
|
||||
@@ -199,13 +199,13 @@ component ContextMenu {
|
||||
data-danger='{item.danger ? "true" : "false"}'
|
||||
data-selected='{item.selected || item.checked ? "true" : "false"}'
|
||||
aria-disabled='{item.disabled ? "true" : "false"}'
|
||||
class="wire-context-menu__item"
|
||||
class="wrn-context-menu__item"
|
||||
@click='chooseItem(item, itemIndex, event)'
|
||||
>
|
||||
{#if item.icon}
|
||||
<span class='wire-context-menu__icon {item.icon}' aria-hidden="true"></span>
|
||||
<span class='wrn-context-menu__icon {item.icon}' aria-hidden="true"></span>
|
||||
{/if}
|
||||
<span class="wire-context-menu__copy">
|
||||
<span class="wrn-context-menu__copy">
|
||||
<strong>{item.label || item.title}</strong>
|
||||
{#if item.description}
|
||||
<small>{item.description}</small>
|
||||
@@ -214,9 +214,9 @@ component ContextMenu {
|
||||
{#if item.shortcut}
|
||||
<kbd>{item.shortcut}</kbd>
|
||||
{:else if item.checked || item.selected}
|
||||
<span class="icon-[lucide--check] wire-context-menu__status" aria-hidden="true"></span>
|
||||
<span class="icon-[lucide--check] wrn-context-menu__status" aria-hidden="true"></span>
|
||||
{:else if item.external}
|
||||
<span class="icon-[lucide--arrow-up-right] wire-context-menu__status" aria-hidden="true"></span>
|
||||
<span class="icon-[lucide--arrow-up-right] wrn-context-menu__status" aria-hidden="true"></span>
|
||||
{/if}
|
||||
</a>
|
||||
{:else}
|
||||
@@ -227,13 +227,13 @@ component ContextMenu {
|
||||
data-danger='{item.danger ? "true" : "false"}'
|
||||
data-selected='{item.selected || item.checked ? "true" : "false"}'
|
||||
disabled='{item.disabled}'
|
||||
class="wire-context-menu__item"
|
||||
class="wrn-context-menu__item"
|
||||
@click='chooseItem(item, itemIndex, event)'
|
||||
>
|
||||
{#if item.icon}
|
||||
<span class='wire-context-menu__icon {item.icon}' aria-hidden="true"></span>
|
||||
<span class='wrn-context-menu__icon {item.icon}' aria-hidden="true"></span>
|
||||
{/if}
|
||||
<span class="wire-context-menu__copy">
|
||||
<span class="wrn-context-menu__copy">
|
||||
<strong>{item.label || item.title}</strong>
|
||||
{#if item.description}
|
||||
<small>{item.description}</small>
|
||||
@@ -242,7 +242,7 @@ component ContextMenu {
|
||||
{#if item.shortcut}
|
||||
<kbd>{item.shortcut}</kbd>
|
||||
{:else if item.checked || item.selected}
|
||||
<span class="icon-[lucide--check] wire-context-menu__status" aria-hidden="true"></span>
|
||||
<span class="icon-[lucide--check] wrn-context-menu__status" aria-hidden="true"></span>
|
||||
{/if}
|
||||
</button>
|
||||
{/if}
|
||||
@@ -256,52 +256,52 @@ component ContextMenu {
|
||||
}
|
||||
|
||||
style {
|
||||
.wire-context-menu {
|
||||
--context-accent: var(--wire-color-primary);
|
||||
--context-soft: var(--wire-color-primary-soft);
|
||||
.wrn-context-menu {
|
||||
--context-accent: var(--wrn-color-primary);
|
||||
--context-soft: var(--wrn-color-primary-soft);
|
||||
position: relative;
|
||||
display: block;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.wire-context-menu[data-color="secondary"] {
|
||||
--context-accent: var(--wire-color-secondary);
|
||||
--context-soft: var(--wire-color-secondary-soft);
|
||||
.wrn-context-menu[data-color="secondary"] {
|
||||
--context-accent: var(--wrn-color-secondary);
|
||||
--context-soft: var(--wrn-color-secondary-soft);
|
||||
}
|
||||
|
||||
.wire-context-menu[data-color="info"] {
|
||||
--context-accent: var(--wire-color-info);
|
||||
--context-soft: var(--wire-color-info-soft);
|
||||
.wrn-context-menu[data-color="info"] {
|
||||
--context-accent: var(--wrn-color-info);
|
||||
--context-soft: var(--wrn-color-info-soft);
|
||||
}
|
||||
|
||||
.wire-context-menu[data-color="success"] {
|
||||
--context-accent: var(--wire-color-success);
|
||||
--context-soft: var(--wire-color-success-soft);
|
||||
.wrn-context-menu[data-color="success"] {
|
||||
--context-accent: var(--wrn-color-success);
|
||||
--context-soft: var(--wrn-color-success-soft);
|
||||
}
|
||||
|
||||
.wire-context-menu[data-color="warning"] {
|
||||
--context-accent: var(--wire-color-warning);
|
||||
--context-soft: var(--wire-color-warning-soft);
|
||||
.wrn-context-menu[data-color="warning"] {
|
||||
--context-accent: var(--wrn-color-warning);
|
||||
--context-soft: var(--wrn-color-warning-soft);
|
||||
}
|
||||
|
||||
.wire-context-menu[data-color="danger"] {
|
||||
--context-accent: var(--wire-color-danger);
|
||||
--context-soft: var(--wire-color-danger-soft);
|
||||
.wrn-context-menu[data-color="danger"] {
|
||||
--context-accent: var(--wrn-color-danger);
|
||||
--context-soft: var(--wrn-color-danger-soft);
|
||||
}
|
||||
|
||||
.wire-context-menu__trigger {
|
||||
.wrn-context-menu__trigger {
|
||||
display: block;
|
||||
min-width: 0;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.wire-context-menu__trigger:focus-visible {
|
||||
.wrn-context-menu__trigger:focus-visible {
|
||||
border-radius: 0.6rem;
|
||||
outline: 2px solid var(--wire-color-focus);
|
||||
outline: 2px solid var(--wrn-color-focus);
|
||||
outline-offset: 3px;
|
||||
}
|
||||
|
||||
.wire-context-menu__dismiss-layer {
|
||||
.wrn-context-menu__dismiss-layer {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
z-index: 1090;
|
||||
@@ -311,20 +311,20 @@ component ContextMenu {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.wire-context-menu__panel {
|
||||
.wrn-context-menu__panel {
|
||||
position: absolute;
|
||||
z-index: 1091;
|
||||
top: calc(100% + 0.5rem);
|
||||
left: 0;
|
||||
width: max-content;
|
||||
min-width: var(--wire-context-min-width);
|
||||
max-width: min(var(--wire-context-max-width), calc(100vw - 1.5rem));
|
||||
min-width: var(--wrn-context-min-width);
|
||||
max-width: min(var(--wrn-context-max-width), calc(100vw - 1.5rem));
|
||||
padding: 0.45rem;
|
||||
color: var(--wire-color-text);
|
||||
color: var(--wrn-color-text);
|
||||
background:
|
||||
linear-gradient(145deg, color-mix(in srgb, var(--context-accent) 5%, transparent), transparent 58%),
|
||||
color-mix(in srgb, var(--wire-color-surface-raised) 96%, transparent);
|
||||
border: 1px solid color-mix(in srgb, var(--context-accent) 18%, var(--wire-color-border));
|
||||
color-mix(in srgb, var(--wrn-color-surface-raised) 96%, transparent);
|
||||
border: 1px solid color-mix(in srgb, var(--context-accent) 18%, var(--wrn-color-border));
|
||||
border-radius: 1rem;
|
||||
box-shadow:
|
||||
0 1px 0 color-mix(in srgb, white 5%, transparent) inset,
|
||||
@@ -333,25 +333,25 @@ component ContextMenu {
|
||||
transform-origin: top left;
|
||||
}
|
||||
|
||||
.wire-context-menu[data-placement="pointer"] .wire-context-menu__panel {
|
||||
.wrn-context-menu[data-placement="pointer"] .wrn-context-menu__panel {
|
||||
position: fixed;
|
||||
top: var(--wire-context-y);
|
||||
left: var(--wire-context-x);
|
||||
top: var(--wrn-context-y);
|
||||
left: var(--wrn-context-x);
|
||||
}
|
||||
|
||||
.wire-context-menu[data-placement="bottom-end"] .wire-context-menu__panel {
|
||||
.wrn-context-menu[data-placement="bottom-end"] .wrn-context-menu__panel {
|
||||
right: 0;
|
||||
left: auto;
|
||||
transform-origin: top right;
|
||||
}
|
||||
|
||||
.wire-context-menu[data-placement="top-start"] .wire-context-menu__panel {
|
||||
.wrn-context-menu[data-placement="top-start"] .wrn-context-menu__panel {
|
||||
top: auto;
|
||||
bottom: calc(100% + 0.5rem);
|
||||
transform-origin: bottom left;
|
||||
}
|
||||
|
||||
.wire-context-menu[data-placement="top-end"] .wire-context-menu__panel {
|
||||
.wrn-context-menu[data-placement="top-end"] .wrn-context-menu__panel {
|
||||
top: auto;
|
||||
right: 0;
|
||||
bottom: calc(100% + 0.5rem);
|
||||
@@ -359,58 +359,58 @@ component ContextMenu {
|
||||
transform-origin: bottom right;
|
||||
}
|
||||
|
||||
.wire-context-menu[data-variant="soft"] .wire-context-menu__panel {
|
||||
.wrn-context-menu[data-variant="soft"] .wrn-context-menu__panel {
|
||||
background:
|
||||
linear-gradient(145deg, var(--context-soft), transparent 72%),
|
||||
var(--wire-color-surface-raised);
|
||||
var(--wrn-color-surface-raised);
|
||||
box-shadow: 0 18px 48px color-mix(in srgb, black 16%, transparent);
|
||||
}
|
||||
|
||||
.wire-context-menu[data-variant="outline"] .wire-context-menu__panel {
|
||||
background: var(--wire-color-surface-raised);
|
||||
.wrn-context-menu[data-variant="outline"] .wrn-context-menu__panel {
|
||||
background: var(--wrn-color-surface-raised);
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.wire-context-menu__header {
|
||||
.wrn-context-menu__header {
|
||||
display: grid;
|
||||
gap: 0.2rem;
|
||||
padding: 0.65rem 0.75rem 0.75rem;
|
||||
border-bottom: 1px solid var(--wire-color-border);
|
||||
border-bottom: 1px solid var(--wrn-color-border);
|
||||
}
|
||||
|
||||
.wire-context-menu__header strong {
|
||||
.wrn-context-menu__header strong {
|
||||
font-size: 0.86rem;
|
||||
font-weight: 650;
|
||||
}
|
||||
|
||||
.wire-context-menu__header span {
|
||||
color: var(--wire-color-text-muted);
|
||||
.wrn-context-menu__header span {
|
||||
color: var(--wrn-color-text-muted);
|
||||
font-size: 0.75rem;
|
||||
line-height: 1.45;
|
||||
}
|
||||
|
||||
.wire-context-menu__items {
|
||||
.wrn-context-menu__items {
|
||||
display: grid;
|
||||
gap: 0.15rem;
|
||||
padding-block: 0.25rem;
|
||||
}
|
||||
|
||||
.wire-context-menu__section-label {
|
||||
.wrn-context-menu__section-label {
|
||||
padding: 0.55rem 0.75rem 0.3rem;
|
||||
color: var(--wire-color-text-muted);
|
||||
color: var(--wrn-color-text-muted);
|
||||
font-size: 0.68rem;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.12em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.wire-context-menu__divider {
|
||||
.wrn-context-menu__divider {
|
||||
height: 1px;
|
||||
margin: 0.3rem 0.45rem;
|
||||
background: var(--wire-color-border);
|
||||
background: var(--wrn-color-border);
|
||||
}
|
||||
|
||||
.wire-context-menu__item {
|
||||
.wrn-context-menu__item {
|
||||
appearance: none;
|
||||
display: grid;
|
||||
grid-template-columns: auto minmax(0, 1fr) auto;
|
||||
@@ -419,7 +419,7 @@ component ContextMenu {
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
padding: 0.65rem 0.7rem;
|
||||
color: var(--wire-color-text);
|
||||
color: var(--wrn-color-text);
|
||||
background: transparent;
|
||||
border: 0;
|
||||
border-radius: 0.72rem;
|
||||
@@ -430,47 +430,47 @@ component ContextMenu {
|
||||
transition: background-color 150ms ease, color 150ms ease, transform 150ms ease;
|
||||
}
|
||||
|
||||
.wire-context-menu__item:hover,
|
||||
.wire-context-menu__item:focus-visible,
|
||||
.wire-context-menu__item[data-selected="true"] {
|
||||
.wrn-context-menu__item:hover,
|
||||
.wrn-context-menu__item:focus-visible,
|
||||
.wrn-context-menu__item[data-selected="true"] {
|
||||
color: var(--context-accent);
|
||||
background: var(--context-soft);
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.wire-context-menu__item:active {
|
||||
.wrn-context-menu__item:active {
|
||||
transform: scale(0.985);
|
||||
}
|
||||
|
||||
.wire-context-menu__item[data-danger="true"] {
|
||||
color: var(--wire-color-danger);
|
||||
.wrn-context-menu__item[data-danger="true"] {
|
||||
color: var(--wrn-color-danger);
|
||||
}
|
||||
|
||||
.wire-context-menu__item[data-danger="true"]:hover,
|
||||
.wire-context-menu__item[data-danger="true"]:focus-visible {
|
||||
background: var(--wire-color-danger-soft);
|
||||
.wrn-context-menu__item[data-danger="true"]:hover,
|
||||
.wrn-context-menu__item[data-danger="true"]:focus-visible {
|
||||
background: var(--wrn-color-danger-soft);
|
||||
}
|
||||
|
||||
.wire-context-menu__item[disabled],
|
||||
.wire-context-menu__item[aria-disabled="true"] {
|
||||
.wrn-context-menu__item[disabled],
|
||||
.wrn-context-menu__item[aria-disabled="true"] {
|
||||
opacity: 0.48;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.wire-context-menu__icon,
|
||||
.wire-context-menu__status {
|
||||
.wrn-context-menu__icon,
|
||||
.wrn-context-menu__status {
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
color: currentColor;
|
||||
}
|
||||
|
||||
.wire-context-menu__copy {
|
||||
.wrn-context-menu__copy {
|
||||
display: grid;
|
||||
gap: 0.12rem;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.wire-context-menu__copy strong {
|
||||
.wrn-context-menu__copy strong {
|
||||
overflow: hidden;
|
||||
font-size: 0.82rem;
|
||||
font-weight: 600;
|
||||
@@ -479,35 +479,35 @@ component ContextMenu {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.wire-context-menu__copy small {
|
||||
.wrn-context-menu__copy small {
|
||||
overflow: hidden;
|
||||
color: var(--wire-color-text-muted);
|
||||
color: var(--wrn-color-text-muted);
|
||||
font-size: 0.7rem;
|
||||
line-height: 1.35;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.wire-context-menu kbd {
|
||||
.wrn-context-menu kbd {
|
||||
padding: 0.16rem 0.38rem;
|
||||
color: var(--wire-color-text-muted);
|
||||
background: var(--wire-color-surface-soft);
|
||||
border: 1px solid var(--wire-color-border);
|
||||
color: var(--wrn-color-text-muted);
|
||||
background: var(--wrn-color-surface-soft);
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: 0.36rem;
|
||||
font-size: 0.64rem;
|
||||
font-family: inherit;
|
||||
}
|
||||
|
||||
.wire-context-menu[data-size="sm"] .wire-context-menu__item {
|
||||
.wrn-context-menu[data-size="sm"] .wrn-context-menu__item {
|
||||
padding: 0.52rem 0.6rem;
|
||||
}
|
||||
|
||||
.wire-context-menu[data-size="lg"] .wire-context-menu__item {
|
||||
.wrn-context-menu[data-size="lg"] .wrn-context-menu__item {
|
||||
padding: 0.78rem 0.82rem;
|
||||
}
|
||||
|
||||
@media (max-width: 639px) {
|
||||
.wire-context-menu[data-placement="pointer"] .wire-context-menu__panel {
|
||||
.wrn-context-menu[data-placement="pointer"] .wrn-context-menu__panel {
|
||||
right: 0.75rem;
|
||||
bottom: 0.75rem;
|
||||
left: 0.75rem;
|
||||
@@ -518,7 +518,7 @@ component ContextMenu {
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.wire-context-menu__item {
|
||||
.wrn-context-menu__item {
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ component CustomScrollbar {
|
||||
<div
|
||||
{...attrs}
|
||||
data-ui-component="CustomScrollbar"
|
||||
class='wire-scrollbar {class}'
|
||||
class='wrn-scrollbar {class}'
|
||||
data-color='{color}'
|
||||
data-size='{size}'
|
||||
data-axis='{axis}'
|
||||
@@ -51,8 +51,8 @@ component CustomScrollbar {
|
||||
}
|
||||
|
||||
style {
|
||||
.wire-scrollbar {
|
||||
--scrollbar-accent: var(--wire-color-primary);
|
||||
.wrn-scrollbar {
|
||||
--scrollbar-accent: var(--wrn-color-primary);
|
||||
min-width: 0;
|
||||
overflow: auto;
|
||||
/*
|
||||
@@ -64,48 +64,48 @@ component CustomScrollbar {
|
||||
overscroll-behavior: contain;
|
||||
}
|
||||
|
||||
.wire-scrollbar[data-color="secondary"] {
|
||||
--scrollbar-accent: var(--wire-color-secondary);
|
||||
.wrn-scrollbar[data-color="secondary"] {
|
||||
--scrollbar-accent: var(--wrn-color-secondary);
|
||||
}
|
||||
|
||||
.wire-scrollbar[data-color="success"] {
|
||||
--scrollbar-accent: var(--wire-color-success);
|
||||
.wrn-scrollbar[data-color="success"] {
|
||||
--scrollbar-accent: var(--wrn-color-success);
|
||||
}
|
||||
|
||||
.wire-scrollbar[data-color="danger"] {
|
||||
--scrollbar-accent: var(--wire-color-danger);
|
||||
.wrn-scrollbar[data-color="danger"] {
|
||||
--scrollbar-accent: var(--wrn-color-danger);
|
||||
}
|
||||
|
||||
.wire-scrollbar[data-color="info"] {
|
||||
--scrollbar-accent: var(--wire-color-info);
|
||||
.wrn-scrollbar[data-color="info"] {
|
||||
--scrollbar-accent: var(--wrn-color-info);
|
||||
}
|
||||
|
||||
.wire-scrollbar[data-axis="vertical"] {
|
||||
.wrn-scrollbar[data-axis="vertical"] {
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.wire-scrollbar[data-axis="horizontal"] {
|
||||
.wrn-scrollbar[data-axis="horizontal"] {
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
||||
.wire-scrollbar::-webkit-scrollbar {
|
||||
.wrn-scrollbar::-webkit-scrollbar {
|
||||
width: var(--scrollbar-thickness, 8px);
|
||||
height: var(--scrollbar-thickness, 8px);
|
||||
}
|
||||
|
||||
.wire-scrollbar::-webkit-scrollbar-track {
|
||||
background: var(--wire-color-surface-soft);
|
||||
.wrn-scrollbar::-webkit-scrollbar-track {
|
||||
background: var(--wrn-color-surface-soft);
|
||||
border-radius: var(--scrollbar-radius, 999px);
|
||||
}
|
||||
|
||||
.wire-scrollbar::-webkit-scrollbar-thumb {
|
||||
.wrn-scrollbar::-webkit-scrollbar-thumb {
|
||||
background: color-mix(in srgb, var(--scrollbar-accent) 45%, transparent);
|
||||
border-radius: var(--scrollbar-radius, 999px);
|
||||
}
|
||||
|
||||
.wire-scrollbar::-webkit-scrollbar-thumb:hover {
|
||||
.wrn-scrollbar::-webkit-scrollbar-thumb:hover {
|
||||
background: var(--scrollbar-accent);
|
||||
}
|
||||
|
||||
@@ -114,7 +114,7 @@ component CustomScrollbar {
|
||||
* width above, so the region keeps its own padding instead.
|
||||
*/
|
||||
@media (hover: none) {
|
||||
.wire-scrollbar {
|
||||
.wrn-scrollbar {
|
||||
scrollbar-width: auto;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import ComponentBaseStyles from "../styles/ComponentBaseStyles.wrn"
|
||||
|
||||
component DataMap {
|
||||
outputs {
|
||||
select(payload: { value?: string | number | boolean | null; values?: Array<string | number | boolean | null | object>; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | string | number | boolean | null)
|
||||
@@ -16,27 +14,95 @@ component DataMap {
|
||||
class: string = ""
|
||||
}
|
||||
view {
|
||||
<section class="wire-component wire-component--color-{color} wire-component--size-{size} wire-next--data-map wire-next--variant-{variant} {class}">
|
||||
<section class="wrn-component wrn-component--color-{color} wrn-component--size-{size} wrn-next--data-map wrn-next--variant-{variant} {class}">
|
||||
{#if title}<strong>{title}</strong>{/if}
|
||||
{#if description}<p>{description}</p>{/if}
|
||||
{#if items}<div class="wire-next__items">{#each items as item}<span>{item.label}</span>{/each}</div>{/if}
|
||||
{#if items}<div class="wrn-next__items">{#each items as item}<span>{item.label}</span>{/each}</div>{/if}
|
||||
<slot />
|
||||
</section>
|
||||
<ComponentBaseStyles hidden />
|
||||
}
|
||||
|
||||
style {
|
||||
.wire-next--data-map {
|
||||
.wrn-next--data-map {
|
||||
display: grid;
|
||||
gap: 0.75rem;
|
||||
padding: 1rem;
|
||||
border: 1px solid var(--wire-color-border);
|
||||
border-radius: var(--wire-radius);
|
||||
color: var(--wire-color-text);
|
||||
background: var(--wire-color-surface);
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: var(--wrn-radius);
|
||||
color: var(--wrn-color-text);
|
||||
background: var(--wrn-color-surface);
|
||||
}
|
||||
.wire-next--data-map > p { margin: 0; color: var(--wire-color-muted); }
|
||||
.wire-next--data-map > .wire-next__items { display: flex; flex-wrap: wrap; gap: 0.5rem; }
|
||||
.wire-next--data-map > .wire-next__items > span { padding: 0.35rem 0.6rem; border-radius: var(--wire-radius-sm); background: var(--wire-color-surface-2); }
|
||||
.wrn-next--data-map > p { margin: 0; color: var(--wrn-color-muted); }
|
||||
.wrn-next--data-map > .wrn-next__items { display: flex; flex-wrap: wrap; gap: 0.5rem; }
|
||||
.wrn-next--data-map > .wrn-next__items > span { padding: 0.35rem 0.6rem; border-radius: var(--wrn-radius-sm); background: var(--wrn-color-surface-2); }
|
||||
|
||||
/* Shared component foundation. */
|
||||
|
||||
.wrn-component {
|
||||
--wrn-component-color: var(--wrn-color-primary);
|
||||
--wrn-component-scale: 1;
|
||||
margin: 0;
|
||||
color: var(--wrn-color-text);
|
||||
font-family: var(--wrn-font-sans, inherit);
|
||||
}
|
||||
|
||||
.wrn-component--color-primary {
|
||||
--wrn-component-color: var(--wrn-color-primary);
|
||||
}
|
||||
|
||||
.wrn-component--color-secondary {
|
||||
--wrn-component-color: var(--wrn-color-secondary);
|
||||
}
|
||||
|
||||
.wrn-component--color-success {
|
||||
--wrn-component-color: var(--wrn-color-success);
|
||||
}
|
||||
|
||||
.wrn-component--color-warning {
|
||||
--wrn-component-color: var(--wrn-color-warning);
|
||||
}
|
||||
|
||||
.wrn-component--color-danger {
|
||||
--wrn-component-color: var(--wrn-color-danger);
|
||||
}
|
||||
|
||||
.wrn-component--color-info {
|
||||
--wrn-component-color: var(--wrn-color-info);
|
||||
}
|
||||
|
||||
.wrn-component--size-xs {
|
||||
--wrn-component-scale: 0.78;
|
||||
}
|
||||
|
||||
.wrn-component--size-sm {
|
||||
--wrn-component-scale: 0.88;
|
||||
}
|
||||
|
||||
.wrn-component--size-default,
|
||||
.wrn-component--size-md {
|
||||
--wrn-component-scale: 1;
|
||||
}
|
||||
|
||||
.wrn-component--size-lg {
|
||||
--wrn-component-scale: 1.14;
|
||||
}
|
||||
|
||||
.wrn-component--size-xl {
|
||||
--wrn-component-scale: 1.28;
|
||||
}
|
||||
|
||||
.wrn-component:not(.wrn-btn) {
|
||||
font-size: calc(1em * var(--wrn-component-scale));
|
||||
}
|
||||
|
||||
.wrn-component :is(a, button, input, select, textarea):focus-visible {
|
||||
outline-color: var(--wrn-component-color);
|
||||
}
|
||||
|
||||
.wrn-component p {
|
||||
margin: 0;
|
||||
color: var(--wrn-color-muted);
|
||||
line-height: 1.6;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import ComponentBaseStyles from "../styles/ComponentBaseStyles.wrn"
|
||||
|
||||
//
|
||||
// DataTable -- columns, sorting, filtering, pagination and selection over an
|
||||
// array of records.
|
||||
@@ -737,29 +735,29 @@ component DataTable {
|
||||
data-layout='{layout}'
|
||||
data-loading='{loading ? "true" : "false"}'
|
||||
data-sticky-first='{stickyFirstColumn ? "true" : "false"}'
|
||||
class='wire-table {class}'
|
||||
class='wrn-table {class}'
|
||||
@window:wrnexus:datatable:rows='applyRows(event)'
|
||||
@window:wrnexus:datatable:error='applyError(event)'
|
||||
>
|
||||
{#if caption || description || searchable}
|
||||
<div class="wire-table__toolbar">
|
||||
<div class="wire-table__heading">
|
||||
<div class="wrn-table__toolbar">
|
||||
<div class="wrn-table__heading">
|
||||
{#if caption}
|
||||
<h3 class="wire-table__caption">{caption}</h3>
|
||||
<h3 class="wrn-table__caption">{caption}</h3>
|
||||
{/if}
|
||||
{#if description}
|
||||
<p class="wire-table__description">{description}</p>
|
||||
<p class="wrn-table__description">{description}</p>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<div class="wire-table__actions" data-show="visibleActions().length">
|
||||
<span class="wire-table__selected-count" data-show="selectedCount()">
|
||||
<div class="wrn-table__actions" data-show="visibleActions().length">
|
||||
<span class="wrn-table__selected-count" data-show="selectedCount()">
|
||||
{selectedCount()} selected
|
||||
</span>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
class="wire-table__action"
|
||||
class="wrn-table__action"
|
||||
data-for="entry in visibleActions()"
|
||||
data-key="entry.id"
|
||||
data-tone='{entry.tone}'
|
||||
@@ -771,7 +769,7 @@ component DataTable {
|
||||
</div>
|
||||
|
||||
{#if searchable}
|
||||
<div class="wire-table__search">
|
||||
<div class="wrn-table__search">
|
||||
<svg
|
||||
viewBox="0 0 24 24"
|
||||
width="15"
|
||||
@@ -797,15 +795,15 @@ component DataTable {
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<div class="wire-table__scroll">
|
||||
<table class="wire-table__table" data-show="layout !== 'comparison'">
|
||||
<div class="wrn-table__scroll">
|
||||
<table class="wrn-table__table" data-show="layout !== 'comparison'">
|
||||
<thead>
|
||||
<tr>
|
||||
{#if selectable}
|
||||
<th class="wire-table__select-cell" scope="col">
|
||||
<th class="wrn-table__select-cell" scope="col">
|
||||
<button
|
||||
type="button"
|
||||
class="wire-table__check"
|
||||
class="wrn-table__check"
|
||||
role="checkbox"
|
||||
aria-label="Select all rows on this page"
|
||||
aria-checked='{allVisibleSelected() ? "true" : "false"}'
|
||||
@@ -828,14 +826,14 @@ component DataTable {
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
class="wire-table__sort"
|
||||
class="wrn-table__sort"
|
||||
data-show="column.sortable"
|
||||
data-active='{column.active}'
|
||||
@click='sortBy(column.key)'
|
||||
>
|
||||
<span>{column.label}</span>
|
||||
<svg
|
||||
class="wire-table__sort-icon"
|
||||
class="wrn-table__sort-icon"
|
||||
viewBox="0 0 24 24"
|
||||
width="12"
|
||||
height="12"
|
||||
@@ -863,10 +861,10 @@ component DataTable {
|
||||
@click='emitRowClick(row.raw, event)'
|
||||
>
|
||||
{#if selectable}
|
||||
<td class="wire-table__select-cell">
|
||||
<td class="wrn-table__select-cell">
|
||||
<button
|
||||
type="button"
|
||||
class="wire-table__check"
|
||||
class="wrn-table__check"
|
||||
role="checkbox"
|
||||
aria-label="Select row"
|
||||
aria-checked='{row.selected}'
|
||||
@@ -893,7 +891,7 @@ component DataTable {
|
||||
</table>
|
||||
|
||||
<!-- Comparison layout: fields down the left, one column per record. -->
|
||||
<table class="wire-table__table wire-table__table--comparison" data-show="layout === 'comparison'">
|
||||
<table class="wrn-table__table wrn-table__table--comparison" data-show="layout === 'comparison'">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">{caption}</th>
|
||||
@@ -908,7 +906,7 @@ component DataTable {
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr data-for="field in comparisonRows()" data-key="field.key">
|
||||
<th scope="row" class="wire-table__field-label">{field.label}</th>
|
||||
<th scope="row" class="wrn-table__field-label">{field.label}</th>
|
||||
<td
|
||||
data-for="cell in field.cells"
|
||||
data-key="cell.key"
|
||||
@@ -921,26 +919,26 @@ component DataTable {
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="wire-table__status" data-show="loading">
|
||||
<span class="wire-table__spinner" aria-hidden="true"></span>
|
||||
<div class="wrn-table__status" data-show="loading">
|
||||
<span class="wrn-table__spinner" aria-hidden="true"></span>
|
||||
<span>{loadingLabel}</span>
|
||||
</div>
|
||||
|
||||
<div class="wire-table__status wire-table__status--error" data-show="loadError">
|
||||
<div class="wrn-table__status wrn-table__status--error" data-show="loadError">
|
||||
<span>{loadError}</span>
|
||||
<button type="button" class="wire-table__action" @click='reload()'>
|
||||
<button type="button" class="wrn-table__action" @click='reload()'>
|
||||
{retryLabel}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="wire-table__status"
|
||||
class="wrn-table__status"
|
||||
data-show="!loading && !loadError && totalCount() === 0"
|
||||
>
|
||||
<span>{emptyMessage()}</span>
|
||||
<button
|
||||
type="button"
|
||||
class="wire-table__action"
|
||||
class="wrn-table__action"
|
||||
data-show="isFiltered()"
|
||||
@click='clearSearch()'
|
||||
>
|
||||
@@ -949,11 +947,11 @@ component DataTable {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="wire-table__footer" data-show="paginated && totalCount() > 0">
|
||||
<p class="wire-table__range">{rangeLabel()}</p>
|
||||
<div class="wrn-table__footer" data-show="paginated && totalCount() > 0">
|
||||
<p class="wrn-table__range">{rangeLabel()}</p>
|
||||
|
||||
<div class="wire-table__pager">
|
||||
<span class="wire-table__page-size">
|
||||
<div class="wrn-table__pager">
|
||||
<span class="wrn-table__page-size">
|
||||
<span>Rows</span>
|
||||
<!-- The shared Dropdown rather than a native select: a select
|
||||
renders its list with the operating system styling, which
|
||||
@@ -961,7 +959,7 @@ component DataTable {
|
||||
slot so it stays reactive -- a prop would be fixed at the
|
||||
value the dropdown was first rendered with. -->
|
||||
<Dropdown
|
||||
class="wire-table__page-dropdown"
|
||||
class="wrn-table__page-dropdown"
|
||||
width="sm"
|
||||
size="sm"
|
||||
placement="top-end"
|
||||
@@ -975,7 +973,7 @@ component DataTable {
|
||||
|
||||
<button
|
||||
type="button"
|
||||
class="wire-table__page-button"
|
||||
class="wrn-table__page-button"
|
||||
aria-label="Previous page"
|
||||
disabled='{currentPage() <= 1}'
|
||||
@click='goToPage(currentPage() - 1)'
|
||||
@@ -996,19 +994,19 @@ component DataTable {
|
||||
</button>
|
||||
|
||||
<span
|
||||
class="wire-table__page-indicator"
|
||||
class="wrn-table__page-indicator"
|
||||
data-show="paginationStyle !== 'numbered'"
|
||||
>
|
||||
{currentPage()} / {pageCount()}
|
||||
</span>
|
||||
|
||||
<span
|
||||
class="wire-table__page-numbers"
|
||||
class="wrn-table__page-numbers"
|
||||
data-show="paginationStyle === 'numbered'"
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
class="wire-table__page-number"
|
||||
class="wrn-table__page-number"
|
||||
data-for="entry in pageNumbers()"
|
||||
data-key="entry.number"
|
||||
data-active='{entry.active}'
|
||||
@@ -1021,7 +1019,7 @@ component DataTable {
|
||||
|
||||
<button
|
||||
type="button"
|
||||
class="wire-table__page-button"
|
||||
class="wrn-table__page-button"
|
||||
aria-label="Next page"
|
||||
disabled='{currentPage() >= pageCount()}'
|
||||
@click='goToPage(currentPage() + 1)'
|
||||
@@ -1045,48 +1043,47 @@ component DataTable {
|
||||
|
||||
<slot></slot>
|
||||
</div>
|
||||
<ComponentBaseStyles hidden />
|
||||
}
|
||||
|
||||
style {
|
||||
.wire-next--data-map {
|
||||
.wrn-next--data-map {
|
||||
display: grid;
|
||||
gap: 0.75rem;
|
||||
padding: 1rem;
|
||||
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);
|
||||
}
|
||||
|
||||
.wire-table {
|
||||
--table-accent: var(--wire-color-primary);
|
||||
.wrn-table {
|
||||
--table-accent: var(--wrn-color-primary);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.85rem;
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
max-width: 100%;
|
||||
color: var(--wire-color-text);
|
||||
color: var(--wrn-color-text);
|
||||
}
|
||||
|
||||
.wire-table[data-color="secondary"] {
|
||||
--table-accent: var(--wire-color-secondary);
|
||||
.wrn-table[data-color="secondary"] {
|
||||
--table-accent: var(--wrn-color-secondary);
|
||||
}
|
||||
|
||||
.wire-table[data-color="success"] {
|
||||
--table-accent: var(--wire-color-success);
|
||||
.wrn-table[data-color="success"] {
|
||||
--table-accent: var(--wrn-color-success);
|
||||
}
|
||||
|
||||
.wire-table[data-color="danger"] {
|
||||
--table-accent: var(--wire-color-danger);
|
||||
.wrn-table[data-color="danger"] {
|
||||
--table-accent: var(--wrn-color-danger);
|
||||
}
|
||||
|
||||
.wire-table[data-color="info"] {
|
||||
--table-accent: var(--wire-color-info);
|
||||
.wrn-table[data-color="info"] {
|
||||
--table-accent: var(--wrn-color-info);
|
||||
}
|
||||
|
||||
.wire-table__toolbar {
|
||||
.wrn-table__toolbar {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
justify-content: space-between;
|
||||
@@ -1094,97 +1091,97 @@ component DataTable {
|
||||
gap: 0.75rem;
|
||||
}
|
||||
|
||||
.wire-table__heading {
|
||||
.wrn-table__heading {
|
||||
display: grid;
|
||||
gap: 0.2rem;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.wire-table__caption {
|
||||
.wrn-table__caption {
|
||||
margin: 0;
|
||||
color: var(--wire-color-text);
|
||||
color: var(--wrn-color-text);
|
||||
font-size: 0.98rem;
|
||||
font-weight: 650;
|
||||
}
|
||||
|
||||
.wire-table__description {
|
||||
.wrn-table__description {
|
||||
margin: 0;
|
||||
color: var(--wire-color-text-muted);
|
||||
color: var(--wrn-color-text-muted);
|
||||
font-size: 0.82rem;
|
||||
}
|
||||
|
||||
.wire-table__actions {
|
||||
.wrn-table__actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.4rem;
|
||||
}
|
||||
|
||||
.wire-table__selected-count {
|
||||
color: var(--wire-color-text-muted);
|
||||
.wrn-table__selected-count {
|
||||
color: var(--wrn-color-text-muted);
|
||||
font-size: 0.78rem;
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
|
||||
.wire-table__action {
|
||||
.wrn-table__action {
|
||||
appearance: none;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.35rem;
|
||||
min-height: 2.1rem;
|
||||
padding: 0 0.7rem;
|
||||
color: var(--wire-color-text);
|
||||
background: var(--wire-color-surface-soft);
|
||||
border: 1px solid var(--wire-color-border);
|
||||
border-radius: var(--wire-radius-sm);
|
||||
color: var(--wrn-color-text);
|
||||
background: var(--wrn-color-surface-soft);
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: var(--wrn-radius-sm);
|
||||
font: inherit;
|
||||
font-size: 0.79rem;
|
||||
cursor: pointer;
|
||||
transition: border-color 140ms ease, color 140ms ease, background 140ms ease;
|
||||
}
|
||||
|
||||
.wire-table__action:hover {
|
||||
.wrn-table__action:hover {
|
||||
color: var(--table-accent);
|
||||
border-color: color-mix(in srgb, var(--table-accent) 45%, var(--wire-color-border));
|
||||
border-color: color-mix(in srgb, var(--table-accent) 45%, var(--wrn-color-border));
|
||||
}
|
||||
|
||||
.wire-table__action[data-tone="danger"] {
|
||||
color: var(--wire-color-danger);
|
||||
border-color: color-mix(in srgb, var(--wire-color-danger) 35%, var(--wire-color-border));
|
||||
.wrn-table__action[data-tone="danger"] {
|
||||
color: var(--wrn-color-danger);
|
||||
border-color: color-mix(in srgb, var(--wrn-color-danger) 35%, var(--wrn-color-border));
|
||||
}
|
||||
|
||||
.wire-table__action[data-tone="danger"]:hover {
|
||||
background: color-mix(in srgb, var(--wire-color-danger) 12%, transparent);
|
||||
.wrn-table__action[data-tone="danger"]:hover {
|
||||
background: color-mix(in srgb, var(--wrn-color-danger) 12%, transparent);
|
||||
}
|
||||
|
||||
/* Full gridlines: vertical rules between columns as well as rows. */
|
||||
.wire-table[data-gridlines="grid"] .wire-table__table th,
|
||||
.wire-table[data-gridlines="grid"] .wire-table__table td {
|
||||
border-right: 1px solid color-mix(in srgb, var(--wire-color-border) 60%, transparent);
|
||||
.wrn-table[data-gridlines="grid"] .wrn-table__table th,
|
||||
.wrn-table[data-gridlines="grid"] .wrn-table__table td {
|
||||
border-right: 1px solid color-mix(in srgb, var(--wrn-color-border) 60%, transparent);
|
||||
}
|
||||
|
||||
.wire-table[data-gridlines="grid"] .wire-table__table th:last-child,
|
||||
.wire-table[data-gridlines="grid"] .wire-table__table td:last-child {
|
||||
.wrn-table[data-gridlines="grid"] .wrn-table__table th:last-child,
|
||||
.wrn-table[data-gridlines="grid"] .wrn-table__table td:last-child {
|
||||
border-right: 0;
|
||||
}
|
||||
|
||||
.wire-table__search {
|
||||
.wrn-table__search {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.45rem;
|
||||
min-height: 2.35rem;
|
||||
padding: 0 0.7rem;
|
||||
color: var(--wire-color-text-muted);
|
||||
background: var(--wire-color-surface-soft);
|
||||
border: 1px solid var(--wire-color-border);
|
||||
color: var(--wrn-color-text-muted);
|
||||
background: var(--wrn-color-surface-soft);
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: 0.7rem;
|
||||
}
|
||||
|
||||
.wire-table__search input {
|
||||
.wrn-table__search input {
|
||||
width: 12rem;
|
||||
max-width: 100%;
|
||||
padding: 0;
|
||||
color: var(--wire-color-text);
|
||||
color: var(--wrn-color-text);
|
||||
background: transparent;
|
||||
border: 0;
|
||||
font: inherit;
|
||||
@@ -1192,8 +1189,8 @@ component DataTable {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.wire-table__search:focus-within {
|
||||
border-color: color-mix(in srgb, var(--table-accent) 45%, var(--wire-color-border));
|
||||
.wrn-table__search:focus-within {
|
||||
border-color: color-mix(in srgb, var(--table-accent) 45%, var(--wrn-color-border));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1205,73 +1202,73 @@ component DataTable {
|
||||
* spilled out over the page beside it instead of scrolling inside its own
|
||||
* box. min-width: 0 alone is not enough once the parent is a grid.
|
||||
*/
|
||||
.wire-table__scroll {
|
||||
.wrn-table__scroll {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
max-width: 100%;
|
||||
overflow-x: auto;
|
||||
border: 1px solid var(--wire-color-border);
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: 0.9rem;
|
||||
}
|
||||
|
||||
.wire-table[data-bordered="false"] .wire-table__scroll {
|
||||
.wrn-table[data-bordered="false"] .wrn-table__scroll {
|
||||
border: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.wire-table__table {
|
||||
.wrn-table__table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
.wire-table__table th,
|
||||
.wire-table__table td {
|
||||
.wrn-table__table th,
|
||||
.wrn-table__table td {
|
||||
padding: 0.7rem 0.85rem;
|
||||
text-align: left;
|
||||
vertical-align: middle;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.wire-table[data-density="compact"] .wire-table__table th,
|
||||
.wire-table[data-density="compact"] .wire-table__table td {
|
||||
.wrn-table[data-density="compact"] .wrn-table__table th,
|
||||
.wrn-table[data-density="compact"] .wrn-table__table td {
|
||||
padding: 0.42rem 0.6rem;
|
||||
}
|
||||
|
||||
.wire-table[data-density="comfortable"] .wire-table__table th,
|
||||
.wire-table[data-density="comfortable"] .wire-table__table td {
|
||||
.wrn-table[data-density="comfortable"] .wrn-table__table th,
|
||||
.wrn-table[data-density="comfortable"] .wrn-table__table td {
|
||||
padding: 0.95rem 1rem;
|
||||
}
|
||||
|
||||
.wire-table__table th[data-align="center"],
|
||||
.wire-table__table td[data-align="center"] {
|
||||
.wrn-table__table th[data-align="center"],
|
||||
.wrn-table__table td[data-align="center"] {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.wire-table__table th[data-align="end"],
|
||||
.wire-table__table td[data-align="end"] {
|
||||
.wrn-table__table th[data-align="end"],
|
||||
.wrn-table__table td[data-align="end"] {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.wire-table__table thead th {
|
||||
.wrn-table__table thead th {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 1;
|
||||
color: var(--wire-color-text-muted);
|
||||
background: var(--wire-color-surface-soft);
|
||||
border-bottom: 1px solid var(--wire-color-border);
|
||||
color: var(--wrn-color-text-muted);
|
||||
background: var(--wrn-color-surface-soft);
|
||||
border-bottom: 1px solid var(--wrn-color-border);
|
||||
font-size: 0.76rem;
|
||||
font-weight: 650;
|
||||
letter-spacing: 0.02em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.wire-table__table tbody tr {
|
||||
border-bottom: 1px solid color-mix(in srgb, var(--wire-color-border) 60%, transparent);
|
||||
.wrn-table__table tbody tr {
|
||||
border-bottom: 1px solid color-mix(in srgb, var(--wrn-color-border) 60%, transparent);
|
||||
}
|
||||
|
||||
.wire-table__table tbody tr:last-child {
|
||||
.wrn-table__table tbody tr:last-child {
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
@@ -1286,24 +1283,24 @@ component DataTable {
|
||||
* about the row, not decoration, so it wins outright; every rule below
|
||||
* sits at the same specificity and is ordered deliberately.
|
||||
*/
|
||||
.wire-table[data-striped="true"] .wire-table__table tbody tr:nth-child(even) {
|
||||
background: color-mix(in srgb, var(--wire-color-surface-soft) 55%, transparent);
|
||||
.wrn-table[data-striped="true"] .wrn-table__table tbody tr:nth-child(even) {
|
||||
background: color-mix(in srgb, var(--wrn-color-surface-soft) 55%, transparent);
|
||||
}
|
||||
|
||||
.wire-table[data-striped] .wire-table__table tbody tr:hover:not([data-selected="true"]) {
|
||||
.wrn-table[data-striped] .wrn-table__table tbody tr:hover:not([data-selected="true"]) {
|
||||
background: color-mix(in srgb, var(--table-accent) 7%, transparent);
|
||||
}
|
||||
|
||||
/* Every selected row identical, striped or not. */
|
||||
.wire-table[data-striped] .wire-table__table tbody tr[data-selected="true"] {
|
||||
.wrn-table[data-striped] .wrn-table__table tbody tr[data-selected="true"] {
|
||||
background: color-mix(in srgb, var(--table-accent) 15%, transparent);
|
||||
}
|
||||
|
||||
.wire-table[data-striped] .wire-table__table tbody tr[data-selected="true"]:hover {
|
||||
.wrn-table[data-striped] .wrn-table__table tbody tr[data-selected="true"]:hover {
|
||||
background: color-mix(in srgb, var(--table-accent) 22%, transparent);
|
||||
}
|
||||
|
||||
.wire-table__sort {
|
||||
.wrn-table__sort {
|
||||
appearance: none;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
@@ -1320,29 +1317,29 @@ component DataTable {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.wire-table__sort:hover {
|
||||
.wrn-table__sort:hover {
|
||||
color: var(--table-accent);
|
||||
}
|
||||
|
||||
.wire-table__sort-icon {
|
||||
.wrn-table__sort-icon {
|
||||
flex: 0 0 auto;
|
||||
opacity: 0.45;
|
||||
}
|
||||
|
||||
.wire-table__sort[data-active="true"] {
|
||||
.wrn-table__sort[data-active="true"] {
|
||||
color: var(--table-accent);
|
||||
}
|
||||
|
||||
.wire-table__sort[data-active="true"] .wire-table__sort-icon {
|
||||
.wrn-table__sort[data-active="true"] .wrn-table__sort-icon {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.wire-table__select-cell {
|
||||
.wrn-table__select-cell {
|
||||
width: 2.6rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.wire-table__check {
|
||||
.wrn-table__check {
|
||||
appearance: none;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
@@ -1351,75 +1348,75 @@ component DataTable {
|
||||
width: 1.05rem;
|
||||
height: 1.05rem;
|
||||
color: transparent;
|
||||
background: var(--wire-color-surface-raised);
|
||||
border: 1px solid var(--wire-color-border);
|
||||
background: var(--wrn-color-surface-raised);
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: 0.32rem;
|
||||
cursor: pointer;
|
||||
transition: background 140ms ease, border-color 140ms ease, color 140ms ease;
|
||||
}
|
||||
|
||||
.wire-table__check[aria-checked="true"] {
|
||||
color: var(--wire-color-primary-contrast);
|
||||
.wrn-table__check[aria-checked="true"] {
|
||||
color: var(--wrn-color-primary-contrast);
|
||||
background: var(--table-accent);
|
||||
border-color: var(--table-accent);
|
||||
}
|
||||
|
||||
.wire-table__check:focus-visible {
|
||||
.wrn-table__check:focus-visible {
|
||||
outline: none;
|
||||
box-shadow: 0 0 0 3px color-mix(in srgb, var(--table-accent) 35%, transparent);
|
||||
}
|
||||
|
||||
.wire-table__table--comparison {
|
||||
.wrn-table__table--comparison {
|
||||
width: auto;
|
||||
min-width: 100%;
|
||||
}
|
||||
|
||||
.wire-table__table--comparison th,
|
||||
.wire-table__table--comparison td {
|
||||
.wrn-table__table--comparison th,
|
||||
.wrn-table__table--comparison td {
|
||||
min-width: 7rem;
|
||||
}
|
||||
|
||||
.wire-table__table--comparison th[scope="row"] {
|
||||
color: var(--wire-color-text-muted);
|
||||
background: var(--wire-color-surface-soft);
|
||||
.wrn-table__table--comparison th[scope="row"] {
|
||||
color: var(--wrn-color-text-muted);
|
||||
background: var(--wrn-color-surface-soft);
|
||||
font-size: 0.76rem;
|
||||
font-weight: 650;
|
||||
text-transform: uppercase;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.wire-table[data-layout="comparison"] .wire-table__table th:first-child,
|
||||
.wire-table[data-layout="comparison"] .wire-table__table td:first-child {
|
||||
.wrn-table[data-layout="comparison"] .wrn-table__table th:first-child,
|
||||
.wrn-table[data-layout="comparison"] .wrn-table__table td:first-child {
|
||||
position: sticky;
|
||||
left: 0;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.wire-table__status {
|
||||
.wrn-table__status {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 0.6rem;
|
||||
padding: 1.75rem 1rem;
|
||||
color: var(--wire-color-text-muted);
|
||||
color: var(--wrn-color-text-muted);
|
||||
font-size: 0.85rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.wire-table__status--error {
|
||||
color: var(--wire-color-danger);
|
||||
.wrn-table__status--error {
|
||||
color: var(--wrn-color-danger);
|
||||
}
|
||||
|
||||
.wire-table__spinner {
|
||||
.wrn-table__spinner {
|
||||
width: 0.95rem;
|
||||
height: 0.95rem;
|
||||
border: 2px solid color-mix(in srgb, currentColor 30%, transparent);
|
||||
border-top-color: currentColor;
|
||||
border-radius: 50%;
|
||||
animation: wire-table-spin 700ms linear infinite;
|
||||
animation: wrn-table-spin 700ms linear infinite;
|
||||
}
|
||||
|
||||
@keyframes wire-table-spin {
|
||||
@keyframes wrn-table-spin {
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
@@ -1427,32 +1424,32 @@ component DataTable {
|
||||
|
||||
/* Dim the rows while a refresh is in flight rather than tearing them out:
|
||||
a table that empties on every keystroke is far harder to read. */
|
||||
.wire-table[data-loading="true"] .wire-table__table tbody {
|
||||
.wrn-table[data-loading="true"] .wrn-table__table tbody {
|
||||
opacity: 0.45;
|
||||
}
|
||||
|
||||
/* Keeps the first column readable while the rest scrolls sideways. */
|
||||
.wire-table[data-sticky-first="true"] .wire-table__table th:first-child,
|
||||
.wire-table[data-sticky-first="true"] .wire-table__table td:first-child {
|
||||
.wrn-table[data-sticky-first="true"] .wrn-table__table th:first-child,
|
||||
.wrn-table[data-sticky-first="true"] .wrn-table__table td:first-child {
|
||||
position: sticky;
|
||||
left: 0;
|
||||
z-index: 2;
|
||||
background: var(--wire-color-surface);
|
||||
background: var(--wrn-color-surface);
|
||||
}
|
||||
|
||||
.wire-table[data-sticky-first="true"] .wire-table__table thead th:first-child {
|
||||
.wrn-table[data-sticky-first="true"] .wrn-table__table thead th:first-child {
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
.wire-table__empty {
|
||||
.wrn-table__empty {
|
||||
margin: 0;
|
||||
padding: 1.75rem 1rem;
|
||||
color: var(--wire-color-text-muted);
|
||||
color: var(--wrn-color-text-muted);
|
||||
font-size: 0.85rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.wire-table__footer {
|
||||
.wrn-table__footer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
@@ -1460,27 +1457,27 @@ component DataTable {
|
||||
gap: 0.75rem;
|
||||
}
|
||||
|
||||
.wire-table__range {
|
||||
.wrn-table__range {
|
||||
margin: 0;
|
||||
color: var(--wire-color-text-muted);
|
||||
color: var(--wrn-color-text-muted);
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
.wire-table__pager {
|
||||
.wrn-table__pager {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.wire-table__page-size {
|
||||
.wrn-table__page-size {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.4rem;
|
||||
color: var(--wire-color-text-muted);
|
||||
color: var(--wrn-color-text-muted);
|
||||
font-size: 0.78rem;
|
||||
}
|
||||
|
||||
.wire-table__page-dropdown {
|
||||
.wrn-table__page-dropdown {
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
@@ -1489,7 +1486,7 @@ component DataTable {
|
||||
* outranks the browser default and would crush the icon inside these
|
||||
* fixed-size controls.
|
||||
*/
|
||||
.wire-table__page-button {
|
||||
.wrn-table__page-button {
|
||||
appearance: none;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
@@ -1498,39 +1495,39 @@ component DataTable {
|
||||
padding: 0;
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
color: var(--wire-color-text);
|
||||
background: var(--wire-color-surface-soft);
|
||||
border: 1px solid var(--wire-color-border);
|
||||
color: var(--wrn-color-text);
|
||||
background: var(--wrn-color-surface-soft);
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: 0.55rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.wire-table__page-button:hover:not(:disabled) {
|
||||
.wrn-table__page-button:hover:not(:disabled) {
|
||||
color: var(--table-accent);
|
||||
border-color: color-mix(in srgb, var(--table-accent) 40%, var(--wire-color-border));
|
||||
border-color: color-mix(in srgb, var(--table-accent) 40%, var(--wrn-color-border));
|
||||
}
|
||||
|
||||
.wire-table__page-button:disabled {
|
||||
.wrn-table__page-button:disabled {
|
||||
opacity: 0.45;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.wire-table__page-button svg {
|
||||
.wrn-table__page-button svg {
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.wire-table__page-numbers {
|
||||
.wrn-table__page-numbers {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.25rem;
|
||||
}
|
||||
|
||||
.wire-table__page-number {
|
||||
.wrn-table__page-number {
|
||||
appearance: none;
|
||||
min-width: 2rem;
|
||||
height: 2rem;
|
||||
padding: 0 0.4rem;
|
||||
color: var(--wire-color-text-muted);
|
||||
color: var(--wrn-color-text-muted);
|
||||
background: transparent;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 0.55rem;
|
||||
@@ -1540,19 +1537,19 @@ component DataTable {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.wire-table__page-number:hover {
|
||||
color: var(--wire-color-text);
|
||||
background: var(--wire-color-surface-soft);
|
||||
.wrn-table__page-number:hover {
|
||||
color: var(--wrn-color-text);
|
||||
background: var(--wrn-color-surface-soft);
|
||||
}
|
||||
|
||||
.wire-table__page-number[data-active="true"] {
|
||||
color: var(--wire-color-primary-contrast);
|
||||
.wrn-table__page-number[data-active="true"] {
|
||||
color: var(--wrn-color-primary-contrast);
|
||||
background: var(--table-accent);
|
||||
border-color: var(--table-accent);
|
||||
}
|
||||
|
||||
.wire-table__page-indicator {
|
||||
color: var(--wire-color-text-muted);
|
||||
.wrn-table__page-indicator {
|
||||
color: var(--wrn-color-text-muted);
|
||||
font-size: 0.78rem;
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
@@ -1563,51 +1560,51 @@ component DataTable {
|
||||
* scrollbar on a phone.
|
||||
*/
|
||||
@media (max-width: 639px) {
|
||||
.wire-table__scroll {
|
||||
.wrn-table__scroll {
|
||||
overflow-x: visible;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.wire-table__table,
|
||||
.wire-table__table tbody,
|
||||
.wire-table__table tr,
|
||||
.wire-table__table td {
|
||||
.wrn-table__table,
|
||||
.wrn-table__table tbody,
|
||||
.wrn-table__table tr,
|
||||
.wrn-table__table td {
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.wire-table__table thead {
|
||||
.wrn-table__table thead {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/*
|
||||
* Each row becomes a card. These are the exact tokens Card paints its
|
||||
* surface with (.wire-next__card-panel in ui.css) rather than a lookalike
|
||||
* surface with (.wrn-next__card-panel in ui.css) rather than a lookalike
|
||||
* of my own, so a stacked row and a real Card cannot drift apart.
|
||||
*
|
||||
* The Card component itself cannot be mounted per row: component tags
|
||||
* are resolved once, server side, while these rows are cloned in the
|
||||
* browser from a single template -- every row would share one mount.
|
||||
*/
|
||||
.wire-table__table tbody tr {
|
||||
.wrn-table__table tbody tr {
|
||||
margin-bottom: 0.7rem;
|
||||
padding: 0.5rem 0.25rem;
|
||||
background: var(--wire-color-surface);
|
||||
border: 1px solid var(--wire-color-border);
|
||||
border-radius: var(--wire-radius-md);
|
||||
box-shadow: var(--wire-shadow-1);
|
||||
background: var(--wrn-color-surface);
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: var(--wrn-radius-md);
|
||||
box-shadow: var(--wrn-shadow-1);
|
||||
}
|
||||
|
||||
.wire-table[data-striped="true"] .wire-table__table tbody tr:nth-child(even) {
|
||||
background: var(--wire-color-surface);
|
||||
.wrn-table[data-striped="true"] .wrn-table__table tbody tr:nth-child(even) {
|
||||
background: var(--wrn-color-surface);
|
||||
}
|
||||
|
||||
.wire-table[data-striped] .wire-table__table tbody tr[data-selected="true"] {
|
||||
background: color-mix(in srgb, var(--table-accent) 15%, var(--wire-color-surface));
|
||||
border-color: color-mix(in srgb, var(--table-accent) 45%, var(--wire-color-border));
|
||||
.wrn-table[data-striped] .wrn-table__table tbody tr[data-selected="true"] {
|
||||
background: color-mix(in srgb, var(--table-accent) 15%, var(--wrn-color-surface));
|
||||
border-color: color-mix(in srgb, var(--table-accent) 45%, var(--wrn-color-border));
|
||||
}
|
||||
|
||||
.wire-table__table td {
|
||||
.wrn-table__table td {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
@@ -1616,32 +1613,101 @@ component DataTable {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.wire-table__table td::before {
|
||||
.wrn-table__table td::before {
|
||||
content: attr(data-label);
|
||||
color: var(--wire-color-text-muted);
|
||||
color: var(--wrn-color-text-muted);
|
||||
font-size: 0.72rem;
|
||||
font-weight: 650;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.wire-table__select-cell {
|
||||
.wrn-table__select-cell {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.wire-table__footer {
|
||||
.wrn-table__footer {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.wire-table__actions {
|
||||
.wrn-table__actions {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* The page-size menu is anchored to a control near the bottom of the
|
||||
screen; it must be able to render outside the footer box. */
|
||||
.wire-table__footer,
|
||||
.wire-table__pager {
|
||||
.wrn-table__footer,
|
||||
.wrn-table__pager {
|
||||
overflow: visible;
|
||||
}
|
||||
}
|
||||
|
||||
/* Shared component foundation. */
|
||||
|
||||
.wrn-component {
|
||||
--wrn-component-color: var(--wrn-color-primary);
|
||||
--wrn-component-scale: 1;
|
||||
margin: 0;
|
||||
color: var(--wrn-color-text);
|
||||
font-family: var(--wrn-font-sans, inherit);
|
||||
}
|
||||
|
||||
.wrn-component--color-primary {
|
||||
--wrn-component-color: var(--wrn-color-primary);
|
||||
}
|
||||
|
||||
.wrn-component--color-secondary {
|
||||
--wrn-component-color: var(--wrn-color-secondary);
|
||||
}
|
||||
|
||||
.wrn-component--color-success {
|
||||
--wrn-component-color: var(--wrn-color-success);
|
||||
}
|
||||
|
||||
.wrn-component--color-warning {
|
||||
--wrn-component-color: var(--wrn-color-warning);
|
||||
}
|
||||
|
||||
.wrn-component--color-danger {
|
||||
--wrn-component-color: var(--wrn-color-danger);
|
||||
}
|
||||
|
||||
.wrn-component--color-info {
|
||||
--wrn-component-color: var(--wrn-color-info);
|
||||
}
|
||||
|
||||
.wrn-component--size-xs {
|
||||
--wrn-component-scale: 0.78;
|
||||
}
|
||||
|
||||
.wrn-component--size-sm {
|
||||
--wrn-component-scale: 0.88;
|
||||
}
|
||||
|
||||
.wrn-component--size-default,
|
||||
.wrn-component--size-md {
|
||||
--wrn-component-scale: 1;
|
||||
}
|
||||
|
||||
.wrn-component--size-lg {
|
||||
--wrn-component-scale: 1.14;
|
||||
}
|
||||
|
||||
.wrn-component--size-xl {
|
||||
--wrn-component-scale: 1.28;
|
||||
}
|
||||
|
||||
.wrn-component:not(.wrn-btn) {
|
||||
font-size: calc(1em * var(--wrn-component-scale));
|
||||
}
|
||||
|
||||
.wrn-component :is(a, button, input, select, textarea):focus-visible {
|
||||
outline-color: var(--wrn-component-color);
|
||||
}
|
||||
|
||||
.wrn-component p {
|
||||
margin: 0;
|
||||
color: var(--wrn-color-muted);
|
||||
line-height: 1.6;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
import FieldStyles from "../styles/FieldStyles.wrn"
|
||||
|
||||
import ComponentBaseStyles from "../styles/ComponentBaseStyles.wrn"
|
||||
|
||||
component DatePicker {
|
||||
outputs {
|
||||
input(payload: { sourceEvent?: Event; value: string | number | boolean | null | object; [key: string]: string | number | boolean | null | object } | string | number | boolean | null | object[])
|
||||
@@ -49,77 +45,634 @@ size: string = "default"
|
||||
client function openCalendar(sourceEvent) { expanded = true; output.open({ value: currentValue, name: name, sourceEvent: sourceEvent }) }
|
||||
client function updateDate(part, nextValue, sourceEvent, nextDate, detail) { if (part === "year") { selectedYear = String(nextValue) } if (part === "month") { selectedMonth = String(nextValue).padStart(2, "0") } if (part === "day") { selectedDay = String(nextValue).padStart(2, "0") } if (!selectedYear || !selectedMonth || !selectedDay) { return } nextDate = selectedYear + "-" + selectedMonth + "-" + selectedDay; if ((min && nextDate < min) || (max && nextDate > max)) { return } currentValue = nextDate; detail = { value: currentValue, year: selectedYear, month: selectedMonth, day: selectedDay, name: name, sourceEvent: sourceEvent }; output.input(detail); output.change(detail) }
|
||||
client function finishDate(sourceEvent) { if (!currentValue) { return } expanded = false; output.close({ value: currentValue, name: name, sourceEvent: sourceEvent }) }
|
||||
client function selectDay(sourceEvent, root, input, nextDate, trigger, detail) { root = sourceEvent.currentTarget.closest(".wire-next--date-picker"); input = root.querySelector(".wire-next__picker-value"); nextDate = input.getAttribute("value").slice(0, 5) + root.querySelector("select").getAttribute("value") + "-" + sourceEvent.currentTarget.dataset.value; currentValue = nextDate; input.setAttribute("value", nextDate); trigger = root.querySelector(".wire-next__date-trigger span"); if (trigger) { trigger.replaceChildren(nextDate) } sourceEvent.currentTarget.setAttribute("aria-pressed", "true"); detail = { value: nextDate, name: name, sourceEvent: sourceEvent }; output.input(detail); output.change(detail) }
|
||||
client function selectDay(sourceEvent, root, input, nextDate, trigger, detail) { root = sourceEvent.currentTarget.closest(".wrn-next--date-picker"); input = root.querySelector(".wrn-next__picker-value"); nextDate = input.getAttribute("value").slice(0, 5) + root.querySelector("select").getAttribute("value") + "-" + sourceEvent.currentTarget.dataset.value; currentValue = nextDate; input.setAttribute("value", nextDate); trigger = root.querySelector(".wrn-next__date-trigger span"); if (trigger) { trigger.replaceChildren(nextDate) } sourceEvent.currentTarget.setAttribute("aria-pressed", "true"); detail = { value: nextDate, name: name, sourceEvent: sourceEvent }; output.input(detail); output.change(detail) }
|
||||
client function clearDate(sourceEvent, detail) { if (disabled || readonly) { return } currentValue = ""; detail = { value: currentValue, name: name, sourceEvent: sourceEvent }; output.input(detail); output.change(detail) }
|
||||
client function handleFocus(sourceEvent) { output.focus({ value: currentValue, name: name, sourceEvent: sourceEvent }) }
|
||||
client function handleBlur(sourceEvent) { output.blur({ value: currentValue, name: name, sourceEvent: sourceEvent }) }
|
||||
client function handleInvalid(sourceEvent) { output.invalid({ name: name, message: sourceEvent.currentTarget.validationMessage, sourceEvent: sourceEvent }) }
|
||||
}
|
||||
view {
|
||||
<div {...attrs} class="wire-component wire-component--color-{color} wire-component--size-{size} wire-next--field wire-next--date-picker {class}" data-variant="{variant}" data-inline="{inline}" data-invalid="{error ? 'true' : 'false'}" data-expanded="{expanded}">
|
||||
<div class="wire-next__field-heading"><label for="{id || name}">{label}</label>{#if cornerHint}<span class="wire-next__field-hint">{cornerHint}</span>{/if}</div>
|
||||
<div class="wire-next__picker-control"><input id="{id || name}" class="wire-next__sr-only wire-next__picker-value" type="text" name="{name}" value="{currentValue}" required="{required}" readonly aria-hidden="true" tabindex="-1" @invalid="handleInvalid(event)" /><button type="button" class="wire-next__date-trigger" disabled="{disabled || readonly}" aria-haspopup="dialog" aria-expanded="{expanded}" @click="openCalendar(event)" @focus="handleFocus(event)" @blur="handleBlur(event)"><span>{currentValue || placeholder || "Select date"}</span><i class="icon-[lucide--calendar-days]" aria-hidden="true"></i></button>{#if currentValue && !readonly && !disabled}<button type="button" class="wire-next__picker-clear" aria-label="Clear date" @click="clearDate(event)">×</button>{/if}</div>
|
||||
<div class="wire-next__calendar" role="dialog" aria-label="{label}"><div class="wire-next__date-selectors"><label>Month<select value="{selectedMonth}" @change="updateDate('month', event.currentTarget.value, event)">{#each months as month}<option value="{month.value}" selected="{month.value === selectedMonth}">{month.label}</option>{/each}</select></label><label>Year<select value="{selectedYear}" @change="updateDate('year', event.currentTarget.value, event)">{#each years as year}<option value="{year}" selected="{String(year) === selectedYear}">{year}</option>{/each}</select></label></div><div class="wire-next__calendar-grid">{#each days as day}<button type="button" data-value="{String(day).padStart(2, '0')}" aria-pressed="{String(day).padStart(2, '0') === selectedDay}" @click="selectDay(event)">{day}</button>{/each}</div><button type="button" class="wire-next__date-done" disabled="{!currentValue}" @click="finishDate(event)">Done</button></div>
|
||||
{#if helperText}<small class="wire-next__field-help">{helperText}</small>{/if}<small class="wire-next__field-error" data-error="{name}">{error}</small>
|
||||
<div {...attrs} class="wrn-component wrn-component--color-{color} wrn-component--size-{size} wrn-next--field wrn-next--date-picker {class}" data-variant="{variant}" data-inline="{inline}" data-invalid="{error ? 'true' : 'false'}" data-expanded="{expanded}">
|
||||
<div class="wrn-next__field-heading"><label for="{id || name}">{label}</label>{#if cornerHint}<span class="wrn-next__field-hint">{cornerHint}</span>{/if}</div>
|
||||
<div class="wrn-next__picker-control"><input id="{id || name}" class="wrn-next__sr-only wrn-next__picker-value" type="text" name="{name}" value="{currentValue}" required="{required}" readonly aria-hidden="true" tabindex="-1" @invalid="handleInvalid(event)" /><button type="button" class="wrn-next__date-trigger" disabled="{disabled || readonly}" aria-haspopup="dialog" aria-expanded="{expanded}" @click="openCalendar(event)" @focus="handleFocus(event)" @blur="handleBlur(event)"><span>{currentValue || placeholder || "Select date"}</span><i class="icon-[lucide--calendar-days]" aria-hidden="true"></i></button>{#if currentValue && !readonly && !disabled}<button type="button" class="wrn-next__picker-clear" aria-label="Clear date" @click="clearDate(event)">×</button>{/if}</div>
|
||||
<div class="wrn-next__calendar" role="dialog" aria-label="{label}"><div class="wrn-next__date-selectors"><label>Month<select value="{selectedMonth}" @change="updateDate('month', event.currentTarget.value, event)">{#each months as month}<option value="{month.value}" selected="{month.value === selectedMonth}">{month.label}</option>{/each}</select></label><label>Year<select value="{selectedYear}" @change="updateDate('year', event.currentTarget.value, event)">{#each years as year}<option value="{year}" selected="{String(year) === selectedYear}">{year}</option>{/each}</select></label></div><div class="wrn-next__calendar-grid">{#each days as day}<button type="button" data-value="{String(day).padStart(2, '0')}" aria-pressed="{String(day).padStart(2, '0') === selectedDay}" @click="selectDay(event)">{day}</button>{/each}</div><button type="button" class="wrn-next__date-done" disabled="{!currentValue}" @click="finishDate(event)">Done</button></div>
|
||||
{#if helperText}<small class="wrn-next__field-help">{helperText}</small>{/if}<small class="wrn-next__field-error" data-error="{name}">{error}</small>
|
||||
</div>
|
||||
<FieldStyles hidden />
|
||||
<ComponentBaseStyles hidden />
|
||||
}
|
||||
|
||||
style {
|
||||
.wire-next__picker-clear {
|
||||
.wrn-next__picker-clear {
|
||||
position: absolute;
|
||||
right: 2.5rem;
|
||||
border: 0;
|
||||
background: transparent;
|
||||
color: var(--wire-color-muted);
|
||||
color: var(--wrn-color-muted);
|
||||
}
|
||||
|
||||
.wire-next__date-selectors {
|
||||
.wrn-next__date-selectors {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
|
||||
gap: 0.65rem;
|
||||
}
|
||||
|
||||
.wire-next__date-selectors label {
|
||||
.wrn-next__date-selectors label {
|
||||
display: grid;
|
||||
gap: 0.3rem;
|
||||
color: var(--wire-color-muted);
|
||||
color: var(--wrn-color-muted);
|
||||
font-size: 0.78rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.wire-next__date-selectors select {
|
||||
.wrn-next__date-selectors select {
|
||||
width: 100%;
|
||||
min-height: 2.35rem;
|
||||
padding: 0.45rem 0.65rem;
|
||||
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;
|
||||
}
|
||||
|
||||
.wire-next__date-done {
|
||||
background: var(--wire-field-color) !important;
|
||||
color: var(--wire-color-primary-contrast, #fff) !important;
|
||||
.wrn-next__date-done {
|
||||
background: var(--wrn-field-color) !important;
|
||||
color: var(--wrn-color-primary-contrast, #fff) !important;
|
||||
font-weight: 650;
|
||||
}
|
||||
|
||||
.wire-next__calendar > header {
|
||||
.wrn-next__calendar > header {
|
||||
display: grid;
|
||||
grid-template-columns: 2.25rem 1fr 2.25rem;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.wire-next__calendar-grid button[data-outside="true"] {
|
||||
color: var(--wire-color-muted);
|
||||
.wrn-next__calendar-grid button[data-outside="true"] {
|
||||
color: var(--wrn-color-muted);
|
||||
opacity: 0.55;
|
||||
}
|
||||
|
||||
.wire-next__calendar-grid button[data-today="true"] {
|
||||
box-shadow: inset 0 0 0 1px var(--wire-field-color);
|
||||
.wrn-next__calendar-grid button[data-today="true"] {
|
||||
box-shadow: inset 0 0 0 1px var(--wrn-field-color);
|
||||
}
|
||||
|
||||
/* Shared component foundation. */
|
||||
|
||||
.wrn-component {
|
||||
--wrn-component-color: var(--wrn-color-primary);
|
||||
--wrn-component-scale: 1;
|
||||
margin: 0;
|
||||
color: var(--wrn-color-text);
|
||||
font-family: var(--wrn-font-sans, inherit);
|
||||
}
|
||||
|
||||
.wrn-component--color-primary {
|
||||
--wrn-component-color: var(--wrn-color-primary);
|
||||
}
|
||||
|
||||
.wrn-component--color-secondary {
|
||||
--wrn-component-color: var(--wrn-color-secondary);
|
||||
}
|
||||
|
||||
.wrn-component--color-success {
|
||||
--wrn-component-color: var(--wrn-color-success);
|
||||
}
|
||||
|
||||
.wrn-component--color-warning {
|
||||
--wrn-component-color: var(--wrn-color-warning);
|
||||
}
|
||||
|
||||
.wrn-component--color-danger {
|
||||
--wrn-component-color: var(--wrn-color-danger);
|
||||
}
|
||||
|
||||
.wrn-component--color-info {
|
||||
--wrn-component-color: var(--wrn-color-info);
|
||||
}
|
||||
|
||||
.wrn-component--size-xs {
|
||||
--wrn-component-scale: 0.78;
|
||||
}
|
||||
|
||||
.wrn-component--size-sm {
|
||||
--wrn-component-scale: 0.88;
|
||||
}
|
||||
|
||||
.wrn-component--size-default,
|
||||
.wrn-component--size-md {
|
||||
--wrn-component-scale: 1;
|
||||
}
|
||||
|
||||
.wrn-component--size-lg {
|
||||
--wrn-component-scale: 1.14;
|
||||
}
|
||||
|
||||
.wrn-component--size-xl {
|
||||
--wrn-component-scale: 1.28;
|
||||
}
|
||||
|
||||
.wrn-component:not(.wrn-btn) {
|
||||
font-size: calc(1em * var(--wrn-component-scale));
|
||||
}
|
||||
|
||||
.wrn-component :is(a, button, input, select, textarea):focus-visible {
|
||||
outline-color: var(--wrn-component-color);
|
||||
}
|
||||
|
||||
.wrn-component p {
|
||||
margin: 0;
|
||||
color: var(--wrn-color-muted);
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
/* Shared field foundation. */
|
||||
|
||||
/* Validation states set by the browser validation runtime. */
|
||||
.wrn-invalid {
|
||||
border-color: var(--wrn-color-danger) !important;
|
||||
}
|
||||
|
||||
.wrn-field-error {
|
||||
display: block;
|
||||
min-height: 1em;
|
||||
margin-top: 0.25rem;
|
||||
color: var(--wrn-color-danger);
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
.wrn-next--choice {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.55rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.wrn-next--choice input {
|
||||
width: 1.1rem;
|
||||
height: 1.1rem;
|
||||
accent-color: var(--wrn-color-primary);
|
||||
}
|
||||
|
||||
.wrn-next--field {
|
||||
display: grid;
|
||||
width: min(100%, 28rem);
|
||||
gap: 0.4rem;
|
||||
font-size: 0.78rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
.wrn-next--field :where(input, textarea, select) {
|
||||
width: 100%;
|
||||
min-height: 2.65rem;
|
||||
padding: 0.6rem 0.7rem;
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: 0.6rem;
|
||||
outline: 0;
|
||||
color: var(--wrn-color-text);
|
||||
background: var(--wrn-color-bg);
|
||||
font: inherit;
|
||||
font-weight: 500;
|
||||
}
|
||||
.wrn-auth-form form > .wrn-next--field,
|
||||
.wrn-auth-form form > .wrn-field {
|
||||
width: 100%;
|
||||
max-width: none;
|
||||
}
|
||||
.wrn-auth-form__submit > .wrn-btn {
|
||||
width: 100%;
|
||||
min-height: 3rem;
|
||||
border-radius: 0.75rem;
|
||||
box-shadow: 0 0.8rem 1.8rem color-mix(in srgb, var(--wrn-btn-color) 20%, transparent);
|
||||
}
|
||||
.wrn-next--field :where(input, textarea, select):focus-visible {
|
||||
border-color: var(--wrn-color-primary);
|
||||
box-shadow: 0 0 0 3px color-mix(in srgb, var(--wrn-color-primary) 16%, transparent);
|
||||
}
|
||||
.wrn-next--field textarea {
|
||||
resize: vertical;
|
||||
}
|
||||
.wrn-next--field,
|
||||
.wrn-next--choice-field {
|
||||
--wrn-field-color: var(--wrn-component-color, var(--wrn-color-primary));
|
||||
width: min(100%, 34rem);
|
||||
min-width: 0;
|
||||
color: var(--wrn-color-text);
|
||||
font-size: 0.8125rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
.wrn-next--field.wrn-next--size-sm,
|
||||
.wrn-next--choice-field.wrn-next--size-sm {
|
||||
font-size: 0.8125rem;
|
||||
}
|
||||
.wrn-next--field.wrn-next--size-lg,
|
||||
.wrn-next--choice-field.wrn-next--size-lg {
|
||||
font-size: 1rem;
|
||||
}
|
||||
.wrn-next__field-heading {
|
||||
display: flex;
|
||||
min-width: 0;
|
||||
align-items: baseline;
|
||||
justify-content: space-between;
|
||||
gap: 1rem;
|
||||
}
|
||||
.wrn-next__field-heading label {
|
||||
color: var(--wrn-color-text);
|
||||
font-weight: 600;
|
||||
}
|
||||
.wrn-next__field-hint,
|
||||
.wrn-next__field-help {
|
||||
color: var(--wrn-color-muted);
|
||||
font-size: 0.82em;
|
||||
font-weight: 500;
|
||||
}
|
||||
.wrn-next__field-control {
|
||||
position: relative;
|
||||
min-width: 0;
|
||||
}
|
||||
.wrn-next__field-control > :is(input, textarea, select) {
|
||||
padding-inline: 0.85rem;
|
||||
border-color: var(--wrn-color-border);
|
||||
border-radius: var(--wrn-radius-sm);
|
||||
background: var(--wrn-color-surface);
|
||||
font-size: 0.8125rem;
|
||||
}
|
||||
.wrn-next__field-control[data-icon-position="start"] > :is(input, textarea, select) {
|
||||
padding-inline-start: 2.5rem;
|
||||
}
|
||||
.wrn-next__field-control[data-icon-position="end"] > :is(input, textarea, select) {
|
||||
padding-inline-end: 2.5rem;
|
||||
}
|
||||
.wrn-next__field-icon {
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
top: 50%;
|
||||
left: 0.85rem;
|
||||
color: var(--wrn-color-muted);
|
||||
pointer-events: none;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
.wrn-next__field-control[data-icon-position="end"] > .wrn-next__field-icon {
|
||||
right: 0.85rem;
|
||||
left: auto;
|
||||
}
|
||||
.wrn-next--field[data-variant="outlined"]
|
||||
.wrn-next__field-control
|
||||
> :is(input, textarea, select) {
|
||||
border-width: 2px;
|
||||
}
|
||||
.wrn-next--field[data-variant="underline"]
|
||||
.wrn-next__field-control
|
||||
> :is(input, textarea, select) {
|
||||
padding-inline: 0;
|
||||
border-width: 0 0 1px;
|
||||
border-radius: 0;
|
||||
background: transparent;
|
||||
box-shadow: none;
|
||||
}
|
||||
.wrn-next--field[data-variant="pill"] .wrn-next__field-control > :is(input, select) {
|
||||
border-radius: 999px;
|
||||
padding-inline: 1.15rem;
|
||||
}
|
||||
.wrn-next--field[data-variant="ghost"] .wrn-next__field-control > :is(input, textarea, select) {
|
||||
border-color: transparent;
|
||||
background: color-mix(in srgb, var(--wrn-field-color) 8%, var(--wrn-color-surface));
|
||||
}
|
||||
.wrn-next__field-floating-label {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 0.85rem;
|
||||
color: var(--wrn-color-muted);
|
||||
pointer-events: none;
|
||||
transform: translateY(-50%);
|
||||
transition: 150ms ease;
|
||||
}
|
||||
.wrn-next--textarea .wrn-next__field-floating-label {
|
||||
top: 1.35rem;
|
||||
}
|
||||
.wrn-next--field[data-floating="true"] .wrn-next__field-control > :is(input, textarea, select) {
|
||||
padding-top: 1.2rem;
|
||||
padding-bottom: 0.3rem;
|
||||
}
|
||||
.wrn-next--field[data-floating="true"] .wrn-next__field-heading > label {
|
||||
position: absolute !important;
|
||||
width: 1px !important;
|
||||
height: 1px !important;
|
||||
overflow: hidden !important;
|
||||
margin: -1px !important;
|
||||
clip: rect(0, 0, 0, 0) !important;
|
||||
white-space: nowrap !important;
|
||||
}
|
||||
.wrn-next--field[data-floating="true"]
|
||||
.wrn-next__field-heading:not(:has(.wrn-next__field-hint)) {
|
||||
display: none;
|
||||
}
|
||||
.wrn-next--field[data-floating="true"]
|
||||
.wrn-next__field-control
|
||||
> :is(input, textarea):is(:focus, :not(:placeholder-shown))
|
||||
+ .wrn-next__field-floating-label {
|
||||
top: 0.42rem;
|
||||
font-size: 0.7em;
|
||||
transform: none;
|
||||
}
|
||||
.wrn-next__field-error {
|
||||
min-height: 1em;
|
||||
color: var(--wrn-color-danger);
|
||||
font-size: 0.82em;
|
||||
font-weight: 600;
|
||||
}
|
||||
.wrn-next__field-error:empty {
|
||||
display: none;
|
||||
}
|
||||
.wrn-next--field[data-invalid="true"] :is(input, textarea, select),
|
||||
.wrn-next--choice-field[data-invalid="true"] input {
|
||||
border-color: var(--wrn-color-danger);
|
||||
}
|
||||
.wrn-next--field :is(input, textarea, select):disabled,
|
||||
.wrn-next--choice-field input:disabled {
|
||||
cursor: not-allowed;
|
||||
opacity: 0.58;
|
||||
}
|
||||
.wrn-next--field :is(input, textarea, select):read-only {
|
||||
background: var(--wrn-color-surface-2);
|
||||
}
|
||||
.wrn-next--field[data-inline="true"],
|
||||
.wrn-next--choice-field[data-inline="true"] {
|
||||
display: grid;
|
||||
width: 100%;
|
||||
max-width: none;
|
||||
grid-template-columns: minmax(7rem, max-content) minmax(12rem, 20rem) minmax(10rem, 1fr);
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
.wrn-next--field[data-inline="true"] .wrn-next__field-heading,
|
||||
.wrn-next--choice-field[data-inline="true"] .wrn-next__field-heading {
|
||||
min-height: 2.65rem;
|
||||
align-items: center;
|
||||
}
|
||||
.wrn-next--field[data-inline="true"] .wrn-next__field-heading {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
.wrn-next--field[data-inline="true"] .wrn-next__field-help,
|
||||
.wrn-next--choice-field[data-inline="true"] .wrn-next__field-help {
|
||||
display: flex;
|
||||
min-height: 2.65rem;
|
||||
align-items: center;
|
||||
}
|
||||
.wrn-next--choice-field[data-inline="true"] {
|
||||
grid-template-columns: minmax(12rem, 20rem) minmax(10rem, 1fr);
|
||||
}
|
||||
.wrn-next--choice-field[data-inline="true"] .wrn-next__field-heading:empty {
|
||||
display: none;
|
||||
}
|
||||
.wrn-next--field[data-inline="true"] .wrn-next__field-error,
|
||||
.wrn-next--choice-field[data-inline="true"] .wrn-next__field-error {
|
||||
grid-column: 2 / -1;
|
||||
}
|
||||
.wrn-next__sr-only {
|
||||
position: absolute !important;
|
||||
width: 1px !important;
|
||||
height: 1px !important;
|
||||
overflow: hidden !important;
|
||||
padding: 0 !important;
|
||||
border: 0 !important;
|
||||
margin: -1px !important;
|
||||
clip: rect(0, 0, 0, 0) !important;
|
||||
white-space: nowrap !important;
|
||||
}
|
||||
.wrn-next__choice-field {
|
||||
display: grid;
|
||||
width: 100%;
|
||||
max-width: none;
|
||||
gap: 0.4rem;
|
||||
}
|
||||
.wrn-next__choice {
|
||||
display: flex;
|
||||
min-width: 0;
|
||||
align-items: center;
|
||||
gap: 0.65rem;
|
||||
color: var(--wrn-color-text);
|
||||
width: 100%;
|
||||
font-size: 0.75rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
.wrn-next__checkbox-content > .wrn-next__choice {
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
align-items: flex-start;
|
||||
}
|
||||
.wrn-next__choice input {
|
||||
flex: 0 0 auto;
|
||||
margin: 0;
|
||||
accent-color: var(--wrn-field-color);
|
||||
}
|
||||
.wrn-next__choice-copy {
|
||||
display: grid;
|
||||
min-width: 0;
|
||||
gap: 0.15rem;
|
||||
line-height: 1.35;
|
||||
}
|
||||
.wrn-next__choice-copy small {
|
||||
color: var(--wrn-color-muted);
|
||||
font-weight: 500;
|
||||
}
|
||||
.wrn-next__radio-group,
|
||||
.wrn-next__checkbox-group {
|
||||
display: grid;
|
||||
min-width: 0;
|
||||
gap: 0.65rem;
|
||||
}
|
||||
.wrn-next--radio-field[data-orientation="horizontal"] .wrn-next__radio-group,
|
||||
.wrn-next--checkbox-field[data-orientation="horizontal"] .wrn-next__checkbox-group {
|
||||
grid-template-columns: repeat(auto-fit, minmax(8rem, max-content));
|
||||
align-items: stretch;
|
||||
}
|
||||
.wrn-next--radio-field[data-card="true"] .wrn-next__radio-group,
|
||||
.wrn-next--checkbox-field[data-card="true"] .wrn-next__checkbox-group {
|
||||
grid-template-columns: repeat(auto-fit, minmax(min(100%, 12rem), 1fr));
|
||||
}
|
||||
.wrn-next--radio-field[data-card="true"] .wrn-next--radio,
|
||||
.wrn-next--checkbox-field[data-card="true"] .wrn-next--checkbox {
|
||||
min-height: 4.5rem;
|
||||
padding: 0.85rem;
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: var(--wrn-radius-sm);
|
||||
background: var(--wrn-color-surface);
|
||||
}
|
||||
.wrn-next--radio-field[data-card="true"] .wrn-next--radio:has(input:checked),
|
||||
.wrn-next--checkbox-field[data-card="true"] .wrn-next--checkbox:has(input:checked) {
|
||||
border-color: var(--wrn-field-color);
|
||||
box-shadow: 0 0 0 1px var(--wrn-field-color);
|
||||
}
|
||||
.wrn-next--radio-field[data-list="true"] .wrn-next--radio,
|
||||
.wrn-next--checkbox-field[data-list="true"] .wrn-next--checkbox {
|
||||
padding-block: 0.75rem;
|
||||
border-bottom: 1px solid var(--wrn-color-border);
|
||||
}
|
||||
.wrn-next--radio-field[data-right-aligned="true"] .wrn-next--radio,
|
||||
.wrn-next--checkbox-field[data-right-aligned="true"] .wrn-next--checkbox {
|
||||
justify-content: space-between;
|
||||
}
|
||||
.wrn-next--radio-field[data-right-aligned="true"] .wrn-next--radio input,
|
||||
.wrn-next--checkbox-field[data-right-aligned="true"] .wrn-next--checkbox input {
|
||||
order: 2;
|
||||
}
|
||||
.wrn-next--radio-field[data-right-aligned="true"] .wrn-next__choice-copy,
|
||||
.wrn-next--checkbox-field[data-right-aligned="true"] .wrn-next__choice-copy {
|
||||
order: 1;
|
||||
}
|
||||
.wrn-next__choice[data-variant="outlined"],
|
||||
.wrn-next__choice[data-variant="floating"] {
|
||||
padding: 0.65rem 0.8rem;
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: var(--wrn-radius-sm);
|
||||
}
|
||||
.wrn-next__choice[data-variant="pill"] {
|
||||
padding: 0.65rem 1rem;
|
||||
border-radius: 999px;
|
||||
background: color-mix(in srgb, var(--wrn-field-color) 9%, var(--wrn-color-surface));
|
||||
}
|
||||
.wrn-next__choice[data-variant="ghost"] {
|
||||
padding: 0.65rem 0.8rem;
|
||||
border-radius: var(--wrn-radius-sm);
|
||||
background: color-mix(in srgb, var(--wrn-field-color) 7%, transparent);
|
||||
}
|
||||
.wrn-next__choice[data-variant="underline"] {
|
||||
padding-block: 0.5rem;
|
||||
border-bottom: 1px solid var(--wrn-color-border);
|
||||
}
|
||||
.wrn-next--select .wrn-next__field-control {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.wrn-next__color-control,
|
||||
.wrn-next__range-control,
|
||||
.wrn-next__input-group-control,
|
||||
.wrn-next__file-control {
|
||||
display: flex;
|
||||
min-width: 0;
|
||||
align-items: center;
|
||||
gap: 0.65rem;
|
||||
}
|
||||
.wrn-next__picker-control,
|
||||
.wrn-next--time-picker .wrn-next__field-control {
|
||||
position: relative;
|
||||
display: flex;
|
||||
min-width: 0;
|
||||
align-items: center;
|
||||
}
|
||||
.wrn-next__picker-control > button:first-of-type,
|
||||
.wrn-next__time-trigger {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
min-height: 2.65rem;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 0.75rem;
|
||||
padding: 0.7rem 0.85rem;
|
||||
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;
|
||||
text-align: left;
|
||||
}
|
||||
.wrn-next__calendar,
|
||||
.wrn-next__time-panel {
|
||||
z-index: 20;
|
||||
display: grid;
|
||||
width: min(100%, 22rem);
|
||||
gap: 0.75rem;
|
||||
padding: 0.85rem;
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: var(--wrn-radius-md);
|
||||
background: var(--wrn-color-surface);
|
||||
box-shadow: var(--wrn-shadow-3);
|
||||
}
|
||||
.wrn-next--date-picker[data-expanded="false"] .wrn-next__calendar,
|
||||
.wrn-next--time-picker[data-expanded="false"] .wrn-next__time-panel {
|
||||
display: none;
|
||||
}
|
||||
.wrn-next__calendar button,
|
||||
.wrn-next__time-panel button {
|
||||
min-height: 2.25rem;
|
||||
border: 0;
|
||||
border-radius: var(--wrn-radius-sm);
|
||||
background: transparent;
|
||||
color: inherit;
|
||||
}
|
||||
.wrn-next__calendar-weekdays,
|
||||
.wrn-next__calendar-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(7, 1fr);
|
||||
gap: 0.2rem;
|
||||
text-align: center;
|
||||
}
|
||||
.wrn-next__calendar-weekdays {
|
||||
color: var(--wrn-color-muted);
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
.wrn-next__calendar-grid button:hover,
|
||||
.wrn-next__time-panel button:hover {
|
||||
background: var(--wrn-color-surface-2);
|
||||
}
|
||||
.wrn-next__calendar-grid button[aria-pressed="true"],
|
||||
.wrn-next__time-panel button[aria-pressed="true"] {
|
||||
background: var(--wrn-field-color);
|
||||
color: var(--wrn-color-primary-contrast, #fff);
|
||||
}
|
||||
.wrn-next__time-period {
|
||||
display: flex;
|
||||
gap: 0.35rem;
|
||||
}
|
||||
.wrn-next--file-upload-progress .wrn-next__row,
|
||||
.wrn-next__upload-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
.wrn-next--file-upload-progress .wrn-next__row > span {
|
||||
display: grid;
|
||||
min-width: 0;
|
||||
}
|
||||
.wrn-next--field[data-variant="underline"]
|
||||
:is(.wrn-next__input-group-control, .wrn-next__file-control, .wrn-next__color-control) {
|
||||
border-width: 0 0 1px;
|
||||
border-radius: 0;
|
||||
background: transparent;
|
||||
}
|
||||
.wrn-next--field[data-variant="outlined"]
|
||||
:is(.wrn-next__input-group-control, .wrn-next__file-control) {
|
||||
border-width: 2px;
|
||||
}
|
||||
.wrn-next--field[data-variant="pill"]
|
||||
:is(.wrn-next__input-group-control, .wrn-next__file-control) {
|
||||
border-radius: 999px;
|
||||
}
|
||||
.wrn-next--field[data-variant="ghost"]
|
||||
:is(.wrn-next__input-group-control, .wrn-next__file-control, .wrn-next__color-control) {
|
||||
border-color: transparent;
|
||||
background: color-mix(in srgb, var(--wrn-field-color) 8%, var(--wrn-color-surface));
|
||||
}
|
||||
@media (max-width: 640px) {
|
||||
.wrn-next--field[data-inline="true"],
|
||||
.wrn-next--choice-field[data-inline="true"] {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.wrn-next--field[data-inline="true"] .wrn-next__field-error,
|
||||
.wrn-next--choice-field[data-inline="true"] .wrn-next__field-error {
|
||||
grid-column: auto;
|
||||
}
|
||||
}
|
||||
.wrn-next--toggle-password:has(input.wrn-invalid) .wrn-next__password-control > input,
|
||||
.wrn-next--toggle-password.wrn-next--invalid .wrn-next__password-control > input {
|
||||
border-color: var(--wrn-color-danger);
|
||||
box-shadow: 0 0 0 3px color-mix(in srgb, var(--wrn-color-danger) 14%, transparent);
|
||||
}
|
||||
.wrn-next--strong-password.wrn-next--invalid input,
|
||||
.wrn-next--strong-password input.wrn-invalid {
|
||||
border-color: var(--wrn-color-danger);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import ComponentBaseStyles from "../styles/ComponentBaseStyles.wrn"
|
||||
|
||||
component DeviceFrame {
|
||||
outputs {
|
||||
change(payload: { device: string; orientation: string; sourceEvent: Event })
|
||||
@@ -28,83 +26,151 @@ component DeviceFrame {
|
||||
client function rotateFrame(sourceEvent) { currentOrientation = currentOrientation === "portrait" ? "landscape" : "portrait"; output.rotate({ device: device, orientation: currentOrientation, sourceEvent: sourceEvent }); output.change({ device: device, orientation: currentOrientation, sourceEvent: sourceEvent }) }
|
||||
}
|
||||
view {
|
||||
<section {...attrs} class="wire-component wire-component--color-{color} wire-component--size-{size} wire-next--device-frame wire-next--variant-{variant} {class}" data-device="{device}" data-orientation="{currentOrientation}">
|
||||
<header><div>{#if title}<strong>{title}</strong>{/if}{#if description}<p>{description}</p>{/if}</div>{#if showToolbar}<div class="wire-next__device-actions" role="toolbar" aria-label="Preview device">{#each items as item}<button type="button" aria-pressed="{item.value === device}" @click="setDevice(item.value, event)">{item.label}</button>{/each}<button type="button" aria-label="Rotate preview" @click="rotateFrame(event)">↻</button></div>{/if}</header>
|
||||
<div class="wire-next__device-shell">{#if src || srcdoc}<iframe title="{frameTitle}" src="{src}" srcdoc="{srcdoc}" allow="{allow}"></iframe>{:else}<div class="wire-next__device-content"><slot /></div>{/if}</div>
|
||||
<section {...attrs} class="wrn-component wrn-component--color-{color} wrn-component--size-{size} wrn-next--device-frame wrn-next--variant-{variant} {class}" data-device="{device}" data-orientation="{currentOrientation}">
|
||||
<header><div>{#if title}<strong>{title}</strong>{/if}{#if description}<p>{description}</p>{/if}</div>{#if showToolbar}<div class="wrn-next__device-actions" role="toolbar" aria-label="Preview device">{#each items as item}<button type="button" aria-pressed="{item.value === device}" @click="setDevice(item.value, event)">{item.label}</button>{/each}<button type="button" aria-label="Rotate preview" @click="rotateFrame(event)">↻</button></div>{/if}</header>
|
||||
<div class="wrn-next__device-shell">{#if src || srcdoc}<iframe title="{frameTitle}" src="{src}" srcdoc="{srcdoc}" allow="{allow}"></iframe>{:else}<div class="wrn-next__device-content"><slot /></div>{/if}</div>
|
||||
</section>
|
||||
<ComponentBaseStyles hidden />
|
||||
}
|
||||
|
||||
style {
|
||||
.wire-next--device-frame {
|
||||
.wrn-next--device-frame {
|
||||
display: grid;
|
||||
gap: 0.75rem;
|
||||
padding: 1rem;
|
||||
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);
|
||||
}
|
||||
|
||||
.wire-next--device-frame > header {
|
||||
.wrn-next--device-frame > header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.wire-next__device-actions {
|
||||
.wrn-next__device-actions {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.4rem;
|
||||
}
|
||||
|
||||
.wire-next__device-actions button {
|
||||
.wrn-next__device-actions button {
|
||||
min-height: 2.25rem;
|
||||
padding-inline: 0.7rem;
|
||||
border: 1px solid var(--wire-color-border);
|
||||
border-radius: var(--wire-radius-sm);
|
||||
background: var(--wire-color-surface-2);
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: var(--wrn-radius-sm);
|
||||
background: var(--wrn-color-surface-2);
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.wire-next__device-shell {
|
||||
.wrn-next__device-shell {
|
||||
overflow: hidden;
|
||||
width: min(100%, 24rem);
|
||||
min-height: 28rem;
|
||||
margin-inline: auto;
|
||||
border: 0.65rem solid var(--wire-color-text);
|
||||
border: 0.65rem solid var(--wrn-color-text);
|
||||
border-radius: 2rem;
|
||||
background: var(--wire-color-background);
|
||||
transition: width var(--wire-motion-normal) var(--wire-ease-standard);
|
||||
background: var(--wrn-color-background);
|
||||
transition: width var(--wrn-motion-normal) var(--wrn-ease-standard);
|
||||
}
|
||||
|
||||
.wire-next--device-frame[data-device="tablet"] .wire-next__device-shell {
|
||||
.wrn-next--device-frame[data-device="tablet"] .wrn-next__device-shell {
|
||||
width: min(100%, 42rem);
|
||||
}
|
||||
|
||||
.wire-next--device-frame[data-device="desktop"] .wire-next__device-shell {
|
||||
.wrn-next--device-frame[data-device="desktop"] .wrn-next__device-shell {
|
||||
width: 100%;
|
||||
border-width: 0.4rem;
|
||||
border-radius: var(--wire-radius-md);
|
||||
border-radius: var(--wrn-radius-md);
|
||||
}
|
||||
|
||||
.wire-next--device-frame[data-orientation="landscape"] .wire-next__device-shell {
|
||||
.wrn-next--device-frame[data-orientation="landscape"] .wrn-next__device-shell {
|
||||
width: min(100%, 48rem);
|
||||
min-height: 20rem;
|
||||
}
|
||||
|
||||
.wire-next__device-shell :is(iframe, .wire-next__device-content) {
|
||||
.wrn-next__device-shell :is(iframe, .wrn-next__device-content) {
|
||||
width: 100%;
|
||||
min-height: inherit;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.wire-next--device-frame > header {
|
||||
.wrn-next--device-frame > header {
|
||||
align-items: stretch;
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
|
||||
/* Shared component foundation. */
|
||||
|
||||
.wrn-component {
|
||||
--wrn-component-color: var(--wrn-color-primary);
|
||||
--wrn-component-scale: 1;
|
||||
margin: 0;
|
||||
color: var(--wrn-color-text);
|
||||
font-family: var(--wrn-font-sans, inherit);
|
||||
}
|
||||
|
||||
.wrn-component--color-primary {
|
||||
--wrn-component-color: var(--wrn-color-primary);
|
||||
}
|
||||
|
||||
.wrn-component--color-secondary {
|
||||
--wrn-component-color: var(--wrn-color-secondary);
|
||||
}
|
||||
|
||||
.wrn-component--color-success {
|
||||
--wrn-component-color: var(--wrn-color-success);
|
||||
}
|
||||
|
||||
.wrn-component--color-warning {
|
||||
--wrn-component-color: var(--wrn-color-warning);
|
||||
}
|
||||
|
||||
.wrn-component--color-danger {
|
||||
--wrn-component-color: var(--wrn-color-danger);
|
||||
}
|
||||
|
||||
.wrn-component--color-info {
|
||||
--wrn-component-color: var(--wrn-color-info);
|
||||
}
|
||||
|
||||
.wrn-component--size-xs {
|
||||
--wrn-component-scale: 0.78;
|
||||
}
|
||||
|
||||
.wrn-component--size-sm {
|
||||
--wrn-component-scale: 0.88;
|
||||
}
|
||||
|
||||
.wrn-component--size-default,
|
||||
.wrn-component--size-md {
|
||||
--wrn-component-scale: 1;
|
||||
}
|
||||
|
||||
.wrn-component--size-lg {
|
||||
--wrn-component-scale: 1.14;
|
||||
}
|
||||
|
||||
.wrn-component--size-xl {
|
||||
--wrn-component-scale: 1.28;
|
||||
}
|
||||
|
||||
.wrn-component:not(.wrn-btn) {
|
||||
font-size: calc(1em * var(--wrn-component-scale));
|
||||
}
|
||||
|
||||
.wrn-component :is(a, button, input, select, textarea):focus-visible {
|
||||
outline-color: var(--wrn-component-color);
|
||||
}
|
||||
|
||||
.wrn-component p {
|
||||
margin: 0;
|
||||
color: var(--wrn-color-muted);
|
||||
line-height: 1.6;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import ComponentBaseStyles from "../styles/ComponentBaseStyles.wrn"
|
||||
|
||||
component DragAndDrop {
|
||||
outputs {
|
||||
dragStart(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||
@@ -20,27 +18,95 @@ component DragAndDrop {
|
||||
class: string = ""
|
||||
}
|
||||
view {
|
||||
<section class="wire-component wire-component--color-{color} wire-component--size-{size} wire-next--drag-and-drop wire-next--variant-{variant} {class}">
|
||||
<section class="wrn-component wrn-component--color-{color} wrn-component--size-{size} wrn-next--drag-and-drop wrn-next--variant-{variant} {class}">
|
||||
{#if title}<strong>{title}</strong>{/if}
|
||||
{#if description}<p>{description}</p>{/if}
|
||||
{#if items}<div class="wire-next__items">{#each items as item}<span>{item.label}</span>{/each}</div>{/if}
|
||||
{#if items}<div class="wrn-next__items">{#each items as item}<span>{item.label}</span>{/each}</div>{/if}
|
||||
<slot />
|
||||
</section>
|
||||
<ComponentBaseStyles hidden />
|
||||
}
|
||||
|
||||
style {
|
||||
.wire-next--drag-and-drop {
|
||||
.wrn-next--drag-and-drop {
|
||||
display: grid;
|
||||
gap: 0.75rem;
|
||||
padding: 1rem;
|
||||
border: 1px solid var(--wire-color-border);
|
||||
border-radius: var(--wire-radius);
|
||||
color: var(--wire-color-text);
|
||||
background: var(--wire-color-surface);
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: var(--wrn-radius);
|
||||
color: var(--wrn-color-text);
|
||||
background: var(--wrn-color-surface);
|
||||
}
|
||||
.wire-next--drag-and-drop > p { margin: 0; color: var(--wire-color-muted); }
|
||||
.wire-next--drag-and-drop > .wire-next__items { display: flex; flex-wrap: wrap; gap: 0.5rem; }
|
||||
.wire-next--drag-and-drop > .wire-next__items > span { padding: 0.35rem 0.6rem; border-radius: var(--wire-radius-sm); background: var(--wire-color-surface-2); }
|
||||
.wrn-next--drag-and-drop > p { margin: 0; color: var(--wrn-color-muted); }
|
||||
.wrn-next--drag-and-drop > .wrn-next__items { display: flex; flex-wrap: wrap; gap: 0.5rem; }
|
||||
.wrn-next--drag-and-drop > .wrn-next__items > span { padding: 0.35rem 0.6rem; border-radius: var(--wrn-radius-sm); background: var(--wrn-color-surface-2); }
|
||||
|
||||
/* Shared component foundation. */
|
||||
|
||||
.wrn-component {
|
||||
--wrn-component-color: var(--wrn-color-primary);
|
||||
--wrn-component-scale: 1;
|
||||
margin: 0;
|
||||
color: var(--wrn-color-text);
|
||||
font-family: var(--wrn-font-sans, inherit);
|
||||
}
|
||||
|
||||
.wrn-component--color-primary {
|
||||
--wrn-component-color: var(--wrn-color-primary);
|
||||
}
|
||||
|
||||
.wrn-component--color-secondary {
|
||||
--wrn-component-color: var(--wrn-color-secondary);
|
||||
}
|
||||
|
||||
.wrn-component--color-success {
|
||||
--wrn-component-color: var(--wrn-color-success);
|
||||
}
|
||||
|
||||
.wrn-component--color-warning {
|
||||
--wrn-component-color: var(--wrn-color-warning);
|
||||
}
|
||||
|
||||
.wrn-component--color-danger {
|
||||
--wrn-component-color: var(--wrn-color-danger);
|
||||
}
|
||||
|
||||
.wrn-component--color-info {
|
||||
--wrn-component-color: var(--wrn-color-info);
|
||||
}
|
||||
|
||||
.wrn-component--size-xs {
|
||||
--wrn-component-scale: 0.78;
|
||||
}
|
||||
|
||||
.wrn-component--size-sm {
|
||||
--wrn-component-scale: 0.88;
|
||||
}
|
||||
|
||||
.wrn-component--size-default,
|
||||
.wrn-component--size-md {
|
||||
--wrn-component-scale: 1;
|
||||
}
|
||||
|
||||
.wrn-component--size-lg {
|
||||
--wrn-component-scale: 1.14;
|
||||
}
|
||||
|
||||
.wrn-component--size-xl {
|
||||
--wrn-component-scale: 1.28;
|
||||
}
|
||||
|
||||
.wrn-component:not(.wrn-btn) {
|
||||
font-size: calc(1em * var(--wrn-component-scale));
|
||||
}
|
||||
|
||||
.wrn-component :is(a, button, input, select, textarea):focus-visible {
|
||||
outline-color: var(--wrn-component-color);
|
||||
}
|
||||
|
||||
.wrn-component p {
|
||||
margin: 0;
|
||||
color: var(--wrn-color-muted);
|
||||
line-height: 1.6;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+107
-107
@@ -80,14 +80,14 @@ open: boolean = false
|
||||
data-variant='{variant}'
|
||||
data-overlay='{overlay ? "true" : "false"}'
|
||||
data-scrollable='{scrollable ? "true" : "false"}'
|
||||
class='wire-drawer {class}'
|
||||
class='wrn-drawer {class}'
|
||||
style='--drawer-duration: {duration}ms'
|
||||
>
|
||||
|
||||
{#if triggerLabel}
|
||||
<button
|
||||
type="button"
|
||||
class="wire-drawer__trigger"
|
||||
class="wrn-drawer__trigger"
|
||||
aria-haspopup="dialog"
|
||||
aria-expanded='{open || visible ? "true" : "false"}'
|
||||
@click='showDrawer(event)'
|
||||
@@ -99,40 +99,40 @@ open: boolean = false
|
||||
</button>
|
||||
{/if}
|
||||
|
||||
<span class="wire-drawer__trigger-slot" @click='showDrawer(event)'>
|
||||
<span class="wrn-drawer__trigger-slot" @click='showDrawer(event)'>
|
||||
<slot name="trigger"></slot>
|
||||
</span>
|
||||
|
||||
<div
|
||||
class="wire-drawer__layer"
|
||||
class="wrn-drawer__layer"
|
||||
role="presentation"
|
||||
@keydown='handleKeydown(event)'
|
||||
>
|
||||
{#if overlay}
|
||||
<button
|
||||
type="button"
|
||||
class="wire-drawer__backdrop"
|
||||
class="wrn-drawer__backdrop"
|
||||
aria-label='{closeLabel}'
|
||||
@click='if (closeOnBackdrop) { cancelDrawer(event) }'
|
||||
></button>
|
||||
{/if}
|
||||
|
||||
<section
|
||||
class="wire-drawer__panel"
|
||||
class="wrn-drawer__panel"
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
aria-label='{label || title}'
|
||||
tabindex="-1"
|
||||
>
|
||||
<div class="wire-drawer__handle" aria-hidden="true"></div>
|
||||
<div class="wrn-drawer__handle" aria-hidden="true"></div>
|
||||
|
||||
<header class="wire-drawer__header">
|
||||
<div class="wire-drawer__heading">
|
||||
<header class="wrn-drawer__header">
|
||||
<div class="wrn-drawer__heading">
|
||||
{#if icon}
|
||||
<span class='wire-drawer__icon {icon}' aria-hidden="true"></span>
|
||||
<span class='wrn-drawer__icon {icon}' aria-hidden="true"></span>
|
||||
{/if}
|
||||
|
||||
<div class="wire-drawer__heading-copy">
|
||||
<div class="wrn-drawer__heading-copy">
|
||||
<slot name="header"></slot>
|
||||
{#if title}
|
||||
<h2>{title}</h2>
|
||||
@@ -146,7 +146,7 @@ open: boolean = false
|
||||
{#if showClose}
|
||||
<button
|
||||
type="button"
|
||||
class="wire-drawer__close"
|
||||
class="wrn-drawer__close"
|
||||
aria-label='{closeLabel}'
|
||||
@click='hideDrawer("close-button", event)'
|
||||
>
|
||||
@@ -155,11 +155,11 @@ open: boolean = false
|
||||
{/if}
|
||||
</header>
|
||||
|
||||
<div class="wire-drawer__body">
|
||||
<div class="wrn-drawer__body">
|
||||
<slot></slot>
|
||||
</div>
|
||||
|
||||
<footer class="wire-drawer__footer">
|
||||
<footer class="wrn-drawer__footer">
|
||||
<slot name="footer"></slot>
|
||||
</footer>
|
||||
</section>
|
||||
@@ -168,50 +168,50 @@ open: boolean = false
|
||||
}
|
||||
|
||||
style {
|
||||
.wire-drawer {
|
||||
--drawer-accent: var(--wire-color-primary);
|
||||
--drawer-soft: var(--wire-color-primary-soft);
|
||||
.wrn-drawer {
|
||||
--drawer-accent: var(--wrn-color-primary);
|
||||
--drawer-soft: var(--wrn-color-primary-soft);
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
.wire-drawer[data-color="secondary"] {
|
||||
--drawer-accent: var(--wire-color-secondary);
|
||||
--drawer-soft: var(--wire-color-secondary-soft);
|
||||
.wrn-drawer[data-color="secondary"] {
|
||||
--drawer-accent: var(--wrn-color-secondary);
|
||||
--drawer-soft: var(--wrn-color-secondary-soft);
|
||||
}
|
||||
|
||||
.wire-drawer[data-color="info"] {
|
||||
--drawer-accent: var(--wire-color-info);
|
||||
--drawer-soft: var(--wire-color-info-soft);
|
||||
.wrn-drawer[data-color="info"] {
|
||||
--drawer-accent: var(--wrn-color-info);
|
||||
--drawer-soft: var(--wrn-color-info-soft);
|
||||
}
|
||||
|
||||
.wire-drawer[data-color="success"] {
|
||||
--drawer-accent: var(--wire-color-success);
|
||||
--drawer-soft: var(--wire-color-success-soft);
|
||||
.wrn-drawer[data-color="success"] {
|
||||
--drawer-accent: var(--wrn-color-success);
|
||||
--drawer-soft: var(--wrn-color-success-soft);
|
||||
}
|
||||
|
||||
.wire-drawer[data-color="warning"] {
|
||||
--drawer-accent: var(--wire-color-warning);
|
||||
--drawer-soft: var(--wire-color-warning-soft);
|
||||
.wrn-drawer[data-color="warning"] {
|
||||
--drawer-accent: var(--wrn-color-warning);
|
||||
--drawer-soft: var(--wrn-color-warning-soft);
|
||||
}
|
||||
|
||||
.wire-drawer[data-color="danger"] {
|
||||
--drawer-accent: var(--wire-color-danger);
|
||||
--drawer-soft: var(--wire-color-danger-soft);
|
||||
.wrn-drawer[data-color="danger"] {
|
||||
--drawer-accent: var(--wrn-color-danger);
|
||||
--drawer-soft: var(--wrn-color-danger-soft);
|
||||
}
|
||||
|
||||
.wire-drawer__trigger,
|
||||
.wire-drawer__trigger-slot {
|
||||
.wrn-drawer__trigger,
|
||||
.wrn-drawer__trigger-slot {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.55rem;
|
||||
}
|
||||
|
||||
.wire-drawer__trigger {
|
||||
.wrn-drawer__trigger {
|
||||
appearance: none;
|
||||
min-height: 2.55rem;
|
||||
padding: 0.65rem 1rem;
|
||||
color: var(--wire-color-primary-contrast);
|
||||
color: var(--wrn-color-primary-contrast);
|
||||
background: var(--drawer-accent);
|
||||
border: 0;
|
||||
border-radius: 0.8rem;
|
||||
@@ -228,7 +228,7 @@ open: boolean = false
|
||||
* delayed by the duration on the way out so the panel can finish sliding
|
||||
* before the layer is taken out of the hit-testing tree.
|
||||
*/
|
||||
.wire-drawer__layer {
|
||||
.wrn-drawer__layer {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
z-index: 1200;
|
||||
@@ -241,7 +241,7 @@ open: boolean = false
|
||||
visibility 0s linear var(--drawer-duration, 260ms);
|
||||
}
|
||||
|
||||
.wire-drawer[data-open="true"] .wire-drawer__layer {
|
||||
.wrn-drawer[data-open="true"] .wrn-drawer__layer {
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
transition:
|
||||
@@ -249,7 +249,7 @@ open: boolean = false
|
||||
visibility 0s linear 0s;
|
||||
}
|
||||
|
||||
.wire-drawer__backdrop {
|
||||
.wrn-drawer__backdrop {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
z-index: 0;
|
||||
@@ -261,11 +261,11 @@ open: boolean = false
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.wire-drawer[data-overlay="false"] .wire-drawer__backdrop {
|
||||
.wrn-drawer[data-overlay="false"] .wrn-drawer__backdrop {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.wire-drawer__panel {
|
||||
.wrn-drawer__panel {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
display: flex;
|
||||
@@ -273,15 +273,15 @@ open: boolean = false
|
||||
width: min(28rem, calc(100vw - 1rem));
|
||||
max-height: 100%;
|
||||
margin-left: auto;
|
||||
color: var(--wire-color-text);
|
||||
color: var(--wrn-color-text);
|
||||
background:
|
||||
radial-gradient(
|
||||
circle at 100% 0%,
|
||||
color-mix(in srgb, var(--drawer-accent) 8%, transparent),
|
||||
transparent 34%
|
||||
),
|
||||
var(--wire-color-surface-raised);
|
||||
border-left: 1px solid color-mix(in srgb, var(--drawer-accent) 18%, var(--wire-color-border));
|
||||
var(--wrn-color-surface-raised);
|
||||
border-left: 1px solid color-mix(in srgb, var(--drawer-accent) 18%, var(--wrn-color-border));
|
||||
box-shadow: -28px 0 80px color-mix(in srgb, black 28%, transparent);
|
||||
pointer-events: auto;
|
||||
overflow: hidden;
|
||||
@@ -290,66 +290,66 @@ open: boolean = false
|
||||
transition: transform var(--drawer-duration, 260ms) cubic-bezier(0.32, 0.72, 0, 1);
|
||||
}
|
||||
|
||||
.wire-drawer[data-open="true"] .wire-drawer__panel {
|
||||
.wrn-drawer[data-open="true"] .wrn-drawer__panel {
|
||||
transform: none;
|
||||
}
|
||||
|
||||
.wire-drawer[data-placement="left"] .wire-drawer__panel {
|
||||
.wrn-drawer[data-placement="left"] .wrn-drawer__panel {
|
||||
transform: translateX(-100%);
|
||||
}
|
||||
|
||||
.wire-drawer[data-placement="top"] .wire-drawer__panel {
|
||||
.wrn-drawer[data-placement="top"] .wrn-drawer__panel {
|
||||
transform: translateY(-100%);
|
||||
}
|
||||
|
||||
.wire-drawer[data-placement="bottom"] .wire-drawer__panel {
|
||||
.wrn-drawer[data-placement="bottom"] .wrn-drawer__panel {
|
||||
transform: translateY(100%);
|
||||
}
|
||||
|
||||
.wire-drawer[data-open="true"][data-placement="left"] .wire-drawer__panel,
|
||||
.wire-drawer[data-open="true"][data-placement="top"] .wire-drawer__panel,
|
||||
.wire-drawer[data-open="true"][data-placement="bottom"] .wire-drawer__panel {
|
||||
.wrn-drawer[data-open="true"][data-placement="left"] .wrn-drawer__panel,
|
||||
.wrn-drawer[data-open="true"][data-placement="top"] .wrn-drawer__panel,
|
||||
.wrn-drawer[data-open="true"][data-placement="bottom"] .wrn-drawer__panel {
|
||||
transform: none;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.wire-drawer__layer,
|
||||
.wire-drawer__panel {
|
||||
.wrn-drawer__layer,
|
||||
.wrn-drawer__panel {
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
|
||||
.wire-drawer[data-size="sm"] .wire-drawer__panel {
|
||||
.wrn-drawer[data-size="sm"] .wrn-drawer__panel {
|
||||
width: min(22rem, calc(100vw - 1rem));
|
||||
}
|
||||
|
||||
.wire-drawer[data-size="lg"] .wire-drawer__panel {
|
||||
.wrn-drawer[data-size="lg"] .wrn-drawer__panel {
|
||||
width: min(38rem, calc(100vw - 1rem));
|
||||
}
|
||||
|
||||
.wire-drawer[data-size="xl"] .wire-drawer__panel {
|
||||
.wrn-drawer[data-size="xl"] .wrn-drawer__panel {
|
||||
width: min(52rem, calc(100vw - 1rem));
|
||||
}
|
||||
|
||||
.wire-drawer[data-size="full"] .wire-drawer__panel {
|
||||
.wrn-drawer[data-size="full"] .wrn-drawer__panel {
|
||||
width: 100vw;
|
||||
}
|
||||
|
||||
.wire-drawer[data-placement="left"] .wire-drawer__panel {
|
||||
.wrn-drawer[data-placement="left"] .wrn-drawer__panel {
|
||||
margin-right: auto;
|
||||
margin-left: 0;
|
||||
border-right: 1px solid color-mix(in srgb, var(--drawer-accent) 18%, var(--wire-color-border));
|
||||
border-right: 1px solid color-mix(in srgb, var(--drawer-accent) 18%, var(--wrn-color-border));
|
||||
border-left: 0;
|
||||
box-shadow: 28px 0 80px color-mix(in srgb, black 28%, transparent);
|
||||
}
|
||||
|
||||
.wire-drawer[data-placement="top"] .wire-drawer__layer,
|
||||
.wire-drawer[data-placement="bottom"] .wire-drawer__layer {
|
||||
.wrn-drawer[data-placement="top"] .wrn-drawer__layer,
|
||||
.wrn-drawer[data-placement="bottom"] .wrn-drawer__layer {
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.wire-drawer[data-placement="top"] .wire-drawer__panel,
|
||||
.wire-drawer[data-placement="bottom"] .wire-drawer__panel {
|
||||
.wrn-drawer[data-placement="top"] .wrn-drawer__panel,
|
||||
.wrn-drawer[data-placement="bottom"] .wrn-drawer__panel {
|
||||
width: 100%;
|
||||
max-height: min(80vh, 44rem);
|
||||
margin: 0;
|
||||
@@ -357,61 +357,61 @@ open: boolean = false
|
||||
box-shadow: 0 24px 80px color-mix(in srgb, black 28%, transparent);
|
||||
}
|
||||
|
||||
.wire-drawer[data-placement="top"] .wire-drawer__panel {
|
||||
border-bottom: 1px solid color-mix(in srgb, var(--drawer-accent) 18%, var(--wire-color-border));
|
||||
.wrn-drawer[data-placement="top"] .wrn-drawer__panel {
|
||||
border-bottom: 1px solid color-mix(in srgb, var(--drawer-accent) 18%, var(--wrn-color-border));
|
||||
}
|
||||
|
||||
.wire-drawer[data-placement="bottom"] .wire-drawer__layer {
|
||||
.wrn-drawer[data-placement="bottom"] .wrn-drawer__layer {
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
.wire-drawer[data-placement="bottom"] .wire-drawer__panel {
|
||||
border-top: 1px solid color-mix(in srgb, var(--drawer-accent) 18%, var(--wire-color-border));
|
||||
.wrn-drawer[data-placement="bottom"] .wrn-drawer__panel {
|
||||
border-top: 1px solid color-mix(in srgb, var(--drawer-accent) 18%, var(--wrn-color-border));
|
||||
border-radius: 1.3rem 1.3rem 0 0;
|
||||
}
|
||||
|
||||
.wire-drawer[data-variant="soft"] .wire-drawer__panel {
|
||||
.wrn-drawer[data-variant="soft"] .wrn-drawer__panel {
|
||||
background:
|
||||
linear-gradient(145deg, var(--drawer-soft), transparent 65%),
|
||||
var(--wire-color-surface-raised);
|
||||
var(--wrn-color-surface-raised);
|
||||
}
|
||||
|
||||
.wire-drawer[data-variant="solid"] .wire-drawer__panel {
|
||||
color: var(--wire-color-primary-contrast);
|
||||
.wrn-drawer[data-variant="solid"] .wrn-drawer__panel {
|
||||
color: var(--wrn-color-primary-contrast);
|
||||
background: var(--drawer-accent);
|
||||
border-color: color-mix(in srgb, white 18%, transparent);
|
||||
}
|
||||
|
||||
.wire-drawer__handle {
|
||||
.wrn-drawer__handle {
|
||||
display: none;
|
||||
width: 2.75rem;
|
||||
height: 0.28rem;
|
||||
margin: 0.55rem auto 0;
|
||||
background: color-mix(in srgb, var(--wire-color-text-muted) 48%, transparent);
|
||||
background: color-mix(in srgb, var(--wrn-color-text-muted) 48%, transparent);
|
||||
border-radius: 999px;
|
||||
}
|
||||
|
||||
.wire-drawer[data-placement="bottom"] .wire-drawer__handle {
|
||||
.wrn-drawer[data-placement="bottom"] .wrn-drawer__handle {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.wire-drawer__header {
|
||||
.wrn-drawer__header {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
gap: 1rem;
|
||||
padding: 1.35rem 1.35rem 1.1rem;
|
||||
border-bottom: 1px solid var(--wire-color-border);
|
||||
border-bottom: 1px solid var(--wrn-color-border);
|
||||
}
|
||||
|
||||
.wire-drawer__heading {
|
||||
.wrn-drawer__heading {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 0.85rem;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.wire-drawer__icon {
|
||||
.wrn-drawer__icon {
|
||||
flex: 0 0 auto;
|
||||
width: 1.25rem;
|
||||
height: 1.25rem;
|
||||
@@ -419,34 +419,34 @@ open: boolean = false
|
||||
color: var(--drawer-accent);
|
||||
}
|
||||
|
||||
.wire-drawer[data-variant="solid"] .wire-drawer__icon {
|
||||
.wrn-drawer[data-variant="solid"] .wrn-drawer__icon {
|
||||
color: currentColor;
|
||||
}
|
||||
|
||||
.wire-drawer__heading-copy {
|
||||
.wrn-drawer__heading-copy {
|
||||
display: grid;
|
||||
gap: 0.3rem;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.wire-drawer__heading-copy h2,
|
||||
.wire-drawer__heading-copy p {
|
||||
.wrn-drawer__heading-copy h2,
|
||||
.wrn-drawer__heading-copy p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.wire-drawer__heading-copy h2 {
|
||||
.wrn-drawer__heading-copy h2 {
|
||||
font-size: 1.05rem;
|
||||
font-weight: 650;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.wire-drawer__heading-copy p {
|
||||
color: var(--wire-color-text-muted);
|
||||
.wrn-drawer__heading-copy p {
|
||||
color: var(--wrn-color-text-muted);
|
||||
font-size: 0.8rem;
|
||||
line-height: 1.55;
|
||||
}
|
||||
|
||||
.wire-drawer[data-variant="solid"] .wire-drawer__heading-copy p {
|
||||
.wrn-drawer[data-variant="solid"] .wrn-drawer__heading-copy p {
|
||||
color: color-mix(in srgb, currentColor 76%, transparent);
|
||||
}
|
||||
|
||||
@@ -456,7 +456,7 @@ open: boolean = false
|
||||
* content box of a couple of pixels, which squeezes the icon to a sliver
|
||||
* and reads as "the close button has no icon". Same trap as Modal.
|
||||
*/
|
||||
.wire-drawer__close {
|
||||
.wrn-drawer__close {
|
||||
appearance: none;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
@@ -465,22 +465,22 @@ open: boolean = false
|
||||
padding: 0;
|
||||
width: 2.35rem;
|
||||
height: 2.35rem;
|
||||
color: var(--wire-color-text-muted);
|
||||
background: var(--wire-color-surface-soft);
|
||||
border: 1px solid var(--wire-color-border);
|
||||
color: var(--wrn-color-text-muted);
|
||||
background: var(--wrn-color-surface-soft);
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: 0.75rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.wire-drawer__close:hover,
|
||||
.wire-drawer__close:focus-visible {
|
||||
.wrn-drawer__close:hover,
|
||||
.wrn-drawer__close:focus-visible {
|
||||
color: var(--drawer-accent);
|
||||
border-color: color-mix(in srgb, var(--drawer-accent) 34%, var(--wire-color-border));
|
||||
border-color: color-mix(in srgb, var(--drawer-accent) 34%, var(--wrn-color-border));
|
||||
outline: none;
|
||||
}
|
||||
|
||||
/* Never let the glyph be shrunk by the flex container. */
|
||||
.wire-drawer__close svg {
|
||||
.wrn-drawer__close svg {
|
||||
flex: 0 0 auto;
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
@@ -494,40 +494,40 @@ open: boolean = false
|
||||
* :where() keeps the specificity low enough that any class the app puts on
|
||||
* its own slot content still wins.
|
||||
*/
|
||||
.wire-drawer__body {
|
||||
.wrn-drawer__body {
|
||||
flex: 1 1 auto;
|
||||
min-height: 0;
|
||||
padding: 1.35rem;
|
||||
color: var(--wire-color-text);
|
||||
color: var(--wrn-color-text);
|
||||
}
|
||||
|
||||
.wire-drawer__body :where(p, li, dd, dt, h1, h2, h3, h4, h5, h6, span, label, code) {
|
||||
.wrn-drawer__body :where(p, li, dd, dt, h1, h2, h3, h4, h5, h6, span, label, code) {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.wire-drawer[data-scrollable="true"] .wire-drawer__body {
|
||||
.wrn-drawer[data-scrollable="true"] .wrn-drawer__body {
|
||||
overflow: auto;
|
||||
overscroll-behavior: contain;
|
||||
}
|
||||
|
||||
.wire-drawer__footer {
|
||||
.wrn-drawer__footer {
|
||||
padding: 1rem 1.35rem 1.35rem;
|
||||
border-top: 1px solid var(--wire-color-border);
|
||||
border-top: 1px solid var(--wrn-color-border);
|
||||
}
|
||||
|
||||
.wire-drawer__footer:empty {
|
||||
.wrn-drawer__footer:empty {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media (max-width: 639px) {
|
||||
.wire-drawer[data-placement="right"] .wire-drawer__panel,
|
||||
.wire-drawer[data-placement="left"] .wire-drawer__panel {
|
||||
.wrn-drawer[data-placement="right"] .wrn-drawer__panel,
|
||||
.wrn-drawer[data-placement="left"] .wrn-drawer__panel {
|
||||
width: min(24rem, 100vw);
|
||||
}
|
||||
|
||||
.wire-drawer__header,
|
||||
.wire-drawer__body,
|
||||
.wire-drawer__footer {
|
||||
.wrn-drawer__header,
|
||||
.wrn-drawer__body,
|
||||
.wrn-drawer__footer {
|
||||
padding-inline: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
+109
-109
@@ -82,7 +82,7 @@ items: unknown[] = []
|
||||
}
|
||||
|
||||
client function moveFocus(sourceEvent, direction) {
|
||||
const root = sourceEvent.currentTarget.closest(".wire-dropdown") || sourceEvent.currentTarget
|
||||
const root = sourceEvent.currentTarget.closest(".wrn-dropdown") || sourceEvent.currentTarget
|
||||
const options = [...root.querySelectorAll("[data-dropdown-item]:not([disabled])")]
|
||||
if (!options.length) {
|
||||
return
|
||||
@@ -110,14 +110,14 @@ items: unknown[] = []
|
||||
moveFocus(sourceEvent, -1)
|
||||
} else if (sourceEvent.key === "Home" && isOpen()) {
|
||||
sourceEvent.preventDefault()
|
||||
const root = sourceEvent.currentTarget.closest(".wire-dropdown") || sourceEvent.currentTarget
|
||||
const root = sourceEvent.currentTarget.closest(".wrn-dropdown") || sourceEvent.currentTarget
|
||||
const first = root.querySelector("[data-dropdown-item]:not([disabled])")
|
||||
if (first) {
|
||||
first.focus()
|
||||
}
|
||||
} else if (sourceEvent.key === "End" && isOpen()) {
|
||||
sourceEvent.preventDefault()
|
||||
const root = sourceEvent.currentTarget.closest(".wire-dropdown") || sourceEvent.currentTarget
|
||||
const root = sourceEvent.currentTarget.closest(".wrn-dropdown") || sourceEvent.currentTarget
|
||||
const options = [...root.querySelectorAll("[data-dropdown-item]:not([disabled])")]
|
||||
if (options.length) {
|
||||
options[options.length - 1].focus()
|
||||
@@ -136,12 +136,12 @@ items: unknown[] = []
|
||||
data-size='{size}'
|
||||
data-color='{color}'
|
||||
data-variant='{variant}'
|
||||
class='wire-dropdown {class}'
|
||||
class='wrn-dropdown {class}'
|
||||
@keydown='handleKeydown(event)'
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
class="wire-dropdown__trigger"
|
||||
class="wrn-dropdown__trigger"
|
||||
disabled='{disabled}'
|
||||
aria-haspopup="menu"
|
||||
aria-expanded='{open || visible ? "true" : "false"}'
|
||||
@@ -149,20 +149,20 @@ items: unknown[] = []
|
||||
>
|
||||
<slot name="trigger"></slot>
|
||||
{#if icon}
|
||||
<span class='wire-dropdown__trigger-icon {icon}' aria-hidden="true"></span>
|
||||
<span class='wrn-dropdown__trigger-icon {icon}' aria-hidden="true"></span>
|
||||
{/if}
|
||||
{#if label}
|
||||
<span class="wire-dropdown__trigger-label">{label}</span>
|
||||
<span class="wrn-dropdown__trigger-label">{label}</span>
|
||||
{/if}
|
||||
{#if showChevron}
|
||||
<span class="icon-[lucide--chevron-down] wire-dropdown__chevron" aria-hidden="true"></span>
|
||||
<span class="icon-[lucide--chevron-down] wrn-dropdown__chevron" aria-hidden="true"></span>
|
||||
{/if}
|
||||
</button>
|
||||
|
||||
{#if closeOnOutside}
|
||||
<button
|
||||
type="button"
|
||||
class="wire-dropdown__dismiss-layer"
|
||||
class="wrn-dropdown__dismiss-layer"
|
||||
data-show='{open || visible}'
|
||||
aria-label="Close menu"
|
||||
@click='hideMenu("outside", event)'
|
||||
@@ -170,7 +170,7 @@ items: unknown[] = []
|
||||
{/if}
|
||||
|
||||
<div
|
||||
class="wire-dropdown__panel"
|
||||
class="wrn-dropdown__panel"
|
||||
data-wrn-anchored="true"
|
||||
data-show='{open || visible}'
|
||||
role="menu"
|
||||
@@ -178,12 +178,12 @@ items: unknown[] = []
|
||||
>
|
||||
<slot name="header"></slot>
|
||||
|
||||
<div class="wire-dropdown__items">
|
||||
<div class="wrn-dropdown__items">
|
||||
{#each items as item, itemIndex}
|
||||
{#if item.type === "divider"}
|
||||
<div class="wire-dropdown__divider" role="separator"></div>
|
||||
<div class="wrn-dropdown__divider" role="separator"></div>
|
||||
{:else if item.type === "header"}
|
||||
<div class="wire-dropdown__section-label">{item.label || item.title}</div>
|
||||
<div class="wrn-dropdown__section-label">{item.label || item.title}</div>
|
||||
{:else if item.href}
|
||||
<a
|
||||
href='{item.href}'
|
||||
@@ -194,26 +194,26 @@ items: unknown[] = []
|
||||
data-danger='{item.danger ? "true" : "false"}'
|
||||
data-selected='{item.selected || item.checked ? "true" : "false"}'
|
||||
aria-disabled='{item.disabled ? "true" : "false"}'
|
||||
class="wire-dropdown__item"
|
||||
class="wrn-dropdown__item"
|
||||
@click='chooseItem(item, itemIndex, event)'
|
||||
>
|
||||
{#if item.icon}
|
||||
<span class='wire-dropdown__item-icon {item.icon}' aria-hidden="true"></span>
|
||||
<span class='wrn-dropdown__item-icon {item.icon}' aria-hidden="true"></span>
|
||||
{/if}
|
||||
<span class="wire-dropdown__copy">
|
||||
<span class="wrn-dropdown__copy">
|
||||
<strong>{item.label || item.title}</strong>
|
||||
{#if item.description}
|
||||
<small>{item.description}</small>
|
||||
{/if}
|
||||
</span>
|
||||
{#if item.badge}
|
||||
<span class="wire-dropdown__badge">{item.badge}</span>
|
||||
<span class="wrn-dropdown__badge">{item.badge}</span>
|
||||
{:else if item.shortcut}
|
||||
<kbd>{item.shortcut}</kbd>
|
||||
{:else if item.checked || item.selected}
|
||||
<span class="icon-[lucide--check] wire-dropdown__status" aria-hidden="true"></span>
|
||||
<span class="icon-[lucide--check] wrn-dropdown__status" aria-hidden="true"></span>
|
||||
{:else if item.external}
|
||||
<span class="icon-[lucide--arrow-up-right] wire-dropdown__status" aria-hidden="true"></span>
|
||||
<span class="icon-[lucide--arrow-up-right] wrn-dropdown__status" aria-hidden="true"></span>
|
||||
{/if}
|
||||
</a>
|
||||
{:else}
|
||||
@@ -224,29 +224,29 @@ items: unknown[] = []
|
||||
data-danger='{item.danger ? "true" : "false"}'
|
||||
data-selected='{item.selected || item.checked ? "true" : "false"}'
|
||||
disabled='{item.disabled}'
|
||||
class="wire-dropdown__item"
|
||||
class="wrn-dropdown__item"
|
||||
@click='chooseItem(item, itemIndex, event)'
|
||||
>
|
||||
{#if item.icon}
|
||||
<span class='wire-dropdown__item-icon {item.icon}' aria-hidden="true"></span>
|
||||
<span class='wrn-dropdown__item-icon {item.icon}' aria-hidden="true"></span>
|
||||
{/if}
|
||||
<span class="wire-dropdown__copy">
|
||||
<span class="wrn-dropdown__copy">
|
||||
<strong>{item.label || item.title}</strong>
|
||||
{#if item.description}
|
||||
<small>{item.description}</small>
|
||||
{/if}
|
||||
</span>
|
||||
{#if item.badge}
|
||||
<span class="wire-dropdown__badge">{item.badge}</span>
|
||||
<span class="wrn-dropdown__badge">{item.badge}</span>
|
||||
{:else if item.shortcut}
|
||||
<kbd>{item.shortcut}</kbd>
|
||||
{:else if item.checked || item.selected}
|
||||
<span class="icon-[lucide--check] wire-dropdown__status" aria-hidden="true"></span>
|
||||
<span class="icon-[lucide--check] wrn-dropdown__status" aria-hidden="true"></span>
|
||||
{/if}
|
||||
</button>
|
||||
{/if}
|
||||
{:empty}
|
||||
<div class="wire-dropdown__empty">{emptyLabel}</div>
|
||||
<div class="wrn-dropdown__empty">{emptyLabel}</div>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
@@ -257,40 +257,40 @@ items: unknown[] = []
|
||||
}
|
||||
|
||||
style {
|
||||
.wire-dropdown {
|
||||
--dropdown-accent: var(--wire-color-primary);
|
||||
--dropdown-soft: var(--wire-color-primary-soft);
|
||||
.wrn-dropdown {
|
||||
--dropdown-accent: var(--wrn-color-primary);
|
||||
--dropdown-soft: var(--wrn-color-primary-soft);
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.wire-dropdown[data-color="secondary"] {
|
||||
--dropdown-accent: var(--wire-color-secondary);
|
||||
--dropdown-soft: var(--wire-color-secondary-soft);
|
||||
.wrn-dropdown[data-color="secondary"] {
|
||||
--dropdown-accent: var(--wrn-color-secondary);
|
||||
--dropdown-soft: var(--wrn-color-secondary-soft);
|
||||
}
|
||||
|
||||
.wire-dropdown[data-color="info"] {
|
||||
--dropdown-accent: var(--wire-color-info);
|
||||
--dropdown-soft: var(--wire-color-info-soft);
|
||||
.wrn-dropdown[data-color="info"] {
|
||||
--dropdown-accent: var(--wrn-color-info);
|
||||
--dropdown-soft: var(--wrn-color-info-soft);
|
||||
}
|
||||
|
||||
.wire-dropdown[data-color="success"] {
|
||||
--dropdown-accent: var(--wire-color-success);
|
||||
--dropdown-soft: var(--wire-color-success-soft);
|
||||
.wrn-dropdown[data-color="success"] {
|
||||
--dropdown-accent: var(--wrn-color-success);
|
||||
--dropdown-soft: var(--wrn-color-success-soft);
|
||||
}
|
||||
|
||||
.wire-dropdown[data-color="warning"] {
|
||||
--dropdown-accent: var(--wire-color-warning);
|
||||
--dropdown-soft: var(--wire-color-warning-soft);
|
||||
.wrn-dropdown[data-color="warning"] {
|
||||
--dropdown-accent: var(--wrn-color-warning);
|
||||
--dropdown-soft: var(--wrn-color-warning-soft);
|
||||
}
|
||||
|
||||
.wire-dropdown[data-color="danger"] {
|
||||
--dropdown-accent: var(--wire-color-danger);
|
||||
--dropdown-soft: var(--wire-color-danger-soft);
|
||||
.wrn-dropdown[data-color="danger"] {
|
||||
--dropdown-accent: var(--wrn-color-danger);
|
||||
--dropdown-soft: var(--wrn-color-danger-soft);
|
||||
}
|
||||
|
||||
.wire-dropdown__trigger {
|
||||
.wrn-dropdown__trigger {
|
||||
appearance: none;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
@@ -298,9 +298,9 @@ items: unknown[] = []
|
||||
gap: 0.55rem;
|
||||
min-height: 2.55rem;
|
||||
padding: 0.65rem 0.9rem;
|
||||
color: var(--wire-color-text);
|
||||
background: var(--wire-color-surface-raised);
|
||||
border: 1px solid var(--wire-color-border);
|
||||
color: var(--wrn-color-text);
|
||||
background: var(--wrn-color-surface-raised);
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: 0.78rem;
|
||||
font: inherit;
|
||||
font-size: 0.84rem;
|
||||
@@ -309,47 +309,47 @@ items: unknown[] = []
|
||||
transition: border-color 150ms ease, background-color 150ms ease, color 150ms ease;
|
||||
}
|
||||
|
||||
.wire-dropdown__trigger:hover,
|
||||
.wire-dropdown__trigger:focus-visible,
|
||||
.wire-dropdown[data-open="true"] .wire-dropdown__trigger {
|
||||
.wrn-dropdown__trigger:hover,
|
||||
.wrn-dropdown__trigger:focus-visible,
|
||||
.wrn-dropdown[data-open="true"] .wrn-dropdown__trigger {
|
||||
color: var(--dropdown-accent);
|
||||
background: var(--dropdown-soft);
|
||||
border-color: color-mix(in srgb, var(--dropdown-accent) 38%, var(--wire-color-border));
|
||||
border-color: color-mix(in srgb, var(--dropdown-accent) 38%, var(--wrn-color-border));
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.wire-dropdown__trigger:disabled {
|
||||
.wrn-dropdown__trigger:disabled {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.wire-dropdown__trigger-icon,
|
||||
.wire-dropdown__chevron {
|
||||
.wrn-dropdown__trigger-icon,
|
||||
.wrn-dropdown__chevron {
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
}
|
||||
|
||||
.wire-dropdown__chevron {
|
||||
.wrn-dropdown__chevron {
|
||||
transition: transform 160ms ease;
|
||||
}
|
||||
|
||||
.wire-dropdown[data-open="true"] .wire-dropdown__chevron {
|
||||
.wrn-dropdown[data-open="true"] .wrn-dropdown__chevron {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
.wire-dropdown[data-size="sm"] .wire-dropdown__trigger {
|
||||
.wrn-dropdown[data-size="sm"] .wrn-dropdown__trigger {
|
||||
min-height: 2.2rem;
|
||||
padding: 0.5rem 0.72rem;
|
||||
font-size: 0.78rem;
|
||||
}
|
||||
|
||||
.wire-dropdown[data-size="lg"] .wire-dropdown__trigger {
|
||||
.wrn-dropdown[data-size="lg"] .wrn-dropdown__trigger {
|
||||
min-height: 2.9rem;
|
||||
padding: 0.78rem 1.05rem;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.wire-dropdown__dismiss-layer {
|
||||
.wrn-dropdown__dismiss-layer {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
z-index: 1100;
|
||||
@@ -359,7 +359,7 @@ items: unknown[] = []
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.wire-dropdown__panel {
|
||||
.wrn-dropdown__panel {
|
||||
position: absolute;
|
||||
z-index: 1101;
|
||||
top: calc(100% + 0.55rem);
|
||||
@@ -368,11 +368,11 @@ items: unknown[] = []
|
||||
min-width: 12rem;
|
||||
max-width: min(22rem, calc(100vw - 1.5rem));
|
||||
padding: 0.45rem;
|
||||
color: var(--wire-color-text);
|
||||
color: var(--wrn-color-text);
|
||||
background:
|
||||
linear-gradient(145deg, color-mix(in srgb, var(--dropdown-accent) 5%, transparent), transparent 60%),
|
||||
color-mix(in srgb, var(--wire-color-surface-raised) 97%, transparent);
|
||||
border: 1px solid color-mix(in srgb, var(--dropdown-accent) 18%, var(--wire-color-border));
|
||||
color-mix(in srgb, var(--wrn-color-surface-raised) 97%, transparent);
|
||||
border: 1px solid color-mix(in srgb, var(--dropdown-accent) 18%, var(--wrn-color-border));
|
||||
border-radius: 1rem;
|
||||
box-shadow:
|
||||
0 1px 0 color-mix(in srgb, white 5%, transparent) inset,
|
||||
@@ -380,73 +380,73 @@ items: unknown[] = []
|
||||
backdrop-filter: blur(18px);
|
||||
}
|
||||
|
||||
.wire-dropdown[data-width="trigger"] .wire-dropdown__panel {
|
||||
.wrn-dropdown[data-width="trigger"] .wrn-dropdown__panel {
|
||||
width: 100%;
|
||||
min-width: 100%;
|
||||
}
|
||||
|
||||
.wire-dropdown[data-width="sm"] .wire-dropdown__panel {
|
||||
.wrn-dropdown[data-width="sm"] .wrn-dropdown__panel {
|
||||
width: 12rem;
|
||||
}
|
||||
|
||||
.wire-dropdown[data-width="md"] .wire-dropdown__panel {
|
||||
.wrn-dropdown[data-width="md"] .wrn-dropdown__panel {
|
||||
width: 17rem;
|
||||
}
|
||||
|
||||
.wire-dropdown[data-width="lg"] .wire-dropdown__panel {
|
||||
.wrn-dropdown[data-width="lg"] .wrn-dropdown__panel {
|
||||
width: 22rem;
|
||||
}
|
||||
|
||||
.wire-dropdown[data-placement="bottom-end"] .wire-dropdown__panel {
|
||||
.wrn-dropdown[data-placement="bottom-end"] .wrn-dropdown__panel {
|
||||
right: 0;
|
||||
left: auto;
|
||||
}
|
||||
|
||||
.wire-dropdown[data-placement="top-start"] .wire-dropdown__panel {
|
||||
.wrn-dropdown[data-placement="top-start"] .wrn-dropdown__panel {
|
||||
top: auto;
|
||||
bottom: calc(100% + 0.55rem);
|
||||
}
|
||||
|
||||
.wire-dropdown[data-placement="top-end"] .wire-dropdown__panel {
|
||||
.wrn-dropdown[data-placement="top-end"] .wrn-dropdown__panel {
|
||||
top: auto;
|
||||
right: 0;
|
||||
bottom: calc(100% + 0.55rem);
|
||||
left: auto;
|
||||
}
|
||||
|
||||
.wire-dropdown[data-variant="soft"] .wire-dropdown__panel {
|
||||
.wrn-dropdown[data-variant="soft"] .wrn-dropdown__panel {
|
||||
background:
|
||||
linear-gradient(145deg, var(--dropdown-soft), transparent 70%),
|
||||
var(--wire-color-surface-raised);
|
||||
var(--wrn-color-surface-raised);
|
||||
box-shadow: 0 18px 48px color-mix(in srgb, black 16%, transparent);
|
||||
}
|
||||
|
||||
.wire-dropdown[data-variant="outline"] .wire-dropdown__panel {
|
||||
background: var(--wire-color-surface-raised);
|
||||
.wrn-dropdown[data-variant="outline"] .wrn-dropdown__panel {
|
||||
background: var(--wrn-color-surface-raised);
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.wire-dropdown__items {
|
||||
.wrn-dropdown__items {
|
||||
display: grid;
|
||||
gap: 0.15rem;
|
||||
}
|
||||
|
||||
.wire-dropdown__section-label {
|
||||
.wrn-dropdown__section-label {
|
||||
padding: 0.55rem 0.72rem 0.3rem;
|
||||
color: var(--wire-color-text-muted);
|
||||
color: var(--wrn-color-text-muted);
|
||||
font-size: 0.68rem;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.12em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.wire-dropdown__divider {
|
||||
.wrn-dropdown__divider {
|
||||
height: 1px;
|
||||
margin: 0.3rem 0.4rem;
|
||||
background: var(--wire-color-border);
|
||||
background: var(--wrn-color-border);
|
||||
}
|
||||
|
||||
.wire-dropdown__item {
|
||||
.wrn-dropdown__item {
|
||||
appearance: none;
|
||||
display: grid;
|
||||
grid-template-columns: auto minmax(0, 1fr) auto;
|
||||
@@ -455,7 +455,7 @@ items: unknown[] = []
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
padding: 0.68rem 0.72rem;
|
||||
color: var(--wire-color-text);
|
||||
color: var(--wrn-color-text);
|
||||
background: transparent;
|
||||
border: 0;
|
||||
border-radius: 0.72rem;
|
||||
@@ -466,46 +466,46 @@ items: unknown[] = []
|
||||
transition: background-color 150ms ease, color 150ms ease, transform 150ms ease;
|
||||
}
|
||||
|
||||
.wire-dropdown__item:hover,
|
||||
.wire-dropdown__item:focus-visible,
|
||||
.wire-dropdown__item[data-selected="true"] {
|
||||
.wrn-dropdown__item:hover,
|
||||
.wrn-dropdown__item:focus-visible,
|
||||
.wrn-dropdown__item[data-selected="true"] {
|
||||
color: var(--dropdown-accent);
|
||||
background: var(--dropdown-soft);
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.wire-dropdown__item:active {
|
||||
.wrn-dropdown__item:active {
|
||||
transform: scale(0.985);
|
||||
}
|
||||
|
||||
.wire-dropdown__item[data-danger="true"] {
|
||||
color: var(--wire-color-danger);
|
||||
.wrn-dropdown__item[data-danger="true"] {
|
||||
color: var(--wrn-color-danger);
|
||||
}
|
||||
|
||||
.wire-dropdown__item[data-danger="true"]:hover,
|
||||
.wire-dropdown__item[data-danger="true"]:focus-visible {
|
||||
background: var(--wire-color-danger-soft);
|
||||
.wrn-dropdown__item[data-danger="true"]:hover,
|
||||
.wrn-dropdown__item[data-danger="true"]:focus-visible {
|
||||
background: var(--wrn-color-danger-soft);
|
||||
}
|
||||
|
||||
.wire-dropdown__item[disabled],
|
||||
.wire-dropdown__item[aria-disabled="true"] {
|
||||
.wrn-dropdown__item[disabled],
|
||||
.wrn-dropdown__item[aria-disabled="true"] {
|
||||
opacity: 0.48;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.wire-dropdown__item-icon,
|
||||
.wire-dropdown__status {
|
||||
.wrn-dropdown__item-icon,
|
||||
.wrn-dropdown__status {
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
}
|
||||
|
||||
.wire-dropdown__copy {
|
||||
.wrn-dropdown__copy {
|
||||
display: grid;
|
||||
gap: 0.12rem;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.wire-dropdown__copy strong {
|
||||
.wrn-dropdown__copy strong {
|
||||
overflow: hidden;
|
||||
font-size: 0.82rem;
|
||||
font-weight: 600;
|
||||
@@ -514,16 +514,16 @@ items: unknown[] = []
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.wire-dropdown__copy small {
|
||||
.wrn-dropdown__copy small {
|
||||
overflow: hidden;
|
||||
color: var(--wire-color-text-muted);
|
||||
color: var(--wrn-color-text-muted);
|
||||
font-size: 0.7rem;
|
||||
line-height: 1.35;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.wire-dropdown__badge {
|
||||
.wrn-dropdown__badge {
|
||||
padding: 0.18rem 0.45rem;
|
||||
color: var(--dropdown-accent);
|
||||
background: var(--dropdown-soft);
|
||||
@@ -532,25 +532,25 @@ items: unknown[] = []
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.wire-dropdown kbd {
|
||||
.wrn-dropdown kbd {
|
||||
padding: 0.16rem 0.38rem;
|
||||
color: var(--wire-color-text-muted);
|
||||
background: var(--wire-color-surface-soft);
|
||||
border: 1px solid var(--wire-color-border);
|
||||
color: var(--wrn-color-text-muted);
|
||||
background: var(--wrn-color-surface-soft);
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: 0.36rem;
|
||||
font-size: 0.64rem;
|
||||
font-family: inherit;
|
||||
}
|
||||
|
||||
.wire-dropdown__empty {
|
||||
.wrn-dropdown__empty {
|
||||
padding: 1rem;
|
||||
color: var(--wire-color-text-muted);
|
||||
color: var(--wrn-color-text-muted);
|
||||
font-size: 0.8rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@media (max-width: 639px) {
|
||||
.wire-dropdown__panel {
|
||||
.wrn-dropdown__panel {
|
||||
position: fixed;
|
||||
right: 0.75rem;
|
||||
bottom: 0.75rem;
|
||||
@@ -563,9 +563,9 @@ items: unknown[] = []
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.wire-dropdown__trigger,
|
||||
.wire-dropdown__chevron,
|
||||
.wire-dropdown__item {
|
||||
.wrn-dropdown__trigger,
|
||||
.wrn-dropdown__chevron,
|
||||
.wrn-dropdown__item {
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
import FieldStyles from "../styles/FieldStyles.wrn"
|
||||
|
||||
import ComponentBaseStyles from "../styles/ComponentBaseStyles.wrn"
|
||||
|
||||
component FileInput {
|
||||
outputs {
|
||||
input(payload: { files: File[]; name: string; sourceEvent: Event })
|
||||
@@ -50,30 +46,587 @@ size: string = "default"
|
||||
client function preventReadonly(sourceEvent) { if (readonly) sourceEvent.preventDefault() }
|
||||
}
|
||||
view {
|
||||
<div {...attrs} class="wire-component wire-component--color-{color} wire-component--size-{size} wire-next--field wire-next--file-input {class}" data-variant="{variant}" data-inline="{inline}" data-invalid="{error ? 'true' : 'false'}">
|
||||
<div class="wire-next__field-heading"><label class="{hiddenLabel ? 'wire-next__sr-only' : ''}" for="{id || name}">{label}</label>{#if cornerHint}<span class="wire-next__field-hint">{cornerHint}</span>{/if}</div>
|
||||
<div class="wire-next__file-control" data-icon-position="{iconPosition}">{#if icon}<span class="{icon}" aria-hidden="true"></span>{/if}<span>{selectedName || value || placeholder}</span><input id="{id || name}" type="file" name="{name}" accept="{accept}" multiple="{multiple}" disabled="{disabled}" required="{required}" aria-readonly="{readonly}" aria-invalid="{error ? 'true' : 'false'}" @click="preventReadonly(event)" @input="handleChange(event)" @change="handleChange(event)" @focus="emitField('focus', event)" @blur="emitField('blur', event)" @invalid="emitField('invalid', event)" /></div>
|
||||
{#if helperText}<small class="wire-next__field-help">{helperText}</small>{/if}<small class="wire-next__field-error" data-error="{name}">{error}</small>
|
||||
<div {...attrs} class="wrn-component wrn-component--color-{color} wrn-component--size-{size} wrn-next--field wrn-next--file-input {class}" data-variant="{variant}" data-inline="{inline}" data-invalid="{error ? 'true' : 'false'}">
|
||||
<div class="wrn-next__field-heading"><label class="{hiddenLabel ? 'wrn-next__sr-only' : ''}" for="{id || name}">{label}</label>{#if cornerHint}<span class="wrn-next__field-hint">{cornerHint}</span>{/if}</div>
|
||||
<div class="wrn-next__file-control" data-icon-position="{iconPosition}">{#if icon}<span class="{icon}" aria-hidden="true"></span>{/if}<span>{selectedName || value || placeholder}</span><input id="{id || name}" type="file" name="{name}" accept="{accept}" multiple="{multiple}" disabled="{disabled}" required="{required}" aria-readonly="{readonly}" aria-invalid="{error ? 'true' : 'false'}" @click="preventReadonly(event)" @input="handleChange(event)" @change="handleChange(event)" @focus="emitField('focus', event)" @blur="emitField('blur', event)" @invalid="emitField('invalid', event)" /></div>
|
||||
{#if helperText}<small class="wrn-next__field-help">{helperText}</small>{/if}<small class="wrn-next__field-error" data-error="{name}">{error}</small>
|
||||
</div>
|
||||
<FieldStyles hidden />
|
||||
<ComponentBaseStyles hidden />
|
||||
}
|
||||
|
||||
style {
|
||||
.wire-next__file-control {
|
||||
.wrn-next__file-control {
|
||||
position: relative;
|
||||
min-height: 2.75rem;
|
||||
padding: 0.65rem 0.85rem;
|
||||
border: 1px dashed var(--wire-color-border);
|
||||
border-radius: var(--wire-radius-sm);
|
||||
background: var(--wire-color-surface);
|
||||
border: 1px dashed var(--wrn-color-border);
|
||||
border-radius: var(--wrn-radius-sm);
|
||||
background: var(--wrn-color-surface);
|
||||
}
|
||||
|
||||
.wire-next__file-control input {
|
||||
.wrn-next__file-control input {
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
opacity: 0;
|
||||
inset: 0;
|
||||
}
|
||||
|
||||
/* Shared component foundation. */
|
||||
|
||||
.wrn-component {
|
||||
--wrn-component-color: var(--wrn-color-primary);
|
||||
--wrn-component-scale: 1;
|
||||
margin: 0;
|
||||
color: var(--wrn-color-text);
|
||||
font-family: var(--wrn-font-sans, inherit);
|
||||
}
|
||||
|
||||
.wrn-component--color-primary {
|
||||
--wrn-component-color: var(--wrn-color-primary);
|
||||
}
|
||||
|
||||
.wrn-component--color-secondary {
|
||||
--wrn-component-color: var(--wrn-color-secondary);
|
||||
}
|
||||
|
||||
.wrn-component--color-success {
|
||||
--wrn-component-color: var(--wrn-color-success);
|
||||
}
|
||||
|
||||
.wrn-component--color-warning {
|
||||
--wrn-component-color: var(--wrn-color-warning);
|
||||
}
|
||||
|
||||
.wrn-component--color-danger {
|
||||
--wrn-component-color: var(--wrn-color-danger);
|
||||
}
|
||||
|
||||
.wrn-component--color-info {
|
||||
--wrn-component-color: var(--wrn-color-info);
|
||||
}
|
||||
|
||||
.wrn-component--size-xs {
|
||||
--wrn-component-scale: 0.78;
|
||||
}
|
||||
|
||||
.wrn-component--size-sm {
|
||||
--wrn-component-scale: 0.88;
|
||||
}
|
||||
|
||||
.wrn-component--size-default,
|
||||
.wrn-component--size-md {
|
||||
--wrn-component-scale: 1;
|
||||
}
|
||||
|
||||
.wrn-component--size-lg {
|
||||
--wrn-component-scale: 1.14;
|
||||
}
|
||||
|
||||
.wrn-component--size-xl {
|
||||
--wrn-component-scale: 1.28;
|
||||
}
|
||||
|
||||
.wrn-component:not(.wrn-btn) {
|
||||
font-size: calc(1em * var(--wrn-component-scale));
|
||||
}
|
||||
|
||||
.wrn-component :is(a, button, input, select, textarea):focus-visible {
|
||||
outline-color: var(--wrn-component-color);
|
||||
}
|
||||
|
||||
.wrn-component p {
|
||||
margin: 0;
|
||||
color: var(--wrn-color-muted);
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
/* Shared field foundation. */
|
||||
|
||||
/* Validation states set by the browser validation runtime. */
|
||||
.wrn-invalid {
|
||||
border-color: var(--wrn-color-danger) !important;
|
||||
}
|
||||
|
||||
.wrn-field-error {
|
||||
display: block;
|
||||
min-height: 1em;
|
||||
margin-top: 0.25rem;
|
||||
color: var(--wrn-color-danger);
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
.wrn-next--choice {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.55rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.wrn-next--choice input {
|
||||
width: 1.1rem;
|
||||
height: 1.1rem;
|
||||
accent-color: var(--wrn-color-primary);
|
||||
}
|
||||
|
||||
.wrn-next--field {
|
||||
display: grid;
|
||||
width: min(100%, 28rem);
|
||||
gap: 0.4rem;
|
||||
font-size: 0.78rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
.wrn-next--field :where(input, textarea, select) {
|
||||
width: 100%;
|
||||
min-height: 2.65rem;
|
||||
padding: 0.6rem 0.7rem;
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: 0.6rem;
|
||||
outline: 0;
|
||||
color: var(--wrn-color-text);
|
||||
background: var(--wrn-color-bg);
|
||||
font: inherit;
|
||||
font-weight: 500;
|
||||
}
|
||||
.wrn-auth-form form > .wrn-next--field,
|
||||
.wrn-auth-form form > .wrn-field {
|
||||
width: 100%;
|
||||
max-width: none;
|
||||
}
|
||||
.wrn-auth-form__submit > .wrn-btn {
|
||||
width: 100%;
|
||||
min-height: 3rem;
|
||||
border-radius: 0.75rem;
|
||||
box-shadow: 0 0.8rem 1.8rem color-mix(in srgb, var(--wrn-btn-color) 20%, transparent);
|
||||
}
|
||||
.wrn-next--field :where(input, textarea, select):focus-visible {
|
||||
border-color: var(--wrn-color-primary);
|
||||
box-shadow: 0 0 0 3px color-mix(in srgb, var(--wrn-color-primary) 16%, transparent);
|
||||
}
|
||||
.wrn-next--field textarea {
|
||||
resize: vertical;
|
||||
}
|
||||
.wrn-next--field,
|
||||
.wrn-next--choice-field {
|
||||
--wrn-field-color: var(--wrn-component-color, var(--wrn-color-primary));
|
||||
width: min(100%, 34rem);
|
||||
min-width: 0;
|
||||
color: var(--wrn-color-text);
|
||||
font-size: 0.8125rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
.wrn-next--field.wrn-next--size-sm,
|
||||
.wrn-next--choice-field.wrn-next--size-sm {
|
||||
font-size: 0.8125rem;
|
||||
}
|
||||
.wrn-next--field.wrn-next--size-lg,
|
||||
.wrn-next--choice-field.wrn-next--size-lg {
|
||||
font-size: 1rem;
|
||||
}
|
||||
.wrn-next__field-heading {
|
||||
display: flex;
|
||||
min-width: 0;
|
||||
align-items: baseline;
|
||||
justify-content: space-between;
|
||||
gap: 1rem;
|
||||
}
|
||||
.wrn-next__field-heading label {
|
||||
color: var(--wrn-color-text);
|
||||
font-weight: 600;
|
||||
}
|
||||
.wrn-next__field-hint,
|
||||
.wrn-next__field-help {
|
||||
color: var(--wrn-color-muted);
|
||||
font-size: 0.82em;
|
||||
font-weight: 500;
|
||||
}
|
||||
.wrn-next__field-control {
|
||||
position: relative;
|
||||
min-width: 0;
|
||||
}
|
||||
.wrn-next__field-control > :is(input, textarea, select) {
|
||||
padding-inline: 0.85rem;
|
||||
border-color: var(--wrn-color-border);
|
||||
border-radius: var(--wrn-radius-sm);
|
||||
background: var(--wrn-color-surface);
|
||||
font-size: 0.8125rem;
|
||||
}
|
||||
.wrn-next__field-control[data-icon-position="start"] > :is(input, textarea, select) {
|
||||
padding-inline-start: 2.5rem;
|
||||
}
|
||||
.wrn-next__field-control[data-icon-position="end"] > :is(input, textarea, select) {
|
||||
padding-inline-end: 2.5rem;
|
||||
}
|
||||
.wrn-next__field-icon {
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
top: 50%;
|
||||
left: 0.85rem;
|
||||
color: var(--wrn-color-muted);
|
||||
pointer-events: none;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
.wrn-next__field-control[data-icon-position="end"] > .wrn-next__field-icon {
|
||||
right: 0.85rem;
|
||||
left: auto;
|
||||
}
|
||||
.wrn-next--field[data-variant="outlined"]
|
||||
.wrn-next__field-control
|
||||
> :is(input, textarea, select) {
|
||||
border-width: 2px;
|
||||
}
|
||||
.wrn-next--field[data-variant="underline"]
|
||||
.wrn-next__field-control
|
||||
> :is(input, textarea, select) {
|
||||
padding-inline: 0;
|
||||
border-width: 0 0 1px;
|
||||
border-radius: 0;
|
||||
background: transparent;
|
||||
box-shadow: none;
|
||||
}
|
||||
.wrn-next--field[data-variant="pill"] .wrn-next__field-control > :is(input, select) {
|
||||
border-radius: 999px;
|
||||
padding-inline: 1.15rem;
|
||||
}
|
||||
.wrn-next--field[data-variant="ghost"] .wrn-next__field-control > :is(input, textarea, select) {
|
||||
border-color: transparent;
|
||||
background: color-mix(in srgb, var(--wrn-field-color) 8%, var(--wrn-color-surface));
|
||||
}
|
||||
.wrn-next__field-floating-label {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 0.85rem;
|
||||
color: var(--wrn-color-muted);
|
||||
pointer-events: none;
|
||||
transform: translateY(-50%);
|
||||
transition: 150ms ease;
|
||||
}
|
||||
.wrn-next--textarea .wrn-next__field-floating-label {
|
||||
top: 1.35rem;
|
||||
}
|
||||
.wrn-next--field[data-floating="true"] .wrn-next__field-control > :is(input, textarea, select) {
|
||||
padding-top: 1.2rem;
|
||||
padding-bottom: 0.3rem;
|
||||
}
|
||||
.wrn-next--field[data-floating="true"] .wrn-next__field-heading > label {
|
||||
position: absolute !important;
|
||||
width: 1px !important;
|
||||
height: 1px !important;
|
||||
overflow: hidden !important;
|
||||
margin: -1px !important;
|
||||
clip: rect(0, 0, 0, 0) !important;
|
||||
white-space: nowrap !important;
|
||||
}
|
||||
.wrn-next--field[data-floating="true"]
|
||||
.wrn-next__field-heading:not(:has(.wrn-next__field-hint)) {
|
||||
display: none;
|
||||
}
|
||||
.wrn-next--field[data-floating="true"]
|
||||
.wrn-next__field-control
|
||||
> :is(input, textarea):is(:focus, :not(:placeholder-shown))
|
||||
+ .wrn-next__field-floating-label {
|
||||
top: 0.42rem;
|
||||
font-size: 0.7em;
|
||||
transform: none;
|
||||
}
|
||||
.wrn-next__field-error {
|
||||
min-height: 1em;
|
||||
color: var(--wrn-color-danger);
|
||||
font-size: 0.82em;
|
||||
font-weight: 600;
|
||||
}
|
||||
.wrn-next__field-error:empty {
|
||||
display: none;
|
||||
}
|
||||
.wrn-next--field[data-invalid="true"] :is(input, textarea, select),
|
||||
.wrn-next--choice-field[data-invalid="true"] input {
|
||||
border-color: var(--wrn-color-danger);
|
||||
}
|
||||
.wrn-next--field :is(input, textarea, select):disabled,
|
||||
.wrn-next--choice-field input:disabled {
|
||||
cursor: not-allowed;
|
||||
opacity: 0.58;
|
||||
}
|
||||
.wrn-next--field :is(input, textarea, select):read-only {
|
||||
background: var(--wrn-color-surface-2);
|
||||
}
|
||||
.wrn-next--field[data-inline="true"],
|
||||
.wrn-next--choice-field[data-inline="true"] {
|
||||
display: grid;
|
||||
width: 100%;
|
||||
max-width: none;
|
||||
grid-template-columns: minmax(7rem, max-content) minmax(12rem, 20rem) minmax(10rem, 1fr);
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
.wrn-next--field[data-inline="true"] .wrn-next__field-heading,
|
||||
.wrn-next--choice-field[data-inline="true"] .wrn-next__field-heading {
|
||||
min-height: 2.65rem;
|
||||
align-items: center;
|
||||
}
|
||||
.wrn-next--field[data-inline="true"] .wrn-next__field-heading {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
.wrn-next--field[data-inline="true"] .wrn-next__field-help,
|
||||
.wrn-next--choice-field[data-inline="true"] .wrn-next__field-help {
|
||||
display: flex;
|
||||
min-height: 2.65rem;
|
||||
align-items: center;
|
||||
}
|
||||
.wrn-next--choice-field[data-inline="true"] {
|
||||
grid-template-columns: minmax(12rem, 20rem) minmax(10rem, 1fr);
|
||||
}
|
||||
.wrn-next--choice-field[data-inline="true"] .wrn-next__field-heading:empty {
|
||||
display: none;
|
||||
}
|
||||
.wrn-next--field[data-inline="true"] .wrn-next__field-error,
|
||||
.wrn-next--choice-field[data-inline="true"] .wrn-next__field-error {
|
||||
grid-column: 2 / -1;
|
||||
}
|
||||
.wrn-next__sr-only {
|
||||
position: absolute !important;
|
||||
width: 1px !important;
|
||||
height: 1px !important;
|
||||
overflow: hidden !important;
|
||||
padding: 0 !important;
|
||||
border: 0 !important;
|
||||
margin: -1px !important;
|
||||
clip: rect(0, 0, 0, 0) !important;
|
||||
white-space: nowrap !important;
|
||||
}
|
||||
.wrn-next__choice-field {
|
||||
display: grid;
|
||||
width: 100%;
|
||||
max-width: none;
|
||||
gap: 0.4rem;
|
||||
}
|
||||
.wrn-next__choice {
|
||||
display: flex;
|
||||
min-width: 0;
|
||||
align-items: center;
|
||||
gap: 0.65rem;
|
||||
color: var(--wrn-color-text);
|
||||
width: 100%;
|
||||
font-size: 0.75rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
.wrn-next__checkbox-content > .wrn-next__choice {
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
align-items: flex-start;
|
||||
}
|
||||
.wrn-next__choice input {
|
||||
flex: 0 0 auto;
|
||||
margin: 0;
|
||||
accent-color: var(--wrn-field-color);
|
||||
}
|
||||
.wrn-next__choice-copy {
|
||||
display: grid;
|
||||
min-width: 0;
|
||||
gap: 0.15rem;
|
||||
line-height: 1.35;
|
||||
}
|
||||
.wrn-next__choice-copy small {
|
||||
color: var(--wrn-color-muted);
|
||||
font-weight: 500;
|
||||
}
|
||||
.wrn-next__radio-group,
|
||||
.wrn-next__checkbox-group {
|
||||
display: grid;
|
||||
min-width: 0;
|
||||
gap: 0.65rem;
|
||||
}
|
||||
.wrn-next--radio-field[data-orientation="horizontal"] .wrn-next__radio-group,
|
||||
.wrn-next--checkbox-field[data-orientation="horizontal"] .wrn-next__checkbox-group {
|
||||
grid-template-columns: repeat(auto-fit, minmax(8rem, max-content));
|
||||
align-items: stretch;
|
||||
}
|
||||
.wrn-next--radio-field[data-card="true"] .wrn-next__radio-group,
|
||||
.wrn-next--checkbox-field[data-card="true"] .wrn-next__checkbox-group {
|
||||
grid-template-columns: repeat(auto-fit, minmax(min(100%, 12rem), 1fr));
|
||||
}
|
||||
.wrn-next--radio-field[data-card="true"] .wrn-next--radio,
|
||||
.wrn-next--checkbox-field[data-card="true"] .wrn-next--checkbox {
|
||||
min-height: 4.5rem;
|
||||
padding: 0.85rem;
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: var(--wrn-radius-sm);
|
||||
background: var(--wrn-color-surface);
|
||||
}
|
||||
.wrn-next--radio-field[data-card="true"] .wrn-next--radio:has(input:checked),
|
||||
.wrn-next--checkbox-field[data-card="true"] .wrn-next--checkbox:has(input:checked) {
|
||||
border-color: var(--wrn-field-color);
|
||||
box-shadow: 0 0 0 1px var(--wrn-field-color);
|
||||
}
|
||||
.wrn-next--radio-field[data-list="true"] .wrn-next--radio,
|
||||
.wrn-next--checkbox-field[data-list="true"] .wrn-next--checkbox {
|
||||
padding-block: 0.75rem;
|
||||
border-bottom: 1px solid var(--wrn-color-border);
|
||||
}
|
||||
.wrn-next--radio-field[data-right-aligned="true"] .wrn-next--radio,
|
||||
.wrn-next--checkbox-field[data-right-aligned="true"] .wrn-next--checkbox {
|
||||
justify-content: space-between;
|
||||
}
|
||||
.wrn-next--radio-field[data-right-aligned="true"] .wrn-next--radio input,
|
||||
.wrn-next--checkbox-field[data-right-aligned="true"] .wrn-next--checkbox input {
|
||||
order: 2;
|
||||
}
|
||||
.wrn-next--radio-field[data-right-aligned="true"] .wrn-next__choice-copy,
|
||||
.wrn-next--checkbox-field[data-right-aligned="true"] .wrn-next__choice-copy {
|
||||
order: 1;
|
||||
}
|
||||
.wrn-next__choice[data-variant="outlined"],
|
||||
.wrn-next__choice[data-variant="floating"] {
|
||||
padding: 0.65rem 0.8rem;
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: var(--wrn-radius-sm);
|
||||
}
|
||||
.wrn-next__choice[data-variant="pill"] {
|
||||
padding: 0.65rem 1rem;
|
||||
border-radius: 999px;
|
||||
background: color-mix(in srgb, var(--wrn-field-color) 9%, var(--wrn-color-surface));
|
||||
}
|
||||
.wrn-next__choice[data-variant="ghost"] {
|
||||
padding: 0.65rem 0.8rem;
|
||||
border-radius: var(--wrn-radius-sm);
|
||||
background: color-mix(in srgb, var(--wrn-field-color) 7%, transparent);
|
||||
}
|
||||
.wrn-next__choice[data-variant="underline"] {
|
||||
padding-block: 0.5rem;
|
||||
border-bottom: 1px solid var(--wrn-color-border);
|
||||
}
|
||||
.wrn-next--select .wrn-next__field-control {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.wrn-next__color-control,
|
||||
.wrn-next__range-control,
|
||||
.wrn-next__input-group-control,
|
||||
.wrn-next__file-control {
|
||||
display: flex;
|
||||
min-width: 0;
|
||||
align-items: center;
|
||||
gap: 0.65rem;
|
||||
}
|
||||
.wrn-next__picker-control,
|
||||
.wrn-next--time-picker .wrn-next__field-control {
|
||||
position: relative;
|
||||
display: flex;
|
||||
min-width: 0;
|
||||
align-items: center;
|
||||
}
|
||||
.wrn-next__picker-control > button:first-of-type,
|
||||
.wrn-next__time-trigger {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
min-height: 2.65rem;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 0.75rem;
|
||||
padding: 0.7rem 0.85rem;
|
||||
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;
|
||||
text-align: left;
|
||||
}
|
||||
.wrn-next__calendar,
|
||||
.wrn-next__time-panel {
|
||||
z-index: 20;
|
||||
display: grid;
|
||||
width: min(100%, 22rem);
|
||||
gap: 0.75rem;
|
||||
padding: 0.85rem;
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: var(--wrn-radius-md);
|
||||
background: var(--wrn-color-surface);
|
||||
box-shadow: var(--wrn-shadow-3);
|
||||
}
|
||||
.wrn-next--date-picker[data-expanded="false"] .wrn-next__calendar,
|
||||
.wrn-next--time-picker[data-expanded="false"] .wrn-next__time-panel {
|
||||
display: none;
|
||||
}
|
||||
.wrn-next__calendar button,
|
||||
.wrn-next__time-panel button {
|
||||
min-height: 2.25rem;
|
||||
border: 0;
|
||||
border-radius: var(--wrn-radius-sm);
|
||||
background: transparent;
|
||||
color: inherit;
|
||||
}
|
||||
.wrn-next__calendar-weekdays,
|
||||
.wrn-next__calendar-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(7, 1fr);
|
||||
gap: 0.2rem;
|
||||
text-align: center;
|
||||
}
|
||||
.wrn-next__calendar-weekdays {
|
||||
color: var(--wrn-color-muted);
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
.wrn-next__calendar-grid button:hover,
|
||||
.wrn-next__time-panel button:hover {
|
||||
background: var(--wrn-color-surface-2);
|
||||
}
|
||||
.wrn-next__calendar-grid button[aria-pressed="true"],
|
||||
.wrn-next__time-panel button[aria-pressed="true"] {
|
||||
background: var(--wrn-field-color);
|
||||
color: var(--wrn-color-primary-contrast, #fff);
|
||||
}
|
||||
.wrn-next__time-period {
|
||||
display: flex;
|
||||
gap: 0.35rem;
|
||||
}
|
||||
.wrn-next--file-upload-progress .wrn-next__row,
|
||||
.wrn-next__upload-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
.wrn-next--file-upload-progress .wrn-next__row > span {
|
||||
display: grid;
|
||||
min-width: 0;
|
||||
}
|
||||
.wrn-next--field[data-variant="underline"]
|
||||
:is(.wrn-next__input-group-control, .wrn-next__file-control, .wrn-next__color-control) {
|
||||
border-width: 0 0 1px;
|
||||
border-radius: 0;
|
||||
background: transparent;
|
||||
}
|
||||
.wrn-next--field[data-variant="outlined"]
|
||||
:is(.wrn-next__input-group-control, .wrn-next__file-control) {
|
||||
border-width: 2px;
|
||||
}
|
||||
.wrn-next--field[data-variant="pill"]
|
||||
:is(.wrn-next__input-group-control, .wrn-next__file-control) {
|
||||
border-radius: 999px;
|
||||
}
|
||||
.wrn-next--field[data-variant="ghost"]
|
||||
:is(.wrn-next__input-group-control, .wrn-next__file-control, .wrn-next__color-control) {
|
||||
border-color: transparent;
|
||||
background: color-mix(in srgb, var(--wrn-field-color) 8%, var(--wrn-color-surface));
|
||||
}
|
||||
@media (max-width: 640px) {
|
||||
.wrn-next--field[data-inline="true"],
|
||||
.wrn-next--choice-field[data-inline="true"] {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.wrn-next--field[data-inline="true"] .wrn-next__field-error,
|
||||
.wrn-next--choice-field[data-inline="true"] .wrn-next__field-error {
|
||||
grid-column: auto;
|
||||
}
|
||||
}
|
||||
.wrn-next--toggle-password:has(input.wrn-invalid) .wrn-next__password-control > input,
|
||||
.wrn-next--toggle-password.wrn-next--invalid .wrn-next__password-control > input {
|
||||
border-color: var(--wrn-color-danger);
|
||||
box-shadow: 0 0 0 3px color-mix(in srgb, var(--wrn-color-danger) 14%, transparent);
|
||||
}
|
||||
.wrn-next--strong-password.wrn-next--invalid input,
|
||||
.wrn-next--strong-password input.wrn-invalid {
|
||||
border-color: var(--wrn-color-danger);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
import FieldStyles from "../styles/FieldStyles.wrn"
|
||||
|
||||
import ComponentBaseStyles from "../styles/ComponentBaseStyles.wrn"
|
||||
|
||||
component FileUploadProgress {
|
||||
outputs {
|
||||
cancel(payload: { sourceEvent?: Event; value: string | number | boolean | null | object; [key: string]: string | number | boolean | null | object } | string | number | boolean | null | object[])
|
||||
@@ -34,60 +30,617 @@ size: string = "default"
|
||||
client function completeUpload(sourceEvent) { currentValue = max; currentStatus = "complete"; output.complete(detail(sourceEvent)) }
|
||||
}
|
||||
view {
|
||||
<div {...attrs} class="wire-component wire-component--color-{color} wire-component--size-{size} wire-next--file-upload-progress {class}" data-status="{currentStatus}" aria-live="polite">
|
||||
<div class="wire-next__row"><span>{#if fileName}<strong>{fileName}</strong><small>{#if uploadedSize || fileSize}{uploadedSize}{#if uploadedSize && fileSize} of {/if}{fileSize}{:else}{label}{/if}</small>{:else}<strong>{label}</strong>{/if}</span>{#if showValue}<strong>{percent()}%</strong>{/if}</div>
|
||||
<div {...attrs} class="wrn-component wrn-component--color-{color} wrn-component--size-{size} wrn-next--file-upload-progress {class}" data-status="{currentStatus}" aria-live="polite">
|
||||
<div class="wrn-next__row"><span>{#if fileName}<strong>{fileName}</strong><small>{#if uploadedSize || fileSize}{uploadedSize}{#if uploadedSize && fileSize} of {/if}{fileSize}{:else}{label}{/if}</small>{:else}<strong>{label}</strong>{/if}</span>{#if showValue}<strong>{percent()}%</strong>{/if}</div>
|
||||
<progress value="{currentValue}" max="{max}" aria-label="{label}"></progress>
|
||||
<div class="wire-next__upload-status"><span class="wire-next__upload-status-icon" aria-hidden="true"></span><span>{#if currentStatus === "uploading"}Uploading securely…{:else if currentStatus === "complete"}Upload complete{:else if currentStatus === "error"}Upload failed{:else}Upload cancelled{/if}</span></div>
|
||||
<div class="wire-next__upload-actions">{#if currentStatus === "uploading"}<button type="button" @click="cancelUpload(event)">{cancelLabel}</button><button type="button" @click="completeUpload(event)">Complete</button>{/if}{#if currentStatus === "error" || currentStatus === "cancelled"}<button type="button" @click="retryUpload(event)">{retryLabel}</button>{/if}</div>
|
||||
<div class="wrn-next__upload-status"><span class="wrn-next__upload-status-icon" aria-hidden="true"></span><span>{#if currentStatus === "uploading"}Uploading securely…{:else if currentStatus === "complete"}Upload complete{:else if currentStatus === "error"}Upload failed{:else}Upload cancelled{/if}</span></div>
|
||||
<div class="wrn-next__upload-actions">{#if currentStatus === "uploading"}<button type="button" @click="cancelUpload(event)">{cancelLabel}</button><button type="button" @click="completeUpload(event)">Complete</button>{/if}{#if currentStatus === "error" || currentStatus === "cancelled"}<button type="button" @click="retryUpload(event)">{retryLabel}</button>{/if}</div>
|
||||
</div>
|
||||
<FieldStyles hidden />
|
||||
<ComponentBaseStyles hidden />
|
||||
}
|
||||
|
||||
style {
|
||||
.wire-next__row {
|
||||
.wrn-next__row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.wire-next--file-upload-progress progress {
|
||||
.wrn-next--file-upload-progress progress {
|
||||
width: 100%;
|
||||
accent-color: var(--wire-color-primary);
|
||||
accent-color: var(--wrn-color-primary);
|
||||
}
|
||||
|
||||
.wire-next--file-upload-progress {
|
||||
.wrn-next--file-upload-progress {
|
||||
display: grid;
|
||||
width: min(100%, 36rem);
|
||||
gap: 0.75rem;
|
||||
padding: 1rem;
|
||||
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);
|
||||
}
|
||||
|
||||
.wire-next--file-upload-progress progress {
|
||||
.wrn-next--file-upload-progress progress {
|
||||
width: 100%;
|
||||
height: 0.55rem;
|
||||
overflow: hidden;
|
||||
border: 0;
|
||||
border-radius: 999px;
|
||||
accent-color: var(--wire-component-color);
|
||||
accent-color: var(--wrn-component-color);
|
||||
}
|
||||
|
||||
.wire-next__upload-actions {
|
||||
.wrn-next__upload-actions {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.wire-next__upload-actions button {
|
||||
.wrn-next__upload-actions button {
|
||||
min-height: 2.25rem;
|
||||
padding-inline: 0.8rem;
|
||||
border: 1px solid var(--wire-color-border);
|
||||
border-radius: var(--wire-radius-sm);
|
||||
background: var(--wire-color-surface-2);
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: var(--wrn-radius-sm);
|
||||
background: var(--wrn-color-surface-2);
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
/* Shared component foundation. */
|
||||
|
||||
.wrn-component {
|
||||
--wrn-component-color: var(--wrn-color-primary);
|
||||
--wrn-component-scale: 1;
|
||||
margin: 0;
|
||||
color: var(--wrn-color-text);
|
||||
font-family: var(--wrn-font-sans, inherit);
|
||||
}
|
||||
|
||||
.wrn-component--color-primary {
|
||||
--wrn-component-color: var(--wrn-color-primary);
|
||||
}
|
||||
|
||||
.wrn-component--color-secondary {
|
||||
--wrn-component-color: var(--wrn-color-secondary);
|
||||
}
|
||||
|
||||
.wrn-component--color-success {
|
||||
--wrn-component-color: var(--wrn-color-success);
|
||||
}
|
||||
|
||||
.wrn-component--color-warning {
|
||||
--wrn-component-color: var(--wrn-color-warning);
|
||||
}
|
||||
|
||||
.wrn-component--color-danger {
|
||||
--wrn-component-color: var(--wrn-color-danger);
|
||||
}
|
||||
|
||||
.wrn-component--color-info {
|
||||
--wrn-component-color: var(--wrn-color-info);
|
||||
}
|
||||
|
||||
.wrn-component--size-xs {
|
||||
--wrn-component-scale: 0.78;
|
||||
}
|
||||
|
||||
.wrn-component--size-sm {
|
||||
--wrn-component-scale: 0.88;
|
||||
}
|
||||
|
||||
.wrn-component--size-default,
|
||||
.wrn-component--size-md {
|
||||
--wrn-component-scale: 1;
|
||||
}
|
||||
|
||||
.wrn-component--size-lg {
|
||||
--wrn-component-scale: 1.14;
|
||||
}
|
||||
|
||||
.wrn-component--size-xl {
|
||||
--wrn-component-scale: 1.28;
|
||||
}
|
||||
|
||||
.wrn-component:not(.wrn-btn) {
|
||||
font-size: calc(1em * var(--wrn-component-scale));
|
||||
}
|
||||
|
||||
.wrn-component :is(a, button, input, select, textarea):focus-visible {
|
||||
outline-color: var(--wrn-component-color);
|
||||
}
|
||||
|
||||
.wrn-component p {
|
||||
margin: 0;
|
||||
color: var(--wrn-color-muted);
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
/* Shared field foundation. */
|
||||
|
||||
/* Validation states set by the browser validation runtime. */
|
||||
.wrn-invalid {
|
||||
border-color: var(--wrn-color-danger) !important;
|
||||
}
|
||||
|
||||
.wrn-field-error {
|
||||
display: block;
|
||||
min-height: 1em;
|
||||
margin-top: 0.25rem;
|
||||
color: var(--wrn-color-danger);
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
.wrn-next--choice {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.55rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.wrn-next--choice input {
|
||||
width: 1.1rem;
|
||||
height: 1.1rem;
|
||||
accent-color: var(--wrn-color-primary);
|
||||
}
|
||||
|
||||
.wrn-next--field {
|
||||
display: grid;
|
||||
width: min(100%, 28rem);
|
||||
gap: 0.4rem;
|
||||
font-size: 0.78rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
.wrn-next--field :where(input, textarea, select) {
|
||||
width: 100%;
|
||||
min-height: 2.65rem;
|
||||
padding: 0.6rem 0.7rem;
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: 0.6rem;
|
||||
outline: 0;
|
||||
color: var(--wrn-color-text);
|
||||
background: var(--wrn-color-bg);
|
||||
font: inherit;
|
||||
font-weight: 500;
|
||||
}
|
||||
.wrn-auth-form form > .wrn-next--field,
|
||||
.wrn-auth-form form > .wrn-field {
|
||||
width: 100%;
|
||||
max-width: none;
|
||||
}
|
||||
.wrn-auth-form__submit > .wrn-btn {
|
||||
width: 100%;
|
||||
min-height: 3rem;
|
||||
border-radius: 0.75rem;
|
||||
box-shadow: 0 0.8rem 1.8rem color-mix(in srgb, var(--wrn-btn-color) 20%, transparent);
|
||||
}
|
||||
.wrn-next--field :where(input, textarea, select):focus-visible {
|
||||
border-color: var(--wrn-color-primary);
|
||||
box-shadow: 0 0 0 3px color-mix(in srgb, var(--wrn-color-primary) 16%, transparent);
|
||||
}
|
||||
.wrn-next--field textarea {
|
||||
resize: vertical;
|
||||
}
|
||||
.wrn-next--field,
|
||||
.wrn-next--choice-field {
|
||||
--wrn-field-color: var(--wrn-component-color, var(--wrn-color-primary));
|
||||
width: min(100%, 34rem);
|
||||
min-width: 0;
|
||||
color: var(--wrn-color-text);
|
||||
font-size: 0.8125rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
.wrn-next--field.wrn-next--size-sm,
|
||||
.wrn-next--choice-field.wrn-next--size-sm {
|
||||
font-size: 0.8125rem;
|
||||
}
|
||||
.wrn-next--field.wrn-next--size-lg,
|
||||
.wrn-next--choice-field.wrn-next--size-lg {
|
||||
font-size: 1rem;
|
||||
}
|
||||
.wrn-next__field-heading {
|
||||
display: flex;
|
||||
min-width: 0;
|
||||
align-items: baseline;
|
||||
justify-content: space-between;
|
||||
gap: 1rem;
|
||||
}
|
||||
.wrn-next__field-heading label {
|
||||
color: var(--wrn-color-text);
|
||||
font-weight: 600;
|
||||
}
|
||||
.wrn-next__field-hint,
|
||||
.wrn-next__field-help {
|
||||
color: var(--wrn-color-muted);
|
||||
font-size: 0.82em;
|
||||
font-weight: 500;
|
||||
}
|
||||
.wrn-next__field-control {
|
||||
position: relative;
|
||||
min-width: 0;
|
||||
}
|
||||
.wrn-next__field-control > :is(input, textarea, select) {
|
||||
padding-inline: 0.85rem;
|
||||
border-color: var(--wrn-color-border);
|
||||
border-radius: var(--wrn-radius-sm);
|
||||
background: var(--wrn-color-surface);
|
||||
font-size: 0.8125rem;
|
||||
}
|
||||
.wrn-next__field-control[data-icon-position="start"] > :is(input, textarea, select) {
|
||||
padding-inline-start: 2.5rem;
|
||||
}
|
||||
.wrn-next__field-control[data-icon-position="end"] > :is(input, textarea, select) {
|
||||
padding-inline-end: 2.5rem;
|
||||
}
|
||||
.wrn-next__field-icon {
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
top: 50%;
|
||||
left: 0.85rem;
|
||||
color: var(--wrn-color-muted);
|
||||
pointer-events: none;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
.wrn-next__field-control[data-icon-position="end"] > .wrn-next__field-icon {
|
||||
right: 0.85rem;
|
||||
left: auto;
|
||||
}
|
||||
.wrn-next--field[data-variant="outlined"]
|
||||
.wrn-next__field-control
|
||||
> :is(input, textarea, select) {
|
||||
border-width: 2px;
|
||||
}
|
||||
.wrn-next--field[data-variant="underline"]
|
||||
.wrn-next__field-control
|
||||
> :is(input, textarea, select) {
|
||||
padding-inline: 0;
|
||||
border-width: 0 0 1px;
|
||||
border-radius: 0;
|
||||
background: transparent;
|
||||
box-shadow: none;
|
||||
}
|
||||
.wrn-next--field[data-variant="pill"] .wrn-next__field-control > :is(input, select) {
|
||||
border-radius: 999px;
|
||||
padding-inline: 1.15rem;
|
||||
}
|
||||
.wrn-next--field[data-variant="ghost"] .wrn-next__field-control > :is(input, textarea, select) {
|
||||
border-color: transparent;
|
||||
background: color-mix(in srgb, var(--wrn-field-color) 8%, var(--wrn-color-surface));
|
||||
}
|
||||
.wrn-next__field-floating-label {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 0.85rem;
|
||||
color: var(--wrn-color-muted);
|
||||
pointer-events: none;
|
||||
transform: translateY(-50%);
|
||||
transition: 150ms ease;
|
||||
}
|
||||
.wrn-next--textarea .wrn-next__field-floating-label {
|
||||
top: 1.35rem;
|
||||
}
|
||||
.wrn-next--field[data-floating="true"] .wrn-next__field-control > :is(input, textarea, select) {
|
||||
padding-top: 1.2rem;
|
||||
padding-bottom: 0.3rem;
|
||||
}
|
||||
.wrn-next--field[data-floating="true"] .wrn-next__field-heading > label {
|
||||
position: absolute !important;
|
||||
width: 1px !important;
|
||||
height: 1px !important;
|
||||
overflow: hidden !important;
|
||||
margin: -1px !important;
|
||||
clip: rect(0, 0, 0, 0) !important;
|
||||
white-space: nowrap !important;
|
||||
}
|
||||
.wrn-next--field[data-floating="true"]
|
||||
.wrn-next__field-heading:not(:has(.wrn-next__field-hint)) {
|
||||
display: none;
|
||||
}
|
||||
.wrn-next--field[data-floating="true"]
|
||||
.wrn-next__field-control
|
||||
> :is(input, textarea):is(:focus, :not(:placeholder-shown))
|
||||
+ .wrn-next__field-floating-label {
|
||||
top: 0.42rem;
|
||||
font-size: 0.7em;
|
||||
transform: none;
|
||||
}
|
||||
.wrn-next__field-error {
|
||||
min-height: 1em;
|
||||
color: var(--wrn-color-danger);
|
||||
font-size: 0.82em;
|
||||
font-weight: 600;
|
||||
}
|
||||
.wrn-next__field-error:empty {
|
||||
display: none;
|
||||
}
|
||||
.wrn-next--field[data-invalid="true"] :is(input, textarea, select),
|
||||
.wrn-next--choice-field[data-invalid="true"] input {
|
||||
border-color: var(--wrn-color-danger);
|
||||
}
|
||||
.wrn-next--field :is(input, textarea, select):disabled,
|
||||
.wrn-next--choice-field input:disabled {
|
||||
cursor: not-allowed;
|
||||
opacity: 0.58;
|
||||
}
|
||||
.wrn-next--field :is(input, textarea, select):read-only {
|
||||
background: var(--wrn-color-surface-2);
|
||||
}
|
||||
.wrn-next--field[data-inline="true"],
|
||||
.wrn-next--choice-field[data-inline="true"] {
|
||||
display: grid;
|
||||
width: 100%;
|
||||
max-width: none;
|
||||
grid-template-columns: minmax(7rem, max-content) minmax(12rem, 20rem) minmax(10rem, 1fr);
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
.wrn-next--field[data-inline="true"] .wrn-next__field-heading,
|
||||
.wrn-next--choice-field[data-inline="true"] .wrn-next__field-heading {
|
||||
min-height: 2.65rem;
|
||||
align-items: center;
|
||||
}
|
||||
.wrn-next--field[data-inline="true"] .wrn-next__field-heading {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
.wrn-next--field[data-inline="true"] .wrn-next__field-help,
|
||||
.wrn-next--choice-field[data-inline="true"] .wrn-next__field-help {
|
||||
display: flex;
|
||||
min-height: 2.65rem;
|
||||
align-items: center;
|
||||
}
|
||||
.wrn-next--choice-field[data-inline="true"] {
|
||||
grid-template-columns: minmax(12rem, 20rem) minmax(10rem, 1fr);
|
||||
}
|
||||
.wrn-next--choice-field[data-inline="true"] .wrn-next__field-heading:empty {
|
||||
display: none;
|
||||
}
|
||||
.wrn-next--field[data-inline="true"] .wrn-next__field-error,
|
||||
.wrn-next--choice-field[data-inline="true"] .wrn-next__field-error {
|
||||
grid-column: 2 / -1;
|
||||
}
|
||||
.wrn-next__sr-only {
|
||||
position: absolute !important;
|
||||
width: 1px !important;
|
||||
height: 1px !important;
|
||||
overflow: hidden !important;
|
||||
padding: 0 !important;
|
||||
border: 0 !important;
|
||||
margin: -1px !important;
|
||||
clip: rect(0, 0, 0, 0) !important;
|
||||
white-space: nowrap !important;
|
||||
}
|
||||
.wrn-next__choice-field {
|
||||
display: grid;
|
||||
width: 100%;
|
||||
max-width: none;
|
||||
gap: 0.4rem;
|
||||
}
|
||||
.wrn-next__choice {
|
||||
display: flex;
|
||||
min-width: 0;
|
||||
align-items: center;
|
||||
gap: 0.65rem;
|
||||
color: var(--wrn-color-text);
|
||||
width: 100%;
|
||||
font-size: 0.75rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
.wrn-next__checkbox-content > .wrn-next__choice {
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
align-items: flex-start;
|
||||
}
|
||||
.wrn-next__choice input {
|
||||
flex: 0 0 auto;
|
||||
margin: 0;
|
||||
accent-color: var(--wrn-field-color);
|
||||
}
|
||||
.wrn-next__choice-copy {
|
||||
display: grid;
|
||||
min-width: 0;
|
||||
gap: 0.15rem;
|
||||
line-height: 1.35;
|
||||
}
|
||||
.wrn-next__choice-copy small {
|
||||
color: var(--wrn-color-muted);
|
||||
font-weight: 500;
|
||||
}
|
||||
.wrn-next__radio-group,
|
||||
.wrn-next__checkbox-group {
|
||||
display: grid;
|
||||
min-width: 0;
|
||||
gap: 0.65rem;
|
||||
}
|
||||
.wrn-next--radio-field[data-orientation="horizontal"] .wrn-next__radio-group,
|
||||
.wrn-next--checkbox-field[data-orientation="horizontal"] .wrn-next__checkbox-group {
|
||||
grid-template-columns: repeat(auto-fit, minmax(8rem, max-content));
|
||||
align-items: stretch;
|
||||
}
|
||||
.wrn-next--radio-field[data-card="true"] .wrn-next__radio-group,
|
||||
.wrn-next--checkbox-field[data-card="true"] .wrn-next__checkbox-group {
|
||||
grid-template-columns: repeat(auto-fit, minmax(min(100%, 12rem), 1fr));
|
||||
}
|
||||
.wrn-next--radio-field[data-card="true"] .wrn-next--radio,
|
||||
.wrn-next--checkbox-field[data-card="true"] .wrn-next--checkbox {
|
||||
min-height: 4.5rem;
|
||||
padding: 0.85rem;
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: var(--wrn-radius-sm);
|
||||
background: var(--wrn-color-surface);
|
||||
}
|
||||
.wrn-next--radio-field[data-card="true"] .wrn-next--radio:has(input:checked),
|
||||
.wrn-next--checkbox-field[data-card="true"] .wrn-next--checkbox:has(input:checked) {
|
||||
border-color: var(--wrn-field-color);
|
||||
box-shadow: 0 0 0 1px var(--wrn-field-color);
|
||||
}
|
||||
.wrn-next--radio-field[data-list="true"] .wrn-next--radio,
|
||||
.wrn-next--checkbox-field[data-list="true"] .wrn-next--checkbox {
|
||||
padding-block: 0.75rem;
|
||||
border-bottom: 1px solid var(--wrn-color-border);
|
||||
}
|
||||
.wrn-next--radio-field[data-right-aligned="true"] .wrn-next--radio,
|
||||
.wrn-next--checkbox-field[data-right-aligned="true"] .wrn-next--checkbox {
|
||||
justify-content: space-between;
|
||||
}
|
||||
.wrn-next--radio-field[data-right-aligned="true"] .wrn-next--radio input,
|
||||
.wrn-next--checkbox-field[data-right-aligned="true"] .wrn-next--checkbox input {
|
||||
order: 2;
|
||||
}
|
||||
.wrn-next--radio-field[data-right-aligned="true"] .wrn-next__choice-copy,
|
||||
.wrn-next--checkbox-field[data-right-aligned="true"] .wrn-next__choice-copy {
|
||||
order: 1;
|
||||
}
|
||||
.wrn-next__choice[data-variant="outlined"],
|
||||
.wrn-next__choice[data-variant="floating"] {
|
||||
padding: 0.65rem 0.8rem;
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: var(--wrn-radius-sm);
|
||||
}
|
||||
.wrn-next__choice[data-variant="pill"] {
|
||||
padding: 0.65rem 1rem;
|
||||
border-radius: 999px;
|
||||
background: color-mix(in srgb, var(--wrn-field-color) 9%, var(--wrn-color-surface));
|
||||
}
|
||||
.wrn-next__choice[data-variant="ghost"] {
|
||||
padding: 0.65rem 0.8rem;
|
||||
border-radius: var(--wrn-radius-sm);
|
||||
background: color-mix(in srgb, var(--wrn-field-color) 7%, transparent);
|
||||
}
|
||||
.wrn-next__choice[data-variant="underline"] {
|
||||
padding-block: 0.5rem;
|
||||
border-bottom: 1px solid var(--wrn-color-border);
|
||||
}
|
||||
.wrn-next--select .wrn-next__field-control {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.wrn-next__color-control,
|
||||
.wrn-next__range-control,
|
||||
.wrn-next__input-group-control,
|
||||
.wrn-next__file-control {
|
||||
display: flex;
|
||||
min-width: 0;
|
||||
align-items: center;
|
||||
gap: 0.65rem;
|
||||
}
|
||||
.wrn-next__picker-control,
|
||||
.wrn-next--time-picker .wrn-next__field-control {
|
||||
position: relative;
|
||||
display: flex;
|
||||
min-width: 0;
|
||||
align-items: center;
|
||||
}
|
||||
.wrn-next__picker-control > button:first-of-type,
|
||||
.wrn-next__time-trigger {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
min-height: 2.65rem;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 0.75rem;
|
||||
padding: 0.7rem 0.85rem;
|
||||
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;
|
||||
text-align: left;
|
||||
}
|
||||
.wrn-next__calendar,
|
||||
.wrn-next__time-panel {
|
||||
z-index: 20;
|
||||
display: grid;
|
||||
width: min(100%, 22rem);
|
||||
gap: 0.75rem;
|
||||
padding: 0.85rem;
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: var(--wrn-radius-md);
|
||||
background: var(--wrn-color-surface);
|
||||
box-shadow: var(--wrn-shadow-3);
|
||||
}
|
||||
.wrn-next--date-picker[data-expanded="false"] .wrn-next__calendar,
|
||||
.wrn-next--time-picker[data-expanded="false"] .wrn-next__time-panel {
|
||||
display: none;
|
||||
}
|
||||
.wrn-next__calendar button,
|
||||
.wrn-next__time-panel button {
|
||||
min-height: 2.25rem;
|
||||
border: 0;
|
||||
border-radius: var(--wrn-radius-sm);
|
||||
background: transparent;
|
||||
color: inherit;
|
||||
}
|
||||
.wrn-next__calendar-weekdays,
|
||||
.wrn-next__calendar-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(7, 1fr);
|
||||
gap: 0.2rem;
|
||||
text-align: center;
|
||||
}
|
||||
.wrn-next__calendar-weekdays {
|
||||
color: var(--wrn-color-muted);
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
.wrn-next__calendar-grid button:hover,
|
||||
.wrn-next__time-panel button:hover {
|
||||
background: var(--wrn-color-surface-2);
|
||||
}
|
||||
.wrn-next__calendar-grid button[aria-pressed="true"],
|
||||
.wrn-next__time-panel button[aria-pressed="true"] {
|
||||
background: var(--wrn-field-color);
|
||||
color: var(--wrn-color-primary-contrast, #fff);
|
||||
}
|
||||
.wrn-next__time-period {
|
||||
display: flex;
|
||||
gap: 0.35rem;
|
||||
}
|
||||
.wrn-next--file-upload-progress .wrn-next__row,
|
||||
.wrn-next__upload-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
.wrn-next--file-upload-progress .wrn-next__row > span {
|
||||
display: grid;
|
||||
min-width: 0;
|
||||
}
|
||||
.wrn-next--field[data-variant="underline"]
|
||||
:is(.wrn-next__input-group-control, .wrn-next__file-control, .wrn-next__color-control) {
|
||||
border-width: 0 0 1px;
|
||||
border-radius: 0;
|
||||
background: transparent;
|
||||
}
|
||||
.wrn-next--field[data-variant="outlined"]
|
||||
:is(.wrn-next__input-group-control, .wrn-next__file-control) {
|
||||
border-width: 2px;
|
||||
}
|
||||
.wrn-next--field[data-variant="pill"]
|
||||
:is(.wrn-next__input-group-control, .wrn-next__file-control) {
|
||||
border-radius: 999px;
|
||||
}
|
||||
.wrn-next--field[data-variant="ghost"]
|
||||
:is(.wrn-next__input-group-control, .wrn-next__file-control, .wrn-next__color-control) {
|
||||
border-color: transparent;
|
||||
background: color-mix(in srgb, var(--wrn-field-color) 8%, var(--wrn-color-surface));
|
||||
}
|
||||
@media (max-width: 640px) {
|
||||
.wrn-next--field[data-inline="true"],
|
||||
.wrn-next--choice-field[data-inline="true"] {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.wrn-next--field[data-inline="true"] .wrn-next__field-error,
|
||||
.wrn-next--choice-field[data-inline="true"] .wrn-next__field-error {
|
||||
grid-column: auto;
|
||||
}
|
||||
}
|
||||
.wrn-next--toggle-password:has(input.wrn-invalid) .wrn-next__password-control > input,
|
||||
.wrn-next--toggle-password.wrn-next--invalid .wrn-next__password-control > input {
|
||||
border-color: var(--wrn-color-danger);
|
||||
box-shadow: 0 0 0 3px color-mix(in srgb, var(--wrn-color-danger) 14%, transparent);
|
||||
}
|
||||
.wrn-next--strong-password.wrn-next--invalid input,
|
||||
.wrn-next--strong-password input.wrn-invalid {
|
||||
border-color: var(--wrn-color-danger);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,14 +26,14 @@ component Image {
|
||||
<figure
|
||||
{...attrs}
|
||||
data-ui-component="Image"
|
||||
class='wire-image {class}'
|
||||
class='wrn-image {class}'
|
||||
data-size='{size}'
|
||||
data-color='{color}'
|
||||
data-fit='{fit}'
|
||||
data-rounded='{rounded}'
|
||||
>
|
||||
<img
|
||||
class="wire-image__img"
|
||||
class="wrn-image__img"
|
||||
data-show="src"
|
||||
src='{src}'
|
||||
alt='{alt}'
|
||||
@@ -44,12 +44,12 @@ component Image {
|
||||
/>
|
||||
|
||||
<div
|
||||
class="wire-image__placeholder"
|
||||
class="wrn-image__placeholder"
|
||||
data-show="!src"
|
||||
role="img"
|
||||
aria-label='{alt || "Image placeholder"}'
|
||||
>
|
||||
<span class="icon-[lucide--image] wire-image__placeholder-icon" aria-hidden="true"></span>
|
||||
<span class="icon-[lucide--image] wrn-image__placeholder-icon" aria-hidden="true"></span>
|
||||
</div>
|
||||
|
||||
<slot></slot>
|
||||
@@ -57,69 +57,69 @@ component Image {
|
||||
}
|
||||
|
||||
style {
|
||||
.wire-image {
|
||||
.wrn-image {
|
||||
position: relative;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
background: var(--wire-color-surface-soft);
|
||||
background: var(--wrn-color-surface-soft);
|
||||
}
|
||||
|
||||
.wire-image[data-rounded="true"] {
|
||||
border-radius: var(--wire-radius-lg);
|
||||
.wrn-image[data-rounded="true"] {
|
||||
border-radius: var(--wrn-radius-lg);
|
||||
}
|
||||
|
||||
/*
|
||||
* The ratio sits on the frame rather than the image, so the space is
|
||||
* reserved before the file arrives and the page does not jump.
|
||||
*/
|
||||
.wire-image[data-size="square"] {
|
||||
.wrn-image[data-size="square"] {
|
||||
aspect-ratio: 1 / 1;
|
||||
}
|
||||
|
||||
.wire-image[data-size="video"] {
|
||||
.wrn-image[data-size="video"] {
|
||||
aspect-ratio: 16 / 9;
|
||||
}
|
||||
|
||||
.wire-image[data-size="landscape"] {
|
||||
.wrn-image[data-size="landscape"] {
|
||||
aspect-ratio: 4 / 3;
|
||||
}
|
||||
|
||||
.wire-image[data-size="portrait"] {
|
||||
.wrn-image[data-size="portrait"] {
|
||||
aspect-ratio: 3 / 4;
|
||||
}
|
||||
|
||||
.wire-image__img {
|
||||
.wrn-image__img {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.wire-image[data-fit="contain"] .wire-image__img {
|
||||
.wrn-image[data-fit="contain"] .wrn-image__img {
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.wire-image[data-fit="fill"] .wire-image__img {
|
||||
.wrn-image[data-fit="fill"] .wrn-image__img {
|
||||
object-fit: fill;
|
||||
}
|
||||
|
||||
.wire-image[data-size="default"] .wire-image__img {
|
||||
.wrn-image[data-size="default"] .wrn-image__img {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.wire-image__placeholder {
|
||||
.wrn-image__placeholder {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
min-height: 12rem;
|
||||
height: 100%;
|
||||
color: var(--wire-color-text-muted);
|
||||
color: var(--wrn-color-text-muted);
|
||||
}
|
||||
|
||||
.wire-image__placeholder-icon {
|
||||
.wrn-image__placeholder-icon {
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
import FieldStyles from "../styles/FieldStyles.wrn"
|
||||
|
||||
import ComponentBaseStyles from "../styles/ComponentBaseStyles.wrn"
|
||||
|
||||
component InputGroup {
|
||||
outputs {
|
||||
input(payload: { value?: string | number | boolean | null; values?: Array<string | number | boolean | null | object>; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | string | number | boolean | null)
|
||||
@@ -43,50 +39,607 @@ component InputGroup {
|
||||
client function handleAction(sourceEvent) { output.action({ name: name, sourceEvent: sourceEvent }) }
|
||||
}
|
||||
view {
|
||||
<div {...attrs} class="wire-component wire-component--color-{color} wire-component--size-{size} wire-next--field wire-next--input-group {class}" data-variant="{variant}" data-inline="{inline}" data-invalid="{error ? 'true' : 'false'}">
|
||||
<div class="wire-next__field-heading"><label class="{hiddenLabel ? 'wire-next__sr-only' : ''}" for="{id || name}">{label}</label>{#if cornerHint}<span class="wire-next__field-hint">{cornerHint}</span>{/if}</div>
|
||||
<div class="wire-next__input-group-control">
|
||||
{#if startText}<span class="wire-next__input-addon">{startText}</span>{/if}
|
||||
{#if icon}<span class="{icon} wire-next__field-icon" data-position="{iconPosition}" aria-hidden="true"></span>{/if}
|
||||
<div {...attrs} class="wrn-component wrn-component--color-{color} wrn-component--size-{size} wrn-next--field wrn-next--input-group {class}" data-variant="{variant}" data-inline="{inline}" data-invalid="{error ? 'true' : 'false'}">
|
||||
<div class="wrn-next__field-heading"><label class="{hiddenLabel ? 'wrn-next__sr-only' : ''}" for="{id || name}">{label}</label>{#if cornerHint}<span class="wrn-next__field-hint">{cornerHint}</span>{/if}</div>
|
||||
<div class="wrn-next__input-group-control">
|
||||
{#if startText}<span class="wrn-next__input-addon">{startText}</span>{/if}
|
||||
{#if icon}<span class="{icon} wrn-next__field-icon" data-position="{iconPosition}" aria-hidden="true"></span>{/if}
|
||||
<input id="{id || name}" type="{type}" name="{name}" value="{value}" placeholder="{placeholder}" readonly="{readonly}" disabled="{disabled}" required="{required}" aria-invalid="{error ? 'true' : 'false'}" @input="emitField('input', event)" @change="emitField('change', event)" @focus="emitField('focus', event)" @blur="emitField('blur', event)" @keydown="handleKeydown(event)" />
|
||||
{#if endText}<span class="wire-next__input-addon">{endText}</span>{/if}
|
||||
{#if endText}<span class="wrn-next__input-addon">{endText}</span>{/if}
|
||||
{#if actionLabel}<button type="button" disabled="{disabled}" @click="handleAction(event)">{actionLabel}</button>{/if}
|
||||
</div>
|
||||
{#if helperText}<small class="wire-next__field-help">{helperText}</small>{/if}<small class="wire-next__field-error" data-error="{name}">{error}</small>
|
||||
{#if helperText}<small class="wrn-next__field-help">{helperText}</small>{/if}<small class="wrn-next__field-error" data-error="{name}">{error}</small>
|
||||
</div>
|
||||
<FieldStyles hidden />
|
||||
<ComponentBaseStyles hidden />
|
||||
}
|
||||
|
||||
style {
|
||||
.wire-next__input-group-control {
|
||||
.wrn-next__input-group-control {
|
||||
overflow: hidden;
|
||||
border: 1px solid var(--wire-color-border);
|
||||
border-radius: var(--wire-radius-sm);
|
||||
background: var(--wire-color-surface);
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: var(--wrn-radius-sm);
|
||||
background: var(--wrn-color-surface);
|
||||
}
|
||||
|
||||
.wire-next__input-group-control input {
|
||||
.wrn-next__input-group-control input {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
border: 0;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.wire-next__input-addon,
|
||||
.wire-next__input-group-control button {
|
||||
.wrn-next__input-addon,
|
||||
.wrn-next__input-group-control button {
|
||||
padding: 0.7rem 0.85rem;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.wire-next__input-group-control button {
|
||||
.wrn-next__input-group-control button {
|
||||
align-self: stretch;
|
||||
border: 0;
|
||||
background: var(--wire-field-color);
|
||||
color: var(--wire-color-primary-contrast, #fff);
|
||||
background: var(--wrn-field-color);
|
||||
color: var(--wrn-color-primary-contrast, #fff);
|
||||
font: inherit;
|
||||
font-weight: 700;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* Shared component foundation. */
|
||||
|
||||
.wrn-component {
|
||||
--wrn-component-color: var(--wrn-color-primary);
|
||||
--wrn-component-scale: 1;
|
||||
margin: 0;
|
||||
color: var(--wrn-color-text);
|
||||
font-family: var(--wrn-font-sans, inherit);
|
||||
}
|
||||
|
||||
.wrn-component--color-primary {
|
||||
--wrn-component-color: var(--wrn-color-primary);
|
||||
}
|
||||
|
||||
.wrn-component--color-secondary {
|
||||
--wrn-component-color: var(--wrn-color-secondary);
|
||||
}
|
||||
|
||||
.wrn-component--color-success {
|
||||
--wrn-component-color: var(--wrn-color-success);
|
||||
}
|
||||
|
||||
.wrn-component--color-warning {
|
||||
--wrn-component-color: var(--wrn-color-warning);
|
||||
}
|
||||
|
||||
.wrn-component--color-danger {
|
||||
--wrn-component-color: var(--wrn-color-danger);
|
||||
}
|
||||
|
||||
.wrn-component--color-info {
|
||||
--wrn-component-color: var(--wrn-color-info);
|
||||
}
|
||||
|
||||
.wrn-component--size-xs {
|
||||
--wrn-component-scale: 0.78;
|
||||
}
|
||||
|
||||
.wrn-component--size-sm {
|
||||
--wrn-component-scale: 0.88;
|
||||
}
|
||||
|
||||
.wrn-component--size-default,
|
||||
.wrn-component--size-md {
|
||||
--wrn-component-scale: 1;
|
||||
}
|
||||
|
||||
.wrn-component--size-lg {
|
||||
--wrn-component-scale: 1.14;
|
||||
}
|
||||
|
||||
.wrn-component--size-xl {
|
||||
--wrn-component-scale: 1.28;
|
||||
}
|
||||
|
||||
.wrn-component:not(.wrn-btn) {
|
||||
font-size: calc(1em * var(--wrn-component-scale));
|
||||
}
|
||||
|
||||
.wrn-component :is(a, button, input, select, textarea):focus-visible {
|
||||
outline-color: var(--wrn-component-color);
|
||||
}
|
||||
|
||||
.wrn-component p {
|
||||
margin: 0;
|
||||
color: var(--wrn-color-muted);
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
/* Shared field foundation. */
|
||||
|
||||
/* Validation states set by the browser validation runtime. */
|
||||
.wrn-invalid {
|
||||
border-color: var(--wrn-color-danger) !important;
|
||||
}
|
||||
|
||||
.wrn-field-error {
|
||||
display: block;
|
||||
min-height: 1em;
|
||||
margin-top: 0.25rem;
|
||||
color: var(--wrn-color-danger);
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
.wrn-next--choice {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.55rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.wrn-next--choice input {
|
||||
width: 1.1rem;
|
||||
height: 1.1rem;
|
||||
accent-color: var(--wrn-color-primary);
|
||||
}
|
||||
|
||||
.wrn-next--field {
|
||||
display: grid;
|
||||
width: min(100%, 28rem);
|
||||
gap: 0.4rem;
|
||||
font-size: 0.78rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
.wrn-next--field :where(input, textarea, select) {
|
||||
width: 100%;
|
||||
min-height: 2.65rem;
|
||||
padding: 0.6rem 0.7rem;
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: 0.6rem;
|
||||
outline: 0;
|
||||
color: var(--wrn-color-text);
|
||||
background: var(--wrn-color-bg);
|
||||
font: inherit;
|
||||
font-weight: 500;
|
||||
}
|
||||
.wrn-auth-form form > .wrn-next--field,
|
||||
.wrn-auth-form form > .wrn-field {
|
||||
width: 100%;
|
||||
max-width: none;
|
||||
}
|
||||
.wrn-auth-form__submit > .wrn-btn {
|
||||
width: 100%;
|
||||
min-height: 3rem;
|
||||
border-radius: 0.75rem;
|
||||
box-shadow: 0 0.8rem 1.8rem color-mix(in srgb, var(--wrn-btn-color) 20%, transparent);
|
||||
}
|
||||
.wrn-next--field :where(input, textarea, select):focus-visible {
|
||||
border-color: var(--wrn-color-primary);
|
||||
box-shadow: 0 0 0 3px color-mix(in srgb, var(--wrn-color-primary) 16%, transparent);
|
||||
}
|
||||
.wrn-next--field textarea {
|
||||
resize: vertical;
|
||||
}
|
||||
.wrn-next--field,
|
||||
.wrn-next--choice-field {
|
||||
--wrn-field-color: var(--wrn-component-color, var(--wrn-color-primary));
|
||||
width: min(100%, 34rem);
|
||||
min-width: 0;
|
||||
color: var(--wrn-color-text);
|
||||
font-size: 0.8125rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
.wrn-next--field.wrn-next--size-sm,
|
||||
.wrn-next--choice-field.wrn-next--size-sm {
|
||||
font-size: 0.8125rem;
|
||||
}
|
||||
.wrn-next--field.wrn-next--size-lg,
|
||||
.wrn-next--choice-field.wrn-next--size-lg {
|
||||
font-size: 1rem;
|
||||
}
|
||||
.wrn-next__field-heading {
|
||||
display: flex;
|
||||
min-width: 0;
|
||||
align-items: baseline;
|
||||
justify-content: space-between;
|
||||
gap: 1rem;
|
||||
}
|
||||
.wrn-next__field-heading label {
|
||||
color: var(--wrn-color-text);
|
||||
font-weight: 600;
|
||||
}
|
||||
.wrn-next__field-hint,
|
||||
.wrn-next__field-help {
|
||||
color: var(--wrn-color-muted);
|
||||
font-size: 0.82em;
|
||||
font-weight: 500;
|
||||
}
|
||||
.wrn-next__field-control {
|
||||
position: relative;
|
||||
min-width: 0;
|
||||
}
|
||||
.wrn-next__field-control > :is(input, textarea, select) {
|
||||
padding-inline: 0.85rem;
|
||||
border-color: var(--wrn-color-border);
|
||||
border-radius: var(--wrn-radius-sm);
|
||||
background: var(--wrn-color-surface);
|
||||
font-size: 0.8125rem;
|
||||
}
|
||||
.wrn-next__field-control[data-icon-position="start"] > :is(input, textarea, select) {
|
||||
padding-inline-start: 2.5rem;
|
||||
}
|
||||
.wrn-next__field-control[data-icon-position="end"] > :is(input, textarea, select) {
|
||||
padding-inline-end: 2.5rem;
|
||||
}
|
||||
.wrn-next__field-icon {
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
top: 50%;
|
||||
left: 0.85rem;
|
||||
color: var(--wrn-color-muted);
|
||||
pointer-events: none;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
.wrn-next__field-control[data-icon-position="end"] > .wrn-next__field-icon {
|
||||
right: 0.85rem;
|
||||
left: auto;
|
||||
}
|
||||
.wrn-next--field[data-variant="outlined"]
|
||||
.wrn-next__field-control
|
||||
> :is(input, textarea, select) {
|
||||
border-width: 2px;
|
||||
}
|
||||
.wrn-next--field[data-variant="underline"]
|
||||
.wrn-next__field-control
|
||||
> :is(input, textarea, select) {
|
||||
padding-inline: 0;
|
||||
border-width: 0 0 1px;
|
||||
border-radius: 0;
|
||||
background: transparent;
|
||||
box-shadow: none;
|
||||
}
|
||||
.wrn-next--field[data-variant="pill"] .wrn-next__field-control > :is(input, select) {
|
||||
border-radius: 999px;
|
||||
padding-inline: 1.15rem;
|
||||
}
|
||||
.wrn-next--field[data-variant="ghost"] .wrn-next__field-control > :is(input, textarea, select) {
|
||||
border-color: transparent;
|
||||
background: color-mix(in srgb, var(--wrn-field-color) 8%, var(--wrn-color-surface));
|
||||
}
|
||||
.wrn-next__field-floating-label {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 0.85rem;
|
||||
color: var(--wrn-color-muted);
|
||||
pointer-events: none;
|
||||
transform: translateY(-50%);
|
||||
transition: 150ms ease;
|
||||
}
|
||||
.wrn-next--textarea .wrn-next__field-floating-label {
|
||||
top: 1.35rem;
|
||||
}
|
||||
.wrn-next--field[data-floating="true"] .wrn-next__field-control > :is(input, textarea, select) {
|
||||
padding-top: 1.2rem;
|
||||
padding-bottom: 0.3rem;
|
||||
}
|
||||
.wrn-next--field[data-floating="true"] .wrn-next__field-heading > label {
|
||||
position: absolute !important;
|
||||
width: 1px !important;
|
||||
height: 1px !important;
|
||||
overflow: hidden !important;
|
||||
margin: -1px !important;
|
||||
clip: rect(0, 0, 0, 0) !important;
|
||||
white-space: nowrap !important;
|
||||
}
|
||||
.wrn-next--field[data-floating="true"]
|
||||
.wrn-next__field-heading:not(:has(.wrn-next__field-hint)) {
|
||||
display: none;
|
||||
}
|
||||
.wrn-next--field[data-floating="true"]
|
||||
.wrn-next__field-control
|
||||
> :is(input, textarea):is(:focus, :not(:placeholder-shown))
|
||||
+ .wrn-next__field-floating-label {
|
||||
top: 0.42rem;
|
||||
font-size: 0.7em;
|
||||
transform: none;
|
||||
}
|
||||
.wrn-next__field-error {
|
||||
min-height: 1em;
|
||||
color: var(--wrn-color-danger);
|
||||
font-size: 0.82em;
|
||||
font-weight: 600;
|
||||
}
|
||||
.wrn-next__field-error:empty {
|
||||
display: none;
|
||||
}
|
||||
.wrn-next--field[data-invalid="true"] :is(input, textarea, select),
|
||||
.wrn-next--choice-field[data-invalid="true"] input {
|
||||
border-color: var(--wrn-color-danger);
|
||||
}
|
||||
.wrn-next--field :is(input, textarea, select):disabled,
|
||||
.wrn-next--choice-field input:disabled {
|
||||
cursor: not-allowed;
|
||||
opacity: 0.58;
|
||||
}
|
||||
.wrn-next--field :is(input, textarea, select):read-only {
|
||||
background: var(--wrn-color-surface-2);
|
||||
}
|
||||
.wrn-next--field[data-inline="true"],
|
||||
.wrn-next--choice-field[data-inline="true"] {
|
||||
display: grid;
|
||||
width: 100%;
|
||||
max-width: none;
|
||||
grid-template-columns: minmax(7rem, max-content) minmax(12rem, 20rem) minmax(10rem, 1fr);
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
.wrn-next--field[data-inline="true"] .wrn-next__field-heading,
|
||||
.wrn-next--choice-field[data-inline="true"] .wrn-next__field-heading {
|
||||
min-height: 2.65rem;
|
||||
align-items: center;
|
||||
}
|
||||
.wrn-next--field[data-inline="true"] .wrn-next__field-heading {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
.wrn-next--field[data-inline="true"] .wrn-next__field-help,
|
||||
.wrn-next--choice-field[data-inline="true"] .wrn-next__field-help {
|
||||
display: flex;
|
||||
min-height: 2.65rem;
|
||||
align-items: center;
|
||||
}
|
||||
.wrn-next--choice-field[data-inline="true"] {
|
||||
grid-template-columns: minmax(12rem, 20rem) minmax(10rem, 1fr);
|
||||
}
|
||||
.wrn-next--choice-field[data-inline="true"] .wrn-next__field-heading:empty {
|
||||
display: none;
|
||||
}
|
||||
.wrn-next--field[data-inline="true"] .wrn-next__field-error,
|
||||
.wrn-next--choice-field[data-inline="true"] .wrn-next__field-error {
|
||||
grid-column: 2 / -1;
|
||||
}
|
||||
.wrn-next__sr-only {
|
||||
position: absolute !important;
|
||||
width: 1px !important;
|
||||
height: 1px !important;
|
||||
overflow: hidden !important;
|
||||
padding: 0 !important;
|
||||
border: 0 !important;
|
||||
margin: -1px !important;
|
||||
clip: rect(0, 0, 0, 0) !important;
|
||||
white-space: nowrap !important;
|
||||
}
|
||||
.wrn-next__choice-field {
|
||||
display: grid;
|
||||
width: 100%;
|
||||
max-width: none;
|
||||
gap: 0.4rem;
|
||||
}
|
||||
.wrn-next__choice {
|
||||
display: flex;
|
||||
min-width: 0;
|
||||
align-items: center;
|
||||
gap: 0.65rem;
|
||||
color: var(--wrn-color-text);
|
||||
width: 100%;
|
||||
font-size: 0.75rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
.wrn-next__checkbox-content > .wrn-next__choice {
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
align-items: flex-start;
|
||||
}
|
||||
.wrn-next__choice input {
|
||||
flex: 0 0 auto;
|
||||
margin: 0;
|
||||
accent-color: var(--wrn-field-color);
|
||||
}
|
||||
.wrn-next__choice-copy {
|
||||
display: grid;
|
||||
min-width: 0;
|
||||
gap: 0.15rem;
|
||||
line-height: 1.35;
|
||||
}
|
||||
.wrn-next__choice-copy small {
|
||||
color: var(--wrn-color-muted);
|
||||
font-weight: 500;
|
||||
}
|
||||
.wrn-next__radio-group,
|
||||
.wrn-next__checkbox-group {
|
||||
display: grid;
|
||||
min-width: 0;
|
||||
gap: 0.65rem;
|
||||
}
|
||||
.wrn-next--radio-field[data-orientation="horizontal"] .wrn-next__radio-group,
|
||||
.wrn-next--checkbox-field[data-orientation="horizontal"] .wrn-next__checkbox-group {
|
||||
grid-template-columns: repeat(auto-fit, minmax(8rem, max-content));
|
||||
align-items: stretch;
|
||||
}
|
||||
.wrn-next--radio-field[data-card="true"] .wrn-next__radio-group,
|
||||
.wrn-next--checkbox-field[data-card="true"] .wrn-next__checkbox-group {
|
||||
grid-template-columns: repeat(auto-fit, minmax(min(100%, 12rem), 1fr));
|
||||
}
|
||||
.wrn-next--radio-field[data-card="true"] .wrn-next--radio,
|
||||
.wrn-next--checkbox-field[data-card="true"] .wrn-next--checkbox {
|
||||
min-height: 4.5rem;
|
||||
padding: 0.85rem;
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: var(--wrn-radius-sm);
|
||||
background: var(--wrn-color-surface);
|
||||
}
|
||||
.wrn-next--radio-field[data-card="true"] .wrn-next--radio:has(input:checked),
|
||||
.wrn-next--checkbox-field[data-card="true"] .wrn-next--checkbox:has(input:checked) {
|
||||
border-color: var(--wrn-field-color);
|
||||
box-shadow: 0 0 0 1px var(--wrn-field-color);
|
||||
}
|
||||
.wrn-next--radio-field[data-list="true"] .wrn-next--radio,
|
||||
.wrn-next--checkbox-field[data-list="true"] .wrn-next--checkbox {
|
||||
padding-block: 0.75rem;
|
||||
border-bottom: 1px solid var(--wrn-color-border);
|
||||
}
|
||||
.wrn-next--radio-field[data-right-aligned="true"] .wrn-next--radio,
|
||||
.wrn-next--checkbox-field[data-right-aligned="true"] .wrn-next--checkbox {
|
||||
justify-content: space-between;
|
||||
}
|
||||
.wrn-next--radio-field[data-right-aligned="true"] .wrn-next--radio input,
|
||||
.wrn-next--checkbox-field[data-right-aligned="true"] .wrn-next--checkbox input {
|
||||
order: 2;
|
||||
}
|
||||
.wrn-next--radio-field[data-right-aligned="true"] .wrn-next__choice-copy,
|
||||
.wrn-next--checkbox-field[data-right-aligned="true"] .wrn-next__choice-copy {
|
||||
order: 1;
|
||||
}
|
||||
.wrn-next__choice[data-variant="outlined"],
|
||||
.wrn-next__choice[data-variant="floating"] {
|
||||
padding: 0.65rem 0.8rem;
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: var(--wrn-radius-sm);
|
||||
}
|
||||
.wrn-next__choice[data-variant="pill"] {
|
||||
padding: 0.65rem 1rem;
|
||||
border-radius: 999px;
|
||||
background: color-mix(in srgb, var(--wrn-field-color) 9%, var(--wrn-color-surface));
|
||||
}
|
||||
.wrn-next__choice[data-variant="ghost"] {
|
||||
padding: 0.65rem 0.8rem;
|
||||
border-radius: var(--wrn-radius-sm);
|
||||
background: color-mix(in srgb, var(--wrn-field-color) 7%, transparent);
|
||||
}
|
||||
.wrn-next__choice[data-variant="underline"] {
|
||||
padding-block: 0.5rem;
|
||||
border-bottom: 1px solid var(--wrn-color-border);
|
||||
}
|
||||
.wrn-next--select .wrn-next__field-control {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.wrn-next__color-control,
|
||||
.wrn-next__range-control,
|
||||
.wrn-next__input-group-control,
|
||||
.wrn-next__file-control {
|
||||
display: flex;
|
||||
min-width: 0;
|
||||
align-items: center;
|
||||
gap: 0.65rem;
|
||||
}
|
||||
.wrn-next__picker-control,
|
||||
.wrn-next--time-picker .wrn-next__field-control {
|
||||
position: relative;
|
||||
display: flex;
|
||||
min-width: 0;
|
||||
align-items: center;
|
||||
}
|
||||
.wrn-next__picker-control > button:first-of-type,
|
||||
.wrn-next__time-trigger {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
min-height: 2.65rem;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 0.75rem;
|
||||
padding: 0.7rem 0.85rem;
|
||||
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;
|
||||
text-align: left;
|
||||
}
|
||||
.wrn-next__calendar,
|
||||
.wrn-next__time-panel {
|
||||
z-index: 20;
|
||||
display: grid;
|
||||
width: min(100%, 22rem);
|
||||
gap: 0.75rem;
|
||||
padding: 0.85rem;
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: var(--wrn-radius-md);
|
||||
background: var(--wrn-color-surface);
|
||||
box-shadow: var(--wrn-shadow-3);
|
||||
}
|
||||
.wrn-next--date-picker[data-expanded="false"] .wrn-next__calendar,
|
||||
.wrn-next--time-picker[data-expanded="false"] .wrn-next__time-panel {
|
||||
display: none;
|
||||
}
|
||||
.wrn-next__calendar button,
|
||||
.wrn-next__time-panel button {
|
||||
min-height: 2.25rem;
|
||||
border: 0;
|
||||
border-radius: var(--wrn-radius-sm);
|
||||
background: transparent;
|
||||
color: inherit;
|
||||
}
|
||||
.wrn-next__calendar-weekdays,
|
||||
.wrn-next__calendar-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(7, 1fr);
|
||||
gap: 0.2rem;
|
||||
text-align: center;
|
||||
}
|
||||
.wrn-next__calendar-weekdays {
|
||||
color: var(--wrn-color-muted);
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
.wrn-next__calendar-grid button:hover,
|
||||
.wrn-next__time-panel button:hover {
|
||||
background: var(--wrn-color-surface-2);
|
||||
}
|
||||
.wrn-next__calendar-grid button[aria-pressed="true"],
|
||||
.wrn-next__time-panel button[aria-pressed="true"] {
|
||||
background: var(--wrn-field-color);
|
||||
color: var(--wrn-color-primary-contrast, #fff);
|
||||
}
|
||||
.wrn-next__time-period {
|
||||
display: flex;
|
||||
gap: 0.35rem;
|
||||
}
|
||||
.wrn-next--file-upload-progress .wrn-next__row,
|
||||
.wrn-next__upload-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
.wrn-next--file-upload-progress .wrn-next__row > span {
|
||||
display: grid;
|
||||
min-width: 0;
|
||||
}
|
||||
.wrn-next--field[data-variant="underline"]
|
||||
:is(.wrn-next__input-group-control, .wrn-next__file-control, .wrn-next__color-control) {
|
||||
border-width: 0 0 1px;
|
||||
border-radius: 0;
|
||||
background: transparent;
|
||||
}
|
||||
.wrn-next--field[data-variant="outlined"]
|
||||
:is(.wrn-next__input-group-control, .wrn-next__file-control) {
|
||||
border-width: 2px;
|
||||
}
|
||||
.wrn-next--field[data-variant="pill"]
|
||||
:is(.wrn-next__input-group-control, .wrn-next__file-control) {
|
||||
border-radius: 999px;
|
||||
}
|
||||
.wrn-next--field[data-variant="ghost"]
|
||||
:is(.wrn-next__input-group-control, .wrn-next__file-control, .wrn-next__color-control) {
|
||||
border-color: transparent;
|
||||
background: color-mix(in srgb, var(--wrn-field-color) 8%, var(--wrn-color-surface));
|
||||
}
|
||||
@media (max-width: 640px) {
|
||||
.wrn-next--field[data-inline="true"],
|
||||
.wrn-next--choice-field[data-inline="true"] {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.wrn-next--field[data-inline="true"] .wrn-next__field-error,
|
||||
.wrn-next--choice-field[data-inline="true"] .wrn-next__field-error {
|
||||
grid-column: auto;
|
||||
}
|
||||
}
|
||||
.wrn-next--toggle-password:has(input.wrn-invalid) .wrn-next__password-control > input,
|
||||
.wrn-next--toggle-password.wrn-next--invalid .wrn-next__password-control > input {
|
||||
border-color: var(--wrn-color-danger);
|
||||
box-shadow: 0 0 0 3px color-mix(in srgb, var(--wrn-color-danger) 14%, transparent);
|
||||
}
|
||||
.wrn-next--strong-password.wrn-next--invalid input,
|
||||
.wrn-next--strong-password input.wrn-invalid {
|
||||
border-color: var(--wrn-color-danger);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,26 +81,26 @@ component InputNumber {
|
||||
|
||||
shared function componentColor() {
|
||||
if (color === "secondary") {
|
||||
return "var(--wire-color-secondary)"
|
||||
return "var(--wrn-color-secondary)"
|
||||
}
|
||||
|
||||
if (color === "success") {
|
||||
return "var(--wire-color-success)"
|
||||
return "var(--wrn-color-success)"
|
||||
}
|
||||
|
||||
if (color === "warning") {
|
||||
return "var(--wire-color-warning)"
|
||||
return "var(--wrn-color-warning)"
|
||||
}
|
||||
|
||||
if (color === "danger") {
|
||||
return "var(--wire-color-danger)"
|
||||
return "var(--wrn-color-danger)"
|
||||
}
|
||||
|
||||
if (color === "info") {
|
||||
return "var(--wire-color-info)"
|
||||
return "var(--wrn-color-info)"
|
||||
}
|
||||
|
||||
return "var(--wire-color-primary)"
|
||||
return "var(--wrn-color-primary)"
|
||||
}
|
||||
|
||||
shared function hasMin() {
|
||||
@@ -420,18 +420,18 @@ component InputNumber {
|
||||
data-disabled='{disabled ? "true" : "false"}'
|
||||
data-full-width='{fullWidth ? "true" : "false"}'
|
||||
style='--input-number-accent: {componentColor()};'
|
||||
class='wire-input-number {class}'
|
||||
class='wrn-input-number {class}'
|
||||
>
|
||||
{#if label !== "" && variant !== "labeled" && variant !== "seat"}
|
||||
<label
|
||||
for='{inputId()}'
|
||||
class='wire-input-number__label'
|
||||
class='wrn-input-number__label'
|
||||
>
|
||||
<span>{label}</span>
|
||||
{#if required}
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class='wire-input-number__required'
|
||||
class='wrn-input-number__required'
|
||||
>*</span>
|
||||
{/if}
|
||||
</label>
|
||||
@@ -440,14 +440,14 @@ component InputNumber {
|
||||
{#if description !== "" && variant !== "labeled" && variant !== "seat"}
|
||||
<p
|
||||
id='{descriptionId()}'
|
||||
class='wire-input-number__description'
|
||||
class='wrn-input-number__description'
|
||||
>
|
||||
{description}
|
||||
</p>
|
||||
{/if}
|
||||
|
||||
<div
|
||||
class='wire-input-number__control'
|
||||
class='wrn-input-number__control'
|
||||
>
|
||||
{#if variant === "horizontal" && showButtons}
|
||||
<button
|
||||
@@ -456,30 +456,30 @@ component InputNumber {
|
||||
aria-controls='{inputId()}'
|
||||
disabled='{decrementDisabled()}'
|
||||
@click='decrementValue(event)'
|
||||
class='wire-input-number__button wire-input-number__button--start'
|
||||
class='wrn-input-number__button wrn-input-number__button--start'
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class='icon-[lucide--minus] wire-input-number__icon'
|
||||
class='icon-[lucide--minus] wrn-input-number__icon'
|
||||
></span>
|
||||
</button>
|
||||
{/if}
|
||||
|
||||
<div
|
||||
class='wire-input-number__content'
|
||||
class='wrn-input-number__content'
|
||||
>
|
||||
{#if variant === "labeled" || variant === "seat"}
|
||||
<div class='wire-input-number__copy'>
|
||||
<div class='wrn-input-number__copy'>
|
||||
{#if label !== ""}
|
||||
<label
|
||||
for='{inputId()}'
|
||||
class='wire-input-number__inner-label'
|
||||
class='wrn-input-number__inner-label'
|
||||
>
|
||||
{label}
|
||||
{#if required}
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class='wire-input-number__required'
|
||||
class='wrn-input-number__required'
|
||||
>*</span>
|
||||
{/if}
|
||||
</label>
|
||||
@@ -488,7 +488,7 @@ component InputNumber {
|
||||
{#if description !== ""}
|
||||
<span
|
||||
id='{descriptionId()}'
|
||||
class='wire-input-number__inner-description'
|
||||
class='wrn-input-number__inner-description'
|
||||
>
|
||||
{description}
|
||||
</span>
|
||||
@@ -497,12 +497,12 @@ component InputNumber {
|
||||
{/if}
|
||||
|
||||
<div
|
||||
class='wire-input-number__field'
|
||||
class='wrn-input-number__field'
|
||||
>
|
||||
{#if prefix !== ""}
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class='wire-input-number__prefix'
|
||||
class='wrn-input-number__prefix'
|
||||
>
|
||||
{prefix}
|
||||
</span>
|
||||
@@ -532,13 +532,13 @@ component InputNumber {
|
||||
@change='handleChange(event)'
|
||||
@keydown='handleKeydown(event)'
|
||||
@wheel='handleWheel(event)'
|
||||
class='wire-input-number__input'
|
||||
class='wrn-input-number__input'
|
||||
/>
|
||||
|
||||
{#if suffix !== ""}
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class='wire-input-number__suffix'
|
||||
class='wrn-input-number__suffix'
|
||||
>
|
||||
{suffix}
|
||||
</span>
|
||||
@@ -553,11 +553,11 @@ component InputNumber {
|
||||
aria-controls='{inputId()}'
|
||||
disabled='{incrementDisabled()}'
|
||||
@click='incrementValue(event)'
|
||||
class='wire-input-number__button wire-input-number__button--end'
|
||||
class='wrn-input-number__button wrn-input-number__button--end'
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class='icon-[lucide--plus] wire-input-number__icon'
|
||||
class='icon-[lucide--plus] wrn-input-number__icon'
|
||||
></span>
|
||||
</button>
|
||||
{:else}
|
||||
@@ -565,7 +565,7 @@ component InputNumber {
|
||||
<div
|
||||
role="group"
|
||||
aria-label='{controlsLabel}'
|
||||
class='wire-input-number__buttons'
|
||||
class='wrn-input-number__buttons'
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
@@ -573,11 +573,11 @@ component InputNumber {
|
||||
aria-controls='{inputId()}'
|
||||
disabled='{decrementDisabled()}'
|
||||
@click='decrementValue(event)'
|
||||
class='wire-input-number__button wire-input-number__button--decrement'
|
||||
class='wrn-input-number__button wrn-input-number__button--decrement'
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class='icon-[lucide--minus] wire-input-number__icon'
|
||||
class='icon-[lucide--minus] wrn-input-number__icon'
|
||||
></span>
|
||||
</button>
|
||||
|
||||
@@ -587,11 +587,11 @@ component InputNumber {
|
||||
aria-controls='{inputId()}'
|
||||
disabled='{incrementDisabled()}'
|
||||
@click='incrementValue(event)'
|
||||
class='wire-input-number__button wire-input-number__button--increment'
|
||||
class='wrn-input-number__button wrn-input-number__button--increment'
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class='icon-[lucide--plus] wire-input-number__icon'
|
||||
class='icon-[lucide--plus] wrn-input-number__icon'
|
||||
></span>
|
||||
</button>
|
||||
</div>
|
||||
@@ -604,11 +604,11 @@ component InputNumber {
|
||||
id='{messageId()}'
|
||||
role="alert"
|
||||
aria-live="polite"
|
||||
class='wire-input-number__message wire-input-number__message--error'
|
||||
class='wrn-input-number__message wrn-input-number__message--error'
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class='icon-[lucide--circle-alert] wire-input-number__error-icon'
|
||||
class='icon-[lucide--circle-alert] wrn-input-number__error-icon'
|
||||
></span>
|
||||
<span>{validationMessage()}</span>
|
||||
</p>
|
||||
@@ -617,7 +617,7 @@ component InputNumber {
|
||||
{#if (!showValidationMessage || !isInvalid() || validationMessage() === "") && helpText !== ""}
|
||||
<p
|
||||
id='{messageId()}'
|
||||
class='wire-input-number__message'
|
||||
class='wrn-input-number__message'
|
||||
>
|
||||
{helpText}
|
||||
</p>
|
||||
@@ -626,57 +626,57 @@ component InputNumber {
|
||||
}
|
||||
|
||||
style {
|
||||
.wire-input-number { position: relative; display: flex; width: 100%; max-width: 24rem; flex-direction: column; gap: 0.375rem; color: var(--wire-color-text); }
|
||||
.wire-input-number[data-full-width="true"] { max-width: none; }
|
||||
.wire-input-number[data-variant="compact"] { width: fit-content; max-width: 100%; }
|
||||
.wire-input-number[data-disabled="true"] { opacity: 0.6; }
|
||||
.wire-input-number__label { display: inline-flex; align-items: center; gap: 0.25rem; color: var(--wire-color-text); font-size: 0.875rem; font-weight: 600; line-height: 1.25rem; }
|
||||
.wire-input-number__required { margin-left: 0.125rem; color: var(--wire-color-danger); }
|
||||
.wire-input-number__description, .wire-input-number__message { margin: 0; color: var(--wire-color-muted); font-size: 0.75rem; line-height: 1.25rem; }
|
||||
.wire-input-number__control { display: flex; min-width: 0; min-height: 2.5rem; overflow: hidden; border: 1px solid var(--wire-color-border); border-radius: var(--wire-radius-sm); color: var(--wire-color-text); background: var(--wire-color-surface); box-shadow: var(--wire-shadow-1); transition: border-color var(--wire-motion-base), box-shadow var(--wire-motion-base), background var(--wire-motion-base); }
|
||||
.wire-input-number__control:focus-within { border-color: var(--input-number-accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--input-number-accent) 18%, transparent); }
|
||||
.wire-input-number[data-invalid="true"] .wire-input-number__control { border-color: var(--wire-color-danger); }
|
||||
.wire-input-number[data-invalid="true"] .wire-input-number__control:focus-within { box-shadow: 0 0 0 3px color-mix(in srgb, var(--wire-color-danger) 18%, transparent); }
|
||||
.wire-input-number[data-disabled="true"] .wire-input-number__control { cursor: not-allowed; background: var(--wire-color-surface-2); }
|
||||
.wire-input-number[data-variant="compact"] .wire-input-number__control { border-radius: 999px; }
|
||||
.wire-input-number[data-size="xs"] .wire-input-number__control { min-height: 2rem; font-size: 0.75rem; }
|
||||
.wire-input-number[data-size="sm"] .wire-input-number__control { min-height: 2.25rem; font-size: 0.875rem; }
|
||||
.wire-input-number[data-size="lg"] .wire-input-number__control { min-height: 3rem; font-size: 1rem; }
|
||||
.wire-input-number[data-size="xl"] .wire-input-number__control { min-height: 3.5rem; font-size: 1.125rem; }
|
||||
.wire-input-number__content { display: flex; min-width: 0; flex: 1; align-items: center; padding-inline: 0.75rem; }
|
||||
.wire-input-number[data-size="xs"] .wire-input-number__content { padding-inline: 0.5rem; }
|
||||
.wire-input-number[data-size="sm"] .wire-input-number__content { padding-inline: 0.625rem; }
|
||||
.wire-input-number[data-size="lg"] .wire-input-number__content { padding-inline: 1rem; }
|
||||
.wire-input-number[data-size="xl"] .wire-input-number__content { padding-inline: 1.25rem; }
|
||||
.wire-input-number[data-variant="labeled"] .wire-input-number__content { flex-direction: column; align-items: stretch; justify-content: center; gap: 0.125rem; }
|
||||
.wire-input-number[data-variant="seat"] .wire-input-number__content { justify-content: space-between; gap: 0.75rem; }
|
||||
.wire-input-number__copy { min-width: 0; flex: 1; }
|
||||
.wire-input-number__inner-label, .wire-input-number__inner-description { display: block; overflow: hidden; color: var(--wire-color-text); font-size: 0.875rem; font-weight: 600; line-height: 1rem; text-overflow: ellipsis; white-space: nowrap; }
|
||||
.wire-input-number__inner-description { color: var(--wire-color-muted); font-size: 0.75rem; font-weight: 400; }
|
||||
.wire-input-number[data-variant="labeled"] .wire-input-number__inner-label { color: var(--wire-color-muted); font-size: 0.75rem; font-weight: 500; }
|
||||
.wire-input-number__field { display: flex; width: 100%; min-width: 0; align-items: center; }
|
||||
.wire-input-number[data-variant="seat"] .wire-input-number__field { width: auto; flex: none; }
|
||||
.wire-input-number__prefix, .wire-input-number__suffix { flex: none; color: var(--wire-color-muted); }
|
||||
.wire-input-number__prefix { padding-right: 0.375rem; } .wire-input-number__suffix { padding-left: 0.375rem; }
|
||||
.wire-input-number__input { width: 100%; min-width: 0; flex: 1; padding: 0; border: 0; outline: none; color: var(--wire-color-text); background: transparent; font: inherit; font-weight: 500; line-height: 1; appearance: textfield; }
|
||||
.wire-input-number__input::-webkit-inner-spin-button, .wire-input-number__input::-webkit-outer-spin-button { appearance: none; }
|
||||
.wire-input-number__input::placeholder { color: var(--wire-color-muted); }
|
||||
.wire-input-number__input:read-only { cursor: default; }
|
||||
.wire-input-number__input:disabled { cursor: not-allowed; }
|
||||
.wire-input-number:is([data-variant="horizontal"], [data-variant="compact"], [data-variant="seat"]) .wire-input-number__input { text-align: center; }
|
||||
.wire-input-number[data-variant="seat"] .wire-input-number__input { width: 2.5rem; flex: none; }
|
||||
.wire-input-number__buttons { display: flex; flex: none; border-left: 1px solid var(--wire-color-border); }
|
||||
.wire-input-number[data-variant="vertical"] .wire-input-number__buttons { flex-direction: column; }
|
||||
.wire-input-number__button { display: inline-flex; width: 2.5rem; flex: none; align-items: center; justify-content: center; padding: 0; border: 0; color: var(--wire-color-muted); background: transparent; transition: color var(--wire-motion-fast), background var(--wire-motion-fast); }
|
||||
.wire-input-number[data-size="xs"] .wire-input-number__button { width: 2rem; } .wire-input-number[data-size="sm"] .wire-input-number__button { width: 2.25rem; } .wire-input-number[data-size="lg"] .wire-input-number__button { width: 3rem; } .wire-input-number[data-size="xl"] .wire-input-number__button { width: 3.5rem; }
|
||||
.wire-input-number__button--start { border-right: 1px solid var(--wire-color-border); } .wire-input-number__button--end { border-left: 1px solid var(--wire-color-border); }
|
||||
.wire-input-number__button--decrement { border-right: 1px solid var(--wire-color-border); }
|
||||
.wire-input-number[data-variant="vertical"] .wire-input-number__button--decrement { border-right: 0; border-bottom: 1px solid var(--wire-color-border); }
|
||||
.wire-input-number__button:hover { color: var(--input-number-accent); background: var(--wire-color-surface-2); }
|
||||
.wire-input-number__button:focus-visible { z-index: 1; outline: 2px solid var(--input-number-accent); outline-offset: -2px; }
|
||||
.wire-input-number__button:disabled { cursor: not-allowed; opacity: 0.4; }
|
||||
.wire-input-number__icon { width: 1rem; height: 1rem; }
|
||||
.wire-input-number__message--error { display: flex; align-items: center; gap: 0.375rem; color: var(--wire-color-danger); }
|
||||
.wire-input-number__error-icon { width: 0.875rem; height: 0.875rem; flex: none; }
|
||||
.wrn-input-number { position: relative; display: flex; width: 100%; max-width: 24rem; flex-direction: column; gap: 0.375rem; color: var(--wrn-color-text); }
|
||||
.wrn-input-number[data-full-width="true"] { max-width: none; }
|
||||
.wrn-input-number[data-variant="compact"] { width: fit-content; max-width: 100%; }
|
||||
.wrn-input-number[data-disabled="true"] { opacity: 0.6; }
|
||||
.wrn-input-number__label { display: inline-flex; align-items: center; gap: 0.25rem; color: var(--wrn-color-text); font-size: 0.875rem; font-weight: 600; line-height: 1.25rem; }
|
||||
.wrn-input-number__required { margin-left: 0.125rem; color: var(--wrn-color-danger); }
|
||||
.wrn-input-number__description, .wrn-input-number__message { margin: 0; color: var(--wrn-color-muted); font-size: 0.75rem; line-height: 1.25rem; }
|
||||
.wrn-input-number__control { display: flex; min-width: 0; min-height: 2.5rem; overflow: hidden; border: 1px solid var(--wrn-color-border); border-radius: var(--wrn-radius-sm); color: var(--wrn-color-text); background: var(--wrn-color-surface); box-shadow: var(--wrn-shadow-1); transition: border-color var(--wrn-motion-base), box-shadow var(--wrn-motion-base), background var(--wrn-motion-base); }
|
||||
.wrn-input-number__control:focus-within { border-color: var(--input-number-accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--input-number-accent) 18%, transparent); }
|
||||
.wrn-input-number[data-invalid="true"] .wrn-input-number__control { border-color: var(--wrn-color-danger); }
|
||||
.wrn-input-number[data-invalid="true"] .wrn-input-number__control:focus-within { box-shadow: 0 0 0 3px color-mix(in srgb, var(--wrn-color-danger) 18%, transparent); }
|
||||
.wrn-input-number[data-disabled="true"] .wrn-input-number__control { cursor: not-allowed; background: var(--wrn-color-surface-2); }
|
||||
.wrn-input-number[data-variant="compact"] .wrn-input-number__control { border-radius: 999px; }
|
||||
.wrn-input-number[data-size="xs"] .wrn-input-number__control { min-height: 2rem; font-size: 0.75rem; }
|
||||
.wrn-input-number[data-size="sm"] .wrn-input-number__control { min-height: 2.25rem; font-size: 0.875rem; }
|
||||
.wrn-input-number[data-size="lg"] .wrn-input-number__control { min-height: 3rem; font-size: 1rem; }
|
||||
.wrn-input-number[data-size="xl"] .wrn-input-number__control { min-height: 3.5rem; font-size: 1.125rem; }
|
||||
.wrn-input-number__content { display: flex; min-width: 0; flex: 1; align-items: center; padding-inline: 0.75rem; }
|
||||
.wrn-input-number[data-size="xs"] .wrn-input-number__content { padding-inline: 0.5rem; }
|
||||
.wrn-input-number[data-size="sm"] .wrn-input-number__content { padding-inline: 0.625rem; }
|
||||
.wrn-input-number[data-size="lg"] .wrn-input-number__content { padding-inline: 1rem; }
|
||||
.wrn-input-number[data-size="xl"] .wrn-input-number__content { padding-inline: 1.25rem; }
|
||||
.wrn-input-number[data-variant="labeled"] .wrn-input-number__content { flex-direction: column; align-items: stretch; justify-content: center; gap: 0.125rem; }
|
||||
.wrn-input-number[data-variant="seat"] .wrn-input-number__content { justify-content: space-between; gap: 0.75rem; }
|
||||
.wrn-input-number__copy { min-width: 0; flex: 1; }
|
||||
.wrn-input-number__inner-label, .wrn-input-number__inner-description { display: block; overflow: hidden; color: var(--wrn-color-text); font-size: 0.875rem; font-weight: 600; line-height: 1rem; text-overflow: ellipsis; white-space: nowrap; }
|
||||
.wrn-input-number__inner-description { color: var(--wrn-color-muted); font-size: 0.75rem; font-weight: 400; }
|
||||
.wrn-input-number[data-variant="labeled"] .wrn-input-number__inner-label { color: var(--wrn-color-muted); font-size: 0.75rem; font-weight: 500; }
|
||||
.wrn-input-number__field { display: flex; width: 100%; min-width: 0; align-items: center; }
|
||||
.wrn-input-number[data-variant="seat"] .wrn-input-number__field { width: auto; flex: none; }
|
||||
.wrn-input-number__prefix, .wrn-input-number__suffix { flex: none; color: var(--wrn-color-muted); }
|
||||
.wrn-input-number__prefix { padding-right: 0.375rem; } .wrn-input-number__suffix { padding-left: 0.375rem; }
|
||||
.wrn-input-number__input { width: 100%; min-width: 0; flex: 1; padding: 0; border: 0; outline: none; color: var(--wrn-color-text); background: transparent; font: inherit; font-weight: 500; line-height: 1; appearance: textfield; }
|
||||
.wrn-input-number__input::-webkit-inner-spin-button, .wrn-input-number__input::-webkit-outer-spin-button { appearance: none; }
|
||||
.wrn-input-number__input::placeholder { color: var(--wrn-color-muted); }
|
||||
.wrn-input-number__input:read-only { cursor: default; }
|
||||
.wrn-input-number__input:disabled { cursor: not-allowed; }
|
||||
.wrn-input-number:is([data-variant="horizontal"], [data-variant="compact"], [data-variant="seat"]) .wrn-input-number__input { text-align: center; }
|
||||
.wrn-input-number[data-variant="seat"] .wrn-input-number__input { width: 2.5rem; flex: none; }
|
||||
.wrn-input-number__buttons { display: flex; flex: none; border-left: 1px solid var(--wrn-color-border); }
|
||||
.wrn-input-number[data-variant="vertical"] .wrn-input-number__buttons { flex-direction: column; }
|
||||
.wrn-input-number__button { display: inline-flex; width: 2.5rem; flex: none; align-items: center; justify-content: center; padding: 0; border: 0; color: var(--wrn-color-muted); background: transparent; transition: color var(--wrn-motion-fast), background var(--wrn-motion-fast); }
|
||||
.wrn-input-number[data-size="xs"] .wrn-input-number__button { width: 2rem; } .wrn-input-number[data-size="sm"] .wrn-input-number__button { width: 2.25rem; } .wrn-input-number[data-size="lg"] .wrn-input-number__button { width: 3rem; } .wrn-input-number[data-size="xl"] .wrn-input-number__button { width: 3.5rem; }
|
||||
.wrn-input-number__button--start { border-right: 1px solid var(--wrn-color-border); } .wrn-input-number__button--end { border-left: 1px solid var(--wrn-color-border); }
|
||||
.wrn-input-number__button--decrement { border-right: 1px solid var(--wrn-color-border); }
|
||||
.wrn-input-number[data-variant="vertical"] .wrn-input-number__button--decrement { border-right: 0; border-bottom: 1px solid var(--wrn-color-border); }
|
||||
.wrn-input-number__button:hover { color: var(--input-number-accent); background: var(--wrn-color-surface-2); }
|
||||
.wrn-input-number__button:focus-visible { z-index: 1; outline: 2px solid var(--input-number-accent); outline-offset: -2px; }
|
||||
.wrn-input-number__button:disabled { cursor: not-allowed; opacity: 0.4; }
|
||||
.wrn-input-number__icon { width: 1rem; height: 1rem; }
|
||||
.wrn-input-number__message--error { display: flex; align-items: center; gap: 0.375rem; color: var(--wrn-color-danger); }
|
||||
.wrn-input-number__error-icon { width: 0.875rem; height: 0.875rem; flex: none; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,37 +16,37 @@ component Kbd {
|
||||
}
|
||||
|
||||
view {
|
||||
<kbd {...attrs} class='wire-kbd {class}' data-size='{size}' data-color='{color}'>
|
||||
<kbd {...attrs} class='wrn-kbd {class}' data-size='{size}' data-color='{color}'>
|
||||
<slot>{label}</slot>
|
||||
</kbd>
|
||||
}
|
||||
|
||||
style {
|
||||
.wire-kbd {
|
||||
.wrn-kbd {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-width: 1.6rem;
|
||||
padding: 0.15rem 0.4rem;
|
||||
border: 1px solid var(--wire-color-border);
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
/* The lower edge is what reads as a physical key. */
|
||||
border-bottom-width: 2px;
|
||||
border-radius: var(--wire-radius-sm);
|
||||
background: var(--wire-color-surface-soft);
|
||||
color: var(--wire-color-text);
|
||||
border-radius: var(--wrn-radius-sm);
|
||||
background: var(--wrn-color-surface-soft);
|
||||
color: var(--wrn-color-text);
|
||||
font-family: inherit;
|
||||
font-size: 0.78rem;
|
||||
font-weight: 600;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.wire-kbd[data-size="sm"] {
|
||||
.wrn-kbd[data-size="sm"] {
|
||||
min-width: 1.4rem;
|
||||
padding: 0.1rem 0.3rem;
|
||||
font-size: 0.7rem;
|
||||
}
|
||||
|
||||
.wire-kbd[data-size="lg"] {
|
||||
.wrn-kbd[data-size="lg"] {
|
||||
min-width: 2rem;
|
||||
padding: 0.3rem 0.55rem;
|
||||
font-size: 0.9rem;
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
// held in the DOM as the --wrn-split custom property and these styles read it.
|
||||
//
|
||||
// This component previously declared resizeStart, resize and resizeEnd with no
|
||||
// pointer handling whatsoever: a caller wired up @resize and received nothing,
|
||||
// pointer handling whatsoever: a caller connected up @resize and received nothing,
|
||||
// for ever, with no error.
|
||||
//
|
||||
// NOTE: the style block uses /* */ comments only -- // is not a CSS comment
|
||||
@@ -86,7 +86,7 @@ component LayoutSplitter {
|
||||
<div
|
||||
{...attrs}
|
||||
data-ui-component="LayoutSplitter"
|
||||
class='wire-splitter {class}'
|
||||
class='wrn-splitter {class}'
|
||||
data-color='{color}'
|
||||
data-orientation='{orientation}'
|
||||
data-wrn-splitter='{isVertical() ? "vertical" : "horizontal"}'
|
||||
@@ -95,12 +95,12 @@ component LayoutSplitter {
|
||||
style='--wrn-split:{currentSize()}%;'
|
||||
@wrnexus:splitter:resize='reportResize(event)'
|
||||
>
|
||||
<div class="wire-splitter__pane wire-splitter__pane--start">
|
||||
<div class="wrn-splitter__pane wrn-splitter__pane--start">
|
||||
<slot name="start"></slot>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="wire-splitter__handle"
|
||||
class="wrn-splitter__handle"
|
||||
data-wrn-splitter-handle="true"
|
||||
role="separator"
|
||||
tabindex="0"
|
||||
@@ -110,10 +110,10 @@ component LayoutSplitter {
|
||||
aria-valuemin='{lowerBound()}'
|
||||
aria-valuemax='{upperBound()}'
|
||||
>
|
||||
<span class="wire-splitter__grip" aria-hidden="true"></span>
|
||||
<span class="wrn-splitter__grip" aria-hidden="true"></span>
|
||||
</div>
|
||||
|
||||
<div class="wire-splitter__pane wire-splitter__pane--end">
|
||||
<div class="wrn-splitter__pane wrn-splitter__pane--end">
|
||||
<slot name="end"></slot>
|
||||
</div>
|
||||
|
||||
@@ -122,8 +122,8 @@ component LayoutSplitter {
|
||||
}
|
||||
|
||||
style {
|
||||
.wire-splitter {
|
||||
--splitter-accent: var(--wire-color-primary);
|
||||
.wrn-splitter {
|
||||
--splitter-accent: var(--wrn-color-primary);
|
||||
display: grid;
|
||||
/* The first track follows the size the runtime resolves. */
|
||||
grid-template-columns: var(--wrn-split, 50%) auto minmax(0, 1fr);
|
||||
@@ -132,34 +132,34 @@ component LayoutSplitter {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.wire-splitter[data-color="secondary"] {
|
||||
--splitter-accent: var(--wire-color-secondary);
|
||||
.wrn-splitter[data-color="secondary"] {
|
||||
--splitter-accent: var(--wrn-color-secondary);
|
||||
}
|
||||
|
||||
.wire-splitter[data-color="success"] {
|
||||
--splitter-accent: var(--wire-color-success);
|
||||
.wrn-splitter[data-color="success"] {
|
||||
--splitter-accent: var(--wrn-color-success);
|
||||
}
|
||||
|
||||
.wire-splitter[data-color="danger"] {
|
||||
--splitter-accent: var(--wire-color-danger);
|
||||
.wrn-splitter[data-color="danger"] {
|
||||
--splitter-accent: var(--wrn-color-danger);
|
||||
}
|
||||
|
||||
.wire-splitter[data-color="info"] {
|
||||
--splitter-accent: var(--wire-color-info);
|
||||
.wrn-splitter[data-color="info"] {
|
||||
--splitter-accent: var(--wrn-color-info);
|
||||
}
|
||||
|
||||
.wire-splitter[data-orientation="vertical"] {
|
||||
.wrn-splitter[data-orientation="vertical"] {
|
||||
grid-template-columns: minmax(0, 1fr);
|
||||
grid-template-rows: var(--wrn-split, 50%) auto minmax(0, 1fr);
|
||||
}
|
||||
|
||||
.wire-splitter__pane {
|
||||
.wrn-splitter__pane {
|
||||
min-width: 0;
|
||||
min-height: 0;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.wire-splitter__handle {
|
||||
.wrn-splitter__handle {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
@@ -173,36 +173,36 @@ component LayoutSplitter {
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.wire-splitter[data-orientation="vertical"] .wire-splitter__handle {
|
||||
.wrn-splitter[data-orientation="vertical"] .wrn-splitter__handle {
|
||||
padding: 0.25rem 0;
|
||||
cursor: row-resize;
|
||||
}
|
||||
|
||||
.wire-splitter__grip {
|
||||
.wrn-splitter__grip {
|
||||
display: block;
|
||||
width: 2px;
|
||||
height: 100%;
|
||||
min-height: 1.5rem;
|
||||
border-radius: 999px;
|
||||
background: var(--wire-color-border);
|
||||
background: var(--wrn-color-border);
|
||||
transition: background 140ms ease;
|
||||
}
|
||||
|
||||
.wire-splitter[data-orientation="vertical"] .wire-splitter__grip {
|
||||
.wrn-splitter[data-orientation="vertical"] .wrn-splitter__grip {
|
||||
width: 100%;
|
||||
min-width: 1.5rem;
|
||||
height: 2px;
|
||||
}
|
||||
|
||||
.wire-splitter__handle:hover .wire-splitter__grip,
|
||||
.wire-splitter[data-wrn-splitter-dragging="true"] .wire-splitter__grip {
|
||||
.wrn-splitter__handle:hover .wrn-splitter__grip,
|
||||
.wrn-splitter[data-wrn-splitter-dragging="true"] .wrn-splitter__grip {
|
||||
background: var(--splitter-accent);
|
||||
}
|
||||
|
||||
.wire-splitter__handle:focus-visible {
|
||||
.wrn-splitter__handle:focus-visible {
|
||||
outline: 2px solid var(--splitter-accent);
|
||||
outline-offset: -2px;
|
||||
border-radius: var(--wire-radius-sm);
|
||||
border-radius: var(--wrn-radius-sm);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -211,13 +211,13 @@ component LayoutSplitter {
|
||||
* no longer has a second track to trade against.
|
||||
*/
|
||||
@media (max-width: 639px) {
|
||||
.wire-splitter,
|
||||
.wire-splitter[data-orientation="vertical"] {
|
||||
.wrn-splitter,
|
||||
.wrn-splitter[data-orientation="vertical"] {
|
||||
grid-template-columns: minmax(0, 1fr);
|
||||
grid-template-rows: auto auto auto;
|
||||
}
|
||||
|
||||
.wire-splitter__handle {
|
||||
.wrn-splitter__handle {
|
||||
cursor: default;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import ComponentBaseStyles from "../styles/ComponentBaseStyles.wrn"
|
||||
|
||||
component LegendIndicator {
|
||||
outputs {
|
||||
toggle(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||
@@ -16,27 +14,95 @@ component LegendIndicator {
|
||||
class: string = ""
|
||||
}
|
||||
view {
|
||||
<section class="wire-component wire-component--color-{color} wire-component--size-{size} wire-next--legend-indicator wire-next--variant-{variant} {class}">
|
||||
<section class="wrn-component wrn-component--color-{color} wrn-component--size-{size} wrn-next--legend-indicator wrn-next--variant-{variant} {class}">
|
||||
{#if title}<strong>{title}</strong>{/if}
|
||||
{#if description}<p>{description}</p>{/if}
|
||||
{#if items}<div class="wire-next__items">{#each items as item}<span>{item.label}</span>{/each}</div>{/if}
|
||||
{#if items}<div class="wrn-next__items">{#each items as item}<span>{item.label}</span>{/each}</div>{/if}
|
||||
<slot />
|
||||
</section>
|
||||
<ComponentBaseStyles hidden />
|
||||
}
|
||||
|
||||
style {
|
||||
.wire-next--legend-indicator {
|
||||
.wrn-next--legend-indicator {
|
||||
display: grid;
|
||||
gap: 0.75rem;
|
||||
padding: 1rem;
|
||||
border: 1px solid var(--wire-color-border);
|
||||
border-radius: var(--wire-radius);
|
||||
color: var(--wire-color-text);
|
||||
background: var(--wire-color-surface);
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: var(--wrn-radius);
|
||||
color: var(--wrn-color-text);
|
||||
background: var(--wrn-color-surface);
|
||||
}
|
||||
.wire-next--legend-indicator > p { margin: 0; color: var(--wire-color-muted); }
|
||||
.wire-next--legend-indicator > .wire-next__items { display: flex; flex-wrap: wrap; gap: 0.5rem; }
|
||||
.wire-next--legend-indicator > .wire-next__items > span { padding: 0.35rem 0.6rem; border-radius: var(--wire-radius-sm); background: var(--wire-color-surface-2); }
|
||||
.wrn-next--legend-indicator > p { margin: 0; color: var(--wrn-color-muted); }
|
||||
.wrn-next--legend-indicator > .wrn-next__items { display: flex; flex-wrap: wrap; gap: 0.5rem; }
|
||||
.wrn-next--legend-indicator > .wrn-next__items > span { padding: 0.35rem 0.6rem; border-radius: var(--wrn-radius-sm); background: var(--wrn-color-surface-2); }
|
||||
|
||||
/* Shared component foundation. */
|
||||
|
||||
.wrn-component {
|
||||
--wrn-component-color: var(--wrn-color-primary);
|
||||
--wrn-component-scale: 1;
|
||||
margin: 0;
|
||||
color: var(--wrn-color-text);
|
||||
font-family: var(--wrn-font-sans, inherit);
|
||||
}
|
||||
|
||||
.wrn-component--color-primary {
|
||||
--wrn-component-color: var(--wrn-color-primary);
|
||||
}
|
||||
|
||||
.wrn-component--color-secondary {
|
||||
--wrn-component-color: var(--wrn-color-secondary);
|
||||
}
|
||||
|
||||
.wrn-component--color-success {
|
||||
--wrn-component-color: var(--wrn-color-success);
|
||||
}
|
||||
|
||||
.wrn-component--color-warning {
|
||||
--wrn-component-color: var(--wrn-color-warning);
|
||||
}
|
||||
|
||||
.wrn-component--color-danger {
|
||||
--wrn-component-color: var(--wrn-color-danger);
|
||||
}
|
||||
|
||||
.wrn-component--color-info {
|
||||
--wrn-component-color: var(--wrn-color-info);
|
||||
}
|
||||
|
||||
.wrn-component--size-xs {
|
||||
--wrn-component-scale: 0.78;
|
||||
}
|
||||
|
||||
.wrn-component--size-sm {
|
||||
--wrn-component-scale: 0.88;
|
||||
}
|
||||
|
||||
.wrn-component--size-default,
|
||||
.wrn-component--size-md {
|
||||
--wrn-component-scale: 1;
|
||||
}
|
||||
|
||||
.wrn-component--size-lg {
|
||||
--wrn-component-scale: 1.14;
|
||||
}
|
||||
|
||||
.wrn-component--size-xl {
|
||||
--wrn-component-scale: 1.28;
|
||||
}
|
||||
|
||||
.wrn-component:not(.wrn-btn) {
|
||||
font-size: calc(1em * var(--wrn-component-scale));
|
||||
}
|
||||
|
||||
.wrn-component :is(a, button, input, select, textarea):focus-visible {
|
||||
outline-color: var(--wrn-component-color);
|
||||
}
|
||||
|
||||
.wrn-component p {
|
||||
margin: 0;
|
||||
color: var(--wrn-color-muted);
|
||||
line-height: 1.6;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ component Link {
|
||||
<a
|
||||
{...attrs}
|
||||
data-ui-component="Link"
|
||||
class='wire-link {class}'
|
||||
class='wrn-link {class}'
|
||||
href='{href}'
|
||||
target='{target}'
|
||||
rel='{external ? (rel || "noopener noreferrer") : rel}'
|
||||
@@ -34,9 +34,9 @@ component Link {
|
||||
data-underline='{underline}'
|
||||
data-external='{external}'
|
||||
>
|
||||
<span class="wire-link__label">{label}</span>
|
||||
<span class="wrn-link__label">{label}</span>
|
||||
<span
|
||||
class="icon-[lucide--external-link] wire-link__icon"
|
||||
class="icon-[lucide--external-link] wrn-link__icon"
|
||||
data-show="external"
|
||||
aria-hidden="true"
|
||||
></span>
|
||||
@@ -45,14 +45,14 @@ component Link {
|
||||
}
|
||||
|
||||
style {
|
||||
.wire-link {
|
||||
--link-tone: var(--wire-color-primary);
|
||||
--link-tone-hover: var(--wire-color-primary-hover);
|
||||
.wrn-link {
|
||||
--link-tone: var(--wrn-color-primary);
|
||||
--link-tone-hover: var(--wrn-color-primary-hover);
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.35rem;
|
||||
min-width: 0;
|
||||
border-radius: var(--wire-radius-sm);
|
||||
border-radius: var(--wrn-radius-sm);
|
||||
color: var(--link-tone);
|
||||
font-size: 0.875rem;
|
||||
font-weight: 600;
|
||||
@@ -61,74 +61,74 @@ component Link {
|
||||
transition: color 140ms ease;
|
||||
}
|
||||
|
||||
.wire-link[data-color="secondary"] {
|
||||
--link-tone: var(--wire-color-secondary);
|
||||
--link-tone-hover: var(--wire-color-secondary-hover);
|
||||
.wrn-link[data-color="secondary"] {
|
||||
--link-tone: var(--wrn-color-secondary);
|
||||
--link-tone-hover: var(--wrn-color-secondary-hover);
|
||||
}
|
||||
|
||||
.wire-link[data-color="success"] {
|
||||
--link-tone: var(--wire-color-success);
|
||||
--link-tone-hover: var(--wire-color-success);
|
||||
.wrn-link[data-color="success"] {
|
||||
--link-tone: var(--wrn-color-success);
|
||||
--link-tone-hover: var(--wrn-color-success);
|
||||
}
|
||||
|
||||
.wire-link[data-color="warning"] {
|
||||
--link-tone: var(--wire-color-warning-text);
|
||||
--link-tone-hover: var(--wire-color-warning-text);
|
||||
.wrn-link[data-color="warning"] {
|
||||
--link-tone: var(--wrn-color-warning-text);
|
||||
--link-tone-hover: var(--wrn-color-warning-text);
|
||||
}
|
||||
|
||||
.wire-link[data-color="danger"] {
|
||||
--link-tone: var(--wire-color-danger);
|
||||
--link-tone-hover: var(--wire-color-danger);
|
||||
.wrn-link[data-color="danger"] {
|
||||
--link-tone: var(--wrn-color-danger);
|
||||
--link-tone-hover: var(--wrn-color-danger);
|
||||
}
|
||||
|
||||
.wire-link[data-color="info"] {
|
||||
--link-tone: var(--wire-color-info);
|
||||
--link-tone-hover: var(--wire-color-info);
|
||||
.wrn-link[data-color="info"] {
|
||||
--link-tone: var(--wrn-color-info);
|
||||
--link-tone-hover: var(--wrn-color-info);
|
||||
}
|
||||
|
||||
.wire-link[data-color="neutral"] {
|
||||
--link-tone: var(--wire-color-text);
|
||||
--link-tone-hover: var(--wire-color-text);
|
||||
.wrn-link[data-color="neutral"] {
|
||||
--link-tone: var(--wrn-color-text);
|
||||
--link-tone-hover: var(--wrn-color-text);
|
||||
}
|
||||
|
||||
.wire-link[data-size="xs"] {
|
||||
.wrn-link[data-size="xs"] {
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
|
||||
.wire-link[data-size="md"] {
|
||||
.wrn-link[data-size="md"] {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.wire-link[data-size="lg"] {
|
||||
.wrn-link[data-size="lg"] {
|
||||
font-size: 1.125rem;
|
||||
}
|
||||
|
||||
.wire-link[data-underline="always"] {
|
||||
.wrn-link[data-underline="always"] {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.wire-link[data-underline="hover"]:hover {
|
||||
.wrn-link[data-underline="hover"]:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.wire-link:hover {
|
||||
.wrn-link:hover {
|
||||
color: var(--link-tone-hover);
|
||||
}
|
||||
|
||||
.wire-link:focus-visible {
|
||||
outline: 2px solid var(--wire-color-focus);
|
||||
.wrn-link:focus-visible {
|
||||
outline: 2px solid var(--wrn-color-focus);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
/* The label truncates; the outbound icon must not shrink with it. */
|
||||
.wire-link__label {
|
||||
.wrn-link__label {
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.wire-link__icon {
|
||||
.wrn-link__icon {
|
||||
flex: 0 0 auto;
|
||||
width: 0.875rem;
|
||||
height: 0.875rem;
|
||||
|
||||
@@ -17,76 +17,76 @@ component List {
|
||||
<section
|
||||
data-ui-component="List"
|
||||
aria-label='{title}'
|
||||
class='wire-list {class}'
|
||||
class='wrn-list {class}'
|
||||
>
|
||||
{#if title || description}
|
||||
<header class="wire-list__header">
|
||||
<header class="wrn-list__header">
|
||||
{#if title}
|
||||
<h3 class="wire-list__title">{title}</h3>
|
||||
<h3 class="wrn-list__title">{title}</h3>
|
||||
{/if}
|
||||
{#if description}
|
||||
<p class="wire-list__description">{description}</p>
|
||||
<p class="wrn-list__description">{description}</p>
|
||||
{/if}
|
||||
</header>
|
||||
{/if}
|
||||
|
||||
<ul
|
||||
class="wire-list__items"
|
||||
class="wrn-list__items"
|
||||
data-variant='{variant}'
|
||||
>
|
||||
{#each items as item, index}
|
||||
<li
|
||||
class="wire-list__item"
|
||||
class="wrn-list__item"
|
||||
data-variant='{variant}'
|
||||
@click='if (!item.href) { output.select({ item: item, index: index }) }'
|
||||
>
|
||||
{#if item.href}
|
||||
<a
|
||||
href='{item.href}'
|
||||
class="wire-list__row"
|
||||
class="wrn-list__row"
|
||||
data-size='{size}'
|
||||
@click='output.select({ item: item, index: index })'
|
||||
>
|
||||
{#if item.icon}
|
||||
<span class="wire-list__leading-icon"><span class='{item.icon}' aria-hidden="true"></span>
|
||||
<span class="wrn-list__leading-icon"><span class='{item.icon}' aria-hidden="true"></span>
|
||||
</span>
|
||||
{/if}
|
||||
{#if item.imageSrc}
|
||||
<img src='{item.imageSrc}' alt='{item.imageAlt || ""}' class="wire-list__image" loading="lazy" />
|
||||
<img src='{item.imageSrc}' alt='{item.imageAlt || ""}' class="wrn-list__image" loading="lazy" />
|
||||
{/if}
|
||||
<div class="wire-list__body">
|
||||
<div class="wire-list__heading">
|
||||
<p class="wire-list__item-title">{item.title || item.label}</p>
|
||||
<div class="wrn-list__body">
|
||||
<div class="wrn-list__heading">
|
||||
<p class="wrn-list__item-title">{item.title || item.label}</p>
|
||||
{#if item.meta}
|
||||
<span class="wire-list__meta">{item.meta}</span>
|
||||
<span class="wrn-list__meta">{item.meta}</span>
|
||||
{/if}
|
||||
</div>
|
||||
{#if item.description}
|
||||
<p class="wire-list__item-description">{item.description}</p>
|
||||
<p class="wrn-list__item-description">{item.description}</p>
|
||||
{/if}
|
||||
{#if item.badge}
|
||||
<span class="wire-list__badge">{item.badge}</span>
|
||||
<span class="wrn-list__badge">{item.badge}</span>
|
||||
{/if}
|
||||
</div>
|
||||
<span class="icon-[lucide--chevron-right] wire-list__chevron" aria-hidden="true"></span>
|
||||
<span class="icon-[lucide--chevron-right] wrn-list__chevron" aria-hidden="true"></span>
|
||||
</a>
|
||||
{:else}
|
||||
<div class="wire-list__row" data-size='{size}'>
|
||||
<div class="wrn-list__row" data-size='{size}'>
|
||||
{#if item.icon}
|
||||
<span class="wire-list__leading-icon"><span class='{item.icon}' aria-hidden="true"></span>
|
||||
<span class="wrn-list__leading-icon"><span class='{item.icon}' aria-hidden="true"></span>
|
||||
</span>
|
||||
{/if}
|
||||
<div class="wire-list__body">
|
||||
<p class="wire-list__item-title">{item.title || item.label}</p>
|
||||
<div class="wrn-list__body">
|
||||
<p class="wrn-list__item-title">{item.title || item.label}</p>
|
||||
{#if item.description}
|
||||
<p class="wire-list__item-description">{item.description}</p>
|
||||
<p class="wrn-list__item-description">{item.description}</p>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</li>
|
||||
{:empty}
|
||||
<li class="wire-list__empty">
|
||||
<li class="wrn-list__empty">
|
||||
No items available.
|
||||
</li>
|
||||
{/each}
|
||||
@@ -97,32 +97,32 @@ component List {
|
||||
}
|
||||
|
||||
style {
|
||||
.wire-list { width: 100%; }
|
||||
.wire-list__header { margin-bottom: 1rem; }
|
||||
.wire-list__title { color: var(--wire-color-text); font-size: 1.125rem; font-weight: 700; }
|
||||
.wire-list__description { margin-top: 0.25rem; color: var(--wire-color-text-muted); font-size: 0.875rem; line-height: 1.5rem; }
|
||||
.wire-list__items { overflow: hidden; }
|
||||
.wire-list__items:is([data-variant="default"], [data-variant="divided"]) > .wire-list__item + .wire-list__item { border-top: 1px solid var(--wire-color-border); }
|
||||
.wire-list__items[data-variant="card"] { border: 1px solid var(--wire-color-border); border-radius: calc(var(--wire-radius) * 1.5); background: var(--wire-color-surface-raised); }
|
||||
.wire-list__items[data-variant="separated"] { display: grid; gap: 0.75rem; }
|
||||
.wire-list__item { min-width: 0; }
|
||||
.wire-list__item[data-variant="separated"] { border: 1px solid var(--wire-color-border); border-radius: var(--wire-radius); background: var(--wire-color-surface-raised); }
|
||||
.wire-list__row { display: flex; min-width: 0; align-items: flex-start; gap: 0.75rem; padding: 0.75rem 1rem; outline: none; transition: background var(--wire-motion-base); }
|
||||
a.wire-list__row:hover { background: var(--wire-color-surface-soft); }
|
||||
.wire-list__row:focus-visible { box-shadow: inset 0 0 0 2px var(--wire-color-focus); }
|
||||
.wire-list__row[data-size="sm"] { padding: 0.625rem 0.75rem; }
|
||||
.wire-list__row[data-size="lg"] { padding: 1rem 1.25rem; }
|
||||
.wire-list__leading-icon { display: flex; width: 2.5rem; height: 2.5rem; flex: none; align-items: center; justify-content: center; border-radius: var(--wire-radius); color: var(--wire-color-primary); background: var(--wire-color-primary-soft); }
|
||||
.wire-list__leading-icon > span { width: 1.25rem; height: 1.25rem; }
|
||||
.wire-list__image { width: 3rem; height: 3rem; flex: none; border-radius: var(--wire-radius); object-fit: cover; }
|
||||
.wire-list__body { min-width: 0; flex: 1; }
|
||||
.wire-list__heading { display: flex; align-items: flex-start; justify-content: space-between; gap: 0.75rem; }
|
||||
.wire-list__item-title { overflow: hidden; color: var(--wire-color-text); font-weight: 600; text-overflow: ellipsis; white-space: nowrap; }
|
||||
.wire-list__meta { flex: none; color: var(--wire-color-text-muted); font-size: 0.75rem; }
|
||||
.wire-list__item-description { display: -webkit-box; margin-top: 0.25rem; overflow: hidden; color: var(--wire-color-text-muted); font-size: 0.875rem; line-height: 1.25rem; -webkit-box-orient: vertical; -webkit-line-clamp: 2; }
|
||||
.wire-list__badge { display: inline-flex; margin-top: 0.5rem; padding: 0.25rem 0.625rem; border-radius: 999px; color: var(--wire-color-primary); background: var(--wire-color-primary-soft); font-size: 0.75rem; font-weight: 600; }
|
||||
.wire-list__chevron { width: 1rem; height: 1rem; flex: none; margin-top: 0.25rem; color: var(--wire-color-text-muted); transition: color var(--wire-motion-base), transform var(--wire-motion-base); }
|
||||
.wire-list__row:hover .wire-list__chevron { color: var(--wire-color-primary); transform: translateX(0.125rem); }
|
||||
.wire-list__empty { padding: 1.5rem; border: 1px dashed var(--wire-color-border); border-radius: var(--wire-radius); color: var(--wire-color-text-muted); font-size: 0.875rem; text-align: center; }
|
||||
.wrn-list { width: 100%; }
|
||||
.wrn-list__header { margin-bottom: 1rem; }
|
||||
.wrn-list__title { color: var(--wrn-color-text); font-size: 1.125rem; font-weight: 700; }
|
||||
.wrn-list__description { margin-top: 0.25rem; color: var(--wrn-color-text-muted); font-size: 0.875rem; line-height: 1.5rem; }
|
||||
.wrn-list__items { overflow: hidden; }
|
||||
.wrn-list__items:is([data-variant="default"], [data-variant="divided"]) > .wrn-list__item + .wrn-list__item { border-top: 1px solid var(--wrn-color-border); }
|
||||
.wrn-list__items[data-variant="card"] { border: 1px solid var(--wrn-color-border); border-radius: calc(var(--wrn-radius) * 1.5); background: var(--wrn-color-surface-raised); }
|
||||
.wrn-list__items[data-variant="separated"] { display: grid; gap: 0.75rem; }
|
||||
.wrn-list__item { min-width: 0; }
|
||||
.wrn-list__item[data-variant="separated"] { border: 1px solid var(--wrn-color-border); border-radius: var(--wrn-radius); background: var(--wrn-color-surface-raised); }
|
||||
.wrn-list__row { display: flex; min-width: 0; align-items: flex-start; gap: 0.75rem; padding: 0.75rem 1rem; outline: none; transition: background var(--wrn-motion-base); }
|
||||
a.wrn-list__row:hover { background: var(--wrn-color-surface-soft); }
|
||||
.wrn-list__row:focus-visible { box-shadow: inset 0 0 0 2px var(--wrn-color-focus); }
|
||||
.wrn-list__row[data-size="sm"] { padding: 0.625rem 0.75rem; }
|
||||
.wrn-list__row[data-size="lg"] { padding: 1rem 1.25rem; }
|
||||
.wrn-list__leading-icon { display: flex; width: 2.5rem; height: 2.5rem; flex: none; align-items: center; justify-content: center; border-radius: var(--wrn-radius); color: var(--wrn-color-primary); background: var(--wrn-color-primary-soft); }
|
||||
.wrn-list__leading-icon > span { width: 1.25rem; height: 1.25rem; }
|
||||
.wrn-list__image { width: 3rem; height: 3rem; flex: none; border-radius: var(--wrn-radius); object-fit: cover; }
|
||||
.wrn-list__body { min-width: 0; flex: 1; }
|
||||
.wrn-list__heading { display: flex; align-items: flex-start; justify-content: space-between; gap: 0.75rem; }
|
||||
.wrn-list__item-title { overflow: hidden; color: var(--wrn-color-text); font-weight: 600; text-overflow: ellipsis; white-space: nowrap; }
|
||||
.wrn-list__meta { flex: none; color: var(--wrn-color-text-muted); font-size: 0.75rem; }
|
||||
.wrn-list__item-description { display: -webkit-box; margin-top: 0.25rem; overflow: hidden; color: var(--wrn-color-text-muted); font-size: 0.875rem; line-height: 1.25rem; -webkit-box-orient: vertical; -webkit-line-clamp: 2; }
|
||||
.wrn-list__badge { display: inline-flex; margin-top: 0.5rem; padding: 0.25rem 0.625rem; border-radius: 999px; color: var(--wrn-color-primary); background: var(--wrn-color-primary-soft); font-size: 0.75rem; font-weight: 600; }
|
||||
.wrn-list__chevron { width: 1rem; height: 1rem; flex: none; margin-top: 0.25rem; color: var(--wrn-color-text-muted); transition: color var(--wrn-motion-base), transform var(--wrn-motion-base); }
|
||||
.wrn-list__row:hover .wrn-list__chevron { color: var(--wrn-color-primary); transform: translateX(0.125rem); }
|
||||
.wrn-list__empty { padding: 1.5rem; border: 1px dashed var(--wrn-color-border); border-radius: var(--wrn-radius); color: var(--wrn-color-text-muted); font-size: 0.875rem; text-align: center; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import ComponentBaseStyles from "../styles/ComponentBaseStyles.wrn"
|
||||
|
||||
component ListGroup {
|
||||
outputs {
|
||||
select(payload: { value?: string | number | boolean | null; values?: Array<string | number | boolean | null | object>; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | string | number | boolean | null)
|
||||
@@ -16,27 +14,95 @@ component ListGroup {
|
||||
class: string = ""
|
||||
}
|
||||
view {
|
||||
<section class="wire-component wire-component--color-{color} wire-component--size-{size} wire-next--list-group wire-next--variant-{variant} {class}">
|
||||
<section class="wrn-component wrn-component--color-{color} wrn-component--size-{size} wrn-next--list-group wrn-next--variant-{variant} {class}">
|
||||
{#if title}<strong>{title}</strong>{/if}
|
||||
{#if description}<p>{description}</p>{/if}
|
||||
{#if items}<div class="wire-next__items">{#each items as item}<span>{item.label}</span>{/each}</div>{/if}
|
||||
{#if items}<div class="wrn-next__items">{#each items as item}<span>{item.label}</span>{/each}</div>{/if}
|
||||
<slot />
|
||||
</section>
|
||||
<ComponentBaseStyles hidden />
|
||||
}
|
||||
|
||||
style {
|
||||
.wire-next--list-group {
|
||||
.wrn-next--list-group {
|
||||
display: grid;
|
||||
gap: 0.75rem;
|
||||
padding: 1rem;
|
||||
border: 1px solid var(--wire-color-border);
|
||||
border-radius: var(--wire-radius);
|
||||
color: var(--wire-color-text);
|
||||
background: var(--wire-color-surface);
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: var(--wrn-radius);
|
||||
color: var(--wrn-color-text);
|
||||
background: var(--wrn-color-surface);
|
||||
}
|
||||
.wire-next--list-group > p { margin: 0; color: var(--wire-color-muted); }
|
||||
.wire-next--list-group > .wire-next__items { display: flex; flex-wrap: wrap; gap: 0.5rem; }
|
||||
.wire-next--list-group > .wire-next__items > span { padding: 0.35rem 0.6rem; border-radius: var(--wire-radius-sm); background: var(--wire-color-surface-2); }
|
||||
.wrn-next--list-group > p { margin: 0; color: var(--wrn-color-muted); }
|
||||
.wrn-next--list-group > .wrn-next__items { display: flex; flex-wrap: wrap; gap: 0.5rem; }
|
||||
.wrn-next--list-group > .wrn-next__items > span { padding: 0.35rem 0.6rem; border-radius: var(--wrn-radius-sm); background: var(--wrn-color-surface-2); }
|
||||
|
||||
/* Shared component foundation. */
|
||||
|
||||
.wrn-component {
|
||||
--wrn-component-color: var(--wrn-color-primary);
|
||||
--wrn-component-scale: 1;
|
||||
margin: 0;
|
||||
color: var(--wrn-color-text);
|
||||
font-family: var(--wrn-font-sans, inherit);
|
||||
}
|
||||
|
||||
.wrn-component--color-primary {
|
||||
--wrn-component-color: var(--wrn-color-primary);
|
||||
}
|
||||
|
||||
.wrn-component--color-secondary {
|
||||
--wrn-component-color: var(--wrn-color-secondary);
|
||||
}
|
||||
|
||||
.wrn-component--color-success {
|
||||
--wrn-component-color: var(--wrn-color-success);
|
||||
}
|
||||
|
||||
.wrn-component--color-warning {
|
||||
--wrn-component-color: var(--wrn-color-warning);
|
||||
}
|
||||
|
||||
.wrn-component--color-danger {
|
||||
--wrn-component-color: var(--wrn-color-danger);
|
||||
}
|
||||
|
||||
.wrn-component--color-info {
|
||||
--wrn-component-color: var(--wrn-color-info);
|
||||
}
|
||||
|
||||
.wrn-component--size-xs {
|
||||
--wrn-component-scale: 0.78;
|
||||
}
|
||||
|
||||
.wrn-component--size-sm {
|
||||
--wrn-component-scale: 0.88;
|
||||
}
|
||||
|
||||
.wrn-component--size-default,
|
||||
.wrn-component--size-md {
|
||||
--wrn-component-scale: 1;
|
||||
}
|
||||
|
||||
.wrn-component--size-lg {
|
||||
--wrn-component-scale: 1.14;
|
||||
}
|
||||
|
||||
.wrn-component--size-xl {
|
||||
--wrn-component-scale: 1.28;
|
||||
}
|
||||
|
||||
.wrn-component:not(.wrn-btn) {
|
||||
font-size: calc(1em * var(--wrn-component-scale));
|
||||
}
|
||||
|
||||
.wrn-component :is(a, button, input, select, textarea):focus-visible {
|
||||
outline-color: var(--wrn-component-color);
|
||||
}
|
||||
|
||||
.wrn-component p {
|
||||
margin: 0;
|
||||
color: var(--wrn-color-muted);
|
||||
line-height: 1.6;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,34 +21,34 @@ component Map {
|
||||
<section
|
||||
data-ui-component="Map"
|
||||
aria-label='{title}'
|
||||
class='wire-map {class}'
|
||||
class='wrn-map {class}'
|
||||
>
|
||||
{#if title || description}
|
||||
<header class="wire-map__header">
|
||||
<header class="wrn-map__header">
|
||||
<div>
|
||||
{#if title}
|
||||
<h3 class="wire-map__title">{title}</h3>
|
||||
<h3 class="wrn-map__title">{title}</h3>
|
||||
{/if}
|
||||
{#if description}
|
||||
<p class="wire-map__description">{description}</p>
|
||||
<p class="wrn-map__description">{description}</p>
|
||||
{/if}
|
||||
</div>
|
||||
<span class="wire-map__header-icon"><span class="icon-[lucide--map]" aria-hidden="true"></span>
|
||||
<span class="wrn-map__header-icon"><span class="icon-[lucide--map]" aria-hidden="true"></span>
|
||||
</span>
|
||||
</header>
|
||||
{/if}
|
||||
|
||||
<div
|
||||
class="wire-map__viewport"
|
||||
class="wrn-map__viewport"
|
||||
data-size='{size}'
|
||||
>
|
||||
<div
|
||||
class="wire-map__grid"
|
||||
style="background-image: linear-gradient(var(--wire-color-border) 1px, transparent 1px), linear-gradient(90deg, var(--wire-color-border) 1px, transparent 1px); background-size: 32px 32px;"
|
||||
class="wrn-map__grid"
|
||||
style="background-image: linear-gradient(var(--wrn-color-border) 1px, transparent 1px), linear-gradient(90deg, var(--wrn-color-border) 1px, transparent 1px); background-size: 32px 32px;"
|
||||
aria-hidden="true"
|
||||
></div>
|
||||
|
||||
<div class="wire-map__content">
|
||||
<div class="wrn-map__content">
|
||||
<slot></slot>
|
||||
</div>
|
||||
|
||||
@@ -57,7 +57,7 @@ component Map {
|
||||
<button
|
||||
type="button"
|
||||
aria-label='{item.label || item.title || "Map marker"}'
|
||||
class="wire-map__marker"
|
||||
class="wrn-map__marker"
|
||||
style='left: {item.x || (20 + index * 12)}%; top: {item.y || (30 + (index % 3) * 18)}%;'
|
||||
@click='output.markerClick(item); output.select(item)'
|
||||
>
|
||||
@@ -66,22 +66,22 @@ component Map {
|
||||
{/each}
|
||||
{/if}
|
||||
|
||||
<div class="wire-map__controls">
|
||||
<div class="wrn-map__controls">
|
||||
<button
|
||||
type="button"
|
||||
aria-label="Zoom in"
|
||||
class="wire-map__control"
|
||||
class="wrn-map__control"
|
||||
@click='output.zoom({ direction: "in" })'
|
||||
>
|
||||
<span class="icon-[lucide--plus] wire-map__control-icon" aria-hidden="true"></span>
|
||||
<span class="icon-[lucide--plus] wrn-map__control-icon" aria-hidden="true"></span>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
aria-label="Zoom out"
|
||||
class="wire-map__control"
|
||||
class="wrn-map__control"
|
||||
@click='output.zoom({ direction: "out" })'
|
||||
>
|
||||
<span class="icon-[lucide--minus] wire-map__control-icon" aria-hidden="true"></span>
|
||||
<span class="icon-[lucide--minus] wrn-map__control-icon" aria-hidden="true"></span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -89,23 +89,23 @@ component Map {
|
||||
}
|
||||
|
||||
style {
|
||||
.wire-map { overflow: hidden; border: 1px solid var(--wire-color-border); border-radius: calc(var(--wire-radius) * 1.5); background: var(--wire-color-surface-raised); box-shadow: var(--wire-shadow-1); }
|
||||
.wire-map__header { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; padding: 1.25rem; border-bottom: 1px solid var(--wire-color-border); }
|
||||
.wire-map__title { color: var(--wire-color-text); font-size: 1.125rem; font-weight: 700; }
|
||||
.wire-map__description { margin-top: 0.25rem; color: var(--wire-color-text-muted); font-size: 0.875rem; line-height: 1.5rem; }
|
||||
.wire-map__header-icon { display: flex; width: 2.5rem; height: 2.5rem; flex: none; align-items: center; justify-content: center; border-radius: var(--wire-radius); color: var(--wire-color-primary); background: var(--wire-color-primary-soft); }
|
||||
.wire-map__header-icon > span { width: 1.25rem; height: 1.25rem; }
|
||||
.wire-map__viewport { position: relative; isolation: isolate; height: 20rem; overflow: hidden; background: var(--wire-color-surface-soft); }
|
||||
.wire-map__viewport[data-size="sm"] { height: 16rem; }
|
||||
.wire-map__viewport[data-size="lg"] { height: 28rem; }
|
||||
.wire-map__grid { position: absolute; inset: 0; opacity: 0.5; pointer-events: none; }
|
||||
.wire-map__content { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; padding: 1.5rem; }
|
||||
.wire-map__marker { position: absolute; display: inline-flex; width: 2.5rem; height: 2.5rem; align-items: center; justify-content: center; padding: 0; border: 4px solid var(--wire-color-surface-raised); border-radius: 50%; color: var(--wire-color-on-primary); background: var(--wire-color-primary); box-shadow: var(--wire-shadow-3); transition: transform var(--wire-motion-base) var(--wire-ease-standard); }
|
||||
.wire-map__marker:hover { transform: scale(1.1); }
|
||||
.wire-map__controls { position: absolute; right: 1rem; bottom: 1rem; display: flex; flex-direction: column; gap: 0.5rem; }
|
||||
.wire-map__control { display: inline-flex; width: 2.5rem; height: 2.5rem; align-items: center; justify-content: center; padding: 0; border: 1px solid var(--wire-color-border); border-radius: var(--wire-radius); color: var(--wire-color-text); background: var(--wire-color-surface-raised); box-shadow: var(--wire-shadow-1); transition: background var(--wire-motion-base); }
|
||||
.wire-map__control:hover { background: var(--wire-color-surface-soft); }
|
||||
.wire-map__marker:focus-visible, .wire-map__control:focus-visible { outline: 2px solid var(--wire-color-focus); outline-offset: 2px; }
|
||||
.wire-map__control-icon { width: 1rem; height: 1rem; }
|
||||
.wrn-map { overflow: hidden; border: 1px solid var(--wrn-color-border); border-radius: calc(var(--wrn-radius) * 1.5); background: var(--wrn-color-surface-raised); box-shadow: var(--wrn-shadow-1); }
|
||||
.wrn-map__header { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; padding: 1.25rem; border-bottom: 1px solid var(--wrn-color-border); }
|
||||
.wrn-map__title { color: var(--wrn-color-text); font-size: 1.125rem; font-weight: 700; }
|
||||
.wrn-map__description { margin-top: 0.25rem; color: var(--wrn-color-text-muted); font-size: 0.875rem; line-height: 1.5rem; }
|
||||
.wrn-map__header-icon { display: flex; width: 2.5rem; height: 2.5rem; flex: none; align-items: center; justify-content: center; border-radius: var(--wrn-radius); color: var(--wrn-color-primary); background: var(--wrn-color-primary-soft); }
|
||||
.wrn-map__header-icon > span { width: 1.25rem; height: 1.25rem; }
|
||||
.wrn-map__viewport { position: relative; isolation: isolate; height: 20rem; overflow: hidden; background: var(--wrn-color-surface-soft); }
|
||||
.wrn-map__viewport[data-size="sm"] { height: 16rem; }
|
||||
.wrn-map__viewport[data-size="lg"] { height: 28rem; }
|
||||
.wrn-map__grid { position: absolute; inset: 0; opacity: 0.5; pointer-events: none; }
|
||||
.wrn-map__content { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; padding: 1.5rem; }
|
||||
.wrn-map__marker { position: absolute; display: inline-flex; width: 2.5rem; height: 2.5rem; align-items: center; justify-content: center; padding: 0; border: 4px solid var(--wrn-color-surface-raised); border-radius: 50%; color: var(--wrn-color-on-primary); background: var(--wrn-color-primary); box-shadow: var(--wrn-shadow-3); transition: transform var(--wrn-motion-base) var(--wrn-ease-standard); }
|
||||
.wrn-map__marker:hover { transform: scale(1.1); }
|
||||
.wrn-map__controls { position: absolute; right: 1rem; bottom: 1rem; display: flex; flex-direction: column; gap: 0.5rem; }
|
||||
.wrn-map__control { display: inline-flex; width: 2.5rem; height: 2.5rem; align-items: center; justify-content: center; padding: 0; border: 1px solid var(--wrn-color-border); border-radius: var(--wrn-radius); color: var(--wrn-color-text); background: var(--wrn-color-surface-raised); box-shadow: var(--wrn-shadow-1); transition: background var(--wrn-motion-base); }
|
||||
.wrn-map__control:hover { background: var(--wrn-color-surface-soft); }
|
||||
.wrn-map__marker:focus-visible, .wrn-map__control:focus-visible { outline: 2px solid var(--wrn-color-focus); outline-offset: 2px; }
|
||||
.wrn-map__control-icon { width: 1rem; height: 1rem; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,44 +21,44 @@ component Marquee {
|
||||
<section
|
||||
data-ui-component="Marquee"
|
||||
aria-label='{title}'
|
||||
class='wire-marquee {class}'
|
||||
class='wrn-marquee {class}'
|
||||
>
|
||||
<div class="wire-marquee__layout">
|
||||
<div class="wrn-marquee__layout">
|
||||
{#if title}
|
||||
<div class="wire-marquee__title">
|
||||
<span class="icon-[lucide--megaphone] wire-marquee__icon" aria-hidden="true"></span>
|
||||
<div class="wrn-marquee__title">
|
||||
<span class="icon-[lucide--megaphone] wrn-marquee__icon" aria-hidden="true"></span>
|
||||
<span>{title}</span>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<div
|
||||
class="wire-marquee__window"
|
||||
class="wrn-marquee__window"
|
||||
@mouseenter='paused = true; output.pause({})'
|
||||
@mouseleave='paused = false; output.resume({})'
|
||||
@focusin='paused = true'
|
||||
@focusout='paused = false'
|
||||
>
|
||||
<div
|
||||
class="wire-marquee__track"
|
||||
class:wire-marquee-paused='paused'
|
||||
class="wrn-marquee__track"
|
||||
class:wrn-marquee-paused='paused'
|
||||
>
|
||||
{#each items as item}
|
||||
<a
|
||||
href='{item.href || "#"}'
|
||||
class="wire-marquee__item"
|
||||
class="wrn-marquee__item"
|
||||
>
|
||||
<span
|
||||
class="wire-marquee__dot"
|
||||
class="wrn-marquee__dot"
|
||||
data-color='{item.color || "primary"}'
|
||||
aria-hidden="true"
|
||||
></span>
|
||||
<span>{item.label || item.title}</span>
|
||||
{#if item.meta}
|
||||
<span class="wire-marquee__meta">{item.meta}</span>
|
||||
<span class="wrn-marquee__meta">{item.meta}</span>
|
||||
{/if}
|
||||
</a>
|
||||
{:empty}
|
||||
<p class="wire-marquee__empty">{description || "No announcements available."}</p>
|
||||
<p class="wrn-marquee__empty">{description || "No announcements available."}</p>
|
||||
{/each}
|
||||
|
||||
{#if items.length > 0}
|
||||
@@ -67,9 +67,9 @@ component Marquee {
|
||||
href='{item.href || "#"}'
|
||||
aria-hidden="true"
|
||||
tabindex="-1"
|
||||
class="wire-marquee__item"
|
||||
class="wrn-marquee__item"
|
||||
>
|
||||
<span class="wire-marquee__dot" aria-hidden="true"></span>
|
||||
<span class="wrn-marquee__dot" aria-hidden="true"></span>
|
||||
<span>{item.label || item.title}</span>
|
||||
</a>
|
||||
{/each}
|
||||
@@ -80,11 +80,11 @@ component Marquee {
|
||||
<button
|
||||
type="button"
|
||||
aria-label='{paused ? "Resume announcements" : "Pause announcements"}'
|
||||
class="wire-marquee__toggle"
|
||||
class="wrn-marquee__toggle"
|
||||
@click='paused = !paused; paused ? output.pause({}) : output.resume({})'
|
||||
>
|
||||
<span class="icon-[lucide--pause] wire-marquee__icon" data-show='!paused' aria-hidden="true"></span>
|
||||
<span class="icon-[lucide--play] wire-marquee__icon" data-show='paused' aria-hidden="true"></span>
|
||||
<span class="icon-[lucide--pause] wrn-marquee__icon" data-show='!paused' aria-hidden="true"></span>
|
||||
<span class="icon-[lucide--play] wrn-marquee__icon" data-show='paused' aria-hidden="true"></span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -93,40 +93,40 @@ component Marquee {
|
||||
}
|
||||
|
||||
style {
|
||||
.wire-marquee { overflow: hidden; border-block: 1px solid var(--wire-color-border); background: var(--wire-color-surface-raised); }
|
||||
.wire-marquee__layout { display: flex; align-items: stretch; }
|
||||
.wire-marquee__title { position: relative; z-index: 1; display: flex; flex: none; align-items: center; gap: 0.5rem; padding: 0.75rem 1rem; border-right: 1px solid var(--wire-color-border); color: var(--wire-color-on-primary); background: var(--wire-color-primary); font-size: 0.875rem; font-weight: 700; }
|
||||
.wire-marquee__window { position: relative; min-width: 0; flex: 1; overflow: hidden; }
|
||||
.wire-marquee__track {
|
||||
.wrn-marquee { overflow: hidden; border-block: 1px solid var(--wrn-color-border); background: var(--wrn-color-surface-raised); }
|
||||
.wrn-marquee__layout { display: flex; align-items: stretch; }
|
||||
.wrn-marquee__title { position: relative; z-index: 1; display: flex; flex: none; align-items: center; gap: 0.5rem; padding: 0.75rem 1rem; border-right: 1px solid var(--wrn-color-border); color: var(--wrn-color-on-primary); background: var(--wrn-color-primary); font-size: 0.875rem; font-weight: 700; }
|
||||
.wrn-marquee__window { position: relative; min-width: 0; flex: 1; overflow: hidden; }
|
||||
.wrn-marquee__track {
|
||||
display: flex; width: max-content; min-width: 100%; align-items: center;
|
||||
animation: wire-marquee 32s linear infinite;
|
||||
animation: wrn-marquee 32s linear infinite;
|
||||
}
|
||||
.wire-marquee-paused { animation-play-state: paused; }
|
||||
.wire-marquee__item { display: flex; flex: none; align-items: center; gap: 0.75rem; padding: 0.75rem 1.25rem; color: var(--wire-color-text); font-size: 0.875rem; font-weight: 500; transition: color var(--wire-motion-base), background var(--wire-motion-base); }
|
||||
.wire-marquee__item:hover { color: var(--wire-color-primary); background: var(--wire-color-primary-soft); }
|
||||
.wire-marquee__item:focus-visible, .wire-marquee__toggle:focus-visible { outline: 2px solid var(--wire-color-focus); outline-offset: -2px; }
|
||||
.wire-marquee__dot { width: 0.5rem; height: 0.5rem; flex: none; border-radius: 50%; background: var(--wire-color-primary); }
|
||||
.wire-marquee__dot[data-color="danger"] { background: var(--wire-color-danger); }
|
||||
.wire-marquee__dot[data-color="warning"] { background: var(--wire-color-warning); }
|
||||
.wire-marquee__dot[data-color="success"] { background: var(--wire-color-success); }
|
||||
.wire-marquee__meta { color: var(--wire-color-text-muted); font-size: 0.75rem; }
|
||||
.wire-marquee__empty { padding: 0.75rem 1.25rem; color: var(--wire-color-text-muted); font-size: 0.875rem; }
|
||||
.wire-marquee__toggle { display: flex; flex: none; align-items: center; justify-content: center; padding-inline: 1rem; border: 0; border-left: 1px solid var(--wire-color-border); color: var(--wire-color-text-muted); background: transparent; transition: color var(--wire-motion-base), background var(--wire-motion-base); }
|
||||
.wire-marquee__toggle:hover { color: var(--wire-color-text); background: var(--wire-color-surface-soft); }
|
||||
.wire-marquee__icon { width: 1rem; height: 1rem; }
|
||||
@media (min-width: 40rem) { .wire-marquee__title { padding-inline: 1.25rem; } }
|
||||
.wrn-marquee-paused { animation-play-state: paused; }
|
||||
.wrn-marquee__item { display: flex; flex: none; align-items: center; gap: 0.75rem; padding: 0.75rem 1.25rem; color: var(--wrn-color-text); font-size: 0.875rem; font-weight: 500; transition: color var(--wrn-motion-base), background var(--wrn-motion-base); }
|
||||
.wrn-marquee__item:hover { color: var(--wrn-color-primary); background: var(--wrn-color-primary-soft); }
|
||||
.wrn-marquee__item:focus-visible, .wrn-marquee__toggle:focus-visible { outline: 2px solid var(--wrn-color-focus); outline-offset: -2px; }
|
||||
.wrn-marquee__dot { width: 0.5rem; height: 0.5rem; flex: none; border-radius: 50%; background: var(--wrn-color-primary); }
|
||||
.wrn-marquee__dot[data-color="danger"] { background: var(--wrn-color-danger); }
|
||||
.wrn-marquee__dot[data-color="warning"] { background: var(--wrn-color-warning); }
|
||||
.wrn-marquee__dot[data-color="success"] { background: var(--wrn-color-success); }
|
||||
.wrn-marquee__meta { color: var(--wrn-color-text-muted); font-size: 0.75rem; }
|
||||
.wrn-marquee__empty { padding: 0.75rem 1.25rem; color: var(--wrn-color-text-muted); font-size: 0.875rem; }
|
||||
.wrn-marquee__toggle { display: flex; flex: none; align-items: center; justify-content: center; padding-inline: 1rem; border: 0; border-left: 1px solid var(--wrn-color-border); color: var(--wrn-color-text-muted); background: transparent; transition: color var(--wrn-motion-base), background var(--wrn-motion-base); }
|
||||
.wrn-marquee__toggle:hover { color: var(--wrn-color-text); background: var(--wrn-color-surface-soft); }
|
||||
.wrn-marquee__icon { width: 1rem; height: 1rem; }
|
||||
@media (min-width: 40rem) { .wrn-marquee__title { padding-inline: 1.25rem; } }
|
||||
|
||||
.wire-marquee-paused {
|
||||
.wrn-marquee-paused {
|
||||
animation-play-state: paused;
|
||||
}
|
||||
|
||||
@keyframes wire-marquee {
|
||||
@keyframes wrn-marquee {
|
||||
from { transform: translateX(0); }
|
||||
to { transform: translateX(-50%); }
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.wire-marquee__track {
|
||||
.wrn-marquee__track {
|
||||
animation: none;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ component MegaMenu {
|
||||
<div
|
||||
{...attrs}
|
||||
data-ui-component="MegaMenu"
|
||||
class='wire-mega {class}'
|
||||
class='wrn-mega {class}'
|
||||
data-color='{color}'
|
||||
data-size='{size}'
|
||||
data-open='{visible}'
|
||||
@@ -89,46 +89,46 @@ component MegaMenu {
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
class="wire-mega__trigger"
|
||||
class="wrn-mega__trigger"
|
||||
aria-haspopup="true"
|
||||
aria-expanded='{visible}'
|
||||
@click='togglePanel(event)'
|
||||
@mouseenter='showPanel(event)'
|
||||
@focus='showPanel(event)'
|
||||
>
|
||||
<span class='wire-mega__trigger-icon {icon}' data-show="icon" aria-hidden="true"></span>
|
||||
<span class="wire-mega__trigger-label">{label}</span>
|
||||
<span class="wire-mega__arrow" aria-hidden="true">›</span>
|
||||
<span class='wrn-mega__trigger-icon {icon}' data-show="icon" aria-hidden="true"></span>
|
||||
<span class="wrn-mega__trigger-label">{label}</span>
|
||||
<span class="wrn-mega__arrow" aria-hidden="true">›</span>
|
||||
</button>
|
||||
|
||||
<div
|
||||
class="wire-mega__panel"
|
||||
class="wrn-mega__panel"
|
||||
data-wrn-anchored="true"
|
||||
data-show="visible"
|
||||
data-wrn-roving="both"
|
||||
>
|
||||
<div class="wire-mega__columns">
|
||||
<div class="wrn-mega__columns">
|
||||
{#each columnList() as column}
|
||||
<section class="wire-mega__column">
|
||||
<h3 class="wire-mega__heading" data-show="column.heading">{column.heading}</h3>
|
||||
<ul class="wire-mega__list">
|
||||
<section class="wrn-mega__column">
|
||||
<h3 class="wrn-mega__heading" data-show="column.heading">{column.heading}</h3>
|
||||
<ul class="wrn-mega__list">
|
||||
{#each itemsOf(column) as item}
|
||||
<li>
|
||||
<a
|
||||
class="wire-mega__link"
|
||||
class="wrn-mega__link"
|
||||
href='{item.href || "#"}'
|
||||
data-wrn-roving-item="true"
|
||||
aria-disabled='{item.disabled ? "true" : "false"}'
|
||||
@click='choose(item)'
|
||||
>
|
||||
<span
|
||||
class='wire-mega__link-icon {item.icon}'
|
||||
class='wrn-mega__link-icon {item.icon}'
|
||||
data-show="item.icon"
|
||||
aria-hidden="true"
|
||||
></span>
|
||||
<span class="wire-mega__link-body">
|
||||
<span class="wire-mega__link-label">{item.label}</span>
|
||||
<span class="wire-mega__link-description" data-show="item.description">
|
||||
<span class="wrn-mega__link-body">
|
||||
<span class="wrn-mega__link-label">{item.label}</span>
|
||||
<span class="wrn-mega__link-description" data-show="item.description">
|
||||
{item.description}
|
||||
</span>
|
||||
</span>
|
||||
@@ -140,77 +140,77 @@ component MegaMenu {
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
<p class="wire-mega__footer" data-show="footer">{footer}</p>
|
||||
<p class="wrn-mega__footer" data-show="footer">{footer}</p>
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
style {
|
||||
.wire-mega {
|
||||
--mega-accent: var(--wire-color-primary);
|
||||
.wrn-mega {
|
||||
--mega-accent: var(--wrn-color-primary);
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.wire-mega[data-color="secondary"] {
|
||||
--mega-accent: var(--wire-color-secondary);
|
||||
.wrn-mega[data-color="secondary"] {
|
||||
--mega-accent: var(--wrn-color-secondary);
|
||||
}
|
||||
|
||||
.wire-mega[data-color="success"] {
|
||||
--mega-accent: var(--wire-color-success);
|
||||
.wrn-mega[data-color="success"] {
|
||||
--mega-accent: var(--wrn-color-success);
|
||||
}
|
||||
|
||||
.wire-mega[data-color="danger"] {
|
||||
--mega-accent: var(--wire-color-danger);
|
||||
.wrn-mega[data-color="danger"] {
|
||||
--mega-accent: var(--wrn-color-danger);
|
||||
}
|
||||
|
||||
.wire-mega[data-color="info"] {
|
||||
--mega-accent: var(--wire-color-info);
|
||||
.wrn-mega[data-color="info"] {
|
||||
--mega-accent: var(--wrn-color-info);
|
||||
}
|
||||
|
||||
.wire-mega[data-size="sm"] {
|
||||
.wrn-mega[data-size="sm"] {
|
||||
font-size: 0.82rem;
|
||||
}
|
||||
|
||||
.wire-mega[data-size="lg"] {
|
||||
.wrn-mega[data-size="lg"] {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.wire-mega__trigger {
|
||||
.wrn-mega__trigger {
|
||||
appearance: none;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.4rem;
|
||||
padding: 0.45rem 0.7rem;
|
||||
border: 1px solid transparent;
|
||||
border-radius: var(--wire-radius-sm);
|
||||
border-radius: var(--wrn-radius-sm);
|
||||
background: transparent;
|
||||
color: var(--wire-color-text-muted);
|
||||
color: var(--wrn-color-text-muted);
|
||||
font: inherit;
|
||||
font-size: 0.9rem;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.wire-mega__trigger:hover,
|
||||
.wire-mega[data-open="true"] .wire-mega__trigger {
|
||||
background: var(--wire-color-surface-soft);
|
||||
color: var(--wire-color-text);
|
||||
.wrn-mega__trigger:hover,
|
||||
.wrn-mega[data-open="true"] .wrn-mega__trigger {
|
||||
background: var(--wrn-color-surface-soft);
|
||||
color: var(--wrn-color-text);
|
||||
}
|
||||
|
||||
.wire-mega__trigger:focus-visible {
|
||||
.wrn-mega__trigger:focus-visible {
|
||||
outline: 2px solid var(--mega-accent);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
.wire-mega__arrow {
|
||||
.wrn-mega__arrow {
|
||||
display: inline-block;
|
||||
transition: transform 160ms ease;
|
||||
}
|
||||
|
||||
.wire-mega[data-open="true"] .wire-mega__arrow {
|
||||
.wrn-mega[data-open="true"] .wrn-mega__arrow {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
|
||||
@@ -220,7 +220,7 @@ component MegaMenu {
|
||||
* element, so crossing it fired mouseleave on the root. The bridge below
|
||||
* covers the gap with a descendant, so the pointer never actually leaves.
|
||||
*/
|
||||
.wire-mega__panel::before {
|
||||
.wrn-mega__panel::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 0;
|
||||
@@ -229,7 +229,7 @@ component MegaMenu {
|
||||
height: 0.6rem;
|
||||
}
|
||||
|
||||
.wire-mega__panel {
|
||||
.wrn-mega__panel {
|
||||
position: absolute;
|
||||
z-index: 40;
|
||||
top: calc(100% + 0.4rem);
|
||||
@@ -237,32 +237,32 @@ component MegaMenu {
|
||||
width: max-content;
|
||||
max-width: min(60rem, calc(100vw - 2rem));
|
||||
padding: 1rem;
|
||||
border: 1px solid var(--wire-color-border);
|
||||
border-radius: var(--wire-radius-lg);
|
||||
background: var(--wire-color-surface);
|
||||
box-shadow: var(--wire-shadow-1);
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: var(--wrn-radius-lg);
|
||||
background: var(--wrn-color-surface);
|
||||
box-shadow: var(--wrn-shadow-1);
|
||||
}
|
||||
|
||||
.wire-mega__columns {
|
||||
.wrn-mega__columns {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
|
||||
gap: 1.25rem;
|
||||
}
|
||||
|
||||
.wire-mega__column {
|
||||
.wrn-mega__column {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.wire-mega__heading {
|
||||
.wrn-mega__heading {
|
||||
margin: 0 0 0.5rem;
|
||||
color: var(--wire-color-text-muted);
|
||||
color: var(--wrn-color-text-muted);
|
||||
font-size: 0.72rem;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.08em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.wire-mega__list {
|
||||
.wrn-mega__list {
|
||||
display: grid;
|
||||
gap: 0.15rem;
|
||||
margin: 0;
|
||||
@@ -270,52 +270,52 @@ component MegaMenu {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.wire-mega__link {
|
||||
.wrn-mega__link {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 0.5rem;
|
||||
padding: 0.45rem 0.5rem;
|
||||
border-radius: var(--wire-radius-sm);
|
||||
color: var(--wire-color-text);
|
||||
border-radius: var(--wrn-radius-sm);
|
||||
color: var(--wrn-color-text);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.wire-mega__link:hover {
|
||||
background: var(--wire-color-surface-soft);
|
||||
.wrn-mega__link:hover {
|
||||
background: var(--wrn-color-surface-soft);
|
||||
}
|
||||
|
||||
.wire-mega__link:focus-visible {
|
||||
.wrn-mega__link:focus-visible {
|
||||
outline: 2px solid var(--mega-accent);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
.wire-mega__link[aria-disabled="true"] {
|
||||
.wrn-mega__link[aria-disabled="true"] {
|
||||
opacity: 0.5;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.wire-mega__link-body {
|
||||
.wrn-mega__link-body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.wire-mega__link-label {
|
||||
.wrn-mega__link-label {
|
||||
font-size: 0.88rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.wire-mega__link-description {
|
||||
color: var(--wire-color-text-muted);
|
||||
.wrn-mega__link-description {
|
||||
color: var(--wrn-color-text-muted);
|
||||
font-size: 0.78rem;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.wire-mega__footer {
|
||||
.wrn-mega__footer {
|
||||
margin: 1rem 0 0;
|
||||
padding-top: 0.75rem;
|
||||
border-top: 1px solid var(--wire-color-border);
|
||||
color: var(--wire-color-text-muted);
|
||||
border-top: 1px solid var(--wrn-color-border);
|
||||
color: var(--wrn-color-text-muted);
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
@@ -325,18 +325,18 @@ component MegaMenu {
|
||||
* a 60rem grid has nowhere to go on a 360px screen.
|
||||
*/
|
||||
@media (max-width: 767px) {
|
||||
.wire-mega {
|
||||
.wrn-mega {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.wire-mega__panel {
|
||||
.wrn-mega__panel {
|
||||
position: static;
|
||||
width: auto;
|
||||
max-width: 100%;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.wire-mega__columns {
|
||||
.wrn-mega__columns {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
+132
-132
@@ -59,7 +59,7 @@ component Modal {
|
||||
// )
|
||||
//
|
||||
// The listener is on the modal root, so the event only ever closes the
|
||||
// modal the dispatching element is actually inside -- no ids to wire up
|
||||
// modal the dispatching element is actually inside -- no ids to wrn up
|
||||
// and no way to close somebody else's modal by accident.
|
||||
client function hideModal(reason, sourceEvent) {
|
||||
visible = false
|
||||
@@ -106,13 +106,13 @@ component Modal {
|
||||
data-scrollable='{scrollable ? "true" : "false"}'
|
||||
data-scroll='{scrollBehavior}'
|
||||
data-destructive='{destructive ? "true" : "false"}'
|
||||
class='wire-modal {class}'
|
||||
class='wrn-modal {class}'
|
||||
@wrnexus:modal:close='hideModal("api", event)'
|
||||
>
|
||||
{#if triggerLabel}
|
||||
<button
|
||||
type="button"
|
||||
class="wire-modal__trigger"
|
||||
class="wrn-modal__trigger"
|
||||
aria-haspopup="dialog"
|
||||
aria-expanded='{isOpen() ? "true" : "false"}'
|
||||
@click='showModal(event)'
|
||||
@@ -129,7 +129,7 @@ component Modal {
|
||||
{/if}
|
||||
|
||||
<span
|
||||
class="wire-modal__trigger-slot"
|
||||
class="wrn-modal__trigger-slot"
|
||||
@click='showModal(event)'
|
||||
>
|
||||
<slot
|
||||
@@ -139,42 +139,42 @@ component Modal {
|
||||
</span>
|
||||
|
||||
<div
|
||||
class="wire-modal__layer"
|
||||
class="wrn-modal__layer"
|
||||
data-show="isOpen()"
|
||||
role="presentation"
|
||||
@keydown='handleKeydown(event)'
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
class="wire-modal__backdrop"
|
||||
class="wrn-modal__backdrop"
|
||||
aria-label='{closeLabel}'
|
||||
@click='if (closeOnBackdrop) { cancelModal(event) }'
|
||||
>
|
||||
</button>
|
||||
|
||||
<section
|
||||
class="wire-modal__panel"
|
||||
class="wrn-modal__panel"
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
aria-label='{label || title}'
|
||||
tabindex="-1"
|
||||
>
|
||||
<header
|
||||
class="wire-modal__header"
|
||||
class="wrn-modal__header"
|
||||
>
|
||||
<div
|
||||
class="wire-modal__heading"
|
||||
class="wrn-modal__heading"
|
||||
>
|
||||
{#if icon}
|
||||
<span
|
||||
class='wire-modal__icon {icon}'
|
||||
class='wrn-modal__icon {icon}'
|
||||
aria-hidden="true"
|
||||
>
|
||||
</span>
|
||||
{/if}
|
||||
|
||||
<div
|
||||
class="wire-modal__heading-copy"
|
||||
class="wrn-modal__heading-copy"
|
||||
>
|
||||
<slot
|
||||
name="header"
|
||||
@@ -192,7 +192,7 @@ component Modal {
|
||||
{#if showClose}
|
||||
<button
|
||||
type="button"
|
||||
class="wire-modal__close"
|
||||
class="wrn-modal__close"
|
||||
aria-label='{closeLabel}'
|
||||
@click='hideModal("close-button", event)'
|
||||
>
|
||||
@@ -215,17 +215,17 @@ component Modal {
|
||||
</header>
|
||||
|
||||
<div
|
||||
class="wire-modal__body"
|
||||
class="wrn-modal__body"
|
||||
>
|
||||
<slot></slot>
|
||||
</div>
|
||||
|
||||
{#if showFooter}
|
||||
<footer
|
||||
class="wire-modal__footer"
|
||||
class="wrn-modal__footer"
|
||||
>
|
||||
<div
|
||||
class="wire-modal__custom-footer"
|
||||
class="wrn-modal__custom-footer"
|
||||
>
|
||||
<slot
|
||||
name="footer"
|
||||
@@ -234,12 +234,12 @@ component Modal {
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="wire-modal__actions"
|
||||
class="wrn-modal__actions"
|
||||
>
|
||||
{#if cancelLabel}
|
||||
<button
|
||||
type="button"
|
||||
class="wire-modal__button wire-modal__button--secondary"
|
||||
class="wrn-modal__button wrn-modal__button--secondary"
|
||||
@click='cancelModal(event)'
|
||||
>
|
||||
{#if cancelIcon}
|
||||
@@ -256,13 +256,13 @@ component Modal {
|
||||
{#if confirmLabel}
|
||||
<button
|
||||
type="button"
|
||||
class="wire-modal__button wire-modal__button--primary"
|
||||
class="wrn-modal__button wrn-modal__button--primary"
|
||||
disabled='{confirmDisabled || confirmLoading}'
|
||||
@click='confirmModal(event)'
|
||||
>
|
||||
{#if confirmLoading}
|
||||
<span
|
||||
class="wire-modal__spinner"
|
||||
class="wrn-modal__spinner"
|
||||
aria-hidden="true"
|
||||
>
|
||||
</span>
|
||||
@@ -285,63 +285,63 @@ component Modal {
|
||||
}
|
||||
|
||||
style {
|
||||
.wire-modal {
|
||||
--modal-accent: var(--wire-color-primary);
|
||||
--modal-soft: var(--wire-color-primary-soft);
|
||||
--modal-contrast: var(--wire-color-primary-contrast);
|
||||
.wrn-modal {
|
||||
--modal-accent: var(--wrn-color-primary);
|
||||
--modal-soft: var(--wrn-color-primary-soft);
|
||||
--modal-contrast: var(--wrn-color-primary-contrast);
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
.wire-modal[data-color="secondary"] {
|
||||
--modal-accent: var(--wire-color-secondary);
|
||||
--modal-soft: var(--wire-color-secondary-soft);
|
||||
--modal-contrast: var(--wire-color-secondary-contrast);
|
||||
.wrn-modal[data-color="secondary"] {
|
||||
--modal-accent: var(--wrn-color-secondary);
|
||||
--modal-soft: var(--wrn-color-secondary-soft);
|
||||
--modal-contrast: var(--wrn-color-secondary-contrast);
|
||||
}
|
||||
|
||||
/*
|
||||
* Fallbacks below (the second var() argument): the theme token generator
|
||||
* (packages/styles/src/theme.ts) only emits a real -contrast token for
|
||||
* primary and secondary. info, success, and danger have no contrast
|
||||
* token defined at all, so var(--wire-color-info-contrast) with no
|
||||
* token defined at all, so var(--wrn-color-info-contrast) with no
|
||||
* fallback resolves to nothing, and --modal-contrast becomes invalid --
|
||||
* which made confirm-button and solid-panel text unreadable. White is a
|
||||
* safe default against these saturated colors until the theme package
|
||||
* defines real tokens for them.
|
||||
*/
|
||||
.wire-modal[data-color="info"] {
|
||||
--modal-accent: var(--wire-color-info);
|
||||
--modal-soft: var(--wire-color-info-soft);
|
||||
--modal-contrast: var(--wire-color-info-contrast, white);
|
||||
.wrn-modal[data-color="info"] {
|
||||
--modal-accent: var(--wrn-color-info);
|
||||
--modal-soft: var(--wrn-color-info-soft);
|
||||
--modal-contrast: var(--wrn-color-info-contrast, white);
|
||||
}
|
||||
|
||||
.wire-modal[data-color="success"] {
|
||||
--modal-accent: var(--wire-color-success);
|
||||
--modal-soft: var(--wire-color-success-soft);
|
||||
--modal-contrast: var(--wire-color-success-contrast, white);
|
||||
.wrn-modal[data-color="success"] {
|
||||
--modal-accent: var(--wrn-color-success);
|
||||
--modal-soft: var(--wrn-color-success-soft);
|
||||
--modal-contrast: var(--wrn-color-success-contrast, white);
|
||||
}
|
||||
|
||||
.wire-modal[data-color="warning"] {
|
||||
--modal-accent: var(--wire-color-warning);
|
||||
--modal-soft: var(--wire-color-warning-soft);
|
||||
--modal-contrast: var(--wire-color-warning-text);
|
||||
.wrn-modal[data-color="warning"] {
|
||||
--modal-accent: var(--wrn-color-warning);
|
||||
--modal-soft: var(--wrn-color-warning-soft);
|
||||
--modal-contrast: var(--wrn-color-warning-text);
|
||||
}
|
||||
|
||||
.wire-modal[data-color="danger"],
|
||||
.wire-modal[data-destructive="true"] {
|
||||
--modal-accent: var(--wire-color-danger);
|
||||
--modal-soft: var(--wire-color-danger-soft);
|
||||
--modal-contrast: var(--wire-color-on-danger, white);
|
||||
.wrn-modal[data-color="danger"],
|
||||
.wrn-modal[data-destructive="true"] {
|
||||
--modal-accent: var(--wrn-color-danger);
|
||||
--modal-soft: var(--wrn-color-danger-soft);
|
||||
--modal-contrast: var(--wrn-color-on-danger, white);
|
||||
}
|
||||
|
||||
.wire-modal__trigger,
|
||||
.wire-modal__trigger-slot {
|
||||
.wrn-modal__trigger,
|
||||
.wrn-modal__trigger-slot {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.55rem;
|
||||
}
|
||||
|
||||
.wire-modal__trigger {
|
||||
.wrn-modal__trigger {
|
||||
appearance: none;
|
||||
min-height: 2.55rem;
|
||||
padding: 0.65rem 1rem;
|
||||
@@ -356,22 +356,22 @@ component Modal {
|
||||
transition: opacity 150ms ease, transform 150ms ease, box-shadow 150ms ease;
|
||||
}
|
||||
|
||||
.wire-modal__trigger:hover {
|
||||
.wrn-modal__trigger:hover {
|
||||
opacity: 0.92;
|
||||
}
|
||||
|
||||
.wire-modal__trigger:active {
|
||||
.wrn-modal__trigger:active {
|
||||
transform: scale(0.97);
|
||||
}
|
||||
|
||||
.wire-modal__trigger:focus-visible {
|
||||
.wrn-modal__trigger:focus-visible {
|
||||
outline: none;
|
||||
box-shadow: 0 0 0 3px color-mix(in srgb, var(--modal-accent) 40%, transparent);
|
||||
}
|
||||
|
||||
/*
|
||||
* Hidden by default so the SSR-rendered HTML never paints the layer before
|
||||
* hydration runs. data-open on the wire-modal root is evaluated and
|
||||
* hydration runs. data-open on the wrn-modal root is evaluated and
|
||||
* serialized to a real true or false string at render time -- a plain
|
||||
* bind, not the raw-expression data-show directive -- so this selector
|
||||
* is correct on first paint with zero flash, with no dependency on
|
||||
@@ -382,7 +382,7 @@ component Modal {
|
||||
* animate -- a box that starts at display: none has no prior frame to
|
||||
* transition from.
|
||||
*/
|
||||
.wire-modal__layer {
|
||||
.wrn-modal__layer {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
z-index: 1250;
|
||||
@@ -395,24 +395,24 @@ component Modal {
|
||||
transition: opacity 180ms ease, visibility 0s linear 180ms;
|
||||
}
|
||||
|
||||
.wire-modal[data-open="true"] .wire-modal__layer {
|
||||
.wrn-modal[data-open="true"] .wrn-modal__layer {
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
transition: opacity 180ms ease, visibility 0s linear 0s;
|
||||
}
|
||||
|
||||
.wire-modal[data-placement="top"] .wire-modal__layer {
|
||||
.wrn-modal[data-placement="top"] .wrn-modal__layer {
|
||||
align-items: flex-start;
|
||||
padding-top: clamp(1rem, 8vh, 5rem);
|
||||
}
|
||||
|
||||
.wire-modal[data-scroll="page"] .wire-modal__layer {
|
||||
.wrn-modal[data-scroll="page"] .wrn-modal__layer {
|
||||
align-items: flex-start;
|
||||
overflow-y: auto;
|
||||
padding: 2.5rem 1rem;
|
||||
}
|
||||
|
||||
.wire-modal__backdrop {
|
||||
.wrn-modal__backdrop {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
z-index: 0;
|
||||
@@ -423,22 +423,22 @@ component Modal {
|
||||
backdrop-filter: blur(9px);
|
||||
}
|
||||
|
||||
.wire-modal__panel {
|
||||
.wrn-modal__panel {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: min(32rem, calc(100vw - 2rem));
|
||||
max-height: min(88vh, 52rem);
|
||||
color: var(--wire-color-text);
|
||||
color: var(--wrn-color-text);
|
||||
background:
|
||||
radial-gradient(
|
||||
circle at 100% 0%,
|
||||
color-mix(in srgb, var(--modal-accent) 9%, transparent),
|
||||
transparent 34%
|
||||
),
|
||||
var(--wire-color-surface-raised);
|
||||
border: 1px solid color-mix(in srgb, var(--modal-accent) 18%, var(--wire-color-border));
|
||||
var(--wrn-color-surface-raised);
|
||||
border: 1px solid color-mix(in srgb, var(--modal-accent) 18%, var(--wrn-color-border));
|
||||
border-radius: 1.35rem;
|
||||
box-shadow:
|
||||
0 1px 0 color-mix(in srgb, white 5%, transparent) inset,
|
||||
@@ -449,71 +449,71 @@ component Modal {
|
||||
transition: opacity 180ms ease, transform 220ms cubic-bezier(0.16, 1, 0.3, 1);
|
||||
}
|
||||
|
||||
.wire-modal[data-open="true"] .wire-modal__panel {
|
||||
.wrn-modal[data-open="true"] .wrn-modal__panel {
|
||||
opacity: 1;
|
||||
transform: none;
|
||||
}
|
||||
|
||||
.wire-modal[data-size="xs"] .wire-modal__panel {
|
||||
.wrn-modal[data-size="xs"] .wrn-modal__panel {
|
||||
width: min(19rem, calc(100vw - 2rem));
|
||||
}
|
||||
|
||||
.wire-modal[data-size="sm"] .wire-modal__panel {
|
||||
.wrn-modal[data-size="sm"] .wrn-modal__panel {
|
||||
width: min(25rem, calc(100vw - 2rem));
|
||||
}
|
||||
|
||||
.wire-modal[data-size="lg"] .wire-modal__panel {
|
||||
.wrn-modal[data-size="lg"] .wrn-modal__panel {
|
||||
width: min(44rem, calc(100vw - 2rem));
|
||||
}
|
||||
|
||||
.wire-modal[data-size="xl"] .wire-modal__panel {
|
||||
.wrn-modal[data-size="xl"] .wrn-modal__panel {
|
||||
width: min(64rem, calc(100vw - 2rem));
|
||||
}
|
||||
|
||||
.wire-modal[data-size="full"] .wire-modal__panel {
|
||||
.wrn-modal[data-size="full"] .wrn-modal__panel {
|
||||
width: calc(100vw - 2rem);
|
||||
height: calc(100vh - 2rem);
|
||||
max-height: none;
|
||||
}
|
||||
|
||||
.wire-modal[data-scroll="page"] .wire-modal__panel {
|
||||
.wrn-modal[data-scroll="page"] .wrn-modal__panel {
|
||||
max-height: none;
|
||||
}
|
||||
|
||||
.wire-modal[data-variant="soft"] .wire-modal__panel {
|
||||
.wrn-modal[data-variant="soft"] .wrn-modal__panel {
|
||||
background:
|
||||
linear-gradient(145deg, var(--modal-soft), transparent 68%),
|
||||
var(--wire-color-surface-raised);
|
||||
var(--wrn-color-surface-raised);
|
||||
}
|
||||
|
||||
.wire-modal[data-variant="outline"] .wire-modal__panel {
|
||||
background: var(--wire-color-surface-raised);
|
||||
.wrn-modal[data-variant="outline"] .wrn-modal__panel {
|
||||
background: var(--wrn-color-surface-raised);
|
||||
box-shadow: 0 24px 72px color-mix(in srgb, black 24%, transparent);
|
||||
}
|
||||
|
||||
.wire-modal[data-variant="solid"] .wire-modal__panel {
|
||||
.wrn-modal[data-variant="solid"] .wrn-modal__panel {
|
||||
color: var(--modal-contrast);
|
||||
background: var(--modal-accent);
|
||||
border-color: color-mix(in srgb, white 20%, transparent);
|
||||
}
|
||||
|
||||
.wire-modal__header {
|
||||
.wrn-modal__header {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
gap: 1rem;
|
||||
padding: 1.4rem 1.4rem 1.15rem;
|
||||
border-bottom: 1px solid var(--wire-color-border);
|
||||
border-bottom: 1px solid var(--wrn-color-border);
|
||||
}
|
||||
|
||||
.wire-modal__heading {
|
||||
.wrn-modal__heading {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 0.9rem;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.wire-modal__icon {
|
||||
.wrn-modal__icon {
|
||||
flex: 0 0 auto;
|
||||
width: 1.3rem;
|
||||
height: 1.3rem;
|
||||
@@ -521,35 +521,35 @@ component Modal {
|
||||
color: var(--modal-accent);
|
||||
}
|
||||
|
||||
.wire-modal[data-variant="solid"] .wire-modal__icon {
|
||||
.wrn-modal[data-variant="solid"] .wrn-modal__icon {
|
||||
color: currentColor;
|
||||
}
|
||||
|
||||
.wire-modal__heading-copy {
|
||||
.wrn-modal__heading-copy {
|
||||
display: grid;
|
||||
gap: 0.3rem;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.wire-modal__heading-copy h2,
|
||||
.wire-modal__heading-copy p {
|
||||
.wrn-modal__heading-copy h2,
|
||||
.wrn-modal__heading-copy p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.wire-modal__heading-copy h2 {
|
||||
.wrn-modal__heading-copy h2 {
|
||||
color: inherit;
|
||||
font-size: 1.08rem;
|
||||
font-weight: 650;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.wire-modal__heading-copy p {
|
||||
color: var(--wire-color-text-muted);
|
||||
.wrn-modal__heading-copy p {
|
||||
color: var(--wrn-color-text-muted);
|
||||
font-size: 0.8rem;
|
||||
line-height: 1.55;
|
||||
}
|
||||
|
||||
.wire-modal[data-variant="solid"] .wire-modal__heading-copy p {
|
||||
.wrn-modal[data-variant="solid"] .wrn-modal__heading-copy p {
|
||||
color: color-mix(in srgb, currentColor 76%, transparent);
|
||||
}
|
||||
|
||||
@@ -559,7 +559,7 @@ component Modal {
|
||||
* 2.15rem button with a ~2px content box -- which squeezed the icon to
|
||||
* 0.4px wide and read as "the close button has no icon".
|
||||
*/
|
||||
.wire-modal__close {
|
||||
.wrn-modal__close {
|
||||
appearance: none;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
@@ -568,7 +568,7 @@ component Modal {
|
||||
padding: 0;
|
||||
width: 2.15rem;
|
||||
height: 2.15rem;
|
||||
color: var(--wire-color-text-muted);
|
||||
color: var(--wrn-color-text-muted);
|
||||
background: transparent;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 9999px;
|
||||
@@ -582,34 +582,34 @@ component Modal {
|
||||
* missing rather than subtle. Derive it from the panel contrast color
|
||||
* instead, and give it a faint ring so it is unmistakably a control.
|
||||
*/
|
||||
.wire-modal[data-variant="solid"] .wire-modal__close {
|
||||
.wrn-modal[data-variant="solid"] .wrn-modal__close {
|
||||
color: color-mix(in srgb, currentColor 82%, transparent);
|
||||
border-color: color-mix(in srgb, currentColor 35%, transparent);
|
||||
}
|
||||
|
||||
.wire-modal[data-variant="solid"] .wire-modal__close:hover {
|
||||
.wrn-modal[data-variant="solid"] .wrn-modal__close:hover {
|
||||
color: currentColor;
|
||||
background: color-mix(in srgb, black 18%, transparent);
|
||||
border-color: color-mix(in srgb, currentColor 55%, transparent);
|
||||
}
|
||||
|
||||
.wire-modal__close:hover {
|
||||
color: var(--wire-color-text);
|
||||
background: var(--wire-color-surface-soft);
|
||||
.wrn-modal__close:hover {
|
||||
color: var(--wrn-color-text);
|
||||
background: var(--wrn-color-surface-soft);
|
||||
}
|
||||
|
||||
.wire-modal__close:focus-visible {
|
||||
.wrn-modal__close:focus-visible {
|
||||
color: var(--modal-accent);
|
||||
border-color: color-mix(in srgb, var(--modal-accent) 45%, transparent);
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.wire-modal__close:active {
|
||||
.wrn-modal__close:active {
|
||||
transform: scale(0.92);
|
||||
}
|
||||
|
||||
/* Never let the glyph be shrunk by the flex container. */
|
||||
.wire-modal__close svg {
|
||||
.wrn-modal__close svg {
|
||||
flex: 0 0 auto;
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
@@ -628,46 +628,46 @@ component Modal {
|
||||
* block scanner treats a quote as a string delimiter while it counts
|
||||
* braces, so a stray one breaks parsing of the whole component.
|
||||
*/
|
||||
.wire-modal__body {
|
||||
.wrn-modal__body {
|
||||
flex: 1 1 auto;
|
||||
min-height: 0;
|
||||
padding: 1.4rem;
|
||||
color: var(--wire-color-text);
|
||||
color: var(--wrn-color-text);
|
||||
}
|
||||
|
||||
/*
|
||||
* :where() keeps this at the specificity of .wire-modal__body alone, so it
|
||||
* :where() keeps this at the specificity of .wrn-modal__body alone, so it
|
||||
* outranks a global element selector but still yields to any class the app
|
||||
* puts on its own slot content (an error message, a muted caption). A
|
||||
* plain .wire-modal__body p list would have quietly overridden those.
|
||||
* plain .wrn-modal__body p list would have quietly overridden those.
|
||||
*/
|
||||
.wire-modal__body :where(p, li, dd, dt, h1, h2, h3, h4, h5, h6, span, label, code) {
|
||||
.wrn-modal__body :where(p, li, dd, dt, h1, h2, h3, h4, h5, h6, span, label, code) {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.wire-modal[data-variant="solid"] .wire-modal__body {
|
||||
.wrn-modal[data-variant="solid"] .wrn-modal__body {
|
||||
color: var(--modal-contrast);
|
||||
}
|
||||
|
||||
.wire-modal[data-scrollable="true"] .wire-modal__body {
|
||||
.wrn-modal[data-scrollable="true"] .wrn-modal__body {
|
||||
overflow: auto;
|
||||
overscroll-behavior: contain;
|
||||
}
|
||||
|
||||
.wire-modal__footer {
|
||||
.wrn-modal__footer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 1rem;
|
||||
padding: 1rem 1.4rem 1.4rem;
|
||||
border-top: 1px solid var(--wire-color-border);
|
||||
border-top: 1px solid var(--wrn-color-border);
|
||||
}
|
||||
|
||||
.wire-modal__custom-footer:empty {
|
||||
.wrn-modal__custom-footer:empty {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.wire-modal__actions {
|
||||
.wrn-modal__actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
@@ -675,7 +675,7 @@ component Modal {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.wire-modal__button {
|
||||
.wrn-modal__button {
|
||||
appearance: none;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
@@ -691,17 +691,17 @@ component Modal {
|
||||
transition: transform 150ms ease, opacity 150ms ease, border-color 150ms ease;
|
||||
}
|
||||
|
||||
.wire-modal__button:active {
|
||||
.wrn-modal__button:active {
|
||||
transform: scale(0.985);
|
||||
}
|
||||
|
||||
.wire-modal__button--secondary {
|
||||
color: var(--wire-color-text);
|
||||
.wrn-modal__button--secondary {
|
||||
color: var(--wrn-color-text);
|
||||
background: transparent;
|
||||
border: 1px solid var(--wire-color-border);
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
}
|
||||
|
||||
.wire-modal__button--primary {
|
||||
.wrn-modal__button--primary {
|
||||
color: var(--modal-contrast);
|
||||
background: var(--modal-accent);
|
||||
border: 1px solid transparent;
|
||||
@@ -713,73 +713,73 @@ component Modal {
|
||||
* Darken the fill slightly and add a light border so the button still
|
||||
* reads as a distinct, clickable pill instead of blending into the panel.
|
||||
*/
|
||||
.wire-modal[data-variant="solid"] .wire-modal__button--primary {
|
||||
.wrn-modal[data-variant="solid"] .wrn-modal__button--primary {
|
||||
background: color-mix(in srgb, black 18%, var(--modal-accent));
|
||||
border-color: color-mix(in srgb, white 32%, transparent);
|
||||
box-shadow: 0 1px 0 color-mix(in srgb, white 12%, transparent) inset;
|
||||
}
|
||||
|
||||
.wire-modal__button:disabled {
|
||||
.wrn-modal__button:disabled {
|
||||
opacity: 0.55;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.wire-modal__spinner {
|
||||
.wrn-modal__spinner {
|
||||
width: 0.95rem;
|
||||
height: 0.95rem;
|
||||
border: 2px solid color-mix(in srgb, currentColor 35%, transparent);
|
||||
border-top-color: currentColor;
|
||||
border-radius: 50%;
|
||||
animation: wire-modal-spin 750ms linear infinite;
|
||||
animation: wrn-modal-spin 750ms linear infinite;
|
||||
}
|
||||
|
||||
@keyframes wire-modal-spin {
|
||||
@keyframes wrn-modal-spin {
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 639px) {
|
||||
.wire-modal__layer {
|
||||
.wrn-modal__layer {
|
||||
align-items: flex-end;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.wire-modal__panel,
|
||||
.wire-modal[data-size="xs"] .wire-modal__panel,
|
||||
.wire-modal[data-size="sm"] .wire-modal__panel,
|
||||
.wire-modal[data-size="lg"] .wire-modal__panel,
|
||||
.wire-modal[data-size="xl"] .wire-modal__panel {
|
||||
.wrn-modal__panel,
|
||||
.wrn-modal[data-size="xs"] .wrn-modal__panel,
|
||||
.wrn-modal[data-size="sm"] .wrn-modal__panel,
|
||||
.wrn-modal[data-size="lg"] .wrn-modal__panel,
|
||||
.wrn-modal[data-size="xl"] .wrn-modal__panel {
|
||||
width: 100%;
|
||||
max-height: 92vh;
|
||||
border-radius: 1.25rem 1.25rem 0 0;
|
||||
}
|
||||
|
||||
.wire-modal__footer {
|
||||
.wrn-modal__footer {
|
||||
align-items: stretch;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.wire-modal__actions {
|
||||
.wrn-modal__actions {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.wire-modal__button {
|
||||
.wrn-modal__button {
|
||||
flex: 1 1 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.wire-modal__button,
|
||||
.wire-modal__spinner,
|
||||
.wire-modal__layer,
|
||||
.wire-modal__panel,
|
||||
.wire-modal__close {
|
||||
.wrn-modal__button,
|
||||
.wrn-modal__spinner,
|
||||
.wrn-modal__layer,
|
||||
.wrn-modal__panel,
|
||||
.wrn-modal__close {
|
||||
animation: none;
|
||||
transition: none;
|
||||
}
|
||||
|
||||
.wire-modal__panel {
|
||||
.wrn-modal__panel {
|
||||
transform: none;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ component Nav {
|
||||
<nav
|
||||
{...attrs}
|
||||
data-ui-component="Nav"
|
||||
class='wire-nav {class}'
|
||||
class='wrn-nav {class}'
|
||||
data-orientation='{orientation}'
|
||||
data-color='{color}'
|
||||
data-size='{size}'
|
||||
@@ -70,21 +70,21 @@ 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" data-wrn-roving='{rovingAxis()}'>
|
||||
<ul class="wrn-nav__list" data-wrn-roving='{rovingAxis()}'>
|
||||
{#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)}'
|
||||
@@ -93,28 +93,28 @@ component Nav {
|
||||
@click='choose(item)'
|
||||
>
|
||||
<span
|
||||
class='wire-nav__icon {item.icon}'
|
||||
class='wrn-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__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"
|
||||
class="wrn-nav__submenu"
|
||||
data-wrn-anchored="true"
|
||||
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"}'
|
||||
@@ -122,28 +122,28 @@ component Nav {
|
||||
@click='choose(child)'
|
||||
>
|
||||
<span
|
||||
class='wire-nav__icon {child.icon}'
|
||||
class='wrn-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__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-wrn-anchored="true"
|
||||
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"}'
|
||||
@@ -151,11 +151,11 @@ component Nav {
|
||||
@click='choose(leaf)'
|
||||
>
|
||||
<span
|
||||
class='wire-nav__icon {leaf.icon}'
|
||||
class='wrn-nav__icon {leaf.icon}'
|
||||
data-show="leaf.icon"
|
||||
aria-hidden="true"
|
||||
></span>
|
||||
<span class="wire-nav__label">{leaf.label}</span>
|
||||
<span class="wrn-nav__label">{leaf.label}</span>
|
||||
</a>
|
||||
</li>
|
||||
{/each}
|
||||
@@ -172,36 +172,36 @@ component Nav {
|
||||
}
|
||||
|
||||
style {
|
||||
.wire-nav {
|
||||
--nav-accent: var(--wire-color-primary);
|
||||
.wrn-nav {
|
||||
--nav-accent: var(--wrn-color-primary);
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.wire-nav[data-color="secondary"] {
|
||||
--nav-accent: var(--wire-color-secondary);
|
||||
.wrn-nav[data-color="secondary"] {
|
||||
--nav-accent: var(--wrn-color-secondary);
|
||||
}
|
||||
|
||||
.wire-nav[data-color="success"] {
|
||||
--nav-accent: var(--wire-color-success);
|
||||
.wrn-nav[data-color="success"] {
|
||||
--nav-accent: var(--wrn-color-success);
|
||||
}
|
||||
|
||||
.wire-nav[data-color="danger"] {
|
||||
--nav-accent: var(--wire-color-danger);
|
||||
.wrn-nav[data-color="danger"] {
|
||||
--nav-accent: var(--wrn-color-danger);
|
||||
}
|
||||
|
||||
.wire-nav[data-color="info"] {
|
||||
--nav-accent: var(--wire-color-info);
|
||||
.wrn-nav[data-color="info"] {
|
||||
--nav-accent: var(--wrn-color-info);
|
||||
}
|
||||
|
||||
.wire-nav[data-size="sm"] {
|
||||
.wrn-nav[data-size="sm"] {
|
||||
font-size: 0.82rem;
|
||||
}
|
||||
|
||||
.wire-nav[data-size="lg"] {
|
||||
.wrn-nav[data-size="lg"] {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.wire-nav__list {
|
||||
.wrn-nav__list {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.25rem;
|
||||
@@ -210,48 +210,48 @@ 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:focus-visible {
|
||||
.wrn-nav__link:focus-visible {
|
||||
outline: 2px solid var(--nav-accent);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
.wire-nav__link[data-active="true"] {
|
||||
.wrn-nav__link[data-active="true"] {
|
||||
background: color-mix(in srgb, var(--nav-accent) 16%, transparent);
|
||||
color: var(--nav-accent);
|
||||
}
|
||||
|
||||
.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: color-mix(in srgb, var(--nav-accent) 16%, transparent);
|
||||
@@ -259,17 +259,17 @@ component Nav {
|
||||
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%;
|
||||
@@ -277,42 +277,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;
|
||||
@@ -327,21 +327,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;
|
||||
|
||||
+198
-132
@@ -1,5 +1,3 @@
|
||||
import ComponentBaseStyles from "../styles/ComponentBaseStyles.wrn"
|
||||
|
||||
component Navbar {
|
||||
outputs {
|
||||
toggle(payload: { open: boolean })
|
||||
@@ -62,47 +60,47 @@ size: string = "default"
|
||||
}
|
||||
|
||||
view {
|
||||
<header class="wire-navbar wire-navbar--width-{maxWidth} wire-component--color-{color} wire-component--size-{size} {sticky ? 'wire-navbar--sticky' : ''} {class}" data-wrn-navbar data-open-on-hover="{openOnHover}">
|
||||
<div class="wire-navbar__topbar" aria-label="{topbarLabel}">
|
||||
<header class="wrn-navbar wrn-navbar--width-{maxWidth} wrn-component--color-{color} wrn-component--size-{size} {sticky ? 'wrn-navbar--sticky' : ''} {class}" data-wrn-navbar data-open-on-hover="{openOnHover}">
|
||||
<div class="wrn-navbar__topbar" aria-label="{topbarLabel}">
|
||||
<slot name="topbar" />
|
||||
</div>
|
||||
|
||||
<div class="wire-navbar__main">
|
||||
<a class="wire-navbar__brand" href="{brand.href || '/'}" aria-label="{brand.ariaLabel || brand.label || label}">
|
||||
<div class="wrn-navbar__main">
|
||||
<a class="wrn-navbar__brand" href="{brand.href || '/'}" aria-label="{brand.ariaLabel || brand.label || label}">
|
||||
{#if brand.logo}
|
||||
<img class="wire-navbar__brand-logo" src="{brand.logo}" alt="{brand.logoAlt || brand.label || ''}" width="{brand.logoWidth || ''}" height="{brand.logoHeight || ''}" />
|
||||
<img class="wrn-navbar__brand-logo" src="{brand.logo}" alt="{brand.logoAlt || brand.label || ''}" width="{brand.logoWidth || ''}" height="{brand.logoHeight || ''}" />
|
||||
{/if}
|
||||
{#if brand.icon}
|
||||
<span class="wire-navbar__brand-icon {brand.icon}" aria-hidden="true"></span>
|
||||
<span class="wrn-navbar__brand-icon {brand.icon}" aria-hidden="true"></span>
|
||||
{/if}
|
||||
{#if brand.label || brand.description}
|
||||
<span class="wire-navbar__brand-copy">
|
||||
<span class="wrn-navbar__brand-copy">
|
||||
{#if brand.label}<strong>{brand.label}</strong>{/if}
|
||||
{#if brand.description}<small>{brand.description}</small>{/if}
|
||||
</span>
|
||||
{/if}
|
||||
</a>
|
||||
|
||||
<button type="button" class="wire-navbar__toggle" aria-label="{mobileLabel}" aria-expanded="{mobileOpen}" @click="toggleNavigation()">
|
||||
<button type="button" class="wrn-navbar__toggle" aria-label="{mobileLabel}" aria-expanded="{mobileOpen}" @click="toggleNavigation()">
|
||||
<span aria-hidden="true"></span><span aria-hidden="true"></span><span aria-hidden="true"></span>
|
||||
</button>
|
||||
|
||||
<div class="wire-navbar__collapse {mobileOpen ? 'is-open' : ''}">
|
||||
<nav class="wire-navbar__menus" aria-label="{label}" data-wrn-roving="horizontal">
|
||||
<div class="wrn-navbar__collapse {mobileOpen ? 'is-open' : ''}">
|
||||
<nav class="wrn-navbar__menus" aria-label="{label}" data-wrn-roving="horizontal">
|
||||
{#each items as item}
|
||||
{#if item.children && item.children.length}
|
||||
<details class="wire-navbar__dropdown wire-navbar__dropdown--{item.type || 'dropdown'}" name="wire-navbar-menu" @toggle="toggleDropdown(event, item)">
|
||||
<details class="wrn-navbar__dropdown wrn-navbar__dropdown--{item.type || 'dropdown'}" name="wrn-navbar-menu" @toggle="toggleDropdown(event, item)">
|
||||
<summary data-wrn-roving-item="true" aria-current="{isItemActive(item) ? 'page' : 'false'}">
|
||||
{#if item.icon}<span class="{item.icon}" aria-hidden="true"></span>{/if}
|
||||
<span>{item.label}</span>
|
||||
<span class="wire-navbar__chevron" aria-hidden="true"></span>
|
||||
<span class="wrn-navbar__chevron" aria-hidden="true"></span>
|
||||
</summary>
|
||||
<div class="wire-navbar__panel wire-navbar__panel--columns-{item.columns || 1}">
|
||||
{#if item.description}<p class="wire-navbar__panel-intro">{item.description}</p>{/if}
|
||||
<div class="wrn-navbar__panel wrn-navbar__panel--columns-{item.columns || 1}">
|
||||
{#if item.description}<p class="wrn-navbar__panel-intro">{item.description}</p>{/if}
|
||||
{#each item.children as child}
|
||||
<div class="wire-navbar__group">
|
||||
<div class="wrn-navbar__group">
|
||||
{#if child.children && child.children.length}
|
||||
{#if child.label}<strong class="wire-navbar__group-title">{child.label}</strong>{/if}
|
||||
{#if child.label}<strong class="wrn-navbar__group-title">{child.label}</strong>{/if}
|
||||
{#if child.description}<small>{child.description}</small>{/if}
|
||||
{#each child.children as nested}
|
||||
<a href="{nested.href || '#'}" target="{nested.target || ''}" rel="{nested.rel || ''}" aria-current="{nested.value === active ? 'page' : 'false'}" @click="selectItem(nested, 3)">
|
||||
@@ -121,7 +119,7 @@ size: string = "default"
|
||||
</div>
|
||||
</details>
|
||||
{:else}
|
||||
<a class="wire-navbar__menu-link" data-wrn-roving-item="true" href="{item.href || '#'}" target="{item.target || ''}" rel="{item.rel || ''}" aria-current="{item.value === active ? 'page' : 'false'}" @click="selectItem(item, 1)">
|
||||
<a class="wrn-navbar__menu-link" data-wrn-roving-item="true" href="{item.href || '#'}" target="{item.target || ''}" rel="{item.rel || ''}" aria-current="{item.value === active ? 'page' : 'false'}" @click="selectItem(item, 1)">
|
||||
{#if item.icon}<span class="{item.icon}" aria-hidden="true"></span>{/if}
|
||||
<span>{item.label}</span>
|
||||
</a>
|
||||
@@ -129,9 +127,9 @@ size: string = "default"
|
||||
{/each}
|
||||
</nav>
|
||||
|
||||
<div class="wire-navbar__actions">
|
||||
<div class="wrn-navbar__actions">
|
||||
{#each actions as item}
|
||||
<a class="wire-navbar__action wire-navbar__action--{item.variant || 'link'}" href="{item.href || '#'}" target="{item.target || ''}" rel="{item.rel || ''}" @click="selectAction(item)">
|
||||
<a class="wrn-navbar__action wrn-navbar__action--{item.variant || 'link'}" href="{item.href || '#'}" target="{item.target || ''}" rel="{item.rel || ''}" @click="selectAction(item)">
|
||||
{#if item.icon}<span class="{item.icon}" aria-hidden="true"></span>{/if}
|
||||
<span>{item.label}</span>
|
||||
</a>
|
||||
@@ -141,46 +139,45 @@ size: string = "default"
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<ComponentBaseStyles hidden />
|
||||
}
|
||||
|
||||
style {
|
||||
/* Full application navigation */
|
||||
.wire-navbar {
|
||||
.wrn-navbar {
|
||||
position: relative;
|
||||
z-index: 40;
|
||||
width: 100%;
|
||||
color: var(--wire-color-text);
|
||||
background: color-mix(in srgb, var(--wire-color-surface) 96%, transparent);
|
||||
border-bottom: 1px solid var(--wire-color-border);
|
||||
color: var(--wrn-color-text);
|
||||
background: color-mix(in srgb, var(--wrn-color-surface) 96%, transparent);
|
||||
border-bottom: 1px solid var(--wrn-color-border);
|
||||
}
|
||||
|
||||
.wire-navbar--sticky {
|
||||
.wrn-navbar--sticky {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
backdrop-filter: blur(16px);
|
||||
}
|
||||
|
||||
.wire-navbar__topbar:empty,
|
||||
.wire-navbar__topbar:not(:has(*)) {
|
||||
.wrn-navbar__topbar:empty,
|
||||
.wrn-navbar__topbar:not(:has(*)) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.wire-navbar__topbar:not(:empty) {
|
||||
.wrn-navbar__topbar:not(:empty) {
|
||||
display: flex;
|
||||
min-height: 2.25rem;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 1rem;
|
||||
padding: 0.35rem clamp(1rem, 4vw, 3rem);
|
||||
color: var(--wire-color-muted);
|
||||
background: var(--wire-color-surface-2);
|
||||
border-bottom: 1px solid var(--wire-color-border);
|
||||
color: var(--wrn-color-muted);
|
||||
background: var(--wrn-color-surface-2);
|
||||
border-bottom: 1px solid var(--wrn-color-border);
|
||||
font-size: 0.75rem;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.wire-navbar__main {
|
||||
.wrn-navbar__main {
|
||||
display: flex;
|
||||
min-height: 4.25rem;
|
||||
width: min(100%, 90rem);
|
||||
@@ -190,25 +187,25 @@ size: string = "default"
|
||||
gap: 1.5rem;
|
||||
}
|
||||
|
||||
.wire-navbar--width-full .wire-navbar__main {
|
||||
.wrn-navbar--width-full .wrn-navbar__main {
|
||||
width: 100%;
|
||||
max-width: none;
|
||||
}
|
||||
|
||||
.wire-navbar--width-compact .wire-navbar__main {
|
||||
.wrn-navbar--width-compact .wrn-navbar__main {
|
||||
width: min(86%, 80rem);
|
||||
}
|
||||
|
||||
.wire-navbar__brand,
|
||||
.wire-navbar__menu-link,
|
||||
.wire-navbar__dropdown summary,
|
||||
.wire-navbar__action,
|
||||
.wire-navbar__panel a {
|
||||
.wrn-navbar__brand,
|
||||
.wrn-navbar__menu-link,
|
||||
.wrn-navbar__dropdown summary,
|
||||
.wrn-navbar__action,
|
||||
.wrn-navbar__panel a {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.wire-navbar__brand {
|
||||
.wrn-navbar__brand {
|
||||
display: inline-flex;
|
||||
min-width: 0;
|
||||
align-items: center;
|
||||
@@ -216,7 +213,7 @@ size: string = "default"
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.wire-navbar__brand-logo {
|
||||
.wrn-navbar__brand-logo {
|
||||
display: block;
|
||||
width: auto;
|
||||
max-width: 11rem;
|
||||
@@ -224,57 +221,57 @@ size: string = "default"
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.wire-navbar__brand-icon {
|
||||
.wrn-navbar__brand-icon {
|
||||
width: 2.5rem;
|
||||
height: 2.5rem;
|
||||
color: var(--wire-component-color, var(--wire-color-primary));
|
||||
color: var(--wrn-component-color, var(--wrn-color-primary));
|
||||
}
|
||||
|
||||
.wire-navbar__brand-copy {
|
||||
.wrn-navbar__brand-copy {
|
||||
display: grid;
|
||||
min-width: 0;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.wire-navbar__brand-copy strong {
|
||||
.wrn-navbar__brand-copy strong {
|
||||
font-size: 0.9rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.wire-navbar__brand-copy small {
|
||||
.wrn-navbar__brand-copy small {
|
||||
margin-top: 0.2rem;
|
||||
color: var(--wire-color-muted);
|
||||
color: var(--wrn-color-muted);
|
||||
font-size: 0.6875rem;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.wire-navbar__collapse,
|
||||
.wire-navbar__menus,
|
||||
.wire-navbar__actions {
|
||||
.wrn-navbar__collapse,
|
||||
.wrn-navbar__menus,
|
||||
.wrn-navbar__actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.wire-navbar__collapse {
|
||||
.wrn-navbar__collapse {
|
||||
min-width: 0;
|
||||
flex: 1;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.wire-navbar__menus {
|
||||
.wrn-navbar__menus {
|
||||
justify-content: center;
|
||||
flex: 1;
|
||||
gap: 0.25rem;
|
||||
}
|
||||
|
||||
.wire-navbar__actions {
|
||||
.wrn-navbar__actions {
|
||||
justify-content: flex-end;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.wire-navbar__menu-link,
|
||||
.wire-navbar__dropdown > summary,
|
||||
.wire-navbar__action {
|
||||
.wrn-navbar__menu-link,
|
||||
.wrn-navbar__dropdown > summary,
|
||||
.wrn-navbar__action {
|
||||
display: inline-flex;
|
||||
min-height: 2.75rem;
|
||||
padding: 0.65rem 0.8rem;
|
||||
@@ -287,60 +284,60 @@ size: string = "default"
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.wire-navbar__menu-link:hover,
|
||||
.wire-navbar__dropdown > summary:hover {
|
||||
color: var(--wire-color-text);
|
||||
background: var(--wire-color-surface-2);
|
||||
.wrn-navbar__menu-link:hover,
|
||||
.wrn-navbar__dropdown > summary:hover {
|
||||
color: var(--wrn-color-text);
|
||||
background: var(--wrn-color-surface-2);
|
||||
}
|
||||
|
||||
.wire-navbar__menu-link[aria-current="page"],
|
||||
.wire-navbar__dropdown > summary[aria-current="page"] {
|
||||
color: var(--wire-component-color, var(--wire-color-primary));
|
||||
.wrn-navbar__menu-link[aria-current="page"],
|
||||
.wrn-navbar__dropdown > summary[aria-current="page"] {
|
||||
color: var(--wrn-component-color, var(--wrn-color-primary));
|
||||
font-weight: 600;
|
||||
background: color-mix(
|
||||
in srgb,
|
||||
var(--wire-component-color, var(--wire-color-primary)) 12%,
|
||||
var(--wrn-component-color, var(--wrn-color-primary)) 12%,
|
||||
transparent
|
||||
);
|
||||
box-shadow: inset 0 -2px 0 var(--wire-component-color, var(--wire-color-primary));
|
||||
box-shadow: inset 0 -2px 0 var(--wrn-component-color, var(--wrn-color-primary));
|
||||
}
|
||||
|
||||
.wire-navbar__menu-link[aria-current="page"]:hover,
|
||||
.wire-navbar__dropdown > summary[aria-current="page"]:hover {
|
||||
color: var(--wire-component-color, var(--wire-color-primary));
|
||||
.wrn-navbar__menu-link[aria-current="page"]:hover,
|
||||
.wrn-navbar__dropdown > summary[aria-current="page"]:hover {
|
||||
color: var(--wrn-component-color, var(--wrn-color-primary));
|
||||
background: color-mix(
|
||||
in srgb,
|
||||
var(--wire-component-color, var(--wire-color-primary)) 16%,
|
||||
var(--wrn-component-color, var(--wrn-color-primary)) 16%,
|
||||
transparent
|
||||
);
|
||||
}
|
||||
|
||||
.wire-navbar__dropdown {
|
||||
.wrn-navbar__dropdown {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.wire-navbar__dropdown > summary {
|
||||
.wrn-navbar__dropdown > summary {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.wire-navbar__dropdown > summary::-webkit-details-marker {
|
||||
.wrn-navbar__dropdown > summary::-webkit-details-marker {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.wire-navbar__chevron {
|
||||
.wrn-navbar__chevron {
|
||||
width: 0.45rem;
|
||||
height: 0.45rem;
|
||||
border-right: 1.5px solid currentColor;
|
||||
border-bottom: 1.5px solid currentColor;
|
||||
transform: rotate(45deg) translateY(-0.15rem);
|
||||
transition: transform var(--wire-motion-fast, 150ms) ease;
|
||||
transition: transform var(--wrn-motion-fast, 150ms) ease;
|
||||
}
|
||||
|
||||
.wire-navbar__dropdown[open] .wire-navbar__chevron {
|
||||
.wrn-navbar__dropdown[open] .wrn-navbar__chevron {
|
||||
transform: rotate(225deg) translate(-0.1rem, -0.1rem);
|
||||
}
|
||||
|
||||
.wire-navbar__panel {
|
||||
.wrn-navbar__panel {
|
||||
position: absolute;
|
||||
top: calc(100% + 0.55rem);
|
||||
left: 50%;
|
||||
@@ -350,10 +347,10 @@ size: string = "default"
|
||||
max-width: min(90vw, 64rem);
|
||||
padding: 0.65rem;
|
||||
gap: 0.45rem;
|
||||
border: 1px solid var(--wire-color-border);
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: 0.9rem;
|
||||
color: var(--wire-color-text);
|
||||
background: var(--wire-color-surface);
|
||||
color: var(--wrn-color-text);
|
||||
background: var(--wrn-color-surface);
|
||||
box-shadow: 0 18px 48px rgb(15 23 42 / 0.16);
|
||||
opacity: 1;
|
||||
transform: translateX(-50%) translateY(0) scale(1);
|
||||
@@ -364,7 +361,7 @@ size: string = "default"
|
||||
display 180ms allow-discrete;
|
||||
}
|
||||
|
||||
.wire-navbar__panel::before {
|
||||
.wrn-navbar__panel::before {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: 100%;
|
||||
@@ -373,57 +370,57 @@ size: string = "default"
|
||||
content: "";
|
||||
}
|
||||
|
||||
.wire-navbar__dropdown:not([open]) > .wire-navbar__panel {
|
||||
.wrn-navbar__dropdown:not([open]) > .wrn-navbar__panel {
|
||||
display: none;
|
||||
opacity: 0;
|
||||
transform: translateX(-50%) translateY(-0.5rem) scale(0.98);
|
||||
}
|
||||
|
||||
@starting-style {
|
||||
.wire-navbar__dropdown[open] > .wire-navbar__panel {
|
||||
.wrn-navbar__dropdown[open] > .wrn-navbar__panel {
|
||||
opacity: 0;
|
||||
transform: translateX(-50%) translateY(-0.5rem) scale(0.98);
|
||||
}
|
||||
}
|
||||
|
||||
.wire-navbar__dropdown--mega {
|
||||
.wrn-navbar__dropdown--mega {
|
||||
position: static;
|
||||
}
|
||||
|
||||
.wire-navbar__dropdown--mega .wire-navbar__panel {
|
||||
.wrn-navbar__dropdown--mega .wrn-navbar__panel {
|
||||
right: auto;
|
||||
left: 50%;
|
||||
width: min(calc(100vw - 2rem), 64rem);
|
||||
}
|
||||
|
||||
.wire-navbar__panel--columns-2 {
|
||||
.wrn-navbar__panel--columns-2 {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.wire-navbar__panel--columns-3 {
|
||||
.wrn-navbar__panel--columns-3 {
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.wire-navbar__panel--columns-4 {
|
||||
.wrn-navbar__panel--columns-4 {
|
||||
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.wire-navbar__panel-intro {
|
||||
.wrn-navbar__panel-intro {
|
||||
grid-column: 1 / -1;
|
||||
margin: 0;
|
||||
padding: 0.5rem 0.65rem;
|
||||
color: var(--wire-color-muted);
|
||||
color: var(--wrn-color-muted);
|
||||
font-size: 0.8125rem;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.wire-navbar__group {
|
||||
.wrn-navbar__group {
|
||||
display: grid;
|
||||
align-content: start;
|
||||
gap: 0.25rem;
|
||||
}
|
||||
|
||||
.wire-navbar__group-title {
|
||||
.wrn-navbar__group-title {
|
||||
padding: 0.55rem 0.65rem 0.25rem;
|
||||
font-size: 0.7rem;
|
||||
font-weight: 600;
|
||||
@@ -431,14 +428,14 @@ size: string = "default"
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.wire-navbar__group > small {
|
||||
.wrn-navbar__group > small {
|
||||
padding: 0 0.65rem 0.4rem;
|
||||
color: var(--wire-color-muted);
|
||||
color: var(--wrn-color-muted);
|
||||
font-size: 0.7rem;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.wire-navbar__panel a {
|
||||
.wrn-navbar__panel a {
|
||||
display: flex;
|
||||
min-height: 2.75rem;
|
||||
padding: 0.65rem;
|
||||
@@ -449,52 +446,52 @@ size: string = "default"
|
||||
font-weight: 450;
|
||||
}
|
||||
|
||||
.wire-navbar__panel a:hover {
|
||||
background: var(--wire-color-surface-2);
|
||||
.wrn-navbar__panel a:hover {
|
||||
background: var(--wrn-color-surface-2);
|
||||
}
|
||||
|
||||
.wire-navbar__panel a span:last-child {
|
||||
.wrn-navbar__panel a span:last-child {
|
||||
display: grid;
|
||||
gap: 0.15rem;
|
||||
}
|
||||
|
||||
.wire-navbar__panel a strong {
|
||||
.wrn-navbar__panel a strong {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.wire-navbar__panel a small {
|
||||
color: var(--wire-color-muted);
|
||||
.wrn-navbar__panel a small {
|
||||
color: var(--wrn-color-muted);
|
||||
font-size: 0.7rem;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.wire-navbar__action {
|
||||
.wrn-navbar__action {
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
|
||||
.wire-navbar__action--primary {
|
||||
color: var(--wire-color-on-primary, #fff);
|
||||
background: var(--wire-component-color, var(--wire-color-primary));
|
||||
.wrn-navbar__action--primary {
|
||||
color: var(--wrn-color-on-primary, #fff);
|
||||
background: var(--wrn-component-color, var(--wrn-color-primary));
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.wire-navbar__action--outline {
|
||||
border-color: var(--wire-color-border);
|
||||
.wrn-navbar__action--outline {
|
||||
border-color: var(--wrn-color-border);
|
||||
}
|
||||
|
||||
.wire-navbar__toggle {
|
||||
.wrn-navbar__toggle {
|
||||
display: none;
|
||||
width: 2.75rem;
|
||||
height: 2.75rem;
|
||||
margin-left: auto;
|
||||
padding: 0.65rem;
|
||||
border: 1px solid var(--wire-color-border);
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: 0.65rem;
|
||||
color: inherit;
|
||||
background: var(--wire-color-surface);
|
||||
background: var(--wrn-color-surface);
|
||||
}
|
||||
|
||||
.wire-navbar__toggle span {
|
||||
.wrn-navbar__toggle span {
|
||||
display: block;
|
||||
height: 2px;
|
||||
margin: 0.25rem 0;
|
||||
@@ -502,13 +499,13 @@ size: string = "default"
|
||||
}
|
||||
|
||||
@media (max-width: 900px) {
|
||||
.wire-navbar--width-compact .wire-navbar__main {
|
||||
.wrn-navbar--width-compact .wrn-navbar__main {
|
||||
width: 100%;
|
||||
}
|
||||
.wire-navbar__toggle {
|
||||
.wrn-navbar__toggle {
|
||||
display: block;
|
||||
}
|
||||
.wire-navbar__collapse {
|
||||
.wrn-navbar__collapse {
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
right: 0;
|
||||
@@ -517,30 +514,30 @@ size: string = "default"
|
||||
padding: 0.75rem 1rem 1rem;
|
||||
align-items: stretch;
|
||||
flex-direction: column;
|
||||
background: var(--wire-color-surface);
|
||||
border-bottom: 1px solid var(--wire-color-border);
|
||||
background: var(--wrn-color-surface);
|
||||
border-bottom: 1px solid var(--wrn-color-border);
|
||||
box-shadow: 0 16px 32px rgb(15 23 42 / 0.12);
|
||||
max-height: calc(100dvh - 4rem);
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
overscroll-behavior: contain;
|
||||
}
|
||||
.wire-navbar__collapse.is-open {
|
||||
.wrn-navbar__collapse.is-open {
|
||||
display: flex;
|
||||
}
|
||||
.wire-navbar__menus,
|
||||
.wire-navbar__actions {
|
||||
.wrn-navbar__menus,
|
||||
.wrn-navbar__actions {
|
||||
width: 100%;
|
||||
align-items: stretch;
|
||||
flex-direction: column;
|
||||
}
|
||||
.wire-navbar__menu-link,
|
||||
.wire-navbar__dropdown > summary,
|
||||
.wire-navbar__action {
|
||||
.wrn-navbar__menu-link,
|
||||
.wrn-navbar__dropdown > summary,
|
||||
.wrn-navbar__action {
|
||||
width: 100%;
|
||||
}
|
||||
.wire-navbar__panel,
|
||||
.wire-navbar__dropdown--mega .wire-navbar__panel {
|
||||
.wrn-navbar__panel,
|
||||
.wrn-navbar__dropdown--mega .wrn-navbar__panel {
|
||||
position: static;
|
||||
width: 100%;
|
||||
max-width: none;
|
||||
@@ -548,27 +545,27 @@ size: string = "default"
|
||||
box-shadow: none;
|
||||
transform: none;
|
||||
overflow: hidden;
|
||||
animation: wire-navbar-mobile-panel 180ms ease both;
|
||||
animation: wrn-navbar-mobile-panel 180ms ease both;
|
||||
}
|
||||
.wire-navbar__dropdown:not([open]) > .wire-navbar__panel,
|
||||
.wire-navbar__dropdown[open] > .wire-navbar__panel {
|
||||
.wrn-navbar__dropdown:not([open]) > .wrn-navbar__panel,
|
||||
.wrn-navbar__dropdown[open] > .wrn-navbar__panel {
|
||||
transform: none;
|
||||
}
|
||||
.wire-navbar__panel[class*="wire-navbar__panel--columns-"] {
|
||||
.wrn-navbar__panel[class*="wrn-navbar__panel--columns-"] {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
.wire-navbar__panel::before {
|
||||
.wrn-navbar__panel::before {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 600px) {
|
||||
.wire-navbar__brand-copy small {
|
||||
.wrn-navbar__brand-copy small {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes wire-navbar-mobile-panel {
|
||||
@keyframes wrn-navbar-mobile-panel {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(-0.35rem);
|
||||
@@ -578,5 +575,74 @@ size: string = "default"
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Shared component foundation. */
|
||||
|
||||
.wrn-component {
|
||||
--wrn-component-color: var(--wrn-color-primary);
|
||||
--wrn-component-scale: 1;
|
||||
margin: 0;
|
||||
color: var(--wrn-color-text);
|
||||
font-family: var(--wrn-font-sans, inherit);
|
||||
}
|
||||
|
||||
.wrn-component--color-primary {
|
||||
--wrn-component-color: var(--wrn-color-primary);
|
||||
}
|
||||
|
||||
.wrn-component--color-secondary {
|
||||
--wrn-component-color: var(--wrn-color-secondary);
|
||||
}
|
||||
|
||||
.wrn-component--color-success {
|
||||
--wrn-component-color: var(--wrn-color-success);
|
||||
}
|
||||
|
||||
.wrn-component--color-warning {
|
||||
--wrn-component-color: var(--wrn-color-warning);
|
||||
}
|
||||
|
||||
.wrn-component--color-danger {
|
||||
--wrn-component-color: var(--wrn-color-danger);
|
||||
}
|
||||
|
||||
.wrn-component--color-info {
|
||||
--wrn-component-color: var(--wrn-color-info);
|
||||
}
|
||||
|
||||
.wrn-component--size-xs {
|
||||
--wrn-component-scale: 0.78;
|
||||
}
|
||||
|
||||
.wrn-component--size-sm {
|
||||
--wrn-component-scale: 0.88;
|
||||
}
|
||||
|
||||
.wrn-component--size-default,
|
||||
.wrn-component--size-md {
|
||||
--wrn-component-scale: 1;
|
||||
}
|
||||
|
||||
.wrn-component--size-lg {
|
||||
--wrn-component-scale: 1.14;
|
||||
}
|
||||
|
||||
.wrn-component--size-xl {
|
||||
--wrn-component-scale: 1.28;
|
||||
}
|
||||
|
||||
.wrn-component:not(.wrn-btn) {
|
||||
font-size: calc(1em * var(--wrn-component-scale));
|
||||
}
|
||||
|
||||
.wrn-component :is(a, button, input, select, textarea):focus-visible {
|
||||
outline-color: var(--wrn-component-color);
|
||||
}
|
||||
|
||||
.wrn-component p {
|
||||
margin: 0;
|
||||
color: var(--wrn-color-muted);
|
||||
line-height: 1.6;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,35 +104,35 @@ component Pagination {
|
||||
<nav
|
||||
{...attrs}
|
||||
data-ui-component="Pagination"
|
||||
class='wire-pagination {class}'
|
||||
class='wrn-pagination {class}'
|
||||
data-variant='{variant}'
|
||||
data-color='{color}'
|
||||
data-size='{size}'
|
||||
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 class="wire-pagination__slot">
|
||||
<span class="wire-pagination__gap" data-show="entry.gap">{entry.label}</span>
|
||||
<li class="wrn-pagination__slot">
|
||||
<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"}'
|
||||
@@ -144,18 +144,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>
|
||||
|
||||
@@ -164,8 +164,8 @@ component Pagination {
|
||||
}
|
||||
|
||||
style {
|
||||
.wire-pagination {
|
||||
--pagination-accent: var(--wire-color-primary);
|
||||
.wrn-pagination {
|
||||
--pagination-accent: var(--wrn-color-primary);
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
@@ -174,44 +174,44 @@ component Pagination {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.wire-pagination[data-color="secondary"] {
|
||||
--pagination-accent: var(--wire-color-secondary);
|
||||
.wrn-pagination[data-color="secondary"] {
|
||||
--pagination-accent: var(--wrn-color-secondary);
|
||||
}
|
||||
|
||||
.wire-pagination[data-color="success"] {
|
||||
--pagination-accent: var(--wire-color-success);
|
||||
.wrn-pagination[data-color="success"] {
|
||||
--pagination-accent: var(--wrn-color-success);
|
||||
}
|
||||
|
||||
.wire-pagination[data-color="danger"] {
|
||||
--pagination-accent: var(--wire-color-danger);
|
||||
.wrn-pagination[data-color="danger"] {
|
||||
--pagination-accent: var(--wrn-color-danger);
|
||||
}
|
||||
|
||||
.wire-pagination[data-color="info"] {
|
||||
--pagination-accent: var(--wire-color-info);
|
||||
.wrn-pagination[data-color="info"] {
|
||||
--pagination-accent: var(--wrn-color-info);
|
||||
}
|
||||
|
||||
.wire-pagination[data-size="sm"] {
|
||||
.wrn-pagination[data-size="sm"] {
|
||||
font-size: 0.82rem;
|
||||
}
|
||||
|
||||
.wire-pagination[data-size="lg"] {
|
||||
.wrn-pagination[data-size="lg"] {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.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;
|
||||
@@ -220,12 +220,12 @@ component Pagination {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.wire-pagination__slot {
|
||||
.wrn-pagination__slot {
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
.wire-pagination__page,
|
||||
.wire-pagination__step {
|
||||
.wrn-pagination__page,
|
||||
.wrn-pagination__step {
|
||||
appearance: none;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
@@ -233,56 +233,56 @@ 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:focus-visible,
|
||||
.wire-pagination__step:focus-visible {
|
||||
.wrn-pagination__page:focus-visible,
|
||||
.wrn-pagination__step:focus-visible {
|
||||
outline: 2px solid var(--pagination-accent);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
.wire-pagination__page[data-active="true"] {
|
||||
.wrn-pagination__page[data-active="true"] {
|
||||
border-color: var(--pagination-accent);
|
||||
background: var(--pagination-accent);
|
||||
color: var(--wire-color-primary-contrast);
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import ComponentBaseStyles from "../styles/ComponentBaseStyles.wrn"
|
||||
|
||||
component PinInput {
|
||||
outputs {
|
||||
input(payload: { value?: string | number | boolean | null; values?: Array<string | number | boolean | null | object>; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | string | number | boolean | null)
|
||||
@@ -51,7 +49,7 @@ component PinInput {
|
||||
view {
|
||||
<fieldset
|
||||
{...attrs}
|
||||
class="wire-component wire-component--color-{color} wire-component--size-{size} wire-next--pin-input {invalid ? 'wire-next--invalid' : ''} {disabled ? 'wire-next--disabled' : ''} {class}"
|
||||
class="wrn-component wrn-component--color-{color} wrn-component--size-{size} wrn-next--pin-input {invalid ? 'wrn-next--invalid' : ''} {disabled ? 'wrn-next--disabled' : ''} {class}"
|
||||
data-wrn-pin-input
|
||||
data-length="{length}"
|
||||
data-pattern="{pattern}"
|
||||
@@ -61,11 +59,11 @@ component PinInput {
|
||||
disabled="{disabled}"
|
||||
aria-describedby="{validationMessage ? `${name}-validation` : helpText ? `${name}-help` : ''}"
|
||||
>
|
||||
<div class="wire-next__pin-heading">
|
||||
<div class="wrn-next__pin-heading">
|
||||
<legend>{label}</legend>
|
||||
<button
|
||||
type="button"
|
||||
class="wire-next__pin-clear"
|
||||
class="wrn-next__pin-clear"
|
||||
data-pin-clear
|
||||
aria-label="{clearLabel}"
|
||||
title="{clearLabel}"
|
||||
@@ -76,7 +74,7 @@ component PinInput {
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="wire-next__pin-cells" role="group" aria-label="{label}">
|
||||
<div class="wrn-next__pin-cells" role="group" aria-label="{label}">
|
||||
{#each inputIndexes() as index}
|
||||
<input
|
||||
data-pin-cell
|
||||
@@ -95,7 +93,7 @@ component PinInput {
|
||||
autofocus="{autoFocus && index === 0}"
|
||||
/>
|
||||
{#if separator && groupSize !== 0 && (index + 1) % groupSize === 0 && index + 1 !== length}
|
||||
<span class="wire-next__pin-separator" aria-hidden="true">{separator}</span>
|
||||
<span class="wrn-next__pin-separator" aria-hidden="true">{separator}</span>
|
||||
{/if}
|
||||
{/each}
|
||||
</div>
|
||||
@@ -111,49 +109,48 @@ component PinInput {
|
||||
{#if helpText && !validationMessage}<small id="{name}-help">{helpText}</small>{/if}
|
||||
<small
|
||||
id="{name}-validation"
|
||||
class="wire-next__validation"
|
||||
class="wrn-next__validation"
|
||||
data-error="{name}"
|
||||
>{validationMessage}</small>
|
||||
</fieldset>
|
||||
<ComponentBaseStyles hidden />
|
||||
}
|
||||
|
||||
style {
|
||||
.wire-next--pin-input.wire-next--invalid .wire-next__pin-cells input,
|
||||
.wire-next--pin-input:has(input.wire-invalid) .wire-next__pin-cells input {
|
||||
border-color: var(--wire-color-danger);
|
||||
.wrn-next--pin-input.wrn-next--invalid .wrn-next__pin-cells input,
|
||||
.wrn-next--pin-input:has(input.wrn-invalid) .wrn-next__pin-cells input {
|
||||
border-color: var(--wrn-color-danger);
|
||||
}
|
||||
|
||||
.wire-next--pin-input {
|
||||
.wrn-next--pin-input {
|
||||
display: grid;
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
gap: 0.65rem;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
color: var(--wire-color-text);
|
||||
color: var(--wrn-color-text);
|
||||
}
|
||||
|
||||
.wire-next__pin-heading {
|
||||
.wrn-next__pin-heading {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.wire-next__pin-heading legend {
|
||||
.wrn-next__pin-heading legend {
|
||||
padding: 0;
|
||||
font-size: 0.82em;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.wire-next__pin-clear {
|
||||
.wrn-next__pin-clear {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.35rem;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
color: var(--wire-component-color);
|
||||
color: var(--wrn-component-color);
|
||||
background: transparent;
|
||||
font: inherit;
|
||||
font-size: 0.7em;
|
||||
@@ -161,12 +158,12 @@ component PinInput {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.wire-next__pin-clear > span:first-child {
|
||||
.wrn-next__pin-clear > span:first-child {
|
||||
width: 0.9rem;
|
||||
height: 0.9rem;
|
||||
}
|
||||
|
||||
.wire-next__pin-cells {
|
||||
.wrn-next__pin-cells {
|
||||
display: flex;
|
||||
max-width: 100%;
|
||||
align-items: center;
|
||||
@@ -176,66 +173,135 @@ component PinInput {
|
||||
scrollbar-width: thin;
|
||||
}
|
||||
|
||||
.wire-next--pin-input .wire-next__pin-cells input {
|
||||
.wrn-next--pin-input .wrn-next__pin-cells input {
|
||||
flex: 0 0 clamp(2.4rem, 8vw, 3.25rem);
|
||||
width: clamp(2.4rem, 8vw, 3.25rem);
|
||||
height: clamp(2.75rem, 9vw, 3.5rem);
|
||||
min-width: clamp(2.4rem, 8vw, 3.25rem);
|
||||
padding: 0;
|
||||
border: 1px solid var(--wire-color-border);
|
||||
border-radius: var(--wire-radius-sm);
|
||||
color: var(--wire-color-text);
|
||||
background: var(--wire-color-bg);
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: var(--wrn-radius-sm);
|
||||
color: var(--wrn-color-text);
|
||||
background: var(--wrn-color-bg);
|
||||
font: inherit;
|
||||
font-size: clamp(1rem, 3vw, 1.25rem);
|
||||
font-weight: 750;
|
||||
text-align: center;
|
||||
caret-color: var(--wire-component-color);
|
||||
caret-color: var(--wrn-component-color);
|
||||
transition:
|
||||
border-color var(--wire-motion-base) var(--wire-ease-standard),
|
||||
box-shadow var(--wire-motion-base) var(--wire-ease-standard),
|
||||
transform var(--wire-motion-fast) var(--wire-ease-standard);
|
||||
border-color var(--wrn-motion-base) var(--wrn-ease-standard),
|
||||
box-shadow var(--wrn-motion-base) var(--wrn-ease-standard),
|
||||
transform var(--wrn-motion-fast) var(--wrn-ease-standard);
|
||||
}
|
||||
|
||||
.wire-next--pin-input .wire-next__pin-cells input::placeholder {
|
||||
color: var(--wire-color-muted);
|
||||
.wrn-next--pin-input .wrn-next__pin-cells input::placeholder {
|
||||
color: var(--wrn-color-muted);
|
||||
opacity: 0.45;
|
||||
}
|
||||
|
||||
.wire-next--pin-input .wire-next__pin-cells input:focus-visible {
|
||||
border-color: var(--wire-component-color);
|
||||
.wrn-next--pin-input .wrn-next__pin-cells input:focus-visible {
|
||||
border-color: var(--wrn-component-color);
|
||||
outline: 0;
|
||||
box-shadow: 0 0 0 3px color-mix(in srgb, var(--wire-component-color) 18%, transparent);
|
||||
box-shadow: 0 0 0 3px color-mix(in srgb, var(--wrn-component-color) 18%, transparent);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.wire-next--pin-input .wire-next__pin-cells input:disabled,
|
||||
.wire-next--pin-input .wire-next__pin-cells input:read-only {
|
||||
.wrn-next--pin-input .wrn-next__pin-cells input:disabled,
|
||||
.wrn-next--pin-input .wrn-next__pin-cells input:read-only {
|
||||
cursor: not-allowed;
|
||||
opacity: 0.55;
|
||||
}
|
||||
|
||||
.wire-next__pin-separator {
|
||||
color: var(--wire-color-muted);
|
||||
.wrn-next__pin-separator {
|
||||
color: var(--wrn-color-muted);
|
||||
font-size: 1.1rem;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.wire-next--pin-input[data-complete="true"] .wire-next__pin-cells input {
|
||||
border-color: color-mix(in srgb, var(--wire-component-color) 72%, var(--wire-color-border));
|
||||
background: color-mix(in srgb, var(--wire-component-color) 7%, var(--wire-color-bg));
|
||||
.wrn-next--pin-input[data-complete="true"] .wrn-next__pin-cells input {
|
||||
border-color: color-mix(in srgb, var(--wrn-component-color) 72%, var(--wrn-color-border));
|
||||
background: color-mix(in srgb, var(--wrn-component-color) 7%, var(--wrn-color-bg));
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.wire-next__pin-cells {
|
||||
.wrn-next__pin-cells {
|
||||
gap: 0.3rem;
|
||||
}
|
||||
.wire-next--pin-input .wire-next__pin-cells input {
|
||||
.wrn-next--pin-input .wrn-next__pin-cells input {
|
||||
flex-basis: min(2.7rem, 12vw);
|
||||
width: min(2.7rem, 12vw);
|
||||
min-width: min(2.7rem, 12vw);
|
||||
height: min(3rem, 14vw);
|
||||
}
|
||||
}
|
||||
|
||||
/* Shared component foundation. */
|
||||
|
||||
.wrn-component {
|
||||
--wrn-component-color: var(--wrn-color-primary);
|
||||
--wrn-component-scale: 1;
|
||||
margin: 0;
|
||||
color: var(--wrn-color-text);
|
||||
font-family: var(--wrn-font-sans, inherit);
|
||||
}
|
||||
|
||||
.wrn-component--color-primary {
|
||||
--wrn-component-color: var(--wrn-color-primary);
|
||||
}
|
||||
|
||||
.wrn-component--color-secondary {
|
||||
--wrn-component-color: var(--wrn-color-secondary);
|
||||
}
|
||||
|
||||
.wrn-component--color-success {
|
||||
--wrn-component-color: var(--wrn-color-success);
|
||||
}
|
||||
|
||||
.wrn-component--color-warning {
|
||||
--wrn-component-color: var(--wrn-color-warning);
|
||||
}
|
||||
|
||||
.wrn-component--color-danger {
|
||||
--wrn-component-color: var(--wrn-color-danger);
|
||||
}
|
||||
|
||||
.wrn-component--color-info {
|
||||
--wrn-component-color: var(--wrn-color-info);
|
||||
}
|
||||
|
||||
.wrn-component--size-xs {
|
||||
--wrn-component-scale: 0.78;
|
||||
}
|
||||
|
||||
.wrn-component--size-sm {
|
||||
--wrn-component-scale: 0.88;
|
||||
}
|
||||
|
||||
.wrn-component--size-default,
|
||||
.wrn-component--size-md {
|
||||
--wrn-component-scale: 1;
|
||||
}
|
||||
|
||||
.wrn-component--size-lg {
|
||||
--wrn-component-scale: 1.14;
|
||||
}
|
||||
|
||||
.wrn-component--size-xl {
|
||||
--wrn-component-scale: 1.28;
|
||||
}
|
||||
|
||||
.wrn-component:not(.wrn-btn) {
|
||||
font-size: calc(1em * var(--wrn-component-scale));
|
||||
}
|
||||
|
||||
.wrn-component :is(a, button, input, select, textarea):focus-visible {
|
||||
outline-color: var(--wrn-component-color);
|
||||
}
|
||||
|
||||
.wrn-component p {
|
||||
margin: 0;
|
||||
color: var(--wrn-color-muted);
|
||||
line-height: 1.6;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,12 +91,12 @@ component Popover {
|
||||
data-size='{size}'
|
||||
data-color='{color}'
|
||||
data-variant='{variant}'
|
||||
class='wire-popover {class}'
|
||||
class='wrn-popover {class}'
|
||||
@keydown='handleKeydown(event)'
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
class="wire-popover__trigger"
|
||||
class="wrn-popover__trigger"
|
||||
disabled='{disabled}'
|
||||
aria-haspopup="dialog"
|
||||
aria-expanded='{open || visible ? "true" : "false"}'
|
||||
@@ -114,7 +114,7 @@ component Popover {
|
||||
{#if closeOnOutside}
|
||||
<button
|
||||
type="button"
|
||||
class="wire-popover__dismiss-layer"
|
||||
class="wrn-popover__dismiss-layer"
|
||||
data-show='{open || visible}'
|
||||
aria-label='{closeLabel}'
|
||||
@click='hidePopover("outside", event)'
|
||||
@@ -122,23 +122,23 @@ component Popover {
|
||||
{/if}
|
||||
|
||||
<section
|
||||
class="wire-popover__panel"
|
||||
class="wrn-popover__panel"
|
||||
data-wrn-anchored="true"
|
||||
data-show='{open || visible}'
|
||||
role="dialog"
|
||||
aria-label='{title || triggerLabel}'
|
||||
>
|
||||
{#if showArrow}
|
||||
<span class="wire-popover__arrow" data-wrn-anchor-arrow="true" aria-hidden="true"></span>
|
||||
<span class="wrn-popover__arrow" data-wrn-anchor-arrow="true" aria-hidden="true"></span>
|
||||
{/if}
|
||||
|
||||
{#if title || description || icon || showClose}
|
||||
<header class="wire-popover__header">
|
||||
<div class="wire-popover__heading">
|
||||
<header class="wrn-popover__header">
|
||||
<div class="wrn-popover__heading">
|
||||
{#if icon}
|
||||
<span class='wire-popover__icon {icon}' aria-hidden="true"></span>
|
||||
<span class='wrn-popover__icon {icon}' aria-hidden="true"></span>
|
||||
{/if}
|
||||
<div class="wire-popover__heading-copy">
|
||||
<div class="wrn-popover__heading-copy">
|
||||
<slot name="header"></slot>
|
||||
{#if title}
|
||||
<h3>{title}</h3>
|
||||
@@ -152,7 +152,7 @@ component Popover {
|
||||
{#if showClose}
|
||||
<button
|
||||
type="button"
|
||||
class="wire-popover__close"
|
||||
class="wrn-popover__close"
|
||||
aria-label='{closeLabel}'
|
||||
@click='hidePopover("close-button", event)'
|
||||
>
|
||||
@@ -162,16 +162,16 @@ component Popover {
|
||||
</header>
|
||||
{/if}
|
||||
|
||||
<div class="wire-popover__body">
|
||||
<div class="wrn-popover__body">
|
||||
<slot></slot>
|
||||
</div>
|
||||
|
||||
{#if actionLabel}
|
||||
<footer class="wire-popover__footer">
|
||||
<footer class="wrn-popover__footer">
|
||||
{#if actionHref}
|
||||
<a
|
||||
href='{actionHref}'
|
||||
class="wire-popover__action"
|
||||
class="wrn-popover__action"
|
||||
@click='activateAction(event)'
|
||||
>
|
||||
<span>{actionLabel}</span>
|
||||
@@ -184,7 +184,7 @@ component Popover {
|
||||
{:else}
|
||||
<button
|
||||
type="button"
|
||||
class="wire-popover__action"
|
||||
class="wrn-popover__action"
|
||||
@click='activateAction(event)'
|
||||
>
|
||||
<span>{actionLabel}</span>
|
||||
@@ -204,45 +204,45 @@ component Popover {
|
||||
}
|
||||
|
||||
style {
|
||||
.wire-popover {
|
||||
--popover-accent: var(--wire-color-primary);
|
||||
--popover-soft: var(--wire-color-primary-soft);
|
||||
--popover-contrast: var(--wire-color-primary-contrast);
|
||||
.wrn-popover {
|
||||
--popover-accent: var(--wrn-color-primary);
|
||||
--popover-soft: var(--wrn-color-primary-soft);
|
||||
--popover-contrast: var(--wrn-color-primary-contrast);
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
.wire-popover[data-color="secondary"] {
|
||||
--popover-accent: var(--wire-color-secondary);
|
||||
--popover-soft: var(--wire-color-secondary-soft);
|
||||
--popover-contrast: var(--wire-color-secondary-contrast);
|
||||
.wrn-popover[data-color="secondary"] {
|
||||
--popover-accent: var(--wrn-color-secondary);
|
||||
--popover-soft: var(--wrn-color-secondary-soft);
|
||||
--popover-contrast: var(--wrn-color-secondary-contrast);
|
||||
}
|
||||
|
||||
.wire-popover[data-color="info"] {
|
||||
--popover-accent: var(--wire-color-info);
|
||||
--popover-soft: var(--wire-color-info-soft);
|
||||
--popover-contrast: var(--wire-color-info-contrast);
|
||||
.wrn-popover[data-color="info"] {
|
||||
--popover-accent: var(--wrn-color-info);
|
||||
--popover-soft: var(--wrn-color-info-soft);
|
||||
--popover-contrast: var(--wrn-color-info-contrast);
|
||||
}
|
||||
|
||||
.wire-popover[data-color="success"] {
|
||||
--popover-accent: var(--wire-color-success);
|
||||
--popover-soft: var(--wire-color-success-soft);
|
||||
--popover-contrast: var(--wire-color-success-contrast);
|
||||
.wrn-popover[data-color="success"] {
|
||||
--popover-accent: var(--wrn-color-success);
|
||||
--popover-soft: var(--wrn-color-success-soft);
|
||||
--popover-contrast: var(--wrn-color-success-contrast);
|
||||
}
|
||||
|
||||
.wire-popover[data-color="warning"] {
|
||||
--popover-accent: var(--wire-color-warning);
|
||||
--popover-soft: var(--wire-color-warning-soft);
|
||||
--popover-contrast: var(--wire-color-warning-text);
|
||||
.wrn-popover[data-color="warning"] {
|
||||
--popover-accent: var(--wrn-color-warning);
|
||||
--popover-soft: var(--wrn-color-warning-soft);
|
||||
--popover-contrast: var(--wrn-color-warning-text);
|
||||
}
|
||||
|
||||
.wire-popover[data-color="danger"] {
|
||||
--popover-accent: var(--wire-color-danger);
|
||||
--popover-soft: var(--wire-color-danger-soft);
|
||||
--popover-contrast: var(--wire-color-on-danger);
|
||||
.wrn-popover[data-color="danger"] {
|
||||
--popover-accent: var(--wrn-color-danger);
|
||||
--popover-soft: var(--wrn-color-danger-soft);
|
||||
--popover-contrast: var(--wrn-color-on-danger);
|
||||
}
|
||||
|
||||
.wire-popover__trigger {
|
||||
.wrn-popover__trigger {
|
||||
appearance: none;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
@@ -250,9 +250,9 @@ component Popover {
|
||||
gap: 0.55rem;
|
||||
min-height: 2.55rem;
|
||||
padding: 0.65rem 0.9rem;
|
||||
color: var(--wire-color-text);
|
||||
background: var(--wire-color-surface-raised);
|
||||
border: 1px solid var(--wire-color-border);
|
||||
color: var(--wrn-color-text);
|
||||
background: var(--wrn-color-surface-raised);
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: 0.78rem;
|
||||
font: inherit;
|
||||
font-size: 0.84rem;
|
||||
@@ -261,33 +261,33 @@ component Popover {
|
||||
transition: color 150ms ease, border-color 150ms ease, background-color 150ms ease;
|
||||
}
|
||||
|
||||
.wire-popover__trigger:hover,
|
||||
.wire-popover__trigger:focus-visible,
|
||||
.wire-popover[data-open="true"] .wire-popover__trigger {
|
||||
.wrn-popover__trigger:hover,
|
||||
.wrn-popover__trigger:focus-visible,
|
||||
.wrn-popover[data-open="true"] .wrn-popover__trigger {
|
||||
color: var(--popover-accent);
|
||||
background: var(--popover-soft);
|
||||
border-color: color-mix(in srgb, var(--popover-accent) 38%, var(--wire-color-border));
|
||||
border-color: color-mix(in srgb, var(--popover-accent) 38%, var(--wrn-color-border));
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.wire-popover__trigger:disabled {
|
||||
.wrn-popover__trigger:disabled {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.wire-popover[data-size="sm"] .wire-popover__trigger {
|
||||
.wrn-popover[data-size="sm"] .wrn-popover__trigger {
|
||||
min-height: 2.2rem;
|
||||
padding: 0.5rem 0.72rem;
|
||||
font-size: 0.78rem;
|
||||
}
|
||||
|
||||
.wire-popover[data-size="lg"] .wire-popover__trigger {
|
||||
.wrn-popover[data-size="lg"] .wrn-popover__trigger {
|
||||
min-height: 2.9rem;
|
||||
padding: 0.78rem 1.05rem;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.wire-popover__dismiss-layer {
|
||||
.wrn-popover__dismiss-layer {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
z-index: 1120;
|
||||
@@ -297,18 +297,18 @@ component Popover {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.wire-popover__panel {
|
||||
.wrn-popover__panel {
|
||||
position: absolute;
|
||||
z-index: 1121;
|
||||
top: calc(100% + 0.72rem);
|
||||
left: 0;
|
||||
width: 18rem;
|
||||
max-width: calc(100vw - 1.5rem);
|
||||
color: var(--wire-color-text);
|
||||
color: var(--wrn-color-text);
|
||||
background:
|
||||
linear-gradient(145deg, color-mix(in srgb, var(--popover-accent) 5%, transparent), transparent 62%),
|
||||
color-mix(in srgb, var(--wire-color-surface-raised) 97%, transparent);
|
||||
border: 1px solid color-mix(in srgb, var(--popover-accent) 18%, var(--wire-color-border));
|
||||
color-mix(in srgb, var(--wrn-color-surface-raised) 97%, transparent);
|
||||
border: 1px solid color-mix(in srgb, var(--popover-accent) 18%, var(--wrn-color-border));
|
||||
border-radius: 1rem;
|
||||
box-shadow:
|
||||
0 1px 0 color-mix(in srgb, white 5%, transparent) inset,
|
||||
@@ -316,125 +316,125 @@ component Popover {
|
||||
backdrop-filter: blur(18px);
|
||||
}
|
||||
|
||||
.wire-popover[data-width="sm"] .wire-popover__panel {
|
||||
.wrn-popover[data-width="sm"] .wrn-popover__panel {
|
||||
width: 14rem;
|
||||
}
|
||||
|
||||
.wire-popover[data-width="lg"] .wire-popover__panel {
|
||||
.wrn-popover[data-width="lg"] .wrn-popover__panel {
|
||||
width: 24rem;
|
||||
}
|
||||
|
||||
.wire-popover[data-width="xl"] .wire-popover__panel {
|
||||
.wrn-popover[data-width="xl"] .wrn-popover__panel {
|
||||
width: 32rem;
|
||||
}
|
||||
|
||||
.wire-popover[data-width="trigger"] .wire-popover__panel {
|
||||
.wrn-popover[data-width="trigger"] .wrn-popover__panel {
|
||||
width: 100%;
|
||||
min-width: 100%;
|
||||
}
|
||||
|
||||
.wire-popover[data-placement="bottom-end"] .wire-popover__panel {
|
||||
.wrn-popover[data-placement="bottom-end"] .wrn-popover__panel {
|
||||
right: 0;
|
||||
left: auto;
|
||||
}
|
||||
|
||||
.wire-popover[data-placement="top-start"] .wire-popover__panel {
|
||||
.wrn-popover[data-placement="top-start"] .wrn-popover__panel {
|
||||
top: auto;
|
||||
bottom: calc(100% + 0.72rem);
|
||||
}
|
||||
|
||||
.wire-popover[data-placement="top-end"] .wire-popover__panel {
|
||||
.wrn-popover[data-placement="top-end"] .wrn-popover__panel {
|
||||
top: auto;
|
||||
right: 0;
|
||||
bottom: calc(100% + 0.72rem);
|
||||
left: auto;
|
||||
}
|
||||
|
||||
.wire-popover[data-placement="left"] .wire-popover__panel {
|
||||
.wrn-popover[data-placement="left"] .wrn-popover__panel {
|
||||
top: 50%;
|
||||
right: calc(100% + 0.72rem);
|
||||
left: auto;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
.wire-popover[data-placement="right"] .wire-popover__panel {
|
||||
.wrn-popover[data-placement="right"] .wrn-popover__panel {
|
||||
top: 50%;
|
||||
left: calc(100% + 0.72rem);
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
.wire-popover[data-variant="soft"] .wire-popover__panel {
|
||||
.wrn-popover[data-variant="soft"] .wrn-popover__panel {
|
||||
background:
|
||||
linear-gradient(145deg, var(--popover-soft), transparent 70%),
|
||||
var(--wire-color-surface-raised);
|
||||
var(--wrn-color-surface-raised);
|
||||
box-shadow: 0 18px 48px color-mix(in srgb, black 16%, transparent);
|
||||
}
|
||||
|
||||
.wire-popover[data-variant="outline"] .wire-popover__panel {
|
||||
background: var(--wire-color-surface-raised);
|
||||
.wrn-popover[data-variant="outline"] .wrn-popover__panel {
|
||||
background: var(--wrn-color-surface-raised);
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.wire-popover[data-variant="solid"] .wire-popover__panel {
|
||||
.wrn-popover[data-variant="solid"] .wrn-popover__panel {
|
||||
color: var(--popover-contrast);
|
||||
background: var(--popover-accent);
|
||||
border-color: color-mix(in srgb, white 20%, transparent);
|
||||
}
|
||||
|
||||
.wire-popover__arrow {
|
||||
.wrn-popover__arrow {
|
||||
position: absolute;
|
||||
top: -0.35rem;
|
||||
left: 1.25rem;
|
||||
width: 0.7rem;
|
||||
height: 0.7rem;
|
||||
background: inherit;
|
||||
border-top: 1px solid color-mix(in srgb, var(--popover-accent) 18%, var(--wire-color-border));
|
||||
border-left: 1px solid color-mix(in srgb, var(--popover-accent) 18%, var(--wire-color-border));
|
||||
border-top: 1px solid color-mix(in srgb, var(--popover-accent) 18%, var(--wrn-color-border));
|
||||
border-left: 1px solid color-mix(in srgb, var(--popover-accent) 18%, var(--wrn-color-border));
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
|
||||
.wire-popover[data-placement="bottom-end"] .wire-popover__arrow {
|
||||
.wrn-popover[data-placement="bottom-end"] .wrn-popover__arrow {
|
||||
right: 1.25rem;
|
||||
left: auto;
|
||||
}
|
||||
|
||||
.wire-popover[data-placement="top-start"] .wire-popover__arrow,
|
||||
.wire-popover[data-placement="top-end"] .wire-popover__arrow {
|
||||
.wrn-popover[data-placement="top-start"] .wrn-popover__arrow,
|
||||
.wrn-popover[data-placement="top-end"] .wrn-popover__arrow {
|
||||
top: auto;
|
||||
bottom: -0.35rem;
|
||||
transform: rotate(225deg);
|
||||
}
|
||||
|
||||
.wire-popover[data-placement="left"] .wire-popover__arrow {
|
||||
.wrn-popover[data-placement="left"] .wrn-popover__arrow {
|
||||
top: 50%;
|
||||
right: -0.35rem;
|
||||
left: auto;
|
||||
transform: translateY(-50%) rotate(135deg);
|
||||
}
|
||||
|
||||
.wire-popover[data-placement="right"] .wire-popover__arrow {
|
||||
.wrn-popover[data-placement="right"] .wrn-popover__arrow {
|
||||
top: 50%;
|
||||
left: -0.35rem;
|
||||
transform: translateY(-50%) rotate(-45deg);
|
||||
}
|
||||
|
||||
.wire-popover__header {
|
||||
.wrn-popover__header {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
gap: 0.8rem;
|
||||
padding: 1rem 1rem 0.8rem;
|
||||
border-bottom: 1px solid var(--wire-color-border);
|
||||
border-bottom: 1px solid var(--wrn-color-border);
|
||||
}
|
||||
|
||||
.wire-popover__heading {
|
||||
.wrn-popover__heading {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 0.7rem;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.wire-popover__icon {
|
||||
.wrn-popover__icon {
|
||||
flex: 0 0 auto;
|
||||
width: 1.05rem;
|
||||
height: 1.05rem;
|
||||
@@ -442,33 +442,33 @@ component Popover {
|
||||
color: var(--popover-accent);
|
||||
}
|
||||
|
||||
.wire-popover[data-variant="solid"] .wire-popover__icon {
|
||||
.wrn-popover[data-variant="solid"] .wrn-popover__icon {
|
||||
color: currentColor;
|
||||
}
|
||||
|
||||
.wire-popover__heading-copy {
|
||||
.wrn-popover__heading-copy {
|
||||
display: grid;
|
||||
gap: 0.2rem;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.wire-popover__heading-copy h3,
|
||||
.wire-popover__heading-copy p {
|
||||
.wrn-popover__heading-copy h3,
|
||||
.wrn-popover__heading-copy p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.wire-popover__heading-copy h3 {
|
||||
.wrn-popover__heading-copy h3 {
|
||||
font-size: 0.9rem;
|
||||
font-weight: 650;
|
||||
}
|
||||
|
||||
.wire-popover__heading-copy p {
|
||||
color: var(--wire-color-text-muted);
|
||||
.wrn-popover__heading-copy p {
|
||||
color: var(--wrn-color-text-muted);
|
||||
font-size: 0.74rem;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.wire-popover[data-variant="solid"] .wire-popover__heading-copy p {
|
||||
.wrn-popover[data-variant="solid"] .wrn-popover__heading-copy p {
|
||||
color: color-mix(in srgb, currentColor 76%, transparent);
|
||||
}
|
||||
|
||||
@@ -477,7 +477,7 @@ component Popover {
|
||||
* outranks the browser default and crushes the icon inside this
|
||||
* fixed-size button. Same trap as Modal and Drawer.
|
||||
*/
|
||||
.wire-popover__close {
|
||||
.wrn-popover__close {
|
||||
padding: 0;
|
||||
appearance: none;
|
||||
display: inline-flex;
|
||||
@@ -486,25 +486,25 @@ component Popover {
|
||||
flex: 0 0 auto;
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
color: var(--wire-color-text-muted);
|
||||
background: var(--wire-color-surface-soft);
|
||||
border: 1px solid var(--wire-color-border);
|
||||
color: var(--wrn-color-text-muted);
|
||||
background: var(--wrn-color-surface-soft);
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: 0.65rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.wire-popover__body {
|
||||
.wrn-popover__body {
|
||||
padding: 1rem;
|
||||
color: var(--wire-color-text-muted);
|
||||
color: var(--wrn-color-text-muted);
|
||||
font-size: 0.8rem;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.wire-popover__footer {
|
||||
.wrn-popover__footer {
|
||||
padding: 0 1rem 1rem;
|
||||
}
|
||||
|
||||
.wire-popover__action {
|
||||
.wrn-popover__action {
|
||||
appearance: none;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
@@ -524,7 +524,7 @@ component Popover {
|
||||
}
|
||||
|
||||
@media (max-width: 639px) {
|
||||
.wire-popover__panel {
|
||||
.wrn-popover__panel {
|
||||
position: fixed;
|
||||
right: 0.75rem;
|
||||
bottom: 0.75rem;
|
||||
@@ -535,7 +535,7 @@ component Popover {
|
||||
transform: none;
|
||||
}
|
||||
|
||||
.wire-popover__arrow {
|
||||
.wrn-popover__arrow {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
import FieldStyles from "../styles/FieldStyles.wrn"
|
||||
|
||||
import ComponentBaseStyles from "../styles/ComponentBaseStyles.wrn"
|
||||
|
||||
component RangeSlider {
|
||||
outputs {
|
||||
input(payload: ({ value: number; name: string; sourceEvent: Event }) | ({ sourceEvent?: Event; value: string | number | boolean | null | object; [key: string]: string | number | boolean | null | object } | string | number | boolean | null | object[]))
|
||||
@@ -41,57 +37,55 @@ component RangeSlider {
|
||||
state currentValue = value
|
||||
functions {
|
||||
shared function percent() { if (Number(max) === Number(min)) { return 0 } return (Number(currentValue) - Number(min)) / (Number(max) - Number(min)) * 100 }
|
||||
client function setValue(nextValue, sourceEvent, commit, detail, root, slider, input, outputElement, progressValue) { if (readonly || disabled) { return } currentValue = Number(nextValue); root = sourceEvent.currentTarget.closest(".wire-next--range-slider"); if (root) { slider = root.querySelector("[role=slider]"); input = root.querySelector("input[name='" + name + "']"); outputElement = root.querySelector("output"); progressValue = (currentValue - Number(min)) / (Number(max) - Number(min)) * 100; if (slider) { slider.setAttribute("aria-valuenow", String(currentValue)); slider.style.setProperty("--wire-range-progress", progressValue + "%") } if (input) { input.value = String(currentValue) } if (outputElement) { outputElement.textContent = String(currentValue) } } detail = { value: currentValue, min: min, max: max, step: step, name: name, sourceEvent: sourceEvent }; output.input(detail); if (commit) { output.change(detail) } }
|
||||
client function setValue(nextValue, sourceEvent, commit, detail, root, slider, input, outputElement, progressValue) { if (readonly || disabled) { return } currentValue = Number(nextValue); root = sourceEvent.currentTarget.closest(".wrn-next--range-slider"); if (root) { slider = root.querySelector("[role=slider]"); input = root.querySelector("input[name='" + name + "']"); outputElement = root.querySelector("output"); progressValue = (currentValue - Number(min)) / (Number(max) - Number(min)) * 100; if (slider) { slider.setAttribute("aria-valuenow", String(currentValue)); slider.style.setProperty("--wrn-range-progress", progressValue + "%") } if (input) { input.value = String(currentValue) } if (outputElement) { outputElement.textContent = String(currentValue) } } detail = { value: currentValue, min: min, max: max, step: step, name: name, sourceEvent: sourceEvent }; output.input(detail); if (commit) { output.change(detail) } }
|
||||
client function valueFromPointer(sourceEvent, rect, ratio) { rect = sourceEvent.currentTarget.getBoundingClientRect(); ratio = Math.max(0, Math.min(1, (sourceEvent.clientX - rect.left) / rect.width)); return Number(min) + ratio * (Number(max) - Number(min)) }
|
||||
client function beginSlide(sourceEvent, rect, ratio, rawValue) { if (readonly || disabled) { return } sourceEvent.currentTarget.setPointerCapture(sourceEvent.pointerId); rect = sourceEvent.currentTarget.getBoundingClientRect(); ratio = Math.max(0, Math.min(1, (sourceEvent.clientX - rect.left) / rect.width)); rawValue = Number(min) + ratio * (Number(max) - Number(min)); currentValue = Number(min) + Math.round((rawValue - Number(min)) / Number(step)) * Number(step); output.input({ value: currentValue, name: name, sourceEvent: sourceEvent }) }
|
||||
client function moveSlide(sourceEvent, rect, ratio, rawValue) { if (!sourceEvent.currentTarget.hasPointerCapture(sourceEvent.pointerId)) { return } rect = sourceEvent.currentTarget.getBoundingClientRect(); ratio = Math.max(0, Math.min(1, (sourceEvent.clientX - rect.left) / rect.width)); rawValue = Number(min) + ratio * (Number(max) - Number(min)); currentValue = Number(min) + Math.round((rawValue - Number(min)) / Number(step)) * Number(step); output.input({ value: currentValue, name: name, sourceEvent: sourceEvent }) }
|
||||
client function endSlide(sourceEvent, rect, ratio, rawValue) { rect = sourceEvent.currentTarget.getBoundingClientRect(); ratio = Math.max(0, Math.min(1, (sourceEvent.clientX - rect.left) / rect.width)); rawValue = Number(min) + ratio * (Number(max) - Number(min)); currentValue = Number(min) + Math.round((rawValue - Number(min)) / Number(step)) * Number(step); if (sourceEvent.currentTarget.hasPointerCapture(sourceEvent.pointerId)) { sourceEvent.currentTarget.releasePointerCapture(sourceEvent.pointerId) } output.change({ value: currentValue, name: name, sourceEvent: sourceEvent }) }
|
||||
client function selectMark(sourceEvent, root, slider, input, outputElement, nextValue, progressValue, detail) { if (readonly || disabled) { return } root = sourceEvent.currentTarget.closest(".wire-next--range-slider"); slider = root.querySelector(".wire-next__custom-slider"); input = root.querySelector(".wire-next__range-value"); outputElement = root.querySelector("output"); nextValue = Number(sourceEvent.currentTarget.dataset.value); currentValue = nextValue; progressValue = (nextValue - Number(min)) / (Number(max) - Number(min)) * 100; slider.setAttribute("aria-valuenow", String(nextValue)); slider.style.setProperty("--wire-range-progress", progressValue + "%"); input.setAttribute("value", String(nextValue)); outputElement.replaceChildren(String(nextValue)); detail = { value: nextValue, min: min, max: max, step: step, name: name, sourceEvent: sourceEvent }; output.input(detail); output.change(detail) }
|
||||
client function selectMark(sourceEvent, root, slider, input, outputElement, nextValue, progressValue, detail) { if (readonly || disabled) { return } root = sourceEvent.currentTarget.closest(".wrn-next--range-slider"); slider = root.querySelector(".wrn-next__custom-slider"); input = root.querySelector(".wrn-next__range-value"); outputElement = root.querySelector("output"); nextValue = Number(sourceEvent.currentTarget.dataset.value); currentValue = nextValue; progressValue = (nextValue - Number(min)) / (Number(max) - Number(min)) * 100; slider.setAttribute("aria-valuenow", String(nextValue)); slider.style.setProperty("--wrn-range-progress", progressValue + "%"); input.setAttribute("value", String(nextValue)); outputElement.replaceChildren(String(nextValue)); detail = { value: nextValue, min: min, max: max, step: step, name: name, sourceEvent: sourceEvent }; output.input(detail); output.change(detail) }
|
||||
client function handleKey(sourceEvent) { if (sourceEvent.key === "ArrowRight") { sourceEvent.preventDefault(); currentValue = Math.min(Number(max), Number(currentValue) + Number(step)); output.input({ value: currentValue, name: name, sourceEvent: sourceEvent }); output.change({ value: currentValue, name: name, sourceEvent: sourceEvent }) } if (sourceEvent.key === "ArrowLeft") { sourceEvent.preventDefault(); currentValue = Math.max(Number(min), Number(currentValue) - Number(step)); output.input({ value: currentValue, name: name, sourceEvent: sourceEvent }); output.change({ value: currentValue, name: name, sourceEvent: sourceEvent }) } if (sourceEvent.key === "Home") { sourceEvent.preventDefault(); currentValue = Number(min); output.change({ value: currentValue, name: name, sourceEvent: sourceEvent }) } if (sourceEvent.key === "End") { sourceEvent.preventDefault(); currentValue = Number(max); output.change({ value: currentValue, name: name, sourceEvent: sourceEvent }) } }
|
||||
client function emitFocus(nameEvent, sourceEvent) { output[nameEvent]({ value: currentValue, name: name, sourceEvent: sourceEvent }) }
|
||||
client function decreaseValue(sourceEvent) { currentValue = Math.max(Number(min), Number(currentValue) - Number(step)); output.input({ value: currentValue, name: name, sourceEvent: sourceEvent }); output.change({ value: currentValue, name: name, sourceEvent: sourceEvent }) }
|
||||
client function increaseValue(sourceEvent) { currentValue = Math.min(Number(max), Number(currentValue) + Number(step)); output.input({ value: currentValue, name: name, sourceEvent: sourceEvent }); output.change({ value: currentValue, name: name, sourceEvent: sourceEvent }) }
|
||||
}
|
||||
view {
|
||||
<div {...attrs} class="wire-component wire-component--color-{color} wire-component--size-{size} wire-next--field wire-next--range-slider {class}" data-variant="{variant}" data-inline="{inline}" data-invalid="{error ? 'true' : 'false'}">
|
||||
<div class="wire-next__field-heading"><label class="{hiddenLabel ? 'wire-next__sr-only' : ''}" for="{id || name}">{label}</label>{#if cornerHint}<span class="wire-next__field-hint">{cornerHint}</span>{/if}</div>
|
||||
<div class="wire-next__range-control" data-variant="{variant}" data-icon-position="{iconPosition}" data-show-steps="{showSteps}">
|
||||
<div {...attrs} class="wrn-component wrn-component--color-{color} wrn-component--size-{size} wrn-next--field wrn-next--range-slider {class}" data-variant="{variant}" data-inline="{inline}" data-invalid="{error ? 'true' : 'false'}">
|
||||
<div class="wrn-next__field-heading"><label class="{hiddenLabel ? 'wrn-next__sr-only' : ''}" for="{id || name}">{label}</label>{#if cornerHint}<span class="wrn-next__field-hint">{cornerHint}</span>{/if}</div>
|
||||
<div class="wrn-next__range-control" data-variant="{variant}" data-icon-position="{iconPosition}" data-show-steps="{showSteps}">
|
||||
{#if icon}<span class="{icon}" aria-hidden="true"></span>{/if}
|
||||
<button type="button" class="wire-next__range-stepper" aria-label="Decrease {label}" disabled="{disabled || readonly}" @click="decreaseValue(event)">−</button>
|
||||
<div class="wire-next__range-track">
|
||||
<input id="{id || name}" class="wire-next__sr-only wire-next__range-value" type="number" name="{name}" value="{currentValue}" min="{min}" max="{max}" step="{step}" required="{required}" readonly />
|
||||
<div class="wire-next__custom-slider" role="slider" tabindex="{disabled ? '-1' : '0'}" aria-label="{hiddenLabel ? label : ''}" aria-valuemin="{min}" aria-valuemax="{max}" aria-valuenow="{currentValue}" aria-disabled="{disabled}" aria-readonly="{readonly}" aria-invalid="{error ? 'true' : 'false'}" style="--wire-range-progress: {percent()}%" @pointerdown="beginSlide(event)" @pointermove="moveSlide(event)" @pointerup="endSlide(event)" @pointercancel="endSlide(event)" @keydown="handleKey(event)" @focus="emitFocus('focus', event)" @blur="emitFocus('blur', event)">
|
||||
<span class="wire-next__slider-fill"></span><span class="wire-next__slider-thumb"></span>
|
||||
{#if marks.length}<span class="wire-next__slider-marks">{#each marks as mark}<button type="button" data-value="{mark.value}" style="left: {(Number(mark.value) - Number(min)) / (Number(max) - Number(min)) * 100}%" aria-label="{mark.label}" @click="selectMark(event)"></button>{/each}</span>{/if}
|
||||
<button type="button" class="wrn-next__range-stepper" aria-label="Decrease {label}" disabled="{disabled || readonly}" @click="decreaseValue(event)">−</button>
|
||||
<div class="wrn-next__range-track">
|
||||
<input id="{id || name}" class="wrn-next__sr-only wrn-next__range-value" type="number" name="{name}" value="{currentValue}" min="{min}" max="{max}" step="{step}" required="{required}" readonly />
|
||||
<div class="wrn-next__custom-slider" role="slider" tabindex="{disabled ? '-1' : '0'}" aria-label="{hiddenLabel ? label : ''}" aria-valuemin="{min}" aria-valuemax="{max}" aria-valuenow="{currentValue}" aria-disabled="{disabled}" aria-readonly="{readonly}" aria-invalid="{error ? 'true' : 'false'}" style="--wrn-range-progress: {percent()}%" @pointerdown="beginSlide(event)" @pointermove="moveSlide(event)" @pointerup="endSlide(event)" @pointercancel="endSlide(event)" @keydown="handleKey(event)" @focus="emitFocus('focus', event)" @blur="emitFocus('blur', event)">
|
||||
<span class="wrn-next__slider-fill"></span><span class="wrn-next__slider-thumb"></span>
|
||||
{#if marks.length}<span class="wrn-next__slider-marks">{#each marks as mark}<button type="button" data-value="{mark.value}" style="left: {(Number(mark.value) - Number(min)) / (Number(max) - Number(min)) * 100}%" aria-label="{mark.label}" @click="selectMark(event)"></button>{/each}</span>{/if}
|
||||
</div>
|
||||
{#if showBounds}<div class="wire-next__range-bounds"><span>{min}</span><span>Step {step}</span><span>{max}</span></div>{/if}
|
||||
{#if showBounds}<div class="wrn-next__range-bounds"><span>{min}</span><span>Step {step}</span><span>{max}</span></div>{/if}
|
||||
</div>
|
||||
{#if showValue}<output for="{id || name}">{currentValue}</output>{/if}
|
||||
<button type="button" class="wire-next__range-stepper" aria-label="Increase {label}" disabled="{disabled || readonly}" @click="increaseValue(event)">+</button>
|
||||
<button type="button" class="wrn-next__range-stepper" aria-label="Increase {label}" disabled="{disabled || readonly}" @click="increaseValue(event)">+</button>
|
||||
</div>
|
||||
{#if helperText}<small class="wire-next__field-help">{helperText}</small>{/if}<small class="wire-next__field-error" data-error="{name}">{error}</small>
|
||||
{#if helperText}<small class="wrn-next__field-help">{helperText}</small>{/if}<small class="wrn-next__field-error" data-error="{name}">{error}</small>
|
||||
</div>
|
||||
<FieldStyles hidden />
|
||||
<ComponentBaseStyles hidden />
|
||||
}
|
||||
|
||||
style {
|
||||
.wire-next__range-track {
|
||||
.wrn-next__range-track {
|
||||
display: grid;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
gap: 0.35rem;
|
||||
}
|
||||
|
||||
.wire-next__range-control input {
|
||||
.wrn-next__range-control input {
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
margin: 0;
|
||||
flex: 1;
|
||||
accent-color: var(--wire-field-color);
|
||||
accent-color: var(--wrn-field-color);
|
||||
}
|
||||
|
||||
.wire-next__custom-slider {
|
||||
.wrn-next__custom-slider {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 1.5rem;
|
||||
@@ -99,8 +93,8 @@ component RangeSlider {
|
||||
touch-action: none;
|
||||
}
|
||||
|
||||
.wire-next__custom-slider::before,
|
||||
.wire-next__slider-fill {
|
||||
.wrn-next__custom-slider::before,
|
||||
.wrn-next__slider-fill {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
height: 0.4rem;
|
||||
@@ -109,106 +103,665 @@ component RangeSlider {
|
||||
content: "";
|
||||
}
|
||||
|
||||
.wire-next__custom-slider::before {
|
||||
.wrn-next__custom-slider::before {
|
||||
right: 0;
|
||||
left: 0;
|
||||
background: var(--wire-color-surface-2);
|
||||
box-shadow: inset 0 0 0 1px var(--wire-color-border);
|
||||
background: var(--wrn-color-surface-2);
|
||||
box-shadow: inset 0 0 0 1px var(--wrn-color-border);
|
||||
}
|
||||
|
||||
.wire-next__slider-fill {
|
||||
.wrn-next__slider-fill {
|
||||
z-index: 1;
|
||||
left: 0;
|
||||
width: var(--wire-range-progress);
|
||||
background: var(--wire-field-color);
|
||||
width: var(--wrn-range-progress);
|
||||
background: var(--wrn-field-color);
|
||||
}
|
||||
|
||||
.wire-next__slider-thumb {
|
||||
.wrn-next__slider-thumb {
|
||||
position: absolute;
|
||||
z-index: 3;
|
||||
top: 50%;
|
||||
left: var(--wire-range-progress);
|
||||
left: var(--wrn-range-progress);
|
||||
width: 1.25rem;
|
||||
height: 1.25rem;
|
||||
border: 3px solid var(--wire-field-color);
|
||||
border: 3px solid var(--wrn-field-color);
|
||||
border-radius: 50%;
|
||||
background: var(--wire-color-surface);
|
||||
box-shadow: var(--wire-shadow-1);
|
||||
background: var(--wrn-color-surface);
|
||||
box-shadow: var(--wrn-shadow-1);
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
.wire-next__custom-slider:focus-visible {
|
||||
outline: 3px solid color-mix(in srgb, var(--wire-field-color) 28%, transparent);
|
||||
.wrn-next__custom-slider:focus-visible {
|
||||
outline: 3px solid color-mix(in srgb, var(--wrn-field-color) 28%, transparent);
|
||||
outline-offset: 3px;
|
||||
}
|
||||
|
||||
.wire-next__slider-marks button {
|
||||
.wrn-next__slider-marks button {
|
||||
position: absolute;
|
||||
z-index: 2;
|
||||
top: 50%;
|
||||
width: 0.55rem;
|
||||
height: 0.55rem;
|
||||
padding: 0;
|
||||
border: 2px solid var(--wire-color-surface);
|
||||
border: 2px solid var(--wrn-color-surface);
|
||||
border-radius: 50%;
|
||||
background: var(--wire-color-muted);
|
||||
background: var(--wrn-color-muted);
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
.wire-next__range-control[data-show-steps="true"] input {
|
||||
.wrn-next__range-control[data-show-steps="true"] input {
|
||||
background-image: repeating-linear-gradient(
|
||||
90deg,
|
||||
transparent 0,
|
||||
transparent calc(10% - 1px),
|
||||
var(--wire-color-border) calc(10% - 1px),
|
||||
var(--wire-color-border) 10%
|
||||
var(--wrn-color-border) calc(10% - 1px),
|
||||
var(--wrn-color-border) 10%
|
||||
);
|
||||
}
|
||||
|
||||
.wire-next__range-bounds {
|
||||
.wrn-next__range-bounds {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr auto 1fr;
|
||||
color: var(--wire-color-muted);
|
||||
color: var(--wrn-color-muted);
|
||||
font-size: 0.78em;
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
|
||||
.wire-next__range-bounds span:nth-child(2) {
|
||||
.wrn-next__range-bounds span:nth-child(2) {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.wire-next__range-bounds span:last-child {
|
||||
.wrn-next__range-bounds span:last-child {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.wire-next__range-control output {
|
||||
.wrn-next__range-control output {
|
||||
min-width: 3ch;
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
|
||||
.wire-next__range-stepper {
|
||||
.wrn-next__range-stepper {
|
||||
display: inline-grid;
|
||||
width: 2.35rem;
|
||||
height: 2.35rem;
|
||||
flex: 0 0 auto;
|
||||
place-items: center;
|
||||
border: 1px solid var(--wire-color-border);
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: 50%;
|
||||
background: var(--wire-color-surface);
|
||||
color: var(--wire-color-text);
|
||||
background: var(--wrn-color-surface);
|
||||
color: var(--wrn-color-text);
|
||||
font: inherit;
|
||||
font-size: 1.2rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.wire-next__range-stepper:hover:not(:disabled) {
|
||||
border-color: var(--wire-field-color);
|
||||
color: var(--wire-field-color);
|
||||
.wrn-next__range-stepper:hover:not(:disabled) {
|
||||
border-color: var(--wrn-field-color);
|
||||
color: var(--wrn-field-color);
|
||||
}
|
||||
|
||||
.wire-next__range-stepper:disabled {
|
||||
.wrn-next__range-stepper:disabled {
|
||||
cursor: not-allowed;
|
||||
opacity: 0.45;
|
||||
}
|
||||
|
||||
/* Shared component foundation. */
|
||||
|
||||
.wrn-component {
|
||||
--wrn-component-color: var(--wrn-color-primary);
|
||||
--wrn-component-scale: 1;
|
||||
margin: 0;
|
||||
color: var(--wrn-color-text);
|
||||
font-family: var(--wrn-font-sans, inherit);
|
||||
}
|
||||
|
||||
.wrn-component--color-primary {
|
||||
--wrn-component-color: var(--wrn-color-primary);
|
||||
}
|
||||
|
||||
.wrn-component--color-secondary {
|
||||
--wrn-component-color: var(--wrn-color-secondary);
|
||||
}
|
||||
|
||||
.wrn-component--color-success {
|
||||
--wrn-component-color: var(--wrn-color-success);
|
||||
}
|
||||
|
||||
.wrn-component--color-warning {
|
||||
--wrn-component-color: var(--wrn-color-warning);
|
||||
}
|
||||
|
||||
.wrn-component--color-danger {
|
||||
--wrn-component-color: var(--wrn-color-danger);
|
||||
}
|
||||
|
||||
.wrn-component--color-info {
|
||||
--wrn-component-color: var(--wrn-color-info);
|
||||
}
|
||||
|
||||
.wrn-component--size-xs {
|
||||
--wrn-component-scale: 0.78;
|
||||
}
|
||||
|
||||
.wrn-component--size-sm {
|
||||
--wrn-component-scale: 0.88;
|
||||
}
|
||||
|
||||
.wrn-component--size-default,
|
||||
.wrn-component--size-md {
|
||||
--wrn-component-scale: 1;
|
||||
}
|
||||
|
||||
.wrn-component--size-lg {
|
||||
--wrn-component-scale: 1.14;
|
||||
}
|
||||
|
||||
.wrn-component--size-xl {
|
||||
--wrn-component-scale: 1.28;
|
||||
}
|
||||
|
||||
.wrn-component:not(.wrn-btn) {
|
||||
font-size: calc(1em * var(--wrn-component-scale));
|
||||
}
|
||||
|
||||
.wrn-component :is(a, button, input, select, textarea):focus-visible {
|
||||
outline-color: var(--wrn-component-color);
|
||||
}
|
||||
|
||||
.wrn-component p {
|
||||
margin: 0;
|
||||
color: var(--wrn-color-muted);
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
/* Shared field foundation. */
|
||||
|
||||
/* Validation states set by the browser validation runtime. */
|
||||
.wrn-invalid {
|
||||
border-color: var(--wrn-color-danger) !important;
|
||||
}
|
||||
|
||||
.wrn-field-error {
|
||||
display: block;
|
||||
min-height: 1em;
|
||||
margin-top: 0.25rem;
|
||||
color: var(--wrn-color-danger);
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
.wrn-next--choice {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.55rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.wrn-next--choice input {
|
||||
width: 1.1rem;
|
||||
height: 1.1rem;
|
||||
accent-color: var(--wrn-color-primary);
|
||||
}
|
||||
|
||||
.wrn-next--field {
|
||||
display: grid;
|
||||
width: min(100%, 28rem);
|
||||
gap: 0.4rem;
|
||||
font-size: 0.78rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
.wrn-next--field :where(input, textarea, select) {
|
||||
width: 100%;
|
||||
min-height: 2.65rem;
|
||||
padding: 0.6rem 0.7rem;
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: 0.6rem;
|
||||
outline: 0;
|
||||
color: var(--wrn-color-text);
|
||||
background: var(--wrn-color-bg);
|
||||
font: inherit;
|
||||
font-weight: 500;
|
||||
}
|
||||
.wrn-auth-form form > .wrn-next--field,
|
||||
.wrn-auth-form form > .wrn-field {
|
||||
width: 100%;
|
||||
max-width: none;
|
||||
}
|
||||
.wrn-auth-form__submit > .wrn-btn {
|
||||
width: 100%;
|
||||
min-height: 3rem;
|
||||
border-radius: 0.75rem;
|
||||
box-shadow: 0 0.8rem 1.8rem color-mix(in srgb, var(--wrn-btn-color) 20%, transparent);
|
||||
}
|
||||
.wrn-next--field :where(input, textarea, select):focus-visible {
|
||||
border-color: var(--wrn-color-primary);
|
||||
box-shadow: 0 0 0 3px color-mix(in srgb, var(--wrn-color-primary) 16%, transparent);
|
||||
}
|
||||
.wrn-next--field textarea {
|
||||
resize: vertical;
|
||||
}
|
||||
.wrn-next--field,
|
||||
.wrn-next--choice-field {
|
||||
--wrn-field-color: var(--wrn-component-color, var(--wrn-color-primary));
|
||||
width: min(100%, 34rem);
|
||||
min-width: 0;
|
||||
color: var(--wrn-color-text);
|
||||
font-size: 0.8125rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
.wrn-next--field.wrn-next--size-sm,
|
||||
.wrn-next--choice-field.wrn-next--size-sm {
|
||||
font-size: 0.8125rem;
|
||||
}
|
||||
.wrn-next--field.wrn-next--size-lg,
|
||||
.wrn-next--choice-field.wrn-next--size-lg {
|
||||
font-size: 1rem;
|
||||
}
|
||||
.wrn-next__field-heading {
|
||||
display: flex;
|
||||
min-width: 0;
|
||||
align-items: baseline;
|
||||
justify-content: space-between;
|
||||
gap: 1rem;
|
||||
}
|
||||
.wrn-next__field-heading label {
|
||||
color: var(--wrn-color-text);
|
||||
font-weight: 600;
|
||||
}
|
||||
.wrn-next__field-hint,
|
||||
.wrn-next__field-help {
|
||||
color: var(--wrn-color-muted);
|
||||
font-size: 0.82em;
|
||||
font-weight: 500;
|
||||
}
|
||||
.wrn-next__field-control {
|
||||
position: relative;
|
||||
min-width: 0;
|
||||
}
|
||||
.wrn-next__field-control > :is(input, textarea, select) {
|
||||
padding-inline: 0.85rem;
|
||||
border-color: var(--wrn-color-border);
|
||||
border-radius: var(--wrn-radius-sm);
|
||||
background: var(--wrn-color-surface);
|
||||
font-size: 0.8125rem;
|
||||
}
|
||||
.wrn-next__field-control[data-icon-position="start"] > :is(input, textarea, select) {
|
||||
padding-inline-start: 2.5rem;
|
||||
}
|
||||
.wrn-next__field-control[data-icon-position="end"] > :is(input, textarea, select) {
|
||||
padding-inline-end: 2.5rem;
|
||||
}
|
||||
.wrn-next__field-icon {
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
top: 50%;
|
||||
left: 0.85rem;
|
||||
color: var(--wrn-color-muted);
|
||||
pointer-events: none;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
.wrn-next__field-control[data-icon-position="end"] > .wrn-next__field-icon {
|
||||
right: 0.85rem;
|
||||
left: auto;
|
||||
}
|
||||
.wrn-next--field[data-variant="outlined"]
|
||||
.wrn-next__field-control
|
||||
> :is(input, textarea, select) {
|
||||
border-width: 2px;
|
||||
}
|
||||
.wrn-next--field[data-variant="underline"]
|
||||
.wrn-next__field-control
|
||||
> :is(input, textarea, select) {
|
||||
padding-inline: 0;
|
||||
border-width: 0 0 1px;
|
||||
border-radius: 0;
|
||||
background: transparent;
|
||||
box-shadow: none;
|
||||
}
|
||||
.wrn-next--field[data-variant="pill"] .wrn-next__field-control > :is(input, select) {
|
||||
border-radius: 999px;
|
||||
padding-inline: 1.15rem;
|
||||
}
|
||||
.wrn-next--field[data-variant="ghost"] .wrn-next__field-control > :is(input, textarea, select) {
|
||||
border-color: transparent;
|
||||
background: color-mix(in srgb, var(--wrn-field-color) 8%, var(--wrn-color-surface));
|
||||
}
|
||||
.wrn-next__field-floating-label {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 0.85rem;
|
||||
color: var(--wrn-color-muted);
|
||||
pointer-events: none;
|
||||
transform: translateY(-50%);
|
||||
transition: 150ms ease;
|
||||
}
|
||||
.wrn-next--textarea .wrn-next__field-floating-label {
|
||||
top: 1.35rem;
|
||||
}
|
||||
.wrn-next--field[data-floating="true"] .wrn-next__field-control > :is(input, textarea, select) {
|
||||
padding-top: 1.2rem;
|
||||
padding-bottom: 0.3rem;
|
||||
}
|
||||
.wrn-next--field[data-floating="true"] .wrn-next__field-heading > label {
|
||||
position: absolute !important;
|
||||
width: 1px !important;
|
||||
height: 1px !important;
|
||||
overflow: hidden !important;
|
||||
margin: -1px !important;
|
||||
clip: rect(0, 0, 0, 0) !important;
|
||||
white-space: nowrap !important;
|
||||
}
|
||||
.wrn-next--field[data-floating="true"]
|
||||
.wrn-next__field-heading:not(:has(.wrn-next__field-hint)) {
|
||||
display: none;
|
||||
}
|
||||
.wrn-next--field[data-floating="true"]
|
||||
.wrn-next__field-control
|
||||
> :is(input, textarea):is(:focus, :not(:placeholder-shown))
|
||||
+ .wrn-next__field-floating-label {
|
||||
top: 0.42rem;
|
||||
font-size: 0.7em;
|
||||
transform: none;
|
||||
}
|
||||
.wrn-next__field-error {
|
||||
min-height: 1em;
|
||||
color: var(--wrn-color-danger);
|
||||
font-size: 0.82em;
|
||||
font-weight: 600;
|
||||
}
|
||||
.wrn-next__field-error:empty {
|
||||
display: none;
|
||||
}
|
||||
.wrn-next--field[data-invalid="true"] :is(input, textarea, select),
|
||||
.wrn-next--choice-field[data-invalid="true"] input {
|
||||
border-color: var(--wrn-color-danger);
|
||||
}
|
||||
.wrn-next--field :is(input, textarea, select):disabled,
|
||||
.wrn-next--choice-field input:disabled {
|
||||
cursor: not-allowed;
|
||||
opacity: 0.58;
|
||||
}
|
||||
.wrn-next--field :is(input, textarea, select):read-only {
|
||||
background: var(--wrn-color-surface-2);
|
||||
}
|
||||
.wrn-next--field[data-inline="true"],
|
||||
.wrn-next--choice-field[data-inline="true"] {
|
||||
display: grid;
|
||||
width: 100%;
|
||||
max-width: none;
|
||||
grid-template-columns: minmax(7rem, max-content) minmax(12rem, 20rem) minmax(10rem, 1fr);
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
.wrn-next--field[data-inline="true"] .wrn-next__field-heading,
|
||||
.wrn-next--choice-field[data-inline="true"] .wrn-next__field-heading {
|
||||
min-height: 2.65rem;
|
||||
align-items: center;
|
||||
}
|
||||
.wrn-next--field[data-inline="true"] .wrn-next__field-heading {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
.wrn-next--field[data-inline="true"] .wrn-next__field-help,
|
||||
.wrn-next--choice-field[data-inline="true"] .wrn-next__field-help {
|
||||
display: flex;
|
||||
min-height: 2.65rem;
|
||||
align-items: center;
|
||||
}
|
||||
.wrn-next--choice-field[data-inline="true"] {
|
||||
grid-template-columns: minmax(12rem, 20rem) minmax(10rem, 1fr);
|
||||
}
|
||||
.wrn-next--choice-field[data-inline="true"] .wrn-next__field-heading:empty {
|
||||
display: none;
|
||||
}
|
||||
.wrn-next--field[data-inline="true"] .wrn-next__field-error,
|
||||
.wrn-next--choice-field[data-inline="true"] .wrn-next__field-error {
|
||||
grid-column: 2 / -1;
|
||||
}
|
||||
.wrn-next__sr-only {
|
||||
position: absolute !important;
|
||||
width: 1px !important;
|
||||
height: 1px !important;
|
||||
overflow: hidden !important;
|
||||
padding: 0 !important;
|
||||
border: 0 !important;
|
||||
margin: -1px !important;
|
||||
clip: rect(0, 0, 0, 0) !important;
|
||||
white-space: nowrap !important;
|
||||
}
|
||||
.wrn-next__choice-field {
|
||||
display: grid;
|
||||
width: 100%;
|
||||
max-width: none;
|
||||
gap: 0.4rem;
|
||||
}
|
||||
.wrn-next__choice {
|
||||
display: flex;
|
||||
min-width: 0;
|
||||
align-items: center;
|
||||
gap: 0.65rem;
|
||||
color: var(--wrn-color-text);
|
||||
width: 100%;
|
||||
font-size: 0.75rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
.wrn-next__checkbox-content > .wrn-next__choice {
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
align-items: flex-start;
|
||||
}
|
||||
.wrn-next__choice input {
|
||||
flex: 0 0 auto;
|
||||
margin: 0;
|
||||
accent-color: var(--wrn-field-color);
|
||||
}
|
||||
.wrn-next__choice-copy {
|
||||
display: grid;
|
||||
min-width: 0;
|
||||
gap: 0.15rem;
|
||||
line-height: 1.35;
|
||||
}
|
||||
.wrn-next__choice-copy small {
|
||||
color: var(--wrn-color-muted);
|
||||
font-weight: 500;
|
||||
}
|
||||
.wrn-next__radio-group,
|
||||
.wrn-next__checkbox-group {
|
||||
display: grid;
|
||||
min-width: 0;
|
||||
gap: 0.65rem;
|
||||
}
|
||||
.wrn-next--radio-field[data-orientation="horizontal"] .wrn-next__radio-group,
|
||||
.wrn-next--checkbox-field[data-orientation="horizontal"] .wrn-next__checkbox-group {
|
||||
grid-template-columns: repeat(auto-fit, minmax(8rem, max-content));
|
||||
align-items: stretch;
|
||||
}
|
||||
.wrn-next--radio-field[data-card="true"] .wrn-next__radio-group,
|
||||
.wrn-next--checkbox-field[data-card="true"] .wrn-next__checkbox-group {
|
||||
grid-template-columns: repeat(auto-fit, minmax(min(100%, 12rem), 1fr));
|
||||
}
|
||||
.wrn-next--radio-field[data-card="true"] .wrn-next--radio,
|
||||
.wrn-next--checkbox-field[data-card="true"] .wrn-next--checkbox {
|
||||
min-height: 4.5rem;
|
||||
padding: 0.85rem;
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: var(--wrn-radius-sm);
|
||||
background: var(--wrn-color-surface);
|
||||
}
|
||||
.wrn-next--radio-field[data-card="true"] .wrn-next--radio:has(input:checked),
|
||||
.wrn-next--checkbox-field[data-card="true"] .wrn-next--checkbox:has(input:checked) {
|
||||
border-color: var(--wrn-field-color);
|
||||
box-shadow: 0 0 0 1px var(--wrn-field-color);
|
||||
}
|
||||
.wrn-next--radio-field[data-list="true"] .wrn-next--radio,
|
||||
.wrn-next--checkbox-field[data-list="true"] .wrn-next--checkbox {
|
||||
padding-block: 0.75rem;
|
||||
border-bottom: 1px solid var(--wrn-color-border);
|
||||
}
|
||||
.wrn-next--radio-field[data-right-aligned="true"] .wrn-next--radio,
|
||||
.wrn-next--checkbox-field[data-right-aligned="true"] .wrn-next--checkbox {
|
||||
justify-content: space-between;
|
||||
}
|
||||
.wrn-next--radio-field[data-right-aligned="true"] .wrn-next--radio input,
|
||||
.wrn-next--checkbox-field[data-right-aligned="true"] .wrn-next--checkbox input {
|
||||
order: 2;
|
||||
}
|
||||
.wrn-next--radio-field[data-right-aligned="true"] .wrn-next__choice-copy,
|
||||
.wrn-next--checkbox-field[data-right-aligned="true"] .wrn-next__choice-copy {
|
||||
order: 1;
|
||||
}
|
||||
.wrn-next__choice[data-variant="outlined"],
|
||||
.wrn-next__choice[data-variant="floating"] {
|
||||
padding: 0.65rem 0.8rem;
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: var(--wrn-radius-sm);
|
||||
}
|
||||
.wrn-next__choice[data-variant="pill"] {
|
||||
padding: 0.65rem 1rem;
|
||||
border-radius: 999px;
|
||||
background: color-mix(in srgb, var(--wrn-field-color) 9%, var(--wrn-color-surface));
|
||||
}
|
||||
.wrn-next__choice[data-variant="ghost"] {
|
||||
padding: 0.65rem 0.8rem;
|
||||
border-radius: var(--wrn-radius-sm);
|
||||
background: color-mix(in srgb, var(--wrn-field-color) 7%, transparent);
|
||||
}
|
||||
.wrn-next__choice[data-variant="underline"] {
|
||||
padding-block: 0.5rem;
|
||||
border-bottom: 1px solid var(--wrn-color-border);
|
||||
}
|
||||
.wrn-next--select .wrn-next__field-control {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.wrn-next__color-control,
|
||||
.wrn-next__range-control,
|
||||
.wrn-next__input-group-control,
|
||||
.wrn-next__file-control {
|
||||
display: flex;
|
||||
min-width: 0;
|
||||
align-items: center;
|
||||
gap: 0.65rem;
|
||||
}
|
||||
.wrn-next__picker-control,
|
||||
.wrn-next--time-picker .wrn-next__field-control {
|
||||
position: relative;
|
||||
display: flex;
|
||||
min-width: 0;
|
||||
align-items: center;
|
||||
}
|
||||
.wrn-next__picker-control > button:first-of-type,
|
||||
.wrn-next__time-trigger {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
min-height: 2.65rem;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 0.75rem;
|
||||
padding: 0.7rem 0.85rem;
|
||||
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;
|
||||
text-align: left;
|
||||
}
|
||||
.wrn-next__calendar,
|
||||
.wrn-next__time-panel {
|
||||
z-index: 20;
|
||||
display: grid;
|
||||
width: min(100%, 22rem);
|
||||
gap: 0.75rem;
|
||||
padding: 0.85rem;
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: var(--wrn-radius-md);
|
||||
background: var(--wrn-color-surface);
|
||||
box-shadow: var(--wrn-shadow-3);
|
||||
}
|
||||
.wrn-next--date-picker[data-expanded="false"] .wrn-next__calendar,
|
||||
.wrn-next--time-picker[data-expanded="false"] .wrn-next__time-panel {
|
||||
display: none;
|
||||
}
|
||||
.wrn-next__calendar button,
|
||||
.wrn-next__time-panel button {
|
||||
min-height: 2.25rem;
|
||||
border: 0;
|
||||
border-radius: var(--wrn-radius-sm);
|
||||
background: transparent;
|
||||
color: inherit;
|
||||
}
|
||||
.wrn-next__calendar-weekdays,
|
||||
.wrn-next__calendar-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(7, 1fr);
|
||||
gap: 0.2rem;
|
||||
text-align: center;
|
||||
}
|
||||
.wrn-next__calendar-weekdays {
|
||||
color: var(--wrn-color-muted);
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
.wrn-next__calendar-grid button:hover,
|
||||
.wrn-next__time-panel button:hover {
|
||||
background: var(--wrn-color-surface-2);
|
||||
}
|
||||
.wrn-next__calendar-grid button[aria-pressed="true"],
|
||||
.wrn-next__time-panel button[aria-pressed="true"] {
|
||||
background: var(--wrn-field-color);
|
||||
color: var(--wrn-color-primary-contrast, #fff);
|
||||
}
|
||||
.wrn-next__time-period {
|
||||
display: flex;
|
||||
gap: 0.35rem;
|
||||
}
|
||||
.wrn-next--file-upload-progress .wrn-next__row,
|
||||
.wrn-next__upload-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
.wrn-next--file-upload-progress .wrn-next__row > span {
|
||||
display: grid;
|
||||
min-width: 0;
|
||||
}
|
||||
.wrn-next--field[data-variant="underline"]
|
||||
:is(.wrn-next__input-group-control, .wrn-next__file-control, .wrn-next__color-control) {
|
||||
border-width: 0 0 1px;
|
||||
border-radius: 0;
|
||||
background: transparent;
|
||||
}
|
||||
.wrn-next--field[data-variant="outlined"]
|
||||
:is(.wrn-next__input-group-control, .wrn-next__file-control) {
|
||||
border-width: 2px;
|
||||
}
|
||||
.wrn-next--field[data-variant="pill"]
|
||||
:is(.wrn-next__input-group-control, .wrn-next__file-control) {
|
||||
border-radius: 999px;
|
||||
}
|
||||
.wrn-next--field[data-variant="ghost"]
|
||||
:is(.wrn-next__input-group-control, .wrn-next__file-control, .wrn-next__color-control) {
|
||||
border-color: transparent;
|
||||
background: color-mix(in srgb, var(--wrn-field-color) 8%, var(--wrn-color-surface));
|
||||
}
|
||||
@media (max-width: 640px) {
|
||||
.wrn-next--field[data-inline="true"],
|
||||
.wrn-next--choice-field[data-inline="true"] {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.wrn-next--field[data-inline="true"] .wrn-next__field-error,
|
||||
.wrn-next--choice-field[data-inline="true"] .wrn-next__field-error {
|
||||
grid-column: auto;
|
||||
}
|
||||
}
|
||||
.wrn-next--toggle-password:has(input.wrn-invalid) .wrn-next__password-control > input,
|
||||
.wrn-next--toggle-password.wrn-next--invalid .wrn-next__password-control > input {
|
||||
border-color: var(--wrn-color-danger);
|
||||
box-shadow: 0 0 0 3px color-mix(in srgb, var(--wrn-color-danger) 14%, transparent);
|
||||
}
|
||||
.wrn-next--strong-password.wrn-next--invalid input,
|
||||
.wrn-next--strong-password input.wrn-invalid {
|
||||
border-color: var(--wrn-color-danger);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import ComponentBaseStyles from "../styles/ComponentBaseStyles.wrn"
|
||||
|
||||
component Rating {
|
||||
outputs {
|
||||
input(payload: { value?: string | number | boolean | null; values?: Array<string | number | boolean | null | object>; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | string | number | boolean | null)
|
||||
@@ -16,27 +14,95 @@ component Rating {
|
||||
class: string = ""
|
||||
}
|
||||
view {
|
||||
<section class="wire-component wire-component--color-{color} wire-component--size-{size} wire-next--rating wire-next--variant-{variant} {class}">
|
||||
<section class="wrn-component wrn-component--color-{color} wrn-component--size-{size} wrn-next--rating wrn-next--variant-{variant} {class}">
|
||||
{#if title}<strong>{title}</strong>{/if}
|
||||
{#if description}<p>{description}</p>{/if}
|
||||
{#if items}<div class="wire-next__items">{#each items as item}<span>{item.label}</span>{/each}</div>{/if}
|
||||
{#if items}<div class="wrn-next__items">{#each items as item}<span>{item.label}</span>{/each}</div>{/if}
|
||||
<slot />
|
||||
</section>
|
||||
<ComponentBaseStyles hidden />
|
||||
}
|
||||
|
||||
style {
|
||||
.wire-next--rating {
|
||||
.wrn-next--rating {
|
||||
display: grid;
|
||||
gap: 0.75rem;
|
||||
padding: 1rem;
|
||||
border: 1px solid var(--wire-color-border);
|
||||
border-radius: var(--wire-radius);
|
||||
color: var(--wire-color-text);
|
||||
background: var(--wire-color-surface);
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: var(--wrn-radius);
|
||||
color: var(--wrn-color-text);
|
||||
background: var(--wrn-color-surface);
|
||||
}
|
||||
.wire-next--rating > p { margin: 0; color: var(--wire-color-muted); }
|
||||
.wire-next--rating > .wire-next__items { display: flex; flex-wrap: wrap; gap: 0.5rem; }
|
||||
.wire-next--rating > .wire-next__items > span { padding: 0.35rem 0.6rem; border-radius: var(--wire-radius-sm); background: var(--wire-color-surface-2); }
|
||||
.wrn-next--rating > p { margin: 0; color: var(--wrn-color-muted); }
|
||||
.wrn-next--rating > .wrn-next__items { display: flex; flex-wrap: wrap; gap: 0.5rem; }
|
||||
.wrn-next--rating > .wrn-next__items > span { padding: 0.35rem 0.6rem; border-radius: var(--wrn-radius-sm); background: var(--wrn-color-surface-2); }
|
||||
|
||||
/* Shared component foundation. */
|
||||
|
||||
.wrn-component {
|
||||
--wrn-component-color: var(--wrn-color-primary);
|
||||
--wrn-component-scale: 1;
|
||||
margin: 0;
|
||||
color: var(--wrn-color-text);
|
||||
font-family: var(--wrn-font-sans, inherit);
|
||||
}
|
||||
|
||||
.wrn-component--color-primary {
|
||||
--wrn-component-color: var(--wrn-color-primary);
|
||||
}
|
||||
|
||||
.wrn-component--color-secondary {
|
||||
--wrn-component-color: var(--wrn-color-secondary);
|
||||
}
|
||||
|
||||
.wrn-component--color-success {
|
||||
--wrn-component-color: var(--wrn-color-success);
|
||||
}
|
||||
|
||||
.wrn-component--color-warning {
|
||||
--wrn-component-color: var(--wrn-color-warning);
|
||||
}
|
||||
|
||||
.wrn-component--color-danger {
|
||||
--wrn-component-color: var(--wrn-color-danger);
|
||||
}
|
||||
|
||||
.wrn-component--color-info {
|
||||
--wrn-component-color: var(--wrn-color-info);
|
||||
}
|
||||
|
||||
.wrn-component--size-xs {
|
||||
--wrn-component-scale: 0.78;
|
||||
}
|
||||
|
||||
.wrn-component--size-sm {
|
||||
--wrn-component-scale: 0.88;
|
||||
}
|
||||
|
||||
.wrn-component--size-default,
|
||||
.wrn-component--size-md {
|
||||
--wrn-component-scale: 1;
|
||||
}
|
||||
|
||||
.wrn-component--size-lg {
|
||||
--wrn-component-scale: 1.14;
|
||||
}
|
||||
|
||||
.wrn-component--size-xl {
|
||||
--wrn-component-scale: 1.28;
|
||||
}
|
||||
|
||||
.wrn-component:not(.wrn-btn) {
|
||||
font-size: calc(1em * var(--wrn-component-scale));
|
||||
}
|
||||
|
||||
.wrn-component :is(a, button, input, select, textarea):focus-visible {
|
||||
outline-color: var(--wrn-component-color);
|
||||
}
|
||||
|
||||
.wrn-component p {
|
||||
margin: 0;
|
||||
color: var(--wrn-color-muted);
|
||||
line-height: 1.6;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,25 +41,25 @@ component Scrollspy {
|
||||
<nav
|
||||
{...attrs}
|
||||
data-ui-component="Scrollspy"
|
||||
class='wire-scrollspy {class}'
|
||||
class='wrn-scrollspy {class}'
|
||||
data-color='{color}'
|
||||
data-size='{size}'
|
||||
data-wrn-scrollspy="true"
|
||||
role="navigation"
|
||||
aria-label='{label}'
|
||||
>
|
||||
<p class="wire-scrollspy__heading" data-show="heading">{heading}</p>
|
||||
<p class="wrn-scrollspy__heading" data-show="heading">{heading}</p>
|
||||
|
||||
<ul class="wire-scrollspy__list">
|
||||
<ul class="wrn-scrollspy__list">
|
||||
{#each itemList() as item}
|
||||
<li class="wire-scrollspy__item">
|
||||
<li class="wrn-scrollspy__item">
|
||||
<a
|
||||
class="wire-scrollspy__link"
|
||||
class="wrn-scrollspy__link"
|
||||
href='{item.href || "#"}'
|
||||
data-active='{isActive(item)}'
|
||||
aria-current='{isActive(item) ? "location" : "false"}'
|
||||
>
|
||||
<span class="wire-scrollspy__label">{item.label}</span>
|
||||
<span class="wrn-scrollspy__label">{item.label}</span>
|
||||
</a>
|
||||
</li>
|
||||
{/each}
|
||||
@@ -70,73 +70,73 @@ component Scrollspy {
|
||||
}
|
||||
|
||||
style {
|
||||
.wire-scrollspy {
|
||||
--scrollspy-accent: var(--wire-color-primary);
|
||||
.wrn-scrollspy {
|
||||
--scrollspy-accent: var(--wrn-color-primary);
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.wire-scrollspy[data-color="secondary"] {
|
||||
--scrollspy-accent: var(--wire-color-secondary);
|
||||
.wrn-scrollspy[data-color="secondary"] {
|
||||
--scrollspy-accent: var(--wrn-color-secondary);
|
||||
}
|
||||
|
||||
.wire-scrollspy[data-color="success"] {
|
||||
--scrollspy-accent: var(--wire-color-success);
|
||||
.wrn-scrollspy[data-color="success"] {
|
||||
--scrollspy-accent: var(--wrn-color-success);
|
||||
}
|
||||
|
||||
.wire-scrollspy[data-color="danger"] {
|
||||
--scrollspy-accent: var(--wire-color-danger);
|
||||
.wrn-scrollspy[data-color="danger"] {
|
||||
--scrollspy-accent: var(--wrn-color-danger);
|
||||
}
|
||||
|
||||
.wire-scrollspy[data-color="info"] {
|
||||
--scrollspy-accent: var(--wire-color-info);
|
||||
.wrn-scrollspy[data-color="info"] {
|
||||
--scrollspy-accent: var(--wrn-color-info);
|
||||
}
|
||||
|
||||
.wire-scrollspy[data-size="sm"] {
|
||||
.wrn-scrollspy[data-size="sm"] {
|
||||
font-size: 0.82rem;
|
||||
}
|
||||
|
||||
.wire-scrollspy[data-size="lg"] {
|
||||
.wrn-scrollspy[data-size="lg"] {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.wire-scrollspy__heading {
|
||||
.wrn-scrollspy__heading {
|
||||
margin: 0 0 0.5rem;
|
||||
color: var(--wire-color-text-muted);
|
||||
color: var(--wrn-color-text-muted);
|
||||
font-size: 0.72rem;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.08em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.wire-scrollspy__list {
|
||||
.wrn-scrollspy__list {
|
||||
display: grid;
|
||||
gap: 0.1rem;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
border-left: 1px solid var(--wire-color-border);
|
||||
border-left: 1px solid var(--wrn-color-border);
|
||||
}
|
||||
|
||||
.wire-scrollspy__link {
|
||||
.wrn-scrollspy__link {
|
||||
display: block;
|
||||
padding: 0.3rem 0.75rem;
|
||||
margin-left: -1px;
|
||||
border-left: 2px solid transparent;
|
||||
color: var(--wire-color-text-muted);
|
||||
color: var(--wrn-color-text-muted);
|
||||
font-size: 0.85rem;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.wire-scrollspy__link:hover {
|
||||
color: var(--wire-color-text);
|
||||
.wrn-scrollspy__link:hover {
|
||||
color: var(--wrn-color-text);
|
||||
}
|
||||
|
||||
.wire-scrollspy__link:focus-visible {
|
||||
.wrn-scrollspy__link:focus-visible {
|
||||
outline: 2px solid var(--scrollspy-accent);
|
||||
outline-offset: -2px;
|
||||
}
|
||||
|
||||
.wire-scrollspy__link[data-active="true"] {
|
||||
.wrn-scrollspy__link[data-active="true"] {
|
||||
border-left-color: var(--scrollspy-accent);
|
||||
color: var(--scrollspy-accent);
|
||||
font-weight: 600;
|
||||
@@ -148,22 +148,22 @@ component Scrollspy {
|
||||
* line rather than a screenful.
|
||||
*/
|
||||
@media (max-width: 767px) {
|
||||
.wire-scrollspy__list {
|
||||
.wrn-scrollspy__list {
|
||||
grid-auto-flow: column;
|
||||
grid-auto-columns: max-content;
|
||||
overflow-x: auto;
|
||||
border-left: 0;
|
||||
border-bottom: 1px solid var(--wire-color-border);
|
||||
border-bottom: 1px solid var(--wrn-color-border);
|
||||
}
|
||||
|
||||
.wire-scrollspy__link {
|
||||
.wrn-scrollspy__link {
|
||||
margin-left: 0;
|
||||
border-left: 0;
|
||||
border-bottom: 2px solid transparent;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.wire-scrollspy__link[data-active="true"] {
|
||||
.wrn-scrollspy__link[data-active="true"] {
|
||||
border-left-color: transparent;
|
||||
border-bottom-color: var(--scrollspy-accent);
|
||||
}
|
||||
|
||||
@@ -26,19 +26,19 @@ component SearchBox {
|
||||
<form
|
||||
data-ui-component="SearchBox"
|
||||
role="search"
|
||||
class='wire-search-box {class}'
|
||||
class='wrn-search-box {class}'
|
||||
@submit='event.preventDefault(); output.search({ value: query, name: name })'
|
||||
>
|
||||
<label
|
||||
class="wire-search-box__label"
|
||||
class="wrn-search-box__label"
|
||||
data-hidden='{label === "" ? "true" : "false"}'
|
||||
>
|
||||
{label}
|
||||
</label>
|
||||
|
||||
<div class="wire-search-box__control">
|
||||
<div class="wrn-search-box__control">
|
||||
<span
|
||||
class="icon-[lucide--search] wire-search-box__search-icon"
|
||||
class="icon-[lucide--search] wrn-search-box__search-icon"
|
||||
aria-hidden="true"
|
||||
></span>
|
||||
|
||||
@@ -53,7 +53,7 @@ component SearchBox {
|
||||
disabled='{disabled}'
|
||||
required='{required}'
|
||||
autocomplete="off"
|
||||
class="wire-search-box__input"
|
||||
class="wrn-search-box__input"
|
||||
data-size='{size}'
|
||||
@input='query = event.target.value'
|
||||
@change='query = event.target.value'
|
||||
@@ -63,34 +63,34 @@ component SearchBox {
|
||||
type="button"
|
||||
aria-label="Clear search"
|
||||
data-show='query.length > 0 && !disabled'
|
||||
class="wire-search-box__button wire-search-box__clear"
|
||||
class="wrn-search-box__button wrn-search-box__clear"
|
||||
@click='query = ""; event.currentTarget.parentElement.querySelector("input")?.focus(); output.clear({ value: "", name: name })'
|
||||
>
|
||||
<span class="icon-[lucide--x] wire-search-box__button-icon" aria-hidden="true"></span>
|
||||
<span class="icon-[lucide--x] wrn-search-box__button-icon" aria-hidden="true"></span>
|
||||
</button>
|
||||
|
||||
<button
|
||||
type="submit"
|
||||
aria-label='{label || "Search"}'
|
||||
disabled='{disabled}'
|
||||
class="wire-search-box__button wire-search-box__submit"
|
||||
class="wrn-search-box__button wrn-search-box__submit"
|
||||
>
|
||||
<span class="icon-[lucide--arrow-right] wire-search-box__button-icon" aria-hidden="true"></span>
|
||||
<span class="icon-[lucide--arrow-right] wrn-search-box__button-icon" aria-hidden="true"></span>
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
}
|
||||
|
||||
style {
|
||||
.wire-search-box { width: 100%; }
|
||||
.wire-search-box__label {
|
||||
.wrn-search-box { width: 100%; }
|
||||
.wrn-search-box__label {
|
||||
display: block;
|
||||
margin-bottom: 0.5rem;
|
||||
color: var(--wire-color-text);
|
||||
color: var(--wrn-color-text);
|
||||
font-size: 0.875rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
.wire-search-box__label[data-hidden="true"] {
|
||||
.wrn-search-box__label[data-hidden="true"] {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
@@ -101,50 +101,50 @@ component SearchBox {
|
||||
white-space: nowrap;
|
||||
border: 0;
|
||||
}
|
||||
.wire-search-box__control { position: relative; display: flex; align-items: center; }
|
||||
.wire-search-box__search-icon {
|
||||
.wrn-search-box__control { position: relative; display: flex; align-items: center; }
|
||||
.wrn-search-box__search-icon {
|
||||
position: absolute;
|
||||
left: 1rem;
|
||||
width: 1.25rem;
|
||||
height: 1.25rem;
|
||||
color: var(--wire-color-input-placeholder);
|
||||
color: var(--wrn-color-input-placeholder);
|
||||
pointer-events: none;
|
||||
}
|
||||
.wire-search-box__input {
|
||||
.wrn-search-box__input {
|
||||
width: 100%;
|
||||
height: 3rem;
|
||||
padding: 0 6rem 0 3rem;
|
||||
border: 1px solid var(--wire-color-input-border);
|
||||
border-radius: var(--wire-radius);
|
||||
border: 1px solid var(--wrn-color-input-border);
|
||||
border-radius: var(--wrn-radius);
|
||||
outline: none;
|
||||
color: var(--wire-color-input-text);
|
||||
background: var(--wire-color-input-background);
|
||||
transition: border-color var(--wire-motion-base) var(--wire-ease-standard), box-shadow var(--wire-motion-base) var(--wire-ease-standard);
|
||||
color: var(--wrn-color-input-text);
|
||||
background: var(--wrn-color-input-background);
|
||||
transition: border-color var(--wrn-motion-base) var(--wrn-ease-standard), box-shadow var(--wrn-motion-base) var(--wrn-ease-standard);
|
||||
}
|
||||
.wire-search-box__input[data-size="sm"] { height: 2.5rem; }
|
||||
.wire-search-box__input[data-size="lg"] { height: 3.5rem; }
|
||||
.wire-search-box__input::placeholder { color: var(--wire-color-input-placeholder); }
|
||||
.wire-search-box__input:hover { border-color: var(--wire-color-input-border-hover); }
|
||||
.wire-search-box__input:focus {
|
||||
border-color: var(--wire-color-input-border-focus);
|
||||
box-shadow: 0 0 0 2px var(--wire-color-focus);
|
||||
.wrn-search-box__input[data-size="sm"] { height: 2.5rem; }
|
||||
.wrn-search-box__input[data-size="lg"] { height: 3.5rem; }
|
||||
.wrn-search-box__input::placeholder { color: var(--wrn-color-input-placeholder); }
|
||||
.wrn-search-box__input:hover { border-color: var(--wrn-color-input-border-hover); }
|
||||
.wrn-search-box__input:focus {
|
||||
border-color: var(--wrn-color-input-border-focus);
|
||||
box-shadow: 0 0 0 2px var(--wrn-color-focus);
|
||||
}
|
||||
.wire-search-box__input:disabled, .wire-search-box__button:disabled { cursor: not-allowed; opacity: 0.6; }
|
||||
.wire-search-box__button {
|
||||
.wrn-search-box__input:disabled, .wrn-search-box__button:disabled { cursor: not-allowed; opacity: 0.6; }
|
||||
.wrn-search-box__button {
|
||||
position: absolute;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
border-radius: var(--wire-radius-sm);
|
||||
transition: color var(--wire-motion-base), background var(--wire-motion-base);
|
||||
border-radius: var(--wrn-radius-sm);
|
||||
transition: color var(--wrn-motion-base), background var(--wrn-motion-base);
|
||||
}
|
||||
.wire-search-box__clear { right: 3rem; width: 2rem; height: 2rem; color: var(--wire-color-text-muted); background: transparent; }
|
||||
.wire-search-box__clear:hover { color: var(--wire-color-text); background: var(--wire-color-surface-soft); }
|
||||
.wire-search-box__submit { right: 0.5rem; width: 2.25rem; height: 2.25rem; color: var(--wire-color-on-primary); background: var(--wire-color-primary); }
|
||||
.wire-search-box__submit:hover { background: var(--wire-color-primary-hover); }
|
||||
.wire-search-box__button:focus-visible { outline: 2px solid var(--wire-color-focus); outline-offset: 2px; }
|
||||
.wire-search-box__button-icon { width: 1rem; height: 1rem; }
|
||||
.wrn-search-box__clear { right: 3rem; width: 2rem; height: 2rem; color: var(--wrn-color-text-muted); background: transparent; }
|
||||
.wrn-search-box__clear:hover { color: var(--wrn-color-text); background: var(--wrn-color-surface-soft); }
|
||||
.wrn-search-box__submit { right: 0.5rem; width: 2.25rem; height: 2.25rem; color: var(--wrn-color-on-primary); background: var(--wrn-color-primary); }
|
||||
.wrn-search-box__submit:hover { background: var(--wrn-color-primary-hover); }
|
||||
.wrn-search-box__button:focus-visible { outline: 2px solid var(--wrn-color-focus); outline-offset: 2px; }
|
||||
.wrn-search-box__button-icon { width: 1rem; height: 1rem; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,29 +88,29 @@ component Sidebar {
|
||||
<div
|
||||
{...attrs}
|
||||
data-ui-component="Sidebar"
|
||||
class='wire-sidebar {class}'
|
||||
class='wrn-sidebar {class}'
|
||||
data-color='{color}'
|
||||
data-size='{size}'
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
class="wire-sidebar__launcher"
|
||||
class="wrn-sidebar__launcher"
|
||||
aria-label='{mobileLabel}'
|
||||
aria-expanded='{drawerOpen}'
|
||||
@click='openDrawer(event)'
|
||||
>
|
||||
<span class="wire-sidebar__launcher-bar" aria-hidden="true"></span>
|
||||
<span class="wire-sidebar__launcher-text">{mobileLabel}</span>
|
||||
<span class="wrn-sidebar__launcher-bar" aria-hidden="true"></span>
|
||||
<span class="wrn-sidebar__launcher-text">{mobileLabel}</span>
|
||||
</button>
|
||||
|
||||
<nav class="wire-sidebar__rail" aria-label='{label}'>
|
||||
<ul class="wire-sidebar__list" data-wrn-roving="vertical">
|
||||
<nav class="wrn-sidebar__rail" aria-label='{label}'>
|
||||
<ul class="wrn-sidebar__list" data-wrn-roving="vertical">
|
||||
{#each entryList() as entry}
|
||||
<li class="wire-sidebar__entry" data-group='{isGroup(entry)}'>
|
||||
<p class="wire-sidebar__heading" data-show="entry.heading">{entry.heading}</p>
|
||||
<li class="wrn-sidebar__entry" data-group='{isGroup(entry)}'>
|
||||
<p class="wrn-sidebar__heading" data-show="entry.heading">{entry.heading}</p>
|
||||
|
||||
<a
|
||||
class="wire-sidebar__link"
|
||||
class="wrn-sidebar__link"
|
||||
data-show="!entry.heading"
|
||||
href='{entry.href || "#"}'
|
||||
data-wrn-roving-item="true"
|
||||
@@ -120,19 +120,19 @@ component Sidebar {
|
||||
@click='choose(entry, 1)'
|
||||
>
|
||||
<span
|
||||
class='wire-sidebar__icon {entry.icon}'
|
||||
class='wrn-sidebar__icon {entry.icon}'
|
||||
data-show="entry.icon"
|
||||
aria-hidden="true"
|
||||
></span>
|
||||
<span class="wire-sidebar__label">{entry.label}</span>
|
||||
<span class="wire-sidebar__badge" data-show="entry.badge">{entry.badge}</span>
|
||||
<span class="wrn-sidebar__label">{entry.label}</span>
|
||||
<span class="wrn-sidebar__badge" data-show="entry.badge">{entry.badge}</span>
|
||||
</a>
|
||||
|
||||
<ul class="wire-sidebar__sublist" data-show="childrenOf(entry).length > 0">
|
||||
<ul class="wrn-sidebar__sublist" data-show="childrenOf(entry).length > 0">
|
||||
{#each childrenOf(entry) as child}
|
||||
<li class="wire-sidebar__entry">
|
||||
<li class="wrn-sidebar__entry">
|
||||
<a
|
||||
class="wire-sidebar__link"
|
||||
class="wrn-sidebar__link"
|
||||
href='{child.href || "#"}'
|
||||
data-active='{isActive(child)}'
|
||||
aria-current='{isActive(child) ? "page" : "false"}'
|
||||
@@ -140,28 +140,28 @@ component Sidebar {
|
||||
@click='choose(child, 2)'
|
||||
>
|
||||
<span
|
||||
class='wire-sidebar__icon {child.icon}'
|
||||
class='wrn-sidebar__icon {child.icon}'
|
||||
data-show="child.icon"
|
||||
aria-hidden="true"
|
||||
></span>
|
||||
<span class="wire-sidebar__label">{child.label}</span>
|
||||
<span class="wire-sidebar__badge" data-show="child.badge">{child.badge}</span>
|
||||
<span class="wrn-sidebar__label">{child.label}</span>
|
||||
<span class="wrn-sidebar__badge" data-show="child.badge">{child.badge}</span>
|
||||
</a>
|
||||
|
||||
<ul
|
||||
class="wire-sidebar__sublist wire-sidebar__sublist--level3"
|
||||
class="wrn-sidebar__sublist wrn-sidebar__sublist--level3"
|
||||
data-show="childrenOf(child).length > 0"
|
||||
>
|
||||
{#each childrenOf(child) as leaf}
|
||||
<li class="wire-sidebar__entry">
|
||||
<li class="wrn-sidebar__entry">
|
||||
<a
|
||||
class="wire-sidebar__link"
|
||||
class="wrn-sidebar__link"
|
||||
href='{leaf.href || "#"}'
|
||||
data-active='{isActive(leaf)}'
|
||||
aria-current='{isActive(leaf) ? "page" : "false"}'
|
||||
@click='choose(leaf, 3)'
|
||||
>
|
||||
<span class="wire-sidebar__label">{leaf.label}</span>
|
||||
<span class="wrn-sidebar__label">{leaf.label}</span>
|
||||
</a>
|
||||
</li>
|
||||
{/each}
|
||||
@@ -188,41 +188,41 @@ component Sidebar {
|
||||
}
|
||||
|
||||
style {
|
||||
.wire-sidebar {
|
||||
--sidebar-accent: var(--wire-color-primary);
|
||||
.wrn-sidebar {
|
||||
--sidebar-accent: var(--wrn-color-primary);
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.wire-sidebar[data-color="secondary"] {
|
||||
--sidebar-accent: var(--wire-color-secondary);
|
||||
.wrn-sidebar[data-color="secondary"] {
|
||||
--sidebar-accent: var(--wrn-color-secondary);
|
||||
}
|
||||
|
||||
.wire-sidebar[data-color="success"] {
|
||||
--sidebar-accent: var(--wire-color-success);
|
||||
.wrn-sidebar[data-color="success"] {
|
||||
--sidebar-accent: var(--wrn-color-success);
|
||||
}
|
||||
|
||||
.wire-sidebar[data-color="danger"] {
|
||||
--sidebar-accent: var(--wire-color-danger);
|
||||
.wrn-sidebar[data-color="danger"] {
|
||||
--sidebar-accent: var(--wrn-color-danger);
|
||||
}
|
||||
|
||||
.wire-sidebar[data-color="info"] {
|
||||
--sidebar-accent: var(--wire-color-info);
|
||||
.wrn-sidebar[data-color="info"] {
|
||||
--sidebar-accent: var(--wrn-color-info);
|
||||
}
|
||||
|
||||
.wire-sidebar[data-size="sm"] {
|
||||
.wrn-sidebar[data-size="sm"] {
|
||||
font-size: 0.82rem;
|
||||
}
|
||||
|
||||
.wire-sidebar[data-size="lg"] {
|
||||
.wrn-sidebar[data-size="lg"] {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.wire-sidebar__rail {
|
||||
.wrn-sidebar__rail {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.wire-sidebar__list,
|
||||
.wire-sidebar__sublist {
|
||||
.wrn-sidebar__list,
|
||||
.wrn-sidebar__sublist {
|
||||
display: grid;
|
||||
gap: 0.1rem;
|
||||
margin: 0;
|
||||
@@ -230,62 +230,62 @@ component Sidebar {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.wire-sidebar__sublist {
|
||||
.wrn-sidebar__sublist {
|
||||
margin-left: 0.85rem;
|
||||
padding-left: 0.5rem;
|
||||
border-left: 1px solid var(--wire-color-border);
|
||||
border-left: 1px solid var(--wrn-color-border);
|
||||
}
|
||||
|
||||
.wire-sidebar__entry[data-group="true"] + .wire-sidebar__entry {
|
||||
.wrn-sidebar__entry[data-group="true"] + .wrn-sidebar__entry {
|
||||
margin-top: 0.35rem;
|
||||
}
|
||||
|
||||
.wire-sidebar__heading {
|
||||
.wrn-sidebar__heading {
|
||||
margin: 0.9rem 0 0.35rem;
|
||||
color: var(--wire-color-text-muted);
|
||||
color: var(--wrn-color-text-muted);
|
||||
font-size: 0.7rem;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.08em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.wire-sidebar__link {
|
||||
.wrn-sidebar__link {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
padding: 0.45rem 0.6rem;
|
||||
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.88rem;
|
||||
font-weight: 600;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.wire-sidebar__link:hover {
|
||||
background: var(--wire-color-surface-soft);
|
||||
color: var(--wire-color-text);
|
||||
.wrn-sidebar__link:hover {
|
||||
background: var(--wrn-color-surface-soft);
|
||||
color: var(--wrn-color-text);
|
||||
}
|
||||
|
||||
.wire-sidebar__link:focus-visible {
|
||||
.wrn-sidebar__link:focus-visible {
|
||||
outline: 2px solid var(--sidebar-accent);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
.wire-sidebar__link[data-active="true"] {
|
||||
.wrn-sidebar__link[data-active="true"] {
|
||||
background: color-mix(in srgb, var(--sidebar-accent) 16%, transparent);
|
||||
color: var(--sidebar-accent);
|
||||
}
|
||||
|
||||
.wire-sidebar__link[aria-disabled="true"] {
|
||||
.wrn-sidebar__link[aria-disabled="true"] {
|
||||
opacity: 0.5;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.wire-sidebar__label {
|
||||
.wrn-sidebar__label {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.wire-sidebar__badge {
|
||||
.wrn-sidebar__badge {
|
||||
margin-left: auto;
|
||||
padding: 0.05rem 0.4rem;
|
||||
border-radius: 999px;
|
||||
@@ -294,21 +294,21 @@ component Sidebar {
|
||||
font-size: 0.72rem;
|
||||
}
|
||||
|
||||
.wire-sidebar__launcher {
|
||||
.wrn-sidebar__launcher {
|
||||
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-sidebar__launcher-bar {
|
||||
.wrn-sidebar__launcher-bar {
|
||||
width: 1rem;
|
||||
height: 2px;
|
||||
background: currentColor;
|
||||
@@ -323,11 +323,11 @@ component Sidebar {
|
||||
* the focus trap and the scroll lock.
|
||||
*/
|
||||
@media (max-width: 767px) {
|
||||
.wire-sidebar__launcher {
|
||||
.wrn-sidebar__launcher {
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
.wire-sidebar__rail {
|
||||
.wrn-sidebar__rail {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,74 +134,74 @@ component Stepper {
|
||||
<div
|
||||
{...attrs}
|
||||
data-ui-component="Stepper"
|
||||
class='wire-stepper {class}'
|
||||
class='wrn-stepper {class}'
|
||||
data-orientation='{orientation}'
|
||||
data-color='{color}'
|
||||
data-size='{size}'
|
||||
data-clickable='{clickable}'
|
||||
>
|
||||
<ol
|
||||
class="wire-stepper__list"
|
||||
class="wrn-stepper__list"
|
||||
data-wrn-roving='{rovingAxis()}'
|
||||
aria-label='{label}'
|
||||
>
|
||||
{#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 ? "true" : "false"}'
|
||||
@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>
|
||||
{/each}
|
||||
</ol>
|
||||
|
||||
<div class="wire-stepper__panels" data-show="showPanel">
|
||||
<div class="wrn-stepper__panels" data-show="showPanel">
|
||||
{#each stepList() as step, index}
|
||||
<div
|
||||
class="wire-stepper__panel"
|
||||
class="wrn-stepper__panel"
|
||||
data-show='isActiveStep(index)'
|
||||
aria-hidden='{index === activeIndex() ? "false" : "true"}'
|
||||
>
|
||||
<h4 class="wire-stepper__panel-title" data-show="step.title">{step.title}</h4>
|
||||
<p class="wire-stepper__panel-body" data-show="step.content">{step.content}</p>
|
||||
<h4 class="wrn-stepper__panel-title" data-show="step.title">{step.title}</h4>
|
||||
<p class="wrn-stepper__panel-body" data-show="step.content">{step.content}</p>
|
||||
<slot name="panel-{index}"></slot>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
<div class="wire-stepper__controls" data-show="controls">
|
||||
<div class="wrn-stepper__controls" data-show="controls">
|
||||
<button
|
||||
type="button"
|
||||
class="wire-stepper__button-control wire-stepper__back"
|
||||
class="wrn-stepper__button-control wrn-stepper__back"
|
||||
disabled='{activeIndex() === 0}'
|
||||
@click='goBack()'
|
||||
>
|
||||
{backLabel}
|
||||
</button>
|
||||
<span class="wire-stepper__controls-spacer"></span>
|
||||
<span class="wrn-stepper__controls-spacer"></span>
|
||||
<button
|
||||
type="button"
|
||||
class="wire-stepper__button-control wire-stepper__skip"
|
||||
class="wrn-stepper__button-control wrn-stepper__skip"
|
||||
data-show="allowSkip && !onLastStep()"
|
||||
@click='goSkip()'
|
||||
>
|
||||
@@ -209,7 +209,7 @@ component Stepper {
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="wire-stepper__button-control wire-stepper__next"
|
||||
class="wrn-stepper__button-control wrn-stepper__next"
|
||||
data-primary="true"
|
||||
disabled='{nextDisabled}'
|
||||
@click='goNext()'
|
||||
@@ -223,12 +223,12 @@ component Stepper {
|
||||
}
|
||||
|
||||
style {
|
||||
.wire-stepper {
|
||||
--stepper-accent: var(--wire-color-primary);
|
||||
.wrn-stepper {
|
||||
--stepper-accent: var(--wrn-color-primary);
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.wire-stepper__list {
|
||||
.wrn-stepper__list {
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
margin: 0;
|
||||
@@ -237,35 +237,35 @@ component Stepper {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.wire-stepper[data-color="secondary"] {
|
||||
--stepper-accent: var(--wire-color-secondary);
|
||||
.wrn-stepper[data-color="secondary"] {
|
||||
--stepper-accent: var(--wrn-color-secondary);
|
||||
}
|
||||
|
||||
.wire-stepper[data-color="success"] {
|
||||
--stepper-accent: var(--wire-color-success);
|
||||
.wrn-stepper[data-color="success"] {
|
||||
--stepper-accent: var(--wrn-color-success);
|
||||
}
|
||||
|
||||
.wire-stepper[data-color="danger"] {
|
||||
--stepper-accent: var(--wire-color-danger);
|
||||
.wrn-stepper[data-color="danger"] {
|
||||
--stepper-accent: var(--wrn-color-danger);
|
||||
}
|
||||
|
||||
.wire-stepper[data-color="info"] {
|
||||
--stepper-accent: var(--wire-color-info);
|
||||
.wrn-stepper[data-color="info"] {
|
||||
--stepper-accent: var(--wrn-color-info);
|
||||
}
|
||||
|
||||
.wire-stepper[data-size="sm"] {
|
||||
.wrn-stepper[data-size="sm"] {
|
||||
font-size: 0.82rem;
|
||||
}
|
||||
|
||||
.wire-stepper[data-size="lg"] {
|
||||
.wrn-stepper[data-size="lg"] {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.wire-stepper[data-orientation="vertical"] .wire-stepper__list {
|
||||
.wrn-stepper[data-orientation="vertical"] .wrn-stepper__list {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.wire-stepper__step {
|
||||
.wrn-stepper__step {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1 1 0;
|
||||
@@ -273,7 +273,7 @@ component Stepper {
|
||||
gap: 0.35rem;
|
||||
}
|
||||
|
||||
.wire-stepper__button {
|
||||
.wrn-stepper__button {
|
||||
appearance: none;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -281,7 +281,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;
|
||||
@@ -289,139 +289,139 @@ 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__button:focus-visible {
|
||||
.wrn-stepper__button:focus-visible {
|
||||
outline: 2px solid var(--stepper-accent);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
.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 {
|
||||
.wrn-stepper__step[data-status="complete"] .wrn-stepper__marker {
|
||||
border-color: var(--stepper-accent);
|
||||
background: var(--stepper-accent);
|
||||
color: var(--wire-color-primary-contrast);
|
||||
color: var(--wrn-color-primary-contrast);
|
||||
}
|
||||
|
||||
.wire-stepper__step[data-status="current"] .wire-stepper__marker {
|
||||
.wrn-stepper__step[data-status="current"] .wrn-stepper__marker {
|
||||
border-color: var(--stepper-accent);
|
||||
color: var(--stepper-accent);
|
||||
box-shadow: 0 0 0 3px color-mix(in srgb, var(--stepper-accent) 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);
|
||||
}
|
||||
|
||||
.wire-stepper__panels {
|
||||
.wrn-stepper__panels {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
.wire-stepper__panel {
|
||||
.wrn-stepper__panel {
|
||||
padding: 1rem;
|
||||
border: 1px solid var(--wire-color-border);
|
||||
border-radius: var(--wire-radius-md);
|
||||
background: var(--wire-color-surface);
|
||||
animation: wire-stepper-in 200ms ease both;
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: var(--wrn-radius-md);
|
||||
background: var(--wrn-color-surface);
|
||||
animation: wrn-stepper-in 200ms ease both;
|
||||
}
|
||||
|
||||
.wire-stepper__panel-title {
|
||||
.wrn-stepper__panel-title {
|
||||
margin: 0 0 0.35rem;
|
||||
font-size: 0.95rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.wire-stepper__panel-body {
|
||||
.wrn-stepper__panel-body {
|
||||
margin: 0;
|
||||
color: var(--wire-color-text-muted);
|
||||
color: var(--wrn-color-text-muted);
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.wire-stepper__controls {
|
||||
.wrn-stepper__controls {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
margin-top: 0.85rem;
|
||||
}
|
||||
|
||||
.wire-stepper__controls-spacer {
|
||||
.wrn-stepper__controls-spacer {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
.wire-stepper__button-control {
|
||||
.wrn-stepper__button-control {
|
||||
appearance: none;
|
||||
padding: 0.45rem 0.9rem;
|
||||
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.86rem;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.wire-stepper__button-control:hover:not(:disabled) {
|
||||
background: var(--wire-color-surface-soft);
|
||||
.wrn-stepper__button-control:hover:not(:disabled) {
|
||||
background: var(--wrn-color-surface-soft);
|
||||
}
|
||||
|
||||
.wire-stepper__button-control:focus-visible {
|
||||
.wrn-stepper__button-control:focus-visible {
|
||||
outline: 2px solid var(--stepper-accent);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
.wire-stepper__button-control[data-primary="true"] {
|
||||
.wrn-stepper__button-control[data-primary="true"] {
|
||||
border-color: var(--stepper-accent);
|
||||
background: var(--stepper-accent);
|
||||
color: var(--wire-color-primary-contrast);
|
||||
color: var(--wrn-color-primary-contrast);
|
||||
}
|
||||
|
||||
/* A held step has to look held, or the button reads as broken. */
|
||||
.wire-stepper__button-control:disabled {
|
||||
.wrn-stepper__button-control:disabled {
|
||||
opacity: 0.45;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
@keyframes wire-stepper-in {
|
||||
@keyframes wrn-stepper-in {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateX(0.75rem);
|
||||
@@ -434,7 +434,7 @@ component Stepper {
|
||||
|
||||
/* A horizontal stepper cannot stay side by side on a phone. */
|
||||
@media (max-width: 639px) {
|
||||
.wire-stepper__list {
|
||||
.wrn-stepper__list {
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
import FieldStyles from "../styles/FieldStyles.wrn"
|
||||
|
||||
import ComponentBaseStyles from "../styles/ComponentBaseStyles.wrn"
|
||||
|
||||
component StrongPassword {
|
||||
outputs {
|
||||
input(payload: { value: string; score: number; maximumScore: number; percent: number; level: string })
|
||||
@@ -121,13 +117,13 @@ component StrongPassword {
|
||||
|
||||
view {
|
||||
<div
|
||||
class="wire-component wire-component--color-{color} wire-component--size-{size} wire-next--strong-password wire-next--strong-password-{presentation} {invalid ? 'wire-next--invalid' : ''} {disabled ? 'wire-next--disabled' : ''} {class}"
|
||||
class="wrn-component wrn-component--color-{color} wrn-component--size-{size} wrn-next--strong-password wrn-next--strong-password-{presentation} {invalid ? 'wrn-next--invalid' : ''} {disabled ? 'wrn-next--disabled' : ''} {class}"
|
||||
data-wrn-strong-password
|
||||
data-strength="{password ? strengthLevel() : 'empty'}"
|
||||
data-score="{password ? score() : 0}"
|
||||
>
|
||||
<label for="{name}-strong-password">{label}</label>
|
||||
<div class="wire-next__strong-password-anchor">
|
||||
<div class="wrn-next__strong-password-anchor">
|
||||
<input
|
||||
{...attrs}
|
||||
id="{name}-strong-password"
|
||||
@@ -150,18 +146,18 @@ component StrongPassword {
|
||||
|
||||
{#if presentation === "popover"}
|
||||
<div
|
||||
class="wire-next__strong-password-popover"
|
||||
class="wrn-next__strong-password-popover"
|
||||
data-open="{detailsOpen ? 'true' : 'false'}"
|
||||
role="status"
|
||||
>
|
||||
<div class="wire-next__strong-password-popover-arrow" aria-hidden="true"></div>
|
||||
<div class="wire-next__strong-password-details">
|
||||
<div class="wire-next__strong-password-summary">
|
||||
<div class="wrn-next__strong-password-popover-arrow" aria-hidden="true"></div>
|
||||
<div class="wrn-next__strong-password-details">
|
||||
<div class="wrn-next__strong-password-summary">
|
||||
<span>Password strength</span>
|
||||
<strong>{password ? strengthLabel() : emptyLabel}</strong>
|
||||
</div>
|
||||
<div
|
||||
class="wire-next__strong-password-meter"
|
||||
class="wrn-next__strong-password-meter"
|
||||
role="progressbar"
|
||||
aria-label="Password strength"
|
||||
aria-valuemin="0"
|
||||
@@ -171,14 +167,14 @@ component StrongPassword {
|
||||
<span style="width: {password ? strengthPercent() : 0}%"></span>
|
||||
</div>
|
||||
{#if showRequirements}
|
||||
<ul class="wire-next__strong-password-requirements">
|
||||
<ul class="wrn-next__strong-password-requirements">
|
||||
<li data-met="{password && hasMinimumLength() ? 'true' : 'false'}">
|
||||
<span aria-hidden="true"></span>At least {minLength} characters
|
||||
</li>
|
||||
{#if requireLowercase}<li data-met="{password && hasLowercase() ? 'true' : 'false'}"><span aria-hidden="true"></span>One lowercase letter</li>{/if}
|
||||
{#if requireUppercase}<li data-met="{password && hasUppercase() ? 'true' : 'false'}"><span aria-hidden="true"></span>One uppercase letter</li>{/if}
|
||||
{#if requireNumber}<li data-met="{password && hasNumber() ? 'true' : 'false'}"><span aria-hidden="true"></span>One number</li>{/if}
|
||||
{#if requireSpecialCharacter}<li data-met="{password && hasSpecialCharacter() ? 'true' : 'false'}"><span aria-hidden="true"></span>One special character: {specialCharactersSet}</li>{/if}
|
||||
{#if requireSpecialCharacter}<li class="wrn-next__strong-password-special" data-met="{password && hasSpecialCharacter() ? 'true' : 'false'}"><span aria-hidden="true"></span>One special character: {specialCharactersSet}</li>{/if}
|
||||
</ul>
|
||||
{/if}
|
||||
{#if hintText}<small id="{name}-hint">{hintText}</small>{/if}
|
||||
@@ -188,13 +184,13 @@ component StrongPassword {
|
||||
</div>
|
||||
|
||||
{#if presentation !== "popover"}
|
||||
<div class="wire-next__strong-password-details">
|
||||
<div class="wire-next__strong-password-summary">
|
||||
<div class="wrn-next__strong-password-details">
|
||||
<div class="wrn-next__strong-password-summary">
|
||||
<span>Password strength</span>
|
||||
<strong>{password ? strengthLabel() : emptyLabel}</strong>
|
||||
</div>
|
||||
<div
|
||||
class="wire-next__strong-password-meter"
|
||||
class="wrn-next__strong-password-meter"
|
||||
role="progressbar"
|
||||
aria-label="Password strength"
|
||||
aria-valuemin="0"
|
||||
@@ -204,112 +200,110 @@ component StrongPassword {
|
||||
<span style="width: {password ? strengthPercent() : 0}%"></span>
|
||||
</div>
|
||||
{#if showRequirements}
|
||||
<ul class="wire-next__strong-password-requirements">
|
||||
<ul class="wrn-next__strong-password-requirements">
|
||||
<li data-met="{password && hasMinimumLength() ? 'true' : 'false'}"><span aria-hidden="true"></span>At least {minLength} characters</li>
|
||||
{#if requireLowercase}<li data-met="{password && hasLowercase() ? 'true' : 'false'}"><span aria-hidden="true"></span>One lowercase letter</li>{/if}
|
||||
{#if requireUppercase}<li data-met="{password && hasUppercase() ? 'true' : 'false'}"><span aria-hidden="true"></span>One uppercase letter</li>{/if}
|
||||
{#if requireNumber}<li data-met="{password && hasNumber() ? 'true' : 'false'}"><span aria-hidden="true"></span>One number</li>{/if}
|
||||
{#if requireSpecialCharacter}<li data-met="{password && hasSpecialCharacter() ? 'true' : 'false'}"><span aria-hidden="true"></span>One special character: {specialCharactersSet}</li>{/if}
|
||||
{#if requireSpecialCharacter}<li class="wrn-next__strong-password-special" data-met="{password && hasSpecialCharacter() ? 'true' : 'false'}"><span aria-hidden="true"></span>One special character: {specialCharactersSet}</li>{/if}
|
||||
</ul>
|
||||
{/if}
|
||||
{#if hintText}<small id="{name}-hint">{hintText}</small>{/if}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<small id="{name}-validation" class="wire-next__validation" data-error="{name}">{validationMessage}</small>
|
||||
<small id="{name}-validation" class="wrn-next__validation" data-error="{name}">{validationMessage}</small>
|
||||
</div>
|
||||
<FieldStyles hidden />
|
||||
<ComponentBaseStyles hidden />
|
||||
}
|
||||
|
||||
style {
|
||||
.wire-next--strong-password {
|
||||
.wrn-next--strong-password {
|
||||
position: relative;
|
||||
display: grid;
|
||||
width: 100%;
|
||||
gap: 0.6rem;
|
||||
color: var(--wire-color-text);
|
||||
color: var(--wrn-color-text);
|
||||
}
|
||||
|
||||
.wire-next--strong-password > label {
|
||||
.wrn-next--strong-password > label {
|
||||
font-size: 0.82em;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.wire-next__strong-password-anchor {
|
||||
.wrn-next__strong-password-anchor {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.wire-next--strong-password input {
|
||||
.wrn-next--strong-password input {
|
||||
width: 100%;
|
||||
min-height: 2.75em;
|
||||
padding: 0.68em 0.85em;
|
||||
border: 1px solid var(--wire-color-border);
|
||||
border-radius: var(--wire-radius-sm);
|
||||
min-height: 2.65rem;
|
||||
padding: 0.7rem 0.85rem;
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: var(--wrn-radius-sm);
|
||||
outline: 0;
|
||||
color: var(--wire-color-text);
|
||||
background: var(--wire-color-surface);
|
||||
color: var(--wrn-color-text);
|
||||
background: var(--wrn-color-surface);
|
||||
font: inherit;
|
||||
transition:
|
||||
border-color 160ms ease,
|
||||
box-shadow 160ms ease;
|
||||
}
|
||||
|
||||
.wire-next--strong-password input:focus-visible {
|
||||
border-color: var(--wire-component-color);
|
||||
box-shadow: 0 0 0 3px color-mix(in srgb, var(--wire-component-color) 16%, transparent);
|
||||
.wrn-next--strong-password input:focus-visible {
|
||||
border-color: var(--wrn-component-color);
|
||||
box-shadow: 0 0 0 3px color-mix(in srgb, var(--wrn-component-color) 16%, transparent);
|
||||
}
|
||||
|
||||
.wire-next__strong-password-details {
|
||||
.wrn-next__strong-password-details {
|
||||
display: grid;
|
||||
gap: 0.65rem;
|
||||
}
|
||||
|
||||
.wire-next__strong-password-summary {
|
||||
.wrn-next__strong-password-summary {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 1rem;
|
||||
color: var(--wire-color-muted);
|
||||
color: var(--wrn-color-muted);
|
||||
font-size: 0.75em;
|
||||
}
|
||||
|
||||
.wire-next__strong-password-summary strong {
|
||||
color: var(--wire-color-text);
|
||||
.wrn-next__strong-password-summary strong {
|
||||
color: var(--wrn-color-text);
|
||||
}
|
||||
|
||||
.wire-next__strong-password-meter {
|
||||
.wrn-next__strong-password-meter {
|
||||
width: 100%;
|
||||
height: 0.42rem;
|
||||
overflow: hidden;
|
||||
border-radius: 999px;
|
||||
background: color-mix(in srgb, var(--wire-color-border) 72%, transparent);
|
||||
background: color-mix(in srgb, var(--wrn-color-border) 72%, transparent);
|
||||
}
|
||||
|
||||
.wire-next__strong-password-meter > span {
|
||||
.wrn-next__strong-password-meter > span {
|
||||
display: block;
|
||||
width: 0;
|
||||
height: 100%;
|
||||
border-radius: inherit;
|
||||
background: var(--wire-color-danger);
|
||||
background: var(--wrn-color-danger);
|
||||
transition:
|
||||
width 180ms ease,
|
||||
background-color 180ms ease;
|
||||
}
|
||||
|
||||
.wire-next--strong-password[data-strength="fair"] .wire-next__strong-password-meter > span {
|
||||
background: var(--wire-color-warning);
|
||||
.wrn-next--strong-password[data-strength="fair"] .wrn-next__strong-password-meter > span {
|
||||
background: var(--wrn-color-warning);
|
||||
}
|
||||
|
||||
.wire-next--strong-password[data-strength="good"] .wire-next__strong-password-meter > span {
|
||||
background: var(--wire-component-color);
|
||||
.wrn-next--strong-password[data-strength="good"] .wrn-next__strong-password-meter > span {
|
||||
background: var(--wrn-component-color);
|
||||
}
|
||||
|
||||
.wire-next--strong-password[data-strength="strong"] .wire-next__strong-password-meter > span {
|
||||
background: var(--wire-color-success);
|
||||
.wrn-next--strong-password[data-strength="strong"] .wrn-next__strong-password-meter > span {
|
||||
background: var(--wrn-color-success);
|
||||
}
|
||||
|
||||
.wire-next__strong-password-requirements {
|
||||
.wrn-next__strong-password-requirements {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
gap: 0.45rem 1rem;
|
||||
@@ -318,17 +312,26 @@ component StrongPassword {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.wire-next__strong-password-requirements li {
|
||||
.wrn-next__strong-password-requirements li {
|
||||
display: flex;
|
||||
min-width: 0;
|
||||
align-items: flex-start;
|
||||
gap: 0.45rem;
|
||||
color: var(--wire-color-muted);
|
||||
color: var(--wrn-color-muted);
|
||||
font-size: 0.72em;
|
||||
line-height: 1.45;
|
||||
}
|
||||
|
||||
.wire-next__strong-password-requirements li > span {
|
||||
.wrn-next__strong-password-requirements .wrn-next__strong-password-special {
|
||||
grid-column: 1 / -1;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.wrn-next__strong-password-special [data-text="specialCharactersSet"] {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.wrn-next__strong-password-requirements li > span[aria-hidden="true"] {
|
||||
position: relative;
|
||||
width: 0.9rem;
|
||||
height: 0.9rem;
|
||||
@@ -338,51 +341,51 @@ component StrongPassword {
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.wire-next__strong-password-requirements li > span::after {
|
||||
.wrn-next__strong-password-requirements li > span[aria-hidden="true"]::after {
|
||||
position: absolute;
|
||||
top: 0.12rem;
|
||||
left: 0.29rem;
|
||||
width: 0.22rem;
|
||||
height: 0.42rem;
|
||||
border: solid var(--wire-color-surface);
|
||||
border: solid var(--wrn-color-surface);
|
||||
border-width: 0 0.1rem 0.1rem 0;
|
||||
content: "";
|
||||
opacity: 0;
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
|
||||
.wire-next__strong-password-requirements li[data-met="true"] {
|
||||
color: var(--wire-color-success);
|
||||
.wrn-next__strong-password-requirements li[data-met="true"] {
|
||||
color: var(--wrn-color-success);
|
||||
}
|
||||
|
||||
.wire-next__strong-password-requirements li[data-met="true"] > span {
|
||||
border-color: var(--wire-color-success);
|
||||
background: var(--wire-color-success);
|
||||
.wrn-next__strong-password-requirements li[data-met="true"] > span[aria-hidden="true"] {
|
||||
border-color: var(--wrn-color-success);
|
||||
background: var(--wrn-color-success);
|
||||
}
|
||||
|
||||
.wire-next__strong-password-requirements li[data-met="true"] > span::after {
|
||||
.wrn-next__strong-password-requirements li[data-met="true"] > span[aria-hidden="true"]::after {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.wire-next__strong-password-details > small {
|
||||
color: var(--wire-color-muted);
|
||||
.wrn-next__strong-password-details > small {
|
||||
color: var(--wrn-color-muted);
|
||||
font-size: 0.7em;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.wire-next__strong-password-popover {
|
||||
.wrn-next__strong-password-popover {
|
||||
position: absolute;
|
||||
top: calc(100% + 0.7rem);
|
||||
left: 0;
|
||||
z-index: 30;
|
||||
width: min(28rem, calc(100vw - 2rem));
|
||||
padding: 1rem;
|
||||
border: 1px solid var(--wire-color-border);
|
||||
border-radius: var(--wire-radius);
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: var(--wrn-radius);
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
background: var(--wire-color-surface);
|
||||
box-shadow: var(--wire-shadow-2);
|
||||
background: var(--wrn-color-surface);
|
||||
box-shadow: var(--wrn-shadow-2);
|
||||
transform: translateY(-0.35rem);
|
||||
transition:
|
||||
opacity 140ms ease,
|
||||
@@ -390,28 +393,587 @@ component StrongPassword {
|
||||
visibility 140ms ease;
|
||||
}
|
||||
|
||||
.wire-next__strong-password-popover[data-open="true"] {
|
||||
.wrn-next__strong-password-popover[data-open="true"] {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
.wire-next__strong-password-popover-arrow {
|
||||
.wrn-next__strong-password-popover-arrow {
|
||||
position: absolute;
|
||||
top: -0.38rem;
|
||||
left: 1.25rem;
|
||||
width: 0.7rem;
|
||||
height: 0.7rem;
|
||||
border-top: 1px solid var(--wire-color-border);
|
||||
border-left: 1px solid var(--wire-color-border);
|
||||
background: var(--wire-color-surface);
|
||||
border-top: 1px solid var(--wrn-color-border);
|
||||
border-left: 1px solid var(--wrn-color-border);
|
||||
background: var(--wrn-color-surface);
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
|
||||
@media (max-width: 560px) {
|
||||
.wire-next__strong-password-requirements {
|
||||
.wrn-next__strong-password-requirements {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
/* Shared component foundation. */
|
||||
|
||||
.wrn-component {
|
||||
--wrn-component-color: var(--wrn-color-primary);
|
||||
--wrn-component-scale: 1;
|
||||
margin: 0;
|
||||
color: var(--wrn-color-text);
|
||||
font-family: var(--wrn-font-sans, inherit);
|
||||
}
|
||||
|
||||
.wrn-component--color-primary {
|
||||
--wrn-component-color: var(--wrn-color-primary);
|
||||
}
|
||||
|
||||
.wrn-component--color-secondary {
|
||||
--wrn-component-color: var(--wrn-color-secondary);
|
||||
}
|
||||
|
||||
.wrn-component--color-success {
|
||||
--wrn-component-color: var(--wrn-color-success);
|
||||
}
|
||||
|
||||
.wrn-component--color-warning {
|
||||
--wrn-component-color: var(--wrn-color-warning);
|
||||
}
|
||||
|
||||
.wrn-component--color-danger {
|
||||
--wrn-component-color: var(--wrn-color-danger);
|
||||
}
|
||||
|
||||
.wrn-component--color-info {
|
||||
--wrn-component-color: var(--wrn-color-info);
|
||||
}
|
||||
|
||||
.wrn-component--size-xs {
|
||||
--wrn-component-scale: 0.78;
|
||||
}
|
||||
|
||||
.wrn-component--size-sm {
|
||||
--wrn-component-scale: 0.88;
|
||||
}
|
||||
|
||||
.wrn-component--size-default,
|
||||
.wrn-component--size-md {
|
||||
--wrn-component-scale: 1;
|
||||
}
|
||||
|
||||
.wrn-component--size-lg {
|
||||
--wrn-component-scale: 1.14;
|
||||
}
|
||||
|
||||
.wrn-component--size-xl {
|
||||
--wrn-component-scale: 1.28;
|
||||
}
|
||||
|
||||
.wrn-component:not(.wrn-btn) {
|
||||
font-size: calc(1em * var(--wrn-component-scale));
|
||||
}
|
||||
|
||||
.wrn-component :is(a, button, input, select, textarea):focus-visible {
|
||||
outline-color: var(--wrn-component-color);
|
||||
}
|
||||
|
||||
.wrn-component p {
|
||||
margin: 0;
|
||||
color: var(--wrn-color-muted);
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
/* Shared field foundation. */
|
||||
|
||||
/* Validation states set by the browser validation runtime. */
|
||||
.wrn-invalid {
|
||||
border-color: var(--wrn-color-danger) !important;
|
||||
}
|
||||
|
||||
.wrn-field-error {
|
||||
display: block;
|
||||
min-height: 1em;
|
||||
margin-top: 0.25rem;
|
||||
color: var(--wrn-color-danger);
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
.wrn-next--choice {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.55rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.wrn-next--choice input {
|
||||
width: 1.1rem;
|
||||
height: 1.1rem;
|
||||
accent-color: var(--wrn-color-primary);
|
||||
}
|
||||
|
||||
.wrn-next--field {
|
||||
display: grid;
|
||||
width: min(100%, 28rem);
|
||||
gap: 0.4rem;
|
||||
font-size: 0.78rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
.wrn-next--field :where(input, textarea, select) {
|
||||
width: 100%;
|
||||
min-height: 2.65rem;
|
||||
padding: 0.6rem 0.7rem;
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: 0.6rem;
|
||||
outline: 0;
|
||||
color: var(--wrn-color-text);
|
||||
background: var(--wrn-color-bg);
|
||||
font: inherit;
|
||||
font-weight: 500;
|
||||
}
|
||||
.wrn-auth-form form > .wrn-next--field,
|
||||
.wrn-auth-form form > .wrn-field {
|
||||
width: 100%;
|
||||
max-width: none;
|
||||
}
|
||||
.wrn-auth-form__submit > .wrn-btn {
|
||||
width: 100%;
|
||||
min-height: 3rem;
|
||||
border-radius: 0.75rem;
|
||||
box-shadow: 0 0.8rem 1.8rem color-mix(in srgb, var(--wrn-btn-color) 20%, transparent);
|
||||
}
|
||||
.wrn-next--field :where(input, textarea, select):focus-visible {
|
||||
border-color: var(--wrn-color-primary);
|
||||
box-shadow: 0 0 0 3px color-mix(in srgb, var(--wrn-color-primary) 16%, transparent);
|
||||
}
|
||||
.wrn-next--field textarea {
|
||||
resize: vertical;
|
||||
}
|
||||
.wrn-next--field,
|
||||
.wrn-next--choice-field {
|
||||
--wrn-field-color: var(--wrn-component-color, var(--wrn-color-primary));
|
||||
width: min(100%, 34rem);
|
||||
min-width: 0;
|
||||
color: var(--wrn-color-text);
|
||||
font-size: 0.8125rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
.wrn-next--field.wrn-next--size-sm,
|
||||
.wrn-next--choice-field.wrn-next--size-sm {
|
||||
font-size: 0.8125rem;
|
||||
}
|
||||
.wrn-next--field.wrn-next--size-lg,
|
||||
.wrn-next--choice-field.wrn-next--size-lg {
|
||||
font-size: 1rem;
|
||||
}
|
||||
.wrn-next__field-heading {
|
||||
display: flex;
|
||||
min-width: 0;
|
||||
align-items: baseline;
|
||||
justify-content: space-between;
|
||||
gap: 1rem;
|
||||
}
|
||||
.wrn-next__field-heading label {
|
||||
color: var(--wrn-color-text);
|
||||
font-weight: 600;
|
||||
}
|
||||
.wrn-next__field-hint,
|
||||
.wrn-next__field-help {
|
||||
color: var(--wrn-color-muted);
|
||||
font-size: 0.82em;
|
||||
font-weight: 500;
|
||||
}
|
||||
.wrn-next__field-control {
|
||||
position: relative;
|
||||
min-width: 0;
|
||||
}
|
||||
.wrn-next__field-control > :is(input, textarea, select) {
|
||||
padding-inline: 0.85rem;
|
||||
border-color: var(--wrn-color-border);
|
||||
border-radius: var(--wrn-radius-sm);
|
||||
background: var(--wrn-color-surface);
|
||||
font-size: 0.8125rem;
|
||||
}
|
||||
.wrn-next__field-control[data-icon-position="start"] > :is(input, textarea, select) {
|
||||
padding-inline-start: 2.5rem;
|
||||
}
|
||||
.wrn-next__field-control[data-icon-position="end"] > :is(input, textarea, select) {
|
||||
padding-inline-end: 2.5rem;
|
||||
}
|
||||
.wrn-next__field-icon {
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
top: 50%;
|
||||
left: 0.85rem;
|
||||
color: var(--wrn-color-muted);
|
||||
pointer-events: none;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
.wrn-next__field-control[data-icon-position="end"] > .wrn-next__field-icon {
|
||||
right: 0.85rem;
|
||||
left: auto;
|
||||
}
|
||||
.wrn-next--field[data-variant="outlined"]
|
||||
.wrn-next__field-control
|
||||
> :is(input, textarea, select) {
|
||||
border-width: 2px;
|
||||
}
|
||||
.wrn-next--field[data-variant="underline"]
|
||||
.wrn-next__field-control
|
||||
> :is(input, textarea, select) {
|
||||
padding-inline: 0;
|
||||
border-width: 0 0 1px;
|
||||
border-radius: 0;
|
||||
background: transparent;
|
||||
box-shadow: none;
|
||||
}
|
||||
.wrn-next--field[data-variant="pill"] .wrn-next__field-control > :is(input, select) {
|
||||
border-radius: 999px;
|
||||
padding-inline: 1.15rem;
|
||||
}
|
||||
.wrn-next--field[data-variant="ghost"] .wrn-next__field-control > :is(input, textarea, select) {
|
||||
border-color: transparent;
|
||||
background: color-mix(in srgb, var(--wrn-field-color) 8%, var(--wrn-color-surface));
|
||||
}
|
||||
.wrn-next__field-floating-label {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 0.85rem;
|
||||
color: var(--wrn-color-muted);
|
||||
pointer-events: none;
|
||||
transform: translateY(-50%);
|
||||
transition: 150ms ease;
|
||||
}
|
||||
.wrn-next--textarea .wrn-next__field-floating-label {
|
||||
top: 1.35rem;
|
||||
}
|
||||
.wrn-next--field[data-floating="true"] .wrn-next__field-control > :is(input, textarea, select) {
|
||||
padding-top: 1.2rem;
|
||||
padding-bottom: 0.3rem;
|
||||
}
|
||||
.wrn-next--field[data-floating="true"] .wrn-next__field-heading > label {
|
||||
position: absolute !important;
|
||||
width: 1px !important;
|
||||
height: 1px !important;
|
||||
overflow: hidden !important;
|
||||
margin: -1px !important;
|
||||
clip: rect(0, 0, 0, 0) !important;
|
||||
white-space: nowrap !important;
|
||||
}
|
||||
.wrn-next--field[data-floating="true"]
|
||||
.wrn-next__field-heading:not(:has(.wrn-next__field-hint)) {
|
||||
display: none;
|
||||
}
|
||||
.wrn-next--field[data-floating="true"]
|
||||
.wrn-next__field-control
|
||||
> :is(input, textarea):is(:focus, :not(:placeholder-shown))
|
||||
+ .wrn-next__field-floating-label {
|
||||
top: 0.42rem;
|
||||
font-size: 0.7em;
|
||||
transform: none;
|
||||
}
|
||||
.wrn-next__field-error {
|
||||
min-height: 1em;
|
||||
color: var(--wrn-color-danger);
|
||||
font-size: 0.82em;
|
||||
font-weight: 600;
|
||||
}
|
||||
.wrn-next__field-error:empty {
|
||||
display: none;
|
||||
}
|
||||
.wrn-next--field[data-invalid="true"] :is(input, textarea, select),
|
||||
.wrn-next--choice-field[data-invalid="true"] input {
|
||||
border-color: var(--wrn-color-danger);
|
||||
}
|
||||
.wrn-next--field :is(input, textarea, select):disabled,
|
||||
.wrn-next--choice-field input:disabled {
|
||||
cursor: not-allowed;
|
||||
opacity: 0.58;
|
||||
}
|
||||
.wrn-next--field :is(input, textarea, select):read-only {
|
||||
background: var(--wrn-color-surface-2);
|
||||
}
|
||||
.wrn-next--field[data-inline="true"],
|
||||
.wrn-next--choice-field[data-inline="true"] {
|
||||
display: grid;
|
||||
width: 100%;
|
||||
max-width: none;
|
||||
grid-template-columns: minmax(7rem, max-content) minmax(12rem, 20rem) minmax(10rem, 1fr);
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
.wrn-next--field[data-inline="true"] .wrn-next__field-heading,
|
||||
.wrn-next--choice-field[data-inline="true"] .wrn-next__field-heading {
|
||||
min-height: 2.65rem;
|
||||
align-items: center;
|
||||
}
|
||||
.wrn-next--field[data-inline="true"] .wrn-next__field-heading {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
.wrn-next--field[data-inline="true"] .wrn-next__field-help,
|
||||
.wrn-next--choice-field[data-inline="true"] .wrn-next__field-help {
|
||||
display: flex;
|
||||
min-height: 2.65rem;
|
||||
align-items: center;
|
||||
}
|
||||
.wrn-next--choice-field[data-inline="true"] {
|
||||
grid-template-columns: minmax(12rem, 20rem) minmax(10rem, 1fr);
|
||||
}
|
||||
.wrn-next--choice-field[data-inline="true"] .wrn-next__field-heading:empty {
|
||||
display: none;
|
||||
}
|
||||
.wrn-next--field[data-inline="true"] .wrn-next__field-error,
|
||||
.wrn-next--choice-field[data-inline="true"] .wrn-next__field-error {
|
||||
grid-column: 2 / -1;
|
||||
}
|
||||
.wrn-next__sr-only {
|
||||
position: absolute !important;
|
||||
width: 1px !important;
|
||||
height: 1px !important;
|
||||
overflow: hidden !important;
|
||||
padding: 0 !important;
|
||||
border: 0 !important;
|
||||
margin: -1px !important;
|
||||
clip: rect(0, 0, 0, 0) !important;
|
||||
white-space: nowrap !important;
|
||||
}
|
||||
.wrn-next__choice-field {
|
||||
display: grid;
|
||||
width: 100%;
|
||||
max-width: none;
|
||||
gap: 0.4rem;
|
||||
}
|
||||
.wrn-next__choice {
|
||||
display: flex;
|
||||
min-width: 0;
|
||||
align-items: center;
|
||||
gap: 0.65rem;
|
||||
color: var(--wrn-color-text);
|
||||
width: 100%;
|
||||
font-size: 0.75rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
.wrn-next__checkbox-content > .wrn-next__choice {
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
align-items: flex-start;
|
||||
}
|
||||
.wrn-next__choice input {
|
||||
flex: 0 0 auto;
|
||||
margin: 0;
|
||||
accent-color: var(--wrn-field-color);
|
||||
}
|
||||
.wrn-next__choice-copy {
|
||||
display: grid;
|
||||
min-width: 0;
|
||||
gap: 0.15rem;
|
||||
line-height: 1.35;
|
||||
}
|
||||
.wrn-next__choice-copy small {
|
||||
color: var(--wrn-color-muted);
|
||||
font-weight: 500;
|
||||
}
|
||||
.wrn-next__radio-group,
|
||||
.wrn-next__checkbox-group {
|
||||
display: grid;
|
||||
min-width: 0;
|
||||
gap: 0.65rem;
|
||||
}
|
||||
.wrn-next--radio-field[data-orientation="horizontal"] .wrn-next__radio-group,
|
||||
.wrn-next--checkbox-field[data-orientation="horizontal"] .wrn-next__checkbox-group {
|
||||
grid-template-columns: repeat(auto-fit, minmax(8rem, max-content));
|
||||
align-items: stretch;
|
||||
}
|
||||
.wrn-next--radio-field[data-card="true"] .wrn-next__radio-group,
|
||||
.wrn-next--checkbox-field[data-card="true"] .wrn-next__checkbox-group {
|
||||
grid-template-columns: repeat(auto-fit, minmax(min(100%, 12rem), 1fr));
|
||||
}
|
||||
.wrn-next--radio-field[data-card="true"] .wrn-next--radio,
|
||||
.wrn-next--checkbox-field[data-card="true"] .wrn-next--checkbox {
|
||||
min-height: 4.5rem;
|
||||
padding: 0.85rem;
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: var(--wrn-radius-sm);
|
||||
background: var(--wrn-color-surface);
|
||||
}
|
||||
.wrn-next--radio-field[data-card="true"] .wrn-next--radio:has(input:checked),
|
||||
.wrn-next--checkbox-field[data-card="true"] .wrn-next--checkbox:has(input:checked) {
|
||||
border-color: var(--wrn-field-color);
|
||||
box-shadow: 0 0 0 1px var(--wrn-field-color);
|
||||
}
|
||||
.wrn-next--radio-field[data-list="true"] .wrn-next--radio,
|
||||
.wrn-next--checkbox-field[data-list="true"] .wrn-next--checkbox {
|
||||
padding-block: 0.75rem;
|
||||
border-bottom: 1px solid var(--wrn-color-border);
|
||||
}
|
||||
.wrn-next--radio-field[data-right-aligned="true"] .wrn-next--radio,
|
||||
.wrn-next--checkbox-field[data-right-aligned="true"] .wrn-next--checkbox {
|
||||
justify-content: space-between;
|
||||
}
|
||||
.wrn-next--radio-field[data-right-aligned="true"] .wrn-next--radio input,
|
||||
.wrn-next--checkbox-field[data-right-aligned="true"] .wrn-next--checkbox input {
|
||||
order: 2;
|
||||
}
|
||||
.wrn-next--radio-field[data-right-aligned="true"] .wrn-next__choice-copy,
|
||||
.wrn-next--checkbox-field[data-right-aligned="true"] .wrn-next__choice-copy {
|
||||
order: 1;
|
||||
}
|
||||
.wrn-next__choice[data-variant="outlined"],
|
||||
.wrn-next__choice[data-variant="floating"] {
|
||||
padding: 0.65rem 0.8rem;
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: var(--wrn-radius-sm);
|
||||
}
|
||||
.wrn-next__choice[data-variant="pill"] {
|
||||
padding: 0.65rem 1rem;
|
||||
border-radius: 999px;
|
||||
background: color-mix(in srgb, var(--wrn-field-color) 9%, var(--wrn-color-surface));
|
||||
}
|
||||
.wrn-next__choice[data-variant="ghost"] {
|
||||
padding: 0.65rem 0.8rem;
|
||||
border-radius: var(--wrn-radius-sm);
|
||||
background: color-mix(in srgb, var(--wrn-field-color) 7%, transparent);
|
||||
}
|
||||
.wrn-next__choice[data-variant="underline"] {
|
||||
padding-block: 0.5rem;
|
||||
border-bottom: 1px solid var(--wrn-color-border);
|
||||
}
|
||||
.wrn-next--select .wrn-next__field-control {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.wrn-next__color-control,
|
||||
.wrn-next__range-control,
|
||||
.wrn-next__input-group-control,
|
||||
.wrn-next__file-control {
|
||||
display: flex;
|
||||
min-width: 0;
|
||||
align-items: center;
|
||||
gap: 0.65rem;
|
||||
}
|
||||
.wrn-next__picker-control,
|
||||
.wrn-next--time-picker .wrn-next__field-control {
|
||||
position: relative;
|
||||
display: flex;
|
||||
min-width: 0;
|
||||
align-items: center;
|
||||
}
|
||||
.wrn-next__picker-control > button:first-of-type,
|
||||
.wrn-next__time-trigger {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
min-height: 2.65rem;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 0.75rem;
|
||||
padding: 0.7rem 0.85rem;
|
||||
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;
|
||||
text-align: left;
|
||||
}
|
||||
.wrn-next__calendar,
|
||||
.wrn-next__time-panel {
|
||||
z-index: 20;
|
||||
display: grid;
|
||||
width: min(100%, 22rem);
|
||||
gap: 0.75rem;
|
||||
padding: 0.85rem;
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: var(--wrn-radius-md);
|
||||
background: var(--wrn-color-surface);
|
||||
box-shadow: var(--wrn-shadow-3);
|
||||
}
|
||||
.wrn-next--date-picker[data-expanded="false"] .wrn-next__calendar,
|
||||
.wrn-next--time-picker[data-expanded="false"] .wrn-next__time-panel {
|
||||
display: none;
|
||||
}
|
||||
.wrn-next__calendar button,
|
||||
.wrn-next__time-panel button {
|
||||
min-height: 2.25rem;
|
||||
border: 0;
|
||||
border-radius: var(--wrn-radius-sm);
|
||||
background: transparent;
|
||||
color: inherit;
|
||||
}
|
||||
.wrn-next__calendar-weekdays,
|
||||
.wrn-next__calendar-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(7, 1fr);
|
||||
gap: 0.2rem;
|
||||
text-align: center;
|
||||
}
|
||||
.wrn-next__calendar-weekdays {
|
||||
color: var(--wrn-color-muted);
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
.wrn-next__calendar-grid button:hover,
|
||||
.wrn-next__time-panel button:hover {
|
||||
background: var(--wrn-color-surface-2);
|
||||
}
|
||||
.wrn-next__calendar-grid button[aria-pressed="true"],
|
||||
.wrn-next__time-panel button[aria-pressed="true"] {
|
||||
background: var(--wrn-field-color);
|
||||
color: var(--wrn-color-primary-contrast, #fff);
|
||||
}
|
||||
.wrn-next__time-period {
|
||||
display: flex;
|
||||
gap: 0.35rem;
|
||||
}
|
||||
.wrn-next--file-upload-progress .wrn-next__row,
|
||||
.wrn-next__upload-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
.wrn-next--file-upload-progress .wrn-next__row > span {
|
||||
display: grid;
|
||||
min-width: 0;
|
||||
}
|
||||
.wrn-next--field[data-variant="underline"]
|
||||
:is(.wrn-next__input-group-control, .wrn-next__file-control, .wrn-next__color-control) {
|
||||
border-width: 0 0 1px;
|
||||
border-radius: 0;
|
||||
background: transparent;
|
||||
}
|
||||
.wrn-next--field[data-variant="outlined"]
|
||||
:is(.wrn-next__input-group-control, .wrn-next__file-control) {
|
||||
border-width: 2px;
|
||||
}
|
||||
.wrn-next--field[data-variant="pill"]
|
||||
:is(.wrn-next__input-group-control, .wrn-next__file-control) {
|
||||
border-radius: 999px;
|
||||
}
|
||||
.wrn-next--field[data-variant="ghost"]
|
||||
:is(.wrn-next__input-group-control, .wrn-next__file-control, .wrn-next__color-control) {
|
||||
border-color: transparent;
|
||||
background: color-mix(in srgb, var(--wrn-field-color) 8%, var(--wrn-color-surface));
|
||||
}
|
||||
@media (max-width: 640px) {
|
||||
.wrn-next--field[data-inline="true"],
|
||||
.wrn-next--choice-field[data-inline="true"] {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.wrn-next--field[data-inline="true"] .wrn-next__field-error,
|
||||
.wrn-next--choice-field[data-inline="true"] .wrn-next__field-error {
|
||||
grid-column: auto;
|
||||
}
|
||||
}
|
||||
.wrn-next--toggle-password:has(input.wrn-invalid) .wrn-next__password-control > input,
|
||||
.wrn-next--toggle-password.wrn-next--invalid .wrn-next__password-control > input {
|
||||
border-color: var(--wrn-color-danger);
|
||||
box-shadow: 0 0 0 3px color-mix(in srgb, var(--wrn-color-danger) 14%, transparent);
|
||||
}
|
||||
.wrn-next--strong-password.wrn-next--invalid input,
|
||||
.wrn-next--strong-password input.wrn-invalid {
|
||||
border-color: var(--wrn-color-danger);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import ComponentBaseStyles from "../styles/ComponentBaseStyles.wrn"
|
||||
|
||||
component StyledIcon {
|
||||
props {
|
||||
size: string = "default"
|
||||
@@ -11,27 +9,95 @@ component StyledIcon {
|
||||
class: string = ""
|
||||
}
|
||||
view {
|
||||
<section class="wire-component wire-component--color-{color} wire-component--size-{size} wire-next--styled-icon wire-next--variant-{variant} {class}">
|
||||
<section class="wrn-component wrn-component--color-{color} wrn-component--size-{size} wrn-next--styled-icon wrn-next--variant-{variant} {class}">
|
||||
{#if title}<strong>{title}</strong>{/if}
|
||||
{#if description}<p>{description}</p>{/if}
|
||||
{#if items}<div class="wire-next__items">{#each items as item}<span>{item.label}</span>{/each}</div>{/if}
|
||||
{#if items}<div class="wrn-next__items">{#each items as item}<span>{item.label}</span>{/each}</div>{/if}
|
||||
<slot />
|
||||
</section>
|
||||
<ComponentBaseStyles hidden />
|
||||
}
|
||||
|
||||
style {
|
||||
.wire-next--styled-icon {
|
||||
.wrn-next--styled-icon {
|
||||
display: grid;
|
||||
gap: 0.75rem;
|
||||
padding: 1rem;
|
||||
border: 1px solid var(--wire-color-border);
|
||||
border-radius: var(--wire-radius);
|
||||
color: var(--wire-color-text);
|
||||
background: var(--wire-color-surface);
|
||||
border: 1px solid var(--wrn-color-border);
|
||||
border-radius: var(--wrn-radius);
|
||||
color: var(--wrn-color-text);
|
||||
background: var(--wrn-color-surface);
|
||||
}
|
||||
.wire-next--styled-icon > p { margin: 0; color: var(--wire-color-muted); }
|
||||
.wire-next--styled-icon > .wire-next__items { display: flex; flex-wrap: wrap; gap: 0.5rem; }
|
||||
.wire-next--styled-icon > .wire-next__items > span { padding: 0.35rem 0.6rem; border-radius: var(--wire-radius-sm); background: var(--wire-color-surface-2); }
|
||||
.wrn-next--styled-icon > p { margin: 0; color: var(--wrn-color-muted); }
|
||||
.wrn-next--styled-icon > .wrn-next__items { display: flex; flex-wrap: wrap; gap: 0.5rem; }
|
||||
.wrn-next--styled-icon > .wrn-next__items > span { padding: 0.35rem 0.6rem; border-radius: var(--wrn-radius-sm); background: var(--wrn-color-surface-2); }
|
||||
|
||||
/* Shared component foundation. */
|
||||
|
||||
.wrn-component {
|
||||
--wrn-component-color: var(--wrn-color-primary);
|
||||
--wrn-component-scale: 1;
|
||||
margin: 0;
|
||||
color: var(--wrn-color-text);
|
||||
font-family: var(--wrn-font-sans, inherit);
|
||||
}
|
||||
|
||||
.wrn-component--color-primary {
|
||||
--wrn-component-color: var(--wrn-color-primary);
|
||||
}
|
||||
|
||||
.wrn-component--color-secondary {
|
||||
--wrn-component-color: var(--wrn-color-secondary);
|
||||
}
|
||||
|
||||
.wrn-component--color-success {
|
||||
--wrn-component-color: var(--wrn-color-success);
|
||||
}
|
||||
|
||||
.wrn-component--color-warning {
|
||||
--wrn-component-color: var(--wrn-color-warning);
|
||||
}
|
||||
|
||||
.wrn-component--color-danger {
|
||||
--wrn-component-color: var(--wrn-color-danger);
|
||||
}
|
||||
|
||||
.wrn-component--color-info {
|
||||
--wrn-component-color: var(--wrn-color-info);
|
||||
}
|
||||
|
||||
.wrn-component--size-xs {
|
||||
--wrn-component-scale: 0.78;
|
||||
}
|
||||
|
||||
.wrn-component--size-sm {
|
||||
--wrn-component-scale: 0.88;
|
||||
}
|
||||
|
||||
.wrn-component--size-default,
|
||||
.wrn-component--size-md {
|
||||
--wrn-component-scale: 1;
|
||||
}
|
||||
|
||||
.wrn-component--size-lg {
|
||||
--wrn-component-scale: 1.14;
|
||||
}
|
||||
|
||||
.wrn-component--size-xl {
|
||||
--wrn-component-scale: 1.28;
|
||||
}
|
||||
|
||||
.wrn-component:not(.wrn-btn) {
|
||||
font-size: calc(1em * var(--wrn-component-scale));
|
||||
}
|
||||
|
||||
.wrn-component :is(a, button, input, select, textarea):focus-visible {
|
||||
outline-color: var(--wrn-component-color);
|
||||
}
|
||||
|
||||
.wrn-component p {
|
||||
margin: 0;
|
||||
color: var(--wrn-color-muted);
|
||||
line-height: 1.6;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user