Label
Renders an accessible label associated with controls.
import { css } from 'remix/component'
import { Checkbox } from '#app/ui/checkbox.tsx'
import { Label } from '#app/ui/label.tsx'
export function LabelDemo() {import { css } from 'remix/component'
import { Checkbox } from '#app/ui/checkbox.tsx'
import { Label } from '#app/ui/label.tsx'
export function LabelDemo() {
return () => (
<div>
<div
mix={css({
display: 'flex',
alignItems: 'center',
'& > :not(:last-child)': { marginInlineEnd: '0.5rem' },
})}
>
<Checkbox id="terms" />
<Label htmlFor="terms">Accept terms and conditions</Label>
</div>
</div>
)
}Installation
$ bunx --bun shadcn@latest add https://www.shadcn-remix.com/r/label.json$ npx shadcn@latest add https://www.shadcn-remix.com/r/label.json$ pnpm dlx shadcn@latest add https://www.shadcn-remix.com/r/label.json$ yarn dlx shadcn@latest add https://www.shadcn-remix.com/r/label.jsonInstall the following dependencies:
$ bun add remix$ npm install remix$ pnpm add remix$ yarn add remixCopy and paste the following code into your project.
import { css, on, type Handle, type Props } from 'remix/component'
const labelStyles = css({
display: 'flex',
alignItems: 'center',
gap: '0.5rem',
fontSize: '0.875rem',
lineHeight: 1,
fontWeight: 500,
userSelect: 'none',
'&:is(:where(.group)[data-disabled="true"] *)': { pointerEvents: 'none', opacity: 0.5 },
'&:is(:where(.peer):disabled ~ *)': { cursor: 'not-allowed', opacity: 0.5 },
})
/**
* Radix Label behavior: double-clicking the label text must not select it, unless the click
* lands on a control rendered inside the label.
*/
const preventDoubleClickSelection = on<HTMLLabelElement, 'mousedown'>('mousedown', (event) => {
let target = event.target as Element
if (target.closest('button, input, select, textarea')) return
if (!event.defaultPrevented && event.detail > 1) event.preventDefault()
})
export function Label(handle: Handle<Props<'label'>>) {
return () => {
let { mix, ...props } = handle.props
return (
<label
data-slot="label"
{...props}
mix={[labelStyles, preventDoubleClickSelection, mix]}
/>
)
}
}Update the import paths to match your project setup.
Usage
import { Label } from '#app/ui/label.tsx'<Label htmlFor="email">Your email address</Label>Examples
Label in Field
For form fields, use the Field component which includes built-in FieldLabel, FieldDescription, and FieldError components. <FieldLabel htmlFor="email">Your email address</FieldLabel> <Input id="email" />
import { css } from 'remix/component'
import { Button } from '#app/ui/button.tsx'
import { Checkbox } from '#app/ui/checkbox.tsx'
import {
Field,import { css } from 'remix/component'
import { Button } from '#app/ui/button.tsx'
import { Checkbox } from '#app/ui/checkbox.tsx'
import {
Field,
FieldDescription,
FieldGroup,
FieldLabel,
FieldLegend,
FieldSeparator,
FieldSet,
} from '#app/ui/field.tsx'
import { Input } from '#app/ui/input.tsx'
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from '#app/ui/select.tsx'
import { Textarea } from '#app/ui/textarea.tsx'
const wrapperStyles = css({ width: '100%', maxWidth: '28rem' })
const normalLabel = css({ fontWeight: 400 })
const threeColumns = css({
display: 'grid',
gridTemplateColumns: 'repeat(3, minmax(0, 1fr))',
gap: '1rem',
})
const noResize = css({ resize: 'none' })
export function FieldDemo() {
return () => (
<div mix={wrapperStyles}>
<form>
<FieldGroup>
<FieldSet>
<FieldLegend>Payment Method</FieldLegend>
<FieldDescription>All transactions are secure and encrypted</FieldDescription>
<FieldGroup>
<Field>
<FieldLabel htmlFor="checkout-7j9-card-name-43j">Name on Card</FieldLabel>
<Input id="checkout-7j9-card-name-43j" placeholder="Evil Rabbit" required />
</Field>
<Field>
<FieldLabel htmlFor="checkout-7j9-card-number-uw1">Card Number</FieldLabel>
<Input id="checkout-7j9-card-number-uw1" placeholder="1234 5678 9012 3456" required />
<FieldDescription>Enter your 16-digit card number</FieldDescription>
</Field>
<div mix={threeColumns}>
<Field>
<FieldLabel htmlFor="checkout-exp-month-ts6">Month</FieldLabel>
<Select defaultValue="">
<SelectTrigger id="checkout-exp-month-ts6">
<SelectValue placeholder="MM" />
</SelectTrigger>
<SelectContent>
<SelectItem value="01">01</SelectItem>
<SelectItem value="02">02</SelectItem>
<SelectItem value="03">03</SelectItem>
<SelectItem value="04">04</SelectItem>
<SelectItem value="05">05</SelectItem>
<SelectItem value="06">06</SelectItem>
<SelectItem value="07">07</SelectItem>
<SelectItem value="08">08</SelectItem>
<SelectItem value="09">09</SelectItem>
<SelectItem value="10">10</SelectItem>
<SelectItem value="11">11</SelectItem>
<SelectItem value="12">12</SelectItem>
</SelectContent>
</Select>
</Field>
<Field>
<FieldLabel htmlFor="checkout-7j9-exp-year-f59">Year</FieldLabel>
<Select defaultValue="">
<SelectTrigger id="checkout-7j9-exp-year-f59">
<SelectValue placeholder="YYYY" />
</SelectTrigger>
<SelectContent>
<SelectItem value="2024">2024</SelectItem>
<SelectItem value="2025">2025</SelectItem>
<SelectItem value="2026">2026</SelectItem>
<SelectItem value="2027">2027</SelectItem>
<SelectItem value="2028">2028</SelectItem>
<SelectItem value="2029">2029</SelectItem>
</SelectContent>
</Select>
</Field>
<Field>
<FieldLabel htmlFor="checkout-7j9-cvv">CVV</FieldLabel>
<Input id="checkout-7j9-cvv" placeholder="123" required />
</Field>
</div>
</FieldGroup>
</FieldSet>
<FieldSeparator />
<FieldSet>
<FieldLegend>Billing Address</FieldLegend>
<FieldDescription>The billing address associated with your payment method</FieldDescription>
<FieldGroup>
<Field orientation="horizontal">
<Checkbox id="checkout-7j9-same-as-shipping-wgm" defaultChecked />
<FieldLabel htmlFor="checkout-7j9-same-as-shipping-wgm" mix={normalLabel}>
Same as shipping address
</FieldLabel>
</Field>
</FieldGroup>
</FieldSet>
<FieldSet>
<FieldGroup>
<Field>
<FieldLabel htmlFor="checkout-7j9-optional-comments">Comments</FieldLabel>
<Textarea
id="checkout-7j9-optional-comments"
placeholder="Add any additional comments"
mix={noResize}
/>
</Field>
</FieldGroup>
</FieldSet>
<Field orientation="horizontal">
<Button type="submit">Submit</Button>
<Button variant="outline" type="button">
Cancel
</Button>
</Field>
</FieldGroup>
</form>
</div>
)
}API Reference
Label
| Prop | Type | Default |
|---|---|---|
mix | MixValue | - |