@moneyforward/mfui-components 3.11.0 → 3.12.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/Breadcrumbs/Breadcrumbs.d.ts +9 -0
- package/dist/src/Breadcrumbs/Breadcrumbs.js +150 -0
- package/dist/src/Breadcrumbs/Breadcrumbs.types.d.ts +31 -0
- package/dist/src/Breadcrumbs/Breadcrumbs.types.js +1 -0
- package/dist/src/Breadcrumbs/index.d.ts +2 -0
- package/dist/src/Breadcrumbs/index.js +1 -0
- package/dist/src/Button/Button.d.ts +1 -1
- package/dist/src/CheckboxGroup/CheckboxGroup.d.ts +1 -1
- package/dist/src/DateTimeSelection/DateRangePicker/DateRangePickerProvider/DateRangePickerProvider.d.ts +2 -2
- package/dist/src/DateTimeSelection/shared/BaseRangePicker/BaseRangePickerProvider/BaseRangePickerProvider.d.ts +2 -2
- package/dist/src/IconButton/IconButton.d.ts +2 -2
- package/dist/src/MultipleSelectBox/MultipleSelectBox.d.ts +1 -1
- package/dist/src/MultipleSelectBox/MultipleSelectBox.js +5 -2
- package/dist/src/MultipleSelectBox/MultipleSelectBox.types.d.ts +9 -0
- package/dist/src/Popover/Popover.js +29 -0
- package/dist/src/RadioButton/RadioButton.d.ts +1 -1
- package/dist/src/RadioGroup/RadioGroup.d.ts +1 -1
- package/dist/src/SplitView/SplitView.d.ts +7 -16
- package/dist/src/SplitView/SplitView.js +110 -70
- package/dist/src/SplitView/SplitView.types.d.ts +84 -56
- package/dist/src/SplitView/hooks/useSplitViewAnimation.d.ts +6 -6
- package/dist/src/SplitView/hooks/useSplitViewAnimation.js +46 -48
- package/dist/src/SplitView/hooks/useSplitViewDrag.d.ts +5 -4
- package/dist/src/SplitView/hooks/useSplitViewDrag.js +22 -12
- package/dist/src/SplitView/hooks/useSplitViewKeyboard.d.ts +7 -6
- package/dist/src/SplitView/hooks/useSplitViewKeyboard.js +22 -16
- package/dist/src/SplitView/hooks/useSplitViewPanelVisibility.d.ts +3 -3
- package/dist/src/SplitView/hooks/useSplitViewPanelVisibility.js +9 -9
- package/dist/src/SplitView/hooks/useSplitViewResize.d.ts +6 -6
- package/dist/src/SplitView/hooks/useSplitViewResize.js +16 -16
- package/dist/src/SplitView/utils/calculatePanelSize.d.ts +11 -11
- package/dist/src/SplitView/utils/calculatePanelSize.js +13 -13
- package/dist/src/SplitView/utils/styles.d.ts +21 -5
- package/dist/src/SplitView/utils/styles.js +47 -21
- package/dist/src/Tooltip/Tooltip.d.ts +2 -1
- package/dist/src/Tooltip/Tooltip.js +4 -2
- package/dist/src/Tooltip/Tooltip.types.d.ts +11 -0
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.js +1 -0
- package/dist/styled-system/recipes/breadcrumbs-slot-recipe.d.ts +33 -0
- package/dist/styled-system/recipes/breadcrumbs-slot-recipe.js +63 -0
- package/dist/styled-system/recipes/index.d.ts +1 -0
- package/dist/styled-system/recipes/index.js +1 -0
- package/dist/styles.css +88 -7
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +3 -3
|
@@ -8,13 +8,13 @@ import { useSplitViewDrag } from './hooks/useSplitViewDrag';
|
|
|
8
8
|
import { useSplitViewKeyboard } from './hooks/useSplitViewKeyboard';
|
|
9
9
|
import { useSplitViewPanelVisibility } from './hooks/useSplitViewPanelVisibility';
|
|
10
10
|
import { useSplitViewResize } from './hooks/useSplitViewResize';
|
|
11
|
-
import {
|
|
11
|
+
import { calculateControlledPanelStyle, calculateDividerStyle } from './utils/styles';
|
|
12
12
|
import { parseSizeToNumber } from './utils/parseSize';
|
|
13
13
|
/**
|
|
14
14
|
* A resizable split layout component with two panels.
|
|
15
15
|
*
|
|
16
16
|
* Users can adjust panel sizes by dragging the divider between panels.
|
|
17
|
-
* The
|
|
17
|
+
* The controlled panel (determined by `targetPanel`) can be shown or hidden using the `isOpen` prop.
|
|
18
18
|
*
|
|
19
19
|
* @example
|
|
20
20
|
* ```tsx
|
|
@@ -24,99 +24,130 @@ import { parseSizeToNumber } from './utils/parseSize';
|
|
|
24
24
|
* leftPanelSlot={<div>Left Panel</div>}
|
|
25
25
|
* rightPanelSlot={<div>Right Panel</div>}
|
|
26
26
|
* isOpen={isOpen}
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
27
|
+
* targetPanel="right"
|
|
28
|
+
* initialPanelSize={300}
|
|
29
|
+
* minPanelSize={200}
|
|
30
|
+
* maxPanelSize={500}
|
|
30
31
|
* style={{ minWidth: '600px' }}
|
|
31
32
|
* />
|
|
32
33
|
* ```
|
|
33
34
|
*/
|
|
34
|
-
export const SplitView = forwardRef(({ className, leftPanelSlot, rightPanelSlot, isOpen, initialRightPanelSize, minRightPanelSize, maxRightPanelSize, leftPanelProps, rightPanelProps, dividerProps, enableAutoUnmount = true, ...props }, ref) => {
|
|
35
|
+
export const SplitView = forwardRef(({ className, leftPanelSlot, rightPanelSlot, isOpen, initialPanelSize, minPanelSize, maxPanelSize, targetPanel, initialRightPanelSize, minRightPanelSize, maxRightPanelSize, leftPanelProps, rightPanelProps, dividerProps, enableAutoUnmount = true, ...props }, ref) => {
|
|
36
|
+
// Normalize legacy props to the new API
|
|
37
|
+
const resolvedTargetPanel = targetPanel ?? 'right';
|
|
38
|
+
const resolvedInitialPanelSize = initialPanelSize ?? initialRightPanelSize;
|
|
39
|
+
const resolvedMinPanelSize = minPanelSize ?? minRightPanelSize;
|
|
40
|
+
const resolvedMaxPanelSize = maxPanelSize ?? maxRightPanelSize;
|
|
35
41
|
// Convert CSS width values to numbers for internal calculations
|
|
36
|
-
const
|
|
37
|
-
const
|
|
38
|
-
const
|
|
39
|
-
//
|
|
42
|
+
const initialPanelSizeNumber = parseSizeToNumber(resolvedInitialPanelSize, 'initialPanelSize');
|
|
43
|
+
const minPanelSizeNumber = parseSizeToNumber(resolvedMinPanelSize, 'minPanelSize');
|
|
44
|
+
const maxPanelSizeNumber = parseSizeToNumber(resolvedMaxPanelSize, 'maxPanelSize');
|
|
45
|
+
// Warn when legacy and new API props are mixed.
|
|
46
|
+
// These checks are intentionally guarded at runtime for JavaScript callers who bypass TypeScript's
|
|
47
|
+
// discriminated union constraints (e.g., via `as any` or plain JS usage).
|
|
40
48
|
useEffect(() => {
|
|
41
|
-
|
|
42
|
-
|
|
49
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
50
|
+
if (initialPanelSize !== undefined && initialRightPanelSize !== undefined) {
|
|
51
|
+
console.warn('SplitView: initialPanelSize and initialRightPanelSize cannot be used together. ' +
|
|
52
|
+
'initialPanelSize takes precedence. Remove initialRightPanelSize.');
|
|
43
53
|
}
|
|
44
|
-
|
|
45
|
-
|
|
54
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
55
|
+
if (minPanelSize !== undefined && minRightPanelSize !== undefined) {
|
|
56
|
+
console.warn('SplitView: minPanelSize and minRightPanelSize cannot be used together. ' +
|
|
57
|
+
'minPanelSize takes precedence. Remove minRightPanelSize.');
|
|
46
58
|
}
|
|
47
|
-
|
|
48
|
-
|
|
59
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
60
|
+
if (maxPanelSize !== undefined && maxRightPanelSize !== undefined) {
|
|
61
|
+
console.warn('SplitView: maxPanelSize and maxRightPanelSize cannot be used together. ' +
|
|
62
|
+
'maxPanelSize takes precedence. Remove maxRightPanelSize.');
|
|
49
63
|
}
|
|
50
|
-
|
|
51
|
-
|
|
64
|
+
}, [initialPanelSize, initialRightPanelSize, minPanelSize, minRightPanelSize, maxPanelSize, maxRightPanelSize]);
|
|
65
|
+
// Validate resolved prop values
|
|
66
|
+
useEffect(() => {
|
|
67
|
+
if (minPanelSizeNumber < 0) {
|
|
68
|
+
console.error(`SplitView: minPanelSize must be non-negative, but got ${String(resolvedMinPanelSize)}.`);
|
|
69
|
+
}
|
|
70
|
+
if (maxPanelSizeNumber < 0) {
|
|
71
|
+
console.error(`SplitView: maxPanelSize must be non-negative, but got ${String(resolvedMaxPanelSize)}.`);
|
|
72
|
+
}
|
|
73
|
+
if (initialPanelSizeNumber < 0) {
|
|
74
|
+
console.error(`SplitView: initialPanelSize must be non-negative, but got ${String(resolvedInitialPanelSize)}.`);
|
|
75
|
+
}
|
|
76
|
+
if (minPanelSizeNumber > maxPanelSizeNumber) {
|
|
77
|
+
console.error(`SplitView: minPanelSize (${String(resolvedMinPanelSize)}) must be less than or equal to maxPanelSize (${String(resolvedMaxPanelSize)}).`);
|
|
52
78
|
}
|
|
53
|
-
if (
|
|
54
|
-
console.error(`SplitView:
|
|
79
|
+
if (initialPanelSizeNumber < minPanelSizeNumber) {
|
|
80
|
+
console.error(`SplitView: initialPanelSize (${String(resolvedInitialPanelSize)}) must be greater than or equal to minPanelSize (${String(resolvedMinPanelSize)}).`);
|
|
55
81
|
}
|
|
56
|
-
if (
|
|
57
|
-
console.error(`SplitView:
|
|
82
|
+
if (initialPanelSizeNumber > maxPanelSizeNumber) {
|
|
83
|
+
console.error(`SplitView: initialPanelSize (${String(resolvedInitialPanelSize)}) must be less than or equal to maxPanelSize (${String(resolvedMaxPanelSize)}).`);
|
|
58
84
|
}
|
|
59
85
|
}, [
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
86
|
+
resolvedInitialPanelSize,
|
|
87
|
+
resolvedMinPanelSize,
|
|
88
|
+
resolvedMaxPanelSize,
|
|
89
|
+
initialPanelSizeNumber,
|
|
90
|
+
minPanelSizeNumber,
|
|
91
|
+
maxPanelSizeNumber,
|
|
66
92
|
]);
|
|
67
93
|
const classes = splitViewSlotRecipe();
|
|
68
94
|
const containerRef = useRef(null);
|
|
69
|
-
|
|
95
|
+
// Size of the controlled panel (the panel specified by targetPanel)
|
|
96
|
+
const [controlledPanelSize, setControlledPanelSize] = useState();
|
|
70
97
|
const [isAnimating, setIsAnimating] = useState(false);
|
|
71
|
-
const [
|
|
98
|
+
const [animatedPanelSize, setAnimatedPanelSize] = useState();
|
|
72
99
|
const [isSlideOutAnimating, setIsSlideOutAnimating] = useState(false);
|
|
73
|
-
// Store last known
|
|
74
|
-
const
|
|
75
|
-
// Memoized callback to update last
|
|
76
|
-
const
|
|
77
|
-
|
|
100
|
+
// Store last known controlled panel size for slide-out animation
|
|
101
|
+
const lastControlledPanelSizeRef = useRef(undefined);
|
|
102
|
+
// Memoized callback to update last controlled panel size
|
|
103
|
+
const setLastControlledPanelSize = useCallback((size) => {
|
|
104
|
+
lastControlledPanelSizeRef.current = size;
|
|
78
105
|
}, []);
|
|
106
|
+
// The slot of the controlled panel (varies by targetPanel)
|
|
107
|
+
const controlledPanelSlot = resolvedTargetPanel === 'left' ? leftPanelSlot : rightPanelSlot;
|
|
79
108
|
// Panel visibility management
|
|
80
|
-
const { isRightPanelVisible, isInitialMountRef, wasRightPanelVisibleOnMountRef, hasRightPanelBeenVisible, setHasRightPanelBeenVisible, previousIsRightPanelVisibleRef, lastRightPanelRef, } = useSplitViewPanelVisibility(isOpen,
|
|
81
|
-
// Determine if
|
|
82
|
-
const
|
|
109
|
+
const { isRightPanelVisible, isInitialMountRef, wasRightPanelVisibleOnMountRef, hasRightPanelBeenVisible, setHasRightPanelBeenVisible, previousIsRightPanelVisibleRef, lastRightPanelRef, } = useSplitViewPanelVisibility(isOpen, controlledPanelSlot);
|
|
110
|
+
// Determine if the controlled panel should be rendered based on enableAutoUnmount
|
|
111
|
+
const shouldRenderControlledPanel = enableAutoUnmount ? isRightPanelVisible : true;
|
|
83
112
|
// Animation management
|
|
84
113
|
useSplitViewAnimation({
|
|
85
114
|
isRightPanelVisible,
|
|
86
115
|
containerRef,
|
|
87
|
-
|
|
88
|
-
|
|
116
|
+
initialPanelSize: initialPanelSizeNumber,
|
|
117
|
+
minPanelSize: minPanelSizeNumber,
|
|
89
118
|
isInitialMountRef,
|
|
90
119
|
wasRightPanelVisibleOnMountRef,
|
|
91
120
|
previousIsRightPanelVisibleRef,
|
|
92
121
|
hasRightPanelBeenVisible,
|
|
93
122
|
isAnimating,
|
|
94
|
-
|
|
95
|
-
|
|
123
|
+
controlledPanelSize,
|
|
124
|
+
lastControlledPanelSizeRef,
|
|
96
125
|
lastRightPanelRef,
|
|
97
|
-
|
|
126
|
+
setControlledPanelSize,
|
|
98
127
|
setIsAnimating,
|
|
99
|
-
|
|
128
|
+
setAnimatedPanelSize,
|
|
100
129
|
setHasRightPanelBeenVisible,
|
|
101
130
|
setIsSlideOutAnimating,
|
|
102
131
|
});
|
|
103
132
|
// Drag management
|
|
104
133
|
const { isDragging, handleMouseDown } = useSplitViewDrag({
|
|
105
134
|
containerRef,
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
135
|
+
targetPanel: resolvedTargetPanel,
|
|
136
|
+
minPanelSize: minPanelSizeNumber,
|
|
137
|
+
maxPanelSize: maxPanelSizeNumber,
|
|
138
|
+
setControlledPanelSize,
|
|
139
|
+
setLastControlledPanelSize,
|
|
110
140
|
});
|
|
111
141
|
// Keyboard navigation
|
|
112
142
|
const { handleKeyDown } = useSplitViewKeyboard({
|
|
113
143
|
containerRef,
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
144
|
+
targetPanel: resolvedTargetPanel,
|
|
145
|
+
controlledPanelSize,
|
|
146
|
+
initialPanelSize: initialPanelSizeNumber,
|
|
147
|
+
minPanelSize: minPanelSizeNumber,
|
|
148
|
+
maxPanelSize: maxPanelSizeNumber,
|
|
149
|
+
setControlledPanelSize,
|
|
150
|
+
setLastControlledPanelSize,
|
|
120
151
|
});
|
|
121
152
|
// Resize management
|
|
122
153
|
useSplitViewResize({
|
|
@@ -124,32 +155,37 @@ export const SplitView = forwardRef(({ className, leftPanelSlot, rightPanelSlot,
|
|
|
124
155
|
containerRef,
|
|
125
156
|
isAnimating,
|
|
126
157
|
isDragging,
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
158
|
+
controlledPanelSize,
|
|
159
|
+
minPanelSize: minPanelSizeNumber,
|
|
160
|
+
maxPanelSize: maxPanelSizeNumber,
|
|
161
|
+
setControlledPanelSize,
|
|
162
|
+
setLastControlledPanelSize,
|
|
132
163
|
});
|
|
133
|
-
// Calculate current
|
|
134
|
-
let
|
|
164
|
+
// Calculate current controlled panel size based on animation and visibility state
|
|
165
|
+
let currentControlledPanelSize;
|
|
135
166
|
if (isAnimating) {
|
|
136
|
-
|
|
167
|
+
currentControlledPanelSize = animatedPanelSize;
|
|
137
168
|
}
|
|
138
169
|
else if (isRightPanelVisible) {
|
|
139
|
-
|
|
140
|
-
currentRightPanelSize = rightPanelSize ?? initialRightPanelSizeNumber;
|
|
170
|
+
currentControlledPanelSize = controlledPanelSize ?? initialPanelSizeNumber;
|
|
141
171
|
}
|
|
142
172
|
else {
|
|
143
|
-
|
|
173
|
+
currentControlledPanelSize = undefined;
|
|
144
174
|
}
|
|
145
|
-
|
|
146
|
-
|
|
175
|
+
// The full open size of the controlled panel: used to fix the inner wrapper width during animation
|
|
176
|
+
// so that the panel content never reflows as the outer div width shrinks.
|
|
177
|
+
const fullControlledPanelSize = lastControlledPanelSizeRef.current ?? controlledPanelSize ?? initialPanelSizeNumber;
|
|
178
|
+
// Calculate styles for the controlled panel (applied to left or right panel based on targetPanel)
|
|
179
|
+
const { outer: controlledPanelOuterStyle, inner: controlledPanelInnerStyle } = calculateControlledPanelStyle({
|
|
180
|
+
currentSize: currentControlledPanelSize,
|
|
181
|
+
fullPanelSize: fullControlledPanelSize,
|
|
182
|
+
targetPanel: resolvedTargetPanel,
|
|
147
183
|
enableAutoUnmount,
|
|
148
184
|
isRightPanelVisible,
|
|
149
185
|
isSlideOutAnimating,
|
|
150
186
|
hasRightPanelBeenVisible,
|
|
151
187
|
isAnimating,
|
|
152
|
-
|
|
188
|
+
panelPropsStyle: resolvedTargetPanel === 'left' ? leftPanelProps?.style : rightPanelProps?.style,
|
|
153
189
|
});
|
|
154
190
|
const dividerStyle = calculateDividerStyle({
|
|
155
191
|
hasRightPanelBeenVisible,
|
|
@@ -157,6 +193,10 @@ export const SplitView = forwardRef(({ className, leftPanelSlot, rightPanelSlot,
|
|
|
157
193
|
isDragging,
|
|
158
194
|
dividerPropsStyle: dividerProps?.style,
|
|
159
195
|
});
|
|
196
|
+
// Apply controlled panel style to the correct panel based on targetPanel.
|
|
197
|
+
// When a panel is the main panel (not controlled), flex: 1 ensures it fills remaining space.
|
|
198
|
+
const computedLeftPanelStyle = resolvedTargetPanel === 'left' ? controlledPanelOuterStyle : leftPanelProps?.style;
|
|
199
|
+
const computedRightPanelStyle = resolvedTargetPanel === 'right' ? controlledPanelOuterStyle : { flex: 1, ...rightPanelProps?.style };
|
|
160
200
|
return (_jsxs("div", { ref: (node) => {
|
|
161
201
|
// Handle both refs
|
|
162
202
|
if (typeof ref === 'function') {
|
|
@@ -167,7 +207,7 @@ export const SplitView = forwardRef(({ className, leftPanelSlot, rightPanelSlot,
|
|
|
167
207
|
ref.current = node;
|
|
168
208
|
}
|
|
169
209
|
containerRef.current = node;
|
|
170
|
-
}, className: cx(classes.root, 'mfui-SplitView__root', className), ...props, children: [_jsx("div", { ...leftPanelProps, className: cx(classes.leftPanel, 'mfui-SplitView__leftPanel', leftPanelProps?.className), children: leftPanelSlot }), isRightPanelVisible || isSlideOutAnimating ? (_jsx("div", { ...dividerProps, className: cx(classes.divider, 'mfui-SplitView__divider', dividerProps?.className), role: "separator", "aria-orientation": "vertical", "aria-label": dividerProps?.['aria-label'] ?? '左右のパネルを調整',
|
|
210
|
+
}, className: cx(classes.root, 'mfui-SplitView__root', className), ...props, children: [resolvedTargetPanel === 'left' ? (shouldRenderControlledPanel || isSlideOutAnimating ? (_jsx("div", { ...leftPanelProps, className: cx(classes.leftPanel, 'mfui-SplitView__leftPanel', leftPanelProps?.className), style: computedLeftPanelStyle, children: _jsx("div", { style: controlledPanelInnerStyle, children: enableAutoUnmount ? (leftPanelSlot ?? lastRightPanelRef.current) : leftPanelSlot }) })) : null) : (_jsx("div", { ...leftPanelProps, className: cx(classes.leftPanel, 'mfui-SplitView__leftPanel', leftPanelProps?.className), style: computedLeftPanelStyle, children: leftPanelSlot })), isRightPanelVisible || isSlideOutAnimating ? (_jsx("div", { ...dividerProps, className: cx(classes.divider, 'mfui-SplitView__divider', dividerProps?.className), role: "separator", "aria-orientation": "vertical", "aria-label": dividerProps?.['aria-label'] ?? '左右のパネルを調整',
|
|
171
211
|
// eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex
|
|
172
|
-
tabIndex: 0, style: dividerStyle, onPointerDown: handleMouseDown, onKeyDown: handleKeyDown })) : null,
|
|
212
|
+
tabIndex: 0, style: dividerStyle, onPointerDown: handleMouseDown, onKeyDown: handleKeyDown })) : null, resolvedTargetPanel === 'right' ? (shouldRenderControlledPanel || isSlideOutAnimating ? (_jsx("div", { ...rightPanelProps, className: cx(classes.rightPanel, 'mfui-SplitView__rightPanel', rightPanelProps?.className), style: computedRightPanelStyle, children: _jsx("div", { style: controlledPanelInnerStyle, children: enableAutoUnmount ? (rightPanelSlot ?? lastRightPanelRef.current) : rightPanelSlot }) })) : null) : (_jsx("div", { ...rightPanelProps, className: cx(classes.rightPanel, 'mfui-SplitView__rightPanel', rightPanelProps?.className), style: computedRightPanelStyle, children: rightPanelSlot }))] }));
|
|
173
213
|
});
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { type ComponentPropsWithoutRef, type CSSProperties, type ReactNode } from 'react';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* Base props shared by both the legacy and new panel size APIs.
|
|
4
4
|
*/
|
|
5
|
-
|
|
5
|
+
type SplitViewBaseProps = {
|
|
6
6
|
/**
|
|
7
|
-
* The content to display in the left panel
|
|
7
|
+
* The content to display in the left panel.
|
|
8
8
|
*/
|
|
9
9
|
leftPanelSlot: ReactNode;
|
|
10
10
|
/**
|
|
@@ -12,89 +12,117 @@ export type SplitViewProps = {
|
|
|
12
12
|
*/
|
|
13
13
|
rightPanelSlot: ReactNode;
|
|
14
14
|
/**
|
|
15
|
-
* Controls
|
|
15
|
+
* Controls which panel is visible.
|
|
16
16
|
*
|
|
17
|
-
* When `true`, the
|
|
18
|
-
* When `false`, the
|
|
19
|
-
* When `undefined`, the
|
|
17
|
+
* When `true`, the controlled panel (determined by `targetPanel`) is shown with a slide-in animation.
|
|
18
|
+
* When `false`, the controlled panel is hidden with a slide-out animation.
|
|
19
|
+
* When `undefined`, the controlled panel is visible by default.
|
|
20
20
|
*
|
|
21
21
|
* The behavior when hidden depends on the `enableAutoUnmount` prop:
|
|
22
|
-
* - `enableAutoUnmount=true` (default): The
|
|
23
|
-
* - `enableAutoUnmount=false`: The
|
|
22
|
+
* - `enableAutoUnmount=true` (default): The controlled panel content will be unmounted when hidden
|
|
23
|
+
* - `enableAutoUnmount=false`: The controlled panel content stays mounted but is hidden via CSS
|
|
24
24
|
*
|
|
25
|
-
* @default undefined (
|
|
25
|
+
* @default undefined (controlled panel is visible by default)
|
|
26
26
|
*
|
|
27
27
|
* @example
|
|
28
28
|
* ```tsx
|
|
29
|
-
* //
|
|
29
|
+
* // New API: control left panel size
|
|
30
30
|
* <SplitView
|
|
31
31
|
* leftPanelSlot={<LeftPanel />}
|
|
32
32
|
* rightPanelSlot={<RightPanel />}
|
|
33
33
|
* isOpen={isOpen}
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
* />
|
|
39
|
-
*
|
|
40
|
-
* // Advanced: State preservation (enableAutoUnmount=false)
|
|
41
|
-
* <SplitView
|
|
42
|
-
* leftPanelSlot={<LeftPanel />}
|
|
43
|
-
* rightPanelSlot={<ExpensiveFormWithState />}
|
|
44
|
-
* isOpen={isOpen}
|
|
45
|
-
* initialRightPanelSize={300}
|
|
46
|
-
* minRightPanelSize={200}
|
|
47
|
-
* maxRightPanelSize={500}
|
|
48
|
-
* enableAutoUnmount={false}
|
|
34
|
+
* targetPanel="left"
|
|
35
|
+
* initialPanelSize={300}
|
|
36
|
+
* minPanelSize={200}
|
|
37
|
+
* maxPanelSize={500}
|
|
49
38
|
* style={{ minWidth: '600px' }}
|
|
50
39
|
* />
|
|
51
40
|
* ```
|
|
52
41
|
*/
|
|
53
42
|
isOpen?: boolean;
|
|
54
43
|
/**
|
|
55
|
-
*
|
|
44
|
+
* Props for the left panel container.
|
|
45
|
+
*/
|
|
46
|
+
leftPanelProps?: ComponentPropsWithoutRef<'div'>;
|
|
47
|
+
/**
|
|
48
|
+
* Props for the right panel container.
|
|
49
|
+
*/
|
|
50
|
+
rightPanelProps?: ComponentPropsWithoutRef<'div'>;
|
|
51
|
+
/**
|
|
52
|
+
* Props for the divider element.
|
|
53
|
+
*/
|
|
54
|
+
dividerProps?: ComponentPropsWithoutRef<'div'>;
|
|
55
|
+
/**
|
|
56
|
+
* Enable auto unmounting of the controlled panel content when it is not displayed.
|
|
57
|
+
* When true, the controlled panel content will return null instead of hiding via CSS.
|
|
56
58
|
*
|
|
57
|
-
*
|
|
58
|
-
|
|
59
|
+
* @default true
|
|
60
|
+
*/
|
|
61
|
+
enableAutoUnmount?: boolean;
|
|
62
|
+
} & ComponentPropsWithoutRef<'div'>;
|
|
63
|
+
/**
|
|
64
|
+
* Legacy panel size props (right-panel-specific).
|
|
65
|
+
*
|
|
66
|
+
* This type will be deprecated in v4.0.0.
|
|
67
|
+
* Use `TargetPanelSizeProps` (`initialPanelSize`, `minPanelSize`, `maxPanelSize`, `targetPanel`) instead.
|
|
68
|
+
*/
|
|
69
|
+
type LegacyPanelSizeProps = {
|
|
70
|
+
/**
|
|
71
|
+
* The initial size of the right panel.
|
|
59
72
|
*
|
|
60
|
-
*
|
|
61
|
-
* ```tsx
|
|
62
|
-
* <SplitView
|
|
63
|
-
* leftPanelSlot={<LeftPanel />}
|
|
64
|
-
* rightPanelSlot={<RightPanel />}
|
|
65
|
-
* initialRightPanelSize={300}
|
|
66
|
-
* minRightPanelSize={200}
|
|
67
|
-
* maxRightPanelSize={500}
|
|
68
|
-
* style={{ minWidth: '600px' }}
|
|
69
|
-
* />
|
|
70
|
-
* ```
|
|
73
|
+
* This prop will be deprecated in v4.0.0. Use `initialPanelSize` with `targetPanel="right"` instead.
|
|
71
74
|
*/
|
|
72
|
-
initialRightPanelSize: CSSProperties['width']
|
|
75
|
+
initialRightPanelSize: NonNullable<CSSProperties['width']>;
|
|
73
76
|
/**
|
|
74
|
-
* The minimum size of the
|
|
77
|
+
* The minimum size of the right panel.
|
|
78
|
+
*
|
|
79
|
+
* This prop will be deprecated in v4.0.0. Use `minPanelSize` with `targetPanel="right"` instead.
|
|
75
80
|
*/
|
|
76
|
-
minRightPanelSize: CSSProperties['minWidth']
|
|
81
|
+
minRightPanelSize: NonNullable<CSSProperties['minWidth']>;
|
|
77
82
|
/**
|
|
78
|
-
* The maximum size of the
|
|
83
|
+
* The maximum size of the right panel.
|
|
84
|
+
*
|
|
85
|
+
* This prop will be deprecated in v4.0.0. Use `maxPanelSize` with `targetPanel="right"` instead.
|
|
79
86
|
*/
|
|
80
|
-
maxRightPanelSize: CSSProperties['maxWidth']
|
|
87
|
+
maxRightPanelSize: NonNullable<CSSProperties['maxWidth']>;
|
|
88
|
+
initialPanelSize?: never;
|
|
89
|
+
minPanelSize?: never;
|
|
90
|
+
maxPanelSize?: never;
|
|
91
|
+
targetPanel?: never;
|
|
92
|
+
};
|
|
93
|
+
/**
|
|
94
|
+
* Panel size props for the new API. Supports controlling either the left or right panel.
|
|
95
|
+
*/
|
|
96
|
+
type TargetPanelSizeProps = {
|
|
81
97
|
/**
|
|
82
|
-
*
|
|
98
|
+
* The initial size of the panel specified by `targetPanel`.
|
|
83
99
|
*/
|
|
84
|
-
|
|
100
|
+
initialPanelSize: NonNullable<CSSProperties['width']>;
|
|
85
101
|
/**
|
|
86
|
-
*
|
|
102
|
+
* The minimum size of the panel specified by `targetPanel`.
|
|
87
103
|
*/
|
|
88
|
-
|
|
104
|
+
minPanelSize: NonNullable<CSSProperties['minWidth']>;
|
|
89
105
|
/**
|
|
90
|
-
*
|
|
106
|
+
* The maximum size of the panel specified by `targetPanel`.
|
|
91
107
|
*/
|
|
92
|
-
|
|
108
|
+
maxPanelSize: NonNullable<CSSProperties['maxWidth']>;
|
|
93
109
|
/**
|
|
94
|
-
*
|
|
95
|
-
*
|
|
110
|
+
* Specifies which panel's size is controlled by `initialPanelSize`, `minPanelSize`, and `maxPanelSize`.
|
|
111
|
+
* Also determines which panel is shown or hidden by the `isOpen` prop.
|
|
96
112
|
*
|
|
97
|
-
*
|
|
113
|
+
* - `"right"`: The right panel has a fixed size; the left panel expands to fill remaining space.
|
|
114
|
+
* - `"left"`: The left panel has a fixed size; the right panel expands to fill remaining space.
|
|
98
115
|
*/
|
|
99
|
-
|
|
100
|
-
|
|
116
|
+
targetPanel: 'left' | 'right';
|
|
117
|
+
/** Disallowed when using the new API. Use `initialPanelSize` instead. */
|
|
118
|
+
initialRightPanelSize?: never;
|
|
119
|
+
/** Disallowed when using the new API. Use `minPanelSize` instead. */
|
|
120
|
+
minRightPanelSize?: never;
|
|
121
|
+
/** Disallowed when using the new API. Use `maxPanelSize` instead. */
|
|
122
|
+
maxRightPanelSize?: never;
|
|
123
|
+
};
|
|
124
|
+
/**
|
|
125
|
+
* Props for the SplitView component.
|
|
126
|
+
*/
|
|
127
|
+
export type SplitViewProps = SplitViewBaseProps & (LegacyPanelSizeProps | TargetPanelSizeProps);
|
|
128
|
+
export {};
|
|
@@ -7,8 +7,8 @@ import { type ReactNode } from 'react';
|
|
|
7
7
|
export declare function useSplitViewAnimation(options: {
|
|
8
8
|
isRightPanelVisible: boolean;
|
|
9
9
|
containerRef: React.RefObject<HTMLDivElement | null>;
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
initialPanelSize: number;
|
|
11
|
+
minPanelSize: number;
|
|
12
12
|
isInitialMountRef: {
|
|
13
13
|
current: boolean;
|
|
14
14
|
};
|
|
@@ -20,16 +20,16 @@ export declare function useSplitViewAnimation(options: {
|
|
|
20
20
|
};
|
|
21
21
|
hasRightPanelBeenVisible: boolean;
|
|
22
22
|
isAnimating: boolean;
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
controlledPanelSize: number | undefined;
|
|
24
|
+
lastControlledPanelSizeRef: {
|
|
25
25
|
current: number | undefined;
|
|
26
26
|
};
|
|
27
27
|
lastRightPanelRef: {
|
|
28
28
|
current: ReactNode;
|
|
29
29
|
};
|
|
30
|
-
|
|
30
|
+
setControlledPanelSize: (size: number | undefined) => void;
|
|
31
31
|
setIsAnimating: (animating: boolean) => void;
|
|
32
|
-
|
|
32
|
+
setAnimatedPanelSize: (size: number | undefined) => void;
|
|
33
33
|
setHasRightPanelBeenVisible: (visible: boolean) => void;
|
|
34
34
|
setIsSlideOutAnimating: (animating: boolean) => void;
|
|
35
35
|
}): void;
|