@ai-matrx/canvas 0.7.2 → 0.8.0
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 +22 -0
- package/README.md +3 -3
- package/dist/index.cjs +5 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +145 -50
- 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 +145 -50
- package/dist/react.js.map +1 -1
- package/dist/styles.css +94 -40
- 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
|
@@ -990,7 +990,11 @@ var CANVAS_PANE_MIN_WIDTH = 280;
|
|
|
990
990
|
var CANVAS_WEB_LAYOUT_RULES = {
|
|
991
991
|
defaultWidth: CANVAS_DEFAULT_WIDTH,
|
|
992
992
|
minWidth: CANVAS_MIN_WIDTH,
|
|
993
|
-
|
|
993
|
+
// The page beside the canvas keeps room for its route header (title, mode switch,
|
|
994
|
+
// the shell's own controls): a 2026-10-03 census of 40 routes found headers 29-67px
|
|
995
|
+
// wide at 420 with a 900px canvas. Hosts pass `regionWidth` so this is the PAGE's
|
|
996
|
+
// width, not the window's.
|
|
997
|
+
centreMinWidth: 600,
|
|
994
998
|
// Split down 70/30 like the desktop: what opens below (notifications, a feed) is the smaller pane.
|
|
995
999
|
stackSplit: 0.7,
|
|
996
1000
|
sideSplit: 0.5,
|
|
@@ -2587,6 +2591,10 @@ var CanvasSinglePaneContext = createContext3(false);
|
|
|
2587
2591
|
function useCanvasSinglePane() {
|
|
2588
2592
|
return useContext3(CanvasSinglePaneContext);
|
|
2589
2593
|
}
|
|
2594
|
+
var CanvasWindowTabsContext = createContext3(false);
|
|
2595
|
+
function useCanvasWindowTabs() {
|
|
2596
|
+
return useContext3(CanvasWindowTabsContext);
|
|
2597
|
+
}
|
|
2590
2598
|
function useSlotSize(slots, paneId) {
|
|
2591
2599
|
return useSyncExternalStore3(
|
|
2592
2600
|
slots.subscribe,
|
|
@@ -2999,6 +3007,20 @@ function windowTabsSignature(state, windowId) {
|
|
|
2999
3007
|
}
|
|
3000
3008
|
return rows.join("");
|
|
3001
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
|
+
}
|
|
3002
3024
|
function parseWindowTabs(signature) {
|
|
3003
3025
|
if (!signature) return [];
|
|
3004
3026
|
const perPane = /* @__PURE__ */ new Map();
|
|
@@ -3029,6 +3051,7 @@ function CanvasPaneView({ paneId }) {
|
|
|
3029
3051
|
const canGoForward = useCanvasState((s) => active ? selectCanvasCanGoForward(s, active.id) : false);
|
|
3030
3052
|
const kind = useItemKind(active?.kind ?? "");
|
|
3031
3053
|
const singlePane = useCanvasSinglePane();
|
|
3054
|
+
const inWindowStrip = useCanvasWindowTabs() && !singlePane;
|
|
3032
3055
|
const windowTabs = useCanvasState((s) => singlePane ? windowTabsSignature(s, windowId) : "");
|
|
3033
3056
|
const sectionRef = useRef7(null);
|
|
3034
3057
|
const bodyRef = useRef7(null);
|
|
@@ -3073,8 +3096,8 @@ function CanvasPaneView({ paneId }) {
|
|
|
3073
3096
|
children: /* @__PURE__ */ jsx7(ArrowRightIcon, {})
|
|
3074
3097
|
}
|
|
3075
3098
|
) : null,
|
|
3076
|
-
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" }),
|
|
3077
|
-
/* @__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, {}) })
|
|
3078
3101
|
] }),
|
|
3079
3102
|
leading: Leading && kindProps ? /* @__PURE__ */ jsx7(Leading, { ...kindProps }) : null,
|
|
3080
3103
|
actions: Action && kindProps ? (
|
|
@@ -3135,24 +3158,56 @@ function SingleTitle({ item, kind }) {
|
|
|
3135
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, {}) })
|
|
3136
3159
|
] });
|
|
3137
3160
|
}
|
|
3138
|
-
|
|
3139
|
-
|
|
3140
|
-
|
|
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;
|
|
3141
3171
|
var TAB_GAP = 2;
|
|
3142
|
-
function
|
|
3143
|
-
if (count <=
|
|
3144
|
-
|
|
3145
|
-
|
|
3146
|
-
|
|
3147
|
-
|
|
3148
|
-
|
|
3149
|
-
const
|
|
3150
|
-
|
|
3151
|
-
|
|
3152
|
-
}
|
|
3153
|
-
|
|
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() {
|
|
3154
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
|
+
}) {
|
|
3155
3209
|
const strip = useRef7(null);
|
|
3210
|
+
const list = useRef7(null);
|
|
3156
3211
|
const [width, setWidth] = useState5(0);
|
|
3157
3212
|
const read = useRef7(() => {
|
|
3158
3213
|
});
|
|
@@ -3178,48 +3233,75 @@ function TabStrip({ tabs, activeItemId }) {
|
|
|
3178
3233
|
useIsoLayoutEffect4(() => {
|
|
3179
3234
|
read.current();
|
|
3180
3235
|
}, [tabs.length]);
|
|
3181
|
-
|
|
3182
|
-
|
|
3183
|
-
|
|
3184
|
-
|
|
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 box = el.getBoundingClientRect();
|
|
3253
|
+
const rect = tab.getBoundingClientRect();
|
|
3254
|
+
if (rect.left < box.left) el.scrollLeft -= box.left - rect.left;
|
|
3255
|
+
else if (rect.right > box.right) el.scrollLeft += rect.right - box.right;
|
|
3256
|
+
}, [activeItemId, width, tabs.length]);
|
|
3257
|
+
const entries = planCanvasTabStrip(tabs, actives);
|
|
3258
|
+
const overflow = canvasTabsOverflow(tabs.length, width);
|
|
3259
|
+
const joined = entries.some((entry) => entry.type === "split");
|
|
3260
|
+
const isActive = (tab) => actives ? actives.get(tab.paneId) === tab.itemId : tab.itemId === activeItemId;
|
|
3261
|
+
const tabView = (tab) => /* @__PURE__ */ jsx7(
|
|
3262
|
+
ItemTab,
|
|
3263
|
+
{
|
|
3264
|
+
itemId: tab.itemId,
|
|
3265
|
+
paneId: tab.paneId,
|
|
3266
|
+
index: tab.index,
|
|
3267
|
+
active: isActive(tab),
|
|
3268
|
+
current: joined && tab.itemId === activeItemId
|
|
3269
|
+
},
|
|
3270
|
+
tab.itemId
|
|
3271
|
+
);
|
|
3185
3272
|
return /* @__PURE__ */ jsxs6(
|
|
3186
3273
|
"div",
|
|
3187
3274
|
{
|
|
3188
3275
|
ref: strip,
|
|
3189
3276
|
className: "mxc-tabstrip",
|
|
3190
|
-
"data-overflow":
|
|
3191
|
-
|
|
3192
|
-
style: { ["--mxc-tab-min"]: `${CANVAS_TAB_MIN_WIDTH}px`, ["--mxc-tab-active-min"]: `${CANVAS_ACTIVE_TAB_MIN_WIDTH}px` },
|
|
3277
|
+
"data-overflow": overflow ? "" : void 0,
|
|
3278
|
+
style: { ["--mxc-tab-min"]: `${CANVAS_TAB_MIN_WIDTH}px` },
|
|
3193
3279
|
children: [
|
|
3194
|
-
/* @__PURE__ */ jsx7(
|
|
3195
|
-
"
|
|
3196
|
-
|
|
3197
|
-
|
|
3198
|
-
|
|
3199
|
-
|
|
3200
|
-
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
if (next) canvas.activate(next.itemId);
|
|
3280
|
+
/* @__PURE__ */ jsx7("div", { ref: list, className: "mxc-tabs", role: "tablist", "aria-label": "Canvas tabs", "aria-multiselectable": joined ? true : void 0, children: entries.map(
|
|
3281
|
+
(entry) => entry.type === "tab" ? tabView(entry.tab) : /* @__PURE__ */ jsx7(
|
|
3282
|
+
"div",
|
|
3283
|
+
{
|
|
3284
|
+
className: "mxc-tab-group",
|
|
3285
|
+
"data-split": "",
|
|
3286
|
+
role: "presentation",
|
|
3287
|
+
style: { ["--mxc-group-n"]: entry.tabs.length },
|
|
3288
|
+
children: entry.tabs.map(tabView)
|
|
3204
3289
|
},
|
|
3205
|
-
|
|
3206
|
-
|
|
3207
|
-
),
|
|
3208
|
-
|
|
3290
|
+
`split:${entry.tabs.map((tab) => tab.itemId).join("|")}`
|
|
3291
|
+
)
|
|
3292
|
+
) }),
|
|
3293
|
+
overflow ? /* @__PURE__ */ jsx7(TabListMenu, { tabs, activeItemId }) : null
|
|
3209
3294
|
]
|
|
3210
3295
|
}
|
|
3211
3296
|
);
|
|
3212
3297
|
}
|
|
3213
|
-
function TabListMenu({ tabs, activeItemId
|
|
3298
|
+
function TabListMenu({ tabs, activeItemId }) {
|
|
3214
3299
|
const canvas = useCanvas();
|
|
3215
3300
|
const { ports, layer } = useCanvasInternals();
|
|
3216
3301
|
const blocking = useRef7(null);
|
|
3217
3302
|
useEffect7(() => () => blocking.current?.(), []);
|
|
3218
3303
|
const label = `All tabs (${tabs.length})`;
|
|
3219
|
-
const trigger = (props) => /* @__PURE__ */
|
|
3220
|
-
/* @__PURE__ */ jsx7(ChevronDownIcon, {}),
|
|
3221
|
-
/* @__PURE__ */ jsx7("span", { className: "mxc-tab-list-count", "aria-hidden": "true", children: hidden })
|
|
3222
|
-
] });
|
|
3304
|
+
const trigger = (props) => /* @__PURE__ */ jsx7(CanvasHeaderButton, { className: "mxc-tab-list", label, ...props, children: /* @__PURE__ */ jsx7(ChevronDownIcon, {}) });
|
|
3223
3305
|
const showMenu = ports.showMenu;
|
|
3224
3306
|
if (showMenu) {
|
|
3225
3307
|
return trigger({
|
|
@@ -3275,7 +3357,13 @@ function TabListEntry({ itemId, active }) {
|
|
|
3275
3357
|
}
|
|
3276
3358
|
);
|
|
3277
3359
|
}
|
|
3278
|
-
function ItemTab({
|
|
3360
|
+
function ItemTab({
|
|
3361
|
+
itemId,
|
|
3362
|
+
paneId,
|
|
3363
|
+
index,
|
|
3364
|
+
active,
|
|
3365
|
+
current = false
|
|
3366
|
+
}) {
|
|
3279
3367
|
const canvas = useCanvas();
|
|
3280
3368
|
const item = useCanvasState((s) => s.items[itemId]);
|
|
3281
3369
|
const kind = useItemKind(item?.kind ?? "");
|
|
@@ -3289,6 +3377,8 @@ function ItemTab({ itemId, paneId, index, active }) {
|
|
|
3289
3377
|
title,
|
|
3290
3378
|
icon: /* @__PURE__ */ jsx7(Icon, {}),
|
|
3291
3379
|
active,
|
|
3380
|
+
"data-mxc-tab": itemId,
|
|
3381
|
+
"data-current": current ? "" : void 0,
|
|
3292
3382
|
onSelect: () => canvas.activate(itemId),
|
|
3293
3383
|
onClose: () => canvas.close(itemId),
|
|
3294
3384
|
...drag,
|
|
@@ -3474,6 +3564,7 @@ function CanvasColumn({ className, style, onLiveWidth, placement = "docked" }) {
|
|
|
3474
3564
|
};
|
|
3475
3565
|
}, [layer]);
|
|
3476
3566
|
if (!layout) return null;
|
|
3567
|
+
const windowTabs = !singlePane && layout.type === "split";
|
|
3477
3568
|
const fitted = fitCanvasWidth(width, region, controller.rules);
|
|
3478
3569
|
const shown = dragWidth ?? fitted;
|
|
3479
3570
|
return /* @__PURE__ */ jsx8(
|
|
@@ -3501,10 +3592,13 @@ function CanvasColumn({ className, style, onLiveWidth, placement = "docked" }) {
|
|
|
3501
3592
|
}
|
|
3502
3593
|
}
|
|
3503
3594
|
) : null,
|
|
3504
|
-
/* @__PURE__ */ jsx8(CanvasSlotsContext.Provider, { value: slots, children: /* @__PURE__ */
|
|
3505
|
-
/* @__PURE__ */
|
|
3595
|
+
/* @__PURE__ */ jsx8(CanvasSlotsContext.Provider, { value: slots, children: /* @__PURE__ */ jsx8(CanvasSinglePaneContext.Provider, { value: singlePane, children: /* @__PURE__ */ jsxs7(CanvasWindowTabsContext.Provider, { value: windowTabs, children: [
|
|
3596
|
+
/* @__PURE__ */ jsxs7("div", { className: "mxc-layout", "data-single-pane": singlePane ? "" : void 0, "data-window-tabs": windowTabs ? "" : void 0, children: [
|
|
3597
|
+
windowTabs ? /* @__PURE__ */ jsx8(CanvasWindowTabs, {}) : null,
|
|
3598
|
+
/* @__PURE__ */ jsx8("div", { className: "mxc-layout-panes", children: singlePane ? /* @__PURE__ */ jsx8(CanvasPaneView, { paneId: presentedPaneId ?? listPaneIds(layout)[0] }) : /* @__PURE__ */ jsx8(LayoutNodeView, { node: layout }) })
|
|
3599
|
+
] }),
|
|
3506
3600
|
/* @__PURE__ */ jsx8(CanvasBodyLayer, {})
|
|
3507
|
-
] }) })
|
|
3601
|
+
] }) }) })
|
|
3508
3602
|
] })
|
|
3509
3603
|
}
|
|
3510
3604
|
);
|
|
@@ -3710,7 +3804,6 @@ function CanvasFrame({ children, className }) {
|
|
|
3710
3804
|
export {
|
|
3711
3805
|
BrowserBar,
|
|
3712
3806
|
BrowserTabs,
|
|
3713
|
-
CANVAS_ACTIVE_TAB_MIN_WIDTH,
|
|
3714
3807
|
CANVAS_TAB_MIN_WIDTH,
|
|
3715
3808
|
CanvasColumn,
|
|
3716
3809
|
CanvasFrame,
|
|
@@ -3724,13 +3817,15 @@ export {
|
|
|
3724
3817
|
CanvasTab,
|
|
3725
3818
|
CanvasToggle,
|
|
3726
3819
|
CanvasWindowScope,
|
|
3820
|
+
CanvasWindowTabs,
|
|
3727
3821
|
beginCanvasResize,
|
|
3728
3822
|
canvasSessionKey,
|
|
3823
|
+
canvasTabsOverflow,
|
|
3729
3824
|
defineCanvasKind,
|
|
3730
|
-
fitCanvasTabs,
|
|
3731
3825
|
getCanvasKind,
|
|
3732
3826
|
itemTitle,
|
|
3733
3827
|
listCanvasKinds,
|
|
3828
|
+
planCanvasTabStrip,
|
|
3734
3829
|
registerCanvasKind,
|
|
3735
3830
|
registerCanvasKinds,
|
|
3736
3831
|
useCanvas,
|