@moneyforward/mfui-components 3.37.2 → 4.1.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 (89) hide show
  1. package/README.md +1 -1
  2. package/dist/src/Button/Button.js +1 -1
  3. package/dist/src/Button/Button.types.d.ts +6 -0
  4. package/dist/src/DataGrid/index.d.ts +40 -8
  5. package/dist/src/DataGrid/index.js +5 -1
  6. package/dist/src/DataTable/DataTable.js +2 -2
  7. package/dist/src/DataTable/DataTable.types.d.ts +20 -0
  8. package/dist/src/DataTable/DataTableCell/DataTableCell.js +8 -5
  9. package/dist/src/DataTable/DataTableHeaderCell/DataTableHeaderCell.js +3 -3
  10. package/dist/src/DataTable/DataTableProvider.d.ts +2 -2
  11. package/dist/src/DataTable/DataTableProvider.js +4 -1
  12. package/dist/src/DataTable/DataTableRow/DataTableRow.js +22 -5
  13. package/dist/src/DataTable/DataTableRow/DataTableRow.types.d.ts +4 -0
  14. package/dist/src/DateTimeSelection/DatePicker/DatePicker.d.ts +8 -1
  15. package/dist/src/DateTimeSelection/DatePicker/DatePicker.js +4 -2
  16. package/dist/src/DateTimeSelection/DateRangePicker/DateRangePicker.d.ts +1 -1
  17. package/dist/src/DateTimeSelection/DateRangePicker/DateRangePicker.js +4 -2
  18. package/dist/src/DateTimeSelection/DateRangePicker/DateRangePicker.types.d.ts +7 -0
  19. package/dist/src/DateTimeSelection/FilterDatePicker/CalendarPopover/CalendarPopover.d.ts +1 -1
  20. package/dist/src/DateTimeSelection/FilterDatePicker/CalendarPopover/CalendarPopover.js +5 -4
  21. package/dist/src/DateTimeSelection/FilterDatePicker/CalendarPopover/CalendarPopover.types.d.ts +1 -0
  22. package/dist/src/DateTimeSelection/FilterDatePicker/FilterDatePicker.d.ts +1 -1
  23. package/dist/src/DateTimeSelection/FilterDatePicker/FilterDatePicker.js +3 -2
  24. package/dist/src/DateTimeSelection/FilterDatePicker/FilterDatePicker.types.d.ts +7 -0
  25. package/dist/src/DateTimeSelection/FilterDateRangePicker/DateRangePickerContent/DateRangePickerContent.d.ts +1 -1
  26. package/dist/src/DateTimeSelection/FilterDateRangePicker/DateRangePickerContent/DateRangePickerContent.js +3 -2
  27. package/dist/src/DateTimeSelection/FilterDateRangePicker/DateRangePickerContent/DateRangePickerContent.types.d.ts +1 -0
  28. package/dist/src/DateTimeSelection/FilterDateRangePicker/FilterDateRangePicker.d.ts +1 -1
  29. package/dist/src/DateTimeSelection/FilterDateRangePicker/FilterDateRangePicker.js +3 -2
  30. package/dist/src/DateTimeSelection/FilterDateRangePicker/FilterDateRangePicker.types.d.ts +7 -0
  31. package/dist/src/DateTimeSelection/shared/BasePicker/constants.d.ts +28 -2
  32. package/dist/src/DateTimeSelection/shared/BasePicker/constants.js +15 -4
  33. package/dist/src/DateTimeSelection/shared/BaseRangePicker/BaseRangePickerPopover/BaseRangePickerPopover.d.ts +4 -0
  34. package/dist/src/DateTimeSelection/shared/BaseRangePicker/BaseRangePickerPopover/BaseRangePickerPopover.js +4 -0
  35. package/dist/src/DateTimeSelection/shared/CalendarGrid/CalendarGrid.js +9 -5
  36. package/dist/src/DateTimeSelection/shared/CalendarGrid/utilities/computeDataForStyling.d.ts +3 -1
  37. package/dist/src/DateTimeSelection/shared/CalendarGrid/utilities/computeDataForStyling.js +20 -18
  38. package/dist/src/DateTimeSelection/shared/CalendarGrid/utilities/useDates.d.ts +6 -3
  39. package/dist/src/DateTimeSelection/shared/CalendarGrid/utilities/useDates.js +9 -5
  40. package/dist/src/DateTimeSelection/shared/CalendarLocale/FirstDayOfWeekContext.d.ts +8 -0
  41. package/dist/src/DateTimeSelection/shared/CalendarLocale/FirstDayOfWeekContext.js +11 -0
  42. package/dist/src/DateTimeSelection/shared/DateCell/DateCell.types.d.ts +1 -1
  43. package/dist/src/DateTimeSelection/shared/DayCell/DayCell.d.ts +4 -3
  44. package/dist/src/DecoratedKeyValueList/DecoratedKeyValueList.d.ts +22 -0
  45. package/dist/src/DecoratedKeyValueList/DecoratedKeyValueList.js +28 -0
  46. package/dist/src/DecoratedKeyValueList/DecoratedKeyValueList.types.d.ts +21 -0
  47. package/dist/src/DecoratedKeyValueList/DecoratedKeyValueList.types.js +1 -0
  48. package/dist/src/DecoratedKeyValueList/DecoratedKeyValueListItem/DecoratedKeyValueListItem.d.ts +8 -0
  49. package/dist/src/DecoratedKeyValueList/DecoratedKeyValueListItem/DecoratedKeyValueListItem.js +18 -0
  50. package/dist/src/DecoratedKeyValueList/DecoratedKeyValueListItem/DecoratedKeyValueListItem.types.d.ts +25 -0
  51. package/dist/src/DecoratedKeyValueList/DecoratedKeyValueListItem/DecoratedKeyValueListItem.types.js +1 -0
  52. package/dist/src/DecoratedKeyValueList/index.d.ts +4 -0
  53. package/dist/src/DecoratedKeyValueList/index.js +2 -0
  54. package/dist/src/DisplayTable/DisplayTable.d.ts +1 -1
  55. package/dist/src/DisplayTable/DisplayTable.js +8 -3
  56. package/dist/src/DisplayTable/DisplayTable.types.d.ts +44 -2
  57. package/dist/src/EmbeddedSidePane/EmbeddedSidePane.d.ts +2 -3
  58. package/dist/src/EmbeddedSidePane/EmbeddedSidePane.types.d.ts +2 -2
  59. package/dist/src/MainNavigation/BaseMainNavigation.js +2 -2
  60. package/dist/src/MainNavigation/NarrowViewportMainNavigation.js +2 -2
  61. package/dist/src/MultilineTextBox/index.d.ts +10 -2
  62. package/dist/src/MultilineTextBox/index.js +5 -1
  63. package/dist/src/SectionMessage/SectionMessage.js +2 -2
  64. package/dist/src/SidePane/SidePane.d.ts +4 -22
  65. package/dist/src/SidePane/SidePane.js +8 -4
  66. package/dist/src/SidePane/SidePane.types.d.ts +50 -8
  67. package/dist/src/SidePane/index.d.ts +1 -1
  68. package/dist/src/Sidebar/Sidebar.d.ts +0 -2
  69. package/dist/src/Sidebar/Sidebar.js +0 -2
  70. package/dist/src/SubNavigation/SubNavigation.js +2 -2
  71. package/dist/src/TextLink/TextLink.js +1 -1
  72. package/dist/src/Toast/Toast.js +1 -1
  73. package/dist/src/index.d.ts +1 -0
  74. package/dist/src/index.js +1 -0
  75. package/dist/styled-system/recipes/data-table-cell-slot-recipe.d.ts +1 -0
  76. package/dist/styled-system/recipes/data-table-cell-slot-recipe.js +5 -0
  77. package/dist/styled-system/recipes/data-table-row-slot-recipe.d.ts +2 -1
  78. package/dist/styled-system/recipes/data-table-row-slot-recipe.js +9 -0
  79. package/dist/styled-system/recipes/decorated-key-value-list-item-slot-recipe.d.ts +33 -0
  80. package/dist/styled-system/recipes/decorated-key-value-list-item-slot-recipe.js +40 -0
  81. package/dist/styled-system/recipes/decorated-key-value-list-slot-recipe.d.ts +36 -0
  82. package/dist/styled-system/recipes/decorated-key-value-list-slot-recipe.js +37 -0
  83. package/dist/styled-system/recipes/index.d.ts +2 -0
  84. package/dist/styled-system/recipes/index.js +2 -0
  85. package/dist/styled-system/recipes/status-label-slot-recipe.d.ts +1 -1
  86. package/dist/styled-system/recipes/status-label-slot-recipe.js +2 -1
  87. package/dist/styles.css +145 -13
  88. package/dist/tsconfig.build.tsbuildinfo +1 -1
  89. package/package.json +4 -4
