@particle-academy/fancy-term 0.4.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -0
- package/dist/index.cjs +29 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +28 -2
- package/dist/index.d.ts +28 -2
- package/dist/index.js +29 -4
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -143,7 +143,13 @@ interface TerminalContextMenuItem {
|
|
|
143
143
|
}
|
|
144
144
|
/** The actions the built-in items dispatch to (wired by the component). */
|
|
145
145
|
interface TerminalMenuActions {
|
|
146
|
-
|
|
146
|
+
/**
|
|
147
|
+
* Receives the menu's {@link TerminalContextMenuContext} so it can copy the
|
|
148
|
+
* selection **snapshotted when the menu opened** — by click time the live
|
|
149
|
+
* xterm selection is often already cleared (a mouse-reporting TUI's redraw
|
|
150
|
+
* clears it right after the right-click), so re-reading it copies nothing.
|
|
151
|
+
*/
|
|
152
|
+
copy: (ctx: TerminalContextMenuContext) => void;
|
|
147
153
|
paste: () => void;
|
|
148
154
|
selectAll: () => void;
|
|
149
155
|
clear: () => void;
|
|
@@ -537,4 +543,24 @@ interface MenuSize {
|
|
|
537
543
|
*/
|
|
538
544
|
declare function clampMenuPosition(at: MenuPoint, menu: MenuSize, viewport: MenuSize, margin?: number): MenuPoint;
|
|
539
545
|
|
|
540
|
-
|
|
546
|
+
/** The bits of a pointer event the snapshot decision needs. */
|
|
547
|
+
interface SnapshotPointerEvent {
|
|
548
|
+
type: "mousedown" | "mouseup";
|
|
549
|
+
/** 0 = left, 1 = middle, 2 = right. */
|
|
550
|
+
button: number;
|
|
551
|
+
}
|
|
552
|
+
/**
|
|
553
|
+
* Compute the next selection snapshot after a pointer event on the terminal
|
|
554
|
+
* surface.
|
|
555
|
+
*
|
|
556
|
+
* - A fresh **left press** starts a new gesture — drop the snapshot (the live
|
|
557
|
+
* selection still reads the *old* text at capture time, so it must not win).
|
|
558
|
+
* - Otherwise a **non-empty live selection** always refreshes the snapshot
|
|
559
|
+
* (drag-select completes on left mouseup; a right press re-captures while
|
|
560
|
+
* the selection is still alive).
|
|
561
|
+
* - An **empty** live selection keeps the previous snapshot — that's exactly
|
|
562
|
+
* the TUI-cleared-it-under-us case the snapshot exists for.
|
|
563
|
+
*/
|
|
564
|
+
declare function nextSelectionSnapshot(prev: string, event: SnapshotPointerEvent, liveSelection: string): string;
|
|
565
|
+
|
|
566
|
+
export { BUILTIN_SHELLS, type ClipboardOption, type ClipboardPayload, type ClipboardProvider, type CopyKeyEvent, type CopyPasteBehavior, type CopyPasteMode, type CursorStyle, type KeyEventLike, type Osc52Mode, type Osc52Request, type ShellProfile, ShellSwitcher, type ShellSwitcherProps, type SnapshotPointerEvent, Terminal, TerminalContextMenu, type TerminalContextMenuConfig, type TerminalContextMenuContext, type TerminalContextMenuItem, type TerminalHandle, type TerminalMenuActions, type TerminalOptions, type TerminalProps, type TerminalSessionApi, type TerminalSessionTransport, type TerminalTheme, type UseTerminalSessionOptions, clampMenuPosition, copyPasteBehavior, decodeBase64, defaultMenuItems, encodeBase64, fancyDarkTheme, isImageFile, navigatorClipboard, nextSelectionSnapshot, osc52Response, parseOsc52, registerOsc52, resolveClipboard, resolveKeyAction, resolveMenuItems, resolveShell, shouldCopyEvent, useTerminal, useTerminalFit, useTerminalSession };
|
package/dist/index.js
CHANGED
|
@@ -767,6 +767,12 @@ function resolveMenuItems(config, ctx, actions) {
|
|
|
767
767
|
const items = config === void 0 || config === true ? defaults : Array.isArray(config) ? config : config(ctx, defaults);
|
|
768
768
|
return items.length > 0 ? items : null;
|
|
769
769
|
}
|
|
770
|
+
|
|
771
|
+
// src/selection-snapshot.ts
|
|
772
|
+
function nextSelectionSnapshot(prev, event, liveSelection) {
|
|
773
|
+
if (event.type === "mousedown" && event.button === 0) return "";
|
|
774
|
+
return liveSelection || prev;
|
|
775
|
+
}
|
|
770
776
|
var Terminal = forwardRef(function Terminal2({
|
|
771
777
|
output,
|
|
772
778
|
theme,
|
|
@@ -867,25 +873,42 @@ var Terminal = forwardRef(function Terminal2({
|
|
|
867
873
|
written.current = output;
|
|
868
874
|
}, [output, handle]);
|
|
869
875
|
const [menu, setMenu] = useState(null);
|
|
876
|
+
const selectionSnapshot = useRef("");
|
|
877
|
+
const trackSelection = useCallback(
|
|
878
|
+
(e) => {
|
|
879
|
+
selectionSnapshot.current = nextSelectionSnapshot(
|
|
880
|
+
selectionSnapshot.current,
|
|
881
|
+
{ type: e.type, button: e.button },
|
|
882
|
+
handle.getSelection()
|
|
883
|
+
);
|
|
884
|
+
},
|
|
885
|
+
[handle]
|
|
886
|
+
);
|
|
870
887
|
const openMenu = useCallback(
|
|
871
888
|
(e) => {
|
|
872
889
|
if (contextMenu === false) return;
|
|
873
890
|
e.preventDefault();
|
|
874
|
-
const selection = handle.getSelection();
|
|
891
|
+
const selection = handle.getSelection() || selectionSnapshot.current;
|
|
875
892
|
const ctx = {
|
|
876
893
|
hasSelection: selection.length > 0,
|
|
877
894
|
selection,
|
|
878
895
|
readOnly: !!readOnly
|
|
879
896
|
};
|
|
880
897
|
const items = resolveMenuItems(contextMenu, ctx, {
|
|
881
|
-
|
|
898
|
+
// Copy writes the SNAPSHOTTED selection through the active clipboard
|
|
899
|
+
// provider — never a click-time re-read, which copies "" over a TUI
|
|
900
|
+
// (falling back to the live selection only when the snapshot is empty).
|
|
901
|
+
copy: (c) => {
|
|
902
|
+
const text = c.selection || handle.getSelection();
|
|
903
|
+
if (text) void providerWrite(resolveClipboard(clipboard).provider, text);
|
|
904
|
+
},
|
|
882
905
|
paste: () => void handle.paste(),
|
|
883
906
|
selectAll: () => handle.selectAll(),
|
|
884
907
|
clear: () => handle.clear()
|
|
885
908
|
});
|
|
886
909
|
if (items) setMenu({ at: { x: e.clientX, y: e.clientY }, items, ctx });
|
|
887
910
|
},
|
|
888
|
-
[contextMenu, handle, readOnly]
|
|
911
|
+
[contextMenu, handle, readOnly, clipboard]
|
|
889
912
|
);
|
|
890
913
|
const menuNode = menu ? /* @__PURE__ */ jsx(TerminalContextMenu, { at: menu.at, items: menu.items, ctx: menu.ctx, onClose: () => setMenu(null) }) : null;
|
|
891
914
|
const surface = /* @__PURE__ */ jsx(
|
|
@@ -893,6 +916,8 @@ var Terminal = forwardRef(function Terminal2({
|
|
|
893
916
|
{
|
|
894
917
|
ref: containerRef,
|
|
895
918
|
"data-fancy-terminal": "",
|
|
919
|
+
onMouseDownCapture: trackSelection,
|
|
920
|
+
onMouseUpCapture: trackSelection,
|
|
896
921
|
onContextMenu: openMenu,
|
|
897
922
|
"data-readonly": readOnly ? "" : void 0,
|
|
898
923
|
"data-fancy-terminal-shell": shellId ?? void 0,
|
|
@@ -995,6 +1020,6 @@ function shouldCopyEvent(e, hasSelection) {
|
|
|
995
1020
|
return false;
|
|
996
1021
|
}
|
|
997
1022
|
|
|
998
|
-
export { BUILTIN_SHELLS, ShellSwitcher, Terminal, TerminalContextMenu, clampMenuPosition, copyPasteBehavior, decodeBase64, defaultMenuItems, encodeBase64, fancyDarkTheme, isImageFile, navigatorClipboard, osc52Response, parseOsc52, registerOsc52, resolveClipboard, resolveKeyAction, resolveMenuItems, resolveShell, shouldCopyEvent, useTerminal, useTerminalFit, useTerminalSession };
|
|
1023
|
+
export { BUILTIN_SHELLS, ShellSwitcher, Terminal, TerminalContextMenu, clampMenuPosition, copyPasteBehavior, decodeBase64, defaultMenuItems, encodeBase64, fancyDarkTheme, isImageFile, navigatorClipboard, nextSelectionSnapshot, osc52Response, parseOsc52, registerOsc52, resolveClipboard, resolveKeyAction, resolveMenuItems, resolveShell, shouldCopyEvent, useTerminal, useTerminalFit, useTerminalSession };
|
|
999
1024
|
//# sourceMappingURL=index.js.map
|
|
1000
1025
|
//# sourceMappingURL=index.js.map
|