@moneyforward/mfui-components 4.3.1 → 4.6.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.
Files changed (108) hide show
  1. package/dist/src/Accordion/Accordion.d.ts +21 -1
  2. package/dist/src/Accordion/Accordion.js +28 -4
  3. package/dist/src/Accordion/Accordion.types.d.ts +21 -0
  4. package/dist/src/Badge/Badge.d.ts +1 -1
  5. package/dist/src/Badge/Badge.js +4 -4
  6. package/dist/src/Badge/Badge.types.d.ts +3 -1
  7. package/dist/src/Breadcrumbs/Breadcrumbs.js +1 -1
  8. package/dist/src/Checkbox/Checkbox.js +7 -3
  9. package/dist/src/CheckboxCard/CheckboxCard.js +3 -1
  10. package/dist/src/DataTable/DataTable.js +9 -2
  11. package/dist/src/DataTable/DataTable.types.d.ts +17 -2
  12. package/dist/src/DataTable/DataTableCell/DataTableCell.js +21 -4
  13. package/dist/src/DataTable/DataTableCell/DataTableCell.types.d.ts +1 -1
  14. package/dist/src/DataTable/DataTableHeaderRow/DataTableHeaderRow.js +9 -5
  15. package/dist/src/DataTable/DataTableHeaderRow/DataTableHeaderRow.types.d.ts +19 -1
  16. package/dist/src/DataTable/DataTableRow/DataTableRow.js +106 -31
  17. package/dist/src/DataTable/DataTableRow/DataTableRow.types.d.ts +63 -12
  18. package/dist/src/DataTable/DataTableRowActionContext.d.ts +34 -0
  19. package/dist/src/DataTable/DataTableRowActionContext.js +8 -0
  20. package/dist/src/DateTimeSelection/DatePicker/DatePickerCalendar/DatePickerCalendar.js +7 -3
  21. package/dist/src/DateTimeSelection/DatePicker/DatePickerDateCell/index.d.ts +1 -1
  22. package/dist/src/DateTimeSelection/DatePicker/DatePickerDateCell/index.js +0 -1
  23. package/dist/src/DateTimeSelection/DateRangePicker/DateRangePickerPopover/DateRangePickerCalendar/DateRangePickerCalendar.js +1 -1
  24. package/dist/src/DateTimeSelection/DateRangePicker/DateRangePickerPopover/utilities/createDateRangePickerPopoverTestUtility.js +2 -2
  25. package/dist/src/DateTimeSelection/DateRangePicker/DateRangePickerProvider/DateRangePickerProvider.js +13 -7
  26. package/dist/src/DateTimeSelection/DateRangePicker/DateRangePickerTrigger/DateRangePickerTrigger.js +1 -1
  27. package/dist/src/DateTimeSelection/FilterDatePicker/FilterDatePicker.js +1 -1
  28. package/dist/src/DateTimeSelection/FilterMonthPicker/FilterMonthPicker.js +1 -1
  29. package/dist/src/DateTimeSelection/FilterMonthRangePicker/FilterMonthRangePicker.js +1 -1
  30. package/dist/src/DateTimeSelection/MonthPicker/MonthPickerPanel/MonthPickerPanel.js +1 -1
  31. package/dist/src/DateTimeSelection/MonthPicker/constants.d.ts +2 -2
  32. package/dist/src/DateTimeSelection/MonthPicker/constants.js +6 -6
  33. package/dist/src/DateTimeSelection/MonthRangePicker/MonthRangePickerMonthCell/MonthRangePickerMonthCell.js +1 -1
  34. package/dist/src/DateTimeSelection/MonthRangePicker/MonthRangePickerNavigation/MonthRangePickerNavigation.js +2 -2
  35. package/dist/src/DateTimeSelection/TimePicker/TimePicker.js +1 -1
  36. package/dist/src/DateTimeSelection/shared/BasePicker/constants.d.ts +2 -2
  37. package/dist/src/DateTimeSelection/shared/BasePicker/constants.js +10 -10
  38. package/dist/src/DateTimeSelection/shared/BaseRangePicker/BaseRangePickerPopover/BaseRangePickerCalendar/BaseRangePickerCalendar.js +1 -1
  39. package/dist/src/DateTimeSelection/shared/BaseRangePicker/BaseRangePickerPopover/constants.js +4 -4
  40. package/dist/src/DateTimeSelection/shared/BaseRangePicker/BaseRangePickerProvider/BaseRangePickerProvider.js +13 -7
  41. package/dist/src/DateTimeSelection/shared/BaseRangePicker/BaseRangePickerTrigger/BaseRangePickerTrigger.js +2 -2
  42. package/dist/src/DateTimeSelection/shared/CalendarGrid/CalendarGrid.js +2 -4
  43. package/dist/src/DateTimeSelection/shared/utilities/japaneseCalendar.js +2 -2
  44. package/dist/src/Dialog/Dialog.d.ts +1 -1
  45. package/dist/src/Dialog/Dialog.types.d.ts +1 -1
  46. package/dist/src/FileDropZone/FileDropZone.js +1 -1
  47. package/dist/src/FileDropZone/utils/fileHelpers.js +1 -1
  48. package/dist/src/MainNavigation/BaseMainNavigation.d.ts +1 -1
  49. package/dist/src/MainNavigation/BaseMainNavigation.js +3 -3
  50. package/dist/src/MainNavigation/MainNavigation.js +2 -1
  51. package/dist/src/MainNavigation/MainNavigation.types.d.ts +9 -0
  52. package/dist/src/MainNavigation/NarrowViewportMainNavigation.js +3 -3
  53. package/dist/src/MultipleSelectBox/MultipleSelectBox.js +27 -18
  54. package/dist/src/MultipleSelectBox/MultipleSelectBoxTrigger/MultipleSelectBoxTrigger.js +1 -1
  55. package/dist/src/MultipleSelectBox/hooks/useCreateOption.js +8 -4
  56. package/dist/src/MultipleSelectBox/hooks/useInitialFocusOnOptionPanelOpen.js +1 -1
  57. package/dist/src/MultipleSelectBox/hooks/useOptionKeyboardNavigation.js +9 -4
  58. package/dist/src/MultipleSelectBox/hooks/useSelectedValues.js +16 -50
  59. package/dist/src/NavigationList/NavigationListItem/NavigationListItem.d.ts +3 -0
  60. package/dist/src/NavigationList/NavigationListItem/NavigationListItem.js +6 -2
  61. package/dist/src/NavigationList/NavigationListItem/NavigationListItem.types.d.ts +2 -1
  62. package/dist/src/NumberBox/NumberBox.d.ts +5 -0
  63. package/dist/src/NumberBox/NumberBox.js +61 -6
  64. package/dist/src/NumberBox/NumberBox.types.d.ts +35 -0
  65. package/dist/src/PageHeader/PageHeader.types.d.ts +2 -0
  66. package/dist/src/Pagination/Pagination.js +4 -1
  67. package/dist/src/Popover/Popover.js +12 -4
  68. package/dist/src/RadioButtonCard/RadioButtonCard.js +3 -1
  69. package/dist/src/SelectBox/SelectBox.js +29 -21
  70. package/dist/src/SelectBox/hooks/useKeyboardNavigation.js +8 -2
  71. package/dist/src/SelectBox/utils/getFlatOptions.js +1 -1
  72. package/dist/src/SidePane/SidePane.js +87 -7
  73. package/dist/src/SidePane/SidePane.types.d.ts +39 -0
  74. package/dist/src/SplitView/hooks/useSplitViewPanelVisibility.js +5 -2
  75. package/dist/src/SubNavigation/SubNavigation.d.ts +10 -1
  76. package/dist/src/SubNavigation/SubNavigation.js +93 -21
  77. package/dist/src/SubNavigation/SubNavigation.types.d.ts +45 -7
  78. package/dist/src/Tabs/Tabs.js +8 -4
  79. package/dist/src/Tabs/hooks/useCalculatedSelectedTabId.js +7 -5
  80. package/dist/src/Tabs/hooks/useTabRegistry.js +5 -5
  81. package/dist/src/Toast/ToastContainer/ToastContainer.js +11 -2
  82. package/dist/src/ToggleSwitch/index.d.ts +1 -1
  83. package/dist/src/ToggleSwitch/index.js +0 -1
  84. package/dist/src/Tooltip/Tooltip.js +8 -3
  85. package/dist/src/Tooltip/hooks/useTooltipDisplayController.js +77 -88
  86. package/dist/src/utilities/dom/containsAcrossShadowRoots.d.ts +21 -0
  87. package/dist/src/utilities/dom/containsAcrossShadowRoots.js +33 -0
  88. package/dist/src/utilities/dom/getFocusableNodes.js +1 -3
  89. package/dist/src/utilities/dom/useFixedColumns.js +6 -8
  90. package/dist/src/utilities/dom/useFocusTrap.js +1 -1
  91. package/dist/src/utilities/dom/useTableEdgeCellMarkers.d.ts +56 -0
  92. package/dist/src/utilities/dom/useTableEdgeCellMarkers.js +223 -0
  93. package/dist/src/utilities/react/flattenChildren.d.ts +15 -0
  94. package/dist/src/utilities/react/flattenChildren.js +28 -0
  95. package/dist/src/utilities/state/useLatest.d.ts +1 -1
  96. package/dist/src/utilities/state/useLatest.js +8 -2
  97. package/dist/styled-system/recipes/badge-slot-recipe.d.ts +1 -1
  98. package/dist/styled-system/recipes/badge-slot-recipe.js +4 -0
  99. package/dist/styled-system/recipes/data-table-cell-slot-recipe.d.ts +1 -1
  100. package/dist/styled-system/recipes/data-table-cell-slot-recipe.js +8 -2
  101. package/dist/styled-system/recipes/data-table-row-slot-recipe.js +13 -6
  102. package/dist/styled-system/recipes/sub-navigation-slot-recipe.d.ts +1 -1
  103. package/dist/styled-system/recipes/sub-navigation-slot-recipe.js +12 -0
  104. package/dist/styles.css +175 -39
  105. package/dist/tsconfig.build.tsbuildinfo +1 -1
  106. package/package.json +12 -12
  107. /package/dist/src/{MultipleSelectBox/utils → utilities/dom}/getDeepActiveElement.d.ts +0 -0
  108. /package/dist/src/{MultipleSelectBox/utils → utilities/dom}/getDeepActiveElement.js +0 -0
