diff --git a/APPLY_COMPONENT_SHOWCASE_UPDATE.ps1 b/APPLY_COMPONENT_SHOWCASE_UPDATE.ps1 new file mode 100644 index 00000000..57bed6cf --- /dev/null +++ b/APPLY_COMPONENT_SHOWCASE_UPDATE.ps1 @@ -0,0 +1,109 @@ +param( + [string]$Root = "E:\WireJS", + [switch]$SkipValidation +) + +$ErrorActionPreference = "Stop" +$PackageRoot = Split-Path -Parent $MyInvocation.MyCommand.Path +$Root = [System.IO.Path]::GetFullPath($Root) + +if (-not (Test-Path (Join-Path $Root "packages\ui\components"))) { + throw "WRNexusJS repository was not found at: $Root" +} + +$timestamp = Get-Date -Format "yyyyMMdd-HHmmss" +$backupRoot = Join-Path $Root ".wrnexus\component-showcase-backup-$timestamp" +New-Item -ItemType Directory -Path $backupRoot -Force | Out-Null + +$files = @( + "scripts/generate-ui-component-reference.mjs", + "packages/ui/component-catalog.json", + "examples/component-showcase/scripts/generate-showcase.mjs", + "examples/component-showcase/scripts/showcase-profiles.mjs", + "examples/component-showcase/public/playground.js", + "examples/component-showcase/app/styles/global.css", + "examples/component-showcase/test/showcase.test.ts", + "examples/component-showcase/README.md" +) + +$generatedFiles = @( + "packages/ui/component-reference.json", + "packages/ui/COMPONENTS.md", + "examples/component-showcase/showcase-manifest.json" +) + +function Convert-RelativePath([string]$relative) { + return $relative.Replace("/", [System.IO.Path]::DirectorySeparatorChar) +} + +function Backup-Path([string]$relative) { + $platformPath = Convert-RelativePath $relative + $source = Join-Path $Root $platformPath + if (-not (Test-Path $source)) { return } + + $destination = Join-Path $backupRoot $platformPath + $destinationParent = Split-Path -Parent $destination + New-Item -ItemType Directory -Path $destinationParent -Force | Out-Null + Copy-Item $source $destination -Recurse -Force +} + +foreach ($relative in $files) { Backup-Path $relative } +foreach ($relative in $generatedFiles) { Backup-Path $relative } +Backup-Path "examples/component-showcase/app/pages" +Backup-Path "examples/component-showcase/app/layouts" + +foreach ($relative in $files) { + $platformPath = Convert-RelativePath $relative + $source = Join-Path $PackageRoot $platformPath + $destination = Join-Path $Root $platformPath + if (-not (Test-Path $source)) { + throw "Patch file is missing: $source" + } + New-Item -ItemType Directory -Path (Split-Path -Parent $destination) -Force | Out-Null + Copy-Item $source $destination -Force + Write-Host "Updated $relative" -ForegroundColor Green +} + +function Invoke-BunStep { + param( + [string]$Label, + [string[]]$Arguments + ) + Write-Host "`n$Label" -ForegroundColor Cyan + & bun @Arguments + if ($LASTEXITCODE -ne 0) { + throw "$Label failed with exit code $LASTEXITCODE." + } +} + +Push-Location $Root +try { + Invoke-BunStep "Generating the current UI component reference" @( + "run", + "scripts/generate-ui-component-reference.mjs" + ) + + $showcaseRoot = Join-Path $Root "examples\component-showcase" + Remove-Item (Join-Path $showcaseRoot ".wrnexus") -Recurse -Force -ErrorAction SilentlyContinue + Remove-Item (Join-Path $showcaseRoot "dist") -Recurse -Force -ErrorAction SilentlyContinue + + Push-Location $showcaseRoot + try { + Invoke-BunStep "Generating component showcase pages and manifest" @("run", "generate") + if (-not $SkipValidation) { + Invoke-BunStep "Validating the complete component showcase" @("run", "check") + } + } + finally { + Pop-Location + } +} +finally { + Pop-Location +} + +Write-Host "`nComponent showcase update applied successfully." -ForegroundColor Green +Write-Host "Backup: $backupRoot" +if ($SkipValidation) { + Write-Host "Validation was skipped. Run: bun run --cwd examples/component-showcase check" -ForegroundColor Yellow +} diff --git a/APPLY_OVERLAY_REACTIVITY_FIX.ps1 b/APPLY_OVERLAY_REACTIVITY_FIX.ps1 new file mode 100644 index 00000000..681b8342 --- /dev/null +++ b/APPLY_OVERLAY_REACTIVITY_FIX.ps1 @@ -0,0 +1,36 @@ +param( + [Parameter(Mandatory = $false)] + [string]$Root = "E:\WireJS" +) + +$ErrorActionPreference = "Stop" +$Root = (Resolve-Path $Root).Path +$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path + +Write-Host "Stopping Bun processes..." -ForegroundColor Cyan +Get-Process bun -ErrorAction SilentlyContinue | Stop-Process -Force + +Write-Host "Applying overlay reactivity fix..." -ForegroundColor Cyan +node (Join-Path $ScriptDir "patch-overlay-showcase.mjs") $Root + +Push-Location $Root +try { + Write-Host "Regenerating UI component reference..." -ForegroundColor Cyan + bun run scripts/generate-ui-component-reference.mjs + + Write-Host "Running focused UI tests..." -ForegroundColor Cyan + bun test packages/ui/test/overlay-reactivity.test.ts + + Push-Location (Join-Path $Root "examples\component-showcase") + try { + Write-Host "Regenerating showcase..." -ForegroundColor Cyan + bun run generate + bun test test/showcase.test.ts + } finally { + Pop-Location + } +} finally { + Pop-Location +} + +Write-Host "Done. Start with: cd E:\WireJS\examples\component-showcase; bun run dev" -ForegroundColor Green diff --git a/PATCH_MANIFEST.json b/PATCH_MANIFEST.json new file mode 100644 index 00000000..0baeae51 --- /dev/null +++ b/PATCH_MANIFEST.json @@ -0,0 +1,23 @@ +{ + "name": "WRNexusJS component showcase complete update", + "scope": "examples/component-showcase and UI catalog generation", + "files": [ + "scripts/generate-ui-component-reference.mjs", + "packages/ui/component-catalog.json", + "examples/component-showcase/scripts/generate-showcase.mjs", + "examples/component-showcase/scripts/showcase-profiles.mjs", + "examples/component-showcase/public/playground.js", + "examples/component-showcase/app/styles/global.css", + "examples/component-showcase/test/showcase.test.ts", + "examples/component-showcase/README.md" + ], + "generatedAfterApply": [ + "packages/ui/component-reference.json", + "packages/ui/COMPONENTS.md", + "examples/component-showcase/showcase-manifest.json", + "examples/component-showcase/app/layouts/showcase.wrn", + "examples/component-showcase/app/layouts/document.wrn", + "examples/component-showcase/app/pages/*.wrn", + "examples/component-showcase/app/pages/components/*.wrn" + ] +} diff --git a/README.md b/README.md index eee8aea3..bec7c050 100644 --- a/README.md +++ b/README.md @@ -1,39 +1,9 @@ -# WRNexusJS +# WRNexus overlay reactivity and event-log fix -WRNexusJS is an SSR-first, Bun-powered full-stack framework with a dedicated `.wrn` language, server rendering, selective client reactivity, file-based routing, database tooling, realtime communication, UI components, mobile support, and framework-native system packages. +This patch updates ContextMenu, Drawer, Dropdown, Modal, Popover, and Tooltip. -## WRNexusJS 0.4.0 +The click/hover/right-click handlers were running and public events were emitted, but the visible DOM bindings depended on `isOpen()` helper calls. The updated component markup binds `data-open`, `data-show`, `aria-expanded`, and `aria-describedby` directly to `open || visible` so the reactive runtime subscribes to the exact state values controlling the overlay. -Version 0.4 introduces a package contribution platform. Installed `@wrnexus/*` systems can now register components, page/API/realtime routes, middleware, browser runtimes, static assets, Tailwind scan sources, database migrations, CLI inspection data, and DevToolbar panels. +The showcase event examples now log an event name plus a safe empty object when an event has no detail. Console output such as `open undefined` is debug output, not a thrown exception. -A package-owned browser runtime is injected only when rendered markup asks for it: - -```wrn - -``` - -`@wrnexus/captcha` marks its output with `data-wrnexus-runtime="captcha"`. WRNexusJS then serves or bundles the package runtime and adds the correct script to the response. Applications no longer copy `captcha.js`, add script tags, or duplicate `Captcha.wrn` inside `@wrnexus/ui`. - -## Development - -```bash -bun install -bun run verify:0.4 -bun run validate:0.4 -``` - -The complete validation command runs framework typechecking, linting, package tests, formatting checks, integration tests, example tests/builds, CAPTCHA showcase checks, and managed CAPTCHA service tests. - -## Main packages - -The monorepo contains 30 framework packages covering the language/compiler, SSR/CSR, routing, server runtime, plugins, database access, queues, PubSub, uploads, validation, security, UI, mobile/native capabilities, AI, tracking, testing, and CAPTCHA. - -Read: - -- `docs/ARCHITECTURE-0.4.md` -- `docs/PACKAGE-RUNTIMES-0.4.md` -- `docs/PACKAGE-UPGRADES-0.4.md` -- `docs/UPGRADE-0.4.md` -- `docs/TEST-CHECKLIST-0.4.md` -- `packages/captcha/README.md` -- `CHANGELOG-0.4.0.md` +The red `Permissions policy violation: unload ... chext_driver.js` message comes from a browser extension/content script and is unrelated to WRNexusJS. diff --git a/README_APPLY.md b/README_APPLY.md new file mode 100644 index 00000000..9e3dcbeb --- /dev/null +++ b/README_APPLY.md @@ -0,0 +1,119 @@ +# WRNexusJS component showcase complete update + +This patch upgrades `examples/component-showcase` so the showcase follows the +current `@wrnexus/ui` source automatically and documents the new and recently +repaired components through real detail-page examples. + +## Apply + +From the extracted patch directory: + +```powershell +powershell ` + -ExecutionPolicy Bypass ` + -File ".\APPLY_COMPONENT_SHOWCASE_UPDATE.ps1" ` + -Root "E:\WireJS" +``` + +The script backs up replaced source files, the generated component reference, +the generated pages, layouts, and showcase manifest under: + +```text +E:\WireJS\.wrnexus\component-showcase-backup- +``` + +It then regenerates the current UI reference, regenerates every showcase page, +and runs the component showcase check. Use `-SkipValidation` only when you need +to copy and generate first and validate manually afterward. + +## Main changes + +### Complete dynamic catalog + +- Generates one detail page for every unique component declaration. +- Deduplicates legacy lowercase component files in the reference generator and + prefers the canonical `.wrn` source. +- Uses only explicitly declared `@event ... = function` entries as the public + event contract. +- Generates `showcase-manifest.json` with component, category, demo, prop, slot, + event, and profile coverage. + +### Component-specific examples + +`scripts/showcase-profiles.mjs` contains production use cases for the new and +recently repaired components, including: + +- PublicPageShell, Section, SectionHeader, MarketingSectionHeader +- AnnouncementBar, Breadcrumb, PageHeader, TextLink +- Hero, HeroActions, SplitHero +- FeatureGrid, FeatureCard, FeatureIconCard +- MetricGrid, MetricCard, StatsBar +- CTASection, BackToTop, Footer +- ContextMenu, Drawer, Dropdown, Modal, Popover, Tooltip +- Container, Grid, Columns, Card, Link, Image, SearchBox, Map, List, Marquee, + Tabs, Timeline, Typography, and Divider + +Every other catalog component keeps responsive generated baseline examples. + +### Correct WRN source generation + +- Uses public component tags such as `` instead of legacy mounts. +- Self-closes components without slots and uses paired tags only when content is + present. +- Uses `data-slot="..."` for named WRNexusJS slots. +- Uses single-quoted dynamic WRN expressions in playground previews. +- Safely serializes arrays and objects without breaking on apostrophes in data + or data URLs. + +### Typed playground + +- Boolean controls preserve explicit `true` and `false` values. +- Number controls remain numbers. +- Array and object controls are validated JSON and remain structured values. +- Free-form props such as icons, labels, IDs, and URLs remain text inputs. +- Enum controls come from explicit public showcase profiles rather than source + comparisons, preventing false VS Code-style restrictions. +- Preview replacement uses `replaceChildren`, rehydrates WRN scopes, rebinds the + theme runtime, and never uses unsafe `innerHTML`. +- Interactive components display live `event.detail` output. + +### Responsive detail pages + +The showcase stylesheet now gives shell, hero, grid, statistics, CTA, footer, +and overlay components the correct preview width and height. In particular, +MetricGrid and FeatureGrid use the complete available stage instead of being +compressed into narrow cards. + +### Event documentation + +Every component with declared public events receives: + +- a complete event list +- declarative `.wrn` handler examples +- browser `addEventListener` examples +- live event output in the playground + +### Tests + +The test suite is manifest-driven rather than using hardcoded component or demo +counts. It verifies generated coverage, typed playground behavior, safe source +syntax, profile coverage, event documentation, responsive stages, specialized +form examples, and compilation of every generated page. + +## Manual commands + +```powershell +cd E:\WireJS +bun run scripts/generate-ui-component-reference.mjs + +cd E:\WireJS\examples\component-showcase +bun run generate +bun run test +bun run build +``` + +For the complete example validation: + +```powershell +bun run check +``` diff --git a/VALIDATION.md b/VALIDATION.md new file mode 100644 index 00000000..34740717 --- /dev/null +++ b/VALIDATION.md @@ -0,0 +1,30 @@ +# Validation performed in the artifact environment + +Validated on 2026-07-31 against the available repository snapshot plus the +latest component replacements from this conversation. + +Passed: + +- Node syntax validation for both generator scripts and the browser playground +- dynamic component-reference parsing and showcase generation +- manifest/detail/event consistency checks for every unique component present in + the artifact snapshot +- generation of category pages, detail pages, typed playgrounds, public event + documentation, and component-specific use cases +- compilation of all 127 generated `.wrn` pages in the artifact snapshot using + the available WRNexusJS compiler build +- safe public component tags, self-closing behavior, named `data-slot` markup, + single-quoted dynamic expressions, and apostrophe-safe structured props + +The artifact snapshot is older than the user's current working repository, so +its unique component count is not used as a release expectation. The patch has +no hardcoded component count: applying it regenerates the current reference and +all pages from the user's live `packages/ui/components` directory. + +Bun is not installed in the artifact execution environment. The apply script +therefore runs the authoritative local commands on the user's Windows checkout: + +```text +bun run scripts/generate-ui-component-reference.mjs +bun run --cwd examples/component-showcase check +``` diff --git a/bun.lock b/bun.lock index 1f667062..f2388f75 100644 --- a/bun.lock +++ b/bun.lock @@ -38,10 +38,13 @@ "dependencies": { "@wrnexus/core": "workspace:*", "@wrnexus/db": "workspace:*", + "@wrnexus/ui": "workspace:*", "@wrnexus/validation": "workspace:*", }, "devDependencies": { "@eslint/js": "latest", + "@iconify-json/lucide": "^1.2.118", + "@iconify/tailwind4": "^1.2.3", "@tailwindcss/cli": "^4.0.0", "@wrnexus/test": "workspace:*", "eslint": "latest", @@ -83,11 +86,11 @@ }, "packages/ai": { "name": "@wrnexus/ai", - "version": "0.5.10", + "version": "0.5.14", }, "packages/auth": { "name": "@wrnexus/auth", - "version": "0.5.10", + "version": "0.5.14", "dependencies": { "@wrnexus/authz": "workspace:*", "@wrnexus/captcha": "workspace:*", @@ -109,11 +112,11 @@ }, "packages/authz": { "name": "@wrnexus/authz", - "version": "0.5.10", + "version": "0.5.14", }, "packages/captcha": { "name": "@wrnexus/captcha", - "version": "0.5.10", + "version": "0.5.14", "dependencies": { "@wrnexus/core": "workspace:*", "@wrnexus/plugin": "workspace:*", @@ -127,7 +130,7 @@ }, "packages/cli": { "name": "@wrnexus/cli", - "version": "0.5.10", + "version": "0.5.14", "bin": { "wrnexus": "src/index.ts", }, @@ -148,29 +151,29 @@ }, "packages/compiler": { "name": "@wrnexus/compiler", - "version": "0.5.10", + "version": "0.5.14", "dependencies": { "@wrnexus/syntax": "workspace:*", }, }, "packages/core": { "name": "@wrnexus/core", - "version": "0.5.10", + "version": "0.5.14", }, "packages/csr": { "name": "@wrnexus/csr", - "version": "0.5.10", + "version": "0.5.14", "dependencies": { "@wrnexus/core": "workspace:*", }, }, "packages/db": { "name": "@wrnexus/db", - "version": "0.5.10", + "version": "0.5.14", }, "packages/dev-server": { "name": "@wrnexus/dev-server", - "version": "0.5.10", + "version": "0.5.14", "dependencies": { "@wrnexus/compiler": "workspace:*", "@wrnexus/core": "workspace:*", @@ -190,7 +193,7 @@ }, "packages/dev-toolbar": { "name": "@wrnexus/dev-toolbar", - "version": "0.5.10", + "version": "0.5.14", "devDependencies": { "@types/bun": "latest", "typescript": "^5.9.2", @@ -198,63 +201,63 @@ }, "packages/encryption": { "name": "@wrnexus/encryption", - "version": "0.5.10", + "version": "0.5.14", }, "packages/helpers": { "name": "@wrnexus/helpers", - "version": "0.5.10", + "version": "0.5.14", "dependencies": { "@wrnexus/core": "workspace:*", }, }, "packages/i18n": { "name": "@wrnexus/i18n", - "version": "0.5.10", + "version": "0.5.14", "dependencies": { "@wrnexus/core": "workspace:*", }, }, "packages/jwt": { "name": "@wrnexus/jwt", - "version": "0.5.10", + "version": "0.5.14", }, "packages/mobile": { "name": "@wrnexus/mobile", - "version": "0.5.10", + "version": "0.5.14", "dependencies": { "@wrnexus/native": "workspace:*", }, }, "packages/native": { "name": "@wrnexus/native", - "version": "0.5.10", + "version": "0.5.14", }, "packages/oauth": { "name": "@wrnexus/oauth", - "version": "0.5.10", + "version": "0.5.14", }, "packages/plugin": { "name": "@wrnexus/plugin", - "version": "0.5.10", + "version": "0.5.14", "dependencies": { "@wrnexus/syntax": "workspace:*", }, }, "packages/pubsub": { "name": "@wrnexus/pubsub", - "version": "0.5.10", + "version": "0.5.14", }, "packages/queue": { "name": "@wrnexus/queue", - "version": "0.5.10", + "version": "0.5.14", }, "packages/reactive": { "name": "@wrnexus/reactive", - "version": "0.5.10", + "version": "0.5.14", }, "packages/router": { "name": "@wrnexus/router", - "version": "0.5.10", + "version": "0.5.14", "dependencies": { "@wrnexus/compiler": "workspace:*", "@wrnexus/core": "workspace:*", @@ -262,14 +265,14 @@ }, "packages/ssr": { "name": "@wrnexus/ssr", - "version": "0.5.10", + "version": "0.5.14", "dependencies": { "@wrnexus/core": "workspace:*", }, }, "packages/styles": { "name": "@wrnexus/styles", - "version": "0.5.10", + "version": "0.5.14", "dependencies": { "@wrnexus/core": "workspace:*", "@wrnexus/plugin": "workspace:*", @@ -278,33 +281,33 @@ }, "packages/syntax": { "name": "@wrnexus/syntax", - "version": "0.5.10", + "version": "0.5.14", }, "packages/test": { "name": "@wrnexus/test", - "version": "0.5.10", + "version": "0.5.14", }, "packages/tracking": { "name": "@wrnexus/tracking", - "version": "0.5.10", + "version": "0.5.14", }, "packages/ui": { "name": "@wrnexus/ui", - "version": "0.5.10", + "version": "0.5.14", "dependencies": { "@wrnexus/core": "workspace:*", }, }, "packages/uploader": { "name": "@wrnexus/uploader", - "version": "0.5.10", + "version": "0.5.14", "dependencies": { "@wrnexus/core": "workspace:*", }, }, "packages/validation": { "name": "@wrnexus/validation", - "version": "0.5.10", + "version": "0.5.14", }, "services/managed-captcha": { "name": "@wrnexus/managed-captcha-service", @@ -948,9 +951,9 @@ "@typescript-eslint/eslint-plugin/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="], - "basic-app/eslint": ["eslint@10.7.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.2", "@eslint/config-array": "^0.23.5", "@eslint/config-helpers": "^0.6.0", "@eslint/core": "^1.2.1", "@eslint/plugin-kit": "^0.7.2", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", "ajv": "^6.14.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", "eslint-scope": "^9.1.2", "eslint-visitor-keys": "^5.0.1", "espree": "^11.2.0", "esquery": "^1.7.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", "minimatch": "^10.2.4", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, "peerDependencies": { "jiti": "*" }, "optionalPeers": ["jiti"], "bin": { "eslint": "bin/eslint.js" } }, "sha512-GVTD7s1vdIl6UYvAfriOPeY1Df8LIZjfofLvHwde+erDHGGuHyuM6xoxRxmHiebhYuD2p1vN4wWh0XzPARSGDQ=="], + "basic-app/eslint": ["eslint@10.8.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.2", "@eslint/config-array": "^0.23.5", "@eslint/config-helpers": "^0.7.0", "@eslint/core": "^1.2.1", "@eslint/plugin-kit": "^0.7.2", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", "ajv": "^6.14.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", "eslint-scope": "^9.1.2", "eslint-visitor-keys": "^5.0.1", "espree": "^11.2.0", "esquery": "^1.7.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", "minimatch": "^10.2.5", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, "peerDependencies": { "jiti": "*" }, "optionalPeers": ["jiti"], "bin": { "eslint": "bin/eslint.js" } }, "sha512-nuKKvN+oIBO0koN7Tm7dlkmnkc21mtt0QJLwAKzjLq14y6lRTdVG36MZHJ8eQHwdJMwZbQNMlPOYedMq/oVJvQ=="], - "basic-app/typescript-eslint": ["typescript-eslint@8.63.0", "", { "dependencies": { "@typescript-eslint/eslint-plugin": "8.63.0", "@typescript-eslint/parser": "8.63.0", "@typescript-eslint/typescript-estree": "8.63.0", "@typescript-eslint/utils": "8.63.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "sha512-xgwXyzG4sK9ALkBxbyGkTMMOS+imnW65iPhxCQMK83KhxyoDNW7l+IDqEf9vMdoUidHpOoS967RCq4eMiTexwQ=="], + "basic-app/typescript-eslint": ["typescript-eslint@8.65.0", "", { "dependencies": { "@typescript-eslint/eslint-plugin": "8.65.0", "@typescript-eslint/parser": "8.65.0", "@typescript-eslint/typescript-estree": "8.65.0", "@typescript-eslint/utils": "8.65.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "sha512-/ggrHAwyjENDusvyxbuqxAC2dTnZg/Z8F+fgQtYIz+L6n/9HfSlEZcFGV/NsMNa6CkGk0xUjUAFwC0vHOflvIA=="], "component-showcase/@iconify-json/lucide": ["@iconify-json/lucide@1.2.118", "", { "dependencies": { "@iconify/types": "*" } }, "sha512-JBnK4YOq6K/lA0JP//27QxFxJ4120TjvfXAzGZZIGjCcXcRRRFxl1rcV7+IWdcVCe90KXdqVaAwLaLf6G3HELw=="], @@ -964,48 +967,50 @@ "svgo/commander": ["commander@11.1.0", "", {}, "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ=="], - "basic-app/typescript-eslint/@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.63.0", "", { "dependencies": { "@eslint-community/regexpp": "^4.12.2", "@typescript-eslint/scope-manager": "8.63.0", "@typescript-eslint/type-utils": "8.63.0", "@typescript-eslint/utils": "8.63.0", "@typescript-eslint/visitor-keys": "8.63.0", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.5.0" }, "peerDependencies": { "@typescript-eslint/parser": "^8.63.0", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "sha512-rvwSgqT+DHpWdzfSzPatRLm02a0GlESt++9iy3hLCDY4BgkaLcl8LBi9Yh7XGFBpwcBE/K3024QuXWTpbz4FfQ=="], + "basic-app/eslint/@eslint/config-helpers": ["@eslint/config-helpers@0.7.0", "", { "dependencies": { "@eslint/core": "^1.2.1" } }, "sha512-DObd/KKUsU+FaFv4PLxSRenpXfQWmPXXP3pPZ6/K1PCrMu2vQpMDMuQe/BqYeoLcz8ro0bVDF1RxOJgfVEdhUw=="], - "basic-app/typescript-eslint/@typescript-eslint/parser": ["@typescript-eslint/parser@8.63.0", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.63.0", "@typescript-eslint/types": "8.63.0", "@typescript-eslint/typescript-estree": "8.63.0", "@typescript-eslint/visitor-keys": "8.63.0", "debug": "^4.4.3" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "sha512-gwh4gvvlaVDKKxyfxMG+Gnu1u9X0OQBwyGLkbwB65dIzBKnxeRiJlNFqlI3zwVhNXJIs6qV7mlFCn/BIajlVig=="], + "basic-app/typescript-eslint/@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.65.0", "", { "dependencies": { "@eslint-community/regexpp": "^4.12.2", "@typescript-eslint/scope-manager": "8.65.0", "@typescript-eslint/type-utils": "8.65.0", "@typescript-eslint/utils": "8.65.0", "@typescript-eslint/visitor-keys": "8.65.0", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.5.0" }, "peerDependencies": { "@typescript-eslint/parser": "^8.65.0", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "sha512-IEgob78X12rHpUmtcwFsXhZdVGJtwTVP8FiCLZkR6GlYVrl2PcuB+KhCE5BlVC/eQpQnu8WXRtkHZuPar+gCRA=="], - "basic-app/typescript-eslint/@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.63.0", "", { "dependencies": { "@typescript-eslint/project-service": "8.63.0", "@typescript-eslint/tsconfig-utils": "8.63.0", "@typescript-eslint/types": "8.63.0", "@typescript-eslint/visitor-keys": "8.63.0", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", "tinyglobby": "^0.2.15", "ts-api-utils": "^2.5.0" }, "peerDependencies": { "typescript": ">=4.8.4 <6.1.0" } }, "sha512-ygBkU+B7ex5UI/gKhaqexWev79uISfIv7XQCRNYO/jmD8rGLPyWLAb3KMRT6nd8Gt9bmUBi9+iX6tBdYfOY81Q=="], + "basic-app/typescript-eslint/@typescript-eslint/parser": ["@typescript-eslint/parser@8.65.0", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.65.0", "@typescript-eslint/types": "8.65.0", "@typescript-eslint/typescript-estree": "8.65.0", "@typescript-eslint/visitor-keys": "8.65.0", "debug": "^4.4.3" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "sha512-CZ4nMxWwgu1HEEFNkeaCptra9QCtkmKdgf3sWh1rl1trIhmxLilgTV4cwcbQ4wemnT4sWQN8CaKOmdYx+g2gMA=="], - "basic-app/typescript-eslint/@typescript-eslint/utils": ["@typescript-eslint/utils@8.63.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", "@typescript-eslint/scope-manager": "8.63.0", "@typescript-eslint/types": "8.63.0", "@typescript-eslint/typescript-estree": "8.63.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "sha512-fUKaeAvrTuQg/Tgt3nliAUSZHJM6DlCcfyEmxCvlX8kieWSStBX+5O5Fnidtc3i2JrH+9c/GL4RY2iasd/GPTA=="], + "basic-app/typescript-eslint/@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.65.0", "", { "dependencies": { "@typescript-eslint/project-service": "8.65.0", "@typescript-eslint/tsconfig-utils": "8.65.0", "@typescript-eslint/types": "8.65.0", "@typescript-eslint/visitor-keys": "8.65.0", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", "tinyglobby": "^0.2.15", "ts-api-utils": "^2.5.0" }, "peerDependencies": { "typescript": ">=4.8.4 <6.1.0" } }, "sha512-JboAE2swaYt4tb1fHhHTABE2K+OLy09XfcTbhnk4Pw96f9dd2e9iYsJ28gBggHlo5z5x1rkyWvcPoTuNTd4oGg=="], + + "basic-app/typescript-eslint/@typescript-eslint/utils": ["@typescript-eslint/utils@8.65.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", "@typescript-eslint/scope-manager": "8.65.0", "@typescript-eslint/types": "8.65.0", "@typescript-eslint/typescript-estree": "8.65.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "sha512-gXiwIHsYreboxeJucHKPvgwl7dXt50mF8s1/c00cP/WoVTyWKFdtfhRWwZiXYFU5H2O8vVoSLNrexFZjYS/SGA=="], "csso/css-tree/mdn-data": ["mdn-data@2.0.28", "", {}, "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g=="], - "basic-app/typescript-eslint/@typescript-eslint/eslint-plugin/@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.63.0", "", { "dependencies": { "@typescript-eslint/types": "8.63.0", "@typescript-eslint/visitor-keys": "8.63.0" } }, "sha512-uUyfMWCnDSN8bCpcrY8nGP2BLkQ9Xn0GsipcONcpIDWhwhO4ZSyHvyS14U3X75mzxWxL3I2UZIrenTzdzcJO8A=="], + "basic-app/typescript-eslint/@typescript-eslint/eslint-plugin/@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.65.0", "", { "dependencies": { "@typescript-eslint/types": "8.65.0", "@typescript-eslint/visitor-keys": "8.65.0" } }, "sha512-Esbl8OSYiVxBokYgWPf7VVWg/BE798wXhimnn9ML9Pt5qoDf8bfQlgjlKXR/k98+AcNzlLKYrpCcrcuZ9DZLgg=="], - "basic-app/typescript-eslint/@typescript-eslint/eslint-plugin/@typescript-eslint/type-utils": ["@typescript-eslint/type-utils@8.63.0", "", { "dependencies": { "@typescript-eslint/types": "8.63.0", "@typescript-eslint/typescript-estree": "8.63.0", "@typescript-eslint/utils": "8.63.0", "debug": "^4.4.3", "ts-api-utils": "^2.5.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "sha512-Nzzh/OGxVCOjObjaj1CQF2RUasyYy2Jfuh+zZ3PjLzG2fYRriAiZLib9UKtO+CpQAS3YHiAS+ckZDclwqI1TPA=="], + "basic-app/typescript-eslint/@typescript-eslint/eslint-plugin/@typescript-eslint/type-utils": ["@typescript-eslint/type-utils@8.65.0", "", { "dependencies": { "@typescript-eslint/types": "8.65.0", "@typescript-eslint/typescript-estree": "8.65.0", "@typescript-eslint/utils": "8.65.0", "debug": "^4.4.3", "ts-api-utils": "^2.5.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "sha512-YjaZ7PRI5qY7ax2L3PbvX0rRyGtipAReCWs0mhhDBHjH/vl0g0BonaGXrKdKpMbIIsMIwDgbk/xzkBTyAltS5g=="], - "basic-app/typescript-eslint/@typescript-eslint/eslint-plugin/@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.63.0", "", { "dependencies": { "@typescript-eslint/types": "8.63.0", "eslint-visitor-keys": "^5.0.0" } }, "sha512-UexrHGnGTpbuQHct2ExOc2ZcFbGUS9FOesCxxqdBGcpI1BxYu/LZ6U8Aq6/72XtF/qRBk9nhuGHFJIXXMhPMdw=="], + "basic-app/typescript-eslint/@typescript-eslint/eslint-plugin/@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.65.0", "", { "dependencies": { "@typescript-eslint/types": "8.65.0", "eslint-visitor-keys": "^5.0.0" } }, "sha512-8C71BQkGjiMmXtop7pHVJu1l2NNShFdkCyD6a2ezzs5vU/L3LRtb69EtcteFwz0mYMPzIgOw0n6OV4VBUWZd7A=="], "basic-app/typescript-eslint/@typescript-eslint/eslint-plugin/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="], - "basic-app/typescript-eslint/@typescript-eslint/parser/@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.63.0", "", { "dependencies": { "@typescript-eslint/types": "8.63.0", "@typescript-eslint/visitor-keys": "8.63.0" } }, "sha512-uUyfMWCnDSN8bCpcrY8nGP2BLkQ9Xn0GsipcONcpIDWhwhO4ZSyHvyS14U3X75mzxWxL3I2UZIrenTzdzcJO8A=="], + "basic-app/typescript-eslint/@typescript-eslint/parser/@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.65.0", "", { "dependencies": { "@typescript-eslint/types": "8.65.0", "@typescript-eslint/visitor-keys": "8.65.0" } }, "sha512-Esbl8OSYiVxBokYgWPf7VVWg/BE798wXhimnn9ML9Pt5qoDf8bfQlgjlKXR/k98+AcNzlLKYrpCcrcuZ9DZLgg=="], - "basic-app/typescript-eslint/@typescript-eslint/parser/@typescript-eslint/types": ["@typescript-eslint/types@8.63.0", "", {}, "sha512-xyLtl9DUBBFrcJS4x2pIqGLH68/tC2uOa4Z7pUteW09D3bXnnXUom4dyPikzWgB7llmIc1zoeI3aoUdC4rPK/Q=="], + "basic-app/typescript-eslint/@typescript-eslint/parser/@typescript-eslint/types": ["@typescript-eslint/types@8.65.0", "", {}, "sha512-JSSwWNy+H0E/01jJEM+hrX6N0OFDzFzeIhHFSAS01tlVaevpG8cFyYRPhS5yjGOvBUx3sqQHVMjCL1CAZZMxBg=="], - "basic-app/typescript-eslint/@typescript-eslint/parser/@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.63.0", "", { "dependencies": { "@typescript-eslint/types": "8.63.0", "eslint-visitor-keys": "^5.0.0" } }, "sha512-UexrHGnGTpbuQHct2ExOc2ZcFbGUS9FOesCxxqdBGcpI1BxYu/LZ6U8Aq6/72XtF/qRBk9nhuGHFJIXXMhPMdw=="], + "basic-app/typescript-eslint/@typescript-eslint/parser/@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.65.0", "", { "dependencies": { "@typescript-eslint/types": "8.65.0", "eslint-visitor-keys": "^5.0.0" } }, "sha512-8C71BQkGjiMmXtop7pHVJu1l2NNShFdkCyD6a2ezzs5vU/L3LRtb69EtcteFwz0mYMPzIgOw0n6OV4VBUWZd7A=="], - "basic-app/typescript-eslint/@typescript-eslint/typescript-estree/@typescript-eslint/project-service": ["@typescript-eslint/project-service@8.63.0", "", { "dependencies": { "@typescript-eslint/tsconfig-utils": "^8.63.0", "@typescript-eslint/types": "^8.63.0", "debug": "^4.4.3" }, "peerDependencies": { "typescript": ">=4.8.4 <6.1.0" } }, "sha512-e5dh0/UI0ok53AlZ5wRkXCB32z/f2jUZqPR/ygAw5WYaSw8j9EoJWlS7wQjr/dmOaqWjnPIn2m+HhVPCMWGZVQ=="], + "basic-app/typescript-eslint/@typescript-eslint/typescript-estree/@typescript-eslint/project-service": ["@typescript-eslint/project-service@8.65.0", "", { "dependencies": { "@typescript-eslint/tsconfig-utils": "^8.65.0", "@typescript-eslint/types": "^8.65.0", "debug": "^4.4.3" }, "peerDependencies": { "typescript": ">=4.8.4 <6.1.0" } }, "sha512-SxnPhbTsGahizDgbu7oqFH/xVtzIqMd/s+WtnSxNxJZJpLbdT5IPdzg8EZxO3+PoKahXmwJLeNQOpKJb3/bi7Q=="], - "basic-app/typescript-eslint/@typescript-eslint/typescript-estree/@typescript-eslint/tsconfig-utils": ["@typescript-eslint/tsconfig-utils@8.63.0", "", { "peerDependencies": { "typescript": ">=4.8.4 <6.1.0" } }, "sha512-sUAbkulqBAsncKnbRP3+7CtQFRKicexnj7ZwNC6ddCR7EmrXvjvdCYMJbUIqMd6lwoEriZjwLo08aS5tSjVMHg=="], + "basic-app/typescript-eslint/@typescript-eslint/typescript-estree/@typescript-eslint/tsconfig-utils": ["@typescript-eslint/tsconfig-utils@8.65.0", "", { "peerDependencies": { "typescript": ">=4.8.4 <6.1.0" } }, "sha512-j6GzGqCiRdA7Qhur2VVmKZAkBLfnHFQfx4TaJGL9RMveZqCo48jSHHO0DTgizEnGhtWnqmbtCUSrqSkdiY/0Hg=="], - "basic-app/typescript-eslint/@typescript-eslint/typescript-estree/@typescript-eslint/types": ["@typescript-eslint/types@8.63.0", "", {}, "sha512-xyLtl9DUBBFrcJS4x2pIqGLH68/tC2uOa4Z7pUteW09D3bXnnXUom4dyPikzWgB7llmIc1zoeI3aoUdC4rPK/Q=="], + "basic-app/typescript-eslint/@typescript-eslint/typescript-estree/@typescript-eslint/types": ["@typescript-eslint/types@8.65.0", "", {}, "sha512-JSSwWNy+H0E/01jJEM+hrX6N0OFDzFzeIhHFSAS01tlVaevpG8cFyYRPhS5yjGOvBUx3sqQHVMjCL1CAZZMxBg=="], - "basic-app/typescript-eslint/@typescript-eslint/typescript-estree/@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.63.0", "", { "dependencies": { "@typescript-eslint/types": "8.63.0", "eslint-visitor-keys": "^5.0.0" } }, "sha512-UexrHGnGTpbuQHct2ExOc2ZcFbGUS9FOesCxxqdBGcpI1BxYu/LZ6U8Aq6/72XtF/qRBk9nhuGHFJIXXMhPMdw=="], + "basic-app/typescript-eslint/@typescript-eslint/typescript-estree/@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.65.0", "", { "dependencies": { "@typescript-eslint/types": "8.65.0", "eslint-visitor-keys": "^5.0.0" } }, "sha512-8C71BQkGjiMmXtop7pHVJu1l2NNShFdkCyD6a2ezzs5vU/L3LRtb69EtcteFwz0mYMPzIgOw0n6OV4VBUWZd7A=="], - "basic-app/typescript-eslint/@typescript-eslint/utils/@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.63.0", "", { "dependencies": { "@typescript-eslint/types": "8.63.0", "@typescript-eslint/visitor-keys": "8.63.0" } }, "sha512-uUyfMWCnDSN8bCpcrY8nGP2BLkQ9Xn0GsipcONcpIDWhwhO4ZSyHvyS14U3X75mzxWxL3I2UZIrenTzdzcJO8A=="], + "basic-app/typescript-eslint/@typescript-eslint/utils/@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.65.0", "", { "dependencies": { "@typescript-eslint/types": "8.65.0", "@typescript-eslint/visitor-keys": "8.65.0" } }, "sha512-Esbl8OSYiVxBokYgWPf7VVWg/BE798wXhimnn9ML9Pt5qoDf8bfQlgjlKXR/k98+AcNzlLKYrpCcrcuZ9DZLgg=="], - "basic-app/typescript-eslint/@typescript-eslint/utils/@typescript-eslint/types": ["@typescript-eslint/types@8.63.0", "", {}, "sha512-xyLtl9DUBBFrcJS4x2pIqGLH68/tC2uOa4Z7pUteW09D3bXnnXUom4dyPikzWgB7llmIc1zoeI3aoUdC4rPK/Q=="], + "basic-app/typescript-eslint/@typescript-eslint/utils/@typescript-eslint/types": ["@typescript-eslint/types@8.65.0", "", {}, "sha512-JSSwWNy+H0E/01jJEM+hrX6N0OFDzFzeIhHFSAS01tlVaevpG8cFyYRPhS5yjGOvBUx3sqQHVMjCL1CAZZMxBg=="], - "basic-app/typescript-eslint/@typescript-eslint/eslint-plugin/@typescript-eslint/scope-manager/@typescript-eslint/types": ["@typescript-eslint/types@8.63.0", "", {}, "sha512-xyLtl9DUBBFrcJS4x2pIqGLH68/tC2uOa4Z7pUteW09D3bXnnXUom4dyPikzWgB7llmIc1zoeI3aoUdC4rPK/Q=="], + "basic-app/typescript-eslint/@typescript-eslint/eslint-plugin/@typescript-eslint/scope-manager/@typescript-eslint/types": ["@typescript-eslint/types@8.65.0", "", {}, "sha512-JSSwWNy+H0E/01jJEM+hrX6N0OFDzFzeIhHFSAS01tlVaevpG8cFyYRPhS5yjGOvBUx3sqQHVMjCL1CAZZMxBg=="], - "basic-app/typescript-eslint/@typescript-eslint/eslint-plugin/@typescript-eslint/type-utils/@typescript-eslint/types": ["@typescript-eslint/types@8.63.0", "", {}, "sha512-xyLtl9DUBBFrcJS4x2pIqGLH68/tC2uOa4Z7pUteW09D3bXnnXUom4dyPikzWgB7llmIc1zoeI3aoUdC4rPK/Q=="], + "basic-app/typescript-eslint/@typescript-eslint/eslint-plugin/@typescript-eslint/type-utils/@typescript-eslint/types": ["@typescript-eslint/types@8.65.0", "", {}, "sha512-JSSwWNy+H0E/01jJEM+hrX6N0OFDzFzeIhHFSAS01tlVaevpG8cFyYRPhS5yjGOvBUx3sqQHVMjCL1CAZZMxBg=="], - "basic-app/typescript-eslint/@typescript-eslint/eslint-plugin/@typescript-eslint/visitor-keys/@typescript-eslint/types": ["@typescript-eslint/types@8.63.0", "", {}, "sha512-xyLtl9DUBBFrcJS4x2pIqGLH68/tC2uOa4Z7pUteW09D3bXnnXUom4dyPikzWgB7llmIc1zoeI3aoUdC4rPK/Q=="], + "basic-app/typescript-eslint/@typescript-eslint/eslint-plugin/@typescript-eslint/visitor-keys/@typescript-eslint/types": ["@typescript-eslint/types@8.65.0", "", {}, "sha512-JSSwWNy+H0E/01jJEM+hrX6N0OFDzFzeIhHFSAS01tlVaevpG8cFyYRPhS5yjGOvBUx3sqQHVMjCL1CAZZMxBg=="], - "basic-app/typescript-eslint/@typescript-eslint/utils/@typescript-eslint/scope-manager/@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.63.0", "", { "dependencies": { "@typescript-eslint/types": "8.63.0", "eslint-visitor-keys": "^5.0.0" } }, "sha512-UexrHGnGTpbuQHct2ExOc2ZcFbGUS9FOesCxxqdBGcpI1BxYu/LZ6U8Aq6/72XtF/qRBk9nhuGHFJIXXMhPMdw=="], + "basic-app/typescript-eslint/@typescript-eslint/utils/@typescript-eslint/scope-manager/@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.65.0", "", { "dependencies": { "@typescript-eslint/types": "8.65.0", "eslint-visitor-keys": "^5.0.0" } }, "sha512-8C71BQkGjiMmXtop7pHVJu1l2NNShFdkCyD6a2ezzs5vU/L3LRtb69EtcteFwz0mYMPzIgOw0n6OV4VBUWZd7A=="], } } diff --git a/examples/basic-app/app/components/Modal.wrn b/examples/basic-app/app/components/Modal.wrn new file mode 100644 index 00000000..e7829160 --- /dev/null +++ b/examples/basic-app/app/components/Modal.wrn @@ -0,0 +1,121 @@ +component Modal { + props { + @event onConfirmed = function + } + + state isOpen = false + + functions { + function confirmed() { + isOpen = false; + if(onConfirmed) { + onConfirmed() + } + } + } + + view { +
+ + +
+
+
+
+ +
+
+ +
+
+
+

