@kushagradhawan/kookie-ui 0.1.50 → 0.1.52
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/components.css +582 -116
- package/dist/cjs/components/_internal/shell-bottom.d.ts +31 -5
- package/dist/cjs/components/_internal/shell-bottom.d.ts.map +1 -1
- package/dist/cjs/components/_internal/shell-bottom.js +1 -1
- package/dist/cjs/components/_internal/shell-bottom.js.map +3 -3
- package/dist/cjs/components/_internal/shell-handles.d.ts.map +1 -1
- package/dist/cjs/components/_internal/shell-handles.js +1 -1
- package/dist/cjs/components/_internal/shell-handles.js.map +3 -3
- package/dist/cjs/components/_internal/shell-inspector.d.ts +23 -5
- package/dist/cjs/components/_internal/shell-inspector.d.ts.map +1 -1
- package/dist/cjs/components/_internal/shell-inspector.js +1 -1
- package/dist/cjs/components/_internal/shell-inspector.js.map +3 -3
- package/dist/cjs/components/_internal/shell-sidebar.d.ts +24 -6
- package/dist/cjs/components/_internal/shell-sidebar.d.ts.map +1 -1
- package/dist/cjs/components/_internal/shell-sidebar.js +1 -1
- package/dist/cjs/components/_internal/shell-sidebar.js.map +3 -3
- package/dist/cjs/components/chatbar.d.ts +21 -2
- package/dist/cjs/components/chatbar.d.ts.map +1 -1
- package/dist/cjs/components/chatbar.js +1 -1
- package/dist/cjs/components/chatbar.js.map +3 -3
- package/dist/cjs/components/shell.context.d.ts +88 -1
- package/dist/cjs/components/shell.context.d.ts.map +1 -1
- package/dist/cjs/components/shell.context.js +1 -1
- package/dist/cjs/components/shell.context.js.map +3 -3
- package/dist/cjs/components/shell.d.ts +51 -13
- package/dist/cjs/components/shell.d.ts.map +1 -1
- package/dist/cjs/components/shell.hooks.d.ts +7 -1
- package/dist/cjs/components/shell.hooks.d.ts.map +1 -1
- package/dist/cjs/components/shell.hooks.js +1 -1
- package/dist/cjs/components/shell.hooks.js.map +3 -3
- package/dist/cjs/components/shell.js +1 -1
- package/dist/cjs/components/shell.js.map +3 -3
- package/dist/cjs/components/shell.types.d.ts +1 -0
- package/dist/cjs/components/shell.types.d.ts.map +1 -1
- package/dist/cjs/components/shell.types.js +1 -1
- package/dist/cjs/components/shell.types.js.map +2 -2
- package/dist/esm/components/_internal/shell-bottom.d.ts +31 -5
- package/dist/esm/components/_internal/shell-bottom.d.ts.map +1 -1
- package/dist/esm/components/_internal/shell-bottom.js +1 -1
- package/dist/esm/components/_internal/shell-bottom.js.map +3 -3
- package/dist/esm/components/_internal/shell-handles.d.ts.map +1 -1
- package/dist/esm/components/_internal/shell-handles.js +1 -1
- package/dist/esm/components/_internal/shell-handles.js.map +3 -3
- package/dist/esm/components/_internal/shell-inspector.d.ts +23 -5
- package/dist/esm/components/_internal/shell-inspector.d.ts.map +1 -1
- package/dist/esm/components/_internal/shell-inspector.js +1 -1
- package/dist/esm/components/_internal/shell-inspector.js.map +3 -3
- package/dist/esm/components/_internal/shell-sidebar.d.ts +24 -6
- package/dist/esm/components/_internal/shell-sidebar.d.ts.map +1 -1
- package/dist/esm/components/_internal/shell-sidebar.js +1 -1
- package/dist/esm/components/_internal/shell-sidebar.js.map +3 -3
- package/dist/esm/components/chatbar.d.ts +21 -2
- package/dist/esm/components/chatbar.d.ts.map +1 -1
- package/dist/esm/components/chatbar.js +1 -1
- package/dist/esm/components/chatbar.js.map +3 -3
- package/dist/esm/components/shell.context.d.ts +88 -1
- package/dist/esm/components/shell.context.d.ts.map +1 -1
- package/dist/esm/components/shell.context.js +1 -1
- package/dist/esm/components/shell.context.js.map +3 -3
- package/dist/esm/components/shell.d.ts +51 -13
- package/dist/esm/components/shell.d.ts.map +1 -1
- package/dist/esm/components/shell.hooks.d.ts +7 -1
- package/dist/esm/components/shell.hooks.d.ts.map +1 -1
- package/dist/esm/components/shell.hooks.js +1 -1
- package/dist/esm/components/shell.hooks.js.map +3 -3
- package/dist/esm/components/shell.js +1 -1
- package/dist/esm/components/shell.js.map +3 -3
- package/dist/esm/components/shell.types.d.ts +1 -0
- package/dist/esm/components/shell.types.d.ts.map +1 -1
- package/dist/esm/components/shell.types.js.map +2 -2
- package/package.json +14 -3
- package/schemas/base-button.json +1 -1
- package/schemas/button.json +1 -1
- package/schemas/icon-button.json +1 -1
- package/schemas/index.json +6 -6
- package/schemas/toggle-button.json +1 -1
- package/schemas/toggle-icon-button.json +1 -1
- package/src/components/_internal/base-menu.css +16 -16
- package/src/components/_internal/base-sidebar-menu.css +23 -20
- package/src/components/_internal/base-sidebar.css +13 -0
- package/src/components/_internal/shell-bottom.tsx +176 -49
- package/src/components/_internal/shell-handles.tsx +29 -4
- package/src/components/_internal/shell-inspector.tsx +175 -43
- package/src/components/_internal/shell-sidebar.tsx +177 -93
- package/src/components/chatbar.css +240 -21
- package/src/components/chatbar.tsx +280 -291
- package/src/components/sheet.css +8 -16
- package/src/components/shell.context.tsx +79 -3
- package/src/components/shell.css +0 -1
- package/src/components/shell.hooks.ts +35 -0
- package/src/components/shell.tsx +574 -235
- package/src/components/shell.types.ts +2 -0
- package/src/components/sidebar.css +2 -2
- package/styles.css +582 -116
|
@@ -84,8 +84,16 @@ export const PaneHandle = React.forwardRef<HTMLDivElement, React.ComponentPropsW
|
|
|
84
84
|
handleEl.releasePointerCapture(pointerId);
|
|
85
85
|
} catch {}
|
|
86
86
|
window.removeEventListener('pointermove', handleMove as any);
|
|
87
|
+
document.removeEventListener('pointermove', handleMove as any);
|
|
88
|
+
window.removeEventListener('mousemove', handleMove as any);
|
|
89
|
+
document.removeEventListener('mousemove', handleMove as any);
|
|
90
|
+
handleEl.removeEventListener('pointermove', handleMove as any);
|
|
87
91
|
window.removeEventListener('pointerup', handleUp as any);
|
|
92
|
+
document.removeEventListener('pointerup', handleUp as any);
|
|
93
|
+
window.removeEventListener('mouseup', handleUp as any);
|
|
94
|
+
document.removeEventListener('mouseup', handleUp as any);
|
|
88
95
|
window.removeEventListener('pointercancel', handleUp as any);
|
|
96
|
+
document.removeEventListener('pointercancel', handleUp as any);
|
|
89
97
|
window.removeEventListener('keydown', handleKey as any);
|
|
90
98
|
handleEl.removeEventListener('lostpointercapture', handleUp as any);
|
|
91
99
|
container.removeAttribute('data-resizing');
|
|
@@ -120,8 +128,17 @@ export const PaneHandle = React.forwardRef<HTMLDivElement, React.ComponentPropsW
|
|
|
120
128
|
}
|
|
121
129
|
};
|
|
122
130
|
window.addEventListener('pointermove', handleMove as any);
|
|
131
|
+
document.addEventListener('pointermove', handleMove as any);
|
|
132
|
+
// Fallbacks for environments that don't fully support PointerEvent on window
|
|
133
|
+
window.addEventListener('mousemove', handleMove as any);
|
|
134
|
+
document.addEventListener('mousemove', handleMove as any);
|
|
135
|
+
handleEl.addEventListener('pointermove', handleMove as any);
|
|
123
136
|
window.addEventListener('pointerup', handleUp as any);
|
|
137
|
+
document.addEventListener('pointerup', handleUp as any);
|
|
138
|
+
window.addEventListener('mouseup', handleUp as any);
|
|
139
|
+
document.addEventListener('mouseup', handleUp as any);
|
|
124
140
|
window.addEventListener('pointercancel', handleUp as any);
|
|
141
|
+
document.addEventListener('pointercancel', handleUp as any);
|
|
125
142
|
window.addEventListener('keydown', handleKey as any);
|
|
126
143
|
handleEl.addEventListener('lostpointercapture', handleUp as any);
|
|
127
144
|
activeCleanupRef.current = cleanup;
|
|
@@ -132,13 +149,20 @@ export const PaneHandle = React.forwardRef<HTMLDivElement, React.ComponentPropsW
|
|
|
132
149
|
onKeyDown={(e) => {
|
|
133
150
|
if (!containerRef.current) return;
|
|
134
151
|
const container = containerRef.current;
|
|
135
|
-
const
|
|
152
|
+
const rawCurrent = getComputedStyle(container).getPropertyValue(cssVarName);
|
|
153
|
+
const parsedCurrent = Number.parseFloat(rawCurrent.trim());
|
|
154
|
+
const current = Number.isFinite(parsedCurrent) ? parsedCurrent : defaultSize;
|
|
136
155
|
const clamp = (v: number) => Math.min(Math.max(v, minSize), maxSize);
|
|
137
156
|
const step = e.shiftKey ? 32 : 8;
|
|
138
157
|
let delta = 0;
|
|
139
158
|
if (orientation === 'vertical') {
|
|
140
|
-
|
|
141
|
-
|
|
159
|
+
const docDir = typeof document !== 'undefined' ? document.dir : undefined;
|
|
160
|
+
const cssDir = getComputedStyle(container).direction;
|
|
161
|
+
const hasRtlAncestor = !!(container.closest && container.closest('[dir="rtl"]'));
|
|
162
|
+
const isRtl = docDir === 'rtl' || cssDir === 'rtl' || hasRtlAncestor;
|
|
163
|
+
if (e.key === 'ArrowRight')
|
|
164
|
+
delta = isRtl ? -step : step; // inline-end
|
|
165
|
+
else if (e.key === 'ArrowLeft') delta = isRtl ? step : -step; // inline-start
|
|
142
166
|
} else {
|
|
143
167
|
if (e.key === 'ArrowDown') delta = step;
|
|
144
168
|
else if (e.key === 'ArrowUp') delta = -step;
|
|
@@ -166,7 +190,8 @@ export const PaneHandle = React.forwardRef<HTMLDivElement, React.ComponentPropsW
|
|
|
166
190
|
if (delta !== 0) {
|
|
167
191
|
e.preventDefault();
|
|
168
192
|
onResizeStart?.(current);
|
|
169
|
-
const
|
|
193
|
+
const signedDelta = orientation === 'vertical' ? (edge === 'start' ? -delta : delta) : delta;
|
|
194
|
+
const next = clamp(current + signedDelta);
|
|
170
195
|
container.style.setProperty(cssVarName, `${next}px`);
|
|
171
196
|
(e.currentTarget as HTMLElement).setAttribute('aria-valuenow', String(next));
|
|
172
197
|
onResize?.(next);
|
|
@@ -3,7 +3,7 @@ import classNames from 'classnames';
|
|
|
3
3
|
import * as Sheet from '../sheet.js';
|
|
4
4
|
import { VisuallyHidden } from '../visually-hidden.js';
|
|
5
5
|
import { useShell } from '../shell.context.js';
|
|
6
|
-
import { useResponsivePresentation } from '../shell.hooks.js';
|
|
6
|
+
import { useResponsivePresentation, useResponsiveValue } from '../shell.hooks.js';
|
|
7
7
|
import { PaneResizeContext } from './shell-resize.js';
|
|
8
8
|
import { InspectorHandle, PaneHandle } from './shell-handles.js';
|
|
9
9
|
import { BREAKPOINTS } from '../shell.types.js';
|
|
@@ -11,9 +11,7 @@ import type { Breakpoint, PaneMode, PaneSizePersistence, ResponsivePresentation
|
|
|
11
11
|
|
|
12
12
|
interface PaneProps extends React.ComponentPropsWithoutRef<'div'> {
|
|
13
13
|
presentation?: ResponsivePresentation;
|
|
14
|
-
mode
|
|
15
|
-
defaultMode?: any;
|
|
16
|
-
onModeChange?: (mode: PaneMode) => void;
|
|
14
|
+
// legacy mode removed
|
|
17
15
|
expandedSize?: number;
|
|
18
16
|
minSize?: number;
|
|
19
17
|
maxSize?: number;
|
|
@@ -32,16 +30,29 @@ interface PaneProps extends React.ComponentPropsWithoutRef<'div'> {
|
|
|
32
30
|
persistence?: PaneSizePersistence;
|
|
33
31
|
}
|
|
34
32
|
|
|
35
|
-
type
|
|
33
|
+
type InspectorOpenChangeMeta = { reason: 'init' | 'toggle' | 'responsive' };
|
|
34
|
+
type InspectorControlledProps = { open: boolean | Partial<Record<Breakpoint, boolean>>; onOpenChange?: (open: boolean, meta: InspectorOpenChangeMeta) => void; defaultOpen?: never };
|
|
35
|
+
type InspectorUncontrolledProps = { defaultOpen?: boolean | Partial<Record<Breakpoint, boolean>>; onOpenChange?: (open: boolean, meta: InspectorOpenChangeMeta) => void; open?: never };
|
|
36
|
+
type InspectorSizeChangeMeta = { reason: 'init' | 'resize' | 'controlled' };
|
|
37
|
+
type InspectorPublicProps = PaneProps &
|
|
38
|
+
(InspectorControlledProps | InspectorUncontrolledProps) & {
|
|
39
|
+
onSizeChange?: (size: number, meta: InspectorSizeChangeMeta) => void;
|
|
40
|
+
sizeUpdate?: 'throttle' | 'debounce';
|
|
41
|
+
sizeUpdateMs?: number;
|
|
42
|
+
};
|
|
36
43
|
|
|
37
|
-
|
|
44
|
+
type InspectorComponent = React.ForwardRefExoticComponent<InspectorPublicProps & React.RefAttributes<HTMLDivElement>> & { Handle: typeof InspectorHandle };
|
|
45
|
+
|
|
46
|
+
export const Inspector = React.forwardRef<HTMLDivElement, InspectorPublicProps>(
|
|
38
47
|
(
|
|
39
48
|
{
|
|
40
49
|
className,
|
|
41
50
|
presentation = { initial: 'overlay', lg: 'fixed' },
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
51
|
+
// removed legacy props
|
|
52
|
+
// new API
|
|
53
|
+
defaultOpen,
|
|
54
|
+
open,
|
|
55
|
+
onOpenChange,
|
|
45
56
|
expandedSize = 320,
|
|
46
57
|
minSize = 200,
|
|
47
58
|
maxSize = 500,
|
|
@@ -80,47 +91,104 @@ export const Inspector = React.forwardRef<HTMLDivElement, PaneProps>(
|
|
|
80
91
|
const handleChildren = childArray.filter((el: React.ReactElement) => React.isValidElement(el) && el.type === InspectorHandle);
|
|
81
92
|
const contentChildren = childArray.filter((el: React.ReactElement) => !(React.isValidElement(el) && el.type === InspectorHandle));
|
|
82
93
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
|
|
94
|
+
// Throttled/debounced emitter for onSizeChange
|
|
95
|
+
const emitSizeChange = React.useMemo(() => {
|
|
96
|
+
const cb = (props as any).onSizeChange as undefined | ((s: number, meta: InspectorSizeChangeMeta) => void);
|
|
97
|
+
const strategy = (props as any).sizeUpdate as undefined | 'throttle' | 'debounce';
|
|
98
|
+
const ms = (props as any).sizeUpdateMs ?? 50;
|
|
99
|
+
if (!cb) return () => {};
|
|
100
|
+
if (strategy === 'debounce') {
|
|
101
|
+
let t: any = null;
|
|
102
|
+
return (s: number, meta: InspectorSizeChangeMeta) => {
|
|
103
|
+
if (t) clearTimeout(t);
|
|
104
|
+
t = setTimeout(() => {
|
|
105
|
+
cb(s, meta);
|
|
106
|
+
}, ms);
|
|
107
|
+
};
|
|
88
108
|
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
109
|
+
if (strategy === 'throttle') {
|
|
110
|
+
let last = 0;
|
|
111
|
+
return (s: number, meta: InspectorSizeChangeMeta) => {
|
|
112
|
+
const now = Date.now();
|
|
113
|
+
if (now - last >= ms) {
|
|
114
|
+
last = now;
|
|
115
|
+
cb(s, meta);
|
|
116
|
+
}
|
|
117
|
+
};
|
|
97
118
|
}
|
|
98
|
-
return
|
|
99
|
-
}, [
|
|
119
|
+
return (s: number, meta: InspectorSizeChangeMeta) => cb(s, meta);
|
|
120
|
+
}, [(props as any).onSizeChange, (props as any).sizeUpdate, (props as any).sizeUpdateMs]);
|
|
100
121
|
|
|
101
|
-
|
|
102
|
-
React.
|
|
103
|
-
|
|
104
|
-
if (
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
const next = resolveResponsiveMode();
|
|
108
|
-
if (next !== shell.inspectorMode) {
|
|
109
|
-
shell.setInspectorMode(next);
|
|
122
|
+
// Dev guards
|
|
123
|
+
const wasControlledRef = React.useRef<boolean | null>(null);
|
|
124
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
125
|
+
if (typeof open !== 'undefined' && typeof defaultOpen !== 'undefined') {
|
|
126
|
+
// eslint-disable-next-line no-console
|
|
127
|
+
console.error('Shell.Inspector: Do not pass both `open` and `defaultOpen`. Choose one.');
|
|
110
128
|
}
|
|
111
|
-
}
|
|
129
|
+
}
|
|
112
130
|
|
|
131
|
+
// Warn on controlled/uncontrolled mode switch
|
|
113
132
|
React.useEffect(() => {
|
|
114
|
-
|
|
115
|
-
|
|
133
|
+
const isControlled = typeof open !== 'undefined';
|
|
134
|
+
if (wasControlledRef.current === null) {
|
|
135
|
+
wasControlledRef.current = isControlled;
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
if (wasControlledRef.current !== isControlled) {
|
|
139
|
+
// eslint-disable-next-line no-console
|
|
140
|
+
console.warn('Shell.Inspector: Switching between controlled and uncontrolled `open` is not supported.');
|
|
141
|
+
wasControlledRef.current = isControlled;
|
|
116
142
|
}
|
|
117
|
-
}, [
|
|
143
|
+
}, [open]);
|
|
144
|
+
|
|
145
|
+
const responsiveNotifiedRef = React.useRef(false);
|
|
146
|
+
const didInitFromDefaultOpenRef = React.useRef(false);
|
|
147
|
+
const resolvedDefaultOpen = useResponsiveValue(defaultOpen);
|
|
148
|
+
React.useEffect(() => {
|
|
149
|
+
if (!shell.currentBreakpointReady) return;
|
|
150
|
+
if (didInitFromDefaultOpenRef.current) return;
|
|
151
|
+
if (typeof open !== 'undefined') return; // controlled ignores default
|
|
152
|
+
if (typeof defaultOpen === 'undefined') return;
|
|
153
|
+
const initialOpen = Boolean(resolvedDefaultOpen);
|
|
154
|
+
shell.setInspectorMode(initialOpen ? 'expanded' : 'collapsed');
|
|
155
|
+
if (initialOpen) onOpenChange?.(true, { reason: 'init' });
|
|
156
|
+
didInitFromDefaultOpenRef.current = true;
|
|
157
|
+
}, [shell.currentBreakpointReady, resolvedDefaultOpen, defaultOpen, open, onOpenChange]);
|
|
118
158
|
|
|
159
|
+
// Controlled responsive open
|
|
160
|
+
const resolvedOpen = useResponsiveValue(open);
|
|
119
161
|
React.useEffect(() => {
|
|
120
|
-
if (
|
|
121
|
-
|
|
162
|
+
if (typeof resolvedOpen === 'undefined') return;
|
|
163
|
+
const shouldExpand = Boolean(resolvedOpen);
|
|
164
|
+
if (shouldExpand && shell.inspectorMode !== 'expanded') shell.setInspectorMode('expanded');
|
|
165
|
+
if (!shouldExpand && shell.inspectorMode !== 'collapsed') shell.setInspectorMode('collapsed');
|
|
166
|
+
}, [resolvedOpen, shell.inspectorMode]);
|
|
167
|
+
|
|
168
|
+
// Removed boolean-only mount init; handled in responsive init effect above
|
|
169
|
+
|
|
170
|
+
// Removed: boolean-only controlled sync. Use responsive-resolved effect below instead.
|
|
171
|
+
|
|
172
|
+
const initNotifiedRef = React.useRef(false);
|
|
173
|
+
const lastInspectorModeRef = React.useRef<PaneMode | null>(null);
|
|
174
|
+
React.useEffect(() => {
|
|
175
|
+
// Notify init open
|
|
176
|
+
if (!initNotifiedRef.current && typeof open === 'undefined' && defaultOpen && shell.inspectorMode === 'expanded') {
|
|
177
|
+
onOpenChange?.(true, { reason: 'init' });
|
|
178
|
+
initNotifiedRef.current = true;
|
|
122
179
|
}
|
|
123
|
-
|
|
180
|
+
|
|
181
|
+
// Notify toggles when uncontrolled (avoid double-notify after responsive change)
|
|
182
|
+
if (typeof open === 'undefined') {
|
|
183
|
+
if (lastInspectorModeRef.current !== null && lastInspectorModeRef.current !== shell.inspectorMode) {
|
|
184
|
+
if (!responsiveNotifiedRef.current) {
|
|
185
|
+
onOpenChange?.(shell.inspectorMode === 'expanded', { reason: 'toggle' });
|
|
186
|
+
}
|
|
187
|
+
responsiveNotifiedRef.current = false;
|
|
188
|
+
}
|
|
189
|
+
lastInspectorModeRef.current = shell.inspectorMode;
|
|
190
|
+
}
|
|
191
|
+
}, [shell.inspectorMode, open, defaultOpen, onOpenChange]);
|
|
124
192
|
|
|
125
193
|
React.useEffect(() => {
|
|
126
194
|
if (shell.inspectorMode === 'expanded') {
|
|
@@ -184,6 +252,7 @@ export const Inspector = React.forwardRef<HTMLDivElement, PaneProps>(
|
|
|
184
252
|
onResizeStart,
|
|
185
253
|
onResizeEnd: (size) => {
|
|
186
254
|
onResizeEnd?.(size);
|
|
255
|
+
emitSizeChange(size, { reason: 'resize' });
|
|
187
256
|
persistenceAdapter?.save?.(size);
|
|
188
257
|
},
|
|
189
258
|
target: 'inspector',
|
|
@@ -199,6 +268,56 @@ export const Inspector = React.forwardRef<HTMLDivElement, PaneProps>(
|
|
|
199
268
|
</PaneResizeContext.Provider>
|
|
200
269
|
) : null;
|
|
201
270
|
|
|
271
|
+
// Normalize CSS lengths to px
|
|
272
|
+
const normalizeToPx = React.useCallback((value: number | string | undefined): number | undefined => {
|
|
273
|
+
if (value == null) return undefined;
|
|
274
|
+
if (typeof value === 'number' && Number.isFinite(value)) return value;
|
|
275
|
+
const str = String(value).trim();
|
|
276
|
+
if (!str) return undefined;
|
|
277
|
+
if (str.endsWith('px')) return Number.parseFloat(str);
|
|
278
|
+
if (str.endsWith('rem')) {
|
|
279
|
+
const rem = Number.parseFloat(getComputedStyle(document.documentElement).fontSize || '16') || 16;
|
|
280
|
+
return Number.parseFloat(str) * rem;
|
|
281
|
+
}
|
|
282
|
+
if (str.endsWith('%')) {
|
|
283
|
+
const pct = Number.parseFloat(str);
|
|
284
|
+
const base = document.documentElement.clientWidth || window.innerWidth || 0;
|
|
285
|
+
return (pct / 100) * base;
|
|
286
|
+
}
|
|
287
|
+
const n = Number.parseFloat(str);
|
|
288
|
+
return Number.isFinite(n) ? n : undefined;
|
|
289
|
+
}, []);
|
|
290
|
+
|
|
291
|
+
// Apply defaultSize on mount when uncontrolled
|
|
292
|
+
React.useEffect(() => {
|
|
293
|
+
if (!localRef.current) return;
|
|
294
|
+
if (typeof (props as any).size === 'undefined' && typeof (props as any).defaultSize !== 'undefined') {
|
|
295
|
+
const px = normalizeToPx((props as any).defaultSize);
|
|
296
|
+
if (typeof px === 'number' && Number.isFinite(px)) {
|
|
297
|
+
const minPx = typeof minSize === 'number' ? minSize : undefined;
|
|
298
|
+
const maxPx = typeof maxSize === 'number' ? maxSize : undefined;
|
|
299
|
+
const clamped = Math.min(maxPx ?? px, Math.max(minPx ?? px, px));
|
|
300
|
+
localRef.current.style.setProperty('--inspector-size', `${clamped}px`);
|
|
301
|
+
emitSizeChange(clamped, { reason: 'init' });
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
305
|
+
}, []);
|
|
306
|
+
|
|
307
|
+
// Controlled size sync
|
|
308
|
+
React.useEffect(() => {
|
|
309
|
+
if (!localRef.current) return;
|
|
310
|
+
if (typeof (props as any).size === 'undefined') return;
|
|
311
|
+
const px = normalizeToPx((props as any).size);
|
|
312
|
+
if (typeof px === 'number' && Number.isFinite(px)) {
|
|
313
|
+
const minPx = typeof minSize === 'number' ? minSize : undefined;
|
|
314
|
+
const maxPx = typeof maxSize === 'number' ? maxSize : undefined;
|
|
315
|
+
const clamped = Math.min(maxPx ?? px, Math.max(minPx ?? px, px));
|
|
316
|
+
localRef.current.style.setProperty('--inspector-size', `${clamped}px`);
|
|
317
|
+
emitSizeChange(clamped, { reason: 'controlled' });
|
|
318
|
+
}
|
|
319
|
+
}, [(props as any).size, minSize, maxSize, normalizeToPx, emitSizeChange]);
|
|
320
|
+
|
|
202
321
|
if (isOverlay) {
|
|
203
322
|
const open = shell.inspectorMode === 'expanded';
|
|
204
323
|
return (
|
|
@@ -213,15 +332,28 @@ export const Inspector = React.forwardRef<HTMLDivElement, PaneProps>(
|
|
|
213
332
|
);
|
|
214
333
|
}
|
|
215
334
|
|
|
335
|
+
// Strip control/size props from DOM spread
|
|
336
|
+
const {
|
|
337
|
+
defaultOpen: _inspectorDefaultOpenIgnored,
|
|
338
|
+
open: _inspectorOpenIgnored,
|
|
339
|
+
onOpenChange: _inspectorOnOpenChangeIgnored,
|
|
340
|
+
size: _sz,
|
|
341
|
+
defaultSize: _dsz,
|
|
342
|
+
onSizeChange: _osc,
|
|
343
|
+
sizeUpdate: _szu,
|
|
344
|
+
sizeUpdateMs: _szums,
|
|
345
|
+
...inspectorDomProps
|
|
346
|
+
} = props as any;
|
|
347
|
+
|
|
216
348
|
return (
|
|
217
349
|
<div
|
|
218
|
-
{...
|
|
350
|
+
{...inspectorDomProps}
|
|
219
351
|
ref={setRef}
|
|
220
352
|
className={classNames('rt-ShellInspector', className)}
|
|
221
353
|
data-mode={shell.inspectorMode}
|
|
222
354
|
data-peek={shell.peekTarget === 'inspector' || undefined}
|
|
223
|
-
data-presentation={resolvedPresentation}
|
|
224
|
-
data-open={(isStacked && isExpanded) || undefined}
|
|
355
|
+
data-presentation={shell.currentBreakpointReady ? resolvedPresentation : undefined}
|
|
356
|
+
data-open={(shell.currentBreakpointReady && isStacked && isExpanded) || undefined}
|
|
225
357
|
style={{
|
|
226
358
|
...style,
|
|
227
359
|
['--inspector-size' as any]: `${expandedSize}px`,
|