{"version":3,"file":"TimePicker.cjs","names":[],"sources":["../../../src/components/TimePicker/TimePicker.tsx"],"sourcesContent":["/**\n * @tempest-limits file-lines, props-count, function-lines — minuteStep and\n * use12Hours change both the list of options and how a typed value parses, so the\n * body holds parsing, formatting and the option list together; the remaining props\n * are the shared field contract.\n */\nimport { useId, useMemo } from \"react\";\nimport { cn } from \"@/utils/cn\";\nimport styles from \"./TimePicker.module.css\";\n\nexport interface TimePickerProps {\n    /** Selected time as a 24h `\"HH:MM\"` string (e.g. `\"14:30\"`). May be `\"\"` for none. */\n    value: string;\n    /** Fired with the new 24h `\"HH:MM\"` string whenever a cell is picked. */\n    onChange: (value: string) => void;\n    /** Granularity of the minute column. Defaults to `5`. */\n    minuteStep?: number;\n    /** When true, show a 1–12 hour column plus an AM/PM column (still emits 24h). */\n    use12Hours?: boolean;\n    label?: string;\n    helperText?: string;\n    disabled?: boolean;\n    className?: string;\n}\n\ntype Period = \"AM\" | \"PM\";\n\ninterface ParsedTime {\n    hour24: number | null;\n    minute: number | null;\n}\n\nfunction pad2(value: number): string {\n    return value.toString().padStart(2, \"0\");\n}\n\n/** Parse a 24h `\"HH:MM\"` string into hour/minute numbers, or nulls when empty/invalid. */\nfunction parseValue(value: string): ParsedTime {\n    const match = /^(\\d{1,2}):(\\d{1,2})$/.exec(value.trim());\n    if (!match) return { hour24: null, minute: null };\n    const hour24 = Number(match[1]);\n    const minute = Number(match[2]);\n    if (hour24 < 0 || hour24 > 23 || minute < 0 || minute > 59) {\n        return { hour24: null, minute: null };\n    }\n    return { hour24, minute };\n}\n\n/** Convert a 24h hour into its 12h display hour (1–12). */\nfunction to12Hour(hour24: number): number {\n    const mod = hour24 % 12;\n    return mod === 0 ? 12 : mod;\n}\n\n/** Convert a 12h display hour + period into a 24h hour (0–23). */\nfunction to24Hour(hour12: number, period: Period): number {\n    const base = hour12 % 12;\n    return period === \"PM\" ? base + 12 : base;\n}\n\n/**\n * TimePicker — inline, dependency-free time picker with Material \"spinner column\" styling.\n *\n * Renders scrollable columns of selectable cells (hours, minutes, and AM/PM when\n * `use12Hours`). Always emits a 24h `\"HH:MM\"` string via `onChange`, regardless of\n * whether the 12h display is enabled.\n */\nexport function TimePicker({\n    value,\n    onChange,\n    minuteStep = 5,\n    use12Hours = false,\n    label,\n    helperText,\n    disabled,\n    className,\n}: TimePickerProps) {\n    const id = useId();\n    const { hour24, minute } = useMemo(() => parseValue(value), [value]);\n\n    const period: Period = hour24 !== null && hour24 >= 12 ? \"PM\" : \"AM\";\n\n    const hourCells = useMemo<number[]>(() => {\n        if (use12Hours) {\n            return Array.from({ length: 12 }, (_, index) => index + 1);\n        }\n        return Array.from({ length: 24 }, (_, index) => index);\n    }, [use12Hours]);\n\n    const minuteCells = useMemo<number[]>(() => {\n        const step = minuteStep > 0 ? minuteStep : 1;\n        const cells: number[] = [];\n        for (let current = 0; current < 60; current += step) {\n            cells.push(current);\n        }\n        return cells;\n    }, [minuteStep]);\n\n    const selectedHourDisplay = hour24 === null ? null : use12Hours ? to12Hour(hour24) : hour24;\n\n    const emit = (nextHour24: number, nextMinute: number): void => {\n        onChange(`${pad2(nextHour24)}:${pad2(nextMinute)}`);\n    };\n\n    const handleHour = (displayHour: number): void => {\n        if (disabled) return;\n        const nextMinute = minute ?? 0;\n        const nextHour24 = use12Hours ? to24Hour(displayHour, period) : displayHour;\n        emit(nextHour24, nextMinute);\n    };\n\n    const handleMinute = (nextMinute: number): void => {\n        if (disabled) return;\n        const baseHour24 = hour24 ?? (use12Hours ? to24Hour(12, \"AM\") : 0);\n        emit(baseHour24, nextMinute);\n    };\n\n    const handlePeriod = (nextPeriod: Period): void => {\n        if (disabled) return;\n        const displayHour = selectedHourDisplay ?? 12;\n        const nextMinute = minute ?? 0;\n        emit(to24Hour(displayHour, nextPeriod), nextMinute);\n    };\n\n    return (\n        <div className={cn(styles.wrapper, disabled && styles.disabled, className)}>\n            {label && (\n                <span id={`${id}-label`} className={styles.label}>\n                    {label}\n                </span>\n            )}\n            <div className={styles.columns}>\n                <ul role=\"listbox\" aria-label=\"Horas\" className={styles.column}>\n                    {hourCells.map((cell) => {\n                        const active = cell === selectedHourDisplay;\n                        return (\n                            <li key={cell} className={styles.cellWrapper}>\n                                <button\n                                    type=\"button\"\n                                    role=\"option\"\n                                    aria-selected={active}\n                                    disabled={disabled}\n                                    className={cn(styles.cell, active && styles.active)}\n                                    onClick={() => handleHour(cell)}\n                                >\n                                    {use12Hours ? cell : pad2(cell)}\n                                </button>\n                            </li>\n                        );\n                    })}\n                </ul>\n                <ul role=\"listbox\" aria-label=\"Minutos\" className={styles.column}>\n                    {minuteCells.map((cell) => {\n                        const active = cell === minute;\n                        return (\n                            <li key={cell} className={styles.cellWrapper}>\n                                <button\n                                    type=\"button\"\n                                    role=\"option\"\n                                    aria-selected={active}\n                                    disabled={disabled}\n                                    className={cn(styles.cell, active && styles.active)}\n                                    onClick={() => handleMinute(cell)}\n                                >\n                                    {pad2(cell)}\n                                </button>\n                            </li>\n                        );\n                    })}\n                </ul>\n                {use12Hours && (\n                    <ul role=\"listbox\" aria-label=\"Período\" className={styles.column}>\n                        {([\"AM\", \"PM\"] as Period[]).map((cell) => {\n                            const active = selectedHourDisplay !== null && cell === period;\n                            return (\n                                <li key={cell} className={styles.cellWrapper}>\n                                    <button\n                                        type=\"button\"\n                                        role=\"option\"\n                                        aria-selected={active}\n                                        disabled={disabled}\n                                        className={cn(styles.cell, active && styles.active)}\n                                        onClick={() => handlePeriod(cell)}\n                                    >\n                                        {cell}\n                                    </button>\n                                </li>\n                            );\n                        })}\n                    </ul>\n                )}\n            </div>\n            {helperText && <span className={styles.helper}>{helperText}</span>}\n        </div>\n    );\n}\n"],"mappings":"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"}