@nextclaw/ui 0.12.35-beta.2 → 0.12.35-beta.3

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.
Files changed (24) hide show
  1. package/CHANGELOG.md +64 -0
  2. package/dist/assets/{channels-list-page-CzDMCXR_.js → channels-list-page-DHmz9iHg.js} +1 -1
  3. package/dist/assets/{chat-page-Doi-sasO.js → chat-page-DOKLoiqI.js} +1 -1
  4. package/dist/assets/{desktop-update-config-Dd4DdPH3.js → desktop-update-config-ClbDsIOs.js} +1 -1
  5. package/dist/assets/doc-browser-ChY6hMn8.js +1 -0
  6. package/dist/assets/doc-browser-cR1vWRs1.js +1 -0
  7. package/dist/assets/{index-dHwM4pEn.js → index-DPz9DRZN.js} +4 -4
  8. package/dist/assets/{mcp-marketplace-page-n9Z25Cyk.js → mcp-marketplace-page-BYPxLdUR.js} +1 -1
  9. package/dist/assets/mcp-marketplace-page-DXCvk7wJ.js +1 -0
  10. package/dist/assets/{model-config-8BVoSVXQ.js → model-config-DcnC_fSr.js} +1 -1
  11. package/dist/assets/{providers-list-CjJmW-od.js → providers-list-BgvjRVmp.js} +1 -1
  12. package/dist/assets/remote-BCuZ1JJe.js +1 -0
  13. package/dist/assets/{runtime-config-page-Ba6atCMq.js → runtime-config-page-B2XPXHrk.js} +1 -1
  14. package/dist/assets/{search-config-BtCNY431.js → search-config-BFmG4_F7.js} +1 -1
  15. package/dist/assets/{secrets-config-Ddh05-J5.js → secrets-config-4uY5sk-V.js} +1 -1
  16. package/dist/index.html +2 -2
  17. package/package.json +9 -9
  18. package/src/shared/components/doc-browser/doc-browser-panel-parts.tsx +2 -2
  19. package/src/shared/components/doc-browser/doc-browser.test.tsx +82 -2
  20. package/src/shared/components/doc-browser/doc-browser.tsx +131 -134
  21. package/dist/assets/doc-browser-DInzGY0W.js +0 -1
  22. package/dist/assets/doc-browser-DxVvmYQk.js +0 -1
  23. package/dist/assets/mcp-marketplace-page-D-dydvbL.js +0 -1
  24. package/dist/assets/remote-DxTFnQm8.js +0 -1
