myoperator-ui 0.0.218 → 0.0.219

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 +780 -1818
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -118,7 +118,6 @@ function transformSemanticClassesInContent(content) {
118
118
  const cnRegex = /\bcn\s*\(/g;
119
119
  let cnMatch;
120
120
  while ((cnMatch = cnRegex.exec(content)) !== null) {
121
- if (cnMatch.index < lastIndex) continue;
122
121
  result += content.slice(lastIndex, cnMatch.index);
123
122
  let depth = 1;
124
123
  let i = cnMatch.index + cnMatch[0].length;
@@ -267,10 +266,8 @@ function looksLikeTailwindClasses(str) {
267
266
  return false;
268
267
  });
269
268
  }
270
- var BORDER_WIDTH_RE = /^border(-[trblxy])?(-[0248]|-\[.+\])?$/;
271
- var BORDER_STYLE_RE = /^border-(solid|dashed|dotted|double|hidden|none)$/;
272
269
  function prefixClassString(classString, prefix) {
273
- const prefixed = classString.split(" ").map((cls) => {
270
+ return classString.split(" ").map((cls) => {
274
271
  if (!cls) return cls;
275
272
  if ((cls.startsWith("aria-") || cls.startsWith("data-")) && !cls.includes("[") && !cls.includes(":")) return cls;
276
273
  if (cls.startsWith("[&") || cls.startsWith("[&_")) {
@@ -320,14 +317,7 @@ function prefixClassString(classString, prefix) {
320
317
  return `-${prefix}${cls.slice(1)}`;
321
318
  }
322
319
  return `${prefix}${cls}`;
323
- });
324
- const origClasses = classString.split(" ");
325
- const hasBorderWidth = origClasses.some((c) => BORDER_WIDTH_RE.test(c));
326
- const hasBorderStyle = origClasses.some((c) => BORDER_STYLE_RE.test(c));
327
- if (hasBorderWidth && !hasBorderStyle) {
328
- prefixed.push(`${prefix}border-solid`);
329
- }
330
- return prefixed.join(" ");
320
+ }).join(" ");
331
321
  }
332
322
  function prefixTailwindClasses(content, prefix) {
333
323
  content = transformSemanticClassesInContent(content);
@@ -345,7 +335,6 @@ function prefixTailwindClasses(content, prefix) {
345
335
  const cnRegex = /\bcn\s*\(/g;
346
336
  let cnMatch;
347
337
  while ((cnMatch = cnRegex.exec(content)) !== null) {
348
- if (cnMatch.index < lastIndex) continue;
349
338
  result += content.slice(lastIndex, cnMatch.index);
350
339
  let depth = 1;
351
340
  let i = cnMatch.index + cnMatch[0].length;
@@ -384,120 +373,7 @@ function prefixTailwindClasses(content, prefix) {
384
373
  return `className="${prefixed}"`;
385
374
  }
386
375
  );
387
- const nonClassKeys = [
388
- // HTML attributes
389
- "name",
390
- "displayName",
391
- "type",
392
- "role",
393
- "id",
394
- "htmlFor",
395
- "for",
396
- "placeholder",
397
- "alt",
398
- "src",
399
- "href",
400
- "target",
401
- "rel",
402
- "method",
403
- "action",
404
- "enctype",
405
- "accept",
406
- "pattern",
407
- "autocomplete",
408
- "value",
409
- "defaultValue",
410
- "label",
411
- "text",
412
- "message",
413
- "helperText",
414
- "ariaLabel",
415
- "ariaDescribedBy",
416
- "description",
417
- "title",
418
- "content",
419
- "header",
420
- "footer",
421
- "caption",
422
- "summary",
423
- "tooltip",
424
- "errorMessage",
425
- "successMessage",
426
- "warningMessage",
427
- "infoMessage",
428
- "hint",
429
- // CSS style properties (camelCase — safe because they can't be CVA variant keys)
430
- "width",
431
- "height",
432
- "minWidth",
433
- "maxWidth",
434
- "minHeight",
435
- "maxHeight",
436
- "padding",
437
- "paddingTop",
438
- "paddingRight",
439
- "paddingBottom",
440
- "paddingLeft",
441
- "margin",
442
- "marginTop",
443
- "marginRight",
444
- "marginBottom",
445
- "marginLeft",
446
- "fontSize",
447
- "fontWeight",
448
- "fontFamily",
449
- "fontStyle",
450
- "lineHeight",
451
- "letterSpacing",
452
- "backgroundColor",
453
- "borderColor",
454
- "borderWidth",
455
- "borderStyle",
456
- "borderRadius",
457
- "zIndex",
458
- "overflow",
459
- "overflowX",
460
- "overflowY",
461
- "userSelect",
462
- "transitionDuration",
463
- "transitionProperty",
464
- "boxShadow",
465
- "textShadow",
466
- "outlineOffset",
467
- "rowGap",
468
- "columnGap",
469
- "gridTemplateColumns",
470
- "gridTemplateRows",
471
- "flexBasis",
472
- "flexGrow",
473
- "flexShrink",
474
- "flexDirection",
475
- "flexWrap",
476
- "alignItems",
477
- "alignSelf",
478
- "justifyContent",
479
- "justifyItems",
480
- "textAlign",
481
- "textDecoration",
482
- "textTransform",
483
- "whiteSpace",
484
- "wordBreak",
485
- "wordSpacing",
486
- "aspectRatio",
487
- "scrollbarWidth",
488
- "scrollBehavior",
489
- "backgroundImage",
490
- "backgroundSize",
491
- "backgroundPosition",
492
- "backgroundRepeat",
493
- "borderTop",
494
- "borderRight",
495
- "borderBottom",
496
- "borderLeft",
497
- "strokeWidth",
498
- "strokeDasharray",
499
- "strokeDashoffset"
500
- ];
376
+ const nonClassKeys = ["name", "displayName", "type", "role", "id", "htmlFor", "for", "placeholder", "alt", "src", "href", "target", "rel", "method", "action", "enctype", "accept", "pattern", "autocomplete", "value", "defaultValue", "label", "text", "message", "helperText", "ariaLabel", "ariaDescribedBy", "description", "title", "content", "header", "footer", "caption", "summary", "tooltip", "errorMessage", "successMessage", "warningMessage", "infoMessage", "hint"];
501
377
  function hasObviousTailwindPatterns(value) {
502
378
  return /(?:^|\s)(hover|focus|active|disabled|group|peer|data-|aria-|sm:|md:|lg:|xl:|2xl:|dark:)/.test(value) || // Group/peer with selectors
503
379
  /group-\[|peer-\[/.test(value) || // Arbitrary selectors
@@ -557,264 +433,8 @@ function prefixTailwindClasses(content, prefix) {
557
433
  return `${funcName}('${prefixed}'`;
558
434
  }
559
435
  );
560
- {
561
- let jsxResult = "";
562
- let jsxLastIndex = 0;
563
- const jsxRegex = /className\s*=\s*\{/g;
564
- let jsxMatch;
565
- while ((jsxMatch = jsxRegex.exec(content)) !== null) {
566
- if (jsxMatch.index < jsxLastIndex) continue;
567
- jsxResult += content.slice(jsxLastIndex, jsxMatch.index);
568
- const bracePos = jsxMatch.index + jsxMatch[0].length - 1;
569
- let depth = 1;
570
- let pos = bracePos + 1;
571
- while (pos < content.length && depth > 0) {
572
- const ch = content[pos];
573
- if (ch === "{") {
574
- depth++;
575
- pos++;
576
- continue;
577
- }
578
- if (ch === "}") {
579
- depth--;
580
- if (depth === 0) {
581
- pos++;
582
- break;
583
- }
584
- pos++;
585
- continue;
586
- }
587
- if (ch === '"') {
588
- pos++;
589
- while (pos < content.length && content[pos] !== '"') {
590
- if (content[pos] === "\\") pos++;
591
- pos++;
592
- }
593
- pos++;
594
- continue;
595
- }
596
- if (ch === "'") {
597
- pos++;
598
- while (pos < content.length && content[pos] !== "'") {
599
- if (content[pos] === "\\") pos++;
600
- pos++;
601
- }
602
- pos++;
603
- continue;
604
- }
605
- if (ch === "`") {
606
- pos++;
607
- let tDepth = 0;
608
- while (pos < content.length) {
609
- if (content[pos] === "\\") {
610
- pos += 2;
611
- continue;
612
- }
613
- if (content[pos] === "`" && tDepth === 0) {
614
- pos++;
615
- break;
616
- }
617
- if (content[pos] === "$" && content[pos + 1] === "{") {
618
- tDepth++;
619
- pos += 2;
620
- continue;
621
- }
622
- if (content[pos] === "}" && tDepth > 0) {
623
- tDepth--;
624
- pos++;
625
- continue;
626
- }
627
- pos++;
628
- }
629
- continue;
630
- }
631
- pos++;
632
- }
633
- const expr = content.slice(bracePos + 1, pos - 1);
634
- const exprTrimmed = expr.trimStart();
635
- if (/^(cn|cva)\s*\(/.test(exprTrimmed)) {
636
- jsxResult += content.slice(jsxMatch.index, pos);
637
- jsxLastIndex = pos;
638
- continue;
639
- }
640
- const prefixedExpr = prefixClassNameExpression(expr, prefix);
641
- jsxResult += jsxMatch[0] + prefixedExpr + "}";
642
- jsxLastIndex = pos;
643
- }
644
- jsxResult += content.slice(jsxLastIndex);
645
- content = jsxResult;
646
- }
647
436
  return content;
648
437
  }
649
- function isAlreadyPrefixed(classString, prefix) {
650
- if (!classString.trim()) return false;
651
- return classString.trim().split(/\s+/).every((c) => {
652
- const lastColon = c.lastIndexOf(":");
653
- const utility = lastColon >= 0 ? c.slice(lastColon + 1) : c;
654
- return utility.startsWith(prefix) || utility.startsWith(`-${prefix}`) || utility.startsWith(`!${prefix}`) || utility.startsWith(`!-${prefix}`);
655
- });
656
- }
657
- function prefixStaticTemplatePart(text, prefix) {
658
- const trimmed = text.trim();
659
- if (!trimmed || !looksLikeTailwindClasses(trimmed)) return text;
660
- const leading = text.match(/^(\s*)/)?.[1] || "";
661
- const trailing = text.match(/(\s*)$/)?.[1] || "";
662
- return leading + prefixClassString(trimmed, prefix) + trailing;
663
- }
664
- function prefixStringLiteralsInExpr(code, prefix) {
665
- let result = code.replace(/"([^"]*)"/g, (m, classes) => {
666
- if (!classes.trim() || !looksLikeTailwindClasses(classes) || isAlreadyPrefixed(classes, prefix)) return m;
667
- return `"${prefixClassString(classes, prefix)}"`;
668
- });
669
- result = result.replace(/'([^']*)'/g, (m, classes) => {
670
- if (!classes.trim() || !looksLikeTailwindClasses(classes) || isAlreadyPrefixed(classes, prefix)) return m;
671
- return `'${prefixClassString(classes, prefix)}'`;
672
- });
673
- return result;
674
- }
675
- function prefixClassNameExpression(expr, prefix) {
676
- let result = "";
677
- let i = 0;
678
- while (i < expr.length) {
679
- if (expr[i] === "`") {
680
- result += "`";
681
- i++;
682
- let staticText = "";
683
- while (i < expr.length && expr[i] !== "`") {
684
- if (expr[i] === "\\") {
685
- staticText += expr[i] + (expr[i + 1] || "");
686
- i += 2;
687
- continue;
688
- }
689
- if (expr[i] === "$" && i + 1 < expr.length && expr[i + 1] === "{") {
690
- if (staticText) {
691
- result += prefixStaticTemplatePart(staticText, prefix);
692
- staticText = "";
693
- }
694
- result += "${";
695
- i += 2;
696
- let exprDepth = 1;
697
- let exprContent = "";
698
- while (i < expr.length && exprDepth > 0) {
699
- if (expr[i] === '"') {
700
- exprContent += expr[i];
701
- i++;
702
- while (i < expr.length && expr[i] !== '"') {
703
- if (expr[i] === "\\") {
704
- exprContent += expr[i];
705
- i++;
706
- }
707
- exprContent += expr[i];
708
- i++;
709
- }
710
- if (i < expr.length) {
711
- exprContent += expr[i];
712
- i++;
713
- }
714
- continue;
715
- }
716
- if (expr[i] === "'") {
717
- exprContent += expr[i];
718
- i++;
719
- while (i < expr.length && expr[i] !== "'") {
720
- if (expr[i] === "\\") {
721
- exprContent += expr[i];
722
- i++;
723
- }
724
- exprContent += expr[i];
725
- i++;
726
- }
727
- if (i < expr.length) {
728
- exprContent += expr[i];
729
- i++;
730
- }
731
- continue;
732
- }
733
- if (expr[i] === "`") {
734
- exprContent += expr[i];
735
- i++;
736
- let nestedDepth = 0;
737
- while (i < expr.length) {
738
- if (expr[i] === "\\") {
739
- exprContent += expr[i];
740
- i++;
741
- if (i < expr.length) {
742
- exprContent += expr[i];
743
- i++;
744
- }
745
- ;
746
- continue;
747
- }
748
- if (expr[i] === "`" && nestedDepth === 0) {
749
- exprContent += expr[i];
750
- i++;
751
- break;
752
- }
753
- if (expr[i] === "$" && i + 1 < expr.length && expr[i + 1] === "{") {
754
- nestedDepth++;
755
- exprContent += "${";
756
- i += 2;
757
- continue;
758
- }
759
- if (expr[i] === "}" && nestedDepth > 0) {
760
- nestedDepth--;
761
- }
762
- exprContent += expr[i];
763
- i++;
764
- }
765
- continue;
766
- }
767
- if (expr[i] === "{") exprDepth++;
768
- else if (expr[i] === "}") {
769
- exprDepth--;
770
- if (exprDepth === 0) {
771
- i++;
772
- break;
773
- }
774
- }
775
- exprContent += expr[i];
776
- i++;
777
- }
778
- result += prefixStringLiteralsInExpr(exprContent, prefix) + "}";
779
- continue;
780
- }
781
- staticText += expr[i];
782
- i++;
783
- }
784
- if (staticText) {
785
- result += prefixStaticTemplatePart(staticText, prefix);
786
- }
787
- if (i < expr.length && expr[i] === "`") {
788
- result += "`";
789
- i++;
790
- }
791
- } else if (expr[i] === '"' || expr[i] === "'") {
792
- const quote = expr[i];
793
- const strStart = i;
794
- i++;
795
- let str = "";
796
- while (i < expr.length && expr[i] !== quote) {
797
- if (expr[i] === "\\") {
798
- str += expr[i] + (expr[i + 1] || "");
799
- i += 2;
800
- continue;
801
- }
802
- str += expr[i];
803
- i++;
804
- }
805
- if (i < expr.length) i++;
806
- if (str.trim() && looksLikeTailwindClasses(str) && !isAlreadyPrefixed(str, prefix)) {
807
- result += quote + prefixClassString(str, prefix) + quote;
808
- } else {
809
- result += expr.slice(strStart, i);
810
- }
811
- } else {
812
- result += expr[i];
813
- i++;
814
- }
815
- }
816
- return result;
817
- }
818
438
  async function getRegistry(prefix = "") {
819
439
  return {
820
440
  "avatar": {
@@ -914,7 +534,7 @@ export interface AvatarProps
914
534
  * <Avatar initials="AS" size="xs" />
915
535
  * \`\`\`
916
536
  */
917
- const Avatar = React.forwardRef(
537
+ const Avatar = React.forwardRef<HTMLDivElement, AvatarProps>(
918
538
  (
919
539
  {
920
540
  className,
@@ -927,8 +547,8 @@ const Avatar = React.forwardRef(
927
547
  status,
928
548
  children,
929
549
  ...props
930
- }: AvatarProps,
931
- ref: React.Ref<HTMLDivElement>
550
+ },
551
+ ref
932
552
  ) => {
933
553
  const resolvedSize = size ?? "md";
934
554
  const displayInitials = initials ?? (name ? getInitials(name) : undefined);
@@ -1005,8 +625,8 @@ export interface DateDividerProps
1005
625
  children: React.ReactNode;
1006
626
  }
1007
627
 
1008
- const DateDivider = React.forwardRef(
1009
- ({ className, children, ...props }: DateDividerProps, ref: React.Ref<HTMLDivElement>) => (
628
+ const DateDivider = React.forwardRef<HTMLDivElement, DateDividerProps>(
629
+ ({ className, children, ...props }, ref) => (
1010
630
  <div
1011
631
  ref={ref}
1012
632
  className={cn("flex items-center gap-4 my-4", className)}
@@ -1062,8 +682,8 @@ export interface ImageMediaProps extends React.HTMLAttributes<HTMLDivElement> {
1062
682
  maxHeight?: number | string;
1063
683
  }
1064
684
 
1065
- const ImageMedia = React.forwardRef(
1066
- ({ className, src, alt = "Image", maxHeight = 280, ...props }: ImageMediaProps, ref: React.Ref<HTMLDivElement>) => {
685
+ const ImageMedia = React.forwardRef<HTMLDivElement, ImageMediaProps>(
686
+ ({ className, src, alt = "Image", maxHeight = 280, ...props }, ref) => {
1067
687
  const maxHeightStyle =
1068
688
  typeof maxHeight === "number" ? \`\${maxHeight}px\` : maxHeight;
1069
689
 
@@ -1127,7 +747,7 @@ export interface PhoneInputProps
1127
747
  wrapperClassName?: string;
1128
748
  }
1129
749
 
1130
- const PhoneInput = React.forwardRef(
750
+ const PhoneInput = React.forwardRef<HTMLInputElement, PhoneInputProps>(
1131
751
  (
1132
752
  {
1133
753
  className,
@@ -1138,8 +758,8 @@ const PhoneInput = React.forwardRef(
1138
758
  wrapperClassName,
1139
759
  disabled,
1140
760
  ...props
1141
- }: PhoneInputProps,
1142
- ref: React.Ref<HTMLInputElement>
761
+ },
762
+ ref
1143
763
  ) => {
1144
764
  return (
1145
765
  <div
@@ -1223,8 +843,8 @@ export interface ReplyQuoteProps extends React.HTMLAttributes<HTMLDivElement> {
1223
843
  message: string;
1224
844
  }
1225
845
 
1226
- const ReplyQuote = React.forwardRef(
1227
- ({ className, sender, message, onClick, onKeyDown, role, tabIndex, "aria-label": ariaLabel, ...props }: ReplyQuoteProps, ref: React.Ref<HTMLDivElement>) => {
846
+ const ReplyQuote = React.forwardRef<HTMLDivElement, ReplyQuoteProps>(
847
+ ({ className, sender, message, onClick, onKeyDown, role, tabIndex, "aria-label": ariaLabel, ...props }, ref) => {
1228
848
  const isInteractive = !!onClick;
1229
849
 
1230
850
  const handleKeyDown = React.useCallback(
@@ -1304,8 +924,8 @@ export interface SystemMessageProps
1304
924
  children: string;
1305
925
  }
1306
926
 
1307
- const SystemMessage = React.forwardRef(
1308
- ({ className, children, ...props }: SystemMessageProps, ref: React.Ref<HTMLDivElement>) => (
927
+ const SystemMessage = React.forwardRef<HTMLDivElement, SystemMessageProps>(
928
+ ({ className, children, ...props }, ref) => (
1309
929
  <div
1310
930
  ref={ref}
1311
931
  className={cn("flex justify-center my-1", className)}
@@ -1366,8 +986,8 @@ export interface UnreadSeparatorProps
1366
986
  label?: string;
1367
987
  }
1368
988
 
1369
- const UnreadSeparator = React.forwardRef(
1370
- ({ className, count, label, ...props }: UnreadSeparatorProps, ref: React.Ref<HTMLDivElement>) => (
989
+ const UnreadSeparator = React.forwardRef<HTMLDivElement, UnreadSeparatorProps>(
990
+ ({ className, count, label, ...props }, ref) => (
1371
991
  <div
1372
992
  ref={ref}
1373
993
  className={cn("flex items-center gap-4 my-2", className)}
@@ -1423,12 +1043,12 @@ const buttonVariants = cva(
1423
1043
  success:
1424
1044
  "bg-semantic-success-primary text-semantic-text-inverted hover:bg-semantic-success-hover",
1425
1045
  outline:
1426
- "border border-[var(--color-neutral-300,#D5D7DA)] bg-semantic-bg-primary text-semantic-text-secondary hover:bg-semantic-primary-surface",
1046
+ "border border-semantic-border-layout bg-semantic-bg-primary text-semantic-text-secondary hover:bg-semantic-primary-surface",
1427
1047
  secondary:
1428
1048
  "bg-semantic-primary-surface text-semantic-text-secondary hover:bg-semantic-bg-hover",
1429
1049
  ghost:
1430
1050
  "text-semantic-text-muted hover:bg-semantic-bg-ui hover:text-semantic-text-primary",
1431
- link: "text-semantic-text-link underline-offset-4 hover:underline",
1051
+ link: "text-semantic-text-secondary underline-offset-4 hover:underline",
1432
1052
  dashed:
1433
1053
  "border border-dashed border-semantic-bg-hover bg-transparent text-semantic-text-muted hover:border-semantic-border-primary hover:text-semantic-text-secondary hover:bg-[var(--color-neutral-50)]",
1434
1054
  },
@@ -1474,7 +1094,7 @@ export interface ButtonProps
1474
1094
  loadingText?: string;
1475
1095
  }
1476
1096
 
1477
- const Button = React.forwardRef(
1097
+ const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
1478
1098
  (
1479
1099
  {
1480
1100
  className,
@@ -1488,8 +1108,8 @@ const Button = React.forwardRef(
1488
1108
  children,
1489
1109
  disabled,
1490
1110
  ...props
1491
- }: ButtonProps,
1492
- ref: React.Ref<HTMLButtonElement>
1111
+ },
1112
+ ref
1493
1113
  ) => {
1494
1114
  const Comp = asChild ? Slot : "button";
1495
1115
 
@@ -1605,7 +1225,7 @@ export interface BadgeProps
1605
1225
  asChild?: boolean;
1606
1226
  }
1607
1227
 
1608
- const Badge = React.forwardRef(
1228
+ const Badge = React.forwardRef<HTMLDivElement, BadgeProps>(
1609
1229
  (
1610
1230
  {
1611
1231
  className,
@@ -1616,8 +1236,8 @@ const Badge = React.forwardRef(
1616
1236
  asChild = false,
1617
1237
  children,
1618
1238
  ...props
1619
- }: BadgeProps,
1620
- ref: React.Ref<HTMLDivElement>
1239
+ },
1240
+ ref
1621
1241
  ) => {
1622
1242
  const Comp = asChild ? Slot : "div";
1623
1243
 
@@ -1706,7 +1326,7 @@ export interface ContactListItemProps
1706
1326
  * />
1707
1327
  * \`\`\`
1708
1328
  */
1709
- const ContactListItem = React.forwardRef(
1329
+ const ContactListItem = React.forwardRef<HTMLDivElement, ContactListItemProps>(
1710
1330
  (
1711
1331
  {
1712
1332
  name,
@@ -1717,8 +1337,8 @@ const ContactListItem = React.forwardRef(
1717
1337
  onClick,
1718
1338
  className,
1719
1339
  ...props
1720
- }: ContactListItemProps,
1721
- ref: React.Ref<HTMLDivElement>
1340
+ },
1341
+ ref
1722
1342
  ) => {
1723
1343
  return (
1724
1344
  <div
@@ -1917,7 +1537,7 @@ export interface TypographyProps extends React.HTMLAttributes<HTMLElement> {
1917
1537
  * <Typography truncate>Very long text that will be truncated...</Typography>
1918
1538
  * \`\`\`
1919
1539
  */
1920
- const Typography = React.forwardRef(
1540
+ const Typography = React.forwardRef<HTMLElement, TypographyProps>(
1921
1541
  (
1922
1542
  {
1923
1543
  children,
@@ -1930,8 +1550,8 @@ const Typography = React.forwardRef(
1930
1550
  tag,
1931
1551
  htmlFor,
1932
1552
  ...props
1933
- }: TypographyProps,
1934
- ref: React.Ref<HTMLElement>
1553
+ },
1554
+ ref
1935
1555
  ) => {
1936
1556
  const key: Key = \`\${kind}-\${variant}\`;
1937
1557
  const Tag = (tag || mapTagName[key]) as React.ElementType;
@@ -1999,9 +1619,9 @@ const inputVariants = cva(
1999
1619
  variants: {
2000
1620
  state: {
2001
1621
  default:
2002
- "border border-semantic-border-input focus:outline-none focus:border-semantic-border-input-focus focus:shadow-[0_0_0_1px_rgba(43,188,202,0.15)]",
1622
+ "border border-semantic-border-input hover:border-semantic-border-input-focus focus:outline-none focus:border-semantic-border-input-focus focus:shadow-[0_0_0_1px_rgba(43,188,202,0.15)]",
2003
1623
  error:
2004
- "border border-semantic-error-primary/40 focus:outline-none focus:border-semantic-error-primary focus:shadow-[0_0_0_1px_rgba(240,68,56,0.1)]",
1624
+ "border border-semantic-error-primary/40 hover:border-semantic-error-primary focus:outline-none focus:border-semantic-error-primary focus:shadow-[0_0_0_1px_rgba(240,68,56,0.1)]",
2005
1625
  },
2006
1626
  },
2007
1627
  defaultVariants: {
@@ -2028,8 +1648,8 @@ export interface InputProps
2028
1648
  showCheckIcon?: boolean;
2029
1649
  }
2030
1650
 
2031
- const Input = React.forwardRef(
2032
- ({ className, state, type, showCheckIcon, onFocus, onBlur, onWheel, ...props }: InputProps, ref: React.Ref<HTMLInputElement>) => {
1651
+ const Input = React.forwardRef<HTMLInputElement, InputProps>(
1652
+ ({ className, state, type, showCheckIcon, onFocus, onBlur, onWheel, ...props }, ref) => {
2033
1653
  const [isFocused, setIsFocused] = React.useState(false);
2034
1654
 
2035
1655
  const inputEl = (
@@ -2127,7 +1747,10 @@ const Select = SelectPrimitive.Root;
2127
1747
 
2128
1748
  const SelectGroup = SelectPrimitive.Group;
2129
1749
 
2130
- const SelectValue = React.forwardRef(({ className, ...props }: React.ComponentPropsWithoutRef<typeof SelectPrimitive.Value>, ref: React.Ref<React.ElementRef<typeof SelectPrimitive.Value>>) => (
1750
+ const SelectValue = React.forwardRef<
1751
+ React.ElementRef<typeof SelectPrimitive.Value>,
1752
+ React.ComponentPropsWithoutRef<typeof SelectPrimitive.Value>
1753
+ >(({ className, ...props }, ref) => (
2131
1754
  <SelectPrimitive.Value
2132
1755
  ref={ref}
2133
1756
  className={cn("[&[data-placeholder]]:text-semantic-text-muted", className)}
@@ -2141,7 +1764,10 @@ export interface SelectTriggerProps
2141
1764
  React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger>,
2142
1765
  VariantProps<typeof selectTriggerVariants> {}
2143
1766
 
2144
- const SelectTrigger = React.forwardRef(({ className, state, children, ...props }: SelectTriggerProps, ref: React.Ref<React.ElementRef<typeof SelectPrimitive.Trigger>>) => (
1767
+ const SelectTrigger = React.forwardRef<
1768
+ React.ElementRef<typeof SelectPrimitive.Trigger>,
1769
+ SelectTriggerProps
1770
+ >(({ className, state, children, ...props }, ref) => (
2145
1771
  <SelectPrimitive.Trigger
2146
1772
  ref={ref}
2147
1773
  className={cn(selectTriggerVariants({ state, className }))}
@@ -2155,7 +1781,10 @@ const SelectTrigger = React.forwardRef(({ className, state, children, ...props }
2155
1781
  ));
2156
1782
  SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
2157
1783
 
2158
- const SelectScrollUpButton = React.forwardRef(({ className, ...props }: React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollUpButton>, ref: React.Ref<React.ElementRef<typeof SelectPrimitive.ScrollUpButton>>) => (
1784
+ const SelectScrollUpButton = React.forwardRef<
1785
+ React.ElementRef<typeof SelectPrimitive.ScrollUpButton>,
1786
+ React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollUpButton>
1787
+ >(({ className, ...props }, ref) => (
2159
1788
  <SelectPrimitive.ScrollUpButton
2160
1789
  ref={ref}
2161
1790
  className={cn(
@@ -2169,7 +1798,10 @@ const SelectScrollUpButton = React.forwardRef(({ className, ...props }: React.Co
2169
1798
  ));
2170
1799
  SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
2171
1800
 
2172
- const SelectScrollDownButton = React.forwardRef(({ className, ...props }: React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollDownButton>, ref: React.Ref<React.ElementRef<typeof SelectPrimitive.ScrollDownButton>>) => (
1801
+ const SelectScrollDownButton = React.forwardRef<
1802
+ React.ElementRef<typeof SelectPrimitive.ScrollDownButton>,
1803
+ React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollDownButton>
1804
+ >(({ className, ...props }, ref) => (
2173
1805
  <SelectPrimitive.ScrollDownButton
2174
1806
  ref={ref}
2175
1807
  className={cn(
@@ -2223,7 +1855,10 @@ function useUnlockBodyScroll() {
2223
1855
  }, []);
2224
1856
  }
2225
1857
 
2226
- const SelectContent = React.forwardRef(({ className, children, position = "popper", ...props }: React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content>, ref: React.Ref<React.ElementRef<typeof SelectPrimitive.Content>>) => {
1858
+ const SelectContent = React.forwardRef<
1859
+ React.ElementRef<typeof SelectPrimitive.Content>,
1860
+ React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content>
1861
+ >(({ className, children, position = "popper", ...props }, ref) => {
2227
1862
  useUnlockBodyScroll();
2228
1863
 
2229
1864
  return (
@@ -2261,7 +1896,10 @@ const SelectContent = React.forwardRef(({ className, children, position = "poppe
2261
1896
  });
2262
1897
  SelectContent.displayName = SelectPrimitive.Content.displayName;
2263
1898
 
2264
- const SelectLabel = React.forwardRef(({ className, ...props }: React.ComponentPropsWithoutRef<typeof SelectPrimitive.Label>, ref: React.Ref<React.ElementRef<typeof SelectPrimitive.Label>>) => (
1899
+ const SelectLabel = React.forwardRef<
1900
+ React.ElementRef<typeof SelectPrimitive.Label>,
1901
+ React.ComponentPropsWithoutRef<typeof SelectPrimitive.Label>
1902
+ >(({ className, ...props }, ref) => (
2265
1903
  <SelectPrimitive.Label
2266
1904
  ref={ref}
2267
1905
  className={cn(
@@ -2273,7 +1911,10 @@ const SelectLabel = React.forwardRef(({ className, ...props }: React.ComponentPr
2273
1911
  ));
2274
1912
  SelectLabel.displayName = SelectPrimitive.Label.displayName;
2275
1913
 
2276
- const SelectItem = React.forwardRef(({ className, children, ...props }: React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item>, ref: React.Ref<React.ElementRef<typeof SelectPrimitive.Item>>) => (
1914
+ const SelectItem = React.forwardRef<
1915
+ React.ElementRef<typeof SelectPrimitive.Item>,
1916
+ React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item>
1917
+ >(({ className, children, ...props }, ref) => (
2277
1918
  <SelectPrimitive.Item
2278
1919
  ref={ref}
2279
1920
  className={cn(
@@ -2294,7 +1935,10 @@ const SelectItem = React.forwardRef(({ className, children, ...props }: React.Co
2294
1935
  ));
2295
1936
  SelectItem.displayName = SelectPrimitive.Item.displayName;
2296
1937
 
2297
- const SelectSeparator = React.forwardRef(({ className, ...props }: React.ComponentPropsWithoutRef<typeof SelectPrimitive.Separator>, ref: React.Ref<React.ElementRef<typeof SelectPrimitive.Separator>>) => (
1938
+ const SelectSeparator = React.forwardRef<
1939
+ React.ElementRef<typeof SelectPrimitive.Separator>,
1940
+ React.ComponentPropsWithoutRef<typeof SelectPrimitive.Separator>
1941
+ >(({ className, ...props }, ref) => (
2298
1942
  <SelectPrimitive.Separator
2299
1943
  ref={ref}
2300
1944
  className={cn("-mx-1 my-1 h-px bg-semantic-border-layout", className)}
@@ -2425,7 +2069,10 @@ export interface CheckboxProps
2425
2069
  separateLabel?: boolean;
2426
2070
  }
2427
2071
 
2428
- const Checkbox = React.forwardRef(
2072
+ const Checkbox = React.forwardRef<
2073
+ React.ElementRef<typeof CheckboxPrimitive.Root>,
2074
+ CheckboxProps
2075
+ >(
2429
2076
  (
2430
2077
  {
2431
2078
  className,
@@ -2438,8 +2085,8 @@ const Checkbox = React.forwardRef(
2438
2085
  id,
2439
2086
  disabled,
2440
2087
  ...props
2441
- }: CheckboxProps,
2442
- ref: React.Ref<React.ElementRef<typeof CheckboxPrimitive.Root>>
2088
+ },
2089
+ ref
2443
2090
  ) => {
2444
2091
  const checkbox = (
2445
2092
  <CheckboxPrimitive.Root
@@ -2643,10 +2290,13 @@ export interface SwitchProps
2643
2290
  labelPosition?: "left" | "right";
2644
2291
  }
2645
2292
 
2646
- const Switch = React.forwardRef(
2293
+ const Switch = React.forwardRef<
2294
+ React.ElementRef<typeof SwitchPrimitives.Root>,
2295
+ SwitchProps
2296
+ >(
2647
2297
  (
2648
- { className, size, label, labelPosition = "right", disabled, ...props }: SwitchProps,
2649
- ref: React.Ref<React.ElementRef<typeof SwitchPrimitives.Root>>
2298
+ { className, size, label, labelPosition = "right", disabled, ...props },
2299
+ ref
2650
2300
  ) => {
2651
2301
  const switchElement = (
2652
2302
  <SwitchPrimitives.Root
@@ -2717,7 +2367,16 @@ export { Switch, switchVariants };
2717
2367
  files: [
2718
2368
  {
2719
2369
  name: "text-field.tsx",
2720
- content: prefixTailwindClasses(`import * as React from "react";
2370
+ content: prefixTailwindClasses(`import {
2371
+ forwardRef,
2372
+ useRef,
2373
+ useCallback,
2374
+ useState,
2375
+ useId,
2376
+ type ChangeEvent,
2377
+ type ReactNode,
2378
+ type ComponentProps,
2379
+ } from "react";
2721
2380
  import { cva, type VariantProps } from "class-variance-authority";
2722
2381
  import { Loader2, X } from "lucide-react";
2723
2382
 
@@ -2732,9 +2391,9 @@ const textFieldContainerVariants = cva(
2732
2391
  variants: {
2733
2392
  state: {
2734
2393
  default:
2735
- "border border-semantic-border-input focus-within:border-semantic-border-input-focus focus-within:shadow-[0_0_0_1px_rgba(43,188,202,0.15)]",
2394
+ "border border-semantic-border-input focus-within:border-semantic-border-input-focus/50 focus-within:shadow-[0_0_0_1px_rgba(43,188,202,0.15)]",
2736
2395
  error:
2737
- "border border-semantic-error-primary/40 focus-within:border-semantic-error-primary focus-within:shadow-[0_0_0_1px_rgba(240,68,56,0.1)]",
2396
+ "border border-semantic-error-primary/40 focus-within:border-semantic-error-primary/60 focus-within:shadow-[0_0_0_1px_rgba(240,68,56,0.1)]",
2738
2397
  },
2739
2398
  disabled: {
2740
2399
  true: "cursor-not-allowed opacity-50 bg-[var(--color-neutral-50)]",
@@ -2757,9 +2416,9 @@ const textFieldInputVariants = cva(
2757
2416
  variants: {
2758
2417
  state: {
2759
2418
  default:
2760
- "border border-semantic-border-input focus:outline-none focus:border-semantic-border-input-focus focus:shadow-[0_0_0_1px_rgba(43,188,202,0.15)]",
2419
+ "border 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)]",
2761
2420
  error:
2762
- "border border-semantic-error-primary/40 focus:outline-none focus:border-semantic-error-primary focus:shadow-[0_0_0_1px_rgba(240,68,56,0.1)]",
2421
+ "border 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)]",
2763
2422
  },
2764
2423
  size: {
2765
2424
  default: "h-[42px] px-4 py-2 text-base file:text-base",
@@ -2785,7 +2444,7 @@ const textFieldInputVariants = cva(
2785
2444
  */
2786
2445
  export interface TextFieldProps
2787
2446
  extends
2788
- Omit<React.ComponentProps<"input">, "size">,
2447
+ Omit<ComponentProps<"input">, "size">,
2789
2448
  VariantProps<typeof textFieldInputVariants> {
2790
2449
  /** Size of the text field \u2014 \`default\` (42px) or \`sm\` (36px, compact) */
2791
2450
  size?: "default" | "sm";
@@ -2798,9 +2457,9 @@ export interface TextFieldProps
2798
2457
  /** Error message - shows error state with red styling */
2799
2458
  error?: string;
2800
2459
  /** Icon displayed on the left inside the input */
2801
- leftIcon?: React.ReactNode;
2460
+ leftIcon?: ReactNode;
2802
2461
  /** Icon displayed on the right inside the input */
2803
- rightIcon?: React.ReactNode;
2462
+ rightIcon?: ReactNode;
2804
2463
  /** Text prefix inside input (e.g., "https://") */
2805
2464
  prefix?: string;
2806
2465
  /** Text suffix inside input (e.g., ".com") */
@@ -2821,7 +2480,7 @@ export interface TextFieldProps
2821
2480
  inputContainerClassName?: string;
2822
2481
  }
2823
2482
 
2824
- const TextField = React.forwardRef(
2483
+ const TextField = forwardRef<HTMLInputElement, TextFieldProps>(
2825
2484
  (
2826
2485
  {
2827
2486
  className,
@@ -2851,22 +2510,22 @@ const TextField = React.forwardRef(
2851
2510
  id,
2852
2511
  type,
2853
2512
  ...props
2854
- }: TextFieldProps,
2855
- ref: React.ForwardedRef<HTMLInputElement>
2513
+ },
2514
+ ref
2856
2515
  ) => {
2857
2516
  // Internal ref for programmatic control (e.g., clearable)
2858
- const internalRef = React.useRef<HTMLInputElement | null>(null);
2859
- const mergedRef = React.useCallback(
2517
+ const internalRef = useRef<HTMLInputElement>(null);
2518
+ const mergedRef = useCallback(
2860
2519
  (node: HTMLInputElement | null) => {
2861
2520
  internalRef.current = node;
2862
2521
  if (typeof ref === "function") ref(node);
2863
- else if (ref && typeof ref === "object") ref.current = node;
2522
+ else if (ref) ref.current = node;
2864
2523
  },
2865
2524
  [ref]
2866
2525
  );
2867
2526
 
2868
2527
  // Internal state for character count in uncontrolled mode
2869
- const [internalValue, setInternalValue] = React.useState(
2528
+ const [internalValue, setInternalValue] = useState(
2870
2529
  defaultValue ?? ""
2871
2530
  );
2872
2531
 
@@ -2878,7 +2537,7 @@ const TextField = React.forwardRef(
2878
2537
  const derivedState = error ? "error" : (state ?? "default");
2879
2538
 
2880
2539
  // Handle change for both controlled and uncontrolled
2881
- const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
2540
+ const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
2882
2541
  if (!isControlled) {
2883
2542
  setInternalValue(e.target.value);
2884
2543
  }
@@ -2905,7 +2564,7 @@ const TextField = React.forwardRef(
2905
2564
  const charCount = String(currentValue).length;
2906
2565
 
2907
2566
  // Generate unique IDs for accessibility
2908
- const generatedId = React.useId();
2567
+ const generatedId = useId();
2909
2568
  const inputId = id || generatedId;
2910
2569
  const helperId = \`\${inputId}-helper\`;
2911
2570
  const errorId = \`\${inputId}-error\`;
@@ -3024,12 +2683,12 @@ const TextField = React.forwardRef(
3024
2683
  {error ? (
3025
2684
  <span
3026
2685
  id={errorId}
3027
- className="text-sm text-semantic-error-primary"
2686
+ className="text-xs text-semantic-error-primary"
3028
2687
  >
3029
2688
  {error}
3030
2689
  </span>
3031
2690
  ) : helperText ? (
3032
- <span id={helperId} className="text-sm text-semantic-text-muted">
2691
+ <span id={helperId} className="text-xs text-semantic-text-muted">
3033
2692
  {helperText}
3034
2693
  </span>
3035
2694
  ) : (
@@ -3038,7 +2697,7 @@ const TextField = React.forwardRef(
3038
2697
  {showCount && maxLength && (
3039
2698
  <span
3040
2699
  className={cn(
3041
- "text-sm",
2700
+ "text-xs",
3042
2701
  charCount > maxLength
3043
2702
  ? "text-semantic-error-primary"
3044
2703
  : "text-semantic-text-muted"
@@ -3056,225 +2715,6 @@ const TextField = React.forwardRef(
3056
2715
  TextField.displayName = "TextField";
3057
2716
 
3058
2717
  export { TextField, textFieldContainerVariants, textFieldInputVariants };
3059
- `, prefix)
3060
- }
3061
- ]
3062
- },
3063
- "textarea": {
3064
- name: "textarea",
3065
- description: "A multi-line text input with label, error state, helper text, character counter, and resize control",
3066
- category: "form",
3067
- dependencies: [
3068
- "class-variance-authority",
3069
- "clsx",
3070
- "tailwind-merge"
3071
- ],
3072
- files: [
3073
- {
3074
- name: "textarea.tsx",
3075
- content: prefixTailwindClasses(`import * as React from "react";
3076
- import { cva, type VariantProps } from "class-variance-authority";
3077
-
3078
- import { cn } from "../../lib/utils";
3079
-
3080
- /**
3081
- * Textarea variants for different visual states
3082
- */
3083
- const textareaVariants = cva(
3084
- "w-full rounded bg-semantic-bg-primary text-semantic-text-primary outline-none transition-all placeholder:text-semantic-text-placeholder disabled:cursor-not-allowed disabled:opacity-50 disabled:bg-[var(--color-neutral-50)]",
3085
- {
3086
- variants: {
3087
- state: {
3088
- default:
3089
- "border border-semantic-border-input focus:outline-none focus:border-semantic-border-input-focus focus:shadow-[0_0_0_1px_rgba(43,188,202,0.15)]",
3090
- error:
3091
- "border border-semantic-error-primary/40 focus:outline-none focus:border-semantic-error-primary focus:shadow-[0_0_0_1px_rgba(240,68,56,0.1)]",
3092
- },
3093
- size: {
3094
- default: "px-4 py-2.5 text-base",
3095
- sm: "px-3 py-2 text-sm",
3096
- },
3097
- },
3098
- defaultVariants: {
3099
- state: "default",
3100
- size: "default",
3101
- },
3102
- }
3103
- );
3104
-
3105
- /**
3106
- * A multi-line text input with label, error state, helper text, character counter, and resize control.
3107
- *
3108
- * @example
3109
- * \`\`\`tsx
3110
- * <Textarea label="Description" placeholder="Enter description" />
3111
- * <Textarea label="Notes" error="Too short" showCount maxLength={500} />
3112
- * <Textarea label="JSON" rows={8} resize="vertical" />
3113
- * \`\`\`
3114
- */
3115
- export interface TextareaProps
3116
- extends Omit<React.ComponentProps<"textarea">, "size">,
3117
- VariantProps<typeof textareaVariants> {
3118
- /** Size of the textarea \u2014 \`default\` or \`sm\` (compact) */
3119
- size?: "default" | "sm";
3120
- /** Label text displayed above the textarea */
3121
- label?: string;
3122
- /** Shows red asterisk next to label when true */
3123
- required?: boolean;
3124
- /** Helper text displayed below the textarea */
3125
- helperText?: string;
3126
- /** Error message \u2014 shows error state with red styling */
3127
- error?: string;
3128
- /** Shows character count when maxLength is set */
3129
- showCount?: boolean;
3130
- /** Controls CSS resize behavior. Defaults to "none" */
3131
- resize?: "none" | "vertical" | "horizontal" | "both";
3132
- /** Additional class for the wrapper container */
3133
- wrapperClassName?: string;
3134
- /** Additional class for the label */
3135
- labelClassName?: string;
3136
- }
3137
-
3138
- const Textarea = React.forwardRef(
3139
- (
3140
- {
3141
- className,
3142
- wrapperClassName,
3143
- labelClassName,
3144
- state,
3145
- size,
3146
- label,
3147
- required,
3148
- helperText,
3149
- error,
3150
- showCount,
3151
- resize = "none",
3152
- maxLength,
3153
- rows = 4,
3154
- value,
3155
- defaultValue,
3156
- onChange,
3157
- disabled,
3158
- id,
3159
- ...props
3160
- }: TextareaProps,
3161
- ref: React.ForwardedRef<HTMLTextAreaElement>
3162
- ) => {
3163
- // Internal state for character count in uncontrolled mode
3164
- const [internalValue, setInternalValue] = React.useState(
3165
- defaultValue ?? ""
3166
- );
3167
-
3168
- // Determine if controlled
3169
- const isControlled = value !== undefined;
3170
- const currentValue = isControlled ? value : internalValue;
3171
-
3172
- // Derive state from props
3173
- const derivedState = error ? "error" : (state ?? "default");
3174
-
3175
- // Handle change for both controlled and uncontrolled
3176
- const handleChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
3177
- if (!isControlled) {
3178
- setInternalValue(e.target.value);
3179
- }
3180
- onChange?.(e);
3181
- };
3182
-
3183
- // Character count
3184
- const charCount = String(currentValue).length;
3185
-
3186
- // Generate unique IDs for accessibility
3187
- const generatedId = React.useId();
3188
- const textareaId = id || generatedId;
3189
- const helperId = \`\${textareaId}-helper\`;
3190
- const errorId = \`\${textareaId}-error\`;
3191
-
3192
- // Determine aria-describedby
3193
- const ariaDescribedBy = error ? errorId : helperText ? helperId : undefined;
3194
-
3195
- // Resize class map
3196
- const resizeClasses: Record<string, string> = {
3197
- none: "resize-none",
3198
- vertical: "resize-y",
3199
- horizontal: "resize-x",
3200
- both: "resize",
3201
- };
3202
-
3203
- return (
3204
- <div className={cn("flex flex-col gap-1", wrapperClassName)}>
3205
- {/* Label */}
3206
- {label && (
3207
- <label
3208
- htmlFor={textareaId}
3209
- className={cn(
3210
- "text-sm font-medium text-semantic-text-muted",
3211
- labelClassName
3212
- )}
3213
- >
3214
- {label}
3215
- {required && (
3216
- <span className="text-semantic-error-primary ml-0.5">*</span>
3217
- )}
3218
- </label>
3219
- )}
3220
-
3221
- {/* Textarea */}
3222
- <textarea
3223
- ref={ref}
3224
- id={textareaId}
3225
- rows={rows}
3226
- className={cn(
3227
- textareaVariants({ state: derivedState, size, className }),
3228
- resizeClasses[resize]
3229
- )}
3230
- disabled={disabled}
3231
- maxLength={maxLength}
3232
- value={isControlled ? value : undefined}
3233
- defaultValue={!isControlled ? defaultValue : undefined}
3234
- onChange={handleChange}
3235
- aria-invalid={!!error}
3236
- aria-describedby={ariaDescribedBy}
3237
- {...props}
3238
- />
3239
-
3240
- {/* Helper text / Error message / Character count */}
3241
- {(error || helperText || (showCount && maxLength)) && (
3242
- <div className="flex justify-between items-start gap-2">
3243
- {error ? (
3244
- <span
3245
- id={errorId}
3246
- className="text-sm text-semantic-error-primary"
3247
- >
3248
- {error}
3249
- </span>
3250
- ) : helperText ? (
3251
- <span id={helperId} className="text-sm text-semantic-text-muted">
3252
- {helperText}
3253
- </span>
3254
- ) : (
3255
- <span />
3256
- )}
3257
- {showCount && maxLength && (
3258
- <span
3259
- className={cn(
3260
- "text-sm",
3261
- charCount > maxLength
3262
- ? "text-semantic-error-primary"
3263
- : "text-semantic-text-muted"
3264
- )}
3265
- >
3266
- {charCount}/{maxLength}
3267
- </span>
3268
- )}
3269
- </div>
3270
- )}
3271
- </div>
3272
- );
3273
- }
3274
- );
3275
- Textarea.displayName = "Textarea";
3276
-
3277
- export { Textarea, textareaVariants };
3278
2718
  `, prefix)
3279
2719
  }
3280
2720
  ]
@@ -3345,7 +2785,7 @@ export interface ReadableFieldProps
3345
2785
  * />
3346
2786
  * \`\`\`
3347
2787
  */
3348
- export const ReadableField = React.forwardRef(
2788
+ export const ReadableField = React.forwardRef<HTMLDivElement, ReadableFieldProps>(
3349
2789
  (
3350
2790
  {
3351
2791
  label,
@@ -3357,8 +2797,8 @@ export const ReadableField = React.forwardRef(
3357
2797
  className,
3358
2798
  inputClassName,
3359
2799
  ...props
3360
- }: ReadableFieldProps,
3361
- ref: React.Ref<HTMLDivElement>
2800
+ },
2801
+ ref
3362
2802
  ) => {
3363
2803
  const [copied, setCopied] = React.useState(false);
3364
2804
  const [isVisible, setIsVisible] = React.useState(!secret);
@@ -3612,7 +3052,7 @@ export interface SelectFieldProps {
3612
3052
  * />
3613
3053
  * \`\`\`
3614
3054
  */
3615
- const SelectField = React.forwardRef(
3055
+ const SelectField = React.forwardRef<HTMLButtonElement, SelectFieldProps>(
3616
3056
  (
3617
3057
  {
3618
3058
  label,
@@ -3635,8 +3075,8 @@ const SelectField = React.forwardRef(
3635
3075
  labelClassName,
3636
3076
  id,
3637
3077
  name,
3638
- }: SelectFieldProps,
3639
- ref: React.Ref<HTMLButtonElement>
3078
+ },
3079
+ ref
3640
3080
  ) => {
3641
3081
  // Internal state for search
3642
3082
  const [searchQuery, setSearchQuery] = React.useState("");
@@ -3964,7 +3404,7 @@ export interface MultiSelectProps extends VariantProps<
3964
3404
  * />
3965
3405
  * \`\`\`
3966
3406
  */
3967
- const MultiSelect = React.forwardRef(
3407
+ const MultiSelect = React.forwardRef<HTMLButtonElement, MultiSelectProps>(
3968
3408
  (
3969
3409
  {
3970
3410
  label,
@@ -3987,8 +3427,8 @@ const MultiSelect = React.forwardRef(
3987
3427
  state,
3988
3428
  id,
3989
3429
  name,
3990
- }: MultiSelectProps,
3991
- ref: React.Ref<HTMLButtonElement>
3430
+ },
3431
+ ref
3992
3432
  ) => {
3993
3433
  // Internal state for selected values (uncontrolled mode)
3994
3434
  const [internalValue, setInternalValue] =
@@ -4011,6 +3451,7 @@ const MultiSelect = React.forwardRef(
4011
3451
  // Generate unique IDs for accessibility
4012
3452
  const generatedId = React.useId();
4013
3453
  const selectId = id || generatedId;
3454
+ const listboxId = \`\${selectId}-listbox\`;
4014
3455
  const helperId = \`\${selectId}-helper\`;
4015
3456
  const errorId = \`\${selectId}-error\`;
4016
3457
 
@@ -4124,6 +3565,7 @@ const MultiSelect = React.forwardRef(
4124
3565
  role="combobox"
4125
3566
  aria-expanded={isOpen}
4126
3567
  aria-haspopup="listbox"
3568
+ aria-controls={listboxId}
4127
3569
  aria-invalid={!!error}
4128
3570
  aria-describedby={ariaDescribedBy}
4129
3571
  disabled={disabled || loading}
@@ -4203,6 +3645,7 @@ const MultiSelect = React.forwardRef(
4203
3645
  {/* Dropdown */}
4204
3646
  {isOpen && (
4205
3647
  <div
3648
+ id={listboxId}
4206
3649
  className={cn(
4207
3650
  "absolute z-50 mt-1 w-full rounded bg-semantic-bg-primary border border-semantic-border-layout shadow-md",
4208
3651
  "top-full"
@@ -4372,7 +3815,7 @@ export interface CreatableSelectProps
4372
3815
  maxLength?: number
4373
3816
  }
4374
3817
 
4375
- const CreatableSelect = React.forwardRef(
3818
+ const CreatableSelect = React.forwardRef<HTMLDivElement, CreatableSelectProps>(
4376
3819
  (
4377
3820
  {
4378
3821
  className,
@@ -4385,8 +3828,8 @@ const CreatableSelect = React.forwardRef(
4385
3828
  disabled = false,
4386
3829
  maxLength,
4387
3830
  ...props
4388
- }: CreatableSelectProps,
4389
- ref: React.Ref<HTMLDivElement>
3831
+ },
3832
+ ref
4390
3833
  ) => {
4391
3834
  const [open, setOpen] = React.useState(false)
4392
3835
  const [search, setSearch] = React.useState("")
@@ -4394,6 +3837,7 @@ const CreatableSelect = React.forwardRef(
4394
3837
  const containerRef = React.useRef<HTMLDivElement>(null)
4395
3838
  const inputRef = React.useRef<HTMLInputElement>(null)
4396
3839
  const listRef = React.useRef<HTMLDivElement>(null)
3840
+ const listboxId = React.useId()
4397
3841
 
4398
3842
  // Merge forwarded ref with internal ref
4399
3843
  React.useImperativeHandle(ref, () => containerRef.current!)
@@ -4536,6 +3980,7 @@ const CreatableSelect = React.forwardRef(
4536
3980
  placeholder={selectedLabel || placeholder}
4537
3981
  aria-expanded="true"
4538
3982
  aria-haspopup="listbox"
3983
+ aria-controls={listboxId}
4539
3984
  role="combobox"
4540
3985
  aria-autocomplete="list"
4541
3986
  />
@@ -4552,6 +3997,7 @@ const CreatableSelect = React.forwardRef(
4552
3997
  )}
4553
3998
  aria-haspopup="listbox"
4554
3999
  aria-expanded="false"
4000
+ aria-controls={listboxId}
4555
4001
  >
4556
4002
  <span
4557
4003
  className={cn(
@@ -4581,6 +4027,7 @@ const CreatableSelect = React.forwardRef(
4581
4027
  {/* Options list */}
4582
4028
  <div
4583
4029
  ref={listRef}
4030
+ id={listboxId}
4584
4031
  role="listbox"
4585
4032
  className="max-h-60 overflow-y-auto p-1"
4586
4033
  >
@@ -4717,7 +4164,10 @@ export interface CreatableMultiSelectProps
4717
4164
  maxLengthPerItem?: number
4718
4165
  }
4719
4166
 
4720
- const CreatableMultiSelect = React.forwardRef(
4167
+ const CreatableMultiSelect = React.forwardRef<
4168
+ HTMLDivElement,
4169
+ CreatableMultiSelectProps
4170
+ >(
4721
4171
  (
4722
4172
  {
4723
4173
  className,
@@ -4732,13 +4182,14 @@ const CreatableMultiSelect = React.forwardRef(
4732
4182
  maxItems,
4733
4183
  maxLengthPerItem,
4734
4184
  ...props
4735
- }: CreatableMultiSelectProps,
4736
- ref: React.Ref<HTMLDivElement>
4185
+ },
4186
+ ref
4737
4187
  ) => {
4738
4188
  const [isOpen, setIsOpen] = React.useState(false)
4739
4189
  const [inputValue, setInputValue] = React.useState("")
4740
4190
  const containerRef = React.useRef<HTMLDivElement>(null)
4741
4191
  const inputRef = React.useRef<HTMLInputElement>(null)
4192
+ const listboxId = React.useId()
4742
4193
 
4743
4194
  React.useImperativeHandle(ref, () => containerRef.current!)
4744
4195
 
@@ -4876,6 +4327,7 @@ const CreatableMultiSelect = React.forwardRef(
4876
4327
  className="flex-1 min-w-[100px] text-base bg-transparent outline-none text-semantic-text-primary placeholder:text-semantic-text-muted"
4877
4328
  role="combobox"
4878
4329
  aria-expanded={isOpen}
4330
+ aria-controls={listboxId}
4879
4331
  aria-haspopup="listbox"
4880
4332
  />
4881
4333
 
@@ -4889,7 +4341,7 @@ const CreatableMultiSelect = React.forwardRef(
4889
4341
 
4890
4342
  {/* Dropdown panel */}
4891
4343
  {isOpen && (
4892
- <div className="absolute z-[9999] top-full mt-1 w-full bg-semantic-bg-primary border border-semantic-border-layout rounded shadow-md animate-in fade-in-0 zoom-in-95 slide-in-from-top-2 duration-200">
4344
+ <div id={listboxId} role="listbox" className="absolute z-[9999] top-full mt-1 w-full bg-semantic-bg-primary border border-semantic-border-layout rounded shadow-md animate-in fade-in-0 zoom-in-95 slide-in-from-top-2 duration-200">
4893
4345
  {/* Creatable hint \u2014 Enter key */}
4894
4346
  <div className="flex items-center justify-between px-4 py-2 border-b border-semantic-border-layout">
4895
4347
  <span className="text-sm text-semantic-text-muted">
@@ -5028,8 +4480,8 @@ export interface TableProps
5028
4480
  wrapContent?: boolean;
5029
4481
  }
5030
4482
 
5031
- const Table = React.forwardRef(
5032
- ({ className, size, withoutBorder, wrapContent, ...props }: TableProps, ref: React.Ref<HTMLTableElement>) => (
4483
+ const Table = React.forwardRef<HTMLTableElement, TableProps>(
4484
+ ({ className, size, withoutBorder, wrapContent, ...props }, ref) => (
5033
4485
  <div
5034
4486
  className={cn(
5035
4487
  "relative w-full overflow-auto",
@@ -5050,7 +4502,10 @@ const Table = React.forwardRef(
5050
4502
  );
5051
4503
  Table.displayName = "Table";
5052
4504
 
5053
- const TableHeader = React.forwardRef(({ className, ...props }: React.HTMLAttributes<HTMLTableSectionElement>, ref: React.Ref<HTMLTableSectionElement>) => (
4505
+ const TableHeader = React.forwardRef<
4506
+ HTMLTableSectionElement,
4507
+ React.HTMLAttributes<HTMLTableSectionElement>
4508
+ >(({ className, ...props }, ref) => (
5054
4509
  <thead
5055
4510
  ref={ref}
5056
4511
  className={cn("bg-[var(--color-neutral-100)] [&_tr]:border-b", className)}
@@ -5069,8 +4524,8 @@ export interface TableBodyProps
5069
4524
  loadingColumns?: number;
5070
4525
  }
5071
4526
 
5072
- const TableBody = React.forwardRef(
5073
- ({ className, isLoading, loadingRows = 5, loadingColumns = 5, children, ...props }: TableBodyProps, ref: React.Ref<HTMLTableSectionElement>) => (
4527
+ const TableBody = React.forwardRef<HTMLTableSectionElement, TableBodyProps>(
4528
+ ({ className, isLoading, loadingRows = 5, loadingColumns = 5, children, ...props }, ref) => (
5074
4529
  <tbody
5075
4530
  ref={ref}
5076
4531
  className={cn("[&_tr:last-child]:border-0", className)}
@@ -5086,7 +4541,10 @@ const TableBody = React.forwardRef(
5086
4541
  );
5087
4542
  TableBody.displayName = "TableBody";
5088
4543
 
5089
- const TableFooter = React.forwardRef(({ className, ...props }: React.HTMLAttributes<HTMLTableSectionElement>, ref: React.Ref<HTMLTableSectionElement>) => (
4544
+ const TableFooter = React.forwardRef<
4545
+ HTMLTableSectionElement,
4546
+ React.HTMLAttributes<HTMLTableSectionElement>
4547
+ >(({ className, ...props }, ref) => (
5090
4548
  <tfoot
5091
4549
  ref={ref}
5092
4550
  className={cn(
@@ -5103,8 +4561,8 @@ export interface TableRowProps extends React.HTMLAttributes<HTMLTableRowElement>
5103
4561
  highlighted?: boolean;
5104
4562
  }
5105
4563
 
5106
- const TableRow = React.forwardRef(
5107
- ({ className, highlighted, ...props }: TableRowProps, ref: React.Ref<HTMLTableRowElement>) => (
4564
+ const TableRow = React.forwardRef<HTMLTableRowElement, TableRowProps>(
4565
+ ({ className, highlighted, ...props }, ref) => (
5108
4566
  <tr
5109
4567
  ref={ref}
5110
4568
  className={cn(
@@ -5129,10 +4587,10 @@ export interface TableHeadProps extends React.ThHTMLAttributes<HTMLTableCellElem
5129
4587
  infoTooltip?: string;
5130
4588
  }
5131
4589
 
5132
- const TableHead = React.forwardRef(
4590
+ const TableHead = React.forwardRef<HTMLTableCellElement, TableHeadProps>(
5133
4591
  (
5134
- { className, sticky, sortDirection, infoTooltip, children, ...props }: TableHeadProps,
5135
- ref: React.Ref<HTMLTableCellElement>
4592
+ { className, sticky, sortDirection, infoTooltip, children, ...props },
4593
+ ref
5136
4594
  ) => (
5137
4595
  <th
5138
4596
  ref={ref}
@@ -5170,8 +4628,8 @@ export interface TableCellProps extends React.TdHTMLAttributes<HTMLTableCellElem
5170
4628
  sticky?: boolean;
5171
4629
  }
5172
4630
 
5173
- const TableCell = React.forwardRef(
5174
- ({ className, sticky, ...props }: TableCellProps, ref: React.Ref<HTMLTableCellElement>) => (
4631
+ const TableCell = React.forwardRef<HTMLTableCellElement, TableCellProps>(
4632
+ ({ className, sticky, ...props }, ref) => (
5175
4633
  <td
5176
4634
  ref={ref}
5177
4635
  className={cn(
@@ -5185,7 +4643,10 @@ const TableCell = React.forwardRef(
5185
4643
  );
5186
4644
  TableCell.displayName = "TableCell";
5187
4645
 
5188
- const TableCaption = React.forwardRef(({ className, ...props }: React.HTMLAttributes<HTMLTableCaptionElement>, ref: React.Ref<HTMLTableCaptionElement>) => (
4646
+ const TableCaption = React.forwardRef<
4647
+ HTMLTableCaptionElement,
4648
+ React.HTMLAttributes<HTMLTableCaptionElement>
4649
+ >(({ className, ...props }, ref) => (
5189
4650
  <caption
5190
4651
  ref={ref}
5191
4652
  className={cn("mt-4 text-sm text-semantic-text-muted", className)}
@@ -5274,8 +4735,8 @@ export interface TableToggleProps extends Omit<SwitchProps, "size"> {
5274
4735
  size?: "sm" | "default";
5275
4736
  }
5276
4737
 
5277
- const TableToggle = React.forwardRef(
5278
- ({ size = "sm", ...props }: TableToggleProps, ref: React.Ref<HTMLButtonElement>) => (
4738
+ const TableToggle = React.forwardRef<HTMLButtonElement, TableToggleProps>(
4739
+ ({ size = "sm", ...props }, ref) => (
5279
4740
  <Switch ref={ref} size={size} {...props} />
5280
4741
  )
5281
4742
  );
@@ -5340,7 +4801,10 @@ export interface TabsListProps
5340
4801
  fullWidth?: boolean
5341
4802
  }
5342
4803
 
5343
- const TabsList = React.forwardRef(({ className, fullWidth, ...props }: TabsListProps, ref: React.Ref<React.ComponentRef<typeof TabsPrimitive.List>>) => (
4804
+ const TabsList = React.forwardRef<
4805
+ React.ComponentRef<typeof TabsPrimitive.List>,
4806
+ TabsListProps
4807
+ >(({ className, fullWidth, ...props }, ref) => (
5344
4808
  <TabsPrimitive.List
5345
4809
  ref={ref}
5346
4810
  className={cn(
@@ -5353,7 +4817,10 @@ const TabsList = React.forwardRef(({ className, fullWidth, ...props }: TabsListP
5353
4817
  ))
5354
4818
  TabsList.displayName = TabsPrimitive.List.displayName
5355
4819
 
5356
- const TabsTrigger = React.forwardRef(({ className, ...props }: React.ComponentPropsWithoutRef<typeof TabsPrimitive.Trigger>, ref: React.Ref<React.ComponentRef<typeof TabsPrimitive.Trigger>>) => (
4820
+ const TabsTrigger = React.forwardRef<
4821
+ React.ComponentRef<typeof TabsPrimitive.Trigger>,
4822
+ React.ComponentPropsWithoutRef<typeof TabsPrimitive.Trigger>
4823
+ >(({ className, ...props }, ref) => (
5357
4824
  <TabsPrimitive.Trigger
5358
4825
  ref={ref}
5359
4826
  className={cn(
@@ -5368,7 +4835,10 @@ const TabsTrigger = React.forwardRef(({ className, ...props }: React.ComponentPr
5368
4835
  ))
5369
4836
  TabsTrigger.displayName = TabsPrimitive.Trigger.displayName
5370
4837
 
5371
- const TabsContent = React.forwardRef(({ className, ...props }: React.ComponentPropsWithoutRef<typeof TabsPrimitive.Content>, ref: React.Ref<React.ComponentRef<typeof TabsPrimitive.Content>>) => (
4838
+ const TabsContent = React.forwardRef<
4839
+ React.ComponentRef<typeof TabsPrimitive.Content>,
4840
+ React.ComponentPropsWithoutRef<typeof TabsPrimitive.Content>
4841
+ >(({ className, ...props }, ref) => (
5372
4842
  <TabsPrimitive.Content
5373
4843
  ref={ref}
5374
4844
  className={cn(
@@ -5415,7 +4885,10 @@ const DialogPortal = DialogPrimitive.Portal;
5415
4885
 
5416
4886
  const DialogClose = DialogPrimitive.Close;
5417
4887
 
5418
- const DialogOverlay = React.forwardRef(({ className, ...props }: React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>, ref: React.Ref<React.ElementRef<typeof DialogPrimitive.Overlay>>) => (
4888
+ const DialogOverlay = React.forwardRef<
4889
+ React.ElementRef<typeof DialogPrimitive.Overlay>,
4890
+ React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>
4891
+ >(({ className, ...props }, ref) => (
5419
4892
  <DialogPrimitive.Overlay
5420
4893
  ref={ref}
5421
4894
  className={cn(
@@ -5473,7 +4946,10 @@ const hasDialogDescription = (children: React.ReactNode): boolean => {
5473
4946
  return found;
5474
4947
  };
5475
4948
 
5476
- const DialogContent = React.forwardRef(({ className, children, size, hideCloseButton = false, ...props }: DialogContentProps, ref: React.Ref<React.ElementRef<typeof DialogPrimitive.Content>>) => {
4949
+ const DialogContent = React.forwardRef<
4950
+ React.ElementRef<typeof DialogPrimitive.Content>,
4951
+ DialogContentProps
4952
+ >(({ className, children, size, hideCloseButton = false, ...props }, ref) => {
5477
4953
  const hasDescription = hasDialogDescription(children);
5478
4954
 
5479
4955
  return (
@@ -5531,7 +5007,10 @@ const DialogFooter = ({
5531
5007
  );
5532
5008
  DialogFooter.displayName = "DialogFooter";
5533
5009
 
5534
- const DialogTitle = React.forwardRef(({ className, ...props }: React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>, ref: React.Ref<React.ElementRef<typeof DialogPrimitive.Title>>) => (
5010
+ const DialogTitle = React.forwardRef<
5011
+ React.ElementRef<typeof DialogPrimitive.Title>,
5012
+ React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>
5013
+ >(({ className, ...props }, ref) => (
5535
5014
  <DialogPrimitive.Title
5536
5015
  ref={ref}
5537
5016
  className={cn(
@@ -5543,7 +5022,10 @@ const DialogTitle = React.forwardRef(({ className, ...props }: React.ComponentPr
5543
5022
  ));
5544
5023
  DialogTitle.displayName = DialogPrimitive.Title.displayName;
5545
5024
 
5546
- const DialogDescription = React.forwardRef(({ className, ...props }: React.ComponentPropsWithoutRef<typeof DialogPrimitive.Description>, ref: React.Ref<React.ElementRef<typeof DialogPrimitive.Description>>) => (
5025
+ const DialogDescription = React.forwardRef<
5026
+ React.ElementRef<typeof DialogPrimitive.Description>,
5027
+ React.ComponentPropsWithoutRef<typeof DialogPrimitive.Description>
5028
+ >(({ className, ...props }, ref) => (
5547
5029
  <DialogPrimitive.Description
5548
5030
  ref={ref}
5549
5031
  className={cn("text-sm text-muted-foreground", className)}
@@ -5591,7 +5073,10 @@ import { cn } from "../../lib/utils";
5591
5073
 
5592
5074
  const DropdownMenu = DropdownMenuPrimitive.Root;
5593
5075
 
5594
- const DropdownMenuTrigger = React.forwardRef(({ className, ...props }: React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Trigger>, ref: React.Ref<React.ElementRef<typeof DropdownMenuPrimitive.Trigger>>) => (
5076
+ const DropdownMenuTrigger = React.forwardRef<
5077
+ React.ElementRef<typeof DropdownMenuPrimitive.Trigger>,
5078
+ React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Trigger>
5079
+ >(({ className, ...props }, ref) => (
5595
5080
  <DropdownMenuPrimitive.Trigger
5596
5081
  ref={ref}
5597
5082
  className={cn("focus-visible:outline-none focus-visible:ring-0", className)}
@@ -5608,9 +5093,12 @@ const DropdownMenuSub = DropdownMenuPrimitive.Sub;
5608
5093
 
5609
5094
  const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;
5610
5095
 
5611
- const DropdownMenuSubTrigger = React.forwardRef(({ className, inset, children, ...props }: React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubTrigger> & {
5096
+ const DropdownMenuSubTrigger = React.forwardRef<
5097
+ React.ElementRef<typeof DropdownMenuPrimitive.SubTrigger>,
5098
+ React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubTrigger> & {
5612
5099
  inset?: boolean;
5613
- }, ref: React.Ref<React.ElementRef<typeof DropdownMenuPrimitive.SubTrigger>>) => (
5100
+ }
5101
+ >(({ className, inset, children, ...props }, ref) => (
5614
5102
  <DropdownMenuPrimitive.SubTrigger
5615
5103
  ref={ref}
5616
5104
  className={cn(
@@ -5627,7 +5115,10 @@ const DropdownMenuSubTrigger = React.forwardRef(({ className, inset, children, .
5627
5115
  DropdownMenuSubTrigger.displayName =
5628
5116
  DropdownMenuPrimitive.SubTrigger.displayName;
5629
5117
 
5630
- const DropdownMenuSubContent = React.forwardRef(({ className, ...props }: React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubContent>, ref: React.Ref<React.ElementRef<typeof DropdownMenuPrimitive.SubContent>>) => (
5118
+ const DropdownMenuSubContent = React.forwardRef<
5119
+ React.ElementRef<typeof DropdownMenuPrimitive.SubContent>,
5120
+ React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubContent>
5121
+ >(({ className, ...props }, ref) => (
5631
5122
  <DropdownMenuPrimitive.SubContent
5632
5123
  ref={ref}
5633
5124
  className={cn(
@@ -5640,7 +5131,10 @@ const DropdownMenuSubContent = React.forwardRef(({ className, ...props }: React.
5640
5131
  DropdownMenuSubContent.displayName =
5641
5132
  DropdownMenuPrimitive.SubContent.displayName;
5642
5133
 
5643
- const DropdownMenuContent = React.forwardRef(({ className, sideOffset = 4, ...props }: React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content>, ref: React.Ref<React.ElementRef<typeof DropdownMenuPrimitive.Content>>) => (
5134
+ const DropdownMenuContent = React.forwardRef<
5135
+ React.ElementRef<typeof DropdownMenuPrimitive.Content>,
5136
+ React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content>
5137
+ >(({ className, sideOffset = 4, ...props }, ref) => (
5644
5138
  <DropdownMenuPrimitive.Portal>
5645
5139
  <DropdownMenuPrimitive.Content
5646
5140
  ref={ref}
@@ -5656,17 +5150,20 @@ const DropdownMenuContent = React.forwardRef(({ className, sideOffset = 4, ...pr
5656
5150
  ));
5657
5151
  DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName;
5658
5152
 
5659
- const DropdownMenuItem = React.forwardRef(({ className, inset, children, description, suffix, ...props }: React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item> & {
5153
+ const DropdownMenuItem = React.forwardRef<
5154
+ React.ElementRef<typeof DropdownMenuPrimitive.Item>,
5155
+ React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item> & {
5660
5156
  inset?: boolean;
5661
5157
  /** Secondary text displayed below children */
5662
5158
  description?: string;
5663
5159
  /** Content displayed at the right edge of the item */
5664
5160
  suffix?: React.ReactNode;
5665
- }, ref: React.Ref<React.ElementRef<typeof DropdownMenuPrimitive.Item>>) => (
5161
+ }
5162
+ >(({ className, inset, children, description, suffix, ...props }, ref) => (
5666
5163
  <DropdownMenuPrimitive.Item
5667
5164
  ref={ref}
5668
5165
  className={cn(
5669
- "relative flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-2 text-sm text-semantic-text-secondary outline-none transition-colors focus:bg-semantic-bg-ui focus:text-semantic-text-primary data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
5166
+ "relative flex cursor-pointer select-none items-center rounded-sm px-2 py-2 text-sm text-semantic-text-secondary outline-none transition-colors focus:bg-semantic-bg-ui focus:text-semantic-text-primary data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
5670
5167
  inset && "pl-8",
5671
5168
  className
5672
5169
  )}
@@ -5687,12 +5184,15 @@ const DropdownMenuItem = React.forwardRef(({ className, inset, children, descrip
5687
5184
  ));
5688
5185
  DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName;
5689
5186
 
5690
- const DropdownMenuCheckboxItem = React.forwardRef(({ className, children, checked, description, suffix, ...props }: React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.CheckboxItem> & {
5187
+ const DropdownMenuCheckboxItem = React.forwardRef<
5188
+ React.ElementRef<typeof DropdownMenuPrimitive.CheckboxItem>,
5189
+ React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.CheckboxItem> & {
5691
5190
  /** Secondary text displayed below children */
5692
5191
  description?: string;
5693
5192
  /** Content displayed at the right edge of the item */
5694
5193
  suffix?: React.ReactNode;
5695
- }, ref: React.Ref<React.ElementRef<typeof DropdownMenuPrimitive.CheckboxItem>>) => (
5194
+ }
5195
+ >(({ className, children, checked, description, suffix, ...props }, ref) => (
5696
5196
  <DropdownMenuPrimitive.CheckboxItem
5697
5197
  ref={ref}
5698
5198
  className={cn(
@@ -5723,12 +5223,15 @@ const DropdownMenuCheckboxItem = React.forwardRef(({ className, children, checke
5723
5223
  DropdownMenuCheckboxItem.displayName =
5724
5224
  DropdownMenuPrimitive.CheckboxItem.displayName;
5725
5225
 
5726
- const DropdownMenuRadioItem = React.forwardRef(({ className, children, description, suffix, ...props }: React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.RadioItem> & {
5226
+ const DropdownMenuRadioItem = React.forwardRef<
5227
+ React.ElementRef<typeof DropdownMenuPrimitive.RadioItem>,
5228
+ React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.RadioItem> & {
5727
5229
  /** Secondary text displayed below children */
5728
5230
  description?: string;
5729
5231
  /** Content displayed at the right edge of the item */
5730
5232
  suffix?: React.ReactNode;
5731
- }, ref: React.Ref<React.ElementRef<typeof DropdownMenuPrimitive.RadioItem>>) => (
5233
+ }
5234
+ >(({ className, children, description, suffix, ...props }, ref) => (
5732
5235
  <DropdownMenuPrimitive.RadioItem
5733
5236
  ref={ref}
5734
5237
  className={cn(
@@ -5757,9 +5260,12 @@ const DropdownMenuRadioItem = React.forwardRef(({ className, children, descripti
5757
5260
  ));
5758
5261
  DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName;
5759
5262
 
5760
- const DropdownMenuLabel = React.forwardRef(({ className, inset, ...props }: React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Label> & {
5263
+ const DropdownMenuLabel = React.forwardRef<
5264
+ React.ElementRef<typeof DropdownMenuPrimitive.Label>,
5265
+ React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Label> & {
5761
5266
  inset?: boolean;
5762
- }, ref: React.Ref<React.ElementRef<typeof DropdownMenuPrimitive.Label>>) => (
5267
+ }
5268
+ >(({ className, inset, ...props }, ref) => (
5763
5269
  <DropdownMenuPrimitive.Label
5764
5270
  ref={ref}
5765
5271
  className={cn(
@@ -5772,7 +5278,10 @@ const DropdownMenuLabel = React.forwardRef(({ className, inset, ...props }: Reac
5772
5278
  ));
5773
5279
  DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName;
5774
5280
 
5775
- const DropdownMenuSeparator = React.forwardRef(({ className, ...props }: React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Separator>, ref: React.Ref<React.ElementRef<typeof DropdownMenuPrimitive.Separator>>) => (
5281
+ const DropdownMenuSeparator = React.forwardRef<
5282
+ React.ElementRef<typeof DropdownMenuPrimitive.Separator>,
5283
+ React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Separator>
5284
+ >(({ className, ...props }, ref) => (
5776
5285
  <DropdownMenuPrimitive.Separator
5777
5286
  ref={ref}
5778
5287
  className={cn("-mx-1 my-1 h-px bg-semantic-border-layout", className)}
@@ -5839,7 +5348,10 @@ const Tooltip = TooltipPrimitive.Root;
5839
5348
 
5840
5349
  const TooltipTrigger = TooltipPrimitive.Trigger;
5841
5350
 
5842
- const TooltipContent = React.forwardRef(({ className, sideOffset = 4, ...props }: React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content>, ref: React.Ref<React.ElementRef<typeof TooltipPrimitive.Content>>) => (
5351
+ const TooltipContent = React.forwardRef<
5352
+ React.ElementRef<typeof TooltipPrimitive.Content>,
5353
+ React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content>
5354
+ >(({ className, sideOffset = 4, ...props }, ref) => (
5843
5355
  <TooltipPrimitive.Portal>
5844
5356
  <TooltipPrimitive.Content
5845
5357
  ref={ref}
@@ -5854,7 +5366,10 @@ const TooltipContent = React.forwardRef(({ className, sideOffset = 4, ...props }
5854
5366
  ));
5855
5367
  TooltipContent.displayName = TooltipPrimitive.Content.displayName;
5856
5368
 
5857
- const TooltipArrow = React.forwardRef(({ className, ...props }: React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Arrow>, ref: React.Ref<React.ElementRef<typeof TooltipPrimitive.Arrow>>) => (
5369
+ const TooltipArrow = React.forwardRef<
5370
+ React.ElementRef<typeof TooltipPrimitive.Arrow>,
5371
+ React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Arrow>
5372
+ >(({ className, ...props }, ref) => (
5858
5373
  <TooltipPrimitive.Arrow
5859
5374
  ref={ref}
5860
5375
  className={cn("fill-semantic-primary", className)}
@@ -5958,7 +5473,10 @@ export interface DeleteConfirmationModalProps {
5958
5473
  * />
5959
5474
  * \`\`\`
5960
5475
  */
5961
- const DeleteConfirmationModal = React.forwardRef(
5476
+ const DeleteConfirmationModal = React.forwardRef<
5477
+ HTMLDivElement,
5478
+ DeleteConfirmationModalProps
5479
+ >(
5962
5480
  (
5963
5481
  {
5964
5482
  open,
@@ -5974,8 +5492,8 @@ const DeleteConfirmationModal = React.forwardRef(
5974
5492
  cancelButtonText = "Cancel",
5975
5493
  trigger,
5976
5494
  className,
5977
- }: DeleteConfirmationModalProps,
5978
- ref: React.Ref<HTMLDivElement>
5495
+ },
5496
+ ref
5979
5497
  ) => {
5980
5498
  const [inputValue, setInputValue] = React.useState("");
5981
5499
  const isConfirmEnabled = inputValue === confirmText;
@@ -6143,7 +5661,10 @@ export interface ConfirmationModalProps {
6143
5661
  * />
6144
5662
  * \`\`\`
6145
5663
  */
6146
- const ConfirmationModal = React.forwardRef(
5664
+ const ConfirmationModal = React.forwardRef<
5665
+ HTMLDivElement,
5666
+ ConfirmationModalProps
5667
+ >(
6147
5668
  (
6148
5669
  {
6149
5670
  open,
@@ -6158,8 +5679,8 @@ const ConfirmationModal = React.forwardRef(
6158
5679
  cancelButtonText = "Cancel",
6159
5680
  trigger,
6160
5681
  className,
6161
- }: ConfirmationModalProps,
6162
- ref: React.Ref<HTMLDivElement>
5682
+ },
5683
+ ref
6163
5684
  ) => {
6164
5685
  const handleConfirm = () => {
6165
5686
  onConfirm?.();
@@ -6291,7 +5812,7 @@ export interface FormModalProps {
6291
5812
  * </FormModal>
6292
5813
  * \`\`\`
6293
5814
  */
6294
- const FormModal = React.forwardRef(
5815
+ const FormModal = React.forwardRef<HTMLDivElement, FormModalProps>(
6295
5816
  (
6296
5817
  {
6297
5818
  open,
@@ -6307,8 +5828,8 @@ const FormModal = React.forwardRef(
6307
5828
  disableSave = false,
6308
5829
  className,
6309
5830
  size = "sm",
6310
- }: FormModalProps,
6311
- ref: React.Ref<HTMLDivElement>
5831
+ },
5832
+ ref
6312
5833
  ) => {
6313
5834
  const handleSave = () => {
6314
5835
  onSave?.();
@@ -6423,8 +5944,8 @@ export interface TagProps
6423
5944
  label?: string;
6424
5945
  }
6425
5946
 
6426
- const Tag = React.forwardRef(
6427
- ({ className, variant, size, label, children, ...props }: TagProps, ref: React.Ref<HTMLSpanElement>) => {
5947
+ const Tag = React.forwardRef<HTMLSpanElement, TagProps>(
5948
+ ({ className, variant, size, label, children, ...props }, ref) => {
6428
5949
  return (
6429
5950
  <span
6430
5951
  className={cn(tagVariants({ variant, size, className }))}
@@ -6432,7 +5953,7 @@ const Tag = React.forwardRef(
6432
5953
  {...props}
6433
5954
  >
6434
5955
  {label && <span className="font-semibold mr-1">{label}</span>}
6435
- <span className="font-normal inline-flex items-center gap-1">{children}</span>
5956
+ <span className="font-normal">{children}</span>
6436
5957
  </span>
6437
5958
  );
6438
5959
  }
@@ -6620,7 +6141,7 @@ export interface AlertProps
6620
6141
  defaultOpen?: boolean;
6621
6142
  }
6622
6143
 
6623
- const Alert = React.forwardRef(
6144
+ const Alert = React.forwardRef<HTMLDivElement, AlertProps>(
6624
6145
  (
6625
6146
  {
6626
6147
  className,
@@ -6635,8 +6156,8 @@ const Alert = React.forwardRef(
6635
6156
  defaultOpen = true,
6636
6157
  children,
6637
6158
  ...props
6638
- }: AlertProps,
6639
- ref: React.Ref<HTMLDivElement>
6159
+ },
6160
+ ref
6640
6161
  ) => {
6641
6162
  const [internalOpen, setInternalOpen] = React.useState(defaultOpen);
6642
6163
  const isControlled = controlledOpen !== undefined;
@@ -6708,19 +6229,27 @@ Alert.displayName = "Alert";
6708
6229
  /**
6709
6230
  * Alert title component for the heading text.
6710
6231
  */
6711
- const AlertTitle = React.forwardRef(({ className, ...props }: React.HTMLAttributes<HTMLHeadingElement>, ref: React.Ref<HTMLHeadingElement>) => (
6232
+ const AlertTitle = React.forwardRef<
6233
+ HTMLHeadingElement,
6234
+ React.HTMLAttributes<HTMLHeadingElement>
6235
+ >(({ className, children, ...props }, ref) => (
6712
6236
  <h5
6713
6237
  ref={ref}
6714
6238
  className={cn("font-semibold leading-tight tracking-tight", className)}
6715
6239
  {...props}
6716
- />
6240
+ >
6241
+ {children}
6242
+ </h5>
6717
6243
  ));
6718
6244
  AlertTitle.displayName = "AlertTitle";
6719
6245
 
6720
6246
  /**
6721
6247
  * Alert description component for the body text.
6722
6248
  */
6723
- const AlertDescription = React.forwardRef(({ className, ...props }: React.HTMLAttributes<HTMLParagraphElement>, ref: React.Ref<HTMLParagraphElement>) => (
6249
+ const AlertDescription = React.forwardRef<
6250
+ HTMLParagraphElement,
6251
+ React.HTMLAttributes<HTMLParagraphElement>
6252
+ >(({ className, ...props }, ref) => (
6724
6253
  <p ref={ref} className={cn("m-0 mt-1 text-sm", className)} {...props} />
6725
6254
  ));
6726
6255
  AlertDescription.displayName = "AlertDescription";
@@ -6754,7 +6283,10 @@ import { cn } from "../../lib/utils";
6754
6283
 
6755
6284
  const ToastProvider = ToastPrimitives.Provider;
6756
6285
 
6757
- const ToastViewport = React.forwardRef(({ className, ...props }: React.ComponentPropsWithoutRef<typeof ToastPrimitives.Viewport>, ref: React.Ref<React.ElementRef<typeof ToastPrimitives.Viewport>>) => (
6286
+ const ToastViewport = React.forwardRef<
6287
+ React.ElementRef<typeof ToastPrimitives.Viewport>,
6288
+ React.ComponentPropsWithoutRef<typeof ToastPrimitives.Viewport>
6289
+ >(({ className, ...props }, ref) => (
6758
6290
  <ToastPrimitives.Viewport
6759
6291
  ref={ref}
6760
6292
  className={cn(
@@ -6788,8 +6320,11 @@ const toastVariants = cva(
6788
6320
  }
6789
6321
  );
6790
6322
 
6791
- const Toast = React.forwardRef(({ className, variant, ...props }: React.ComponentPropsWithoutRef<typeof ToastPrimitives.Root> &
6792
- VariantProps<typeof toastVariants>, ref: React.Ref<React.ElementRef<typeof ToastPrimitives.Root>>) => {
6323
+ const Toast = React.forwardRef<
6324
+ React.ElementRef<typeof ToastPrimitives.Root>,
6325
+ React.ComponentPropsWithoutRef<typeof ToastPrimitives.Root> &
6326
+ VariantProps<typeof toastVariants>
6327
+ >(({ className, variant, ...props }, ref) => {
6793
6328
  return (
6794
6329
  <ToastPrimitives.Root
6795
6330
  ref={ref}
@@ -6800,7 +6335,10 @@ const Toast = React.forwardRef(({ className, variant, ...props }: React.Componen
6800
6335
  });
6801
6336
  Toast.displayName = ToastPrimitives.Root.displayName;
6802
6337
 
6803
- const ToastAction = React.forwardRef(({ className, ...props }: React.ComponentPropsWithoutRef<typeof ToastPrimitives.Action>, ref: React.Ref<React.ElementRef<typeof ToastPrimitives.Action>>) => (
6338
+ const ToastAction = React.forwardRef<
6339
+ React.ElementRef<typeof ToastPrimitives.Action>,
6340
+ React.ComponentPropsWithoutRef<typeof ToastPrimitives.Action>
6341
+ >(({ className, ...props }, ref) => (
6804
6342
  <ToastPrimitives.Action
6805
6343
  ref={ref}
6806
6344
  className={cn(
@@ -6816,7 +6354,10 @@ const ToastAction = React.forwardRef(({ className, ...props }: React.ComponentPr
6816
6354
  ));
6817
6355
  ToastAction.displayName = ToastPrimitives.Action.displayName;
6818
6356
 
6819
- const ToastClose = React.forwardRef(({ className, ...props }: React.ComponentPropsWithoutRef<typeof ToastPrimitives.Close>, ref: React.Ref<React.ElementRef<typeof ToastPrimitives.Close>>) => (
6357
+ const ToastClose = React.forwardRef<
6358
+ React.ElementRef<typeof ToastPrimitives.Close>,
6359
+ React.ComponentPropsWithoutRef<typeof ToastPrimitives.Close>
6360
+ >(({ className, ...props }, ref) => (
6820
6361
  <ToastPrimitives.Close
6821
6362
  ref={ref}
6822
6363
  className={cn(
@@ -6831,7 +6372,10 @@ const ToastClose = React.forwardRef(({ className, ...props }: React.ComponentPro
6831
6372
  ));
6832
6373
  ToastClose.displayName = ToastPrimitives.Close.displayName;
6833
6374
 
6834
- const ToastTitle = React.forwardRef(({ className, ...props }: React.ComponentPropsWithoutRef<typeof ToastPrimitives.Title>, ref: React.Ref<React.ElementRef<typeof ToastPrimitives.Title>>) => (
6375
+ const ToastTitle = React.forwardRef<
6376
+ React.ElementRef<typeof ToastPrimitives.Title>,
6377
+ React.ComponentPropsWithoutRef<typeof ToastPrimitives.Title>
6378
+ >(({ className, ...props }, ref) => (
6835
6379
  <ToastPrimitives.Title
6836
6380
  ref={ref}
6837
6381
  className={cn("text-sm font-semibold tracking-[0.014px]", className)}
@@ -6840,7 +6384,10 @@ const ToastTitle = React.forwardRef(({ className, ...props }: React.ComponentPro
6840
6384
  ));
6841
6385
  ToastTitle.displayName = ToastPrimitives.Title.displayName;
6842
6386
 
6843
- const ToastDescription = React.forwardRef(({ className, ...props }: React.ComponentPropsWithoutRef<typeof ToastPrimitives.Description>, ref: React.Ref<React.ElementRef<typeof ToastPrimitives.Description>>) => (
6387
+ const ToastDescription = React.forwardRef<
6388
+ React.ElementRef<typeof ToastPrimitives.Description>,
6389
+ React.ComponentPropsWithoutRef<typeof ToastPrimitives.Description>
6390
+ >(({ className, ...props }, ref) => (
6844
6391
  <ToastPrimitives.Description
6845
6392
  ref={ref}
6846
6393
  className={cn("text-xs tracking-[0.048px]", className)}
@@ -7289,7 +6836,7 @@ export interface SpinnerProps
7289
6836
  "aria-label"?: string;
7290
6837
  }
7291
6838
 
7292
- const Spinner = React.forwardRef(
6839
+ const Spinner = React.forwardRef<HTMLDivElement, SpinnerProps>(
7293
6840
  (
7294
6841
  {
7295
6842
  className,
@@ -7297,8 +6844,8 @@ const Spinner = React.forwardRef(
7297
6844
  variant,
7298
6845
  "aria-label": ariaLabel = "Loading",
7299
6846
  ...props
7300
- }: SpinnerProps,
7301
- ref: React.Ref<HTMLDivElement>
6847
+ },
6848
+ ref
7302
6849
  ) => {
7303
6850
  const strokeWidth = strokeWidths[size || "default"] ?? 3;
7304
6851
  const radius = 10;
@@ -7418,8 +6965,8 @@ export interface SkeletonProps
7418
6965
  height?: number | string;
7419
6966
  }
7420
6967
 
7421
- const Skeleton = React.forwardRef(
7422
- ({ className, variant, shape, width, height, style, ...props }: SkeletonProps, ref: React.Ref<HTMLDivElement>) => {
6968
+ const Skeleton = React.forwardRef<HTMLDivElement, SkeletonProps>(
6969
+ ({ className, variant, shape, width, height, style, ...props }, ref) => {
7423
6970
  const dimensionStyle: React.CSSProperties = {
7424
6971
  ...style,
7425
6972
  ...(width !== undefined
@@ -7662,7 +7209,7 @@ export interface AccordionProps
7662
7209
  onValueChange?: (value: string[]) => void;
7663
7210
  }
7664
7211
 
7665
- const Accordion = React.forwardRef(
7212
+ const Accordion = React.forwardRef<HTMLDivElement, AccordionProps>(
7666
7213
  (
7667
7214
  {
7668
7215
  className,
@@ -7673,8 +7220,8 @@ const Accordion = React.forwardRef(
7673
7220
  onValueChange,
7674
7221
  children,
7675
7222
  ...props
7676
- }: AccordionProps,
7677
- ref: React.Ref<HTMLDivElement>
7223
+ },
7224
+ ref
7678
7225
  ) => {
7679
7226
  const [internalValue, setInternalValue] =
7680
7227
  React.useState<string[]>(defaultValue);
@@ -7730,8 +7277,8 @@ export interface AccordionItemProps
7730
7277
  disabled?: boolean;
7731
7278
  }
7732
7279
 
7733
- const AccordionItem = React.forwardRef(
7734
- ({ className, value, disabled, children, ...props }: AccordionItemProps, ref: React.Ref<HTMLDivElement>) => {
7280
+ const AccordionItem = React.forwardRef<HTMLDivElement, AccordionItemProps>(
7281
+ ({ className, value, disabled, children, ...props }, ref) => {
7735
7282
  const { value: openValues, variant } = useAccordionContext();
7736
7283
  const isOpen = openValues.includes(value);
7737
7284
 
@@ -7771,7 +7318,10 @@ export interface AccordionTriggerProps
7771
7318
  showChevron?: boolean;
7772
7319
  }
7773
7320
 
7774
- const AccordionTrigger = React.forwardRef(({ className, showChevron = true, children, ...props }: AccordionTriggerProps, ref: React.Ref<HTMLButtonElement>) => {
7321
+ const AccordionTrigger = React.forwardRef<
7322
+ HTMLButtonElement,
7323
+ AccordionTriggerProps
7324
+ >(({ className, showChevron = true, children, ...props }, ref) => {
7775
7325
  const {
7776
7326
  type,
7777
7327
  value: openValues,
@@ -7830,7 +7380,10 @@ export interface AccordionContentProps
7830
7380
  React.HTMLAttributes<HTMLDivElement>,
7831
7381
  VariantProps<typeof accordionContentVariants> {}
7832
7382
 
7833
- const AccordionContent = React.forwardRef(({ className, children, ...props }: AccordionContentProps, ref: React.Ref<HTMLDivElement>) => {
7383
+ const AccordionContent = React.forwardRef<
7384
+ HTMLDivElement,
7385
+ AccordionContentProps
7386
+ >(({ className, children, ...props }, ref) => {
7834
7387
  const { variant } = useAccordionContext();
7835
7388
  const { isOpen } = useAccordionItemContext();
7836
7389
  const contentRef = React.useRef<HTMLDivElement>(null);
@@ -7962,7 +7515,7 @@ export interface PageHeaderProps
7962
7515
  mobileOverflowLimit?: number;
7963
7516
  }
7964
7517
 
7965
- const PageHeader = React.forwardRef(
7518
+ const PageHeader = React.forwardRef<HTMLDivElement, PageHeaderProps>(
7966
7519
  (
7967
7520
  {
7968
7521
  className,
@@ -7978,8 +7531,8 @@ const PageHeader = React.forwardRef(
7978
7531
  layout = "responsive",
7979
7532
  mobileOverflowLimit = 2,
7980
7533
  ...props
7981
- }: PageHeaderProps,
7982
- ref: React.Ref<HTMLDivElement>
7534
+ },
7535
+ ref
7983
7536
  ) => {
7984
7537
  // State for overflow expansion (moved to top level)
7985
7538
  const [isOverflowExpanded, setIsOverflowExpanded] = React.useState(false);
@@ -8267,7 +7820,7 @@ export interface PanelProps
8267
7820
  * </Panel>
8268
7821
  * \`\`\`
8269
7822
  */
8270
- const Panel = React.forwardRef(
7823
+ const Panel = React.forwardRef<HTMLElement, PanelProps>(
8271
7824
  (
8272
7825
  {
8273
7826
  open = true,
@@ -8281,8 +7834,8 @@ const Panel = React.forwardRef(
8281
7834
  "aria-label": ariaLabel,
8282
7835
  onKeyDown,
8283
7836
  ...props
8284
- }: PanelProps,
8285
- ref: React.Ref<HTMLElement>
7837
+ },
7838
+ ref
8286
7839
  ) => {
8287
7840
  const resolvedSize = size ?? "default";
8288
7841
  const widthClass = panelWidths[resolvedSize];
@@ -8726,7 +8279,10 @@ import type { EventSelectorProps, EventCategory, EventGroup } from "./types";
8726
8279
  * />
8727
8280
  * \`\`\`
8728
8281
  */
8729
- export const EventSelector = React.forwardRef(
8282
+ export const EventSelector = React.forwardRef<
8283
+ HTMLDivElement,
8284
+ EventSelectorProps
8285
+ >(
8730
8286
  (
8731
8287
  {
8732
8288
  events,
@@ -8741,8 +8297,8 @@ export const EventSelector = React.forwardRef(
8741
8297
  renderEmptyGroup,
8742
8298
  className,
8743
8299
  ...props
8744
- }: EventSelectorProps,
8745
- ref: React.Ref<HTMLDivElement>
8300
+ },
8301
+ ref
8746
8302
  ) => {
8747
8303
  // Controlled vs uncontrolled state
8748
8304
  const [internalSelected, setInternalSelected] = React.useState<string[]>(
@@ -8903,7 +8459,10 @@ import type { EventGroupComponentProps } from "./types";
8903
8459
  /**
8904
8460
  * Event group with accordion section and group-level checkbox
8905
8461
  */
8906
- export const EventGroupComponent = React.forwardRef(
8462
+ export const EventGroupComponent = React.forwardRef<
8463
+ HTMLDivElement,
8464
+ EventGroupComponentProps & React.HTMLAttributes<HTMLDivElement>
8465
+ >(
8907
8466
  (
8908
8467
  {
8909
8468
  group,
@@ -8915,8 +8474,8 @@ export const EventGroupComponent = React.forwardRef(
8915
8474
  defaultExpanded = false,
8916
8475
  className,
8917
8476
  ...props
8918
- }: EventGroupComponentProps & React.HTMLAttributes<HTMLDivElement>,
8919
- ref: React.Ref<HTMLDivElement>
8477
+ },
8478
+ ref
8920
8479
  ) => {
8921
8480
  // Calculate selection state for this group
8922
8481
  const groupEventIds = events.map((e) => e.id);
@@ -9079,7 +8638,10 @@ import type { EventItemComponentProps } from "./types";
9079
8638
  /**
9080
8639
  * Individual event item with checkbox
9081
8640
  */
9082
- export const EventItemComponent = React.forwardRef(({ event, isSelected, onSelectionChange, className, ...props }: EventItemComponentProps & React.HTMLAttributes<HTMLDivElement>, ref: React.Ref<HTMLDivElement>) => {
8641
+ export const EventItemComponent = React.forwardRef<
8642
+ HTMLDivElement,
8643
+ EventItemComponentProps & React.HTMLAttributes<HTMLDivElement>
8644
+ >(({ event, isSelected, onSelectionChange, className, ...props }, ref) => {
9083
8645
  return (
9084
8646
  <div
9085
8647
  ref={ref}
@@ -9290,7 +8852,10 @@ const generateId = () =>
9290
8852
  * />
9291
8853
  * \`\`\`
9292
8854
  */
9293
- export const KeyValueInput = React.forwardRef(
8855
+ export const KeyValueInput = React.forwardRef<
8856
+ HTMLDivElement,
8857
+ KeyValueInputProps
8858
+ >(
9294
8859
  (
9295
8860
  {
9296
8861
  title,
@@ -9308,8 +8873,8 @@ export const KeyValueInput = React.forwardRef(
9308
8873
  defaultValue = [],
9309
8874
  className,
9310
8875
  ...props
9311
- }: KeyValueInputProps,
9312
- ref: React.Ref<HTMLDivElement>
8876
+ },
8877
+ ref
9313
8878
  ) => {
9314
8879
  // Controlled vs uncontrolled state
9315
8880
  const [internalPairs, setInternalPairs] =
@@ -9506,7 +9071,10 @@ import type { KeyValueRowProps } from "./types";
9506
9071
  /**
9507
9072
  * Individual key-value pair row with inputs and delete button
9508
9073
  */
9509
- export const KeyValueRow = React.forwardRef(
9074
+ export const KeyValueRow = React.forwardRef<
9075
+ HTMLDivElement,
9076
+ KeyValueRowProps & React.HTMLAttributes<HTMLDivElement>
9077
+ >(
9510
9078
  (
9511
9079
  {
9512
9080
  pair,
@@ -9522,8 +9090,8 @@ export const KeyValueRow = React.forwardRef(
9522
9090
  onDelete,
9523
9091
  className,
9524
9092
  ...props
9525
- }: KeyValueRowProps & React.HTMLAttributes<HTMLDivElement>,
9526
- ref: React.Ref<HTMLDivElement>
9093
+ },
9094
+ ref
9527
9095
  ) => {
9528
9096
  // Determine if inputs should show error state
9529
9097
  const keyHasError = isDuplicateKey || (keyRequired && isKeyEmpty);
@@ -9738,7 +9306,10 @@ export interface ApiFeatureCardProps
9738
9306
  * />
9739
9307
  * \`\`\`
9740
9308
  */
9741
- export const ApiFeatureCard = React.forwardRef(
9309
+ export const ApiFeatureCard = React.forwardRef<
9310
+ HTMLDivElement,
9311
+ ApiFeatureCardProps
9312
+ >(
9742
9313
  (
9743
9314
  {
9744
9315
  icon,
@@ -9751,8 +9322,8 @@ export const ApiFeatureCard = React.forwardRef(
9751
9322
  capabilitiesLabel = "Key Capabilities",
9752
9323
  className,
9753
9324
  ...props
9754
- }: ApiFeatureCardProps,
9755
- ref: React.Ref<HTMLDivElement>
9325
+ },
9326
+ ref
9756
9327
  ) => {
9757
9328
  return (
9758
9329
  <div
@@ -9924,7 +9495,10 @@ export interface EndpointDetailsProps
9924
9495
  * />
9925
9496
  * \`\`\`
9926
9497
  */
9927
- export const EndpointDetails = React.forwardRef(
9498
+ export const EndpointDetails = React.forwardRef<
9499
+ HTMLDivElement,
9500
+ EndpointDetailsProps
9501
+ >(
9928
9502
  (
9929
9503
  {
9930
9504
  title = "Endpoint Details",
@@ -9945,8 +9519,8 @@ export const EndpointDetails = React.forwardRef(
9945
9519
  revokeDescription = "Revoking access will immediately disable all integrations using these keys.",
9946
9520
  className,
9947
9521
  ...props
9948
- }: EndpointDetailsProps,
9949
- ref: React.Ref<HTMLDivElement>
9522
+ },
9523
+ ref
9950
9524
  ) => {
9951
9525
  const isCalling = variant === "calling";
9952
9526
 
@@ -10136,7 +9710,10 @@ export interface AlertConfigurationProps {
10136
9710
  * AlertConfiguration component displays current alert values for minimum balance and top-up.
10137
9711
  * Used in payment auto-pay setup to show notification thresholds.
10138
9712
  */
10139
- export const AlertConfiguration = React.forwardRef(
9713
+ export const AlertConfiguration = React.forwardRef<
9714
+ HTMLDivElement,
9715
+ AlertConfigurationProps
9716
+ >(
10140
9717
  (
10141
9718
  {
10142
9719
  minimumBalance,
@@ -10144,8 +9721,8 @@ export const AlertConfiguration = React.forwardRef(
10144
9721
  currencySymbol = "\u20B9",
10145
9722
  onEdit,
10146
9723
  className,
10147
- }: AlertConfigurationProps,
10148
- ref: React.Ref<HTMLDivElement>
9724
+ },
9725
+ ref
10149
9726
  ) => {
10150
9727
  const formatCurrency = (amount: number) => {
10151
9728
  const formatted = amount.toLocaleString("en-IN", {
@@ -10280,7 +9857,10 @@ export interface AlertValuesModalProps {
10280
9857
  * AlertValuesModal component for editing alert configuration values.
10281
9858
  * Displays a form with inputs for minimum balance and minimum top-up.
10282
9859
  */
10283
- export const AlertValuesModal = React.forwardRef(
9860
+ export const AlertValuesModal = React.forwardRef<
9861
+ HTMLDivElement,
9862
+ AlertValuesModalProps
9863
+ >(
10284
9864
  (
10285
9865
  {
10286
9866
  open,
@@ -10292,8 +9872,8 @@ export const AlertValuesModal = React.forwardRef(
10292
9872
  topupOptions,
10293
9873
  onSave,
10294
9874
  loading = false,
10295
- }: AlertValuesModalProps,
10296
- ref: React.Ref<HTMLDivElement>
9875
+ },
9876
+ ref
10297
9877
  ) => {
10298
9878
  const [minimumBalance, setMinimumBalance] = React.useState(
10299
9879
  initialMinimumBalance.toString()
@@ -10442,7 +10022,7 @@ import type { AutoPaySetupProps } from "./types";
10442
10022
  * />
10443
10023
  * \`\`\`
10444
10024
  */
10445
- export const AutoPaySetup = React.forwardRef(
10025
+ export const AutoPaySetup = React.forwardRef<HTMLDivElement, AutoPaySetupProps>(
10446
10026
  (
10447
10027
  {
10448
10028
  title = "Auto-pay setup",
@@ -10461,8 +10041,8 @@ export const AutoPaySetup = React.forwardRef(
10461
10041
  open,
10462
10042
  onOpenChange,
10463
10043
  className,
10464
- }: AutoPaySetupProps,
10465
- ref: React.Ref<HTMLDivElement>
10044
+ },
10045
+ ref
10466
10046
  ) => {
10467
10047
  const isControlled = open !== undefined;
10468
10048
 
@@ -10653,7 +10233,7 @@ import type { BankDetailsProps, BankDetailItem } from "./types";
10653
10233
  * />
10654
10234
  * \`\`\`
10655
10235
  */
10656
- export const BankDetails = React.forwardRef(
10236
+ export const BankDetails = React.forwardRef<HTMLDivElement, BankDetailsProps>(
10657
10237
  (
10658
10238
  {
10659
10239
  title = "Bank details",
@@ -10665,8 +10245,8 @@ export const BankDetails = React.forwardRef(
10665
10245
  onOpenChange,
10666
10246
  onCopy,
10667
10247
  className,
10668
- }: BankDetailsProps,
10669
- ref: React.Ref<HTMLDivElement>
10248
+ },
10249
+ ref
10670
10250
  ) => {
10671
10251
  const isControlled = open !== undefined;
10672
10252
 
@@ -11482,8 +11062,8 @@ const BreakdownCardRow = ({ item }: { item: BreakdownCardItem }) => (
11482
11062
  * />
11483
11063
  * \`\`\`
11484
11064
  */
11485
- export const PaymentSummary = React.forwardRef(
11486
- ({ items = [], summaryItems, className, title, headerInfo, subtotal, breakdownCard, creditLimit }: PaymentSummaryProps, ref: React.Ref<HTMLDivElement>) => {
11065
+ export const PaymentSummary = React.forwardRef<HTMLDivElement, PaymentSummaryProps>(
11066
+ ({ items = [], summaryItems, className, title, headerInfo, subtotal, breakdownCard, creditLimit }, ref) => {
11487
11067
  const hasItemsBorder =
11488
11068
  items.length > 0 &&
11489
11069
  (!!subtotal || !!breakdownCard || (summaryItems && summaryItems.length > 0));
@@ -11680,7 +11260,10 @@ import type { PaymentOptionCardProps } from "./types";
11680
11260
  * />
11681
11261
  * \`\`\`
11682
11262
  */
11683
- export const PaymentOptionCard = React.forwardRef(
11263
+ export const PaymentOptionCard = React.forwardRef<
11264
+ HTMLDivElement,
11265
+ PaymentOptionCardProps
11266
+ >(
11684
11267
  (
11685
11268
  {
11686
11269
  title = "Select payment method",
@@ -11695,8 +11278,8 @@ export const PaymentOptionCard = React.forwardRef(
11695
11278
  loading = false,
11696
11279
  disabled = false,
11697
11280
  className,
11698
- }: PaymentOptionCardProps,
11699
- ref: React.Ref<HTMLDivElement>
11281
+ },
11282
+ ref
11700
11283
  ) => {
11701
11284
  const [internalSelected, setInternalSelected] = React.useState<
11702
11285
  string | undefined
@@ -11829,7 +11412,10 @@ export interface PaymentOptionCardModalProps
11829
11412
  * />
11830
11413
  * \`\`\`
11831
11414
  */
11832
- export const PaymentOptionCardModal = React.forwardRef(
11415
+ export const PaymentOptionCardModal = React.forwardRef<
11416
+ HTMLDivElement,
11417
+ PaymentOptionCardModalProps
11418
+ >(
11833
11419
  (
11834
11420
  {
11835
11421
  open,
@@ -11845,8 +11431,8 @@ export const PaymentOptionCardModal = React.forwardRef(
11845
11431
  loading,
11846
11432
  disabled,
11847
11433
  className,
11848
- }: PaymentOptionCardModalProps,
11849
- ref: React.Ref<HTMLDivElement>
11434
+ },
11435
+ ref
11850
11436
  ) => {
11851
11437
  const handleClose = () => {
11852
11438
  onOpenChange(false);
@@ -11984,7 +11570,7 @@ const DEFAULT_FEATURES: PlanFeature[] = [
11984
11570
  { name: "Channel(s)", free: "1 Pair(s)", rate: "\u20B9 300.00" },
11985
11571
  ];
11986
11572
 
11987
- const PlanDetailModal = React.forwardRef(
11573
+ const PlanDetailModal = React.forwardRef<HTMLDivElement, PlanDetailModalProps>(
11988
11574
  (
11989
11575
  {
11990
11576
  open,
@@ -11995,8 +11581,8 @@ const PlanDetailModal = React.forwardRef(
11995
11581
  onClose,
11996
11582
  className,
11997
11583
  ...props
11998
- }: PlanDetailModalProps,
11999
- ref: React.Ref<HTMLDivElement>
11584
+ },
11585
+ ref
12000
11586
  ) => {
12001
11587
  const handleClose = () => {
12002
11588
  onClose?.();
@@ -12205,7 +11791,7 @@ const renderOptionIcon = (icon: BillingCycleOption["icon"]) => {
12205
11791
  return icon;
12206
11792
  };
12207
11793
 
12208
- const PlanUpgradeModal = React.forwardRef(
11794
+ const PlanUpgradeModal = React.forwardRef<HTMLDivElement, PlanUpgradeModalProps>(
12209
11795
  (
12210
11796
  {
12211
11797
  open,
@@ -12222,8 +11808,8 @@ const PlanUpgradeModal = React.forwardRef(
12222
11808
  onClose,
12223
11809
  className,
12224
11810
  ...props
12225
- }: PlanUpgradeModalProps,
12226
- ref: React.Ref<HTMLDivElement>
11811
+ },
11812
+ ref
12227
11813
  ) => {
12228
11814
  const initialOptionId = defaultSelectedOptionId ?? options[0]?.id;
12229
11815
  const [internalSelectedOptionId, setInternalSelectedOptionId] = React.useState<
@@ -12501,7 +12087,10 @@ const getStatusIcon = (tone: PlanUpgradeSummaryTone) => {
12501
12087
  return <AlertCircle className="size-6 text-semantic-warning-text" aria-hidden="true" />;
12502
12088
  };
12503
12089
 
12504
- const PlanUpgradeSummaryModal = React.forwardRef(
12090
+ const PlanUpgradeSummaryModal = React.forwardRef<
12091
+ HTMLDivElement,
12092
+ PlanUpgradeSummaryModalProps
12093
+ >(
12505
12094
  (
12506
12095
  {
12507
12096
  open,
@@ -12523,8 +12112,8 @@ const PlanUpgradeSummaryModal = React.forwardRef(
12523
12112
  closeAriaLabel = "Close plan summary modal",
12524
12113
  className,
12525
12114
  ...props
12526
- }: PlanUpgradeSummaryModalProps,
12527
- ref: React.Ref<HTMLDivElement>
12115
+ },
12116
+ ref
12528
12117
  ) => {
12529
12118
  const resolvedStatus = status ?? defaultStatusByMode[mode];
12530
12119
  const resolvedTone = resolvedStatus.tone ?? defaultStatusByMode[mode].tone ?? "warning";
@@ -12761,7 +12350,7 @@ import type { LetUsDriveCardProps } from "./types";
12761
12350
  * />
12762
12351
  * \`\`\`
12763
12352
  */
12764
- const LetUsDriveCard = React.forwardRef(
12353
+ const LetUsDriveCard = React.forwardRef<HTMLDivElement, LetUsDriveCardProps>(
12765
12354
  (
12766
12355
  {
12767
12356
  title,
@@ -12781,8 +12370,8 @@ const LetUsDriveCard = React.forwardRef(
12781
12370
  onCtaClick,
12782
12371
  className,
12783
12372
  ...props
12784
- }: LetUsDriveCardProps,
12785
- ref: React.Ref<HTMLDivElement>
12373
+ },
12374
+ ref
12786
12375
  ) => {
12787
12376
  const [internalExpanded, setInternalExpanded] = React.useState(false);
12788
12377
  const isControlled = controlledExpanded !== undefined;
@@ -12806,7 +12395,7 @@ const LetUsDriveCard = React.forwardRef(
12806
12395
  <div
12807
12396
  ref={ref}
12808
12397
  className={cn(
12809
- "flex min-h-0 flex-col gap-6 rounded-[14px] border border-semantic-border-layout bg-card p-5 shadow-sm",
12398
+ "flex h-full min-h-0 flex-col gap-6 rounded-[14px] border border-semantic-border-layout bg-card p-5 shadow-sm",
12810
12399
  className
12811
12400
  )}
12812
12401
  {...props}
@@ -13045,7 +12634,7 @@ import type { PowerUpCardProps } from "./types";
13045
12634
  * />
13046
12635
  * \`\`\`
13047
12636
  */
13048
- const PowerUpCard = React.forwardRef(
12637
+ const PowerUpCard = React.forwardRef<HTMLDivElement, PowerUpCardProps>(
13049
12638
  (
13050
12639
  {
13051
12640
  icon,
@@ -13056,8 +12645,8 @@ const PowerUpCard = React.forwardRef(
13056
12645
  onCtaClick,
13057
12646
  className,
13058
12647
  ...props
13059
- }: PowerUpCardProps,
13060
- ref: React.Ref<HTMLDivElement>
12648
+ },
12649
+ ref
13061
12650
  ) => {
13062
12651
  return (
13063
12652
  <div
@@ -13184,7 +12773,7 @@ import type { PricingCardProps } from "./types";
13184
12773
  * />
13185
12774
  * \`\`\`
13186
12775
  */
13187
- const PricingCard = React.forwardRef(
12776
+ const PricingCard = React.forwardRef<HTMLDivElement, PricingCardProps>(
13188
12777
  (
13189
12778
  {
13190
12779
  planName,
@@ -13208,8 +12797,8 @@ const PricingCard = React.forwardRef(
13208
12797
  infoText,
13209
12798
  className,
13210
12799
  ...props
13211
- }: PricingCardProps,
13212
- ref: React.Ref<HTMLDivElement>
12800
+ },
12801
+ ref
13213
12802
  ) => {
13214
12803
  const buttonText =
13215
12804
  ctaText || (isCurrentPlan ? "Current plan" : "Select plan");
@@ -13231,6 +12820,9 @@ const PricingCard = React.forwardRef(
13231
12820
  {/* Header */}
13232
12821
  <div
13233
12822
  className="flex flex-col gap-4 rounded-t-xl rounded-b-lg p-4"
12823
+ style={
12824
+ headerBgColor ? { backgroundColor: headerBgColor } : undefined
12825
+ }
13234
12826
  >
13235
12827
  {/* Plan name + badge */}
13236
12828
  <div className="flex items-center gap-4">
@@ -13288,11 +12880,11 @@ const PricingCard = React.forwardRef(
13288
12880
  </div>
13289
12881
  )}
13290
12882
  <Button
13291
- variant={isCurrentPlan ? "secondary" : "default"}
12883
+ variant={isCurrentPlan ? "outline" : "default"}
13292
12884
  className="w-full"
13293
12885
  onClick={onCtaClick}
13294
12886
  loading={ctaLoading}
13295
- disabled={ctaDisabled || isCurrentPlan}
12887
+ disabled={ctaDisabled}
13296
12888
  >
13297
12889
  {buttonText}
13298
12890
  </Button>
@@ -13339,34 +12931,29 @@ const PricingCard = React.forwardRef(
13339
12931
  </div>
13340
12932
  )}
13341
12933
 
13342
- {/* Bottom sections pushed to card bottom for grid alignment */}
13343
- {(addon || (usageDetails && usageDetails.length > 0)) && (
13344
- <div className="mt-auto flex flex-col gap-6">
13345
- {/* Addon */}
13346
- {addon && (
13347
- <div className="flex items-center gap-2.5 rounded-md bg-[var(--color-info-25)] border border-[#f3f5f6] pl-4 py-2.5">
13348
- {addon.icon && (
13349
- <div className="size-5 shrink-0">{addon.icon}</div>
13350
- )}
13351
- <span className="text-sm text-semantic-text-primary tracking-[0.035px]">
13352
- {addon.text}
13353
- </span>
13354
- </div>
12934
+ {/* Addon */}
12935
+ {addon && (
12936
+ <div className="flex items-center gap-2.5 rounded-md bg-[var(--color-info-25)] border border-[#f3f5f6] pl-4 py-2.5">
12937
+ {addon.icon && (
12938
+ <div className="size-5 shrink-0">{addon.icon}</div>
13355
12939
  )}
12940
+ <span className="text-sm text-semantic-text-primary tracking-[0.035px]">
12941
+ {addon.text}
12942
+ </span>
12943
+ </div>
12944
+ )}
13356
12945
 
13357
- {/* Usage Details */}
13358
- {usageDetails && usageDetails.length > 0 && (
13359
- <div className="flex flex-col gap-2.5 rounded-md bg-[var(--color-info-25)] border border-[#f3f5f6] px-4 py-2.5">
13360
- {usageDetails.map((detail, index) => (
13361
- <div key={index} className="flex items-start gap-2">
13362
- <span className="size-1.5 rounded-full bg-semantic-primary shrink-0 mt-[7px]" />
13363
- <span className="text-sm text-semantic-text-primary tracking-[0.035px]">
13364
- <strong>{detail.label}:</strong> {detail.value}
13365
- </span>
13366
- </div>
13367
- ))}
12946
+ {/* Usage Details */}
12947
+ {usageDetails && usageDetails.length > 0 && (
12948
+ <div className="flex flex-col gap-2.5 rounded-md bg-[var(--color-info-25)] border border-[#f3f5f6] px-4 py-2.5">
12949
+ {usageDetails.map((detail, index) => (
12950
+ <div key={index} className="flex items-start gap-2">
12951
+ <span className="size-1.5 rounded-full bg-semantic-primary shrink-0 mt-[7px]" />
12952
+ <span className="text-sm text-semantic-text-primary tracking-[0.035px]">
12953
+ <strong>{detail.label}:</strong> {detail.value}
12954
+ </span>
13368
12955
  </div>
13369
- )}
12956
+ ))}
13370
12957
  </div>
13371
12958
  )}
13372
12959
  </div>
@@ -13387,8 +12974,8 @@ interface PlanIconProps extends React.SVGAttributes<SVGElement> {
13387
12974
  className?: string;
13388
12975
  }
13389
12976
 
13390
- const CompactCarIcon = React.forwardRef(
13391
- ({ className, ...props }: PlanIconProps, ref: React.Ref<SVGSVGElement>) => (
12977
+ const CompactCarIcon = React.forwardRef<SVGSVGElement, PlanIconProps>(
12978
+ ({ className, ...props }, ref) => (
13392
12979
  <svg
13393
12980
  ref={ref}
13394
12981
  className={className}
@@ -13427,8 +13014,8 @@ const CompactCarIcon = React.forwardRef(
13427
13014
  );
13428
13015
  CompactCarIcon.displayName = "CompactCarIcon";
13429
13016
 
13430
- const SedanCarIcon = React.forwardRef(
13431
- ({ className, ...props }: PlanIconProps, ref: React.Ref<SVGSVGElement>) => (
13017
+ const SedanCarIcon = React.forwardRef<SVGSVGElement, PlanIconProps>(
13018
+ ({ className, ...props }, ref) => (
13432
13019
  <svg
13433
13020
  ref={ref}
13434
13021
  className={className}
@@ -13479,8 +13066,8 @@ const SedanCarIcon = React.forwardRef(
13479
13066
  );
13480
13067
  SedanCarIcon.displayName = "SedanCarIcon";
13481
13068
 
13482
- const SuvCarIcon = React.forwardRef(
13483
- ({ className, ...props }: PlanIconProps, ref: React.Ref<SVGSVGElement>) => (
13069
+ const SuvCarIcon = React.forwardRef<SVGSVGElement, PlanIconProps>(
13070
+ ({ className, ...props }, ref) => (
13484
13071
  <svg
13485
13072
  ref={ref}
13486
13073
  className={className}
@@ -13693,7 +13280,7 @@ import type { PricingPageProps } from "./types";
13693
13280
  * />
13694
13281
  * \`\`\`
13695
13282
  */
13696
- const PricingPage = React.forwardRef(
13283
+ const PricingPage = React.forwardRef<HTMLDivElement, PricingPageProps>(
13697
13284
  (
13698
13285
  {
13699
13286
  title = "Select business plan",
@@ -13713,10 +13300,11 @@ const PricingPage = React.forwardRef(
13713
13300
  onFeatureComparisonClick,
13714
13301
  letUsDriveCards = [],
13715
13302
  letUsDriveTitle = "Let us drive \u2014 Full-service management",
13303
+ letUsDriveExpandMode,
13716
13304
  className,
13717
13305
  ...props
13718
- }: PricingPageProps,
13719
- ref: React.Ref<HTMLDivElement>
13306
+ },
13307
+ ref
13720
13308
  ) => {
13721
13309
  // Internal state for uncontrolled mode
13722
13310
  const [internalTab, setInternalTab] = React.useState(
@@ -13725,6 +13313,9 @@ const PricingPage = React.forwardRef(
13725
13313
  const [internalBilling, setInternalBilling] = React.useState<
13726
13314
  "monthly" | "yearly"
13727
13315
  >("monthly");
13316
+ const [expandedLetUsDriveIndices, setExpandedLetUsDriveIndices] =
13317
+ React.useState<number[]>([]);
13318
+
13728
13319
  const currentTab = controlledTab ?? internalTab;
13729
13320
  const currentBilling = controlledBilling ?? internalBilling;
13730
13321
 
@@ -13738,6 +13329,30 @@ const PricingPage = React.forwardRef(
13738
13329
  onBillingPeriodChange?.(period);
13739
13330
  };
13740
13331
 
13332
+ const cardCount = letUsDriveCards.length;
13333
+
13334
+ const handleLetUsDriveExpandedChange = (index: number, expanded: boolean) => {
13335
+ if (letUsDriveExpandMode === "all") {
13336
+ if (expanded) {
13337
+ setExpandedLetUsDriveIndices(
13338
+ Array.from({ length: cardCount }, (_, i) => i)
13339
+ );
13340
+ } else {
13341
+ setExpandedLetUsDriveIndices((prev) =>
13342
+ prev.filter((i) => i !== index)
13343
+ );
13344
+ }
13345
+ } else {
13346
+ if (expanded) {
13347
+ setExpandedLetUsDriveIndices([index]);
13348
+ } else {
13349
+ setExpandedLetUsDriveIndices((prev) =>
13350
+ prev.filter((i) => i !== index)
13351
+ );
13352
+ }
13353
+ }
13354
+ };
13355
+
13741
13356
  const hasPowerUps = powerUpCards.length > 0;
13742
13357
  const hasLetUsDrive = letUsDriveCards.length > 0;
13743
13358
 
@@ -13833,11 +13448,22 @@ const PricingPage = React.forwardRef(
13833
13448
  {letUsDriveTitle}
13834
13449
  </h2>
13835
13450
 
13836
- {/* Service cards \u2014 items-start so expanding one card doesn't stretch others */}
13837
- <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 items-start">
13838
- {letUsDriveCards.map((cardProps, index) => (
13839
- <LetUsDriveCard key={index} {...cardProps} />
13840
- ))}
13451
+ {/* Service cards \u2014 items-stretch + card h-full + mt-auto on actions align Talk to us buttons */}
13452
+ <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 items-stretch">
13453
+ {letUsDriveCards.map((cardProps, index) => {
13454
+ const hasDetailsContent =
13455
+ cardProps.detailsContent &&
13456
+ cardProps.detailsContent.items.length > 0;
13457
+ const useControlledExpand =
13458
+ letUsDriveExpandMode && hasDetailsContent;
13459
+ const merged = { ...cardProps };
13460
+ if (useControlledExpand) {
13461
+ merged.expanded = expandedLetUsDriveIndices.includes(index);
13462
+ merged.onExpandedChange = (expanded: boolean) =>
13463
+ handleLetUsDriveExpandedChange(index, expanded);
13464
+ }
13465
+ return <LetUsDriveCard key={index} {...merged} />;
13466
+ })}
13841
13467
  </div>
13842
13468
  </div>
13843
13469
  </div>
@@ -13926,6 +13552,13 @@ export interface PricingPageProps
13926
13552
  letUsDriveCards?: LetUsDriveCardProps[];
13927
13553
  /** Let-us-drive section heading (default: "Let us drive \u2014 Full-service management") */
13928
13554
  letUsDriveTitle?: string;
13555
+ /**
13556
+ * When set, controls how "Show details" expands across cards.
13557
+ * - "single": only the clicked card expands (accordion).
13558
+ * - "all": clicking "Show details" on any card expands all cards that have detailsContent.
13559
+ * Ignored when cards are used without detailsContent or without controlled expanded state.
13560
+ */
13561
+ letUsDriveExpandMode?: "single" | "all";
13929
13562
  }
13930
13563
  `, prefix)
13931
13564
  },
@@ -13982,7 +13615,7 @@ import type { PricingToggleProps } from "./types";
13982
13615
  * />
13983
13616
  * \`\`\`
13984
13617
  */
13985
- const PricingToggle = React.forwardRef(
13618
+ const PricingToggle = React.forwardRef<HTMLDivElement, PricingToggleProps>(
13986
13619
  (
13987
13620
  {
13988
13621
  tabs,
@@ -13995,8 +13628,8 @@ const PricingToggle = React.forwardRef(
13995
13628
  yearlyLabel = "Yearly (Save 20%)",
13996
13629
  className,
13997
13630
  ...props
13998
- }: PricingToggleProps,
13999
- ref: React.Ref<HTMLDivElement>
13631
+ },
13632
+ ref
14000
13633
  ) => {
14001
13634
  const isYearly = billingPeriod === "yearly";
14002
13635
 
@@ -14241,8 +13874,8 @@ interface BrandIconProps extends React.SVGAttributes<SVGElement> {
14241
13874
  * Used in TalkToUsModal and available for any component that needs
14242
13875
  * the MyOperator contact/chat branding.
14243
13876
  */
14244
- const MyOperatorChatIcon = React.forwardRef(
14245
- ({ className, ...props }: BrandIconProps, ref: React.Ref<SVGSVGElement>) => (
13877
+ const MyOperatorChatIcon = React.forwardRef<SVGSVGElement, BrandIconProps>(
13878
+ ({ className, ...props }, ref) => (
14246
13879
  <svg
14247
13880
  ref={ref}
14248
13881
  className={className}
@@ -14375,8 +14008,8 @@ function getTypeLabel(
14375
14008
  * All displayed data (icon, badge, name, count, last published) comes from the \`bot\` prop.
14376
14009
  * Set bot.type to "chatbot" or "voicebot"; no separate card components needed.
14377
14010
  */
14378
- export const BotCard = React.forwardRef(
14379
- ({ bot, typeLabels, onEdit, onDelete, className, ...props }: BotCardProps, ref: React.Ref<HTMLDivElement>) => {
14011
+ export const BotCard = React.forwardRef<HTMLDivElement, BotCardProps>(
14012
+ ({ bot, typeLabels, onEdit, onDelete, className, ...props }, ref) => {
14380
14013
  const typeLabel = getTypeLabel(bot, typeLabels);
14381
14014
  const isChatbot = bot.type === "chatbot";
14382
14015
 
@@ -14406,6 +14039,7 @@ export const BotCard = React.forwardRef(
14406
14039
  className={cn(
14407
14040
  "relative bg-semantic-bg-primary border border-semantic-border-layout rounded-[5px] min-w-0 max-w-full overflow-hidden flex flex-col",
14408
14041
  "shadow-[0px_4px_15.1px_0px_rgba(0,0,0,0.06)] p-3 sm:p-4 md:p-5",
14042
+ "min-h-[180px] sm:min-h-[207px] h-full shrink-0",
14409
14043
  onEdit && "cursor-pointer",
14410
14044
  className
14411
14045
  )}
@@ -14463,7 +14097,7 @@ export const BotCard = React.forwardRef(
14463
14097
  </div>
14464
14098
 
14465
14099
  {/* Bot name */}
14466
- <h3 className="m-0 text-sm sm:text-base font-normal text-semantic-text-primary line-clamp-1 mb-1 min-w-0">
14100
+ <h3 className="m-0 text-sm sm:text-base font-normal text-semantic-text-primary truncate mb-1 min-w-0">
14467
14101
  {bot.name}
14468
14102
  </h3>
14469
14103
 
@@ -14491,7 +14125,7 @@ export const BotCard = React.forwardRef(
14491
14125
  </span>
14492
14126
  )}
14493
14127
  {(bot.lastPublishedBy || bot.lastPublishedDate) ? (
14494
- <p className="m-0 text-xs sm:text-sm text-semantic-text-muted line-clamp-1">
14128
+ <p className="m-0 text-xs sm:text-sm text-semantic-text-muted truncate">
14495
14129
  {bot.lastPublishedBy
14496
14130
  ? \`\${bot.lastPublishedBy} | \${bot.lastPublishedDate ?? "\u2014"}\`
14497
14131
  : bot.lastPublishedDate}
@@ -14541,7 +14175,10 @@ const BOT_TYPE_OPTIONS: BotTypeOption[] = [
14541
14175
  },
14542
14176
  ];
14543
14177
 
14544
- export const CreateBotModal = React.forwardRef(({ open, onOpenChange, onSubmit, isLoading, className }: CreateBotModalProps, ref: React.Ref<HTMLDivElement>) => {
14178
+ export const CreateBotModal = React.forwardRef<
14179
+ HTMLDivElement,
14180
+ CreateBotModalProps
14181
+ >(({ open, onOpenChange, onSubmit, isLoading, className }, ref) => {
14545
14182
  const [name, setName] = React.useState("");
14546
14183
  const [selectedType, setSelectedType] = React.useState<BotType>("chatbot");
14547
14184
 
@@ -14689,15 +14326,15 @@ import type { CreateBotFlowProps } from "./types";
14689
14326
  * Create bot flow: "Create new bot" card + Create Bot modal. No header (title/subtitle/search).
14690
14327
  * Use when you want the create-bot experience without the list header.
14691
14328
  */
14692
- export const CreateBotFlow = React.forwardRef(
14329
+ export const CreateBotFlow = React.forwardRef<HTMLDivElement, CreateBotFlowProps>(
14693
14330
  (
14694
14331
  {
14695
14332
  createCardLabel = "Create new bot",
14696
14333
  onSubmit,
14697
14334
  className,
14698
14335
  ...props
14699
- }: CreateBotFlowProps,
14700
- ref: React.Ref<HTMLDivElement>
14336
+ },
14337
+ ref
14701
14338
  ) => {
14702
14339
  const [modalOpen, setModalOpen] = React.useState(false);
14703
14340
 
@@ -14813,7 +14450,7 @@ import { BotListGrid } from "./bot-list-grid";
14813
14450
  import { CreateBotModal } from "./create-bot-modal";
14814
14451
  import type { BotListProps } from "./types";
14815
14452
 
14816
- export const BotList = React.forwardRef(
14453
+ export const BotList = React.forwardRef<HTMLDivElement, BotListProps>(
14817
14454
  (
14818
14455
  {
14819
14456
  bots = [],
@@ -14829,8 +14466,8 @@ export const BotList = React.forwardRef(
14829
14466
  createCardLabel = "Create new bot",
14830
14467
  className,
14831
14468
  ...props
14832
- }: BotListProps,
14833
- ref: React.Ref<HTMLDivElement>
14469
+ },
14470
+ ref
14834
14471
  ) => {
14835
14472
  const [searchQuery, setSearchQuery] = React.useState("");
14836
14473
  const [createModalOpen, setCreateModalOpen] = React.useState(false);
@@ -14940,10 +14577,10 @@ const botListHeaderVariants = cva("min-w-0", {
14940
14577
  },
14941
14578
  });
14942
14579
 
14943
- export const BotListHeader = React.forwardRef(
14580
+ export const BotListHeader = React.forwardRef<HTMLDivElement, BotListHeaderProps>(
14944
14581
  (
14945
- { title, subtitle, variant = "default", rightContent, className, ...props }: BotListHeaderProps,
14946
- ref: React.Ref<HTMLDivElement>
14582
+ { title, subtitle, variant = "default", rightContent, className, ...props },
14583
+ ref
14947
14584
  ) => {
14948
14585
  const rootClassName = cn(botListHeaderVariants({ variant }), className);
14949
14586
  const titleBlock = (
@@ -14990,7 +14627,7 @@ import { Search } from "lucide-react";
14990
14627
  import { cn } from "../../../lib/utils";
14991
14628
  import type { BotListSearchProps } from "./types";
14992
14629
 
14993
- export const BotListSearch = React.forwardRef(
14630
+ export const BotListSearch = React.forwardRef<HTMLDivElement, BotListSearchProps>(
14994
14631
  (
14995
14632
  {
14996
14633
  value,
@@ -14999,8 +14636,8 @@ export const BotListSearch = React.forwardRef(
14999
14636
  defaultValue,
15000
14637
  className,
15001
14638
  ...props
15002
- }: BotListSearchProps,
15003
- ref: React.Ref<HTMLDivElement>
14639
+ },
14640
+ ref
15004
14641
  ) => {
15005
14642
  const [internalValue, setInternalValue] = React.useState(defaultValue ?? "");
15006
14643
  const isControlled = value !== undefined;
@@ -15047,15 +14684,18 @@ import { Plus } from "lucide-react";
15047
14684
  import { cn } from "../../../lib/utils";
15048
14685
  import type { BotListCreateCardProps } from "./types";
15049
14686
 
15050
- export const BotListCreateCard = React.forwardRef(
14687
+ export const BotListCreateCard = React.forwardRef<
14688
+ HTMLButtonElement,
14689
+ BotListCreateCardProps
14690
+ >(
15051
14691
  (
15052
14692
  {
15053
14693
  label = "Create new bot",
15054
14694
  onClick,
15055
14695
  className,
15056
14696
  ...props
15057
- }: BotListCreateCardProps,
15058
- ref: React.Ref<HTMLButtonElement>
14697
+ },
14698
+ ref
15059
14699
  ) => (
15060
14700
  <button
15061
14701
  ref={ref}
@@ -15104,13 +14744,14 @@ BotListCreateCard.displayName = "BotListCreateCard";
15104
14744
  import { cn } from "../../../lib/utils";
15105
14745
  import type { BotListGridProps } from "./types";
15106
14746
 
15107
- export const BotListGrid = React.forwardRef(
15108
- ({ children, className, ...props }: BotListGridProps, ref: React.Ref<HTMLDivElement>) => (
14747
+ export const BotListGrid = React.forwardRef<HTMLDivElement, BotListGridProps>(
14748
+ ({ children, className, ...props }, ref) => (
15109
14749
  <div
15110
14750
  ref={ref}
15111
14751
  className={cn(
15112
- "grid w-full min-w-0 max-w-full overflow-hidden gap-3 sm:gap-5 md:gap-6",
14752
+ "grid w-full min-w-0 max-w-full content-start gap-3 sm:gap-5 md:gap-6",
15113
14753
  "grid-cols-[repeat(auto-fill,minmax(min(100%,280px),1fr))]",
14754
+ "auto-rows-auto items-stretch",
15114
14755
  className
15115
14756
  )}
15116
14757
  {...props}
@@ -15406,7 +15047,7 @@ function getTimeRemaining(progress: number) {
15406
15047
  : \`\${secs} seconds remaining\`;
15407
15048
  }
15408
15049
 
15409
- const FileUploadModal = React.forwardRef(
15050
+ const FileUploadModal = React.forwardRef<HTMLDivElement, FileUploadModalProps>(
15410
15051
  (
15411
15052
  {
15412
15053
  open,
@@ -15429,8 +15070,8 @@ const FileUploadModal = React.forwardRef(
15429
15070
  loading = false,
15430
15071
  className,
15431
15072
  ...props
15432
- }: FileUploadModalProps,
15433
- ref: React.Ref<HTMLDivElement>
15073
+ },
15074
+ ref
15434
15075
  ) => {
15435
15076
  const [items, setItems] = React.useState<UploadItem[]>([]);
15436
15077
  const fileInputRef = React.useRef<HTMLInputElement>(null);
@@ -15800,8 +15441,8 @@ import { X, Play, File } from "lucide-react";
15800
15441
  import { cn } from "../../../lib/utils";
15801
15442
  import type { AttachmentPreviewProps } from "./types";
15802
15443
 
15803
- const AttachmentPreview = React.forwardRef(
15804
- ({ className, file, onRemove, ...props }: AttachmentPreviewProps, ref: React.Ref<HTMLDivElement>) => {
15444
+ const AttachmentPreview = React.forwardRef<HTMLDivElement, AttachmentPreviewProps>(
15445
+ ({ className, file, onRemove, ...props }, ref) => {
15805
15446
  const url = React.useMemo(() => URL.createObjectURL(file), [file]);
15806
15447
 
15807
15448
  const isImage = file.type.startsWith("image/");
@@ -15959,7 +15600,7 @@ const BAR_WIDTH = 2;
15959
15600
  const BAR_GAP = 1.5;
15960
15601
  const SVG_HEIGHT = 32;
15961
15602
 
15962
- const AudioMedia = React.forwardRef(
15603
+ const AudioMedia = React.forwardRef<HTMLDivElement, AudioMediaProps>(
15963
15604
  (
15964
15605
  {
15965
15606
  className,
@@ -15973,8 +15614,8 @@ const AudioMedia = React.forwardRef(
15973
15614
  onPlayChange,
15974
15615
  onSpeedChange,
15975
15616
  ...props
15976
- }: AudioMediaProps,
15977
- ref: React.Ref<HTMLDivElement>
15617
+ },
15618
+ ref
15978
15619
  ) => {
15979
15620
  const [playing, setPlaying] = React.useState(false);
15980
15621
  const [speed, setSpeed] = React.useState(1);
@@ -16174,8 +15815,8 @@ import { Reply, ExternalLink, ChevronLeft, ChevronRight } from "lucide-react";
16174
15815
  import { cn } from "../../../lib/utils";
16175
15816
  import type { CarouselMediaProps } from "./types";
16176
15817
 
16177
- const CarouselMedia = React.forwardRef(
16178
- ({ className, cards, cardWidth = 260, imageHeight = 200, ...props }: CarouselMediaProps, ref: React.Ref<HTMLDivElement>) => {
15818
+ const CarouselMedia = React.forwardRef<HTMLDivElement, CarouselMediaProps>(
15819
+ ({ className, cards, cardWidth = 260, imageHeight = 200, ...props }, ref) => {
16179
15820
  const scrollRef = useRef<HTMLDivElement>(null);
16180
15821
  const [canScrollLeft, setCanScrollLeft] = useState(false);
16181
15822
  const [canScrollRight, setCanScrollRight] = useState(
@@ -16429,7 +16070,7 @@ function DeliveryFooter({
16429
16070
  * </ChatBubble>
16430
16071
  * \`\`\`
16431
16072
  */
16432
- const ChatBubble = React.forwardRef(
16073
+ const ChatBubble = React.forwardRef<HTMLDivElement, ChatBubbleProps>(
16433
16074
  (
16434
16075
  {
16435
16076
  variant,
@@ -16444,8 +16085,8 @@ const ChatBubble = React.forwardRef(
16444
16085
  children,
16445
16086
  className,
16446
16087
  ...props
16447
- }: ChatBubbleProps,
16448
- ref: React.Ref<HTMLDivElement>
16088
+ },
16089
+ ref
16449
16090
  ) => {
16450
16091
  const hasMedia = !!media;
16451
16092
 
@@ -16563,126 +16204,6 @@ export interface ChatBubbleProps extends React.HTMLAttributes<HTMLDivElement> {
16563
16204
  name: "index.ts",
16564
16205
  content: prefixTailwindClasses(`export { ChatBubble } from "./chat-bubble";
16565
16206
  export type { ChatBubbleProps, ChatBubbleReply, DeliveryStatus } from "./types";
16566
- `, prefix)
16567
- }
16568
- ]
16569
- },
16570
- "chat-timeline-divider": {
16571
- name: "chat-timeline-divider",
16572
- description: "A timeline divider for chat message lists \u2014 renders centered content between horizontal lines with date, unread, and system event variants",
16573
- category: "custom",
16574
- dependencies: [
16575
- "clsx",
16576
- "tailwind-merge"
16577
- ],
16578
- internalDependencies: [],
16579
- isMultiFile: true,
16580
- directory: "chat-timeline-divider",
16581
- mainFile: "chat-timeline-divider.tsx",
16582
- files: [
16583
- {
16584
- name: "chat-timeline-divider.tsx",
16585
- content: prefixTailwindClasses(`import * as React from "react";
16586
- import { cn } from "../../../lib/utils";
16587
-
16588
- /* \u2500\u2500 Types \u2500\u2500 */
16589
-
16590
- export type ChatTimelineDividerVariant = "default" | "unread" | "system";
16591
-
16592
- export interface ChatTimelineDividerProps
16593
- extends Omit<React.HTMLAttributes<HTMLDivElement>, "children"> {
16594
- /**
16595
- * Visual style of the divider.
16596
- * - \`default\`: plain centered text between lines (e.g. "Today", "Yesterday")
16597
- * - \`unread\`: bold text in a white pill with border (e.g. "3 unread messages")
16598
- * - \`system\`: muted text in a white pill with border (e.g. "Assigned to Alex Smith")
16599
- */
16600
- variant?: ChatTimelineDividerVariant;
16601
- /** Content to display \u2014 text or ReactNode for rich content (e.g. linked names) */
16602
- children: React.ReactNode;
16603
- }
16604
-
16605
- /* \u2500\u2500 Variant styles \u2500\u2500 */
16606
-
16607
- const containerStyles: Record<ChatTimelineDividerVariant, string> = {
16608
- default: "",
16609
- unread:
16610
- "bg-white px-2.5 py-0.5 rounded-full border border-semantic-border-layout shadow-sm",
16611
- system:
16612
- "bg-white px-2.5 py-1 rounded-full border border-semantic-border-layout shadow-[0px_1px_2px_0px_rgba(10,13,18,0.05)]",
16613
- };
16614
-
16615
- const textStyles: Record<ChatTimelineDividerVariant, string> = {
16616
- default: "text-[13px] text-semantic-text-muted",
16617
- unread: "text-[12px] font-semibold text-semantic-text-primary",
16618
- system: "text-[13px] text-semantic-text-muted",
16619
- };
16620
-
16621
- /* \u2500\u2500 Component \u2500\u2500 */
16622
-
16623
- /**
16624
- * ChatTimelineDivider renders a centered label between two horizontal lines
16625
- * in a chat message timeline.
16626
- *
16627
- * Use it to separate messages by date, mark unread boundaries,
16628
- * or display system/action events (assignments, resolutions, etc.).
16629
- *
16630
- * @example
16631
- * \`\`\`tsx
16632
- * // Date separator
16633
- * <ChatTimelineDivider>Today</ChatTimelineDivider>
16634
- *
16635
- * // Unread count
16636
- * <ChatTimelineDivider variant="unread">3 unread messages</ChatTimelineDivider>
16637
- *
16638
- * // System event with linked names
16639
- * <ChatTimelineDivider variant="system">
16640
- * Assigned to <span className="text-semantic-text-link font-medium">Alex Smith</span>
16641
- * </ChatTimelineDivider>
16642
- * \`\`\`
16643
- */
16644
- const ChatTimelineDivider = React.forwardRef<
16645
- HTMLDivElement,
16646
- ChatTimelineDividerProps
16647
- >(
16648
- (
16649
- { variant = "default", children, className, ...props },
16650
- ref
16651
- ) => {
16652
- const showLines = true;
16653
-
16654
- return (
16655
- <div
16656
- ref={ref}
16657
- role="separator"
16658
- className={cn("flex items-center gap-4 my-2", className)}
16659
- {...props}
16660
- >
16661
- {showLines && (
16662
- <div className="flex-1 h-px bg-semantic-border-layout" />
16663
- )}
16664
- <div className={cn(containerStyles[variant])}>
16665
- <span className={cn(textStyles[variant])}>{children}</span>
16666
- </div>
16667
- {showLines && (
16668
- <div className="flex-1 h-px bg-semantic-border-layout" />
16669
- )}
16670
- </div>
16671
- );
16672
- }
16673
- );
16674
- ChatTimelineDivider.displayName = "ChatTimelineDivider";
16675
-
16676
- export { ChatTimelineDivider };
16677
- `, prefix)
16678
- },
16679
- {
16680
- name: "index.ts",
16681
- content: prefixTailwindClasses(`export {
16682
- ChatTimelineDivider,
16683
- type ChatTimelineDividerProps,
16684
- type ChatTimelineDividerVariant,
16685
- } from "./chat-timeline-divider";
16686
16207
  `, prefix)
16687
16208
  }
16688
16209
  ]
@@ -16738,7 +16259,7 @@ import type { ChatComposerProps } from "./types";
16738
16259
  * />
16739
16260
  * \`\`\`
16740
16261
  */
16741
- const ChatComposer = React.forwardRef(
16262
+ const ChatComposer = React.forwardRef<HTMLDivElement, ChatComposerProps>(
16742
16263
  (
16743
16264
  {
16744
16265
  className,
@@ -16762,8 +16283,8 @@ const ChatComposer = React.forwardRef(
16762
16283
  expiredMessage = "This chat has expired. Send a template to continue.",
16763
16284
  onTemplateClick,
16764
16285
  ...props
16765
- }: ChatComposerProps,
16766
- ref: React.Ref<HTMLDivElement>
16286
+ },
16287
+ ref
16767
16288
  ) => {
16768
16289
  const textareaRef = React.useRef<HTMLTextAreaElement>(null);
16769
16290
 
@@ -16938,8 +16459,8 @@ export interface ChatComposerProps extends Omit<React.HTMLAttributes<HTMLDivElem
16938
16459
  leftActions?: React.ReactNode;
16939
16460
  /** Slot for right action buttons (rendered inside textarea container, bottom-right) */
16940
16461
  rightActions?: React.ReactNode;
16941
- /** Send button label. Accepts text or JSX (e.g. icon + text). Defaults to "Send" */
16942
- sendLabel?: React.ReactNode;
16462
+ /** Send button label. Defaults to "Send" */
16463
+ sendLabel?: string;
16943
16464
  /** Whether to show the send dropdown chevron. Defaults to false */
16944
16465
  showSendDropdown?: boolean;
16945
16466
  /** Whether the chat is expired (shows template prompt instead of composer) */
@@ -16980,7 +16501,7 @@ import { cn } from "../../../lib/utils";
16980
16501
  import { File, FileSpreadsheet, ArrowDownToLine } from "lucide-react";
16981
16502
  import type { DocMediaProps } from "./types";
16982
16503
 
16983
- const DocMedia = React.forwardRef(
16504
+ const DocMedia = React.forwardRef<HTMLDivElement, DocMediaProps>(
16984
16505
  (
16985
16506
  {
16986
16507
  className,
@@ -16993,8 +16514,8 @@ const DocMedia = React.forwardRef(
16993
16514
  caption,
16994
16515
  onDownload,
16995
16516
  ...props
16996
- }: DocMediaProps,
16997
- ref: React.Ref<HTMLDivElement>
16517
+ },
16518
+ ref
16998
16519
  ) => {
16999
16520
  if (variant === "preview") {
17000
16521
  return (
@@ -17033,35 +16554,12 @@ const DocMedia = React.forwardRef(
17033
16554
 
17034
16555
  if (variant === "download") {
17035
16556
  return (
17036
- <div
17037
- ref={ref}
17038
- className={cn("relative rounded-t overflow-hidden", className)}
17039
- {...props}
17040
- >
16557
+ <div ref={ref} className={cn("relative", className)} {...props}>
17041
16558
  <img
17042
16559
  src={thumbnailUrl}
17043
16560
  alt={caption || filename || "Document"}
17044
- className="w-full object-cover"
17045
- style={{ aspectRatio: "442/308" }}
16561
+ className="w-full rounded-t object-cover max-h-[280px]"
17046
16562
  />
17047
- <div className="absolute inset-0 bg-gradient-to-t from-[#1d222f] via-[#1d222f]/30 to-transparent" />
17048
- <div className="absolute bottom-0 left-0 right-0 px-4 py-3">
17049
- <p className="m-0 text-[14px] font-semibold text-white truncate">
17050
- {filename || "Document"}
17051
- </p>
17052
- <div className="flex items-center gap-1.5 mt-1">
17053
- <File className="size-3.5 text-white/80" />
17054
- <span className="text-[12px] text-white/80">
17055
- {[
17056
- fileType,
17057
- pageCount && \`\${pageCount} pages\`,
17058
- fileSize,
17059
- ]
17060
- .filter(Boolean)
17061
- .join(" \\u00B7 ")}
17062
- </span>
17063
- </div>
17064
- </div>
17065
16563
  </div>
17066
16564
  );
17067
16565
  }
@@ -17204,7 +16702,7 @@ import type { VideoMediaProps } from "./types";
17204
16702
 
17205
16703
  const DEFAULT_SPEED_OPTIONS = [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2];
17206
16704
 
17207
- const VideoMedia = React.forwardRef(
16705
+ const VideoMedia = React.forwardRef<HTMLDivElement, VideoMediaProps>(
17208
16706
  (
17209
16707
  {
17210
16708
  className,
@@ -17216,8 +16714,8 @@ const VideoMedia = React.forwardRef(
17216
16714
  onSpeedChange,
17217
16715
  onClick,
17218
16716
  ...props
17219
- }: VideoMediaProps,
17220
- ref: React.Ref<HTMLDivElement>
16717
+ },
16718
+ ref
17221
16719
  ) => {
17222
16720
  const [playing, setPlaying] = useState(false);
17223
16721
  const [muted, setMuted] = useState(false);
@@ -17450,10 +16948,7 @@ export type { VideoMediaProps } from "./types";
17450
16948
  "creatable-multi-select",
17451
16949
  "page-header",
17452
16950
  "tag",
17453
- "file-upload-modal",
17454
- "form-modal",
17455
- "text-field",
17456
- "textarea"
16951
+ "file-upload-modal"
17457
16952
  ],
17458
16953
  isMultiFile: true,
17459
16954
  directory: "ivr-bot",
@@ -17505,7 +17000,7 @@ const DEFAULT_DATA: IvrBotConfigData = {
17505
17000
  };
17506
17001
 
17507
17002
  // \u2500\u2500\u2500 Main IvrBotConfig \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
17508
- export const IvrBotConfig = React.forwardRef(
17003
+ export const IvrBotConfig = React.forwardRef<HTMLDivElement, IvrBotConfigProps>(
17509
17004
  (
17510
17005
  {
17511
17006
  botTitle = "IVR bot",
@@ -17552,8 +17047,8 @@ export const IvrBotConfig = React.forwardRef(
17552
17047
  callEndThresholdMin,
17553
17048
  callEndThresholdMax,
17554
17049
  className,
17555
- }: IvrBotConfigProps,
17556
- ref: React.Ref<HTMLDivElement>
17050
+ },
17051
+ ref
17557
17052
  ) => {
17558
17053
  const [data, setData] = React.useState<IvrBotConfigData>({
17559
17054
  ...DEFAULT_DATA,
@@ -17756,7 +17251,7 @@ IvrBotConfig.displayName = "IvrBotConfig";
17756
17251
  {
17757
17252
  name: "create-function-modal.tsx",
17758
17253
  content: prefixTailwindClasses(`import * as React from "react";
17759
- import { Trash2, ChevronDown, X, Plus, Pencil } from "lucide-react";
17254
+ import { Trash2, ChevronDown, X, Plus } from "lucide-react";
17760
17255
  import { cn } from "../../../lib/utils";
17761
17256
  import {
17762
17257
  Dialog,
@@ -17764,9 +17259,6 @@ import {
17764
17259
  DialogTitle,
17765
17260
  } from "../dialog";
17766
17261
  import { Button } from "../button";
17767
- import { FormModal } from "../form-modal";
17768
- import { TextField } from "../text-field";
17769
- import { Textarea } from "../textarea";
17770
17262
  import type {
17771
17263
  CreateFunctionModalProps,
17772
17264
  CreateFunctionData,
@@ -17774,12 +17266,10 @@ import type {
17774
17266
  FunctionTabType,
17775
17267
  HttpMethod,
17776
17268
  KeyValuePair,
17777
- VariableGroup,
17778
- VariableItem,
17779
- VariableFormData,
17780
17269
  } from "./types";
17781
17270
 
17782
17271
  const HTTP_METHODS: HttpMethod[] = ["GET", "POST", "PUT", "DELETE", "PATCH"];
17272
+ const METHODS_WITH_BODY: HttpMethod[] = ["POST", "PUT", "PATCH"];
17783
17273
  const FUNCTION_NAME_MAX = 100;
17784
17274
  const BODY_MAX = 4000;
17785
17275
  const URL_MAX = 500;
@@ -17787,8 +17277,6 @@ const HEADER_KEY_MAX = 512;
17787
17277
  const HEADER_VALUE_MAX = 2048;
17788
17278
 
17789
17279
  const FUNCTION_NAME_REGEX = /^(?!_+$)(?=.*[a-zA-Z])[a-zA-Z][a-zA-Z0-9_]*$/;
17790
- const VARIABLE_NAME_MAX = 30;
17791
- const VARIABLE_NAME_REGEX = /^[a-zA-Z][a-zA-Z0-9_]*$/;
17792
17280
  const URL_REGEX = /^https?:\\/\\//;
17793
17281
  const HEADER_KEY_REGEX = /^[!#$%&'*+\\-.^_\`|~0-9a-zA-Z]+$/;
17794
17282
  // Query parameter validation (aligned with apiIntegrationSchema.queryParams)
@@ -17838,399 +17326,126 @@ function insertVar(value: string, variable: string, from: number, to: number): s
17838
17326
  return value.slice(0, from) + variable + value.slice(to);
17839
17327
  }
17840
17328
 
17841
- function extractVarRefs(texts: string[]): string[] {
17842
- const pattern = /\\{\\{[^}]+\\}\\}/g;
17843
- const all = texts.flatMap((t) => t.match(pattern) ?? []);
17844
- return Array.from(new Set(all));
17845
- }
17846
-
17847
- // \u2500\u2500 Value segment parser \u2014 splits "text {{var}} text" into typed segments \u2500\u2500\u2500\u2500\u2500
17848
-
17849
- type ValueSegment =
17850
- | { type: "text"; content: string }
17851
- | { type: "var"; name: string; raw: string };
17852
-
17853
- function parseValueSegments(value: string): ValueSegment[] {
17854
- const segments: ValueSegment[] = [];
17855
- const regex = /\\{\\{([^}]+)\\}\\}/g;
17856
- let lastIndex = 0;
17857
- let match;
17858
- while ((match = regex.exec(value)) !== null) {
17859
- if (match.index > lastIndex) {
17860
- segments.push({ type: "text", content: value.slice(lastIndex, match.index) });
17861
- }
17862
- segments.push({ type: "var", name: match[1], raw: match[0] });
17863
- lastIndex = regex.lastIndex;
17864
- }
17865
- if (lastIndex < value.length) {
17866
- segments.push({ type: "text", content: value.slice(lastIndex) });
17867
- }
17868
- return segments;
17869
- }
17870
-
17871
- /** Mirror-div technique \u2014 returns { top, left } relative to the element's top-left corner. */
17872
- function getCaretPixelPos(
17873
- el: HTMLTextAreaElement | HTMLInputElement,
17874
- position: number
17875
- ): { top: number; left: number } {
17876
- const cs = window.getComputedStyle(el);
17877
- const mirror = document.createElement("div");
17878
-
17879
- (
17880
- [
17881
- "boxSizing", "width", "paddingTop", "paddingRight", "paddingBottom", "paddingLeft",
17882
- "borderTopWidth", "borderRightWidth", "borderBottomWidth", "borderLeftWidth",
17883
- "fontFamily", "fontSize", "fontWeight", "fontStyle", "fontVariant",
17884
- "letterSpacing", "lineHeight", "textTransform", "wordSpacing", "tabSize",
17885
- ] as (keyof CSSStyleDeclaration)[]
17886
- ).forEach((prop) => {
17887
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
17888
- (mirror.style as any)[prop] = cs[prop];
17889
- });
17890
-
17891
- mirror.style.whiteSpace = el.tagName === "TEXTAREA" ? "pre-wrap" : "pre";
17892
- mirror.style.wordWrap = el.tagName === "TEXTAREA" ? "break-word" : "normal";
17893
- mirror.style.position = "absolute";
17894
- mirror.style.visibility = "hidden";
17895
- mirror.style.overflow = "hidden";
17896
- mirror.style.top = "0";
17897
- mirror.style.left = "0";
17898
- mirror.style.width = el.offsetWidth + "px";
17899
-
17900
- document.body.appendChild(mirror);
17901
- mirror.appendChild(document.createTextNode(el.value.substring(0, position)));
17902
-
17903
- const marker = document.createElement("span");
17904
- marker.textContent = "\\u200b";
17905
- mirror.appendChild(marker);
17906
-
17907
- const markerRect = marker.getBoundingClientRect();
17908
- const mirrorRect = mirror.getBoundingClientRect();
17909
- document.body.removeChild(mirror);
17910
-
17911
- const scrollTop = el instanceof HTMLTextAreaElement ? el.scrollTop : 0;
17912
- return {
17913
- top: markerRect.top - mirrorRect.top - scrollTop,
17914
- left: markerRect.left - mirrorRect.left,
17915
- };
17916
- }
17917
-
17918
- // Uses same visual classes as DropdownMenuContent + DropdownMenuItem.
17919
- // Position is cursor-anchored via getCaretPixelPos.
17920
- // No search bar \u2014 typing after {{ already filters via filterQuery.
17921
- function VarPopup({
17922
- variables,
17923
- variableGroups,
17924
- filterQuery = "",
17925
- onSelect,
17926
- onAddVariable,
17927
- onEditVariable,
17928
- style,
17929
- }: {
17930
- variables: string[];
17931
- variableGroups?: VariableGroup[];
17932
- filterQuery?: string;
17933
- onSelect: (v: string) => void;
17934
- onAddVariable?: () => void;
17935
- onEditVariable?: (variable: string) => void;
17936
- style?: React.CSSProperties;
17937
- }) {
17938
- const hasGroups = variableGroups && variableGroups.length > 0;
17939
-
17940
- if (!hasGroups && variables.length === 0) return null;
17941
-
17942
- // Flat mode \u2014 variables are already pre-filtered by VariableInput
17943
- if (!hasGroups) {
17944
- return (
17945
- <div
17946
- role="listbox"
17947
- style={style}
17948
- className="absolute z-[9999] min-w-[14rem] max-w-sm rounded-md border border-semantic-border-layout bg-semantic-bg-primary py-1 text-semantic-text-primary shadow-md"
17949
- >
17950
- {/* Add new variable */}
17951
- {onAddVariable && (
17952
- <button
17953
- type="button"
17954
- onMouseDown={(e) => { e.preventDefault(); onAddVariable(); }}
17955
- className="flex w-full items-center gap-2 px-3 py-2 text-sm font-medium text-semantic-text-primary hover:bg-semantic-bg-ui transition-colors"
17956
- >
17957
- <Plus className="size-3.5 shrink-0" />
17958
- Add new variable
17959
- </button>
17960
- )}
17961
-
17962
- {/* Variable list */}
17963
- <div className="max-h-48 overflow-y-auto p-1">
17964
- {variables.map((v) => (
17965
- <button
17966
- key={v}
17967
- type="button"
17968
- role="option"
17969
- onMouseDown={(e) => { e.preventDefault(); onSelect(v); }}
17970
- className="relative flex w-full cursor-pointer select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors hover:bg-semantic-bg-ui"
17971
- >
17972
- {v}
17973
- </button>
17974
- ))}
17975
- {variables.length === 0 && (
17976
- <p className="m-0 px-2 py-1.5 text-sm text-semantic-text-muted">No variables found</p>
17977
- )}
17978
- </div>
17979
- </div>
17980
- );
17981
- }
17982
-
17983
- // Grouped mode \u2014 filter by the {{ trigger query
17984
- const lowerQuery = filterQuery.toLowerCase();
17985
- const filteredGroups = variableGroups.map((g) => ({
17986
- ...g,
17987
- items: g.items.filter((item) =>
17988
- item.name.toLowerCase().includes(lowerQuery)
17989
- ),
17990
- })).filter((g) => g.items.length > 0);
17991
-
17992
- return (
17993
- <div
17994
- role="listbox"
17995
- style={style}
17996
- className="absolute z-[9999] min-w-[14rem] max-w-sm rounded-md border border-semantic-border-layout bg-semantic-bg-primary py-1 text-semantic-text-primary shadow-md"
17997
- >
17998
- {/* Add new variable */}
17999
- {onAddVariable && (
18000
- <>
18001
- <button
18002
- type="button"
18003
- onMouseDown={(e) => { e.preventDefault(); onAddVariable(); }}
18004
- className="flex w-full items-center gap-2 px-3 py-2 text-sm font-medium text-semantic-text-primary hover:bg-semantic-bg-ui transition-colors"
18005
- >
18006
- <Plus className="size-3.5 shrink-0" />
18007
- Add new variable
18008
- </button>
18009
- <div className="border-t border-semantic-border-layout" />
18010
- </>
18011
- )}
18012
-
18013
- {/* Grouped variable list */}
18014
- <div className="max-h-48 overflow-y-auto p-1">
18015
- {filteredGroups.map((group) => (
18016
- <div key={group.label}>
18017
- <p className="m-0 px-2 pt-2 pb-1 text-sm font-medium text-semantic-text-muted">
18018
- {group.label}
18019
- </p>
18020
- {group.items.map((item) => {
18021
- const insertValue = item.value ?? \`{{\${item.name}}}\`;
18022
- return (
18023
- <div key={item.name} className="flex items-center rounded-sm transition-colors hover:bg-semantic-bg-ui">
18024
- <button
18025
- type="button"
18026
- role="option"
18027
- onMouseDown={(e) => { e.preventDefault(); onSelect(insertValue); }}
18028
- className="relative flex flex-1 min-w-0 cursor-pointer select-none items-center px-2 py-1.5 text-sm outline-none"
18029
- >
18030
- {\`{{\${item.name}}}\`}
18031
- </button>
18032
- {item.editable && onEditVariable && (
18033
- <button
18034
- type="button"
18035
- onMouseDown={(e) => { e.preventDefault(); onEditVariable(item.name); }}
18036
- className="shrink-0 p-1.5 rounded text-semantic-text-muted hover:text-semantic-text-primary transition-colors"
18037
- aria-label={\`Edit \${item.name}\`}
18038
- >
18039
- <Pencil className="size-3.5" />
18040
- </button>
18041
- )}
18042
- </div>
18043
- );
18044
- })}
18045
- </div>
18046
- ))}
18047
- {filteredGroups.length === 0 && (
18048
- <p className="m-0 px-2 py-1.5 text-sm text-semantic-text-muted">No variables found</p>
18049
- )}
18050
- </div>
18051
- </div>
18052
- );
17329
+ function extractVarRefs(texts: string[]): string[] {
17330
+ const pattern = /\\{\\{[^}]+\\}\\}/g;
17331
+ const all = texts.flatMap((t) => t.match(pattern) ?? []);
17332
+ return Array.from(new Set(all));
18053
17333
  }
18054
17334
 
18055
- // \u2500\u2500 VariableFormModal \u2014 create/edit a variable \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
17335
+ /** Mirror-div technique \u2014 returns { top, left } relative to the element's top-left corner. */
17336
+ function getCaretPixelPos(
17337
+ el: HTMLTextAreaElement | HTMLInputElement,
17338
+ position: number
17339
+ ): { top: number; left: number } {
17340
+ const cs = window.getComputedStyle(el);
17341
+ const mirror = document.createElement("div");
18056
17342
 
18057
- function VariableFormModal({
18058
- open,
18059
- onOpenChange,
18060
- mode,
18061
- initialData,
18062
- onSave,
18063
- }: {
18064
- open: boolean;
18065
- onOpenChange: (open: boolean) => void;
18066
- mode: "create" | "edit";
18067
- initialData?: VariableItem;
18068
- onSave: (data: VariableFormData) => void;
18069
- }) {
18070
- const [name, setName] = React.useState("");
18071
- const [description, setDescription] = React.useState("");
18072
- const [required, setRequired] = React.useState(false);
18073
- const [nameError, setNameError] = React.useState("");
17343
+ (
17344
+ [
17345
+ "boxSizing", "width", "paddingTop", "paddingRight", "paddingBottom", "paddingLeft",
17346
+ "borderTopWidth", "borderRightWidth", "borderBottomWidth", "borderLeftWidth",
17347
+ "fontFamily", "fontSize", "fontWeight", "fontStyle", "fontVariant",
17348
+ "letterSpacing", "lineHeight", "textTransform", "wordSpacing", "tabSize",
17349
+ ] as (keyof CSSStyleDeclaration)[]
17350
+ ).forEach((prop) => {
17351
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
17352
+ (mirror.style as any)[prop] = cs[prop];
17353
+ });
18074
17354
 
18075
- // Reset form when modal opens
18076
- React.useEffect(() => {
18077
- if (open) {
18078
- setName(initialData?.name ?? "");
18079
- setDescription(initialData?.description ?? "");
18080
- setRequired(initialData?.required ?? false);
18081
- setNameError("");
18082
- }
18083
- }, [open, initialData]);
17355
+ mirror.style.whiteSpace = el.tagName === "TEXTAREA" ? "pre-wrap" : "pre";
17356
+ mirror.style.wordWrap = el.tagName === "TEXTAREA" ? "break-word" : "normal";
17357
+ mirror.style.position = "absolute";
17358
+ mirror.style.visibility = "hidden";
17359
+ mirror.style.overflow = "hidden";
17360
+ mirror.style.top = "0";
17361
+ mirror.style.left = "0";
17362
+ mirror.style.width = el.offsetWidth + "px";
18084
17363
 
18085
- const validateName = (v: string) => {
18086
- if (!v.trim()) return "";
18087
- if (!VARIABLE_NAME_REGEX.test(v)) {
18088
- return "Variable name should start with alphabet; Cannot have special characters except underscore (_)";
18089
- }
18090
- return "";
18091
- };
17364
+ document.body.appendChild(mirror);
17365
+ mirror.appendChild(document.createTextNode(el.value.substring(0, position)));
18092
17366
 
18093
- const handleNameChange = (e: React.ChangeEvent<HTMLInputElement>) => {
18094
- const v = e.target.value;
18095
- setName(v);
18096
- setNameError(validateName(v));
18097
- };
17367
+ const marker = document.createElement("span");
17368
+ marker.textContent = "\\u200b";
17369
+ mirror.appendChild(marker);
18098
17370
 
18099
- const handleSave = () => {
18100
- const error = validateName(name);
18101
- if (error || !name.trim()) {
18102
- setNameError(error || "Variable name is required");
18103
- return;
18104
- }
18105
- onSave({ name: name.trim(), description: description.trim() || undefined, required });
17371
+ const markerRect = marker.getBoundingClientRect();
17372
+ const mirrorRect = mirror.getBoundingClientRect();
17373
+ document.body.removeChild(mirror);
17374
+
17375
+ const scrollTop = el instanceof HTMLTextAreaElement ? el.scrollTop : 0;
17376
+ return {
17377
+ top: markerRect.top - mirrorRect.top - scrollTop,
17378
+ left: markerRect.left - mirrorRect.left,
18106
17379
  };
17380
+ }
18107
17381
 
17382
+ // Uses same visual classes as DropdownMenuContent + DropdownMenuItem.
17383
+ // Position is cursor-anchored via getCaretPixelPos.
17384
+ function VarPopup({
17385
+ variables,
17386
+ onSelect,
17387
+ style,
17388
+ }: {
17389
+ variables: string[];
17390
+ onSelect: (v: string) => void;
17391
+ style?: React.CSSProperties;
17392
+ }) {
17393
+ if (variables.length === 0) return null;
18108
17394
  return (
18109
- <FormModal
18110
- open={open}
18111
- onOpenChange={onOpenChange}
18112
- title={mode === "create" ? "Create new variable" : "Edit variable"}
18113
- saveButtonText={mode === "create" ? "Save" : "Save Changes"}
18114
- disableSave={!name.trim() || !!nameError}
18115
- onSave={handleSave}
18116
- size="default"
17395
+ <div
17396
+ role="listbox"
17397
+ style={style}
17398
+ className="absolute z-[9999] min-w-[8rem] max-w-xs overflow-hidden rounded-md border border-semantic-border-layout bg-semantic-bg-primary p-1 text-semantic-text-primary shadow-md"
18117
17399
  >
18118
- <div className="flex flex-col gap-4">
18119
- <div className="flex flex-col gap-1.5">
18120
- <label className="text-sm font-medium text-semantic-text-muted">
18121
- Variable name{" "}
18122
- <span className="text-semantic-error-primary">*</span>
18123
- </label>
18124
- <div className="relative">
18125
- <input
18126
- type="text"
18127
- value={name}
18128
- onChange={handleNameChange}
18129
- placeholder="e.g., customer_name"
18130
- maxLength={VARIABLE_NAME_MAX}
18131
- className={cn(inputCls, "pr-16")}
18132
- />
18133
- <span className="absolute right-3 top-1/2 -translate-y-1/2 text-sm text-semantic-text-muted pointer-events-none">
18134
- {name.length}/{VARIABLE_NAME_MAX}
18135
- </span>
18136
- </div>
18137
- <span className={cn("text-sm", nameError ? "text-semantic-error-primary" : "text-semantic-text-muted")}>
18138
- {nameError || "Variable name should start with alphabet; Cannot have special characters except underscore (_)"}
18139
- </span>
18140
- </div>
18141
- <TextField
18142
- label="Description (optional)"
18143
- placeholder="What this variable represents"
18144
- value={description}
18145
- onChange={(e) => setDescription(e.target.value)}
18146
- />
18147
- <div className="flex flex-col gap-1.5">
18148
- <span className="text-sm font-medium text-semantic-text-muted">Required</span>
18149
- <div className="flex items-center gap-6">
18150
- <label className="flex items-center gap-2 cursor-pointer">
18151
- <input
18152
- type="radio"
18153
- name="variable-required"
18154
- checked={required}
18155
- onChange={() => setRequired(true)}
18156
- className="size-4 accent-semantic-primary"
18157
- />
18158
- <span className="text-base text-semantic-text-primary">Yes</span>
18159
- </label>
18160
- <label className="flex items-center gap-2 cursor-pointer">
18161
- <input
18162
- type="radio"
18163
- name="variable-required"
18164
- checked={!required}
18165
- onChange={() => setRequired(false)}
18166
- className="size-4 accent-semantic-primary"
18167
- />
18168
- <span className="text-base text-semantic-text-primary">No</span>
18169
- </label>
18170
- </div>
18171
- </div>
18172
- </div>
18173
- </FormModal>
17400
+ {variables.map((v) => (
17401
+ <button
17402
+ key={v}
17403
+ type="button"
17404
+ role="option"
17405
+ aria-selected={false}
17406
+ onMouseDown={(e) => {
17407
+ e.preventDefault(); // keep input focused so blur doesn't close popup first
17408
+ onSelect(v);
17409
+ }}
17410
+ className="relative flex w-full cursor-pointer select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors hover:bg-semantic-bg-ui focus:bg-semantic-bg-ui"
17411
+ >
17412
+ {v}
17413
+ </button>
17414
+ ))}
17415
+ </div>
18174
17416
  );
18175
17417
  }
18176
17418
 
18177
- // \u2500\u2500 VariableInput \u2014 input with {{ autocomplete + badge display \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
17419
+ // \u2500\u2500 VariableInput \u2014 input with {{ autocomplete \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
18178
17420
 
18179
17421
  function VariableInput({
18180
17422
  value,
18181
17423
  onChange,
18182
17424
  sessionVariables,
18183
- variableGroups,
18184
- onAddVariable,
18185
- onEditVariable,
18186
17425
  placeholder,
18187
17426
  maxLength,
18188
17427
  className,
18189
17428
  inputRef: externalInputRef,
18190
- disabled,
18191
17429
  ...inputProps
18192
17430
  }: {
18193
17431
  value: string;
18194
17432
  onChange: (v: string) => void;
18195
17433
  sessionVariables: string[];
18196
- variableGroups?: VariableGroup[];
18197
- onAddVariable?: () => void;
18198
- onEditVariable?: (variable: string) => void;
18199
17434
  placeholder?: string;
18200
17435
  maxLength?: number;
18201
17436
  className?: string;
18202
17437
  inputRef?: React.RefObject<HTMLInputElement>;
18203
- disabled?: boolean;
18204
17438
  [k: string]: unknown;
18205
17439
  }) {
18206
17440
  const internalRef = React.useRef<HTMLInputElement>(null);
18207
17441
  const inputRef = externalInputRef ?? internalRef;
18208
- const displayRef = React.useRef<HTMLDivElement>(null);
18209
17442
  const [trigger, setTrigger] = React.useState<TriggerState | null>(null);
18210
17443
  const [popupStyle, setPopupStyle] = React.useState<React.CSSProperties | undefined>();
18211
- const [isEditing, setIsEditing] = React.useState(false);
18212
- const [isExpanded, setIsExpanded] = React.useState(false);
18213
- const [isOverflowing, setIsOverflowing] = React.useState(false);
18214
17444
 
18215
17445
  const filtered = trigger
18216
17446
  ? sessionVariables.filter((v) => v.toLowerCase().includes(trigger.query))
18217
17447
  : [];
18218
17448
 
18219
- // Parse value into text + variable segments
18220
- const segments = React.useMemo(() => parseValueSegments(value), [value]);
18221
- const hasVariables = segments.some((s) => s.type === "var");
18222
- const showDisplay = !isEditing && value.length > 0 && hasVariables;
18223
-
18224
- // Check overflow in display mode
18225
- React.useEffect(() => {
18226
- if (showDisplay && displayRef.current && !isExpanded) {
18227
- const el = displayRef.current;
18228
- setIsOverflowing(el.scrollWidth > el.clientWidth);
18229
- } else {
18230
- setIsOverflowing(false);
18231
- }
18232
- }, [showDisplay, value, isExpanded]);
18233
-
18234
17449
  const updatePopupPos = (el: HTMLInputElement, cursor: number) => {
18235
17450
  const caret = getCaretPixelPos(el, cursor);
18236
17451
  const lineHeight = parseFloat(window.getComputedStyle(el).lineHeight) || 20;
@@ -18259,15 +17474,13 @@ function VariableInput({
18259
17474
 
18260
17475
  return (
18261
17476
  <div className="relative w-full">
18262
- {/* Input \u2014 always in DOM, hidden when display mode is active */}
18263
17477
  <input
18264
17478
  ref={inputRef}
18265
17479
  type="text"
18266
17480
  value={value}
18267
17481
  placeholder={placeholder}
18268
17482
  maxLength={maxLength}
18269
- disabled={disabled}
18270
- className={cn(className, showDisplay && "opacity-0 pointer-events-none")}
17483
+ className={className}
18271
17484
  onChange={(e) => {
18272
17485
  onChange(e.target.value);
18273
17486
  const cursor = e.target.selectionStart ?? e.target.value.length;
@@ -18279,88 +17492,10 @@ function VariableInput({
18279
17492
  onKeyDown={(e) => {
18280
17493
  if (e.key === "Escape") clearTrigger();
18281
17494
  }}
18282
- onFocus={() => setIsEditing(true)}
18283
- onBlur={() => {
18284
- clearTrigger();
18285
- setIsEditing(false);
18286
- setIsExpanded(false);
18287
- }}
17495
+ onBlur={() => clearTrigger()}
18288
17496
  {...inputProps}
18289
17497
  />
18290
-
18291
- {/* Display mode \u2014 variable badges + text + overflow */}
18292
- {showDisplay && (
18293
- <div
18294
- className={cn(
18295
- "absolute cursor-text",
18296
- !isExpanded && "inset-0 flex items-center",
18297
- isExpanded && "inset-x-0 top-0 z-10",
18298
- disabled && "opacity-50 cursor-not-allowed"
18299
- )}
18300
- onClick={() => {
18301
- if (!disabled) inputRef.current?.focus();
18302
- }}
18303
- >
18304
- <div
18305
- ref={displayRef}
18306
- className={cn(
18307
- "flex items-center gap-1 px-2",
18308
- !isExpanded && "flex-1 min-w-0 overflow-hidden",
18309
- isExpanded && "flex-wrap bg-semantic-bg-primary border border-semantic-border-input rounded py-1.5 shadow-sm"
18310
- )}
18311
- >
18312
- {segments.map((seg, i) =>
18313
- seg.type === "text" ? (
18314
- <span key={i} className="text-sm text-semantic-text-primary whitespace-pre shrink-0">{seg.content}</span>
18315
- ) : (
18316
- <span
18317
- key={i}
18318
- className="inline-flex items-center gap-1 shrink-0 rounded px-1.5 py-0.5 text-sm bg-semantic-info-surface text-semantic-text-primary"
18319
- >
18320
- {seg.name}
18321
- {onEditVariable && (
18322
- <button
18323
- type="button"
18324
- onMouseDown={(e) => {
18325
- e.preventDefault();
18326
- e.stopPropagation();
18327
- onEditVariable(seg.name);
18328
- }}
18329
- className="p-0.5 text-semantic-text-muted hover:text-semantic-text-primary transition-colors"
18330
- >
18331
- <Pencil className="size-3" />
18332
- </button>
18333
- )}
18334
- </span>
18335
- )
18336
- )}
18337
- </div>
18338
- {isOverflowing && !isExpanded && (
18339
- <button
18340
- type="button"
18341
- onMouseDown={(e) => {
18342
- e.preventDefault();
18343
- e.stopPropagation();
18344
- setIsExpanded(true);
18345
- }}
18346
- className="shrink-0 px-1 text-sm font-medium text-semantic-text-muted hover:text-semantic-text-primary"
18347
- >
18348
- ...
18349
- </button>
18350
- )}
18351
- </div>
18352
- )}
18353
-
18354
- {/* VarPopup */}
18355
- <VarPopup
18356
- variables={filtered}
18357
- variableGroups={trigger ? variableGroups : undefined}
18358
- filterQuery={trigger?.query ?? ""}
18359
- onSelect={handleSelect}
18360
- onAddVariable={onAddVariable}
18361
- onEditVariable={onEditVariable}
18362
- style={popupStyle}
18363
- />
17498
+ <VarPopup variables={filtered} onSelect={handleSelect} style={popupStyle} />
18364
17499
  </div>
18365
17500
  );
18366
17501
  }
@@ -18370,7 +17505,7 @@ const inputCls = cn(
18370
17505
  "w-full h-[42px] px-4 text-base rounded border",
18371
17506
  "border-semantic-border-input bg-semantic-bg-primary",
18372
17507
  "text-semantic-text-primary placeholder:text-semantic-text-muted",
18373
- "outline-none",
17508
+ "outline-none hover:border-semantic-border-input-focus",
18374
17509
  "focus:border-semantic-border-input-focus focus:shadow-[0_0_0_1px_rgba(43,188,202,0.15)]",
18375
17510
  "disabled:opacity-50 disabled:cursor-not-allowed"
18376
17511
  );
@@ -18379,7 +17514,7 @@ const textareaCls = cn(
18379
17514
  "w-full px-4 py-2.5 text-base rounded border resize-none",
18380
17515
  "border-semantic-border-input bg-semantic-bg-primary",
18381
17516
  "text-semantic-text-primary placeholder:text-semantic-text-muted",
18382
- "outline-none",
17517
+ "outline-none hover:border-semantic-border-input-focus",
18383
17518
  "focus:border-semantic-border-input-focus focus:shadow-[0_0_0_1px_rgba(43,188,202,0.15)]",
18384
17519
  "disabled:opacity-50 disabled:cursor-not-allowed"
18385
17520
  );
@@ -18397,9 +17532,6 @@ function KeyValueTable({
18397
17532
  keyRegex,
18398
17533
  keyRegexError,
18399
17534
  sessionVariables = [],
18400
- variableGroups,
18401
- onAddVariable,
18402
- onEditVariable,
18403
17535
  disabled = false,
18404
17536
  }: {
18405
17537
  rows: KeyValuePair[];
@@ -18411,9 +17543,6 @@ function KeyValueTable({
18411
17543
  keyRegex?: RegExp;
18412
17544
  keyRegexError?: string;
18413
17545
  sessionVariables?: string[];
18414
- variableGroups?: VariableGroup[];
18415
- onAddVariable?: () => void;
18416
- onEditVariable?: (variable: string) => void;
18417
17546
  disabled?: boolean;
18418
17547
  }) {
18419
17548
  const update = (id: string, patch: Partial<KeyValuePair>) => {
@@ -18445,14 +17574,14 @@ function KeyValueTable({
18445
17574
 
18446
17575
  return (
18447
17576
  <div className="flex flex-col gap-1.5">
18448
- <span className="text-sm text-semantic-text-muted">{label}</span>
18449
- <div className="border border-semantic-border-layout rounded">
17577
+ <span className="text-xs text-semantic-text-muted">{label}</span>
17578
+ <div className="border border-semantic-border-layout rounded overflow-hidden">
18450
17579
  {/* Column headers \u2014 desktop only; border-r on Key cell defines column boundary */}
18451
- <div className="hidden sm:flex border-b border-semantic-border-layout rounded-t">
18452
- <div className="flex-1 min-w-0 px-3 py-2 text-sm font-semibold text-semantic-text-muted border-r border-semantic-border-layout">
17580
+ <div className="hidden sm:flex bg-semantic-bg-ui border-b border-semantic-border-layout">
17581
+ <div className="flex-1 min-w-0 px-3 py-2 text-xs font-semibold text-semantic-text-muted border-r border-semantic-border-layout">
18453
17582
  Key
18454
17583
  </div>
18455
- <div className="flex-[2] min-w-0 px-3 py-2 text-sm font-semibold text-semantic-text-muted">
17584
+ <div className="flex-[2] min-w-0 px-3 py-2 text-xs font-semibold text-semantic-text-muted">
18456
17585
  Value
18457
17586
  </div>
18458
17587
  <div className="w-10 shrink-0" aria-hidden="true" />
@@ -18468,7 +17597,7 @@ function KeyValueTable({
18468
17597
  >
18469
17598
  {/* Key column \u2014 border-r on column (not input) so it aligns with header */}
18470
17599
  <div className="flex-1 flex flex-col min-w-0 sm:border-r sm:border-semantic-border-layout">
18471
- <span className="sm:hidden px-3 pt-2.5 pb-0.5 text-sm font-semibold text-semantic-text-muted uppercase tracking-wide">
17600
+ <span className="sm:hidden px-3 pt-2.5 pb-0.5 text-[10px] font-semibold text-semantic-text-muted uppercase tracking-wide">
18472
17601
  Key
18473
17602
  </span>
18474
17603
  <input
@@ -18479,36 +17608,45 @@ function KeyValueTable({
18479
17608
  maxLength={keyMaxLength}
18480
17609
  disabled={disabled}
18481
17610
  className={cn(
18482
- "w-full px-3 py-2.5 text-base text-semantic-text-primary placeholder:text-semantic-text-muted bg-semantic-bg-primary outline-none",
17611
+ "w-full px-3 py-2.5 text-base text-semantic-text-primary placeholder:text-semantic-text-muted bg-semantic-bg-primary outline-none focus:bg-semantic-bg-hover",
18483
17612
  "disabled:opacity-50 disabled:cursor-not-allowed",
18484
- errors.key && "text-semantic-error-primary"
17613
+ errors.key && "border-semantic-error-primary"
18485
17614
  )}
18486
17615
  aria-invalid={Boolean(errors.key)}
17616
+ aria-describedby={errors.key ? \`err-key-\${row.id}\` : undefined}
18487
17617
  />
17618
+ {errors.key && (
17619
+ <p id={\`err-key-\${row.id}\`} className="m-0 px-3 pt-0.5 text-xs text-semantic-error-primary">
17620
+ {errors.key}
17621
+ </p>
17622
+ )}
18488
17623
  </div>
18489
17624
 
18490
17625
  {/* Value column \u2014 uses VariableInput for {{ autocomplete */}
18491
17626
  <div className="flex-[2] flex flex-col min-w-0">
18492
- <span className="sm:hidden px-3 pt-2.5 pb-0.5 text-sm font-semibold text-semantic-text-muted uppercase tracking-wide">
17627
+ <span className="sm:hidden px-3 pt-2.5 pb-0.5 text-[10px] font-semibold text-semantic-text-muted uppercase tracking-wide">
18493
17628
  Value
18494
17629
  </span>
18495
17630
  <VariableInput
18496
17631
  value={row.value}
18497
17632
  onChange={(v) => update(row.id, { value: v })}
18498
17633
  sessionVariables={sessionVariables}
18499
- variableGroups={variableGroups}
18500
- onAddVariable={onAddVariable}
18501
- onEditVariable={onEditVariable}
18502
17634
  placeholder="Type {{ to add variables"
18503
17635
  maxLength={valueMaxLength}
18504
17636
  disabled={disabled}
18505
17637
  className={cn(
18506
- "w-full px-3 py-2.5 text-base text-semantic-text-primary placeholder:text-semantic-text-muted bg-semantic-bg-primary outline-none",
17638
+ "w-full px-3 py-2.5 text-base text-semantic-text-primary placeholder:text-semantic-text-muted bg-semantic-bg-primary outline-none focus:bg-semantic-bg-hover",
18507
17639
  "disabled:opacity-50 disabled:cursor-not-allowed",
18508
- errors.value && "text-semantic-error-primary"
17640
+ errors.value && "border-semantic-error-primary"
18509
17641
  )}
18510
17642
  aria-invalid={Boolean(errors.value)}
17643
+ aria-describedby={errors.value ? \`err-value-\${row.id}\` : undefined}
18511
17644
  />
17645
+ {errors.value && (
17646
+ <p id={\`err-value-\${row.id}\`} className="m-0 px-3 pt-0.5 text-xs text-semantic-error-primary">
17647
+ {errors.value}
17648
+ </p>
17649
+ )}
18512
17650
  </div>
18513
17651
 
18514
17652
  {/* Action column \u2014 delete aligned with row (same as KeyValueRow / knowledge-base-card) */}
@@ -18535,7 +17673,7 @@ function KeyValueTable({
18535
17673
  onClick={add}
18536
17674
  disabled={disabled}
18537
17675
  className={cn(
18538
- "w-full flex items-center gap-2 px-3 py-2.5 text-sm text-semantic-text-muted hover:bg-semantic-bg-ui transition-colors",
17676
+ "w-full flex items-center gap-2 px-3 py-2.5 text-sm text-semantic-text-muted hover:bg-semantic-bg-hover transition-colors",
18539
17677
  disabled && "opacity-50 cursor-not-allowed"
18540
17678
  )}
18541
17679
  >
@@ -18543,35 +17681,15 @@ function KeyValueTable({
18543
17681
  <span>Add row</span>
18544
17682
  </button>
18545
17683
  </div>
18546
-
18547
- {/* Collected row errors \u2014 shown below the table */}
18548
- {(() => {
18549
- const allErrors = rows
18550
- .map((row) => {
18551
- const errs = getErrors(row);
18552
- const msgs: string[] = [];
18553
- if (errs.key) msgs.push(errs.key);
18554
- if (errs.value) msgs.push(errs.value);
18555
- return msgs;
18556
- })
18557
- .flat();
18558
- if (allErrors.length === 0) return null;
18559
- // Deduplicate
18560
- const unique = Array.from(new Set(allErrors));
18561
- return (
18562
- <div className="flex flex-col gap-0.5">
18563
- {unique.map((msg) => (
18564
- <p key={msg} className="m-0 text-sm text-semantic-error-primary">{msg}</p>
18565
- ))}
18566
- </div>
18567
- );
18568
- })()}
18569
17684
  </div>
18570
17685
  );
18571
17686
  }
18572
17687
 
18573
17688
  // \u2500\u2500 Modal \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
18574
- export const CreateFunctionModal = React.forwardRef(
17689
+ export const CreateFunctionModal = React.forwardRef<
17690
+ HTMLDivElement,
17691
+ CreateFunctionModalProps
17692
+ >(
18575
17693
  (
18576
17694
  {
18577
17695
  open,
@@ -18585,13 +17703,10 @@ export const CreateFunctionModal = React.forwardRef(
18585
17703
  initialStep = 1,
18586
17704
  initialTab = "header",
18587
17705
  sessionVariables = DEFAULT_SESSION_VARIABLES,
18588
- variableGroups,
18589
- onAddVariable,
18590
- onEditVariable,
18591
17706
  disabled = false,
18592
17707
  className,
18593
- }: CreateFunctionModalProps,
18594
- ref: React.Ref<HTMLDivElement>
17708
+ },
17709
+ ref
18595
17710
  ) => {
18596
17711
  const [step, setStep] = React.useState<1 | 2>(initialStep);
18597
17712
 
@@ -18612,35 +17727,6 @@ export const CreateFunctionModal = React.forwardRef(
18612
17727
  const [urlError, setUrlError] = React.useState("");
18613
17728
  const [bodyError, setBodyError] = React.useState("");
18614
17729
 
18615
- // Variable modal state
18616
- const [varModalOpen, setVarModalOpen] = React.useState(false);
18617
- const [varModalMode, setVarModalMode] = React.useState<"create" | "edit">("create");
18618
- const [varModalInitialData, setVarModalInitialData] = React.useState<VariableItem | undefined>();
18619
-
18620
- const handleAddVariableClick = () => {
18621
- setVarModalMode("create");
18622
- setVarModalInitialData(undefined);
18623
- setVarModalOpen(true);
18624
- };
18625
-
18626
- const handleEditVariableClick = (variableName: string) => {
18627
- const variable = variableGroups
18628
- ?.flatMap((g) => g.items)
18629
- .find((item) => item.name === variableName);
18630
- setVarModalMode("edit");
18631
- setVarModalInitialData(variable ?? { name: variableName, editable: true });
18632
- setVarModalOpen(true);
18633
- };
18634
-
18635
- const handleVariableSave = (data: VariableFormData) => {
18636
- if (varModalMode === "create") {
18637
- onAddVariable?.(data);
18638
- } else {
18639
- onEditVariable?.(varModalInitialData?.name ?? "", data);
18640
- }
18641
- setVarModalOpen(false);
18642
- };
18643
-
18644
17730
  // Variable trigger state for URL and body
18645
17731
  const urlInputRef = React.useRef<HTMLInputElement>(null);
18646
17732
  const bodyTextareaRef = React.useRef<HTMLTextAreaElement>(null);
@@ -18735,7 +17821,14 @@ export const CreateFunctionModal = React.forwardRef(
18735
17821
  onOpenChange(false);
18736
17822
  }, [reset, onOpenChange]);
18737
17823
 
18738
- // Body tab is always visible regardless of HTTP method
17824
+ const supportsBody = METHODS_WITH_BODY.includes(method);
17825
+
17826
+ // When switching to a method without body, reset to header tab if body was active
17827
+ React.useEffect(() => {
17828
+ if (!supportsBody && activeTab === "body") {
17829
+ setActiveTab("header");
17830
+ }
17831
+ }, [supportsBody, activeTab]);
18739
17832
 
18740
17833
  const validateName = (value: string) => {
18741
17834
  if (value.trim() && !FUNCTION_NAME_REGEX.test(value.trim())) {
@@ -18870,10 +17963,11 @@ export const CreateFunctionModal = React.forwardRef(
18870
17963
  body: "Body",
18871
17964
  };
18872
17965
 
18873
- const visibleTabs: FunctionTabType[] = ["header", "queryParams", "body"];
17966
+ const visibleTabs: FunctionTabType[] = supportsBody
17967
+ ? ["header", "queryParams", "body"]
17968
+ : ["header", "queryParams"];
18874
17969
 
18875
17970
  return (
18876
- <>
18877
17971
  <Dialog open={open} onOpenChange={onOpenChange}>
18878
17972
  <DialogContent
18879
17973
  ref={ref}
@@ -18881,7 +17975,7 @@ export const CreateFunctionModal = React.forwardRef(
18881
17975
  hideCloseButton
18882
17976
  className={cn(
18883
17977
  "flex flex-col gap-0 p-0 w-[calc(100vw-2rem)] sm:w-full",
18884
- "max-h-[calc(100vh-2rem)] overflow-hidden",
17978
+ "max-h-[calc(100svh-2rem)] overflow-hidden",
18885
17979
  className
18886
17980
  )}
18887
17981
  >
@@ -18901,7 +17995,7 @@ export const CreateFunctionModal = React.forwardRef(
18901
17995
  </div>
18902
17996
 
18903
17997
  {/* \u2500\u2500 Scrollable body \u2500\u2500 */}
18904
- <div className="flex-1 overflow-y-auto min-h-0 overscroll-contain px-4 py-5 sm:px-6">
17998
+ <div className="flex-1 overflow-y-auto min-h-0 px-4 py-5 sm:px-6">
18905
17999
  {/* \u2500 Step 1 \u2500 */}
18906
18000
  {step === 1 && (
18907
18001
  <div className="flex flex-col gap-5">
@@ -18928,33 +18022,44 @@ export const CreateFunctionModal = React.forwardRef(
18928
18022
  placeholder="Enter name of the function"
18929
18023
  className={cn(inputCls, "pr-16")}
18930
18024
  />
18931
- <span className="absolute right-3 top-1/2 -translate-y-1/2 text-sm text-semantic-text-muted pointer-events-none">
18025
+ <span className="absolute right-3 top-1/2 -translate-y-1/2 text-xs italic text-semantic-text-muted pointer-events-none">
18932
18026
  {name.length}/{FUNCTION_NAME_MAX}
18933
18027
  </span>
18934
18028
  </div>
18935
18029
  {nameError && (
18936
- <p className="m-0 text-sm text-semantic-error-primary">{nameError}</p>
18030
+ <p className="m-0 text-xs text-semantic-error-primary">{nameError}</p>
18937
18031
  )}
18938
18032
  </div>
18939
18033
 
18940
- <Textarea
18941
- id="fn-prompt"
18942
- label="Prompt"
18943
- required
18944
- value={prompt}
18945
- maxLength={promptMaxLength}
18946
- showCount
18947
- disabled={disabled}
18948
- onChange={(e) => setPrompt(e.target.value)}
18949
- placeholder="Enter the description of the function"
18950
- rows={5}
18951
- labelClassName="font-semibold text-semantic-text-primary"
18952
- error={
18953
- prompt.length > 0 && prompt.trim().length < promptMinLength
18954
- ? \`Minimum \${promptMinLength} characters required\`
18955
- : undefined
18956
- }
18957
- />
18034
+ <div className="flex flex-col gap-1.5">
18035
+ <label
18036
+ htmlFor="fn-prompt"
18037
+ className="text-sm font-semibold text-semantic-text-primary"
18038
+ >
18039
+ Prompt{" "}
18040
+ <span className="text-semantic-error-primary">*</span>
18041
+ </label>
18042
+ <div className="relative">
18043
+ <textarea
18044
+ id="fn-prompt"
18045
+ value={prompt}
18046
+ maxLength={promptMaxLength}
18047
+ disabled={disabled}
18048
+ onChange={(e) => setPrompt(e.target.value)}
18049
+ placeholder="Enter the description of the function"
18050
+ rows={5}
18051
+ className={cn(textareaCls, "pb-7")}
18052
+ />
18053
+ <span className="absolute bottom-2 right-3 text-xs italic text-semantic-text-muted pointer-events-none">
18054
+ {prompt.length}/{promptMaxLength}
18055
+ </span>
18056
+ </div>
18057
+ {prompt.length > 0 && prompt.trim().length < promptMinLength && (
18058
+ <p className="m-0 text-xs text-semantic-error-primary">
18059
+ Minimum {promptMinLength} characters required
18060
+ </p>
18061
+ )}
18062
+ </div>
18958
18063
  </div>
18959
18064
  )}
18960
18065
 
@@ -18963,12 +18068,13 @@ export const CreateFunctionModal = React.forwardRef(
18963
18068
  <div className="flex flex-col gap-5">
18964
18069
  {/* API URL \u2014 always a single combined row */}
18965
18070
  <div className="flex flex-col gap-1.5">
18966
- <span className="text-sm text-semantic-text-muted tracking-[0.048px]">
18071
+ <span className="text-xs text-semantic-text-muted tracking-[0.048px]">
18967
18072
  API URL
18968
18073
  </span>
18969
18074
  <div
18970
18075
  className={cn(
18971
18076
  "flex h-[42px] rounded border border-semantic-border-input overflow-visible bg-semantic-bg-primary",
18077
+ "hover:border-semantic-border-input-focus",
18972
18078
  "focus-within:border-semantic-border-input-focus focus-within:shadow-[0_0_0_1px_rgba(43,188,202,0.15)]",
18973
18079
  "transition-shadow"
18974
18080
  )}
@@ -19029,19 +18135,11 @@ export const CreateFunctionModal = React.forwardRef(
19029
18135
  disabled && "opacity-50 cursor-not-allowed"
19030
18136
  )}
19031
18137
  />
19032
- <VarPopup
19033
- variables={filteredUrlVars}
19034
- variableGroups={urlTrigger ? variableGroups : undefined}
19035
- filterQuery={urlTrigger?.query ?? ""}
19036
- onSelect={handleUrlVarSelect}
19037
- onAddVariable={onAddVariable ? handleAddVariableClick : undefined}
19038
- onEditVariable={onEditVariable ? handleEditVariableClick : undefined}
19039
- style={urlPopupStyle}
19040
- />
18138
+ <VarPopup variables={filteredUrlVars} onSelect={handleUrlVarSelect} style={urlPopupStyle} />
19041
18139
  </div>
19042
18140
  </div>
19043
18141
  {urlError && (
19044
- <p className="m-0 text-sm text-semantic-error-primary">{urlError}</p>
18142
+ <p className="m-0 text-xs text-semantic-error-primary">{urlError}</p>
19045
18143
  )}
19046
18144
  </div>
19047
18145
 
@@ -19081,9 +18179,6 @@ export const CreateFunctionModal = React.forwardRef(
19081
18179
  keyRegex={HEADER_KEY_REGEX}
19082
18180
  keyRegexError="Invalid header key. Use only alphanumeric and !#$%&'*+-.^_\`|~ characters."
19083
18181
  sessionVariables={sessionVariables}
19084
- variableGroups={variableGroups}
19085
- onAddVariable={handleAddVariableClick}
19086
- onEditVariable={handleEditVariableClick}
19087
18182
  disabled={disabled}
19088
18183
  />
19089
18184
  )}
@@ -19103,15 +18198,12 @@ export const CreateFunctionModal = React.forwardRef(
19103
18198
  };
19104
18199
  }}
19105
18200
  sessionVariables={sessionVariables}
19106
- variableGroups={variableGroups}
19107
- onAddVariable={handleAddVariableClick}
19108
- onEditVariable={handleEditVariableClick}
19109
18201
  disabled={disabled}
19110
18202
  />
19111
18203
  )}
19112
18204
  {activeTab === "body" && (
19113
18205
  <div className="flex flex-col gap-1.5">
19114
- <span className="text-sm text-semantic-text-muted">
18206
+ <span className="text-xs text-semantic-text-muted">
19115
18207
  Body
19116
18208
  </span>
19117
18209
  <div className={cn("relative")}>
@@ -19141,21 +18233,13 @@ export const CreateFunctionModal = React.forwardRef(
19141
18233
  rows={6}
19142
18234
  className={cn(textareaCls, "pb-7")}
19143
18235
  />
19144
- <span className="absolute bottom-2 right-3 text-sm text-semantic-text-muted pointer-events-none">
18236
+ <span className="absolute bottom-2 right-3 text-xs italic text-semantic-text-muted pointer-events-none">
19145
18237
  {body.length}/{BODY_MAX}
19146
18238
  </span>
19147
- <VarPopup
19148
- variables={filteredBodyVars}
19149
- variableGroups={bodyTrigger ? variableGroups : undefined}
19150
- filterQuery={bodyTrigger?.query ?? ""}
19151
- onSelect={handleBodyVarSelect}
19152
- onAddVariable={onAddVariable ? handleAddVariableClick : undefined}
19153
- onEditVariable={onEditVariable ? handleEditVariableClick : undefined}
19154
- style={bodyPopupStyle}
19155
- />
18239
+ <VarPopup variables={filteredBodyVars} onSelect={handleBodyVarSelect} style={bodyPopupStyle} />
19156
18240
  </div>
19157
18241
  {bodyError && (
19158
- <p className="m-0 text-sm text-semantic-error-primary">{bodyError}</p>
18242
+ <p className="m-0 text-xs text-semantic-error-primary">{bodyError}</p>
19159
18243
  )}
19160
18244
  </div>
19161
18245
  )}
@@ -19164,7 +18248,7 @@ export const CreateFunctionModal = React.forwardRef(
19164
18248
  {/* Test Your API */}
19165
18249
  <div className="flex flex-col gap-4">
19166
18250
  <div className="flex flex-col gap-1.5">
19167
- <span className="text-sm font-semibold text-semantic-text-muted tracking-[0.048px]">
18251
+ <span className="text-xs font-semibold text-semantic-text-muted tracking-[0.048px]">
19168
18252
  Test Your API
19169
18253
  </span>
19170
18254
  <div className="border-t border-semantic-border-layout" />
@@ -19173,12 +18257,12 @@ export const CreateFunctionModal = React.forwardRef(
19173
18257
  {/* Variable test values \u2014 shown when URL/body/params contain {{variables}} */}
19174
18258
  {testableVars.length > 0 && (
19175
18259
  <div className="flex flex-col gap-2">
19176
- <span className="text-sm text-semantic-text-muted">
18260
+ <span className="text-xs text-semantic-text-muted">
19177
18261
  Variable values for testing
19178
18262
  </span>
19179
18263
  {testableVars.map((variable) => (
19180
18264
  <div key={variable} className="flex items-center gap-3">
19181
- <span className="text-sm text-semantic-text-muted font-mono shrink-0 min-w-[120px]">
18265
+ <span className="text-xs text-semantic-text-muted font-mono shrink-0 min-w-[120px]">
19182
18266
  {variable}
19183
18267
  </span>
19184
18268
  <input
@@ -19208,7 +18292,7 @@ export const CreateFunctionModal = React.forwardRef(
19208
18292
  </button>
19209
18293
 
19210
18294
  <div className="flex flex-col gap-1.5">
19211
- <span className="text-sm text-semantic-text-muted">
18295
+ <span className="text-xs text-semantic-text-muted">
19212
18296
  Response from API
19213
18297
  </span>
19214
18298
  <textarea
@@ -19266,15 +18350,6 @@ export const CreateFunctionModal = React.forwardRef(
19266
18350
  </div>
19267
18351
  </DialogContent>
19268
18352
  </Dialog>
19269
-
19270
- <VariableFormModal
19271
- open={varModalOpen}
19272
- onOpenChange={setVarModalOpen}
19273
- mode={varModalMode}
19274
- initialData={varModalInitialData}
19275
- onSave={handleVariableSave}
19276
- />
19277
- </>
19278
18353
  );
19279
18354
  }
19280
18355
  );
@@ -19486,7 +18561,7 @@ const DEFAULT_LANGUAGE_OPTIONS: LanguageOption[] = [
19486
18561
 
19487
18562
  // \u2500\u2500\u2500 Component \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
19488
18563
 
19489
- const BotIdentityCard = React.forwardRef(
18564
+ const BotIdentityCard = React.forwardRef<HTMLDivElement, BotIdentityCardProps>(
19490
18565
  (
19491
18566
  {
19492
18567
  data,
@@ -19500,8 +18575,8 @@ const BotIdentityCard = React.forwardRef(
19500
18575
  playingVoice,
19501
18576
  disabled,
19502
18577
  className,
19503
- }: BotIdentityCardProps,
19504
- ref: React.Ref<HTMLDivElement>
18578
+ },
18579
+ ref
19505
18580
  ) => {
19506
18581
  return (
19507
18582
  <div
@@ -19803,6 +18878,7 @@ function VarPopup({
19803
18878
  key={v}
19804
18879
  type="button"
19805
18880
  role="option"
18881
+ aria-selected={false}
19806
18882
  onMouseDown={(e) => {
19807
18883
  e.preventDefault(); // keep textarea focused so blur doesn't close popup first
19808
18884
  onSelect(v);
@@ -19846,7 +18922,7 @@ function SectionCard({
19846
18922
 
19847
18923
  // \u2500\u2500\u2500 Component \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
19848
18924
 
19849
- const BotBehaviorCard = React.forwardRef(
18925
+ const BotBehaviorCard = React.forwardRef<HTMLDivElement, BotBehaviorCardProps>(
19850
18926
  (
19851
18927
  {
19852
18928
  data,
@@ -19856,8 +18932,8 @@ const BotBehaviorCard = React.forwardRef(
19856
18932
  maxLength = 5000,
19857
18933
  disabled,
19858
18934
  className,
19859
- }: BotBehaviorCardProps,
19860
- ref: React.Ref<HTMLDivElement>
18935
+ },
18936
+ ref
19861
18937
  ) => {
19862
18938
  const prompt = data.systemPrompt ?? "";
19863
18939
  const MAX = maxLength;
@@ -20041,7 +19117,7 @@ import {
20041
19117
  TooltipTrigger,
20042
19118
  } from "../tooltip";
20043
19119
  import { BOT_KNOWLEDGE_STATUS } from "./types";
20044
- import type { KnowledgeBaseFile } from "./types";
19120
+ import type { KnowledgeBaseFile, KnowledgeFileStatus } from "./types";
20045
19121
 
20046
19122
  // \u2500\u2500\u2500 Types \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
20047
19123
 
@@ -20075,7 +19151,7 @@ export interface KnowledgeBaseCardProps {
20075
19151
  // \u2500\u2500\u2500 Status config \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
20076
19152
 
20077
19153
  type BadgeVariant = "default" | "active" | "destructive";
20078
- const STATUS_CONFIG: Record<BOT_KNOWLEDGE_STATUS, { label: string; variant: BadgeVariant }> = {
19154
+ const STATUS_CONFIG: Record<KnowledgeFileStatus, { label: string; variant: BadgeVariant }> = {
20079
19155
  [BOT_KNOWLEDGE_STATUS.PENDING]: { label: "Pending", variant: "default" },
20080
19156
  [BOT_KNOWLEDGE_STATUS.READY]: { label: "Ready", variant: "active" },
20081
19157
  [BOT_KNOWLEDGE_STATUS.PROCESSING]: { label: "Processing", variant: "active" },
@@ -20084,7 +19160,7 @@ const STATUS_CONFIG: Record<BOT_KNOWLEDGE_STATUS, { label: string; variant: Badg
20084
19160
 
20085
19161
  // \u2500\u2500\u2500 Component \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
20086
19162
 
20087
- const KnowledgeBaseCard = React.forwardRef(
19163
+ const KnowledgeBaseCard = React.forwardRef<HTMLDivElement, KnowledgeBaseCardProps>(
20088
19164
  (
20089
19165
  {
20090
19166
  files,
@@ -20096,8 +19172,8 @@ const KnowledgeBaseCard = React.forwardRef(
20096
19172
  downloadDisabled,
20097
19173
  deleteDisabled,
20098
19174
  className,
20099
- }: KnowledgeBaseCardProps,
20100
- ref: React.Ref<HTMLDivElement>
19175
+ },
19176
+ ref
20101
19177
  ) => {
20102
19178
  return (
20103
19179
  <div
@@ -20249,8 +19325,8 @@ export interface FunctionsCardProps {
20249
19325
 
20250
19326
  // \u2500\u2500\u2500 Component \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
20251
19327
 
20252
- const FunctionsCard = React.forwardRef(
20253
- ({ functions, onAddFunction, onEditFunction, onDeleteFunction, infoTooltip, disabled, editDisabled, deleteDisabled, className }: FunctionsCardProps, ref: React.Ref<HTMLDivElement>) => {
19328
+ const FunctionsCard = React.forwardRef<HTMLDivElement, FunctionsCardProps>(
19329
+ ({ functions, onAddFunction, onEditFunction, onDeleteFunction, infoTooltip, disabled, editDisabled, deleteDisabled, className }, ref) => {
20254
19330
  return (
20255
19331
  <div
20256
19332
  ref={ref}
@@ -20436,8 +19512,8 @@ function Field({
20436
19512
 
20437
19513
  // \u2500\u2500\u2500 Component \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
20438
19514
 
20439
- const FrustrationHandoverCard = React.forwardRef(
20440
- ({ data, onChange, departmentOptions = DEFAULT_DEPARTMENT_OPTIONS, disabled, className }: FrustrationHandoverCardProps, ref: React.Ref<HTMLDivElement>) => {
19515
+ const FrustrationHandoverCard = React.forwardRef<HTMLDivElement, FrustrationHandoverCardProps>(
19516
+ ({ data, onChange, departmentOptions = DEFAULT_DEPARTMENT_OPTIONS, disabled, className }, ref) => {
20441
19517
  return (
20442
19518
  <div
20443
19519
  ref={ref}
@@ -20610,7 +19686,7 @@ function NumberSpinner({
20610
19686
 
20611
19687
  // \u2500\u2500\u2500 Component \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
20612
19688
 
20613
- const AdvancedSettingsCard = React.forwardRef(
19689
+ const AdvancedSettingsCard = React.forwardRef<HTMLDivElement, AdvancedSettingsCardProps>(
20614
19690
  (
20615
19691
  {
20616
19692
  data,
@@ -20621,8 +19697,8 @@ const AdvancedSettingsCard = React.forwardRef(
20621
19697
  callEndThresholdMax = 10,
20622
19698
  disabled,
20623
19699
  className,
20624
- }: AdvancedSettingsCardProps,
20625
- ref: React.Ref<HTMLDivElement>
19700
+ },
19701
+ ref
20626
19702
  ) => {
20627
19703
  return (
20628
19704
  <div
@@ -20788,7 +19864,10 @@ function PromptField({
20788
19864
 
20789
19865
  // \u2500\u2500\u2500 Component \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
20790
19866
 
20791
- const FallbackPromptsCard = React.forwardRef(
19867
+ const FallbackPromptsCard = React.forwardRef<
19868
+ HTMLDivElement,
19869
+ FallbackPromptsCardProps
19870
+ >(
20792
19871
  (
20793
19872
  {
20794
19873
  data,
@@ -20799,8 +19878,8 @@ const FallbackPromptsCard = React.forwardRef(
20799
19878
  disabled,
20800
19879
  defaultOpen = false,
20801
19880
  className,
20802
- }: FallbackPromptsCardProps,
20803
- ref: React.Ref<HTMLDivElement>
19881
+ },
19882
+ ref
20804
19883
  ) => {
20805
19884
  return (
20806
19885
  <div
@@ -20871,9 +19950,7 @@ export const BOT_KNOWLEDGE_STATUS = {
20871
19950
  FAILED: "failed",
20872
19951
  } as const;
20873
19952
 
20874
- export type BOT_KNOWLEDGE_STATUS = typeof BOT_KNOWLEDGE_STATUS[keyof typeof BOT_KNOWLEDGE_STATUS];
20875
-
20876
- export type KnowledgeFileStatus = BOT_KNOWLEDGE_STATUS;
19953
+ export type KnowledgeFileStatus = typeof BOT_KNOWLEDGE_STATUS[keyof typeof BOT_KNOWLEDGE_STATUS];
20877
19954
 
20878
19955
  export interface KeyValuePair {
20879
19956
  id: string;
@@ -20881,35 +19958,6 @@ export interface KeyValuePair {
20881
19958
  value: string;
20882
19959
  }
20883
19960
 
20884
- /** A single variable shown in the {{ autocomplete popup */
20885
- export interface VariableItem {
20886
- /** Display name (e.g., "Order_id") */
20887
- name: string;
20888
- /** Value inserted into the input. Defaults to \`{{name}}\` if omitted */
20889
- value?: string;
20890
- /** When true, an edit icon is shown next to this variable */
20891
- editable?: boolean;
20892
- /** Description of what this variable represents */
20893
- description?: string;
20894
- /** Whether this variable is required */
20895
- required?: boolean;
20896
- }
20897
-
20898
- /** Data shape for creating or editing a variable */
20899
- export interface VariableFormData {
20900
- name: string;
20901
- description?: string;
20902
- required?: boolean;
20903
- }
20904
-
20905
- /** A labelled group of variables in the autocomplete popup */
20906
- export interface VariableGroup {
20907
- /** Group header text (e.g., "Function variables", "Session variables") */
20908
- label: string;
20909
- /** Variables in this group */
20910
- items: VariableItem[];
20911
- }
20912
-
20913
19961
  export interface FunctionItem {
20914
19962
  id: string;
20915
19963
  name: string;
@@ -20960,12 +20008,6 @@ export interface CreateFunctionModalProps {
20960
20008
  initialTab?: FunctionTabType;
20961
20009
  /** Session variables available for {{ autocomplete in URL, body, header values, and query param values */
20962
20010
  sessionVariables?: string[];
20963
- /** Grouped variables shown in the {{ autocomplete popup (overrides flat list display when provided) */
20964
- variableGroups?: VariableGroup[];
20965
- /** Called when user saves a new variable from the autocomplete popup */
20966
- onAddVariable?: (data: VariableFormData) => void;
20967
- /** Called when user edits a variable from the autocomplete popup */
20968
- onEditVariable?: (originalName: string, data: VariableFormData) => void;
20969
20011
  /** When true, all form fields are disabled (view mode) but Next is enabled so user can browse steps */
20970
20012
  disabled?: boolean;
20971
20013
  className?: string;
@@ -21126,9 +20168,6 @@ export type {
21126
20168
  HttpMethod,
21127
20169
  FunctionTabType,
21128
20170
  SelectOption,
21129
- VariableItem,
21130
- VariableGroup,
21131
- VariableFormData,
21132
20171
  } from "./types";
21133
20172
  `, prefix)
21134
20173
  }
@@ -21198,7 +20237,7 @@ function formatCurrency(amount: number, symbol: string = "\u20B9"): string {
21198
20237
  * />
21199
20238
  * \`\`\`
21200
20239
  */
21201
- export const WalletTopup = React.forwardRef(
20240
+ export const WalletTopup = React.forwardRef<HTMLDivElement, WalletTopupProps>(
21202
20241
  (
21203
20242
  {
21204
20243
  title = "Instant wallet top-up",
@@ -21245,8 +20284,8 @@ export const WalletTopup = React.forwardRef(
21245
20284
  open,
21246
20285
  onOpenChange,
21247
20286
  className,
21248
- }: WalletTopupProps,
21249
- ref: React.Ref<HTMLDivElement>
20287
+ },
20288
+ ref
21250
20289
  ) => {
21251
20290
  const isOpenControlled = open !== undefined;
21252
20291
 
@@ -23248,99 +22287,22 @@ async function sync(options) {
23248
22287
  }
23249
22288
  let selectedToAdd = toAdd;
23250
22289
  let selectedToUpdate = toUpdate;
23251
- const CUSTOM_GROUPS = {
23252
- "attachment-preview": "Chat",
23253
- "audio-media": "Chat",
23254
- "carousel-media": "Chat",
23255
- "chat-bubble": "Chat",
23256
- "chat-composer": "Chat",
23257
- "contact-list-item": "Chat",
23258
- "date-divider": "Chat",
23259
- "doc-media": "Chat",
23260
- "image-media": "Chat",
23261
- "reply-quote": "Chat",
23262
- "system-message": "Chat",
23263
- "unread-separator": "Chat",
23264
- "video-media": "Chat",
23265
- "event-selector": "Webhook",
23266
- "key-value-input": "Webhook",
23267
- "api-feature-card": "Webhook",
23268
- "endpoint-details": "Webhook",
23269
- "alert-configuration": "Webhook",
23270
- "auto-pay-setup": "Plan & Payment",
23271
- "bank-details": "Plan & Payment",
23272
- "date-range-modal": "Plan & Payment",
23273
- "payment-option-card": "Plan & Payment",
23274
- "plan-upgrade-modal": "Plan & Payment",
23275
- "plan-upgrade-summary-modal": "Plan & Payment",
23276
- "payment-summary": "Plan & Payment",
23277
- "let-us-drive-card": "Plan & Payment",
23278
- "power-up-card": "Plan & Payment",
23279
- "pricing-card": "Plan & Payment",
23280
- "pricing-page": "Plan & Payment",
23281
- "pricing-toggle": "Plan & Payment",
23282
- "talk-to-us-modal": "Plan & Payment",
23283
- "wallet-topup": "Plan & Payment",
23284
- "file-upload-modal": "Plan & Payment",
23285
- "plan-detail-modal": "Plan & Payment",
23286
- "bots": "AI Bot",
23287
- "ivr-bot": "AI Bot"
23288
- };
23289
22290
  if (!options.yes && toAdd.length > 0) {
23290
- const uiToAdd = toAdd.filter((c) => !CUSTOM_GROUPS[c]);
23291
- const customToAdd = toAdd.filter((c) => !!CUSTOM_GROUPS[c]);
23292
- const picked = [];
23293
- if (uiToAdd.length > 0) {
23294
- console.log(chalk5.cyan.bold(" \u2500\u2500 Components \u2500\u2500\n"));
23295
- const { selected } = await prompts3({
23296
- type: "multiselect",
23297
- name: "selected",
23298
- message: "Select new components to add",
23299
- choices: uiToAdd.map((c) => ({
23300
- title: c,
23301
- value: c,
23302
- selected: false
23303
- }))
23304
- });
23305
- if (!selected) {
23306
- console.log(chalk5.yellow("\n Sync cancelled.\n"));
23307
- process.exit(0);
23308
- }
23309
- picked.push(...selected);
23310
- }
23311
- if (customToAdd.length > 0) {
23312
- const grouped = /* @__PURE__ */ new Map();
23313
- for (const c of customToAdd) {
23314
- const group = CUSTOM_GROUPS[c] || "Other";
23315
- if (!grouped.has(group)) grouped.set(group, []);
23316
- grouped.get(group).push(c);
23317
- }
23318
- const sortedGroups = [...grouped.keys()].sort();
23319
- console.log(chalk5.cyan.bold("\n \u2500\u2500 Custom \u2500\u2500\n"));
23320
- const { selected } = await prompts3({
23321
- type: "multiselect",
23322
- name: "selected",
23323
- message: "Select custom component folders to add",
23324
- choices: sortedGroups.map((group) => {
23325
- const components = grouped.get(group);
23326
- const count = components.length;
23327
- return {
23328
- title: group,
23329
- value: group,
23330
- selected: false,
23331
- description: `${count} component${count === 1 ? "" : "s"}`
23332
- };
23333
- })
23334
- });
23335
- if (!selected) {
23336
- console.log(chalk5.yellow("\n Sync cancelled.\n"));
23337
- process.exit(0);
23338
- }
23339
- for (const group of selected) {
23340
- picked.push(...grouped.get(group));
23341
- }
22291
+ const { selected } = await prompts3({
22292
+ type: "multiselect",
22293
+ name: "selected",
22294
+ message: "Select new components to add",
22295
+ choices: toAdd.map((c) => {
22296
+ const comp = registry[c];
22297
+ const fileCount = comp.isMultiFile ? ` (${comp.files.length} files)` : "";
22298
+ return { title: `${c}${fileCount}`, value: c, selected: true };
22299
+ })
22300
+ });
22301
+ if (!selected) {
22302
+ console.log(chalk5.yellow("\n Sync cancelled.\n"));
22303
+ process.exit(0);
23342
22304
  }
23343
- selectedToAdd = picked;
22305
+ selectedToAdd = selected;
23344
22306
  }
23345
22307
  if (!options.yes && toUpdate.length > 0) {
23346
22308
  const { selected } = await prompts3({