@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
@@ -1,6 +1,19 @@
1
- import { type ComponentPropsWithoutRef } from 'react';
1
+ import { type ComponentPropsWithoutRef, type ReactNode } from 'react';
2
2
  import { type HeadingProps } from '../Heading';
3
3
  export type CellDataType = 'text' | 'amount';
4
+ export type DisplayTableRenderOptions = {
5
+ /**
6
+ * The original title element wrapped in the heading tag specified by `titleTag`.
7
+ * This ensures proper semantic HTML structure and accessibility.
8
+ * It is `null` when `title` is not provided.
9
+ */
10
+ headingNode: ReactNode;
11
+ /**
12
+ * The original lead element.
13
+ * It is `null` when `lead` is not provided.
14
+ */
15
+ leadNode: ReactNode;
16
+ };
4
17
  /**
5
18
  * The props for the `DisplayTable` component.
6
19
  *
@@ -14,7 +27,7 @@ export type DisplayTableProps = {
14
27
  * This is used to provide a title for the table.
15
28
  * The title is displayed above the table.
16
29
  */
17
- title: string;
30
+ title?: string;
18
31
  /**
19
32
  * The tag of the title.
20
33
  * This is used to determine the HTML tag to be used for the title.
@@ -23,6 +36,35 @@ export type DisplayTableProps = {
23
36
  * @default 'h4'
24
37
  */
25
38
  titleTag?: HeadingProps['tag'];
39
+ /**
40
+ * Custom render function for the entire heading area.
41
+ * It provides the original title and lead elements for flexible layout composition.
42
+ * When provided, it replaces the default rendering of both `title` and `lead`.
43
+ *
44
+ * @param options - Contains the original title and lead elements.
45
+ *
46
+ * @returns Custom content for the entire heading area.
47
+ *
48
+ * @example
49
+ * ```tsx
50
+ * <DisplayTable
51
+ * title="Sales report"
52
+ * lead="Updated daily"
53
+ * renderHeading={({ headingNode, leadNode }) => (
54
+ * <div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
55
+ * <div>
56
+ * {headingNode}
57
+ * {leadNode}
58
+ * </div>
59
+ * <Button>Edit</Button>
60
+ * </div>
61
+ * )}
62
+ * >
63
+ * ...
64
+ * </DisplayTable>
65
+ * ```
66
+ */
67
+ renderHeading?: (options: DisplayTableRenderOptions) => ReactNode;
26
68
  /**
27
69
  * The lead text of the table.
28
70
  * This is used to provide additional information about the table.
@@ -1,3 +1,4 @@
1
+ import { type EmbeddedSidePaneProps } from './EmbeddedSidePane.types';
1
2
  /**
2
3
  * `EmbeddedSidePane` is a variant of `SidePane` that is positioned absolutely within its container.
3
4
  * The container must have `position: relative` for proper positioning and `overflow: hidden/clip` for clipping.
@@ -5,9 +6,7 @@
5
6
  *
6
7
  * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/div
7
8
  */
8
- export declare const EmbeddedSidePane: import("react").ForwardRefExoticComponent<{
9
- container?: HTMLElement | null;
10
- } & Omit<import("..").SidePaneProps, "enableNonModal" | "targetDOMNode"> & import("react").RefAttributes<HTMLDivElement>> & {
9
+ export declare const EmbeddedSidePane: import("react").ForwardRefExoticComponent<EmbeddedSidePaneProps & import("react").RefAttributes<HTMLDivElement>> & {
11
10
  /**
12
11
  * The `EmbeddedSidePane.Container` component is used to define the container for the `EmbeddedSidePane`.
13
12
  * It should be a parent element that has `position: relative` for proper positioning and `overflow: hidden/clip` for clipping.
@@ -1,5 +1,5 @@
1
1
  import { type ComponentPropsWithoutRef } from 'react';
2
- import { type SidePaneProps } from '../SidePane/SidePane.types';
2
+ import { type SidePaneAccessibleNameProps, type SidePaneBaseProps } from '../SidePane/SidePane.types';
3
3
  export type EmbeddedSidePaneProps = {
4
4
  /**
5
5
  * The container element where the EmbeddedSidePane will be rendered inside and positioned.
@@ -8,5 +8,5 @@ export type EmbeddedSidePaneProps = {
8
8
  * @default undefined
9
9
  */
10
10
  container?: HTMLElement | null;
11
- } & Omit<SidePaneProps, 'targetDOMNode' | 'enableNonModal'>;
11
+ } & Omit<SidePaneBaseProps, 'targetDOMNode' | 'enableNonModal'> & SidePaneAccessibleNameProps;
12
12
  export type EmbeddedSidePaneContainerProps = ComponentPropsWithoutRef<'div'>;