+ Transparent Modal +

+ +

+ Welcome to WRNexusJS +

+ +

+ This modal uses a transparent glass background with blur, + soft borders, and theme-aware colors. +

+
+ + +
+ +
+

+ You can place forms, confirmation messages, account details, + images, or any other component inside this modal. +

+
+ +
+ + + +
+
+
+
+
+ } + + style { + } +} diff --git a/examples/basic-app/app/layouts/document.wrn b/examples/basic-app/app/layouts/document.wrn new file mode 100644 index 00000000..3a2d0cdc --- /dev/null +++ b/examples/basic-app/app/layouts/document.wrn @@ -0,0 +1,26 @@ +// Global document layout. The framework renders this once around the selected +// page layout and merges SEO metadata, styles, and scripts into /. +// Request cookies, resolved theme, language, URL, and pathname are available +// as SSR props, so document attributes do not need a client-side correction. +layout Document { + props { + cookies = {} + theme = "light" + language = "en" + url = "" + pathname = "/" + } + + view { + + + +
+ +
+ + + } +} diff --git a/examples/basic-app/app/pages/modal.wrn b/examples/basic-app/app/pages/modal.wrn new file mode 100644 index 00000000..cf70249c --- /dev/null +++ b/examples/basic-app/app/pages/modal.wrn @@ -0,0 +1,14 @@ +page ModalPage { + + functions { + function onConfirmed() { + alert("User Confirmed") + } + } + + view { + + } +} diff --git a/examples/basic-app/app/pages/ui.wrn b/examples/basic-app/app/pages/ui.wrn index d83a3e93..1e3e150e 100644 --- a/examples/basic-app/app/pages/ui.wrn +++ b/examples/basic-app/app/pages/ui.wrn @@ -1,85 +1,991 @@ -// Wire UI showcase. Route: /ui. Every element below is a server-rendered -// component from @wrnexus/ui (auto-discovered), styled by theme tokens. page UI { - layout = "public" + state heroActions = [ + { + label: "Browse components", + href: "#component-01", + icon: "icon-[lucide--blocks]", + variant: "default", + color: "primary" + }, + { + label: "View metrics", + href: "#component-14", + icon: "icon-[lucide--chart-no-axes-combined]", + variant: "outline", + color: "primary" + } + ] + + state statsItems = [ + { + label: "Composite components", + value: "18", + description: "Shown separately with a practical use case", + icon: "icon-[lucide--blocks]", + color: "primary" + }, + { + label: "Rendering", + value: "SSR", + description: "Server-first WRNexusJS component rendering", + icon: "icon-[lucide--server]", + color: "info" + }, + { + label: "Responsive", + value: "Yes", + description: "Mobile, tablet, and desktop layouts", + icon: "icon-[lucide--monitor-smartphone]", + color: "success" + }, + { + label: "Theme aware", + value: "Yes", + description: "Supports active theme and accent palettes", + icon: "icon-[lucide--palette]", + color: "warning" + } + ] + + state featureItems = [ + { + icon: "icon-[lucide--shield-check]", + title: "Citizen services", + description: "Expose public safety and citizen-service capabilities.", + href: "/citizen-services", + actionLabel: "View services" + }, + { + icon: "icon-[lucide--map-pinned]", + title: "Station directory", + description: "Help visitors locate stations and jurisdiction contacts.", + href: "/contact/police-station-directory", + actionLabel: "Find station" + }, + { + icon: "icon-[lucide--radio-tower]", + title: "Public updates", + description: "Publish official alerts, notices, and verified information.", + href: "/media", + actionLabel: "View updates" + } + ] + + state metricItems = [ + { + label: "Public services", + value: "24", + description: "Citizen-facing services available online.", + icon: "icon-[lucide--hand-heart]", + trend: "+4", + trendLabel: "this release", + trendDirection: "up", + color: "primary" + }, + { + label: "Police stations", + value: "126", + description: "Searchable directory entries.", + icon: "icon-[lucide--landmark]", + trend: "Updated", + trendLabel: "today", + trendDirection: "neutral", + color: "info" + }, + { + label: "Availability", + value: "99.9", + suffix: "%", + description: "Target service availability.", + icon: "icon-[lucide--activity]", + trend: "Stable", + trendLabel: "30 days", + trendDirection: "positive", + color: "success" + } + ] + + state breadcrumbs = [ + { + label: "Home", + href: "/", + value: "home", + icon: "icon-[lucide--house]" + }, + { + label: "Components", + href: "/components", + value: "components" + }, + { + label: "Page header", + value: "page-header", + current: true + } + ] + + state heroVisualItems = [ + { + label: "Reusable components", + description: "Compose complete pages using shared UI.", + value: "108", + icon: "icon-[lucide--blocks]" + }, + { + label: "Theme support", + description: "Built for light, dark, and accent palettes.", + value: "Ready", + icon: "icon-[lucide--palette]" + }, + { + label: "Responsive layout", + description: "Optimized for mobile, tablet, and desktop.", + value: "100%", + icon: "icon-[lucide--monitor-smartphone]" + } + ] seo { - title = "Wire UI" - description = "Built-in Wire UI components and layout primitives." + title = "18 UI Components — Names and Use Cases" + description = "All 18 WRNexusJS composite UI components shown individually with their names and practical use cases." + canonical = "/ui-18-components" } view { -