@@ -15,4 +15,5 @@ export type InternalDateRangePickerContentProps = {
15
15
  isCalendarOpen: boolean;
16
16
  toggleCalendar: () => void;
17
17
  calendarLocale: NonNullable<BasePickerProps['calendarLocale']>;
18
+ firstDayOfWeek: NonNullable<FilterDateRangePickerProps['firstDayOfWeek']>;
18
19
  };
@@ -11,4 +11,4 @@ import { type FilterDateRangePickerProps } from './FilterDateRangePicker.types';
11
11
  * neither of which are appropriate here. FilterDateRangePicker uses CalendarIcon and
12
12
  * has no form-field semantics.
13
13
  */
14
- export declare function FilterDateRangePicker({ label, value, defaultValue, onChange, open, onOpenStateChanged, format, enableClearButton, clearButtonProps, disabled, className, targetDOMNode, minDate, maxDate, calendarLocale, }: FilterDateRangePickerProps): import("react/jsx-runtime").JSX.Element;
14
+ export declare function FilterDateRangePicker({ label, value, defaultValue, onChange, open, onOpenStateChanged, format, enableClearButton, clearButtonProps, disabled, className, targetDOMNode, minDate, maxDate, calendarLocale, firstDayOfWeek, }: FilterDateRangePickerProps): import("react/jsx-runtime").JSX.Element;
@@ -5,6 +5,7 @@ import { filterDateRangePickerSlotRecipe } from '../../../styled-system/recipes'
5
5
  import { useDisclosure } from '../../utilities/state/useDisclosure';
6
6
  import { BaseRangePickerProvider } from '../shared/BaseRangePicker/BaseRangePickerProvider';
7
7
  import { InternalDateRangePickerContent } from './DateRangePickerContent/DateRangePickerContent';
8
+ import { DEFAULT_FIRST_DAY_OF_WEEK } from '../shared/BasePicker/constants';
8
9
  const DEFAULT_FORMAT = 'YYYY/MM/DD';
9
10
  /**
10
11
  * FilterDateRangePicker component.
@@ -18,7 +19,7 @@ const DEFAULT_FORMAT = 'YYYY/MM/DD';
18
19
  * neither of which are appropriate here. FilterDateRangePicker uses CalendarIcon and
19
20
  * has no form-field semantics.
20
21
  */
