@moneyforward/mfui-components 3.28.1 → 3.29.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/Accordion/Accordion.js +1 -1
- package/dist/src/DataTable/DataTableCell/DataTableCell.js +1 -1
- package/dist/src/DataTable/DataTableCell/DataTableCell.types.d.ts +8 -0
- package/dist/src/DataTable/DataTableRow/DataTableRow.js +7 -1
- package/dist/src/DateTimeSelection/FilterDatePicker/CalendarPopover/CalendarPopover.d.ts +1 -1
- package/dist/src/DateTimeSelection/FilterDatePicker/CalendarPopover/CalendarPopover.js +2 -2
- package/dist/src/DateTimeSelection/FilterDatePicker/CalendarPopover/CalendarPopover.types.d.ts +1 -0
- package/dist/src/DateTimeSelection/FilterDatePicker/FilterDatePicker.d.ts +1 -1
- package/dist/src/DateTimeSelection/FilterDatePicker/FilterDatePicker.js +2 -2
- package/dist/src/DateTimeSelection/FilterDatePicker/FilterDatePicker.types.d.ts +7 -1
- package/dist/src/DateTimeSelection/FilterDateRangePicker/DateRangePickerContent/DateRangePickerContent.d.ts +1 -1
- package/dist/src/DateTimeSelection/FilterDateRangePicker/DateRangePickerContent/DateRangePickerContent.js +2 -2
- package/dist/src/DateTimeSelection/FilterDateRangePicker/DateRangePickerContent/DateRangePickerContent.types.d.ts +1 -0
- package/dist/src/DateTimeSelection/FilterDateRangePicker/FilterDateRangePicker.d.ts +1 -1
- package/dist/src/DateTimeSelection/FilterDateRangePicker/FilterDateRangePicker.js +2 -2
- package/dist/src/DateTimeSelection/FilterDateRangePicker/FilterDateRangePicker.types.d.ts +7 -1
- package/dist/src/DateTimeSelection/FilterMonthPicker/FilterMonthPicker.d.ts +1 -1
- package/dist/src/DateTimeSelection/FilterMonthPicker/FilterMonthPicker.js +2 -2
- package/dist/src/DateTimeSelection/FilterMonthPicker/FilterMonthPicker.types.d.ts +7 -1
- package/dist/src/DateTimeSelection/FilterMonthPicker/MonthPickerPopover/MonthPickerPopover.d.ts +1 -1
- package/dist/src/DateTimeSelection/FilterMonthPicker/MonthPickerPopover/MonthPickerPopover.js +2 -2
- package/dist/src/DateTimeSelection/FilterMonthPicker/MonthPickerPopover/MonthPickerPopover.types.d.ts +1 -0
- package/dist/src/DateTimeSelection/FilterMonthRangePicker/FilterMonthRangePicker.d.ts +1 -1
- package/dist/src/DateTimeSelection/FilterMonthRangePicker/FilterMonthRangePicker.js +2 -2
- package/dist/src/DateTimeSelection/FilterMonthRangePicker/FilterMonthRangePicker.types.d.ts +7 -1
- package/dist/src/DateTimeSelection/FilterMonthRangePicker/MonthRangePickerPopover/MonthRangePickerPopover.d.ts +1 -1
- package/dist/src/DateTimeSelection/FilterMonthRangePicker/MonthRangePickerPopover/MonthRangePickerPopover.js +2 -2
- package/dist/src/DateTimeSelection/FilterMonthRangePicker/MonthRangePickerPopover/MonthRangePickerPopover.types.d.ts +1 -0
- package/dist/src/DateTimeSelection/MonthRangePicker/MonthRangePickerMonthCell/MonthRangePickerMonthCell.js +1 -1
- package/dist/src/DateTimeSelection/TimePicker/TimePicker.d.ts +2 -0
- package/dist/src/DateTimeSelection/TimePicker/TimePicker.js +2 -2
- package/dist/src/DateTimeSelection/TimePicker/TimePicker.types.d.ts +6 -0
- package/dist/src/DateTimeSelection/shared/BaseRangePicker/BaseRangePickerPopover/BaseRangePickerCalendar/BaseRangePickerDateCell.js +1 -1
- package/dist/src/DateTimeSelection/shared/DayCell/DayCell.js +2 -2
- package/dist/src/DateTimeSelection/shared/accessibility/getDateAriaAttributes.d.ts +0 -1
- package/dist/src/DateTimeSelection/shared/accessibility/getDateAriaAttributes.js +0 -1
- package/dist/src/Dialog/Dialog.d.ts +3 -1
- package/dist/src/Dialog/Dialog.js +8 -4
- package/dist/src/Dialog/hooks/useDialogStateController.d.ts +5 -1
- package/dist/src/Dialog/hooks/useDialogStateController.js +7 -4
- package/dist/src/Disclosure/Disclosure.js +1 -1
- package/dist/src/MultipleSelectBox/MultipleSelectBox.js +5 -4
- package/dist/src/MultipleSelectBox/MultipleSelectBox.types.d.ts +13 -2
- package/dist/src/MultipleSelectBox/hooks/useInitialFocusOnOptionPanelOpen.js +3 -6
- package/dist/src/MultipleSelectBox/utils/getDeepActiveElement.d.ts +11 -0
- package/dist/src/MultipleSelectBox/utils/getDeepActiveElement.js +17 -0
- package/dist/src/SearchBox/SearchBox.d.ts +3 -0
- package/dist/src/SearchBox/SearchBox.js +3 -0
- package/dist/src/SelectBox/SelectBox.js +9 -6
- package/dist/src/SelectBox/SelectBox.types.d.ts +13 -2
- package/dist/styled-system/recipes/day-cell-slot-recipe.d.ts +1 -1
- package/dist/styled-system/recipes/day-cell-slot-recipe.js +4 -0
- package/dist/styled-system/tokens/index.js +60 -0
- package/dist/styled-system/tokens/tokens.d.ts +2 -2
- package/dist/styled-system/types/prop-type.d.ts +1 -1
- package/dist/styles.css +19 -5
- package/dist/theme-orange.css +18 -3
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +2 -2
|
@@ -4,6 +4,7 @@ type UseDialogStateControllerOptions = {
|
|
|
4
4
|
onClose?: () => void;
|
|
5
5
|
forwardedRef: ForwardedRef<HTMLDivElement | null>;
|
|
6
6
|
customFocusElement?: RefObject<HTMLElement | null> | HTMLElement | null;
|
|
7
|
+
insideElement?: HTMLElement | null;
|
|
7
8
|
};
|
|
8
9
|
/**
|
|
9
10
|
* Custom hook to control the open/close state of a dialog.
|
|
@@ -23,9 +24,12 @@ type UseDialogStateControllerOptions = {
|
|
|
23
24
|
* @param options.customFocusElement - Optional custom element to focus when the dialog opens.
|
|
24
25
|
* When provided, this element receives focus instead of the dialog container.
|
|
25
26
|
*
|
|
27
|
+
* @param options.insideElement - The dialog window element with `role="dialog"`. It receives
|
|
28
|
+
* default focus when the dialog opens, keeping focus inside the `aria-modal` boundary.
|
|
29
|
+
*
|
|
26
30
|
* @returns Object containing functions to handle closing the dialog and stopping the dialog from closing.
|
|
27
31
|
*/
|
|
28
|
-
export declare const useDialogStateController: ({ open, forwardedRef, onClose, customFocusElement, }: UseDialogStateControllerOptions) => {
|
|
32
|
+
export declare const useDialogStateController: ({ open, forwardedRef, onClose, customFocusElement, insideElement, }: UseDialogStateControllerOptions) => {
|
|
29
33
|
localOpen: boolean | undefined;
|
|
30
34
|
closeDialog: () => void;
|
|
31
35
|
handleStopCloseDialog: (event: React.MouseEvent<HTMLDivElement>) => void;
|
|
@@ -19,9 +19,12 @@ import { useUpdateEffect } from '../../utilities/effect/useUpdateEffect';
|
|
|
19
19
|
* @param options.customFocusElement - Optional custom element to focus when the dialog opens.
|
|
20
20
|
* When provided, this element receives focus instead of the dialog container.
|
|
21
21
|
*
|
|
22
|
+
* @param options.insideElement - The dialog window element with `role="dialog"`. It receives
|
|
23
|
+
* default focus when the dialog opens, keeping focus inside the `aria-modal` boundary.
|
|
24
|
+
*
|
|
22
25
|
* @returns Object containing functions to handle closing the dialog and stopping the dialog from closing.
|
|
23
26
|
*/
|
|
24
|
-
export const useDialogStateController = ({ open, forwardedRef, onClose, customFocusElement, }) => {
|
|
27
|
+
export const useDialogStateController = ({ open, forwardedRef, onClose, customFocusElement, insideElement, }) => {
|
|
25
28
|
const [dialogElement, setDialogElement] = useState(null);
|
|
26
29
|
const [localOpen, setLocalOpen] = useState(open);
|
|
27
30
|
// Whenever the `open` prop changes, update the local state.
|
|
@@ -67,9 +70,9 @@ export const useDialogStateController = ({ open, forwardedRef, onClose, customFo
|
|
|
67
70
|
customFocusElement.focus();
|
|
68
71
|
return;
|
|
69
72
|
}
|
|
70
|
-
// Default behavior: focus the dialog
|
|
71
|
-
dialogElement?.focus();
|
|
72
|
-
}, [localOpen, dialogElement, customFocusElement]);
|
|
73
|
+
// Default behavior: focus the dialog window (`role="dialog"` element)
|
|
74
|
+
(insideElement ?? dialogElement)?.focus();
|
|
75
|
+
}, [localOpen, dialogElement, insideElement, customFocusElement]);
|
|
73
76
|
return {
|
|
74
77
|
localOpen,
|
|
75
78
|
closeDialog,
|
|
@@ -47,7 +47,7 @@ const Trigger = forwardRef(({ targetId, children, className, onClick, ...props }
|
|
|
47
47
|
toggle();
|
|
48
48
|
onClick?.(event);
|
|
49
49
|
}, [onClick, toggle]);
|
|
50
|
-
return (_jsx(FocusIndicator, { children: _jsxs("button", { ref: ref, className: cx(classes.trigger, 'mfui-Disclosure__trigger', className), "aria-expanded": isOpen, "aria-controls": targetId, onClick: handleClick, ...props, children: [_jsx(Typography, { variant: "controlLabel", children: children }), isOpen ? _jsx(DisclosureBasicExpanded, { "aria-hidden": "true" }) : _jsx(DisclosureBasicCollapsed, { "aria-hidden": "true" })] }) }));
|
|
50
|
+
return (_jsx(FocusIndicator, { children: _jsxs("button", { ref: ref, className: cx(classes.trigger, 'mfui-Disclosure__trigger', className), "aria-expanded": isOpen, "aria-controls": targetId, type: "button", onClick: handleClick, ...props, children: [_jsx(Typography, { variant: "controlLabel", children: children }), isOpen ? _jsx(DisclosureBasicExpanded, { "aria-hidden": "true" }) : _jsx(DisclosureBasicCollapsed, { "aria-hidden": "true" })] }) }));
|
|
51
51
|
});
|
|
52
52
|
/**
|
|
53
53
|
* The target component for the Disclosure.
|
|
@@ -315,13 +315,14 @@ placeholder, emptyMessage, disabled, invalid, targetDOMNode, name, onChange, val
|
|
|
315
315
|
]);
|
|
316
316
|
// Render infinite scroll loading indicator
|
|
317
317
|
const renderInfiniteScrollLoading = useCallback(() => isInfiniteScrollLoading && enableInfiniteScroll ? (_jsx("div", { className: cx(classes.infiniteScrollLoading, 'mfui-MultipleSelectBox__infiniteScrollLoading'), children: _jsx(ProgressIndicator, {}) })) : null, [isInfiniteScrollLoading, enableInfiniteScroll, classes.infiniteScrollLoading]);
|
|
318
|
-
const searchNode = enableSearchOptions ? (_jsx(SearchBox, { ref: searchInputRef, enableClearButton: true, value: searchText, textBoxSize: "small", autoComplete: "off", onChange: onSearchTextChange, ...searchBoxProps })) : null;
|
|
318
|
+
const searchNode = enableSearchOptions ? (_jsx(SearchBox, { ref: searchInputRef, enableClearButton: true, value: searchText, textBoxSize: "small", autoComplete: "off", "aria-label": "\u691C\u7D22\u3059\u308B", onChange: onSearchTextChange, ...searchBoxProps })) : null;
|
|
319
319
|
const allOptionsControlsNode = enableAllOptionsControls ? (_jsxs(HStack, { justifyContent: "space-between", children: [_jsx(Button, { ref: selectAllButtonRef, size: "small", onClick: handleSelectAll, children: selectAllButtonProps?.label ?? 'すべて選択' }), _jsx(Button, { ref: clearAllButtonRef, size: "small", onClick: handleClearAll, children: clearAllButtonProps?.label ?? 'すべて解除' })] })) : null;
|
|
320
320
|
const selectedCountNode = enableApplyControls || showSelectedCount ? (_jsx(Typography, { variant: "body", color: "neutral.600", children: enableApplyControls
|
|
321
321
|
? (selectedCountProps?.render?.(temporaryValues.size) ?? `${String(temporaryValues.size)}件選択中`)
|
|
322
322
|
: (selectedCountProps?.render?.(localSelectedValuesSet.size) ??
|
|
323
323
|
`${String(localSelectedValuesSet.size)}件選択中`) })) : null;
|
|
324
324
|
const applyControlsNode = enableApplyControls ? (_jsxs(HStack, { gap: "horizontal.0-1of2", children: [_jsx(Button, { ref: cancelButtonRef, size: "small", priority: "secondary", onClick: handleCancelButtonClick, children: cancelButtonProps?.label ?? 'キャンセル' }), _jsx(Button, { ref: applyButtonRef, size: "small", priority: "primary", onClick: handleApplyButtonClick, children: applyButtonProps?.label ?? '適用' })] })) : null;
|
|
325
|
+
const resolvedNotFoundMessage = typeof notFoundMessage === 'function' ? notFoundMessage(searchText.trim()) : notFoundMessage;
|
|
325
326
|
const optionsNode = (_jsxs("div", { ref: scrollWrapperRef, className: cx(classes.scrollWrapper, 'mfui-MultipleSelectBox__scrollWrapper'), onScroll: enableInfiniteScroll ? handleInfiniteScroll : undefined, children: [_jsx("ul", { ref: listBoxRef, role: "listbox", id: listBoxId, className: cx(classes.listBox, 'mfui-MultipleSelectBox__listBox'), tabIndex: -1, style: isVirtualized && totalSize > 0
|
|
326
327
|
? {
|
|
327
328
|
height: `${String(totalSize)}px`,
|
|
@@ -338,10 +339,10 @@ placeholder, emptyMessage, disabled, invalid, targetDOMNode, name, onChange, val
|
|
|
338
339
|
!isVirtualized && renderInfiniteScrollError(),
|
|
339
340
|
].filter(Boolean)
|
|
340
341
|
: [
|
|
341
|
-
_jsx("li", { className: cx(classes.emptyMessage, 'mfui-MultipleSelectBox__emptyMessage'), children: _jsx(Typography, { variant: "body", children: enableSearchOptions && searchText &&
|
|
342
|
-
?
|
|
342
|
+
_jsx("li", { className: cx(classes.emptyMessage, 'mfui-MultipleSelectBox__emptyMessage'), children: _jsx(Typography, { variant: "body", children: enableSearchOptions && searchText && resolvedNotFoundMessage
|
|
343
|
+
? resolvedNotFoundMessage
|
|
343
344
|
: options.length > 0
|
|
344
|
-
?
|
|
345
|
+
? resolvedNotFoundMessage
|
|
345
346
|
: emptyMessage }) }, "empty"),
|
|
346
347
|
!isVirtualized && renderInfiniteScrollError(),
|
|
347
348
|
].filter(Boolean) }), isVirtualized ? renderInfiniteScrollLoading() : null, isVirtualized ? renderInfiniteScrollError('div') : null] }));
|
|
@@ -398,12 +398,23 @@ export type MultipleSelectBoxProps<T extends AllowedValueTypes = string, Additio
|
|
|
398
398
|
enableSearchOptions?: boolean;
|
|
399
399
|
/**
|
|
400
400
|
* The message to be displayed when the options are not found.
|
|
401
|
+
*
|
|
402
|
+
* Pass a function to include the current search text in the message,
|
|
403
|
+
* as recommended by the design guidelines.
|
|
404
|
+
*
|
|
405
|
+
* @example
|
|
406
|
+
* ```tsx
|
|
407
|
+
* <MultipleSelectBox notFoundMessage={(searchText) => `${searchText}を含むオプションがありません。`} />
|
|
408
|
+
* ```
|
|
401
409
|
*/
|
|
402
|
-
notFoundMessage?: string;
|
|
410
|
+
notFoundMessage?: string | ((searchText: string) => React.ReactNode);
|
|
403
411
|
/**
|
|
404
412
|
* The properties for the SearchBox component.
|
|
413
|
+
*
|
|
414
|
+
* Pass `aria-label` to override the search input's default
|
|
415
|
+
* accessible name (`検索する`).
|
|
405
416
|
*/
|
|
406
|
-
searchBoxProps?: Pick<SearchBoxProps, 'clearButtonProps' | 'placeholder' | 'invalid'>;
|
|
417
|
+
searchBoxProps?: Pick<SearchBoxProps, 'clearButtonProps' | 'placeholder' | 'invalid' | 'aria-label'>;
|
|
407
418
|
/**
|
|
408
419
|
* The properties for the option panel element.
|
|
409
420
|
*
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { useEffect } from 'react';
|
|
2
|
+
import { getDeepActiveElement } from '../utils/getDeepActiveElement';
|
|
2
3
|
import { isSelectableOption } from '../utils/isSelectableOption';
|
|
3
4
|
/**
|
|
4
5
|
* Control the focus when the option panel is opened.
|
|
@@ -9,7 +10,7 @@ export const useInitialFocusOnOptionPanelOpen = ({ isOptionPanelOpen, selectAllB
|
|
|
9
10
|
if (!isOptionPanelOpen)
|
|
10
11
|
return;
|
|
11
12
|
// Check if the active element is one of the all options control buttons
|
|
12
|
-
const
|
|
13
|
+
const activeElement = getDeepActiveElement();
|
|
13
14
|
// If an all options control button is focused, don't change focus
|
|
14
15
|
if (activeElement === selectAllButtonRef.current || activeElement === clearAllButtonRef.current) {
|
|
15
16
|
return;
|
|
@@ -17,7 +18,7 @@ export const useInitialFocusOnOptionPanelOpen = ({ isOptionPanelOpen, selectAllB
|
|
|
17
18
|
// Focus the search input when the select is searchable and the value is empty.
|
|
18
19
|
if (enableSearchOptions) {
|
|
19
20
|
// If it is already focused, return.
|
|
20
|
-
if (searchInputRef.current ===
|
|
21
|
+
if (searchInputRef.current === activeElement)
|
|
21
22
|
return;
|
|
22
23
|
// Otherwise, focus the search input
|
|
23
24
|
if (localSelectedValuesSet.size === 0) {
|
|
@@ -57,10 +58,6 @@ export const useInitialFocusOnOptionPanelOpen = ({ isOptionPanelOpen, selectAllB
|
|
|
57
58
|
if (focusIndexInOptions === -1)
|
|
58
59
|
focusIndexInOptions = 0;
|
|
59
60
|
}
|
|
60
|
-
else {
|
|
61
|
-
// Default to the first focusable option
|
|
62
|
-
focusIndexInOptions = 0;
|
|
63
|
-
}
|
|
64
61
|
const optionNode = optionPanelRef.current?.querySelectorAll('[role="option"][data-focusable="true"]');
|
|
65
62
|
if (optionNode && optionNode.length > 0) {
|
|
66
63
|
optionNode[focusIndexInOptions]?.focus({ preventScroll: true });
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns the truly focused element, traversing into shadow roots recursively.
|
|
3
|
+
*
|
|
4
|
+
* `document.activeElement` stops at the shadow host when focus is inside a Shadow DOM.
|
|
5
|
+
* This function follows the chain of `shadowRoot.activeElement` until the deepest focused element is found.
|
|
6
|
+
*
|
|
7
|
+
* @param root - The root to start from (defaults to `document`)
|
|
8
|
+
*
|
|
9
|
+
* @returns The deepest active element, or `null` if nothing is focused
|
|
10
|
+
*/
|
|
11
|
+
export declare const getDeepActiveElement: (root?: Document | ShadowRoot) => Element | null;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns the truly focused element, traversing into shadow roots recursively.
|
|
3
|
+
*
|
|
4
|
+
* `document.activeElement` stops at the shadow host when focus is inside a Shadow DOM.
|
|
5
|
+
* This function follows the chain of `shadowRoot.activeElement` until the deepest focused element is found.
|
|
6
|
+
*
|
|
7
|
+
* @param root - The root to start from (defaults to `document`)
|
|
8
|
+
*
|
|
9
|
+
* @returns The deepest active element, or `null` if nothing is focused
|
|
10
|
+
*/
|
|
11
|
+
export const getDeepActiveElement = (root = document) => {
|
|
12
|
+
const active = root.activeElement;
|
|
13
|
+
if (active?.shadowRoot) {
|
|
14
|
+
return getDeepActiveElement(active.shadowRoot) ?? active;
|
|
15
|
+
}
|
|
16
|
+
return active;
|
|
17
|
+
};
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The component wrapped the TextBox component with Search icon.
|
|
3
3
|
* Some props in the TextBox component are not supported.
|
|
4
|
+
*
|
|
5
|
+
* The input has no default accessible name. Provide one with `aria-label`
|
|
6
|
+
* or associate an external label with `aria-labelledby`.
|
|
4
7
|
*/
|
|
5
8
|
export declare const SearchBox: import("react").ForwardRefExoticComponent<Omit<import("..").TextBoxProps, "prefixSlot" | "suffixSlot"> & {
|
|
6
9
|
normalizeFullWidth?: boolean;
|
|
@@ -7,6 +7,9 @@ import { normalizeFullWidth } from '../utilities/string/normalizeFullWidth';
|
|
|
7
7
|
/**
|
|
8
8
|
* The component wrapped the TextBox component with Search icon.
|
|
9
9
|
* Some props in the TextBox component are not supported.
|
|
10
|
+
*
|
|
11
|
+
* The input has no default accessible name. Provide one with `aria-label`
|
|
12
|
+
* or associate an external label with `aria-labelledby`.
|
|
10
13
|
*/
|
|
11
14
|
export const SearchBox = forwardRef(({ className, normalizeFullWidth: shouldNormalizeFullWidth = false, onChange, ...rest }, ref) => {
|
|
12
15
|
const handleChange = useCallback((event) => {
|
|
@@ -208,7 +208,7 @@ export const SelectBox = forwardRef((props, ref) => {
|
|
|
208
208
|
}
|
|
209
209
|
return (_jsx(Typography, { variant: "controlLabel", className: cx(classes.placeholder, 'mfui-SelectBox__placeholder'), children: placeholder }));
|
|
210
210
|
};
|
|
211
|
-
const searchNode = enableSearchOptions ? (_jsx("div", { className: cx(classes.menuHeader, 'mfui-SelectBox__menuHeader'), children: _jsx(SearchBox, { ref: searchInputRef, enableClearButton: true, value: searchText, textBoxSize: "small", autoComplete: "off", onChange: onSearchTextChange, ...searchBoxProps }) })) : null;
|
|
211
|
+
const searchNode = enableSearchOptions ? (_jsx("div", { className: cx(classes.menuHeader, 'mfui-SelectBox__menuHeader'), children: _jsx(SearchBox, { ref: searchInputRef, enableClearButton: true, value: searchText, textBoxSize: "small", autoComplete: "off", "aria-label": "\u691C\u7D22\u3059\u308B", onChange: onSearchTextChange, ...searchBoxProps }) })) : null;
|
|
212
212
|
// Render virtualized items - extracted for better maintainability
|
|
213
213
|
const renderVirtualizedItems = useCallback(() => virtualItems.map((virtualItem) => {
|
|
214
214
|
const virtualizedItem = virtualizedItems[virtualItem.index];
|
|
@@ -278,11 +278,14 @@ export const SelectBox = forwardRef((props, ref) => {
|
|
|
278
278
|
createKeyDownHandler,
|
|
279
279
|
]);
|
|
280
280
|
// Render empty message - extracted for better maintainability
|
|
281
|
-
const renderEmptyMessage = useCallback(() =>
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
?
|
|
285
|
-
:
|
|
281
|
+
const renderEmptyMessage = useCallback(() => {
|
|
282
|
+
const resolvedNotFoundMessage = typeof notFoundMessage === 'function' ? notFoundMessage(searchText.trim()) : notFoundMessage;
|
|
283
|
+
return (_jsx("li", { className: cx(classes.emptyMessage, 'mfui-SelectBox__emptyMessage'), children: _jsx(Typography, { variant: "body", children: enableSearchOptions && searchText && resolvedNotFoundMessage
|
|
284
|
+
? resolvedNotFoundMessage
|
|
285
|
+
: options.length > 0
|
|
286
|
+
? resolvedNotFoundMessage
|
|
287
|
+
: emptyMessage }) }, "empty-message"));
|
|
288
|
+
}, [classes.emptyMessage, enableSearchOptions, searchText, notFoundMessage, options.length, emptyMessage]);
|
|
286
289
|
// Render infinite scroll error message with retry button
|
|
287
290
|
const renderInfiniteScrollError = useCallback((as = 'li') => {
|
|
288
291
|
if (!infiniteScrollError)
|
|
@@ -334,12 +334,23 @@ export type SelectBoxProps<T extends AllowedValueTypes = string, AdditionalProps
|
|
|
334
334
|
enableSearchOptions?: boolean;
|
|
335
335
|
/**
|
|
336
336
|
* The message to be displayed when the options are not found.
|
|
337
|
+
*
|
|
338
|
+
* Pass a function to include the current search text in the message,
|
|
339
|
+
* as recommended by the design guidelines.
|
|
340
|
+
*
|
|
341
|
+
* @example
|
|
342
|
+
* ```tsx
|
|
343
|
+
* <SelectBox notFoundMessage={(searchText) => `${searchText}を含むオプションがありません。`} />
|
|
344
|
+
* ```
|
|
337
345
|
*/
|
|
338
|
-
notFoundMessage?: string;
|
|
346
|
+
notFoundMessage?: string | ((searchText: string) => React.ReactNode);
|
|
339
347
|
/**
|
|
340
348
|
* The properties for the SearchBox component.
|
|
349
|
+
*
|
|
350
|
+
* Pass `aria-label` to override the search input's default
|
|
351
|
+
* accessible name (`検索する`).
|
|
341
352
|
*/
|
|
342
|
-
searchBoxProps?: Pick<SearchBoxProps, 'clearButtonProps' | 'placeholder'>;
|
|
353
|
+
searchBoxProps?: Pick<SearchBoxProps, 'clearButtonProps' | 'placeholder' | 'aria-label'>;
|
|
343
354
|
/**
|
|
344
355
|
* Flag to indicate loading state of the options.
|
|
345
356
|
* When true, the SelectBox will display skeleton placeholders
|
|
@@ -10,7 +10,7 @@ type DayCellSlotRecipeVariantMap = {
|
|
|
10
10
|
[key in keyof DayCellSlotRecipeVariant]: Array<DayCellSlotRecipeVariant[key]>
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
type DayCellSlotRecipeSlot = "root" | "label"
|
|
13
|
+
type DayCellSlotRecipeSlot = "root" | "label" | "srOnlyLabel"
|
|
14
14
|
|
|
15
15
|
export type DayCellSlotRecipeVariantProps = {
|
|
16
16
|
[key in keyof DayCellSlotRecipeVariant]?: ConditionalValue<DayCellSlotRecipeVariant[key]> | undefined
|
|
@@ -10,6 +10,10 @@ const dayCellSlotRecipeSlotNames = [
|
|
|
10
10
|
[
|
|
11
11
|
"label",
|
|
12
12
|
"DayCell__label"
|
|
13
|
+
],
|
|
14
|
+
[
|
|
15
|
+
"srOnlyLabel",
|
|
16
|
+
"DayCell__srOnlyLabel"
|
|
13
17
|
]
|
|
14
18
|
];
|
|
15
19
|
const dayCellSlotRecipeSlotFns = /* @__PURE__ */ dayCellSlotRecipeSlotNames.map(([slotName, slotKey]) => [slotName, createRecipe(slotKey, dayCellSlotRecipeDefaultVariants, getSlotCompoundVariant(dayCellSlotRecipeCompoundVariants, slotName))]);
|
|
@@ -6083,6 +6083,18 @@ const tokens = {
|
|
|
6083
6083
|
"value": "#bad4f7ff",
|
|
6084
6084
|
"variable": "var(--mfui-colors-mfui\\.color\\.primary\\.sub-background\\.pressed)"
|
|
6085
6085
|
},
|
|
6086
|
+
"colors.mfui.color.primary.text-on-sub-background.none": {
|
|
6087
|
+
"value": "#165cb7ff",
|
|
6088
|
+
"variable": "var(--mfui-colors-mfui\\.color\\.primary\\.text-on-sub-background\\.none)"
|
|
6089
|
+
},
|
|
6090
|
+
"colors.mfui.color.primary.text-on-sub-background.hovered": {
|
|
6091
|
+
"value": "#004396ff",
|
|
6092
|
+
"variable": "var(--mfui-colors-mfui\\.color\\.primary\\.text-on-sub-background\\.hovered)"
|
|
6093
|
+
},
|
|
6094
|
+
"colors.mfui.color.primary.text-on-sub-background.pressed": {
|
|
6095
|
+
"value": "#072977ff",
|
|
6096
|
+
"variable": "var(--mfui-colors-mfui\\.color\\.primary\\.text-on-sub-background\\.pressed)"
|
|
6097
|
+
},
|
|
6086
6098
|
"colors.mfui.color.readonly.content": {
|
|
6087
6099
|
"value": "#262626ff",
|
|
6088
6100
|
"variable": "var(--mfui-colors-mfui\\.color\\.readonly\\.content)"
|
|
@@ -6179,6 +6191,18 @@ const tokens = {
|
|
|
6179
6191
|
"value": "#003e90ff",
|
|
6180
6192
|
"variable": "var(--mfui-colors-mfui\\.color\\.selected\\.border\\.pressed)"
|
|
6181
6193
|
},
|
|
6194
|
+
"colors.mfui.color.selected.text-on-background.none": {
|
|
6195
|
+
"value": "#165cb7ff",
|
|
6196
|
+
"variable": "var(--mfui-colors-mfui\\.color\\.selected\\.text-on-background\\.none)"
|
|
6197
|
+
},
|
|
6198
|
+
"colors.mfui.color.selected.text-on-background.hovered": {
|
|
6199
|
+
"value": "#004396ff",
|
|
6200
|
+
"variable": "var(--mfui-colors-mfui\\.color\\.selected\\.text-on-background\\.hovered)"
|
|
6201
|
+
},
|
|
6202
|
+
"colors.mfui.color.selected.text-on-background.pressed": {
|
|
6203
|
+
"value": "#072977ff",
|
|
6204
|
+
"variable": "var(--mfui-colors-mfui\\.color\\.selected\\.text-on-background\\.pressed)"
|
|
6205
|
+
},
|
|
6182
6206
|
"colors.mfui.color.shadow.elevation-plus-1-shadow-1.none": {
|
|
6183
6207
|
"value": "#00000033",
|
|
6184
6208
|
"variable": "var(--mfui-colors-mfui\\.color\\.shadow\\.elevation-plus-1-shadow-1\\.none)"
|
|
@@ -6243,6 +6267,18 @@ const tokens = {
|
|
|
6243
6267
|
"value": "#9ee1afff",
|
|
6244
6268
|
"variable": "var(--mfui-colors-mfui\\.color\\.signal-green\\.sub-background\\.pressed)"
|
|
6245
6269
|
},
|
|
6270
|
+
"colors.mfui.color.signal-green.text-on-sub-background.none": {
|
|
6271
|
+
"value": "#006d36ff",
|
|
6272
|
+
"variable": "var(--mfui-colors-mfui\\.color\\.signal-green\\.text-on-sub-background\\.none)"
|
|
6273
|
+
},
|
|
6274
|
+
"colors.mfui.color.signal-green.text-on-sub-background.hovered": {
|
|
6275
|
+
"value": "#005227ff",
|
|
6276
|
+
"variable": "var(--mfui-colors-mfui\\.color\\.signal-green\\.text-on-sub-background\\.hovered)"
|
|
6277
|
+
},
|
|
6278
|
+
"colors.mfui.color.signal-green.text-on-sub-background.pressed": {
|
|
6279
|
+
"value": "#003919ff",
|
|
6280
|
+
"variable": "var(--mfui-colors-mfui\\.color\\.signal-green\\.text-on-sub-background\\.pressed)"
|
|
6281
|
+
},
|
|
6246
6282
|
"colors.mfui.color.signal-neutral.sub-background.none": {
|
|
6247
6283
|
"value": "#f3f3f3ff",
|
|
6248
6284
|
"variable": "var(--mfui-colors-mfui\\.color\\.signal-neutral\\.sub-background\\.none)"
|
|
@@ -6303,6 +6339,18 @@ const tokens = {
|
|
|
6303
6339
|
"value": "#ffc3baff",
|
|
6304
6340
|
"variable": "var(--mfui-colors-mfui\\.color\\.signal-red\\.sub-background\\.pressed)"
|
|
6305
6341
|
},
|
|
6342
|
+
"colors.mfui.color.signal-red.text-on-sub-background.none": {
|
|
6343
|
+
"value": "#ba1828ff",
|
|
6344
|
+
"variable": "var(--mfui-colors-mfui\\.color\\.signal-red\\.text-on-sub-background\\.none)"
|
|
6345
|
+
},
|
|
6346
|
+
"colors.mfui.color.signal-red.text-on-sub-background.hovered": {
|
|
6347
|
+
"value": "#93001aff",
|
|
6348
|
+
"variable": "var(--mfui-colors-mfui\\.color\\.signal-red\\.text-on-sub-background\\.hovered)"
|
|
6349
|
+
},
|
|
6350
|
+
"colors.mfui.color.signal-red.text-on-sub-background.pressed": {
|
|
6351
|
+
"value": "#68000fff",
|
|
6352
|
+
"variable": "var(--mfui-colors-mfui\\.color\\.signal-red\\.text-on-sub-background\\.pressed)"
|
|
6353
|
+
},
|
|
6306
6354
|
"colors.mfui.color.signal-yellow.content.none": {
|
|
6307
6355
|
"value": "#8b7200ff",
|
|
6308
6356
|
"variable": "var(--mfui-colors-mfui\\.color\\.signal-yellow\\.content\\.none)"
|
|
@@ -6351,6 +6399,18 @@ const tokens = {
|
|
|
6351
6399
|
"value": "#eecf79ff",
|
|
6352
6400
|
"variable": "var(--mfui-colors-mfui\\.color\\.signal-yellow\\.sub-background\\.pressed)"
|
|
6353
6401
|
},
|
|
6402
|
+
"colors.mfui.color.signal-yellow.text-on-sub-background.none": {
|
|
6403
|
+
"value": "#775a01ff",
|
|
6404
|
+
"variable": "var(--mfui-colors-mfui\\.color\\.signal-yellow\\.text-on-sub-background\\.none)"
|
|
6405
|
+
},
|
|
6406
|
+
"colors.mfui.color.signal-yellow.text-on-sub-background.hovered": {
|
|
6407
|
+
"value": "#604100ff",
|
|
6408
|
+
"variable": "var(--mfui-colors-mfui\\.color\\.signal-yellow\\.text-on-sub-background\\.hovered)"
|
|
6409
|
+
},
|
|
6410
|
+
"colors.mfui.color.signal-yellow.text-on-sub-background.pressed": {
|
|
6411
|
+
"value": "#462a00ff",
|
|
6412
|
+
"variable": "var(--mfui-colors-mfui\\.color\\.signal-yellow\\.text-on-sub-background\\.pressed)"
|
|
6413
|
+
},
|
|
6354
6414
|
"shadows.mfui.elevation.plus-1.shadow-1": {
|
|
6355
6415
|
"value": "0px 1px 1px 1px #00000033",
|
|
6356
6416
|
"variable": "var(--mfui-shadows-mfui\\.elevation\\.plus-1\\.shadow-1)"
|