@sybilion/uilib 1.3.59 → 1.3.60
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/esm/components/ui/Chat/ChatSheet/useChatPanelChromeModel.js +33 -19
- package/dist/esm/hooks/panelWidth.js +13 -2
- package/package.json +1 -1
- package/src/components/ui/Chat/ChatSheet/useChatPanelChromeModel.tsx +34 -19
- package/src/hooks/panelWidth.test.ts +33 -0
- package/src/hooks/panelWidth.ts +27 -2
|
@@ -123,29 +123,27 @@ function useChatPanelChromeModel({ embedAsPage, presets, scopeId, onMessage, onS
|
|
|
123
123
|
if (embedAsPage) {
|
|
124
124
|
return;
|
|
125
125
|
}
|
|
126
|
-
const run = () => {
|
|
127
|
-
setIsOpen(open);
|
|
128
|
-
setChatPanelOpen(open);
|
|
129
|
-
};
|
|
130
|
-
if (!isMobile &&
|
|
131
|
-
'startViewTransition' in document &&
|
|
132
|
-
document.startViewTransition) {
|
|
133
|
-
document.startViewTransition(run);
|
|
134
|
-
}
|
|
135
|
-
else {
|
|
136
|
-
run();
|
|
137
|
-
}
|
|
138
126
|
if (open) {
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
// and drop other query keys.
|
|
127
|
+
setIsOpen(true);
|
|
128
|
+
setChatPanelOpen(true);
|
|
142
129
|
if (!searchParams.has(CHAT_QUERY_PARAM)) {
|
|
143
130
|
addSearchParams({ [CHAT_QUERY_PARAM]: CHAT_OPEN_VALUE });
|
|
144
131
|
}
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
const applyClose = () => {
|
|
135
|
+
setIsOpen(false);
|
|
136
|
+
setChatPanelOpen(false);
|
|
137
|
+
};
|
|
138
|
+
if (!isMobile &&
|
|
139
|
+
'startViewTransition' in document &&
|
|
140
|
+
document.startViewTransition) {
|
|
141
|
+
document.startViewTransition(applyClose);
|
|
145
142
|
}
|
|
146
143
|
else {
|
|
147
|
-
|
|
144
|
+
applyClose();
|
|
148
145
|
}
|
|
146
|
+
removeSearchParams(CHAT_QUERY_PARAM);
|
|
149
147
|
};
|
|
150
148
|
const isEmpty = isChatEmpty(chat) && !isLoading;
|
|
151
149
|
const openNewChatWithPrefill = useCallback((prompt) => {
|
|
@@ -630,9 +628,25 @@ function useChatPanelChromeModel({ embedAsPage, presets, scopeId, onMessage, onS
|
|
|
630
628
|
if (embedAsPage) {
|
|
631
629
|
return;
|
|
632
630
|
}
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
631
|
+
if (!chatOpen) {
|
|
632
|
+
setIsOpen(false);
|
|
633
|
+
setChatPanelOpen(false);
|
|
634
|
+
return;
|
|
635
|
+
}
|
|
636
|
+
if (!shellChatPanelOpen && sidebarNavOpen) {
|
|
637
|
+
removeSearchParams(CHAT_QUERY_PARAM);
|
|
638
|
+
return;
|
|
639
|
+
}
|
|
640
|
+
setIsOpen(true);
|
|
641
|
+
setChatPanelOpen(true);
|
|
642
|
+
}, [
|
|
643
|
+
embedAsPage,
|
|
644
|
+
chatOpen,
|
|
645
|
+
setChatPanelOpen,
|
|
646
|
+
sidebarNavOpen,
|
|
647
|
+
shellChatPanelOpen,
|
|
648
|
+
removeSearchParams,
|
|
649
|
+
]);
|
|
636
650
|
/** Shell closed chat for space (e.g. nav opened); keep UI and URL in sync. */
|
|
637
651
|
useEffect(() => {
|
|
638
652
|
if (embedAsPage || shellChatPanelOpen || !isOpen) {
|
|
@@ -46,13 +46,24 @@ function clampChatWidthPx(px, shellWidth, effectiveSidebarWidthPx) {
|
|
|
46
46
|
function defaultChatWidthPx(shellWidth) {
|
|
47
47
|
return clampChatWidthPx(CHAT_WIDTH_DEFAULT_PX, shellWidth, SIDEBAR_WIDTH_DEFAULT_PX);
|
|
48
48
|
}
|
|
49
|
+
/**
|
|
50
|
+
* Stored width can fall below panel min when the shell was narrow (clamp cap < min).
|
|
51
|
+
* For dual-panel fit checks, treat open panels as at least their min width.
|
|
52
|
+
*/
|
|
53
|
+
function effectiveOpenPanelWidthPx(px, minPx, bothPanelsOpen) {
|
|
54
|
+
if (bothPanelsOpen) {
|
|
55
|
+
return Math.max(px, minPx);
|
|
56
|
+
}
|
|
57
|
+
return px > 0 ? px : minPx;
|
|
58
|
+
}
|
|
49
59
|
/** Minimum shell width when nav and/or chat panels are open (main column at least `CENTRAL_AREA_MIN_PX`). */
|
|
50
60
|
function requiredShellWidthForSidebars(widths) {
|
|
61
|
+
const bothPanelsOpen = widths.mainSidebarOpen && widths.chatPanelOpen;
|
|
51
62
|
const sidebarW = widths.mainSidebarOpen
|
|
52
|
-
? widths.sidebarWidthPx
|
|
63
|
+
? effectiveOpenPanelWidthPx(widths.sidebarWidthPx, SIDEBAR_WIDTH_MIN_PX, bothPanelsOpen)
|
|
53
64
|
: 0;
|
|
54
65
|
const chatW = widths.chatPanelOpen
|
|
55
|
-
? widths.chatWidthPx
|
|
66
|
+
? effectiveOpenPanelWidthPx(widths.chatWidthPx, CHAT_WIDTH_MIN_PX, bothPanelsOpen)
|
|
56
67
|
: 0;
|
|
57
68
|
return sidebarW + CENTRAL_AREA_MIN_PX + chatW;
|
|
58
69
|
}
|
package/package.json
CHANGED
|
@@ -287,30 +287,29 @@ export function useChatPanelChromeModel({
|
|
|
287
287
|
if (embedAsPage) {
|
|
288
288
|
return;
|
|
289
289
|
}
|
|
290
|
-
|
|
291
|
-
setIsOpen(
|
|
292
|
-
setChatPanelOpen(
|
|
290
|
+
if (open) {
|
|
291
|
+
setIsOpen(true);
|
|
292
|
+
setChatPanelOpen(true);
|
|
293
|
+
if (!searchParams.has(CHAT_QUERY_PARAM)) {
|
|
294
|
+
addSearchParams({ [CHAT_QUERY_PARAM]: CHAT_OPEN_VALUE });
|
|
295
|
+
}
|
|
296
|
+
return;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
const applyClose = () => {
|
|
300
|
+
setIsOpen(false);
|
|
301
|
+
setChatPanelOpen(false);
|
|
293
302
|
};
|
|
294
303
|
if (
|
|
295
304
|
!isMobile &&
|
|
296
305
|
'startViewTransition' in document &&
|
|
297
306
|
document.startViewTransition
|
|
298
307
|
) {
|
|
299
|
-
document.startViewTransition(
|
|
308
|
+
document.startViewTransition(applyClose);
|
|
300
309
|
} else {
|
|
301
|
-
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
if (open) {
|
|
305
|
-
// Avoid a second setSearchParams when `chat` is already set (e.g. Reports merges
|
|
306
|
-
// reportId + chat in one update). A redundant add can merge from a stale `prev`
|
|
307
|
-
// and drop other query keys.
|
|
308
|
-
if (!searchParams.has(CHAT_QUERY_PARAM)) {
|
|
309
|
-
addSearchParams({ [CHAT_QUERY_PARAM]: CHAT_OPEN_VALUE });
|
|
310
|
-
}
|
|
311
|
-
} else {
|
|
312
|
-
removeSearchParams(CHAT_QUERY_PARAM);
|
|
310
|
+
applyClose();
|
|
313
311
|
}
|
|
312
|
+
removeSearchParams(CHAT_QUERY_PARAM);
|
|
314
313
|
};
|
|
315
314
|
|
|
316
315
|
const isEmpty = isChatEmpty(chat) && !isLoading;
|
|
@@ -856,9 +855,25 @@ export function useChatPanelChromeModel({
|
|
|
856
855
|
if (embedAsPage) {
|
|
857
856
|
return;
|
|
858
857
|
}
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
858
|
+
if (!chatOpen) {
|
|
859
|
+
setIsOpen(false);
|
|
860
|
+
setChatPanelOpen(false);
|
|
861
|
+
return;
|
|
862
|
+
}
|
|
863
|
+
if (!shellChatPanelOpen && sidebarNavOpen) {
|
|
864
|
+
removeSearchParams(CHAT_QUERY_PARAM);
|
|
865
|
+
return;
|
|
866
|
+
}
|
|
867
|
+
setIsOpen(true);
|
|
868
|
+
setChatPanelOpen(true);
|
|
869
|
+
}, [
|
|
870
|
+
embedAsPage,
|
|
871
|
+
chatOpen,
|
|
872
|
+
setChatPanelOpen,
|
|
873
|
+
sidebarNavOpen,
|
|
874
|
+
shellChatPanelOpen,
|
|
875
|
+
removeSearchParams,
|
|
876
|
+
]);
|
|
862
877
|
|
|
863
878
|
/** Shell closed chat for space (e.g. nav opened); keep UI and URL in sync. */
|
|
864
879
|
useEffect(() => {
|
|
@@ -37,6 +37,28 @@ describe('requiredShellWidthForSidebars', () => {
|
|
|
37
37
|
}),
|
|
38
38
|
).toBe(SIDEBAR_WIDTH_MIN_PX + CENTRAL_AREA_MIN_PX + CHAT_WIDTH_MIN_PX);
|
|
39
39
|
});
|
|
40
|
+
|
|
41
|
+
it('uses panel mins for sub-min stored widths when both panels are open', () => {
|
|
42
|
+
expect(
|
|
43
|
+
requiredShellWidthForSidebars({
|
|
44
|
+
mainSidebarOpen: true,
|
|
45
|
+
chatPanelOpen: true,
|
|
46
|
+
sidebarWidthPx: 300,
|
|
47
|
+
chatWidthPx: 37,
|
|
48
|
+
}),
|
|
49
|
+
).toBe(300 + CENTRAL_AREA_MIN_PX + CHAT_WIDTH_MIN_PX);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it('keeps actual chat width when only chat is open', () => {
|
|
53
|
+
expect(
|
|
54
|
+
requiredShellWidthForSidebars({
|
|
55
|
+
mainSidebarOpen: false,
|
|
56
|
+
chatPanelOpen: true,
|
|
57
|
+
sidebarWidthPx: 300,
|
|
58
|
+
chatWidthPx: 337,
|
|
59
|
+
}),
|
|
60
|
+
).toBe(CENTRAL_AREA_MIN_PX + 337);
|
|
61
|
+
});
|
|
40
62
|
});
|
|
41
63
|
|
|
42
64
|
describe('shellFitsSidebarsLayout', () => {
|
|
@@ -62,6 +84,17 @@ describe('shellFitsSidebarsLayout', () => {
|
|
|
62
84
|
).toBe(false);
|
|
63
85
|
});
|
|
64
86
|
|
|
87
|
+
it('returns false when sub-min chat width would falsely fit at shell edge', () => {
|
|
88
|
+
expect(
|
|
89
|
+
shellFitsSidebarsLayout(1137, {
|
|
90
|
+
mainSidebarOpen: true,
|
|
91
|
+
chatPanelOpen: true,
|
|
92
|
+
sidebarWidthPx: 300,
|
|
93
|
+
chatWidthPx: 37,
|
|
94
|
+
}),
|
|
95
|
+
).toBe(false);
|
|
96
|
+
});
|
|
97
|
+
|
|
65
98
|
it('returns true for unknown shell width', () => {
|
|
66
99
|
expect(
|
|
67
100
|
shellFitsSidebarsLayout(0, {
|
package/src/hooks/panelWidth.ts
CHANGED
|
@@ -86,15 +86,40 @@ export type SidebarsLayoutWidths = {
|
|
|
86
86
|
chatWidthPx: number;
|
|
87
87
|
};
|
|
88
88
|
|
|
89
|
+
/**
|
|
90
|
+
* Stored width can fall below panel min when the shell was narrow (clamp cap < min).
|
|
91
|
+
* For dual-panel fit checks, treat open panels as at least their min width.
|
|
92
|
+
*/
|
|
93
|
+
function effectiveOpenPanelWidthPx(
|
|
94
|
+
px: number,
|
|
95
|
+
minPx: number,
|
|
96
|
+
bothPanelsOpen: boolean,
|
|
97
|
+
): number {
|
|
98
|
+
if (bothPanelsOpen) {
|
|
99
|
+
return Math.max(px, minPx);
|
|
100
|
+
}
|
|
101
|
+
return px > 0 ? px : minPx;
|
|
102
|
+
}
|
|
103
|
+
|
|
89
104
|
/** Minimum shell width when nav and/or chat panels are open (main column at least `CENTRAL_AREA_MIN_PX`). */
|
|
90
105
|
export function requiredShellWidthForSidebars(
|
|
91
106
|
widths: SidebarsLayoutWidths,
|
|
92
107
|
): number {
|
|
108
|
+
const bothPanelsOpen =
|
|
109
|
+
widths.mainSidebarOpen && widths.chatPanelOpen;
|
|
93
110
|
const sidebarW = widths.mainSidebarOpen
|
|
94
|
-
?
|
|
111
|
+
? effectiveOpenPanelWidthPx(
|
|
112
|
+
widths.sidebarWidthPx,
|
|
113
|
+
SIDEBAR_WIDTH_MIN_PX,
|
|
114
|
+
bothPanelsOpen,
|
|
115
|
+
)
|
|
95
116
|
: 0;
|
|
96
117
|
const chatW = widths.chatPanelOpen
|
|
97
|
-
?
|
|
118
|
+
? effectiveOpenPanelWidthPx(
|
|
119
|
+
widths.chatWidthPx,
|
|
120
|
+
CHAT_WIDTH_MIN_PX,
|
|
121
|
+
bothPanelsOpen,
|
|
122
|
+
)
|
|
98
123
|
: 0;
|
|
99
124
|
return sidebarW + CENTRAL_AREA_MIN_PX + chatW;
|
|
100
125
|
}
|