@@ -1,5 +1,6 @@
1
- import { type ComponentPropsWithRef } from 'react';
1
+ import { type ComponentPropsWithRef, type ComponentPropsWithoutRef } from 'react';
2
2
  import { type CheckboxProps } from '../../Checkbox';
3
+ import { type DataTableSelectionCheckboxWrapper } from '../DataTable.types';
3
4
  /**
4
5
  * The props for the `DataTableRow` component.
5
6
  *
@@ -10,7 +11,7 @@ import { type CheckboxProps } from '../../Checkbox';
10
11
  export type DataTableRowProps = {
11
12
  /**
12
13
  * Whether the row is disabled.
13
- * When true, interaction when the row is clicked and the checkbox for selectable feature will be disabled.
14
+ * When true, interaction when the row is clicked, the row action button and the checkbox for selectable feature will be disabled.
14
15
  * The row content remains visible with appropriate styling for readability.
15
16
  * Interactive elements passed as a children for DataTable.Cell won't be disabled automatically.
16
17
  *
@@ -18,8 +19,13 @@ export type DataTableRowProps = {
18
19
  */
19
20
  disabled?: boolean;
20
21
  /**
21
- * The state of the row whether it is highlighted without a selected.
22
- * This prop displays a highlighted background color regardless of the `enableRowSelection` prop of the DataTable component.
22
+ * Whether the row displays the highlighted background color.
23
+ * This prop works regardless of the `enableRowSelection` prop of the `DataTable` component: on a selectable table
24
+ * the row is highlighted when this prop is `true` OR when `checkboxProps.checked` is `true`, so a row can be
25
+ * highlighted while it is not selected.
26
+ *
27
+ * Note that the highlighted background is the same color as the selected one, so on a selectable table the
28
+ * selection checkbox, not the background, is what tells a selected row from a merely highlighted one.
23
29
  *
24
30
  * @default false
25
31
  */
