@ai-matrx/canvas 0.7.3 → 0.8.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/CHANGELOG.md +20 -0
- package/README.md +2 -2
- package/dist/react.cjs +141 -49
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +34 -15
- package/dist/react.d.ts +34 -15
- package/dist/react.js +141 -49
- package/dist/react.js.map +1 -1
- package/dist/styles.css +97 -39
- package/package.json +1 -1
package/dist/react.d.cts
CHANGED
|
@@ -381,26 +381,45 @@ declare function CanvasFrame({ children, className }: {
|
|
|
381
381
|
declare function useCanvasPresentation(): CanvasPresentation | null;
|
|
382
382
|
|
|
383
383
|
declare function itemTitle(item: CanvasItem, kind: AnyCanvasKind | undefined): string;
|
|
384
|
+
/** One tab of a strip and the pane it lives in (a window-wide strip shows every pane's tabs). */
|
|
385
|
+
interface CanvasStripTab {
|
|
386
|
+
readonly itemId: CanvasItemId;
|
|
387
|
+
readonly paneId: CanvasPaneId;
|
|
388
|
+
/** Its index inside its own pane (where a tab dropped on it lands). */
|
|
389
|
+
readonly index: number;
|
|
390
|
+
}
|
|
384
391
|
declare function CanvasPaneView({ paneId }: {
|
|
385
392
|
paneId: CanvasPaneId;
|
|
386
393
|
}): react.JSX.Element | null;
|
|
387
|
-
/** A background tab's floor (px): icon + ~7 letters + "…" ("Messag…"). Mirrored to CSS as --mxc-tab-min. */
|
|
388
|
-
declare const CANVAS_TAB_MIN_WIDTH = 88;
|
|
389
|
-
/** The active tab's floor (px): icon + ~8 letters + "…" + its close. Mirrored to CSS as --mxc-tab-active-min. */
|
|
390
|
-
declare const CANVAS_ACTIVE_TAB_MIN_WIDTH = 112;
|
|
391
394
|
/**
|
|
392
|
-
*
|
|
393
|
-
*
|
|
394
|
-
*
|
|
395
|
-
* rule is testable without a layout engine. `width <= 0` (not measured yet)
|
|
396
|
-
* shows everything.
|
|
395
|
+
* Every tab's floor (px): icon + ~10 letters + "…" — still readable. Tabs shrink
|
|
396
|
+
* evenly from 12rem down to this; past it the strip scrolls. Mirrored to CSS as
|
|
397
|
+
* --mxc-tab-min.
|
|
397
398
|
*/
|
|
398
|
-
declare
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
399
|
+
declare const CANVAS_TAB_MIN_WIDTH = 120;
|
|
400
|
+
/** True when `count` tabs at their floor do not fit `width` px: the strip scrolls and offers "All tabs". */
|
|
401
|
+
declare function canvasTabsOverflow(count: number, width: number): boolean;
|
|
402
|
+
/** One entry of a strip: a tab, or a split's visible tabs drawn as ONE joined tab (Chrome split view). */
|
|
403
|
+
type CanvasStripEntry = {
|
|
404
|
+
readonly type: "tab";
|
|
405
|
+
readonly tab: CanvasStripTab;
|
|
406
|
+
} | {
|
|
407
|
+
readonly type: "split";
|
|
408
|
+
readonly tabs: readonly CanvasStripTab[];
|
|
403
409
|
};
|
|
410
|
+
/**
|
|
411
|
+
* The strip's entries. With `actives` (each pane's active item) for two or more
|
|
412
|
+
* panes, those tabs become one joined entry, placed where the first of them
|
|
413
|
+
* stands; every other tab keeps its place. Pure, so the rule is testable.
|
|
414
|
+
*/
|
|
415
|
+
declare function planCanvasTabStrip(tabs: readonly CanvasStripTab[], actives?: ReadonlyMap<CanvasPaneId, CanvasItemId> | null): CanvasStripEntry[];
|
|
416
|
+
/**
|
|
417
|
+
* THE window-wide tab strip of a split canvas (Chrome split view): every
|
|
418
|
+
* pane's tabs in one row above the panes, the panes' visible tabs drawn as
|
|
419
|
+
* one joined tab, "+" opening in the focused pane. A split never halves the
|
|
420
|
+
* strip into one per pane.
|
|
421
|
+
*/
|
|
422
|
+
declare function CanvasWindowTabs(): react.JSX.Element;
|
|
404
423
|
|
|
405
424
|
/**
|
|
406
425
|
* One resize gesture (the canvas edge, a split handle). While it runs:
|
|
@@ -512,4 +531,4 @@ interface BrowserBarProps {
|
|
|
512
531
|
/** A browser's back · forward · reload · address bar, for a kind's leading slot or its body. */
|
|
513
532
|
declare function BrowserBar({ url, canGoBack, canGoForward, onBack, onForward, onReload, onNavigate, trailing, className }: BrowserBarProps): react.JSX.Element;
|
|
514
533
|
|
|
515
|
-
export { type AnyCanvasKind, BrowserBar, type BrowserBarProps, type BrowserTab, BrowserTabs, type BrowserTabsProps,
|
|
534
|
+
export { type AnyCanvasKind, BrowserBar, type BrowserBarProps, type BrowserTab, BrowserTabs, type BrowserTabsProps, CANVAS_TAB_MIN_WIDTH, CanvasColumn, type CanvasColumnProps, type CanvasFloating, CanvasFrame, CanvasHeaderButton, type CanvasHeaderButtonProps, type CanvasHostPorts, type CanvasKind, type CanvasKindIcon, CanvasKindIcons, type CanvasKindProps, type CanvasLauncherEntry, type CanvasMenuEntry, type CanvasMenuItem, CanvasMenuTrigger, type CanvasNativeBodyFrame, type CanvasNativeBodyInfo, type CanvasNativeRect, type CanvasOverlayPort, CanvasPaneView, CanvasPanel, CanvasPanelEmpty, type CanvasPanelProps, CanvasProvider, type CanvasProviderProps, type CanvasShowMenu, type CanvasStripEntry, type CanvasStripTab, CanvasTab, type CanvasTabProps, type CanvasTabStripMode, CanvasToggle, CanvasWindowScope, CanvasWindowTabs, beginCanvasResize, canvasSessionKey, canvasTabsOverflow, defineCanvasKind, getCanvasKind, itemTitle, listCanvasKinds, planCanvasTabStrip, registerCanvasKind, registerCanvasKinds, useCanvas, useCanvasColumnWidth, useCanvasHostPorts, useCanvasIsPresented, useCanvasKind, useCanvasKindToggle, useCanvasKinds, useCanvasLauncherEntries, useCanvasLauncherEntry, useCanvasMenuItems, useCanvasNativeBodies, useCanvasPresentation, useCanvasState, useCanvasWindowId, useOptionalCanvas, useOptionalCanvasState };
|
package/dist/react.d.ts
CHANGED
|
@@ -381,26 +381,45 @@ declare function CanvasFrame({ children, className }: {
|
|
|
381
381
|
declare function useCanvasPresentation(): CanvasPresentation | null;
|
|
382
382
|
|
|
383
383
|
declare function itemTitle(item: CanvasItem, kind: AnyCanvasKind | undefined): string;
|
|
384
|
+
/** One tab of a strip and the pane it lives in (a window-wide strip shows every pane's tabs). */
|
|
385
|
+
interface CanvasStripTab {
|
|
386
|
+
readonly itemId: CanvasItemId;
|
|
387
|
+
readonly paneId: CanvasPaneId;
|
|
388
|
+
/** Its index inside its own pane (where a tab dropped on it lands). */
|
|
389
|
+
readonly index: number;
|
|
390
|
+
}
|
|
384
391
|
declare function CanvasPaneView({ paneId }: {
|
|
385
392
|
paneId: CanvasPaneId;
|
|
386
393
|
}): react.JSX.Element | null;
|
|
387
|
-
/** A background tab's floor (px): icon + ~7 letters + "…" ("Messag…"). Mirrored to CSS as --mxc-tab-min. */
|
|
388
|
-
declare const CANVAS_TAB_MIN_WIDTH = 88;
|
|
389
|
-
/** The active tab's floor (px): icon + ~8 letters + "…" + its close. Mirrored to CSS as --mxc-tab-active-min. */
|
|
390
|
-
declare const CANVAS_ACTIVE_TAB_MIN_WIDTH = 112;
|
|
391
394
|
/**
|
|
392
|
-
*
|
|
393
|
-
*
|
|
394
|
-
*
|
|
395
|
-
* rule is testable without a layout engine. `width <= 0` (not measured yet)
|
|
396
|
-
* shows everything.
|
|
395
|
+
* Every tab's floor (px): icon + ~10 letters + "…" — still readable. Tabs shrink
|
|
396
|
+
* evenly from 12rem down to this; past it the strip scrolls. Mirrored to CSS as
|
|
397
|
+
* --mxc-tab-min.
|
|
397
398
|
*/
|
|
398
|
-
declare
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
399
|
+
declare const CANVAS_TAB_MIN_WIDTH = 120;
|
|
400
|
+
/** True when `count` tabs at their floor do not fit `width` px: the strip scrolls and offers "All tabs". */
|
|
401
|
+
declare function canvasTabsOverflow(count: number, width: number): boolean;
|
|
402
|
+
/** One entry of a strip: a tab, or a split's visible tabs drawn as ONE joined tab (Chrome split view). */
|
|
403
|
+
type CanvasStripEntry = {
|
|
404
|
+
readonly type: "tab";
|
|
405
|
+
readonly tab: CanvasStripTab;
|
|
406
|
+
} | {
|
|
407
|
+
readonly type: "split";
|
|
408
|
+
readonly tabs: readonly CanvasStripTab[];
|
|
403
409
|
};
|
|
410
|
+
/**
|
|
411
|
+
* The strip's entries. With `actives` (each pane's active item) for two or more
|
|
412
|
+
* panes, those tabs become one joined entry, placed where the first of them
|
|
413
|
+
* stands; every other tab keeps its place. Pure, so the rule is testable.
|
|
414
|
+
*/
|
|
415
|
+
declare function planCanvasTabStrip(tabs: readonly CanvasStripTab[], actives?: ReadonlyMap<CanvasPaneId, CanvasItemId> | null): CanvasStripEntry[];
|
|
416
|
+
/**
|
|
417
|
+
* THE window-wide tab strip of a split canvas (Chrome split view): every
|
|
418
|
+
* pane's tabs in one row above the panes, the panes' visible tabs drawn as
|
|
419
|
+
* one joined tab, "+" opening in the focused pane. A split never halves the
|
|
420
|
+
* strip into one per pane.
|
|
421
|
+
*/
|
|
422
|
+
declare function CanvasWindowTabs(): react.JSX.Element;
|
|
404
423
|
|
|
405
424
|
/**
|
|
406
425
|
* One resize gesture (the canvas edge, a split handle). While it runs:
|
|
@@ -512,4 +531,4 @@ interface BrowserBarProps {
|
|
|
512
531
|
/** A browser's back · forward · reload · address bar, for a kind's leading slot or its body. */
|
|
513
532
|
declare function BrowserBar({ url, canGoBack, canGoForward, onBack, onForward, onReload, onNavigate, trailing, className }: BrowserBarProps): react.JSX.Element;
|
|
514
533
|
|
|
515
|
-
export { type AnyCanvasKind, BrowserBar, type BrowserBarProps, type BrowserTab, BrowserTabs, type BrowserTabsProps,
|
|
534
|
+
export { type AnyCanvasKind, BrowserBar, type BrowserBarProps, type BrowserTab, BrowserTabs, type BrowserTabsProps, CANVAS_TAB_MIN_WIDTH, CanvasColumn, type CanvasColumnProps, type CanvasFloating, CanvasFrame, CanvasHeaderButton, type CanvasHeaderButtonProps, type CanvasHostPorts, type CanvasKind, type CanvasKindIcon, CanvasKindIcons, type CanvasKindProps, type CanvasLauncherEntry, type CanvasMenuEntry, type CanvasMenuItem, CanvasMenuTrigger, type CanvasNativeBodyFrame, type CanvasNativeBodyInfo, type CanvasNativeRect, type CanvasOverlayPort, CanvasPaneView, CanvasPanel, CanvasPanelEmpty, type CanvasPanelProps, CanvasProvider, type CanvasProviderProps, type CanvasShowMenu, type CanvasStripEntry, type CanvasStripTab, CanvasTab, type CanvasTabProps, type CanvasTabStripMode, CanvasToggle, CanvasWindowScope, CanvasWindowTabs, beginCanvasResize, canvasSessionKey, canvasTabsOverflow, defineCanvasKind, getCanvasKind, itemTitle, listCanvasKinds, planCanvasTabStrip, registerCanvasKind, registerCanvasKinds, useCanvas, useCanvasColumnWidth, useCanvasHostPorts, useCanvasIsPresented, useCanvasKind, useCanvasKindToggle, useCanvasKinds, useCanvasLauncherEntries, useCanvasLauncherEntry, useCanvasMenuItems, useCanvasNativeBodies, useCanvasPresentation, useCanvasState, useCanvasWindowId, useOptionalCanvas, useOptionalCanvasState };
|
package/dist/react.js
CHANGED
|
@@ -2591,6 +2591,10 @@ var CanvasSinglePaneContext = createContext3(false);
|
|
|
2591
2591
|
function useCanvasSinglePane() {
|
|
2592
2592
|
return useContext3(CanvasSinglePaneContext);
|
|
2593
2593
|
}
|
|
2594
|
+
var CanvasWindowTabsContext = createContext3(false);
|
|
2595
|
+
function useCanvasWindowTabs() {
|
|
2596
|
+
return useContext3(CanvasWindowTabsContext);
|
|
2597
|
+
}
|
|
2594
2598
|
function useSlotSize(slots, paneId) {
|
|
2595
2599
|
return useSyncExternalStore3(
|
|
2596
2600
|
slots.subscribe,
|
|
@@ -3003,6 +3007,20 @@ function windowTabsSignature(state, windowId) {
|
|
|
3003
3007
|
}
|
|
3004
3008
|
return rows.join("");
|
|
3005
3009
|
}
|
|
3010
|
+
function paneActivesSignature(state, windowId) {
|
|
3011
|
+
const frame2 = canvasWindowFrame(state, windowId);
|
|
3012
|
+
if (!frame2) return "";
|
|
3013
|
+
return listPaneIds(frame2.layout).map((paneId) => `${paneId}${state.panes[paneId]?.activeItemId ?? ""}`).join("");
|
|
3014
|
+
}
|
|
3015
|
+
function parsePaneActives(signature) {
|
|
3016
|
+
const actives = /* @__PURE__ */ new Map();
|
|
3017
|
+
if (!signature) return actives;
|
|
3018
|
+
for (const row of signature.split("")) {
|
|
3019
|
+
const [paneId = "", itemId = ""] = row.split("");
|
|
3020
|
+
if (itemId) actives.set(paneId, itemId);
|
|
3021
|
+
}
|
|
3022
|
+
return actives;
|
|
3023
|
+
}
|
|
3006
3024
|
function parseWindowTabs(signature) {
|
|
3007
3025
|
if (!signature) return [];
|
|
3008
3026
|
const perPane = /* @__PURE__ */ new Map();
|
|
@@ -3033,6 +3051,7 @@ function CanvasPaneView({ paneId }) {
|
|
|
3033
3051
|
const canGoForward = useCanvasState((s) => active ? selectCanvasCanGoForward(s, active.id) : false);
|
|
3034
3052
|
const kind = useItemKind(active?.kind ?? "");
|
|
3035
3053
|
const singlePane = useCanvasSinglePane();
|
|
3054
|
+
const inWindowStrip = useCanvasWindowTabs() && !singlePane;
|
|
3036
3055
|
const windowTabs = useCanvasState((s) => singlePane ? windowTabsSignature(s, windowId) : "");
|
|
3037
3056
|
const sectionRef = useRef7(null);
|
|
3038
3057
|
const bodyRef = useRef7(null);
|
|
@@ -3077,8 +3096,8 @@ function CanvasPaneView({ paneId }) {
|
|
|
3077
3096
|
children: /* @__PURE__ */ jsx7(ArrowRightIcon, {})
|
|
3078
3097
|
}
|
|
3079
3098
|
) : null,
|
|
3080
|
-
single && active ? /* @__PURE__ */ jsx7(SingleTitle, { item: active, kind }) : tabs.length > 0 ? /* @__PURE__ */ jsx7(TabStrip, { tabs, activeItemId: pane.activeItemId }) : /* @__PURE__ */ jsx7("span", { className: "mxc-panel-title", children: "New tab" }),
|
|
3081
|
-
/* @__PURE__ */ jsx7(CanvasHeaderButton, { className: "mxc-new-tab", label: "New tab", onClick: () => void canvas.newTab(paneId), children: /* @__PURE__ */ jsx7(PlusIcon, {}) })
|
|
3099
|
+
inWindowStrip ? active ? /* @__PURE__ */ jsx7(PaneTitle, { item: active, kind }) : /* @__PURE__ */ jsx7("span", { className: "mxc-panel-title", children: "New tab" }) : single && active ? /* @__PURE__ */ jsx7(SingleTitle, { item: active, kind }) : tabs.length > 0 ? /* @__PURE__ */ jsx7(TabStrip, { tabs, activeItemId: pane.activeItemId }) : /* @__PURE__ */ jsx7("span", { className: "mxc-panel-title", children: "New tab" }),
|
|
3100
|
+
inWindowStrip ? null : /* @__PURE__ */ jsx7(CanvasHeaderButton, { className: "mxc-new-tab", label: "New tab", onClick: () => void canvas.newTab(paneId), children: /* @__PURE__ */ jsx7(PlusIcon, {}) })
|
|
3082
3101
|
] }),
|
|
3083
3102
|
leading: Leading && kindProps ? /* @__PURE__ */ jsx7(Leading, { ...kindProps }) : null,
|
|
3084
3103
|
actions: Action && kindProps ? (
|
|
@@ -3139,24 +3158,56 @@ function SingleTitle({ item, kind }) {
|
|
|
3139
3158
|
/* @__PURE__ */ jsx7("button", { type: "button", className: "mxc-tab-close", "data-slot": "browser-tab-close", "aria-label": `Close ${title}`, onClick: () => canvas.close(item.id), children: /* @__PURE__ */ jsx7(CloseIcon, {}) })
|
|
3140
3159
|
] });
|
|
3141
3160
|
}
|
|
3142
|
-
|
|
3143
|
-
|
|
3144
|
-
|
|
3161
|
+
function PaneTitle({ item, kind }) {
|
|
3162
|
+
const title = itemTitle(item, kind);
|
|
3163
|
+
const drag = useTabDrag(item.id, title);
|
|
3164
|
+
const Icon = kind?.icon ?? AlertIcon;
|
|
3165
|
+
return /* @__PURE__ */ jsxs6("span", { className: "mxc-panel-title mxc-pane-title", "data-draggable": "", title, ...drag, children: [
|
|
3166
|
+
/* @__PURE__ */ jsx7(Icon, { className: "mxc-title-icon" }),
|
|
3167
|
+
/* @__PURE__ */ jsx7("span", { className: "mxc-tab-title", children: title })
|
|
3168
|
+
] });
|
|
3169
|
+
}
|
|
3170
|
+
var CANVAS_TAB_MIN_WIDTH = 120;
|
|
3145
3171
|
var TAB_GAP = 2;
|
|
3146
|
-
function
|
|
3147
|
-
if (count <=
|
|
3148
|
-
|
|
3149
|
-
|
|
3150
|
-
|
|
3151
|
-
|
|
3152
|
-
|
|
3153
|
-
const
|
|
3154
|
-
|
|
3155
|
-
|
|
3156
|
-
}
|
|
3157
|
-
|
|
3172
|
+
function canvasTabsOverflow(count, width) {
|
|
3173
|
+
if (count <= 1 || width <= 0) return false;
|
|
3174
|
+
return count * CANVAS_TAB_MIN_WIDTH + (count - 1) * TAB_GAP > width;
|
|
3175
|
+
}
|
|
3176
|
+
function planCanvasTabStrip(tabs, actives) {
|
|
3177
|
+
const joined = actives ? tabs.filter((tab) => actives.get(tab.paneId) === tab.itemId) : [];
|
|
3178
|
+
if (joined.length < 2) return tabs.map((tab) => ({ type: "tab", tab }));
|
|
3179
|
+
const entries = [];
|
|
3180
|
+
let placed = false;
|
|
3181
|
+
for (const tab of tabs) {
|
|
3182
|
+
if (!joined.includes(tab)) entries.push({ type: "tab", tab });
|
|
3183
|
+
else if (!placed) {
|
|
3184
|
+
entries.push({ type: "split", tabs: joined });
|
|
3185
|
+
placed = true;
|
|
3186
|
+
}
|
|
3187
|
+
}
|
|
3188
|
+
return entries;
|
|
3189
|
+
}
|
|
3190
|
+
function CanvasWindowTabs() {
|
|
3158
3191
|
const canvas = useCanvas();
|
|
3192
|
+
const { windowId } = useCanvasInternals();
|
|
3193
|
+
const signature = useCanvasState((s) => windowTabsSignature(s, windowId));
|
|
3194
|
+
const activesSignature = useCanvasState((s) => paneActivesSignature(s, windowId));
|
|
3195
|
+
const focusedPaneId = useCanvasState((s) => selectCanvasFocusedPaneId(s, windowId));
|
|
3196
|
+
const focusedActive = useCanvasState((s) => focusedPaneId ? s.panes[focusedPaneId]?.activeItemId ?? null : null);
|
|
3197
|
+
const tabs = parseWindowTabs(signature);
|
|
3198
|
+
const actives = parsePaneActives(activesSignature);
|
|
3199
|
+
return /* @__PURE__ */ jsxs6("div", { className: "mxc-window-tabs", "data-slot": "canvas-window-tabs", children: [
|
|
3200
|
+
/* @__PURE__ */ jsx7(TabStrip, { tabs, activeItemId: focusedActive, actives }),
|
|
3201
|
+
/* @__PURE__ */ jsx7(CanvasHeaderButton, { className: "mxc-new-tab", label: "New tab", onClick: () => void canvas.newTab(focusedPaneId ?? void 0), children: /* @__PURE__ */ jsx7(PlusIcon, {}) })
|
|
3202
|
+
] });
|
|
3203
|
+
}
|
|
3204
|
+
function TabStrip({
|
|
3205
|
+
tabs,
|
|
3206
|
+
activeItemId,
|
|
3207
|
+
actives
|
|
3208
|
+
}) {
|
|
3159
3209
|
const strip = useRef7(null);
|
|
3210
|
+
const list = useRef7(null);
|
|
3160
3211
|
const [width, setWidth] = useState5(0);
|
|
3161
3212
|
const read = useRef7(() => {
|
|
3162
3213
|
});
|
|
@@ -3182,48 +3233,76 @@ function TabStrip({ tabs, activeItemId }) {
|
|
|
3182
3233
|
useIsoLayoutEffect4(() => {
|
|
3183
3234
|
read.current();
|
|
3184
3235
|
}, [tabs.length]);
|
|
3185
|
-
|
|
3186
|
-
|
|
3187
|
-
|
|
3188
|
-
|
|
3236
|
+
useEffect7(() => {
|
|
3237
|
+
const el = list.current;
|
|
3238
|
+
if (!el) return void 0;
|
|
3239
|
+
const onWheel = (event) => {
|
|
3240
|
+
if (Math.abs(event.deltaY) <= Math.abs(event.deltaX) || el.scrollWidth <= el.clientWidth) return;
|
|
3241
|
+
event.preventDefault();
|
|
3242
|
+
el.scrollLeft += event.deltaY;
|
|
3243
|
+
};
|
|
3244
|
+
el.addEventListener("wheel", onWheel, { passive: false });
|
|
3245
|
+
return () => el.removeEventListener("wheel", onWheel);
|
|
3246
|
+
}, []);
|
|
3247
|
+
useIsoLayoutEffect4(() => {
|
|
3248
|
+
const el = list.current;
|
|
3249
|
+
if (!el || !activeItemId) return;
|
|
3250
|
+
const tab = [...el.querySelectorAll("[data-mxc-tab]")].find((node) => node.dataset.mxcTab === activeItemId);
|
|
3251
|
+
if (!tab) return;
|
|
3252
|
+
const target = tab.closest(".mxc-tab-group") ?? tab;
|
|
3253
|
+
const box = el.getBoundingClientRect();
|
|
3254
|
+
const rect = target.getBoundingClientRect();
|
|
3255
|
+
if (rect.left < box.left) el.scrollLeft -= box.left - rect.left;
|
|
3256
|
+
else if (rect.right > box.right) el.scrollLeft += rect.right - box.right;
|
|
3257
|
+
}, [activeItemId, width, tabs.length]);
|
|
3258
|
+
const entries = planCanvasTabStrip(tabs, actives);
|
|
3259
|
+
const overflow = canvasTabsOverflow(tabs.length, width);
|
|
3260
|
+
const joined = entries.some((entry) => entry.type === "split");
|
|
3261
|
+
const isActive = (tab) => actives ? actives.get(tab.paneId) === tab.itemId : tab.itemId === activeItemId;
|
|
3262
|
+
const tabView = (tab) => /* @__PURE__ */ jsx7(
|
|
3263
|
+
ItemTab,
|
|
3264
|
+
{
|
|
3265
|
+
itemId: tab.itemId,
|
|
3266
|
+
paneId: tab.paneId,
|
|
3267
|
+
index: tab.index,
|
|
3268
|
+
active: isActive(tab),
|
|
3269
|
+
current: joined && tab.itemId === activeItemId
|
|
3270
|
+
},
|
|
3271
|
+
tab.itemId
|
|
3272
|
+
);
|
|
3189
3273
|
return /* @__PURE__ */ jsxs6(
|
|
3190
3274
|
"div",
|
|
3191
3275
|
{
|
|
3192
3276
|
ref: strip,
|
|
3193
3277
|
className: "mxc-tabstrip",
|
|
3194
|
-
"data-overflow":
|
|
3195
|
-
|
|
3196
|
-
style: { ["--mxc-tab-min"]: `${CANVAS_TAB_MIN_WIDTH}px`, ["--mxc-tab-active-min"]: `${CANVAS_ACTIVE_TAB_MIN_WIDTH}px` },
|
|
3278
|
+
"data-overflow": overflow ? "" : void 0,
|
|
3279
|
+
style: { ["--mxc-tab-min"]: `${CANVAS_TAB_MIN_WIDTH}px` },
|
|
3197
3280
|
children: [
|
|
3198
|
-
/* @__PURE__ */ jsx7(
|
|
3199
|
-
"
|
|
3200
|
-
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
|
|
3204
|
-
|
|
3205
|
-
|
|
3206
|
-
|
|
3207
|
-
if (next) canvas.activate(next.itemId);
|
|
3281
|
+
/* @__PURE__ */ jsx7("div", { ref: list, className: "mxc-tabs", role: "tablist", "aria-label": "Canvas tabs", "aria-multiselectable": joined ? true : void 0, children: entries.map(
|
|
3282
|
+
(entry) => entry.type === "tab" ? tabView(entry.tab) : /* @__PURE__ */ jsx7(
|
|
3283
|
+
"div",
|
|
3284
|
+
{
|
|
3285
|
+
className: "mxc-tab-group",
|
|
3286
|
+
"data-split": "",
|
|
3287
|
+
role: "presentation",
|
|
3288
|
+
style: { ["--mxc-group-n"]: entry.tabs.length },
|
|
3289
|
+
children: entry.tabs.map(tabView)
|
|
3208
3290
|
},
|
|
3209
|
-
|
|
3210
|
-
|
|
3211
|
-
),
|
|
3212
|
-
|
|
3291
|
+
`split:${entry.tabs.map((tab) => tab.itemId).join("|")}`
|
|
3292
|
+
)
|
|
3293
|
+
) }),
|
|
3294
|
+
overflow ? /* @__PURE__ */ jsx7(TabListMenu, { tabs, activeItemId }) : null
|
|
3213
3295
|
]
|
|
3214
3296
|
}
|
|
3215
3297
|
);
|
|
3216
3298
|
}
|
|
3217
|
-
function TabListMenu({ tabs, activeItemId
|
|
3299
|
+
function TabListMenu({ tabs, activeItemId }) {
|
|
3218
3300
|
const canvas = useCanvas();
|
|
3219
3301
|
const { ports, layer } = useCanvasInternals();
|
|
3220
3302
|
const blocking = useRef7(null);
|
|
3221
3303
|
useEffect7(() => () => blocking.current?.(), []);
|
|
3222
3304
|
const label = `All tabs (${tabs.length})`;
|
|
3223
|
-
const trigger = (props) => /* @__PURE__ */
|
|
3224
|
-
/* @__PURE__ */ jsx7(ChevronDownIcon, {}),
|
|
3225
|
-
/* @__PURE__ */ jsx7("span", { className: "mxc-tab-list-count", "aria-hidden": "true", children: hidden })
|
|
3226
|
-
] });
|
|
3305
|
+
const trigger = (props) => /* @__PURE__ */ jsx7(CanvasHeaderButton, { className: "mxc-tab-list", label, ...props, children: /* @__PURE__ */ jsx7(ChevronDownIcon, {}) });
|
|
3227
3306
|
const showMenu = ports.showMenu;
|
|
3228
3307
|
if (showMenu) {
|
|
3229
3308
|
return trigger({
|
|
@@ -3279,7 +3358,13 @@ function TabListEntry({ itemId, active }) {
|
|
|
3279
3358
|
}
|
|
3280
3359
|
);
|
|
3281
3360
|
}
|
|
3282
|
-
function ItemTab({
|
|
3361
|
+
function ItemTab({
|
|
3362
|
+
itemId,
|
|
3363
|
+
paneId,
|
|
3364
|
+
index,
|
|
3365
|
+
active,
|
|
3366
|
+
current = false
|
|
3367
|
+
}) {
|
|
3283
3368
|
const canvas = useCanvas();
|
|
3284
3369
|
const item = useCanvasState((s) => s.items[itemId]);
|
|
3285
3370
|
const kind = useItemKind(item?.kind ?? "");
|
|
@@ -3293,6 +3378,8 @@ function ItemTab({ itemId, paneId, index, active }) {
|
|
|
3293
3378
|
title,
|
|
3294
3379
|
icon: /* @__PURE__ */ jsx7(Icon, {}),
|
|
3295
3380
|
active,
|
|
3381
|
+
"data-mxc-tab": itemId,
|
|
3382
|
+
"data-current": current ? "" : void 0,
|
|
3296
3383
|
onSelect: () => canvas.activate(itemId),
|
|
3297
3384
|
onClose: () => canvas.close(itemId),
|
|
3298
3385
|
...drag,
|
|
@@ -3478,6 +3565,7 @@ function CanvasColumn({ className, style, onLiveWidth, placement = "docked" }) {
|
|
|
3478
3565
|
};
|
|
3479
3566
|
}, [layer]);
|
|
3480
3567
|
if (!layout) return null;
|
|
3568
|
+
const windowTabs = !singlePane && layout.type === "split";
|
|
3481
3569
|
const fitted = fitCanvasWidth(width, region, controller.rules);
|
|
3482
3570
|
const shown = dragWidth ?? fitted;
|
|
3483
3571
|
return /* @__PURE__ */ jsx8(
|
|
@@ -3505,10 +3593,13 @@ function CanvasColumn({ className, style, onLiveWidth, placement = "docked" }) {
|
|
|
3505
3593
|
}
|
|
3506
3594
|
}
|
|
3507
3595
|
) : null,
|
|
3508
|
-
/* @__PURE__ */ jsx8(CanvasSlotsContext.Provider, { value: slots, children: /* @__PURE__ */
|
|
3509
|
-
/* @__PURE__ */
|
|
3596
|
+
/* @__PURE__ */ jsx8(CanvasSlotsContext.Provider, { value: slots, children: /* @__PURE__ */ jsx8(CanvasSinglePaneContext.Provider, { value: singlePane, children: /* @__PURE__ */ jsxs7(CanvasWindowTabsContext.Provider, { value: windowTabs, children: [
|
|
3597
|
+
/* @__PURE__ */ jsxs7("div", { className: "mxc-layout", "data-single-pane": singlePane ? "" : void 0, "data-window-tabs": windowTabs ? "" : void 0, children: [
|
|
3598
|
+
windowTabs ? /* @__PURE__ */ jsx8(CanvasWindowTabs, {}) : null,
|
|
3599
|
+
/* @__PURE__ */ jsx8("div", { className: "mxc-layout-panes", children: singlePane ? /* @__PURE__ */ jsx8(CanvasPaneView, { paneId: presentedPaneId ?? listPaneIds(layout)[0] }) : /* @__PURE__ */ jsx8(LayoutNodeView, { node: layout }) })
|
|
3600
|
+
] }),
|
|
3510
3601
|
/* @__PURE__ */ jsx8(CanvasBodyLayer, {})
|
|
3511
|
-
] }) })
|
|
3602
|
+
] }) }) })
|
|
3512
3603
|
] })
|
|
3513
3604
|
}
|
|
3514
3605
|
);
|
|
@@ -3714,7 +3805,6 @@ function CanvasFrame({ children, className }) {
|
|
|
3714
3805
|
export {
|
|
3715
3806
|
BrowserBar,
|
|
3716
3807
|
BrowserTabs,
|
|
3717
|
-
CANVAS_ACTIVE_TAB_MIN_WIDTH,
|
|
3718
3808
|
CANVAS_TAB_MIN_WIDTH,
|
|
3719
3809
|
CanvasColumn,
|
|
3720
3810
|
CanvasFrame,
|
|
@@ -3728,13 +3818,15 @@ export {
|
|
|
3728
3818
|
CanvasTab,
|
|
3729
3819
|
CanvasToggle,
|
|
3730
3820
|
CanvasWindowScope,
|
|
3821
|
+
CanvasWindowTabs,
|
|
3731
3822
|
beginCanvasResize,
|
|
3732
3823
|
canvasSessionKey,
|
|
3824
|
+
canvasTabsOverflow,
|
|
3733
3825
|
defineCanvasKind,
|
|
3734
|
-
fitCanvasTabs,
|
|
3735
3826
|
getCanvasKind,
|
|
3736
3827
|
itemTitle,
|
|
3737
3828
|
listCanvasKinds,
|
|
3829
|
+
planCanvasTabStrip,
|
|
3738
3830
|
registerCanvasKind,
|
|
3739
3831
|
registerCanvasKinds,
|
|
3740
3832
|
useCanvas,
|