Files
kycnotme/web/src/components/InputCheckboxGroup.astro
2025-05-25 12:28:30 +00:00

67 lines
2.2 KiB
Plaintext

---
import { Icon } from 'astro-icon/components'
import { cn } from '../lib/cn'
import { baseInputClassNames } from '../lib/formInputs'
import InputWrapper from './InputWrapper.astro'
import type { ComponentProps } from 'astro/types'
type Props = Omit<ComponentProps<typeof InputWrapper>, 'children' | 'inputId'> & {
options: {
label: string
value: string
icon?: string[] | string
iconClassName?: string[] | string
}[]
disabled?: boolean
selectedValues?: string[]
size?: 'lg' | 'md'
}
const { options, disabled, selectedValues = [], size = 'md', ...wrapperProps } = Astro.props
const inputId = Astro.locals.makeId(`input-${wrapperProps.name}`)
const hasError = !!wrapperProps.error && wrapperProps.error.length > 0
---
<InputWrapper inputId={inputId} {...wrapperProps}>
<div class={cn(baseInputClassNames.div, hasError && baseInputClassNames.error)}>
<div
class={cn('h-48 overflow-y-auto mask-y-from-[calc(100%-var(--spacing)*8)] py-5', {
'h-96': size === 'lg',
'h-48': size === 'md',
})}
>
{
options.map((option) => {
const icons = option.icon ? (Array.isArray(option.icon) ? option.icon : [option.icon]) : []
const iconClassName = option.iconClassName
? Array.isArray(option.iconClassName)
? option.iconClassName
: Array.from({ length: icons.length }, () => option.iconClassName)
: []
return (
<label class="hover:bg-night-500 flex cursor-pointer items-center gap-2 px-5 py-1">
<input
transition:persist
type="checkbox"
name={wrapperProps.name}
value={option.value}
checked={selectedValues.includes(option.value)}
class={cn(hasError && baseInputClassNames.error, disabled && baseInputClassNames.disabled)}
disabled={disabled}
/>
{icons.map((icon, index) => (
<Icon name={icon} class={cn('size-4 shrink-0', iconClassName[index])} />
))}
<span class="truncate text-sm leading-none">{option.label}</span>
</label>
)
})
}
</div>
</div>
</InputWrapper>