@@ -38,29 +44,74 @@ export type DataTableRowProps = {
38
44
  * @property onClick - The handler called when the checkbox is clicked (for event propagation control).
39
45
  *
40
46
  * @property disabled - Whether the checkbox is disabled.
47
+ *
48
+ * @property wrapper - The function that wraps the checkbox, for example with the `Tooltip` component.
49
+ * It receives the checkbox element and must render it as it is, because the row owns the checkbox itself.
50
+ * Keep the `Tooltip` component with its default `trigger` (`['hover', 'focus']`) so that keyboard users can also
51
+ * read the content; a tooltip opened by a click would duplicate the action of the checkbox.
52
+ * When the content restates the accessible name of the checkbox, pass `hideFromScreenReader` to the `Tooltip`
53
+ * component to avoid announcing the same information twice.
54
+ *
55
+ * ```tsx
56
+ * <DataTable.Row
57
+ * checkboxProps={{
58
+ * wrapper: (checkbox) => <Tooltip content="この行を選択">{checkbox}</Tooltip>,
59
+ * }}
60
+ * >
61
+ * ```
41
62
  */
42
- checkboxProps?: Pick<CheckboxProps, 'aria-label' | 'checked' | 'onChange' | 'disabled' | 'onClick'>;
63
+ checkboxProps?: Pick<CheckboxProps, 'aria-label' | 'checked' | 'onChange' | 'disabled' | 'onClick'> & {
64
+ wrapper?: DataTableSelectionCheckboxWrapper;
65
+ };
43
66
  /**
44
67
  * The callback function that is called when the row is clicked.
45
- * If provided, the row can be focused and the focus indicator is displayed.
46
68
  *
47
- * This prop will be passed to the `onClick` and `onKeyDown` of the `tr` element.
48
- * When the element is clicked, the event is passed to the `onClickRow` prop, but event isn't passed when the Enter or Space key is pressed.
69
+ * If provided, a visually hidden button is rendered inside the row so that keyboard and
70
+ * screen reader users can perform the row action without making the `tr` element itself
71
+ * interactive. The `tr` element keeps the `row` role and is not focusable, so the controls
72
+ * inside the cells stay reachable. Activating the button (Enter or Space) triggers this
73
+ * callback via the bubbled click event, and the focus indicator is displayed on the row
74
+ * while the button is focused. The accessible name of the button can be customized with
75
+ * the `rowActionButtonProps` prop.
76
+ *
77
+ * The button is hosted by the first `DataTableCell` of the row that is not a row header (the
78
+ * selection checkbox cell when the row is selectable), wherever the cell is rendered in the
79
+ * React tree: intermediate components, wrapper components and Fragments are all fine. If the
80
+ * row renders no `DataTableCell` at all, the button is not rendered, the row becomes unusable
81
+ * with a keyboard or screen reader, and a warning is logged.
49
82
  *
50
83
  * Note that this callback is NOT called when the click originates from an interactive
51
84
  * descendant inside the row — e.g. a button, link, input (including `Checkbox`), select,
52
85
  * label, or an element with an interactive ARIA role such as `checkbox` or `menuitem`.
53
86
  * Handle those interactions on the descendant itself (e.g. the `Checkbox`'s `onChange`).
54
- * Likewise, Enter or Space triggers this callback only while the row itself is focused,
55
- * not while a focusable descendant is focused.
56
87
  *
57
88
  * When the `enableRowClickSelection` prop of the `DataTable` component is `true`, the selection checkbox stops
58
- * responding to clicks on its own, so this callback is called for the clicks on the checkbox cell as well.
89
+ * responding to pointer clicks on its own, so this callback is called for the clicks on the checkbox cell as well.
59
90
  * Do not toggle the row selection here in that case, otherwise the selection is toggled twice.
91
+ * Toggling the checkbox with the keyboard does not call this callback.
60
92
  *
61
93
  * @default undefined
62
94
  */
63
- onClickRow?: (event: React.MouseEvent<HTMLTableRowElement> | React.KeyboardEvent<HTMLTableRowElement>) => void;
95
+ onClickRow?: (event: React.MouseEvent<HTMLTableRowElement>) => void;
96
+ /**
97
+ * The properties for the visually hidden button that makes the clickable row accessible
98
+ * to keyboard and screen reader users.
99
+ * This prop is available when the `onClickRow` prop is provided.
100
+ * If this prop is not passed, the default values for each property will be applied.
101
+ *
102
+ * @property aria-label - The alternative text for the button. default is '行の操作', or '行を開閉' when the
103
+ * row toggles a disclosure (a cell has `disclosureIconProps` without `onClickCell`).
104
+ *
105
+ * @property aria-labelledby - The id of the element that names the button, e.g. the row header cell.
106
+ * It takes precedence over `aria-label`.
107
+ *
108
+ * @property aria-describedby - The id of the element that describes the button.
109
+ *
110
+ * @property aria-controls - The id of the element that the row action expands or collapses.
111
+ *
112
+ * @property id - The id of the button, e.g. to move the focus back to the row action after closing a dialog.
113
+ */
114
+ rowActionButtonProps?: Pick<ComponentPropsWithoutRef<'button'>, 'aria-label' | 'aria-labelledby' | 'aria-describedby' | 'aria-controls' | 'id'>;
64
115
  /**
65
116
  * Whether the table rows are selectable.
66
117
  * If `true`, the checkbox cell will be added to the first column of header and each row.
@@ -0,0 +1,34 @@
1
+ import { type ComponentPropsWithoutRef } from 'react';
2
+ /**
3
+ * The attributes of the visually hidden row action button, resolved by `DataTableRow`.
4
+ */
5
+ export type RowActionButtonProps = Pick<ComponentPropsWithoutRef<'button'>, 'aria-label' | 'aria-labelledby' | 'aria-describedby' | 'aria-controls' | 'aria-expanded' | 'id' | 'disabled'>;
6
+ /**
7
+ * A cell that registered itself as a candidate host of the row action button.
8
+ */
9
+ export type RowActionCellEntry = {
10
+ /** The rendered cell element, used to order the candidates by their position in the row. */
11
+ element: HTMLTableCellElement;
12
+ /** Row header cells host the button only when the row has no other cell. */
13
+ isRowHeader: boolean;
14
+ /** Called by the row when the cell becomes, or stops being, the host. */
15
+ setIsHost: (isHost: boolean) => void;
16
+ };
17
+ export type DataTableRowActionContextValue = {
18
+ /** The attributes of the row action button, or `undefined` when the row has no row action. */
19
+ buttonProps: RowActionButtonProps | undefined;
20
+ /**
21
+ * Registers a cell as a candidate host of the row action button, or `undefined` when the row has
22
+ * no row action so that the cells skip the registration.
23
+ *
24
+ * @returns The function that unregisters the cell.
25
+ */
26
+ registerCell: ((entry: RowActionCellEntry) => () => void) | undefined;
27
+ };
28
+ /**
29
+ * Lets any `DataTableCell` rendered inside a `DataTableRow` take part in hosting the row action
30
+ * button, regardless of how the consumer composes the cells (intermediate components, wrappers,
31
+ * Fragments). The row decides which registered cell hosts the button.
32
+ */
33
+ export declare const DataTableRowActionContext: import("react").Context<DataTableRowActionContextValue | null>;
34
+ export declare const useDataTableRowActionContext: () => DataTableRowActionContextValue | null;
@@ -0,0 +1,8 @@
1
+ import { createContext, useContext } from 'react';
2
+ /**
3
+ * Lets any `DataTableCell` rendered inside a `DataTableRow` take part in hosting the row action
4
+ * button, regardless of how the consumer composes the cells (intermediate components, wrappers,
5
+ * Fragments). The row decides which registered cell hosts the button.
6
+ */
7
+ export const DataTableRowActionContext = createContext(null);
8
+ export const useDataTableRowActionContext = () => useContext(DataTableRowActionContext);
@@ -22,9 +22,13 @@ export function DatePickerCalendar({ value, onChange, minDate, maxDate, checkDis
22
22
  const { viewingValue, setViewingValue, pendingFocusDate, setPendingFocusDate } = useBasePickerContext();
23
23
  const [internalValue, setInternalValue] = useState(value);
24
24
  const calendarLocale = useCalendarLocale();
25
- useEffect(() => {
25
+ // Adjusted during render (React's documented pattern for resyncing state to a changed
26
+ // prop) rather than in an effect, so the UI never flashes the stale value for one frame.
27
+ const [prevValueProp, setPrevValueProp] = useState(value);
28
+ if (value !== prevValueProp) {
29
+ setPrevValueProp(value);
26
30
  setInternalValue(value);
27
- }, [value]);
31
+ }
28
32
  const setValue = useCallback((date, event) => {
29
33
  setInternalValue(date);
30
34
  onChange?.(date, event);
@@ -81,7 +85,7 @@ export function DatePickerCalendar({ value, onChange, minDate, maxDate, checkDis
81
85
  newDate.setFullYear(year);
82
86
  setViewingValue(newDate);
83
87
  }, [setViewingValue, viewingValue]);
84
- const shouldFilterYears = !!(minDate || maxDate);
88
+ const shouldFilterYears = !!(minDate ?? maxDate);
85
89
  const filterYear = useCallback((y) => {
86
90
  const normalizedMinDate = minDate ? new Date(minDate) : undefined;
87
91
  const normalizedMaxDate = maxDate ? new Date(maxDate) : undefined;
@@ -1,2 +1,2 @@
1
1
  export * from './DatePickerDateCell';
2
- export * from './DatePickerDateCell.types';
2
+ export type * from './DatePickerDateCell.types';
@@ -1,2 +1 @@
1
1
  export * from './DatePickerDateCell';
2
- export * from './DatePickerDateCell.types';
@@ -39,5 +39,5 @@ export function DateRangePickerCalendar({ viewingMonth, handleKeyboardNavigation
39
39
  };
40
40
  return (_jsx(DateRangePickerDateCell, { ...rest, date: date, selected: selected, inRange: inRange, disabled: disabled, isRangeStart: isStart, isRangeEnd: isEnd, onClick: handleClick, onMouseEnter: handleMouseEnter, onFocus: handleFocus, onMouseLeave: clearPreview, onBlur: clearPreview }, date.toISOString()));
41
41
  }, [isDateDisabled, isRangeStart, isRangeEnd, isInRange, handleDateClick, handlePreview, clearPreview]);
42
- return (_jsx("div", { className: cx(classNames.root, 'mfui-DateRangePickerCalendar__root'), children: _jsx(CalendarGrid, { viewingValue: viewingMonth, renderDateCell: renderDateCell, pendingFocusDate: pendingFocusDate ?? undefined, value: temporaryStart || temporaryEnd, onDateClick: undefined, onPendingFocusDateChange: setPendingFocusDate, onKeyboardNavigation: handleKeyboardNavigation }) }));
42
+ return (_jsx("div", { className: cx(classNames.root, 'mfui-DateRangePickerCalendar__root'), children: _jsx(CalendarGrid, { viewingValue: viewingMonth, renderDateCell: renderDateCell, pendingFocusDate: pendingFocusDate ?? undefined, value: temporaryStart ?? temporaryEnd, onDateClick: undefined, onPendingFocusDateChange: setPendingFocusDate, onKeyboardNavigation: handleKeyboardNavigation }) }));
43
43
  }
@@ -5,7 +5,7 @@ export function createDateRangePickerPopoverTestUtility({ user }) {
5
5
  // Look for the previous month button by finding buttons that might contain previous month indicators
6
6
  const allButtons = screen.getAllByRole('button');
7
7
  // The previous month button is typically the first IconButton in the navigation
8
- return (allButtons.find((button) => button.getAttribute('aria-label')?.includes('月') || button.getAttribute('aria-label')?.includes('month')) ??
8
+ return (allButtons.find((button) => !!button.getAttribute('aria-label')?.includes('月') || !!button.getAttribute('aria-label')?.includes('month')) ??
9
9
  allButtons.find((button) => button.querySelector('svg')) ??
10
10
  allButtons[0]);
11
11
  }
@@ -15,7 +15,7 @@ export function createDateRangePickerPopoverTestUtility({ user }) {
15
15
  // Find the button with next month aria-label
16
16
  const nextButton = allButtons.find((button) => {
17
17
  const label = button.getAttribute('aria-label');
18
- return label?.includes('次の') || label?.includes('Next');
18
+ return !!label?.includes('次の') || !!label?.includes('Next');
19
19
  });
20
20
  return nextButton ?? allButtons[1]; // fallback to second button
21
21
  }
@@ -1,6 +1,6 @@
1
1
  'use client';
2
2
  import { jsx as _jsx } from "react/jsx-runtime";
3
- import { createContext, useCallback, useContext, useEffect, useMemo, useState } from 'react';
3
+ import { createContext, useCallback, useContext, useMemo, useState } from 'react';
4
4
  import { flushSync } from 'react-dom';
5
5
  import { dayjs } from '../../../utilities/date/dayjs';
6
6
  import { useUpdateEffect } from '../../../utilities/effect/useUpdateEffect';
@@ -48,7 +48,7 @@ const useDateRangePickerContextValue = ({ value, defaultValue, disabled = false,
48
48
  const today = useMemo(() => new Date(), []);
49
49
  const [viewingMonth, setViewingMonth] = useTransformedState(value?.[0] ?? defaultValue?.[0] ?? new Date(today.getFullYear(), today.getMonth(), 1), normalizeToFirstOfMonth);
50
50
  // --- Selection/Preview State and Logic ---
51
- const [selecting, setSelecting] = useState('start');
51
+ const [selecting, setSelecting] = useState(() => (!startDate || endDate ? 'start' : 'end'));
52
52
  const [temporaryStart, setTemporaryStart] = useState(startDate);
53
53
  const [temporaryEnd, setTemporaryEnd] = useState(endDate);
54
54
  const [previewDate, setPreviewDate] = useState();
@@ -85,10 +85,10 @@ const useDateRangePickerContextValue = ({ value, defaultValue, disabled = false,
85
85
  onChange?.([newStartDate, newEndDate]);
86
86
  }, [onChange, format, setDates]);
87
87
  const handleStartDateChange = useCallback((date, nextEndDate) => {
88
- handleChange([date, nextEndDate !== undefined ? nextEndDate : endDate]);
88
+ handleChange([date, nextEndDate ?? endDate]);
89
89
  }, [endDate, handleChange]);
90
90
  const handleEndDateChange = useCallback((date, nextStartDate) => {
91
- handleChange([nextStartDate !== undefined ? nextStartDate : startDate, date]);
91
+ handleChange([nextStartDate ?? startDate, date]);
92
92
  }, [startDate, handleChange]);
93
93
  const handleStartDateStringChange = useCallback((value) => {
94
94
  setDateStrings([value, endDateString]);
@@ -131,12 +131,18 @@ const useDateRangePickerContextValue = ({ value, defaultValue, disabled = false,
131
131
  setTemporaryEnd(undefined);
132
132
  close();
133
133
  }, [handleChange, close]);
134
- useEffect(() => {
134
+ // Adjusted during render (React's documented pattern for resyncing state to changed
135
+ // props) rather than in an effect, so the UI never flashes the stale value for one frame.
136
+ const [prevStartDate, setPrevStartDate] = useState(startDate);
137
+ const [prevEndDate, setPrevEndDate] = useState(endDate);
138
+ if (startDate !== prevStartDate || endDate !== prevEndDate) {
139
+ setPrevStartDate(startDate);
140
+ setPrevEndDate(endDate);
135
141
  setTemporaryStart(startDate);
136
142
  setTemporaryEnd(endDate);
137
143
  setSelecting(!startDate || endDate ? 'start' : 'end');
138
144
  setPreviewDate(undefined);
139
- }, [startDate, endDate]);
145
+ }
140
146
  const handleDateClick = useCallback((date) => {
141
147
  // Prevent selection of disabled dates
142
148
  if (isDateOutsideConstraints(date, minDate, maxDate)) {
@@ -200,7 +206,7 @@ const useDateRangePickerContextValue = ({ value, defaultValue, disabled = false,
200
206
  }
201
207
  // handleChange already calls setDates and setDateStrings, so we don't need to call them again
202
208
  handleChange([newStart, newEnd]);
203
- // Do not setTemporaryStart/setTemporaryEnd here; let the effect sync them from startDate/endDate
209
+ // Do not setTemporaryStart/setTemporaryEnd here; the render-time adjustment above syncs them from startDate/endDate
204
210
  close();
205
211
  }, [handleChange, close, temporaryStart, temporaryEnd, minDate, maxDate]);
206
212
  const handleCancel = useCallback(() => {
@@ -34,7 +34,7 @@ export const DateRangePickerTrigger = forwardRef(({ enableClearValue = false, in
34
34
  });
35
35
  const { placeholder: startPlaceholder = LOCALE.START_DATE_PLACEHOLDER } = startInputProps;
36
36
  const { placeholder: endPlaceholder = LOCALE.END_DATE_PLACEHOLDER } = endInputProps;
37
- const shouldShowClearButton = enableClearValue && (enhancedStartInputProps.value || enhancedEndInputProps.value);
37
+ const shouldShowClearButton = enableClearValue && ((enhancedStartInputProps.value ?? '') || (enhancedEndInputProps.value ?? ''));
38
38
  // The error state takes precedence over the caution state
39
39
  const classes = baseRangePickerTriggerSlotRecipe({ invalid, caution: caution && !invalid, disabled, size });
40
40
  const handleClickClearButton = useCallback((event) => {
@@ -25,7 +25,7 @@ export function FilterDatePicker({ label, value, defaultValue, onChange, open, o
25
25
  const triggerRef = useRef(null);
26
26
  const dialogId = useId();
27
27
  const [internalValue, setInternalValue] = useState(defaultValue);
28
- const currentValue = value !== undefined ? value : internalValue;
28
+ const currentValue = value ?? internalValue;
29
29
  // When a controlled value transitions back to undefined, clear any stale internal value
30
30
  // so the component doesn't show a previously-selected uncontrolled date.
31
31
  const previousValueRef = useRef(value);
@@ -24,7 +24,7 @@ export function FilterMonthPicker({ label, value, defaultValue, onChange, open,
24
24
  const triggerRef = useRef(null);
25
25
  const dialogId = useId();
26
26
  const [internalValue, setInternalValue] = useState(defaultValue);
27
- const currentValue = value !== undefined ? value : internalValue;
27
+ const currentValue = value ?? internalValue;
28
28
  // When a controlled value transitions back to undefined, clear any stale internal value
29
29
  // so the component doesn't show a previously-selected uncontrolled month.
30
30
  const previousValueRef = useRef(value);
@@ -26,7 +26,7 @@ export function FilterMonthRangePicker({ label, value, defaultValue, onChange, o
26
26
  const triggerRef = useRef(null);
27
27
  const dialogId = useId();
28
28
  const [internalValue, setInternalValue] = useState(() => defaultValue ?? [undefined, undefined]);
29
- const currentValue = value !== undefined ? value : internalValue;
29
+ const currentValue = value ?? internalValue;
30
30
  const previousValueRef = useRef(value);
31
31
  useEffect(() => {
32
32
  const previousValue = previousValueRef.current;
@@ -88,7 +88,7 @@ export function MonthPickerPanel({ viewingValue, setViewingValue, value, onChang
88
88
  const handleYearSelect = useCallback((newYear) => {
89
89
  setViewingValue(new Date(newYear, 0, 1));
90
90
  }, [setViewingValue]);
91
- const shouldFilterYears = !!(minMonth || maxMonth || checkDisabledMonth);
91
+ const shouldFilterYears = !!(minMonth ?? maxMonth ?? checkDisabledMonth);
92
92
  const filterYear = useCallback((y) => {
93
93
  const normalizedMinMonth = minMonth ? new Date(minMonth) : undefined;
94
94
  const normalizedMaxMonth = maxMonth ? new Date(maxMonth) : undefined;
@@ -1,5 +1,5 @@
1
- export declare const LABEL_PREV_YEAR = "\u524D\u306E\u5E74";
2
- export declare const LABEL_NEXT_YEAR = "\u6B21\u306E\u5E74";
1
+ export declare const LABEL_PREV_YEAR = "\u524D\u306E\u5E74\u3092\u8868\u793A";
2
+ export declare const LABEL_NEXT_YEAR = "\u6B21\u306E\u5E74\u3092\u8868\u793A";
3
3
  export declare const LABEL_OPEN_CALENDAR = "\u30AB\u30EC\u30F3\u30C0\u30FC\u3092\u958B\u304F";
4
4
  export declare const LABEL_CLOSE_CALENDAR = "\u30AB\u30EC\u30F3\u30C0\u30FC\u3092\u9589\u3058\u308B";
5
5
  type MonthPickerLabelKey = 'prevYear' | 'nextYear';
@@ -1,5 +1,5 @@
1
- export const LABEL_PREV_YEAR = '前の年'; // Previous year
2
- export const LABEL_NEXT_YEAR = '次の年'; // Next year
1
+ export const LABEL_PREV_YEAR = '前の年を表示'; // Show previous year
2
+ export const LABEL_NEXT_YEAR = '次の年を表示'; // Show next year
3
3
  export const LABEL_OPEN_CALENDAR = 'カレンダーを開く'; // Open calendar
4
4
  export const LABEL_CLOSE_CALENDAR = 'カレンダーを閉じる'; // Close calendar
5
5
  /**
@@ -7,12 +7,12 @@ export const LABEL_CLOSE_CALENDAR = 'カレンダーを閉じる'; // Close cale
7
7
  */
8
8
  export const MONTH_PICKER_LABELS = {
9
9
  ja: {
10
- prevYear: '前の年',
11
- nextYear: '次の年',
10
+ prevYear: '前の年を表示',
11
+ nextYear: '次の年を表示',
12
12
  },
13
13
  en: {
14
- prevYear: 'Previous year',
15
- nextYear: 'Next year',
14
+ prevYear: 'Show previous year',
15
+ nextYear: 'Show next year',
16
16
  },
17
17
  };
18
18
  /**
@@ -23,7 +23,7 @@ import 'dayjs/locale/ja';
23
23
  export function MonthRangePickerMonthCell({ isInRange, isRangeStart, isRangeEnd, onMouseEnter, onMouseLeave, handleKeyboardNavigation, ...monthCellProps }) {
24
24
  const calendarLocale = useCalendarLocale();
25
25
  // Calculate if this month is selected (either start or end of range)
26
- const selected = isRangeStart || isRangeEnd || monthCellProps.selected || false;
26
+ const selected = !!isRangeStart || !!isRangeEnd || !!monthCellProps.selected;
27
27
  const monthFormat = useMemo(() => getMonthCellMonthFormat(calendarLocale, monthCellProps.date), [calendarLocale, monthCellProps.date]);
28
28
  // Create accessible label for range selection
29
29
  const accessibleLabel = useMemo(() => {
@@ -11,8 +11,8 @@ import { yearToEraLabel } from '../../shared/utilities/japaneseCalendar';
11
11
  // Constants for year navigation limits
12
12
  const MINIMUM_VIEWABLE_YEAR = 1900;
13
13
  const MAXIMUM_VIEWABLE_YEAR = 2100;
14
- const LABEL_PREV_YEAR = { ja: '前年', en: 'Previous year' };
15
- const LABEL_NEXT_YEAR = { ja: '翌年', en: 'Next year' };
14
+ const LABEL_PREV_YEAR = { ja: '前の年を表示', en: 'Show previous year' };
15
+ const LABEL_NEXT_YEAR = { ja: '次の年を表示', en: 'Show next year' };
16
16
  /**
17
17
  * Year navigation component for MonthRangePicker.
18
18
  *
@@ -41,7 +41,7 @@ export const TimePicker = forwardRef(({ value, defaultValue, onChange, format =
41
41
  // Track the live value internally so the clear button can read it whether
42
42
  // the consumer is using `value` (controlled) or `defaultValue` (uncontrolled).
43
43
  const [internalValue, setInternalValue] = useState(value ?? defaultValue ?? '');
44
- const effectiveValue = value === undefined ? internalValue : value;
44
+ const effectiveValue = value ?? internalValue;
45
45
  const hasValue = effectiveValue !== '';
46
46
  // The error state takes precedence over the caution state
47
47
  const classes = timePickerSlotRecipe({ size, disabled, invalid, caution: caution && !invalid });
@@ -2,8 +2,8 @@ import { type BasePickerProps } from './BasePicker.types';
2
2
  /**
3
3
  * Default labels for the DatePicker components with Japanese text
4
4
  */
5
- export declare const LABEL_GO_TO_PREV_MONTH = "\u524D\u306E\u6708";
6
- export declare const LABEL_GO_TO_NEXT_MONTH = "\u6B21\u306E\u6708";
5
+ export declare const LABEL_GO_TO_PREV_MONTH = "\u524D\u306E\u6708\u3092\u8868\u793A";
6
+ export declare const LABEL_GO_TO_NEXT_MONTH = "\u6B21\u306E\u6708\u3092\u8868\u793A";
7
7
  export declare const LABEL_SELECT_MONTH = "\u6708\u3092\u9078\u629E";
8
8
  export declare const LABEL_OPEN_CALENDAR = "\u30AB\u30EC\u30F3\u30C0\u30FC\u3092\u958B\u304F";
9
9
  export declare const LABEL_CLOSE_CALENDAR = "\u30AB\u30EC\u30F3\u30C0\u30FC\u3092\u9589\u3058\u308B";
@@ -1,18 +1,18 @@
1
1
  /**
2
2
  * Default labels for the DatePicker components with Japanese text
3
3
  */
4
- export const LABEL_GO_TO_PREV_MONTH = '前の月';
5
- export const LABEL_GO_TO_NEXT_MONTH = '次の月';
4
+ export const LABEL_GO_TO_PREV_MONTH = '前の月を表示';
5
+ export const LABEL_GO_TO_NEXT_MONTH = '次の月を表示';
6
6
  export const LABEL_SELECT_MONTH = '月を選択';
7
7
  export const LABEL_OPEN_CALENDAR = 'カレンダーを開く';
8
8
  export const LABEL_CLOSE_CALENDAR = 'カレンダーを閉じる';
9
9
  export const LABEL_TODAY = '今日';
10
10
  export const BASE_PICKER_LABELS = {
11
11
  ja: {
12
- GO_TO_PREV_MONTH: '前の月',
13
- GO_TO_NEXT_MONTH: '次の月',
14
- GO_TO_PREV_YEAR: '前の年',
15
- GO_TO_NEXT_YEAR: '次の年',
12
+ GO_TO_PREV_MONTH: '前の月を表示',
13
+ GO_TO_NEXT_MONTH: '次の月を表示',
14
+ GO_TO_PREV_YEAR: '前の年を表示',
15
+ GO_TO_NEXT_YEAR: '次の年を表示',
16
16
  SELECT_MONTH: '月を選択',
17
17
  SELECT_YEAR: '年を選択',
18
18
  OPEN_CALENDAR: 'カレンダーを開く',
@@ -21,10 +21,10 @@ export const BASE_PICKER_LABELS = {
21
21
  CLEAR_VALUE: '値をクリアする',
22
22
  },
23
23
  en: {
24
- GO_TO_PREV_MONTH: 'Previous month',
25
- GO_TO_NEXT_MONTH: 'Next month',
26
- GO_TO_PREV_YEAR: 'Previous year',
27
- GO_TO_NEXT_YEAR: 'Next year',
24
+ GO_TO_PREV_MONTH: 'Show previous month',
25
+ GO_TO_NEXT_MONTH: 'Show next month',
26
+ GO_TO_PREV_YEAR: 'Show previous year',
27
+ GO_TO_NEXT_YEAR: 'Show next year',
28
28
  SELECT_MONTH: 'Select month',
29
29
  SELECT_YEAR: 'Select year',
30
30
  OPEN_CALENDAR: 'Open calendar',
@@ -39,5 +39,5 @@ export function BaseRangePickerCalendar({ viewingMonth, handleKeyboardNavigation
39
39
  };
40
40
  return (_jsx(BaseRangePickerDateCell, { ...rest, date: date, selected: selected, inRange: inRange, disabled: disabled, isRangeStart: isStart, isRangeEnd: isEnd, onClick: handleClick, onMouseEnter: handleMouseEnter, onFocus: handleFocus, onMouseLeave: clearPreview, onBlur: clearPreview }, date.toISOString()));
41
41
  }, [isDateDisabled, isRangeStart, isRangeEnd, isInRange, handleDateClick, handlePreview, clearPreview]);
42
- return (_jsx("div", { className: cx(classNames.root, 'mfui-BaseRangePickerCalendar__root'), children: _jsx(CalendarGrid, { viewingValue: viewingMonth, renderDateCell: renderDateCell, pendingFocusDate: pendingFocusDate ?? undefined, value: temporaryStart || temporaryEnd, onDateClick: undefined, onPendingFocusDateChange: setPendingFocusDate, onKeyboardNavigation: handleKeyboardNavigation }) }));
42
+ return (_jsx("div", { className: cx(classNames.root, 'mfui-BaseRangePickerCalendar__root'), children: _jsx(CalendarGrid, { viewingValue: viewingMonth, renderDateCell: renderDateCell, pendingFocusDate: pendingFocusDate ?? undefined, value: temporaryStart ?? temporaryEnd, onDateClick: undefined, onPendingFocusDateChange: setPendingFocusDate, onKeyboardNavigation: handleKeyboardNavigation }) }));
43
43
  }
@@ -1,13 +1,13 @@
1
1
  export const BASE_RANGE_PICKER_POPOVER_LABELS = {
2
2
  ja: {
3
- GO_TO_PREV_MONTH: '前の月',
4
- GO_TO_NEXT_MONTH: '次の月',
3
+ GO_TO_PREV_MONTH: '前の月を表示',
4
+ GO_TO_NEXT_MONTH: '次の月を表示',
5
5
  APPLY: '適用',
6
6
  CANCEL: 'キャンセル',
7
7
  },
8
8
  en: {
9
- GO_TO_PREV_MONTH: 'Previous month',
10
- GO_TO_NEXT_MONTH: 'Next month',
9
+ GO_TO_PREV_MONTH: 'Show previous month',
10
+ GO_TO_NEXT_MONTH: 'Show next month',
11
11
  APPLY: 'Apply',
12
12
  CANCEL: 'Cancel',
13
13
  },
@@ -1,6 +1,6 @@
1
1
  'use client';
2
2
  import { jsx as _jsx } from "react/jsx-runtime";
3
- import { createContext, useCallback, useContext, useEffect, useMemo, useState } from 'react';
3
+ import { createContext, useCallback, useContext, useMemo, useState } from 'react';
4
4
  import { flushSync } from 'react-dom';
5
5
  import { dayjs } from '../../../../utilities/date/dayjs';
6
6
  import { useUpdateEffect } from '../../../../utilities/effect/useUpdateEffect';
@@ -117,7 +117,7 @@ const useBaseRangePickerContextValue = ({ value, defaultValue, disabled = false,
117
117
  today,
118
118
  }), normalizeToFirstOfMonth);
119
119
  // --- Selection/Preview State and Logic ---
120
- const [selecting, setSelecting] = useState('start');
120
+ const [selecting, setSelecting] = useState(() => (!startDate || endDate ? 'start' : 'end'));
121
121
  const [temporaryStart, setTemporaryStart] = useState(startDate);
122
122
  const [temporaryEnd, setTemporaryEnd] = useState(endDate);
123
123
  const [previewDate, setPreviewDate] = useState();
@@ -151,7 +151,7 @@ const useBaseRangePickerContextValue = ({ value, defaultValue, disabled = false,
151
151
  onChange?.([newStartDate, newEndDate]);
152
152
  }, [onChange, formatDate, setDates]);
153
153
  const handleStartDateChange = useCallback((date, nextEndDate) => {
154
- const proposedEndDate = nextEndDate !== undefined ? nextEndDate : endDate;
154
+ const proposedEndDate = nextEndDate ?? endDate;
155
155
  // Apply auto-completion behavior when start date is set and end date is missing
156
156
  // This follows design guidelines: if only one date is provided, both should be set to same value
157
157
  if (date && !proposedEndDate) {
@@ -162,7 +162,7 @@ const useBaseRangePickerContextValue = ({ value, defaultValue, disabled = false,
162
162
  }
163
163
  }, [endDate, handleChange]);
164
164
  const handleEndDateChange = useCallback((date, nextStartDate) => {
165
- const proposedStartDate = nextStartDate !== undefined ? nextStartDate : startDate;
165
+ const proposedStartDate = nextStartDate ?? startDate;
166
166
  // Apply auto-completion behavior when end date is set and start date is missing
167
167
  // This follows design guidelines: if only one date is provided, both should be set to same value
168
168
  if (date && !proposedStartDate) {
@@ -237,12 +237,18 @@ const useBaseRangePickerContextValue = ({ value, defaultValue, disabled = false,
237
237
  setTemporaryEnd(undefined);
238
238
  close();
239
239
  }, [handleChange, close]);
240
- useEffect(() => {
240
+ // Adjusted during render (React's documented pattern for resyncing state to changed
241
+ // props) rather than in an effect, so the UI never flashes the stale value for one frame.
242
+ const [prevStartDate, setPrevStartDate] = useState(startDate);
243
+ const [prevEndDate, setPrevEndDate] = useState(endDate);
244
+ if (startDate !== prevStartDate || endDate !== prevEndDate) {
245
+ setPrevStartDate(startDate);
246
+ setPrevEndDate(endDate);
241
247
  setTemporaryStart(startDate);
242
248
  setTemporaryEnd(endDate);
243
249
  setSelecting(!startDate || endDate ? 'start' : 'end');
244
250
  setPreviewDate(undefined);
245
- }, [startDate, endDate]);
251
+ }
246
252
  const handleDateClick = useCallback((date) => {
247
253
  // Prevent selection of disabled dates
248
254
  if (isDateOutsideConstraints(date, minDate, maxDate, format)) {
@@ -309,7 +315,7 @@ const useBaseRangePickerContextValue = ({ value, defaultValue, disabled = false,
309
315
  const autoCompletedRange = autoCompletePartialRange([newStart, newEnd]);
310
316
  // handleChange already calls setDates and setDateStrings, so we don't need to call them again
311
317
  handleChange(autoCompletedRange);
312
- // Do not setTemporaryStart/setTemporaryEnd here; let the effect sync them from startDate/endDate
318
+ // Do not setTemporaryStart/setTemporaryEnd here; the render-time adjustment above syncs them from startDate/endDate
313
319
  close();
314
320
  }, [handleChange, close, temporaryStart, temporaryEnd, minDate, maxDate, format]);
315
321
  const handleCancel = useCallback(() => {
@@ -39,7 +39,7 @@ export const BaseRangePickerTrigger = forwardRef(({ enableClearValue = false, in
39
39
  // Use input props placeholder, fallback to default
40
40
  const finalStartPlaceholder = startInputPlaceholder ?? getBaseRangePickerTriggerLabel('START_DATE_PLACEHOLDER', calendarLocale);
41
41
  const finalEndPlaceholder = endInputPlaceholder ?? getBaseRangePickerTriggerLabel('END_DATE_PLACEHOLDER', calendarLocale);
42
- const shouldShowClearButton = enableClearValue && (enhancedStartInputProps.value || enhancedEndInputProps.value);
42
+ const shouldShowClearButton = enableClearValue && ((enhancedStartInputProps.value ?? '') || (enhancedEndInputProps.value ?? ''));
43
43
  // The error state takes precedence over the caution state
44
44
  const classes = baseRangePickerTriggerSlotRecipe({ invalid, caution: caution && !invalid, disabled, size });
45
45
  // Popover open: mark calendar icon active. Use `undefined` when closed — `data-active="false"` is still truthy in CSS.
@@ -48,6 +48,6 @@ export const BaseRangePickerTrigger = forwardRef(({ enableClearValue = false, in
48
48
  handleClear();
49
49
  onClickClearButton?.(event);
50
50
  }, [handleClear, onClickClearButton]);
51
- return (_jsxs("div", { ...wrapperProps, ...props, ref: ref, className: cx(classes.root, 'mfui-BaseRangePickerTrigger__root', wrapperProps.className), children: [_jsx("div", { className: cx(classes.inputGroup, 'mfui-BaseRangePickerTrigger__inputGroup'), children: isTouchDevice ? (_jsxs(_Fragment, { children: [_jsx("input", { type: "hidden", value: enhancedStartInputProps.value, name: startInputProps.name }), _jsx("input", { type: "hidden", value: enhancedEndInputProps.value, name: endInputProps.name }), _jsx("div", { className: cx(classes.input, 'mfui-BaseRangePickerTrigger__input'), onClick: !disableAutoOpen && !disabled ? handleInputClick('start', startInputProps.onClick) : undefined, children: enhancedStartInputProps.value || finalStartPlaceholder }), _jsx(Typography, { variant: "controlLabel", className: cx(classes.separator, 'mfui-BaseRangePickerTrigger__separator'), children: SEPARATOR_CONTENT }), _jsx("div", { className: cx(classes.input, 'mfui-BaseRangePickerTrigger__input'), onClick: !disableAutoOpen && !disabled ? handleInputClick('end', endInputProps.onClick) : undefined, children: enhancedEndInputProps.value || finalEndPlaceholder })] })) : (_jsxs(_Fragment, { children: [_jsx(FocusIndicator, { position: "inside", children: _jsx("input", { ref: startInputRef, disabled: disabled, className: cx(classes.input, 'mfui-BaseRangePickerTrigger__input'), ...enhancedStartInputProps, placeholder: finalStartPlaceholder }) }), _jsx(Typography, { variant: "controlLabel", className: cx(classes.separator, 'mfui-BaseRangePickerTrigger__separator'), children: SEPARATOR_CONTENT }), _jsx(FocusIndicator, { position: "inside", children: _jsx("input", { ref: endInputRef, disabled: disabled, className: cx(classes.input, 'mfui-BaseRangePickerTrigger__input'), ...enhancedEndInputProps, placeholder: finalEndPlaceholder }) })] })) }), shouldShowClearButton ? (_jsx(ClearButton, { size: size === 'small' ? 'small' : 'default', "aria-label": clearAriaLabel ?? getBaseRangePickerTriggerLabel('CLEAR_BUTTON_LABEL', calendarLocale), className: cx(classes.actionIcon, 'mfui-BaseRangePickerTrigger__actionIcon'), disabled: disabled, onClick: handleClickClearButton })) : null, _jsx(IconButton, { size: size === 'small' ? 'small' : 'default', "aria-label": calendarAriaLabel ?? getBaseRangePickerTriggerLabel('CALENDAR_BUTTON_LABEL', calendarLocale), className: cx(classes.actionIcon, 'mfui-BaseRangePickerTrigger__actionIcon'), "data-active": shouldCalendarIconActive, disabled: disabled, onClick: onCalendarClick ?? toggle, children: _jsx(Calendar, {}) })] }));
51
+ return (_jsxs("div", { ...wrapperProps, ...props, ref: ref, className: cx(classes.root, 'mfui-BaseRangePickerTrigger__root', wrapperProps.className), children: [_jsx("div", { className: cx(classes.inputGroup, 'mfui-BaseRangePickerTrigger__inputGroup'), children: isTouchDevice ? (_jsxs(_Fragment, { children: [_jsx("input", { type: "hidden", value: enhancedStartInputProps.value, name: startInputProps.name }), _jsx("input", { type: "hidden", value: enhancedEndInputProps.value, name: endInputProps.name }), _jsx("div", { className: cx(classes.input, 'mfui-BaseRangePickerTrigger__input'), onClick: !disableAutoOpen && !disabled ? handleInputClick('start', startInputProps.onClick) : undefined, children: (enhancedStartInputProps.value ?? '') || finalStartPlaceholder }), _jsx(Typography, { variant: "controlLabel", className: cx(classes.separator, 'mfui-BaseRangePickerTrigger__separator'), children: SEPARATOR_CONTENT }), _jsx("div", { className: cx(classes.input, 'mfui-BaseRangePickerTrigger__input'), onClick: !disableAutoOpen && !disabled ? handleInputClick('end', endInputProps.onClick) : undefined, children: (enhancedEndInputProps.value ?? '') || finalEndPlaceholder })] })) : (_jsxs(_Fragment, { children: [_jsx(FocusIndicator, { position: "inside", children: _jsx("input", { ref: startInputRef, disabled: disabled, className: cx(classes.input, 'mfui-BaseRangePickerTrigger__input'), ...enhancedStartInputProps, placeholder: finalStartPlaceholder }) }), _jsx(Typography, { variant: "controlLabel", className: cx(classes.separator, 'mfui-BaseRangePickerTrigger__separator'), children: SEPARATOR_CONTENT }), _jsx(FocusIndicator, { position: "inside", children: _jsx("input", { ref: endInputRef, disabled: disabled, className: cx(classes.input, 'mfui-BaseRangePickerTrigger__input'), ...enhancedEndInputProps, placeholder: finalEndPlaceholder }) })] })) }), shouldShowClearButton ? (_jsx(ClearButton, { size: size === 'small' ? 'small' : 'default', "aria-label": clearAriaLabel ?? getBaseRangePickerTriggerLabel('CLEAR_BUTTON_LABEL', calendarLocale), className: cx(classes.actionIcon, 'mfui-BaseRangePickerTrigger__actionIcon'), disabled: disabled, onClick: handleClickClearButton })) : null, _jsx(IconButton, { size: size === 'small' ? 'small' : 'default', "aria-label": calendarAriaLabel ?? getBaseRangePickerTriggerLabel('CALENDAR_BUTTON_LABEL', calendarLocale), className: cx(classes.actionIcon, 'mfui-BaseRangePickerTrigger__actionIcon'), "data-active": shouldCalendarIconActive, disabled: disabled, onClick: onCalendarClick ?? toggle, children: _jsx(Calendar, {}) })] }));
52
52
  });
53
53
  BaseRangePickerTrigger.displayName = 'BaseRangePicker.Trigger';
@@ -32,7 +32,7 @@ export function CalendarGrid({ viewingValue, minDate, maxDate, checkDisabledDate
32
32
  if (!dateNumber)
33
33
  return null;
34
34
  const date = new Date(viewingValue.getFullYear(), viewingValue.getMonth(), dateNumber);
35
- const isDisabledByProps = (startOfMinDate && date < startOfMinDate) || (startOfMaxDate && date > startOfMaxDate);
35
+ const isDisabledByProps = !!(startOfMinDate && date < startOfMinDate) || !!(startOfMaxDate && date > startOfMaxDate);
36
36
  const isDisabledByCallback = checkDisabledDate?.(date);
37
37
  const disabled = isDisabledByProps || !!isDisabledByCallback;
38
38
  const isSelected = value ? checkIsSameDate(value, date) : false;
@@ -57,7 +57,7 @@ export function CalendarGrid({ viewingValue, minDate, maxDate, checkDisabledDate
57
57
  let tabbableDateIndex = -1;
58
58
  // First, try to find the selected date if it exists and is not disabled
59
59
  if (value) {
60
- tabbableDateIndex = newDates.findIndex((dateItem) => dateItem && dateItem.selected && !dateItem.disabled);
60
+ tabbableDateIndex = newDates.findIndex((dateItem) => dateItem?.selected && !dateItem.disabled);
61
61
  }
62
62
  // If no selected date or selected date is disabled, try today's date
63
63
  if (tabbableDateIndex === -1) {
@@ -101,8 +101,6 @@ export function CalendarGrid({ viewingValue, minDate, maxDate, checkDisabledDate
101
101
  .map((_, index) => ((weekStart + index) % 7))
102
102
  .map((weekday) => (_jsx(DayCell, { day: weekday }, weekday))), computedPropsForDates.map((dateItem, index) => {
103
103
  // All props are generated internally and guaranteed to have required fields
104
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
105
- // @ts-ignore
106
104
  if (!dateItem) {
107
105
  return (_jsx("div", { className: cx(classes.emptyDateCell, 'mfui-CalendarGrid__emptyDateCell') }, `empty-date-${String(index)}`));
108
106
  }