@moneyforward/mfui-components 3.29.1 → 3.31.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/Button/Button.d.ts +4 -4
- package/dist/src/CheckboxCard/CheckboxCard.d.ts +2 -2
- package/dist/src/CheckboxCard/CheckboxCard.js +1 -1
- package/dist/src/DataTable/DataTable.js +2 -2
- package/dist/src/DataTable/DataTable.types.d.ts +9 -0
- package/dist/src/DataTable/DataTableCell/DataTableCell.js +3 -2
- package/dist/src/DataTable/DataTableHeaderCell/DataTableHeaderCell.js +2 -1
- package/dist/src/DataTable/DataTableProvider.d.ts +2 -2
- package/dist/src/DataTable/DataTableProvider.js +4 -1
- package/dist/src/DataTable/DataTableRow/DataTableRow.js +34 -3
- package/dist/src/DateTimeSelection/DateRangePicker/DateRangePickerProvider/DateRangePickerProvider.d.ts +2 -2
- package/dist/src/DateTimeSelection/DateRangePicker/DateRangePickerTrigger/constants.d.ts +4 -4
- package/dist/src/DateTimeSelection/DateRangePicker/DateRangePickerTrigger/hooks/useDateRangeTriggerInputClick.d.ts +1 -1
- package/dist/src/DateTimeSelection/DateRangePicker/utilities/createDateRangePickerTestUtility.d.ts +1 -1
- package/dist/src/DateTimeSelection/MonthRangePicker/MonthRangePickerMonthCell/constants.d.ts +5 -5
- package/dist/src/DateTimeSelection/TimePicker/TimePicker.d.ts +9 -9
- package/dist/src/DateTimeSelection/shared/BasePicker/basePickerUtilities/useBasePickerValueController.d.ts +1 -1
- package/dist/src/DateTimeSelection/shared/BasePicker/constants.d.ts +1 -1
- package/dist/src/DateTimeSelection/shared/BasePicker/constants.js +2 -0
- package/dist/src/DateTimeSelection/shared/BaseRangePicker/BaseRangePickerPopover/BaseRangePickerCalendar/constants.d.ts +6 -6
- package/dist/src/DateTimeSelection/shared/BaseRangePicker/BaseRangePickerProvider/BaseRangePickerProvider.d.ts +2 -2
- package/dist/src/DateTimeSelection/shared/BaseRangePicker/BaseRangePickerTrigger/BaseRangePickerTrigger.js +1 -1
- package/dist/src/DateTimeSelection/shared/BaseRangePicker/BaseRangePickerTrigger/hooks/useDateRangeTriggerInputClick.d.ts +1 -1
- package/dist/src/DateTimeSelection/shared/BaseRangePicker/utilities/createBaseRangePickerTestUtility.d.ts +1 -1
- package/dist/src/DateTimeSelection/shared/YearSelector/YearSelector.js +7 -1
- package/dist/src/DateTimeSelection/shared/accessibility/constants.d.ts +6 -6
- package/dist/src/Dialog/Dialog.d.ts +4 -4
- package/dist/src/Disclosure/Disclosure.d.ts +21 -10
- package/dist/src/DropdownMenu/DropdownMenu.d.ts +3 -3
- package/dist/src/DropdownMenu/DropdownMenu.js +26 -2
- package/dist/src/DropdownMenu/DropdownMenuButtonTrigger.d.ts +2 -2
- package/dist/src/DropdownMenu/DropdownMenuContainer/DropdownMenuContainer.js +28 -3
- package/dist/src/DropdownMenu/DropdownMenuContainer/DropdownMenuContainer.types.d.ts +5 -2
- package/dist/src/DropdownMenu/DropdownMenuItem/DropdownMenuItem.d.ts +1 -1
- package/dist/src/DropdownMenu/DropdownMenuItem/DropdownMenuItem.js +29 -6
- package/dist/src/DropdownMenu/DropdownMenuItem/DropdownMenuItem.types.d.ts +6 -0
- package/dist/src/EmbeddedSidePane/EmbeddedSidePane.d.ts +1 -1
- package/dist/src/FileBox/FileBox.d.ts +4 -4
- package/dist/src/FileBox/FileBox.js +1 -1
- package/dist/src/FileDropZone/FileDropZone.d.ts +4 -4
- package/dist/src/FileDropZone/utils/fileHelpers.d.ts +3 -3
- package/dist/src/FilterTrigger/FilterTrigger.d.ts +2 -2
- package/dist/src/Heading/Heading.d.ts +2 -2
- package/dist/src/HelpMessage/HelpMessage.d.ts +3 -3
- package/dist/src/IconButton/IconButton.d.ts +6 -6
- package/dist/src/KeyValue/KeyValue.d.ts +2 -2
- package/dist/src/MainNavigation/BaseMainNavigation.d.ts +1 -1
- package/dist/src/MainNavigation/BaseMainNavigation.js +4 -2
- package/dist/src/MainNavigation/MainNavigation.js +3 -3
- package/dist/src/MainNavigation/MainNavigation.types.d.ts +18 -0
- package/dist/src/MultipleSelectBox/MultipleSelectBox.js +1 -1
- package/dist/src/MultipleSelectBox/hooks/useApplyControls.d.ts +1 -1
- package/dist/src/MultipleSelectBox/hooks/useSelectedValues.d.ts +1 -1
- package/dist/src/NumberBox/NumberBox.d.ts +1 -1
- package/dist/src/NumberBox/NumberBox.js +68 -21
- package/dist/src/Pagination/ItemsCount/ItemsCount.js +1 -1
- package/dist/src/Popover/Popover.js +1 -1
- package/dist/src/RadioButton/RadioButton.d.ts +1 -1
- package/dist/src/RadioButtonCard/RadioButtonCard.d.ts +2 -2
- package/dist/src/RadioButtonCard/RadioButtonCard.js +1 -1
- package/dist/src/RadioGroup/RadioGroup.d.ts +1 -1
- package/dist/src/SearchBox/SearchBox.js +18 -4
- package/dist/src/SectionMessage/SectionMessage.d.ts +5 -5
- package/dist/src/SectionMessage/SectionMessage.js +11 -4
- package/dist/src/SectionMessage/SectionMessage.types.d.ts +4 -4
- package/dist/src/SelectBox/SelectBox.js +1 -1
- package/dist/src/SelectBox/SelectBoxOption.js +1 -1
- package/dist/src/SelectBox/SelectBoxOptionGroup.js +1 -1
- package/dist/src/SidePane/SidePane.d.ts +9 -7
- package/dist/src/SidePane/SidePane.js +8 -4
- package/dist/src/SidePane/hooks/useSidePaneStateController.d.ts +7 -2
- package/dist/src/SidePane/hooks/useSidePaneStateController.js +11 -5
- package/dist/src/Sidebar/Sidebar.d.ts +10 -1
- package/dist/src/Sidebar/Sidebar.js +40 -10
- package/dist/src/Sidebar/Sidebar.types.d.ts +39 -2
- package/dist/src/Sidebar/SidebarContext.d.ts +3 -0
- package/dist/src/Sidebar/SidebarContext.js +2 -0
- package/dist/src/Sidebar/SidebarMenuHeading/SidebarMenuHeading.d.ts +49 -0
- package/dist/src/Sidebar/SidebarMenuHeading/SidebarMenuHeading.js +113 -0
- package/dist/src/Sidebar/SidebarMenuHeading/SidebarMenuHeading.types.d.ts +36 -0
- package/dist/src/Sidebar/SidebarMenuHeading/SidebarMenuHeading.types.js +1 -0
- package/dist/src/Sidebar/SidebarMenuHeading/index.d.ts +2 -0
- package/dist/src/Sidebar/SidebarMenuHeading/index.js +1 -0
- package/dist/src/Sidebar/SidebarNavigationItem.js +6 -3
- package/dist/src/Sidebar/hooks/useSidebarResize.d.ts +2 -1
- package/dist/src/Sidebar/hooks/useSidebarResize.js +31 -3
- package/dist/src/Sidebar/index.d.ts +2 -1
- package/dist/src/Stack/Stack.d.ts +5 -5
- package/dist/src/StatusLabel/StatusLabel.d.ts +2 -2
- package/dist/src/Stepper/Step/Step.js +1 -1
- package/dist/src/SubNavigation/SubNavigation.js +1 -1
- package/dist/src/Tag/Tag.d.ts +1 -1
- package/dist/src/Tag/Tag.js +2 -2
- package/dist/src/Tag/Tag.types.d.ts +7 -0
- package/dist/src/TextBox/TextBox.d.ts +6 -6
- package/dist/src/TextLink/TextLink.d.ts +2 -2
- package/dist/src/Textarea/Textarea.d.ts +4 -4
- package/dist/src/Toast/Toast.d.ts +3 -3
- package/dist/src/Toast/Toast.js +9 -5
- package/dist/src/Toast/Toast.types.d.ts +3 -5
- package/dist/src/Toast/api/toast.d.ts +18 -2
- package/dist/src/Tooltip/Tooltip.d.ts +3 -3
- package/dist/src/Tooltip/Tooltip.js +1 -1
- package/dist/src/Tooltip/Tooltip.types.d.ts +2 -0
- package/dist/src/Tooltip/hooks/useTooltipDisplayController.js +14 -2
- package/dist/src/utilities/dom/dispatchNativeInputValueWithEvent.d.ts +1 -1
- package/dist/src/utilities/dom/useFocusTrap.d.ts +1 -1
- package/dist/src/utilities/react/useIsomorphicLayoutEffect.d.ts +2 -2
- package/dist/styled-system/css/conditions.d.ts +3 -3
- package/dist/styled-system/helpers.d.ts +36 -35
- package/dist/styled-system/jsx/factory-helper.d.ts +4 -4
- package/dist/styled-system/recipes/create-recipe.d.ts +2 -2
- package/dist/styled-system/recipes/data-table-cell-slot-recipe.d.ts +1 -0
- package/dist/styled-system/recipes/data-table-cell-slot-recipe.js +4 -0
- package/dist/styled-system/recipes/data-table-header-cell-slot-recipe.d.ts +1 -0
- package/dist/styled-system/recipes/data-table-header-cell-slot-recipe.js +4 -0
- package/dist/styled-system/recipes/dropdown-menu-item-slot-recipe.d.ts +1 -1
- package/dist/styled-system/recipes/dropdown-menu-item-slot-recipe.js +12 -0
- package/dist/styled-system/recipes/index.d.ts +2 -1
- package/dist/styled-system/recipes/index.js +1 -0
- package/dist/styled-system/recipes/section-message-slot-recipe.d.ts +1 -1
- package/dist/styled-system/recipes/section-message-slot-recipe.js +3 -1
- package/dist/styled-system/recipes/sidebar-menu-heading-slot-recipe.d.ts +33 -0
- package/dist/styled-system/recipes/sidebar-menu-heading-slot-recipe.js +44 -0
- package/dist/styled-system/recipes/sidebar-slot-recipe.d.ts +1 -1
- package/dist/styled-system/recipes/sidebar-slot-recipe.js +4 -0
- package/dist/styles.css +158 -14
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +11 -11
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect, useRef, useState } from 'react';
|
|
4
|
+
import { Copy, Current } from '@moneyforward/mfui-icons-react';
|
|
5
|
+
import { cx } from '../../../styled-system/css';
|
|
6
|
+
import { sidebarMenuHeadingSlotRecipe } from '../../../styled-system/recipes';
|
|
7
|
+
import { DropdownMenu } from '../../DropdownMenu';
|
|
8
|
+
import { Tooltip } from '../../Tooltip';
|
|
9
|
+
import { CLOSE_DELAY } from '../../Tooltip/Tooltip.constants';
|
|
10
|
+
import { Typography } from '../../Typography';
|
|
11
|
+
// How long the "copied" feedback stays while the user remains on the row.
|
|
12
|
+
const COPIED_FEEDBACK_DURATION_MS = 5000;
|
|
13
|
+
// Copy-to-clipboard feedback for the identification-number row: `copied` drives the tooltip text,
|
|
14
|
+
// the icon swap, and the live region; the handlers are spread onto the `DropdownMenu.Item`.
|
|
15
|
+
function useCopyFeedback(text) {
|
|
16
|
+
const [copied, setCopied] = useState(false);
|
|
17
|
+
const timerRef = useRef(undefined);
|
|
18
|
+
useEffect(() => () => {
|
|
19
|
+
window.clearTimeout(timerRef.current);
|
|
20
|
+
}, []);
|
|
21
|
+
// On blur (keyboard focus moved on), dismiss immediately so the tooltip never lingers next to a
|
|
22
|
+
// newly focused item; the copy result is still announced by the `role="status"` live region.
|
|
23
|
+
const onBlur = () => {
|
|
24
|
+
window.clearTimeout(timerRef.current);
|
|
25
|
+
setCopied(false);
|
|
26
|
+
};
|
|
27
|
+
// On mouse leave, dismiss after the same delay as the Tooltip's own close behavior.
|
|
28
|
+
const onMouseLeave = () => {
|
|
29
|
+
window.clearTimeout(timerRef.current);
|
|
30
|
+
timerRef.current = window.setTimeout(() => {
|
|
31
|
+
setCopied(false);
|
|
32
|
+
}, CLOSE_DELAY);
|
|
33
|
+
};
|
|
34
|
+
// Copy the text, keep the menu open, and show the "copied" feedback (tooltip + icon) while the
|
|
35
|
+
// user stays on the row. The feedback only appears once the clipboard write succeeds; on failure
|
|
36
|
+
// the row keeps its copy label so the user can retry.
|
|
37
|
+
const onClick = (event) => {
|
|
38
|
+
event.preventDefault(); // keep the menu open after copying
|
|
39
|
+
navigator.clipboard
|
|
40
|
+
.writeText(text ?? '')
|
|
41
|
+
.then(() => {
|
|
42
|
+
setCopied(true);
|
|
43
|
+
window.clearTimeout(timerRef.current);
|
|
44
|
+
timerRef.current = window.setTimeout(() => {
|
|
45
|
+
setCopied(false);
|
|
46
|
+
}, COPIED_FEEDBACK_DURATION_MS);
|
|
47
|
+
})
|
|
48
|
+
.catch(() => {
|
|
49
|
+
// Swallow the rejection (insecure context, missing clipboard-write permission, etc.) so it
|
|
50
|
+
// does not surface as an unhandled promise rejection.
|
|
51
|
+
});
|
|
52
|
+
};
|
|
53
|
+
return { copied, onClick, onBlur, onMouseLeave };
|
|
54
|
+
}
|
|
55
|
+
function SidebarMenuHeading({ name, identificationNumber, copy }) {
|
|
56
|
+
const classes = sidebarMenuHeadingSlotRecipe();
|
|
57
|
+
const { copied, ...copyHandlers } = useCopyFeedback(copy?.text);
|
|
58
|
+
const copiedLabel = copy?.copiedLabel ?? 'コピーしました';
|
|
59
|
+
const numberRow = (_jsxs(DropdownMenu.Item, { className: cx(classes.numberRow, 'mfui-SidebarMenuHeading__numberRow'), ...(copy ? copyHandlers : {}), children: [_jsx(Typography, { className: cx(classes.numberText, 'mfui-SidebarMenuHeading__numberText'), children: identificationNumber }), copy ? (copied ? (_jsx(Current, { "aria-hidden": true, className: cx(classes.numberIcon, 'mfui-SidebarMenuHeading__numberIcon') })) : (_jsx(Copy, { "aria-hidden": true, className: cx(classes.numberIcon, 'mfui-SidebarMenuHeading__numberIcon') }))) : null] }));
|
|
60
|
+
return (_jsxs(_Fragment, { children: [_jsx(DropdownMenu.Heading, { children: name }), copy ? (_jsxs(_Fragment, { children: [_jsx(Tooltip, { content: copied ? copiedLabel : copy.label, open: copied || undefined, placement: "right", targetDOMNode: typeof document === 'undefined' ? undefined : document.body, className: cx(classes.tooltip, 'mfui-SidebarMenuHeading__tooltip'), children: numberRow }), _jsx("span", { role: "status", className: cx(classes.status, 'mfui-SidebarMenuHeading__status'), children: copied ? copiedLabel : '' })] })) : (numberRow)] }));
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* The heading block of the Sidebar tenant menu: the tenant name heading and the
|
|
64
|
+
* identification-number row. Place it as the first child of `Sidebar.TenantMenu`.
|
|
65
|
+
*
|
|
66
|
+
* Pass the `copy` prop to make the identification-number row copy its value to the clipboard,
|
|
67
|
+
* with a tooltip and a screen-reader announcement. The feedback after copying reads `コピーしました`
|
|
68
|
+
* by default and can be changed via `copy.copiedLabel`. Without `copy`, the row is static text.
|
|
69
|
+
*
|
|
70
|
+
* @param props - The props of the `Sidebar.TenantMenuHeading` component.
|
|
71
|
+
*
|
|
72
|
+
* @example
|
|
73
|
+
* ```tsx
|
|
74
|
+
* <Sidebar.TenantMenu name="株式会社サンプル" tooltipLabel="事業者">
|
|
75
|
+
* <Sidebar.TenantMenuHeading
|
|
76
|
+
* name="株式会社サンプル"
|
|
77
|
+
* identificationNumber="事業者番号:0123-4567"
|
|
78
|
+
* copy={{ text: '0123-4567', label: '事業者番号をコピーする' }}
|
|
79
|
+
* />
|
|
80
|
+
* <DropdownMenu.Divider />
|
|
81
|
+
* <DropdownMenu.Item href="https://example.com">事業者設定</DropdownMenu.Item>
|
|
82
|
+
* </Sidebar.TenantMenu>
|
|
83
|
+
* ```
|
|
84
|
+
*/
|
|
85
|
+
export function SidebarTenantMenuHeading(props) {
|
|
86
|
+
return _jsx(SidebarMenuHeading, { ...props });
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* The heading block of the Sidebar user menu: the user (account) name heading and the
|
|
90
|
+
* identification-number row. Place it as the first child of `Sidebar.UserMenu`.
|
|
91
|
+
*
|
|
92
|
+
* Pass the `copy` prop to make the identification-number row copy its value to the clipboard,
|
|
93
|
+
* with a tooltip and a screen-reader announcement. The feedback after copying reads `コピーしました`
|
|
94
|
+
* by default and can be changed via `copy.copiedLabel`. Without `copy`, the row is static text.
|
|
95
|
+
*
|
|
96
|
+
* @param props - The props of the `Sidebar.UserMenuHeading` component.
|
|
97
|
+
*
|
|
98
|
+
* @example
|
|
99
|
+
* ```tsx
|
|
100
|
+
* <Sidebar.UserMenu name="山田 太郎" tooltipLabel="アカウント">
|
|
101
|
+
* <Sidebar.UserMenuHeading
|
|
102
|
+
* name="山田 太郎"
|
|
103
|
+
* identificationNumber="従業員番号:1234"
|
|
104
|
+
* copy={{ text: '1234', label: '従業員番号をコピーする' }}
|
|
105
|
+
* />
|
|
106
|
+
* <DropdownMenu.Divider />
|
|
107
|
+
* <DropdownMenu.Item onClick={handleLogout}>ログアウト</DropdownMenu.Item>
|
|
108
|
+
* </Sidebar.UserMenu>
|
|
109
|
+
* ```
|
|
110
|
+
*/
|
|
111
|
+
export function SidebarUserMenuHeading(props) {
|
|
112
|
+
return _jsx(SidebarMenuHeading, { ...props });
|
|
113
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The copy-to-clipboard settings for the identification-number row.
|
|
3
|
+
*/
|
|
4
|
+
export type SidebarMenuHeadingCopy = {
|
|
5
|
+
/**
|
|
6
|
+
* The text written to the clipboard when the row is selected (e.g. `"0123-4567"`).
|
|
7
|
+
*/
|
|
8
|
+
text: string;
|
|
9
|
+
/**
|
|
10
|
+
* The tooltip label prompting the copy action (e.g. `"事業者番号をコピーする"`).
|
|
11
|
+
*/
|
|
12
|
+
label: string;
|
|
13
|
+
/**
|
|
14
|
+
* The label shown in the tooltip and announced to screen readers right after copying.
|
|
15
|
+
*
|
|
16
|
+
* @default 'コピーしました'
|
|
17
|
+
*/
|
|
18
|
+
copiedLabel?: string;
|
|
19
|
+
};
|
|
20
|
+
export type SidebarMenuHeadingProps = {
|
|
21
|
+
/**
|
|
22
|
+
* The tenant (business) or user (account) name shown as the menu heading.
|
|
23
|
+
*/
|
|
24
|
+
name: string;
|
|
25
|
+
/**
|
|
26
|
+
* The identification-number row text (e.g. `"事業者番号:0123-4567"`).
|
|
27
|
+
*/
|
|
28
|
+
identificationNumber: string;
|
|
29
|
+
/**
|
|
30
|
+
* Enables copy-to-clipboard on the identification-number row: the row becomes a menu item button
|
|
31
|
+
* with a copy icon, a tooltip, and a screen-reader announcement. When omitted, the row is static text.
|
|
32
|
+
*/
|
|
33
|
+
copy?: SidebarMenuHeadingCopy;
|
|
34
|
+
};
|
|
35
|
+
export type SidebarTenantMenuHeadingProps = SidebarMenuHeadingProps;
|
|
36
|
+
export type SidebarUserMenuHeadingProps = SidebarMenuHeadingProps;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { SidebarTenantMenuHeading, SidebarUserMenuHeading } from './SidebarMenuHeading';
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { cloneElement, useRef, useState } from 'react';
|
|
3
|
+
import { cloneElement, useContext, useRef, useState, } from 'react';
|
|
4
4
|
import { cx } from '../../styled-system/css';
|
|
5
5
|
import { sidebarSlotRecipe } from '../../styled-system/recipes';
|
|
6
6
|
import { FocusIndicator } from '../FocusIndicator';
|
|
7
7
|
import { Tooltip } from '../Tooltip';
|
|
8
8
|
import { Typography } from '../Typography';
|
|
9
9
|
import { useIsomorphicLayoutEffect } from '../utilities/react/useIsomorphicLayoutEffect';
|
|
10
|
+
import { SidebarContext } from './SidebarContext';
|
|
10
11
|
/**
|
|
11
12
|
* A single navigation item shown in the Sidebar.
|
|
12
13
|
*
|
|
@@ -15,6 +16,7 @@ import { useIsomorphicLayoutEffect } from '../utilities/react/useIsomorphicLayou
|
|
|
15
16
|
*/
|
|
16
17
|
export function SidebarNavigationItem({ label, icon, isCurrent, maxLines, ...rest }) {
|
|
17
18
|
const classes = sidebarSlotRecipe();
|
|
19
|
+
const { isCollapsed } = useContext(SidebarContext);
|
|
18
20
|
const labelRef = useRef(null);
|
|
19
21
|
const [isTruncated, setIsTruncated] = useState(false);
|
|
20
22
|
useIsomorphicLayoutEffect(() => {
|
|
@@ -40,9 +42,10 @@ export function SidebarNavigationItem({ label, icon, isCurrent, maxLines, ...res
|
|
|
40
42
|
const href = isAnchor ? rest.href : undefined;
|
|
41
43
|
const target = 'target' in rest ? rest.target : undefined;
|
|
42
44
|
const onClick = 'onClick' in rest ? rest.onClick : undefined;
|
|
43
|
-
|
|
45
|
+
const shouldShowTooltip = isCollapsed || isTruncated;
|
|
46
|
+
return (_jsx("li", { className: cx(classes.navigationListItem, 'mfui-Sidebar__navigationListItem'), style: maxLines !== undefined ? { '--mfui-sidebar-max-lines': maxLines } : undefined, children: _jsx(Tooltip, { content: label, disabled: !shouldShowTooltip, placement: "right", children: _jsx(FocusIndicator, { children: _jsx(Tag, { "data-mfui-focusable": true, href: href, target: target, type: isAnchor ? undefined : 'button', "aria-label": isCollapsed ? label : undefined, "aria-current": isCurrent ? 'page' : undefined, className: cx(classes.navigationLink, 'mfui-Sidebar__navigationLink'), onClick: onClick, children: _jsxs("div", { className: cx(classes.navigationLinkInner, 'mfui-Sidebar__navigationLinkInner'), children: [_jsx("span", { className: cx(classes.navigationLinkIcon, 'mfui-Sidebar__navigationLinkIcon'), children: cloneElement(icon, {
|
|
44
47
|
width: 18,
|
|
45
48
|
height: 18,
|
|
46
49
|
'aria-hidden': true,
|
|
47
|
-
}) }), _jsx(Typography, { ref: labelRef, variant: "controlLabel", className: cx(classes.navigationLinkLabel, 'mfui-Sidebar__navigationLinkLabel'), children: label })] }) }) }) }) }));
|
|
50
|
+
}) }), isCollapsed ? null : (_jsx(Typography, { ref: labelRef, variant: "controlLabel", className: cx(classes.navigationLinkLabel, 'mfui-Sidebar__navigationLinkLabel'), children: label }))] }) }) }) }) }));
|
|
48
51
|
}
|
|
@@ -12,11 +12,12 @@ import { type KeyboardEvent, type PointerEvent as ReactPointerEvent } from 'reac
|
|
|
12
12
|
*
|
|
13
13
|
* @returns Object containing the current width, resolved bounds, refs, and resize handlers
|
|
14
14
|
*/
|
|
15
|
-
export declare function useSidebarResize({ minWidth, maxWidth, defaultWidth, onWidthChange, }?: {
|
|
15
|
+
export declare function useSidebarResize({ minWidth, maxWidth, defaultWidth, onWidthChange, isCollapsed, }?: {
|
|
16
16
|
minWidth?: number;
|
|
17
17
|
maxWidth?: number;
|
|
18
18
|
defaultWidth?: number;
|
|
19
19
|
onWidthChange?: (width: number) => void;
|
|
20
|
+
isCollapsed?: boolean;
|
|
20
21
|
}): {
|
|
21
22
|
width: number;
|
|
22
23
|
minWidth: number;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { useCallback, useEffect, useRef, useState, } from 'react';
|
|
1
|
+
import { useCallback, useEffect, useMemo, useRef, useState, } from 'react';
|
|
2
2
|
const DEFAULT_WIDTH = 200;
|
|
3
3
|
const DEFAULT_MIN_WIDTH = 180;
|
|
4
4
|
const DEFAULT_MAX_WIDTH = 280;
|
|
5
|
+
const COLLAPSED_WIDTH = 48;
|
|
5
6
|
const KEYBOARD_STEP_PX = 14;
|
|
6
7
|
/**
|
|
7
8
|
* Hook to manage the resizable width of the Sidebar via pointer dragging and keyboard control.
|
|
@@ -16,10 +17,11 @@ const KEYBOARD_STEP_PX = 14;
|
|
|
16
17
|
*
|
|
17
18
|
* @returns Object containing the current width, resolved bounds, refs, and resize handlers
|
|
18
19
|
*/
|
|
19
|
-
export function useSidebarResize({ minWidth = DEFAULT_MIN_WIDTH, maxWidth = DEFAULT_MAX_WIDTH, defaultWidth, onWidthChange, } = {}) {
|
|
20
|
+
export function useSidebarResize({ minWidth = DEFAULT_MIN_WIDTH, maxWidth = DEFAULT_MAX_WIDTH, defaultWidth, onWidthChange, isCollapsed = false, } = {}) {
|
|
20
21
|
const rootRef = useRef(null);
|
|
21
22
|
const [isDragging, setIsDragging] = useState(false);
|
|
22
23
|
const pointerIdRef = useRef(null);
|
|
24
|
+
const isCollapsedRef = useRef(isCollapsed);
|
|
23
25
|
const onWidthChangeRef = useRef(onWidthChange);
|
|
24
26
|
useEffect(() => {
|
|
25
27
|
onWidthChangeRef.current = onWidthChange;
|
|
@@ -37,6 +39,7 @@ export function useSidebarResize({ minWidth = DEFAULT_MIN_WIDTH, maxWidth = DEFA
|
|
|
37
39
|
// not re-synced on later changes, so the user's drag/keyboard adjustments are never overridden.
|
|
38
40
|
const initialWidth = clamp(defaultWidth ?? DEFAULT_WIDTH);
|
|
39
41
|
const widthRef = useRef(initialWidth);
|
|
42
|
+
const lastExpandedWidthRef = useRef(initialWidth);
|
|
40
43
|
const [width, setWidth] = useState(initialWidth);
|
|
41
44
|
const notify = useCallback((value) => {
|
|
42
45
|
onWidthChangeRef.current?.(value);
|
|
@@ -47,6 +50,9 @@ export function useSidebarResize({ minWidth = DEFAULT_MIN_WIDTH, maxWidth = DEFA
|
|
|
47
50
|
}, []);
|
|
48
51
|
// --- Drag ---
|
|
49
52
|
const handlePointerDown = useCallback((event) => {
|
|
53
|
+
if (isCollapsedRef.current) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
50
56
|
event.preventDefault();
|
|
51
57
|
event.currentTarget.setPointerCapture(event.pointerId);
|
|
52
58
|
pointerIdRef.current = event.pointerId;
|
|
@@ -82,6 +88,9 @@ export function useSidebarResize({ minWidth = DEFAULT_MIN_WIDTH, maxWidth = DEFA
|
|
|
82
88
|
}, [isDragging, handlePointerMove, handlePointerUp]);
|
|
83
89
|
// --- Keyboard ---
|
|
84
90
|
const handleKeyDown = useCallback((event) => {
|
|
91
|
+
if (isCollapsedRef.current) {
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
85
94
|
let newWidth;
|
|
86
95
|
switch (event.key) {
|
|
87
96
|
case 'ArrowRight':
|
|
@@ -107,5 +116,24 @@ export function useSidebarResize({ minWidth = DEFAULT_MIN_WIDTH, maxWidth = DEFA
|
|
|
107
116
|
notify(newWidth);
|
|
108
117
|
}
|
|
109
118
|
}, [minWidth, maxWidth, applyWidth, notify]);
|
|
110
|
-
|
|
119
|
+
useEffect(() => {
|
|
120
|
+
if (isCollapsedRef.current === isCollapsed) {
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
if (isCollapsed) {
|
|
124
|
+
lastExpandedWidthRef.current = widthRef.current;
|
|
125
|
+
setIsDragging(false);
|
|
126
|
+
pointerIdRef.current = null;
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
// width/widthRef never change while collapsed (handlePointerDown/handleKeyDown
|
|
130
|
+
// early-return above), so this is a no-op today. Kept as a defensive restore in
|
|
131
|
+
// case a future change allows width-affecting state (e.g. minWidth/maxWidth) to
|
|
132
|
+
// change while collapsed.
|
|
133
|
+
applyWidth(lastExpandedWidthRef.current);
|
|
134
|
+
}
|
|
135
|
+
isCollapsedRef.current = isCollapsed;
|
|
136
|
+
}, [applyWidth, isCollapsed]);
|
|
137
|
+
const effectiveWidth = useMemo(() => (isCollapsed ? COLLAPSED_WIDTH : width), [isCollapsed, width]);
|
|
138
|
+
return { width: effectiveWidth, minWidth, maxWidth, rootRef, isDragging, handlePointerDown, handleKeyDown };
|
|
111
139
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { Sidebar } from './Sidebar';
|
|
2
|
-
export type { SidebarProps, SidebarNavigationItem, SidebarNavigationDivider, SidebarNavigationEntry, } from './Sidebar.types';
|
|
2
|
+
export type { SidebarProps, SidebarFooterIconMenuSlotState, SidebarNavigationItem, SidebarNavigationDivider, SidebarNavigationEntry, } from './Sidebar.types';
|
|
3
3
|
export type { SidebarNavigationItemProps } from './SidebarNavigationItem';
|
|
4
4
|
export type { SidebarServiceMenuProps } from './SidebarServiceMenu';
|
|
5
5
|
export type { SidebarTenantMenuProps } from './SidebarTenantMenu';
|
|
6
6
|
export type { SidebarUserMenuProps } from './SidebarUserMenu';
|
|
7
|
+
export type { SidebarTenantMenuHeadingProps, SidebarUserMenuHeadingProps, SidebarMenuHeadingCopy, } from './SidebarMenuHeading';
|
|
@@ -13,11 +13,11 @@ import { type StackProps } from './Stack.types';
|
|
|
13
13
|
*/
|
|
14
14
|
export declare const Stack: import("react").ForwardRefExoticComponent<{
|
|
15
15
|
children?: import("react").ReactNode;
|
|
16
|
-
direction?: import("react").CSSProperties[
|
|
17
|
-
gap?: ("horizontal.
|
|
18
|
-
wrap?: import("react").CSSProperties[
|
|
19
|
-
alignItems?: import("react").CSSProperties[
|
|
20
|
-
justifyContent?: import("react").CSSProperties[
|
|
16
|
+
direction?: import("react").CSSProperties['flexDirection'];
|
|
17
|
+
gap?: ("horizontal.0-1of2" | "horizontal.0-1of4" | "horizontal.0-1of8" | "horizontal.1" | "horizontal.1-1of2" | "horizontal.2" | "horizontal.2-1of2" | "horizontal.20" | "horizontal.3" | "horizontal.3-1of2" | "horizontal.3-1of7" | "horizontal.4" | "horizontal.4-1of2" | "horizontal.5" | "horizontal.5-1of2" | "horizontal.6" | "horizontal.6-1of2" | "horizontal.7" | "horizontal.7-1of2" | "horizontal.8" | "vertical.0-1of2" | "vertical.0-1of3" | "vertical.0-1of4" | "vertical.0-1of6" | "vertical.0-1of8" | "vertical.0-2of3" | "vertical.0-3of4" | "vertical.0-5of6" | "vertical.0-7of8" | "vertical.1" | "vertical.1-1of2" | "vertical.1-1of3" | "vertical.1-1of4" | "vertical.1-1of8" | "vertical.1-2of3" | "vertical.2" | "vertical.2-1of2" | "vertical.3") | `${number}px` | number;
|
|
18
|
+
wrap?: import("react").CSSProperties['flexWrap'];
|
|
19
|
+
alignItems?: import("react").CSSProperties['alignItems'];
|
|
20
|
+
justifyContent?: import("react").CSSProperties['justifyContent'];
|
|
21
21
|
} & Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
|
|
22
22
|
/**
|
|
23
23
|
* This component is inherited from the Stack component and helps you create a horizontal stack layout.
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
export declare const StatusLabel: import("react").ForwardRefExoticComponent<{
|
|
12
12
|
label: string;
|
|
13
13
|
icon?: import("react").ReactNode;
|
|
14
|
-
status?: import("../../styled-system/recipes").StatusLabelSlotRecipeVariant[
|
|
15
|
-
size?: import("../../styled-system/recipes").StatusLabelSlotRecipeVariant[
|
|
14
|
+
status?: import("../../styled-system/recipes").StatusLabelSlotRecipeVariant['status'];
|
|
15
|
+
size?: import("../../styled-system/recipes").StatusLabelSlotRecipeVariant['size'];
|
|
16
16
|
className?: string;
|
|
17
17
|
} & Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref"> & import("react").RefAttributes<HTMLSpanElement>>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import {
|
|
2
|
+
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { createElement, useContext } from 'react';
|
|
4
4
|
import { cx } from '../../../styled-system/css';
|
|
5
5
|
import { stepperSlotRecipe } from '../../../styled-system/recipes';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { DisclosureBasicCollapsed, Lock } from '@moneyforward/mfui-icons-react';
|
|
3
3
|
import { cx } from '../../styled-system/css';
|
|
4
4
|
import { subNavigationSlotRecipe } from '../../styled-system/recipes';
|
package/dist/src/Tag/Tag.d.ts
CHANGED
|
@@ -7,4 +7,4 @@ import { type TagProps } from './Tag.types';
|
|
|
7
7
|
* - If `disabled` is `true` and `onClick` is provided, the tag will be displayed as disabled button.
|
|
8
8
|
* - If `showCloseButton` is `true`, the tag will be displayed with a close button.
|
|
9
9
|
*/
|
|
10
|
-
export declare function Tag({ label, onClick, href, customLinkComponent, disabled, onClose, target, rel, className, }: TagProps): import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
export declare function Tag({ label, onClick, href, customLinkComponent, disabled, onClose, closeButtonProps, target, rel, className, }: TagProps): import("react/jsx-runtime").JSX.Element;
|
package/dist/src/Tag/Tag.js
CHANGED
|
@@ -14,10 +14,10 @@ import { cx } from '../../styled-system/css';
|
|
|
14
14
|
* - If `disabled` is `true` and `onClick` is provided, the tag will be displayed as disabled button.
|
|
15
15
|
* - If `showCloseButton` is `true`, the tag will be displayed with a close button.
|
|
16
16
|
*/
|
|
17
|
-
export function Tag({ label, onClick, href, customLinkComponent, disabled = false, onClose, target, rel, className, }) {
|
|
17
|
+
export function Tag({ label, onClick, href, customLinkComponent, disabled = false, onClose, closeButtonProps, target, rel, className, }) {
|
|
18
18
|
const isClickable = !!onClick || !!href;
|
|
19
19
|
const classes = tagSlotRecipe({ interactable: isClickable, showCloseButton: !!onClose });
|
|
20
|
-
const closeButton = (_jsx(IconButton, { disabled: disabled, className: cx(classes.closeButton, 'mfui-Tag__closeButton'), "aria-label": `${label}を削除する`, onClick: onClose, children: _jsx(Close, {}) }));
|
|
20
|
+
const closeButton = (_jsx(IconButton, { disabled: disabled, className: cx(classes.closeButton, 'mfui-Tag__closeButton'), "aria-label": closeButtonProps?.['aria-label'] ?? `${label}を削除する`, onClick: onClose, children: _jsx(Close, {}) }));
|
|
21
21
|
if (!isClickable) {
|
|
22
22
|
return (_jsx(FocusIndicator, { children: _jsxs("span", { className: cx(classes.root, 'mfui-Tag__root', className), children: [_jsx(Typography, { variant: "condensedInput", children: label }), onClose ? closeButton : null] }) }));
|
|
23
23
|
}
|
|
@@ -33,6 +33,13 @@ export type TagProps = {
|
|
|
33
33
|
* The handler to close the tag. When this prop is provided, the close button will be shown
|
|
34
34
|
*/
|
|
35
35
|
onClose?: (event: MouseEvent<HTMLButtonElement>) => void;
|
|
36
|
+
/**
|
|
37
|
+
* The properties for the close button.
|
|
38
|
+
* If this prop is not passed, the default values for each property will be applied.
|
|
39
|
+
*
|
|
40
|
+
* @property aria-label - The alternative text for the close button. default is '{label}を削除する'.
|
|
41
|
+
*/
|
|
42
|
+
closeButtonProps?: Pick<ComponentPropsWithoutRef<'button'>, 'aria-label'>;
|
|
36
43
|
/**
|
|
37
44
|
* Class name to be applied to the wrapper element.
|
|
38
45
|
*/
|
|
@@ -9,13 +9,13 @@ import React from 'react';
|
|
|
9
9
|
*/
|
|
10
10
|
export declare const TextBox: React.ForwardRefExoticComponent<{
|
|
11
11
|
enableClearButton?: boolean;
|
|
12
|
-
onClear?: import("..").IconButtonProps[
|
|
13
|
-
invalid?: import("../../styled-system/recipes").TextBoxSlotRecipeVariant[
|
|
14
|
-
textBoxSize?: import("../../styled-system/recipes").TextBoxSlotRecipeVariant[
|
|
15
|
-
disabled?: import("../../styled-system/recipes").TextBoxSlotRecipeVariant[
|
|
16
|
-
wrapperProps?: React.ComponentPropsWithRef<
|
|
12
|
+
onClear?: import("..").IconButtonProps['onClick'];
|
|
13
|
+
invalid?: import("../../styled-system/recipes").TextBoxSlotRecipeVariant['invalid'];
|
|
14
|
+
textBoxSize?: import("../../styled-system/recipes").TextBoxSlotRecipeVariant['size'];
|
|
15
|
+
disabled?: import("../../styled-system/recipes").TextBoxSlotRecipeVariant['disabled'];
|
|
16
|
+
wrapperProps?: React.ComponentPropsWithRef<'div'>;
|
|
17
17
|
prefixSlot?: React.ReactNode;
|
|
18
18
|
suffixSlot?: React.ReactNode;
|
|
19
|
-
clearButtonProps?: Pick<React.ComponentPropsWithoutRef<
|
|
19
|
+
clearButtonProps?: Pick<React.ComponentPropsWithoutRef<'input'>, 'aria-label'>;
|
|
20
20
|
touchDeviceReadOnly?: boolean;
|
|
21
21
|
} & Omit<Omit<React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, "ref">, "prefix"> & React.RefAttributes<HTMLInputElement>>;
|
|
@@ -7,9 +7,9 @@
|
|
|
7
7
|
*/
|
|
8
8
|
export declare const TextLink: import("react").ForwardRefExoticComponent<{
|
|
9
9
|
children?: React.ReactNode;
|
|
10
|
-
variant?: import("../../styled-system/recipes").TextLinkSlotRecipeVariant[
|
|
10
|
+
variant?: import("../../styled-system/recipes").TextLinkSlotRecipeVariant['variant'];
|
|
11
11
|
className?: string;
|
|
12
12
|
customLinkComponent?: import("react").ElementType;
|
|
13
13
|
showExternalIcon?: boolean;
|
|
14
|
-
externalIconProps?: import("react").ComponentPropsWithoutRef<
|
|
14
|
+
externalIconProps?: import("react").ComponentPropsWithoutRef<'svg'>['aria-label'];
|
|
15
15
|
} & Omit<import("react").DetailedHTMLProps<import("react").AnchorHTMLAttributes<HTMLAnchorElement>, HTMLAnchorElement>, "ref"> & import("react").RefAttributes<HTMLAnchorElement>>;
|
|
@@ -10,9 +10,9 @@
|
|
|
10
10
|
* @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea
|
|
11
11
|
*/
|
|
12
12
|
export declare const Textarea: import("react").ForwardRefExoticComponent<{
|
|
13
|
-
invalid?: import("../../styled-system/recipes").TextBoxSlotRecipeVariant[
|
|
14
|
-
size?: import("../../styled-system/recipes").TextBoxSlotRecipeVariant[
|
|
15
|
-
disabled?: import("../../styled-system/recipes").TextBoxSlotRecipeVariant[
|
|
13
|
+
invalid?: import("../../styled-system/recipes").TextBoxSlotRecipeVariant['invalid'];
|
|
14
|
+
size?: import("../../styled-system/recipes").TextBoxSlotRecipeVariant['size'];
|
|
15
|
+
disabled?: import("../../styled-system/recipes").TextBoxSlotRecipeVariant['disabled'];
|
|
16
16
|
enableAutoResize?: boolean;
|
|
17
|
-
resize?:
|
|
17
|
+
resize?: 'none' | 'vertical' | 'horizontal' | 'both';
|
|
18
18
|
} & Omit<import("react").DetailedHTMLProps<import("react").TextareaHTMLAttributes<HTMLTextAreaElement>, HTMLTextAreaElement>, "ref"> & import("react").RefAttributes<HTMLTextAreaElement>>;
|
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
* This component switches the variants of looks depends on the props: type and actionText.
|
|
4
4
|
*/
|
|
5
5
|
export declare const Toast: import("react").ForwardRefExoticComponent<{
|
|
6
|
-
type?: import("../../styled-system/recipes").ToastSlotRecipeVariant[
|
|
6
|
+
type?: import("../../styled-system/recipes").ToastSlotRecipeVariant['type'];
|
|
7
7
|
message: import("react").ReactNode;
|
|
8
8
|
onClose?: () => void;
|
|
9
9
|
actionSlot?: import("react").ReactNode;
|
|
10
|
-
statusIconProps?: Pick<import("react").ComponentPropsWithoutRef<
|
|
11
|
-
closeButtonProps?: Pick<import("react").ComponentPropsWithoutRef<
|
|
10
|
+
statusIconProps?: Pick<import("react").ComponentPropsWithoutRef<'svg'>, 'aria-label'>;
|
|
11
|
+
closeButtonProps?: Pick<import("react").ComponentPropsWithoutRef<'button'>, 'aria-label'>;
|
|
12
12
|
duration?: number;
|
|
13
13
|
activeElement?: Element | null;
|
|
14
14
|
customIcon?: import("react").ReactElement;
|
package/dist/src/Toast/Toast.js
CHANGED
|
@@ -18,20 +18,24 @@ export const Toast = forwardRef(({ className, type = 'success', actionSlot, mess
|
|
|
18
18
|
const timerRef = useRef(null);
|
|
19
19
|
const startTimeRef = useRef(null);
|
|
20
20
|
const localDurationRef = useRef(null);
|
|
21
|
+
// The status is conveyed by the message content itself, so the status icon is decorative
|
|
22
|
+
// and hidden from assistive technology unless a label is explicitly provided.
|
|
23
|
+
const statusIconLabel = statusIconProps?.['aria-label'];
|
|
24
|
+
const statusIconA11yProps = statusIconLabel === undefined ? { 'aria-hidden': true } : { 'aria-label': statusIconLabel };
|
|
21
25
|
const icon = (() => {
|
|
22
26
|
if (type === 'success') {
|
|
23
|
-
return _jsx(Approval, {
|
|
27
|
+
return _jsx(Approval, { ...statusIconA11yProps });
|
|
24
28
|
}
|
|
25
29
|
if (type === 'failure') {
|
|
26
|
-
return _jsx(Error, {
|
|
30
|
+
return _jsx(Error, { ...statusIconA11yProps });
|
|
27
31
|
}
|
|
28
32
|
if (type === 'caution') {
|
|
29
|
-
return _jsx(Caution, {
|
|
33
|
+
return _jsx(Caution, { ...statusIconA11yProps });
|
|
30
34
|
}
|
|
31
35
|
if (type === 'progress') {
|
|
32
|
-
return _jsx(ProgressIndicator, {});
|
|
36
|
+
return _jsx(ProgressIndicator, { "aria-hidden": true });
|
|
33
37
|
}
|
|
34
|
-
return _jsx(Pending, {
|
|
38
|
+
return _jsx(Pending, { ...statusIconA11yProps });
|
|
35
39
|
})();
|
|
36
40
|
// Handle the duration of the toast
|
|
37
41
|
useEffect(() => {
|
|
@@ -26,13 +26,11 @@ export type ToastProps = {
|
|
|
26
26
|
actionSlot?: ReactNode;
|
|
27
27
|
/**
|
|
28
28
|
* The properties for the status icon.
|
|
29
|
-
* If this prop is not passed, the default values for each property will be applied.
|
|
30
29
|
*
|
|
31
30
|
* @property aria-label - The alternative text for the status icon.
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
* -
|
|
35
|
-
* - 'busy' type: '進行中'
|
|
31
|
+
* By default, the status icon is decorative and hidden from assistive technology (`aria-hidden`),
|
|
32
|
+
* because the message content itself conveys the status.
|
|
33
|
+
* Pass an `aria-label` only when the icon needs to be announced.
|
|
36
34
|
*/
|
|
37
35
|
statusIconProps?: Pick<ComponentPropsWithoutRef<'svg'>, 'aria-label'>;
|
|
38
36
|
/**
|
|
@@ -1,11 +1,27 @@
|
|
|
1
1
|
import { type ToastSlotRecipeVariant } from '../../../styled-system/recipes';
|
|
2
2
|
import { type ToastApiProps } from './toast.types';
|
|
3
|
+
/**
|
|
4
|
+
* Show a toast message
|
|
5
|
+
*
|
|
6
|
+
* @param props - The toast message properties.
|
|
7
|
+
*
|
|
8
|
+
* @param type - The type of the toast message.
|
|
9
|
+
*/
|
|
10
|
+
declare const showToast: (props: ToastApiProps | string, type?: ToastSlotRecipeVariant['type']) => void;
|
|
11
|
+
/**
|
|
12
|
+
* Destroy a toast message.
|
|
13
|
+
* If the key is not provided, all toasts will be destroyed.
|
|
14
|
+
*
|
|
15
|
+
* @param key - The key of the toast message to destroy.
|
|
16
|
+
*/
|
|
17
|
+
declare const destroyToast: (key?: string) => void;
|
|
3
18
|
export declare const toast: {
|
|
4
|
-
show:
|
|
19
|
+
show: typeof showToast;
|
|
5
20
|
success: (props: ToastApiProps | string) => void;
|
|
6
21
|
failure: (props: ToastApiProps | string) => void;
|
|
7
22
|
busy: (props: ToastApiProps | string) => void;
|
|
8
23
|
progress: (props: ToastApiProps | string) => void;
|
|
9
24
|
caution: (props: ToastApiProps | string) => void;
|
|
10
|
-
destroy:
|
|
25
|
+
destroy: typeof destroyToast;
|
|
11
26
|
};
|
|
27
|
+
export {};
|
|
@@ -41,6 +41,6 @@ export declare const Tooltip: import("react").ForwardRefExoticComponent<{
|
|
|
41
41
|
targetDOMNode?: HTMLElement | null;
|
|
42
42
|
disabled?: boolean;
|
|
43
43
|
hideFromScreenReader?: boolean;
|
|
44
|
-
maxWidth?: import("react").CSSProperties[
|
|
45
|
-
contentProps?: Pick<import("react").ComponentPropsWithoutRef<
|
|
46
|
-
} & Omit<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref">, "
|
|
44
|
+
maxWidth?: import("react").CSSProperties['maxWidth'];
|
|
45
|
+
contentProps?: Pick<import("react").ComponentPropsWithoutRef<'div'>, 'className' | 'id'>;
|
|
46
|
+
} & Omit<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref">, "content" | "disabled"> & import("react").RefAttributes<HTMLDivElement>>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import {
|
|
2
|
+
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { forwardRef, useId, useRef, isValidElement, cloneElement, useEffect, useMemo } from 'react';
|
|
4
4
|
import { getOverflowAncestors } from '@floating-ui/react-dom';
|
|
5
5
|
import { cx } from '../../styled-system/css';
|
|
@@ -16,6 +16,8 @@ export type TooltipProps = {
|
|
|
16
16
|
/**
|
|
17
17
|
* Controls the visibility of the tooltip.
|
|
18
18
|
* If not specified, the tooltip will automatically show or hidden by using trigger.
|
|
19
|
+
* When this prop changes back from a boolean to `undefined`, the tooltip closes and
|
|
20
|
+
* returns to trigger-based control (a fresh hover/focus is required to reopen it).
|
|
19
21
|
*
|
|
20
22
|
* @default undefined
|
|
21
23
|
*/
|
|
@@ -42,6 +42,7 @@ export function useTooltipDisplayController({ trigger, wrapperProps, tooltipOpen
|
|
|
42
42
|
const isHoveringTooltip = useRef(false);
|
|
43
43
|
const isHoveringTrigger = useRef(false);
|
|
44
44
|
const previousDisabled = useRef(disabled);
|
|
45
|
+
const previousTooltipOpen = useRef(tooltipOpen);
|
|
45
46
|
const triggers = useMemo(() => (typeof trigger === 'string' ? [trigger] : trigger), [trigger]);
|
|
46
47
|
const onActualClose = useCallback(() => {
|
|
47
48
|
const id = tooltipId.current;
|
|
@@ -218,8 +219,8 @@ export function useTooltipDisplayController({ trigger, wrapperProps, tooltipOpen
|
|
|
218
219
|
}, [closeImmediate]);
|
|
219
220
|
// Handle programmatic control with TooltipManager integration
|
|
220
221
|
useEffect(() => {
|
|
222
|
+
const id = tooltipId.current;
|
|
221
223
|
if (tooltipOpen !== undefined) {
|
|
222
|
-
const id = tooltipId.current;
|
|
223
224
|
if (tooltipOpen) {
|
|
224
225
|
tooltipManager.requestOpen(id);
|
|
225
226
|
}
|
|
@@ -227,7 +228,18 @@ export function useTooltipDisplayController({ trigger, wrapperProps, tooltipOpen
|
|
|
227
228
|
tooltipManager.onClose(id);
|
|
228
229
|
}
|
|
229
230
|
}
|
|
230
|
-
|
|
231
|
+
else if (previousTooltipOpen.current !== undefined) {
|
|
232
|
+
// Leaving controlled mode (`open` became undefined): reset to closed instead of leaking
|
|
233
|
+
// the last state into uncontrolled mode. Trigger handlers are detached while controlled,
|
|
234
|
+
// so the hover/focus tracking refs may be stale — clear them and require a fresh trigger.
|
|
235
|
+
tooltipManager.onClose(id);
|
|
236
|
+
triggerSource.current = undefined;
|
|
237
|
+
isHoveringTrigger.current = false;
|
|
238
|
+
isHoveringTooltip.current = false;
|
|
239
|
+
closeImmediate();
|
|
240
|
+
}
|
|
241
|
+
previousTooltipOpen.current = tooltipOpen;
|
|
242
|
+
}, [tooltipOpen, closeImmediate]);
|
|
231
243
|
useEffect(() => {
|
|
232
244
|
if (disabled && !previousDisabled.current) {
|
|
233
245
|
const id = tooltipId.current;
|
|
@@ -11,4 +11,4 @@
|
|
|
11
11
|
*
|
|
12
12
|
* @param value - The value to set, is string
|
|
13
13
|
*/
|
|
14
|
-
export declare const dispatchNativeInputValueWithEvent: <Element extends HTMLInputElement | HTMLTextAreaElement = HTMLInputElement>(input: Element, value: Element[
|
|
14
|
+
export declare const dispatchNativeInputValueWithEvent: <Element extends HTMLInputElement | HTMLTextAreaElement = HTMLInputElement>(input: Element, value: Element['value']) => void;
|
|
@@ -22,6 +22,6 @@ type Options = {
|
|
|
22
22
|
* @returns The props for the focus trap.
|
|
23
23
|
*/
|
|
24
24
|
export declare function useFocusTrap({ onKeyDown, onPressingTabOnNotFocusableElement }?: Options): {
|
|
25
|
-
handleOnKeyDown:
|
|
25
|
+
handleOnKeyDown: KeyboardEventHandler<HTMLElement>;
|
|
26
26
|
};
|
|
27
27
|
export {};
|