21
- export function FilterDateRangePicker({ label, value, defaultValue, onChange, open, onOpenStateChanged, format = DEFAULT_FORMAT, enableClearButton = false, clearButtonProps, disabled = false, className, targetDOMNode, minDate, maxDate, calendarLocale = 'ja', }) {
22
+ export function FilterDateRangePicker({ label, value, defaultValue, onChange, open, onOpenStateChanged, format = DEFAULT_FORMAT, enableClearButton = false, clearButtonProps, disabled = false, className, targetDOMNode, minDate, maxDate, calendarLocale = 'ja', firstDayOfWeek = DEFAULT_FIRST_DAY_OF_WEEK, }) {
22
23
  const classes = filterDateRangePickerSlotRecipe();
23
24
  const triggerRef = useRef(null);
24
25
  const dialogId = useId();
@@ -38,5 +39,5 @@ export function FilterDateRangePicker({ label, value, defaultValue, onChange, op
38
39
  onOpenStateChanged?.(false);
39
40
  },
40
41
  });
41
- return (_jsx(BaseRangePickerProvider, { value: value, defaultValue: defaultValue, format: format, isOpen: isCalendarOpen, open: openCalendar, close: closeCalendar, minDate: minDate, maxDate: maxDate, disabled: disabled, onChange: onChange, children: _jsx(InternalDateRangePickerContent, { classes: classes, triggerRef: triggerRef, dialogId: dialogId, label: label, format: format, disabled: disabled, className: className, enableClearButton: enableClearButton, clearButtonProps: clearButtonProps, targetDOMNode: targetDOMNode, isCalendarOpen: isCalendarOpen, toggleCalendar: toggleCalendar, calendarLocale: calendarLocale }) }));
42
+ return (_jsx(BaseRangePickerProvider, { value: value, defaultValue: defaultValue, format: format, isOpen: isCalendarOpen, open: openCalendar, close: closeCalendar, minDate: minDate, maxDate: maxDate, disabled: disabled, onChange: onChange, children: _jsx(InternalDateRangePickerContent, { classes: classes, triggerRef: triggerRef, dialogId: dialogId, label: label, format: format, disabled: disabled, className: className, enableClearButton: enableClearButton, clearButtonProps: clearButtonProps, targetDOMNode: targetDOMNode, isCalendarOpen: isCalendarOpen, toggleCalendar: toggleCalendar, calendarLocale: calendarLocale, firstDayOfWeek: firstDayOfWeek }) }));
42
43
  }
@@ -1,5 +1,6 @@
1
1
  import { type PopoverProps } from '../../Popover';
2
2
  import { type BasePickerProps } from '../shared/BasePicker';
3
+ import { type FirstDayOfWeek } from '../shared/BasePicker/constants';
3
4
  import { type DateRangeInput } from '../shared/BaseRangePicker/BaseRangePicker.types';
4
5
  export type FilterDateRangePickerProps = {
5
6
  /**
@@ -82,4 +83,10 @@ export type FilterDateRangePickerProps = {
82
83
  * @default 'ja'
83
84
  */
84
85
  calendarLocale?: BasePickerProps['calendarLocale'];
86
+ /**
87
+ * The day of the week that the calendar week starts on.
88
+ *
89
+ * @default 'monday'
90
+ */
91
+ firstDayOfWeek?: FirstDayOfWeek;
85
92
  };
@@ -10,8 +10,34 @@ export declare const LABEL_CLOSE_CALENDAR = "\u30AB\u30EC\u30F3\u30C0\u30FC\u309
10
10
  export declare const LABEL_TODAY = "\u4ECA\u65E5";
11
11
  type LabelKey = 'GO_TO_PREV_MONTH' | 'GO_TO_NEXT_MONTH' | 'GO_TO_PREV_YEAR' | 'GO_TO_NEXT_YEAR' | 'SELECT_MONTH' | 'SELECT_YEAR' | 'OPEN_CALENDAR' | 'CLOSE_CALENDAR' | 'TODAY' | 'CLEAR_VALUE';
12
12
  export declare const BASE_PICKER_LABELS: Record<NonNullable<BasePickerProps['calendarLocale']>, Record<LabelKey, string>>;
13
- export declare const DAY_ABBREVIATIONS: Record<NonNullable<BasePickerProps['calendarLocale']>, string[]>;
14
- export declare const DAY_FULL_NAMES: Record<NonNullable<BasePickerProps['calendarLocale']>, string[]>;
13
+ /**
14
+ * The day of the week the calendar week starts on.
15
+ */
16
+ export type FirstDayOfWeek = 'sunday' | 'monday';
17
+ /**
18
+ * The index of a day of the week, matching the value returned by `Date.prototype.getDay()`.
19
+ *
20
+ * 0 = Sunday, 1 = Monday, 2 = Tuesday, 3 = Wednesday, 4 = Thursday, 5 = Friday, 6 = Saturday
21
+ */
22
+ export type DayIndex = 0 | 1 | 2 | 3 | 4 | 5 | 6;
23
+ /**
24
+ * Maps the public `firstDayOfWeek` value to the matching `Date.prototype.getDay()` index.
25
+ */
26
+ export declare const FIRST_DAY_OF_WEEK_TO_DAY_INDEX: {
27
+ readonly sunday: 0;
28
+ readonly monday: 1;
29
+ };
30
+ /**
31
+ * The default day of the week the calendar week starts on.
32
+ */
33
+ export declare const DEFAULT_FIRST_DAY_OF_WEEK: FirstDayOfWeek;
34
+ /**
35
+ * Day-of-the-week labels indexed by `Date.prototype.getDay()` (0 = Sunday).
36
+ * The tuple type keeps the arrays exactly seven entries long.
37
+ */
38
+ type DayLabels = readonly [string, string, string, string, string, string, string];
39
+ export declare const DAY_ABBREVIATIONS: Record<NonNullable<BasePickerProps['calendarLocale']>, DayLabels>;
40
+ export declare const DAY_FULL_NAMES: Record<NonNullable<BasePickerProps['calendarLocale']>, DayLabels>;
15
41
  export declare function getBasePickerLabel(key: LabelKey, locale?: NonNullable<BasePickerProps['calendarLocale']>): string;
16
42
  /**
17
43
  * The minimum year that can be selected in the DatePicker
@@ -33,13 +33,24 @@ export const BASE_PICKER_LABELS = {
33
33
  CLEAR_VALUE: 'Clear value',
34
34
  },
35
35
  };
36
+ /**
37
+ * Maps the public `firstDayOfWeek` value to the matching `Date.prototype.getDay()` index.
38
+ */
39
+ export const FIRST_DAY_OF_WEEK_TO_DAY_INDEX = {
40
+ sunday: 0,
41
+ monday: 1,
42
+ };
43
+ /**
44
+ * The default day of the week the calendar week starts on.
45
+ */
46
+ export const DEFAULT_FIRST_DAY_OF_WEEK = 'monday';
36
47
  export const DAY_ABBREVIATIONS = {
37
- ja: ['月', '火', '水', '木', '金', '土', '日'],
38
- en: ['Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su'],
48
+ ja: ['日', '月', '火', '水', '木', '金', '土'],
49
+ en: ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'],
39
50
  };