Wire UI components

- -
-
- -
-
- Buttons -
-
-
-
-
-
+ +
+
+

+ 01. PublicPageShell +

+

+ PublicPageShell +

+

+ + Use case: + + Provide the outer structure for a complete public page, including maximum width, page background, overflow handling, before/after slots, and minimum-height behavior. +

+

+ This complete page is rendered inside PublicPageShell. +

-
-
- Badges -
-
-
-
+
+
+

+ 02. AnnouncementBar +

+

+ AnnouncementBar +

+

+ + Use case: Display an important site-wide update, emergency alert, release notice, or time-sensitive action above the primary page content. +

+
-
- Input -
-
-
- Spinner -
-
-
-
- -
-
- More components -
-
-
-
-
+
+
+

+ 03. PageHeader +

+

+ PageHeader +

+

+ + Use case: Introduce an internal or public page with an eyebrow, title, description, icon, breadcrumbs, and primary or secondary actions. +

+
+
-
- - - -
-
-
-
-
-

Hover this

tooltip trigger
.

-
- NameRole - AdaAdminGraceEditor -
-
-
-
+
+
+

+ 04. Hero +

+

+ Hero +

+

+ + Use case: Create the primary marketing or public-information introduction with headline emphasis, supporting content, trust items, actions, and an optional visual area. +

+
+ +
-
- Four ways, least to most control: change a theme token, redefine a - .wire-* class in your CSS, pass a class prop, or run - wrnexus eject <name> to copy the component into app/components. -
-
- } -} +
+
+

+ 05. HeroActions +

+

+ HeroActions +

+

+ + Use case: Group hero buttons with consistent alignment, mobile stacking, orientation, sizing, variants, and responsive behavior. +

+
+ +
+
+
+ +
+
+

+ 06. StatsBar +

+

+ StatsBar +

+

+ + Use case: Present a compact row of key facts, service counts, performance indicators, trust signals, or public portal statistics. +

+
+ +
+ +
+
+

+ 07. Section +

+

+ Section +

+

+ + Use case: Create predictable page sections with shared spacing, width constraints, surfaces, borders, and responsive vertical rhythm. +

+
+
+
+

+ Content placed inside a Section component +

+

+ The component owns spacing, surface, borders, and content width. +

+
+
+
+ +
+
+

+ 08. SectionHeader +

+

+ SectionHeader +

+

+ + Use case: Add a consistent heading block to content sections, including eyebrow text, description, icon slot, action slot, alignment, and heading level. +

+
+ +
+ + + +
+ +
+
+ +
+
+

+ 09. MarketingSectionHeader +

+

+ MarketingSectionHeader +

+

+ + Use case: Introduce marketing, services, solutions, features, benefits, case studies, or product sections with a prominent optional action. +

+
+ +
+ +
+
+

+ 10. TextLink +

+

+ TextLink +

+

+ + Use case: Provide a lightweight inline action for “view all,” “learn more,” “open documentation,” or related navigation without using a full button. +

+
+ +
+
+
+ +
+
+

+ 11. FeatureGrid +

+

+ FeatureGrid +

+

+ + Use case: Arrange services, features, solutions, benefits, or linked capabilities in a responsive equal-height grid. +

