Input
Usage
Clicking the button will change the status to indeterminate.
"use client";
import React from "react";
import { Input } from "@/ui/input";
import { Button } from "@/ui/button";
import { Stack } from "@/ui/stack";
import { Group } from "@/ui/group";
import { useListState } from "@/hooks/use-list-state";
import { sanitizedWord } from "@/utility/text-parser";
const initialValues = [
{ label: "Receive email notifications", checked: false },
{ label: "Receive sms notifications", checked: false },
{ label: "Receive push notifications", checked: false },
];
export function InputCheckboxDemo() {
const [isIndeterminate, setIsIndeterminate] = React.useState(false);
const [checked, setChecked] = React.useState(false);
const [values, handlers] = useListState(initialValues);
const allChecked = values.every((value) => value.checked);
const indeterminate = values.some((value) => value.checked) && !allChecked;
const items = values.map((value, index) => (
<Group key={index} className="w-max">
<Input
type="checkbox"
id={sanitizedWord(value.label)}
className="ml-8"
checked={value.checked}
onChange={(event) => handlers.setItemProp(index, "checked", event.currentTarget.checked)}
/>
<label htmlFor={sanitizedWord(value.label)} className="text-sm text-muted-foreground">{value.label}</label>
</Group>
));
return (
<Stack className="m-auto">
<Stack className="m-auto mb-8">
<Group className="w-max">
<Input
type="checkbox"
checked={allChecked}
indeterminate={indeterminate}
id="all-notifications"
onChange={() =>
handlers.setState((current) =>
current.map((value) => ({ ...value, checked: !allChecked }))
)
}
/>
<label htmlFor="all-notifications" className="text-sm text-muted-foreground">Receive all notifications</label>
</Group>
{items}
</Stack>
<Stack className="m-auto border-t pt-8">
<Input
type="checkbox"
indeterminate={isIndeterminate}
checked={checked}
onChange={(e) => {
setChecked(e.target.checked);
// setIsIndeterminate(false); // Remove indeterminate status if clicked
}}
/>
<Button onClick={() => setIsIndeterminate( i => !i )} className="w-max">
Indeterminate
</Button>
<p className="text-sm text-muted-foreground">Clicking the button will change the status to indeterminate.</p>
</Stack>
</Stack>
);
}
Properties
"use client";
import React from "react";
import { Input } from "@/ui/input";
export function InputDemo() {
const [value, setValue] = React.useState<string>("");
const [checked, setChecked] = React.useState<boolean>(false);
return (
<Input
type="text"
value={value}
checked={checked}
onChange={e => setValue(e.target.value)}
onClick={() => setChecked(c => !c)}
/>
);
}
indeterminate
- The indeterminate function is usually used on checkbox elements to indicate a state that is not fully selected.
- When the
indeterminate
property istrue
, thecheckbox
will be in a neutral state. - This property is only relevant for inputs with
type="checkbox"
Handle style changes and onChange based on input type
API References
Styles API
type Size = (number | (string & {})) | { h?: React.CSSProperties["height"]; w?: React.CSSProperties["width"] };
Styles API | Type | Default | Annotation |
---|---|---|---|
unstyled? | boolean | false | if true , all default styles will be removed |
variant? | React.HTMLInputTypeAttribute | text | same with input type |
size? | Size | {h: 36, w: "100%"} | numbers are converted to rem |
Props API
Props API | Type | Default | Annotation |
---|---|---|---|
type? | HTMLInputTypeAttribute | text | Handle style changes and onChange based on input type |
indeterminate? | boolean | undefined | Allows the checkbox to have a neutral state (neither checked nor unchecked). Useful if you want to use it on a checkbox type. |
Source Codes
input.tsx
globals.css
/* input */
@layer base {
.stylelayer-inputs {
@apply [-moz-appearance:none] [-webkit-appearance:none] appearance-none;
&:is(input) {
&:where([type="checkbox"]) {
@apply [--check-sz:calc((var(--input-sz)*12)/100)] [--timing-function:cubic-bezier(0.25,0,0.35,1)];
&::before,
&::after {
@apply content-[''] absolute bg-background block w-[--check-w] h-[--check-sz] rounded-full top-1/2 left-[19%] [transform-origin:left_center] [transform:--check-transform] [transition:transform_150ms_var(--timing-function)_var(--check-delay,0ms)];
}
&::before {
@apply [--check-w:calc(var(--check-sz)*3)] [--check-transform:rotate(45deg)_translate(calc(var(--check-sz)*-0.55),calc(var(--check-sz)*-0.45))_scaleX(var(--scale-x))] [--scale-x:0] [--check-delay:150ms];
}
&::after {
@apply [--check-w:calc(var(--check-sz)*5)] [--scale-x:0];
}
&:not([data-state="indeterminate"]) {
&::after {
@apply [--check-transform:rotate(-45deg)_translate(calc(var(--check-sz)*0),calc(var(--check-sz)*2))_scaleX(var(--scale-x))];
}
}
&:checked {
&::before {
@apply [--scale-x:1];
}
&::after {
@apply [--scale-x:1] [--check-delay:150ms];
}
}
&:where([data-state="indeterminate"]) {
&::before {
@apply content-[none] hidden;
}
&::after {
@apply inset-auto [--check-transform:none];
}
}
}
&:where([type="radio"]) {
@apply p-0 [--check-sz:calc(var(--input-sz)*(40/100))] [--timing-function:cubic-bezier(0.25,0,0.35,1)];
&::before {
@apply content-[''] absolute bg-color block size-[--check-sz] rounded-full origin-center [transform:--check-transform] [transition:transform_150ms_var(--timing-function)_var(--check-delay,0ms)] [--check-transform:scale(var(--scale))] [--scale:0];
}
&:checked {
&::before {
@apply [--scale:1];
}
}
}
&:where([type="search"]) {
&::before {
@apply content-[''] absolute bg-color block size-[--check-sz] rounded-full origin-center [transform:--check-transform] [transition:transform_150ms_var(--timing-function)_var(--check-delay,0ms)] [--check-transform:scale(var(--scale))] [--scale:0];
}
&:checked {
&::before {
@apply [--scale:1];
}
}
}
&:where([type="email"]) {
@apply [background:--bg-type-email];
--bg-type-email: 6px center / 20px no-repeat var(--bg-required);
--bg-atmail: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjNzU3NTc1IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIHN0cm9rZS13aWR0aD0iMiI+PHBhdGggZD0ibTE2LDh2NWMwLC44LjMyLDEuNTYuODgsMi4xMnMxLjMzLjg4LDIuMTIuODgsMS41Ni0uMzIsMi4xMi0uODguODgtMS4zMy44OC0yLjEydi0xYzAtMi4yNi0uNzYtNC40NS0yLjE3LTYuMjItMS40LTEuNzctMy4zNi0zLjAxLTUuNTYtMy41Mi0yLjItLjUxLTQuNS0uMjctNi41NS43LTIuMDQuOTYtMy42OSwyLjU5LTQuNjksNC42MS0xLDIuMDItMS4yOCw0LjMzLS44MSw2LjUzLjQ3LDIuMiwxLjY4LDQuMTksMy40Myw1LjYyLDEuNzQsMS40MywzLjkyLDIuMjMsNi4xOCwyLjI3LDIuMjYuMDQsNC40Ni0uNjksNi4yNS0yLjA2bS0yLjA4LTcuOTRjMCwyLjIxLTEuNzksNC00LDRzLTQtMS43OS00LTQsMS43OS00LDQtNCw0LDEuNzksNCw0WiIvPjwvc3ZnPg==");
&::-webkit-input-placeholder {
@apply absolute inline-flex items-center left-8;
}
&::-moz-placeholder {
@apply absolute inline-flex items-center left-8;
}
&:-moz-placeholder {
@apply absolute inline-flex items-center left-8;
}
&:-ms-input-placeholder {
@apply absolute inline-flex items-center left-8;
}
}
&:where([type="date"], [type="datetime-local"], [type="month"], [type="week"]) {
&::-webkit-calendar-picker-indicator {
@apply [--sz-icon:22px] right-2 absolute z-9 size-[--sz-icon] p-0 cursor-pointer [-moz-appearance:none] [-webkit-appearance:none] appearance-none [background:--calendar-check,var(--calendar-error,var(--calendar-add))];
}
--calendar-add: no-repeat center
url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgaGVpZ2h0PSIyNCIgd2lkdGg9IjI0IiBmaWxsPSJub25lIiBzdHJva2U9IiM3NTc1NzUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLXdpZHRoPSIxLjUiPjxwYXRoIGQ9Im02LDRoMTJjMi4yMSwwLDQsMS43OSw0LDR2MTBjMCwyLjIxLTEuNzksNC00LDRINmMtMi4yMSwwLTQtMS43OS00LTR2LTEwYzAtMi4yMSwxLjc5LTQsNC00Wm0yLTJ2My41bTgtMy41djMuNW0tOCw3LjVoOG0tNC00djgiLz48L3N2Zz4=");
&:where(:valid:is(:not([value=""]))) {
--calendar-check: no-repeat center
url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgaGVpZ2h0PSIyNCIgd2lkdGg9IjI0IiBmaWxsPSJub25lIiBzdHJva2U9IiM3NTc1NzUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLXdpZHRoPSIxLjUiPjxwYXRoIGQ9Im02LDRoMTJjMi4yMSwwLDQsMS43OSw0LDR2MTBjMCwyLjIxLTEuNzksNC00LDRINmMtMi4yMSwwLTQtMS43OS00LTR2LTEwYzAtMi4yMSwxLjc5LTQsNC00Wm0yLTJ2My41bTgtMy41djMuNW0xLjMsNC42bC01LjQsNS40Yy0uNTMuNTMtMS40LjUzLTEuOTMsMGwtMy4yOC0zLjI4Ii8+PC9zdmc+");
}
&:where(:is(:invalid)) {
--calendar-error: scroll no-repeat center
url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgaGVpZ2h0PSIyNCIgd2lkdGg9IjI0IiBmaWxsPSJub25lIiBzdHJva2U9IiNjYzAwMDAiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLXdpZHRoPSIxLjUiPjxwYXRoIGQ9Im02LDRoMTJjMi4yMSwwLDQsMS43OSw0LDR2MTBjMCwyLjIxLTEuNzksNC00LDRINmMtMi4yMSwwLTQtMS43OS00LTR2LTEwYzAtMi4yMSwxLjc5LTQsNC00Wm0yLTJ2My41bTgtMy41djMuNW0tNi44MywxMC4zM2w1LjY2LTUuNjZtLTUuNjYsMGw1LjY2LDUuNjYiLz48L3N2Zz4=");
}
}
&:where([type="time"]) {
&::-webkit-calendar-picker-indicator {
@apply [--sz-icon:22px] right-2 absolute z-9 size-[--sz-icon] p-0 cursor-pointer [-moz-appearance:none] [-webkit-appearance:none] appearance-none [background:--clock-check,var(--clock-error,var(--clock-add))];
}
--clock-add: no-repeat center
url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgaGVpZ2h0PSIyNCIgd2lkdGg9IjI0IiBmaWxsPSJub25lIiBzdHJva2U9IiM3NTc1NzUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLXdpZHRoPSIxLjUiPjxwYXRoIGQ9Im0yMSwxM2MwLDQuOTctNC4wMyw5LTksOVMzLDE3Ljk3LDMsMTMsNy4wMyw0LDEyLDRzOSw0LjAzLDksOVptLTEzLDBoOG0tNC00djhtNi4yNS0xNWwzLjc1LDMuMzFNNS43NSwybC0zLjc1LDMuMzEiLz48L3N2Zz4=");
&:where(:valid:is(:not([value=""]))) {
--clock-check: no-repeat center
url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgaGVpZ2h0PSIyNCIgd2lkdGg9IjI0IiBmaWxsPSJub25lIiBzdHJva2U9IiM3NTc1NzUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLXdpZHRoPSIxLjUiPjxwYXRoIGQ9Im0yMC45MiwxMi45OWMwLDQuOTctNC4wMyw5LTksOS00Ljk3LDAtOS00LjAzLTktOSwwLTQuOTcsNC4wMy05LDktOSw0Ljk3LDAsOSw0LjAzLDksOVptLTIuNzUtMTFsMy43NSwzLjMxTTUuNjcsMS45OWwtMy43NSwzLjMxbTEzLjY3LDEwLjU5bC0yLjc5LTEuNjZjLS40OS0uMjktLjg4LS45OC0uODgtMS41NXYtMy42OSIvPjwvc3ZnPg==");
}
&:where(:is(:invalid)) {
--clock-error: scroll no-repeat center
url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgaGVpZ2h0PSIyNCIgd2lkdGg9IjI0IiBmaWxsPSJub25lIiBzdHJva2U9IiNjYzAwMDAiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLXdpZHRoPSIxLjUiPjxwYXRoIGQ9Im0yMSwxM2MwLDQuOTctNC4wMyw5LTksOS00Ljk3LDAtOS00LjAzLTktOSwwLTQuOTcsNC4wMy05LDktOSw0Ljk3LDAsOSw0LjAzLDksOVptLTIuNzUtMTFsMy43NSwzLjMxTTUuNzUsMmwtMy43NSwzLjMxbTcuMTcsMTAuNTJsNS42Ni01LjY2bS01LjY2LDBsNS42Niw1LjY2Ii8+PC9zdmc+");
}
}
&:where([type="number"]) {
@apply [clip-path:circle(32px_at_center)];
&::-webkit-inner-spin-button,
&::-webkit-outer-spin-button {
@apply p-0 m-0 [-moz-appearance:none] [-webkit-appearance:none] appearance-none h-auto;
}
}
&:where([type="search"]) {
@apply [-moz-appearance:none] [-webkit-appearance:none] appearance-none;
&::-webkit-search-decoration {
@apply p-0 m-0 [-moz-appearance:none] [-webkit-appearance:none] appearance-none h-auto;
}
}
&:where([type="color"]) {
@apply [--clip-path:circle(17px_at_center)];
&::-webkit-color-swatch-wrapper {
@apply p-0 m-0 rounded-[--round,999px] scale-125 overflow-hidden border [-moz-appearance:none] [-webkit-appearance:none] appearance-none;
}
&::-webkit-color-swatch {
@apply p-0 m-0 rounded-[--round,999px] scale-125 overflow-hidden border-0 outline-0 border-none outline-none border-transparent outline-offset-0 [-moz-appearance:none] [-webkit-appearance:none] appearance-none;
}
&::-moz-color-swatch {
@apply p-0 m-0 rounded-[--round,999px] scale-125 overflow-hidden border-0 outline-0 border-none outline-none border-transparent outline-offset-0 [-moz-appearance:none] [-webkit-appearance:none] appearance-none;
}
}
&:where([type="file"]) {
@apply text-center [text-align-last:center];
&::before {
@apply content-[attr(placeholder)] top-0 inset-x-0 text-muted-foreground absolute size-full flex items-center justify-center translate-y-[5%];
}
&::-webkit-file-upload-button {
@apply cursor-pointer p-0 m-0 size-[30%] absolute inset-1/2 -translate-x-1/2 -translate-y-full text-transparent rounded-xl [-moz-appearance:none] [-webkit-appearance:none] appearance-none [background:--upload-check,var(--upload-error,var(--upload-add))];
}
&::file-selector-button {
@apply cursor-pointer p-0 m-0 size-[30%] absolute inset-1/2 -translate-x-1/2 -translate-y-full text-transparent rounded-xl [-moz-appearance:none] [-webkit-appearance:none] appearance-none [background:--upload-check,var(--upload-error,var(--upload-add))];
}
&::-ms-browse {
@apply cursor-pointer p-0 m-0 size-[30%] absolute inset-1/2 -translate-x-1/2 -translate-y-full text-transparent rounded-xl [-moz-appearance:none] [-webkit-appearance:none] appearance-none [background:--upload-check,var(--upload-error,var(--upload-add))];
}
--upload-add: scroll no-repeat center
url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjNzU3NTc1IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIHN0cm9rZS13aWR0aD0iMS41Ij48cGF0aCBkPSJtMTIsMTR2N20tNC0zbDQtNCw0LDRtLTEyLTIuNDJjLTIuNy0yLjkyLTIuNjYtNy42MS4xMS0xMC40NywyLjc2LTIuODYsNy4yLTIuODEsOS45LjExLjc5Ljg2LDEuMzgsMS45MSwxLjcsMy4wNmgxLjc5YzIuNDksMCw0LjUsMi4xMyw0LjUsNC43NiwwLDEuNTktLjc1LDMuMDctMiwzLjk2Ii8+PC9zdmc+");
&:where(:valid:is(:not([value=""]))) {
--upload-check: scroll no-repeat center
url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDA3NmY1IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIHN0cm9rZS13aWR0aD0iMS41Ij48cGF0aCBkPSJtNCwxNS41OGMtMi43LTIuOTItMi42Ni03LjYxLjExLTEwLjQ3LDIuNzYtMi44Niw3LjItMi44MSw5LjkuMTEuNzkuODYsMS4zOCwxLjkxLDEuNywzLjA2aDEuNzljMi40OSwwLDQuNSwyLjEzLDQuNSw0Ljc2LDAsMS41OS0uNzUsMy4wNy0yLDMuOTZtLTIuNjktMS44bC01LjQsNS40Yy0uNTMuNTMtMS40LjUzLTEuOTMsMGwtMy4yOC0zLjI4Ii8+PC9zdmc+");
}
&:where(:is(:invalid)) {
--upload-error: scroll no-repeat center
url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjY2MwMDAwIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIHN0cm9rZS13aWR0aD0iMS41Ij48cGF0aCBkPSJtNCwxNS41OGMtMi43LTIuOTItMi42Ni03LjYxLjExLTEwLjQ3LDIuNzYtMi44Niw3LjItMi44MSw5LjkuMTEuNzkuODYsMS4zOCwxLjkxLDEuNywzLjA2aDEuNzljMi40OSwwLDQuNSwyLjEzLDQuNSw0Ljc2LDAsMS41OS0uNzUsMy4wNy0yLDMuOTZtLTEwLjgzLDRsNS42Ni01LjY2bS01LjY2LDBsNS42Niw1LjY2Ii8+PC9zdmc+");
}
}
&:where([type="range"]) {
@apply [--is-thumb-fill:radial-gradient(circle,var(--thumb-inner-color),var(--thumb-border),var(--thumb-outer-color)_var(--thumb-border))];
&:not(.slider-range) {
@apply [--track-color:hsl(var(--muted))] [--clip-edges:5.5px] [--clip-top:3.5px] [--clip-bottom:12.5px] [--clip-further:calc(100%+6px)] [--is-track-clip:polygon(100%_0px,var(--clip-edges)_0px,0px_var(--clip-top),-100vmax_var(--clip-top),-100vmax_var(--clip-bottom),0px_var(--clip-bottom),var(--clip-edges)_100%,var(--clip-further)_var(--clip-further))] [--is-track-fill:calc(-100vmax-var(--thumb-sz))_0_0_calc(100vmax+(var(--thumb-sz)/3.5))_var(--track-color-active)];
}
&::-webkit-slider-thumb {
@apply size-[--thumb-sz] rounded-full relative cursor-pointer appearance-none transition-all [background:--is-thumb-fill] [box-shadow:--is-track-fill] [clip-path:--is-track-clip];
}
&::-moz-range-thumb {
@apply size-[--thumb-sz] rounded-full relative cursor-pointer appearance-none transition-all [background:--is-thumb-fill];
}
&::-webkit-slider-runnable-track {
@apply size-full rounded-full appearance-none transition-all [background:linear-gradient(var(--track-color)_0_0)_scroll_no-repeat_center/100%_var(--track-height)];
}
&::-moz-range-track {
@apply h-[var(--track-height)] rounded-full bg-[--track-color] w-full appearance-none transition-all;
}
&::-moz-range-progress {
@apply h-[var(--track-height)] rounded-full bg-[--track-color-active] delay-75 appearance-none;
}
}
}
}
}