@@ -40,7 +40,7 @@ export function BaseMainNavigation({ className, featureShortcut, navigationItems
40
40
  if (navigation.children) {
41
41
  return (_jsx(NestedNavigationItemRenderer, { navigation: navigation, originalIndex: index, navId: navId, classes: classes, InternalLinkTag: InternalLinkTag, isCollapsed: isCollapsed, nestedNavigationDisplay: nestedNavigationDisplay, openPopoverIndex: openPopoverIndex, setOpenPopoverIndex: setOpenPopoverIndex }, index));
42
42
  }
43
- return (_jsx("li", { className: cx(classes.listItem, 'mfui-BaseMainNavigation__listItem'), children: _jsx(Tooltip, { className: cx(classes.listItemTooltip, 'mfui-BaseMainNavigation__listItemTooltip'), content: navigation.label, disabled: !isCollapsed, placement: "right", children: _jsx(FocusIndicator, { position: "inside", children: _jsx(NavigationLink, { tag: InternalLinkTag, isExternal: navigation.isExternal, href: navigation.href, className: cx(classes.listItemAnchor, 'mfui-BaseMainNavigation__listItemAnchor'), "aria-label": isCollapsed ? navigation.label : undefined, "aria-current": navigation.isCurrent ? 'page' : undefined, children: _jsxs("div", { className: cx(classes.labelGroup, 'mfui-BaseMainNavigation__labelGroup'), children: [_jsxs("div", { className: cx(classes.iconAndLabel, 'mfui-BaseMainNavigation__iconAndLabel'), children: [_jsx("div", { "aria-hidden": "true", className: cx(classes.listItemAnchorIcon, 'mfui-BaseMainNavigation__listItemAnchorIcon'), children: navigation.icon }), isCollapsed ? null : _jsx(Typography, { variant: "controlLabel", children: navigation.label })] }), navigation.locked ? (_jsx(Lock, { className: cx(classes.lockIcon, 'mfui-BaseMainNavigation__lockIcon'), "aria-label": navigation.lockIconProps?.['aria-label'] ?? 'ロックされています' })) : null, !isCollapsed && navigation.statusSlot && navigation.locked !== true
43
+ return (_jsx("li", { className: cx(classes.listItem, 'mfui-BaseMainNavigation__listItem'), children: _jsx(Tooltip, { className: cx(classes.listItemTooltip, 'mfui-BaseMainNavigation__listItemTooltip'), content: navigation.label, disabled: !isCollapsed, placement: "right", children: _jsx(FocusIndicator, { position: "inside", children: _jsx(NavigationLink, { tag: InternalLinkTag, isExternal: navigation.isExternal, href: navigation.href, className: cx(classes.listItemAnchor, 'mfui-BaseMainNavigation__listItemAnchor'), "aria-label": isCollapsed ? navigation.label : undefined, "aria-current": navigation.isCurrent ? 'page' : undefined, children: _jsxs("div", { className: cx(classes.labelGroup, 'mfui-BaseMainNavigation__labelGroup'), children: [_jsxs("div", { className: cx(classes.iconAndLabel, 'mfui-BaseMainNavigation__iconAndLabel'), children: [_jsx("div", { "aria-hidden": "true", className: cx(classes.listItemAnchorIcon, 'mfui-BaseMainNavigation__listItemAnchorIcon'), children: navigation.icon }), isCollapsed ? null : _jsx(Typography, { variant: "controlLabel", children: navigation.label })] }), navigation.locked ? (_jsx(Lock, { className: cx(classes.lockIcon, 'mfui-BaseMainNavigation__lockIcon'), role: "img", "aria-label": navigation.lockIconProps?.['aria-label'] ?? 'ロックされています' })) : null, !isCollapsed && navigation.statusSlot && navigation.locked !== true
44
44
  ? navigation.statusSlot
45
45
  : null] }) }) }) }) }, index));
46
46
  }) }), navigationItems.some((navigation) => 'isGroupMenu' in navigation && navigation.isGroupMenu) && (_jsx("ul", { className: cx(classes.groupMenuList, 'mfui-BaseMainNavigation__groupMenuList'), children: navigationItems.map((navigation, index) => {
@@ -55,7 +55,7 @@ export function BaseMainNavigation({ className, featureShortcut, navigationItems
55
55
  return null;
56
56
  }
57
57
  const groupLabelId = `${navId}-group-label-${String(index)}`;
58
- return (_jsxs("div", { className: cx(classes.groupLabelSection, 'mfui-BaseMainNavigation__groupLabelSection'), children: [_jsx("div", { className: cx(classes.groupLabel, 'mfui-BaseMainNavigation__groupLabel'), children: _jsx(Typography, { id: groupLabelId, variant: "condensedControlLabel", className: cx(classes.groupLabelText, 'mfui-BaseMainNavigation__groupLabelText'), children: navigation.label }) }), _jsx("ul", { "aria-labelledby": groupLabelId, className: cx(classes.childrenList, 'mfui-BaseMainNavigation__childrenList'), children: navigation.children.map((child, childIndex) => (_jsx("li", { className: cx(classes.childrenListItem, 'mfui-BaseMainNavigation__childrenListItem'), children: _jsx(FocusIndicator, { position: "inside", children: _jsx(NavigationLink, { tag: InternalLinkTag, isExternal: child.isExternal, href: child.href, className: cx(classes.listItemAnchor, 'mfui-BaseMainNavigation__listItemAnchor'), "aria-current": child.isCurrent ? 'page' : undefined, children: _jsxs("div", { className: cx(classes.labelGroup, 'mfui-BaseMainNavigation__labelGroup'), children: [_jsxs("div", { className: cx(classes.iconAndLabel, 'mfui-BaseMainNavigation__iconAndLabel'), children: [_jsx("div", { "aria-hidden": "true", className: cx(classes.listItemAnchorIcon, 'mfui-BaseMainNavigation__listItemAnchorIcon'), children: child.icon }), _jsx(Typography, { variant: "controlLabel", children: child.label })] }), child.locked ? (_jsx(Lock, { className: cx(classes.lockIcon, 'mfui-BaseMainNavigation__lockIcon'), "aria-label": child.lockIconProps?.['aria-label'] ?? 'ロックされています' })) : null, child.statusSlot && child.locked !== true ? child.statusSlot : null] }) }) }) }, childIndex))) })] }, index));
58
+ return (_jsxs("div", { className: cx(classes.groupLabelSection, 'mfui-BaseMainNavigation__groupLabelSection'), children: [_jsx("div", { className: cx(classes.groupLabel, 'mfui-BaseMainNavigation__groupLabel'), children: _jsx(Typography, { id: groupLabelId, variant: "condensedControlLabel", className: cx(classes.groupLabelText, 'mfui-BaseMainNavigation__groupLabelText'), children: navigation.label }) }), _jsx("ul", { "aria-labelledby": groupLabelId, className: cx(classes.childrenList, 'mfui-BaseMainNavigation__childrenList'), children: navigation.children.map((child, childIndex) => (_jsx("li", { className: cx(classes.childrenListItem, 'mfui-BaseMainNavigation__childrenListItem'), children: _jsx(FocusIndicator, { position: "inside", children: _jsx(NavigationLink, { tag: InternalLinkTag, isExternal: child.isExternal, href: child.href, className: cx(classes.listItemAnchor, 'mfui-BaseMainNavigation__listItemAnchor'), "aria-current": child.isCurrent ? 'page' : undefined, children: _jsxs("div", { className: cx(classes.labelGroup, 'mfui-BaseMainNavigation__labelGroup'), children: [_jsxs("div", { className: cx(classes.iconAndLabel, 'mfui-BaseMainNavigation__iconAndLabel'), children: [_jsx("div", { "aria-hidden": "true", className: cx(classes.listItemAnchorIcon, 'mfui-BaseMainNavigation__listItemAnchorIcon'), children: child.icon }), _jsx(Typography, { variant: "controlLabel", children: child.label })] }), child.locked ? (_jsx(Lock, { className: cx(classes.lockIcon, 'mfui-BaseMainNavigation__lockIcon'), role: "img", "aria-label": child.lockIconProps?.['aria-label'] ?? 'ロックされています' })) : null, child.statusSlot && child.locked !== true ? child.statusSlot : null] }) }) }) }, childIndex))) })] }, index));
59
59
  })] }), enableCollapsible ? (_jsx("div", { className: cx(classes.footer, 'mfui-BaseMainNavigation__footer'), children: _jsx(Tooltip, { content: toggleButtonLabel, placement: "right", children: _jsx(ToggleButton, { className: cx(classes.toggleButton, 'mfui-BaseMainNavigation__toggleButton'), iconClassName: cx(classes.toggleButtonIcon, 'mfui-BaseMainNavigation__toggleButtonIcon'), isCollapsed: isCollapsed, "aria-label": toggleButtonLabel, targetId: navId, handleClickToggleButton: handleClickToggleButton }) }) })) : null] }));
60
60
  }
61
61
  /**
@@ -54,13 +54,13 @@ export const NarrowViewportMainNavigation = forwardRef(({ className, featureShor
54
54
  return null;
55
55
  }
56
56
  return (_jsx("li", { className: cx(classes.listItem, 'mfui-NarrowViewportMainNavigation__listItem'), children: navigation.children ? (_jsxs("details", { open: ('isOpenByDefault' in navigation && navigation.isOpenByDefault) ||
57
- hasCurrentNavigationInChildren(navigation.children), className: cx(classes.parentDetails, 'mfui-NarrowViewportMainNavigation__parentDetails'), children: [_jsx(FocusIndicator, { position: "inside", children: _jsxs("summary", { className: cx(classes.parentSummary, 'mfui-NarrowViewportMainNavigation__parentSummary'), children: [_jsx("div", { "aria-hidden": "true", className: cx(classes.parentSummaryIcon, 'mfui-NarrowViewportMainNavigation__parentSummaryIcon'), children: navigation.icon }), _jsx(Typography, { variant: "controlLabel", children: navigation.label }), _jsx(DisclosureBasicCollapsed, { className: "mfui-NarrowViewportMainNavigation__icon_collapsed", "aria-hidden": "true", "data-mfui-content": "main-navigation-icon-collapsed" }), _jsx(DisclosureBasicExpanded, { className: "mfui-NarrowViewportMainNavigation__icon_expanded", "aria-hidden": "true", "data-mfui-content": "main-navigation-icon-expanded" })] }) }), _jsx("ul", { className: cx(classes.childrenList, 'mfui-NarrowViewportMainNavigation__childrenList'), children: navigation.children.map((child, childIndex) => (_jsx("li", { className: cx(classes.childrenListItem, 'mfui-NarrowViewportMainNavigation__childrenListItem'), children: _jsx(FocusIndicator, { position: "inside", children: _jsx(NavigationLink, { tag: InternalLinkTag, isExternal: child.isExternal, href: child.href, className: cx(classes.childrenListItemAnchor, 'mfui-NarrowViewportMainNavigation__childrenListItemAnchor'), "aria-current": child.isCurrent ? 'page' : undefined, onClick: handleCloseMainNavigation, children: _jsx(Typography, { variant: "controlLabel", children: child.label }) }) }) }, childIndex))) })] })) : (_jsx(FocusIndicator, { position: "inside", children: _jsx(NavigationLink, { tag: InternalLinkTag, isExternal: navigation.isExternal, href: navigation.href, className: cx(classes.listItemAnchor, 'mfui-NarrowViewportMainNavigation__listItemAnchor'), "aria-current": navigation.isCurrent ? 'page' : undefined, onClick: handleCloseMainNavigation, children: _jsxs("div", { className: cx(classes.labelGroup, 'mfui-NarrowViewportMainNavigation__labelGroup'), children: [_jsxs("div", { className: cx(classes.iconAndLabel, 'mfui-NarrowViewportMainNavigation__iconAndLabel'), children: [_jsx("div", { "aria-hidden": "true", className: cx(classes.listItemAnchorIcon, 'mfui-NarrowViewportMainNavigation__listItemAnchorIcon'), children: navigation.icon }), _jsx(Typography, { variant: "controlLabel", children: navigation.label })] }), navigation.locked ? (_jsx(Lock, { className: cx(classes.lockIcon, 'mfui-NarrowViewportMainNavigation__lockIcon'), "aria-label": navigation.lockIconProps?.['aria-label'] ?? 'ロックされています' })) : null] }) }) })) }, index));
57
+ hasCurrentNavigationInChildren(navigation.children), className: cx(classes.parentDetails, 'mfui-NarrowViewportMainNavigation__parentDetails'), children: [_jsx(FocusIndicator, { position: "inside", children: _jsxs("summary", { className: cx(classes.parentSummary, 'mfui-NarrowViewportMainNavigation__parentSummary'), children: [_jsx("div", { "aria-hidden": "true", className: cx(classes.parentSummaryIcon, 'mfui-NarrowViewportMainNavigation__parentSummaryIcon'), children: navigation.icon }), _jsx(Typography, { variant: "controlLabel", children: navigation.label }), _jsx(DisclosureBasicCollapsed, { className: "mfui-NarrowViewportMainNavigation__icon_collapsed", "aria-hidden": "true", "data-mfui-content": "main-navigation-icon-collapsed" }), _jsx(DisclosureBasicExpanded, { className: "mfui-NarrowViewportMainNavigation__icon_expanded", "aria-hidden": "true", "data-mfui-content": "main-navigation-icon-expanded" })] }) }), _jsx("ul", { className: cx(classes.childrenList, 'mfui-NarrowViewportMainNavigation__childrenList'), children: navigation.children.map((child, childIndex) => (_jsx("li", { className: cx(classes.childrenListItem, 'mfui-NarrowViewportMainNavigation__childrenListItem'), children: _jsx(FocusIndicator, { position: "inside", children: _jsx(NavigationLink, { tag: InternalLinkTag, isExternal: child.isExternal, href: child.href, className: cx(classes.childrenListItemAnchor, 'mfui-NarrowViewportMainNavigation__childrenListItemAnchor'), "aria-current": child.isCurrent ? 'page' : undefined, onClick: handleCloseMainNavigation, children: _jsx(Typography, { variant: "controlLabel", children: child.label }) }) }) }, childIndex))) })] })) : (_jsx(FocusIndicator, { position: "inside", children: _jsx(NavigationLink, { tag: InternalLinkTag, isExternal: navigation.isExternal, href: navigation.href, className: cx(classes.listItemAnchor, 'mfui-NarrowViewportMainNavigation__listItemAnchor'), "aria-current": navigation.isCurrent ? 'page' : undefined, onClick: handleCloseMainNavigation, children: _jsxs("div", { className: cx(classes.labelGroup, 'mfui-NarrowViewportMainNavigation__labelGroup'), children: [_jsxs("div", { className: cx(classes.iconAndLabel, 'mfui-NarrowViewportMainNavigation__iconAndLabel'), children: [_jsx("div", { "aria-hidden": "true", className: cx(classes.listItemAnchorIcon, 'mfui-NarrowViewportMainNavigation__listItemAnchorIcon'), children: navigation.icon }), _jsx(Typography, { variant: "controlLabel", children: navigation.label })] }), navigation.locked ? (_jsx(Lock, { className: cx(classes.lockIcon, 'mfui-NarrowViewportMainNavigation__lockIcon'), role: "img", "aria-label": navigation.lockIconProps?.['aria-label'] ?? 'ロックされています' })) : null] }) }) })) }, index));
58
58
  }) }), navigationItems.map((navigation, index) => {
59
59
  const isGroupLabel = navigation.children && 'isGroupLabel' in navigation && navigation.isGroupLabel;
60
60
  if (!isGroupLabel) {
61
61
  return null;
62
62
  }
63
63
  const groupLabelId = `${navId}-group-label-${String(index)}`;
64
- return (_jsxs("div", { className: cx(classes.groupLabelSection, 'mfui-NarrowViewportMainNavigation__groupLabelSection'), children: [_jsx("div", { className: cx(classes.groupLabel, 'mfui-NarrowViewportMainNavigation__groupLabel'), children: _jsx(Typography, { id: groupLabelId, variant: "condensedControlLabel", className: cx(classes.groupLabelText, 'mfui-NarrowViewportMainNavigation__groupLabelText'), children: navigation.label }) }), _jsx("ul", { "aria-labelledby": groupLabelId, className: cx(classes.childrenList, 'mfui-NarrowViewportMainNavigation__childrenList'), children: navigation.children.map((child, childIndex) => (_jsx("li", { className: cx(classes.childrenListItem, 'mfui-NarrowViewportMainNavigation__childrenListItem'), children: _jsx(FocusIndicator, { position: "inside", children: _jsx(NavigationLink, { tag: InternalLinkTag, isExternal: child.isExternal, href: child.href, className: cx(classes.listItemAnchor, 'mfui-NarrowViewportMainNavigation__listItemAnchor'), "aria-current": child.isCurrent ? 'page' : undefined, onClick: handleCloseMainNavigation, children: _jsxs("div", { className: cx(classes.labelGroup, 'mfui-NarrowViewportMainNavigation__labelGroup'), children: [_jsxs("div", { className: cx(classes.iconAndLabel, 'mfui-NarrowViewportMainNavigation__iconAndLabel'), children: [_jsx("div", { "aria-hidden": "true", className: cx(classes.listItemAnchorIcon, 'mfui-NarrowViewportMainNavigation__listItemAnchorIcon'), children: child.icon }), _jsx(Typography, { variant: "controlLabel", children: child.label })] }), child.locked ? (_jsx(Lock, { className: cx(classes.lockIcon, 'mfui-NarrowViewportMainNavigation__lockIcon'), "aria-label": child.lockIconProps?.['aria-label'] ?? 'ロックされています' })) : null, child.statusSlot && child.locked !== true ? child.statusSlot : null] }) }) }) }, childIndex))) })] }, index));
64
+ return (_jsxs("div", { className: cx(classes.groupLabelSection, 'mfui-NarrowViewportMainNavigation__groupLabelSection'), children: [_jsx("div", { className: cx(classes.groupLabel, 'mfui-NarrowViewportMainNavigation__groupLabel'), children: _jsx(Typography, { id: groupLabelId, variant: "condensedControlLabel", className: cx(classes.groupLabelText, 'mfui-NarrowViewportMainNavigation__groupLabelText'), children: navigation.label }) }), _jsx("ul", { "aria-labelledby": groupLabelId, className: cx(classes.childrenList, 'mfui-NarrowViewportMainNavigation__childrenList'), children: navigation.children.map((child, childIndex) => (_jsx("li", { className: cx(classes.childrenListItem, 'mfui-NarrowViewportMainNavigation__childrenListItem'), children: _jsx(FocusIndicator, { position: "inside", children: _jsx(NavigationLink, { tag: InternalLinkTag, isExternal: child.isExternal, href: child.href, className: cx(classes.listItemAnchor, 'mfui-NarrowViewportMainNavigation__listItemAnchor'), "aria-current": child.isCurrent ? 'page' : undefined, onClick: handleCloseMainNavigation, children: _jsxs("div", { className: cx(classes.labelGroup, 'mfui-NarrowViewportMainNavigation__labelGroup'), children: [_jsxs("div", { className: cx(classes.iconAndLabel, 'mfui-NarrowViewportMainNavigation__iconAndLabel'), children: [_jsx("div", { "aria-hidden": "true", className: cx(classes.listItemAnchorIcon, 'mfui-NarrowViewportMainNavigation__listItemAnchorIcon'), children: child.icon }), _jsx(Typography, { variant: "controlLabel", children: child.label })] }), child.locked ? (_jsx(Lock, { className: cx(classes.lockIcon, 'mfui-NarrowViewportMainNavigation__lockIcon'), role: "img", "aria-label": child.lockIconProps?.['aria-label'] ?? 'ロックされています' })) : null, child.statusSlot && child.locked !== true ? child.statusSlot : null] }) }) }) }, childIndex))) })] }, index));
65
65
  })] })] })] }) }));
66
66
  });
@@ -6,5 +6,13 @@
6
6
  *
7
7
  * @see Textarea
8
8
  */
9
- export { Textarea as MultilineTextBox } from '../Textarea';
10
- export type { TextareaProps as MultilineTextBoxProps } from '../Textarea';
9
+ export {
10
+ /**
11
+ * @deprecated Use `Textarea` instead. `MultilineTextBox` will be removed in v5.0.0.
12
+ */
13
+ Textarea as MultilineTextBox, } from '../Textarea';
14
+ export type {
15
+ /**
16
+ * @deprecated Use `TextareaProps` instead. `MultilineTextBoxProps` will be removed in v5.0.0.
17
+ */
18
+ TextareaProps as MultilineTextBoxProps, } from '../Textarea';
@@ -6,4 +6,8 @@
6
6
  *
7
7
  * @see Textarea
8
8
  */
9
- export { Textarea as MultilineTextBox } from '../Textarea';
9
+ export {
10
+ /**
11
+ * @deprecated Use `Textarea` instead. `MultilineTextBox` will be removed in v5.0.0.
12
+ */
13
+ Textarea as MultilineTextBox, } from '../Textarea';
@@ -25,7 +25,7 @@ export const SectionMessage = forwardRef(({ messageType = 'neutral', region = 'i
25
25
  // The status is conveyed by the message content itself, so the status icon is decorative
26
26
  // and hidden from assistive technology unless a label is explicitly provided.
27
27
  const statusIconLabel = statusIconProps?.['aria-label'];
28
- const statusIconA11yProps = statusIconLabel === undefined ? { 'aria-hidden': true } : { 'aria-label': statusIconLabel };
28
+ const statusIconA11yProps = statusIconLabel === undefined ? { 'aria-hidden': true } : { role: 'img', 'aria-label': statusIconLabel };
29
29
  const StatusIcon = {
30
30
  neutral: null,
31
31
  info: _jsx(Info, { ...statusIconA11yProps, className: cx(classes.statusIcon, 'mfui-SectionMessage__statusIcon') }),
@@ -33,7 +33,7 @@ export const SectionMessage = forwardRef(({ messageType = 'neutral', region = 'i
33
33
  error: _jsx(Error, { ...statusIconA11yProps, className: cx(classes.statusIcon, 'mfui-SectionMessage__statusIcon') }),
34
34
  caution: (_jsx(Caution, { ...statusIconA11yProps, className: cx(classes.statusIcon, 'mfui-SectionMessage__statusIcon') })),
35
35
  busy: _jsx(Pending, { ...statusIconA11yProps, className: cx(classes.statusIcon, 'mfui-SectionMessage__statusIcon') }),
36
- progress: (_jsx(ProgressIndicator, { role: "img", ...statusIconA11yProps, className: cx(classes.statusIcon, 'mfui-SectionMessage__statusIcon') })),
36
+ progress: (_jsx(ProgressIndicator, { ...statusIconA11yProps, className: cx(classes.statusIcon, 'mfui-SectionMessage__statusIcon') })),
37
37
  }[messageType];
38
38
  const contentIsString = typeof children === 'string';
39
39
  return (_jsxs("div", { ref: ref, className: cx(classes.root, 'mfui-SectionMessage__root', className), ...props, role: "alert", children: [_jsxs("div", { className: cx(classes.topSection, 'mfui-SectionMessage__topSection'), children: [_jsxs("div", { className: cx(classes.content, 'mfui-SectionMessage__content'), children: [StatusIcon, contentIsString ? _jsx(Typography, { variant: "body", children: children }) : children] }), _jsxs("div", { className: cx(classes.rightSection, 'mfui-SectionMessage__rightSection'), children: [_jsx("div", { className: cx(classes.actionSlot, classes.desktopActionSlot, 'mfui-SectionMessage__actionSlot'), "data-mfui-content": "SectionMessage-action-slot-desktop", children: actionSlot }), onClose ? (_jsx(IconButton, { "aria-label": closeButtonProps?.['aria-label'] ?? '閉じる', onClick: onClose, children: _jsx(Close, { "aria-hidden": true, className: cx(classes.closeIcon, 'mfui-SectionMessage__closeIcon') }) })) : null] })] }), actionSlot && !disableResponsive ? (_jsx("div", { className: cx(classes.actionSlot, classes.mobileActionSlot, 'mfui-SectionMessage__actionSlot'), "data-mfui-content": "SectionMessage-action-slot-mobile", children: actionSlot })) : null] }));
@@ -1,32 +1,14 @@
1
+ import { type SidePaneProps } from './SidePane.types';
1
2
  /**
2
3
  * The general purpose SidePane component.
3
4
  * This component extends the props of `<div>` element. The extended props and `ref` are
4
5
  * applied to the root overlay element covering the viewport, while `role="dialog"` (and
5
6
  * `aria-modal="true"` when `enableModal` is set) are set on the inner pane window element.
7
+ * The accessible name props (`title` / `aria-labelledby` / `aria-label`) are applied to the
8
+ * `role="dialog"` element, not the root overlay element.
6
9
  *
7
10
  * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dialog
8
11
  */
9
- export declare const SidePane: import("react").ForwardRefExoticComponent<{
10
- children?: import("react").ReactNode;
11
- title?: string;
12
- renderHeading?: (options: import("./SidePane.types").SidePaneRenderOptions) => import("react").ReactNode;
13
- actionSlot?: import("react").ReactNode;
14
- position?: import("../../styled-system/recipes").SidePaneSlotRecipeVariant['position'];
15
- closeButtonProps?: {
16
- isCollapseIcon?: boolean;
17
- } & Pick<import("react").ComponentPropsWithoutRef<'button'>, 'aria-label'>;
18
- targetDOMNode?: HTMLElement | null;
19
- enableModal?: boolean;
20
- disableBackdropClose?: boolean;
21
- enableAutoUnmount?: boolean;
22
- formFooterProps?: Pick<import("..").FormFooterProps, 'optionsSlot' | 'actionsSlot'> & {
23
- position?: import("..").FormFooterProps['position'];
24
- };
25
- insideProps?: {
26
- className?: string;
27
- };
28
- open?: boolean;
29
- onClose?: import("./SidePane.types").OnCloseFunction;
30
- } & Omit<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref">, "onClose" | "open"> & {
12
+ export declare const SidePane: import("react").ForwardRefExoticComponent<SidePaneProps & {
31
13
  ref?: (import("react").RefCallback<HTMLDivElement | null> | import("react").RefObject<HTMLDivElement | null> | null) | undefined;
32
14
  } & import("react").Attributes>;
@@ -1,6 +1,6 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { useCallback, useMemo, useState } from 'react';
3
+ import { useCallback, useId, useMemo, useState } from 'react';
4
4
  import { Close, PaneExpansionToRight, PaneExpansionToLeft } from '@moneyforward/mfui-icons-react';
5
5
  import { cx } from '../../styled-system/css';
6
6
  import { Heading } from '../Heading';
@@ -16,10 +16,12 @@ import { FormFooter } from '../FormFooter';
16
16
  * This component extends the props of `<div>` element. The extended props and `ref` are
17
17
  * applied to the root overlay element covering the viewport, while `role="dialog"` (and
18
18
  * `aria-modal="true"` when `enableModal` is set) are set on the inner pane window element.
19
+ * The accessible name props (`title` / `aria-labelledby` / `aria-label`) are applied to the
20
+ * `role="dialog"` element, not the root overlay element.
19
21
  *
20
22
  * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dialog
21
23
  */
22
- export const SidePane = compatibleForwardRef(({ open, title, renderHeading, onClose, className, children, actionSlot, formFooterProps, position = 'right', enableModal = false, enableAutoUnmount = true, disableBackdropClose = false, closeButtonProps, targetDOMNode, insideProps, ...props }, ref) => {
24
+ export const SidePane = compatibleForwardRef(({ open, title, 'aria-labelledby': ariaLabelledby, 'aria-label': ariaLabel, renderHeading, onClose, className, children, actionSlot, formFooterProps, position = 'right', enableModal = false, enableAutoUnmount = true, disableBackdropClose = false, closeButtonProps, targetDOMNode, insideProps, ...props }, ref) => {
23
25
  const classes = sidePaneSlotRecipe({ position, nonModal: !enableModal });
24
26
  const [insideElement, setInsideElement] = useState(null);
25
27
  const { localOpen, handleCloseSidePane, handleStopCloseSidePane, sidePaneElement, setSidePaneElement } = useSidePaneStateController({
@@ -59,9 +61,11 @@ export const SidePane = compatibleForwardRef(({ open, title, renderHeading, onCl
59
61
  const targetElement = useAutomaticTargetDomNode(targetDOMNode, sidePaneElement);
60
62
  const shouldRenderContent = enableAutoUnmount ? localOpen : true;
61
63
  const resolvedFormFooterPosition = formFooterProps?.position ?? 'sticky';
62
- const headingNode = title ? (_jsx(Heading, { variant: "pageHeading2", tag: "h2", children: title })) : null;
64
+ const id = useId();
65
+ const titleId = `mfui-sidepane-title-${id}`;
66
+ const headingNode = title ? (_jsx(Heading, { variant: "pageHeading2", tag: "h2", id: titleId, children: title })) : null;
63
67
  return (_jsx(TargetDomNodeProvider, { targetDomNode: sidePaneElement, children: shouldRenderContent ? (_jsx(Portal, { targetDOMNode: targetElement, children: _jsxs("div", { ref: setSidePaneElement, ...props, className: cx(classes.root, 'mfui-SidePane__root', className), style: {
64
68
  ...props.style,
65
69
  ...(!enableAutoUnmount && !localOpen && { display: 'none' }),
66
- }, onKeyDown: handleOnKeyDown, children: [enableModal ? (_jsx("div", { "data-mfui-content": "backdrop", className: cx(classes.backdrop, 'mfui-SidePane__backdrop'), onClick: handleBackdropClick })) : null, _jsxs("div", { ref: setInsideElement, role: "dialog", "aria-modal": enableModal ? 'true' : undefined, tabIndex: -1, "data-mfui-content": "inside", className: cx(classes.inside, 'mfui-SidePane__inside', insideProps?.className), onClick: handleStopCloseSidePane, children: [_jsxs("div", { className: cx(classes.header, 'mfui-SidePane__header'), children: [renderHeading ? (renderHeading({ headingNode })) : (_jsx("div", { className: cx(classes.title, 'mfui-SidePane__title'), children: headingNode })), _jsxs("div", { className: cx(classes.actionSlotWrapper, 'mfui-SidePane__actionSlotWrapper'), children: [!!actionSlot && (_jsx("div", { className: cx(classes.actionSlot, 'mfui-SidePane__actionSlot'), children: actionSlot })), _jsx("div", { className: cx(classes.closeButtonWrapper, 'mfui-SidePane__closeButtonWrapper'), children: _jsx(IconButton, { "aria-label": closeButtonProps?.['aria-label'] ?? '閉じる', onClick: handleCloseSidePane, children: closeButtonIcon }) })] })] }), _jsxs("div", { className: cx(classes.content, 'mfui-SidePane__content'), children: [_jsx("div", { className: cx(classes.contentBody, 'mfui-SidePane__contentBody'), children: children }), resolvedFormFooterPosition === 'stacking' ? (_jsx("div", { className: cx(classes.footer, 'mfui-SidePane__footer'), children: _jsx(FormFooter, { sectionPosition: "fill", ...formFooterProps, position: resolvedFormFooterPosition }) })) : null] }), formFooterProps && resolvedFormFooterPosition !== 'stacking' ? (_jsx("div", { className: cx(classes.footer, 'mfui-SidePane__footer'), children: _jsx(FormFooter, { sectionPosition: "fill", ...formFooterProps, position: resolvedFormFooterPosition }) })) : null] })] }) })) : null }));
70
+ }, onKeyDown: handleOnKeyDown, children: [enableModal ? (_jsx("div", { "data-mfui-content": "backdrop", className: cx(classes.backdrop, 'mfui-SidePane__backdrop'), onClick: handleBackdropClick })) : null, _jsxs("div", { ref: setInsideElement, role: "dialog", "aria-modal": enableModal ? 'true' : undefined, "aria-labelledby": ariaLabelledby ?? (title ? titleId : undefined), "aria-label": ariaLabel, tabIndex: -1, "data-mfui-content": "inside", className: cx(classes.inside, 'mfui-SidePane__inside', insideProps?.className), onClick: handleStopCloseSidePane, children: [_jsxs("div", { className: cx(classes.header, 'mfui-SidePane__header'), children: [renderHeading ? (renderHeading({ headingNode })) : (_jsx("div", { className: cx(classes.title, 'mfui-SidePane__title'), children: headingNode })), _jsxs("div", { className: cx(classes.actionSlotWrapper, 'mfui-SidePane__actionSlotWrapper'), children: [!!actionSlot && (_jsx("div", { className: cx(classes.actionSlot, 'mfui-SidePane__actionSlot'), children: actionSlot })), _jsx("div", { className: cx(classes.closeButtonWrapper, 'mfui-SidePane__closeButtonWrapper'), children: _jsx(IconButton, { "aria-label": closeButtonProps?.['aria-label'] ?? '閉じる', onClick: handleCloseSidePane, children: closeButtonIcon }) })] })] }), _jsxs("div", { className: cx(classes.content, 'mfui-SidePane__content'), children: [_jsx("div", { className: cx(classes.contentBody, 'mfui-SidePane__contentBody'), children: children }), resolvedFormFooterPosition === 'stacking' ? (_jsx("div", { className: cx(classes.footer, 'mfui-SidePane__footer'), children: _jsx(FormFooter, { sectionPosition: "fill", ...formFooterProps, position: resolvedFormFooterPosition }) })) : null] }), formFooterProps && resolvedFormFooterPosition !== 'stacking' ? (_jsx("div", { className: cx(classes.footer, 'mfui-SidePane__footer'), children: _jsx(FormFooter, { sectionPosition: "fill", ...formFooterProps, position: resolvedFormFooterPosition }) })) : null] })] }) })) : null }));
67
71
  });
@@ -10,28 +10,63 @@ export type SidePaneRenderOptions = {
10
10
  headingNode: ReactNode;
11
11
  };
12
12
  /**
13
- * SidePaneProps is a type that defines the properties for the SidePane component.
13
+ * Props that provide the accessible name of the side pane dialog.
14
+ * At least one of `title`, `aria-labelledby`, or `aria-label` is required so that
15
+ * the `role="dialog"` element always has an accessible name.
16
+ *
17
+ * When multiple props are provided, they are applied in this priority order:
18
+ * 1. `aria-labelledby` — an explicit reference always wins, so a custom visible heading
19
+ * rendered via `renderHeading` (without `headingNode`) can name the dialog even when
20
+ * `title` is also set. Put an `id` on the custom heading element and pass it here.
21
+ * 2. `title` — the generated `<h2>` heading is referenced by the dialog via `aria-labelledby`.
22
+ * 3. `aria-label` — use when the side pane has no visible heading.
23
+ */
24
+ export type SidePaneAccessibleNameProps = {
25
+ /**
26
+ * The heading title of the dialog.
27
+ * Rendered as an `<h2>` heading and referenced by the dialog element via `aria-labelledby`.
28
+ */
29
+ title: string;
30
+ 'aria-labelledby'?: string;
31
+ 'aria-label'?: string;
32
+ } | {
33
+ title?: string;
34
+ /**
35
+ * The id of the visible element that labels the dialog.
36
+ * Use this when rendering a custom heading via `renderHeading` without `headingNode`.
37
+ */
38
+ 'aria-labelledby': string;
39
+ 'aria-label'?: string;
40
+ } | {
41
+ title?: string;
42
+ 'aria-labelledby'?: string;
43
+ /**
44
+ * The accessible name of the dialog.
45
+ * Use this when the side pane has no visible heading.
46
+ */
47
+ 'aria-label': string;
48
+ };
49
+ /**
50
+ * SidePaneBaseProps is a type that defines the properties for the SidePane component,
51
+ * except for the accessible name props (see `SidePaneAccessibleNameProps`).
14
52
  *
15
53
  * It includes:
16
- * - `title`: The heading title of the dialog.
17
54
  * - `isOpen` and `onClose`: These props are conditionally required based on whether the component is controlled or uncontrolled.
18
55
  * - If `isOpen` is defined, `onClose` is required (controlled component).
19
56
  * - If `isOpen` is undefined, `onClose` is optional (uncontrolled component).
20
57
  * - Additional props from `ComponentPropsWithoutRef<'div'>` are also included.
21
58
  */
22
- export type SidePaneProps = {
59
+ export type SidePaneBaseProps = {
23
60
  /**
24
61
  * The main content of the side pane.
25
62
  */
26
63
  children?: ReactNode;
27
- /**
28
- * The heading title of the dialog.
29
- */
30
- title?: string;
31
64
  /**
32
65
  * Custom render function for the heading area.
33
66
  * Provides the original headingNode wrapped in <h2> tag for flexible layout composition.
34
67
  * When provided, this takes precedence over the default title rendering.
68
+ * If the custom layout does not render `headingNode`, provide `aria-labelledby` or
69
+ * `aria-label` instead of `title` so the dialog keeps its accessible name.
35
70
  *
36
71
  * @param options - Contains the headingNode for layout composition
37
72
  *
@@ -143,4 +178,11 @@ export type SidePaneProps = {
143
178
  * This prop is required when using the side pane as a controlled component.
144
179
  */
145
180
  onClose?: OnCloseFunction;
146
- } & Omit<ComponentPropsWithoutRef<'div'>, 'open' | 'onClose'>;
181
+ } & Omit<ComponentPropsWithoutRef<'div'>, 'open' | 'onClose' | 'title' | 'aria-label' | 'aria-labelledby'>;
182
+ /**
183
+ * SidePaneProps is a type that defines the properties for the SidePane component.
184
+ *
185
+ * It requires at least one of `title`, `aria-labelledby`, or `aria-label`
186
+ * so that the dialog always has an accessible name (see `SidePaneAccessibleNameProps`).
187
+ */
188
+ export type SidePaneProps = SidePaneBaseProps & SidePaneAccessibleNameProps;
@@ -1,2 +1,2 @@
1
1
  export { SidePane } from './SidePane';
2
- export { type SidePaneProps } from './SidePane.types';
2
+ export { type SidePaneProps, type SidePaneBaseProps, type SidePaneAccessibleNameProps } from './SidePane.types';
@@ -10,8 +10,6 @@ declare function SidebarBase({ className, logoSlot, mainNavigationItems, extraNa
10
10
  * A navigation layout component that combines a logo header, a navigation area,
11
11
  * and a footer with icon menu and user information.
12
12
  *
13
- * **EXPERIMENTAL**: This component is experimental and may be changed or removed in the future.
14
- *
15
13
  * The width is resizable via the drag handle on the right edge. See the `WidthPersistence` story for
16
14
  * an example of persisting the width across reloads via `onWidthChange` and `defaultWidth`.
17
15
  *
@@ -51,8 +51,6 @@ function SidebarToggleButton({ isCollapsed, ariaLabel, navId, onClick, }) {
51
51
  * A navigation layout component that combines a logo header, a navigation area,
52
52
  * and a footer with icon menu and user information.
53
53
  *
54
- * **EXPERIMENTAL**: This component is experimental and may be changed or removed in the future.
55
- *
56
54
  * The width is resizable via the drag handle on the right edge. See the `WidthPersistence` story for
57
55
  * an example of persisting the width across reloads via `onWidthChange` and `defaultWidth`.
58
56
  *
@@ -39,7 +39,7 @@ const renderNavigationItem = (navigationItem, customLinkComponent, classes, nest
39
39
  }
40
40
  if (href) {
41
41
  // The the parent item will be rendered as a link with separated disclosure icon button.
42
- return (_jsxs(_Fragment, { children: [_jsx(NavigationLink, { navigationItem: navigationItem, customLinkComponent: customLinkComponent, classes: classes, renderNavigationLabel: renderNavigationLabel }), _jsx(NestedNavigationList, { summarySlot: _jsx("div", { "data-mfui-content": "sub-navigation-disclosure-icon", className: cx(classes.disclosureIcon, 'mfui-SubNavigation__disclosureIcon'), children: _jsx(DisclosureBasicCollapsed, { "aria-label": label }) }), nestedNavigationItems: children, customLinkComponent: customLinkComponent, classes: classes, nestLevel: nestLevel + 1, renderNavigationLabel: renderNavigationLabel })] }));
42
+ return (_jsxs(_Fragment, { children: [_jsx(NavigationLink, { navigationItem: navigationItem, customLinkComponent: customLinkComponent, classes: classes, renderNavigationLabel: renderNavigationLabel }), _jsx(NestedNavigationList, { summarySlot: _jsx("div", { "data-mfui-content": "sub-navigation-disclosure-icon", className: cx(classes.disclosureIcon, 'mfui-SubNavigation__disclosureIcon'), children: _jsx(DisclosureBasicCollapsed, { role: "img", "aria-label": label }) }), nestedNavigationItems: children, customLinkComponent: customLinkComponent, classes: classes, nestLevel: nestLevel + 1, renderNavigationLabel: renderNavigationLabel })] }));
43
43
  }
44
44
  // The the parent item will be rendered as a disclosure button with an icon.
45
45
  return (_jsx(NestedNavigationList, { summarySlot: _jsxs(_Fragment, { children: [_jsx(NavigationLabelGroup, { label, labelIcon, locked, lockIconProps, statusSlot, classes, renderNavigationLabel }), _jsx("div", { "data-mfui-content": "sub-navigation-disclosure-icon", className: cx(classes.disclosureIcon, 'mfui-SubNavigation__disclosureIcon'), children: _jsx(DisclosureBasicCollapsed, { "aria-hidden": "true" }) })] }), nestedNavigationItems: children, customLinkComponent: customLinkComponent, classes: classes, nestLevel: nestLevel + 1, renderNavigationLabel: renderNavigationLabel }));
@@ -52,7 +52,7 @@ function NavigationLabelGroup({ label, labelIcon, locked, lockIconProps, statusS
52
52
  // If locked=true, display <Lock /> icon in preference to any other status of the statusSlot option.
53
53
  const renderStatus = () => {
54
54
  if (locked) {
55
- return (_jsx("div", { className: cx(classes.statusSlot, 'mfui-SubNavigation__statusSlot'), children: _jsx(Lock, { "aria-label": lockIconProps?.['aria-label'] ?? 'ロックされています' }) }));
55
+ return (_jsx("div", { className: cx(classes.statusSlot, 'mfui-SubNavigation__statusSlot'), children: _jsx(Lock, { role: "img", "aria-label": lockIconProps?.['aria-label'] ?? 'ロックされています' }) }));
56
56
  }
57
57
  if (statusSlot) {
58
58
  return _jsx("div", { className: cx(classes.statusSlot, 'mfui-SubNavigation__statusSlot'), children: statusSlot });
@@ -14,5 +14,5 @@ import { textLinkSlotRecipe } from '../../styled-system/recipes';
14
14
  export const TextLink = forwardRef(({ children, variant = 'inherit', className, customLinkComponent, showExternalIcon, externalIconProps, ...rest }, ref) => {
15
15
  const classes = textLinkSlotRecipe({ variant });
16
16
  const Tag = customLinkComponent ?? 'a';
17
- return (_jsx(FocusIndicator, { children: _jsxs(Tag, { ...rest, ref: ref, className: cx(classes.root, 'mfui-TextLink__root', className), children: [children, showExternalIcon ? (_jsx("span", { className: cx(classes.externalLinkIconContainer, 'mfui-TextLink__externalLinkIconContainer'), children: _jsx(ExternalLink, { className: cx(classes.externalLinkIcon, 'mfui-TextLink__externalLinkIcon'), "aria-label": externalIconProps ?? '別のタブで開きます' }) })) : null] }) }));
17
+ return (_jsx(FocusIndicator, { children: _jsxs(Tag, { ...rest, ref: ref, className: cx(classes.root, 'mfui-TextLink__root', className), children: [children, showExternalIcon ? (_jsx("span", { className: cx(classes.externalLinkIconContainer, 'mfui-TextLink__externalLinkIconContainer'), children: _jsx(ExternalLink, { className: cx(classes.externalLinkIcon, 'mfui-TextLink__externalLinkIcon'), role: "img", "aria-label": externalIconProps ?? '別のタブで開きます' }) })) : null] }) }));
18
18
  });
@@ -21,7 +21,7 @@ export const Toast = forwardRef(({ className, type = 'success', actionSlot, mess
21
21
  // The status is conveyed by the message content itself, so the status icon is decorative
22
22
  // and hidden from assistive technology unless a label is explicitly provided.
23
23
  const statusIconLabel = statusIconProps?.['aria-label'];
24
- const statusIconA11yProps = statusIconLabel === undefined ? { 'aria-hidden': true } : { 'aria-label': statusIconLabel };
24
+ const statusIconA11yProps = statusIconLabel === undefined ? { 'aria-hidden': true } : { role: 'img', 'aria-label': statusIconLabel };
25
25
  const icon = (() => {
26
26
  if (type === 'success') {
27
27
  return _jsx(Approval, { ...statusIconA11yProps });
@@ -8,6 +8,7 @@ export * from './CheckboxGroup';
8
8
  export * from './DataGrid';
9
9
  export * from './DataTable';
10
10
  export * from './DateTimeSelection';
11
+ export * from './DecoratedKeyValueList';
11
12
  export * from './DeterminateProgressIndicator';
12
13
  export * from './Dialog';
13
14
  export * from './Disclosure';
package/dist/src/index.js CHANGED
@@ -8,6 +8,7 @@ export * from './CheckboxGroup';
8
8
  export * from './DataGrid';
9
9
  export * from './DataTable';
10
10
  export * from './DateTimeSelection';
11
+ export * from './DecoratedKeyValueList';
11
12
  export * from './DeterminateProgressIndicator';
12
13
  export * from './Dialog';
13
14
  export * from './Disclosure';
@@ -5,6 +5,7 @@ import type { DistributiveOmit, Pretty } from '../types/system-types';
5
5
  interface DataTableCellSlotRecipeVariant {
6
6
  size: "small" | "medium"
7
7
  isCheckboxCell: boolean
8
+ isCheckboxCellInteractive: boolean
8
9
  rowHighlighted: boolean
9
10
  fixedColumn: boolean
10
11
  verticalBorder: boolean
@@ -4,6 +4,7 @@ const dataTableCellSlotRecipeDefaultVariants = {};
4
4
  const dataTableCellSlotRecipeCompoundVariants = [
5
5
  {
6
6
  "isCheckboxCell": true,
7
+ "isCheckboxCellInteractive": true,
7
8
  "rowHighlighted": true,
8
9
  "css": {
9
10
  "defaultCell": {
@@ -74,6 +75,7 @@ const dataTableCellSlotRecipeFn = memo((props = {}) => {
74
75
  const dataTableCellSlotRecipeVariantKeys = [
75
76
  "size",
76
77
  "isCheckboxCell",
78
+ "isCheckboxCellInteractive",
77
79
  "rowHighlighted",
78
80
  "fixedColumn",
79
81
  "verticalBorder",
@@ -97,6 +99,9 @@ export const dataTableCellSlotRecipe = /* @__PURE__ */ Object.assign(dataTableCe
97
99
  "isCheckboxCell": [
98
100
  "true"
99
101
  ],
102
+ "isCheckboxCellInteractive": [
103
+ "true"
104
+ ],
100
105
  "rowHighlighted": [
101
106
  "true"
102
107
  ],
@@ -6,6 +6,7 @@ interface DataTableRowSlotRecipeVariant {
6
6
  layout: "default" | "edge-to-edge"
7
7
  highlighted: boolean
8
8
  interactive: boolean
9
+ rowClickSelectable: boolean
9
10
  disabled: boolean
10
11
  }
11
12
 
@@ -13,7 +14,7 @@ type DataTableRowSlotRecipeVariantMap = {
13
14
  [key in keyof DataTableRowSlotRecipeVariant]: Array<DataTableRowSlotRecipeVariant[key]>
14
15
  }
15
16
 
16
- type DataTableRowSlotRecipeSlot = "root"
17
+ type DataTableRowSlotRecipeSlot = "root" | "selectionCheckbox"
17
18
 
18
19
  export type DataTableRowSlotRecipeVariantProps = {
19
20
  [key in keyof DataTableRowSlotRecipeVariant]?: DataTableRowSlotRecipeVariant[key] | undefined
@@ -33,6 +33,10 @@ const dataTableRowSlotRecipeSlotNames = [
33
33
  [
34
34
  "root",
35
35
  "DataTableRow__root"
36
+ ],
37
+ [
38
+ "selectionCheckbox",
39
+ "DataTableRow__selectionCheckbox"
36
40
  ]
37
41
  ];
38
42
  const dataTableRowSlotRecipeSlotFns = /* @__PURE__ */ dataTableRowSlotRecipeSlotNames.map(([slotName, slotKey]) => [slotName, createRecipe(slotKey, dataTableRowSlotRecipeDefaultVariants, getSlotCompoundVariant(dataTableRowSlotRecipeCompoundVariants, slotName))]);
@@ -43,6 +47,7 @@ const dataTableRowSlotRecipeVariantKeys = [
43
47
  "layout",
44
48
  "highlighted",
45
49
  "interactive",
50
+ "rowClickSelectable",
46
51
  "disabled"
47
52
  ];
48
53
  const getVariantProps = (variants) => ({ ...dataTableRowSlotRecipeDefaultVariants, ...compact(variants) });
@@ -65,6 +70,10 @@ export const dataTableRowSlotRecipe = /* @__PURE__ */ Object.assign(dataTableRow
65
70
  "true",
66
71
  "false"
67
72
  ],
73
+ "rowClickSelectable": [
74
+ "true",
75
+ "false"
76
+ ],
68
77
  "disabled": [
69
78
  "true",
70
79
  "false"
@@ -0,0 +1,33 @@
1
+ /* eslint-disable */
2
+ import type { ConditionalValue } from '../types/index';
3
+ import type { DistributiveOmit, Pretty } from '../types/system-types';
4
+
5
+ interface DecoratedKeyValueListItemSlotRecipeVariant {
6
+
7
+ }
8
+
9
+ type DecoratedKeyValueListItemSlotRecipeVariantMap = {
10
+ [key in keyof DecoratedKeyValueListItemSlotRecipeVariant]: Array<DecoratedKeyValueListItemSlotRecipeVariant[key]>
11
+ }
12
+
13
+ type DecoratedKeyValueListItemSlotRecipeSlot = "root" | "keyItem" | "valueGroup" | "valueItem"
14
+
15
+ export type DecoratedKeyValueListItemSlotRecipeVariantProps = {
16
+ [key in keyof DecoratedKeyValueListItemSlotRecipeVariant]?: ConditionalValue<DecoratedKeyValueListItemSlotRecipeVariant[key]> | undefined
17
+ }
18
+
19
+ export interface DecoratedKeyValueListItemSlotRecipeRecipe {
20
+ __slot: DecoratedKeyValueListItemSlotRecipeSlot
21
+ __type: DecoratedKeyValueListItemSlotRecipeVariantProps
22
+ (props?: DecoratedKeyValueListItemSlotRecipeVariantProps): Pretty<Record<DecoratedKeyValueListItemSlotRecipeSlot, string>>
23
+ raw: (props?: DecoratedKeyValueListItemSlotRecipeVariantProps) => DecoratedKeyValueListItemSlotRecipeVariantProps
24
+ variantMap: DecoratedKeyValueListItemSlotRecipeVariantMap
25
+ variantKeys: Array<keyof DecoratedKeyValueListItemSlotRecipeVariant>
26
+ splitVariantProps<Props extends DecoratedKeyValueListItemSlotRecipeVariantProps>(props: Props): [DecoratedKeyValueListItemSlotRecipeVariantProps, Pretty<DistributiveOmit<Props, keyof DecoratedKeyValueListItemSlotRecipeVariantProps>>]
27
+ getVariantProps: (props?: DecoratedKeyValueListItemSlotRecipeVariantProps) => DecoratedKeyValueListItemSlotRecipeVariantProps
28
+ }
29
+
30
+ /**
31
+ * Slot class created for the MFUI DecoratedKeyValueListItem component.
32
+ */
33
+ export declare const decoratedKeyValueListItemSlotRecipe: DecoratedKeyValueListItemSlotRecipeRecipe