+
+ + {#each featureItems as item, index} + + {/each} + +
+ +
+
+

+ 12. FeatureCard +

+

+ FeatureCard +

+

+ + Use case: Present a linked feature or service with an icon, title, description, badge, visual variant, hover treatment, and action label. +

+
+
+ +
+
+ +
+
+

+ 13. FeatureIconCard +

+

+ FeatureIconCard +

+

+ + Use case: Highlight a capability where the icon treatment should carry stronger visual importance than a standard feature card. +

+
+
+ +
+
+ +
+
+

+ 14. MetricGrid +

+

+ MetricGrid +

+

+ + Use case: Arrange operational values, KPIs, public statistics, usage summaries, or service indicators in a responsive grid. +

+
+ +
+ +
+
+

+ 15. MetricCard +

+

+ MetricCard +

+

+ + Use case: Display one metric with a label, value, suffix, description, icon, trend, status direction, and optional action. +

+
+
+ +
+
+ +
+
+

+ 16. SplitHero +

+

+ SplitHero +

+

+ + Use case: Build a two-column introduction that balances descriptive content and a visual, screenshot, feature panel, image, map, or media block. +

+
+ +
+
+ +

+ Visual content area +

+

+ Add a product screenshot, service diagram, dashboard, image, or interactive preview. +

+
+
+
+
+ +
+
+

+ 17. CTASection +

+

+ CTASection +

+

+ + Use case: Close a page or major section with a strong conversion action such as registration, sign-in, contact, application, service request, or documentation access. +

+
+ +
+ +
+
+

+ 18. BackToTop +

+

+ BackToTop +

+

+ + Use case: Provide a floating control on long pages that returns visitors to the top and can optionally show scroll progress. +

+

+ Scroll down the page until the floating button becomes visible. +

+
+
+ +
+ +
+ + } + } diff --git a/examples/basic-app/app/styles/global.css b/examples/basic-app/app/styles/global.css index cb0c88e0..21912387 100644 --- a/examples/basic-app/app/styles/global.css +++ b/examples/basic-app/app/styles/global.css @@ -7,6 +7,7 @@ * components are `.wrn`/`.tsx` files under app/. Paths are relative to this file. */ @import "tailwindcss"; +@plugin "@iconify/tailwind4"; @source "../**/*.wrn"; @source "../**/*.tsx"; @@ -44,9 +45,7 @@ body { min-height: 100vh; display: flex; flex-direction: column; - max-width: var(--maxw); margin: 0 auto; - padding: 3rem 1.25rem; } h1 { diff --git a/examples/basic-app/package.json b/examples/basic-app/package.json index 55ea5544..03c8c5f0 100644 --- a/examples/basic-app/package.json +++ b/examples/basic-app/package.json @@ -17,11 +17,14 @@ "dependencies": { "@wrnexus/core": "workspace:*", "@wrnexus/validation": "workspace:*", - "@wrnexus/db": "workspace:*" + "@wrnexus/db": "workspace:*", + "@wrnexus/ui": "workspace:*" }, "devDependencies": { "@wrnexus/test": "workspace:*", "@eslint/js": "latest", + "@iconify-json/lucide": "^1.2.118", + "@iconify/tailwind4": "^1.2.3", "@tailwindcss/cli": "^4.0.0", "eslint": "latest", "prettier": "^3.9.4", diff --git a/examples/component-showcase/README.md b/examples/component-showcase/README.md index 841d0264..8279af3f 100644 --- a/examples/component-showcase/README.md +++ b/examples/component-showcase/README.md @@ -1,23 +1,71 @@ # WRNexus UI component showcase -This example renders every component from `@wrnexus/ui` with representative, -prop-driven data. Pages are generated from `packages/ui/component-reference.json` -so coverage stays synchronized with the packaged component catalog. +The showcase is generated from `packages/ui/component-reference.json`. It stays +synchronized with the current component source rather than maintaining a second +hand-written catalog. ```bash bun run --cwd examples/component-showcase dev ``` -Open `http://localhost:3000`. The index links to the category catalog, and every -component card opens a dedicated documentation page with three live use cases, -usage examples, its prop API, events, slots, and related navigation. +Open `http://localhost:3000`. -After changing UI component props, regenerate and verify the catalog: +## Detail-page coverage + +Every current UI component receives a dedicated detail page with: + +- an interactive server-rendered playground for every declared prop +- typed boolean, number, array, and object controls +- public component-tag syntax with single-quoted dynamic WRN expressions +- component-specific production use cases when a profile exists +- responsive fallback examples for every remaining component +- copyable `.wrn` source beside every live preview +- complete props, slots, and explicitly declared public events +- live `event.detail` output for interactive components +- previous and next component navigation + +The specialized profiles for new and recently repaired components live in: + +```text +scripts/showcase-profiles.mjs +``` + +Update that file to add product-quality examples or public enum options. Do not +infer allowed prop values from implementation comparisons; unrestricted values +such as icon classes, labels, IDs, and URLs must remain free-form inputs. + +## Generated files + +The generator creates: + +```text +app/layouts/showcase.wrn +app/layouts/document.wrn +app/pages/*.wrn +app/pages/components/*.wrn +showcase-manifest.json +``` + +`showcase-manifest.json` records component, category, demo, prop, slot, and event +coverage and is used by the test suite. Do not hand-edit generated pages. + +## Validation + +After changing UI components, metadata, profiles, the playground, or showcase +styles, run: ```bash +bun run scripts/generate-ui-component-reference.mjs bun run --cwd examples/component-showcase generate +bun run --cwd examples/component-showcase test +bun run --cwd examples/component-showcase build +``` + +The complete local check is: + +```bash bun run --cwd examples/component-showcase check ``` -Files under `app/pages/` are generated. Customize the generator or stylesheet -instead of editing those pages directly. +Review representative component pages at mobile, tablet, and desktop widths and +in light, dark, keyboard-only, and reduced-motion modes before publishing. diff --git a/examples/component-showcase/app/layouts/showcase.wrn b/examples/component-showcase/app/layouts/showcase.wrn index 8bddc782..1d2ed77f 100644 --- a/examples/component-showcase/app/layouts/showcase.wrn +++ b/examples/component-showcase/app/layouts/showcase.wrn @@ -9,7 +9,7 @@ layout Showcase {
@@ -30,39 +30,47 @@ layout Showcase {
Advanced Forms - +
Base - +
- Blocks - + Core + +
+
+ Data +
Forms - +
Integrations - +
Layout - + +
+
+ Marketing +
Navigation - +
Overlays - +
Tables - +

No components found.

diff --git a/examples/component-showcase/app/pages/accessibility.wrn b/examples/component-showcase/app/pages/accessibility.wrn index de126e90..da39f85b 100644 --- a/examples/component-showcase/app/pages/accessibility.wrn +++ b/examples/component-showcase/app/pages/accessibility.wrn @@ -10,7 +10,7 @@ page AccessibilityGuide {
Getting Started

Accessibility

Keyboard interaction, visible focus states, labels, and reduced-motion support ship by default.

Overview

Keyboard interaction, visible focus states, labels, and reduced-motion support ship by default.

Configuration

Use the design switcher in the header to test this setting live.

Component behavior

The setting is inherited by components, blocks, templates, and playground previews.

- + } } diff --git a/examples/component-showcase/app/pages/advanced-forms.wrn b/examples/component-showcase/app/pages/advanced-forms.wrn index 6fc8eae7..b3a091e0 100644 --- a/examples/component-showcase/app/pages/advanced-forms.wrn +++ b/examples/component-showcase/app/pages/advanced-forms.wrn @@ -3,100 +3,90 @@ page AdvancedFormsShowcase { layout = "showcase" seo { title = "Advanced Forms components" - description = "9 advanced-forms components from @wrnexus/ui." + description = "8 advanced-forms components from @wrnexus/ui." } view {
Component category

Advanced Forms

-

9 unique, responsive, theme-aware components. Open a component to inspect multiple live configurations and its complete props API.

-
9 componentsMultiple use cases116 live configurations
+

8 unique, responsive, theme-aware components. Open a component to inspect multiple live configurations and its complete props API.

+
8 componentsMultiple use cases112 live configurations
-
+
-
+
Advanced Forms

Advanced Select

Theme-aware, responsive advanced select component.

-
+
-
+
Advanced Forms

Combo Box

Editable autocomplete combobox with local and remote suggestions.

-
+
-
+
Advanced Forms

Copy Markup

Theme-aware, responsive copy markup component.

-
+
-
+
Advanced Forms

Input Number

Theme-aware, responsive input number component.

-
+
-
+
Advanced Forms

Pin Input

Secure multi-cell PIN and verification-code input with regex and paste support.

-
+
-
-
-
-
Advanced Forms

Search Box

Theme-aware, responsive search box component.

- -
-
-
-
- -
+
Advanced Forms

Strong Password

Theme-aware, responsive strong password component.

-
+
-
+
Advanced Forms

Toggle Count

Theme-aware, responsive toggle count component.

-
+
-
+
Advanced Forms

Toggle Password

Accessible password field with optional show and hide controls.

diff --git a/examples/component-showcase/app/pages/base.wrn b/examples/component-showcase/app/pages/base.wrn index 9a08a5fd..40276a11 100644 --- a/examples/component-showcase/app/pages/base.wrn +++ b/examples/component-showcase/app/pages/base.wrn @@ -3,290 +3,280 @@ page BaseShowcase { layout = "showcase" seo { title = "Base components" - description = "28 base components from @wrnexus/ui." + description = "27 base components from @wrnexus/ui." } view {
Component category

Base

-

28 unique, responsive, theme-aware components. Open a component to inspect multiple live configurations and its complete props API.

-
28 componentsMultiple use cases172 live configurations
+

27 unique, responsive, theme-aware components. Open a component to inspect multiple live configurations and its complete props API.

+
27 componentsMultiple use cases86 live configurations
-
+ -
+ -
+ -
+
-
+
Base

Avatar Group

Theme-aware, responsive avatar group component.

-
+ -
+
-
+
Base

Blockquote

Theme-aware, responsive blockquote component.

-
+ -
+
-
+
Base

Button Group

Theme-aware, responsive button group component.

-
+
-
+

Supporting content belongs inside the default slot.

-
Base

Card

Theme-aware, responsive card component.

+
Base

Card

Group related content in a responsive themed surface with title, description, content, and supporting slots.

-
+ -
+
-
+
Base

Chat Bubble

Theme-aware, responsive chat bubble component.

-
+ -
+
-
+
Base

Date Picker

Theme-aware, responsive date picker component.

-
+
-
+
Base

Device Frame

Theme-aware, responsive device frame component.

-
+
-
+
Base

File Upload Progress

Theme-aware, responsive file upload progress component.

-
+
-
-
-
-
Base

Hero Actions

Responsive action group for hero and call-to-action sections.

- -
-
-
-
- -
+
Base

Legend Indicator

Theme-aware, responsive legend indicator component.

-
+
-
+
-
Base

List

Theme-aware, responsive list component.

+
Base

List

Present structured responsive linked or status items with icons, descriptions, actions, and selection events.

-
+
-
+
Base

List Group

Theme-aware, responsive list group component.

-
+
-
+
-
Base

Marquee

Theme-aware, responsive marquee component.

+
Base

Marquee

Continuously present responsive labels, partners, notices, or capabilities with pause and resume behavior.

-
+ -
+ -
+ -
+ -
+
-
+
Base

Styled Icon

Theme-aware, responsive styled icon component.

-
+
-
+
-
Base

Timeline

Theme-aware, responsive timeline component.

+
Base

Timeline

Present responsive chronological activity, milestones, or workflow status with rich item metadata.

-
+ -
+
-
+
Base

Tree View

Theme-aware, responsive tree view component.

diff --git a/examples/component-showcase/app/pages/blocks.wrn b/examples/component-showcase/app/pages/block-library.wrn similarity index 99% rename from examples/component-showcase/app/pages/blocks.wrn rename to examples/component-showcase/app/pages/block-library.wrn index 59df0ea8..ac809850 100644 --- a/examples/component-showcase/app/pages/blocks.wrn +++ b/examples/component-showcase/app/pages/block-library.wrn @@ -1,4 +1,4 @@ -page Blocks { +page BlockLibrary { layout = "showcase" seo { title = "UI blocks" description = "Complete sections composed from WRNexus UI components." } view { diff --git a/examples/component-showcase/app/pages/colors.wrn b/examples/component-showcase/app/pages/colors.wrn index 4949fc97..e1f53c86 100644 --- a/examples/component-showcase/app/pages/colors.wrn +++ b/examples/component-showcase/app/pages/colors.wrn @@ -10,7 +10,7 @@ page ColorsGuide {
Customization

Colors

Semantic primary, secondary, success, warning, danger, and info tokens remain available in every palette.

Brand colors

Primary and secondary tokens communicate brand hierarchy.

Status colors

Success, warning, danger, and info preserve their semantic meaning in every palette.

Component override

Pass color="success" or another semantic color to any component.

- +
} } diff --git a/examples/component-showcase/app/pages/components/accordion.wrn b/examples/component-showcase/app/pages/components/accordion.wrn index 2922b615..4d867583 100644 --- a/examples/component-showcase/app/pages/components/accordion.wrn +++ b/examples/component-showcase/app/pages/components/accordion.wrn @@ -4,20 +4,20 @@ page AccordionDetail { state playground_size = ctx.url.searchParams.get("pg_size") ?? "default" state playground_color = ctx.url.searchParams.get("pg_color") ?? "primary" state playground_variant = ctx.url.searchParams.get("pg_variant") ?? "default" - state playground_class = ctx.url.searchParams.get("pg_class") ?? "" - state playground_id = ctx.url.searchParams.get("pg_id") ?? "accordion-example-1" - state playground_items = ctx.url.searchParams.get("pg_items") ?? "[\n {\n \"value\": \"first\",\n \"label\": \"Accordion #1\",\n \"content\": \"This is the item's accordion body. It is hidden by default until the section is opened. Use it for supporting details, explanations, or progressive disclosure.\"\n },\n {\n \"value\": \"second\",\n \"label\": \"Accordion #2\",\n \"content\": \"This is the item's accordion body. It is hidden by default until the section is opened. Use it for supporting details, explanations, or progressive disclosure.\"\n },\n {\n \"value\": \"third\",\n \"label\": \"Accordion #3\",\n \"content\": \"This is the item's accordion body. It is hidden by default until the section is opened. Use it for supporting details, explanations, or progressive disclosure.\"\n }\n]" - state playground_defaultOpen = ctx.url.searchParams.get("pg_defaultOpen") ?? "[\n \"first\"\n]" - state playground_multiple = ctx.url.searchParams.get("pg_multiple") ?? "false" - state playground_alwaysOpen = ctx.url.searchParams.get("pg_alwaysOpen") ?? "false" - state playground_disabled = ctx.url.searchParams.get("pg_disabled") ?? "false" + state playground_class = ctx.url.searchParams.get("pg_class") ?? "showcase-instance showcase-instance--1" + state playground_id = ctx.url.searchParams.get("pg_id") ?? "accordion" + state playground_items = JSON.parse(ctx.url.searchParams.get("pg_items") ?? "[{\"id\":\"accordion-0-1\",\"key\":\"accordion-0-1\",\"value\":\"primary\",\"label\":\"Primary workflow\",\"title\":\"Primary workflow\",\"description\":\"A clean default configuration for everyday product interfaces.\",\"text\":\"A configurable sample message.\",\"href\":\"#accordion-demo\",\"actionHref\":\"#accordion-demo\",\"actionLabel\":\"View details\",\"icon\":\"icon-[lucide--sparkles]\",\"iconClass\":\"icon-[lucide--sparkles]\",\"variant\":\"primary\",\"status\":\"Active\",\"time\":\"09:30\",\"current\":true,\"selected\":true,\"checked\":true,\"disabled\":false,\"outgoing\":false,\"open\":true,\"number\":1,\"count\":16,\"percentage\":72,\"color\":\"#7c3aed\",\"target\":\"_self\",\"ariaLabel\":\"Open primary workflow 1\",\"items\":[{\"label\":\"Nested option A\",\"value\":\"nested-a\"},{\"label\":\"Nested option B\",\"value\":\"nested-b\"}],\"links\":[{\"label\":\"Documentation\",\"href\":\"#documentation\"},{\"label\":\"API reference\",\"href\":\"#api-reference\"}],\"values\":[\"Included\",\"Standard\"]},{\"id\":\"accordion-0-2\",\"key\":\"accordion-0-2\",\"value\":\"secondary\",\"label\":\"Additional option\",\"title\":\"Supporting example\",\"description\":\"A clean default configuration for everyday product interfaces.\",\"text\":\"Another configurable message.\",\"href\":\"#accordion-demo\",\"actionHref\":\"#accordion-demo\",\"actionLabel\":\"View details\",\"icon\":\"icon-[lucide--sparkles]\",\"iconClass\":\"icon-[lucide--sparkles]\",\"variant\":\"primary\",\"status\":\"Active\",\"time\":\"09:30\",\"current\":false,\"selected\":false,\"checked\":false,\"disabled\":false,\"outgoing\":true,\"open\":true,\"number\":2,\"count\":32,\"percentage\":72,\"color\":\"#7c3aed\",\"target\":\"_self\",\"ariaLabel\":\"Open primary workflow 2\",\"items\":[{\"label\":\"Nested option A\",\"value\":\"nested-a\"},{\"label\":\"Nested option B\",\"value\":\"nested-b\"}],\"links\":[{\"label\":\"Documentation\",\"href\":\"#documentation\"},{\"label\":\"API reference\",\"href\":\"#api-reference\"}],\"values\":[\"Included\",\"Standard\"]}]") + state playground_defaultOpen = JSON.parse(ctx.url.searchParams.get("pg_defaultOpen") ?? "[{\"id\":\"accordion-0-1\",\"key\":\"accordion-0-1\",\"value\":\"primary\",\"label\":\"Primary workflow\",\"title\":\"Primary workflow\",\"description\":\"A clean default configuration for everyday product interfaces.\",\"text\":\"A configurable sample message.\",\"href\":\"#accordion-demo\",\"actionHref\":\"#accordion-demo\",\"actionLabel\":\"View details\",\"icon\":\"icon-[lucide--sparkles]\",\"iconClass\":\"icon-[lucide--sparkles]\",\"variant\":\"primary\",\"status\":\"Active\",\"time\":\"09:30\",\"current\":true,\"selected\":true,\"checked\":true,\"disabled\":false,\"outgoing\":false,\"open\":true,\"number\":1,\"count\":16,\"percentage\":72,\"color\":\"#7c3aed\",\"target\":\"_self\",\"ariaLabel\":\"Open primary workflow 1\",\"items\":[{\"label\":\"Nested option A\",\"value\":\"nested-a\"},{\"label\":\"Nested option B\",\"value\":\"nested-b\"}],\"links\":[{\"label\":\"Documentation\",\"href\":\"#documentation\"},{\"label\":\"API reference\",\"href\":\"#api-reference\"}],\"values\":[\"Included\",\"Standard\"]},{\"id\":\"accordion-0-2\",\"key\":\"accordion-0-2\",\"value\":\"secondary\",\"label\":\"Additional option\",\"title\":\"Supporting example\",\"description\":\"A clean default configuration for everyday product interfaces.\",\"text\":\"Another configurable message.\",\"href\":\"#accordion-demo\",\"actionHref\":\"#accordion-demo\",\"actionLabel\":\"View details\",\"icon\":\"icon-[lucide--sparkles]\",\"iconClass\":\"icon-[lucide--sparkles]\",\"variant\":\"primary\",\"status\":\"Active\",\"time\":\"09:30\",\"current\":false,\"selected\":false,\"checked\":false,\"disabled\":false,\"outgoing\":true,\"open\":true,\"number\":2,\"count\":32,\"percentage\":72,\"color\":\"#7c3aed\",\"target\":\"_self\",\"ariaLabel\":\"Open primary workflow 2\",\"items\":[{\"label\":\"Nested option A\",\"value\":\"nested-a\"},{\"label\":\"Nested option B\",\"value\":\"nested-b\"}],\"links\":[{\"label\":\"Documentation\",\"href\":\"#documentation\"},{\"label\":\"API reference\",\"href\":\"#api-reference\"}],\"values\":[\"Included\",\"Standard\"]}]") + state playground_multiple = (ctx.url.searchParams.get("pg_multiple") ?? "false") === "true" + state playground_alwaysOpen = (ctx.url.searchParams.get("pg_alwaysOpen") ?? "false") === "true" + state playground_disabled = (ctx.url.searchParams.get("pg_disabled") ?? "false") === "true" state playground_indicator = ctx.url.searchParams.get("pg_indicator") ?? "plus" state playground_indicatorPosition = ctx.url.searchParams.get("pg_indicatorPosition") ?? "start" - state playground_showIndicator = ctx.url.searchParams.get("pg_showIndicator") ?? "true" - state playground_bordered = ctx.url.searchParams.get("pg_bordered") ?? "false" - state playground_separated = ctx.url.searchParams.get("pg_separated") ?? "false" - state playground_flush = ctx.url.searchParams.get("pg_flush") ?? "false" - state playground_contentItalic = ctx.url.searchParams.get("pg_contentItalic") ?? "true" + state playground_showIndicator = (ctx.url.searchParams.get("pg_showIndicator") ?? "true") === "true" + state playground_bordered = (ctx.url.searchParams.get("pg_bordered") ?? "false") === "true" + state playground_separated = (ctx.url.searchParams.get("pg_separated") ?? "false") === "true" + state playground_flush = (ctx.url.searchParams.get("pg_flush") ?? "false") === "true" + state playground_contentItalic = (ctx.url.searchParams.get("pg_contentItalic") ?? "false") === "true" seo { title = "Accordion" description = "Theme-aware, responsive accordion component." @@ -35,62 +35,453 @@ page AccordionDetail {
-
+
Interactive playground

Configure Accordion

Change any prop and inspect the server-rendered component immediately.

Live preview
-
+
Component code
<Accordion
-  id="accordion-example-1"
   items='[
     {
-      "value": "first",
-      "label": "Accordion #1",
-      "content": "This is the item\'s accordion body. It is hidden by default until the section is opened. Use it for supporting details, explanations, or progressive disclosure."
+      "id": "accordion-0-1",
+      "key": "accordion-0-1",
+      "value": "primary",
+      "label": "Primary workflow",
+      "title": "Primary workflow",
+      "description": "A clean default configuration for everyday product interfaces.",
+      "text": "A configurable sample message.",
+      "href": "#accordion-demo",
+      "actionHref": "#accordion-demo",
+      "actionLabel": "View details",
+      "icon": "icon-[lucide--sparkles]",
+      "iconClass": "icon-[lucide--sparkles]",
+      "variant": "primary",
+      "status": "Active",
+      "time": "09:30",
+      "current": true,
+      "selected": true,
+      "checked": true,
+      "disabled": false,
+      "outgoing": false,
+      "open": true,
+      "number": 1,
+      "count": 16,
+      "percentage": 72,
+      "color": "#7c3aed",
+      "target": "_self",
+      "ariaLabel": "Open primary workflow 1",
+      "items": [
+        {
+          "label": "Nested option A",
+          "value": "nested-a"
+        },
+        {
+          "label": "Nested option B",
+          "value": "nested-b"
+        }
+      ],
+      "links": [
+        {
+          "label": "Documentation",
+          "href": "#documentation"
+        },
+        {
+          "label": "API reference",
+          "href": "#api-reference"
+        }
+      ],
+      "values": [
+        "Included",
+        "Standard"
+      ]
     },
     {
-      "value": "second",
-      "label": "Accordion #2",
-      "content": "This is the item\'s accordion body. It is hidden by default until the section is opened. Use it for supporting details, explanations, or progressive disclosure."
-    },
-    {
-      "value": "third",
-      "label": "Accordion #3",
-      "content": "This is the item\'s accordion body. It is hidden by default until the section is opened. Use it for supporting details, explanations, or progressive disclosure."
+      "id": "accordion-0-2",
+      "key": "accordion-0-2",
+      "value": "secondary",
+      "label": "Additional option",
+      "title": "Supporting example",
+      "description": "A clean default configuration for everyday product interfaces.",
+      "text": "Another configurable message.",
+      "href": "#accordion-demo",
+      "actionHref": "#accordion-demo",
+      "actionLabel": "View details",
+      "icon": "icon-[lucide--sparkles]",
+      "iconClass": "icon-[lucide--sparkles]",
+      "variant": "primary",
+      "status": "Active",
+      "time": "09:30",
+      "current": false,
+      "selected": false,
+      "checked": false,
+      "disabled": false,
+      "outgoing": true,
+      "open": true,
+      "number": 2,
+      "count": 32,
+      "percentage": 72,
+      "color": "#7c3aed",
+      "target": "_self",
+      "ariaLabel": "Open primary workflow 2",
+      "items": [
+        {
+          "label": "Nested option A",
+          "value": "nested-a"
+        },
+        {
+          "label": "Nested option B",
+          "value": "nested-b"
+        }
+      ],
+      "links": [
+        {
+          "label": "Documentation",
+          "href": "#documentation"
+        },
+        {
+          "label": "API reference",
+          "href": "#api-reference"
+        }
+      ],
+      "values": [
+        "Included",
+        "Standard"
+      ]
     }
   ]'
   defaultOpen='[
-    "first"
+    {
+      "id": "accordion-0-1",
+      "key": "accordion-0-1",
+      "value": "primary",
+      "label": "Primary workflow",
+      "title": "Primary workflow",
+      "description": "A clean default configuration for everyday product interfaces.",
+      "text": "A configurable sample message.",
+      "href": "#accordion-demo",
+      "actionHref": "#accordion-demo",
+      "actionLabel": "View details",
+      "icon": "icon-[lucide--sparkles]",
+      "iconClass": "icon-[lucide--sparkles]",
+      "variant": "primary",
+      "status": "Active",
+      "time": "09:30",
+      "current": true,
+      "selected": true,
+      "checked": true,
+      "disabled": false,
+      "outgoing": false,
+      "open": true,
+      "number": 1,
+      "count": 16,
+      "percentage": 72,
+      "color": "#7c3aed",
+      "target": "_self",
+      "ariaLabel": "Open primary workflow 1",
+      "items": [
+        {
+          "label": "Nested option A",
+          "value": "nested-a"
+        },
+        {
+          "label": "Nested option B",
+          "value": "nested-b"
+        }
+      ],
+      "links": [
+        {
+          "label": "Documentation",
+          "href": "#documentation"
+        },
+        {
+          "label": "API reference",
+          "href": "#api-reference"
+        }
+      ],
+      "values": [
+        "Included",
+        "Standard"
+      ]
+    },
+    {
+      "id": "accordion-0-2",
+      "key": "accordion-0-2",
+      "value": "secondary",
+      "label": "Additional option",
+      "title": "Supporting example",
+      "description": "A clean default configuration for everyday product interfaces.",
+      "text": "Another configurable message.",
+      "href": "#accordion-demo",
+      "actionHref": "#accordion-demo",
+      "actionLabel": "View details",
+      "icon": "icon-[lucide--sparkles]",
+      "iconClass": "icon-[lucide--sparkles]",
+      "variant": "primary",
+      "status": "Active",
+      "time": "09:30",
+      "current": false,
+      "selected": false,
+      "checked": false,
+      "disabled": false,
+      "outgoing": true,
+      "open": true,
+      "number": 2,
+      "count": 32,
+      "percentage": 72,
+      "color": "#7c3aed",
+      "target": "_self",
+      "ariaLabel": "Open primary workflow 2",
+      "items": [
+        {
+          "label": "Nested option A",
+          "value": "nested-a"
+        },
+        {
+          "label": "Nested option B",
+          "value": "nested-b"
+        }
+      ],
+      "links": [
+        {
+          "label": "Documentation",
+          "href": "#documentation"
+        },
+        {
+          "label": "API reference",
+          "href": "#api-reference"
+        }
+      ],
+      "values": [
+        "Included",
+        "Standard"
+      ]
+    }
   ]'
-  contentItalic="true"
 />
+
Event outputInteract with the preview to inspect event.detail.
Component props17 controls
-
+ { + "id": "accordion-0-1", + "key": "accordion-0-1", + "value": "primary", + "label": "Primary workflow", + "title": "Primary workflow", + "description": "A clean default configuration for everyday product interfaces.", + "text": "A configurable sample message.", + "href": "#accordion-demo", + "actionHref": "#accordion-demo", + "actionLabel": "View details", + "icon": "icon-[lucide--sparkles]", + "iconClass": "icon-[lucide--sparkles]", + "variant": "primary", + "status": "Active", + "time": "09:30", + "current": true, + "selected": true, + "checked": true, + "disabled": false, + "outgoing": false, + "open": true, + "number": 1, + "count": 16, + "percentage": 72, + "color": "#7c3aed", + "target": "_self", + "ariaLabel": "Open primary workflow 1", + "items": [ + { + "label": "Nested option A", + "value": "nested-a" + }, + { + "label": "Nested option B", + "value": "nested-b" + } + ], + "links": [ + { + "label": "Documentation", + "href": "#documentation" + }, + { + "label": "API reference", + "href": "#api-reference" + } + ], + "values": [ + "Included", + "Standard" + ] + }, + { + "id": "accordion-0-2", + "key": "accordion-0-2", + "value": "secondary", + "label": "Additional option", + "title": "Supporting example", + "description": "A clean default configuration for everyday product interfaces.", + "text": "Another configurable message.", + "href": "#accordion-demo", + "actionHref": "#accordion-demo", + "actionLabel": "View details", + "icon": "icon-[lucide--sparkles]", + "iconClass": "icon-[lucide--sparkles]", + "variant": "primary", + "status": "Active", + "time": "09:30", + "current": false, + "selected": false, + "checked": false, + "disabled": false, + "outgoing": true, + "open": true, + "number": 2, + "count": 32, + "percentage": 72, + "color": "#7c3aed", + "target": "_self", + "ariaLabel": "Open primary workflow 2", + "items": [ + { + "label": "Nested option A", + "value": "nested-a" + }, + { + "label": "Nested option B", + "value": "nested-b" + } + ], + "links": [ + { + "label": "Documentation", + "href": "#documentation" + }, + { + "label": "API reference", + "href": "#api-reference" + } + ], + "values": [ + "Included", + "Standard" + ] + } +]
@@ -99,395 +490,731 @@ page AccordionDetail {
Live examples

Designed for real product surfaces

Compare configurations and resize the browser to check responsive behavior.

-
Basic usage

Default accordion

Open one section at a time with a clear plus and minus indicator.

+
Recommended

Production default

Balanced spacing, hierarchy, and content for the most common product workflow.

01
Live preview
-
+ +
-
+
Component usage.wrn
<Accordion
-  id="accordion-example-1"
   items='[
     {
-      "value": "first",
-      "label": "Accordion #1",
-      "content": "This is the item\'s accordion body. It is hidden by default until the section is opened. Use it for supporting details, explanations, or progressive disclosure."
+      "id": "accordion-0-1",
+      "key": "accordion-0-1",
+      "value": "primary",
+      "label": "Primary workflow",
+      "title": "Primary workflow",
+      "description": "A clean default configuration for everyday product interfaces.",
+      "text": "A configurable sample message.",
+      "href": "#accordion-demo",
+      "actionHref": "#accordion-demo",
+      "actionLabel": "View details",
+      "icon": "icon-[lucide--sparkles]",
+      "iconClass": "icon-[lucide--sparkles]",
+      "variant": "primary",
+      "status": "Active",
+      "time": "09:30",
+      "current": true,
+      "selected": true,
+      "checked": true,
+      "disabled": false,
+      "outgoing": false,
+      "open": true,
+      "number": 1,
+      "count": 16,
+      "percentage": 72,
+      "color": "#7c3aed",
+      "target": "_self",
+      "ariaLabel": "Open primary workflow 1",
+      "items": [
+        {
+          "label": "Nested option A",
+          "value": "nested-a"
+        },
+        {
+          "label": "Nested option B",
+          "value": "nested-b"
+        }
+      ],
+      "links": [
+        {
+          "label": "Documentation",
+          "href": "#documentation"
+        },
+        {
+          "label": "API reference",
+          "href": "#api-reference"
+        }
+      ],
+      "values": [
+        "Included",
+        "Standard"
+      ]
     },
     {
-      "value": "second",
-      "label": "Accordion #2",
-      "content": "This is the item\'s accordion body. It is hidden by default until the section is opened. Use it for supporting details, explanations, or progressive disclosure."
-    },
-    {
-      "value": "third",
-      "label": "Accordion #3",
-      "content": "This is the item\'s accordion body. It is hidden by default until the section is opened. Use it for supporting details, explanations, or progressive disclosure."
+      "id": "accordion-0-2",
+      "key": "accordion-0-2",
+      "value": "secondary",
+      "label": "Additional option",
+      "title": "Supporting example",
+      "description": "A clean default configuration for everyday product interfaces.",
+      "text": "Another configurable message.",
+      "href": "#accordion-demo",
+      "actionHref": "#accordion-demo",
+      "actionLabel": "View details",
+      "icon": "icon-[lucide--sparkles]",
+      "iconClass": "icon-[lucide--sparkles]",
+      "variant": "primary",
+      "status": "Active",
+      "time": "09:30",
+      "current": false,
+      "selected": false,
+      "checked": false,
+      "disabled": false,
+      "outgoing": true,
+      "open": true,
+      "number": 2,
+      "count": 32,
+      "percentage": 72,
+      "color": "#7c3aed",
+      "target": "_self",
+      "ariaLabel": "Open primary workflow 2",
+      "items": [
+        {
+          "label": "Nested option A",
+          "value": "nested-a"
+        },
+        {
+          "label": "Nested option B",
+          "value": "nested-b"
+        }
+      ],
+      "links": [
+        {
+          "label": "Documentation",
+          "href": "#documentation"
+        },
+        {
+          "label": "API reference",
+          "href": "#api-reference"
+        }
+      ],
+      "values": [
+        "Included",
+        "Standard"
+      ]
     }
   ]'
   defaultOpen='[
-    "first"
+    {
+      "id": "accordion-0-1",
+      "key": "accordion-0-1",
+      "value": "primary",
+      "label": "Primary workflow",
+      "title": "Primary workflow",
+      "description": "A clean default configuration for everyday product interfaces.",
+      "text": "A configurable sample message.",
+      "href": "#accordion-demo",
+      "actionHref": "#accordion-demo",
+      "actionLabel": "View details",
+      "icon": "icon-[lucide--sparkles]",
+      "iconClass": "icon-[lucide--sparkles]",
+      "variant": "primary",
+      "status": "Active",
+      "time": "09:30",
+      "current": true,
+      "selected": true,
+      "checked": true,
+      "disabled": false,
+      "outgoing": false,
+      "open": true,
+      "number": 1,
+      "count": 16,
+      "percentage": 72,
+      "color": "#7c3aed",
+      "target": "_self",
+      "ariaLabel": "Open primary workflow 1",
+      "items": [
+        {
+          "label": "Nested option A",
+          "value": "nested-a"
+        },
+        {
+          "label": "Nested option B",
+          "value": "nested-b"
+        }
+      ],
+      "links": [
+        {
+          "label": "Documentation",
+          "href": "#documentation"
+        },
+        {
+          "label": "API reference",
+          "href": "#api-reference"
+        }
+      ],
+      "values": [
+        "Included",
+        "Standard"
+      ]
+    },
+    {
+      "id": "accordion-0-2",
+      "key": "accordion-0-2",
+      "value": "secondary",
+      "label": "Additional option",
+      "title": "Supporting example",
+      "description": "A clean default configuration for everyday product interfaces.",
+      "text": "Another configurable message.",
+      "href": "#accordion-demo",
+      "actionHref": "#accordion-demo",
+      "actionLabel": "View details",
+      "icon": "icon-[lucide--sparkles]",
+      "iconClass": "icon-[lucide--sparkles]",
+      "variant": "primary",
+      "status": "Active",
+      "time": "09:30",
+      "current": false,
+      "selected": false,
+      "checked": false,
+      "disabled": false,
+      "outgoing": true,
+      "open": true,
+      "number": 2,
+      "count": 32,
+      "percentage": 72,
+      "color": "#7c3aed",
+      "target": "_self",
+      "ariaLabel": "Open primary workflow 2",
+      "items": [
+        {
+          "label": "Nested option A",
+          "value": "nested-a"
+        },
+        {
+          "label": "Nested option B",
+          "value": "nested-b"
+        }
+      ],
+      "links": [
+        {
+          "label": "Documentation",
+          "href": "#documentation"
+        },
+        {
+          "label": "API reference",
+          "href": "#api-reference"
+        }
+      ],
+      "values": [
+        "Included",
+        "Standard"
+      ]
+    }
   ]'
-  contentItalic="true"
 />
-
Behavior

Always open

Allow several content sections to remain expanded at the same time.

+
Dense UI

Compact application

A tighter variation for dashboards, side panels, tables, and operational interfaces.

02
Live preview
-
+ +
-
+
Component usage.wrn
<Accordion
-  id="accordion-example-2"
+  size="sm"
+  variant="secondary"
   items='[
     {
-      "value": "first",
-      "label": "Accordion #1",
-      "content": "This is the item\'s accordion body. It is hidden by default until the section is opened. Use it for supporting details, explanations, or progressive disclosure."
+      "id": "accordion-1-1",
+      "key": "accordion-1-1",
+      "value": "primary",
+      "label": "Secondary workflow",
+      "title": "Secondary workflow",
+      "description": "A compact configuration designed for dense application layouts.",
+      "text": "A configurable sample message.",
+      "href": "#accordion-demo",
+      "actionHref": "#accordion-demo",
+      "actionLabel": "View details",
+      "icon": "icon-[lucide--zap]",
+      "iconClass": "icon-[lucide--zap]",
+      "variant": "secondary",
+      "status": "Active",
+      "time": "10:15",
+      "current": true,
+      "selected": true,
+      "checked": true,
+      "disabled": false,
+      "outgoing": false,
+      "open": true,
+      "number": 1,
+      "count": 24,
+      "percentage": 48,
+      "color": "#0284c7",
+      "target": "_self",
+      "ariaLabel": "Open secondary workflow 1",
+      "items": [
+        {
+          "label": "Nested option A",
+          "value": "nested-a"
+        },
+        {
+          "label": "Nested option B",
+          "value": "nested-b"
+        }
+      ],
+      "links": [
+        {
+          "label": "Documentation",
+          "href": "#documentation"
+        },
+        {
+          "label": "API reference",
+          "href": "#api-reference"
+        }
+      ],
+      "values": [
+        "Included",
+        "Standard"
+      ]
     },
     {
-      "value": "second",
-      "label": "Accordion #2",
-      "content": "This is the item\'s accordion body. It is hidden by default until the section is opened. Use it for supporting details, explanations, or progressive disclosure."
-    },
-    {
-      "value": "third",
-      "label": "Accordion #3",
-      "content": "This is the item\'s accordion body. It is hidden by default until the section is opened. Use it for supporting details, explanations, or progressive disclosure."
+      "id": "accordion-1-2",
+      "key": "accordion-1-2",
+      "value": "secondary",
+      "label": "Additional option",
+      "title": "Supporting example",
+      "description": "A compact configuration designed for dense application layouts.",
+      "text": "Another configurable message.",
+      "href": "#accordion-demo",
+      "actionHref": "#accordion-demo",
+      "actionLabel": "View details",
+      "icon": "icon-[lucide--zap]",
+      "iconClass": "icon-[lucide--zap]",
+      "variant": "secondary",
+      "status": "Active",
+      "time": "10:15",
+      "current": false,
+      "selected": false,
+      "checked": false,
+      "disabled": false,
+      "outgoing": true,
+      "open": true,
+      "number": 2,
+      "count": 48,
+      "percentage": 48,
+      "color": "#0284c7",
+      "target": "_self",
+      "ariaLabel": "Open secondary workflow 2",
+      "items": [
+        {
+          "label": "Nested option A",
+          "value": "nested-a"
+        },
+        {
+          "label": "Nested option B",
+          "value": "nested-b"
+        }
+      ],
+      "links": [
+        {
+          "label": "Documentation",
+          "href": "#documentation"
+        },
+        {
+          "label": "API reference",
+          "href": "#api-reference"
+        }
+      ],
+      "values": [
+        "Included",
+        "Standard"
+      ]
     }
   ]'
   defaultOpen='[
-    "first",
-    "second"
+    {
+      "id": "accordion-1-1",
+      "key": "accordion-1-1",
+      "value": "primary",
+      "label": "Secondary workflow",
+      "title": "Secondary workflow",
+      "description": "A compact configuration designed for dense application layouts.",
+      "text": "A configurable sample message.",
+      "href": "#accordion-demo",
+      "actionHref": "#accordion-demo",
+      "actionLabel": "View details",
+      "icon": "icon-[lucide--zap]",
+      "iconClass": "icon-[lucide--zap]",
+      "variant": "secondary",
+      "status": "Active",
+      "time": "10:15",
+      "current": true,
+      "selected": true,
+      "checked": true,
+      "disabled": false,
+      "outgoing": false,
+      "open": true,
+      "number": 1,
+      "count": 24,
+      "percentage": 48,
+      "color": "#0284c7",
+      "target": "_self",
+      "ariaLabel": "Open secondary workflow 1",
+      "items": [
+        {
+          "label": "Nested option A",
+          "value": "nested-a"
+        },
+        {
+          "label": "Nested option B",
+          "value": "nested-b"
+        }
+      ],
+      "links": [
+        {
+          "label": "Documentation",
+          "href": "#documentation"
+        },
+        {
+          "label": "API reference",
+          "href": "#api-reference"
+        }
+      ],
+      "values": [
+        "Included",
+        "Standard"
+      ]
+    },
+    {
+      "id": "accordion-1-2",
+      "key": "accordion-1-2",
+      "value": "secondary",
+      "label": "Additional option",
+      "title": "Supporting example",
+      "description": "A compact configuration designed for dense application layouts.",
+      "text": "Another configurable message.",
+      "href": "#accordion-demo",
+      "actionHref": "#accordion-demo",
+      "actionLabel": "View details",
+      "icon": "icon-[lucide--zap]",
+      "iconClass": "icon-[lucide--zap]",
+      "variant": "secondary",
+      "status": "Active",
+      "time": "10:15",
+      "current": false,
+      "selected": false,
+      "checked": false,
+      "disabled": false,
+      "outgoing": true,
+      "open": true,
+      "number": 2,
+      "count": 48,
+      "percentage": 48,
+      "color": "#0284c7",
+      "target": "_self",
+      "ariaLabel": "Open secondary workflow 2",
+      "items": [
+        {
+          "label": "Nested option A",
+          "value": "nested-a"
+        },
+        {
+          "label": "Nested option B",
+          "value": "nested-b"
+        }
+      ],
+      "links": [
+        {
+          "label": "Documentation",
+          "href": "#documentation"
+        },
+        {
+          "label": "API reference",
+          "href": "#api-reference"
+        }
+      ],
+      "values": [
+        "Included",
+        "Standard"
+      ]
+    }
   ]'
-  alwaysOpen="true"
-  contentItalic="true"
 />
-
Composition

Nested accordion

Place a coordinated secondary accordion inside an expanded parent section.

+
Extended

Rich configuration

A more expressive variation using additional data, stronger emphasis, and optional states.

03
Live preview
-
+ +
-
+
Component usage.wrn
<Accordion
-  id="accordion-example-3"
+  size="lg"
+  variant="success"
   items='[
     {
-      "value": "first",
-      "label": "Accordion #1",
-      "content": "This is the item\'s accordion body. It is hidden by default until the section is opened. Use it for supporting details, explanations, or progressive disclosure.",
-      "children": [
+      "id": "accordion-2-1",
+      "key": "accordion-2-1",
+      "value": "primary",
+      "label": "Advanced workflow",
+      "title": "Advanced workflow",
+      "description": "A richer configuration with more supporting information and actions.",
+      "text": "A configurable sample message.",
+      "href": "#accordion-demo",
+      "actionHref": "#accordion-demo",
+      "actionLabel": "Explore workflow",
+      "icon": "icon-[lucide--circle-check]",
+      "iconClass": "icon-[lucide--circle-check]",
+      "variant": "success",
+      "status": "Complete",
+      "time": "11:45",
+      "current": true,
+      "selected": true,
+      "checked": true,
+      "disabled": false,
+      "outgoing": false,
+      "open": true,
+      "number": 1,
+      "count": 32,
+      "percentage": 91,
+      "color": "#059669",
+      "target": "_self",
+      "ariaLabel": "Open advanced workflow 1",
+      "items": [
         {
-          "value": "sub-first",
-          "label": "Sub accordion #1",
-          "content": "This is the item\'s accordion body. It is hidden by default until the section is opened. Use it for supporting details, explanations, or progressive disclosure."
+          "label": "Nested option A",
+          "value": "nested-a"
         },
         {
-          "value": "sub-second",
-          "label": "Sub accordion #2",
-          "content": "This is the item\'s accordion body. It is hidden by default until the section is opened. Use it for supporting details, explanations, or progressive disclosure."
-        },
-        {
-          "value": "sub-third",
-          "label": "Sub accordion #3",
-          "content": "This is the item\'s accordion body. It is hidden by default until the section is opened. Use it for supporting details, explanations, or progressive disclosure."
+          "label": "Nested option B",
+          "value": "nested-b"
         }
+      ],
+      "links": [
+        {
+          "label": "Documentation",
+          "href": "#documentation"
+        },
+        {
+          "label": "API reference",
+          "href": "#api-reference"
+        }
+      ],
+      "values": [
+        "Included",
+        "Unlimited"
       ]
     },
     {
-      "value": "second",
-      "label": "Accordion #2",
-      "content": "This is the item\'s accordion body. It is hidden by default until the section is opened. Use it for supporting details, explanations, or progressive disclosure."
-    },
-    {
-      "value": "third",
-      "label": "Accordion #3",
-      "content": "This is the item\'s accordion body. It is hidden by default until the section is opened. Use it for supporting details, explanations, or progressive disclosure."
+      "id": "accordion-2-2",
+      "key": "accordion-2-2",
+      "value": "secondary",
+      "label": "Additional option",
+      "title": "Supporting example",
+      "description": "A richer configuration with more supporting information and actions.",
+      "text": "Another configurable message.",
+      "href": "#accordion-demo",
+      "actionHref": "#accordion-demo",
+      "actionLabel": "Explore workflow",
+      "icon": "icon-[lucide--circle-check]",
+      "iconClass": "icon-[lucide--circle-check]",
+      "variant": "success",
+      "status": "Complete",
+      "time": "11:45",
+      "current": false,
+      "selected": false,
+      "checked": false,
+      "disabled": true,
+      "outgoing": true,
+      "open": true,
+      "number": 2,
+      "count": 64,
+      "percentage": 91,
+      "color": "#059669",
+      "target": "_self",
+      "ariaLabel": "Open advanced workflow 2",
+      "items": [
+        {
+          "label": "Nested option A",
+          "value": "nested-a"
+        },
+        {
+          "label": "Nested option B",
+          "value": "nested-b"
+        }
+      ],
+      "links": [
+        {
+          "label": "Documentation",
+          "href": "#documentation"
+        },
+        {
+          "label": "API reference",
+          "href": "#api-reference"
+        }
+      ],
+      "values": [
+        "Included",
+        "Unlimited"
+      ]
     }
   ]'
   defaultOpen='[
-    "first",
-    "first.sub-first"
-  ]'
-  alwaysOpen="true"
-  contentItalic="true"
-/>
-
-
-
-
-
-
Indicators

Without an indicator

Use a minimal text-only accordion when visual indicators are unnecessary.

- 04 -
-
-
-
Live preview
-
-
-
-
Component usage.wrn
-
<Accordion
-  id="accordion-example-4"
-  items='[
     {
-      "value": "first",
-      "label": "Accordion #1",
-      "content": "This is the item\'s accordion body. It is hidden by default until the section is opened. Use it for supporting details, explanations, or progressive disclosure."
+      "id": "accordion-2-1",
+      "key": "accordion-2-1",
+      "value": "primary",
+      "label": "Advanced workflow",
+      "title": "Advanced workflow",
+      "description": "A richer configuration with more supporting information and actions.",
+      "text": "A configurable sample message.",
+      "href": "#accordion-demo",
+      "actionHref": "#accordion-demo",
+      "actionLabel": "Explore workflow",
+      "icon": "icon-[lucide--circle-check]",
+      "iconClass": "icon-[lucide--circle-check]",
+      "variant": "success",
+      "status": "Complete",
+      "time": "11:45",
+      "current": true,
+      "selected": true,
+      "checked": true,
+      "disabled": false,
+      "outgoing": false,
+      "open": true,
+      "number": 1,
+      "count": 32,
+      "percentage": 91,
+      "color": "#059669",
+      "target": "_self",
+      "ariaLabel": "Open advanced workflow 1",
+      "items": [
+        {
+          "label": "Nested option A",
+          "value": "nested-a"
+        },
+        {
+          "label": "Nested option B",
+          "value": "nested-b"
+        }
+      ],
+      "links": [
+        {
+          "label": "Documentation",
+          "href": "#documentation"
+        },
+        {
+          "label": "API reference",
+          "href": "#api-reference"
+        }
+      ],
+      "values": [
+        "Included",
+        "Unlimited"
+      ]
     },
     {
-      "value": "second",
-      "label": "Accordion #2",
-      "content": "This is the item\'s accordion body. It is hidden by default until the section is opened. Use it for supporting details, explanations, or progressive disclosure."
-    },
-    {
-      "value": "third",
-      "label": "Accordion #3",
-      "content": "This is the item\'s accordion body. It is hidden by default until the section is opened. Use it for supporting details, explanations, or progressive disclosure."
+      "id": "accordion-2-2",
+      "key": "accordion-2-2",
+      "value": "secondary",
+      "label": "Additional option",
+      "title": "Supporting example",
+      "description": "A richer configuration with more supporting information and actions.",
+      "text": "Another configurable message.",
+      "href": "#accordion-demo",
+      "actionHref": "#accordion-demo",
+      "actionLabel": "Explore workflow",
+      "icon": "icon-[lucide--circle-check]",
+      "iconClass": "icon-[lucide--circle-check]",
+      "variant": "success",
+      "status": "Complete",
+      "time": "11:45",
+      "current": false,
+      "selected": false,
+      "checked": false,
+      "disabled": true,
+      "outgoing": true,
+      "open": true,
+      "number": 2,
+      "count": 64,
+      "percentage": 91,
+      "color": "#059669",
+      "target": "_self",
+      "ariaLabel": "Open advanced workflow 2",
+      "items": [
+        {
+          "label": "Nested option A",
+          "value": "nested-a"
+        },
+        {
+          "label": "Nested option B",
+          "value": "nested-b"
+        }
+      ],
+      "links": [
+        {
+          "label": "Documentation",
+          "href": "#documentation"
+        },
+        {
+          "label": "API reference",
+          "href": "#api-reference"
+        }
+      ],
+      "values": [
+        "Included",
+        "Unlimited"
+      ]
     }
   ]'
-  defaultOpen='[
-    "first"
-  ]'
-  showIndicator="false"
-  contentItalic="true"
-/>
-
-
-
-
-
-
Indicators

Chevron indicator

Communicate expanded state with a rotating chevron.

- 05 -
-
-
-
Live preview
-
-
-
-
Component usage.wrn
-
<Accordion
-  variant="chevron"
-  id="accordion-example-5"
-  items='[
-    {
-      "value": "first",
-      "label": "Accordion #1",
-      "content": "This is the item\'s accordion body. It is hidden by default until the section is opened. Use it for supporting details, explanations, or progressive disclosure."
-    },
-    {
-      "value": "second",
-      "label": "Accordion #2",
-      "content": "This is the item\'s accordion body. It is hidden by default until the section is opened. Use it for supporting details, explanations, or progressive disclosure."
-    },
-    {
-      "value": "third",
-      "label": "Accordion #3",
-      "content": "This is the item\'s accordion body. It is hidden by default until the section is opened. Use it for supporting details, explanations, or progressive disclosure."
-    }
-  ]'
-  defaultOpen='[
-    "first"
-  ]'
-  indicator="chevron"
-  contentItalic="true"
-/>
-
-
-
-
-
-
Layout

