@octanejs/resizable-panels 0.0.19 → 0.0.21
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@octanejs/resizable-panels",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.21",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -29,17 +29,17 @@
|
|
|
29
29
|
".": "./src/index.tsrx"
|
|
30
30
|
},
|
|
31
31
|
"peerDependencies": {
|
|
32
|
-
"octane": "^0.
|
|
32
|
+
"octane": "^0.11.0"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
|
-
"@octanejs/testing-library": "0.1.
|
|
35
|
+
"@octanejs/testing-library": "0.1.61",
|
|
36
36
|
"@testing-library/jest-dom": "^6.9.1",
|
|
37
37
|
"@testing-library/react": "^16.3.2",
|
|
38
38
|
"@testing-library/user-event": "^14.6.1",
|
|
39
39
|
"@types/react": "^19.2.17",
|
|
40
40
|
"@types/react-dom": "^19.2.3",
|
|
41
|
-
"@tsrx/react": "^0.
|
|
42
|
-
"octane": "0.
|
|
41
|
+
"@tsrx/react": "^0.4.5",
|
|
42
|
+
"octane": "0.11.0",
|
|
43
43
|
"jsdom": "26.1.0",
|
|
44
44
|
"playwright": "^1.61.1",
|
|
45
45
|
"react": "19.2.3",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"upstream:materialize": "node ../../scripts/react-port/materialize.mjs run --package-dir .",
|
|
56
56
|
"upstream:verify": "node ../../scripts/react-parity/verify-provenance.mjs && node audit/verify-provenance.mjs",
|
|
57
57
|
"upstream:verify:negative-controls": "node audit/verify-provenance.mjs --negative-controls",
|
|
58
|
-
"typecheck:probes": "tsc --noEmit -p audit/type-probes/tsconfig.pristine.json
|
|
58
|
+
"typecheck:probes": "tsc --noEmit -p audit/type-probes/tsconfig.pristine.json",
|
|
59
59
|
"typecheck": "octane-tsc -p tsconfig.json -p typetests/tsconfig.json"
|
|
60
60
|
}
|
|
61
61
|
}
|
|
@@ -79,10 +79,10 @@ export function Group(props: GroupProps) @{
|
|
|
79
79
|
if (state) {
|
|
80
80
|
const dragActive =
|
|
81
81
|
interaction.state === 'active' &&
|
|
82
|
-
|
|
82
|
+
interaction.hitRegions.some((region) => region.group === group);
|
|
83
83
|
return {
|
|
84
84
|
flexGrow: state.layout[panelId] ?? 1,
|
|
85
|
-
pointerEvents: dragActive ? 'none' as const : undefined,
|
|
85
|
+
pointerEvents: dragActive ? ('none' as const) : undefined,
|
|
86
86
|
};
|
|
87
87
|
}
|
|
88
88
|
const initialSize = defaultLayout?.[panelId];
|
|
@@ -128,10 +128,11 @@ export function Group(props: GroupProps) @{
|
|
|
128
128
|
if (panel) panel.panelConstraints.disabled = next.disabled;
|
|
129
129
|
const group = getRegisteredGroup(id);
|
|
130
130
|
const state = getMountedGroupState(id);
|
|
131
|
-
if (group && state)
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
131
|
+
if (group && state)
|
|
132
|
+
updateMountedGroup(group, {
|
|
133
|
+
...state,
|
|
134
|
+
derivedPanelConstraints: calculatePanelConstraints(group),
|
|
135
|
+
});
|
|
135
136
|
},
|
|
136
137
|
updateSeparatorProps(separatorId, next) {
|
|
137
138
|
const separator = valuesRef.current.separators.find(
|
|
@@ -151,7 +152,7 @@ export function Group(props: GroupProps) @{
|
|
|
151
152
|
let sortedDefaultLayout: Layout | undefined;
|
|
152
153
|
if (
|
|
153
154
|
stableProps.defaultLayout &&
|
|
154
|
-
|
|
155
|
+
Object.keys(stableProps.defaultLayout).length === values.panels.length
|
|
155
156
|
) {
|
|
156
157
|
sortedDefaultLayout = {};
|
|
157
158
|
for (const panel of values.panels) {
|
|
@@ -189,26 +190,33 @@ export function Group(props: GroupProps) @{
|
|
|
189
190
|
for (const constraints of derivedPanelConstraints) {
|
|
190
191
|
const previousLayout = event.prev?.layout;
|
|
191
192
|
if (
|
|
192
|
-
constraints.collapsible &&
|
|
193
|
-
|
|
194
|
-
|
|
193
|
+
constraints.collapsible &&
|
|
194
|
+
previousLayout &&
|
|
195
|
+
layoutNumbersEqual(constraints.collapsedSize, layout[constraints.panelId]) &&
|
|
196
|
+
!layoutNumbersEqual(constraints.collapsedSize, previousLayout[constraints.panelId])
|
|
195
197
|
) {
|
|
196
198
|
group.mutableState.expandedPanelSizes[constraints.panelId] =
|
|
197
199
|
previousLayout[constraints.panelId];
|
|
198
200
|
}
|
|
199
201
|
}
|
|
200
202
|
onLayoutChange(layout);
|
|
201
|
-
if (getInteractionState().state !== 'active')
|
|
202
|
-
layout,
|
|
203
|
-
event.isUserInteraction,
|
|
204
|
-
);
|
|
203
|
+
if (getInteractionState().state !== 'active')
|
|
204
|
+
onLayoutChanged(layout, event.isUserInteraction);
|
|
205
205
|
});
|
|
206
206
|
return () => {
|
|
207
207
|
registeredGroupRef.current = null;
|
|
208
208
|
unmount();
|
|
209
209
|
unsubscribe();
|
|
210
210
|
};
|
|
211
|
-
}, [
|
|
211
|
+
}, [
|
|
212
|
+
disabled,
|
|
213
|
+
id,
|
|
214
|
+
onLayoutChange,
|
|
215
|
+
onLayoutChanged,
|
|
216
|
+
orientation,
|
|
217
|
+
panelOrSeparatorChangeSigil,
|
|
218
|
+
stableProps,
|
|
219
|
+
]);
|
|
212
220
|
|
|
213
221
|
// Match upstream: prop updates only refresh mutable state; they do not reapply
|
|
214
222
|
// defaultLayout via setLayout (React leaves the live layout alone).
|
|
@@ -219,26 +227,30 @@ export function Group(props: GroupProps) @{
|
|
|
219
227
|
group.mutableState.disableCursor = !!disableCursor;
|
|
220
228
|
}, [defaultLayout, disableCursor]);
|
|
221
229
|
|
|
222
|
-
return
|
|
223
|
-
<
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
230
|
+
return (
|
|
231
|
+
<GroupContext value={context}>
|
|
232
|
+
<div
|
|
233
|
+
{...rest}
|
|
234
|
+
className={className}
|
|
235
|
+
data-group
|
|
236
|
+
data-testid={id}
|
|
237
|
+
id={id}
|
|
238
|
+
ref={mergedRef}
|
|
239
|
+
style={{
|
|
240
|
+
height: '100%',
|
|
241
|
+
width: '100%',
|
|
242
|
+
overflow: 'hidden',
|
|
243
|
+
...style,
|
|
244
|
+
display: 'flex',
|
|
245
|
+
flexDirection: orientation === 'horizontal' ? 'row' : 'column',
|
|
246
|
+
flexWrap: 'nowrap',
|
|
247
|
+
touchAction: orientation === 'horizontal' ? 'pan-y' : 'pan-x',
|
|
248
|
+
}}
|
|
249
|
+
>
|
|
250
|
+
{children}
|
|
251
|
+
</div>
|
|
252
|
+
</GroupContext>
|
|
253
|
+
);
|
|
242
254
|
}
|
|
243
255
|
|
|
244
256
|
(Group as { displayName?: string }).displayName = 'Group';
|
|
@@ -32,16 +32,23 @@ export function Panel(props: PanelProps) @{
|
|
|
32
32
|
const stableProps = useStableObject({ disabled });
|
|
33
33
|
const elementRef = useRef<HTMLDivElement | null>(null);
|
|
34
34
|
const mergedRef = useMergedRefs(elementRef, elementRefProp);
|
|
35
|
-
const {
|
|
36
|
-
|
|
35
|
+
const {
|
|
36
|
+
getPanelStyles,
|
|
37
|
+
id: groupId,
|
|
38
|
+
orientation,
|
|
39
|
+
registerPanel,
|
|
40
|
+
updatePanelProps,
|
|
41
|
+
} = useGroupContext();
|
|
37
42
|
const hasOnResize = onResizeUnstable != null;
|
|
38
|
-
const onResizeStable = useStableCallback(
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
const onResizeStable = useStableCallback(
|
|
44
|
+
(
|
|
45
|
+
panelSize: PanelSize,
|
|
46
|
+
_id: string | number | undefined,
|
|
47
|
+
prevPanelSize: PanelSize | undefined,
|
|
48
|
+
) => {
|
|
49
|
+
onResizeUnstable?.(panelSize, idProp, prevPanelSize);
|
|
50
|
+
},
|
|
51
|
+
);
|
|
45
52
|
|
|
46
53
|
useIsomorphicLayoutEffect(() => {
|
|
47
54
|
const element = elementRef.current;
|
|
@@ -63,7 +70,20 @@ export function Panel(props: PanelProps) @{
|
|
|
63
70
|
},
|
|
64
71
|
};
|
|
65
72
|
return registerPanel(registeredPanel);
|
|
66
|
-
}, [
|
|
73
|
+
}, [
|
|
74
|
+
groupResizeBehavior,
|
|
75
|
+
collapsedSize,
|
|
76
|
+
collapsible,
|
|
77
|
+
defaultSize,
|
|
78
|
+
hasOnResize,
|
|
79
|
+
id,
|
|
80
|
+
idIsStable,
|
|
81
|
+
maxSize,
|
|
82
|
+
minSize,
|
|
83
|
+
onResizeStable,
|
|
84
|
+
registerPanel,
|
|
85
|
+
stableProps,
|
|
86
|
+
]);
|
|
67
87
|
|
|
68
88
|
useEffect(() => updatePanelProps(id, { disabled }), [disabled, id, updatePanelProps]);
|
|
69
89
|
usePanelImperativeHandle(id, panelRef);
|
|
@@ -77,41 +97,44 @@ export function Panel(props: PanelProps) @{
|
|
|
77
97
|
read,
|
|
78
98
|
read,
|
|
79
99
|
);
|
|
80
|
-
const panelStyles =
|
|
81
|
-
panelStylesString
|
|
82
|
-
|
|
83
|
-
:
|
|
84
|
-
|
|
85
|
-
: { flexGrow: 1 };
|
|
100
|
+
const panelStyles = panelStylesString
|
|
101
|
+
? (JSON.parse(panelStylesString) as Record<string, unknown>)
|
|
102
|
+
: defaultSize !== undefined
|
|
103
|
+
? { flexGrow: undefined, flexShrink: undefined, flexBasis: defaultSize }
|
|
104
|
+
: { flexGrow: 1 };
|
|
86
105
|
|
|
87
|
-
return
|
|
88
|
-
{...rest}
|
|
89
|
-
data-disabled={disabled || undefined}
|
|
90
|
-
data-panel
|
|
91
|
-
data-testid={id}
|
|
92
|
-
id={id}
|
|
93
|
-
ref={mergedRef}
|
|
94
|
-
style={{
|
|
95
|
-
...PROHIBITED_CSS_PROPERTIES,
|
|
96
|
-
display: 'flex',
|
|
97
|
-
flexBasis: 0,
|
|
98
|
-
flexShrink: 1,
|
|
99
|
-
overflow: 'visible',
|
|
100
|
-
...panelStyles,
|
|
101
|
-
}}
|
|
102
|
-
>
|
|
106
|
+
return (
|
|
103
107
|
<div
|
|
104
|
-
|
|
108
|
+
{...rest}
|
|
109
|
+
data-disabled={disabled || undefined}
|
|
110
|
+
data-panel
|
|
111
|
+
data-testid={id}
|
|
112
|
+
id={id}
|
|
113
|
+
ref={mergedRef}
|
|
105
114
|
style={{
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
115
|
+
...PROHIBITED_CSS_PROPERTIES,
|
|
116
|
+
display: 'flex',
|
|
117
|
+
flexBasis: 0,
|
|
118
|
+
flexShrink: 1,
|
|
119
|
+
overflow: 'visible',
|
|
120
|
+
...panelStyles,
|
|
112
121
|
}}
|
|
113
|
-
>
|
|
114
|
-
|
|
122
|
+
>
|
|
123
|
+
<div
|
|
124
|
+
className={className}
|
|
125
|
+
style={{
|
|
126
|
+
maxHeight: '100%',
|
|
127
|
+
maxWidth: '100%',
|
|
128
|
+
flexGrow: 1,
|
|
129
|
+
overflow: 'auto',
|
|
130
|
+
...style,
|
|
131
|
+
touchAction: orientation === 'horizontal' ? 'pan-y' : 'pan-x',
|
|
132
|
+
}}
|
|
133
|
+
>
|
|
134
|
+
{children}
|
|
135
|
+
</div>
|
|
136
|
+
</div>
|
|
137
|
+
);
|
|
115
138
|
}
|
|
116
139
|
|
|
117
140
|
(Panel as { displayName?: string }).displayName = 'Panel';
|
|
@@ -42,8 +42,7 @@ export function Separator(props: SeparatorProps) @{
|
|
|
42
42
|
registerSeparator,
|
|
43
43
|
updateSeparatorProps,
|
|
44
44
|
} = useGroupContext();
|
|
45
|
-
const orientation =
|
|
46
|
-
groupOrientation === 'horizontal' ? 'vertical' : 'horizontal';
|
|
45
|
+
const orientation = groupOrientation === 'horizontal' ? 'vertical' : 'horizontal';
|
|
47
46
|
|
|
48
47
|
useIsomorphicLayoutEffect(() => {
|
|
49
48
|
const element = elementRef.current;
|
|
@@ -58,7 +57,7 @@ export function Separator(props: SeparatorProps) @{
|
|
|
58
57
|
const removeInteractionListener = subscribeToInteractionState((event) => {
|
|
59
58
|
setDragState(
|
|
60
59
|
event.next.state !== 'inactive' &&
|
|
61
|
-
|
|
60
|
+
event.next.hitRegions.some((region) => region.separator === separator)
|
|
62
61
|
? event.next.state
|
|
63
62
|
: 'inactive',
|
|
64
63
|
);
|
|
@@ -85,42 +84,49 @@ export function Separator(props: SeparatorProps) @{
|
|
|
85
84
|
};
|
|
86
85
|
}, [groupId, id, registerSeparator, stableProps]);
|
|
87
86
|
|
|
88
|
-
useEffect(
|
|
89
|
-
disabled,
|
|
90
|
-
disableDoubleClick,
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
? 'active'
|
|
101
|
-
: isFocused
|
|
102
|
-
? 'focus'
|
|
103
|
-
: dragState;
|
|
87
|
+
useEffect(
|
|
88
|
+
() => updateSeparatorProps(id, { disabled, disableDoubleClick }),
|
|
89
|
+
[disabled, disableDoubleClick, id, updateSeparatorProps],
|
|
90
|
+
);
|
|
91
|
+
const cursor = disabled && !disableCursor ? 'not-allowed' : undefined;
|
|
92
|
+
const dataSeparator = disabled
|
|
93
|
+
? 'disabled'
|
|
94
|
+
: dragState === 'active'
|
|
95
|
+
? 'active'
|
|
96
|
+
: isFocused
|
|
97
|
+
? 'focus'
|
|
98
|
+
: dragState;
|
|
104
99
|
|
|
105
|
-
return
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
100
|
+
return (
|
|
101
|
+
<div
|
|
102
|
+
{...rest}
|
|
103
|
+
aria-controls={aria.valueControls}
|
|
104
|
+
aria-disabled={disabled || undefined}
|
|
105
|
+
aria-orientation={orientation}
|
|
106
|
+
aria-valuemax={aria.valueMax}
|
|
107
|
+
aria-valuemin={aria.valueMin}
|
|
108
|
+
aria-valuenow={aria.valueNow}
|
|
109
|
+
className={className}
|
|
110
|
+
data-separator={dataSeparator}
|
|
111
|
+
data-testid={id}
|
|
112
|
+
id={id}
|
|
113
|
+
onBlur={() => setIsFocused(false)}
|
|
114
|
+
onFocus={() => setIsFocused(true)}
|
|
115
|
+
ref={mergedRef}
|
|
116
|
+
role="separator"
|
|
117
|
+
style={{
|
|
118
|
+
flexBasis: 'auto',
|
|
119
|
+
cursor,
|
|
120
|
+
...style,
|
|
121
|
+
flexGrow: 0,
|
|
122
|
+
flexShrink: 0,
|
|
123
|
+
touchAction: 'none',
|
|
124
|
+
}}
|
|
125
|
+
tabIndex={disabled ? undefined : 0}
|
|
126
|
+
>
|
|
127
|
+
{children}
|
|
128
|
+
</div>
|
|
129
|
+
);
|
|
124
130
|
}
|
|
125
131
|
|
|
126
132
|
(Separator as { displayName?: string }).displayName = 'Separator';
|
package/src/index.tsrx
CHANGED
|
@@ -7,6 +7,20 @@ export { useDefaultLayout } from './components/group/useDefaultLayout';
|
|
|
7
7
|
export { usePanelCallbackRef } from './components/panel/usePanelCallbackRef';
|
|
8
8
|
export { usePanelRef } from './components/panel/usePanelRef';
|
|
9
9
|
export { isCoarsePointer } from './global/utils/isCoarsePointer';
|
|
10
|
-
export type {
|
|
11
|
-
|
|
10
|
+
export type {
|
|
11
|
+
GroupImperativeHandle,
|
|
12
|
+
GroupProps,
|
|
13
|
+
Layout,
|
|
14
|
+
LayoutChangedMeta,
|
|
15
|
+
LayoutStorage,
|
|
16
|
+
OnGroupLayoutChange,
|
|
17
|
+
Orientation,
|
|
18
|
+
} from './components/group/types';
|
|
19
|
+
export type {
|
|
20
|
+
OnPanelResize,
|
|
21
|
+
PanelImperativeHandle,
|
|
22
|
+
PanelProps,
|
|
23
|
+
PanelSize,
|
|
24
|
+
SizeUnit,
|
|
25
|
+
} from './components/panel/types';
|
|
12
26
|
export type { SeparatorProps } from './components/separator/types';
|