@xsolla/xui-calendar 0.227.0 → 0.228.0
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/README.md +33 -16
- package/native/index.d.mts +6 -0
- package/native/index.d.ts +6 -0
- package/native/index.js +125 -11
- package/native/index.js.map +1 -1
- package/native/index.mjs +145 -24
- package/native/index.mjs.map +1 -1
- package/package.json +7 -7
- package/web/index.d.mts +6 -0
- package/web/index.d.ts +6 -0
- package/web/index.js +125 -11
- package/web/index.js.map +1 -1
- package/web/index.mjs +145 -24
- package/web/index.mjs.map +1 -1
package/native/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/Calendar.tsx","../../../../foundation/primitives-native/src/Box.tsx","../../../../foundation/primitives-native/src/Text.tsx","../../src/CalendarHeader.tsx","../../src/utils.ts","../../src/CalendarGrid.tsx","../../src/CalendarChips.tsx","../../src/DualCalendar.tsx"],"sourcesContent":["import { forwardRef, useCallback, useEffect, useState } from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box } from \"@xsolla/xui-primitives\";\nimport { useResolvedTheme } from \"@xsolla/xui-core\";\nimport { addMonths, subDays, subMonths, startOfDay } from \"date-fns\";\nimport { CalendarHeader } from \"./CalendarHeader\";\nimport { CalendarGrid } from \"./CalendarGrid\";\nimport { CalendarChips } from \"./CalendarChips\";\nimport type { CalendarProps } from \"./types\";\n\nexport const Calendar = forwardRef<any, CalendarProps>(\n (\n {\n locale = \"enUS\",\n onChange,\n startDate,\n endDate,\n selectedDate,\n selectsRange = false,\n contextMenuMaxHeight,\n topContent,\n bottomContent,\n chips,\n activeChip,\n onChipSelect,\n testID,\n minDate,\n maxDate,\n firstDayOfWeek = 0,\n month,\n initialMonth,\n themeMode,\n themeProductContext,\n },\n ref\n ) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n\n const [currentMonth, setCurrentMonth] = useState<Date>(\n (month || initialMonth || selectedDate || startDate || new Date()) as Date\n );\n const [selectedStartDate, setSelectedStartDate] = useState<\n Date | null | undefined\n >(startDate);\n const [selectedEndDate, setSelectedEndDate] = useState<\n Date | null | undefined\n >(endDate);\n const [locSelectedDate, setLocSelectedDate] = useState<\n Date | null | undefined\n >(selectedDate);\n const [selectingRange, setSelectingRange] = useState<Date | null>(null);\n\n useEffect(() => {\n setSelectedStartDate(startDate);\n setSelectedEndDate(endDate);\n setLocSelectedDate(selectedDate);\n if (month !== undefined) {\n setCurrentMonth(month);\n }\n }, [startDate, endDate, selectedDate, month]);\n\n const handleChange = useCallback(\n (date: Date) => {\n const newDate = new Date(\n date.getFullYear(),\n date.getMonth(),\n date.getDate()\n );\n\n if (!selectsRange) {\n setLocSelectedDate(newDate);\n onChange?.(newDate);\n } else {\n if (!selectedStartDate || (selectedStartDate && selectedEndDate)) {\n setSelectedStartDate(newDate);\n setSelectedEndDate(null);\n setSelectingRange(newDate);\n onChange?.([newDate, null]);\n } else {\n const start =\n selectedStartDate < newDate ? selectedStartDate : newDate;\n const end =\n selectedStartDate < newDate ? newDate : selectedStartDate;\n setSelectedStartDate(start);\n setSelectedEndDate(end);\n setSelectingRange(null);\n onChange?.([start, end]);\n }\n }\n },\n [onChange, selectsRange, selectedStartDate, selectedEndDate]\n );\n\n const decreaseMonth = useCallback(\n () => setCurrentMonth((prev) => subMonths(prev, 1)),\n []\n );\n const increaseMonth = useCallback(\n () => setCurrentMonth((prev) => addMonths(prev, 1)),\n []\n );\n const changeMonth = useCallback(\n (m: number) =>\n setCurrentMonth((prev) => new Date(prev.getFullYear(), m, 1)),\n []\n );\n const changeYear = useCallback(\n (y: number) => setCurrentMonth((prev) => new Date(y, prev.getMonth(), 1)),\n []\n );\n\n const handleChipSelect = useCallback(\n (value: string | null) => {\n onChipSelect?.(value);\n\n const chip = chips?.find((c) => c.value === value);\n if (!chip || chip.days === undefined) return;\n\n const today = startOfDay(new Date());\n\n if (chip.days === 0) {\n if (selectsRange) {\n setSelectedStartDate(today);\n setSelectedEndDate(today);\n setSelectingRange(null);\n onChange?.([today, today]);\n } else {\n setLocSelectedDate(today);\n onChange?.(today);\n }\n setCurrentMonth(today);\n return;\n }\n\n const start = subDays(today, chip.days);\n if (selectsRange) {\n setSelectedStartDate(start);\n setSelectedEndDate(today);\n setSelectingRange(null);\n onChange?.([start, today]);\n } else {\n setLocSelectedDate(start);\n onChange?.(start);\n }\n setCurrentMonth(start);\n },\n [chips, selectsRange, onChange, onChipSelect]\n );\n\n return (\n <Box\n ref={ref}\n testID={testID}\n backgroundColor={theme.colors.layer.float}\n borderRadius={theme.shape.contextMenu.md.borderRadius}\n padding={16}\n overflow=\"hidden\"\n style={{\n boxShadow:\n \"0px 2px 3px 0px rgba(7, 7, 8, 0.2), 0px 6px 10px 4px rgba(7, 7, 8, 0.1)\",\n width: 312,\n }}\n >\n {topContent?.({ close: () => {} })}\n\n {chips && chips.length > 0 && (\n <CalendarChips\n chips={chips}\n activeChip={activeChip}\n onChipSelect={handleChipSelect}\n themeMode={themeMode}\n themeProductContext={themeProductContext}\n />\n )}\n\n <CalendarHeader\n monthDate={currentMonth}\n decreaseMonth={decreaseMonth}\n increaseMonth={increaseMonth}\n changeYear={changeYear}\n changeMonth={changeMonth}\n locale={locale}\n minDate={minDate}\n maxDate={maxDate}\n contextMenuMaxHeight={contextMenuMaxHeight}\n themeMode={themeMode}\n themeProductContext={themeProductContext}\n />\n\n <CalendarGrid\n currentMonth={currentMonth}\n locale={locale}\n firstDayOfWeek={firstDayOfWeek}\n selectsRange={selectsRange}\n minDate={minDate}\n maxDate={maxDate}\n startDate={selectedStartDate}\n endDate={selectedEndDate}\n selectedDate={locSelectedDate}\n selectingRange={selectingRange}\n onDayPress={handleChange}\n themeMode={themeMode}\n themeProductContext={themeProductContext}\n />\n\n {bottomContent?.({ close: () => {} })}\n </Box>\n );\n }\n);\n\nCalendar.displayName = \"Calendar\";\n","import React from \"react\";\nimport {\n View,\n Pressable,\n Image,\n ViewStyle,\n ImageStyle,\n DimensionValue,\n AnimatableNumericValue,\n AccessibilityRole,\n} from \"react-native\";\nimport { BoxProps } from \"@xsolla/xui-primitives-core\";\n\nconst roleToAccessibilityRole: Record<string, AccessibilityRole> = {\n button: \"button\",\n link: \"link\",\n img: \"image\",\n image: \"image\",\n summary: \"summary\",\n switch: \"switch\",\n checkbox: \"checkbox\",\n radio: \"radio\",\n heading: \"header\",\n text: \"text\",\n search: \"search\",\n alert: \"alert\",\n none: \"none\",\n presentation: \"none\",\n progressbar: \"progressbar\",\n scrollbar: \"scrollbar\",\n adjustable: \"adjustable\",\n tab: \"tab\",\n menu: \"menu\",\n menuitem: \"menuitem\",\n list: \"list\",\n timer: \"timer\",\n};\n\n/** RN ViewStyle.gap is typed as number (Yoga gap), not DimensionValue. */\nconst toGapValue = (gap: number | string | undefined): number | undefined => {\n if (gap === undefined) return undefined;\n if (typeof gap === \"number\") return gap;\n const pxMatch = /^(\\d+(?:\\.\\d+)?)px$/.exec(gap);\n if (pxMatch) return Number(pxMatch[1]);\n const asNumber = Number(gap);\n return Number.isFinite(asNumber) ? asNumber : undefined;\n};\n\n/**\n * Yoga has no inline formatting context, so RN's ViewStyle.display only\n * accepts \"flex\" | \"none\". Every inline-ish web value collapses to a plain\n * flex container — the box already fills only its content on native, which is\n * what those callers wanted on web anyway. Returning undefined (rather than\n * \"flex\") leaves RN's own default in place.\n */\nconst toNativeDisplay = (\n display: BoxProps[\"display\"]\n): ViewStyle[\"display\"] => (display === \"none\" ? \"none\" : undefined);\n\nexport const Box: React.FC<BoxProps> = ({\n children,\n onPress,\n onLayout,\n onMoveShouldSetResponder,\n onResponderGrant,\n onResponderMove,\n onResponderRelease,\n onResponderTerminate,\n backgroundColor,\n borderColor,\n borderWidth,\n borderBottomWidth,\n borderBottomColor,\n borderTopWidth,\n borderTopColor,\n borderLeftWidth,\n borderLeftColor,\n borderRightWidth,\n borderRightColor,\n borderRadius,\n borderStyle,\n height,\n padding,\n paddingHorizontal,\n paddingVertical,\n margin,\n marginTop,\n marginBottom,\n marginLeft,\n marginRight,\n display,\n flexDirection,\n flexWrap,\n alignItems,\n justifyContent,\n alignSelf,\n position,\n top,\n bottom,\n left,\n right,\n width,\n minWidth,\n minHeight,\n maxWidth,\n maxHeight,\n flex,\n flexShrink,\n gap,\n overflow,\n opacity,\n zIndex,\n hoverStyle,\n pressStyle,\n style,\n disabled,\n \"data-testid\": dataTestId,\n testID,\n as,\n src,\n alt,\n ...rest\n}) => {\n const getContainerStyle = (pressed?: boolean): ViewStyle => ({\n backgroundColor:\n pressed && pressStyle?.backgroundColor\n ? pressStyle.backgroundColor\n : backgroundColor,\n borderColor,\n borderWidth,\n borderBottomWidth,\n borderBottomColor,\n borderTopWidth,\n borderTopColor,\n borderLeftWidth,\n borderLeftColor,\n borderRightWidth,\n borderRightColor,\n borderRadius: borderRadius as AnimatableNumericValue,\n borderStyle: borderStyle as ViewStyle[\"borderStyle\"],\n overflow,\n opacity: opacity ?? (disabled ? 0.5 : undefined),\n zIndex,\n height: height as DimensionValue,\n width: width as DimensionValue,\n minWidth: minWidth as DimensionValue,\n minHeight: minHeight as DimensionValue,\n maxWidth: maxWidth as DimensionValue,\n maxHeight: maxHeight as DimensionValue,\n padding: padding as DimensionValue,\n paddingHorizontal: paddingHorizontal as DimensionValue,\n paddingVertical: paddingVertical as DimensionValue,\n margin: margin as DimensionValue,\n marginTop: marginTop as DimensionValue,\n marginBottom: marginBottom as DimensionValue,\n marginLeft: marginLeft as DimensionValue,\n marginRight: marginRight as DimensionValue,\n display: toNativeDisplay(display),\n flexDirection,\n flexWrap,\n alignItems,\n justifyContent,\n alignSelf,\n position: position as ViewStyle[\"position\"],\n top: top as DimensionValue,\n bottom: bottom as DimensionValue,\n left: left as DimensionValue,\n right: right as DimensionValue,\n flex,\n flexShrink,\n gap: toGapValue(gap),\n ...(style as ViewStyle),\n });\n\n const finalTestID = dataTestId || testID;\n\n // Map web a11y props; drop the rest of the web-only attributes before\n // spreading onto RN hosts (unknown props warn at runtime).\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const {\n role,\n tabIndex,\n onKeyDown,\n onKeyUp,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": _ariaLabelledBy,\n \"aria-current\": _ariaCurrent,\n \"aria-disabled\": ariaDisabled,\n \"aria-live\": ariaLive,\n \"aria-busy\": ariaBusy,\n className,\n \"data-testid\": _dataTestId,\n cursor: _cursor,\n type: _type,\n ...nativeRest\n } = rest as Record<string, unknown>;\n\n const accessibilityRole =\n (typeof role === \"string\" && roleToAccessibilityRole[role]) ||\n (as === \"button\" ? \"button\" : undefined);\n const isDisabled = Boolean(disabled || ariaDisabled);\n const accessibilityState = {\n disabled: isDisabled || undefined,\n busy: Boolean(ariaBusy) || undefined,\n };\n const accessibilityLiveRegion =\n ariaLive === \"polite\" || ariaLive === \"assertive\" ? ariaLive : undefined;\n\n // Handle as=\"img\" for React Native\n if (as === \"img\" && src) {\n const imageStyle: ImageStyle = {\n width: width as DimensionValue,\n height: height as DimensionValue,\n borderRadius: borderRadius as number,\n position: position as ImageStyle[\"position\"],\n top: top as DimensionValue,\n bottom: bottom as DimensionValue,\n left: left as DimensionValue,\n right: right as DimensionValue,\n ...(style as ImageStyle),\n };\n\n return (\n <Image\n source={{ uri: src }}\n style={imageStyle}\n testID={finalTestID}\n accessibilityLabel={typeof ariaLabel === \"string\" ? ariaLabel : alt}\n resizeMode=\"cover\"\n {...nativeRest}\n />\n );\n }\n\n // Prefer Pressable whenever the node is interactive or explicitly a button,\n // so disabled / aria-disabled controls stay in the a11y tree as buttons.\n if (onPress || as === \"button\") {\n return (\n <Pressable\n onPress={!isDisabled && onPress ? onPress : undefined}\n disabled={isDisabled}\n onLayout={onLayout}\n onMoveShouldSetResponder={onMoveShouldSetResponder}\n onResponderGrant={onResponderGrant}\n onResponderMove={onResponderMove}\n onResponderRelease={onResponderRelease}\n onResponderTerminate={onResponderTerminate}\n style={({ pressed }) => getContainerStyle(pressed)}\n testID={finalTestID}\n accessibilityRole={accessibilityRole}\n accessibilityLabel={\n typeof ariaLabel === \"string\" ? ariaLabel : undefined\n }\n accessibilityState={accessibilityState}\n accessibilityLiveRegion={accessibilityLiveRegion}\n {...nativeRest}\n >\n {children}\n </Pressable>\n );\n }\n\n return (\n <View\n style={getContainerStyle()}\n testID={finalTestID}\n onLayout={onLayout}\n onMoveShouldSetResponder={onMoveShouldSetResponder}\n onResponderGrant={onResponderGrant}\n onResponderMove={onResponderMove}\n onResponderRelease={onResponderRelease}\n onResponderTerminate={onResponderTerminate}\n accessibilityRole={accessibilityRole}\n accessibilityLabel={typeof ariaLabel === \"string\" ? ariaLabel : undefined}\n accessibilityState={accessibilityState}\n accessibilityLiveRegion={accessibilityLiveRegion}\n {...nativeRest}\n >\n {children}\n </View>\n );\n};\n","import React from \"react\";\nimport {\n Text as RNText,\n TextStyle,\n AccessibilityRole,\n StyleSheet,\n} from \"react-native\";\nimport { TextProps } from \"@xsolla/xui-primitives-core\";\n\nconst roleMap: Record<string, AccessibilityRole> = {\n alert: \"alert\",\n heading: \"header\",\n button: \"button\",\n link: \"link\",\n text: \"text\",\n};\n\nconst parseNumericValue = (\n value: string | number | undefined\n): number | undefined => {\n if (value === undefined) return undefined;\n if (typeof value === \"number\") return value;\n const parsed = parseFloat(value);\n return isNaN(parsed) ? undefined : parsed;\n};\n\nexport const Text: React.FC<TextProps> = ({\n children,\n color,\n fontSize,\n fontWeight,\n fontFamily,\n textAlign,\n lineHeight,\n numberOfLines,\n id,\n role,\n testID,\n \"data-testid\": dataTestId,\n style: styleProp,\n ...props\n}) => {\n let resolvedFontFamily = fontFamily\n ? fontFamily.split(\",\")[0].replace(/['\"]/g, \"\").trim()\n : undefined;\n\n if (\n resolvedFontFamily === \"Pilat Wide\" ||\n resolvedFontFamily === \"Pilat Wide Bold\" ||\n resolvedFontFamily === \"Aktiv Grotesk\"\n ) {\n resolvedFontFamily = undefined;\n }\n\n const incomingStyle = StyleSheet.flatten(styleProp) as TextStyle | undefined;\n\n const baseStyle: TextStyle = {\n color: color ?? incomingStyle?.color,\n fontSize: typeof fontSize === \"number\" ? fontSize : undefined,\n fontWeight: fontWeight as TextStyle[\"fontWeight\"],\n fontFamily: resolvedFontFamily,\n textDecorationLine: props.textDecoration as TextStyle[\"textDecorationLine\"],\n textAlign: textAlign ?? incomingStyle?.textAlign,\n lineHeight: parseNumericValue(lineHeight ?? incomingStyle?.lineHeight),\n marginTop: parseNumericValue(\n incomingStyle?.marginTop as number | string | undefined\n ),\n marginBottom: parseNumericValue(\n incomingStyle?.marginBottom as number | string | undefined\n ),\n };\n\n const accessibilityRole = role ? roleMap[role] : undefined;\n\n return (\n <RNText\n style={baseStyle}\n numberOfLines={numberOfLines}\n testID={dataTestId || testID || id}\n accessibilityRole={accessibilityRole}\n >\n {children}\n </RNText>\n );\n};\n","import React, { useCallback, useMemo } from \"react\";\nimport { IconButton } from \"@xsolla/xui-button\";\nimport { Select } from \"@xsolla/xui-select\";\nimport { ArrowLeft, ArrowRight } from \"@xsolla/xui-icons-base\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box } from \"@xsolla/xui-primitives\";\nimport { getMonthInLocale } from \"./utils\";\nimport type { CalendarHeaderProps } from \"./types\";\n\nconst months = [\n \"january\",\n \"february\",\n \"march\",\n \"april\",\n \"may\",\n \"june\",\n \"july\",\n \"august\",\n \"september\",\n \"october\",\n \"november\",\n \"december\",\n];\n\nexport const CalendarHeader: React.FC<CalendarHeaderProps> = ({\n monthDate,\n decreaseMonth,\n increaseMonth,\n changeYear,\n changeMonth,\n prevMonthButtonDisabled,\n nextMonthButtonDisabled,\n locale,\n minDate,\n maxDate,\n contextMenuMaxHeight,\n testID,\n themeMode,\n themeProductContext,\n}) => {\n const handleChangeMonth = useCallback(\n (value: any) => {\n changeMonth(months.indexOf(value as string));\n },\n [changeMonth]\n );\n\n const handleChangeYear = useCallback(\n (value: any) => {\n changeYear(parseInt(value as string, 10));\n },\n [changeYear]\n );\n\n const monthOptions = useMemo(() => {\n return months.map((month, index) => ({\n label: getMonthInLocale(index, locale),\n value: month,\n }));\n }, [locale]);\n\n const yearOptions = useMemo(() => {\n const options = [];\n const yearStart = minDate ? minDate.getFullYear() : 1900;\n const yearEnd = maxDate\n ? maxDate.getFullYear()\n : new Date().getFullYear() + 100;\n for (let i = yearEnd; i >= yearStart; i--) {\n options.push({ value: i.toString(), label: i.toString() });\n }\n return options;\n }, [minDate, maxDate]);\n\n return (\n <Box\n testID={testID}\n width=\"100%\"\n flexDirection=\"row\"\n justifyContent=\"space-between\"\n alignItems=\"center\"\n marginBottom={16}\n gap={8}\n >\n <IconButton\n size=\"xs\"\n tone=\"mono\"\n variant=\"tertiary\"\n onPress={decreaseMonth}\n disabled={prevMonthButtonDisabled}\n icon={<ArrowLeft size={16} />}\n aria-label=\"Previous month\"\n themeMode={themeMode}\n themeProductContext={themeProductContext}\n />\n\n <Box flexDirection=\"row\" flex={1} gap={4}>\n <Box flex={1.5}>\n <Select\n value={months[monthDate.getMonth()]}\n onChange={handleChangeMonth}\n options={monthOptions}\n size=\"sm\"\n maxHeight={contextMenuMaxHeight}\n themeMode={themeMode}\n themeProductContext={themeProductContext}\n />\n </Box>\n <Box flex={1}>\n <Select\n value={monthDate.getFullYear().toString()}\n onChange={handleChangeYear}\n options={yearOptions}\n size=\"sm\"\n maxHeight={contextMenuMaxHeight}\n themeMode={themeMode}\n themeProductContext={themeProductContext}\n />\n </Box>\n </Box>\n\n <IconButton\n size=\"xs\"\n tone=\"mono\"\n variant=\"tertiary\"\n onPress={increaseMonth}\n disabled={nextMonthButtonDisabled}\n icon={<ArrowRight size={16} />}\n aria-label=\"Next month\"\n themeMode={themeMode}\n themeProductContext={themeProductContext}\n />\n </Box>\n );\n};\n","import { format, setMonth } from \"date-fns\";\nimport * as locales from \"date-fns/locale\";\nimport type { CalendarLocaleType } from \"./types\";\n\nconst defaultLocale = \"enUS\";\n\nexport function formatDate(\n date: Date,\n formatStr: string,\n locale: CalendarLocaleType = defaultLocale\n) {\n const localeObj = locales[locale] || locales[defaultLocale];\n\n return format(date, formatStr, {\n locale: localeObj,\n });\n}\n\nexport function getMonthInLocale(\n month: number,\n locale: CalendarLocaleType = defaultLocale\n) {\n return formatDate(setMonth(new Date(), month), \"LLLL\", locale);\n}\n","import React, { useMemo, useCallback, useState } from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box, Text } from \"@xsolla/xui-primitives\";\nimport { useResolvedTheme } from \"@xsolla/xui-core\";\nimport {\n addDays,\n eachDayOfInterval,\n endOfDay,\n endOfMonth,\n endOfWeek,\n format,\n isAfter,\n isBefore,\n isSameDay,\n isSameMonth,\n isToday,\n isWithinInterval,\n startOfDay,\n startOfMonth,\n startOfWeek,\n} from \"date-fns\";\nimport * as locales from \"date-fns/locale\";\nimport type { CalendarGridProps } from \"./types\";\n\n/** Width of a single day cell. */\nconst DAY_CELL_WIDTH = 40;\n/**\n * Natural width of the 7-column grid. The header and week rows are pinned to\n * this so the cells sit flush against each other: a range highlight has to read\n * as one continuous band, which it cannot do if the row distributes slack\n * between the cells. See FEP-834.\n */\nconst GRID_WIDTH = DAY_CELL_WIDTH * 7;\n\nexport const CalendarGrid: React.FC<CalendarGridProps> = ({\n currentMonth,\n locale = \"enUS\",\n firstDayOfWeek = 0,\n selectsRange = false,\n minDate,\n maxDate,\n startDate,\n endDate,\n selectedDate,\n selectingRange,\n onDayPress,\n testID,\n themeMode,\n themeProductContext,\n}) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n const localeObj = (locales as any)[locale] || locales.enUS;\n const [hoveredKey, setHoveredKey] = useState<string | null>(null);\n\n const monthStart = startOfMonth(currentMonth);\n const monthEnd = endOfMonth(currentMonth);\n const weekStartsOn = (firstDayOfWeek ?? 0) as any;\n const calendarStart = startOfWeek(monthStart, { weekStartsOn });\n const calendarEnd = endOfWeek(monthEnd, { weekStartsOn });\n\n const days = eachDayOfInterval({ start: calendarStart, end: calendarEnd });\n\n const weekDays = useMemo(() => {\n return Array.from({ length: 7 }, (_, i) => {\n const day = addDays(calendarStart, i);\n return format(day, \"EEEEEE\", { locale: localeObj });\n });\n }, [calendarStart, localeObj]);\n\n const weeks = useMemo(() => {\n const weekArray: Date[][] = [];\n for (let i = 0; i < days.length; i += 7) {\n weekArray.push(days.slice(i, i + 7));\n }\n return weekArray;\n }, [days]);\n\n const isDateDisabled = useCallback(\n (date: Date) => {\n if (minDate && isBefore(date, startOfDay(minDate))) return true;\n if (maxDate && isAfter(date, endOfDay(maxDate))) return true;\n return false;\n },\n [minDate, maxDate]\n );\n\n const isDateInRange = useCallback(\n (date: Date) => {\n if (!selectsRange || !startDate) return false;\n const rangeEnd = endDate || selectingRange;\n if (!rangeEnd) return false;\n const start = startDate < rangeEnd ? startDate : rangeEnd;\n const end = startDate < rangeEnd ? rangeEnd : startDate;\n return isWithinInterval(date, {\n start: startOfDay(start),\n end: endOfDay(end),\n });\n },\n [selectsRange, startDate, endDate, selectingRange]\n );\n\n return (\n <Box testID={testID}>\n <Box\n flexDirection=\"row\"\n justifyContent=\"flex-start\"\n width={GRID_WIDTH}\n marginBottom={8}\n >\n {weekDays.map((day, i) => (\n <Box key={i} width={DAY_CELL_WIDTH} alignItems=\"center\">\n <Text\n fontSize={12}\n fontWeight=\"600\"\n color={theme.colors.content.tertiary}\n >\n {day.toUpperCase()}\n </Text>\n </Box>\n ))}\n </Box>\n\n <Box gap={2}>\n {weeks.map((week, i) => (\n <Box\n key={i}\n flexDirection=\"row\"\n justifyContent=\"flex-start\"\n width={GRID_WIDTH}\n >\n {week.map((day, j) => {\n const dayKey = format(day, \"yyyy-MM-dd\");\n const isOutsideMonth = !isSameMonth(day, currentMonth);\n const isSelected =\n (!selectsRange &&\n selectedDate &&\n isSameDay(day, selectedDate)) ||\n (selectsRange &&\n startDate &&\n endDate &&\n isSameDay(day, startDate) &&\n isSameDay(day, endDate));\n const isRangeStart =\n selectsRange && startDate && isSameDay(day, startDate);\n const isRangeEnd =\n selectsRange && endDate && isSameDay(day, endDate);\n const inRange = isDateInRange(day);\n const today = isToday(day);\n const disabled = isDateDisabled(day);\n const isHoverable =\n !disabled && !isOutsideMonth && !isSelected && !isRangeStart && !isRangeEnd;\n const isHovered = isHoverable && hoveredKey === dayKey;\n\n let bgColor = \"transparent\";\n let textColor = theme.colors.content.primary;\n\n if (isSelected || isRangeStart || isRangeEnd || inRange) {\n bgColor = theme.colors.control.check.bg;\n textColor = theme.colors.control.check.icon;\n } else if (isHovered || today) {\n bgColor = theme.colors.control.check.bgHover;\n textColor = theme.colors.control.check.icon;\n } else if (isOutsideMonth || disabled) {\n textColor = theme.colors.control.text.disable;\n }\n\n return (\n <Box\n key={j}\n width={DAY_CELL_WIDTH}\n height={32}\n alignItems=\"center\"\n justifyContent=\"center\"\n borderTopLeftRadius={isSelected || isRangeStart ? 4 : 0}\n borderTopRightRadius={isSelected || isRangeEnd ? 4 : 0}\n borderBottomLeftRadius={isSelected || isRangeStart ? 4 : 0}\n borderBottomRightRadius={isSelected || isRangeEnd ? 4 : 0}\n backgroundColor={bgColor}\n cursor={disabled || isOutsideMonth ? \"default\" : \"pointer\"}\n onPress={() =>\n !disabled && !isOutsideMonth && onDayPress?.(day)\n }\n onMouseEnter={() =>\n isHoverable && setHoveredKey(dayKey)\n }\n onMouseLeave={() =>\n setHoveredKey((current) =>\n current === dayKey ? null : current\n )\n }\n hoverStyle={\n isHoverable\n ? { backgroundColor: theme.colors.control.check.bgHover }\n : undefined\n }\n >\n <Text\n color={textColor}\n fontSize={14}\n fontWeight={\n isSelected || isRangeStart || isRangeEnd ? \"600\" : \"400\"\n }\n >\n {format(day, \"d\")}\n </Text>\n </Box>\n );\n })}\n </Box>\n ))}\n </Box>\n </Box>\n );\n};\n","import React from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box, Text } from \"@xsolla/xui-primitives\";\nimport { useResolvedTheme } from \"@xsolla/xui-core\";\nimport type { CalendarChipsProps } from \"./types\";\n\nexport const CalendarChips: React.FC<CalendarChipsProps> = ({\n chips,\n activeChip,\n onChipSelect,\n testID,\n themeMode,\n themeProductContext,\n}) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n const toggleColors = theme.colors.control.toggleButton;\n // Tag's sizing scale is a compact-chip scale; toggleButtonGroup's is a\n // full-button scale and renders oversized here. Only the colors come\n // from the toggle-button tokens (to match the Figma selected/hover states).\n const sizeStyles = theme.sizing.tag(\"sm\");\n const borderWidth = sizeStyles.borderWidth;\n\n if (!chips || chips.length === 0) return null;\n\n return (\n <Box\n testID={testID}\n flexDirection=\"row\"\n flexWrap=\"wrap\"\n gap={8}\n marginBottom={16}\n >\n {chips.map((chip) => {\n const isActive = activeChip === chip.value;\n const bgColor = isActive ? toggleColors.bgActive : toggleColors.bg;\n const textColor = isActive ? toggleColors.textActive : toggleColors.text;\n const borderColor = isActive\n ? toggleColors.borderActive\n : toggleColors.border;\n\n return (\n <Box\n key={chip.value}\n as=\"button\"\n role=\"radio\"\n aria-checked={isActive}\n testID={chip.value}\n onPress={() => onChipSelect?.(chip.value)}\n height={sizeStyles.height}\n paddingHorizontal={sizeStyles.padding}\n alignItems=\"center\"\n justifyContent=\"center\"\n backgroundColor={bgColor}\n borderWidth={borderWidth}\n borderColor={borderColor}\n borderStyle=\"solid\"\n borderRadius={sizeStyles.radius}\n cursor=\"pointer\"\n hoverStyle={\n !isActive\n ? {\n backgroundColor: toggleColors.bgHover,\n borderColor: toggleColors.borderHover,\n }\n : undefined\n }\n >\n <Text\n color={textColor}\n fontSize={sizeStyles.fontSize}\n fontWeight=\"400\"\n whiteSpace=\"nowrap\"\n >\n {chip.label}\n </Text>\n </Box>\n );\n })}\n </Box>\n );\n};\n","import { forwardRef, useCallback, useEffect, useState } from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box } from \"@xsolla/xui-primitives\";\nimport { useResolvedTheme } from \"@xsolla/xui-core\";\nimport {\n addMonths,\n isSameMonth,\n subDays,\n subMonths,\n startOfDay,\n} from \"date-fns\";\nimport { CalendarHeader } from \"./CalendarHeader\";\nimport { CalendarGrid } from \"./CalendarGrid\";\nimport { CalendarChips } from \"./CalendarChips\";\nimport type { DualCalendarProps } from \"./types\";\n\nexport const DualCalendar = forwardRef<any, DualCalendarProps>(\n (\n {\n locale = \"enUS\",\n onChange,\n startDate,\n endDate,\n contextMenuMaxHeight,\n topContent,\n bottomContent,\n chips,\n activeChip,\n onChipSelect,\n testID,\n minDate,\n maxDate,\n firstDayOfWeek = 0,\n month,\n initialMonth,\n themeMode,\n themeProductContext,\n },\n ref\n ) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n\n // Each panel owns its visible month (XUITSD-122): navigating one panel\n // must not move the other. The right panel starts one month after the\n // left one, and both are re-paired only when the view is driven from\n // outside (`month`, chips).\n const [leftMonth, setLeftMonth] = useState<Date>(\n (month || initialMonth || startDate || new Date()) as Date\n );\n const [rightMonth, setRightMonth] = useState<Date>(() =>\n addMonths((month || initialMonth || startDate || new Date()) as Date, 1)\n );\n const [selectedStartDate, setSelectedStartDate] = useState<\n Date | null | undefined\n >(startDate);\n const [selectedEndDate, setSelectedEndDate] = useState<\n Date | null | undefined\n >(endDate);\n const [selectingRange, setSelectingRange] = useState<Date | null>(null);\n\n /** Show `date`'s month in the left panel and the next month on the right. */\n const showFrom = useCallback((date: Date) => {\n setLeftMonth(date);\n setRightMonth(addMonths(date, 1));\n }, []);\n\n useEffect(() => {\n setSelectedStartDate(startDate);\n setSelectedEndDate(endDate);\n }, [startDate, endDate]);\n\n // Follow the controlled `month` only when it actually changes (by\n // year+month, so a consumer re-creating the Date each render is a no-op),\n // and only when that month is not already on screen. Re-pairing the\n // panels on every `startDate`/`endDate` change made a click in the right\n // panel shift both panels.\n const monthKey = month ? month.getFullYear() * 12 + month.getMonth() : null;\n useEffect(() => {\n if (!month) return;\n if (isSameMonth(month, leftMonth) || isSameMonth(month, rightMonth)) {\n return;\n }\n showFrom(month);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [monthKey]);\n\n const startNewRange = useCallback(\n (date: Date) => {\n setSelectedStartDate(date);\n setSelectedEndDate(null);\n setSelectingRange(date);\n onChange?.([date, null]);\n },\n [onChange]\n );\n\n const completeRange = useCallback(\n (start: Date, end: Date) => {\n setSelectedStartDate(start);\n setSelectedEndDate(end);\n setSelectingRange(null);\n onChange?.([start, end]);\n },\n [onChange]\n );\n\n const handleDayPress = useCallback(\n (date: Date, panel: \"left\" | \"right\") => {\n const newDate = new Date(\n date.getFullYear(),\n date.getMonth(),\n date.getDate()\n );\n\n if (!selectedStartDate) {\n startNewRange(newDate);\n return;\n }\n\n if (selectedEndDate) {\n // With a complete range, the right panel edits the end of the period\n // (XUITSD-122). A day before the start can't be an end, so it starts\n // a new range instead, as does any click in the left panel.\n if (panel === \"right\" && newDate >= selectedStartDate) {\n completeRange(selectedStartDate, newDate);\n } else {\n startNewRange(newDate);\n }\n return;\n }\n\n const start = selectedStartDate < newDate ? selectedStartDate : newDate;\n const end = selectedStartDate < newDate ? newDate : selectedStartDate;\n completeRange(start, end);\n },\n [selectedStartDate, selectedEndDate, startNewRange, completeRange]\n );\n\n const handleLeftDayPress = useCallback(\n (date: Date) => handleDayPress(date, \"left\"),\n [handleDayPress]\n );\n const handleRightDayPress = useCallback(\n (date: Date) => handleDayPress(date, \"right\"),\n [handleDayPress]\n );\n\n const decreaseLeftMonth = useCallback(\n () => setLeftMonth((prev) => subMonths(prev, 1)),\n []\n );\n const increaseLeftMonth = useCallback(\n () => setLeftMonth((prev) => addMonths(prev, 1)),\n []\n );\n const changeLeftMonth = useCallback(\n (m: number) => setLeftMonth((prev) => new Date(prev.getFullYear(), m, 1)),\n []\n );\n const changeLeftYear = useCallback(\n (y: number) => setLeftMonth((prev) => new Date(y, prev.getMonth(), 1)),\n []\n );\n\n const decreaseRightMonth = useCallback(\n () => setRightMonth((prev) => subMonths(prev, 1)),\n []\n );\n const increaseRightMonth = useCallback(\n () => setRightMonth((prev) => addMonths(prev, 1)),\n []\n );\n const changeRightMonth = useCallback(\n (m: number) =>\n setRightMonth((prev) => new Date(prev.getFullYear(), m, 1)),\n []\n );\n const changeRightYear = useCallback(\n (y: number) => setRightMonth((prev) => new Date(y, prev.getMonth(), 1)),\n []\n );\n\n const handleChipSelect = useCallback(\n (value: string | null) => {\n onChipSelect?.(value);\n\n const chip = chips?.find((c) => c.value === value);\n if (!chip || chip.days === undefined) return;\n\n const today = startOfDay(new Date());\n\n if (chip.days === 0) {\n setSelectedStartDate(today);\n setSelectedEndDate(today);\n setSelectingRange(null);\n showFrom(today);\n onChange?.([today, today]);\n return;\n }\n\n const start = subDays(today, chip.days);\n setSelectedStartDate(start);\n setSelectedEndDate(today);\n setSelectingRange(null);\n showFrom(start);\n onChange?.([start, today]);\n },\n [chips, onChange, onChipSelect, showFrom]\n );\n\n return (\n <Box\n ref={ref}\n testID={testID}\n backgroundColor={theme.colors.layer.float}\n borderRadius={theme.shape.contextMenu.md.borderRadius}\n padding={16}\n overflow=\"hidden\"\n style={{\n boxShadow:\n \"0px 2px 3px 0px rgba(7, 7, 8, 0.2), 0px 6px 10px 4px rgba(7, 7, 8, 0.1)\",\n width: 624,\n }}\n >\n {topContent?.({ close: () => {} })}\n\n {chips && chips.length > 0 && (\n <CalendarChips\n chips={chips}\n activeChip={activeChip}\n onChipSelect={handleChipSelect}\n themeMode={themeMode}\n themeProductContext={themeProductContext}\n />\n )}\n\n <Box flexDirection=\"row\" gap={16}>\n <Box flex={1}>\n <CalendarHeader\n monthDate={leftMonth}\n decreaseMonth={decreaseLeftMonth}\n increaseMonth={increaseLeftMonth}\n changeYear={changeLeftYear}\n changeMonth={changeLeftMonth}\n locale={locale}\n minDate={minDate}\n maxDate={maxDate}\n contextMenuMaxHeight={contextMenuMaxHeight}\n themeMode={themeMode}\n themeProductContext={themeProductContext}\n />\n\n <CalendarGrid\n currentMonth={leftMonth}\n locale={locale}\n firstDayOfWeek={firstDayOfWeek}\n selectsRange\n minDate={minDate}\n maxDate={maxDate}\n startDate={selectedStartDate}\n endDate={selectedEndDate}\n selectingRange={selectingRange}\n onDayPress={handleLeftDayPress}\n themeMode={themeMode}\n themeProductContext={themeProductContext}\n />\n </Box>\n\n <Box flex={1}>\n <CalendarHeader\n monthDate={rightMonth}\n decreaseMonth={decreaseRightMonth}\n increaseMonth={increaseRightMonth}\n changeYear={changeRightYear}\n changeMonth={changeRightMonth}\n locale={locale}\n minDate={minDate}\n maxDate={maxDate}\n contextMenuMaxHeight={contextMenuMaxHeight}\n themeMode={themeMode}\n themeProductContext={themeProductContext}\n />\n\n <CalendarGrid\n currentMonth={rightMonth}\n locale={locale}\n firstDayOfWeek={firstDayOfWeek}\n selectsRange\n minDate={minDate}\n maxDate={maxDate}\n startDate={selectedStartDate}\n endDate={selectedEndDate}\n selectingRange={selectingRange}\n onDayPress={handleRightDayPress}\n themeMode={themeMode}\n themeProductContext={themeProductContext}\n />\n </Box>\n </Box>\n\n {bottomContent?.({ close: () => {} })}\n </Box>\n );\n }\n);\n\nDualCalendar.displayName = \"DualCalendar\";\n"],"mappings":"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","names":["useCallback","useState","jsx","useResolvedTheme","startOfDay","jsx","useMemo","useCallback","format","locales","jsx","jsxs","useMemo","useCallback","useResolvedTheme","jsx","jsx","jsxs","useResolvedTheme","useState","useCallback","startOfDay","forwardRef","useCallback","useEffect","useState","useResolvedTheme","addMonths","isSameMonth","subDays","subMonths","startOfDay","jsx","jsxs","forwardRef","useResolvedTheme","useState","addMonths","useCallback","useEffect","isSameMonth","subMonths","startOfDay","subDays"]}
|
|
1
|
+
{"version":3,"sources":["../../src/Calendar.tsx","../../../../foundation/primitives-native/src/Box.tsx","../../../../foundation/primitives-native/src/Text.tsx","../../../../foundation/primitives-native/src/index.tsx","../../src/CalendarHeader.tsx","../../src/utils.ts","../../src/CalendarGrid.tsx","../../src/CalendarChips.tsx","../../src/DualCalendar.tsx"],"sourcesContent":["import { forwardRef, useCallback, useEffect, useState } from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box } from \"@xsolla/xui-primitives\";\nimport { useResolvedTheme } from \"@xsolla/xui-core\";\nimport { addMonths, subDays, subMonths, startOfDay } from \"date-fns\";\nimport { CalendarHeader } from \"./CalendarHeader\";\nimport { CalendarGrid } from \"./CalendarGrid\";\nimport { CalendarChips } from \"./CalendarChips\";\nimport type { CalendarProps } from \"./types\";\n\nexport const Calendar = forwardRef<any, CalendarProps>(\n (\n {\n locale = \"enUS\",\n onChange,\n startDate,\n endDate,\n selectedDate,\n selectsRange = false,\n contextMenuMaxHeight,\n topContent,\n bottomContent,\n chips,\n activeChip,\n onChipSelect,\n testID,\n minDate,\n maxDate,\n firstDayOfWeek = 0,\n month,\n initialMonth,\n themeMode,\n themeProductContext,\n },\n ref\n ) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n\n const [currentMonth, setCurrentMonth] = useState<Date>(\n (month || initialMonth || selectedDate || startDate || new Date()) as Date\n );\n const [selectedStartDate, setSelectedStartDate] = useState<\n Date | null | undefined\n >(startDate);\n const [selectedEndDate, setSelectedEndDate] = useState<\n Date | null | undefined\n >(endDate);\n const [locSelectedDate, setLocSelectedDate] = useState<\n Date | null | undefined\n >(selectedDate);\n const [selectingRange, setSelectingRange] = useState<Date | null>(null);\n\n useEffect(() => {\n setSelectedStartDate(startDate);\n setSelectedEndDate(endDate);\n setLocSelectedDate(selectedDate);\n if (month !== undefined) {\n setCurrentMonth(month);\n }\n }, [startDate, endDate, selectedDate, month]);\n\n const handleChange = useCallback(\n (date: Date) => {\n const newDate = new Date(\n date.getFullYear(),\n date.getMonth(),\n date.getDate()\n );\n\n if (!selectsRange) {\n setLocSelectedDate(newDate);\n onChange?.(newDate);\n } else {\n if (!selectedStartDate || (selectedStartDate && selectedEndDate)) {\n setSelectedStartDate(newDate);\n setSelectedEndDate(null);\n setSelectingRange(newDate);\n onChange?.([newDate, null]);\n } else {\n const start =\n selectedStartDate < newDate ? selectedStartDate : newDate;\n const end =\n selectedStartDate < newDate ? newDate : selectedStartDate;\n setSelectedStartDate(start);\n setSelectedEndDate(end);\n setSelectingRange(null);\n onChange?.([start, end]);\n }\n }\n },\n [onChange, selectsRange, selectedStartDate, selectedEndDate]\n );\n\n const decreaseMonth = useCallback(\n () => setCurrentMonth((prev) => subMonths(prev, 1)),\n []\n );\n const increaseMonth = useCallback(\n () => setCurrentMonth((prev) => addMonths(prev, 1)),\n []\n );\n const changeMonth = useCallback(\n (m: number) =>\n setCurrentMonth((prev) => new Date(prev.getFullYear(), m, 1)),\n []\n );\n const changeYear = useCallback(\n (y: number) => setCurrentMonth((prev) => new Date(y, prev.getMonth(), 1)),\n []\n );\n\n const handleChipSelect = useCallback(\n (value: string | null) => {\n onChipSelect?.(value);\n\n const chip = chips?.find((c) => c.value === value);\n if (!chip || chip.days === undefined) return;\n\n const today = startOfDay(new Date());\n\n if (chip.days === 0) {\n if (selectsRange) {\n setSelectedStartDate(today);\n setSelectedEndDate(today);\n setSelectingRange(null);\n onChange?.([today, today]);\n } else {\n setLocSelectedDate(today);\n onChange?.(today);\n }\n setCurrentMonth(today);\n return;\n }\n\n const start = subDays(today, chip.days);\n if (selectsRange) {\n setSelectedStartDate(start);\n setSelectedEndDate(today);\n setSelectingRange(null);\n onChange?.([start, today]);\n } else {\n setLocSelectedDate(start);\n onChange?.(start);\n }\n setCurrentMonth(start);\n },\n [chips, selectsRange, onChange, onChipSelect]\n );\n\n return (\n <Box\n ref={ref}\n testID={testID}\n backgroundColor={theme.colors.layer.float}\n borderRadius={theme.shape.contextMenu.md.borderRadius}\n padding={16}\n overflow=\"hidden\"\n style={{\n boxShadow:\n \"0px 2px 3px 0px rgba(7, 7, 8, 0.2), 0px 6px 10px 4px rgba(7, 7, 8, 0.1)\",\n width: 312,\n }}\n >\n {topContent?.({ close: () => {} })}\n\n {chips && chips.length > 0 && (\n <CalendarChips\n chips={chips}\n activeChip={activeChip}\n onChipSelect={handleChipSelect}\n themeMode={themeMode}\n themeProductContext={themeProductContext}\n />\n )}\n\n <CalendarHeader\n monthDate={currentMonth}\n decreaseMonth={decreaseMonth}\n increaseMonth={increaseMonth}\n changeYear={changeYear}\n changeMonth={changeMonth}\n locale={locale}\n minDate={minDate}\n maxDate={maxDate}\n contextMenuMaxHeight={contextMenuMaxHeight}\n themeMode={themeMode}\n themeProductContext={themeProductContext}\n />\n\n <CalendarGrid\n currentMonth={currentMonth}\n locale={locale}\n firstDayOfWeek={firstDayOfWeek}\n selectsRange={selectsRange}\n minDate={minDate}\n maxDate={maxDate}\n startDate={selectedStartDate}\n endDate={selectedEndDate}\n selectedDate={locSelectedDate}\n selectingRange={selectingRange}\n onDayPress={handleChange}\n onMonthChange={setCurrentMonth}\n themeMode={themeMode}\n themeProductContext={themeProductContext}\n />\n\n {bottomContent?.({ close: () => {} })}\n </Box>\n );\n }\n);\n\nCalendar.displayName = \"Calendar\";\n","import React from \"react\";\nimport {\n View,\n Pressable,\n Image,\n ViewStyle,\n ImageStyle,\n DimensionValue,\n AnimatableNumericValue,\n AccessibilityRole,\n} from \"react-native\";\nimport { BoxProps } from \"@xsolla/xui-primitives-core\";\n\nconst roleToAccessibilityRole: Record<string, AccessibilityRole> = {\n button: \"button\",\n link: \"link\",\n img: \"image\",\n image: \"image\",\n summary: \"summary\",\n switch: \"switch\",\n checkbox: \"checkbox\",\n radio: \"radio\",\n heading: \"header\",\n text: \"text\",\n search: \"search\",\n alert: \"alert\",\n none: \"none\",\n presentation: \"none\",\n progressbar: \"progressbar\",\n scrollbar: \"scrollbar\",\n adjustable: \"adjustable\",\n tab: \"tab\",\n menu: \"menu\",\n menuitem: \"menuitem\",\n list: \"list\",\n timer: \"timer\",\n};\n\n/** RN ViewStyle.gap is typed as number (Yoga gap), not DimensionValue. */\nconst toGapValue = (gap: number | string | undefined): number | undefined => {\n if (gap === undefined) return undefined;\n if (typeof gap === \"number\") return gap;\n const pxMatch = /^(\\d+(?:\\.\\d+)?)px$/.exec(gap);\n if (pxMatch) return Number(pxMatch[1]);\n const asNumber = Number(gap);\n return Number.isFinite(asNumber) ? asNumber : undefined;\n};\n\n/**\n * Yoga has no inline formatting context, so RN's ViewStyle.display only\n * accepts \"flex\" | \"none\". Every inline-ish web value collapses to a plain\n * flex container — the box already fills only its content on native, which is\n * what those callers wanted on web anyway. Returning undefined (rather than\n * \"flex\") leaves RN's own default in place.\n */\nconst toNativeDisplay = (\n display: BoxProps[\"display\"]\n): ViewStyle[\"display\"] => (display === \"none\" ? \"none\" : undefined);\n\nexport const Box: React.FC<BoxProps> = ({\n children,\n onPress,\n onLayout,\n onMoveShouldSetResponder,\n onResponderGrant,\n onResponderMove,\n onResponderRelease,\n onResponderTerminate,\n backgroundColor,\n borderColor,\n borderWidth,\n borderBottomWidth,\n borderBottomColor,\n borderTopWidth,\n borderTopColor,\n borderLeftWidth,\n borderLeftColor,\n borderRightWidth,\n borderRightColor,\n borderRadius,\n borderStyle,\n height,\n padding,\n paddingHorizontal,\n paddingVertical,\n margin,\n marginTop,\n marginBottom,\n marginLeft,\n marginRight,\n display,\n flexDirection,\n flexWrap,\n alignItems,\n justifyContent,\n alignSelf,\n position,\n top,\n bottom,\n left,\n right,\n width,\n minWidth,\n minHeight,\n maxWidth,\n maxHeight,\n flex,\n flexShrink,\n gap,\n overflow,\n opacity,\n zIndex,\n hoverStyle,\n pressStyle,\n style,\n disabled,\n \"data-testid\": dataTestId,\n testID,\n as,\n src,\n alt,\n ...rest\n}) => {\n const getContainerStyle = (pressed?: boolean): ViewStyle => ({\n backgroundColor:\n pressed && pressStyle?.backgroundColor\n ? pressStyle.backgroundColor\n : backgroundColor,\n borderColor,\n borderWidth,\n borderBottomWidth,\n borderBottomColor,\n borderTopWidth,\n borderTopColor,\n borderLeftWidth,\n borderLeftColor,\n borderRightWidth,\n borderRightColor,\n borderRadius: borderRadius as AnimatableNumericValue,\n borderStyle: borderStyle as ViewStyle[\"borderStyle\"],\n overflow,\n opacity: opacity ?? (disabled ? 0.5 : undefined),\n zIndex,\n height: height as DimensionValue,\n width: width as DimensionValue,\n minWidth: minWidth as DimensionValue,\n minHeight: minHeight as DimensionValue,\n maxWidth: maxWidth as DimensionValue,\n maxHeight: maxHeight as DimensionValue,\n padding: padding as DimensionValue,\n paddingHorizontal: paddingHorizontal as DimensionValue,\n paddingVertical: paddingVertical as DimensionValue,\n margin: margin as DimensionValue,\n marginTop: marginTop as DimensionValue,\n marginBottom: marginBottom as DimensionValue,\n marginLeft: marginLeft as DimensionValue,\n marginRight: marginRight as DimensionValue,\n display: toNativeDisplay(display),\n flexDirection,\n flexWrap,\n alignItems,\n justifyContent,\n alignSelf,\n position: position as ViewStyle[\"position\"],\n top: top as DimensionValue,\n bottom: bottom as DimensionValue,\n left: left as DimensionValue,\n right: right as DimensionValue,\n flex,\n flexShrink,\n gap: toGapValue(gap),\n ...(style as ViewStyle),\n });\n\n const finalTestID = dataTestId || testID;\n\n // Map web a11y props; drop the rest of the web-only attributes before\n // spreading onto RN hosts (unknown props warn at runtime).\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const {\n role,\n tabIndex,\n onKeyDown,\n onKeyUp,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": _ariaLabelledBy,\n \"aria-current\": _ariaCurrent,\n \"aria-disabled\": ariaDisabled,\n \"aria-live\": ariaLive,\n \"aria-busy\": ariaBusy,\n className,\n \"data-testid\": _dataTestId,\n cursor: _cursor,\n type: _type,\n ...nativeRest\n } = rest as Record<string, unknown>;\n\n const accessibilityRole =\n (typeof role === \"string\" && roleToAccessibilityRole[role]) ||\n (as === \"button\" ? \"button\" : undefined);\n const isDisabled = Boolean(disabled || ariaDisabled);\n const accessibilityState = {\n disabled: isDisabled || undefined,\n busy: Boolean(ariaBusy) || undefined,\n };\n const accessibilityLiveRegion =\n ariaLive === \"polite\" || ariaLive === \"assertive\" ? ariaLive : undefined;\n\n // Handle as=\"img\" for React Native\n if (as === \"img\" && src) {\n const imageStyle: ImageStyle = {\n width: width as DimensionValue,\n height: height as DimensionValue,\n borderRadius: borderRadius as number,\n position: position as ImageStyle[\"position\"],\n top: top as DimensionValue,\n bottom: bottom as DimensionValue,\n left: left as DimensionValue,\n right: right as DimensionValue,\n ...(style as ImageStyle),\n };\n\n return (\n <Image\n source={{ uri: src }}\n style={imageStyle}\n testID={finalTestID}\n accessibilityLabel={typeof ariaLabel === \"string\" ? ariaLabel : alt}\n resizeMode=\"cover\"\n {...nativeRest}\n />\n );\n }\n\n // Prefer Pressable whenever the node is interactive or explicitly a button,\n // so disabled / aria-disabled controls stay in the a11y tree as buttons.\n if (onPress || as === \"button\") {\n return (\n <Pressable\n onPress={!isDisabled && onPress ? onPress : undefined}\n disabled={isDisabled}\n onLayout={onLayout}\n onMoveShouldSetResponder={onMoveShouldSetResponder}\n onResponderGrant={onResponderGrant}\n onResponderMove={onResponderMove}\n onResponderRelease={onResponderRelease}\n onResponderTerminate={onResponderTerminate}\n style={({ pressed }) => getContainerStyle(pressed)}\n testID={finalTestID}\n accessibilityRole={accessibilityRole}\n accessibilityLabel={\n typeof ariaLabel === \"string\" ? ariaLabel : undefined\n }\n accessibilityState={accessibilityState}\n accessibilityLiveRegion={accessibilityLiveRegion}\n {...nativeRest}\n >\n {children}\n </Pressable>\n );\n }\n\n return (\n <View\n style={getContainerStyle()}\n testID={finalTestID}\n onLayout={onLayout}\n onMoveShouldSetResponder={onMoveShouldSetResponder}\n onResponderGrant={onResponderGrant}\n onResponderMove={onResponderMove}\n onResponderRelease={onResponderRelease}\n onResponderTerminate={onResponderTerminate}\n accessibilityRole={accessibilityRole}\n accessibilityLabel={typeof ariaLabel === \"string\" ? ariaLabel : undefined}\n accessibilityState={accessibilityState}\n accessibilityLiveRegion={accessibilityLiveRegion}\n {...nativeRest}\n >\n {children}\n </View>\n );\n};\n","import React from \"react\";\nimport {\n Text as RNText,\n TextStyle,\n AccessibilityRole,\n StyleSheet,\n} from \"react-native\";\nimport { TextProps } from \"@xsolla/xui-primitives-core\";\n\nconst roleMap: Record<string, AccessibilityRole> = {\n alert: \"alert\",\n heading: \"header\",\n button: \"button\",\n link: \"link\",\n text: \"text\",\n};\n\nconst parseNumericValue = (\n value: string | number | undefined\n): number | undefined => {\n if (value === undefined) return undefined;\n if (typeof value === \"number\") return value;\n const parsed = parseFloat(value);\n return isNaN(parsed) ? undefined : parsed;\n};\n\nexport const Text: React.FC<TextProps> = ({\n children,\n color,\n fontSize,\n fontWeight,\n fontFamily,\n textAlign,\n lineHeight,\n numberOfLines,\n id,\n role,\n testID,\n \"data-testid\": dataTestId,\n style: styleProp,\n ...props\n}) => {\n let resolvedFontFamily = fontFamily\n ? fontFamily.split(\",\")[0].replace(/['\"]/g, \"\").trim()\n : undefined;\n\n if (\n resolvedFontFamily === \"Pilat Wide\" ||\n resolvedFontFamily === \"Pilat Wide Bold\" ||\n resolvedFontFamily === \"Aktiv Grotesk\"\n ) {\n resolvedFontFamily = undefined;\n }\n\n const incomingStyle = StyleSheet.flatten(styleProp) as TextStyle | undefined;\n\n const baseStyle: TextStyle = {\n color: color ?? incomingStyle?.color,\n fontSize: typeof fontSize === \"number\" ? fontSize : undefined,\n fontWeight: fontWeight as TextStyle[\"fontWeight\"],\n fontFamily: resolvedFontFamily,\n textDecorationLine: props.textDecoration as TextStyle[\"textDecorationLine\"],\n textAlign: textAlign ?? incomingStyle?.textAlign,\n lineHeight: parseNumericValue(lineHeight ?? incomingStyle?.lineHeight),\n marginTop: parseNumericValue(\n incomingStyle?.marginTop as number | string | undefined\n ),\n marginBottom: parseNumericValue(\n incomingStyle?.marginBottom as number | string | undefined\n ),\n };\n\n const accessibilityRole = role ? roleMap[role] : undefined;\n\n return (\n <RNText\n style={baseStyle}\n numberOfLines={numberOfLines}\n testID={dataTestId || testID || id}\n accessibilityRole={accessibilityRole}\n >\n {children}\n </RNText>\n );\n};\n","export * from \"./Box\";\nexport * from \"./Text\";\nexport * from \"./Spinner\";\nexport * from \"./Icon\";\nexport * from \"./Divider\";\nexport * from \"./Input\";\nexport * from \"./TextArea\";\nexport * from \"./LinearGradient\";\n\nexport const isWeb = false;\nexport const isNative = true;\n","import React, { useCallback, useMemo } from \"react\";\nimport { IconButton } from \"@xsolla/xui-button\";\nimport { Select } from \"@xsolla/xui-select\";\nimport { ArrowLeft, ArrowRight } from \"@xsolla/xui-icons-base\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box } from \"@xsolla/xui-primitives\";\nimport { getMonthInLocale } from \"./utils\";\nimport type { CalendarHeaderProps } from \"./types\";\n\nconst months = [\n \"january\",\n \"february\",\n \"march\",\n \"april\",\n \"may\",\n \"june\",\n \"july\",\n \"august\",\n \"september\",\n \"october\",\n \"november\",\n \"december\",\n];\n\nexport const CalendarHeader: React.FC<CalendarHeaderProps> = ({\n monthDate,\n decreaseMonth,\n increaseMonth,\n changeYear,\n changeMonth,\n prevMonthButtonDisabled,\n nextMonthButtonDisabled,\n locale,\n minDate,\n maxDate,\n contextMenuMaxHeight,\n testID,\n themeMode,\n themeProductContext,\n}) => {\n const handleChangeMonth = useCallback(\n (value: any) => {\n changeMonth(months.indexOf(value as string));\n },\n [changeMonth]\n );\n\n const handleChangeYear = useCallback(\n (value: any) => {\n changeYear(parseInt(value as string, 10));\n },\n [changeYear]\n );\n\n const monthOptions = useMemo(() => {\n return months.map((month, index) => ({\n label: getMonthInLocale(index, locale),\n value: month,\n }));\n }, [locale]);\n\n const yearOptions = useMemo(() => {\n const options = [];\n const yearStart = minDate ? minDate.getFullYear() : 1900;\n const yearEnd = maxDate\n ? maxDate.getFullYear()\n : new Date().getFullYear() + 100;\n for (let i = yearEnd; i >= yearStart; i--) {\n options.push({ value: i.toString(), label: i.toString() });\n }\n return options;\n }, [minDate, maxDate]);\n\n return (\n <Box\n testID={testID}\n width=\"100%\"\n flexDirection=\"row\"\n justifyContent=\"space-between\"\n alignItems=\"center\"\n marginBottom={16}\n gap={8}\n >\n <IconButton\n size=\"xs\"\n tone=\"mono\"\n variant=\"tertiary\"\n onPress={decreaseMonth}\n disabled={prevMonthButtonDisabled}\n icon={<ArrowLeft size={16} />}\n aria-label=\"Previous month\"\n themeMode={themeMode}\n themeProductContext={themeProductContext}\n />\n\n <Box flexDirection=\"row\" flex={1} gap={4}>\n <Box flex={1.5}>\n <Select\n value={months[monthDate.getMonth()]}\n onChange={handleChangeMonth}\n options={monthOptions}\n size=\"sm\"\n maxHeight={contextMenuMaxHeight}\n themeMode={themeMode}\n themeProductContext={themeProductContext}\n />\n </Box>\n <Box flex={1}>\n <Select\n value={monthDate.getFullYear().toString()}\n onChange={handleChangeYear}\n options={yearOptions}\n size=\"sm\"\n maxHeight={contextMenuMaxHeight}\n themeMode={themeMode}\n themeProductContext={themeProductContext}\n />\n </Box>\n </Box>\n\n <IconButton\n size=\"xs\"\n tone=\"mono\"\n variant=\"tertiary\"\n onPress={increaseMonth}\n disabled={nextMonthButtonDisabled}\n icon={<ArrowRight size={16} />}\n aria-label=\"Next month\"\n themeMode={themeMode}\n themeProductContext={themeProductContext}\n />\n </Box>\n );\n};\n","import { format, setMonth } from \"date-fns\";\nimport * as locales from \"date-fns/locale\";\nimport type { CalendarLocaleType } from \"./types\";\n\nconst defaultLocale = \"enUS\";\n\nexport function formatDate(\n date: Date,\n formatStr: string,\n locale: CalendarLocaleType = defaultLocale\n) {\n const localeObj = locales[locale] || locales[defaultLocale];\n\n return format(date, formatStr, {\n locale: localeObj,\n });\n}\n\nexport function getMonthInLocale(\n month: number,\n locale: CalendarLocaleType = defaultLocale\n) {\n return formatDate(setMonth(new Date(), month), \"LLLL\", locale);\n}\n","import React, {\n useMemo,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box, Text, isWeb } from \"@xsolla/xui-primitives\";\nimport { useResolvedTheme } from \"@xsolla/xui-core\";\nimport {\n addDays,\n addMonths,\n eachDayOfInterval,\n endOfDay,\n endOfMonth,\n endOfWeek,\n format,\n isAfter,\n isBefore,\n isSameDay,\n isSameMonth,\n isToday,\n isWithinInterval,\n startOfDay,\n startOfMonth,\n startOfWeek,\n} from \"date-fns\";\nimport * as locales from \"date-fns/locale\";\nimport type { CalendarGridProps } from \"./types\";\n\n/** Width of a single day cell. */\nconst DAY_CELL_WIDTH = 40;\n/**\n * Natural width of the 7-column grid. The header and week rows are pinned to\n * this so the cells sit flush against each other: a range highlight has to read\n * as one continuous band, which it cannot do if the row distributes slack\n * between the cells. See FEP-834.\n */\nconst GRID_WIDTH = DAY_CELL_WIDTH * 7;\n\nconst dayKeyOf = (date: Date) => format(date, \"yyyy-MM-dd\");\n\nexport const CalendarGrid: React.FC<CalendarGridProps> = ({\n currentMonth,\n locale = \"enUS\",\n firstDayOfWeek = 0,\n selectsRange = false,\n minDate,\n maxDate,\n startDate,\n endDate,\n selectedDate,\n selectingRange,\n onDayPress,\n onMonthChange,\n testID,\n themeMode,\n themeProductContext,\n}) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n const localeObj = (locales as any)[locale] || locales.enUS;\n const [hoveredKey, setHoveredKey] = useState<string | null>(null);\n\n const monthStart = startOfMonth(currentMonth);\n const monthEnd = endOfMonth(currentMonth);\n const weekStartsOn = (firstDayOfWeek ?? 0) as any;\n const calendarStart = startOfWeek(monthStart, { weekStartsOn });\n const calendarEnd = endOfWeek(monthEnd, { weekStartsOn });\n\n const days = eachDayOfInterval({ start: calendarStart, end: calendarEnd });\n\n const weekDays = useMemo(() => {\n return Array.from({ length: 7 }, (_, i) => {\n const day = addDays(calendarStart, i);\n return format(day, \"EEEEEE\", { locale: localeObj });\n });\n }, [calendarStart, localeObj]);\n\n const weeks = useMemo(() => {\n const weekArray: Date[][] = [];\n for (let i = 0; i < days.length; i += 7) {\n weekArray.push(days.slice(i, i + 7));\n }\n return weekArray;\n }, [days]);\n\n const isDateDisabled = useCallback(\n (date: Date) => {\n if (minDate && isBefore(date, startOfDay(minDate))) return true;\n if (maxDate && isAfter(date, endOfDay(maxDate))) return true;\n return false;\n },\n [minDate, maxDate]\n );\n\n const isDateInRange = useCallback(\n (date: Date) => {\n if (!selectsRange || !startDate) return false;\n const rangeEnd = endDate || selectingRange;\n if (!rangeEnd) return false;\n const start = startDate < rangeEnd ? startDate : rangeEnd;\n const end = startDate < rangeEnd ? rangeEnd : startDate;\n return isWithinInterval(date, {\n start: startOfDay(start),\n end: endOfDay(end),\n });\n },\n [selectsRange, startDate, endDate, selectingRange]\n );\n\n // Roving tab stop (XUITSD-131): exactly one day of the visible month is in\n // the tab order. Arrow keys move it, Enter/Space select it. It defaults to\n // the selected day, then today, then the first day of the month.\n const [focusedDate, setFocusedDate] = useState<Date | null>(null);\n const dayRefs = useRef<Map<string, HTMLElement>>(new Map());\n const shouldMoveFocus = useRef(false);\n\n const tabStopDate = useMemo(() => {\n if (focusedDate && isSameMonth(focusedDate, currentMonth)) {\n return focusedDate;\n }\n const preferred = selectsRange ? startDate : selectedDate;\n if (preferred && isSameMonth(preferred, currentMonth)) return preferred;\n const today = new Date();\n if (isSameMonth(today, currentMonth)) return today;\n return monthStart;\n }, [\n focusedDate,\n currentMonth,\n selectsRange,\n startDate,\n selectedDate,\n monthStart,\n ]);\n const tabStopKey = dayKeyOf(tabStopDate);\n\n useEffect(() => {\n if (!shouldMoveFocus.current) return;\n shouldMoveFocus.current = false;\n dayRefs.current.get(tabStopKey)?.focus();\n }, [tabStopKey, currentMonth]);\n\n const moveFocus = useCallback(\n (target: Date) => {\n if (!isSameMonth(target, currentMonth)) {\n // Leaving the month needs the parent to change the visible month.\n if (!onMonthChange) return;\n onMonthChange(startOfMonth(target));\n }\n shouldMoveFocus.current = true;\n setFocusedDate(target);\n },\n [currentMonth, onMonthChange]\n );\n\n const handleDayKeyDown = useCallback(\n (event: React.KeyboardEvent, day: Date) => {\n let target: Date | null = null;\n switch (event.key) {\n case \"ArrowLeft\":\n target = addDays(day, -1);\n break;\n case \"ArrowRight\":\n target = addDays(day, 1);\n break;\n case \"ArrowUp\":\n target = addDays(day, -7);\n break;\n case \"ArrowDown\":\n target = addDays(day, 7);\n break;\n case \"Home\":\n target = startOfWeek(day, { weekStartsOn });\n break;\n case \"End\":\n target = endOfWeek(day, { weekStartsOn });\n break;\n case \"PageUp\":\n target = addMonths(day, -1);\n break;\n case \"PageDown\":\n target = addMonths(day, 1);\n break;\n case \"Enter\":\n case \" \":\n event.preventDefault();\n if (!isDateDisabled(day)) onDayPress?.(day);\n return;\n default:\n return;\n }\n event.preventDefault();\n moveFocus(target);\n },\n [isDateDisabled, moveFocus, onDayPress, weekStartsOn]\n );\n\n return (\n <Box testID={testID} role=\"grid\">\n <Box\n role=\"row\"\n flexDirection=\"row\"\n justifyContent=\"flex-start\"\n width={GRID_WIDTH}\n marginBottom={8}\n >\n {weekDays.map((day, i) => (\n <Box\n key={i}\n role=\"columnheader\"\n width={DAY_CELL_WIDTH}\n alignItems=\"center\"\n >\n <Text\n fontSize={12}\n fontWeight=\"600\"\n color={theme.colors.content.tertiary}\n >\n {day.toUpperCase()}\n </Text>\n </Box>\n ))}\n </Box>\n\n <Box gap={2}>\n {weeks.map((week, i) => (\n <Box\n key={i}\n role=\"row\"\n flexDirection=\"row\"\n justifyContent=\"flex-start\"\n width={GRID_WIDTH}\n >\n {week.map((day, j) => {\n const dayKey = dayKeyOf(day);\n const isOutsideMonth = !isSameMonth(day, currentMonth);\n const isSelected =\n (!selectsRange &&\n selectedDate &&\n isSameDay(day, selectedDate)) ||\n (selectsRange &&\n startDate &&\n endDate &&\n isSameDay(day, startDate) &&\n isSameDay(day, endDate));\n const isRangeStart =\n selectsRange && startDate && isSameDay(day, startDate);\n const isRangeEnd =\n selectsRange && endDate && isSameDay(day, endDate);\n const inRange = isDateInRange(day);\n const today = isToday(day);\n const disabled = isDateDisabled(day);\n const isHoverable =\n !disabled &&\n !isOutsideMonth &&\n !isSelected &&\n !isRangeStart &&\n !isRangeEnd;\n const isHovered = isHoverable && hoveredKey === dayKey;\n const isTabStop = !isOutsideMonth && dayKey === tabStopKey;\n\n let bgColor = \"transparent\";\n let textColor = theme.colors.content.primary;\n\n if (isSelected || isRangeStart || isRangeEnd || inRange) {\n bgColor = theme.colors.control.check.bg;\n textColor = theme.colors.control.check.icon;\n } else if (isHovered || today) {\n bgColor = theme.colors.control.check.bgHover;\n textColor = theme.colors.control.check.icon;\n } else if (isOutsideMonth || disabled) {\n textColor = theme.colors.control.text.disable;\n }\n\n // Keyboard props are web-only; native uses its own a11y model.\n const keyboardProps =\n isWeb && !isOutsideMonth\n ? {\n ref: (node: HTMLElement | null) => {\n if (node) dayRefs.current.set(dayKey, node);\n else dayRefs.current.delete(dayKey);\n },\n tabIndex: isTabStop ? 0 : -1,\n onKeyDown: (event: React.KeyboardEvent) =>\n handleDayKeyDown(event, day),\n }\n : {};\n\n return (\n <Box\n key={j}\n {...keyboardProps}\n role=\"gridcell\"\n aria-label={\n isOutsideMonth\n ? undefined\n : format(day, \"EEEE, d MMMM yyyy\", { locale: localeObj })\n }\n aria-selected={\n isOutsideMonth\n ? undefined\n : Boolean(isSelected || isRangeStart || isRangeEnd)\n }\n aria-disabled={disabled || isOutsideMonth || undefined}\n aria-current={today ? \"date\" : undefined}\n width={DAY_CELL_WIDTH}\n height={32}\n alignItems=\"center\"\n justifyContent=\"center\"\n borderTopLeftRadius={isSelected || isRangeStart ? 4 : 0}\n borderTopRightRadius={isSelected || isRangeEnd ? 4 : 0}\n borderBottomLeftRadius={isSelected || isRangeStart ? 4 : 0}\n borderBottomRightRadius={isSelected || isRangeEnd ? 4 : 0}\n backgroundColor={bgColor}\n cursor={disabled || isOutsideMonth ? \"default\" : \"pointer\"}\n onPress={() => {\n if (disabled || isOutsideMonth) return;\n setFocusedDate(day);\n onDayPress?.(day);\n }}\n onMouseEnter={() => isHoverable && setHoveredKey(dayKey)}\n onMouseLeave={() =>\n setHoveredKey((current) =>\n current === dayKey ? null : current\n )\n }\n hoverStyle={\n isHoverable\n ? { backgroundColor: theme.colors.control.check.bgHover }\n : undefined\n }\n >\n <Text\n color={textColor}\n fontSize={14}\n fontWeight={\n isSelected || isRangeStart || isRangeEnd ? \"600\" : \"400\"\n }\n >\n {format(day, \"d\")}\n </Text>\n </Box>\n );\n })}\n </Box>\n ))}\n </Box>\n </Box>\n );\n};\n","import React from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box, Text } from \"@xsolla/xui-primitives\";\nimport { useResolvedTheme } from \"@xsolla/xui-core\";\nimport type { CalendarChipsProps } from \"./types\";\n\nexport const CalendarChips: React.FC<CalendarChipsProps> = ({\n chips,\n activeChip,\n onChipSelect,\n testID,\n themeMode,\n themeProductContext,\n}) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n const toggleColors = theme.colors.control.toggleButton;\n // Tag's sizing scale is a compact-chip scale; toggleButtonGroup's is a\n // full-button scale and renders oversized here. Only the colors come\n // from the toggle-button tokens (to match the Figma selected/hover states).\n const sizeStyles = theme.sizing.tag(\"sm\");\n const borderWidth = sizeStyles.borderWidth;\n\n if (!chips || chips.length === 0) return null;\n\n return (\n <Box\n testID={testID}\n flexDirection=\"row\"\n flexWrap=\"wrap\"\n gap={8}\n marginBottom={16}\n >\n {chips.map((chip) => {\n const isActive = activeChip === chip.value;\n const bgColor = isActive ? toggleColors.bgActive : toggleColors.bg;\n const textColor = isActive ? toggleColors.textActive : toggleColors.text;\n const borderColor = isActive\n ? toggleColors.borderActive\n : toggleColors.border;\n\n return (\n <Box\n key={chip.value}\n as=\"button\"\n role=\"radio\"\n aria-checked={isActive}\n testID={chip.value}\n onPress={() => onChipSelect?.(chip.value)}\n height={sizeStyles.height}\n paddingHorizontal={sizeStyles.padding}\n alignItems=\"center\"\n justifyContent=\"center\"\n backgroundColor={bgColor}\n borderWidth={borderWidth}\n borderColor={borderColor}\n borderStyle=\"solid\"\n borderRadius={sizeStyles.radius}\n cursor=\"pointer\"\n hoverStyle={\n !isActive\n ? {\n backgroundColor: toggleColors.bgHover,\n borderColor: toggleColors.borderHover,\n }\n : undefined\n }\n >\n <Text\n color={textColor}\n fontSize={sizeStyles.fontSize}\n fontWeight=\"400\"\n whiteSpace=\"nowrap\"\n >\n {chip.label}\n </Text>\n </Box>\n );\n })}\n </Box>\n );\n};\n","import { forwardRef, useCallback, useEffect, useState } from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box } from \"@xsolla/xui-primitives\";\nimport { useResolvedTheme } from \"@xsolla/xui-core\";\nimport {\n addMonths,\n isSameMonth,\n subDays,\n subMonths,\n startOfDay,\n} from \"date-fns\";\nimport { CalendarHeader } from \"./CalendarHeader\";\nimport { CalendarGrid } from \"./CalendarGrid\";\nimport { CalendarChips } from \"./CalendarChips\";\nimport type { DualCalendarProps } from \"./types\";\n\nexport const DualCalendar = forwardRef<any, DualCalendarProps>(\n (\n {\n locale = \"enUS\",\n onChange,\n startDate,\n endDate,\n contextMenuMaxHeight,\n topContent,\n bottomContent,\n chips,\n activeChip,\n onChipSelect,\n testID,\n minDate,\n maxDate,\n firstDayOfWeek = 0,\n month,\n initialMonth,\n themeMode,\n themeProductContext,\n },\n ref\n ) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n\n // Each panel owns its visible month (XUITSD-122): navigating one panel\n // must not move the other. The right panel starts one month after the\n // left one, and both are re-paired only when the view is driven from\n // outside (`month`, chips).\n const [leftMonth, setLeftMonth] = useState<Date>(\n (month || initialMonth || startDate || new Date()) as Date\n );\n const [rightMonth, setRightMonth] = useState<Date>(() =>\n addMonths((month || initialMonth || startDate || new Date()) as Date, 1)\n );\n const [selectedStartDate, setSelectedStartDate] = useState<\n Date | null | undefined\n >(startDate);\n const [selectedEndDate, setSelectedEndDate] = useState<\n Date | null | undefined\n >(endDate);\n const [selectingRange, setSelectingRange] = useState<Date | null>(null);\n\n /** Show `date`'s month in the left panel and the next month on the right. */\n const showFrom = useCallback((date: Date) => {\n setLeftMonth(date);\n setRightMonth(addMonths(date, 1));\n }, []);\n\n useEffect(() => {\n setSelectedStartDate(startDate);\n setSelectedEndDate(endDate);\n }, [startDate, endDate]);\n\n // Follow the controlled `month` only when it actually changes (by\n // year+month, so a consumer re-creating the Date each render is a no-op),\n // and only when that month is not already on screen. Re-pairing the\n // panels on every `startDate`/`endDate` change made a click in the right\n // panel shift both panels.\n const monthKey = month ? month.getFullYear() * 12 + month.getMonth() : null;\n useEffect(() => {\n if (!month) return;\n if (isSameMonth(month, leftMonth) || isSameMonth(month, rightMonth)) {\n return;\n }\n showFrom(month);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [monthKey]);\n\n const startNewRange = useCallback(\n (date: Date) => {\n setSelectedStartDate(date);\n setSelectedEndDate(null);\n setSelectingRange(date);\n onChange?.([date, null]);\n },\n [onChange]\n );\n\n const completeRange = useCallback(\n (start: Date, end: Date) => {\n setSelectedStartDate(start);\n setSelectedEndDate(end);\n setSelectingRange(null);\n onChange?.([start, end]);\n },\n [onChange]\n );\n\n const handleDayPress = useCallback(\n (date: Date, panel: \"left\" | \"right\") => {\n const newDate = new Date(\n date.getFullYear(),\n date.getMonth(),\n date.getDate()\n );\n\n if (!selectedStartDate) {\n startNewRange(newDate);\n return;\n }\n\n if (selectedEndDate) {\n // With a complete range, the right panel edits the end of the period\n // (XUITSD-122). A day before the start can't be an end, so it starts\n // a new range instead, as does any click in the left panel.\n if (panel === \"right\" && newDate >= selectedStartDate) {\n completeRange(selectedStartDate, newDate);\n } else {\n startNewRange(newDate);\n }\n return;\n }\n\n const start = selectedStartDate < newDate ? selectedStartDate : newDate;\n const end = selectedStartDate < newDate ? newDate : selectedStartDate;\n completeRange(start, end);\n },\n [selectedStartDate, selectedEndDate, startNewRange, completeRange]\n );\n\n const handleLeftDayPress = useCallback(\n (date: Date) => handleDayPress(date, \"left\"),\n [handleDayPress]\n );\n const handleRightDayPress = useCallback(\n (date: Date) => handleDayPress(date, \"right\"),\n [handleDayPress]\n );\n\n const decreaseLeftMonth = useCallback(\n () => setLeftMonth((prev) => subMonths(prev, 1)),\n []\n );\n const increaseLeftMonth = useCallback(\n () => setLeftMonth((prev) => addMonths(prev, 1)),\n []\n );\n const changeLeftMonth = useCallback(\n (m: number) => setLeftMonth((prev) => new Date(prev.getFullYear(), m, 1)),\n []\n );\n const changeLeftYear = useCallback(\n (y: number) => setLeftMonth((prev) => new Date(y, prev.getMonth(), 1)),\n []\n );\n\n const decreaseRightMonth = useCallback(\n () => setRightMonth((prev) => subMonths(prev, 1)),\n []\n );\n const increaseRightMonth = useCallback(\n () => setRightMonth((prev) => addMonths(prev, 1)),\n []\n );\n const changeRightMonth = useCallback(\n (m: number) =>\n setRightMonth((prev) => new Date(prev.getFullYear(), m, 1)),\n []\n );\n const changeRightYear = useCallback(\n (y: number) => setRightMonth((prev) => new Date(y, prev.getMonth(), 1)),\n []\n );\n\n const handleChipSelect = useCallback(\n (value: string | null) => {\n onChipSelect?.(value);\n\n const chip = chips?.find((c) => c.value === value);\n if (!chip || chip.days === undefined) return;\n\n const today = startOfDay(new Date());\n\n if (chip.days === 0) {\n setSelectedStartDate(today);\n setSelectedEndDate(today);\n setSelectingRange(null);\n showFrom(today);\n onChange?.([today, today]);\n return;\n }\n\n const start = subDays(today, chip.days);\n setSelectedStartDate(start);\n setSelectedEndDate(today);\n setSelectingRange(null);\n showFrom(start);\n onChange?.([start, today]);\n },\n [chips, onChange, onChipSelect, showFrom]\n );\n\n return (\n <Box\n ref={ref}\n testID={testID}\n backgroundColor={theme.colors.layer.float}\n borderRadius={theme.shape.contextMenu.md.borderRadius}\n padding={16}\n overflow=\"hidden\"\n style={{\n boxShadow:\n \"0px 2px 3px 0px rgba(7, 7, 8, 0.2), 0px 6px 10px 4px rgba(7, 7, 8, 0.1)\",\n width: 624,\n }}\n >\n {topContent?.({ close: () => {} })}\n\n {chips && chips.length > 0 && (\n <CalendarChips\n chips={chips}\n activeChip={activeChip}\n onChipSelect={handleChipSelect}\n themeMode={themeMode}\n themeProductContext={themeProductContext}\n />\n )}\n\n <Box flexDirection=\"row\" gap={16}>\n <Box flex={1}>\n <CalendarHeader\n monthDate={leftMonth}\n decreaseMonth={decreaseLeftMonth}\n increaseMonth={increaseLeftMonth}\n changeYear={changeLeftYear}\n changeMonth={changeLeftMonth}\n locale={locale}\n minDate={minDate}\n maxDate={maxDate}\n contextMenuMaxHeight={contextMenuMaxHeight}\n themeMode={themeMode}\n themeProductContext={themeProductContext}\n />\n\n <CalendarGrid\n currentMonth={leftMonth}\n locale={locale}\n firstDayOfWeek={firstDayOfWeek}\n selectsRange\n minDate={minDate}\n maxDate={maxDate}\n startDate={selectedStartDate}\n endDate={selectedEndDate}\n selectingRange={selectingRange}\n onDayPress={handleLeftDayPress}\n themeMode={themeMode}\n themeProductContext={themeProductContext}\n />\n </Box>\n\n <Box flex={1}>\n <CalendarHeader\n monthDate={rightMonth}\n decreaseMonth={decreaseRightMonth}\n increaseMonth={increaseRightMonth}\n changeYear={changeRightYear}\n changeMonth={changeRightMonth}\n locale={locale}\n minDate={minDate}\n maxDate={maxDate}\n contextMenuMaxHeight={contextMenuMaxHeight}\n themeMode={themeMode}\n themeProductContext={themeProductContext}\n />\n\n <CalendarGrid\n currentMonth={rightMonth}\n locale={locale}\n firstDayOfWeek={firstDayOfWeek}\n selectsRange\n minDate={minDate}\n maxDate={maxDate}\n startDate={selectedStartDate}\n endDate={selectedEndDate}\n selectingRange={selectingRange}\n onDayPress={handleRightDayPress}\n themeMode={themeMode}\n themeProductContext={themeProductContext}\n />\n </Box>\n </Box>\n\n {bottomContent?.({ close: () => {} })}\n </Box>\n );\n }\n);\n\nDualCalendar.displayName = \"DualCalendar\";\n"],"mappings":"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","names":["useCallback","useEffect","useState","jsx","useResolvedTheme","addMonths","startOfDay","jsx","useMemo","useCallback","format","locales","jsx","jsxs","useMemo","useCallback","useResolvedTheme","jsx","jsx","jsxs","useResolvedTheme","useState","useEffect","useCallback","addMonths","startOfDay","forwardRef","useCallback","useEffect","useState","useResolvedTheme","addMonths","isSameMonth","subDays","subMonths","startOfDay","jsx","jsxs","forwardRef","useResolvedTheme","useState","addMonths","useCallback","useEffect","isSameMonth","subMonths","startOfDay","subDays"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xsolla/xui-calendar",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.228.0",
|
|
4
4
|
"main": "./web/index.js",
|
|
5
5
|
"module": "./web/index.mjs",
|
|
6
6
|
"types": "./web/index.d.ts",
|
|
@@ -13,12 +13,12 @@
|
|
|
13
13
|
"test:coverage": "vitest run --coverage"
|
|
14
14
|
},
|
|
15
15
|
"dependencies": {
|
|
16
|
-
"@xsolla/xui-button": "0.
|
|
17
|
-
"@xsolla/xui-core": "0.
|
|
18
|
-
"@xsolla/xui-icons-base": "0.
|
|
19
|
-
"@xsolla/xui-primitives-core": "0.
|
|
20
|
-
"@xsolla/xui-select": "0.
|
|
21
|
-
"@xsolla/xui-tag": "0.
|
|
16
|
+
"@xsolla/xui-button": "0.228.0",
|
|
17
|
+
"@xsolla/xui-core": "0.228.0",
|
|
18
|
+
"@xsolla/xui-icons-base": "0.228.0",
|
|
19
|
+
"@xsolla/xui-primitives-core": "0.228.0",
|
|
20
|
+
"@xsolla/xui-select": "0.228.0",
|
|
21
|
+
"@xsolla/xui-tag": "0.228.0",
|
|
22
22
|
"date-fns": "^3.0.0"
|
|
23
23
|
},
|
|
24
24
|
"peerDependencies": {
|
package/web/index.d.mts
CHANGED
|
@@ -40,6 +40,12 @@ interface CalendarGridProps extends ThemeOverrideProps {
|
|
|
40
40
|
selectedDate?: Date | null;
|
|
41
41
|
selectingRange?: Date | null;
|
|
42
42
|
onDayPress?: (date: Date) => void;
|
|
43
|
+
/**
|
|
44
|
+
* Called with the first day of a month when keyboard navigation moves past
|
|
45
|
+
* the visible month (arrow keys, PageUp/PageDown). Without it, keyboard
|
|
46
|
+
* focus stays inside the visible month.
|
|
47
|
+
*/
|
|
48
|
+
onMonthChange?: (month: Date) => void;
|
|
43
49
|
testID?: string;
|
|
44
50
|
}
|
|
45
51
|
interface CalendarHeaderProps extends ThemeOverrideProps {
|
package/web/index.d.ts
CHANGED
|
@@ -40,6 +40,12 @@ interface CalendarGridProps extends ThemeOverrideProps {
|
|
|
40
40
|
selectedDate?: Date | null;
|
|
41
41
|
selectingRange?: Date | null;
|
|
42
42
|
onDayPress?: (date: Date) => void;
|
|
43
|
+
/**
|
|
44
|
+
* Called with the first day of a month when keyboard navigation moves past
|
|
45
|
+
* the visible month (arrow keys, PageUp/PageDown). Without it, keyboard
|
|
46
|
+
* focus stays inside the visible month.
|
|
47
|
+
*/
|
|
48
|
+
onMonthChange?: (month: Date) => void;
|
|
43
49
|
testID?: string;
|
|
44
50
|
}
|
|
45
51
|
interface CalendarHeaderProps extends ThemeOverrideProps {
|
package/web/index.js
CHANGED
|
@@ -378,6 +378,9 @@ var Text = ({
|
|
|
378
378
|
);
|
|
379
379
|
};
|
|
380
380
|
|
|
381
|
+
// ../../foundation/primitives-web/src/index.tsx
|
|
382
|
+
var isWeb = true;
|
|
383
|
+
|
|
381
384
|
// src/Calendar.tsx
|
|
382
385
|
var import_xui_core3 = require("@xsolla/xui-core");
|
|
383
386
|
var import_date_fns3 = require("date-fns");
|
|
@@ -539,6 +542,7 @@ var locales2 = __toESM(require("date-fns/locale"));
|
|
|
539
542
|
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
540
543
|
var DAY_CELL_WIDTH = 40;
|
|
541
544
|
var GRID_WIDTH = DAY_CELL_WIDTH * 7;
|
|
545
|
+
var dayKeyOf = (date) => (0, import_date_fns2.format)(date, "yyyy-MM-dd");
|
|
542
546
|
var CalendarGrid = ({
|
|
543
547
|
currentMonth,
|
|
544
548
|
locale = "enUS",
|
|
@@ -551,6 +555,7 @@ var CalendarGrid = ({
|
|
|
551
555
|
selectedDate,
|
|
552
556
|
selectingRange,
|
|
553
557
|
onDayPress,
|
|
558
|
+
onMonthChange,
|
|
554
559
|
testID,
|
|
555
560
|
themeMode,
|
|
556
561
|
themeProductContext
|
|
@@ -599,33 +604,122 @@ var CalendarGrid = ({
|
|
|
599
604
|
},
|
|
600
605
|
[selectsRange, startDate, endDate, selectingRange]
|
|
601
606
|
);
|
|
602
|
-
|
|
607
|
+
const [focusedDate, setFocusedDate] = (0, import_react4.useState)(null);
|
|
608
|
+
const dayRefs = (0, import_react4.useRef)(/* @__PURE__ */ new Map());
|
|
609
|
+
const shouldMoveFocus = (0, import_react4.useRef)(false);
|
|
610
|
+
const tabStopDate = (0, import_react4.useMemo)(() => {
|
|
611
|
+
if (focusedDate && (0, import_date_fns2.isSameMonth)(focusedDate, currentMonth)) {
|
|
612
|
+
return focusedDate;
|
|
613
|
+
}
|
|
614
|
+
const preferred = selectsRange ? startDate : selectedDate;
|
|
615
|
+
if (preferred && (0, import_date_fns2.isSameMonth)(preferred, currentMonth)) return preferred;
|
|
616
|
+
const today = /* @__PURE__ */ new Date();
|
|
617
|
+
if ((0, import_date_fns2.isSameMonth)(today, currentMonth)) return today;
|
|
618
|
+
return monthStart;
|
|
619
|
+
}, [
|
|
620
|
+
focusedDate,
|
|
621
|
+
currentMonth,
|
|
622
|
+
selectsRange,
|
|
623
|
+
startDate,
|
|
624
|
+
selectedDate,
|
|
625
|
+
monthStart
|
|
626
|
+
]);
|
|
627
|
+
const tabStopKey = dayKeyOf(tabStopDate);
|
|
628
|
+
(0, import_react4.useEffect)(() => {
|
|
629
|
+
if (!shouldMoveFocus.current) return;
|
|
630
|
+
shouldMoveFocus.current = false;
|
|
631
|
+
dayRefs.current.get(tabStopKey)?.focus();
|
|
632
|
+
}, [tabStopKey, currentMonth]);
|
|
633
|
+
const moveFocus = (0, import_react4.useCallback)(
|
|
634
|
+
(target) => {
|
|
635
|
+
if (!(0, import_date_fns2.isSameMonth)(target, currentMonth)) {
|
|
636
|
+
if (!onMonthChange) return;
|
|
637
|
+
onMonthChange((0, import_date_fns2.startOfMonth)(target));
|
|
638
|
+
}
|
|
639
|
+
shouldMoveFocus.current = true;
|
|
640
|
+
setFocusedDate(target);
|
|
641
|
+
},
|
|
642
|
+
[currentMonth, onMonthChange]
|
|
643
|
+
);
|
|
644
|
+
const handleDayKeyDown = (0, import_react4.useCallback)(
|
|
645
|
+
(event, day) => {
|
|
646
|
+
let target = null;
|
|
647
|
+
switch (event.key) {
|
|
648
|
+
case "ArrowLeft":
|
|
649
|
+
target = (0, import_date_fns2.addDays)(day, -1);
|
|
650
|
+
break;
|
|
651
|
+
case "ArrowRight":
|
|
652
|
+
target = (0, import_date_fns2.addDays)(day, 1);
|
|
653
|
+
break;
|
|
654
|
+
case "ArrowUp":
|
|
655
|
+
target = (0, import_date_fns2.addDays)(day, -7);
|
|
656
|
+
break;
|
|
657
|
+
case "ArrowDown":
|
|
658
|
+
target = (0, import_date_fns2.addDays)(day, 7);
|
|
659
|
+
break;
|
|
660
|
+
case "Home":
|
|
661
|
+
target = (0, import_date_fns2.startOfWeek)(day, { weekStartsOn });
|
|
662
|
+
break;
|
|
663
|
+
case "End":
|
|
664
|
+
target = (0, import_date_fns2.endOfWeek)(day, { weekStartsOn });
|
|
665
|
+
break;
|
|
666
|
+
case "PageUp":
|
|
667
|
+
target = (0, import_date_fns2.addMonths)(day, -1);
|
|
668
|
+
break;
|
|
669
|
+
case "PageDown":
|
|
670
|
+
target = (0, import_date_fns2.addMonths)(day, 1);
|
|
671
|
+
break;
|
|
672
|
+
case "Enter":
|
|
673
|
+
case " ":
|
|
674
|
+
event.preventDefault();
|
|
675
|
+
if (!isDateDisabled(day)) onDayPress?.(day);
|
|
676
|
+
return;
|
|
677
|
+
default:
|
|
678
|
+
return;
|
|
679
|
+
}
|
|
680
|
+
event.preventDefault();
|
|
681
|
+
moveFocus(target);
|
|
682
|
+
},
|
|
683
|
+
[isDateDisabled, moveFocus, onDayPress, weekStartsOn]
|
|
684
|
+
);
|
|
685
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Box, { testID, role: "grid", children: [
|
|
603
686
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
604
687
|
Box,
|
|
605
688
|
{
|
|
689
|
+
role: "row",
|
|
606
690
|
flexDirection: "row",
|
|
607
691
|
justifyContent: "flex-start",
|
|
608
692
|
width: GRID_WIDTH,
|
|
609
693
|
marginBottom: 8,
|
|
610
|
-
children: weekDays.map((day, i) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
611
|
-
|
|
694
|
+
children: weekDays.map((day, i) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
695
|
+
Box,
|
|
612
696
|
{
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
children:
|
|
617
|
-
|
|
618
|
-
|
|
697
|
+
role: "columnheader",
|
|
698
|
+
width: DAY_CELL_WIDTH,
|
|
699
|
+
alignItems: "center",
|
|
700
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
701
|
+
Text,
|
|
702
|
+
{
|
|
703
|
+
fontSize: 12,
|
|
704
|
+
fontWeight: "600",
|
|
705
|
+
color: theme.colors.content.tertiary,
|
|
706
|
+
children: day.toUpperCase()
|
|
707
|
+
}
|
|
708
|
+
)
|
|
709
|
+
},
|
|
710
|
+
i
|
|
711
|
+
))
|
|
619
712
|
}
|
|
620
713
|
),
|
|
621
714
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Box, { gap: 2, children: weeks.map((week, i) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
622
715
|
Box,
|
|
623
716
|
{
|
|
717
|
+
role: "row",
|
|
624
718
|
flexDirection: "row",
|
|
625
719
|
justifyContent: "flex-start",
|
|
626
720
|
width: GRID_WIDTH,
|
|
627
721
|
children: week.map((day, j) => {
|
|
628
|
-
const dayKey = (
|
|
722
|
+
const dayKey = dayKeyOf(day);
|
|
629
723
|
const isOutsideMonth = !(0, import_date_fns2.isSameMonth)(day, currentMonth);
|
|
630
724
|
const isSelected = !selectsRange && selectedDate && (0, import_date_fns2.isSameDay)(day, selectedDate) || selectsRange && startDate && endDate && (0, import_date_fns2.isSameDay)(day, startDate) && (0, import_date_fns2.isSameDay)(day, endDate);
|
|
631
725
|
const isRangeStart = selectsRange && startDate && (0, import_date_fns2.isSameDay)(day, startDate);
|
|
@@ -635,6 +729,7 @@ var CalendarGrid = ({
|
|
|
635
729
|
const disabled = isDateDisabled(day);
|
|
636
730
|
const isHoverable = !disabled && !isOutsideMonth && !isSelected && !isRangeStart && !isRangeEnd;
|
|
637
731
|
const isHovered = isHoverable && hoveredKey === dayKey;
|
|
732
|
+
const isTabStop = !isOutsideMonth && dayKey === tabStopKey;
|
|
638
733
|
let bgColor = "transparent";
|
|
639
734
|
let textColor = theme.colors.content.primary;
|
|
640
735
|
if (isSelected || isRangeStart || isRangeEnd || inRange) {
|
|
@@ -646,9 +741,23 @@ var CalendarGrid = ({
|
|
|
646
741
|
} else if (isOutsideMonth || disabled) {
|
|
647
742
|
textColor = theme.colors.control.text.disable;
|
|
648
743
|
}
|
|
744
|
+
const keyboardProps = isWeb && !isOutsideMonth ? {
|
|
745
|
+
ref: (node) => {
|
|
746
|
+
if (node) dayRefs.current.set(dayKey, node);
|
|
747
|
+
else dayRefs.current.delete(dayKey);
|
|
748
|
+
},
|
|
749
|
+
tabIndex: isTabStop ? 0 : -1,
|
|
750
|
+
onKeyDown: (event) => handleDayKeyDown(event, day)
|
|
751
|
+
} : {};
|
|
649
752
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
650
753
|
Box,
|
|
651
754
|
{
|
|
755
|
+
...keyboardProps,
|
|
756
|
+
role: "gridcell",
|
|
757
|
+
"aria-label": isOutsideMonth ? void 0 : (0, import_date_fns2.format)(day, "EEEE, d MMMM yyyy", { locale: localeObj }),
|
|
758
|
+
"aria-selected": isOutsideMonth ? void 0 : Boolean(isSelected || isRangeStart || isRangeEnd),
|
|
759
|
+
"aria-disabled": disabled || isOutsideMonth || void 0,
|
|
760
|
+
"aria-current": today ? "date" : void 0,
|
|
652
761
|
width: DAY_CELL_WIDTH,
|
|
653
762
|
height: 32,
|
|
654
763
|
alignItems: "center",
|
|
@@ -659,7 +768,11 @@ var CalendarGrid = ({
|
|
|
659
768
|
borderBottomRightRadius: isSelected || isRangeEnd ? 4 : 0,
|
|
660
769
|
backgroundColor: bgColor,
|
|
661
770
|
cursor: disabled || isOutsideMonth ? "default" : "pointer",
|
|
662
|
-
onPress: () =>
|
|
771
|
+
onPress: () => {
|
|
772
|
+
if (disabled || isOutsideMonth) return;
|
|
773
|
+
setFocusedDate(day);
|
|
774
|
+
onDayPress?.(day);
|
|
775
|
+
},
|
|
663
776
|
onMouseEnter: () => isHoverable && setHoveredKey(dayKey),
|
|
664
777
|
onMouseLeave: () => setHoveredKey(
|
|
665
778
|
(current) => current === dayKey ? null : current
|
|
@@ -927,6 +1040,7 @@ var Calendar = (0, import_react5.forwardRef)(
|
|
|
927
1040
|
selectedDate: locSelectedDate,
|
|
928
1041
|
selectingRange,
|
|
929
1042
|
onDayPress: handleChange,
|
|
1043
|
+
onMonthChange: setCurrentMonth,
|
|
930
1044
|
themeMode,
|
|
931
1045
|
themeProductContext
|
|
932
1046
|
}
|