Separated title and indicator

Place the title and state indicator at opposite ends of each trigger.

- 06 -
-
-
-
Live preview
-
-
-
-
Component usage.wrn
-
<Accordion
-  variant="chevron"
-  id="accordion-example-6"
-  items='[
-    {
-      "value": "first",
-      "label": "Accordion #1",
-      "content": "This is the item\'s accordion body. It is hidden by default until the section is opened. Use it for supporting details, explanations, or progressive disclosure."
-    },
-    {
-      "value": "second",
-      "label": "Accordion #2",
-      "content": "This is the item\'s accordion body. It is hidden by default until the section is opened. Use it for supporting details, explanations, or progressive disclosure."
-    },
-    {
-      "value": "third",
-      "label": "Accordion #3",
-      "content": "This is the item\'s accordion body. It is hidden by default until the section is opened. Use it for supporting details, explanations, or progressive disclosure."
-    }
-  ]'
-  defaultOpen='[
-    "first"
-  ]'
-  indicator="chevron"
-  indicatorPosition="end"
-  contentItalic="true"
-/>
-
-
-
-
-
-
Surface

Bordered accordion

Group sections inside one bordered surface with dividing lines.

- 07 -
-
-
-
Live preview
-
-
-
-
Component usage.wrn
-
<Accordion
-  id="accordion-example-7"
-  items='[
-    {
-      "value": "first",
-      "label": "Accordion #1",
-      "content": "This is the item\'s accordion body. It is hidden by default until the section is opened. Use it for supporting details, explanations, or progressive disclosure."
-    },
-    {
-      "value": "second",
-      "label": "Accordion #2",
-      "content": "This is the item\'s accordion body. It is hidden by default until the section is opened. Use it for supporting details, explanations, or progressive disclosure."
-    },
-    {
-      "value": "third",
-      "label": "Accordion #3",
-      "content": "This is the item\'s accordion body. It is hidden by default until the section is opened. Use it for supporting details, explanations, or progressive disclosure."
-    }
-  ]'
-  defaultOpen='[
-    "first"
-  ]'
-  bordered="true"
-  contentItalic="true"
-/>
-
-
-
-
-
-
Surface

