@industry-theme/xterm-terminal-panel 0.2.2 → 0.2.4
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/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +517 -340
- package/dist/src/components/TabBar/TabBar.d.ts +4 -0
- package/dist/src/components/TabBar/TabBar.d.ts.map +1 -0
- package/dist/src/components/TabBar/TabButton.d.ts +4 -0
- package/dist/src/components/TabBar/TabButton.d.ts.map +1 -0
- package/dist/src/components/TabBar/index.d.ts +4 -0
- package/dist/src/components/TabBar/index.d.ts.map +1 -0
- package/dist/src/components/ThemedTerminal.d.ts.map +1 -1
- package/dist/src/hooks/useTabKeyboardShortcuts.d.ts +8 -0
- package/dist/src/hooks/useTabKeyboardShortcuts.d.ts.map +1 -0
- package/dist/src/panel-types/index.d.ts +7 -7
- package/dist/src/panel-types/index.d.ts.map +1 -1
- package/dist/src/panels/TabbedTerminalPanel.d.ts +2 -2
- package/dist/src/panels/TabbedTerminalPanel.d.ts.map +1 -1
- package/dist/src/types/mixed-tab.d.ts +20 -0
- package/dist/src/types/mixed-tab.d.ts.map +1 -0
- package/dist/src/types/tab.d.ts +42 -0
- package/dist/src/types/tab.d.ts.map +1 -0
- package/package.json +4 -1
package/dist/index.js
CHANGED
|
@@ -800,10 +800,268 @@ function useThemedTerminal() {
|
|
|
800
800
|
getCSSVariables
|
|
801
801
|
};
|
|
802
802
|
}
|
|
803
|
-
// src/
|
|
803
|
+
// src/components/TabBar/TabBar.tsx
|
|
804
|
+
import { useTheme as useTheme4 } from "@principal-ade/industry-theme";
|
|
805
|
+
import { Plus } from "lucide-react";
|
|
806
|
+
import { useState as useState2 } from "react";
|
|
807
|
+
|
|
808
|
+
// src/components/TabBar/TabButton.tsx
|
|
804
809
|
import { useTheme as useTheme3 } from "@principal-ade/industry-theme";
|
|
810
|
+
import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
811
|
+
var TabButton = ({
|
|
812
|
+
tab,
|
|
813
|
+
isActive,
|
|
814
|
+
isHovered,
|
|
815
|
+
onMouseEnter,
|
|
816
|
+
onMouseLeave,
|
|
817
|
+
onClick,
|
|
818
|
+
onClose,
|
|
819
|
+
keyboardHint,
|
|
820
|
+
renderAccessory
|
|
821
|
+
}) => {
|
|
822
|
+
const { theme } = useTheme3();
|
|
823
|
+
const showCloseButton = isHovered || isActive;
|
|
824
|
+
const closable = tab.closable !== false;
|
|
825
|
+
return /* @__PURE__ */ jsxs2("div", {
|
|
826
|
+
onMouseEnter,
|
|
827
|
+
onMouseLeave,
|
|
828
|
+
onClick,
|
|
829
|
+
style: {
|
|
830
|
+
display: "flex",
|
|
831
|
+
alignItems: "center",
|
|
832
|
+
justifyContent: "center",
|
|
833
|
+
gap: "6px",
|
|
834
|
+
padding: "6px 8px",
|
|
835
|
+
backgroundColor: isActive ? theme.colors.background : theme.colors.backgroundSecondary,
|
|
836
|
+
cursor: "pointer",
|
|
837
|
+
fontSize: theme.fontSizes[1],
|
|
838
|
+
fontWeight: isActive ? theme.fontWeights.semibold : theme.fontWeights.body,
|
|
839
|
+
fontFamily: theme.fonts.body,
|
|
840
|
+
color: isActive ? theme.colors.text : theme.colors.textSecondary,
|
|
841
|
+
whiteSpace: "nowrap",
|
|
842
|
+
transition: "all 0.2s",
|
|
843
|
+
flex: 1,
|
|
844
|
+
minWidth: 0,
|
|
845
|
+
height: "100%",
|
|
846
|
+
position: "relative",
|
|
847
|
+
boxSizing: "border-box"
|
|
848
|
+
},
|
|
849
|
+
children: [
|
|
850
|
+
closable && showCloseButton && /* @__PURE__ */ jsx3("button", {
|
|
851
|
+
onClick: (e) => {
|
|
852
|
+
e.stopPropagation();
|
|
853
|
+
onClose();
|
|
854
|
+
},
|
|
855
|
+
style: {
|
|
856
|
+
display: "flex",
|
|
857
|
+
alignItems: "center",
|
|
858
|
+
justifyContent: "center",
|
|
859
|
+
width: "16px",
|
|
860
|
+
height: "16px",
|
|
861
|
+
borderRadius: "3px",
|
|
862
|
+
border: "none",
|
|
863
|
+
backgroundColor: "transparent",
|
|
864
|
+
cursor: "pointer",
|
|
865
|
+
color: theme.colors.textSecondary,
|
|
866
|
+
padding: 0,
|
|
867
|
+
position: "absolute",
|
|
868
|
+
left: "8px"
|
|
869
|
+
},
|
|
870
|
+
onMouseEnter: (e) => {
|
|
871
|
+
e.currentTarget.style.backgroundColor = theme.colors.backgroundTertiary;
|
|
872
|
+
},
|
|
873
|
+
onMouseLeave: (e) => {
|
|
874
|
+
e.currentTarget.style.backgroundColor = "transparent";
|
|
875
|
+
},
|
|
876
|
+
title: "Close (⌘W)",
|
|
877
|
+
children: "×"
|
|
878
|
+
}),
|
|
879
|
+
tab.icon && /* @__PURE__ */ jsx3("div", {
|
|
880
|
+
style: { flexShrink: 0, display: "flex", alignItems: "center" },
|
|
881
|
+
children: tab.icon
|
|
882
|
+
}),
|
|
883
|
+
/* @__PURE__ */ jsx3("span", {
|
|
884
|
+
style: {
|
|
885
|
+
overflow: "hidden",
|
|
886
|
+
textOverflow: "ellipsis",
|
|
887
|
+
whiteSpace: "nowrap"
|
|
888
|
+
},
|
|
889
|
+
title: tab.label,
|
|
890
|
+
children: tab.label
|
|
891
|
+
}),
|
|
892
|
+
renderAccessory ? renderAccessory(tab) : keyboardHint && /* @__PURE__ */ jsx3("span", {
|
|
893
|
+
style: {
|
|
894
|
+
fontSize: theme.fontSizes[0],
|
|
895
|
+
color: theme.colors.textSecondary,
|
|
896
|
+
opacity: 0.6,
|
|
897
|
+
flexShrink: 0
|
|
898
|
+
},
|
|
899
|
+
children: keyboardHint
|
|
900
|
+
})
|
|
901
|
+
]
|
|
902
|
+
});
|
|
903
|
+
};
|
|
904
|
+
TabButton.displayName = "TabButton";
|
|
905
|
+
|
|
906
|
+
// src/components/TabBar/TabBar.tsx
|
|
907
|
+
import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
908
|
+
var TabBar = ({
|
|
909
|
+
tabs,
|
|
910
|
+
activeTabId,
|
|
911
|
+
onTabClick,
|
|
912
|
+
onTabClose,
|
|
913
|
+
onNewTab,
|
|
914
|
+
leftSection,
|
|
915
|
+
rightSection,
|
|
916
|
+
renderTabAccessory,
|
|
917
|
+
className,
|
|
918
|
+
showKeyboardHints = true
|
|
919
|
+
}) => {
|
|
920
|
+
const { theme } = useTheme4();
|
|
921
|
+
const [hoveredTabId, setHoveredTabId] = useState2(null);
|
|
922
|
+
return /* @__PURE__ */ jsxs3("div", {
|
|
923
|
+
className,
|
|
924
|
+
style: {
|
|
925
|
+
display: "flex",
|
|
926
|
+
alignItems: "stretch",
|
|
927
|
+
height: "40px",
|
|
928
|
+
flexShrink: 0,
|
|
929
|
+
boxSizing: "border-box"
|
|
930
|
+
},
|
|
931
|
+
children: [
|
|
932
|
+
leftSection && /* @__PURE__ */ jsx4("div", {
|
|
933
|
+
style: {
|
|
934
|
+
display: "flex",
|
|
935
|
+
alignItems: "center",
|
|
936
|
+
gap: "4px",
|
|
937
|
+
padding: "0 8px",
|
|
938
|
+
backgroundColor: theme.colors.backgroundSecondary,
|
|
939
|
+
borderRight: `1px solid ${theme.colors.border}`,
|
|
940
|
+
borderBottom: `1px solid ${theme.colors.border}`,
|
|
941
|
+
boxSizing: "border-box"
|
|
942
|
+
},
|
|
943
|
+
children: leftSection
|
|
944
|
+
}),
|
|
945
|
+
/* @__PURE__ */ jsx4("div", {
|
|
946
|
+
style: {
|
|
947
|
+
display: "flex",
|
|
948
|
+
alignItems: "center",
|
|
949
|
+
flex: 1,
|
|
950
|
+
overflow: "hidden",
|
|
951
|
+
backgroundColor: theme.colors.backgroundSecondary,
|
|
952
|
+
borderBottom: `1px solid ${theme.colors.border}`,
|
|
953
|
+
boxSizing: "border-box"
|
|
954
|
+
},
|
|
955
|
+
children: tabs.map((tab, index) => /* @__PURE__ */ jsx4(TabButton, {
|
|
956
|
+
tab,
|
|
957
|
+
isActive: tab.id === activeTabId,
|
|
958
|
+
isHovered: tab.id === hoveredTabId,
|
|
959
|
+
onMouseEnter: () => setHoveredTabId(tab.id),
|
|
960
|
+
onMouseLeave: () => setHoveredTabId(null),
|
|
961
|
+
onClick: () => onTabClick(tab.id),
|
|
962
|
+
onClose: () => onTabClose(tab.id),
|
|
963
|
+
keyboardHint: showKeyboardHints && index < 9 ? `⌘ ${index + 1}` : undefined,
|
|
964
|
+
renderAccessory: renderTabAccessory
|
|
965
|
+
}, tab.id))
|
|
966
|
+
}),
|
|
967
|
+
rightSection !== undefined ? rightSection && /* @__PURE__ */ jsx4("div", {
|
|
968
|
+
style: {
|
|
969
|
+
display: "flex",
|
|
970
|
+
alignItems: "center",
|
|
971
|
+
gap: "4px",
|
|
972
|
+
padding: "0 8px",
|
|
973
|
+
backgroundColor: theme.colors.backgroundSecondary,
|
|
974
|
+
borderLeft: `1px solid ${theme.colors.border}`,
|
|
975
|
+
borderBottom: `1px solid ${theme.colors.border}`,
|
|
976
|
+
boxSizing: "border-box"
|
|
977
|
+
},
|
|
978
|
+
children: rightSection
|
|
979
|
+
}) : onNewTab && /* @__PURE__ */ jsx4("div", {
|
|
980
|
+
style: {
|
|
981
|
+
display: "flex",
|
|
982
|
+
alignItems: "center",
|
|
983
|
+
gap: "4px",
|
|
984
|
+
padding: "0 8px",
|
|
985
|
+
backgroundColor: theme.colors.backgroundSecondary,
|
|
986
|
+
borderLeft: `1px solid ${theme.colors.border}`,
|
|
987
|
+
borderBottom: `1px solid ${theme.colors.border}`,
|
|
988
|
+
boxSizing: "border-box"
|
|
989
|
+
},
|
|
990
|
+
children: /* @__PURE__ */ jsx4("button", {
|
|
991
|
+
onClick: onNewTab,
|
|
992
|
+
style: {
|
|
993
|
+
display: "flex",
|
|
994
|
+
alignItems: "center",
|
|
995
|
+
justifyContent: "center",
|
|
996
|
+
width: "28px",
|
|
997
|
+
height: "28px",
|
|
998
|
+
border: "none",
|
|
999
|
+
borderRadius: "4px",
|
|
1000
|
+
backgroundColor: "transparent",
|
|
1001
|
+
cursor: "pointer",
|
|
1002
|
+
color: theme.colors.textSecondary
|
|
1003
|
+
},
|
|
1004
|
+
onMouseEnter: (e) => {
|
|
1005
|
+
e.currentTarget.style.backgroundColor = theme.colors.backgroundTertiary;
|
|
1006
|
+
},
|
|
1007
|
+
onMouseLeave: (e) => {
|
|
1008
|
+
e.currentTarget.style.backgroundColor = "transparent";
|
|
1009
|
+
},
|
|
1010
|
+
title: "New Tab (⌘T)",
|
|
1011
|
+
children: /* @__PURE__ */ jsx4(Plus, {
|
|
1012
|
+
size: 14
|
|
1013
|
+
})
|
|
1014
|
+
})
|
|
1015
|
+
})
|
|
1016
|
+
]
|
|
1017
|
+
});
|
|
1018
|
+
};
|
|
1019
|
+
TabBar.displayName = "TabBar";
|
|
1020
|
+
// src/types/mixed-tab.ts
|
|
1021
|
+
function isTabOfType(tab, contentType) {
|
|
1022
|
+
return tab.contentType === contentType;
|
|
1023
|
+
}
|
|
1024
|
+
// src/hooks/useTabKeyboardShortcuts.ts
|
|
1025
|
+
import { useEffect as useEffect2 } from "react";
|
|
1026
|
+
var useTabKeyboardShortcuts = ({
|
|
1027
|
+
onNewTab,
|
|
1028
|
+
onCloseTab,
|
|
1029
|
+
onSwitchToTab,
|
|
1030
|
+
enabled = true
|
|
1031
|
+
}) => {
|
|
1032
|
+
useEffect2(() => {
|
|
1033
|
+
if (!enabled)
|
|
1034
|
+
return;
|
|
1035
|
+
const handleKeyDown = (e) => {
|
|
1036
|
+
const isCmdOrCtrl = e.metaKey || e.ctrlKey;
|
|
1037
|
+
if (isCmdOrCtrl && e.key === "t" && onNewTab) {
|
|
1038
|
+
e.preventDefault();
|
|
1039
|
+
e.stopPropagation();
|
|
1040
|
+
onNewTab();
|
|
1041
|
+
return;
|
|
1042
|
+
}
|
|
1043
|
+
if (isCmdOrCtrl && e.key === "w" && onCloseTab) {
|
|
1044
|
+
e.preventDefault();
|
|
1045
|
+
e.stopPropagation();
|
|
1046
|
+
onCloseTab();
|
|
1047
|
+
return;
|
|
1048
|
+
}
|
|
1049
|
+
if (isCmdOrCtrl && /^[1-9]$/.test(e.key) && onSwitchToTab) {
|
|
1050
|
+
e.preventDefault();
|
|
1051
|
+
e.stopPropagation();
|
|
1052
|
+
const index = parseInt(e.key, 10) - 1;
|
|
1053
|
+
onSwitchToTab(index);
|
|
1054
|
+
return;
|
|
1055
|
+
}
|
|
1056
|
+
};
|
|
1057
|
+
window.addEventListener("keydown", handleKeyDown);
|
|
1058
|
+
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
1059
|
+
}, [enabled, onNewTab, onCloseTab, onSwitchToTab]);
|
|
1060
|
+
};
|
|
1061
|
+
// src/panels/TerminalPanel.tsx
|
|
1062
|
+
import { useTheme as useTheme5 } from "@principal-ade/industry-theme";
|
|
805
1063
|
import { Lock, Unlock, ArrowDown } from "lucide-react";
|
|
806
|
-
import { useEffect as
|
|
1064
|
+
import { useEffect as useEffect3, useRef as useRef2, useState as useState3 } from "react";
|
|
807
1065
|
|
|
808
1066
|
// src/panel-types/index.ts
|
|
809
1067
|
function getTerminalSessions(context) {
|
|
@@ -838,19 +1096,19 @@ function getTerminalSlice(context) {
|
|
|
838
1096
|
}
|
|
839
1097
|
|
|
840
1098
|
// src/panels/TerminalPanel.tsx
|
|
841
|
-
import { jsx as
|
|
1099
|
+
import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
842
1100
|
var TerminalPanel = ({
|
|
843
1101
|
context,
|
|
844
1102
|
actions,
|
|
845
1103
|
events: _events,
|
|
846
1104
|
terminalScope = "repository"
|
|
847
1105
|
}) => {
|
|
848
|
-
const { theme } =
|
|
849
|
-
const [sessionId, setSessionId] =
|
|
850
|
-
const [error, setError] =
|
|
851
|
-
const [isInitializing, setIsInitializing] =
|
|
852
|
-
const [usingMessagePort, setUsingMessagePort] =
|
|
853
|
-
const [scrollPosition, setScrollPosition] =
|
|
1106
|
+
const { theme } = useTheme5();
|
|
1107
|
+
const [sessionId, setSessionId] = useState3(null);
|
|
1108
|
+
const [error, setError] = useState3(null);
|
|
1109
|
+
const [isInitializing, setIsInitializing] = useState3(true);
|
|
1110
|
+
const [usingMessagePort, setUsingMessagePort] = useState3(false);
|
|
1111
|
+
const [scrollPosition, setScrollPosition] = useState3({
|
|
854
1112
|
isAtTop: false,
|
|
855
1113
|
isAtBottom: true,
|
|
856
1114
|
isScrollLocked: false
|
|
@@ -859,7 +1117,7 @@ var TerminalPanel = ({
|
|
|
859
1117
|
const dataPortRef = useRef2(null);
|
|
860
1118
|
const terminalDirectory = getTerminalDirectory(context, terminalScope);
|
|
861
1119
|
const pendingSessionIdRef = useRef2(null);
|
|
862
|
-
|
|
1120
|
+
useEffect3(() => {
|
|
863
1121
|
let mounted = true;
|
|
864
1122
|
let unsubscribePortReady = null;
|
|
865
1123
|
const initTerminal = async () => {
|
|
@@ -917,7 +1175,7 @@ var TerminalPanel = ({
|
|
|
917
1175
|
}
|
|
918
1176
|
};
|
|
919
1177
|
}, []);
|
|
920
|
-
|
|
1178
|
+
useEffect3(() => {
|
|
921
1179
|
if (usingMessagePort)
|
|
922
1180
|
return;
|
|
923
1181
|
if (!sessionId)
|
|
@@ -930,7 +1188,7 @@ var TerminalPanel = ({
|
|
|
930
1188
|
}, 5000);
|
|
931
1189
|
return () => clearTimeout(timeout);
|
|
932
1190
|
}, [sessionId, usingMessagePort]);
|
|
933
|
-
|
|
1191
|
+
useEffect3(() => {
|
|
934
1192
|
if (!usingMessagePort || !dataPortRef.current)
|
|
935
1193
|
return;
|
|
936
1194
|
const port = dataPortRef.current;
|
|
@@ -988,7 +1246,7 @@ var TerminalPanel = ({
|
|
|
988
1246
|
hasNotifiedPtyRef.current = true;
|
|
989
1247
|
}
|
|
990
1248
|
};
|
|
991
|
-
|
|
1249
|
+
useEffect3(() => {
|
|
992
1250
|
hasNotifiedPtyRef.current = false;
|
|
993
1251
|
}, [sessionId]);
|
|
994
1252
|
const handleScrollPositionChange = (position) => {
|
|
@@ -996,7 +1254,7 @@ var TerminalPanel = ({
|
|
|
996
1254
|
};
|
|
997
1255
|
const sessionInfo = sessionId ? getTerminalSession(context, sessionId) : undefined;
|
|
998
1256
|
if (error) {
|
|
999
|
-
return /* @__PURE__ */
|
|
1257
|
+
return /* @__PURE__ */ jsxs4("div", {
|
|
1000
1258
|
style: {
|
|
1001
1259
|
padding: "20px",
|
|
1002
1260
|
color: "#ef4444",
|
|
@@ -1009,11 +1267,11 @@ var TerminalPanel = ({
|
|
|
1009
1267
|
gap: "10px"
|
|
1010
1268
|
},
|
|
1011
1269
|
children: [
|
|
1012
|
-
/* @__PURE__ */
|
|
1270
|
+
/* @__PURE__ */ jsx5("div", {
|
|
1013
1271
|
style: { fontSize: "16px", fontWeight: "bold" },
|
|
1014
1272
|
children: "Terminal Error"
|
|
1015
1273
|
}),
|
|
1016
|
-
/* @__PURE__ */
|
|
1274
|
+
/* @__PURE__ */ jsx5("div", {
|
|
1017
1275
|
style: { fontSize: "14px", opacity: 0.8 },
|
|
1018
1276
|
children: error
|
|
1019
1277
|
})
|
|
@@ -1021,7 +1279,7 @@ var TerminalPanel = ({
|
|
|
1021
1279
|
});
|
|
1022
1280
|
}
|
|
1023
1281
|
if (isInitializing || !sessionId) {
|
|
1024
|
-
return /* @__PURE__ */
|
|
1282
|
+
return /* @__PURE__ */ jsx5("div", {
|
|
1025
1283
|
style: {
|
|
1026
1284
|
padding: "20px",
|
|
1027
1285
|
color: "#a0a0a0",
|
|
@@ -1047,10 +1305,10 @@ var TerminalPanel = ({
|
|
|
1047
1305
|
terminalRef.current?.scrollToBottom();
|
|
1048
1306
|
}
|
|
1049
1307
|
};
|
|
1050
|
-
return /* @__PURE__ */
|
|
1308
|
+
return /* @__PURE__ */ jsxs4("div", {
|
|
1051
1309
|
style: { height: "100%", width: "100%", display: "flex", flexDirection: "column" },
|
|
1052
1310
|
children: [
|
|
1053
|
-
/* @__PURE__ */
|
|
1311
|
+
/* @__PURE__ */ jsxs4("div", {
|
|
1054
1312
|
style: {
|
|
1055
1313
|
display: "flex",
|
|
1056
1314
|
gap: "8px",
|
|
@@ -1060,7 +1318,7 @@ var TerminalPanel = ({
|
|
|
1060
1318
|
alignItems: "center"
|
|
1061
1319
|
},
|
|
1062
1320
|
children: [
|
|
1063
|
-
/* @__PURE__ */
|
|
1321
|
+
/* @__PURE__ */ jsxs4("span", {
|
|
1064
1322
|
style: {
|
|
1065
1323
|
fontSize: "12px",
|
|
1066
1324
|
color: theme.colors.textSecondary,
|
|
@@ -1073,7 +1331,7 @@ var TerminalPanel = ({
|
|
|
1073
1331
|
sessionInfo?.shell
|
|
1074
1332
|
]
|
|
1075
1333
|
}),
|
|
1076
|
-
/* @__PURE__ */
|
|
1334
|
+
/* @__PURE__ */ jsxs4("button", {
|
|
1077
1335
|
onClick: handleToggleScrollLock,
|
|
1078
1336
|
style: {
|
|
1079
1337
|
display: "flex",
|
|
@@ -1092,17 +1350,17 @@ var TerminalPanel = ({
|
|
|
1092
1350
|
onMouseLeave: (e) => e.currentTarget.style.opacity = "1",
|
|
1093
1351
|
title: scrollPosition.isScrollLocked ? "Click to unlock scroll" : "Click to lock scroll to bottom",
|
|
1094
1352
|
children: [
|
|
1095
|
-
scrollPosition.isScrollLocked ? /* @__PURE__ */
|
|
1353
|
+
scrollPosition.isScrollLocked ? /* @__PURE__ */ jsx5(Lock, {
|
|
1096
1354
|
size: 12
|
|
1097
|
-
}) : /* @__PURE__ */
|
|
1355
|
+
}) : /* @__PURE__ */ jsx5(Unlock, {
|
|
1098
1356
|
size: 12
|
|
1099
1357
|
}),
|
|
1100
|
-
/* @__PURE__ */
|
|
1358
|
+
/* @__PURE__ */ jsx5("span", {
|
|
1101
1359
|
children: scrollPosition.isScrollLocked ? "Locked" : "Unlocked"
|
|
1102
1360
|
})
|
|
1103
1361
|
]
|
|
1104
1362
|
}),
|
|
1105
|
-
/* @__PURE__ */
|
|
1363
|
+
/* @__PURE__ */ jsxs4("button", {
|
|
1106
1364
|
onClick: handleScrollToBottom,
|
|
1107
1365
|
disabled: scrollPosition.isAtBottom,
|
|
1108
1366
|
style: {
|
|
@@ -1123,19 +1381,19 @@ var TerminalPanel = ({
|
|
|
1123
1381
|
onMouseLeave: (e) => !scrollPosition.isAtBottom && (e.currentTarget.style.opacity = "1"),
|
|
1124
1382
|
title: "Scroll to bottom and lock",
|
|
1125
1383
|
children: [
|
|
1126
|
-
/* @__PURE__ */
|
|
1384
|
+
/* @__PURE__ */ jsx5(ArrowDown, {
|
|
1127
1385
|
size: 12
|
|
1128
1386
|
}),
|
|
1129
|
-
/* @__PURE__ */
|
|
1387
|
+
/* @__PURE__ */ jsx5("span", {
|
|
1130
1388
|
children: "Bottom"
|
|
1131
1389
|
})
|
|
1132
1390
|
]
|
|
1133
1391
|
})
|
|
1134
1392
|
]
|
|
1135
1393
|
}),
|
|
1136
|
-
/* @__PURE__ */
|
|
1394
|
+
/* @__PURE__ */ jsx5("div", {
|
|
1137
1395
|
style: { flex: 1 },
|
|
1138
|
-
children: /* @__PURE__ */
|
|
1396
|
+
children: /* @__PURE__ */ jsx5(ThemedTerminalWithProvider, {
|
|
1139
1397
|
ref: terminalRef,
|
|
1140
1398
|
onData: handleTerminalData,
|
|
1141
1399
|
onResize: handleTerminalResize,
|
|
@@ -1153,28 +1411,28 @@ var TerminalPanel = ({
|
|
|
1153
1411
|
});
|
|
1154
1412
|
};
|
|
1155
1413
|
// src/panels/TabbedTerminalPanel.tsx
|
|
1156
|
-
import { useTheme as
|
|
1157
|
-
import { Terminal as TerminalIcon2,
|
|
1158
|
-
import
|
|
1159
|
-
useState as
|
|
1414
|
+
import { useTheme as useTheme6 } from "@principal-ade/industry-theme";
|
|
1415
|
+
import { Terminal as TerminalIcon2, Lock as Lock2, Unlock as Unlock2, Box, Boxes } from "lucide-react";
|
|
1416
|
+
import React2, {
|
|
1417
|
+
useState as useState4,
|
|
1160
1418
|
useCallback as useCallback2,
|
|
1161
|
-
useEffect as
|
|
1419
|
+
useEffect as useEffect4,
|
|
1162
1420
|
useRef as useRef3
|
|
1163
1421
|
} from "react";
|
|
1164
|
-
import { jsx as
|
|
1422
|
+
import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1165
1423
|
function TerminalTabContentInner(props, ref) {
|
|
1166
1424
|
const { tab, sessionId, isActive, isVisible, actions, events, terminalContext, onSessionCreated, onScrollPositionChange, isForeign = false } = props;
|
|
1167
1425
|
const terminalRef = useRef3(null);
|
|
1168
|
-
const [localSessionId, setLocalSessionId] =
|
|
1169
|
-
const [isInitialized, setIsInitialized] =
|
|
1426
|
+
const [localSessionId, setLocalSessionId] = useState4(sessionId);
|
|
1427
|
+
const [isInitialized, setIsInitialized] = useState4(false);
|
|
1170
1428
|
const hasInitializedRef = useRef3(false);
|
|
1171
|
-
const [scrollPosition, setScrollPosition] =
|
|
1429
|
+
const [scrollPosition, setScrollPosition] = useState4({
|
|
1172
1430
|
isAtTop: false,
|
|
1173
1431
|
isAtBottom: true,
|
|
1174
1432
|
isScrollLocked: false
|
|
1175
1433
|
});
|
|
1176
|
-
const [shouldRenderTerminal, setShouldRenderTerminal] =
|
|
1177
|
-
const [ownerWindowId, setOwnerWindowId] =
|
|
1434
|
+
const [shouldRenderTerminal, setShouldRenderTerminal] = useState4(true);
|
|
1435
|
+
const [ownerWindowId, setOwnerWindowId] = useState4(null);
|
|
1178
1436
|
const needsRefreshOnResizeRef = useRef3(false);
|
|
1179
1437
|
const claimAndConnect = useCallback2(async (targetSessionId, force = false) => {
|
|
1180
1438
|
try {
|
|
@@ -1194,7 +1452,7 @@ function TerminalTabContentInner(props, ref) {
|
|
|
1194
1452
|
throw error;
|
|
1195
1453
|
}
|
|
1196
1454
|
}, [actions]);
|
|
1197
|
-
|
|
1455
|
+
useEffect4(() => {
|
|
1198
1456
|
if (hasInitializedRef.current) {
|
|
1199
1457
|
return;
|
|
1200
1458
|
}
|
|
@@ -1239,7 +1497,7 @@ function TerminalTabContentInner(props, ref) {
|
|
|
1239
1497
|
mounted = false;
|
|
1240
1498
|
};
|
|
1241
1499
|
}, []);
|
|
1242
|
-
|
|
1500
|
+
useEffect4(() => {
|
|
1243
1501
|
if (!localSessionId || !isInitialized || !shouldRenderTerminal) {
|
|
1244
1502
|
return;
|
|
1245
1503
|
}
|
|
@@ -1291,7 +1549,7 @@ function TerminalTabContentInner(props, ref) {
|
|
|
1291
1549
|
});
|
|
1292
1550
|
}
|
|
1293
1551
|
}, [localSessionId, events]);
|
|
1294
|
-
|
|
1552
|
+
useEffect4(() => {
|
|
1295
1553
|
if (!localSessionId || !actions.onOwnershipLost) {
|
|
1296
1554
|
return;
|
|
1297
1555
|
}
|
|
@@ -1341,12 +1599,12 @@ function TerminalTabContentInner(props, ref) {
|
|
|
1341
1599
|
terminalRef.current?.scrollToBottom();
|
|
1342
1600
|
}
|
|
1343
1601
|
}, [scrollPosition.isScrollLocked]);
|
|
1344
|
-
|
|
1602
|
+
React2.useImperativeHandle(ref, () => ({
|
|
1345
1603
|
scrollToBottom: handleScrollToBottom,
|
|
1346
1604
|
toggleScrollLock: handleToggleScrollLock
|
|
1347
1605
|
}), [handleScrollToBottom, handleToggleScrollLock]);
|
|
1348
1606
|
if (!isInitialized) {
|
|
1349
|
-
return /* @__PURE__ */
|
|
1607
|
+
return /* @__PURE__ */ jsx6("div", {
|
|
1350
1608
|
style: {
|
|
1351
1609
|
display: isActive ? "flex" : "none",
|
|
1352
1610
|
height: "100%",
|
|
@@ -1369,14 +1627,14 @@ function TerminalTabContentInner(props, ref) {
|
|
|
1369
1627
|
],
|
|
1370
1628
|
opacity: 1
|
|
1371
1629
|
} : undefined;
|
|
1372
|
-
return /* @__PURE__ */
|
|
1630
|
+
return /* @__PURE__ */ jsx6("div", {
|
|
1373
1631
|
style: {
|
|
1374
1632
|
display: isActive ? "flex" : "none",
|
|
1375
1633
|
flexDirection: "column",
|
|
1376
1634
|
height: "100%",
|
|
1377
1635
|
width: "100%"
|
|
1378
1636
|
},
|
|
1379
|
-
children: /* @__PURE__ */
|
|
1637
|
+
children: /* @__PURE__ */ jsx6(ThemedTerminalWithProvider, {
|
|
1380
1638
|
ref: terminalRef,
|
|
1381
1639
|
onData: shouldRenderTerminal ? handleData : undefined,
|
|
1382
1640
|
onResize: shouldRenderTerminal ? handleResize : undefined,
|
|
@@ -1397,7 +1655,7 @@ function TerminalTabContentInner(props, ref) {
|
|
|
1397
1655
|
});
|
|
1398
1656
|
}
|
|
1399
1657
|
var areTerminalTabContentPropsEqual = (prevProps, nextProps) => {
|
|
1400
|
-
const tabEqual = prevProps.tab.id === nextProps.tab.id && prevProps.tab.directory === nextProps.tab.directory && prevProps.tab.
|
|
1658
|
+
const tabEqual = prevProps.tab.id === nextProps.tab.id && prevProps.tab.directory === nextProps.tab.directory && prevProps.tab.label === nextProps.tab.label;
|
|
1401
1659
|
const changes = [];
|
|
1402
1660
|
if (!tabEqual)
|
|
1403
1661
|
changes.push("tab");
|
|
@@ -1413,8 +1671,8 @@ var areTerminalTabContentPropsEqual = (prevProps, nextProps) => {
|
|
|
1413
1671
|
changes.push("isForeign");
|
|
1414
1672
|
return changes.length === 0;
|
|
1415
1673
|
};
|
|
1416
|
-
var TerminalTabContentForwarded =
|
|
1417
|
-
var TerminalTabContent =
|
|
1674
|
+
var TerminalTabContentForwarded = React2.forwardRef(TerminalTabContentInner);
|
|
1675
|
+
var TerminalTabContent = React2.memo(TerminalTabContentForwarded, areTerminalTabContentPropsEqual);
|
|
1418
1676
|
TerminalTabContent.displayName = "TerminalTabContent";
|
|
1419
1677
|
var TabbedTerminalPanelInner = ({
|
|
1420
1678
|
context: _context,
|
|
@@ -1428,22 +1686,22 @@ var TabbedTerminalPanelInner = ({
|
|
|
1428
1686
|
initialTabs = [],
|
|
1429
1687
|
showAllTerminals = false,
|
|
1430
1688
|
onShowAllTerminalsChange,
|
|
1431
|
-
tabLabelPrefix
|
|
1689
|
+
tabLabelPrefix,
|
|
1690
|
+
renderTabContent
|
|
1432
1691
|
}) => {
|
|
1433
|
-
const { theme } =
|
|
1434
|
-
const [ownedTabs, setOwnedTabs] =
|
|
1435
|
-
const [foreignTabs, setForeignTabs] =
|
|
1436
|
-
const [activeTabId, setActiveTabId] =
|
|
1437
|
-
const [sessionIds, setSessionIds] =
|
|
1438
|
-
const [
|
|
1439
|
-
const
|
|
1440
|
-
const getOwnedTabLabel = useCallback2((index, directory2) => {
|
|
1692
|
+
const { theme } = useTheme6();
|
|
1693
|
+
const [ownedTabs, setOwnedTabs] = useState4(initialTabs);
|
|
1694
|
+
const [foreignTabs, setForeignTabs] = useState4([]);
|
|
1695
|
+
const [activeTabId, setActiveTabId] = useState4(null);
|
|
1696
|
+
const [sessionIds, setSessionIds] = useState4(new Map);
|
|
1697
|
+
const [scrollPositions, setScrollPositions] = useState4(new Map);
|
|
1698
|
+
const getOwnedTabLabel = useCallback2((index, _directory) => {
|
|
1441
1699
|
if (tabLabelPrefix) {
|
|
1442
1700
|
return `${tabLabelPrefix} ${index + 1}`;
|
|
1443
1701
|
}
|
|
1444
|
-
return
|
|
1702
|
+
return `⌘ ${index + 1}`;
|
|
1445
1703
|
}, [tabLabelPrefix]);
|
|
1446
|
-
const tabs =
|
|
1704
|
+
const tabs = React2.useMemo(() => {
|
|
1447
1705
|
const labeledOwnedTabs = ownedTabs.map((tab, index) => ({
|
|
1448
1706
|
...tab,
|
|
1449
1707
|
label: getOwnedTabLabel(index, tab.directory)
|
|
@@ -1451,6 +1709,18 @@ var TabbedTerminalPanelInner = ({
|
|
|
1451
1709
|
const sortedForeignTabs = [...foreignTabs].sort((a, b) => a.label.localeCompare(b.label));
|
|
1452
1710
|
return [...labeledOwnedTabs, ...sortedForeignTabs];
|
|
1453
1711
|
}, [ownedTabs, foreignTabs, getOwnedTabLabel]);
|
|
1712
|
+
const genericTabs = React2.useMemo(() => {
|
|
1713
|
+
return tabs.map((tab) => ({
|
|
1714
|
+
id: tab.id,
|
|
1715
|
+
label: tab.label,
|
|
1716
|
+
closable: true,
|
|
1717
|
+
contentType: tab.contentType,
|
|
1718
|
+
metadata: {
|
|
1719
|
+
...tab.directory && { directory: tab.directory },
|
|
1720
|
+
...tab.command && { command: tab.command }
|
|
1721
|
+
}
|
|
1722
|
+
}));
|
|
1723
|
+
}, [tabs]);
|
|
1454
1724
|
const tabRefsMap = useRef3(new Map);
|
|
1455
1725
|
const refCallbacksMap = useRef3(new Map);
|
|
1456
1726
|
const getRefCallback = useCallback2((tabId) => {
|
|
@@ -1493,14 +1763,15 @@ var TabbedTerminalPanelInner = ({
|
|
|
1493
1763
|
if (ownedSessions.length > 0 && initialTabs.length === 0) {
|
|
1494
1764
|
const restoredTabs = [];
|
|
1495
1765
|
const restoredSessionIds = new Map;
|
|
1496
|
-
ownedSessions.forEach((session
|
|
1766
|
+
ownedSessions.forEach((session) => {
|
|
1497
1767
|
const tabId = `tab-restored-${session.id}`;
|
|
1498
1768
|
const sessionCwd = session.cwd || directory;
|
|
1499
1769
|
const tab = {
|
|
1500
1770
|
id: tabId,
|
|
1501
1771
|
label: sessionCwd.split("/").pop() || sessionCwd,
|
|
1772
|
+
contentType: "terminal",
|
|
1502
1773
|
directory: sessionCwd,
|
|
1503
|
-
|
|
1774
|
+
closable: true
|
|
1504
1775
|
};
|
|
1505
1776
|
restoredTabs.push(tab);
|
|
1506
1777
|
restoredSessionIds.set(tabId, session.id);
|
|
@@ -1511,7 +1782,7 @@ var TabbedTerminalPanelInner = ({
|
|
|
1511
1782
|
onTabsChange?.(restoredTabs);
|
|
1512
1783
|
} else if (initialTabs.length > 0) {
|
|
1513
1784
|
setOwnedTabs(initialTabs);
|
|
1514
|
-
setActiveTabId(initialTabs
|
|
1785
|
+
setActiveTabId(initialTabs[0]?.id || null);
|
|
1515
1786
|
}
|
|
1516
1787
|
} catch (err) {
|
|
1517
1788
|
console.error("[TabbedTerminalPanel] Failed to restore owned sessions:", err);
|
|
@@ -1532,8 +1803,9 @@ var TabbedTerminalPanelInner = ({
|
|
|
1532
1803
|
const tab = {
|
|
1533
1804
|
id: tabId,
|
|
1534
1805
|
label: sessionCwd.split("/").pop() || sessionCwd,
|
|
1806
|
+
contentType: "terminal",
|
|
1535
1807
|
directory: sessionCwd,
|
|
1536
|
-
|
|
1808
|
+
closable: true
|
|
1537
1809
|
};
|
|
1538
1810
|
foreignTabsList.push(tab);
|
|
1539
1811
|
newSessionIds.set(tabId, session.id);
|
|
@@ -1559,13 +1831,13 @@ var TabbedTerminalPanelInner = ({
|
|
|
1559
1831
|
return [];
|
|
1560
1832
|
});
|
|
1561
1833
|
}, []);
|
|
1562
|
-
|
|
1834
|
+
useEffect4(() => {
|
|
1563
1835
|
if (hasInitializedRef.current)
|
|
1564
1836
|
return;
|
|
1565
1837
|
hasInitializedRef.current = true;
|
|
1566
1838
|
restoreOwnedSessions();
|
|
1567
1839
|
}, []);
|
|
1568
|
-
|
|
1840
|
+
useEffect4(() => {
|
|
1569
1841
|
const handleSessionCreated2 = (event) => {
|
|
1570
1842
|
const customEvent = event;
|
|
1571
1843
|
const { context } = customEvent.detail || {};
|
|
@@ -1579,7 +1851,7 @@ var TabbedTerminalPanelInner = ({
|
|
|
1579
1851
|
window.removeEventListener("terminal-session-created", handleSessionCreated2);
|
|
1580
1852
|
};
|
|
1581
1853
|
}, [terminalContext, restoreOwnedSessions]);
|
|
1582
|
-
|
|
1854
|
+
useEffect4(() => {
|
|
1583
1855
|
if (showAllTerminals) {
|
|
1584
1856
|
fetchForeignSessions();
|
|
1585
1857
|
} else {
|
|
@@ -1603,17 +1875,16 @@ var TabbedTerminalPanelInner = ({
|
|
|
1603
1875
|
const newTab = {
|
|
1604
1876
|
id: `tab-${Date.now()}`,
|
|
1605
1877
|
label: label || directoryName,
|
|
1878
|
+
contentType: "terminal",
|
|
1606
1879
|
directory: targetDir,
|
|
1607
1880
|
command,
|
|
1608
|
-
|
|
1881
|
+
closable: true
|
|
1609
1882
|
};
|
|
1610
1883
|
setOwnedTabs((prevTabs) => {
|
|
1611
|
-
const
|
|
1612
|
-
const newTabs = [...updatedTabs, newTab];
|
|
1884
|
+
const newTabs = [...prevTabs, newTab];
|
|
1613
1885
|
onTabsChange?.(newTabs);
|
|
1614
1886
|
return newTabs;
|
|
1615
1887
|
});
|
|
1616
|
-
setForeignTabs((prevTabs) => prevTabs.map((t) => ({ ...t, isActive: false })));
|
|
1617
1888
|
setActiveTabId(newTab.id);
|
|
1618
1889
|
}, [directory, onTabsChange]);
|
|
1619
1890
|
const isForeignTab = useCallback2((tabId) => {
|
|
@@ -1648,11 +1919,8 @@ var TabbedTerminalPanelInner = ({
|
|
|
1648
1919
|
const nextActiveId = findNextActiveTab([...ownedTabs, ...newTabs]);
|
|
1649
1920
|
if (nextActiveId !== activeTabId) {
|
|
1650
1921
|
setActiveTabId(nextActiveId);
|
|
1651
|
-
if (nextActiveId) {
|
|
1652
|
-
setOwnedTabs((owned) => owned.map((t) => ({ ...t, isActive: t.id === nextActiveId })));
|
|
1653
|
-
}
|
|
1654
1922
|
}
|
|
1655
|
-
return newTabs
|
|
1923
|
+
return newTabs;
|
|
1656
1924
|
});
|
|
1657
1925
|
} else {
|
|
1658
1926
|
setOwnedTabs((prevTabs) => {
|
|
@@ -1660,71 +1928,74 @@ var TabbedTerminalPanelInner = ({
|
|
|
1660
1928
|
const nextActiveId = findNextActiveTab([...newTabs, ...foreignTabs]);
|
|
1661
1929
|
if (nextActiveId !== activeTabId) {
|
|
1662
1930
|
setActiveTabId(nextActiveId);
|
|
1663
|
-
if (nextActiveId) {
|
|
1664
|
-
setForeignTabs((foreign) => foreign.map((t) => ({ ...t, isActive: t.id === nextActiveId })));
|
|
1665
|
-
}
|
|
1666
1931
|
}
|
|
1667
1932
|
onTabsChange?.(newTabs);
|
|
1668
|
-
return newTabs
|
|
1933
|
+
return newTabs;
|
|
1669
1934
|
});
|
|
1670
1935
|
}
|
|
1671
1936
|
}, [activeTabId, sessionIds, actions, onTabsChange, isForeignTab, ownedTabs, foreignTabs]);
|
|
1672
1937
|
const handleSessionCreated = useCallback2((tabId, sessionId) => {
|
|
1673
1938
|
setSessionIds((prev) => new Map(prev).set(tabId, sessionId));
|
|
1674
1939
|
}, []);
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
const closeTabRef = useRef3(closeTab);
|
|
1679
|
-
const switchTabRef = useRef3(switchTab);
|
|
1680
|
-
useEffect3(() => {
|
|
1681
|
-
tabsRef.current = tabs;
|
|
1682
|
-
activeTabIdRef.current = activeTabId;
|
|
1683
|
-
addNewTabRef.current = addNewTab;
|
|
1684
|
-
closeTabRef.current = closeTab;
|
|
1685
|
-
switchTabRef.current = switchTab;
|
|
1686
|
-
}, [tabs, activeTabId, addNewTab, closeTab, switchTab]);
|
|
1687
|
-
useEffect3(() => {
|
|
1688
|
-
const handleKeyDown = (e) => {
|
|
1689
|
-
if ((e.metaKey || e.ctrlKey) && e.key === "t") {
|
|
1690
|
-
e.preventDefault();
|
|
1691
|
-
e.stopPropagation();
|
|
1692
|
-
if (isCreatingTabRef.current)
|
|
1693
|
-
return;
|
|
1694
|
-
isCreatingTabRef.current = true;
|
|
1695
|
-
addNewTabRef.current?.();
|
|
1696
|
-
setTimeout(() => {
|
|
1697
|
-
isCreatingTabRef.current = false;
|
|
1698
|
-
}, 500);
|
|
1699
|
-
return;
|
|
1700
|
-
}
|
|
1701
|
-
if ((e.metaKey || e.ctrlKey) && e.key === "w") {
|
|
1702
|
-
const currentActiveTabId = activeTabIdRef.current;
|
|
1703
|
-
const currentTabs = tabsRef.current;
|
|
1704
|
-
if (currentActiveTabId && currentTabs.length > 0) {
|
|
1705
|
-
e.preventDefault();
|
|
1706
|
-
e.stopPropagation();
|
|
1707
|
-
closeTabRef.current?.(currentActiveTabId);
|
|
1708
|
-
}
|
|
1940
|
+
useTabKeyboardShortcuts({
|
|
1941
|
+
onNewTab: () => {
|
|
1942
|
+
if (isCreatingTabRef.current)
|
|
1709
1943
|
return;
|
|
1944
|
+
isCreatingTabRef.current = true;
|
|
1945
|
+
addNewTab();
|
|
1946
|
+
setTimeout(() => {
|
|
1947
|
+
isCreatingTabRef.current = false;
|
|
1948
|
+
}, 500);
|
|
1949
|
+
},
|
|
1950
|
+
onCloseTab: () => {
|
|
1951
|
+
if (activeTabId && tabs.length > 0) {
|
|
1952
|
+
closeTab(activeTabId);
|
|
1710
1953
|
}
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
if (tabIndex >= 0 && tabIndex < currentTabs.length) {
|
|
1717
|
-
const targetTab = currentTabs[tabIndex];
|
|
1718
|
-
if (targetTab) {
|
|
1719
|
-
switchTabRef.current?.(targetTab.id);
|
|
1720
|
-
}
|
|
1721
|
-
}
|
|
1954
|
+
},
|
|
1955
|
+
onSwitchToTab: (index) => {
|
|
1956
|
+
const tabIndex = index === 8 && tabs.length > 9 ? tabs.length - 1 : index;
|
|
1957
|
+
if (tabIndex >= 0 && tabIndex < tabs.length) {
|
|
1958
|
+
switchTab(tabs[tabIndex].id);
|
|
1722
1959
|
}
|
|
1723
|
-
}
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1960
|
+
}
|
|
1961
|
+
});
|
|
1962
|
+
const renderTabAccessory = useCallback2((tab) => {
|
|
1963
|
+
if (tab.id !== activeTabId)
|
|
1964
|
+
return null;
|
|
1965
|
+
const scrollPosition = scrollPositions.get(tab.id) ?? defaultScrollPosition;
|
|
1966
|
+
return /* @__PURE__ */ jsx6("button", {
|
|
1967
|
+
onClick: (e) => {
|
|
1968
|
+
e.stopPropagation();
|
|
1969
|
+
handleToggleScrollLock();
|
|
1970
|
+
},
|
|
1971
|
+
style: {
|
|
1972
|
+
display: "flex",
|
|
1973
|
+
alignItems: "center",
|
|
1974
|
+
justifyContent: "center",
|
|
1975
|
+
width: "16px",
|
|
1976
|
+
height: "16px",
|
|
1977
|
+
borderRadius: "3px",
|
|
1978
|
+
border: "none",
|
|
1979
|
+
backgroundColor: "transparent",
|
|
1980
|
+
cursor: "pointer",
|
|
1981
|
+
color: scrollPosition.isScrollLocked ? theme.colors.success : theme.colors.warning,
|
|
1982
|
+
padding: 0
|
|
1983
|
+
},
|
|
1984
|
+
onMouseEnter: (e) => {
|
|
1985
|
+
e.currentTarget.style.backgroundColor = theme.colors.backgroundTertiary;
|
|
1986
|
+
},
|
|
1987
|
+
onMouseLeave: (e) => {
|
|
1988
|
+
e.currentTarget.style.backgroundColor = "transparent";
|
|
1989
|
+
},
|
|
1990
|
+
title: scrollPosition.isScrollLocked ? "Scroll locked" : "Scroll unlocked",
|
|
1991
|
+
children: scrollPosition.isScrollLocked ? /* @__PURE__ */ jsx6(Lock2, {
|
|
1992
|
+
size: 10
|
|
1993
|
+
}) : /* @__PURE__ */ jsx6(Unlock2, {
|
|
1994
|
+
size: 10
|
|
1995
|
+
})
|
|
1996
|
+
});
|
|
1997
|
+
}, [activeTabId, scrollPositions, defaultScrollPosition, handleToggleScrollLock, theme]);
|
|
1998
|
+
return /* @__PURE__ */ jsxs5("div", {
|
|
1728
1999
|
style: {
|
|
1729
2000
|
display: "flex",
|
|
1730
2001
|
flexDirection: "column",
|
|
@@ -1732,205 +2003,50 @@ var TabbedTerminalPanelInner = ({
|
|
|
1732
2003
|
backgroundColor: theme.colors.background
|
|
1733
2004
|
},
|
|
1734
2005
|
children: [
|
|
1735
|
-
!hideHeader && /* @__PURE__ */
|
|
2006
|
+
!hideHeader && /* @__PURE__ */ jsx6("div", {
|
|
1736
2007
|
ref: headerRef,
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
/* @__PURE__ */ jsx4("div", {
|
|
1746
|
-
style: {
|
|
1747
|
-
display: "flex",
|
|
1748
|
-
alignItems: "center",
|
|
1749
|
-
gap: "4px",
|
|
1750
|
-
padding: "0 8px",
|
|
1751
|
-
borderRight: `1px solid ${theme.colors.border}`,
|
|
1752
|
-
borderBottom: `1px solid ${theme.colors.border}`,
|
|
1753
|
-
boxSizing: "border-box"
|
|
1754
|
-
},
|
|
1755
|
-
children: /* @__PURE__ */ jsx4("button", {
|
|
1756
|
-
onClick: () => onShowAllTerminalsChange?.(!showAllTerminals),
|
|
1757
|
-
style: {
|
|
1758
|
-
display: "flex",
|
|
1759
|
-
alignItems: "center",
|
|
1760
|
-
justifyContent: "center",
|
|
1761
|
-
width: "28px",
|
|
1762
|
-
height: "28px",
|
|
1763
|
-
border: "none",
|
|
1764
|
-
borderRadius: "4px",
|
|
1765
|
-
backgroundColor: showAllTerminals ? `${theme.colors.primary}22` : "transparent",
|
|
1766
|
-
cursor: "pointer",
|
|
1767
|
-
color: showAllTerminals ? theme.colors.primary : theme.colors.textSecondary
|
|
1768
|
-
},
|
|
1769
|
-
onMouseEnter: (e) => {
|
|
1770
|
-
if (!showAllTerminals) {
|
|
1771
|
-
e.currentTarget.style.backgroundColor = theme.colors.backgroundTertiary;
|
|
1772
|
-
}
|
|
1773
|
-
},
|
|
1774
|
-
onMouseLeave: (e) => {
|
|
1775
|
-
if (!showAllTerminals) {
|
|
1776
|
-
e.currentTarget.style.backgroundColor = "transparent";
|
|
1777
|
-
}
|
|
1778
|
-
},
|
|
1779
|
-
title: showAllTerminals ? "Showing all terminals (click to filter by context)" : "Show all terminals",
|
|
1780
|
-
children: showAllTerminals ? /* @__PURE__ */ jsx4(Boxes, {
|
|
1781
|
-
size: 14
|
|
1782
|
-
}) : /* @__PURE__ */ jsx4(Box, {
|
|
1783
|
-
size: 14
|
|
1784
|
-
})
|
|
1785
|
-
})
|
|
1786
|
-
}),
|
|
1787
|
-
/* @__PURE__ */ jsx4("div", {
|
|
1788
|
-
style: {
|
|
1789
|
-
display: "flex",
|
|
1790
|
-
alignItems: "center",
|
|
1791
|
-
flex: 1,
|
|
1792
|
-
overflow: "hidden",
|
|
1793
|
-
borderBottom: `1px solid ${theme.colors.border}`,
|
|
1794
|
-
boxSizing: "border-box"
|
|
1795
|
-
},
|
|
1796
|
-
children: tabs.map((tab) => /* @__PURE__ */ jsxs3("div", {
|
|
1797
|
-
onClick: (e) => {
|
|
1798
|
-
e.stopPropagation();
|
|
1799
|
-
switchTab(tab.id);
|
|
1800
|
-
},
|
|
1801
|
-
onMouseEnter: () => setHoveredTabId(tab.id),
|
|
1802
|
-
onMouseLeave: () => setHoveredTabId(null),
|
|
1803
|
-
style: {
|
|
1804
|
-
display: "flex",
|
|
1805
|
-
alignItems: "center",
|
|
1806
|
-
justifyContent: "center",
|
|
1807
|
-
gap: "6px",
|
|
1808
|
-
padding: "6px 8px",
|
|
1809
|
-
backgroundColor: tab.isActive ? theme.colors.background : theme.colors.backgroundSecondary,
|
|
1810
|
-
borderBottom: "none",
|
|
1811
|
-
cursor: "pointer",
|
|
1812
|
-
fontSize: theme.fontSizes[1],
|
|
1813
|
-
fontWeight: tab.isActive ? theme.fontWeights.semibold : theme.fontWeights.body,
|
|
1814
|
-
fontFamily: theme.fonts.body,
|
|
1815
|
-
color: tab.isActive ? theme.colors.text : theme.colors.textSecondary,
|
|
1816
|
-
whiteSpace: "nowrap",
|
|
1817
|
-
transition: "all 0.2s",
|
|
1818
|
-
flex: 1,
|
|
1819
|
-
minWidth: 0,
|
|
1820
|
-
height: "100%",
|
|
1821
|
-
position: "relative",
|
|
1822
|
-
boxSizing: "border-box"
|
|
1823
|
-
},
|
|
1824
|
-
children: [
|
|
1825
|
-
hoveredTabId === tab.id && /* @__PURE__ */ jsx4("button", {
|
|
1826
|
-
onClick: (e) => {
|
|
1827
|
-
e.stopPropagation();
|
|
1828
|
-
closeTab(tab.id);
|
|
1829
|
-
},
|
|
1830
|
-
style: {
|
|
1831
|
-
display: "flex",
|
|
1832
|
-
alignItems: "center",
|
|
1833
|
-
justifyContent: "center",
|
|
1834
|
-
width: "16px",
|
|
1835
|
-
height: "16px",
|
|
1836
|
-
borderRadius: "3px",
|
|
1837
|
-
border: "none",
|
|
1838
|
-
backgroundColor: "transparent",
|
|
1839
|
-
cursor: "pointer",
|
|
1840
|
-
color: theme.colors.textSecondary,
|
|
1841
|
-
padding: 0,
|
|
1842
|
-
position: "absolute",
|
|
1843
|
-
left: "8px"
|
|
1844
|
-
},
|
|
1845
|
-
onMouseEnter: (e) => {
|
|
1846
|
-
e.currentTarget.style.backgroundColor = theme.colors.backgroundTertiary;
|
|
1847
|
-
},
|
|
1848
|
-
onMouseLeave: (e) => {
|
|
1849
|
-
e.currentTarget.style.backgroundColor = "transparent";
|
|
1850
|
-
},
|
|
1851
|
-
children: /* @__PURE__ */ jsx4(X2, {
|
|
1852
|
-
size: 12
|
|
1853
|
-
})
|
|
1854
|
-
}),
|
|
1855
|
-
/* @__PURE__ */ jsx4("span", {
|
|
1856
|
-
title: tab.directory,
|
|
1857
|
-
children: tab.label
|
|
1858
|
-
}),
|
|
1859
|
-
tab.isActive && /* @__PURE__ */ jsx4("button", {
|
|
1860
|
-
onClick: (e) => {
|
|
1861
|
-
e.stopPropagation();
|
|
1862
|
-
handleToggleScrollLock();
|
|
1863
|
-
},
|
|
1864
|
-
style: {
|
|
1865
|
-
display: "flex",
|
|
1866
|
-
alignItems: "center",
|
|
1867
|
-
justifyContent: "center",
|
|
1868
|
-
width: "16px",
|
|
1869
|
-
height: "16px",
|
|
1870
|
-
borderRadius: "3px",
|
|
1871
|
-
border: "none",
|
|
1872
|
-
backgroundColor: "transparent",
|
|
1873
|
-
cursor: "pointer",
|
|
1874
|
-
color: (scrollPositions.get(tab.id) ?? defaultScrollPosition).isScrollLocked ? theme.colors.success : theme.colors.warning,
|
|
1875
|
-
padding: 0,
|
|
1876
|
-
position: "absolute",
|
|
1877
|
-
right: "8px"
|
|
1878
|
-
},
|
|
1879
|
-
onMouseEnter: (e) => {
|
|
1880
|
-
e.currentTarget.style.backgroundColor = theme.colors.backgroundTertiary;
|
|
1881
|
-
},
|
|
1882
|
-
onMouseLeave: (e) => {
|
|
1883
|
-
e.currentTarget.style.backgroundColor = "transparent";
|
|
1884
|
-
},
|
|
1885
|
-
title: (scrollPositions.get(tab.id) ?? defaultScrollPosition).isScrollLocked ? "Scroll locked" : "Scroll unlocked",
|
|
1886
|
-
children: (scrollPositions.get(tab.id) ?? defaultScrollPosition).isScrollLocked ? /* @__PURE__ */ jsx4(Lock2, {
|
|
1887
|
-
size: 10
|
|
1888
|
-
}) : /* @__PURE__ */ jsx4(Unlock2, {
|
|
1889
|
-
size: 10
|
|
1890
|
-
})
|
|
1891
|
-
})
|
|
1892
|
-
]
|
|
1893
|
-
}, tab.id))
|
|
1894
|
-
}),
|
|
1895
|
-
/* @__PURE__ */ jsx4("div", {
|
|
2008
|
+
children: /* @__PURE__ */ jsx6(TabBar, {
|
|
2009
|
+
tabs: genericTabs,
|
|
2010
|
+
activeTabId,
|
|
2011
|
+
onTabClick: switchTab,
|
|
2012
|
+
onTabClose: closeTab,
|
|
2013
|
+
onNewTab: addNewTab,
|
|
2014
|
+
leftSection: /* @__PURE__ */ jsx6("button", {
|
|
2015
|
+
onClick: () => onShowAllTerminalsChange?.(!showAllTerminals),
|
|
1896
2016
|
style: {
|
|
1897
2017
|
display: "flex",
|
|
1898
2018
|
alignItems: "center",
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
2019
|
+
justifyContent: "center",
|
|
2020
|
+
width: "28px",
|
|
2021
|
+
height: "28px",
|
|
2022
|
+
border: "none",
|
|
2023
|
+
borderRadius: "4px",
|
|
2024
|
+
backgroundColor: showAllTerminals ? `${theme.colors.primary}22` : "transparent",
|
|
2025
|
+
cursor: "pointer",
|
|
2026
|
+
color: showAllTerminals ? theme.colors.primary : theme.colors.textSecondary
|
|
1904
2027
|
},
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
style: {
|
|
1908
|
-
display: "flex",
|
|
1909
|
-
alignItems: "center",
|
|
1910
|
-
justifyContent: "center",
|
|
1911
|
-
width: "28px",
|
|
1912
|
-
height: "28px",
|
|
1913
|
-
border: "none",
|
|
1914
|
-
borderRadius: "4px",
|
|
1915
|
-
backgroundColor: "transparent",
|
|
1916
|
-
cursor: "pointer",
|
|
1917
|
-
color: theme.colors.textSecondary
|
|
1918
|
-
},
|
|
1919
|
-
onMouseEnter: (e) => {
|
|
2028
|
+
onMouseEnter: (e) => {
|
|
2029
|
+
if (!showAllTerminals) {
|
|
1920
2030
|
e.currentTarget.style.backgroundColor = theme.colors.backgroundTertiary;
|
|
1921
|
-
}
|
|
1922
|
-
|
|
2031
|
+
}
|
|
2032
|
+
},
|
|
2033
|
+
onMouseLeave: (e) => {
|
|
2034
|
+
if (!showAllTerminals) {
|
|
1923
2035
|
e.currentTarget.style.backgroundColor = "transparent";
|
|
1924
|
-
}
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
2036
|
+
}
|
|
2037
|
+
},
|
|
2038
|
+
title: showAllTerminals ? "Showing all terminals (click to filter by context)" : "Show all terminals",
|
|
2039
|
+
children: showAllTerminals ? /* @__PURE__ */ jsx6(Boxes, {
|
|
2040
|
+
size: 14
|
|
2041
|
+
}) : /* @__PURE__ */ jsx6(Box, {
|
|
2042
|
+
size: 14
|
|
1929
2043
|
})
|
|
1930
|
-
})
|
|
1931
|
-
|
|
2044
|
+
}),
|
|
2045
|
+
renderTabAccessory,
|
|
2046
|
+
showKeyboardHints: false
|
|
2047
|
+
})
|
|
1932
2048
|
}),
|
|
1933
|
-
/* @__PURE__ */
|
|
2049
|
+
/* @__PURE__ */ jsxs5("div", {
|
|
1934
2050
|
style: {
|
|
1935
2051
|
flex: 1,
|
|
1936
2052
|
display: "flex",
|
|
@@ -1940,20 +2056,74 @@ var TabbedTerminalPanelInner = ({
|
|
|
1940
2056
|
minHeight: 0
|
|
1941
2057
|
},
|
|
1942
2058
|
children: [
|
|
1943
|
-
tabs.map((tab) =>
|
|
1944
|
-
|
|
1945
|
-
tab
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
2059
|
+
tabs.map((tab) => {
|
|
2060
|
+
const isActive = tab.id === activeTabId;
|
|
2061
|
+
const sessionId = sessionIds.get(tab.id) || null;
|
|
2062
|
+
if (renderTabContent) {
|
|
2063
|
+
const customContent = renderTabContent(tab, isActive, sessionId);
|
|
2064
|
+
if (customContent === null && tab.contentType === "terminal") {
|
|
2065
|
+
return /* @__PURE__ */ jsx6(TerminalTabContent, {
|
|
2066
|
+
ref: getRefCallback(tab.id),
|
|
2067
|
+
tab,
|
|
2068
|
+
sessionId,
|
|
2069
|
+
isActive,
|
|
2070
|
+
isVisible,
|
|
2071
|
+
actions,
|
|
2072
|
+
events,
|
|
2073
|
+
terminalContext,
|
|
2074
|
+
onSessionCreated: handleSessionCreated,
|
|
2075
|
+
onScrollPositionChange: handleTabScrollPositionChange,
|
|
2076
|
+
isForeign: tab.id.startsWith("tab-foreign-")
|
|
2077
|
+
}, tab.id);
|
|
2078
|
+
}
|
|
2079
|
+
return /* @__PURE__ */ jsx6("div", {
|
|
2080
|
+
style: {
|
|
2081
|
+
display: isActive ? "flex" : "none",
|
|
2082
|
+
flexDirection: "column",
|
|
2083
|
+
height: "100%",
|
|
2084
|
+
width: "100%"
|
|
2085
|
+
},
|
|
2086
|
+
children: customContent
|
|
2087
|
+
}, tab.id);
|
|
2088
|
+
}
|
|
2089
|
+
if (tab.contentType === "terminal") {
|
|
2090
|
+
return /* @__PURE__ */ jsx6(TerminalTabContent, {
|
|
2091
|
+
ref: getRefCallback(tab.id),
|
|
2092
|
+
tab,
|
|
2093
|
+
sessionId,
|
|
2094
|
+
isActive,
|
|
2095
|
+
isVisible,
|
|
2096
|
+
actions,
|
|
2097
|
+
events,
|
|
2098
|
+
terminalContext,
|
|
2099
|
+
onSessionCreated: handleSessionCreated,
|
|
2100
|
+
onScrollPositionChange: handleTabScrollPositionChange,
|
|
2101
|
+
isForeign: tab.id.startsWith("tab-foreign-")
|
|
2102
|
+
}, tab.id);
|
|
2103
|
+
}
|
|
2104
|
+
return /* @__PURE__ */ jsxs5("div", {
|
|
2105
|
+
style: {
|
|
2106
|
+
display: isActive ? "flex" : "none",
|
|
2107
|
+
alignItems: "center",
|
|
2108
|
+
justifyContent: "center",
|
|
2109
|
+
height: "100%",
|
|
2110
|
+
color: theme.colors.textSecondary
|
|
2111
|
+
},
|
|
2112
|
+
children: [
|
|
2113
|
+
/* @__PURE__ */ jsxs5("p", {
|
|
2114
|
+
children: [
|
|
2115
|
+
"Unknown content type: ",
|
|
2116
|
+
tab.contentType
|
|
2117
|
+
]
|
|
2118
|
+
}),
|
|
2119
|
+
/* @__PURE__ */ jsx6("p", {
|
|
2120
|
+
style: { fontSize: theme.fontSizes[0], marginTop: "8px" },
|
|
2121
|
+
children: "Provide a renderTabContent prop to render custom tab types"
|
|
2122
|
+
})
|
|
2123
|
+
]
|
|
2124
|
+
}, tab.id);
|
|
2125
|
+
}),
|
|
2126
|
+
tabs.length === 0 && /* @__PURE__ */ jsxs5("div", {
|
|
1957
2127
|
style: {
|
|
1958
2128
|
display: "flex",
|
|
1959
2129
|
flexDirection: "column",
|
|
@@ -1963,14 +2133,14 @@ var TabbedTerminalPanelInner = ({
|
|
|
1963
2133
|
color: theme.colors.textSecondary
|
|
1964
2134
|
},
|
|
1965
2135
|
children: [
|
|
1966
|
-
/* @__PURE__ */
|
|
2136
|
+
/* @__PURE__ */ jsx6(TerminalIcon2, {
|
|
1967
2137
|
size: 32,
|
|
1968
2138
|
style: { opacity: 0.5, marginBottom: "16px" }
|
|
1969
2139
|
}),
|
|
1970
|
-
/* @__PURE__ */
|
|
2140
|
+
/* @__PURE__ */ jsx6("p", {
|
|
1971
2141
|
children: "No terminal sessions"
|
|
1972
2142
|
}),
|
|
1973
|
-
/* @__PURE__ */
|
|
2143
|
+
/* @__PURE__ */ jsx6("button", {
|
|
1974
2144
|
onClick: () => addNewTab(),
|
|
1975
2145
|
style: {
|
|
1976
2146
|
marginTop: "16px",
|
|
@@ -1993,7 +2163,7 @@ var TabbedTerminalPanelInner = ({
|
|
|
1993
2163
|
});
|
|
1994
2164
|
};
|
|
1995
2165
|
TabbedTerminalPanelInner.displayName = "TabbedTerminalPanelInner";
|
|
1996
|
-
var
|
|
2166
|
+
var TabbedTerminalPanelMemoized = React2.memo(TabbedTerminalPanelInner, (prevProps, nextProps) => {
|
|
1997
2167
|
const changes = [];
|
|
1998
2168
|
if (prevProps.terminalContext !== nextProps.terminalContext)
|
|
1999
2169
|
changes.push("terminalContext");
|
|
@@ -2015,9 +2185,12 @@ var TabbedTerminalPanel = React.memo(TabbedTerminalPanelInner, (prevProps, nextP
|
|
|
2015
2185
|
changes.push("onShowAllTerminalsChange");
|
|
2016
2186
|
if (prevProps.initialTabs !== nextProps.initialTabs)
|
|
2017
2187
|
changes.push("initialTabs");
|
|
2188
|
+
if (prevProps.renderTabContent !== nextProps.renderTabContent)
|
|
2189
|
+
changes.push("renderTabContent");
|
|
2018
2190
|
return changes.length === 0;
|
|
2019
2191
|
});
|
|
2020
|
-
|
|
2192
|
+
TabbedTerminalPanelMemoized.displayName = "TabbedTerminalPanel";
|
|
2193
|
+
var TabbedTerminalPanel = TabbedTerminalPanelMemoized;
|
|
2021
2194
|
// src/tools/index.ts
|
|
2022
2195
|
var createTerminalSessionTool = {
|
|
2023
2196
|
name: "create_terminal_session",
|
|
@@ -2200,12 +2373,14 @@ var onPackageUnload = async () => {
|
|
|
2200
2373
|
export {
|
|
2201
2374
|
writeToTerminalTool,
|
|
2202
2375
|
useThemedTerminal,
|
|
2376
|
+
useTabKeyboardShortcuts,
|
|
2203
2377
|
terminalPanelToolsMetadata,
|
|
2204
2378
|
terminalPanelTools,
|
|
2205
2379
|
panels,
|
|
2206
2380
|
onPackageUnload,
|
|
2207
2381
|
onPackageLoad,
|
|
2208
2382
|
isTerminalLoading,
|
|
2383
|
+
isTabOfType,
|
|
2209
2384
|
getWorkspacePath,
|
|
2210
2385
|
getTerminalSlice,
|
|
2211
2386
|
getTerminalSessions,
|
|
@@ -2221,5 +2396,7 @@ export {
|
|
|
2221
2396
|
ThemedTerminalWithProvider,
|
|
2222
2397
|
ThemedTerminal,
|
|
2223
2398
|
TerminalPanel,
|
|
2224
|
-
TabbedTerminalPanel
|
|
2399
|
+
TabbedTerminalPanel,
|
|
2400
|
+
TabButton,
|
|
2401
|
+
TabBar
|
|
2225
2402
|
};
|