Files
WRNexusJSDoc/app/pages/components/input-number.wrn
T

655 lines
36 KiB
Plaintext

page InputNumbercomponent {
seo {
title = "InputNumber component"
description = "Theme-aware, responsive input number component."
}
view {
<div class="docs-shell">
<SkipLink label="Skip to content" href="#main" class="docs-skip-link" />
<header class="topbar">
<a class="brand" href="/"><span>W</span> WRNexusJS</a>
<nav aria-label="Primary"><a href="/getting-started">Get started</a><a href="/packages">Packages</a><a href="/components">Components</a><a href="/language">Language</a><a href="/architecture">Architecture</a></nav>
<div class="topbar-actions"><a class="preview-pill" href="/access">Private preview · v0.5.0</a><button data-wire-theme-toggle class="theme-button" aria-label="Toggle color theme" title="Toggle color theme">◐</button></div>
</header>
<div class="mobile-doc-nav"><details><summary>Browse documentation</summary><nav><a href="/getting-started">Get started</a><a href="/packages">Packages</a><a href="/components">Components</a><a href="/language">Language</a><a href="/architecture">Architecture</a><a href="/tutorial">Tutorial</a><a href="/guides/project-structure">Guides</a><a href="/examples">Examples</a><a href="/search">Search</a></nav></details></div>
<main class="portal-main docs-layout component-detail-page"><article id="main" class="documentation prose standalone"><nav class="breadcrumbs" aria-label="Breadcrumb"><a href="/">Home</a><span>/</span><a href="/components">Components</a><span>/</span><span aria-current="page">InputNumber</span></nav><section class="doc-intro"><span class="eyebrow">advanced-forms component</span><h1>InputNumber</h1><p>Theme-aware, responsive input number component.</p><div class="doc-meta"><span>@wrnexus/ui 0.5.0</span><span>40 props</span><span>0 slots</span><span>4 events</span></div></section><section id="usage"><h2>Usage</h2><p>Components are auto-discovered. Use the component directly in any <code>.wrn</code> view:</p><pre data-language="wrn"><code>&lt;InputNumber
size=&quot;default&quot;
color=&quot;primary&quot;
variant=&quot;default&quot;
id=&quot;id&quot;
name=&quot;quantity&quot;
/&gt;</code></pre><p>Legacy mount name: <code>data-component=&quot;InputNumber&quot;</code>.</p></section><section id="props"><h2>Props and attributes</h2><div class="table-wrap"><table><thead><tr><th>Prop</th><th>Type</th><th>Requirement</th><th>Default</th></tr></thead><tbody><tr><td><code>size</code></td><td><code>string</code></td><td>Optional</td><td><code>&quot;default&quot;</code></td></tr><tr><td><code>color</code></td><td><code>string</code></td><td>Optional</td><td><code>&quot;primary&quot;</code></td></tr><tr><td><code>variant</code></td><td><code>string</code></td><td>Optional</td><td><code>&quot;default&quot;</code></td></tr><tr><td><code>class</code></td><td><code>string</code></td><td>Optional</td><td><code>&quot;&quot;</code></td></tr><tr><td><code>id</code></td><td><code>string</code></td><td>Optional</td><td><code>&quot;&quot;</code></td></tr><tr><td><code>name</code></td><td><code>string</code></td><td>Optional</td><td><code>&quot;quantity&quot;</code></td></tr><tr><td><code>value</code></td><td><code>number</code></td><td>Optional</td><td><code>0</code></td></tr><tr><td><code>min</code></td><td><code>string</code></td><td>Optional</td><td><code>&quot;&quot;</code></td></tr><tr><td><code>max</code></td><td><code>string</code></td><td>Optional</td><td><code>&quot;&quot;</code></td></tr><tr><td><code>step</code></td><td><code>number</code></td><td>Optional</td><td><code>1</code></td></tr><tr><td><code>precision</code></td><td><code>string</code></td><td>Optional</td><td><code>&quot;auto&quot;</code></td></tr><tr><td><code>label</code></td><td><code>string</code></td><td>Optional</td><td><code>&quot;&quot;</code></td></tr><tr><td><code>description</code></td><td><code>string</code></td><td>Optional</td><td><code>&quot;&quot;</code></td></tr><tr><td><code>helpText</code></td><td><code>string</code></td><td>Optional</td><td><code>&quot;&quot;</code></td></tr><tr><td><code>error</code></td><td><code>string</code></td><td>Optional</td><td><code>&quot;&quot;</code></td></tr><tr><td><code>invalid</code></td><td><code>boolean</code></td><td>Optional</td><td><code>false</code></td></tr><tr><td><code>prefix</code></td><td><code>string</code></td><td>Optional</td><td><code>&quot;&quot;</code></td></tr><tr><td><code>suffix</code></td><td><code>string</code></td><td>Optional</td><td><code>&quot;&quot;</code></td></tr><tr><td><code>placeholder</code></td><td><code>string</code></td><td>Optional</td><td><code>&quot;&quot;</code></td></tr><tr><td><code>autocomplete</code></td><td><code>string</code></td><td>Optional</td><td><code>&quot;off&quot;</code></td></tr><tr><td><code>inputMode</code></td><td><code>string</code></td><td>Optional</td><td><code>&quot;decimal&quot;</code></td></tr><tr><td><code>ariaLabel</code></td><td><code>string</code></td><td>Optional</td><td><code>&quot;&quot;</code></td></tr><tr><td><code>required</code></td><td><code>boolean</code></td><td>Optional</td><td><code>false</code></td></tr><tr><td><code>disabled</code></td><td><code>boolean</code></td><td>Optional</td><td><code>false</code></td></tr><tr><td><code>inputDisabled</code></td><td><code>boolean</code></td><td>Optional</td><td><code>false</code></td></tr><tr><td><code>buttonsDisabled</code></td><td><code>boolean</code></td><td>Optional</td><td><code>false</code></td></tr><tr><td><code>readonly</code></td><td><code>boolean</code></td><td>Optional</td><td><code>false</code></td></tr><tr><td><code>allowInput</code></td><td><code>boolean</code></td><td>Optional</td><td><code>true</code></td></tr><tr><td><code>keyboard</code></td><td><code>boolean</code></td><td>Optional</td><td><code>true</code></td></tr><tr><td><code>wheel</code></td><td><code>boolean</code></td><td>Optional</td><td><code>false</code></td></tr><tr><td><code>clamp</code></td><td><code>boolean</code></td><td>Optional</td><td><code>true</code></td></tr><tr><td><code>fullWidth</code></td><td><code>boolean</code></td><td>Optional</td><td><code>false</code></td></tr><tr><td><code>showButtons</code></td><td><code>boolean</code></td><td>Optional</td><td><code>true</code></td></tr><tr><td><code>showValidationMessage</code></td><td><code>boolean</code></td><td>Optional</td><td><code>true</code></td></tr><tr><td><code>decrementLabel</code></td><td><code>string</code></td><td>Optional</td><td><code>&quot;Decrease value&quot;</code></td></tr><tr><td><code>incrementLabel</code></td><td><code>string</code></td><td>Optional</td><td><code>&quot;Increase value&quot;</code></td></tr><tr><td><code>controlsLabel</code></td><td><code>string</code></td><td>Optional</td><td><code>&quot;Quantity controls&quot;</code></td></tr><tr><td><code>requiredMessage</code></td><td><code>string</code></td><td>Optional</td><td><code>&quot;A value is required.&quot;</code></td></tr><tr><td><code>minMessage</code></td><td><code>string</code></td><td>Optional</td><td><code>&quot;Value is below the minimum.&quot;</code></td></tr><tr><td><code>maxMessage</code></td><td><code>string</code></td><td>Optional</td><td><code>&quot;Value is above the maximum.&quot;</code></td></tr></tbody></table></div></section><section id="slots"><h2>Slots</h2><p>This component does not declare a slot.</p></section><section id="events"><h2>Events</h2><ul><li><code>input</code></li><li><code>change</code></li><li><code>increment</code></li><li><code>decrement</code></li></ul></section><section id="source"><h2>Source contract</h2><p>Installed source: <code>components/InputNumber.wrn</code></p><pre data-language="wrn"><code>component InputNumber &#123;
props &#123;
size = &quot;default&quot;
color = &quot;primary&quot;
variant = &quot;default&quot;
class = &quot;&quot;
id = &quot;&quot;
name = &quot;quantity&quot;
value = 0
min = &quot;&quot;
max = &quot;&quot;
step = 1
precision = &quot;auto&quot;
label = &quot;&quot;
description = &quot;&quot;
helpText = &quot;&quot;
error = &quot;&quot;
invalid = false
prefix = &quot;&quot;
suffix = &quot;&quot;
placeholder = &quot;&quot;
autocomplete = &quot;off&quot;
inputMode = &quot;decimal&quot;
ariaLabel = &quot;&quot;
required = false
disabled = false
inputDisabled = false
buttonsDisabled = false
readonly = false
allowInput = true
keyboard = true
wheel = false
clamp = true
fullWidth = false
showButtons = true
showValidationMessage = true
decrementLabel = &quot;Decrease value&quot;
incrementLabel = &quot;Increase value&quot;
controlsLabel = &quot;Quantity controls&quot;
requiredMessage = &quot;A value is required.&quot;
minMessage = &quot;Value is below the minimum.&quot;
maxMessage = &quot;Value is above the maximum.&quot;
@event input = function
@event change = function
@event increment = function
@event decrement = function
&#125;
state currentValue = value
state committedValue = value
functions &#123;
function inputId() &#123;
if (id !== &quot;&quot;) &#123;
return id
&#125;
if (name !== &quot;&quot;) &#123;
return name
&#125;
return &quot;input-number&quot;
&#125;
function descriptionId() &#123;
return inputId() + &quot;-description&quot;
&#125;
function messageId() &#123;
return inputId() + &quot;-message&quot;
&#125;
function componentColor() &#123;
if (color === &quot;secondary&quot;) &#123;
return &quot;var(--wire-color-secondary)&quot;
&#125;
if (color === &quot;success&quot;) &#123;
return &quot;var(--wire-color-success)&quot;
&#125;
if (color === &quot;warning&quot;) &#123;
return &quot;var(--wire-color-warning)&quot;
&#125;
if (color === &quot;danger&quot;) &#123;
return &quot;var(--wire-color-danger)&quot;
&#125;
if (color === &quot;info&quot;) &#123;
return &quot;var(--wire-color-info)&quot;
&#125;
return &quot;var(--wire-color-primary)&quot;
&#125;
function hasMin() &#123;
return min !== &quot;&quot; &amp;&amp; min !== null &amp;&amp; min !== undefined
&#125;
function hasMax() &#123;
return max !== &quot;&quot; &amp;&amp; max !== null &amp;&amp; max !== undefined
&#125;
function isBlank() &#123;
return currentValue === &quot;&quot; || currentValue === null || currentValue === undefined
&#125;
function normalizedStep() &#123;
return Number(step) &gt; 0 ? Number(step) : 1
&#125;
function inferredPrecision() &#123;
if (precision !== &quot;auto&quot; &amp;&amp; precision !== &quot;&quot;) &#123;
return Math.max(0, Number(precision) || 0)
&#125;
if (String(normalizedStep()).includes(&quot;.&quot;)) &#123;
return String(normalizedStep()).split(&quot;.&quot;)[1].length
&#125;
return 0
&#125;
function precisionFactor() &#123;
return Math.pow(10, inferredPrecision())
&#125;
function roundValue(nextValue) &#123;
return Math.round(Number(nextValue) * precisionFactor()) / precisionFactor()
&#125;
function clampValue(nextValue) &#123;
nextValue = Number(nextValue)
if (hasMin() &amp;&amp; nextValue &lt; Number(min)) &#123;
nextValue = Number(min)
&#125;
if (hasMax() &amp;&amp; nextValue &gt; Number(max)) &#123;
nextValue = Number(max)
&#125;
return roundValue(nextValue)
&#125;
function isBelowMin() &#123;
return !isBlank() &amp;&amp; hasMin() &amp;&amp; Number(currentValue) &lt; Number(min)
&#125;
function isAboveMax() &#123;
return !isBlank() &amp;&amp; hasMax() &amp;&amp; Number(currentValue) &gt; Number(max)
&#125;
function isInvalid() &#123;
return (
invalid ||
error !== &quot;&quot; ||
(required &amp;&amp; isBlank()) ||
isBelowMin() ||
isAboveMax()
)
&#125;
function validationMessage() &#123;
if (error !== &quot;&quot;) &#123;
return error
&#125;
if (required &amp;&amp; isBlank()) &#123;
return requiredMessage
&#125;
if (isBelowMin()) &#123;
return minMessage
&#125;
if (isAboveMax()) &#123;
return maxMessage
&#125;
return &quot;&quot;
&#125;
function hasMessage() &#123;
return (
helpText !== &quot;&quot; ||
(showValidationMessage &amp;&amp; isInvalid() &amp;&amp; validationMessage() !== &quot;&quot;)
)
&#125;
function describedBy() &#123;
if (description !== &quot;&quot; &amp;&amp; hasMessage()) &#123;
return descriptionId() + &quot; &quot; + messageId()
&#125;
if (description !== &quot;&quot;) &#123;
return descriptionId()
&#125;
if (hasMessage()) &#123;
return messageId()
&#125;
return &quot;&quot;
&#125;
function decrementDisabled() &#123;
return (
disabled ||
readonly ||
buttonsDisabled ||
(hasMin() &amp;&amp; !isBlank() &amp;&amp; Number(currentValue) &lt;= Number(min))
)
&#125;
function incrementDisabled() &#123;
return (
disabled ||
readonly ||
buttonsDisabled ||
(hasMax() &amp;&amp; !isBlank() &amp;&amp; Number(currentValue) &gt;= Number(max))
)
&#125;
function dispatchInputNumberEvent(
sourceEvent,
eventName,
action,
previousValue,
root,
customEvent
) &#123;
root = sourceEvent.currentTarget.closest(&quot;[data-wrn-input-number]&quot;)
if (!root &amp;&amp; sourceEvent.target) &#123;
root = sourceEvent.target.closest(&quot;[data-wrn-input-number]&quot;)
&#125;
if (!root) &#123;
return
&#125;
customEvent = document.createEvent(&quot;CustomEvent&quot;)
customEvent.initCustomEvent(eventName, true, false, &#123;
component: &quot;InputNumber&quot;,
name: name,
value: currentValue,
previousValue: previousValue,
action: action,
min: hasMin() ? Number(min) : null,
max: hasMax() ? Number(max) : null,
step: normalizedStep(),
valid: !isInvalid()
&#125;)
root.dispatchEvent(customEvent)
&#125;
function applyControlValue(nextValue, action, sourceEvent, previousValue) &#123;
previousValue = currentValue
currentValue = clampValue(nextValue)
committedValue = currentValue
dispatchInputNumberEvent(
sourceEvent,
&quot;input&quot;,
action,
previousValue
)
dispatchInputNumberEvent(
sourceEvent,
&quot;change&quot;,
action,
previousValue
)
dispatchInputNumberEvent(
sourceEvent,
action,
action,
previousValue
)
&#125;
function incrementValue(sourceEvent, nextValue) &#123;
if (incrementDisabled()) &#123;
return
&#125;
if (isBlank()) &#123;
nextValue = hasMin() ? Number(min) : normalizedStep()
&#125; else &#123;
nextValue =
Number(currentValue) +
normalizedStep() * (sourceEvent.shiftKey ? 10 : 1)
&#125;
applyControlValue(nextValue, &quot;increment&quot;, sourceEvent)
&#125;
function decrementValue(sourceEvent, nextValue) &#123;
if (decrementDisabled()) &#123;
return
&#125;
if (isBlank()) &#123;
nextValue = hasMax() ? Number(max) : -normalizedStep()
&#125; else &#123;
nextValue =
Number(currentValue) -
normalizedStep() * (sourceEvent.shiftKey ? 10 : 1)
&#125;
applyControlValue(nextValue, &quot;decrement&quot;, sourceEvent)
&#125;
function handleInput(sourceEvent, previousValue, nextValue) &#123;
sourceEvent.stopPropagation()
previousValue = currentValue
nextValue = sourceEvent.target.value
if (nextValue === &quot;&quot;) &#123;
currentValue = &quot;&quot;
&#125; else if (!Number.isNaN(Number(nextValue))) &#123;
currentValue = roundValue(Number(nextValue))
&#125;
dispatchInputNumberEvent(
sourceEvent,
&quot;input&quot;,
&quot;input&quot;,
previousValue
)
&#125;
function handleChange(sourceEvent, previousValue) &#123;
sourceEvent.stopPropagation()
previousValue = committedValue
if (!isBlank()) &#123;
currentValue = clamp
? clampValue(currentValue)
: roundValue(currentValue)
&#125;
committedValue = currentValue
dispatchInputNumberEvent(
sourceEvent,
&quot;change&quot;,
&quot;change&quot;,
previousValue
)
&#125;
function handleKeydown(sourceEvent) &#123;
if (
!keyboard ||
disabled ||
readonly ||
inputDisabled ||
!allowInput
) &#123;
return
&#125;
if (sourceEvent.key === &quot;ArrowUp&quot;) &#123;
sourceEvent.preventDefault()
incrementValue(sourceEvent)
&#125; else if (sourceEvent.key === &quot;ArrowDown&quot;) &#123;
sourceEvent.preventDefault()
decrementValue(sourceEvent)
&#125; else if (sourceEvent.key === &quot;Home&quot; &amp;&amp; hasMin()) &#123;
sourceEvent.preventDefault()
applyControlValue(Number(min), &quot;decrement&quot;, sourceEvent)
&#125; else if (sourceEvent.key === &quot;End&quot; &amp;&amp; hasMax()) &#123;
sourceEvent.preventDefault()
applyControlValue(Number(max), &quot;increment&quot;, sourceEvent)
&#125;
&#125;
function handleWheel(sourceEvent) &#123;
if (
!wheel ||
disabled ||
readonly ||
inputDisabled ||
!allowInput
) &#123;
return
&#125;
sourceEvent.preventDefault()
if (sourceEvent.deltaY &lt; 0) &#123;
incrementValue(sourceEvent)
&#125; else if (sourceEvent.deltaY &gt; 0) &#123;
decrementValue(sourceEvent)
&#125;
&#125;
&#125;
view &#123;
&lt;div
&#123;...attrs&#125;
data-wrn-input-number
data-variant='&#123;variant&#125;'
data-size='&#123;size&#125;'
data-color='&#123;color&#125;'
data-value='&#123;currentValue&#125;'
data-invalid='&#123;isInvalid() ? &quot;true&quot; : &quot;false&quot;&#125;'
data-disabled='&#123;disabled ? &quot;true&quot; : &quot;false&quot;&#125;'
style='--input-number-accent: &#123;componentColor()&#125;;'
class='relative flex flex-col gap-1.5 text-[var(--wire-color-text)] &#123;fullWidth ? &quot;w-full&quot; : variant === &quot;compact&quot; ? &quot;w-fit max-w-full&quot; : &quot;w-full max-w-sm&quot;&#125; &#123;disabled ? &quot;opacity-60&quot; : &quot;&quot;&#125; &#123;class&#125;'
&gt;
&#123;#if label !== &quot;&quot; &amp;&amp; variant !== &quot;labeled&quot; &amp;&amp; variant !== &quot;seat&quot;&#125;
&lt;label
for='&#123;inputId()&#125;'
class='inline-flex items-center gap-1 text-sm font-semibold leading-5 text-[var(--wire-color-text)]'
&gt;
&lt;span&gt;&#123;label&#125;&lt;/span&gt;
&#123;#if required&#125;
&lt;span
aria-hidden=&quot;true&quot;
class='text-[var(--wire-color-danger)]'
&gt;*&lt;/span&gt;
&#123;/if&#125;
&lt;/label&gt;
&#123;/if&#125;
&#123;#if description !== &quot;&quot; &amp;&amp; variant !== &quot;labeled&quot; &amp;&amp; variant !== &quot;seat&quot;&#125;
&lt;p
id='&#123;descriptionId()&#125;'
class='m-0 text-xs leading-5 text-[var(--wire-color-muted)]'
&gt;
&#123;description&#125;
&lt;/p&gt;
&#123;/if&#125;
&lt;div
class='group flex min-w-0 overflow-hidden border bg-[var(--wire-color-surface)] text-[var(--wire-color-text)] shadow-[var(--wire-shadow-1)] transition-[border-color,box-shadow,background-color] duration-[var(--wire-motion-base)] ease-[var(--wire-ease-standard)] focus-within:border-[var(--input-number-accent)] focus-within:shadow-[0_0_0_3px_color-mix(in_srgb,var(--input-number-accent)_18%,transparent)] &#123;variant === &quot;compact&quot; ? &quot;rounded-full&quot; : &quot;rounded-[var(--wire-radius-sm)]&quot;&#125; &#123;size === &quot;xs&quot; ? &quot;min-h-8 text-xs&quot; : size === &quot;sm&quot; ? &quot;min-h-9 text-sm&quot; : size === &quot;lg&quot; ? &quot;min-h-12 text-base&quot; : size === &quot;xl&quot; ? &quot;min-h-14 text-lg&quot; : &quot;min-h-10 text-sm&quot;&#125; &#123;isInvalid() ? &quot;border-[var(--wire-color-danger)] focus-within:border-[var(--wire-color-danger)] focus-within:shadow-[0_0_0_3px_color-mix(in_srgb,var(--wire-color-danger)_18%,transparent)]&quot; : &quot;border-[var(--wire-color-border)]&quot;&#125; &#123;disabled ? &quot;cursor-not-allowed bg-[var(--wire-color-surface-2)]&quot; : &quot;&quot;&#125;'
&gt;
&#123;#if variant === &quot;horizontal&quot; &amp;&amp; showButtons&#125;
&lt;button
type=&quot;button&quot;
aria-label='&#123;decrementLabel&#125;'
aria-controls='&#123;inputId()&#125;'
disabled='&#123;decrementDisabled()&#125;'
@click='decrementValue(event)'
class='inline-flex shrink-0 items-center justify-center border-r border-[var(--wire-color-border)] bg-transparent text-[var(--wire-color-muted)] transition-[color,background-color] duration-[var(--wire-motion-fast)] hover:bg-[var(--wire-color-surface-2)] hover:text-[var(--input-number-accent)] focus-visible:z-10 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-[var(--input-number-accent)] disabled:cursor-not-allowed disabled:opacity-40 &#123;size === &quot;xs&quot; ? &quot;w-8&quot; : size === &quot;sm&quot; ? &quot;w-9&quot; : size === &quot;lg&quot; ? &quot;w-12&quot; : size === &quot;xl&quot; ? &quot;w-14&quot; : &quot;w-10&quot;&#125;'
&gt;
&lt;span
aria-hidden=&quot;true&quot;
class='icon-[lucide--minus] size-4'
&gt;
&lt;/span&gt;
&lt;/button&gt;
&#123;/if&#125;
&lt;div
class='flex min-w-0 flex-1 &#123;variant === &quot;labeled&quot; ? &quot;flex-col items-stretch justify-center gap-0.5&quot; : variant === &quot;seat&quot; ? &quot;items-center justify-between gap-3&quot; : &quot;items-center&quot;&#125; &#123;size === &quot;xs&quot; ? &quot;px-2&quot; : size === &quot;sm&quot; ? &quot;px-2.5&quot; : size === &quot;lg&quot; ? &quot;px-4&quot; : size === &quot;xl&quot; ? &quot;px-5&quot; : &quot;px-3&quot;&#125;'
&gt;
&#123;#if variant === &quot;labeled&quot; || variant === &quot;seat&quot;&#125;
&lt;div class='min-w-0 flex-1'&gt;
&#123;#if label !== &quot;&quot;&#125;
&lt;label
for='&#123;inputId()&#125;'
class='block truncate font-semibold leading-4 text-[var(--wire-color-text)] &#123;variant === &quot;labeled&quot; ? &quot;text-xs font-medium text-[var(--wire-color-muted)]&quot; : &quot;text-sm&quot;&#125;'
&gt;
&#123;label&#125;
&#123;#if required&#125;
&lt;span
aria-hidden=&quot;true&quot;
class='ml-0.5 text-[var(--wire-color-danger)]'
&gt;*&lt;/span&gt;
&#123;/if&#125;
&lt;/label&gt;
&#123;/if&#125;
&#123;#if description !== &quot;&quot;&#125;
&lt;span
id='&#123;descriptionId()&#125;'
class='block truncate text-xs leading-4 text-[var(--wire-color-muted)]'
&gt;
&#123;description&#125;
&lt;/span&gt;
&#123;/if&#125;
&lt;/div&gt;
&#123;/if&#125;
&lt;div
class='flex min-w-0 items-center &#123;variant === &quot;seat&quot; ? &quot;w-auto shrink-0&quot; : &quot;w-full&quot;&#125;'
&gt;
&#123;#if prefix !== &quot;&quot;&#125;
&lt;span
aria-hidden=&quot;true&quot;
class='shrink-0 pr-1.5 text-[var(--wire-color-muted)]'
&gt;
&#123;prefix&#125;
&lt;/span&gt;
&#123;/if&#125;
&lt;input
id='&#123;inputId()&#125;'
name='&#123;name&#125;'
type=&quot;number&quot;
value='&#123;currentValue&#125;'
min='&#123;min&#125;'
max='&#123;max&#125;'
step='&#123;normalizedStep()&#125;'
placeholder='&#123;placeholder&#125;'
autocomplete='&#123;autocomplete&#125;'
inputmode='&#123;inputMode&#125;'
aria-label='&#123;ariaLabel !== &quot;&quot; ? ariaLabel : label !== &quot;&quot; ? label : name&#125;'
aria-describedby='&#123;describedBy()&#125;'
aria-invalid='&#123;isInvalid() ? &quot;true&quot; : &quot;false&quot;&#125;'
aria-required='&#123;required ? &quot;true&quot; : &quot;false&quot;&#125;'
aria-disabled='&#123;disabled || inputDisabled ? &quot;true&quot; : &quot;false&quot;&#125;'
required='&#123;required&#125;'
disabled='&#123;disabled&#125;'
readonly='&#123;readonly || inputDisabled || !allowInput&#125;'
tabindex='&#123;inputDisabled ? &quot;-1&quot; : &quot;0&quot;&#125;'
@input='handleInput(event)'
@change='handleChange(event)'
@keydown='handleKeydown(event)'
@wheel='handleWheel(event)'
class='min-w-0 flex-1 appearance-none border-0 bg-transparent p-0 font-medium leading-none text-[var(--wire-color-text)] outline-none placeholder:text-[var(--wire-color-muted)] read-only:cursor-default disabled:cursor-not-allowed [&amp;::-webkit-inner-spin-button]:appearance-none [&amp;::-webkit-outer-spin-button]:appearance-none &#123;variant === &quot;horizontal&quot; || variant === &quot;compact&quot; || variant === &quot;seat&quot; ? &quot;text-center&quot; : &quot;text-left&quot;&#125; &#123;variant === &quot;seat&quot; ? &quot;w-10 flex-none&quot; : &quot;w-full&quot;&#125;'
/&gt;
&#123;#if suffix !== &quot;&quot;&#125;
&lt;span
aria-hidden=&quot;true&quot;
class='shrink-0 pl-1.5 text-[var(--wire-color-muted)]'
&gt;
&#123;suffix&#125;
&lt;/span&gt;
&#123;/if&#125;
&lt;/div&gt;
&lt;/div&gt;
&#123;#if variant === &quot;horizontal&quot; &amp;&amp; showButtons&#125;
&lt;button
type=&quot;button&quot;
aria-label='&#123;incrementLabel&#125;'
aria-controls='&#123;inputId()&#125;'
disabled='&#123;incrementDisabled()&#125;'
@click='incrementValue(event)'
class='inline-flex shrink-0 items-center justify-center border-l border-[var(--wire-color-border)] bg-transparent text-[var(--wire-color-muted)] transition-[color,background-color] duration-[var(--wire-motion-fast)] hover:bg-[var(--wire-color-surface-2)] hover:text-[var(--input-number-accent)] focus-visible:z-10 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-[var(--input-number-accent)] disabled:cursor-not-allowed disabled:opacity-40 &#123;size === &quot;xs&quot; ? &quot;w-8&quot; : size === &quot;sm&quot; ? &quot;w-9&quot; : size === &quot;lg&quot; ? &quot;w-12&quot; : size === &quot;xl&quot; ? &quot;w-14&quot; : &quot;w-10&quot;&#125;'
&gt;
&lt;span
aria-hidden=&quot;true&quot;
class='icon-[lucide--plus] size-4'
&gt;
&lt;/span&gt;
&lt;/button&gt;
&#123;:else&#125;
&#123;#if showButtons&#125;
&lt;div
role=&quot;group&quot;
aria-label='&#123;controlsLabel&#125;'
class='flex shrink-0 border-l border-[var(--wire-color-border)] &#123;variant === &quot;vertical&quot; ? &quot;flex-col&quot; : &quot;flex-row&quot;&#125;'
&gt;
&lt;button
type=&quot;button&quot;
aria-label='&#123;decrementLabel&#125;'
aria-controls='&#123;inputId()&#125;'
disabled='&#123;decrementDisabled()&#125;'
@click='decrementValue(event)'
class='inline-flex items-center justify-center bg-transparent text-[var(--wire-color-muted)] transition-[color,background-color] duration-[var(--wire-motion-fast)] hover:bg-[var(--wire-color-surface-2)] hover:text-[var(--input-number-accent)] focus-visible:z-10 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-[var(--input-number-accent)] disabled:cursor-not-allowed disabled:opacity-40 &#123;variant === &quot;vertical&quot; ? &quot;flex-1 border-b border-[var(--wire-color-border)]&quot; : &quot;border-r border-[var(--wire-color-border)]&quot;&#125; &#123;size === &quot;xs&quot; ? &quot;w-8&quot; : size === &quot;sm&quot; ? &quot;w-9&quot; : size === &quot;lg&quot; ? &quot;w-12&quot; : size === &quot;xl&quot; ? &quot;w-14&quot; : &quot;w-10&quot;&#125;'
&gt;
&lt;span
aria-hidden=&quot;true&quot;
class='icon-[lucide--minus] size-4'
&gt;
&lt;/span&gt;
&lt;/button&gt;
&lt;button
type=&quot;button&quot;
aria-label='&#123;incrementLabel&#125;'
aria-controls='&#123;inputId()&#125;'
disabled='&#123;incrementDisabled()&#125;'
@click='incrementValue(event)'
class='inline-flex items-center justify-center bg-transparent text-[var(--wire-color-muted)] transition-[color,background-color] duration-[var(--wire-motion-fast)] hover:bg-[var(--wire-color-surface-2)] hover:text-[var(--input-number-accent)] focus-visible:z-10 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-[var(--input-number-accent)] disabled:cursor-not-allowed disabled:opacity-40 &#123;variant === &quot;vertical&quot; ? &quot;flex-1&quot; : &quot;&quot;&#125; &#123;size === &quot;xs&quot; ? &quot;w-8&quot; : size === &quot;sm&quot; ? &quot;w-9&quot; : size === &quot;lg&quot; ? &quot;w-12&quot; : size === &quot;xl&quot; ? &quot;w-14&quot; : &quot;w-10&quot;&#125;'
&gt;
&lt;span
aria-hidden=&quot;true&quot;
class='icon-[lucide--plus] size-4'
&gt;
&lt;/span&gt;
&lt;/button&gt;
&lt;/div&gt;
&#123;/if&#125;
&#123;/if&#125;
&lt;/div&gt;
&#123;#if showValidationMessage &amp;&amp; isInvalid() &amp;&amp; validationMessage() !== &quot;&quot;&#125;
&lt;p
id='&#123;messageId()&#125;'
role=&quot;alert&quot;
aria-live=&quot;polite&quot;
class='m-0 flex items-center gap-1.5 text-xs leading-5 text-[var(--wire-color-danger)]'
&gt;
&lt;span
aria-hidden=&quot;true&quot;
class='icon-[lucide--circle-alert] size-3.5 shrink-0'
&gt;
&lt;/span&gt;
&lt;span&gt;&#123;validationMessage()&#125;&lt;/span&gt;
&lt;/p&gt;
&#123;/if&#125;
&#123;#if (!showValidationMessage || !isInvalid() || validationMessage() === &quot;&quot;) &amp;&amp; helpText !== &quot;&quot;&#125;
&lt;p
id='&#123;messageId()&#125;'
class='m-0 text-xs leading-5 text-[var(--wire-color-muted)]'
&gt;
&#123;helpText&#125;
&lt;/p&gt;
&#123;/if&#125;
&lt;/div&gt;
&#125;
&#125;
</code></pre></section></article><aside class="on-this-page"><h2>On this page</h2><nav><a href="#usage">Usage</a><a href="#props">Props and attributes</a><a href="#slots">Slots</a><a href="#events">Events</a><a href="#source">Source contract</a></nav></aside></main>
<footer><div class="footer-brand"><span class="footer-mark" aria-hidden="true">W</span><p><strong>WRNexusJS 0.5.0</strong><span>Complete API documentation generated from installed package declarations.</span></p></div><nav aria-label="Footer"><a href="/packages">All packages</a><a href="/getting-started">Get started</a><a href="/security">Security</a><a href="/support">Support</a><a href="/llms.txt">AI guide</a></nav><p class="footer-meta">Private Developer Preview · Bun-native</p></footer>
<BackToTop />
</div>
}
}