Files
Clintchiz 2c960fc1dc
Quality / quality (ubuntu-latest) (push) Failing after 9m49s
Quality / quality (windows-latest) (push) Canceled after 0s
refactor: migrate legacy wire namespace to wrn
2026-08-12 18:51:15 +05:30

237 lines
6.6 KiB
Plaintext

import AdvancedSelect from "@wrnexus/ui/components/AdvancedSelect.wrn"
import ComboBox from "@wrnexus/ui/components/Combobox.wrn"
// Component event test page. Route: /test
//
// Events bubble from the exact ComboBox or AdvancedSelect that emitted them.
// The <section> below listens once for every child component, while the first
// ComboBox also demonstrates a listener attached directly to one component.
page Test {
layout = "public"
state teams = [{ value: "design", label: "Design", description: "Product and visual design", icon: "icon-[lucide--palette]" }, { value: "engineering", label: "Engineering", description: "Platform engineering", icon: "icon-[lucide--code-2]" }, { value: "growth", label: "Growth", description: "Marketing and customer growth", icon: "icon-[lucide--trending-up]" }, { value: "support", label: "Support", description: "Customer operations", icon: "icon-[lucide--life-buoy]" }]
state eventName = "No event yet"
state eventSource = "Interact with a component"
state eventPayload = "{}"
state selectedTeam = ""
seo {
title = "Component event test"
description = "Test ComboBox and AdvancedSelect events on one WRN page."
canonical = "/test"
}
functions {
function handleComponentEvent(event) {
eventName = event.type
eventSource = event.target.getAttribute("data-field") || event.detail.component
eventPayload = JSON.stringify(event.detail, null, 2)
}
function handleTeamSelect(event) {
selectedTeam = event.detail.value
}
}
view {
<header class="test-hero">
<span>WRN component events</span>
<h1>ComboBox and AdvancedSelect event test</h1>
<p>
This page contains multiple component instances. Every component has a
unique <code>id</code> and <code>data-field</code>, so the event source
is always identifiable.
</p>
</header>
<!--
Event delegation: these eight listeners receive events from every
ComboBox and AdvancedSelect inside this section because the custom events
bubble from their component roots.
-->
<section
class="test-grid"
@search="handleComponentEvent(event)"
@select="handleComponentEvent(event)"
@change="handleComponentEvent(event)"
@clear="handleComponentEvent(event)"
@open="handleComponentEvent(event)"
@close="handleComponentEvent(event)"
@load="handleComponentEvent(event)"
@error="handleComponentEvent(event)"
>
<article class="test-card">
<span class="test-card__type">Direct listener</span>
<h2>Team ComboBox</h2>
<p>
Its <code>@select</code> listener updates the selected-team
text below. The delegated section listener also receives the event.
</p>
<ComboBox
id="team-combobox"
data-field="team-combobox"
name="team"
label="Choose a team"
placeholder="Search teams"
options="{teams}"
optionTemplate="icon"
@select="handleTeamSelect(event)"
/>
<output class="test-selection">
Selected team: {selectedTeam || "None"}
</output>
</article>
<article class="test-card">
<span class="test-card__type">Second instance</span>
<h2>Reviewer ComboBox</h2>
<p>
This is another ComboBox on the same page. Its events remain
distinguishable through <code>data-field="reviewer-combobox"</code>.
</p>
<ComboBox
id="reviewer-combobox"
data-field="reviewer-combobox"
name="reviewer"
label="Choose a reviewer team"
placeholder="Search reviewer teams"
options="{teams}"
/>
</article>
<article class="test-card">
<span class="test-card__type">Multiple selection</span>
<h2>Project teams</h2>
<p>
AdvancedSelect emits the same event names. Multiple values are
available through <code>event.detail.values</code>.
</p>
<AdvancedSelect
id="project-teams"
data-field="project-teams"
name="projectTeams"
label="Assign project teams"
placeholder="Choose one or more teams"
options="{teams}"
multiple
showCounter
maxSelections="3"
optionTemplate="icon"
/>
</article>
<aside class="event-monitor" aria-live="polite">
<div>
<span>Latest event</span>
<strong>{eventName}</strong>
</div>
<div>
<span>Source component</span>
<strong>{eventSource}</strong>
</div>
<pre><code>{eventPayload}</code></pre>
</aside>
</section>
}
style {
.test-hero {
display: grid;
max-width: 52rem;
gap: 0.75rem;
margin-block: 3rem 2rem;
}
.test-hero > span,
.test-card__type,
.event-monitor span {
color: var(--wrn-color-primary);
font-size: 0.72rem;
font-weight: 800;
letter-spacing: 0.08em;
text-transform: uppercase;
}
.test-hero h1,
.test-card h2,
.test-hero p,
.test-card p {
margin: 0;
}
.test-hero p,
.test-card p {
color: var(--wrn-color-muted);
line-height: 1.65;
}
.test-grid {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 1rem;
margin-bottom: 4rem;
}
.test-card,
.event-monitor {
display: grid;
align-content: start;
gap: 1rem;
padding: clamp(1rem, 3vw, 1.5rem);
border: 1px solid var(--wrn-color-border);
border-radius: var(--wrn-radius-lg);
background: var(--wrn-color-surface);
box-shadow: var(--wrn-shadow-1);
}
.test-selection {
color: var(--wrn-color-muted);
font-size: 0.82rem;
}
.event-monitor {
position: sticky;
bottom: 1rem;
grid-column: 1 / -1;
grid-template-columns: repeat(2, minmax(0, 1fr));
background: color-mix(in srgb, var(--wrn-color-surface) 94%, var(--wrn-color-primary));
}
.event-monitor > div {
display: grid;
gap: 0.35rem;
}
.event-monitor pre {
grid-column: 1 / -1;
max-height: 18rem;
overflow: auto;
margin: 0;
padding: 1rem;
border-radius: var(--wrn-radius-md);
background: var(--wrn-color-bg);
font-size: 0.75rem;
line-height: 1.65;
white-space: pre-wrap;
}
@media (max-width: 760px) {
.test-grid {
grid-template-columns: 1fr;
}
.event-monitor {
grid-template-columns: 1fr;
}
.event-monitor pre {
grid-column: auto;
}
}
}
}