myoperator-mcp 0.2.337 → 0.2.339

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 +123 -38
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -4766,7 +4766,7 @@ const DropdownMenuItem = React.forwardRef(({ className, inset, children, descrip
4766
4766
  renderDropdownMenuItemChildren(children)
4767
4767
  )}
4768
4768
  {suffix && (
4769
- <span className="ml-auto text-xs text-semantic-text-muted shrink-0 pl-2">{suffix}</span>
4769
+ <span className="ml-auto text-xs text-semantic-text-muted shrink-0 pl-4">{suffix}</span>
4770
4770
  )}
4771
4771
  </DropdownMenuPrimitive.Item>
4772
4772
  ));
@@ -4805,7 +4805,7 @@ const DropdownMenuCheckboxItem = React.forwardRef(({ className, children, checke
4805
4805
  renderDropdownMenuItemChildren(children)
4806
4806
  )}
4807
4807
  {suffix && (
4808
- <span className="ml-auto text-xs text-semantic-text-muted shrink-0 pl-2">{suffix}</span>
4808
+ <span className="ml-auto text-xs text-semantic-text-muted shrink-0 pl-4">{suffix}</span>
4809
4809
  )}
4810
4810
  </DropdownMenuPrimitive.CheckboxItem>
4811
4811
  ));
@@ -4844,7 +4844,7 @@ const DropdownMenuRadioItem = React.forwardRef(({ className, children, descripti
4844
4844
  renderDropdownMenuItemChildren(children)
4845
4845
  )}
4846
4846
  {suffix && (
4847
- <span className="ml-auto text-xs text-semantic-text-muted shrink-0 pl-2">{suffix}</span>
4847
+ <span className="ml-auto text-xs text-semantic-text-muted shrink-0 pl-4">{suffix}</span>
4848
4848
  )}
4849
4849
  </DropdownMenuPrimitive.RadioItem>
4850
4850
  ));
@@ -7489,61 +7489,146 @@ import { cn } from "@/lib/utils";
7489
7489
  * Used in chat applications for reply-to previews.
7490
7490
  *
