@moneyforward/mfui-components 3.33.0 → 3.35.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/FileDropZone/FileDropZone.d.ts +1 -1
- package/dist/src/FileDropZone/FileDropZone.js +4 -2
- package/dist/src/FileDropZone/FileDropZone.types.d.ts +5 -3
- package/dist/src/IconButton/IconButton.d.ts +2 -0
- package/dist/src/IconButton/IconButton.js +2 -2
- package/dist/src/IconButton/IconButton.types.d.ts +7 -0
- package/dist/src/MultipleSelectBox/MultipleSelectBox.types.d.ts +4 -0
- package/dist/src/MultipleSelectBox/hooks/useSearchBox.js +14 -3
- package/dist/src/SectionMessage/SectionMessage.js +2 -1
- package/dist/src/SelectBox/SelectBox.js +8 -1
- package/dist/src/SelectBox/SelectBox.types.d.ts +7 -0
- package/dist/src/SelectBox/hooks/useSearchBox.d.ts +6 -1
- package/dist/src/SelectBox/hooks/useSearchBox.js +23 -4
- package/dist/src/SplitView/SplitView.js +16 -2
- package/dist/src/Tabs/TabList/TabList.d.ts +1 -1
- package/dist/src/Tabs/TabList/TabList.js +2 -2
- package/dist/src/Tabs/TabPanel/TabPanel.d.ts +1 -1
- package/dist/src/Tabs/TabPanel/TabPanel.js +2 -2
- package/dist/src/Tabs/Tabs.d.ts +1 -1
- package/dist/src/Tabs/Tabs.js +2 -2
- package/dist/styled-system/recipes/file-drop-zone-slot-recipe.d.ts +1 -1
- package/dist/styled-system/recipes/file-drop-zone-slot-recipe.js +4 -0
- package/dist/styled-system/recipes/icon-button-slot-recipe.d.ts +2 -1
- package/dist/styled-system/recipes/icon-button-slot-recipe.js +33 -2
- package/dist/styled-system/recipes/section-message-slot-recipe.d.ts +1 -1
- package/dist/styled-system/recipes/section-message-slot-recipe.js +1 -0
- package/dist/styles.css +40 -6
- package/package.json +3 -3
|
@@ -33,7 +33,7 @@ export declare const FileDropZone: import("react").ForwardRefExoticComponent<{
|
|
|
33
33
|
multiple?: import("react").ComponentPropsWithoutRef<'input'>['multiple'];
|
|
34
34
|
accept?: import("react").ComponentPropsWithoutRef<'input'>['accept'];
|
|
35
35
|
clearButtonProps?: Pick<import("..").IconButtonProps, 'aria-label'>;
|
|
36
|
-
errorMessage?: string;
|
|
36
|
+
errorMessage?: string | string[];
|
|
37
37
|
helperMessage?: string;
|
|
38
38
|
illustrationUrl?: string;
|
|
39
39
|
extraElement?: React.ReactNode;
|
|
@@ -70,6 +70,8 @@ fileSelectButtonLabel = 'ファイルを選択', instructionText, fileCountLabel
|
|
|
70
70
|
const previousValueRef = useRef(value);
|
|
71
71
|
const isUserInitiatedClearRef = useRef(false);
|
|
72
72
|
const displayValues = isControlled ? value : internalValues;
|
|
73
|
+
const errorMessages = (Array.isArray(errorMessage) ? errorMessage : [errorMessage]).filter((message) => Boolean(message));
|
|
74
|
+
const fileBoxMaxWidthStyle = { maxWidth: fileBoxWidth };
|
|
73
75
|
const isNarrowViewport = useIsNarrowViewport();
|
|
74
76
|
const clearButtonWidth = isNarrowViewport ? 32 : 24;
|
|
75
77
|
const truncatedSingleName = useMiddleTruncatedText(displayValues?.[0] ?? '', fileNameRef, clearButtonWidth);
|
|
@@ -206,9 +208,9 @@ fileSelectButtonLabel = 'ファイルを選択', instructionText, fileCountLabel
|
|
|
206
208
|
}
|
|
207
209
|
return '';
|
|
208
210
|
}, [displayValues, truncatedSingleName, classes.span, getFileCountText]);
|
|
209
|
-
return (_jsxs("div", { className: cx(classes.root, 'mfui-FileDropZone__root'), children: [_jsx("input", { ref: mergeRefs(ref, inputRef), id: id, type: "file", disabled: disabled, multiple: multiple, accept: accept, className: cx(classes.input, 'mfui-FileDropZone__input'), tabIndex: -1, "aria-hidden": "true", onChange: handleChange, onDragEnter: handleDragEnter, onDragLeave: handleDragLeave, onDrop: handleDrop, ...props }, key), _jsxs("div", { "data-mfui-content": "file-drop-zone-container", className: cx(classes.container, 'mfui-FileDropZone__container', className), style: style, onClick: handleContainerClick, onDragEnter: handleDragEnter, onDragLeave: handleDragLeave, onDragOver: handleDragOver, onDrop: handleDrop, children: [illustrationUrl ? (_jsx("div", { "data-mfui-content": "file-drop-zone-illustration", className: cx(classes.illustration, 'mfui-FileDropZone__illustration'), children: _jsx("img", { src: illustrationUrl, alt: "illustration" }) })) : null, _jsxs("div", { "data-mfui-content": "file-drop-zone-main-container", className: cx(classes.mainContainer, 'mfui-FileDropZone__mainContainer'),
|
|
211
|
+
return (_jsxs("div", { className: cx(classes.root, 'mfui-FileDropZone__root'), children: [_jsx("input", { ref: mergeRefs(ref, inputRef), id: id, type: "file", disabled: disabled, multiple: multiple, accept: accept, className: cx(classes.input, 'mfui-FileDropZone__input'), tabIndex: -1, "aria-hidden": "true", onChange: handleChange, onDragEnter: handleDragEnter, onDragLeave: handleDragLeave, onDrop: handleDrop, ...props }, key), _jsxs("div", { "data-mfui-content": "file-drop-zone-container", className: cx(classes.container, 'mfui-FileDropZone__container', className), style: style, onClick: handleContainerClick, onDragEnter: handleDragEnter, onDragLeave: handleDragLeave, onDragOver: handleDragOver, onDrop: handleDrop, children: [illustrationUrl ? (_jsx("div", { "data-mfui-content": "file-drop-zone-illustration", className: cx(classes.illustration, 'mfui-FileDropZone__illustration'), children: _jsx("img", { src: illustrationUrl, alt: "illustration" }) })) : null, _jsxs("div", { "data-mfui-content": "file-drop-zone-main-container", className: cx(classes.mainContainer, 'mfui-FileDropZone__mainContainer'), children: [_jsx("div", { "data-mfui-content": "file-drop-zone-instruction", className: cx(classes.instruction, 'mfui-FileDropZone__instruction'), style: fileBoxMaxWidthStyle, children: _jsx("p", { className: cx(classes.phrase, 'mfui-FileDropZone__phrase'), children: normalizedInstructionText }) }), _jsxs("div", { "data-mfui-content": "file-drop-zone-button-container", className: cx(classes.buttonContainer, 'mfui-FileDropZone__buttonContainer'), style: fileBoxMaxWidthStyle, children: [_jsx(Button, { ref: buttonRef, className: cx(classes.button, 'mfui-FileDropZone__button'), disabled: disabled, "aria-describedby": errorMessages.length > 0 || helperMessage || (displayValues && displayValues.length > 0)
|
|
210
212
|
? `${id ? `${id}-` : ''}file-drop-zone-messages`
|
|
211
|
-
: undefined, onClick: handleFileInputTrigger, children: fileSelectButtonLabel }), displayValues !== undefined && displayValues.length > 0 && (_jsxs("div", { "data-mfui-content": "file-drop-zone-file-info", className: cx(classes.fileInfo, 'mfui-FileDropZone__fileInfo'), style: { maxWidth: `${(fileInfoWidth || 147).toString()}px` }, children: [renderDisplayValues, _jsx(ClearButton, { ...clearButtonProps, "aria-label": clearButtonProps?.['aria-label'] ?? 'ファイルをクリアする', className: cx(classes.clearButton, 'mfui-FileDropZone__clearButton'), disabled: disabled, onClick: handleClear })] }))] }), _jsxs("div", { id: id ? `${id}-file-drop-zone-messages` : 'file-drop-zone-messages', "data-mfui-content": "file-drop-zone-help-message", className: cx(classes.helpMessage, 'mfui-FileDropZone__helpMessage'), children: [
|
|
213
|
+
: undefined, onClick: handleFileInputTrigger, children: fileSelectButtonLabel }), displayValues !== undefined && displayValues.length > 0 && (_jsxs("div", { "data-mfui-content": "file-drop-zone-file-info", className: cx(classes.fileInfo, 'mfui-FileDropZone__fileInfo'), style: { maxWidth: `${(fileInfoWidth || 147).toString()}px` }, children: [renderDisplayValues, _jsx(ClearButton, { ...clearButtonProps, "aria-label": clearButtonProps?.['aria-label'] ?? 'ファイルをクリアする', className: cx(classes.clearButton, 'mfui-FileDropZone__clearButton'), disabled: disabled, onClick: handleClear })] }))] }), _jsxs("div", { id: id ? `${id}-file-drop-zone-messages` : 'file-drop-zone-messages', "data-mfui-content": "file-drop-zone-help-message", className: cx(classes.helpMessage, 'mfui-FileDropZone__helpMessage'), children: [errorMessages.length > 0 ? (_jsx("div", { role: "alert", "data-mfui-content": "file-drop-zone-error-messages", className: cx(classes.errorMessages, 'mfui-FileDropZone__errorMessages'), children: errorMessages.map((message, index) => (_jsx(HelpMessage, { role: undefined, messageType: "error", messageAlign: "center", children: message }, index))) })) : null, helperMessage ? _jsx(HelpMessage, { messageAlign: "center", children: helperMessage }) : null, displayValues && displayValues.length > 0 ? (_jsx("div", { className: "sr-only", children: displayValues.length === 1
|
|
212
214
|
? getScreenReaderText('single', displayValues[0] || '')
|
|
213
215
|
: getScreenReaderText('multiple', displayValues.length) })) : null] })] }), extraElement ? (_jsx("div", { "data-mfui-content": "file-drop-zone-extra", className: cx(classes.extra, 'mfui-FileDropZone__extra'), children: extraElement })) : null] })] }));
|
|
214
216
|
});
|
|
@@ -41,11 +41,12 @@ export type FileDropZoneProps = {
|
|
|
41
41
|
*/
|
|
42
42
|
clearButtonProps?: Pick<IconButtonProps, 'aria-label'>;
|
|
43
43
|
/**
|
|
44
|
-
* The error message for the file drop zone.
|
|
44
|
+
* The error message or messages for the file drop zone.
|
|
45
|
+
* Empty strings are not rendered.
|
|
45
46
|
*
|
|
46
47
|
* @default undefined
|
|
47
48
|
*/
|
|
48
|
-
errorMessage?: string;
|
|
49
|
+
errorMessage?: string | string[];
|
|
49
50
|
/**
|
|
50
51
|
* The helper message for the file drop zone.
|
|
51
52
|
*
|
|
@@ -117,7 +118,8 @@ export type FileDropZoneProps = {
|
|
|
117
118
|
*/
|
|
118
119
|
onValueCleared?: () => void;
|
|
119
120
|
/**
|
|
120
|
-
* The width of the
|
|
121
|
+
* The maximum width of the instruction text and button row.
|
|
122
|
+
* Error and helper messages are intentionally not constrained by this value.
|
|
121
123
|
*
|
|
122
124
|
* @default 280
|
|
123
125
|
*/
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export declare const InternalIconButton: import("react").ForwardRefExoticComponent<{
|
|
2
2
|
outlined?: import("../../styled-system/recipes").IconButtonSlotRecipeVariant['outlined'];
|
|
3
|
+
destructive?: import("../../styled-system/recipes").IconButtonSlotRecipeVariant['destructive'];
|
|
3
4
|
children: React.ReactNode;
|
|
4
5
|
disabled?: boolean;
|
|
5
6
|
href?: string;
|
|
@@ -9,6 +10,7 @@ export declare const InternalIconButton: import("react").ForwardRefExoticCompone
|
|
|
9
10
|
} & import("react").RefAttributes<HTMLAnchorElement | HTMLButtonElement>>;
|
|
10
11
|
export declare const IconButton: import("react").ForwardRefExoticComponent<{
|
|
11
12
|
outlined?: import("../../styled-system/recipes").IconButtonSlotRecipeVariant['outlined'];
|
|
13
|
+
destructive?: import("../../styled-system/recipes").IconButtonSlotRecipeVariant['destructive'];
|
|
12
14
|
children: React.ReactNode;
|
|
13
15
|
disabled?: boolean;
|
|
14
16
|
href?: string;
|
|
@@ -20,8 +20,8 @@ import { FocusIndicator } from '../FocusIndicator';
|
|
|
20
20
|
*
|
|
21
21
|
* @param ref - Forwarded ref for the rendered button or anchor element.
|
|
22
22
|
*/
|
|
23
|
-
function IconButtonBase({ children, outlined, size = 'default', className, href, customLinkComponent, disabled = false, type = 'button', ...rest }, ref) {
|
|
24
|
-
const classes = iconButtonSlotRecipe({ outlined, size });
|
|
23
|
+
function IconButtonBase({ children, outlined, destructive, size = 'default', className, href, customLinkComponent, disabled = false, type = 'button', ...rest }, ref) {
|
|
24
|
+
const classes = iconButtonSlotRecipe({ outlined, size, destructive });
|
|
25
25
|
const isButton = disabled || href === undefined;
|
|
26
26
|
const Tag = useMemo(() => {
|
|
27
27
|
// If disabled, always render as a button since the link component doesn't support disabled prop
|
|
@@ -7,6 +7,13 @@ type IconButtonCommonProps = {
|
|
|
7
7
|
* @default false
|
|
8
8
|
*/
|
|
9
9
|
outlined?: IconButtonSlotRecipeVariant['outlined'];
|
|
10
|
+
/**
|
|
11
|
+
* Whether the button is destructive.
|
|
12
|
+
* The style of the button will be changed to indicate that the action is destructive.
|
|
13
|
+
*
|
|
14
|
+
* @default false
|
|
15
|
+
*/
|
|
16
|
+
destructive?: IconButtonSlotRecipeVariant['destructive'];
|
|
10
17
|
/**
|
|
11
18
|
* Icon element to be rendered inside the button.
|
|
12
19
|
* Only one element (typically an SVG icon) is expected.
|
|
@@ -446,6 +446,10 @@ export type MultipleSelectBoxProps<T extends AllowedValueTypes = string, Additio
|
|
|
446
446
|
* Handler executed when text is entered in the search box.
|
|
447
447
|
* The handler is debounced by 300ms.
|
|
448
448
|
*
|
|
449
|
+
* If the handler is provided after the user has already typed (e.g.
|
|
450
|
+
* `onSearchOptions={isReady ? handleSearch : undefined}`), it is called
|
|
451
|
+
* once with the current search text so that pending input is not lost.
|
|
452
|
+
*
|
|
449
453
|
* When this prop is provided, client-side filtering is disabled as it's
|
|
450
454
|
* assumed that filtering will be handled by the prop.
|
|
451
455
|
*/
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { useEffect, useMemo, useRef, useState } from 'react';
|
|
3
|
+
import { useLatest } from '../../utilities/state/useLatest';
|
|
3
4
|
import { normalizeFullWidth } from '../../utilities/string/normalizeFullWidth';
|
|
4
5
|
/**
|
|
5
6
|
* Custom hook to handle search functionality within a SelectBox component.
|
|
@@ -18,6 +19,10 @@ export const useSearchBox = (options, enableSearchOptions, onSearchOptions) => {
|
|
|
18
19
|
const [searchText, setSearchText] = useState('');
|
|
19
20
|
const debounceRef = useRef(null);
|
|
20
21
|
const previousSearchTextRef = useRef('');
|
|
22
|
+
// Keep the latest handler in a ref so that a new handler identity (e.g. an
|
|
23
|
+
// inline function re-created on parent re-render) does not re-run the
|
|
24
|
+
// debounce effect and cancel a pending call.
|
|
25
|
+
const onSearchOptionsRef = useLatest(onSearchOptions);
|
|
21
26
|
const filteredOptions = useMemo(() => {
|
|
22
27
|
if (!enableSearchOptions || onSearchOptions) {
|
|
23
28
|
return options;
|
|
@@ -29,8 +34,14 @@ export const useSearchBox = (options, enableSearchOptions, onSearchOptions) => {
|
|
|
29
34
|
const onSearchTextChange = (event) => {
|
|
30
35
|
setSearchText(event.target.value);
|
|
31
36
|
};
|
|
37
|
+
// Track only the presence of the handler (not its identity) so that an
|
|
38
|
+
// undefined → defined transition re-runs the effect and dispatches the
|
|
39
|
+
// pending search text, while identity changes do not cancel pending calls.
|
|
40
|
+
// This preserves the behavior of the previous implementation, where the
|
|
41
|
+
// handler itself was an effect dependency and the transition dispatched.
|
|
42
|
+
const hasSearchHandler = Boolean(onSearchOptions);
|
|
32
43
|
useEffect(() => {
|
|
33
|
-
if (!enableSearchOptions || !
|
|
44
|
+
if (!enableSearchOptions || !hasSearchHandler)
|
|
34
45
|
return;
|
|
35
46
|
// Skip if searchText hasn't changed (prevents initial mount and unnecessary calls)
|
|
36
47
|
if (searchText === previousSearchTextRef.current) {
|
|
@@ -41,14 +52,14 @@ export const useSearchBox = (options, enableSearchOptions, onSearchOptions) => {
|
|
|
41
52
|
clearTimeout(debounceRef.current);
|
|
42
53
|
}
|
|
43
54
|
debounceRef.current = setTimeout(() => {
|
|
44
|
-
|
|
55
|
+
onSearchOptionsRef.current?.(searchText);
|
|
45
56
|
}, 300);
|
|
46
57
|
return () => {
|
|
47
58
|
if (debounceRef.current) {
|
|
48
59
|
clearTimeout(debounceRef.current);
|
|
49
60
|
}
|
|
50
61
|
};
|
|
51
|
-
}, [searchText,
|
|
62
|
+
}, [searchText, enableSearchOptions, hasSearchHandler, onSearchOptionsRef]);
|
|
52
63
|
return {
|
|
53
64
|
onSearchTextChange,
|
|
54
65
|
filteredOptions,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { forwardRef } from 'react';
|
|
3
|
-
import { Error, Approval, Caution, Close, Pending } from '@moneyforward/mfui-icons-react';
|
|
3
|
+
import { Error, Approval, Caution, Close, Info, Pending } from '@moneyforward/mfui-icons-react';
|
|
4
4
|
import { cx } from '../../styled-system/css';
|
|
5
5
|
import { sectionMessageSlotRecipe } from '../../styled-system/recipes';
|
|
6
6
|
import { IconButton } from '../IconButton';
|
|
@@ -28,6 +28,7 @@ export const SectionMessage = forwardRef(({ messageType = 'neutral', region = 'i
|
|
|
28
28
|
const statusIconA11yProps = statusIconLabel === undefined ? { 'aria-hidden': true } : { 'aria-label': statusIconLabel };
|
|
29
29
|
const StatusIcon = {
|
|
30
30
|
neutral: null,
|
|
31
|
+
info: _jsx(Info, { ...statusIconA11yProps, className: cx(classes.statusIcon, 'mfui-SectionMessage__statusIcon') }),
|
|
31
32
|
success: (_jsx(Approval, { ...statusIconA11yProps, className: cx(classes.statusIcon, 'mfui-SectionMessage__statusIcon') })),
|
|
32
33
|
error: _jsx(Error, { ...statusIconA11yProps, className: cx(classes.statusIcon, 'mfui-SectionMessage__statusIcon') }),
|
|
33
34
|
caution: (_jsx(Caution, { ...statusIconA11yProps, className: cx(classes.statusIcon, 'mfui-SectionMessage__statusIcon') })),
|
|
@@ -53,7 +53,14 @@ export const SelectBox = forwardRef((props, ref) => {
|
|
|
53
53
|
triggerRef.current?.focus();
|
|
54
54
|
},
|
|
55
55
|
});
|
|
56
|
-
const { searchText, onSearchTextChange, filteredOptions } = useSearchBox(options, enableSearchOptions, onSearchOptions);
|
|
56
|
+
const { searchText, onSearchTextChange, filteredOptions, resetSearchText } = useSearchBox(options, enableSearchOptions, onSearchOptions);
|
|
57
|
+
// Clear the search text whenever the option panel closes so that
|
|
58
|
+
// reopening always starts from an unfiltered option list.
|
|
59
|
+
useUpdateEffect(() => {
|
|
60
|
+
if (!isOptionPanelOpen) {
|
|
61
|
+
resetSearchText();
|
|
62
|
+
}
|
|
63
|
+
}, [isOptionPanelOpen, resetSearchText]);
|
|
57
64
|
const selectedOption = useMemo(() => {
|
|
58
65
|
if (value === undefined)
|
|
59
66
|
return null;
|
|
@@ -361,6 +361,13 @@ export type SelectBoxProps<T extends AllowedValueTypes = string, AdditionalProps
|
|
|
361
361
|
* Handler executed when text is entered in the search box.
|
|
362
362
|
* The handler is debounced by 300ms.
|
|
363
363
|
*
|
|
364
|
+
* Also called with an empty string when the option panel closes, because the
|
|
365
|
+
* search text is reset on close so that reopening shows the full option list.
|
|
366
|
+
*
|
|
367
|
+
* If the handler is provided after the user has already typed (e.g.
|
|
368
|
+
* `onSearchOptions={isReady ? handleSearch : undefined}`), it is called
|
|
369
|
+
* once with the current search text so that pending input is not lost.
|
|
370
|
+
*
|
|
364
371
|
* When this prop is provided, client-side filtering is disabled as it's
|
|
365
372
|
* assumed that filtering will be handled by the prop.
|
|
366
373
|
*/
|
|
@@ -10,7 +10,8 @@ import { type BasedAdditionalProps, type SelectBoxOption } from '../SelectBox.ty
|
|
|
10
10
|
* provided, client-side filtering is disabled as it's assumed that the caller
|
|
11
11
|
* will handle the filtering.
|
|
12
12
|
*
|
|
13
|
-
* @returns Object containing the filtered options, search text,
|
|
13
|
+
* @returns Object containing the filtered options, search text, handler to update search text,
|
|
14
|
+
* and a callback to reset the search text.
|
|
14
15
|
*/
|
|
15
16
|
export declare const useSearchBox: <T extends string | number | undefined = string, AdditionalProps extends BasedAdditionalProps = BasedAdditionalProps>(options: (SelectBoxOption<T, AdditionalProps> | null | undefined)[], enableSearchOptions: boolean, onSearchOptions?: (text: string) => void) => {
|
|
16
17
|
/**
|
|
@@ -25,4 +26,8 @@ export declare const useSearchBox: <T extends string | number | undefined = stri
|
|
|
25
26
|
* Current search text value.
|
|
26
27
|
*/
|
|
27
28
|
searchText: string;
|
|
29
|
+
/**
|
|
30
|
+
* Resets the search text to an empty string.
|
|
31
|
+
*/
|
|
32
|
+
resetSearchText: () => void;
|
|
28
33
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
3
|
+
import { useLatest } from '../../utilities/state/useLatest';
|
|
3
4
|
import { normalizeFullWidth } from '../../utilities/string/normalizeFullWidth';
|
|
4
5
|
/**
|
|
5
6
|
* Custom hook to handle search functionality within a SelectBox component.
|
|
@@ -12,12 +13,17 @@ import { normalizeFullWidth } from '../../utilities/string/normalizeFullWidth';
|
|
|
12
13
|
* provided, client-side filtering is disabled as it's assumed that the caller
|
|
13
14
|
* will handle the filtering.
|
|
14
15
|
*
|
|
15
|
-
* @returns Object containing the filtered options, search text,
|
|
16
|
+
* @returns Object containing the filtered options, search text, handler to update search text,
|
|
17
|
+
* and a callback to reset the search text.
|
|
16
18
|
*/
|
|
17
19
|
export const useSearchBox = (options, enableSearchOptions, onSearchOptions) => {
|
|
18
20
|
const [searchText, setSearchText] = useState('');
|
|
19
21
|
const debounceRef = useRef(null);
|
|
20
22
|
const previousSearchTextRef = useRef('');
|
|
23
|
+
// Keep the latest handler in a ref so that a new handler identity (e.g. an
|
|
24
|
+
// inline function re-created on parent re-render) does not re-run the
|
|
25
|
+
// debounce effect and cancel a pending call.
|
|
26
|
+
const onSearchOptionsRef = useLatest(onSearchOptions);
|
|
21
27
|
const filteredOptions = useMemo(() => {
|
|
22
28
|
// If not searchable or if onSearchOptions is provided, return all options without filtering
|
|
23
29
|
if (!enableSearchOptions || onSearchOptions) {
|
|
@@ -49,8 +55,17 @@ export const useSearchBox = (options, enableSearchOptions, onSearchOptions) => {
|
|
|
49
55
|
const handleSearchTextChange = useCallback((event) => {
|
|
50
56
|
setSearchText(event.target.value);
|
|
51
57
|
}, []);
|
|
58
|
+
const resetSearchText = useCallback(() => {
|
|
59
|
+
setSearchText('');
|
|
60
|
+
}, []);
|
|
61
|
+
// Track only the presence of the handler (not its identity) so that an
|
|
62
|
+
// undefined → defined transition re-runs the effect and dispatches the
|
|
63
|
+
// pending search text, while identity changes do not cancel pending calls.
|
|
64
|
+
// This preserves the behavior of the previous implementation, where the
|
|
65
|
+
// handler itself was an effect dependency and the transition dispatched.
|
|
66
|
+
const hasSearchHandler = Boolean(onSearchOptions);
|
|
52
67
|
useEffect(() => {
|
|
53
|
-
if (!enableSearchOptions || !
|
|
68
|
+
if (!enableSearchOptions || !hasSearchHandler)
|
|
54
69
|
return;
|
|
55
70
|
// Skip if searchText hasn't changed (prevents initial mount and unnecessary calls)
|
|
56
71
|
if (searchText === previousSearchTextRef.current) {
|
|
@@ -61,14 +76,14 @@ export const useSearchBox = (options, enableSearchOptions, onSearchOptions) => {
|
|
|
61
76
|
clearTimeout(debounceRef.current);
|
|
62
77
|
}
|
|
63
78
|
debounceRef.current = setTimeout(() => {
|
|
64
|
-
|
|
79
|
+
onSearchOptionsRef.current?.(searchText);
|
|
65
80
|
}, 300);
|
|
66
81
|
return () => {
|
|
67
82
|
if (debounceRef.current) {
|
|
68
83
|
clearTimeout(debounceRef.current);
|
|
69
84
|
}
|
|
70
85
|
};
|
|
71
|
-
}, [searchText,
|
|
86
|
+
}, [searchText, enableSearchOptions, hasSearchHandler, onSearchOptionsRef]);
|
|
72
87
|
return {
|
|
73
88
|
/**
|
|
74
89
|
* Handler for search input change events.
|
|
@@ -82,5 +97,9 @@ export const useSearchBox = (options, enableSearchOptions, onSearchOptions) => {
|
|
|
82
97
|
* Current search text value.
|
|
83
98
|
*/
|
|
84
99
|
searchText,
|
|
100
|
+
/**
|
|
101
|
+
* Resets the search text to an empty string.
|
|
102
|
+
*/
|
|
103
|
+
resetSearchText,
|
|
85
104
|
};
|
|
86
105
|
};
|
|
@@ -195,6 +195,20 @@ export const SplitView = forwardRef(({ className, leftPanelSlot, rightPanelSlot,
|
|
|
195
195
|
isDragging,
|
|
196
196
|
dividerPropsStyle: dividerProps?.style,
|
|
197
197
|
});
|
|
198
|
+
// `dividerProps` is spread after the built-in attributes so that consumers can override ARIA
|
|
199
|
+
// attributes (e.g. aria-label, aria-valuenow). These four entries must be excluded from that
|
|
200
|
+
// spread and re-applied afterwards, otherwise they would silently replace internal wiring:
|
|
201
|
+
// the styling classes/styles and the resize event handlers.
|
|
202
|
+
const { className: dividerClassName, style: _dividerPropsStyle, onPointerDown: dividerOnPointerDown, onKeyDown: dividerOnKeyDown, ...restDividerProps } = dividerProps ?? {};
|
|
203
|
+
// Run the internal resize handler first, then forward the event to the consumer's handler.
|
|
204
|
+
const handleDividerPointerDown = (event) => {
|
|
205
|
+
handleMouseDown(event);
|
|
206
|
+
dividerOnPointerDown?.(event);
|
|
207
|
+
};
|
|
208
|
+
const handleDividerKeyDown = (event) => {
|
|
209
|
+
handleKeyDown(event);
|
|
210
|
+
dividerOnKeyDown?.(event);
|
|
211
|
+
};
|
|
198
212
|
// Apply controlled panel style to the correct panel based on targetPanel.
|
|
199
213
|
// When a panel is the main panel (not controlled), flex: 1 ensures it fills remaining space.
|
|
200
214
|
const computedLeftPanelStyle = resolvedTargetPanel === 'left' ? controlledPanelOuterStyle : leftPanelProps?.style;
|
|
@@ -209,7 +223,7 @@ export const SplitView = forwardRef(({ className, leftPanelSlot, rightPanelSlot,
|
|
|
209
223
|
ref.current = node;
|
|
210
224
|
}
|
|
211
225
|
containerRef.current = node;
|
|
212
|
-
}, className: cx(classes.root, 'mfui-SplitView__root', className), ...props, children: [resolvedTargetPanel === 'left' ? (shouldRenderControlledPanel || isSlideOutAnimating ? (_jsx("div", { ...leftPanelProps, className: cx(classes.leftPanel, 'mfui-SplitView__leftPanel', leftPanelProps?.className), style: computedLeftPanelStyle, children: _jsx("div", { style: controlledPanelInnerStyle, children: enableAutoUnmount ? (leftPanelSlot ?? lastRightPanelRef.current) : leftPanelSlot }) })) : null) : (_jsx("div", { ...leftPanelProps, className: cx(classes.leftPanel, 'mfui-SplitView__leftPanel', leftPanelProps?.className), style: computedLeftPanelStyle, children: leftPanelSlot })), isRightPanelVisible || isSlideOutAnimating ? (_jsx("div", {
|
|
226
|
+
}, className: cx(classes.root, 'mfui-SplitView__root', className), ...props, children: [resolvedTargetPanel === 'left' ? (shouldRenderControlledPanel || isSlideOutAnimating ? (_jsx("div", { ...leftPanelProps, className: cx(classes.leftPanel, 'mfui-SplitView__leftPanel', leftPanelProps?.className), style: computedLeftPanelStyle, children: _jsx("div", { style: controlledPanelInnerStyle, children: enableAutoUnmount ? (leftPanelSlot ?? lastRightPanelRef.current) : leftPanelSlot }) })) : null) : (_jsx("div", { ...leftPanelProps, className: cx(classes.leftPanel, 'mfui-SplitView__leftPanel', leftPanelProps?.className), style: computedLeftPanelStyle, children: leftPanelSlot })), isRightPanelVisible || isSlideOutAnimating ? (_jsx("div", { role: "separator", "aria-orientation": "vertical", "aria-label": dividerProps?.['aria-label'] ?? '左右のパネルを調整', "aria-valuenow": currentControlledPanelSize ?? initialPanelSizeNumber, "aria-valuemin": minPanelSizeNumber, "aria-valuemax": maxPanelSizeNumber,
|
|
213
227
|
// eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex
|
|
214
|
-
tabIndex: 0, style: dividerStyle, onPointerDown:
|
|
228
|
+
tabIndex: 0, ...restDividerProps, className: cx(classes.divider, 'mfui-SplitView__divider', dividerClassName), style: dividerStyle, onPointerDown: handleDividerPointerDown, onKeyDown: handleDividerKeyDown })) : null, resolvedTargetPanel === 'right' ? (shouldRenderControlledPanel || isSlideOutAnimating ? (_jsx("div", { ...rightPanelProps, className: cx(classes.rightPanel, 'mfui-SplitView__rightPanel', rightPanelProps?.className), style: computedRightPanelStyle, children: _jsx("div", { style: controlledPanelInnerStyle, children: enableAutoUnmount ? (rightPanelSlot ?? lastRightPanelRef.current) : rightPanelSlot }) })) : null) : (_jsx("div", { ...rightPanelProps, className: cx(classes.rightPanel, 'mfui-SplitView__rightPanel', rightPanelProps?.className), style: computedRightPanelStyle, children: rightPanelSlot }))] }));
|
|
215
229
|
});
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { type TabListProps } from './TabList.types';
|
|
2
|
-
export declare function TabList({ children, scrollLeftButtonProps, scrollRightButtonProps, allTabsDropdownMenuProps, }: TabListProps): import("react/jsx-runtime").JSX.Element;
|
|
2
|
+
export declare function TabList({ children, scrollLeftButtonProps, scrollRightButtonProps, allTabsDropdownMenuProps, className, style, }: TabListProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -5,10 +5,10 @@ import { tabListSlotRecipe } from '../../../styled-system/recipes';
|
|
|
5
5
|
import { TabMenu } from './TabMenu';
|
|
6
6
|
import { useShouldShowMenuController } from './hooks/useShouldShowMenuController';
|
|
7
7
|
import { cx } from '../../../styled-system/css';
|
|
8
|
-
export function TabList({ children, scrollLeftButtonProps, scrollRightButtonProps, allTabsDropdownMenuProps, }) {
|
|
8
|
+
export function TabList({ children, scrollLeftButtonProps, scrollRightButtonProps, allTabsDropdownMenuProps, className, style, }) {
|
|
9
9
|
const classNames = tabListSlotRecipe({});
|
|
10
10
|
const containerRef = useRef(null);
|
|
11
11
|
const tabListRef = useRef(null);
|
|
12
12
|
const isOverflowed = useShouldShowMenuController(tabListRef, containerRef);
|
|
13
|
-
return (_jsxs("div", { ref: containerRef, className: cx(classNames.root, 'mfui-TabList__root'), children: [_jsx("div", { ref: tabListRef, role: "tablist", className: cx(classNames.tabList, isOverflowed && classNames.isOverflowed, 'mfui-TabList__tabList'), children: children }), _jsx("div", { className: cx(classNames.blankSpace, 'mfui-TabList__blankSpace') }), isOverflowed ? (_jsx(TabMenu, { tabListRef: tabListRef, scrollLeftButtonProps: scrollLeftButtonProps, scrollRightButtonProps: scrollRightButtonProps, allTabsDropdownMenuProps: allTabsDropdownMenuProps })) : null] }));
|
|
13
|
+
return (_jsxs("div", { ref: containerRef, className: cx(classNames.root, 'mfui-TabList__root', className), style: style, children: [_jsx("div", { ref: tabListRef, role: "tablist", className: cx(classNames.tabList, isOverflowed && classNames.isOverflowed, 'mfui-TabList__tabList'), children: children }), _jsx("div", { className: cx(classNames.blankSpace, 'mfui-TabList__blankSpace') }), isOverflowed ? (_jsx(TabMenu, { tabListRef: tabListRef, scrollLeftButtonProps: scrollLeftButtonProps, scrollRightButtonProps: scrollRightButtonProps, allTabsDropdownMenuProps: allTabsDropdownMenuProps })) : null] }));
|
|
14
14
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { type TabPanelProps } from './TabPanel.types';
|
|
2
|
-
export declare function TabPanel({ forTabId, enableAutoUnmount, children, style, ...props }: TabPanelProps): import("react/jsx-runtime").JSX.Element | null;
|
|
2
|
+
export declare function TabPanel({ forTabId, enableAutoUnmount, children, className, style, ...props }: TabPanelProps): import("react/jsx-runtime").JSX.Element | null;
|
|
@@ -4,7 +4,7 @@ import { useContext } from 'react';
|
|
|
4
4
|
import { tabPanelSlotRecipe } from '../../../styled-system/recipes';
|
|
5
5
|
import { TabContext } from '../TabContext';
|
|
6
6
|
import { cx } from '../../../styled-system/css';
|
|
7
|
-
export function TabPanel({ forTabId, enableAutoUnmount, children, style, ...props }) {
|
|
7
|
+
export function TabPanel({ forTabId, enableAutoUnmount, children, className, style, ...props }) {
|
|
8
8
|
const { selectedTabId, enableAutoUnmount: contextEnableAutoUnmount } = useContext(TabContext);
|
|
9
9
|
// Use prop value if provided, otherwise fall back to context value
|
|
10
10
|
const shouldAutoUnmount = enableAutoUnmount ?? contextEnableAutoUnmount;
|
|
@@ -12,7 +12,7 @@ export function TabPanel({ forTabId, enableAutoUnmount, children, style, ...prop
|
|
|
12
12
|
if (shouldAutoUnmount && !isSelected)
|
|
13
13
|
return null;
|
|
14
14
|
const classNames = tabPanelSlotRecipe();
|
|
15
|
-
return (_jsx("div", { role: "tabpanel", id: `tabpanel-${forTabId}`, className: cx(classNames.root, 'mfui-TabPanel__root'), "aria-labelledby": forTabId, style: {
|
|
15
|
+
return (_jsx("div", { role: "tabpanel", id: `tabpanel-${forTabId}`, className: cx(classNames.root, 'mfui-TabPanel__root', className), "aria-labelledby": forTabId, style: {
|
|
16
16
|
...style,
|
|
17
17
|
display: !shouldAutoUnmount && !isSelected ? 'none' : undefined,
|
|
18
18
|
}, ...props, children: children }));
|
package/dist/src/Tabs/Tabs.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { type TabsProps } from './Tabs.types';
|
|
|
2
2
|
import { TabItem } from './TabItem';
|
|
3
3
|
import { TabList } from './TabList';
|
|
4
4
|
import { TabPanel } from './TabPanel';
|
|
5
|
-
declare function Base({ selectedTabId, onSelectedTabChange, targetDOMNode, enableAutoUnmount, children }: TabsProps): import("react/jsx-runtime").JSX.Element;
|
|
5
|
+
declare function Base({ selectedTabId, onSelectedTabChange, targetDOMNode, enableAutoUnmount, children, className, style, }: TabsProps): import("react/jsx-runtime").JSX.Element;
|
|
6
6
|
/**
|
|
7
7
|
* The Tabs component manages the tabs, tab lists, and tab panels within a tab section.
|
|
8
8
|
* It provides the necessary context for handling tab selection and rendering the appropriate content.
|
package/dist/src/Tabs/Tabs.js
CHANGED
|
@@ -9,7 +9,7 @@ import { TabPanel } from './TabPanel';
|
|
|
9
9
|
import { TabContext } from './TabContext';
|
|
10
10
|
import { getTargetDomNode } from '../utilities/dom/getTargetDomNode';
|
|
11
11
|
import { cx } from '../../styled-system/css';
|
|
12
|
-
function Base({ selectedTabId, onSelectedTabChange, targetDOMNode, enableAutoUnmount = true, children }) {
|
|
12
|
+
function Base({ selectedTabId, onSelectedTabChange, targetDOMNode, enableAutoUnmount = true, children, className, style, }) {
|
|
13
13
|
const classNames = tabsSlotRecipe();
|
|
14
14
|
const [shouldShowMenu, setShouldShowMenu] = useState(false);
|
|
15
15
|
const wrapperRef = useRef(null);
|
|
@@ -59,7 +59,7 @@ function Base({ selectedTabId, onSelectedTabChange, targetDOMNode, enableAutoUnm
|
|
|
59
59
|
unregisterTab,
|
|
60
60
|
enableAutoUnmount,
|
|
61
61
|
]);
|
|
62
|
-
return (_jsx(TabContext.Provider, { value: contextValue, children: _jsx("div", { ref: wrapperRef, className: cx(classNames.root, 'mfui-Tabs__root'), children: children }) }));
|
|
62
|
+
return (_jsx(TabContext.Provider, { value: contextValue, children: _jsx("div", { ref: wrapperRef, className: cx(classNames.root, 'mfui-Tabs__root', className), style: style, children: children }) }));
|
|
63
63
|
}
|
|
64
64
|
/**
|
|
65
65
|
* The Tabs component manages the tabs, tab lists, and tab panels within a tab section.
|
|
@@ -17,7 +17,7 @@ type FileDropZoneSlotRecipeVariantMap = {
|
|
|
17
17
|
[key in keyof FileDropZoneSlotRecipeVariant]: Array<FileDropZoneSlotRecipeVariant[key]>
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
type FileDropZoneSlotRecipeSlot = "root" | "input" | "container" | "illustration" | "mainContainer" | "instruction" | "buttonContainer" | "button" | "fileInfo" | "span" | "clearButton" | "helpMessage" | "extra" | "phrase"
|
|
20
|
+
type FileDropZoneSlotRecipeSlot = "root" | "input" | "container" | "illustration" | "mainContainer" | "instruction" | "buttonContainer" | "button" | "fileInfo" | "span" | "clearButton" | "helpMessage" | "errorMessages" | "extra" | "phrase"
|
|
21
21
|
|
|
22
22
|
export type FileDropZoneSlotRecipeVariantProps = {
|
|
23
23
|
[key in keyof FileDropZoneSlotRecipeVariant]?: FileDropZoneSlotRecipeVariant[key] | undefined
|
|
@@ -8,6 +8,7 @@ interface IconButtonSlotRecipeVariant {
|
|
|
8
8
|
*/
|
|
9
9
|
size: "small" | "default"
|
|
10
10
|
outlined: boolean
|
|
11
|
+
destructive: boolean
|
|
11
12
|
}
|
|
12
13
|
|
|
13
14
|
type IconButtonSlotRecipeVariantMap = {
|
|
@@ -17,7 +18,7 @@ type IconButtonSlotRecipeVariantMap = {
|
|
|
17
18
|
type IconButtonSlotRecipeSlot = "root"
|
|
18
19
|
|
|
19
20
|
export type IconButtonSlotRecipeVariantProps = {
|
|
20
|
-
[key in keyof IconButtonSlotRecipeVariant]?:
|
|
21
|
+
[key in keyof IconButtonSlotRecipeVariant]?: IconButtonSlotRecipeVariant[key] | undefined
|
|
21
22
|
}
|
|
22
23
|
|
|
23
24
|
export interface IconButtonSlotRecipeRecipe {
|
|
@@ -3,7 +3,33 @@ import { createRecipe } from './create-recipe.js';
|
|
|
3
3
|
const iconButtonSlotRecipeDefaultVariants = {
|
|
4
4
|
"size": "default"
|
|
5
5
|
};
|
|
6
|
-
const iconButtonSlotRecipeCompoundVariants = [
|
|
6
|
+
const iconButtonSlotRecipeCompoundVariants = [
|
|
7
|
+
{
|
|
8
|
+
"destructive": true,
|
|
9
|
+
"outlined": true,
|
|
10
|
+
"css": {
|
|
11
|
+
"root": {
|
|
12
|
+
"borderColor": "mfui.color.signal-red.border.none",
|
|
13
|
+
"_hover": {
|
|
14
|
+
"_notDisabled": {
|
|
15
|
+
"borderColor": "mfui.color.signal-red.border.hovered"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"_focusVisible": {
|
|
19
|
+
"borderColor": "mfui.color.signal-red.border.hovered"
|
|
20
|
+
},
|
|
21
|
+
"_active": {
|
|
22
|
+
"_notDisabled": {
|
|
23
|
+
"borderColor": "mfui.color.signal-red.border.pressed"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"_disabled": {
|
|
27
|
+
"borderColor": "mfui.color.disabled.border"
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
];
|
|
7
33
|
const iconButtonSlotRecipeSlotNames = [
|
|
8
34
|
[
|
|
9
35
|
"root",
|
|
@@ -16,7 +42,8 @@ const iconButtonSlotRecipeFn = memo((props = {}) => {
|
|
|
16
42
|
});
|
|
17
43
|
const iconButtonSlotRecipeVariantKeys = [
|
|
18
44
|
"size",
|
|
19
|
-
"outlined"
|
|
45
|
+
"outlined",
|
|
46
|
+
"destructive"
|
|
20
47
|
];
|
|
21
48
|
const getVariantProps = (variants) => ({ ...iconButtonSlotRecipeDefaultVariants, ...compact(variants) });
|
|
22
49
|
export const iconButtonSlotRecipe = /* @__PURE__ */ Object.assign(iconButtonSlotRecipeFn, {
|
|
@@ -32,6 +59,10 @@ export const iconButtonSlotRecipe = /* @__PURE__ */ Object.assign(iconButtonSlot
|
|
|
32
59
|
],
|
|
33
60
|
"outlined": [
|
|
34
61
|
"true"
|
|
62
|
+
],
|
|
63
|
+
"destructive": [
|
|
64
|
+
"true",
|
|
65
|
+
"false"
|
|
35
66
|
]
|
|
36
67
|
},
|
|
37
68
|
splitVariantProps(props) {
|
|
@@ -3,7 +3,7 @@ import type { ConditionalValue } from '../types/index';
|
|
|
3
3
|
import type { DistributiveOmit, Pretty } from '../types/system-types';
|
|
4
4
|
|
|
5
5
|
interface SectionMessageSlotRecipeVariant {
|
|
6
|
-
messageType: "neutral" | "success" | "error" | "caution" | "busy" | "progress"
|
|
6
|
+
messageType: "neutral" | "info" | "success" | "error" | "caution" | "busy" | "progress"
|
|
7
7
|
region: "inline" | "page"
|
|
8
8
|
disableResponsive: boolean
|
|
9
9
|
}
|
package/dist/styles.css
CHANGED
|
@@ -4685,8 +4685,6 @@
|
|
|
4685
4685
|
background-color: var(--mfui-colors-mfui\.color\.neutral\.thin-background\.none);
|
|
4686
4686
|
font-family: var(--mfui-fonts-mfui\.typography\.font-family\.label);
|
|
4687
4687
|
font-size: var(--mfui-font-sizes-mfui\.typography\.font-size\.control-label);
|
|
4688
|
-
width: 100%;
|
|
4689
|
-
min-width: max-content;
|
|
4690
4688
|
height: 100%;
|
|
4691
4689
|
}
|
|
4692
4690
|
|
|
@@ -4695,6 +4693,7 @@
|
|
|
4695
4693
|
flex-direction: column;
|
|
4696
4694
|
align-items: center;
|
|
4697
4695
|
justify-content: center;
|
|
4696
|
+
width: 100%;
|
|
4698
4697
|
}
|
|
4699
4698
|
|
|
4700
4699
|
.mfui-fqNMeO {
|
|
@@ -4715,6 +4714,7 @@
|
|
|
4715
4714
|
align-items: center;
|
|
4716
4715
|
justify-content: center;
|
|
4717
4716
|
width: 100%;
|
|
4717
|
+
min-width: max-content;
|
|
4718
4718
|
}
|
|
4719
4719
|
|
|
4720
4720
|
.mfui-juYDJw {
|
|
@@ -4767,6 +4767,12 @@
|
|
|
4767
4767
|
height: 1px;
|
|
4768
4768
|
}
|
|
4769
4769
|
|
|
4770
|
+
.mfui-VkDTa {
|
|
4771
|
+
display: flex;
|
|
4772
|
+
flex-direction: column;
|
|
4773
|
+
align-items: center;
|
|
4774
|
+
}
|
|
4775
|
+
|
|
4770
4776
|
.mfui-kakNKU {
|
|
4771
4777
|
padding-inline: var(--mfui-spacing-mfui\.size\.padding\.main-content\.horizontal\.comfort);
|
|
4772
4778
|
padding-block: var(--mfui-spacing-mfui\.size\.padding\.content\.vertical\.comfort);
|
|
@@ -6460,6 +6466,26 @@ li:last-child > .mfui-cXGJls {
|
|
|
6460
6466
|
border-color: var(--mfui-colors-mfui\.color\.neutral\.border\.hovered);
|
|
6461
6467
|
}
|
|
6462
6468
|
|
|
6469
|
+
.mfui-cpUpeB {
|
|
6470
|
+
color: var(--mfui-colors-mfui\.color\.signal-red\.content\.none);
|
|
6471
|
+
}
|
|
6472
|
+
|
|
6473
|
+
.mfui-cpUpeB:is([aria-expanded=true], [data-expanded], [data-state="expanded"]) {
|
|
6474
|
+
color: var(--mfui-colors-mfui\.color\.signal-red\.content\.pressed);
|
|
6475
|
+
}
|
|
6476
|
+
|
|
6477
|
+
.mfui-cpUpeB:is(:disabled, [disabled], [data-disabled], [aria-disabled=true]) {
|
|
6478
|
+
color: var(--mfui-colors-mfui\.color\.disabled\.content);
|
|
6479
|
+
}
|
|
6480
|
+
|
|
6481
|
+
.mfui-cpUpeB:is(:focus-visible, [data-focus-visible]),.mfui-cpUpeB:is(:hover, [data-hover]):not(:disabled, [disabled], [data-disabled]) {
|
|
6482
|
+
color: var(--mfui-colors-mfui\.color\.signal-red\.content\.hovered);
|
|
6483
|
+
}
|
|
6484
|
+
|
|
6485
|
+
.mfui-cpUpeB:is(:active, [data-active]):not(:disabled, [disabled], [data-disabled]) {
|
|
6486
|
+
color: var(--mfui-colors-mfui\.color\.signal-red\.content\.pressed);
|
|
6487
|
+
}
|
|
6488
|
+
|
|
6463
6489
|
.mfui-bWjutw .mfui-FocusIndicator__root:is(:focus-visible, [data-focus-visible]),.mfui-bWjutw .mfui-FocusIndicator__root:has(input:focus-visible, input[data-focus-visible=true], textarea:focus-visible, textarea[data-focus-visible=true]) {
|
|
6464
6490
|
box-shadow: none;
|
|
6465
6491
|
}
|
|
@@ -6858,6 +6884,10 @@ li:last-child > .mfui-cXGJls {
|
|
|
6858
6884
|
resize: horizontal;
|
|
6859
6885
|
}
|
|
6860
6886
|
|
|
6887
|
+
.mfui-dpIccs {
|
|
6888
|
+
color: var(--mfui-colors-mfui\.color\.neutral\.content\.none);
|
|
6889
|
+
}
|
|
6890
|
+
|
|
6861
6891
|
.mfui-cFyzwg {
|
|
6862
6892
|
background-color: var(--mfui-colors-mfui\.color\.signal-green\.sub-background\.none);
|
|
6863
6893
|
}
|
|
@@ -8701,6 +8731,10 @@ li:last-child > .mfui-cXGJls {
|
|
|
8701
8731
|
border: none;
|
|
8702
8732
|
}
|
|
8703
8733
|
|
|
8734
|
+
.mfui-gpYLkO:is(:disabled, [disabled], [data-disabled], [aria-disabled=true]) {
|
|
8735
|
+
border-color: var(--mfui-colors-mfui\.color\.disabled\.border);
|
|
8736
|
+
}
|
|
8737
|
+
|
|
8704
8738
|
.mfui-kGMVVf:is(:disabled, [disabled], [data-disabled], [aria-disabled=true]) {
|
|
8705
8739
|
background-color: var(--mfui-colors-mfui\.color\.disabled\.background);
|
|
8706
8740
|
}
|
|
@@ -8717,14 +8751,14 @@ tr:last-child > .mfui-gtOHny::before {
|
|
|
8717
8751
|
height: 100%;
|
|
8718
8752
|
}
|
|
8719
8753
|
|
|
8720
|
-
.mfui-kSeSQV:is(:focus-visible, [data-focus-visible]),.mfui-dqyxbp:has(input:focus-visible, input[data-focus-visible=true], textarea:focus-visible, textarea[data-focus-visible=true]) {
|
|
8721
|
-
outline: 2px solid var(--mfui-colors-mfui\.color\.primary\.border\.none);
|
|
8722
|
-
}
|
|
8723
|
-
|
|
8724
8754
|
.mfui-iHQAZp:is(:focus-visible, [data-focus-visible]) {
|
|
8725
8755
|
border-color: var(--mfui-colors-mfui\.color\.signal-red\.border\.hovered);
|
|
8726
8756
|
}
|
|
8727
8757
|
|
|
8758
|
+
.mfui-kSeSQV:is(:focus-visible, [data-focus-visible]),.mfui-dqyxbp:has(input:focus-visible, input[data-focus-visible=true], textarea:focus-visible, textarea[data-focus-visible=true]) {
|
|
8759
|
+
outline: 2px solid var(--mfui-colors-mfui\.color\.primary\.border\.none);
|
|
8760
|
+
}
|
|
8761
|
+
|
|
8728
8762
|
.group:is(:focus-visible, [data-focus-visible]) .mfui-iYLcWF {
|
|
8729
8763
|
border-color: var(--mfui-colors-mfui\.color\.base\.inverted-border\.hovered);
|
|
8730
8764
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@moneyforward/mfui-components",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.35.0",
|
|
4
4
|
"description": "React UI Component Library for all Money Forward products",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -63,8 +63,8 @@
|
|
|
63
63
|
"@floating-ui/react-dom": "^2.1.2",
|
|
64
64
|
"@tanstack/react-virtual": "^3.13.18",
|
|
65
65
|
"dayjs": "^1.11.13",
|
|
66
|
-
"@moneyforward/mfui-
|
|
67
|
-
"@moneyforward/mfui-
|
|
66
|
+
"@moneyforward/mfui-icons-react": "^3.6.0",
|
|
67
|
+
"@moneyforward/mfui-design-tokens": "^3.3.1"
|
|
68
68
|
},
|
|
69
69
|
"scripts": {
|
|
70
70
|
"prepare:panda": "panda codegen",
|