Skip to main content

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 ?? volume.min}
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 passes these props to your render function:

State Properties

  • value (number | null) - Current numeric value, or null when the entity is unavailable
  • min (number) - Minimum allowed value
  • max (number) - Maximum allowed value
  • step (number) - Step increment/decrement size
  • unit (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 (rejects non-finite numbers, clamps to min/max)
  • increment() - Increase value by step amount (does nothing while value is null)
  • decrement() - Decrease value by step amount (does nothing while value is null)

Entity Properties

  • entityId (string) - The entity ID
  • state (string) - Raw state value from Home Assistant
  • attributes (object) - All entity attributes
  • lastChanged (Date) - When the entity last changed
  • lastUpdated (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

The useNumbers hook returns every number entity Home Assistant knows about:

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

Each item in the array is a raw entity object with entity_id, state, and attributes.

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 ?? min}
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 === null || value <= min}>
-
</button>
<span>{value}{unit}</span>
<button onClick={increment} disabled={value === null || 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 ?? min}
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 ?? min}
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 ?? volume.min}
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

  • value is null while the entity is unavailable or its state isn't numeric. increment and decrement do nothing in that case, and controlled inputs need a fallback (the examples above use value ?? min)
  • setValue rejects non-finite numbers (NaN, Infinity) with a thrown error and clamps everything else to the min/max bounds
  • increment and decrement move by step and stop at the bounds
  • Typical number entities: volume, temperature offsets, brightness thresholds