7491
7491
  * When an \`onClick\` handler is provided, the component becomes interactive:
7492
- * it receives \`role="button"\`, \`tabIndex={0}\`, and keyboard support (Enter/Space).
7493
- * A focus ring is shown when focused via keyboard.
7492
+ * it renders as a \`<button>\`, with native keyboard support.
7494
7493
  *
7495
7494
  * @example
7496
7495
  * \`\`\`tsx
7497
7496
  * <ReplyQuote sender="John Doe" message="Hello, how are you?" />
7498
- * <ReplyQuote sender="Jane" message="Check this out!" onClick={() => scrollToMessage()} />
7497
+ * <ReplyQuote sender="Jane" message="Check this out!" thumbnailUrl="https://..." onClick={() => scrollToMessage()} />
7499
7498
  * \`\`\`
7500
7499
  */
7501
- export interface ReplyQuoteProps extends React.HTMLAttributes<HTMLDivElement> {
7500
+ export interface ReplyQuoteProps
7501
+ extends Omit<
7502
+ React.HTMLAttributes<HTMLDivElement>,
7503
+ "onClick" | "onKeyDown"
7504
+ > {
7502
7505
  /** Name of the person being quoted */
7503
7506
  sender: string;
7504
- /** The quoted message content */
7507
+ /** The quoted message text (plain string or formatted React node) */
7505
7508
  message: React.ReactNode;
7509
+ /** Optional thumbnail shown on the right (e.g. template image header) */
7510
+ thumbnailUrl?: string;
7511
+ onClick?: React.MouseEventHandler<HTMLElement>;
7512
+ onKeyDown?: React.KeyboardEventHandler<HTMLElement>;
7506
7513
  }
7507
7514
 
7508
- const ReplyQuote = React.forwardRef(
7509
- ({ className, sender, message, onClick, onKeyDown, role, tabIndex, "aria-label": ariaLabel, ...props }: ReplyQuoteProps, ref: React.Ref<HTMLDivElement>) => {
7510
- const isInteractive = !!onClick;
7511
- const messageLabel = typeof message === "string" ? \`: \${message}\` : "";
7512
-
7513
- const handleKeyDown = React.useCallback(
7514
- (e: React.KeyboardEvent<HTMLDivElement>) => {
7515
- if (onClick && (e.key === "Enter" || e.key === " ")) {
7516
- if (e.key === " ") {
7517
- e.preventDefault();
7518
- }
7519
- onClick(e as unknown as React.MouseEvent<HTMLDivElement>);
7520
- }
7521
- onKeyDown?.(e);
7522
- },
7523
- [onClick, onKeyDown]
7524
- );
7515
+ function ReplyQuoteInner({
7516
+ sender,
7517
+ message,
7518
+ thumbnailUrl,
7519
+ }: Pick<ReplyQuoteProps, "sender" | "message" | "thumbnailUrl">) {
7520
+ const thumb = thumbnailUrl?.trim();
7525
7521
 
7526
- return (
7522
+ return (
7523
+ <>
7527
7524
  <div
7528
- ref={ref}
7529
7525
  className={cn(
7530
- "tw-max-w-full tw-min-w-0 tw-bg-[var(--semantic-bg-ui,#F5F5F5)] tw-border-l-[3px] tw-border-solid tw-border-[var(--semantic-border-accent,#27ABB8)] tw-rounded-sm tw-px-4 tw-py-1.5 tw-mb-2 tw-h-[56px] tw-flex tw-flex-col tw-justify-center tw-gap-0 tw-overflow-hidden tw-cursor-pointer hover:tw-bg-[var(--semantic-bg-hover,#D5D7DA)] tw-transition-colors",
7531
- isInteractive && "focus-visible:tw-ring-2 focus-visible:tw-ring-[var(--semantic-border-focus,#2BBCCA)] focus-visible:tw-ring-offset-1 focus-visible:tw-outline-none",
7532
- className
7526
+ "tw-min-w-0 tw-flex tw-flex-col tw-justify-start",
7527
+ thumb ? "tw-flex-1" : "tw-w-full"
7533
7528
  )}
7534
- role={role ?? (isInteractive ? "button" : undefined)}
7535
- tabIndex={tabIndex ?? (isInteractive ? 0 : undefined)}
7536
- onClick={onClick}
7537
- onKeyDown={isInteractive ? handleKeyDown : onKeyDown}
7538
- aria-label={ariaLabel ?? \`Quoted reply from \${sender}\${messageLabel}\`}
7539
- {...props}
7540
7529
  >
7541
7530
  <p className="tw-m-0 tw-min-w-0 tw-shrink-0 tw-truncate tw-text-[14px] tw-font-semibold tw-leading-5 tw-tracking-[0.014px] tw-text-[var(--semantic-text-primary,#181D27)]">
7542
7531
  {sender}
7543
7532
  </p>
7544
- <div className="tw-m-0 tw-min-h-0 tw-min-w-0 tw-flex-1 tw-overflow-hidden tw-text-ellipsis tw-whitespace-nowrap tw-text-[14px] tw-leading-5 tw-text-[var(--semantic-text-muted,#717680)] [&_*]:tw-inline">
7533
+ <p className="tw-m-0 tw-min-h-0 tw-min-w-0 tw-flex-1 tw-truncate tw-text-[14px] tw-leading-5 tw-text-[var(--semantic-text-muted,#717680)]">
7545
7534
  {message}
7546
- </div>
7535
+ </p>
7536
+ </div>
7537
+ {thumb ? (
7538
+ <img
7539
+ src={thumb}
7540
+ alt=""
7541
+ className="tw-size-11 tw-shrink-0 tw-rounded-sm tw-object-cover"
7542
+ />
7543
+ ) : null}
7544
+ </>
7545
+ );
7546
+ }
7547
+
7548
+ function replyQuoteClassName(
7549
+ className: string | undefined,
7550
+ hasThumbnail: boolean,
7551
+ isInteractive: boolean
7552
+ ) {
7553
+ return cn(
7554
+ "tw-w-full tw-min-w-0 tw-bg-[var(--semantic-bg-ui,#F5F5F5)] tw-border-l-[3px] tw-border-solid tw-border-[var(--semantic-border-accent,#27ABB8)] tw-rounded-sm tw-px-4 tw-py-1.5 tw-mb-2 tw-h-[56px] tw-overflow-hidden tw-cursor-pointer hover:tw-bg-[var(--semantic-bg-hover,#D5D7DA)] tw-transition-colors tw-text-left",
7555
+ hasThumbnail
7556
+ ? "tw-flex tw-flex-row tw-items-center tw-gap-2"
7557
+ : "tw-flex tw-flex-col tw-justify-start tw-gap-0",
7558
+ isInteractive &&
7559
+ "focus-visible:tw-ring-2 focus-visible:tw-ring-[var(--semantic-border-focus,#2BBCCA)] focus-visible:tw-ring-offset-1 focus-visible:tw-outline-none tw-border-t-0 tw-border-r-0 tw-border-b-0",
7560
+ className
7561
+ );
7562
+ }
7563
+
7564
+ const ReplyQuote = React.forwardRef<HTMLDivElement, ReplyQuoteProps>(
7565
+ (
7566
+ {
7567
+ className,
7568
+ sender,
7569
+ message,
7570
+ thumbnailUrl,
7571
+ onClick,
7572
+ onKeyDown,
7573
+ role,
7574
+ tabIndex,
7575
+ "aria-label": ariaLabel,
7576
+ ...props
7577
+ },
7578
+ ref
7579
+ ) => {
7580
+ const isInteractive = !!onClick;
7581
+ const thumb = Boolean(thumbnailUrl?.trim());
7582
+ const label =
7583
+ ariaLabel ??
7584
+ \`Quoted reply from \${sender}\${
7585
+ typeof message === "string" && message ? \`: \${message}\` : ""
7586
+ }\`;
7587
+
7588
+ if (isInteractive) {
7589
+ const {
7590
+ onCopy,
7591
+ onCut,
7592
+ onPaste,
7593
+ ...buttonProps
7594
+ } = props as React.ButtonHTMLAttributes<HTMLButtonElement>;
7595
+
7596
+ return (
7597
+ <button
7598
+ type="button"
7599
+ className={replyQuoteClassName(className, thumb, true)}
7600
+ onClick={onClick}
7601
+ onKeyDown={onKeyDown}
7602
+ aria-label={label}
7603
+ onCopy={onCopy}
7604
+ onCut={onCut}
7605
+ onPaste={onPaste}
7606
+ {...buttonProps}
7607
+ >
7608
+ <ReplyQuoteInner
7609
+ sender={sender}
7610
+ message={message}
7611
+ thumbnailUrl={thumbnailUrl}
7612
+ />
7613
+ </button>
7614
+ );
7615
+ }
7616
+
7617
+ return (
7618
+ <div
7619
+ ref={ref}
7620
+ className={replyQuoteClassName(className, thumb, false)}
7621
+ role={role}
7622
+ tabIndex={tabIndex}
7623
+ onKeyDown={onKeyDown}
7624
+ aria-label={label}
7625
+ {...props}
7626
+ >
7627
+ <ReplyQuoteInner
7628
+ sender={sender}
7629
+ message={message}
7630
+ thumbnailUrl={thumbnailUrl}
7631
+ />
7547
7632
  </div>
7548
7633
  );
7549
7634
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "myoperator-mcp",
3
- "version": "0.2.337",
3
+ "version": "0.2.339",
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",