Number Input
A field that allows user input of numeric values.
import { defineConfig } from '@pandacss/dev'
import { createPreset } from '@park-ui/panda-preset'
export default defineConfig({
preflight: true,
presets: [
'@pandacss/preset-base',
createPreset({
accentColor: '__ACCENT_COLOR__',
grayColor: '__GRAY_COLOR__',
borderRadius: '__BORDER_RADIUS__',
}),
],
include: ['./src/**/*.{js,jsx,ts,tsx}'],
jsxFramework: '__JS_FRAMEWORK__',
outdir: 'styled-system',
})
import { parkwindPlugin } from '@park-ui/tailwind-plugin'
import type { Config } from 'tailwindcss'
const config: Config = {
content: ['./src/**/*.{astro,html,js,jsx,svelte,ts,tsx,vue}'],
theme: {
extend: {},
},
plugins: [parkwindPlugin],
parkUI: {
accentColor: '__ACCENT_COLOR__',
grayColor: '__GRAY_COLOR__',
borderRadius: '__BORDER_RADIUS__',
},
darkMode: ['class'],
}
export default config
A field that allows user input of numeric values.
import { NumberInput, type NumberInputProps } from '~/components/ui/number-input'
export const Demo = (props: NumberInputProps) => {
return (
<NumberInput defaultValue="3" {...props}>
Label
</NumberInput>
)
}
Insert code snippet into your project. Update import paths as needed.
import {
NumberInput as ArkNumberInput,
type NumberInputRootProps,
} from '@ark-ui/react/number-input'
import { forwardRef, type ReactNode } from 'react'
import { tv, type VariantProps } from 'tailwind-variants'
export interface NumberInputProps extends NumberInputRootProps, NumberInputVariantProps {
children?: ReactNode
}
export const NumberInput = forwardRef<HTMLDivElement, NumberInputProps>((props, ref) => {
const { children, className, ...rootProps } = props
const { root, control, label, input, incrementTrigger, decrementTrigger } = styles({})
return (
<ArkNumberInput.Root ref={ref} className={root({ className })} {...rootProps}>
{children && <ArkNumberInput.Label className={label()}>{children}</ArkNumberInput.Label>}
<ArkNumberInput.Control className={control()}>
<ArkNumberInput.Input className={input()} />
<ArkNumberInput.IncrementTrigger className={incrementTrigger()}>
<ChevronUpIcon />
</ArkNumberInput.IncrementTrigger>
<ArkNumberInput.DecrementTrigger className={decrementTrigger()}>
<ChevronDownIcon />
</ArkNumberInput.DecrementTrigger>
</ArkNumberInput.Control>
</ArkNumberInput.Root>
)
})
NumberInput.displayName = 'NumberInput'
type NumberInputVariantProps = VariantProps<typeof styles>
const styles = tv(
{
base: 'numberInput',
defaultVariants: { size: 'md' },
slots: {
root: 'numberInput__root',
label: 'numberInput__label',
input: 'numberInput__input',
control: 'numberInput__control',
incrementTrigger: 'numberInput__incrementTrigger',
decrementTrigger: 'numberInput__decrementTrigger',
scrubber: 'numberInput__scrubber',
},
variants: {
size: {
md: {
root: 'numberInput__root--size_md',
label: 'numberInput__label--size_md',
input: 'numberInput__input--size_md',
control: 'numberInput__control--size_md',
incrementTrigger: 'numberInput__incrementTrigger--size_md',
decrementTrigger: 'numberInput__decrementTrigger--size_md',
scrubber: 'numberInput__scrubber--size_md',
},
lg: {
root: 'numberInput__root--size_lg',
label: 'numberInput__label--size_lg',
input: 'numberInput__input--size_lg',
control: 'numberInput__control--size_lg',
incrementTrigger: 'numberInput__incrementTrigger--size_lg',
decrementTrigger: 'numberInput__decrementTrigger--size_lg',
scrubber: 'numberInput__scrubber--size_lg',
},
xl: {
root: 'numberInput__root--size_xl',
label: 'numberInput__label--size_xl',
input: 'numberInput__input--size_xl',
control: 'numberInput__control--size_xl',
incrementTrigger: 'numberInput__incrementTrigger--size_xl',
decrementTrigger: 'numberInput__decrementTrigger--size_xl',
scrubber: 'numberInput__scrubber--size_xl',
},
},
},
},
{ twMerge: false },
)
const ChevronUpIcon = () => (
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<title>Chevron Up</title>
<path
fill="none"
stroke="currentColor"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
d="m18 15l-6-6l-6 6"
/>
</svg>
)
const ChevronDownIcon = () => (
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<title>Chevron Down</title>
<path
fill="none"
stroke="currentColor"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
d="m6 9l6 6l6-6"
/>
</svg>
)
import { NumberInput as ArkNumberInput, type NumberInputRootProps } from '@ark-ui/solid'
import { type JSX, Show, children, splitProps } from 'solid-js'
import { type VariantProps, tv } from 'tailwind-variants'
export interface NumberInputProps
extends Omit<NumberInputRootProps, 'children'>,
NumberInputVariantProps {
children?: JSX.Element
}
export const NumberInput = (props: NumberInputProps) => {
const [variantProps, numberInputProps] = splitProps(props, ['size', 'class'])
const { root, control, label, input, incrementTrigger, decrementTrigger } = styles(variantProps)
const getChildren = children(() => numberInputProps.children)
return (
<ArkNumberInput.Root class={root()} {...numberInputProps}>
<Show when={getChildren()}>
<ArkNumberInput.Label class={label()}>{getChildren()}</ArkNumberInput.Label>
</Show>
<ArkNumberInput.Control class={control()}>
<ArkNumberInput.Input class={input()} />
<ArkNumberInput.IncrementTrigger class={incrementTrigger()}>
<ChevronUpIcon />
</ArkNumberInput.IncrementTrigger>
<ArkNumberInput.DecrementTrigger class={decrementTrigger()}>
<ChevronDownIcon />
</ArkNumberInput.DecrementTrigger>
</ArkNumberInput.Control>
</ArkNumberInput.Root>
)
}
type NumberInputVariantProps = VariantProps<typeof styles>
const styles = tv(
{
base: 'numberInput',
defaultVariants: { size: 'md' },
slots: {
root: 'numberInput__root',
label: 'numberInput__label',
input: 'numberInput__input',
control: 'numberInput__control',
incrementTrigger: 'numberInput__incrementTrigger',
decrementTrigger: 'numberInput__decrementTrigger',
scrubber: 'numberInput__scrubber',
},
variants: {
size: {
md: {
root: 'numberInput__root--size_md',
label: 'numberInput__label--size_md',
input: 'numberInput__input--size_md',
control: 'numberInput__control--size_md',
incrementTrigger: 'numberInput__incrementTrigger--size_md',
decrementTrigger: 'numberInput__decrementTrigger--size_md',
scrubber: 'numberInput__scrubber--size_md',
},
lg: {
root: 'numberInput__root--size_lg',
label: 'numberInput__label--size_lg',
input: 'numberInput__input--size_lg',
control: 'numberInput__control--size_lg',
incrementTrigger: 'numberInput__incrementTrigger--size_lg',
decrementTrigger: 'numberInput__decrementTrigger--size_lg',
scrubber: 'numberInput__scrubber--size_lg',
},
xl: {
root: 'numberInput__root--size_xl',
label: 'numberInput__label--size_xl',
input: 'numberInput__input--size_xl',
control: 'numberInput__control--size_xl',
incrementTrigger: 'numberInput__incrementTrigger--size_xl',
decrementTrigger: 'numberInput__decrementTrigger--size_xl',
scrubber: 'numberInput__scrubber--size_xl',
},
},
},
},
{ twMerge: false },
)
const ChevronUpIcon = () => (
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<title>Chevron Up</title>
<path
fill="none"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="m18 15l-6-6l-6 6"
/>
</svg>
)
const ChevronDownIcon = () => (
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<title>Chevron Down</title>
<path
fill="none"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="m6 9l6 6l6-6"
/>
</svg>
)
Not yet available
Previous
MenuNext
Pagination