@@ -1,4 +1,4 @@
1
- import { useState, useRef, useCallback, useEffect, type CSSProperties } from 'react';
1
+ import { useState, useRef, useCallback, useEffect } from 'react';
2
2
  import {
3
3
  DOCS_DEFAULT_BASE_URL,
4
4
  useDocBrowser,
@@ -20,30 +20,22 @@ type DocBrowserProps = {
20
20
  displayMode?: 'desktop' | 'fullscreen';
21
21
  };
22
22
 
23
- function getPanelClassName(isFullscreen: boolean): string {
24
- return cn(
25
- 'flex flex-col bg-white overflow-hidden relative',
26
- isFullscreen
27
- ? 'fixed inset-0 z-[9999] h-[100dvh] w-screen rounded-none border-0 shadow-2xl'
28
- : 'rounded-2xl shadow-2xl border border-gray-200',
29
- );
30
- }
23
+ type FloatingPanelRect = { x: number; y: number; w: number; h: number };
24
+ type FloatingPanelResizeEdge = 'left' | 'right' | 'top' | 'bottom' | 'bottom-right';
25
+ type FloatingPanelInteraction = {
26
+ kind: 'drag' | 'resize';
27
+ edge?: FloatingPanelResizeEdge;
28
+ startX: number;
29
+ startY: number;
30
+ startRect: FloatingPanelRect;
31
+ };
32
+
33
+ const FLOATING_PANEL_MARGIN = 40;
34
+ const FLOATING_PANEL_MIN_WIDTH = 360;
35
+ const FLOATING_PANEL_MIN_HEIGHT = 400;
31
36
 
32
- function getPanelStyle(params: {
33
- isFullscreen: boolean;
34
- floatPos: { x: number; y: number };
35
- floatSize: { w: number; h: number };
36
- }): CSSProperties | undefined {
37
- const { isFullscreen, floatPos, floatSize } = params;
38
- if (isFullscreen) return undefined;
39
- return {
40
- position: 'fixed',
41
- left: floatPos.x,
42
- top: floatPos.y,
43
- width: floatSize.w,
44
- height: floatSize.h,
45
- zIndex: 9999,
46
- };
37
+ function clamp(value: number, min: number, max: number): number {
38
+ return Math.min(max, Math.max(min, value));
47
39
  }
48
40
 
49
41
  export function DocBrowser({
@@ -68,16 +60,14 @@ export function DocBrowser({
68
60
  } = useDocBrowser();
69
61
 
70
62
  const [urlInput, setUrlInput] = useState('');
71
- const [isDragging, setIsDragging] = useState(false);
72
- const [isResizing, setIsResizing] = useState(false);
73
63
  const [iframeReloadVersion, setIframeReloadVersion] = useState(0);
74
- const [floatPos, setFloatPos] = useState(() => ({
75
- x: Math.max(40, window.innerWidth - 520),
64
+ const [floatRect, setFloatRect] = useState<FloatingPanelRect>(() => ({
65
+ x: Math.max(FLOATING_PANEL_MARGIN, window.innerWidth - 520),
76
66
  y: 80,
67
+ w: 480,
68
+ h: 600,
77
69
  }));
78
- const [floatSize, setFloatSize] = useState({ w: 480, h: 600 });
79
- const dragRef = useRef<{ startX: number; startY: number; startPosX: number; startPosY: number } | null>(null);
80
- const resizeRef = useRef<{ startX: number; startY: number; startW: number; startH: number } | null>(null);
70
+ const [floatInteraction, setFloatInteraction] = useState<FloatingPanelInteraction | null>(null);
81
71
  const iframeRef = useRef<HTMLIFrameElement>(null);
82
72
  const currentUrl = currentTab?.currentUrl ?? DOCS_DEFAULT_BASE_URL;
83
73
  const navVersion = currentTab?.navVersion ?? 0;
@@ -118,15 +108,6 @@ export function DocBrowser({
118
108
  }
119
109
  }, [currentUrl, navVersion, isDocsTab]);
120
110
 
121
- useEffect(() => {
122
- if (mode === 'floating') {
123
- setFloatPos((prev) => ({
124
- x: Math.max(40, window.innerWidth - floatSize.w - 40),
125
- y: prev.y,
126
- }));
127
- }
128
- }, [mode, floatSize.w]);
129
-
130
111
  useEffect(() => {
131
112
  const handler = (e: MessageEvent) => {
132
113
  if (!isDocsTab) {
@@ -140,6 +121,76 @@ export function DocBrowser({
140
121
  return () => window.removeEventListener('message', handler);
141
122
  }, [syncUrl, isDocsTab]);
142
123
 
124
+ const startFloatDrag = useCallback((event: React.PointerEvent<HTMLElement>) => {
125
+ event.preventDefault();
126
+ setFloatInteraction({
127
+ kind: 'drag',
128
+ startX: event.clientX,
129
+ startY: event.clientY,
130
+ startRect: floatRect,
131
+ });
132
+ }, [floatRect]);
133
+
134
+ const startFloatResize = useCallback((edge: FloatingPanelResizeEdge) => (event: React.PointerEvent<HTMLElement>) => {
135
+ event.preventDefault();
136
+ event.stopPropagation();
137
+ setFloatInteraction({
138
+ kind: 'resize',
139
+ edge,
140
+ startX: event.clientX,
141
+ startY: event.clientY,
142
+ startRect: floatRect,
143
+ });
144
+ }, [floatRect]);
145
+
146
+ useEffect(() => {
147
+ if (!floatInteraction) return;
148
+
149
+ const onMove = (event: PointerEvent) => {
150
+ const { startRect, startX, startY } = floatInteraction;
151
+ const dx = event.clientX - startX;
152
+ const dy = event.clientY - startY;
153
+
154
+ if (floatInteraction.kind === 'drag') {
155
+ setFloatRect({
156
+ ...startRect,
157
+ x: clamp(startRect.x + dx, FLOATING_PANEL_MARGIN, window.innerWidth - FLOATING_PANEL_MARGIN - startRect.w),
158
+ y: clamp(startRect.y + dy, FLOATING_PANEL_MARGIN, window.innerHeight - FLOATING_PANEL_MARGIN - startRect.h),
159
+ });
160
+ return;
161
+ }
162
+
163
+ if (floatInteraction.edge === 'left' || floatInteraction.edge === 'top') {
164
+ const isLeftEdge = floatInteraction.edge === 'left';
165
+ const fixedEdge = isLeftEdge ? startRect.x + startRect.w : startRect.y + startRect.h;
166
+ const movingEdge = isLeftEdge ? startRect.x + dx : startRect.y + dy;
167
+ const minSize = isLeftEdge ? FLOATING_PANEL_MIN_WIDTH : FLOATING_PANEL_MIN_HEIGHT;
168
+ const nextEdge = clamp(movingEdge, FLOATING_PANEL_MARGIN, fixedEdge - minSize);
169
+ setFloatRect(isLeftEdge ? { ...startRect, x: nextEdge, w: fixedEdge - nextEdge } : { ...startRect, y: nextEdge, h: fixedEdge - nextEdge });
170
+ return;
171
+ }
172
+
173
+ const right = clamp(startRect.x + startRect.w + dx, startRect.x + FLOATING_PANEL_MIN_WIDTH, window.innerWidth - FLOATING_PANEL_MARGIN);
174
+ const bottom = clamp(startRect.y + startRect.h + dy, startRect.y + FLOATING_PANEL_MIN_HEIGHT, window.innerHeight - FLOATING_PANEL_MARGIN);
175
+ setFloatRect({
176
+ ...startRect,
177
+ w: floatInteraction.edge === 'bottom' ? startRect.w : right - startRect.x,
178
+ h: floatInteraction.edge === 'right' ? startRect.h : bottom - startRect.y,
179
+ });
180
+ };
181
+
182
+ const onEnd = () => setFloatInteraction(null);
183
+
184
+ window.addEventListener('pointermove', onMove);
185
+ window.addEventListener('pointerup', onEnd);
186
+ window.addEventListener('pointercancel', onEnd);
187
+ return () => {
188
+ window.removeEventListener('pointermove', onMove);
189
+ window.removeEventListener('pointerup', onEnd);
190
+ window.removeEventListener('pointercancel', onEnd);
191
+ };
192
+ }, [floatInteraction]);
193
+
143
194
  const handleUrlSubmit = useCallback((e: React.FormEvent) => {
144
195
  e.preventDefault();
145
196
  if (!isDocsTab) return;
@@ -154,88 +205,6 @@ export function DocBrowser({
154
205
  }
155
206
  }, [urlInput, navigate, isDocsTab]);
156
207
 
157
- const onDragStart = useCallback((e: React.MouseEvent) => {
158
- if (mode !== 'floating') return;
159
- setIsDragging(true);
160
- dragRef.current = {
161
- startX: e.clientX,
162
- startY: e.clientY,
163
- startPosX: floatPos.x,
164
- startPosY: floatPos.y,
165
- };
166
- }, [mode, floatPos]);
167
-
168
- useEffect(() => {
169
- if (!isDragging) return;
170
- const onMove = (e: MouseEvent) => {
171
- if (!dragRef.current) return;
172
- setFloatPos({
173
- x: dragRef.current.startPosX + (e.clientX - dragRef.current.startX),
174
- y: dragRef.current.startPosY + (e.clientY - dragRef.current.startY),
175
- });
176
- };
177
- const onUp = () => {
178
- setIsDragging(false);
179
- dragRef.current = null;
180
- };
181
- window.addEventListener('mousemove', onMove);
182
- window.addEventListener('mouseup', onUp);
183
- return () => {
184
- window.removeEventListener('mousemove', onMove);
185
- window.removeEventListener('mouseup', onUp);
186
- };
187
- }, [isDragging]);
188
-
189
- const onResizeStart = useCallback((e: React.MouseEvent) => {
190
- e.preventDefault();
191
- e.stopPropagation();
192
- setIsResizing(true);
193
- const { axis } = (e.currentTarget as HTMLElement).dataset;
194
- resizeRef.current = {
195
- startX: e.clientX,
196
- startY: e.clientY,
197
- startW: floatSize.w,
198
- startH: floatSize.h,
199
- };
200
- const onMove = (ev: MouseEvent) => {
201
- if (!resizeRef.current) return;
202
- setFloatSize((prev) => ({
203
- w: axis === 'y' ? prev.w : Math.max(360, resizeRef.current!.startW + (ev.clientX - resizeRef.current!.startX)),
204
- h: axis === 'x' ? prev.h : Math.max(400, resizeRef.current!.startH + (ev.clientY - resizeRef.current!.startY)),
205
- }));
206
- };
207
- const onUp = () => {
208
- setIsResizing(false);
209
- resizeRef.current = null;
210
- window.removeEventListener('mousemove', onMove);
211
- window.removeEventListener('mouseup', onUp);
212
- };
213
- window.addEventListener('mousemove', onMove);
214
- window.addEventListener('mouseup', onUp);
215
- }, [floatSize]);
216
-
217
- const onLeftResizeStart = useCallback((e: React.MouseEvent) => {
218
- e.preventDefault();
219
- e.stopPropagation();
220
- setIsResizing(true);
221
- const startX = e.clientX;
222
- const startW = floatSize.w;
223
- const startPosX = floatPos.x;
224
- const onMove = (ev: MouseEvent) => {
225
- const delta = startX - ev.clientX;
226
- const newW = Math.max(360, startW + delta);
227
- setFloatSize((prev) => ({ ...prev, w: newW }));
228
- setFloatPos((prev) => ({ ...prev, x: startPosX - (newW - startW) }));
229
- };
230
- const onUp = () => {
231
- setIsResizing(false);
232
- window.removeEventListener('mousemove', onMove);
233
- window.removeEventListener('mouseup', onUp);
234
- };
235
- window.addEventListener('mousemove', onMove);
236
- window.addEventListener('mouseup', onUp);
237
- }, [floatSize.w, floatPos.x]);
238
-
239
208
  const refreshIframe = useCallback(() => {
240
209
  setIframeReloadVersion((version) => version + 1);
241
210
  }, []);
@@ -265,7 +234,7 @@ export function DocBrowser({
265
234
  isDocked={isDocked}
266
235
  isFullscreen={isFullscreen}
267
236
  onClose={close}
268
- onDragStart={onDragStart}
237
+ onDragStart={startFloatDrag}
269
238
  onToggleMode={toggleMode}
270
239
  />
271
240
 
@@ -297,8 +266,8 @@ export function DocBrowser({
297
266
  iframeRef={iframeRef}
298
267
  iframeReloadVersion={iframeReloadVersion}
299
268
  iframeSandbox={iframeSandbox}
300
- isDragging={isDragging}
301
- isResizing={isResizing}
269
+ isDragging={floatInteraction?.kind === 'drag'}
270
+ isResizing={floatInteraction?.kind === 'resize'}
302
271
  navVersion={navVersion}
303
272
  />
304
273
 
@@ -319,22 +288,52 @@ export function DocBrowser({
319
288
  );
320
289
  }
321
290
 
322
- const panel = (
291
+ return (
323
292
  <div
324
293
  data-testid="doc-browser-panel"
325
- className={getPanelClassName(isFullscreen)}
326
- style={getPanelStyle({ isFullscreen, floatPos, floatSize })}
294
+ className={cn(
295
+ 'flex flex-col bg-white overflow-hidden relative',
296
+ isFullscreen
297
+ ? 'fixed inset-0 z-[9999] h-[100dvh] w-screen rounded-none border-0 shadow-2xl'
298
+ : 'rounded-2xl shadow-2xl border border-gray-200',
299
+ )}
300
+ style={
301
+ isFullscreen
302
+ ? undefined
303
+ : {
304
+ position: 'fixed',
305
+ left: floatRect.x,
306
+ top: floatRect.y,
307
+ width: floatRect.w,
308
+ height: floatRect.h,
309
+ zIndex: 9999,
310
+ }
311
+ }
327
312
  >
328
313
  {panelContent}
329
314
 
330
315
  {!isDocked && !isFullscreen && (
331
316
  <>
332
- <div className="absolute top-0 left-0 w-1.5 h-full cursor-ew-resize z-20 hover:bg-primary/10 transition-colors" onMouseDown={onLeftResizeStart} />
333
- <div className="absolute top-0 right-0 w-1.5 h-full cursor-ew-resize z-20 hover:bg-primary/10 transition-colors" onMouseDown={onResizeStart} data-axis="x" />
334
- <div className="absolute bottom-0 left-0 h-1.5 w-full cursor-ns-resize z-20 hover:bg-primary/10 transition-colors" onMouseDown={onResizeStart} data-axis="y" />
317
+ <div className="absolute top-0 left-0 h-1.5 w-full cursor-ns-resize z-20 hover:bg-primary/10 transition-colors" data-testid="doc-browser-resize-top" onPointerDown={startFloatResize('top')} />
318
+ <div
319
+ className="absolute top-0 left-0 w-1.5 h-full cursor-ew-resize z-20 hover:bg-primary/10 transition-colors"
320
+ data-testid="doc-browser-resize-left"
321
+ onPointerDown={startFloatResize('left')}
322
+ />
323
+ <div
324
+ className="absolute top-0 right-0 w-1.5 h-full cursor-ew-resize z-20 hover:bg-primary/10 transition-colors"
325
+ data-testid="doc-browser-resize-right"
326
+ onPointerDown={startFloatResize('right')}
327
+ />
328
+ <div
329
+ className="absolute bottom-0 left-0 h-1.5 w-full cursor-ns-resize z-20 hover:bg-primary/10 transition-colors"
330
+ data-testid="doc-browser-resize-bottom"
331
+ onPointerDown={startFloatResize('bottom')}
332
+ />
335
333
  <div
336
334
  className="absolute bottom-0 right-0 w-4 h-4 cursor-se-resize z-30 flex items-center justify-center text-gray-300 hover:text-gray-500 transition-colors"
337
- onMouseDown={onResizeStart}
335
+ data-testid="doc-browser-resize-bottom-right"
336
+ onPointerDown={startFloatResize('bottom-right')}
338
337
  >
339
338
  <GripVertical className="w-3 h-3 rotate-[-45deg]" />
340
339
  </div>
@@ -342,6 +341,4 @@ export function DocBrowser({
342
341
  )}
343
342
  </div>
344
343
  );
345
-
346
- return panel;
347
344
  }
@@ -1 +0,0 @@
1
- import{t as e}from"./doc-browser-DxVvmYQk.js";export{e as DocBrowser};
@@ -1 +0,0 @@
1
- import{_ as e,m as t,p as n,r,u as i}from"./i18n-tWKGEGxB.js";import{t as a}from"./createLucideIcon-Cwr2o6Zq.js";import{n as o,t as s}from"./search-Czito3Dk.js";import{t as c}from"./book-open--T9dJHnp.js";import{t as l}from"./external-link-CZ9bQY0L.js";import{t as u}from"./plus-BqfNq7Tu.js";import{t as d}from"./x-DBP3WiC9.js";import{i as f,r as p,t as m}from"./doc-browser-context-CLczyX2Z.js";var h=a(`ArrowRight`,[[`path`,{d:`M5 12h14`,key:`1ays0h`}],[`path`,{d:`m12 5 7 7-7 7`,key:`xquz4c`}]]),g=a(`GripVertical`,[[`circle`,{cx:`9`,cy:`12`,r:`1`,key:`1vctgf`}],[`circle`,{cx:`9`,cy:`5`,r:`1`,key:`hp0tcf`}],[`circle`,{cx:`9`,cy:`19`,r:`1`,key:`fkjjf6`}],[`circle`,{cx:`15`,cy:`12`,r:`1`,key:`1tmaij`}],[`circle`,{cx:`15`,cy:`5`,r:`1`,key:`19l28e`}],[`circle`,{cx:`15`,cy:`19`,r:`1`,key:`f4zoj3`}]]),_=a(`Maximize2`,[[`polyline`,{points:`15 3 21 3 21 9`,key:`mznyad`}],[`polyline`,{points:`9 21 3 21 3 15`,key:`1avn1i`}],[`line`,{x1:`21`,x2:`14`,y1:`3`,y2:`10`,key:`ota7mn`}],[`line`,{x1:`3`,x2:`10`,y1:`21`,y2:`14`,key:`1atl0r`}]]),v=a(`PanelRightOpen`,[[`rect`,{width:`18`,height:`18`,x:`3`,y:`3`,rx:`2`,key:`afitv7`}],[`path`,{d:`M15 3v18`,key:`14nvp0`}],[`path`,{d:`m10 15-3-3 3-3`,key:`1pgupc`}]]),y=n();function b({currentTab:e,customRenderer:t,isDocked:n,isFullscreen:a,onClose:o,onDragStart:s,onToggleMode:l}){let u=e&&t?.getTitle?t.getTitle(e):r(`docBrowserTitle`),f=e&&t?.renderIcon?t.renderIcon(e):(0,y.jsx)(c,{className:`w-4 h-4 text-primary shrink-0`});return(0,y.jsxs)(`div`,{className:i(`flex items-center justify-between px-4 py-2.5 bg-gray-50 border-b border-gray-200 shrink-0 select-none`,!n&&!a&&`cursor-grab active:cursor-grabbing`,a&&`pt-[calc(env(safe-area-inset-top,0px)+0.625rem)]`),onMouseDown:!n&&!a?s:void 0,children:[(0,y.jsxs)(`div`,{className:`flex items-center gap-2.5 min-w-0`,children:[f,(0,y.jsx)(`span`,{className:`text-sm font-semibold text-gray-900 truncate`,children:u})]}),(0,y.jsxs)(`div`,{className:`flex items-center gap-1`,children:[a?null:(0,y.jsx)(`button`,{onClick:l,className:`hover:bg-gray-200 rounded-md p-1.5 text-gray-500 hover:text-gray-700 transition-colors`,title:r(n?`docBrowserFloatMode`:`docBrowserDockMode`),children:n?(0,y.jsx)(_,{className:`w-3.5 h-3.5`}):(0,y.jsx)(v,{className:`w-3.5 h-3.5`})}),(0,y.jsx)(`button`,{onClick:o,className:`hover:bg-gray-200 rounded-md p-1.5 text-gray-500 hover:text-gray-700 transition-colors`,title:r(`docBrowserClose`),children:(0,y.jsx)(d,{className:`w-3.5 h-3.5`})})]})]})}function ee({currentTab:e,isDocsTab:t,onBack:n,onForward:i,onSubmit:a,onUrlInputChange:c,urlInput:l}){return t?(0,y.jsxs)(`div`,{className:`flex items-center gap-2 px-3.5 py-2 bg-white border-b border-gray-100 shrink-0`,children:[(0,y.jsx)(`button`,{onClick:n,disabled:!t||(e?.historyIndex??0)<=0,className:`p-1.5 rounded-md hover:bg-gray-100 disabled:opacity-30 disabled:cursor-not-allowed text-gray-600 transition-colors`,children:(0,y.jsx)(o,{className:`w-4 h-4`})}),(0,y.jsx)(`button`,{onClick:i,disabled:!t||(e?.historyIndex??0)>=(e?.history.length??0)-1,className:`p-1.5 rounded-md hover:bg-gray-100 disabled:opacity-30 disabled:cursor-not-allowed text-gray-600 transition-colors`,children:(0,y.jsx)(h,{className:`w-4 h-4`})}),(0,y.jsxs)(`form`,{onSubmit:a,className:`flex-1 relative`,children:[(0,y.jsx)(s,{className:`w-3.5 h-3.5 absolute left-3 top-1/2 -translate-y-1/2 text-gray-400`}),(0,y.jsx)(`input`,{type:`text`,value:l,onChange:e=>c(e.target.value),placeholder:r(`docBrowserSearchPlaceholder`),className:`w-full h-8 pl-8 pr-3 rounded-lg bg-gray-50 border border-gray-200 text-xs text-gray-700 focus:outline-none focus:ring-1 focus:ring-primary/30 focus:border-primary/40 transition-colors placeholder:text-gray-400`})]})]}):null}function te({activeTabId:e,currentTab:t,currentUrl:n,customContent:r,iframeRef:i,iframeReloadVersion:a,iframeSandbox:o,isDragging:s,isResizing:c,navVersion:l}){return(0,y.jsxs)(`div`,{className:`flex-1 relative overflow-hidden`,children:[r||(0,y.jsx)(`iframe`,{ref:i,src:n,className:`absolute inset-0 w-full h-full border-0`,title:t?.title||`NextClaw Docs`,sandbox:o,allow:`clipboard-read; clipboard-write`},`${e}:${l}:${a}`),(c||s)&&(0,y.jsx)(`div`,{className:`absolute inset-0 z-10`})]})}function ne({currentUrl:e,isDocsTab:t}){return!t||!p(e)?null:(0,y.jsx)(`div`,{className:`flex items-center justify-between px-4 py-2 bg-gray-50 border-t border-gray-200 shrink-0`,children:(0,y.jsxs)(`a`,{href:e,target:`_blank`,rel:`noopener noreferrer`,"data-doc-external":!0,className:`flex items-center gap-1.5 text-xs text-primary hover:text-primary-hover font-medium transition-colors`,children:[r(`docBrowserOpenExternal`),(0,y.jsx)(l,{className:`w-3 h-3`})]})})}function re({tabs:e,activeTabId:t,onOpenDocs:n,onSetActiveTab:a,onCloseTab:o}){return(0,y.jsxs)(`div`,{className:`flex items-center gap-1.5 px-2.5 py-2 bg-background border-b border-[#f1e7d4] overflow-x-auto custom-scrollbar`,children:[e.map(e=>(0,y.jsxs)(`div`,{className:i(`inline-flex items-center gap-1 h-7 px-1.5 rounded-lg text-xs border max-w-[220px] shrink-0 transition-colors`,e.id===t?`bg-amber-50/80 border-amber-200 text-amber-900 shadow-[0_1px_2px_rgba(30,20,10,0.04)]`:`bg-[#f9f8f5] border-[#eee3d1] text-[#78644d] hover:bg-[#fff7ea] hover:text-[#2f2212]`),children:[(0,y.jsx)(`button`,{type:`button`,onClick:()=>a(e.id),className:`truncate text-left px-1`,title:e.title,children:e.title||r(`docBrowserTabUntitled`)}),(0,y.jsx)(`button`,{type:`button`,onClick:t=>{t.stopPropagation(),o(e.id)},className:`rounded p-0.5 hover:bg-black/10`,"aria-label":r(`docBrowserCloseTab`),children:(0,y.jsx)(d,{className:`w-3 h-3`})})]},e.id)),(0,y.jsx)(`button`,{type:`button`,onClick:n,className:`inline-flex items-center justify-center w-7 h-7 rounded-lg border border-[#eee3d1] bg-white text-[#78644d] hover:bg-[#fff7ea] hover:text-[#2f2212] shrink-0`,title:r(`docBrowserNewTab`),children:(0,y.jsx)(u,{className:`w-3.5 h-3.5`})})]})}var x=e(t(),1);function S({children:e,className:t,style:n,defaultWidth:r=420,minWidth:a=320,maxWidth:o=860,overlay:s=!1,...c}){let l=(0,x.useRef)(null),[u,d]=(0,x.useState)(!1),[f,p]=(0,x.useState)(r),m=e=>{if(s)return;e.preventDefault(),e.stopPropagation(),d(!0),l.current={startX:e.clientX,startWidth:f};let t=e=>{let t=l.current;if(!t)return;let n=t.startWidth+t.startX-e.clientX;p(Math.max(a,Math.min(o,n)))},n=()=>{d(!1),l.current=null,window.removeEventListener(`mousemove`,t),window.removeEventListener(`mouseup`,n)};window.addEventListener(`mousemove`,t),window.addEventListener(`mouseup`,n)};return(0,y.jsxs)(`aside`,{...c,className:i(`relative flex h-full min-h-0 shrink-0 overflow-hidden bg-white`,s?`fixed inset-0 z-40`:`border-l border-gray-200`,t),style:s?n:{...n,width:f},children:[s?null:(0,y.jsx)(`div`,{className:`absolute left-0 top-0 z-20 h-full w-1.5 cursor-ew-resize transition-colors hover:bg-primary/10`,"data-testid":`resizable-right-panel-handle`,onMouseDown:m}),(0,y.jsx)(`div`,{className:`flex h-full min-h-0 w-full flex-col overflow-hidden`,children:e}),u?(0,y.jsx)(`div`,{className:`absolute inset-0 z-10`}):null]})}function C(e){return i(`flex flex-col bg-white overflow-hidden relative`,e?`fixed inset-0 z-[9999] h-[100dvh] w-screen rounded-none border-0 shadow-2xl`:`rounded-2xl shadow-2xl border border-gray-200`)}function w(e){let{isFullscreen:t,floatPos:n,floatSize:r}=e;if(!t)return{position:`fixed`,left:n.x,top:n.y,width:r.w,height:r.h,zIndex:9999}}function T({customTabRenderers:e={},displayMode:t=`desktop`}){let{isOpen:n,mode:r,tabs:i,activeTabId:a,currentTab:o,open:s,close:c,toggleMode:l,goBack:u,goForward:d,navigate:p,syncUrl:h,setActiveTab:_,closeTab:v}=f(),[T,E]=(0,x.useState)(``),[D,O]=(0,x.useState)(!1),[k,A]=(0,x.useState)(!1),[j,M]=(0,x.useState)(0),[N,P]=(0,x.useState)(()=>({x:Math.max(40,window.innerWidth-520),y:80})),[F,I]=(0,x.useState)({w:480,h:600}),L=(0,x.useRef)(null),R=(0,x.useRef)(null),z=(0,x.useRef)(null),B=o?.currentUrl??m,V=o?.navVersion??0,H=(0,x.useRef)(V),U=o?.kind===`docs`;(0,x.useEffect)(()=>{if(!U){E(``);return}try{E(new URL(B).pathname)}catch{E(B)}},[B,a,U]),(0,x.useEffect)(()=>{if(U){if(V!==H.current){H.current=V;return}if(z.current?.contentWindow)try{let e=new URL(B).pathname;z.current.contentWindow.postMessage({type:`docs-navigate`,path:e},`*`)}catch{}}},[B,V,U]),(0,x.useEffect)(()=>{r===`floating`&&P(e=>({x:Math.max(40,window.innerWidth-F.w-40),y:e.y}))},[r,F.w]),(0,x.useEffect)(()=>{let e=e=>{U&&e.data?.type===`docs-route-change`&&typeof e.data.url==`string`&&h(e.data.url)};return window.addEventListener(`message`,e),()=>window.removeEventListener(`message`,e)},[h,U]);let W=(0,x.useCallback)(e=>{if(e.preventDefault(),!U)return;let t=T.trim();t&&(t.startsWith(`/`)?p(`${m}${t}`):t.startsWith(`http`)?p(t):p(`${m}/${t}`))},[T,p,U]),G=(0,x.useCallback)(e=>{r===`floating`&&(O(!0),L.current={startX:e.clientX,startY:e.clientY,startPosX:N.x,startPosY:N.y})},[r,N]);(0,x.useEffect)(()=>{if(!D)return;let e=e=>{L.current&&P({x:L.current.startPosX+(e.clientX-L.current.startX),y:L.current.startPosY+(e.clientY-L.current.startY)})},t=()=>{O(!1),L.current=null};return window.addEventListener(`mousemove`,e),window.addEventListener(`mouseup`,t),()=>{window.removeEventListener(`mousemove`,e),window.removeEventListener(`mouseup`,t)}},[D]);let K=(0,x.useCallback)(e=>{e.preventDefault(),e.stopPropagation(),A(!0);let{axis:t}=e.currentTarget.dataset;R.current={startX:e.clientX,startY:e.clientY,startW:F.w,startH:F.h};let n=e=>{R.current&&I(n=>({w:t===`y`?n.w:Math.max(360,R.current.startW+(e.clientX-R.current.startX)),h:t===`x`?n.h:Math.max(400,R.current.startH+(e.clientY-R.current.startY))}))},r=()=>{A(!1),R.current=null,window.removeEventListener(`mousemove`,n),window.removeEventListener(`mouseup`,r)};window.addEventListener(`mousemove`,n),window.addEventListener(`mouseup`,r)},[F]),q=(0,x.useCallback)(e=>{e.preventDefault(),e.stopPropagation(),A(!0);let t=e.clientX,n=F.w,r=N.x,i=e=>{let i=t-e.clientX,a=Math.max(360,n+i);I(e=>({...e,w:a})),P(e=>({...e,x:r-(a-n)}))},a=()=>{A(!1),window.removeEventListener(`mousemove`,i),window.removeEventListener(`mouseup`,a)};window.addEventListener(`mousemove`,i),window.addEventListener(`mouseup`,a)},[F.w,N.x]),J=(0,x.useCallback)(()=>{M(e=>e+1)},[]);if(!n)return null;let Y=r===`docked`,X=t===`fullscreen`,Z=o?e[o.kind]:void 0,Q=o?{currentUrl:B,open:s,refreshIframe:J,tab:o}:void 0,ie=Q?Z?.renderToolbar?.(Q):null,ae=Q?Z?.renderContent?.(Q):null,oe=o?Z?.getIframeSandbox?.(o)??`allow-same-origin allow-scripts allow-popups allow-forms`:`allow-same-origin allow-scripts allow-popups allow-forms`,$=(0,y.jsxs)(y.Fragment,{children:[(0,y.jsx)(b,{currentTab:o,customRenderer:Z,isDocked:Y,isFullscreen:X,onClose:c,onDragStart:G,onToggleMode:l}),(0,y.jsx)(re,{tabs:i,activeTabId:a,onOpenDocs:()=>s(void 0,{kind:`docs`,newTab:!0,title:`Docs`}),onSetActiveTab:_,onCloseTab:v}),(0,y.jsx)(ee,{currentTab:o,isDocsTab:U,onBack:u,onForward:d,onSubmit:W,onUrlInputChange:E,urlInput:T}),ie,(0,y.jsx)(te,{activeTabId:a,currentTab:o,currentUrl:B,customContent:ae,iframeRef:z,iframeReloadVersion:j,iframeSandbox:oe,isDragging:D,isResizing:k,navVersion:V}),(0,y.jsx)(ne,{currentUrl:B,isDocsTab:U})]});return Y&&!X?(0,y.jsx)(S,{"data-testid":`doc-browser-panel`,defaultWidth:420,minWidth:320,maxWidth:860,children:$}):(0,y.jsxs)(`div`,{"data-testid":`doc-browser-panel`,className:C(X),style:w({isFullscreen:X,floatPos:N,floatSize:F}),children:[$,!Y&&!X&&(0,y.jsxs)(y.Fragment,{children:[(0,y.jsx)(`div`,{className:`absolute top-0 left-0 w-1.5 h-full cursor-ew-resize z-20 hover:bg-primary/10 transition-colors`,onMouseDown:q}),(0,y.jsx)(`div`,{className:`absolute top-0 right-0 w-1.5 h-full cursor-ew-resize z-20 hover:bg-primary/10 transition-colors`,onMouseDown:K,"data-axis":`x`}),(0,y.jsx)(`div`,{className:`absolute bottom-0 left-0 h-1.5 w-full cursor-ns-resize z-20 hover:bg-primary/10 transition-colors`,onMouseDown:K,"data-axis":`y`}),(0,y.jsx)(`div`,{className:`absolute bottom-0 right-0 w-4 h-4 cursor-se-resize z-30 flex items-center justify-center text-gray-300 hover:text-gray-500 transition-colors`,onMouseDown:K,children:(0,y.jsx)(g,{className:`w-3 h-3 rotate-[-45deg]`})})]})]})}export{S as n,T as t};
@@ -1 +0,0 @@
1
- import{t as e}from"./mcp-marketplace-page-n9Z25Cyk.js";export{e as McpMarketplacePage};
@@ -1 +0,0 @@
1
- import{Rt as e}from"./index-dHwM4pEn.js";export{e as RemoteAccessPage};