Bordered open content

Render each section as an independent rounded card.

- 08 -
-
-
-
Live preview
-
-
-
-
Component usage.wrn
-
<Accordion
-  id="accordion-example-8"
-  items='[
-    {
-      "value": "first",
-      "label": "Accordion #1",
-      "content": "This is the item\'s accordion body. It is hidden by default until the section is opened. Use it for supporting details, explanations, or progressive disclosure."
-    },
-    {
-      "value": "second",
-      "label": "Accordion #2",
-      "content": "This is the item\'s accordion body. It is hidden by default until the section is opened. Use it for supporting details, explanations, or progressive disclosure."
-    },
-    {
-      "value": "third",
-      "label": "Accordion #3",
-      "content": "This is the item\'s accordion body. It is hidden by default until the section is opened. Use it for supporting details, explanations, or progressive disclosure."
-    }
-  ]'
-  defaultOpen='[
-    "second"
-  ]'
-  indicatorPosition="end"
-  separated="true"
-  contentItalic="true"
-/>
-
-
-
-
-
-
States

Disabled section

Disable an individual section while keeping the rest of the accordion interactive.

- 09 -
-
-
-
Live preview
-
-
-
-
Component usage.wrn
-
<Accordion
-  id="accordion-example-9"
-  items='[
-    {
-      "value": "first",
-      "label": "Accordion #1",
-      "content": "This is the item\'s accordion body. It is hidden by default until the section is opened. Use it for supporting details, explanations, or progressive disclosure."
-    },
-    {
-      "value": "second",
-      "label": "Accordion #2",
-      "content": "This is the item\'s accordion body. It is hidden by default until the section is opened. Use it for supporting details, explanations, or progressive disclosure.",
-      "disabled": true
-    },
-    {
-      "value": "third",
-      "label": "Accordion #3",
-      "content": "This is the item\'s accordion body. It is hidden by default until the section is opened. Use it for supporting details, explanations, or progressive disclosure."
-    }
-  ]'
-  defaultOpen='[
-    "first"
-  ]'
-  contentItalic="true"
 />
-
Component events

Events

Public events declared by this component. Custom events bubble from the component root and expose state through event.detail.

@changeFires when the component value or selection changes.
@openFires when the component opens.
@closeFires when the component closes.
Event listener.js
const component = document.querySelector('[data-wrn-events]')
+        
Component events

Respond to every public interaction

Use declarative @event handlers in .wrn files or subscribe to the bubbling browser events from JavaScript.

@changeFires when the component's committed value or selection changes.
@openFires after the component opens.
@closeFires after the component closes.
Declarative handlers.wrn
<Accordion
+  @change='console.log(event.detail)'
+  @open='console.log(event.detail)'
+  @close='console.log(event.detail)'
+/>
Browser listeners.js
const component = document.querySelector("[data-ui-component=\"Accordion\"], [data-component=\"Accordion\"]")
 
-component.addEventListener('change', (event) => {
-  console.log(event.detail)
-})
+component?.addEventListener("change", (event) => { + console.log("change", event.detail) +}) + +component?.addEventListener("open", (event) => { + console.log("open", event.detail) +}) + +component?.addEventListener("close", (event) => { + console.log("close", event.detail) +})
Component API

Props and configuration

All content and behavior shown above is supplied through these props and slots.

PropTypeDefaultRequired
sizestring"default"No
colorstring"primary"No
variantstring"default"No
classstring""No
idstring"accordion"No
itemsstring[]No
defaultOpenstring[]No
multiplebooleanfalseNo
alwaysOpenbooleanfalseNo
disabledbooleanfalseNo
indicatorstring"plus"No
indicatorPositionstring"start"No
showIndicatorbooleantrueNo
borderedbooleanfalseNo
separatedbooleanfalseNo
flushbooleanfalseNo
contentItalicbooleanfalseNo
-
Component events

Events

Public events declared by this component. Custom events bubble from the component root and expose state through event.detail.

