mirror of
https://github.com/tabler/tabler.git
synced 2026-10-12 21:27:06 +04:00
81 lines
2.8 KiB
Plaintext
81 lines
2.8 KiB
Plaintext
---
|
|
// Form group: label (.form-label) + control slot + optional hint (.form-hint).
|
|
// When `for` is omitted and associate is true (default), the control is nested
|
|
// inside the label for implicit association. Set associate={false} for groups
|
|
// with multiple controls.
|
|
import FormHint from './FormHint.astro'
|
|
|
|
interface Props {
|
|
label?: string
|
|
/** .required asterisk on the label — also set required on the control */
|
|
required?: boolean
|
|
/** .form-label-description at the inline end of the label */
|
|
description?: string
|
|
/** .form-hint under the control */
|
|
hint?: string
|
|
/** for attribute of the label — must match the slotted control's id */
|
|
for?: string
|
|
/** extra classes on the label (e.g. visually-hidden) */
|
|
labelClass?: string
|
|
/** wrapper classes; replaces the default mb-3 */
|
|
class?: string
|
|
/** marks the group invalid — pair with aria-invalid and .is-invalid on the control */
|
|
invalid?: boolean
|
|
/** error message shown under the control (.invalid-feedback) */
|
|
error?: string
|
|
/** nest the control in the label when `for` is omitted (default true) */
|
|
associate?: boolean
|
|
}
|
|
|
|
const { label, required, description, hint, for: htmlFor, labelClass, class: className = 'mb-3', invalid, error, associate = true } = Astro.props
|
|
|
|
// Hint/error ids exist only when the caller provides `for` — an auto-derived
|
|
// id is unreferenceable by the slotted control anyway, and label-based slugs
|
|
// collide between same-label groups on one page.
|
|
const hintId = hint && htmlFor ? `${htmlFor}-hint` : undefined
|
|
const errorId = error && htmlFor ? `${htmlFor}-error` : undefined
|
|
const wrapLabel = Boolean(label && !htmlFor && associate)
|
|
---
|
|
|
|
<div class:list={[className, invalid && 'has-validation']}>
|
|
{
|
|
label && htmlFor && (
|
|
<label class:list={['form-label', required && 'required', labelClass]} for={htmlFor}>
|
|
{label}
|
|
{required && <span class="visually-hidden"> (required)</span>}
|
|
{description && <span class="form-label-description">{description}</span>}
|
|
</label>
|
|
)
|
|
}
|
|
{
|
|
label && !htmlFor && !associate && (
|
|
<div class:list={['form-label', required && 'required', labelClass]}>
|
|
{label}
|
|
{description && <span class="form-label-description">{description}</span>}
|
|
</div>
|
|
)
|
|
}
|
|
{
|
|
wrapLabel ? (
|
|
<label class="d-block">
|
|
<span class:list={['form-label', required && 'required', labelClass]}>
|
|
{label}
|
|
{required && <span class="visually-hidden"> (required)</span>}
|
|
{description && <span class="form-label-description">{description}</span>}
|
|
</span>
|
|
<slot />
|
|
</label>
|
|
) : (
|
|
<slot />
|
|
)
|
|
}
|
|
{
|
|
error && (
|
|
<div class="invalid-feedback d-block" id={errorId} role="alert">
|
|
{error}
|
|
</div>
|
|
)
|
|
}
|
|
{hint && <FormHint id={hintId}>{hint}</FormHint>}
|
|
</div>
|