myoperator-mcp 0.2.309 → 0.2.310

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 +91 -34
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -4167,6 +4167,15 @@ Input.displayName = "Input";
4167
4167
  export { Input, inputVariants };
4168
4168
  `,
4169
4169
  "multi-select": `import * as React from "react";
4170
+ import { createPortal } from "react-dom";
4171
+ import {
4172
+ autoUpdate,
4173
+ flip,
4174
+ offset,
4175
+ shift,
4176
+ size,
4177
+ useFloating,
4178
+ } from "@floating-ui/react-dom";
4170
4179
  import { cva, type VariantProps } from "class-variance-authority";
4171
4180
  import { Check, ChevronDown, CircleAlert, Loader2, X } from "lucide-react";
4172
4181
 
@@ -4285,10 +4294,8 @@ const multiSelectTriggerVariants = cva(
4285
4294
  {
4286
4295
  variants: {
4287
4296
  state: {
4288
- default:
4289
- "border border-solid border-semantic-border-input focus:outline-none focus:border-semantic-border-input-focus/50 focus:shadow-[0_0_0_1px_rgba(43,188,202,0.15)]",
4290
- error:
4291
- "border border-solid border-semantic-error-primary/40 focus:outline-none focus:border-semantic-error-primary/60 focus:shadow-[0_0_0_1px_rgba(240,68,56,0.1)]",
4297
+ default: "border border-solid border-semantic-border-input focus:outline-none focus:border-semantic-border-input-focus/50 focus:shadow-[0_0_0_1px_rgba(43,188,202,0.15)]",
4298
+ error: "border border-solid border-semantic-error-primary/40 focus:outline-none focus:border-semantic-error-primary/60 focus:shadow-[0_0_0_1px_rgba(240,68,56,0.1)]",
4292
4299
  },
4293
4300
  },
4294
4301
  defaultVariants: {
@@ -4420,7 +4427,40 @@ const MultiSelect = React.forwardRef(
4420
4427
  const [searchQuery, setSearchQuery] = React.useState("");
4421
4428
 
4422
4429
  // Container ref for click outside detection
4423
- const containerRef = React.useRef<HTMLDivElement>(null);
4430
+ const containerRef = React.useRef<HTMLDivElement | null>(null);
4431
+
4432
+ const { refs, floatingStyles, isPositioned } = useFloating({
4433
+ open: isOpen,
4434
+ placement: "bottom-start",
4435
+ strategy: "fixed",
4436
+ middleware: [
4437
+ offset(4),
4438
+ flip({ padding: 8 }),
4439
+ shift({ padding: 8 }),
4440
+ size({
4441
+ padding: 8,
4442
+ apply({ rects, elements }) {
4443
+ elements.floating.style.width = \`\${rects.reference.width}px\`;
4444
+ },
4445
+ }),
4446
+ ],
4447
+ whileElementsMounted: (reference, floating, update) =>
4448
+ autoUpdate(reference, floating, update, { animationFrame: true }),
4449
+ });
4450
+
4451
+ const setAnchorRef = React.useCallback(
4452
+ (node: HTMLDivElement | null) => {
4453
+ refs.setReference(node);
4454
+ },
4455
+ [refs]
4456
+ );
4457
+
4458
+ const setDropdownRef = React.useCallback(
4459
+ (node: HTMLDivElement | null) => {
4460
+ refs.setFloating(node);
4461
+ },
4462
+ [refs]
4463
+ );
4424
4464
 
4425
4465
  const flatOptions = React.useMemo(
4426
4466
  () => flattenMultiSelectOptions(options),
@@ -4561,22 +4601,31 @@ const MultiSelect = React.forwardRef(
4561
4601
  onValueChange?.([]);
4562
4602
  };
4563
4603
 
4564
- // Close dropdown when clicking outside
4604
+ // Close dropdown when clicking outside (defer so opening click does not close immediately)
4565
4605
  React.useEffect(() => {
4606
+ if (!isOpen) return;
4607
+
4566
4608
  const handleClickOutside = (event: MouseEvent) => {
4609
+ const target = event.target as Node;
4567
4610
  if (
4568
- containerRef.current &&
4569
- !containerRef.current.contains(event.target as Node)
4611
+ containerRef.current?.contains(target) ||
4612
+ refs.floating.current?.contains(target)
4570
4613
  ) {
4571
- setIsOpen(false);
4572
- setSearchQuery("");
4614
+ return;
4573
4615
  }
4616
+ setIsOpen(false);
4617
+ setSearchQuery("");
4574
4618
  };
4575
4619
 
4576
- document.addEventListener("mousedown", handleClickOutside);
4577
- return () =>
4620
+ const timeoutId = window.setTimeout(() => {
4621
+ document.addEventListener("mousedown", handleClickOutside);
4622
+ }, 0);
4623
+
4624
+ return () => {
4625
+ window.clearTimeout(timeoutId);
4578
4626
  document.removeEventListener("mousedown", handleClickOutside);
4579
- }, []);
4627
+ };
4628
+ }, [isOpen, refs.floating]);
4580
4629
 
4581
4630
  // Handle keyboard navigation
4582
4631
  const handleKeyDown = (e: React.KeyboardEvent) => {
@@ -4612,9 +4661,11 @@ const MultiSelect = React.forwardRef(
4612
4661
  </label>
4613
4662
  )}
4614
4663
 
4615
- {/* Trigger + helper/error + listbox share one positioning context so the
4616
- menu opens directly under the field (and under helper text when present). */}
4617
- <div className="relative w-full min-w-0 flex flex-col gap-1">
4664
+ {/* Anchor for floating menu (portaled to body to escape overflow:hidden scroll areas). */}
4665
+ <div
4666
+ ref={setAnchorRef}
4667
+ className="relative w-full min-w-0 flex flex-col gap-1"
4668
+ >
4618
4669
  {/* Trigger */}
4619
4670
  <button
4620
4671
  ref={ref}
@@ -4734,18 +4785,23 @@ const MultiSelect = React.forwardRef(
4734
4785
  </div>
4735
4786
  )}
4736
4787
 
4737
- {/* Dropdown */}
4738
- {isOpen && (
4739
- <TooltipProvider delayDuration={200}>
4740
- <div
4741
- id={listboxId}
4742
- className={cn(
4743
- "absolute left-0 right-0 z-[100] mt-1 w-full rounded bg-semantic-bg-primary border border-solid border-semantic-border-layout shadow-md",
4744
- "top-full"
4745
- )}
4746
- role="listbox"
4747
- aria-multiselectable="true"
4748
- >
4788
+ {isOpen &&
4789
+ typeof document !== "undefined" &&
4790
+ createPortal(
4791
+ <TooltipProvider delayDuration={200}>
4792
+ <div
4793
+ ref={setDropdownRef}
4794
+ id={listboxId}
4795
+ role="listbox"
4796
+ aria-multiselectable="true"
4797
+ className="rounded bg-semantic-bg-primary border border-solid border-semantic-border-layout shadow-md"
4798
+ style={{
4799
+ ...floatingStyles,
4800
+ zIndex: 10050,
4801
+ visibility: isPositioned ? undefined : "hidden",
4802
+ }}
4803
+ onMouseDown={(e) => e.stopPropagation()}
4804
+ >
4749
4805
  {/* Search input */}
4750
4806
  {searchable && (
4751
4807
  <div className="p-2 border-b border-solid border-semantic-border-layout">
@@ -4773,7 +4829,7 @@ const MultiSelect = React.forwardRef(
4773
4829
  <div
4774
4830
  key={\`divider-\${itemIndex}\`}
4775
4831
  role="separator"
4776
- className="my-1 h-px bg-semantic-border-layout"
4832
+ className="my-1 h-px bg-[var(--semantic-border-layout,#E9EAEB)]"
4777
4833
  />
4778
4834
  );
4779
4835
  }
@@ -4823,7 +4879,7 @@ const MultiSelect = React.forwardRef(
4823
4879
  >
4824
4880
  <span className="absolute right-2 flex size-4 items-center justify-center">
4825
4881
  {isSelected && (
4826
- <Check className="size-4 text-semantic-brand" />
4882
+ <Check className="size-4 text-semantic-primary" />
4827
4883
  )}
4828
4884
  </span>
4829
4885
  <span className="min-w-0 flex-1 whitespace-normal break-words text-left">
@@ -4882,7 +4938,7 @@ const MultiSelect = React.forwardRef(
4882
4938
  </TooltipTrigger>
4883
4939
  <TooltipContent
4884
4940
  side="top"
4885
- className="max-w-xs bg-semantic-primary text-semantic-text-inverted border-semantic-primary"
4941
+ className="max-w-xs bg-semantic-primary text-semantic-text-inverted border-semantic-primary border-solid"
4886
4942
  >
4887
4943
  {overlayCopy}
4888
4944
  </TooltipContent>
@@ -4908,9 +4964,10 @@ const MultiSelect = React.forwardRef(
4908
4964
  {selectedValues.length} / {maxSelections} selected
4909
4965
  </div>
4910
4966
  ) : null}
4911
- </div>
4912
- </TooltipProvider>
4913
- )}
4967
+ </div>
4968
+ </TooltipProvider>,
4969
+ document.body
4970
+ )}
4914
4971
  </div>
4915
4972
 
4916
4973
  {/* Hidden input for form submission */}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "myoperator-mcp",
3
- "version": "0.2.309",
3
+ "version": "0.2.310",
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",