component InputNumber { outputs { input(payload: { value?: string | number | boolean | null; values?: Array; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | string | number | boolean | null) change(payload: { value?: string | number | boolean | null; values?: Array; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | string | number | boolean | null) increment(payload: { value: number; previousValue?: number; sourceEvent?: Event; [key: string]: string | number | boolean | null | object }) decrement(payload: { value: number; previousValue?: number; sourceEvent?: Event; [key: string]: string | number | boolean | null | object }) } 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." } state currentValue = value state committedValue = value functions { shared function inputId() { if (id !== "") { return id } if (name !== "") { return name } return "input-number" } shared function descriptionId() { return inputId() + "-description" } shared function messageId() { return inputId() + "-message" } shared function componentColor() { if (color === "secondary") { return "var(--wire-color-secondary)" } if (color === "success") { return "var(--wire-color-success)" } if (color === "warning") { return "var(--wire-color-warning)" } if (color === "danger") { return "var(--wire-color-danger)" } if (color === "info") { return "var(--wire-color-info)" } return "var(--wire-color-primary)" } shared function hasMin() { return min !== "" && min !== null && min !== undefined } shared function hasMax() { return max !== "" && max !== null && max !== undefined } shared function isBlank() { return currentValue === "" || currentValue === null || currentValue === undefined } shared function normalizedStep() { return Number(step) > 0 ? Number(step) : 1 } shared function inferredPrecision() { if (precision !== "auto" && precision !== "") { return Math.max(0, Number(precision) || 0) } if (String(normalizedStep()).includes(".")) { return String(normalizedStep()).split(".")[1].length } return 0 } shared function precisionFactor() { return Math.pow(10, inferredPrecision()) } shared function roundValue(nextValue) { return Math.round(Number(nextValue) * precisionFactor()) / precisionFactor() } shared function clampValue(nextValue) { nextValue = Number(nextValue) if (hasMin() && nextValue < Number(min)) { nextValue = Number(min) } if (hasMax() && nextValue > Number(max)) { nextValue = Number(max) } return roundValue(nextValue) } shared function isBelowMin() { return !isBlank() && hasMin() && Number(currentValue) < Number(min) } shared function isAboveMax() { return !isBlank() && hasMax() && Number(currentValue) > Number(max) } shared function isInvalid() { return ( invalid || error !== "" || (required && isBlank()) || isBelowMin() || isAboveMax() ) } shared function validationMessage() { if (error !== "") { return error } if (required && isBlank()) { return requiredMessage } if (isBelowMin()) { return minMessage } if (isAboveMax()) { return maxMessage } return "" } shared function hasMessage() { return ( helpText !== "" || (showValidationMessage && isInvalid() && validationMessage() !== "") ) } shared function describedBy() { if (description !== "" && hasMessage()) { return descriptionId() + " " + messageId() } if (description !== "") { return descriptionId() } if (hasMessage()) { return messageId() } return "" } shared function decrementDisabled() { return ( disabled || readonly || buttonsDisabled || (hasMin() && !isBlank() && Number(currentValue) <= Number(min)) ) } shared function incrementDisabled() { return ( disabled || readonly || buttonsDisabled || (hasMax() && !isBlank() && Number(currentValue) >= Number(max)) ) } client function dispatchInputNumberEvent( sourceEvent, eventName, action, previousValue, root, customEvent ) { root = sourceEvent.currentTarget.closest("[data-wrn-input-number]") if (!root && sourceEvent.target) { root = sourceEvent.target.closest("[data-wrn-input-number]") } if (!root) { return } customEvent = document.createEvent("CustomEvent") customEvent.initCustomEvent(eventName, true, false, { component: "InputNumber", name: name, value: currentValue, previousValue: previousValue, action: action, min: hasMin() ? Number(min) : null, max: hasMax() ? Number(max) : null, step: normalizedStep(), valid: !isInvalid() }) root.dispatchEvent(customEvent) } client function applyControlValue(nextValue, action, sourceEvent, previousValue) { previousValue = currentValue currentValue = clampValue(nextValue) committedValue = currentValue dispatchInputNumberEvent( sourceEvent, "input", action, previousValue ) dispatchInputNumberEvent( sourceEvent, "change", action, previousValue ) dispatchInputNumberEvent( sourceEvent, action, action, previousValue ) } client function incrementValue(sourceEvent, nextValue) { if (incrementDisabled()) { return } if (isBlank()) { nextValue = hasMin() ? Number(min) : normalizedStep() } else { nextValue = Number(currentValue) + normalizedStep() * (sourceEvent.shiftKey ? 10 : 1) } applyControlValue(nextValue, "increment", sourceEvent) } client function decrementValue(sourceEvent, nextValue) { if (decrementDisabled()) { return } if (isBlank()) { nextValue = hasMax() ? Number(max) : -normalizedStep() } else { nextValue = Number(currentValue) - normalizedStep() * (sourceEvent.shiftKey ? 10 : 1) } applyControlValue(nextValue, "decrement", sourceEvent) } client function handleInput(sourceEvent, previousValue, nextValue) { sourceEvent.stopPropagation() previousValue = currentValue nextValue = sourceEvent.target.value if (nextValue === "") { currentValue = "" } else if (!Number.isNaN(Number(nextValue))) { currentValue = roundValue(Number(nextValue)) } dispatchInputNumberEvent( sourceEvent, "input", "input", previousValue ) } client function handleChange(sourceEvent, previousValue) { sourceEvent.stopPropagation() previousValue = committedValue if (!isBlank()) { currentValue = clamp ? clampValue(currentValue) : roundValue(currentValue) } committedValue = currentValue dispatchInputNumberEvent( sourceEvent, "change", "change", previousValue ) } client function handleKeydown(sourceEvent) { if ( !keyboard || disabled || readonly || inputDisabled || !allowInput ) { return } if (sourceEvent.key === "ArrowUp") { sourceEvent.preventDefault() incrementValue(sourceEvent) } else if (sourceEvent.key === "ArrowDown") { sourceEvent.preventDefault() decrementValue(sourceEvent) } else if (sourceEvent.key === "Home" && hasMin()) { sourceEvent.preventDefault() applyControlValue(Number(min), "decrement", sourceEvent) } else if (sourceEvent.key === "End" && hasMax()) { sourceEvent.preventDefault() applyControlValue(Number(max), "increment", sourceEvent) } } client function handleWheel(sourceEvent) { if ( !wheel || disabled || readonly || inputDisabled || !allowInput ) { return } sourceEvent.preventDefault() if (sourceEvent.deltaY < 0) { incrementValue(sourceEvent) } else if (sourceEvent.deltaY > 0) { decrementValue(sourceEvent) } } } view {
{#if label !== "" && variant !== "labeled" && variant !== "seat"} {/if} {#if description !== "" && variant !== "labeled" && variant !== "seat"}

{description}

{/if}
{#if variant === "horizontal" && showButtons} {/if}
{#if variant === "labeled" || variant === "seat"}
{#if label !== ""} {/if} {#if description !== ""} {description} {/if}
{/if}
{#if prefix !== ""} {/if} {#if suffix !== ""} {/if}
{#if variant === "horizontal" && showButtons} {:else} {#if showButtons}
{/if} {/if}
{#if showValidationMessage && isInvalid() && validationMessage() !== ""} {/if} {#if (!showValidationMessage || !isInvalid() || validationMessage() === "") && helpText !== ""}

{helpText}

{/if}
} }