myoperator-mcp 0.2.326 → 0.2.328

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/dist/index.js +54 -4
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -9174,6 +9174,11 @@ import { cn } from "@/lib/utils";
9174
9174
  const normalizeTextareaSpaces = (value: string): string =>
9175
9175
  String(value).replace(/ {2,}/g, " ");
9176
9176
 
9177
+ const getNormalizedSelectionOffset = (
9178
+ value: string,
9179
+ selectionOffset: number | null
9180
+ ): number => normalizeTextareaSpaces(value.slice(0, selectionOffset ?? value.length)).length;
9181
+
9177
9182
  // Default counter length: normalized text length (spaces count; duplicate spaces do not).
9178
9183
  const countNonWhitespaceChars = (value: string): number =>
9179
9184
  normalizeTextareaSpaces(value).length;
@@ -9256,7 +9261,7 @@ export interface TextareaProps
9256
9261
  labelClassName?: string;
9257
9262
  }
9258
9263
 
9259
- const Textarea = React.forwardRef(
9264
+ const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(
9260
9265
  (
9261
9266
  {
9262
9267
  className,
@@ -9282,8 +9287,27 @@ const Textarea = React.forwardRef(
9282
9287
  id,
9283
9288
  ...props
9284
9289
  }: TextareaProps,
9285
- ref: React.ForwardedRef<HTMLTextAreaElement>
9290
+ ref
9286
9291
  ) => {
9292
+ const textareaRef = React.useRef<HTMLTextAreaElement>(null);
9293
+ const pendingSelectionRef = React.useRef<[number, number] | null>(null);
9294
+
9295
+ const setTextareaRef = React.useCallback(
9296
+ (node: HTMLTextAreaElement | null) => {
9297
+ textareaRef.current = node;
9298
+
9299
+ if (typeof ref === "function") {
9300
+ ref(node);
9301
+ return;
9302
+ }
9303
+
9304
+ if (ref) {
9305
+ ref.current = node;
9306
+ }
9307
+ },
9308
+ [ref]
9309
+ );
9310
+
9287
9311
  // Internal state for character count in uncontrolled mode (normalized)
9288
9312
  const [internalValue, setInternalValue] = React.useState(() =>
9289
9313
  normalizeTextareaSpaces(String(defaultValue ?? ""))
@@ -9295,12 +9319,38 @@ const Textarea = React.forwardRef(
9295
9319
  ? normalizeTextareaSpaces(String(value ?? ""))
9296
9320
  : internalValue;
9297
9321
 
9322
+ const restoreSelection = React.useCallback(() => {
9323
+ const pendingSelection = pendingSelectionRef.current;
9324
+ const textarea = textareaRef.current;
9325
+
9326
+ if (!pendingSelection || !textarea) return;
9327
+
9328
+ pendingSelectionRef.current = null;
9329
+ textarea.setSelectionRange(...pendingSelection);
9330
+ }, []);
9331
+
9332
+ React.useLayoutEffect(() => {
9333
+ restoreSelection();
9334
+ });
9335
+
9298
9336
  // Derive state from props
9299
9337
  const derivedState = error ? "error" : (state ?? "default");
9300
9338
 
9301
9339
  // Handle change for both controlled and uncontrolled \u2014 collapse duplicate spaces
9302
9340
  const handleChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
9303
- const normalized = normalizeTextareaSpaces(e.target.value);
9341
+ const nextValue = e.target.value;
9342
+ const normalized = normalizeTextareaSpaces(nextValue);
9343
+
9344
+ if (normalized !== nextValue) {
9345
+ const nextSelection: [number, number] = [
9346
+ getNormalizedSelectionOffset(nextValue, e.target.selectionStart),
9347
+ getNormalizedSelectionOffset(nextValue, e.target.selectionEnd),
9348
+ ];
9349
+ pendingSelectionRef.current = nextSelection;
9350
+ e.target.setSelectionRange(...nextSelection);
9351
+ requestAnimationFrame(restoreSelection);
9352
+ }
9353
+
9304
9354
  if (!isControlled) {
9305
9355
  setInternalValue(normalized);
9306
9356
  }
@@ -9358,7 +9408,7 @@ const Textarea = React.forwardRef(
9358
9408
 
9359
9409
  {/* Textarea */}
9360
9410
  <textarea
9361
- ref={ref}
9411
+ ref={setTextareaRef}
9362
9412
  id={textareaId}
9363
9413
  rows={rows}
9364
9414
  className={cn(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "myoperator-mcp",
3
- "version": "0.2.326",
3
+ "version": "0.2.328",
4
4
  "description": "MCP server for myOperator UI components - enables AI assistants to access component metadata, examples, and design tokens",
5
5
  "type": "module",
6
6
  "bin": "./dist/index.js",