@allxsmith/bestax-bulma 5.27.6 → 5.27.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bestax.css +1 -1
- package/dist/bestax.css.map +1 -1
- package/dist/esm/elements/Notification.js +1 -0
- package/dist/esm/elements/Notification.js.map +1 -1
- package/dist/esm/form/DateInputBase.js +2 -3
- package/dist/esm/form/DateInputBase.js.map +1 -1
- package/dist/esm/form/DateRangeInputBase.js +18 -3
- package/dist/esm/form/DateRangeInputBase.js.map +1 -1
- package/dist/esm/form/DateTimeInputBase.js +2 -3
- package/dist/esm/form/DateTimeInputBase.js.map +1 -1
- package/dist/esm/form/Field.js +39 -7
- package/dist/esm/form/Field.js.map +1 -1
- package/dist/esm/form/FormContext.js +56 -11
- package/dist/esm/form/FormContext.js.map +1 -1
- package/dist/esm/form/InputBase.js +6 -5
- package/dist/esm/form/InputBase.js.map +1 -1
- package/dist/esm/form/SelectBase.js +7 -5
- package/dist/esm/form/SelectBase.js.map +1 -1
- package/dist/esm/form/TextAreaBase.js +6 -5
- package/dist/esm/form/TextAreaBase.js.map +1 -1
- package/dist/esm/form/TimeInputBase.js +2 -3
- package/dist/esm/form/TimeInputBase.js.map +1 -1
- package/dist/esm/form/useAutoLabelId.js +8 -3
- package/dist/esm/form/useAutoLabelId.js.map +1 -1
- package/dist/esm/helpers/Theme.js +87 -17
- package/dist/esm/helpers/Theme.js.map +1 -1
- package/dist/esm/helpers/devWarnings.js +8 -3
- package/dist/esm/helpers/devWarnings.js.map +1 -1
- package/dist/esm/helpers/useFlexboxClasses.js +1 -1
- package/dist/esm/helpers/useOtherClasses.js +1 -1
- package/dist/esm/helpers/useSpacingClasses.js +1 -1
- package/dist/esm/helpers/useTypographyClasses.js +1 -1
- package/dist/esm/helpers/useVisibilityClasses.js +1 -1
- package/dist/extras.css +1 -1
- package/dist/extras.css.map +1 -1
- package/dist/index.cjs +226 -55
- package/dist/index.cjs.map +1 -1
- package/dist/types/elements/Notification.d.ts +5 -0
- package/dist/types/form/DateRangeInputBase.d.ts +5 -0
- package/dist/types/form/Field.d.ts +2 -2
- package/dist/types/form/FormContext.d.ts +50 -10
- package/dist/types/form/useAutoLabelId.d.ts +4 -2
- package/dist/types/helpers/Theme.d.ts +15 -1
- package/dist/types/helpers/devWarnings.d.ts +8 -0
- package/dist/types-cjs/elements/Notification.d.ts +5 -0
- package/dist/types-cjs/form/DateRangeInputBase.d.ts +5 -0
- package/dist/types-cjs/form/Field.d.ts +2 -2
- package/dist/types-cjs/form/FormContext.d.ts +50 -10
- package/dist/types-cjs/form/useAutoLabelId.d.ts +4 -2
- package/dist/types-cjs/helpers/Theme.d.ts +15 -1
- package/dist/types-cjs/helpers/devWarnings.d.ts +8 -0
- package/dist/versions/bestax-no-dark-mode.css +1 -1
- package/dist/versions/bestax-no-dark-mode.css.map +1 -1
- package/dist/versions/bestax-no-helpers-prefixed.css +1 -1
- package/dist/versions/bestax-no-helpers-prefixed.css.map +1 -1
- package/dist/versions/bestax-no-helpers.css +1 -1
- package/dist/versions/bestax-no-helpers.css.map +1 -1
- package/dist/versions/bestax-prefixed.css +1 -1
- package/dist/versions/bestax-prefixed.css.map +1 -1
- package/package.json +18 -18
- package/src/scss/elements/_index.scss +1 -0
- package/src/scss/elements/_notification.scss +69 -0
|
@@ -12,7 +12,7 @@ import { PickerPopover } from './_pickerInternals/PickerPopover.js';
|
|
|
12
12
|
import { useNativeMobilePicker } from './_pickerInternals/useNativeMobilePicker.js';
|
|
13
13
|
import { useSegmentedEntry } from './_pickerInternals/useSegmentedEntry.js';
|
|
14
14
|
import { useControlLoading } from './controlLoading.js';
|
|
15
|
-
import {
|
|
15
|
+
import { useFieldLabelTarget } from './FormContext.js';
|
|
16
16
|
import { Icon } from '../elements/Icon.js';
|
|
17
17
|
import { getActiveElementInTree } from '../helpers/shadowDom.js';
|
|
18
18
|
import { inertProps } from '../helpers/inertProps.js';
|
|
@@ -60,8 +60,7 @@ const DateTimeInputBase = forwardRef((props, ref) => {
|
|
|
60
60
|
// when the caller set none, as InputBase does, and the popover's ids
|
|
61
61
|
// follow it. Inline there is no input to name, so nothing takes the
|
|
62
62
|
// Field's id or builds on it.
|
|
63
|
-
const
|
|
64
|
-
const id = idProp ?? (inline ? undefined : fieldLabelId);
|
|
63
|
+
const id = useFieldLabelTarget(idProp, !inline);
|
|
65
64
|
// The launcher gives way to the loading spinner of a Control this sits in.
|
|
66
65
|
const controlLoading = useControlLoading();
|
|
67
66
|
const triggerIcon = triggerIconProp ?? !controlLoading;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DateTimeInputBase.js","sources":["../../../src/form/DateTimeInputBase.tsx"],"sourcesContent":["import React, {\n forwardRef,\n useCallback,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport { useBulmaClasses, BulmaClassesProps } from '../helpers/useBulmaClasses';\nimport {\n PickerPosition,\n HourFormat,\n DayOfWeek,\n PickerLabels,\n mergeLabels,\n} from './_pickerInternals/pickerTypes';\nimport {\n formatDateTime,\n formatTime,\n hourCycleFromFormat,\n parseDate,\n DateFormatOption,\n DEFAULT_DATETIME_FORMAT,\n} from './_pickerInternals/formatters';\nimport {\n isWithin,\n setTimeOfDay,\n clampDate,\n FIRST_YEAR,\n floorMin,\n isSameDay,\n makeDate,\n} from './_pickerInternals/dateUtils';\nimport { Calendar, CALENDAR_FOCUSED_CELL } from './_pickerInternals/Calendar';\nimport { TimeWheels } from './_pickerInternals/TimeWheels';\nimport { PickerPopover } from './_pickerInternals/PickerPopover';\nimport { useNativeMobilePicker } from './_pickerInternals/useNativeMobilePicker';\nimport { useSegmentedEntry } from './_pickerInternals/useSegmentedEntry';\nimport { useControlLoading } from './controlLoading';\nimport { useFieldLabelId } from './FormContext';\nimport { Icon } from '../elements/Icon';\nimport { getActiveElementInTree } from '../helpers/shadowDom';\nimport { inertProps } from '../helpers/inertProps';\n\n// The year is padded to four digits, as `datetime-local` requires. HTML has\n// no such shape for a year before 1, so a date then is empty, as that input\n// would make it.\nconst toIsoDateTime = (d: Date, withSeconds: boolean): string => {\n if (d.getFullYear() < FIRST_YEAR) return '';\n const yyyy = String(d.getFullYear()).padStart(4, '0');\n const mo = String(d.getMonth() + 1).padStart(2, '0');\n const dd = String(d.getDate()).padStart(2, '0');\n const hh = String(d.getHours()).padStart(2, '0');\n const mm = String(d.getMinutes()).padStart(2, '0');\n const ss = String(d.getSeconds()).padStart(2, '0');\n return withSeconds\n ? `${yyyy}-${mo}-${dd}T${hh}:${mm}:${ss}`\n : `${yyyy}-${mo}-${dd}T${hh}:${mm}`;\n};\n\nconst fromIsoDateTime = (s: string): Date | null => {\n // The HTML datetime-local value may carry fractional seconds (the spec\n // allows them and some engines normalize to `:ss.sss`); accept and drop.\n // Its year is four or more digits, as `toIsoDateTime` writes one past 9999.\n const m =\n /^(\\d{4,})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2})(?::(\\d{2})(?:\\.\\d{1,3})?)?$/.exec(\n s\n );\n if (!m) return null;\n const d = makeDate(Number(m[1]), Number(m[2]) - 1, Number(m[3]));\n d.setHours(Number(m[4]), Number(m[5]), m[6] ? Number(m[6]) : 0, 0);\n return d;\n};\n\n/**\n * Props for the raw DateTimeInput base. Use the higher-level `DateTimeInput`\n * for Field/Control composition. Combines the prop set of `DateInputBaseProps`\n * and `TimeInputBaseProps`.\n */\nexport interface DateTimeInputBaseProps\n extends\n Omit<\n React.InputHTMLAttributes<HTMLInputElement>,\n | 'value'\n | 'defaultValue'\n | 'onChange'\n | 'size'\n | 'color'\n | 'min'\n | 'max'\n | 'type'\n | 'popover'\n >,\n Omit<BulmaClassesProps, 'color'> {\n /** Controlled selected date-time. */\n value?: Date | null;\n /** Initial value for uncontrolled usage. */\n defaultValue?: Date | null;\n /**\n * Fired when either the date or time portion changes. Picking a day keeps\n * the value's whole time of day, down to seconds and milliseconds the field\n * doesn't show, and `min` and `max` judge the picked day at that time. An\n * empty field's day is picked at midnight.\n */\n onChange?: (d: Date | null) => void;\n /** Fired when the popover opens. */\n onOpen?: () => void;\n /** Fired when the popover closes. */\n onClose?: () => void;\n /**\n * Lower bound for the combined date-time. A `min` before year 1 is raised\n * to midnight on 1 January of year 1, where the range starts without one\n * too: HTML's datetime-local input holds no earlier year, so the calendar,\n * the time wheels and typing stop there.\n */\n min?: Date;\n /** Upper bound for the combined date-time. */\n max?: Date;\n /** Disable the input. */\n disabled?: boolean;\n /** Read-only input. */\n readOnly?: boolean;\n /** Placeholder text. */\n placeholder?: string;\n /**\n * Token format string or `Intl.DateTimeFormat` options. Default `'YYYY-MM-DD HH:mm'`.\n * @defaultValue 'YYYY-MM-DD HH:mm'\n */\n format?: DateFormatOption;\n /**\n * Custom parser. Enter and leaving the field call it only if the user\n * changed the text, so focus passing through commits nothing and the value\n * keeps what the format leaves out, such as seconds.\n */\n parse?: (s: string) => Date | null;\n /** BCP-47 locale tag. */\n locale?: string;\n /** Render the panel inline (no popover). */\n inline?: boolean;\n /** Use `<input type=\"datetime-local\">` on coarse-pointer devices. */\n mobileNative?: boolean | 'auto';\n /** Allow segmented keyboard typing (type the date-time directly across all segments). `false` makes the field picker-only. */\n editable?: boolean;\n /** Whether the calendar + time popover exists. `false` makes the field input-only (segmented typing with no popover). Default `true`. */\n popover?: boolean;\n /**\n * Open the popover on focus. Default `true`. Focus that a closing popover\n * hands back to the input leaves it closed. Dismissing it commits nothing:\n * an empty field stays empty, and leaving afterwards commits only what was\n * typed since. With it off, the launcher or Alt+ArrowDown opens it.\n */\n openOnFocus?: boolean;\n /** Off by default — users typically tweak both halves before committing. */\n closeOnSelect?: boolean;\n /** Popover anchor position. */\n position?: PickerPosition;\n /** Render the popover into `document.body` via portal. */\n appendToBody?: boolean;\n /**\n * Bulma color modifier for the input, also carried by the calendar and the\n * time wheels, where it colors the selected date and the selection band.\n * Today's date and the calendar's keyboard focus ring take the color's\n * `-on-scheme` variant, which Bulma adjusts to contrast with the background,\n * so pale colors stay readable. A focused wheel's ring is\n * drawn inside the band in the color's `-invert`, like the selected value,\n * so it shows on the fill. Unset, they use their\n * `--bulma-dateinput-*` and `--bulma-timeinput-wheel-*` variables, which\n * follow `primary` by default. The footer's time pill and Done button do not\n * follow `color`.\n */\n color?: 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger';\n /** Size variant. */\n size?: 'small' | 'medium' | 'large';\n /** Rounded input corners. */\n isRounded?: boolean;\n // date subset\n /** Disable specific dates. Blocked dates are also rejected during manual typing (the predicate receives the full candidate date-time — prefer day-based checks). */\n shouldDisableDate?: (d: Date) => boolean;\n /** Convenience array of disabled dates, matched by calendar day; also rejected by manual typing. */\n unselectableDates?: Date[];\n /** Day the calendar week starts on. */\n firstDayOfWeek?: DayOfWeek;\n /** Override the 7 day-name labels. */\n dayNames?: string[];\n /** Override the 12 month-name labels. */\n monthNames?: string[];\n /** Show dimmed dates from adjacent months. */\n nearbyMonthDays?: boolean;\n // time subset\n /** Time format. */\n hourFormat?: HourFormat;\n /** Show seconds column. Note: iOS Safari's native datetime-local picker UI does not include a seconds wheel; pass `mobileNative={false}` if you need one on iOS. */\n enableSeconds?: boolean;\n /** Hour step. */\n incrementHours?: number;\n /** Step between minute-wheel values (`1` = every minute, iOS-style). */\n incrementMinutes?: number;\n /** Step between second-wheel values (only with `enableSeconds`). */\n incrementSeconds?: number;\n /** Block specific times. Blocked times are also rejected during manual typing. */\n unselectableTimes?: (d: Date) => boolean;\n /** Decorative left icon glyph for the wrapping `Control` (shown by default). Set `''` to hide. */\n iconLeftName?: string;\n /**\n * Show a clickable launcher button on the right that toggles the popover.\n * Hidden by default while a `Control` it sits in shows its `isLoading`\n * spinner, which shares that right edge.\n * @defaultValue true\n */\n triggerIcon?: boolean;\n /** Glyph for the right launcher button. */\n triggerIconName?: string;\n /** Play a short audible tick on each time-wheel crossing. Default `false`. */\n audioTick?: boolean;\n /** Auto-route tactile feedback per wheel tick (vibrate on Android, audio thunk on iOS). Default `false`. */\n haptics?: boolean;\n /** Optional translatable string overrides. */\n labels?: PickerLabels;\n}\n\n/**\n * Raw DateTimeInput — combined input + calendar + time spinner without\n * Field/Control wrapping. Use `DateTimeInput` for the convenience wrapper.\n *\n * @function\n * @param {DateTimeInputBaseProps} props\n * @returns {JSX.Element}\n */\nexport const DateTimeInputBase = forwardRef<\n HTMLInputElement,\n DateTimeInputBaseProps\n>((props, ref) => {\n const {\n value: controlledValue,\n defaultValue,\n onChange,\n onOpen,\n onClose,\n min,\n max,\n disabled,\n readOnly,\n placeholder,\n format,\n parse,\n locale,\n inline = false,\n mobileNative = 'auto',\n editable = true,\n popover = true,\n openOnFocus = true,\n closeOnSelect = false,\n position = 'bottom-left',\n appendToBody = false,\n color,\n size,\n isRounded,\n shouldDisableDate,\n unselectableDates,\n firstDayOfWeek = 0,\n dayNames,\n monthNames,\n nearbyMonthDays = true,\n hourFormat = '24',\n enableSeconds = false,\n incrementHours = 1,\n // Step between visible wheel values; 1 gives the iOS-style every-minute wheel.\n incrementMinutes = 1,\n incrementSeconds = 1,\n unselectableTimes,\n className,\n name,\n form,\n required,\n id: idProp,\n onFocus,\n onClick,\n onKeyDown,\n onBlur,\n iconLeftName: _iconLeftName,\n triggerIcon: triggerIconProp,\n triggerIconName = 'chevron-down',\n audioTick = false,\n haptics = false,\n labels,\n ...rest\n } = props;\n // Inside a labeled Field the input takes the id the label points at\n // when the caller set none, as InputBase does, and the popover's ids\n // follow it. Inline there is no input to name, so nothing takes the\n // Field's id or builds on it.\n const fieldLabelId = useFieldLabelId();\n const id = idProp ?? (inline ? undefined : fieldLabelId);\n // The launcher gives way to the loading spinner of a Control this sits in.\n const controlLoading = useControlLoading();\n const triggerIcon = triggerIconProp ?? !controlLoading;\n const t = mergeLabels(labels);\n\n // Platform-appropriate feedback routing for the time wheel: on iOS (no\n // navigator.vibrate) the audio thunk fills in; on Android the real haptic\n // fires and no audio is layered on. `audioTick` always wins.\n const hasVibrate =\n typeof navigator !== 'undefined' && typeof navigator.vibrate === 'function';\n const effectiveAudioTick = audioTick || (haptics && !hasVibrate);\n\n const isControlled = controlledValue !== undefined;\n const [internalValue, setInternalValue] = useState<Date | null>(\n defaultValue ?? null\n );\n const value = isControlled ? (controlledValue ?? null) : internalValue;\n\n // Nothing before year 1 is in range, as in HTML's date inputs.\n const lowerBound = useMemo(() => floorMin(min), [min]);\n\n const initialFocused = useMemo(\n () => clampDate(value ?? new Date(), lowerBound, max),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n []\n );\n const [focusedDate, setFocusedDate] = useState<Date>(initialFocused);\n // Re-clamp focusedDate when min/max change so the focused cell stays valid.\n useEffect(() => {\n setFocusedDate(prev => clampDate(prev, lowerBound, max));\n }, [lowerBound, max]);\n\n const defaultFormat: DateFormatOption =\n format ??\n (hourFormat === '12'\n ? enableSeconds\n ? 'YYYY-MM-DD hh:mm:ss A'\n : 'YYYY-MM-DD hh:mm A'\n : enableSeconds\n ? 'YYYY-MM-DD HH:mm:ss'\n : DEFAULT_DATETIME_FORMAT);\n\n // The displayed format is the source of truth for the hour cycle: an explicit\n // 12-hour `format` must drive a 12-hour wheel + pill even when `hourFormat`\n // was left at its default. Fall back to the raw prop only when the cycle\n // can't be read from the format (an Intl-options object, or no hour token).\n const effectiveHourFormat = hourCycleFromFormat(defaultFormat) ?? hourFormat;\n\n const [open, setOpenState] = useState(false);\n // The time wheels are collapsed by default (iOS-style); the user reveals\n // them by clicking the time value in the footer.\n const [timeOpen, setTimeOpen] = useState(false);\n const [text, setText] = useState<string>(\n value ? formatDateTime(value, defaultFormat, locale) : ''\n );\n\n const inputRef = useRef<HTMLInputElement>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n // Snapshot of the value when the popover opens, so Reset can revert the\n // edits made in this session (reverting to empty if it opened empty).\n const valueAtOpenRef = useRef<Date | null>(null);\n const reactId = useId();\n const popoverId = id ? `${id}-popover` : `picker-${reactId}`;\n const timeWheelsId = `${popoverId}-time`;\n\n const { bulmaHelperClasses, rest: cleanRest } = useBulmaClasses(rest);\n\n const { shouldUseNative, isSmallViewport } = useNativeMobilePicker({\n force: mobileNative === 'auto' ? undefined : mobileNative,\n });\n const useNative = !inline && shouldUseNative;\n const wheelItemHeight = isSmallViewport ? 40 : 32;\n\n // Time-only format for the footer's \"Time 5:07 PM\" display.\n const timeDisplayFormat =\n effectiveHourFormat === '12'\n ? enableSeconds\n ? 'h:mm:ss A'\n : 'h:mm A'\n : enableSeconds\n ? 'HH:mm:ss'\n : 'HH:mm';\n\n const inputClass = usePrefixedClassNames('input', {\n [`is-${color}`]: !!color,\n [`is-${size}`]: !!size,\n 'is-rounded': isRounded,\n });\n const containerClass = usePrefixedClassNames('datetimeinput-container');\n const triggerClass = usePrefixedClassNames('datetimeinput-trigger');\n const panelClass = usePrefixedClassNames('datetimeinput');\n const calendarWrapClass = usePrefixedClassNames(\n 'datetimeinput-calendar-wrap'\n );\n const timeOverlayClass = usePrefixedClassNames('datetimeinput-time-overlay');\n const timeCardClass = usePrefixedClassNames('datetimeinput-time-card');\n const footerClass = usePrefixedClassNames('datetimeinput-footer');\n const footerTimeClass = usePrefixedClassNames('datetimeinput-footer-time');\n const footerActionsClass = usePrefixedClassNames(\n 'datetimeinput-footer-actions'\n );\n const footerResetClass = usePrefixedClassNames('datetimeinput-footer-reset');\n const footerDoneClass = usePrefixedClassNames('datetimeinput-footer-done');\n const footerTimePillClass = usePrefixedClassNames(\n 'datetimeinput-footer-time-pill'\n );\n\n // What the latest request asked for, so a second request in the same event\n // sees it before React renders. The callbacks fire here rather than in a\n // state updater, which StrictMode calls twice, and after the state is set,\n // so a request a callback makes is the one that lands last.\n const requestedOpenRef = useRef(false);\n const setOpen = useCallback(\n (next: boolean) => {\n if (requestedOpenRef.current === next) return;\n requestedOpenRef.current = next;\n setOpenState(next);\n if (next) {\n valueAtOpenRef.current = value;\n onOpen?.();\n } else {\n onClose?.();\n }\n },\n [onOpen, onClose, value]\n );\n\n useEffect(() => {\n setText(value ? formatDateTime(value, defaultFormat, locale) : '');\n }, [value, defaultFormat, locale]);\n\n // Collapse the time wheels whenever the popover closes.\n useEffect(() => {\n if (!open) setTimeOpen(false);\n }, [open]);\n\n // The footer's Time button opens the wheels, and the hours wheel takes\n // focus so the keys turn it straight away. The calendar they cover is\n // inert meanwhile, so no tab stop, pointer or screen reader reaches a day\n // behind them. Closing the wheels hands focus back to the button: focus\n // in them would fall to the page as they unmount, and a pointer press\n // outside them has already dropped it on the panel or the page. Focus the\n // keys moved on to the footer, such as Reset, stays there.\n const panelRef = useRef<HTMLDivElement>(null);\n const timeButtonRef = useRef<HTMLButtonElement>(null);\n const timeOverlayRef = useRef<HTMLDivElement>(null);\n useEffect(() => {\n if (!timeOpen) return;\n timeOverlayRef.current\n ?.querySelector<HTMLElement>('[role=\"spinbutton\"]')\n ?.focus();\n }, [timeOpen]);\n const closeTime = useCallback(() => {\n const panel = panelRef.current;\n const active = getActiveElementInTree(panel);\n const movedOn =\n !!panel?.contains(active) && !timeOverlayRef.current?.contains(active);\n if (!movedOn) timeButtonRef.current?.focus();\n setTimeOpen(false);\n }, []);\n\n const commitValue = useCallback(\n (next: Date | null) => {\n if (!isControlled) setInternalValue(next);\n // Keep the calendar's focused cell tracking typed / parsed values.\n if (next) setFocusedDate(next);\n onChange?.(next);\n },\n [isControlled, onChange]\n );\n\n // A picked day takes the value's whole time of day, seconds and all, or\n // midnight in an empty field. The day handed over by the keyboard is the\n // calendar's focused date, which can carry the time of the clock it\n // started from, so none of its time is kept.\n const handleDateSelect = useCallback(\n (d: Date) => {\n const merged = setTimeOfDay(d, {\n hours: value?.getHours() ?? 0,\n minutes: value?.getMinutes() ?? 0,\n seconds: value?.getSeconds() ?? 0,\n milliseconds: value?.getMilliseconds() ?? 0,\n });\n if (!isWithin(merged, lowerBound, max)) return;\n commitValue(merged);\n setFocusedDate(d);\n },\n [value, lowerBound, max, commitValue]\n );\n\n // The wheels set the value's time. An empty field starts from the focused\n // day, at the whole minute or second the wheels show.\n const handleTimeChange = useCallback(\n (parts: { hours: number; minutes: number; seconds?: number }) => {\n const next = value\n ? setTimeOfDay(value, parts)\n : setTimeOfDay(focusedDate, {\n ...parts,\n seconds: parts.seconds ?? 0,\n milliseconds: 0,\n });\n if (!isWithin(next, lowerBound, max)) return;\n commitValue(next);\n },\n [value, focusedDate, lowerBound, max, commitValue]\n );\n\n const tryParse = useCallback(\n (s: string): Date | null => {\n const trimmed = s.trim();\n if (!trimmed) return null;\n if (parse) return parse(trimmed);\n const fmt = typeof defaultFormat === 'string' ? defaultFormat : undefined;\n return parseDate(trimmed, fmt ?? DEFAULT_DATETIME_FORMAT, locale);\n },\n [parse, defaultFormat, locale]\n );\n\n // The Date the user edits when starting without a current value: now, at\n // the whole minute, or the whole second with `enableSeconds`.\n const makeBaseDate = useCallback(\n (): Date =>\n setTimeOfDay(new Date(), {\n seconds: enableSeconds ? undefined : 0,\n milliseconds: 0,\n }),\n [enableSeconds]\n );\n\n const inputReadOnlyAttr = !!readOnly || !editable;\n const canOpen = !!popover && !disabled && !readOnly;\n\n // Blocking predicate for manual entry, combining the calendar's\n // disabled-day logic with the wheels' unselectable-times predicate. The\n // candidate passed in carries the full date-time, so date predicates\n // should use day-based checks.\n const isBlocked = useMemo(() => {\n if (!shouldDisableDate && !unselectableDates?.length && !unselectableTimes)\n return undefined;\n return (d: Date) =>\n !!shouldDisableDate?.(d) ||\n !!unselectableDates?.some(u => isSameDay(u, d)) ||\n !!unselectableTimes?.(d);\n }, [shouldDisableDate, unselectableDates, unselectableTimes]);\n\n const { inputHandlers } = useSegmentedEntry({\n format: defaultFormat,\n value,\n commitValue,\n formatFn: formatDateTime,\n tryParse,\n text,\n setText,\n makeBaseDate,\n locale,\n min: lowerBound,\n max,\n isBlocked,\n disabled,\n readOnly,\n editable,\n popover,\n openOnFocus,\n closeOnSelect,\n isOpen: open,\n setOpen,\n inputRef,\n containerRef,\n onFocus,\n onClick,\n onKeyDown,\n onBlur,\n });\n\n const combinedRef = useCallback(\n (node: HTMLInputElement | null) => {\n (inputRef as React.MutableRefObject<HTMLInputElement | null>).current =\n node;\n if (typeof ref === 'function') ref(node);\n else if (ref)\n (ref as React.MutableRefObject<HTMLInputElement | null>).current = node;\n },\n [ref]\n );\n\n if (useNative) {\n const nativeStep = enableSeconds ? incrementSeconds : incrementMinutes * 60;\n return (\n <input\n {...cleanRest}\n ref={combinedRef}\n type=\"datetime-local\"\n step={nativeStep}\n className={classNames(inputClass, bulmaHelperClasses, className)}\n value={value ? toIsoDateTime(value, enableSeconds) : ''}\n onChange={e => {\n const parsed = e.target.value\n ? fromIsoDateTime(e.target.value)\n : null;\n commitValue(parsed);\n }}\n min={min ? toIsoDateTime(lowerBound, enableSeconds) : undefined}\n max={max ? toIsoDateTime(max, enableSeconds) : undefined}\n disabled={disabled}\n readOnly={readOnly}\n placeholder={placeholder}\n name={name}\n form={form}\n required={required}\n id={id}\n />\n );\n }\n\n const spinnerValue = {\n hours: value?.getHours() ?? 0,\n minutes: value?.getMinutes() ?? 0,\n seconds: enableSeconds ? (value?.getSeconds() ?? 0) : undefined,\n };\n\n const panel = (\n <div\n ref={panelRef}\n className={panelClass}\n onKeyDown={e => {\n // First Escape collapses the floating time wheels; the popover's own\n // Escape handler (which closes the whole panel) only sees the second.\n if (timeOpen && e.key === 'Escape') {\n e.stopPropagation();\n closeTime();\n }\n }}\n >\n <div className={calendarWrapClass}>\n <div {...inertProps(timeOpen)}>\n <Calendar\n value={value}\n focusedDate={focusedDate}\n onSelect={handleDateSelect}\n onFocusedDateChange={setFocusedDate}\n min={min}\n max={max}\n shouldDisableDate={shouldDisableDate}\n unselectableDates={unselectableDates}\n firstDayOfWeek={firstDayOfWeek}\n locale={locale}\n dayNames={dayNames}\n monthNames={monthNames}\n nearbyMonthDays={nearbyMonthDays}\n color={color}\n size={size}\n id={`${popoverId}-cal`}\n autoFocusCell={open}\n labels={labels}\n />\n </div>\n {timeOpen && (\n <div\n ref={timeOverlayRef}\n className={timeOverlayClass}\n onClick={e => {\n // Tap outside the wheel card (on the covered calendar area)\n // collapses the wheels without selecting a date, matching the\n // native behavior.\n if (e.target === e.currentTarget) closeTime();\n }}\n >\n <div className={timeCardClass}>\n <TimeWheels\n value={spinnerValue}\n onChange={handleTimeChange}\n hourFormat={effectiveHourFormat}\n enableSeconds={enableSeconds}\n incrementHours={incrementHours}\n incrementMinutes={incrementMinutes}\n incrementSeconds={incrementSeconds}\n unselectableTimes={unselectableTimes}\n color={color}\n size={size}\n disabled={disabled}\n id={timeWheelsId}\n labels={labels}\n itemHeight={wheelItemHeight}\n audioTick={effectiveAudioTick}\n // Enter on a wheel commits the time, which the wheels already\n // did live, and closes: the popover, or inline, where there\n // is no popover, the wheels, as Escape does.\n onCommit={() => (inline ? closeTime() : setOpen(false))}\n />\n </div>\n </div>\n )}\n </div>\n <div className={footerClass}>\n <button\n ref={timeButtonRef}\n type=\"button\"\n className={footerTimeClass}\n onClick={() => (timeOpen ? closeTime() : setTimeOpen(true))}\n aria-expanded={timeOpen}\n // The wheels exist only while open, so only then is there an\n // element for the button to name.\n aria-controls={timeOpen ? timeWheelsId : undefined}\n disabled={disabled}\n >\n <span>{t.time}</span>\n <span className={footerTimePillClass}>\n {value ? formatTime(value, timeDisplayFormat, locale) : '—'}\n </span>\n </button>\n <div className={footerActionsClass}>\n <button\n type=\"button\"\n className={footerResetClass}\n onClick={() => commitValue(valueAtOpenRef.current)}\n >\n {t.reset}\n </button>\n <button\n type=\"button\"\n className={footerDoneClass}\n aria-label={t.done}\n onClick={() => setOpen(false)}\n >\n <svg width=\"22\" height=\"22\" viewBox=\"0 0 22 22\" aria-hidden=\"true\">\n <path\n d=\"M5 11l4 4 8-8\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n </button>\n </div>\n </div>\n </div>\n );\n\n if (inline) {\n return (\n <div\n {...cleanRest}\n ref={containerRef}\n className={classNames(containerClass, bulmaHelperClasses, className)}\n >\n {panel}\n {name && (\n <input\n type=\"hidden\"\n name={name}\n form={form}\n value={value ? toIsoDateTime(value, enableSeconds) : ''}\n required={required}\n />\n )}\n </div>\n );\n }\n\n return (\n <div\n ref={containerRef}\n className={classNames(containerClass, bulmaHelperClasses, className)}\n {...cleanRest}\n >\n <input\n ref={combinedRef}\n type=\"text\"\n role=\"combobox\"\n aria-haspopup=\"dialog\"\n aria-expanded={open}\n aria-controls={popoverId}\n autoComplete=\"off\"\n className={inputClass}\n value={text}\n placeholder={placeholder}\n disabled={disabled}\n readOnly={inputReadOnlyAttr}\n name={name}\n form={form}\n required={required}\n id={id}\n {...inputHandlers}\n />\n {popover && triggerIcon && (\n <button\n type=\"button\"\n className={triggerClass}\n onClick={() => {\n if (canOpen) setOpen(!open);\n }}\n disabled={!canOpen}\n aria-label={t.chooseDateTime}\n aria-haspopup=\"dialog\"\n aria-controls={popoverId}\n aria-expanded={open}\n tabIndex={canOpen ? 0 : -1}\n >\n <Icon name={triggerIconName} size={size} />\n </button>\n )}\n {popover && (\n <PickerPopover\n isOpen={open}\n onClose={() => setOpen(false)}\n anchorRef={containerRef}\n position={position}\n appendToBody={appendToBody}\n ariaLabel={t.chooseDateTime}\n id={popoverId}\n restoreFocusRef={inputRef}\n initialFocusSelector={CALENDAR_FOCUSED_CELL}\n >\n {panel}\n </PickerPopover>\n )}\n </div>\n );\n});\n\nDateTimeInputBase.displayName = 'DateTimeInputBase';\n\nexport default DateTimeInputBase;\n"],"names":["_jsx","_jsxs"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"DateTimeInputBase.js","sources":["../../../src/form/DateTimeInputBase.tsx"],"sourcesContent":["import React, {\n forwardRef,\n useCallback,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport { useBulmaClasses, BulmaClassesProps } from '../helpers/useBulmaClasses';\nimport {\n PickerPosition,\n HourFormat,\n DayOfWeek,\n PickerLabels,\n mergeLabels,\n} from './_pickerInternals/pickerTypes';\nimport {\n formatDateTime,\n formatTime,\n hourCycleFromFormat,\n parseDate,\n DateFormatOption,\n DEFAULT_DATETIME_FORMAT,\n} from './_pickerInternals/formatters';\nimport {\n isWithin,\n setTimeOfDay,\n clampDate,\n FIRST_YEAR,\n floorMin,\n isSameDay,\n makeDate,\n} from './_pickerInternals/dateUtils';\nimport { Calendar, CALENDAR_FOCUSED_CELL } from './_pickerInternals/Calendar';\nimport { TimeWheels } from './_pickerInternals/TimeWheels';\nimport { PickerPopover } from './_pickerInternals/PickerPopover';\nimport { useNativeMobilePicker } from './_pickerInternals/useNativeMobilePicker';\nimport { useSegmentedEntry } from './_pickerInternals/useSegmentedEntry';\nimport { useControlLoading } from './controlLoading';\nimport { useFieldLabelTarget } from './FormContext';\nimport { Icon } from '../elements/Icon';\nimport { getActiveElementInTree } from '../helpers/shadowDom';\nimport { inertProps } from '../helpers/inertProps';\n\n// The year is padded to four digits, as `datetime-local` requires. HTML has\n// no such shape for a year before 1, so a date then is empty, as that input\n// would make it.\nconst toIsoDateTime = (d: Date, withSeconds: boolean): string => {\n if (d.getFullYear() < FIRST_YEAR) return '';\n const yyyy = String(d.getFullYear()).padStart(4, '0');\n const mo = String(d.getMonth() + 1).padStart(2, '0');\n const dd = String(d.getDate()).padStart(2, '0');\n const hh = String(d.getHours()).padStart(2, '0');\n const mm = String(d.getMinutes()).padStart(2, '0');\n const ss = String(d.getSeconds()).padStart(2, '0');\n return withSeconds\n ? `${yyyy}-${mo}-${dd}T${hh}:${mm}:${ss}`\n : `${yyyy}-${mo}-${dd}T${hh}:${mm}`;\n};\n\nconst fromIsoDateTime = (s: string): Date | null => {\n // The HTML datetime-local value may carry fractional seconds (the spec\n // allows them and some engines normalize to `:ss.sss`); accept and drop.\n // Its year is four or more digits, as `toIsoDateTime` writes one past 9999.\n const m =\n /^(\\d{4,})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2})(?::(\\d{2})(?:\\.\\d{1,3})?)?$/.exec(\n s\n );\n if (!m) return null;\n const d = makeDate(Number(m[1]), Number(m[2]) - 1, Number(m[3]));\n d.setHours(Number(m[4]), Number(m[5]), m[6] ? Number(m[6]) : 0, 0);\n return d;\n};\n\n/**\n * Props for the raw DateTimeInput base. Use the higher-level `DateTimeInput`\n * for Field/Control composition. Combines the prop set of `DateInputBaseProps`\n * and `TimeInputBaseProps`.\n */\nexport interface DateTimeInputBaseProps\n extends\n Omit<\n React.InputHTMLAttributes<HTMLInputElement>,\n | 'value'\n | 'defaultValue'\n | 'onChange'\n | 'size'\n | 'color'\n | 'min'\n | 'max'\n | 'type'\n | 'popover'\n >,\n Omit<BulmaClassesProps, 'color'> {\n /** Controlled selected date-time. */\n value?: Date | null;\n /** Initial value for uncontrolled usage. */\n defaultValue?: Date | null;\n /**\n * Fired when either the date or time portion changes. Picking a day keeps\n * the value's whole time of day, down to seconds and milliseconds the field\n * doesn't show, and `min` and `max` judge the picked day at that time. An\n * empty field's day is picked at midnight.\n */\n onChange?: (d: Date | null) => void;\n /** Fired when the popover opens. */\n onOpen?: () => void;\n /** Fired when the popover closes. */\n onClose?: () => void;\n /**\n * Lower bound for the combined date-time. A `min` before year 1 is raised\n * to midnight on 1 January of year 1, where the range starts without one\n * too: HTML's datetime-local input holds no earlier year, so the calendar,\n * the time wheels and typing stop there.\n */\n min?: Date;\n /** Upper bound for the combined date-time. */\n max?: Date;\n /** Disable the input. */\n disabled?: boolean;\n /** Read-only input. */\n readOnly?: boolean;\n /** Placeholder text. */\n placeholder?: string;\n /**\n * Token format string or `Intl.DateTimeFormat` options. Default `'YYYY-MM-DD HH:mm'`.\n * @defaultValue 'YYYY-MM-DD HH:mm'\n */\n format?: DateFormatOption;\n /**\n * Custom parser. Enter and leaving the field call it only if the user\n * changed the text, so focus passing through commits nothing and the value\n * keeps what the format leaves out, such as seconds.\n */\n parse?: (s: string) => Date | null;\n /** BCP-47 locale tag. */\n locale?: string;\n /** Render the panel inline (no popover). */\n inline?: boolean;\n /** Use `<input type=\"datetime-local\">` on coarse-pointer devices. */\n mobileNative?: boolean | 'auto';\n /** Allow segmented keyboard typing (type the date-time directly across all segments). `false` makes the field picker-only. */\n editable?: boolean;\n /** Whether the calendar + time popover exists. `false` makes the field input-only (segmented typing with no popover). Default `true`. */\n popover?: boolean;\n /**\n * Open the popover on focus. Default `true`. Focus that a closing popover\n * hands back to the input leaves it closed. Dismissing it commits nothing:\n * an empty field stays empty, and leaving afterwards commits only what was\n * typed since. With it off, the launcher or Alt+ArrowDown opens it.\n */\n openOnFocus?: boolean;\n /** Off by default — users typically tweak both halves before committing. */\n closeOnSelect?: boolean;\n /** Popover anchor position. */\n position?: PickerPosition;\n /** Render the popover into `document.body` via portal. */\n appendToBody?: boolean;\n /**\n * Bulma color modifier for the input, also carried by the calendar and the\n * time wheels, where it colors the selected date and the selection band.\n * Today's date and the calendar's keyboard focus ring take the color's\n * `-on-scheme` variant, which Bulma adjusts to contrast with the background,\n * so pale colors stay readable. A focused wheel's ring is\n * drawn inside the band in the color's `-invert`, like the selected value,\n * so it shows on the fill. Unset, they use their\n * `--bulma-dateinput-*` and `--bulma-timeinput-wheel-*` variables, which\n * follow `primary` by default. The footer's time pill and Done button do not\n * follow `color`.\n */\n color?: 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger';\n /** Size variant. */\n size?: 'small' | 'medium' | 'large';\n /** Rounded input corners. */\n isRounded?: boolean;\n // date subset\n /** Disable specific dates. Blocked dates are also rejected during manual typing (the predicate receives the full candidate date-time — prefer day-based checks). */\n shouldDisableDate?: (d: Date) => boolean;\n /** Convenience array of disabled dates, matched by calendar day; also rejected by manual typing. */\n unselectableDates?: Date[];\n /** Day the calendar week starts on. */\n firstDayOfWeek?: DayOfWeek;\n /** Override the 7 day-name labels. */\n dayNames?: string[];\n /** Override the 12 month-name labels. */\n monthNames?: string[];\n /** Show dimmed dates from adjacent months. */\n nearbyMonthDays?: boolean;\n // time subset\n /** Time format. */\n hourFormat?: HourFormat;\n /** Show seconds column. Note: iOS Safari's native datetime-local picker UI does not include a seconds wheel; pass `mobileNative={false}` if you need one on iOS. */\n enableSeconds?: boolean;\n /** Hour step. */\n incrementHours?: number;\n /** Step between minute-wheel values (`1` = every minute, iOS-style). */\n incrementMinutes?: number;\n /** Step between second-wheel values (only with `enableSeconds`). */\n incrementSeconds?: number;\n /** Block specific times. Blocked times are also rejected during manual typing. */\n unselectableTimes?: (d: Date) => boolean;\n /** Decorative left icon glyph for the wrapping `Control` (shown by default). Set `''` to hide. */\n iconLeftName?: string;\n /**\n * Show a clickable launcher button on the right that toggles the popover.\n * Hidden by default while a `Control` it sits in shows its `isLoading`\n * spinner, which shares that right edge.\n * @defaultValue true\n */\n triggerIcon?: boolean;\n /** Glyph for the right launcher button. */\n triggerIconName?: string;\n /** Play a short audible tick on each time-wheel crossing. Default `false`. */\n audioTick?: boolean;\n /** Auto-route tactile feedback per wheel tick (vibrate on Android, audio thunk on iOS). Default `false`. */\n haptics?: boolean;\n /** Optional translatable string overrides. */\n labels?: PickerLabels;\n}\n\n/**\n * Raw DateTimeInput — combined input + calendar + time spinner without\n * Field/Control wrapping. Use `DateTimeInput` for the convenience wrapper.\n *\n * @function\n * @param {DateTimeInputBaseProps} props\n * @returns {JSX.Element}\n */\nexport const DateTimeInputBase = forwardRef<\n HTMLInputElement,\n DateTimeInputBaseProps\n>((props, ref) => {\n const {\n value: controlledValue,\n defaultValue,\n onChange,\n onOpen,\n onClose,\n min,\n max,\n disabled,\n readOnly,\n placeholder,\n format,\n parse,\n locale,\n inline = false,\n mobileNative = 'auto',\n editable = true,\n popover = true,\n openOnFocus = true,\n closeOnSelect = false,\n position = 'bottom-left',\n appendToBody = false,\n color,\n size,\n isRounded,\n shouldDisableDate,\n unselectableDates,\n firstDayOfWeek = 0,\n dayNames,\n monthNames,\n nearbyMonthDays = true,\n hourFormat = '24',\n enableSeconds = false,\n incrementHours = 1,\n // Step between visible wheel values; 1 gives the iOS-style every-minute wheel.\n incrementMinutes = 1,\n incrementSeconds = 1,\n unselectableTimes,\n className,\n name,\n form,\n required,\n id: idProp,\n onFocus,\n onClick,\n onKeyDown,\n onBlur,\n iconLeftName: _iconLeftName,\n triggerIcon: triggerIconProp,\n triggerIconName = 'chevron-down',\n audioTick = false,\n haptics = false,\n labels,\n ...rest\n } = props;\n // Inside a labeled Field the input takes the id the label points at\n // when the caller set none, as InputBase does, and the popover's ids\n // follow it. Inline there is no input to name, so nothing takes the\n // Field's id or builds on it.\n const id = useFieldLabelTarget(idProp, !inline);\n // The launcher gives way to the loading spinner of a Control this sits in.\n const controlLoading = useControlLoading();\n const triggerIcon = triggerIconProp ?? !controlLoading;\n const t = mergeLabels(labels);\n\n // Platform-appropriate feedback routing for the time wheel: on iOS (no\n // navigator.vibrate) the audio thunk fills in; on Android the real haptic\n // fires and no audio is layered on. `audioTick` always wins.\n const hasVibrate =\n typeof navigator !== 'undefined' && typeof navigator.vibrate === 'function';\n const effectiveAudioTick = audioTick || (haptics && !hasVibrate);\n\n const isControlled = controlledValue !== undefined;\n const [internalValue, setInternalValue] = useState<Date | null>(\n defaultValue ?? null\n );\n const value = isControlled ? (controlledValue ?? null) : internalValue;\n\n // Nothing before year 1 is in range, as in HTML's date inputs.\n const lowerBound = useMemo(() => floorMin(min), [min]);\n\n const initialFocused = useMemo(\n () => clampDate(value ?? new Date(), lowerBound, max),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n []\n );\n const [focusedDate, setFocusedDate] = useState<Date>(initialFocused);\n // Re-clamp focusedDate when min/max change so the focused cell stays valid.\n useEffect(() => {\n setFocusedDate(prev => clampDate(prev, lowerBound, max));\n }, [lowerBound, max]);\n\n const defaultFormat: DateFormatOption =\n format ??\n (hourFormat === '12'\n ? enableSeconds\n ? 'YYYY-MM-DD hh:mm:ss A'\n : 'YYYY-MM-DD hh:mm A'\n : enableSeconds\n ? 'YYYY-MM-DD HH:mm:ss'\n : DEFAULT_DATETIME_FORMAT);\n\n // The displayed format is the source of truth for the hour cycle: an explicit\n // 12-hour `format` must drive a 12-hour wheel + pill even when `hourFormat`\n // was left at its default. Fall back to the raw prop only when the cycle\n // can't be read from the format (an Intl-options object, or no hour token).\n const effectiveHourFormat = hourCycleFromFormat(defaultFormat) ?? hourFormat;\n\n const [open, setOpenState] = useState(false);\n // The time wheels are collapsed by default (iOS-style); the user reveals\n // them by clicking the time value in the footer.\n const [timeOpen, setTimeOpen] = useState(false);\n const [text, setText] = useState<string>(\n value ? formatDateTime(value, defaultFormat, locale) : ''\n );\n\n const inputRef = useRef<HTMLInputElement>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n // Snapshot of the value when the popover opens, so Reset can revert the\n // edits made in this session (reverting to empty if it opened empty).\n const valueAtOpenRef = useRef<Date | null>(null);\n const reactId = useId();\n const popoverId = id ? `${id}-popover` : `picker-${reactId}`;\n const timeWheelsId = `${popoverId}-time`;\n\n const { bulmaHelperClasses, rest: cleanRest } = useBulmaClasses(rest);\n\n const { shouldUseNative, isSmallViewport } = useNativeMobilePicker({\n force: mobileNative === 'auto' ? undefined : mobileNative,\n });\n const useNative = !inline && shouldUseNative;\n const wheelItemHeight = isSmallViewport ? 40 : 32;\n\n // Time-only format for the footer's \"Time 5:07 PM\" display.\n const timeDisplayFormat =\n effectiveHourFormat === '12'\n ? enableSeconds\n ? 'h:mm:ss A'\n : 'h:mm A'\n : enableSeconds\n ? 'HH:mm:ss'\n : 'HH:mm';\n\n const inputClass = usePrefixedClassNames('input', {\n [`is-${color}`]: !!color,\n [`is-${size}`]: !!size,\n 'is-rounded': isRounded,\n });\n const containerClass = usePrefixedClassNames('datetimeinput-container');\n const triggerClass = usePrefixedClassNames('datetimeinput-trigger');\n const panelClass = usePrefixedClassNames('datetimeinput');\n const calendarWrapClass = usePrefixedClassNames(\n 'datetimeinput-calendar-wrap'\n );\n const timeOverlayClass = usePrefixedClassNames('datetimeinput-time-overlay');\n const timeCardClass = usePrefixedClassNames('datetimeinput-time-card');\n const footerClass = usePrefixedClassNames('datetimeinput-footer');\n const footerTimeClass = usePrefixedClassNames('datetimeinput-footer-time');\n const footerActionsClass = usePrefixedClassNames(\n 'datetimeinput-footer-actions'\n );\n const footerResetClass = usePrefixedClassNames('datetimeinput-footer-reset');\n const footerDoneClass = usePrefixedClassNames('datetimeinput-footer-done');\n const footerTimePillClass = usePrefixedClassNames(\n 'datetimeinput-footer-time-pill'\n );\n\n // What the latest request asked for, so a second request in the same event\n // sees it before React renders. The callbacks fire here rather than in a\n // state updater, which StrictMode calls twice, and after the state is set,\n // so a request a callback makes is the one that lands last.\n const requestedOpenRef = useRef(false);\n const setOpen = useCallback(\n (next: boolean) => {\n if (requestedOpenRef.current === next) return;\n requestedOpenRef.current = next;\n setOpenState(next);\n if (next) {\n valueAtOpenRef.current = value;\n onOpen?.();\n } else {\n onClose?.();\n }\n },\n [onOpen, onClose, value]\n );\n\n useEffect(() => {\n setText(value ? formatDateTime(value, defaultFormat, locale) : '');\n }, [value, defaultFormat, locale]);\n\n // Collapse the time wheels whenever the popover closes.\n useEffect(() => {\n if (!open) setTimeOpen(false);\n }, [open]);\n\n // The footer's Time button opens the wheels, and the hours wheel takes\n // focus so the keys turn it straight away. The calendar they cover is\n // inert meanwhile, so no tab stop, pointer or screen reader reaches a day\n // behind them. Closing the wheels hands focus back to the button: focus\n // in them would fall to the page as they unmount, and a pointer press\n // outside them has already dropped it on the panel or the page. Focus the\n // keys moved on to the footer, such as Reset, stays there.\n const panelRef = useRef<HTMLDivElement>(null);\n const timeButtonRef = useRef<HTMLButtonElement>(null);\n const timeOverlayRef = useRef<HTMLDivElement>(null);\n useEffect(() => {\n if (!timeOpen) return;\n timeOverlayRef.current\n ?.querySelector<HTMLElement>('[role=\"spinbutton\"]')\n ?.focus();\n }, [timeOpen]);\n const closeTime = useCallback(() => {\n const panel = panelRef.current;\n const active = getActiveElementInTree(panel);\n const movedOn =\n !!panel?.contains(active) && !timeOverlayRef.current?.contains(active);\n if (!movedOn) timeButtonRef.current?.focus();\n setTimeOpen(false);\n }, []);\n\n const commitValue = useCallback(\n (next: Date | null) => {\n if (!isControlled) setInternalValue(next);\n // Keep the calendar's focused cell tracking typed / parsed values.\n if (next) setFocusedDate(next);\n onChange?.(next);\n },\n [isControlled, onChange]\n );\n\n // A picked day takes the value's whole time of day, seconds and all, or\n // midnight in an empty field. The day handed over by the keyboard is the\n // calendar's focused date, which can carry the time of the clock it\n // started from, so none of its time is kept.\n const handleDateSelect = useCallback(\n (d: Date) => {\n const merged = setTimeOfDay(d, {\n hours: value?.getHours() ?? 0,\n minutes: value?.getMinutes() ?? 0,\n seconds: value?.getSeconds() ?? 0,\n milliseconds: value?.getMilliseconds() ?? 0,\n });\n if (!isWithin(merged, lowerBound, max)) return;\n commitValue(merged);\n setFocusedDate(d);\n },\n [value, lowerBound, max, commitValue]\n );\n\n // The wheels set the value's time. An empty field starts from the focused\n // day, at the whole minute or second the wheels show.\n const handleTimeChange = useCallback(\n (parts: { hours: number; minutes: number; seconds?: number }) => {\n const next = value\n ? setTimeOfDay(value, parts)\n : setTimeOfDay(focusedDate, {\n ...parts,\n seconds: parts.seconds ?? 0,\n milliseconds: 0,\n });\n if (!isWithin(next, lowerBound, max)) return;\n commitValue(next);\n },\n [value, focusedDate, lowerBound, max, commitValue]\n );\n\n const tryParse = useCallback(\n (s: string): Date | null => {\n const trimmed = s.trim();\n if (!trimmed) return null;\n if (parse) return parse(trimmed);\n const fmt = typeof defaultFormat === 'string' ? defaultFormat : undefined;\n return parseDate(trimmed, fmt ?? DEFAULT_DATETIME_FORMAT, locale);\n },\n [parse, defaultFormat, locale]\n );\n\n // The Date the user edits when starting without a current value: now, at\n // the whole minute, or the whole second with `enableSeconds`.\n const makeBaseDate = useCallback(\n (): Date =>\n setTimeOfDay(new Date(), {\n seconds: enableSeconds ? undefined : 0,\n milliseconds: 0,\n }),\n [enableSeconds]\n );\n\n const inputReadOnlyAttr = !!readOnly || !editable;\n const canOpen = !!popover && !disabled && !readOnly;\n\n // Blocking predicate for manual entry, combining the calendar's\n // disabled-day logic with the wheels' unselectable-times predicate. The\n // candidate passed in carries the full date-time, so date predicates\n // should use day-based checks.\n const isBlocked = useMemo(() => {\n if (!shouldDisableDate && !unselectableDates?.length && !unselectableTimes)\n return undefined;\n return (d: Date) =>\n !!shouldDisableDate?.(d) ||\n !!unselectableDates?.some(u => isSameDay(u, d)) ||\n !!unselectableTimes?.(d);\n }, [shouldDisableDate, unselectableDates, unselectableTimes]);\n\n const { inputHandlers } = useSegmentedEntry({\n format: defaultFormat,\n value,\n commitValue,\n formatFn: formatDateTime,\n tryParse,\n text,\n setText,\n makeBaseDate,\n locale,\n min: lowerBound,\n max,\n isBlocked,\n disabled,\n readOnly,\n editable,\n popover,\n openOnFocus,\n closeOnSelect,\n isOpen: open,\n setOpen,\n inputRef,\n containerRef,\n onFocus,\n onClick,\n onKeyDown,\n onBlur,\n });\n\n const combinedRef = useCallback(\n (node: HTMLInputElement | null) => {\n (inputRef as React.MutableRefObject<HTMLInputElement | null>).current =\n node;\n if (typeof ref === 'function') ref(node);\n else if (ref)\n (ref as React.MutableRefObject<HTMLInputElement | null>).current = node;\n },\n [ref]\n );\n\n if (useNative) {\n const nativeStep = enableSeconds ? incrementSeconds : incrementMinutes * 60;\n return (\n <input\n {...cleanRest}\n ref={combinedRef}\n type=\"datetime-local\"\n step={nativeStep}\n className={classNames(inputClass, bulmaHelperClasses, className)}\n value={value ? toIsoDateTime(value, enableSeconds) : ''}\n onChange={e => {\n const parsed = e.target.value\n ? fromIsoDateTime(e.target.value)\n : null;\n commitValue(parsed);\n }}\n min={min ? toIsoDateTime(lowerBound, enableSeconds) : undefined}\n max={max ? toIsoDateTime(max, enableSeconds) : undefined}\n disabled={disabled}\n readOnly={readOnly}\n placeholder={placeholder}\n name={name}\n form={form}\n required={required}\n id={id}\n />\n );\n }\n\n const spinnerValue = {\n hours: value?.getHours() ?? 0,\n minutes: value?.getMinutes() ?? 0,\n seconds: enableSeconds ? (value?.getSeconds() ?? 0) : undefined,\n };\n\n const panel = (\n <div\n ref={panelRef}\n className={panelClass}\n onKeyDown={e => {\n // First Escape collapses the floating time wheels; the popover's own\n // Escape handler (which closes the whole panel) only sees the second.\n if (timeOpen && e.key === 'Escape') {\n e.stopPropagation();\n closeTime();\n }\n }}\n >\n <div className={calendarWrapClass}>\n <div {...inertProps(timeOpen)}>\n <Calendar\n value={value}\n focusedDate={focusedDate}\n onSelect={handleDateSelect}\n onFocusedDateChange={setFocusedDate}\n min={min}\n max={max}\n shouldDisableDate={shouldDisableDate}\n unselectableDates={unselectableDates}\n firstDayOfWeek={firstDayOfWeek}\n locale={locale}\n dayNames={dayNames}\n monthNames={monthNames}\n nearbyMonthDays={nearbyMonthDays}\n color={color}\n size={size}\n id={`${popoverId}-cal`}\n autoFocusCell={open}\n labels={labels}\n />\n </div>\n {timeOpen && (\n <div\n ref={timeOverlayRef}\n className={timeOverlayClass}\n onClick={e => {\n // Tap outside the wheel card (on the covered calendar area)\n // collapses the wheels without selecting a date, matching the\n // native behavior.\n if (e.target === e.currentTarget) closeTime();\n }}\n >\n <div className={timeCardClass}>\n <TimeWheels\n value={spinnerValue}\n onChange={handleTimeChange}\n hourFormat={effectiveHourFormat}\n enableSeconds={enableSeconds}\n incrementHours={incrementHours}\n incrementMinutes={incrementMinutes}\n incrementSeconds={incrementSeconds}\n unselectableTimes={unselectableTimes}\n color={color}\n size={size}\n disabled={disabled}\n id={timeWheelsId}\n labels={labels}\n itemHeight={wheelItemHeight}\n audioTick={effectiveAudioTick}\n // Enter on a wheel commits the time, which the wheels already\n // did live, and closes: the popover, or inline, where there\n // is no popover, the wheels, as Escape does.\n onCommit={() => (inline ? closeTime() : setOpen(false))}\n />\n </div>\n </div>\n )}\n </div>\n <div className={footerClass}>\n <button\n ref={timeButtonRef}\n type=\"button\"\n className={footerTimeClass}\n onClick={() => (timeOpen ? closeTime() : setTimeOpen(true))}\n aria-expanded={timeOpen}\n // The wheels exist only while open, so only then is there an\n // element for the button to name.\n aria-controls={timeOpen ? timeWheelsId : undefined}\n disabled={disabled}\n >\n <span>{t.time}</span>\n <span className={footerTimePillClass}>\n {value ? formatTime(value, timeDisplayFormat, locale) : '—'}\n </span>\n </button>\n <div className={footerActionsClass}>\n <button\n type=\"button\"\n className={footerResetClass}\n onClick={() => commitValue(valueAtOpenRef.current)}\n >\n {t.reset}\n </button>\n <button\n type=\"button\"\n className={footerDoneClass}\n aria-label={t.done}\n onClick={() => setOpen(false)}\n >\n <svg width=\"22\" height=\"22\" viewBox=\"0 0 22 22\" aria-hidden=\"true\">\n <path\n d=\"M5 11l4 4 8-8\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n </button>\n </div>\n </div>\n </div>\n );\n\n if (inline) {\n return (\n <div\n {...cleanRest}\n ref={containerRef}\n className={classNames(containerClass, bulmaHelperClasses, className)}\n >\n {panel}\n {name && (\n <input\n type=\"hidden\"\n name={name}\n form={form}\n value={value ? toIsoDateTime(value, enableSeconds) : ''}\n required={required}\n />\n )}\n </div>\n );\n }\n\n return (\n <div\n ref={containerRef}\n className={classNames(containerClass, bulmaHelperClasses, className)}\n {...cleanRest}\n >\n <input\n ref={combinedRef}\n type=\"text\"\n role=\"combobox\"\n aria-haspopup=\"dialog\"\n aria-expanded={open}\n aria-controls={popoverId}\n autoComplete=\"off\"\n className={inputClass}\n value={text}\n placeholder={placeholder}\n disabled={disabled}\n readOnly={inputReadOnlyAttr}\n name={name}\n form={form}\n required={required}\n id={id}\n {...inputHandlers}\n />\n {popover && triggerIcon && (\n <button\n type=\"button\"\n className={triggerClass}\n onClick={() => {\n if (canOpen) setOpen(!open);\n }}\n disabled={!canOpen}\n aria-label={t.chooseDateTime}\n aria-haspopup=\"dialog\"\n aria-controls={popoverId}\n aria-expanded={open}\n tabIndex={canOpen ? 0 : -1}\n >\n <Icon name={triggerIconName} size={size} />\n </button>\n )}\n {popover && (\n <PickerPopover\n isOpen={open}\n onClose={() => setOpen(false)}\n anchorRef={containerRef}\n position={position}\n appendToBody={appendToBody}\n ariaLabel={t.chooseDateTime}\n id={popoverId}\n restoreFocusRef={inputRef}\n initialFocusSelector={CALENDAR_FOCUSED_CELL}\n >\n {panel}\n </PickerPopover>\n )}\n </div>\n );\n});\n\nDateTimeInputBase.displayName = 'DateTimeInputBase';\n\nexport default DateTimeInputBase;\n"],"names":["_jsx","_jsxs"],"mappings":"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"}
|
package/dist/esm/form/Field.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
/* @allxsmith/bestax-bulma — AI agents: see AGENTS.md in the package root, or https://bestax.io/llms.txt */
|
|
2
2
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
3
|
-
import React, { useId, useMemo } from 'react';
|
|
3
|
+
import React, { useId, useMemo, useRef, useState, useCallback } from 'react';
|
|
4
4
|
import { usePrefixedClassNames, classNames } from '../helpers/classNames.js';
|
|
5
5
|
import { withSubComponents } from '../helpers/withSubComponents.js';
|
|
6
6
|
import { useBulmaClasses } from '../helpers/useBulmaClasses.js';
|
|
7
|
-
import { useFieldLabelFor, FieldProvider, FieldLabelIdProvider, FieldLabelElementIdProvider, FieldLabelForProvider } from './FormContext.js';
|
|
7
|
+
import { useFieldLabelFor, FieldProvider, FieldLabelIdProvider, FieldLabelElementIdProvider, FieldLabelForProvider, FieldLabelForReportProvider } from './FormContext.js';
|
|
8
|
+
import { useClientLayoutEffect } from '../helpers/useClientLayoutEffect.js';
|
|
8
9
|
import { Control } from './Control.js';
|
|
9
10
|
|
|
10
11
|
/**
|
|
@@ -122,8 +123,9 @@ const FieldComponent = ({ horizontal, grouped, hasAddons, narrow, label, labelSi
|
|
|
122
123
|
const targetId = label && !userWiredLabel && !grouped && !hasAddons
|
|
123
124
|
? generatedId
|
|
124
125
|
: undefined;
|
|
125
|
-
// A group control (Radios, Checkboxes, Rate, DateRangeInput
|
|
126
|
-
// that `for`, so it points `aria-labelledby` at the label
|
|
126
|
+
// A group control (Radios, Checkboxes, Rate, DateRangeInput and its base)
|
|
127
|
+
// cannot take that `for`, so it points `aria-labelledby` at the label
|
|
128
|
+
// itself (#939).
|
|
127
129
|
// The label gets an id whenever the association is on, unless the caller
|
|
128
130
|
// gave it one.
|
|
129
131
|
const labelId = labelProps?.id ?? (targetId ? `${targetId}-label` : undefined);
|
|
@@ -140,13 +142,43 @@ const FieldComponent = ({ horizontal, grouped, hasAddons, narrow, label, labelSi
|
|
|
140
142
|
const labelForTarget = userWiredLabel ? labelProps.htmlFor : targetId;
|
|
141
143
|
const ownLabelFor = useMemo(() => ({ htmlFor: labelForTarget, id: labelId }), [labelForTarget, labelId]);
|
|
142
144
|
const labelFor = label ? ownLabelFor : inheritedLabelFor;
|
|
145
|
+
// Whether the label keeps its generated `for` (#1004). Content that takes
|
|
146
|
+
// the Field's id says so from a layout effect, and this Field's own layout
|
|
147
|
+
// effect runs after its content's in the same commit, so by then every
|
|
148
|
+
// report has landed. Until it runs, on the server and in the first render
|
|
149
|
+
// while hydrating, the label writes the `for` as it always has. From then
|
|
150
|
+
// on it keeps the `for` only while some content holds the id, and content
|
|
151
|
+
// that mounts or changes later reports when it does. Counted in a ref, and
|
|
152
|
+
// state is set only once settled, so content that takes the id renders
|
|
153
|
+
// the Field just once.
|
|
154
|
+
const takersRef = useRef(0);
|
|
155
|
+
const settledRef = useRef(false);
|
|
156
|
+
const [forTaken, setForTaken] = useState(true);
|
|
157
|
+
const settle = useCallback(() => {
|
|
158
|
+
if (settledRef.current)
|
|
159
|
+
setForTaken(takersRef.current > 0);
|
|
160
|
+
}, []);
|
|
161
|
+
const reportLabelFor = useCallback(() => {
|
|
162
|
+
takersRef.current += 1;
|
|
163
|
+
settle();
|
|
164
|
+
return () => {
|
|
165
|
+
takersRef.current -= 1;
|
|
166
|
+
settle();
|
|
167
|
+
};
|
|
168
|
+
}, [settle]);
|
|
169
|
+
useClientLayoutEffect(() => {
|
|
170
|
+
settledRef.current = true;
|
|
171
|
+
if (targetId)
|
|
172
|
+
settle();
|
|
173
|
+
}, [targetId, settle]);
|
|
174
|
+
const renderedTargetId = forTaken ? targetId : undefined;
|
|
143
175
|
let renderedLabel = null;
|
|
144
176
|
if (label) {
|
|
145
177
|
if (horizontal) {
|
|
146
|
-
renderedLabel = (jsx(FieldLabel, { size: effectiveLabelSize, children: jsx("label", { htmlFor:
|
|
178
|
+
renderedLabel = (jsx(FieldLabel, { size: effectiveLabelSize, children: jsx("label", { htmlFor: renderedTargetId, ...labelProps, id: labelId, className: classNames(labelClass, labelProps?.className), style: labelProps?.style, children: label }) }));
|
|
147
179
|
}
|
|
148
180
|
else {
|
|
149
|
-
renderedLabel = (jsx("label", { htmlFor:
|
|
181
|
+
renderedLabel = (jsx("label", { htmlFor: renderedTargetId, ...labelProps, id: labelId, className: classNames(labelClass, labelProps?.className), style: { display: 'block', ...(labelProps?.style || {}) }, children: label }));
|
|
150
182
|
}
|
|
151
183
|
}
|
|
152
184
|
// If horizontal, wrap children in FieldBody (unless the user already provided
|
|
@@ -169,7 +201,7 @@ const FieldComponent = ({ horizontal, grouped, hasAddons, narrow, label, labelSi
|
|
|
169
201
|
content = jsx(FieldBody, { children: children });
|
|
170
202
|
}
|
|
171
203
|
}
|
|
172
|
-
return (jsx(FieldProvider, { value: true, children: jsx(FieldLabelIdProvider, { value: targetId, children: jsx(FieldLabelElementIdProvider, { value: targetId ? labelId : undefined, children: jsx(FieldLabelForProvider, { value: labelFor, children: jsxs("div", { className: fieldClass, ...rest, children: [renderedLabel, content] }) }) }) }) }));
|
|
204
|
+
return (jsx(FieldProvider, { value: true, children: jsx(FieldLabelIdProvider, { value: targetId, children: jsx(FieldLabelElementIdProvider, { value: targetId ? labelId : undefined, children: jsx(FieldLabelForProvider, { value: labelFor, children: jsx(FieldLabelForReportProvider, { value: targetId ? reportLabelFor : undefined, children: jsxs("div", { className: fieldClass, ...rest, children: [renderedLabel, content] }) }) }) }) }) }));
|
|
173
205
|
};
|
|
174
206
|
FieldLabel.displayName = 'FieldLabel';
|
|
175
207
|
FieldBody.displayName = 'FieldBody';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Field.js","sources":["../../../src/form/Field.tsx"],"sourcesContent":["import React, { useId, useMemo } from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport { withSubComponents } from '../helpers/withSubComponents';\nimport {\n useBulmaClasses,\n BulmaClassesProps,\n validColors,\n} from '../helpers/useBulmaClasses';\nimport {\n FieldProvider,\n FieldLabelIdProvider,\n FieldLabelElementIdProvider,\n FieldLabelForProvider,\n useFieldLabelFor,\n} from './FormContext';\nimport { Control } from './Control';\n\n/**\n * Props for the Field component.\n */\nexport interface FieldProps\n extends\n React.HTMLAttributes<HTMLDivElement>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /** Renders the field as horizontal (label and control side by side). */\n horizontal?: boolean;\n /** Group controls in a row (optionally centered, right, or multiline). */\n grouped?: boolean | 'centered' | 'right' | 'multiline';\n /** Group controls as addons (optionally centered or right-aligned). */\n hasAddons?: boolean | 'centered' | 'right';\n /** Constrains the field to its content's width (used inside horizontal field bodies). */\n narrow?: boolean;\n /** Field label, rendered above the widget. Automatically names the one control the Field holds: a composed `InputBase`, `SelectBase`, `TextAreaBase`, `DateInputBase`, `TimeInputBase` or `DateTimeInputBase` (an `inline` picker has no input, so it takes nothing), or a bestax input that renders a single input of its own (`Input`, `Select`, `TextArea`, `Numberinput`, `Slider`, `DateInput`, `TimeInput`, `DateTimeInput`, `Autocomplete`, `Taginput`, `File`), adopts a generated id that the label's `htmlFor` points at, and a group (`Radios`, `Checkboxes`, `Rate`, `DateRangeInput`) points `aria-labelledby` at the label's own id unless you gave the group an `aria-label` or `aria-labelledby`. A range `Slider` takes the id on its low thumb and also starts each thumb's name with the label through `aria-labelledby`, unless its `ariaLabel` names that thumb or its own `aria-label` or `aria-labelledby` takes the label's place. An `Autocomplete` also names its open suggestion list after the label through `aria-labelledby`. Nothing else takes the label: `Checkbox`, `Radio` and `Switch` are named by their own children. Only the single inputs take the `htmlFor`, so with a group or any other content it matches nothing. Pass `labelProps={{ htmlFor }}` to wire your own `id`, or `labelProps={{ htmlFor: undefined }}` to opt out. Skipped for `grouped`/`hasAddons` fields (multiple controls), and a nested `Field` starts its own scope, so a horizontal Field whose body holds an inner `Field` names the control there only when you wire it. Two controls in one plain labeled Field would both adopt the id, so give each an `id` of its own. */\n label?: React.ReactNode;\n /** Size for the label. */\n labelSize?: 'small' | 'normal' | 'medium' | 'large';\n /** Props for the label element. An explicit `htmlFor` key — even set to `undefined` — takes over the association. While the association is on, the label renders with the `id` given here, or a generated one, and a group control, a range `Slider`'s thumbs and an `Autocomplete`'s suggestion list point `aria-labelledby` at it. A label you take over gets no generated id, and no group points at it on its own. With an `id` here, though, a range `Slider` or an `Autocomplete` whose `id` your `htmlFor` names still points its thumbs or its suggestion list at it, in a `grouped` or `hasAddons` Field too. To point a group in an inner `Field` at this label by hand, pass that `id` with `htmlFor: undefined`, or the label keeps a generated `htmlFor` that nothing takes. */\n labelProps?: React.LabelHTMLAttributes<HTMLLabelElement> & {\n [key: string]: unknown;\n };\n /** Text color for the field. */\n textColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Bulma color for the field. */\n color?: 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger';\n /** Background color for the field. */\n bgColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Additional CSS classes. */\n className?: string;\n /** Field content. */\n children?: React.ReactNode;\n}\n\n/**\n * Props for the FieldLabel component.\n */\nexport interface FieldLabelProps\n extends\n React.HTMLAttributes<HTMLDivElement>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /** Size for the field label. */\n size?: 'small' | 'normal' | 'medium' | 'large';\n /** Text color for the label. */\n textColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Bulma color for the label. */\n color?: 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger';\n /** Background color for the label. */\n bgColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Additional CSS classes. */\n className?: string;\n /** Field label content. */\n children?: React.ReactNode;\n}\n\n/**\n * Props for the FieldBody component.\n */\nexport interface FieldBodyProps\n extends\n React.HTMLAttributes<HTMLDivElement>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /** Text color for the field body. */\n textColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Bulma color for the field body. */\n color?: 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger';\n /** Background color for the field body. */\n bgColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Additional CSS classes. */\n className?: string;\n /** Field body content. */\n children?: React.ReactNode;\n}\n\n/**\n * FieldLabel component for rendering a Bulma field label. It renders the\n * label column of a horizontal `Field` (a `div` with the `field-label` class),\n * not a `<label>`, so text placed straight in it names nothing. Put a `<label>`\n * with the `label` class inside it and point its `htmlFor` at the control's\n * `id`, or give the horizontal `Field` a `label` prop, which renders this\n * column and its `<label>` for you. A `<label>` you put here names the\n * control through its `htmlFor` alone: a range `Slider`'s thumbs and an\n * `Autocomplete`'s suggestion list point `aria-labelledby` at a `Field`'s\n * label only when its `label` prop renders it and it names the control.\n * Where it would not name the control on its own, as in an inner `Field`,\n * pass `labelProps={{ htmlFor, id }}` with a matching `id` on the control.\n *\n * @function\n * @param {FieldLabelProps} props - Props for the FieldLabel component.\n * @returns {JSX.Element} The rendered field label.\n *\n * @example\n * <FieldLabel size=\"normal\">\n * <label className=\"label\" htmlFor=\"name\">Name</label>\n * </FieldLabel>\n */\nexport const FieldLabel: React.FC<FieldLabelProps> = ({\n size,\n textColor,\n bgColor,\n className,\n children,\n ...props\n}) => {\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n color: textColor,\n backgroundColor: bgColor,\n ...props,\n });\n\n const mainClass = usePrefixedClassNames('field-label', {\n [`is-${size}`]: !!size,\n });\n const fieldLabelClass = classNames(mainClass, bulmaHelperClasses, className);\n // Spread ...props and ...rest so custom props like data-testid are included\n return (\n <div className={fieldLabelClass} {...props} {...rest}>\n {children}\n </div>\n );\n};\n\n/**\n * FieldBody component for rendering Bulma field body.\n *\n * @function\n * @param {FieldBodyProps} props - Props for the FieldBody component.\n * @returns {JSX.Element} The rendered field body.\n *\n * @example\n * <FieldBody><input className=\"input\" /></FieldBody>\n */\nexport const FieldBody: React.FC<FieldBodyProps> = ({\n textColor,\n bgColor,\n className,\n children,\n ...props\n}) => {\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n color: textColor,\n backgroundColor: bgColor,\n ...props,\n });\n\n const mainClass = usePrefixedClassNames('field-body');\n const fieldBodyClass = classNames(mainClass, bulmaHelperClasses, className);\n // Spread ...props and ...rest so custom props like data-testid are included\n return (\n <div className={fieldBodyClass} {...props} {...rest}>\n {children}\n </div>\n );\n};\n\n/**\n * The `Field` component is a Bulma-styled form field container.\n *\n * @function\n * @param {FieldProps} props - Props for the Field component.\n * @returns {JSX.Element} The rendered field container.\n * @see {@link https://bulma.io/documentation/form/general/#field | Bulma Field documentation}\n *\n * @example\n * // Labelled field — the label auto-associates with the composed base\n * <Field label=\"Email\">\n * <Control>\n * <InputBase type=\"email\" />\n * </Control>\n * </Field>\n *\n * @example\n * // Horizontal field\n * <Field horizontal label=\"Name\">\n * <Control>\n * <InputBase />\n * </Control>\n * </Field>\n */\nconst FieldComponent: React.FC<FieldProps> = ({\n horizontal,\n grouped,\n hasAddons,\n narrow,\n label,\n labelSize,\n labelProps,\n textColor,\n color: _fieldColor,\n bgColor,\n className,\n children,\n ...props\n}) => {\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n color: textColor,\n backgroundColor: bgColor,\n ...props,\n });\n\n const mainClass = usePrefixedClassNames('field', {\n 'is-horizontal': horizontal,\n 'has-addons': !!hasAddons,\n 'has-addons-centered': hasAddons === 'centered',\n 'has-addons-right': hasAddons === 'right',\n 'is-narrow': narrow,\n 'is-grouped':\n grouped === true ||\n grouped === 'centered' ||\n grouped === 'right' ||\n grouped === 'multiline',\n 'is-grouped-centered': grouped === 'centered',\n 'is-grouped-right': grouped === 'right',\n 'is-grouped-multiline': grouped === 'multiline',\n });\n const fieldClass = classNames(mainClass, bulmaHelperClasses, className);\n\n // Default labelSize to 'normal' when horizontal for proper baseline alignment\n const effectiveLabelSize = labelSize ?? (horizontal ? 'normal' : undefined);\n\n const labelClass = usePrefixedClassNames('label');\n\n // Auto-associate the label with a single composed base control (#495): the\n // label points at a generated id shared via context, which a composed base\n // adopts when the user supplied no id of their own.\n // Presence semantics on htmlFor — even an explicit `htmlFor: undefined`\n // means the caller owns the association. Grouped/addons fields hold several\n // controls, so no single association is generated for them.\n const generatedId = useId();\n const userWiredLabel = !!labelProps && 'htmlFor' in labelProps;\n const targetId =\n label && !userWiredLabel && !grouped && !hasAddons\n ? generatedId\n : undefined;\n // A group control (Radios, Checkboxes, Rate, DateRangeInput) cannot take\n // that `for`, so it points `aria-labelledby` at the label itself (#939).\n // The label gets an id whenever the association is on, unless the caller\n // gave it one.\n const labelId =\n labelProps?.id ?? (targetId ? `${targetId}-label` : undefined);\n // What the rendered label's `for` points at, generated or the caller's, and\n // the id it renders with, so a control can tell when a label wired by hand\n // names it and point at that label. An unlabeled Field passes on its\n // parent's. Unlike `targetId`, a label wired by hand passes on its own in\n // `grouped`/`hasAddons` Fields too, on purpose: those only stop the Field\n // picking one control out of several, and the caller's `for` has picked\n // one, so a range Slider or Autocomplete it names points at that label in\n // a row as well. A group reads the label element id below instead, which\n // stays off for a label wired by hand, since no group takes its `for`.\n const inheritedLabelFor = useFieldLabelFor();\n const labelForTarget = userWiredLabel ? labelProps.htmlFor : targetId;\n const ownLabelFor = useMemo(\n () => ({ htmlFor: labelForTarget, id: labelId }),\n [labelForTarget, labelId]\n );\n const labelFor = label ? ownLabelFor : inheritedLabelFor;\n\n let renderedLabel = null;\n if (label) {\n if (horizontal) {\n renderedLabel = (\n <FieldLabel size={effectiveLabelSize}>\n <label\n htmlFor={targetId}\n {...labelProps}\n id={labelId}\n className={classNames(labelClass, labelProps?.className)}\n style={labelProps?.style}\n >\n {label}\n </label>\n </FieldLabel>\n );\n } else {\n renderedLabel = (\n <label\n htmlFor={targetId}\n {...labelProps}\n id={labelId}\n className={classNames(labelClass, labelProps?.className)}\n style={{ display: 'block', ...(labelProps?.style || {}) }}\n >\n {label}\n </label>\n );\n }\n }\n\n // If horizontal, wrap children in FieldBody (unless the user already provided\n // a FieldBody — either as the single child, or as one element among siblings\n // like <Field.Label/> + <Field.Body/>).\n let content = children;\n if (horizontal) {\n const isFieldBody = (c: React.ReactNode): boolean =>\n React.isValidElement(c) &&\n // @ts-expect-error displayName isn't on the public type\n (c.type === FieldBody || c.type?.displayName === 'FieldBody');\n const isFieldLabel = (c: React.ReactNode): boolean =>\n React.isValidElement(c) &&\n // @ts-expect-error displayName isn't on the public type\n (c.type === FieldLabel || c.type?.displayName === 'FieldLabel');\n const childArray = React.Children.toArray(children);\n const userProvidedStructure = childArray.some(\n c => isFieldBody(c) || isFieldLabel(c)\n );\n if (userProvidedStructure) {\n content = children;\n } else {\n content = <FieldBody>{children}</FieldBody>;\n }\n }\n\n return (\n <FieldProvider value={true}>\n <FieldLabelIdProvider value={targetId}>\n <FieldLabelElementIdProvider value={targetId ? labelId : undefined}>\n <FieldLabelForProvider value={labelFor}>\n <div className={fieldClass} {...rest}>\n {renderedLabel}\n {content}\n </div>\n </FieldLabelForProvider>\n </FieldLabelElementIdProvider>\n </FieldLabelIdProvider>\n </FieldProvider>\n );\n};\n\nFieldLabel.displayName = 'FieldLabel';\nFieldBody.displayName = 'FieldBody';\n\nexport const Field = withSubComponents(\n FieldComponent,\n {\n Label: FieldLabel,\n Body: FieldBody,\n Control,\n },\n 'Field'\n);\n\nexport default Field;\n"],"names":["_jsx","_jsxs"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Field.js","sources":["../../../src/form/Field.tsx"],"sourcesContent":["import React, { useCallback, useId, useMemo, useRef, useState } from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport { withSubComponents } from '../helpers/withSubComponents';\nimport {\n useBulmaClasses,\n BulmaClassesProps,\n validColors,\n} from '../helpers/useBulmaClasses';\nimport {\n FieldProvider,\n FieldLabelIdProvider,\n FieldLabelElementIdProvider,\n FieldLabelForProvider,\n FieldLabelForReportProvider,\n useFieldLabelFor,\n} from './FormContext';\nimport { useClientLayoutEffect } from '../helpers/useClientLayoutEffect';\nimport { Control } from './Control';\n\n/**\n * Props for the Field component.\n */\nexport interface FieldProps\n extends\n React.HTMLAttributes<HTMLDivElement>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /** Renders the field as horizontal (label and control side by side). */\n horizontal?: boolean;\n /** Group controls in a row (optionally centered, right, or multiline). */\n grouped?: boolean | 'centered' | 'right' | 'multiline';\n /** Group controls as addons (optionally centered or right-aligned). */\n hasAddons?: boolean | 'centered' | 'right';\n /** Constrains the field to its content's width (used inside horizontal field bodies). */\n narrow?: boolean;\n /** Field label, rendered above the widget. Automatically names the one control the Field holds: a composed `InputBase`, `SelectBase`, `TextAreaBase`, `DateInputBase`, `TimeInputBase` or `DateTimeInputBase` (an `inline` picker has no input, so it takes nothing), or a bestax input that renders a single input of its own (`Input`, `Select`, `TextArea`, `Numberinput`, `Slider`, `DateInput`, `TimeInput`, `DateTimeInput`, `Autocomplete`, `Taginput`, `File`), adopts a generated id that the label's `htmlFor` points at, and a group (`Radios`, `Checkboxes`, `Rate`, `DateRangeInput`, or a composed `DateRangeInputBase`, `inline` or not) points `aria-labelledby` at the label's own id unless you gave the group an `aria-label` or `aria-labelledby`. A range `Slider` takes the id on its low thumb and also starts each thumb's name with the label through `aria-labelledby`, unless its `ariaLabel` names that thumb or its own `aria-label` or `aria-labelledby` takes the label's place. An `Autocomplete` also names its open suggestion list after the label through `aria-labelledby`. Nothing else takes the label: `Checkbox`, `Radio` and `Switch` are named by their own children. Only the single inputs take the `htmlFor`, so once the Field's content has mounted the label keeps it only while one of them holds the id, and drops it over anything else: a group, a `Checkbox`, `Radio` or `Switch`, an `inline` picker, an inner `Field`, an input with an `id` of its own, markup of your own, or nothing at all. A server render, and the first render while hydrating, still write the `htmlFor`, which keeps hydration matching, and an input that mounts later puts it back. Pass `labelProps={{ htmlFor }}` to wire your own `id`, a `for` the label always keeps, or `labelProps={{ htmlFor: undefined }}` to opt out. Skipped for `grouped`/`hasAddons` fields (multiple controls), and a nested `Field` starts its own scope, so a horizontal Field whose body holds an inner `Field` names the control there only when you wire it. Two controls in one plain labeled Field would both adopt the id, so give each an `id` of its own. */\n label?: React.ReactNode;\n /** Size for the label. */\n labelSize?: 'small' | 'normal' | 'medium' | 'large';\n /** Props for the label element. An explicit `htmlFor` key — even set to `undefined` — takes over the association. While the association is on, the label renders with the `id` given here, or a generated one, and a group control, a range `Slider`'s thumbs and an `Autocomplete`'s suggestion list point `aria-labelledby` at it. A label you take over gets no generated id, and no group points at it on its own. With an `id` here, though, a range `Slider` or an `Autocomplete` whose `id` your `htmlFor` names still points its thumbs or its suggestion list at it, in a `grouped` or `hasAddons` Field too. To point a group in an inner `Field` at this label by hand, pass that `id`. Nothing in the inner `Field` takes the generated `htmlFor`, so the label drops it after mounting, and adding `htmlFor: undefined` keeps it out of server-rendered markup too. */\n labelProps?: React.LabelHTMLAttributes<HTMLLabelElement> & {\n [key: string]: unknown;\n };\n /** Text color for the field. */\n textColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Bulma color for the field. */\n color?: 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger';\n /** Background color for the field. */\n bgColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Additional CSS classes. */\n className?: string;\n /** Field content. */\n children?: React.ReactNode;\n}\n\n/**\n * Props for the FieldLabel component.\n */\nexport interface FieldLabelProps\n extends\n React.HTMLAttributes<HTMLDivElement>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /** Size for the field label. */\n size?: 'small' | 'normal' | 'medium' | 'large';\n /** Text color for the label. */\n textColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Bulma color for the label. */\n color?: 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger';\n /** Background color for the label. */\n bgColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Additional CSS classes. */\n className?: string;\n /** Field label content. */\n children?: React.ReactNode;\n}\n\n/**\n * Props for the FieldBody component.\n */\nexport interface FieldBodyProps\n extends\n React.HTMLAttributes<HTMLDivElement>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /** Text color for the field body. */\n textColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Bulma color for the field body. */\n color?: 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger';\n /** Background color for the field body. */\n bgColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Additional CSS classes. */\n className?: string;\n /** Field body content. */\n children?: React.ReactNode;\n}\n\n/**\n * FieldLabel component for rendering a Bulma field label. It renders the\n * label column of a horizontal `Field` (a `div` with the `field-label` class),\n * not a `<label>`, so text placed straight in it names nothing. Put a `<label>`\n * with the `label` class inside it and point its `htmlFor` at the control's\n * `id`, or give the horizontal `Field` a `label` prop, which renders this\n * column and its `<label>` for you. A `<label>` you put here names the\n * control through its `htmlFor` alone: a range `Slider`'s thumbs and an\n * `Autocomplete`'s suggestion list point `aria-labelledby` at a `Field`'s\n * label only when its `label` prop renders it and it names the control.\n * Where it would not name the control on its own, as in an inner `Field`,\n * pass `labelProps={{ htmlFor, id }}` with a matching `id` on the control.\n *\n * @function\n * @param {FieldLabelProps} props - Props for the FieldLabel component.\n * @returns {JSX.Element} The rendered field label.\n *\n * @example\n * <FieldLabel size=\"normal\">\n * <label className=\"label\" htmlFor=\"name\">Name</label>\n * </FieldLabel>\n */\nexport const FieldLabel: React.FC<FieldLabelProps> = ({\n size,\n textColor,\n bgColor,\n className,\n children,\n ...props\n}) => {\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n color: textColor,\n backgroundColor: bgColor,\n ...props,\n });\n\n const mainClass = usePrefixedClassNames('field-label', {\n [`is-${size}`]: !!size,\n });\n const fieldLabelClass = classNames(mainClass, bulmaHelperClasses, className);\n // Spread ...props and ...rest so custom props like data-testid are included\n return (\n <div className={fieldLabelClass} {...props} {...rest}>\n {children}\n </div>\n );\n};\n\n/**\n * FieldBody component for rendering Bulma field body.\n *\n * @function\n * @param {FieldBodyProps} props - Props for the FieldBody component.\n * @returns {JSX.Element} The rendered field body.\n *\n * @example\n * <FieldBody><input className=\"input\" /></FieldBody>\n */\nexport const FieldBody: React.FC<FieldBodyProps> = ({\n textColor,\n bgColor,\n className,\n children,\n ...props\n}) => {\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n color: textColor,\n backgroundColor: bgColor,\n ...props,\n });\n\n const mainClass = usePrefixedClassNames('field-body');\n const fieldBodyClass = classNames(mainClass, bulmaHelperClasses, className);\n // Spread ...props and ...rest so custom props like data-testid are included\n return (\n <div className={fieldBodyClass} {...props} {...rest}>\n {children}\n </div>\n );\n};\n\n/**\n * The `Field` component is a Bulma-styled form field container.\n *\n * @function\n * @param {FieldProps} props - Props for the Field component.\n * @returns {JSX.Element} The rendered field container.\n * @see {@link https://bulma.io/documentation/form/general/#field | Bulma Field documentation}\n *\n * @example\n * // Labelled field — the label auto-associates with the composed base\n * <Field label=\"Email\">\n * <Control>\n * <InputBase type=\"email\" />\n * </Control>\n * </Field>\n *\n * @example\n * // Horizontal field\n * <Field horizontal label=\"Name\">\n * <Control>\n * <InputBase />\n * </Control>\n * </Field>\n */\nconst FieldComponent: React.FC<FieldProps> = ({\n horizontal,\n grouped,\n hasAddons,\n narrow,\n label,\n labelSize,\n labelProps,\n textColor,\n color: _fieldColor,\n bgColor,\n className,\n children,\n ...props\n}) => {\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n color: textColor,\n backgroundColor: bgColor,\n ...props,\n });\n\n const mainClass = usePrefixedClassNames('field', {\n 'is-horizontal': horizontal,\n 'has-addons': !!hasAddons,\n 'has-addons-centered': hasAddons === 'centered',\n 'has-addons-right': hasAddons === 'right',\n 'is-narrow': narrow,\n 'is-grouped':\n grouped === true ||\n grouped === 'centered' ||\n grouped === 'right' ||\n grouped === 'multiline',\n 'is-grouped-centered': grouped === 'centered',\n 'is-grouped-right': grouped === 'right',\n 'is-grouped-multiline': grouped === 'multiline',\n });\n const fieldClass = classNames(mainClass, bulmaHelperClasses, className);\n\n // Default labelSize to 'normal' when horizontal for proper baseline alignment\n const effectiveLabelSize = labelSize ?? (horizontal ? 'normal' : undefined);\n\n const labelClass = usePrefixedClassNames('label');\n\n // Auto-associate the label with a single composed base control (#495): the\n // label points at a generated id shared via context, which a composed base\n // adopts when the user supplied no id of their own.\n // Presence semantics on htmlFor — even an explicit `htmlFor: undefined`\n // means the caller owns the association. Grouped/addons fields hold several\n // controls, so no single association is generated for them.\n const generatedId = useId();\n const userWiredLabel = !!labelProps && 'htmlFor' in labelProps;\n const targetId =\n label && !userWiredLabel && !grouped && !hasAddons\n ? generatedId\n : undefined;\n // A group control (Radios, Checkboxes, Rate, DateRangeInput and its base)\n // cannot take that `for`, so it points `aria-labelledby` at the label\n // itself (#939).\n // The label gets an id whenever the association is on, unless the caller\n // gave it one.\n const labelId =\n labelProps?.id ?? (targetId ? `${targetId}-label` : undefined);\n // What the rendered label's `for` points at, generated or the caller's, and\n // the id it renders with, so a control can tell when a label wired by hand\n // names it and point at that label. An unlabeled Field passes on its\n // parent's. Unlike `targetId`, a label wired by hand passes on its own in\n // `grouped`/`hasAddons` Fields too, on purpose: those only stop the Field\n // picking one control out of several, and the caller's `for` has picked\n // one, so a range Slider or Autocomplete it names points at that label in\n // a row as well. A group reads the label element id below instead, which\n // stays off for a label wired by hand, since no group takes its `for`.\n const inheritedLabelFor = useFieldLabelFor();\n const labelForTarget = userWiredLabel ? labelProps.htmlFor : targetId;\n const ownLabelFor = useMemo(\n () => ({ htmlFor: labelForTarget, id: labelId }),\n [labelForTarget, labelId]\n );\n const labelFor = label ? ownLabelFor : inheritedLabelFor;\n\n // Whether the label keeps its generated `for` (#1004). Content that takes\n // the Field's id says so from a layout effect, and this Field's own layout\n // effect runs after its content's in the same commit, so by then every\n // report has landed. Until it runs, on the server and in the first render\n // while hydrating, the label writes the `for` as it always has. From then\n // on it keeps the `for` only while some content holds the id, and content\n // that mounts or changes later reports when it does. Counted in a ref, and\n // state is set only once settled, so content that takes the id renders\n // the Field just once.\n const takersRef = useRef(0);\n const settledRef = useRef(false);\n const [forTaken, setForTaken] = useState(true);\n const settle = useCallback(() => {\n if (settledRef.current) setForTaken(takersRef.current > 0);\n }, []);\n const reportLabelFor = useCallback(() => {\n takersRef.current += 1;\n settle();\n return () => {\n takersRef.current -= 1;\n settle();\n };\n }, [settle]);\n useClientLayoutEffect(() => {\n settledRef.current = true;\n if (targetId) settle();\n }, [targetId, settle]);\n const renderedTargetId = forTaken ? targetId : undefined;\n\n let renderedLabel = null;\n if (label) {\n if (horizontal) {\n renderedLabel = (\n <FieldLabel size={effectiveLabelSize}>\n <label\n htmlFor={renderedTargetId}\n {...labelProps}\n id={labelId}\n className={classNames(labelClass, labelProps?.className)}\n style={labelProps?.style}\n >\n {label}\n </label>\n </FieldLabel>\n );\n } else {\n renderedLabel = (\n <label\n htmlFor={renderedTargetId}\n {...labelProps}\n id={labelId}\n className={classNames(labelClass, labelProps?.className)}\n style={{ display: 'block', ...(labelProps?.style || {}) }}\n >\n {label}\n </label>\n );\n }\n }\n\n // If horizontal, wrap children in FieldBody (unless the user already provided\n // a FieldBody — either as the single child, or as one element among siblings\n // like <Field.Label/> + <Field.Body/>).\n let content = children;\n if (horizontal) {\n const isFieldBody = (c: React.ReactNode): boolean =>\n React.isValidElement(c) &&\n // @ts-expect-error displayName isn't on the public type\n (c.type === FieldBody || c.type?.displayName === 'FieldBody');\n const isFieldLabel = (c: React.ReactNode): boolean =>\n React.isValidElement(c) &&\n // @ts-expect-error displayName isn't on the public type\n (c.type === FieldLabel || c.type?.displayName === 'FieldLabel');\n const childArray = React.Children.toArray(children);\n const userProvidedStructure = childArray.some(\n c => isFieldBody(c) || isFieldLabel(c)\n );\n if (userProvidedStructure) {\n content = children;\n } else {\n content = <FieldBody>{children}</FieldBody>;\n }\n }\n\n return (\n <FieldProvider value={true}>\n <FieldLabelIdProvider value={targetId}>\n <FieldLabelElementIdProvider value={targetId ? labelId : undefined}>\n <FieldLabelForProvider value={labelFor}>\n <FieldLabelForReportProvider\n value={targetId ? reportLabelFor : undefined}\n >\n <div className={fieldClass} {...rest}>\n {renderedLabel}\n {content}\n </div>\n </FieldLabelForReportProvider>\n </FieldLabelForProvider>\n </FieldLabelElementIdProvider>\n </FieldLabelIdProvider>\n </FieldProvider>\n );\n};\n\nFieldLabel.displayName = 'FieldLabel';\nFieldBody.displayName = 'FieldBody';\n\nexport const Field = withSubComponents(\n FieldComponent,\n {\n Label: FieldLabel,\n Body: FieldBody,\n Control,\n },\n 'Field'\n);\n\nexport default Field;\n"],"names":["_jsx","_jsxs"],"mappings":"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"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/* @allxsmith/bestax-bulma — AI agents: see AGENTS.md in the package root, or https://bestax.io/llms.txt */
|
|
2
2
|
import { createContext, useContext } from 'react';
|
|
3
3
|
import { warnOnce } from '../helpers/devWarnings.js';
|
|
4
|
+
import { useClientLayoutEffect } from '../helpers/useClientLayoutEffect.js';
|
|
4
5
|
|
|
5
6
|
const FieldContext = createContext(false);
|
|
6
7
|
const ControlContext = createContext(false);
|
|
@@ -143,10 +144,14 @@ const FieldLabelIdContext = createContext(undefined);
|
|
|
143
144
|
* The id a labeled Field wants its single composed control to adopt (#495).
|
|
144
145
|
* `undefined` outside a Field, in unlabeled/grouped/addons Fields, or when the
|
|
145
146
|
* user took over the association with an explicit `labelProps.htmlFor`.
|
|
146
|
-
* Consumed by the single-control bases
|
|
147
|
-
* and the date and time picker bases
|
|
148
|
-
* `useAutoLabelId`, by the convenience
|
|
149
|
-
* own (#939).
|
|
147
|
+
* Consumed through `useFieldLabelTarget` by the single-control bases
|
|
148
|
+
* (InputBase, SelectBase, TextAreaBase, and the date and time picker bases
|
|
149
|
+
* unless inline, #968) and, through `useAutoLabelId`, by the convenience
|
|
150
|
+
* inputs that render an input of their own (#939). Read it only through
|
|
151
|
+
* those, which report what they take: a control that read it directly would
|
|
152
|
+
* report nothing and lose its label (#1004), and
|
|
153
|
+
* `__tests__/field-label-readers.test.ts` fails on one. Internal; not part of
|
|
154
|
+
* the public API.
|
|
150
155
|
*/
|
|
151
156
|
const useFieldLabelId = () => useContext(FieldLabelIdContext);
|
|
152
157
|
/** Provider for the Field label-target id — used internally by Field. */
|
|
@@ -154,8 +159,9 @@ const FieldLabelIdProvider = FieldLabelIdContext.Provider;
|
|
|
154
159
|
const FieldLabelElementIdContext = createContext(undefined);
|
|
155
160
|
/**
|
|
156
161
|
* The id of a labeled Field's own `<label>`, for a group control (Radios,
|
|
157
|
-
* Checkboxes, Rate, DateRangeInput) to point
|
|
158
|
-
* the label's `htmlFor`
|
|
162
|
+
* Checkboxes, Rate, DateRangeInput and DateRangeInputBase) to point
|
|
163
|
+
* `aria-labelledby` at, since a group cannot take the label's `htmlFor`
|
|
164
|
+
* (#939, #1005). Set under the same conditions as
|
|
159
165
|
* {@link useFieldLabelId}. Consumed through `useAutoLabelledBy`.
|
|
160
166
|
* Internal; not part of the public API.
|
|
161
167
|
*/
|
|
@@ -171,15 +177,54 @@ const FieldLabelForContext = createContext({});
|
|
|
171
177
|
* the outer label names it, and point at that label by its id, as a range
|
|
172
178
|
* Slider's thumbs (#981) and Autocomplete's suggestion list (#998) do. The
|
|
173
179
|
* `htmlFor` is only ever compared with a control's own id, never adopted, so
|
|
174
|
-
* it hands out no id for a control.
|
|
175
|
-
*
|
|
176
|
-
*
|
|
177
|
-
* `
|
|
180
|
+
* it hands out no id for a control. It keeps the generated id after the
|
|
181
|
+
* label drops a `for` nothing took (#1004), which no control's id matches
|
|
182
|
+
* then, so the value does not change under the content that reported it.
|
|
183
|
+
* The `id` is set only while that label renders with it. Unlike
|
|
184
|
+
* {@link useFieldLabelId}, it is set in a `grouped` or `hasAddons` Field
|
|
185
|
+
* too, so a label wired by hand names the control its `for` picks in those
|
|
186
|
+
* rows as well. Consumed through `useAutoLabelId`.
|
|
178
187
|
* Internal; not part of the public API.
|
|
179
188
|
*/
|
|
180
189
|
const useFieldLabelFor = () => useContext(FieldLabelForContext);
|
|
181
190
|
/** Provider for the Field label's `htmlFor` target and id, used internally by Field. */
|
|
182
191
|
const FieldLabelForProvider = FieldLabelForContext.Provider;
|
|
192
|
+
const FieldLabelForReportContext = createContext(undefined);
|
|
193
|
+
/**
|
|
194
|
+
* Tells the nearest labeled Field that this content took its generated id
|
|
195
|
+
* while `takesFor` is true (#1004). Once the Field's content has mounted, its
|
|
196
|
+
* label keeps the generated `for` only while something has said so, so the
|
|
197
|
+
* label renders none over a group, a `Checkbox`, `Radio` or `Switch`, an
|
|
198
|
+
* inner `Field`, an input with an `id` of its own, markup of your own, or
|
|
199
|
+
* nothing at all. Anything that puts the id from {@link useFieldLabelId} on
|
|
200
|
+
* an element has to say so, or the label drops the `for` that names it, and
|
|
201
|
+
* content that takes no id has nothing to do. Set under the same conditions
|
|
202
|
+
* as {@link useFieldLabelId}, so a label wired by hand and a `grouped` or
|
|
203
|
+
* `hasAddons` Field hear nothing. It reports from a layout effect, which a
|
|
204
|
+
* server never runs and a hydrating client runs only after its first render,
|
|
205
|
+
* so that render writes the `for` the way the server did.
|
|
206
|
+
* Internal; not part of the public API.
|
|
207
|
+
*/
|
|
208
|
+
const useReportFieldLabelFor = (takesFor) => {
|
|
209
|
+
const report = useContext(FieldLabelForReportContext);
|
|
210
|
+
useClientLayoutEffect(() => (takesFor ? report?.() : undefined), [report, takesFor]);
|
|
211
|
+
};
|
|
212
|
+
/** Provider for the labeled Field's report function, used internally by Field. */
|
|
213
|
+
const FieldLabelForReportProvider = FieldLabelForReportContext.Provider;
|
|
214
|
+
/**
|
|
215
|
+
* The id a control with one input of its own renders with: the caller's
|
|
216
|
+
* `id` when one arrived, otherwise the one a labeled Field offers (#495),
|
|
217
|
+
* unless it has no input to put it on (`hasInput: false`, as in an `inline`
|
|
218
|
+
* picker). It also tells that Field when it took the Field's id, through
|
|
219
|
+
* {@link useReportFieldLabelFor}, so the label keeps its `for` (#1004). Used
|
|
220
|
+
* by the single-control bases. Internal; not part of the public API.
|
|
221
|
+
*/
|
|
222
|
+
const useFieldLabelTarget = (id, hasInput = true) => {
|
|
223
|
+
const fieldLabelId = useFieldLabelId();
|
|
224
|
+
const target = id ?? (hasInput ? fieldLabelId : undefined);
|
|
225
|
+
useReportFieldLabelFor(fieldLabelId !== undefined && target === fieldLabelId);
|
|
226
|
+
return target;
|
|
227
|
+
};
|
|
183
228
|
const RadiosContext = createContext(undefined);
|
|
184
229
|
const CheckboxesContext = createContext(undefined);
|
|
185
230
|
/**
|
|
@@ -197,5 +242,5 @@ const RadiosProvider = RadiosContext.Provider;
|
|
|
197
242
|
/** Provider for the Checkboxes group context — used internally by Checkboxes. */
|
|
198
243
|
const CheckboxesProvider = CheckboxesContext.Provider;
|
|
199
244
|
|
|
200
|
-
export { CheckboxesProvider, ControlProvider, FieldLabelElementIdProvider, FieldLabelForProvider, FieldLabelIdProvider, FieldProvider, RadiosProvider, rendersOwnControl, rendersOwnField, useCheckboxesGroup, useFieldLabelElementId, useFieldLabelFor, useFieldLabelId, useInsideControl, useInsideField, useRadiosGroup };
|
|
245
|
+
export { CheckboxesProvider, ControlProvider, FieldLabelElementIdProvider, FieldLabelForProvider, FieldLabelForReportProvider, FieldLabelIdProvider, FieldProvider, RadiosProvider, rendersOwnControl, rendersOwnField, useCheckboxesGroup, useFieldLabelElementId, useFieldLabelFor, useFieldLabelId, useFieldLabelTarget, useInsideControl, useInsideField, useRadiosGroup, useReportFieldLabelFor };
|
|
201
246
|
//# sourceMappingURL=FormContext.js.map
|