dsh-focus-overlay 0.11.2 → 0.11.3

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.
Files changed (2) hide show
  1. package/lib/client.js +25 -15
  2. package/package.json +2 -1
package/lib/client.js CHANGED
@@ -1036,13 +1036,27 @@ window.__ModuleLoader__.load({
1036
1036
  function InputBar(props) {
1037
1037
  const { t, width, value, queueCount, occCount, errorLine, textareaRef, onFocusChange, onChange, onSend } = props;
1038
1038
  const composingRef = (0, react.useRef)(false);
1039
+ const echoingRef = (0, react.useRef)(false);
1039
1040
  const [pending, setPending] = (0, react.useState)(null);
1040
1041
  const shown = pending ?? value;
1041
1042
  const empty = shown.trim() === "";
1042
- const flush = (v) => {
1043
- if (v === null) return;
1043
+ const echo = (el, next) => {
1044
+ const start = el.selectionStart;
1045
+ const end = el.selectionEnd;
1046
+ echoingRef.current = true;
1047
+ try {
1048
+ onChange(next);
1049
+ } finally {
1050
+ echoingRef.current = false;
1051
+ }
1052
+ if (document.activeElement !== el) {
1053
+ el.focus();
1054
+ el.setSelectionRange(start, end);
1055
+ }
1056
+ };
1057
+ const flush = (el) => {
1044
1058
  setPending(null);
1045
- onChange(v);
1059
+ echo(el, el.value);
1046
1060
  };
1047
1061
  const onCompositionStart = () => {
1048
1062
  composingRef.current = true;
@@ -1050,8 +1064,7 @@ window.__ModuleLoader__.load({
1050
1064
  };
1051
1065
  const onCompositionEnd = (e) => {
1052
1066
  composingRef.current = false;
1053
- flush(e.currentTarget.value);
1054
- refocusAfterEcho(e.currentTarget);
1067
+ flush(e.currentTarget);
1055
1068
  };
1056
1069
  const onKeyDown = (e) => {
1057
1070
  if (e.key === "Enter" && !e.shiftKey && !e.nativeEvent.isComposing && e.nativeEvent.keyCode !== 229) {
@@ -1063,12 +1076,6 @@ window.__ModuleLoader__.load({
1063
1076
  el.style.height = "auto";
1064
1077
  el.style.height = `${Math.min(el.scrollHeight, 120)}px`;
1065
1078
  };
1066
- const refocusAfterEcho = (el) => {
1067
- if (document.activeElement === el) return;
1068
- el.focus();
1069
- const end = el.value.length;
1070
- el.setSelectionRange(end, end);
1071
- };
1072
1079
  (0, react.useEffect)(() => {
1073
1080
  if (textareaRef.current) autoGrow(textareaRef.current);
1074
1081
  }, [shown, textareaRef]);
@@ -1077,10 +1084,9 @@ window.__ModuleLoader__.load({
1077
1084
  if (composingRef.current) setPending(el.value);
1078
1085
  else {
1079
1086
  setPending(null);
1080
- onChange(el.value);
1087
+ echo(el, el.value);
1081
1088
  }
1082
1089
  autoGrow(el);
1083
- refocusAfterEcho(el);
1084
1090
  };
1085
1091
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1086
1092
  className: "fm-bar",
@@ -1109,10 +1115,14 @@ window.__ModuleLoader__.load({
1109
1115
  onKeyDown,
1110
1116
  onFocus: () => onFocusChange(true),
1111
1117
  onBlur: () => {
1118
+ if (echoingRef.current) return;
1112
1119
  if (composingRef.current) {
1113
1120
  composingRef.current = false;
1114
- flush(shown);
1115
- if (textareaRef.current) refocusAfterEcho(textareaRef.current);
1121
+ const el = textareaRef.current;
1122
+ if (el) {
1123
+ flush(el);
1124
+ if (document.activeElement === el) return;
1125
+ }
1116
1126
  }
1117
1127
  onFocusChange(false);
1118
1128
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-focus-overlay",
3
- "version": "0.11.2",
3
+ "version": "0.11.3",
4
4
  "description": "Focus Mode for the dsh web GUI: a full-screen reading overlay that hides chrome and folds the AI tool-call flow into summaries, reusing the official Markdown / image primitives.",
5
5
  "type": "module",
6
6
  "main": "lib/index.mjs",
@@ -54,6 +54,7 @@
54
54
  "bundle"
55
55
  ],
56
56
  "devDependencies": {
57
+ "playwright-core": "^1.63.0",
57
58
  "tsdown": "0.22.2",
58
59
  "vitest": "^4.1.10"
59
60
  },