Page not found
The address may be outdated or misspelled. No private or duplicate route is exposed here.
diff --git a/app/pages/404.wrn b/app/pages/404.wrn
index 891e58d8..543e4147 100644
--- a/app/pages/404.wrn
+++ b/app/pages/404.wrn
@@ -7,10 +7,10 @@ page Pagenotfound {
view {
The address may be outdated or misspelled. No private or duplicate route is exposed here.
WRNexusJS 0.4.0 packages are not available from the public npm registry. Installation requires approval and private registry credentials supplied by WorkRoot. Never paste registry tokens into source control, issue reports, or support messages.
bunx @wrnexus/cli@0.4.0 create my-appAccess approval, response time, licensing terms, and support level remain owner-controlled. This site does not collect access requests directly.
WRNexusJS 0.5.0 packages are not available from the public npm registry. Installation requires approval and private registry credentials supplied by WorkRoot. Never paste registry tokens into source control, issue reports, or support messages.
bunx @wrnexus/cli@0.5.0 create my-appAccess approval, response time, licensing terms, and support level remain owner-controlled. This site does not collect access requests directly.
WRNexusJS is Bun-native and SSR-first. File discovery maps pages and API handlers; middleware enriches or short-circuits a request; the compiler turns .wrn declarations into server render functions and small feature runtimes.
core owns contexts, middleware, sessions and rooms; router discovers routes; compiler parses .wrn; ssr renders documents; csr supplies browser runtimes; dev-server and cli orchestrate development and builds.
Validation happens at trust boundaries. Session authentication establishes identity; authorization makes resource decisions. CSP, Trusted Types, CSRF, upload checks, WebSocket origins, request limits, and output escaping are layered controls—not substitutes for application policy.
Rooms are process-local unless connected through pub/sub. Redis-backed pub/sub distributes events. Queue durability depends on the selected driver and must be evaluated explicitly.
The gateway can dispatch multiple applications while preserving route, component, asset, config, and session boundaries. Validate host routing and isolation before production.
wrnexus build . produces dist/server.js and hashed/static assets. Run the server with Bun, apply migrations before traffic, terminate TLS at a trusted edge, and forward only expected proxy headers.
Mobile compatibility bridges SSR-safe Capacitor capabilities; native route generation is experimental and is not general web portability. Test each target platform.
app/routes.gen.ts, .wrnexus/, and dist/ are generated. The runtime is Bun-only. Preview packages are private. Historical compatibility and long-term support policy are not yet published.
WRNexusJS is Bun-native and SSR-first. File discovery maps pages and API handlers; middleware enriches or short-circuits a request; the compiler turns .wrn declarations into server render functions and small feature runtimes.
core owns contexts, middleware, sessions and rooms; router discovers routes; compiler parses .wrn; ssr renders documents; csr supplies browser runtimes; dev-server and cli orchestrate development and builds.
Validation happens at trust boundaries. Session authentication establishes identity; authorization makes resource decisions. CSP, Trusted Types, CSRF, upload checks, WebSocket origins, request limits, and output escaping are layered controls—not substitutes for application policy.
Rooms are process-local unless connected through pub/sub. Redis-backed pub/sub distributes events. Queue durability depends on the selected driver and must be evaluated explicitly.
The gateway can dispatch multiple applications while preserving route, component, asset, config, and session boundaries. Validate host routing and isolation before production.
wrnexus build . produces dist/server.js and hashed/static assets. Run the server with Bun, apply migrations before traffic, terminate TLS at a trusted edge, and forward only expected proxy headers.
Mobile compatibility bridges SSR-safe Capacitor capabilities; native route generation is experimental and is not general web portability. Test each target platform.
app/routes.gen.ts, .wrnexus/, and dist/ are generated. The runtime is Bun-only. Preview packages are private. Historical compatibility and long-term support policy are not yet published.
No comparative speed claims are published. A valid baseline must record scripts, commit, Bun/framework versions, hardware, OS, warmup, samples, workload, raw results, median, percentiles, memory, HTML size, browser JavaScript size, and run date.
The roadmap starts with WRNexusJS-only measurements before any maintained equivalent-workload comparison.
Documentation is aligned to all 30 installed packages. This release adds @wrnexus/helpers, original-request URL helpers, safe login redirects, working wrnexus workspace add, and forward-auth redirect propagation.
Run wrnexus update --latest and keep every @wrnexus/* package on 0.4.0. Existing applications must explicitly add @wrnexus/helpers before importing it; newly scaffolded applications include it automatically.
The packages use semantic-looking versions, but a formal compatibility and old-release support policy has not been approved. Preview consumers should treat minor releases as potentially requiring migration review.
Documentation is aligned to all 31 installed packages. This release adds @wrnexus/helpers, original-request URL helpers, safe login redirects, working wrnexus workspace add, and forward-auth redirect propagation.
Run wrnexus update --latest and keep every @wrnexus/* package on 0.5.0. Existing applications must explicitly add @wrnexus/helpers before importing it; newly scaffolded applications include it automatically.
The packages use semantic-looking versions, but a formal compatibility and old-release support policy has not been approved. Preview consumers should treat minor releases as potentially requiring migration review.
Production-ready, server-rendered components documented directly from the installed .wrn sources.
Showing {category} components
Theme-aware, responsive accordion component.
View component → -integrationsTheme-aware, responsive advanced date picker component.
View component → -integrationsTheme-aware, responsive advanced range slider component.
View component → +Production-ready, server-rendered components documented directly from the installed .wrn sources.
Showing {category} components
Theme-aware, responsive accordion component.
View component → +integrationsTheme-aware, responsive advanced date picker component.
View component → +integrationsTheme-aware, responsive advanced range slider component.
View component → advanced-formsTheme-aware, responsive advanced select component.
View component → -baseTheme-aware, responsive alert component.
View component → -baseTheme-aware, responsive avatar component.
View component → -baseTheme-aware, responsive avatar group component.
View component → -baseTheme-aware, responsive badge component.
View component → -baseTheme-aware, responsive blockquote component.
View component → -navigationTheme-aware, responsive breadcrumb component.
View component → -baseTheme-aware, responsive button component.
View component → -baseTheme-aware, responsive button group component.
View component → -baseTheme-aware, responsive card component.
View component → -baseTheme-aware, responsive carousel component.
View component → -integrationsTheme-aware, responsive chart component.
View component → -baseTheme-aware, responsive chat bubble component.
View component → -formsTheme-aware, responsive checkbox component.
View component → -integrationsTheme-aware, responsive clipboard component.
View component → -baseTheme-aware, responsive collapse component.
View component → -formsTheme-aware, responsive color picker component.
View component → +baseTheme-aware, responsive alert component.
View component → +baseTheme-aware, responsive avatar component.
View component → +baseTheme-aware, responsive avatar group component.
View component → +baseTheme-aware, responsive badge component.
View component → +baseTheme-aware, responsive blockquote component.
View component → +navigationTheme-aware, responsive breadcrumb component.
View component → +baseTheme-aware, responsive button component.
View component → +baseTheme-aware, responsive button group component.
View component → +baseTheme-aware, responsive card component.
View component → +baseTheme-aware, responsive carousel component.
View component → +integrationsTheme-aware, responsive chart component.
View component → +baseTheme-aware, responsive chat bubble component.
View component → +formsTheme-aware, responsive checkbox component.
View component → +integrationsTheme-aware, responsive clipboard component.
View component → +baseTheme-aware, responsive collapse component.
View component → +formsTheme-aware, responsive color picker component.
View component → layoutTheme-aware, responsive columns component.
View component → advanced-formsEditable autocomplete combobox with local and remote suggestions.
View component → -integrationsTheme-aware, responsive confetti component.
View component → +integrationsTheme-aware, responsive confetti component.
View component → layoutTheme-aware, responsive container component.
View component → -overlaysTheme-aware, responsive context menu component.
View component → -advanced-formsTheme-aware, responsive copy markup component.
View component → -layoutTheme-aware, responsive custom scrollbar component.
View component → -integrationsTheme-aware, responsive data map component.
View component → -integrationsTheme-aware, responsive data table component.
View component → -baseTheme-aware, responsive date picker component.
View component → -baseTheme-aware, responsive device frame component.
View component → +overlaysTheme-aware, responsive context menu component.
View component → +advanced-formsTheme-aware, responsive copy markup component.
View component → +layoutTheme-aware, responsive custom scrollbar component.
View component → +integrationsTheme-aware, responsive data map component.
View component → +integrationsTheme-aware, responsive data table component.
View component → +baseTheme-aware, responsive date picker component.
View component → +baseTheme-aware, responsive device frame component.
View component → layoutTheme-aware, responsive divider component.
View component → -integrationsTheme-aware, responsive drag and drop component.
View component → -overlaysTheme-aware, responsive drawer component.
View component → -overlaysTheme-aware, responsive dropdown component.
View component → -formsTheme-aware, responsive file input component.
View component → -integrationsTheme-aware, responsive file upload component.
View component → -baseTheme-aware, responsive file upload progress component.
View component → +integrationsTheme-aware, responsive drag and drop component.
View component → +overlaysTheme-aware, responsive drawer component.
View component → +overlaysTheme-aware, responsive dropdown component.
View component → +formsTheme-aware, responsive file input component.
View component → +integrationsTheme-aware, responsive file upload component.
View component → +baseTheme-aware, responsive file upload progress component.
View component → layoutTheme-aware, responsive grid component.
View component → -layoutTheme-aware, responsive image component.
View component → -formsTheme-aware, responsive input component.
View component → -formsTheme-aware, responsive input group component.
View component → +layoutTheme-aware, responsive image component.
View component → +formsTheme-aware, responsive input component.
View component → +formsTheme-aware, responsive input group component.
View component → advanced-formsTheme-aware, responsive input number component.
View component → layoutTheme-aware, responsive kbd component.
View component → -layoutTheme-aware, responsive layout splitter component.
View component → -baseTheme-aware, responsive legend indicator component.
View component → -layoutTheme-aware, responsive link component.
View component → -baseTheme-aware, responsive list component.
View component → -baseTheme-aware, responsive list group component.
View component → -integrationsTheme-aware, responsive map component.
View component → -baseTheme-aware, responsive marquee component.
View component → -navigationTheme-aware, responsive mega menu component.
View component → -overlaysTheme-aware, responsive modal component.
View component → -navigationTheme-aware, responsive nav component.
View component → -navigationTheme-aware, responsive navbar component.
View component → -navigationTheme-aware, responsive pagination component.
View component → +layoutTheme-aware, responsive layout splitter component.
View component → +baseTheme-aware, responsive legend indicator component.
View component → +layoutTheme-aware, responsive link component.
View component → +baseTheme-aware, responsive list component.
View component → +baseTheme-aware, responsive list group component.
View component → +integrationsTheme-aware, responsive map component.
View component → +baseTheme-aware, responsive marquee component.
View component → +navigationTheme-aware, responsive mega menu component.
View component → +overlaysTheme-aware, responsive modal component.
View component → +navigationTheme-aware, responsive nav component.
View component → +navigationTheme-aware, responsive navbar component.
View component → +navigationTheme-aware, responsive pagination component.
View component → advanced-formsSecure multi-cell PIN and verification-code input with regex and paste support.
View component → -overlaysTheme-aware, responsive popover component.
View component → +overlaysTheme-aware, responsive popover component.
View component → baseTheme-aware, responsive progress component.
View component → -formsTheme-aware, responsive radio component.
View component → -formsTheme-aware, responsive range slider component.
View component → -baseTheme-aware, responsive rating component.
View component → -navigationTheme-aware, responsive scrollspy component.
View component → -advanced-formsTheme-aware, responsive search box component.
View component → -formsTheme-aware, responsive select component.
View component → -navigationTheme-aware, responsive sidebar component.
View component → +formsTheme-aware, responsive radio component.
View component → +formsTheme-aware, responsive range slider component.
View component → +baseTheme-aware, responsive rating component.
View component → +navigationTheme-aware, responsive scrollspy component.
View component → +advanced-formsTheme-aware, responsive search box component.
View component → +formsTheme-aware, responsive select component.
View component → +navigationTheme-aware, responsive sidebar component.
View component → baseTheme-aware, responsive skeleton component.
View component → baseTheme-aware, responsive spinner component.
View component → -navigationTheme-aware, responsive stepper component.
View component → +navigationTheme-aware, responsive stepper component.
View component → advanced-formsTheme-aware, responsive strong password component.
View component → baseTheme-aware, responsive styled icon component.
View component → -formsTheme-aware, responsive switch component.
View component → -tablesTheme-aware, responsive table component.
View component → -navigationTheme-aware, responsive tabs component.
View component → -formsTheme-aware, responsive textarea component.
View component → -baseTheme-aware, responsive timeline component.
View component → -formsTheme-aware, responsive time picker component.
View component → -baseTheme-aware, responsive toast component.
View component → -integrationsTheme-aware, responsive toast notifications component.
View component → -advanced-formsTheme-aware, responsive toggle count component.
View component → +formsTheme-aware, responsive switch component.
View component → +tablesTheme-aware, responsive table component.
View component → +navigationTheme-aware, responsive tabs component.
View component → +formsTheme-aware, responsive textarea component.
View component → +baseTheme-aware, responsive timeline component.
View component → +formsTheme-aware, responsive time picker component.
View component → +baseTheme-aware, responsive toast component.
View component → +integrationsTheme-aware, responsive toast notifications component.
View component → +advanced-formsTheme-aware, responsive toggle count component.
View component → advanced-formsAccessible password field with optional show and hide controls.
View component → -overlaysTheme-aware, responsive tooltip component.
View component → -baseTheme-aware, responsive tree view component.
View component → +overlaysTheme-aware, responsive tooltip component.
View component → +baseTheme-aware, responsive tree view component.
View component → layoutTheme-aware, responsive typography component.
View component → -integrationsTheme-aware, responsive wysiwyg editor component.
View component →Theme-aware, responsive wysiwyg editor component.
View component →Theme-aware, responsive accordion component.
Components are auto-discovered. Use the component directly in any .wrn view:
<Accordion
+ base componentAccordion
Theme-aware, responsive accordion component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Accordion
size="default"
color="primary"
+ variant="default"
+ id="accordion"
items="[]"
- multiple="false"
-/>
Legacy mount name: data-component="Accordion".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"itemsstringOptional []multiplebooleanOptional falseclassstringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/Accordion.wrn
component Accordion {
+/>
Legacy mount name: data-component="Accordion".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"variantstringOptional "default"classstringOptional ""idstringOptional "accordion"itemsstringOptional []defaultOpenstringOptional []multiplebooleanOptional falsealwaysOpenbooleanOptional falsedisabledbooleanOptional falseindicatorstringOptional "plus"indicatorPositionstringOptional "start"showIndicatorbooleanOptional trueborderedbooleanOptional falseseparatedbooleanOptional falseflushbooleanOptional falsecontentItalicbooleanOptional false
Slots
This component does not declare a slot.
Events
changeopenclose
Source contract
Installed source: components/Accordion.wrn
component Accordion {
props {
size = "default"
color = "primary"
- items = []
- multiple = false
+ variant = "default"
class = ""
+
+ id = "accordion"
+ items = []
+ defaultOpen = []
+ multiple = false
+ alwaysOpen = false
+ disabled = false
+
+ indicator = "plus"
+ indicatorPosition = "start"
+ showIndicator = true
+ bordered = false
+ separated = false
+ flush = false
+ contentItalic = false
+
+ @event change = function
+ @event open = function
+ @event close = function
}
+
+ state openValues = defaultOpen
+
+ functions {
+ function itemValue(item, index) {
+ return item.value !== undefined && item.value !== ""
+ ? String(item.value)
+ : String(index)
+ }
+
+ function nestedValue(parent, parentIndex, item, index) {
+ return itemValue(parent, parentIndex) + "." + itemValue(item, index)
+ }
+
+ function isOpen(value) {
+ return openValues.includes(value)
+ }
+
+ function allowsMultiple() {
+ return multiple || alwaysOpen
+ }
+
+ function dispatchAccordionEvent(sourceEvent, eventName, value, item, root, customEvent) {
+ root = sourceEvent.currentTarget.closest("[data-wrn-accordion]")
+
+ if (!root) {
+ return
+ }
+
+ customEvent = document.createEvent("CustomEvent")
+ customEvent.initCustomEvent(eventName, true, false, {
+ component: "Accordion",
+ value: value,
+ item: item,
+ open: isOpen(value),
+ openValues: openValues
+ })
+ root.dispatchEvent(customEvent)
+ }
+
+ function toggleItem(sourceEvent, value, item, wasOpen) {
+ if (disabled || item.disabled) {
+ return
+ }
+
+ wasOpen = isOpen(value)
+
+ if (wasOpen) {
+ openValues = openValues.filter((entry) => entry !== value)
+ } else if (allowsMultiple()) {
+ openValues = openValues.concat([value])
+ } else {
+ openValues = [value]
+ }
+
+ dispatchAccordionEvent(
+ sourceEvent,
+ wasOpen ? "close" : "open",
+ value,
+ item
+ )
+ dispatchAccordionEvent(sourceEvent, "change", value, item)
+ }
+
+ }
+
view {
- <div class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--accordion {class}">
- {#each items as item}<details open="{item.open}">
- <summary>{item.label}</summary>
- <div>{item.content}</div>
- </details>{/each}
- <slot />
+ <div
+ {...attrs}
+ id="{id}"
+ data-wrn-accordion
+ data-variant="{variant}"
+ data-indicator="{indicator}"
+ data-multiple="{allowsMultiple() ? 'true' : 'false'}"
+ class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--accordion wire-next--accordion-{variant} {bordered ? 'wire-next--accordion-bordered' : ''} {separated ? 'wire-next--accordion-separated' : ''} {flush ? 'wire-next--accordion-flush' : ''} {disabled ? 'wire-next--disabled' : ''} {class}"
+ >
+ {#each items as item, index}
+ <section
+ class="wire-next__accordion-item"
+ data-open="{isOpen(itemValue(item, index)) ? 'true' : 'false'}"
+ data-disabled="{disabled || item.disabled ? 'true' : 'false'}"
+ >
+ <h3 class="wire-next__accordion-heading">
+ <button
+ type="button"
+ id="{id}-trigger-{index}"
+ aria-expanded="{isOpen(itemValue(item, index)) ? 'true' : 'false'}"
+ aria-controls="{id}-panel-{index}"
+ disabled="{disabled || item.disabled}"
+ @click="toggleItem(event, itemValue(item, index), item)"
+ >
+ {#if showIndicator && indicatorPosition === "start"}
+ <span class="wire-next__accordion-indicator" aria-hidden="true">
+ {#if indicator === "chevron"}
+ <span class="icon-[lucide--chevron-down]">
+ </span>
+ {:else}
+ <span>+</span>
+ {/if}
+ </span>
+ {/if}
+ <span>{item.label || item.title}</span>
+ {#if showIndicator && indicatorPosition === "end"}
+ <span class="wire-next__accordion-indicator" aria-hidden="true">
+ {#if indicator === "chevron"}
+ <span class="icon-[lucide--chevron-down]">
+ </span>
+ {:else}
+ <span>+</span>
+ {/if}
+ </span>
+ {/if}
+ </button>
+ </h3>
+ <div
+ id="{id}-panel-{index}"
+ class="wire-next__accordion-panel"
+ role="region"
+ aria-labelledby="{id}-trigger-{index}"
+ aria-hidden="{isOpen(itemValue(item, index)) ? 'false' : 'true'}"
+ >
+ <div>
+ <div class="wire-next__accordion-content {contentItalic ? 'wire-next__accordion-content-italic' : ''}">
+ {#if item.content}<p>{item.content}</p>{/if}
+
+ {#if item.children && item.children.length > 0}
+ <div class="wire-next__accordion-nested">
+ {#each item.children as child, childIndex}
+ <section
+ class="wire-next__accordion-item"
+ data-open="{isOpen(nestedValue(item, index, child, childIndex)) ? 'true' : 'false'}"
+ >
+ <h4 class="wire-next__accordion-heading">
+ <button
+ type="button"
+ id="{id}-trigger-{index}-{childIndex}"
+ aria-expanded="{isOpen(nestedValue(item, index, child, childIndex)) ? 'true' : 'false'}"
+ aria-controls="{id}-panel-{index}-{childIndex}"
+ disabled="{disabled || child.disabled}"
+ @click="toggleItem(event, nestedValue(item, index, child, childIndex), child)"
+ >
+ {#if showIndicator}
+ <span class="wire-next__accordion-indicator" aria-hidden="true">
+ {#if indicator === "chevron"}
+ <span class="icon-[lucide--chevron-down]">
+ </span>
+ {:else}
+ <span>+</span>
+ {/if}
+ </span>
+ {/if}
+ <span>{child.label || child.title}</span>
+ </button>
+ </h4>
+ <div
+ id="{id}-panel-{index}-{childIndex}"
+ class="wire-next__accordion-panel"
+ role="region"
+ aria-labelledby="{id}-trigger-{index}-{childIndex}"
+ aria-hidden="{isOpen(nestedValue(item, index, child, childIndex)) ? 'false' : 'true'}"
+ >
+ <div>
+ <div class="wire-next__accordion-content {contentItalic ? 'wire-next__accordion-content-italic' : ''}">
+ <p>{child.content}</p>
</div>
+ </div>
+ </div>
+ </section>
+ {/each}
+ </div>
+ {/if}
+ </div>
+ </div>
+ </div>
+ </section>
+ {/each}
+ </div>
}
}
-
+
}
diff --git a/app/pages/components/advanced-date-picker.wrn b/app/pages/components/advanced-date-picker.wrn
index 2e08537e..522bfdd6 100644
--- a/app/pages/components/advanced-date-picker.wrn
+++ b/app/pages/components/advanced-date-picker.wrn
@@ -10,17 +10,22 @@ page AdvancedDatePickercomponent {
W WRNexusJS
-
+
Browse documentation
- integrations componentAdvancedDatePicker
Theme-aware, responsive advanced date picker component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<AdvancedDatePicker
+ integrations componentAdvancedDatePicker
Theme-aware, responsive advanced date picker component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<AdvancedDatePicker
size="default"
color="primary"
title="Advanced Date Picker"
description="description"
items="[]"
-/>
Legacy mount name: data-component="AdvancedDatePicker".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"titlestringOptional "Advanced Date Picker"descriptionstringOptional ""itemsstringOptional []variantstringOptional "default"classstringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/AdvancedDatePicker.wrn
component AdvancedDatePicker {
+/>
Legacy mount name: data-component="AdvancedDatePicker".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"titlestringOptional "Advanced Date Picker"descriptionstringOptional ""itemsstringOptional []variantstringOptional "default"classstringOptional ""
Slots
default
Events
inputchangeopencloseclear
Source contract
Installed source: components/AdvancedDatePicker.wrn
component AdvancedDatePicker {
props {
+ @event input = function
+ @event change = function
+ @event open = function
+ @event close = function
+ @event clear = function
size = "default"
color = "primary"
title = "Advanced Date Picker"
@@ -39,7 +44,7 @@ page AdvancedDatePickercomponent {
}
}
-
+
}
diff --git a/app/pages/components/advanced-range-slider.wrn b/app/pages/components/advanced-range-slider.wrn
index 6a943ed7..23aded89 100644
--- a/app/pages/components/advanced-range-slider.wrn
+++ b/app/pages/components/advanced-range-slider.wrn
@@ -10,17 +10,21 @@ page AdvancedRangeSlidercomponent {
W WRNexusJS
-
+
Browse documentation
- integrations componentAdvancedRangeSlider
Theme-aware, responsive advanced range slider component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<AdvancedRangeSlider
+ integrations componentAdvancedRangeSlider
Theme-aware, responsive advanced range slider component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<AdvancedRangeSlider
size="default"
color="primary"
title="Advanced Range Slider"
description="description"
items="[]"
-/>
Legacy mount name: data-component="AdvancedRangeSlider".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"titlestringOptional "Advanced Range Slider"descriptionstringOptional ""itemsstringOptional []variantstringOptional "default"classstringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/AdvancedRangeSlider.wrn
component AdvancedRangeSlider {
+/>
Legacy mount name: data-component="AdvancedRangeSlider".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"titlestringOptional "Advanced Range Slider"descriptionstringOptional ""itemsstringOptional []variantstringOptional "default"classstringOptional ""
Slots
default
Events
inputchangestartend
Source contract
Installed source: components/AdvancedRangeSlider.wrn
component AdvancedRangeSlider {
props {
+ @event input = function
+ @event change = function
+ @event start = function
+ @event end = function
size = "default"
color = "primary"
title = "Advanced Range Slider"
@@ -39,7 +43,7 @@ page AdvancedRangeSlidercomponent {
}
}
-
+
}
diff --git a/app/pages/components/advanced-select.wrn b/app/pages/components/advanced-select.wrn
index 1a03e5bb..f93d055f 100644
--- a/app/pages/components/advanced-select.wrn
+++ b/app/pages/components/advanced-select.wrn
@@ -10,10 +10,10 @@ page AdvancedSelectcomponent {
W WRNexusJS
-
+
Browse documentation
- advanced-forms componentAdvancedSelect
Theme-aware, responsive advanced select component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<AdvancedSelect
+ advanced-forms componentAdvancedSelect
Theme-aware, responsive advanced select component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<AdvancedSelect
size="default"
color="primary"
label="Advanced Select"
@@ -486,7 +486,7 @@ page AdvancedSelectcomponent {
}
}
-
+
}
diff --git a/app/pages/components/alert.wrn b/app/pages/components/alert.wrn
index cd113258..b66f3062 100644
--- a/app/pages/components/alert.wrn
+++ b/app/pages/components/alert.wrn
@@ -10,36 +10,165 @@ page Alertcomponent {
W WRNexusJS
-
+
Browse documentation
- base componentAlert
Theme-aware, responsive alert component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Alert
+ base componentAlert
Theme-aware, responsive alert component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Alert
size="default"
- color="primary"
- title="Alert"
- description="description"
- items="[]"
-/>
Legacy mount name: data-component="Alert".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"titlestringOptional "Alert"descriptionstringOptional ""itemsstringOptional []variantstringOptional "default"classstringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/alert.wrn
component Alert {
+ color="info"
+ variant="soft"
+ radius="md"
+ shadow="sm"
+/>
Legacy mount name: data-component="Alert".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "info"variantstringOptional "soft"classstringOptional ""radiusstringOptional "md"shadowstringOptional "sm"titlestringOptional "Alert"descriptionstringOptional ""itemsstringOptional []actionsstringOptional []showIconbooleanOptional falseiconstringOptional ""dismissiblebooleanOptional falsedismissLabelstringOptional "Dismiss alert"rolestringOptional "alert"livestringOptional "polite"linkLabelstringOptional ""linkHrefstringOptional ""actionLabelstringOptional ""actionHrefstringOptional ""compactbooleanOptional false
Slots
This component does not declare a slot.
Events
dismissaction
Source contract
Installed source: components/alert.wrn
component Alert {
props {
size = "default"
- color = "primary"
+ color = "info"
+ variant = "soft"
+ class = ""
+ radius = "md"
+ shadow = "sm"
+
title = "Alert"
description = ""
items = []
- variant = "default"
- class = ""
+ actions = []
+
+ showIcon = false
+ icon = ""
+ dismissible = false
+ dismissLabel = "Dismiss alert"
+ role = "alert"
+ live = "polite"
+
+ linkLabel = ""
+ linkHref = ""
+ actionLabel = ""
+ actionHref = ""
+ compact = false
+
+ @event dismiss = function
+ @event action = function
}
+
+ state visible = true
+
+ functions {
+ function dispatchAlertEvent(sourceEvent, eventName, action, root, customEvent) {
+ root = sourceEvent.currentTarget.closest("[data-wrn-alert]")
+
+ if (!root) {
+ return
+ }
+
+ customEvent = document.createEvent("CustomEvent")
+ customEvent.initCustomEvent(eventName, true, false, {
+ component: "Alert",
+ title: title,
+ color: color,
+ variant: variant,
+ action: action
+ })
+ root.dispatchEvent(customEvent)
+ }
+
+ function dismissAlert(sourceEvent) {
+ visible = false
+ dispatchAlertEvent(sourceEvent, "dismiss", null)
+ }
+
+ function selectAction(sourceEvent, action) {
+ dispatchAlertEvent(sourceEvent, "action", action)
+ }
+ }
+
view {
- <section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--alert wire-next--variant-{variant} {class}">
- {#if title}<strong>{title}</strong>{/if}
- {#if description}<p>{description}</p>{/if}
- {#if items}<div class="wire-next__items">{#each items as item}<span>{item.label}</span>{/each}</div>{/if}
- <slot />
- </section>
+ <section
+ {...attrs}
+ data-wrn-alert
+ data-color="{color}"
+ data-variant="{variant}"
+ data-radius="{radius}"
+ data-shadow="{shadow}"
+ data-show="visible"
+ aria-hidden="{visible ? 'false' : 'true'}"
+ role="{role}"
+ aria-live="{live}"
+ class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--alert wire-next--alert-{variant} {compact ? 'wire-next--alert-compact' : ''} {class}"
+ >
+ {#if showIcon}
+ <span class="wire-next__alert-icon" aria-hidden="true">
+ {#if icon}
+ <span class="{icon}">
+ </span>
+ {:else if color === "success"}
+ <span class="icon-[lucide--circle-check]">
+ </span>
+ {:else if color === "danger"}
+ <span class="icon-[lucide--circle-x]">
+ </span>
+ {:else if color === "warning"}
+ <span class="icon-[lucide--triangle-alert]">
+ </span>
+ {:else}
+ <span class="icon-[lucide--info]">
+ </span>
+ {/if}
+ </span>
+ {/if}
+
+ <div class="wire-next__alert-body">
+ {#if title}<strong class="wire-next__alert-title">{title}</strong>{/if}
+ {#if description}<p>{description}</p>{/if}
+
+ {#if items.length > 0}
+ <ul>
+ {#each items as item}<li>{item.label || item}</li>{/each}
+ </ul>
+ {/if}
+
+ {#if actions.length > 0 || actionLabel || linkLabel}
+ <div class="wire-next__alert-actions">
+ {#each actions as item}
+ <a
+ href="{item.href || '#'}"
+ data-variant="{item.variant || 'link'}"
+ @click="selectAction(event, item)"
+ >{item.label}</a>
+ {/each}
+ {#if actionLabel}
+ <a
+ href="{actionHref || '#'}"
+ data-variant="action"
+ @click="selectAction(event, { label: actionLabel, href: actionHref })"
+ >{actionLabel}</a>
+ {/if}
+ {#if linkLabel}
+ <a
+ href="{linkHref || '#'}"
+ data-variant="link"
+ @click="selectAction(event, { label: linkLabel, href: linkHref })"
+ >{linkLabel}</a>
+ {/if}
+ </div>
+ {/if}
+ </div>
+
+ {#if dismissible}
+ <button
+ type="button"
+ class="wire-next__alert-dismiss"
+ aria-label="{dismissLabel}"
+ @click="dismissAlert(event)"
+ >
+ <span class="icon-[lucide--x]" aria-hidden="true">
+ </span>
+ </button>
+ {/if}
+ </section>
}
}
-
+
}
diff --git a/app/pages/components/avatar-group.wrn b/app/pages/components/avatar-group.wrn
index e147b2de..ccc5bd0b 100644
--- a/app/pages/components/avatar-group.wrn
+++ b/app/pages/components/avatar-group.wrn
@@ -10,36 +10,138 @@ page AvatarGroupcomponent {
W WRNexusJS
-
+
Browse documentation
- base componentAvatarGroup
Theme-aware, responsive avatar group component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<AvatarGroup
- size="default"
- color="primary"
- title="Avatar Group"
- description="description"
+ base componentAvatarGroup
Theme-aware, responsive avatar group component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<AvatarGroup
items="[]"
-/>
Legacy mount name: data-component="AvatarGroup".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"titlestringOptional "Avatar Group"descriptionstringOptional ""itemsstringOptional []variantstringOptional "default"classstringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/AvatarGroup.wrn
component AvatarGroup {
+ size="md"
+ color="primary"
+ variant="solid"
+ shape="circle"
+/>
Legacy mount name: data-component="AvatarGroup".
Props and attributes
Prop Type Requirement Default itemsstringOptional []sizestringOptional "md"colorstringOptional "primary"variantstringOptional "solid"shapestringOptional "circle"layoutstringOptional "stack"maxVisiblenumberOptional 4columnsnumberOptional 3borderColorstringOptional ""showTooltipsbooleanOptional trueoverflowLabelstringOptional "Show remaining members"classstringOptional ""
Slots
This component does not declare a slot.
Events
overflow
Source contract
Installed source: components/AvatarGroup.wrn
component AvatarGroup {
props {
- size = "default"
- color = "primary"
- title = "Avatar Group"
- description = ""
items = []
- variant = "default"
+ size = "md"
+ color = "primary"
+ variant = "solid"
+ shape = "circle"
+ layout = "stack"
+ maxVisible = 4
+ columns = 3
+ borderColor = ""
+ showTooltips = true
+ overflowLabel = "Show remaining members"
class = ""
+
+ @event overflow = function
}
+
+ state overflowOpen = false
+
+ functions {
+ function visibleMembers() {
+ return items.slice(0, Number(maxVisible))
+ }
+
+ function hiddenMembers() {
+ return items.slice(Number(maxVisible))
+ }
+
+ function toggleOverflow(sourceEvent, root, customEvent) {
+ overflowOpen = !overflowOpen
+ root = sourceEvent.currentTarget.closest("[data-wrn-avatar-group]")
+
+ customEvent = document.createEvent("CustomEvent")
+ customEvent.initCustomEvent("overflow", true, false, {
+ component: "AvatarGroup",
+ open: overflowOpen,
+ hiddenCount: hiddenMembers().length
+ })
+ root.dispatchEvent(customEvent)
+ }
+ }
+
view {
- <section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--avatar-group wire-next--variant-{variant} {class}">
- {#if title}<strong>{title}</strong>{/if}
- {#if description}<p>{description}</p>{/if}
- {#if items}<div class="wire-next__items">{#each items as item}<span>{item.label}</span>{/each}</div>{/if}
- <slot />
- </section>
+ <div
+ {...attrs}
+ class="wire-next wire-next--avatar-group {class}"
+ data-wrn-avatar-group
+ data-layout="{layout}"
+ data-shape="{shape}"
+ data-size="{size}"
+ style="--wire-avatar-group-columns:{columns}; --wire-avatar-group-ring:{borderColor || 'var(--wire-color-bg)'}"
+ role="group"
+ aria-label="Avatar group"
+ >
+ <div class="wire-next__avatar-group-members">
+ {#each visibleMembers() as item}
+ <span
+ class="wire-next__avatar-group-member"
+ data-size="{item.size || size}"
+ data-shape="{item.shape || shape}"
+ data-color="{item.color || color}"
+ data-variant="{item.variant || variant}"
+ tabindex="{showTooltips && (item.tooltip || item.name) ? '0' : '-1'}"
+ aria-label="{item.name || item.alt || item.initials || 'Group member'}"
+ >
+ <span class="wire-next__avatar-group-avatar">
+ {#if item.src}
+ <img src="{item.src}" alt="{item.alt || item.name || ''}" loading="lazy" />
+ {:else if item.initials}
+ <span aria-hidden="true">{item.initials}</span>
+ {:else}
+ <span class="icon-[lucide--user-round]" aria-hidden="true">
+ </span>
+ {/if}
+ </span>
+
+ {#if showTooltips && (item.tooltip || item.name)}
+ <span class="wire-next__avatar-group-tooltip" role="tooltip">
+ {item.tooltip || item.name}
+ </span>
+ {/if}
+ </span>
+ {/each}
+
+ {#if hiddenMembers().length > 0}
+ <span class="wire-next__avatar-group-overflow">
+ <button
+ type="button"
+ class="wire-next__avatar-group-overflow-button"
+ aria-label="{overflowLabel}"
+ aria-expanded="{overflowOpen ? 'true' : 'false'}"
+ @click="toggleOverflow(event)"
+ >
+ +{hiddenMembers().length}
+ </button>
+ <span
+ class="wire-next__avatar-group-menu"
+ role="menu"
+ data-show="overflowOpen"
+ aria-hidden="{overflowOpen ? 'false' : 'true'}"
+ >
+ {#each hiddenMembers() as item}
+ <span class="wire-next__avatar-group-menu-item" role="menuitem">
+ <span class="wire-next__avatar-group-menu-avatar">
+ {#if item.src}
+ <img src="{item.src}" alt="" loading="lazy" />
+ {:else}
+ <span>{item.initials || '?'}</span>
+ {/if}
+ </span>
+ <span>{item.name || item.alt || item.initials || 'Team member'}</span>
+ </span>
+ {/each}
+ </span>
+ </span>
+ {/if}
+ </div>
+ </div>
}
}
-
+
}
diff --git a/app/pages/components/avatar.wrn b/app/pages/components/avatar.wrn
index 04e528e5..4a4bf768 100644
--- a/app/pages/components/avatar.wrn
+++ b/app/pages/components/avatar.wrn
@@ -10,36 +10,107 @@ page Avatarcomponent {
W WRNexusJS
-
+
Browse documentation
- base componentAvatar
Theme-aware, responsive avatar component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Avatar
- size="default"
+ base componentAvatar
Theme-aware, responsive avatar component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Avatar
+ src="src"
+ alt="alt"
+ initials="initials"
+ size="md"
color="primary"
- title="Avatar"
- description="description"
- items="[]"
-/>
Legacy mount name: data-component="Avatar".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"titlestringOptional "Avatar"descriptionstringOptional ""itemsstringOptional []variantstringOptional "default"classstringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/avatar.wrn
component Avatar {
+/>
Legacy mount name: data-component="Avatar".
Props and attributes
Prop Type Requirement Default srcstringOptional ""altstringOptional ""initialsstringOptional ""sizestringOptional "md"colorstringOptional "primary"variantstringOptional "solid"shapestringOptional "circle"statusstringOptional ""statusLabelstringOptional ""statusPositionstringOptional "bottom"badgestringOptional ""badgeIconstringOptional ""badgeLabelstringOptional ""tooltipstringOptional ""namestringOptional ""descriptionstringOptional ""loadingstringOptional "lazy"classstringOptional ""
Slots
This component does not declare a slot.
Events
loaderrorclick
Source contract
Installed source: components/avatar.wrn
component Avatar {
props {
- size = "default"
+ @event load = function
+ @event error = function
+ @event click = function
+ src = ""
+ alt = ""
+ initials = ""
+ size = "md"
color = "primary"
- title = "Avatar"
+ variant = "solid"
+ shape = "circle"
+
+ status = ""
+ statusLabel = ""
+ statusPosition = "bottom"
+
+ badge = ""
+ badgeIcon = ""
+ badgeLabel = ""
+
+ tooltip = ""
+ name = ""
description = ""
- items = []
- variant = "default"
+ loading = "lazy"
class = ""
}
+
view {
- <section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--avatar wire-next--variant-{variant} {class}">
- {#if title}<strong>{title}</strong>{/if}
- {#if description}<p>{description}</p>{/if}
- {#if items}<div class="wire-next__items">{#each items as item}<span>{item.label}</span>{/each}</div>{/if}
- <slot />
- </section>
+ <span
+ {...attrs}
+ class="wire-next wire-next--avatar {description ? 'wire-next--avatar-media' : ''} {class}"
+ data-wrn-avatar
+ >
+ <span
+ class="wire-next__avatar-wrap"
+ data-shape="{shape}"
+ data-size="{size}"
+ data-color="{color}"
+ data-variant="{variant}"
+ data-status-position="{statusPosition}"
+ tabindex="{tooltip ? '0' : '-1'}"
+ aria-label="{tooltip || name || alt || initials || 'Avatar'}"
+ >
+ <span class="wire-next__avatar">
+ {#if src}
+ <img src="{src}" alt="{alt || name}" loading="{loading}" />
+ {:else if initials}
+ <span class="wire-next__avatar-initials" aria-hidden="true">{initials}</span>
+ {:else}
+ <span class="wire-next__avatar-placeholder icon-[lucide--user-round]" aria-hidden="true">
+ </span>
+ {/if}
+ </span>
+
+ {#if status}
+ <span
+ class="wire-next__avatar-status"
+ data-status="{status}"
+ title="{statusLabel || status}"
+ aria-label="{statusLabel || status}"
+ >
+ </span>
+ {/if}
+
+ {#if badgeIcon}
+ <span class="wire-next__avatar-badge" aria-label="{badgeLabel || 'Linked account'}">
+ <span class="{badgeIcon}" aria-hidden="true">
+ </span>
+ </span>
+ {:else if badge}
+ <span class="wire-next__avatar-badge wire-next__avatar-badge--text" aria-label="{badgeLabel || badge}">
+ {badge}
+ </span>
+ {/if}
+
+ {#if tooltip}
+ <span class="wire-next__avatar-tooltip" role="tooltip">{tooltip}</span>
+ {/if}
+ </span>
+
+ {#if description}
+ <span class="wire-next__avatar-copy">
+ <strong>{name || alt || initials}</strong>
+ <span>{description}</span>
+ </span>
+ {/if}
+ </span>
}
}
-
+
}
diff --git a/app/pages/components/badge.wrn b/app/pages/components/badge.wrn
index 849cc6e5..eeb92386 100644
--- a/app/pages/components/badge.wrn
+++ b/app/pages/components/badge.wrn
@@ -10,36 +10,125 @@ page Badgecomponent {
W WRNexusJS
-
+
Browse documentation
- base componentBadge
Theme-aware, responsive badge component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Badge
- size="default"
+ base componentBadge
Theme-aware, responsive badge component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Badge
+ label="Badge"
+ size="md"
color="primary"
- title="Badge"
- description="description"
- items="[]"
-/>
Legacy mount name: data-component="Badge".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"titlestringOptional "Badge"descriptionstringOptional ""itemsstringOptional []variantstringOptional "default"classstringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/badge.wrn
component Badge {
+ variant="solid"
+ shape="pill"
+/>
Legacy mount name: data-component="Badge".
Props and attributes
Prop Type Requirement Default labelstringOptional "Badge"sizestringOptional "md"colorstringOptional "primary"variantstringOptional "solid"shapestringOptional "pill"classstringOptional ""iconstringOptional ""iconPositionstringOptional "start"dotbooleanOptional falsedotOnlybooleanOptional falsedotLabelstringOptional "Status"animatedbooleanOptional falseavatarSrcstringOptional ""avatarAltstringOptional ""dismissiblebooleanOptional falsedismissLabelstringOptional "Remove badge"truncatebooleanOptional falsemaxWidthstringOptional "12rem"anchorLabelstringOptional ""anchorIconstringOptional ""placementstringOptional "inline"anchorLabelTextstringOptional "Badge anchor"
Slots
This component does not declare a slot.
Events
dismiss
Source contract
Installed source: components/Badge.wrn
component Badge {
props {
- size = "default"
+ label = "Badge"
+ size = "md"
color = "primary"
- title = "Badge"
- description = ""
- items = []
- variant = "default"
+ variant = "solid"
+ shape = "pill"
class = ""
+
+ icon = ""
+ iconPosition = "start"
+ dot = false
+ dotOnly = false
+ dotLabel = "Status"
+ animated = false
+
+ avatarSrc = ""
+ avatarAlt = ""
+ dismissible = false
+ dismissLabel = "Remove badge"
+ truncate = false
+ maxWidth = "12rem"
+
+ anchorLabel = ""
+ anchorIcon = ""
+ placement = "inline"
+ anchorLabelText = "Badge anchor"
+
+ @event dismiss = function
}
+
+ state visible = true
+
+ functions {
+ function dismissBadge(sourceEvent, root, customEvent) {
+ visible = false
+ root = sourceEvent.currentTarget.closest("[data-wrn-badge]")
+ customEvent = document.createEvent("CustomEvent")
+ customEvent.initCustomEvent("dismiss", true, false, {
+ component: "Badge",
+ label: label
+ })
+ root.dispatchEvent(customEvent)
+ }
+ }
+
view {
- <section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--badge wire-next--variant-{variant} {class}">
- {#if title}<strong>{title}</strong>{/if}
- {#if description}<p>{description}</p>{/if}
- {#if items}<div class="wire-next__items">{#each items as item}<span>{item.label}</span>{/each}</div>{/if}
- <slot />
- </section>
+ <span
+ {...attrs}
+ class="wire-next wire-next--badge-root {anchorLabel || anchorIcon ? 'wire-next--badge-anchored' : ''} {class}"
+ data-wrn-badge
+ data-placement="{placement}"
+ data-show="visible"
+ aria-hidden="{visible ? 'false' : 'true'}"
+ >
+ {#if anchorLabel || anchorIcon}
+ <button type="button" class="wire-next__badge-anchor" aria-label="{anchorLabelText}">
+ {#if anchorIcon}<span class="{anchorIcon}" aria-hidden="true">
+ </span>{/if}
+ {#if anchorLabel}<span>{anchorLabel}</span>{/if}
+ </button>
+ {/if}
+
+ <span
+ class="wire-next__badge"
+ data-size="{size}"
+ data-color="{color}"
+ data-variant="{variant}"
+ data-shape="{shape}"
+ data-animated="{animated ? 'true' : 'false'}"
+ style="--wire-badge-max-width:{maxWidth}"
+ role="{dotOnly ? 'status' : ''}"
+ aria-label="{dotOnly ? dotLabel : ''}"
+ >
+ {#if animated}
+ <span class="wire-next__badge-ping" aria-hidden="true">
+ </span>
+ {/if}
+ {#if avatarSrc}
+ <img class="wire-next__badge-avatar" src="{avatarSrc}" alt="{avatarAlt}" loading="lazy" />
+ {/if}
+ {#if dot || dotOnly}
+ <span class="wire-next__badge-dot" aria-hidden="true">
+ </span>
+ {/if}
+ {#if icon && iconPosition === "start"}
+ <span class="wire-next__badge-icon {icon}" aria-hidden="true">
+ </span>
+ {/if}
+ {#if !dotOnly}
+ <span class="wire-next__badge-label {truncate ? 'wire-next__badge-label--truncate' : ''}">
+ {label}
+ </span>
+ {/if}
+ {#if icon && iconPosition === "end"}
+ <span class="wire-next__badge-icon {icon}" aria-hidden="true">
+ </span>
+ {/if}
+ {#if dismissible}
+ <button type="button" class="wire-next__badge-dismiss" aria-label="{dismissLabel}" @click="dismissBadge(event)">
+ <span class="icon-[lucide--x]" aria-hidden="true">
+ </span>
+ </button>
+ {/if}
+ </span>
+ </span>
}
}
-
+
}
diff --git a/app/pages/components/blockquote.wrn b/app/pages/components/blockquote.wrn
index 0a28876b..226d9172 100644
--- a/app/pages/components/blockquote.wrn
+++ b/app/pages/components/blockquote.wrn
@@ -10,36 +10,86 @@ page Blockquotecomponent {
W WRNexusJS
-
+
Browse documentation
- base componentBlockquote
Theme-aware, responsive blockquote component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Blockquote
- size="default"
- color="primary"
- title="Blockquote"
- description="description"
- items="[]"
-/>
Legacy mount name: data-component="Blockquote".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"titlestringOptional "Blockquote"descriptionstringOptional ""itemsstringOptional []variantstringOptional "default"classstringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/Blockquote.wrn
component Blockquote {
+ base componentBlockquote
Theme-aware, responsive blockquote component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Blockquote
+ quote="I just wanted to say that I'm very happy with my purchase so far. The documentation is outstanding - clear and detailed."
+ citation="citation"
+ citationTitle="citationTitle"
+ citationUrl="citationUrl"
+ avatarSrc="avatarSrc"
+/>
Legacy mount name: data-component="Blockquote".
Props and attributes
Prop Type Requirement Default quotestringOptional "I just wanted to say that I'm very happy with my purchase so far. The documentation is outstanding - clear and detailed."citationstringOptional ""citationTitlestringOptional ""citationUrlstringOptional ""avatarSrcstringOptional ""avatarAltstringOptional ""sizestringOptional "md"colorstringOptional "primary"alignstringOptional "left"variantstringOptional "default"quoteMarkbooleanOptional trueitalicbooleanOptional trueclassstringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/Blockquote.wrn
component Blockquote {
props {
- size = "default"
+ quote = "I just wanted to say that I'm very happy with my purchase so far. The documentation is outstanding - clear and detailed."
+ citation = ""
+ citationTitle = ""
+ citationUrl = ""
+ avatarSrc = ""
+ avatarAlt = ""
+ size = "md"
color = "primary"
- title = "Blockquote"
- description = ""
- items = []
+ align = "left"
variant = "default"
+ quoteMark = true
+ italic = true
class = ""
}
+
view {
- <section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--blockquote wire-next--variant-{variant} {class}">
- {#if title}<strong>{title}</strong>{/if}
- {#if description}<p>{description}</p>{/if}
- {#if items}<div class="wire-next__items">{#each items as item}<span>{item.label}</span>{/each}</div>{/if}
- <slot />
- </section>
+ <figure
+ {...attrs}
+ class="wire-next wire-next--blockquote wire-next--color-{color} wire-next--size-{size} {class}"
+ data-size="{size}"
+ data-color="{color}"
+ data-align="{align}"
+ data-variant="{variant}"
+ data-italic="{italic}"
+ >
+ <blockquote cite="{citationUrl}">
+ {#if quoteMark}
+ <span class="wire-next__blockquote-mark" aria-hidden="true">“</span>
+ {/if}
+
+ <div class="wire-next__blockquote-copy">
+ {#if quote}
+ <p>{quote}</p>
+ {:else}
+ <slot />
+ {/if}
+ </div>
+ </blockquote>
+
+ {#if citation || citationTitle || avatarSrc}
+ <figcaption class="wire-next__blockquote-citation">
+ {#if avatarSrc}
+ <img
+ class="wire-next__blockquote-avatar"
+ src="{avatarSrc}"
+ alt="{avatarAlt}"
+ loading="lazy"
+ />
+ {/if}
+
+ <span class="wire-next__blockquote-attribution">
+ {#if citation}
+ {#if citationUrl}
+ <cite>
+ <a href="{citationUrl}">{citation}</a>
+ </cite>
+ {:else}
+ <cite>{citation}</cite>
+ {/if}
+ {/if}
+ {#if citationTitle}<span>{citationTitle}</span>{/if}
+ </span>
+ </figcaption>
+ {/if}
+ </figure>
}
}
-
+
}
diff --git a/app/pages/components/breadcrumb.wrn b/app/pages/components/breadcrumb.wrn
index 0713fabc..496983b5 100644
--- a/app/pages/components/breadcrumb.wrn
+++ b/app/pages/components/breadcrumb.wrn
@@ -10,17 +10,19 @@ page Breadcrumbcomponent {
W WRNexusJS
-
+
Browse documentation
- navigation componentBreadcrumb
Theme-aware, responsive breadcrumb component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Breadcrumb
+ navigation componentBreadcrumb
Theme-aware, responsive breadcrumb component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Breadcrumb
size="default"
color="primary"
label="Breadcrumb"
items="[]"
active="active"
-/>
Legacy mount name: data-component="Breadcrumb".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"labelstringOptional "Breadcrumb"itemsstringOptional []activestringOptional ""orientationstringOptional "horizontal"classstringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/Breadcrumb.wrn
component Breadcrumb {
+/>
Legacy mount name: data-component="Breadcrumb".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"labelstringOptional "Breadcrumb"itemsstringOptional []activestringOptional ""orientationstringOptional "horizontal"classstringOptional ""
Slots
default
Events
navigateclick
Source contract
Installed source: components/Breadcrumb.wrn
component Breadcrumb {
props {
+ @event navigate = function
+ @event click = function
size = "default"
color = "primary"
label = "Breadcrumb"
@@ -37,7 +39,7 @@ page Breadcrumbcomponent {
}
}
-
+
}
diff --git a/app/pages/components/button-group.wrn b/app/pages/components/button-group.wrn
index cfbe786d..97d0362b 100644
--- a/app/pages/components/button-group.wrn
+++ b/app/pages/components/button-group.wrn
@@ -10,36 +10,107 @@ page ButtonGroupcomponent {
W WRNexusJS
-
+
Browse documentation
- base componentButtonGroup
Theme-aware, responsive button group component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<ButtonGroup
- size="default"
- color="primary"
- title="Button Group"
- description="description"
+ base componentButtonGroup
Theme-aware, responsive button group component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<ButtonGroup
items="[]"
-/>
Legacy mount name: data-component="ButtonGroup".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"titlestringOptional "Button Group"descriptionstringOptional ""itemsstringOptional []variantstringOptional "default"classstringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/ButtonGroup.wrn
component ButtonGroup {
+ value="value"
+ size="md"
+ color="primary"
+ variant="default"
+/>
Legacy mount name: data-component="ButtonGroup".
Props and attributes
Prop Type Requirement Default itemsstringOptional []valuestringOptional ""sizestringOptional "md"colorstringOptional "primary"variantstringOptional "default"orientationstringOptional "horizontal"responsivebooleanOptional falseattachedbooleanOptional trueselectablebooleanOptional falsetoolbarbooleanOptional falsedisabledbooleanOptional falseariaLabelstringOptional "Button group"classstringOptional ""
Slots
default
Events
clickselectchange
Source contract
Installed source: components/ButtonGroup.wrn
component ButtonGroup {
props {
- size = "default"
- color = "primary"
- title = "Button Group"
- description = ""
+ @event click = function
+ @event select = function
+ @event change = function
items = []
+ value = ""
+ size = "md"
+ color = "primary"
variant = "default"
+ orientation = "horizontal"
+ responsive = false
+ attached = true
+ selectable = false
+ toolbar = false
+ disabled = false
+ ariaLabel = "Button group"
class = ""
}
+
+ state selectedValue = value
+
+ functions {
+ function itemValue(item, index) {
+ return item.value || item.label || String(index)
+ }
+
+ function selectItem(item, index) {
+ previousValue = selectedValue
+ nextValue = itemValue(item, index)
+
+ $emit("select", {
+ value: nextValue,
+ previousValue: previousValue,
+ item: item,
+ index: index
+ })
+
+ if (selectable && previousValue !== nextValue) {
+ selectedValue = nextValue
+ $emit("change", {
+ value: nextValue,
+ previousValue: previousValue,
+ item: item,
+ index: index
+ })
+ }
+ }
+ }
+
view {
- <section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--button-group wire-next--variant-{variant} {class}">
- {#if title}<strong>{title}</strong>{/if}
- {#if description}<p>{description}</p>{/if}
- {#if items}<div class="wire-next__items">{#each items as item}<span>{item.label}</span>{/each}</div>{/if}
+ <div
+ {...attrs}
+ class="wire-next wire-next--button-group {class}"
+ role="{toolbar ? 'toolbar' : 'group'}"
+ aria-label="{ariaLabel}"
+ aria-orientation="{orientation}"
+ data-size="{size}"
+ data-color="{color}"
+ data-variant="{variant}"
+ data-orientation="{orientation}"
+ data-responsive="{responsive}"
+ data-attached="{attached}"
+ data-selectable="{selectable}"
+ data-disabled="{disabled}"
+ >
+ {#if items}
+ {#each items as item, index}
+ <button
+ type="{item.type || 'button'}"
+ class="wire-btn wire-btn--variant-{item.variant || variant} wire-btn--color-{item.color || color} wire-btn--size-{item.size || size}"
+ disabled="{disabled || item.disabled}"
+ aria-label="{item.ariaLabel || item.label}"
+ aria-pressed="{selectable ? (selectedValue === (item.value || item.label || String(index)) ? 'true' : 'false') : ''}"
+ data-value="{item.value || item.label || String(index)}"
+ data-selected="{selectable && selectedValue === (item.value || item.label || String(index)) ? 'true' : 'false'}"
+ @click="selectItem(item, index)"
+ >
+ {#if item.icon}
+ <span class="wire-btn__icon {item.icon}" aria-hidden="true">
+ </span>
+ {/if}
+ <span class="wire-btn__label">{item.label}</span>
+ </button>
+ {/each}
+ {/if}
<slot />
- </section>
+ </div>
}
}
-
+
}
diff --git a/app/pages/components/button.wrn b/app/pages/components/button.wrn
index f0e3443a..fb090cd2 100644
--- a/app/pages/components/button.wrn
+++ b/app/pages/components/button.wrn
@@ -10,17 +10,20 @@ page Buttoncomponent {
W WRNexusJS
-
+
Browse documentation
- base componentButton
Theme-aware, responsive button component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Button
+ base componentButton
Theme-aware, responsive button component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Button
label="Button"
loadingLabel="Loading…"
description="description"
as="as"
href="href"
-/>
Legacy mount name: data-component="Button".
Props and attributes
Prop Type Requirement Default labelstringOptional "Button"loadingLabelstringOptional "Loading…"descriptionstringOptional ""asstringOptional ""hrefstringOptional ""targetstringOptional ""relstringOptional ""typestringOptional "button"variantstringOptional "default"colorstringOptional "primary"sizestringOptional "default"disabledbooleanOptional falseloadingbooleanOptional falsepillbooleanOptional falsefullWidthbooleanOptional falseiconstringOptional ""iconPositionstringOptional "start"ariaLabelstringOptional ""ariaPressedstringOptional ""ariaExpandedstringOptional ""ariaControlsstringOptional ""titlestringOptional ""autofocusbooleanOptional falsecontrolClassstringOptional ""classstringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/button.wrn
component Button {
+/>
Legacy mount name: data-component="Button".
Props and attributes
Prop Type Requirement Default labelstringOptional "Button"loadingLabelstringOptional "Loading…"descriptionstringOptional ""asstringOptional ""hrefstringOptional ""targetstringOptional ""relstringOptional ""typestringOptional "button"variantstringOptional "default"colorstringOptional "primary"sizestringOptional "default"disabledbooleanOptional falseloadingbooleanOptional falsepillbooleanOptional falsefullWidthbooleanOptional falseiconstringOptional ""iconPositionstringOptional "start"ariaLabelstringOptional ""ariaPressedstringOptional ""ariaExpandedstringOptional ""ariaControlsstringOptional ""titlestringOptional ""autofocusbooleanOptional falsecontrolClassstringOptional ""classstringOptional ""
Slots
default
Events
clickfocusblur
Source contract
Installed source: components/button.wrn
component Button {
props {
+ @event click = function
+ @event focus = function
+ @event blur = function
label = "Button"
loadingLabel = "Loading…"
description = ""
@@ -181,7 +184,7 @@ page Buttoncomponent {
}
}
-
+
}
diff --git a/app/pages/components/card.wrn b/app/pages/components/card.wrn
index a8055fb8..b6e69c5b 100644
--- a/app/pages/components/card.wrn
+++ b/app/pages/components/card.wrn
@@ -10,36 +10,280 @@ page Cardcomponent {
W WRNexusJS
-
+
Browse documentation
- base componentCard
Theme-aware, responsive card component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Card
- size="default"
- color="primary"
- title="Card"
+ base componentCard
Theme-aware, responsive card component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Card
+ title="Card title"
+ subtitle="subtitle"
description="description"
- items="[]"
-/>
Legacy mount name: data-component="Card".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"titlestringOptional "Card"descriptionstringOptional ""itemsstringOptional []variantstringOptional "default"classstringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/card.wrn
component Card {
+ header="header"
+ footer="footer"
+/>
Legacy mount name: data-component="Card".
Props and attributes
Prop Type Requirement Default titlestringOptional "Card title"subtitlestringOptional ""descriptionstringOptional ""headerstringOptional ""footerstringOptional ""imageSrcstringOptional ""imageAltstringOptional ""imagePositionstringOptional "top"actionLabelstringOptional ""actionHrefstringOptional ""headerActionsstringOptional []navigationstringOptional []activeNavstringOptional ""mobileNavigationbooleanOptional falsealertTitlestringOptional ""alertDescriptionstringOptional ""emptybooleanOptional falseemptyTitlestringOptional "No data to show"emptyIconstringOptional "icon-[lucide--inbox]"itemsstringOptional []sizestringOptional "md"colorstringOptional "primary"variantstringOptional "default"layoutstringOptional "vertical"alignstringOptional "left"hoverstringOptional "none"scrollablebooleanOptional falsemaxHeightstringOptional "18rem"dismissiblebooleanOptional falseariaLabelstringOptional ""classstringOptional ""
Slots
default
Events
clickactionnavigatedismissloaderror
Source contract
Installed source: components/card.wrn
component Card {
props {
- size = "default"
- color = "primary"
- title = "Card"
+ @event click = function
+ @event action = function
+ @event navigate = function
+ @event dismiss = function
+ @event load = function
+ @event error = function
+ title = "Card title"
+ subtitle = ""
description = ""
+ header = ""
+ footer = ""
+ imageSrc = ""
+ imageAlt = ""
+ imagePosition = "top"
+ actionLabel = ""
+ actionHref = ""
+ headerActions = []
+ navigation = []
+ activeNav = ""
+ mobileNavigation = false
+ alertTitle = ""
+ alertDescription = ""
+ empty = false
+ emptyTitle = "No data to show"
+ emptyIcon = "icon-[lucide--inbox]"
items = []
+ size = "md"
+ color = "primary"
variant = "default"
+ layout = "vertical"
+ align = "left"
+ hover = "none"
+ scrollable = false
+ maxHeight = "18rem"
+ dismissible = false
+ ariaLabel = ""
class = ""
}
+
+ state visible = true
+ state selectedNav = activeNav
+
+ functions {
+ function chooseNavigation(item, index) {
+ previousValue = selectedNav
+ selectedNav = item.value || item.label
+ $emit("navigate", {
+ value: selectedNav,
+ previousValue: previousValue,
+ item: item,
+ index: index
+ })
+ }
+
+ function chooseMobileNavigation(sourceEvent) {
+ previousValue = selectedNav
+ selectedNav = sourceEvent.target.value
+ $emit("navigate", {
+ value: selectedNav,
+ previousValue: previousValue
+ })
+ }
+
+ function chooseAction(action, index) {
+ $emit("action", {
+ action: action,
+ index: index
+ })
+ }
+
+ function dismissCard(sourceEvent) {
+ panel = sourceEvent.currentTarget.closest(".wire-next__card-panel")
+ if (panel) {
+ panel.setAttribute("hidden", "")
+ }
+ visible = false
+ $emit("dismiss", {
+ title: title
+ })
+ }
+ }
+
view {
- <section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--card wire-next--variant-{variant} {class}">
- {#if title}<strong>{title}</strong>{/if}
- {#if description}<p>{description}</p>{/if}
- {#if items}<div class="wire-next__items">{#each items as item}<span>{item.label}</span>{/each}</div>{/if}
- <slot />
- </section>
+ <section
+ {...attrs}
+ class="wire-next wire-next--card {class}"
+ data-size="{size}"
+ data-color="{color}"
+ data-variant="{variant}"
+ data-layout="{layout}"
+ data-align="{align}"
+ data-hover="{hover}"
+ data-image-position="{imagePosition}"
+ data-group="{items.length > 0}"
+ aria-label="{ariaLabel || title}"
+ >
+ {#if items.length > 0}
+ <div class="wire-next__card-group">
+ {#each items as item}
+ <article class="wire-next__card-panel">
+ {#if item.imageSrc}
+ <div class="wire-next__card-media">
+ <img src="{item.imageSrc}" alt="{item.imageAlt || ''}" loading="lazy" />
+ </div>
+ {/if}
+ <div class="wire-next__card-body">
+ {#if item.title}<h3>{item.title}</h3>{/if}
+ {#if item.description}<p>{item.description}</p>{/if}
+ </div>
+ {#if item.footer}<footer class="wire-next__card-footer">{item.footer}</footer>{/if}
+ </article>
+ {/each}
+ </div>
+ {:else if visible}
+ <article class="wire-next__card-panel">
+ {#if imagePosition === "overlay" && imageSrc}
+ <div class="wire-next__card-media wire-next__card-media--overlay">
+ <img
+ src="{imageSrc}"
+ alt="{imageAlt}"
+ loading="lazy"
+ @load="$emit('load', { src: imageSrc })"
+ @error="$emit('error', { src: imageSrc })"
+ />
+ <div class="wire-next__card-overlay">
+ {#if title}<h3>{title}</h3>{/if}
+ {#if subtitle}<span class="wire-next__card-subtitle">{subtitle}</span>{/if}
+ {#if description}<p>{description}</p>{/if}
+ {#if footer}<small>{footer}</small>{/if}
+ </div>
+ </div>
+ {:else}
+ {#if header || headerActions.length > 0 || dismissible}
+ <header class="wire-next__card-header">
+ <span>{header}</span>
+ {#if headerActions.length > 0 || dismissible}
+ <span class="wire-next__card-header-actions">
+ {#each headerActions as action, index}
+ <button
+ type="button"
+ aria-label="{action.ariaLabel || action.label}"
+ title="{action.label}"
+ @click="chooseAction(action, index)"
+ >
+ {#if action.icon}<span class="{action.icon}" aria-hidden="true">
+ </span>{/if}
+ {#if !action.icon}<span>{action.label}</span>{/if}
+ </button>
+ {/each}
+ {#if dismissible}
+ <button type="button" aria-label="Close card" @click="dismissCard(event)">
+ <span class="icon-[lucide--x]" aria-hidden="true">
+ </span>
+ </button>
+ {/if}
+ </span>
+ {/if}
+ </header>
+ {/if}
+
+ {#if navigation.length > 0}
+ <nav class="wire-next__card-navigation" aria-label="{ariaLabel || title}">
+ <div class="wire-next__card-tabs">
+ {#each navigation as item, index}
+ <button
+ type="button"
+ data-active="{selectedNav === (item.value || item.label)}"
+ aria-current="{selectedNav === (item.value || item.label) ? 'page' : ''}"
+ @click="chooseNavigation(item, index)"
+ >
+ {item.label}
+ </button>
+ {/each}
+ </div>
+ {#if mobileNavigation}
+ <select
+ class="wire-next__card-navigation-select"
+ aria-label="{ariaLabel || title}"
+ value="{selectedNav}"
+ @change="chooseMobileNavigation(event)"
+ >
+ {#each navigation as item}
+ <option
+ value="{item.value || item.label}"
+ selected="{selectedNav === (item.value || item.label)}"
+ >
+ {item.label}
+ </option>
+ {/each}
+ </select>
+ {/if}
+ </nav>
+ {/if}
+
+ {#if imageSrc && imagePosition !== "bottom"}
+ <div class="wire-next__card-media">
+ <img
+ src="{imageSrc}"
+ alt="{imageAlt}"
+ loading="lazy"
+ @load="$emit('load', { src: imageSrc })"
+ @error="$emit('error', { src: imageSrc })"
+ />
+ </div>
+ {/if}
+
+ {#if alertTitle || alertDescription}
+ <aside class="wire-next__card-alert" role="status">
+ {#if alertTitle}<strong>{alertTitle}</strong>{/if}
+ {#if alertDescription}<span>{alertDescription}</span>{/if}
+ </aside>
+ {/if}
+
+ <div
+ class="wire-next__card-body"
+ data-scrollable="{scrollable}"
+ style="--wire-card-max-height: {maxHeight}"
+ >
+ {#if empty}
+ <div class="wire-next__card-empty">
+ <span class="{emptyIcon}" aria-hidden="true">
+ </span>
+ <strong>{emptyTitle}</strong>
+ </div>
+ {:else}
+ {#if title}<h3>{title}</h3>{/if}
+ {#if subtitle}<span class="wire-next__card-subtitle">{subtitle}</span>{/if}
+ {#if description}<p>{description}</p>{/if}
+ <slot />
+ {#if actionLabel}
+ <a
+ class="wire-next__card-action"
+ href="{actionHref || '#'}"
+ @click="$emit('action', { label: actionLabel, href: actionHref })"
+ >
+ {actionLabel}<span class="icon-[lucide--chevron-right]" aria-hidden="true">
+ </span>
+ </a>
+ {/if}
+ {/if}
+ </div>
+
+ {#if footer}<footer class="wire-next__card-footer">{footer}</footer>{/if}
+
+ {#if imageSrc && imagePosition === "bottom"}
+ <div class="wire-next__card-media">
+ <img
+ src="{imageSrc}"
+ alt="{imageAlt}"
+ loading="lazy"
+ @load="$emit('load', { src: imageSrc })"
+ @error="$emit('error', { src: imageSrc })"
+ />
+ </div>
+ {/if}
+ {/if}
+ </article>
+ {/if}
+ </section>
}
}
-
+
}
diff --git a/app/pages/components/carousel.wrn b/app/pages/components/carousel.wrn
index 51a4829c..1c89386b 100644
--- a/app/pages/components/carousel.wrn
+++ b/app/pages/components/carousel.wrn
@@ -10,36 +10,480 @@ page Carouselcomponent {
W WRNexusJS
-
+
Browse documentation
- base componentCarousel
Theme-aware, responsive carousel component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Carousel
+ base componentCarousel
Theme-aware, responsive carousel component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Carousel
size="default"
color="primary"
- title="Carousel"
+ title="title"
description="description"
items="[]"
-/>
Legacy mount name: data-component="Carousel".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"titlestringOptional "Carousel"descriptionstringOptional ""itemsstringOptional []variantstringOptional "default"classstringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/Carousel.wrn
component Carousel {
+/>
Legacy mount name: data-component="Carousel".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"titlestringOptional ""descriptionstringOptional ""itemsstringOptional []activeIndexnumberOptional 0slidesPerViewnumberOptional 1gapstringOptional "0.75rem"showPaginationbooleanOptional falseisAutoPlaybooleanOptional falseautoplayIntervalnumberOptional 4000isInfiniteLoopbooleanOptional falseisRTLbooleanOptional falseisCenteredbooleanOptional falseisDraggablebooleanOptional falseisAutoHeightbooleanOptional falseisSnapbooleanOptional falseshowCounterbooleanOptional falsethumbnailsstringOptional "none"ariaLabelstringOptional "Content carousel"variantstringOptional "default"classstringOptional ""
Slots
default
Events
initializechangepreviousnextplaypausereachStartreachEnddragStartdragEnd
Source contract
Installed source: components/carousel.wrn
// Interactive, hydration-safe content carousel.
+component Carousel {
props {
+ @event initialize = function
+ @event change = function
+ @event previous = function
+ @event next = function
+ @event play = function
+ @event pause = function
+ @event reachStart = function
+ @event reachEnd = function
+ @event dragStart = function
+ @event dragEnd = function
size = "default"
color = "primary"
- title = "Carousel"
+ title = ""
description = ""
items = []
+ activeIndex = 0
+ slidesPerView = 1
+ gap = "0.75rem"
+ showPagination = false
+ isAutoPlay = false
+ autoplayInterval = 4000
+ isInfiniteLoop = false
+ isRTL = false
+ isCentered = false
+ isDraggable = false
+ isAutoHeight = false
+ isSnap = false
+ showCounter = false
+ thumbnails = "none"
+ ariaLabel = "Content carousel"
variant = "default"
class = ""
}
+
+ state currentIndex = activeIndex
+ state playing = false
+ state dragOrigin = null
+ state dragOffset = 0
+ state autoplayTimer = null
+ state carouselRoot = null
+
+ functions {
+ function slideCount() {
+ return items.length
+ }
+
+ function maximumIndex(count, visible) {
+ count = slideCount()
+ visible = Math.max(1, Number(slidesPerView) || 1)
+ if (isCentered || isSnap) {
+ return Math.max(0, count - 1)
+ }
+ return Math.max(0, count - visible)
+ }
+
+ function normalizedIndex(index, maximum) {
+ maximum = maximumIndex()
+ if (slideCount() === 0) {
+ return 0
+ }
+ if (isInfiniteLoop) {
+ if (index < 0) {
+ return maximum
+ }
+ if (index > maximum) {
+ return 0
+ }
+ }
+ return Math.max(0, Math.min(index, maximum))
+ }
+
+ function rememberRoot(sourceEvent, root) {
+ if (!sourceEvent || !sourceEvent.currentTarget) {
+ return
+ }
+ root = sourceEvent.currentTarget.closest(".wire-next--carousel")
+ if (root) {
+ carouselRoot = root
+ }
+ }
+
+ function syncNavigation(sourceEvent, index, root, viewport, slides, slide, thumbnails, thumbnail, rail) {
+ rememberRoot(sourceEvent)
+ root = carouselRoot
+ if (!root) {
+ return
+ }
+ if (isSnap) {
+ viewport = root.querySelector(".wire-next__carousel-viewport")
+ slides = root.querySelectorAll(".wire-next__carousel-slide")
+ slide = slides[index]
+ if (viewport && slide) {
+ viewport.scrollTo({
+ left: slide.offsetLeft - (viewport.clientWidth - slide.clientWidth) / 2,
+ behavior: "smooth"
+ })
+ }
+ }
+ thumbnails = root.querySelectorAll(".wire-next__carousel-thumbnails button")
+ if (thumbnails[index]) {
+ thumbnail = thumbnails[index]
+ rail = thumbnail.parentElement
+ rail.scrollTo({
+ left: thumbnail.offsetLeft - (rail.clientWidth - thumbnail.clientWidth) / 2,
+ top: thumbnail.offsetTop - (rail.clientHeight - thumbnail.clientHeight) / 2,
+ behavior: "smooth"
+ })
+ }
+ }
+
+ function handleSnapScroll(sourceEvent, slides, viewport, viewportCenter, closestIndex, closestDistance, slide, slideCenter, distance, previousIndex) {
+ if (!isSnap) {
+ return
+ }
+ rememberRoot(sourceEvent)
+ viewport = sourceEvent.currentTarget
+ slides = viewport.querySelectorAll(".wire-next__carousel-slide")
+ viewportCenter = viewport.scrollLeft + viewport.clientWidth / 2
+ closestIndex = currentIndex
+ closestDistance = 1000000000
+ slides.forEach(function (candidate, index) {
+ slideCenter = candidate.offsetLeft + candidate.clientWidth / 2
+ distance = Math.abs(slideCenter - viewportCenter)
+ if (distance < closestDistance) {
+ closestDistance = distance
+ closestIndex = index
+ }
+ })
+ closestIndex = normalizedIndex(closestIndex)
+ if (closestIndex !== currentIndex) {
+ previousIndex = currentIndex
+ currentIndex = closestIndex
+ $emit("change", {
+ index: currentIndex,
+ previousIndex: previousIndex,
+ item: items[currentIndex],
+ reason: "snap"
+ })
+ slides = carouselRoot.querySelectorAll(".wire-next__carousel-thumbnails button")
+ slide = slides[currentIndex]
+ if (slide) {
+ viewport = slide.parentElement
+ viewport.scrollTo({
+ left: slide.offsetLeft - (viewport.clientWidth - slide.clientWidth) / 2,
+ top: slide.offsetTop - (viewport.clientHeight - slide.clientHeight) / 2,
+ behavior: "smooth"
+ })
+ }
+ }
+ }
+
+ function selectSlide(index, reason, sourceEvent, previousIndex) {
+ if (slideCount() === 0) {
+ return
+ }
+ previousIndex = currentIndex
+ currentIndex = normalizedIndex(Number(index))
+ syncNavigation(sourceEvent, currentIndex)
+ if (previousIndex === currentIndex && reason !== "initialize") {
+ return
+ }
+ $emit("change", {
+ index: currentIndex,
+ previousIndex: previousIndex,
+ item: items[currentIndex],
+ reason: reason || "select"
+ })
+ if (currentIndex === 0) {
+ $emit("reachStart", { index: currentIndex })
+ }
+ if (currentIndex === maximumIndex()) {
+ $emit("reachEnd", { index: currentIndex })
+ }
+ }
+
+ function previousSlide(sourceEvent, previousIndex) {
+ previousIndex = currentIndex
+ selectSlide(currentIndex - 1, "previous", sourceEvent)
+ $emit("previous", {
+ index: currentIndex,
+ previousIndex: previousIndex,
+ item: items[currentIndex]
+ })
+ }
+
+ function nextSlide(sourceEvent, previousIndex) {
+ previousIndex = currentIndex
+ selectSlide(currentIndex + 1, "next", sourceEvent)
+ $emit("next", {
+ index: currentIndex,
+ previousIndex: previousIndex,
+ item: items[currentIndex]
+ })
+ }
+
+ function handleKeydown(sourceEvent) {
+ if (sourceEvent.key === "ArrowLeft") {
+ sourceEvent.preventDefault()
+ if (isRTL) {
+ nextSlide(sourceEvent)
+ } else {
+ previousSlide(sourceEvent)
+ }
+ }
+ if (sourceEvent.key === "ArrowRight") {
+ sourceEvent.preventDefault()
+ if (isRTL) {
+ previousSlide(sourceEvent)
+ } else {
+ nextSlide(sourceEvent)
+ }
+ }
+ if (sourceEvent.key === "Home") {
+ sourceEvent.preventDefault()
+ selectSlide(0, "keyboard", sourceEvent)
+ }
+ if (sourceEvent.key === "End") {
+ sourceEvent.preventDefault()
+ selectSlide(maximumIndex(), "keyboard", sourceEvent)
+ }
+ }
+
+ function beginDrag(sourceEvent) {
+ if (!isDraggable || isSnap) {
+ return
+ }
+ sourceEvent.preventDefault()
+ dragOrigin = sourceEvent.clientX
+ dragOffset = 0
+ sourceEvent.currentTarget.setPointerCapture(sourceEvent.pointerId)
+ $emit("dragStart", { index: currentIndex, x: dragOrigin })
+ }
+
+ function moveDrag(sourceEvent) {
+ if (!isDraggable || isSnap || dragOrigin === null) {
+ return
+ }
+ sourceEvent.preventDefault()
+ dragOffset = sourceEvent.clientX - dragOrigin
+ }
+
+ function cancelDrag() {
+ dragOrigin = null
+ dragOffset = 0
+ }
+
+ function endDrag(sourceEvent, distance) {
+ if (!isDraggable || isSnap || dragOrigin === null) {
+ return
+ }
+ sourceEvent.preventDefault()
+ distance = dragOffset || sourceEvent.clientX - dragOrigin
+ dragOrigin = null
+ dragOffset = 0
+ if (Math.abs(distance) > 20) {
+ if ((distance < 0 && !isRTL) || (distance > 0 && isRTL)) {
+ nextSlide(sourceEvent)
+ } else {
+ previousSlide(sourceEvent)
+ }
+ }
+ $emit("dragEnd", {
+ index: currentIndex,
+ distance: distance
+ })
+ }
+
+ function advanceAutoplay() {
+ if (currentIndex >= maximumIndex()) {
+ selectSlide(0, "autoplay")
+ } else {
+ selectSlide(currentIndex + 1, "autoplay")
+ }
+ }
+
+ function startAutoplay() {
+ if (!isAutoPlay || playing || slideCount() < 2) {
+ return
+ }
+ playing = true
+ autoplayTimer = setInterval(advanceAutoplay, Math.max(1000, Number(autoplayInterval)))
+ $emit("play", { index: currentIndex, interval: autoplayInterval })
+ }
+
+ function pauseAutoplay() {
+ if (autoplayTimer) {
+ clearInterval(autoplayTimer)
+ }
+ autoplayTimer = null
+ if (playing) {
+ $emit("pause", { index: currentIndex })
+ }
+ playing = false
+ }
+
+ }
+
+ lifecycle {
+ mount {
+ $emit("initialize", { index: currentIndex, count: slideCount() })
+ startAutoplay()
+ }
+ unmount {
+ if (autoplayTimer) {
+ clearInterval(autoplayTimer)
+ }
+ }
+ }
+
view {
- <section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--carousel wire-next--variant-{variant} {class}">
- {#if title}<strong>{title}</strong>{/if}
- {#if description}<p>{description}</p>{/if}
- {#if items}<div class="wire-next__items">{#each items as item}<span>{item.label}</span>{/each}</div>{/if}
- <slot />
+ <section
+ {...attrs}
+ class="wire-next wire-next--carousel wire-next--color-{color} wire-next--size-{size} wire-next--variant-{variant} {class}"
+ data-rtl="{isRTL}"
+ data-centered="{isCentered}"
+ data-draggable="{isDraggable && !isSnap}"
+ data-dragging="{dragOrigin !== null}"
+ data-auto-height="{isAutoHeight}"
+ data-snap="{isSnap}"
+ data-thumbnails="{thumbnails}"
+ dir="{isRTL ? 'rtl' : 'ltr'}"
+ role="region"
+ aria-roledescription="carousel"
+ aria-label="{ariaLabel}"
+ @keydown="handleKeydown(event)"
+ @mouseenter="rememberRoot(event); pauseAutoplay()"
+ @mouseleave="startAutoplay()"
+ @focusin="rememberRoot(event); pauseAutoplay()"
+ @focusout="startAutoplay()"
+ >
+ {#if title || description}
+ <header class="wire-next__carousel-header">
+ {#if title}<h3>{title}</h3>{/if}
+ {#if description}<p>{description}</p>{/if}
+ </header>
+ {/if}
+
+ <div class="wire-next__carousel-layout">
+ {#if thumbnails === "vertical"}
+ <div class="wire-next__carousel-thumbnails" aria-label="Choose a slide">
+ {#each items as item, index}
+ <button
+ type="button"
+ data-active="{index === currentIndex}"
+ aria-label="Show slide {index + 1}: {item.label || item.title}"
+ aria-current="{index === currentIndex ? 'true' : 'false'}"
+ @click="selectSlide(index, 'thumbnail', event)"
+ >
+ {#if item.thumbnail}<img src="{item.thumbnail}" alt="" />{/if}
+ <span>{item.label || item.title || "Slide " + (index + 1)}</span>
+ </button>
+ {/each}
+ </div>
+ {/if}
+
+ <div class="wire-next__carousel-main">
+ <div class="wire-next__carousel-stage">
+ <div
+ class="wire-next__carousel-viewport"
+ tabindex="0"
+ @scroll="handleSnapScroll(event)"
+ @pointerdown="beginDrag(event)"
+ @pointermove="moveDrag(event)"
+ @pointerup="endDrag(event)"
+ @pointercancel="cancelDrag()"
+ @lostpointercapture="cancelDrag()"
+ >
+ <div
+ class="wire-next__carousel-track"
+ style="--wire-carousel-index: {currentIndex}; --wire-carousel-per-view: {slidesPerView}; --wire-carousel-gap: {gap}; --wire-carousel-drag-offset: {dragOffset}px"
+ >
+ {#each items as item, index}
+ <article
+ class="wire-next__carousel-slide"
+ data-active="{index === currentIndex}"
+ role="group"
+ aria-roledescription="slide"
+ aria-label="{index + 1} of {items.length}"
+ aria-hidden="{index === currentIndex ? 'false' : 'true'}"
+ >
+ {#if item.imageSrc}
+ <img src="{item.imageSrc}" alt="{item.imageAlt || item.title || ''}" />
+ {/if}
+ <div class="wire-next__carousel-slide-content">
+ {#if item.eyebrow}<span>{item.eyebrow}</span>{/if}
+ {#if item.title || item.label}<h4>{item.title || item.label}</h4>{/if}
+ {#if item.description}<p>{item.description}</p>{/if}
+ {#if item.actionLabel}
+ <a href="{item.actionHref || '#'}">{item.actionLabel}</a>
+ {/if}
+ </div>
+ </article>
+ {/each}
+ <slot />
+ </div>
+ </div>
+ <button
+ class="wire-next__carousel-control wire-next__carousel-control--previous"
+ type="button"
+ aria-label="Previous slide"
+ disabled="{!isInfiniteLoop && currentIndex === 0}"
+ @click="previousSlide(event)"
+ >
+ <span class="icon-[lucide--chevron-left]" aria-hidden="true">
+ </span>
+ </button>
+ <button
+ class="wire-next__carousel-control wire-next__carousel-control--next"
+ type="button"
+ aria-label="Next slide"
+ disabled="{!isInfiniteLoop && currentIndex === maximumIndex()}"
+ @click="nextSlide(event)"
+ >
+ <span class="icon-[lucide--chevron-right]" aria-hidden="true">
+ </span>
+ </button>
+
+ {#if showCounter}
+ <output class="wire-next__carousel-counter" aria-live="polite">
+ {currentIndex + 1} / {items.length}
+ </output>
+ {/if}
+ </div>
+
+ {#if showPagination}
+ <div class="wire-next__carousel-pagination" aria-label="Choose a slide">
+ {#each items as item, index}
+ <button
+ type="button"
+ data-active="{index === currentIndex}"
+ aria-label="Show slide {index + 1}"
+ aria-current="{index === currentIndex ? 'true' : 'false'}"
+ @click="selectSlide(index, 'pagination', event)"
+ >
+ </button>
+ {/each}
+ </div>
+ {/if}
+
+ {#if thumbnails === "horizontal"}
+ <div class="wire-next__carousel-thumbnails" aria-label="Choose a slide">
+ {#each items as item, index}
+ <button
+ type="button"
+ data-active="{index === currentIndex}"
+ aria-label="Show slide {index + 1}: {item.label || item.title}"
+ aria-current="{index === currentIndex ? 'true' : 'false'}"
+ @click="selectSlide(index, 'thumbnail', event)"
+ >
+ {#if item.thumbnail}<img src="{item.thumbnail}" alt="" />{/if}
+ <span>{item.label || item.title || "Slide " + (index + 1)}</span>
+ </button>
+ {/each}
+ </div>
+ {/if}
+ </div>
+ </div>
</section>
}
}
-
+
}
diff --git a/app/pages/components/chart.wrn b/app/pages/components/chart.wrn
index 22f3eb91..ba1a2d31 100644
--- a/app/pages/components/chart.wrn
+++ b/app/pages/components/chart.wrn
@@ -10,17 +10,20 @@ page Chartcomponent {
W WRNexusJS
-
+
Browse documentation
- integrations componentChart
Theme-aware, responsive chart component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Chart
+ integrations componentChart
Theme-aware, responsive chart component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Chart
size="default"
color="primary"
title="Chart"
description="description"
items="[]"
-/>
Legacy mount name: data-component="Chart".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"titlestringOptional "Chart"descriptionstringOptional ""itemsstringOptional []variantstringOptional "default"classstringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/Chart.wrn
component Chart {
+/>
Legacy mount name: data-component="Chart".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"titlestringOptional "Chart"descriptionstringOptional ""itemsstringOptional []variantstringOptional "default"classstringOptional ""
Slots
default
Events
selectdataPointClicklegendToggle
Source contract
Installed source: components/Chart.wrn
component Chart {
props {
+ @event select = function
+ @event dataPointClick = function
+ @event legendToggle = function
size = "default"
color = "primary"
title = "Chart"
@@ -39,7 +42,7 @@ page Chartcomponent {
}
}
-
+
}
diff --git a/app/pages/components/chat-bubble.wrn b/app/pages/components/chat-bubble.wrn
index 15a6f826..754fbb64 100644
--- a/app/pages/components/chat-bubble.wrn
+++ b/app/pages/components/chat-bubble.wrn
@@ -10,36 +10,165 @@ page ChatBubblecomponent {
W WRNexusJS
-
+
Browse documentation
- base componentChatBubble
Theme-aware, responsive chat bubble component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<ChatBubble
+ base componentChatBubble
Theme-aware, responsive chat bubble component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<ChatBubble
size="default"
color="primary"
- title="Chat Bubble"
+ title="title"
description="description"
items="[]"
-/>
Legacy mount name: data-component="ChatBubble".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"titlestringOptional "Chat Bubble"descriptionstringOptional ""itemsstringOptional []variantstringOptional "default"classstringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/ChatBubble.wrn
component ChatBubble {
+/>
Legacy mount name: data-component="ChatBubble".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"titlestringOptional ""descriptionstringOptional ""itemsstringOptional []oneSidedbooleanOptional falseshowAvatarsbooleanOptional falseshowMetadatabooleanOptional falseariaLabelstringOptional "Conversation"variantstringOptional "default"classstringOptional ""
Slots
default
Events
actionmessageClickavatarClicklinkClick
Source contract
Installed source: components/ChatBubble.wrn
component ChatBubble {
props {
+ @event action = function
+ @event messageClick = function
+ @event avatarClick = function
+ @event linkClick = function
size = "default"
color = "primary"
- title = "Chat Bubble"
+ title = ""
description = ""
items = []
+ oneSided = false
+ showAvatars = false
+ showMetadata = false
+ ariaLabel = "Conversation"
variant = "default"
class = ""
}
+
+ functions {
+ function messageDirection(item) {
+ return item.direction === "outgoing" ? "outgoing" : "incoming"
+ }
+
+ function selectMessage(item, index) {
+ $emit("messageClick", {
+ item: item,
+ index: index,
+ direction: messageDirection(item)
+ })
+ }
+
+ function selectAvatar(sourceEvent, item, index) {
+ sourceEvent.stopPropagation()
+ $emit("avatarClick", {
+ item: item,
+ index: index,
+ direction: messageDirection(item)
+ })
+ }
+
+ function selectLink(sourceEvent, link, item, index) {
+ sourceEvent.stopPropagation()
+ $emit("linkClick", {
+ link: link,
+ item: item,
+ index: index
+ })
+ }
+
+ function selectAction(sourceEvent, item, index) {
+ sourceEvent.stopPropagation()
+ $emit("action", {
+ action: item.action || "retry",
+ item: item,
+ index: index
+ })
+ }
+ }
+
view {
- <section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--chat-bubble wire-next--variant-{variant} {class}">
- {#if title}<strong>{title}</strong>{/if}
- {#if description}<p>{description}</p>{/if}
- {#if items}<div class="wire-next__items">{#each items as item}<span>{item.label}</span>{/each}</div>{/if}
+ <section
+ {...attrs}
+ class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--chat-bubble wire-next--variant-{variant} {class}"
+ data-one-sided="{oneSided}"
+ role="log"
+ aria-label="{ariaLabel}"
+ aria-live="polite"
+ >
+ {#if title || description}
+ <header class="wire-next__chat-header">
+ {#if title}<h3>{title}</h3>{/if}
+ {#if description}<p>{description}</p>{/if}
+ </header>
+ {/if}
+
+ {#if items.length}
+ <div class="wire-next__chat-thread">
+ {#each items as item, index}
+ <article
+ class="wire-next__chat-message"
+ data-direction="{messageDirection(item)}"
+ aria-label="{messageDirection(item) === 'outgoing' ? 'Sent message' : 'Received message'}"
+ >
+ <div class="wire-next__chat-row">
+ {#if showAvatars && (item.avatarSrc || item.avatarFallback)}
+ <button
+ class="wire-next__chat-avatar"
+ type="button"
+ aria-label="{item.avatarLabel || item.author || 'Message author'}"
+ @click="selectAvatar(event, item, index)"
+ >
+ {#if item.avatarSrc}
+ <img src="{item.avatarSrc}" alt="{item.avatarAlt || ''}" />
+ {:else}
+ <span>{item.avatarFallback}</span>
+ {/if}
+ </button>
+ {/if}
+
+ <div
+ class="wire-next__chat-content"
+ role="button"
+ tabindex="0"
+ @click="selectMessage(item, index)"
+ @keydown="if (event.key === 'Enter' || event.key === ' ') { event.preventDefault(); selectMessage(item, index) }"
+ >
+ {#if item.title}<h4>{item.title}</h4>{/if}
+ {#if item.text}<p>{item.text}</p>{/if}
+ {#if item.bullets && item.bullets.length}
+ <ul>
+ {#each item.bullets as bullet}<li>{bullet}</li>{/each}
+ </ul>
+ {/if}
+ {#if item.links && item.links.length}
+ <nav aria-label="Message links">
+ {#each item.links as link}
+ <a
+ href="{link.href || '#'}"
+ @click="selectLink(event, link, item, index)"
+ >{link.label}</a>
+ {/each}
+ </nav>
+ {/if}
+ </div>
+ </div>
+
+ {#if showMetadata && (item.timestamp || item.status || item.actionLabel)}
+ <footer class="wire-next__chat-meta" data-tone="{item.statusTone || 'muted'}">
+ {#if item.statusIcon}<span class="{item.statusIcon}" aria-hidden="true">
+ </span>{/if}
+ {#if item.status}<span>{item.status}</span>{/if}
+ {#if item.timestamp}<time datetime="{item.datetime || ''}">{item.timestamp}</time>{/if}
+ {#if item.actionLabel}
+ <button type="button" @click="selectAction(event, item, index)">
+ {item.actionLabel}
+ </button>
+ {/if}
+ </footer>
+ {/if}
+ </article>
+ {/each}
+ </div>
+ {/if}
<slot />
</section>
}
}
-
+
}
diff --git a/app/pages/components/checkbox.wrn b/app/pages/components/checkbox.wrn
index 337bf39e..4b8d8a62 100644
--- a/app/pages/components/checkbox.wrn
+++ b/app/pages/components/checkbox.wrn
@@ -10,35 +10,81 @@ page Checkboxcomponent {
W WRNexusJS
-
+
Browse documentation
- forms componentCheckbox
Theme-aware, responsive checkbox component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Checkbox
+ forms componentCheckbox
Theme-aware, responsive checkbox component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Checkbox
size="default"
color="primary"
- label="Checkbox"
+ id="id"
name="name"
- value="on"
-/>
Legacy mount name: data-component="Checkbox".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"labelstringOptional "Checkbox"namestringOptional ""valuestringOptional "on"checkedbooleanOptional falsedisabledbooleanOptional falseclassstringOptional ""
Slots
This component does not declare a slot.
Events
This component does not declare a custom event.
Source contract
Installed source: components/checkbox.wrn
component Checkbox {
+ label="Checkbox"
+/>
Legacy mount name: data-component="Checkbox".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"idstringOptional ""namestringOptional ""labelstringOptional "Checkbox"hiddenLabelbooleanOptional falseplaceholderstringOptional ""variantstringOptional "normal"iconstringOptional ""iconPositionstringOptional "start"valuestringOptional "on"valuesstringOptional []optionsstringOptional []checkedbooleanOptional falseindeterminatebooleanOptional falseorientationstringOptional "vertical"cardbooleanOptional falserightAlignedbooleanOptional falselistbooleanOptional falsehelperTextstringOptional ""cornerHintstringOptional ""errorstringOptional ""inlinebooleanOptional falsereadonlybooleanOptional falsedisabledbooleanOptional falserequiredbooleanOptional falseclassstringOptional ""
Slots
This component does not declare a slot.
Events
inputchangefocusblurinvalid
Source contract
Installed source: components/Checkbox.wrn
component Checkbox {
props {
+ @event input = function
+ @event change = function
+ @event focus = function
+ @event blur = function
+ @event invalid = function
size = "default"
color = "primary"
- label = "Checkbox"
+ id = ""
name = ""
+ label = "Checkbox"
+ hiddenLabel = false
+ placeholder = ""
+ variant = "normal"
+ icon = ""
+ iconPosition = "start"
value = "on"
+ values = []
+ options = []
checked = false
+ indeterminate = false
+ orientation = "vertical"
+ card = false
+ rightAligned = false
+ list = false
+ helperText = ""
+ cornerHint = ""
+ error = ""
+ inline = false
+ readonly = false
disabled = false
+ required = false
class = ""
}
+ functions {
+ function emitField(nameEvent, sourceEvent) { sourceEvent.stopPropagation(); $emit(nameEvent, { checked: sourceEvent.currentTarget.checked, value: sourceEvent.currentTarget.value, values: values, name: name, sourceEvent: sourceEvent }) }
+ function preventReadonly(sourceEvent) { if (readonly) sourceEvent.preventDefault() }
+ }
view {
- <label class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--choice wire-next--checkbox {class}">
- <input {...attrs} type="checkbox" name="{name}" value="{value}" checked="{checked}" disabled="{disabled}" />
- <span>{label}</span>
+ <div {...attrs} class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--choice-field wire-next--checkbox-field {class}" data-inline="{inline}" data-invalid="{error ? 'true' : 'false'}" data-orientation="{orientation}" data-card="{card}" data-list="{list}" data-right-aligned="{rightAligned}">
+ <div class="wire-next__field-heading">{#if options.length || cornerHint}<span class="{hiddenLabel ? 'wire-next__sr-only' : ''}">{label}</span>{#if cornerHint}<span class="wire-next__field-hint">{cornerHint}</span>{/if}{/if}</div>
+ {#if options.length}
+ <div class="wire-next__checkbox-group" role="group" aria-label="{hiddenLabel ? label : ''}" aria-invalid="{error ? 'true' : 'false'}">
+ {#each options as option}
+ <label class="wire-next__choice wire-next--checkbox" for="{id || name}-{option.value}" data-variant="{variant}" data-disabled="{disabled || option.disabled}">
+ <input id="{id || name}-{option.value}" type="checkbox" name="{name}" value="{option.value}" checked="{values.includes(option.value) || option.checked}" disabled="{disabled || option.disabled}" required="{required}" readonly="{readonly}" @click="preventReadonly(event)" @input="emitField('input', event)" @change="emitField('change', event)" @focus="emitField('focus', event)" @blur="emitField('blur', event)" @invalid="emitField('invalid', event)" />
+ <span class="wire-next__choice-copy">
+ <strong>{option.label}</strong>{#if option.description}<small>{option.description}</small>{/if}</span>
</label>
+ {/each}
+ </div>
+ {:else}
+ <label class="wire-next__choice wire-next--checkbox" for="{id || name}" data-variant="{variant}" data-icon-position="{iconPosition}">
+ <input id="{id || name}" type="checkbox" name="{name}" value="{value}" checked="{checked}" disabled="{disabled}" required="{required}" readonly="{readonly}" aria-checked="{indeterminate ? 'mixed' : (checked ? 'true' : 'false')}" aria-invalid="{error ? 'true' : 'false'}" @click="preventReadonly(event)" @input="emitField('input', event)" @change="emitField('change', event)" @focus="emitField('focus', event)" @blur="emitField('blur', event)" @invalid="emitField('invalid', event)" />
+ {#if icon}<span class="{icon}" aria-hidden="true">
+ </span>{/if}
+ <span class="{hiddenLabel || cornerHint ? 'wire-next__sr-only' : ''}">{label}</span>
+ </label>
+ {/if}
+ {#if helperText}<small class="wire-next__field-help">{helperText}</small>{/if}<small class="wire-next__field-error" data-error="{name}">{error}</small>
+ </div>
}
}
-
+
}
diff --git a/app/pages/components/clipboard.wrn b/app/pages/components/clipboard.wrn
index bf343d72..3b3a07ae 100644
--- a/app/pages/components/clipboard.wrn
+++ b/app/pages/components/clipboard.wrn
@@ -10,17 +10,20 @@ page Clipboardcomponent {
W WRNexusJS
-
+
Browse documentation
- integrations componentClipboard
Theme-aware, responsive clipboard component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Clipboard
+ integrations componentClipboard
Theme-aware, responsive clipboard component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Clipboard
size="default"
color="primary"
title="Clipboard"
description="description"
items="[]"
-/>
Legacy mount name: data-component="Clipboard".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"titlestringOptional "Clipboard"descriptionstringOptional ""itemsstringOptional []variantstringOptional "default"classstringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/Clipboard.wrn
component Clipboard {
+/>
Legacy mount name: data-component="Clipboard".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"titlestringOptional "Clipboard"descriptionstringOptional ""itemsstringOptional []variantstringOptional "default"classstringOptional ""
Slots
default
Events
copysuccesserror
Source contract
Installed source: components/Clipboard.wrn
component Clipboard {
props {
+ @event copy = function
+ @event success = function
+ @event error = function
size = "default"
color = "primary"
title = "Clipboard"
@@ -39,7 +42,7 @@ page Clipboardcomponent {
}
}
-
+
}
diff --git a/app/pages/components/collapse.wrn b/app/pages/components/collapse.wrn
index 2981db33..691eab3f 100644
--- a/app/pages/components/collapse.wrn
+++ b/app/pages/components/collapse.wrn
@@ -10,34 +10,112 @@ page Collapsecomponent {
W WRNexusJS
-
+
Browse documentation
- base componentCollapse
Theme-aware, responsive collapse component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Collapse
+ base componentCollapse
Theme-aware, responsive collapse component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Collapse
size="default"
color="primary"
items="[]"
multiple="false"
-/>
Legacy mount name: data-component="Collapse".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"itemsstringOptional []multiplebooleanOptional falseclassstringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/Collapse.wrn
component Collapse {
+ mode="panel"
+/>
Legacy mount name: data-component="Collapse".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"itemsstringOptional []multiplebooleanOptional falsemodestringOptional "panel"initialOpenIndexesstringOptional []ariaLabelstringOptional "Collapsible content"classstringOptional ""
Slots
default
Events
toggleopenclose
Source contract
Installed source: components/Collapse.wrn
component Collapse {
props {
+ @event toggle = function
+ @event open = function
+ @event close = function
size = "default"
color = "primary"
items = []
multiple = false
+ mode = "panel"
+ initialOpenIndexes = []
+ ariaLabel = "Collapsible content"
class = ""
}
+
+ state openIndexes = initialOpenIndexes
+
+ functions {
+ function isOpen(index) {
+ return openIndexes.includes(index)
+ }
+
+ function toggleItem(index, item, opening) {
+ if (item.disabled) {
+ return
+ }
+ opening = !isOpen(index)
+ if (opening) {
+ if (multiple) {
+ openIndexes = openIndexes.concat(index)
+ } else {
+ openIndexes = [index]
+ }
+ $emit("open", { index: index, item: item })
+ } else {
+ openIndexes = openIndexes.filter((openIndex) => openIndex !== index)
+ $emit("close", { index: index, item: item })
+ }
+ $emit("toggle", {
+ index: index,
+ item: item,
+ open: opening,
+ openIndexes: openIndexes
+ })
+ }
+ }
+
view {
- <div class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--collapse {class}">
- {#each items as item}<details open="{item.open}">
- <summary>{item.label}</summary>
- <div>{item.content}</div>
- </details>{/each}
- <slot />
+ <section
+ {...attrs}
+ class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--collapse {class}"
+ data-mode="{mode}"
+ aria-label="{ariaLabel}"
+ >
+ {#each items as item, index}
+ <article class="wire-next__collapse-item" data-open="{isOpen(index)}">
+ {#if mode === "inline" && item.preview}
+ <p class="wire-next__collapse-preview">{item.preview}</p>
+ {/if}
+
+ <button
+ class="wire-next__collapse-trigger"
+ type="button"
+ aria-expanded="{isOpen(index) ? 'true' : 'false'}"
+ aria-controls="{item.id || 'collapse-panel-' + index}"
+ disabled="{item.disabled}"
+ @click="toggleItem(index, item)"
+ >
+ <span>{isOpen(index) ? (item.closeLabel || "Read less") : item.label}</span>
+ <span class="icon-[lucide--chevron-down] wire-next__collapse-chevron" aria-hidden="true">
+ </span>
+ </button>
+ <div
+ id="{item.id || 'collapse-panel-' + index}"
+ class="wire-next__collapse-panel"
+ data-open="{isOpen(index)}"
+ aria-hidden="{isOpen(index) ? 'false' : 'true'}"
+ inert="{!isOpen(index)}"
+ >
+ <div class="wire-next__collapse-content">
+ {#if item.title}<h4>{item.title}</h4>{/if}
+ {#if item.content}<p>{item.content}</p>{/if}
+ {#if item.links && item.links.length}
+ <nav aria-label="Related links">
+ {#each item.links as link}<a href="{link.href || '#'}">{link.label}</a>{/each}
+ </nav>
+ {/if}
+ </div>
</div>
+ </article>
+ {/each}
+ <slot />
+ </section>
}
}
-
+
}
diff --git a/app/pages/components/color-picker.wrn b/app/pages/components/color-picker.wrn
index cfcf5981..99de1282 100644
--- a/app/pages/components/color-picker.wrn
+++ b/app/pages/components/color-picker.wrn
@@ -10,40 +10,59 @@ page ColorPickercomponent {
W WRNexusJS
-
+
Browse documentation
- forms componentColorPicker
Theme-aware, responsive color picker component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<ColorPicker
+ forms componentColorPicker
Theme-aware, responsive color picker component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<ColorPicker
size="default"
color="primary"
- label="Color Picker"
+ id="id"
name="name"
- value="value"
-/>
Legacy mount name: data-component="ColorPicker".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"labelstringOptional "Color Picker"namestringOptional ""valuestringOptional ""placeholderstringOptional ""typestringOptional "color"minstringOptional ""maxstringOptional ""stepstringOptional ""disabledbooleanOptional falserequiredbooleanOptional falseclassstringOptional ""
Slots
This component does not declare a slot.
Events
This component does not declare a custom event.
Source contract
Installed source: components/ColorPicker.wrn
component ColorPicker {
+ label="Color"
+/>
Legacy mount name: data-component="ColorPicker".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"idstringOptional ""namestringOptional ""labelstringOptional "Color"hiddenLabelbooleanOptional falseplaceholderstringOptional ""valuestringOptional "#2563eb"iconstringOptional ""iconPositionstringOptional "start"helperTextstringOptional ""cornerHintstringOptional ""errorstringOptional ""inlinebooleanOptional falsevariantstringOptional "normal"readonlybooleanOptional falsedisabledbooleanOptional falserequiredbooleanOptional falseclassstringOptional ""
Slots
This component does not declare a slot.
Events
inputchangefocusblur
Source contract
Installed source: components/ColorPicker.wrn
component ColorPicker {
props {
+ @event input = function
+ @event change = function
+ @event focus = function
+ @event blur = function
size = "default"
color = "primary"
- label = "Color Picker"
+ id = ""
name = ""
- value = ""
+ label = "Color"
+ hiddenLabel = false
placeholder = ""
- type = "color"
- min = ""
- max = ""
- step = ""
+ value = "#2563eb"
+ icon = ""
+ iconPosition = "start"
+ helperText = ""
+ cornerHint = ""
+ error = ""
+ inline = false
+ variant = "normal"
+ readonly = false
disabled = false
required = false
class = ""
}
+ functions {
+ function emitField(nameEvent, sourceEvent) { sourceEvent.stopPropagation(); $emit(nameEvent, { value: sourceEvent.currentTarget.value, name: name, sourceEvent: sourceEvent }) }
+ function preventReadonly(sourceEvent) { if (readonly) sourceEvent.preventDefault() }
+ }
view {
- <label class="wire-next wire-next--field wire-next--color-picker {class}">
- <span>{label}</span>
- <input {...attrs} type="{type}" name="{name}" value="{value}" placeholder="{placeholder}" min="{min}" max="{max}" step="{step}" disabled="{disabled}" required="{required}" />
- </label>
+ <div {...attrs} class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--field wire-next--color-picker {class}" data-variant="{variant}" data-inline="{inline}" data-invalid="{error ? 'true' : 'false'}">
+ <div class="wire-next__field-heading">
+ <label class="{hiddenLabel ? 'wire-next__sr-only' : ''}" for="{id || name}">{label}</label>{#if cornerHint}<span class="wire-next__field-hint">{cornerHint}</span>{/if}</div>
+ <div class="wire-next__color-control" data-icon-position="{iconPosition}">{#if icon}<span class="{icon}" aria-hidden="true">
+ </span>{/if}<input id="{id || name}" type="color" name="{name}" value="{value}" disabled="{disabled}" required="{required}" readonly="{readonly}" aria-invalid="{error ? 'true' : 'false'}" @click="preventReadonly(event)" @input="emitField('input', event)" @change="emitField('change', event)" @focus="emitField('focus', event)" @blur="emitField('blur', event)" />
+ <output>{value}</output>
+ </div>
+ {#if helperText}<small class="wire-next__field-help">{helperText}</small>{/if}<small class="wire-next__field-error" data-error="{name}">{error}</small>
+ </div>
}
}
-
+
}
diff --git a/app/pages/components/columns.wrn b/app/pages/components/columns.wrn
index 93a8959e..8d020266 100644
--- a/app/pages/components/columns.wrn
+++ b/app/pages/components/columns.wrn
@@ -10,10 +10,10 @@ page Columnscomponent {
W WRNexusJS
-
+
Browse documentation
- layout componentColumns
Theme-aware, responsive columns component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Columns
+ layout componentColumns
Theme-aware, responsive columns component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Columns
size="default"
color="primary"
columns="2"
@@ -35,7 +35,7 @@ page Columnscomponent {
}
}
-
+
}
diff --git a/app/pages/components/combo-box.wrn b/app/pages/components/combo-box.wrn
index 7e3f9467..a1ac467f 100644
--- a/app/pages/components/combo-box.wrn
+++ b/app/pages/components/combo-box.wrn
@@ -10,10 +10,10 @@ page ComboBoxcomponent {
W WRNexusJS
-
+
Browse documentation
- advanced-forms componentComboBox
Editable autocomplete combobox with local and remote suggestions.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<ComboBox
+ advanced-forms componentComboBox
Editable autocomplete combobox with local and remote suggestions.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<ComboBox
size="default"
color="primary"
label="ComboBox"
@@ -413,7 +413,7 @@ page ComboBoxcomponent {
}
}
-
+
}
diff --git a/app/pages/components/confetti.wrn b/app/pages/components/confetti.wrn
index d863171e..44776a36 100644
--- a/app/pages/components/confetti.wrn
+++ b/app/pages/components/confetti.wrn
@@ -10,17 +10,19 @@ page Confetticomponent {
W WRNexusJS
-
+
Browse documentation
- integrations componentConfetti
Theme-aware, responsive confetti component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Confetti
+ integrations componentConfetti
Theme-aware, responsive confetti component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Confetti
size="default"
color="primary"
title="Confetti"
description="description"
items="[]"
-/>
Legacy mount name: data-component="Confetti".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"titlestringOptional "Confetti"descriptionstringOptional ""itemsstringOptional []variantstringOptional "default"classstringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/Confetti.wrn
component Confetti {
+/>
Legacy mount name: data-component="Confetti".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"titlestringOptional "Confetti"descriptionstringOptional ""itemsstringOptional []variantstringOptional "default"classstringOptional ""
Slots
default
Events
startcomplete
Source contract
Installed source: components/Confetti.wrn
component Confetti {
props {
+ @event start = function
+ @event complete = function
size = "default"
color = "primary"
title = "Confetti"
@@ -39,7 +41,7 @@ page Confetticomponent {
}
}
-
+
}
diff --git a/app/pages/components/container.wrn b/app/pages/components/container.wrn
index b43d6910..4db9b403 100644
--- a/app/pages/components/container.wrn
+++ b/app/pages/components/container.wrn
@@ -10,10 +10,10 @@ page Containercomponent {
W WRNexusJS
-
+
Browse documentation
- layout componentContainer
Theme-aware, responsive container component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Container
+ layout componentContainer
Theme-aware, responsive container component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Container
size="default"
color="primary"
columns="2"
@@ -35,7 +35,7 @@ page Containercomponent {
}
}
-
+
}
diff --git a/app/pages/components/context-menu.wrn b/app/pages/components/context-menu.wrn
index f7a8877a..826c90e7 100644
--- a/app/pages/components/context-menu.wrn
+++ b/app/pages/components/context-menu.wrn
@@ -10,17 +10,20 @@ page ContextMenucomponent {
W WRNexusJS
-
+
Browse documentation
- overlays componentContextMenu
Theme-aware, responsive context menu component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<ContextMenu
+ overlays componentContextMenu
Theme-aware, responsive context menu component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<ContextMenu
size="default"
color="primary"
title="Context Menu"
description="description"
open="false"
-/>
Legacy mount name: data-component="ContextMenu".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"titlestringOptional "Context Menu"descriptionstringOptional ""openbooleanOptional falseplacementstringOptional "bottom"closeLabelstringOptional "Close"classstringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/ContextMenu.wrn
component ContextMenu {
+/>
Legacy mount name: data-component="ContextMenu".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"titlestringOptional "Context Menu"descriptionstringOptional ""openbooleanOptional falseplacementstringOptional "bottom"closeLabelstringOptional "Close"classstringOptional ""
Slots
default
Events
opencloseselect
Source contract
Installed source: components/ContextMenu.wrn
component ContextMenu {
props {
+ @event open = function
+ @event close = function
+ @event select = function
size = "default"
color = "primary"
title = "Context Menu"
@@ -42,7 +45,7 @@ page ContextMenucomponent {
}
}
-
+
}
diff --git a/app/pages/components/copy-markup.wrn b/app/pages/components/copy-markup.wrn
index bebe8cc1..7b16795e 100644
--- a/app/pages/components/copy-markup.wrn
+++ b/app/pages/components/copy-markup.wrn
@@ -10,17 +10,20 @@ page CopyMarkupcomponent {
W WRNexusJS
-
+
Browse documentation
- advanced-forms componentCopyMarkup
Theme-aware, responsive copy markup component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<CopyMarkup
+ advanced-forms componentCopyMarkup
Theme-aware, responsive copy markup component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<CopyMarkup
size="default"
color="primary"
label="Copy Markup"
name="name"
value="value"
-/>
Legacy mount name: data-component="CopyMarkup".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"labelstringOptional "Copy Markup"namestringOptional ""valuestringOptional ""placeholderstringOptional ""typestringOptional "text"minstringOptional ""maxstringOptional ""stepstringOptional ""disabledbooleanOptional falserequiredbooleanOptional falseclassstringOptional ""
Slots
This component does not declare a slot.
Events
This component does not declare a custom event.
Source contract
Installed source: components/CopyMarkup.wrn
component CopyMarkup {
+/>
Legacy mount name: data-component="CopyMarkup".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"labelstringOptional "Copy Markup"namestringOptional ""valuestringOptional ""placeholderstringOptional ""typestringOptional "text"minstringOptional ""maxstringOptional ""stepstringOptional ""disabledbooleanOptional falserequiredbooleanOptional falseclassstringOptional ""
Slots
This component does not declare a slot.
Events
copysuccesserror
Source contract
Installed source: components/CopyMarkup.wrn
component CopyMarkup {
props {
+ @event copy = function
+ @event success = function
+ @event error = function
size = "default"
color = "primary"
label = "Copy Markup"
@@ -43,7 +46,7 @@ page CopyMarkupcomponent {
}
}
-
+
}
diff --git a/app/pages/components/custom-scrollbar.wrn b/app/pages/components/custom-scrollbar.wrn
index e39ad967..2819d613 100644
--- a/app/pages/components/custom-scrollbar.wrn
+++ b/app/pages/components/custom-scrollbar.wrn
@@ -10,17 +10,18 @@ page CustomScrollbarcomponent {
W WRNexusJS
-
+
Browse documentation
- layout componentCustomScrollbar
Theme-aware, responsive custom scrollbar component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<CustomScrollbar
+ layout componentCustomScrollbar
Theme-aware, responsive custom scrollbar component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<CustomScrollbar
size="default"
color="primary"
columns="2"
gap="md"
maxWidth="xl"
-/>
Legacy mount name: data-component="CustomScrollbar".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"columnsnumberOptional 2gapstringOptional "md"maxWidthstringOptional "xl"classstringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/CustomScrollbar.wrn
component CustomScrollbar {
+/>
Legacy mount name: data-component="CustomScrollbar".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"columnsnumberOptional 2gapstringOptional "md"maxWidthstringOptional "xl"classstringOptional ""
Slots
default
Events
scroll
Source contract
Installed source: components/CustomScrollbar.wrn
component CustomScrollbar {
props {
+ @event scroll = function
size = "default"
color = "primary"
columns = 2
@@ -35,7 +36,7 @@ page CustomScrollbarcomponent {
}
}
-
+
}
diff --git a/app/pages/components/data-map.wrn b/app/pages/components/data-map.wrn
index e0cbb612..7031f501 100644
--- a/app/pages/components/data-map.wrn
+++ b/app/pages/components/data-map.wrn
@@ -10,17 +10,19 @@ page DataMapcomponent {
W WRNexusJS
-
+
Browse documentation
- integrations componentDataMap
Theme-aware, responsive data map component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<DataMap
+ integrations componentDataMap
Theme-aware, responsive data map component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<DataMap
size="default"
color="primary"
title="Data Map"
description="description"
items="[]"
-/>
Legacy mount name: data-component="DataMap".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"titlestringOptional "Data Map"descriptionstringOptional ""itemsstringOptional []variantstringOptional "default"classstringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/DataMap.wrn
component DataMap {
+/>
Legacy mount name: data-component="DataMap".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"titlestringOptional "Data Map"descriptionstringOptional ""itemsstringOptional []variantstringOptional "default"classstringOptional ""
Slots
default
Events
selectchange
Source contract
Installed source: components/DataMap.wrn
component DataMap {
props {
+ @event select = function
+ @event change = function
size = "default"
color = "primary"
title = "Data Map"
@@ -39,7 +41,7 @@ page DataMapcomponent {
}
}
-
+
}
diff --git a/app/pages/components/data-table.wrn b/app/pages/components/data-table.wrn
index e1f8c32c..d28b729d 100644
--- a/app/pages/components/data-table.wrn
+++ b/app/pages/components/data-table.wrn
@@ -10,17 +10,22 @@ page DataTablecomponent {
W WRNexusJS
-
+
Browse documentation
- integrations componentDataTable
Theme-aware, responsive data table component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<DataTable
+ integrations componentDataTable
Theme-aware, responsive data table component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<DataTable
size="default"
color="primary"
caption="Data Table"
columns="[]"
rows="[]"
-/>
Legacy mount name: data-component="DataTable".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"captionstringOptional "Data Table"columnsstringOptional []rowsstringOptional []stripedbooleanOptional trueclassstringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/DataTable.wrn
component DataTable {
+/>
Legacy mount name: data-component="DataTable".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"captionstringOptional "Data Table"columnsstringOptional []rowsstringOptional []stripedbooleanOptional trueclassstringOptional ""
Slots
default
Events
sortselectchangerowClickpageChange
Source contract
Installed source: components/DataTable.wrn
component DataTable {
props {
+ @event sort = function
+ @event select = function
+ @event change = function
+ @event rowClick = function
+ @event pageChange = function
size = "default"
color = "primary"
caption = "Data Table"
@@ -43,7 +48,7 @@ page DataTablecomponent {
}
}
-
+
}
diff --git a/app/pages/components/date-picker.wrn b/app/pages/components/date-picker.wrn
index 0c877b10..efa11523 100644
--- a/app/pages/components/date-picker.wrn
+++ b/app/pages/components/date-picker.wrn
@@ -10,40 +10,92 @@ page DatePickercomponent {
W WRNexusJS
-
+
Browse documentation
- base componentDatePicker
Theme-aware, responsive date picker component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<DatePicker
+ base componentDatePicker
Theme-aware, responsive date picker component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<DatePicker
size="default"
color="primary"
label="Date Picker"
+ id="id"
name="name"
- value="value"
-/>
Legacy mount name: data-component="DatePicker".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"labelstringOptional "Date Picker"namestringOptional ""valuestringOptional ""placeholderstringOptional ""typestringOptional "date"minstringOptional ""maxstringOptional ""stepstringOptional ""disabledbooleanOptional falserequiredbooleanOptional falseclassstringOptional ""
Slots
This component does not declare a slot.
Events
This component does not declare a custom event.
Source contract
Installed source: components/DatePicker.wrn
component DatePicker {
+/>
Legacy mount name: data-component="DatePicker".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"labelstringOptional "Date Picker"idstringOptional ""namestringOptional ""valuestringOptional ""placeholderstringOptional ""typestringOptional "date"localestringOptional "en-US"firstDayOfWeeknumberOptional 0monthsstringOptional [{ label: "Jan", value: "01" }, { label: "Feb", value: "02" }, { label: "Mar", value: "03" }, { label: "Apr", value: "04" }, { label: "May", value: "05" }, { label: "Jun", value: "06" }, { label: "Jul", value: "07" }, { label: "Aug", value: "08" }, { label: "Sep", value: "09" }, { label: "Oct", value: "10" }, { label: "Nov", value: "11" }, { label: "Dec", value: "12" }]daysstringOptional [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]yearsstringOptional [2024, 2025, 2026, 2027, 2028, 2029, 2030]minstringOptional ""maxstringOptional ""stepstringOptional ""helperTextstringOptional ""cornerHintstringOptional ""errorstringOptional ""variantstringOptional "normal"inlinebooleanOptional falsereadonlybooleanOptional falsedisabledbooleanOptional falserequiredbooleanOptional falseclassstringOptional ""
Slots
This component does not declare a slot.
Events
inputchangeopenclosefocusblurinvalid
Source contract
Installed source: components/DatePicker.wrn
component DatePicker {
props {
+ @event input = function
+ @event change = function
+ @event open = function
+ @event close = function
+ @event focus = function
+ @event blur = function
+ @event invalid = function
size = "default"
color = "primary"
label = "Date Picker"
+ id = ""
name = ""
value = ""
placeholder = ""
type = "date"
+ locale = "en-US"
+ firstDayOfWeek = 0
+ months = [{ label: "Jan", value: "01" }, { label: "Feb", value: "02" }, { label: "Mar", value: "03" }, { label: "Apr", value: "04" }, { label: "May", value: "05" }, { label: "Jun", value: "06" }, { label: "Jul", value: "07" }, { label: "Aug", value: "08" }, { label: "Sep", value: "09" }, { label: "Oct", value: "10" }, { label: "Nov", value: "11" }, { label: "Dec", value: "12" }]
+ days = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]
+ years = [2024, 2025, 2026, 2027, 2028, 2029, 2030]
min = ""
max = ""
step = ""
+ helperText = ""
+ cornerHint = ""
+ error = ""
+ variant = "normal"
+ inline = false
+ readonly = false
disabled = false
required = false
class = ""
}
+ state currentValue = value
+ state selectedYear = value ? value.split("-")[0] : ""
+ state selectedMonth = value ? value.split("-")[1] : ""
+ state selectedDay = value ? value.split("-")[2] : ""
+ state expanded = false
+ functions {
+ function openCalendar(sourceEvent) { expanded = true; $emit("open", { value: currentValue, name: name, sourceEvent: sourceEvent }) }
+ function updateDate(part, nextValue, sourceEvent, nextDate, detail) { if (part === "year") { selectedYear = String(nextValue) } if (part === "month") { selectedMonth = String(nextValue).padStart(2, "0") } if (part === "day") { selectedDay = String(nextValue).padStart(2, "0") } if (!selectedYear || !selectedMonth || !selectedDay) { return } nextDate = selectedYear + "-" + selectedMonth + "-" + selectedDay; if ((min && nextDate < min) || (max && nextDate > max)) { return } currentValue = nextDate; detail = { value: currentValue, year: selectedYear, month: selectedMonth, day: selectedDay, name: name, sourceEvent: sourceEvent }; $emit("input", detail); $emit("change", detail) }
+ function finishDate(sourceEvent) { if (!currentValue) { return } expanded = false; $emit("close", { value: currentValue, name: name, sourceEvent: sourceEvent }) }
+ function selectDay(sourceEvent, root, input, nextDate, trigger, detail) { root = sourceEvent.currentTarget.closest(".wire-next--date-picker"); input = root.querySelector(".wire-next__picker-value"); nextDate = input.getAttribute("value").slice(0, 5) + root.querySelector("select").getAttribute("value") + "-" + sourceEvent.currentTarget.dataset.value; currentValue = nextDate; input.setAttribute("value", nextDate); trigger = root.querySelector(".wire-next__date-trigger span"); if (trigger) { trigger.replaceChildren(nextDate) } sourceEvent.currentTarget.setAttribute("aria-pressed", "true"); detail = { value: nextDate, name: name, sourceEvent: sourceEvent }; $emit("input", detail); $emit("change", detail) }
+ function clearDate(sourceEvent, detail) { if (disabled || readonly) { return } currentValue = ""; detail = { value: currentValue, name: name, sourceEvent: sourceEvent }; $emit("input", detail); $emit("change", detail) }
+ function handleFocus(sourceEvent) { $emit("focus", { value: currentValue, name: name, sourceEvent: sourceEvent }) }
+ function handleBlur(sourceEvent) { $emit("blur", { value: currentValue, name: name, sourceEvent: sourceEvent }) }
+ function handleInvalid(sourceEvent) { $emit("invalid", { name: name, message: sourceEvent.currentTarget.validationMessage, sourceEvent: sourceEvent }) }
+ }
view {
- <label class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--field wire-next--date-picker {class}">
- <span>{label}</span>
- <input {...attrs} type="{type}" name="{name}" value="{value}" placeholder="{placeholder}" min="{min}" max="{max}" step="{step}" disabled="{disabled}" required="{required}" />
+ <div {...attrs} class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--field wire-next--date-picker {class}" data-variant="{variant}" data-inline="{inline}" data-invalid="{error ? 'true' : 'false'}" data-expanded="{expanded}">
+ <div class="wire-next__field-heading">
+ <label for="{id || name}">{label}</label>{#if cornerHint}<span class="wire-next__field-hint">{cornerHint}</span>{/if}</div>
+ <div class="wire-next__picker-control">
+ <input id="{id || name}" class="wire-next__sr-only wire-next__picker-value" type="text" name="{name}" value="{currentValue}" required="{required}" readonly aria-hidden="true" tabindex="-1" @invalid="handleInvalid(event)" />
+ <button type="button" class="wire-next__date-trigger" disabled="{disabled || readonly}" aria-haspopup="dialog" aria-expanded="{expanded}" @click="openCalendar(event)" @focus="handleFocus(event)" @blur="handleBlur(event)">
+ <span>{currentValue || placeholder || "Select date"}</span>
+ <i class="icon-[lucide--calendar-days]" aria-hidden="true">
+ </i>
+ </button>{#if currentValue && !readonly && !disabled}<button type="button" class="wire-next__picker-clear" aria-label="Clear date" @click="clearDate(event)">×</button>{/if}</div>
+ <div class="wire-next__calendar" role="dialog" aria-label="{label}">
+ <div class="wire-next__date-selectors">
+ <label>Month<select value="{selectedMonth}" @change="updateDate('month', event.currentTarget.value, event)">{#each months as month}<option value="{month.value}" selected="{month.value === selectedMonth}">{month.label}</option>{/each}</select>
</label>
+ <label>Year<select value="{selectedYear}" @change="updateDate('year', event.currentTarget.value, event)">{#each years as year}<option value="{year}" selected="{String(year) === selectedYear}">{year}</option>{/each}</select>
+ </label>
+ </div>
+ <div class="wire-next__calendar-grid">{#each days as day}<button type="button" data-value="{String(day).padStart(2, '0')}" aria-pressed="{String(day).padStart(2, '0') === selectedDay}" @click="selectDay(event)">{day}</button>{/each}</div>
+ <button type="button" class="wire-next__date-done" disabled="{!currentValue}" @click="finishDate(event)">Done</button>
+ </div>
+ {#if helperText}<small class="wire-next__field-help">{helperText}</small>{/if}<small class="wire-next__field-error" data-error="{name}">{error}</small>
+ </div>
}
}
-
+
}
diff --git a/app/pages/components/device-frame.wrn b/app/pages/components/device-frame.wrn
index ed07b0c9..d2394cf3 100644
--- a/app/pages/components/device-frame.wrn
+++ b/app/pages/components/device-frame.wrn
@@ -10,36 +10,53 @@ page DeviceFramecomponent {
W WRNexusJS
-
+
Browse documentation
- base componentDeviceFrame
Theme-aware, responsive device frame component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<DeviceFrame
+ base componentDeviceFrame
Theme-aware, responsive device frame component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<DeviceFrame
size="default"
color="primary"
title="Device Frame"
description="description"
items="[]"
-/>
Legacy mount name: data-component="DeviceFrame".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"titlestringOptional "Device Frame"descriptionstringOptional ""itemsstringOptional []variantstringOptional "default"classstringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/DeviceFrame.wrn
component DeviceFrame {
+/>
Legacy mount name: data-component="DeviceFrame".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"titlestringOptional "Device Frame"descriptionstringOptional ""itemsstringOptional []variantstringOptional "default"devicestringOptional "phone"orientationstringOptional "portrait"srcstringOptional ""srcdocstringOptional ""frameTitlestringOptional "Device preview"showToolbarbooleanOptional trueallowstringOptional ""classstringOptional ""
Slots
default
Events
changerotate
Source contract
Installed source: components/DeviceFrame.wrn
component DeviceFrame {
props {
+ @event change = function
+ @event rotate = function
size = "default"
color = "primary"
title = "Device Frame"
description = ""
items = []
variant = "default"
+ device = "phone"
+ orientation = "portrait"
+ src = ""
+ srcdoc = ""
+ frameTitle = "Device preview"
+ showToolbar = true
+ allow = ""
class = ""
}
+ state currentOrientation = orientation
+ functions {
+ function setDevice(nextDevice, sourceEvent) { $emit("change", { device: nextDevice, orientation: currentOrientation, sourceEvent: sourceEvent }) }
+ function rotateFrame(sourceEvent) { currentOrientation = currentOrientation === "portrait" ? "landscape" : "portrait"; $emit("rotate", { device: device, orientation: currentOrientation, sourceEvent: sourceEvent }); $emit("change", { device: device, orientation: currentOrientation, sourceEvent: sourceEvent }) }
+ }
view {
- <section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--device-frame wire-next--variant-{variant} {class}">
- {#if title}<strong>{title}</strong>{/if}
- {#if description}<p>{description}</p>{/if}
- {#if items}<div class="wire-next__items">{#each items as item}<span>{item.label}</span>{/each}</div>{/if}
- <slot />
+ <section {...attrs} class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--device-frame wire-next--variant-{variant} {class}" data-device="{device}" data-orientation="{currentOrientation}">
+ <header>
+ <div>{#if title}<strong>{title}</strong>{/if}{#if description}<p>{description}</p>{/if}</div>{#if showToolbar}<div class="wire-next__device-actions" role="toolbar" aria-label="Preview device">{#each items as item}<button type="button" aria-pressed="{item.value === device}" @click="setDevice(item.value, event)">{item.label}</button>{/each}<button type="button" aria-label="Rotate preview" @click="rotateFrame(event)">↻</button>
+ </div>{/if}</header>
+ <div class="wire-next__device-shell">{#if src || srcdoc}<iframe title="{frameTitle}" src="{src}" srcdoc="{srcdoc}" allow="{allow}">
+ </iframe>{:else}<div class="wire-next__device-content">
+ <slot />
+ </div>{/if}</div>
</section>
}
}
-
+
}
diff --git a/app/pages/components/divider.wrn b/app/pages/components/divider.wrn
index 2445d3a6..42df8d27 100644
--- a/app/pages/components/divider.wrn
+++ b/app/pages/components/divider.wrn
@@ -10,10 +10,10 @@ page Dividercomponent {
W WRNexusJS
-
+
Browse documentation
- layout componentDivider
Theme-aware, responsive divider component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Divider
+ layout componentDivider
Theme-aware, responsive divider component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Divider
size="default"
color="primary"
label="label"
@@ -31,7 +31,7 @@ page Dividercomponent {
}
}
-
+
}
diff --git a/app/pages/components/drag-and-drop.wrn b/app/pages/components/drag-and-drop.wrn
index 1e8c8af7..d0960f0d 100644
--- a/app/pages/components/drag-and-drop.wrn
+++ b/app/pages/components/drag-and-drop.wrn
@@ -10,17 +10,23 @@ page DragAndDropcomponent {
W WRNexusJS
-
+
Browse documentation
- integrations componentDragAndDrop
Theme-aware, responsive drag and drop component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<DragAndDrop
+ integrations componentDragAndDrop
Theme-aware, responsive drag and drop component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<DragAndDrop
size="default"
color="primary"
title="Drag And Drop"
description="description"
items="[]"
-/>
Legacy mount name: data-component="DragAndDrop".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"titlestringOptional "Drag And Drop"descriptionstringOptional ""itemsstringOptional []variantstringOptional "default"classstringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/DragAndDrop.wrn
component DragAndDrop {
+/>
Legacy mount name: data-component="DragAndDrop".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"titlestringOptional "Drag And Drop"descriptionstringOptional ""itemsstringOptional []variantstringOptional "default"classstringOptional ""
Slots
default
Events
dragStartdragEnddragEnterdragLeavedropchange
Source contract
Installed source: components/DragAndDrop.wrn
component DragAndDrop {
props {
+ @event dragStart = function
+ @event dragEnd = function
+ @event dragEnter = function
+ @event dragLeave = function
+ @event drop = function
+ @event change = function
size = "default"
color = "primary"
title = "Drag And Drop"
@@ -39,7 +45,7 @@ page DragAndDropcomponent {
}
}
-
+
}
diff --git a/app/pages/components/drawer.wrn b/app/pages/components/drawer.wrn
index 52187f5a..39d227cb 100644
--- a/app/pages/components/drawer.wrn
+++ b/app/pages/components/drawer.wrn
@@ -10,17 +10,19 @@ page Drawercomponent {
W WRNexusJS
-
+
Browse documentation
- overlays componentDrawer
Theme-aware, responsive drawer component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Drawer
+ overlays componentDrawer
Theme-aware, responsive drawer component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Drawer
size="default"
color="primary"
title="Drawer"
description="description"
open="false"
-/>
Legacy mount name: data-component="Drawer".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"titlestringOptional "Drawer"descriptionstringOptional ""openbooleanOptional falseplacementstringOptional "bottom"closeLabelstringOptional "Close"classstringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/Drawer.wrn
component Drawer {
+/>
Legacy mount name: data-component="Drawer".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"titlestringOptional "Drawer"descriptionstringOptional ""openbooleanOptional falseplacementstringOptional "bottom"closeLabelstringOptional "Close"classstringOptional ""
Slots
default
Events
openclose
Source contract
Installed source: components/Drawer.wrn
component Drawer {
props {
+ @event open = function
+ @event close = function
size = "default"
color = "primary"
title = "Drawer"
@@ -42,7 +44,7 @@ page Drawercomponent {
}
}
-
+
}
diff --git a/app/pages/components/dropdown.wrn b/app/pages/components/dropdown.wrn
index 168cfb1b..6daed11a 100644
--- a/app/pages/components/dropdown.wrn
+++ b/app/pages/components/dropdown.wrn
@@ -10,17 +10,21 @@ page Dropdowncomponent {
W WRNexusJS
-
+
Browse documentation
- overlays componentDropdown
Theme-aware, responsive dropdown component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Dropdown
+ overlays componentDropdown
Theme-aware, responsive dropdown component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Dropdown
size="default"
color="primary"
title="Dropdown"
description="description"
open="false"
-/>
Legacy mount name: data-component="Dropdown".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"titlestringOptional "Dropdown"descriptionstringOptional ""openbooleanOptional falseplacementstringOptional "bottom"closeLabelstringOptional "Close"classstringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/Dropdown.wrn
component Dropdown {
+/>
Legacy mount name: data-component="Dropdown".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"titlestringOptional "Dropdown"descriptionstringOptional ""openbooleanOptional falseplacementstringOptional "bottom"closeLabelstringOptional "Close"classstringOptional ""
Slots
default
Events
opencloseselectchange
Source contract
Installed source: components/Dropdown.wrn
component Dropdown {
props {
+ @event open = function
+ @event close = function
+ @event select = function
+ @event change = function
size = "default"
color = "primary"
title = "Dropdown"
@@ -42,7 +46,7 @@ page Dropdowncomponent {
}
}
-
+
}
diff --git a/app/pages/components/file-input.wrn b/app/pages/components/file-input.wrn
index 7e60809a..62623c3b 100644
--- a/app/pages/components/file-input.wrn
+++ b/app/pages/components/file-input.wrn
@@ -10,40 +10,73 @@ page FileInputcomponent {
W WRNexusJS
-
+
Browse documentation
- forms componentFileInput
Theme-aware, responsive file input component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<FileInput
+ forms componentFileInput
Theme-aware, responsive file input component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<FileInput
size="default"
color="primary"
- label="File Input"
+ id="id"
name="name"
- value="value"
-/>
Legacy mount name: data-component="FileInput".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"labelstringOptional "File Input"namestringOptional ""valuestringOptional ""placeholderstringOptional ""typestringOptional "file"minstringOptional ""maxstringOptional ""stepstringOptional ""disabledbooleanOptional falserequiredbooleanOptional falseclassstringOptional ""
Slots
This component does not declare a slot.
Events
This component does not declare a custom event.
Source contract
Installed source: components/FileInput.wrn
component FileInput {
+ label="File"
+/>
Legacy mount name: data-component="FileInput".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"idstringOptional ""namestringOptional ""labelstringOptional "File"hiddenLabelbooleanOptional falseplaceholderstringOptional "Choose a file"valuestringOptional ""iconstringOptional "icon-[lucide--upload]"iconPositionstringOptional "start"acceptstringOptional ""multiplebooleanOptional falsehelperTextstringOptional ""cornerHintstringOptional ""errorstringOptional ""inlinebooleanOptional falsevariantstringOptional "normal"readonlybooleanOptional falsedisabledbooleanOptional falserequiredbooleanOptional falseclassstringOptional ""
Slots
This component does not declare a slot.
Events
inputchangefocusblurselectclearinvalid
Source contract
Installed source: components/FileInput.wrn
component FileInput {
props {
+ @event input = function
+ @event change = function
+ @event focus = function
+ @event blur = function
+ @event select = function
+ @event clear = function
+ @event invalid = function
size = "default"
color = "primary"
- label = "File Input"
+ id = ""
name = ""
+ label = "File"
+ hiddenLabel = false
+ placeholder = "Choose a file"
value = ""
- placeholder = ""
- type = "file"
- min = ""
- max = ""
- step = ""
+ icon = "icon-[lucide--upload]"
+ iconPosition = "start"
+ accept = ""
+ multiple = false
+ helperText = ""
+ cornerHint = ""
+ error = ""
+ inline = false
+ variant = "normal"
+ readonly = false
disabled = false
required = false
class = ""
}
+ state selectedName = ""
+ functions {
+ function handleChange(sourceEvent) {
+ sourceEvent.stopPropagation()
+ selectedName = sourceEvent.currentTarget.files && sourceEvent.currentTarget.files.length ? sourceEvent.currentTarget.files[0].name : ""
+ $emit("input", { files: sourceEvent.currentTarget.files, name: name, sourceEvent: sourceEvent })
+ $emit("change", { files: sourceEvent.currentTarget.files, name: name, sourceEvent: sourceEvent })
+ if (selectedName) $emit("select", { files: sourceEvent.currentTarget.files, name: name, sourceEvent: sourceEvent })
+ else $emit("clear", { name: name, sourceEvent: sourceEvent })
+ }
+ function emitField(nameEvent, sourceEvent) { sourceEvent.stopPropagation(); $emit(nameEvent, { name: name, sourceEvent: sourceEvent }) }
+ function preventReadonly(sourceEvent) { if (readonly) sourceEvent.preventDefault() }
+ }
view {
- <label class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--field wire-next--file-input {class}">
- <span>{label}</span>
- <input {...attrs} type="{type}" name="{name}" value="{value}" placeholder="{placeholder}" min="{min}" max="{max}" step="{step}" disabled="{disabled}" required="{required}" />
- </label>
+ <div {...attrs} class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--field wire-next--file-input {class}" data-variant="{variant}" data-inline="{inline}" data-invalid="{error ? 'true' : 'false'}">
+ <div class="wire-next__field-heading">
+ <label class="{hiddenLabel ? 'wire-next__sr-only' : ''}" for="{id || name}">{label}</label>{#if cornerHint}<span class="wire-next__field-hint">{cornerHint}</span>{/if}</div>
+ <div class="wire-next__file-control" data-icon-position="{iconPosition}">{#if icon}<span class="{icon}" aria-hidden="true">
+ </span>{/if}<span>{selectedName || value || placeholder}</span>
+ <input id="{id || name}" type="file" name="{name}" accept="{accept}" multiple="{multiple}" disabled="{disabled}" required="{required}" aria-readonly="{readonly}" aria-invalid="{error ? 'true' : 'false'}" @click="preventReadonly(event)" @input="handleChange(event)" @change="handleChange(event)" @focus="emitField('focus', event)" @blur="emitField('blur', event)" @invalid="emitField('invalid', event)" />
+ </div>
+ {#if helperText}<small class="wire-next__field-help">{helperText}</small>{/if}<small class="wire-next__field-error" data-error="{name}">{error}</small>
+ </div>
}
}
-
+
}
diff --git a/app/pages/components/file-upload-progress.wrn b/app/pages/components/file-upload-progress.wrn
index 2bea4ee2..10916aa6 100644
--- a/app/pages/components/file-upload-progress.wrn
+++ b/app/pages/components/file-upload-progress.wrn
@@ -10,36 +10,62 @@ page FileUploadProgresscomponent {
W WRNexusJS
-
+
Browse documentation
- base componentFileUploadProgress
Theme-aware, responsive file upload progress component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<FileUploadProgress
+ base componentFileUploadProgress
Theme-aware, responsive file upload progress component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<FileUploadProgress
size="default"
color="primary"
label="Progress"
value="50"
max="100"
-/>
Legacy mount name: data-component="FileUploadProgress".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"labelstringOptional "Progress"valuenumberOptional 50maxnumberOptional 100showValuebooleanOptional trueclassstringOptional ""
Slots
This component does not declare a slot.
Events
This component does not declare a custom event.
Source contract
Installed source: components/FileUploadProgress.wrn
component FileUploadProgress {
+/>
Legacy mount name: data-component="FileUploadProgress".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"labelstringOptional "Progress"valuenumberOptional 50maxnumberOptional 100showValuebooleanOptional truefileNamestringOptional ""fileSizestringOptional ""uploadedSizestringOptional ""statusstringOptional "uploading"cancelLabelstringOptional "Cancel upload"retryLabelstringOptional "Retry upload"classstringOptional ""
Slots
This component does not declare a slot.
Events
cancelretrycomplete
Source contract
Installed source: components/FileUploadProgress.wrn
component FileUploadProgress {
props {
+ @event cancel = function
+ @event retry = function
+ @event complete = function
size = "default"
color = "primary"
label = "Progress"
value = 50
max = 100
showValue = true
+ fileName = ""
+ fileSize = ""
+ uploadedSize = ""
+ status = "uploading"
+ cancelLabel = "Cancel upload"
+ retryLabel = "Retry upload"
class = ""
}
+ state currentValue = value
+ state currentStatus = status
+ functions {
+ function percent() { if (!Number(max)) { return 0 } return Math.max(0, Math.min(100, Math.round(Number(currentValue) / Number(max) * 100))) }
+ function detail(sourceEvent) { return { value: currentValue, max: max, percent: percent(), status: currentStatus, fileName: fileName, sourceEvent: sourceEvent } }
+ function cancelUpload(sourceEvent) { currentStatus = "cancelled"; $emit("cancel", detail(sourceEvent)) }
+ function retryUpload(sourceEvent) { currentValue = 0; currentStatus = "uploading"; $emit("retry", detail(sourceEvent)) }
+ function completeUpload(sourceEvent) { currentValue = max; currentStatus = "complete"; $emit("complete", detail(sourceEvent)) }
+ }
view {
- <div class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--file-upload-progress {class}">
+ <div {...attrs} class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--file-upload-progress {class}" data-status="{currentStatus}" aria-live="polite">
<div class="wire-next__row">
- <span>{label}</span>{#if showValue}<strong>{value}%</strong>{/if}</div>
- <progress value="{value}" max="{max}">
+ <span>{#if fileName}<strong>{fileName}</strong>
+ <small>{#if uploadedSize || fileSize}{uploadedSize}{#if uploadedSize && fileSize} of {/if}{fileSize}{:else}{label}{/if}</small>{:else}<strong>{label}</strong>{/if}</span>{#if showValue}<strong>{percent()}%</strong>{/if}</div>
+ <progress value="{currentValue}" max="{max}" aria-label="{label}">
</progress>
+ <div class="wire-next__upload-status">
+ <span class="wire-next__upload-status-icon" aria-hidden="true">
+ </span>
+ <span>{#if currentStatus === "uploading"}Uploading securely…{:else if currentStatus === "complete"}Upload complete{:else if currentStatus === "error"}Upload failed{:else}Upload cancelled{/if}</span>
+ </div>
+ <div class="wire-next__upload-actions">{#if currentStatus === "uploading"}<button type="button" @click="cancelUpload(event)">{cancelLabel}</button>
+ <button type="button" @click="completeUpload(event)">Complete</button>{/if}{#if currentStatus === "error" || currentStatus === "cancelled"}<button type="button" @click="retryUpload(event)">{retryLabel}</button>{/if}</div>
</div>
}
}
-
+
}
diff --git a/app/pages/components/file-upload.wrn b/app/pages/components/file-upload.wrn
index ac536388..f2beccf2 100644
--- a/app/pages/components/file-upload.wrn
+++ b/app/pages/components/file-upload.wrn
@@ -10,17 +10,24 @@ page FileUploadcomponent {
W WRNexusJS
-
+
Browse documentation
- integrations componentFileUpload
Theme-aware, responsive file upload component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<FileUpload
+ integrations componentFileUpload
Theme-aware, responsive file upload component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<FileUpload
size="default"
color="primary"
title="File Upload"
description="description"
items="[]"
-/>
Legacy mount name: data-component="FileUpload".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"titlestringOptional "File Upload"descriptionstringOptional ""itemsstringOptional []variantstringOptional "default"classstringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/FileUpload.wrn
component FileUpload {
+/>
Legacy mount name: data-component="FileUpload".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"titlestringOptional "File Upload"descriptionstringOptional ""itemsstringOptional []variantstringOptional "default"classstringOptional ""
Slots
default
Events
selectuploadprogresssuccesserrorcancelremove
Source contract
Installed source: components/FileUpload.wrn
component FileUpload {
props {
+ @event select = function
+ @event upload = function
+ @event progress = function
+ @event success = function
+ @event error = function
+ @event cancel = function
+ @event remove = function
size = "default"
color = "primary"
title = "File Upload"
@@ -39,7 +46,7 @@ page FileUploadcomponent {
}
}
-
+
}
diff --git a/app/pages/components/grid.wrn b/app/pages/components/grid.wrn
index 1613a7e7..23f1289b 100644
--- a/app/pages/components/grid.wrn
+++ b/app/pages/components/grid.wrn
@@ -10,10 +10,10 @@ page Gridcomponent {
W WRNexusJS
-
+
Browse documentation
- layout componentGrid
Theme-aware, responsive grid component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Grid
+ layout componentGrid
Theme-aware, responsive grid component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Grid
size="default"
color="primary"
columns="2"
@@ -35,7 +35,7 @@ page Gridcomponent {
}
}
-
+
}
diff --git a/app/pages/components/image.wrn b/app/pages/components/image.wrn
index 1f2f2595..4208e1d6 100644
--- a/app/pages/components/image.wrn
+++ b/app/pages/components/image.wrn
@@ -10,17 +10,19 @@ page Imagecomponent {
W WRNexusJS
-
+
Browse documentation
- layout componentImage
Theme-aware, responsive image component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Image
+ layout componentImage
Theme-aware, responsive image component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Image
size="default"
color="primary"
src="src"
alt="alt"
width="width"
-/>
Legacy mount name: data-component="Image".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"srcstringOptional ""altstringOptional ""widthstringOptional ""heightstringOptional ""loadingstringOptional "lazy"roundedbooleanOptional falseclassstringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/Image.wrn
component Image {
+/>
Legacy mount name: data-component="Image".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"srcstringOptional ""altstringOptional ""widthstringOptional ""heightstringOptional ""loadingstringOptional "lazy"roundedbooleanOptional falseclassstringOptional ""
Slots
default
Events
loaderror
Source contract
Installed source: components/Image.wrn
component Image {
props {
+ @event load = function
+ @event error = function
size = "default"
color = "primary"
src = ""
@@ -39,7 +41,7 @@ page Imagecomponent {
}
}
-
+
}
diff --git a/app/pages/components/input-group.wrn b/app/pages/components/input-group.wrn
index b3ed520d..5aed88c6 100644
--- a/app/pages/components/input-group.wrn
+++ b/app/pages/components/input-group.wrn
@@ -10,40 +10,70 @@ page InputGroupcomponent {
W WRNexusJS
-
+
Browse documentation
- forms componentInputGroup
Theme-aware, responsive input group component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<InputGroup
+ forms componentInputGroup
Theme-aware, responsive input group component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<InputGroup
size="default"
color="primary"
- label="Input Group"
+ id="id"
name="name"
- value="value"
-/>
Legacy mount name: data-component="InputGroup".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"labelstringOptional "Input Group"namestringOptional ""valuestringOptional ""placeholderstringOptional ""typestringOptional "text"minstringOptional ""maxstringOptional ""stepstringOptional ""disabledbooleanOptional falserequiredbooleanOptional falseclassstringOptional ""
Slots
This component does not declare a slot.
Events
This component does not declare a custom event.
Source contract
Installed source: components/InputGroup.wrn
component InputGroup {
+ label="Input group"
+/>
Legacy mount name: data-component="InputGroup".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"idstringOptional ""namestringOptional ""labelstringOptional "Input group"hiddenLabelbooleanOptional falsevaluestringOptional ""placeholderstringOptional ""typestringOptional "text"startTextstringOptional ""endTextstringOptional ""iconstringOptional ""iconPositionstringOptional "start"actionLabelstringOptional ""helperTextstringOptional ""cornerHintstringOptional ""errorstringOptional ""inlinebooleanOptional falsevariantstringOptional "normal"readonlybooleanOptional falsedisabledbooleanOptional falserequiredbooleanOptional falseclassstringOptional ""
Slots
This component does not declare a slot.
Events
inputchangefocusblursubmitaction
Source contract
Installed source: components/InputGroup.wrn
component InputGroup {
props {
+ @event input = function
+ @event change = function
+ @event focus = function
+ @event blur = function
+ @event submit = function
+ @event action = function
size = "default"
color = "primary"
- label = "Input Group"
+ id = ""
name = ""
+ label = "Input group"
+ hiddenLabel = false
value = ""
placeholder = ""
type = "text"
- min = ""
- max = ""
- step = ""
+ startText = ""
+ endText = ""
+ icon = ""
+ iconPosition = "start"
+ actionLabel = ""
+ helperText = ""
+ cornerHint = ""
+ error = ""
+ inline = false
+ variant = "normal"
+ readonly = false
disabled = false
required = false
class = ""
}
+ functions {
+ function emitField(nameEvent, sourceEvent) { sourceEvent.stopPropagation(); $emit(nameEvent, { value: sourceEvent.currentTarget.value, name: name, sourceEvent: sourceEvent }) }
+ function handleKeydown(sourceEvent) { if (sourceEvent.key === "Enter") { sourceEvent.stopPropagation(); $emit("submit", { value: sourceEvent.currentTarget.value, name: name, sourceEvent: sourceEvent }) } }
+ function handleAction(sourceEvent) { $emit("action", { name: name, sourceEvent: sourceEvent }) }
+ }
view {
- <label class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--field wire-next--input-group {class}">
- <span>{label}</span>
- <input {...attrs} type="{type}" name="{name}" value="{value}" placeholder="{placeholder}" min="{min}" max="{max}" step="{step}" disabled="{disabled}" required="{required}" />
- </label>
+ <div {...attrs} class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--field wire-next--input-group {class}" data-variant="{variant}" data-inline="{inline}" data-invalid="{error ? 'true' : 'false'}">
+ <div class="wire-next__field-heading">
+ <label class="{hiddenLabel ? 'wire-next__sr-only' : ''}" for="{id || name}">{label}</label>{#if cornerHint}<span class="wire-next__field-hint">{cornerHint}</span>{/if}</div>
+ <div class="wire-next__input-group-control">
+ {#if startText}<span class="wire-next__input-addon">{startText}</span>{/if}
+ {#if icon}<span class="{icon} wire-next__field-icon" data-position="{iconPosition}" aria-hidden="true">
+ </span>{/if}
+ <input id="{id || name}" type="{type}" name="{name}" value="{value}" placeholder="{placeholder}" readonly="{readonly}" disabled="{disabled}" required="{required}" aria-invalid="{error ? 'true' : 'false'}" @input="emitField('input', event)" @change="emitField('change', event)" @focus="emitField('focus', event)" @blur="emitField('blur', event)" @keydown="handleKeydown(event)" />
+ {#if endText}<span class="wire-next__input-addon">{endText}</span>{/if}
+ {#if actionLabel}<button type="button" disabled="{disabled}" @click="handleAction(event)">{actionLabel}</button>{/if}
+ </div>
+ {#if helperText}<small class="wire-next__field-help">{helperText}</small>{/if}<small class="wire-next__field-error" data-error="{name}">{error}</small>
+ </div>
}
}
-
+
}
diff --git a/app/pages/components/input-number.wrn b/app/pages/components/input-number.wrn
index b5a87e69..201abb0f 100644
--- a/app/pages/components/input-number.wrn
+++ b/app/pages/components/input-number.wrn
@@ -10,10 +10,10 @@ page InputNumbercomponent {
W WRNexusJS
-
+
Browse documentation
- advanced-forms componentInputNumber
Theme-aware, responsive input number component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<InputNumber
+ advanced-forms componentInputNumber
Theme-aware, responsive input number component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<InputNumber
size="default"
color="primary"
variant="default"
@@ -647,7 +647,7 @@ page InputNumbercomponent {
}
}
-
+
}
diff --git a/app/pages/components/input.wrn b/app/pages/components/input.wrn
index 10bbfeb4..7a5bfb8d 100644
--- a/app/pages/components/input.wrn
+++ b/app/pages/components/input.wrn
@@ -10,40 +10,110 @@ page Inputcomponent {
W WRNexusJS
-
+
Browse documentation
- forms componentInput
Theme-aware, responsive input component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Input
+ forms componentInput
Theme-aware, responsive input component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Input
size="default"
color="primary"
- label="Input"
+ id="id"
name="name"
- value="value"
-/>
Legacy mount name: data-component="Input".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"labelstringOptional "Input"namestringOptional ""valuestringOptional ""placeholderstringOptional ""typestringOptional "text"minstringOptional ""maxstringOptional ""stepstringOptional ""disabledbooleanOptional falserequiredbooleanOptional falseclassstringOptional ""
Slots
This component does not declare a slot.
Events
This component does not declare a custom event.
Source contract
Installed source: components/input.wrn
component Input {
+ label="Input"
+/>
Legacy mount name: data-component="Input".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"idstringOptional ""namestringOptional ""labelstringOptional "Input"hiddenLabelbooleanOptional falseplaceholderstringOptional ""valuestringOptional ""typestringOptional "text"variantstringOptional "normal"iconstringOptional ""iconPositionstringOptional "start"helperTextstringOptional ""cornerHintstringOptional ""errorstringOptional ""inlinebooleanOptional falsereadonlybooleanOptional falsedisabledbooleanOptional falserequiredbooleanOptional falseautocompletestringOptional ""inputmodestringOptional ""minlengthstringOptional ""maxlengthstringOptional ""patternstringOptional ""minstringOptional ""maxstringOptional ""stepstringOptional ""classstringOptional ""
Slots
This component does not declare a slot.
Events
inputchangefocusblurinvalidkeydownkeyup
Source contract
Installed source: components/Input.wrn
component Input {
props {
+ @event input = function
+ @event change = function
+ @event focus = function
+ @event blur = function
+ @event invalid = function
+ @event keydown = function
+ @event keyup = function
size = "default"
color = "primary"
- label = "Input"
+ id = ""
name = ""
- value = ""
+ label = "Input"
+ hiddenLabel = false
placeholder = ""
+ value = ""
type = "text"
+ variant = "normal"
+ icon = ""
+ iconPosition = "start"
+ helperText = ""
+ cornerHint = ""
+ error = ""
+ inline = false
+ readonly = false
+ disabled = false
+ required = false
+ autocomplete = ""
+ inputmode = ""
+ minlength = ""
+ maxlength = ""
+ pattern = ""
min = ""
max = ""
step = ""
- disabled = false
- required = false
class = ""
}
+ functions {
+ function detail(sourceEvent) {
+ return { value: sourceEvent.currentTarget.value, name: name, sourceEvent: sourceEvent }
+ }
+ function handleInput(sourceEvent) { sourceEvent.stopPropagation(); $emit("input", detail(sourceEvent)) }
+ function handleChange(sourceEvent) { sourceEvent.stopPropagation(); $emit("change", detail(sourceEvent)) }
+ function handleFocus(sourceEvent) { sourceEvent.stopPropagation(); $emit("focus", detail(sourceEvent)) }
+ function handleBlur(sourceEvent) { sourceEvent.stopPropagation(); $emit("blur", detail(sourceEvent)) }
+ function handleInvalid(sourceEvent) { sourceEvent.stopPropagation(); $emit("invalid", { value: sourceEvent.currentTarget.value, name: name, message: sourceEvent.currentTarget.validationMessage, sourceEvent: sourceEvent }) }
+ function handleKeydown(sourceEvent) { sourceEvent.stopPropagation(); $emit("keydown", { key: sourceEvent.key, value: sourceEvent.currentTarget.value, name: name, sourceEvent: sourceEvent }) }
+ function handleKeyup(sourceEvent) { sourceEvent.stopPropagation(); $emit("keyup", { key: sourceEvent.key, value: sourceEvent.currentTarget.value, name: name, sourceEvent: sourceEvent }) }
+ }
view {
- <label class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--field wire-next--input {class}">
- <span>{label}</span>
- <input {...attrs} type="{type}" name="{name}" value="{value}" placeholder="{placeholder}" min="{min}" max="{max}" step="{step}" disabled="{disabled}" required="{required}" />
- </label>
+ <div {...attrs} class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--field wire-next--input {class}" data-variant="{variant}" data-inline="{inline}" data-floating="{variant === 'floating'}" data-invalid="{error ? 'true' : 'false'}">
+ <div class="wire-next__field-heading">
+ <label class="{hiddenLabel ? 'wire-next__sr-only' : ''}" for="{id || name}">{label}</label>
+ {#if cornerHint}<span class="wire-next__field-hint">{cornerHint}</span>{/if}
+ </div>
+ <div class="wire-next__field-control" data-icon-position="{iconPosition}">
+ {#if icon}<span class="{icon} wire-next__field-icon" aria-hidden="true">
+ </span>{/if}
+ <input
+ id="{id || name}"
+ type="{type}"
+ name="{name}"
+ value="{value}"
+ placeholder="{variant === 'floating' ? ' ' : placeholder}"
+ readonly="{readonly}"
+ disabled="{disabled}"
+ required="{required}"
+ autocomplete="{autocomplete}"
+ inputmode="{inputmode}"
+ minlength="{minlength}"
+ maxlength="{maxlength}"
+ pattern="{pattern}"
+ min="{min}"
+ max="{max}"
+ step="{step}"
+ aria-invalid="{error ? 'true' : 'false'}"
+ aria-describedby="{error ? (id || name) + '-error' : (helperText ? (id || name) + '-help' : '')}"
+ @input="handleInput(event)"
+ @change="handleChange(event)"
+ @focus="handleFocus(event)"
+ @blur="handleBlur(event)"
+ @invalid="handleInvalid(event)"
+ @keydown="handleKeydown(event)"
+ @keyup="handleKeyup(event)"
+ />
+ {#if variant === "floating"}<span class="wire-next__field-floating-label">{label}</span>{/if}
+ </div>
+ {#if helperText}<small id="{(id || name) + '-help'}" class="wire-next__field-help">{helperText}</small>{/if}
+ <small id="{(id || name) + '-error'}" class="wire-next__field-error" data-error="{name}">{error}</small>
+ </div>
}
}
-
+
}
diff --git a/app/pages/components/kbd.wrn b/app/pages/components/kbd.wrn
index ed78e796..237c0314 100644
--- a/app/pages/components/kbd.wrn
+++ b/app/pages/components/kbd.wrn
@@ -10,10 +10,10 @@ page Kbdcomponent {
W WRNexusJS
-
+
Browse documentation
- layout componentKbd
Theme-aware, responsive kbd component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Kbd
+ layout componentKbd
Theme-aware, responsive kbd component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Kbd
size="default"
color="primary"
label="⌘ K"
@@ -31,7 +31,7 @@ page Kbdcomponent {
}
}
-
+
}
diff --git a/app/pages/components/layout-splitter.wrn b/app/pages/components/layout-splitter.wrn
index 84e44469..b870ffe6 100644
--- a/app/pages/components/layout-splitter.wrn
+++ b/app/pages/components/layout-splitter.wrn
@@ -10,17 +10,20 @@ page LayoutSplittercomponent {
W WRNexusJS
-
+
Browse documentation
- layout componentLayoutSplitter
Theme-aware, responsive layout splitter component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<LayoutSplitter
+ layout componentLayoutSplitter
Theme-aware, responsive layout splitter component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<LayoutSplitter
size="default"
color="primary"
columns="2"
gap="md"
maxWidth="xl"
-/>
Legacy mount name: data-component="LayoutSplitter".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"columnsnumberOptional 2gapstringOptional "md"maxWidthstringOptional "xl"classstringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/LayoutSplitter.wrn
component LayoutSplitter {
+/>
Legacy mount name: data-component="LayoutSplitter".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"columnsnumberOptional 2gapstringOptional "md"maxWidthstringOptional "xl"classstringOptional ""
Slots
default
Events
resizeStartresizeresizeEnd
Source contract
Installed source: components/LayoutSplitter.wrn
component LayoutSplitter {
props {
+ @event resizeStart = function
+ @event resize = function
+ @event resizeEnd = function
size = "default"
color = "primary"
columns = 2
@@ -35,7 +38,7 @@ page LayoutSplittercomponent {
}
}
-
+
}
diff --git a/app/pages/components/legend-indicator.wrn b/app/pages/components/legend-indicator.wrn
index b0896c3e..8c1f5b48 100644
--- a/app/pages/components/legend-indicator.wrn
+++ b/app/pages/components/legend-indicator.wrn
@@ -10,17 +10,19 @@ page LegendIndicatorcomponent {
W WRNexusJS
-
+
Browse documentation
- base componentLegendIndicator
Theme-aware, responsive legend indicator component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<LegendIndicator
+ base componentLegendIndicator
Theme-aware, responsive legend indicator component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<LegendIndicator
size="default"
color="primary"
title="Legend Indicator"
description="description"
items="[]"
-/>
Legacy mount name: data-component="LegendIndicator".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"titlestringOptional "Legend Indicator"descriptionstringOptional ""itemsstringOptional []variantstringOptional "default"classstringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/LegendIndicator.wrn
component LegendIndicator {
+/>
Legacy mount name: data-component="LegendIndicator".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"titlestringOptional "Legend Indicator"descriptionstringOptional ""itemsstringOptional []variantstringOptional "default"classstringOptional ""
Slots
default
Events
toggleselect
Source contract
Installed source: components/LegendIndicator.wrn
component LegendIndicator {
props {
+ @event toggle = function
+ @event select = function
size = "default"
color = "primary"
title = "Legend Indicator"
@@ -39,7 +41,7 @@ page LegendIndicatorcomponent {
}
}
-
+
}
diff --git a/app/pages/components/link.wrn b/app/pages/components/link.wrn
index 9f775e18..68dc6ac4 100644
--- a/app/pages/components/link.wrn
+++ b/app/pages/components/link.wrn
@@ -10,17 +10,20 @@ page Linkcomponent {
W WRNexusJS
-
+
Browse documentation
- layout componentLink
Theme-aware, responsive link component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Link
+ layout componentLink
Theme-aware, responsive link component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Link
size="default"
color="primary"
label="Link"
href="#"
target="target"
-/>
Legacy mount name: data-component="Link".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"labelstringOptional "Link"hrefstringOptional "#"targetstringOptional ""relstringOptional ""externalbooleanOptional falseclassstringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/Link.wrn
component Link {
+/>
Legacy mount name: data-component="Link".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"labelstringOptional "Link"hrefstringOptional "#"targetstringOptional ""relstringOptional ""externalbooleanOptional falseclassstringOptional ""
Slots
default
Events
clickfocusblur
Source contract
Installed source: components/Link.wrn
component Link {
props {
+ @event click = function
+ @event focus = function
+ @event blur = function
size = "default"
color = "primary"
label = "Link"
@@ -36,7 +39,7 @@ page Linkcomponent {
}
}
-
+
}
diff --git a/app/pages/components/list-group.wrn b/app/pages/components/list-group.wrn
index 3a331344..19732d58 100644
--- a/app/pages/components/list-group.wrn
+++ b/app/pages/components/list-group.wrn
@@ -10,17 +10,19 @@ page ListGroupcomponent {
W WRNexusJS
-
+
Browse documentation
- base componentListGroup
Theme-aware, responsive list group component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<ListGroup
+ base componentListGroup
Theme-aware, responsive list group component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<ListGroup
size="default"
color="primary"
title="List Group"
description="description"
items="[]"
-/>
Legacy mount name: data-component="ListGroup".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"titlestringOptional "List Group"descriptionstringOptional ""itemsstringOptional []variantstringOptional "default"classstringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/ListGroup.wrn
component ListGroup {
+/>
Legacy mount name: data-component="ListGroup".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"titlestringOptional "List Group"descriptionstringOptional ""itemsstringOptional []variantstringOptional "default"classstringOptional ""
Slots
default
Events
selectchange
Source contract
Installed source: components/ListGroup.wrn
component ListGroup {
props {
+ @event select = function
+ @event change = function
size = "default"
color = "primary"
title = "List Group"
@@ -39,7 +41,7 @@ page ListGroupcomponent {
}
}
-
+
}
diff --git a/app/pages/components/list.wrn b/app/pages/components/list.wrn
index 1c9eb3e5..49ec1dd4 100644
--- a/app/pages/components/list.wrn
+++ b/app/pages/components/list.wrn
@@ -10,17 +10,19 @@ page Listcomponent {
W WRNexusJS
-
+
Browse documentation
- base componentList
Theme-aware, responsive list component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<List
+ base componentList
Theme-aware, responsive list component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<List
size="default"
color="primary"
title="List"
description="description"
items="[]"
-/>
Legacy mount name: data-component="List".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"titlestringOptional "List"descriptionstringOptional ""itemsstringOptional []variantstringOptional "default"classstringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/List.wrn
component List {
+/>
Legacy mount name: data-component="List".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"titlestringOptional "List"descriptionstringOptional ""itemsstringOptional []variantstringOptional "default"classstringOptional ""
Slots
default
Events
selectclick
Source contract
Installed source: components/List.wrn
component List {
props {
+ @event select = function
+ @event click = function
size = "default"
color = "primary"
title = "List"
@@ -39,7 +41,7 @@ page Listcomponent {
}
}
-
+
}
diff --git a/app/pages/components/map.wrn b/app/pages/components/map.wrn
index 6521bc10..1d722967 100644
--- a/app/pages/components/map.wrn
+++ b/app/pages/components/map.wrn
@@ -10,17 +10,21 @@ page Mapcomponent {
W WRNexusJS
-
+
Browse documentation
- integrations componentMap
Theme-aware, responsive map component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Map
+ integrations componentMap
Theme-aware, responsive map component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Map
size="default"
color="primary"
title="Map"
description="description"
items="[]"
-/>
Legacy mount name: data-component="Map".
Props and attributes