@moneyforward/mfui-components 3.13.0 → 3.13.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/DateTimeSelection/MonthRangePicker/MonthRangePicker.js +18 -6
- package/dist/src/DateTimeSelection/shared/BaseRangePicker/BaseRangePicker.types.d.ts +14 -5
- package/dist/src/DateTimeSelection/shared/BaseRangePicker/BaseRangePickerProvider/BaseRangePickerProvider.js +41 -6
- package/dist/src/SelectBox/SelectBox.js +1 -1
- package/dist/styles.css +2 -0
- package/package.json +3 -3
|
@@ -63,7 +63,7 @@ const AccordionTrigger = forwardRef(({ children, className, onClick, ...props },
|
|
|
63
63
|
toggle();
|
|
64
64
|
onClick?.(event);
|
|
65
65
|
}, [onClick, toggle]);
|
|
66
|
-
return (_jsx(FocusIndicator, { children: _jsxs("button", { ref: ref, className: cx(classes.trigger, 'mfui-Accordion__trigger', className), "aria-expanded": isOpen, "aria-controls": id, onClick: handleClick, ...props, children: [_jsx(Typography, { variant: "controlLabel", children: children }), isOpen ? _jsx(DisclosureBasicExpanded, {}) : _jsx(DisclosureBasicCollapsed, {})] }) }));
|
|
66
|
+
return (_jsx(FocusIndicator, { children: _jsxs("button", { ref: ref, className: cx(classes.trigger, 'mfui-Accordion__trigger', className), "aria-expanded": isOpen, "aria-controls": id, onClick: handleClick, ...props, children: [_jsx(Typography, { variant: "controlLabel", children: children }), isOpen ? _jsx(DisclosureBasicExpanded, { "aria-hidden": "true" }) : _jsx(DisclosureBasicCollapsed, { "aria-hidden": "true" })] }) }));
|
|
67
67
|
});
|
|
68
68
|
const AccordionTarget = forwardRef(({ children, className, style, ...props }, ref) => {
|
|
69
69
|
const { size } = useAccordionContext();
|
|
@@ -31,14 +31,26 @@ import { MonthRangePickerPanel } from './MonthRangePickerPanel';
|
|
|
31
31
|
*/
|
|
32
32
|
export function MonthRangePicker({ format = 'YYYY/MM', minMonth, maxMonth, startInputProps = {}, endInputProps = {}, initialDisplayedMonths, ...restProps }) {
|
|
33
33
|
// MonthRangePicker panels are grouped by year (left = viewingYear, right = viewingYear + 1).
|
|
34
|
-
// When `previousAndCurrent` is requested, we
|
|
35
|
-
// shows the previous year
|
|
36
|
-
const initialViewingDate =
|
|
37
|
-
|
|
34
|
+
// When `previousAndCurrent` is requested, we shift by a full year so the left panel
|
|
35
|
+
// shows the previous year. This applies regardless of whether `value` is set.
|
|
36
|
+
const initialViewingDate = (() => {
|
|
37
|
+
if (initialDisplayedMonths !== 'previousAndCurrent') {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
const startDate = restProps.value?.[0] ?? restProps.defaultValue?.[0];
|
|
41
|
+
if (!startDate) {
|
|
42
|
+
// No value: show previous year relative to today
|
|
38
43
|
const today = new Date();
|
|
39
44
|
return new Date(today.getFullYear() - 1, 0, 1);
|
|
40
|
-
}
|
|
41
|
-
|
|
45
|
+
}
|
|
46
|
+
const endDate = restProps.value?.[1] ?? restProps.defaultValue?.[1];
|
|
47
|
+
if (endDate && startDate.getFullYear() !== endDate.getFullYear()) {
|
|
48
|
+
// Value spans different years: provider handles it via the multi-month path
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
// Same-year value + previousAndCurrent: show previous year on the left
|
|
52
|
+
return new Date(startDate.getFullYear() - 1, 0, 1);
|
|
53
|
+
})();
|
|
42
54
|
return (_jsx(BaseRangePicker, { ...restProps, format: format, initialDisplayedMonths: initialDisplayedMonths, initialViewingDate: initialViewingDate, startInputProps: {
|
|
43
55
|
placeholder: '開始月',
|
|
44
56
|
...startInputProps,
|
|
@@ -272,12 +272,15 @@ export type BaseRangePickerProps = {
|
|
|
272
272
|
calendarLocale?: BasePickerProps['calendarLocale'];
|
|
273
273
|
/**
|
|
274
274
|
* Controls which months are initially displayed in the two-panel calendar view.
|
|
275
|
-
* - `'currentAndNext'`: Shows
|
|
276
|
-
*
|
|
275
|
+
* - `'currentAndNext'`: Shows the value's start month on the left and the next month on the right.
|
|
276
|
+
* When no value is set, shows the current month on the left and next month on the right.
|
|
277
|
+
* - `'previousAndCurrent'`: Shows the month before the value's start month on the left and
|
|
278
|
+
* the value's start month on the right.
|
|
279
|
+
* When no value is set, shows the previous month on the left and current month on the right.
|
|
277
280
|
* Useful for log date range selection where showing future months is not meaningful.
|
|
278
281
|
*
|
|
279
|
-
*
|
|
280
|
-
*
|
|
282
|
+
* When `value`/`defaultValue` spans two different months, the calendar always shows both selected
|
|
283
|
+
* months regardless of this setting.
|
|
281
284
|
*
|
|
282
285
|
* @default 'currentAndNext'
|
|
283
286
|
*
|
|
@@ -285,6 +288,12 @@ export type BaseRangePickerProps = {
|
|
|
285
288
|
* ```tsx
|
|
286
289
|
* // Show previous month + current month for log date selection
|
|
287
290
|
* <DateRangePicker initialDisplayedMonths="previousAndCurrent" />
|
|
291
|
+
*
|
|
292
|
+
* // With a value set: shows February (left) and March (right)
|
|
293
|
+
* <DateRangePicker
|
|
294
|
+
* initialDisplayedMonths="previousAndCurrent"
|
|
295
|
+
* value={[new Date(2024, 2, 1), new Date(2024, 2, 15)]}
|
|
296
|
+
* />
|
|
288
297
|
* ```
|
|
289
298
|
*/
|
|
290
299
|
initialDisplayedMonths?: 'currentAndNext' | 'previousAndCurrent';
|
|
@@ -293,7 +302,7 @@ export type BaseRangePickerProps = {
|
|
|
293
302
|
* Use this when the component operates at a different granularity than months
|
|
294
303
|
* (e.g., MonthRangePicker uses years for panel navigation).
|
|
295
304
|
*
|
|
296
|
-
*
|
|
305
|
+
* Takes the highest priority in the `viewingMonth` computation.
|
|
297
306
|
*
|
|
298
307
|
* @internal
|
|
299
308
|
*/
|
|
@@ -11,6 +11,40 @@ const noop = () => { };
|
|
|
11
11
|
function normalizeToFirstOfMonth(date) {
|
|
12
12
|
return dayjs(date).startOf('month').toDate();
|
|
13
13
|
}
|
|
14
|
+
/**
|
|
15
|
+
* Computes the initial viewing month for the dual-panel calendar.
|
|
16
|
+
*
|
|
17
|
+
* Priority:
|
|
18
|
+
* 1. `initialViewingDate` — explicit internal override (used by MonthRangePicker for year-level navigation)
|
|
19
|
+
* 2. `value`/`defaultValue` spans **different** months → use start month (both selected months visible)
|
|
20
|
+
* 3. `value`/`defaultValue` within a **single** month:
|
|
21
|
+
* - `previousAndCurrent` → start month − 1 month (left panel = month before value, right = value month)
|
|
22
|
+
* - `currentAndNext` → start month (left panel = value month, right = next month)
|
|
23
|
+
* 4. No value → `initialDisplayedMonths` relative to today
|
|
24
|
+
*/
|
|
25
|
+
function computeInitialViewingMonth({ value, defaultValue, initialViewingDate, initialDisplayedMonths, today, }) {
|
|
26
|
+
if (initialViewingDate) {
|
|
27
|
+
return initialViewingDate;
|
|
28
|
+
}
|
|
29
|
+
const rangeStart = value?.[0] ?? defaultValue?.[0];
|
|
30
|
+
const rangeEnd = value?.[1] ?? defaultValue?.[1];
|
|
31
|
+
if (rangeStart) {
|
|
32
|
+
if (rangeEnd && !dayjs(rangeStart).isSame(rangeEnd, 'month')) {
|
|
33
|
+
// Spans different months: show start month on the left
|
|
34
|
+
return rangeStart;
|
|
35
|
+
}
|
|
36
|
+
// Single-month value: apply initialDisplayedMonths
|
|
37
|
+
if (initialDisplayedMonths === 'previousAndCurrent') {
|
|
38
|
+
return dayjs(rangeStart).subtract(1, 'month').toDate();
|
|
39
|
+
}
|
|
40
|
+
return rangeStart;
|
|
41
|
+
}
|
|
42
|
+
// No value: apply initialDisplayedMonths relative to today
|
|
43
|
+
if (initialDisplayedMonths === 'previousAndCurrent') {
|
|
44
|
+
return new Date(today.getFullYear(), today.getMonth() - 1, 1);
|
|
45
|
+
}
|
|
46
|
+
return new Date(today.getFullYear(), today.getMonth(), 1);
|
|
47
|
+
}
|
|
14
48
|
/**
|
|
15
49
|
* Checks if a date is outside the specified constraints
|
|
16
50
|
*
|
|
@@ -73,12 +107,13 @@ const useBaseRangePickerContextValue = ({ value, defaultValue, disabled = false,
|
|
|
73
107
|
const [startDateString, endDateString] = dateStrings;
|
|
74
108
|
// Add viewingMonth state
|
|
75
109
|
const today = useMemo(() => new Date(), []);
|
|
76
|
-
const [viewingMonth, setViewingMonth] = useTransformedState(
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
110
|
+
const [viewingMonth, setViewingMonth] = useTransformedState(computeInitialViewingMonth({
|
|
111
|
+
value,
|
|
112
|
+
defaultValue,
|
|
113
|
+
initialViewingDate,
|
|
114
|
+
initialDisplayedMonths,
|
|
115
|
+
today,
|
|
116
|
+
}), normalizeToFirstOfMonth);
|
|
82
117
|
// --- Selection/Preview State and Logic ---
|
|
83
118
|
const [selecting, setSelecting] = useState('start');
|
|
84
119
|
const [temporaryStart, setTemporaryStart] = useState(startDate);
|
|
@@ -328,7 +328,7 @@ export const SelectBox = forwardRef((props, ref) => {
|
|
|
328
328
|
return (_jsx(Popover, { open: isOptionPanelOpen, targetDOMNode: targetDOMNode, minWidth: popoverContentProps?.minWidth, maxHeight: popoverWrapperProps?.maxHeight, allowedPlacements: popoverContentProps?.allowedPlacements, enableConstrainedContentWidth: enableConstrainedPopoverWidth, renderContent: () => (_jsx("div", { ref: optionPanelRef, id: listBoxId, className: cx(classes.optionPanel, 'mfui-SelectBox__optionPanel', popoverContentProps?.className), tabIndex: -1, onKeyDown: handleKeyDownMenu, children: renderPopoverContent ? (renderPopoverContent({ searchNode, optionsNode })) : (_jsxs(_Fragment, { children: [searchNode, optionsNode] })) })), renderTrigger: ({ setTriggerRef, togglePopover, isPopoverOpen, handleTriggerKeyDown, handleTriggerBlur }) => (_jsxs("div", { ref: setTriggerRef, ...triggerWrapperProps, className: cx(classes.triggerWrapper, 'mfui-SelectBox__triggerWrapper', triggerWrapperProps?.className), children: [_jsx(FocusIndicator, { children: _jsxs("button", { ref: triggerRef, id: id, type: "button", role: "combobox", disabled: disabled, "aria-label": triggerProps?.['aria-label'], "aria-controls": listBoxId, "aria-expanded": isPopoverOpen, "aria-haspopup": "listbox", "aria-invalid": invalid, className: cx(classes.trigger, 'mfui-SelectBox__trigger', triggerProps?.className), "data-placeholder": !!placeholder && !localSelectedOption, "data-selected": !!localSelectedOption, "data-mfui-has-clear-button": showClearButton, onClick: togglePopover, onKeyDown: (event) => {
|
|
329
329
|
handleTypeAhead(event.nativeEvent);
|
|
330
330
|
handleTriggerKeyDown(event);
|
|
331
|
-
}, onBlur: handleTriggerBlur, children: [_jsx("span", { "data-mfui-content": "select-box-trigger-display-value", children: renderTriggerLabel() }), _jsx(DropdownIcon, {}), _jsx("input", { ref: ref, type: "hidden", value: localSelectedOption?.value ?? '', name: name, disabled: disabled })] }) }), showClearButton ? (_jsx("div", { className: cx(classes.clearButtonWrapper, 'mfui-SelectBox__clearButtonWrapper'), children: _jsx(ClearButton, { size: size === 'small' ? 'small' : size === 'large' ? 'large' : 'default', "aria-label": clearButtonProps?.['aria-label'] ?? '値をクリアする', "data-mfui-content": "select-box-clear-button", onClick: (event) => {
|
|
331
|
+
}, onBlur: handleTriggerBlur, children: [_jsx("span", { "data-mfui-content": "select-box-trigger-display-value", children: renderTriggerLabel() }), _jsx(DropdownIcon, { "aria-hidden": "true", focusable: false }), _jsx("input", { ref: ref, type: "hidden", value: localSelectedOption?.value ?? '', name: name, disabled: disabled })] }) }), showClearButton ? (_jsx("div", { className: cx(classes.clearButtonWrapper, 'mfui-SelectBox__clearButtonWrapper'), children: _jsx(ClearButton, { size: size === 'small' ? 'small' : size === 'large' ? 'large' : 'default', "aria-label": clearButtonProps?.['aria-label'] ?? '値をクリアする', "data-mfui-content": "select-box-clear-button", onClick: (event) => {
|
|
332
332
|
event.stopPropagation();
|
|
333
333
|
handleClearValue();
|
|
334
334
|
} }) })) : null] })), contentProps: { className: classes.popover }, enableAutoUnmount: enableAutoUnmount, onOpenStateChanged: toggleOptionPanel, onBlur: onBlur }));
|
package/dist/styles.css
CHANGED
|
@@ -1326,6 +1326,8 @@
|
|
|
1326
1326
|
background-color: var(--mfui-colors-mfui\.color\.neutral\.background\.none);
|
|
1327
1327
|
color: var(--mfui-colors-mfui\.color\.base\.inverted-content\.none);
|
|
1328
1328
|
box-shadow: var(--mfui-shadows-mfui\.elevation\.plus-1\.shadow-1);
|
|
1329
|
+
word-break: break-word;
|
|
1330
|
+
overflow-wrap: break-word;
|
|
1329
1331
|
min-height: 24px;
|
|
1330
1332
|
}
|
|
1331
1333
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@moneyforward/mfui-components",
|
|
3
|
-
"version": "3.13.
|
|
3
|
+
"version": "3.13.1",
|
|
4
4
|
"description": "React UI Component Library for all Money Forward products",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -61,8 +61,8 @@
|
|
|
61
61
|
"@floating-ui/react-dom": "^2.1.2",
|
|
62
62
|
"@tanstack/react-virtual": "^3.13.18",
|
|
63
63
|
"dayjs": "^1.11.13",
|
|
64
|
-
"@moneyforward/mfui-
|
|
65
|
-
"@moneyforward/mfui-
|
|
64
|
+
"@moneyforward/mfui-design-tokens": "^3.1.0",
|
|
65
|
+
"@moneyforward/mfui-icons-react": "^3.1.0"
|
|
66
66
|
},
|
|
67
67
|
"scripts": {
|
|
68
68
|
"prepare:panda": "panda codegen",
|