@industry-theme/xterm-terminal-panel 0.8.9 → 0.8.11

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.js CHANGED
@@ -37,7 +37,7 @@ import {
37
37
  // package.json
38
38
  var package_default = {
39
39
  name: "@industry-theme/xterm-terminal-panel",
40
- version: "0.8.8",
40
+ version: "0.8.11",
41
41
  description: "Industry-themed xterm.js terminal components with panel framework integration",
42
42
  type: "module",
43
43
  sideEffects: [
@@ -2442,7 +2442,7 @@ var useTabKeyboardShortcuts = ({
2442
2442
  }, [enabled, onNewTab, onCloseTab, onSwitchToTab]);
2443
2443
  };
2444
2444
  // src/panels/TabbedTerminalPanel.tsx
2445
- import { useTheme as useTheme6 } from "@principal-ade/industry-theme";
2445
+ import { useTheme as useTheme7 } from "@principal-ade/industry-theme";
2446
2446
  import { CollapsibleSplitPane } from "@principal-ade/panels";
2447
2447
  import { Terminal as TerminalIcon2, Box, Boxes, Paperclip } from "lucide-react";
2448
2448
  import React3, {
@@ -2451,11 +2451,64 @@ import React3, {
2451
2451
  useEffect as useEffect4,
2452
2452
  useRef as useRef4
2453
2453
  } from "react";
2454
- import { jsx as jsx10, jsxs as jsxs8, Fragment as Fragment2 } from "react/jsx-runtime";
2455
- var ActivityIndicator = ({ color, isAnimating }) => /* @__PURE__ */ jsxs8("div", {
2454
+
2455
+ // src/components/TerminalStatusBar.tsx
2456
+ import { useTheme as useTheme6 } from "@principal-ade/industry-theme";
2457
+ import { Folder } from "lucide-react";
2458
+ import { jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
2459
+ var TerminalStatusBar = ({
2460
+ directory
2461
+ }) => {
2462
+ const { theme } = useTheme6();
2463
+ if (!directory) {
2464
+ return null;
2465
+ }
2466
+ return /* @__PURE__ */ jsxs8("div", {
2467
+ style: {
2468
+ flex: "0 0 auto",
2469
+ display: "flex",
2470
+ alignItems: "center",
2471
+ gap: 6,
2472
+ height: 22,
2473
+ padding: "0 10px",
2474
+ backgroundColor: theme.colors.backgroundSecondary ?? theme.colors.background,
2475
+ borderTop: `1px solid ${theme.colors.border}`,
2476
+ color: theme.colors.textSecondary,
2477
+ fontSize: theme.fontSizes[0],
2478
+ fontFamily: theme.fonts.monospace,
2479
+ userSelect: "none",
2480
+ overflow: "hidden"
2481
+ },
2482
+ title: directory,
2483
+ children: [
2484
+ /* @__PURE__ */ jsx10(Folder, {
2485
+ size: 12,
2486
+ style: { flex: "0 0 auto", opacity: 0.7 }
2487
+ }),
2488
+ /* @__PURE__ */ jsx10("span", {
2489
+ style: {
2490
+ direction: "rtl",
2491
+ textAlign: "left",
2492
+ whiteSpace: "nowrap",
2493
+ overflow: "hidden",
2494
+ textOverflow: "ellipsis",
2495
+ minWidth: 0
2496
+ },
2497
+ children: /* @__PURE__ */ jsx10("bdi", {
2498
+ children: directory
2499
+ })
2500
+ })
2501
+ ]
2502
+ });
2503
+ };
2504
+ TerminalStatusBar.displayName = "TerminalStatusBar";
2505
+
2506
+ // src/panels/TabbedTerminalPanel.tsx
2507
+ import { jsx as jsx11, jsxs as jsxs9, Fragment as Fragment2 } from "react/jsx-runtime";
2508
+ var ActivityIndicator = ({ color, isAnimating }) => /* @__PURE__ */ jsxs9("div", {
2456
2509
  style: { display: "flex", gap: 1, alignItems: "center", height: 12 },
2457
2510
  children: [
2458
- [0, 1, 2, 3, 4].map((i) => /* @__PURE__ */ jsx10("div", {
2511
+ [0, 1, 2, 3, 4].map((i) => /* @__PURE__ */ jsx11("div", {
2459
2512
  style: {
2460
2513
  width: 2,
2461
2514
  height: 10,
@@ -2466,7 +2519,7 @@ var ActivityIndicator = ({ color, isAnimating }) => /* @__PURE__ */ jsxs8("div",
2466
2519
  animation: isAnimating ? `waveSine 1.2s ease-in-out ${i * 0.1}s infinite` : "none"
2467
2520
  }
2468
2521
  }, i)),
2469
- /* @__PURE__ */ jsx10("style", {
2522
+ /* @__PURE__ */ jsx11("style", {
2470
2523
  children: `
2471
2524
  @keyframes waveSine {
2472
2525
  0%, 100% { transform: scaleY(0.4); }
@@ -2511,14 +2564,14 @@ function TerminalTabContentInner(props, ref) {
2511
2564
  React3.useImperativeHandle(ref, () => ({
2512
2565
  scrollToBottom: () => sessionRef.current?.scrollToBottom()
2513
2566
  }), []);
2514
- return /* @__PURE__ */ jsx10("div", {
2567
+ return /* @__PURE__ */ jsx11("div", {
2515
2568
  style: {
2516
2569
  display: "flex",
2517
2570
  flexDirection: "column",
2518
2571
  height: "100%",
2519
2572
  width: "100%"
2520
2573
  },
2521
- children: /* @__PURE__ */ jsx10(TerminalSession, {
2574
+ children: /* @__PURE__ */ jsx11(TerminalSession, {
2522
2575
  ref: sessionRef,
2523
2576
  actions,
2524
2577
  events,
@@ -2603,7 +2656,7 @@ var TabbedTerminalPanelInner = ({
2603
2656
  onTabAssociate: onTabAssociateProp,
2604
2657
  onTabDissociate: _onTabDissociate
2605
2658
  }) => {
2606
- const { theme } = useTheme6();
2659
+ const { theme } = useTheme7();
2607
2660
  const onTabAssociate = actions.onTabAssociate ?? onTabAssociateProp;
2608
2661
  const [ownedTabs, setOwnedTabs] = useState4(initialTabs);
2609
2662
  const [foreignTabs, setForeignTabs] = useState4([]);
@@ -2633,11 +2686,6 @@ var TabbedTerminalPanelInner = ({
2633
2686
  useEffect4(() => {
2634
2687
  const customTabsFromProp = initialTabs.filter((tab) => tab.contentType !== "terminal");
2635
2688
  setOwnedTabs((prevTabs) => {
2636
- const existingTerminalTabs = prevTabs.filter((tab) => tab.contentType === "terminal");
2637
- const mergedTabs = [
2638
- ...existingTerminalTabs,
2639
- ...customTabsFromProp
2640
- ];
2641
2689
  const prevCustomTabs = prevTabs.filter((tab) => tab.contentType !== "terminal");
2642
2690
  const customTabsChanged = prevCustomTabs.length !== customTabsFromProp.length || !customTabsFromProp.every((tab) => {
2643
2691
  const prev = prevCustomTabs.find((p) => p.id === tab.id);
@@ -2648,7 +2696,11 @@ var TabbedTerminalPanelInner = ({
2648
2696
  if (!customTabsChanged) {
2649
2697
  return prevTabs;
2650
2698
  }
2651
- return mergedTabs;
2699
+ const propById = new Map(customTabsFromProp.map((tab) => [tab.id, tab]));
2700
+ const prevCustomIds = new Set(prevCustomTabs.map((tab) => tab.id));
2701
+ const kept = prevTabs.filter((tab) => tab.contentType === "terminal" || propById.has(tab.id)).map((tab) => tab.contentType !== "terminal" && propById.has(tab.id) ? propById.get(tab.id) : tab);
2702
+ const added = customTabsFromProp.filter((tab) => !prevCustomIds.has(tab.id));
2703
+ return [...kept, ...added];
2652
2704
  });
2653
2705
  }, [customTabsKey]);
2654
2706
  useEffect4(() => {
@@ -2747,9 +2799,7 @@ var TabbedTerminalPanelInner = ({
2747
2799
  const tabsToAdd = newRestoredTabs.filter((t) => !existingIds.has(t.id));
2748
2800
  if (tabsToAdd.length === 0)
2749
2801
  return prevTabs;
2750
- const terminalTabs = prevTabs.filter((t) => t.contentType === "terminal");
2751
- const customTabs = prevTabs.filter((t) => t.contentType !== "terminal");
2752
- const merged = [...terminalTabs, ...tabsToAdd, ...customTabs];
2802
+ const merged = [...prevTabs, ...tabsToAdd];
2753
2803
  appendedTabs = merged;
2754
2804
  return merged;
2755
2805
  });
@@ -2969,8 +3019,8 @@ var TabbedTerminalPanelInner = ({
2969
3019
  const isActive = tab.id === activeTabId;
2970
3020
  if (!isActive)
2971
3021
  return null;
2972
- return /* @__PURE__ */ jsx10(Fragment2, {
2973
- children: /* @__PURE__ */ jsx10("div", {
3022
+ return /* @__PURE__ */ jsx11(Fragment2, {
3023
+ children: /* @__PURE__ */ jsx11("div", {
2974
3024
  style: {
2975
3025
  position: "absolute",
2976
3026
  right: "8px",
@@ -2981,7 +3031,7 @@ var TabbedTerminalPanelInner = ({
2981
3031
  height: "16px"
2982
3032
  },
2983
3033
  title: isWorking ? "Terminal active" : "Terminal idle",
2984
- children: /* @__PURE__ */ jsx10(ActivityIndicator, {
3034
+ children: /* @__PURE__ */ jsx11(ActivityIndicator, {
2985
3035
  color: theme.colors.primary,
2986
3036
  isAnimating: isWorking ?? false
2987
3037
  })
@@ -2989,7 +3039,7 @@ var TabbedTerminalPanelInner = ({
2989
3039
  });
2990
3040
  }, [activeTabId, theme, sessionIds, workingStates, activityStates]);
2991
3041
  const renderTerminalWithAssociation = useCallback5((tab, isActive, sessionId, association) => {
2992
- const terminalContent = /* @__PURE__ */ jsx10(TerminalTabContent, {
3042
+ const terminalContent = /* @__PURE__ */ jsx11(TerminalTabContent, {
2993
3043
  ref: getRefCallback(tab.id),
2994
3044
  tab,
2995
3045
  sessionId,
@@ -3006,7 +3056,7 @@ var TabbedTerminalPanelInner = ({
3006
3056
  onActivityStateChange: handleActivityStateChange
3007
3057
  }, `terminal-${tab.id}`);
3008
3058
  const hasAssociation = !!association;
3009
- const secondaryContent = hasAssociation && renderAssociatedContent ? renderAssociatedContent(association.associatedTabId, isActive) : /* @__PURE__ */ jsx10("div", {
3059
+ const secondaryContent = hasAssociation && renderAssociatedContent ? renderAssociatedContent(association.associatedTabId, isActive) : /* @__PURE__ */ jsx11("div", {
3010
3060
  style: {
3011
3061
  height: "100%",
3012
3062
  display: "flex",
@@ -3018,12 +3068,12 @@ var TabbedTerminalPanelInner = ({
3018
3068
  },
3019
3069
  children: "Drag a tab here to associate it with this terminal"
3020
3070
  });
3021
- const headerConfig = hasAssociation && getAssociatedHeader ? getAssociatedHeader(association.associatedTabId) : { title: "Drop zone", icon: /* @__PURE__ */ jsx10(Paperclip, {
3071
+ const headerConfig = hasAssociation && getAssociatedHeader ? getAssociatedHeader(association.associatedTabId) : { title: "Drop zone", icon: /* @__PURE__ */ jsx11(Paperclip, {
3022
3072
  size: 14
3023
3073
  }) };
3024
3074
  const isCollapsed = hasAssociation ? association.collapsed : true;
3025
3075
  const handleCollapsedChange = hasAssociation ? (collapsed) => onAssociationCollapsedChange?.(tab.id, collapsed) : undefined;
3026
- return /* @__PURE__ */ jsx10(CollapsibleSplitPane, {
3076
+ return /* @__PURE__ */ jsx11(CollapsibleSplitPane, {
3027
3077
  style: { height: "100%" },
3028
3078
  primaryContent: terminalContent,
3029
3079
  secondaryContent,
@@ -3096,7 +3146,7 @@ var TabbedTerminalPanelInner = ({
3096
3146
  setActiveTabId(activeTabId);
3097
3147
  }
3098
3148
  }, [activeTabId, tabs, onTabAssociate, setActiveTabId]);
3099
- return /* @__PURE__ */ jsxs8("div", {
3149
+ return /* @__PURE__ */ jsxs9("div", {
3100
3150
  style: {
3101
3151
  display: "flex",
3102
3152
  flexDirection: "column",
@@ -3104,15 +3154,15 @@ var TabbedTerminalPanelInner = ({
3104
3154
  backgroundColor: theme.colors.background
3105
3155
  },
3106
3156
  children: [
3107
- !hideHeader && /* @__PURE__ */ jsx10("div", {
3157
+ !hideHeader && /* @__PURE__ */ jsx11("div", {
3108
3158
  ref: headerRef,
3109
- children: /* @__PURE__ */ jsx10(TabBar, {
3159
+ children: /* @__PURE__ */ jsx11(TabBar, {
3110
3160
  tabs: genericTabs,
3111
3161
  activeTabId,
3112
3162
  onTabClick: switchTab,
3113
3163
  onTabClose: closeTab,
3114
3164
  onNewTab: addNewTab,
3115
- leftSection: hideShowAllTerminalsButton ? undefined : /* @__PURE__ */ jsx10("button", {
3165
+ leftSection: hideShowAllTerminalsButton ? undefined : /* @__PURE__ */ jsx11("button", {
3116
3166
  onClick: () => onShowAllTerminalsChange?.(!showAllTerminals),
3117
3167
  style: {
3118
3168
  display: "flex",
@@ -3137,9 +3187,9 @@ var TabbedTerminalPanelInner = ({
3137
3187
  }
3138
3188
  },
3139
3189
  title: showAllTerminals ? "Showing all terminals (click to filter by context)" : "Show all terminals",
3140
- children: showAllTerminals ? /* @__PURE__ */ jsx10(Boxes, {
3190
+ children: showAllTerminals ? /* @__PURE__ */ jsx11(Boxes, {
3141
3191
  size: 14
3142
- }) : /* @__PURE__ */ jsx10(Box, {
3192
+ }) : /* @__PURE__ */ jsx11(Box, {
3143
3193
  size: 14
3144
3194
  })
3145
3195
  }),
@@ -3152,7 +3202,7 @@ var TabbedTerminalPanelInner = ({
3152
3202
  canDropOnTab
3153
3203
  })
3154
3204
  }),
3155
- /* @__PURE__ */ jsxs8("div", {
3205
+ /* @__PURE__ */ jsxs9("div", {
3156
3206
  style: {
3157
3207
  flex: 1,
3158
3208
  display: "flex",
@@ -3206,7 +3256,7 @@ var TabbedTerminalPanelInner = ({
3206
3256
  const customContent = renderTabContent(tab, isActive, sessionId, width);
3207
3257
  if (customContent === null && tab.contentType === "terminal") {
3208
3258
  const association = associations?.[tab.id];
3209
- return /* @__PURE__ */ jsx10("div", {
3259
+ return /* @__PURE__ */ jsx11("div", {
3210
3260
  inert: !isActive,
3211
3261
  style: {
3212
3262
  position: "absolute",
@@ -3219,7 +3269,7 @@ var TabbedTerminalPanelInner = ({
3219
3269
  }, tab.id);
3220
3270
  }
3221
3271
  const hasBeenActivated = activatedTabs.has(tab.id);
3222
- return /* @__PURE__ */ jsx10("div", {
3272
+ return /* @__PURE__ */ jsx11("div", {
3223
3273
  inert: !isActive,
3224
3274
  style: {
3225
3275
  position: "absolute",
@@ -3233,7 +3283,7 @@ var TabbedTerminalPanelInner = ({
3233
3283
  }
3234
3284
  if (tab.contentType === "terminal") {
3235
3285
  const association = associations?.[tab.id];
3236
- return /* @__PURE__ */ jsx10("div", {
3286
+ return /* @__PURE__ */ jsx11("div", {
3237
3287
  inert: !isActive,
3238
3288
  style: {
3239
3289
  position: "absolute",
@@ -3245,7 +3295,7 @@ var TabbedTerminalPanelInner = ({
3245
3295
  children: renderTerminalWithAssociation(tab, isActive, sessionId, association)
3246
3296
  }, tab.id);
3247
3297
  }
3248
- return /* @__PURE__ */ jsxs8("div", {
3298
+ return /* @__PURE__ */ jsxs9("div", {
3249
3299
  inert: !isActive,
3250
3300
  style: {
3251
3301
  position: "absolute",
@@ -3257,20 +3307,20 @@ var TabbedTerminalPanelInner = ({
3257
3307
  color: theme.colors.textSecondary
3258
3308
  },
3259
3309
  children: [
3260
- /* @__PURE__ */ jsxs8("p", {
3310
+ /* @__PURE__ */ jsxs9("p", {
3261
3311
  children: [
3262
3312
  "Unknown content type: ",
3263
3313
  tab.contentType
3264
3314
  ]
3265
3315
  }),
3266
- /* @__PURE__ */ jsx10("p", {
3316
+ /* @__PURE__ */ jsx11("p", {
3267
3317
  style: { fontSize: theme.fontSizes[0], marginTop: "8px" },
3268
3318
  children: "Provide a renderTabContent prop to render custom tab types"
3269
3319
  })
3270
3320
  ]
3271
3321
  }, tab.id);
3272
3322
  }),
3273
- tabs.length === 0 && /* @__PURE__ */ jsxs8("div", {
3323
+ tabs.length === 0 && /* @__PURE__ */ jsxs9("div", {
3274
3324
  style: {
3275
3325
  display: "flex",
3276
3326
  flexDirection: "column",
@@ -3280,11 +3330,11 @@ var TabbedTerminalPanelInner = ({
3280
3330
  color: theme.colors.textSecondary
3281
3331
  },
3282
3332
  children: [
3283
- /* @__PURE__ */ jsx10(TerminalIcon2, {
3333
+ /* @__PURE__ */ jsx11(TerminalIcon2, {
3284
3334
  size: 32,
3285
3335
  style: { opacity: 0.5, marginBottom: "16px" }
3286
3336
  }),
3287
- /* @__PURE__ */ jsx10("button", {
3337
+ /* @__PURE__ */ jsx11("button", {
3288
3338
  onClick: () => addNewTab(),
3289
3339
  style: {
3290
3340
  marginTop: "16px",
@@ -3302,6 +3352,9 @@ var TabbedTerminalPanelInner = ({
3302
3352
  ]
3303
3353
  })
3304
3354
  ]
3355
+ }),
3356
+ /* @__PURE__ */ jsx11(TerminalStatusBar, {
3357
+ directory: tabs.find((t) => t.id === activeTabId)?.directory
3305
3358
  })
3306
3359
  ]
3307
3360
  });
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ export interface TerminalStatusBarProps {
3
+ directory?: string;
4
+ }
5
+ export declare const TerminalStatusBar: React.FC<TerminalStatusBarProps>;
6
+ //# sourceMappingURL=TerminalStatusBar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TerminalStatusBar.d.ts","sourceRoot":"","sources":["../../../src/components/TerminalStatusBar.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,WAAW,sBAAsB;IAErC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAUD,eAAO,MAAM,iBAAiB,EAAE,KAAK,CAAC,EAAE,CAAC,sBAAsB,CAgD9D,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"TabbedTerminalPanel.d.ts","sourceRoot":"","sources":["../../../src/panels/TabbedTerminalPanel.tsx"],"names":[],"mappings":"AAIA,OAAO,KAKN,MAAM,OAAO,CAAC;AAMf,OAAO,KAAK,EACV,wBAAwB,EACxB,WAAW,EAGZ,MAAM,gBAAgB,CAAC;AAgExB,MAAM,WAAW,qBAAqB;IACpC,cAAc,EAAE,MAAM,IAAI,CAAC;CAC5B;AAmtCD,eAAO,MAAM,mBAAmB,EAAkC,CAAC,IAAI,SAAS,OAAO,cAAc,EAAE,OAAO,GAAG,WAAW,EAC1H,KAAK,EAAE,wBAAwB,CAAC,IAAI,CAAC,KAClC,KAAK,CAAC,YAAY,CAAC"}
1
+ {"version":3,"file":"TabbedTerminalPanel.d.ts","sourceRoot":"","sources":["../../../src/panels/TabbedTerminalPanel.tsx"],"names":[],"mappings":"AAIA,OAAO,KAKN,MAAM,OAAO,CAAC;AAOf,OAAO,KAAK,EACV,wBAAwB,EACxB,WAAW,EAGZ,MAAM,gBAAgB,CAAC;AAgExB,MAAM,WAAW,qBAAqB;IACpC,cAAc,EAAE,MAAM,IAAI,CAAC;CAC5B;AA6tCD,eAAO,MAAM,mBAAmB,EAAkC,CAAC,IAAI,SAAS,OAAO,cAAc,EAAE,OAAO,GAAG,WAAW,EAC1H,KAAK,EAAE,wBAAwB,CAAC,IAAI,CAAC,KAClC,KAAK,CAAC,YAAY,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@industry-theme/xterm-terminal-panel",
3
- "version": "0.8.9",
3
+ "version": "0.8.11",
4
4
  "description": "Industry-themed xterm.js terminal components with panel framework integration",
5
5
  "type": "module",
6
6
  "sideEffects": [