@brycks/core-front 0.3.4 → 0.3.6
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/components/data/List/List.cjs +1 -1
- package/dist/components/data/List/List.cjs.map +1 -1
- package/dist/components/data/List/List.js +1 -1
- package/dist/components/data/List/List.js.map +1 -1
- package/dist/components/data/Table/Table.cjs +1 -1
- package/dist/components/data/Table/Table.cjs.map +1 -1
- package/dist/components/data/Table/Table.js +141 -124
- package/dist/components/data/Table/Table.js.map +1 -1
- package/dist/components/data/TreeView/TreeView.cjs +1 -1
- package/dist/components/data/TreeView/TreeView.cjs.map +1 -1
- package/dist/components/data/TreeView/TreeView.js +1 -1
- package/dist/components/data/TreeView/TreeView.js.map +1 -1
- package/dist/components/feedback/Alert/Alert.cjs +1 -1
- package/dist/components/feedback/Alert/Alert.cjs.map +1 -1
- package/dist/components/feedback/Alert/Alert.js +20 -19
- package/dist/components/feedback/Alert/Alert.js.map +1 -1
- package/dist/components/feedback/Drawer/Drawer.cjs +2 -2
- package/dist/components/feedback/Drawer/Drawer.cjs.map +1 -1
- package/dist/components/feedback/Drawer/Drawer.js +58 -57
- package/dist/components/feedback/Drawer/Drawer.js.map +1 -1
- package/dist/components/feedback/Modal/Modal.cjs +1 -1
- package/dist/components/feedback/Modal/Modal.cjs.map +1 -1
- package/dist/components/feedback/Modal/Modal.js +63 -61
- package/dist/components/feedback/Modal/Modal.js.map +1 -1
- package/dist/components/feedback/Popover/Popover.cjs +2 -2
- package/dist/components/feedback/Popover/Popover.cjs.map +1 -1
- package/dist/components/feedback/Popover/Popover.js +88 -79
- package/dist/components/feedback/Popover/Popover.js.map +1 -1
- package/dist/components/feedback/Toast/Toast.cjs +2 -2
- package/dist/components/feedback/Toast/Toast.cjs.map +1 -1
- package/dist/components/feedback/Toast/Toast.js +102 -93
- package/dist/components/feedback/Toast/Toast.js.map +1 -1
- package/dist/components/form/Combobox/Combobox.cjs +2 -2
- package/dist/components/form/Combobox/Combobox.cjs.map +1 -1
- package/dist/components/form/Combobox/Combobox.js +139 -139
- package/dist/components/form/Combobox/Combobox.js.map +1 -1
- package/dist/components/form/DateInput/DateInput.cjs +1 -1
- package/dist/components/form/DateInput/DateInput.cjs.map +1 -1
- package/dist/components/form/DateInput/DateInput.js +2 -2
- package/dist/components/form/DateInput/DateInput.js.map +1 -1
- package/dist/components/form/DateRangePicker/DateRangePicker.cjs +1 -1
- package/dist/components/form/DateRangePicker/DateRangePicker.cjs.map +1 -1
- package/dist/components/form/DateRangePicker/DateRangePicker.js +34 -34
- package/dist/components/form/DateRangePicker/DateRangePicker.js.map +1 -1
- package/dist/components/form/DropZone/DropZone.cjs +1 -1
- package/dist/components/form/DropZone/DropZone.cjs.map +1 -1
- package/dist/components/form/DropZone/DropZone.js +10 -10
- package/dist/components/form/DropZone/DropZone.js.map +1 -1
- package/dist/components/form/FileInput/FileInput.cjs +1 -1
- package/dist/components/form/FileInput/FileInput.cjs.map +1 -1
- package/dist/components/form/FileInput/FileInput.js +1 -1
- package/dist/components/form/FileInput/FileInput.js.map +1 -1
- package/dist/components/form/FormCard/FormCard.cjs +1 -1
- package/dist/components/form/FormCard/FormCard.cjs.map +1 -1
- package/dist/components/form/FormCard/FormCard.js +9 -9
- package/dist/components/form/FormCard/FormCard.js.map +1 -1
- package/dist/components/form/FormField/FormField.cjs +1 -1
- package/dist/components/form/FormField/FormField.cjs.map +1 -1
- package/dist/components/form/FormField/FormField.js +67 -55
- package/dist/components/form/FormField/FormField.js.map +1 -1
- package/dist/components/form/MultiSelect/MultiSelect.cjs +1 -1
- package/dist/components/form/MultiSelect/MultiSelect.cjs.map +1 -1
- package/dist/components/form/MultiSelect/MultiSelect.js +2 -3
- package/dist/components/form/MultiSelect/MultiSelect.js.map +1 -1
- package/dist/components/form/Radio/Radio.cjs +1 -1
- package/dist/components/form/Radio/Radio.cjs.map +1 -1
- package/dist/components/form/Radio/Radio.js +20 -20
- package/dist/components/form/Radio/Radio.js.map +1 -1
- package/dist/components/form/TagInput/TagInput.cjs +1 -1
- package/dist/components/form/TagInput/TagInput.cjs.map +1 -1
- package/dist/components/form/TagInput/TagInput.js +104 -102
- package/dist/components/form/TagInput/TagInput.js.map +1 -1
- package/dist/components/form/TimePicker/TimePicker.cjs +1 -1
- package/dist/components/form/TimePicker/TimePicker.cjs.map +1 -1
- package/dist/components/form/TimePicker/TimePicker.js +29 -30
- package/dist/components/form/TimePicker/TimePicker.js.map +1 -1
- package/dist/components/layout/Collapse/Collapse.cjs.map +1 -1
- package/dist/components/layout/Collapse/Collapse.js.map +1 -1
- package/dist/components/media/Image/Image.cjs +1 -1
- package/dist/components/media/Image/Image.cjs.map +1 -1
- package/dist/components/media/Image/Image.js +9 -9
- package/dist/components/media/Image/Image.js.map +1 -1
- package/dist/components/media/ImageThumbnail/ImageThumbnail.cjs +1 -1
- package/dist/components/media/ImageThumbnail/ImageThumbnail.cjs.map +1 -1
- package/dist/components/media/ImageThumbnail/ImageThumbnail.js +6 -6
- package/dist/components/media/ImageThumbnail/ImageThumbnail.js.map +1 -1
- package/dist/components/navigation/Accordion/Accordion.cjs +1 -1
- package/dist/components/navigation/Accordion/Accordion.cjs.map +1 -1
- package/dist/components/navigation/Accordion/Accordion.js +0 -1
- package/dist/components/navigation/Accordion/Accordion.js.map +1 -1
- package/dist/components/navigation/Menu/Menu.cjs +1 -1
- package/dist/components/navigation/Menu/Menu.cjs.map +1 -1
- package/dist/components/navigation/Menu/Menu.js +87 -86
- package/dist/components/navigation/Menu/Menu.js.map +1 -1
- package/dist/components/navigation/Pagination/Pagination.cjs +1 -1
- package/dist/components/navigation/Pagination/Pagination.cjs.map +1 -1
- package/dist/components/navigation/Pagination/Pagination.js +107 -99
- package/dist/components/navigation/Pagination/Pagination.js.map +1 -1
- package/dist/components/utility/Avatar/Avatar.cjs +1 -1
- package/dist/components/utility/Avatar/Avatar.cjs.map +1 -1
- package/dist/components/utility/Avatar/Avatar.js +10 -10
- package/dist/components/utility/Avatar/Avatar.js.map +1 -1
- package/dist/components/utility/Logo/Logo.cjs +1 -1
- package/dist/components/utility/Logo/Logo.cjs.map +1 -1
- package/dist/components/utility/Logo/Logo.js +10 -10
- package/dist/components/utility/Logo/Logo.js.map +1 -1
- package/dist/design-system/themes/ThemeProvider.cjs +1 -1
- package/dist/design-system/themes/ThemeProvider.cjs.map +1 -1
- package/dist/design-system/themes/ThemeProvider.js +46 -46
- package/dist/design-system/themes/ThemeProvider.js.map +1 -1
- package/dist/design-system/tokens/zIndex.cjs +1 -1
- package/dist/design-system/tokens/zIndex.cjs.map +1 -1
- package/dist/design-system/tokens/zIndex.js +2 -0
- package/dist/design-system/tokens/zIndex.js.map +1 -1
- package/dist/feedback.d.ts +8 -0
- package/dist/form.d.ts +10 -0
- package/dist/index.d.ts +29 -0
- package/dist/navigation.d.ts +19 -0
- package/dist/styles.css +1 -1
- package/dist/tokens.d.ts +2 -0
- package/package.json +2 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DateRangePicker.js","sources":["../../../../src/components/form/DateRangePicker/DateRangePicker.tsx"],"sourcesContent":["/**\n * DateRangePicker Component\n *\n * A date range selection component with calendar UI.\n * Supports preset ranges and custom date selection.\n *\n * @module components/form/DateRangePicker\n */\n\nimport {\n forwardRef,\n useState,\n useCallback,\n useRef,\n useEffect,\n type CSSProperties,\n type KeyboardEvent,\n} from 'react'\nimport { createPortal } from 'react-dom'\nimport { cx } from '../../../utils/styles'\nimport { spacing, fontSizes, durations, easings } from '../../../design-system'\nimport { componentHeights, componentPaddingX } from '../../../design-system/primitives'\n\nexport type DateRangePickerSize = 'sm' | 'md' | 'lg'\n\nexport interface DateRange {\n start: Date | null\n end: Date | null\n}\n\nexport interface DateRangePreset {\n label: string\n getValue: () => DateRange\n}\n\nexport interface DateRangePickerProps {\n /** Current date range value */\n value?: DateRange\n /** Default date range value (uncontrolled) */\n defaultValue?: DateRange\n /** Callback when date range changes */\n onChange?: (value: DateRange) => void\n /** Component size */\n size?: DateRangePickerSize\n /** Minimum selectable date */\n minDate?: Date\n /** Maximum selectable date */\n maxDate?: Date\n /** Placeholder text */\n placeholder?: string\n /** Whether the input is disabled */\n disabled?: boolean\n /** Whether the input is invalid */\n isInvalid?: boolean\n /** Whether to allow clearing */\n clearable?: boolean\n /** Preset date ranges */\n presets?: DateRangePreset[]\n /** Date format display */\n dateFormat?: (date: Date) => string\n /** Label for accessibility */\n 'aria-label'?: string\n /** Custom class name */\n className?: string\n /** Test ID */\n testId?: string\n}\n\nconst sizeConfig: Record<DateRangePickerSize, { height: number; fontSize: number; padding: number }> = {\n sm: { height: componentHeights.sm, fontSize: fontSizes.base - 1, padding: componentPaddingX.sm },\n md: { height: componentHeights.md, fontSize: fontSizes.base, padding: componentPaddingX.md },\n lg: { height: componentHeights.lg, fontSize: fontSizes.md, padding: componentPaddingX.lg },\n}\n\nconst DAYS = ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa']\nconst MONTHS = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']\n\nconst defaultDateFormat = (date: Date): string => {\n return `${date.getMonth() + 1}/${date.getDate()}/${date.getFullYear()}`\n}\n\nfunction CalendarIcon() {\n return (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden=\"true\">\n <rect x=\"2\" y=\"3\" width=\"12\" height=\"11\" rx=\"2\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n <path d=\"M2 6h12\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n <path d=\"M5 1v3M11 1v3\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n </svg>\n )\n}\n\nfunction ChevronIcon({ direction }: { direction: 'left' | 'right' }) {\n return (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden=\"true\">\n <path\n d={direction === 'left' ? 'M10 4l-4 4 4 4' : 'M6 4l4 4-4 4'}\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n )\n}\n\nfunction ClearIcon() {\n return (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M4 4l6 6M10 4l-6 6\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n </svg>\n )\n}\n\nconst getDaysInMonth = (year: number, month: number): number => {\n return new Date(year, month + 1, 0).getDate()\n}\n\nconst getFirstDayOfMonth = (year: number, month: number): number => {\n return new Date(year, month, 1).getDay()\n}\n\nconst isSameDay = (date1: Date | null, date2: Date | null): boolean => {\n if (!date1 || !date2) return false\n return (\n date1.getFullYear() === date2.getFullYear() &&\n date1.getMonth() === date2.getMonth() &&\n date1.getDate() === date2.getDate()\n )\n}\n\nconst isInRange = (date: Date, start: Date | null, end: Date | null): boolean => {\n if (!start || !end) return false\n const time = date.getTime()\n return time > start.getTime() && time < end.getTime()\n}\n\nconst isDateDisabled = (date: Date, minDate?: Date, maxDate?: Date): boolean => {\n if (minDate && date < minDate) return true\n if (maxDate && date > maxDate) return true\n return false\n}\n\nexport const DateRangePicker = forwardRef<HTMLDivElement, DateRangePickerProps>(function DateRangePicker(\n {\n value: controlledValue,\n defaultValue = { start: null, end: null },\n onChange,\n size = 'md',\n minDate,\n maxDate,\n placeholder = 'Select date range',\n disabled = false,\n isInvalid = false,\n clearable = true,\n presets,\n dateFormat = defaultDateFormat,\n 'aria-label': ariaLabel = 'Select date range',\n className,\n testId,\n },\n ref\n) {\n const [internalValue, setInternalValue] = useState<DateRange>(defaultValue)\n const [isOpen, setIsOpen] = useState(false)\n const [isFocused, setIsFocused] = useState(false)\n const [viewDate, setViewDate] = useState(() => {\n const initial = controlledValue?.start || defaultValue.start || new Date()\n return { year: initial.getFullYear(), month: initial.getMonth() }\n })\n const [selectingEnd, setSelectingEnd] = useState(false)\n const [hoverDate, setHoverDate] = useState<Date | null>(null)\n\n const containerRef = useRef<HTMLDivElement>(null)\n\n const value = controlledValue !== undefined ? controlledValue : internalValue\n const config = sizeConfig[size]\n\n const updateValue = useCallback(\n (newValue: DateRange) => {\n if (controlledValue === undefined) {\n setInternalValue(newValue)\n }\n onChange?.(newValue)\n },\n [controlledValue, onChange]\n )\n\n const handleDateClick = useCallback(\n (date: Date) => {\n if (isDateDisabled(date, minDate, maxDate)) return\n\n if (!selectingEnd || !value.start) {\n // Start new selection\n updateValue({ start: date, end: null })\n setSelectingEnd(true)\n } else {\n // Complete selection\n if (date < value.start) {\n updateValue({ start: date, end: value.start })\n } else {\n updateValue({ start: value.start, end: date })\n }\n setSelectingEnd(false)\n setIsOpen(false)\n }\n },\n [selectingEnd, value.start, minDate, maxDate, updateValue]\n )\n\n const handlePresetClick = useCallback(\n (preset: DateRangePreset) => {\n const newValue = preset.getValue()\n updateValue(newValue)\n setIsOpen(false)\n setSelectingEnd(false)\n },\n [updateValue]\n )\n\n const handleClear = useCallback(\n (e: React.MouseEvent) => {\n e.stopPropagation()\n updateValue({ start: null, end: null })\n setSelectingEnd(false)\n },\n [updateValue]\n )\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent<HTMLDivElement>) => {\n if (e.key === 'Escape') {\n setIsOpen(false)\n setSelectingEnd(false)\n }\n },\n []\n )\n\n // Close on outside click\n useEffect(() => {\n if (!isOpen) return\n\n const handleClick = (e: MouseEvent) => {\n if (!containerRef.current?.contains(e.target as Node)) {\n setIsOpen(false)\n setSelectingEnd(false)\n }\n }\n\n document.addEventListener('mousedown', handleClick)\n return () => document.removeEventListener('mousedown', handleClick)\n }, [isOpen])\n\n // Calculate dropdown position\n const [dropdownPosition, setDropdownPosition] = useState({ top: 0, left: 0 })\n\n useEffect(() => {\n if (!isOpen || !containerRef.current) return\n\n const updatePosition = () => {\n const rect = containerRef.current!.getBoundingClientRect()\n setDropdownPosition({\n top: rect.bottom + window.scrollY + spacing[1],\n left: rect.left + window.scrollX,\n })\n }\n\n updatePosition()\n window.addEventListener('resize', updatePosition)\n window.addEventListener('scroll', updatePosition, true)\n\n return () => {\n window.removeEventListener('resize', updatePosition)\n window.removeEventListener('scroll', updatePosition, true)\n }\n }, [isOpen])\n\n const goToPrevMonth = useCallback(() => {\n setViewDate((prev) => {\n if (prev.month === 0) {\n return { year: prev.year - 1, month: 11 }\n }\n return { ...prev, month: prev.month - 1 }\n })\n }, [])\n\n const goToNextMonth = useCallback(() => {\n setViewDate((prev) => {\n if (prev.month === 11) {\n return { year: prev.year + 1, month: 0 }\n }\n return { ...prev, month: prev.month + 1 }\n })\n }, [])\n\n // Generate calendar days\n const renderCalendar = (monthOffset: number = 0) => {\n let { year, month } = viewDate\n month += monthOffset\n if (month > 11) {\n month = 0\n year++\n }\n\n const daysInMonth = getDaysInMonth(year, month)\n const firstDay = getFirstDayOfMonth(year, month)\n const days: (Date | null)[] = []\n\n // Empty cells for days before the first day\n for (let i = 0; i < firstDay; i++) {\n days.push(null)\n }\n\n // Days of the month\n for (let i = 1; i <= daysInMonth; i++) {\n days.push(new Date(year, month, i))\n }\n\n const effectiveEnd = selectingEnd && hoverDate && value.start && !value.end ? hoverDate : value.end\n\n return (\n <div style={{ flex: 1 }}>\n <div style={calendarHeaderStyle}>\n {monthOffset === 0 && (\n <button\n type=\"button\"\n aria-label=\"Previous month\"\n style={navButtonStyle}\n onClick={goToPrevMonth}\n >\n <ChevronIcon direction=\"left\" />\n </button>\n )}\n <span style={{ fontWeight: 600 }}>\n {MONTHS[month]} {year}\n </span>\n {monthOffset === 1 && (\n <button\n type=\"button\"\n aria-label=\"Next month\"\n style={navButtonStyle}\n onClick={goToNextMonth}\n >\n <ChevronIcon direction=\"right\" />\n </button>\n )}\n </div>\n <div style={daysHeaderStyle}>\n {DAYS.map((day) => (\n <div key={day} style={dayHeaderStyle}>\n {day}\n </div>\n ))}\n </div>\n <div style={daysGridStyle}>\n {days.map((date, index) => {\n if (!date) {\n return <div key={`empty-${index}`} style={dayStyle(false, false, false, false)} />\n }\n\n const isStart = isSameDay(date, value.start)\n const isEnd = isSameDay(date, effectiveEnd)\n const isRange = isInRange(date, value.start, effectiveEnd)\n const isDisabled = isDateDisabled(date, minDate, maxDate)\n\n return (\n <button\n key={date.toISOString()}\n type=\"button\"\n disabled={isDisabled}\n style={dayStyle(isStart || isEnd, isRange, isDisabled, isSameDay(date, new Date()))}\n onClick={() => handleDateClick(date)}\n onMouseEnter={() => selectingEnd && setHoverDate(date)}\n onMouseLeave={() => setHoverDate(null)}\n >\n {date.getDate()}\n </button>\n )\n })}\n </div>\n </div>\n )\n }\n\n const displayValue = value.start && value.end\n ? `${dateFormat(value.start)} - ${dateFormat(value.end)}`\n : value.start\n ? `${dateFormat(value.start)} - ...`\n : ''\n\n const containerStyle: CSSProperties = {\n position: 'relative',\n display: 'inline-flex',\n width: '100%',\n }\n\n const inputWrapperStyle: CSSProperties = {\n position: 'relative',\n display: 'flex',\n alignItems: 'center',\n width: '100%',\n height: config.height,\n backgroundColor: disabled ? 'var(--brycks-background-muted)' : 'var(--brycks-background-default)',\n border: `1px solid ${\n isInvalid\n ? 'var(--brycks-error-default)'\n : isFocused\n ? 'var(--brycks-primary-default)'\n : 'var(--brycks-border-default)'\n }`,\n borderRadius: 'var(--brycks-radius-md)',\n transition: `all ${durations.fast}ms ${easings.easeOut}`,\n cursor: disabled ? 'not-allowed' : 'pointer',\n boxShadow: isFocused ? 'var(--brycks-focus-ring)' : undefined,\n padding: `0 ${config.padding}px`,\n paddingRight: clearable && (value.start || value.end) ? spacing[10] : config.padding,\n }\n\n const iconStyle: CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n marginRight: spacing[2],\n color: 'var(--brycks-foreground-muted)',\n }\n\n const textStyle: CSSProperties = {\n flex: 1,\n fontSize: config.fontSize,\n color: displayValue ? 'var(--brycks-foreground-default)' : 'var(--brycks-foreground-muted)',\n }\n\n const clearButtonStyle: CSSProperties = {\n position: 'absolute',\n right: config.padding,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: spacing[5],\n height: spacing[5],\n color: 'var(--brycks-foreground-muted)',\n cursor: 'pointer',\n borderRadius: 'var(--brycks-radius-sm)',\n transition: `all ${durations.fast}ms ${easings.easeOut}`,\n }\n\n const dropdownStyle: CSSProperties = {\n position: 'absolute',\n top: dropdownPosition.top,\n left: dropdownPosition.left,\n backgroundColor: 'var(--brycks-background-elevated)',\n border: '1px solid var(--brycks-border-default)',\n borderRadius: 'var(--brycks-radius-lg)',\n boxShadow: 'var(--brycks-shadow-lg)',\n zIndex: 'var(--brycks-z-dropdown)' as unknown as number,\n padding: spacing[3],\n display: 'flex',\n gap: spacing[4],\n }\n\n const calendarHeaderStyle: CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n marginBottom: spacing[2],\n minHeight: spacing[8],\n fontSize: fontSizes.base,\n }\n\n const navButtonStyle: CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: spacing[7],\n height: spacing[7],\n backgroundColor: 'transparent',\n border: 'none',\n borderRadius: 'var(--brycks-radius-md)',\n cursor: 'pointer',\n color: 'var(--brycks-foreground-default)',\n transition: `all ${durations.fast}ms ${easings.easeOut}`,\n }\n\n const daysHeaderStyle: CSSProperties = {\n display: 'grid',\n gridTemplateColumns: 'repeat(7, 1fr)',\n gap: spacing[0.5],\n marginBottom: spacing[1],\n }\n\n const dayHeaderStyle: CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n height: spacing[7],\n fontSize: fontSizes.xs,\n fontWeight: 600,\n color: 'var(--brycks-foreground-muted)',\n }\n\n const daysGridStyle: CSSProperties = {\n display: 'grid',\n gridTemplateColumns: 'repeat(7, 1fr)',\n gap: spacing[0.5],\n }\n\n const dayStyle = (isSelected: boolean, isRange: boolean, isDisabled: boolean, isToday: boolean): CSSProperties => ({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: spacing[8],\n height: spacing[8],\n fontSize: fontSizes.sm,\n fontWeight: isSelected ? 600 : 400,\n color: isDisabled\n ? 'var(--brycks-foreground-disabled)'\n : isSelected\n ? 'white'\n : 'var(--brycks-foreground-default)',\n backgroundColor: isSelected\n ? 'var(--brycks-primary-default)'\n : isRange\n ? 'var(--brycks-primary-50)'\n : 'transparent',\n border: isToday && !isSelected ? '1px solid var(--brycks-border-strong)' : 'none',\n borderRadius: 'var(--brycks-radius-md)',\n cursor: isDisabled ? 'not-allowed' : 'pointer',\n opacity: isDisabled ? 0.5 : 1,\n transition: `all ${durations.fast}ms ${easings.easeOut}`,\n })\n\n const presetsStyle: CSSProperties = {\n display: 'flex',\n flexDirection: 'column',\n gap: spacing[1],\n borderLeft: '1px solid var(--brycks-border-default)',\n paddingLeft: spacing[3],\n minWidth: 140,\n }\n\n const presetButtonStyle: CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n padding: `${spacing[2]}px ${spacing[3]}px`,\n fontSize: fontSizes.sm,\n color: 'var(--brycks-foreground-default)',\n backgroundColor: 'transparent',\n border: 'none',\n borderRadius: 'var(--brycks-radius-md)',\n cursor: 'pointer',\n textAlign: 'left',\n transition: `all ${durations.fast}ms ${easings.easeOut}`,\n }\n\n return (\n <div\n ref={(node) => {\n (containerRef as React.MutableRefObject<HTMLDivElement | null>).current = node\n if (typeof ref === 'function') ref(node)\n else if (ref) ref.current = node\n }}\n className={cx('brycks-daterangepicker', `brycks-daterangepicker--${size}`, className)}\n style={containerStyle}\n data-testid={testId}\n onKeyDown={handleKeyDown}\n >\n <div\n role=\"button\"\n tabIndex={disabled ? -1 : 0}\n aria-label={ariaLabel}\n aria-expanded={isOpen}\n aria-haspopup=\"dialog\"\n aria-invalid={isInvalid}\n style={inputWrapperStyle}\n onClick={() => !disabled && setIsOpen(true)}\n onFocus={() => setIsFocused(true)}\n onBlur={() => setIsFocused(false)}\n >\n <span style={iconStyle}>\n <CalendarIcon />\n </span>\n <span style={textStyle}>{displayValue || placeholder}</span>\n {clearable && (value.start || value.end) && !disabled && (\n <button\n type=\"button\"\n aria-label=\"Clear date range\"\n style={clearButtonStyle}\n onClick={handleClear}\n onMouseEnter={(e) => {\n e.currentTarget.style.backgroundColor = 'var(--brycks-background-muted)'\n e.currentTarget.style.color = 'var(--brycks-foreground-default)'\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = 'transparent'\n e.currentTarget.style.color = 'var(--brycks-foreground-muted)'\n }}\n >\n <ClearIcon />\n </button>\n )}\n </div>\n\n {isOpen &&\n createPortal(\n <div role=\"dialog\" aria-label=\"Date range picker\" style={dropdownStyle}>\n {renderCalendar(0)}\n {renderCalendar(1)}\n {presets && presets.length > 0 && (\n <div style={presetsStyle}>\n <div style={{ fontSize: fontSizes.xs, fontWeight: 600, color: 'var(--brycks-foreground-muted)', marginBottom: spacing[1] }}>\n Presets\n </div>\n {presets.map((preset, index) => (\n <button\n key={index}\n type=\"button\"\n style={presetButtonStyle}\n onClick={() => handlePresetClick(preset)}\n onMouseEnter={(e) => {\n e.currentTarget.style.backgroundColor = 'var(--brycks-background-muted)'\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = 'transparent'\n }}\n >\n {preset.label}\n </button>\n ))}\n </div>\n )}\n </div>,\n document.body\n )}\n </div>\n )\n})\n\nDateRangePicker.displayName = 'DateRangePicker'\n"],"names":["sizeConfig","componentHeights","fontSizes","componentPaddingX","DAYS","MONTHS","defaultDateFormat","date","CalendarIcon","jsxs","jsx","ChevronIcon","direction","ClearIcon","getDaysInMonth","year","month","getFirstDayOfMonth","isSameDay","date1","date2","isInRange","start","end","time","isDateDisabled","minDate","maxDate","DateRangePicker","forwardRef","controlledValue","defaultValue","onChange","size","placeholder","disabled","isInvalid","clearable","presets","dateFormat","ariaLabel","className","testId","ref","internalValue","setInternalValue","useState","isOpen","setIsOpen","isFocused","setIsFocused","viewDate","setViewDate","initial","selectingEnd","setSelectingEnd","hoverDate","setHoverDate","containerRef","useRef","value","config","updateValue","useCallback","newValue","handleDateClick","handlePresetClick","preset","handleClear","handleKeyDown","useEffect","handleClick","e","dropdownPosition","setDropdownPosition","updatePosition","rect","spacing","goToPrevMonth","prev","goToNextMonth","renderCalendar","monthOffset","daysInMonth","firstDay","days","i","effectiveEnd","calendarHeaderStyle","navButtonStyle","daysHeaderStyle","day","dayHeaderStyle","daysGridStyle","index","dayStyle","isStart","isEnd","isRange","isDisabled","displayValue","containerStyle","inputWrapperStyle","durations","easings","iconStyle","textStyle","clearButtonStyle","dropdownStyle","isSelected","isToday","presetsStyle","presetButtonStyle","node","cx","createPortal"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"DateRangePicker.js","sources":["../../../../src/components/form/DateRangePicker/DateRangePicker.tsx"],"sourcesContent":["/**\n * DateRangePicker Component\n *\n * A date range selection component with calendar UI.\n * Supports preset ranges and custom date selection.\n *\n * @module components/form/DateRangePicker\n */\n\nimport {\n forwardRef,\n useState,\n useCallback,\n useRef,\n useEffect,\n type CSSProperties,\n type KeyboardEvent,\n} from 'react'\nimport { createPortal } from 'react-dom'\nimport { cx } from '../../../utils/styles'\nimport { spacing, fontSizes, durations, easings } from '../../../design-system'\nimport { componentHeights, componentPaddingX } from '../../../design-system/primitives'\n\nexport type DateRangePickerSize = 'sm' | 'md' | 'lg'\n\nexport interface DateRange {\n start: Date | null\n end: Date | null\n}\n\nexport interface DateRangePreset {\n label: string\n getValue: () => DateRange\n}\n\nexport interface DateRangePickerProps {\n /** Current date range value */\n value?: DateRange\n /** Default date range value (uncontrolled) */\n defaultValue?: DateRange\n /** Callback when date range changes */\n onChange?: (value: DateRange) => void\n /** Component size */\n size?: DateRangePickerSize\n /** Minimum selectable date */\n minDate?: Date\n /** Maximum selectable date */\n maxDate?: Date\n /** Placeholder text */\n placeholder?: string\n /** Whether the input is disabled */\n disabled?: boolean\n /** Whether the input is invalid */\n isInvalid?: boolean\n /** Whether to allow clearing */\n clearable?: boolean\n /** Preset date ranges */\n presets?: DateRangePreset[]\n /** Date format display */\n dateFormat?: (date: Date) => string\n /** Label for accessibility */\n 'aria-label'?: string\n /** Custom class name */\n className?: string\n /** Test ID */\n testId?: string\n}\n\nconst sizeConfig: Record<DateRangePickerSize, { height: number; fontSize: number; padding: number }> = {\n sm: { height: componentHeights.sm, fontSize: fontSizes.base - 1, padding: componentPaddingX.sm },\n md: { height: componentHeights.md, fontSize: fontSizes.base, padding: componentPaddingX.md },\n lg: { height: componentHeights.lg, fontSize: fontSizes.md, padding: componentPaddingX.lg },\n}\n\nconst DAYS = ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa']\nconst MONTHS = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']\n\nconst defaultDateFormat = (date: Date): string => {\n return `${date.getMonth() + 1}/${date.getDate()}/${date.getFullYear()}`\n}\n\nfunction CalendarIcon() {\n return (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden=\"true\">\n <rect x=\"2\" y=\"3\" width=\"12\" height=\"11\" rx=\"2\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n <path d=\"M2 6h12\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n <path d=\"M5 1v3M11 1v3\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n </svg>\n )\n}\n\nfunction ChevronIcon({ direction }: { direction: 'left' | 'right' }) {\n return (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden=\"true\">\n <path\n d={direction === 'left' ? 'M10 4l-4 4 4 4' : 'M6 4l4 4-4 4'}\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n )\n}\n\nfunction ClearIcon() {\n return (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M4 4l6 6M10 4l-6 6\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n </svg>\n )\n}\n\nconst getDaysInMonth = (year: number, month: number): number => {\n return new Date(year, month + 1, 0).getDate()\n}\n\nconst getFirstDayOfMonth = (year: number, month: number): number => {\n return new Date(year, month, 1).getDay()\n}\n\nconst isSameDay = (date1: Date | null, date2: Date | null): boolean => {\n if (!date1 || !date2) return false\n return (\n date1.getFullYear() === date2.getFullYear() &&\n date1.getMonth() === date2.getMonth() &&\n date1.getDate() === date2.getDate()\n )\n}\n\nconst isInRange = (date: Date, start: Date | null, end: Date | null): boolean => {\n if (!start || !end) return false\n const time = date.getTime()\n return time > start.getTime() && time < end.getTime()\n}\n\nconst isDateDisabled = (date: Date, minDate?: Date, maxDate?: Date): boolean => {\n if (minDate && date < minDate) return true\n if (maxDate && date > maxDate) return true\n return false\n}\n\nexport const DateRangePicker = forwardRef<HTMLDivElement, DateRangePickerProps>(function DateRangePicker(\n {\n value: controlledValue,\n defaultValue = { start: null, end: null },\n onChange,\n size = 'md',\n minDate,\n maxDate,\n placeholder = 'Select date range',\n disabled = false,\n isInvalid = false,\n clearable = true,\n presets,\n dateFormat = defaultDateFormat,\n 'aria-label': ariaLabel = 'Select date range',\n className,\n testId,\n },\n ref\n) {\n const [internalValue, setInternalValue] = useState<DateRange>(defaultValue)\n const [isOpen, setIsOpen] = useState(false)\n const [isFocused, setIsFocused] = useState(false)\n const [viewDate, setViewDate] = useState(() => {\n const initial = controlledValue?.start || defaultValue.start || new Date()\n return { year: initial.getFullYear(), month: initial.getMonth() }\n })\n const [selectingEnd, setSelectingEnd] = useState(false)\n const [hoverDate, setHoverDate] = useState<Date | null>(null)\n\n const containerRef = useRef<HTMLDivElement>(null)\n\n const value = controlledValue !== undefined ? controlledValue : internalValue\n const config = sizeConfig[size]\n\n const updateValue = useCallback(\n (newValue: DateRange) => {\n if (controlledValue === undefined) {\n setInternalValue(newValue)\n }\n onChange?.(newValue)\n },\n [controlledValue, onChange]\n )\n\n const handleDateClick = useCallback(\n (date: Date) => {\n if (isDateDisabled(date, minDate, maxDate)) return\n\n if (!selectingEnd || !value.start) {\n // Start new selection\n updateValue({ start: date, end: null })\n setSelectingEnd(true)\n } else {\n // Complete selection\n if (date < value.start) {\n updateValue({ start: date, end: value.start })\n } else {\n updateValue({ start: value.start, end: date })\n }\n setSelectingEnd(false)\n setIsOpen(false)\n }\n },\n [selectingEnd, value.start, minDate, maxDate, updateValue]\n )\n\n const handlePresetClick = useCallback(\n (preset: DateRangePreset) => {\n const newValue = preset.getValue()\n updateValue(newValue)\n setIsOpen(false)\n setSelectingEnd(false)\n },\n [updateValue]\n )\n\n const handleClear = useCallback(\n (e: React.MouseEvent) => {\n e.stopPropagation()\n updateValue({ start: null, end: null })\n setSelectingEnd(false)\n },\n [updateValue]\n )\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent<HTMLDivElement>) => {\n if (e.key === 'Escape') {\n setIsOpen(false)\n setSelectingEnd(false)\n }\n },\n []\n )\n\n // Close on outside click\n useEffect(() => {\n if (!isOpen) return\n\n const handleClick = (e: MouseEvent) => {\n if (!containerRef.current?.contains(e.target as Node)) {\n setIsOpen(false)\n setSelectingEnd(false)\n }\n }\n\n document.addEventListener('mousedown', handleClick)\n return () => document.removeEventListener('mousedown', handleClick)\n }, [isOpen])\n\n // Calculate dropdown position\n const [dropdownPosition, setDropdownPosition] = useState({ top: 0, left: 0 })\n\n useEffect(() => {\n if (!isOpen || !containerRef.current) return\n\n const updatePosition = () => {\n const rect = containerRef.current!.getBoundingClientRect()\n setDropdownPosition({\n top: rect.bottom + window.scrollY + spacing[1],\n left: rect.left + window.scrollX,\n })\n }\n\n updatePosition()\n window.addEventListener('resize', updatePosition)\n window.addEventListener('scroll', updatePosition, true)\n\n return () => {\n window.removeEventListener('resize', updatePosition)\n window.removeEventListener('scroll', updatePosition, true)\n }\n }, [isOpen])\n\n const goToPrevMonth = useCallback(() => {\n setViewDate((prev) => {\n if (prev.month === 0) {\n return { year: prev.year - 1, month: 11 }\n }\n return { ...prev, month: prev.month - 1 }\n })\n }, [])\n\n const goToNextMonth = useCallback(() => {\n setViewDate((prev) => {\n if (prev.month === 11) {\n return { year: prev.year + 1, month: 0 }\n }\n return { ...prev, month: prev.month + 1 }\n })\n }, [])\n\n // Generate calendar days\n const renderCalendar = (monthOffset: number = 0) => {\n let { year, month } = viewDate\n month += monthOffset\n if (month > 11) {\n month = 0\n year++\n }\n\n const daysInMonth = getDaysInMonth(year, month)\n const firstDay = getFirstDayOfMonth(year, month)\n const days: (Date | null)[] = []\n\n // Empty cells for days before the first day\n for (let i = 0; i < firstDay; i++) {\n days.push(null)\n }\n\n // Days of the month\n for (let i = 1; i <= daysInMonth; i++) {\n days.push(new Date(year, month, i))\n }\n\n const effectiveEnd = selectingEnd && hoverDate && value.start && !value.end ? hoverDate : value.end\n\n return (\n <div style={{ flex: 1 }}>\n <div style={calendarHeaderStyle}>\n {monthOffset === 0 && (\n <button\n type=\"button\"\n aria-label=\"Previous month\"\n style={navButtonStyle}\n onClick={goToPrevMonth}\n >\n <ChevronIcon direction=\"left\" />\n </button>\n )}\n <span style={{ fontWeight: 600 }}>\n {MONTHS[month]} {year}\n </span>\n {monthOffset === 1 && (\n <button\n type=\"button\"\n aria-label=\"Next month\"\n style={navButtonStyle}\n onClick={goToNextMonth}\n >\n <ChevronIcon direction=\"right\" />\n </button>\n )}\n </div>\n <div style={daysHeaderStyle}>\n {DAYS.map((day) => (\n <div key={day} style={dayHeaderStyle}>\n {day}\n </div>\n ))}\n </div>\n <div style={daysGridStyle}>\n {days.map((date, index) => {\n if (!date) {\n return <div key={`empty-${index}`} style={dayStyle(false, false, false, false)} />\n }\n\n const isStart = isSameDay(date, value.start)\n const isEnd = isSameDay(date, effectiveEnd)\n const isRange = isInRange(date, value.start, effectiveEnd)\n const isDisabled = isDateDisabled(date, minDate, maxDate)\n\n return (\n <button\n key={date.toISOString()}\n type=\"button\"\n disabled={isDisabled}\n style={dayStyle(isStart || isEnd, isRange, isDisabled, isSameDay(date, new Date()))}\n onClick={() => handleDateClick(date)}\n onMouseEnter={() => selectingEnd && setHoverDate(date)}\n onMouseLeave={() => setHoverDate(null)}\n >\n {date.getDate()}\n </button>\n )\n })}\n </div>\n </div>\n )\n }\n\n const displayValue = value.start && value.end\n ? `${dateFormat(value.start)} - ${dateFormat(value.end)}`\n : value.start\n ? `${dateFormat(value.start)} - ...`\n : ''\n\n const containerStyle: CSSProperties = {\n position: 'relative',\n display: 'inline-flex',\n width: '100%',\n }\n\n const inputWrapperStyle: CSSProperties = {\n position: 'relative',\n display: 'flex',\n alignItems: 'center',\n width: '100%',\n height: config.height,\n backgroundColor: disabled ? 'var(--brycks-background-muted)' : 'var(--brycks-background-default)',\n border: `1px solid ${\n isInvalid\n ? 'var(--brycks-error-default)'\n : isFocused\n ? 'var(--brycks-primary-default)'\n : 'var(--brycks-border-default)'\n }`,\n borderRadius: 'var(--brycks-radius-md)',\n transition: `all ${durations.fast}ms ${easings.easeOut}`,\n cursor: disabled ? 'not-allowed' : 'pointer',\n boxShadow: isFocused ? 'var(--brycks-focus-ring)' : undefined,\n padding: `0 ${config.padding}px`,\n paddingRight: clearable && (value.start || value.end) ? spacing[10] : config.padding,\n }\n\n const iconStyle: CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n marginRight: spacing[2],\n color: 'var(--brycks-foreground-muted)',\n }\n\n const textStyle: CSSProperties = {\n flex: 1,\n fontSize: config.fontSize,\n color: displayValue ? 'var(--brycks-foreground-default)' : 'var(--brycks-foreground-muted)',\n }\n\n const clearButtonStyle: CSSProperties = {\n position: 'absolute',\n right: config.padding,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: spacing[5],\n height: spacing[5],\n color: 'var(--brycks-foreground-muted)',\n cursor: 'pointer',\n borderRadius: 'var(--brycks-radius-sm)',\n transition: `all ${durations.fast}ms ${easings.easeOut}`,\n }\n\n const dropdownStyle: CSSProperties = {\n position: 'absolute',\n top: dropdownPosition.top,\n left: dropdownPosition.left,\n backgroundColor: 'var(--brycks-background-elevated)',\n border: '1px solid var(--brycks-border-default)',\n borderRadius: 'var(--brycks-radius-lg)',\n boxShadow: 'var(--brycks-shadow-lg)',\n zIndex: 'var(--brycks-z-dropdown)' as unknown as number,\n padding: spacing[3],\n display: 'flex',\n gap: spacing[4],\n }\n\n const calendarHeaderStyle: CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n marginBottom: spacing[2],\n minHeight: spacing[8],\n fontSize: fontSizes.base,\n }\n\n const navButtonStyle: CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: spacing[7],\n height: spacing[7],\n backgroundColor: 'transparent',\n border: 'none',\n borderRadius: 'var(--brycks-radius-md)',\n cursor: 'pointer',\n color: 'var(--brycks-foreground-default)',\n transition: `all ${durations.fast}ms ${easings.easeOut}`,\n }\n\n const daysHeaderStyle: CSSProperties = {\n display: 'grid',\n gridTemplateColumns: 'repeat(7, 1fr)',\n gap: spacing[0.5],\n marginBottom: spacing[1],\n }\n\n const dayHeaderStyle: CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n height: spacing[7],\n fontSize: fontSizes.xs,\n fontWeight: 600,\n color: 'var(--brycks-foreground-muted)',\n }\n\n const daysGridStyle: CSSProperties = {\n display: 'grid',\n gridTemplateColumns: 'repeat(7, 1fr)',\n gap: spacing[0.5],\n }\n\n const dayStyle = (isSelected: boolean, isRange: boolean, isDisabled: boolean, isToday: boolean): CSSProperties => ({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: spacing[8],\n height: spacing[8],\n fontSize: fontSizes.sm,\n fontWeight: isSelected ? 600 : 400,\n color: isDisabled\n ? 'var(--brycks-foreground-disabled)'\n : isSelected\n ? 'var(--brycks-primary-foreground)'\n : 'var(--brycks-foreground-default)',\n backgroundColor: isSelected\n ? 'var(--brycks-primary-default)'\n : isRange\n ? 'var(--brycks-primary-muted)'\n : 'transparent',\n border: isToday && !isSelected ? '1px solid var(--brycks-border-strong)' : 'none',\n borderRadius: 'var(--brycks-radius-md)',\n cursor: isDisabled ? 'not-allowed' : 'pointer',\n opacity: isDisabled ? 0.5 : 1,\n transition: `all ${durations.fast}ms ${easings.easeOut}`,\n })\n\n const presetsStyle: CSSProperties = {\n display: 'flex',\n flexDirection: 'column',\n gap: spacing[1],\n borderLeft: '1px solid var(--brycks-border-default)',\n paddingLeft: spacing[3],\n minWidth: 140,\n }\n\n const presetButtonStyle: CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n padding: `${spacing[2]}px ${spacing[3]}px`,\n fontSize: fontSizes.sm,\n color: 'var(--brycks-foreground-default)',\n backgroundColor: 'transparent',\n border: 'none',\n borderRadius: 'var(--brycks-radius-md)',\n cursor: 'pointer',\n textAlign: 'left',\n transition: `all ${durations.fast}ms ${easings.easeOut}`,\n }\n\n return (\n <div\n ref={(node) => {\n (containerRef as React.MutableRefObject<HTMLDivElement | null>).current = node\n if (typeof ref === 'function') ref(node)\n else if (ref) ref.current = node\n }}\n className={cx('brycks-daterangepicker', `brycks-daterangepicker--${size}`, className)}\n style={containerStyle}\n data-testid={testId}\n onKeyDown={handleKeyDown}\n >\n <div\n role=\"button\"\n tabIndex={disabled ? -1 : 0}\n aria-label={ariaLabel}\n aria-expanded={isOpen}\n aria-haspopup=\"dialog\"\n aria-invalid={isInvalid}\n style={inputWrapperStyle}\n onClick={() => !disabled && setIsOpen(true)}\n onFocus={() => setIsFocused(true)}\n onBlur={() => setIsFocused(false)}\n >\n <span style={iconStyle}>\n <CalendarIcon />\n </span>\n <span style={textStyle}>{displayValue || placeholder}</span>\n {clearable && (value.start || value.end) && !disabled && (\n <button\n type=\"button\"\n aria-label=\"Clear date range\"\n style={clearButtonStyle}\n onClick={handleClear}\n onMouseEnter={(e) => {\n e.currentTarget.style.backgroundColor = 'var(--brycks-background-muted)'\n e.currentTarget.style.color = 'var(--brycks-foreground-default)'\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = 'transparent'\n e.currentTarget.style.color = 'var(--brycks-foreground-muted)'\n }}\n >\n <ClearIcon />\n </button>\n )}\n </div>\n\n {isOpen &&\n createPortal(\n <div role=\"dialog\" aria-label=\"Date range picker\" style={dropdownStyle}>\n {renderCalendar(0)}\n {renderCalendar(1)}\n {presets && presets.length > 0 && (\n <div style={presetsStyle}>\n <div style={{ fontSize: fontSizes.xs, fontWeight: 600, color: 'var(--brycks-foreground-muted)', marginBottom: spacing[1] }}>\n Presets\n </div>\n {presets.map((preset, index) => (\n <button\n key={index}\n type=\"button\"\n style={presetButtonStyle}\n onClick={() => handlePresetClick(preset)}\n onMouseEnter={(e) => {\n e.currentTarget.style.backgroundColor = 'var(--brycks-background-muted)'\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = 'transparent'\n }}\n >\n {preset.label}\n </button>\n ))}\n </div>\n )}\n </div>,\n document.body\n )}\n </div>\n )\n})\n\nDateRangePicker.displayName = 'DateRangePicker'\n"],"names":["sizeConfig","componentHeights","fontSizes","componentPaddingX","DAYS","MONTHS","defaultDateFormat","date","CalendarIcon","jsxs","jsx","ChevronIcon","direction","ClearIcon","getDaysInMonth","year","month","getFirstDayOfMonth","isSameDay","date1","date2","isInRange","start","end","time","isDateDisabled","minDate","maxDate","DateRangePicker","forwardRef","controlledValue","defaultValue","onChange","size","placeholder","disabled","isInvalid","clearable","presets","dateFormat","ariaLabel","className","testId","ref","internalValue","setInternalValue","useState","isOpen","setIsOpen","isFocused","setIsFocused","viewDate","setViewDate","initial","selectingEnd","setSelectingEnd","hoverDate","setHoverDate","containerRef","useRef","value","config","updateValue","useCallback","newValue","handleDateClick","handlePresetClick","preset","handleClear","handleKeyDown","useEffect","handleClick","e","dropdownPosition","setDropdownPosition","updatePosition","rect","spacing","goToPrevMonth","prev","goToNextMonth","renderCalendar","monthOffset","daysInMonth","firstDay","days","i","effectiveEnd","calendarHeaderStyle","navButtonStyle","daysHeaderStyle","day","dayHeaderStyle","daysGridStyle","index","dayStyle","isStart","isEnd","isRange","isDisabled","displayValue","containerStyle","inputWrapperStyle","durations","easings","iconStyle","textStyle","clearButtonStyle","dropdownStyle","isSelected","isToday","presetsStyle","presetButtonStyle","node","cx","createPortal"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("react/jsx-runtime"),t=require("react"),F=require("../../../utils/styles.cjs"),d=t.forwardRef(function({onFiles:k,accept:g,multiple:i=!0,maxSize:f,disabled:e=!1,children:p,icon:v,helperText:y,error:s,className:b,testId:D},m){const[c,l]=t.useState(!1),a=t.useRef(null),h=t.useCallback(r=>{r.preventDefault(),r.stopPropagation(),e||l(!0)},[e]),x=t.useCallback(r=>{r.preventDefault(),r.stopPropagation(),l(!1)},[]),C=t.useCallback(r=>{r.preventDefault(),r.stopPropagation(),e||l(!0)},[e]),u=t.useCallback(r=>{if(!r||r.length===0)return;let n=Array.from(r);f&&(n=n.filter(E=>E.size<=f)),!i&&n.length>1&&(n=[n[0]]),k?.(n)},[f,i,k]),j=t.useCallback(r=>{r.preventDefault(),r.stopPropagation(),l(!1),!e&&u(r.dataTransfer.files)},[e,u]),z=t.useCallback(()=>{e||a.current?.click()},[e]),S=t.useCallback(r=>{u(r.target.files),a.current&&(a.current.value="")},[u]),R=t.useCallback(r=>{(r.key==="Enter"||r.key===" ")&&!e&&(r.preventDefault(),a.current?.click())},[e]),O={padding:"40px 20px",border:`2px dashed ${s?"var(--brycks-error-default)":c?"var(--brycks-primary-default)":"var(--brycks-border-muted)"}`,borderRadius:"var(--brycks-radius-lg)",cursor:e?"not-allowed":"pointer",textAlign:"center",transition:"all var(--brycks-duration-fast) var(--brycks-
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("react/jsx-runtime"),t=require("react"),F=require("../../../utils/styles.cjs"),d=t.forwardRef(function({onFiles:k,accept:g,multiple:i=!0,maxSize:f,disabled:e=!1,children:p,icon:v,helperText:y,error:s,className:b,testId:D},m){const[c,l]=t.useState(!1),a=t.useRef(null),h=t.useCallback(r=>{r.preventDefault(),r.stopPropagation(),e||l(!0)},[e]),x=t.useCallback(r=>{r.preventDefault(),r.stopPropagation(),l(!1)},[]),C=t.useCallback(r=>{r.preventDefault(),r.stopPropagation(),e||l(!0)},[e]),u=t.useCallback(r=>{if(!r||r.length===0)return;let n=Array.from(r);f&&(n=n.filter(E=>E.size<=f)),!i&&n.length>1&&(n=[n[0]]),k?.(n)},[f,i,k]),j=t.useCallback(r=>{r.preventDefault(),r.stopPropagation(),l(!1),!e&&u(r.dataTransfer.files)},[e,u]),z=t.useCallback(()=>{e||a.current?.click()},[e]),S=t.useCallback(r=>{u(r.target.files),a.current&&(a.current.value="")},[u]),R=t.useCallback(r=>{(r.key==="Enter"||r.key===" ")&&!e&&(r.preventDefault(),a.current?.click())},[e]),O={padding:"40px 20px",border:`2px dashed ${s?"var(--brycks-error-default)":c?"var(--brycks-primary-default)":"var(--brycks-border-muted)"}`,borderRadius:"var(--brycks-radius-lg)",cursor:e?"not-allowed":"pointer",textAlign:"center",transition:"all var(--brycks-duration-fast) var(--brycks-ease-out)",background:c?"var(--brycks-primary-muted)":"var(--brycks-background-muted)",opacity:e?.5:1},P={display:"flex",justifyContent:"center",marginBottom:12,color:c?"var(--brycks-primary-default)":"var(--brycks-foreground-muted)"},w={fontFamily:"var(--brycks-font-sans)",fontSize:"var(--brycks-font-size-sm)",fontWeight:500,color:"var(--brycks-foreground-default)",marginBottom:y?4:0},Z={fontFamily:"var(--brycks-font-sans)",fontSize:"var(--brycks-font-size-xs)",color:"var(--brycks-foreground-muted)"},q={fontFamily:"var(--brycks-font-sans)",fontSize:"var(--brycks-font-size-xs)",color:"var(--brycks-error-default)",marginTop:8};return o.jsxs("div",{ref:m,className:F.cx("brycks-dropzone",c&&"brycks-dropzone--drag-over",e&&"brycks-dropzone--disabled",s&&"brycks-dropzone--error",b),style:O,onClick:z,onDragEnter:h,onDragLeave:x,onDragOver:C,onDrop:j,onKeyDown:R,role:"button",tabIndex:e?-1:0,"aria-disabled":e,"data-testid":D,children:[o.jsx("input",{ref:a,type:"file",accept:g,multiple:i,onChange:S,style:{display:"none"},"aria-hidden":"true"}),v&&o.jsx("div",{style:P,children:v}),p&&o.jsx("div",{style:w,children:p}),y&&o.jsx("div",{style:Z,children:y}),s&&o.jsx("div",{style:q,children:s})]})});d.displayName="DropZone";exports.DropZone=d;
|
|
2
2
|
//# sourceMappingURL=DropZone.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DropZone.cjs","sources":["../../../../src/components/form/DropZone/DropZone.tsx"],"sourcesContent":["/**\n * DropZone Component\n *\n * File upload area with drag-and-drop support.\n * Provides visual feedback during drag operations.\n */\n\nimport {\n forwardRef,\n useState,\n useRef,\n useCallback,\n type CSSProperties,\n type ReactNode,\n type DragEvent,\n type ChangeEvent,\n} from 'react'\nimport { cx } from '../../../utils/styles'\n\nexport interface DropZoneProps {\n /** Callback when files are selected or dropped */\n onFiles?: (files: File[]) => void\n /** Accepted file types (e.g., \"image/*\", \".pdf,.doc\") */\n accept?: string\n /** Whether multiple files can be selected */\n multiple?: boolean\n /** Maximum file size in bytes */\n maxSize?: number\n /** Whether the drop zone is disabled */\n disabled?: boolean\n /** Main text content */\n children?: ReactNode\n /** Icon to display */\n icon?: ReactNode\n /** Helper text shown below main content */\n helperText?: string\n /** Error message */\n error?: string\n /** Custom class name */\n className?: string\n /** Test ID */\n testId?: string\n}\n\nexport const DropZone = forwardRef<HTMLDivElement, DropZoneProps>(\n function DropZone(\n {\n onFiles,\n accept,\n multiple = true,\n maxSize,\n disabled = false,\n children,\n icon,\n helperText,\n error,\n className,\n testId,\n },\n ref\n ) {\n const [isDragOver, setIsDragOver] = useState(false)\n const fileInputRef = useRef<HTMLInputElement>(null)\n\n const handleDragEnter = useCallback(\n (e: DragEvent<HTMLDivElement>) => {\n e.preventDefault()\n e.stopPropagation()\n if (!disabled) {\n setIsDragOver(true)\n }\n },\n [disabled]\n )\n\n const handleDragLeave = useCallback((e: DragEvent<HTMLDivElement>) => {\n e.preventDefault()\n e.stopPropagation()\n setIsDragOver(false)\n }, [])\n\n const handleDragOver = useCallback(\n (e: DragEvent<HTMLDivElement>) => {\n e.preventDefault()\n e.stopPropagation()\n if (!disabled) {\n setIsDragOver(true)\n }\n },\n [disabled]\n )\n\n const processFiles = useCallback(\n (fileList: FileList | null) => {\n if (!fileList || fileList.length === 0) return\n\n let files = Array.from(fileList)\n\n // Filter by size if maxSize is set\n if (maxSize) {\n files = files.filter((file) => file.size <= maxSize)\n }\n\n // Take only first file if multiple is false\n if (!multiple && files.length > 1) {\n files = [files[0]]\n }\n\n onFiles?.(files)\n },\n [maxSize, multiple, onFiles]\n )\n\n const handleDrop = useCallback(\n (e: DragEvent<HTMLDivElement>) => {\n e.preventDefault()\n e.stopPropagation()\n setIsDragOver(false)\n\n if (disabled) return\n\n processFiles(e.dataTransfer.files)\n },\n [disabled, processFiles]\n )\n\n const handleClick = useCallback(() => {\n if (!disabled) {\n fileInputRef.current?.click()\n }\n }, [disabled])\n\n const handleChange = useCallback(\n (e: ChangeEvent<HTMLInputElement>) => {\n processFiles(e.target.files)\n // Reset input value to allow selecting the same file again\n if (fileInputRef.current) {\n fileInputRef.current.value = ''\n }\n },\n [processFiles]\n )\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if ((e.key === 'Enter' || e.key === ' ') && !disabled) {\n e.preventDefault()\n fileInputRef.current?.click()\n }\n },\n [disabled]\n )\n\n const containerStyle: CSSProperties = {\n padding: '40px 20px',\n border: `2px dashed ${\n error\n ? 'var(--brycks-error-default)'\n : isDragOver\n ? 'var(--brycks-primary-default)'\n : 'var(--brycks-border-muted)'\n }`,\n borderRadius: 'var(--brycks-radius-lg)',\n cursor: disabled ? 'not-allowed' : 'pointer',\n textAlign: 'center',\n transition: 'all var(--brycks-duration-fast) var(--brycks-
|
|
1
|
+
{"version":3,"file":"DropZone.cjs","sources":["../../../../src/components/form/DropZone/DropZone.tsx"],"sourcesContent":["/**\n * DropZone Component\n *\n * File upload area with drag-and-drop support.\n * Provides visual feedback during drag operations.\n */\n\nimport {\n forwardRef,\n useState,\n useRef,\n useCallback,\n type CSSProperties,\n type ReactNode,\n type DragEvent,\n type ChangeEvent,\n} from 'react'\nimport { cx } from '../../../utils/styles'\n\nexport interface DropZoneProps {\n /** Callback when files are selected or dropped */\n onFiles?: (files: File[]) => void\n /** Accepted file types (e.g., \"image/*\", \".pdf,.doc\") */\n accept?: string\n /** Whether multiple files can be selected */\n multiple?: boolean\n /** Maximum file size in bytes */\n maxSize?: number\n /** Whether the drop zone is disabled */\n disabled?: boolean\n /** Main text content */\n children?: ReactNode\n /** Icon to display */\n icon?: ReactNode\n /** Helper text shown below main content */\n helperText?: string\n /** Error message */\n error?: string\n /** Custom class name */\n className?: string\n /** Test ID */\n testId?: string\n}\n\nexport const DropZone = forwardRef<HTMLDivElement, DropZoneProps>(\n function DropZone(\n {\n onFiles,\n accept,\n multiple = true,\n maxSize,\n disabled = false,\n children,\n icon,\n helperText,\n error,\n className,\n testId,\n },\n ref\n ) {\n const [isDragOver, setIsDragOver] = useState(false)\n const fileInputRef = useRef<HTMLInputElement>(null)\n\n const handleDragEnter = useCallback(\n (e: DragEvent<HTMLDivElement>) => {\n e.preventDefault()\n e.stopPropagation()\n if (!disabled) {\n setIsDragOver(true)\n }\n },\n [disabled]\n )\n\n const handleDragLeave = useCallback((e: DragEvent<HTMLDivElement>) => {\n e.preventDefault()\n e.stopPropagation()\n setIsDragOver(false)\n }, [])\n\n const handleDragOver = useCallback(\n (e: DragEvent<HTMLDivElement>) => {\n e.preventDefault()\n e.stopPropagation()\n if (!disabled) {\n setIsDragOver(true)\n }\n },\n [disabled]\n )\n\n const processFiles = useCallback(\n (fileList: FileList | null) => {\n if (!fileList || fileList.length === 0) return\n\n let files = Array.from(fileList)\n\n // Filter by size if maxSize is set\n if (maxSize) {\n files = files.filter((file) => file.size <= maxSize)\n }\n\n // Take only first file if multiple is false\n if (!multiple && files.length > 1) {\n files = [files[0]]\n }\n\n onFiles?.(files)\n },\n [maxSize, multiple, onFiles]\n )\n\n const handleDrop = useCallback(\n (e: DragEvent<HTMLDivElement>) => {\n e.preventDefault()\n e.stopPropagation()\n setIsDragOver(false)\n\n if (disabled) return\n\n processFiles(e.dataTransfer.files)\n },\n [disabled, processFiles]\n )\n\n const handleClick = useCallback(() => {\n if (!disabled) {\n fileInputRef.current?.click()\n }\n }, [disabled])\n\n const handleChange = useCallback(\n (e: ChangeEvent<HTMLInputElement>) => {\n processFiles(e.target.files)\n // Reset input value to allow selecting the same file again\n if (fileInputRef.current) {\n fileInputRef.current.value = ''\n }\n },\n [processFiles]\n )\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if ((e.key === 'Enter' || e.key === ' ') && !disabled) {\n e.preventDefault()\n fileInputRef.current?.click()\n }\n },\n [disabled]\n )\n\n const containerStyle: CSSProperties = {\n padding: '40px 20px',\n border: `2px dashed ${\n error\n ? 'var(--brycks-error-default)'\n : isDragOver\n ? 'var(--brycks-primary-default)'\n : 'var(--brycks-border-muted)'\n }`,\n borderRadius: 'var(--brycks-radius-lg)',\n cursor: disabled ? 'not-allowed' : 'pointer',\n textAlign: 'center',\n transition: 'all var(--brycks-duration-fast) var(--brycks-ease-out)',\n background: isDragOver\n ? 'var(--brycks-primary-muted)'\n : 'var(--brycks-background-muted)',\n opacity: disabled ? 0.5 : 1,\n }\n\n const iconStyle: CSSProperties = {\n display: 'flex',\n justifyContent: 'center',\n marginBottom: 12,\n color: isDragOver\n ? 'var(--brycks-primary-default)'\n : 'var(--brycks-foreground-muted)',\n }\n\n const textStyle: CSSProperties = {\n fontFamily: 'var(--brycks-font-sans)',\n fontSize: 'var(--brycks-font-size-sm)',\n fontWeight: 500,\n color: 'var(--brycks-foreground-default)',\n marginBottom: helperText ? 4 : 0,\n }\n\n const helperStyle: CSSProperties = {\n fontFamily: 'var(--brycks-font-sans)',\n fontSize: 'var(--brycks-font-size-xs)',\n color: 'var(--brycks-foreground-muted)',\n }\n\n const errorStyle: CSSProperties = {\n fontFamily: 'var(--brycks-font-sans)',\n fontSize: 'var(--brycks-font-size-xs)',\n color: 'var(--brycks-error-default)',\n marginTop: 8,\n }\n\n return (\n <div\n ref={ref}\n className={cx(\n 'brycks-dropzone',\n isDragOver && 'brycks-dropzone--drag-over',\n disabled && 'brycks-dropzone--disabled',\n error && 'brycks-dropzone--error',\n className\n )}\n style={containerStyle}\n onClick={handleClick}\n onDragEnter={handleDragEnter}\n onDragLeave={handleDragLeave}\n onDragOver={handleDragOver}\n onDrop={handleDrop}\n onKeyDown={handleKeyDown}\n role=\"button\"\n tabIndex={disabled ? -1 : 0}\n aria-disabled={disabled}\n data-testid={testId}\n >\n <input\n ref={fileInputRef}\n type=\"file\"\n accept={accept}\n multiple={multiple}\n onChange={handleChange}\n style={{ display: 'none' }}\n aria-hidden=\"true\"\n />\n\n {icon && <div style={iconStyle}>{icon}</div>}\n\n {children && <div style={textStyle}>{children}</div>}\n\n {helperText && <div style={helperStyle}>{helperText}</div>}\n\n {error && <div style={errorStyle}>{error}</div>}\n </div>\n )\n }\n)\n\nDropZone.displayName = 'DropZone'\n"],"names":["DropZone","forwardRef","onFiles","accept","multiple","maxSize","disabled","children","icon","helperText","error","className","testId","ref","isDragOver","setIsDragOver","useState","fileInputRef","useRef","handleDragEnter","useCallback","e","handleDragLeave","handleDragOver","processFiles","fileList","files","file","handleDrop","handleClick","handleChange","handleKeyDown","containerStyle","iconStyle","textStyle","helperStyle","errorStyle","jsxs","cx","jsx"],"mappings":"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"}
|
|
@@ -5,7 +5,7 @@ const N = Z(
|
|
|
5
5
|
function({
|
|
6
6
|
onFiles: p,
|
|
7
7
|
accept: k,
|
|
8
|
-
multiple:
|
|
8
|
+
multiple: i = !0,
|
|
9
9
|
maxSize: y,
|
|
10
10
|
disabled: t = !1,
|
|
11
11
|
children: v,
|
|
@@ -27,25 +27,25 @@ const N = Z(
|
|
|
27
27
|
r.preventDefault(), r.stopPropagation(), t || f(!0);
|
|
28
28
|
},
|
|
29
29
|
[t]
|
|
30
|
-
),
|
|
30
|
+
), l = e(
|
|
31
31
|
(r) => {
|
|
32
32
|
if (!r || r.length === 0) return;
|
|
33
33
|
let o = Array.from(r);
|
|
34
|
-
y && (o = o.filter((F) => F.size <= y)), !
|
|
34
|
+
y && (o = o.filter((F) => F.size <= y)), !i && o.length > 1 && (o = [o[0]]), p?.(o);
|
|
35
35
|
},
|
|
36
|
-
[y,
|
|
36
|
+
[y, i, p]
|
|
37
37
|
), z = e(
|
|
38
38
|
(r) => {
|
|
39
|
-
r.preventDefault(), r.stopPropagation(), f(!1), !t &&
|
|
39
|
+
r.preventDefault(), r.stopPropagation(), f(!1), !t && l(r.dataTransfer.files);
|
|
40
40
|
},
|
|
41
|
-
[t,
|
|
41
|
+
[t, l]
|
|
42
42
|
), S = e(() => {
|
|
43
43
|
t || n.current?.click();
|
|
44
44
|
}, [t]), C = e(
|
|
45
45
|
(r) => {
|
|
46
|
-
|
|
46
|
+
l(r.target.files), n.current && (n.current.value = "");
|
|
47
47
|
},
|
|
48
|
-
[
|
|
48
|
+
[l]
|
|
49
49
|
), w = e(
|
|
50
50
|
(r) => {
|
|
51
51
|
(r.key === "Enter" || r.key === " ") && !t && (r.preventDefault(), n.current?.click());
|
|
@@ -57,7 +57,7 @@ const N = Z(
|
|
|
57
57
|
borderRadius: "var(--brycks-radius-lg)",
|
|
58
58
|
cursor: t ? "not-allowed" : "pointer",
|
|
59
59
|
textAlign: "center",
|
|
60
|
-
transition: "all var(--brycks-duration-fast) var(--brycks-
|
|
60
|
+
transition: "all var(--brycks-duration-fast) var(--brycks-ease-out)",
|
|
61
61
|
background: c ? "var(--brycks-primary-muted)" : "var(--brycks-background-muted)",
|
|
62
62
|
opacity: t ? 0.5 : 1
|
|
63
63
|
}, P = {
|
|
@@ -110,7 +110,7 @@ const N = Z(
|
|
|
110
110
|
ref: n,
|
|
111
111
|
type: "file",
|
|
112
112
|
accept: k,
|
|
113
|
-
multiple:
|
|
113
|
+
multiple: i,
|
|
114
114
|
onChange: C,
|
|
115
115
|
style: { display: "none" },
|
|
116
116
|
"aria-hidden": "true"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DropZone.js","sources":["../../../../src/components/form/DropZone/DropZone.tsx"],"sourcesContent":["/**\n * DropZone Component\n *\n * File upload area with drag-and-drop support.\n * Provides visual feedback during drag operations.\n */\n\nimport {\n forwardRef,\n useState,\n useRef,\n useCallback,\n type CSSProperties,\n type ReactNode,\n type DragEvent,\n type ChangeEvent,\n} from 'react'\nimport { cx } from '../../../utils/styles'\n\nexport interface DropZoneProps {\n /** Callback when files are selected or dropped */\n onFiles?: (files: File[]) => void\n /** Accepted file types (e.g., \"image/*\", \".pdf,.doc\") */\n accept?: string\n /** Whether multiple files can be selected */\n multiple?: boolean\n /** Maximum file size in bytes */\n maxSize?: number\n /** Whether the drop zone is disabled */\n disabled?: boolean\n /** Main text content */\n children?: ReactNode\n /** Icon to display */\n icon?: ReactNode\n /** Helper text shown below main content */\n helperText?: string\n /** Error message */\n error?: string\n /** Custom class name */\n className?: string\n /** Test ID */\n testId?: string\n}\n\nexport const DropZone = forwardRef<HTMLDivElement, DropZoneProps>(\n function DropZone(\n {\n onFiles,\n accept,\n multiple = true,\n maxSize,\n disabled = false,\n children,\n icon,\n helperText,\n error,\n className,\n testId,\n },\n ref\n ) {\n const [isDragOver, setIsDragOver] = useState(false)\n const fileInputRef = useRef<HTMLInputElement>(null)\n\n const handleDragEnter = useCallback(\n (e: DragEvent<HTMLDivElement>) => {\n e.preventDefault()\n e.stopPropagation()\n if (!disabled) {\n setIsDragOver(true)\n }\n },\n [disabled]\n )\n\n const handleDragLeave = useCallback((e: DragEvent<HTMLDivElement>) => {\n e.preventDefault()\n e.stopPropagation()\n setIsDragOver(false)\n }, [])\n\n const handleDragOver = useCallback(\n (e: DragEvent<HTMLDivElement>) => {\n e.preventDefault()\n e.stopPropagation()\n if (!disabled) {\n setIsDragOver(true)\n }\n },\n [disabled]\n )\n\n const processFiles = useCallback(\n (fileList: FileList | null) => {\n if (!fileList || fileList.length === 0) return\n\n let files = Array.from(fileList)\n\n // Filter by size if maxSize is set\n if (maxSize) {\n files = files.filter((file) => file.size <= maxSize)\n }\n\n // Take only first file if multiple is false\n if (!multiple && files.length > 1) {\n files = [files[0]]\n }\n\n onFiles?.(files)\n },\n [maxSize, multiple, onFiles]\n )\n\n const handleDrop = useCallback(\n (e: DragEvent<HTMLDivElement>) => {\n e.preventDefault()\n e.stopPropagation()\n setIsDragOver(false)\n\n if (disabled) return\n\n processFiles(e.dataTransfer.files)\n },\n [disabled, processFiles]\n )\n\n const handleClick = useCallback(() => {\n if (!disabled) {\n fileInputRef.current?.click()\n }\n }, [disabled])\n\n const handleChange = useCallback(\n (e: ChangeEvent<HTMLInputElement>) => {\n processFiles(e.target.files)\n // Reset input value to allow selecting the same file again\n if (fileInputRef.current) {\n fileInputRef.current.value = ''\n }\n },\n [processFiles]\n )\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if ((e.key === 'Enter' || e.key === ' ') && !disabled) {\n e.preventDefault()\n fileInputRef.current?.click()\n }\n },\n [disabled]\n )\n\n const containerStyle: CSSProperties = {\n padding: '40px 20px',\n border: `2px dashed ${\n error\n ? 'var(--brycks-error-default)'\n : isDragOver\n ? 'var(--brycks-primary-default)'\n : 'var(--brycks-border-muted)'\n }`,\n borderRadius: 'var(--brycks-radius-lg)',\n cursor: disabled ? 'not-allowed' : 'pointer',\n textAlign: 'center',\n transition: 'all var(--brycks-duration-fast) var(--brycks-easing-out)',\n background: isDragOver\n ? 'var(--brycks-primary-muted)'\n : 'var(--brycks-background-muted)',\n opacity: disabled ? 0.5 : 1,\n }\n\n const iconStyle: CSSProperties = {\n display: 'flex',\n justifyContent: 'center',\n marginBottom: 12,\n color: isDragOver\n ? 'var(--brycks-primary-default)'\n : 'var(--brycks-foreground-muted)',\n }\n\n const textStyle: CSSProperties = {\n fontFamily: 'var(--brycks-font-sans)',\n fontSize: 'var(--brycks-font-size-sm)',\n fontWeight: 500,\n color: 'var(--brycks-foreground-default)',\n marginBottom: helperText ? 4 : 0,\n }\n\n const helperStyle: CSSProperties = {\n fontFamily: 'var(--brycks-font-sans)',\n fontSize: 'var(--brycks-font-size-xs)',\n color: 'var(--brycks-foreground-muted)',\n }\n\n const errorStyle: CSSProperties = {\n fontFamily: 'var(--brycks-font-sans)',\n fontSize: 'var(--brycks-font-size-xs)',\n color: 'var(--brycks-error-default)',\n marginTop: 8,\n }\n\n return (\n <div\n ref={ref}\n className={cx(\n 'brycks-dropzone',\n isDragOver && 'brycks-dropzone--drag-over',\n disabled && 'brycks-dropzone--disabled',\n error && 'brycks-dropzone--error',\n className\n )}\n style={containerStyle}\n onClick={handleClick}\n onDragEnter={handleDragEnter}\n onDragLeave={handleDragLeave}\n onDragOver={handleDragOver}\n onDrop={handleDrop}\n onKeyDown={handleKeyDown}\n role=\"button\"\n tabIndex={disabled ? -1 : 0}\n aria-disabled={disabled}\n data-testid={testId}\n >\n <input\n ref={fileInputRef}\n type=\"file\"\n accept={accept}\n multiple={multiple}\n onChange={handleChange}\n style={{ display: 'none' }}\n aria-hidden=\"true\"\n />\n\n {icon && <div style={iconStyle}>{icon}</div>}\n\n {children && <div style={textStyle}>{children}</div>}\n\n {helperText && <div style={helperStyle}>{helperText}</div>}\n\n {error && <div style={errorStyle}>{error}</div>}\n </div>\n )\n }\n)\n\nDropZone.displayName = 'DropZone'\n"],"names":["DropZone","forwardRef","onFiles","accept","multiple","maxSize","disabled","children","icon","helperText","error","className","testId","ref","isDragOver","setIsDragOver","useState","fileInputRef","useRef","handleDragEnter","useCallback","e","handleDragLeave","handleDragOver","processFiles","fileList","files","file","handleDrop","handleClick","handleChange","handleKeyDown","containerStyle","iconStyle","textStyle","helperStyle","errorStyle","jsxs","cx","jsx"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"DropZone.js","sources":["../../../../src/components/form/DropZone/DropZone.tsx"],"sourcesContent":["/**\n * DropZone Component\n *\n * File upload area with drag-and-drop support.\n * Provides visual feedback during drag operations.\n */\n\nimport {\n forwardRef,\n useState,\n useRef,\n useCallback,\n type CSSProperties,\n type ReactNode,\n type DragEvent,\n type ChangeEvent,\n} from 'react'\nimport { cx } from '../../../utils/styles'\n\nexport interface DropZoneProps {\n /** Callback when files are selected or dropped */\n onFiles?: (files: File[]) => void\n /** Accepted file types (e.g., \"image/*\", \".pdf,.doc\") */\n accept?: string\n /** Whether multiple files can be selected */\n multiple?: boolean\n /** Maximum file size in bytes */\n maxSize?: number\n /** Whether the drop zone is disabled */\n disabled?: boolean\n /** Main text content */\n children?: ReactNode\n /** Icon to display */\n icon?: ReactNode\n /** Helper text shown below main content */\n helperText?: string\n /** Error message */\n error?: string\n /** Custom class name */\n className?: string\n /** Test ID */\n testId?: string\n}\n\nexport const DropZone = forwardRef<HTMLDivElement, DropZoneProps>(\n function DropZone(\n {\n onFiles,\n accept,\n multiple = true,\n maxSize,\n disabled = false,\n children,\n icon,\n helperText,\n error,\n className,\n testId,\n },\n ref\n ) {\n const [isDragOver, setIsDragOver] = useState(false)\n const fileInputRef = useRef<HTMLInputElement>(null)\n\n const handleDragEnter = useCallback(\n (e: DragEvent<HTMLDivElement>) => {\n e.preventDefault()\n e.stopPropagation()\n if (!disabled) {\n setIsDragOver(true)\n }\n },\n [disabled]\n )\n\n const handleDragLeave = useCallback((e: DragEvent<HTMLDivElement>) => {\n e.preventDefault()\n e.stopPropagation()\n setIsDragOver(false)\n }, [])\n\n const handleDragOver = useCallback(\n (e: DragEvent<HTMLDivElement>) => {\n e.preventDefault()\n e.stopPropagation()\n if (!disabled) {\n setIsDragOver(true)\n }\n },\n [disabled]\n )\n\n const processFiles = useCallback(\n (fileList: FileList | null) => {\n if (!fileList || fileList.length === 0) return\n\n let files = Array.from(fileList)\n\n // Filter by size if maxSize is set\n if (maxSize) {\n files = files.filter((file) => file.size <= maxSize)\n }\n\n // Take only first file if multiple is false\n if (!multiple && files.length > 1) {\n files = [files[0]]\n }\n\n onFiles?.(files)\n },\n [maxSize, multiple, onFiles]\n )\n\n const handleDrop = useCallback(\n (e: DragEvent<HTMLDivElement>) => {\n e.preventDefault()\n e.stopPropagation()\n setIsDragOver(false)\n\n if (disabled) return\n\n processFiles(e.dataTransfer.files)\n },\n [disabled, processFiles]\n )\n\n const handleClick = useCallback(() => {\n if (!disabled) {\n fileInputRef.current?.click()\n }\n }, [disabled])\n\n const handleChange = useCallback(\n (e: ChangeEvent<HTMLInputElement>) => {\n processFiles(e.target.files)\n // Reset input value to allow selecting the same file again\n if (fileInputRef.current) {\n fileInputRef.current.value = ''\n }\n },\n [processFiles]\n )\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if ((e.key === 'Enter' || e.key === ' ') && !disabled) {\n e.preventDefault()\n fileInputRef.current?.click()\n }\n },\n [disabled]\n )\n\n const containerStyle: CSSProperties = {\n padding: '40px 20px',\n border: `2px dashed ${\n error\n ? 'var(--brycks-error-default)'\n : isDragOver\n ? 'var(--brycks-primary-default)'\n : 'var(--brycks-border-muted)'\n }`,\n borderRadius: 'var(--brycks-radius-lg)',\n cursor: disabled ? 'not-allowed' : 'pointer',\n textAlign: 'center',\n transition: 'all var(--brycks-duration-fast) var(--brycks-ease-out)',\n background: isDragOver\n ? 'var(--brycks-primary-muted)'\n : 'var(--brycks-background-muted)',\n opacity: disabled ? 0.5 : 1,\n }\n\n const iconStyle: CSSProperties = {\n display: 'flex',\n justifyContent: 'center',\n marginBottom: 12,\n color: isDragOver\n ? 'var(--brycks-primary-default)'\n : 'var(--brycks-foreground-muted)',\n }\n\n const textStyle: CSSProperties = {\n fontFamily: 'var(--brycks-font-sans)',\n fontSize: 'var(--brycks-font-size-sm)',\n fontWeight: 500,\n color: 'var(--brycks-foreground-default)',\n marginBottom: helperText ? 4 : 0,\n }\n\n const helperStyle: CSSProperties = {\n fontFamily: 'var(--brycks-font-sans)',\n fontSize: 'var(--brycks-font-size-xs)',\n color: 'var(--brycks-foreground-muted)',\n }\n\n const errorStyle: CSSProperties = {\n fontFamily: 'var(--brycks-font-sans)',\n fontSize: 'var(--brycks-font-size-xs)',\n color: 'var(--brycks-error-default)',\n marginTop: 8,\n }\n\n return (\n <div\n ref={ref}\n className={cx(\n 'brycks-dropzone',\n isDragOver && 'brycks-dropzone--drag-over',\n disabled && 'brycks-dropzone--disabled',\n error && 'brycks-dropzone--error',\n className\n )}\n style={containerStyle}\n onClick={handleClick}\n onDragEnter={handleDragEnter}\n onDragLeave={handleDragLeave}\n onDragOver={handleDragOver}\n onDrop={handleDrop}\n onKeyDown={handleKeyDown}\n role=\"button\"\n tabIndex={disabled ? -1 : 0}\n aria-disabled={disabled}\n data-testid={testId}\n >\n <input\n ref={fileInputRef}\n type=\"file\"\n accept={accept}\n multiple={multiple}\n onChange={handleChange}\n style={{ display: 'none' }}\n aria-hidden=\"true\"\n />\n\n {icon && <div style={iconStyle}>{icon}</div>}\n\n {children && <div style={textStyle}>{children}</div>}\n\n {helperText && <div style={helperStyle}>{helperText}</div>}\n\n {error && <div style={errorStyle}>{error}</div>}\n </div>\n )\n }\n)\n\nDropZone.displayName = 'DropZone'\n"],"names":["DropZone","forwardRef","onFiles","accept","multiple","maxSize","disabled","children","icon","helperText","error","className","testId","ref","isDragOver","setIsDragOver","useState","fileInputRef","useRef","handleDragEnter","useCallback","e","handleDragLeave","handleDragOver","processFiles","fileList","files","file","handleDrop","handleClick","handleChange","handleKeyDown","containerStyle","iconStyle","textStyle","helperStyle","errorStyle","jsxs","cx","jsx"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("react/jsx-runtime"),n=require("react"),Q=require("../../../utils/styles.cjs"),V={sm:{height:80,fontSize:12,padding:16,iconSize:24},md:{height:120,fontSize:14,padding:24,iconSize:32},lg:{height:160,fontSize:16,padding:32,iconSize:40}};function X({size:f}){return t.jsx("svg",{width:f,height:f,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.5",children:t.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12"})})}const x=n.forwardRef(function({size:h="md",variant:S="dropzone",accept:m,multiple:a=!1,maxSize:d,label:k,description:y,error:p,isInvalid:D=!1,onChange:v,icon:j,disabled:r=!1,className:C,style:z,testId:w,...I},i){const[c,g]=n.useState(!1),[F,b]=n.useState(!1),l=n.useRef(null),o=V[h],R=D||!!p,u=n.useCallback(e=>{if(!e||e.length===0)return;let s=Array.from(e);d&&(s=s.filter(J=>J.size<=d)),!a&&s.length>1&&(s=[s[0]]),v?.(s)},[d,a,v]),O=n.useCallback(e=>{e.preventDefault(),e.stopPropagation(),r||g(!0)},[r]),P=n.useCallback(e=>{e.preventDefault(),e.stopPropagation(),g(!1)},[]),T=n.useCallback(e=>{e.preventDefault(),e.stopPropagation(),g(!1),r||u(e.dataTransfer.files)},[r,u]),W=n.useCallback(e=>{u(e.target.files),l.current&&(l.current.value="")},[u]),q=n.useCallback(()=>{r||l.current?.click()},[r]),A=n.useCallback(e=>{(e.key==="Enter"||e.key===" ")&&!r&&(e.preventDefault(),l.current?.click())},[r]),L={display:"flex",flexDirection:"column",gap:6,...z},M={fontSize:o.fontSize,fontWeight:500,color:"var(--brycks-foreground-default)"},$={display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",gap:8,minHeight:o.height,padding:o.padding,border:`2px dashed ${R?"var(--brycks-error-default)":c||F?"var(--brycks-primary-default)":"var(--brycks-border-default)"}`,borderRadius:"var(--brycks-radius-lg)",backgroundColor:c?"var(--brycks-primary-muted)":"var(--brycks-background-muted)",cursor:r?"not-allowed":"pointer",opacity:r?.5:1,transition:"all 150ms ease-out",outline:"none"},B={color:c?"var(--brycks-primary-default)":"var(--brycks-foreground-muted)",transition:"color 150ms ease-out"},E={display:"flex",flexDirection:"column",alignItems:"center",gap:4,textAlign:"center"},K={fontSize:o.fontSize,fontWeight:500,color:"var(--brycks-foreground-default)"},N={fontSize:o.fontSize-2,color:"var(--brycks-foreground-muted)"},H={color:"var(--brycks-primary-default)",fontWeight:500},U={fontSize:o.fontSize-2,color:"var(--brycks-error-default)"},G=a?"Drag files here or click to browse":"Drag a file here or click to browse";return t.jsxs("div",{className:Q.cx("brycks-file-input",`brycks-file-input--${h}`,`brycks-file-input--${S}`,C),style:L,children:[k&&t.jsx("label",{style:M,children:k}),t.jsxs("div",{style:$,onDragOver:O,onDragLeave:P,onDrop:T,onClick:q,onKeyDown:A,onFocus:()=>b(!0),onBlur:()=>b(!1),tabIndex:r?-1:0,role:"button","aria-label":String(y)||G,children:[t.jsx("div",{style:B,children:j||t.jsx(X,{size:o.iconSize})}),t.jsxs("div",{style:E,children:[t.jsx("span",{style:K,children:c?"Drop files here":t.jsxs(t.Fragment,{children:[t.jsx("span",{style:H,children:"Click to browse"})," or drag files here"]})}),y&&t.jsx("span",{style:N,children:y})]})]}),p&&t.jsx("span",{style:U,children:p}),t.jsx("input",{ref:e=>{l.current=e,typeof i=="function"?i(e):i&&(i.current=e)},type:"file",accept:m,multiple:a,disabled:r,onChange:W,style:{display:"none"},"data-testid":w,...I})]})});x.displayName="FileInput";exports.FileInput=x;
|
|
2
2
|
//# sourceMappingURL=FileInput.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FileInput.cjs","sources":["../../../../src/components/form/FileInput/FileInput.tsx"],"sourcesContent":["/**\n * FileInput Component\n *\n * Accessible file upload input with drag-and-drop support.\n * Supports multiple files and file type restrictions.\n */\n\nimport {\n forwardRef,\n useState,\n useRef,\n useCallback,\n type CSSProperties,\n type InputHTMLAttributes,\n type DragEvent,\n type ReactNode,\n} from 'react'\nimport { cx } from '../../../utils/styles'\n\nexport type FileInputSize = 'sm' | 'md' | 'lg'\nexport type FileInputVariant = 'default' | 'dropzone'\n\nexport interface FileInputProps\n extends Omit<InputHTMLAttributes<HTMLInputElement>, 'size' | 'type' | 'onChange' | 'value'> {\n /** Input size */\n size?: FileInputSize\n /** Input variant */\n variant?: FileInputVariant\n /** Accepted file types (e.g., \"image/*,.pdf\") */\n accept?: string\n /** Whether multiple files can be selected */\n multiple?: boolean\n /** Maximum file size in bytes */\n maxSize?: number\n /** Label text */\n label?: ReactNode\n /** Description text inside dropzone */\n description?: ReactNode\n /** Error message */\n error?: ReactNode\n /** Whether the input is invalid */\n isInvalid?: boolean\n /** Callback when files are selected */\n onChange?: (files: File[]) => void\n /** Icon to display in dropzone */\n icon?: ReactNode\n /** Custom class name */\n className?: string\n /** Test ID */\n testId?: string\n}\n\nconst sizeConfig: Record<FileInputSize, { height: number; fontSize: number; padding: number; iconSize: number }> = {\n sm: { height: 80, fontSize: 12, padding: 16, iconSize: 24 },\n md: { height: 120, fontSize: 14, padding: 24, iconSize: 32 },\n lg: { height: 160, fontSize: 16, padding: 32, iconSize: 40 },\n}\n\nfunction UploadIcon({ size }: { size: number }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.5\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12\" />\n </svg>\n )\n}\n\nexport const FileInput = forwardRef<HTMLInputElement, FileInputProps>(function FileInput(\n {\n size = 'md',\n variant = 'dropzone',\n accept,\n multiple = false,\n maxSize,\n label,\n description,\n error,\n isInvalid = false,\n onChange,\n icon,\n disabled = false,\n className,\n style,\n testId,\n ...props\n },\n ref\n) {\n const [isDragOver, setIsDragOver] = useState(false)\n const [isFocused, setIsFocused] = useState(false)\n const inputRef = useRef<HTMLInputElement>(null)\n const config = sizeConfig[size]\n const hasError = isInvalid || !!error\n\n const handleFiles = useCallback(\n (fileList: FileList | null) => {\n if (!fileList || fileList.length === 0) return\n\n let files = Array.from(fileList)\n\n // Filter by max size if specified\n if (maxSize) {\n files = files.filter((file) => file.size <= maxSize)\n }\n\n // If not multiple, only take first file\n if (!multiple && files.length > 1) {\n files = [files[0]]\n }\n\n onChange?.(files)\n },\n [maxSize, multiple, onChange]\n )\n\n const handleDragOver = useCallback((e: DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n if (!disabled) {\n setIsDragOver(true)\n }\n }, [disabled])\n\n const handleDragLeave = useCallback((e: DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n setIsDragOver(false)\n }, [])\n\n const handleDrop = useCallback(\n (e: DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n setIsDragOver(false)\n\n if (!disabled) {\n handleFiles(e.dataTransfer.files)\n }\n },\n [disabled, handleFiles]\n )\n\n const handleChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n handleFiles(e.target.files)\n // Reset input value to allow selecting the same file again\n if (inputRef.current) {\n inputRef.current.value = ''\n }\n },\n [handleFiles]\n )\n\n const handleClick = useCallback(() => {\n if (!disabled) {\n inputRef.current?.click()\n }\n }, [disabled])\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if ((e.key === 'Enter' || e.key === ' ') && !disabled) {\n e.preventDefault()\n inputRef.current?.click()\n }\n },\n [disabled]\n )\n\n const containerStyle: CSSProperties = {\n display: 'flex',\n flexDirection: 'column',\n gap: 6,\n ...style,\n }\n\n const labelStyle: CSSProperties = {\n fontSize: config.fontSize,\n fontWeight: 500,\n color: 'var(--brycks-foreground-default)',\n }\n\n const dropzoneStyle: CSSProperties = {\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n gap: 8,\n minHeight: config.height,\n padding: config.padding,\n border: `2px dashed ${\n hasError\n ? 'var(--brycks-error-default)'\n : isDragOver\n ? 'var(--brycks-primary-default)'\n : isFocused\n ? 'var(--brycks-primary-default)'\n : 'var(--brycks-border-default)'\n }`,\n borderRadius: 'var(--brycks-radius-lg)',\n backgroundColor: isDragOver\n ? 'var(--brycks-primary-50)'\n : 'var(--brycks-background-muted)',\n cursor: disabled ? 'not-allowed' : 'pointer',\n opacity: disabled ? 0.5 : 1,\n transition: 'all 150ms ease-out',\n outline: 'none',\n }\n\n const iconContainerStyle: CSSProperties = {\n color: isDragOver\n ? 'var(--brycks-primary-default)'\n : 'var(--brycks-foreground-muted)',\n transition: 'color 150ms ease-out',\n }\n\n const textContainerStyle: CSSProperties = {\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n gap: 4,\n textAlign: 'center',\n }\n\n const primaryTextStyle: CSSProperties = {\n fontSize: config.fontSize,\n fontWeight: 500,\n color: 'var(--brycks-foreground-default)',\n }\n\n const secondaryTextStyle: CSSProperties = {\n fontSize: config.fontSize - 2,\n color: 'var(--brycks-foreground-muted)',\n }\n\n const browseStyle: CSSProperties = {\n color: 'var(--brycks-primary-default)',\n fontWeight: 500,\n }\n\n const errorStyle: CSSProperties = {\n fontSize: config.fontSize - 2,\n color: 'var(--brycks-error-default)',\n }\n\n const defaultDescription = multiple\n ? 'Drag files here or click to browse'\n : 'Drag a file here or click to browse'\n\n return (\n <div\n className={cx('brycks-file-input', `brycks-file-input--${size}`, `brycks-file-input--${variant}`, className)}\n style={containerStyle}\n >\n {label && <label style={labelStyle}>{label}</label>}\n <div\n style={dropzoneStyle}\n onDragOver={handleDragOver}\n onDragLeave={handleDragLeave}\n onDrop={handleDrop}\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n onFocus={() => setIsFocused(true)}\n onBlur={() => setIsFocused(false)}\n tabIndex={disabled ? -1 : 0}\n role=\"button\"\n aria-label={String(description) || defaultDescription}\n >\n <div style={iconContainerStyle}>\n {icon || <UploadIcon size={config.iconSize} />}\n </div>\n <div style={textContainerStyle}>\n <span style={primaryTextStyle}>\n {isDragOver ? 'Drop files here' : (\n <>\n <span style={browseStyle}>Click to browse</span> or drag files here\n </>\n )}\n </span>\n {description && <span style={secondaryTextStyle}>{description}</span>}\n </div>\n </div>\n {error && <span style={errorStyle}>{error}</span>}\n <input\n ref={(node) => {\n (inputRef as React.MutableRefObject<HTMLInputElement | null>).current = node\n if (typeof ref === 'function') ref(node)\n else if (ref) ref.current = node\n }}\n type=\"file\"\n accept={accept}\n multiple={multiple}\n disabled={disabled}\n onChange={handleChange}\n style={{ display: 'none' }}\n data-testid={testId}\n {...props}\n />\n </div>\n )\n})\n\nFileInput.displayName = 'FileInput'\n"],"names":["sizeConfig","UploadIcon","size","jsx","FileInput","forwardRef","variant","accept","multiple","maxSize","label","description","error","isInvalid","onChange","icon","disabled","className","style","testId","props","ref","isDragOver","setIsDragOver","useState","isFocused","setIsFocused","inputRef","useRef","config","hasError","handleFiles","useCallback","fileList","files","file","handleDragOver","handleDragLeave","handleDrop","handleChange","handleClick","handleKeyDown","containerStyle","labelStyle","dropzoneStyle","iconContainerStyle","textContainerStyle","primaryTextStyle","secondaryTextStyle","browseStyle","errorStyle","defaultDescription","jsxs","cx","Fragment","node"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"FileInput.cjs","sources":["../../../../src/components/form/FileInput/FileInput.tsx"],"sourcesContent":["/**\n * FileInput Component\n *\n * Accessible file upload input with drag-and-drop support.\n * Supports multiple files and file type restrictions.\n */\n\nimport {\n forwardRef,\n useState,\n useRef,\n useCallback,\n type CSSProperties,\n type InputHTMLAttributes,\n type DragEvent,\n type ReactNode,\n} from 'react'\nimport { cx } from '../../../utils/styles'\n\nexport type FileInputSize = 'sm' | 'md' | 'lg'\nexport type FileInputVariant = 'default' | 'dropzone'\n\nexport interface FileInputProps\n extends Omit<InputHTMLAttributes<HTMLInputElement>, 'size' | 'type' | 'onChange' | 'value'> {\n /** Input size */\n size?: FileInputSize\n /** Input variant */\n variant?: FileInputVariant\n /** Accepted file types (e.g., \"image/*,.pdf\") */\n accept?: string\n /** Whether multiple files can be selected */\n multiple?: boolean\n /** Maximum file size in bytes */\n maxSize?: number\n /** Label text */\n label?: ReactNode\n /** Description text inside dropzone */\n description?: ReactNode\n /** Error message */\n error?: ReactNode\n /** Whether the input is invalid */\n isInvalid?: boolean\n /** Callback when files are selected */\n onChange?: (files: File[]) => void\n /** Icon to display in dropzone */\n icon?: ReactNode\n /** Custom class name */\n className?: string\n /** Test ID */\n testId?: string\n}\n\nconst sizeConfig: Record<FileInputSize, { height: number; fontSize: number; padding: number; iconSize: number }> = {\n sm: { height: 80, fontSize: 12, padding: 16, iconSize: 24 },\n md: { height: 120, fontSize: 14, padding: 24, iconSize: 32 },\n lg: { height: 160, fontSize: 16, padding: 32, iconSize: 40 },\n}\n\nfunction UploadIcon({ size }: { size: number }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.5\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12\" />\n </svg>\n )\n}\n\nexport const FileInput = forwardRef<HTMLInputElement, FileInputProps>(function FileInput(\n {\n size = 'md',\n variant = 'dropzone',\n accept,\n multiple = false,\n maxSize,\n label,\n description,\n error,\n isInvalid = false,\n onChange,\n icon,\n disabled = false,\n className,\n style,\n testId,\n ...props\n },\n ref\n) {\n const [isDragOver, setIsDragOver] = useState(false)\n const [isFocused, setIsFocused] = useState(false)\n const inputRef = useRef<HTMLInputElement>(null)\n const config = sizeConfig[size]\n const hasError = isInvalid || !!error\n\n const handleFiles = useCallback(\n (fileList: FileList | null) => {\n if (!fileList || fileList.length === 0) return\n\n let files = Array.from(fileList)\n\n // Filter by max size if specified\n if (maxSize) {\n files = files.filter((file) => file.size <= maxSize)\n }\n\n // If not multiple, only take first file\n if (!multiple && files.length > 1) {\n files = [files[0]]\n }\n\n onChange?.(files)\n },\n [maxSize, multiple, onChange]\n )\n\n const handleDragOver = useCallback((e: DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n if (!disabled) {\n setIsDragOver(true)\n }\n }, [disabled])\n\n const handleDragLeave = useCallback((e: DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n setIsDragOver(false)\n }, [])\n\n const handleDrop = useCallback(\n (e: DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n setIsDragOver(false)\n\n if (!disabled) {\n handleFiles(e.dataTransfer.files)\n }\n },\n [disabled, handleFiles]\n )\n\n const handleChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n handleFiles(e.target.files)\n // Reset input value to allow selecting the same file again\n if (inputRef.current) {\n inputRef.current.value = ''\n }\n },\n [handleFiles]\n )\n\n const handleClick = useCallback(() => {\n if (!disabled) {\n inputRef.current?.click()\n }\n }, [disabled])\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if ((e.key === 'Enter' || e.key === ' ') && !disabled) {\n e.preventDefault()\n inputRef.current?.click()\n }\n },\n [disabled]\n )\n\n const containerStyle: CSSProperties = {\n display: 'flex',\n flexDirection: 'column',\n gap: 6,\n ...style,\n }\n\n const labelStyle: CSSProperties = {\n fontSize: config.fontSize,\n fontWeight: 500,\n color: 'var(--brycks-foreground-default)',\n }\n\n const dropzoneStyle: CSSProperties = {\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n gap: 8,\n minHeight: config.height,\n padding: config.padding,\n border: `2px dashed ${\n hasError\n ? 'var(--brycks-error-default)'\n : isDragOver\n ? 'var(--brycks-primary-default)'\n : isFocused\n ? 'var(--brycks-primary-default)'\n : 'var(--brycks-border-default)'\n }`,\n borderRadius: 'var(--brycks-radius-lg)',\n backgroundColor: isDragOver\n ? 'var(--brycks-primary-muted)'\n : 'var(--brycks-background-muted)',\n cursor: disabled ? 'not-allowed' : 'pointer',\n opacity: disabled ? 0.5 : 1,\n transition: 'all 150ms ease-out',\n outline: 'none',\n }\n\n const iconContainerStyle: CSSProperties = {\n color: isDragOver\n ? 'var(--brycks-primary-default)'\n : 'var(--brycks-foreground-muted)',\n transition: 'color 150ms ease-out',\n }\n\n const textContainerStyle: CSSProperties = {\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n gap: 4,\n textAlign: 'center',\n }\n\n const primaryTextStyle: CSSProperties = {\n fontSize: config.fontSize,\n fontWeight: 500,\n color: 'var(--brycks-foreground-default)',\n }\n\n const secondaryTextStyle: CSSProperties = {\n fontSize: config.fontSize - 2,\n color: 'var(--brycks-foreground-muted)',\n }\n\n const browseStyle: CSSProperties = {\n color: 'var(--brycks-primary-default)',\n fontWeight: 500,\n }\n\n const errorStyle: CSSProperties = {\n fontSize: config.fontSize - 2,\n color: 'var(--brycks-error-default)',\n }\n\n const defaultDescription = multiple\n ? 'Drag files here or click to browse'\n : 'Drag a file here or click to browse'\n\n return (\n <div\n className={cx('brycks-file-input', `brycks-file-input--${size}`, `brycks-file-input--${variant}`, className)}\n style={containerStyle}\n >\n {label && <label style={labelStyle}>{label}</label>}\n <div\n style={dropzoneStyle}\n onDragOver={handleDragOver}\n onDragLeave={handleDragLeave}\n onDrop={handleDrop}\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n onFocus={() => setIsFocused(true)}\n onBlur={() => setIsFocused(false)}\n tabIndex={disabled ? -1 : 0}\n role=\"button\"\n aria-label={String(description) || defaultDescription}\n >\n <div style={iconContainerStyle}>\n {icon || <UploadIcon size={config.iconSize} />}\n </div>\n <div style={textContainerStyle}>\n <span style={primaryTextStyle}>\n {isDragOver ? 'Drop files here' : (\n <>\n <span style={browseStyle}>Click to browse</span> or drag files here\n </>\n )}\n </span>\n {description && <span style={secondaryTextStyle}>{description}</span>}\n </div>\n </div>\n {error && <span style={errorStyle}>{error}</span>}\n <input\n ref={(node) => {\n (inputRef as React.MutableRefObject<HTMLInputElement | null>).current = node\n if (typeof ref === 'function') ref(node)\n else if (ref) ref.current = node\n }}\n type=\"file\"\n accept={accept}\n multiple={multiple}\n disabled={disabled}\n onChange={handleChange}\n style={{ display: 'none' }}\n data-testid={testId}\n {...props}\n />\n </div>\n )\n})\n\nFileInput.displayName = 'FileInput'\n"],"names":["sizeConfig","UploadIcon","size","jsx","FileInput","forwardRef","variant","accept","multiple","maxSize","label","description","error","isInvalid","onChange","icon","disabled","className","style","testId","props","ref","isDragOver","setIsDragOver","useState","isFocused","setIsFocused","inputRef","useRef","config","hasError","handleFiles","useCallback","fileList","files","file","handleDragOver","handleDragLeave","handleDrop","handleChange","handleClick","handleKeyDown","containerStyle","labelStyle","dropzoneStyle","iconContainerStyle","textContainerStyle","primaryTextStyle","secondaryTextStyle","browseStyle","errorStyle","defaultDescription","jsxs","cx","Fragment","node"],"mappings":"+KAoDMA,EAA6G,CACjH,GAAI,CAAE,OAAQ,GAAI,SAAU,GAAI,QAAS,GAAI,SAAU,EAAA,EACvD,GAAI,CAAE,OAAQ,IAAK,SAAU,GAAI,QAAS,GAAI,SAAU,EAAA,EACxD,GAAI,CAAE,OAAQ,IAAK,SAAU,GAAI,QAAS,GAAI,SAAU,EAAA,CAC1D,EAEA,SAASC,EAAW,CAAE,KAAAC,GAA0B,CAC9C,OACEC,MAAC,OAAI,MAAOD,EAAM,OAAQA,EAAM,QAAQ,YAAY,KAAK,OAAO,OAAO,eAAe,YAAY,MAChG,eAAC,OAAA,CAAK,cAAc,QAAQ,eAAe,QAAQ,EAAE,uFAAA,CAAwF,CAAA,CAC/I,CAEJ,CAEO,MAAME,EAAYC,EAAAA,WAA6C,SACpE,CACE,KAAAH,EAAO,KACP,QAAAI,EAAU,WACV,OAAAC,EACA,SAAAC,EAAW,GACX,QAAAC,EACA,MAAAC,EACA,YAAAC,EACA,MAAAC,EACA,UAAAC,EAAY,GACZ,SAAAC,EACA,KAAAC,EACA,SAAAC,EAAW,GACX,UAAAC,EACA,MAAAC,EACA,OAAAC,EACA,GAAGC,CACL,EACAC,EACA,CACA,KAAM,CAACC,EAAYC,CAAa,EAAIC,EAAAA,SAAS,EAAK,EAC5C,CAACC,EAAWC,CAAY,EAAIF,EAAAA,SAAS,EAAK,EAC1CG,EAAWC,EAAAA,OAAyB,IAAI,EACxCC,EAAS7B,EAAWE,CAAI,EACxB4B,EAAWjB,GAAa,CAAC,CAACD,EAE1BmB,EAAcC,EAAAA,YACjBC,GAA8B,CAC7B,GAAI,CAACA,GAAYA,EAAS,SAAW,EAAG,OAExC,IAAIC,EAAQ,MAAM,KAAKD,CAAQ,EAG3BxB,IACFyB,EAAQA,EAAM,OAAQC,GAASA,EAAK,MAAQ1B,CAAO,GAIjD,CAACD,GAAY0B,EAAM,OAAS,IAC9BA,EAAQ,CAACA,EAAM,CAAC,CAAC,GAGnBpB,IAAWoB,CAAK,CAClB,EACA,CAACzB,EAASD,EAAUM,CAAQ,CAAA,EAGxBsB,EAAiBJ,cAAa,GAAiB,CACnD,EAAE,eAAA,EACF,EAAE,gBAAA,EACGhB,GACHO,EAAc,EAAI,CAEtB,EAAG,CAACP,CAAQ,CAAC,EAEPqB,EAAkBL,cAAa,GAAiB,CACpD,EAAE,eAAA,EACF,EAAE,gBAAA,EACFT,EAAc,EAAK,CACrB,EAAG,CAAA,CAAE,EAECe,EAAaN,EAAAA,YAChB,GAAiB,CAChB,EAAE,eAAA,EACF,EAAE,gBAAA,EACFT,EAAc,EAAK,EAEdP,GACHe,EAAY,EAAE,aAAa,KAAK,CAEpC,EACA,CAACf,EAAUe,CAAW,CAAA,EAGlBQ,EAAeP,EAAAA,YAClB,GAA2C,CAC1CD,EAAY,EAAE,OAAO,KAAK,EAEtBJ,EAAS,UACXA,EAAS,QAAQ,MAAQ,GAE7B,EACA,CAACI,CAAW,CAAA,EAGRS,EAAcR,EAAAA,YAAY,IAAM,CAC/BhB,GACHW,EAAS,SAAS,MAAA,CAEtB,EAAG,CAACX,CAAQ,CAAC,EAEPyB,EAAgBT,EAAAA,YACnB,GAA2B,EACrB,EAAE,MAAQ,SAAW,EAAE,MAAQ,MAAQ,CAAChB,IAC3C,EAAE,eAAA,EACFW,EAAS,SAAS,MAAA,EAEtB,EACA,CAACX,CAAQ,CAAA,EAGL0B,EAAgC,CACpC,QAAS,OACT,cAAe,SACf,IAAK,EACL,GAAGxB,CAAA,EAGCyB,EAA4B,CAChC,SAAUd,EAAO,SACjB,WAAY,IACZ,MAAO,kCAAA,EAGHe,EAA+B,CACnC,QAAS,OACT,cAAe,SACf,WAAY,SACZ,eAAgB,SAChB,IAAK,EACL,UAAWf,EAAO,OAClB,QAASA,EAAO,QAChB,OAAQ,cACNC,EACI,8BACAR,GAEAG,EADA,gCAGA,8BACN,GACA,aAAc,0BACd,gBAAiBH,EACb,8BACA,iCACJ,OAAQN,EAAW,cAAgB,UACnC,QAASA,EAAW,GAAM,EAC1B,WAAY,qBACZ,QAAS,MAAA,EAGL6B,EAAoC,CACxC,MAAOvB,EACH,gCACA,iCACJ,WAAY,sBAAA,EAGRwB,EAAoC,CACxC,QAAS,OACT,cAAe,SACf,WAAY,SACZ,IAAK,EACL,UAAW,QAAA,EAGPC,EAAkC,CACtC,SAAUlB,EAAO,SACjB,WAAY,IACZ,MAAO,kCAAA,EAGHmB,EAAoC,CACxC,SAAUnB,EAAO,SAAW,EAC5B,MAAO,gCAAA,EAGHoB,EAA6B,CACjC,MAAO,gCACP,WAAY,GAAA,EAGRC,EAA4B,CAChC,SAAUrB,EAAO,SAAW,EAC5B,MAAO,6BAAA,EAGHsB,EAAqB3C,EACvB,qCACA,sCAEJ,OACE4C,EAAAA,KAAC,MAAA,CACC,UAAWC,EAAAA,GAAG,oBAAqB,sBAAsBnD,CAAI,GAAI,sBAAsBI,CAAO,GAAIW,CAAS,EAC3G,MAAOyB,EAEN,SAAA,CAAAhC,GAASP,EAAAA,IAAC,QAAA,CAAM,MAAOwC,EAAa,SAAAjC,EAAM,EAC3C0C,EAAAA,KAAC,MAAA,CACC,MAAOR,EACP,WAAYR,EACZ,YAAaC,EACb,OAAQC,EACR,QAASE,EACT,UAAWC,EACX,QAAS,IAAMf,EAAa,EAAI,EAChC,OAAQ,IAAMA,EAAa,EAAK,EAChC,SAAUV,EAAW,GAAK,EAC1B,KAAK,SACL,aAAY,OAAOL,CAAW,GAAKwC,EAEnC,SAAA,CAAAhD,EAAAA,IAAC,MAAA,CAAI,MAAO0C,EACT,SAAA9B,SAASd,EAAA,CAAW,KAAM4B,EAAO,QAAA,CAAU,CAAA,CAC9C,EACAuB,EAAAA,KAAC,MAAA,CAAI,MAAON,EACV,SAAA,CAAA3C,EAAAA,IAAC,OAAA,CAAK,MAAO4C,EACV,SAAAzB,EAAa,kBACZ8B,EAAAA,KAAAE,EAAAA,SAAA,CACE,SAAA,CAAAnD,EAAAA,IAAC,OAAA,CAAK,MAAO8C,EAAa,SAAA,kBAAe,EAAO,qBAAA,CAAA,CAClD,CAAA,CAEJ,EACCtC,GAAeR,EAAAA,IAAC,OAAA,CAAK,MAAO6C,EAAqB,SAAArC,CAAA,CAAY,CAAA,CAAA,CAChE,CAAA,CAAA,CAAA,EAEDC,GAAST,EAAAA,IAAC,OAAA,CAAK,MAAO+C,EAAa,SAAAtC,EAAM,EAC1CT,EAAAA,IAAC,QAAA,CACC,IAAMoD,GAAS,CACZ5B,EAA6D,QAAU4B,EACpE,OAAOlC,GAAQ,WAAYA,EAAIkC,CAAI,EAC9BlC,MAAS,QAAUkC,EAC9B,EACA,KAAK,OACL,OAAAhD,EACA,SAAAC,EACA,SAAAQ,EACA,SAAUuB,EACV,MAAO,CAAE,QAAS,MAAA,EAClB,cAAapB,EACZ,GAAGC,CAAA,CAAA,CACN,CAAA,CAAA,CAGN,CAAC,EAEDhB,EAAU,YAAc"}
|
|
@@ -74,7 +74,7 @@ const re = X(function({
|
|
|
74
74
|
padding: n.padding,
|
|
75
75
|
border: `2px dashed ${R ? "var(--brycks-error-default)" : c || O ? "var(--brycks-primary-default)" : "var(--brycks-border-default)"}`,
|
|
76
76
|
borderRadius: "var(--brycks-radius-lg)",
|
|
77
|
-
backgroundColor: c ? "var(--brycks-primary-
|
|
77
|
+
backgroundColor: c ? "var(--brycks-primary-muted)" : "var(--brycks-background-muted)",
|
|
78
78
|
cursor: r ? "not-allowed" : "pointer",
|
|
79
79
|
opacity: r ? 0.5 : 1,
|
|
80
80
|
transition: "all 150ms ease-out",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FileInput.js","sources":["../../../../src/components/form/FileInput/FileInput.tsx"],"sourcesContent":["/**\n * FileInput Component\n *\n * Accessible file upload input with drag-and-drop support.\n * Supports multiple files and file type restrictions.\n */\n\nimport {\n forwardRef,\n useState,\n useRef,\n useCallback,\n type CSSProperties,\n type InputHTMLAttributes,\n type DragEvent,\n type ReactNode,\n} from 'react'\nimport { cx } from '../../../utils/styles'\n\nexport type FileInputSize = 'sm' | 'md' | 'lg'\nexport type FileInputVariant = 'default' | 'dropzone'\n\nexport interface FileInputProps\n extends Omit<InputHTMLAttributes<HTMLInputElement>, 'size' | 'type' | 'onChange' | 'value'> {\n /** Input size */\n size?: FileInputSize\n /** Input variant */\n variant?: FileInputVariant\n /** Accepted file types (e.g., \"image/*,.pdf\") */\n accept?: string\n /** Whether multiple files can be selected */\n multiple?: boolean\n /** Maximum file size in bytes */\n maxSize?: number\n /** Label text */\n label?: ReactNode\n /** Description text inside dropzone */\n description?: ReactNode\n /** Error message */\n error?: ReactNode\n /** Whether the input is invalid */\n isInvalid?: boolean\n /** Callback when files are selected */\n onChange?: (files: File[]) => void\n /** Icon to display in dropzone */\n icon?: ReactNode\n /** Custom class name */\n className?: string\n /** Test ID */\n testId?: string\n}\n\nconst sizeConfig: Record<FileInputSize, { height: number; fontSize: number; padding: number; iconSize: number }> = {\n sm: { height: 80, fontSize: 12, padding: 16, iconSize: 24 },\n md: { height: 120, fontSize: 14, padding: 24, iconSize: 32 },\n lg: { height: 160, fontSize: 16, padding: 32, iconSize: 40 },\n}\n\nfunction UploadIcon({ size }: { size: number }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.5\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12\" />\n </svg>\n )\n}\n\nexport const FileInput = forwardRef<HTMLInputElement, FileInputProps>(function FileInput(\n {\n size = 'md',\n variant = 'dropzone',\n accept,\n multiple = false,\n maxSize,\n label,\n description,\n error,\n isInvalid = false,\n onChange,\n icon,\n disabled = false,\n className,\n style,\n testId,\n ...props\n },\n ref\n) {\n const [isDragOver, setIsDragOver] = useState(false)\n const [isFocused, setIsFocused] = useState(false)\n const inputRef = useRef<HTMLInputElement>(null)\n const config = sizeConfig[size]\n const hasError = isInvalid || !!error\n\n const handleFiles = useCallback(\n (fileList: FileList | null) => {\n if (!fileList || fileList.length === 0) return\n\n let files = Array.from(fileList)\n\n // Filter by max size if specified\n if (maxSize) {\n files = files.filter((file) => file.size <= maxSize)\n }\n\n // If not multiple, only take first file\n if (!multiple && files.length > 1) {\n files = [files[0]]\n }\n\n onChange?.(files)\n },\n [maxSize, multiple, onChange]\n )\n\n const handleDragOver = useCallback((e: DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n if (!disabled) {\n setIsDragOver(true)\n }\n }, [disabled])\n\n const handleDragLeave = useCallback((e: DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n setIsDragOver(false)\n }, [])\n\n const handleDrop = useCallback(\n (e: DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n setIsDragOver(false)\n\n if (!disabled) {\n handleFiles(e.dataTransfer.files)\n }\n },\n [disabled, handleFiles]\n )\n\n const handleChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n handleFiles(e.target.files)\n // Reset input value to allow selecting the same file again\n if (inputRef.current) {\n inputRef.current.value = ''\n }\n },\n [handleFiles]\n )\n\n const handleClick = useCallback(() => {\n if (!disabled) {\n inputRef.current?.click()\n }\n }, [disabled])\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if ((e.key === 'Enter' || e.key === ' ') && !disabled) {\n e.preventDefault()\n inputRef.current?.click()\n }\n },\n [disabled]\n )\n\n const containerStyle: CSSProperties = {\n display: 'flex',\n flexDirection: 'column',\n gap: 6,\n ...style,\n }\n\n const labelStyle: CSSProperties = {\n fontSize: config.fontSize,\n fontWeight: 500,\n color: 'var(--brycks-foreground-default)',\n }\n\n const dropzoneStyle: CSSProperties = {\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n gap: 8,\n minHeight: config.height,\n padding: config.padding,\n border: `2px dashed ${\n hasError\n ? 'var(--brycks-error-default)'\n : isDragOver\n ? 'var(--brycks-primary-default)'\n : isFocused\n ? 'var(--brycks-primary-default)'\n : 'var(--brycks-border-default)'\n }`,\n borderRadius: 'var(--brycks-radius-lg)',\n backgroundColor: isDragOver\n ? 'var(--brycks-primary-50)'\n : 'var(--brycks-background-muted)',\n cursor: disabled ? 'not-allowed' : 'pointer',\n opacity: disabled ? 0.5 : 1,\n transition: 'all 150ms ease-out',\n outline: 'none',\n }\n\n const iconContainerStyle: CSSProperties = {\n color: isDragOver\n ? 'var(--brycks-primary-default)'\n : 'var(--brycks-foreground-muted)',\n transition: 'color 150ms ease-out',\n }\n\n const textContainerStyle: CSSProperties = {\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n gap: 4,\n textAlign: 'center',\n }\n\n const primaryTextStyle: CSSProperties = {\n fontSize: config.fontSize,\n fontWeight: 500,\n color: 'var(--brycks-foreground-default)',\n }\n\n const secondaryTextStyle: CSSProperties = {\n fontSize: config.fontSize - 2,\n color: 'var(--brycks-foreground-muted)',\n }\n\n const browseStyle: CSSProperties = {\n color: 'var(--brycks-primary-default)',\n fontWeight: 500,\n }\n\n const errorStyle: CSSProperties = {\n fontSize: config.fontSize - 2,\n color: 'var(--brycks-error-default)',\n }\n\n const defaultDescription = multiple\n ? 'Drag files here or click to browse'\n : 'Drag a file here or click to browse'\n\n return (\n <div\n className={cx('brycks-file-input', `brycks-file-input--${size}`, `brycks-file-input--${variant}`, className)}\n style={containerStyle}\n >\n {label && <label style={labelStyle}>{label}</label>}\n <div\n style={dropzoneStyle}\n onDragOver={handleDragOver}\n onDragLeave={handleDragLeave}\n onDrop={handleDrop}\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n onFocus={() => setIsFocused(true)}\n onBlur={() => setIsFocused(false)}\n tabIndex={disabled ? -1 : 0}\n role=\"button\"\n aria-label={String(description) || defaultDescription}\n >\n <div style={iconContainerStyle}>\n {icon || <UploadIcon size={config.iconSize} />}\n </div>\n <div style={textContainerStyle}>\n <span style={primaryTextStyle}>\n {isDragOver ? 'Drop files here' : (\n <>\n <span style={browseStyle}>Click to browse</span> or drag files here\n </>\n )}\n </span>\n {description && <span style={secondaryTextStyle}>{description}</span>}\n </div>\n </div>\n {error && <span style={errorStyle}>{error}</span>}\n <input\n ref={(node) => {\n (inputRef as React.MutableRefObject<HTMLInputElement | null>).current = node\n if (typeof ref === 'function') ref(node)\n else if (ref) ref.current = node\n }}\n type=\"file\"\n accept={accept}\n multiple={multiple}\n disabled={disabled}\n onChange={handleChange}\n style={{ display: 'none' }}\n data-testid={testId}\n {...props}\n />\n </div>\n )\n})\n\nFileInput.displayName = 'FileInput'\n"],"names":["sizeConfig","UploadIcon","size","jsx","FileInput","forwardRef","variant","accept","multiple","maxSize","label","description","error","isInvalid","onChange","icon","disabled","className","style","testId","props","ref","isDragOver","setIsDragOver","useState","isFocused","setIsFocused","inputRef","useRef","config","hasError","handleFiles","useCallback","fileList","files","file","handleDragOver","handleDragLeave","handleDrop","handleChange","handleClick","handleKeyDown","containerStyle","labelStyle","dropzoneStyle","iconContainerStyle","textContainerStyle","primaryTextStyle","secondaryTextStyle","browseStyle","errorStyle","defaultDescription","jsxs","cx","Fragment","node"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"FileInput.js","sources":["../../../../src/components/form/FileInput/FileInput.tsx"],"sourcesContent":["/**\n * FileInput Component\n *\n * Accessible file upload input with drag-and-drop support.\n * Supports multiple files and file type restrictions.\n */\n\nimport {\n forwardRef,\n useState,\n useRef,\n useCallback,\n type CSSProperties,\n type InputHTMLAttributes,\n type DragEvent,\n type ReactNode,\n} from 'react'\nimport { cx } from '../../../utils/styles'\n\nexport type FileInputSize = 'sm' | 'md' | 'lg'\nexport type FileInputVariant = 'default' | 'dropzone'\n\nexport interface FileInputProps\n extends Omit<InputHTMLAttributes<HTMLInputElement>, 'size' | 'type' | 'onChange' | 'value'> {\n /** Input size */\n size?: FileInputSize\n /** Input variant */\n variant?: FileInputVariant\n /** Accepted file types (e.g., \"image/*,.pdf\") */\n accept?: string\n /** Whether multiple files can be selected */\n multiple?: boolean\n /** Maximum file size in bytes */\n maxSize?: number\n /** Label text */\n label?: ReactNode\n /** Description text inside dropzone */\n description?: ReactNode\n /** Error message */\n error?: ReactNode\n /** Whether the input is invalid */\n isInvalid?: boolean\n /** Callback when files are selected */\n onChange?: (files: File[]) => void\n /** Icon to display in dropzone */\n icon?: ReactNode\n /** Custom class name */\n className?: string\n /** Test ID */\n testId?: string\n}\n\nconst sizeConfig: Record<FileInputSize, { height: number; fontSize: number; padding: number; iconSize: number }> = {\n sm: { height: 80, fontSize: 12, padding: 16, iconSize: 24 },\n md: { height: 120, fontSize: 14, padding: 24, iconSize: 32 },\n lg: { height: 160, fontSize: 16, padding: 32, iconSize: 40 },\n}\n\nfunction UploadIcon({ size }: { size: number }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.5\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12\" />\n </svg>\n )\n}\n\nexport const FileInput = forwardRef<HTMLInputElement, FileInputProps>(function FileInput(\n {\n size = 'md',\n variant = 'dropzone',\n accept,\n multiple = false,\n maxSize,\n label,\n description,\n error,\n isInvalid = false,\n onChange,\n icon,\n disabled = false,\n className,\n style,\n testId,\n ...props\n },\n ref\n) {\n const [isDragOver, setIsDragOver] = useState(false)\n const [isFocused, setIsFocused] = useState(false)\n const inputRef = useRef<HTMLInputElement>(null)\n const config = sizeConfig[size]\n const hasError = isInvalid || !!error\n\n const handleFiles = useCallback(\n (fileList: FileList | null) => {\n if (!fileList || fileList.length === 0) return\n\n let files = Array.from(fileList)\n\n // Filter by max size if specified\n if (maxSize) {\n files = files.filter((file) => file.size <= maxSize)\n }\n\n // If not multiple, only take first file\n if (!multiple && files.length > 1) {\n files = [files[0]]\n }\n\n onChange?.(files)\n },\n [maxSize, multiple, onChange]\n )\n\n const handleDragOver = useCallback((e: DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n if (!disabled) {\n setIsDragOver(true)\n }\n }, [disabled])\n\n const handleDragLeave = useCallback((e: DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n setIsDragOver(false)\n }, [])\n\n const handleDrop = useCallback(\n (e: DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n setIsDragOver(false)\n\n if (!disabled) {\n handleFiles(e.dataTransfer.files)\n }\n },\n [disabled, handleFiles]\n )\n\n const handleChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n handleFiles(e.target.files)\n // Reset input value to allow selecting the same file again\n if (inputRef.current) {\n inputRef.current.value = ''\n }\n },\n [handleFiles]\n )\n\n const handleClick = useCallback(() => {\n if (!disabled) {\n inputRef.current?.click()\n }\n }, [disabled])\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if ((e.key === 'Enter' || e.key === ' ') && !disabled) {\n e.preventDefault()\n inputRef.current?.click()\n }\n },\n [disabled]\n )\n\n const containerStyle: CSSProperties = {\n display: 'flex',\n flexDirection: 'column',\n gap: 6,\n ...style,\n }\n\n const labelStyle: CSSProperties = {\n fontSize: config.fontSize,\n fontWeight: 500,\n color: 'var(--brycks-foreground-default)',\n }\n\n const dropzoneStyle: CSSProperties = {\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n gap: 8,\n minHeight: config.height,\n padding: config.padding,\n border: `2px dashed ${\n hasError\n ? 'var(--brycks-error-default)'\n : isDragOver\n ? 'var(--brycks-primary-default)'\n : isFocused\n ? 'var(--brycks-primary-default)'\n : 'var(--brycks-border-default)'\n }`,\n borderRadius: 'var(--brycks-radius-lg)',\n backgroundColor: isDragOver\n ? 'var(--brycks-primary-muted)'\n : 'var(--brycks-background-muted)',\n cursor: disabled ? 'not-allowed' : 'pointer',\n opacity: disabled ? 0.5 : 1,\n transition: 'all 150ms ease-out',\n outline: 'none',\n }\n\n const iconContainerStyle: CSSProperties = {\n color: isDragOver\n ? 'var(--brycks-primary-default)'\n : 'var(--brycks-foreground-muted)',\n transition: 'color 150ms ease-out',\n }\n\n const textContainerStyle: CSSProperties = {\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n gap: 4,\n textAlign: 'center',\n }\n\n const primaryTextStyle: CSSProperties = {\n fontSize: config.fontSize,\n fontWeight: 500,\n color: 'var(--brycks-foreground-default)',\n }\n\n const secondaryTextStyle: CSSProperties = {\n fontSize: config.fontSize - 2,\n color: 'var(--brycks-foreground-muted)',\n }\n\n const browseStyle: CSSProperties = {\n color: 'var(--brycks-primary-default)',\n fontWeight: 500,\n }\n\n const errorStyle: CSSProperties = {\n fontSize: config.fontSize - 2,\n color: 'var(--brycks-error-default)',\n }\n\n const defaultDescription = multiple\n ? 'Drag files here or click to browse'\n : 'Drag a file here or click to browse'\n\n return (\n <div\n className={cx('brycks-file-input', `brycks-file-input--${size}`, `brycks-file-input--${variant}`, className)}\n style={containerStyle}\n >\n {label && <label style={labelStyle}>{label}</label>}\n <div\n style={dropzoneStyle}\n onDragOver={handleDragOver}\n onDragLeave={handleDragLeave}\n onDrop={handleDrop}\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n onFocus={() => setIsFocused(true)}\n onBlur={() => setIsFocused(false)}\n tabIndex={disabled ? -1 : 0}\n role=\"button\"\n aria-label={String(description) || defaultDescription}\n >\n <div style={iconContainerStyle}>\n {icon || <UploadIcon size={config.iconSize} />}\n </div>\n <div style={textContainerStyle}>\n <span style={primaryTextStyle}>\n {isDragOver ? 'Drop files here' : (\n <>\n <span style={browseStyle}>Click to browse</span> or drag files here\n </>\n )}\n </span>\n {description && <span style={secondaryTextStyle}>{description}</span>}\n </div>\n </div>\n {error && <span style={errorStyle}>{error}</span>}\n <input\n ref={(node) => {\n (inputRef as React.MutableRefObject<HTMLInputElement | null>).current = node\n if (typeof ref === 'function') ref(node)\n else if (ref) ref.current = node\n }}\n type=\"file\"\n accept={accept}\n multiple={multiple}\n disabled={disabled}\n onChange={handleChange}\n style={{ display: 'none' }}\n data-testid={testId}\n {...props}\n />\n </div>\n )\n})\n\nFileInput.displayName = 'FileInput'\n"],"names":["sizeConfig","UploadIcon","size","jsx","FileInput","forwardRef","variant","accept","multiple","maxSize","label","description","error","isInvalid","onChange","icon","disabled","className","style","testId","props","ref","isDragOver","setIsDragOver","useState","isFocused","setIsFocused","inputRef","useRef","config","hasError","handleFiles","useCallback","fileList","files","file","handleDragOver","handleDragLeave","handleDrop","handleChange","handleClick","handleKeyDown","containerStyle","labelStyle","dropzoneStyle","iconContainerStyle","textContainerStyle","primaryTextStyle","secondaryTextStyle","browseStyle","errorStyle","defaultDescription","jsxs","cx","Fragment","node"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("react/jsx-runtime"),h=require("react"),p=require("../../../utils/styles.cjs"),x={neutral:"var(--brycks-background-muted)",primary:"var(--brycks-primary-muted)",success:"var(--brycks-success-muted)",warning:"var(--brycks-warning-muted)",error:"var(--brycks-error-muted)",info:"var(--brycks-info-muted)"},
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("react/jsx-runtime"),h=require("react"),p=require("../../../utils/styles.cjs"),x={neutral:"var(--brycks-background-muted)",primary:"var(--brycks-primary-muted)",success:"var(--brycks-success-muted)",warning:"var(--brycks-warning-muted)",error:"var(--brycks-error-muted)",info:"var(--brycks-info-muted)"},a=h.forwardRef(function({title:e,icon:s,iconIntent:d="primary",headerExtra:t,children:c,className:o,style:n,testId:i,...l},y){const m={background:"var(--brycks-background-elevated)",borderRadius:"var(--brycks-radius-lg)",border:"1px solid var(--brycks-border-muted)",overflow:"hidden",...n},b={display:"flex",alignItems:"center",justifyContent:"space-between",padding:"16px 20px",borderBottom:"1px solid var(--brycks-border-muted)"},u={display:"flex",alignItems:"center",gap:12},f={width:32,height:32,borderRadius:"50%",background:x[d],display:"flex",alignItems:"center",justifyContent:"center",flexShrink:0},k={fontFamily:"var(--brycks-font-sans)",fontSize:"var(--brycks-font-size-md)",fontWeight:600,color:"var(--brycks-foreground-default)",lineHeight:1.4,margin:0},v={padding:20},g=e||s||t;return r.jsxs("div",{ref:y,className:p.cx("brycks-form-card",o),style:m,"data-testid":i,...l,children:[g&&r.jsxs("div",{className:"brycks-form-card__header",style:b,children:[r.jsxs("div",{style:u,children:[s&&r.jsx("div",{className:"brycks-form-card__icon",style:f,children:s}),e&&r.jsx("h3",{className:"brycks-form-card__title",style:k,children:e})]}),t&&r.jsx("div",{className:"brycks-form-card__header-extra",children:t})]}),r.jsx("div",{className:"brycks-form-card__body",style:v,children:c})]})});a.displayName="FormCard";exports.FormCard=a;
|
|
2
2
|
//# sourceMappingURL=FormCard.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FormCard.cjs","sources":["../../../../src/components/form/FormCard/FormCard.tsx"],"sourcesContent":["/**\n * FormCard Component\n *\n * Card wrapper optimized for form sections with optional icon and title.\n * Provides consistent spacing and visual hierarchy for form layouts.\n */\n\nimport {\n forwardRef,\n type CSSProperties,\n type ReactNode,\n type HTMLAttributes,\n} from 'react'\nimport { cx } from '../../../utils/styles'\n\nexport type FormCardIntent = 'neutral' | 'primary' | 'success' | 'warning' | 'error' | 'info'\n\nexport interface FormCardProps extends HTMLAttributes<HTMLDivElement> {\n /** Card title */\n title?: string\n /** Icon displayed before title */\n icon?: ReactNode\n /** Color intent for the icon circle */\n iconIntent?: FormCardIntent\n /** Additional content in the header (e.g., counter, badge) */\n headerExtra?: ReactNode\n /** Card body content */\n children?: ReactNode\n /** Custom class name */\n className?: string\n /** Test ID */\n testId?: string\n}\n\nconst intentColors: Record<FormCardIntent, string> = {\n neutral: 'var(--brycks-background-muted)',\n primary: 'var(--brycks-primary-muted)',\n success: 'var(--brycks-success-muted)',\n warning: 'var(--brycks-warning-muted)',\n error: 'var(--brycks-error-muted)',\n info: 'var(--brycks-info-muted)',\n}\n\nexport const FormCard = forwardRef<HTMLDivElement, FormCardProps>(\n function FormCard(\n {\n title,\n icon,\n iconIntent = 'primary',\n headerExtra,\n children,\n className,\n style,\n testId,\n ...props\n },\n ref\n ) {\n const cardStyle: CSSProperties = {\n background: 'var(--brycks-background-
|
|
1
|
+
{"version":3,"file":"FormCard.cjs","sources":["../../../../src/components/form/FormCard/FormCard.tsx"],"sourcesContent":["/**\n * FormCard Component\n *\n * Card wrapper optimized for form sections with optional icon and title.\n * Provides consistent spacing and visual hierarchy for form layouts.\n */\n\nimport {\n forwardRef,\n type CSSProperties,\n type ReactNode,\n type HTMLAttributes,\n} from 'react'\nimport { cx } from '../../../utils/styles'\n\nexport type FormCardIntent = 'neutral' | 'primary' | 'success' | 'warning' | 'error' | 'info'\n\nexport interface FormCardProps extends HTMLAttributes<HTMLDivElement> {\n /** Card title */\n title?: string\n /** Icon displayed before title */\n icon?: ReactNode\n /** Color intent for the icon circle */\n iconIntent?: FormCardIntent\n /** Additional content in the header (e.g., counter, badge) */\n headerExtra?: ReactNode\n /** Card body content */\n children?: ReactNode\n /** Custom class name */\n className?: string\n /** Test ID */\n testId?: string\n}\n\nconst intentColors: Record<FormCardIntent, string> = {\n neutral: 'var(--brycks-background-muted)',\n primary: 'var(--brycks-primary-muted)',\n success: 'var(--brycks-success-muted)',\n warning: 'var(--brycks-warning-muted)',\n error: 'var(--brycks-error-muted)',\n info: 'var(--brycks-info-muted)',\n}\n\nexport const FormCard = forwardRef<HTMLDivElement, FormCardProps>(\n function FormCard(\n {\n title,\n icon,\n iconIntent = 'primary',\n headerExtra,\n children,\n className,\n style,\n testId,\n ...props\n },\n ref\n ) {\n const cardStyle: CSSProperties = {\n background: 'var(--brycks-background-elevated)',\n borderRadius: 'var(--brycks-radius-lg)',\n border: '1px solid var(--brycks-border-muted)',\n overflow: 'hidden',\n ...style,\n }\n\n const headerStyle: CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: '16px 20px',\n borderBottom: '1px solid var(--brycks-border-muted)',\n }\n\n const headerLeftStyle: CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n gap: 12,\n }\n\n const iconCircleStyle: CSSProperties = {\n width: 32,\n height: 32,\n borderRadius: '50%',\n background: intentColors[iconIntent],\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n flexShrink: 0,\n }\n\n const titleStyle: CSSProperties = {\n fontFamily: 'var(--brycks-font-sans)',\n fontSize: 'var(--brycks-font-size-md)',\n fontWeight: 600,\n color: 'var(--brycks-foreground-default)',\n lineHeight: 1.4,\n margin: 0,\n }\n\n const bodyStyle: CSSProperties = {\n padding: 20,\n }\n\n const hasHeader = title || icon || headerExtra\n\n return (\n <div\n ref={ref}\n className={cx('brycks-form-card', className)}\n style={cardStyle}\n data-testid={testId}\n {...props}\n >\n {hasHeader && (\n <div className=\"brycks-form-card__header\" style={headerStyle}>\n <div style={headerLeftStyle}>\n {icon && (\n <div\n className=\"brycks-form-card__icon\"\n style={iconCircleStyle}\n >\n {icon}\n </div>\n )}\n {title && (\n <h3 className=\"brycks-form-card__title\" style={titleStyle}>\n {title}\n </h3>\n )}\n </div>\n {headerExtra && (\n <div className=\"brycks-form-card__header-extra\">\n {headerExtra}\n </div>\n )}\n </div>\n )}\n\n <div className=\"brycks-form-card__body\" style={bodyStyle}>\n {children}\n </div>\n </div>\n )\n }\n)\n\nFormCard.displayName = 'FormCard'\n"],"names":["intentColors","FormCard","forwardRef","title","icon","iconIntent","headerExtra","children","className","style","testId","props","ref","cardStyle","headerStyle","headerLeftStyle","iconCircleStyle","titleStyle","bodyStyle","hasHeader","jsxs","cx","jsx"],"mappings":"+KAkCMA,EAA+C,CACnD,QAAS,iCACT,QAAS,8BACT,QAAS,8BACT,QAAS,8BACT,MAAO,4BACP,KAAM,0BACR,EAEaC,EAAWC,EAAAA,WACtB,SACE,CACE,MAAAC,EACA,KAAAC,EACA,WAAAC,EAAa,UACb,YAAAC,EACA,SAAAC,EACA,UAAAC,EACA,MAAAC,EACA,OAAAC,EACA,GAAGC,CAAA,EAELC,EACA,CACA,MAAMC,EAA2B,CAC/B,WAAY,oCACZ,aAAc,0BACd,OAAQ,uCACR,SAAU,SACV,GAAGJ,CAAA,EAGCK,EAA6B,CACjC,QAAS,OACT,WAAY,SACZ,eAAgB,gBAChB,QAAS,YACT,aAAc,sCAAA,EAGVC,EAAiC,CACrC,QAAS,OACT,WAAY,SACZ,IAAK,EAAA,EAGDC,EAAiC,CACrC,MAAO,GACP,OAAQ,GACR,aAAc,MACd,WAAYhB,EAAaK,CAAU,EACnC,QAAS,OACT,WAAY,SACZ,eAAgB,SAChB,WAAY,CAAA,EAGRY,EAA4B,CAChC,WAAY,0BACZ,SAAU,6BACV,WAAY,IACZ,MAAO,mCACP,WAAY,IACZ,OAAQ,CAAA,EAGJC,EAA2B,CAC/B,QAAS,EAAA,EAGLC,EAAYhB,GAASC,GAAQE,EAEnC,OACEc,EAAAA,KAAC,MAAA,CACC,IAAAR,EACA,UAAWS,EAAAA,GAAG,mBAAoBb,CAAS,EAC3C,MAAOK,EACP,cAAaH,EACZ,GAAGC,EAEH,SAAA,CAAAQ,GACCC,EAAAA,KAAC,MAAA,CAAI,UAAU,2BAA2B,MAAON,EAC/C,SAAA,CAAAM,EAAAA,KAAC,MAAA,CAAI,MAAOL,EACT,SAAA,CAAAX,GACCkB,EAAAA,IAAC,MAAA,CACC,UAAU,yBACV,MAAON,EAEN,SAAAZ,CAAA,CAAA,EAGJD,GACCmB,EAAAA,IAAC,KAAA,CAAG,UAAU,0BAA0B,MAAOL,EAC5C,SAAAd,CAAA,CACH,CAAA,EAEJ,EACCG,GACCgB,EAAAA,IAAC,MAAA,CAAI,UAAU,iCACZ,SAAAhB,CAAA,CACH,CAAA,EAEJ,QAGD,MAAA,CAAI,UAAU,yBAAyB,MAAOY,EAC5C,SAAAX,CAAA,CACH,CAAA,CAAA,CAAA,CAGN,CACF,EAEAN,EAAS,YAAc"}
|