@moneyforward/mfui-components 3.19.0 → 3.21.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/CheckboxCard/CheckboxCard.js +1 -7
- package/dist/src/DateTimeSelection/DatePicker/DatePicker.js +2 -11
- package/dist/src/DateTimeSelection/DateRangePicker/DateRangePicker.d.ts +1 -1
- package/dist/src/DateTimeSelection/DateRangePicker/DateRangePicker.js +10 -2
- package/dist/src/DateTimeSelection/DateRangePicker/DateRangePicker.types.d.ts +14 -0
- package/dist/src/DateTimeSelection/DateRangePicker/DateRangePickerPopover/DateRangePickerPopover.js +13 -5
- package/dist/src/DateTimeSelection/DateRangePicker/DateRangePickerPopover/utilities/createDateRangePickerPopoverTestUtility.js +2 -2
- package/dist/src/DateTimeSelection/DateRangePicker/DateRangePickerProvider/DateRangePickerProvider.js +11 -12
- package/dist/src/DateTimeSelection/DateRangePicker/DateRangePickerTrigger/hooks/useDateRangeTriggerValueController.js +4 -3
- package/dist/src/DateTimeSelection/DateRangePicker/DateRangePickerTrigger/utilities/createDateRangePickerTriggerTestUtility.js +3 -1
- package/dist/src/DateTimeSelection/FilterDateRangePicker/DateRangePickerContent/DateRangePickerContent.d.ts +6 -0
- package/dist/src/DateTimeSelection/FilterDateRangePicker/DateRangePickerContent/DateRangePickerContent.js +33 -0
- package/dist/src/DateTimeSelection/FilterDateRangePicker/DateRangePickerContent/DateRangePickerContent.types.d.ts +17 -0
- package/dist/src/DateTimeSelection/FilterDateRangePicker/FilterDateRangePicker.d.ts +14 -0
- package/dist/src/DateTimeSelection/FilterDateRangePicker/FilterDateRangePicker.js +42 -0
- package/dist/src/DateTimeSelection/FilterDateRangePicker/FilterDateRangePicker.types.d.ts +78 -0
- package/dist/src/DateTimeSelection/FilterDateRangePicker/FilterDateRangePicker.types.js +1 -0
- package/dist/src/DateTimeSelection/FilterDateRangePicker/index.d.ts +2 -0
- package/dist/src/DateTimeSelection/FilterDateRangePicker/index.js +1 -0
- package/dist/src/DateTimeSelection/FilterMonthPicker/FilterMonthPicker.d.ts +14 -0
- package/dist/src/DateTimeSelection/FilterMonthPicker/FilterMonthPicker.js +75 -0
- package/dist/src/DateTimeSelection/FilterMonthPicker/FilterMonthPicker.types.d.ts +83 -0
- package/dist/src/DateTimeSelection/FilterMonthPicker/FilterMonthPicker.types.js +1 -0
- package/dist/src/DateTimeSelection/FilterMonthPicker/MonthPickerPopover/MonthPickerPopover.d.ts +6 -0
- package/dist/src/DateTimeSelection/FilterMonthPicker/MonthPickerPopover/MonthPickerPopover.js +45 -0
- package/dist/src/DateTimeSelection/FilterMonthPicker/MonthPickerPopover/MonthPickerPopover.types.d.ts +24 -0
- package/dist/src/DateTimeSelection/FilterMonthPicker/MonthPickerPopover/MonthPickerPopover.types.js +1 -0
- package/dist/src/DateTimeSelection/FilterMonthPicker/index.d.ts +2 -0
- package/dist/src/DateTimeSelection/FilterMonthPicker/index.js +1 -0
- package/dist/src/DateTimeSelection/FilterMonthRangePicker/FilterMonthRangePicker.d.ts +15 -0
- package/dist/src/DateTimeSelection/FilterMonthRangePicker/FilterMonthRangePicker.js +89 -0
- package/dist/src/DateTimeSelection/FilterMonthRangePicker/FilterMonthRangePicker.types.d.ts +75 -0
- package/dist/src/DateTimeSelection/FilterMonthRangePicker/FilterMonthRangePicker.types.js +1 -0
- package/dist/src/DateTimeSelection/FilterMonthRangePicker/MonthRangePickerPopover/MonthRangePickerPopover.d.ts +5 -0
- package/dist/src/DateTimeSelection/FilterMonthRangePicker/MonthRangePickerPopover/MonthRangePickerPopover.js +54 -0
- package/dist/src/DateTimeSelection/FilterMonthRangePicker/MonthRangePickerPopover/MonthRangePickerPopover.types.d.ts +19 -0
- package/dist/src/DateTimeSelection/FilterMonthRangePicker/MonthRangePickerPopover/MonthRangePickerPopover.types.js +1 -0
- package/dist/src/DateTimeSelection/FilterMonthRangePicker/index.d.ts +2 -0
- package/dist/src/DateTimeSelection/FilterMonthRangePicker/index.js +1 -0
- package/dist/src/DateTimeSelection/MonthPicker/MonthPicker.d.ts +1 -1
- package/dist/src/DateTimeSelection/MonthPicker/MonthPicker.js +10 -2
- package/dist/src/DateTimeSelection/MonthPicker/MonthPicker.types.d.ts +14 -0
- package/dist/src/DateTimeSelection/MonthPicker/MonthPickerPanel/MonthCell/MonthCell.js +2 -25
- package/dist/src/DateTimeSelection/MonthPicker/MonthPickerPanel/MonthPickerPanel.js +1 -1
- package/dist/src/DateTimeSelection/MonthRangePicker/MonthRangePicker.d.ts +1 -1
- package/dist/src/DateTimeSelection/MonthRangePicker/MonthRangePicker.js +14 -5
- package/dist/src/DateTimeSelection/MonthRangePicker/MonthRangePicker.types.d.ts +21 -0
- package/dist/src/DateTimeSelection/MonthRangePicker/MonthRangePickerMonthCell/MonthRangePickerMonthCell.d.ts +1 -0
- package/dist/src/DateTimeSelection/MonthRangePicker/MonthRangePickerMonthCell/MonthRangePickerMonthCell.js +10 -3
- package/dist/src/DateTimeSelection/MonthRangePicker/MonthRangePickerNavigation/MonthRangePickerNavigation.js +16 -3
- package/dist/src/DateTimeSelection/MonthRangePicker/MonthRangePickerPanel/MonthRangePickerPanel.js +3 -1
- package/dist/src/DateTimeSelection/TimePicker/TimePicker.d.ts +43 -0
- package/dist/src/DateTimeSelection/TimePicker/TimePicker.js +85 -0
- package/dist/src/DateTimeSelection/TimePicker/TimePicker.types.d.ts +61 -0
- package/dist/src/DateTimeSelection/TimePicker/TimePicker.types.js +1 -0
- package/dist/src/DateTimeSelection/TimePicker/constants.d.ts +4 -0
- package/dist/src/DateTimeSelection/TimePicker/constants.js +12 -0
- package/dist/src/DateTimeSelection/TimePicker/index.d.ts +2 -0
- package/dist/src/DateTimeSelection/TimePicker/index.js +1 -0
- package/dist/src/DateTimeSelection/index.d.ts +4 -0
- package/dist/src/DateTimeSelection/index.js +4 -0
- package/dist/src/DateTimeSelection/shared/BaseRangePicker/BaseRangePicker.d.ts +1 -1
- package/dist/src/DateTimeSelection/shared/BaseRangePicker/BaseRangePicker.js +26 -10
- package/dist/src/DateTimeSelection/shared/BaseRangePicker/BaseRangePicker.types.d.ts +19 -0
- package/dist/src/DateTimeSelection/shared/BaseRangePicker/BaseRangePickerProvider/BaseRangePickerProvider.js +40 -19
- package/dist/src/DateTimeSelection/shared/BaseRangePicker/BaseRangePickerProvider/BaseRangePickerProvider.types.d.ts +19 -0
- package/dist/src/DateTimeSelection/shared/BaseRangePicker/BaseRangePickerTrigger/BaseRangePickerTrigger.js +4 -6
- package/dist/src/DateTimeSelection/shared/BaseRangePicker/BaseRangePickerTrigger/hooks/useDateRangeTriggerValueController.js +4 -3
- package/dist/src/DateTimeSelection/shared/CalendarLocale/CalendarLocaleContext.d.ts +1 -1
- package/dist/src/DateTimeSelection/shared/CalendarLocale/CalendarLocaleContext.js +1 -1
- package/dist/src/DateTimeSelection/shared/DayCell/DayCell.js +2 -3
- package/dist/src/DateTimeSelection/shared/MonthGrid/MonthGrid.js +3 -3
- package/dist/src/DateTimeSelection/shared/YearSelector/YearSelector.js +1 -1
- package/dist/src/DateTimeSelection/shared/utilities/dateParsing.js +27 -9
- package/dist/src/DateTimeSelection/shared/utilities/japaneseCalendar.d.ts +36 -8
- package/dist/src/DateTimeSelection/shared/utilities/japaneseCalendar.js +82 -15
- package/dist/src/DateTimeSelection/shared/utilities/monthCellMonthFormat.d.ts +14 -0
- package/dist/src/DateTimeSelection/shared/utilities/monthCellMonthFormat.js +35 -0
- package/dist/src/MultilineTextBox/index.d.ts +10 -2
- package/dist/src/MultilineTextBox/index.js +9 -1
- package/dist/src/MultipleSelectBox/MultipleSelectBoxTrigger/MultipleSelectBoxTrigger.js +1 -3
- package/dist/src/RadioButtonCard/RadioButtonCard.js +1 -7
- package/dist/src/TextBox/TextBox.js +2 -6
- package/dist/src/{MultilineTextBox/MultilineTextBox.d.ts → Textarea/Textarea.d.ts} +5 -2
- package/dist/src/{MultilineTextBox/MultilineTextBox.js → Textarea/Textarea.js} +9 -5
- package/dist/src/{MultilineTextBox/MultilineTextBox.types.d.ts → Textarea/Textarea.types.d.ts} +2 -2
- package/dist/src/Textarea/Textarea.types.js +1 -0
- package/dist/src/Textarea/index.d.ts +2 -0
- package/dist/src/Textarea/index.js +1 -0
- package/dist/src/Tooltip/Tooltip.js +12 -3
- package/dist/src/Typography/Typography.js +1 -3
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.js +1 -0
- package/dist/styled-system/recipes/filter-date-range-picker-slot-recipe.d.ts +33 -0
- package/dist/styled-system/recipes/filter-date-range-picker-slot-recipe.js +48 -0
- package/dist/styled-system/recipes/filter-month-picker-slot-recipe.d.ts +33 -0
- package/dist/styled-system/recipes/filter-month-picker-slot-recipe.js +44 -0
- package/dist/styled-system/recipes/filter-month-range-picker-slot-recipe.d.ts +33 -0
- package/dist/styled-system/recipes/filter-month-range-picker-slot-recipe.js +44 -0
- package/dist/styled-system/recipes/index.d.ts +5 -1
- package/dist/styled-system/recipes/index.js +5 -1
- package/dist/styled-system/recipes/textarea-slot-recipe.d.ts +52 -0
- package/dist/styled-system/recipes/textarea-slot-recipe.js +64 -0
- package/dist/styled-system/recipes/time-picker-slot-recipe.d.ts +44 -0
- package/dist/styled-system/recipes/time-picker-slot-recipe.js +62 -0
- package/dist/styles.css +601 -25
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +13 -11
- package/dist/src/DateTimeSelection/shared/BasePicker/YearSelector/YearSelector.d.ts +0 -18
- package/dist/src/DateTimeSelection/shared/BasePicker/YearSelector/YearSelector.js +0 -36
- package/dist/styled-system/recipes/multiline-text-box-slot-recipe.d.ts +0 -52
- package/dist/styled-system/recipes/multiline-text-box-slot-recipe.js +0 -64
- /package/dist/src/{MultilineTextBox/MultilineTextBox.types.js → DateTimeSelection/FilterDateRangePicker/DateRangePickerContent/DateRangePickerContent.types.js} +0 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { useMemo } from 'react';
|
|
2
2
|
import { dayjs } from '../../../../../utilities/date/dayjs';
|
|
3
|
+
import { parseInputDate } from '../../../utilities/dateParsing';
|
|
3
4
|
import { useBaseRangePickerContext } from '../../BaseRangePickerProvider';
|
|
4
5
|
const createInputProps = (baseProps, value, format, onStringChange, onDateChange, otherDate, isDateDisabled) => ({
|
|
5
6
|
...baseProps,
|
|
@@ -15,12 +16,12 @@ const createInputProps = (baseProps, value, format, onStringChange, onDateChange
|
|
|
15
16
|
if (event.defaultPrevented)
|
|
16
17
|
return;
|
|
17
18
|
baseProps.onBlur?.(event);
|
|
18
|
-
const
|
|
19
|
-
if (!
|
|
19
|
+
const parseResult = parseInputDate(value, format);
|
|
20
|
+
if (!parseResult.isValid || !parseResult.result) {
|
|
20
21
|
onDateChange(undefined, otherDate);
|
|
21
22
|
return;
|
|
22
23
|
}
|
|
23
|
-
const currentDate =
|
|
24
|
+
const currentDate = dayjs(parseResult.result).startOf('day').toDate();
|
|
24
25
|
// Check if the date is disabled due to constraints
|
|
25
26
|
if (isDateDisabled?.(currentDate)) {
|
|
26
27
|
// Clear the input if the date violates constraints
|
|
@@ -5,4 +5,4 @@ export declare function CalendarLocaleProvider({ value, children, }: {
|
|
|
5
5
|
value: CalendarLocaleContextValue;
|
|
6
6
|
children: React.ReactNode;
|
|
7
7
|
}): import("react/jsx-runtime").JSX.Element;
|
|
8
|
-
export declare function useCalendarLocale(): CalendarLocaleContextValue
|
|
8
|
+
export declare function useCalendarLocale(): NonNullable<CalendarLocaleContextValue>;
|
|
@@ -6,5 +6,5 @@ export function CalendarLocaleProvider({ value, children, }) {
|
|
|
6
6
|
return _jsx(CalendarLocaleContext.Provider, { value: value, children: children });
|
|
7
7
|
}
|
|
8
8
|
export function useCalendarLocale() {
|
|
9
|
-
return useContext(CalendarLocaleContext);
|
|
9
|
+
return useContext(CalendarLocaleContext) ?? 'ja';
|
|
10
10
|
}
|
|
@@ -10,8 +10,7 @@ import { useCalendarLocale } from '../CalendarLocale/CalendarLocaleContext';
|
|
|
10
10
|
export function DayCell({ day }) {
|
|
11
11
|
const calendarLocale = useCalendarLocale();
|
|
12
12
|
const classNames = dayCellSlotRecipe();
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
const fullName = DAY_FULL_NAMES[safeLocale][day];
|
|
13
|
+
const abbreviation = DAY_ABBREVIATIONS[calendarLocale][day];
|
|
14
|
+
const fullName = DAY_FULL_NAMES[calendarLocale][day];
|
|
16
15
|
return (_jsx("div", { className: cx(classNames.root, 'mfui-DayCell__root'), "aria-label": fullName, children: _jsx(Typography, { "aria-hidden": true, variant: "contentHeading", className: cx(classNames.label, 'mfui-DayCell__label'), children: abbreviation }) }));
|
|
17
16
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import React, {
|
|
2
|
+
import React, { useLayoutEffect } from 'react';
|
|
3
3
|
import { monthGridSlotRecipe } from '../../../../styled-system/recipes';
|
|
4
4
|
import { cx } from '../../../../styled-system/css';
|
|
5
5
|
/**
|
|
@@ -28,8 +28,8 @@ export function MonthGrid({ year, selectedMonth, minMonth, maxMonth, checkDisabl
|
|
|
28
28
|
const firstTabbableIndex = monthStates.find(({ disabled }) => !disabled)?.month ?? -1;
|
|
29
29
|
return { monthStates, firstTabbableIndex };
|
|
30
30
|
}, [months, year, minMonth, maxMonth, checkDisabledMonth]);
|
|
31
|
-
// Handle pending focus
|
|
32
|
-
|
|
31
|
+
// Handle pending focus before paint so the focused month cell matches keyboard / popover-open flows.
|
|
32
|
+
useLayoutEffect(() => {
|
|
33
33
|
if (!pendingFocusMonth)
|
|
34
34
|
return;
|
|
35
35
|
const targetCell = document.querySelector(`[data-mfui-month="${pendingFocusMonth}"]`);
|
|
@@ -16,7 +16,7 @@ export function YearSelector({ value, onChange, filterYear, triggerProps, trigge
|
|
|
16
16
|
const year = MINIMUM_VIEWABLE_YEAR + i;
|
|
17
17
|
let label;
|
|
18
18
|
if (displayJapaneseCalendar) {
|
|
19
|
-
label = yearToEraLabel(year, calendarLocale
|
|
19
|
+
label = yearToEraLabel(year, calendarLocale);
|
|
20
20
|
}
|
|
21
21
|
else if (calendarLocale === 'ja') {
|
|
22
22
|
label = `${String(year)}年`;
|
|
@@ -20,16 +20,23 @@ export function parseInputDate(inputString, format) {
|
|
|
20
20
|
// Use the refined Japanese era detection from japaneseCalendar utility
|
|
21
21
|
const hasJapaneseEra = isJapaneseEraFormat(inputString);
|
|
22
22
|
if (hasJapaneseEra) {
|
|
23
|
-
//
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
23
|
+
// Skip month-only wareki parsing when the format requires a day component.
|
|
24
|
+
// e.g. "令和7年1月" should not parse for YYYY/MM/DD — the user hasn't typed the day yet.
|
|
25
|
+
const isMonthOnlyEra = inputString.trimEnd().endsWith('月');
|
|
26
|
+
const formatRequiresDay = format.includes('D');
|
|
27
|
+
const shouldTryWareki = !(isMonthOnlyEra && formatRequiresDay);
|
|
28
|
+
if (shouldTryWareki) {
|
|
29
|
+
// Try Japanese calendar parsing for era formats
|
|
30
|
+
try {
|
|
31
|
+
const jpResult = warekiToDate(inputString);
|
|
32
|
+
if (jpResult.isValid) {
|
|
33
|
+
return { isValid: true, result: jpResult.result };
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
// If Japanese calendar parsing fails, fall back to dayjs
|
|
38
|
+
console.warn('Japanese calendar parsing failed:', error);
|
|
28
39
|
}
|
|
29
|
-
}
|
|
30
|
-
catch (error) {
|
|
31
|
-
// If Japanese calendar parsing fails, fall back to dayjs
|
|
32
|
-
console.warn('Japanese calendar parsing failed:', error);
|
|
33
40
|
}
|
|
34
41
|
}
|
|
35
42
|
// Try dayjs parsing for Western calendar format first
|
|
@@ -37,6 +44,17 @@ export function parseInputDate(inputString, format) {
|
|
|
37
44
|
if (dayjsResult.isValid()) {
|
|
38
45
|
return { isValid: true, result: dayjsResult.toDate() };
|
|
39
46
|
}
|
|
47
|
+
// Fall back to single-digit month/day tokens when the format uses two-digit tokens (MM/DD).
|
|
48
|
+
// For example, "2026/6/6" fails with "YYYY/MM/DD" but succeeds with "YYYY/M/D".
|
|
49
|
+
// Strict mode is intentional here: it ensures YYYY matches exactly 4 digits, preventing
|
|
50
|
+
// format-mismatch inputs like "31/12/2023" from accidentally passing via native Date fallback.
|
|
51
|
+
const yyyymdFormat = format.replaceAll(/\bMM\b/g, 'M').replaceAll(/\bDD\b/g, 'D');
|
|
52
|
+
if (yyyymdFormat !== format) {
|
|
53
|
+
const yyyymdResult = dayjs(inputString, yyyymdFormat, true);
|
|
54
|
+
if (yyyymdResult.isValid()) {
|
|
55
|
+
return { isValid: true, result: yyyymdResult.toDate() };
|
|
56
|
+
}
|
|
57
|
+
}
|
|
40
58
|
// Fall back to YYYYMMDD format (8-digit number without delimiters) if the specified format fails
|
|
41
59
|
// This allows inputs like "20251215" to be parsed even when format is "YYYY-MM-DD"
|
|
42
60
|
if (/^\d{8}$/.test(inputString)) {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
declare const REIWA
|
|
2
|
-
declare const HEISEI
|
|
3
|
-
declare const SHOWA
|
|
4
|
-
declare const TAISHO
|
|
5
|
-
declare const MEIJI
|
|
1
|
+
declare const REIWA = "\u4EE4\u548C";
|
|
2
|
+
declare const HEISEI = "\u5E73\u6210";
|
|
3
|
+
declare const SHOWA = "\u662D\u548C";
|
|
4
|
+
declare const TAISHO = "\u5927\u6B63";
|
|
5
|
+
declare const MEIJI = "\u660E\u6CBB";
|
|
6
6
|
type Geongo = typeof REIWA | typeof HEISEI | typeof SHOWA | typeof TAISHO | typeof MEIJI;
|
|
7
7
|
declare const WAREKI_START_YEARS: {
|
|
8
8
|
readonly r: 2019;
|
|
@@ -64,13 +64,41 @@ export declare function isJapaneseEraFormat(inputString: string): boolean;
|
|
|
64
64
|
export declare function yearToEraLabel(year: number, locale: 'ja' | 'en'): string;
|
|
65
65
|
/**
|
|
66
66
|
* Formats a Date to a short English era string for display in the DatePicker trigger input.
|
|
67
|
-
* Format: "{EraName} {eraYear}/{
|
|
68
|
-
* For pre-Meiji dates (year < 1868): falls back to the Gregorian year (e.g., "1867/
|
|
67
|
+
* Format: "{EraName} {eraYear}/{MM}/{DD}" (e.g., "Reiwa 7/03/06").
|
|
68
|
+
* For pre-Meiji dates (year < 1868): falls back to the Gregorian year (e.g., "1867/03/06").
|
|
69
69
|
*
|
|
70
70
|
* @param date - The date to format
|
|
71
71
|
*
|
|
72
|
-
* @returns Short English era string (e.g., "Reiwa 7/
|
|
72
|
+
* @returns Short English era string (e.g., "Reiwa 7/03/06")
|
|
73
73
|
*/
|
|
74
74
|
export declare function dateToEnglishEraShort(date: Date): string;
|
|
75
|
+
/**
|
|
76
|
+
* Formats a Date to a short English era string for display in the MonthPicker trigger input.
|
|
77
|
+
* Format: "{EraName} {eraYear}/{MM}" (e.g., "Reiwa 7/03").
|
|
78
|
+
* For pre-Meiji dates (year < 1868): falls back to the Gregorian year (e.g., "1867/03").
|
|
79
|
+
*
|
|
80
|
+
* @param date - The date to format
|
|
81
|
+
*
|
|
82
|
+
* @returns Short English era month string (e.g., "Reiwa 7/03")
|
|
83
|
+
*/
|
|
84
|
+
export declare function dateToEnglishEraMonthShort(date: Date): string;
|
|
85
|
+
/**
|
|
86
|
+
* Formats a Date to a Japanese-era string with day precision (e.g., "令和7年3月6日").
|
|
87
|
+
* Uses the platform's built-in `ja-JP-u-ca-japanese` calendar.
|
|
88
|
+
*
|
|
89
|
+
* @param date - The date to format
|
|
90
|
+
*
|
|
91
|
+
* @returns Japanese era string with day (e.g., "令和7年3月6日")
|
|
92
|
+
*/
|
|
93
|
+
export declare function dateToJapaneseEra(date: Date): string;
|
|
94
|
+
/**
|
|
95
|
+
* Formats a Date to a Japanese-era string with month precision (e.g., "令和7年3月").
|
|
96
|
+
* Uses the platform's built-in `ja-JP-u-ca-japanese` calendar.
|
|
97
|
+
*
|
|
98
|
+
* @param date - The date to format
|
|
99
|
+
*
|
|
100
|
+
* @returns Japanese era month string (e.g., "令和7年3月")
|
|
101
|
+
*/
|
|
102
|
+
export declare function dateToJapaneseEraMonth(date: Date): string;
|
|
75
103
|
export { warekiReg, dateToWareki, fullWidthToHalfWidth, selectGengo, WAREKI_START_YEARS };
|
|
76
104
|
export type { WarekiResult };
|
|
@@ -38,8 +38,8 @@ const WAREKI_START_YEARS = {
|
|
|
38
38
|
const warekiReg = {
|
|
39
39
|
// Western calendar: supports full-width numbers and flexible separators
|
|
40
40
|
dateString: new RegExp(String.raw `^([0-90-9]{4})${WESTERN_SEPARATOR}([0-90-9]{1,2})${WESTERN_SEPARATOR}([0-90-9]{1,2})(?:[\s.]([0-90-9]{2}):([0-90-9]{2}))?$`),
|
|
41
|
-
// Japanese era: supports
|
|
42
|
-
wareki: new RegExp(String.raw `^(${Object.keys(WAREKI_START_YEARS).join('|')})(元|[0-90-9]{1,2})(?:年([0-90-9]{1,2})月([0-90-9]{1,2})日|[./-]([0-90-9]{1,2})[./-]([0-90-9]{1,2}))$`),
|
|
41
|
+
// Japanese era: supports traditional (H12年2月12日), Western-style (H12.2.12), and month-only (H12年2月) formats
|
|
42
|
+
wareki: new RegExp(String.raw `^(${Object.keys(WAREKI_START_YEARS).join('|')})(元|[0-90-9]{1,2})(?:年([0-90-9]{1,2})月([0-90-9]{1,2})日|[./-]([0-90-9]{1,2})[./-]([0-90-9]{1,2})|年([0-90-9]{1,2})月)$`),
|
|
43
43
|
// Era detection for both traditional and Western-style formats
|
|
44
44
|
eraDetection: /^(?:令和|平成|昭和|大正|明治|[rhstmRHSTM])(?:元|[0-90-9]{1,2})(?:年|[./-])/,
|
|
45
45
|
};
|
|
@@ -137,11 +137,12 @@ export function warekiToDate(wareki) {
|
|
|
137
137
|
const baseYear = WAREKI_START_YEARS[matchedWareki[1]];
|
|
138
138
|
// Handle "元" (first year) and regular years
|
|
139
139
|
const eraYear = matchedWareki[2] === '元' ? 1 : Number(matchedWareki[2]);
|
|
140
|
-
// Handle
|
|
140
|
+
// Handle traditional (年月日), Western-style (./- separators), and month-only (年月) formats
|
|
141
141
|
// Traditional format: groups 3,4 (month, day)
|
|
142
142
|
// Western format: groups 5,6 (month, day)
|
|
143
|
-
|
|
144
|
-
const
|
|
143
|
+
// Month-only format: group 7 (month), day defaults to 1
|
|
144
|
+
const month = Number(matchedWareki[3] || matchedWareki[5] || matchedWareki[7]);
|
|
145
|
+
const day = matchedWareki[7] !== undefined ? 1 : Number(matchedWareki[4] || matchedWareki[6]);
|
|
145
146
|
// Validation: ensure era year is reasonable (1-200 years per era)
|
|
146
147
|
if (eraYear < 1 || eraYear > 200) {
|
|
147
148
|
return {
|
|
@@ -240,24 +241,90 @@ export function yearToEraLabel(year, locale) {
|
|
|
240
241
|
return `${gengo}${eraYear === 1 ? '元' : String(eraYear)}年`;
|
|
241
242
|
}
|
|
242
243
|
/**
|
|
243
|
-
*
|
|
244
|
-
*
|
|
245
|
-
* For pre-Meiji dates (year < 1868): falls back to the Gregorian year (e.g., "1867/12/25").
|
|
244
|
+
* Internal helper used by `dateToEnglishEraShort` and `dateToEnglishEraMonthShort`.
|
|
245
|
+
* Pre-Meiji dates (year < 1868) fall back to the Gregorian year.
|
|
246
246
|
*
|
|
247
247
|
* @param date - The date to format
|
|
248
248
|
*
|
|
249
|
-
* @
|
|
249
|
+
* @param options - Format options. `includeDay: true` produces "{Era} {Y}/{MM}/{DD}";
|
|
250
|
+
* `includeDay: false` produces "{Era} {Y}/{MM}" and resolves the era using day 1.
|
|
251
|
+
*
|
|
252
|
+
* @returns Formatted English era string
|
|
250
253
|
*/
|
|
251
|
-
|
|
254
|
+
function dateToEnglishEra(date, { includeDay }) {
|
|
252
255
|
const year = date.getFullYear();
|
|
253
|
-
const
|
|
254
|
-
const
|
|
256
|
+
const monthNum = date.getMonth() + 1;
|
|
257
|
+
const dayNum = date.getDate();
|
|
258
|
+
const month = String(monthNum).padStart(2, '0');
|
|
259
|
+
const daySuffix = includeDay ? `/${String(dayNum).padStart(2, '0')}` : '';
|
|
255
260
|
if (year < MEIJI_START_YEAR) {
|
|
256
|
-
return `${String(year)}/${
|
|
261
|
+
return `${String(year)}/${month}${daySuffix}`;
|
|
257
262
|
}
|
|
258
|
-
|
|
263
|
+
// Month-only outputs resolve the era using day 1, which means the transition month
|
|
264
|
+
// keeps the older era label (e.g., Dec 1926 → Taisho 15/12, not Showa 1/12).
|
|
265
|
+
const gengo = selectGengo(year, monthNum, includeDay ? dayNum : 1);
|
|
259
266
|
const eraYear = year - WAREKI_START_YEARS[gengo] + 1;
|
|
260
|
-
return `${ERA_NAMES_EN[gengo]} ${String(eraYear)}/${
|
|
267
|
+
return `${ERA_NAMES_EN[gengo]} ${String(eraYear)}/${month}${daySuffix}`;
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Formats a Date to a short English era string for display in the DatePicker trigger input.
|
|
271
|
+
* Format: "{EraName} {eraYear}/{MM}/{DD}" (e.g., "Reiwa 7/03/06").
|
|
272
|
+
* For pre-Meiji dates (year < 1868): falls back to the Gregorian year (e.g., "1867/03/06").
|
|
273
|
+
*
|
|
274
|
+
* @param date - The date to format
|
|
275
|
+
*
|
|
276
|
+
* @returns Short English era string (e.g., "Reiwa 7/03/06")
|
|
277
|
+
*/
|
|
278
|
+
export function dateToEnglishEraShort(date) {
|
|
279
|
+
return dateToEnglishEra(date, { includeDay: true });
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Formats a Date to a short English era string for display in the MonthPicker trigger input.
|
|
283
|
+
* Format: "{EraName} {eraYear}/{MM}" (e.g., "Reiwa 7/03").
|
|
284
|
+
* For pre-Meiji dates (year < 1868): falls back to the Gregorian year (e.g., "1867/03").
|
|
285
|
+
*
|
|
286
|
+
* @param date - The date to format
|
|
287
|
+
*
|
|
288
|
+
* @returns Short English era month string (e.g., "Reiwa 7/03")
|
|
289
|
+
*/
|
|
290
|
+
export function dateToEnglishEraMonthShort(date) {
|
|
291
|
+
return dateToEnglishEra(date, { includeDay: false });
|
|
292
|
+
}
|
|
293
|
+
// Cached Intl formatters for the Japanese era (wareki) — module-level so the
|
|
294
|
+
// formatter instances are reused across components instead of being created
|
|
295
|
+
// inside each `useMemo`.
|
|
296
|
+
const japaneseEraDateFormatter = new Intl.DateTimeFormat('ja-JP-u-ca-japanese', {
|
|
297
|
+
era: 'long',
|
|
298
|
+
year: 'numeric',
|
|
299
|
+
month: 'narrow',
|
|
300
|
+
day: 'numeric',
|
|
301
|
+
});
|
|
302
|
+
const japaneseEraMonthFormatter = new Intl.DateTimeFormat('ja-JP-u-ca-japanese', {
|
|
303
|
+
era: 'long',
|
|
304
|
+
year: 'numeric',
|
|
305
|
+
month: 'narrow',
|
|
306
|
+
});
|
|
307
|
+
/**
|
|
308
|
+
* Formats a Date to a Japanese-era string with day precision (e.g., "令和7年3月6日").
|
|
309
|
+
* Uses the platform's built-in `ja-JP-u-ca-japanese` calendar.
|
|
310
|
+
*
|
|
311
|
+
* @param date - The date to format
|
|
312
|
+
*
|
|
313
|
+
* @returns Japanese era string with day (e.g., "令和7年3月6日")
|
|
314
|
+
*/
|
|
315
|
+
export function dateToJapaneseEra(date) {
|
|
316
|
+
return japaneseEraDateFormatter.format(date);
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* Formats a Date to a Japanese-era string with month precision (e.g., "令和7年3月").
|
|
320
|
+
* Uses the platform's built-in `ja-JP-u-ca-japanese` calendar.
|
|
321
|
+
*
|
|
322
|
+
* @param date - The date to format
|
|
323
|
+
*
|
|
324
|
+
* @returns Japanese era month string (e.g., "令和7年3月")
|
|
325
|
+
*/
|
|
326
|
+
export function dateToJapaneseEraMonth(date) {
|
|
327
|
+
return japaneseEraMonthFormatter.format(date);
|
|
261
328
|
}
|
|
262
329
|
// Export the utility functions and constants
|
|
263
330
|
export { warekiReg, dateToWareki, fullWidthToHalfWidth, selectGengo, WAREKI_START_YEARS };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type BasePickerProps } from '../BasePicker/BasePicker.types';
|
|
2
|
+
/**
|
|
3
|
+
* dayjs format string for the visible month label in {@link MonthCell} (`monthLabel`),
|
|
4
|
+
* based on calendar locale (Japanese `M月` vs English three-letter abbreviations).
|
|
5
|
+
*
|
|
6
|
+
* @param calendarLocale - The calendar locale (`'ja'` or `'en'`) — selects between
|
|
7
|
+
* Japanese (`M月`) and English (`[Jan]`–`[Dec]`) abbreviations
|
|
8
|
+
*
|
|
9
|
+
* @param date - The date whose month index selects the English abbreviation.
|
|
10
|
+
* Only consulted when `calendarLocale === 'en'`.
|
|
11
|
+
*
|
|
12
|
+
* @returns A dayjs-compatible format string for the month label
|
|
13
|
+
*/
|
|
14
|
+
export declare function getMonthCellMonthFormat(calendarLocale: BasePickerProps['calendarLocale'], date: Date): string;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// English month abbreviations wrapped in square brackets to escape them in dayjs format strings
|
|
2
|
+
const ENGLISH_MONTH_ABBREVIATIONS = [
|
|
3
|
+
'[Jan]',
|
|
4
|
+
'[Feb]',
|
|
5
|
+
'[Mar]',
|
|
6
|
+
'[Apr]',
|
|
7
|
+
'[May]',
|
|
8
|
+
'[Jun]',
|
|
9
|
+
'[Jul]',
|
|
10
|
+
'[Aug]',
|
|
11
|
+
'[Sep]',
|
|
12
|
+
'[Oct]',
|
|
13
|
+
'[Nov]',
|
|
14
|
+
'[Dec]',
|
|
15
|
+
];
|
|
16
|
+
/**
|
|
17
|
+
* dayjs format string for the visible month label in {@link MonthCell} (`monthLabel`),
|
|
18
|
+
* based on calendar locale (Japanese `M月` vs English three-letter abbreviations).
|
|
19
|
+
*
|
|
20
|
+
* @param calendarLocale - The calendar locale (`'ja'` or `'en'`) — selects between
|
|
21
|
+
* Japanese (`M月`) and English (`[Jan]`–`[Dec]`) abbreviations
|
|
22
|
+
*
|
|
23
|
+
* @param date - The date whose month index selects the English abbreviation.
|
|
24
|
+
* Only consulted when `calendarLocale === 'en'`.
|
|
25
|
+
*
|
|
26
|
+
* @returns A dayjs-compatible format string for the month label
|
|
27
|
+
*/
|
|
28
|
+
export function getMonthCellMonthFormat(calendarLocale, date) {
|
|
29
|
+
if (calendarLocale === 'en') {
|
|
30
|
+
// Date.getMonth() always returns 0–11, so the array access is safe.
|
|
31
|
+
const monthIndex = date.getMonth();
|
|
32
|
+
return ENGLISH_MONTH_ABBREVIATIONS[monthIndex];
|
|
33
|
+
}
|
|
34
|
+
return 'M月';
|
|
35
|
+
}
|
|
@@ -1,2 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* MultilineTextBox backward compatibility re-exports.
|
|
3
|
+
*
|
|
4
|
+
* MultilineTextBox has been renamed to Textarea.
|
|
5
|
+
* Please migrate to Textarea. MultilineTextBox will be removed in a future major version (v5.0.0).
|
|
6
|
+
*
|
|
7
|
+
* @see Textarea
|
|
8
|
+
*/
|
|
9
|
+
export { Textarea as MultilineTextBox } from '../Textarea';
|
|
10
|
+
export type { TextareaProps as MultilineTextBoxProps } from '../Textarea';
|
|
@@ -1 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* MultilineTextBox backward compatibility re-exports.
|
|
3
|
+
*
|
|
4
|
+
* MultilineTextBox has been renamed to Textarea.
|
|
5
|
+
* Please migrate to Textarea. MultilineTextBox will be removed in a future major version (v5.0.0).
|
|
6
|
+
*
|
|
7
|
+
* @see Textarea
|
|
8
|
+
*/
|
|
9
|
+
export { Textarea as MultilineTextBox } from '../Textarea';
|
|
@@ -48,8 +48,6 @@ placeholder, renderDisplayValue, updateSelectedValues, clearButtonProps, disable
|
|
|
48
48
|
.map((option) => option.value)
|
|
49
49
|
.filter((v) => v != null)
|
|
50
50
|
.map(String);
|
|
51
|
-
return (
|
|
52
|
-
// use div element instead of button element to prevent the nested button element when the selected options are rendered as tag list
|
|
53
|
-
_jsx(FocusIndicator, { children: _jsxs("div", { ref: wrapperRef, className: cx(classes.wrapper, 'mfui-MultipleSelectBoxTrigger__wrapper', triggerWrapperProps?.className), children: [_jsx("button", { ref: mergeRefs(ref, triggerRef), type: "button", role: "combobox", "aria-controls": listBoxId, "aria-expanded": isOptionPanelOpen, "aria-haspopup": "listbox", "aria-invalid": invalid, value: selectedValues, disabled: disabled, onKeyDown: onKeyDown, onBlur: onBlur, ...rest, ...triggerProps, className: cx(classes.trigger, 'mfui-MultipleSelectBoxTrigger__trigger', triggerProps?.className) }), _jsx("input", { type: "hidden", name: name, value: selectedValues }), _jsx("div", { className: cx(classes.displayValues, 'mfui-MultipleSelectBoxTrigger__displayValues'), "data-mfui-content": "multiple-select-box-trigger-display-values", children: renderer() }), selectedOptions.length > 0 && !disabled && !disableClearButton ? (_jsx("div", { className: cx(classes.clearButtonContainer, 'mfui-MultipleSelectBoxTrigger__clearButtonContainer'), children: _jsx(ClearButton, { size: size === 'small' ? 'small' : 'default', className: cx(classes.clearButton, 'mfui-MultipleSelectBoxTrigger__clearButton'), "aria-label": clearButtonProps?.['aria-label'] ?? '値をクリアする', "data-mfui-content": "multiple-select-box-clear-button", onClick: handleClearValue }) })) : null, _jsx("div", { className: cx(classes.dropdownIconContainer, 'mfui-MultipleSelectBoxTrigger__dropdownIconContainer'), children: _jsx(DropdownIcon, { className: cx(classes.dropdownIcon, 'mfui-MultipleSelectBoxTrigger__dropdownIcon') }) })] }) }));
|
|
51
|
+
return (_jsx(FocusIndicator, { children: _jsxs("div", { ref: wrapperRef, className: cx(classes.wrapper, 'mfui-MultipleSelectBoxTrigger__wrapper', triggerWrapperProps?.className), children: [_jsx("button", { ref: mergeRefs(ref, triggerRef), type: "button", role: "combobox", "aria-controls": listBoxId, "aria-expanded": isOptionPanelOpen, "aria-haspopup": "listbox", "aria-invalid": invalid, value: selectedValues, disabled: disabled, onKeyDown: onKeyDown, onBlur: onBlur, ...rest, ...triggerProps, className: cx(classes.trigger, 'mfui-MultipleSelectBoxTrigger__trigger', triggerProps?.className) }), _jsx("input", { type: "hidden", name: name, value: selectedValues }), _jsx("div", { className: cx(classes.displayValues, 'mfui-MultipleSelectBoxTrigger__displayValues'), "data-mfui-content": "multiple-select-box-trigger-display-values", children: renderer() }), selectedOptions.length > 0 && !disabled && !disableClearButton ? (_jsx("div", { className: cx(classes.clearButtonContainer, 'mfui-MultipleSelectBoxTrigger__clearButtonContainer'), children: _jsx(ClearButton, { size: size === 'small' ? 'small' : 'default', className: cx(classes.clearButton, 'mfui-MultipleSelectBoxTrigger__clearButton'), "aria-label": clearButtonProps?.['aria-label'] ?? '値をクリアする', "data-mfui-content": "multiple-select-box-clear-button", onClick: handleClearValue }) })) : null, _jsx("div", { className: cx(classes.dropdownIconContainer, 'mfui-MultipleSelectBoxTrigger__dropdownIconContainer'), children: _jsx(DropdownIcon, { className: cx(classes.dropdownIcon, 'mfui-MultipleSelectBoxTrigger__dropdownIcon') }) })] }) }));
|
|
54
52
|
}
|
|
55
53
|
export const MultipleSelectBoxTrigger = forwardRef(MultipleSelectBoxTriggerInner);
|
|
@@ -28,11 +28,5 @@ export const RadioButtonCard = forwardRef(({ label, layout = 'vertical', renderD
|
|
|
28
28
|
disableResponsive,
|
|
29
29
|
isResponsive: Boolean(responsiveSlot.narrowViewport),
|
|
30
30
|
});
|
|
31
|
-
return (_jsxs("div", { className: cx(classes.root, 'mfui-RadioButtonCard__root', className), children: [_jsx(FocusIndicator, { disableNestedFocus: true, children: _jsxs(Typography, { variant: "label", className: cx(classes.inputWrapper, 'mfui-RadioButtonCard__inputWrapper'), as: "label", htmlFor: props.id, children: [_jsx(RadioButton, { ref: ref, ...props, className: cx(classes.input, 'mfui-RadioButtonCard__input') }), _jsx("span", { className: cx(classes.label, 'mfui-RadioButtonCard__label'), children: label })] }) }), responsiveSlot.narrowViewport && disableResponsive ? (
|
|
32
|
-
/* When responsive is disabled, render single element but with both contents using CSS for switching */
|
|
33
|
-
_jsxs(_Fragment, { children: [_jsx("div", { "data-mfui-content": "details", className: cx(classes.details, classes.detailsWide, 'mfui-RadioButtonCard__details'), children: responsiveSlot.base(radioButtonState) }), _jsx("div", { "data-mfui-content": "details", className: cx(classes.details, classes.detailsNarrow, 'mfui-RadioButtonCard__details'), children: responsiveSlot.narrowViewport(radioButtonState) })] })) : responsiveSlot.narrowViewport ? (
|
|
34
|
-
/* When responsive is enabled, render separate wide/narrow elements */
|
|
35
|
-
_jsxs(_Fragment, { children: [_jsx("div", { "data-mfui-content": "details", className: cx(classes.details, classes.detailsWide, 'mfui-RadioButtonCard__details'), children: responsiveSlot.base(radioButtonState) }), _jsx("div", { "data-mfui-content": "details", className: cx(classes.details, classes.detailsNarrow, 'mfui-RadioButtonCard__details'), children: responsiveSlot.narrowViewport(radioButtonState) })] })) : responsiveSlot.base ? (
|
|
36
|
-
/* For function-based renderDetailsSlot or ResponsiveSlot with only base, use single details element */
|
|
37
|
-
_jsx("div", { "data-mfui-content": "details", className: cx(classes.details, 'mfui-RadioButtonCard__details'), children: responsiveSlot.base(radioButtonState) })) : null] }));
|
|
31
|
+
return (_jsxs("div", { className: cx(classes.root, 'mfui-RadioButtonCard__root', className), children: [_jsx(FocusIndicator, { disableNestedFocus: true, children: _jsxs(Typography, { variant: "label", className: cx(classes.inputWrapper, 'mfui-RadioButtonCard__inputWrapper'), as: "label", htmlFor: props.id, children: [_jsx(RadioButton, { ref: ref, ...props, className: cx(classes.input, 'mfui-RadioButtonCard__input') }), _jsx("span", { className: cx(classes.label, 'mfui-RadioButtonCard__label'), children: label })] }) }), responsiveSlot.narrowViewport && disableResponsive ? (_jsxs(_Fragment, { children: [_jsx("div", { "data-mfui-content": "details", className: cx(classes.details, classes.detailsWide, 'mfui-RadioButtonCard__details'), children: responsiveSlot.base(radioButtonState) }), _jsx("div", { "data-mfui-content": "details", className: cx(classes.details, classes.detailsNarrow, 'mfui-RadioButtonCard__details'), children: responsiveSlot.narrowViewport(radioButtonState) })] })) : responsiveSlot.narrowViewport ? (_jsxs(_Fragment, { children: [_jsx("div", { "data-mfui-content": "details", className: cx(classes.details, classes.detailsWide, 'mfui-RadioButtonCard__details'), children: responsiveSlot.base(radioButtonState) }), _jsx("div", { "data-mfui-content": "details", className: cx(classes.details, classes.detailsNarrow, 'mfui-RadioButtonCard__details'), children: responsiveSlot.narrowViewport(radioButtonState) })] })) : responsiveSlot.base ? (_jsx("div", { "data-mfui-content": "details", className: cx(classes.details, 'mfui-RadioButtonCard__details'), children: responsiveSlot.base(radioButtonState) })) : null] }));
|
|
38
32
|
});
|
|
@@ -41,11 +41,7 @@ export const TextBox = forwardRef(({ enableClearButton = false, onClear, invalid
|
|
|
41
41
|
}, [onClear, shouldUseTouchDeviceMode]);
|
|
42
42
|
// Get the display value for touch device mode
|
|
43
43
|
const displayValue = (inputProps.value ?? inputProps.defaultValue ?? '');
|
|
44
|
-
return shouldUseTouchDeviceMode ? (
|
|
45
|
-
// Touch device: wrapper + hidden input + display div
|
|
46
|
-
_jsxs("div", { ...wrapperProps, className: cx(classes.root, 'mfui-TextBox__root', wrapperProps.className), children: [_jsx("input", { type: "hidden", value: displayValue, name: inputProps.name }), prefixSlot ? _jsx("div", { className: cx(classes.prefix, 'mfui-TextBox__prefix'), children: prefixSlot }) : null, _jsx("div", { className: cx(classes.input, 'mfui-TextBox__input'), children: displayValue || inputProps.placeholder }), shouldShowClearButton ? (_jsx(ClearButton, { size: textBoxSize === 'small' ? 'small' : textBoxSize === 'large' ? 'large' : 'default', "aria-label": clearButtonProps?.['aria-label'] ?? '値をクリアする', className: cx(classes.clearButton, 'mfui-TextBox__clearButton'), disabled: disabled, onClick: (event) => {
|
|
44
|
+
return shouldUseTouchDeviceMode ? (_jsxs("div", { ...wrapperProps, className: cx(classes.root, 'mfui-TextBox__root', wrapperProps.className), children: [_jsx("input", { type: "hidden", value: displayValue, name: inputProps.name }), prefixSlot ? _jsx("div", { className: cx(classes.prefix, 'mfui-TextBox__prefix'), children: prefixSlot }) : null, _jsx("div", { className: cx(classes.input, 'mfui-TextBox__input'), children: displayValue || inputProps.placeholder }), shouldShowClearButton ? (_jsx(ClearButton, { size: textBoxSize === 'small' ? 'small' : textBoxSize === 'large' ? 'large' : 'default', "aria-label": clearButtonProps?.['aria-label'] ?? '値をクリアする', className: cx(classes.clearButton, 'mfui-TextBox__clearButton'), disabled: disabled, onClick: (event) => {
|
|
47
45
|
onClear?.(event);
|
|
48
|
-
} })) : null, suffixSlot ? _jsx("div", { className: cx(classes.suffix, 'mfui-TextBox__suffix'), children: suffixSlot }) : null] })) : (
|
|
49
|
-
// Desktop: Standard input with FocusIndicator
|
|
50
|
-
_jsx(FocusIndicator, { children: _jsxs("div", { ...wrapperProps, className: cx(classes.root, 'mfui-TextBox__root', wrapperProps.className), children: [prefixSlot ? _jsx("div", { className: cx(classes.prefix, 'mfui-TextBox__prefix'), children: prefixSlot }) : null, _jsx("input", { ref: mergedInputRef, disabled: disabled, ...inputProps, className: cx(classes.input, 'mfui-TextBox__input', inputProps.className), onChange: handleChange, onInput: handleInput }), shouldShowClearButton ? (_jsx(ClearButton, { size: textBoxSize === 'small' ? 'small' : textBoxSize === 'large' ? 'large' : 'default', "aria-label": clearButtonProps?.['aria-label'] ?? '値をクリアする', className: cx(classes.clearButton, 'mfui-TextBox__clearButton'), disabled: disabled, onClick: onClickClear })) : null, suffixSlot ? _jsx("div", { className: cx(classes.suffix, 'mfui-TextBox__suffix'), children: suffixSlot }) : null] }) }));
|
|
46
|
+
} })) : null, suffixSlot ? _jsx("div", { className: cx(classes.suffix, 'mfui-TextBox__suffix'), children: suffixSlot }) : null] })) : (_jsx(FocusIndicator, { children: _jsxs("div", { ...wrapperProps, className: cx(classes.root, 'mfui-TextBox__root', wrapperProps.className), children: [prefixSlot ? _jsx("div", { className: cx(classes.prefix, 'mfui-TextBox__prefix'), children: prefixSlot }) : null, _jsx("input", { ref: mergedInputRef, disabled: disabled, ...inputProps, className: cx(classes.input, 'mfui-TextBox__input', inputProps.className), onChange: handleChange, onInput: handleInput }), shouldShowClearButton ? (_jsx(ClearButton, { size: textBoxSize === 'small' ? 'small' : textBoxSize === 'large' ? 'large' : 'default', "aria-label": clearButtonProps?.['aria-label'] ?? '値をクリアする', className: cx(classes.clearButton, 'mfui-TextBox__clearButton'), disabled: disabled, onClick: onClickClear })) : null, suffixSlot ? _jsx("div", { className: cx(classes.suffix, 'mfui-TextBox__suffix'), children: suffixSlot }) : null] }) }));
|
|
51
47
|
});
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The general-purpose
|
|
2
|
+
* The general-purpose Textarea component.
|
|
3
3
|
* This component switches the variants of looks and behaviors depends on the props: size, invalid, disabled.
|
|
4
4
|
*
|
|
5
5
|
* Also extends the props of `<textarea>` element
|
|
6
6
|
*
|
|
7
|
+
* > **Migration note**: `MultilineTextBox` has been renamed to `Textarea`.
|
|
8
|
+
* > Please migrate to `Textarea`. `MultilineTextBox` will be removed in a future major version (v5.0.0).
|
|
9
|
+
*
|
|
7
10
|
* @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea
|
|
8
11
|
*/
|
|
9
|
-
export declare const
|
|
12
|
+
export declare const Textarea: import("react").ForwardRefExoticComponent<{
|
|
10
13
|
invalid?: import("../../styled-system/recipes").TextBoxSlotRecipeVariant["invalid"];
|
|
11
14
|
size?: import("../../styled-system/recipes").TextBoxSlotRecipeVariant["size"];
|
|
12
15
|
disabled?: import("../../styled-system/recipes").TextBoxSlotRecipeVariant["disabled"];
|
|
@@ -1,22 +1,25 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { forwardRef, useRef, useCallback, useEffect } from 'react';
|
|
3
3
|
import { cx } from '../../styled-system/css';
|
|
4
|
-
import {
|
|
4
|
+
import { textareaSlotRecipe } from '../../styled-system/recipes';
|
|
5
5
|
import { FocusIndicator } from '../FocusIndicator';
|
|
6
6
|
import { mergeRefs } from '../utilities/dom/mergeRefs';
|
|
7
7
|
/**
|
|
8
|
-
* The general-purpose
|
|
8
|
+
* The general-purpose Textarea component.
|
|
9
9
|
* This component switches the variants of looks and behaviors depends on the props: size, invalid, disabled.
|
|
10
10
|
*
|
|
11
11
|
* Also extends the props of `<textarea>` element
|
|
12
12
|
*
|
|
13
|
+
* > **Migration note**: `MultilineTextBox` has been renamed to `Textarea`.
|
|
14
|
+
* > Please migrate to `Textarea`. `MultilineTextBox` will be removed in a future major version (v5.0.0).
|
|
15
|
+
*
|
|
13
16
|
* @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea
|
|
14
17
|
*/
|
|
15
|
-
export const
|
|
18
|
+
export const Textarea = forwardRef(({ invalid = false, size = 'medium', disabled = false, rows = 1, enableAutoResize = false, resize = 'both', onChange, ...props }, ref) => {
|
|
16
19
|
const localRef = useRef(null);
|
|
17
20
|
// When enableAutoResize is true, force resize to 'none' to prevent conflicts
|
|
18
21
|
const effectiveResize = enableAutoResize ? 'none' : resize;
|
|
19
|
-
const classes =
|
|
22
|
+
const classes = textareaSlotRecipe({ size, disabled, invalid, enableAutoResize, resize: effectiveResize });
|
|
20
23
|
const adjustHeight = useCallback(() => {
|
|
21
24
|
if (!enableAutoResize || !localRef.current)
|
|
22
25
|
return;
|
|
@@ -47,5 +50,6 @@ export const MultilineTextBox = forwardRef(({ invalid = false, size = 'medium',
|
|
|
47
50
|
adjustHeight();
|
|
48
51
|
}
|
|
49
52
|
}, [enableAutoResize, adjustHeight]);
|
|
50
|
-
return (_jsx(FocusIndicator, { children: _jsx("textarea", { ref: mergeRefs(ref, localRef), ...props, rows: rows, className: cx(classes.root, 'mfui-
|
|
53
|
+
return (_jsx(FocusIndicator, { children: _jsx("textarea", { ref: mergeRefs(ref, localRef), ...props, rows: rows, className: cx(classes.root, 'mfui-Textarea__root',
|
|
54
|
+
/* TODO: Remove in v5.0.0 */ 'mfui-MultilineTextBox__root', props.className), disabled: disabled, onChange: handleChange }) }));
|
|
51
55
|
});
|
package/dist/src/{MultilineTextBox/MultilineTextBox.types.d.ts → Textarea/Textarea.types.d.ts}
RENAMED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { type ComponentPropsWithoutRef } from 'react';
|
|
2
2
|
import { type TextBoxSlotRecipeVariant } from '../../styled-system/recipes';
|
|
3
3
|
/**
|
|
4
|
-
* The props for the
|
|
4
|
+
* The props for the Textarea component.
|
|
5
5
|
*/
|
|
6
|
-
export type
|
|
6
|
+
export type TextareaProps = {
|
|
7
7
|
/**
|
|
8
8
|
* Whether the textarea is invalid or not.
|
|
9
9
|
* This will change the style of the text box.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Textarea } from './Textarea';
|
|
@@ -79,7 +79,16 @@ export const Tooltip = forwardRef(({ children, open, onOpenStateChanged, content
|
|
|
79
79
|
}, [calculatedOpen, closeImmediate]);
|
|
80
80
|
const triggerRef = mergeRefs(setTriggerReference, rootRef, ref);
|
|
81
81
|
const classes = tooltipSlotRecipe();
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
82
|
+
const ariaDescribedBy = !hideFromScreenReader && content != null ? tooltipId : undefined;
|
|
83
|
+
return (_jsxs(_Fragment, { children: [_jsx("div", { ref: triggerRef, ...wrapperProps, className: cx(classes.root, 'mfui-Tooltip__root', className), ...rootAttributes, children: isValidElement(children) ? (cloneElement(children, ariaDescribedBy ? { 'aria-describedby': ariaDescribedBy } : undefined)) : (_jsx("span", { ...(ariaDescribedBy ? { 'aria-describedby': ariaDescribedBy } : undefined), children: children })) }), !calculatedOpen && !hideFromScreenReader && content != null && (_jsx(Portal, { targetDOMNode: targetElement, children: _jsx("div", { "data-mfui-tooltip-hidden": true, id: tooltipId, style: {
|
|
84
|
+
position: 'absolute',
|
|
85
|
+
width: '1px',
|
|
86
|
+
height: '1px',
|
|
87
|
+
padding: 0,
|
|
88
|
+
margin: '-1px',
|
|
89
|
+
overflow: 'hidden',
|
|
90
|
+
clip: 'rect(0, 0, 0, 0)',
|
|
91
|
+
whiteSpace: 'nowrap',
|
|
92
|
+
borderWidth: 0,
|
|
93
|
+
}, children: content }) })), calculatedOpen ? (_jsx(Portal, { targetDOMNode: targetElement, children: _jsxs("div", { ref: setTooltipReference, className: cx(classes.tooltip, 'mfui-Tooltip__tooltip', contentProps?.className), role: "tooltip", id: tooltipId, "aria-hidden": hideFromScreenReader ? true : undefined, style: { maxWidth, ...tooltipStyles }, ...tooltipAttributes, children: [typeof content === 'string' ? _jsx(Typography, { variant: "helpMessage", children: content }) : content, _jsx(ArrowIcon, { ref: arrowRef, "aria-hidden": true, placement: calculatedPlacement, className: cx(classes.arrow, 'mfui-Tooltip__arrow'), style: arrowStyles })] }) })) : null] }));
|
|
85
94
|
});
|
|
@@ -21,9 +21,7 @@ function InternalTypography(props, ref) {
|
|
|
21
21
|
return variant.startsWith('strong') ? 'strong' : 'span';
|
|
22
22
|
}, [variant, tag, rest.href]);
|
|
23
23
|
const classes = typographySlotRecipe({ variant });
|
|
24
|
-
return (
|
|
25
|
-
// @ts-expect-error Ignore the error for ref due to the complexion.
|
|
26
|
-
_jsx(Tag, { ref: ref, ...rest, className: cx(classes.root, 'mfui-Typography__root', className), children: children }));
|
|
24
|
+
return (_jsx(Tag, { ref: ref, ...rest, className: cx(classes.root, 'mfui-Typography__root', className), children: children }));
|
|
27
25
|
}
|
|
28
26
|
/**
|
|
29
27
|
*
|
package/dist/src/index.d.ts
CHANGED
package/dist/src/index.js
CHANGED