Accordion
Reusable accordion component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Accordion
- title="Question"
- open="false"
-/>Legacy mount name: data-component="Accordion".
Props and attributes
| Prop | Type | Requirement | Default |
|---|---|---|---|
class | string | Optional | "" |
title | string | Optional | "Question" |
open | boolean | Optional | false |
Slots
default
Events
click
Source contract
Installed source: components/Accordion.wrn
component Accordion {
- props {
- class = ""
- title = "Question"
- open = false
- }
-
- state expanded = open
-
- view {
- <div class="border-b border-slate-200 dark:border-slate-800 {class}" >
- <button
- type="button"
- class="flex w-full items-center justify-between gap-4 py-5 text-left font-semibold"
- aria-expanded="{expanded}"
- @click="expanded = !expanded"
- >
- <span >
- {title}
- </span>
- <span class="text-xl transition-transform {expanded ? 'rotate-45' : ''}">+</span>
- </button>
- <div
- data-show="expanded"
- class="pb-5 text-slate-600 dark:text-slate-300"
- >
- <slot />
- </div>
+ 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"
+ 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 {
+ props {
+ size = "default"
+ color = "primary"
+ items = []
+ multiple = false
+ class = ""
+ }
+ 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>
}
}
-
+
}
diff --git a/app/pages/components/advanced-date-picker.wrn b/app/pages/components/advanced-date-picker.wrn
new file mode 100644
index 00000000..38119e14
--- /dev/null
+++ b/app/pages/components/advanced-date-picker.wrn
@@ -0,0 +1,46 @@
+page AdvancedDatePickercomponent {
+ seo {
+ title = "AdvancedDatePicker component"
+ description = "Theme-aware, responsive advanced date picker component."
+ }
+
+ view {
+
+
+
+ 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
+ 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 {
+ props {
+ size = "default"
+ color = "primary"
+ title = "Advanced Date Picker"
+ description = ""
+ items = []
+ variant = "default"
+ class = ""
+ }
+ view {
+ <section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--advanced-date-picker 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>
+ }
+}
+
+
+
+
+ }
+}
diff --git a/app/pages/components/advanced-range-slider.wrn b/app/pages/components/advanced-range-slider.wrn
new file mode 100644
index 00000000..f1807831
--- /dev/null
+++ b/app/pages/components/advanced-range-slider.wrn
@@ -0,0 +1,46 @@
+page AdvancedRangeSlidercomponent {
+ seo {
+ title = "AdvancedRangeSlider component"
+ description = "Theme-aware, responsive advanced range slider component."
+ }
+
+ view {
+
+
+
+ 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
+ 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 {
+ props {
+ size = "default"
+ color = "primary"
+ title = "Advanced Range Slider"
+ description = ""
+ items = []
+ variant = "default"
+ class = ""
+ }
+ view {
+ <section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--advanced-range-slider 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>
+ }
+}
+
+
+
+
+ }
+}
diff --git a/app/pages/components/advanced-select.wrn b/app/pages/components/advanced-select.wrn
new file mode 100644
index 00000000..c7311c9b
--- /dev/null
+++ b/app/pages/components/advanced-select.wrn
@@ -0,0 +1,493 @@
+page AdvancedSelectcomponent {
+ seo {
+ title = "AdvancedSelect component"
+ description = "Theme-aware, responsive advanced select component."
+ }
+
+ view {
+
+
+
+ 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
+ size="default"
+ color="primary"
+ label="Advanced Select"
+ name="name"
+ value="value"
+/>
Legacy mount name: data-component="AdvancedSelect".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"labelstringOptional "Advanced Select"namestringOptional ""valuestringOptional ""valuesstringOptional []optionsstringOptional []groupsstringOptional []placeholderstringOptional "Select an option"placeholderIconstringOptional ""searchPlaceholderstringOptional "Search options…"multiplebooleanOptional falsesearchablebooleanOptional truedefaultOpenbooleanOptional falseclearablebooleanOptional trueallowEmptybooleanOptional truetagsbooleanOptional falsedisabledbooleanOptional falserequiredbooleanOptional falseinvalidbooleanOptional falsevalidationMessagestringOptional ""helpTextstringOptional ""loadingbooleanOptional falseloadingLabelstringOptional "Loading options…"emptyLabelstringOptional "No options found"selectedOptionsLabelstringOptional "Selected options"clearLabelstringOptional "Clear selection"createLabelstringOptional "Create"loadMoreLabelstringOptional "Load more"searchModestringOptional "contains"searchFieldsstringOptional "label,description"minSearchLengthnumberOptional 0searchResultLimitnumberOptional 0maxSelectionsnumberOptional 0showCounterbooleanOptional falsecounterTemplatestringOptional "{selected} selected"optionTemplatestringOptional "default"selectedTemplatestringOptional "default"closeOnSelectbooleanOptional truescrollToSelectedbooleanOptional truefixedbooleanOptional falseplacementstringOptional "bottom"remotebooleanOptional falseremoteUrlstringOptional ""remoteQueryParamstringOptional "q"remoteDebouncenumberOptional 250remoteAutoLoadbooleanOptional trueinfinitebooleanOptional falsehasMorebooleanOptional falsepagenumberOptional 1classstringOptional ""
Slots
This component does not declare a slot.
Events
searchselectchangeclearopencloseloaderror
Source contract
Installed source: components/AdvancedSelect.wrn
component AdvancedSelect {
+ props {
+ size = "default"
+ color = "primary"
+ label = "Advanced Select"
+ name = ""
+ value = ""
+ values = []
+ options = []
+ groups = []
+ placeholder = "Select an option"
+ placeholderIcon = ""
+ searchPlaceholder = "Search options…"
+ multiple = false
+ searchable = true
+ defaultOpen = false
+ clearable = true
+ allowEmpty = true
+ tags = false
+ disabled = false
+ required = false
+ invalid = false
+ validationMessage = ""
+ helpText = ""
+ loading = false
+ loadingLabel = "Loading options…"
+ emptyLabel = "No options found"
+ selectedOptionsLabel = "Selected options"
+ clearLabel = "Clear selection"
+ createLabel = "Create"
+ loadMoreLabel = "Load more"
+ searchMode = "contains"
+ searchFields = "label,description"
+ minSearchLength = 0
+ searchResultLimit = 0
+ maxSelections = 0
+ showCounter = false
+ counterTemplate = "{selected} selected"
+ optionTemplate = "default"
+ selectedTemplate = "default"
+ closeOnSelect = true
+ scrollToSelected = true
+ fixed = false
+ placement = "bottom"
+ remote = false
+ remoteUrl = ""
+ remoteQueryParam = "q"
+ remoteDebounce = 250
+ remoteAutoLoad = true
+ infinite = false
+ hasMore = false
+ page = 1
+ class = ""
+ @event search = function
+ @event select = function
+ @event change = function
+ @event clear = function
+ @event open = function
+ @event close = function
+ @event load = function
+ @event error = function
+ }
+
+ state open = defaultOpen
+ state query = ""
+ state activeIndex = -1
+ state selectedValue = value
+ state selectedValues = values
+
+ functions {
+ function allOptions() {
+ return [...groups.flatMap((group) => group.options || []), ...options]
+ }
+
+ function searchableText(option) {
+ return ((option.label || "") + " " + (option.description || "")).toLowerCase()
+ }
+
+ function matches(option) {
+ if (!query || query.length < Number(minSearchLength || 0)) {
+ return true
+ }
+ if (searchMode === "startsWith") {
+ return searchableText(option).startsWith(query.toLowerCase())
+ }
+ if (searchMode === "exact") {
+ return searchableText(option) === query.toLowerCase()
+ }
+ return searchableText(option).includes(query.toLowerCase())
+ }
+
+ function matchingOptions(list) {
+ return list.filter((option) => matches(option))
+ }
+
+ function visibleOptions(list) {
+ if (searchResultLimit > 0) {
+ return matchingOptions(list).slice(0, Number(searchResultLimit))
+ }
+ return matchingOptions(list)
+ }
+
+ function flatVisibleOptions() {
+ return visibleOptions(allOptions())
+ }
+
+ function isSelected(option) {
+ return (
+ multiple
+ ? selectedValues.includes(option.value)
+ : selectedValue === option.value
+ )
+ }
+
+ function selectedOptions() {
+ return allOptions().filter((option) => isSelected(option))
+ }
+
+ function selectedCount() {
+ return multiple ? selectedValues.length : selectedValue ? 1 : 0
+ }
+
+ function counterText() {
+ return (
+ maxSelections
+ ? selectedCount() + " / " + maxSelections + " selected"
+ : selectedCount() + " selected"
+ )
+ }
+
+ function selectedText() {
+ return (
+ multiple
+ ? selectedValues.join(", ")
+ : selectedOptions().length
+ ? selectedOptions()[0].label
+ : ""
+ )
+ }
+
+ function triggerText() {
+ return selectedCount() ? selectedText() : placeholder
+ }
+
+ function canSelect(option) {
+ if (option.disabled) {
+ return false
+ }
+ if (!multiple || isSelected(option)) {
+ return true
+ }
+ if (maxSelections <= 0) {
+ return true
+ }
+ return selectedCount() < maxSelections
+ }
+
+ function chooseSingle(option) {
+ if (!canSelect(option)) {
+ return
+ }
+ selectedValue = option.value
+ query = ""
+ if (closeOnSelect) {
+ open = false
+ }
+ }
+
+ function chooseMultiple(option) {
+ if (!canSelect(option)) {
+ return
+ }
+ if (isSelected(option)) {
+ selectedValues = selectedValues.filter((item) => item !== option.value)
+ } else {
+ selectedValues = selectedValues.concat([option.value])
+ }
+ query = ""
+ }
+
+ function chooseOption(option) {
+ if (multiple) {
+ chooseMultiple(option)
+ return
+ }
+ chooseSingle(option)
+ }
+
+ function clearSelection(event) {
+ event.stopPropagation()
+ selectedValue = ""
+ selectedValues = []
+ query = ""
+ open = false
+ }
+
+ function toggle() {
+ if (disabled) {
+ return;
+ };
+ open = !open;
+ activeIndex = open && flatVisibleOptions().length ? 0 : -1;
+ }
+
+ function moveActive(direction) {
+ if (!flatVisibleOptions().length) {
+ return
+ }
+ activeIndex = (activeIndex + direction + flatVisibleOptions().length) % flatVisibleOptions().length
+ }
+
+ function handleKeydown(event) {
+ if (disabled) {
+ return
+ }
+ if (event.key === "ArrowDown") {
+ event.preventDefault()
+ if (!open) {
+ open = true
+ }
+ moveActive(1)
+ } else if (event.key === "ArrowUp") {
+ event.preventDefault()
+ if (!open) {
+ open = true
+ }
+ moveActive(-1)
+ } else if (event.key === "Enter" || event.key === " ") {
+ event.preventDefault()
+ if (!open) {
+ open = true
+ } else if (activeIndex >= 0) {
+ chooseOption(flatVisibleOptions()[activeIndex])
+ }
+ } else if (event.key === "Escape") {
+ open = false
+ } else if (event.key === "Home" && open) {
+ event.preventDefault()
+ activeIndex = 0
+ } else if (event.key === "End" && open) {
+ event.preventDefault()
+ activeIndex = flatVisibleOptions().length - 1
+ }
+ }
+
+ function optionIndex(option) {
+ return flatVisibleOptions().findIndex((item) => item.value === option.value)
+ }
+ }
+
+ view {
+ <div
+ class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--advanced-select {open ? 'wire-next--open' : ''} {fixed ? 'wire-next--advanced-select-fixed' : ''} {invalid ? 'wire-next--invalid' : ''} {disabled ? 'wire-next--disabled' : ''} {class}"
+ data-placement="{placement}"
+ data-search-mode="{searchMode}"
+ data-remote="{remote ? 'true' : 'false'}"
+ data-remote-url="{remoteUrl}"
+ data-remote-query-param="{remoteQueryParam}"
+ data-remote-debounce="{remoteDebounce}"
+ data-remote-auto-load="{remoteAutoLoad ? 'true' : 'false'}"
+ data-infinite="{infinite ? 'true' : 'false'}"
+ data-page="{page}"
+ data-wrn-select
+ @focusout="if (!event.currentTarget.contains(event.relatedTarget)) { open = false }"
+ >
+ <div class="wire-next__row">
+ <label id="{name}-label" for="{name}-trigger">{label}</label>
+ <small data-show="showCounter" data-text="counterText()">{counterText()}</small>
+ </div>
+ <div class="wire-next__select-control">
+ <button
+ {...attrs}
+ id="{name}-trigger"
+ type="button"
+ class="wire-next__select-trigger"
+ role="combobox"
+ aria-haspopup="listbox"
+ aria-expanded="{open}"
+ aria-controls="{name}-listbox"
+ aria-labelledby="{name}-label"
+ aria-invalid="{invalid}"
+ disabled="{disabled}"
+ @click="toggle()"
+ @keydown="handleKeydown(event)"
+ >
+ <span class="wire-next__select-value">
+ <span data-show="!multiple" data-text="triggerText()">{triggerText()}</span>
+ <span
+ data-show="multiple && selectedTemplate === 'count' && selectedCount() > 0"
+ data-text="selectedCount() + ' selected'"
+ >{selectedCount()} selected</span>
+ <span
+ data-show="multiple && selectedTemplate === 'text' && selectedCount() > 0"
+ data-text="selectedText()"
+ >{selectedText()}</span>
+ <span
+ class="wire-next__select-tags"
+ aria-label="{selectedOptionsLabel}"
+ data-show="multiple && selectedTemplate !== 'count' && selectedTemplate !== 'text' && selectedCount() > 0"
+ >
+ {#each allOptions() as option}
+ <span data-show="isSelected(option)">
+ {#if optionTemplate === "icon" && option.icon}<i class="{option.icon}" aria-hidden="true">
+ </i>{/if}
+ {#if optionTemplate === "avatar" && option.avatar}<img src="{option.avatar}" alt="" />{/if}
+ {#if optionTemplate === "color" && option.color}<i class="wire-next__color-dot" style="--option-color: {option.color}">
+ </i>{/if}
+ {option.label}
+ </span>
+ {/each}
+ </span>
+ <span data-show="multiple && selectedCount() === 0">
+ {#if placeholderIcon}<i class="{placeholderIcon}" aria-hidden="true">
+ </i>{/if}
+ <span class="wire-next__placeholder">{placeholder}</span>
+ </span>
+ </span>
+ <span
+ class="wire-next__select-chevron icon-[lucide--chevrons-up-down]"
+ aria-hidden="true"
+ >
+ </span>
+ </button>
+ <button
+ type="button"
+ class="wire-next__clear-select"
+ data-show="clearable && allowEmpty && selectedCount() > 0 && !disabled"
+ aria-label="{clearLabel}"
+ title="{clearLabel}"
+ @click="clearSelection(event)"
+ >
+ <span class="icon-[lucide--x]" aria-hidden="true">
+ </span>
+ </button>
+ </div>
+ <div
+ class="wire-next__select-dropdown {fixed ? 'wire-next__select-dropdown--fixed' : ''}"
+ data-show="open"
+ style="{open ? '' : 'display: none'}"
+ >
+ {#if searchable}
+ <label class="wire-next__select-search">
+ <span class="wire-visually-hidden">{searchPlaceholder}</span>
+ <span class="wire-next__search-icon" aria-hidden="true">⌕</span>
+ <input
+ type="search"
+ value="{query}"
+ placeholder="{searchPlaceholder}"
+ autocomplete="off"
+ @input="query = event.target.value; activeIndex = flatVisibleOptions().length ? 0 : -1"
+ @keydown="handleKeydown(event)"
+ />
+ </label>
+ {/if}
+
+ <div
+ class="wire-next__select-message"
+ data-show="remote && query.length !== 0 && query.length < minSearchLength"
+ >Enter at least {minSearchLength} characters.</div>
+ <div class="wire-next__select-message" data-show="loading" role="status">
+ <i class="wire-spinner wire-spinner--inline" aria-hidden="true">
+ </i>
+ {loadingLabel}
+ </div>
+ <div
+ id="{name}-listbox"
+ class="wire-next__select-list"
+ data-show="(!remote || (query.length === 0 && remoteAutoLoad) || query.length >= minSearchLength) && !loading"
+ role="listbox"
+ aria-multiselectable="{multiple}"
+ >
+ {#each groups as group}
+ {#if visibleOptions(group.options || []).length}
+ <div class="wire-next__option-group" role="group" aria-label="{group.label}">
+ <div class="wire-next__group-label">{group.label}</div>
+ {#each group.options || [] as option}
+ <button
+ type="button"
+ class="wire-next__select-option {isSelected(option) ? 'wire-next__select-option--selected' : ''} {optionIndex(option) === activeIndex ? 'wire-next__select-option--active' : ''}"
+ data-option-value="{option.value}"
+ data-show="matches(option)"
+ role="option"
+ aria-selected="{isSelected(option)}"
+ disabled="{!canSelect(option)}"
+ @mouseenter="activeIndex = optionIndex(option)"
+ @click="chooseOption(option)"
+ >
+ {#if optionTemplate === "icon" && option.icon}<i class="{option.icon}" aria-hidden="true">
+ </i>{/if}
+ {#if optionTemplate === "avatar" && option.avatar}<img src="{option.avatar}" alt="" />{/if}
+ {#if optionTemplate === "color" && option.color}<i class="wire-next__color-dot" style="--option-color: {option.color}">
+ </i>{/if}
+ <span>
+ <strong>{option.label}</strong>{#if option.description}<small>{option.description}</small>{/if}</span>
+ <i
+ class="wire-next__check icon-[lucide--check]"
+ data-show="isSelected(option)"
+ aria-hidden="true"
+ >
+ </i>
+ </button>
+ {/each}
+ </div>
+ {/if}
+ {/each}
+
+ {#each options as option}
+ <button
+ type="button"
+ class="wire-next__select-option {isSelected(option) ? 'wire-next__select-option--selected' : ''} {optionIndex(option) === activeIndex ? 'wire-next__select-option--active' : ''}"
+ data-option-value="{option.value}"
+ data-show="matches(option)"
+ role="option"
+ aria-selected="{isSelected(option)}"
+ disabled="{!canSelect(option)}"
+ @mouseenter="activeIndex = optionIndex(option)"
+ @click="chooseOption(option)"
+ >
+ {#if optionTemplate === "icon" && option.icon}<i class="{option.icon}" aria-hidden="true">
+ </i>{/if}
+ {#if optionTemplate === "avatar" && option.avatar}<img src="{option.avatar}" alt="" />{/if}
+ {#if optionTemplate === "color" && option.color}<i class="wire-next__color-dot" style="--option-color: {option.color}">
+ </i>{/if}
+ <span>
+ <strong>{option.label}</strong>{#if option.description}<small>{option.description}</small>{/if}</span>
+ <i
+ class="wire-next__check icon-[lucide--check]"
+ data-show="isSelected(option)"
+ aria-hidden="true"
+ >
+ </i>
+ </button>
+ {/each}
+
+ {#if !loading && !flatVisibleOptions().length}
+ <div class="wire-next__select-message">{emptyLabel}</div>
+ {/if}
+ </div>
+
+ {#if tags && query && !allOptions().some((option) => option.label.toLowerCase() === query.toLowerCase())}
+ <button type="button" class="wire-next__create-option">{createLabel} “{query}”</button>
+ {/if}
+ <button
+ type="button"
+ class="wire-next__load-more"
+ data-wrn-select-load-more
+ data-show="infinite && hasMore"
+ >{loadMoreLabel}</button>
+ </div>
+ <input
+ type="hidden"
+ name="{name}"
+ value="{multiple ? selectedValues.join(',') : selectedValue}"
+ required="{required}"
+ aria-describedby="{validationMessage ? `${name}-validation` : helpText ? `${name}-help` : ''}"
+ />
+
+ {#if helpText && !validationMessage}<small id="{name}-help">{helpText}</small>{/if}
+ <small
+ id="{name}-validation"
+ class="wire-next__validation"
+ data-error="{name}"
+ >{validationMessage}</small>
+ </div>
+ }
+}
+
+
+
+
+ }
+}
diff --git a/app/pages/components/alert.wrn b/app/pages/components/alert.wrn
index c03a409c..b97a11b0 100644
--- a/app/pages/components/alert.wrn
+++ b/app/pages/components/alert.wrn
@@ -1,7 +1,7 @@
-page alertcomponent {
+page Alertcomponent {
seo {
- title = "alert component"
- description = "Reusable alert component."
+ title = "Alert component"
+ description = "Theme-aware, responsive alert component."
}
view {
@@ -10,44 +10,36 @@ page alertcomponent {
W WRNexusJS
-
+
Browse documentation
- core componentalert
Reusable alert component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<alert
- title="Notice"
+ 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"
- variant="info"
- dismissible="false"
-/>
Legacy mount name: data-component="alert".
Props and attributes
Prop Type Requirement Default classstringOptional ""titlestringOptional "Notice"descriptionstringOptional ""variantstringOptional "info"dismissiblebooleanOptional false
Slots
default
Events
click
Source contract
Installed source: components/alert.wrn
component Alert {
+ 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 {
props {
- class = ""
- title = "Notice"
+ size = "default"
+ color = "primary"
+ title = "Alert"
description = ""
- variant = "info"
- dismissible = false
+ items = []
+ variant = "default"
+ class = ""
}
-
- state visible = true
-
view {
- <aside data-show="visible" role="alert" class="wire-alert wire-alert--{variant} wire-alert--rich {class}">
- <span class="wire-alert__icon" aria-hidden="true">
- <svg viewBox="0 0 24 24">
- <path d="M12 3 4.5 6v5.4c0 4.6 3.2 8.8 7.5 9.6 4.3-.8 7.5-5 7.5-9.6V6L12 3Z" />
- <path d="m9 12 2 2 4-4" />
- </svg>
- </span>
- <div class="wire-alert__content">
- {#if title}<h3 class="wire-alert__title">{title}</h3>{/if}
- {#if description}<p class="wire-alert__body">{description}</p>{/if}
- <slot />
- </div>
- {#if dismissible}<button type="button" aria-label="Dismiss" @click="visible = false" class="wire-alert__dismiss">×</button>{/if}
- </aside>
+ <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>
}
}
-
+
}
diff --git a/app/pages/components/avatar-group.wrn b/app/pages/components/avatar-group.wrn
index 17d0a8cb..d2d05e2f 100644
--- a/app/pages/components/avatar-group.wrn
+++ b/app/pages/components/avatar-group.wrn
@@ -1,7 +1,7 @@
page AvatarGroupcomponent {
seo {
title = "AvatarGroup component"
- description = "Reusable avatar group component."
+ description = "Theme-aware, responsive avatar group component."
}
view {
@@ -10,42 +10,36 @@ page AvatarGroupcomponent {
W WRNexusJS
-
+
Browse documentation
- forms componentAvatarGroup
Reusable avatar group component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<AvatarGroup
- label="Avatar"
- name="name"
- value="value"
- placeholder="placeholder"
- type="text"
-/>
Legacy mount name: data-component="AvatarGroup".
Props and attributes
Prop Type Requirement Default labelstringOptional "Avatar"namestringOptional ""valuestringOptional ""placeholderstringOptional ""typestringOptional "text"requiredbooleanOptional falsedisabledbooleanOptional falsereadonlybooleanOptional falsehelpstringOptional ""errorstringOptional ""classstringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/AvatarGroup.wrn
component AvatarGroup {
+ 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"
+ 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 {
props {
- label = "Avatar"
- name = ""
- value = ""
- placeholder = ""
- type = "text"
- required = false
- disabled = false
- readonly = false
- help = ""
- error = ""
+ size = "default"
+ color = "primary"
+ title = "Avatar Group"
+ description = ""
+ items = []
+ variant = "default"
class = ""
}
view {
- <label class="wire-field wire-catalog-field {class}">
- <span class="wire-label">{label}<span data-show="required" class="wire-required"> *</span>
- </span>
- <input name="{name}" value="{value}" placeholder="{placeholder}" type="{type}" required="{required}" disabled="{disabled}" readonly="{readonly}" aria-invalid="{error ? 'true' : 'false'}" class="wire-input" />
- <span data-show="help && !error" class="wire-field-message wire-field-message--help">{help}</span>
- <span data-show="error" role="alert" class="wire-field-message wire-field-message--error">{error}</span>
- <slot />
- </label>
+ <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>
}
}
-
+
}
diff --git a/app/pages/components/avatar.wrn b/app/pages/components/avatar.wrn
index 4014ca86..5bc5455d 100644
--- a/app/pages/components/avatar.wrn
+++ b/app/pages/components/avatar.wrn
@@ -1,7 +1,7 @@
page Avatarcomponent {
seo {
title = "Avatar component"
- description = "Reusable avatar component."
+ description = "Theme-aware, responsive avatar component."
}
view {
@@ -10,31 +10,36 @@ page Avatarcomponent {
W WRNexusJS
-
+
Browse documentation
- content componentAvatar
Reusable avatar component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Avatar
- src="src"
- alt="alt"
- initials="WR"
- size="md"
-/>
Legacy mount name: data-component="Avatar".
Props and attributes
Prop Type Requirement Default classstringOptional ""srcstringOptional ""altstringOptional ""initialsstringOptional "WR"sizestringOptional "md"
Slots
This component does not declare a slot.
Events
This component does not declare a custom event.
Source contract
Installed source: components/Avatar.wrn
component Avatar {
+ base componentAvatar
Theme-aware, responsive avatar component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Avatar
+ size="default"
+ 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 {
props {
+ size = "default"
+ color = "primary"
+ title = "Avatar"
+ description = ""
+ items = []
+ variant = "default"
class = ""
- src = ""
- alt = ""
- initials = "WR"
- size = "md"
}
view {
- <span class="inline-flex shrink-0 items-center justify-center overflow-hidden rounded-full bg-gradient-to-br from-violet-500 to-fuchsia-500 font-semibold text-white {size === 'sm' ? 'size-8 text-xs' : size === 'lg' ? 'size-14 text-base' : 'size-10 text-sm'} {class}">
- <img data-show="src" src="{src}" alt="{alt}" class="h-full w-full object-cover" />
- <span data-show="!src" aria-hidden="true">{initials}</span>
- </span>
+ <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>
}
}
-
+
}
diff --git a/app/pages/components/badge.wrn b/app/pages/components/badge.wrn
index a391ff85..60fae5ab 100644
--- a/app/pages/components/badge.wrn
+++ b/app/pages/components/badge.wrn
@@ -1,7 +1,7 @@
page Badgecomponent {
seo {
title = "Badge component"
- description = "Reusable badge component."
+ description = "Theme-aware, responsive badge component."
}
view {
@@ -10,46 +10,36 @@ page Badgecomponent {
W WRNexusJS
-
+
Browse documentation
- feedback componentBadge
Reusable badge component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Badge
- label="label"
- variant="neutral"
- size="md"
-/>
Legacy mount name: data-component="Badge".
Props and attributes
Prop Type Requirement Default classstringOptional ""labelstringOptional ""variantstringOptional "neutral"sizestringOptional "md"
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/Badge.wrn
component Badge {
+ base componentBadge
Theme-aware, responsive badge component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Badge
+ size="default"
+ 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 {
props {
+ size = "default"
+ color = "primary"
+ title = "Badge"
+ description = ""
+ items = []
+ variant = "default"
class = ""
- label = ""
- variant = "neutral"
- size = "md"
}
-
view {
- <span class="wire-badge wire-badge--{variant} wire-badge--{size} {class}">
- {#if variant === "success"}
- <span class="size-1.5 rounded-full bg-[var(--wire-color-success)]" aria-hidden="true">
- </span>
- {/if}
- {#if variant === "warning"}
- <span class="size-1.5 rounded-full bg-[var(--wire-color-warning)]" aria-hidden="true">
- </span>
- {/if}
- {#if variant === "danger"}
- <span class="size-1.5 rounded-full bg-[var(--wire-color-danger)]" aria-hidden="true">
- </span>
- {/if}
- {#if variant === "brand"}
- <span class="size-1.5 rounded-full bg-[var(--wire-color-primary)]" aria-hidden="true">
- </span>
- {/if}
- <span>{label}</span>
- <slot />
- </span>
+ <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>
}
}
-
+
}
diff --git a/app/pages/components/blockquote.wrn b/app/pages/components/blockquote.wrn
new file mode 100644
index 00000000..c3708996
--- /dev/null
+++ b/app/pages/components/blockquote.wrn
@@ -0,0 +1,46 @@
+page Blockquotecomponent {
+ seo {
+ title = "Blockquote component"
+ description = "Theme-aware, responsive blockquote component."
+ }
+
+ view {
+
+
+
+ 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 {
+ props {
+ size = "default"
+ color = "primary"
+ title = "Blockquote"
+ description = ""
+ items = []
+ variant = "default"
+ 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>
+ }
+}
+
+
+
+
+ }
+}
diff --git a/app/pages/components/breadcrumb.wrn b/app/pages/components/breadcrumb.wrn
new file mode 100644
index 00000000..04be1b8b
--- /dev/null
+++ b/app/pages/components/breadcrumb.wrn
@@ -0,0 +1,44 @@
+page Breadcrumbcomponent {
+ seo {
+ title = "Breadcrumb component"
+ description = "Theme-aware, responsive breadcrumb component."
+ }
+
+ view {
+
+
+
+ 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
+ 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 {
+ props {
+ size = "default"
+ color = "primary"
+ label = "Breadcrumb"
+ items = []
+ active = ""
+ orientation = "horizontal"
+ class = ""
+ }
+ view {
+ <nav class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--breadcrumb wire-next--{orientation} {class}" aria-label="{label}">
+ {#each items as item}<a href="{item.href}" aria-current="{item.value === active ? 'page' : ''}">{item.label}</a>{/each}
+ <slot />
+ </nav>
+ }
+}
+
+
+
+
+ }
+}
diff --git a/app/pages/components/button-group.wrn b/app/pages/components/button-group.wrn
index 1a2f0b02..e8010bdc 100644
--- a/app/pages/components/button-group.wrn
+++ b/app/pages/components/button-group.wrn
@@ -1,7 +1,7 @@
page ButtonGroupcomponent {
seo {
title = "ButtonGroup component"
- description = "Reusable button group component."
+ description = "Theme-aware, responsive button group component."
}
view {
@@ -10,42 +10,36 @@ page ButtonGroupcomponent {
W WRNexusJS
-
+
Browse documentation
- forms componentButtonGroup
Reusable button group component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<ButtonGroup
- label="Button"
- name="name"
- value="value"
- placeholder="placeholder"
- type="text"
-/>
Legacy mount name: data-component="ButtonGroup".
Props and attributes
Prop Type Requirement Default labelstringOptional "Button"namestringOptional ""valuestringOptional ""placeholderstringOptional ""typestringOptional "text"requiredbooleanOptional falsedisabledbooleanOptional falsereadonlybooleanOptional falsehelpstringOptional ""errorstringOptional ""classstringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/ButtonGroup.wrn
component ButtonGroup {
+ 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"
+ 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 {
props {
- label = "Button"
- name = ""
- value = ""
- placeholder = ""
- type = "text"
- required = false
- disabled = false
- readonly = false
- help = ""
- error = ""
+ size = "default"
+ color = "primary"
+ title = "Button Group"
+ description = ""
+ items = []
+ variant = "default"
class = ""
}
view {
- <label class="wire-field wire-catalog-field {class}">
- <span class="wire-label">{label}<span data-show="required" class="wire-required"> *</span>
- </span>
- <input name="{name}" value="{value}" placeholder="{placeholder}" type="{type}" required="{required}" disabled="{disabled}" readonly="{readonly}" aria-invalid="{error ? 'true' : 'false'}" class="wire-input" />
- <span data-show="help && !error" class="wire-field-message wire-field-message--help">{help}</span>
- <span data-show="error" role="alert" class="wire-field-message wire-field-message--error">{error}</span>
- <slot />
- </label>
+ <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}
+ <slot />
+ </section>
}
}
-
+
}
diff --git a/app/pages/components/button.wrn b/app/pages/components/button.wrn
index 6acbe66b..54e303ce 100644
--- a/app/pages/components/button.wrn
+++ b/app/pages/components/button.wrn
@@ -1,7 +1,7 @@
page Buttoncomponent {
seo {
title = "Button component"
- description = "Reusable button component."
+ description = "Theme-aware, responsive button component."
}
view {
@@ -10,60 +10,178 @@ page Buttoncomponent {
W WRNexusJS
-
+
Browse documentation
- actions componentButton
Reusable 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"
- type="button"
- variant="primary"
- size="md"
- disabled="false"
-/>
Legacy mount name: data-component="Button".
Props and attributes
Prop Type Requirement Default labelstringOptional "Button"typestringOptional "button"variantstringOptional "primary"sizestringOptional "md"disabledbooleanOptional falseloadingbooleanOptional falseiconstringOptional ""iconPositionstringOptional "start"fullWidthbooleanOptional falseclassNamestringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/Button.wrn
component 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 {
props {
label = "Button"
+ loadingLabel = "Loading…"
+ description = ""
+ as = ""
+ href = ""
+ target = ""
+ rel = ""
type = "button"
- variant = "primary"
- size = "md"
+ variant = "default"
+ color = "primary"
+ size = "default"
disabled = false
loading = false
+ pill = false
+ fullWidth = false
icon = ""
iconPosition = "start"
- fullWidth = false
- className = ""
+ ariaLabel = ""
+ ariaPressed = ""
+ ariaExpanded = ""
+ ariaControls = ""
+ title = ""
+ autofocus = false
+ controlClass = ""
+ class = ""
}
view {
- <button
- type="{type}"
- disabled="{disabled || loading}"
- aria-busy="{loading}"
- class="wire-btn wire-btn--{variant} wire-btn--{size} {className}"
- class:w-full='{fullWidth}'
+ <span
+ class="wire-action {fullWidth ? 'w-full' : ''} {class}"
>
- {#if loading}
- <span class="wire-spinner" aria-hidden="true">
+ {#if as === "a" || (as === "" && href)}
+ <a
+ {...attrs}
+ href="{disabled || loading ? '' : href}"
+ target="{target}"
+ rel="{rel}"
+ title="{title}"
+ aria-label="{ariaLabel || ((size === 'icon' || size === 'icon-xs' || size === 'icon-sm' || size === 'icon-lg') ? label : '')}"
+ aria-disabled="{disabled || loading}"
+ aria-busy="{loading}"
+ aria-pressed="{ariaPressed}"
+ aria-expanded="{ariaExpanded}"
+ aria-controls="{ariaControls}"
+ tabindex="{disabled || loading ? '-1' : '0'}"
+ class="wire-btn wire-btn--variant-{variant} wire-btn--color-{color} wire-btn--size-{size} {pill ? 'wire-btn--pill' : ''} {description ? 'wire-btn--with-description' : ''} {fullWidth ? 'w-full' : ''} {controlClass}"
+ >
+ {#if loading}
+ <span
+ class="wire-spinner wire-spinner--inline"
+ aria-hidden="true"
+ >
</span>
- {/if}
-
- {#if icon && !loading && iconPosition === "start"}
- <span class="{icon} size-4 shrink-0" aria-hidden="true">
+ {/if}
+ {#if icon && !loading && iconPosition === "start"}
+ <span
+ class="wire-btn__icon {icon}"
+ aria-hidden="true"
+ >
</span>
- {/if}
-
- <span>{label}</span>
-
- {#if icon && !loading && iconPosition === "end"}
- <span class="{icon} size-4 shrink-0" aria-hidden="true">
+ {/if}
+ <span
+ class="wire-btn__copy {(size === 'icon' || size === 'icon-xs' || size === 'icon-sm' || size === 'icon-lg') ? 'wire-visually-hidden' : ''}"
+ >
+ <span
+ class="wire-btn__label"
+ >
+ <slot>{loading ? loadingLabel : label}</slot>
</span>
- {/if}
-
- <slot />
+ {#if description && !loading}
+ <span
+ class="wire-btn__description"
+ >
+ {description}
+ </span>
+ {/if}
+ </span>
+ {#if icon && !loading && iconPosition === "end"}
+ <span
+ class="wire-btn__icon {icon}"
+ aria-hidden="true"
+ >
+ </span>
+ {/if}
+ {#if (size === "icon" || size === "icon-xs" || size === "icon-sm" || size === "icon-lg") && (ariaLabel || label)}
+ <span
+ class="wire-btn__tooltip"
+ role="tooltip"
+ aria-hidden="true"
+ >
+ {ariaLabel || label}
+ </span>
+ {/if}
+ </a>
+ {:else}
+ <button
+ {...attrs}
+ type="{type}"
+ title="{title}"
+ autofocus="{autofocus}"
+ disabled="{disabled || loading}"
+ aria-label="{ariaLabel || ((size === 'icon' || size === 'icon-xs' || size === 'icon-sm' || size === 'icon-lg') ? label : '')}"
+ aria-busy="{loading}"
+ aria-pressed="{ariaPressed}"
+ aria-expanded="{ariaExpanded}"
+ aria-controls="{ariaControls}"
+ class="wire-btn wire-btn--variant-{variant} wire-btn--color-{color} wire-btn--size-{size} {pill ? 'wire-btn--pill' : ''} {description ? 'wire-btn--with-description' : ''} {fullWidth ? 'w-full' : ''} {controlClass}"
+ >
+ {#if loading}
+ <span
+ class="wire-spinner wire-spinner--inline"
+ aria-hidden="true"
+ >
+ </span>
+ {/if}
+ {#if icon && !loading && iconPosition === "start"}
+ <span
+ class="wire-btn__icon {icon}"
+ aria-hidden="true"
+ >
+ </span>
+ {/if}
+ <span
+ class="wire-btn__copy {(size === 'icon' || size === 'icon-xs' || size === 'icon-sm' || size === 'icon-lg') ? 'wire-visually-hidden' : ''}"
+ >
+ <span
+ class="wire-btn__label"
+ >
+ <slot>{loading ? loadingLabel : label}</slot>
+ </span>
+ {#if description && !loading}
+ <span
+ class="wire-btn__description"
+ >
+ {description}
+ </span>
+ {/if}
+ </span>
+ {#if icon && !loading && iconPosition === "end"}
+ <span
+ class="wire-btn__icon {icon}"
+ aria-hidden="true"
+ >
+ </span>
+ {/if}
+ {#if (size === "icon" || size === "icon-xs" || size === "icon-sm" || size === "icon-lg") && (ariaLabel || label)}
+ <span
+ class="wire-btn__tooltip"
+ role="tooltip"
+ aria-hidden="true"
+ >
+ {ariaLabel || label}
+ </span>
+ {/if}
</button>
+ {/if}
+ </span>
}
}
-
+
}
diff --git a/app/pages/components/card.wrn b/app/pages/components/card.wrn
index 858955ce..92f8e984 100644
--- a/app/pages/components/card.wrn
+++ b/app/pages/components/card.wrn
@@ -1,7 +1,7 @@
-page cardcomponent {
+page Cardcomponent {
seo {
- title = "card component"
- description = "Reusable card component."
+ title = "Card component"
+ description = "Theme-aware, responsive card component."
}
view {
@@ -10,28 +10,36 @@ page cardcomponent {
W WRNexusJS
-
+
Browse documentation
- core componentcard
Reusable card component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<card
- variant="default"
- padding="md"
- interactive="false"
-/>
Legacy mount name: data-component="card".
Props and attributes
Prop Type Requirement Default variantstringOptional "default"paddingstringOptional "md"interactivebooleanOptional falseclassNamestringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/card.wrn
component Card {
+ 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"
+ 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 {
props {
+ size = "default"
+ color = "primary"
+ title = "Card"
+ description = ""
+ items = []
variant = "default"
- padding = "md"
- interactive = false
- className = ""
+ class = ""
}
view {
- <article class="wire-card wire-card--{variant} wire-card--padding-{padding} {interactive ? 'wire-card--interactive' : ''} {className}">
- <slot />
- </article>
+ <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>
}
}
-
+
}
diff --git a/app/pages/components/carousel.wrn b/app/pages/components/carousel.wrn
index 404dd8fa..28d9fd6f 100644
--- a/app/pages/components/carousel.wrn
+++ b/app/pages/components/carousel.wrn
@@ -1,7 +1,7 @@
page Carouselcomponent {
seo {
title = "Carousel component"
- description = "Reusable carousel component."
+ description = "Theme-aware, responsive carousel component."
}
view {
@@ -10,32 +10,36 @@ page Carouselcomponent {
W WRNexusJS
-
+
Browse documentation
- content componentCarousel
Reusable carousel component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Carousel
- eyebrow="eyebrow"
- title="title"
+ 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"
description="description"
- href="href"
- actionLabel="Learn more"
-/>
Legacy mount name: data-component="Carousel".
Props and attributes
Prop Type Requirement Default eyebrowstringOptional ""titlestringOptional ""descriptionstringOptional ""hrefstringOptional ""actionLabelstringOptional "Learn more"imagestringOptional ""altstringOptional ""classstringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/Carousel.wrn
component Carousel {
+ 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 {
props {
- eyebrow = ""
- title = ""
+ size = "default"
+ color = "primary"
+ title = "Carousel"
description = ""
- href = ""
- actionLabel = "Learn more"
- image = ""
- alt = ""
+ items = []
+ variant = "default"
class = ""
}
view {
- <article class="wire-card wire-catalog-card {class}">{#if image}<img src="{image}" alt="{alt}" class="wire-catalog-card__image" />{/if}{#if eyebrow}<span class="wire-eyebrow">{eyebrow}</span>{/if}{#if title}<h3>{title}</h3>{/if}{#if description}<p>{description}</p>{/if}<slot />{#if href}<a href="{href}" class="wire-btn wire-btn--ghost">{actionLabel}</a>{/if}</article>
+ <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>
}
}
-
+
}
diff --git a/app/pages/components/chart.wrn b/app/pages/components/chart.wrn
new file mode 100644
index 00000000..4800eee7
--- /dev/null
+++ b/app/pages/components/chart.wrn
@@ -0,0 +1,46 @@
+page Chartcomponent {
+ seo {
+ title = "Chart component"
+ description = "Theme-aware, responsive chart component."
+ }
+
+ view {
+
+
+
+ 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
+ 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 {
+ props {
+ size = "default"
+ color = "primary"
+ title = "Chart"
+ description = ""
+ items = []
+ variant = "default"
+ class = ""
+ }
+ view {
+ <section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--chart 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>
+ }
+}
+
+
+
+
+ }
+}
diff --git a/app/pages/components/chat-bubble.wrn b/app/pages/components/chat-bubble.wrn
new file mode 100644
index 00000000..7c8c87f1
--- /dev/null
+++ b/app/pages/components/chat-bubble.wrn
@@ -0,0 +1,46 @@
+page ChatBubblecomponent {
+ seo {
+ title = "ChatBubble component"
+ description = "Theme-aware, responsive chat bubble component."
+ }
+
+ view {
+
+
+
+ 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
+ size="default"
+ color="primary"
+ title="Chat Bubble"
+ 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 {
+ props {
+ size = "default"
+ color = "primary"
+ title = "Chat Bubble"
+ description = ""
+ items = []
+ variant = "default"
+ class = ""
+ }
+ 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}
+ <slot />
+ </section>
+ }
+}
+
+
+
+
+ }
+}
diff --git a/app/pages/components/checkbox.wrn b/app/pages/components/checkbox.wrn
index 5360b82e..88969bce 100644
--- a/app/pages/components/checkbox.wrn
+++ b/app/pages/components/checkbox.wrn
@@ -1,7 +1,7 @@
page Checkboxcomponent {
seo {
title = "Checkbox component"
- description = "Reusable checkbox component."
+ description = "Theme-aware, responsive checkbox component."
}
view {
@@ -10,37 +10,35 @@ page Checkboxcomponent {
W WRNexusJS
-
+
Browse documentation
- core componentCheckbox
Reusable checkbox component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Checkbox
- id="id"
- name="name"
+ 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"
- description="description"
- checked="false"
-/>
Legacy mount name: data-component="Checkbox".
Props and attributes
Prop Type Requirement Default classstringOptional ""idstringOptional ""namestringOptional ""labelstringOptional "Checkbox"descriptionstringOptional ""checkedbooleanOptional falsedisabledbooleanOptional false
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 {
+ 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 {
props {
- class = ""
- id = ""
- name = ""
+ size = "default"
+ color = "primary"
label = "Checkbox"
- description = ""
+ name = ""
+ value = "on"
checked = false
disabled = false
+ class = ""
}
view {
- <label for="{id}" class="flex min-h-11 cursor-pointer items-start gap-3 rounded-xl p-2 transition hover:bg-slate-50 dark:hover:bg-slate-900 {class}">
- <input id="{id}" name="{name}" type="checkbox" checked="{checked}" disabled="{disabled}" class="mt-0.5 size-5 rounded border-slate-300 text-violet-600 focus:ring-violet-500 dark:border-slate-700 dark:bg-slate-950" />
- <span>
- <span class="block text-sm font-semibold text-slate-900 dark:text-white">{label}</span>
- <span data-show="description" class="mt-0.5 block text-sm text-slate-500 dark:text-slate-400">{description}</span>
- </span>
+ <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>
</label>
}
}
-
+
}
diff --git a/app/pages/components/clipboard.wrn b/app/pages/components/clipboard.wrn
new file mode 100644
index 00000000..6f6bc5d8
--- /dev/null
+++ b/app/pages/components/clipboard.wrn
@@ -0,0 +1,46 @@
+page Clipboardcomponent {
+ seo {
+ title = "Clipboard component"
+ description = "Theme-aware, responsive clipboard component."
+ }
+
+ view {
+
+
+
+ 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
+ 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 {
+ props {
+ size = "default"
+ color = "primary"
+ title = "Clipboard"
+ description = ""
+ items = []
+ variant = "default"
+ class = ""
+ }
+ view {
+ <section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--clipboard 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>
+ }
+}
+
+
+
+
+ }
+}
diff --git a/app/pages/components/collapse.wrn b/app/pages/components/collapse.wrn
new file mode 100644
index 00000000..c40e6b87
--- /dev/null
+++ b/app/pages/components/collapse.wrn
@@ -0,0 +1,44 @@
+page Collapsecomponent {
+ seo {
+ title = "Collapse component"
+ description = "Theme-aware, responsive collapse component."
+ }
+
+ view {
+
+
+
+ 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
+ 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 {
+ props {
+ size = "default"
+ color = "primary"
+ items = []
+ multiple = false
+ class = ""
+ }
+ 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 />
+ </div>
+ }
+}
+
+
+
+
+ }
+}
diff --git a/app/pages/components/color-picker.wrn b/app/pages/components/color-picker.wrn
index 9c11539c..5244d406 100644
--- a/app/pages/components/color-picker.wrn
+++ b/app/pages/components/color-picker.wrn
@@ -1,7 +1,7 @@
page ColorPickercomponent {
seo {
title = "ColorPicker component"
- description = "Reusable color picker component."
+ description = "Theme-aware, responsive color picker component."
}
view {
@@ -10,42 +10,40 @@ page ColorPickercomponent {
W WRNexusJS
-
+
Browse documentation
- forms componentColorPicker
Reusable color picker component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<ColorPicker
- label="Color"
+ 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"
name="name"
value="value"
- placeholder="placeholder"
- type="text"
-/>
Legacy mount name: data-component="ColorPicker".
Props and attributes
Prop Type Requirement Default labelstringOptional "Color"namestringOptional ""valuestringOptional ""placeholderstringOptional ""typestringOptional "text"requiredbooleanOptional falsedisabledbooleanOptional falsereadonlybooleanOptional falsehelpstringOptional ""errorstringOptional ""classstringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/ColorPicker.wrn
component ColorPicker {
+/>
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 {
props {
- label = "Color"
+ size = "default"
+ color = "primary"
+ label = "Color Picker"
name = ""
value = ""
placeholder = ""
- type = "text"
- required = false
+ type = "color"
+ min = ""
+ max = ""
+ step = ""
disabled = false
- readonly = false
- help = ""
- error = ""
+ required = false
class = ""
}
view {
- <label class="wire-field wire-catalog-field {class}">
- <span class="wire-label">{label}<span data-show="required" class="wire-required"> *</span>
- </span>
- <input name="{name}" value="{value}" placeholder="{placeholder}" type="{type}" required="{required}" disabled="{disabled}" readonly="{readonly}" aria-invalid="{error ? 'true' : 'false'}" class="wire-input" />
- <span data-show="help && !error" class="wire-field-message wire-field-message--help">{help}</span>
- <span data-show="error" role="alert" class="wire-field-message wire-field-message--error">{error}</span>
- <slot />
+ <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>
}
}
-
+
}
diff --git a/app/pages/components/columns.wrn b/app/pages/components/columns.wrn
new file mode 100644
index 00000000..830a9c8c
--- /dev/null
+++ b/app/pages/components/columns.wrn
@@ -0,0 +1,42 @@
+page Columnscomponent {
+ seo {
+ title = "Columns component"
+ description = "Theme-aware, responsive columns component."
+ }
+
+ view {
+
+
+
+ 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
+ size="default"
+ color="primary"
+ columns="2"
+ gap="md"
+ maxWidth="xl"
+/>
Legacy mount name: data-component="Columns".
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/Columns.wrn
component Columns {
+ props {
+ size = "default"
+ color = "primary"
+ columns = 2
+ gap = "md"
+ maxWidth = "xl"
+ class = ""
+ }
+ view {
+ <div class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--columns wire-next--gap-{gap} wire-next--columns-{columns} wire-next--max-{maxWidth} {class}">
+ <slot />
+ </div>
+ }
+}
+
+
+
+
+ }
+}
diff --git a/app/pages/components/combo-box.wrn b/app/pages/components/combo-box.wrn
new file mode 100644
index 00000000..5887496e
--- /dev/null
+++ b/app/pages/components/combo-box.wrn
@@ -0,0 +1,420 @@
+page ComboBoxcomponent {
+ seo {
+ title = "ComboBox component"
+ description = "Editable autocomplete combobox with local and remote suggestions."
+ }
+
+ view {
+
+
+
+ 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
+ size="default"
+ color="primary"
+ label="ComboBox"
+ name="name"
+ value="value"
+/>
Legacy mount name: data-component="ComboBox".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"labelstringOptional "ComboBox"namestringOptional ""valuestringOptional ""optionsstringOptional []groupsstringOptional []placeholderstringOptional "Search or select an option"searchPlaceholderstringOptional "Start typing…"clearablebooleanOptional trueallowCustomValuebooleanOptional falsedisabledbooleanOptional falserequiredbooleanOptional falseinvalidbooleanOptional falsevalidationMessagestringOptional ""helpTextstringOptional ""loadingbooleanOptional falseloadingLabelstringOptional "Loading suggestions…"emptyLabelstringOptional "No matching options"clearLabelstringOptional "Clear value"toggleLabelstringOptional "Toggle suggestions"searchModestringOptional "contains"searchFieldsstringOptional "label,description"minSearchLengthnumberOptional 0searchResultLimitnumberOptional 0optionTemplatestringOptional "default"defaultOpenbooleanOptional falsecloseOnSelectbooleanOptional truefixedbooleanOptional falseplacementstringOptional "bottom"autocompletestringOptional "off"remotebooleanOptional falseremoteUrlstringOptional ""remoteQueryParamstringOptional "q"remoteDebouncenumberOptional 250remoteAutoLoadbooleanOptional trueinfinitebooleanOptional falsehasMorebooleanOptional falsepagenumberOptional 1loadMoreLabelstringOptional "Load more"classstringOptional ""
Slots
This component does not declare a slot.
Events
searchselectchangeclearopencloseloaderror
Source contract
Installed source: components/ComboBox.wrn
component ComboBox {
+ props {
+ size = "default"
+ color = "primary"
+ label = "ComboBox"
+ name = ""
+ value = ""
+ options = []
+ groups = []
+ placeholder = "Search or select an option"
+ searchPlaceholder = "Start typing…"
+ clearable = true
+ allowCustomValue = false
+ disabled = false
+ required = false
+ invalid = false
+ validationMessage = ""
+ helpText = ""
+ loading = false
+ loadingLabel = "Loading suggestions…"
+ emptyLabel = "No matching options"
+ clearLabel = "Clear value"
+ toggleLabel = "Toggle suggestions"
+ searchMode = "contains"
+ searchFields = "label,description"
+ minSearchLength = 0
+ searchResultLimit = 0
+ optionTemplate = "default"
+ defaultOpen = false
+ closeOnSelect = true
+ fixed = false
+ placement = "bottom"
+ autocomplete = "off"
+ remote = false
+ remoteUrl = ""
+ remoteQueryParam = "q"
+ remoteDebounce = 250
+ remoteAutoLoad = true
+ infinite = false
+ hasMore = false
+ page = 1
+ loadMoreLabel = "Load more"
+ class = ""
+ @event search = function
+ @event select = function
+ @event change = function
+ @event clear = function
+ @event open = function
+ @event close = function
+ @event load = function
+ @event error = function
+ }
+
+ state open = defaultOpen
+ state query = ""
+ state selectedValue = value
+ state activeIndex = -1
+
+ functions {
+ function allOptions() {
+ return [...groups.flatMap((group) => group.options || []), ...options]
+ }
+
+ function searchableText(option) {
+ return ((option.label || "") + " " + (option.description || "")).toLowerCase()
+ }
+
+ function matches(option) {
+ if (!query || query.length < minSearchLength) {
+ return true
+ }
+ if (searchMode === "startsWith") {
+ return searchableText(option).startsWith(query.toLowerCase())
+ }
+ if (searchMode === "exact") {
+ return searchableText(option) === query.toLowerCase()
+ }
+ return searchableText(option).includes(query.toLowerCase())
+ }
+
+ function matchingOptions(list) {
+ return list.filter((option) => matches(option))
+ }
+
+ function visibleOptions(list) {
+ if (searchResultLimit > 0) {
+ return matchingOptions(list).slice(0, searchResultLimit)
+ }
+ return matchingOptions(list)
+ }
+
+ function flatVisibleOptions() {
+ return visibleOptions(allOptions())
+ }
+
+ function isSelected(option) {
+ return selectedValue === option.value
+ }
+
+ function selectedOptions() {
+ return allOptions().filter((option) => isSelected(option))
+ }
+
+ function selectedText() {
+ return selectedOptions().length ? selectedOptions()[0].label : selectedValue
+ }
+
+ function inputText() {
+ return query || selectedText()
+ }
+
+ function shouldShowDropdown() {
+ if (!open) {
+ return false
+ }
+ if (loading) {
+ return true
+ }
+ if (remote && query.length !== 0 && query.length < minSearchLength) {
+ return true
+ }
+ if (flatVisibleOptions().length) {
+ return true
+ }
+ return infinite && hasMore
+ }
+
+ function canSelect(option) {
+ return !option.disabled
+ }
+
+ function chooseOption(option) {
+ if (!canSelect(option)) {
+ return
+ }
+ selectedValue = option.value
+ query = option.label
+ activeIndex = optionIndex(option)
+ if (closeOnSelect) {
+ open = false
+ }
+ }
+
+ function updateQuery(event) {
+ query = event.target.value
+ selectedValue = allowCustomValue ? event.target.value : ""
+ open = true
+ activeIndex = flatVisibleOptions().length ? 0 : -1
+ }
+
+ function clearValue(event) {
+ if (event) {
+ event.stopPropagation()
+ }
+ query = ""
+ selectedValue = ""
+ activeIndex = -1
+ open = false
+ }
+
+ function openDropdown() {
+ if (!disabled) {
+ open = true
+ activeIndex = flatVisibleOptions().length ? 0 : -1
+ }
+ }
+
+ function closeDropdown() {
+ open = false
+ }
+
+ function toggle() {
+ if (open) {
+ closeDropdown()
+ } else {
+ openDropdown()
+ }
+ }
+
+ function setValue(nextValue) {
+ selectedValue = nextValue
+ query = ""
+ }
+
+ function moveActive(direction) {
+ if (!flatVisibleOptions().length) {
+ return
+ }
+ activeIndex = (activeIndex + direction + flatVisibleOptions().length) % flatVisibleOptions().length
+ }
+
+ function handleKeydown(event) {
+ if (disabled) {
+ return
+ }
+ if (event.key === "ArrowDown") {
+ event.preventDefault()
+ openDropdown()
+ moveActive(1)
+ } else if (event.key === "ArrowUp") {
+ event.preventDefault()
+ openDropdown()
+ moveActive(-1)
+ } else if (event.key === "Enter" && open && activeIndex >= 0) {
+ event.preventDefault()
+ chooseOption(flatVisibleOptions()[activeIndex])
+ } else if (event.key === "Escape") {
+ closeDropdown()
+ } else if (event.key === "Home" && open) {
+ event.preventDefault()
+ activeIndex = 0
+ } else if (event.key === "End" && open) {
+ event.preventDefault()
+ activeIndex = flatVisibleOptions().length - 1
+ }
+ }
+
+ function optionIndex(option) {
+ return flatVisibleOptions().findIndex((item) => item.value === option.value)
+ }
+ }
+
+ view {
+ <div
+ class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--advanced-select wire-next--combobox {open ? 'wire-next--open' : ''} {fixed ? 'wire-next--advanced-select-fixed' : ''} {invalid ? 'wire-next--invalid' : ''} {disabled ? 'wire-next--disabled' : ''} {class}"
+ data-placement="{placement}"
+ data-search-mode="{searchMode}"
+ data-remote="{remote ? 'true' : 'false'}"
+ data-remote-url="{remoteUrl}"
+ data-remote-query-param="{remoteQueryParam}"
+ data-remote-debounce="{remoteDebounce}"
+ data-remote-auto-load="{remoteAutoLoad ? 'true' : 'false'}"
+ data-infinite="{infinite ? 'true' : 'false'}"
+ data-page="{page}"
+ data-wrn-select
+ data-wrn-combobox
+ @focusout="if (!event.currentTarget.contains(event.relatedTarget)) { closeDropdown() }"
+ >
+ <label id="{name}-label" for="{name}-input">{label}</label>
+ <div class="wire-next__select-control wire-next__combobox-control">
+ <span class="wire-next__search-icon icon-[lucide--search]" aria-hidden="true">
+ </span>
+ <input
+ {...attrs}
+ id="{name}-input"
+ class="wire-next__select-trigger wire-next__combobox-input"
+ type="text"
+ role="combobox"
+ name="{allowCustomValue ? name : ''}"
+ value="{inputText()}"
+ placeholder="{placeholder}"
+ autocomplete="{autocomplete}"
+ aria-autocomplete="list"
+ aria-haspopup="listbox"
+ aria-expanded="{open}"
+ aria-controls="{name}-listbox"
+ aria-labelledby="{name}-label"
+ aria-invalid="{invalid}"
+ disabled="{disabled}"
+ required="{required && allowCustomValue}"
+ @focus="openDropdown()"
+ @click="openDropdown()"
+ @input="updateQuery(event)"
+ @keydown="handleKeydown(event)"
+ />
+ <button
+ type="button"
+ class="wire-next__clear-select"
+ data-show="clearable && inputText() && !disabled"
+ aria-label="{clearLabel}"
+ title="{clearLabel}"
+ @click="clearValue(event)"
+ >
+ <span class="icon-[lucide--x]" aria-hidden="true">
+ </span>
+ </button>
+ <button
+ type="button"
+ class="wire-next__combobox-toggle"
+ aria-label="{toggleLabel}"
+ tabindex="-1"
+ disabled="{disabled}"
+ @click="toggle()"
+ >
+ <span class="wire-next__select-chevron icon-[lucide--chevrons-up-down]" aria-hidden="true">
+ </span>
+ </button>
+ </div>
+ <div
+ class="wire-next__select-dropdown {fixed ? 'wire-next__select-dropdown--fixed' : ''}"
+ data-show="shouldShowDropdown()"
+ style="{shouldShowDropdown() ? '' : 'display: none'}"
+ >
+ <div
+ class="wire-next__select-message"
+ data-show="remote && query.length !== 0 && query.length < minSearchLength"
+ >Enter at least {minSearchLength} characters.</div>
+ <div class="wire-next__select-message" data-show="loading" role="status">
+ <i class="wire-spinner wire-spinner--inline" aria-hidden="true">
+ </i>
+ {loadingLabel}
+ </div>
+ <div
+ id="{name}-listbox"
+ class="wire-next__select-list"
+ data-show="(!remote || (query.length === 0 && remoteAutoLoad) || query.length >= minSearchLength) && !loading"
+ role="listbox"
+ >
+ {#each groups as group}
+ {#if visibleOptions(group.options || []).length}
+ <div class="wire-next__option-group" role="group" aria-label="{group.label}">
+ <div class="wire-next__group-label">{group.label}</div>
+ {#each group.options || [] as option}
+ <button
+ type="button"
+ class="wire-next__select-option {isSelected(option) ? 'wire-next__select-option--selected' : ''} {optionIndex(option) === activeIndex ? 'wire-next__select-option--active' : ''}"
+ data-option-value="{option.value}"
+ data-show="matches(option)"
+ role="option"
+ aria-selected="{isSelected(option)}"
+ disabled="{!canSelect(option)}"
+ @mouseenter="activeIndex = optionIndex(option)"
+ @mousedown="event.preventDefault()"
+ @click="chooseOption(option)"
+ >
+ {#if optionTemplate === "icon" && option.icon}<i class="{option.icon}" aria-hidden="true">
+ </i>{/if}
+ {#if optionTemplate === "avatar" && option.avatar}<img src="{option.avatar}" alt="" />{/if}
+ {#if optionTemplate === "color" && option.color}<i class="wire-next__color-dot" style="--option-color: {option.color}">
+ </i>{/if}
+ <span>
+ <strong>{option.label}</strong>{#if option.description}<small>{option.description}</small>{/if}</span>
+ <i class="wire-next__check icon-[lucide--check]" data-show="isSelected(option)" aria-hidden="true">
+ </i>
+ </button>
+ {/each}
+ </div>
+ {/if}
+ {/each}
+
+ {#each options as option}
+ <button
+ type="button"
+ class="wire-next__select-option {isSelected(option) ? 'wire-next__select-option--selected' : ''} {optionIndex(option) === activeIndex ? 'wire-next__select-option--active' : ''}"
+ data-option-value="{option.value}"
+ data-show="matches(option)"
+ role="option"
+ aria-selected="{isSelected(option)}"
+ disabled="{!canSelect(option)}"
+ @mouseenter="activeIndex = optionIndex(option)"
+ @mousedown="event.preventDefault()"
+ @click="chooseOption(option)"
+ >
+ {#if optionTemplate === "icon" && option.icon}<i class="{option.icon}" aria-hidden="true">
+ </i>{/if}
+ {#if optionTemplate === "avatar" && option.avatar}<img src="{option.avatar}" alt="" />{/if}
+ {#if optionTemplate === "color" && option.color}<i class="wire-next__color-dot" style="--option-color: {option.color}">
+ </i>{/if}
+ <span>
+ <strong>{option.label}</strong>{#if option.description}<small>{option.description}</small>{/if}</span>
+ <i class="wire-next__check icon-[lucide--check]" data-show="isSelected(option)" aria-hidden="true">
+ </i>
+ </button>
+ {/each}
+ </div>
+ <button
+ type="button"
+ class="wire-next__load-more"
+ data-wrn-select-load-more
+ data-show="infinite && hasMore"
+ >{loadMoreLabel}</button>
+ </div>
+
+ {#if !allowCustomValue}
+ <input
+ type="hidden"
+ name="{name}"
+ value="{selectedValue}"
+ required="{required}"
+ data-error="{name}"
+ aria-describedby="{validationMessage ? `${name}-validation` : helpText ? `${name}-help` : ''}"
+ />
+ {/if}
+
+ {#if helpText && !validationMessage}<small id="{name}-help">{helpText}</small>{/if}
+ <small
+ id="{name}-validation"
+ class="wire-next__validation"
+ data-error="{name}"
+ >{validationMessage}</small>
+ </div>
+ }
+}
+
+
+
+
+ }
+}
diff --git a/app/pages/components/confetti.wrn b/app/pages/components/confetti.wrn
new file mode 100644
index 00000000..8151731a
--- /dev/null
+++ b/app/pages/components/confetti.wrn
@@ -0,0 +1,46 @@
+page Confetticomponent {
+ seo {
+ title = "Confetti component"
+ description = "Theme-aware, responsive confetti component."
+ }
+
+ view {
+
+
+
+ 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
+ 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 {
+ props {
+ size = "default"
+ color = "primary"
+ title = "Confetti"
+ description = ""
+ items = []
+ variant = "default"
+ class = ""
+ }
+ view {
+ <section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--confetti 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>
+ }
+}
+
+
+
+
+ }
+}
diff --git a/app/pages/components/container.wrn b/app/pages/components/container.wrn
index e6913ec7..d6cd79bb 100644
--- a/app/pages/components/container.wrn
+++ b/app/pages/components/container.wrn
@@ -1,7 +1,7 @@
page Containercomponent {
seo {
title = "Container component"
- description = "Reusable container component."
+ description = "Theme-aware, responsive container component."
}
view {
@@ -10,24 +10,32 @@ page Containercomponent {
W WRNexusJS
-
+
Browse documentation
- core componentContainer
Reusable 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"
-/>
Legacy mount name: data-component="Container".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"classNamestringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/Container.wrn
component Container {
+ color="primary"
+ columns="2"
+ gap="md"
+ maxWidth="xl"
+/>
Legacy mount name: data-component="Container".
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/Container.wrn
component Container {
props {
size = "default"
- className = ""
+ color = "primary"
+ columns = 2
+ gap = "md"
+ maxWidth = "xl"
+ class = ""
}
view {
- <div class="w-full {size === 'narrow' ? 'max-w-3xl' : size === 'wide' ? 'max-w-screen-2xl' : 'max-w-7xl'} {className}">
+ <div class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--container wire-next--gap-{gap} wire-next--columns-{columns} wire-next--max-{maxWidth} {class}">
<slot />
</div>
}
}
-
+
}
diff --git a/app/pages/components/context-menu.wrn b/app/pages/components/context-menu.wrn
index 7fc9109d..337727ca 100644
--- a/app/pages/components/context-menu.wrn
+++ b/app/pages/components/context-menu.wrn
@@ -1,7 +1,7 @@
page ContextMenucomponent {
seo {
title = "ContextMenu component"
- description = "Reusable context menu component."
+ description = "Theme-aware, responsive context menu component."
}
view {
@@ -10,37 +10,39 @@ page ContextMenucomponent {
W WRNexusJS
-
+
Browse documentation
- overlays componentContextMenu
Reusable context menu component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<ContextMenu
- title="title"
+ 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"
- closeLabel="Close"
-/>
Legacy mount name: data-component="ContextMenu".
Props and attributes
Prop Type Requirement Default titlestringOptional ""descriptionstringOptional ""openbooleanOptional falsecloseLabelstringOptional "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
This component does not declare a custom event.
Source contract
Installed source: components/ContextMenu.wrn
component ContextMenu {
props {
- title = ""
+ size = "default"
+ color = "primary"
+ title = "Context Menu"
description = ""
open = false
+ placement = "bottom"
closeLabel = "Close"
class = ""
}
view {
- <div data-show="open" class="wire-overlay wire-catalog-overlay {class}">
- <section role="dialog" aria-modal="true" aria-label="{title}" class="wire-dialog">
+ <div data-show="{open}" class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--context-menu wire-next--placement-{placement} {class}" role="region" aria-modal="false" aria-label="{title}">
<header>
- <h2 data-show="title" class="wire-dialog__title">{title}</h2>
- <p data-show="description" class="wire-dialog__description">{description}</p>
+ <strong>{title}</strong>
+ <button type="button" aria-label="{closeLabel}">×</button>
</header>
- <slot />
- <button type="button" class="wire-btn wire-btn--ghost">{closeLabel}</button>
- </section>
+ {#if description}<p>{description}</p>{/if}
+ <slot />
</div>
}
}
-
+
}
diff --git a/app/pages/components/copy-markup.wrn b/app/pages/components/copy-markup.wrn
new file mode 100644
index 00000000..22b9571b
--- /dev/null
+++ b/app/pages/components/copy-markup.wrn
@@ -0,0 +1,50 @@
+page CopyMarkupcomponent {
+ seo {
+ title = "CopyMarkup component"
+ description = "Theme-aware, responsive copy markup component."
+ }
+
+ view {
+
+
+
+ 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
+ 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 {
+ props {
+ size = "default"
+ color = "primary"
+ label = "Copy Markup"
+ name = ""
+ value = ""
+ placeholder = ""
+ type = "text"
+ min = ""
+ max = ""
+ step = ""
+ disabled = false
+ required = false
+ class = ""
+ }
+ view {
+ <label class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--field wire-next--copy-markup {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>
+ }
+}
+
+
+
+
+ }
+}
diff --git a/app/pages/components/custom-scrollbar.wrn b/app/pages/components/custom-scrollbar.wrn
new file mode 100644
index 00000000..09a814c3
--- /dev/null
+++ b/app/pages/components/custom-scrollbar.wrn
@@ -0,0 +1,42 @@
+page CustomScrollbarcomponent {
+ seo {
+ title = "CustomScrollbar component"
+ description = "Theme-aware, responsive custom scrollbar component."
+ }
+
+ view {
+
+
+
+ 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
+ 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 {
+ props {
+ size = "default"
+ color = "primary"
+ columns = 2
+ gap = "md"
+ maxWidth = "xl"
+ class = ""
+ }
+ view {
+ <div class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--custom-scrollbar wire-next--gap-{gap} wire-next--columns-{columns} wire-next--max-{maxWidth} {class}">
+ <slot />
+ </div>
+ }
+}
+
+
+
+
+ }
+}
diff --git a/app/pages/components/data-map.wrn b/app/pages/components/data-map.wrn
new file mode 100644
index 00000000..fa0ddf3d
--- /dev/null
+++ b/app/pages/components/data-map.wrn
@@ -0,0 +1,46 @@
+page DataMapcomponent {
+ seo {
+ title = "DataMap component"
+ description = "Theme-aware, responsive data map component."
+ }
+
+ view {
+
+
+
+ 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
+ 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 {
+ props {
+ size = "default"
+ color = "primary"
+ title = "Data Map"
+ description = ""
+ items = []
+ variant = "default"
+ class = ""
+ }
+ view {
+ <section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--data-map 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>
+ }
+}
+
+
+
+
+ }
+}
diff --git a/app/pages/components/data-table.wrn b/app/pages/components/data-table.wrn
index 1f9b24e0..d0ae8e29 100644
--- a/app/pages/components/data-table.wrn
+++ b/app/pages/components/data-table.wrn
@@ -1,7 +1,7 @@
page DataTablecomponent {
seo {
title = "DataTable component"
- description = "Reusable data table component."
+ description = "Theme-aware, responsive data table component."
}
view {
@@ -10,40 +10,40 @@ page DataTablecomponent {
W WRNexusJS
-
+
Browse documentation
- data componentDataTable
Reusable data table component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<DataTable
- caption="Data table"
+ 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="[]"
- emptyMessage="No data available."
- striped="false"
-/>
Legacy mount name: data-component="DataTable".
Props and attributes
Prop Type Requirement Default captionstringOptional "Data table"columnsstringOptional []rowsstringOptional []emptyMessagestringOptional "No data available."stripedbooleanOptional falseclassstringOptional ""
Slots
This component does not declare a slot.
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
This component does not declare a custom event.
Source contract
Installed source: components/DataTable.wrn
component DataTable {
props {
- caption = "Data table"
+ size = "default"
+ color = "primary"
+ caption = "Data Table"
columns = []
rows = []
- emptyMessage = "No data available."
- striped = false
+ striped = true
class = ""
}
view {
- <div class="wire-table-wrap {class}" tabindex="0" role="region" aria-label="{caption}">
- <table class="wire-table {striped ? 'wire-table--striped' : ''}">
- <caption class="wire-visually-hidden">{caption}</caption>
+ <div class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--table {class}">
+ <table>
+ <caption>{caption}</caption>
<thead>
- <tr>{#each columns as column}<th scope="col">{column.label}</th>{/each}</tr>
+ <tr>{#each columns as column}<th>{column.label}</th>{/each}</tr>
</thead>
- <tbody>{#each rows as row}<tr>{#each columns as column}<td>{row[column.key]}</td>{/each}</tr>{:empty}<tr>
- <td colspan="{columns.length}">{emptyMessage}</td>
- </tr>{/each}</tbody>
+ <tbody>{#each rows as row}<tr>{#each columns as column}<td>{row[column.key]}</td>{/each}</tr>{/each}</tbody>
</table>
+ <slot />
</div>
}
}
-
+
}
diff --git a/app/pages/components/date-picker.wrn b/app/pages/components/date-picker.wrn
index b985c102..f086e01e 100644
--- a/app/pages/components/date-picker.wrn
+++ b/app/pages/components/date-picker.wrn
@@ -1,7 +1,7 @@
page DatePickercomponent {
seo {
title = "DatePicker component"
- description = "Reusable date picker component."
+ description = "Theme-aware, responsive date picker component."
}
view {
@@ -10,32 +10,40 @@ page DatePickercomponent {
W WRNexusJS
-
+
Browse documentation
- forms componentDatePicker
Reusable date picker component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<DatePicker
- id="date"
- name="date"
- label="Date"
+ 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"
+ name="name"
value="value"
- min="min"
-/>
Legacy mount name: data-component="DatePicker".
Props and attributes
Prop Type Requirement Default classstringOptional ""idstringOptional "date"namestringOptional "date"labelstringOptional "Date"valuestringOptional ""minstringOptional ""maxstringOptional ""requiredbooleanOptional false
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"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 {
props {
+ size = "default"
+ color = "primary"
+ label = "Date Picker"
+ name = ""
+ value = ""
+ placeholder = ""
+ type = "date"
+ min = ""
+ max = ""
+ step = ""
+ disabled = false
+ required = false
class = ""
- id: string = "date"
- name: string = "date"
- label: string = "Date"
- value: string = ""
- min: string = ""
- max: string = ""
- required: boolean = false
}
view {
- <DateInput class="{class}" id="{id}" name="{name}" label="{label}" value="{value}" required="{required}" />
+ <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}" />
+ </label>
}
}
-
+
}
diff --git a/app/pages/components/device-frame.wrn b/app/pages/components/device-frame.wrn
new file mode 100644
index 00000000..f6d81146
--- /dev/null
+++ b/app/pages/components/device-frame.wrn
@@ -0,0 +1,46 @@
+page DeviceFramecomponent {
+ seo {
+ title = "DeviceFrame component"
+ description = "Theme-aware, responsive device frame component."
+ }
+
+ view {
+
+
+
+ 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
+ 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 {
+ props {
+ size = "default"
+ color = "primary"
+ title = "Device Frame"
+ description = ""
+ items = []
+ variant = "default"
+ class = ""
+ }
+ 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>
+ }
+}
+
+
+
+
+ }
+}
diff --git a/app/pages/components/divider.wrn b/app/pages/components/divider.wrn
index 0bffc687..a69ed5bc 100644
--- a/app/pages/components/divider.wrn
+++ b/app/pages/components/divider.wrn
@@ -1,7 +1,7 @@
page Dividercomponent {
seo {
title = "Divider component"
- description = "Reusable divider component."
+ description = "Theme-aware, responsive divider component."
}
view {
@@ -10,21 +10,28 @@ page Dividercomponent {
W WRNexusJS
-
+
Browse documentation
- core componentDivider
Reusable divider component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Divider />
Legacy mount name: data-component="Divider".
Props and attributes
Prop Type Requirement Default classNamestringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/Divider.wrn
component 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"
+ orientation="horizontal"
+/>
Legacy mount name: data-component="Divider".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"labelstringOptional ""orientationstringOptional "horizontal"classstringOptional ""
Slots
This component does not declare a slot.
Events
This component does not declare a custom event.
Source contract
Installed source: components/Divider.wrn
component Divider {
props {
- className = ""
+ size = "default"
+ color = "primary"
+ label = ""
+ orientation = "horizontal"
+ class = ""
}
view {
- <div class="h-px w-full bg-slate-200 dark:bg-slate-800 {className}">
- <slot />
- </div>
+ <div class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--divider wire-next--divider-{orientation} {class}" role="separator" aria-orientation="{orientation}">{#if label}<span>{label}</span>{/if}</div>
}
}
-
+
}
diff --git a/app/pages/components/drag-and-drop.wrn b/app/pages/components/drag-and-drop.wrn
new file mode 100644
index 00000000..b4ce7388
--- /dev/null
+++ b/app/pages/components/drag-and-drop.wrn
@@ -0,0 +1,46 @@
+page DragAndDropcomponent {
+ seo {
+ title = "DragAndDrop component"
+ description = "Theme-aware, responsive drag and drop component."
+ }
+
+ view {
+
+
+
+ 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
+ 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 {
+ props {
+ size = "default"
+ color = "primary"
+ title = "Drag And Drop"
+ description = ""
+ items = []
+ variant = "default"
+ class = ""
+ }
+ view {
+ <section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--drag-and-drop 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>
+ }
+}
+
+
+
+
+ }
+}
diff --git a/app/pages/components/drawer.wrn b/app/pages/components/drawer.wrn
index 254d0baa..082803e8 100644
--- a/app/pages/components/drawer.wrn
+++ b/app/pages/components/drawer.wrn
@@ -1,7 +1,7 @@
page Drawercomponent {
seo {
title = "Drawer component"
- description = "Reusable drawer component."
+ description = "Theme-aware, responsive drawer component."
}
view {
@@ -10,39 +10,39 @@ page Drawercomponent {
W WRNexusJS
-
+
Browse documentation
- core componentDrawer
Reusable drawer component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Drawer
- title="Panel"
+ 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"
- side="right"
-/>
Legacy mount name: data-component="Drawer".
Props and attributes
Prop Type Requirement Default classstringOptional ""titlestringOptional "Panel"openbooleanOptional falsesidestringOptional "right"
Slots
default
Events
click
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
This component does not declare a custom event.
Source contract
Installed source: components/Drawer.wrn
component Drawer {
props {
- class = ""
- title = "Panel"
+ size = "default"
+ color = "primary"
+ title = "Drawer"
+ description = ""
open = false
- side = "right"
+ placement = "bottom"
+ closeLabel = "Close"
+ class = ""
}
- state visible = open
view {
- <div data-show="visible" class="fixed inset-0 z-50 {class}" role="dialog" aria-modal="true">
- <button class="absolute inset-0 bg-slate-950/50" aria-label="Close" @click="visible = false">
- </button>
- <aside class="absolute inset-y-0 w-[min(92vw,28rem)] overflow-auto bg-white p-6 shadow-2xl transition dark:bg-slate-900 {side === 'left' ? 'left-0' : 'right-0'}">
- <header class="flex items-center justify-between">
- <h2 class="text-xl font-bold">{title}</h2>
- <button @click="visible = false" class="size-10 rounded-xl hover:bg-slate-100">×</button>
+ <div data-show="{open}" class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--drawer wire-next--placement-{placement} {class}" role="dialog" aria-modal="true" aria-label="{title}">
+ <header>
+ <strong>{title}</strong>
+ <button type="button" aria-label="{closeLabel}">×</button>
</header>
- <div class="mt-6">
- <slot />
- </div>
- </aside>
+ {#if description}<p>{description}</p>{/if}
+ <slot />
</div>
}
}
-
+
}
diff --git a/app/pages/components/dropdown.wrn b/app/pages/components/dropdown.wrn
new file mode 100644
index 00000000..777bb40d
--- /dev/null
+++ b/app/pages/components/dropdown.wrn
@@ -0,0 +1,49 @@
+page Dropdowncomponent {
+ seo {
+ title = "Dropdown component"
+ description = "Theme-aware, responsive dropdown component."
+ }
+
+ view {
+
+
+
+ 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
+ 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 {
+ props {
+ size = "default"
+ color = "primary"
+ title = "Dropdown"
+ description = ""
+ open = false
+ placement = "bottom"
+ closeLabel = "Close"
+ class = ""
+ }
+ view {
+ <div data-show="{open}" class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--dropdown wire-next--placement-{placement} {class}" role="region" aria-modal="false" aria-label="{title}">
+ <header>
+ <strong>{title}</strong>
+ <button type="button" aria-label="{closeLabel}">×</button>
+ </header>
+ {#if description}<p>{description}</p>{/if}
+ <slot />
+ </div>
+ }
+}
+
+
+
+
+ }
+}
diff --git a/app/pages/components/file-input.wrn b/app/pages/components/file-input.wrn
index 5c452147..464e4982 100644
--- a/app/pages/components/file-input.wrn
+++ b/app/pages/components/file-input.wrn
@@ -1,7 +1,7 @@
page FileInputcomponent {
seo {
title = "FileInput component"
- description = "Reusable file input component."
+ description = "Theme-aware, responsive file input component."
}
view {
@@ -10,42 +10,40 @@ page FileInputcomponent {
W WRNexusJS
-
+
Browse documentation
- forms componentFileInput
Reusable file input component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<FileInput
- label="File"
+ 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"
name="name"
value="value"
- placeholder="placeholder"
- type="text"
-/>
Legacy mount name: data-component="FileInput".
Props and attributes
Prop Type Requirement Default labelstringOptional "File"namestringOptional ""valuestringOptional ""placeholderstringOptional ""typestringOptional "text"requiredbooleanOptional falsedisabledbooleanOptional falsereadonlybooleanOptional falsehelpstringOptional ""errorstringOptional ""classstringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/FileInput.wrn
component FileInput {
+/>
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 {
props {
- label = "File"
+ size = "default"
+ color = "primary"
+ label = "File Input"
name = ""
value = ""
placeholder = ""
- type = "text"
- required = false
+ type = "file"
+ min = ""
+ max = ""
+ step = ""
disabled = false
- readonly = false
- help = ""
- error = ""
+ required = false
class = ""
}
view {
- <label class="wire-field wire-catalog-field {class}">
- <span class="wire-label">{label}<span data-show="required" class="wire-required"> *</span>
- </span>
- <input name="{name}" value="{value}" placeholder="{placeholder}" type="{type}" required="{required}" disabled="{disabled}" readonly="{readonly}" aria-invalid="{error ? 'true' : 'false'}" class="wire-input" />
- <span data-show="help && !error" class="wire-field-message wire-field-message--help">{help}</span>
- <span data-show="error" role="alert" class="wire-field-message wire-field-message--error">{error}</span>
- <slot />
+ <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>
}
}
-
+
}
diff --git a/app/pages/components/file-upload-progress.wrn b/app/pages/components/file-upload-progress.wrn
new file mode 100644
index 00000000..bbc68f7d
--- /dev/null
+++ b/app/pages/components/file-upload-progress.wrn
@@ -0,0 +1,46 @@
+page FileUploadProgresscomponent {
+ seo {
+ title = "FileUploadProgress component"
+ description = "Theme-aware, responsive file upload progress component."
+ }
+
+ view {
+
+
+
+ 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
+ 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 {
+ props {
+ size = "default"
+ color = "primary"
+ label = "Progress"
+ value = 50
+ max = 100
+ showValue = true
+ class = ""
+ }
+ view {
+ <div class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--file-upload-progress {class}">
+ <div class="wire-next__row">
+ <span>{label}</span>{#if showValue}<strong>{value}%</strong>{/if}</div>
+ <progress value="{value}" max="{max}">
+ </progress>
+ </div>
+ }
+}
+
+
+
+
+ }
+}
diff --git a/app/pages/components/file-upload.wrn b/app/pages/components/file-upload.wrn
index 694ab3b9..3d9c94e5 100644
--- a/app/pages/components/file-upload.wrn
+++ b/app/pages/components/file-upload.wrn
@@ -1,7 +1,7 @@
page FileUploadcomponent {
seo {
title = "FileUpload component"
- description = "Reusable file upload component."
+ description = "Theme-aware, responsive file upload component."
}
view {
@@ -10,36 +10,36 @@ page FileUploadcomponent {
W WRNexusJS
-
+
Browse documentation
- content componentFileUpload
Reusable file upload component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<FileUpload
- id="file"
- name="file"
- label="Upload file"
- accept="accept"
- multiple="false"
-/>
Legacy mount name: data-component="FileUpload".
Props and attributes
Prop Type Requirement Default classstringOptional ""idstringOptional "file"namestringOptional "file"labelstringOptional "Upload file"acceptstringOptional ""multiplebooleanOptional falsehelpstringOptional "Drag and drop or browse"
Slots
This component does not declare a slot.
Events
This component does not declare a custom event.
Source contract
Installed source: components/FileUpload.wrn
component 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 {
props {
+ size = "default"
+ color = "primary"
+ title = "File Upload"
+ description = ""
+ items = []
+ variant = "default"
class = ""
- id = "file"
- name = "file"
- label = "Upload file"
- accept = ""
- multiple = false
- help = "Drag and drop or browse"
}
view {
- <label for="{id}" class="flex min-h-40 cursor-pointer flex-col items-center justify-center rounded-2xl border-2 border-dashed border-slate-300 bg-slate-50 p-6 text-center transition hover:border-violet-500 hover:bg-violet-50/50 focus-within:ring-4 focus-within:ring-violet-500/10 dark:border-slate-700 dark:bg-slate-900/50 {class}">
- <span class="text-3xl" aria-hidden="true">⇧</span>
- <span class="mt-2 font-semibold">{label}</span>
- <span class="mt-1 text-sm text-slate-500">{help}</span>
- <input id="{id}" name="{name}" type="file" accept="{accept}" multiple="{multiple}" class="sr-only" />
- </label>
+ <section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--file-upload 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>
}
}
-
+
}
diff --git a/app/pages/components/grid.wrn b/app/pages/components/grid.wrn
index 93496807..fe24bfc6 100644
--- a/app/pages/components/grid.wrn
+++ b/app/pages/components/grid.wrn
@@ -1,7 +1,7 @@
page Gridcomponent {
seo {
title = "Grid component"
- description = "Reusable grid component."
+ description = "Theme-aware, responsive grid component."
}
view {
@@ -10,24 +10,32 @@ page Gridcomponent {
W WRNexusJS
-
+
Browse documentation
- data componentGrid
Reusable grid component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Grid
- gap="4"
-/>
Legacy mount name: data-component="Grid".
Props and attributes
Prop Type Requirement Default gapstringOptional "4"classNamestringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/Grid.wrn
component 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"
+ gap="md"
+ maxWidth="xl"
+/>
Legacy mount name: data-component="Grid".
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/Grid.wrn
component Grid {
props {
- gap = "4"
- className = ""
+ size = "default"
+ color = "primary"
+ columns = 2
+ gap = "md"
+ maxWidth = "xl"
+ class = ""
}
view {
- <div class="grid gap-{gap} {className}">
+ <div class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--grid wire-next--gap-{gap} wire-next--columns-{columns} wire-next--max-{maxWidth} {class}">
<slot />
</div>
}
}
-
+
}
diff --git a/app/pages/components/image.wrn b/app/pages/components/image.wrn
new file mode 100644
index 00000000..98e81870
--- /dev/null
+++ b/app/pages/components/image.wrn
@@ -0,0 +1,46 @@
+page Imagecomponent {
+ seo {
+ title = "Image component"
+ description = "Theme-aware, responsive image component."
+ }
+
+ view {
+
+
+
+ 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
+ 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 {
+ props {
+ size = "default"
+ color = "primary"
+ src = ""
+ alt = ""
+ width = ""
+ height = ""
+ loading = "lazy"
+ rounded = false
+ class = ""
+ }
+ view {
+ <figure class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--image {rounded ? 'wire-next--rounded' : ''} {class}">
+ <img src="{src}" alt="{alt}" width="{width}" height="{height}" loading="{loading}" />
+ <slot />
+ </figure>
+ }
+}
+
+
+
+
+ }
+}
diff --git a/app/pages/components/input-group.wrn b/app/pages/components/input-group.wrn
index 2e3751fd..919cbc3f 100644
--- a/app/pages/components/input-group.wrn
+++ b/app/pages/components/input-group.wrn
@@ -1,7 +1,7 @@
page InputGroupcomponent {
seo {
title = "InputGroup component"
- description = "Reusable input group component."
+ description = "Theme-aware, responsive input group component."
}
view {
@@ -10,42 +10,40 @@ page InputGroupcomponent {
W WRNexusJS
-
+
Browse documentation
- forms componentInputGroup
Reusable input group component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<InputGroup
- label="Input"
+ 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"
name="name"
value="value"
- placeholder="placeholder"
- type="text"
-/>
Legacy mount name: data-component="InputGroup".
Props and attributes
Prop Type Requirement Default labelstringOptional "Input"namestringOptional ""valuestringOptional ""placeholderstringOptional ""typestringOptional "text"requiredbooleanOptional falsedisabledbooleanOptional falsereadonlybooleanOptional falsehelpstringOptional ""errorstringOptional ""classstringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/InputGroup.wrn
component InputGroup {
+/>
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 {
props {
- label = "Input"
+ size = "default"
+ color = "primary"
+ label = "Input Group"
name = ""
value = ""
placeholder = ""
type = "text"
- required = false
+ min = ""
+ max = ""
+ step = ""
disabled = false
- readonly = false
- help = ""
- error = ""
+ required = false
class = ""
}
view {
- <label class="wire-field wire-catalog-field {class}">
- <span class="wire-label">{label}<span data-show="required" class="wire-required"> *</span>
- </span>
- <input name="{name}" value="{value}" placeholder="{placeholder}" type="{type}" required="{required}" disabled="{disabled}" readonly="{readonly}" aria-invalid="{error ? 'true' : 'false'}" class="wire-input" />
- <span data-show="help && !error" class="wire-field-message wire-field-message--help">{help}</span>
- <span data-show="error" role="alert" class="wire-field-message wire-field-message--error">{error}</span>
- <slot />
+ <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>
}
}
-
+
}
diff --git a/app/pages/components/input-number.wrn b/app/pages/components/input-number.wrn
new file mode 100644
index 00000000..c160e26a
--- /dev/null
+++ b/app/pages/components/input-number.wrn
@@ -0,0 +1,50 @@
+page InputNumbercomponent {
+ seo {
+ title = "InputNumber component"
+ description = "Theme-aware, responsive input number component."
+ }
+
+ view {
+
+
+
+ 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
+ size="default"
+ color="primary"
+ label="Input Number"
+ name="name"
+ value="value"
+/>
Legacy mount name: data-component="InputNumber".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"labelstringOptional "Input Number"namestringOptional ""valuestringOptional ""placeholderstringOptional ""typestringOptional "number"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/InputNumber.wrn
component InputNumber {
+ props {
+ size = "default"
+ color = "primary"
+ label = "Input Number"
+ name = ""
+ value = ""
+ placeholder = ""
+ type = "number"
+ min = ""
+ max = ""
+ step = ""
+ disabled = false
+ required = false
+ class = ""
+ }
+ view {
+ <label class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--field wire-next--input-number {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>
+ }
+}
+
+
+
+
+ }
+}
diff --git a/app/pages/components/input.wrn b/app/pages/components/input.wrn
index 11345179..2a69f4c6 100644
--- a/app/pages/components/input.wrn
+++ b/app/pages/components/input.wrn
@@ -1,7 +1,7 @@
-page inputcomponent {
+page Inputcomponent {
seo {
- title = "input component"
- description = "Reusable input component."
+ title = "Input component"
+ description = "Theme-aware, responsive input component."
}
view {
@@ -10,29 +10,40 @@ page inputcomponent {
W WRNexusJS
-
+
Browse documentation
- core componentinput
Reusable input component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<input
- type="text"
+ 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"
name="name"
value="value"
- placeholder="placeholder"
-/>
Legacy mount name: data-component="input".
Props and attributes
Prop Type Requirement Default typestringOptional "text"namestringOptional ""valuestringOptional ""placeholderstringOptional ""classstringOptional ""
Slots
This component does not declare a slot.
Events
This component does not declare a custom event.
Source contract
Installed source: components/input.wrn
// Text input. Pairs with the validation system (name maps to a field).
-component Input {
+/>
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 {
props {
- type = "text"
+ size = "default"
+ color = "primary"
+ label = "Input"
name = ""
value = ""
placeholder = ""
+ type = "text"
+ min = ""
+ max = ""
+ step = ""
+ disabled = false
+ required = false
class = ""
}
view {
- <input type="{type}" name="{name}" value="{value}" placeholder="{placeholder}" class="wire-input {class}">
+ <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>
}
}
-
+
}
diff --git a/app/pages/components/kbd.wrn b/app/pages/components/kbd.wrn
new file mode 100644
index 00000000..31aef04e
--- /dev/null
+++ b/app/pages/components/kbd.wrn
@@ -0,0 +1,38 @@
+page Kbdcomponent {
+ seo {
+ title = "Kbd component"
+ description = "Theme-aware, responsive kbd component."
+ }
+
+ view {
+
+
+
+ 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
+ size="default"
+ color="primary"
+ label="⌘ K"
+/>
Legacy mount name: data-component="Kbd".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"labelstringOptional "⌘ K"classstringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/Kbd.wrn
component Kbd {
+ props {
+ size = "default"
+ color = "primary"
+ label = "⌘ K"
+ class = ""
+ }
+ view {
+ <kbd class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--kbd {class}">
+ <slot>{label}</slot>
+ </kbd>
+ }
+}
+
+
+
+
+ }
+}
diff --git a/app/pages/components/layout-splitter.wrn b/app/pages/components/layout-splitter.wrn
new file mode 100644
index 00000000..d4739a04
--- /dev/null
+++ b/app/pages/components/layout-splitter.wrn
@@ -0,0 +1,42 @@
+page LayoutSplittercomponent {
+ seo {
+ title = "LayoutSplitter component"
+ description = "Theme-aware, responsive layout splitter component."
+ }
+
+ view {
+
+
+
+ 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
+ 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 {
+ props {
+ size = "default"
+ color = "primary"
+ columns = 2
+ gap = "md"
+ maxWidth = "xl"
+ class = ""
+ }
+ view {
+ <div class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--layout-splitter wire-next--gap-{gap} wire-next--columns-{columns} wire-next--max-{maxWidth} {class}">
+ <slot />
+ </div>
+ }
+}
+
+
+
+
+ }
+}
diff --git a/app/pages/components/legend-indicator.wrn b/app/pages/components/legend-indicator.wrn
new file mode 100644
index 00000000..45a50c53
--- /dev/null
+++ b/app/pages/components/legend-indicator.wrn
@@ -0,0 +1,46 @@
+page LegendIndicatorcomponent {
+ seo {
+ title = "LegendIndicator component"
+ description = "Theme-aware, responsive legend indicator component."
+ }
+
+ view {
+
+
+
+ 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
+ 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 {
+ props {
+ size = "default"
+ color = "primary"
+ title = "Legend Indicator"
+ description = ""
+ items = []
+ variant = "default"
+ class = ""
+ }
+ view {
+ <section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--legend-indicator 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>
+ }
+}
+
+
+
+
+ }
+}
diff --git a/app/pages/components/link.wrn b/app/pages/components/link.wrn
index 2399ee54..0f2704f0 100644
--- a/app/pages/components/link.wrn
+++ b/app/pages/components/link.wrn
@@ -1,7 +1,7 @@
page Linkcomponent {
seo {
title = "Link component"
- description = "Reusable link component."
+ description = "Theme-aware, responsive link component."
}
view {
@@ -10,27 +10,33 @@ page Linkcomponent {
W WRNexusJS
-
+
Browse documentation
- core componentLink
Reusable link component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Link
- href="#"
+ 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"
- external="false"
-/>
Legacy mount name: data-component="Link".
Props and attributes
Prop Type Requirement Default hrefstringOptional "#"labelstringOptional "Link"externalbooleanOptional falseclassNamestringOptional ""
Slots
This component does not declare a slot.
Events
This component does not declare a custom event.
Source contract
Installed source: components/Link.wrn
component 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 {
props {
- href = "#"
+ size = "default"
+ color = "primary"
label = "Link"
+ href = "#"
+ target = ""
+ rel = ""
external = false
- className = ""
+ class = ""
}
view {
- <a href="{href}" target="{external ? '_blank' : ''}" rel="{external ? 'noreferrer' : ''}" class="font-medium text-violet-600 underline-offset-4 transition hover:text-violet-700 hover:underline focus-visible:rounded focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-violet-500 {className}">{label}<span data-show="external" aria-hidden="true"> ↗</span>
- </a>
+ <a {...attrs} href="{href}" target="{target}" rel="{rel}" class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--link {class}">
+ <slot>{label}</slot>{#if external}<span aria-hidden="true">↗</span>{/if}</a>
}
}
-
+
}
diff --git a/app/pages/components/list-group.wrn b/app/pages/components/list-group.wrn
new file mode 100644
index 00000000..3144f56a
--- /dev/null
+++ b/app/pages/components/list-group.wrn
@@ -0,0 +1,46 @@
+page ListGroupcomponent {
+ seo {
+ title = "ListGroup component"
+ description = "Theme-aware, responsive list group component."
+ }
+
+ view {
+
+
+
+ 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
+ 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 {
+ props {
+ size = "default"
+ color = "primary"
+ title = "List Group"
+ description = ""
+ items = []
+ variant = "default"
+ class = ""
+ }
+ view {
+ <section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--list-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>
+ }
+}
+
+
+
+
+ }
+}
diff --git a/app/pages/components/list.wrn b/app/pages/components/list.wrn
index 04da69ef..ad57ede8 100644
--- a/app/pages/components/list.wrn
+++ b/app/pages/components/list.wrn
@@ -1,7 +1,7 @@
page Listcomponent {
seo {
title = "List component"
- description = "Reusable list component."
+ description = "Theme-aware, responsive list component."
}
view {
@@ -10,37 +10,36 @@ page Listcomponent {
W WRNexusJS
-
+
Browse documentation
- data componentList
Reusable list component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<List
- title="title"
+ 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"
- empty="false"
- emptyText="No items available."
-/>
Legacy mount name: data-component="List".
Props and attributes
Prop Type Requirement Default titlestringOptional ""descriptionstringOptional ""emptybooleanOptional falseemptyTextstringOptional "No items available."classstringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/List.wrn
component List {
+ 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 {
props {
- title = ""
+ size = "default"
+ color = "primary"
+ title = "List"
description = ""
- empty = false
- emptyText = "No items available."
+ items = []
+ variant = "default"
class = ""
}
view {
- <section class="wire-catalog-collection {class}">
- <header data-show="title || description">
- <h2 data-show="title">{title}</h2>
- <p data-show="description">{description}</p>
- </header>
- <div data-show="!empty" role="list" class="wire-catalog-collection__items">
- <slot />
- </div>
- <p data-show="empty" role="status" class="wire-muted">{emptyText}</p>
+ <section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--list 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>
}
}
-
+
}
diff --git a/app/pages/components/map.wrn b/app/pages/components/map.wrn
new file mode 100644
index 00000000..8dade8e3
--- /dev/null
+++ b/app/pages/components/map.wrn
@@ -0,0 +1,46 @@
+page Mapcomponent {
+ seo {
+ title = "Map component"
+ description = "Theme-aware, responsive map component."
+ }
+
+ view {
+
+
+
+ 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
+ size="default"
+ color="primary"
+ title="Map"
+ description="description"
+ items="[]"
+/>
Legacy mount name: data-component="Map".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"titlestringOptional "Map"descriptionstringOptional ""itemsstringOptional []variantstringOptional "default"classstringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/Map.wrn
component Map {
+ props {
+ size = "default"
+ color = "primary"
+ title = "Map"
+ description = ""
+ items = []
+ variant = "default"
+ class = ""
+ }
+ view {
+ <section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--map 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>
+ }
+}
+
+
+
+
+ }
+}
diff --git a/app/pages/components/marquee.wrn b/app/pages/components/marquee.wrn
new file mode 100644
index 00000000..59b5e4f3
--- /dev/null
+++ b/app/pages/components/marquee.wrn
@@ -0,0 +1,46 @@
+page Marqueecomponent {
+ seo {
+ title = "Marquee component"
+ description = "Theme-aware, responsive marquee component."
+ }
+
+ view {
+
+
+
+ W WRNexusJS
+
+
+
+ Browse documentation
+ base componentMarquee
Theme-aware, responsive marquee component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Marquee
+ size="default"
+ color="primary"
+ title="Marquee"
+ description="description"
+ items="[]"
+/>
Legacy mount name: data-component="Marquee".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"titlestringOptional "Marquee"descriptionstringOptional ""itemsstringOptional []variantstringOptional "default"classstringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/Marquee.wrn
component Marquee {
+ props {
+ size = "default"
+ color = "primary"
+ title = "Marquee"
+ description = ""
+ items = []
+ variant = "default"
+ class = ""
+ }
+ view {
+ <section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--marquee 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>
+ }
+}
+
+
+
+
+ }
+}
diff --git a/app/pages/components/mega-menu.wrn b/app/pages/components/mega-menu.wrn
index c71c7701..bad2947f 100644
--- a/app/pages/components/mega-menu.wrn
+++ b/app/pages/components/mega-menu.wrn
@@ -1,7 +1,7 @@
page MegaMenucomponent {
seo {
title = "MegaMenu component"
- description = "Reusable mega menu component."
+ description = "Theme-aware, responsive mega menu component."
}
view {
@@ -10,34 +10,34 @@ page MegaMenucomponent {
W WRNexusJS
-
+
Browse documentation
- overlays componentMegaMenu
Reusable mega menu component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<MegaMenu
- label="Explore"
- sections="[]"
-/>
Legacy mount name: data-component="MegaMenu".
Props and attributes
Prop Type Requirement Default labelstringOptional "Explore"sectionsstringOptional []classstringOptional ""
Slots
This component does not declare a slot.
Events
click
Source contract
Installed source: components/MegaMenu.wrn
component MegaMenu {
+ navigation componentMegaMenu
Theme-aware, responsive mega menu component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<MegaMenu
+ size="default"
+ color="primary"
+ label="Mega Menu"
+ items="[]"
+ active="active"
+/>
Legacy mount name: data-component="MegaMenu".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"labelstringOptional "Mega Menu"itemsstringOptional []activestringOptional ""orientationstringOptional "horizontal"classstringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/MegaMenu.wrn
component MegaMenu {
props {
- label = "Explore"
- sections = []
+ size = "default"
+ color = "primary"
+ label = "Mega Menu"
+ items = []
+ active = ""
+ orientation = "horizontal"
class = ""
}
- state open = false
view {
- <div class="wire-mega-menu {class}">
- <button type="button" class="wire-mega-menu__trigger" aria-expanded="{open}" @click="open = !open">{label}<span aria-hidden="true">⌄</span>
- </button>
- <div data-show="open" class="wire-mega-menu__panel">{#each sections as section}<section>
- <h3>{section.title}</h3>
- <ul>{#each section.items as item}<li>
- <a href="{item.href}">{item.label}</a>
- </li>{/each}</ul>
- </section>{/each}</div>
- </div>
+ <nav class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--mega-menu wire-next--{orientation} {class}" aria-label="{label}">
+ {#each items as item}<a href="{item.href}" aria-current="{item.value === active ? 'page' : ''}">{item.label}</a>{/each}
+ <slot />
+ </nav>
}
}
-
+
}
diff --git a/app/pages/components/modal.wrn b/app/pages/components/modal.wrn
index 4c871699..98206656 100644
--- a/app/pages/components/modal.wrn
+++ b/app/pages/components/modal.wrn
@@ -1,7 +1,7 @@
page Modalcomponent {
seo {
title = "Modal component"
- description = "Reusable modal component."
+ description = "Theme-aware, responsive modal component."
}
view {
@@ -10,46 +10,39 @@ page Modalcomponent {
W WRNexusJS
-
+
Browse documentation
- core componentModal
Reusable modal component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Modal
- title="Dialog"
+ overlays componentModal
Theme-aware, responsive modal component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Modal
+ size="default"
+ color="primary"
+ title="Modal"
description="description"
open="false"
- size="md"
- closeLabel="Close"
-/>
Legacy mount name: data-component="Modal".
Props and attributes
Prop Type Requirement Default classstringOptional ""titlestringOptional "Dialog"descriptionstringOptional ""openbooleanOptional falsesizestringOptional "md"closeLabelstringOptional "Close"
Slots
default
Events
click
Source contract
Installed source: components/Modal.wrn
component Modal {
+/>
Legacy mount name: data-component="Modal".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"titlestringOptional "Modal"descriptionstringOptional ""openbooleanOptional falseplacementstringOptional "bottom"closeLabelstringOptional "Close"classstringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/Modal.wrn
component Modal {
props {
- class = ""
- title = "Dialog"
+ size = "default"
+ color = "primary"
+ title = "Modal"
description = ""
open = false
- size = "md"
+ placement = "bottom"
closeLabel = "Close"
+ class = ""
}
- state visible = open
view {
- <div data-show="visible" class="fixed inset-0 z-50 flex items-end justify-center p-4 sm:items-center {class}" role="dialog" aria-modal="true" aria-labelledby="modal-title">
- <button class="absolute inset-0 bg-slate-950/60 backdrop-blur-sm" aria-label="{closeLabel}" @click="visible = false">
- </button>
- <section class="relative max-h-[90vh] w-full overflow-auto rounded-3xl border border-slate-200 bg-white p-6 shadow-2xl dark:border-slate-800 dark:bg-slate-900 {size === 'sm' ? 'max-w-md' : size === 'lg' ? 'max-w-4xl' : 'max-w-2xl'}">
- <header class="flex items-start justify-between gap-4">
- <div>
- <h2 id="modal-title" class="text-xl font-bold">{title}</h2>
- <p data-show="description" class="mt-1 text-sm text-slate-500">{description}</p>
- </div>
- <button type="button" aria-label="{closeLabel}" @click="visible = false" class="inline-flex size-10 items-center justify-center rounded-xl hover:bg-slate-100 dark:hover:bg-slate-800">×</button>
+ <div data-show="{open}" class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--modal wire-next--placement-{placement} {class}" role="dialog" aria-modal="true" aria-label="{title}">
+ <header>
+ <strong>{title}</strong>
+ <button type="button" aria-label="{closeLabel}">×</button>
</header>
- <div class="mt-5">
- <slot />
- </div>
- </section>
+ {#if description}<p>{description}</p>{/if}
+ <slot />
</div>
}
}
-
+
}
diff --git a/app/pages/components/nav.wrn b/app/pages/components/nav.wrn
new file mode 100644
index 00000000..27b449d7
--- /dev/null
+++ b/app/pages/components/nav.wrn
@@ -0,0 +1,44 @@
+page Navcomponent {
+ seo {
+ title = "Nav component"
+ description = "Theme-aware, responsive nav component."
+ }
+
+ view {
+
+
+
+ W WRNexusJS
+
+
+
+ Browse documentation
+ navigation componentNav
Theme-aware, responsive nav component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Nav
+ size="default"
+ color="primary"
+ label="Nav"
+ items="[]"
+ active="active"
+/>
Legacy mount name: data-component="Nav".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"labelstringOptional "Nav"itemsstringOptional []activestringOptional ""orientationstringOptional "horizontal"classstringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/Nav.wrn
component Nav {
+ props {
+ size = "default"
+ color = "primary"
+ label = "Nav"
+ items = []
+ active = ""
+ orientation = "horizontal"
+ class = ""
+ }
+ view {
+ <nav class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--nav wire-next--{orientation} {class}" aria-label="{label}">
+ {#each items as item}<a href="{item.href}" aria-current="{item.value === active ? 'page' : ''}">{item.label}</a>{/each}
+ <slot />
+ </nav>
+ }
+}
+
+
+
+
+ }
+}
diff --git a/app/pages/components/navbar.wrn b/app/pages/components/navbar.wrn
new file mode 100644
index 00000000..33002b02
--- /dev/null
+++ b/app/pages/components/navbar.wrn
@@ -0,0 +1,44 @@
+page Navbarcomponent {
+ seo {
+ title = "Navbar component"
+ description = "Theme-aware, responsive navbar component."
+ }
+
+ view {
+
+
+
+ W WRNexusJS
+
+
+
+ Browse documentation
+ navigation componentNavbar
Theme-aware, responsive navbar component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Navbar
+ size="default"
+ color="primary"
+ label="Navbar"
+ items="[]"
+ active="active"
+/>
Legacy mount name: data-component="Navbar".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"labelstringOptional "Navbar"itemsstringOptional []activestringOptional ""orientationstringOptional "horizontal"classstringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/Navbar.wrn
component Navbar {
+ props {
+ size = "default"
+ color = "primary"
+ label = "Navbar"
+ items = []
+ active = ""
+ orientation = "horizontal"
+ class = ""
+ }
+ view {
+ <nav class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--navbar wire-next--{orientation} {class}" aria-label="{label}">
+ {#each items as item}<a href="{item.href}" aria-current="{item.value === active ? 'page' : ''}">{item.label}</a>{/each}
+ <slot />
+ </nav>
+ }
+}
+
+
+
+
+ }
+}
diff --git a/app/pages/components/pagination.wrn b/app/pages/components/pagination.wrn
index e3d84d9d..b4f5b3db 100644
--- a/app/pages/components/pagination.wrn
+++ b/app/pages/components/pagination.wrn
@@ -1,7 +1,7 @@
page Paginationcomponent {
seo {
title = "Pagination component"
- description = "Reusable pagination component."
+ description = "Theme-aware, responsive pagination component."
}
view {
@@ -10,196 +10,34 @@ page Paginationcomponent {
W WRNexusJS
-
+
Browse documentation
- core componentPagination
Reusable pagination component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Pagination
- currentPage="1"
- totalPages="1"
- previousHref="previousHref"
- nextHref="nextHref"
- pages="[]"
-/>
Legacy mount name: data-component="Pagination".
Props and attributes
Prop Type Requirement Default classstringOptional ""currentPagenumberOptional 1totalPagesnumberOptional 1previousHrefstringOptional ""nextHrefstringOptional ""pagesstringOptional []showNumbersbooleanOptional trueshowSummarybooleanOptional truetotalItemsnumberOptional 0pageSizenumberOptional 10compactbooleanOptional falsecenteredbooleanOptional false
Slots
This component does not declare a slot.
Events
This component does not declare a custom event.
Source contract
Installed source: components/Pagination.wrn
component Pagination {
- props {
- class: string = ""
- currentPage = 1
- totalPages = 1
-
- previousHref = ""
- nextHref = ""
-
- pages = []
-
- showNumbers = true
- showSummary = true
-
- totalItems = 0
- pageSize = 10
-
- compact = false
- centered = false
- }
-
- view {
- <nav
- aria-label="Pagination"
- class="w-full {class}"
- class:hidden="totalPages <= 1"
- >
- <!-- Result summary -->
- <div
- class="mb-4 text-sm text-slate-500 dark:text-slate-400"
- class:hidden="!showSummary || totalItems <= 0"
- class:text-center="centered"
- >
- Showing
-
- <span class="font-semibold text-slate-950 dark:text-white">
- {(currentPage - 1) * pageSize + 1}
- </span>
-
- to
-
- <span class="font-semibold text-slate-950 dark:text-white">
- {currentPage * pageSize > totalItems ? totalItems : currentPage * pageSize}
- </span>
-
- of
-
- <span class="font-semibold text-slate-950 dark:text-white">
- {totalItems}
- </span>
-
- results
- </div>
- <div
- class="flex flex-col gap-4 sm:flex-row sm:items-center"
- class:sm:justify-center="centered"
- class:sm:justify-between="!centered"
- >
- <!-- Previous -->
- <a
- href="{previousHref}"
- aria-label="Go to previous page"
- class="group h-11 items-center justify-center gap-2 rounded-xl border border-slate-200 bg-white px-4 text-sm font-semibold text-slate-700 shadow-sm transition hover:-translate-y-0.5 hover:border-indigo-300 hover:bg-slate-50 hover:text-indigo-700 focus:outline-none focus-visible:ring-2 focus-visible:ring-indigo-500 dark:border-white/10 dark:bg-white/5 dark:text-slate-200 dark:hover:border-indigo-500/30 dark:hover:bg-white/10 dark:hover:text-indigo-300"
- class:hidden="previousHref === ''"
- class:inline-flex="previousHref !== ''"
- >
- <span class="icon-[lucide--arrow-left] h-4 w-4 transition-transform group-hover:-translate-x-0.5" aria-hidden="true" >
- </span>
- <span class:hidden="compact">
- Previous
- </span>
- </a>
- <span
- aria-disabled="true"
- class="h-11 cursor-not-allowed items-center justify-center gap-2 rounded-xl border border-slate-200 bg-slate-50 px-4 text-sm font-semibold text-slate-400 dark:border-white/10 dark:bg-white/[0.03] dark:text-slate-600"
- class:hidden="previousHref !== ''"
- class:inline-flex="previousHref === ''"
- >
- <span class="icon-[lucide--arrow-left] h-4 w-4" aria-hidden="true" >
- </span>
- <span class:hidden="compact">
- Previous
- </span>
- </span>
- <!-- Numbered pages -->
- <div
- class="flex flex-wrap items-center justify-center gap-1.5"
- class:hidden="!showNumbers"
- >
- {#each pages as page}
- <!-- Ellipsis -->
- <span
- class="grid h-10 w-10 place-items-center text-sm font-semibold text-slate-400"
- class:hidden="!page.ellipsis"
- >
- …
- </span>
- <!-- Page link -->
- <a
- href="{page.href}"
- aria-label="Go to page {page.number}"
- class="h-10 min-w-10 items-center justify-center rounded-xl px-3 text-sm font-semibold transition focus:outline-none focus-visible:ring-2 focus-visible:ring-indigo-500"
- class:hidden="page.ellipsis || page.current"
- class:inline-flex="!page.ellipsis && !page.current"
- class:border="!page.current"
- class:border-slate-200="!page.current"
- class:bg-white="!page.current"
- class:text-slate-600="!page.current"
- class:hover:border-indigo-300="!page.current"
- class:hover:bg-indigo-50="!page.current"
- class:hover:text-indigo-700="!page.current"
- class:dark:border-white/10="!page.current"
- class:dark:bg-white/5="!page.current"
- class:dark:text-slate-300="!page.current"
- class:dark:hover:border-indigo-500/30="!page.current"
- class:dark:hover:bg-indigo-500/10="!page.current"
- class:dark:hover:text-indigo-300="!page.current"
- >
- {page.number}
- </a>
- <!-- Current page -->
- <span
- aria-current="page"
- aria-label="Current page, page {page.number}"
- class="h-10 min-w-10 items-center justify-center rounded-xl bg-indigo-600 px-3 text-sm font-bold text-white shadow-lg shadow-indigo-600/20"
- class:hidden="page.ellipsis || !page.current"
- class:inline-flex="!page.ellipsis && page.current"
- >
- {page.number}
- </span>
- {/each}
- </div>
- <!-- Mobile page counter -->
- <div
- class="flex items-center justify-center rounded-xl border border-slate-200 bg-slate-50 px-4 py-2.5 text-sm font-medium text-slate-500 dark:border-white/10 dark:bg-white/5 dark:text-slate-400"
- class:hidden="showNumbers"
- >
- Page
-
- <span class="mx-1 font-bold text-slate-950 dark:text-white">
- {currentPage}
- </span>
-
- of
-
- <span class="ml-1 font-bold text-slate-950 dark:text-white">
- {totalPages}
- </span>
- </div>
- <!-- Next -->
- <a
- href="{nextHref}"
- aria-label="Go to next page"
- class="group h-11 items-center justify-center gap-2 rounded-xl bg-indigo-600 px-4 text-sm font-bold text-white shadow-lg shadow-indigo-600/20 transition hover:-translate-y-0.5 hover:bg-indigo-500 hover:shadow-xl focus:outline-none focus-visible:ring-2 focus-visible:ring-indigo-500 focus-visible:ring-offset-2 dark:focus-visible:ring-offset-slate-950"
- class:hidden="nextHref === ''"
- class:inline-flex="nextHref !== ''"
- >
- <span class:hidden="compact">
- Next
- </span>
- <span class="icon-[lucide--arrow-right] h-4 w-4 transition-transform group-hover:translate-x-0.5" aria-hidden="true" >
- </span>
- </a>
- <span
- aria-disabled="true"
- class="h-11 cursor-not-allowed items-center justify-center gap-2 rounded-xl border border-slate-200 bg-slate-50 px-4 text-sm font-semibold text-slate-400 dark:border-white/10 dark:bg-white/[0.03] dark:text-slate-600"
- class:hidden="nextHref !== ''"
- class:inline-flex="nextHref === ''"
- >
- <span class:hidden="compact">
- Next
- </span>
- <span class="icon-[lucide--arrow-right] h-4 w-4" aria-hidden="true" >
- </span>
- </span>
- </div>
+ navigation componentPagination
Theme-aware, responsive pagination component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Pagination
+ size="default"
+ color="primary"
+ label="Pagination"
+ items="[]"
+ active="active"
+/>
Legacy mount name: data-component="Pagination".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"labelstringOptional "Pagination"itemsstringOptional []activestringOptional ""orientationstringOptional "horizontal"classstringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/Pagination.wrn
component Pagination {
+ props {
+ size = "default"
+ color = "primary"
+ label = "Pagination"
+ items = []
+ active = ""
+ orientation = "horizontal"
+ class = ""
+ }
+ view {
+ <nav class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--pagination wire-next--{orientation} {class}" aria-label="{label}">
+ {#each items as item}<a href="{item.href}" aria-current="{item.value === active ? 'page' : ''}">{item.label}</a>{/each}
+ <slot />
</nav>
}
}
-
+
}
diff --git a/app/pages/components/pin-input.wrn b/app/pages/components/pin-input.wrn
index 552dac04..2366f6f4 100644
--- a/app/pages/components/pin-input.wrn
+++ b/app/pages/components/pin-input.wrn
@@ -1,7 +1,7 @@
page PinInputcomponent {
seo {
title = "PinInput component"
- description = "Reusable pin input component."
+ description = "Secure multi-cell PIN and verification-code input with regex and paste support."
}
view {
@@ -10,42 +10,130 @@ page PinInputcomponent {
W WRNexusJS
-
+
Browse documentation
- forms componentPinInput
Reusable pin input component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<PinInput
- label="Pin"
- name="name"
+ advanced-forms componentPinInput
Secure multi-cell PIN and verification-code input with regex and paste support.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<PinInput
+ size="default"
+ color="primary"
+ label="Verification code"
+ name="pin"
value="value"
- placeholder="placeholder"
- type="text"
-/>
Legacy mount name: data-component="PinInput".
Props and attributes
Prop Type Requirement Default labelstringOptional "Pin"namestringOptional ""valuestringOptional ""placeholderstringOptional ""typestringOptional "text"requiredbooleanOptional falsedisabledbooleanOptional falsereadonlybooleanOptional falsehelpstringOptional ""errorstringOptional ""classstringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/PinInput.wrn
component PinInput {
+/>
Legacy mount name: data-component="PinInput".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"labelstringOptional "Verification code"namestringOptional "pin"valuestringOptional ""lengthnumberOptional 4patternstringOptional "[0-9]"typestringOptional "text"inputModestringOptional "numeric"placeholderstringOptional "○"autocompletestringOptional "one-time-code"maskedbooleanOptional falsedisabledbooleanOptional falsereadonlybooleanOptional falserequiredbooleanOptional falseautoFocusbooleanOptional falseautoSubmitbooleanOptional falseallowPastebooleanOptional trueclearablebooleanOptional trueclearLabelstringOptional "Clear code"separatorstringOptional ""groupSizenumberOptional 0helpTextstringOptional ""invalidbooleanOptional falsevalidationMessagestringOptional ""classstringOptional ""
Slots
This component does not declare a slot.
Events
inputchangecompletepasteclearerror
Source contract
Installed source: components/PinInput.wrn
component PinInput {
props {
- label = "Pin"
- name = ""
+ size = "default"
+ color = "primary"
+ label = "Verification code"
+ name = "pin"
value = ""
- placeholder = ""
+ length = 4
+ pattern = "[0-9]"
type = "text"
- required = false
+ inputMode = "numeric"
+ placeholder = "○"
+ autocomplete = "one-time-code"
+ masked = false
disabled = false
readonly = false
- help = ""
- error = ""
+ required = false
+ autoFocus = false
+ autoSubmit = false
+ allowPaste = true
+ clearable = true
+ clearLabel = "Clear code"
+ separator = ""
+ groupSize = 0
+ helpText = ""
+ invalid = false
+ validationMessage = ""
class = ""
+ @event input = function
+ @event change = function
+ @event complete = function
+ @event paste = function
+ @event clear = function
+ @event error = function
}
+
+ functions {
+ function inputIndexes() {
+ return [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11].slice(
+ 0,
+ Math.max(1, Math.min(12, Number(length)))
+ )
+ }
+ }
+
view {
- <label class="wire-field wire-catalog-field {class}">
- <span class="wire-label">{label}<span data-show="required" class="wire-required"> *</span>
+ <fieldset
+ {...attrs}
+ class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--pin-input {invalid ? 'wire-next--invalid' : ''} {disabled ? 'wire-next--disabled' : ''} {class}"
+ data-wrn-pin-input
+ data-length="{length}"
+ data-pattern="{pattern}"
+ data-allow-paste="{allowPaste ? 'true' : 'false'}"
+ data-auto-submit="{autoSubmit ? 'true' : 'false'}"
+ data-value="{value}"
+ disabled="{disabled}"
+ aria-describedby="{validationMessage ? `${name}-validation` : helpText ? `${name}-help` : ''}"
+ >
+ <div class="wire-next__pin-heading">
+ <legend>{label}</legend>
+ <button
+ type="button"
+ class="wire-next__pin-clear"
+ data-pin-clear
+ aria-label="{clearLabel}"
+ title="{clearLabel}"
+ style="{clearable && value ? '' : 'display: none'}"
+ >
+ <span class="icon-[lucide--rotate-ccw]" aria-hidden="true">
</span>
- <input name="{name}" value="{value}" placeholder="{placeholder}" type="{type}" required="{required}" disabled="{disabled}" readonly="{readonly}" aria-invalid="{error ? 'true' : 'false'}" class="wire-input" />
- <span data-show="help && !error" class="wire-field-message wire-field-message--help">{help}</span>
- <span data-show="error" role="alert" class="wire-field-message wire-field-message--error">{error}</span>
- <slot />
- </label>
+ <span>{clearLabel}</span>
+ </button>
+ </div>
+ <div class="wire-next__pin-cells" role="group" aria-label="{label}">
+ {#each inputIndexes() as index}
+ <input
+ data-pin-cell
+ data-pin-index="{index}"
+ id="{name}-{index}"
+ type="{masked ? 'password' : type}"
+ inputmode="{inputMode}"
+ maxlength="1"
+ value="{value[index] || ''}"
+ placeholder="{placeholder}"
+ autocomplete="{index === 0 ? autocomplete : 'off'}"
+ aria-label="{label} digit {index + 1} of {length}"
+ aria-required="{required ? 'true' : 'false'}"
+ readonly="{readonly}"
+ disabled="{disabled}"
+ autofocus="{autoFocus && index === 0}"
+ />
+ {#if separator && groupSize !== 0 && (index + 1) % groupSize === 0 && index + 1 !== length}
+ <span class="wire-next__pin-separator" aria-hidden="true">{separator}</span>
+ {/if}
+ {/each}
+ </div>
+ <input
+ type="hidden"
+ name="{name}"
+ value="{value}"
+ required="{required}"
+ data-pin-value
+ />
+
+ {#if helpText && !validationMessage}<small id="{name}-help">{helpText}</small>{/if}
+ <small
+ id="{name}-validation"
+ class="wire-next__validation"
+ data-error="{name}"
+ >{validationMessage}</small>
+ </fieldset>
}
}
-
+
}
diff --git a/app/pages/components/popover.wrn b/app/pages/components/popover.wrn
index a6db927e..00fcc859 100644
--- a/app/pages/components/popover.wrn
+++ b/app/pages/components/popover.wrn
@@ -1,7 +1,7 @@
page Popovercomponent {
seo {
title = "Popover component"
- description = "Reusable popover component."
+ description = "Theme-aware, responsive popover component."
}
view {
@@ -10,37 +10,39 @@ page Popovercomponent {
W WRNexusJS
-
+
Browse documentation
- overlays componentPopover
Reusable popover component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Popover
- title="title"
+ overlays componentPopover
Theme-aware, responsive popover component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Popover
+ size="default"
+ color="primary"
+ title="Popover"
description="description"
open="false"
- closeLabel="Close"
-/>
Legacy mount name: data-component="Popover".
Props and attributes
Prop Type Requirement Default titlestringOptional ""descriptionstringOptional ""openbooleanOptional falsecloseLabelstringOptional "Close"classstringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/Popover.wrn
component Popover {
+/>
Legacy mount name: data-component="Popover".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"titlestringOptional "Popover"descriptionstringOptional ""openbooleanOptional falseplacementstringOptional "bottom"closeLabelstringOptional "Close"classstringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/Popover.wrn
component Popover {
props {
- title = ""
+ size = "default"
+ color = "primary"
+ title = "Popover"
description = ""
open = false
+ placement = "bottom"
closeLabel = "Close"
class = ""
}
view {
- <div data-show="open" class="wire-overlay wire-catalog-overlay {class}">
- <section role="dialog" aria-modal="true" aria-label="{title}" class="wire-dialog">
+ <div data-show="{open}" class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--popover wire-next--placement-{placement} {class}" role="region" aria-modal="false" aria-label="{title}">
<header>
- <h2 data-show="title" class="wire-dialog__title">{title}</h2>
- <p data-show="description" class="wire-dialog__description">{description}</p>
+ <strong>{title}</strong>
+ <button type="button" aria-label="{closeLabel}">×</button>
</header>
- <slot />
- <button type="button" class="wire-btn wire-btn--ghost">{closeLabel}</button>
- </section>
+ {#if description}<p>{description}</p>{/if}
+ <slot />
</div>
}
}
-
+
}
diff --git a/app/pages/components/progress.wrn b/app/pages/components/progress.wrn
index 47e61c13..196aa04a 100644
--- a/app/pages/components/progress.wrn
+++ b/app/pages/components/progress.wrn
@@ -1,7 +1,7 @@
-page progresscomponent {
+page Progresscomponent {
seo {
- title = "progress component"
- description = "Reusable progress component."
+ title = "Progress component"
+ description = "Theme-aware, responsive progress component."
}
view {
@@ -10,26 +10,36 @@ page progresscomponent {
W WRNexusJS
-
+
Browse documentation
- core componentprogress
Reusable progress component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<progress
- value="0"
+ base componentProgress
Theme-aware, responsive progress component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Progress
+ size="default"
+ color="primary"
+ label="Progress"
+ value="50"
max="100"
-/>
Legacy mount name: data-component="progress".
Props and attributes
Prop Type Requirement Default valuenumberOptional 0maxnumberOptional 100classstringOptional ""
Slots
This component does not declare a slot.
Events
This component does not declare a custom event.
Source contract
Installed source: components/progress.wrn
// Progress bar (native <progress>, themed).
-component Progress {
+/>
Legacy mount name: data-component="Progress".
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/Progress.wrn
component Progress {
props {
- value = 0
+ size = "default"
+ color = "primary"
+ label = "Progress"
+ value = 50
max = 100
+ showValue = true
class = ""
}
view {
- <progress class="wire-progress {class}" value="{value}" max="{max}">
+ <div class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--progress {class}">
+ <div class="wire-next__row">
+ <span>{label}</span>{#if showValue}<strong>{value}%</strong>{/if}</div>
+ <progress value="{value}" max="{max}">
</progress>
+ </div>
}
}
-
+
}
diff --git a/app/pages/components/radio.wrn b/app/pages/components/radio.wrn
index d97d810d..ad23c1a5 100644
--- a/app/pages/components/radio.wrn
+++ b/app/pages/components/radio.wrn
@@ -1,7 +1,7 @@
page Radiocomponent {
seo {
title = "Radio component"
- description = "Reusable radio component."
+ description = "Theme-aware, responsive radio component."
}
view {
@@ -10,38 +10,35 @@ page Radiocomponent {
W WRNexusJS
-
+
Browse documentation
- core componentRadio
Reusable radio component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Radio
- id="id"
- name="choice"
- value="value"
- label="Option"
- description="description"
-/>
Legacy mount name: data-component="Radio".
Props and attributes
Prop Type Requirement Default classstringOptional ""idstringOptional ""namestringOptional "choice"valuestringOptional ""labelstringOptional "Option"descriptionstringOptional ""checkedbooleanOptional falsedisabledbooleanOptional false
Slots
This component does not declare a slot.
Events
This component does not declare a custom event.
Source contract
Installed source: components/Radio.wrn
component Radio {
+ forms componentRadio
Theme-aware, responsive radio component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Radio
+ size="default"
+ color="primary"
+ label="Radio"
+ name="name"
+ value="on"
+/>
Legacy mount name: data-component="Radio".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"labelstringOptional "Radio"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/Radio.wrn
component Radio {
props {
- class = ""
- id = ""
- name = "choice"
- value = ""
- label = "Option"
- description = ""
+ size = "default"
+ color = "primary"
+ label = "Radio"
+ name = ""
+ value = "on"
checked = false
disabled = false
+ class = ""
}
view {
- <label for="{id}" class="flex min-h-11 cursor-pointer items-start gap-3 rounded-xl border border-slate-200 p-3 transition hover:border-violet-400 dark:border-slate-800 {class}">
- <input id="{id}" name="{name}" type="radio" value="{value}" checked="{checked}" disabled="{disabled}" class="mt-0.5 size-5 border-slate-300 text-violet-600 focus:ring-violet-500" />
- <span>
- <span class="block text-sm font-semibold">{label}</span>
- <span data-show="description" class="text-sm text-slate-500">{description}</span>
- </span>
+ <label class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--choice wire-next--radio {class}">
+ <input {...attrs} type="radio" name="{name}" value="{value}" checked="{checked}" disabled="{disabled}" />
+ <span>{label}</span>
</label>
}
}
-
+
}
diff --git a/app/pages/components/range-slider.wrn b/app/pages/components/range-slider.wrn
index 76d39f0a..0536cd33 100644
--- a/app/pages/components/range-slider.wrn
+++ b/app/pages/components/range-slider.wrn
@@ -1,7 +1,7 @@
page RangeSlidercomponent {
seo {
title = "RangeSlider component"
- description = "Reusable range slider component."
+ description = "Theme-aware, responsive range slider component."
}
view {
@@ -10,32 +10,40 @@ page RangeSlidercomponent {
W WRNexusJS
-
+
Browse documentation
- content componentRangeSlider
Reusable range slider component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<RangeSlider
- eyebrow="eyebrow"
- title="title"
- description="description"
- href="href"
- actionLabel="Learn more"
-/>
Legacy mount name: data-component="RangeSlider".
Props and attributes
Prop Type Requirement Default eyebrowstringOptional ""titlestringOptional ""descriptionstringOptional ""hrefstringOptional ""actionLabelstringOptional "Learn more"imagestringOptional ""altstringOptional ""classstringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/RangeSlider.wrn
component RangeSlider {
+ forms componentRangeSlider
Theme-aware, responsive range slider component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<RangeSlider
+ size="default"
+ color="primary"
+ label="Range Slider"
+ name="name"
+ value="value"
+/>
Legacy mount name: data-component="RangeSlider".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"labelstringOptional "Range Slider"namestringOptional ""valuestringOptional ""placeholderstringOptional ""typestringOptional "range"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/RangeSlider.wrn
component RangeSlider {
props {
- eyebrow = ""
- title = ""
- description = ""
- href = ""
- actionLabel = "Learn more"
- image = ""
- alt = ""
+ size = "default"
+ color = "primary"
+ label = "Range Slider"
+ name = ""
+ value = ""
+ placeholder = ""
+ type = "range"
+ min = ""
+ max = ""
+ step = ""
+ disabled = false
+ required = false
class = ""
}
view {
- <article class="wire-card wire-catalog-card {class}">{#if image}<img src="{image}" alt="{alt}" class="wire-catalog-card__image" />{/if}{#if eyebrow}<span class="wire-eyebrow">{eyebrow}</span>{/if}{#if title}<h3>{title}</h3>{/if}{#if description}<p>{description}</p>{/if}<slot />{#if href}<a href="{href}" class="wire-btn wire-btn--ghost">{actionLabel}</a>{/if}</article>
+ <label class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--field wire-next--range-slider {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>
}
}
-
+
}
diff --git a/app/pages/components/rating.wrn b/app/pages/components/rating.wrn
new file mode 100644
index 00000000..df81f02e
--- /dev/null
+++ b/app/pages/components/rating.wrn
@@ -0,0 +1,46 @@
+page Ratingcomponent {
+ seo {
+ title = "Rating component"
+ description = "Theme-aware, responsive rating component."
+ }
+
+ view {
+
+
+
+ W WRNexusJS
+
+
+
+ Browse documentation
+ base componentRating
Theme-aware, responsive rating component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Rating
+ size="default"
+ color="primary"
+ title="Rating"
+ description="description"
+ items="[]"
+/>
Legacy mount name: data-component="Rating".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"titlestringOptional "Rating"descriptionstringOptional ""itemsstringOptional []variantstringOptional "default"classstringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/Rating.wrn
component Rating {
+ props {
+ size = "default"
+ color = "primary"
+ title = "Rating"
+ description = ""
+ items = []
+ variant = "default"
+ class = ""
+ }
+ view {
+ <section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--rating 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>
+ }
+}
+
+
+
+
+ }
+}
diff --git a/app/pages/components/scrollspy.wrn b/app/pages/components/scrollspy.wrn
new file mode 100644
index 00000000..d0418a25
--- /dev/null
+++ b/app/pages/components/scrollspy.wrn
@@ -0,0 +1,44 @@
+page Scrollspycomponent {
+ seo {
+ title = "Scrollspy component"
+ description = "Theme-aware, responsive scrollspy component."
+ }
+
+ view {
+
+
+
+ W WRNexusJS
+
+
+
+ Browse documentation
+ navigation componentScrollspy
Theme-aware, responsive scrollspy component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Scrollspy
+ size="default"
+ color="primary"
+ label="Scrollspy"
+ items="[]"
+ active="active"
+/>
Legacy mount name: data-component="Scrollspy".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"labelstringOptional "Scrollspy"itemsstringOptional []activestringOptional ""orientationstringOptional "horizontal"classstringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/Scrollspy.wrn
component Scrollspy {
+ props {
+ size = "default"
+ color = "primary"
+ label = "Scrollspy"
+ items = []
+ active = ""
+ orientation = "horizontal"
+ class = ""
+ }
+ view {
+ <nav class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--scrollspy wire-next--{orientation} {class}" aria-label="{label}">
+ {#each items as item}<a href="{item.href}" aria-current="{item.value === active ? 'page' : ''}">{item.label}</a>{/each}
+ <slot />
+ </nav>
+ }
+}
+
+
+
+
+ }
+}
diff --git a/app/pages/components/search-box.wrn b/app/pages/components/search-box.wrn
new file mode 100644
index 00000000..6fdead4c
--- /dev/null
+++ b/app/pages/components/search-box.wrn
@@ -0,0 +1,50 @@
+page SearchBoxcomponent {
+ seo {
+ title = "SearchBox component"
+ description = "Theme-aware, responsive search box component."
+ }
+
+ view {
+
+
+
+ W WRNexusJS
+
+
+
+ Browse documentation
+ advanced-forms componentSearchBox
Theme-aware, responsive search box component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<SearchBox
+ size="default"
+ color="primary"
+ label="Search Box"
+ name="name"
+ value="value"
+/>
Legacy mount name: data-component="SearchBox".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"labelstringOptional "Search Box"namestringOptional ""valuestringOptional ""placeholderstringOptional ""typestringOptional "search"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/SearchBox.wrn
component SearchBox {
+ props {
+ size = "default"
+ color = "primary"
+ label = "Search Box"
+ name = ""
+ value = ""
+ placeholder = ""
+ type = "search"
+ min = ""
+ max = ""
+ step = ""
+ disabled = false
+ required = false
+ class = ""
+ }
+ view {
+ <label class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--field wire-next--search-box {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>
+ }
+}
+
+
+
+
+ }
+}
diff --git a/app/pages/components/select.wrn b/app/pages/components/select.wrn
index 1a353e75..cef3ec9e 100644
--- a/app/pages/components/select.wrn
+++ b/app/pages/components/select.wrn
@@ -1,7 +1,7 @@
page Selectcomponent {
seo {
title = "Select component"
- description = "Reusable select component."
+ description = "Theme-aware, responsive select component."
}
view {
@@ -10,40 +10,38 @@ page Selectcomponent {
W WRNexusJS
-
+
Browse documentation
- core componentSelect
Reusable select component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Select
- id="id"
- name="name"
+ forms componentSelect
Theme-aware, responsive select component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Select
+ size="default"
+ color="primary"
label="Select"
- help="help"
- error="error"
-/>
Legacy mount name: data-component="Select".
Props and attributes
Prop Type Requirement Default classstringOptional ""idstringOptional ""namestringOptional ""labelstringOptional "Select"helpstringOptional ""errorstringOptional ""requiredbooleanOptional falsedisabledbooleanOptional false
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/Select.wrn
component Select {
+ name="name"
+ value="value"
+/>
Legacy mount name: data-component="Select".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"labelstringOptional "Select"namestringOptional ""valuestringOptional ""optionsstringOptional []placeholderstringOptional "Select an option"multiplebooleanOptional falsedisabledbooleanOptional falseclassstringOptional ""
Slots
This component does not declare a slot.
Events
This component does not declare a custom event.
Source contract
Installed source: components/Select.wrn
component Select {
props {
- class = ""
- id = ""
- name = ""
+ size = "default"
+ color = "primary"
label = "Select"
- help = ""
- error = ""
- required = false
+ name = ""
+ value = ""
+ options = []
+ placeholder = "Select an option"
+ multiple = false
disabled = false
+ class = ""
}
view {
- <div class="space-y-2 {class}">
- <label for="{id}" class="block text-sm font-semibold text-slate-800 dark:text-slate-200">{label}<span data-show="required" class="ml-1 text-red-500">*</span>
+ <label class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--field wire-next--select {class}">
+ <span>{label}</span>
+ <select {...attrs} name="{name}" multiple="{multiple}" disabled="{disabled}">
+ <option value="">{placeholder}</option>{#each options as option}<option value="{option.value}" selected="{option.value === value}">{option.label}</option>{/each}</select>
</label>
- <select id="{id}" name="{name}" required="{required}" disabled="{disabled}" class="min-h-11 w-full rounded-xl border border-slate-300 bg-white px-3.5 py-2.5 text-slate-950 shadow-sm outline-none transition focus:border-violet-500 focus:ring-4 focus:ring-violet-500/10 dark:border-slate-700 dark:bg-slate-950 dark:text-white">
- <slot />
- </select>
- <p data-show="help && !error" class="text-sm text-slate-500">{help}</p>
- <p data-show="error" role="alert" class="text-sm font-medium text-red-600">{error}</p>
- </div>
}
}
-
+
}
diff --git a/app/pages/components/sidebar.wrn b/app/pages/components/sidebar.wrn
new file mode 100644
index 00000000..735c3e29
--- /dev/null
+++ b/app/pages/components/sidebar.wrn
@@ -0,0 +1,44 @@
+page Sidebarcomponent {
+ seo {
+ title = "Sidebar component"
+ description = "Theme-aware, responsive sidebar component."
+ }
+
+ view {
+
+
+
+ W WRNexusJS
+
+
+
+ Browse documentation
+ navigation componentSidebar
Theme-aware, responsive sidebar component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Sidebar
+ size="default"
+ color="primary"
+ label="Sidebar"
+ items="[]"
+ active="active"
+/>
Legacy mount name: data-component="Sidebar".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"labelstringOptional "Sidebar"itemsstringOptional []activestringOptional ""orientationstringOptional "horizontal"classstringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/Sidebar.wrn
component Sidebar {
+ props {
+ size = "default"
+ color = "primary"
+ label = "Sidebar"
+ items = []
+ active = ""
+ orientation = "horizontal"
+ class = ""
+ }
+ view {
+ <nav class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--sidebar wire-next--{orientation} {class}" aria-label="{label}">
+ {#each items as item}<a href="{item.href}" aria-current="{item.value === active ? 'page' : ''}">{item.label}</a>{/each}
+ <slot />
+ </nav>
+ }
+}
+
+
+
+
+ }
+}
diff --git a/app/pages/components/skeleton.wrn b/app/pages/components/skeleton.wrn
index 72e52c05..f534c9f3 100644
--- a/app/pages/components/skeleton.wrn
+++ b/app/pages/components/skeleton.wrn
@@ -1,7 +1,7 @@
page Skeletoncomponent {
seo {
title = "Skeleton component"
- description = "Reusable skeleton component."
+ description = "Theme-aware, responsive skeleton component."
}
view {
@@ -10,25 +10,32 @@ page Skeletoncomponent {
W WRNexusJS
-
+
Browse documentation
- feedback componentSkeleton
Reusable skeleton component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Skeleton
- height="4"
- rounded="lg"
-/>
Legacy mount name: data-component="Skeleton".
Props and attributes
Prop Type Requirement Default heightstringOptional "4"roundedstringOptional "lg"classNamestringOptional ""
Slots
This component does not declare a slot.
Events
This component does not declare a custom event.
Source contract
Installed source: components/Skeleton.wrn
component Skeleton {
+ base componentSkeleton
Theme-aware, responsive skeleton component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Skeleton
+ color="primary"
+ label="Loading"
+ size="md"
+ lines="3"
+/>
Legacy mount name: data-component="Skeleton".
Props and attributes
Prop Type Requirement Default colorstringOptional "primary"labelstringOptional "Loading"sizestringOptional "md"linesnumberOptional 3classstringOptional ""
Slots
This component does not declare a slot.
Events
This component does not declare a custom event.
Source contract
Installed source: components/Skeleton.wrn
component Skeleton {
props {
- height = "4"
- rounded = "lg"
- className = ""
+ color = "primary"
+ label = "Loading"
+ size = "md"
+ lines = 3
+ class = ""
}
view {
- <div aria-hidden="true" class="animate-pulse bg-slate-200 dark:bg-slate-800 h-{height} rounded-{rounded} {className}">
- </div>
+ <div class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--skeleton wire-next--size-{size} {class}" role="status" aria-label="{label}">
+ {#if "Skeleton" === "Skeleton"}{#each Array(lines).fill(0) as line}<span>
+ </span>{/each}{:else}<i aria-hidden="true">
+ </i>{/if}
+ </div>
}
}
-
+
}
diff --git a/app/pages/components/spinner.wrn b/app/pages/components/spinner.wrn
index 55f5ac9b..993b99b0 100644
--- a/app/pages/components/spinner.wrn
+++ b/app/pages/components/spinner.wrn
@@ -1,7 +1,7 @@
page Spinnercomponent {
seo {
title = "Spinner component"
- description = "Reusable spinner component."
+ description = "Theme-aware, responsive spinner component."
}
view {
@@ -10,25 +10,32 @@ page Spinnercomponent {
W WRNexusJS
-
+
Browse documentation
- core componentSpinner
Reusable spinner component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Spinner
+ base componentSpinner
Theme-aware, responsive spinner component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Spinner
+ color="primary"
label="Loading"
size="md"
-/>
Legacy mount name: data-component="Spinner".
Props and attributes
Prop Type Requirement Default classstringOptional ""labelstringOptional "Loading"sizestringOptional "md"
Slots
This component does not declare a slot.
Events
This component does not declare a custom event.
Source contract
Installed source: components/Spinner.wrn
component Spinner {
+ lines="3"
+/>
Legacy mount name: data-component="Spinner".
Props and attributes
Prop Type Requirement Default colorstringOptional "primary"labelstringOptional "Loading"sizestringOptional "md"linesnumberOptional 3classstringOptional ""
Slots
This component does not declare a slot.
Events
This component does not declare a custom event.
Source contract
Installed source: components/Spinner.wrn
component Spinner {
props {
- class = ""
+ color = "primary"
label = "Loading"
size = "md"
+ lines = 3
+ class = ""
}
view {
- <span role="status" aria-label="{label}" class="inline-block animate-spin rounded-full border-2 border-slate-300 border-r-violet-600 {size === 'sm' ? 'size-4' : size === 'lg' ? 'size-10' : 'size-6'} {class}">
- </span>
+ <div class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--spinner wire-next--size-{size} {class}" role="status" aria-label="{label}">
+ {#if "Spinner" === "Skeleton"}{#each Array(lines).fill(0) as line}<span>
+ </span>{/each}{:else}<i aria-hidden="true">
+ </i>{/if}
+ </div>
}
}
-
+
}
diff --git a/app/pages/components/stepper.wrn b/app/pages/components/stepper.wrn
index 21044876..e9e4666b 100644
--- a/app/pages/components/stepper.wrn
+++ b/app/pages/components/stepper.wrn
@@ -1,7 +1,7 @@
page Steppercomponent {
seo {
title = "Stepper component"
- description = "Reusable stepper component."
+ description = "Theme-aware, responsive stepper component."
}
view {
@@ -10,32 +10,34 @@ page Steppercomponent {
W WRNexusJS
-
+
Browse documentation
- content componentStepper
Reusable stepper component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Stepper
- eyebrow="eyebrow"
- title="title"
- description="description"
- href="href"
- actionLabel="Learn more"
-/>
Legacy mount name: data-component="Stepper".
Props and attributes
Prop Type Requirement Default eyebrowstringOptional ""titlestringOptional ""descriptionstringOptional ""hrefstringOptional ""actionLabelstringOptional "Learn more"imagestringOptional ""altstringOptional ""classstringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/Stepper.wrn
component Stepper {
+ navigation componentStepper
Theme-aware, responsive stepper component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Stepper
+ size="default"
+ color="primary"
+ label="Stepper"
+ items="[]"
+ active="active"
+/>
Legacy mount name: data-component="Stepper".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"labelstringOptional "Stepper"itemsstringOptional []activestringOptional ""orientationstringOptional "horizontal"classstringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/Stepper.wrn
component Stepper {
props {
- eyebrow = ""
- title = ""
- description = ""
- href = ""
- actionLabel = "Learn more"
- image = ""
- alt = ""
+ size = "default"
+ color = "primary"
+ label = "Stepper"
+ items = []
+ active = ""
+ orientation = "horizontal"
class = ""
}
view {
- <article class="wire-card wire-catalog-card {class}">{#if image}<img src="{image}" alt="{alt}" class="wire-catalog-card__image" />{/if}{#if eyebrow}<span class="wire-eyebrow">{eyebrow}</span>{/if}{#if title}<h3>{title}</h3>{/if}{#if description}<p>{description}</p>{/if}<slot />{#if href}<a href="{href}" class="wire-btn wire-btn--ghost">{actionLabel}</a>{/if}</article>
+ <nav class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--stepper wire-next--{orientation} {class}" aria-label="{label}">
+ {#each items as item}<a href="{item.href}" aria-current="{item.value === active ? 'page' : ''}">{item.label}</a>{/each}
+ <slot />
+ </nav>
}
}
-
+
}
diff --git a/app/pages/components/strong-password.wrn b/app/pages/components/strong-password.wrn
new file mode 100644
index 00000000..3053b3ef
--- /dev/null
+++ b/app/pages/components/strong-password.wrn
@@ -0,0 +1,264 @@
+page StrongPasswordcomponent {
+ seo {
+ title = "StrongPassword component"
+ description = "Theme-aware, responsive strong password component."
+ }
+
+ view {
+
+
+
+ W WRNexusJS
+
+
+
+ Browse documentation
+ advanced-forms componentStrongPassword
Theme-aware, responsive strong password component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<StrongPassword
+ size="default"
+ color="primary"
+ label="Password"
+ name="password"
+ value="value"
+/>
Legacy mount name: data-component="StrongPassword".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"labelstringOptional "Password"namestringOptional "password"valuestringOptional ""placeholderstringOptional "Create a strong password"autocompletestringOptional "new-password"minLengthnumberOptional 8specialCharactersSetstringOptional "!@#$%^&*()_+-=[]{}|;:,.<>?"requireLowercasebooleanOptional truerequireUppercasebooleanOptional truerequireNumberbooleanOptional truerequireSpecialCharacterbooleanOptional trueshowRequirementsbooleanOptional truepresentationstringOptional "inline"hintTextstringOptional "Use a unique password you do not use elsewhere."emptyLabelstringOptional "Enter a password"weakLabelstringOptional "Weak"fairLabelstringOptional "Fair"goodLabelstringOptional "Good"strongLabelstringOptional "Strong"disabledbooleanOptional falsereadonlybooleanOptional falserequiredbooleanOptional falseinvalidbooleanOptional falsevalidationMessagestringOptional ""classstringOptional ""
Slots
This component does not declare a slot.
Events
inputchangestrength
Source contract
Installed source: components/StrongPassword.wrn
component StrongPassword {
+ props {
+ size = "default"
+ color = "primary"
+ label = "Password"
+ name = "password"
+ value = ""
+ placeholder = "Create a strong password"
+ autocomplete = "new-password"
+ minLength = 8
+ specialCharactersSet = "!@#$%^&*()_+-=[]{}|;:,.<>?"
+ requireLowercase = true
+ requireUppercase = true
+ requireNumber = true
+ requireSpecialCharacter = true
+ showRequirements = true
+ presentation = "inline"
+ hintText = "Use a unique password you do not use elsewhere."
+ emptyLabel = "Enter a password"
+ weakLabel = "Weak"
+ fairLabel = "Fair"
+ goodLabel = "Good"
+ strongLabel = "Strong"
+ disabled = false
+ readonly = false
+ required = false
+ invalid = false
+ validationMessage = ""
+ class = ""
+ @event input = function
+ @event change = function
+ @event strength = function
+ }
+
+ state password = value
+ state detailsOpen = false
+
+ functions {
+ function hasMinimumLength() {
+ return password.length >= Number(minLength)
+ }
+
+ function hasLowercase() {
+ return password !== password.toUpperCase()
+ }
+
+ function hasUppercase() {
+ return password !== password.toLowerCase()
+ }
+
+ function hasNumber() {
+ return containsCharacterAt("0123456789", 0)
+ }
+
+ function hasSpecialCharacter() {
+ return containsCharacterAt(specialCharactersSet, 0)
+ }
+
+ function containsCharacterAt(characters, index) {
+ if (index >= characters.length) {
+ return false
+ }
+ if (password.includes(characters[index])) {
+ return true
+ }
+ return containsCharacterAt(characters, index + 1)
+ }
+
+ function score() {
+ return (hasMinimumLength() ? 1 : 0) + (requireLowercase && hasLowercase() ? 1 : 0) + (requireUppercase && hasUppercase() ? 1 : 0) + (requireNumber && hasNumber() ? 1 : 0) + (requireSpecialCharacter && hasSpecialCharacter() ? 1 : 0)
+ }
+
+ function maximumScore() {
+ return 1 + (requireLowercase ? 1 : 0) + (requireUppercase ? 1 : 0) + (requireNumber ? 1 : 0) + (requireSpecialCharacter ? 1 : 0)
+ }
+
+ function strengthPercent() {
+ return Math.round(score() / maximumScore() * 100)
+ }
+
+ function strengthLevel() {
+ if (!password) {
+ return "empty"
+ }
+ if (strengthPercent() <= 25) {
+ return "weak"
+ }
+ if (strengthPercent() <= 50) {
+ return "fair"
+ }
+ if (strengthPercent() < 100) {
+ return "good"
+ }
+ return "strong"
+ }
+
+ function strengthLabel() {
+ if (strengthLevel() === "weak") {
+ return weakLabel
+ }
+ if (strengthLevel() === "fair") {
+ return fairLabel
+ }
+ if (strengthLevel() === "good") {
+ return goodLabel
+ }
+ if (strengthLevel() === "strong") {
+ return strongLabel
+ }
+ return emptyLabel
+ }
+
+ }
+
+ view {
+ <div
+ class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--strong-password wire-next--strong-password-{presentation} {invalid ? 'wire-next--invalid' : ''} {disabled ? 'wire-next--disabled' : ''} {class}"
+ data-wrn-strong-password
+ data-strength="{password ? strengthLevel() : 'empty'}"
+ data-score="{password ? score() : 0}"
+ >
+ <label for="{name}-strong-password">{label}</label>
+ <div class="wire-next__strong-password-anchor">
+ <input
+ {...attrs}
+ id="{name}-strong-password"
+ type="password"
+ name="{name}"
+ value="{password}"
+ placeholder="{placeholder}"
+ autocomplete="{autocomplete}"
+ minlength="{minLength}"
+ disabled="{disabled}"
+ readonly="{readonly}"
+ required="{required}"
+ aria-invalid="{invalid ? 'true' : 'false'}"
+ aria-describedby="{validationMessage ? name + '-validation' : hintText ? name + '-hint' : ''}"
+ @focus="detailsOpen = true"
+ @blur="detailsOpen = false"
+ @input="password = event.target.value; $emit('input', { value: password, score: score(), maximumScore: maximumScore(), percent: strengthPercent(), level: strengthLevel() }); $emit('strength', { value: password, score: score(), maximumScore: maximumScore(), percent: strengthPercent(), level: strengthLevel() })"
+ @change="$emit('change', { value: password, score: score(), maximumScore: maximumScore(), percent: strengthPercent(), level: strengthLevel() })"
+ />
+
+ {#if presentation === "popover"}
+ <div
+ class="wire-next__strong-password-popover"
+ data-open="{detailsOpen ? 'true' : 'false'}"
+ role="status"
+ >
+ <div class="wire-next__strong-password-popover-arrow" aria-hidden="true">
+ </div>
+ <div class="wire-next__strong-password-details">
+ <div class="wire-next__strong-password-summary">
+ <span>Password strength</span>
+ <strong>{password ? strengthLabel() : emptyLabel}</strong>
+ </div>
+ <div
+ class="wire-next__strong-password-meter"
+ role="progressbar"
+ aria-label="Password strength"
+ aria-valuemin="0"
+ aria-valuemax="100"
+ aria-valuenow="{password ? strengthPercent() : 0}"
+ >
+ <span style="width: {password ? strengthPercent() : 0}%">
+ </span>
+ </div>
+ {#if showRequirements}
+ <ul class="wire-next__strong-password-requirements">
+ <li data-met="{password && hasMinimumLength() ? 'true' : 'false'}">
+ <span aria-hidden="true">
+ </span>At least {minLength} characters
+ </li>
+ {#if requireLowercase}<li data-met="{password && hasLowercase() ? 'true' : 'false'}">
+ <span aria-hidden="true">
+ </span>One lowercase letter</li>{/if}
+ {#if requireUppercase}<li data-met="{password && hasUppercase() ? 'true' : 'false'}">
+ <span aria-hidden="true">
+ </span>One uppercase letter</li>{/if}
+ {#if requireNumber}<li data-met="{password && hasNumber() ? 'true' : 'false'}">
+ <span aria-hidden="true">
+ </span>One number</li>{/if}
+ {#if requireSpecialCharacter}<li data-met="{password && hasSpecialCharacter() ? 'true' : 'false'}">
+ <span aria-hidden="true">
+ </span>One special character: {specialCharactersSet}</li>{/if}
+ </ul>
+ {/if}
+ {#if hintText}<small id="{name}-hint">{hintText}</small>{/if}
+ </div>
+ </div>
+ {/if}
+ </div>
+
+ {#if presentation !== "popover"}
+ <div class="wire-next__strong-password-details">
+ <div class="wire-next__strong-password-summary">
+ <span>Password strength</span>
+ <strong>{password ? strengthLabel() : emptyLabel}</strong>
+ </div>
+ <div
+ class="wire-next__strong-password-meter"
+ role="progressbar"
+ aria-label="Password strength"
+ aria-valuemin="0"
+ aria-valuemax="100"
+ aria-valuenow="{password ? strengthPercent() : 0}"
+ >
+ <span style="width: {password ? strengthPercent() : 0}%">
+ </span>
+ </div>
+ {#if showRequirements}
+ <ul class="wire-next__strong-password-requirements">
+ <li data-met="{password && hasMinimumLength() ? 'true' : 'false'}">
+ <span aria-hidden="true">
+ </span>At least {minLength} characters</li>
+ {#if requireLowercase}<li data-met="{password && hasLowercase() ? 'true' : 'false'}">
+ <span aria-hidden="true">
+ </span>One lowercase letter</li>{/if}
+ {#if requireUppercase}<li data-met="{password && hasUppercase() ? 'true' : 'false'}">
+ <span aria-hidden="true">
+ </span>One uppercase letter</li>{/if}
+ {#if requireNumber}<li data-met="{password && hasNumber() ? 'true' : 'false'}">
+ <span aria-hidden="true">
+ </span>One number</li>{/if}
+ {#if requireSpecialCharacter}<li data-met="{password && hasSpecialCharacter() ? 'true' : 'false'}">
+ <span aria-hidden="true">
+ </span>One special character: {specialCharactersSet}</li>{/if}
+ </ul>
+ {/if}
+ {#if hintText}<small id="{name}-hint">{hintText}</small>{/if}
+ </div>
+ {/if}
+
+ <small id="{name}-validation" class="wire-next__validation" data-error="{name}">{validationMessage}</small>
+ </div>
+ }
+}
+
+
+
+
+ }
+}
diff --git a/app/pages/components/styled-icon.wrn b/app/pages/components/styled-icon.wrn
new file mode 100644
index 00000000..5efc8d5c
--- /dev/null
+++ b/app/pages/components/styled-icon.wrn
@@ -0,0 +1,46 @@
+page StyledIconcomponent {
+ seo {
+ title = "StyledIcon component"
+ description = "Theme-aware, responsive styled icon component."
+ }
+
+ view {
+
+
+
+ W WRNexusJS
+
+
+
+ Browse documentation
+ base componentStyledIcon
Theme-aware, responsive styled icon component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<StyledIcon
+ size="default"
+ color="primary"
+ title="Styled Icon"
+ description="description"
+ items="[]"
+/>
Legacy mount name: data-component="StyledIcon".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"titlestringOptional "Styled Icon"descriptionstringOptional ""itemsstringOptional []variantstringOptional "default"classstringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/StyledIcon.wrn
component StyledIcon {
+ props {
+ size = "default"
+ color = "primary"
+ title = "Styled Icon"
+ description = ""
+ items = []
+ variant = "default"
+ class = ""
+ }
+ view {
+ <section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--styled-icon 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>
+ }
+}
+
+
+
+
+ }
+}
diff --git a/app/pages/components/switch.wrn b/app/pages/components/switch.wrn
index 57a9a853..3afc2e45 100644
--- a/app/pages/components/switch.wrn
+++ b/app/pages/components/switch.wrn
@@ -1,7 +1,7 @@
page Switchcomponent {
seo {
title = "Switch component"
- description = "Reusable switch component."
+ description = "Theme-aware, responsive switch component."
}
view {
@@ -10,42 +10,35 @@ page Switchcomponent {
W WRNexusJS
-
+
Browse documentation
- core componentSwitch
Reusable switch component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Switch
- id="id"
- name="name"
+ forms componentSwitch
Theme-aware, responsive switch component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Switch
+ size="default"
+ color="primary"
label="Switch"
- description="description"
- checked="false"
-/>
Legacy mount name: data-component="Switch".
Props and attributes
Prop Type Requirement Default classstringOptional ""idstringOptional ""namestringOptional ""labelstringOptional "Switch"descriptionstringOptional ""checkedbooleanOptional falsedisabledbooleanOptional false
Slots
This component does not declare a slot.
Events
click
Source contract
Installed source: components/Switch.wrn
component Switch {
+ name="name"
+ value="on"
+/>
Legacy mount name: data-component="Switch".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"labelstringOptional "Switch"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/Switch.wrn
component Switch {
props {
- class = ""
- id = ""
- name = ""
+ size = "default"
+ color = "primary"
label = "Switch"
- description = ""
+ name = ""
+ value = "on"
checked = false
disabled = false
+ class = ""
}
- state on = checked
view {
- <button id="{id}" type="button" role="switch" aria-checked="{on}" disabled="{disabled}" @click="on = !on" class="flex w-full items-center justify-between gap-4 rounded-xl p-2 text-left focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-violet-500 disabled:opacity-50 {class}">
- <span>
- <span class="block text-sm font-semibold">{label}</span>
- <span data-show="description" class="text-sm text-slate-500">{description}</span>
- </span>
- <span class="relative inline-flex h-6 w-11 shrink-0 rounded-full transition {on ? 'bg-violet-600' : 'bg-slate-300 dark:bg-slate-700'}">
- <span class="absolute top-0.5 size-5 rounded-full bg-white shadow transition-transform {on ? 'translate-x-5' : 'translate-x-0.5'}">
- </span>
- </span>
- <input type="hidden" name="{name}" value="{on ? 'true' : 'false'}" />
- </button>
+ <label class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--choice wire-next--switch {class}">
+ <input {...attrs} type="checkbox" name="{name}" value="{value}" checked="{checked}" disabled="{disabled}" />
+ <span>{label}</span>
+ </label>
}
}
-
+
}
diff --git a/app/pages/components/table.wrn b/app/pages/components/table.wrn
index 1307956a..d0986c5a 100644
--- a/app/pages/components/table.wrn
+++ b/app/pages/components/table.wrn
@@ -1,7 +1,7 @@
page Tablecomponent {
seo {
title = "Table component"
- description = "Reusable table component."
+ description = "Theme-aware, responsive table component."
}
view {
@@ -10,41 +10,40 @@ page Tablecomponent {
W WRNexusJS
-
+
Browse documentation
- data componentTable
Reusable table component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Table
- caption="Data table"
- responsive="true"
- striped="false"
- hoverable="true"
- compact="false"
-/>
Legacy mount name: data-component="Table".
Props and attributes
Prop Type Requirement Default classstringOptional ""captionstringOptional "Data table"responsivebooleanOptional truestripedbooleanOptional falsehoverablebooleanOptional truecompactbooleanOptional false
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/Table.wrn
component Table {
+ tables componentTable
Theme-aware, responsive table component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Table
+ size="default"
+ color="primary"
+ caption="Table"
+ columns="[]"
+ rows="[]"
+/>
Legacy mount name: data-component="Table".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"captionstringOptional "Table"columnsstringOptional []rowsstringOptional []stripedbooleanOptional trueclassstringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/Table.wrn
component Table {
props {
+ size = "default"
+ color = "primary"
+ caption = "Table"
+ columns = []
+ rows = []
+ striped = true
class = ""
- caption = "Data table"
- responsive = true
- striped = false
- hoverable = true
- compact = false
}
-
view {
- <div class="wire-table-wrap rounded-2xl border border-[var(--wire-color-border)] bg-[var(--wire-color-surface)] shadow-[var(--wire-shadow-sm)] {class}">
- <table
- class="wire-table min-w-[640px]"
- class:wire-table--striped='{striped}'
- class:wire-table--compact='{compact}'
- class:wire-table--hoverable='{hoverable}'
- >
- <caption class="wire-visually-hidden">{caption}</caption>
- <slot />
+ <div class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--table {class}">
+ <table>
+ <caption>{caption}</caption>
+ <thead>
+ <tr>{#each columns as column}<th>{column.label}</th>{/each}</tr>
+ </thead>
+ <tbody>{#each rows as row}<tr>{#each columns as column}<td>{row[column.key]}</td>{/each}</tr>{/each}</tbody>
</table>
+ <slot />
</div>
}
}
-
+
}
diff --git a/app/pages/components/tabs.wrn b/app/pages/components/tabs.wrn
index 762eddd4..dc7f520c 100644
--- a/app/pages/components/tabs.wrn
+++ b/app/pages/components/tabs.wrn
@@ -1,7 +1,7 @@
page Tabscomponent {
seo {
title = "Tabs component"
- description = "Reusable tabs component."
+ description = "Theme-aware, responsive tabs component."
}
view {
@@ -10,34 +10,34 @@ page Tabscomponent {
W WRNexusJS
-
+
Browse documentation
- content componentTabs
Reusable tabs component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Tabs
- active="first"
-/>
Legacy mount name: data-component="Tabs".
Props and attributes
Prop Type Requirement Default classstringOptional ""activestringOptional "first"
Slots
firstsecond
Events
click
Source contract
Installed source: components/Tabs.wrn
component Tabs {
+ navigation componentTabs
Theme-aware, responsive tabs component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Tabs
+ size="default"
+ color="primary"
+ label="Tabs"
+ items="[]"
+ active="active"
+/>
Legacy mount name: data-component="Tabs".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"labelstringOptional "Tabs"itemsstringOptional []activestringOptional ""orientationstringOptional "horizontal"classstringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/Tabs.wrn
component Tabs {
props {
+ size = "default"
+ color = "primary"
+ label = "Tabs"
+ items = []
+ active = ""
+ orientation = "horizontal"
class = ""
- active = "first"
}
- state current = active
view {
- <div class="{class}">
- <div role="tablist" class="flex gap-1 overflow-x-auto rounded-xl bg-slate-100 p-1 dark:bg-slate-800">
- <button role="tab" aria-selected="{current === 'first'}" @click="current = 'first'" class="min-h-10 flex-1 rounded-lg px-4 text-sm font-semibold transition {current === 'first' ? 'bg-white shadow dark:bg-slate-900' : 'text-slate-500'}">First</button>
- <button role="tab" aria-selected="{current === 'second'}" @click="current = 'second'" class="min-h-10 flex-1 rounded-lg px-4 text-sm font-semibold transition {current === 'second' ? 'bg-white shadow dark:bg-slate-900' : 'text-slate-500'}">Second</button>
- </div>
- <div data-show="current === 'first'" role="tabpanel" class="pt-5">
- <slot name="first" />
- </div>
- <div data-show="current === 'second'" role="tabpanel" class="pt-5">
- <slot name="second" />
- </div>
- </div>
+ <nav class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--tabs wire-next--{orientation} {class}" aria-label="{label}">
+ {#each items as item}<a href="{item.href}" aria-current="{item.value === active ? 'page' : ''}">{item.label}</a>{/each}
+ <slot />
+ </nav>
}
}
-
+
}
diff --git a/app/pages/components/textarea.wrn b/app/pages/components/textarea.wrn
index e4faef73..af5e9195 100644
--- a/app/pages/components/textarea.wrn
+++ b/app/pages/components/textarea.wrn
@@ -1,7 +1,7 @@
page Textareacomponent {
seo {
title = "Textarea component"
- description = "Reusable textarea component."
+ description = "Theme-aware, responsive textarea component."
}
view {
@@ -10,41 +10,37 @@ page Textareacomponent {
W WRNexusJS
-
+
Browse documentation
- core componentTextarea
Reusable textarea component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Textarea
- id="id"
+ forms componentTextarea
Theme-aware, responsive textarea component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Textarea
+ size="default"
+ color="primary"
+ label="Textarea"
name="name"
- label="Message"
value="value"
- placeholder="placeholder"
-/>
Legacy mount name: data-component="Textarea".
Props and attributes
Prop Type Requirement Default classstringOptional ""idstringOptional ""namestringOptional ""labelstringOptional "Message"valuestringOptional ""placeholderstringOptional ""rowsnumberOptional 5helpstringOptional ""errorstringOptional ""requiredbooleanOptional falsedisabledbooleanOptional false
Slots
This component does not declare a slot.
Events
This component does not declare a custom event.
Source contract
Installed source: components/Textarea.wrn
component Textarea {
+/>
Legacy mount name: data-component="Textarea".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"labelstringOptional "Textarea"namestringOptional ""valuestringOptional ""placeholderstringOptional ""rowsnumberOptional 5disabledbooleanOptional falserequiredbooleanOptional falseclassstringOptional ""
Slots
This component does not declare a slot.
Events
This component does not declare a custom event.
Source contract
Installed source: components/Textarea.wrn
component Textarea {
props {
- class = ""
- id = ""
+ size = "default"
+ color = "primary"
+ label = "Textarea"
name = ""
- label = "Message"
value = ""
placeholder = ""
rows = 5
- help = ""
- error = ""
- required = false
disabled = false
+ required = false
+ class = ""
}
view {
- <div class="space-y-2 {class}">
- <label for="{id}" class="block text-sm font-semibold text-slate-800 dark:text-slate-200">{label}<span data-show="required" class="ml-1 text-red-500">*</span>
+ <label class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--field wire-next--textarea {class}">
+ <span>{label}</span>
+ <textarea {...attrs} name="{name}" placeholder="{placeholder}" rows="{rows}" disabled="{disabled}" required="{required}">{value}</textarea>
</label>
- <textarea id="{id}" name="{name}" rows="{rows}" placeholder="{placeholder}" required="{required}" disabled="{disabled}" aria-invalid="{!!error}" class="w-full resize-y rounded-xl border bg-white px-3.5 py-3 text-slate-950 shadow-sm outline-none transition focus:border-violet-500 focus:ring-4 focus:ring-violet-500/10 dark:bg-slate-950 dark:text-white {error ? 'border-red-500' : 'border-slate-300 dark:border-slate-700'}">{value}</textarea>
- <p data-show="help && !error" class="text-sm text-slate-500">{help}</p>
- <p data-show="error" role="alert" class="text-sm font-medium text-red-600">{error}</p>
- </div>
}
}
-
+
}
diff --git a/app/pages/components/time-picker.wrn b/app/pages/components/time-picker.wrn
index eb8aa4e5..c3700c28 100644
--- a/app/pages/components/time-picker.wrn
+++ b/app/pages/components/time-picker.wrn
@@ -1,7 +1,7 @@
page TimePickercomponent {
seo {
title = "TimePicker component"
- description = "Reusable time picker component."
+ description = "Theme-aware, responsive time picker component."
}
view {
@@ -10,37 +10,40 @@ page TimePickercomponent {
W WRNexusJS
-
+
Browse documentation
- forms componentTimePicker
Reusable time picker component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<TimePicker
- id="time-picker"
- name="time"
- label="Time"
+ forms componentTimePicker
Theme-aware, responsive time picker component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<TimePicker
+ size="default"
+ color="primary"
+ label="Time Picker"
+ name="name"
value="value"
- min="min"
-/>
Legacy mount name: data-component="TimePicker".
Props and attributes
Prop Type Requirement Default idstringOptional "time-picker"namestringOptional "time"labelstringOptional "Time"valuestringOptional ""minstringOptional ""maxstringOptional ""stepnumberOptional 60requiredbooleanOptional falsedisabledbooleanOptional falseclassstringOptional ""
Slots
This component does not declare a slot.
Events
This component does not declare a custom event.
Source contract
Installed source: components/TimePicker.wrn
component TimePicker {
+/>
Legacy mount name: data-component="TimePicker".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"labelstringOptional "Time Picker"namestringOptional ""valuestringOptional ""placeholderstringOptional ""typestringOptional "time"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/TimePicker.wrn
component TimePicker {
props {
- id = "time-picker"
- name = "time"
- label = "Time"
+ size = "default"
+ color = "primary"
+ label = "Time Picker"
+ name = ""
value = ""
+ placeholder = ""
+ type = "time"
min = ""
max = ""
- step = 60
- required = false
+ step = ""
disabled = false
+ required = false
class = ""
}
view {
- <div class="wire-field {class}">
- <label for="{id}" class="wire-label">{label}</label>
- <input id="{id}" name="{name}" type="time" value="{value}" min="{min}" max="{max}" step="{step}" required="{required}" disabled="{disabled}" class="wire-input" />
- </div>
+ <label class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--field wire-next--time-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>
}
}
-
+
}
diff --git a/app/pages/components/timeline.wrn b/app/pages/components/timeline.wrn
index bdef7b4b..f52ea0ce 100644
--- a/app/pages/components/timeline.wrn
+++ b/app/pages/components/timeline.wrn
@@ -1,7 +1,7 @@
page Timelinecomponent {
seo {
title = "Timeline component"
- description = "Reusable timeline component."
+ description = "Theme-aware, responsive timeline component."
}
view {
@@ -10,27 +10,36 @@ page Timelinecomponent {
W WRNexusJS
-
+
Browse documentation
- visualization componentTimeline
Reusable timeline component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Timeline
+ base componentTimeline
Theme-aware, responsive timeline component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Timeline
+ size="default"
+ color="primary"
title="Timeline"
-/>
Legacy mount name: data-component="Timeline".
Props and attributes
Prop Type Requirement Default classstringOptional ""titlestringOptional "Timeline"
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/Timeline.wrn
component Timeline {
+ description="description"
+ items="[]"
+/>
Legacy mount name: data-component="Timeline".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"titlestringOptional "Timeline"descriptionstringOptional ""itemsstringOptional []variantstringOptional "default"classstringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/Timeline.wrn
component Timeline {
props {
- class = ""
+ size = "default"
+ color = "primary"
title = "Timeline"
+ description = ""
+ items = []
+ variant = "default"
+ class = ""
}
view {
- <section class="{class}">
- <h2 class="text-lg font-bold">{title}</h2>
- <ol class="mt-5 border-l border-slate-200 pl-6 dark:border-slate-800">
- <slot />
- </ol>
+ <section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--timeline 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>
}
}
-
+
}
diff --git a/app/pages/components/toast-notifications.wrn b/app/pages/components/toast-notifications.wrn
new file mode 100644
index 00000000..2bf0cb46
--- /dev/null
+++ b/app/pages/components/toast-notifications.wrn
@@ -0,0 +1,46 @@
+page ToastNotificationscomponent {
+ seo {
+ title = "ToastNotifications component"
+ description = "Theme-aware, responsive toast notifications component."
+ }
+
+ view {
+
+
+
+ W WRNexusJS
+
+
+
+ Browse documentation
+ integrations componentToastNotifications
Theme-aware, responsive toast notifications component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<ToastNotifications
+ size="default"
+ color="primary"
+ title="Toast Notifications"
+ description="description"
+ items="[]"
+/>
Legacy mount name: data-component="ToastNotifications".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"titlestringOptional "Toast Notifications"descriptionstringOptional ""itemsstringOptional []variantstringOptional "default"classstringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/ToastNotifications.wrn
component ToastNotifications {
+ props {
+ size = "default"
+ color = "primary"
+ title = "Toast Notifications"
+ description = ""
+ items = []
+ variant = "default"
+ class = ""
+ }
+ view {
+ <section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--toast-notifications 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>
+ }
+}
+
+
+
+
+ }
+}
diff --git a/app/pages/components/toast.wrn b/app/pages/components/toast.wrn
index cb68e7d7..fe6caaa4 100644
--- a/app/pages/components/toast.wrn
+++ b/app/pages/components/toast.wrn
@@ -1,7 +1,7 @@
page Toastcomponent {
seo {
title = "Toast component"
- description = "Reusable toast component."
+ description = "Theme-aware, responsive toast component."
}
view {
@@ -10,36 +10,36 @@ page Toastcomponent {
W WRNexusJS
-
+
Browse documentation
- core componentToast
Reusable toast component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Toast
- title="Saved"
+ base componentToast
Theme-aware, responsive toast component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Toast
+ size="default"
+ color="primary"
+ title="Toast"
description="description"
- variant="success"
- duration="5000"
-/>
Legacy mount name: data-component="Toast".
Props and attributes
Prop Type Requirement Default classstringOptional ""titlestringOptional "Saved"descriptionstringOptional ""variantstringOptional "success"durationnumberOptional 5000
Slots
This component does not declare a slot.
Events
click
Source contract
Installed source: components/Toast.wrn
component Toast {
+ items="[]"
+/>
Legacy mount name: data-component="Toast".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"titlestringOptional "Toast"descriptionstringOptional ""itemsstringOptional []variantstringOptional "default"classstringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/Toast.wrn
component Toast {
props {
- class = ""
- title = "Saved"
+ size = "default"
+ color = "primary"
+ title = "Toast"
description = ""
- variant = "success"
- duration = 5000
+ items = []
+ variant = "default"
+ class = ""
}
- state visible = true
view {
- <div data-show="visible" role="status" aria-live="polite" class="pointer-events-auto flex w-full max-w-sm items-start gap-3 rounded-2xl border bg-white p-4 shadow-2xl dark:border-slate-800 dark:bg-slate-900 {class}">
- <span class="mt-0.5 flex size-8 items-center justify-center rounded-full {variant === 'success' ? 'bg-emerald-100 text-emerald-700' : variant === 'danger' ? 'bg-red-100 text-red-700' : 'bg-blue-100 text-blue-700'}">{variant === 'success' ? '✓' : variant === 'danger' ? '!' : 'i'}</span>
- <div class="min-w-0 flex-1">
- <p class="font-semibold">{title}</p>
- <p data-show="description" class="mt-1 text-sm text-slate-500">{description}</p>
- </div>
- <button type="button" aria-label="Close" @click="visible = false" class="rounded-lg p-1 text-slate-400 hover:bg-slate-100">×</button>
- </div>
+ <section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--toast 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>
}
}
-
+
}
diff --git a/app/pages/components/toggle-count.wrn b/app/pages/components/toggle-count.wrn
new file mode 100644
index 00000000..8a844aed
--- /dev/null
+++ b/app/pages/components/toggle-count.wrn
@@ -0,0 +1,50 @@
+page ToggleCountcomponent {
+ seo {
+ title = "ToggleCount component"
+ description = "Theme-aware, responsive toggle count component."
+ }
+
+ view {
+
+
+
+ W WRNexusJS
+
+
+
+ Browse documentation
+ advanced-forms componentToggleCount
Theme-aware, responsive toggle count component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<ToggleCount
+ size="default"
+ color="primary"
+ label="Toggle Count"
+ name="name"
+ value="value"
+/>
Legacy mount name: data-component="ToggleCount".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"labelstringOptional "Toggle Count"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/ToggleCount.wrn
component ToggleCount {
+ props {
+ size = "default"
+ color = "primary"
+ label = "Toggle Count"
+ name = ""
+ value = ""
+ placeholder = ""
+ type = "text"
+ min = ""
+ max = ""
+ step = ""
+ disabled = false
+ required = false
+ class = ""
+ }
+ view {
+ <label class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--field wire-next--toggle-count {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>
+ }
+}
+
+
+
+
+ }
+}
diff --git a/app/pages/components/toggle-password.wrn b/app/pages/components/toggle-password.wrn
new file mode 100644
index 00000000..53ab7fe4
--- /dev/null
+++ b/app/pages/components/toggle-password.wrn
@@ -0,0 +1,182 @@
+page TogglePasswordcomponent {
+ seo {
+ title = "TogglePassword component"
+ description = "Accessible password field with optional show and hide controls."
+ }
+
+ view {
+
+
+
+ W WRNexusJS
+
+
+
+ Browse documentation
+ advanced-forms componentTogglePassword
Accessible password field with optional show and hide controls.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<TogglePassword
+ size="default"
+ color="primary"
+ label="Password"
+ name="password"
+ value="value"
+/>
Legacy mount name: data-component="TogglePassword".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"labelstringOptional "Password"namestringOptional "password"valuestringOptional ""placeholderstringOptional "Enter your password"autocompletestringOptional "current-password"minlengthstringOptional ""maxlengthstringOptional ""patternstringOptional "(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[^A-Za-z0-9]).{8,}"fieldsstringOptional []visiblebooleanOptional falsetoggleablebooleanOptional truetoggleModestringOptional "button"checkboxLabelstringOptional "Show password"showLabelstringOptional "Show password"hideLabelstringOptional "Hide password"disabledbooleanOptional falsereadonlybooleanOptional falserequiredbooleanOptional falseinvalidbooleanOptional falsehelpTextstringOptional ""validationMessagestringOptional ""classstringOptional ""
Slots
This component does not declare a slot.
Events
inputchangetoggle
Source contract
Installed source: components/TogglePassword.wrn
component TogglePassword {
+ props {
+ size = "default"
+ color = "primary"
+ label = "Password"
+ name = "password"
+ value = ""
+ placeholder = "Enter your password"
+ autocomplete = "current-password"
+ minlength = ""
+ maxlength = ""
+ pattern = "(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[^A-Za-z0-9]).{8,}"
+ fields = []
+ visible = false
+ toggleable = true
+ toggleMode = "button"
+ checkboxLabel = "Show password"
+ showLabel = "Show password"
+ hideLabel = "Hide password"
+ disabled = false
+ readonly = false
+ required = false
+ invalid = false
+ helpText = ""
+ validationMessage = ""
+ class = ""
+ @event input = function
+ @event change = function
+ @event toggle = function
+ }
+
+ state revealed = visible
+
+ functions {
+ function toggleVisibility() {
+ if (disabled || readonly || !toggleable) {
+ return
+ }
+ revealed = !revealed
+ }
+
+ function fieldId(field, index) {
+ return field.id || field.name || name + "-" + index
+ }
+
+ function fieldName(field, index) {
+ return field.name || name + "-" + index
+ }
+ }
+
+ view {
+ <fieldset
+ class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--toggle-password {invalid ? 'wire-next--invalid' : ''} {disabled ? 'wire-next--disabled' : ''} {class}"
+ data-wrn-toggle-password
+ data-visible="{revealed ? 'true' : 'false'}"
+ >
+ {#if fields.length}
+ <div class="wire-next__password-fields">
+ {#each fields as field, index}
+ <div class="wire-next__password-field">
+ <label for="{fieldId(field, index)}">{field.label || label}</label>
+ <div class="wire-next__password-control">
+ <input
+ id="{fieldId(field, index)}"
+ type="{revealed ? 'text' : 'password'}"
+ name="{fieldName(field, index)}"
+ value="{field.value || ''}"
+ placeholder="{field.placeholder || placeholder}"
+ autocomplete="{field.autocomplete || autocomplete}"
+ minlength="{field.minlength || minlength}"
+ maxlength="{field.maxlength || maxlength}"
+ pattern="{field.pattern || pattern}"
+ disabled="{disabled || field.disabled}"
+ readonly="{readonly || field.readonly}"
+ required="{required || field.required}"
+ aria-invalid="{invalid ? 'true' : 'false'}"
+ @input="$emit('input', { name: event.target.name, value: event.target.value, visible: revealed })"
+ @change="$emit('change', { name: event.target.name, value: event.target.value, visible: revealed })"
+ />
+ {#if toggleable && toggleMode === "button"}
+ <button
+ type="button"
+ class="wire-next__password-toggle"
+ aria-label="{revealed ? hideLabel : showLabel}"
+ title="{revealed ? hideLabel : showLabel}"
+ aria-pressed="{revealed ? 'true' : 'false'}"
+ disabled="{disabled || readonly}"
+ @click="toggleVisibility(); $emit('toggle', { visible: revealed })"
+ >
+ <span class="wire-next__password-icon wire-next__password-icon--show" aria-hidden="true">
+ </span>
+ </button>
+ {/if}
+ </div>
+ </div>
+ {/each}
+ </div>
+ {:else}
+ <label for="{name}-password">{label}</label>
+ <div class="wire-next__password-control">
+ <input
+ {...attrs}
+ id="{name}-password"
+ type="{revealed ? 'text' : 'password'}"
+ name="{name}"
+ value="{value}"
+ placeholder="{placeholder}"
+ autocomplete="{autocomplete}"
+ minlength="{minlength}"
+ maxlength="{maxlength}"
+ pattern="{pattern}"
+ disabled="{disabled}"
+ readonly="{readonly}"
+ required="{required}"
+ aria-invalid="{invalid ? 'true' : 'false'}"
+ aria-describedby="{validationMessage ? name + '-validation' : helpText ? name + '-help' : ''}"
+ @input="$emit('input', { value: event.target.value, visible: revealed })"
+ @change="$emit('change', { value: event.target.value, visible: revealed })"
+ />
+ {#if toggleable && toggleMode === "button"}
+ <button
+ type="button"
+ class="wire-next__password-toggle"
+ aria-label="{revealed ? hideLabel : showLabel}"
+ title="{revealed ? hideLabel : showLabel}"
+ aria-pressed="{revealed ? 'true' : 'false'}"
+ disabled="{disabled || readonly}"
+ @click="toggleVisibility(); $emit('toggle', { visible: revealed })"
+ >
+ <span class="wire-next__password-icon wire-next__password-icon--show" aria-hidden="true">
+ </span>
+ </button>
+ {/if}
+ </div>
+ {/if}
+ {#if toggleable && toggleMode === "checkbox"}
+ <label class="wire-next__password-checkbox">
+ <input
+ type="checkbox"
+ checked="{revealed}"
+ disabled="{disabled || readonly}"
+ @change="revealed = event.target.checked; $emit('toggle', { visible: revealed })"
+ />
+ <span>{checkboxLabel}</span>
+ </label>
+ {/if}
+ {#if helpText && !validationMessage}<small id="{name}-help">{helpText}</small>{/if}
+ <small
+ id="{name}-validation"
+ class="wire-next__validation"
+ data-error="{name}"
+ >{validationMessage}</small>
+ </fieldset>
+ }
+}
+
+
+
+
+ }
+}
diff --git a/app/pages/components/tooltip.wrn b/app/pages/components/tooltip.wrn
index a39f7bd4..243111f0 100644
--- a/app/pages/components/tooltip.wrn
+++ b/app/pages/components/tooltip.wrn
@@ -1,7 +1,7 @@
page Tooltipcomponent {
seo {
title = "Tooltip component"
- description = "Reusable tooltip component."
+ description = "Theme-aware, responsive tooltip component."
}
view {
@@ -10,27 +10,39 @@ page Tooltipcomponent {
W WRNexusJS
-
+
Browse documentation
- content componentTooltip
Reusable tooltip component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Tooltip
- text="Helpful information"
- position="top"
-/>
Legacy mount name: data-component="Tooltip".
Props and attributes
Prop Type Requirement Default classstringOptional ""textstringOptional "Helpful information"positionstringOptional "top"
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/Tooltip.wrn
component Tooltip {
+ overlays componentTooltip
Theme-aware, responsive tooltip component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Tooltip
+ size="default"
+ color="primary"
+ title="Tooltip"
+ description="description"
+ open="false"
+/>
Legacy mount name: data-component="Tooltip".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"titlestringOptional "Tooltip"descriptionstringOptional ""openbooleanOptional falseplacementstringOptional "bottom"closeLabelstringOptional "Close"classstringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/Tooltip.wrn
component Tooltip {
props {
+ size = "default"
+ color = "primary"
+ title = "Tooltip"
+ description = ""
+ open = false
+ placement = "bottom"
+ closeLabel = "Close"
class = ""
- text = "Helpful information"
- position = "top"
}
view {
- <span class="group relative inline-flex {class}">
- <slot />
- <span role="tooltip" class="pointer-events-none absolute z-40 w-max max-w-xs rounded-lg bg-slate-950 px-2.5 py-1.5 text-xs font-medium text-white opacity-0 shadow-lg transition duration-200 group-hover:opacity-100 group-focus-within:opacity-100 {position === 'bottom' ? 'left-1/2 top-full mt-2 -translate-x-1/2' : 'bottom-full left-1/2 mb-2 -translate-x-1/2'}">{text}</span>
- </span>
+ <div data-show="{open}" class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--tooltip wire-next--placement-{placement} {class}" role="region" aria-modal="false" aria-label="{title}">
+ <header>
+ <strong>{title}</strong>
+ <button type="button" aria-label="{closeLabel}">×</button>
+ </header>
+ {#if description}<p>{description}</p>{/if}
+ <slot />
+ </div>
}
}
-
+
}
diff --git a/app/pages/components/tree-view.wrn b/app/pages/components/tree-view.wrn
new file mode 100644
index 00000000..06f3b3c9
--- /dev/null
+++ b/app/pages/components/tree-view.wrn
@@ -0,0 +1,46 @@
+page TreeViewcomponent {
+ seo {
+ title = "TreeView component"
+ description = "Theme-aware, responsive tree view component."
+ }
+
+ view {
+
+
+
+ W WRNexusJS
+
+
+
+ Browse documentation
+ base componentTreeView
Theme-aware, responsive tree view component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<TreeView
+ size="default"
+ color="primary"
+ title="Tree View"
+ description="description"
+ items="[]"
+/>
Legacy mount name: data-component="TreeView".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"titlestringOptional "Tree View"descriptionstringOptional ""itemsstringOptional []variantstringOptional "default"classstringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/TreeView.wrn
component TreeView {
+ props {
+ size = "default"
+ color = "primary"
+ title = "Tree View"
+ description = ""
+ items = []
+ variant = "default"
+ class = ""
+ }
+ view {
+ <section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--tree-view 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>
+ }
+}
+
+
+
+
+ }
+}
diff --git a/app/pages/components/typography.wrn b/app/pages/components/typography.wrn
index 52e51f5a..d3927617 100644
--- a/app/pages/components/typography.wrn
+++ b/app/pages/components/typography.wrn
@@ -1,7 +1,7 @@
page Typographycomponent {
seo {
title = "Typography component"
- description = "Reusable typography component."
+ description = "Theme-aware, responsive typography component."
}
view {
@@ -10,28 +10,32 @@ page Typographycomponent {
W WRNexusJS
-
+
Browse documentation
- core componentTypography
Reusable typography component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Typography
- as="p"
- variant="body"
- align="start"
-/>
Legacy mount name: data-component="Typography".
Props and attributes
Prop Type Requirement Default asstringOptional "p"variantstringOptional "body"alignstringOptional "start"classstringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/Typography.wrn
component Typography {
+ layout componentTypography
Theme-aware, responsive typography component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<Typography
+ size="default"
+ color="primary"
+ columns="2"
+ gap="md"
+ maxWidth="xl"
+/>
Legacy mount name: data-component="Typography".
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/Typography.wrn
component Typography {
props {
- as = "p"
- variant = "body"
- align = "start"
+ size = "default"
+ color = "primary"
+ columns = 2
+ gap = "md"
+ maxWidth = "xl"
class = ""
}
view {
- <div class="wire-type wire-type--{variant} wire-text--{align} {class}">
+ <article class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--typography wire-next--gap-{gap} wire-next--columns-{columns} wire-next--max-{maxWidth} {class}">
<slot />
- </div>
+ </article>
}
}
-
+
}
diff --git a/app/pages/components/wysiwyg-editor.wrn b/app/pages/components/wysiwyg-editor.wrn
new file mode 100644
index 00000000..1647f826
--- /dev/null
+++ b/app/pages/components/wysiwyg-editor.wrn
@@ -0,0 +1,46 @@
+page WysiwygEditorcomponent {
+ seo {
+ title = "WysiwygEditor component"
+ description = "Theme-aware, responsive wysiwyg editor component."
+ }
+
+ view {
+
+
+
+ W WRNexusJS
+
+
+
+ Browse documentation
+ integrations componentWysiwygEditor
Theme-aware, responsive wysiwyg editor component.
Usage
Components are auto-discovered. Use the component directly in any .wrn view:
<WysiwygEditor
+ size="default"
+ color="primary"
+ title="Wysiwyg Editor"
+ description="description"
+ items="[]"
+/>
Legacy mount name: data-component="WysiwygEditor".
Props and attributes
Prop Type Requirement Default sizestringOptional "default"colorstringOptional "primary"titlestringOptional "Wysiwyg Editor"descriptionstringOptional ""itemsstringOptional []variantstringOptional "default"classstringOptional ""
Slots
default
Events
This component does not declare a custom event.
Source contract
Installed source: components/WysiwygEditor.wrn
component WysiwygEditor {
+ props {
+ size = "default"
+ color = "primary"
+ title = "Wysiwyg Editor"
+ description = ""
+ items = []
+ variant = "default"
+ class = ""
+ }
+ view {
+ <section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--wysiwyg-editor 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>
+ }
+}
+
+
+
+
+ }
+}
diff --git a/app/pages/packages.wrn b/app/pages/packages.wrn
index 4109cc37..d6e387ef 100644
--- a/app/pages/packages.wrn
+++ b/app/pages/packages.wrn
@@ -12,10 +12,10 @@ page Packages {
W WRNexusJS
-
+
Browse documentation
- 26 focused packagesPackage reference
Everything in the framework, organized by responsibility and documented from the published 0.3.4 APIs.
Showing {category} packages
+ 26 focused packagesPackage reference
Everything in the framework, organized by responsibility and documented from the published 0.3.5 APIs.
Showing {category} packages
AI@wrnexus/ai
Server-side Anthropic client with generation and streaming.
Open documentation →
@@ -93,7 +93,7 @@ page Packages {
Security@wrnexus/validation
Typed schemas, coercion, validation, and browser descriptors.
Open documentation →
-
+
}
diff --git a/app/pages/packages/ai.wrn b/app/pages/packages/ai.wrn
index ac37d84f..a1a86cdc 100644
--- a/app/pages/packages/ai.wrn
+++ b/app/pages/packages/ai.wrn
@@ -10,11 +10,11 @@ page wrnexusai {
W WRNexusJS
-
+
Browse documentation
- AI · Package reference@wrnexus/ai
Server-side Anthropic client with generation and streaming.
Install the package
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/ai@0.3.4
Request preview access. Never put registry tokens in source control.
A tiny, zero-dependency Claude (Anthropic) client for WRNexusJS apps — generate and stream text with Claude from any server-side code.
+ AI · Package reference@wrnexus/ai
Server-side Anthropic client with generation and streaming.
Install the package
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/ai@0.3.5
Request preview access. Never put registry tokens in source control.
A tiny, zero-dependency Claude (Anthropic) client for WRNexusJS apps — generate and stream text with Claude from any server-side code.
Part of the WRNexusJS framework — an SSR-first, Bun-native full-stack web framework.
Overview
@wrnexus/ai is a thin, dependency-free wrapper over the Anthropic Messages API, built on fetch (Bun-native, no SDK). Use it in API routes, jobs, or middleware to call Claude. It defaults to the most capable model, claude-opus-4-8, reads your key from ANTHROPIC_API_KEY, and supports both one-shot generation and streaming.
@@ -201,7 +201,7 @@ export const POST = async (ctx) => {
};
-
+
}
diff --git a/app/pages/packages/authz.wrn b/app/pages/packages/authz.wrn
index 4d80fa53..fe51329d 100644
--- a/app/pages/packages/authz.wrn
+++ b/app/pages/packages/authz.wrn
@@ -10,11 +10,11 @@ page wrnexusauthz {
W WRNexusJS
-
+
Browse documentation
- Security · Package reference@wrnexus/authz
Role, permission, policy, and authorization guards.
Install the package
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/authz@0.3.4
Request preview access. Never put registry tokens in source control.
Composable authorization for WRNexusJS — role-based (RBAC), policy-based (PBAC), and attribute-based (ABAC) access control that reduces to a boolean check plus an authorize() guard.
+ Security · Package reference@wrnexus/authz
Role, permission, policy, and authorization guards.
Install the package
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/authz@0.3.5
Request preview access. Never put registry tokens in source control.
Composable authorization for WRNexusJS — role-based (RBAC), policy-based (PBAC), and attribute-based (ABAC) access control that reduces to a boolean check plus an authorize() guard.
Part of the WRNexusJS framework — an SSR-first, Bun-native full-stack web framework.
Overview
@wrnexus/authz is a small, server-side authorization toolkit. It gives you three interchangeable models — RBAC (roles → permissions), PBAC (policy predicates), and ABAC (attribute matchers) — that all collapse to a boolean | Promise<boolean> decision. Wrap any decision in a Middleware guard (authorize, requireRole, requirePermission) to protect WRNexusJS routes. Reach for it whenever a route or action needs to be gated on who the user is, what roles they hold, or attributes of the user and the resource. It plugs into @wrnexus/core by reading ctx.user as the authorization subject.
@@ -226,7 +226,7 @@ app.put(
);
-
+
}
diff --git a/app/pages/packages/cli.wrn b/app/pages/packages/cli.wrn
index e86d4578..11a78910 100644
--- a/app/pages/packages/cli.wrn
+++ b/app/pages/packages/cli.wrn
@@ -10,11 +10,11 @@ page wrnexuscli {
W WRNexusJS
-
+
Browse documentation
- Tooling · Package reference@wrnexus/cli
Create, develop, build, generate, test, and maintain WRNexusJS apps.
Install the package
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/cli@0.3.4
Request preview access. Never put registry tokens in source control.
The wrnexus command-line tool that scaffolds, runs, builds, tests, and manages WRNexusJS apps.
+ Tooling · Package reference@wrnexus/cli
Create, develop, build, generate, test, and maintain WRNexusJS apps.
Install the package
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/cli@0.3.5
Request preview access. Never put registry tokens in source control.
The wrnexus command-line tool that scaffolds, runs, builds, tests, and manages WRNexusJS apps.
Part of the WRNexusJS framework — an SSR-first, Bun-native full-stack web framework.
Overview
@wrnexus/cli provides the wrnexus executable — the single entry point for developing a WRNexusJS app. It runs the HMR dev server, produces a self-contained production build, scaffolds apps/pages/components, drives database migrations, regenerates typed routes and queries, runs tests, and manages configuration profiles. It also scaffolds multi-app monorepos and serves them behind a domain-routing gateway. This is a CLI/build-time package (it shells out to the Bun binary for the dev child and tests) and it also exports the workspace config types via a subpath.
@@ -153,7 +153,7 @@ wrnexus update --latest
wrnexus doctor
-
+
}
diff --git a/app/pages/packages/compiler.wrn b/app/pages/packages/compiler.wrn
index 6a5cae16..697501f9 100644
--- a/app/pages/packages/compiler.wrn
+++ b/app/pages/packages/compiler.wrn
@@ -10,11 +10,11 @@ page wrnexuscompiler {
W WRNexusJS
-
+
Browse documentation
- Core · Package reference@wrnexus/compiler
Parser and code generators for the .wrn language.
Install the package
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/compiler@0.3.4
Request preview access. Never put registry tokens in source control.
Compiler for the .wrn language — tokenizes, parses, and lowers .wrn page and component files to TypeScript.
+ Core · Package reference@wrnexus/compiler
Parser and code generators for the .wrn language.
Install the package
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/compiler@0.3.5
Request preview access. Never put registry tokens in source control.
Compiler for the .wrn language — tokenizes, parses, and lowers .wrn page and component files to TypeScript.
Part of the WRNexusJS framework — an SSR-first, Bun-native full-stack web framework.
Overview
@wrnexus/compiler turns .wrn source into TypeScript that targets the framework's runtime primitives. A .wrn file declares either a page (a route) or a component (a reusable, prop-driven fragment) with blocks for state, view (plain HTML), seo, style, functions, api, ssr/client data bindings, and realtime websocket handlers. The pipeline is source → Lexer → parse() → PageAst → generate() → TypeScript. It is a build/server-side library — the WRNexusJS dev loader calls it to compile .wrn files on the fly, surfacing ParseError as a readable error page.
@@ -108,6 +108,7 @@ lx.next(); // { type: "lbrace", value: "{", pos: 1
layout = "<name>" — selects app/layouts/<name>.wrn (pages only).
types { <TypeScript declarations> } — reusable interfaces and aliases for the current file.
props { name: Type = <default> ... } — typed component props. Omit = <default> to make a prop required. Legacy inferred props remain supported.
+@event name = function inside props — declares a public component event. Emit it from component behavior with name(detail) or $emit("name", detail), and consume it with <Component @name="handler(event)" />.
state <ident>: Type = <expr> — typed reactive state seeded from a raw JS expression. The annotation is optional for backward compatibility.
view { <html> } — plain HTML with {expr} interpolation in text and attributes, hyphenated attributes, boolean attributes, @event="..." client bindings, and <!-- comments -->. Attribute expressions that reference state keep an SSR value and update reactively in the browser.
seo { key = "value" ... } — metadata merged into the generated meta.
@@ -123,7 +124,7 @@ lx.next(); // { type: "lbrace", value: "{", pos: 1
Pure TypeScript with no runtime dependencies; runs under Bun as part of the WRNexusJS toolchain (Node is not supported).
Generated modules target WRNexusJS runtime primitives (data-scope, data-text, data-on-*, data-for, data-component, __wrnexus*/__wire* helpers) — consume the output within a WRNexusJS app, e.g. via @wrnexus/core's dev loader.
Complete TypeScript API
Generated from the exact installed package declarations.
import { PageAst as PageAst$1, WrnDiagnostic } from '@wrnexus/syntax';
-export { ActionBlock, ApiBlock, Attr, ComputedDecl, DataApiBlock, DataMode, EffectBlock, LexError, Lexer, LoadBlock, ModeFunctionsBlock, PageAst, ParseError, PropDecl, RealtimeBlock, SeoBlock, StateDecl, ViewNode, WrnDiagnostic, assertValidAst, diagnose, diagnosticFromError, eraseFunctionTypes, formatDiagnostic, inferredRuntimeType, parse, runtimeTypeOf } from '@wrnexus/syntax';
+export { ActionBlock, ApiBlock, Attr, ComputedDecl, DataApiBlock, DataMode, EffectBlock, EventDecl, LexError, Lexer, LoadBlock, ModeFunctionsBlock, PageAst, ParseError, PropDecl, RealtimeBlock, SeoBlock, StateDecl, ViewNode, WrnDiagnostic, assertValidAst, diagnose, diagnosticFromError, eraseFunctionTypes, formatDiagnostic, inferredRuntimeType, parse, runtimeTypeOf } from '@wrnexus/syntax';
import { PageAst } from '@wrnexus/syntax/parser';
/**
@@ -207,7 +208,7 @@ lx.next(); // { type: "ident", value: "Home", pos: 5
lx.next(); // { type: "lbrace", value: "{", pos: 10 }
-
+
}
diff --git a/app/pages/packages/core.wrn b/app/pages/packages/core.wrn
index 2d771743..4c94e608 100644
--- a/app/pages/packages/core.wrn
+++ b/app/pages/packages/core.wrn
@@ -10,11 +10,11 @@ page wrnexuscore {
W WRNexusJS
-
+
Browse documentation
- Core · Package reference@wrnexus/core
Contexts, middleware, security, sessions, caching, JSX, and realtime.
Install the package
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/core@0.3.4
Request preview access. Never put registry tokens in source control.
The framework core: the request Context, middleware contract, and the security, session, caching, streaming, realtime, and JSX primitives every other WRNexusJS package builds on.
+ Core · Package reference@wrnexus/core
Contexts, middleware, security, sessions, caching, JSX, and realtime.
Install the package
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/core@0.3.5
Request preview access. Never put registry tokens in source control.
The framework core: the request Context, middleware contract, and the security, session, caching, streaming, realtime, and JSX primitives every other WRNexusJS package builds on.
Part of the WRNexusJS framework — an SSR-first, Bun-native full-stack web framework.
Overview
@wrnexus/core is the shared foundation of WRNexusJS. It defines the Context object that flows through every middleware, page, and API route, plus the Middleware/Next contract they implement. On top of that it ships the building blocks a real app needs: cookie-backed sessions, password auth, CSRF protection, rate limiting, request logging, HTTP + in-memory caching, file uploads, streaming/SSE responses, WebSocket "rooms", security headers/CORS, and a server-side JSX runtime that renders to HTML strings. Everything here is server-side and Bun-native (it uses Bun.password, Bun.write, the web-standard Request/Response, and crypto). You depend on it directly and transitively through the rest of the framework.
@@ -1136,7 +1136,7 @@ const registry = createRealtimeRegistry();
bridgeRealtime(registry, createPubSub(redisDriver(process.env.REDIS_URL)));
-
+
}
diff --git a/app/pages/packages/csr.wrn b/app/pages/packages/csr.wrn
index 84be933c..4c86aa9a 100644
--- a/app/pages/packages/csr.wrn
+++ b/app/pages/packages/csr.wrn
@@ -10,11 +10,11 @@ page wrnexuscsr {
W WRNexusJS
-
+
Browse documentation
- Frontend · Package reference@wrnexus/csr
Reactive, navigation, and realtime browser runtimes.
Install the package
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/csr@0.3.4
Request preview access. Never put registry tokens in source control.
The browser-side client runtime for WRNexusJS — generic, self-contained JS that hydrates server-rendered pages with reactivity, client-side navigation, and realtime rooms.
+ Frontend · Package reference@wrnexus/csr
Reactive, navigation, and realtime browser runtimes.
Install the package
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/csr@0.3.5
Request preview access. Never put registry tokens in source control.
The browser-side client runtime for WRNexusJS — generic, self-contained JS that hydrates server-rendered pages with reactivity, client-side navigation, and realtime rooms.
Part of the WRNexusJS framework — an SSR-first, Bun-native full-stack web framework.
Overview
@wrnexus/csr holds the three client runtimes that WRNexusJS serves to the browser. Components are authored as .wrn files and rendered on the server; this package provides the single, generic runtime that hydrates that HTML in the browser — there are no per-component browser bundles. Each runtime is exported as a plain-JS string (no build step, no imports) intended to be served verbatim from a well-known URL:
@@ -251,7 +251,7 @@ room.on("chat", (msg) => console.log(msg.user, msg.text));
room.send({ type: "chat", user: "ada", text: "hi" });
-
+
}
diff --git a/app/pages/packages/db.wrn b/app/pages/packages/db.wrn
index 9a9d36d9..45f6f322 100644
--- a/app/pages/packages/db.wrn
+++ b/app/pages/packages/db.wrn
@@ -10,11 +10,11 @@ page wrnexusdb {
W WRNexusJS
-
+
Browse documentation
- Data · Package reference@wrnexus/db
Database adapters, typed queries, models, migrations, and sessions.
Install the package
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/db@0.3.4
Request preview access. Never put registry tokens in source control.
The database layer for WRNexusJS: TS models as the single source of truth for DDL, validation, and result typing, plus a driver-based Db client, migrations, and a sqlc-style query generator.
+ Data · Package reference@wrnexus/db
Database adapters, typed queries, models, migrations, and sessions.
Install the package
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/db@0.3.5
Request preview access. Never put registry tokens in source control.
The database layer for WRNexusJS: TS models as the single source of truth for DDL, validation, and result typing, plus a driver-based Db client, migrations, and a sqlc-style query generator.
Part of the WRNexusJS framework — an SSR-first, Bun-native full-stack web framework.
Overview
@wrnexus/db is the server-side data layer. You describe tables as TypeScript models (the v column builder + table()); those models drive migrations, coerce raw DB rows into typed objects, and feed the query generator. A thin Driver interface is implemented by adapters for SQLite (bun:sqlite), Postgres/MySQL (Bun.SQL), and MongoDB. The Db client adds ergonomics — model-mapped all/one, transactions, createTable, pagination, and batched relation loading. A process-wide registry (getDb/setDb) exposes configured connections to pages and API routes. Reach for it whenever a WRNexusJS app needs persistence.
@@ -340,7 +340,7 @@ await repo.insert({ email: "a@b.com" });
const active = await repo.find({ active: true });
-
+
}
diff --git a/app/pages/packages/dev-server.wrn b/app/pages/packages/dev-server.wrn
index 2af2bddd..bc2024ec 100644
--- a/app/pages/packages/dev-server.wrn
+++ b/app/pages/packages/dev-server.wrn
@@ -10,11 +10,11 @@ page wrnexusdevserver {
W WRNexusJS
-
+
Browse documentation
- Runtime · Package reference@wrnexus/dev-server
Development and production servers, HMR, assets, and gateways.
Install the package
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/dev-server@0.3.4
Request preview access. Never put registry tokens in source control.
The WRNexusJS HTTP + WebSocket server runtime — request dispatch, SSR document assembly, live-reload (HMR), and the portable production handler.
+ Runtime · Package reference@wrnexus/dev-server
Development and production servers, HMR, assets, and gateways.
Install the package
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/dev-server@0.3.5
Request preview access. Never put registry tokens in source control.
The WRNexusJS HTTP + WebSocket server runtime — request dispatch, SSR document assembly, live-reload (HMR), and the portable production handler.
Part of the WRNexusJS framework — an SSR-first, Bun-native full-stack web framework.
Overview
This package is the server runtime that powers a WRNexusJS app in both development and production. A single request runtime (createHandlers) owns HTTP/WebSocket dispatch and SSR document assembly; it knows nothing about _how_ modules and assets are produced, so the dev and prod entry points wire in different backends: dev uses dynamic module loading plus on-the-fly bundling and injects a live-reload client; prod uses a static, pre-built manifest with cache-immutable assets. The package also ships a multi-app gateway (route several apps by Host header behind one port) and a portable node:http adapter for WinterCG hosts. It is entirely server-side and Bun-native (Bun.serve, Bun.file, Bun.gzipSync).
@@ -716,7 +716,7 @@ await startGateway({
});
-
+
}
diff --git a/app/pages/packages/encryption.wrn b/app/pages/packages/encryption.wrn
index 912687ad..a9295c63 100644
--- a/app/pages/packages/encryption.wrn
+++ b/app/pages/packages/encryption.wrn
@@ -10,11 +10,11 @@ page wrnexusencryption {
W WRNexusJS
-
+
Browse documentation
- Security · Package reference@wrnexus/encryption
Hashing, HMAC, authenticated encryption, and key derivation.
Install the package
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/encryption@0.3.4
Request preview access. Never put registry tokens in source control.
Dependency-free crypto helpers for WRNexusJS: authenticated symmetric encryption (AES-256-GCM), hashing, and HMAC signing.
+ Security · Package reference@wrnexus/encryption
Hashing, HMAC, authenticated encryption, and key derivation.
Install the package
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/encryption@0.3.5
Request preview access. Never put registry tokens in source control.
Dependency-free crypto helpers for WRNexusJS: authenticated symmetric encryption (AES-256-GCM), hashing, and HMAC signing.
Part of the WRNexusJS framework — an SSR-first, Bun-native full-stack web framework.
Overview
This package provides small, focused cryptographic primitives for server-side use: encrypting secrets/tokens/database fields at rest with AES-256-GCM, deriving keys from passwords via PBKDF2, computing SHA-256 digests, and signing/verifying payloads with HMAC-SHA256. It is built entirely on the standard Web Crypto API (crypto.subtle) plus btoa/atob and TextEncoder/TextDecoder — no third-party dependencies. Reach for it whenever you need to protect sensitive values or verify webhook signatures. All functions are async (Web Crypto is promise-based).
@@ -107,7 +107,7 @@ const ok = await hmacVerify(rawBody, webhookSecret, incomingSignatureHeader);
if (!ok) throw new Error("Invalid webhook signature");
-
+
}
diff --git a/app/pages/packages/helpers.wrn b/app/pages/packages/helpers.wrn
index d79c864f..df49b82c 100644
--- a/app/pages/packages/helpers.wrn
+++ b/app/pages/packages/helpers.wrn
@@ -10,11 +10,11 @@ page wrnexushelpers {
W WRNexusJS
-
+
Browse documentation
- Tooling · Package reference@wrnexus/helpers
Safe Context URL helpers and forward-auth login redirects.
Install the package
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/helpers@0.3.4
Request preview access. Never put registry tokens in source control.
Safe convenience helpers for common WRNexusJS application flows. The package uses standard Context, URL, and Response values and has no runtime dependency beyond @wrnexus/core.
+ Tooling · Package reference@wrnexus/helpers
Safe Context URL helpers and forward-auth login redirects.
Install the package
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/helpers@0.3.5
Request preview access. Never put registry tokens in source control.
Safe convenience helpers for common WRNexusJS application flows. The package uses standard Context, URL, and Response values and has no runtime dependency beyond @wrnexus/core.
bun add @wrnexus/helpers
The package is private, so the machine must be authenticated to the wrnexus npm organization.
Usage
@@ -135,7 +135,7 @@ export const GET = async (ctx: Context) => {
};
-
+
}
diff --git a/app/pages/packages/i18n.wrn b/app/pages/packages/i18n.wrn
index a019cb54..0b152a68 100644
--- a/app/pages/packages/i18n.wrn
+++ b/app/pages/packages/i18n.wrn
@@ -10,11 +10,11 @@ page wrnexusi18n {
W WRNexusJS
-
+
Browse documentation
- Frontend · Package reference@wrnexus/i18n
Translation loading, locale resolution, and Intl formatting.
Install the package
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/i18n@0.3.4
Request preview access. Never put registry tokens in source control.
Per-request translations plus locale-aware number, date, and currency formatting for WRNexusJS apps.
+ Frontend · Package reference@wrnexus/i18n
Translation loading, locale resolution, and Intl formatting.
Install the package
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/i18n@0.3.5
Request preview access. Never put registry tokens in source control.
Per-request translations plus locale-aware number, date, and currency formatting for WRNexusJS apps.
Part of the WRNexusJS framework — an SSR-first, Bun-native full-stack web framework.
Overview
@wrnexus/i18n loads locale files from app/locales/<lang>.json, resolves the active language for each request (cookie → Accept-Language → default), and builds a t(key, params) translator used both in server code and in .wrn views. It also ships Intl-based formatting helpers and a tiny client runtime that wires up a language switcher. Translation lookup, language resolution, and HTML marker rewriting run server-side; only the small I18N_RUNTIME snippet runs in the browser.
@@ -231,7 +231,7 @@ formatRelativeTime(-3, "day", lang); // "3 days ago"
plural(2, { one: "# item", other: "# items" }, lang); // "2 items"
-
+
}
diff --git a/app/pages/packages/jwt.wrn b/app/pages/packages/jwt.wrn
index ed52befe..10e889b0 100644
--- a/app/pages/packages/jwt.wrn
+++ b/app/pages/packages/jwt.wrn
@@ -10,11 +10,11 @@ page wrnexusjwt {
W WRNexusJS
-
+
Browse documentation
- Security · Package reference@wrnexus/jwt
HS256 JWT signing, verification, and bearer authentication.
Install the package
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/jwt@0.3.4
Request preview access. Never put registry tokens in source control.
Dependency-free JSON Web Tokens (HS256) via Web Crypto, plus a bearer-token auth middleware for WRNexusJS.
+ Security · Package reference@wrnexus/jwt
HS256 JWT signing, verification, and bearer authentication.
Install the package
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/jwt@0.3.5
Request preview access. Never put registry tokens in source control.
Dependency-free JSON Web Tokens (HS256) via Web Crypto, plus a bearer-token auth middleware for WRNexusJS.
Part of the WRNexusJS framework — an SSR-first, Bun-native full-stack web framework.
Overview
@wrnexus/jwt signs and verifies stateless JSON Web Tokens using the HS256 (HMAC-SHA-256) algorithm. It has no runtime dependencies — signing and verification are implemented directly on the standard Web Crypto API (crypto.subtle), which Bun provides natively. It runs server-side and pairs with the session-based auth in @wrnexus/core, giving you a stateless option for API and mobile clients. Reach for it when you need bearer-token auth rather than cookie sessions.
@@ -164,7 +164,7 @@ app.use(jwtAuth({ secret: process.env.JWT_SECRET! }));
app.use(jwtAuth({ secret: process.env.JWT_SECRET!, required: false }));
-
+
}
diff --git a/app/pages/packages/mobile.wrn b/app/pages/packages/mobile.wrn
index 4c8d0573..04931a90 100644
--- a/app/pages/packages/mobile.wrn
+++ b/app/pages/packages/mobile.wrn
@@ -10,11 +10,11 @@ page wrnexusmobile {
W WRNexusJS
-
+
Browse documentation
- Native · Package reference@wrnexus/mobile
SSR-safe compatibility access to Capacitor plugins.
Install the package
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/mobile@0.3.4
Request preview access. Never put registry tokens in source control.
SSR-safe access to Capacitor plugins from WRNexusJS browser code.
+ Native · Package reference@wrnexus/mobile
SSR-safe compatibility access to Capacitor plugins.
Install the package
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/mobile@0.3.5
Request preview access. Never put registry tokens in source control.
SSR-safe access to Capacitor plugins from WRNexusJS browser code.
Overview
@wrnexus/mobile keeps optional native imports out of server rendering while giving browser-owned modules one consistent registry for Capacitor plugins. During SSR, mobile.isNative() is false and mobile.platform() is "web".
Install a plugin through the WRNexusJS CLI so the web and native projects stay aligned:
@@ -131,7 +131,7 @@ const network = mobile.plugin<NetworkPlugin>("Network");
const status = network ? await network.getStatus() : { connected: true, connectionType: "unknown" };
-
+
}
diff --git a/app/pages/packages/native.wrn b/app/pages/packages/native.wrn
index d2f35e4b..83b8390d 100644
--- a/app/pages/packages/native.wrn
+++ b/app/pages/packages/native.wrn
@@ -10,11 +10,11 @@ page wrnexusnative {
W WRNexusJS
-
+
Browse documentation
- Native · Package reference@wrnexus/native
Cross-platform browser and Capacitor capability registry.
Install the package
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/native@0.3.4
Request preview access. Never put registry tokens in source control.
Cross-platform capabilities for browsers, Capacitor WebViews, and compiled native apps.
+ Native · Package reference@wrnexus/native
Cross-platform browser and Capacitor capability registry.
Install the package
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/native@0.3.5
Request preview access. Never put registry tokens in source control.
Cross-platform capabilities for browsers, Capacitor WebViews, and compiled native apps.
Overview
@wrnexus/native exposes capabilities by name so application code can ask what the current platform supports before presenting an action. Browser capabilities use Web APIs; mobile capabilities use installed Capacitor plugins. platform() returns "server" during SSR, "browser" on the web, and the Capacitor platform in a native WebView.
bun add @wrnexus/native
@@ -123,7 +123,7 @@ const position = await native.run(
);
-
+
}
diff --git a/app/pages/packages/oauth.wrn b/app/pages/packages/oauth.wrn
index 7c4fcc7c..914c30ce 100644
--- a/app/pages/packages/oauth.wrn
+++ b/app/pages/packages/oauth.wrn
@@ -10,11 +10,11 @@ page wrnexusoauth {
W WRNexusJS
-
+
Browse documentation
- Security · Package reference@wrnexus/oauth
OAuth 2.0, PKCE, provider presets, and profile mapping.
Install the package
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/oauth@0.3.4
Request preview access. Never put registry tokens in source control.
Dependency-free OAuth 2.0 sign-in for any provider, with PKCE and presets for Google, GitHub, and Discord.
+ Security · Package reference@wrnexus/oauth
OAuth 2.0, PKCE, provider presets, and profile mapping.
Install the package
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/oauth@0.3.5
Request preview access. Never put registry tokens in source control.
Dependency-free OAuth 2.0 sign-in for any provider, with PKCE and presets for Google, GitHub, and Discord.
Part of the WRNexusJS framework — an SSR-first, Bun-native full-stack web framework.
Overview
@wrnexus/oauth implements the OAuth 2.0 Authorization Code flow (with PKCE) for server-side sign-in. It ships ready-made provider presets and a defineProvider helper for custom providers, then gives you two flow functions — startAuth (build the redirect) and completeAuth (exchange the code and fetch the user's profile). It has no runtime dependencies: it uses the platform fetch and WebCrypto only. Pairs naturally with @wrnexus/core's logIn to establish a session once you have a normalized profile.
@@ -286,7 +286,7 @@ const gitlab = defineProvider({
});
-
+
}
diff --git a/app/pages/packages/pubsub.wrn b/app/pages/packages/pubsub.wrn
index 78b309ef..c30ef299 100644
--- a/app/pages/packages/pubsub.wrn
+++ b/app/pages/packages/pubsub.wrn
@@ -10,11 +10,11 @@ page wrnexuspubsub {
W WRNexusJS
-
+
Browse documentation
- Realtime · Package reference@wrnexus/pubsub
In-process and Redis-backed publish/subscribe.
Install the package
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/pubsub@0.3.4
Request preview access. Never put registry tokens in source control.
Topic-based publish/subscribe with a pluggable driver — in-process by default, Redis for cross-process messaging.
+ Realtime · Package reference@wrnexus/pubsub
In-process and Redis-backed publish/subscribe.
Install the package
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/pubsub@0.3.5
Request preview access. Never put registry tokens in source control.
Topic-based publish/subscribe with a pluggable driver — in-process by default, Redis for cross-process messaging.
Part of the WRNexusJS framework — an SSR-first, Bun-native full-stack web framework.
Overview
@wrnexus/pubsub is a small server-side pub/sub bus. You publish messages to a topic and subscribe with topic patterns; handlers fire for matching topics. The default driver keeps everything in-process, and you can swap in the Redis driver (@wrnexus/pubsub/redis) to fan messages out across processes or hosts. It also backs @wrnexus/core's realtime bridge for horizontal scaling.
@@ -146,7 +146,7 @@ await bus.publish("order:created", { id: 7 });
driver.close();
-
+
}
diff --git a/app/pages/packages/queue.wrn b/app/pages/packages/queue.wrn
index f5769f0d..03d32e22 100644
--- a/app/pages/packages/queue.wrn
+++ b/app/pages/packages/queue.wrn
@@ -10,11 +10,11 @@ page wrnexusqueue {
W WRNexusJS
-
+
Browse documentation
- Data · Package reference@wrnexus/queue
Background jobs with delay, concurrency, retry, and repetition.
Install the package
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/queue@0.3.4
Request preview access. Never put registry tokens in source control.
A background job queue with delays, retries + exponential backoff, recurring jobs, and concurrent workers.
+ Data · Package reference@wrnexus/queue
Background jobs with delay, concurrency, retry, and repetition.
Install the package
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/queue@0.3.5
Request preview access. Never put registry tokens in source control.
A background job queue with delays, retries + exponential backoff, recurring jobs, and concurrent workers.
Part of the WRNexusJS framework — an SSR-first, Bun-native full-stack web framework.
Overview
@wrnexus/queue is a server-side in-process job queue. You register named workers, enqueue jobs (optionally delayed or recurring), and let the queue poll and run them on a timer — with per-job retry limits and doubling backoff between attempts. The default store lives in memory; the design allows a pluggable driver to back it with Redis/SQL for durability across restarts. Reach for it when you need to defer work (emails, webhooks, cleanup) off the request path without a heavyweight external broker. Tests can drive it deterministically via drain().
@@ -217,7 +217,7 @@ clock = 5000;
const ran = await queue.drain(); // => 1
-
+
}
diff --git a/app/pages/packages/reactive.wrn b/app/pages/packages/reactive.wrn
index e38c319b..87790c4c 100644
--- a/app/pages/packages/reactive.wrn
+++ b/app/pages/packages/reactive.wrn
@@ -10,11 +10,11 @@ page wrnexusreactive {
W WRNexusJS
-
+
Browse documentation
- Frontend · Package reference@wrnexus/reactive
Small type-safe reactive signal primitives.
Install the package
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/reactive@0.3.4
Request preview access. Never put registry tokens in source control.
Tiny, type-safe reactive primitives (signals) with zero dependencies.
+ Frontend · Package reference@wrnexus/reactive
Small type-safe reactive signal primitives.
Install the package
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/reactive@0.3.5
Request preview access. Never put registry tokens in source control.
Tiny, type-safe reactive primitives (signals) with zero dependencies.
Part of the WRNexusJS framework — an SSR-first, Bun-native full-stack web framework.
Overview
@wrnexus/reactive is the seed of WRNexusJS's reactivity layer: a minimal signal primitive that holds a value, notifies subscribers when it changes, and hands back an unsubscribe function. It is deliberately small and framework-agnostic — it powers nothing on its own, but is shaped so client islands (and later the .wrn compiler's state blocks) can build reactive bindings on top of it. Reach for it when you need observable state without pulling in a full reactivity library.
@@ -128,7 +128,7 @@ const user: Signal<{ name: string } | null> = signal(null);
user.set({ name: "Ada" });
-
+
}
diff --git a/app/pages/packages/router.wrn b/app/pages/packages/router.wrn
index b6aaab1e..27b9cc68 100644
--- a/app/pages/packages/router.wrn
+++ b/app/pages/packages/router.wrn
@@ -10,11 +10,11 @@ page wrnexusrouter {
W WRNexusJS
-
+
Browse documentation
- Core · Package reference@wrnexus/router
Filesystem discovery, route matching, and typed route generation.
Install the package
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/router@0.3.4
Request preview access. Never put registry tokens in source control.
File-based router that maps an app/ directory onto route tables and matches request paths against them.
+ Core · Package reference@wrnexus/router
Filesystem discovery, route matching, and typed route generation.
Install the package
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/router@0.3.5
Request preview access. Never put registry tokens in source control.
File-based router that maps an app/ directory onto route tables and matches request paths against them.
Part of the WRNexusJS framework — an SSR-first, Bun-native full-stack web framework.
Overview
@wrnexus/router scans an application's app/ directory once at startup and builds route tables for pages, API endpoints, realtime channels, middleware, server-rendered .wrn components, layouts, and validation schemas. It also compiles URL patterns (/users/[id]) into RegExps and matches request paths against them. Request input is never turned into a file path, which makes the router immune to path traversal. This is a server-side package used by the WRNexusJS runtime to resolve incoming requests, plus a codegen helper for compile-time typed links.
@@ -273,7 +273,7 @@ const routes = sortRoutes([{ raw: "/posts/[slug]", file: "
const m = matchRoute(routes, "/posts/hello"); // { route, params: { slug: "hello" } }
-
+
}
diff --git a/app/pages/packages/ssr.wrn b/app/pages/packages/ssr.wrn
index e8931c8a..828683b2 100644
--- a/app/pages/packages/ssr.wrn
+++ b/app/pages/packages/ssr.wrn
@@ -10,11 +10,11 @@ page wrnexusssr {
W WRNexusJS
-
+
Browse documentation
- Runtime · Package reference@wrnexus/ssr
Secure HTML document rendering and SEO metadata.
Install the package
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/ssr@0.3.4
Request preview access. Never put registry tokens in source control.
Server-side rendering: wraps a page's HTML body in a complete HTML document with a metadata-driven <head>.
+ Runtime · Package reference@wrnexus/ssr
Secure HTML document rendering and SEO metadata.
Install the package
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/ssr@0.3.5
Request preview access. Never put registry tokens in source control.
Server-side rendering: wraps a page's HTML body in a complete HTML document with a metadata-driven <head>.
Part of the WRNexusJS framework — an SSR-first, Bun-native full-stack web framework.
Overview
Pages in WRNexusJS return an HTML string for the body. @wrnexus/ssr takes that body and produces a full HTML document — building the <head> from page metadata and global SEO defaults, resolving canonical/Open Graph/Twitter tags, and injecting module preloads and <script type="module"> tags. It is deliberately server-only: nothing in this package touches the DOM or ships to the browser, keeping server code genuinely server-only. Reach for it on the server when turning a rendered page body into a response document.
@@ -128,6 +128,12 @@ interface RenderOptions {
extraBody?: string;
/** Attributes for the `<html>` element, e.g. ` data-theme="dark"` (trusted). */
htmlAttrs?: string;
+ /**
+ * Optional application-authored full document shell. It must contain
+ * `<html>`, `<head>`, and `<body>`. Framework metadata, assets, and scripts
+ * are merged into it instead of wrapping the rendered body again.
+ */
+ documentTemplate?: string;
}
/**
* Render a complete HTML document.
@@ -180,7 +186,7 @@ return new Response(html, {
return new Response(html, { headers: { "content-type": "text/html; charset=utf-8" } });
-
+
}
diff --git a/app/pages/packages/styles.wrn b/app/pages/packages/styles.wrn
index d7e26f4e..ef12e2ad 100644
--- a/app/pages/packages/styles.wrn
+++ b/app/pages/packages/styles.wrn
@@ -10,11 +10,11 @@ page wrnexusstyles {
W WRNexusJS
-
+
Browse documentation
- Frontend · Package reference@wrnexus/styles
CSS pipeline, themes, fonts, profiles, and application config.
Install the package
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/styles@0.3.4
Request preview access. Never put registry tokens in source control.
Global CSS bundling, the --wire-* design-token theme system, and the wrnexus.config.ts app-config loader for WRNexusJS apps.
+ Frontend · Package reference@wrnexus/styles
CSS pipeline, themes, fonts, profiles, and application config.
Install the package
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/styles@0.3.5
Request preview access. Never put registry tokens in source control.
Global CSS bundling, the --wire-* design-token theme system, and the wrnexus.config.ts app-config loader for WRNexusJS apps.
Part of the WRNexusJS framework — an SSR-first, Bun-native full-stack web framework.
Overview
This package owns three server-side concerns that shape every page a WRNexusJS app renders:
@@ -697,7 +697,7 @@ const themeJs = renderThemeRuntime(theme); // served at THEME_JS_HREF
-
+
}
diff --git a/app/pages/packages/test.wrn b/app/pages/packages/test.wrn
index 2aff1216..532f638a 100644
--- a/app/pages/packages/test.wrn
+++ b/app/pages/packages/test.wrn
@@ -10,11 +10,11 @@ page wrnexustest {
W WRNexusJS
-
+
Browse documentation
- Tooling · Package reference@wrnexus/test
WRNexusJS-aware component, route, and browser testing utilities.
Install the package
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/test@0.3.4
Request preview access. Never put registry tokens in source control.
Testing utilities for WRNexusJS apps — component rendering, reactive-DOM mounting, route handler calls, and a full in-process app harness, plus a one-import re-export of bun:test.
+ Tooling · Package reference@wrnexus/test
WRNexusJS-aware component, route, and browser testing utilities.
Install the package
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/test@0.3.5
Request preview access. Never put registry tokens in source control.
Testing utilities for WRNexusJS apps — component rendering, reactive-DOM mounting, route handler calls, and a full in-process app harness, plus a one-import re-export of bun:test.
Part of the WRNexusJS framework — an SSR-first, Bun-native full-stack web framework.
Overview
@wrnexus/test is the server-side test toolkit you reach for when writing tests for a WRNexusJS app. It runs under bun test (invoked via wrnexus test) and gives you a single import surface: the bun:test primitives (test, expect, mock, …) re-exported alongside WRNexusJS-aware helpers that compile .wrn components, hydrate server HTML in a DOM, invoke API route handlers, and boot the real app on an ephemeral port for integration tests.
@@ -185,7 +185,7 @@ test("health endpoint", async () => {
});
-
+
}
diff --git a/app/pages/packages/tracking.wrn b/app/pages/packages/tracking.wrn
index 928e04e4..8915e214 100644
--- a/app/pages/packages/tracking.wrn
+++ b/app/pages/packages/tracking.wrn
@@ -10,11 +10,11 @@ page wrnexustracking {
W WRNexusJS
-
+
Browse documentation
- Runtime · Package reference@wrnexus/tracking
Error/event capture, middleware, filtering, and sinks.
Install the package
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/tracking@0.3.4
Request preview access. Never put registry tokens in source control.
Error tracking for WRNexusJS apps: capture exceptions manually or via middleware and fan them out to pluggable sinks.
+ Runtime · Package reference@wrnexus/tracking
Error/event capture, middleware, filtering, and sinks.
Install the package
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/tracking@0.3.5
Request preview access. Never put registry tokens in source control.
Error tracking for WRNexusJS apps: capture exceptions manually or via middleware and fan them out to pluggable sinks.
Part of the WRNexusJS framework — an SSR-first, Bun-native full-stack web framework.
Overview
@wrnexus/tracking is a small, server-side error-capture layer. You create a tracker with one or more sinks, then feed it errors — either manually with tracker.capture(err, context) or automatically by mounting tracker.middleware() in your request pipeline. A consoleSink is included; forwarding to Sentry, Datadog, or any other backend is just a matter of writing a tiny sink. Reach for it when you want a single, sink-agnostic place to route application errors. Sinks run best-effort — a throwing sink never breaks the request.
@@ -163,7 +163,7 @@ const tracker = createTracker({
tracker.addSink(anotherSink); // add more sinks later
-
+
}
diff --git a/app/pages/packages/ui.wrn b/app/pages/packages/ui.wrn
index c06556fc..e438c10e 100644
--- a/app/pages/packages/ui.wrn
+++ b/app/pages/packages/ui.wrn
@@ -10,11 +10,11 @@ page wrnexusui {
W WRNexusJS
-
+
Browse documentation
- Frontend · Package reference@wrnexus/ui
Themeable server-rendered UI components and CSS.
Install the package
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/ui@0.3.4
Request preview access. Never put registry tokens in source control.
First-party Wire UI component library — a set of themeable .wrn components plus a single tokenized stylesheet.
+ Frontend · Package reference@wrnexus/ui
Themeable server-rendered UI components and CSS.
Install the package
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/ui@0.3.5
Request preview access. Never put registry tokens in source control.
First-party Wire UI component library — a set of themeable .wrn components plus a single tokenized stylesheet.
Part of the WRNexusJS framework — an SSR-first, Bun-native full-stack web framework.
Overview
@wrnexus/ui ships a library of server-rendered .wrn components (layout, form controls, and feedback UI) together with one themeable stylesheet, ui.css. The components are auto-discovered by the framework router — you don't import them in code. Once the package's component directory is on the router's scan path, you mount any component in a page with data-component="<name>". Every visual is driven by var(--wire-*) theme tokens, so components restyle instantly when the theme changes. The tiny JS surface (src/index.ts) exists only so the toolchain (CLI build + dev server) can locate the component directory and stylesheet.
@@ -128,10 +128,10 @@ const router = buildRouter(appDir, { componentDirs: [uiComponentsDir()]
<div data-component="badge" label="New"></div>
<button data-component="button" label="Save" variant="primary" size="lg"></button>
<div data-component="alert" variant="success" title="Done" message="Saved."></div>
-</div>