KitlenoKitlenov2.0.0

Forms & Input / Checkbox & Radio

Checkbox & Radio

Custom-styled checkbox and radio inputs for multi-select and single-select options in forms, replacing default browser styling with a consistent look.

Checkbox & Radio

Custom-styled checkbox and radio inputs with a checked-state icon, built without relying on default browser styling.

CheckboxRadio.jsx
'use client'
import { useState } from 'react'
import { Check } from 'lucide-react'

export default function CheckboxRadio() {
  const [checked, setChecked] = useState({ a: true, b: false })
  const [selected, setSelected] = useState('monthly')

  return (
    <div className="p-4 flex flex-col gap-6">
      {/* Checkboxes */}
      <div className="flex flex-col gap-3">
        {[
          { key: 'a', label: 'Email notifications' },
          { key: 'b', label: 'Marketing updates' }
        ].map((item) => (
          <label key={item.key} className="flex items-center gap-3 cursor-pointer select-none">
            <div
              onClick={() => setChecked((c) => ({ ...c, [item.key]: !c[item.key] }))}
              className={`flex h-5 w-5 items-center justify-center rounded-[6px] border-2 transition-colors duration-200
                ${checked[item.key]
                  ? 'bg-[#1d1d1f] border-[#1d1d1f] dark:bg-white dark:border-white'
                  : 'bg-transparent border-[#d0d0d0] dark:border-[#4c4c4c]'}`}
            >
              {checked[item.key] && <Check size={13} strokeWidth={3} className="text-white dark:text-[#1d1d1f]" />}
            </div>
            <span className="text-[14px] text-[#1d1d1f] dark:text-[#f5f5f7]">{item.label}</span>
          </label>
        ))}
      </div>

      {/* Radio buttons */}
      <div className="flex flex-col gap-3">
        {[
          { key: 'monthly', label: 'Billed monthly' },
          { key: 'yearly', label: 'Billed yearly' }
        ].map((item) => (
          <label key={item.key} className="flex items-center gap-3 cursor-pointer select-none">
            <div
              onClick={() => setSelected(item.key)}
              className={`flex h-5 w-5 items-center justify-center rounded-full border-2 transition-colors duration-200
                ${selected === item.key ? 'border-[#1d1d1f] dark:border-white' : 'border-[#d0d0d0] dark:border-[#4c4c4c]'}`}
            >
              {selected === item.key && <div className="h-[9px] w-[9px] rounded-full bg-[#1d1d1f] dark:bg-white" />}
            </div>
            <span className="text-[14px] text-[#1d1d1f] dark:text-[#f5f5f7]">{item.label}</span>
          </label>
        ))}
      </div>
    </div>
  )
}