Number
Numeric input controls with configurable min/max/step values.
Quick Example
// Component approach
<Number entityId="number.speaker_volume">
{({ value, setValue, increment, decrement }) => (
<div>
<button onClick={decrement}>-</button>
<span>{value}%</span>
<button onClick={increment}>+</button>
</div>
)}
</Number>
// Hook approach
const volume = useNumber('number.speaker_volume')
<input
type="range"
min={volume.min}
max={volume.max}
step={volume.step}
value={volume.value}
onChange={(e) => volume.setValue(parseFloat(e.target.value))}
/>
Component API
Basic Usage
import { Number } from 'hass-react'
<Number entityId="number.speaker_volume">
{(numberProps) => (
// Your UI here
)}
</Number>
Render Props
The Number component provides these props to your render function:
State Properties
value(number) - Current numeric valuemin(number) - Minimum allowed valuemax(number) - Maximum allowed valuestep(number) - Step increment/decrement sizeunit(string | undefined) - Unit of measurement (e.g., "%", "°F")deviceClass(string | undefined) - Device class (e.g., "temperature", "humidity")mode('auto' | 'box' | 'slider') - UI mode hint from Home Assistant (defaults to'auto')
Control Methods
setValue(value: number)- Set the value (validates min/max/step)increment()- Increase value by step amountdecrement()- Decrease value by step amount
Entity Properties
entityId(string) - The entity IDstate(string) - Raw state value from Home Assistantattributes(object) - All entity attributeslastChanged(Date) - When the entity last changedlastUpdated(Date) - When the entity was last updated
Hook API
Basic Usage
import { useNumber } from 'hass-react'
function MyComponent() {
const numberEntity = useNumber('number.speaker_volume')
// All the same properties as component render props
return <div>{numberEntity.value}{numberEntity.unit}</div>
}
The useNumber hook returns an object with all the same properties and methods as the component's render props.
List All Numbers
Use the useNumbers hook to retrieve all available number entities:
import { useNumbers } from 'hass-react'
function NumberList() {
const numbers = useNumbers()
return (
<div>
<h2>Available Numbers ({numbers.length})</h2>
{numbers.map(number => (
<div key={number.entity_id}>
{number.attributes.friendly_name || number.entity_id}
</div>
))}
</div>
)
}
The useNumbers hook fetches all number entities from Home Assistant and returns an array of number objects.
Examples
Simple Slider
<Number entityId="number.speaker_volume">
{({ value, setValue, min, max, step, unit }) => (
<div>
<label>Volume: {value}{unit}</label>
<input
type="range"
min={min}
max={max}
step={step}
value={value}
onChange={(e) => setValue(parseFloat(e.target.value))}
/>
</div>
)}
</Number>
Number Card with Buttons
<Number entityId="number.thermostat_offset">
{({ value, increment, decrement, min, max, unit, attributes }) => (
<div>
<h3>{attributes.friendly_name}</h3>
<div>
<button onClick={decrement} disabled={value <= min}>
-
</button>
<span>{value}{unit}</span>
<button onClick={increment} disabled={value >= max}>
+
</button>
</div>
<p>Range: {min} - {max}{unit}</p>
</div>
)}
</Number>
Combined Slider and Buttons
<Number entityId="number.brightness_threshold">
{({ value, setValue, increment, decrement, min, max, step, unit }) => (
<div>
<h4>Brightness Threshold</h4>
<input
type="range"
min={min}
max={max}
step={step}
value={value}
onChange={(e) => setValue(parseFloat(e.target.value))}
/>
<div>
<span>{min}{unit}</span>
<div>
<button onClick={decrement}>-</button>
<span>{value}{unit}</span>
<button onClick={increment}>+</button>
</div>
<span>{max}{unit}</span>
</div>
</div>
)}
</Number>
Number Input Field
<Number entityId="number.countdown_timer">
{({ value, setValue, min, max, step, attributes }) => (
<div>
<label htmlFor="timer">{attributes.friendly_name}</label>
<input
id="timer"
type="number"
min={min}
max={max}
step={step}
value={value}
onChange={(e) => setValue(parseFloat(e.target.value))}
/>
</div>
)}
</Number>
Using Hooks
import { useNumber } from 'hass-react'
function VolumeControl({ entityId }) {
const volume = useNumber(entityId)
return (
<div>
<h3>{volume.attributes.friendly_name}</h3>
<input
type="range"
min={volume.min}
max={volume.max}
step={volume.step}
value={volume.value}
onChange={(e) => volume.setValue(parseFloat(e.target.value))}
/>
<p>{volume.value}{volume.unit}</p>
<div>
<button onClick={() => volume.setValue(volume.min)}>Min</button>
<button onClick={volume.decrement}>-</button>
<button onClick={volume.increment}>+</button>
<button onClick={() => volume.setValue(volume.max)}>Max</button>
</div>
</div>
)
}
Validation Display
<Number entityId="number.pool_temperature">
{({ value, setValue, min, max, step, unit }) => {
const [inputValue, setInputValue] = React.useState(value.toString())
const [error, setError] = React.useState('')
const handleChange = (e) => {
const newValue = e.target.value
setInputValue(newValue)
const num = parseFloat(newValue)
if (isNaN(num)) {
setError('Please enter a valid number')
} else if (num < min) {
setError(`Value must be at least ${min}${unit}`)
} else if (num > max) {
setError(`Value must be at most ${max}${unit}`)
} else if (Math.abs((num - min) % step) > 1e-8) {
setError(`Value must be in increments of ${step}${unit}`)
} else {
setError('')
setValue(num)
}
}
return (
<div>
<label>Pool Temperature</label>
<input
type="number"
value={inputValue}
onChange={handleChange}
min={min}
max={max}
step={step}
/>
{error && <p>{error}</p>}
</div>
)
}}
</Number>
Notes
- The
setValuemethod automatically validates that the value is a valid number using Zod validation and clamps it to min/max bounds - Invalid values (NaN, Infinity, etc.) will throw an error with a descriptive message
- The
incrementanddecrementmethods respect thestepproperty and won't exceed min/max bounds - Number entities are commonly used for volume controls, temperature settings, brightness thresholds, and other numeric configurations