@moneyforward/mfui-components 3.25.1 → 3.27.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/DateTimeSelection/DatePicker/DatePickerCalendar/DatePickerCalendar.js +5 -3
- package/dist/src/DateTimeSelection/shared/BasePicker/BasePicker.d.ts +1 -1
- package/dist/src/DateTimeSelection/shared/BasePicker/BasePicker.js +7 -7
- package/dist/src/DateTimeSelection/shared/BasePicker/BasePicker.types.d.ts +11 -0
- package/dist/src/DropdownMenu/DropdownMenu.d.ts +1 -1
- package/dist/src/DropdownMenu/DropdownMenu.js +3 -3
- package/dist/src/DropdownMenu/DropdownMenu.types.d.ts +57 -5
- package/dist/src/DropdownMenu/DropdownMenuButtonTrigger.d.ts +46 -0
- package/dist/src/DropdownMenu/DropdownMenuButtonTrigger.js +56 -0
- package/dist/src/MultipleSelectBox/MultipleSelectBox.js +31 -23
- package/dist/src/SelectBox/SelectBox.js +25 -17
- package/dist/src/Sidebar/Sidebar.d.ts +63 -0
- package/dist/src/Sidebar/Sidebar.js +82 -0
- package/dist/src/Sidebar/Sidebar.types.d.ts +143 -0
- package/dist/src/Sidebar/Sidebar.types.js +1 -0
- package/dist/src/Sidebar/SidebarNavigationItem.d.ts +9 -0
- package/dist/src/Sidebar/SidebarNavigationItem.js +48 -0
- package/dist/src/Sidebar/SidebarServiceMenu.d.ts +23 -0
- package/dist/src/Sidebar/SidebarServiceMenu.js +20 -0
- package/dist/src/Sidebar/SidebarTenantMenu.d.ts +23 -0
- package/dist/src/Sidebar/SidebarTenantMenu.js +18 -0
- package/dist/src/Sidebar/SidebarUserMenu.d.ts +23 -0
- package/dist/src/Sidebar/SidebarUserMenu.js +18 -0
- package/dist/src/Sidebar/hooks/useSidebarResize.d.ts +28 -0
- package/dist/src/Sidebar/hooks/useSidebarResize.js +111 -0
- package/dist/src/Sidebar/index.d.ts +6 -0
- package/dist/src/Sidebar/index.js +1 -0
- package/dist/src/SplitView/SplitView.js +3 -1
- package/dist/src/SplitView/SplitView.types.d.ts +6 -0
- package/dist/src/SplitView/hooks/useSplitViewDrag.d.ts +1 -0
- package/dist/src/SplitView/hooks/useSplitViewDrag.js +11 -1
- package/dist/src/SplitView/hooks/useSplitViewKeyboard.d.ts +1 -0
- package/dist/src/SplitView/hooks/useSplitViewKeyboard.js +9 -2
- package/dist/src/Tooltip/hooks/useTooltipDisplayController.js +28 -1
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.js +1 -0
- package/dist/src/utilities/react/useIsomorphicLayoutEffect.d.ts +11 -0
- package/dist/src/utilities/react/useIsomorphicLayoutEffect.js +11 -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/sidebar-slot-recipe.d.ts +33 -0
- package/dist/styled-system/recipes/sidebar-slot-recipe.js +112 -0
- package/dist/styled-system/tokens/index.js +6 -6
- package/dist/styles.css +346 -6
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +3 -3
|
@@ -53,9 +53,11 @@ export function DatePickerCalendar({ value, onChange, minDate, maxDate, checkDis
|
|
|
53
53
|
setViewingValue(newDate);
|
|
54
54
|
}, [setViewingValue, viewingValue]);
|
|
55
55
|
const { isPrevYearDisabled, isNextYearDisabled } = useMemo(() => ({
|
|
56
|
-
isPrevYearDisabled: viewingValue.getFullYear() <= MINIMUM_VIEWABLE_YEAR
|
|
57
|
-
|
|
58
|
-
|
|
56
|
+
isPrevYearDisabled: viewingValue.getFullYear() <= MINIMUM_VIEWABLE_YEAR ||
|
|
57
|
+
(minDate ? viewingValue.getFullYear() <= minDate.getFullYear() : false),
|
|
58
|
+
isNextYearDisabled: viewingValue.getFullYear() >= MAXIMUM_VIEWABLE_YEAR ||
|
|
59
|
+
(maxDate ? viewingValue.getFullYear() >= maxDate.getFullYear() : false),
|
|
60
|
+
}), [viewingValue, minDate, maxDate]);
|
|
59
61
|
const { isPrevMonthDisabled, isNextMonthDisabled } = useMemo(() => {
|
|
60
62
|
const firstDayOfMonth = new Date(viewingValue.getFullYear(), viewingValue.getMonth(), 1);
|
|
61
63
|
const firstDayOfNextMonth = new Date(viewingValue.getFullYear(), viewingValue.getMonth() + 1, 1);
|
|
@@ -4,4 +4,4 @@ import { type BasePickerProps } from './BasePicker.types';
|
|
|
4
4
|
* This component uses the composition component of the TextBox component. Please refer to the TextBox documentation for their usage.
|
|
5
5
|
* This component extends the props of TextBox component.
|
|
6
6
|
*/
|
|
7
|
-
export declare function BasePicker({ targetDOMNode, enableAutoUnmount, open, onOpenStateChanged, disableAutoOpen, format, baseFormat, customFormatValue, value, defaultValue, onChange, calendarIconButtonProps, renderPopoverContent, onBlur, allowedPlacements, enableViewportConstraint, calendarLocale, disabled, ...textBoxProps }: BasePickerProps): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export declare function BasePicker({ targetDOMNode, enableAutoUnmount, open, onOpenStateChanged, disableAutoOpen, format, baseFormat, customFormatValue, value, defaultValue, initialViewingDate, onChange, calendarIconButtonProps, renderPopoverContent, onBlur, allowedPlacements, enableViewportConstraint, calendarLocale, disabled, ...textBoxProps }: BasePickerProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -18,7 +18,7 @@ import { getBasePickerLabel } from './constants';
|
|
|
18
18
|
* This component uses the composition component of the TextBox component. Please refer to the TextBox documentation for their usage.
|
|
19
19
|
* This component extends the props of TextBox component.
|
|
20
20
|
*/
|
|
21
|
-
export function BasePicker({ targetDOMNode, enableAutoUnmount = true, open = false, onOpenStateChanged, disableAutoOpen = false, format = 'YYYY/MM/DD', baseFormat = 'YYYY-MM-DD', customFormatValue, value, defaultValue, onChange, calendarIconButtonProps, renderPopoverContent, onBlur, allowedPlacements, enableViewportConstraint, calendarLocale = 'ja', disabled, ...textBoxProps }) {
|
|
21
|
+
export function BasePicker({ targetDOMNode, enableAutoUnmount = true, open = false, onOpenStateChanged, disableAutoOpen = false, format = 'YYYY/MM/DD', baseFormat = 'YYYY-MM-DD', customFormatValue, value, defaultValue, initialViewingDate, onChange, calendarIconButtonProps, renderPopoverContent, onBlur, allowedPlacements, enableViewportConstraint, calendarLocale = 'ja', disabled, ...textBoxProps }) {
|
|
22
22
|
const textBoxRef = useRef(null);
|
|
23
23
|
const basePickerPopoverWrapperRef = useRef(null);
|
|
24
24
|
const triggerRef = useRef(null);
|
|
@@ -76,7 +76,7 @@ export function BasePicker({ targetDOMNode, enableAutoUnmount = true, open = fal
|
|
|
76
76
|
}
|
|
77
77
|
openPopover(event);
|
|
78
78
|
}, [textBoxProps.wrapperProps, textBoxRef]);
|
|
79
|
-
return (_jsx(BasePickerProvider, { initialViewingValue: value ?? defaultValue, value: value, internalValue: inputValueProps.value, format: format, baseFormat: baseFormat, children: _jsx(InternalPopover, { renderTrigger: ({ setTriggerRef, togglePopover, openPopover, handleTriggerKeyDown, handleTriggerBlur }) => (_jsx(TextBox, { ref: textBoxRef, ...inputValueProps, touchDeviceReadOnly: true, suffixSlot: _jsx(IconButton, { size: textBoxProps.textBoxSize === 'small' ? 'small' : 'default', "aria-label": calendarIconButtonProps?.['aria-label'] ?? calendarIconLabel, "data-active": shouldCalendarIconActive, "data-mfui-content": "calendar-icon-button", disabled: disabled, onClick: togglePopover, onBlur: handleTriggerBlur, children: _jsx(Calendar, {}) }), disabled: disabled, ...textBoxProps, wrapperProps: {
|
|
79
|
+
return (_jsx(BasePickerProvider, { initialViewingValue: value ?? defaultValue ?? initialViewingDate, value: value, internalValue: inputValueProps.value, format: format, baseFormat: baseFormat, children: _jsx(InternalPopover, { renderTrigger: ({ setTriggerRef, togglePopover, openPopover, handleTriggerKeyDown, handleTriggerBlur }) => (_jsx(TextBox, { ref: textBoxRef, ...inputValueProps, touchDeviceReadOnly: true, suffixSlot: _jsx(IconButton, { size: textBoxProps.textBoxSize === 'small' ? 'small' : 'default', "aria-label": calendarIconButtonProps?.['aria-label'] ?? calendarIconLabel, "data-active": shouldCalendarIconActive, "data-mfui-content": "calendar-icon-button", disabled: disabled, onClick: togglePopover, onBlur: handleTriggerBlur, children: _jsx(Calendar, {}) }), disabled: disabled, ...textBoxProps, wrapperProps: {
|
|
80
80
|
...textBoxProps.wrapperProps,
|
|
81
81
|
ref: mergeRefs(setTriggerRef, triggerRef, textBoxProps.wrapperProps?.ref),
|
|
82
82
|
onKeyDown: (event) => {
|
|
@@ -93,7 +93,7 @@ export function BasePicker({ targetDOMNode, enableAutoUnmount = true, open = fal
|
|
|
93
93
|
inputValueProps.onBlur(event);
|
|
94
94
|
// Then call the Popover's smart blur detection
|
|
95
95
|
handleTriggerBlur(event);
|
|
96
|
-
} })), open: isBasePickerOpen, targetDOMNode: targetDOMNode, enableAutoUnmount: enableAutoUnmount, minWidth: "min-content", value: value, defaultValue: defaultValue, baseFormat: baseFormat, renderPopoverContent: renderPopoverContent, textBoxRef: textBoxRef, triggerRef: triggerRef, basePickerPopoverWrapperRef: basePickerPopoverWrapperRef, handleOnKeyDown: handleOnKeyDown, pickerPopoverProps: pickerPopoverProps, allowedPlacements: allowedPlacements, enableViewportConstraint: enableViewportConstraint, onOpenStateChanged: toggleBasePicker, onBlur: onBlur }) }));
|
|
96
|
+
} })), open: isBasePickerOpen, targetDOMNode: targetDOMNode, enableAutoUnmount: enableAutoUnmount, minWidth: "min-content", value: value, defaultValue: defaultValue, initialViewingDate: initialViewingDate, baseFormat: baseFormat, renderPopoverContent: renderPopoverContent, textBoxRef: textBoxRef, triggerRef: triggerRef, basePickerPopoverWrapperRef: basePickerPopoverWrapperRef, handleOnKeyDown: handleOnKeyDown, pickerPopoverProps: pickerPopoverProps, allowedPlacements: allowedPlacements, enableViewportConstraint: enableViewportConstraint, onOpenStateChanged: toggleBasePicker, onBlur: onBlur }) }));
|
|
97
97
|
}
|
|
98
98
|
/**
|
|
99
99
|
* Internal Popover component that needs access to BasePickerContext.
|
|
@@ -101,7 +101,7 @@ export function BasePicker({ targetDOMNode, enableAutoUnmount = true, open = fal
|
|
|
101
101
|
* which requires being within a BasePickerProvider. Creating it as an internal
|
|
102
102
|
* component ensures proper context access while keeping the logic encapsulated.
|
|
103
103
|
*/
|
|
104
|
-
function InternalPopover({ value, defaultValue, textBoxRef, triggerRef, baseFormat = 'YYYY-MM-DD', renderPopoverContent, basePickerPopoverWrapperRef, handleOnKeyDown, pickerPopoverProps, onOpenStateChanged, allowedPlacements, enableViewportConstraint, ...popoverProps }) {
|
|
104
|
+
function InternalPopover({ value, defaultValue, initialViewingDate, textBoxRef, triggerRef, baseFormat = 'YYYY-MM-DD', renderPopoverContent, basePickerPopoverWrapperRef, handleOnKeyDown, pickerPopoverProps, onOpenStateChanged, allowedPlacements, enableViewportConstraint, ...popoverProps }) {
|
|
105
105
|
// Always call the hook at the top level to ensure consistent hook order
|
|
106
106
|
const { viewingValue, setViewingValue, setPendingFocusDate } = useBasePickerContext();
|
|
107
107
|
const handlePopoverOpen = useCallback((event) => {
|
|
@@ -119,8 +119,8 @@ function InternalPopover({ value, defaultValue, textBoxRef, triggerRef, baseForm
|
|
|
119
119
|
!isClickOnClearButton;
|
|
120
120
|
if (isClickOnTextBox || isClickOnWrapper)
|
|
121
121
|
return;
|
|
122
|
-
// Get the date to focus on
|
|
123
|
-
const dateToFocus = dayjs(value ?? defaultValue ?? new Date())
|
|
122
|
+
// Get the date to focus on: selected value → initialViewingDate → today
|
|
123
|
+
const dateToFocus = dayjs(value ?? defaultValue ?? initialViewingDate ?? new Date())
|
|
124
124
|
.startOf('day')
|
|
125
125
|
.toDate();
|
|
126
126
|
const formattedDate = dayjs(dateToFocus).format(baseFormat);
|
|
@@ -128,7 +128,7 @@ function InternalPopover({ value, defaultValue, textBoxRef, triggerRef, baseForm
|
|
|
128
128
|
setViewingValue(dayjs(dateToFocus).startOf('month').startOf('day').toDate());
|
|
129
129
|
// Set the pending focus date to ensure proper focus after month change
|
|
130
130
|
setPendingFocusDate(formattedDate);
|
|
131
|
-
}, [textBoxRef, triggerRef, value, defaultValue, baseFormat, setViewingValue, setPendingFocusDate]);
|
|
131
|
+
}, [textBoxRef, triggerRef, value, defaultValue, initialViewingDate, baseFormat, setViewingValue, setPendingFocusDate]);
|
|
132
132
|
return (_jsx(Popover, { enableAutomaticPortalTargetResolution: true, enableViewportConstraint: enableViewportConstraint ?? false, enableAutoFocusOnPopover: false, ...popoverProps, renderContent: () => (_jsx("div", { ref: basePickerPopoverWrapperRef, className: "mfui-BasePicker__popoverWrapper", onKeyDown: handleOnKeyDown, children: renderPopoverContent({
|
|
133
133
|
viewingValue,
|
|
134
134
|
setViewingValue,
|
|
@@ -97,6 +97,17 @@ export type BasePickerProps = {
|
|
|
97
97
|
* @default 'ja'
|
|
98
98
|
*/
|
|
99
99
|
calendarLocale?: 'ja' | 'en';
|
|
100
|
+
/**
|
|
101
|
+
* The initial date the calendar view is centered on when the picker is opened without a selected value.
|
|
102
|
+
* Useful when `minDate` is in the future — without this, the calendar would open showing today
|
|
103
|
+
* even though all visible dates are disabled.
|
|
104
|
+
*
|
|
105
|
+
* When `value` or `defaultValue` is set, this prop is ignored because the calendar always
|
|
106
|
+
* navigates to the selected date's month.
|
|
107
|
+
*
|
|
108
|
+
* @default undefined (falls back to today)
|
|
109
|
+
*/
|
|
110
|
+
initialViewingDate?: Date;
|
|
100
111
|
/**
|
|
101
112
|
* Custom render function for the popover content. This is required to make BasePicker truly generic.
|
|
102
113
|
*
|
|
@@ -19,7 +19,7 @@ import { DropdownMenuHeading } from './DropdownMenuHeading';
|
|
|
19
19
|
* </DropdownMenu>
|
|
20
20
|
* ```
|
|
21
21
|
*/
|
|
22
|
-
export declare function DropdownMenu({ icon, label, children, triggerProps, menuPopoverProps, disabled, targetDOMNode, enableAutoUnmount, onOpenStateChanged, onBlur, }: DropdownMenuProps<ReactElement | undefined>): import("react/jsx-runtime").JSX.Element;
|
|
22
|
+
export declare function DropdownMenu({ icon, label, children, triggerProps, tooltipLabel, tooltipPlacement, triggerMiddleTruncate, triggerTypographyVariant, menuPopoverProps, disabled, targetDOMNode, enableAutoUnmount, onOpenStateChanged, onBlur, }: DropdownMenuProps<ReactElement | undefined>): import("react/jsx-runtime").JSX.Element;
|
|
23
23
|
export declare namespace DropdownMenu {
|
|
24
24
|
var Divider: typeof DropdownMenuDivider;
|
|
25
25
|
var Item: typeof DropdownMenuItem;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
3
|
import { useCallback, useState } from 'react';
|
|
4
|
-
import {
|
|
4
|
+
import { DropdownMenuButtonTrigger } from './DropdownMenuButtonTrigger';
|
|
5
5
|
import { DropdownMenuContainer } from './DropdownMenuContainer';
|
|
6
6
|
import { DropdownMenuDivider } from './DropdownMenuDivider';
|
|
7
7
|
import { DropdownMenuItem } from './DropdownMenuItem';
|
|
@@ -27,7 +27,7 @@ import { DropdownMenuHeading } from './DropdownMenuHeading';
|
|
|
27
27
|
* </DropdownMenu>
|
|
28
28
|
* ```
|
|
29
29
|
*/
|
|
30
|
-
export function DropdownMenu({ icon, label, children, triggerProps, menuPopoverProps, disabled, targetDOMNode, enableAutoUnmount, onOpenStateChanged, onBlur, }) {
|
|
30
|
+
export function DropdownMenu({ icon, label, children, triggerProps, tooltipLabel, tooltipPlacement, triggerMiddleTruncate, triggerTypographyVariant, menuPopoverProps, disabled, targetDOMNode, enableAutoUnmount, onOpenStateChanged, onBlur, }) {
|
|
31
31
|
const [menuDefaultFocusPosition, setMenuDefaultFocusPosition] = useState('first');
|
|
32
32
|
const handleTriggerKeyDownLocal = useCallback((event) => {
|
|
33
33
|
switch (event.key) {
|
|
@@ -49,7 +49,7 @@ export function DropdownMenu({ icon, label, children, triggerProps, menuPopoverP
|
|
|
49
49
|
handleTriggerKeyDownLocal(event);
|
|
50
50
|
handleTriggerKeyDown(event);
|
|
51
51
|
};
|
|
52
|
-
return icon ? (_jsx(IconButton, { ref: setTriggerRef, "aria-expanded": isPopoverOpen, "aria-haspopup": "menu", disabled: disabled, onKeyDown: handleKeyDownCommon, onBlur: handleTriggerBlur, onClick: togglePopover, ...triggerProps, "aria-label": label, children: icon })) : (_jsx(
|
|
52
|
+
return icon ? (_jsx(IconButton, { ref: setTriggerRef, "aria-expanded": isPopoverOpen, "aria-haspopup": "menu", disabled: disabled, onKeyDown: handleKeyDownCommon, onBlur: handleTriggerBlur, onClick: togglePopover, ...triggerProps, "aria-label": label, children: icon })) : (_jsx(DropdownMenuButtonTrigger, { label: label, tooltipLabel: tooltipLabel, tooltipPlacement: tooltipPlacement, triggerMiddleTruncate: triggerMiddleTruncate, triggerTypographyVariant: triggerTypographyVariant, triggerProps: triggerProps, disabled: disabled, isPopoverOpen: isPopoverOpen, setTriggerRef: setTriggerRef, togglePopover: togglePopover, handleTriggerKeyDown: handleKeyDownCommon, handleTriggerBlur: handleTriggerBlur }));
|
|
53
53
|
}, renderContent: ({ closePopover }) => (_jsx(DropdownMenuProvider, { value: { closeMenuPopover: closePopover }, children: _jsx(DropdownMenuContainer, { defaultFocusItem: menuDefaultFocusPosition, onClose: closePopover, children: children }) })), enableAutoFocusOnPopover: false, enableAutoUnmount: enableAutoUnmount, contentProps: {
|
|
54
54
|
className: cx(classes.popover, menuPopoverProps?.className),
|
|
55
55
|
}, onBlur: onBlur, onOpenStateChanged: onOpenStateChanged }));
|
|
@@ -2,6 +2,47 @@ import { type ComponentPropsWithoutRef, type ReactElement, type ReactNode } from
|
|
|
2
2
|
import { type ButtonProps } from '../Button';
|
|
3
3
|
import { type IconButtonProps } from '../IconButton';
|
|
4
4
|
import { type PopoverProps } from '../Popover';
|
|
5
|
+
import { type TooltipProps } from '../Tooltip';
|
|
6
|
+
import { type TypographyProps } from '../Typography';
|
|
7
|
+
/**
|
|
8
|
+
* The props of the default Button-based trigger that are managed by the DropdownMenu itself
|
|
9
|
+
* (as opposed to `triggerProps`, which is forwarded to the underlying Button).
|
|
10
|
+
*
|
|
11
|
+
* These describe trigger-presentation concerns that the Button cannot express on its own:
|
|
12
|
+
* a describing tooltip and middle truncation of the label.
|
|
13
|
+
*/
|
|
14
|
+
export type DropdownMenuButtonTriggerProps = {
|
|
15
|
+
/**
|
|
16
|
+
* The tooltip label describing what the trigger is (e.g. `"事業者"`).
|
|
17
|
+
* Shown on hover/focus and wired to the trigger via `aria-describedby` for screen readers.
|
|
18
|
+
* When omitted, no tooltip is shown.
|
|
19
|
+
*/
|
|
20
|
+
tooltipLabel?: string;
|
|
21
|
+
/**
|
|
22
|
+
* The placement of the trigger tooltip (only applied when `tooltipLabel` is set).
|
|
23
|
+
*
|
|
24
|
+
* Accepts a single placement (e.g. `"top"`) for fixed positioning, or an array
|
|
25
|
+
* (e.g. `["top", "bottom"]`) for priority-based positioning with fallbacks.
|
|
26
|
+
* When omitted, the tooltip is placed automatically.
|
|
27
|
+
*/
|
|
28
|
+
tooltipPlacement?: TooltipProps['placement'];
|
|
29
|
+
/**
|
|
30
|
+
* Whether the trigger label is middle-truncated (e.g. `"Money…ward"`) when it overflows
|
|
31
|
+
* the available width. When omitted, the label is not truncated by the component.
|
|
32
|
+
*
|
|
33
|
+
* @default false
|
|
34
|
+
*/
|
|
35
|
+
triggerMiddleTruncate?: boolean;
|
|
36
|
+
/**
|
|
37
|
+
* The Typography variant of the trigger label. Use this when the label needs a different
|
|
38
|
+
* type style than the default (e.g. `"condensedControlLabel"`).
|
|
39
|
+
*
|
|
40
|
+
* Only applied when `tooltipLabel` or `triggerMiddleTruncate` is set.
|
|
41
|
+
*
|
|
42
|
+
* @default 'controlLabel'
|
|
43
|
+
*/
|
|
44
|
+
triggerTypographyVariant?: TypographyProps['variant'];
|
|
45
|
+
};
|
|
5
46
|
type DropdownMenuCommonProps = {
|
|
6
47
|
/**
|
|
7
48
|
* The list of the dropdown menu.
|
|
@@ -26,7 +67,7 @@ type DropdownMenuCommonProps = {
|
|
|
26
67
|
* If the icon prop is provided, the label prop will be set as the aria-label of the icon button.
|
|
27
68
|
* If the icon prop is not provided, the label prop will be set as the label of the button.
|
|
28
69
|
*/
|
|
29
|
-
label
|
|
70
|
+
label?: string;
|
|
30
71
|
/**
|
|
31
72
|
* The properties for the popover content panel.
|
|
32
73
|
*
|
|
@@ -77,7 +118,14 @@ type DropdownMenuCommonProps = {
|
|
|
77
118
|
*/
|
|
78
119
|
onBlur?: (event: React.FocusEvent<HTMLElement>) => void;
|
|
79
120
|
};
|
|
80
|
-
type
|
|
121
|
+
type DropdownMenuButtonTriggerPropsNever = {
|
|
122
|
+
[K in keyof DropdownMenuButtonTriggerProps]?: undefined;
|
|
123
|
+
};
|
|
124
|
+
type DropdownMenuPropsWithIcon = DropdownMenuButtonTriggerPropsNever & {
|
|
125
|
+
/**
|
|
126
|
+
* The aria-label of the trigger icon button of the dropdown menu.
|
|
127
|
+
*/
|
|
128
|
+
label: string;
|
|
81
129
|
icon: ReactElement;
|
|
82
130
|
/**
|
|
83
131
|
* Button component and the IconButton component.
|
|
@@ -90,6 +138,10 @@ type DropdownMenuPropsWithIcon = {
|
|
|
90
138
|
triggerProps?: Pick<IconButtonProps, 'outlined' | 'className'>;
|
|
91
139
|
};
|
|
92
140
|
type DropdownMenuPropsWithoutIcon = {
|
|
141
|
+
/**
|
|
142
|
+
* The label of the trigger button of the dropdown menu.
|
|
143
|
+
*/
|
|
144
|
+
label: string;
|
|
93
145
|
icon?: undefined;
|
|
94
146
|
/**
|
|
95
147
|
* Button component and the IconButton component.
|
|
@@ -97,9 +149,9 @@ type DropdownMenuPropsWithoutIcon = {
|
|
|
97
149
|
* Use this prop if you need to customize the style of the trigger button.
|
|
98
150
|
*
|
|
99
151
|
* If the icon prop is not provided, the following props are acceptable as props of the Button component:
|
|
100
|
-
* 'size' | 'priority' | 'destructive' | 'leftIcon' | 'loading' | 'className'
|
|
152
|
+
* 'size' | 'priority' | 'destructive' | 'leftIcon' | 'loading' | 'className' | 'isDropdownTrigger'
|
|
101
153
|
*/
|
|
102
|
-
triggerProps?: Pick<ButtonProps, 'size' | 'priority' | 'destructive' | 'leftIcon' | 'loading' | 'className'>;
|
|
103
|
-
};
|
|
154
|
+
triggerProps?: Pick<ButtonProps, 'size' | 'priority' | 'destructive' | 'leftIcon' | 'loading' | 'className' | 'isDropdownTrigger'>;
|
|
155
|
+
} & DropdownMenuButtonTriggerProps;
|
|
104
156
|
export type DropdownMenuProps<IconType = undefined> = DropdownMenuCommonProps & (IconType extends ReactElement ? DropdownMenuPropsWithIcon : DropdownMenuPropsWithoutIcon) & Pick<PopoverProps, 'targetDOMNode' | 'enableAutoUnmount'>;
|
|
105
157
|
export {};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { type FocusEventHandler, type KeyboardEventHandler, type SyntheticEvent } from 'react';
|
|
2
|
+
import { type ButtonProps } from '../Button';
|
|
3
|
+
import { type DropdownMenuButtonTriggerProps } from './DropdownMenu.types';
|
|
4
|
+
type DropdownMenuButtonTriggerComponentProps = DropdownMenuButtonTriggerProps & {
|
|
5
|
+
/**
|
|
6
|
+
* The accessible label / visible text of the trigger button.
|
|
7
|
+
*/
|
|
8
|
+
label: string;
|
|
9
|
+
/**
|
|
10
|
+
* Props forwarded to the underlying Button for design customization.
|
|
11
|
+
*/
|
|
12
|
+
triggerProps?: Pick<ButtonProps, 'size' | 'priority' | 'destructive' | 'leftIcon' | 'loading' | 'className' | 'isDropdownTrigger'>;
|
|
13
|
+
/**
|
|
14
|
+
* The disabled state of the trigger.
|
|
15
|
+
*/
|
|
16
|
+
disabled?: boolean;
|
|
17
|
+
/**
|
|
18
|
+
* The current open state of the dropdown menu, used for `aria-expanded`.
|
|
19
|
+
*/
|
|
20
|
+
isPopoverOpen: boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Ref setter for the trigger element so the popover can position itself.
|
|
23
|
+
*/
|
|
24
|
+
setTriggerRef: (element: HTMLElement | null) => void;
|
|
25
|
+
/**
|
|
26
|
+
* Toggles the open state of the dropdown menu.
|
|
27
|
+
*/
|
|
28
|
+
togglePopover: (event?: SyntheticEvent) => void;
|
|
29
|
+
/**
|
|
30
|
+
* Keyboard handler for the trigger (ArrowUp / ArrowDown focus behavior already merged in).
|
|
31
|
+
*/
|
|
32
|
+
handleTriggerKeyDown: KeyboardEventHandler<HTMLElement>;
|
|
33
|
+
/**
|
|
34
|
+
* Blur handler for the trigger with smart blur detection.
|
|
35
|
+
*/
|
|
36
|
+
handleTriggerBlur: FocusEventHandler<HTMLElement>;
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* The default Button-based trigger of the DropdownMenu.
|
|
40
|
+
*
|
|
41
|
+
* On top of the plain Button trigger, it wires up the optional trigger features that are owned by
|
|
42
|
+
* the DropdownMenu rather than the Button: a describing tooltip (`tooltipLabel`) and middle
|
|
43
|
+
* truncation of the label (`triggerMiddleTruncate`). Design customization stays on `triggerProps`.
|
|
44
|
+
*/
|
|
45
|
+
export declare function DropdownMenuButtonTrigger({ label, tooltipLabel, tooltipPlacement, triggerMiddleTruncate, triggerTypographyVariant, triggerProps, disabled, isPopoverOpen, setTriggerRef, togglePopover, handleTriggerKeyDown, handleTriggerBlur, }: DropdownMenuButtonTriggerComponentProps): import("react/jsx-runtime").JSX.Element;
|
|
46
|
+
export {};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { useRef } from 'react';
|
|
4
|
+
import { Button } from '../Button';
|
|
5
|
+
import { Tooltip } from '../Tooltip';
|
|
6
|
+
import { Typography } from '../Typography';
|
|
7
|
+
import { useMiddleTruncatedText } from '../utilities/dom/useMiddleTruncatedText';
|
|
8
|
+
const TRUNCATED_LABEL_STYLE = {
|
|
9
|
+
overflow: 'hidden',
|
|
10
|
+
textOverflow: 'ellipsis',
|
|
11
|
+
whiteSpace: 'nowrap',
|
|
12
|
+
flex: '1 0 0',
|
|
13
|
+
minWidth: '1px',
|
|
14
|
+
color: 'inherit',
|
|
15
|
+
};
|
|
16
|
+
// The tooltip wraps the trigger Button (so focus on the button bubbles up to the tooltip and shows
|
|
17
|
+
// it on keyboard focus). The wrapper must not shrink the full-width trigger, hence `width: 100%`.
|
|
18
|
+
const TOOLTIP_WRAPPER_STYLE = {
|
|
19
|
+
display: 'flex',
|
|
20
|
+
minWidth: 0,
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* The default Button-based trigger of the DropdownMenu.
|
|
24
|
+
*
|
|
25
|
+
* On top of the plain Button trigger, it wires up the optional trigger features that are owned by
|
|
26
|
+
* the DropdownMenu rather than the Button: a describing tooltip (`tooltipLabel`) and middle
|
|
27
|
+
* truncation of the label (`triggerMiddleTruncate`). Design customization stays on `triggerProps`.
|
|
28
|
+
*/
|
|
29
|
+
export function DropdownMenuButtonTrigger({ label, tooltipLabel, tooltipPlacement, triggerMiddleTruncate = false, triggerTypographyVariant = 'controlLabel', triggerProps, disabled, isPopoverOpen, setTriggerRef, togglePopover, handleTriggerKeyDown, handleTriggerBlur, }) {
|
|
30
|
+
const labelRef = useRef(null);
|
|
31
|
+
// The ref is only attached when middle truncation is enabled, so the hook is a no-op otherwise.
|
|
32
|
+
const truncatedLabel = useMiddleTruncatedText(label, labelRef);
|
|
33
|
+
const sharedButtonProps = {
|
|
34
|
+
ref: setTriggerRef,
|
|
35
|
+
'aria-expanded': isPopoverOpen,
|
|
36
|
+
'aria-haspopup': 'menu',
|
|
37
|
+
disabled,
|
|
38
|
+
onKeyDown: handleTriggerKeyDown,
|
|
39
|
+
onBlur: handleTriggerBlur,
|
|
40
|
+
onClick: togglePopover,
|
|
41
|
+
};
|
|
42
|
+
// The label needs custom rendering (Typography / truncation span) only when one of the managed
|
|
43
|
+
// trigger features is requested. Otherwise the plain string label is passed to the Button,
|
|
44
|
+
// preserving the existing default-trigger behavior.
|
|
45
|
+
const needsCustomLabel = tooltipLabel != null || triggerMiddleTruncate;
|
|
46
|
+
if (!needsCustomLabel) {
|
|
47
|
+
return (_jsx(Button, { isDropdownTrigger: true, ...sharedButtonProps, ...triggerProps, children: label }));
|
|
48
|
+
}
|
|
49
|
+
const trigger = (_jsx(Button, { isDropdownTrigger: true, ...sharedButtonProps, ...triggerProps, "aria-label": label, children: _jsx(Typography, { variant: triggerTypographyVariant, style: TRUNCATED_LABEL_STYLE, children: triggerMiddleTruncate ? _jsx("span", { ref: labelRef, children: truncatedLabel }) : label }) }));
|
|
50
|
+
if (tooltipLabel == null) {
|
|
51
|
+
return trigger;
|
|
52
|
+
}
|
|
53
|
+
// Wrap the trigger (not its inner label) so the tooltip opens on keyboard focus of the button and
|
|
54
|
+
// its content is wired to the button via `aria-describedby` automatically by the Tooltip.
|
|
55
|
+
return (_jsx(Tooltip, { content: tooltipLabel, placement: tooltipPlacement, style: TOOLTIP_WRAPPER_STYLE, children: trigger }));
|
|
56
|
+
}
|
|
@@ -295,10 +295,15 @@ placeholder, emptyMessage, disabled, invalid, targetDOMNode, name, onChange, val
|
|
|
295
295
|
tabbableOptionIndex,
|
|
296
296
|
]);
|
|
297
297
|
// Render infinite scroll error message with retry button
|
|
298
|
-
const renderInfiniteScrollError = useCallback((
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
298
|
+
const renderInfiniteScrollError = useCallback((as = 'li') => {
|
|
299
|
+
if (!infiniteScrollError)
|
|
300
|
+
return null;
|
|
301
|
+
const Tag = as;
|
|
302
|
+
return (_jsxs(Tag, { className: cx(classes.infiniteScrollError, 'mfui-MultipleSelectBox__infiniteScrollError'), role: "alert", children: [_jsxs("div", { className: cx(classes.infiniteScrollErrorMessage, 'mfui-MultipleSelectBox__infiniteScrollErrorMessage'), "aria-live": "polite", children: [_jsx(Error, { "aria-hidden": true, className: cx(classes.infiniteScrollErrorIcon, 'mfui-MultipleSelectBox__infiniteScrollErrorIcon') }), _jsx(Typography, { variant: "body", children: infiniteScrollErrorMessage })] }), _jsx("div", { className: cx(classes.infiniteScrollErrorButton, 'mfui-MultipleSelectBox__infiniteScrollErrorButton'), children: _jsx(Button, { size: "small", onClick: (event) => {
|
|
303
|
+
event.stopPropagation();
|
|
304
|
+
retryInfiniteScroll();
|
|
305
|
+
}, children: infiniteScrollRetryButtonText }) })] }));
|
|
306
|
+
}, [
|
|
302
307
|
infiniteScrollError,
|
|
303
308
|
classes.infiniteScrollError,
|
|
304
309
|
classes.infiniteScrollErrorIcon,
|
|
@@ -317,26 +322,29 @@ placeholder, emptyMessage, disabled, invalid, targetDOMNode, name, onChange, val
|
|
|
317
322
|
: (selectedCountProps?.render?.(localSelectedValuesSet.size) ??
|
|
318
323
|
`${String(localSelectedValuesSet.size)}件選択中`) })) : null;
|
|
319
324
|
const applyControlsNode = enableApplyControls ? (_jsxs(HStack, { gap: "horizontal.0-1of2", children: [_jsx(Button, { ref: cancelButtonRef, size: "small", priority: "secondary", onClick: handleCancelButtonClick, children: cancelButtonProps?.label ?? 'キャンセル' }), _jsx(Button, { ref: applyButtonRef, size: "small", priority: "primary", onClick: handleApplyButtonClick, children: applyButtonProps?.label ?? '適用' })] })) : null;
|
|
320
|
-
const optionsNode = (
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
325
|
+
const optionsNode = (_jsxs("div", { ref: scrollWrapperRef, className: cx(classes.scrollWrapper, 'mfui-MultipleSelectBox__scrollWrapper'), onScroll: enableInfiniteScroll ? handleInfiniteScroll : undefined, children: [_jsx("ul", { ref: listBoxRef, role: "listbox", id: listBoxId, className: cx(classes.listBox, 'mfui-MultipleSelectBox__listBox'), tabIndex: -1, style: isVirtualized && totalSize > 0
|
|
326
|
+
? {
|
|
327
|
+
height: `${String(totalSize)}px`,
|
|
328
|
+
position: 'relative',
|
|
329
|
+
}
|
|
330
|
+
: undefined, children: loading
|
|
331
|
+
? Array.from({ length: SKELETON_ITEM_COUNT }).map((_, index) => (_jsx("li", { className: cx(classes.skeletonItem, 'mfui-MultipleSelectBox__skeletonItem'), children: _jsx(Skeleton, {}) }, index)))
|
|
332
|
+
: isVirtualized && virtualItems.length > 0
|
|
333
|
+
? renderVirtualizedItems()
|
|
334
|
+
: filteredOptions.length > 0
|
|
335
|
+
? [
|
|
336
|
+
...renderNonVirtualizedItems(),
|
|
337
|
+
!isVirtualized && renderInfiniteScrollLoading(),
|
|
338
|
+
!isVirtualized && renderInfiniteScrollError(),
|
|
339
|
+
].filter(Boolean)
|
|
340
|
+
: [
|
|
341
|
+
_jsx("li", { className: cx(classes.emptyMessage, 'mfui-MultipleSelectBox__emptyMessage'), children: _jsx(Typography, { variant: "body", children: enableSearchOptions && searchText && notFoundMessage
|
|
336
342
|
? notFoundMessage
|
|
337
|
-
:
|
|
338
|
-
|
|
339
|
-
|
|
343
|
+
: options.length > 0
|
|
344
|
+
? notFoundMessage
|
|
345
|
+
: emptyMessage }) }, "empty"),
|
|
346
|
+
!isVirtualized && renderInfiniteScrollError(),
|
|
347
|
+
].filter(Boolean) }), isVirtualized ? renderInfiniteScrollLoading() : null, isVirtualized ? renderInfiniteScrollError('div') : null] }));
|
|
340
348
|
const createOptionAreaNode = isCreateOptionVisible ? (_jsxs("div", { className: cx(classes.createOptionArea, 'mfui-MultipleSelectBox__createOptionArea'), children: [_jsxs("button", { "data-mfui-content": "create-new-option", type: "button", className: cx(classes.createOptionButton, 'mfui-MultipleSelectBox__createOptionButton'), disabled: isCreating, onClick: handleCreateOption, children: [_jsx(Add, { "aria-hidden": true }), createOptionProps?.renderLabel?.(searchText.trim()) ?? (_jsxs(_Fragment, { children: [_jsx(Typography, { variant: "strongBody", children: searchText.trim() }), _jsx(Typography, { variant: "body", children: "\u3092\u8FFD\u52A0" })] }))] }), createError ? (_jsx("div", { className: cx(classes.createOptionErrorMessage, 'mfui-MultipleSelectBox__createOptionErrorMessage'), children: _jsx(HelpMessage, { messageType: "error", children: createOptionProps?.renderErrorMessage?.(searchText.trim()) ??
|
|
341
349
|
`${searchText.trim()}を追加できませんでした。` }) })) : null] })) : null;
|
|
342
350
|
return (_jsx(Popover, { renderTrigger: ({ setTriggerRef, togglePopover, handleTriggerKeyDown, handleTriggerBlur }) => (_jsx(MultipleSelectBoxTrigger, { ref: triggerRef, wrapperRef: setTriggerRef, selectedOptions: localSelectedOptions, id: id, disabled: disabled, triggerProps: triggerProps, triggerWrapperProps: triggerWrapperProps, name: name,
|
|
@@ -284,10 +284,15 @@ export const SelectBox = forwardRef((props, ref) => {
|
|
|
284
284
|
? notFoundMessage
|
|
285
285
|
: emptyMessage }) }, "empty-message")), [classes.emptyMessage, enableSearchOptions, searchText, notFoundMessage, options.length, emptyMessage]);
|
|
286
286
|
// Render infinite scroll error message with retry button
|
|
287
|
-
const renderInfiniteScrollError = useCallback((
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
287
|
+
const renderInfiniteScrollError = useCallback((as = 'li') => {
|
|
288
|
+
if (!infiniteScrollError)
|
|
289
|
+
return null;
|
|
290
|
+
const Tag = as;
|
|
291
|
+
return (_jsxs(Tag, { className: cx(classes.infiniteScrollError, 'mfui-SelectBox__infiniteScrollError'), role: "alert", children: [_jsxs("div", { className: cx(classes.infiniteScrollErrorMessage, 'mfui-SelectBox__infiniteScrollErrorMessage'), "aria-live": "polite", children: [_jsx(Error, { "aria-hidden": true, className: cx(classes.infiniteScrollErrorIcon, 'mfui-SelectBox__infiniteScrollErrorIcon') }), _jsx(Typography, { variant: "body", children: infiniteScrollErrorMessage })] }), _jsx("div", { className: cx(classes.infiniteScrollErrorButton, 'mfui-SelectBox__infiniteScrollErrorButton'), children: _jsx(Button, { size: "small", onClick: (event) => {
|
|
292
|
+
event.stopPropagation();
|
|
293
|
+
retryInfiniteScroll();
|
|
294
|
+
}, children: infiniteScrollRetryButtonText }) })] }, "infinite-scroll-error"));
|
|
295
|
+
}, [
|
|
291
296
|
infiniteScrollError,
|
|
292
297
|
classes.infiniteScrollError,
|
|
293
298
|
classes.infiniteScrollErrorIcon,
|
|
@@ -299,19 +304,22 @@ export const SelectBox = forwardRef((props, ref) => {
|
|
|
299
304
|
]);
|
|
300
305
|
// Render infinite scroll loading indicator
|
|
301
306
|
const renderInfiniteScrollLoading = useCallback(() => isInfiniteScrollLoading && enableInfiniteScroll ? (_jsx("div", { className: cx(classes.infiniteScrollLoading, 'mfui-SelectBox__infiniteScrollLoading'), children: _jsx(ProgressIndicator, {}) }, "infinite-scroll-loading")) : null, [isInfiniteScrollLoading, enableInfiniteScroll, classes.infiniteScrollLoading]);
|
|
302
|
-
const optionsNode = (
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
307
|
+
const optionsNode = (_jsxs("div", { ref: scrollWrapperRef, className: cx(classes.scrollWrapper, 'mfui-SelectBox__scrollWrapper'), onScroll: enableInfiniteScroll ? handleInfiniteScroll : undefined, children: [_jsx("ul", { role: "listbox", id: listBoxId, className: cx(classes.listBox, 'mfui-SelectBox__listBox'), tabIndex: -1, style: isVirtualized
|
|
308
|
+
? {
|
|
309
|
+
height: `${String(totalSize)}px`,
|
|
310
|
+
position: 'relative',
|
|
311
|
+
}
|
|
312
|
+
: undefined, children: loading
|
|
313
|
+
? Array.from({ length: SKELETON_ITEM_COUNT }).map((_, index) => (_jsx("li", { className: cx(classes.skeletonItem, 'mfui-SelectBox__skeletonItem'), children: _jsx(Skeleton, {}) }, index)))
|
|
314
|
+
: isVirtualized && virtualItems.length > 0
|
|
315
|
+
? renderVirtualizedItems()
|
|
316
|
+
: filteredOptions.length > 0
|
|
317
|
+
? [
|
|
318
|
+
...renderNonVirtualizedItems(),
|
|
319
|
+
!isVirtualized && renderInfiniteScrollLoading(),
|
|
320
|
+
!isVirtualized && renderInfiniteScrollError(),
|
|
321
|
+
].filter(Boolean)
|
|
322
|
+
: [renderEmptyMessage(), !isVirtualized && renderInfiniteScrollError()].filter(Boolean) }), isVirtualized ? renderInfiniteScrollLoading() : null, isVirtualized ? renderInfiniteScrollError('div') : null] }));
|
|
315
323
|
const handleClearValue = () => {
|
|
316
324
|
setLocalSelectedOption(null);
|
|
317
325
|
onChange?.(null);
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { type SidebarProps } from './Sidebar.types';
|
|
2
|
+
import { SidebarServiceMenu } from './SidebarServiceMenu';
|
|
3
|
+
import { SidebarTenantMenu } from './SidebarTenantMenu';
|
|
4
|
+
import { SidebarUserMenu } from './SidebarUserMenu';
|
|
5
|
+
import { SidebarNavigationItem } from './SidebarNavigationItem';
|
|
6
|
+
declare function SidebarBase({ className, logoSlot, mainNavigationItems, extraNavigationSlot, footerSlot, serviceMenuSlot, footerIconMenuSlot, tenantSlot, userSlot, minWidth, maxWidth, defaultWidth, onWidthChange, mainNavigationLabel, extraNavigationLabel, resizeHandleLabel, }: SidebarProps): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
/**
|
|
8
|
+
* The sidebar component.
|
|
9
|
+
* A navigation layout component that combines a logo header, a navigation area,
|
|
10
|
+
* and a footer with icon menu and user information.
|
|
11
|
+
*
|
|
12
|
+
* **EXPERIMENTAL**: This component is experimental and may be changed or removed in the future.
|
|
13
|
+
*
|
|
14
|
+
* The width is resizable via the drag handle on the right edge. See the `WidthPersistence` story for
|
|
15
|
+
* an example of persisting the width across reloads via `onWidthChange` and `defaultWidth`.
|
|
16
|
+
*
|
|
17
|
+
* The following composition components are provided as sub-components:
|
|
18
|
+
* - `Sidebar.NavigationItem` — a single navigation item; `mainNavigationItems` renders these for you,
|
|
19
|
+
* but it can also be used directly inside `extraNavigationSlot`.
|
|
20
|
+
* - `Sidebar.ServiceMenu` — the footer service menu trigger, intended to wrap a list of services.
|
|
21
|
+
* - `Sidebar.TenantMenu` — the footer tenant (business) name and its menu.
|
|
22
|
+
* - `Sidebar.UserMenu` — the footer user (account) name and its menu.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```tsx
|
|
26
|
+
* <Sidebar
|
|
27
|
+
* logoSlot={<YourLogo />}
|
|
28
|
+
* defaultWidth={savedWidth}
|
|
29
|
+
* onWidthChange={(width) => persistWidth(width)}
|
|
30
|
+
* mainNavigationItems={[
|
|
31
|
+
* { label: 'Home', icon: <HomeIcon />, href: '/', isCurrent: true },
|
|
32
|
+
* { label: 'Search', icon: <SearchIcon />, onClick: handleSearch },
|
|
33
|
+
* ]}
|
|
34
|
+
* serviceMenuSlot={
|
|
35
|
+
* <Sidebar.ServiceMenu label="サービス" icon={<ApplicationsIcon />}>
|
|
36
|
+
* <DropdownMenu.Item href="https://example.com">マイページ</DropdownMenu.Item>
|
|
37
|
+
* </Sidebar.ServiceMenu>
|
|
38
|
+
* }
|
|
39
|
+
* footerIconMenuSlot={<YourIconButtons />}
|
|
40
|
+
* tenantSlot={
|
|
41
|
+
* <Sidebar.TenantMenu name="株式会社サンプル" tooltipLabel="事業者">
|
|
42
|
+
* <DropdownMenu.Item href="https://example.com">事業者設定</DropdownMenu.Item>
|
|
43
|
+
* </Sidebar.TenantMenu>
|
|
44
|
+
* }
|
|
45
|
+
* userSlot={
|
|
46
|
+
* <Sidebar.UserMenu name="山田 太郎" tooltipLabel="アカウント">
|
|
47
|
+
* <DropdownMenu.Item onClick={handleLogout}>ログアウト</DropdownMenu.Item>
|
|
48
|
+
* </Sidebar.UserMenu>
|
|
49
|
+
* }
|
|
50
|
+
* />
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
export declare const Sidebar: typeof SidebarBase & {
|
|
54
|
+
/** @see {@link SidebarNavigationItem} */
|
|
55
|
+
NavigationItem: typeof SidebarNavigationItem;
|
|
56
|
+
/** @see {@link SidebarServiceMenu} */
|
|
57
|
+
ServiceMenu: typeof SidebarServiceMenu;
|
|
58
|
+
/** @see {@link SidebarTenantMenu} */
|
|
59
|
+
TenantMenu: typeof SidebarTenantMenu;
|
|
60
|
+
/** @see {@link SidebarUserMenu} */
|
|
61
|
+
UserMenu: typeof SidebarUserMenu;
|
|
62
|
+
};
|
|
63
|
+
export {};
|