@inputFires immediately as the component value changes.
@changeFires when the component value or selection changes.
@openFires when the component opens.
@closeFires when the component closes.
@clearFires after the current value or collection is cleared.
Event listener.js
const component = document.querySelector('[data-wrn-events]')
+        
Component events

Respond to every public interaction

Use declarative @event handlers in .wrn files or subscribe to the bubbling browser events from JavaScript.

@inputFires as the editable value changes.
@changeFires when the component's committed value or selection changes.
@openFires after the component opens.
@closeFires after the component closes.
@clearFires after the current value or selection is cleared.
Declarative handlers.wrn
<AdvancedDatePicker
+  @input='console.log(event.detail)'
+  @change='console.log(event.detail)'
+  @open='console.log(event.detail)'
+  @close='console.log(event.detail)'
+  @clear='console.log(event.detail)'
+/>
Browser listeners.js
const component = document.querySelector("[data-ui-component=\"AdvancedDatePicker\"], [data-component=\"AdvancedDatePicker\"]")
 
-component.addEventListener('input', (event) => {
-  console.log(event.detail)
-})
+component?.addEventListener("input", (event) => { + console.log("input", event.detail) +}) + +component?.addEventListener("change", (event) => { + console.log("change", event.detail) +}) + +component?.addEventListener("open", (event) => { + console.log("open", event.detail) +}) + +component?.addEventListener("close", (event) => { + console.log("close", event.detail) +}) + +component?.addEventListener("clear", (event) => { + console.log("clear", event.detail) +})
Component API

Props and configuration

All content and behavior shown above is supplied through these props and slots.

PropTypeDefaultRequired
sizestring"default"No
colorstring"primary"No
titlestring"Advanced Date Picker"No
descriptionstring""No
itemsstring[]No
variantstring"default"No
classstring""No
-
Component events

Events

Public events declared by this component. Custom events bubble from the component root and expose state through event.detail.

@inputFires immediately as the component value changes.
@changeFires when the component value or selection changes.
@startFires when the component emits the start event.
@endFires when the component emits the end event.
Event listener.js
const component = document.querySelector('[data-wrn-events]')
+        
Component events

Respond to every public interaction

Use declarative @event handlers in .wrn files or subscribe to the bubbling browser events from JavaScript.

@inputFires as the editable value changes.
@changeFires when the component's committed value or selection changes.
@startFires when the component emits the start event.
@endFires when the component emits the end event.
Declarative handlers.wrn
<AdvancedRangeSlider
+  @input='console.log(event.detail)'
+  @change='console.log(event.detail)'
+  @start='console.log(event.detail)'
+  @end='console.log(event.detail)'
+/>
Browser listeners.js
const component = document.querySelector("[data-ui-component=\"AdvancedRangeSlider\"], [data-component=\"AdvancedRangeSlider\"]")
 
-component.addEventListener('input', (event) => {
-  console.log(event.detail)
-})
+component?.addEventListener("input", (event) => { + console.log("input", event.detail) +}) + +component?.addEventListener("change", (event) => { + console.log("change", event.detail) +}) + +component?.addEventListener("start", (event) => { + console.log("start", event.detail) +}) + +component?.addEventListener("end", (event) => { + console.log("end", event.detail) +})
Component API

Props and configuration

All content and behavior shown above is supplied through these props and slots.

PropTypeDefaultRequired
sizestring"default"No
colorstring"primary"No
titlestring"Advanced Range Slider"No
descriptionstring""No
itemsstring[]No
variantstring"default"No
classstring""No
-
Component events

Events

Public events declared by this component. Custom events bubble from the component root and expose state through event.detail.

@searchFires when the search query changes or is submitted.
@selectFires when an item or option is selected.
@changeFires when the component value or selection changes.
@clearFires after the current value or collection is cleared.
@openFires when the component opens.
@closeFires when the component closes.
@loadFires when component data or media finishes loading.
@errorFires when the component encounters an error.
Event listener.js
const component = document.querySelector('[data-wrn-events]')
+        
Component events

Respond to every public interaction

Use declarative @event handlers in .wrn files or subscribe to the bubbling browser events from JavaScript.

@searchFires when the current search query changes.
@selectFires when an item, option, card, or result is selected.
@changeFires when the component's committed value or selection changes.
@clearFires after the current value or selection is cleared.
@openFires after the component opens.
@closeFires after the component closes.
@loadFires after remote or deferred content loads successfully.
@errorFires when the component cannot complete an operation.
Declarative handlers.wrn
<AdvancedSelect
+  @search='console.log(event.detail)'
+  @select='console.log(event.detail)'
+  @change='console.log(event.detail)'
+  @clear='console.log(event.detail)'
+  @open='console.log(event.detail)'
+  @close='console.log(event.detail)'
+  @load='console.log(event.detail)'
+  @error='console.log(event.detail)'
+/>
Browser listeners.js
const component = document.querySelector("[data-ui-component=\"AdvancedSelect\"], [data-component=\"AdvancedSelect\"]")
 
-component.addEventListener('search', (event) => {
-  console.log(event.detail)
-})
+component?.addEventListener("search", (event) => { + console.log("search", event.detail) +}) + +component?.addEventListener("select", (event) => { + console.log("select", event.detail) +}) + +component?.addEventListener("change", (event) => { + console.log("change", event.detail) +}) + +component?.addEventListener("clear", (event) => { + console.log("clear", event.detail) +}) + +component?.addEventListener("open", (event) => { + console.log("open", event.detail) +}) + +component?.addEventListener("close", (event) => { + console.log("close", event.detail) +}) + +component?.addEventListener("load", (event) => { + console.log("load", event.detail) +}) + +component?.addEventListener("error", (event) => { + console.log("error", event.detail) +})
Component API

Props and configuration

All content and behavior shown above is supplied through these props and slots.

PropTypeDefaultRequired
sizestring"default"No
colorstring"primary"No
labelstring"Advanced Select"No
namestring""No
valuestring""No
valuesstring[]No
optionsstring[]No
groupsstring[]No
placeholderstring"Select an option"No
placeholderIconstring""No
searchPlaceholderstring"Search options…"No
multiplebooleanfalseNo
searchablebooleantrueNo
defaultOpenbooleanfalseNo
clearablebooleantrueNo
allowEmptybooleantrueNo
tagsbooleanfalseNo
disabledbooleanfalseNo
requiredbooleanfalseNo
invalidbooleanfalseNo
validationMessagestring""No
helpTextstring""No
loadingbooleanfalseNo
loadingLabelstring"Loading options…"No
emptyLabelstring"No options found"No
selectedOptionsLabelstring"Selected options"No
clearLabelstring"Clear selection"No
createLabelstring"Create"No
loadMoreLabelstring"Load more"No
searchModestring"contains"No
searchFieldsstring"label,description"No
minSearchLengthnumber0No
searchResultLimitnumber0No
maxSelectionsnumber0No
showCounterbooleanfalseNo
counterTemplatestring"{selected} selected"No
optionTemplatestring"default"No
selectedTemplatestring"default"No
closeOnSelectbooleantrueNo
scrollToSelectedbooleantrueNo
fixedbooleanfalseNo
placementstring"bottom"No
remotebooleanfalseNo
remoteUrlstring""No
remoteQueryParamstring"q"No
remoteDebouncenumber250No
remoteAutoLoadbooleantrueNo
infinitebooleanfalseNo
hasMorebooleanfalseNo
pagenumber1No
classstring""No
-
Component events

Events

Public events declared by this component. Custom events bubble from the component root and expose state through event.detail.

@submitFires when the component submits its value.
@changeFires when the component value or selection changes.
@inputFires immediately as the component value changes.
@focusFires when the component receives focus.
@blurFires when focus leaves the component.
Event listener.js
const component = document.querySelector('[data-wrn-events]')
+        
Component events

Respond to every public interaction

Use declarative @event handlers in .wrn files or subscribe to the bubbling browser events from JavaScript.

@submitFires when the component emits the submit event.
@changeFires when the component's committed value or selection changes.
@inputFires as the editable value changes.
@focusFires when the interactive control receives focus.
@blurFires when focus leaves the interactive control.
Declarative handlers.wrn
<AuthForm
+  @submit='console.log(event.detail)'
+  @change='console.log(event.detail)'
+  @input='console.log(event.detail)'
+  @focus='console.log(event.detail)'
+  @blur='console.log(event.detail)'
+/>
Browser listeners.js
const component = document.querySelector("[data-ui-component=\"AuthForm\"], [data-component=\"AuthForm\"]")
 
-component.addEventListener('submit', (event) => {
-  console.log(event.detail)
-})
+component?.addEventListener("submit", (event) => { + console.log("submit", event.detail) +}) + +component?.addEventListener("change", (event) => { + console.log("change", event.detail) +}) + +component?.addEventListener("input", (event) => { + console.log("input", event.detail) +}) + +component?.addEventListener("focus", (event) => { + console.log("focus", event.detail) +}) + +component?.addEventListener("blur", (event) => { + console.log("blur", event.detail) +})
Component API

Props and configuration

All content and behavior shown above is supplied through these props and slots.

PropTypeDefaultRequired
sizestring"default"No
colorstring"primary"No
modestring"sign-in"No
actionstring"/api/auth/login"No
methodstring"post"No
titlestring"Sign in"No
descriptionstring""No
returnTostring""No
schemastring""No
showRememberbooleantrueNo
showNamebooleantrueNo
submitLabelstring"Continue"No
classstring""No
-
Component events

Events

Public events declared by this component. Custom events bubble from the component root and expose state through event.detail.

No public component events.
+
Component API

Props and configuration

All content and behavior shown above is supplied through these props and slots.

PropTypeDefaultRequired
sizestring"default"No
colorstring"primary"No
eyebrowstring"Secure identity"No
titlestring"Welcome back"No
descriptionstring""No
brandstring"Police Management System"No
featuresstring[]No
classstring""No
} } diff --git a/examples/component-showcase/app/pages/components/avatar-group.wrn b/examples/component-showcase/app/pages/components/avatar-group.wrn index c3a2360f..faf216cb 100644 --- a/examples/component-showcase/app/pages/components/avatar-group.wrn +++ b/examples/component-showcase/app/pages/components/avatar-group.wrn @@ -1,18 +1,18 @@ // Generated by scripts/generate-showcase.mjs. Do not edit directly. page AvatarGroupDetail { layout = "showcase" - state playground_items = ctx.url.searchParams.get("pg_items") ?? "[\n {\n \"src\": \"/avatar-example.svg\",\n \"name\": \"Mark Wanner\",\n \"alt\": \"Mark Wanner\"\n },\n {\n \"src\": \"/avatar-example-2.svg\",\n \"name\": \"Maria Guan\",\n \"alt\": \"Maria Guan\"\n },\n {\n \"src\": \"/avatar-example-3.svg\",\n \"name\": \"Amil Evara\",\n \"alt\": \"Amil Evara\"\n },\n {\n \"initials\": \"EE\",\n \"name\": \"Ebele Egbuna\",\n \"color\": \"info\"\n }\n]" - state playground_size = ctx.url.searchParams.get("pg_size") ?? "lg" + state playground_items = JSON.parse(ctx.url.searchParams.get("pg_items") ?? "[{\"id\":\"avatar-group-0-1\",\"key\":\"avatar-group-0-1\",\"value\":\"primary\",\"label\":\"Primary workflow\",\"title\":\"Primary workflow\",\"description\":\"A clean default configuration for everyday product interfaces.\",\"text\":\"A configurable sample message.\",\"href\":\"#avatar-group-demo\",\"actionHref\":\"#avatar-group-demo\",\"actionLabel\":\"View details\",\"icon\":\"icon-[lucide--sparkles]\",\"iconClass\":\"icon-[lucide--sparkles]\",\"variant\":\"primary\",\"status\":\"Active\",\"time\":\"09:30\",\"current\":true,\"selected\":true,\"checked\":true,\"disabled\":false,\"outgoing\":false,\"open\":true,\"number\":1,\"count\":16,\"percentage\":72,\"color\":\"#7c3aed\",\"target\":\"_self\",\"ariaLabel\":\"Open primary workflow 1\",\"items\":[{\"label\":\"Nested option A\",\"value\":\"nested-a\"},{\"label\":\"Nested option B\",\"value\":\"nested-b\"}],\"links\":[{\"label\":\"Documentation\",\"href\":\"#documentation\"},{\"label\":\"API reference\",\"href\":\"#api-reference\"}],\"values\":[\"Included\",\"Standard\"]},{\"id\":\"avatar-group-0-2\",\"key\":\"avatar-group-0-2\",\"value\":\"secondary\",\"label\":\"Additional option\",\"title\":\"Supporting example\",\"description\":\"A clean default configuration for everyday product interfaces.\",\"text\":\"Another configurable message.\",\"href\":\"#avatar-group-demo\",\"actionHref\":\"#avatar-group-demo\",\"actionLabel\":\"View details\",\"icon\":\"icon-[lucide--sparkles]\",\"iconClass\":\"icon-[lucide--sparkles]\",\"variant\":\"primary\",\"status\":\"Active\",\"time\":\"09:30\",\"current\":false,\"selected\":false,\"checked\":false,\"disabled\":false,\"outgoing\":true,\"open\":true,\"number\":2,\"count\":32,\"percentage\":72,\"color\":\"#7c3aed\",\"target\":\"_self\",\"ariaLabel\":\"Open primary workflow 2\",\"items\":[{\"label\":\"Nested option A\",\"value\":\"nested-a\"},{\"label\":\"Nested option B\",\"value\":\"nested-b\"}],\"links\":[{\"label\":\"Documentation\",\"href\":\"#documentation\"},{\"label\":\"API reference\",\"href\":\"#api-reference\"}],\"values\":[\"Included\",\"Standard\"]}]") + state playground_size = ctx.url.searchParams.get("pg_size") ?? "md" state playground_color = ctx.url.searchParams.get("pg_color") ?? "primary" state playground_variant = ctx.url.searchParams.get("pg_variant") ?? "solid" state playground_shape = ctx.url.searchParams.get("pg_shape") ?? "circle" state playground_layout = ctx.url.searchParams.get("pg_layout") ?? "stack" - state playground_maxVisible = ctx.url.searchParams.get("pg_maxVisible") ?? "4" - state playground_columns = ctx.url.searchParams.get("pg_columns") ?? "3" + state playground_maxVisible = Number(ctx.url.searchParams.get("pg_maxVisible") ?? "4") + state playground_columns = Number(ctx.url.searchParams.get("pg_columns") ?? "3") state playground_borderColor = ctx.url.searchParams.get("pg_borderColor") ?? "" - state playground_showTooltips = ctx.url.searchParams.get("pg_showTooltips") ?? "true" - state playground_overflowLabel = ctx.url.searchParams.get("pg_overflowLabel") ?? "Show remaining members" - state playground_class = ctx.url.searchParams.get("pg_class") ?? "" + state playground_showTooltips = (ctx.url.searchParams.get("pg_showTooltips") ?? "true") === "true" + state playground_overflowLabel = ctx.url.searchParams.get("pg_overflowLabel") ?? "Avatar Group" + state playground_class = ctx.url.searchParams.get("pg_class") ?? "showcase-instance showcase-instance--1" seo { title = "Avatar Group" description = "Theme-aware, responsive avatar group component." @@ -30,66 +30,239 @@ page AvatarGroupDetail {
-
+
Interactive playground

Configure Avatar Group

Change any prop and inspect the server-rendered component immediately.

Live preview
-
+
Component code
<AvatarGroup
   items='[
     {
-      "src": "/avatar-example.svg",
-      "name": "Mark Wanner",
-      "alt": "Mark Wanner"
+      "id": "avatar-group-0-1",
+      "key": "avatar-group-0-1",
+      "value": "primary",
+      "label": "Primary workflow",
+      "title": "Primary workflow",
+      "description": "A clean default configuration for everyday product interfaces.",
+      "text": "A configurable sample message.",
+      "href": "#avatar-group-demo",
+      "actionHref": "#avatar-group-demo",
+      "actionLabel": "View details",
+      "icon": "icon-[lucide--sparkles]",
+      "iconClass": "icon-[lucide--sparkles]",
+      "variant": "primary",
+      "status": "Active",
+      "time": "09:30",
+      "current": true,
+      "selected": true,
+      "checked": true,
+      "disabled": false,
+      "outgoing": false,
+      "open": true,
+      "number": 1,
+      "count": 16,
+      "percentage": 72,
+      "color": "#7c3aed",
+      "target": "_self",
+      "ariaLabel": "Open primary workflow 1",
+      "items": [
+        {
+          "label": "Nested option A",
+          "value": "nested-a"
+        },
+        {
+          "label": "Nested option B",
+          "value": "nested-b"
+        }
+      ],
+      "links": [
+        {
+          "label": "Documentation",
+          "href": "#documentation"
+        },
+        {
+          "label": "API reference",
+          "href": "#api-reference"
+        }
+      ],
+      "values": [
+        "Included",
+        "Standard"
+      ]
     },
     {
-      "src": "/avatar-example-2.svg",
-      "name": "Maria Guan",
-      "alt": "Maria Guan"
-    },
-    {
-      "src": "/avatar-example-3.svg",
-      "name": "Amil Evara",
-      "alt": "Amil Evara"
-    },
-    {
-      "initials": "EE",
-      "name": "Ebele Egbuna",
-      "color": "info"
+      "id": "avatar-group-0-2",
+      "key": "avatar-group-0-2",
+      "value": "secondary",
+      "label": "Additional option",
+      "title": "Supporting example",
+      "description": "A clean default configuration for everyday product interfaces.",
+      "text": "Another configurable message.",
+      "href": "#avatar-group-demo",
+      "actionHref": "#avatar-group-demo",
+      "actionLabel": "View details",
+      "icon": "icon-[lucide--sparkles]",
+      "iconClass": "icon-[lucide--sparkles]",
+      "variant": "primary",
+      "status": "Active",
+      "time": "09:30",
+      "current": false,
+      "selected": false,
+      "checked": false,
+      "disabled": false,
+      "outgoing": true,
+      "open": true,
+      "number": 2,
+      "count": 32,
+      "percentage": 72,
+      "color": "#7c3aed",
+      "target": "_self",
+      "ariaLabel": "Open primary workflow 2",
+      "items": [
+        {
+          "label": "Nested option A",
+          "value": "nested-a"
+        },
+        {
+          "label": "Nested option B",
+          "value": "nested-b"
+        }
+      ],
+      "links": [
+        {
+          "label": "Documentation",
+          "href": "#documentation"
+        },
+        {
+          "label": "API reference",
+          "href": "#api-reference"
+        }
+      ],
+      "values": [
+        "Included",
+        "Standard"
+      ]
     }
   ]'