40
51
  export const DAY_FULL_NAMES = {
41
- ja: ['月曜日', '火曜日', '水曜日', '木曜日', '金曜日', '土曜日', '日曜日'],
42
- en: ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'],
52
+ ja: ['日曜日', '月曜日', '火曜日', '水曜日', '木曜日', '金曜日', '土曜日'],
53
+ en: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
43
54
  };
44
55
  export function getBasePickerLabel(key, locale = 'ja') {
45
56
  const safeLocale = locale in BASE_PICKER_LABELS ? locale : 'ja';
@@ -13,6 +13,10 @@ import { type BaseRangePickerProps } from '../BaseRangePicker.types';
13
13
  * @remarks
14
14
  * - Accessibility is handled by subcomponents (calendars and footer).
15
15
  * - This component should not be used outside a BaseRangePickerProvider.
16
+ * - `firstDayOfWeek` is intentionally not supported here. This popover is only reachable through
17
+ * BaseRangePicker's backward-compatible default `renderPopoverContent`, and every real consumer
18
+ * (DateRangePicker / MonthRangePicker) supplies its own. The calendars therefore fall back to the
19
+ * FirstDayOfWeekContext default ('monday'), which matches the previous hardcoded behaviour.
16
20
  *
17
21
  * @example
18
22
  * <BaseRangePickerProvider>
@@ -28,6 +28,10 @@ const addMonths = (date, months) => new Date(date.getFullYear(), date.getMonth()
28
28
  * @remarks
29
29
  * - Accessibility is handled by subcomponents (calendars and footer).
30
30
  * - This component should not be used outside a BaseRangePickerProvider.
31
+ * - `firstDayOfWeek` is intentionally not supported here. This popover is only reachable through
32
+ * BaseRangePicker's backward-compatible default `renderPopoverContent`, and every real consumer
33
+ * (DateRangePicker / MonthRangePicker) supplies its own. The calendars therefore fall back to the
34
+ * FirstDayOfWeekContext default ('monday'), which matches the previous hardcoded behaviour.
31
35
  *
32
36
  * @example
33
37
  * <BaseRangePickerProvider>
@@ -8,9 +8,13 @@ import { computeDataForStyling } from './utilities/computeDataForStyling';
8
8
  import { checkIsSameDate } from './utilities/dateUtilities';
9
9
  import { dayjs } from '../../../utilities/date/dayjs';
10
10
  import { calendarGridSlotRecipe } from '../../../../styled-system/recipes';
11
+ import { useFirstDayOfWeek } from '../CalendarLocale/FirstDayOfWeekContext';
12
+ import { FIRST_DAY_OF_WEEK_TO_DAY_INDEX } from '../BasePicker/constants';
11
13
  export function CalendarGrid({ viewingValue, minDate, maxDate, checkDisabledDate, onKeyboardNavigation, pendingFocusDate, onPendingFocusDateChange, value, renderDateCell, className, onDateClick, }) {
12
- const dates = useDates(viewingValue);
13
- const computedDataForStyles = useMemo(() => computeDataForStyling(viewingValue), [viewingValue]);
14
+ const firstDayOfWeek = useFirstDayOfWeek();
15
+ const weekStart = FIRST_DAY_OF_WEEK_TO_DAY_INDEX[firstDayOfWeek];
16
+ const dates = useDates(viewingValue, weekStart);
17
+ const computedDataForStyles = useMemo(() => computeDataForStyling(viewingValue, weekStart), [viewingValue, weekStart]);
14
18
  const computedPropsForDates = useMemo(() => {
15
19
  // Normalize to Date objects — Storybook Controls can pass ISO strings instead of Date instances.
16
20
  // Cast to unknown first to suppress the unnecessary-condition lint rule while preserving runtime safety.
@@ -93,9 +97,9 @@ export function CalendarGrid({ viewingValue, minDate, maxDate, checkDisabledDate
93
97
  onPendingFocusDateChange?.(null);
94
98
  }, [viewingValue, pendingFocusDate, onPendingFocusDateChange]);
95
99
  const classes = calendarGridSlotRecipe();
96
- return (_jsxs("div", { className: cx(classes.calendarGrid, 'mfui-CalendarGrid__calendarGrid', className), children: [Array(7)
97
- .fill(null)
98
- .map((_, index) => (_jsx(DayCell, { day: index }, index))), computedPropsForDates.map((dateItem, index) => {
100
+ return (_jsxs("div", { className: cx(classes.calendarGrid, 'mfui-CalendarGrid__calendarGrid', className), children: [Array.from({ length: 7 })
101
+ .map((_, index) => ((weekStart + index) % 7))
102
+ .map((weekday) => (_jsx(DayCell, { day: weekday }, weekday))), computedPropsForDates.map((dateItem, index) => {
99
103
  // All props are generated internally and guaranteed to have required fields
100
104
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
101
105
  // @ts-ignore
@@ -1,11 +1,13 @@
1
+ import { type DayIndex } from '../../BasePicker/constants';
1
2
  /**
2
3
  * Compute data for styling the calendar view
3
4
  *
4
5
  * @param viewingValue - The value that is currently viewing
6
+ * @param weekStart - The `Date.prototype.getDay()` index the week starts on (0 = Sunday, 1 = Monday)
5
7
  *
6
8
  * @returns The data for styling the calendar view
7
9
  */
8
- export declare function computeDataForStyling(viewingValue: Date): {
10
+ export declare function computeDataForStyling(viewingValue: Date, weekStart: DayIndex): {
9
11
  datesHasBorderTopLeftRadius: Set<number>;
10
12
  datesHasBorderTopRightRadius: Set<number>;
11
13
  datesHasBorderBottomLeftRadius: Set<number>;
@@ -3,43 +3,45 @@ import { getTotalDaysInMonth } from './dateUtilities';
3
3
  * Compute data for styling the calendar view
4
4
  *
5
5
  * @param viewingValue - The value that is currently viewing
6
+ * @param weekStart - The `Date.prototype.getDay()` index the week starts on (0 = Sunday, 1 = Monday)
6
7
  *
7
8
  * @returns The data for styling the calendar view
8
9
  */
9
- export function computeDataForStyling(viewingValue) {
10
+ export function computeDataForStyling(viewingValue, weekStart) {
10
11
  const year = viewingValue.getFullYear();
11
12
  const month = viewingValue.getMonth();
12
13
  const firstDate = viewingValue.getDate(); // of course, it's 1, but for readability
13
14
  const firstDateDay = viewingValue.getDay();
15
+ // The last column of the grid, i.e. the day right before the week starts over
16
+ const weekEnd = (weekStart + 6) % 7;
14
17
  const datesHasBorderTopLeftRadius = new Set();
15
18
  // First date of the month has borderTopLeftRadius
16
19
  datesHasBorderTopLeftRadius.add(1);
17
- // First Monday of the month has borderTopLeftRadius
18
- // Because Monday is 1, so we will use 8 to represent Monday and % 7 to get the correct date
19
- const firstMonday = firstDate + ((8 - firstDateDay) % 7);
20
- datesHasBorderTopLeftRadius.add(firstMonday);
20
+ // First date sitting at the start of a row has borderTopLeftRadius
21
+ const firstRowStartDate = firstDate + ((weekStart - firstDateDay + 7) % 7);
22
+ datesHasBorderTopLeftRadius.add(firstRowStartDate);
21
23
  const datesHasBorderTopRightRadius = new Set();
22
- // First Sunday of the month has borderTopRightRadius
23
- const firstSunday = viewingValue.getDate() + ((7 - firstDateDay) % 7);
24
- datesHasBorderTopRightRadius.add(firstSunday);
24
+ // First date sitting at the end of a row has borderTopRightRadius
25
+ const firstRowEndDate = firstDate + ((weekEnd - firstDateDay + 7) % 7);
26
+ datesHasBorderTopRightRadius.add(firstRowEndDate);
25
27
  const lastDate = new Date(year, month + 1, 0);
26
28
  const datesHasBorderBottomLeftRadius = new Set();
27
- // Last Monday of the month has borderBottomLeftRadius
28
- const lastMonday = lastDate.getDate() - ((lastDate.getDay() + 6) % 7);
29
- datesHasBorderBottomLeftRadius.add(lastMonday);
29
+ // Last date sitting at the start of a row has borderBottomLeftRadius
30
+ const lastRowStartDate = lastDate.getDate() - ((lastDate.getDay() - weekStart + 7) % 7);
31
+ datesHasBorderBottomLeftRadius.add(lastRowStartDate);
30
32
  const datesHasBorderBottomRightRadius = new Set();
31
33
  // Last date of the month has borderBottomRightRadius
32
34
  datesHasBorderBottomRightRadius.add(lastDate.getDate());
33
- // Last Sunday of the month has borderBottomRightRadius
34
- const lastSunday = lastDate.getDate() - lastDate.getDay();
35
- datesHasBorderBottomRightRadius.add(lastSunday);
35
+ // Last date sitting at the end of a row has borderBottomRightRadius
36
+ const lastRowEndDate = lastDate.getDate() - ((lastDate.getDay() - weekEnd + 7) % 7);
37
+ datesHasBorderBottomRightRadius.add(lastRowEndDate);
36
38
  const datesHasBorderRight = new Set();
37
- // All Sundays have borderRight
39
+ // All dates in the last column have borderRight
38
40
  Array(getTotalDaysInMonth(month, year))
39
41
  .fill(0)
40
42
  .forEach((_date, dateIndex) => {
41
43
  const day = new Date(year, month, dateIndex + 1).getDay();
42
- if (day === 0) {
44
+ if (day === weekEnd) {
43
45
  datesHasBorderRight.add(dateIndex + 1);
44
46
  }
45
47
  });
@@ -54,10 +56,10 @@ export function computeDataForStyling(viewingValue) {
54
56
  });
55
57
  const lastWeekDates = new Set();
56
58
  // Last dates of the last week of the viewing month
57
- // Simply by adding the last date, then subtracting the index, util it's Monday
59
+ // Simply by adding the last date, then subtracting the index, until the row starts over
58
60
  for (let i = 0; i < 7; i++) {
59
61
  const date = lastDate.getDate() - i;
60
- if (new Date(year, month, date).getDay() === 1) {
62
+ if (new Date(year, month, date).getDay() === weekStart) {
61
63
  lastWeekDates.add(date);
62
64
  break;
63
65
  }
@@ -1,12 +1,15 @@
1
+ import { type DayIndex } from '../../BasePicker/constants';
1
2
  /**
2
3
  * Separate the viewing value into dates
3
- * To make sure it always start with Monday, it will fill the blank by null value
4
+ * To make sure it always starts on the configured first day of the week, it will fill the blank by null value
4
5
  *
5
- * @param viewingValue - The date that user is viewing
6
+ * @param viewingValue - The date that user is viewing. Always normalized to the first day of the month.
7
+ * @param weekStart - The `Date.prototype.getDay()` index the week starts on (0 = Sunday, 1 = Monday)
6
8
  *
7
9
  * @returns The chunked dates as the example
8
10
  *
9
11
  * @example
12
+ * // 2025-09 with weekStart = 1 (Monday)
10
13
  * [
11
14
  * null, 1, 2, 3, 4, 5, 6,
12
15
  * 7, 8, 9, 10, 11, 12, 13,
@@ -16,4 +19,4 @@
16
19
  * null, null, null, null, null, null, null
17
20
  * ]
18
21
  */
19
- export declare function useDates(viewingValue: Date): (number | null)[];
22
+ export declare function useDates(viewingValue: Date, weekStart: DayIndex): (number | null)[];
@@ -2,13 +2,15 @@ import { useMemo } from 'react';
2
2
  import { getTotalDaysInMonth } from './dateUtilities';
3
3
  /**
4
4
  * Separate the viewing value into dates
5
- * To make sure it always start with Monday, it will fill the blank by null value
5
+ * To make sure it always starts on the configured first day of the week, it will fill the blank by null value
6
6
  *
7
- * @param viewingValue - The date that user is viewing
7
+ * @param viewingValue - The date that user is viewing. Always normalized to the first day of the month.
8
+ * @param weekStart - The `Date.prototype.getDay()` index the week starts on (0 = Sunday, 1 = Monday)
8
9
  *
9
10
  * @returns The chunked dates as the example
10
11
  *
11
12
  * @example
13
+ * // 2025-09 with weekStart = 1 (Monday)
12
14
  * [
13
15
  * null, 1, 2, 3, 4, 5, 6,
14
16
  * 7, 8, 9, 10, 11, 12, 13,
@@ -18,16 +20,18 @@ import { getTotalDaysInMonth } from './dateUtilities';
18
20
  * null, null, null, null, null, null, null
19
21
  * ]
20
22
  */
21
- export function useDates(viewingValue) {
23
+ export function useDates(viewingValue, weekStart) {
22
24
  return useMemo(() => {
23
25
  // Count empty dates at start
24
- const emptyDatesStart = Array(viewingValue.getDay() === 0 ? 6 : viewingValue.getDay() - 1).fill(null);
26
+ const leadingEmptyCount = (viewingValue.getDay() - weekStart + 7) % 7;
27
+ const emptyDatesStart = Array(leadingEmptyCount).fill(null);
25
28
  // List up dates of viewing value
26
29
  const dates = Array(getTotalDaysInMonth(viewingValue.getMonth(), viewingValue.getFullYear()))
27
30
  .fill(0)
28
31
  .map((_, dateIndex) => dateIndex + 1);
29
32
  // Keep the calendar at six weeks so its height does not change between months.
33
+ // The maximum leading offset (6) plus the longest month (31) is 37, so 42 cells always fit.
30
34
  const emptyDatesEnd = Array(42 - emptyDatesStart.length - dates.length).fill(null);
31
35
  return [...emptyDatesStart, ...dates, ...emptyDatesEnd];
32
- }, [viewingValue]);
36
+ }, [viewingValue, weekStart]);
33
37
  }
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ import { type FirstDayOfWeek } from '../BasePicker/constants';
3
+ export type FirstDayOfWeekContextValue = FirstDayOfWeek | undefined;
4
+ export declare function FirstDayOfWeekProvider({ value, children, }: {
5
+ value: FirstDayOfWeekContextValue;
6
+ children: React.ReactNode;
7
+ }): import("react/jsx-runtime").JSX.Element;
8
+ export declare function useFirstDayOfWeek(): FirstDayOfWeek;
@@ -0,0 +1,11 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { createContext, useContext } from 'react';
4
+ import { DEFAULT_FIRST_DAY_OF_WEEK } from '../BasePicker/constants';
5
+ const FirstDayOfWeekContext = createContext(DEFAULT_FIRST_DAY_OF_WEEK);
6
+ export function FirstDayOfWeekProvider({ value, children, }) {
7
+ return _jsx(FirstDayOfWeekContext.Provider, { value: value, children: children });
8
+ }
9
+ export function useFirstDayOfWeek() {
10
+ return useContext(FirstDayOfWeekContext) ?? DEFAULT_FIRST_DAY_OF_WEEK;
11
+ }
@@ -59,7 +59,7 @@ export type DateCellProps = {
59
59
  /**
60
60
  * Whether the cell has right border or not.
61
61
  * It will be calculated on the Calendar component and passed down to the DateCell component.
62
- * If it is Sunday, it will have borderRight.
62
+ * If it is in the last column of the week, it will have borderRight.
63
63
  *
64
64
  * @default false
65
65
  */
@@ -1,13 +1,14 @@
1
+ import { type DayIndex } from '../BasePicker/constants';
1
2
  /**
2
3
  * DayCellProps is the props interface for the DayCell component.
3
4
  */
4
5
  type DayCellProps = {
5
6
  /**
6
- * The day of the week.
7
+ * The day of the week, matching the value returned by `Date.prototype.getDay()`.
7
8
  *
8
- * 0 = Monday, 1 = Tuesday, 2 = Wednesday, 3 = Thursday, 4 = Friday, 5 = Saturday, 6 = Sunday
9
+ * 0 = Sunday, 1 = Monday, 2 = Tuesday, 3 = Wednesday, 4 = Thursday, 5 = Friday, 6 = Saturday
9
10
  */
10
- day: number;
11
+ day: DayIndex;
11
12
  };
12
13
  /**
13
14
  * DayCell is a cell that represents a day of the week in the Calendar component.
@@ -0,0 +1,22 @@
1
+ /**
2
+ * A table-styled list of key-value rows.
3
+ * Use DecoratedKeyValueList.Item to render each row.
4
+ *
5
+ * @example
6
+ * ```jsx
7
+ * <DecoratedKeyValueList>
8
+ * <DecoratedKeyValueList.Item keyItem="Name" valueItem="Jane Doe" />
9
+ * <DecoratedKeyValueList.Item keyItem="Role" valueItem="Administrator" />
10
+ * </DecoratedKeyValueList>
11
+ * ```
12
+ */
13
+ export declare const DecoratedKeyValueList: import("react").ForwardRefExoticComponent<{
14
+ size?: import("../../styled-system/recipes").DecoratedKeyValueListSlotRecipeVariant['size'];
15
+ gridTemplateColumns?: import("react").CSSProperties['gridTemplateColumns'];
16
+ children?: React.ReactNode;
17
+ } & Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLUListElement>, HTMLUListElement>, "ref"> & import("react").RefAttributes<HTMLUListElement>> & {
18
+ /**
19
+ * A row in the DecoratedKeyValueList.
20
+ */
21
+ Item: import("react").ForwardRefExoticComponent<import(".").DecoratedKeyValueListItemProps & import("react").RefAttributes<HTMLLIElement>>;
22
+ };
@@ -0,0 +1,28 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { forwardRef } from 'react';
3
+ import { cx } from '../../styled-system/css';
4
+ import { decoratedKeyValueListSlotRecipe } from '../../styled-system/recipes';
5
+ import { DecoratedKeyValueListItem } from './DecoratedKeyValueListItem/DecoratedKeyValueListItem';
6
+ const DecoratedKeyValueListBase = forwardRef(({ size = 'medium', gridTemplateColumns = '140px 1fr', children, className, style, ...props }, ref) => {
7
+ const classes = decoratedKeyValueListSlotRecipe({ size });
8
+ return (_jsx("ul", { ref: ref, className: cx(classes.root, 'mfui-DecoratedKeyValueList__root', className), ...props, style: { gridTemplateColumns, ...style }, children: children }));
9
+ });
10
+ /**
11
+ * A table-styled list of key-value rows.
12
+ * Use DecoratedKeyValueList.Item to render each row.
13
+ *
14
+ * @example
15
+ * ```jsx
16
+ * <DecoratedKeyValueList>
17
+ * <DecoratedKeyValueList.Item keyItem="Name" valueItem="Jane Doe" />
18
+ * <DecoratedKeyValueList.Item keyItem="Role" valueItem="Administrator" />
19
+ * </DecoratedKeyValueList>
20
+ * ```
21
+ */
22
+ export const DecoratedKeyValueList = Object.assign(DecoratedKeyValueListBase, {
23
+ /**
24
+ * A row in the DecoratedKeyValueList.
25
+ */
26
+ Item: DecoratedKeyValueListItem,
27
+ });
28
+ DecoratedKeyValueList.displayName = 'DecoratedKeyValueList';
@@ -0,0 +1,21 @@
1
+ import { type CSSProperties, type ComponentPropsWithoutRef } from 'react';
2
+ import { type DecoratedKeyValueListSlotRecipeVariant } from '../../styled-system/recipes';
3
+ /**
4
+ * Props for the DecoratedKeyValueList component.
5
+ */
6
+ export type DecoratedKeyValueListProps = {
7
+ /**
8
+ * The size (row density) of all items in the list.
9
+ * @default 'medium'
10
+ */
11
+ size?: DecoratedKeyValueListSlotRecipeVariant['size'];
12
+ /**
13
+ * The grid template columns defining the key / value column widths.
14
+ * @default '140px 1fr'
15
+ */
16
+ gridTemplateColumns?: CSSProperties['gridTemplateColumns'];
17
+ /**
18
+ * The rows of the list. Use DecoratedKeyValueList.Item.
19
+ */
20
+ children?: React.ReactNode;
21
+ } & ComponentPropsWithoutRef<'ul'>;
@@ -0,0 +1,8 @@
1
+ import { type DecoratedKeyValueListItemProps } from './DecoratedKeyValueListItem.types';
2
+ /**
3
+ * A row in a DecoratedKeyValueList.
4
+ * The key item accepts any React node. Use `valueItem` for a single value item,
5
+ * or `valueItems` to stack multiple simple value items separated by dividers.
6
+ * Associate form controls with their key items explicitly using native labeling or ARIA attributes.
7
+ */
8
+ export declare const DecoratedKeyValueListItem: import("react").ForwardRefExoticComponent<DecoratedKeyValueListItemProps & import("react").RefAttributes<HTMLLIElement>>;
@@ -0,0 +1,18 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { forwardRef } from 'react';
3
+ import { cx } from '../../../styled-system/css';
4
+ import { decoratedKeyValueListItemSlotRecipe } from '../../../styled-system/recipes';
5
+ /**
6
+ * A row in a DecoratedKeyValueList.
7
+ * The key item accepts any React node. Use `valueItem` for a single value item,
8
+ * or `valueItems` to stack multiple simple value items separated by dividers.
9
+ * Associate form controls with their key items explicitly using native labeling or ARIA attributes.
10
+ */
11
+ export const DecoratedKeyValueListItem = forwardRef(({ keyItem, valueItem, valueItems, className, ...props }, ref) => {
12
+ const classes = decoratedKeyValueListItemSlotRecipe();
13
+ // Skip nullish and boolean entries so conditional expressions like
14
+ // `condition && <Node />` do not render an empty cell with a divider.
15
+ const resolvedValueItems = (valueItems ?? [valueItem]).filter((entry) => entry !== null && entry !== undefined && typeof entry !== 'boolean');
16
+ return (_jsxs("li", { ref: ref, className: cx(classes.root, 'mfui-DecoratedKeyValueListItem__root', className), ...props, children: [_jsx("div", { className: cx(classes.keyItem, 'mfui-DecoratedKeyValueListItem__keyItem'), children: keyItem }), _jsx("div", { className: cx(classes.valueGroup, 'mfui-DecoratedKeyValueListItem__valueGroup'), children: resolvedValueItems.map((entry, index) => (_jsx("div", { className: cx(classes.valueItem, 'mfui-DecoratedKeyValueListItem__valueItem'), children: entry }, index))) })] }));
17
+ });
18
+ DecoratedKeyValueListItem.displayName = 'DecoratedKeyValueListItem';
@@ -0,0 +1,25 @@
1
+ import { type ComponentPropsWithoutRef } from 'react';
2
+ type DecoratedKeyValueListItemValueProps = {
3
+ /**
4
+ * The value item of the row. Accepts any ReactNode (text, form controls, nested tables, etc.).
5
+ */
6
+ valueItem: React.ReactNode;
7
+ valueItems?: never;
8
+ } | {
9
+ /**
10
+ * Multiple value items stacked vertically in the row, separated by dividers.
11
+ * Intended for simple content such as strings. Nullish and boolean entries are skipped.
12
+ */
13
+ valueItems: React.ReactNode[];
14
+ valueItem?: never;
15
+ };
16
+ /**
17
+ * Props for the DecoratedKeyValueListItem component.
18
+ */
19
+ export type DecoratedKeyValueListItemProps = {
20
+ /**
21
+ * The key item of the row. Accepts any ReactNode.
22
+ */
23
+ keyItem: React.ReactNode;
24
+ } & DecoratedKeyValueListItemValueProps & Omit<ComponentPropsWithoutRef<'li'>, 'children' | 'value'>;
25
+ export {};
@@ -0,0 +1,4 @@
1
+ export { DecoratedKeyValueList } from './DecoratedKeyValueList';
2
+ export type { DecoratedKeyValueListProps } from './DecoratedKeyValueList.types';
3
+ export { DecoratedKeyValueListItem } from './DecoratedKeyValueListItem/DecoratedKeyValueListItem';
4
+ export type { DecoratedKeyValueListItemProps } from './DecoratedKeyValueListItem/DecoratedKeyValueListItem.types';
@@ -0,0 +1,2 @@
1
+ export { DecoratedKeyValueList } from './DecoratedKeyValueList';
2
+ export { DecoratedKeyValueListItem } from './DecoratedKeyValueListItem/DecoratedKeyValueListItem';
@@ -5,7 +5,7 @@ import { DisplayTableHeader } from './DisplayTableHeader';
5
5
  import { DisplayTableHeaderCell } from './DisplayTableHeaderCell';
6
6
  import { DisplayTableHeaderRow } from './DisplayTableHeaderRow';
7
7
  import { DisplayTableRow } from './DisplayTableRow';
8
- declare function Base({ title, titleTag, lead, className, fixedHeader, leftFixedColumnIndex, rightFixedColumnIndex, wrapperProps, loading, ...props }: DisplayTableProps): import("react/jsx-runtime").JSX.Element;
8
+ declare function Base({ title, titleTag, renderHeading, lead, className, fixedHeader, leftFixedColumnIndex, rightFixedColumnIndex, wrapperProps, loading, ...props }: DisplayTableProps): import("react/jsx-runtime").JSX.Element;
9
9
  /**
10
10
  * The `DisplayTable` component.
11
11
  *
@@ -1,5 +1,5 @@
1
1
  'use client';
2
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { DisplayTableProvider } from './DisplayTableProvider';
4
4
  import { displayTableSlotRecipe } from '../../styled-system/recipes';
5
5
  import { DisplayTableBody } from './DisplayTableBody';
@@ -11,9 +11,14 @@ import { DisplayTableRow } from './DisplayTableRow';
11
11
  import { cx } from '../../styled-system/css';
12
12
  import { Heading } from '../Heading';
13
13
  import { Typography } from '../Typography';
14
- function Base({ title, titleTag = 'h4', lead, className, fixedHeader = false, leftFixedColumnIndex, rightFixedColumnIndex, wrapperProps, loading = false, ...props }) {
14
+ function Base({ title, titleTag = 'h4', renderHeading, lead, className, fixedHeader = false, leftFixedColumnIndex, rightFixedColumnIndex, wrapperProps, loading = false, ...props }) {
15
15
  const classes = displayTableSlotRecipe({ fixedHeader });
16
- return (_jsx(DisplayTableProvider, { fixedHeader: fixedHeader, leftFixedColumnIndex: leftFixedColumnIndex, rightFixedColumnIndex: rightFixedColumnIndex, loading: loading, children: _jsxs("div", { ...wrapperProps, className: cx(classes.wrapper, 'mfui-DisplayTable__wrapper', wrapperProps?.className), children: [_jsxs("div", { className: cx(classes.header, 'mfui-DisplayTable__header'), children: [_jsx(Heading, { variant: "sectionHeading2", tag: titleTag, className: cx(classes.title, 'mfui-DisplayTable__title'), children: title }), lead ? (_jsx(Typography, { tag: "p", className: cx(classes.lead, 'mfui-DisplayTable__lead'), children: lead })) : null] }), _jsx("div", { className: cx(classes.body, 'mfui-DisplayTable__body'), children: _jsx("table", { className: cx(classes.table, 'mfui-DisplayTable__table', className), "aria-live": "polite", "aria-busy": loading, "aria-label": loading ? 'データを読み込み中' : undefined, ...props }) })] }) }));
16
+ const headingNode = title ? (_jsx(Heading, { variant: "sectionHeading2", tag: titleTag, className: cx(classes.title, 'mfui-DisplayTable__title'), children: title })) : null;
17
+ const leadNode = lead ? (_jsx(Typography, { tag: "p", className: cx(classes.lead, 'mfui-DisplayTable__lead'), children: lead })) : null;
18
+ const headingContent = renderHeading ? (renderHeading({ headingNode, leadNode })) : headingNode || leadNode ? (_jsxs(_Fragment, { children: [headingNode, leadNode] })) : null;
19
+ // `renderHeading` can return renderable falsy values such as `0`, so only nodes React never renders are excluded.
20
+ const hasHeadingContent = headingContent != null && typeof headingContent !== 'boolean' && headingContent !== '';
21
+ return (_jsx(DisplayTableProvider, { fixedHeader: fixedHeader, leftFixedColumnIndex: leftFixedColumnIndex, rightFixedColumnIndex: rightFixedColumnIndex, loading: loading, children: _jsxs("div", { ...wrapperProps, className: cx(classes.wrapper, 'mfui-DisplayTable__wrapper', wrapperProps?.className), children: [hasHeadingContent ? (_jsx("div", { className: cx(classes.header, 'mfui-DisplayTable__header'), children: headingContent })) : null, _jsx("div", { className: cx(classes.body, 'mfui-DisplayTable__body'), children: _jsx("table", { className: cx(classes.table, 'mfui-DisplayTable__table', className), "aria-live": "polite", "aria-busy": loading, "aria-label": loading ? 'データを読み込み中' : undefined, ...props }) })] }) }));
17
22
  }
18
23
  /**
19
24
  * The `DisplayTable` component.