diff --git a/app/pages/404.wrn b/app/pages/404.wrn index 891e58d8..543e4147 100644 --- a/app/pages/404.wrn +++ b/app/pages/404.wrn @@ -7,10 +7,10 @@ page Pagenotfound { view {
-
W WRNexusJS
+
W WRNexusJS
- +
} diff --git a/app/pages/access.wrn b/app/pages/access.wrn index b4730aee..2e60258e 100644 --- a/app/pages/access.wrn +++ b/app/pages/access.wrn @@ -7,10 +7,10 @@ page Access { view {
-
W WRNexusJS
+
W WRNexusJS
-

Request preview access

WRNexusJS 0.4.0 packages are not available from the public npm registry. Installation requires approval and private registry credentials supplied by WorkRoot. Never paste registry tokens into source control, issue reports, or support messages.

Request process

  1. Contact WorkRoot through the public contact path at workroot.in.
  2. Describe the application, team, expected deployment, and Bun environment.
  3. After approval, follow the registry instructions supplied privately.
  4. Use the canonical scaffold command below only after authentication.
bunx @wrnexus/cli@0.4.0 create my-app

Access approval, response time, licensing terms, and support level remain owner-controlled. This site does not collect access requests directly.

- +

Request preview access

WRNexusJS 0.5.0 packages are not available from the public npm registry. Installation requires approval and private registry credentials supplied by WorkRoot. Never paste registry tokens into source control, issue reports, or support messages.

Request process

  1. Contact WorkRoot through the public contact path at workroot.in.
  2. Describe the application, team, expected deployment, and Bun environment.
  3. After approval, follow the registry instructions supplied privately.
  4. Use the canonical scaffold command below only after authentication.
bunx @wrnexus/cli@0.5.0 create my-app

Access approval, response time, licensing terms, and support level remain owner-controlled. This site does not collect access requests directly.

+
} diff --git a/app/pages/architecture.wrn b/app/pages/architecture.wrn index 1a56ecda..3a6aaff2 100644 --- a/app/pages/architecture.wrn +++ b/app/pages/architecture.wrn @@ -7,10 +7,10 @@ page Architecture { view {
-
W WRNexusJS
+
W WRNexusJS
-
Framework architecture · 0.4.0

Architecture

WRNexusJS is Bun-native and SSR-first. File discovery maps pages and API handlers; middleware enriches or short-circuits a request; the compiler turns .wrn declarations into server render functions and small feature runtimes.

Request and build lifecycle

  1. DiscoverPages, APIs, middleware, components, layouts, schemas, rooms
  2. CompileParse .wrn, validate grammar, generate server code
  3. RequestLimits, security, locale, session, middleware
  4. MatchStatic and dynamic file route
  5. RenderSSR data, escaped interpolation, components, metadata
  6. EnhanceOnly required reactive/directive runtimes

Package boundaries

core owns contexts, middleware, sessions and rooms; router discovers routes; compiler parses .wrn; ssr renders documents; csr supplies browser runtimes; dev-server and cli orchestrate development and builds.

Security and data flow

Validation happens at trust boundaries. Session authentication establishes identity; authorization makes resource decisions. CSP, Trusted Types, CSRF, upload checks, WebSocket origins, request limits, and output escaping are layered controls—not substitutes for application policy.

Realtime and scale

Rooms are process-local unless connected through pub/sub. Redis-backed pub/sub distributes events. Queue durability depends on the selected driver and must be evaluated explicitly.

Workspaces and gateways

The gateway can dispatch multiple applications while preserving route, component, asset, config, and session boundaries. Validate host routing and isolation before production.

Build and deployment

wrnexus build . produces dist/server.js and hashed/static assets. Run the server with Bun, apply migrations before traffic, terminate TLS at a trusted edge, and forward only expected proxy headers.

Mobile

Mobile compatibility bridges SSR-safe Capacitor capabilities; native route generation is experimental and is not general web portability. Test each target platform.

Generated files and limits

app/routes.gen.ts, .wrnexus/, and dist/ are generated. The runtime is Bun-only. Preview packages are private. Historical compatibility and long-term support policy are not yet published.

- +
Framework architecture · 0.5.0

Architecture

WRNexusJS is Bun-native and SSR-first. File discovery maps pages and API handlers; middleware enriches or short-circuits a request; the compiler turns .wrn declarations into server render functions and small feature runtimes.

Request and build lifecycle

  1. DiscoverPages, APIs, middleware, components, layouts, schemas, rooms
  2. CompileParse .wrn, validate grammar, generate server code
  3. RequestLimits, security, locale, session, middleware
  4. MatchStatic and dynamic file route
  5. RenderSSR data, escaped interpolation, components, metadata
  6. EnhanceOnly required reactive/directive runtimes

Package boundaries

core owns contexts, middleware, sessions and rooms; router discovers routes; compiler parses .wrn; ssr renders documents; csr supplies browser runtimes; dev-server and cli orchestrate development and builds.

Security and data flow

Validation happens at trust boundaries. Session authentication establishes identity; authorization makes resource decisions. CSP, Trusted Types, CSRF, upload checks, WebSocket origins, request limits, and output escaping are layered controls—not substitutes for application policy.

Realtime and scale

Rooms are process-local unless connected through pub/sub. Redis-backed pub/sub distributes events. Queue durability depends on the selected driver and must be evaluated explicitly.

Workspaces and gateways

The gateway can dispatch multiple applications while preserving route, component, asset, config, and session boundaries. Validate host routing and isolation before production.

Build and deployment

wrnexus build . produces dist/server.js and hashed/static assets. Run the server with Bun, apply migrations before traffic, terminate TLS at a trusted edge, and forward only expected proxy headers.

Mobile

Mobile compatibility bridges SSR-safe Capacitor capabilities; native route generation is experimental and is not general web portability. Test each target platform.

Generated files and limits

app/routes.gen.ts, .wrnexus/, and dist/ are generated. The runtime is Bun-only. Preview packages are private. Historical compatibility and long-term support policy are not yet published.

+
} diff --git a/app/pages/benchmarks.wrn b/app/pages/benchmarks.wrn index 4ff0f1c5..70a4bdd2 100644 --- a/app/pages/benchmarks.wrn +++ b/app/pages/benchmarks.wrn @@ -7,10 +7,10 @@ page Benchmarks { view {
-
W WRNexusJS
+
W WRNexusJS

Benchmarks

No publishable benchmark dataset yet

No comparative speed claims are published. A valid baseline must record scripts, commit, Bun/framework versions, hardware, OS, warmup, samples, workload, raw results, median, percentiles, memory, HTML size, browser JavaScript size, and run date.

The roadmap starts with WRNexusJS-only measurements before any maintained equivalent-workload comparison.

- +
} diff --git a/app/pages/changelog.wrn b/app/pages/changelog.wrn index 199c6662..12c0cfdf 100644 --- a/app/pages/changelog.wrn +++ b/app/pages/changelog.wrn @@ -7,10 +7,10 @@ page Changelog { view {
-
W WRNexusJS
+
W WRNexusJS
-

Changelog

0.4.0 2026-07-13

Documentation is aligned to all 30 installed packages. This release adds @wrnexus/helpers, original-request URL helpers, safe login redirects, working wrnexus workspace add, and forward-auth redirect propagation.

Migration notes

Run wrnexus update --latest and keep every @wrnexus/* package on 0.4.0. Existing applications must explicitly add @wrnexus/helpers before importing it; newly scaffolded applications include it automatically.

Versioning and support

The packages use semantic-looking versions, but a formal compatibility and old-release support policy has not been approved. Preview consumers should treat minor releases as potentially requiring migration review.

- +

Changelog

0.5.0 2026-07-13

Documentation is aligned to all 31 installed packages. This release adds @wrnexus/helpers, original-request URL helpers, safe login redirects, working wrnexus workspace add, and forward-auth redirect propagation.

Migration notes

Run wrnexus update --latest and keep every @wrnexus/* package on 0.5.0. Existing applications must explicitly add @wrnexus/helpers before importing it; newly scaffolded applications include it automatically.

Versioning and support

The packages use semantic-looking versions, but a formal compatibility and old-release support policy has not been approved. Preview consumers should treat minor releases as potentially requiring migration review.

+
} diff --git a/app/pages/components.wrn b/app/pages/components.wrn index 3c08c765..90179e5b 100644 --- a/app/pages/components.wrn +++ b/app/pages/components.wrn @@ -12,95 +12,95 @@ page Components {
W WRNexusJS - +
-
@wrnexus/ui · 85 components

Component reference

Production-ready, server-rendered components documented directly from the installed .wrn sources.

Showing {category} components

base

Accordion

Theme-aware, responsive accordion component.

5 props1 slots0 events
View component →
-integrations

AdvancedDatePicker

Theme-aware, responsive advanced date picker component.

7 props1 slots0 events
View component →
-integrations

AdvancedRangeSlider

Theme-aware, responsive advanced range slider component.

7 props1 slots0 events
View component →
+
@wrnexus/ui · 85 components

Component reference

Production-ready, server-rendered components documented directly from the installed .wrn sources.

Showing {category} components

base

Accordion

Theme-aware, responsive accordion component.

17 props0 slots3 events
View component →
+integrations

AdvancedDatePicker

Theme-aware, responsive advanced date picker component.

7 props1 slots5 events
View component →
+integrations

AdvancedRangeSlider

Theme-aware, responsive advanced range slider component.

7 props1 slots4 events
View component →
advanced-forms

AdvancedSelect

Theme-aware, responsive advanced select component.

51 props0 slots8 events
View component →
-base

Alert

Theme-aware, responsive alert component.

7 props1 slots0 events
View component →
-base

Avatar

Theme-aware, responsive avatar component.

7 props1 slots0 events
View component →
-base

AvatarGroup

Theme-aware, responsive avatar group component.

7 props1 slots0 events
View component →
-base

Badge

Theme-aware, responsive badge component.

7 props1 slots0 events
View component →
-base

Blockquote

Theme-aware, responsive blockquote component.

7 props1 slots0 events
View component →
-navigation

Breadcrumb

Theme-aware, responsive breadcrumb component.

7 props1 slots0 events
View component →
-base

Button

Theme-aware, responsive button component.

25 props1 slots0 events
View component →
-base

ButtonGroup

Theme-aware, responsive button group component.

7 props1 slots0 events
View component →
-base

Card

Theme-aware, responsive card component.

7 props1 slots0 events
View component →
-base

Carousel

Theme-aware, responsive carousel component.

7 props1 slots0 events
View component →
-integrations

Chart

Theme-aware, responsive chart component.

7 props1 slots0 events
View component →
-base

ChatBubble

Theme-aware, responsive chat bubble component.

7 props1 slots0 events
View component →
-forms

Checkbox

Theme-aware, responsive checkbox component.

8 props0 slots0 events
View component →
-integrations

Clipboard

Theme-aware, responsive clipboard component.

7 props1 slots0 events
View component →
-base

Collapse

Theme-aware, responsive collapse component.

5 props1 slots0 events
View component →
-forms

ColorPicker

Theme-aware, responsive color picker component.

13 props0 slots0 events
View component →
+base

Alert

Theme-aware, responsive alert component.

21 props0 slots2 events
View component →
+base

Avatar

Theme-aware, responsive avatar component.

18 props0 slots3 events
View component →
+base

AvatarGroup

Theme-aware, responsive avatar group component.

12 props0 slots1 events
View component →
+base

Badge

Theme-aware, responsive badge component.

22 props0 slots1 events
View component →
+base

Blockquote

Theme-aware, responsive blockquote component.

13 props1 slots0 events
View component →
+navigation

Breadcrumb

Theme-aware, responsive breadcrumb component.

7 props1 slots2 events
View component →
+base

Button

Theme-aware, responsive button component.

25 props1 slots3 events
View component →
+base

ButtonGroup

Theme-aware, responsive button group component.

13 props1 slots3 events
View component →
+base

Card

Theme-aware, responsive card component.

31 props1 slots6 events
View component →
+base

Carousel

Theme-aware, responsive carousel component.

22 props1 slots10 events
View component →
+integrations

Chart

Theme-aware, responsive chart component.

7 props1 slots3 events
View component →
+base

ChatBubble

Theme-aware, responsive chat bubble component.

11 props1 slots4 events
View component →
+forms

Checkbox

Theme-aware, responsive checkbox component.

27 props0 slots5 events
View component →
+integrations

Clipboard

Theme-aware, responsive clipboard component.

7 props1 slots3 events
View component →
+base

Collapse

Theme-aware, responsive collapse component.

8 props1 slots3 events
View component →
+forms

ColorPicker

Theme-aware, responsive color picker component.

19 props0 slots4 events
View component →
layout

Columns

Theme-aware, responsive columns component.

6 props1 slots0 events
View component →
advanced-forms

ComboBox

Editable autocomplete combobox with local and remote suggestions.

41 props0 slots8 events
View component →
-integrations

Confetti

Theme-aware, responsive confetti component.

7 props1 slots0 events
View component →
+integrations

Confetti

Theme-aware, responsive confetti component.

7 props1 slots2 events
View component →
layout

Container

Theme-aware, responsive container component.

6 props1 slots0 events
View component →
-overlays

ContextMenu

Theme-aware, responsive context menu component.

8 props1 slots0 events
View component →
-advanced-forms

CopyMarkup

Theme-aware, responsive copy markup component.

13 props0 slots0 events
View component →
-layout

CustomScrollbar

Theme-aware, responsive custom scrollbar component.

6 props1 slots0 events
View component →
-integrations

DataMap

Theme-aware, responsive data map component.

7 props1 slots0 events
View component →
-integrations

DataTable

Theme-aware, responsive data table component.

7 props1 slots0 events
View component →
-base

DatePicker

Theme-aware, responsive date picker component.

13 props0 slots0 events
View component →
-base

DeviceFrame

Theme-aware, responsive device frame component.

7 props1 slots0 events
View component →
+overlays

ContextMenu

Theme-aware, responsive context menu component.

8 props1 slots3 events
View component →
+advanced-forms

CopyMarkup

Theme-aware, responsive copy markup component.

13 props0 slots3 events
View component →
+layout

CustomScrollbar

Theme-aware, responsive custom scrollbar component.

6 props1 slots1 events
View component →
+integrations

DataMap

Theme-aware, responsive data map component.

7 props1 slots2 events
View component →
+integrations

DataTable

Theme-aware, responsive data table component.

7 props1 slots5 events
View component →
+base

DatePicker

Theme-aware, responsive date picker component.

25 props0 slots7 events
View component →
+base

DeviceFrame

Theme-aware, responsive device frame component.

14 props1 slots2 events
View component →
layout

Divider

Theme-aware, responsive divider component.

5 props0 slots0 events
View component →
-integrations

DragAndDrop

Theme-aware, responsive drag and drop component.

7 props1 slots0 events
View component →
-overlays

Drawer

Theme-aware, responsive drawer component.

8 props1 slots0 events
View component →
-overlays

Dropdown

Theme-aware, responsive dropdown component.

8 props1 slots0 events
View component →
-forms

FileInput

Theme-aware, responsive file input component.

13 props0 slots0 events
View component →
-integrations

FileUpload

Theme-aware, responsive file upload component.

7 props1 slots0 events
View component →
-base

FileUploadProgress

Theme-aware, responsive file upload progress component.

7 props0 slots0 events
View component →
+integrations

DragAndDrop

Theme-aware, responsive drag and drop component.

7 props1 slots6 events
View component →
+overlays

Drawer

Theme-aware, responsive drawer component.

8 props1 slots2 events
View component →
+overlays

Dropdown

Theme-aware, responsive dropdown component.

8 props1 slots4 events
View component →
+forms

FileInput

Theme-aware, responsive file input component.

21 props0 slots7 events
View component →
+integrations

FileUpload

Theme-aware, responsive file upload component.

7 props1 slots7 events
View component →
+base

FileUploadProgress

Theme-aware, responsive file upload progress component.

13 props0 slots3 events
View component →
layout

Grid

Theme-aware, responsive grid component.

6 props1 slots0 events
View component →
-layout

Image

Theme-aware, responsive image component.

9 props1 slots0 events
View component →
-forms

Input

Theme-aware, responsive input component.

13 props0 slots0 events
View component →
-forms

InputGroup

Theme-aware, responsive input group component.

13 props0 slots0 events
View component →
+layout

Image

Theme-aware, responsive image component.

9 props1 slots2 events
View component →
+forms

Input

Theme-aware, responsive input component.

28 props0 slots7 events
View component →
+forms

InputGroup

Theme-aware, responsive input group component.

23 props0 slots6 events
View component →
advanced-forms

InputNumber

Theme-aware, responsive input number component.

40 props0 slots4 events
View component →
layout

Kbd

Theme-aware, responsive kbd component.

4 props1 slots0 events
View component →
-layout

LayoutSplitter

Theme-aware, responsive layout splitter component.

6 props1 slots0 events
View component →
-base

LegendIndicator

Theme-aware, responsive legend indicator component.

7 props1 slots0 events
View component →
-layout

Link

Theme-aware, responsive link component.

8 props1 slots0 events
View component →
-base

List

Theme-aware, responsive list component.

7 props1 slots0 events
View component →
-base

ListGroup

Theme-aware, responsive list group component.

7 props1 slots0 events
View component →
-integrations

Map

Theme-aware, responsive map component.

7 props1 slots0 events
View component →
-base

Marquee

Theme-aware, responsive marquee component.

7 props1 slots0 events
View component →
-navigation

MegaMenu

Theme-aware, responsive mega menu component.

7 props1 slots0 events
View component →
-overlays

Modal

Theme-aware, responsive modal component.

8 props1 slots0 events
View component →
-navigation

Nav

Theme-aware, responsive nav component.

7 props1 slots0 events
View component →
-navigation

Navbar

Theme-aware, responsive navbar component.

7 props1 slots0 events
View component →
-navigation

Pagination

Theme-aware, responsive pagination component.

7 props1 slots0 events
View component →
+layout

LayoutSplitter

Theme-aware, responsive layout splitter component.

6 props1 slots3 events
View component →
+base

LegendIndicator

Theme-aware, responsive legend indicator component.

7 props1 slots2 events
View component →
+layout

Link

Theme-aware, responsive link component.

8 props1 slots3 events
View component →
+base

List

Theme-aware, responsive list component.

7 props1 slots2 events
View component →
+base

ListGroup

Theme-aware, responsive list group component.

7 props1 slots2 events
View component →
+integrations

Map

Theme-aware, responsive map component.

7 props1 slots4 events
View component →
+base

Marquee

Theme-aware, responsive marquee component.

7 props1 slots2 events
View component →
+navigation

MegaMenu

Theme-aware, responsive mega menu component.

7 props1 slots3 events
View component →
+overlays

Modal

Theme-aware, responsive modal component.

8 props1 slots4 events
View component →
+navigation

Nav

Theme-aware, responsive nav component.

7 props1 slots2 events
View component →
+navigation

Navbar

Theme-aware, responsive navbar component.

7 props1 slots3 events
View component →
+navigation

Pagination

Theme-aware, responsive pagination component.

7 props1 slots3 events
View component →
advanced-forms

PinInput

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

26 props0 slots6 events
View component →
-overlays

Popover

Theme-aware, responsive popover component.

8 props1 slots0 events
View component →
+overlays

Popover

Theme-aware, responsive popover component.

8 props1 slots2 events
View component →
base

Progress

Theme-aware, responsive progress component.

7 props0 slots0 events
View component →
-forms

Radio

Theme-aware, responsive radio component.

8 props0 slots0 events
View component →
-forms

RangeSlider

Theme-aware, responsive range slider component.

13 props0 slots0 events
View component →
-base

Rating

Theme-aware, responsive rating component.

7 props1 slots0 events
View component →
-navigation

Scrollspy

Theme-aware, responsive scrollspy component.

7 props1 slots0 events
View component →
-advanced-forms

SearchBox

Theme-aware, responsive search box component.

13 props0 slots0 events
View component →
-forms

Select

Theme-aware, responsive select component.

10 props0 slots0 events
View component →
-navigation

Sidebar

Theme-aware, responsive sidebar component.

7 props1 slots0 events
View component →
+forms

Radio

Theme-aware, responsive radio component.

25 props0 slots5 events
View component →
+forms

RangeSlider

Theme-aware, responsive range slider component.

26 props0 slots4 events
View component →
+base

Rating

Theme-aware, responsive rating component.

7 props1 slots2 events
View component →
+navigation

Scrollspy

Theme-aware, responsive scrollspy component.

7 props1 slots1 events
View component →
+advanced-forms

SearchBox

Theme-aware, responsive search box component.

13 props0 slots5 events
View component →
+forms

Select

Theme-aware, responsive select component.

22 props0 slots7 events
View component →
+navigation

Sidebar

Theme-aware, responsive sidebar component.

7 props1 slots3 events
View component →
base

Skeleton

Theme-aware, responsive skeleton component.

5 props0 slots0 events
View component →
base

Spinner

Theme-aware, responsive spinner component.

5 props0 slots0 events
View component →
-navigation

Stepper

Theme-aware, responsive stepper component.

7 props1 slots0 events
View component →
+navigation

Stepper

Theme-aware, responsive stepper component.

7 props1 slots4 events
View component →
advanced-forms

StrongPassword

Theme-aware, responsive strong password component.

27 props0 slots3 events
View component →
base

StyledIcon

Theme-aware, responsive styled icon component.

7 props1 slots0 events
View component →
-forms

Switch

Theme-aware, responsive switch component.

8 props0 slots0 events
View component →
-tables

Table

Theme-aware, responsive table component.

7 props1 slots0 events
View component →
-navigation

Tabs

Theme-aware, responsive tabs component.

7 props1 slots0 events
View component →
-forms

Textarea

Theme-aware, responsive textarea component.

10 props0 slots0 events
View component →
-base

Timeline

Theme-aware, responsive timeline component.

7 props1 slots0 events
View component →
-forms

TimePicker

Theme-aware, responsive time picker component.

13 props0 slots0 events
View component →
-base

Toast

Theme-aware, responsive toast component.

7 props1 slots0 events
View component →
-integrations

ToastNotifications

Theme-aware, responsive toast notifications component.

7 props1 slots0 events
View component →
-advanced-forms

ToggleCount

Theme-aware, responsive toggle count component.

13 props0 slots0 events
View component →
+forms

Switch

Theme-aware, responsive switch component.

20 props0 slots4 events
View component →
+tables

Table

Theme-aware, responsive table component.

7 props1 slots3 events
View component →
+navigation

Tabs

Theme-aware, responsive tabs component.

7 props1 slots2 events
View component →
+forms

Textarea

Theme-aware, responsive textarea component.

23 props0 slots5 events
View component →
+base

Timeline

Theme-aware, responsive timeline component.

7 props1 slots1 events
View component →
+forms

TimePicker

Theme-aware, responsive time picker component.

26 props0 slots7 events
View component →
+base

Toast

Theme-aware, responsive toast component.

7 props1 slots2 events
View component →
+integrations

ToastNotifications

Theme-aware, responsive toast notifications component.

7 props1 slots4 events
View component →
+advanced-forms

ToggleCount

Theme-aware, responsive toggle count component.

23 props0 slots2 events
View component →
advanced-forms

TogglePassword

Accessible password field with optional show and hide controls.

24 props0 slots3 events
View component →
-overlays

Tooltip

Theme-aware, responsive tooltip component.

8 props1 slots0 events
View component →
-base

TreeView

Theme-aware, responsive tree view component.

7 props1 slots0 events
View component →
+overlays

Tooltip

Theme-aware, responsive tooltip component.

8 props1 slots2 events
View component →
+base

TreeView

Theme-aware, responsive tree view component.

7 props1 slots4 events
View component →
layout

Typography

Theme-aware, responsive typography component.

6 props1 slots0 events
View component →
-integrations

WysiwygEditor

Theme-aware, responsive wysiwyg editor component.

7 props1 slots0 events
View component →
- +integrations

WysiwygEditor

Theme-aware, responsive wysiwyg editor component.

7 props1 slots4 events
View component →
+ } diff --git a/app/pages/components/accordion.wrn b/app/pages/components/accordion.wrn index 5fceb305..196d4c10 100644 --- a/app/pages/components/accordion.wrn +++ b/app/pages/components/accordion.wrn @@ -10,34 +10,222 @@ page Accordioncomponent {
W WRNexusJS - +
-
base component

Accordion

Theme-aware, responsive accordion component.

@wrnexus/ui 0.4.05 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Accordion
+      
base component

Accordion

Theme-aware, responsive accordion component.

@wrnexus/ui 0.5.017 props0 slots3 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Accordion
   size="default"
   color="primary"
+  variant="default"
+  id="accordion"
   items="[]"
-  multiple="false"
-/>

Legacy mount name: data-component="Accordion".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
itemsstringOptional[]
multiplebooleanOptionalfalse
classstringOptional""

Slots

  • default

Events

This component does not declare a custom event.

Source contract

Installed source: components/Accordion.wrn

component Accordion {
+/>

Legacy mount name: data-component="Accordion".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
variantstringOptional"default"
classstringOptional""
idstringOptional"accordion"
itemsstringOptional[]
defaultOpenstringOptional[]
multiplebooleanOptionalfalse
alwaysOpenbooleanOptionalfalse
disabledbooleanOptionalfalse
indicatorstringOptional"plus"
indicatorPositionstringOptional"start"
showIndicatorbooleanOptionaltrue
borderedbooleanOptionalfalse
separatedbooleanOptionalfalse
flushbooleanOptionalfalse
contentItalicbooleanOptionalfalse

Slots

This component does not declare a slot.

Events

  • change
  • open
  • close

Source contract

Installed source: components/Accordion.wrn

component Accordion {
   props {
     size = "default"
     color = "primary"
-    items = []
-    multiple = false
+    variant = "default"
     class = ""
+
+    id = "accordion"
+    items = []
+    defaultOpen = []
+    multiple = false
+    alwaysOpen = false
+    disabled = false
+
+    indicator = "plus"
+    indicatorPosition = "start"
+    showIndicator = true
+    bordered = false
+    separated = false
+    flush = false
+    contentItalic = false
+
+    @event change = function
+    @event open = function
+    @event close = function
   }
+
+  state openValues = defaultOpen
+
+  functions {
+    function itemValue(item, index) {
+      return item.value !== undefined && item.value !== ""
+        ? String(item.value)
+        : String(index)
+    }
+
+    function nestedValue(parent, parentIndex, item, index) {
+      return itemValue(parent, parentIndex) + "." + itemValue(item, index)
+    }
+
+    function isOpen(value) {
+      return openValues.includes(value)
+    }
+
+    function allowsMultiple() {
+      return multiple || alwaysOpen
+    }
+
+    function dispatchAccordionEvent(sourceEvent, eventName, value, item, root, customEvent) {
+      root = sourceEvent.currentTarget.closest("[data-wrn-accordion]")
+
+      if (!root) {
+        return
+      }
+
+      customEvent = document.createEvent("CustomEvent")
+      customEvent.initCustomEvent(eventName, true, false, {
+        component: "Accordion",
+        value: value,
+        item: item,
+        open: isOpen(value),
+        openValues: openValues
+      })
+      root.dispatchEvent(customEvent)
+    }
+
+    function toggleItem(sourceEvent, value, item, wasOpen) {
+      if (disabled || item.disabled) {
+        return
+      }
+
+      wasOpen = isOpen(value)
+
+      if (wasOpen) {
+        openValues = openValues.filter((entry) => entry !== value)
+      } else if (allowsMultiple()) {
+        openValues = openValues.concat([value])
+      } else {
+        openValues = [value]
+      }
+
+      dispatchAccordionEvent(
+        sourceEvent,
+        wasOpen ? "close" : "open",
+        value,
+        item
+      )
+      dispatchAccordionEvent(sourceEvent, "change", value, item)
+    }
+
+  }
+
   view {
-        <div class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--accordion {class}">
-      {#each items as item}<details open="{item.open}">
-        <summary>{item.label}</summary>
-        <div>{item.content}</div>
-        </details>{/each}
-      <slot />
+        <div
+      {...attrs}
+      id="{id}"
+      data-wrn-accordion
+      data-variant="{variant}"
+      data-indicator="{indicator}"
+      data-multiple="{allowsMultiple() ? 'true' : 'false'}"
+      class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--accordion wire-next--accordion-{variant} {bordered ? 'wire-next--accordion-bordered' : ''} {separated ? 'wire-next--accordion-separated' : ''} {flush ? 'wire-next--accordion-flush' : ''} {disabled ? 'wire-next--disabled' : ''} {class}"
+    >
+      {#each items as item, index}
+        <section
+          class="wire-next__accordion-item"
+          data-open="{isOpen(itemValue(item, index)) ? 'true' : 'false'}"
+          data-disabled="{disabled || item.disabled ? 'true' : 'false'}"
+        >
+        <h3 class="wire-next__accordion-heading">
+        <button
+              type="button"
+              id="{id}-trigger-{index}"
+              aria-expanded="{isOpen(itemValue(item, index)) ? 'true' : 'false'}"
+              aria-controls="{id}-panel-{index}"
+              disabled="{disabled || item.disabled}"
+              @click="toggleItem(event, itemValue(item, index), item)"
+            >
+              {#if showIndicator && indicatorPosition === "start"}
+                <span class="wire-next__accordion-indicator" aria-hidden="true">
+                  {#if indicator === "chevron"}
+                    <span class="icon-[lucide--chevron-down]">
+        </span>
+                  {:else}
+                    <span>+</span>
+                  {/if}
+                </span>
+              {/if}
+              <span>{item.label || item.title}</span>
+              {#if showIndicator && indicatorPosition === "end"}
+                <span class="wire-next__accordion-indicator" aria-hidden="true">
+                  {#if indicator === "chevron"}
+                    <span class="icon-[lucide--chevron-down]">
+        </span>
+                  {:else}
+                    <span>+</span>
+                  {/if}
+                </span>
+              {/if}
+            </button>
+        </h3>
+        <div
+            id="{id}-panel-{index}"
+            class="wire-next__accordion-panel"
+            role="region"
+            aria-labelledby="{id}-trigger-{index}"
+            aria-hidden="{isOpen(itemValue(item, index)) ? 'false' : 'true'}"
+          >
+        <div>
+        <div class="wire-next__accordion-content {contentItalic ? 'wire-next__accordion-content-italic' : ''}">
+                {#if item.content}<p>{item.content}</p>{/if}
+
+                {#if item.children && item.children.length > 0}
+                  <div class="wire-next__accordion-nested">
+                    {#each item.children as child, childIndex}
+                      <section
+                        class="wire-next__accordion-item"
+                        data-open="{isOpen(nestedValue(item, index, child, childIndex)) ? 'true' : 'false'}"
+                      >
+        <h4 class="wire-next__accordion-heading">
+        <button
+                            type="button"
+                            id="{id}-trigger-{index}-{childIndex}"
+                            aria-expanded="{isOpen(nestedValue(item, index, child, childIndex)) ? 'true' : 'false'}"
+                            aria-controls="{id}-panel-{index}-{childIndex}"
+                            disabled="{disabled || child.disabled}"
+                            @click="toggleItem(event, nestedValue(item, index, child, childIndex), child)"
+                          >
+                            {#if showIndicator}
+                              <span class="wire-next__accordion-indicator" aria-hidden="true">
+                                {#if indicator === "chevron"}
+                                  <span class="icon-[lucide--chevron-down]">
+        </span>
+                                {:else}
+                                  <span>+</span>
+                                {/if}
+                              </span>
+                            {/if}
+                            <span>{child.label || child.title}</span>
+        </button>
+        </h4>
+        <div
+                          id="{id}-panel-{index}-{childIndex}"
+                          class="wire-next__accordion-panel"
+                          role="region"
+                          aria-labelledby="{id}-trigger-{index}-{childIndex}"
+                          aria-hidden="{isOpen(nestedValue(item, index, child, childIndex)) ? 'false' : 'true'}"
+                        >
+        <div>
+        <div class="wire-next__accordion-content {contentItalic ? 'wire-next__accordion-content-italic' : ''}">
+        <p>{child.content}</p>
         </div>
+        </div>
+        </div>
+        </section>
+                    {/each}
+                  </div>
+                {/if}
+              </div>
+        </div>
+        </div>
+        </section>
+      {/each}
+    </div>
     }
 }
 
- + } diff --git a/app/pages/components/advanced-date-picker.wrn b/app/pages/components/advanced-date-picker.wrn index 2e08537e..522bfdd6 100644 --- a/app/pages/components/advanced-date-picker.wrn +++ b/app/pages/components/advanced-date-picker.wrn @@ -10,17 +10,22 @@ page AdvancedDatePickercomponent {
W WRNexusJS - +
-
integrations component

AdvancedDatePicker

Theme-aware, responsive advanced date picker component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<AdvancedDatePicker
+      
integrations component

AdvancedDatePicker

Theme-aware, responsive advanced date picker component.

@wrnexus/ui 0.5.07 props1 slots5 events

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

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
titlestringOptional"Advanced Date Picker"
descriptionstringOptional""
itemsstringOptional[]
variantstringOptional"default"
classstringOptional""

Slots

  • default

Events

This component does not declare a custom event.

Source contract

Installed source: components/AdvancedDatePicker.wrn

component AdvancedDatePicker {
+/>

Legacy mount name: data-component="AdvancedDatePicker".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
titlestringOptional"Advanced Date Picker"
descriptionstringOptional""
itemsstringOptional[]
variantstringOptional"default"
classstringOptional""

Slots

  • default

Events

  • input
  • change
  • open
  • close
  • clear

Source contract

Installed source: components/AdvancedDatePicker.wrn

component AdvancedDatePicker {
   props {
+    @event input = function
+    @event change = function
+    @event open = function
+    @event close = function
+    @event clear = function
     size = "default"
     color = "primary"
     title = "Advanced Date Picker"
@@ -39,7 +44,7 @@ page AdvancedDatePickercomponent {
     }
 }
 
- + } diff --git a/app/pages/components/advanced-range-slider.wrn b/app/pages/components/advanced-range-slider.wrn index 6a943ed7..23aded89 100644 --- a/app/pages/components/advanced-range-slider.wrn +++ b/app/pages/components/advanced-range-slider.wrn @@ -10,17 +10,21 @@ page AdvancedRangeSlidercomponent {
W WRNexusJS - +
-
integrations component

AdvancedRangeSlider

Theme-aware, responsive advanced range slider component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<AdvancedRangeSlider
+      
integrations component

AdvancedRangeSlider

Theme-aware, responsive advanced range slider component.

@wrnexus/ui 0.5.07 props1 slots4 events

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

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
titlestringOptional"Advanced Range Slider"
descriptionstringOptional""
itemsstringOptional[]
variantstringOptional"default"
classstringOptional""

Slots

  • default

Events

This component does not declare a custom event.

Source contract

Installed source: components/AdvancedRangeSlider.wrn

component AdvancedRangeSlider {
+/>

Legacy mount name: data-component="AdvancedRangeSlider".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
titlestringOptional"Advanced Range Slider"
descriptionstringOptional""
itemsstringOptional[]
variantstringOptional"default"
classstringOptional""

Slots

  • default

Events

  • input
  • change
  • start
  • end

Source contract

Installed source: components/AdvancedRangeSlider.wrn

component AdvancedRangeSlider {
   props {
+    @event input = function
+    @event change = function
+    @event start = function
+    @event end = function
     size = "default"
     color = "primary"
     title = "Advanced Range Slider"
@@ -39,7 +43,7 @@ page AdvancedRangeSlidercomponent {
     }
 }
 
- + } diff --git a/app/pages/components/advanced-select.wrn b/app/pages/components/advanced-select.wrn index 1a03e5bb..f93d055f 100644 --- a/app/pages/components/advanced-select.wrn +++ b/app/pages/components/advanced-select.wrn @@ -10,10 +10,10 @@ page AdvancedSelectcomponent {
W WRNexusJS - +
-
advanced-forms component

AdvancedSelect

Theme-aware, responsive advanced select component.

@wrnexus/ui 0.4.051 props0 slots8 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<AdvancedSelect
+      
advanced-forms component

AdvancedSelect

Theme-aware, responsive advanced select component.

@wrnexus/ui 0.5.051 props0 slots8 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<AdvancedSelect
   size="default"
   color="primary"
   label="Advanced Select"
@@ -486,7 +486,7 @@ page AdvancedSelectcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/alert.wrn b/app/pages/components/alert.wrn index cd113258..b66f3062 100644 --- a/app/pages/components/alert.wrn +++ b/app/pages/components/alert.wrn @@ -10,36 +10,165 @@ page Alertcomponent {
W WRNexusJS - +
-
base component

Alert

Theme-aware, responsive alert component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Alert
+      
base component

Alert

Theme-aware, responsive alert component.

@wrnexus/ui 0.5.021 props0 slots2 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Alert
   size="default"
-  color="primary"
-  title="Alert"
-  description="description"
-  items="[]"
-/>

Legacy mount name: data-component="Alert".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
titlestringOptional"Alert"
descriptionstringOptional""
itemsstringOptional[]
variantstringOptional"default"
classstringOptional""

Slots

  • default

Events

This component does not declare a custom event.

Source contract

Installed source: components/alert.wrn

component Alert {
+  color="info"
+  variant="soft"
+  radius="md"
+  shadow="sm"
+/>

Legacy mount name: data-component="Alert".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"info"
variantstringOptional"soft"
classstringOptional""
radiusstringOptional"md"
shadowstringOptional"sm"
titlestringOptional"Alert"
descriptionstringOptional""
itemsstringOptional[]
actionsstringOptional[]
showIconbooleanOptionalfalse
iconstringOptional""
dismissiblebooleanOptionalfalse
dismissLabelstringOptional"Dismiss alert"
rolestringOptional"alert"
livestringOptional"polite"
linkLabelstringOptional""
linkHrefstringOptional""
actionLabelstringOptional""
actionHrefstringOptional""
compactbooleanOptionalfalse

Slots

This component does not declare a slot.

Events

  • dismiss
  • action

Source contract

Installed source: components/alert.wrn

component Alert {
   props {
     size = "default"
-    color = "primary"
+    color = "info"
+    variant = "soft"
+    class = ""
+    radius = "md"
+    shadow = "sm"
+
     title = "Alert"
     description = ""
     items = []
-    variant = "default"
-    class = ""
+    actions = []
+
+    showIcon = false
+    icon = ""
+    dismissible = false
+    dismissLabel = "Dismiss alert"
+    role = "alert"
+    live = "polite"
+
+    linkLabel = ""
+    linkHref = ""
+    actionLabel = ""
+    actionHref = ""
+    compact = false
+
+    @event dismiss = function
+    @event action = function
   }
+
+  state visible = true
+
+  functions {
+    function dispatchAlertEvent(sourceEvent, eventName, action, root, customEvent) {
+      root = sourceEvent.currentTarget.closest("[data-wrn-alert]")
+
+      if (!root) {
+        return
+      }
+
+      customEvent = document.createEvent("CustomEvent")
+      customEvent.initCustomEvent(eventName, true, false, {
+        component: "Alert",
+        title: title,
+        color: color,
+        variant: variant,
+        action: action
+      })
+      root.dispatchEvent(customEvent)
+    }
+
+    function dismissAlert(sourceEvent) {
+      visible = false
+      dispatchAlertEvent(sourceEvent, "dismiss", null)
+    }
+
+    function selectAction(sourceEvent, action) {
+      dispatchAlertEvent(sourceEvent, "action", action)
+    }
+  }
+
   view {
-        <section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--alert wire-next--variant-{variant} {class}">
-      {#if title}<strong>{title}</strong>{/if}
-      {#if description}<p>{description}</p>{/if}
-      {#if items}<div class="wire-next__items">{#each items as item}<span>{item.label}</span>{/each}</div>{/if}
-      <slot />
-        </section>
+        <section
+      {...attrs}
+      data-wrn-alert
+      data-color="{color}"
+      data-variant="{variant}"
+      data-radius="{radius}"
+      data-shadow="{shadow}"
+      data-show="visible"
+      aria-hidden="{visible ? 'false' : 'true'}"
+      role="{role}"
+      aria-live="{live}"
+      class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--alert wire-next--alert-{variant} {compact ? 'wire-next--alert-compact' : ''} {class}"
+    >
+      {#if showIcon}
+        <span class="wire-next__alert-icon" aria-hidden="true">
+          {#if icon}
+            <span class="{icon}">
+        </span>
+          {:else if color === "success"}
+            <span class="icon-[lucide--circle-check]">
+        </span>
+          {:else if color === "danger"}
+            <span class="icon-[lucide--circle-x]">
+        </span>
+          {:else if color === "warning"}
+            <span class="icon-[lucide--triangle-alert]">
+        </span>
+          {:else}
+            <span class="icon-[lucide--info]">
+        </span>
+          {/if}
+        </span>
+      {/if}
+
+      <div class="wire-next__alert-body">
+        {#if title}<strong class="wire-next__alert-title">{title}</strong>{/if}
+        {#if description}<p>{description}</p>{/if}
+
+        {#if items.length > 0}
+          <ul>
+            {#each items as item}<li>{item.label || item}</li>{/each}
+          </ul>
+        {/if}
+
+        {#if actions.length > 0 || actionLabel || linkLabel}
+          <div class="wire-next__alert-actions">
+            {#each actions as item}
+              <a
+                href="{item.href || '#'}"
+                data-variant="{item.variant || 'link'}"
+                @click="selectAction(event, item)"
+              >{item.label}</a>
+            {/each}
+            {#if actionLabel}
+              <a
+                href="{actionHref || '#'}"
+                data-variant="action"
+                @click="selectAction(event, { label: actionLabel, href: actionHref })"
+              >{actionLabel}</a>
+            {/if}
+            {#if linkLabel}
+              <a
+                href="{linkHref || '#'}"
+                data-variant="link"
+                @click="selectAction(event, { label: linkLabel, href: linkHref })"
+              >{linkLabel}</a>
+            {/if}
+          </div>
+        {/if}
+      </div>
+
+      {#if dismissible}
+        <button
+          type="button"
+          class="wire-next__alert-dismiss"
+          aria-label="{dismissLabel}"
+          @click="dismissAlert(event)"
+        >
+        <span class="icon-[lucide--x]" aria-hidden="true">
+        </span>
+        </button>
+      {/if}
+    </section>
     }
 }
 
- + } diff --git a/app/pages/components/avatar-group.wrn b/app/pages/components/avatar-group.wrn index e147b2de..ccc5bd0b 100644 --- a/app/pages/components/avatar-group.wrn +++ b/app/pages/components/avatar-group.wrn @@ -10,36 +10,138 @@ page AvatarGroupcomponent {
W WRNexusJS - +
-
base component

AvatarGroup

Theme-aware, responsive avatar group component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<AvatarGroup
-  size="default"
-  color="primary"
-  title="Avatar Group"
-  description="description"
+      
base component

AvatarGroup

Theme-aware, responsive avatar group component.

@wrnexus/ui 0.5.012 props0 slots1 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<AvatarGroup
   items="[]"
-/>

Legacy mount name: data-component="AvatarGroup".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
titlestringOptional"Avatar Group"
descriptionstringOptional""
itemsstringOptional[]
variantstringOptional"default"
classstringOptional""

Slots

  • default

Events

This component does not declare a custom event.

Source contract

Installed source: components/AvatarGroup.wrn

component AvatarGroup {
+  size="md"
+  color="primary"
+  variant="solid"
+  shape="circle"
+/>

Legacy mount name: data-component="AvatarGroup".

Props and attributes

PropTypeRequirementDefault
itemsstringOptional[]
sizestringOptional"md"
colorstringOptional"primary"
variantstringOptional"solid"
shapestringOptional"circle"
layoutstringOptional"stack"
maxVisiblenumberOptional4
columnsnumberOptional3
borderColorstringOptional""
showTooltipsbooleanOptionaltrue
overflowLabelstringOptional"Show remaining members"
classstringOptional""

Slots

This component does not declare a slot.

Events

  • overflow

Source contract

Installed source: components/AvatarGroup.wrn

component AvatarGroup {
   props {
-    size = "default"
-    color = "primary"
-    title = "Avatar Group"
-    description = ""
     items = []
-    variant = "default"
+    size = "md"
+    color = "primary"
+    variant = "solid"
+    shape = "circle"
+    layout = "stack"
+    maxVisible = 4
+    columns = 3
+    borderColor = ""
+    showTooltips = true
+    overflowLabel = "Show remaining members"
     class = ""
+
+    @event overflow = function
   }
+
+  state overflowOpen = false
+
+  functions {
+    function visibleMembers() {
+      return items.slice(0, Number(maxVisible))
+    }
+
+    function hiddenMembers() {
+      return items.slice(Number(maxVisible))
+    }
+
+    function toggleOverflow(sourceEvent, root, customEvent) {
+      overflowOpen = !overflowOpen
+      root = sourceEvent.currentTarget.closest("[data-wrn-avatar-group]")
+
+      customEvent = document.createEvent("CustomEvent")
+      customEvent.initCustomEvent("overflow", true, false, {
+        component: "AvatarGroup",
+        open: overflowOpen,
+        hiddenCount: hiddenMembers().length
+      })
+      root.dispatchEvent(customEvent)
+    }
+  }
+
   view {
-        <section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--avatar-group wire-next--variant-{variant} {class}">
-      {#if title}<strong>{title}</strong>{/if}
-      {#if description}<p>{description}</p>{/if}
-      {#if items}<div class="wire-next__items">{#each items as item}<span>{item.label}</span>{/each}</div>{/if}
-      <slot />
-        </section>
+        <div
+      {...attrs}
+      class="wire-next wire-next--avatar-group {class}"
+      data-wrn-avatar-group
+      data-layout="{layout}"
+      data-shape="{shape}"
+      data-size="{size}"
+      style="--wire-avatar-group-columns:{columns}; --wire-avatar-group-ring:{borderColor || 'var(--wire-color-bg)'}"
+      role="group"
+      aria-label="Avatar group"
+    >
+        <div class="wire-next__avatar-group-members">
+        {#each visibleMembers() as item}
+          <span
+            class="wire-next__avatar-group-member"
+            data-size="{item.size || size}"
+            data-shape="{item.shape || shape}"
+            data-color="{item.color || color}"
+            data-variant="{item.variant || variant}"
+            tabindex="{showTooltips && (item.tooltip || item.name) ? '0' : '-1'}"
+            aria-label="{item.name || item.alt || item.initials || 'Group member'}"
+          >
+        <span class="wire-next__avatar-group-avatar">
+              {#if item.src}
+                <img src="{item.src}" alt="{item.alt || item.name || ''}" loading="lazy" />
+              {:else if item.initials}
+                <span aria-hidden="true">{item.initials}</span>
+              {:else}
+                <span class="icon-[lucide--user-round]" aria-hidden="true">
+        </span>
+              {/if}
+            </span>
+
+            {#if showTooltips && (item.tooltip || item.name)}
+              <span class="wire-next__avatar-group-tooltip" role="tooltip">
+                {item.tooltip || item.name}
+              </span>
+            {/if}
+          </span>
+        {/each}
+
+        {#if hiddenMembers().length > 0}
+          <span class="wire-next__avatar-group-overflow">
+        <button
+              type="button"
+              class="wire-next__avatar-group-overflow-button"
+              aria-label="{overflowLabel}"
+              aria-expanded="{overflowOpen ? 'true' : 'false'}"
+              @click="toggleOverflow(event)"
+            >
+              +{hiddenMembers().length}
+            </button>
+        <span
+              class="wire-next__avatar-group-menu"
+              role="menu"
+              data-show="overflowOpen"
+              aria-hidden="{overflowOpen ? 'false' : 'true'}"
+            >
+              {#each hiddenMembers() as item}
+                <span class="wire-next__avatar-group-menu-item" role="menuitem">
+        <span class="wire-next__avatar-group-menu-avatar">
+                    {#if item.src}
+                      <img src="{item.src}" alt="" loading="lazy" />
+                    {:else}
+                      <span>{item.initials || '?'}</span>
+                    {/if}
+                  </span>
+        <span>{item.name || item.alt || item.initials || 'Team member'}</span>
+        </span>
+              {/each}
+            </span>
+        </span>
+        {/if}
+      </div>
+        </div>
     }
 }
 
- + } diff --git a/app/pages/components/avatar.wrn b/app/pages/components/avatar.wrn index 04e528e5..4a4bf768 100644 --- a/app/pages/components/avatar.wrn +++ b/app/pages/components/avatar.wrn @@ -10,36 +10,107 @@ page Avatarcomponent {
W WRNexusJS - +
-
base component

Avatar

Theme-aware, responsive avatar component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Avatar
-  size="default"
+      
base component

Avatar

Theme-aware, responsive avatar component.

@wrnexus/ui 0.5.018 props0 slots3 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Avatar
+  src="src"
+  alt="alt"
+  initials="initials"
+  size="md"
   color="primary"
-  title="Avatar"
-  description="description"
-  items="[]"
-/>

Legacy mount name: data-component="Avatar".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
titlestringOptional"Avatar"
descriptionstringOptional""
itemsstringOptional[]
variantstringOptional"default"
classstringOptional""

Slots

  • default

Events

This component does not declare a custom event.

Source contract

Installed source: components/avatar.wrn

component Avatar {
+/>

Legacy mount name: data-component="Avatar".

Props and attributes

PropTypeRequirementDefault
srcstringOptional""
altstringOptional""
initialsstringOptional""
sizestringOptional"md"
colorstringOptional"primary"
variantstringOptional"solid"
shapestringOptional"circle"
statusstringOptional""
statusLabelstringOptional""
statusPositionstringOptional"bottom"
badgestringOptional""
badgeIconstringOptional""
badgeLabelstringOptional""
tooltipstringOptional""
namestringOptional""
descriptionstringOptional""
loadingstringOptional"lazy"
classstringOptional""

Slots

This component does not declare a slot.

Events

  • load
  • error
  • click

Source contract

Installed source: components/avatar.wrn

component Avatar {
   props {
-    size = "default"
+    @event load = function
+    @event error = function
+    @event click = function
+    src = ""
+    alt = ""
+    initials = ""
+    size = "md"
     color = "primary"
-    title = "Avatar"
+    variant = "solid"
+    shape = "circle"
+
+    status = ""
+    statusLabel = ""
+    statusPosition = "bottom"
+
+    badge = ""
+    badgeIcon = ""
+    badgeLabel = ""
+
+    tooltip = ""
+    name = ""
     description = ""
-    items = []
-    variant = "default"
+    loading = "lazy"
     class = ""
   }
+
   view {
-        <section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--avatar wire-next--variant-{variant} {class}">
-      {#if title}<strong>{title}</strong>{/if}
-      {#if description}<p>{description}</p>{/if}
-      {#if items}<div class="wire-next__items">{#each items as item}<span>{item.label}</span>{/each}</div>{/if}
-      <slot />
-        </section>
+        <span
+      {...attrs}
+      class="wire-next wire-next--avatar {description ? 'wire-next--avatar-media' : ''} {class}"
+      data-wrn-avatar
+    >
+        <span
+        class="wire-next__avatar-wrap"
+        data-shape="{shape}"
+        data-size="{size}"
+        data-color="{color}"
+        data-variant="{variant}"
+        data-status-position="{statusPosition}"
+        tabindex="{tooltip ? '0' : '-1'}"
+        aria-label="{tooltip || name || alt || initials || 'Avatar'}"
+      >
+        <span class="wire-next__avatar">
+          {#if src}
+            <img src="{src}" alt="{alt || name}" loading="{loading}" />
+          {:else if initials}
+            <span class="wire-next__avatar-initials" aria-hidden="true">{initials}</span>
+          {:else}
+            <span class="wire-next__avatar-placeholder icon-[lucide--user-round]" aria-hidden="true">
+        </span>
+          {/if}
+        </span>
+
+        {#if status}
+          <span
+            class="wire-next__avatar-status"
+            data-status="{status}"
+            title="{statusLabel || status}"
+            aria-label="{statusLabel || status}"
+          >
+        </span>
+        {/if}
+
+        {#if badgeIcon}
+          <span class="wire-next__avatar-badge" aria-label="{badgeLabel || 'Linked account'}">
+        <span class="{badgeIcon}" aria-hidden="true">
+        </span>
+        </span>
+        {:else if badge}
+          <span class="wire-next__avatar-badge wire-next__avatar-badge--text" aria-label="{badgeLabel || badge}">
+            {badge}
+          </span>
+        {/if}
+
+        {#if tooltip}
+          <span class="wire-next__avatar-tooltip" role="tooltip">{tooltip}</span>
+        {/if}
+      </span>
+
+      {#if description}
+        <span class="wire-next__avatar-copy">
+        <strong>{name || alt || initials}</strong>
+        <span>{description}</span>
+        </span>
+      {/if}
+    </span>
     }
 }
 
- + } diff --git a/app/pages/components/badge.wrn b/app/pages/components/badge.wrn index 849cc6e5..eeb92386 100644 --- a/app/pages/components/badge.wrn +++ b/app/pages/components/badge.wrn @@ -10,36 +10,125 @@ page Badgecomponent {
W WRNexusJS - +
-
base component

Badge

Theme-aware, responsive badge component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Badge
-  size="default"
+      
base component

Badge

Theme-aware, responsive badge component.

@wrnexus/ui 0.5.022 props0 slots1 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Badge
+  label="Badge"
+  size="md"
   color="primary"
-  title="Badge"
-  description="description"
-  items="[]"
-/>

Legacy mount name: data-component="Badge".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
titlestringOptional"Badge"
descriptionstringOptional""
itemsstringOptional[]
variantstringOptional"default"
classstringOptional""

Slots

  • default

Events

This component does not declare a custom event.

Source contract

Installed source: components/badge.wrn

component Badge {
+  variant="solid"
+  shape="pill"
+/>

Legacy mount name: data-component="Badge".

Props and attributes

PropTypeRequirementDefault
labelstringOptional"Badge"
sizestringOptional"md"
colorstringOptional"primary"
variantstringOptional"solid"
shapestringOptional"pill"
classstringOptional""
iconstringOptional""
iconPositionstringOptional"start"
dotbooleanOptionalfalse
dotOnlybooleanOptionalfalse
dotLabelstringOptional"Status"
animatedbooleanOptionalfalse
avatarSrcstringOptional""
avatarAltstringOptional""
dismissiblebooleanOptionalfalse
dismissLabelstringOptional"Remove badge"
truncatebooleanOptionalfalse
maxWidthstringOptional"12rem"
anchorLabelstringOptional""
anchorIconstringOptional""
placementstringOptional"inline"
anchorLabelTextstringOptional"Badge anchor"

Slots

This component does not declare a slot.

Events

  • dismiss

Source contract

Installed source: components/Badge.wrn

component Badge {
   props {
-    size = "default"
+    label = "Badge"
+    size = "md"
     color = "primary"
-    title = "Badge"
-    description = ""
-    items = []
-    variant = "default"
+    variant = "solid"
+    shape = "pill"
     class = ""
+
+    icon = ""
+    iconPosition = "start"
+    dot = false
+    dotOnly = false
+    dotLabel = "Status"
+    animated = false
+
+    avatarSrc = ""
+    avatarAlt = ""
+    dismissible = false
+    dismissLabel = "Remove badge"
+    truncate = false
+    maxWidth = "12rem"
+
+    anchorLabel = ""
+    anchorIcon = ""
+    placement = "inline"
+    anchorLabelText = "Badge anchor"
+
+    @event dismiss = function
   }
+
+  state visible = true
+
+  functions {
+    function dismissBadge(sourceEvent, root, customEvent) {
+      visible = false
+      root = sourceEvent.currentTarget.closest("[data-wrn-badge]")
+      customEvent = document.createEvent("CustomEvent")
+      customEvent.initCustomEvent("dismiss", true, false, {
+        component: "Badge",
+        label: label
+      })
+      root.dispatchEvent(customEvent)
+    }
+  }
+
   view {
-        <section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--badge wire-next--variant-{variant} {class}">
-      {#if title}<strong>{title}</strong>{/if}
-      {#if description}<p>{description}</p>{/if}
-      {#if items}<div class="wire-next__items">{#each items as item}<span>{item.label}</span>{/each}</div>{/if}
-      <slot />
-        </section>
+        <span
+      {...attrs}
+      class="wire-next wire-next--badge-root {anchorLabel || anchorIcon ? 'wire-next--badge-anchored' : ''} {class}"
+      data-wrn-badge
+      data-placement="{placement}"
+      data-show="visible"
+      aria-hidden="{visible ? 'false' : 'true'}"
+    >
+      {#if anchorLabel || anchorIcon}
+        <button type="button" class="wire-next__badge-anchor" aria-label="{anchorLabelText}">
+          {#if anchorIcon}<span class="{anchorIcon}" aria-hidden="true">
+        </span>{/if}
+          {#if anchorLabel}<span>{anchorLabel}</span>{/if}
+        </button>
+      {/if}
+
+      <span
+        class="wire-next__badge"
+        data-size="{size}"
+        data-color="{color}"
+        data-variant="{variant}"
+        data-shape="{shape}"
+        data-animated="{animated ? 'true' : 'false'}"
+        style="--wire-badge-max-width:{maxWidth}"
+        role="{dotOnly ? 'status' : ''}"
+        aria-label="{dotOnly ? dotLabel : ''}"
+      >
+        {#if animated}
+          <span class="wire-next__badge-ping" aria-hidden="true">
+        </span>
+        {/if}
+        {#if avatarSrc}
+          <img class="wire-next__badge-avatar" src="{avatarSrc}" alt="{avatarAlt}" loading="lazy" />
+        {/if}
+        {#if dot || dotOnly}
+          <span class="wire-next__badge-dot" aria-hidden="true">
+        </span>
+        {/if}
+        {#if icon && iconPosition === "start"}
+          <span class="wire-next__badge-icon {icon}" aria-hidden="true">
+        </span>
+        {/if}
+        {#if !dotOnly}
+          <span class="wire-next__badge-label {truncate ? 'wire-next__badge-label--truncate' : ''}">
+            {label}
+          </span>
+        {/if}
+        {#if icon && iconPosition === "end"}
+          <span class="wire-next__badge-icon {icon}" aria-hidden="true">
+        </span>
+        {/if}
+        {#if dismissible}
+          <button type="button" class="wire-next__badge-dismiss" aria-label="{dismissLabel}" @click="dismissBadge(event)">
+        <span class="icon-[lucide--x]" aria-hidden="true">
+        </span>
+        </button>
+        {/if}
+      </span>
+        </span>
     }
 }
 
- + } diff --git a/app/pages/components/blockquote.wrn b/app/pages/components/blockquote.wrn index 0a28876b..226d9172 100644 --- a/app/pages/components/blockquote.wrn +++ b/app/pages/components/blockquote.wrn @@ -10,36 +10,86 @@ page Blockquotecomponent {
W WRNexusJS - +
-
base component

Blockquote

Theme-aware, responsive blockquote component.

@wrnexus/ui 0.4.07 props1 slots0 events

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

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
titlestringOptional"Blockquote"
descriptionstringOptional""
itemsstringOptional[]
variantstringOptional"default"
classstringOptional""

Slots

  • default

Events

This component does not declare a custom event.

Source contract

Installed source: components/Blockquote.wrn

component Blockquote {
+      
base component

Blockquote

Theme-aware, responsive blockquote component.

@wrnexus/ui 0.5.013 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Blockquote
+  quote="I just wanted to say that I'm very happy with my purchase so far. The documentation is outstanding - clear and detailed."
+  citation="citation"
+  citationTitle="citationTitle"
+  citationUrl="citationUrl"
+  avatarSrc="avatarSrc"
+/>

Legacy mount name: data-component="Blockquote".

Props and attributes

PropTypeRequirementDefault
quotestringOptional"I just wanted to say that I'm very happy with my purchase so far. The documentation is outstanding - clear and detailed."
citationstringOptional""
citationTitlestringOptional""
citationUrlstringOptional""
avatarSrcstringOptional""
avatarAltstringOptional""
sizestringOptional"md"
colorstringOptional"primary"
alignstringOptional"left"
variantstringOptional"default"
quoteMarkbooleanOptionaltrue
italicbooleanOptionaltrue
classstringOptional""

Slots

  • default

Events

This component does not declare a custom event.

Source contract

Installed source: components/Blockquote.wrn

component Blockquote {
   props {
-    size = "default"
+    quote = "I just wanted to say that I'm very happy with my purchase so far. The documentation is outstanding - clear and detailed."
+    citation = ""
+    citationTitle = ""
+    citationUrl = ""
+    avatarSrc = ""
+    avatarAlt = ""
+    size = "md"
     color = "primary"
-    title = "Blockquote"
-    description = ""
-    items = []
+    align = "left"
     variant = "default"
+    quoteMark = true
+    italic = true
     class = ""
   }
+
   view {
-        <section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--blockquote wire-next--variant-{variant} {class}">
-      {#if title}<strong>{title}</strong>{/if}
-      {#if description}<p>{description}</p>{/if}
-      {#if items}<div class="wire-next__items">{#each items as item}<span>{item.label}</span>{/each}</div>{/if}
-      <slot />
-        </section>
+        <figure
+      {...attrs}
+      class="wire-next wire-next--blockquote wire-next--color-{color} wire-next--size-{size} {class}"
+      data-size="{size}"
+      data-color="{color}"
+      data-align="{align}"
+      data-variant="{variant}"
+      data-italic="{italic}"
+    >
+        <blockquote cite="{citationUrl}">
+        {#if quoteMark}
+          <span class="wire-next__blockquote-mark" aria-hidden="true">“</span>
+        {/if}
+
+        <div class="wire-next__blockquote-copy">
+          {#if quote}
+            <p>{quote}</p>
+          {:else}
+            <slot />
+          {/if}
+        </div>
+        </blockquote>
+
+      {#if citation || citationTitle || avatarSrc}
+        <figcaption class="wire-next__blockquote-citation">
+          {#if avatarSrc}
+            <img
+              class="wire-next__blockquote-avatar"
+              src="{avatarSrc}"
+              alt="{avatarAlt}"
+              loading="lazy"
+            />
+          {/if}
+
+          <span class="wire-next__blockquote-attribution">
+            {#if citation}
+              {#if citationUrl}
+                <cite>
+        <a href="{citationUrl}">{citation}</a>
+        </cite>
+              {:else}
+                <cite>{citation}</cite>
+              {/if}
+            {/if}
+            {#if citationTitle}<span>{citationTitle}</span>{/if}
+          </span>
+        </figcaption>
+      {/if}
+    </figure>
     }
 }
 
- + } diff --git a/app/pages/components/breadcrumb.wrn b/app/pages/components/breadcrumb.wrn index 0713fabc..496983b5 100644 --- a/app/pages/components/breadcrumb.wrn +++ b/app/pages/components/breadcrumb.wrn @@ -10,17 +10,19 @@ page Breadcrumbcomponent {
W WRNexusJS - +
-
navigation component

Breadcrumb

Theme-aware, responsive breadcrumb component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Breadcrumb
+      
navigation component

Breadcrumb

Theme-aware, responsive breadcrumb component.

@wrnexus/ui 0.5.07 props1 slots2 events

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

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
labelstringOptional"Breadcrumb"
itemsstringOptional[]
activestringOptional""
orientationstringOptional"horizontal"
classstringOptional""

Slots

  • default

Events

This component does not declare a custom event.

Source contract

Installed source: components/Breadcrumb.wrn

component Breadcrumb {
+/>

Legacy mount name: data-component="Breadcrumb".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
labelstringOptional"Breadcrumb"
itemsstringOptional[]
activestringOptional""
orientationstringOptional"horizontal"
classstringOptional""

Slots

  • default

Events

  • navigate
  • click

Source contract

Installed source: components/Breadcrumb.wrn

component Breadcrumb {
   props {
+    @event navigate = function
+    @event click = function
     size = "default"
     color = "primary"
     label = "Breadcrumb"
@@ -37,7 +39,7 @@ page Breadcrumbcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/button-group.wrn b/app/pages/components/button-group.wrn index cfbe786d..97d0362b 100644 --- a/app/pages/components/button-group.wrn +++ b/app/pages/components/button-group.wrn @@ -10,36 +10,107 @@ page ButtonGroupcomponent {
W WRNexusJS - +
-
base component

ButtonGroup

Theme-aware, responsive button group component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<ButtonGroup
-  size="default"
-  color="primary"
-  title="Button Group"
-  description="description"
+      
base component

ButtonGroup

Theme-aware, responsive button group component.

@wrnexus/ui 0.5.013 props1 slots3 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<ButtonGroup
   items="[]"
-/>

Legacy mount name: data-component="ButtonGroup".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
titlestringOptional"Button Group"
descriptionstringOptional""
itemsstringOptional[]
variantstringOptional"default"
classstringOptional""

Slots

  • default

Events

This component does not declare a custom event.

Source contract

Installed source: components/ButtonGroup.wrn

component ButtonGroup {
+  value="value"
+  size="md"
+  color="primary"
+  variant="default"
+/>

Legacy mount name: data-component="ButtonGroup".

Props and attributes

PropTypeRequirementDefault
itemsstringOptional[]
valuestringOptional""
sizestringOptional"md"
colorstringOptional"primary"
variantstringOptional"default"
orientationstringOptional"horizontal"
responsivebooleanOptionalfalse
attachedbooleanOptionaltrue
selectablebooleanOptionalfalse
toolbarbooleanOptionalfalse
disabledbooleanOptionalfalse
ariaLabelstringOptional"Button group"
classstringOptional""

Slots

  • default

Events

  • click
  • select
  • change

Source contract

Installed source: components/ButtonGroup.wrn

component ButtonGroup {
   props {
-    size = "default"
-    color = "primary"
-    title = "Button Group"
-    description = ""
+    @event click = function
+    @event select = function
+    @event change = function
     items = []
+    value = ""
+    size = "md"
+    color = "primary"
     variant = "default"
+    orientation = "horizontal"
+    responsive = false
+    attached = true
+    selectable = false
+    toolbar = false
+    disabled = false
+    ariaLabel = "Button group"
     class = ""
   }
+
+  state selectedValue = value
+
+  functions {
+    function itemValue(item, index) {
+      return item.value || item.label || String(index)
+    }
+
+    function selectItem(item, index) {
+      previousValue = selectedValue
+      nextValue = itemValue(item, index)
+
+      $emit("select", {
+        value: nextValue,
+        previousValue: previousValue,
+        item: item,
+        index: index
+      })
+
+      if (selectable && previousValue !== nextValue) {
+        selectedValue = nextValue
+        $emit("change", {
+          value: nextValue,
+          previousValue: previousValue,
+          item: item,
+          index: index
+        })
+      }
+    }
+  }
+
   view {
-        <section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--button-group wire-next--variant-{variant} {class}">
-      {#if title}<strong>{title}</strong>{/if}
-      {#if description}<p>{description}</p>{/if}
-      {#if items}<div class="wire-next__items">{#each items as item}<span>{item.label}</span>{/each}</div>{/if}
+        <div
+      {...attrs}
+      class="wire-next wire-next--button-group {class}"
+      role="{toolbar ? 'toolbar' : 'group'}"
+      aria-label="{ariaLabel}"
+      aria-orientation="{orientation}"
+      data-size="{size}"
+      data-color="{color}"
+      data-variant="{variant}"
+      data-orientation="{orientation}"
+      data-responsive="{responsive}"
+      data-attached="{attached}"
+      data-selectable="{selectable}"
+      data-disabled="{disabled}"
+    >
+      {#if items}
+        {#each items as item, index}
+          <button
+            type="{item.type || 'button'}"
+            class="wire-btn wire-btn--variant-{item.variant || variant} wire-btn--color-{item.color || color} wire-btn--size-{item.size || size}"
+            disabled="{disabled || item.disabled}"
+            aria-label="{item.ariaLabel || item.label}"
+            aria-pressed="{selectable ? (selectedValue === (item.value || item.label || String(index)) ? 'true' : 'false') : ''}"
+            data-value="{item.value || item.label || String(index)}"
+            data-selected="{selectable && selectedValue === (item.value || item.label || String(index)) ? 'true' : 'false'}"
+            @click="selectItem(item, index)"
+          >
+            {#if item.icon}
+              <span class="wire-btn__icon {item.icon}" aria-hidden="true">
+        </span>
+            {/if}
+            <span class="wire-btn__label">{item.label}</span>
+        </button>
+        {/each}
+      {/if}
       <slot />
-        </section>
+        </div>
     }
 }
 
- + } diff --git a/app/pages/components/button.wrn b/app/pages/components/button.wrn index f0e3443a..fb090cd2 100644 --- a/app/pages/components/button.wrn +++ b/app/pages/components/button.wrn @@ -10,17 +10,20 @@ page Buttoncomponent {
W WRNexusJS - +
-
base component

Button

Theme-aware, responsive button component.

@wrnexus/ui 0.4.025 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Button
+      
base component

Button

Theme-aware, responsive button component.

@wrnexus/ui 0.5.025 props1 slots3 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Button
   label="Button"
   loadingLabel="Loading…"
   description="description"
   as="as"
   href="href"
-/>

Legacy mount name: data-component="Button".

Props and attributes

PropTypeRequirementDefault
labelstringOptional"Button"
loadingLabelstringOptional"Loading…"
descriptionstringOptional""
asstringOptional""
hrefstringOptional""
targetstringOptional""
relstringOptional""
typestringOptional"button"
variantstringOptional"default"
colorstringOptional"primary"
sizestringOptional"default"
disabledbooleanOptionalfalse
loadingbooleanOptionalfalse
pillbooleanOptionalfalse
fullWidthbooleanOptionalfalse
iconstringOptional""
iconPositionstringOptional"start"
ariaLabelstringOptional""
ariaPressedstringOptional""
ariaExpandedstringOptional""
ariaControlsstringOptional""
titlestringOptional""
autofocusbooleanOptionalfalse
controlClassstringOptional""
classstringOptional""

Slots

  • default

Events

This component does not declare a custom event.

Source contract

Installed source: components/button.wrn

component Button {
+/>

Legacy mount name: data-component="Button".

Props and attributes

PropTypeRequirementDefault
labelstringOptional"Button"
loadingLabelstringOptional"Loading…"
descriptionstringOptional""
asstringOptional""
hrefstringOptional""
targetstringOptional""
relstringOptional""
typestringOptional"button"
variantstringOptional"default"
colorstringOptional"primary"
sizestringOptional"default"
disabledbooleanOptionalfalse
loadingbooleanOptionalfalse
pillbooleanOptionalfalse
fullWidthbooleanOptionalfalse
iconstringOptional""
iconPositionstringOptional"start"
ariaLabelstringOptional""
ariaPressedstringOptional""
ariaExpandedstringOptional""
ariaControlsstringOptional""
titlestringOptional""
autofocusbooleanOptionalfalse
controlClassstringOptional""
classstringOptional""

Slots

  • default

Events

  • click
  • focus
  • blur

Source contract

Installed source: components/button.wrn

component Button {
   props {
+    @event click = function
+    @event focus = function
+    @event blur = function
     label = "Button"
     loadingLabel = "Loading…"
     description = ""
@@ -181,7 +184,7 @@ page Buttoncomponent {
     }
 }
 
- + } diff --git a/app/pages/components/card.wrn b/app/pages/components/card.wrn index a8055fb8..b6e69c5b 100644 --- a/app/pages/components/card.wrn +++ b/app/pages/components/card.wrn @@ -10,36 +10,280 @@ page Cardcomponent {
W WRNexusJS - +
-
base component

Card

Theme-aware, responsive card component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Card
-  size="default"
-  color="primary"
-  title="Card"
+      
base component

Card

Theme-aware, responsive card component.

@wrnexus/ui 0.5.031 props1 slots6 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Card
+  title="Card title"
+  subtitle="subtitle"
   description="description"
-  items="[]"
-/>

Legacy mount name: data-component="Card".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
titlestringOptional"Card"
descriptionstringOptional""
itemsstringOptional[]
variantstringOptional"default"
classstringOptional""

Slots

  • default

Events

This component does not declare a custom event.

Source contract

Installed source: components/card.wrn

component Card {
+  header="header"
+  footer="footer"
+/>

Legacy mount name: data-component="Card".

Props and attributes

PropTypeRequirementDefault
titlestringOptional"Card title"
subtitlestringOptional""
descriptionstringOptional""
headerstringOptional""
footerstringOptional""
imageSrcstringOptional""
imageAltstringOptional""
imagePositionstringOptional"top"
actionLabelstringOptional""
actionHrefstringOptional""
headerActionsstringOptional[]
navigationstringOptional[]
activeNavstringOptional""
mobileNavigationbooleanOptionalfalse
alertTitlestringOptional""
alertDescriptionstringOptional""
emptybooleanOptionalfalse
emptyTitlestringOptional"No data to show"
emptyIconstringOptional"icon-[lucide--inbox]"
itemsstringOptional[]
sizestringOptional"md"
colorstringOptional"primary"
variantstringOptional"default"
layoutstringOptional"vertical"
alignstringOptional"left"
hoverstringOptional"none"
scrollablebooleanOptionalfalse
maxHeightstringOptional"18rem"
dismissiblebooleanOptionalfalse
ariaLabelstringOptional""
classstringOptional""

Slots

  • default

Events

  • click
  • action
  • navigate
  • dismiss
  • load
  • error

Source contract

Installed source: components/card.wrn

component Card {
   props {
-    size = "default"
-    color = "primary"
-    title = "Card"
+    @event click = function
+    @event action = function
+    @event navigate = function
+    @event dismiss = function
+    @event load = function
+    @event error = function
+    title = "Card title"
+    subtitle = ""
     description = ""
+    header = ""
+    footer = ""
+    imageSrc = ""
+    imageAlt = ""
+    imagePosition = "top"
+    actionLabel = ""
+    actionHref = ""
+    headerActions = []
+    navigation = []
+    activeNav = ""
+    mobileNavigation = false
+    alertTitle = ""
+    alertDescription = ""
+    empty = false
+    emptyTitle = "No data to show"
+    emptyIcon = "icon-[lucide--inbox]"
     items = []
+    size = "md"
+    color = "primary"
     variant = "default"
+    layout = "vertical"
+    align = "left"
+    hover = "none"
+    scrollable = false
+    maxHeight = "18rem"
+    dismissible = false
+    ariaLabel = ""
     class = ""
   }
+
+  state visible = true
+  state selectedNav = activeNav
+
+  functions {
+    function chooseNavigation(item, index) {
+      previousValue = selectedNav
+      selectedNav = item.value || item.label
+      $emit("navigate", {
+        value: selectedNav,
+        previousValue: previousValue,
+        item: item,
+        index: index
+      })
+    }
+
+    function chooseMobileNavigation(sourceEvent) {
+      previousValue = selectedNav
+      selectedNav = sourceEvent.target.value
+      $emit("navigate", {
+        value: selectedNav,
+        previousValue: previousValue
+      })
+    }
+
+    function chooseAction(action, index) {
+      $emit("action", {
+        action: action,
+        index: index
+      })
+    }
+
+    function dismissCard(sourceEvent) {
+      panel = sourceEvent.currentTarget.closest(".wire-next__card-panel")
+      if (panel) {
+        panel.setAttribute("hidden", "")
+      }
+      visible = false
+      $emit("dismiss", {
+        title: title
+      })
+    }
+  }
+
   view {
-        <section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--card wire-next--variant-{variant} {class}">
-      {#if title}<strong>{title}</strong>{/if}
-      {#if description}<p>{description}</p>{/if}
-      {#if items}<div class="wire-next__items">{#each items as item}<span>{item.label}</span>{/each}</div>{/if}
-      <slot />
-        </section>
+        <section
+      {...attrs}
+      class="wire-next wire-next--card {class}"
+      data-size="{size}"
+      data-color="{color}"
+      data-variant="{variant}"
+      data-layout="{layout}"
+      data-align="{align}"
+      data-hover="{hover}"
+      data-image-position="{imagePosition}"
+      data-group="{items.length > 0}"
+      aria-label="{ariaLabel || title}"
+    >
+      {#if items.length > 0}
+        <div class="wire-next__card-group">
+          {#each items as item}
+            <article class="wire-next__card-panel">
+              {#if item.imageSrc}
+                <div class="wire-next__card-media">
+        <img src="{item.imageSrc}" alt="{item.imageAlt || ''}" loading="lazy" />
+        </div>
+              {/if}
+              <div class="wire-next__card-body">
+                {#if item.title}<h3>{item.title}</h3>{/if}
+                {#if item.description}<p>{item.description}</p>{/if}
+              </div>
+              {#if item.footer}<footer class="wire-next__card-footer">{item.footer}</footer>{/if}
+            </article>
+          {/each}
+        </div>
+      {:else if visible}
+        <article class="wire-next__card-panel">
+          {#if imagePosition === "overlay" && imageSrc}
+            <div class="wire-next__card-media wire-next__card-media--overlay">
+        <img
+                src="{imageSrc}"
+                alt="{imageAlt}"
+                loading="lazy"
+                @load="$emit('load', { src: imageSrc })"
+                @error="$emit('error', { src: imageSrc })"
+              />
+        <div class="wire-next__card-overlay">
+                {#if title}<h3>{title}</h3>{/if}
+                {#if subtitle}<span class="wire-next__card-subtitle">{subtitle}</span>{/if}
+                {#if description}<p>{description}</p>{/if}
+                {#if footer}<small>{footer}</small>{/if}
+              </div>
+        </div>
+          {:else}
+            {#if header || headerActions.length > 0 || dismissible}
+              <header class="wire-next__card-header">
+        <span>{header}</span>
+                {#if headerActions.length > 0 || dismissible}
+                  <span class="wire-next__card-header-actions">
+                    {#each headerActions as action, index}
+                      <button
+                        type="button"
+                        aria-label="{action.ariaLabel || action.label}"
+                        title="{action.label}"
+                        @click="chooseAction(action, index)"
+                      >
+                        {#if action.icon}<span class="{action.icon}" aria-hidden="true">
+        </span>{/if}
+                        {#if !action.icon}<span>{action.label}</span>{/if}
+                      </button>
+                    {/each}
+                    {#if dismissible}
+                      <button type="button" aria-label="Close card" @click="dismissCard(event)">
+        <span class="icon-[lucide--x]" aria-hidden="true">
+        </span>
+        </button>
+                    {/if}
+                  </span>
+                {/if}
+              </header>
+            {/if}
+
+            {#if navigation.length > 0}
+              <nav class="wire-next__card-navigation" aria-label="{ariaLabel || title}">
+        <div class="wire-next__card-tabs">
+                  {#each navigation as item, index}
+                    <button
+                      type="button"
+                      data-active="{selectedNav === (item.value || item.label)}"
+                      aria-current="{selectedNav === (item.value || item.label) ? 'page' : ''}"
+                      @click="chooseNavigation(item, index)"
+                    >
+                      {item.label}
+                    </button>
+                  {/each}
+                </div>
+                {#if mobileNavigation}
+                  <select
+                    class="wire-next__card-navigation-select"
+                    aria-label="{ariaLabel || title}"
+                    value="{selectedNav}"
+                    @change="chooseMobileNavigation(event)"
+                  >
+                    {#each navigation as item}
+                      <option
+                        value="{item.value || item.label}"
+                        selected="{selectedNav === (item.value || item.label)}"
+                      >
+                        {item.label}
+                      </option>
+                    {/each}
+                  </select>
+                {/if}
+              </nav>
+            {/if}
+
+            {#if imageSrc && imagePosition !== "bottom"}
+              <div class="wire-next__card-media">
+        <img
+                  src="{imageSrc}"
+                  alt="{imageAlt}"
+                  loading="lazy"
+                  @load="$emit('load', { src: imageSrc })"
+                  @error="$emit('error', { src: imageSrc })"
+                />
+        </div>
+            {/if}
+
+            {#if alertTitle || alertDescription}
+              <aside class="wire-next__card-alert" role="status">
+                {#if alertTitle}<strong>{alertTitle}</strong>{/if}
+                {#if alertDescription}<span>{alertDescription}</span>{/if}
+              </aside>
+            {/if}
+
+            <div
+              class="wire-next__card-body"
+              data-scrollable="{scrollable}"
+              style="--wire-card-max-height: {maxHeight}"
+            >
+              {#if empty}
+                <div class="wire-next__card-empty">
+        <span class="{emptyIcon}" aria-hidden="true">
+        </span>
+        <strong>{emptyTitle}</strong>
+        </div>
+              {:else}
+                {#if title}<h3>{title}</h3>{/if}
+                {#if subtitle}<span class="wire-next__card-subtitle">{subtitle}</span>{/if}
+                {#if description}<p>{description}</p>{/if}
+                <slot />
+                {#if actionLabel}
+                  <a
+                    class="wire-next__card-action"
+                    href="{actionHref || '#'}"
+                    @click="$emit('action', { label: actionLabel, href: actionHref })"
+                  >
+                    {actionLabel}<span class="icon-[lucide--chevron-right]" aria-hidden="true">
+        </span>
+        </a>
+                {/if}
+              {/if}
+            </div>
+
+            {#if footer}<footer class="wire-next__card-footer">{footer}</footer>{/if}
+
+            {#if imageSrc && imagePosition === "bottom"}
+              <div class="wire-next__card-media">
+        <img
+                  src="{imageSrc}"
+                  alt="{imageAlt}"
+                  loading="lazy"
+                  @load="$emit('load', { src: imageSrc })"
+                  @error="$emit('error', { src: imageSrc })"
+                />
+        </div>
+            {/if}
+          {/if}
+        </article>
+      {/if}
+    </section>
     }
 }
 
- + } diff --git a/app/pages/components/carousel.wrn b/app/pages/components/carousel.wrn index 51a4829c..1c89386b 100644 --- a/app/pages/components/carousel.wrn +++ b/app/pages/components/carousel.wrn @@ -10,36 +10,480 @@ page Carouselcomponent {
W WRNexusJS - +
-
base component

Carousel

Theme-aware, responsive carousel component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Carousel
+      
base component

Carousel

Theme-aware, responsive carousel component.

@wrnexus/ui 0.5.022 props1 slots10 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Carousel
   size="default"
   color="primary"
-  title="Carousel"
+  title="title"
   description="description"
   items="[]"
-/>

Legacy mount name: data-component="Carousel".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
titlestringOptional"Carousel"
descriptionstringOptional""
itemsstringOptional[]
variantstringOptional"default"
classstringOptional""

Slots

  • default

Events

This component does not declare a custom event.

Source contract

Installed source: components/Carousel.wrn

component Carousel {
+/>

Legacy mount name: data-component="Carousel".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
titlestringOptional""
descriptionstringOptional""
itemsstringOptional[]
activeIndexnumberOptional0
slidesPerViewnumberOptional1
gapstringOptional"0.75rem"
showPaginationbooleanOptionalfalse
isAutoPlaybooleanOptionalfalse
autoplayIntervalnumberOptional4000
isInfiniteLoopbooleanOptionalfalse
isRTLbooleanOptionalfalse
isCenteredbooleanOptionalfalse
isDraggablebooleanOptionalfalse
isAutoHeightbooleanOptionalfalse
isSnapbooleanOptionalfalse
showCounterbooleanOptionalfalse
thumbnailsstringOptional"none"
ariaLabelstringOptional"Content carousel"
variantstringOptional"default"
classstringOptional""

Slots

  • default

Events

  • initialize
  • change
  • previous
  • next
  • play
  • pause
  • reachStart
  • reachEnd
  • dragStart
  • dragEnd

Source contract

Installed source: components/carousel.wrn

// Interactive, hydration-safe content carousel.
+component Carousel {
   props {
+    @event initialize = function
+    @event change = function
+    @event previous = function
+    @event next = function
+    @event play = function
+    @event pause = function
+    @event reachStart = function
+    @event reachEnd = function
+    @event dragStart = function
+    @event dragEnd = function
     size = "default"
     color = "primary"
-    title = "Carousel"
+    title = ""
     description = ""
     items = []
+    activeIndex = 0
+    slidesPerView = 1
+    gap = "0.75rem"
+    showPagination = false
+    isAutoPlay = false
+    autoplayInterval = 4000
+    isInfiniteLoop = false
+    isRTL = false
+    isCentered = false
+    isDraggable = false
+    isAutoHeight = false
+    isSnap = false
+    showCounter = false
+    thumbnails = "none"
+    ariaLabel = "Content carousel"
     variant = "default"
     class = ""
   }
+
+  state currentIndex = activeIndex
+  state playing = false
+  state dragOrigin = null
+  state dragOffset = 0
+  state autoplayTimer = null
+  state carouselRoot = null
+
+  functions {
+    function slideCount() {
+      return items.length
+    }
+
+    function maximumIndex(count, visible) {
+      count = slideCount()
+      visible = Math.max(1, Number(slidesPerView) || 1)
+      if (isCentered || isSnap) {
+        return Math.max(0, count - 1)
+      }
+      return Math.max(0, count - visible)
+    }
+
+    function normalizedIndex(index, maximum) {
+      maximum = maximumIndex()
+      if (slideCount() === 0) {
+        return 0
+      }
+      if (isInfiniteLoop) {
+        if (index < 0) {
+          return maximum
+        }
+        if (index > maximum) {
+          return 0
+        }
+      }
+      return Math.max(0, Math.min(index, maximum))
+    }
+
+    function rememberRoot(sourceEvent, root) {
+      if (!sourceEvent || !sourceEvent.currentTarget) {
+        return
+      }
+      root = sourceEvent.currentTarget.closest(".wire-next--carousel")
+      if (root) {
+        carouselRoot = root
+      }
+    }
+
+    function syncNavigation(sourceEvent, index, root, viewport, slides, slide, thumbnails, thumbnail, rail) {
+      rememberRoot(sourceEvent)
+      root = carouselRoot
+      if (!root) {
+        return
+      }
+      if (isSnap) {
+        viewport = root.querySelector(".wire-next__carousel-viewport")
+        slides = root.querySelectorAll(".wire-next__carousel-slide")
+        slide = slides[index]
+        if (viewport && slide) {
+          viewport.scrollTo({
+            left: slide.offsetLeft - (viewport.clientWidth - slide.clientWidth) / 2,
+            behavior: "smooth"
+          })
+        }
+      }
+      thumbnails = root.querySelectorAll(".wire-next__carousel-thumbnails button")
+      if (thumbnails[index]) {
+        thumbnail = thumbnails[index]
+        rail = thumbnail.parentElement
+        rail.scrollTo({
+          left: thumbnail.offsetLeft - (rail.clientWidth - thumbnail.clientWidth) / 2,
+          top: thumbnail.offsetTop - (rail.clientHeight - thumbnail.clientHeight) / 2,
+          behavior: "smooth"
+        })
+      }
+    }
+
+    function handleSnapScroll(sourceEvent, slides, viewport, viewportCenter, closestIndex, closestDistance, slide, slideCenter, distance, previousIndex) {
+      if (!isSnap) {
+        return
+      }
+      rememberRoot(sourceEvent)
+      viewport = sourceEvent.currentTarget
+      slides = viewport.querySelectorAll(".wire-next__carousel-slide")
+      viewportCenter = viewport.scrollLeft + viewport.clientWidth / 2
+      closestIndex = currentIndex
+      closestDistance = 1000000000
+      slides.forEach(function (candidate, index) {
+        slideCenter = candidate.offsetLeft + candidate.clientWidth / 2
+        distance = Math.abs(slideCenter - viewportCenter)
+        if (distance < closestDistance) {
+          closestDistance = distance
+          closestIndex = index
+        }
+      })
+      closestIndex = normalizedIndex(closestIndex)
+      if (closestIndex !== currentIndex) {
+        previousIndex = currentIndex
+        currentIndex = closestIndex
+        $emit("change", {
+          index: currentIndex,
+          previousIndex: previousIndex,
+          item: items[currentIndex],
+          reason: "snap"
+        })
+        slides = carouselRoot.querySelectorAll(".wire-next__carousel-thumbnails button")
+        slide = slides[currentIndex]
+        if (slide) {
+          viewport = slide.parentElement
+          viewport.scrollTo({
+            left: slide.offsetLeft - (viewport.clientWidth - slide.clientWidth) / 2,
+            top: slide.offsetTop - (viewport.clientHeight - slide.clientHeight) / 2,
+            behavior: "smooth"
+          })
+        }
+      }
+    }
+
+    function selectSlide(index, reason, sourceEvent, previousIndex) {
+      if (slideCount() === 0) {
+        return
+      }
+      previousIndex = currentIndex
+      currentIndex = normalizedIndex(Number(index))
+      syncNavigation(sourceEvent, currentIndex)
+      if (previousIndex === currentIndex && reason !== "initialize") {
+        return
+      }
+      $emit("change", {
+        index: currentIndex,
+        previousIndex: previousIndex,
+        item: items[currentIndex],
+        reason: reason || "select"
+      })
+      if (currentIndex === 0) {
+        $emit("reachStart", { index: currentIndex })
+      }
+      if (currentIndex === maximumIndex()) {
+        $emit("reachEnd", { index: currentIndex })
+      }
+    }
+
+    function previousSlide(sourceEvent, previousIndex) {
+      previousIndex = currentIndex
+      selectSlide(currentIndex - 1, "previous", sourceEvent)
+      $emit("previous", {
+        index: currentIndex,
+        previousIndex: previousIndex,
+        item: items[currentIndex]
+      })
+    }
+
+    function nextSlide(sourceEvent, previousIndex) {
+      previousIndex = currentIndex
+      selectSlide(currentIndex + 1, "next", sourceEvent)
+      $emit("next", {
+        index: currentIndex,
+        previousIndex: previousIndex,
+        item: items[currentIndex]
+      })
+    }
+
+    function handleKeydown(sourceEvent) {
+      if (sourceEvent.key === "ArrowLeft") {
+        sourceEvent.preventDefault()
+        if (isRTL) {
+          nextSlide(sourceEvent)
+        } else {
+          previousSlide(sourceEvent)
+        }
+      }
+      if (sourceEvent.key === "ArrowRight") {
+        sourceEvent.preventDefault()
+        if (isRTL) {
+          previousSlide(sourceEvent)
+        } else {
+          nextSlide(sourceEvent)
+        }
+      }
+      if (sourceEvent.key === "Home") {
+        sourceEvent.preventDefault()
+        selectSlide(0, "keyboard", sourceEvent)
+      }
+      if (sourceEvent.key === "End") {
+        sourceEvent.preventDefault()
+        selectSlide(maximumIndex(), "keyboard", sourceEvent)
+      }
+    }
+
+    function beginDrag(sourceEvent) {
+      if (!isDraggable || isSnap) {
+        return
+      }
+      sourceEvent.preventDefault()
+      dragOrigin = sourceEvent.clientX
+      dragOffset = 0
+      sourceEvent.currentTarget.setPointerCapture(sourceEvent.pointerId)
+      $emit("dragStart", { index: currentIndex, x: dragOrigin })
+    }
+
+    function moveDrag(sourceEvent) {
+      if (!isDraggable || isSnap || dragOrigin === null) {
+        return
+      }
+      sourceEvent.preventDefault()
+      dragOffset = sourceEvent.clientX - dragOrigin
+    }
+
+    function cancelDrag() {
+      dragOrigin = null
+      dragOffset = 0
+    }
+
+    function endDrag(sourceEvent, distance) {
+      if (!isDraggable || isSnap || dragOrigin === null) {
+        return
+      }
+      sourceEvent.preventDefault()
+      distance = dragOffset || sourceEvent.clientX - dragOrigin
+      dragOrigin = null
+      dragOffset = 0
+      if (Math.abs(distance) > 20) {
+        if ((distance < 0 && !isRTL) || (distance > 0 && isRTL)) {
+          nextSlide(sourceEvent)
+        } else {
+          previousSlide(sourceEvent)
+        }
+      }
+      $emit("dragEnd", {
+        index: currentIndex,
+        distance: distance
+      })
+    }
+
+    function advanceAutoplay() {
+      if (currentIndex >= maximumIndex()) {
+        selectSlide(0, "autoplay")
+      } else {
+        selectSlide(currentIndex + 1, "autoplay")
+      }
+    }
+
+    function startAutoplay() {
+      if (!isAutoPlay || playing || slideCount() < 2) {
+        return
+      }
+      playing = true
+      autoplayTimer = setInterval(advanceAutoplay, Math.max(1000, Number(autoplayInterval)))
+      $emit("play", { index: currentIndex, interval: autoplayInterval })
+    }
+
+    function pauseAutoplay() {
+      if (autoplayTimer) {
+        clearInterval(autoplayTimer)
+      }
+      autoplayTimer = null
+      if (playing) {
+        $emit("pause", { index: currentIndex })
+      }
+      playing = false
+    }
+
+  }
+
+  lifecycle {
+    mount {
+      $emit("initialize", { index: currentIndex, count: slideCount() })
+      startAutoplay()
+    }
+    unmount {
+      if (autoplayTimer) {
+        clearInterval(autoplayTimer)
+      }
+    }
+  }
+
   view {
-        <section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--carousel wire-next--variant-{variant} {class}">
-      {#if title}<strong>{title}</strong>{/if}
-      {#if description}<p>{description}</p>{/if}
-      {#if items}<div class="wire-next__items">{#each items as item}<span>{item.label}</span>{/each}</div>{/if}
-      <slot />
+        <section
+      {...attrs}
+      class="wire-next wire-next--carousel wire-next--color-{color} wire-next--size-{size} wire-next--variant-{variant} {class}"
+      data-rtl="{isRTL}"
+      data-centered="{isCentered}"
+      data-draggable="{isDraggable && !isSnap}"
+      data-dragging="{dragOrigin !== null}"
+      data-auto-height="{isAutoHeight}"
+      data-snap="{isSnap}"
+      data-thumbnails="{thumbnails}"
+      dir="{isRTL ? 'rtl' : 'ltr'}"
+      role="region"
+      aria-roledescription="carousel"
+      aria-label="{ariaLabel}"
+      @keydown="handleKeydown(event)"
+      @mouseenter="rememberRoot(event); pauseAutoplay()"
+      @mouseleave="startAutoplay()"
+      @focusin="rememberRoot(event); pauseAutoplay()"
+      @focusout="startAutoplay()"
+    >
+      {#if title || description}
+        <header class="wire-next__carousel-header">
+          {#if title}<h3>{title}</h3>{/if}
+          {#if description}<p>{description}</p>{/if}
+        </header>
+      {/if}
+
+        <div class="wire-next__carousel-layout">
+          {#if thumbnails === "vertical"}
+            <div class="wire-next__carousel-thumbnails" aria-label="Choose a slide">
+              {#each items as item, index}
+                <button
+                  type="button"
+                  data-active="{index === currentIndex}"
+                  aria-label="Show slide {index + 1}: {item.label || item.title}"
+                  aria-current="{index === currentIndex ? 'true' : 'false'}"
+                  @click="selectSlide(index, 'thumbnail', event)"
+                >
+                  {#if item.thumbnail}<img src="{item.thumbnail}" alt="" />{/if}
+                  <span>{item.label || item.title || "Slide " + (index + 1)}</span>
+        </button>
+              {/each}
+            </div>
+          {/if}
+
+          <div class="wire-next__carousel-main">
+        <div class="wire-next__carousel-stage">
+        <div
+                class="wire-next__carousel-viewport"
+                tabindex="0"
+                @scroll="handleSnapScroll(event)"
+                @pointerdown="beginDrag(event)"
+                @pointermove="moveDrag(event)"
+                @pointerup="endDrag(event)"
+                @pointercancel="cancelDrag()"
+                @lostpointercapture="cancelDrag()"
+              >
+        <div
+                  class="wire-next__carousel-track"
+                  style="--wire-carousel-index: {currentIndex}; --wire-carousel-per-view: {slidesPerView}; --wire-carousel-gap: {gap}; --wire-carousel-drag-offset: {dragOffset}px"
+                >
+                  {#each items as item, index}
+                    <article
+                      class="wire-next__carousel-slide"
+                      data-active="{index === currentIndex}"
+                      role="group"
+                      aria-roledescription="slide"
+                      aria-label="{index + 1} of {items.length}"
+                      aria-hidden="{index === currentIndex ? 'false' : 'true'}"
+                    >
+                      {#if item.imageSrc}
+                        <img src="{item.imageSrc}" alt="{item.imageAlt || item.title || ''}" />
+                      {/if}
+                      <div class="wire-next__carousel-slide-content">
+                        {#if item.eyebrow}<span>{item.eyebrow}</span>{/if}
+                        {#if item.title || item.label}<h4>{item.title || item.label}</h4>{/if}
+                        {#if item.description}<p>{item.description}</p>{/if}
+                        {#if item.actionLabel}
+                          <a href="{item.actionHref || '#'}">{item.actionLabel}</a>
+                        {/if}
+                      </div>
+        </article>
+                  {/each}
+                  <slot />
+        </div>
+        </div>
+        <button
+                class="wire-next__carousel-control wire-next__carousel-control--previous"
+                type="button"
+                aria-label="Previous slide"
+                disabled="{!isInfiniteLoop && currentIndex === 0}"
+                @click="previousSlide(event)"
+              >
+        <span class="icon-[lucide--chevron-left]" aria-hidden="true">
+        </span>
+        </button>
+        <button
+                class="wire-next__carousel-control wire-next__carousel-control--next"
+                type="button"
+                aria-label="Next slide"
+                disabled="{!isInfiniteLoop && currentIndex === maximumIndex()}"
+                @click="nextSlide(event)"
+              >
+        <span class="icon-[lucide--chevron-right]" aria-hidden="true">
+        </span>
+        </button>
+
+              {#if showCounter}
+                <output class="wire-next__carousel-counter" aria-live="polite">
+                  {currentIndex + 1} / {items.length}
+                </output>
+              {/if}
+            </div>
+
+            {#if showPagination}
+              <div class="wire-next__carousel-pagination" aria-label="Choose a slide">
+                {#each items as item, index}
+                  <button
+                    type="button"
+                    data-active="{index === currentIndex}"
+                    aria-label="Show slide {index + 1}"
+                    aria-current="{index === currentIndex ? 'true' : 'false'}"
+                    @click="selectSlide(index, 'pagination', event)"
+                  >
+        </button>
+                {/each}
+              </div>
+            {/if}
+
+            {#if thumbnails === "horizontal"}
+              <div class="wire-next__carousel-thumbnails" aria-label="Choose a slide">
+                {#each items as item, index}
+                  <button
+                    type="button"
+                    data-active="{index === currentIndex}"
+                    aria-label="Show slide {index + 1}: {item.label || item.title}"
+                    aria-current="{index === currentIndex ? 'true' : 'false'}"
+                    @click="selectSlide(index, 'thumbnail', event)"
+                  >
+                    {#if item.thumbnail}<img src="{item.thumbnail}" alt="" />{/if}
+                    <span>{item.label || item.title || "Slide " + (index + 1)}</span>
+        </button>
+                {/each}
+              </div>
+            {/if}
+          </div>
+        </div>
         </section>
     }
 }
 
- + } diff --git a/app/pages/components/chart.wrn b/app/pages/components/chart.wrn index 22f3eb91..ba1a2d31 100644 --- a/app/pages/components/chart.wrn +++ b/app/pages/components/chart.wrn @@ -10,17 +10,20 @@ page Chartcomponent {
W WRNexusJS - +
-
integrations component

Chart

Theme-aware, responsive chart component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Chart
+      
integrations component

Chart

Theme-aware, responsive chart component.

@wrnexus/ui 0.5.07 props1 slots3 events

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

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
titlestringOptional"Chart"
descriptionstringOptional""
itemsstringOptional[]
variantstringOptional"default"
classstringOptional""

Slots

  • default

Events

This component does not declare a custom event.

Source contract

Installed source: components/Chart.wrn

component Chart {
+/>

Legacy mount name: data-component="Chart".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
titlestringOptional"Chart"
descriptionstringOptional""
itemsstringOptional[]
variantstringOptional"default"
classstringOptional""

Slots

  • default

Events

  • select
  • dataPointClick
  • legendToggle

Source contract

Installed source: components/Chart.wrn

component Chart {
   props {
+    @event select = function
+    @event dataPointClick = function
+    @event legendToggle = function
     size = "default"
     color = "primary"
     title = "Chart"
@@ -39,7 +42,7 @@ page Chartcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/chat-bubble.wrn b/app/pages/components/chat-bubble.wrn index 15a6f826..754fbb64 100644 --- a/app/pages/components/chat-bubble.wrn +++ b/app/pages/components/chat-bubble.wrn @@ -10,36 +10,165 @@ page ChatBubblecomponent {
W WRNexusJS - +
-
base component

ChatBubble

Theme-aware, responsive chat bubble component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<ChatBubble
+      
base component

ChatBubble

Theme-aware, responsive chat bubble component.

@wrnexus/ui 0.5.011 props1 slots4 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<ChatBubble
   size="default"
   color="primary"
-  title="Chat Bubble"
+  title="title"
   description="description"
   items="[]"
-/>

Legacy mount name: data-component="ChatBubble".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
titlestringOptional"Chat Bubble"
descriptionstringOptional""
itemsstringOptional[]
variantstringOptional"default"
classstringOptional""

Slots

  • default

Events

This component does not declare a custom event.

Source contract

Installed source: components/ChatBubble.wrn

component ChatBubble {
+/>

Legacy mount name: data-component="ChatBubble".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
titlestringOptional""
descriptionstringOptional""
itemsstringOptional[]
oneSidedbooleanOptionalfalse
showAvatarsbooleanOptionalfalse
showMetadatabooleanOptionalfalse
ariaLabelstringOptional"Conversation"
variantstringOptional"default"
classstringOptional""

Slots

  • default

Events

  • action
  • messageClick
  • avatarClick
  • linkClick

Source contract

Installed source: components/ChatBubble.wrn

component ChatBubble {
   props {
+    @event action = function
+    @event messageClick = function
+    @event avatarClick = function
+    @event linkClick = function
     size = "default"
     color = "primary"
-    title = "Chat Bubble"
+    title = ""
     description = ""
     items = []
+    oneSided = false
+    showAvatars = false
+    showMetadata = false
+    ariaLabel = "Conversation"
     variant = "default"
     class = ""
   }
+
+  functions {
+    function messageDirection(item) {
+      return item.direction === "outgoing" ? "outgoing" : "incoming"
+    }
+
+    function selectMessage(item, index) {
+      $emit("messageClick", {
+        item: item,
+        index: index,
+        direction: messageDirection(item)
+      })
+    }
+
+    function selectAvatar(sourceEvent, item, index) {
+      sourceEvent.stopPropagation()
+      $emit("avatarClick", {
+        item: item,
+        index: index,
+        direction: messageDirection(item)
+      })
+    }
+
+    function selectLink(sourceEvent, link, item, index) {
+      sourceEvent.stopPropagation()
+      $emit("linkClick", {
+        link: link,
+        item: item,
+        index: index
+      })
+    }
+
+    function selectAction(sourceEvent, item, index) {
+      sourceEvent.stopPropagation()
+      $emit("action", {
+        action: item.action || "retry",
+        item: item,
+        index: index
+      })
+    }
+  }
+
   view {
-        <section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--chat-bubble wire-next--variant-{variant} {class}">
-      {#if title}<strong>{title}</strong>{/if}
-      {#if description}<p>{description}</p>{/if}
-      {#if items}<div class="wire-next__items">{#each items as item}<span>{item.label}</span>{/each}</div>{/if}
+        <section
+      {...attrs}
+      class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--chat-bubble wire-next--variant-{variant} {class}"
+      data-one-sided="{oneSided}"
+      role="log"
+      aria-label="{ariaLabel}"
+      aria-live="polite"
+    >
+      {#if title || description}
+        <header class="wire-next__chat-header">
+          {#if title}<h3>{title}</h3>{/if}
+          {#if description}<p>{description}</p>{/if}
+        </header>
+      {/if}
+
+      {#if items.length}
+        <div class="wire-next__chat-thread">
+          {#each items as item, index}
+            <article
+              class="wire-next__chat-message"
+              data-direction="{messageDirection(item)}"
+              aria-label="{messageDirection(item) === 'outgoing' ? 'Sent message' : 'Received message'}"
+            >
+        <div class="wire-next__chat-row">
+                {#if showAvatars && (item.avatarSrc || item.avatarFallback)}
+                  <button
+                    class="wire-next__chat-avatar"
+                    type="button"
+                    aria-label="{item.avatarLabel || item.author || 'Message author'}"
+                    @click="selectAvatar(event, item, index)"
+                  >
+                    {#if item.avatarSrc}
+                      <img src="{item.avatarSrc}" alt="{item.avatarAlt || ''}" />
+                    {:else}
+                      <span>{item.avatarFallback}</span>
+                    {/if}
+                  </button>
+                {/if}
+
+                <div
+                  class="wire-next__chat-content"
+                  role="button"
+                  tabindex="0"
+                  @click="selectMessage(item, index)"
+                  @keydown="if (event.key === 'Enter' || event.key === ' ') { event.preventDefault(); selectMessage(item, index) }"
+                >
+                  {#if item.title}<h4>{item.title}</h4>{/if}
+                  {#if item.text}<p>{item.text}</p>{/if}
+                  {#if item.bullets && item.bullets.length}
+                    <ul>
+                      {#each item.bullets as bullet}<li>{bullet}</li>{/each}
+                    </ul>
+                  {/if}
+                  {#if item.links && item.links.length}
+                    <nav aria-label="Message links">
+                      {#each item.links as link}
+                        <a
+                          href="{link.href || '#'}"
+                          @click="selectLink(event, link, item, index)"
+                        >{link.label}</a>
+                      {/each}
+                    </nav>
+                  {/if}
+                </div>
+        </div>
+
+              {#if showMetadata && (item.timestamp || item.status || item.actionLabel)}
+                <footer class="wire-next__chat-meta" data-tone="{item.statusTone || 'muted'}">
+                  {#if item.statusIcon}<span class="{item.statusIcon}" aria-hidden="true">
+        </span>{/if}
+                  {#if item.status}<span>{item.status}</span>{/if}
+                  {#if item.timestamp}<time datetime="{item.datetime || ''}">{item.timestamp}</time>{/if}
+                  {#if item.actionLabel}
+                    <button type="button" @click="selectAction(event, item, index)">
+                      {item.actionLabel}
+                    </button>
+                  {/if}
+                </footer>
+              {/if}
+            </article>
+          {/each}
+        </div>
+      {/if}
       <slot />
         </section>
     }
 }
 
- + } diff --git a/app/pages/components/checkbox.wrn b/app/pages/components/checkbox.wrn index 337bf39e..4b8d8a62 100644 --- a/app/pages/components/checkbox.wrn +++ b/app/pages/components/checkbox.wrn @@ -10,35 +10,81 @@ page Checkboxcomponent {
W WRNexusJS - +
-
forms component

Checkbox

Theme-aware, responsive checkbox component.

@wrnexus/ui 0.4.08 props0 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Checkbox
+      
forms component

Checkbox

Theme-aware, responsive checkbox component.

@wrnexus/ui 0.5.027 props0 slots5 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Checkbox
   size="default"
   color="primary"
-  label="Checkbox"
+  id="id"
   name="name"
-  value="on"
-/>

Legacy mount name: data-component="Checkbox".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
labelstringOptional"Checkbox"
namestringOptional""
valuestringOptional"on"
checkedbooleanOptionalfalse
disabledbooleanOptionalfalse
classstringOptional""

Slots

This component does not declare a slot.

Events

This component does not declare a custom event.

Source contract

Installed source: components/checkbox.wrn

component Checkbox {
+  label="Checkbox"
+/>

Legacy mount name: data-component="Checkbox".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
idstringOptional""
namestringOptional""
labelstringOptional"Checkbox"
hiddenLabelbooleanOptionalfalse
placeholderstringOptional""
variantstringOptional"normal"
iconstringOptional""
iconPositionstringOptional"start"
valuestringOptional"on"
valuesstringOptional[]
optionsstringOptional[]
checkedbooleanOptionalfalse
indeterminatebooleanOptionalfalse
orientationstringOptional"vertical"
cardbooleanOptionalfalse
rightAlignedbooleanOptionalfalse
listbooleanOptionalfalse
helperTextstringOptional""
cornerHintstringOptional""
errorstringOptional""
inlinebooleanOptionalfalse
readonlybooleanOptionalfalse
disabledbooleanOptionalfalse
requiredbooleanOptionalfalse
classstringOptional""

Slots

This component does not declare a slot.

Events

  • input
  • change
  • focus
  • blur
  • invalid

Source contract

Installed source: components/Checkbox.wrn

component Checkbox {
   props {
+    @event input = function
+    @event change = function
+    @event focus = function
+    @event blur = function
+    @event invalid = function
     size = "default"
     color = "primary"
-    label = "Checkbox"
+    id = ""
     name = ""
+    label = "Checkbox"
+    hiddenLabel = false
+    placeholder = ""
+    variant = "normal"
+    icon = ""
+    iconPosition = "start"
     value = "on"
+    values = []
+    options = []
     checked = false
+    indeterminate = false
+    orientation = "vertical"
+    card = false
+    rightAligned = false
+    list = false
+    helperText = ""
+    cornerHint = ""
+    error = ""
+    inline = false
+    readonly = false
     disabled = false
+    required = false
     class = ""
   }
+  functions {
+    function emitField(nameEvent, sourceEvent) { sourceEvent.stopPropagation(); $emit(nameEvent, { checked: sourceEvent.currentTarget.checked, value: sourceEvent.currentTarget.value, values: values, name: name, sourceEvent: sourceEvent }) }
+    function preventReadonly(sourceEvent) { if (readonly) sourceEvent.preventDefault() }
+  }
   view {
-        <label class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--choice wire-next--checkbox {class}">
-        <input {...attrs} type="checkbox" name="{name}" value="{value}" checked="{checked}" disabled="{disabled}" />
-        <span>{label}</span>
+        <div {...attrs} class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--choice-field wire-next--checkbox-field {class}" data-inline="{inline}" data-invalid="{error ? 'true' : 'false'}" data-orientation="{orientation}" data-card="{card}" data-list="{list}" data-right-aligned="{rightAligned}">
+        <div class="wire-next__field-heading">{#if options.length || cornerHint}<span class="{hiddenLabel ? 'wire-next__sr-only' : ''}">{label}</span>{#if cornerHint}<span class="wire-next__field-hint">{cornerHint}</span>{/if}{/if}</div>
+      {#if options.length}
+        <div class="wire-next__checkbox-group" role="group" aria-label="{hiddenLabel ? label : ''}" aria-invalid="{error ? 'true' : 'false'}">
+          {#each options as option}
+            <label class="wire-next__choice wire-next--checkbox" for="{id || name}-{option.value}" data-variant="{variant}" data-disabled="{disabled || option.disabled}">
+        <input id="{id || name}-{option.value}" type="checkbox" name="{name}" value="{option.value}" checked="{values.includes(option.value) || option.checked}" disabled="{disabled || option.disabled}" required="{required}" readonly="{readonly}" @click="preventReadonly(event)" @input="emitField('input', event)" @change="emitField('change', event)" @focus="emitField('focus', event)" @blur="emitField('blur', event)" @invalid="emitField('invalid', event)" />
+        <span class="wire-next__choice-copy">
+        <strong>{option.label}</strong>{#if option.description}<small>{option.description}</small>{/if}</span>
         </label>
+          {/each}
+        </div>
+      {:else}
+        <label class="wire-next__choice wire-next--checkbox" for="{id || name}" data-variant="{variant}" data-icon-position="{iconPosition}">
+        <input id="{id || name}" type="checkbox" name="{name}" value="{value}" checked="{checked}" disabled="{disabled}" required="{required}" readonly="{readonly}" aria-checked="{indeterminate ? 'mixed' : (checked ? 'true' : 'false')}" aria-invalid="{error ? 'true' : 'false'}" @click="preventReadonly(event)" @input="emitField('input', event)" @change="emitField('change', event)" @focus="emitField('focus', event)" @blur="emitField('blur', event)" @invalid="emitField('invalid', event)" />
+          {#if icon}<span class="{icon}" aria-hidden="true">
+        </span>{/if}
+          <span class="{hiddenLabel || cornerHint ? 'wire-next__sr-only' : ''}">{label}</span>
+        </label>
+      {/if}
+      {#if helperText}<small class="wire-next__field-help">{helperText}</small>{/if}<small class="wire-next__field-error" data-error="{name}">{error}</small>
+        </div>
     }
 }
 
- + } diff --git a/app/pages/components/clipboard.wrn b/app/pages/components/clipboard.wrn index bf343d72..3b3a07ae 100644 --- a/app/pages/components/clipboard.wrn +++ b/app/pages/components/clipboard.wrn @@ -10,17 +10,20 @@ page Clipboardcomponent {
W WRNexusJS - +
-
integrations component

Clipboard

Theme-aware, responsive clipboard component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Clipboard
+      
integrations component

Clipboard

Theme-aware, responsive clipboard component.

@wrnexus/ui 0.5.07 props1 slots3 events

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

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
titlestringOptional"Clipboard"
descriptionstringOptional""
itemsstringOptional[]
variantstringOptional"default"
classstringOptional""

Slots

  • default

Events

This component does not declare a custom event.

Source contract

Installed source: components/Clipboard.wrn

component Clipboard {
+/>

Legacy mount name: data-component="Clipboard".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
titlestringOptional"Clipboard"
descriptionstringOptional""
itemsstringOptional[]
variantstringOptional"default"
classstringOptional""

Slots

  • default

Events

  • copy
  • success
  • error

Source contract

Installed source: components/Clipboard.wrn

component Clipboard {
   props {
+    @event copy = function
+    @event success = function
+    @event error = function
     size = "default"
     color = "primary"
     title = "Clipboard"
@@ -39,7 +42,7 @@ page Clipboardcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/collapse.wrn b/app/pages/components/collapse.wrn index 2981db33..691eab3f 100644 --- a/app/pages/components/collapse.wrn +++ b/app/pages/components/collapse.wrn @@ -10,34 +10,112 @@ page Collapsecomponent {
W WRNexusJS - +
-
base component

Collapse

Theme-aware, responsive collapse component.

@wrnexus/ui 0.4.05 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Collapse
+      
base component

Collapse

Theme-aware, responsive collapse component.

@wrnexus/ui 0.5.08 props1 slots3 events

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

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
itemsstringOptional[]
multiplebooleanOptionalfalse
classstringOptional""

Slots

  • default

Events

This component does not declare a custom event.

Source contract

Installed source: components/Collapse.wrn

component Collapse {
+  mode="panel"
+/>

Legacy mount name: data-component="Collapse".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
itemsstringOptional[]
multiplebooleanOptionalfalse
modestringOptional"panel"
initialOpenIndexesstringOptional[]
ariaLabelstringOptional"Collapsible content"
classstringOptional""

Slots

  • default

Events

  • toggle
  • open
  • close

Source contract

Installed source: components/Collapse.wrn

component Collapse {
   props {
+    @event toggle = function
+    @event open = function
+    @event close = function
     size = "default"
     color = "primary"
     items = []
     multiple = false
+    mode = "panel"
+    initialOpenIndexes = []
+    ariaLabel = "Collapsible content"
     class = ""
   }
+
+  state openIndexes = initialOpenIndexes
+
+  functions {
+    function isOpen(index) {
+      return openIndexes.includes(index)
+    }
+
+    function toggleItem(index, item, opening) {
+      if (item.disabled) {
+        return
+      }
+      opening = !isOpen(index)
+      if (opening) {
+        if (multiple) {
+          openIndexes = openIndexes.concat(index)
+        } else {
+          openIndexes = [index]
+        }
+        $emit("open", { index: index, item: item })
+      } else {
+        openIndexes = openIndexes.filter((openIndex) => openIndex !== index)
+        $emit("close", { index: index, item: item })
+      }
+      $emit("toggle", {
+        index: index,
+        item: item,
+        open: opening,
+        openIndexes: openIndexes
+      })
+    }
+  }
+
   view {
-        <div class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--collapse {class}">
-      {#each items as item}<details open="{item.open}">
-        <summary>{item.label}</summary>
-        <div>{item.content}</div>
-        </details>{/each}
-      <slot />
+        <section
+      {...attrs}
+      class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--collapse {class}"
+      data-mode="{mode}"
+      aria-label="{ariaLabel}"
+    >
+      {#each items as item, index}
+        <article class="wire-next__collapse-item" data-open="{isOpen(index)}">
+          {#if mode === "inline" && item.preview}
+            <p class="wire-next__collapse-preview">{item.preview}</p>
+          {/if}
+
+          <button
+            class="wire-next__collapse-trigger"
+            type="button"
+            aria-expanded="{isOpen(index) ? 'true' : 'false'}"
+            aria-controls="{item.id || 'collapse-panel-' + index}"
+            disabled="{item.disabled}"
+            @click="toggleItem(index, item)"
+          >
+        <span>{isOpen(index) ? (item.closeLabel || "Read less") : item.label}</span>
+        <span class="icon-[lucide--chevron-down] wire-next__collapse-chevron" aria-hidden="true">
+        </span>
+        </button>
+        <div
+            id="{item.id || 'collapse-panel-' + index}"
+            class="wire-next__collapse-panel"
+            data-open="{isOpen(index)}"
+            aria-hidden="{isOpen(index) ? 'false' : 'true'}"
+            inert="{!isOpen(index)}"
+          >
+        <div class="wire-next__collapse-content">
+              {#if item.title}<h4>{item.title}</h4>{/if}
+              {#if item.content}<p>{item.content}</p>{/if}
+              {#if item.links && item.links.length}
+                <nav aria-label="Related links">
+                  {#each item.links as link}<a href="{link.href || '#'}">{link.label}</a>{/each}
+                </nav>
+              {/if}
+            </div>
         </div>
+        </article>
+      {/each}
+      <slot />
+        </section>
     }
 }
 
- + } diff --git a/app/pages/components/color-picker.wrn b/app/pages/components/color-picker.wrn index cfcf5981..99de1282 100644 --- a/app/pages/components/color-picker.wrn +++ b/app/pages/components/color-picker.wrn @@ -10,40 +10,59 @@ page ColorPickercomponent {
W WRNexusJS - +
-
forms component

ColorPicker

Theme-aware, responsive color picker component.

@wrnexus/ui 0.4.013 props0 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<ColorPicker
+      
forms component

ColorPicker

Theme-aware, responsive color picker component.

@wrnexus/ui 0.5.019 props0 slots4 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<ColorPicker
   size="default"
   color="primary"
-  label="Color Picker"
+  id="id"
   name="name"
-  value="value"
-/>

Legacy mount name: data-component="ColorPicker".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
labelstringOptional"Color Picker"
namestringOptional""
valuestringOptional""
placeholderstringOptional""
typestringOptional"color"
minstringOptional""
maxstringOptional""
stepstringOptional""
disabledbooleanOptionalfalse
requiredbooleanOptionalfalse
classstringOptional""

Slots

This component does not declare a slot.

Events

This component does not declare a custom event.

Source contract

Installed source: components/ColorPicker.wrn

component ColorPicker {
+  label="Color"
+/>

Legacy mount name: data-component="ColorPicker".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
idstringOptional""
namestringOptional""
labelstringOptional"Color"
hiddenLabelbooleanOptionalfalse
placeholderstringOptional""
valuestringOptional"#2563eb"
iconstringOptional""
iconPositionstringOptional"start"
helperTextstringOptional""
cornerHintstringOptional""
errorstringOptional""
inlinebooleanOptionalfalse
variantstringOptional"normal"
readonlybooleanOptionalfalse
disabledbooleanOptionalfalse
requiredbooleanOptionalfalse
classstringOptional""

Slots

This component does not declare a slot.

Events

  • input
  • change
  • focus
  • blur

Source contract

Installed source: components/ColorPicker.wrn

component ColorPicker {
   props {
+    @event input = function
+    @event change = function
+    @event focus = function
+    @event blur = function
     size = "default"
     color = "primary"
-    label = "Color Picker"
+    id = ""
     name = ""
-    value = ""
+    label = "Color"
+    hiddenLabel = false
     placeholder = ""
-    type = "color"
-    min = ""
-    max = ""
-    step = ""
+    value = "#2563eb"
+    icon = ""
+    iconPosition = "start"
+    helperText = ""
+    cornerHint = ""
+    error = ""
+    inline = false
+    variant = "normal"
+    readonly = false
     disabled = false
     required = false
     class = ""
   }
+  functions {
+    function emitField(nameEvent, sourceEvent) { sourceEvent.stopPropagation(); $emit(nameEvent, { value: sourceEvent.currentTarget.value, name: name, sourceEvent: sourceEvent }) }
+    function preventReadonly(sourceEvent) { if (readonly) sourceEvent.preventDefault() }
+  }
   view {
-        <label class="wire-next wire-next--field wire-next--color-picker {class}">
-        <span>{label}</span>
-        <input {...attrs} type="{type}" name="{name}" value="{value}" placeholder="{placeholder}" min="{min}" max="{max}" step="{step}" disabled="{disabled}" required="{required}" />
-        </label>
+        <div {...attrs} class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--field wire-next--color-picker {class}" data-variant="{variant}" data-inline="{inline}" data-invalid="{error ? 'true' : 'false'}">
+        <div class="wire-next__field-heading">
+        <label class="{hiddenLabel ? 'wire-next__sr-only' : ''}" for="{id || name}">{label}</label>{#if cornerHint}<span class="wire-next__field-hint">{cornerHint}</span>{/if}</div>
+        <div class="wire-next__color-control" data-icon-position="{iconPosition}">{#if icon}<span class="{icon}" aria-hidden="true">
+        </span>{/if}<input id="{id || name}" type="color" name="{name}" value="{value}" disabled="{disabled}" required="{required}" readonly="{readonly}" aria-invalid="{error ? 'true' : 'false'}" @click="preventReadonly(event)" @input="emitField('input', event)" @change="emitField('change', event)" @focus="emitField('focus', event)" @blur="emitField('blur', event)" />
+        <output>{value}</output>
+        </div>
+      {#if helperText}<small class="wire-next__field-help">{helperText}</small>{/if}<small class="wire-next__field-error" data-error="{name}">{error}</small>
+        </div>
     }
 }
 
- + } diff --git a/app/pages/components/columns.wrn b/app/pages/components/columns.wrn index 93a8959e..8d020266 100644 --- a/app/pages/components/columns.wrn +++ b/app/pages/components/columns.wrn @@ -10,10 +10,10 @@ page Columnscomponent {
W WRNexusJS - +
-
layout component

Columns

Theme-aware, responsive columns component.

@wrnexus/ui 0.4.06 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Columns
+      
layout component

Columns

Theme-aware, responsive columns component.

@wrnexus/ui 0.5.06 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Columns
   size="default"
   color="primary"
   columns="2"
@@ -35,7 +35,7 @@ page Columnscomponent {
     }
 }
 
- + } diff --git a/app/pages/components/combo-box.wrn b/app/pages/components/combo-box.wrn index 7e3f9467..a1ac467f 100644 --- a/app/pages/components/combo-box.wrn +++ b/app/pages/components/combo-box.wrn @@ -10,10 +10,10 @@ page ComboBoxcomponent {
W WRNexusJS - +
-
advanced-forms component

ComboBox

Editable autocomplete combobox with local and remote suggestions.

@wrnexus/ui 0.4.041 props0 slots8 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<ComboBox
+      
advanced-forms component

ComboBox

Editable autocomplete combobox with local and remote suggestions.

@wrnexus/ui 0.5.041 props0 slots8 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<ComboBox
   size="default"
   color="primary"
   label="ComboBox"
@@ -413,7 +413,7 @@ page ComboBoxcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/confetti.wrn b/app/pages/components/confetti.wrn index d863171e..44776a36 100644 --- a/app/pages/components/confetti.wrn +++ b/app/pages/components/confetti.wrn @@ -10,17 +10,19 @@ page Confetticomponent {
W WRNexusJS - +
-
integrations component

Confetti

Theme-aware, responsive confetti component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Confetti
+      
integrations component

Confetti

Theme-aware, responsive confetti component.

@wrnexus/ui 0.5.07 props1 slots2 events

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

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
titlestringOptional"Confetti"
descriptionstringOptional""
itemsstringOptional[]
variantstringOptional"default"
classstringOptional""

Slots

  • default

Events

This component does not declare a custom event.

Source contract

Installed source: components/Confetti.wrn

component Confetti {
+/>

Legacy mount name: data-component="Confetti".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
titlestringOptional"Confetti"
descriptionstringOptional""
itemsstringOptional[]
variantstringOptional"default"
classstringOptional""

Slots

  • default

Events

  • start
  • complete

Source contract

Installed source: components/Confetti.wrn

component Confetti {
   props {
+    @event start = function
+    @event complete = function
     size = "default"
     color = "primary"
     title = "Confetti"
@@ -39,7 +41,7 @@ page Confetticomponent {
     }
 }
 
- + } diff --git a/app/pages/components/container.wrn b/app/pages/components/container.wrn index b43d6910..4db9b403 100644 --- a/app/pages/components/container.wrn +++ b/app/pages/components/container.wrn @@ -10,10 +10,10 @@ page Containercomponent {
W WRNexusJS - +
-
layout component

Container

Theme-aware, responsive container component.

@wrnexus/ui 0.4.06 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Container
+      
layout component

Container

Theme-aware, responsive container component.

@wrnexus/ui 0.5.06 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Container
   size="default"
   color="primary"
   columns="2"
@@ -35,7 +35,7 @@ page Containercomponent {
     }
 }
 
- + } diff --git a/app/pages/components/context-menu.wrn b/app/pages/components/context-menu.wrn index f7a8877a..826c90e7 100644 --- a/app/pages/components/context-menu.wrn +++ b/app/pages/components/context-menu.wrn @@ -10,17 +10,20 @@ page ContextMenucomponent {
W WRNexusJS - +
-
overlays component

ContextMenu

Theme-aware, responsive context menu component.

@wrnexus/ui 0.4.08 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<ContextMenu
+      
overlays component

ContextMenu

Theme-aware, responsive context menu component.

@wrnexus/ui 0.5.08 props1 slots3 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<ContextMenu
   size="default"
   color="primary"
   title="Context Menu"
   description="description"
   open="false"
-/>

Legacy mount name: data-component="ContextMenu".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
titlestringOptional"Context Menu"
descriptionstringOptional""
openbooleanOptionalfalse
placementstringOptional"bottom"
closeLabelstringOptional"Close"
classstringOptional""

Slots

  • default

Events

This component does not declare a custom event.

Source contract

Installed source: components/ContextMenu.wrn

component ContextMenu {
+/>

Legacy mount name: data-component="ContextMenu".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
titlestringOptional"Context Menu"
descriptionstringOptional""
openbooleanOptionalfalse
placementstringOptional"bottom"
closeLabelstringOptional"Close"
classstringOptional""

Slots

  • default

Events

  • open
  • close
  • select

Source contract

Installed source: components/ContextMenu.wrn

component ContextMenu {
   props {
+    @event open = function
+    @event close = function
+    @event select = function
     size = "default"
     color = "primary"
     title = "Context Menu"
@@ -42,7 +45,7 @@ page ContextMenucomponent {
     }
 }
 
- + } diff --git a/app/pages/components/copy-markup.wrn b/app/pages/components/copy-markup.wrn index bebe8cc1..7b16795e 100644 --- a/app/pages/components/copy-markup.wrn +++ b/app/pages/components/copy-markup.wrn @@ -10,17 +10,20 @@ page CopyMarkupcomponent {
W WRNexusJS - +
-
advanced-forms component

CopyMarkup

Theme-aware, responsive copy markup component.

@wrnexus/ui 0.4.013 props0 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<CopyMarkup
+      
advanced-forms component

CopyMarkup

Theme-aware, responsive copy markup component.

@wrnexus/ui 0.5.013 props0 slots3 events

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

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
labelstringOptional"Copy Markup"
namestringOptional""
valuestringOptional""
placeholderstringOptional""
typestringOptional"text"
minstringOptional""
maxstringOptional""
stepstringOptional""
disabledbooleanOptionalfalse
requiredbooleanOptionalfalse
classstringOptional""

Slots

This component does not declare a slot.

Events

This component does not declare a custom event.

Source contract

Installed source: components/CopyMarkup.wrn

component CopyMarkup {
+/>

Legacy mount name: data-component="CopyMarkup".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
labelstringOptional"Copy Markup"
namestringOptional""
valuestringOptional""
placeholderstringOptional""
typestringOptional"text"
minstringOptional""
maxstringOptional""
stepstringOptional""
disabledbooleanOptionalfalse
requiredbooleanOptionalfalse
classstringOptional""

Slots

This component does not declare a slot.

Events

  • copy
  • success
  • error

Source contract

Installed source: components/CopyMarkup.wrn

component CopyMarkup {
   props {
+    @event copy = function
+    @event success = function
+    @event error = function
     size = "default"
     color = "primary"
     label = "Copy Markup"
@@ -43,7 +46,7 @@ page CopyMarkupcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/custom-scrollbar.wrn b/app/pages/components/custom-scrollbar.wrn index e39ad967..2819d613 100644 --- a/app/pages/components/custom-scrollbar.wrn +++ b/app/pages/components/custom-scrollbar.wrn @@ -10,17 +10,18 @@ page CustomScrollbarcomponent {
W WRNexusJS - +
-
layout component

CustomScrollbar

Theme-aware, responsive custom scrollbar component.

@wrnexus/ui 0.4.06 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<CustomScrollbar
+      
layout component

CustomScrollbar

Theme-aware, responsive custom scrollbar component.

@wrnexus/ui 0.5.06 props1 slots1 events

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

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
columnsnumberOptional2
gapstringOptional"md"
maxWidthstringOptional"xl"
classstringOptional""

Slots

  • default

Events

This component does not declare a custom event.

Source contract

Installed source: components/CustomScrollbar.wrn

component CustomScrollbar {
+/>

Legacy mount name: data-component="CustomScrollbar".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
columnsnumberOptional2
gapstringOptional"md"
maxWidthstringOptional"xl"
classstringOptional""

Slots

  • default

Events

  • scroll

Source contract

Installed source: components/CustomScrollbar.wrn

component CustomScrollbar {
   props {
+    @event scroll = function
     size = "default"
     color = "primary"
     columns = 2
@@ -35,7 +36,7 @@ page CustomScrollbarcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/data-map.wrn b/app/pages/components/data-map.wrn index e0cbb612..7031f501 100644 --- a/app/pages/components/data-map.wrn +++ b/app/pages/components/data-map.wrn @@ -10,17 +10,19 @@ page DataMapcomponent {
W WRNexusJS - +
-
integrations component

DataMap

Theme-aware, responsive data map component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<DataMap
+      
integrations component

DataMap

Theme-aware, responsive data map component.

@wrnexus/ui 0.5.07 props1 slots2 events

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

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
titlestringOptional"Data Map"
descriptionstringOptional""
itemsstringOptional[]
variantstringOptional"default"
classstringOptional""

Slots

  • default

Events

This component does not declare a custom event.

Source contract

Installed source: components/DataMap.wrn

component DataMap {
+/>

Legacy mount name: data-component="DataMap".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
titlestringOptional"Data Map"
descriptionstringOptional""
itemsstringOptional[]
variantstringOptional"default"
classstringOptional""

Slots

  • default

Events

  • select
  • change

Source contract

Installed source: components/DataMap.wrn

component DataMap {
   props {
+    @event select = function
+    @event change = function
     size = "default"
     color = "primary"
     title = "Data Map"
@@ -39,7 +41,7 @@ page DataMapcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/data-table.wrn b/app/pages/components/data-table.wrn index e1f8c32c..d28b729d 100644 --- a/app/pages/components/data-table.wrn +++ b/app/pages/components/data-table.wrn @@ -10,17 +10,22 @@ page DataTablecomponent {
W WRNexusJS - +
-
integrations component

DataTable

Theme-aware, responsive data table component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<DataTable
+      
integrations component

DataTable

Theme-aware, responsive data table component.

@wrnexus/ui 0.5.07 props1 slots5 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<DataTable
   size="default"
   color="primary"
   caption="Data Table"
   columns="[]"
   rows="[]"
-/>

Legacy mount name: data-component="DataTable".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
captionstringOptional"Data Table"
columnsstringOptional[]
rowsstringOptional[]
stripedbooleanOptionaltrue
classstringOptional""

Slots

  • default

Events

This component does not declare a custom event.

Source contract

Installed source: components/DataTable.wrn

component DataTable {
+/>

Legacy mount name: data-component="DataTable".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
captionstringOptional"Data Table"
columnsstringOptional[]
rowsstringOptional[]
stripedbooleanOptionaltrue
classstringOptional""

Slots

  • default

Events

  • sort
  • select
  • change
  • rowClick
  • pageChange

Source contract

Installed source: components/DataTable.wrn

component DataTable {
   props {
+    @event sort = function
+    @event select = function
+    @event change = function
+    @event rowClick = function
+    @event pageChange = function
     size = "default"
     color = "primary"
     caption = "Data Table"
@@ -43,7 +48,7 @@ page DataTablecomponent {
     }
 }
 
- + } diff --git a/app/pages/components/date-picker.wrn b/app/pages/components/date-picker.wrn index 0c877b10..efa11523 100644 --- a/app/pages/components/date-picker.wrn +++ b/app/pages/components/date-picker.wrn @@ -10,40 +10,92 @@ page DatePickercomponent {
W WRNexusJS - +
-
base component

DatePicker

Theme-aware, responsive date picker component.

@wrnexus/ui 0.4.013 props0 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<DatePicker
+      
base component

DatePicker

Theme-aware, responsive date picker component.

@wrnexus/ui 0.5.025 props0 slots7 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<DatePicker
   size="default"
   color="primary"
   label="Date Picker"
+  id="id"
   name="name"
-  value="value"
-/>

Legacy mount name: data-component="DatePicker".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
labelstringOptional"Date Picker"
namestringOptional""
valuestringOptional""
placeholderstringOptional""
typestringOptional"date"
minstringOptional""
maxstringOptional""
stepstringOptional""
disabledbooleanOptionalfalse
requiredbooleanOptionalfalse
classstringOptional""

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

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
labelstringOptional"Date Picker"
idstringOptional""
namestringOptional""
valuestringOptional""
placeholderstringOptional""
typestringOptional"date"
localestringOptional"en-US"
firstDayOfWeeknumberOptional0
monthsstringOptional[{ label: "Jan", value: "01" }, { label: "Feb", value: "02" }, { label: "Mar", value: "03" }, { label: "Apr", value: "04" }, { label: "May", value: "05" }, { label: "Jun", value: "06" }, { label: "Jul", value: "07" }, { label: "Aug", value: "08" }, { label: "Sep", value: "09" }, { label: "Oct", value: "10" }, { label: "Nov", value: "11" }, { label: "Dec", value: "12" }]
daysstringOptional[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]
yearsstringOptional[2024, 2025, 2026, 2027, 2028, 2029, 2030]
minstringOptional""
maxstringOptional""
stepstringOptional""
helperTextstringOptional""
cornerHintstringOptional""
errorstringOptional""
variantstringOptional"normal"
inlinebooleanOptionalfalse
readonlybooleanOptionalfalse
disabledbooleanOptionalfalse
requiredbooleanOptionalfalse
classstringOptional""

Slots

This component does not declare a slot.

Events

  • input
  • change
  • open
  • close
  • focus
  • blur
  • invalid

Source contract

Installed source: components/DatePicker.wrn

component DatePicker {
   props {
+    @event input = function
+    @event change = function
+    @event open = function
+    @event close = function
+    @event focus = function
+    @event blur = function
+    @event invalid = function
     size = "default"
     color = "primary"
     label = "Date Picker"
+    id = ""
     name = ""
     value = ""
     placeholder = ""
     type = "date"
+    locale = "en-US"
+    firstDayOfWeek = 0
+    months = [{ label: "Jan", value: "01" }, { label: "Feb", value: "02" }, { label: "Mar", value: "03" }, { label: "Apr", value: "04" }, { label: "May", value: "05" }, { label: "Jun", value: "06" }, { label: "Jul", value: "07" }, { label: "Aug", value: "08" }, { label: "Sep", value: "09" }, { label: "Oct", value: "10" }, { label: "Nov", value: "11" }, { label: "Dec", value: "12" }]
+    days = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]
+    years = [2024, 2025, 2026, 2027, 2028, 2029, 2030]
     min = ""
     max = ""
     step = ""
+    helperText = ""
+    cornerHint = ""
+    error = ""
+    variant = "normal"
+    inline = false
+    readonly = false
     disabled = false
     required = false
     class = ""
   }
+  state currentValue = value
+  state selectedYear = value ? value.split("-")[0] : ""
+  state selectedMonth = value ? value.split("-")[1] : ""
+  state selectedDay = value ? value.split("-")[2] : ""
+  state expanded = false
+  functions {
+    function openCalendar(sourceEvent) { expanded = true; $emit("open", { value: currentValue, name: name, sourceEvent: sourceEvent }) }
+    function updateDate(part, nextValue, sourceEvent, nextDate, detail) { if (part === "year") { selectedYear = String(nextValue) } if (part === "month") { selectedMonth = String(nextValue).padStart(2, "0") } if (part === "day") { selectedDay = String(nextValue).padStart(2, "0") } if (!selectedYear || !selectedMonth || !selectedDay) { return } nextDate = selectedYear + "-" + selectedMonth + "-" + selectedDay; if ((min && nextDate < min) || (max && nextDate > max)) { return } currentValue = nextDate; detail = { value: currentValue, year: selectedYear, month: selectedMonth, day: selectedDay, name: name, sourceEvent: sourceEvent }; $emit("input", detail); $emit("change", detail) }
+    function finishDate(sourceEvent) { if (!currentValue) { return } expanded = false; $emit("close", { value: currentValue, name: name, sourceEvent: sourceEvent }) }
+    function selectDay(sourceEvent, root, input, nextDate, trigger, detail) { root = sourceEvent.currentTarget.closest(".wire-next--date-picker"); input = root.querySelector(".wire-next__picker-value"); nextDate = input.getAttribute("value").slice(0, 5) + root.querySelector("select").getAttribute("value") + "-" + sourceEvent.currentTarget.dataset.value; currentValue = nextDate; input.setAttribute("value", nextDate); trigger = root.querySelector(".wire-next__date-trigger span"); if (trigger) { trigger.replaceChildren(nextDate) } sourceEvent.currentTarget.setAttribute("aria-pressed", "true"); detail = { value: nextDate, name: name, sourceEvent: sourceEvent }; $emit("input", detail); $emit("change", detail) }
+    function clearDate(sourceEvent, detail) { if (disabled || readonly) { return } currentValue = ""; detail = { value: currentValue, name: name, sourceEvent: sourceEvent }; $emit("input", detail); $emit("change", detail) }
+    function handleFocus(sourceEvent) { $emit("focus", { value: currentValue, name: name, sourceEvent: sourceEvent }) }
+    function handleBlur(sourceEvent) { $emit("blur", { value: currentValue, name: name, sourceEvent: sourceEvent }) }
+    function handleInvalid(sourceEvent) { $emit("invalid", { name: name, message: sourceEvent.currentTarget.validationMessage, sourceEvent: sourceEvent }) }
+  }
   view {
-        <label class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--field wire-next--date-picker {class}">
-        <span>{label}</span>
-        <input {...attrs} type="{type}" name="{name}" value="{value}" placeholder="{placeholder}" min="{min}" max="{max}" step="{step}" disabled="{disabled}" required="{required}" />
+        <div {...attrs} class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--field wire-next--date-picker {class}" data-variant="{variant}" data-inline="{inline}" data-invalid="{error ? 'true' : 'false'}" data-expanded="{expanded}">
+        <div class="wire-next__field-heading">
+        <label for="{id || name}">{label}</label>{#if cornerHint}<span class="wire-next__field-hint">{cornerHint}</span>{/if}</div>
+        <div class="wire-next__picker-control">
+        <input id="{id || name}" class="wire-next__sr-only wire-next__picker-value" type="text" name="{name}" value="{currentValue}" required="{required}" readonly aria-hidden="true" tabindex="-1" @invalid="handleInvalid(event)" />
+        <button type="button" class="wire-next__date-trigger" disabled="{disabled || readonly}" aria-haspopup="dialog" aria-expanded="{expanded}" @click="openCalendar(event)" @focus="handleFocus(event)" @blur="handleBlur(event)">
+        <span>{currentValue || placeholder || "Select date"}</span>
+        <i class="icon-[lucide--calendar-days]" aria-hidden="true">
+        </i>
+        </button>{#if currentValue && !readonly && !disabled}<button type="button" class="wire-next__picker-clear" aria-label="Clear date" @click="clearDate(event)">×</button>{/if}</div>
+        <div class="wire-next__calendar" role="dialog" aria-label="{label}">
+        <div class="wire-next__date-selectors">
+        <label>Month<select value="{selectedMonth}" @change="updateDate('month', event.currentTarget.value, event)">{#each months as month}<option value="{month.value}" selected="{month.value === selectedMonth}">{month.label}</option>{/each}</select>
         </label>
+        <label>Year<select value="{selectedYear}" @change="updateDate('year', event.currentTarget.value, event)">{#each years as year}<option value="{year}" selected="{String(year) === selectedYear}">{year}</option>{/each}</select>
+        </label>
+        </div>
+        <div class="wire-next__calendar-grid">{#each days as day}<button type="button" data-value="{String(day).padStart(2, '0')}" aria-pressed="{String(day).padStart(2, '0') === selectedDay}" @click="selectDay(event)">{day}</button>{/each}</div>
+        <button type="button" class="wire-next__date-done" disabled="{!currentValue}" @click="finishDate(event)">Done</button>
+        </div>
+      {#if helperText}<small class="wire-next__field-help">{helperText}</small>{/if}<small class="wire-next__field-error" data-error="{name}">{error}</small>
+        </div>
     }
 }
 
- + } diff --git a/app/pages/components/device-frame.wrn b/app/pages/components/device-frame.wrn index ed07b0c9..d2394cf3 100644 --- a/app/pages/components/device-frame.wrn +++ b/app/pages/components/device-frame.wrn @@ -10,36 +10,53 @@ page DeviceFramecomponent {
W WRNexusJS - +
-
base component

DeviceFrame

Theme-aware, responsive device frame component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<DeviceFrame
+      
base component

DeviceFrame

Theme-aware, responsive device frame component.

@wrnexus/ui 0.5.014 props1 slots2 events

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

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
titlestringOptional"Device Frame"
descriptionstringOptional""
itemsstringOptional[]
variantstringOptional"default"
classstringOptional""

Slots

  • default

Events

This component does not declare a custom event.

Source contract

Installed source: components/DeviceFrame.wrn

component DeviceFrame {
+/>

Legacy mount name: data-component="DeviceFrame".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
titlestringOptional"Device Frame"
descriptionstringOptional""
itemsstringOptional[]
variantstringOptional"default"
devicestringOptional"phone"
orientationstringOptional"portrait"
srcstringOptional""
srcdocstringOptional""
frameTitlestringOptional"Device preview"
showToolbarbooleanOptionaltrue
allowstringOptional""
classstringOptional""

Slots

  • default

Events

  • change
  • rotate

Source contract

Installed source: components/DeviceFrame.wrn

component DeviceFrame {
   props {
+    @event change = function
+    @event rotate = function
     size = "default"
     color = "primary"
     title = "Device Frame"
     description = ""
     items = []
     variant = "default"
+    device = "phone"
+    orientation = "portrait"
+    src = ""
+    srcdoc = ""
+    frameTitle = "Device preview"
+    showToolbar = true
+    allow = ""
     class = ""
   }
+  state currentOrientation = orientation
+  functions {
+    function setDevice(nextDevice, sourceEvent) { $emit("change", { device: nextDevice, orientation: currentOrientation, sourceEvent: sourceEvent }) }
+    function rotateFrame(sourceEvent) { currentOrientation = currentOrientation === "portrait" ? "landscape" : "portrait"; $emit("rotate", { device: device, orientation: currentOrientation, sourceEvent: sourceEvent }); $emit("change", { device: device, orientation: currentOrientation, sourceEvent: sourceEvent }) }
+  }
   view {
-        <section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--device-frame wire-next--variant-{variant} {class}">
-      {#if title}<strong>{title}</strong>{/if}
-      {#if description}<p>{description}</p>{/if}
-      {#if items}<div class="wire-next__items">{#each items as item}<span>{item.label}</span>{/each}</div>{/if}
-      <slot />
+        <section {...attrs} class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--device-frame wire-next--variant-{variant} {class}" data-device="{device}" data-orientation="{currentOrientation}">
+        <header>
+        <div>{#if title}<strong>{title}</strong>{/if}{#if description}<p>{description}</p>{/if}</div>{#if showToolbar}<div class="wire-next__device-actions" role="toolbar" aria-label="Preview device">{#each items as item}<button type="button" aria-pressed="{item.value === device}" @click="setDevice(item.value, event)">{item.label}</button>{/each}<button type="button" aria-label="Rotate preview" @click="rotateFrame(event)">↻</button>
+        </div>{/if}</header>
+        <div class="wire-next__device-shell">{#if src || srcdoc}<iframe title="{frameTitle}" src="{src}" srcdoc="{srcdoc}" allow="{allow}">
+        </iframe>{:else}<div class="wire-next__device-content">
+        <slot />
+        </div>{/if}</div>
         </section>
     }
 }
 
- + } diff --git a/app/pages/components/divider.wrn b/app/pages/components/divider.wrn index 2445d3a6..42df8d27 100644 --- a/app/pages/components/divider.wrn +++ b/app/pages/components/divider.wrn @@ -10,10 +10,10 @@ page Dividercomponent {
W WRNexusJS - +
-
layout component

Divider

Theme-aware, responsive divider component.

@wrnexus/ui 0.4.05 props0 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Divider
+      
layout component

Divider

Theme-aware, responsive divider component.

@wrnexus/ui 0.5.05 props0 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Divider
   size="default"
   color="primary"
   label="label"
@@ -31,7 +31,7 @@ page Dividercomponent {
     }
 }
 
- + } diff --git a/app/pages/components/drag-and-drop.wrn b/app/pages/components/drag-and-drop.wrn index 1e8c8af7..d0960f0d 100644 --- a/app/pages/components/drag-and-drop.wrn +++ b/app/pages/components/drag-and-drop.wrn @@ -10,17 +10,23 @@ page DragAndDropcomponent {
W WRNexusJS - +
-
integrations component

DragAndDrop

Theme-aware, responsive drag and drop component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<DragAndDrop
+      
integrations component

DragAndDrop

Theme-aware, responsive drag and drop component.

@wrnexus/ui 0.5.07 props1 slots6 events

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

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
titlestringOptional"Drag And Drop"
descriptionstringOptional""
itemsstringOptional[]
variantstringOptional"default"
classstringOptional""

Slots

  • default

Events

This component does not declare a custom event.

Source contract

Installed source: components/DragAndDrop.wrn

component DragAndDrop {
+/>

Legacy mount name: data-component="DragAndDrop".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
titlestringOptional"Drag And Drop"
descriptionstringOptional""
itemsstringOptional[]
variantstringOptional"default"
classstringOptional""

Slots

  • default

Events

  • dragStart
  • dragEnd
  • dragEnter
  • dragLeave
  • drop
  • change

Source contract

Installed source: components/DragAndDrop.wrn

component DragAndDrop {
   props {
+    @event dragStart = function
+    @event dragEnd = function
+    @event dragEnter = function
+    @event dragLeave = function
+    @event drop = function
+    @event change = function
     size = "default"
     color = "primary"
     title = "Drag And Drop"
@@ -39,7 +45,7 @@ page DragAndDropcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/drawer.wrn b/app/pages/components/drawer.wrn index 52187f5a..39d227cb 100644 --- a/app/pages/components/drawer.wrn +++ b/app/pages/components/drawer.wrn @@ -10,17 +10,19 @@ page Drawercomponent {
W WRNexusJS - +
-
overlays component

Drawer

Theme-aware, responsive drawer component.

@wrnexus/ui 0.4.08 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Drawer
+      
overlays component

Drawer

Theme-aware, responsive drawer component.

@wrnexus/ui 0.5.08 props1 slots2 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Drawer
   size="default"
   color="primary"
   title="Drawer"
   description="description"
   open="false"
-/>

Legacy mount name: data-component="Drawer".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
titlestringOptional"Drawer"
descriptionstringOptional""
openbooleanOptionalfalse
placementstringOptional"bottom"
closeLabelstringOptional"Close"
classstringOptional""

Slots

  • default

Events

This component does not declare a custom event.

Source contract

Installed source: components/Drawer.wrn

component Drawer {
+/>

Legacy mount name: data-component="Drawer".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
titlestringOptional"Drawer"
descriptionstringOptional""
openbooleanOptionalfalse
placementstringOptional"bottom"
closeLabelstringOptional"Close"
classstringOptional""

Slots

  • default

Events

  • open
  • close

Source contract

Installed source: components/Drawer.wrn

component Drawer {
   props {
+    @event open = function
+    @event close = function
     size = "default"
     color = "primary"
     title = "Drawer"
@@ -42,7 +44,7 @@ page Drawercomponent {
     }
 }
 
- + } diff --git a/app/pages/components/dropdown.wrn b/app/pages/components/dropdown.wrn index 168cfb1b..6daed11a 100644 --- a/app/pages/components/dropdown.wrn +++ b/app/pages/components/dropdown.wrn @@ -10,17 +10,21 @@ page Dropdowncomponent {
W WRNexusJS - +
-
overlays component

Dropdown

Theme-aware, responsive dropdown component.

@wrnexus/ui 0.4.08 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Dropdown
+      
overlays component

Dropdown

Theme-aware, responsive dropdown component.

@wrnexus/ui 0.5.08 props1 slots4 events

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

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
titlestringOptional"Dropdown"
descriptionstringOptional""
openbooleanOptionalfalse
placementstringOptional"bottom"
closeLabelstringOptional"Close"
classstringOptional""

Slots

  • default

Events

This component does not declare a custom event.

Source contract

Installed source: components/Dropdown.wrn

component Dropdown {
+/>

Legacy mount name: data-component="Dropdown".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
titlestringOptional"Dropdown"
descriptionstringOptional""
openbooleanOptionalfalse
placementstringOptional"bottom"
closeLabelstringOptional"Close"
classstringOptional""

Slots

  • default

Events

  • open
  • close
  • select
  • change

Source contract

Installed source: components/Dropdown.wrn

component Dropdown {
   props {
+    @event open = function
+    @event close = function
+    @event select = function
+    @event change = function
     size = "default"
     color = "primary"
     title = "Dropdown"
@@ -42,7 +46,7 @@ page Dropdowncomponent {
     }
 }
 
- + } diff --git a/app/pages/components/file-input.wrn b/app/pages/components/file-input.wrn index 7e60809a..62623c3b 100644 --- a/app/pages/components/file-input.wrn +++ b/app/pages/components/file-input.wrn @@ -10,40 +10,73 @@ page FileInputcomponent {
W WRNexusJS - +
-
forms component

FileInput

Theme-aware, responsive file input component.

@wrnexus/ui 0.4.013 props0 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<FileInput
+      
forms component

FileInput

Theme-aware, responsive file input component.

@wrnexus/ui 0.5.021 props0 slots7 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<FileInput
   size="default"
   color="primary"
-  label="File Input"
+  id="id"
   name="name"
-  value="value"
-/>

Legacy mount name: data-component="FileInput".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
labelstringOptional"File Input"
namestringOptional""
valuestringOptional""
placeholderstringOptional""
typestringOptional"file"
minstringOptional""
maxstringOptional""
stepstringOptional""
disabledbooleanOptionalfalse
requiredbooleanOptionalfalse
classstringOptional""

Slots

This component does not declare a slot.

Events

This component does not declare a custom event.

Source contract

Installed source: components/FileInput.wrn

component FileInput {
+  label="File"
+/>

Legacy mount name: data-component="FileInput".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
idstringOptional""
namestringOptional""
labelstringOptional"File"
hiddenLabelbooleanOptionalfalse
placeholderstringOptional"Choose a file"
valuestringOptional""
iconstringOptional"icon-[lucide--upload]"
iconPositionstringOptional"start"
acceptstringOptional""
multiplebooleanOptionalfalse
helperTextstringOptional""
cornerHintstringOptional""
errorstringOptional""
inlinebooleanOptionalfalse
variantstringOptional"normal"
readonlybooleanOptionalfalse
disabledbooleanOptionalfalse
requiredbooleanOptionalfalse
classstringOptional""

Slots

This component does not declare a slot.

Events

  • input
  • change
  • focus
  • blur
  • select
  • clear
  • invalid

Source contract

Installed source: components/FileInput.wrn

component FileInput {
   props {
+    @event input = function
+    @event change = function
+    @event focus = function
+    @event blur = function
+    @event select = function
+    @event clear = function
+    @event invalid = function
     size = "default"
     color = "primary"
-    label = "File Input"
+    id = ""
     name = ""
+    label = "File"
+    hiddenLabel = false
+    placeholder = "Choose a file"
     value = ""
-    placeholder = ""
-    type = "file"
-    min = ""
-    max = ""
-    step = ""
+    icon = "icon-[lucide--upload]"
+    iconPosition = "start"
+    accept = ""
+    multiple = false
+    helperText = ""
+    cornerHint = ""
+    error = ""
+    inline = false
+    variant = "normal"
+    readonly = false
     disabled = false
     required = false
     class = ""
   }
+  state selectedName = ""
+  functions {
+    function handleChange(sourceEvent) {
+      sourceEvent.stopPropagation()
+      selectedName = sourceEvent.currentTarget.files && sourceEvent.currentTarget.files.length ? sourceEvent.currentTarget.files[0].name : ""
+      $emit("input", { files: sourceEvent.currentTarget.files, name: name, sourceEvent: sourceEvent })
+      $emit("change", { files: sourceEvent.currentTarget.files, name: name, sourceEvent: sourceEvent })
+      if (selectedName) $emit("select", { files: sourceEvent.currentTarget.files, name: name, sourceEvent: sourceEvent })
+      else $emit("clear", { name: name, sourceEvent: sourceEvent })
+    }
+    function emitField(nameEvent, sourceEvent) { sourceEvent.stopPropagation(); $emit(nameEvent, { name: name, sourceEvent: sourceEvent }) }
+    function preventReadonly(sourceEvent) { if (readonly) sourceEvent.preventDefault() }
+  }
   view {
-        <label class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--field wire-next--file-input {class}">
-        <span>{label}</span>
-        <input {...attrs} type="{type}" name="{name}" value="{value}" placeholder="{placeholder}" min="{min}" max="{max}" step="{step}" disabled="{disabled}" required="{required}" />
-        </label>
+        <div {...attrs} class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--field wire-next--file-input {class}" data-variant="{variant}" data-inline="{inline}" data-invalid="{error ? 'true' : 'false'}">
+        <div class="wire-next__field-heading">
+        <label class="{hiddenLabel ? 'wire-next__sr-only' : ''}" for="{id || name}">{label}</label>{#if cornerHint}<span class="wire-next__field-hint">{cornerHint}</span>{/if}</div>
+        <div class="wire-next__file-control" data-icon-position="{iconPosition}">{#if icon}<span class="{icon}" aria-hidden="true">
+        </span>{/if}<span>{selectedName || value || placeholder}</span>
+        <input id="{id || name}" type="file" name="{name}" accept="{accept}" multiple="{multiple}" disabled="{disabled}" required="{required}" aria-readonly="{readonly}" aria-invalid="{error ? 'true' : 'false'}" @click="preventReadonly(event)" @input="handleChange(event)" @change="handleChange(event)" @focus="emitField('focus', event)" @blur="emitField('blur', event)" @invalid="emitField('invalid', event)" />
+        </div>
+      {#if helperText}<small class="wire-next__field-help">{helperText}</small>{/if}<small class="wire-next__field-error" data-error="{name}">{error}</small>
+        </div>
     }
 }
 
- + } diff --git a/app/pages/components/file-upload-progress.wrn b/app/pages/components/file-upload-progress.wrn index 2bea4ee2..10916aa6 100644 --- a/app/pages/components/file-upload-progress.wrn +++ b/app/pages/components/file-upload-progress.wrn @@ -10,36 +10,62 @@ page FileUploadProgresscomponent {
W WRNexusJS - +
-
base component

FileUploadProgress

Theme-aware, responsive file upload progress component.

@wrnexus/ui 0.4.07 props0 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<FileUploadProgress
+      
base component

FileUploadProgress

Theme-aware, responsive file upload progress component.

@wrnexus/ui 0.5.013 props0 slots3 events

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

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
labelstringOptional"Progress"
valuenumberOptional50
maxnumberOptional100
showValuebooleanOptionaltrue
classstringOptional""

Slots

This component does not declare a slot.

Events

This component does not declare a custom event.

Source contract

Installed source: components/FileUploadProgress.wrn

component FileUploadProgress {
+/>

Legacy mount name: data-component="FileUploadProgress".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
labelstringOptional"Progress"
valuenumberOptional50
maxnumberOptional100
showValuebooleanOptionaltrue
fileNamestringOptional""
fileSizestringOptional""
uploadedSizestringOptional""
statusstringOptional"uploading"
cancelLabelstringOptional"Cancel upload"
retryLabelstringOptional"Retry upload"
classstringOptional""

Slots

This component does not declare a slot.

Events

  • cancel
  • retry
  • complete

Source contract

Installed source: components/FileUploadProgress.wrn

component FileUploadProgress {
   props {
+    @event cancel = function
+    @event retry = function
+    @event complete = function
     size = "default"
     color = "primary"
     label = "Progress"
     value = 50
     max = 100
     showValue = true
+    fileName = ""
+    fileSize = ""
+    uploadedSize = ""
+    status = "uploading"
+    cancelLabel = "Cancel upload"
+    retryLabel = "Retry upload"
     class = ""
   }
+  state currentValue = value
+  state currentStatus = status
+  functions {
+    function percent() { if (!Number(max)) { return 0 } return Math.max(0, Math.min(100, Math.round(Number(currentValue) / Number(max) * 100))) }
+    function detail(sourceEvent) { return { value: currentValue, max: max, percent: percent(), status: currentStatus, fileName: fileName, sourceEvent: sourceEvent } }
+    function cancelUpload(sourceEvent) { currentStatus = "cancelled"; $emit("cancel", detail(sourceEvent)) }
+    function retryUpload(sourceEvent) { currentValue = 0; currentStatus = "uploading"; $emit("retry", detail(sourceEvent)) }
+    function completeUpload(sourceEvent) { currentValue = max; currentStatus = "complete"; $emit("complete", detail(sourceEvent)) }
+  }
   view {
-        <div class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--file-upload-progress {class}">
+        <div {...attrs} class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--file-upload-progress {class}" data-status="{currentStatus}" aria-live="polite">
         <div class="wire-next__row">
-        <span>{label}</span>{#if showValue}<strong>{value}%</strong>{/if}</div>
-        <progress value="{value}" max="{max}">
+        <span>{#if fileName}<strong>{fileName}</strong>
+        <small>{#if uploadedSize || fileSize}{uploadedSize}{#if uploadedSize && fileSize} of {/if}{fileSize}{:else}{label}{/if}</small>{:else}<strong>{label}</strong>{/if}</span>{#if showValue}<strong>{percent()}%</strong>{/if}</div>
+        <progress value="{currentValue}" max="{max}" aria-label="{label}">
         </progress>
+        <div class="wire-next__upload-status">
+        <span class="wire-next__upload-status-icon" aria-hidden="true">
+        </span>
+        <span>{#if currentStatus === "uploading"}Uploading securely…{:else if currentStatus === "complete"}Upload complete{:else if currentStatus === "error"}Upload failed{:else}Upload cancelled{/if}</span>
+        </div>
+        <div class="wire-next__upload-actions">{#if currentStatus === "uploading"}<button type="button" @click="cancelUpload(event)">{cancelLabel}</button>
+        <button type="button" @click="completeUpload(event)">Complete</button>{/if}{#if currentStatus === "error" || currentStatus === "cancelled"}<button type="button" @click="retryUpload(event)">{retryLabel}</button>{/if}</div>
         </div>
     }
 }
 
- + } diff --git a/app/pages/components/file-upload.wrn b/app/pages/components/file-upload.wrn index ac536388..f2beccf2 100644 --- a/app/pages/components/file-upload.wrn +++ b/app/pages/components/file-upload.wrn @@ -10,17 +10,24 @@ page FileUploadcomponent {
W WRNexusJS - +
-
integrations component

FileUpload

Theme-aware, responsive file upload component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<FileUpload
+      
integrations component

FileUpload

Theme-aware, responsive file upload component.

@wrnexus/ui 0.5.07 props1 slots7 events

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

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
titlestringOptional"File Upload"
descriptionstringOptional""
itemsstringOptional[]
variantstringOptional"default"
classstringOptional""

Slots

  • default

Events

This component does not declare a custom event.

Source contract

Installed source: components/FileUpload.wrn

component FileUpload {
+/>

Legacy mount name: data-component="FileUpload".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
titlestringOptional"File Upload"
descriptionstringOptional""
itemsstringOptional[]
variantstringOptional"default"
classstringOptional""

Slots

  • default

Events

  • select
  • upload
  • progress
  • success
  • error
  • cancel
  • remove

Source contract

Installed source: components/FileUpload.wrn

component FileUpload {
   props {
+    @event select = function
+    @event upload = function
+    @event progress = function
+    @event success = function
+    @event error = function
+    @event cancel = function
+    @event remove = function
     size = "default"
     color = "primary"
     title = "File Upload"
@@ -39,7 +46,7 @@ page FileUploadcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/grid.wrn b/app/pages/components/grid.wrn index 1613a7e7..23f1289b 100644 --- a/app/pages/components/grid.wrn +++ b/app/pages/components/grid.wrn @@ -10,10 +10,10 @@ page Gridcomponent {
W WRNexusJS - +
-
layout component

Grid

Theme-aware, responsive grid component.

@wrnexus/ui 0.4.06 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Grid
+      
layout component

Grid

Theme-aware, responsive grid component.

@wrnexus/ui 0.5.06 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Grid
   size="default"
   color="primary"
   columns="2"
@@ -35,7 +35,7 @@ page Gridcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/image.wrn b/app/pages/components/image.wrn index 1f2f2595..4208e1d6 100644 --- a/app/pages/components/image.wrn +++ b/app/pages/components/image.wrn @@ -10,17 +10,19 @@ page Imagecomponent {
W WRNexusJS - +
-
layout component

Image

Theme-aware, responsive image component.

@wrnexus/ui 0.4.09 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Image
+      
layout component

Image

Theme-aware, responsive image component.

@wrnexus/ui 0.5.09 props1 slots2 events

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

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
srcstringOptional""
altstringOptional""
widthstringOptional""
heightstringOptional""
loadingstringOptional"lazy"
roundedbooleanOptionalfalse
classstringOptional""

Slots

  • default

Events

This component does not declare a custom event.

Source contract

Installed source: components/Image.wrn

component Image {
+/>

Legacy mount name: data-component="Image".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
srcstringOptional""
altstringOptional""
widthstringOptional""
heightstringOptional""
loadingstringOptional"lazy"
roundedbooleanOptionalfalse
classstringOptional""

Slots

  • default

Events

  • load
  • error

Source contract

Installed source: components/Image.wrn

component Image {
   props {
+    @event load = function
+    @event error = function
     size = "default"
     color = "primary"
     src = ""
@@ -39,7 +41,7 @@ page Imagecomponent {
     }
 }
 
- + } diff --git a/app/pages/components/input-group.wrn b/app/pages/components/input-group.wrn index b3ed520d..5aed88c6 100644 --- a/app/pages/components/input-group.wrn +++ b/app/pages/components/input-group.wrn @@ -10,40 +10,70 @@ page InputGroupcomponent {
W WRNexusJS - +
-
forms component

InputGroup

Theme-aware, responsive input group component.

@wrnexus/ui 0.4.013 props0 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<InputGroup
+      
forms component

InputGroup

Theme-aware, responsive input group component.

@wrnexus/ui 0.5.023 props0 slots6 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<InputGroup
   size="default"
   color="primary"
-  label="Input Group"
+  id="id"
   name="name"
-  value="value"
-/>

Legacy mount name: data-component="InputGroup".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
labelstringOptional"Input Group"
namestringOptional""
valuestringOptional""
placeholderstringOptional""
typestringOptional"text"
minstringOptional""
maxstringOptional""
stepstringOptional""
disabledbooleanOptionalfalse
requiredbooleanOptionalfalse
classstringOptional""

Slots

This component does not declare a slot.

Events

This component does not declare a custom event.

Source contract

Installed source: components/InputGroup.wrn

component InputGroup {
+  label="Input group"
+/>

Legacy mount name: data-component="InputGroup".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
idstringOptional""
namestringOptional""
labelstringOptional"Input group"
hiddenLabelbooleanOptionalfalse
valuestringOptional""
placeholderstringOptional""
typestringOptional"text"
startTextstringOptional""
endTextstringOptional""
iconstringOptional""
iconPositionstringOptional"start"
actionLabelstringOptional""
helperTextstringOptional""
cornerHintstringOptional""
errorstringOptional""
inlinebooleanOptionalfalse
variantstringOptional"normal"
readonlybooleanOptionalfalse
disabledbooleanOptionalfalse
requiredbooleanOptionalfalse
classstringOptional""

Slots

This component does not declare a slot.

Events

  • input
  • change
  • focus
  • blur
  • submit
  • action

Source contract

Installed source: components/InputGroup.wrn

component InputGroup {
   props {
+    @event input = function
+    @event change = function
+    @event focus = function
+    @event blur = function
+    @event submit = function
+    @event action = function
     size = "default"
     color = "primary"
-    label = "Input Group"
+    id = ""
     name = ""
+    label = "Input group"
+    hiddenLabel = false
     value = ""
     placeholder = ""
     type = "text"
-    min = ""
-    max = ""
-    step = ""
+    startText = ""
+    endText = ""
+    icon = ""
+    iconPosition = "start"
+    actionLabel = ""
+    helperText = ""
+    cornerHint = ""
+    error = ""
+    inline = false
+    variant = "normal"
+    readonly = false
     disabled = false
     required = false
     class = ""
   }
+  functions {
+    function emitField(nameEvent, sourceEvent) { sourceEvent.stopPropagation(); $emit(nameEvent, { value: sourceEvent.currentTarget.value, name: name, sourceEvent: sourceEvent }) }
+    function handleKeydown(sourceEvent) { if (sourceEvent.key === "Enter") { sourceEvent.stopPropagation(); $emit("submit", { value: sourceEvent.currentTarget.value, name: name, sourceEvent: sourceEvent }) } }
+    function handleAction(sourceEvent) { $emit("action", { name: name, sourceEvent: sourceEvent }) }
+  }
   view {
-        <label class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--field wire-next--input-group {class}">
-        <span>{label}</span>
-        <input {...attrs} type="{type}" name="{name}" value="{value}" placeholder="{placeholder}" min="{min}" max="{max}" step="{step}" disabled="{disabled}" required="{required}" />
-        </label>
+        <div {...attrs} class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--field wire-next--input-group {class}" data-variant="{variant}" data-inline="{inline}" data-invalid="{error ? 'true' : 'false'}">
+        <div class="wire-next__field-heading">
+        <label class="{hiddenLabel ? 'wire-next__sr-only' : ''}" for="{id || name}">{label}</label>{#if cornerHint}<span class="wire-next__field-hint">{cornerHint}</span>{/if}</div>
+        <div class="wire-next__input-group-control">
+        {#if startText}<span class="wire-next__input-addon">{startText}</span>{/if}
+        {#if icon}<span class="{icon} wire-next__field-icon" data-position="{iconPosition}" aria-hidden="true">
+        </span>{/if}
+        <input id="{id || name}" type="{type}" name="{name}" value="{value}" placeholder="{placeholder}" readonly="{readonly}" disabled="{disabled}" required="{required}" aria-invalid="{error ? 'true' : 'false'}" @input="emitField('input', event)" @change="emitField('change', event)" @focus="emitField('focus', event)" @blur="emitField('blur', event)" @keydown="handleKeydown(event)" />
+        {#if endText}<span class="wire-next__input-addon">{endText}</span>{/if}
+        {#if actionLabel}<button type="button" disabled="{disabled}" @click="handleAction(event)">{actionLabel}</button>{/if}
+      </div>
+      {#if helperText}<small class="wire-next__field-help">{helperText}</small>{/if}<small class="wire-next__field-error" data-error="{name}">{error}</small>
+        </div>
     }
 }
 
- + } diff --git a/app/pages/components/input-number.wrn b/app/pages/components/input-number.wrn index b5a87e69..201abb0f 100644 --- a/app/pages/components/input-number.wrn +++ b/app/pages/components/input-number.wrn @@ -10,10 +10,10 @@ page InputNumbercomponent {
W WRNexusJS - +
-
advanced-forms component

InputNumber

Theme-aware, responsive input number component.

@wrnexus/ui 0.4.040 props0 slots4 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<InputNumber
+      
advanced-forms component

InputNumber

Theme-aware, responsive input number component.

@wrnexus/ui 0.5.040 props0 slots4 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<InputNumber
   size="default"
   color="primary"
   variant="default"
@@ -647,7 +647,7 @@ page InputNumbercomponent {
     }
 }
 
- + } diff --git a/app/pages/components/input.wrn b/app/pages/components/input.wrn index 10bbfeb4..7a5bfb8d 100644 --- a/app/pages/components/input.wrn +++ b/app/pages/components/input.wrn @@ -10,40 +10,110 @@ page Inputcomponent {
W WRNexusJS - +
-
forms component

Input

Theme-aware, responsive input component.

@wrnexus/ui 0.4.013 props0 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Input
+      
forms component

Input

Theme-aware, responsive input component.

@wrnexus/ui 0.5.028 props0 slots7 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Input
   size="default"
   color="primary"
-  label="Input"
+  id="id"
   name="name"
-  value="value"
-/>

Legacy mount name: data-component="Input".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
labelstringOptional"Input"
namestringOptional""
valuestringOptional""
placeholderstringOptional""
typestringOptional"text"
minstringOptional""
maxstringOptional""
stepstringOptional""
disabledbooleanOptionalfalse
requiredbooleanOptionalfalse
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

component Input {
+  label="Input"
+/>

Legacy mount name: data-component="Input".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
idstringOptional""
namestringOptional""
labelstringOptional"Input"
hiddenLabelbooleanOptionalfalse
placeholderstringOptional""
valuestringOptional""
typestringOptional"text"
variantstringOptional"normal"
iconstringOptional""
iconPositionstringOptional"start"
helperTextstringOptional""
cornerHintstringOptional""
errorstringOptional""
inlinebooleanOptionalfalse
readonlybooleanOptionalfalse
disabledbooleanOptionalfalse
requiredbooleanOptionalfalse
autocompletestringOptional""
inputmodestringOptional""
minlengthstringOptional""
maxlengthstringOptional""
patternstringOptional""
minstringOptional""
maxstringOptional""
stepstringOptional""
classstringOptional""

Slots

This component does not declare a slot.

Events

  • input
  • change
  • focus
  • blur
  • invalid
  • keydown
  • keyup

Source contract

Installed source: components/Input.wrn

component Input {
   props {
+    @event input = function
+    @event change = function
+    @event focus = function
+    @event blur = function
+    @event invalid = function
+    @event keydown = function
+    @event keyup = function
     size = "default"
     color = "primary"
-    label = "Input"
+    id = ""
     name = ""
-    value = ""
+    label = "Input"
+    hiddenLabel = false
     placeholder = ""
+    value = ""
     type = "text"
+    variant = "normal"
+    icon = ""
+    iconPosition = "start"
+    helperText = ""
+    cornerHint = ""
+    error = ""
+    inline = false
+    readonly = false
+    disabled = false
+    required = false
+    autocomplete = ""
+    inputmode = ""
+    minlength = ""
+    maxlength = ""
+    pattern = ""
     min = ""
     max = ""
     step = ""
-    disabled = false
-    required = false
     class = ""
   }
+  functions {
+    function detail(sourceEvent) {
+      return { value: sourceEvent.currentTarget.value, name: name, sourceEvent: sourceEvent }
+    }
+    function handleInput(sourceEvent) { sourceEvent.stopPropagation(); $emit("input", detail(sourceEvent)) }
+    function handleChange(sourceEvent) { sourceEvent.stopPropagation(); $emit("change", detail(sourceEvent)) }
+    function handleFocus(sourceEvent) { sourceEvent.stopPropagation(); $emit("focus", detail(sourceEvent)) }
+    function handleBlur(sourceEvent) { sourceEvent.stopPropagation(); $emit("blur", detail(sourceEvent)) }
+    function handleInvalid(sourceEvent) { sourceEvent.stopPropagation(); $emit("invalid", { value: sourceEvent.currentTarget.value, name: name, message: sourceEvent.currentTarget.validationMessage, sourceEvent: sourceEvent }) }
+    function handleKeydown(sourceEvent) { sourceEvent.stopPropagation(); $emit("keydown", { key: sourceEvent.key, value: sourceEvent.currentTarget.value, name: name, sourceEvent: sourceEvent }) }
+    function handleKeyup(sourceEvent) { sourceEvent.stopPropagation(); $emit("keyup", { key: sourceEvent.key, value: sourceEvent.currentTarget.value, name: name, sourceEvent: sourceEvent }) }
+  }
   view {
-        <label class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--field wire-next--input {class}">
-        <span>{label}</span>
-        <input {...attrs} type="{type}" name="{name}" value="{value}" placeholder="{placeholder}" min="{min}" max="{max}" step="{step}" disabled="{disabled}" required="{required}" />
-        </label>
+        <div {...attrs} class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--field wire-next--input {class}" data-variant="{variant}" data-inline="{inline}" data-floating="{variant === 'floating'}" data-invalid="{error ? 'true' : 'false'}">
+        <div class="wire-next__field-heading">
+        <label class="{hiddenLabel ? 'wire-next__sr-only' : ''}" for="{id || name}">{label}</label>
+        {#if cornerHint}<span class="wire-next__field-hint">{cornerHint}</span>{/if}
+      </div>
+        <div class="wire-next__field-control" data-icon-position="{iconPosition}">
+        {#if icon}<span class="{icon} wire-next__field-icon" aria-hidden="true">
+        </span>{/if}
+        <input
+          id="{id || name}"
+          type="{type}"
+          name="{name}"
+          value="{value}"
+          placeholder="{variant === 'floating' ? ' ' : placeholder}"
+          readonly="{readonly}"
+          disabled="{disabled}"
+          required="{required}"
+          autocomplete="{autocomplete}"
+          inputmode="{inputmode}"
+          minlength="{minlength}"
+          maxlength="{maxlength}"
+          pattern="{pattern}"
+          min="{min}"
+          max="{max}"
+          step="{step}"
+          aria-invalid="{error ? 'true' : 'false'}"
+          aria-describedby="{error ? (id || name) + '-error' : (helperText ? (id || name) + '-help' : '')}"
+          @input="handleInput(event)"
+          @change="handleChange(event)"
+          @focus="handleFocus(event)"
+          @blur="handleBlur(event)"
+          @invalid="handleInvalid(event)"
+          @keydown="handleKeydown(event)"
+          @keyup="handleKeyup(event)"
+        />
+        {#if variant === "floating"}<span class="wire-next__field-floating-label">{label}</span>{/if}
+      </div>
+      {#if helperText}<small id="{(id || name) + '-help'}" class="wire-next__field-help">{helperText}</small>{/if}
+      <small id="{(id || name) + '-error'}" class="wire-next__field-error" data-error="{name}">{error}</small>
+        </div>
     }
 }
 
- + } diff --git a/app/pages/components/kbd.wrn b/app/pages/components/kbd.wrn index ed78e796..237c0314 100644 --- a/app/pages/components/kbd.wrn +++ b/app/pages/components/kbd.wrn @@ -10,10 +10,10 @@ page Kbdcomponent {
W WRNexusJS - +
-
layout component

Kbd

Theme-aware, responsive kbd component.

@wrnexus/ui 0.4.04 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Kbd
+      
layout component

Kbd

Theme-aware, responsive kbd component.

@wrnexus/ui 0.5.04 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Kbd
   size="default"
   color="primary"
   label="⌘ K"
@@ -31,7 +31,7 @@ page Kbdcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/layout-splitter.wrn b/app/pages/components/layout-splitter.wrn index 84e44469..b870ffe6 100644 --- a/app/pages/components/layout-splitter.wrn +++ b/app/pages/components/layout-splitter.wrn @@ -10,17 +10,20 @@ page LayoutSplittercomponent {
W WRNexusJS - +
-
layout component

LayoutSplitter

Theme-aware, responsive layout splitter component.

@wrnexus/ui 0.4.06 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<LayoutSplitter
+      
layout component

LayoutSplitter

Theme-aware, responsive layout splitter component.

@wrnexus/ui 0.5.06 props1 slots3 events

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

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
columnsnumberOptional2
gapstringOptional"md"
maxWidthstringOptional"xl"
classstringOptional""

Slots

  • default

Events

This component does not declare a custom event.

Source contract

Installed source: components/LayoutSplitter.wrn

component LayoutSplitter {
+/>

Legacy mount name: data-component="LayoutSplitter".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
columnsnumberOptional2
gapstringOptional"md"
maxWidthstringOptional"xl"
classstringOptional""

Slots

  • default

Events

  • resizeStart
  • resize
  • resizeEnd

Source contract

Installed source: components/LayoutSplitter.wrn

component LayoutSplitter {
   props {
+    @event resizeStart = function
+    @event resize = function
+    @event resizeEnd = function
     size = "default"
     color = "primary"
     columns = 2
@@ -35,7 +38,7 @@ page LayoutSplittercomponent {
     }
 }
 
- + } diff --git a/app/pages/components/legend-indicator.wrn b/app/pages/components/legend-indicator.wrn index b0896c3e..8c1f5b48 100644 --- a/app/pages/components/legend-indicator.wrn +++ b/app/pages/components/legend-indicator.wrn @@ -10,17 +10,19 @@ page LegendIndicatorcomponent {
W WRNexusJS - +
-
base component

LegendIndicator

Theme-aware, responsive legend indicator component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<LegendIndicator
+      
base component

LegendIndicator

Theme-aware, responsive legend indicator component.

@wrnexus/ui 0.5.07 props1 slots2 events

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

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
titlestringOptional"Legend Indicator"
descriptionstringOptional""
itemsstringOptional[]
variantstringOptional"default"
classstringOptional""

Slots

  • default

Events

This component does not declare a custom event.

Source contract

Installed source: components/LegendIndicator.wrn

component LegendIndicator {
+/>

Legacy mount name: data-component="LegendIndicator".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
titlestringOptional"Legend Indicator"
descriptionstringOptional""
itemsstringOptional[]
variantstringOptional"default"
classstringOptional""

Slots

  • default

Events

  • toggle
  • select

Source contract

Installed source: components/LegendIndicator.wrn

component LegendIndicator {
   props {
+    @event toggle = function
+    @event select = function
     size = "default"
     color = "primary"
     title = "Legend Indicator"
@@ -39,7 +41,7 @@ page LegendIndicatorcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/link.wrn b/app/pages/components/link.wrn index 9f775e18..68dc6ac4 100644 --- a/app/pages/components/link.wrn +++ b/app/pages/components/link.wrn @@ -10,17 +10,20 @@ page Linkcomponent {
W WRNexusJS - +
-
layout component

Link

Theme-aware, responsive link component.

@wrnexus/ui 0.4.08 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Link
+      
layout component

Link

Theme-aware, responsive link component.

@wrnexus/ui 0.5.08 props1 slots3 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Link
   size="default"
   color="primary"
   label="Link"
   href="#"
   target="target"
-/>

Legacy mount name: data-component="Link".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
labelstringOptional"Link"
hrefstringOptional"#"
targetstringOptional""
relstringOptional""
externalbooleanOptionalfalse
classstringOptional""

Slots

  • default

Events

This component does not declare a custom event.

Source contract

Installed source: components/Link.wrn

component Link {
+/>

Legacy mount name: data-component="Link".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
labelstringOptional"Link"
hrefstringOptional"#"
targetstringOptional""
relstringOptional""
externalbooleanOptionalfalse
classstringOptional""

Slots

  • default

Events

  • click
  • focus
  • blur

Source contract

Installed source: components/Link.wrn

component Link {
   props {
+    @event click = function
+    @event focus = function
+    @event blur = function
     size = "default"
     color = "primary"
     label = "Link"
@@ -36,7 +39,7 @@ page Linkcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/list-group.wrn b/app/pages/components/list-group.wrn index 3a331344..19732d58 100644 --- a/app/pages/components/list-group.wrn +++ b/app/pages/components/list-group.wrn @@ -10,17 +10,19 @@ page ListGroupcomponent {
W WRNexusJS - +
-
base component

ListGroup

Theme-aware, responsive list group component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<ListGroup
+      
base component

ListGroup

Theme-aware, responsive list group component.

@wrnexus/ui 0.5.07 props1 slots2 events

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

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
titlestringOptional"List Group"
descriptionstringOptional""
itemsstringOptional[]
variantstringOptional"default"
classstringOptional""

Slots

  • default

Events

This component does not declare a custom event.

Source contract

Installed source: components/ListGroup.wrn

component ListGroup {
+/>

Legacy mount name: data-component="ListGroup".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
titlestringOptional"List Group"
descriptionstringOptional""
itemsstringOptional[]
variantstringOptional"default"
classstringOptional""

Slots

  • default

Events

  • select
  • change

Source contract

Installed source: components/ListGroup.wrn

component ListGroup {
   props {
+    @event select = function
+    @event change = function
     size = "default"
     color = "primary"
     title = "List Group"
@@ -39,7 +41,7 @@ page ListGroupcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/list.wrn b/app/pages/components/list.wrn index 1c9eb3e5..49ec1dd4 100644 --- a/app/pages/components/list.wrn +++ b/app/pages/components/list.wrn @@ -10,17 +10,19 @@ page Listcomponent {
W WRNexusJS - +
-
base component

List

Theme-aware, responsive list component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<List
+      
base component

List

Theme-aware, responsive list component.

@wrnexus/ui 0.5.07 props1 slots2 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<List
   size="default"
   color="primary"
   title="List"
   description="description"
   items="[]"
-/>

Legacy mount name: data-component="List".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
titlestringOptional"List"
descriptionstringOptional""
itemsstringOptional[]
variantstringOptional"default"
classstringOptional""

Slots

  • default

Events

This component does not declare a custom event.

Source contract

Installed source: components/List.wrn

component List {
+/>

Legacy mount name: data-component="List".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
titlestringOptional"List"
descriptionstringOptional""
itemsstringOptional[]
variantstringOptional"default"
classstringOptional""

Slots

  • default

Events

  • select
  • click

Source contract

Installed source: components/List.wrn

component List {
   props {
+    @event select = function
+    @event click = function
     size = "default"
     color = "primary"
     title = "List"
@@ -39,7 +41,7 @@ page Listcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/map.wrn b/app/pages/components/map.wrn index 6521bc10..1d722967 100644 --- a/app/pages/components/map.wrn +++ b/app/pages/components/map.wrn @@ -10,17 +10,21 @@ page Mapcomponent {
W WRNexusJS - +
-
integrations component

Map

Theme-aware, responsive map component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Map
+      
integrations component

Map

Theme-aware, responsive map component.

@wrnexus/ui 0.5.07 props1 slots4 events

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

PropTypeRequirementDefault
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 {
+/>

Legacy mount name: data-component="Map".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
titlestringOptional"Map"
descriptionstringOptional""
itemsstringOptional[]
variantstringOptional"default"
classstringOptional""

Slots

  • default

Events

  • ready
  • move
  • zoom
  • markerClick

Source contract

Installed source: components/Map.wrn

component Map {
   props {
+    @event ready = function
+    @event move = function
+    @event zoom = function
+    @event markerClick = function
     size = "default"
     color = "primary"
     title = "Map"
@@ -39,7 +43,7 @@ page Mapcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/marquee.wrn b/app/pages/components/marquee.wrn index 8bc19776..f344e997 100644 --- a/app/pages/components/marquee.wrn +++ b/app/pages/components/marquee.wrn @@ -10,17 +10,19 @@ page Marqueecomponent {
W WRNexusJS - +
-
base component

Marquee

Theme-aware, responsive marquee component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Marquee
+      
base component

Marquee

Theme-aware, responsive marquee component.

@wrnexus/ui 0.5.07 props1 slots2 events

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

PropTypeRequirementDefault
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 {
+/>

Legacy mount name: data-component="Marquee".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
titlestringOptional"Marquee"
descriptionstringOptional""
itemsstringOptional[]
variantstringOptional"default"
classstringOptional""

Slots

  • default

Events

  • pause
  • resume

Source contract

Installed source: components/Marquee.wrn

component Marquee {
   props {
+    @event pause = function
+    @event resume = function
     size = "default"
     color = "primary"
     title = "Marquee"
@@ -39,7 +41,7 @@ page Marqueecomponent {
     }
 }
 
- + } diff --git a/app/pages/components/mega-menu.wrn b/app/pages/components/mega-menu.wrn index fee67207..667f893a 100644 --- a/app/pages/components/mega-menu.wrn +++ b/app/pages/components/mega-menu.wrn @@ -10,17 +10,20 @@ page MegaMenucomponent {
W WRNexusJS - +
-
navigation component

MegaMenu

Theme-aware, responsive mega menu component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<MegaMenu
+      
navigation component

MegaMenu

Theme-aware, responsive mega menu component.

@wrnexus/ui 0.5.07 props1 slots3 events

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

PropTypeRequirementDefault
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 {
+/>

Legacy mount name: data-component="MegaMenu".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
labelstringOptional"Mega Menu"
itemsstringOptional[]
activestringOptional""
orientationstringOptional"horizontal"
classstringOptional""

Slots

  • default

Events

  • open
  • close
  • select

Source contract

Installed source: components/MegaMenu.wrn

component MegaMenu {
   props {
+    @event open = function
+    @event close = function
+    @event select = function
     size = "default"
     color = "primary"
     label = "Mega Menu"
@@ -37,7 +40,7 @@ page MegaMenucomponent {
     }
 }
 
- + } diff --git a/app/pages/components/modal.wrn b/app/pages/components/modal.wrn index 98d67146..7be2a09c 100644 --- a/app/pages/components/modal.wrn +++ b/app/pages/components/modal.wrn @@ -10,17 +10,21 @@ page Modalcomponent {
W WRNexusJS - +
-
overlays component

Modal

Theme-aware, responsive modal component.

@wrnexus/ui 0.4.08 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Modal
+      
overlays component

Modal

Theme-aware, responsive modal component.

@wrnexus/ui 0.5.08 props1 slots4 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Modal
   size="default"
   color="primary"
   title="Modal"
   description="description"
   open="false"
-/>

Legacy mount name: data-component="Modal".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
titlestringOptional"Modal"
descriptionstringOptional""
openbooleanOptionalfalse
placementstringOptional"bottom"
closeLabelstringOptional"Close"
classstringOptional""

Slots

  • default

Events

This component does not declare a custom event.

Source contract

Installed source: components/Modal.wrn

component Modal {
+/>

Legacy mount name: data-component="Modal".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
titlestringOptional"Modal"
descriptionstringOptional""
openbooleanOptionalfalse
placementstringOptional"bottom"
closeLabelstringOptional"Close"
classstringOptional""

Slots

  • default

Events

  • open
  • close
  • cancel
  • confirm

Source contract

Installed source: components/Modal.wrn

component Modal {
   props {
+    @event open = function
+    @event close = function
+    @event cancel = function
+    @event confirm = function
     size = "default"
     color = "primary"
     title = "Modal"
@@ -42,7 +46,7 @@ page Modalcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/nav.wrn b/app/pages/components/nav.wrn index 1789491c..a1e0cab8 100644 --- a/app/pages/components/nav.wrn +++ b/app/pages/components/nav.wrn @@ -10,17 +10,19 @@ page Navcomponent {
W WRNexusJS - +
-
navigation component

Nav

Theme-aware, responsive nav component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Nav
+      
navigation component

Nav

Theme-aware, responsive nav component.

@wrnexus/ui 0.5.07 props1 slots2 events

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

PropTypeRequirementDefault
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 {
+/>

Legacy mount name: data-component="Nav".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
labelstringOptional"Nav"
itemsstringOptional[]
activestringOptional""
orientationstringOptional"horizontal"
classstringOptional""

Slots

  • default

Events

  • select
  • change

Source contract

Installed source: components/Nav.wrn

component Nav {
   props {
+    @event select = function
+    @event change = function
     size = "default"
     color = "primary"
     label = "Nav"
@@ -37,7 +39,7 @@ page Navcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/navbar.wrn b/app/pages/components/navbar.wrn index 117b9eb6..b9db3a58 100644 --- a/app/pages/components/navbar.wrn +++ b/app/pages/components/navbar.wrn @@ -10,17 +10,20 @@ page Navbarcomponent {
W WRNexusJS - +
-
navigation component

Navbar

Theme-aware, responsive navbar component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Navbar
+      
navigation component

Navbar

Theme-aware, responsive navbar component.

@wrnexus/ui 0.5.07 props1 slots3 events

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

PropTypeRequirementDefault
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 {
+/>

Legacy mount name: data-component="Navbar".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
labelstringOptional"Navbar"
itemsstringOptional[]
activestringOptional""
orientationstringOptional"horizontal"
classstringOptional""

Slots

  • default

Events

  • toggle
  • open
  • close

Source contract

Installed source: components/Navbar.wrn

component Navbar {
   props {
+    @event toggle = function
+    @event open = function
+    @event close = function
     size = "default"
     color = "primary"
     label = "Navbar"
@@ -37,7 +40,7 @@ page Navbarcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/pagination.wrn b/app/pages/components/pagination.wrn index 620083d3..38707e0d 100644 --- a/app/pages/components/pagination.wrn +++ b/app/pages/components/pagination.wrn @@ -10,17 +10,20 @@ page Paginationcomponent {
W WRNexusJS - +
-
navigation component

Pagination

Theme-aware, responsive pagination component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Pagination
+      
navigation component

Pagination

Theme-aware, responsive pagination component.

@wrnexus/ui 0.5.07 props1 slots3 events

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

PropTypeRequirementDefault
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 {
+/>

Legacy mount name: data-component="Pagination".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
labelstringOptional"Pagination"
itemsstringOptional[]
activestringOptional""
orientationstringOptional"horizontal"
classstringOptional""

Slots

  • default

Events

  • change
  • previous
  • next

Source contract

Installed source: components/Pagination.wrn

component Pagination {
   props {
+    @event change = function
+    @event previous = function
+    @event next = function
     size = "default"
     color = "primary"
     label = "Pagination"
@@ -37,7 +40,7 @@ page Paginationcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/pin-input.wrn b/app/pages/components/pin-input.wrn index a4432098..d47db663 100644 --- a/app/pages/components/pin-input.wrn +++ b/app/pages/components/pin-input.wrn @@ -10,10 +10,10 @@ page PinInputcomponent {
W WRNexusJS - +
-
advanced-forms component

PinInput

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

@wrnexus/ui 0.4.026 props0 slots6 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<PinInput
+      
advanced-forms component

PinInput

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

@wrnexus/ui 0.5.026 props0 slots6 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<PinInput
   size="default"
   color="primary"
   label="Verification code"
@@ -133,7 +133,7 @@ page PinInputcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/popover.wrn b/app/pages/components/popover.wrn index 70fa9f09..e1840b8b 100644 --- a/app/pages/components/popover.wrn +++ b/app/pages/components/popover.wrn @@ -10,17 +10,19 @@ page Popovercomponent {
W WRNexusJS - +
-
overlays component

Popover

Theme-aware, responsive popover component.

@wrnexus/ui 0.4.08 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Popover
+      
overlays component

Popover

Theme-aware, responsive popover component.

@wrnexus/ui 0.5.08 props1 slots2 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Popover
   size="default"
   color="primary"
   title="Popover"
   description="description"
   open="false"
-/>

Legacy mount name: data-component="Popover".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
titlestringOptional"Popover"
descriptionstringOptional""
openbooleanOptionalfalse
placementstringOptional"bottom"
closeLabelstringOptional"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

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
titlestringOptional"Popover"
descriptionstringOptional""
openbooleanOptionalfalse
placementstringOptional"bottom"
closeLabelstringOptional"Close"
classstringOptional""

Slots

  • default

Events

  • open
  • close

Source contract

Installed source: components/Popover.wrn

component Popover {
   props {
+    @event open = function
+    @event close = function
     size = "default"
     color = "primary"
     title = "Popover"
@@ -42,7 +44,7 @@ page Popovercomponent {
     }
 }
 
- + } diff --git a/app/pages/components/progress.wrn b/app/pages/components/progress.wrn index 6dfca1a4..876fa168 100644 --- a/app/pages/components/progress.wrn +++ b/app/pages/components/progress.wrn @@ -10,10 +10,10 @@ page Progresscomponent {
W WRNexusJS - +
-
base component

Progress

Theme-aware, responsive progress component.

@wrnexus/ui 0.4.07 props0 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Progress
+      
base component

Progress

Theme-aware, responsive progress component.

@wrnexus/ui 0.5.07 props0 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Progress
   size="default"
   color="primary"
   label="Progress"
@@ -39,7 +39,7 @@ page Progresscomponent {
     }
 }
 
- + } diff --git a/app/pages/components/radio.wrn b/app/pages/components/radio.wrn index 90904e4d..09ce69fe 100644 --- a/app/pages/components/radio.wrn +++ b/app/pages/components/radio.wrn @@ -10,35 +10,77 @@ page Radiocomponent {
W WRNexusJS - +
-
forms component

Radio

Theme-aware, responsive radio component.

@wrnexus/ui 0.4.08 props0 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Radio
+      
forms component

Radio

Theme-aware, responsive radio component.

@wrnexus/ui 0.5.025 props0 slots5 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Radio
   size="default"
   color="primary"
-  label="Radio"
+  id="id"
   name="name"
-  value="on"
-/>

Legacy mount name: data-component="Radio".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
labelstringOptional"Radio"
namestringOptional""
valuestringOptional"on"
checkedbooleanOptionalfalse
disabledbooleanOptionalfalse
classstringOptional""

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 {
+  label="Radio"
+/>

Legacy mount name: data-component="Radio".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
idstringOptional""
namestringOptional""
labelstringOptional"Radio"
hiddenLabelbooleanOptionalfalse
placeholderstringOptional""
variantstringOptional"normal"
iconstringOptional""
iconPositionstringOptional"start"
valuestringOptional"on"
optionsstringOptional[]
checkedbooleanOptionalfalse
orientationstringOptional"vertical"
cardbooleanOptionalfalse
rightAlignedbooleanOptionalfalse
listbooleanOptionalfalse
helperTextstringOptional""
cornerHintstringOptional""
errorstringOptional""
inlinebooleanOptionalfalse
readonlybooleanOptionalfalse
disabledbooleanOptionalfalse
requiredbooleanOptionalfalse
classstringOptional""

Slots

This component does not declare a slot.

Events

  • input
  • change
  • focus
  • blur
  • invalid

Source contract

Installed source: components/Radio.wrn

component Radio {
   props {
+    @event input = function
+    @event change = function
+    @event focus = function
+    @event blur = function
+    @event invalid = function
     size = "default"
     color = "primary"
-    label = "Radio"
+    id = ""
     name = ""
+    label = "Radio"
+    hiddenLabel = false
+    placeholder = ""
+    variant = "normal"
+    icon = ""
+    iconPosition = "start"
     value = "on"
+    options = []
     checked = false
+    orientation = "vertical"
+    card = false
+    rightAligned = false
+    list = false
+    helperText = ""
+    cornerHint = ""
+    error = ""
+    inline = false
+    readonly = false
     disabled = false
+    required = false
     class = ""
   }
+  functions {
+    function emitField(nameEvent, sourceEvent) { sourceEvent.stopPropagation(); $emit(nameEvent, { checked: sourceEvent.currentTarget.checked, value: sourceEvent.currentTarget.value, name: name, sourceEvent: sourceEvent }) }
+    function preventReadonly(sourceEvent) { if (readonly) sourceEvent.preventDefault() }
+  }
   view {
-        <label class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--choice wire-next--radio {class}">
-        <input {...attrs} type="radio" name="{name}" value="{value}" checked="{checked}" disabled="{disabled}" />
-        <span>{label}</span>
+        <div {...attrs} class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--choice-field wire-next--radio-field {class}" data-inline="{inline}" data-invalid="{error ? 'true' : 'false'}" data-orientation="{orientation}" data-card="{card}" data-list="{list}" data-right-aligned="{rightAligned}">
+        <div class="wire-next__field-heading">{#if options.length || cornerHint}<span class="{hiddenLabel ? 'wire-next__sr-only' : ''}">{label}</span>{#if cornerHint}<span class="wire-next__field-hint">{cornerHint}</span>{/if}{/if}</div>
+      {#if options.length}
+        <div class="wire-next__radio-group" role="radiogroup" aria-label="{hiddenLabel ? label : ''}" aria-invalid="{error ? 'true' : 'false'}">
+          {#each options as option}
+            <label class="wire-next__choice wire-next--radio" for="{id || name}-{option.value}" data-variant="{variant}" data-disabled="{disabled || option.disabled}">
+        <input id="{id || name}-{option.value}" type="radio" name="{name}" value="{option.value}" checked="{option.value === value || option.checked}" disabled="{disabled || option.disabled}" required="{required}" readonly="{readonly}" @click="preventReadonly(event)" @input="emitField('input', event)" @change="emitField('change', event)" @focus="emitField('focus', event)" @blur="emitField('blur', event)" @invalid="emitField('invalid', event)" />
+        <span class="wire-next__choice-copy">
+        <strong>{option.label}</strong>{#if option.description}<small>{option.description}</small>{/if}</span>
         </label>
+          {/each}
+        </div>
+      {:else}
+        <label class="wire-next__choice wire-next--radio" for="{id || name}" data-variant="{variant}" data-icon-position="{iconPosition}">
+        <input id="{id || name}" type="radio" name="{name}" value="{value}" checked="{checked}" disabled="{disabled}" required="{required}" readonly="{readonly}" aria-invalid="{error ? 'true' : 'false'}" @click="preventReadonly(event)" @input="emitField('input', event)" @change="emitField('change', event)" @focus="emitField('focus', event)" @blur="emitField('blur', event)" @invalid="emitField('invalid', event)" />{#if icon}<span class="{icon}" aria-hidden="true">
+        </span>{/if}<span class="{hiddenLabel || cornerHint ? 'wire-next__sr-only' : ''}">{label}</span>
+        </label>
+      {/if}
+      {#if helperText}<small class="wire-next__field-help">{helperText}</small>{/if}<small class="wire-next__field-error" data-error="{name}">{error}</small>
+        </div>
     }
 }
 
- + } diff --git a/app/pages/components/range-slider.wrn b/app/pages/components/range-slider.wrn index 19852abd..bd207a96 100644 --- a/app/pages/components/range-slider.wrn +++ b/app/pages/components/range-slider.wrn @@ -10,40 +10,95 @@ page RangeSlidercomponent {
W WRNexusJS - +
-
forms component

RangeSlider

Theme-aware, responsive range slider component.

@wrnexus/ui 0.4.013 props0 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<RangeSlider
+      
forms component

RangeSlider

Theme-aware, responsive range slider component.

@wrnexus/ui 0.5.026 props0 slots4 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<RangeSlider
   size="default"
   color="primary"
-  label="Range Slider"
+  id="id"
   name="name"
-  value="value"
-/>

Legacy mount name: data-component="RangeSlider".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
labelstringOptional"Range Slider"
namestringOptional""
valuestringOptional""
placeholderstringOptional""
typestringOptional"range"
minstringOptional""
maxstringOptional""
stepstringOptional""
disabledbooleanOptionalfalse
requiredbooleanOptionalfalse
classstringOptional""

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 {
+  label="Range"
+/>

Legacy mount name: data-component="RangeSlider".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
idstringOptional""
namestringOptional""
labelstringOptional"Range"
hiddenLabelbooleanOptionalfalse
placeholderstringOptional""
variantstringOptional"normal"
iconstringOptional""
iconPositionstringOptional"start"
valuenumberOptional50
minnumberOptional0
maxnumberOptional100
stepnumberOptional1
showValuebooleanOptionaltrue
showBoundsbooleanOptionaltrue
showStepsbooleanOptionalfalse
marksstringOptional[]
helperTextstringOptional""
cornerHintstringOptional""
errorstringOptional""
inlinebooleanOptionalfalse
readonlybooleanOptionalfalse
disabledbooleanOptionalfalse
requiredbooleanOptionalfalse
classstringOptional""

Slots

This component does not declare a slot.

Events

  • input
  • change
  • focus
  • blur

Source contract

Installed source: components/RangeSlider.wrn

component RangeSlider {
   props {
+    @event input = function
+    @event change = function
+    @event focus = function
+    @event blur = function
     size = "default"
     color = "primary"
-    label = "Range Slider"
+    id = ""
     name = ""
-    value = ""
+    label = "Range"
+    hiddenLabel = false
     placeholder = ""
-    type = "range"
-    min = ""
-    max = ""
-    step = ""
+    variant = "normal"
+    icon = ""
+    iconPosition = "start"
+    value = 50
+    min = 0
+    max = 100
+    step = 1
+    showValue = true
+    showBounds = true
+    showSteps = false
+    marks = []
+    helperText = ""
+    cornerHint = ""
+    error = ""
+    inline = false
+    readonly = false
     disabled = false
     required = false
     class = ""
   }
+  state currentValue = value
+  functions {
+    function percent() { if (Number(max) === Number(min)) { return 0 } return (Number(currentValue) - Number(min)) / (Number(max) - Number(min)) * 100 }
+    function setValue(nextValue, sourceEvent, commit, detail, root, slider, input, output, progressValue) { if (readonly || disabled) { return } currentValue = Number(nextValue); root = sourceEvent.currentTarget.closest(".wire-next--range-slider"); if (root) { slider = root.querySelector("[role=slider]"); input = root.querySelector("input[name='" + name + "']"); output = root.querySelector("output"); progressValue = (currentValue - Number(min)) / (Number(max) - Number(min)) * 100; if (slider) { slider.setAttribute("aria-valuenow", String(currentValue)); slider.style.setProperty("--wire-range-progress", progressValue + "%") } if (input) { input.value = String(currentValue) } if (output) { output.textContent = String(currentValue) } } detail = { value: currentValue, min: min, max: max, step: step, name: name, sourceEvent: sourceEvent }; $emit("input", detail); if (commit) { $emit("change", detail) } }
+    function valueFromPointer(sourceEvent, rect, ratio) { rect = sourceEvent.currentTarget.getBoundingClientRect(); ratio = Math.max(0, Math.min(1, (sourceEvent.clientX - rect.left) / rect.width)); return Number(min) + ratio * (Number(max) - Number(min)) }
+    function beginSlide(sourceEvent, rect, ratio, rawValue) { if (readonly || disabled) { return } sourceEvent.currentTarget.setPointerCapture(sourceEvent.pointerId); rect = sourceEvent.currentTarget.getBoundingClientRect(); ratio = Math.max(0, Math.min(1, (sourceEvent.clientX - rect.left) / rect.width)); rawValue = Number(min) + ratio * (Number(max) - Number(min)); currentValue = Number(min) + Math.round((rawValue - Number(min)) / Number(step)) * Number(step); $emit("input", { value: currentValue, name: name, sourceEvent: sourceEvent }) }
+    function moveSlide(sourceEvent, rect, ratio, rawValue) { if (!sourceEvent.currentTarget.hasPointerCapture(sourceEvent.pointerId)) { return } rect = sourceEvent.currentTarget.getBoundingClientRect(); ratio = Math.max(0, Math.min(1, (sourceEvent.clientX - rect.left) / rect.width)); rawValue = Number(min) + ratio * (Number(max) - Number(min)); currentValue = Number(min) + Math.round((rawValue - Number(min)) / Number(step)) * Number(step); $emit("input", { value: currentValue, name: name, sourceEvent: sourceEvent }) }
+    function endSlide(sourceEvent, rect, ratio, rawValue) { rect = sourceEvent.currentTarget.getBoundingClientRect(); ratio = Math.max(0, Math.min(1, (sourceEvent.clientX - rect.left) / rect.width)); rawValue = Number(min) + ratio * (Number(max) - Number(min)); currentValue = Number(min) + Math.round((rawValue - Number(min)) / Number(step)) * Number(step); if (sourceEvent.currentTarget.hasPointerCapture(sourceEvent.pointerId)) { sourceEvent.currentTarget.releasePointerCapture(sourceEvent.pointerId) } $emit("change", { value: currentValue, name: name, sourceEvent: sourceEvent }) }
+    function selectMark(sourceEvent, root, slider, input, output, nextValue, progressValue, detail) { if (readonly || disabled) { return } root = sourceEvent.currentTarget.closest(".wire-next--range-slider"); slider = root.querySelector(".wire-next__custom-slider"); input = root.querySelector(".wire-next__range-value"); output = root.querySelector("output"); nextValue = Number(sourceEvent.currentTarget.dataset.value); currentValue = nextValue; progressValue = (nextValue - Number(min)) / (Number(max) - Number(min)) * 100; slider.setAttribute("aria-valuenow", String(nextValue)); slider.style.setProperty("--wire-range-progress", progressValue + "%"); input.setAttribute("value", String(nextValue)); output.replaceChildren(String(nextValue)); detail = { value: nextValue, min: min, max: max, step: step, name: name, sourceEvent: sourceEvent }; $emit("input", detail); $emit("change", detail) }
+    function handleKey(sourceEvent) { if (sourceEvent.key === "ArrowRight") { sourceEvent.preventDefault(); currentValue = Math.min(Number(max), Number(currentValue) + Number(step)); $emit("input", { value: currentValue, name: name, sourceEvent: sourceEvent }); $emit("change", { value: currentValue, name: name, sourceEvent: sourceEvent }) } if (sourceEvent.key === "ArrowLeft") { sourceEvent.preventDefault(); currentValue = Math.max(Number(min), Number(currentValue) - Number(step)); $emit("input", { value: currentValue, name: name, sourceEvent: sourceEvent }); $emit("change", { value: currentValue, name: name, sourceEvent: sourceEvent }) } if (sourceEvent.key === "Home") { sourceEvent.preventDefault(); currentValue = Number(min); $emit("change", { value: currentValue, name: name, sourceEvent: sourceEvent }) } if (sourceEvent.key === "End") { sourceEvent.preventDefault(); currentValue = Number(max); $emit("change", { value: currentValue, name: name, sourceEvent: sourceEvent }) } }
+    function emitFocus(nameEvent, sourceEvent) { $emit(nameEvent, { value: currentValue, name: name, sourceEvent: sourceEvent }) }
+    function decreaseValue(sourceEvent) { currentValue = Math.max(Number(min), Number(currentValue) - Number(step)); $emit("input", { value: currentValue, name: name, sourceEvent: sourceEvent }); $emit("change", { value: currentValue, name: name, sourceEvent: sourceEvent }) }
+    function increaseValue(sourceEvent) { currentValue = Math.min(Number(max), Number(currentValue) + Number(step)); $emit("input", { value: currentValue, name: name, sourceEvent: sourceEvent }); $emit("change", { value: currentValue, name: name, sourceEvent: sourceEvent }) }
+  }
   view {
-        <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>
+        <div {...attrs} class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--field wire-next--range-slider {class}" data-variant="{variant}" data-inline="{inline}" data-invalid="{error ? 'true' : 'false'}">
+        <div class="wire-next__field-heading">
+        <label class="{hiddenLabel ? 'wire-next__sr-only' : ''}" for="{id || name}">{label}</label>{#if cornerHint}<span class="wire-next__field-hint">{cornerHint}</span>{/if}</div>
+        <div class="wire-next__range-control" data-variant="{variant}" data-icon-position="{iconPosition}" data-show-steps="{showSteps}">
+        {#if icon}<span class="{icon}" aria-hidden="true">
+        </span>{/if}
+        <button type="button" class="wire-next__range-stepper" aria-label="Decrease {label}" disabled="{disabled || readonly}" @click="decreaseValue(event)">−</button>
+        <div class="wire-next__range-track">
+        <input id="{id || name}" class="wire-next__sr-only wire-next__range-value" type="number" name="{name}" value="{currentValue}" min="{min}" max="{max}" step="{step}" required="{required}" readonly />
+        <div class="wire-next__custom-slider" role="slider" tabindex="{disabled ? '-1' : '0'}" aria-label="{hiddenLabel ? label : ''}" aria-valuemin="{min}" aria-valuemax="{max}" aria-valuenow="{currentValue}" aria-disabled="{disabled}" aria-readonly="{readonly}" aria-invalid="{error ? 'true' : 'false'}" style="--wire-range-progress: {percent()}%" @pointerdown="beginSlide(event)" @pointermove="moveSlide(event)" @pointerup="endSlide(event)" @pointercancel="endSlide(event)" @keydown="handleKey(event)" @focus="emitFocus('focus', event)" @blur="emitFocus('blur', event)">
+        <span class="wire-next__slider-fill">
+        </span>
+        <span class="wire-next__slider-thumb">
+        </span>
+            {#if marks.length}<span class="wire-next__slider-marks">{#each marks as mark}<button type="button" data-value="{mark.value}" style="left: {(Number(mark.value) - Number(min)) / (Number(max) - Number(min)) * 100}%" aria-label="{mark.label}" @click="selectMark(event)">
+        </button>{/each}</span>{/if}
+          </div>
+          {#if showBounds}<div class="wire-next__range-bounds">
+        <span>{min}</span>
+        <span>Step {step}</span>
+        <span>{max}</span>
+        </div>{/if}
+        </div>
+        {#if showValue}<output for="{id || name}">{currentValue}</output>{/if}
+        <button type="button" class="wire-next__range-stepper" aria-label="Increase {label}" disabled="{disabled || readonly}" @click="increaseValue(event)">+</button>
+        </div>
+      {#if helperText}<small class="wire-next__field-help">{helperText}</small>{/if}<small class="wire-next__field-error" data-error="{name}">{error}</small>
+        </div>
     }
 }
 
- + } diff --git a/app/pages/components/rating.wrn b/app/pages/components/rating.wrn index 12fc0922..2d456e6c 100644 --- a/app/pages/components/rating.wrn +++ b/app/pages/components/rating.wrn @@ -10,17 +10,19 @@ page Ratingcomponent {
W WRNexusJS - +
-
base component

Rating

Theme-aware, responsive rating component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Rating
+      
base component

Rating

Theme-aware, responsive rating component.

@wrnexus/ui 0.5.07 props1 slots2 events

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

PropTypeRequirementDefault
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 {
+/>

Legacy mount name: data-component="Rating".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
titlestringOptional"Rating"
descriptionstringOptional""
itemsstringOptional[]
variantstringOptional"default"
classstringOptional""

Slots

  • default

Events

  • input
  • change

Source contract

Installed source: components/Rating.wrn

component Rating {
   props {
+    @event input = function
+    @event change = function
     size = "default"
     color = "primary"
     title = "Rating"
@@ -39,7 +41,7 @@ page Ratingcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/scrollspy.wrn b/app/pages/components/scrollspy.wrn index 9e6fa28d..d3ac3f35 100644 --- a/app/pages/components/scrollspy.wrn +++ b/app/pages/components/scrollspy.wrn @@ -10,17 +10,18 @@ page Scrollspycomponent {
W WRNexusJS - +
-
navigation component

Scrollspy

Theme-aware, responsive scrollspy component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Scrollspy
+      
navigation component

Scrollspy

Theme-aware, responsive scrollspy component.

@wrnexus/ui 0.5.07 props1 slots1 events

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

PropTypeRequirementDefault
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 {
+/>

Legacy mount name: data-component="Scrollspy".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
labelstringOptional"Scrollspy"
itemsstringOptional[]
activestringOptional""
orientationstringOptional"horizontal"
classstringOptional""

Slots

  • default

Events

  • change

Source contract

Installed source: components/Scrollspy.wrn

component Scrollspy {
   props {
+    @event change = function
     size = "default"
     color = "primary"
     label = "Scrollspy"
@@ -37,7 +38,7 @@ page Scrollspycomponent {
     }
 }
 
- + } diff --git a/app/pages/components/search-box.wrn b/app/pages/components/search-box.wrn index 876a46f8..ecb2f1c4 100644 --- a/app/pages/components/search-box.wrn +++ b/app/pages/components/search-box.wrn @@ -10,17 +10,22 @@ page SearchBoxcomponent {
W WRNexusJS - +
-
advanced-forms component

SearchBox

Theme-aware, responsive search box component.

@wrnexus/ui 0.4.013 props0 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<SearchBox
+      
advanced-forms component

SearchBox

Theme-aware, responsive search box component.

@wrnexus/ui 0.5.013 props0 slots5 events

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

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
labelstringOptional"Search Box"
namestringOptional""
valuestringOptional""
placeholderstringOptional""
typestringOptional"search"
minstringOptional""
maxstringOptional""
stepstringOptional""
disabledbooleanOptionalfalse
requiredbooleanOptionalfalse
classstringOptional""

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 {
+/>

Legacy mount name: data-component="SearchBox".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
labelstringOptional"Search Box"
namestringOptional""
valuestringOptional""
placeholderstringOptional""
typestringOptional"search"
minstringOptional""
maxstringOptional""
stepstringOptional""
disabledbooleanOptionalfalse
requiredbooleanOptionalfalse
classstringOptional""

Slots

This component does not declare a slot.

Events

  • input
  • change
  • search
  • submit
  • clear

Source contract

Installed source: components/SearchBox.wrn

component SearchBox {
   props {
+    @event input = function
+    @event change = function
+    @event search = function
+    @event submit = function
+    @event clear = function
     size = "default"
     color = "primary"
     label = "Search Box"
@@ -43,7 +48,7 @@ page SearchBoxcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/select.wrn b/app/pages/components/select.wrn index 80f2cb92..699c0a87 100644 --- a/app/pages/components/select.wrn +++ b/app/pages/components/select.wrn @@ -10,38 +10,80 @@ page Selectcomponent {
W WRNexusJS - +
-
forms component

Select

Theme-aware, responsive select component.

@wrnexus/ui 0.4.010 props0 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Select
+      
forms component

Select

Theme-aware, responsive select component.

@wrnexus/ui 0.5.022 props0 slots7 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Select
   size="default"
   color="primary"
-  label="Select"
+  id="id"
   name="name"
-  value="value"
-/>

Legacy mount name: data-component="Select".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
labelstringOptional"Select"
namestringOptional""
valuestringOptional""
optionsstringOptional[]
placeholderstringOptional"Select an option"
multiplebooleanOptionalfalse
disabledbooleanOptionalfalse
classstringOptional""

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 {
+  label="Select"
+/>

Legacy mount name: data-component="Select".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
idstringOptional""
namestringOptional""
labelstringOptional"Select"
hiddenLabelbooleanOptionalfalse
valuestringOptional""
valuesstringOptional[]
optionsstringOptional[]
placeholderstringOptional"Select an option"
variantstringOptional"normal"
iconstringOptional""
iconPositionstringOptional"start"
helperTextstringOptional""
cornerHintstringOptional""
errorstringOptional""
inlinebooleanOptionalfalse
multiplebooleanOptionalfalse
readonlybooleanOptionalfalse
disabledbooleanOptionalfalse
requiredbooleanOptionalfalse
classstringOptional""

Slots

This component does not declare a slot.

Events

  • input
  • change
  • focus
  • blur
  • open
  • close
  • invalid

Source contract

Installed source: components/Select.wrn

component Select {
   props {
+    @event input = function
+    @event change = function
+    @event focus = function
+    @event blur = function
+    @event open = function
+    @event close = function
+    @event invalid = function
     size = "default"
     color = "primary"
-    label = "Select"
+    id = ""
     name = ""
+    label = "Select"
+    hiddenLabel = false
     value = ""
+    values = []
     options = []
     placeholder = "Select an option"
+    variant = "normal"
+    icon = ""
+    iconPosition = "start"
+    helperText = ""
+    cornerHint = ""
+    error = ""
+    inline = false
     multiple = false
+    readonly = false
     disabled = false
+    required = false
     class = ""
   }
+  functions {
+    function selected(option) {
+      if (multiple) return values.includes(option.value)
+      return option.value === value
+    }
+    function emitField(nameEvent, sourceEvent) {
+      sourceEvent.stopPropagation()
+      $emit(nameEvent, { value: sourceEvent.currentTarget.value, name: name, sourceEvent: sourceEvent })
+    }
+    function handleFocus(sourceEvent) { emitField("focus", sourceEvent); $emit("open", { name: name, sourceEvent: sourceEvent }) }
+    function handleBlur(sourceEvent) { emitField("blur", sourceEvent); $emit("close", { name: name, sourceEvent: sourceEvent }) }
+    function handleInvalid(sourceEvent) { $emit("invalid", { name: name, message: sourceEvent.currentTarget.validationMessage, sourceEvent: sourceEvent }) }
+  }
   view {
-        <label class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--field wire-next--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>
+        <div {...attrs} class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--field wire-next--select {class}" data-variant="{variant}" data-inline="{inline}" data-floating="{variant === 'floating'}" data-invalid="{error ? 'true' : 'false'}" data-readonly="{readonly}">
+        <div class="wire-next__field-heading">
+        <label class="{hiddenLabel ? 'wire-next__sr-only' : ''}" for="{id || name}">{label}</label>{#if cornerHint}<span class="wire-next__field-hint">{cornerHint}</span>{/if}</div>
+        <div class="wire-next__field-control" data-icon-position="{iconPosition}">
+        {#if icon}<span class="{icon} wire-next__field-icon" aria-hidden="true">
+        </span>{/if}
+        <select id="{id || name}" name="{name}" multiple="{multiple}" disabled="{disabled || readonly}" required="{required}" aria-readonly="{readonly}" aria-invalid="{error ? 'true' : 'false'}" @input="emitField('input', event)" @change="emitField('change', event)" @focus="handleFocus(event)" @blur="handleBlur(event)" @invalid="handleInvalid(event)">
+          {#if !multiple}<option value="" selected="{value === ''}" disabled="{required}">{placeholder}</option>{/if}
+          {#each options as option}<option value="{option.value}" selected="{selected(option)}" disabled="{option.disabled}">{option.label}</option>{/each}
+        </select>
+        {#if variant === "floating"}<span class="wire-next__field-floating-label">{label}</span>{/if}
+      </div>
+      {#if helperText}<small class="wire-next__field-help">{helperText}</small>{/if}
+      <small class="wire-next__field-error" data-error="{name}">{error}</small>
+        </div>
     }
 }
 
- + } diff --git a/app/pages/components/sidebar.wrn b/app/pages/components/sidebar.wrn index da14d575..737615fa 100644 --- a/app/pages/components/sidebar.wrn +++ b/app/pages/components/sidebar.wrn @@ -10,17 +10,20 @@ page Sidebarcomponent {
W WRNexusJS - +
-
navigation component

Sidebar

Theme-aware, responsive sidebar component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Sidebar
+      
navigation component

Sidebar

Theme-aware, responsive sidebar component.

@wrnexus/ui 0.5.07 props1 slots3 events

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

PropTypeRequirementDefault
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 {
+/>

Legacy mount name: data-component="Sidebar".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
labelstringOptional"Sidebar"
itemsstringOptional[]
activestringOptional""
orientationstringOptional"horizontal"
classstringOptional""

Slots

  • default

Events

  • toggle
  • open
  • close

Source contract

Installed source: components/Sidebar.wrn

component Sidebar {
   props {
+    @event toggle = function
+    @event open = function
+    @event close = function
     size = "default"
     color = "primary"
     label = "Sidebar"
@@ -37,7 +40,7 @@ page Sidebarcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/skeleton.wrn b/app/pages/components/skeleton.wrn index 058a742f..cbb1feb3 100644 --- a/app/pages/components/skeleton.wrn +++ b/app/pages/components/skeleton.wrn @@ -10,10 +10,10 @@ page Skeletoncomponent {
W WRNexusJS - +
-
base component

Skeleton

Theme-aware, responsive skeleton component.

@wrnexus/ui 0.4.05 props0 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Skeleton
+      
base component

Skeleton

Theme-aware, responsive skeleton component.

@wrnexus/ui 0.5.05 props0 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Skeleton
   color="primary"
   label="Loading"
   size="md"
@@ -35,7 +35,7 @@ page Skeletoncomponent {
     }
 }
 
- + } diff --git a/app/pages/components/spinner.wrn b/app/pages/components/spinner.wrn index f81843e2..b11b7b19 100644 --- a/app/pages/components/spinner.wrn +++ b/app/pages/components/spinner.wrn @@ -10,10 +10,10 @@ page Spinnercomponent {
W WRNexusJS - +
-
base component

Spinner

Theme-aware, responsive spinner component.

@wrnexus/ui 0.4.05 props0 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Spinner
+      
base component

Spinner

Theme-aware, responsive spinner component.

@wrnexus/ui 0.5.05 props0 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Spinner
   color="primary"
   label="Loading"
   size="md"
@@ -35,7 +35,7 @@ page Spinnercomponent {
     }
 }
 
- + } diff --git a/app/pages/components/stepper.wrn b/app/pages/components/stepper.wrn index 7c738104..77a95e3b 100644 --- a/app/pages/components/stepper.wrn +++ b/app/pages/components/stepper.wrn @@ -10,17 +10,21 @@ page Steppercomponent {
W WRNexusJS - +
-
navigation component

Stepper

Theme-aware, responsive stepper component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Stepper
+      
navigation component

Stepper

Theme-aware, responsive stepper component.

@wrnexus/ui 0.5.07 props1 slots4 events

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

PropTypeRequirementDefault
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 {
+/>

Legacy mount name: data-component="Stepper".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
labelstringOptional"Stepper"
itemsstringOptional[]
activestringOptional""
orientationstringOptional"horizontal"
classstringOptional""

Slots

  • default

Events

  • change
  • previous
  • next
  • complete

Source contract

Installed source: components/Stepper.wrn

component Stepper {
   props {
+    @event change = function
+    @event previous = function
+    @event next = function
+    @event complete = function
     size = "default"
     color = "primary"
     label = "Stepper"
@@ -37,7 +41,7 @@ page Steppercomponent {
     }
 }
 
- + } diff --git a/app/pages/components/strong-password.wrn b/app/pages/components/strong-password.wrn index fcc54a01..9ceb2d41 100644 --- a/app/pages/components/strong-password.wrn +++ b/app/pages/components/strong-password.wrn @@ -10,10 +10,10 @@ page StrongPasswordcomponent {
W WRNexusJS - +
-
advanced-forms component

StrongPassword

Theme-aware, responsive strong password component.

@wrnexus/ui 0.4.027 props0 slots3 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<StrongPassword
+      
advanced-forms component

StrongPassword

Theme-aware, responsive strong password component.

@wrnexus/ui 0.5.027 props0 slots3 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<StrongPassword
   size="default"
   color="primary"
   label="Password"
@@ -257,7 +257,7 @@ page StrongPasswordcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/styled-icon.wrn b/app/pages/components/styled-icon.wrn index 731c3c26..1871c219 100644 --- a/app/pages/components/styled-icon.wrn +++ b/app/pages/components/styled-icon.wrn @@ -10,10 +10,10 @@ page StyledIconcomponent {
W WRNexusJS - +
-
base component

StyledIcon

Theme-aware, responsive styled icon component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<StyledIcon
+      
base component

StyledIcon

Theme-aware, responsive styled icon component.

@wrnexus/ui 0.5.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<StyledIcon
   size="default"
   color="primary"
   title="Styled Icon"
@@ -39,7 +39,7 @@ page StyledIconcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/switch.wrn b/app/pages/components/switch.wrn index 773e4a85..6654e949 100644 --- a/app/pages/components/switch.wrn +++ b/app/pages/components/switch.wrn @@ -10,35 +10,60 @@ page Switchcomponent {
W WRNexusJS - +
-
forms component

Switch

Theme-aware, responsive switch component.

@wrnexus/ui 0.4.08 props0 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Switch
+      
forms component

Switch

Theme-aware, responsive switch component.

@wrnexus/ui 0.5.020 props0 slots4 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Switch
   size="default"
   color="primary"
-  label="Switch"
+  id="id"
   name="name"
-  value="on"
-/>

Legacy mount name: data-component="Switch".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
labelstringOptional"Switch"
namestringOptional""
valuestringOptional"on"
checkedbooleanOptionalfalse
disabledbooleanOptionalfalse
classstringOptional""

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 {
+  label="Switch"
+/>

Legacy mount name: data-component="Switch".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
idstringOptional""
namestringOptional""
labelstringOptional"Switch"
hiddenLabelbooleanOptionalfalse
placeholderstringOptional""
variantstringOptional"normal"
iconstringOptional""
iconPositionstringOptional"start"
valuestringOptional"on"
checkedbooleanOptionalfalse
helperTextstringOptional""
cornerHintstringOptional""
errorstringOptional""
inlinebooleanOptionalfalse
readonlybooleanOptionalfalse
disabledbooleanOptionalfalse
requiredbooleanOptionalfalse
classstringOptional""

Slots

This component does not declare a slot.

Events

  • input
  • change
  • focus
  • blur

Source contract

Installed source: components/Switch.wrn

component Switch {
   props {
+    @event input = function
+    @event change = function
+    @event focus = function
+    @event blur = function
     size = "default"
     color = "primary"
-    label = "Switch"
+    id = ""
     name = ""
+    label = "Switch"
+    hiddenLabel = false
+    placeholder = ""
+    variant = "normal"
+    icon = ""
+    iconPosition = "start"
     value = "on"
     checked = false
+    helperText = ""
+    cornerHint = ""
+    error = ""
+    inline = false
+    readonly = false
     disabled = false
+    required = false
     class = ""
   }
+  functions {
+    function emitField(nameEvent, sourceEvent) { sourceEvent.stopPropagation(); $emit(nameEvent, { checked: sourceEvent.currentTarget.checked, value: value, name: name, sourceEvent: sourceEvent }) }
+    function preventReadonly(sourceEvent) { if (readonly) sourceEvent.preventDefault() }
+  }
   view {
-        <label class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--choice wire-next--switch {class}">
-        <input {...attrs} type="checkbox" name="{name}" value="{value}" checked="{checked}" disabled="{disabled}" />
-        <span>{label}</span>
+        <div {...attrs} class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--choice-field {class}" data-inline="{inline}" data-invalid="{error ? 'true' : 'false'}">
+        <div class="wire-next__field-heading">{#if cornerHint}<span class="{hiddenLabel ? 'wire-next__sr-only' : ''}">{label}</span>
+        <span class="wire-next__field-hint">{cornerHint}</span>{/if}</div>
+        <label class="wire-next__choice wire-next--switch" for="{id || name}" data-variant="{variant}" data-icon-position="{iconPosition}">
+        <input id="{id || name}" type="checkbox" role="switch" name="{name}" value="{value}" checked="{checked}" disabled="{disabled}" required="{required}" readonly="{readonly}" aria-checked="{checked ? 'true' : 'false'}" aria-invalid="{error ? 'true' : 'false'}" @click="preventReadonly(event)" @input="emitField('input', event)" @change="emitField('change', event)" @focus="emitField('focus', event)" @blur="emitField('blur', event)" />{#if icon}<span class="{icon}" aria-hidden="true">
+        </span>{/if}<span class="{hiddenLabel || cornerHint ? 'wire-next__sr-only' : ''}">{label}</span>
         </label>
+      {#if helperText}<small class="wire-next__field-help">{helperText}</small>{/if}<small class="wire-next__field-error" data-error="{name}">{error}</small>
+        </div>
     }
 }
 
- + } diff --git a/app/pages/components/table.wrn b/app/pages/components/table.wrn index d4777bc7..65335122 100644 --- a/app/pages/components/table.wrn +++ b/app/pages/components/table.wrn @@ -10,17 +10,20 @@ page Tablecomponent {
W WRNexusJS - +
-
tables component

Table

Theme-aware, responsive table component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Table
+      
tables component

Table

Theme-aware, responsive table component.

@wrnexus/ui 0.5.07 props1 slots3 events

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

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
captionstringOptional"Table"
columnsstringOptional[]
rowsstringOptional[]
stripedbooleanOptionaltrue
classstringOptional""

Slots

  • default

Events

This component does not declare a custom event.

Source contract

Installed source: components/table.wrn

component Table {
+/>

Legacy mount name: data-component="Table".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
captionstringOptional"Table"
columnsstringOptional[]
rowsstringOptional[]
stripedbooleanOptionaltrue
classstringOptional""

Slots

  • default

Events

  • sort
  • select
  • rowClick

Source contract

Installed source: components/table.wrn

component Table {
   props {
+    @event sort = function
+    @event select = function
+    @event rowClick = function
     size = "default"
     color = "primary"
     caption = "Table"
@@ -43,7 +46,7 @@ page Tablecomponent {
     }
 }
 
- + } diff --git a/app/pages/components/tabs.wrn b/app/pages/components/tabs.wrn index 49178ba2..66bb7f43 100644 --- a/app/pages/components/tabs.wrn +++ b/app/pages/components/tabs.wrn @@ -10,17 +10,19 @@ page Tabscomponent {
W WRNexusJS - +
-
navigation component

Tabs

Theme-aware, responsive tabs component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Tabs
+      
navigation component

Tabs

Theme-aware, responsive tabs component.

@wrnexus/ui 0.5.07 props1 slots2 events

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

PropTypeRequirementDefault
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 {
+/>

Legacy mount name: data-component="Tabs".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
labelstringOptional"Tabs"
itemsstringOptional[]
activestringOptional""
orientationstringOptional"horizontal"
classstringOptional""

Slots

  • default

Events

  • change
  • select

Source contract

Installed source: components/Tabs.wrn

component Tabs {
   props {
+    @event change = function
+    @event select = function
     size = "default"
     color = "primary"
     label = "Tabs"
@@ -37,7 +39,7 @@ page Tabscomponent {
     }
 }
 
- + } diff --git a/app/pages/components/textarea.wrn b/app/pages/components/textarea.wrn index 166a0aec..03ab5d5c 100644 --- a/app/pages/components/textarea.wrn +++ b/app/pages/components/textarea.wrn @@ -10,37 +10,72 @@ page Textareacomponent {
W WRNexusJS - +
-
forms component

Textarea

Theme-aware, responsive textarea component.

@wrnexus/ui 0.4.010 props0 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Textarea
+      
forms component

Textarea

Theme-aware, responsive textarea component.

@wrnexus/ui 0.5.023 props0 slots5 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Textarea
   size="default"
   color="primary"
-  label="Textarea"
+  id="id"
   name="name"
-  value="value"
-/>

Legacy mount name: data-component="Textarea".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
labelstringOptional"Textarea"
namestringOptional""
valuestringOptional""
placeholderstringOptional""
rowsnumberOptional5
disabledbooleanOptionalfalse
requiredbooleanOptionalfalse
classstringOptional""

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 {
+  label="Textarea"
+/>

Legacy mount name: data-component="Textarea".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
idstringOptional""
namestringOptional""
labelstringOptional"Textarea"
hiddenLabelbooleanOptionalfalse
placeholderstringOptional""
valuestringOptional""
variantstringOptional"normal"
iconstringOptional""
iconPositionstringOptional"start"
helperTextstringOptional""
cornerHintstringOptional""
errorstringOptional""
inlinebooleanOptionalfalse
rowsnumberOptional5
resizestringOptional"vertical"
readonlybooleanOptionalfalse
disabledbooleanOptionalfalse
requiredbooleanOptionalfalse
minlengthstringOptional""
maxlengthstringOptional""
classstringOptional""

Slots

This component does not declare a slot.

Events

  • input
  • change
  • focus
  • blur
  • invalid

Source contract

Installed source: components/Textarea.wrn

component Textarea {
   props {
+    @event input = function
+    @event change = function
+    @event focus = function
+    @event blur = function
+    @event invalid = function
     size = "default"
     color = "primary"
-    label = "Textarea"
+    id = ""
     name = ""
-    value = ""
+    label = "Textarea"
+    hiddenLabel = false
     placeholder = ""
+    value = ""
+    variant = "normal"
+    icon = ""
+    iconPosition = "start"
+    helperText = ""
+    cornerHint = ""
+    error = ""
+    inline = false
     rows = 5
+    resize = "vertical"
+    readonly = false
     disabled = false
     required = false
+    minlength = ""
+    maxlength = ""
     class = ""
   }
+  functions {
+    function emitField(nameEvent, sourceEvent) {
+      sourceEvent.stopPropagation()
+      $emit(nameEvent, { value: sourceEvent.currentTarget.value, name: name, sourceEvent: sourceEvent })
+    }
+    function handleInvalid(sourceEvent) {
+      $emit("invalid", { value: sourceEvent.currentTarget.value, name: name, message: sourceEvent.currentTarget.validationMessage, sourceEvent: sourceEvent })
+    }
+  }
   view {
-        <label class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--field wire-next--textarea {class}">
-        <span>{label}</span>
-        <textarea {...attrs} name="{name}" placeholder="{placeholder}" rows="{rows}" disabled="{disabled}" required="{required}">{value}</textarea>
-        </label>
+        <div {...attrs} class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--field wire-next--textarea {class}" data-variant="{variant}" data-inline="{inline}" data-floating="{variant === 'floating'}" data-invalid="{error ? 'true' : 'false'}">
+        <div class="wire-next__field-heading">
+        <label class="{hiddenLabel ? 'wire-next__sr-only' : ''}" for="{id || name}">{label}</label>{#if cornerHint}<span class="wire-next__field-hint">{cornerHint}</span>{/if}</div>
+        <div class="wire-next__field-control" data-icon-position="{iconPosition}">
+        {#if icon}<span class="{icon} wire-next__field-icon" aria-hidden="true">
+        </span>{/if}
+        <textarea id="{id || name}" name="{name}" placeholder="{variant === 'floating' ? ' ' : placeholder}" rows="{rows}" style="resize: {resize}" readonly="{readonly}" disabled="{disabled}" required="{required}" minlength="{minlength}" maxlength="{maxlength}" aria-invalid="{error ? 'true' : 'false'}" aria-describedby="{error ? (id || name) + '-error' : (helperText ? (id || name) + '-help' : '')}" @input="emitField('input', event)" @change="emitField('change', event)" @focus="emitField('focus', event)" @blur="emitField('blur', event)" @invalid="handleInvalid(event)">{value}</textarea>
+        {#if variant === "floating"}<span class="wire-next__field-floating-label">{label}</span>{/if}
+      </div>
+      {#if helperText}<small id="{(id || name) + '-help'}" class="wire-next__field-help">{helperText}</small>{/if}
+      <small id="{(id || name) + '-error'}" class="wire-next__field-error" data-error="{name}">{error}</small>
+        </div>
     }
 }
 
- + } diff --git a/app/pages/components/time-picker.wrn b/app/pages/components/time-picker.wrn index 8244e7e1..76fbaf71 100644 --- a/app/pages/components/time-picker.wrn +++ b/app/pages/components/time-picker.wrn @@ -10,40 +10,96 @@ page TimePickercomponent {
W WRNexusJS - +
-
forms component

TimePicker

Theme-aware, responsive time picker component.

@wrnexus/ui 0.4.013 props0 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<TimePicker
+      
forms component

TimePicker

Theme-aware, responsive time picker component.

@wrnexus/ui 0.5.026 props0 slots7 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<TimePicker
   size="default"
   color="primary"
-  label="Time Picker"
+  id="id"
   name="name"
-  value="value"
-/>

Legacy mount name: data-component="TimePicker".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
labelstringOptional"Time Picker"
namestringOptional""
valuestringOptional""
placeholderstringOptional""
typestringOptional"time"
minstringOptional""
maxstringOptional""
stepstringOptional""
disabledbooleanOptionalfalse
requiredbooleanOptionalfalse
classstringOptional""

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 {
+  label="Time"
+/>

Legacy mount name: data-component="TimePicker".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
idstringOptional""
namestringOptional""
labelstringOptional"Time"
hiddenLabelbooleanOptionalfalse
valuestringOptional""
placeholderstringOptional""
variantstringOptional"normal"
iconstringOptional"icon-[lucide--clock-3]"
iconPositionstringOptional"end"
helperTextstringOptional""
cornerHintstringOptional""
errorstringOptional""
inlinebooleanOptionalfalse
minstringOptional""
maxstringOptional""
stepstringOptional""
formatstringOptional"24"
minuteStepnumberOptional5
hoursstringOptional["00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23"]
minutesstringOptional["00", "05", "10", "15", "20", "25", "30", "35", "40", "45", "50", "55"]
readonlybooleanOptionalfalse
disabledbooleanOptionalfalse
requiredbooleanOptionalfalse
classstringOptional""

Slots

This component does not declare a slot.

Events

  • input
  • change
  • focus
  • blur
  • open
  • close
  • invalid

Source contract

Installed source: components/TimePicker.wrn

component TimePicker {
   props {
+    @event input = function
+    @event change = function
+    @event focus = function
+    @event blur = function
+    @event open = function
+    @event close = function
+    @event invalid = function
     size = "default"
     color = "primary"
-    label = "Time Picker"
+    id = ""
     name = ""
+    label = "Time"
+    hiddenLabel = false
     value = ""
     placeholder = ""
-    type = "time"
+    variant = "normal"
+    icon = "icon-[lucide--clock-3]"
+    iconPosition = "end"
+    helperText = ""
+    cornerHint = ""
+    error = ""
+    inline = false
     min = ""
     max = ""
     step = ""
+    format = "24"
+    minuteStep = 5
+    hours = ["00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23"]
+    minutes = ["00", "05", "10", "15", "20", "25", "30", "35", "40", "45", "50", "55"]
+    readonly = false
     disabled = false
     required = false
     class = ""
   }
+  state currentValue = value
+  state selectedHour = value ? value.split(":")[0] : "00"
+  state selectedMinute = value ? value.split(":")[1] : "00"
+  state expanded = false
+  functions {
+    function commit(part, nextValue, sourceEvent, next, detail) { if (part === "hour") { selectedHour = String(nextValue).padStart(2, "0") } if (part === "minute") { selectedMinute = String(nextValue).padStart(2, "0") } next = selectedHour + ":" + selectedMinute; if ((min && next < min) || (max && next > max)) { return } currentValue = next; detail = { value: currentValue, hour: selectedHour, minute: selectedMinute, name: name, sourceEvent: sourceEvent }; $emit("input", detail); $emit("change", detail) }
+    function selectTimePart(sourceEvent, root, input, parts, hourValue, minuteValue, next, trigger, detail) { root = sourceEvent.currentTarget.closest(".wire-next--time-picker"); input = root.querySelector(".wire-next__time-value"); parts = String(input.value || value || "00:00").split(":"); hourValue = sourceEvent.currentTarget.dataset.part === "hour" ? sourceEvent.currentTarget.dataset.value : parts[0]; minuteValue = sourceEvent.currentTarget.dataset.part === "minute" ? sourceEvent.currentTarget.dataset.value : parts[1]; next = hourValue + ":" + minuteValue; if ((min && next < min) || (max && next > max)) { return } currentValue = next; input.setAttribute("value", next); trigger = root.querySelector(".wire-next__time-trigger span"); if (trigger) { trigger.replaceChildren(next) } sourceEvent.currentTarget.setAttribute("aria-pressed", "true"); detail = { value: next, hour: hourValue, minute: minuteValue, name: name, sourceEvent: sourceEvent }; $emit("input", detail); $emit("change", detail) }
+    function openPicker(sourceEvent) { expanded = true; $emit("open", { value: currentValue, name: name, sourceEvent: sourceEvent }) }
+    function closePicker(sourceEvent) { expanded = false; $emit("close", { value: currentValue, name: name, sourceEvent: sourceEvent }) }
+    function handleFocus(sourceEvent) { $emit("focus", { value: currentValue, name: name, sourceEvent: sourceEvent }) }
+    function handleBlur(sourceEvent) { $emit("blur", { value: currentValue, name: name, sourceEvent: sourceEvent }) }
+    function handleInvalid(sourceEvent) { $emit("invalid", { name: name, message: sourceEvent.currentTarget.validationMessage, sourceEvent: sourceEvent }) }
+  }
   view {
-        <label class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--field wire-next--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>
+        <div {...attrs} class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--field wire-next--time-picker {class}" data-variant="{variant}" data-inline="{inline}" data-floating="{variant === 'floating'}" data-invalid="{error ? 'true' : 'false'}" data-expanded="{expanded}">
+        <div class="wire-next__field-heading">
+        <label class="{hiddenLabel ? 'wire-next__sr-only' : ''}" for="{id || name}">{label}</label>{#if cornerHint}<span class="wire-next__field-hint">{cornerHint}</span>{/if}</div>
+        <div class="wire-next__field-control" data-icon-position="{iconPosition}">
+        {#if icon}<span class="{icon} wire-next__field-icon" aria-hidden="true">
+        </span>{/if}
+        <input id="{id || name}" class="wire-next__sr-only wire-next__time-value" type="text" name="{name}" value="{currentValue}" required="{required}" readonly aria-hidden="true" tabindex="-1" @invalid="handleInvalid(event)" />
+        <button type="button" class="wire-next__time-trigger" disabled="{disabled || readonly}" aria-haspopup="dialog" aria-expanded="{expanded}" @click="openPicker(event)" @focus="handleFocus(event)" @blur="handleBlur(event)">
+        <span>{currentValue || placeholder || "Select time"}</span>
+        <i class="{icon}" aria-hidden="true">
+        </i>
+        </button>
+        </div>
+        <div class="wire-next__time-panel" role="dialog" aria-label="{label}">
+        <div>
+        <strong>Hour</strong>
+        <div class="wire-next__time-options">{#each hours as hour}<button type="button" data-part="hour" data-value="{hour}" aria-pressed="{String(hour) === selectedHour}" @click="selectTimePart(event)">{hour}</button>{/each}</div>
+        </div>
+        <div>
+        <strong>Minute</strong>
+        <div class="wire-next__time-options">{#each minutes as minute}<button type="button" data-part="minute" data-value="{minute}" aria-pressed="{String(minute) === selectedMinute}" @click="selectTimePart(event)">{minute}</button>{/each}</div>
+        </div>
+        <button type="button" class="wire-next__time-done" @click="closePicker(event)">Done</button>
+        </div>
+      {#if helperText}<small class="wire-next__field-help">{helperText}</small>{/if}
+      <small class="wire-next__field-error" data-error="{name}">{error}</small>
+        </div>
     }
 }
 
- + } diff --git a/app/pages/components/timeline.wrn b/app/pages/components/timeline.wrn index 1851bb7b..d5822c34 100644 --- a/app/pages/components/timeline.wrn +++ b/app/pages/components/timeline.wrn @@ -10,17 +10,18 @@ page Timelinecomponent {
W WRNexusJS - +
-
base component

Timeline

Theme-aware, responsive timeline component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Timeline
+      
base component

Timeline

Theme-aware, responsive timeline component.

@wrnexus/ui 0.5.07 props1 slots1 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Timeline
   size="default"
   color="primary"
   title="Timeline"
   description="description"
   items="[]"
-/>

Legacy mount name: data-component="Timeline".

Props and attributes

PropTypeRequirementDefault
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 {
+/>

Legacy mount name: data-component="Timeline".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
titlestringOptional"Timeline"
descriptionstringOptional""
itemsstringOptional[]
variantstringOptional"default"
classstringOptional""

Slots

  • default

Events

  • select

Source contract

Installed source: components/Timeline.wrn

component Timeline {
   props {
+    @event select = function
     size = "default"
     color = "primary"
     title = "Timeline"
@@ -39,7 +40,7 @@ page Timelinecomponent {
     }
 }
 
- + } diff --git a/app/pages/components/toast-notifications.wrn b/app/pages/components/toast-notifications.wrn index caa2e15f..08a62fc7 100644 --- a/app/pages/components/toast-notifications.wrn +++ b/app/pages/components/toast-notifications.wrn @@ -10,17 +10,21 @@ page ToastNotificationscomponent {
W WRNexusJS - +
-
integrations component

ToastNotifications

Theme-aware, responsive toast notifications component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<ToastNotifications
+      
integrations component

ToastNotifications

Theme-aware, responsive toast notifications component.

@wrnexus/ui 0.5.07 props1 slots4 events

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

PropTypeRequirementDefault
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 {
+/>

Legacy mount name: data-component="ToastNotifications".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
titlestringOptional"Toast Notifications"
descriptionstringOptional""
itemsstringOptional[]
variantstringOptional"default"
classstringOptional""

Slots

  • default

Events

  • add
  • dismiss
  • clear
  • action

Source contract

Installed source: components/ToastNotifications.wrn

component ToastNotifications {
   props {
+    @event add = function
+    @event dismiss = function
+    @event clear = function
+    @event action = function
     size = "default"
     color = "primary"
     title = "Toast Notifications"
@@ -39,7 +43,7 @@ page ToastNotificationscomponent {
     }
 }
 
- + } diff --git a/app/pages/components/toast.wrn b/app/pages/components/toast.wrn index 3258ddc4..ed8dacff 100644 --- a/app/pages/components/toast.wrn +++ b/app/pages/components/toast.wrn @@ -10,17 +10,19 @@ page Toastcomponent {
W WRNexusJS - +
-
base component

Toast

Theme-aware, responsive toast component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Toast
+      
base component

Toast

Theme-aware, responsive toast component.

@wrnexus/ui 0.5.07 props1 slots2 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Toast
   size="default"
   color="primary"
   title="Toast"
   description="description"
   items="[]"
-/>

Legacy mount name: data-component="Toast".

Props and attributes

PropTypeRequirementDefault
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 {
+/>

Legacy mount name: data-component="Toast".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
titlestringOptional"Toast"
descriptionstringOptional""
itemsstringOptional[]
variantstringOptional"default"
classstringOptional""

Slots

  • default

Events

  • dismiss
  • action

Source contract

Installed source: components/Toast.wrn

component Toast {
   props {
+    @event dismiss = function
+    @event action = function
     size = "default"
     color = "primary"
     title = "Toast"
@@ -39,7 +41,7 @@ page Toastcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/toggle-count.wrn b/app/pages/components/toggle-count.wrn index 9ba6563b..01a62584 100644 --- a/app/pages/components/toggle-count.wrn +++ b/app/pages/components/toggle-count.wrn @@ -10,40 +10,254 @@ page ToggleCountcomponent {
W WRNexusJS - +
-
advanced-forms component

ToggleCount

Theme-aware, responsive toggle count component.

@wrnexus/ui 0.4.013 props0 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<ToggleCount
+      
advanced-forms component

ToggleCount

Theme-aware, responsive toggle count component.

@wrnexus/ui 0.5.023 props0 slots2 events

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

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
labelstringOptional"Toggle Count"
namestringOptional""
valuestringOptional""
placeholderstringOptional""
typestringOptional"text"
minstringOptional""
maxstringOptional""
stepstringOptional""
disabledbooleanOptionalfalse
requiredbooleanOptionalfalse
classstringOptional""

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 {
+  variant="segmented"
+  name="billing-cycle"
+  value="monthly"
+/>

Legacy mount name: data-component="ToggleCount".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
variantstringOptional"segmented"
classstringOptional""
namestringOptional"billing-cycle"
valuestringOptional"monthly"
firstValuestringOptional"monthly"
firstLabelstringOptional"Monthly"
secondValuestringOptional"annual"
secondLabelstringOptional"Annual"
ariaLabelstringOptional"Billing frequency"
itemsstringOptional[]
currencystringOptional"$"
suffixstringOptional""
firstValueKeystringOptional"monthly"
secondValueKeystringOptional"annual"
emptyValuestringOptional"—"
alignstringOptional"end"
fullWidthbooleanOptionaltrue
disabledbooleanOptionalfalse
animatebooleanOptionaltrue
animationDurationnumberOptional450
animationStepsnumberOptional18

Slots

This component does not declare a slot.

Events

  • change
  • toggle

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
+    variant = "segmented"
     class = ""
+
+    name = "billing-cycle"
+    value = "monthly"
+    firstValue = "monthly"
+    firstLabel = "Monthly"
+    secondValue = "annual"
+    secondLabel = "Annual"
+    ariaLabel = "Billing frequency"
+
+    items = []
+    currency = "$"
+    suffix = ""
+    firstValueKey = "monthly"
+    secondValueKey = "annual"
+    emptyValue = "—"
+
+    align = "end"
+    fullWidth = true
+    disabled = false
+    animate = true
+    animationDuration = 450
+    animationSteps = 18
+
+    @event change = function
+    @event toggle = function
   }
+
+  state selectedValue = value
+
+  functions {
+    function isFirstSelected() {
+      return selectedValue === firstValue
+    }
+
+    function isSecondSelected() {
+      return selectedValue === secondValue
+    }
+
+    function displayValue(item) {
+      if (isSecondSelected()) {
+        return item[secondValueKey] !== undefined
+          ? item[secondValueKey]
+          : emptyValue
+      }
+
+      return item[firstValueKey] !== undefined
+        ? item[firstValueKey]
+        : emptyValue
+    }
+
+    function dispatchToggleEvent(sourceEvent, previousValue, root, customEvent) {
+      root = sourceEvent.currentTarget.closest("[data-wrn-toggle-count]")
+
+      if (!root) {
+        return
+      }
+
+      customEvent = document.createEvent("CustomEvent")
+      customEvent.initCustomEvent("change", true, false, {
+        component: "ToggleCount",
+        name: name,
+        value: selectedValue,
+        previousValue: previousValue,
+        firstValue: firstValue,
+        secondValue: secondValue
+      })
+      root.dispatchEvent(customEvent)
+
+      customEvent = document.createEvent("CustomEvent")
+      customEvent.initCustomEvent("toggle", true, false, {
+        component: "ToggleCount",
+        name: name,
+        value: selectedValue,
+        previousValue: previousValue,
+        firstValue: firstValue,
+        secondValue: secondValue
+      })
+      root.dispatchEvent(customEvent)
+    }
+
+    function selectValue(sourceEvent, nextValue, previousValue) {
+      if (disabled || selectedValue === nextValue) {
+        return
+      }
+
+      previousValue = selectedValue
+      selectedValue = nextValue
+
+      if (
+        animate &&
+        !window.matchMedia("(prefers-reduced-motion: reduce)").matches
+      ) {
+        animateDisplayedValues(sourceEvent, previousValue)
+      }
+
+      dispatchToggleEvent(sourceEvent, previousValue)
+    }
+
+    function animateDisplayedValues(sourceEvent, previousValue, root, nodes) {
+      root = sourceEvent.currentTarget.closest("[data-wrn-toggle-count]")
+
+      if (!root) {
+        return
+      }
+
+      nodes = root.querySelectorAll("[data-toggle-count-value]")
+      animateValueAt(nodes, 0, previousValue)
+    }
+
+    function animateValueAt(nodes, index, previousValue, node, fromValue, toValue) {
+      if (index >= nodes.length) {
+        return
+      }
+
+      node = nodes[index]
+      fromValue = Number(
+        previousValue === secondValue
+          ? node.getAttribute("data-second-value")
+          : node.getAttribute("data-first-value")
+      )
+      toValue = Number(
+        selectedValue === secondValue
+          ? node.getAttribute("data-second-value")
+          : node.getAttribute("data-first-value")
+      )
+
+      if (!Number.isNaN(fromValue) && !Number.isNaN(toValue)) {
+        animateValueFrame(node, fromValue, toValue, 0)
+      }
+
+      animateValueAt(nodes, index + 1, previousValue)
+    }
+
+    function animateValueFrame(node, fromValue, toValue, frame, totalFrames, nextValue) {
+      totalFrames = Math.max(1, Number(animationSteps) || 1)
+
+      if (frame >= totalFrames) {
+        node.replaceChildren(String(toValue))
+        return
+      }
+
+      nextValue = Math.round(
+        fromValue +
+        (toValue - fromValue) * (frame / totalFrames)
+      )
+      node.replaceChildren(String(nextValue))
+
+      setTimeout(
+        animateValueFrame,
+        Math.max(1, Number(animationDuration) / totalFrames),
+        node,
+        fromValue,
+        toValue,
+        frame + 1
+      )
+    }
+
+    function toggleValue(sourceEvent) {
+      selectValue(
+        sourceEvent,
+        isFirstSelected() ? secondValue : firstValue
+      )
+    }
+  }
+
   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>
+        <section
+      {...attrs}
+      data-wrn-toggle-count
+      data-variant="{variant}"
+      data-value="{selectedValue}"
+      data-disabled="{disabled ? 'true' : 'false'}"
+      class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--toggle-count wire-next--toggle-count-{variant} {fullWidth ? 'wire-next--toggle-count-full' : ''} {disabled ? 'wire-next--disabled' : ''} {class}"
+    >
+        <input type="hidden" name="{name}" value="{selectedValue}" />
+        <div class="wire-next__toggle-count-control wire-next__toggle-count-control--{align}">
+        {#if variant === "switch"}
+          <span data-selected="{isFirstSelected() ? 'true' : 'false'}">{firstLabel}</span>
+        <button
+            type="button"
+            role="switch"
+            aria-label="{ariaLabel}"
+            aria-checked="{isSecondSelected() ? 'true' : 'false'}"
+            disabled="{disabled}"
+            @click="toggleValue(event)"
+            class="wire-next__toggle-count-switch"
+          >
+        <span aria-hidden="true">
+        </span>
+        </button>
+        <span data-selected="{isSecondSelected() ? 'true' : 'false'}">{secondLabel}</span>
+        {:else}
+          <div class="wire-next__toggle-count-segmented" role="group" aria-label="{ariaLabel}">
+        <button
+              type="button"
+              aria-pressed="{isFirstSelected() ? 'true' : 'false'}"
+              disabled="{disabled}"
+              @click="selectValue(event, firstValue)"
+            >{firstLabel}</button>
+        <button
+              type="button"
+              aria-pressed="{isSecondSelected() ? 'true' : 'false'}"
+              disabled="{disabled}"
+              @click="selectValue(event, secondValue)"
+            >{secondLabel}</button>
+        </div>
+        {/if}
+      </div>
+
+      {#if items.length > 0}
+        <div class="wire-next__toggle-count-items">
+          {#each items as item}
+            <article>
+        <span>{item.label || item.name}</span>
+        <strong>
+                {#if currency}<small>{currency}</small>{/if}
+                <span
+                  data-toggle-count-value
+                  data-first-value="{item[firstValueKey]}"
+                  data-second-value="{item[secondValueKey]}"
+                >{displayValue(item)}</span>
+                {#if suffix}<small>{suffix}</small>{/if}
+              </strong>
+              {#if item.description}<small>{item.description}</small>{/if}
+            </article>
+          {/each}
+        </div>
+      {/if}
+    </section>
     }
 }
 
- + } diff --git a/app/pages/components/toggle-password.wrn b/app/pages/components/toggle-password.wrn index d429adbe..ef2c7868 100644 --- a/app/pages/components/toggle-password.wrn +++ b/app/pages/components/toggle-password.wrn @@ -10,10 +10,10 @@ page TogglePasswordcomponent {
W WRNexusJS - +
-
advanced-forms component

TogglePassword

Accessible password field with optional show and hide controls.

@wrnexus/ui 0.4.024 props0 slots3 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<TogglePassword
+      
advanced-forms component

TogglePassword

Accessible password field with optional show and hide controls.

@wrnexus/ui 0.5.024 props0 slots3 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<TogglePassword
   size="default"
   color="primary"
   label="Password"
@@ -175,7 +175,7 @@ page TogglePasswordcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/tooltip.wrn b/app/pages/components/tooltip.wrn index 2a020e6b..9b40297b 100644 --- a/app/pages/components/tooltip.wrn +++ b/app/pages/components/tooltip.wrn @@ -10,17 +10,19 @@ page Tooltipcomponent {
W WRNexusJS - +
-
overlays component

Tooltip

Theme-aware, responsive tooltip component.

@wrnexus/ui 0.4.08 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Tooltip
+      
overlays component

Tooltip

Theme-aware, responsive tooltip component.

@wrnexus/ui 0.5.08 props1 slots2 events

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

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
titlestringOptional"Tooltip"
descriptionstringOptional""
openbooleanOptionalfalse
placementstringOptional"bottom"
closeLabelstringOptional"Close"
classstringOptional""

Slots

  • default

Events

This component does not declare a custom event.

Source contract

Installed source: components/tooltip.wrn

component Tooltip {
+/>

Legacy mount name: data-component="Tooltip".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
titlestringOptional"Tooltip"
descriptionstringOptional""
openbooleanOptionalfalse
placementstringOptional"bottom"
closeLabelstringOptional"Close"
classstringOptional""

Slots

  • default

Events

  • open
  • close

Source contract

Installed source: components/tooltip.wrn

component Tooltip {
   props {
+    @event open = function
+    @event close = function
     size = "default"
     color = "primary"
     title = "Tooltip"
@@ -42,7 +44,7 @@ page Tooltipcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/tree-view.wrn b/app/pages/components/tree-view.wrn index b5499209..2c48936e 100644 --- a/app/pages/components/tree-view.wrn +++ b/app/pages/components/tree-view.wrn @@ -10,17 +10,21 @@ page TreeViewcomponent {
W WRNexusJS - +
-
base component

TreeView

Theme-aware, responsive tree view component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<TreeView
+      
base component

TreeView

Theme-aware, responsive tree view component.

@wrnexus/ui 0.5.07 props1 slots4 events

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

PropTypeRequirementDefault
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 {
+/>

Legacy mount name: data-component="TreeView".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
titlestringOptional"Tree View"
descriptionstringOptional""
itemsstringOptional[]
variantstringOptional"default"
classstringOptional""

Slots

  • default

Events

  • select
  • toggle
  • expand
  • collapse

Source contract

Installed source: components/TreeView.wrn

component TreeView {
   props {
+    @event select = function
+    @event toggle = function
+    @event expand = function
+    @event collapse = function
     size = "default"
     color = "primary"
     title = "Tree View"
@@ -39,7 +43,7 @@ page TreeViewcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/typography.wrn b/app/pages/components/typography.wrn index 3e6f1bfd..c2a553f2 100644 --- a/app/pages/components/typography.wrn +++ b/app/pages/components/typography.wrn @@ -10,10 +10,10 @@ page Typographycomponent {
W WRNexusJS - +
-
layout component

Typography

Theme-aware, responsive typography component.

@wrnexus/ui 0.4.06 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Typography
+      
layout component

Typography

Theme-aware, responsive typography component.

@wrnexus/ui 0.5.06 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Typography
   size="default"
   color="primary"
   columns="2"
@@ -35,7 +35,7 @@ page Typographycomponent {
     }
 }
 
- + } diff --git a/app/pages/components/wysiwyg-editor.wrn b/app/pages/components/wysiwyg-editor.wrn index 508d3b38..0987bcf1 100644 --- a/app/pages/components/wysiwyg-editor.wrn +++ b/app/pages/components/wysiwyg-editor.wrn @@ -10,17 +10,21 @@ page WysiwygEditorcomponent {
W WRNexusJS - +
-
integrations component

WysiwygEditor

Theme-aware, responsive wysiwyg editor component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<WysiwygEditor
+      
integrations component

WysiwygEditor

Theme-aware, responsive wysiwyg editor component.

@wrnexus/ui 0.5.07 props1 slots4 events

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

PropTypeRequirementDefault
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 {
+/>

Legacy mount name: data-component="WysiwygEditor".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
titlestringOptional"Wysiwyg Editor"
descriptionstringOptional""
itemsstringOptional[]
variantstringOptional"default"
classstringOptional""

Slots

  • default

Events

  • input
  • change
  • focus
  • blur

Source contract

Installed source: components/WysiwygEditor.wrn

component WysiwygEditor {
   props {
+    @event input = function
+    @event change = function
+    @event focus = function
+    @event blur = function
     size = "default"
     color = "primary"
     title = "Wysiwyg Editor"
@@ -39,7 +43,7 @@ page WysiwygEditorcomponent {
     }
 }
 
- + } diff --git a/app/pages/examples.wrn b/app/pages/examples.wrn index 8e5963e0..309fdf88 100644 --- a/app/pages/examples.wrn +++ b/app/pages/examples.wrn @@ -7,10 +7,10 @@ page Examples { view {
-
W WRNexusJS
+
W WRNexusJS
-

Examples

Examples are tied to installed 0.4.0 package documentation. The focused snippets in guides are source-verified; standalone runnable projects and CI compilation are tracked as remaining work.

Minimal .wrn page

Documented

Database CRUD

Planned fixture

Authentication and protected route

Planned fixture

Permissions

Planned fixture

Forms and validation

Documented

Realtime dashboard

Planned fixture

File upload

Planned fixture

Background queue

Planned fixture

Redis pub/sub

Planned fixture

Workspace gateway

Planned fixture

Deployment

Planned fixture

Experimental mobile mode

Planned fixture
- +

Examples

Examples are tied to installed 0.5.0 package documentation. The focused snippets in guides are source-verified; standalone runnable projects and CI compilation are tracked as remaining work.

Minimal .wrn page

Documented

Database CRUD

Planned fixture

Authentication and protected route

Planned fixture

Permissions

Planned fixture

Forms and validation

Documented

Realtime dashboard

Planned fixture

File upload

Planned fixture

Background queue

Planned fixture

Redis pub/sub

Planned fixture

Workspace gateway

Planned fixture

Deployment

Planned fixture

Experimental mobile mode

Planned fixture
+
} diff --git a/app/pages/getting-started.wrn b/app/pages/getting-started.wrn index 6e75886a..c4988e9f 100644 --- a/app/pages/getting-started.wrn +++ b/app/pages/getting-started.wrn @@ -7,9 +7,9 @@ page Gettingstarted { view {
-
W WRNexusJS
+
W WRNexusJS
-
Preview guide · v0.4.0

Build a contact inbox

This path creates a server-rendered page, validated API route, middleware, and realtime next step. It requires approved registry access and Bun 1.3.x; this site was verified with Bun 1.3.14.

1. Create the project

bunx @wrnexus/cli@0.4.0 create my-app
+      
Preview guide · v0.5.0

Build a contact inbox

This path creates a server-rendered page, validated API route, middleware, and realtime next step. It requires approved registry access and Bun 1.3.x; this site was verified with Bun 1.3.14.

1. Create the project

bunx @wrnexus/cli@0.5.0 create my-app
 cd my-app
 bun install
 bun run dev

2. Know the structure

app/pages/       # file-based .wrn routes
@@ -39,7 +39,7 @@ export const POST = async (ctx) => {
 }

7. Test and ship

bun run test
 bun run build
 bun dist/server.js

Next: deployment, database, authentication, and workspaces.

- +
} diff --git a/app/pages/guides/api-routes.wrn b/app/pages/guides/api-routes.wrn index 388ea19d..46338000 100644 --- a/app/pages/guides/api-routes.wrn +++ b/app/pages/guides/api-routes.wrn @@ -7,10 +7,10 @@ page APIroutes { view {
-
W WRNexusJS
+
W WRNexusJS
-
Preview guide · 0.4.0

API routes

Export GET, POST, PUT, PATCH, or DELETE from app/api files. Validate request bodies, enforce authentication and authorization, cap request sizes, and return Web Responses.

Release scope

This guide describes installed 0.4.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

- +
Preview guide · 0.5.0

API routes

Export GET, POST, PUT, PATCH, or DELETE from app/api files. Validate request bodies, enforce authentication and authorization, cap request sizes, and return Web Responses.

Release scope

This guide describes installed 0.5.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

+
} diff --git a/app/pages/guides/authentication.wrn b/app/pages/guides/authentication.wrn index 950eb7c7..60033590 100644 --- a/app/pages/guides/authentication.wrn +++ b/app/pages/guides/authentication.wrn @@ -7,10 +7,10 @@ page Authentication { view {
-
W WRNexusJS
+
W WRNexusJS
-
Preview guide · 0.4.0

Authentication

Configure session authentication, log users in through supported auth helpers, and read identity from context. Cookie flags, rotation, expiry, and secret storage remain deployment responsibilities.

Release scope

This guide describes installed 0.4.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

- +
Preview guide · 0.5.0

Authentication

Configure session authentication, log users in through supported auth helpers, and read identity from context. Cookie flags, rotation, expiry, and secret storage remain deployment responsibilities.

Release scope

This guide describes installed 0.5.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

+
} diff --git a/app/pages/guides/authorization.wrn b/app/pages/guides/authorization.wrn index eb3c5f82..c8bbdea6 100644 --- a/app/pages/guides/authorization.wrn +++ b/app/pages/guides/authorization.wrn @@ -7,10 +7,10 @@ page Authorization { view {
-
W WRNexusJS
+
W WRNexusJS
-
Preview guide · 0.4.0

Authorization

Authentication identifies; authorization decides. Enforce permissions in server routes and policies, including object ownership. UI hiding is never an authorization boundary.

Release scope

This guide describes installed 0.4.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

- +
Preview guide · 0.5.0

Authorization

Authentication identifies; authorization decides. Enforce permissions in server routes and policies, including object ownership. UI hiding is never an authorization boundary.

Release scope

This guide describes installed 0.5.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

+
} diff --git a/app/pages/guides/configuration-and-profiles.wrn b/app/pages/guides/configuration-and-profiles.wrn index 8beebe5a..81accb41 100644 --- a/app/pages/guides/configuration-and-profiles.wrn +++ b/app/pages/guides/configuration-and-profiles.wrn @@ -7,10 +7,10 @@ page Configurationandprofiles { view {
-
W WRNexusJS
+
W WRNexusJS
-
Preview guide · 0.4.0

Configuration and profiles

wrnexus.config.ts owns styles, SEO, security, data, mobile, fonts, and profiles. Keep secrets in validated environment variables and review merged production configuration.

Release scope

This guide describes installed 0.4.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

- +
Preview guide · 0.5.0

Configuration and profiles

wrnexus.config.ts owns styles, SEO, security, data, mobile, fonts, and profiles. Keep secrets in validated environment variables and review merged production configuration.

Release scope

This guide describes installed 0.5.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

+
} diff --git a/app/pages/guides/database.wrn b/app/pages/guides/database.wrn index 27c30744..0facad54 100644 --- a/app/pages/guides/database.wrn +++ b/app/pages/guides/database.wrn @@ -7,10 +7,10 @@ page Database { view {
-
W WRNexusJS
+
W WRNexusJS
-
Preview guide · 0.4.0

Database

Configure SQLite or the installed supported driver, keep queries in named SQL blocks, generate typed functions, and apply migrations before traffic. Back up data and test rollback independently.

Release scope

This guide describes installed 0.4.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

- +
Preview guide · 0.5.0

Database

Configure SQLite or the installed supported driver, keep queries in named SQL blocks, generate typed functions, and apply migrations before traffic. Back up data and test rollback independently.

Release scope

This guide describes installed 0.5.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

+
} diff --git a/app/pages/guides/deployment.wrn b/app/pages/guides/deployment.wrn index 05022715..eeddda1b 100644 --- a/app/pages/guides/deployment.wrn +++ b/app/pages/guides/deployment.wrn @@ -7,10 +7,10 @@ page Deployment { view {
-
W WRNexusJS
+
W WRNexusJS
-
Preview guide · 0.4.0

Deployment

Run bun run build, apply migrations, and start dist/server.js with Bun. Configure TLS, proxy trust, environment validation, health checks, graceful restarts, logs, backups, and restrictive security headers.

Release scope

This guide describes installed 0.4.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

- +
Preview guide · 0.5.0

Deployment

Run bun run build, apply migrations, and start dist/server.js with Bun. Configure TLS, proxy trust, environment validation, health checks, graceful restarts, logs, backups, and restrictive security headers.

Release scope

This guide describes installed 0.5.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

+
} diff --git a/app/pages/guides/forms-and-validation.wrn b/app/pages/guides/forms-and-validation.wrn index fa08b4b7..e78cb908 100644 --- a/app/pages/guides/forms-and-validation.wrn +++ b/app/pages/guides/forms-and-validation.wrn @@ -7,10 +7,10 @@ page Formsandvalidation { view {
-
W WRNexusJS
+
W WRNexusJS
-
Preview guide · 0.4.0

Forms and validation

Define a v.object schema, use data-schema on the form, show field errors with data-error, and always call parseBody on the server. refine is server-only.

Release scope

This guide describes installed 0.4.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

- +
Preview guide · 0.5.0

Forms and validation

Define a v.object schema, use data-schema on the form, show field errors with data-error, and always call parseBody on the server. refine is server-only.

Release scope

This guide describes installed 0.5.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

+
} diff --git a/app/pages/guides/i18n-and-themes.wrn b/app/pages/guides/i18n-and-themes.wrn index 3bcf67f5..3ec3f47b 100644 --- a/app/pages/guides/i18n-and-themes.wrn +++ b/app/pages/guides/i18n-and-themes.wrn @@ -7,10 +7,10 @@ page Internationalizationandthemes { view {
-
W WRNexusJS
+
W WRNexusJS
-
Preview guide · 0.4.0

Internationalization and themes

Store locale JSON under app/locales and use translation directives. Themes resolve CSS tokens; ensure contrast, system preference behavior, persistence, and non-color cues.

Release scope

This guide describes installed 0.4.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

- +
Preview guide · 0.5.0

Internationalization and themes

Store locale JSON under app/locales and use translation directives. Themes resolve CSS tokens; ensure contrast, system preference behavior, persistence, and non-color cues.

Release scope

This guide describes installed 0.5.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

+
} diff --git a/app/pages/guides/middleware.wrn b/app/pages/guides/middleware.wrn index b47e3e3a..272cbc74 100644 --- a/app/pages/guides/middleware.wrn +++ b/app/pages/guides/middleware.wrn @@ -7,10 +7,10 @@ page Middleware { view {
-
W WRNexusJS
+
W WRNexusJS
-
Preview guide · 0.4.0

Middleware

Middleware receives context and next. Return next() to continue or return a Response to stop. Put request limits and trust-boundary controls before business logic.

Release scope

This guide describes installed 0.4.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

- +
Preview guide · 0.5.0

Middleware

Middleware receives context and next. Return next() to continue or return a Response to stop. Put request limits and trust-boundary controls before business logic.

Release scope

This guide describes installed 0.5.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

+
} diff --git a/app/pages/guides/mobile.wrn b/app/pages/guides/mobile.wrn index 10fbe350..68955efc 100644 --- a/app/pages/guides/mobile.wrn +++ b/app/pages/guides/mobile.wrn @@ -7,10 +7,10 @@ page Mobile { view {
-
W WRNexusJS
+
W WRNexusJS
-
Preview guide · 0.4.0

Mobile

Mobile capabilities are experimental in this preview. Test Capacitor permissions and lifecycle on each platform; do not assume every .wrn or browser API converts to native.

Release scope

This guide describes installed 0.4.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

- +
Preview guide · 0.5.0

Mobile

Mobile capabilities are experimental in this preview. Test Capacitor permissions and lifecycle on each platform; do not assume every .wrn or browser API converts to native.

Release scope

This guide describes installed 0.5.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

+
} diff --git a/app/pages/guides/observability.wrn b/app/pages/guides/observability.wrn index 5a0afe31..d4699659 100644 --- a/app/pages/guides/observability.wrn +++ b/app/pages/guides/observability.wrn @@ -7,10 +7,10 @@ page Observability { view {
-
W WRNexusJS
+
W WRNexusJS
-
Preview guide · 0.4.0

Observability

Use tracking middleware and sinks with redaction, sampling, stable request identifiers, alert ownership, and retention limits. Never capture registry tokens or session secrets.

Release scope

This guide describes installed 0.4.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

- +
Preview guide · 0.5.0

Observability

Use tracking middleware and sinks with redaction, sampling, stable request identifiers, alert ownership, and retention limits. Never capture registry tokens or session secrets.

Release scope

This guide describes installed 0.5.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

+
} diff --git a/app/pages/guides/pages-and-components.wrn b/app/pages/guides/pages-and-components.wrn index 8c1817c1..d3c23c3a 100644 --- a/app/pages/guides/pages-and-components.wrn +++ b/app/pages/guides/pages-and-components.wrn @@ -7,10 +7,10 @@ page Pagesandcomponents { view {
-
W WRNexusJS
+
W WRNexusJS
-
Preview guide · 0.4.0

Pages and components

Pages are routable, components are reusable, and layouts provide shared slots. Mount a component with data-component and keep browser state scoped and minimal.

Release scope

This guide describes installed 0.4.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

- +
Preview guide · 0.5.0

Pages and components

Pages are routable, components are reusable, and layouts provide shared slots. Mount a component with data-component and keep browser state scoped and minimal.

Release scope

This guide describes installed 0.5.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

+
} diff --git a/app/pages/guides/project-structure.wrn b/app/pages/guides/project-structure.wrn index 98862da9..222ea18e 100644 --- a/app/pages/guides/project-structure.wrn +++ b/app/pages/guides/project-structure.wrn @@ -7,10 +7,10 @@ page Projectstructure { view {
-
W WRNexusJS
+
W WRNexusJS
-
Preview guide · 0.4.0

Project structure

Pages, components, layouts, APIs, middleware, schemas, database files, locales, realtime rooms, and styles live under app. Never edit app/routes.gen.ts, .wrnexus, or dist by hand.

Release scope

This guide describes installed 0.4.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

- +
Preview guide · 0.5.0

Project structure

Pages, components, layouts, APIs, middleware, schemas, database files, locales, realtime rooms, and styles live under app. Never edit app/routes.gen.ts, .wrnexus, or dist by hand.

Release scope

This guide describes installed 0.5.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

+
} diff --git a/app/pages/guides/pubsub.wrn b/app/pages/guides/pubsub.wrn index 9c6cb2c3..363215be 100644 --- a/app/pages/guides/pubsub.wrn +++ b/app/pages/guides/pubsub.wrn @@ -7,10 +7,10 @@ page Pubsub { view {
-
W WRNexusJS
+
W WRNexusJS
-
Preview guide · 0.4.0

Pub/sub

The in-process driver cannot cross processes. Use Redis where instances must share events, define channel ownership, and design for reconnects and duplicate delivery.

Release scope

This guide describes installed 0.4.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

- +
Preview guide · 0.5.0

Pub/sub

The in-process driver cannot cross processes. Use Redis where instances must share events, define channel ownership, and design for reconnects and duplicate delivery.

Release scope

This guide describes installed 0.5.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

+
} diff --git a/app/pages/guides/queues.wrn b/app/pages/guides/queues.wrn index 47ab7783..797b43c9 100644 --- a/app/pages/guides/queues.wrn +++ b/app/pages/guides/queues.wrn @@ -7,10 +7,10 @@ page Queues { view {
-
W WRNexusJS
+
W WRNexusJS
-
Preview guide · 0.4.0

Queues

Queue behavior is preview-level. Treat in-process work as non-durable, make handlers idempotent, cap retries, record failures, and choose a production persistence strategy.

Release scope

This guide describes installed 0.4.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

- +
Preview guide · 0.5.0

Queues

Queue behavior is preview-level. Treat in-process work as non-durable, make handlers idempotent, cap retries, record failures, and choose a production persistence strategy.

Release scope

This guide describes installed 0.5.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

+
} diff --git a/app/pages/guides/realtime.wrn b/app/pages/guides/realtime.wrn index 5fd3e006..b178f342 100644 --- a/app/pages/guides/realtime.wrn +++ b/app/pages/guides/realtime.wrn @@ -7,10 +7,10 @@ page Realtime { view {
-
W WRNexusJS
+
W WRNexusJS
-
Preview guide · 0.4.0

Realtime

defineRoom handles connection and messages. Validate message shapes, authorize subscriptions, restrict origins, bound payloads, and use pub/sub to scale across processes.

Release scope

This guide describes installed 0.4.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

- +
Preview guide · 0.5.0

Realtime

defineRoom handles connection and messages. Validate message shapes, authorize subscriptions, restrict origins, bound payloads, and use pub/sub to scale across processes.

Release scope

This guide describes installed 0.5.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

+
} diff --git a/app/pages/guides/routing.wrn b/app/pages/guides/routing.wrn index 11fae245..ae4af20c 100644 --- a/app/pages/guides/routing.wrn +++ b/app/pages/guides/routing.wrn @@ -7,10 +7,10 @@ page Routing { view {
-
W WRNexusJS
+
W WRNexusJS
-
Preview guide · 0.4.0

Routing

A page filename defines its URL; index maps to the directory root and bracket segments are dynamic parameters. API files under app/api expose HTTP method functions and receive a Context.

Release scope

This guide describes installed 0.4.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

- +
Preview guide · 0.5.0

Routing

A page filename defines its URL; index maps to the directory root and bracket segments are dynamic parameters. API files under app/api expose HTTP method functions and receive a Context.

Release scope

This guide describes installed 0.5.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

+
} diff --git a/app/pages/guides/security.wrn b/app/pages/guides/security.wrn index 064dd01f..1bbc74fb 100644 --- a/app/pages/guides/security.wrn +++ b/app/pages/guides/security.wrn @@ -7,10 +7,10 @@ page Applicationsecurity { view {
-
W WRNexusJS
+
W WRNexusJS
-
Preview guide · 0.4.0

Application security

Use CSP, CSRF, Trusted Types, session hardening, validation, origin checks, upload restrictions, encryption, request limits, and explicit CORS. See the security policy for reporting.

Release scope

This guide describes installed 0.4.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

- +
Preview guide · 0.5.0

Application security

Use CSP, CSRF, Trusted Types, session hardening, validation, origin checks, upload restrictions, encryption, request limits, and explicit CORS. See the security policy for reporting.

Release scope

This guide describes installed 0.5.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

+
} diff --git a/app/pages/guides/server-data.wrn b/app/pages/guides/server-data.wrn index 3be0e194..85fe4a29 100644 --- a/app/pages/guides/server-data.wrn +++ b/app/pages/guides/server-data.wrn @@ -7,10 +7,10 @@ page Serverdata { view {
-
W WRNexusJS
+
W WRNexusJS
-
Preview guide · 0.4.0

Server data

Use an ssr API binding, return the desired response field, and render it with a server #each block. Values are escaped. Avoid fetching private data through a route that lacks authorization.

Release scope

This guide describes installed 0.4.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

- +
Preview guide · 0.5.0

Server data

Use an ssr API binding, return the desired response field, and render it with a server #each block. Values are escaped. Avoid fetching private data through a route that lacks authorization.

Release scope

This guide describes installed 0.5.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

+
} diff --git a/app/pages/guides/testing.wrn b/app/pages/guides/testing.wrn index a8b4a4d2..02e7a1e6 100644 --- a/app/pages/guides/testing.wrn +++ b/app/pages/guides/testing.wrn @@ -7,10 +7,10 @@ page Testing { view {
-
W WRNexusJS
+
W WRNexusJS
-
Preview guide · 0.4.0

Testing

Use Bun tests and @wrnexus/test helpers. Cover server HTML, API status and validation, authorization failures, reactive behavior, and a production startup smoke test.

Release scope

This guide describes installed 0.4.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

- +
Preview guide · 0.5.0

Testing

Use Bun tests and @wrnexus/test helpers. Cover server HTML, API status and validation, authorization failures, reactive behavior, and a production startup smoke test.

Release scope

This guide describes installed 0.5.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

+
} diff --git a/app/pages/guides/troubleshooting.wrn b/app/pages/guides/troubleshooting.wrn index c0218f36..88b595cb 100644 --- a/app/pages/guides/troubleshooting.wrn +++ b/app/pages/guides/troubleshooting.wrn @@ -7,10 +7,10 @@ page Troubleshooting { view {
-
W WRNexusJS
+
W WRNexusJS
-
Preview guide · 0.4.0

Troubleshooting

Confirm Bun and package versions, regenerate docs/routes through supported commands, read the first compiler diagnostic, check file naming, validate config, and reproduce under a production build.

Release scope

This guide describes installed 0.4.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

- +
Preview guide · 0.5.0

Troubleshooting

Confirm Bun and package versions, regenerate docs/routes through supported commands, read the first compiler diagnostic, check file naming, validate config, and reproduce under a production build.

Release scope

This guide describes installed 0.5.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

+
} diff --git a/app/pages/guides/upgrading.wrn b/app/pages/guides/upgrading.wrn index e1e7dab3..6f14c77e 100644 --- a/app/pages/guides/upgrading.wrn +++ b/app/pages/guides/upgrading.wrn @@ -7,10 +7,10 @@ page Upgrading { view {
-
W WRNexusJS
+
W WRNexusJS
-
Preview guide · 0.4.0

Upgrading

Back up and commit first, then use wrnexus update --latest as documented by the installed CLI. Review migrations and keep every @wrnexus package aligned. Current release: 0.4.0.

Release scope

This guide describes installed 0.4.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

- +
Preview guide · 0.5.0

Upgrading

Back up and commit first, then use wrnexus update --latest as documented by the installed CLI. Review migrations and keep every @wrnexus package aligned. Current release: 0.5.0.

Release scope

This guide describes installed 0.5.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

+
} diff --git a/app/pages/guides/uploads.wrn b/app/pages/guides/uploads.wrn index 7202765d..5a537837 100644 --- a/app/pages/guides/uploads.wrn +++ b/app/pages/guides/uploads.wrn @@ -7,10 +7,10 @@ page Uploads { view {
-
W WRNexusJS
+
W WRNexusJS
-
Preview guide · 0.4.0

Uploads

Configure named stores, accepted MIME/extensions, and maxBytes. Random keys avoid path traversal. Private files require an authenticated serving route; v1 buffers each file in memory.

Release scope

This guide describes installed 0.4.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

- +
Preview guide · 0.5.0

Uploads

Configure named stores, accepted MIME/extensions, and maxBytes. Random keys avoid path traversal. Private files require an authenticated serving route; v1 buffers each file in memory.

Release scope

This guide describes installed 0.5.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

+
} diff --git a/app/pages/guides/workspaces-and-gateway.wrn b/app/pages/guides/workspaces-and-gateway.wrn index 21c23de8..a78a1063 100644 --- a/app/pages/guides/workspaces-and-gateway.wrn +++ b/app/pages/guides/workspaces-and-gateway.wrn @@ -7,9 +7,9 @@ page Workspacesandgateway { view {
-
W WRNexusJS
+
W WRNexusJS
-
Preview guide · 0.4.0

Workspaces and gateway

A workspace runs isolated applications behind one domain-routing gateway. Add an application from the workspace root; the CLI scaffolds apps/reports and registers it in wrnexus.workspace.ts:

wrnexus workspace add reports --domain=reports.localhost
+      
Preview guide · 0.5.0

Workspaces and gateway

A workspace runs isolated applications behind one domain-routing gateway. Add an application from the workspace root; the CLI scaffolds apps/reports and registers it in wrnexus.workspace.ts:

wrnexus workspace add reports --domain=reports.localhost
 bun install
 bun run dev

Forward authentication

Point protected applications at a dedicated verifier endpoint. The verifier must return 2xx for an authenticated session, 401/403 to deny access, or an HTTP redirect to begin browser login.

// wrnexus.workspace.ts
 {
@@ -28,8 +28,8 @@ export const GET = async (ctx: Context) => {
   return redirectToLogin(ctx, "/login", {
     allowedHosts: ["admin.localhost:3000", "reports.localhost:3000"],
   });
-};

Always allowlist redirect hosts. After login, validate or sign the returnTo value before redirecting. Keep internal app ports private and open applications through the gateway port.

Release scope

This guide describes installed 0.4.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

- +};

Always allowlist redirect hosts. After login, validate or sign the returnTo value before redirecting. Keep internal app ports private and open applications through the gateway port.

Release scope

This guide describes installed 0.5.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

+
} diff --git a/app/pages/index.wrn b/app/pages/index.wrn index d64de96e..f2e6f635 100644 --- a/app/pages/index.wrn +++ b/app/pages/index.wrn @@ -7,9 +7,9 @@ page Home { view {
-
W WRNexusJS
+
W WRNexusJS
-

WRNexusJS v0.4.0

Build from the server.
Ship only what matters.

WRNexusJS is an SSR-first, Bun-native full-stack framework. Build typed pages, APIs, validated forms, realtime rooms, secure sessions, workspaces, and optional mobile experiences with the .wrn component language.

Private developer preview. Request access to the package registry.

app/pages/dashboard.wrn
page Dashboard {
+      

WRNexusJS v0.5.0

Build from the server.
Ship only what matters.

WRNexusJS is an SSR-first, Bun-native full-stack framework. Build typed pages, APIs, validated forms, realtime rooms, secure sessions, workspaces, and optional mobile experiences with the .wrn component language.

Private developer preview. Request access to the package registry.

app/pages/dashboard.wrn
page Dashboard {
   ssr { api tasks GET /api/tasks { return tasks } }
   view {
     <main>
@@ -35,10 +35,10 @@ export const POST = async (ctx) => {
   return result.ok ? Response.json({ ok: true }, { status: 201 }) : result.response;
 };

Request lifecycle

  1. RequestSecurity headers and request limits
  2. MiddlewareAuthentication, policy, and context
  3. File routePage or API handler
  4. Compiler + SSRSafe HTML and scoped runtime
  5. ResponseHTML, JSON, stream, or realtime upgrade
-

Production proof

WorkRoot

Public creator/company site and approved WRNexusJS production showcase.

wrnexusjs.dev

This documentation application runs WRNexusJS 0.4.0.

View deployment notes and showcase status →

-

Capability status

CapabilityStatusDetails
SSR, routing, compiler, APIsPreviewInstalled in 0.4.0; public support policy pending.
Mobile/nativeExperimentalCapacitor compatibility and native generation have platform limitations.
Durable queuesExperimentalProduction durability requires an appropriate driver strategy.
-

Continue exploring

- +

Production proof

WorkRoot

Public creator/company site and approved WRNexusJS production showcase.

wrnexusjs.dev

This documentation application runs WRNexusJS 0.5.0.

View deployment notes and showcase status →

+

Capability status

CapabilityStatusDetails
SSR, routing, compiler, APIsPreviewInstalled in 0.5.0; public support policy pending.
Mobile/nativeExperimentalCapacitor compatibility and native generation have platform limitations.
Durable queuesExperimentalProduction durability requires an appropriate driver strategy.
+

Continue exploring

+
} diff --git a/app/pages/language.wrn b/app/pages/language.wrn index 4e27f5c3..1a044411 100644 --- a/app/pages/language.wrn +++ b/app/pages/language.wrn @@ -7,15 +7,15 @@ page Thewrnlanguage { view {
-
W WRNexusJS
+
W WRNexusJS
-
Language reference · 0.4.0

The .wrn language

File anatomy

page Account {
+      
Language reference · 0.5.0

The .wrn language

File anatomy

page Account {
   layout = "public"
   seo { title = "Account" description = "Manage your account." }
   state count = 0
   view { <button @click="count++">Count {count}</button> }
 }

Pages, components, layouts, props, and state

Pages are routes. Components declare default-valued props and may hold state. Layouts provide shared slots. Mount components with data-component; fill default or named slots with data-slot.

Interpolation, conditionals, and loops

Interpolation is HTML-escaped. Use server {#if} and {#each} for SSR data. Use data-show for reactive client visibility.

Events and directives

@click and other events execute in the reactive scope. Data attributes opt into forms, i18n, themes, realtime, uploader, browser, and mobile behavior. Consult the exact package page because availability varies.

Forms, i18n, themes, and realtime

form[data-schema] connects descriptors to client and server validation. Translation keys use {t:key}. Theme toggles use data-wire-theme-toggle. Realtime pages opt into a named room.

Escaping and security

Text interpolation is escaped by default. Do not construct trusted HTML from user input. Server-only refinements must be repeated at the authoritative mutation boundary.

Common compiler errors

  • Use balanced braces; a literal brace must be escaped.
  • Declare UI in view, not JSX or hooks.
  • Use a valid page, component, or layout declaration matching the file role.
  • Keep server loops tied to available SSR bindings.
  • Check troubleshooting and compiler API for this release.
- +
} diff --git a/app/pages/license.wrn b/app/pages/license.wrn index 7f49c316..74d15d1b 100644 --- a/app/pages/license.wrn +++ b/app/pages/license.wrn @@ -7,10 +7,10 @@ page License { view {
-
W WRNexusJS
+
W WRNexusJS

License

Owner decision required

This documentation repository contains no public license file, and the packages are unavailable from the public npm registry. No open-source license or redistribution right should be inferred.

Approved preview users must follow the private/commercial terms supplied by WorkRoot. Contact WorkRoot before copying, redistributing, or using WRNexusJS in production.

- +
} diff --git a/app/pages/packages.wrn b/app/pages/packages.wrn index 17b31e69..7a49aa1e 100644 --- a/app/pages/packages.wrn +++ b/app/pages/packages.wrn @@ -12,10 +12,10 @@ page Packages {
W WRNexusJS - +
-
26 focused packages

Package reference

Everything in the framework, organized by responsibility and documented from the published 0.4.0 APIs.

Showing {category} packages

+
26 focused packages

Package reference

Everything in the framework, organized by responsibility and documented from the published 0.5.0 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 4da1fb08..9193fd4e 100644 --- a/app/pages/packages/ai.wrn +++ b/app/pages/packages/ai.wrn @@ -10,11 +10,11 @@ page wrnexusai {
W WRNexusJS - +
-
AI · Package reference

@wrnexus/ai

Server-side Anthropic client with generation and streaming.

v0.4.0Private registryAI

Install the package

After WorkRoot approves private registry access, install the release-aligned package:

bun add @wrnexus/ai@0.4.0

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.

v0.5.0Private registryAI

Install the package

After WorkRoot approves private registry access, install the release-aligned package:

bun add @wrnexus/ai@0.5.0

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.

@@ -240,7 +240,7 @@ export const POST = async (ctx) => { };
- + } diff --git a/app/pages/packages/authz.wrn b/app/pages/packages/authz.wrn index 0bfd58c2..1a7a9e66 100644 --- a/app/pages/packages/authz.wrn +++ b/app/pages/packages/authz.wrn @@ -10,11 +10,11 @@ page wrnexusauthz {
W WRNexusJS - +
-
Security · Package reference

@wrnexus/authz

Role, permission, policy, and authorization guards.

v0.4.0Private registrySecurity

Install the package

After WorkRoot approves private registry access, install the release-aligned package:

bun add @wrnexus/authz@0.4.0

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.

v0.5.0Private registrySecurity

Install the package

After WorkRoot approves private registry access, install the release-aligned package:

bun add @wrnexus/authz@0.5.0

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.

@@ -242,7 +242,7 @@ app.put( );
- + } diff --git a/app/pages/packages/cli.wrn b/app/pages/packages/cli.wrn index f8c657df..5b416e10 100644 --- a/app/pages/packages/cli.wrn +++ b/app/pages/packages/cli.wrn @@ -10,11 +10,11 @@ page wrnexuscli {
W WRNexusJS - +
-
Tooling · Package reference

@wrnexus/cli

Create, develop, build, generate, test, and maintain WRNexusJS apps.

v0.4.0Private registryTooling

Install the package

After WorkRoot approves private registry access, install the release-aligned package:

bun add @wrnexus/cli@0.4.0

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.

v0.5.0Private registryTooling

Install the package

After WorkRoot approves private registry access, install the release-aligned package:

bun add @wrnexus/cli@0.5.0

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 663aa9c8..0af601d7 100644 --- a/app/pages/packages/compiler.wrn +++ b/app/pages/packages/compiler.wrn @@ -10,11 +10,11 @@ page wrnexuscompiler {
W WRNexusJS - +
-
Core · Package reference

@wrnexus/compiler

Parser and code generators for the .wrn language.

v0.4.0Private registryCore

Install the package

After WorkRoot approves private registry access, install the release-aligned package:

bun add @wrnexus/compiler@0.4.0

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.

v0.5.0Private registryCore

Install the package

After WorkRoot approves private registry access, install the release-aligned package:

bun add @wrnexus/compiler@0.5.0

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.

@@ -241,7 +241,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 7e0bf743..73c68be1 100644 --- a/app/pages/packages/core.wrn +++ b/app/pages/packages/core.wrn @@ -10,11 +10,11 @@ page wrnexuscore {
W WRNexusJS - +
-
Core · Package reference

@wrnexus/core

Contexts, middleware, security, sessions, caching, JSX, and realtime.

v0.4.0Private registryCore

Install the package

After WorkRoot approves private registry access, install the release-aligned package:

bun add @wrnexus/core@0.4.0

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.

v0.5.0Private registryCore

Install the package

After WorkRoot approves private registry access, install the release-aligned package:

bun add @wrnexus/core@0.5.0

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.

@@ -1210,7 +1210,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 86951d75..5e365a9f 100644 --- a/app/pages/packages/csr.wrn +++ b/app/pages/packages/csr.wrn @@ -10,11 +10,11 @@ page wrnexuscsr {
W WRNexusJS - +
-
Frontend · Package reference

@wrnexus/csr

Reactive, navigation, and realtime browser runtimes.

v0.4.0Private registryFrontend

Install the package

After WorkRoot approves private registry access, install the release-aligned package:

bun add @wrnexus/csr@0.4.0

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.

v0.5.0Private registryFrontend

Install the package

After WorkRoot approves private registry access, install the release-aligned package:

bun add @wrnexus/csr@0.5.0

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 0dd72424..1c216dd6 100644 --- a/app/pages/packages/db.wrn +++ b/app/pages/packages/db.wrn @@ -10,11 +10,11 @@ page wrnexusdb {
W WRNexusJS - +
-
Data · Package reference

@wrnexus/db

Database adapters, typed queries, models, migrations, and sessions.

v0.4.0Private registryData

Install the package

After WorkRoot approves private registry access, install the release-aligned package:

bun add @wrnexus/db@0.4.0

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.

v0.5.0Private registryData

Install the package

After WorkRoot approves private registry access, install the release-aligned package:

bun add @wrnexus/db@0.5.0

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.

@@ -375,7 +375,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 a114fe11..baa4bd4a 100644 --- a/app/pages/packages/dev-server.wrn +++ b/app/pages/packages/dev-server.wrn @@ -10,11 +10,11 @@ page wrnexusdevserver {
W WRNexusJS - +
-
Runtime · Package reference

@wrnexus/dev-server

Development and production servers, HMR, assets, and gateways.

v0.4.0Private registryRuntime

Install the package

After WorkRoot approves private registry access, install the release-aligned package:

bun add @wrnexus/dev-server@0.4.0

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.

v0.5.0Private registryRuntime

Install the package

After WorkRoot approves private registry access, install the release-aligned package:

bun add @wrnexus/dev-server@0.5.0

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).

@@ -641,6 +641,7 @@ interface ServeOptions { mode?: Mode; /** Inject the live-reload client (defaults to true in development). */ hmr?: boolean; + appConfig?: Record<string, unknown>; /** Resolved absolute path to the global CSS entry, or null. */ styleEntry?: string | null; /** Custom styles config (e.g. a Tailwind/PostCSS processor). */ @@ -729,7 +730,7 @@ await startGateway({ });
- + } diff --git a/app/pages/packages/encryption.wrn b/app/pages/packages/encryption.wrn index baed096f..680ecaa4 100644 --- a/app/pages/packages/encryption.wrn +++ b/app/pages/packages/encryption.wrn @@ -10,11 +10,11 @@ page wrnexusencryption {
W WRNexusJS - +
-
Security · Package reference

@wrnexus/encryption

Hashing, HMAC, authenticated encryption, and key derivation.

v0.4.0Private registrySecurity

Install the package

After WorkRoot approves private registry access, install the release-aligned package:

bun add @wrnexus/encryption@0.4.0

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.

v0.5.0Private registrySecurity

Install the package

After WorkRoot approves private registry access, install the release-aligned package:

bun add @wrnexus/encryption@0.5.0

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).

@@ -127,7 +127,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 4ba2f760..cdae58c7 100644 --- a/app/pages/packages/helpers.wrn +++ b/app/pages/packages/helpers.wrn @@ -10,11 +10,11 @@ page wrnexushelpers {
W WRNexusJS - +
-
Tooling · Package reference

@wrnexus/helpers

Safe Context URL helpers and forward-auth login redirects.

v0.4.0Private registryTooling

Install the package

After WorkRoot approves private registry access, install the release-aligned package:

bun add @wrnexus/helpers@0.4.0

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.

v0.5.0Private registryTooling

Install the package

After WorkRoot approves private registry access, install the release-aligned package:

bun add @wrnexus/helpers@0.5.0

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

@@ -154,7 +154,7 @@ export const GET = async (ctx: Context) => { };
- + } diff --git a/app/pages/packages/i18n.wrn b/app/pages/packages/i18n.wrn index 42dfdf56..23e473c8 100644 --- a/app/pages/packages/i18n.wrn +++ b/app/pages/packages/i18n.wrn @@ -10,11 +10,11 @@ page wrnexusi18n {
W WRNexusJS - +
-
Frontend · Package reference

@wrnexus/i18n

Translation loading, locale resolution, and Intl formatting.

v0.4.0Private registryFrontend

Install the package

After WorkRoot approves private registry access, install the release-aligned package:

bun add @wrnexus/i18n@0.4.0

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.

v0.5.0Private registryFrontend

Install the package

After WorkRoot approves private registry access, install the release-aligned package:

bun add @wrnexus/i18n@0.5.0

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.

@@ -251,7 +251,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 b59301af..a38045e0 100644 --- a/app/pages/packages/jwt.wrn +++ b/app/pages/packages/jwt.wrn @@ -10,11 +10,11 @@ page wrnexusjwt {
W WRNexusJS - +
-
Security · Package reference

@wrnexus/jwt

HS256 JWT signing, verification, and bearer authentication.

v0.4.0Private registrySecurity

Install the package

After WorkRoot approves private registry access, install the release-aligned package:

bun add @wrnexus/jwt@0.4.0

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.

v0.5.0Private registrySecurity

Install the package

After WorkRoot approves private registry access, install the release-aligned package:

bun add @wrnexus/jwt@0.5.0

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.

@@ -192,7 +192,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 03541915..2065811b 100644 --- a/app/pages/packages/mobile.wrn +++ b/app/pages/packages/mobile.wrn @@ -10,11 +10,11 @@ page wrnexusmobile {
W WRNexusJS - +
-
Native · Package reference

@wrnexus/mobile

SSR-safe compatibility access to Capacitor plugins.

v0.4.0Private registryNative

Install the package

After WorkRoot approves private registry access, install the release-aligned package:

bun add @wrnexus/mobile@0.4.0

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.

v0.5.0Private registryNative

Install the package

After WorkRoot approves private registry access, install the release-aligned package:

bun add @wrnexus/mobile@0.5.0

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:

@@ -169,7 +169,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 606b4fa9..c9bd39cc 100644 --- a/app/pages/packages/native.wrn +++ b/app/pages/packages/native.wrn @@ -10,11 +10,11 @@ page wrnexusnative {
W WRNexusJS - +
-
Native · Package reference

@wrnexus/native

Cross-platform browser and Capacitor capability registry.

v0.4.0Private registryNative

Install the package

After WorkRoot approves private registry access, install the release-aligned package:

bun add @wrnexus/native@0.4.0

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.

v0.5.0Private registryNative

Install the package

After WorkRoot approves private registry access, install the release-aligned package:

bun add @wrnexus/native@0.5.0

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
@@ -152,7 +152,7 @@ const position = await native.run( );
- + } diff --git a/app/pages/packages/oauth.wrn b/app/pages/packages/oauth.wrn index 095879c8..66cbf84f 100644 --- a/app/pages/packages/oauth.wrn +++ b/app/pages/packages/oauth.wrn @@ -10,11 +10,11 @@ page wrnexusoauth {
W WRNexusJS - +
-
Security · Package reference

@wrnexus/oauth

OAuth 2.0, PKCE, provider presets, and profile mapping.

v0.4.0Private registrySecurity

Install the package

After WorkRoot approves private registry access, install the release-aligned package:

bun add @wrnexus/oauth@0.4.0

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.

v0.5.0Private registrySecurity

Install the package

After WorkRoot approves private registry access, install the release-aligned package:

bun add @wrnexus/oauth@0.5.0

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.

@@ -313,7 +313,7 @@ const gitlab = defineProvider({ });
- + } diff --git a/app/pages/packages/pubsub.wrn b/app/pages/packages/pubsub.wrn index 0bd181d4..ab3da702 100644 --- a/app/pages/packages/pubsub.wrn +++ b/app/pages/packages/pubsub.wrn @@ -10,11 +10,11 @@ page wrnexuspubsub {
W WRNexusJS - +
-
Realtime · Package reference

@wrnexus/pubsub

In-process and Redis-backed publish/subscribe.

v0.4.0Private registryRealtime

Install the package

After WorkRoot approves private registry access, install the release-aligned package:

bun add @wrnexus/pubsub@0.4.0

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.

v0.5.0Private registryRealtime

Install the package

After WorkRoot approves private registry access, install the release-aligned package:

bun add @wrnexus/pubsub@0.5.0

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.

@@ -176,7 +176,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 0cbaf78f..9c2530cf 100644 --- a/app/pages/packages/queue.wrn +++ b/app/pages/packages/queue.wrn @@ -10,11 +10,11 @@ page wrnexusqueue {
W WRNexusJS - +
-
Data · Package reference

@wrnexus/queue

Background jobs with delay, concurrency, retry, and repetition.

v0.4.0Private registryData

Install the package

After WorkRoot approves private registry access, install the release-aligned package:

bun add @wrnexus/queue@0.4.0

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.

v0.5.0Private registryData

Install the package

After WorkRoot approves private registry access, install the release-aligned package:

bun add @wrnexus/queue@0.5.0

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().

@@ -252,7 +252,7 @@ clock = 5000; const ran = await queue.drain(); // => 1
- + } diff --git a/app/pages/packages/reactive.wrn b/app/pages/packages/reactive.wrn index acd71854..d661f2e4 100644 --- a/app/pages/packages/reactive.wrn +++ b/app/pages/packages/reactive.wrn @@ -10,11 +10,11 @@ page wrnexusreactive {
W WRNexusJS - +
-
Frontend · Package reference

@wrnexus/reactive

Small type-safe reactive signal primitives.

v0.4.0Private registryFrontend

Install the package

After WorkRoot approves private registry access, install the release-aligned package:

bun add @wrnexus/reactive@0.4.0

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.

v0.5.0Private registryFrontend

Install the package

After WorkRoot approves private registry access, install the release-aligned package:

bun add @wrnexus/reactive@0.5.0

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.

@@ -156,7 +156,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 ef85a5d6..feb94a64 100644 --- a/app/pages/packages/router.wrn +++ b/app/pages/packages/router.wrn @@ -10,11 +10,11 @@ page wrnexusrouter {
W WRNexusJS - +
-
Core · Package reference

@wrnexus/router

Filesystem discovery, route matching, and typed route generation.

v0.4.0Private registryCore

Install the package

After WorkRoot approves private registry access, install the release-aligned package:

bun add @wrnexus/router@0.4.0

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.

v0.5.0Private registryCore

Install the package

After WorkRoot approves private registry access, install the release-aligned package:

bun add @wrnexus/router@0.5.0

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.

@@ -300,7 +300,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 c4ed3138..fc7e1fca 100644 --- a/app/pages/packages/ssr.wrn +++ b/app/pages/packages/ssr.wrn @@ -10,11 +10,11 @@ page wrnexusssr {
W WRNexusJS - +
-
Runtime · Package reference

@wrnexus/ssr

Secure HTML document rendering and SEO metadata.

v0.4.0Private registryRuntime

Install the package

After WorkRoot approves private registry access, install the release-aligned package:

bun add @wrnexus/ssr@0.4.0

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.

v0.5.0Private registryRuntime

Install the package

After WorkRoot approves private registry access, install the release-aligned package:

bun add @wrnexus/ssr@0.5.0

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.

@@ -198,7 +198,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 47e4bf76..584713ef 100644 --- a/app/pages/packages/styles.wrn +++ b/app/pages/packages/styles.wrn @@ -10,11 +10,11 @@ page wrnexusstyles {
W WRNexusJS - +
-
Frontend · Package reference

@wrnexus/styles

CSS pipeline, themes, fonts, profiles, and application config.

v0.4.0Private registryFrontend

Install the package

After WorkRoot approves private registry access, install the release-aligned package:

bun add @wrnexus/styles@0.4.0

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.

v0.5.0Private registryFrontend

Install the package

After WorkRoot approves private registry access, install the release-aligned package:

bun add @wrnexus/styles@0.5.0

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:

@@ -727,7 +727,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 48f7d34d..2fb9dd70 100644 --- a/app/pages/packages/test.wrn +++ b/app/pages/packages/test.wrn @@ -10,11 +10,11 @@ page wrnexustest {
W WRNexusJS - +
-
Tooling · Package reference

@wrnexus/test

WRNexusJS-aware component, route, and browser testing utilities.

v0.4.0Private registryTooling

Install the package

After WorkRoot approves private registry access, install the release-aligned package:

bun add @wrnexus/test@0.4.0

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.

v0.5.0Private registryTooling

Install the package

After WorkRoot approves private registry access, install the release-aligned package:

bun add @wrnexus/test@0.5.0

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.

@@ -220,7 +220,7 @@ test("health endpoint", async () => { });
- + } diff --git a/app/pages/packages/tracking.wrn b/app/pages/packages/tracking.wrn index bf4950c3..a525f7d3 100644 --- a/app/pages/packages/tracking.wrn +++ b/app/pages/packages/tracking.wrn @@ -10,11 +10,11 @@ page wrnexustracking {
W WRNexusJS - +
-
Runtime · Package reference

@wrnexus/tracking

Error/event capture, middleware, filtering, and sinks.

v0.4.0Private registryRuntime

Install the package

After WorkRoot approves private registry access, install the release-aligned package:

bun add @wrnexus/tracking@0.4.0

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.

v0.5.0Private registryRuntime

Install the package

After WorkRoot approves private registry access, install the release-aligned package:

bun add @wrnexus/tracking@0.5.0

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.

@@ -199,7 +199,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 45c62b97..1e82e5e0 100644 --- a/app/pages/packages/ui.wrn +++ b/app/pages/packages/ui.wrn @@ -10,11 +10,11 @@ page wrnexusui {
W WRNexusJS - +
-
Frontend · Package reference

@wrnexus/ui

Themeable server-rendered UI components and CSS.

v0.4.0Private registryFrontend

Install the package

After WorkRoot approves private registry access, install the release-aligned package:

bun add @wrnexus/ui@0.4.0

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.

v0.5.0Private registryFrontend

Install the package

After WorkRoot approves private registry access, install the release-aligned package:

bun add @wrnexus/ui@0.5.0

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.

@@ -155,7 +155,7 @@ const router = buildRouter(appDir, { componentDirs: [uiComponentsDir()]  </div>

Explore the component library

The component reference now has a dedicated catalog with searchable cards and one complete page per component.

Browse all 85 components →

- + } diff --git a/app/pages/packages/uploader.wrn b/app/pages/packages/uploader.wrn index 5d9c172a..1184a5b0 100644 --- a/app/pages/packages/uploader.wrn +++ b/app/pages/packages/uploader.wrn @@ -10,11 +10,11 @@ page wrnexusuploader {
W WRNexusJS - +
-
Data · Package reference

@wrnexus/uploader

Validated local/S3 uploads and secure file serving.

v0.4.0Private registryData

Install the package

After WorkRoot approves private registry access, install the release-aligned package:

bun add @wrnexus/uploader@0.4.0

Request preview access. Never put registry tokens in source control.

Config-driven file uploads + serving for WRNexusJS. Declare named storage stores (local disk or any S3-compatible backend) in wrnexus.config.ts, upload with one function call, drop a drag-and-drop widget on a page, and serve files back — public or private. Zero external dependencies (S3 is signed with a built-in AWS SigV4 implementation, like the rest of the framework).

+
Data · Package reference

@wrnexus/uploader

Validated local/S3 uploads and secure file serving.

v0.5.0Private registryData

Install the package

After WorkRoot approves private registry access, install the release-aligned package:

bun add @wrnexus/uploader@0.5.0

Request preview access. Never put registry tokens in source control.

Config-driven file uploads + serving for WRNexusJS. Declare named storage stores (local disk or any S3-compatible backend) in wrnexus.config.ts, upload with one function call, drop a drag-and-drop widget on a page, and serve files back — public or private. Zero external dependencies (S3 is signed with a built-in AWS SigV4 implementation, like the rest of the framework).

Usage

Configure local and S3 stores

// wrnexus.config.ts
@@ -453,7 +453,7 @@ import { serveFromStore } from "@wrnexus/uploader";
 export const GET = serveFromStore("docs"); // your middleware decides who gets in
- + } diff --git a/app/pages/packages/validation.wrn b/app/pages/packages/validation.wrn index 3697dad0..1cbef12b 100644 --- a/app/pages/packages/validation.wrn +++ b/app/pages/packages/validation.wrn @@ -10,11 +10,11 @@ page wrnexusvalidation {
W WRNexusJS - +
-
Security · Package reference

@wrnexus/validation

Typed schemas, coercion, validation, and browser descriptors.

v0.4.0Private registrySecurity

Install the package

After WorkRoot approves private registry access, install the release-aligned package:

bun add @wrnexus/validation@0.4.0

Request preview access. Never put registry tokens in source control.

One fluent schema, validated on the server (API bodies, env vars) and mirrored to an eval-free browser validator for forms.
+
Security · Package reference

@wrnexus/validation

Typed schemas, coercion, validation, and browser descriptors.

v0.5.0Private registrySecurity

Install the package

After WorkRoot approves private registry access, install the release-aligned package:

bun add @wrnexus/validation@0.5.0

Request preview access. Never put registry tokens in source control.

One fluent schema, validated on the server (API bodies, env vars) and mirrored to an eval-free browser validator for forms.

Part of the WRNexusJS framework — an SSR-first, Bun-native full-stack web framework.

Overview

Define a schema once with the fluent v builder, then reuse it in three places: .parse() runs server-side and returns coerced values plus per-field errors; .describe() emits a plain-JSON SchemaDescriptor that the browser runtime interprets (no eval, no bundled validator); and helpers like parseBody and parseEnv wire schemas straight into API routes and startup config. The server rule logic (applyRule/checkField) and the client runtime (VALIDATE_RUNTIME) mirror each other exactly, so a form validates identically in both places. Schemas are conventionally kept in app/schemas/.

@@ -214,7 +214,7 @@ type RuleDescriptor = { message?: string; }; interface FieldDescriptor { - type: "string" | "number" | "boolean"; + type: "string" | "number" | "boolean" | "unknown"; optional?: boolean; /** Message used when a required field is empty. Defaults to "Required". */ requiredMessage?: string; @@ -250,7 +250,7 @@ type Refinement = { message?: string; }; declare abstract class FieldSchema { - abstract readonly type: "string" | "number" | "boolean"; + abstract readonly type: "string" | "number" | "boolean" | "unknown"; protected _optional: boolean; protected _requiredMessage?: string; protected _label?: string; @@ -296,9 +296,19 @@ declare class NumberSchema extends FieldSchema { declare class BooleanSchema extends FieldSchema { readonly type: "boolean"; } +declare class UnknownSchema extends FieldSchema { + readonly type: "unknown"; +} +type AnyFieldSchema = StringSchema | NumberSchema | BooleanSchema | UnknownSchema; declare class ObjectSchema { private readonly fields; constructor(fields: Record<string, FieldSchema>); + /** Return a defensive copy of the schema fields. */ + getFields(): Readonly<Record<string, FieldSchema>>; + /** Create a new schema with fields added or replaced. The original is unchanged. */ + extend(fields: Record<string, FieldSchema>): ObjectSchema; + /** Create a new schema containing fields from both schemas. */ + merge(schema: ObjectSchema): ObjectSchema; /** Validate an input object; returns coerced values + per-field errors. */ parse(input: unknown): ParseResult; describe(): SchemaDescriptor; @@ -308,6 +318,7 @@ declare const v: { string: () => StringSchema; number: () => NumberSchema; boolean: () => BooleanSchema; + unknown: () => UnknownSchema; object: (fields: Record<string, FieldSchema>) => ObjectSchema; }; /** @@ -337,7 +348,7 @@ declare function parseBody<T = Record<string, unknown>>(schema: Obje response: Response; }>; -export { AsyncObjectSchema, type AsyncRefinement, type AsyncValidationContext, type FieldDescriptor, ObjectSchema, type OpenApiSchema, type ParseResult, type RuleDescriptor, type SchemaDescriptor, VALIDATE_RUNTIME, applyRule, asyncSchema, checkField, invalid, mergeValidationResults, parseBody, parseBodyAsync, parseEnv, renderSchemasScript, schemaToOpenApi, v }; +export { type AnyFieldSchema, AsyncObjectSchema, type AsyncRefinement, type AsyncValidationContext, BooleanSchema, type FieldDescriptor, FieldSchema, NumberSchema, ObjectSchema, type OpenApiSchema, type ParseResult, type RuleDescriptor, type SchemaDescriptor, StringSchema, UnknownSchema, VALIDATE_RUNTIME, applyRule, asyncSchema, checkField, invalid, mergeValidationResults, parseBody, parseBodyAsync, parseEnv, renderSchemasScript, schemaToOpenApi, v };

Examples

Copy-ready examples from the installed package documentation.

Define a schema and validate an API body

import { v, parseBody } from "@wrnexus/validation";
 
 export const signupSchema = v.object({
@@ -373,7 +384,7 @@ const head = `<script>${renderSchemasScript({ signup: signupSche
 // render a <form data-schema="signup"> with [data-error="email"] etc.
- + } diff --git a/app/pages/releases/0.5.0.wrn b/app/pages/releases/0.5.0.wrn new file mode 100644 index 00000000..489d53bf --- /dev/null +++ b/app/pages/releases/0.5.0.wrn @@ -0,0 +1,17 @@ +page Release050 { + seo { + title = "Release 0.5.0" + description = "WRNexusJS 0.5.0 release notes." + canonical = "https://wrnexusjs.dev/releases/0.5.0" + } + view { + +
+
W WRNexusJS
+ +

WRNexusJS 0.5.0

Released 2026-07-13. All 31 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.

+ + +
+ } +} \ No newline at end of file diff --git a/app/pages/roadmap.wrn b/app/pages/roadmap.wrn index 57053e74..b47432f5 100644 --- a/app/pages/roadmap.wrn +++ b/app/pages/roadmap.wrn @@ -7,10 +7,10 @@ page Roadmap { view {
-
W WRNexusJS
+
W WRNexusJS

Roadmap

Roadmap items are direction, not delivery commitments. Dates require explicit owner approval.

Now

  • Private preview onboarding and accurate package references
  • Runnable documentation fixtures and link/accessibility checks
  • License, support, and disclosure owner decisions

Next

  • Durable queue driver guidance
  • Expanded database/auth/realtime examples
  • Versioned release notes and migration fixtures

Later / exploration

  • Historical documentation selector
  • Maintained reproducible benchmarks
  • Broader mobile/native coverage
- +
} diff --git a/app/pages/search.wrn b/app/pages/search.wrn index d658e3c5..9c24c06f 100644 --- a/app/pages/search.wrn +++ b/app/pages/search.wrn @@ -7,10 +7,10 @@ page Search { view {
-
W WRNexusJS
+
W WRNexusJS
-

Search documentation

This build-time index is local and sends no query to a third party. Use your browser’s find command to filter this compact index.

Core documentation

Get started · Packages · Components · Language · Architecture

Guides

Project structure · Routing · Pages and components · Server data · API routes · Middleware · Forms and validation · Authentication · Authorization · Application security · Database · Uploads · Realtime · Pub/sub · Queues · Testing · Workspaces and gateway · Deployment · Configuration and profiles · Internationalization and themes · Mobile · Observability · Upgrading · Troubleshooting

Package APIs

@wrnexus/ai · @wrnexus/authz · @wrnexus/compiler · @wrnexus/core · @wrnexus/csr · @wrnexus/db · @wrnexus/dev-server · @wrnexus/encryption · @wrnexus/helpers · @wrnexus/i18n · @wrnexus/jwt · @wrnexus/mobile · @wrnexus/native · @wrnexus/oauth · @wrnexus/pubsub · @wrnexus/queue · @wrnexus/reactive · @wrnexus/router · @wrnexus/ssr · @wrnexus/styles · @wrnexus/test · @wrnexus/tracking · @wrnexus/ui · @wrnexus/uploader · @wrnexus/validation · @wrnexus/dev-toolbar · @wrnexus/syntax · @wrnexus/plugin · @wrnexus/captcha · @wrnexus/cli

- +

Search documentation

This build-time index is local and sends no query to a third party. Use your browser’s find command to filter this compact index.

Core documentation

Get started · Packages · Components · Language · Architecture

Guides

Project structure · Routing · Pages and components · Server data · API routes · Middleware · Forms and validation · Authentication · Authorization · Application security · Database · Uploads · Realtime · Pub/sub · Queues · Testing · Workspaces and gateway · Deployment · Configuration and profiles · Internationalization and themes · Mobile · Observability · Upgrading · Troubleshooting

Package APIs

@wrnexus/ai · @wrnexus/authz · @wrnexus/compiler · @wrnexus/core · @wrnexus/csr · @wrnexus/db · @wrnexus/dev-server · @wrnexus/encryption · @wrnexus/helpers · @wrnexus/i18n · @wrnexus/jwt · @wrnexus/mobile · @wrnexus/native · @wrnexus/oauth · @wrnexus/pubsub · @wrnexus/queue · @wrnexus/reactive · @wrnexus/router · @wrnexus/ssr · @wrnexus/styles · @wrnexus/test · @wrnexus/tracking · @wrnexus/ui · @wrnexus/uploader · @wrnexus/validation · @wrnexus/dev-toolbar · @wrnexus/syntax · @wrnexus/plugin · @wrnexus/captcha · @wrnexus/auth · @wrnexus/cli

+
} diff --git a/app/pages/security.wrn b/app/pages/security.wrn index f14328e8..37da7410 100644 --- a/app/pages/security.wrn +++ b/app/pages/security.wrn @@ -7,10 +7,10 @@ page Security { view {
-
W WRNexusJS
+
W WRNexusJS
-

Security

WRNexusJS provides primitives for CSP, CSRF, Trusted Types, sessions, validation, authorization, encryption, upload restrictions, request limits, and WebSocket-origin checks. Applications remain responsible for correct configuration, business authorization, secrets, dependencies, data protection, and operations.

Supported releases

Only the current private-preview release 0.4.0 is documented here. A formal old-release support window is not yet published.

Report a vulnerability

Use WorkRoot’s approved private contact path at workroot.in. Do not publish exploit details or secrets. Include affected version, impact, reproduction, and a safe contact method. Response targets, encryption key, bounty, audit, and certification are not currently claimed.

Deployment controls

Use restrictive CSP and permissions policies, HSTS only on HTTPS production origins, MIME sniffing protection, restrictive referrers, explicit CORS, secure cookies, CSRF validation, request limits, and origin checks. See application security.

- +

Security

WRNexusJS provides primitives for CSP, CSRF, Trusted Types, sessions, validation, authorization, encryption, upload restrictions, request limits, and WebSocket-origin checks. Applications remain responsible for correct configuration, business authorization, secrets, dependencies, data protection, and operations.

Supported releases

Only the current private-preview release 0.5.0 is documented here. A formal old-release support window is not yet published.

Report a vulnerability

Use WorkRoot’s approved private contact path at workroot.in. Do not publish exploit details or secrets. Include affected version, impact, reproduction, and a safe contact method. Response targets, encryption key, bounty, audit, and certification are not currently claimed.

Deployment controls

Use restrictive CSP and permissions policies, HSTS only on HTTPS production origins, MIME sniffing protection, restrictive referrers, explicit CORS, secure cookies, CSRF validation, request limits, and origin checks. See application security.

+
} diff --git a/app/pages/showcase.wrn b/app/pages/showcase.wrn index 696f1f9d..4e67648a 100644 --- a/app/pages/showcase.wrn +++ b/app/pages/showcase.wrn @@ -7,10 +7,10 @@ page Showcase { view {
-
W WRNexusJS
+
W WRNexusJS
-

Showcase

Only confirmed public properties are listed; no customer or traffic claims are made.

WorkRoot

Creator/company site demonstrating a public WRNexusJS deployment. Exact deployed version and infrastructure notes await owner confirmation.

WRNexusJS docs

This documentation portal, built and verified against WRNexusJS 0.4.0 on Bun.

Screenshots are intentionally deferred until approved assets and alt text are available.

- +

Showcase

Only confirmed public properties are listed; no customer or traffic claims are made.

WorkRoot

Creator/company site demonstrating a public WRNexusJS deployment. Exact deployed version and infrastructure notes await owner confirmation.

WRNexusJS docs

This documentation portal, built and verified against WRNexusJS 0.5.0 on Bun.

Screenshots are intentionally deferred until approved assets and alt text are available.

+
} diff --git a/app/pages/support.wrn b/app/pages/support.wrn index c2187fc2..4c89de04 100644 --- a/app/pages/support.wrn +++ b/app/pages/support.wrn @@ -7,10 +7,10 @@ page Support { view {
-
W WRNexusJS
+
W WRNexusJS

Support

WRNexusJS has no public Discord, public issue tracker, or guaranteed community support channel listed by this repository. Preview access and support begin through WorkRoot’s public contact path.

Include WRNexusJS version, Bun version, OS, a minimal reproduction, expected and actual behavior, and sanitized logs. Never include registry tokens, credentials, session cookies, or private data.

Support scope, service levels, and commercial terms require owner confirmation.

- +
} diff --git a/app/pages/tutorial.wrn b/app/pages/tutorial.wrn index eef0a137..b19d823c 100644 --- a/app/pages/tutorial.wrn +++ b/app/pages/tutorial.wrn @@ -7,9 +7,9 @@ page Tutorial { view {
-
W WRNexusJS
+
W WRNexusJS
-
Preview · runnable-project extraction pending

Secure task board

This tutorial connects the installed 0.4.0 APIs into one design. Snippets are limited to declarations and README patterns verified in the installed packages; a CI-compiled standalone fixture remains on the roadmap.

Application shape

A .wrn page renders tasks from an SSR API binding. A shared validation schema protects mutations. Session middleware identifies users, authorization policies gate updates, and a realtime room broadcasts changes.

Schema and create route

import { v, parseBody } from "@wrnexus/validation";
+      
Preview · runnable-project extraction pending

Secure task board

This tutorial connects the installed 0.5.0 APIs into one design. Snippets are limited to declarations and README patterns verified in the installed packages; a CI-compiled standalone fixture remains on the roadmap.

Application shape

A .wrn page renders tasks from an SSR API binding. A shared validation schema protects mutations. Session middleware identifies users, authorization policies gate updates, and a realtime room broadcasts changes.

Schema and create route

import { v, parseBody } from "@wrnexus/validation";
 const task = v.object({ title: v.string().trim().min(3).max(120) });
 export const POST = async (ctx) => {
   const parsed = await parseBody(task, ctx.req);
@@ -23,7 +23,7 @@ export const POST = async (ctx) => {
     </ul></main>
   }
 }

Production checklist

  • Choose SQLite for local development or configure the supported PostgreSQL driver.
  • Run migrations before accepting traffic.
  • Enable session authentication and enforce authorization on every mutation.
  • Validate upload types and sizes; keep private objects behind authenticated routes.
  • Use Redis pub/sub when realtime rooms span processes.
  • Treat the default queue as non-durable until a production driver is selected.

Follow the focused database, authentication, authorization, realtime, and upload guides.

- +
} diff --git a/bun.lock b/bun.lock index 4e19ed21..13926eab 100644 --- a/bun.lock +++ b/bun.lock @@ -7,42 +7,43 @@ "dependencies": { "@iconify-json/lucide": "^1.2.118", "@iconify/tailwind4": "^1.2.3", - "@wrnexus/ai": "^0.4.0", - "@wrnexus/authz": "^0.4.0", - "@wrnexus/captcha": "^0.4.0", - "@wrnexus/compiler": "^0.4.0", - "@wrnexus/core": "^0.4.0", - "@wrnexus/csr": "^0.4.0", - "@wrnexus/db": "^0.4.0", - "@wrnexus/dev-server": "^0.4.0", - "@wrnexus/dev-toolbar": "^0.4.0", - "@wrnexus/encryption": "^0.4.0", - "@wrnexus/helpers": "^0.4.0", - "@wrnexus/i18n": "^0.4.0", - "@wrnexus/jwt": "^0.4.0", - "@wrnexus/mobile": "^0.4.0", - "@wrnexus/native": "^0.4.0", - "@wrnexus/oauth": "^0.4.0", - "@wrnexus/plugin": "^0.4.0", - "@wrnexus/pubsub": "^0.4.0", - "@wrnexus/queue": "^0.4.0", - "@wrnexus/reactive": "^0.4.0", - "@wrnexus/router": "^0.4.0", - "@wrnexus/ssr": "^0.4.0", - "@wrnexus/styles": "^0.4.0", - "@wrnexus/syntax": "^0.4.0", - "@wrnexus/test": "^0.4.0", - "@wrnexus/tracking": "^0.4.0", - "@wrnexus/ui": "^0.4.0", - "@wrnexus/uploader": "^0.4.0", - "@wrnexus/validation": "^0.4.0", + "@wrnexus/ai": "^0.5.0", + "@wrnexus/auth": "^0.5.0", + "@wrnexus/authz": "^0.5.0", + "@wrnexus/captcha": "^0.5.0", + "@wrnexus/compiler": "^0.5.0", + "@wrnexus/core": "^0.5.0", + "@wrnexus/csr": "^0.5.0", + "@wrnexus/db": "^0.5.0", + "@wrnexus/dev-server": "^0.5.0", + "@wrnexus/dev-toolbar": "^0.5.0", + "@wrnexus/encryption": "^0.5.0", + "@wrnexus/helpers": "^0.5.0", + "@wrnexus/i18n": "^0.5.0", + "@wrnexus/jwt": "^0.5.0", + "@wrnexus/mobile": "^0.5.0", + "@wrnexus/native": "^0.5.0", + "@wrnexus/oauth": "^0.5.0", + "@wrnexus/plugin": "^0.5.0", + "@wrnexus/pubsub": "^0.5.0", + "@wrnexus/queue": "^0.5.0", + "@wrnexus/reactive": "^0.5.0", + "@wrnexus/router": "^0.5.0", + "@wrnexus/ssr": "^0.5.0", + "@wrnexus/styles": "^0.5.0", + "@wrnexus/syntax": "^0.5.0", + "@wrnexus/test": "^0.5.0", + "@wrnexus/tracking": "^0.5.0", + "@wrnexus/ui": "^0.5.0", + "@wrnexus/uploader": "^0.5.0", + "@wrnexus/validation": "^0.5.0", }, "devDependencies": { "@eslint/js": "^9.0.0", "@tailwindcss/cli": "^4.0.0", "@types/bun": "latest", "@types/node": "^26.1.1", - "@wrnexus/cli": "^0.4.0", + "@wrnexus/cli": "^0.5.0", "eslint": "^9.0.0", "prettier": "latest", "tailwindcss": "^4.0.0", @@ -190,65 +191,67 @@ "@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.63.0", "", { "dependencies": { "@typescript-eslint/types": "8.63.0", "eslint-visitor-keys": "^5.0.0" } }, "sha512-UexrHGnGTpbuQHct2ExOc2ZcFbGUS9FOesCxxqdBGcpI1BxYu/LZ6U8Aq6/72XtF/qRBk9nhuGHFJIXXMhPMdw=="], - "@wrnexus/ai": ["@wrnexus/ai@0.4.0", "", {}, "sha512-fbblrY0suzPu+mhmF7S3uVogxW/ze4Gdvlms6k2ex9McQV+w9KM0Zkv2C124ImY34HyC/uVKayL12edih0ourg=="], + "@wrnexus/ai": ["@wrnexus/ai@0.5.0", "", {}, "sha512-dDd52mo1d+hF+Wly1/A98SAXdJDvB41X1Bo4oH+5qZd540lDZ+cZgR9kcpPj0hp6WySt6dMZ53nDiiOV9xkOkg=="], - "@wrnexus/authz": ["@wrnexus/authz@0.4.0", "", {}, "sha512-3mj2/DIPG0qgNsjew8GYPq0y+7XJPKxkcMxveXdOBprFSiEgqcMcqJcthX/AlJ3VZuwQcurNOFcouJPe0Y3A3w=="], + "@wrnexus/auth": ["@wrnexus/auth@0.5.0", "", { "dependencies": { "@wrnexus/authz": "^0.5.0", "@wrnexus/captcha": "^0.5.0", "@wrnexus/core": "^0.5.0", "@wrnexus/db": "^0.5.0", "@wrnexus/encryption": "^0.5.0", "@wrnexus/jwt": "^0.5.0", "@wrnexus/oauth": "^0.5.0", "@wrnexus/plugin": "^0.5.0", "@wrnexus/queue": "^0.5.0", "@wrnexus/validation": "^0.5.0" } }, "sha512-k7499JNApJGEoFRxGXVVJXJ6INMejs2moKrUxuDwsjtsPmUJBNx+actHB0wW0XldK2Ou8MP6F9OSalJh+Pt5Sg=="], - "@wrnexus/captcha": ["@wrnexus/captcha@0.4.0", "", { "dependencies": { "@wrnexus/core": "^0.4.0", "@wrnexus/plugin": "^0.4.0", "@wrnexus/validation": "^0.4.0" } }, "sha512-PFi6i6h7vMUHbReJ3tAtcGq7TrDVQLCgC+CWczT70gMszVo9+Mhh+TNkINlzUL1WUFwChnrL/K6U5xRWcYfDVg=="], + "@wrnexus/authz": ["@wrnexus/authz@0.5.0", "", {}, "sha512-k4qHI0ZrmEFwIJIvhEZqbc4l49aEgMfyJhAqgd3o4wjrSlbJas/j0te83A4TEuc5arqMUDiWeOHVzgaXsCrGoA=="], - "@wrnexus/cli": ["@wrnexus/cli@0.4.0", "", { "dependencies": { "@wrnexus/compiler": "^0.4.0", "@wrnexus/core": "^0.4.0", "@wrnexus/csr": "^0.4.0", "@wrnexus/db": "^0.4.0", "@wrnexus/dev-server": "^0.4.0", "@wrnexus/i18n": "^0.4.0", "@wrnexus/plugin": "^0.4.0", "@wrnexus/router": "^0.4.0", "@wrnexus/styles": "^0.4.0", "@wrnexus/syntax": "^0.4.0", "@wrnexus/ui": "^0.4.0", "@wrnexus/validation": "^0.4.0" }, "bin": { "wrnexus": "dist/index.js" } }, "sha512-I4bE61wov5B8USlJYDlqhSutHHXo4QezUYjZesbowN/AKBqEN4rSfKGapCqFjl6VScl3llMsRr/bkYP6+aIZTg=="], + "@wrnexus/captcha": ["@wrnexus/captcha@0.5.0", "", { "dependencies": { "@wrnexus/core": "^0.5.0", "@wrnexus/plugin": "^0.5.0", "@wrnexus/validation": "^0.5.0" } }, "sha512-/eMywZkIHr+1f3I9ZG9RJzqASjig89Ud7EeATz+PnPta8aMMrX/hiikcKWQth9EOirO8bj4lxI8FFM3usX8Yxg=="], - "@wrnexus/compiler": ["@wrnexus/compiler@0.4.0", "", { "dependencies": { "@wrnexus/syntax": "^0.4.0" } }, "sha512-E0Uj4AYN9JcDDZhhk2QNBM3VioxtP5Q+ASYV33ivgrXPXmmHwDi0Xtfa3D1U3nn7UmdxneBnE57S7Oyy8MBM+w=="], + "@wrnexus/cli": ["@wrnexus/cli@0.5.0", "", { "dependencies": { "@wrnexus/compiler": "^0.5.0", "@wrnexus/core": "^0.5.0", "@wrnexus/csr": "^0.5.0", "@wrnexus/db": "^0.5.0", "@wrnexus/dev-server": "^0.5.0", "@wrnexus/i18n": "^0.5.0", "@wrnexus/plugin": "^0.5.0", "@wrnexus/router": "^0.5.0", "@wrnexus/styles": "^0.5.0", "@wrnexus/syntax": "^0.5.0", "@wrnexus/ui": "^0.5.0", "@wrnexus/validation": "^0.5.0" }, "bin": { "wrnexus": "dist/index.js" } }, "sha512-ZdPNdROxXlHgCngRqBpZXJIEjFedcVsgEkNOBroG78ehLj88wYWotzANRDYsAaHpFq5nZBuEJNbNFdd/nECsgQ=="], - "@wrnexus/core": ["@wrnexus/core@0.4.0", "", {}, "sha512-N4Y6O0gSaNEKK24gBu4YTsXBnLnFjaY2WUlobTUOHcV2/h0MOuXjVc6dolQZnRjkza541Wg+exKu6OKmaMQDjg=="], + "@wrnexus/compiler": ["@wrnexus/compiler@0.5.0", "", { "dependencies": { "@wrnexus/syntax": "^0.5.0" } }, "sha512-94ccs3AU1gRM360VMIGqhLvc3czzV9KsNjV3W6On1NbVGRyKnUwTuHj5+UOplb5zfn+UlyTxJhS7bEB2rZgykg=="], - "@wrnexus/csr": ["@wrnexus/csr@0.4.0", "", { "dependencies": { "@wrnexus/core": "^0.4.0" } }, "sha512-bCu/oonwrIu7rk8F2p2hZ0ch6ijEPeEUPxv021+meOVvj/67GFAS01vaxX5B/Iia0c2Sf+saeIhCtXh/sz72QA=="], + "@wrnexus/core": ["@wrnexus/core@0.5.0", "", {}, "sha512-X5hrY6ib2pvpUHplz0KMCHV7SPVfY9eP4J99SI39efXuL2ekMd6Vr7ueh+MixscgBinjG8YdPTo/xs0gYwRx0A=="], - "@wrnexus/db": ["@wrnexus/db@0.4.0", "", {}, "sha512-FjjWEF+/mKbmpfL5hGMilcon+uvSbXdTUwuR1ehtRP8Eldg8WqHICYkQtVB5mRnBu8lqwhsfdE5uYbK/a9Jhkg=="], + "@wrnexus/csr": ["@wrnexus/csr@0.5.0", "", { "dependencies": { "@wrnexus/core": "^0.5.0" } }, "sha512-sL4B/I7/oTtv/JC4HFSc9qGIW0f23bwTS9M0R9P7x5/LZibTOV9QbktpPJbWrcd+fVLHFXUb/LkicuugCgj81g=="], - "@wrnexus/dev-server": ["@wrnexus/dev-server@0.4.0", "", { "dependencies": { "@wrnexus/compiler": "^0.4.0", "@wrnexus/core": "^0.4.0", "@wrnexus/csr": "^0.4.0", "@wrnexus/db": "^0.4.0", "@wrnexus/dev-toolbar": "^0.4.0", "@wrnexus/i18n": "^0.4.0", "@wrnexus/plugin": "^0.4.0", "@wrnexus/pubsub": "^0.4.0", "@wrnexus/router": "^0.4.0", "@wrnexus/ssr": "^0.4.0", "@wrnexus/styles": "^0.4.0", "@wrnexus/ui": "^0.4.0", "@wrnexus/uploader": "^0.4.0", "@wrnexus/validation": "^0.4.0" } }, "sha512-g2NKtIGjWNt3iOppEjt3e7XUQIYqS+yaybzTnCI4KFU31nQwqB8lpr9wl4l7iXD6brBlo0bUBl9c4btfGufgqQ=="], + "@wrnexus/db": ["@wrnexus/db@0.5.0", "", {}, "sha512-RcKnaHZuf+vvBw9ew3MxuOy5CXL5H0NvejlvnPLNFBGj0bpiPbCPh0+G6P8u0Fk9xXe3tH3AGCPE07lQlMP2uA=="], - "@wrnexus/dev-toolbar": ["@wrnexus/dev-toolbar@0.4.0", "", {}, "sha512-O/bWHT1TZTsMvY0umVRELcaaw/CcGzjrI/2JNGjaRFrru1ahgF1oq7DNBhBTCfprot/8NI/DdxkVwbgiAfiMlw=="], + "@wrnexus/dev-server": ["@wrnexus/dev-server@0.5.0", "", { "dependencies": { "@wrnexus/compiler": "^0.5.0", "@wrnexus/core": "^0.5.0", "@wrnexus/csr": "^0.5.0", "@wrnexus/db": "^0.5.0", "@wrnexus/dev-toolbar": "^0.5.0", "@wrnexus/i18n": "^0.5.0", "@wrnexus/plugin": "^0.5.0", "@wrnexus/pubsub": "^0.5.0", "@wrnexus/router": "^0.5.0", "@wrnexus/ssr": "^0.5.0", "@wrnexus/styles": "^0.5.0", "@wrnexus/ui": "^0.5.0", "@wrnexus/uploader": "^0.5.0", "@wrnexus/validation": "^0.5.0" } }, "sha512-T3vF8h4Gxv0OnAa0K3pxvyQoEpOoyDDPTknOVVqCjYOb/9LxiK12MlUTUuHgzT6gZS4tLbrHwOjtJTuaFpIAhA=="], - "@wrnexus/encryption": ["@wrnexus/encryption@0.4.0", "", {}, "sha512-A+fs/mhl8hmdzRrWO3c2baI9L9VZAJEMje/GXI6Z+fVbV2RgN9rjJvCxVJlFAljx8VNllqN3psPMrQEh0ge3Nw=="], + "@wrnexus/dev-toolbar": ["@wrnexus/dev-toolbar@0.5.0", "", {}, "sha512-7WIz+/bZkp+Y+FXlDVVJOOCqHrVFI8RbvvShsXx5QRl+H88srtuIknA6QsM3vnrXh5hwabkhDZxPqwreeVrN5Q=="], - "@wrnexus/helpers": ["@wrnexus/helpers@0.4.0", "", { "dependencies": { "@wrnexus/core": "^0.4.0" } }, "sha512-bz5rsnKsgMC1PXqeuM7xbGnIaUsxF8vP01Is3xbUuFnftyNFy/fwb5zJVU/TPL3O2dft52e9vqOy1UbKBMH+Sg=="], + "@wrnexus/encryption": ["@wrnexus/encryption@0.5.0", "", {}, "sha512-4SL21R83ue4/AUcYFmKf+S4PMWl0EBzHvscoDT+WvkxmF3FCSfO0gGuolE8cMP7L25TkNO48h1Q2MOOlK19kww=="], - "@wrnexus/i18n": ["@wrnexus/i18n@0.4.0", "", { "dependencies": { "@wrnexus/core": "^0.4.0" } }, "sha512-wOyLplDrweV6UO5tOjhvhr8hyFCgNNlkONnaXUPFe8i11Xj+5bOtBo4cYsKR7KqbaAHG/Xx0AceBW5ppYheAow=="], + "@wrnexus/helpers": ["@wrnexus/helpers@0.5.0", "", { "dependencies": { "@wrnexus/core": "^0.5.0" } }, "sha512-wDqhRt1cmqkOFxF988IYDFXVRDBYMDliXO96tvNR4JlI/krpgny6oQzwX6Llgc3gwe2WPhGEKs53Qjolikr+cg=="], - "@wrnexus/jwt": ["@wrnexus/jwt@0.4.0", "", {}, "sha512-TJdwiSfk5hpQCY3Jnn9XHPVjo/BAJirLn3LxOSf7oA7toPuZ0t+Zegt3lyE1YocfbwRUXBhUzayojloJF0aINw=="], + "@wrnexus/i18n": ["@wrnexus/i18n@0.5.0", "", { "dependencies": { "@wrnexus/core": "^0.5.0" } }, "sha512-Tt+P+hCRXrxrT2n0YLqFyn1YH06FU2jqcfZrgdYaRhjpaEjHC/2Vq76wHQbcHIjIUewgYpvo/dOqJK93/7h+Ng=="], - "@wrnexus/mobile": ["@wrnexus/mobile@0.4.0", "", { "dependencies": { "@wrnexus/native": "^0.4.0" } }, "sha512-2IXD4WdK12y7SihqcF0iOE2zsUtIJ+SiI71k4E3LRaFjt2qFzcY/v77T8rSBHMVJLTlMJCEoYIxRcsC5NuHACA=="], + "@wrnexus/jwt": ["@wrnexus/jwt@0.5.0", "", {}, "sha512-nw30zfBO4vLcQ29kLgbraQfatItv4DwAVluS2T3eWXLHS59P9ZMXbYwjW8Gs6kdn3tdY0nRqgPShR+5wMNuY1A=="], - "@wrnexus/native": ["@wrnexus/native@0.4.0", "", {}, "sha512-SY1PxVk7Jsaus7ag7eUaQA1E6BKeL1PW0aWyks+6YnNnqkfyu+IObSVvoX7hxaWEDnNR+um+mcwwT+38pfcpcg=="], + "@wrnexus/mobile": ["@wrnexus/mobile@0.5.0", "", { "dependencies": { "@wrnexus/native": "^0.5.0" } }, "sha512-2tAVdMsClAfRJzOX28Iuo9DDyPClmnoMikx7LTXbmPXT3jYcmeHi4cLXePEk8ArGxA6wvP0lPk67JyyZHYOalw=="], - "@wrnexus/oauth": ["@wrnexus/oauth@0.4.0", "", {}, "sha512-eAlyvvXdJMTdbsQd5HpryjVU+jNB1RKNrYIo1RqDhiE/beApt2SlkcWkMUKub30iBZOtLDYekSZH1BJevuPtNA=="], + "@wrnexus/native": ["@wrnexus/native@0.5.0", "", {}, "sha512-c/o54ZJirCKtd6ls4ljab4lJWZQRYIwS9P4ajnibVHN5PHIHrdYtkk2Xut97CfIG8DDgsy5KL7agu4Y4wow6BQ=="], - "@wrnexus/plugin": ["@wrnexus/plugin@0.4.0", "", { "dependencies": { "@wrnexus/syntax": "^0.4.0" } }, "sha512-IOudqyNkiBUxylECudE1hpt6SG8Q3k3qffQzR+stEVTgTZz5HVWaRTaPk4d49/wC0tnzGE121HLVgDwF/KCubg=="], + "@wrnexus/oauth": ["@wrnexus/oauth@0.5.0", "", {}, "sha512-azKLvepX7oyswLtGMTTDCmjhFMGZ2FX8sn3i7hyYmeMFlBNjaXZYruvwZyUIa5Xi255GVy0Do7TOkvHyb122sA=="], - "@wrnexus/pubsub": ["@wrnexus/pubsub@0.4.0", "", {}, "sha512-SNrzUt+DFmriglzQRFbV2LysbIOV3CRQ4jUUtL9mgoX6vXtEbCrx/+nfoaYZRZgtqEk2YxEQR7gwUQ3PiiaziQ=="], + "@wrnexus/plugin": ["@wrnexus/plugin@0.5.0", "", { "dependencies": { "@wrnexus/syntax": "^0.5.0" } }, "sha512-8OVYE821ytS97Yg7GmmfSe4mod+02B+jRZ8TUhvHWw+/9FWCA72UEI4z9pbFMj4dUZpw5h0YWyVtl8vcAwqGvA=="], - "@wrnexus/queue": ["@wrnexus/queue@0.4.0", "", {}, "sha512-QoB/Hi4jnoWH+n4k2Qqiq3dPWugOxZq7blV4SfqfcrIRvDAmCuTqUzLL0p812XVvnyaXDaqeJxaMnwBA0DRFow=="], + "@wrnexus/pubsub": ["@wrnexus/pubsub@0.5.0", "", {}, "sha512-mKB6EOS3PtxD2eAzN8TzHpqWXWptMGDhO/UFSkLXyO/wTsyaMN52CqxI5TAtFDCiHNkAifIfQp7ObgWT35EoQA=="], - "@wrnexus/reactive": ["@wrnexus/reactive@0.4.0", "", {}, "sha512-XYthkvTdvILPY5ltLEP2WGRfC8/5h9td5n7bbrLGp3rzyirBRloDeiKIAtvXaw7uz1D7BiMZD6o4QdUJyXScrA=="], + "@wrnexus/queue": ["@wrnexus/queue@0.5.0", "", {}, "sha512-A2BbS+/TOluAdUYlu1a/4vCQCYyn5W+2vlfwAwPJMOay5EfotUX7LcGSi3cNG17mgwOP8rZ49Yxffhyuq7q9Zg=="], - "@wrnexus/router": ["@wrnexus/router@0.4.0", "", { "dependencies": { "@wrnexus/compiler": "^0.4.0", "@wrnexus/core": "^0.4.0" } }, "sha512-qEqN0haUkvhreGuO5DpZ+U3a7EhuBgD8rOabHb1wiK3/ltMA550W4BL1oOtEea/oAKMgrlQTjrsWniHOB9jNrg=="], + "@wrnexus/reactive": ["@wrnexus/reactive@0.5.0", "", {}, "sha512-YhR5L34j1FBixns3hLEZnjCl/IMCntzXz5TGxsC6jNKaU6RYa2mhhaoOi/+781eHz+3bEGB5kHQcXTqQ+cF0oQ=="], - "@wrnexus/ssr": ["@wrnexus/ssr@0.4.0", "", { "dependencies": { "@wrnexus/core": "^0.4.0" } }, "sha512-7Slmf94KifALpkihbls5ttTsWUndxMnsCOg/OXQszvxaVDbqUS/fP9fMYRHgoFSBI4nR+e6a3J51VGjdQbnJHw=="], + "@wrnexus/router": ["@wrnexus/router@0.5.0", "", { "dependencies": { "@wrnexus/compiler": "^0.5.0", "@wrnexus/core": "^0.5.0" } }, "sha512-y2ZKLltAWz6l4Jgf4K/HmBCiBOnAjFypBJbmL404G5d+UcIOd7/NYwZKaGaIG2WRMY+7WUpMLji++Bi7UXgVRg=="], - "@wrnexus/styles": ["@wrnexus/styles@0.4.0", "", { "dependencies": { "@wrnexus/core": "^0.4.0", "@wrnexus/plugin": "^0.4.0", "@wrnexus/uploader": "^0.4.0" } }, "sha512-kEVZX/nmBjvoUBbywyhzwM/XcURfmyb6asd7VrZjM3dvcUVCW28xLpcaMIRd/V74zUVJd283J5Oa9T89w5H6CA=="], + "@wrnexus/ssr": ["@wrnexus/ssr@0.5.0", "", { "dependencies": { "@wrnexus/core": "^0.5.0" } }, "sha512-vl4FwuZbeWrTrIhxr+/VqickC3bRNz4+zP/HgsSbatycWJaC9mhLp4rr2kS2id5I4EcJAL1eHMBcPxDFywqoNg=="], - "@wrnexus/syntax": ["@wrnexus/syntax@0.4.0", "", {}, "sha512-p2MF32Fw6jVtroSL2UwCY5S792vLogn6WATPXgcwkELadyHxHUl5vcgzAzYCb2hX9t8/qUsWFjKhNeTUZXsQmg=="], + "@wrnexus/styles": ["@wrnexus/styles@0.5.0", "", { "dependencies": { "@wrnexus/core": "^0.5.0", "@wrnexus/plugin": "^0.5.0", "@wrnexus/uploader": "^0.5.0" } }, "sha512-8UU1yXoF3dTUF085jrTjSA9xvERS5IUdXvEzT6H7/zorGaghIp8PB+IaL50kUEDT6oS2YZS2bZZ8kOnkI3uEXg=="], - "@wrnexus/test": ["@wrnexus/test@0.4.0", "", {}, "sha512-d3pYHQQltHgWuYI6QP68TkiUIiiHybCsXXx6JIwjudvWKeSKHMwpR7W50QOYQG3nbx//rwQsXV7wmLXQV5fpOA=="], + "@wrnexus/syntax": ["@wrnexus/syntax@0.5.0", "", {}, "sha512-5dh+VJ+/lE+M/HtllrOtNN67wow1moZlvKdlhPjymfaaEhshY6sWnOgrjDllDDDc+xuMHUBrkMUx6OUnSQASMA=="], - "@wrnexus/tracking": ["@wrnexus/tracking@0.4.0", "", {}, "sha512-7mBX29IX1h9d8OhHO38jDSmpkcoKWd6Y1LCXmgFS+mCatr6jXBs1xdhMGuvsyCbQBNJ8HMqICMP4ar4SNFvlfg=="], + "@wrnexus/test": ["@wrnexus/test@0.5.0", "", {}, "sha512-c+PfbLcWHp21r0FlnS1BKY/y+UUGREU8RYYOAYqQiPGX8CWhTEqd4Y2hKZZZeHDh3I1H5YLAX9y9hPv6bTuIbw=="], - "@wrnexus/ui": ["@wrnexus/ui@0.4.0", "", { "dependencies": { "@wrnexus/core": "^0.4.0" } }, "sha512-xDMyMyM066XBDgmQu1lNW/i+8caDL/4S3M9w6wfuXMXFLEDWCFkDhS2PZox5UY4E6TGWkBGYKYj54lzGZoSosg=="], + "@wrnexus/tracking": ["@wrnexus/tracking@0.5.0", "", {}, "sha512-EhtncSMK1QJQY2G4GbNaAAnuF10Ox/GqdL0/cM+rHrX19YQCDrET3f1VQs9pG2oqRi0CcO46EDfVfFK29rA2ug=="], - "@wrnexus/uploader": ["@wrnexus/uploader@0.4.0", "", { "dependencies": { "@wrnexus/core": "^0.4.0" } }, "sha512-Hc6jfPEl7jGokgNkIpP7dAQrQrwFZcUHNT1FfnN4CI1gcQfLLsx2VMZv68V84Zq9lDHYNjJOZqK768v8yUTOMQ=="], + "@wrnexus/ui": ["@wrnexus/ui@0.5.0", "", { "dependencies": { "@wrnexus/core": "^0.5.0" } }, "sha512-ECXlUp7aYOA5E/pWnHoNL8m+vvaWHCD2hFrG62xFSKFoGgP18KrP6IIYGwb6plB93QfDsCLObQicOhmxo9GGCQ=="], - "@wrnexus/validation": ["@wrnexus/validation@0.4.0", "", {}, "sha512-Eytpznn0+7Q4xDGTDIdvlLezw2wOEtps1yvTHzYcoHASxpp560x11PBppd4eD+2sbhjBM5xa8wkdPsejg1Ga1g=="], + "@wrnexus/uploader": ["@wrnexus/uploader@0.5.0", "", { "dependencies": { "@wrnexus/core": "^0.5.0" } }, "sha512-MiFCydGpWjl5BA5yET5ZuVKmZkm0zfCljWB0ZEG1mxSlFv3DpVZCnDkB5DZZKCIByGfpV8q4p/LVWuSFqgAH3w=="], + + "@wrnexus/validation": ["@wrnexus/validation@0.5.0", "", {}, "sha512-/YRV48clsSV5n4HgWDgKXWE/h+AiMcr0MmScQlZ1lJE48LXKN4OS+yAzAWVT/+jgvomUkMZKLDu5Quc1H0gjXQ=="], "acorn": ["acorn@8.17.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg=="], diff --git a/docs/documentation-coverage-matrix.md b/docs/documentation-coverage-matrix.md index 17289a74..623b5eb0 100644 --- a/docs/documentation-coverage-matrix.md +++ b/docs/documentation-coverage-matrix.md @@ -3,6 +3,7 @@ | Area | Package reference | Concept guide | Runnable fixture | Tests | Stability | Limitation | | -------------------- | --------------------- | ---------------------------- | ---------------- | ------------------ | ------------ | ------------------------ | | @wrnexus/ai | /packages/ai | Architecture/package guide | Planned | Generator coverage | Preview | No standalone CI fixture | +| @wrnexus/auth | /packages/auth | Architecture/package guide | Planned | Generator coverage | Preview | No standalone CI fixture | | @wrnexus/authz | /packages/authz | /guides/authorization | Planned | Generator coverage | Preview | No standalone CI fixture | | @wrnexus/captcha | /packages/captcha | Architecture/package guide | Planned | Generator coverage | Preview | No standalone CI fixture | | @wrnexus/cli | /packages/cli | Architecture/package guide | Planned | Generator coverage | Preview | No standalone CI fixture | diff --git a/docs/release-access-status.md b/docs/release-access-status.md index aa6d4bc3..4ee66647 100644 --- a/docs/release-access-status.md +++ b/docs/release-access-status.md @@ -2,6 +2,6 @@ ## Decision: Mode B — Private Developer Preview -Active version: 0.4.0, derived from package.json#wrnexus.version. All 30 installed @wrnexus packages resolve to 0.4.0 and npm reports restricted access. The repository remote is a private WorkRoot Git service and no public license file exists. +Active version: 0.5.0, derived from package.json#wrnexus.version. All 31 installed @wrnexus packages resolve to 0.5.0 and npm reports restricted access. The repository remote is a private WorkRoot Git service and no public license file exists. -External users cannot execute an installation without approved private registry credentials. The truthful CTA is Request preview access. After approval, the canonical command is bunx @wrnexus/cli@0.4.0 create my-app. Tokens must never appear in documentation or source. +External users cannot execute an installation without approved private registry credentials. The truthful CTA is Request preview access. After approval, the canonical command is bunx @wrnexus/cli@0.5.0 create my-app. Tokens must never appear in documentation or source. diff --git a/docs/site-audit.md b/docs/site-audit.md index 3a17133f..c1fe6b61 100644 --- a/docs/site-audit.md +++ b/docs/site-audit.md @@ -1,18 +1,18 @@ # WRNexusJS site audit -Date: 2026-07-13. Baseline: Bun 1.3.14, framework 0.4.0. +Date: 2026-07-13. Baseline: Bun 1.3.14, framework 0.5.0. ## Baseline results - authenticated private-registry installation: pass. -- docs generation: pass (30 package pages plus portal and guide pages). +- docs generation: pass (31 package pages plus portal and guide pages). - tests, lint, formatting, and production build are required by the release check. - package access remains restricted/private. - repository: private WorkRoot Git remote; no public license file exists. ## Findings -Package documentation, discovery assets, and AI-readable references are generated from the installed release. The 0.4.0 portal includes the helpers package, workspace app addition, and safe forward-auth login redirect guidance. +Package documentation, discovery assets, and AI-readable references are generated from the installed release. The 0.5.0 portal includes the helpers package, workspace app addition, and safe forward-auth login redirect guidance. ## Audit limitations diff --git a/package-lock.json b/package-lock.json index 3388ed0b..0264a91e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,42 +10,43 @@ "dependencies": { "@iconify-json/lucide": "^1.2.118", "@iconify/tailwind4": "^1.2.3", - "@wrnexus/ai": "^0.4.0", - "@wrnexus/authz": "^0.4.0", - "@wrnexus/captcha": "^0.4.0", - "@wrnexus/compiler": "^0.4.0", - "@wrnexus/core": "^0.4.0", - "@wrnexus/csr": "^0.4.0", - "@wrnexus/db": "^0.4.0", - "@wrnexus/dev-server": "^0.4.0", - "@wrnexus/dev-toolbar": "^0.4.0", - "@wrnexus/encryption": "^0.4.0", - "@wrnexus/helpers": "^0.4.0", - "@wrnexus/i18n": "^0.4.0", - "@wrnexus/jwt": "^0.4.0", - "@wrnexus/mobile": "^0.4.0", - "@wrnexus/native": "^0.4.0", - "@wrnexus/oauth": "^0.4.0", - "@wrnexus/plugin": "^0.4.0", - "@wrnexus/pubsub": "^0.4.0", - "@wrnexus/queue": "^0.4.0", - "@wrnexus/reactive": "^0.4.0", - "@wrnexus/router": "^0.4.0", - "@wrnexus/ssr": "^0.4.0", - "@wrnexus/styles": "^0.4.0", - "@wrnexus/syntax": "^0.4.0", - "@wrnexus/test": "^0.4.0", - "@wrnexus/tracking": "^0.4.0", - "@wrnexus/ui": "^0.4.0", - "@wrnexus/uploader": "^0.4.0", - "@wrnexus/validation": "^0.4.0" + "@wrnexus/ai": "^0.5.0", + "@wrnexus/auth": "^0.5.0", + "@wrnexus/authz": "^0.5.0", + "@wrnexus/captcha": "^0.5.0", + "@wrnexus/compiler": "^0.5.0", + "@wrnexus/core": "^0.5.0", + "@wrnexus/csr": "^0.5.0", + "@wrnexus/db": "^0.5.0", + "@wrnexus/dev-server": "^0.5.0", + "@wrnexus/dev-toolbar": "^0.5.0", + "@wrnexus/encryption": "^0.5.0", + "@wrnexus/helpers": "^0.5.0", + "@wrnexus/i18n": "^0.5.0", + "@wrnexus/jwt": "^0.5.0", + "@wrnexus/mobile": "^0.5.0", + "@wrnexus/native": "^0.5.0", + "@wrnexus/oauth": "^0.5.0", + "@wrnexus/plugin": "^0.5.0", + "@wrnexus/pubsub": "^0.5.0", + "@wrnexus/queue": "^0.5.0", + "@wrnexus/reactive": "^0.5.0", + "@wrnexus/router": "^0.5.0", + "@wrnexus/ssr": "^0.5.0", + "@wrnexus/styles": "^0.5.0", + "@wrnexus/syntax": "^0.5.0", + "@wrnexus/test": "^0.5.0", + "@wrnexus/tracking": "^0.5.0", + "@wrnexus/ui": "^0.5.0", + "@wrnexus/uploader": "^0.5.0", + "@wrnexus/validation": "^0.5.0" }, "devDependencies": { "@eslint/js": "^9.0.0", "@tailwindcss/cli": "^4.0.0", "@types/bun": "latest", "@types/node": "^26.1.1", - "@wrnexus/cli": "^0.4.0", + "@wrnexus/cli": "^0.5.0", "eslint": "^9.0.0", "prettier": "latest", "tailwindcss": "^4.0.0", @@ -1305,56 +1306,77 @@ } }, "node_modules/@wrnexus/ai": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@wrnexus/ai/-/ai-0.4.0.tgz", - "integrity": "sha512-fbblrY0suzPu+mhmF7S3uVogxW/ze4Gdvlms6k2ex9McQV+w9KM0Zkv2C124ImY34HyC/uVKayL12edih0ourg==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@wrnexus/ai/-/ai-0.5.0.tgz", + "integrity": "sha512-dDd52mo1d+hF+Wly1/A98SAXdJDvB41X1Bo4oH+5qZd540lDZ+cZgR9kcpPj0hp6WySt6dMZ53nDiiOV9xkOkg==", "license": "MIT", "engines": { "bun": ">=1.3.0" } }, + "node_modules/@wrnexus/auth": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@wrnexus/auth/-/auth-0.5.0.tgz", + "integrity": "sha512-k7499JNApJGEoFRxGXVVJXJ6INMejs2moKrUxuDwsjtsPmUJBNx+actHB0wW0XldK2Ou8MP6F9OSalJh+Pt5Sg==", + "license": "MIT", + "dependencies": { + "@wrnexus/authz": "^0.5.0", + "@wrnexus/captcha": "^0.5.0", + "@wrnexus/core": "^0.5.0", + "@wrnexus/db": "^0.5.0", + "@wrnexus/encryption": "^0.5.0", + "@wrnexus/jwt": "^0.5.0", + "@wrnexus/oauth": "^0.5.0", + "@wrnexus/plugin": "^0.5.0", + "@wrnexus/queue": "^0.5.0", + "@wrnexus/validation": "^0.5.0" + }, + "engines": { + "bun": ">=1.3.0" + } + }, "node_modules/@wrnexus/authz": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@wrnexus/authz/-/authz-0.4.0.tgz", - "integrity": "sha512-3mj2/DIPG0qgNsjew8GYPq0y+7XJPKxkcMxveXdOBprFSiEgqcMcqJcthX/AlJ3VZuwQcurNOFcouJPe0Y3A3w==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@wrnexus/authz/-/authz-0.5.0.tgz", + "integrity": "sha512-k4qHI0ZrmEFwIJIvhEZqbc4l49aEgMfyJhAqgd3o4wjrSlbJas/j0te83A4TEuc5arqMUDiWeOHVzgaXsCrGoA==", "license": "MIT", "engines": { "bun": ">=1.3.0" } }, "node_modules/@wrnexus/captcha": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@wrnexus/captcha/-/captcha-0.4.0.tgz", - "integrity": "sha512-PFi6i6h7vMUHbReJ3tAtcGq7TrDVQLCgC+CWczT70gMszVo9+Mhh+TNkINlzUL1WUFwChnrL/K6U5xRWcYfDVg==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@wrnexus/captcha/-/captcha-0.5.0.tgz", + "integrity": "sha512-/eMywZkIHr+1f3I9ZG9RJzqASjig89Ud7EeATz+PnPta8aMMrX/hiikcKWQth9EOirO8bj4lxI8FFM3usX8Yxg==", "license": "MIT", "dependencies": { - "@wrnexus/core": "^0.4.0", - "@wrnexus/plugin": "^0.4.0", - "@wrnexus/validation": "^0.4.0" + "@wrnexus/core": "^0.5.0", + "@wrnexus/plugin": "^0.5.0", + "@wrnexus/validation": "^0.5.0" }, "engines": { "bun": ">=1.3.0" } }, "node_modules/@wrnexus/cli": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@wrnexus/cli/-/cli-0.4.0.tgz", - "integrity": "sha512-I4bE61wov5B8USlJYDlqhSutHHXo4QezUYjZesbowN/AKBqEN4rSfKGapCqFjl6VScl3llMsRr/bkYP6+aIZTg==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@wrnexus/cli/-/cli-0.5.0.tgz", + "integrity": "sha512-ZdPNdROxXlHgCngRqBpZXJIEjFedcVsgEkNOBroG78ehLj88wYWotzANRDYsAaHpFq5nZBuEJNbNFdd/nECsgQ==", "dev": true, "license": "MIT", "dependencies": { - "@wrnexus/compiler": "^0.4.0", - "@wrnexus/core": "^0.4.0", - "@wrnexus/csr": "^0.4.0", - "@wrnexus/db": "^0.4.0", - "@wrnexus/dev-server": "^0.4.0", - "@wrnexus/i18n": "^0.4.0", - "@wrnexus/plugin": "^0.4.0", - "@wrnexus/router": "^0.4.0", - "@wrnexus/styles": "^0.4.0", - "@wrnexus/syntax": "^0.4.0", - "@wrnexus/ui": "^0.4.0", - "@wrnexus/validation": "^0.4.0" + "@wrnexus/compiler": "^0.5.0", + "@wrnexus/core": "^0.5.0", + "@wrnexus/csr": "^0.5.0", + "@wrnexus/db": "^0.5.0", + "@wrnexus/dev-server": "^0.5.0", + "@wrnexus/i18n": "^0.5.0", + "@wrnexus/plugin": "^0.5.0", + "@wrnexus/router": "^0.5.0", + "@wrnexus/styles": "^0.5.0", + "@wrnexus/syntax": "^0.5.0", + "@wrnexus/ui": "^0.5.0", + "@wrnexus/validation": "^0.5.0" }, "bin": { "wrnexus": "dist/index.js" @@ -1364,286 +1386,286 @@ } }, "node_modules/@wrnexus/compiler": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@wrnexus/compiler/-/compiler-0.4.0.tgz", - "integrity": "sha512-E0Uj4AYN9JcDDZhhk2QNBM3VioxtP5Q+ASYV33ivgrXPXmmHwDi0Xtfa3D1U3nn7UmdxneBnE57S7Oyy8MBM+w==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@wrnexus/compiler/-/compiler-0.5.0.tgz", + "integrity": "sha512-94ccs3AU1gRM360VMIGqhLvc3czzV9KsNjV3W6On1NbVGRyKnUwTuHj5+UOplb5zfn+UlyTxJhS7bEB2rZgykg==", "license": "MIT", "dependencies": { - "@wrnexus/syntax": "^0.4.0" + "@wrnexus/syntax": "^0.5.0" }, "engines": { "bun": ">=1.3.0" } }, "node_modules/@wrnexus/core": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@wrnexus/core/-/core-0.4.0.tgz", - "integrity": "sha512-N4Y6O0gSaNEKK24gBu4YTsXBnLnFjaY2WUlobTUOHcV2/h0MOuXjVc6dolQZnRjkza541Wg+exKu6OKmaMQDjg==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@wrnexus/core/-/core-0.5.0.tgz", + "integrity": "sha512-X5hrY6ib2pvpUHplz0KMCHV7SPVfY9eP4J99SI39efXuL2ekMd6Vr7ueh+MixscgBinjG8YdPTo/xs0gYwRx0A==", "license": "MIT", "engines": { "bun": ">=1.3.0" } }, "node_modules/@wrnexus/csr": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@wrnexus/csr/-/csr-0.4.0.tgz", - "integrity": "sha512-bCu/oonwrIu7rk8F2p2hZ0ch6ijEPeEUPxv021+meOVvj/67GFAS01vaxX5B/Iia0c2Sf+saeIhCtXh/sz72QA==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@wrnexus/csr/-/csr-0.5.0.tgz", + "integrity": "sha512-sL4B/I7/oTtv/JC4HFSc9qGIW0f23bwTS9M0R9P7x5/LZibTOV9QbktpPJbWrcd+fVLHFXUb/LkicuugCgj81g==", "license": "MIT", "dependencies": { - "@wrnexus/core": "^0.4.0" + "@wrnexus/core": "^0.5.0" }, "engines": { "bun": ">=1.3.0" } }, "node_modules/@wrnexus/db": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@wrnexus/db/-/db-0.4.0.tgz", - "integrity": "sha512-FjjWEF+/mKbmpfL5hGMilcon+uvSbXdTUwuR1ehtRP8Eldg8WqHICYkQtVB5mRnBu8lqwhsfdE5uYbK/a9Jhkg==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@wrnexus/db/-/db-0.5.0.tgz", + "integrity": "sha512-RcKnaHZuf+vvBw9ew3MxuOy5CXL5H0NvejlvnPLNFBGj0bpiPbCPh0+G6P8u0Fk9xXe3tH3AGCPE07lQlMP2uA==", "license": "MIT", "engines": { "bun": ">=1.3.0" } }, "node_modules/@wrnexus/dev-server": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@wrnexus/dev-server/-/dev-server-0.4.0.tgz", - "integrity": "sha512-g2NKtIGjWNt3iOppEjt3e7XUQIYqS+yaybzTnCI4KFU31nQwqB8lpr9wl4l7iXD6brBlo0bUBl9c4btfGufgqQ==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@wrnexus/dev-server/-/dev-server-0.5.0.tgz", + "integrity": "sha512-T3vF8h4Gxv0OnAa0K3pxvyQoEpOoyDDPTknOVVqCjYOb/9LxiK12MlUTUuHgzT6gZS4tLbrHwOjtJTuaFpIAhA==", "license": "MIT", "dependencies": { - "@wrnexus/compiler": "^0.4.0", - "@wrnexus/core": "^0.4.0", - "@wrnexus/csr": "^0.4.0", - "@wrnexus/db": "^0.4.0", - "@wrnexus/dev-toolbar": "^0.4.0", - "@wrnexus/i18n": "^0.4.0", - "@wrnexus/plugin": "^0.4.0", - "@wrnexus/pubsub": "^0.4.0", - "@wrnexus/router": "^0.4.0", - "@wrnexus/ssr": "^0.4.0", - "@wrnexus/styles": "^0.4.0", - "@wrnexus/ui": "^0.4.0", - "@wrnexus/uploader": "^0.4.0", - "@wrnexus/validation": "^0.4.0" + "@wrnexus/compiler": "^0.5.0", + "@wrnexus/core": "^0.5.0", + "@wrnexus/csr": "^0.5.0", + "@wrnexus/db": "^0.5.0", + "@wrnexus/dev-toolbar": "^0.5.0", + "@wrnexus/i18n": "^0.5.0", + "@wrnexus/plugin": "^0.5.0", + "@wrnexus/pubsub": "^0.5.0", + "@wrnexus/router": "^0.5.0", + "@wrnexus/ssr": "^0.5.0", + "@wrnexus/styles": "^0.5.0", + "@wrnexus/ui": "^0.5.0", + "@wrnexus/uploader": "^0.5.0", + "@wrnexus/validation": "^0.5.0" }, "engines": { "bun": ">=1.3.0" } }, "node_modules/@wrnexus/dev-toolbar": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@wrnexus/dev-toolbar/-/dev-toolbar-0.4.0.tgz", - "integrity": "sha512-O/bWHT1TZTsMvY0umVRELcaaw/CcGzjrI/2JNGjaRFrru1ahgF1oq7DNBhBTCfprot/8NI/DdxkVwbgiAfiMlw==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@wrnexus/dev-toolbar/-/dev-toolbar-0.5.0.tgz", + "integrity": "sha512-7WIz+/bZkp+Y+FXlDVVJOOCqHrVFI8RbvvShsXx5QRl+H88srtuIknA6QsM3vnrXh5hwabkhDZxPqwreeVrN5Q==", "license": "MIT", "engines": { "bun": ">=1.3.0" } }, "node_modules/@wrnexus/encryption": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@wrnexus/encryption/-/encryption-0.4.0.tgz", - "integrity": "sha512-A+fs/mhl8hmdzRrWO3c2baI9L9VZAJEMje/GXI6Z+fVbV2RgN9rjJvCxVJlFAljx8VNllqN3psPMrQEh0ge3Nw==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@wrnexus/encryption/-/encryption-0.5.0.tgz", + "integrity": "sha512-4SL21R83ue4/AUcYFmKf+S4PMWl0EBzHvscoDT+WvkxmF3FCSfO0gGuolE8cMP7L25TkNO48h1Q2MOOlK19kww==", "license": "MIT", "engines": { "bun": ">=1.3.0" } }, "node_modules/@wrnexus/helpers": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@wrnexus/helpers/-/helpers-0.4.0.tgz", - "integrity": "sha512-bz5rsnKsgMC1PXqeuM7xbGnIaUsxF8vP01Is3xbUuFnftyNFy/fwb5zJVU/TPL3O2dft52e9vqOy1UbKBMH+Sg==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@wrnexus/helpers/-/helpers-0.5.0.tgz", + "integrity": "sha512-wDqhRt1cmqkOFxF988IYDFXVRDBYMDliXO96tvNR4JlI/krpgny6oQzwX6Llgc3gwe2WPhGEKs53Qjolikr+cg==", "license": "MIT", "dependencies": { - "@wrnexus/core": "^0.4.0" + "@wrnexus/core": "^0.5.0" }, "engines": { "bun": ">=1.3.0" } }, "node_modules/@wrnexus/i18n": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@wrnexus/i18n/-/i18n-0.4.0.tgz", - "integrity": "sha512-wOyLplDrweV6UO5tOjhvhr8hyFCgNNlkONnaXUPFe8i11Xj+5bOtBo4cYsKR7KqbaAHG/Xx0AceBW5ppYheAow==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@wrnexus/i18n/-/i18n-0.5.0.tgz", + "integrity": "sha512-Tt+P+hCRXrxrT2n0YLqFyn1YH06FU2jqcfZrgdYaRhjpaEjHC/2Vq76wHQbcHIjIUewgYpvo/dOqJK93/7h+Ng==", "license": "MIT", "dependencies": { - "@wrnexus/core": "^0.4.0" + "@wrnexus/core": "^0.5.0" }, "engines": { "bun": ">=1.3.0" } }, "node_modules/@wrnexus/jwt": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@wrnexus/jwt/-/jwt-0.4.0.tgz", - "integrity": "sha512-TJdwiSfk5hpQCY3Jnn9XHPVjo/BAJirLn3LxOSf7oA7toPuZ0t+Zegt3lyE1YocfbwRUXBhUzayojloJF0aINw==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@wrnexus/jwt/-/jwt-0.5.0.tgz", + "integrity": "sha512-nw30zfBO4vLcQ29kLgbraQfatItv4DwAVluS2T3eWXLHS59P9ZMXbYwjW8Gs6kdn3tdY0nRqgPShR+5wMNuY1A==", "license": "MIT", "engines": { "bun": ">=1.3.0" } }, "node_modules/@wrnexus/mobile": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@wrnexus/mobile/-/mobile-0.4.0.tgz", - "integrity": "sha512-2IXD4WdK12y7SihqcF0iOE2zsUtIJ+SiI71k4E3LRaFjt2qFzcY/v77T8rSBHMVJLTlMJCEoYIxRcsC5NuHACA==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@wrnexus/mobile/-/mobile-0.5.0.tgz", + "integrity": "sha512-2tAVdMsClAfRJzOX28Iuo9DDyPClmnoMikx7LTXbmPXT3jYcmeHi4cLXePEk8ArGxA6wvP0lPk67JyyZHYOalw==", "license": "MIT", "dependencies": { - "@wrnexus/native": "^0.4.0" + "@wrnexus/native": "^0.5.0" }, "engines": { "bun": ">=1.3.0" } }, "node_modules/@wrnexus/native": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@wrnexus/native/-/native-0.4.0.tgz", - "integrity": "sha512-SY1PxVk7Jsaus7ag7eUaQA1E6BKeL1PW0aWyks+6YnNnqkfyu+IObSVvoX7hxaWEDnNR+um+mcwwT+38pfcpcg==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@wrnexus/native/-/native-0.5.0.tgz", + "integrity": "sha512-c/o54ZJirCKtd6ls4ljab4lJWZQRYIwS9P4ajnibVHN5PHIHrdYtkk2Xut97CfIG8DDgsy5KL7agu4Y4wow6BQ==", "license": "MIT", "engines": { "bun": ">=1.3.0" } }, "node_modules/@wrnexus/oauth": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@wrnexus/oauth/-/oauth-0.4.0.tgz", - "integrity": "sha512-eAlyvvXdJMTdbsQd5HpryjVU+jNB1RKNrYIo1RqDhiE/beApt2SlkcWkMUKub30iBZOtLDYekSZH1BJevuPtNA==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@wrnexus/oauth/-/oauth-0.5.0.tgz", + "integrity": "sha512-azKLvepX7oyswLtGMTTDCmjhFMGZ2FX8sn3i7hyYmeMFlBNjaXZYruvwZyUIa5Xi255GVy0Do7TOkvHyb122sA==", "license": "MIT", "engines": { "bun": ">=1.3.0" } }, "node_modules/@wrnexus/plugin": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@wrnexus/plugin/-/plugin-0.4.0.tgz", - "integrity": "sha512-IOudqyNkiBUxylECudE1hpt6SG8Q3k3qffQzR+stEVTgTZz5HVWaRTaPk4d49/wC0tnzGE121HLVgDwF/KCubg==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@wrnexus/plugin/-/plugin-0.5.0.tgz", + "integrity": "sha512-8OVYE821ytS97Yg7GmmfSe4mod+02B+jRZ8TUhvHWw+/9FWCA72UEI4z9pbFMj4dUZpw5h0YWyVtl8vcAwqGvA==", "license": "MIT", "dependencies": { - "@wrnexus/syntax": "^0.4.0" + "@wrnexus/syntax": "^0.5.0" }, "engines": { "bun": ">=1.3.0" } }, "node_modules/@wrnexus/pubsub": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@wrnexus/pubsub/-/pubsub-0.4.0.tgz", - "integrity": "sha512-SNrzUt+DFmriglzQRFbV2LysbIOV3CRQ4jUUtL9mgoX6vXtEbCrx/+nfoaYZRZgtqEk2YxEQR7gwUQ3PiiaziQ==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@wrnexus/pubsub/-/pubsub-0.5.0.tgz", + "integrity": "sha512-mKB6EOS3PtxD2eAzN8TzHpqWXWptMGDhO/UFSkLXyO/wTsyaMN52CqxI5TAtFDCiHNkAifIfQp7ObgWT35EoQA==", "license": "MIT", "engines": { "bun": ">=1.3.0" } }, "node_modules/@wrnexus/queue": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@wrnexus/queue/-/queue-0.4.0.tgz", - "integrity": "sha512-QoB/Hi4jnoWH+n4k2Qqiq3dPWugOxZq7blV4SfqfcrIRvDAmCuTqUzLL0p812XVvnyaXDaqeJxaMnwBA0DRFow==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@wrnexus/queue/-/queue-0.5.0.tgz", + "integrity": "sha512-A2BbS+/TOluAdUYlu1a/4vCQCYyn5W+2vlfwAwPJMOay5EfotUX7LcGSi3cNG17mgwOP8rZ49Yxffhyuq7q9Zg==", "license": "MIT", "engines": { "bun": ">=1.3.0" } }, "node_modules/@wrnexus/reactive": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@wrnexus/reactive/-/reactive-0.4.0.tgz", - "integrity": "sha512-XYthkvTdvILPY5ltLEP2WGRfC8/5h9td5n7bbrLGp3rzyirBRloDeiKIAtvXaw7uz1D7BiMZD6o4QdUJyXScrA==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@wrnexus/reactive/-/reactive-0.5.0.tgz", + "integrity": "sha512-YhR5L34j1FBixns3hLEZnjCl/IMCntzXz5TGxsC6jNKaU6RYa2mhhaoOi/+781eHz+3bEGB5kHQcXTqQ+cF0oQ==", "license": "MIT", "engines": { "bun": ">=1.3.0" } }, "node_modules/@wrnexus/router": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@wrnexus/router/-/router-0.4.0.tgz", - "integrity": "sha512-qEqN0haUkvhreGuO5DpZ+U3a7EhuBgD8rOabHb1wiK3/ltMA550W4BL1oOtEea/oAKMgrlQTjrsWniHOB9jNrg==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@wrnexus/router/-/router-0.5.0.tgz", + "integrity": "sha512-y2ZKLltAWz6l4Jgf4K/HmBCiBOnAjFypBJbmL404G5d+UcIOd7/NYwZKaGaIG2WRMY+7WUpMLji++Bi7UXgVRg==", "license": "MIT", "dependencies": { - "@wrnexus/compiler": "^0.4.0", - "@wrnexus/core": "^0.4.0" + "@wrnexus/compiler": "^0.5.0", + "@wrnexus/core": "^0.5.0" }, "engines": { "bun": ">=1.3.0" } }, "node_modules/@wrnexus/ssr": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@wrnexus/ssr/-/ssr-0.4.0.tgz", - "integrity": "sha512-7Slmf94KifALpkihbls5ttTsWUndxMnsCOg/OXQszvxaVDbqUS/fP9fMYRHgoFSBI4nR+e6a3J51VGjdQbnJHw==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@wrnexus/ssr/-/ssr-0.5.0.tgz", + "integrity": "sha512-vl4FwuZbeWrTrIhxr+/VqickC3bRNz4+zP/HgsSbatycWJaC9mhLp4rr2kS2id5I4EcJAL1eHMBcPxDFywqoNg==", "license": "MIT", "dependencies": { - "@wrnexus/core": "^0.4.0" + "@wrnexus/core": "^0.5.0" }, "engines": { "bun": ">=1.3.0" } }, "node_modules/@wrnexus/styles": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@wrnexus/styles/-/styles-0.4.0.tgz", - "integrity": "sha512-kEVZX/nmBjvoUBbywyhzwM/XcURfmyb6asd7VrZjM3dvcUVCW28xLpcaMIRd/V74zUVJd283J5Oa9T89w5H6CA==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@wrnexus/styles/-/styles-0.5.0.tgz", + "integrity": "sha512-8UU1yXoF3dTUF085jrTjSA9xvERS5IUdXvEzT6H7/zorGaghIp8PB+IaL50kUEDT6oS2YZS2bZZ8kOnkI3uEXg==", "license": "MIT", "dependencies": { - "@wrnexus/core": "^0.4.0", - "@wrnexus/plugin": "^0.4.0", - "@wrnexus/uploader": "^0.4.0" + "@wrnexus/core": "^0.5.0", + "@wrnexus/plugin": "^0.5.0", + "@wrnexus/uploader": "^0.5.0" }, "engines": { "bun": ">=1.3.0" } }, "node_modules/@wrnexus/syntax": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@wrnexus/syntax/-/syntax-0.4.0.tgz", - "integrity": "sha512-p2MF32Fw6jVtroSL2UwCY5S792vLogn6WATPXgcwkELadyHxHUl5vcgzAzYCb2hX9t8/qUsWFjKhNeTUZXsQmg==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@wrnexus/syntax/-/syntax-0.5.0.tgz", + "integrity": "sha512-5dh+VJ+/lE+M/HtllrOtNN67wow1moZlvKdlhPjymfaaEhshY6sWnOgrjDllDDDc+xuMHUBrkMUx6OUnSQASMA==", "license": "MIT", "engines": { "bun": ">=1.3.0" } }, "node_modules/@wrnexus/test": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@wrnexus/test/-/test-0.4.0.tgz", - "integrity": "sha512-d3pYHQQltHgWuYI6QP68TkiUIiiHybCsXXx6JIwjudvWKeSKHMwpR7W50QOYQG3nbx//rwQsXV7wmLXQV5fpOA==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@wrnexus/test/-/test-0.5.0.tgz", + "integrity": "sha512-c+PfbLcWHp21r0FlnS1BKY/y+UUGREU8RYYOAYqQiPGX8CWhTEqd4Y2hKZZZeHDh3I1H5YLAX9y9hPv6bTuIbw==", "license": "MIT", "engines": { "bun": ">=1.3.0" } }, "node_modules/@wrnexus/tracking": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@wrnexus/tracking/-/tracking-0.4.0.tgz", - "integrity": "sha512-7mBX29IX1h9d8OhHO38jDSmpkcoKWd6Y1LCXmgFS+mCatr6jXBs1xdhMGuvsyCbQBNJ8HMqICMP4ar4SNFvlfg==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@wrnexus/tracking/-/tracking-0.5.0.tgz", + "integrity": "sha512-EhtncSMK1QJQY2G4GbNaAAnuF10Ox/GqdL0/cM+rHrX19YQCDrET3f1VQs9pG2oqRi0CcO46EDfVfFK29rA2ug==", "license": "MIT", "engines": { "bun": ">=1.3.0" } }, "node_modules/@wrnexus/ui": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@wrnexus/ui/-/ui-0.4.0.tgz", - "integrity": "sha512-xDMyMyM066XBDgmQu1lNW/i+8caDL/4S3M9w6wfuXMXFLEDWCFkDhS2PZox5UY4E6TGWkBGYKYj54lzGZoSosg==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@wrnexus/ui/-/ui-0.5.0.tgz", + "integrity": "sha512-ECXlUp7aYOA5E/pWnHoNL8m+vvaWHCD2hFrG62xFSKFoGgP18KrP6IIYGwb6plB93QfDsCLObQicOhmxo9GGCQ==", "license": "MIT", "dependencies": { - "@wrnexus/core": "^0.4.0" + "@wrnexus/core": "^0.5.0" }, "engines": { "bun": ">=1.3.0" } }, "node_modules/@wrnexus/uploader": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@wrnexus/uploader/-/uploader-0.4.0.tgz", - "integrity": "sha512-Hc6jfPEl7jGokgNkIpP7dAQrQrwFZcUHNT1FfnN4CI1gcQfLLsx2VMZv68V84Zq9lDHYNjJOZqK768v8yUTOMQ==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@wrnexus/uploader/-/uploader-0.5.0.tgz", + "integrity": "sha512-MiFCydGpWjl5BA5yET5ZuVKmZkm0zfCljWB0ZEG1mxSlFv3DpVZCnDkB5DZZKCIByGfpV8q4p/LVWuSFqgAH3w==", "license": "MIT", "dependencies": { - "@wrnexus/core": "^0.4.0" + "@wrnexus/core": "^0.5.0" }, "engines": { "bun": ">=1.3.0" } }, "node_modules/@wrnexus/validation": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@wrnexus/validation/-/validation-0.4.0.tgz", - "integrity": "sha512-Eytpznn0+7Q4xDGTDIdvlLezw2wOEtps1yvTHzYcoHASxpp560x11PBppd4eD+2sbhjBM5xa8wkdPsejg1Ga1g==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@wrnexus/validation/-/validation-0.5.0.tgz", + "integrity": "sha512-/YRV48clsSV5n4HgWDgKXWE/h+AiMcr0MmScQlZ1lJE48LXKN4OS+yAzAWVT/+jgvomUkMZKLDu5Quc1H0gjXQ==", "license": "MIT", "engines": { "bun": ">=1.3.0" diff --git a/package.json b/package.json index 45f112f0..a7af3ee7 100644 --- a/package.json +++ b/package.json @@ -27,42 +27,43 @@ "dependencies": { "@iconify-json/lucide": "^1.2.118", "@iconify/tailwind4": "^1.2.3", - "@wrnexus/ai": "^0.4.0", - "@wrnexus/authz": "^0.4.0", - "@wrnexus/compiler": "^0.4.0", - "@wrnexus/core": "^0.4.0", - "@wrnexus/csr": "^0.4.0", - "@wrnexus/db": "^0.4.0", - "@wrnexus/dev-server": "^0.4.0", - "@wrnexus/encryption": "^0.4.0", - "@wrnexus/helpers": "^0.4.0", - "@wrnexus/i18n": "^0.4.0", - "@wrnexus/jwt": "^0.4.0", - "@wrnexus/mobile": "^0.4.0", - "@wrnexus/native": "^0.4.0", - "@wrnexus/oauth": "^0.4.0", - "@wrnexus/pubsub": "^0.4.0", - "@wrnexus/queue": "^0.4.0", - "@wrnexus/reactive": "^0.4.0", - "@wrnexus/router": "^0.4.0", - "@wrnexus/ssr": "^0.4.0", - "@wrnexus/styles": "^0.4.0", - "@wrnexus/test": "^0.4.0", - "@wrnexus/tracking": "^0.4.0", - "@wrnexus/ui": "^0.4.0", - "@wrnexus/uploader": "^0.4.0", - "@wrnexus/validation": "^0.4.0", - "@wrnexus/dev-toolbar": "^0.4.0", - "@wrnexus/syntax": "^0.4.0", - "@wrnexus/plugin": "^0.4.0", - "@wrnexus/captcha": "^0.4.0" + "@wrnexus/ai": "^0.5.0", + "@wrnexus/authz": "^0.5.0", + "@wrnexus/compiler": "^0.5.0", + "@wrnexus/core": "^0.5.0", + "@wrnexus/csr": "^0.5.0", + "@wrnexus/db": "^0.5.0", + "@wrnexus/dev-server": "^0.5.0", + "@wrnexus/encryption": "^0.5.0", + "@wrnexus/helpers": "^0.5.0", + "@wrnexus/i18n": "^0.5.0", + "@wrnexus/jwt": "^0.5.0", + "@wrnexus/mobile": "^0.5.0", + "@wrnexus/native": "^0.5.0", + "@wrnexus/oauth": "^0.5.0", + "@wrnexus/pubsub": "^0.5.0", + "@wrnexus/queue": "^0.5.0", + "@wrnexus/reactive": "^0.5.0", + "@wrnexus/router": "^0.5.0", + "@wrnexus/ssr": "^0.5.0", + "@wrnexus/styles": "^0.5.0", + "@wrnexus/test": "^0.5.0", + "@wrnexus/tracking": "^0.5.0", + "@wrnexus/ui": "^0.5.0", + "@wrnexus/uploader": "^0.5.0", + "@wrnexus/validation": "^0.5.0", + "@wrnexus/dev-toolbar": "^0.5.0", + "@wrnexus/syntax": "^0.5.0", + "@wrnexus/plugin": "^0.5.0", + "@wrnexus/captcha": "^0.5.0", + "@wrnexus/auth": "^0.5.0" }, "devDependencies": { "@eslint/js": "^9.0.0", "@tailwindcss/cli": "^4.0.0", "@types/bun": "latest", "@types/node": "^26.1.1", - "@wrnexus/cli": "^0.4.0", + "@wrnexus/cli": "^0.5.0", "eslint": "^9.0.0", "prettier": "latest", "tailwindcss": "^4.0.0", @@ -70,6 +71,6 @@ "typescript-eslint": "latest" }, "wrnexus": { - "version": "0.4.0" + "version": "0.5.0" } } diff --git a/public/docs-index.json b/public/docs-index.json index 8266a551..bb94b563 100644 --- a/public/docs-index.json +++ b/public/docs-index.json @@ -1,5 +1,5 @@ { - "version": "0.4.0", + "version": "0.5.0", "status": "private-developer-preview", "generatedAt": "2026-07-13", "documents": [ @@ -7,1106 +7,1113 @@ "url": "/", "title": "WRNexusJS", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/access", "title": "access", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/getting-started", "title": "getting started", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/tutorial", "title": "tutorial", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/architecture", "title": "architecture", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/language", "title": "language", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/packages", "title": "packages", "section": "package", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components", "title": "components", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/guides/project-structure", "title": "project structure", "section": "guide", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/guides/routing", "title": "routing", "section": "guide", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/guides/pages-and-components", "title": "pages and components", "section": "guide", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/guides/server-data", "title": "server data", "section": "guide", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/guides/api-routes", "title": "api routes", "section": "guide", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/guides/middleware", "title": "middleware", "section": "guide", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/guides/forms-and-validation", "title": "forms and validation", "section": "guide", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/guides/authentication", "title": "authentication", "section": "guide", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/guides/authorization", "title": "authorization", "section": "guide", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/guides/security", "title": "security", "section": "guide", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/guides/database", "title": "database", "section": "guide", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/guides/uploads", "title": "uploads", "section": "guide", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/guides/realtime", "title": "realtime", "section": "guide", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/guides/pubsub", "title": "pubsub", "section": "guide", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/guides/queues", "title": "queues", "section": "guide", - "version": "0.4.0", + "version": "0.5.0", "stability": "experimental" }, { "url": "/guides/testing", "title": "testing", "section": "guide", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/guides/workspaces-and-gateway", "title": "workspaces and gateway", "section": "guide", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/guides/deployment", "title": "deployment", "section": "guide", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/guides/configuration-and-profiles", "title": "configuration and profiles", "section": "guide", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/guides/i18n-and-themes", "title": "i18n and themes", "section": "guide", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/guides/mobile", "title": "mobile", "section": "guide", - "version": "0.4.0", + "version": "0.5.0", "stability": "experimental" }, { "url": "/guides/observability", "title": "observability", "section": "guide", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/guides/upgrading", "title": "upgrading", "section": "guide", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/guides/troubleshooting", "title": "troubleshooting", "section": "guide", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/examples", "title": "examples", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/showcase", "title": "showcase", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/benchmarks", "title": "benchmarks", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/roadmap", "title": "roadmap", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/changelog", "title": "changelog", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { - "url": "/releases/0.4.0", - "title": "0.4.0", + "url": "/releases/0.5.0", + "title": "0.5.0", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/security", "title": "security", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/support", "title": "support", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/license", "title": "license", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/search", "title": "search", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/404", "title": "404", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/packages/ai", "title": "ai", "section": "package", - "version": "0.4.0", + "version": "0.5.0", + "stability": "preview" + }, + { + "url": "/packages/auth", + "title": "auth", + "section": "package", + "version": "0.5.0", "stability": "preview" }, { "url": "/packages/authz", "title": "authz", "section": "package", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/packages/captcha", "title": "captcha", "section": "package", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/packages/cli", "title": "cli", "section": "package", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/packages/compiler", "title": "compiler", "section": "package", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/packages/core", "title": "core", "section": "package", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/packages/csr", "title": "csr", "section": "package", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/packages/db", "title": "db", "section": "package", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/packages/dev-server", "title": "dev server", "section": "package", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/packages/dev-toolbar", "title": "dev toolbar", "section": "package", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/packages/encryption", "title": "encryption", "section": "package", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/packages/helpers", "title": "helpers", "section": "package", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/packages/i18n", "title": "i18n", "section": "package", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/packages/jwt", "title": "jwt", "section": "package", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/packages/mobile", "title": "mobile", "section": "package", - "version": "0.4.0", + "version": "0.5.0", "stability": "experimental" }, { "url": "/packages/native", "title": "native", "section": "package", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/packages/oauth", "title": "oauth", "section": "package", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/packages/plugin", "title": "plugin", "section": "package", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/packages/pubsub", "title": "pubsub", "section": "package", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/packages/queue", "title": "queue", "section": "package", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/packages/reactive", "title": "reactive", "section": "package", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/packages/router", "title": "router", "section": "package", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/packages/ssr", "title": "ssr", "section": "package", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/packages/styles", "title": "styles", "section": "package", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/packages/syntax", "title": "syntax", "section": "package", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/packages/test", "title": "test", "section": "package", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/packages/tracking", "title": "tracking", "section": "package", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/packages/ui", "title": "ui", "section": "package", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/packages/uploader", "title": "uploader", "section": "package", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/packages/validation", "title": "validation", "section": "package", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/accordion", "title": "accordion", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/advanced-date-picker", "title": "advanced date picker", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/advanced-range-slider", "title": "advanced range slider", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/advanced-select", "title": "advanced select", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/alert", "title": "alert", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/avatar", "title": "avatar", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/avatar-group", "title": "avatar group", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/badge", "title": "badge", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/blockquote", "title": "blockquote", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/breadcrumb", "title": "breadcrumb", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/button", "title": "button", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/button-group", "title": "button group", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/card", "title": "card", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/carousel", "title": "carousel", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/chart", "title": "chart", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/chat-bubble", "title": "chat bubble", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/checkbox", "title": "checkbox", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/clipboard", "title": "clipboard", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/collapse", "title": "collapse", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/color-picker", "title": "color picker", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/columns", "title": "columns", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/combo-box", "title": "combo box", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/confetti", "title": "confetti", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/container", "title": "container", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/context-menu", "title": "context menu", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/copy-markup", "title": "copy markup", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/custom-scrollbar", "title": "custom scrollbar", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/data-map", "title": "data map", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/data-table", "title": "data table", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/date-picker", "title": "date picker", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/device-frame", "title": "device frame", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/divider", "title": "divider", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/drag-and-drop", "title": "drag and drop", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/drawer", "title": "drawer", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/dropdown", "title": "dropdown", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/file-input", "title": "file input", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/file-upload", "title": "file upload", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/file-upload-progress", "title": "file upload progress", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/grid", "title": "grid", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/image", "title": "image", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/input", "title": "input", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/input-group", "title": "input group", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/input-number", "title": "input number", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/kbd", "title": "kbd", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/layout-splitter", "title": "layout splitter", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/legend-indicator", "title": "legend indicator", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/link", "title": "link", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/list", "title": "list", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/list-group", "title": "list group", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/map", "title": "map", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/marquee", "title": "marquee", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/mega-menu", "title": "mega menu", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/modal", "title": "modal", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/nav", "title": "nav", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/navbar", "title": "navbar", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/pagination", "title": "pagination", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/pin-input", "title": "pin input", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/popover", "title": "popover", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/progress", "title": "progress", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/radio", "title": "radio", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/range-slider", "title": "range slider", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/rating", "title": "rating", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/scrollspy", "title": "scrollspy", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/search-box", "title": "search box", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/select", "title": "select", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/sidebar", "title": "sidebar", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/skeleton", "title": "skeleton", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/spinner", "title": "spinner", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/stepper", "title": "stepper", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/strong-password", "title": "strong password", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/styled-icon", "title": "styled icon", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/switch", "title": "switch", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/table", "title": "table", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/tabs", "title": "tabs", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/textarea", "title": "textarea", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/timeline", "title": "timeline", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/time-picker", "title": "time picker", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/toast", "title": "toast", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/toast-notifications", "title": "toast notifications", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/toggle-count", "title": "toggle count", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/toggle-password", "title": "toggle password", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/tooltip", "title": "tooltip", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/tree-view", "title": "tree view", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/typography", "title": "typography", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" }, { "url": "/components/wysiwyg-editor", "title": "wysiwyg editor", "section": "portal", - "version": "0.4.0", + "version": "0.5.0", "stability": "preview" } ] diff --git a/public/llms-full.txt b/public/llms-full.txt index 5c1097fc..992eecd0 100644 --- a/public/llms-full.txt +++ b/public/llms-full.txt @@ -1,4 +1,4 @@ -# WRNexusJS 0.4.0 comprehensive documentation index +# WRNexusJS 0.5.0 comprehensive documentation index Status: Private Developer Preview. Runtime: Bun. UI language: .wrn. This is the documentation application, not the framework monorepo. @@ -40,13 +40,14 @@ This is the documentation application, not the framework monorepo. - https://wrnexusjs.dev/benchmarks - https://wrnexusjs.dev/roadmap - https://wrnexusjs.dev/changelog -- https://wrnexusjs.dev/releases/0.4.0 +- https://wrnexusjs.dev/releases/0.5.0 - https://wrnexusjs.dev/security - https://wrnexusjs.dev/support - https://wrnexusjs.dev/license - https://wrnexusjs.dev/search - https://wrnexusjs.dev/404 - https://wrnexusjs.dev/packages/ai +- https://wrnexusjs.dev/packages/auth - https://wrnexusjs.dev/packages/authz - https://wrnexusjs.dev/packages/captcha - https://wrnexusjs.dev/packages/cli @@ -169,23 +170,23 @@ For exact APIs, use installed package README files followed by exported declarat ### Accordion Mount: data-component="Accordion" Category: base -Props: size: string = "default", color: string = "primary", items: string = [], multiple: boolean = false, class: string = "" -Slots: default -Events: none +Props: size: string = "default", color: string = "primary", variant: string = "default", class: string = "", id: string = "accordion", items: string = [], defaultOpen: string = [], multiple: boolean = false, alwaysOpen: boolean = false, disabled: boolean = false, indicator: string = "plus", indicatorPosition: string = "start", showIndicator: boolean = true, bordered: boolean = false, separated: boolean = false, flush: boolean = false, contentItalic: boolean = false +Slots: none +Events: change, open, close ### AdvancedDatePicker Mount: data-component="AdvancedDatePicker" Category: integrations Props: size: string = "default", color: string = "primary", title: string = "Advanced Date Picker", description: string = "", items: string = [], variant: string = "default", class: string = "" Slots: default -Events: none +Events: input, change, open, close, clear ### AdvancedRangeSlider Mount: data-component="AdvancedRangeSlider" Category: integrations Props: size: string = "default", color: string = "primary", title: string = "Advanced Range Slider", description: string = "", items: string = [], variant: string = "default", class: string = "" Slots: default -Events: none +Events: input, change, start, end ### AdvancedSelect Mount: data-component="AdvancedSelect" @@ -197,35 +198,35 @@ Events: search, select, change, clear, open, close, load, error ### Alert Mount: data-component="Alert" Category: base -Props: size: string = "default", color: string = "primary", title: string = "Alert", description: string = "", items: string = [], variant: string = "default", class: string = "" -Slots: default -Events: none +Props: size: string = "default", color: string = "info", variant: string = "soft", class: string = "", radius: string = "md", shadow: string = "sm", title: string = "Alert", description: string = "", items: string = [], actions: string = [], showIcon: boolean = false, icon: string = "", dismissible: boolean = false, dismissLabel: string = "Dismiss alert", role: string = "alert", live: string = "polite", linkLabel: string = "", linkHref: string = "", actionLabel: string = "", actionHref: string = "", compact: boolean = false +Slots: none +Events: dismiss, action ### Avatar Mount: data-component="Avatar" Category: base -Props: size: string = "default", color: string = "primary", title: string = "Avatar", description: string = "", items: string = [], variant: string = "default", class: string = "" -Slots: default -Events: none +Props: src: string = "", alt: string = "", initials: string = "", size: string = "md", color: string = "primary", variant: string = "solid", shape: string = "circle", status: string = "", statusLabel: string = "", statusPosition: string = "bottom", badge: string = "", badgeIcon: string = "", badgeLabel: string = "", tooltip: string = "", name: string = "", description: string = "", loading: string = "lazy", class: string = "" +Slots: none +Events: load, error, click ### AvatarGroup Mount: data-component="AvatarGroup" Category: base -Props: size: string = "default", color: string = "primary", title: string = "Avatar Group", description: string = "", items: string = [], variant: string = "default", class: string = "" -Slots: default -Events: none +Props: items: string = [], size: string = "md", color: string = "primary", variant: string = "solid", shape: string = "circle", layout: string = "stack", maxVisible: number = 4, columns: number = 3, borderColor: string = "", showTooltips: boolean = true, overflowLabel: string = "Show remaining members", class: string = "" +Slots: none +Events: overflow ### Badge Mount: data-component="Badge" Category: base -Props: size: string = "default", color: string = "primary", title: string = "Badge", description: string = "", items: string = [], variant: string = "default", class: string = "" -Slots: default -Events: none +Props: label: string = "Badge", size: string = "md", color: string = "primary", variant: string = "solid", shape: string = "pill", class: string = "", icon: string = "", iconPosition: string = "start", dot: boolean = false, dotOnly: boolean = false, dotLabel: string = "Status", animated: boolean = false, avatarSrc: string = "", avatarAlt: string = "", dismissible: boolean = false, dismissLabel: string = "Remove badge", truncate: boolean = false, maxWidth: string = "12rem", anchorLabel: string = "", anchorIcon: string = "", placement: string = "inline", anchorLabelText: string = "Badge anchor" +Slots: none +Events: dismiss ### Blockquote Mount: data-component="Blockquote" Category: base -Props: size: string = "default", color: string = "primary", title: string = "Blockquote", description: string = "", items: string = [], variant: string = "default", class: string = "" +Props: quote: string = "I just wanted to say that I'm very happy with my purchase so far. The documentation is outstanding - clear and detailed.", citation: string = "", citationTitle: string = "", citationUrl: string = "", avatarSrc: string = "", avatarAlt: string = "", size: string = "md", color: string = "primary", align: string = "left", variant: string = "default", quoteMark: boolean = true, italic: boolean = true, class: string = "" Slots: default Events: none @@ -234,77 +235,77 @@ Mount: data-component="Breadcrumb" Category: navigation Props: size: string = "default", color: string = "primary", label: string = "Breadcrumb", items: string = [], active: string = "", orientation: string = "horizontal", class: string = "" Slots: default -Events: none +Events: navigate, click ### Button Mount: data-component="Button" Category: base Props: label: string = "Button", loadingLabel: string = "Loading…", description: string = "", as: string = "", href: string = "", target: string = "", rel: string = "", type: string = "button", variant: string = "default", color: string = "primary", size: string = "default", disabled: boolean = false, loading: boolean = false, pill: boolean = false, fullWidth: boolean = false, icon: string = "", iconPosition: string = "start", ariaLabel: string = "", ariaPressed: string = "", ariaExpanded: string = "", ariaControls: string = "", title: string = "", autofocus: boolean = false, controlClass: string = "", class: string = "" Slots: default -Events: none +Events: click, focus, blur ### ButtonGroup Mount: data-component="ButtonGroup" Category: base -Props: size: string = "default", color: string = "primary", title: string = "Button Group", description: string = "", items: string = [], variant: string = "default", class: string = "" +Props: items: string = [], value: string = "", size: string = "md", color: string = "primary", variant: string = "default", orientation: string = "horizontal", responsive: boolean = false, attached: boolean = true, selectable: boolean = false, toolbar: boolean = false, disabled: boolean = false, ariaLabel: string = "Button group", class: string = "" Slots: default -Events: none +Events: click, select, change ### Card Mount: data-component="Card" Category: base -Props: size: string = "default", color: string = "primary", title: string = "Card", description: string = "", items: string = [], variant: string = "default", class: string = "" +Props: title: string = "Card title", subtitle: string = "", description: string = "", header: string = "", footer: string = "", imageSrc: string = "", imageAlt: string = "", imagePosition: string = "top", actionLabel: string = "", actionHref: string = "", headerActions: string = [], navigation: string = [], activeNav: string = "", mobileNavigation: boolean = false, alertTitle: string = "", alertDescription: string = "", empty: boolean = false, emptyTitle: string = "No data to show", emptyIcon: string = "icon-[lucide--inbox]", items: string = [], size: string = "md", color: string = "primary", variant: string = "default", layout: string = "vertical", align: string = "left", hover: string = "none", scrollable: boolean = false, maxHeight: string = "18rem", dismissible: boolean = false, ariaLabel: string = "", class: string = "" Slots: default -Events: none +Events: click, action, navigate, dismiss, load, error ### Carousel Mount: data-component="Carousel" Category: base -Props: size: string = "default", color: string = "primary", title: string = "Carousel", description: string = "", items: string = [], variant: string = "default", class: string = "" +Props: size: string = "default", color: string = "primary", title: string = "", description: string = "", items: string = [], activeIndex: number = 0, slidesPerView: number = 1, gap: string = "0.75rem", showPagination: boolean = false, isAutoPlay: boolean = false, autoplayInterval: number = 4000, isInfiniteLoop: boolean = false, isRTL: boolean = false, isCentered: boolean = false, isDraggable: boolean = false, isAutoHeight: boolean = false, isSnap: boolean = false, showCounter: boolean = false, thumbnails: string = "none", ariaLabel: string = "Content carousel", variant: string = "default", class: string = "" Slots: default -Events: none +Events: initialize, change, previous, next, play, pause, reachStart, reachEnd, dragStart, dragEnd ### Chart Mount: data-component="Chart" Category: integrations Props: size: string = "default", color: string = "primary", title: string = "Chart", description: string = "", items: string = [], variant: string = "default", class: string = "" Slots: default -Events: none +Events: select, dataPointClick, legendToggle ### ChatBubble Mount: data-component="ChatBubble" Category: base -Props: size: string = "default", color: string = "primary", title: string = "Chat Bubble", description: string = "", items: string = [], variant: string = "default", class: string = "" +Props: size: string = "default", color: string = "primary", title: string = "", description: string = "", items: string = [], oneSided: boolean = false, showAvatars: boolean = false, showMetadata: boolean = false, ariaLabel: string = "Conversation", variant: string = "default", class: string = "" Slots: default -Events: none +Events: action, messageClick, avatarClick, linkClick ### Checkbox Mount: data-component="Checkbox" Category: forms -Props: size: string = "default", color: string = "primary", label: string = "Checkbox", name: string = "", value: string = "on", checked: boolean = false, disabled: boolean = false, class: string = "" +Props: size: string = "default", color: string = "primary", id: string = "", name: string = "", label: string = "Checkbox", hiddenLabel: boolean = false, placeholder: string = "", variant: string = "normal", icon: string = "", iconPosition: string = "start", value: string = "on", values: string = [], options: string = [], checked: boolean = false, indeterminate: boolean = false, orientation: string = "vertical", card: boolean = false, rightAligned: boolean = false, list: boolean = false, helperText: string = "", cornerHint: string = "", error: string = "", inline: boolean = false, readonly: boolean = false, disabled: boolean = false, required: boolean = false, class: string = "" Slots: none -Events: none +Events: input, change, focus, blur, invalid ### Clipboard Mount: data-component="Clipboard" Category: integrations Props: size: string = "default", color: string = "primary", title: string = "Clipboard", description: string = "", items: string = [], variant: string = "default", class: string = "" Slots: default -Events: none +Events: copy, success, error ### Collapse Mount: data-component="Collapse" Category: base -Props: size: string = "default", color: string = "primary", items: string = [], multiple: boolean = false, class: string = "" +Props: size: string = "default", color: string = "primary", items: string = [], multiple: boolean = false, mode: string = "panel", initialOpenIndexes: string = [], ariaLabel: string = "Collapsible content", class: string = "" Slots: default -Events: none +Events: toggle, open, close ### ColorPicker Mount: data-component="ColorPicker" Category: forms -Props: size: string = "default", color: string = "primary", label: string = "Color Picker", name: string = "", value: string = "", placeholder: string = "", type: string = "color", min: string = "", max: string = "", step: string = "", disabled: boolean = false, required: boolean = false, class: string = "" +Props: size: string = "default", color: string = "primary", id: string = "", name: string = "", label: string = "Color", hiddenLabel: boolean = false, placeholder: string = "", value: string = "#2563eb", icon: string = "", iconPosition: string = "start", helperText: string = "", cornerHint: string = "", error: string = "", inline: boolean = false, variant: string = "normal", readonly: boolean = false, disabled: boolean = false, required: boolean = false, class: string = "" Slots: none -Events: none +Events: input, change, focus, blur ### Columns Mount: data-component="Columns" @@ -325,7 +326,7 @@ Mount: data-component="Confetti" Category: integrations Props: size: string = "default", color: string = "primary", title: string = "Confetti", description: string = "", items: string = [], variant: string = "default", class: string = "" Slots: default -Events: none +Events: start, complete ### Container Mount: data-component="Container" @@ -339,49 +340,49 @@ Mount: data-component="ContextMenu" Category: overlays Props: size: string = "default", color: string = "primary", title: string = "Context Menu", description: string = "", open: boolean = false, placement: string = "bottom", closeLabel: string = "Close", class: string = "" Slots: default -Events: none +Events: open, close, select ### CopyMarkup Mount: data-component="CopyMarkup" Category: advanced-forms Props: size: string = "default", color: string = "primary", label: string = "Copy Markup", name: string = "", value: string = "", placeholder: string = "", type: string = "text", min: string = "", max: string = "", step: string = "", disabled: boolean = false, required: boolean = false, class: string = "" Slots: none -Events: none +Events: copy, success, error ### CustomScrollbar Mount: data-component="CustomScrollbar" Category: layout Props: size: string = "default", color: string = "primary", columns: number = 2, gap: string = "md", maxWidth: string = "xl", class: string = "" Slots: default -Events: none +Events: scroll ### DataMap Mount: data-component="DataMap" Category: integrations Props: size: string = "default", color: string = "primary", title: string = "Data Map", description: string = "", items: string = [], variant: string = "default", class: string = "" Slots: default -Events: none +Events: select, change ### DataTable Mount: data-component="DataTable" Category: integrations Props: size: string = "default", color: string = "primary", caption: string = "Data Table", columns: string = [], rows: string = [], striped: boolean = true, class: string = "" Slots: default -Events: none +Events: sort, select, change, rowClick, pageChange ### DatePicker Mount: data-component="DatePicker" Category: base -Props: size: string = "default", color: string = "primary", label: string = "Date Picker", name: string = "", value: string = "", placeholder: string = "", type: string = "date", min: string = "", max: string = "", step: string = "", disabled: boolean = false, required: boolean = false, class: string = "" +Props: size: string = "default", color: string = "primary", label: string = "Date Picker", id: string = "", name: string = "", value: string = "", placeholder: string = "", type: string = "date", locale: string = "en-US", firstDayOfWeek: number = 0, months: string = [{ label: "Jan", value: "01" }, { label: "Feb", value: "02" }, { label: "Mar", value: "03" }, { label: "Apr", value: "04" }, { label: "May", value: "05" }, { label: "Jun", value: "06" }, { label: "Jul", value: "07" }, { label: "Aug", value: "08" }, { label: "Sep", value: "09" }, { label: "Oct", value: "10" }, { label: "Nov", value: "11" }, { label: "Dec", value: "12" }], days: string = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31], years: string = [2024, 2025, 2026, 2027, 2028, 2029, 2030], min: string = "", max: string = "", step: string = "", helperText: string = "", cornerHint: string = "", error: string = "", variant: string = "normal", inline: boolean = false, readonly: boolean = false, disabled: boolean = false, required: boolean = false, class: string = "" Slots: none -Events: none +Events: input, change, open, close, focus, blur, invalid ### DeviceFrame Mount: data-component="DeviceFrame" Category: base -Props: size: string = "default", color: string = "primary", title: string = "Device Frame", description: string = "", items: string = [], variant: string = "default", class: string = "" +Props: size: string = "default", color: string = "primary", title: string = "Device Frame", description: string = "", items: string = [], variant: string = "default", device: string = "phone", orientation: string = "portrait", src: string = "", srcdoc: string = "", frameTitle: string = "Device preview", showToolbar: boolean = true, allow: string = "", class: string = "" Slots: default -Events: none +Events: change, rotate ### Divider Mount: data-component="Divider" @@ -395,42 +396,42 @@ Mount: data-component="DragAndDrop" Category: integrations Props: size: string = "default", color: string = "primary", title: string = "Drag And Drop", description: string = "", items: string = [], variant: string = "default", class: string = "" Slots: default -Events: none +Events: dragStart, dragEnd, dragEnter, dragLeave, drop, change ### Drawer Mount: data-component="Drawer" Category: overlays Props: size: string = "default", color: string = "primary", title: string = "Drawer", description: string = "", open: boolean = false, placement: string = "bottom", closeLabel: string = "Close", class: string = "" Slots: default -Events: none +Events: open, close ### Dropdown Mount: data-component="Dropdown" Category: overlays Props: size: string = "default", color: string = "primary", title: string = "Dropdown", description: string = "", open: boolean = false, placement: string = "bottom", closeLabel: string = "Close", class: string = "" Slots: default -Events: none +Events: open, close, select, change ### FileInput Mount: data-component="FileInput" Category: forms -Props: size: string = "default", color: string = "primary", label: string = "File Input", name: string = "", value: string = "", placeholder: string = "", type: string = "file", min: string = "", max: string = "", step: string = "", disabled: boolean = false, required: boolean = false, class: string = "" +Props: size: string = "default", color: string = "primary", id: string = "", name: string = "", label: string = "File", hiddenLabel: boolean = false, placeholder: string = "Choose a file", value: string = "", icon: string = "icon-[lucide--upload]", iconPosition: string = "start", accept: string = "", multiple: boolean = false, helperText: string = "", cornerHint: string = "", error: string = "", inline: boolean = false, variant: string = "normal", readonly: boolean = false, disabled: boolean = false, required: boolean = false, class: string = "" Slots: none -Events: none +Events: input, change, focus, blur, select, clear, invalid ### FileUpload Mount: data-component="FileUpload" Category: integrations Props: size: string = "default", color: string = "primary", title: string = "File Upload", description: string = "", items: string = [], variant: string = "default", class: string = "" Slots: default -Events: none +Events: select, upload, progress, success, error, cancel, remove ### FileUploadProgress Mount: data-component="FileUploadProgress" Category: base -Props: size: string = "default", color: string = "primary", label: string = "Progress", value: number = 50, max: number = 100, showValue: boolean = true, class: string = "" +Props: size: string = "default", color: string = "primary", label: string = "Progress", value: number = 50, max: number = 100, showValue: boolean = true, fileName: string = "", fileSize: string = "", uploadedSize: string = "", status: string = "uploading", cancelLabel: string = "Cancel upload", retryLabel: string = "Retry upload", class: string = "" Slots: none -Events: none +Events: cancel, retry, complete ### Grid Mount: data-component="Grid" @@ -444,21 +445,21 @@ Mount: data-component="Image" Category: layout Props: size: string = "default", color: string = "primary", src: string = "", alt: string = "", width: string = "", height: string = "", loading: string = "lazy", rounded: boolean = false, class: string = "" Slots: default -Events: none +Events: load, error ### Input Mount: data-component="Input" Category: forms -Props: size: string = "default", color: string = "primary", label: string = "Input", name: string = "", value: string = "", placeholder: string = "", type: string = "text", min: string = "", max: string = "", step: string = "", disabled: boolean = false, required: boolean = false, class: string = "" +Props: size: string = "default", color: string = "primary", id: string = "", name: string = "", label: string = "Input", hiddenLabel: boolean = false, placeholder: string = "", value: string = "", type: string = "text", variant: string = "normal", icon: string = "", iconPosition: string = "start", helperText: string = "", cornerHint: string = "", error: string = "", inline: boolean = false, readonly: boolean = false, disabled: boolean = false, required: boolean = false, autocomplete: string = "", inputmode: string = "", minlength: string = "", maxlength: string = "", pattern: string = "", min: string = "", max: string = "", step: string = "", class: string = "" Slots: none -Events: none +Events: input, change, focus, blur, invalid, keydown, keyup ### InputGroup Mount: data-component="InputGroup" Category: forms -Props: size: string = "default", color: string = "primary", label: string = "Input Group", name: string = "", value: string = "", placeholder: string = "", type: string = "text", min: string = "", max: string = "", step: string = "", disabled: boolean = false, required: boolean = false, class: string = "" +Props: size: string = "default", color: string = "primary", id: string = "", name: string = "", label: string = "Input group", hiddenLabel: boolean = false, value: string = "", placeholder: string = "", type: string = "text", startText: string = "", endText: string = "", icon: string = "", iconPosition: string = "start", actionLabel: string = "", helperText: string = "", cornerHint: string = "", error: string = "", inline: boolean = false, variant: string = "normal", readonly: boolean = false, disabled: boolean = false, required: boolean = false, class: string = "" Slots: none -Events: none +Events: input, change, focus, blur, submit, action ### InputNumber Mount: data-component="InputNumber" @@ -479,84 +480,84 @@ Mount: data-component="LayoutSplitter" Category: layout Props: size: string = "default", color: string = "primary", columns: number = 2, gap: string = "md", maxWidth: string = "xl", class: string = "" Slots: default -Events: none +Events: resizeStart, resize, resizeEnd ### LegendIndicator Mount: data-component="LegendIndicator" Category: base Props: size: string = "default", color: string = "primary", title: string = "Legend Indicator", description: string = "", items: string = [], variant: string = "default", class: string = "" Slots: default -Events: none +Events: toggle, select ### Link Mount: data-component="Link" Category: layout Props: size: string = "default", color: string = "primary", label: string = "Link", href: string = "#", target: string = "", rel: string = "", external: boolean = false, class: string = "" Slots: default -Events: none +Events: click, focus, blur ### List Mount: data-component="List" Category: base Props: size: string = "default", color: string = "primary", title: string = "List", description: string = "", items: string = [], variant: string = "default", class: string = "" Slots: default -Events: none +Events: select, click ### ListGroup Mount: data-component="ListGroup" Category: base Props: size: string = "default", color: string = "primary", title: string = "List Group", description: string = "", items: string = [], variant: string = "default", class: string = "" Slots: default -Events: none +Events: select, change ### Map Mount: data-component="Map" Category: integrations Props: size: string = "default", color: string = "primary", title: string = "Map", description: string = "", items: string = [], variant: string = "default", class: string = "" Slots: default -Events: none +Events: ready, move, zoom, markerClick ### Marquee Mount: data-component="Marquee" Category: base Props: size: string = "default", color: string = "primary", title: string = "Marquee", description: string = "", items: string = [], variant: string = "default", class: string = "" Slots: default -Events: none +Events: pause, resume ### MegaMenu Mount: data-component="MegaMenu" Category: navigation Props: size: string = "default", color: string = "primary", label: string = "Mega Menu", items: string = [], active: string = "", orientation: string = "horizontal", class: string = "" Slots: default -Events: none +Events: open, close, select ### Modal Mount: data-component="Modal" Category: overlays Props: size: string = "default", color: string = "primary", title: string = "Modal", description: string = "", open: boolean = false, placement: string = "bottom", closeLabel: string = "Close", class: string = "" Slots: default -Events: none +Events: open, close, cancel, confirm ### Nav Mount: data-component="Nav" Category: navigation Props: size: string = "default", color: string = "primary", label: string = "Nav", items: string = [], active: string = "", orientation: string = "horizontal", class: string = "" Slots: default -Events: none +Events: select, change ### Navbar Mount: data-component="Navbar" Category: navigation Props: size: string = "default", color: string = "primary", label: string = "Navbar", items: string = [], active: string = "", orientation: string = "horizontal", class: string = "" Slots: default -Events: none +Events: toggle, open, close ### Pagination Mount: data-component="Pagination" Category: navigation Props: size: string = "default", color: string = "primary", label: string = "Pagination", items: string = [], active: string = "", orientation: string = "horizontal", class: string = "" Slots: default -Events: none +Events: change, previous, next ### PinInput Mount: data-component="PinInput" @@ -570,7 +571,7 @@ Mount: data-component="Popover" Category: overlays Props: size: string = "default", color: string = "primary", title: string = "Popover", description: string = "", open: boolean = false, placement: string = "bottom", closeLabel: string = "Close", class: string = "" Slots: default -Events: none +Events: open, close ### Progress Mount: data-component="Progress" @@ -582,51 +583,51 @@ Events: none ### Radio Mount: data-component="Radio" Category: forms -Props: size: string = "default", color: string = "primary", label: string = "Radio", name: string = "", value: string = "on", checked: boolean = false, disabled: boolean = false, class: string = "" +Props: size: string = "default", color: string = "primary", id: string = "", name: string = "", label: string = "Radio", hiddenLabel: boolean = false, placeholder: string = "", variant: string = "normal", icon: string = "", iconPosition: string = "start", value: string = "on", options: string = [], checked: boolean = false, orientation: string = "vertical", card: boolean = false, rightAligned: boolean = false, list: boolean = false, helperText: string = "", cornerHint: string = "", error: string = "", inline: boolean = false, readonly: boolean = false, disabled: boolean = false, required: boolean = false, class: string = "" Slots: none -Events: none +Events: input, change, focus, blur, invalid ### RangeSlider Mount: data-component="RangeSlider" Category: forms -Props: size: string = "default", color: string = "primary", label: string = "Range Slider", name: string = "", value: string = "", placeholder: string = "", type: string = "range", min: string = "", max: string = "", step: string = "", disabled: boolean = false, required: boolean = false, class: string = "" +Props: size: string = "default", color: string = "primary", id: string = "", name: string = "", label: string = "Range", hiddenLabel: boolean = false, placeholder: string = "", variant: string = "normal", icon: string = "", iconPosition: string = "start", value: number = 50, min: number = 0, max: number = 100, step: number = 1, showValue: boolean = true, showBounds: boolean = true, showSteps: boolean = false, marks: string = [], helperText: string = "", cornerHint: string = "", error: string = "", inline: boolean = false, readonly: boolean = false, disabled: boolean = false, required: boolean = false, class: string = "" Slots: none -Events: none +Events: input, change, focus, blur ### Rating Mount: data-component="Rating" Category: base Props: size: string = "default", color: string = "primary", title: string = "Rating", description: string = "", items: string = [], variant: string = "default", class: string = "" Slots: default -Events: none +Events: input, change ### Scrollspy Mount: data-component="Scrollspy" Category: navigation Props: size: string = "default", color: string = "primary", label: string = "Scrollspy", items: string = [], active: string = "", orientation: string = "horizontal", class: string = "" Slots: default -Events: none +Events: change ### SearchBox Mount: data-component="SearchBox" Category: advanced-forms Props: size: string = "default", color: string = "primary", label: string = "Search Box", name: string = "", value: string = "", placeholder: string = "", type: string = "search", min: string = "", max: string = "", step: string = "", disabled: boolean = false, required: boolean = false, class: string = "" Slots: none -Events: none +Events: input, change, search, submit, clear ### Select Mount: data-component="Select" Category: forms -Props: size: string = "default", color: string = "primary", label: string = "Select", name: string = "", value: string = "", options: string = [], placeholder: string = "Select an option", multiple: boolean = false, disabled: boolean = false, class: string = "" +Props: size: string = "default", color: string = "primary", id: string = "", name: string = "", label: string = "Select", hiddenLabel: boolean = false, value: string = "", values: string = [], options: string = [], placeholder: string = "Select an option", variant: string = "normal", icon: string = "", iconPosition: string = "start", helperText: string = "", cornerHint: string = "", error: string = "", inline: boolean = false, multiple: boolean = false, readonly: boolean = false, disabled: boolean = false, required: boolean = false, class: string = "" Slots: none -Events: none +Events: input, change, focus, blur, open, close, invalid ### Sidebar Mount: data-component="Sidebar" Category: navigation Props: size: string = "default", color: string = "primary", label: string = "Sidebar", items: string = [], active: string = "", orientation: string = "horizontal", class: string = "" Slots: default -Events: none +Events: toggle, open, close ### Skeleton Mount: data-component="Skeleton" @@ -647,7 +648,7 @@ Mount: data-component="Stepper" Category: navigation Props: size: string = "default", color: string = "primary", label: string = "Stepper", items: string = [], active: string = "", orientation: string = "horizontal", class: string = "" Slots: default -Events: none +Events: change, previous, next, complete ### StrongPassword Mount: data-component="StrongPassword" @@ -666,65 +667,65 @@ Events: none ### Switch Mount: data-component="Switch" Category: forms -Props: size: string = "default", color: string = "primary", label: string = "Switch", name: string = "", value: string = "on", checked: boolean = false, disabled: boolean = false, class: string = "" +Props: size: string = "default", color: string = "primary", id: string = "", name: string = "", label: string = "Switch", hiddenLabel: boolean = false, placeholder: string = "", variant: string = "normal", icon: string = "", iconPosition: string = "start", value: string = "on", checked: boolean = false, helperText: string = "", cornerHint: string = "", error: string = "", inline: boolean = false, readonly: boolean = false, disabled: boolean = false, required: boolean = false, class: string = "" Slots: none -Events: none +Events: input, change, focus, blur ### Table Mount: data-component="Table" Category: tables Props: size: string = "default", color: string = "primary", caption: string = "Table", columns: string = [], rows: string = [], striped: boolean = true, class: string = "" Slots: default -Events: none +Events: sort, select, rowClick ### Tabs Mount: data-component="Tabs" Category: navigation Props: size: string = "default", color: string = "primary", label: string = "Tabs", items: string = [], active: string = "", orientation: string = "horizontal", class: string = "" Slots: default -Events: none +Events: change, select ### Textarea Mount: data-component="Textarea" Category: forms -Props: size: string = "default", color: string = "primary", label: string = "Textarea", name: string = "", value: string = "", placeholder: string = "", rows: number = 5, disabled: boolean = false, required: boolean = false, class: string = "" +Props: size: string = "default", color: string = "primary", id: string = "", name: string = "", label: string = "Textarea", hiddenLabel: boolean = false, placeholder: string = "", value: string = "", variant: string = "normal", icon: string = "", iconPosition: string = "start", helperText: string = "", cornerHint: string = "", error: string = "", inline: boolean = false, rows: number = 5, resize: string = "vertical", readonly: boolean = false, disabled: boolean = false, required: boolean = false, minlength: string = "", maxlength: string = "", class: string = "" Slots: none -Events: none +Events: input, change, focus, blur, invalid ### Timeline Mount: data-component="Timeline" Category: base Props: size: string = "default", color: string = "primary", title: string = "Timeline", description: string = "", items: string = [], variant: string = "default", class: string = "" Slots: default -Events: none +Events: select ### TimePicker Mount: data-component="TimePicker" Category: forms -Props: size: string = "default", color: string = "primary", label: string = "Time Picker", name: string = "", value: string = "", placeholder: string = "", type: string = "time", min: string = "", max: string = "", step: string = "", disabled: boolean = false, required: boolean = false, class: string = "" +Props: size: string = "default", color: string = "primary", id: string = "", name: string = "", label: string = "Time", hiddenLabel: boolean = false, value: string = "", placeholder: string = "", variant: string = "normal", icon: string = "icon-[lucide--clock-3]", iconPosition: string = "end", helperText: string = "", cornerHint: string = "", error: string = "", inline: boolean = false, min: string = "", max: string = "", step: string = "", format: string = "24", minuteStep: number = 5, hours: string = ["00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23"], minutes: string = ["00", "05", "10", "15", "20", "25", "30", "35", "40", "45", "50", "55"], readonly: boolean = false, disabled: boolean = false, required: boolean = false, class: string = "" Slots: none -Events: none +Events: input, change, focus, blur, open, close, invalid ### Toast Mount: data-component="Toast" Category: base Props: size: string = "default", color: string = "primary", title: string = "Toast", description: string = "", items: string = [], variant: string = "default", class: string = "" Slots: default -Events: none +Events: dismiss, action ### ToastNotifications Mount: data-component="ToastNotifications" Category: integrations Props: size: string = "default", color: string = "primary", title: string = "Toast Notifications", description: string = "", items: string = [], variant: string = "default", class: string = "" Slots: default -Events: none +Events: add, dismiss, clear, action ### ToggleCount Mount: data-component="ToggleCount" Category: advanced-forms -Props: size: string = "default", color: string = "primary", label: string = "Toggle Count", name: string = "", value: string = "", placeholder: string = "", type: string = "text", min: string = "", max: string = "", step: string = "", disabled: boolean = false, required: boolean = false, class: string = "" +Props: size: string = "default", color: string = "primary", variant: string = "segmented", class: string = "", name: string = "billing-cycle", value: string = "monthly", firstValue: string = "monthly", firstLabel: string = "Monthly", secondValue: string = "annual", secondLabel: string = "Annual", ariaLabel: string = "Billing frequency", items: string = [], currency: string = "$", suffix: string = "", firstValueKey: string = "monthly", secondValueKey: string = "annual", emptyValue: string = "—", align: string = "end", fullWidth: boolean = true, disabled: boolean = false, animate: boolean = true, animationDuration: number = 450, animationSteps: number = 18 Slots: none -Events: none +Events: change, toggle ### TogglePassword Mount: data-component="TogglePassword" @@ -738,14 +739,14 @@ Mount: data-component="Tooltip" Category: overlays Props: size: string = "default", color: string = "primary", title: string = "Tooltip", description: string = "", open: boolean = false, placement: string = "bottom", closeLabel: string = "Close", class: string = "" Slots: default -Events: none +Events: open, close ### TreeView Mount: data-component="TreeView" Category: base Props: size: string = "default", color: string = "primary", title: string = "Tree View", description: string = "", items: string = [], variant: string = "default", class: string = "" Slots: default -Events: none +Events: select, toggle, expand, collapse ### Typography Mount: data-component="Typography" @@ -759,4 +760,4 @@ Mount: data-component="WysiwygEditor" Category: integrations Props: size: string = "default", color: string = "primary", title: string = "Wysiwyg Editor", description: string = "", items: string = [], variant: string = "default", class: string = "" Slots: default -Events: none +Events: input, change, focus, blur diff --git a/public/llms.txt b/public/llms.txt index 7da85b2c..bbdaca5d 100644 --- a/public/llms.txt +++ b/public/llms.txt @@ -1,4 +1,4 @@ -# WRNexusJS documentation 0.4.0 +# WRNexusJS documentation 0.5.0 Status: Private Developer Preview. This site documents 29 release-aligned packages. @@ -17707,9 +17707,1207 @@ Props: size: string = "default", color: string = "primary", title: string = "Wys Slots: default Events: none +# UI component catalog + +The installed @wrnexus/ui release contains 85 documented components. Every mount name, prop type, required/default status, slot, and event is included below and in llms-full.txt. + +### Accordion +Mount: data-component="Accordion" +Category: base +Props: size: string = "default", color: string = "primary", variant: string = "default", class: string = "", id: string = "accordion", items: string = [], defaultOpen: string = [], multiple: boolean = false, alwaysOpen: boolean = false, disabled: boolean = false, indicator: string = "plus", indicatorPosition: string = "start", showIndicator: boolean = true, bordered: boolean = false, separated: boolean = false, flush: boolean = false, contentItalic: boolean = false +Slots: none +Events: change, open, close + +### AdvancedDatePicker +Mount: data-component="AdvancedDatePicker" +Category: integrations +Props: size: string = "default", color: string = "primary", title: string = "Advanced Date Picker", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: input, change, open, close, clear + +### AdvancedRangeSlider +Mount: data-component="AdvancedRangeSlider" +Category: integrations +Props: size: string = "default", color: string = "primary", title: string = "Advanced Range Slider", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: input, change, start, end + +### AdvancedSelect +Mount: data-component="AdvancedSelect" +Category: advanced-forms +Props: size: string = "default", color: string = "primary", label: string = "Advanced Select", name: string = "", value: string = "", values: string = [], options: string = [], groups: string = [], placeholder: string = "Select an option", placeholderIcon: string = "", searchPlaceholder: string = "Search options…", multiple: boolean = false, searchable: boolean = true, defaultOpen: boolean = false, clearable: boolean = true, allowEmpty: boolean = true, tags: boolean = false, disabled: boolean = false, required: boolean = false, invalid: boolean = false, validationMessage: string = "", helpText: string = "", loading: boolean = false, loadingLabel: string = "Loading options…", emptyLabel: string = "No options found", selectedOptionsLabel: string = "Selected options", clearLabel: string = "Clear selection", createLabel: string = "Create", loadMoreLabel: string = "Load more", searchMode: string = "contains", searchFields: string = "label,description", minSearchLength: number = 0, searchResultLimit: number = 0, maxSelections: number = 0, showCounter: boolean = false, counterTemplate: string = "{selected} selected", optionTemplate: string = "default", selectedTemplate: string = "default", closeOnSelect: boolean = true, scrollToSelected: boolean = true, fixed: boolean = false, placement: string = "bottom", remote: boolean = false, remoteUrl: string = "", remoteQueryParam: string = "q", remoteDebounce: number = 250, remoteAutoLoad: boolean = true, infinite: boolean = false, hasMore: boolean = false, page: number = 1, class: string = "" +Slots: none +Events: search, select, change, clear, open, close, load, error + +### Alert +Mount: data-component="Alert" +Category: base +Props: size: string = "default", color: string = "info", variant: string = "soft", class: string = "", radius: string = "md", shadow: string = "sm", title: string = "Alert", description: string = "", items: string = [], actions: string = [], showIcon: boolean = false, icon: string = "", dismissible: boolean = false, dismissLabel: string = "Dismiss alert", role: string = "alert", live: string = "polite", linkLabel: string = "", linkHref: string = "", actionLabel: string = "", actionHref: string = "", compact: boolean = false +Slots: none +Events: dismiss, action + +### Avatar +Mount: data-component="Avatar" +Category: base +Props: src: string = "", alt: string = "", initials: string = "", size: string = "md", color: string = "primary", variant: string = "solid", shape: string = "circle", status: string = "", statusLabel: string = "", statusPosition: string = "bottom", badge: string = "", badgeIcon: string = "", badgeLabel: string = "", tooltip: string = "", name: string = "", description: string = "", loading: string = "lazy", class: string = "" +Slots: none +Events: load, error, click + +### AvatarGroup +Mount: data-component="AvatarGroup" +Category: base +Props: items: string = [], size: string = "md", color: string = "primary", variant: string = "solid", shape: string = "circle", layout: string = "stack", maxVisible: number = 4, columns: number = 3, borderColor: string = "", showTooltips: boolean = true, overflowLabel: string = "Show remaining members", class: string = "" +Slots: none +Events: overflow + +### Badge +Mount: data-component="Badge" +Category: base +Props: label: string = "Badge", size: string = "md", color: string = "primary", variant: string = "solid", shape: string = "pill", class: string = "", icon: string = "", iconPosition: string = "start", dot: boolean = false, dotOnly: boolean = false, dotLabel: string = "Status", animated: boolean = false, avatarSrc: string = "", avatarAlt: string = "", dismissible: boolean = false, dismissLabel: string = "Remove badge", truncate: boolean = false, maxWidth: string = "12rem", anchorLabel: string = "", anchorIcon: string = "", placement: string = "inline", anchorLabelText: string = "Badge anchor" +Slots: none +Events: dismiss + +### Blockquote +Mount: data-component="Blockquote" +Category: base +Props: quote: string = "I just wanted to say that I'm very happy with my purchase so far. The documentation is outstanding - clear and detailed.", citation: string = "", citationTitle: string = "", citationUrl: string = "", avatarSrc: string = "", avatarAlt: string = "", size: string = "md", color: string = "primary", align: string = "left", variant: string = "default", quoteMark: boolean = true, italic: boolean = true, class: string = "" +Slots: default +Events: none + +### Breadcrumb +Mount: data-component="Breadcrumb" +Category: navigation +Props: size: string = "default", color: string = "primary", label: string = "Breadcrumb", items: string = [], active: string = "", orientation: string = "horizontal", class: string = "" +Slots: default +Events: navigate, click + +### Button +Mount: data-component="Button" +Category: base +Props: label: string = "Button", loadingLabel: string = "Loading…", description: string = "", as: string = "", href: string = "", target: string = "", rel: string = "", type: string = "button", variant: string = "default", color: string = "primary", size: string = "default", disabled: boolean = false, loading: boolean = false, pill: boolean = false, fullWidth: boolean = false, icon: string = "", iconPosition: string = "start", ariaLabel: string = "", ariaPressed: string = "", ariaExpanded: string = "", ariaControls: string = "", title: string = "", autofocus: boolean = false, controlClass: string = "", class: string = "" +Slots: default +Events: click, focus, blur + +### ButtonGroup +Mount: data-component="ButtonGroup" +Category: base +Props: items: string = [], value: string = "", size: string = "md", color: string = "primary", variant: string = "default", orientation: string = "horizontal", responsive: boolean = false, attached: boolean = true, selectable: boolean = false, toolbar: boolean = false, disabled: boolean = false, ariaLabel: string = "Button group", class: string = "" +Slots: default +Events: click, select, change + +### Card +Mount: data-component="Card" +Category: base +Props: title: string = "Card title", subtitle: string = "", description: string = "", header: string = "", footer: string = "", imageSrc: string = "", imageAlt: string = "", imagePosition: string = "top", actionLabel: string = "", actionHref: string = "", headerActions: string = [], navigation: string = [], activeNav: string = "", mobileNavigation: boolean = false, alertTitle: string = "", alertDescription: string = "", empty: boolean = false, emptyTitle: string = "No data to show", emptyIcon: string = "icon-[lucide--inbox]", items: string = [], size: string = "md", color: string = "primary", variant: string = "default", layout: string = "vertical", align: string = "left", hover: string = "none", scrollable: boolean = false, maxHeight: string = "18rem", dismissible: boolean = false, ariaLabel: string = "", class: string = "" +Slots: default +Events: click, action, navigate, dismiss, load, error + +### Carousel +Mount: data-component="Carousel" +Category: base +Props: size: string = "default", color: string = "primary", title: string = "", description: string = "", items: string = [], activeIndex: number = 0, slidesPerView: number = 1, gap: string = "0.75rem", showPagination: boolean = false, isAutoPlay: boolean = false, autoplayInterval: number = 4000, isInfiniteLoop: boolean = false, isRTL: boolean = false, isCentered: boolean = false, isDraggable: boolean = false, isAutoHeight: boolean = false, isSnap: boolean = false, showCounter: boolean = false, thumbnails: string = "none", ariaLabel: string = "Content carousel", variant: string = "default", class: string = "" +Slots: default +Events: initialize, change, previous, next, play, pause, reachStart, reachEnd, dragStart, dragEnd + +### Chart +Mount: data-component="Chart" +Category: integrations +Props: size: string = "default", color: string = "primary", title: string = "Chart", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: select, dataPointClick, legendToggle + +### ChatBubble +Mount: data-component="ChatBubble" +Category: base +Props: size: string = "default", color: string = "primary", title: string = "", description: string = "", items: string = [], oneSided: boolean = false, showAvatars: boolean = false, showMetadata: boolean = false, ariaLabel: string = "Conversation", variant: string = "default", class: string = "" +Slots: default +Events: action, messageClick, avatarClick, linkClick + +### Checkbox +Mount: data-component="Checkbox" +Category: forms +Props: size: string = "default", color: string = "primary", id: string = "", name: string = "", label: string = "Checkbox", hiddenLabel: boolean = false, placeholder: string = "", variant: string = "normal", icon: string = "", iconPosition: string = "start", value: string = "on", values: string = [], options: string = [], checked: boolean = false, indeterminate: boolean = false, orientation: string = "vertical", card: boolean = false, rightAligned: boolean = false, list: boolean = false, helperText: string = "", cornerHint: string = "", error: string = "", inline: boolean = false, readonly: boolean = false, disabled: boolean = false, required: boolean = false, class: string = "" +Slots: none +Events: input, change, focus, blur, invalid + +### Clipboard +Mount: data-component="Clipboard" +Category: integrations +Props: size: string = "default", color: string = "primary", title: string = "Clipboard", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: copy, success, error + +### Collapse +Mount: data-component="Collapse" +Category: base +Props: size: string = "default", color: string = "primary", items: string = [], multiple: boolean = false, mode: string = "panel", initialOpenIndexes: string = [], ariaLabel: string = "Collapsible content", class: string = "" +Slots: default +Events: toggle, open, close + +### ColorPicker +Mount: data-component="ColorPicker" +Category: forms +Props: size: string = "default", color: string = "primary", id: string = "", name: string = "", label: string = "Color", hiddenLabel: boolean = false, placeholder: string = "", value: string = "#2563eb", icon: string = "", iconPosition: string = "start", helperText: string = "", cornerHint: string = "", error: string = "", inline: boolean = false, variant: string = "normal", readonly: boolean = false, disabled: boolean = false, required: boolean = false, class: string = "" +Slots: none +Events: input, change, focus, blur + +### Columns +Mount: data-component="Columns" +Category: layout +Props: size: string = "default", color: string = "primary", columns: number = 2, gap: string = "md", maxWidth: string = "xl", class: string = "" +Slots: default +Events: none + +### ComboBox +Mount: data-component="ComboBox" +Category: advanced-forms +Props: size: string = "default", color: string = "primary", label: string = "ComboBox", name: string = "", value: string = "", options: string = [], groups: string = [], placeholder: string = "Search or select an option", searchPlaceholder: string = "Start typing…", clearable: boolean = true, allowCustomValue: boolean = false, disabled: boolean = false, required: boolean = false, invalid: boolean = false, validationMessage: string = "", helpText: string = "", loading: boolean = false, loadingLabel: string = "Loading suggestions…", emptyLabel: string = "No matching options", clearLabel: string = "Clear value", toggleLabel: string = "Toggle suggestions", searchMode: string = "contains", searchFields: string = "label,description", minSearchLength: number = 0, searchResultLimit: number = 0, optionTemplate: string = "default", defaultOpen: boolean = false, closeOnSelect: boolean = true, fixed: boolean = false, placement: string = "bottom", autocomplete: string = "off", remote: boolean = false, remoteUrl: string = "", remoteQueryParam: string = "q", remoteDebounce: number = 250, remoteAutoLoad: boolean = true, infinite: boolean = false, hasMore: boolean = false, page: number = 1, loadMoreLabel: string = "Load more", class: string = "" +Slots: none +Events: search, select, change, clear, open, close, load, error + +### Confetti +Mount: data-component="Confetti" +Category: integrations +Props: size: string = "default", color: string = "primary", title: string = "Confetti", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: start, complete + +### Container +Mount: data-component="Container" +Category: layout +Props: size: string = "default", color: string = "primary", columns: number = 2, gap: string = "md", maxWidth: string = "xl", class: string = "" +Slots: default +Events: none + +### ContextMenu +Mount: data-component="ContextMenu" +Category: overlays +Props: size: string = "default", color: string = "primary", title: string = "Context Menu", description: string = "", open: boolean = false, placement: string = "bottom", closeLabel: string = "Close", class: string = "" +Slots: default +Events: open, close, select + +### CopyMarkup +Mount: data-component="CopyMarkup" +Category: advanced-forms +Props: size: string = "default", color: string = "primary", label: string = "Copy Markup", name: string = "", value: string = "", placeholder: string = "", type: string = "text", min: string = "", max: string = "", step: string = "", disabled: boolean = false, required: boolean = false, class: string = "" +Slots: none +Events: copy, success, error + +### CustomScrollbar +Mount: data-component="CustomScrollbar" +Category: layout +Props: size: string = "default", color: string = "primary", columns: number = 2, gap: string = "md", maxWidth: string = "xl", class: string = "" +Slots: default +Events: scroll + +### DataMap +Mount: data-component="DataMap" +Category: integrations +Props: size: string = "default", color: string = "primary", title: string = "Data Map", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: select, change + +### DataTable +Mount: data-component="DataTable" +Category: integrations +Props: size: string = "default", color: string = "primary", caption: string = "Data Table", columns: string = [], rows: string = [], striped: boolean = true, class: string = "" +Slots: default +Events: sort, select, change, rowClick, pageChange + +### DatePicker +Mount: data-component="DatePicker" +Category: base +Props: size: string = "default", color: string = "primary", label: string = "Date Picker", id: string = "", name: string = "", value: string = "", placeholder: string = "", type: string = "date", locale: string = "en-US", firstDayOfWeek: number = 0, months: string = [{ label: "Jan", value: "01" }, { label: "Feb", value: "02" }, { label: "Mar", value: "03" }, { label: "Apr", value: "04" }, { label: "May", value: "05" }, { label: "Jun", value: "06" }, { label: "Jul", value: "07" }, { label: "Aug", value: "08" }, { label: "Sep", value: "09" }, { label: "Oct", value: "10" }, { label: "Nov", value: "11" }, { label: "Dec", value: "12" }], days: string = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31], years: string = [2024, 2025, 2026, 2027, 2028, 2029, 2030], min: string = "", max: string = "", step: string = "", helperText: string = "", cornerHint: string = "", error: string = "", variant: string = "normal", inline: boolean = false, readonly: boolean = false, disabled: boolean = false, required: boolean = false, class: string = "" +Slots: none +Events: input, change, open, close, focus, blur, invalid + +### DeviceFrame +Mount: data-component="DeviceFrame" +Category: base +Props: size: string = "default", color: string = "primary", title: string = "Device Frame", description: string = "", items: string = [], variant: string = "default", device: string = "phone", orientation: string = "portrait", src: string = "", srcdoc: string = "", frameTitle: string = "Device preview", showToolbar: boolean = true, allow: string = "", class: string = "" +Slots: default +Events: change, rotate + +### Divider +Mount: data-component="Divider" +Category: layout +Props: size: string = "default", color: string = "primary", label: string = "", orientation: string = "horizontal", class: string = "" +Slots: none +Events: none + +### DragAndDrop +Mount: data-component="DragAndDrop" +Category: integrations +Props: size: string = "default", color: string = "primary", title: string = "Drag And Drop", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: dragStart, dragEnd, dragEnter, dragLeave, drop, change + +### Drawer +Mount: data-component="Drawer" +Category: overlays +Props: size: string = "default", color: string = "primary", title: string = "Drawer", description: string = "", open: boolean = false, placement: string = "bottom", closeLabel: string = "Close", class: string = "" +Slots: default +Events: open, close + +### Dropdown +Mount: data-component="Dropdown" +Category: overlays +Props: size: string = "default", color: string = "primary", title: string = "Dropdown", description: string = "", open: boolean = false, placement: string = "bottom", closeLabel: string = "Close", class: string = "" +Slots: default +Events: open, close, select, change + +### FileInput +Mount: data-component="FileInput" +Category: forms +Props: size: string = "default", color: string = "primary", id: string = "", name: string = "", label: string = "File", hiddenLabel: boolean = false, placeholder: string = "Choose a file", value: string = "", icon: string = "icon-[lucide--upload]", iconPosition: string = "start", accept: string = "", multiple: boolean = false, helperText: string = "", cornerHint: string = "", error: string = "", inline: boolean = false, variant: string = "normal", readonly: boolean = false, disabled: boolean = false, required: boolean = false, class: string = "" +Slots: none +Events: input, change, focus, blur, select, clear, invalid + +### FileUpload +Mount: data-component="FileUpload" +Category: integrations +Props: size: string = "default", color: string = "primary", title: string = "File Upload", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: select, upload, progress, success, error, cancel, remove + +### FileUploadProgress +Mount: data-component="FileUploadProgress" +Category: base +Props: size: string = "default", color: string = "primary", label: string = "Progress", value: number = 50, max: number = 100, showValue: boolean = true, fileName: string = "", fileSize: string = "", uploadedSize: string = "", status: string = "uploading", cancelLabel: string = "Cancel upload", retryLabel: string = "Retry upload", class: string = "" +Slots: none +Events: cancel, retry, complete + +### Grid +Mount: data-component="Grid" +Category: layout +Props: size: string = "default", color: string = "primary", columns: number = 2, gap: string = "md", maxWidth: string = "xl", class: string = "" +Slots: default +Events: none + +### Image +Mount: data-component="Image" +Category: layout +Props: size: string = "default", color: string = "primary", src: string = "", alt: string = "", width: string = "", height: string = "", loading: string = "lazy", rounded: boolean = false, class: string = "" +Slots: default +Events: load, error + +### Input +Mount: data-component="Input" +Category: forms +Props: size: string = "default", color: string = "primary", id: string = "", name: string = "", label: string = "Input", hiddenLabel: boolean = false, placeholder: string = "", value: string = "", type: string = "text", variant: string = "normal", icon: string = "", iconPosition: string = "start", helperText: string = "", cornerHint: string = "", error: string = "", inline: boolean = false, readonly: boolean = false, disabled: boolean = false, required: boolean = false, autocomplete: string = "", inputmode: string = "", minlength: string = "", maxlength: string = "", pattern: string = "", min: string = "", max: string = "", step: string = "", class: string = "" +Slots: none +Events: input, change, focus, blur, invalid, keydown, keyup + +### InputGroup +Mount: data-component="InputGroup" +Category: forms +Props: size: string = "default", color: string = "primary", id: string = "", name: string = "", label: string = "Input group", hiddenLabel: boolean = false, value: string = "", placeholder: string = "", type: string = "text", startText: string = "", endText: string = "", icon: string = "", iconPosition: string = "start", actionLabel: string = "", helperText: string = "", cornerHint: string = "", error: string = "", inline: boolean = false, variant: string = "normal", readonly: boolean = false, disabled: boolean = false, required: boolean = false, class: string = "" +Slots: none +Events: input, change, focus, blur, submit, action + +### InputNumber +Mount: data-component="InputNumber" +Category: advanced-forms +Props: size: string = "default", color: string = "primary", variant: string = "default", class: string = "", id: string = "", name: string = "quantity", value: number = 0, min: string = "", max: string = "", step: number = 1, precision: string = "auto", label: string = "", description: string = "", helpText: string = "", error: string = "", invalid: boolean = false, prefix: string = "", suffix: string = "", placeholder: string = "", autocomplete: string = "off", inputMode: string = "decimal", ariaLabel: string = "", required: boolean = false, disabled: boolean = false, inputDisabled: boolean = false, buttonsDisabled: boolean = false, readonly: boolean = false, allowInput: boolean = true, keyboard: boolean = true, wheel: boolean = false, clamp: boolean = true, fullWidth: boolean = false, showButtons: boolean = true, showValidationMessage: boolean = true, decrementLabel: string = "Decrease value", incrementLabel: string = "Increase value", controlsLabel: string = "Quantity controls", requiredMessage: string = "A value is required.", minMessage: string = "Value is below the minimum.", maxMessage: string = "Value is above the maximum." +Slots: none +Events: input, change, increment, decrement + +### Kbd +Mount: data-component="Kbd" +Category: layout +Props: size: string = "default", color: string = "primary", label: string = "⌘ K", class: string = "" +Slots: default +Events: none + +### LayoutSplitter +Mount: data-component="LayoutSplitter" +Category: layout +Props: size: string = "default", color: string = "primary", columns: number = 2, gap: string = "md", maxWidth: string = "xl", class: string = "" +Slots: default +Events: resizeStart, resize, resizeEnd + +### LegendIndicator +Mount: data-component="LegendIndicator" +Category: base +Props: size: string = "default", color: string = "primary", title: string = "Legend Indicator", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: toggle, select + +### Link +Mount: data-component="Link" +Category: layout +Props: size: string = "default", color: string = "primary", label: string = "Link", href: string = "#", target: string = "", rel: string = "", external: boolean = false, class: string = "" +Slots: default +Events: click, focus, blur + +### List +Mount: data-component="List" +Category: base +Props: size: string = "default", color: string = "primary", title: string = "List", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: select, click + +### ListGroup +Mount: data-component="ListGroup" +Category: base +Props: size: string = "default", color: string = "primary", title: string = "List Group", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: select, change + +### Map +Mount: data-component="Map" +Category: integrations +Props: size: string = "default", color: string = "primary", title: string = "Map", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: ready, move, zoom, markerClick + +### Marquee +Mount: data-component="Marquee" +Category: base +Props: size: string = "default", color: string = "primary", title: string = "Marquee", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: pause, resume + +### MegaMenu +Mount: data-component="MegaMenu" +Category: navigation +Props: size: string = "default", color: string = "primary", label: string = "Mega Menu", items: string = [], active: string = "", orientation: string = "horizontal", class: string = "" +Slots: default +Events: open, close, select + +### Modal +Mount: data-component="Modal" +Category: overlays +Props: size: string = "default", color: string = "primary", title: string = "Modal", description: string = "", open: boolean = false, placement: string = "bottom", closeLabel: string = "Close", class: string = "" +Slots: default +Events: open, close, cancel, confirm + +### Nav +Mount: data-component="Nav" +Category: navigation +Props: size: string = "default", color: string = "primary", label: string = "Nav", items: string = [], active: string = "", orientation: string = "horizontal", class: string = "" +Slots: default +Events: select, change + +### Navbar +Mount: data-component="Navbar" +Category: navigation +Props: size: string = "default", color: string = "primary", label: string = "Navbar", items: string = [], active: string = "", orientation: string = "horizontal", class: string = "" +Slots: default +Events: toggle, open, close + +### Pagination +Mount: data-component="Pagination" +Category: navigation +Props: size: string = "default", color: string = "primary", label: string = "Pagination", items: string = [], active: string = "", orientation: string = "horizontal", class: string = "" +Slots: default +Events: change, previous, next + +### PinInput +Mount: data-component="PinInput" +Category: advanced-forms +Props: size: string = "default", color: string = "primary", label: string = "Verification code", name: string = "pin", value: string = "", length: number = 4, pattern: string = "[0-9]", type: string = "text", inputMode: string = "numeric", placeholder: string = "○", autocomplete: string = "one-time-code", masked: boolean = false, disabled: boolean = false, readonly: boolean = false, required: boolean = false, autoFocus: boolean = false, autoSubmit: boolean = false, allowPaste: boolean = true, clearable: boolean = true, clearLabel: string = "Clear code", separator: string = "", groupSize: number = 0, helpText: string = "", invalid: boolean = false, validationMessage: string = "", class: string = "" +Slots: none +Events: input, change, complete, paste, clear, error + +### Popover +Mount: data-component="Popover" +Category: overlays +Props: size: string = "default", color: string = "primary", title: string = "Popover", description: string = "", open: boolean = false, placement: string = "bottom", closeLabel: string = "Close", class: string = "" +Slots: default +Events: open, close + +### Progress +Mount: data-component="Progress" +Category: base +Props: size: string = "default", color: string = "primary", label: string = "Progress", value: number = 50, max: number = 100, showValue: boolean = true, class: string = "" +Slots: none +Events: none + +### Radio +Mount: data-component="Radio" +Category: forms +Props: size: string = "default", color: string = "primary", id: string = "", name: string = "", label: string = "Radio", hiddenLabel: boolean = false, placeholder: string = "", variant: string = "normal", icon: string = "", iconPosition: string = "start", value: string = "on", options: string = [], checked: boolean = false, orientation: string = "vertical", card: boolean = false, rightAligned: boolean = false, list: boolean = false, helperText: string = "", cornerHint: string = "", error: string = "", inline: boolean = false, readonly: boolean = false, disabled: boolean = false, required: boolean = false, class: string = "" +Slots: none +Events: input, change, focus, blur, invalid + +### RangeSlider +Mount: data-component="RangeSlider" +Category: forms +Props: size: string = "default", color: string = "primary", id: string = "", name: string = "", label: string = "Range", hiddenLabel: boolean = false, placeholder: string = "", variant: string = "normal", icon: string = "", iconPosition: string = "start", value: number = 50, min: number = 0, max: number = 100, step: number = 1, showValue: boolean = true, showBounds: boolean = true, showSteps: boolean = false, marks: string = [], helperText: string = "", cornerHint: string = "", error: string = "", inline: boolean = false, readonly: boolean = false, disabled: boolean = false, required: boolean = false, class: string = "" +Slots: none +Events: input, change, focus, blur + +### Rating +Mount: data-component="Rating" +Category: base +Props: size: string = "default", color: string = "primary", title: string = "Rating", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: input, change + +### Scrollspy +Mount: data-component="Scrollspy" +Category: navigation +Props: size: string = "default", color: string = "primary", label: string = "Scrollspy", items: string = [], active: string = "", orientation: string = "horizontal", class: string = "" +Slots: default +Events: change + +### SearchBox +Mount: data-component="SearchBox" +Category: advanced-forms +Props: size: string = "default", color: string = "primary", label: string = "Search Box", name: string = "", value: string = "", placeholder: string = "", type: string = "search", min: string = "", max: string = "", step: string = "", disabled: boolean = false, required: boolean = false, class: string = "" +Slots: none +Events: input, change, search, submit, clear + +### Select +Mount: data-component="Select" +Category: forms +Props: size: string = "default", color: string = "primary", id: string = "", name: string = "", label: string = "Select", hiddenLabel: boolean = false, value: string = "", values: string = [], options: string = [], placeholder: string = "Select an option", variant: string = "normal", icon: string = "", iconPosition: string = "start", helperText: string = "", cornerHint: string = "", error: string = "", inline: boolean = false, multiple: boolean = false, readonly: boolean = false, disabled: boolean = false, required: boolean = false, class: string = "" +Slots: none +Events: input, change, focus, blur, open, close, invalid + +### Sidebar +Mount: data-component="Sidebar" +Category: navigation +Props: size: string = "default", color: string = "primary", label: string = "Sidebar", items: string = [], active: string = "", orientation: string = "horizontal", class: string = "" +Slots: default +Events: toggle, open, close + +### Skeleton +Mount: data-component="Skeleton" +Category: base +Props: color: string = "primary", label: string = "Loading", size: string = "md", lines: number = 3, class: string = "" +Slots: none +Events: none + +### Spinner +Mount: data-component="Spinner" +Category: base +Props: color: string = "primary", label: string = "Loading", size: string = "md", lines: number = 3, class: string = "" +Slots: none +Events: none + +### Stepper +Mount: data-component="Stepper" +Category: navigation +Props: size: string = "default", color: string = "primary", label: string = "Stepper", items: string = [], active: string = "", orientation: string = "horizontal", class: string = "" +Slots: default +Events: change, previous, next, complete + +### StrongPassword +Mount: data-component="StrongPassword" +Category: advanced-forms +Props: size: string = "default", color: string = "primary", label: string = "Password", name: string = "password", value: string = "", placeholder: string = "Create a strong password", autocomplete: string = "new-password", minLength: number = 8, specialCharactersSet: string = "!@#$%^&*()_+-=[]{}|;:,.<>?", requireLowercase: boolean = true, requireUppercase: boolean = true, requireNumber: boolean = true, requireSpecialCharacter: boolean = true, showRequirements: boolean = true, presentation: string = "inline", hintText: string = "Use a unique password you do not use elsewhere.", emptyLabel: string = "Enter a password", weakLabel: string = "Weak", fairLabel: string = "Fair", goodLabel: string = "Good", strongLabel: string = "Strong", disabled: boolean = false, readonly: boolean = false, required: boolean = false, invalid: boolean = false, validationMessage: string = "", class: string = "" +Slots: none +Events: input, change, strength + +### StyledIcon +Mount: data-component="StyledIcon" +Category: base +Props: size: string = "default", color: string = "primary", title: string = "Styled Icon", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: none + +### Switch +Mount: data-component="Switch" +Category: forms +Props: size: string = "default", color: string = "primary", id: string = "", name: string = "", label: string = "Switch", hiddenLabel: boolean = false, placeholder: string = "", variant: string = "normal", icon: string = "", iconPosition: string = "start", value: string = "on", checked: boolean = false, helperText: string = "", cornerHint: string = "", error: string = "", inline: boolean = false, readonly: boolean = false, disabled: boolean = false, required: boolean = false, class: string = "" +Slots: none +Events: input, change, focus, blur + +### Table +Mount: data-component="Table" +Category: tables +Props: size: string = "default", color: string = "primary", caption: string = "Table", columns: string = [], rows: string = [], striped: boolean = true, class: string = "" +Slots: default +Events: sort, select, rowClick + +### Tabs +Mount: data-component="Tabs" +Category: navigation +Props: size: string = "default", color: string = "primary", label: string = "Tabs", items: string = [], active: string = "", orientation: string = "horizontal", class: string = "" +Slots: default +Events: change, select + +### Textarea +Mount: data-component="Textarea" +Category: forms +Props: size: string = "default", color: string = "primary", id: string = "", name: string = "", label: string = "Textarea", hiddenLabel: boolean = false, placeholder: string = "", value: string = "", variant: string = "normal", icon: string = "", iconPosition: string = "start", helperText: string = "", cornerHint: string = "", error: string = "", inline: boolean = false, rows: number = 5, resize: string = "vertical", readonly: boolean = false, disabled: boolean = false, required: boolean = false, minlength: string = "", maxlength: string = "", class: string = "" +Slots: none +Events: input, change, focus, blur, invalid + +### Timeline +Mount: data-component="Timeline" +Category: base +Props: size: string = "default", color: string = "primary", title: string = "Timeline", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: select + +### TimePicker +Mount: data-component="TimePicker" +Category: forms +Props: size: string = "default", color: string = "primary", id: string = "", name: string = "", label: string = "Time", hiddenLabel: boolean = false, value: string = "", placeholder: string = "", variant: string = "normal", icon: string = "icon-[lucide--clock-3]", iconPosition: string = "end", helperText: string = "", cornerHint: string = "", error: string = "", inline: boolean = false, min: string = "", max: string = "", step: string = "", format: string = "24", minuteStep: number = 5, hours: string = ["00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23"], minutes: string = ["00", "05", "10", "15", "20", "25", "30", "35", "40", "45", "50", "55"], readonly: boolean = false, disabled: boolean = false, required: boolean = false, class: string = "" +Slots: none +Events: input, change, focus, blur, open, close, invalid + +### Toast +Mount: data-component="Toast" +Category: base +Props: size: string = "default", color: string = "primary", title: string = "Toast", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: dismiss, action + +### ToastNotifications +Mount: data-component="ToastNotifications" +Category: integrations +Props: size: string = "default", color: string = "primary", title: string = "Toast Notifications", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: add, dismiss, clear, action + +### ToggleCount +Mount: data-component="ToggleCount" +Category: advanced-forms +Props: size: string = "default", color: string = "primary", variant: string = "segmented", class: string = "", name: string = "billing-cycle", value: string = "monthly", firstValue: string = "monthly", firstLabel: string = "Monthly", secondValue: string = "annual", secondLabel: string = "Annual", ariaLabel: string = "Billing frequency", items: string = [], currency: string = "$", suffix: string = "", firstValueKey: string = "monthly", secondValueKey: string = "annual", emptyValue: string = "—", align: string = "end", fullWidth: boolean = true, disabled: boolean = false, animate: boolean = true, animationDuration: number = 450, animationSteps: number = 18 +Slots: none +Events: change, toggle + +### TogglePassword +Mount: data-component="TogglePassword" +Category: advanced-forms +Props: size: string = "default", color: string = "primary", label: string = "Password", name: string = "password", value: string = "", placeholder: string = "Enter your password", autocomplete: string = "current-password", minlength: string = "", maxlength: string = "", pattern: string = "(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[^A-Za-z0-9]).{8,}", fields: string = [], visible: boolean = false, toggleable: boolean = true, toggleMode: string = "button", checkboxLabel: string = "Show password", showLabel: string = "Show password", hideLabel: string = "Hide password", disabled: boolean = false, readonly: boolean = false, required: boolean = false, invalid: boolean = false, helpText: string = "", validationMessage: string = "", class: string = "" +Slots: none +Events: input, change, toggle + +### Tooltip +Mount: data-component="Tooltip" +Category: overlays +Props: size: string = "default", color: string = "primary", title: string = "Tooltip", description: string = "", open: boolean = false, placement: string = "bottom", closeLabel: string = "Close", class: string = "" +Slots: default +Events: open, close + +### TreeView +Mount: data-component="TreeView" +Category: base +Props: size: string = "default", color: string = "primary", title: string = "Tree View", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: select, toggle, expand, collapse + +### Typography +Mount: data-component="Typography" +Category: layout +Props: size: string = "default", color: string = "primary", columns: number = 2, gap: string = "md", maxWidth: string = "xl", class: string = "" +Slots: default +Events: none + +### WysiwygEditor +Mount: data-component="WysiwygEditor" +Category: integrations +Props: size: string = "default", color: string = "primary", title: string = "Wysiwyg Editor", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: input, change, focus, blur + +# UI component catalog + +The installed @wrnexus/ui release contains 85 documented components. Every mount name, prop type, required/default status, slot, and event is included below and in llms-full.txt. + +### Accordion +Mount: data-component="Accordion" +Category: base +Props: size: string = "default", color: string = "primary", variant: string = "default", class: string = "", id: string = "accordion", items: string = [], defaultOpen: string = [], multiple: boolean = false, alwaysOpen: boolean = false, disabled: boolean = false, indicator: string = "plus", indicatorPosition: string = "start", showIndicator: boolean = true, bordered: boolean = false, separated: boolean = false, flush: boolean = false, contentItalic: boolean = false +Slots: none +Events: change, open, close + +### AdvancedDatePicker +Mount: data-component="AdvancedDatePicker" +Category: integrations +Props: size: string = "default", color: string = "primary", title: string = "Advanced Date Picker", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: input, change, open, close, clear + +### AdvancedRangeSlider +Mount: data-component="AdvancedRangeSlider" +Category: integrations +Props: size: string = "default", color: string = "primary", title: string = "Advanced Range Slider", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: input, change, start, end + +### AdvancedSelect +Mount: data-component="AdvancedSelect" +Category: advanced-forms +Props: size: string = "default", color: string = "primary", label: string = "Advanced Select", name: string = "", value: string = "", values: string = [], options: string = [], groups: string = [], placeholder: string = "Select an option", placeholderIcon: string = "", searchPlaceholder: string = "Search options…", multiple: boolean = false, searchable: boolean = true, defaultOpen: boolean = false, clearable: boolean = true, allowEmpty: boolean = true, tags: boolean = false, disabled: boolean = false, required: boolean = false, invalid: boolean = false, validationMessage: string = "", helpText: string = "", loading: boolean = false, loadingLabel: string = "Loading options…", emptyLabel: string = "No options found", selectedOptionsLabel: string = "Selected options", clearLabel: string = "Clear selection", createLabel: string = "Create", loadMoreLabel: string = "Load more", searchMode: string = "contains", searchFields: string = "label,description", minSearchLength: number = 0, searchResultLimit: number = 0, maxSelections: number = 0, showCounter: boolean = false, counterTemplate: string = "{selected} selected", optionTemplate: string = "default", selectedTemplate: string = "default", closeOnSelect: boolean = true, scrollToSelected: boolean = true, fixed: boolean = false, placement: string = "bottom", remote: boolean = false, remoteUrl: string = "", remoteQueryParam: string = "q", remoteDebounce: number = 250, remoteAutoLoad: boolean = true, infinite: boolean = false, hasMore: boolean = false, page: number = 1, class: string = "" +Slots: none +Events: search, select, change, clear, open, close, load, error + +### Alert +Mount: data-component="Alert" +Category: base +Props: size: string = "default", color: string = "info", variant: string = "soft", class: string = "", radius: string = "md", shadow: string = "sm", title: string = "Alert", description: string = "", items: string = [], actions: string = [], showIcon: boolean = false, icon: string = "", dismissible: boolean = false, dismissLabel: string = "Dismiss alert", role: string = "alert", live: string = "polite", linkLabel: string = "", linkHref: string = "", actionLabel: string = "", actionHref: string = "", compact: boolean = false +Slots: none +Events: dismiss, action + +### Avatar +Mount: data-component="Avatar" +Category: base +Props: src: string = "", alt: string = "", initials: string = "", size: string = "md", color: string = "primary", variant: string = "solid", shape: string = "circle", status: string = "", statusLabel: string = "", statusPosition: string = "bottom", badge: string = "", badgeIcon: string = "", badgeLabel: string = "", tooltip: string = "", name: string = "", description: string = "", loading: string = "lazy", class: string = "" +Slots: none +Events: load, error, click + +### AvatarGroup +Mount: data-component="AvatarGroup" +Category: base +Props: items: string = [], size: string = "md", color: string = "primary", variant: string = "solid", shape: string = "circle", layout: string = "stack", maxVisible: number = 4, columns: number = 3, borderColor: string = "", showTooltips: boolean = true, overflowLabel: string = "Show remaining members", class: string = "" +Slots: none +Events: overflow + +### Badge +Mount: data-component="Badge" +Category: base +Props: label: string = "Badge", size: string = "md", color: string = "primary", variant: string = "solid", shape: string = "pill", class: string = "", icon: string = "", iconPosition: string = "start", dot: boolean = false, dotOnly: boolean = false, dotLabel: string = "Status", animated: boolean = false, avatarSrc: string = "", avatarAlt: string = "", dismissible: boolean = false, dismissLabel: string = "Remove badge", truncate: boolean = false, maxWidth: string = "12rem", anchorLabel: string = "", anchorIcon: string = "", placement: string = "inline", anchorLabelText: string = "Badge anchor" +Slots: none +Events: dismiss + +### Blockquote +Mount: data-component="Blockquote" +Category: base +Props: quote: string = "I just wanted to say that I'm very happy with my purchase so far. The documentation is outstanding - clear and detailed.", citation: string = "", citationTitle: string = "", citationUrl: string = "", avatarSrc: string = "", avatarAlt: string = "", size: string = "md", color: string = "primary", align: string = "left", variant: string = "default", quoteMark: boolean = true, italic: boolean = true, class: string = "" +Slots: default +Events: none + +### Breadcrumb +Mount: data-component="Breadcrumb" +Category: navigation +Props: size: string = "default", color: string = "primary", label: string = "Breadcrumb", items: string = [], active: string = "", orientation: string = "horizontal", class: string = "" +Slots: default +Events: navigate, click + +### Button +Mount: data-component="Button" +Category: base +Props: label: string = "Button", loadingLabel: string = "Loading…", description: string = "", as: string = "", href: string = "", target: string = "", rel: string = "", type: string = "button", variant: string = "default", color: string = "primary", size: string = "default", disabled: boolean = false, loading: boolean = false, pill: boolean = false, fullWidth: boolean = false, icon: string = "", iconPosition: string = "start", ariaLabel: string = "", ariaPressed: string = "", ariaExpanded: string = "", ariaControls: string = "", title: string = "", autofocus: boolean = false, controlClass: string = "", class: string = "" +Slots: default +Events: click, focus, blur + +### ButtonGroup +Mount: data-component="ButtonGroup" +Category: base +Props: items: string = [], value: string = "", size: string = "md", color: string = "primary", variant: string = "default", orientation: string = "horizontal", responsive: boolean = false, attached: boolean = true, selectable: boolean = false, toolbar: boolean = false, disabled: boolean = false, ariaLabel: string = "Button group", class: string = "" +Slots: default +Events: click, select, change + +### Card +Mount: data-component="Card" +Category: base +Props: title: string = "Card title", subtitle: string = "", description: string = "", header: string = "", footer: string = "", imageSrc: string = "", imageAlt: string = "", imagePosition: string = "top", actionLabel: string = "", actionHref: string = "", headerActions: string = [], navigation: string = [], activeNav: string = "", mobileNavigation: boolean = false, alertTitle: string = "", alertDescription: string = "", empty: boolean = false, emptyTitle: string = "No data to show", emptyIcon: string = "icon-[lucide--inbox]", items: string = [], size: string = "md", color: string = "primary", variant: string = "default", layout: string = "vertical", align: string = "left", hover: string = "none", scrollable: boolean = false, maxHeight: string = "18rem", dismissible: boolean = false, ariaLabel: string = "", class: string = "" +Slots: default +Events: click, action, navigate, dismiss, load, error + +### Carousel +Mount: data-component="Carousel" +Category: base +Props: size: string = "default", color: string = "primary", title: string = "", description: string = "", items: string = [], activeIndex: number = 0, slidesPerView: number = 1, gap: string = "0.75rem", showPagination: boolean = false, isAutoPlay: boolean = false, autoplayInterval: number = 4000, isInfiniteLoop: boolean = false, isRTL: boolean = false, isCentered: boolean = false, isDraggable: boolean = false, isAutoHeight: boolean = false, isSnap: boolean = false, showCounter: boolean = false, thumbnails: string = "none", ariaLabel: string = "Content carousel", variant: string = "default", class: string = "" +Slots: default +Events: initialize, change, previous, next, play, pause, reachStart, reachEnd, dragStart, dragEnd + +### Chart +Mount: data-component="Chart" +Category: integrations +Props: size: string = "default", color: string = "primary", title: string = "Chart", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: select, dataPointClick, legendToggle + +### ChatBubble +Mount: data-component="ChatBubble" +Category: base +Props: size: string = "default", color: string = "primary", title: string = "", description: string = "", items: string = [], oneSided: boolean = false, showAvatars: boolean = false, showMetadata: boolean = false, ariaLabel: string = "Conversation", variant: string = "default", class: string = "" +Slots: default +Events: action, messageClick, avatarClick, linkClick + +### Checkbox +Mount: data-component="Checkbox" +Category: forms +Props: size: string = "default", color: string = "primary", id: string = "", name: string = "", label: string = "Checkbox", hiddenLabel: boolean = false, placeholder: string = "", variant: string = "normal", icon: string = "", iconPosition: string = "start", value: string = "on", values: string = [], options: string = [], checked: boolean = false, indeterminate: boolean = false, orientation: string = "vertical", card: boolean = false, rightAligned: boolean = false, list: boolean = false, helperText: string = "", cornerHint: string = "", error: string = "", inline: boolean = false, readonly: boolean = false, disabled: boolean = false, required: boolean = false, class: string = "" +Slots: none +Events: input, change, focus, blur, invalid + +### Clipboard +Mount: data-component="Clipboard" +Category: integrations +Props: size: string = "default", color: string = "primary", title: string = "Clipboard", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: copy, success, error + +### Collapse +Mount: data-component="Collapse" +Category: base +Props: size: string = "default", color: string = "primary", items: string = [], multiple: boolean = false, mode: string = "panel", initialOpenIndexes: string = [], ariaLabel: string = "Collapsible content", class: string = "" +Slots: default +Events: toggle, open, close + +### ColorPicker +Mount: data-component="ColorPicker" +Category: forms +Props: size: string = "default", color: string = "primary", id: string = "", name: string = "", label: string = "Color", hiddenLabel: boolean = false, placeholder: string = "", value: string = "#2563eb", icon: string = "", iconPosition: string = "start", helperText: string = "", cornerHint: string = "", error: string = "", inline: boolean = false, variant: string = "normal", readonly: boolean = false, disabled: boolean = false, required: boolean = false, class: string = "" +Slots: none +Events: input, change, focus, blur + +### Columns +Mount: data-component="Columns" +Category: layout +Props: size: string = "default", color: string = "primary", columns: number = 2, gap: string = "md", maxWidth: string = "xl", class: string = "" +Slots: default +Events: none + +### ComboBox +Mount: data-component="ComboBox" +Category: advanced-forms +Props: size: string = "default", color: string = "primary", label: string = "ComboBox", name: string = "", value: string = "", options: string = [], groups: string = [], placeholder: string = "Search or select an option", searchPlaceholder: string = "Start typing…", clearable: boolean = true, allowCustomValue: boolean = false, disabled: boolean = false, required: boolean = false, invalid: boolean = false, validationMessage: string = "", helpText: string = "", loading: boolean = false, loadingLabel: string = "Loading suggestions…", emptyLabel: string = "No matching options", clearLabel: string = "Clear value", toggleLabel: string = "Toggle suggestions", searchMode: string = "contains", searchFields: string = "label,description", minSearchLength: number = 0, searchResultLimit: number = 0, optionTemplate: string = "default", defaultOpen: boolean = false, closeOnSelect: boolean = true, fixed: boolean = false, placement: string = "bottom", autocomplete: string = "off", remote: boolean = false, remoteUrl: string = "", remoteQueryParam: string = "q", remoteDebounce: number = 250, remoteAutoLoad: boolean = true, infinite: boolean = false, hasMore: boolean = false, page: number = 1, loadMoreLabel: string = "Load more", class: string = "" +Slots: none +Events: search, select, change, clear, open, close, load, error + +### Confetti +Mount: data-component="Confetti" +Category: integrations +Props: size: string = "default", color: string = "primary", title: string = "Confetti", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: start, complete + +### Container +Mount: data-component="Container" +Category: layout +Props: size: string = "default", color: string = "primary", columns: number = 2, gap: string = "md", maxWidth: string = "xl", class: string = "" +Slots: default +Events: none + +### ContextMenu +Mount: data-component="ContextMenu" +Category: overlays +Props: size: string = "default", color: string = "primary", title: string = "Context Menu", description: string = "", open: boolean = false, placement: string = "bottom", closeLabel: string = "Close", class: string = "" +Slots: default +Events: open, close, select + +### CopyMarkup +Mount: data-component="CopyMarkup" +Category: advanced-forms +Props: size: string = "default", color: string = "primary", label: string = "Copy Markup", name: string = "", value: string = "", placeholder: string = "", type: string = "text", min: string = "", max: string = "", step: string = "", disabled: boolean = false, required: boolean = false, class: string = "" +Slots: none +Events: copy, success, error + +### CustomScrollbar +Mount: data-component="CustomScrollbar" +Category: layout +Props: size: string = "default", color: string = "primary", columns: number = 2, gap: string = "md", maxWidth: string = "xl", class: string = "" +Slots: default +Events: scroll + +### DataMap +Mount: data-component="DataMap" +Category: integrations +Props: size: string = "default", color: string = "primary", title: string = "Data Map", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: select, change + +### DataTable +Mount: data-component="DataTable" +Category: integrations +Props: size: string = "default", color: string = "primary", caption: string = "Data Table", columns: string = [], rows: string = [], striped: boolean = true, class: string = "" +Slots: default +Events: sort, select, change, rowClick, pageChange + +### DatePicker +Mount: data-component="DatePicker" +Category: base +Props: size: string = "default", color: string = "primary", label: string = "Date Picker", id: string = "", name: string = "", value: string = "", placeholder: string = "", type: string = "date", locale: string = "en-US", firstDayOfWeek: number = 0, months: string = [{ label: "Jan", value: "01" }, { label: "Feb", value: "02" }, { label: "Mar", value: "03" }, { label: "Apr", value: "04" }, { label: "May", value: "05" }, { label: "Jun", value: "06" }, { label: "Jul", value: "07" }, { label: "Aug", value: "08" }, { label: "Sep", value: "09" }, { label: "Oct", value: "10" }, { label: "Nov", value: "11" }, { label: "Dec", value: "12" }], days: string = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31], years: string = [2024, 2025, 2026, 2027, 2028, 2029, 2030], min: string = "", max: string = "", step: string = "", helperText: string = "", cornerHint: string = "", error: string = "", variant: string = "normal", inline: boolean = false, readonly: boolean = false, disabled: boolean = false, required: boolean = false, class: string = "" +Slots: none +Events: input, change, open, close, focus, blur, invalid + +### DeviceFrame +Mount: data-component="DeviceFrame" +Category: base +Props: size: string = "default", color: string = "primary", title: string = "Device Frame", description: string = "", items: string = [], variant: string = "default", device: string = "phone", orientation: string = "portrait", src: string = "", srcdoc: string = "", frameTitle: string = "Device preview", showToolbar: boolean = true, allow: string = "", class: string = "" +Slots: default +Events: change, rotate + +### Divider +Mount: data-component="Divider" +Category: layout +Props: size: string = "default", color: string = "primary", label: string = "", orientation: string = "horizontal", class: string = "" +Slots: none +Events: none + +### DragAndDrop +Mount: data-component="DragAndDrop" +Category: integrations +Props: size: string = "default", color: string = "primary", title: string = "Drag And Drop", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: dragStart, dragEnd, dragEnter, dragLeave, drop, change + +### Drawer +Mount: data-component="Drawer" +Category: overlays +Props: size: string = "default", color: string = "primary", title: string = "Drawer", description: string = "", open: boolean = false, placement: string = "bottom", closeLabel: string = "Close", class: string = "" +Slots: default +Events: open, close + +### Dropdown +Mount: data-component="Dropdown" +Category: overlays +Props: size: string = "default", color: string = "primary", title: string = "Dropdown", description: string = "", open: boolean = false, placement: string = "bottom", closeLabel: string = "Close", class: string = "" +Slots: default +Events: open, close, select, change + +### FileInput +Mount: data-component="FileInput" +Category: forms +Props: size: string = "default", color: string = "primary", id: string = "", name: string = "", label: string = "File", hiddenLabel: boolean = false, placeholder: string = "Choose a file", value: string = "", icon: string = "icon-[lucide--upload]", iconPosition: string = "start", accept: string = "", multiple: boolean = false, helperText: string = "", cornerHint: string = "", error: string = "", inline: boolean = false, variant: string = "normal", readonly: boolean = false, disabled: boolean = false, required: boolean = false, class: string = "" +Slots: none +Events: input, change, focus, blur, select, clear, invalid + +### FileUpload +Mount: data-component="FileUpload" +Category: integrations +Props: size: string = "default", color: string = "primary", title: string = "File Upload", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: select, upload, progress, success, error, cancel, remove + +### FileUploadProgress +Mount: data-component="FileUploadProgress" +Category: base +Props: size: string = "default", color: string = "primary", label: string = "Progress", value: number = 50, max: number = 100, showValue: boolean = true, fileName: string = "", fileSize: string = "", uploadedSize: string = "", status: string = "uploading", cancelLabel: string = "Cancel upload", retryLabel: string = "Retry upload", class: string = "" +Slots: none +Events: cancel, retry, complete + +### Grid +Mount: data-component="Grid" +Category: layout +Props: size: string = "default", color: string = "primary", columns: number = 2, gap: string = "md", maxWidth: string = "xl", class: string = "" +Slots: default +Events: none + +### Image +Mount: data-component="Image" +Category: layout +Props: size: string = "default", color: string = "primary", src: string = "", alt: string = "", width: string = "", height: string = "", loading: string = "lazy", rounded: boolean = false, class: string = "" +Slots: default +Events: load, error + +### Input +Mount: data-component="Input" +Category: forms +Props: size: string = "default", color: string = "primary", id: string = "", name: string = "", label: string = "Input", hiddenLabel: boolean = false, placeholder: string = "", value: string = "", type: string = "text", variant: string = "normal", icon: string = "", iconPosition: string = "start", helperText: string = "", cornerHint: string = "", error: string = "", inline: boolean = false, readonly: boolean = false, disabled: boolean = false, required: boolean = false, autocomplete: string = "", inputmode: string = "", minlength: string = "", maxlength: string = "", pattern: string = "", min: string = "", max: string = "", step: string = "", class: string = "" +Slots: none +Events: input, change, focus, blur, invalid, keydown, keyup + +### InputGroup +Mount: data-component="InputGroup" +Category: forms +Props: size: string = "default", color: string = "primary", id: string = "", name: string = "", label: string = "Input group", hiddenLabel: boolean = false, value: string = "", placeholder: string = "", type: string = "text", startText: string = "", endText: string = "", icon: string = "", iconPosition: string = "start", actionLabel: string = "", helperText: string = "", cornerHint: string = "", error: string = "", inline: boolean = false, variant: string = "normal", readonly: boolean = false, disabled: boolean = false, required: boolean = false, class: string = "" +Slots: none +Events: input, change, focus, blur, submit, action + +### InputNumber +Mount: data-component="InputNumber" +Category: advanced-forms +Props: size: string = "default", color: string = "primary", variant: string = "default", class: string = "", id: string = "", name: string = "quantity", value: number = 0, min: string = "", max: string = "", step: number = 1, precision: string = "auto", label: string = "", description: string = "", helpText: string = "", error: string = "", invalid: boolean = false, prefix: string = "", suffix: string = "", placeholder: string = "", autocomplete: string = "off", inputMode: string = "decimal", ariaLabel: string = "", required: boolean = false, disabled: boolean = false, inputDisabled: boolean = false, buttonsDisabled: boolean = false, readonly: boolean = false, allowInput: boolean = true, keyboard: boolean = true, wheel: boolean = false, clamp: boolean = true, fullWidth: boolean = false, showButtons: boolean = true, showValidationMessage: boolean = true, decrementLabel: string = "Decrease value", incrementLabel: string = "Increase value", controlsLabel: string = "Quantity controls", requiredMessage: string = "A value is required.", minMessage: string = "Value is below the minimum.", maxMessage: string = "Value is above the maximum." +Slots: none +Events: input, change, increment, decrement + +### Kbd +Mount: data-component="Kbd" +Category: layout +Props: size: string = "default", color: string = "primary", label: string = "⌘ K", class: string = "" +Slots: default +Events: none + +### LayoutSplitter +Mount: data-component="LayoutSplitter" +Category: layout +Props: size: string = "default", color: string = "primary", columns: number = 2, gap: string = "md", maxWidth: string = "xl", class: string = "" +Slots: default +Events: resizeStart, resize, resizeEnd + +### LegendIndicator +Mount: data-component="LegendIndicator" +Category: base +Props: size: string = "default", color: string = "primary", title: string = "Legend Indicator", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: toggle, select + +### Link +Mount: data-component="Link" +Category: layout +Props: size: string = "default", color: string = "primary", label: string = "Link", href: string = "#", target: string = "", rel: string = "", external: boolean = false, class: string = "" +Slots: default +Events: click, focus, blur + +### List +Mount: data-component="List" +Category: base +Props: size: string = "default", color: string = "primary", title: string = "List", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: select, click + +### ListGroup +Mount: data-component="ListGroup" +Category: base +Props: size: string = "default", color: string = "primary", title: string = "List Group", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: select, change + +### Map +Mount: data-component="Map" +Category: integrations +Props: size: string = "default", color: string = "primary", title: string = "Map", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: ready, move, zoom, markerClick + +### Marquee +Mount: data-component="Marquee" +Category: base +Props: size: string = "default", color: string = "primary", title: string = "Marquee", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: pause, resume + +### MegaMenu +Mount: data-component="MegaMenu" +Category: navigation +Props: size: string = "default", color: string = "primary", label: string = "Mega Menu", items: string = [], active: string = "", orientation: string = "horizontal", class: string = "" +Slots: default +Events: open, close, select + +### Modal +Mount: data-component="Modal" +Category: overlays +Props: size: string = "default", color: string = "primary", title: string = "Modal", description: string = "", open: boolean = false, placement: string = "bottom", closeLabel: string = "Close", class: string = "" +Slots: default +Events: open, close, cancel, confirm + +### Nav +Mount: data-component="Nav" +Category: navigation +Props: size: string = "default", color: string = "primary", label: string = "Nav", items: string = [], active: string = "", orientation: string = "horizontal", class: string = "" +Slots: default +Events: select, change + +### Navbar +Mount: data-component="Navbar" +Category: navigation +Props: size: string = "default", color: string = "primary", label: string = "Navbar", items: string = [], active: string = "", orientation: string = "horizontal", class: string = "" +Slots: default +Events: toggle, open, close + +### Pagination +Mount: data-component="Pagination" +Category: navigation +Props: size: string = "default", color: string = "primary", label: string = "Pagination", items: string = [], active: string = "", orientation: string = "horizontal", class: string = "" +Slots: default +Events: change, previous, next + +### PinInput +Mount: data-component="PinInput" +Category: advanced-forms +Props: size: string = "default", color: string = "primary", label: string = "Verification code", name: string = "pin", value: string = "", length: number = 4, pattern: string = "[0-9]", type: string = "text", inputMode: string = "numeric", placeholder: string = "○", autocomplete: string = "one-time-code", masked: boolean = false, disabled: boolean = false, readonly: boolean = false, required: boolean = false, autoFocus: boolean = false, autoSubmit: boolean = false, allowPaste: boolean = true, clearable: boolean = true, clearLabel: string = "Clear code", separator: string = "", groupSize: number = 0, helpText: string = "", invalid: boolean = false, validationMessage: string = "", class: string = "" +Slots: none +Events: input, change, complete, paste, clear, error + +### Popover +Mount: data-component="Popover" +Category: overlays +Props: size: string = "default", color: string = "primary", title: string = "Popover", description: string = "", open: boolean = false, placement: string = "bottom", closeLabel: string = "Close", class: string = "" +Slots: default +Events: open, close + +### Progress +Mount: data-component="Progress" +Category: base +Props: size: string = "default", color: string = "primary", label: string = "Progress", value: number = 50, max: number = 100, showValue: boolean = true, class: string = "" +Slots: none +Events: none + +### Radio +Mount: data-component="Radio" +Category: forms +Props: size: string = "default", color: string = "primary", id: string = "", name: string = "", label: string = "Radio", hiddenLabel: boolean = false, placeholder: string = "", variant: string = "normal", icon: string = "", iconPosition: string = "start", value: string = "on", options: string = [], checked: boolean = false, orientation: string = "vertical", card: boolean = false, rightAligned: boolean = false, list: boolean = false, helperText: string = "", cornerHint: string = "", error: string = "", inline: boolean = false, readonly: boolean = false, disabled: boolean = false, required: boolean = false, class: string = "" +Slots: none +Events: input, change, focus, blur, invalid + +### RangeSlider +Mount: data-component="RangeSlider" +Category: forms +Props: size: string = "default", color: string = "primary", id: string = "", name: string = "", label: string = "Range", hiddenLabel: boolean = false, placeholder: string = "", variant: string = "normal", icon: string = "", iconPosition: string = "start", value: number = 50, min: number = 0, max: number = 100, step: number = 1, showValue: boolean = true, showBounds: boolean = true, showSteps: boolean = false, marks: string = [], helperText: string = "", cornerHint: string = "", error: string = "", inline: boolean = false, readonly: boolean = false, disabled: boolean = false, required: boolean = false, class: string = "" +Slots: none +Events: input, change, focus, blur + +### Rating +Mount: data-component="Rating" +Category: base +Props: size: string = "default", color: string = "primary", title: string = "Rating", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: input, change + +### Scrollspy +Mount: data-component="Scrollspy" +Category: navigation +Props: size: string = "default", color: string = "primary", label: string = "Scrollspy", items: string = [], active: string = "", orientation: string = "horizontal", class: string = "" +Slots: default +Events: change + +### SearchBox +Mount: data-component="SearchBox" +Category: advanced-forms +Props: size: string = "default", color: string = "primary", label: string = "Search Box", name: string = "", value: string = "", placeholder: string = "", type: string = "search", min: string = "", max: string = "", step: string = "", disabled: boolean = false, required: boolean = false, class: string = "" +Slots: none +Events: input, change, search, submit, clear + +### Select +Mount: data-component="Select" +Category: forms +Props: size: string = "default", color: string = "primary", id: string = "", name: string = "", label: string = "Select", hiddenLabel: boolean = false, value: string = "", values: string = [], options: string = [], placeholder: string = "Select an option", variant: string = "normal", icon: string = "", iconPosition: string = "start", helperText: string = "", cornerHint: string = "", error: string = "", inline: boolean = false, multiple: boolean = false, readonly: boolean = false, disabled: boolean = false, required: boolean = false, class: string = "" +Slots: none +Events: input, change, focus, blur, open, close, invalid + +### Sidebar +Mount: data-component="Sidebar" +Category: navigation +Props: size: string = "default", color: string = "primary", label: string = "Sidebar", items: string = [], active: string = "", orientation: string = "horizontal", class: string = "" +Slots: default +Events: toggle, open, close + +### Skeleton +Mount: data-component="Skeleton" +Category: base +Props: color: string = "primary", label: string = "Loading", size: string = "md", lines: number = 3, class: string = "" +Slots: none +Events: none + +### Spinner +Mount: data-component="Spinner" +Category: base +Props: color: string = "primary", label: string = "Loading", size: string = "md", lines: number = 3, class: string = "" +Slots: none +Events: none + +### Stepper +Mount: data-component="Stepper" +Category: navigation +Props: size: string = "default", color: string = "primary", label: string = "Stepper", items: string = [], active: string = "", orientation: string = "horizontal", class: string = "" +Slots: default +Events: change, previous, next, complete + +### StrongPassword +Mount: data-component="StrongPassword" +Category: advanced-forms +Props: size: string = "default", color: string = "primary", label: string = "Password", name: string = "password", value: string = "", placeholder: string = "Create a strong password", autocomplete: string = "new-password", minLength: number = 8, specialCharactersSet: string = "!@#$%^&*()_+-=[]{}|;:,.<>?", requireLowercase: boolean = true, requireUppercase: boolean = true, requireNumber: boolean = true, requireSpecialCharacter: boolean = true, showRequirements: boolean = true, presentation: string = "inline", hintText: string = "Use a unique password you do not use elsewhere.", emptyLabel: string = "Enter a password", weakLabel: string = "Weak", fairLabel: string = "Fair", goodLabel: string = "Good", strongLabel: string = "Strong", disabled: boolean = false, readonly: boolean = false, required: boolean = false, invalid: boolean = false, validationMessage: string = "", class: string = "" +Slots: none +Events: input, change, strength + +### StyledIcon +Mount: data-component="StyledIcon" +Category: base +Props: size: string = "default", color: string = "primary", title: string = "Styled Icon", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: none + +### Switch +Mount: data-component="Switch" +Category: forms +Props: size: string = "default", color: string = "primary", id: string = "", name: string = "", label: string = "Switch", hiddenLabel: boolean = false, placeholder: string = "", variant: string = "normal", icon: string = "", iconPosition: string = "start", value: string = "on", checked: boolean = false, helperText: string = "", cornerHint: string = "", error: string = "", inline: boolean = false, readonly: boolean = false, disabled: boolean = false, required: boolean = false, class: string = "" +Slots: none +Events: input, change, focus, blur + +### Table +Mount: data-component="Table" +Category: tables +Props: size: string = "default", color: string = "primary", caption: string = "Table", columns: string = [], rows: string = [], striped: boolean = true, class: string = "" +Slots: default +Events: sort, select, rowClick + +### Tabs +Mount: data-component="Tabs" +Category: navigation +Props: size: string = "default", color: string = "primary", label: string = "Tabs", items: string = [], active: string = "", orientation: string = "horizontal", class: string = "" +Slots: default +Events: change, select + +### Textarea +Mount: data-component="Textarea" +Category: forms +Props: size: string = "default", color: string = "primary", id: string = "", name: string = "", label: string = "Textarea", hiddenLabel: boolean = false, placeholder: string = "", value: string = "", variant: string = "normal", icon: string = "", iconPosition: string = "start", helperText: string = "", cornerHint: string = "", error: string = "", inline: boolean = false, rows: number = 5, resize: string = "vertical", readonly: boolean = false, disabled: boolean = false, required: boolean = false, minlength: string = "", maxlength: string = "", class: string = "" +Slots: none +Events: input, change, focus, blur, invalid + +### Timeline +Mount: data-component="Timeline" +Category: base +Props: size: string = "default", color: string = "primary", title: string = "Timeline", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: select + +### TimePicker +Mount: data-component="TimePicker" +Category: forms +Props: size: string = "default", color: string = "primary", id: string = "", name: string = "", label: string = "Time", hiddenLabel: boolean = false, value: string = "", placeholder: string = "", variant: string = "normal", icon: string = "icon-[lucide--clock-3]", iconPosition: string = "end", helperText: string = "", cornerHint: string = "", error: string = "", inline: boolean = false, min: string = "", max: string = "", step: string = "", format: string = "24", minuteStep: number = 5, hours: string = ["00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23"], minutes: string = ["00", "05", "10", "15", "20", "25", "30", "35", "40", "45", "50", "55"], readonly: boolean = false, disabled: boolean = false, required: boolean = false, class: string = "" +Slots: none +Events: input, change, focus, blur, open, close, invalid + +### Toast +Mount: data-component="Toast" +Category: base +Props: size: string = "default", color: string = "primary", title: string = "Toast", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: dismiss, action + +### ToastNotifications +Mount: data-component="ToastNotifications" +Category: integrations +Props: size: string = "default", color: string = "primary", title: string = "Toast Notifications", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: add, dismiss, clear, action + +### ToggleCount +Mount: data-component="ToggleCount" +Category: advanced-forms +Props: size: string = "default", color: string = "primary", variant: string = "segmented", class: string = "", name: string = "billing-cycle", value: string = "monthly", firstValue: string = "monthly", firstLabel: string = "Monthly", secondValue: string = "annual", secondLabel: string = "Annual", ariaLabel: string = "Billing frequency", items: string = [], currency: string = "$", suffix: string = "", firstValueKey: string = "monthly", secondValueKey: string = "annual", emptyValue: string = "—", align: string = "end", fullWidth: boolean = true, disabled: boolean = false, animate: boolean = true, animationDuration: number = 450, animationSteps: number = 18 +Slots: none +Events: change, toggle + +### TogglePassword +Mount: data-component="TogglePassword" +Category: advanced-forms +Props: size: string = "default", color: string = "primary", label: string = "Password", name: string = "password", value: string = "", placeholder: string = "Enter your password", autocomplete: string = "current-password", minlength: string = "", maxlength: string = "", pattern: string = "(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[^A-Za-z0-9]).{8,}", fields: string = [], visible: boolean = false, toggleable: boolean = true, toggleMode: string = "button", checkboxLabel: string = "Show password", showLabel: string = "Show password", hideLabel: string = "Hide password", disabled: boolean = false, readonly: boolean = false, required: boolean = false, invalid: boolean = false, helpText: string = "", validationMessage: string = "", class: string = "" +Slots: none +Events: input, change, toggle + +### Tooltip +Mount: data-component="Tooltip" +Category: overlays +Props: size: string = "default", color: string = "primary", title: string = "Tooltip", description: string = "", open: boolean = false, placement: string = "bottom", closeLabel: string = "Close", class: string = "" +Slots: default +Events: open, close + +### TreeView +Mount: data-component="TreeView" +Category: base +Props: size: string = "default", color: string = "primary", title: string = "Tree View", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: select, toggle, expand, collapse + +### Typography +Mount: data-component="Typography" +Category: layout +Props: size: string = "default", color: string = "primary", columns: number = 2, gap: string = "md", maxWidth: string = "xl", class: string = "" +Slots: default +Events: none + +### WysiwygEditor +Mount: data-component="WysiwygEditor" +Category: integrations +Props: size: string = "default", color: string = "primary", title: string = "Wysiwyg Editor", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: input, change, focus, blur + # Installed package documentation -The following README files and declarations come from the installed private 0.4.0 release. +The following README files and declarations come from the installed private 0.5.0 release. ## @wrnexus/ai @@ -17994,6 +19192,414 @@ export { type AI, type AIClient, type AIClientOptions, type AIConfig, AIError, t --- +## @wrnexus/auth + +Documentation URL: https://wrnexusjs.dev/packages/auth + +# @wrnexus/auth + +Framework-native authentication, identity, account-security, and session management for WRNexusJS. + +## Capabilities + +- Password registration, login, recovery, reset, and authenticated password changes +- Email, phone, and username identities with verification and generic resend responses +- Magic links and passwordless email/SMS OTP login +- MFA transactions using verified email OTP, verified SMS OTP, TOTP, or recovery codes +- RFC 6238 TOTP with counter replay protection +- One-use recovery codes; regeneration invalidates previous unused codes +- Passkey/WebAuthn registration and strong passwordless sign-in through a provider contract +- OAuth account linking and provider sign-in +- Invitations, session rotation, idle and absolute expiry, revocation, and trusted devices +- Deny-by-default audited support impersonation +- Adaptive risk scoring, CAPTCHA escalation, temporary lockout, and optional login alerts +- Memory and SQL stores +- Optional encryption-keyring protection for TOTP and OAuth secrets +- Automatic API routes, middleware, browser schemas, components, runtime, migrations, and DevToolbar checks + +Passkeys are a strong sign-in method. They are not currently exposed as a selectable second step in `TwoFactorChallenge`; the implemented MFA methods are email OTP, SMS OTP, TOTP, and recovery codes. + +## Install + +```bash +bun add @wrnexus/auth +``` + +WRNexusJS discovers the package automatically. Do not copy package components, client scripts, schemas, or standard `/api/auth/*` route files into the application. + +## Default configuration + +Create the engine: + +```ts +// app/lib/auth.ts +import { createAuthEngine, MemoryAuthStore } from "@wrnexus/auth"; + +export const auth = createAuthEngine({ + store: new MemoryAuthStore(), + secret: process.env.AUTH_SECRET!, + issuer: "My application", + onSignedIn(ctx, returnTo) { + const safe = returnTo?.startsWith("/") && !returnTo.startsWith("//") ? returnTo : "/account"; + return Response.redirect(new URL(safe, ctx.url), 303); + }, + onSignedOut(ctx) { + return Response.redirect(new URL("/sign-in", ctx.url), 303); + }, + onSuccessfulSignUp() { + return { + autoSignIn: true, + redirectTo: "/account", + }; + }, + delivery: { + async send(message) { + // Queue email/SMS through your provider. Never log message.code or message.token. + }, + }, +}); +``` + +Authentication behavior belongs in this engine definition: delivery, token URL +mapping, successful sign-in/sign-out responses, password policy, risk thresholds, +MFA, passkeys, and auditing can all be configured in one server-only location. +The older `config.auth.onSignedIn` and `config.auth.onSignedOut` fields remain +supported as compatibility overrides, but new applications should configure +these hooks on `createAuthEngine`. + +### Successful signup behavior + +Without `onSuccessfulSignUp`, a successful package registration redirects to +`/sign-in`. + +To sign in immediately after registration: + +```ts +onSuccessfulSignUp(ctx, user) { + return { + autoSignIn: true, + redirectTo: "/account", + }; +} +``` + +Automatic sign-in runs the normal login policy. It does not bypass required +email or phone verification, CAPTCHA, MFA, account status, or risk checks. The +hook may also return a `Response` for a completely custom HTTP result, or return +`{ redirectTo: "/welcome" }` to redirect without creating a session. + +Register it through application configuration: + +```ts +// wrnexus.config.ts +import type { AuthConfig } from "@wrnexus/auth"; +import type { AppConfig } from "@wrnexus/styles"; +import { auth } from "./app/lib/auth.ts"; + +const config = { + auth: { + engine: auth, + routes: true, + middleware: true, + migrations: false, + }, +} satisfies AppConfig & { auth: AuthConfig }; + +export default config; +``` + +That configuration automatically activates package routes, auth-session middleware, components, browser validation schemas, and the auth client runtime. `setDefaultAuthEngine()` remains available only for advanced manual integrations and tests. + +## SQL production configuration + +```ts +import { createAuthEngine, SqlAuthStore } from "@wrnexus/auth"; +import { getDb } from "@wrnexus/db"; + +export const auth = createAuthEngine({ + store: new SqlAuthStore(getDb()), + secret: process.env.AUTH_SECRET!, +}); +``` + +```ts +export default { + db: { + // Application database configuration. + }, + auth: { + engine: auth, + routes: true, + middleware: true, + migrations: true, + }, +}; +``` + +The package contributes both ordered migrations: + +```text +001_auth.sql +002_auth_otp_purpose.sql +``` + +Migrations are enabled automatically only when `auth.engine` and a default `config.db` are present. Set `auth.migrations` explicitly when an application needs different behavior. + +## Delivered action URLs + +By default, the engine builds links from the supplied `baseUrl` and token purpose. Applications can map those links to their own page structure without replacing package APIs: + +```ts +const auth = createAuthEngine({ + store: new SqlAuthStore(getDb()), + secret: process.env.AUTH_SECRET!, + tokenUrl({ purpose, token, baseUrl }) { + if (!baseUrl) return undefined; + + const paths = { + "verify-email": `/verify-email?token=${encodeURIComponent(token)}`, + "verify-phone": `/verify-phone?token=${encodeURIComponent(token)}`, + "password-reset": `/recover/reset?token=${encodeURIComponent(token)}`, + "magic-link": `/magic-link?token=${encodeURIComponent(token)}`, + invite: `/invitation?token=${encodeURIComponent(token)}`, + }; + + const path = paths[purpose as keyof typeof paths]; + return path ? new URL(path, baseUrl).toString() : undefined; + }, +}); +``` + +Returning `undefined` intentionally omits the URL while still delivering the raw token. The callback runs only in trusted server code. + +## Built-in validation + +Every packaged auth form has a built-in `@wrnexus/validation` schema. The same resolved schema is used by the browser and the package API handler. + +Default use requires no `app/schemas` files: + +```wrn + + + + + +``` + +To customize one schema, extend the package default and register only that override: + +```ts +// app/schemas/custom-password-request.ts +import { authSchemas } from "@wrnexus/auth"; +import { v } from "@wrnexus/validation"; + +export default authSchemas.passwordResetRequest.extend({ + identifier: v + .string() + .trim() + .required("Enter your registered email address") + .email("Enter a valid registered email address"), +}); +``` + +```ts +import customPasswordRequest from "./app/schemas/custom-password-request.ts"; + +export default { + auth: { + engine: auth, + schemas: { + passwordResetRequest: customPasswordRequest, + }, + }, +}; +``` + +`` can keep its default `schema="auth-password-request"`. The plugin automatically publishes the overridden browser descriptor under that same built-in schema ID. All other forms continue using package defaults. + +## Route controls + +Use a boolean to enable or disable all package routes: + +```ts +auth: { + engine: auth, + routes: true, +} +``` + +Or control feature groups: + +```ts +routes: { + enabled: true, + registration: true, + login: true, + verification: true, + password: true, + invitations: true, + magicLink: true, + otp: true, + mfa: true, + sessions: true, + impersonation: false, + passkeys: true, +} +``` + +Application routes have normal framework precedence. Disable a package group only when the application intentionally owns every endpoint in that group; no `excludeRoutes` list is required. + +## Package endpoints + +```text +POST /api/auth/register +POST /api/auth/login +POST /api/auth/logout +POST /api/auth/verification/request +GET|POST /api/auth/verify/email +POST /api/auth/verify/phone +POST /api/auth/password/request +POST /api/auth/password/reset +POST /api/auth/password/change +POST /api/auth/invitations/accept +POST /api/auth/magic-link/request +GET|POST /api/auth/magic-link +POST /api/auth/otp/login/request +POST /api/auth/otp/login/complete +POST /api/auth/otp +POST /api/auth/otp/verify +POST /api/auth/totp/setup +POST /api/auth/totp/confirm +POST /api/auth/totp/disable +POST /api/auth/recovery-codes +POST /api/auth/mfa/otp +POST /api/auth/mfa/complete +GET /api/auth/sessions +POST /api/auth/sessions/revoke +POST /api/auth/impersonation/start +POST /api/auth/impersonation/stop +POST /api/auth/passkeys/register/options +POST /api/auth/passkeys/register/verify +POST /api/auth/passkeys/login/options +POST /api/auth/passkeys/login/verify +``` + +Each URL uses a route-specific module, so rewritten framework request URLs cannot make the handler fall through to a shared-dispatcher `404`. + +Unsafe package routes validate the framework CSRF token by default. Set `auth.csrf: false` only when an external API gateway provides an equivalent protection model. + +## Components + +```wrn + + + + + + + + + + + + + + + + +``` + +`identifier` is optional on verification components. Supply it when an unauthenticated verification page should support resending a token. The response remains generic whether the account exists or not. + +## CAPTCHA and risk + +The HTTP handlers never trust a browser `captchaVerified` field. CAPTCHA completion is accepted only from server-populated `ctx.locals.captcha.success` or `ctx.locals.captchaVerified === true`. + +Rate limiting remains an application or gateway responsibility. Apply it to registration, login, reset, magic-link, OTP, verification, passkey, invitation, and impersonation endpoints. + +## MFA + +1. Password, OAuth, magic-link, or OTP login may return `code: "mfa-required"` with a short-lived `mfaToken`. +2. The response lists only methods actually available to that user. +3. Email/SMS MFA is offered only for verified linked identities. +4. `beginMfaOtp()` issues an MFA-bound OTP when needed. +5. `completeMfa()` consumes the one-time transaction and creates the session. + +## Passkeys + +The browser runtime coordinates `navigator.credentials.create()` and `navigator.credentials.get()`. A configured server-side `PasskeyProvider` must verify the challenge, RP ID, origin, signature, user presence or verification, counter, and credential ownership. + +Multi-process deployments must provide a shared `PasskeyChallengeStore`; the default memory implementation is process-local. Missing passkey providers return a controlled `503` response rather than crashing the route. + +## Protect long-lived secrets + +```ts +import { createAuthSecretProtector } from "@wrnexus/auth"; +import { createKeyring } from "@wrnexus/encryption"; + +const keyring = createKeyring([ + { + id: "auth-2026-01", + secret: process.env.AUTH_ENCRYPTION_KEY!, + active: true, + }, +]); + +const auth = createAuthEngine({ + store: new SqlAuthStore(getDb()), + secret: process.env.AUTH_SECRET!, + secretProtector: createAuthSecretProtector(keyring), +}); +``` + +TOTP seeds and OAuth access/refresh tokens are protected before persistence. Keep old keys available during rotation. + +## Custom HTTP integration + +`createAuthHttpHandlers()` remains available for custom route paths or response behavior. Prefer package routes for standard flows; copied application API files are unnecessary. + +## Development + +```bash +bun run auth:dev +bun run validate:auth +``` + +Read [SECURITY.md](./SECURITY.md) before production deployment. + +### Exported TypeScript declarations + +```ts +export { A as AuthEngine, c as createAuthEngine, i as inferIdentityType, n as normalizeEmail, a as normalizeIdentity, b as normalizePhone, d as normalizeUsername, p as publicUser, s as safeAuthReturnTo } from './engine-jttXj6PP.js'; +import { n as AuthRiskSignals, l as AuthRiskDecision } from './types-JLkQpcAt.js'; +export { A as AuthAccountStatus, a as AuthClock, b as AuthDeliveryMessage, c as AuthDeliveryProvider, d as AuthEngineOptions, e as AuthIdentity, f as AuthIdentityType, g as AuthImpersonationDecision, h as AuthMfaMethod, i as AuthPublicUser, j as AuthRandom, k as AuthResult, m as AuthRiskLevel, o as AuthSecretProtector, p as AuthSecurityEvent, q as AuthSession, r as AuthSignedInHandler, s as AuthSignedOutHandler, M as AuthStore, t as AuthSuccessfulSignUpAction, u as AuthSuccessfulSignUpHandler, v as AuthTokenPurpose, w as AuthTokenUrlInput, x as AuthUser, y as AuthenticatedContext, L as LoginAttempt, z as LoginInput, N as MemoryPasskeyChallengeStore, O as OAuthAccount, B as OneTimeToken, C as OtpChallenge, P as PasskeyAuthenticationOptions, Q as PasskeyChallengeKind, S as PasskeyChallengeRecord, U as PasskeyChallengeStore, D as PasskeyCredential, E as PasskeyProvider, F as PasskeyRegistrationOptions, G as PasskeyVerificationResult, H as PasswordBreachProvider, I as PasswordCredential, R as RecoveryCodeRecord, J as RegisterInput, T as TotpCredential, K as TrustedDevice, V as assertPasskeyProvider } from './types-JLkQpcAt.js'; +export { MemoryAuthStore } from './stores/memory.js'; +export { SqlAuthStore } from './stores/sql.js'; +export { AUTH_SESSION_KEY, authSession, clearAuthSession, establishAuthSession, getAuthSession, getAuthUser, isAuthenticatedContext, requireAuth } from './middleware.js'; +export { A as AuthHttpOptions, a as AuthPasskeyHttpOptions, b as AuthSchemaOverrides, c as AuthSchemaSet, d as authBrowserSchemaDescriptors, e as authBrowserSchemaMap, f as authSchemas, g as authenticatorConfirmSchema, h as authenticatorDisableSchema, i as authenticatorSetupSchema, j as changePasswordSchema, k as createAuthHttpHandlers, l as emptyActionSchema, m as impersonationStartSchema, n as invitationAcceptSchema, o as loginSchema, p as magicLinkConsumeSchema, q as magicLinkRequestSchema, r as mfaOtpRequestSchema, s as mfaSchema, t as otpIssueSchema, u as otpLoginCompleteSchema, v as otpLoginRequestSchema, w as otpSchema, x as passkeyAuthenticationOptionsSchema, y as passkeyAuthenticationVerifySchema, z as passkeyRegistrationOptionsSchema, B as passkeyRegistrationVerifySchema, C as passwordResetRequestSchema, D as passwordResetSchema, E as recoveryCodesSchema, F as registerSchema, G as resolveAuthSchemas, H as sessionRevokeSchema, I as signUpSchema, J as verificationRequestSchema, K as verificationTokenSchema } from './index-CrF_lZDQ.js'; +export { AuthAuditIssue, AuthConfig, AuthPluginOptions, AuthRoutesConfig, authComponentsDir, authPlugin } from './plugin.js'; +export { DefaultAuthRouteOptions, clearDefaultAuthEngine, getDefaultAuthEngine, getDefaultAuthRouteOptions, getDefaultAuthSchemas, hasDefaultAuthEngine, setDefaultAuthEngine, setDefaultAuthRouteOptions, setDefaultAuthSchemas, tryGetDefaultAuthEngine } from './runtime.js'; +export { createAuthSecretProtector } from './protector.js'; +export { decodeBase32, encodeBase32, generateTotp, generateTotpSecret, totpUri, verifyTotp } from './totp/index.js'; +import '@wrnexus/oauth'; +import '@wrnexus/core'; +import '@wrnexus/db'; +import '@wrnexus/validation'; +import '@wrnexus/plugin'; +import '@wrnexus/encryption'; + +interface RiskPolicy { + captchaThreshold: number; + mfaThreshold: number; + blockThreshold: number; +} +declare function evaluateAuthRisk(signals?: AuthRiskSignals, policy?: RiskPolicy): AuthRiskDecision; + +export { AuthRiskDecision, AuthRiskSignals, type RiskPolicy, evaluateAuthRisk }; +``` + +--- + ## @wrnexus/authz Documentation URL: https://wrnexusjs.dev/packages/authz @@ -18436,6 +20042,38 @@ export async function POST(ctx) { The CAPTCHA runtime binds its required-form check in the capture phase, so a `data-schema` validator cannot submit the form before CAPTCHA verification. After a successful form request, the component automatically creates a fresh challenge. +### Retryable operations such as login + +A login may consume a valid CAPTCHA and then fail because the password is +incorrect. Configure a short action-bound session grant so the user can correct +their credentials without solving CAPTCHA again: + +```ts +const guard = captchaGuard({ + action: "auth-login", + engine, + bindHostname: true, + bindSession: true, + verifiedForMs: 5 * 60_000, +}); +``` + +Keep the verified widget state for non-CAPTCHA form errors: + +```wrn + +``` + +The grant is stored in the current session and bound to the configured action. +Expired grants and CAPTCHA-specific errors still require and load a fresh +challenge. Keep login rate limits and authentication lockout enabled; +`verifiedForMs` removes repeated human verification, not credential-abuse +controls. + ## Validate a schema and CAPTCHA together ```ts @@ -21910,6 +23548,7 @@ interface ServeOptions { mode?: Mode; /** Inject the live-reload client (defaults to true in development). */ hmr?: boolean; + appConfig?: Record; /** Resolved absolute path to the global CSS entry, or null. */ styleEntry?: string | null; /** Custom styles config (e.g. a Tailwind/PostCSS processor). */ @@ -26933,7 +28572,7 @@ type RuleDescriptor = { message?: string; }; interface FieldDescriptor { - type: "string" | "number" | "boolean"; + type: "string" | "number" | "boolean" | "unknown"; optional?: boolean; /** Message used when a required field is empty. Defaults to "Required". */ requiredMessage?: string; @@ -26969,7 +28608,7 @@ type Refinement = { message?: string; }; declare abstract class FieldSchema { - abstract readonly type: "string" | "number" | "boolean"; + abstract readonly type: "string" | "number" | "boolean" | "unknown"; protected _optional: boolean; protected _requiredMessage?: string; protected _label?: string; @@ -27015,9 +28654,19 @@ declare class NumberSchema extends FieldSchema { declare class BooleanSchema extends FieldSchema { readonly type: "boolean"; } +declare class UnknownSchema extends FieldSchema { + readonly type: "unknown"; +} +type AnyFieldSchema = StringSchema | NumberSchema | BooleanSchema | UnknownSchema; declare class ObjectSchema { private readonly fields; constructor(fields: Record); + /** Return a defensive copy of the schema fields. */ + getFields(): Readonly>; + /** Create a new schema with fields added or replaced. The original is unchanged. */ + extend(fields: Record): ObjectSchema; + /** Create a new schema containing fields from both schemas. */ + merge(schema: ObjectSchema): ObjectSchema; /** Validate an input object; returns coerced values + per-field errors. */ parse(input: unknown): ParseResult; describe(): SchemaDescriptor; @@ -27027,6 +28676,7 @@ declare const v: { string: () => StringSchema; number: () => NumberSchema; boolean: () => BooleanSchema; + unknown: () => UnknownSchema; object: (fields: Record) => ObjectSchema; }; /** @@ -27056,5 +28706,5 @@ declare function parseBody>(schema: ObjectSchema, re response: Response; }>; -export { AsyncObjectSchema, type AsyncRefinement, type AsyncValidationContext, type FieldDescriptor, ObjectSchema, type OpenApiSchema, type ParseResult, type RuleDescriptor, type SchemaDescriptor, VALIDATE_RUNTIME, applyRule, asyncSchema, checkField, invalid, mergeValidationResults, parseBody, parseBodyAsync, parseEnv, renderSchemasScript, schemaToOpenApi, v }; +export { type AnyFieldSchema, AsyncObjectSchema, type AsyncRefinement, type AsyncValidationContext, BooleanSchema, type FieldDescriptor, FieldSchema, NumberSchema, ObjectSchema, type OpenApiSchema, type ParseResult, type RuleDescriptor, type SchemaDescriptor, StringSchema, UnknownSchema, VALIDATE_RUNTIME, applyRule, asyncSchema, checkField, invalid, mergeValidationResults, parseBody, parseBodyAsync, parseEnv, renderSchemasScript, schemaToOpenApi, v }; ``` diff --git a/public/sitemap.xml b/public/sitemap.xml index 95fc28bc..42afccaf 100644 --- a/public/sitemap.xml +++ b/public/sitemap.xml @@ -1,2 +1,2 @@ -https://wrnexusjs.dev/https://wrnexusjs.dev/accesshttps://wrnexusjs.dev/getting-startedhttps://wrnexusjs.dev/tutorialhttps://wrnexusjs.dev/architecturehttps://wrnexusjs.dev/languagehttps://wrnexusjs.dev/packageshttps://wrnexusjs.dev/componentshttps://wrnexusjs.dev/guides/project-structurehttps://wrnexusjs.dev/guides/routinghttps://wrnexusjs.dev/guides/pages-and-componentshttps://wrnexusjs.dev/guides/server-datahttps://wrnexusjs.dev/guides/api-routeshttps://wrnexusjs.dev/guides/middlewarehttps://wrnexusjs.dev/guides/forms-and-validationhttps://wrnexusjs.dev/guides/authenticationhttps://wrnexusjs.dev/guides/authorizationhttps://wrnexusjs.dev/guides/securityhttps://wrnexusjs.dev/guides/databasehttps://wrnexusjs.dev/guides/uploadshttps://wrnexusjs.dev/guides/realtimehttps://wrnexusjs.dev/guides/pubsubhttps://wrnexusjs.dev/guides/queueshttps://wrnexusjs.dev/guides/testinghttps://wrnexusjs.dev/guides/workspaces-and-gatewayhttps://wrnexusjs.dev/guides/deploymenthttps://wrnexusjs.dev/guides/configuration-and-profileshttps://wrnexusjs.dev/guides/i18n-and-themeshttps://wrnexusjs.dev/guides/mobilehttps://wrnexusjs.dev/guides/observabilityhttps://wrnexusjs.dev/guides/upgradinghttps://wrnexusjs.dev/guides/troubleshootinghttps://wrnexusjs.dev/exampleshttps://wrnexusjs.dev/showcasehttps://wrnexusjs.dev/benchmarkshttps://wrnexusjs.dev/roadmaphttps://wrnexusjs.dev/changeloghttps://wrnexusjs.dev/releases/0.4.0https://wrnexusjs.dev/securityhttps://wrnexusjs.dev/supporthttps://wrnexusjs.dev/licensehttps://wrnexusjs.dev/searchhttps://wrnexusjs.dev/404https://wrnexusjs.dev/packages/aihttps://wrnexusjs.dev/packages/authzhttps://wrnexusjs.dev/packages/captchahttps://wrnexusjs.dev/packages/clihttps://wrnexusjs.dev/packages/compilerhttps://wrnexusjs.dev/packages/corehttps://wrnexusjs.dev/packages/csrhttps://wrnexusjs.dev/packages/dbhttps://wrnexusjs.dev/packages/dev-serverhttps://wrnexusjs.dev/packages/dev-toolbarhttps://wrnexusjs.dev/packages/encryptionhttps://wrnexusjs.dev/packages/helpershttps://wrnexusjs.dev/packages/i18nhttps://wrnexusjs.dev/packages/jwthttps://wrnexusjs.dev/packages/mobilehttps://wrnexusjs.dev/packages/nativehttps://wrnexusjs.dev/packages/oauthhttps://wrnexusjs.dev/packages/pluginhttps://wrnexusjs.dev/packages/pubsubhttps://wrnexusjs.dev/packages/queuehttps://wrnexusjs.dev/packages/reactivehttps://wrnexusjs.dev/packages/routerhttps://wrnexusjs.dev/packages/ssrhttps://wrnexusjs.dev/packages/styleshttps://wrnexusjs.dev/packages/syntaxhttps://wrnexusjs.dev/packages/testhttps://wrnexusjs.dev/packages/trackinghttps://wrnexusjs.dev/packages/uihttps://wrnexusjs.dev/packages/uploaderhttps://wrnexusjs.dev/packages/validationhttps://wrnexusjs.dev/components/accordionhttps://wrnexusjs.dev/components/advanced-date-pickerhttps://wrnexusjs.dev/components/advanced-range-sliderhttps://wrnexusjs.dev/components/advanced-selecthttps://wrnexusjs.dev/components/alerthttps://wrnexusjs.dev/components/avatarhttps://wrnexusjs.dev/components/avatar-grouphttps://wrnexusjs.dev/components/badgehttps://wrnexusjs.dev/components/blockquotehttps://wrnexusjs.dev/components/breadcrumbhttps://wrnexusjs.dev/components/buttonhttps://wrnexusjs.dev/components/button-grouphttps://wrnexusjs.dev/components/cardhttps://wrnexusjs.dev/components/carouselhttps://wrnexusjs.dev/components/charthttps://wrnexusjs.dev/components/chat-bubblehttps://wrnexusjs.dev/components/checkboxhttps://wrnexusjs.dev/components/clipboardhttps://wrnexusjs.dev/components/collapsehttps://wrnexusjs.dev/components/color-pickerhttps://wrnexusjs.dev/components/columnshttps://wrnexusjs.dev/components/combo-boxhttps://wrnexusjs.dev/components/confettihttps://wrnexusjs.dev/components/containerhttps://wrnexusjs.dev/components/context-menuhttps://wrnexusjs.dev/components/copy-markuphttps://wrnexusjs.dev/components/custom-scrollbarhttps://wrnexusjs.dev/components/data-maphttps://wrnexusjs.dev/components/data-tablehttps://wrnexusjs.dev/components/date-pickerhttps://wrnexusjs.dev/components/device-framehttps://wrnexusjs.dev/components/dividerhttps://wrnexusjs.dev/components/drag-and-drophttps://wrnexusjs.dev/components/drawerhttps://wrnexusjs.dev/components/dropdownhttps://wrnexusjs.dev/components/file-inputhttps://wrnexusjs.dev/components/file-uploadhttps://wrnexusjs.dev/components/file-upload-progresshttps://wrnexusjs.dev/components/gridhttps://wrnexusjs.dev/components/imagehttps://wrnexusjs.dev/components/inputhttps://wrnexusjs.dev/components/input-grouphttps://wrnexusjs.dev/components/input-numberhttps://wrnexusjs.dev/components/kbdhttps://wrnexusjs.dev/components/layout-splitterhttps://wrnexusjs.dev/components/legend-indicatorhttps://wrnexusjs.dev/components/linkhttps://wrnexusjs.dev/components/listhttps://wrnexusjs.dev/components/list-grouphttps://wrnexusjs.dev/components/maphttps://wrnexusjs.dev/components/marqueehttps://wrnexusjs.dev/components/mega-menuhttps://wrnexusjs.dev/components/modalhttps://wrnexusjs.dev/components/navhttps://wrnexusjs.dev/components/navbarhttps://wrnexusjs.dev/components/paginationhttps://wrnexusjs.dev/components/pin-inputhttps://wrnexusjs.dev/components/popoverhttps://wrnexusjs.dev/components/progresshttps://wrnexusjs.dev/components/radiohttps://wrnexusjs.dev/components/range-sliderhttps://wrnexusjs.dev/components/ratinghttps://wrnexusjs.dev/components/scrollspyhttps://wrnexusjs.dev/components/search-boxhttps://wrnexusjs.dev/components/selecthttps://wrnexusjs.dev/components/sidebarhttps://wrnexusjs.dev/components/skeletonhttps://wrnexusjs.dev/components/spinnerhttps://wrnexusjs.dev/components/stepperhttps://wrnexusjs.dev/components/strong-passwordhttps://wrnexusjs.dev/components/styled-iconhttps://wrnexusjs.dev/components/switchhttps://wrnexusjs.dev/components/tablehttps://wrnexusjs.dev/components/tabshttps://wrnexusjs.dev/components/textareahttps://wrnexusjs.dev/components/timelinehttps://wrnexusjs.dev/components/time-pickerhttps://wrnexusjs.dev/components/toasthttps://wrnexusjs.dev/components/toast-notificationshttps://wrnexusjs.dev/components/toggle-counthttps://wrnexusjs.dev/components/toggle-passwordhttps://wrnexusjs.dev/components/tooltiphttps://wrnexusjs.dev/components/tree-viewhttps://wrnexusjs.dev/components/typographyhttps://wrnexusjs.dev/components/wysiwyg-editor +https://wrnexusjs.dev/https://wrnexusjs.dev/accesshttps://wrnexusjs.dev/getting-startedhttps://wrnexusjs.dev/tutorialhttps://wrnexusjs.dev/architecturehttps://wrnexusjs.dev/languagehttps://wrnexusjs.dev/packageshttps://wrnexusjs.dev/componentshttps://wrnexusjs.dev/guides/project-structurehttps://wrnexusjs.dev/guides/routinghttps://wrnexusjs.dev/guides/pages-and-componentshttps://wrnexusjs.dev/guides/server-datahttps://wrnexusjs.dev/guides/api-routeshttps://wrnexusjs.dev/guides/middlewarehttps://wrnexusjs.dev/guides/forms-and-validationhttps://wrnexusjs.dev/guides/authenticationhttps://wrnexusjs.dev/guides/authorizationhttps://wrnexusjs.dev/guides/securityhttps://wrnexusjs.dev/guides/databasehttps://wrnexusjs.dev/guides/uploadshttps://wrnexusjs.dev/guides/realtimehttps://wrnexusjs.dev/guides/pubsubhttps://wrnexusjs.dev/guides/queueshttps://wrnexusjs.dev/guides/testinghttps://wrnexusjs.dev/guides/workspaces-and-gatewayhttps://wrnexusjs.dev/guides/deploymenthttps://wrnexusjs.dev/guides/configuration-and-profileshttps://wrnexusjs.dev/guides/i18n-and-themeshttps://wrnexusjs.dev/guides/mobilehttps://wrnexusjs.dev/guides/observabilityhttps://wrnexusjs.dev/guides/upgradinghttps://wrnexusjs.dev/guides/troubleshootinghttps://wrnexusjs.dev/exampleshttps://wrnexusjs.dev/showcasehttps://wrnexusjs.dev/benchmarkshttps://wrnexusjs.dev/roadmaphttps://wrnexusjs.dev/changeloghttps://wrnexusjs.dev/releases/0.5.0https://wrnexusjs.dev/securityhttps://wrnexusjs.dev/supporthttps://wrnexusjs.dev/licensehttps://wrnexusjs.dev/searchhttps://wrnexusjs.dev/404https://wrnexusjs.dev/packages/aihttps://wrnexusjs.dev/packages/authhttps://wrnexusjs.dev/packages/authzhttps://wrnexusjs.dev/packages/captchahttps://wrnexusjs.dev/packages/clihttps://wrnexusjs.dev/packages/compilerhttps://wrnexusjs.dev/packages/corehttps://wrnexusjs.dev/packages/csrhttps://wrnexusjs.dev/packages/dbhttps://wrnexusjs.dev/packages/dev-serverhttps://wrnexusjs.dev/packages/dev-toolbarhttps://wrnexusjs.dev/packages/encryptionhttps://wrnexusjs.dev/packages/helpershttps://wrnexusjs.dev/packages/i18nhttps://wrnexusjs.dev/packages/jwthttps://wrnexusjs.dev/packages/mobilehttps://wrnexusjs.dev/packages/nativehttps://wrnexusjs.dev/packages/oauthhttps://wrnexusjs.dev/packages/pluginhttps://wrnexusjs.dev/packages/pubsubhttps://wrnexusjs.dev/packages/queuehttps://wrnexusjs.dev/packages/reactivehttps://wrnexusjs.dev/packages/routerhttps://wrnexusjs.dev/packages/ssrhttps://wrnexusjs.dev/packages/styleshttps://wrnexusjs.dev/packages/syntaxhttps://wrnexusjs.dev/packages/testhttps://wrnexusjs.dev/packages/trackinghttps://wrnexusjs.dev/packages/uihttps://wrnexusjs.dev/packages/uploaderhttps://wrnexusjs.dev/packages/validationhttps://wrnexusjs.dev/components/accordionhttps://wrnexusjs.dev/components/advanced-date-pickerhttps://wrnexusjs.dev/components/advanced-range-sliderhttps://wrnexusjs.dev/components/advanced-selecthttps://wrnexusjs.dev/components/alerthttps://wrnexusjs.dev/components/avatarhttps://wrnexusjs.dev/components/avatar-grouphttps://wrnexusjs.dev/components/badgehttps://wrnexusjs.dev/components/blockquotehttps://wrnexusjs.dev/components/breadcrumbhttps://wrnexusjs.dev/components/buttonhttps://wrnexusjs.dev/components/button-grouphttps://wrnexusjs.dev/components/cardhttps://wrnexusjs.dev/components/carouselhttps://wrnexusjs.dev/components/charthttps://wrnexusjs.dev/components/chat-bubblehttps://wrnexusjs.dev/components/checkboxhttps://wrnexusjs.dev/components/clipboardhttps://wrnexusjs.dev/components/collapsehttps://wrnexusjs.dev/components/color-pickerhttps://wrnexusjs.dev/components/columnshttps://wrnexusjs.dev/components/combo-boxhttps://wrnexusjs.dev/components/confettihttps://wrnexusjs.dev/components/containerhttps://wrnexusjs.dev/components/context-menuhttps://wrnexusjs.dev/components/copy-markuphttps://wrnexusjs.dev/components/custom-scrollbarhttps://wrnexusjs.dev/components/data-maphttps://wrnexusjs.dev/components/data-tablehttps://wrnexusjs.dev/components/date-pickerhttps://wrnexusjs.dev/components/device-framehttps://wrnexusjs.dev/components/dividerhttps://wrnexusjs.dev/components/drag-and-drophttps://wrnexusjs.dev/components/drawerhttps://wrnexusjs.dev/components/dropdownhttps://wrnexusjs.dev/components/file-inputhttps://wrnexusjs.dev/components/file-uploadhttps://wrnexusjs.dev/components/file-upload-progresshttps://wrnexusjs.dev/components/gridhttps://wrnexusjs.dev/components/imagehttps://wrnexusjs.dev/components/inputhttps://wrnexusjs.dev/components/input-grouphttps://wrnexusjs.dev/components/input-numberhttps://wrnexusjs.dev/components/kbdhttps://wrnexusjs.dev/components/layout-splitterhttps://wrnexusjs.dev/components/legend-indicatorhttps://wrnexusjs.dev/components/linkhttps://wrnexusjs.dev/components/listhttps://wrnexusjs.dev/components/list-grouphttps://wrnexusjs.dev/components/maphttps://wrnexusjs.dev/components/marqueehttps://wrnexusjs.dev/components/mega-menuhttps://wrnexusjs.dev/components/modalhttps://wrnexusjs.dev/components/navhttps://wrnexusjs.dev/components/navbarhttps://wrnexusjs.dev/components/paginationhttps://wrnexusjs.dev/components/pin-inputhttps://wrnexusjs.dev/components/popoverhttps://wrnexusjs.dev/components/progresshttps://wrnexusjs.dev/components/radiohttps://wrnexusjs.dev/components/range-sliderhttps://wrnexusjs.dev/components/ratinghttps://wrnexusjs.dev/components/scrollspyhttps://wrnexusjs.dev/components/search-boxhttps://wrnexusjs.dev/components/selecthttps://wrnexusjs.dev/components/sidebarhttps://wrnexusjs.dev/components/skeletonhttps://wrnexusjs.dev/components/spinnerhttps://wrnexusjs.dev/components/stepperhttps://wrnexusjs.dev/components/strong-passwordhttps://wrnexusjs.dev/components/styled-iconhttps://wrnexusjs.dev/components/switchhttps://wrnexusjs.dev/components/tablehttps://wrnexusjs.dev/components/tabshttps://wrnexusjs.dev/components/textareahttps://wrnexusjs.dev/components/timelinehttps://wrnexusjs.dev/components/time-pickerhttps://wrnexusjs.dev/components/toasthttps://wrnexusjs.dev/components/toast-notificationshttps://wrnexusjs.dev/components/toggle-counthttps://wrnexusjs.dev/components/toggle-passwordhttps://wrnexusjs.dev/components/tooltiphttps://wrnexusjs.dev/components/tree-viewhttps://wrnexusjs.dev/components/typographyhttps://wrnexusjs.dev/components/wysiwyg-editor