-  size="lg"
+  overflowLabel="Avatar Group"
 />
+
Event outputInteract with the preview to inspect event.detail.
Component props12 controls
+]
@@ -98,252 +271,400 @@ page AvatarGroupDetail {
Live examples

Designed for real product surfaces

Compare configurations and resize the browser to check responsive behavior.

-
Facepile

Overlapping stack

Overlap avatars with negative spacing to create a compact team facepile.

+
Recommended

Production default

Balanced spacing, hierarchy, and content for the most common product workflow.

01
Live preview
-
+ +
-
+
Component usage.wrn
<AvatarGroup
   items='[
     {
-      "src": "/avatar-example.svg",
-      "name": "Mark Wanner",
-      "alt": "Mark Wanner"
+      "id": "avatar-group-0-1",
+      "key": "avatar-group-0-1",
+      "value": "primary",
+      "label": "Primary workflow",
+      "title": "Primary workflow",
+      "description": "A clean default configuration for everyday product interfaces.",
+      "text": "A configurable sample message.",
+      "href": "#avatar-group-demo",
+      "actionHref": "#avatar-group-demo",
+      "actionLabel": "View details",
+      "icon": "icon-[lucide--sparkles]",
+      "iconClass": "icon-[lucide--sparkles]",
+      "variant": "primary",
+      "status": "Active",
+      "time": "09:30",
+      "current": true,
+      "selected": true,
+      "checked": true,
+      "disabled": false,
+      "outgoing": false,
+      "open": true,
+      "number": 1,
+      "count": 16,
+      "percentage": 72,
+      "color": "#7c3aed",
+      "target": "_self",
+      "ariaLabel": "Open primary workflow 1",
+      "items": [
+        {
+          "label": "Nested option A",
+          "value": "nested-a"
+        },
+        {
+          "label": "Nested option B",
+          "value": "nested-b"
+        }
+      ],
+      "links": [
+        {
+          "label": "Documentation",
+          "href": "#documentation"
+        },
+        {
+          "label": "API reference",
+          "href": "#api-reference"
+        }
+      ],
+      "values": [
+        "Included",
+        "Standard"
+      ]
     },
     {
-      "src": "/avatar-example-2.svg",
-      "name": "Maria Guan",
-      "alt": "Maria Guan"
-    },
-    {
-      "src": "/avatar-example-3.svg",
-      "name": "Amil Evara",
-      "alt": "Amil Evara"
-    },
-    {
-      "initials": "EE",
-      "name": "Ebele Egbuna",
-      "color": "info"
+      "id": "avatar-group-0-2",
+      "key": "avatar-group-0-2",
+      "value": "secondary",
+      "label": "Additional option",
+      "title": "Supporting example",
+      "description": "A clean default configuration for everyday product interfaces.",
+      "text": "Another configurable message.",
+      "href": "#avatar-group-demo",
+      "actionHref": "#avatar-group-demo",
+      "actionLabel": "View details",
+      "icon": "icon-[lucide--sparkles]",
+      "iconClass": "icon-[lucide--sparkles]",
+      "variant": "primary",
+      "status": "Active",
+      "time": "09:30",
+      "current": false,
+      "selected": false,
+      "checked": false,
+      "disabled": false,
+      "outgoing": true,
+      "open": true,
+      "number": 2,
+      "count": 32,
+      "percentage": 72,
+      "color": "#7c3aed",
+      "target": "_self",
+      "ariaLabel": "Open primary workflow 2",
+      "items": [
+        {
+          "label": "Nested option A",
+          "value": "nested-a"
+        },
+        {
+          "label": "Nested option B",
+          "value": "nested-b"
+        }
+      ],
+      "links": [
+        {
+          "label": "Documentation",
+          "href": "#documentation"
+        },
+        {
+          "label": "API reference",
+          "href": "#api-reference"
+        }
+      ],
+      "values": [
+        "Included",
+        "Standard"
+      ]
     }
   ]'
-  size="lg"
+  overflowLabel="Avatar Group"
 />
-
Layout

Grid layout

Arrange members in a grid with equal spacing and a clear overflow count.

+
Dense UI

Compact application

A tighter variation for dashboards, side panels, tables, and operational interfaces.

02
Live preview
-
+ +
-
+
Component usage.wrn
<AvatarGroup
   items='[
     {
-      "src": "/avatar-example.svg",
-      "name": "Mark Wanner",
-      "alt": "Mark Wanner"
+      "id": "avatar-group-1-1",
+      "key": "avatar-group-1-1",
+      "value": "primary",
+      "label": "Secondary workflow",
+      "title": "Secondary workflow",
+      "description": "A compact configuration designed for dense application layouts.",
+      "text": "A configurable sample message.",
+      "href": "#avatar-group-demo",
+      "actionHref": "#avatar-group-demo",
+      "actionLabel": "View details",
+      "icon": "icon-[lucide--zap]",
+      "iconClass": "icon-[lucide--zap]",
+      "variant": "secondary",
+      "status": "Active",
+      "time": "10:15",
+      "current": true,
+      "selected": true,
+      "checked": true,
+      "disabled": false,
+      "outgoing": false,
+      "open": true,
+      "number": 1,
+      "count": 24,
+      "percentage": 48,
+      "color": "#0284c7",
+      "target": "_self",
+      "ariaLabel": "Open secondary workflow 1",
+      "items": [
+        {
+          "label": "Nested option A",
+          "value": "nested-a"
+        },
+        {
+          "label": "Nested option B",
+          "value": "nested-b"
+        }
+      ],
+      "links": [
+        {
+          "label": "Documentation",
+          "href": "#documentation"
+        },
+        {
+          "label": "API reference",
+          "href": "#api-reference"
+        }
+      ],
+      "values": [
+        "Included",
+        "Standard"
+      ]
     },
     {
-      "src": "/avatar-example-2.svg",
-      "name": "Maria Guan",
-      "alt": "Maria Guan"
-    },
-    {
-      "src": "/avatar-example-3.svg",
-      "name": "Amil Evara",
-      "alt": "Amil Evara"
-    },
-    {
-      "initials": "EE",
-      "name": "Ebele Egbuna",
-      "color": "info"
-    },
-    {
-      "initials": "CL",
-      "name": "Chris Lynch",
-      "color": "success"
-    },
-    {
-      "initials": "NS",
-      "name": "Nora Singh",
-      "color": "warning"
-    },
-    {
-      "initials": "JR",
-      "name": "Jon Rivera",
-      "color": "danger"
-    },
-    {
-      "initials": "AK",
-      "name": "Amina Khan",
-      "color": "secondary"
+      "id": "avatar-group-1-2",
+      "key": "avatar-group-1-2",
+      "value": "secondary",
+      "label": "Additional option",
+      "title": "Supporting example",
+      "description": "A compact configuration designed for dense application layouts.",
+      "text": "Another configurable message.",
+      "href": "#avatar-group-demo",
+      "actionHref": "#avatar-group-demo",
+      "actionLabel": "View details",
+      "icon": "icon-[lucide--zap]",
+      "iconClass": "icon-[lucide--zap]",
+      "variant": "secondary",
+      "status": "Active",
+      "time": "10:15",
+      "current": false,
+      "selected": false,
+      "checked": false,
+      "disabled": false,
+      "outgoing": true,
+      "open": true,
+      "number": 2,
+      "count": 48,
+      "percentage": 48,
+      "color": "#0284c7",
+      "target": "_self",
+      "ariaLabel": "Open secondary workflow 2",
+      "items": [
+        {
+          "label": "Nested option A",
+          "value": "nested-a"
+        },
+        {
+          "label": "Nested option B",
+          "value": "nested-b"
+        }
+      ],
+      "links": [
+        {
+          "label": "Documentation",
+          "href": "#documentation"
+        },
+        {
+          "label": "API reference",
+          "href": "#api-reference"
+        }
+      ],
+      "values": [
+        "Included",
+        "Standard"
+      ]
     }
   ]'
-  layout="grid"
-  maxVisible="7"
+  size="sm"
+  variant="secondary"
+  overflowLabel="Compact example"
 />
-
Border

Custom border color

Change the ring color so stacked groups remain distinct on different surfaces.

+
Extended

Rich configuration

A more expressive variation using additional data, stronger emphasis, and optional states.

03
Live preview
-
+ +
-
+
Component usage.wrn
<AvatarGroup
   items='[
     {
-      "src": "/avatar-example.svg",
-      "name": "Mark Wanner",
-      "alt": "Mark Wanner"
+      "id": "avatar-group-2-1",
+      "key": "avatar-group-2-1",
+      "value": "primary",
+      "label": "Advanced workflow",
+      "title": "Advanced workflow",
+      "description": "A richer configuration with more supporting information and actions.",
+      "text": "A configurable sample message.",
+      "href": "#avatar-group-demo",
+      "actionHref": "#avatar-group-demo",
+      "actionLabel": "Explore workflow",
+      "icon": "icon-[lucide--circle-check]",
+      "iconClass": "icon-[lucide--circle-check]",
+      "variant": "success",
+      "status": "Complete",
+      "time": "11:45",
+      "current": true,
+      "selected": true,
+      "checked": true,
+      "disabled": false,
+      "outgoing": false,
+      "open": true,
+      "number": 1,
+      "count": 32,
+      "percentage": 91,
+      "color": "#059669",
+      "target": "_self",
+      "ariaLabel": "Open advanced workflow 1",
+      "items": [
+        {
+          "label": "Nested option A",
+          "value": "nested-a"
+        },
+        {
+          "label": "Nested option B",
+          "value": "nested-b"
+        }
+      ],
+      "links": [
+        {
+          "label": "Documentation",
+          "href": "#documentation"
+        },
+        {
+          "label": "API reference",
+          "href": "#api-reference"
+        }
+      ],
+      "values": [
+        "Included",
+        "Unlimited"
+      ]
     },
     {
-      "src": "/avatar-example-2.svg",
-      "name": "Maria Guan",
-      "alt": "Maria Guan"
-    },
-    {
-      "src": "/avatar-example-3.svg",
-      "name": "Amil Evara",
-      "alt": "Amil Evara"
-    },
-    {
-      "initials": "EE",
-      "name": "Ebele Egbuna",
-      "color": "info"
-    }
-  ]'
-  borderColor="#2583ff"
-/>
-
-
-
-
-
-
Tooltip

Member tooltips

Reveal each member's name on pointer hover or keyboard focus.

- 04 -
-
-
-
Live preview
-
-
-
-
Component usage.wrn
-
<AvatarGroup
-  items='[
-    {
-      "src": "/avatar-example.svg",
-      "name": "Mark Wanner",
-      "alt": "Mark Wanner"
-    },
-    {
-      "src": "/avatar-example-2.svg",
-      "name": "Maria Guan",
-      "alt": "Maria Guan"
-    },
-    {
-      "src": "/avatar-example-3.svg",
-      "name": "Amil Evara",
-      "alt": "Amil Evara"
-    },
-    {
-      "initials": "EE",
-      "name": "Ebele Egbuna",
-      "color": "info"
-    }
-  ]'
-/>
-
-
-
-
-
-
Overflow

Dropdown overflow

Open the overflow counter to inspect members hidden by the visible limit.

- 05 -
-
-
-
Live preview
-
-
-
-
Component usage.wrn
-
<AvatarGroup
-  items='[
-    {
-      "src": "/avatar-example.svg",
-      "name": "Mark Wanner",
-      "alt": "Mark Wanner"
-    },
-    {
-      "src": "/avatar-example-2.svg",
-      "name": "Maria Guan",
-      "alt": "Maria Guan"
-    },
-    {
-      "src": "/avatar-example-3.svg",
-      "name": "Amil Evara",
-      "alt": "Amil Evara"
-    },
-    {
-      "initials": "EE",
-      "name": "Ebele Egbuna",
-      "color": "info"
-    },
-    {
-      "initials": "CL",
-      "name": "Chris Lynch",
-      "color": "success"
-    },
-    {
-      "initials": "NS",
-      "name": "Nora Singh",
-      "color": "warning"
-    },
-    {
-      "initials": "JR",
-      "name": "Jon Rivera",
-      "color": "danger"
-    },
-    {
-      "initials": "AK",
-      "name": "Amina Khan",
-      "color": "secondary"
+      "id": "avatar-group-2-2",
+      "key": "avatar-group-2-2",
+      "value": "secondary",
+      "label": "Additional option",
+      "title": "Supporting example",
+      "description": "A richer configuration with more supporting information and actions.",
+      "text": "Another configurable message.",
+      "href": "#avatar-group-demo",
+      "actionHref": "#avatar-group-demo",
+      "actionLabel": "Explore workflow",
+      "icon": "icon-[lucide--circle-check]",
+      "iconClass": "icon-[lucide--circle-check]",
+      "variant": "success",
+      "status": "Complete",
+      "time": "11:45",
+      "current": false,
+      "selected": false,
+      "checked": false,
+      "disabled": true,
+      "outgoing": true,
+      "open": true,
+      "number": 2,
+      "count": 64,
+      "percentage": 91,
+      "color": "#059669",
+      "target": "_self",
+      "ariaLabel": "Open advanced workflow 2",
+      "items": [
+        {
+          "label": "Nested option A",
+          "value": "nested-a"
+        },
+        {
+          "label": "Nested option B",
+          "value": "nested-b"
+        }
+      ],
+      "links": [
+        {
+          "label": "Documentation",
+          "href": "#documentation"
+        },
+        {
+          "label": "API reference",
+          "href": "#api-reference"
+        }
+      ],
+      "values": [
+        "Included",
+        "Unlimited"
+      ]
     }
   ]'
+  size="lg"
+  variant="success"
+  overflowLabel="Advanced example"
 />
-
Component events

Events

Public events declared by this component. Custom events bubble from the component root and expose state through event.detail.

@overflowFires when the component emits the overflow event.
Event listener.js
const component = document.querySelector('[data-wrn-events]')
+        
Component events

Respond to every public interaction

Use declarative @event handlers in .wrn files or subscribe to the bubbling browser events from JavaScript.

@overflowFires when the component emits the overflow event.
Declarative handlers.wrn
<AvatarGroup
+  @overflow='console.log(event.detail)'
+/>
Browser listeners.js
const component = document.querySelector("[data-ui-component=\"AvatarGroup\"], [data-component=\"AvatarGroup\"]")
 
-component.addEventListener('overflow', (event) => {
-  console.log(event.detail)
-})
+component?.addEventListener("overflow", (event) => { + console.log("overflow", event.detail) +})
Component API

Props and configuration

All content and behavior shown above is supplied through these props and slots.

PropTypeDefaultRequired
itemsstring[]No
sizestring"md"No
colorstring"primary"No
variantstring"solid"No
shapestring"circle"No
layoutstring"stack"No
maxVisiblenumber4No
columnsnumber3No
borderColorstring""No
showTooltipsbooleantrueNo
overflowLabelstring"Show remaining members"No
classstring""No
@@ -76,17 +84,16 @@ page BlockquoteDetail {
Live preview
-
+ +
Component usage.wrn
<Blockquote
-  quote="Good design makes the complex understandable and the useful feel effortless."
-  citation="Josh Grazioso"
-  citationTitle="Product designer"
+  citationTitle="Compact Blockquote"
   size="sm"
-  color="info"
   align="center"
+  variant="secondary"
 />
@@ -99,30 +106,25 @@ page BlockquoteDetail {
Live preview
-
+ +
Component usage.wrn
<Blockquote
-  quote="The strongest product experiences are built when clarity, craft, and empathy reinforce one another."
-  citation="Josh Grazioso"
-  citationTitle="Source title"
-  citationUrl="#blockquote-demo"
-  avatarSrc="/avatar-example.svg"
-  avatarAlt="Josh Grazioso"
+  citationTitle="Advanced Blockquote"
   size="lg"
-  color="success"
-  variant="bordered"
-  quoteMark="false"
+  align="end"
+  variant="success"
 />
-
Component events

Events

Public events declared by this component. Custom events bubble from the component root and expose state through event.detail.

No public component events.
+
Component API

Props and configuration

All content and behavior shown above is supplied through these props and slots.

PropTypeDefaultRequired
quotestring"I just wanted to say that I'm very happy with my purchase so far. The documentation is outstanding - clear and detailed."No
citationstring""No
citationTitlestring""No
citationUrlstring""No
avatarSrcstring""No
avatarAltstring""No
sizestring"md"No
colorstring"primary"No
alignstring"left"No
variantstring"default"No
quoteMarkbooleantrueNo
italicbooleantrueNo
classstring""No
-
Component events

Events

Public events declared by this component. Custom events bubble from the component root and expose state through event.detail.

@clickFires when the component is activated by pointer or keyboard.
@focusFires when the component receives focus.
@blurFires when focus leaves the component.
Event listener.js
const component = document.querySelector('[data-wrn-events]')
+        
Component events

Respond to every public interaction

Use declarative @event handlers in .wrn files or subscribe to the bubbling browser events from JavaScript.

@clickFires when the interactive surface is activated.
@focusFires when the interactive control receives focus.
@blurFires when focus leaves the interactive control.
Declarative handlers.wrn
<Button
+  @click='console.log(event.detail)'
+  @focus='console.log(event.detail)'
+  @blur='console.log(event.detail)'
+/>
Browser listeners.js
const component = document.querySelector("[data-ui-component=\"Button\"], [data-component=\"Button\"]")
 
-component.addEventListener('click', (event) => {
-  console.log(event.detail)
-})
+component?.addEventListener("click", (event) => { + console.log("click", event.detail) +}) + +component?.addEventListener("focus", (event) => { + console.log("focus", event.detail) +}) + +component?.addEventListener("blur", (event) => { + console.log("blur", event.detail) +})
Component API

Props and configuration

All content and behavior shown above is supplied through these props and slots.

PropTypeDefaultRequired
labelstring"Button"No
loadingLabelstring"Loading…"No
descriptionstring""No
asstring""No
hrefstring""No
targetstring""No
relstring""No
typestring"button"No
variantstring"default"No
colorstring"primary"No
sizestring"default"No
disabledbooleanfalseNo
loadingbooleanfalseNo
pillbooleanfalseNo
fullWidthbooleanfalseNo
iconstring""No
iconPositionstring"start"No
ariaLabelstring""No
ariaPressedstring""No
ariaExpandedstring""No
ariaControlsstring""No
titlestring""No
autofocusbooleanfalseNo
controlClassstring""No
classstring""No