a tool for shared writing and social publishing
at main 3.5 kB view raw
1import { CheckboxChecked } from "./Icons/CheckboxChecked"; 2import { CheckboxEmpty } from "./Icons/CheckboxEmpty"; 3import { Props } from "./Icons/Props"; 4import React, { forwardRef, type JSX } from "react"; 5 6export function Checkbox(props: { 7 checked: boolean; 8 onChange: (e: React.ChangeEvent<HTMLInputElement>) => void; 9 children: React.ReactNode; 10 className?: string; 11 small?: boolean; 12}) { 13 return ( 14 <label 15 className={`flex w-full gap-2 items-start cursor-pointer ${props.className} ${props.checked ? "text-primary font-bold " : " text-tertiary font-normal"} ${props.small && "text-sm"}`} 16 > 17 <input 18 type="checkbox" 19 checked={props.checked} 20 className="hidden" 21 onChange={(e) => props.onChange(e)} 22 /> 23 {!props.checked ? ( 24 <CheckboxEmpty 25 className={`shrink-0 text-tertiary ${props.small ? "mt-1" : "mt-[6px]"}`} 26 /> 27 ) : ( 28 <CheckboxChecked 29 className={`shrink-0 text-accent-contrast ${props.small ? "mt-1" : "mt-[6px]"}`} 30 /> 31 )} 32 {props.children} 33 </label> 34 ); 35} 36 37type RadioProps = Omit<JSX.IntrinsicElements["input"], "content">; 38 39export function Radio( 40 props: { 41 onChange: (e: React.ChangeEvent<HTMLInputElement>) => void; 42 children: React.ReactNode; 43 radioEmptyClassName?: string; 44 radioCheckedClassName?: string; 45 } & JSX.IntrinsicElements["input"], 46) { 47 return ( 48 <label 49 htmlFor={props.id} 50 className={`flex gap-2 items-start cursor-pointer shrink-0 ${props.checked ? "text-primary font-bold " : " text-tertiary font-normal"}`} 51 > 52 <input 53 type="radio" 54 name={props.name} 55 id={props.id} 56 value={props.value} 57 checked={props.checked} 58 className="hidden" 59 onChange={(e) => props.onChange(e)} 60 /> 61 {!props.checked ? ( 62 <RadioEmpty 63 className={`shrink-0 mt-[6px] text-tertiary ${props.radioEmptyClassName}`} 64 /> 65 ) : ( 66 <RadioChecked 67 className={`shrink-0 mt-[6px] text-accent-contrast ${props.radioCheckedClassName}`} 68 /> 69 )} 70 {props.children} 71 </label> 72 ); 73} 74 75const RadioEmpty = (props: Props) => { 76 return ( 77 <svg 78 width="12" 79 height="12" 80 viewBox="0 0 12 12" 81 fill="none" 82 xmlns="http://www.w3.org/2000/svg" 83 {...props} 84 > 85 <path 86 fillRule="evenodd" 87 clipRule="evenodd" 88 d="M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11ZM6 12C9.31371 12 12 9.31371 12 6C12 2.68629 9.31371 0 6 0C2.68629 0 0 2.68629 0 6C0 9.31371 2.68629 12 6 12Z" 89 fill="currentColor" 90 /> 91 </svg> 92 ); 93}; 94 95const RadioChecked = (props: Props) => { 96 return ( 97 <svg 98 width="12" 99 height="12" 100 viewBox="0 0 12 12" 101 fill="none" 102 xmlns="http://www.w3.org/2000/svg" 103 {...props} 104 > 105 <path 106 fillRule="evenodd" 107 clipRule="evenodd" 108 d="M6 10.5C8.48528 10.5 10.5 8.48528 10.5 6C10.5 3.51472 8.48528 1.5 6 1.5C3.51472 1.5 1.5 3.51472 1.5 6C1.5 8.48528 3.51472 10.5 6 10.5ZM6 12C9.31371 12 12 9.31371 12 6C12 2.68629 9.31371 0 6 0C2.68629 0 0 2.68629 0 6C0 9.31371 2.68629 12 6 12Z" 109 fill="currentColor" 110 /> 111 <path 112 d="M9 6C9 7.65685 7.65685 9 6 9C4.34315 9 3 7.65685 3 6C3 4.34315 4.34315 3 6 3C7.65685 3 9 4.34315 9 6Z" 113 fill="currentColor" 114 /> 115 </svg> 116 ); 117};