@mlw-packages/react-components 1.10.18 → 1.10.20

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.
package/dist/index.js CHANGED
@@ -2590,10 +2590,10 @@ function Badge({
2590
2590
  purple: "bg-purple-50 text-purple-500 border-purple-200"
2591
2591
  };
2592
2592
  const rankClasses = {
2593
- diamond: "bg-cyan-100 text-cyan-600 border-cyan-300",
2594
- gold: "bg-yellow-100 text-yellow-500 border-yellow-300",
2595
- silver: "bg-gray-100 text-gray-500 border-gray-300",
2596
- bronze: "bg-orange-100 text-orange-700 border-orange-300"
2593
+ diamond: "bg-cyan-100 text-cyan-600 border-cyan-300 dark:text-cyan-800 dark:border-cyan-800",
2594
+ gold: "bg-amber-50 text-amber-500 border-amber-300 dark:text-amber-600 dark:border-amber-600 dark:bg-amber-50",
2595
+ silver: "bg-gray-100 text-gray-500 border-gray-300 dark:text-gray-800 dark:border-gray-800",
2596
+ bronze: "bg-orange-100 text-orange-700 border-orange-300 dark:text-orange-800 dark:border-orange-800"
2597
2597
  };
2598
2598
  return /* @__PURE__ */ jsxRuntime.jsx(
2599
2599
  Comp,
@@ -3858,7 +3858,7 @@ var FileUploader = React32__namespace.forwardRef(
3858
3858
  showPreview = true,
3859
3859
  dropzoneText = "Arraste arquivos aqui ou clique para selecionar",
3860
3860
  dropzoneSubtext,
3861
- animate: animate2 = true,
3861
+ animate: animate3 = true,
3862
3862
  ...props
3863
3863
  }, ref) => {
3864
3864
  const [isDragging, setIsDragging] = React32__namespace.useState(false);
@@ -4011,7 +4011,7 @@ var FileUploader = React32__namespace.forwardRef(
4011
4011
  framerMotion.motion.p,
4012
4012
  {
4013
4013
  className: "mb-2 text-xs font-semibold text-foreground",
4014
- initial: animate2 ? { opacity: 0, y: -10 } : false,
4014
+ initial: animate3 ? { opacity: 0, y: -10 } : false,
4015
4015
  animate: { opacity: 1, y: 0 },
4016
4016
  transition: { delay: 0.1 },
4017
4017
  children: dropzoneText
@@ -4021,7 +4021,7 @@ var FileUploader = React32__namespace.forwardRef(
4021
4021
  framerMotion.motion.p,
4022
4022
  {
4023
4023
  className: "text-xs text-muted-foreground",
4024
- initial: animate2 ? { opacity: 0, y: -10 } : false,
4024
+ initial: animate3 ? { opacity: 0, y: -10 } : false,
4025
4025
  animate: { opacity: 1, y: 0 },
4026
4026
  transition: { delay: 0.2 },
4027
4027
  children: defaultSubtext
@@ -4031,7 +4031,7 @@ var FileUploader = React32__namespace.forwardRef(
4031
4031
  framerMotion.motion.div,
4032
4032
  {
4033
4033
  className: "py-2 w-full",
4034
- initial: animate2 ? { opacity: 0, y: 10 } : false,
4034
+ initial: animate3 ? { opacity: 0, y: 10 } : false,
4035
4035
  animate: { opacity: 1, y: 0 },
4036
4036
  transition: { delay: 0.3 },
4037
4037
  children: [
@@ -4046,7 +4046,7 @@ var FileUploader = React32__namespace.forwardRef(
4046
4046
  framerMotion.motion.div,
4047
4047
  {
4048
4048
  layout: true,
4049
- initial: animate2 ? { opacity: 0, x: -20 } : false,
4049
+ initial: animate3 ? { opacity: 0, x: -20 } : false,
4050
4050
  animate: { opacity: 1, x: 0 },
4051
4051
  exit: {
4052
4052
  opacity: 0,
@@ -4054,7 +4054,7 @@ var FileUploader = React32__namespace.forwardRef(
4054
4054
  transition: { duration: 0.2 }
4055
4055
  },
4056
4056
  transition: {
4057
- delay: animate2 ? index * 0.05 : 0,
4057
+ delay: animate3 ? index * 0.05 : 0,
4058
4058
  layout: { duration: 0.2 }
4059
4059
  },
4060
4060
  className: cn(
@@ -10176,28 +10176,37 @@ function EventAgenda({
10176
10176
  initialDate,
10177
10177
  onClick,
10178
10178
  showYearView = false,
10179
- noTime = false
10179
+ noTime = false,
10180
+ onlyDay,
10181
+ onlyMonth,
10182
+ onlyWeek,
10183
+ onlyAgenda,
10184
+ onlyYear
10180
10185
  }) {
10186
+ const lockedView = onlyDay ? "day" : onlyMonth ? "month" : onlyWeek ? "week" : onlyAgenda ? "agenda" : onlyYear ? "year" : void 0;
10181
10187
  const [currentDate, setCurrentDate] = React32.useState(
10182
10188
  initialDate && new Date(initialDate) || /* @__PURE__ */ new Date()
10183
10189
  );
10184
- const [view, setView] = React32.useState(initialView);
10190
+ const [view, setView] = React32.useState(
10191
+ lockedView || initialView
10192
+ );
10185
10193
  const [selectedEvent, setSelectedEvent] = React32.useState(null);
10194
+ const activeView = lockedView || view;
10186
10195
  const goPrevious = () => {
10187
- if (view === "month") setCurrentDate((d) => dateFns.subMonths(d, 1));
10188
- else if (view === "week") setCurrentDate((d) => dateFns.subWeeks(d, 1));
10189
- else if (view === "day") setCurrentDate((d) => dateFns.addDays(d, -1));
10190
- else if (view === "agenda")
10196
+ if (activeView === "month") setCurrentDate((d) => dateFns.subMonths(d, 1));
10197
+ else if (activeView === "week") setCurrentDate((d) => dateFns.subWeeks(d, 1));
10198
+ else if (activeView === "day") setCurrentDate((d) => dateFns.addDays(d, -1));
10199
+ else if (activeView === "agenda")
10191
10200
  setCurrentDate((d) => dateFns.addDays(d, -AgendaDaysToShowAgenda));
10192
- else if (view === "year") setCurrentDate((d) => dateFns.subYears(d, 1));
10201
+ else if (activeView === "year") setCurrentDate((d) => dateFns.subYears(d, 1));
10193
10202
  };
10194
10203
  const goNext = () => {
10195
- if (view === "month") setCurrentDate((d) => dateFns.addMonths(d, 1));
10196
- else if (view === "week") setCurrentDate((d) => dateFns.addWeeks(d, 1));
10197
- else if (view === "day") setCurrentDate((d) => dateFns.addDays(d, 1));
10198
- else if (view === "agenda")
10204
+ if (activeView === "month") setCurrentDate((d) => dateFns.addMonths(d, 1));
10205
+ else if (activeView === "week") setCurrentDate((d) => dateFns.addWeeks(d, 1));
10206
+ else if (activeView === "day") setCurrentDate((d) => dateFns.addDays(d, 1));
10207
+ else if (activeView === "agenda")
10199
10208
  setCurrentDate((d) => dateFns.addDays(d, AgendaDaysToShowAgenda));
10200
- else if (view === "year") setCurrentDate((d) => dateFns.addYears(d, 1));
10209
+ else if (activeView === "year") setCurrentDate((d) => dateFns.addYears(d, 1));
10201
10210
  };
10202
10211
  const handleEventSelect = (event, e) => {
10203
10212
  try {
@@ -10243,9 +10252,9 @@ function EventAgenda({
10243
10252
  };
10244
10253
  const viewTitle = React32.useMemo(() => {
10245
10254
  const capitalize2 = (s) => s ? s.charAt(0).toUpperCase() + s.slice(1) : s;
10246
- if (view === "month")
10255
+ if (activeView === "month")
10247
10256
  return capitalize2(dateFns.format(currentDate, "MMMM yyyy", { locale: locale.ptBR }));
10248
- if (view === "week") {
10257
+ if (activeView === "week") {
10249
10258
  const start = dateFns.startOfWeek(currentDate, { weekStartsOn: 1 });
10250
10259
  const end = dateFns.endOfWeek(currentDate, { weekStartsOn: 1 });
10251
10260
  if (dateFns.isSameMonth(start, end))
@@ -10254,17 +10263,19 @@ function EventAgenda({
10254
10263
  const s2 = capitalize2(dateFns.format(end, "MMM yyyy", { locale: locale.ptBR }));
10255
10264
  return `${s1} - ${s2}`;
10256
10265
  }
10257
- if (view === "day")
10258
- return dateFns.format(currentDate, "d 'de' MMMM 'de' yyyy", { locale: locale.ptBR });
10259
- if (view === "agenda") {
10266
+ if (activeView === "day")
10267
+ return capitalize2(
10268
+ dateFns.format(currentDate, "EEEE, d 'de' MMMM", { locale: locale.ptBR })
10269
+ );
10270
+ if (activeView === "agenda") {
10260
10271
  const start = currentDate;
10261
10272
  return capitalize2(dateFns.format(start, "MMMM yyyy", { locale: locale.ptBR }));
10262
10273
  }
10263
- if (view === "year") {
10274
+ if (activeView === "year") {
10264
10275
  return dateFns.format(currentDate, "yyyy");
10265
10276
  }
10266
10277
  return capitalize2(dateFns.format(currentDate, "MMMM yyyy", { locale: locale.ptBR }));
10267
- }, [currentDate, view]);
10278
+ }, [currentDate, activeView]);
10268
10279
  const availableViews = showYearView ? ["year", "month", "week", "day", "agenda"] : ["month", "week", "day", "agenda"];
10269
10280
  const selectItems = availableViews.map(
10270
10281
  (v) => ({
@@ -10312,22 +10323,22 @@ function EventAgenda({
10312
10323
  ] }),
10313
10324
  /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "font-semibold text-sm sm:text-base md:text-lg lg:text-xl xl:text-2xl min-w-0 truncate sm:whitespace-normal", children: viewTitle })
10314
10325
  ] }),
10315
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsxRuntime.jsx(
10326
+ !lockedView && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsxRuntime.jsx(
10316
10327
  Select,
10317
10328
  {
10318
- selected: view,
10329
+ selected: activeView,
10319
10330
  onChange: (v) => {
10320
10331
  setView(v);
10321
10332
  },
10322
10333
  items: selectItems,
10323
- placeholder: viewLabel(view),
10334
+ placeholder: viewLabel(activeView),
10324
10335
  className: "min-w-24",
10325
10336
  hideClear: true
10326
10337
  }
10327
10338
  ) })
10328
10339
  ] }),
10329
10340
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col transition-all duration-200 ease-in-out", children: [
10330
- view === "month" && /* @__PURE__ */ jsxRuntime.jsx(
10341
+ activeView === "month" && /* @__PURE__ */ jsxRuntime.jsx(
10331
10342
  MonthViewAgenda,
10332
10343
  {
10333
10344
  currentDate,
@@ -10336,7 +10347,7 @@ function EventAgenda({
10336
10347
  noTime
10337
10348
  }
10338
10349
  ),
10339
- view === "week" && /* @__PURE__ */ jsxRuntime.jsx(
10350
+ activeView === "week" && /* @__PURE__ */ jsxRuntime.jsx(
10340
10351
  WeekViewAgenda,
10341
10352
  {
10342
10353
  currentDate,
@@ -10345,7 +10356,7 @@ function EventAgenda({
10345
10356
  noTime
10346
10357
  }
10347
10358
  ),
10348
- view === "day" && /* @__PURE__ */ jsxRuntime.jsx(
10359
+ activeView === "day" && /* @__PURE__ */ jsxRuntime.jsx(
10349
10360
  DayViewAgenda,
10350
10361
  {
10351
10362
  currentDate,
@@ -10354,7 +10365,7 @@ function EventAgenda({
10354
10365
  noTime
10355
10366
  }
10356
10367
  ),
10357
- view === "agenda" && /* @__PURE__ */ jsxRuntime.jsx(
10368
+ activeView === "agenda" && /* @__PURE__ */ jsxRuntime.jsx(
10358
10369
  Agenda,
10359
10370
  {
10360
10371
  currentDate,
@@ -10363,14 +10374,16 @@ function EventAgenda({
10363
10374
  noTime
10364
10375
  }
10365
10376
  ),
10366
- view === "year" && /* @__PURE__ */ jsxRuntime.jsx(
10377
+ activeView === "year" && /* @__PURE__ */ jsxRuntime.jsx(
10367
10378
  YearViewAgenda,
10368
10379
  {
10369
10380
  currentDate,
10370
10381
  events,
10371
10382
  onMonthSelect: (monthDate) => {
10372
10383
  setCurrentDate(monthDate);
10373
- setView("month");
10384
+ if (!lockedView) {
10385
+ setView("month");
10386
+ }
10374
10387
  }
10375
10388
  }
10376
10389
  )
@@ -16612,6 +16625,13 @@ var useIsTruncated = (ref) => {
16612
16625
  }, [ref]);
16613
16626
  return truncated;
16614
16627
  };
16628
+ var SNAP_HEIGHTS = {
16629
+ collapsed: "80px",
16630
+ peek: "42dvh",
16631
+ full: "85dvh"
16632
+ };
16633
+ var VELOCITY_THRESHOLD = 500;
16634
+ var CLOSE_THRESHOLD = 50;
16615
16635
  var CopyData = ({ value }) => {
16616
16636
  const [copied, setCopied] = React32.useState(false);
16617
16637
  const handleCopy = React32.useCallback(() => {
@@ -16645,26 +16665,56 @@ var propertyLabels = {
16645
16665
  Destino: "Destino",
16646
16666
  Origem: "Origem"
16647
16667
  };
16648
- var IntegrationCard = ({ title, details }) => {
16668
+ var LongPressTooltip = ({ content, isMobile, children }) => {
16669
+ const [open, setOpen] = React32.useState(false);
16670
+ const timerRef = React32.useRef(null);
16671
+ const handleTouchStart = React32.useCallback(() => {
16672
+ timerRef.current = setTimeout(() => setOpen(true), 1e3);
16673
+ }, []);
16674
+ const handleTouchEnd = React32.useCallback(() => {
16675
+ if (timerRef.current) clearTimeout(timerRef.current);
16676
+ setTimeout(() => setOpen(false), 1500);
16677
+ }, []);
16678
+ React32.useEffect(
16679
+ () => () => {
16680
+ if (timerRef.current) clearTimeout(timerRef.current);
16681
+ },
16682
+ []
16683
+ );
16684
+ return /* @__PURE__ */ jsxRuntime.jsx(TooltipProviderBase, { children: /* @__PURE__ */ jsxRuntime.jsxs(
16685
+ TooltipBase,
16686
+ {
16687
+ open: isMobile ? open : void 0,
16688
+ onOpenChange: isMobile ? setOpen : void 0,
16689
+ children: [
16690
+ /* @__PURE__ */ jsxRuntime.jsx(TooltipTriggerBase, { asChild: true, children: isMobile ? React32__namespace.default.cloneElement(children, {
16691
+ onTouchStart: handleTouchStart,
16692
+ onTouchEnd: handleTouchEnd,
16693
+ onTouchCancel: handleTouchEnd
16694
+ }) : children }),
16695
+ /* @__PURE__ */ jsxRuntime.jsx(TooltipContentBase, { sideOffset: 6, className: "z-[10001]", children: content })
16696
+ ]
16697
+ }
16698
+ ) });
16699
+ };
16700
+ var IntegrationCard = ({ title, details, isMobile }) => {
16649
16701
  const titleRef = React32.useRef(null);
16650
16702
  const isTitleTruncated = useIsTruncated(titleRef);
16651
16703
  const blackList = ["id", "elementId", "identity"];
16652
16704
  const entries = details ? Object.entries(details).filter(
16653
16705
  ([key, value]) => value !== void 0 && value !== null && value !== "" && !blackList.includes(key)
16654
16706
  ) : [];
16707
+ const titleSpan = /* @__PURE__ */ jsxRuntime.jsx(
16708
+ "span",
16709
+ {
16710
+ ref: titleRef,
16711
+ className: "text-sm font-bold text-foreground truncate flex-1 min-w-0 cursor-default",
16712
+ children: title
16713
+ }
16714
+ );
16655
16715
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-border/40 bg-muted/20 overflow-hidden", children: [
16656
16716
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 px-3 py-2 border-b border-border/30", children: [
16657
- /* @__PURE__ */ jsxRuntime.jsx(TooltipProviderBase, { children: /* @__PURE__ */ jsxRuntime.jsxs(TooltipBase, { children: [
16658
- /* @__PURE__ */ jsxRuntime.jsx(TooltipTriggerBase, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
16659
- "span",
16660
- {
16661
- ref: titleRef,
16662
- className: "text-sm font-bold text-foreground truncate flex-1 min-w-0 cursor-default",
16663
- children: title
16664
- }
16665
- ) }),
16666
- isTitleTruncated && /* @__PURE__ */ jsxRuntime.jsx(TooltipContentBase, { sideOffset: 6, className: "z-[10001]", children: title })
16667
- ] }) }),
16717
+ isTitleTruncated ? /* @__PURE__ */ jsxRuntime.jsx(LongPressTooltip, { content: title, isMobile, children: titleSpan }) : titleSpan,
16668
16718
  entries.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
16669
16719
  CopyData,
16670
16720
  {
@@ -16684,69 +16734,59 @@ var IntegrationCard = ({ title, details }) => {
16684
16734
  }) })
16685
16735
  ] });
16686
16736
  };
16687
- var Name = ({
16688
- name,
16689
- description
16690
- }) => {
16737
+ var Name = ({ name, description, isMobile }) => {
16691
16738
  const nameRef = React32.useRef(null);
16692
16739
  const descRef = React32.useRef(null);
16693
16740
  const isNameTruncated = useIsTruncated(nameRef);
16694
16741
  const isDescTruncated = useIsTruncated(descRef);
16695
16742
  const showTooltip = isNameTruncated || isDescTruncated;
16696
- return /* @__PURE__ */ jsxRuntime.jsx(TooltipProviderBase, { children: /* @__PURE__ */ jsxRuntime.jsxs(TooltipBase, { children: [
16697
- /* @__PURE__ */ jsxRuntime.jsx(TooltipTriggerBase, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "cursor-default min-w-0", children: [
16698
- /* @__PURE__ */ jsxRuntime.jsx(
16699
- "h3",
16700
- {
16701
- ref: nameRef,
16702
- className: "text-xl font-bold text-foreground tracking-tight truncate",
16703
- children: name
16704
- }
16705
- ),
16706
- description && /* @__PURE__ */ jsxRuntime.jsx(
16707
- "p",
16708
- {
16709
- ref: descRef,
16710
- className: "text-xs text-foreground/70 truncate mt-0.5",
16711
- children: description
16712
- }
16713
- )
16714
- ] }) }),
16715
- showTooltip && /* @__PURE__ */ jsxRuntime.jsxs(TooltipContentBase, { sideOffset: 8, className: "z-[10001]", children: [
16716
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-semibold", children: name }),
16717
- description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-foreground/70 mt-0.5", children: description })
16718
- ] })
16719
- ] }) });
16743
+ const content = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "cursor-default min-w-0", children: [
16744
+ /* @__PURE__ */ jsxRuntime.jsx(
16745
+ "h3",
16746
+ {
16747
+ ref: nameRef,
16748
+ className: "text-xl font-bold text-foreground tracking-tight truncate",
16749
+ children: name
16750
+ }
16751
+ ),
16752
+ description && /* @__PURE__ */ jsxRuntime.jsx("p", { ref: descRef, className: "text-xs text-foreground/70 truncate mt-0.5", children: description })
16753
+ ] });
16754
+ if (!showTooltip) return content;
16755
+ return /* @__PURE__ */ jsxRuntime.jsx(
16756
+ LongPressTooltip,
16757
+ {
16758
+ content: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
16759
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-semibold", children: name }),
16760
+ description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-foreground/70 mt-0.5", children: description })
16761
+ ] }),
16762
+ isMobile,
16763
+ children: content
16764
+ }
16765
+ );
16720
16766
  };
16721
- var SystemNode = React32__namespace.default.forwardRef(
16722
- ({ label }, ref) => {
16723
- const innerRef = React32.useRef(null);
16724
- const truncated = label.length > 9 ? label.substring(0, 9) + "\u2026" : label;
16725
- const needsTooltip = label.length > 9;
16726
- const setRefs = React32.useCallback(
16727
- (node) => {
16728
- innerRef.current = node;
16729
- if (typeof ref === "function") ref(node);
16730
- else if (ref)
16731
- ref.current = node;
16732
- },
16733
- [ref]
16734
- );
16735
- const circle = /* @__PURE__ */ jsxRuntime.jsx(
16767
+ function SystemNodeInner({ label, isMobile }, ref) {
16768
+ const truncated = label.length > 9 ? label.substring(0, 9) + "\u2026" : label;
16769
+ const needsTooltip = label.length > 9;
16770
+ if (!needsTooltip) {
16771
+ return /* @__PURE__ */ jsxRuntime.jsx(
16736
16772
  "div",
16737
16773
  {
16738
- ref: setRefs,
16774
+ ref,
16739
16775
  className: "w-[76px] h-[76px] rounded-full bg-primary flex items-center justify-center shrink-0 z-10 cursor-default",
16740
16776
  children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-bold text-primary-foreground text-center px-2 leading-tight select-none", children: truncated })
16741
16777
  }
16742
16778
  );
16743
- if (!needsTooltip) return circle;
16744
- return /* @__PURE__ */ jsxRuntime.jsx(TooltipProviderBase, { children: /* @__PURE__ */ jsxRuntime.jsxs(TooltipBase, { children: [
16745
- /* @__PURE__ */ jsxRuntime.jsx(TooltipTriggerBase, { asChild: true, children: circle }),
16746
- /* @__PURE__ */ jsxRuntime.jsx(TooltipContentBase, { sideOffset: 8, className: "z-[10001]", children: label })
16747
- ] }) });
16748
16779
  }
16749
- );
16780
+ return /* @__PURE__ */ jsxRuntime.jsx(LongPressTooltip, { content: label, isMobile, children: /* @__PURE__ */ jsxRuntime.jsx(
16781
+ "div",
16782
+ {
16783
+ ref,
16784
+ className: "w-[76px] h-[76px] rounded-full bg-primary flex items-center justify-center shrink-0 z-10 cursor-default",
16785
+ children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-bold text-primary-foreground text-center px-2 leading-tight select-none", children: truncated })
16786
+ }
16787
+ ) });
16788
+ }
16789
+ var SystemNode = React32__namespace.default.forwardRef(SystemNodeInner);
16750
16790
  SystemNode.displayName = "SystemNode";
16751
16791
  var Beam = ({ isInput, containerRef, leftRef, rightRef }) => {
16752
16792
  const gradientId = React32.useId();
@@ -16754,6 +16794,7 @@ var Beam = ({ isInput, containerRef, leftRef, rightRef }) => {
16754
16794
  const [svgSize, setSvgSize] = React32.useState({ w: 0, h: 0 });
16755
16795
  React32.useEffect(() => {
16756
16796
  let rafId;
16797
+ let running = true;
16757
16798
  const update = () => {
16758
16799
  const container = containerRef.current;
16759
16800
  const left = leftRef.current;
@@ -16766,39 +16807,31 @@ var Beam = ({ isInput, containerRef, leftRef, rightRef }) => {
16766
16807
  const cy1 = lr.top - cr.top + lr.height / 2;
16767
16808
  const cx2 = rr.left - cr.left + rr.width / 2;
16768
16809
  const cy2 = rr.top - cr.top + rr.height / 2;
16769
- const dx = cx2 - cx1, dy = cy2 - cy1;
16810
+ const dx = cx2 - cx1;
16811
+ const dy = cy2 - cy1;
16770
16812
  const dist = Math.sqrt(dx * dx + dy * dy);
16771
16813
  if (dist === 0) return;
16772
- const ux = dx / dist, uy = dy / dist;
16814
+ const ux = dx / dist;
16815
+ const uy = dy / dist;
16773
16816
  const r1 = lr.width / 2;
16774
16817
  const r2 = rr.width / 2;
16775
- setSvgSize({ w: cr.width, h: cr.height });
16776
- setPathD(
16777
- `M ${cx1 + ux * r1},${cy1 + uy * r1} L ${cx2 - ux * r2},${cy2 - uy * r2}`
16818
+ const newW = cr.width;
16819
+ const newH = cr.height;
16820
+ const newPath = `M ${cx1 + ux * r1},${cy1 + uy * r1} L ${cx2 - ux * r2},${cy2 - uy * r2}`;
16821
+ setSvgSize(
16822
+ (prev) => prev.w !== newW || prev.h !== newH ? { w: newW, h: newH } : prev
16778
16823
  );
16824
+ setPathD((prev) => prev !== newPath ? newPath : prev);
16779
16825
  };
16780
- const schedule = () => {
16781
- cancelAnimationFrame(rafId);
16782
- rafId = requestAnimationFrame(update);
16826
+ const loop = () => {
16827
+ if (!running) return;
16828
+ update();
16829
+ rafId = requestAnimationFrame(loop);
16783
16830
  };
16784
- requestAnimationFrame(() => requestAnimationFrame(update));
16785
- schedule();
16786
- const ro = new ResizeObserver(schedule);
16787
- if (containerRef.current) ro.observe(containerRef.current);
16788
- if (leftRef.current) ro.observe(leftRef.current);
16789
- if (rightRef.current) ro.observe(rightRef.current);
16790
- const mo = new MutationObserver(schedule);
16791
- if (containerRef.current) {
16792
- mo.observe(containerRef.current, {
16793
- attributes: true,
16794
- attributeFilter: ["class", "style"],
16795
- subtree: true
16796
- });
16797
- }
16831
+ rafId = requestAnimationFrame(loop);
16798
16832
  return () => {
16833
+ running = false;
16799
16834
  cancelAnimationFrame(rafId);
16800
- ro.disconnect();
16801
- mo.disconnect();
16802
16835
  };
16803
16836
  }, [containerRef, leftRef, rightRef]);
16804
16837
  const animX1 = isInput ? ["90%", "-10%"] : ["10%", "110%"];
@@ -16864,7 +16897,7 @@ var Beam = ({ isInput, containerRef, leftRef, rightRef }) => {
16864
16897
  }
16865
16898
  );
16866
16899
  };
16867
- var SystemsDiagram = ({ isInput, currentSystem, externalSystem }) => {
16900
+ var SystemsDiagram = ({ isInput, currentSystem, externalSystem, isMobile }) => {
16868
16901
  const containerRef = React32.useRef(null);
16869
16902
  const leftRef = React32.useRef(null);
16870
16903
  const rightRef = React32.useRef(null);
@@ -16878,14 +16911,16 @@ var SystemsDiagram = ({ isInput, currentSystem, externalSystem }) => {
16878
16911
  SystemNode,
16879
16912
  {
16880
16913
  ref: leftRef,
16881
- label: isInput ? externalSystem : currentSystem
16914
+ label: isInput ? externalSystem : currentSystem,
16915
+ isMobile
16882
16916
  }
16883
16917
  ),
16884
16918
  /* @__PURE__ */ jsxRuntime.jsx(
16885
16919
  SystemNode,
16886
16920
  {
16887
16921
  ref: rightRef,
16888
- label: isInput ? currentSystem : externalSystem
16922
+ label: isInput ? currentSystem : externalSystem,
16923
+ isMobile
16889
16924
  }
16890
16925
  ),
16891
16926
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -16901,47 +16936,84 @@ var SystemsDiagram = ({ isInput, currentSystem, externalSystem }) => {
16901
16936
  }
16902
16937
  );
16903
16938
  };
16904
- var BodyComponent = ({ data, isLoading, connections, isInput, externalSystem }) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-3 py-3 space-y-3 max-h-[460px] overflow-y-auto [&::-webkit-scrollbar]:w-1 [&::-webkit-scrollbar-track]:bg-transparent [&::-webkit-scrollbar-thumb]:bg-muted-foreground/20 [&::-webkit-scrollbar-thumb]:rounded-full hover:[&::-webkit-scrollbar-thumb]:bg-muted-foreground/40 transition-colors", children: [
16905
- isLoading ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
16906
- /* @__PURE__ */ jsxRuntime.jsx(SkeletonBase, { className: "h-6 w-3/4" }),
16907
- /* @__PURE__ */ jsxRuntime.jsx(SkeletonBase, { className: "h-3.5 w-1/2" })
16908
- ] }) : /* @__PURE__ */ jsxRuntime.jsx(Name, { name: data.name, description: data.description }),
16909
- isLoading ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
16910
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between py-1", children: [
16911
- /* @__PURE__ */ jsxRuntime.jsx(SkeletonBase, { className: "w-[76px] h-[76px] rounded-full" }),
16912
- /* @__PURE__ */ jsxRuntime.jsx(SkeletonBase, { className: "w-[76px] h-[76px] rounded-full" })
16913
- ] }),
16914
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-t border-border/20" }),
16915
- [1, 2].map((i) => /* @__PURE__ */ jsxRuntime.jsxs(
16916
- "div",
16917
- {
16918
- className: "rounded-lg border border-border/20 overflow-hidden",
16919
- children: [
16920
- /* @__PURE__ */ jsxRuntime.jsx(SkeletonBase, { className: "h-8 w-full" }),
16921
- [1, 2, 3].map((j) => /* @__PURE__ */ jsxRuntime.jsx(SkeletonBase, { className: "h-7 w-full mt-px" }, j))
16922
- ]
16939
+ var BodyComponent = ({
16940
+ data,
16941
+ isLoading,
16942
+ connections,
16943
+ isInput,
16944
+ externalSystem,
16945
+ isMobile,
16946
+ scrollable
16947
+ }) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative min-h-0 flex-1 overflow-hidden", children: [
16948
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute top-0 left-0 right-0 h-5 bg-gradient-to-b from-card to-transparent z-10 pointer-events-none" }),
16949
+ /* @__PURE__ */ jsxRuntime.jsxs(
16950
+ "div",
16951
+ {
16952
+ className: [
16953
+ "px-3 py-3 space-y-3",
16954
+ scrollable ? "overflow-y-auto overscroll-contain [&::-webkit-scrollbar]:w-1 [&::-webkit-scrollbar-track]:bg-transparent [&::-webkit-scrollbar-thumb]:bg-primary/20 [&::-webkit-scrollbar-thumb]:rounded-full" : "overflow-hidden",
16955
+ isMobile ? "max-h-[calc(85dvh-80px)]" : "max-h [&::-webkit-scrollbar]:hidden"
16956
+ ].join(" "),
16957
+ onPointerDownCapture: (e) => {
16958
+ if (scrollable) e.stopPropagation();
16923
16959
  },
16924
- i
16925
- ))
16926
- ] }) : connections.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground text-center", children: "Nenhuma conex\xE3o encontrada" }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
16927
- /* @__PURE__ */ jsxRuntime.jsx(
16928
- SystemsDiagram,
16929
- {
16930
- isInput,
16931
- currentSystem: data.name,
16932
- externalSystem
16933
- }
16934
- ),
16935
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-bold text-muted-foreground uppercase -mb-2", children: isInput ? "Informa\xE7\xF5es de Entrada" : "Informa\xE7\xF5es de Sa\xEDda" }) }),
16936
- /* @__PURE__ */ jsxRuntime.jsx("div", { children: connections.map((conn) => /* @__PURE__ */ jsxRuntime.jsx(
16937
- IntegrationCard,
16938
- {
16939
- title: conn.name,
16940
- details: conn.integration
16960
+ onTouchStartCapture: (e) => {
16961
+ if (scrollable) e.stopPropagation();
16941
16962
  },
16942
- conn.id
16943
- )) })
16944
- ] })
16963
+ children: [
16964
+ isLoading ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
16965
+ /* @__PURE__ */ jsxRuntime.jsx(SkeletonBase, { className: "h-6 w-3/4" }),
16966
+ /* @__PURE__ */ jsxRuntime.jsx(SkeletonBase, { className: "h-3.5 w-1/2" })
16967
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx(
16968
+ Name,
16969
+ {
16970
+ name: data.name,
16971
+ description: data.description,
16972
+ isMobile
16973
+ }
16974
+ ),
16975
+ isLoading ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
16976
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between py-1", children: [
16977
+ /* @__PURE__ */ jsxRuntime.jsx(SkeletonBase, { className: "w-[76px] h-[76px] rounded-full" }),
16978
+ /* @__PURE__ */ jsxRuntime.jsx(SkeletonBase, { className: "w-[76px] h-[76px] rounded-full" })
16979
+ ] }),
16980
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-t border-border/20" }),
16981
+ [1, 2].map((i) => /* @__PURE__ */ jsxRuntime.jsxs(
16982
+ "div",
16983
+ {
16984
+ className: "rounded-lg border border-border/20 overflow-hidden",
16985
+ children: [
16986
+ /* @__PURE__ */ jsxRuntime.jsx(SkeletonBase, { className: "h-8 w-full" }),
16987
+ [1, 2, 3].map((j) => /* @__PURE__ */ jsxRuntime.jsx(SkeletonBase, { className: "h-7 w-full mt-px" }, j))
16988
+ ]
16989
+ },
16990
+ i
16991
+ ))
16992
+ ] }) : connections.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground text-center", children: "Nenhuma conex\xE3o encontrada" }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
16993
+ /* @__PURE__ */ jsxRuntime.jsx(
16994
+ SystemsDiagram,
16995
+ {
16996
+ isInput,
16997
+ currentSystem: data.name,
16998
+ externalSystem,
16999
+ isMobile
17000
+ }
17001
+ ),
17002
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-bold text-muted-foreground uppercase -mb-2", children: isInput ? "Informa\xE7\xF5es de Entrada" : "Informa\xE7\xF5es de Sa\xEDda" }) }),
17003
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-2", children: connections.map((conn) => /* @__PURE__ */ jsxRuntime.jsx(
17004
+ IntegrationCard,
17005
+ {
17006
+ title: conn.name,
17007
+ details: conn.integration,
17008
+ isMobile
17009
+ },
17010
+ conn.id
17011
+ )) })
17012
+ ] })
17013
+ ]
17014
+ }
17015
+ ),
17016
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute bottom-0 left-0 right-0 h-5 bg-gradient-to-t from-card to-transparent z-10 pointer-events-none" })
16945
17017
  ] });
16946
17018
  var Body = React32__namespace.default.memo(BodyComponent);
16947
17019
  var modalVariants = {
@@ -16961,6 +17033,25 @@ var modalVariants = {
16961
17033
  transition: { type: "spring", stiffness: 400, damping: 28 }
16962
17034
  }
16963
17035
  };
17036
+ function resolveSnapPx(snap) {
17037
+ const vh = typeof window !== "undefined" ? window.innerHeight : 800;
17038
+ if (snap === "collapsed") return 80;
17039
+ if (snap === "peek") return vh * 0.42;
17040
+ return vh * 0.85;
17041
+ }
17042
+ function nearestSnap(heightPx) {
17043
+ const snaps = ["collapsed", "peek", "full"];
17044
+ let best = "peek";
17045
+ let bestDist = Infinity;
17046
+ for (const s of snaps) {
17047
+ const dist = Math.abs(resolveSnapPx(s) - heightPx);
17048
+ if (dist < bestDist) {
17049
+ bestDist = dist;
17050
+ best = s;
17051
+ }
17052
+ }
17053
+ return best;
17054
+ }
16964
17055
  var IntegrationModal = ({
16965
17056
  id,
16966
17057
  data,
@@ -17055,6 +17146,66 @@ var IntegrationModal = ({
17055
17146
  },
17056
17147
  [id, onMouseDown]
17057
17148
  );
17149
+ const [snap, setSnap] = React32.useState("peek");
17150
+ const sheetHeight = framerMotion.useMotionValue(SNAP_HEIGHTS.peek);
17151
+ const snapTo = React32.useCallback(
17152
+ (target) => {
17153
+ setSnap(target);
17154
+ framerMotion.animate(sheetHeight, SNAP_HEIGHTS[target], {
17155
+ type: "spring",
17156
+ stiffness: 320,
17157
+ damping: 36
17158
+ });
17159
+ },
17160
+ [sheetHeight]
17161
+ );
17162
+ React32.useEffect(() => {
17163
+ if (isMobile) {
17164
+ sheetHeight.set("0px");
17165
+ framerMotion.animate(sheetHeight, SNAP_HEIGHTS.peek, {
17166
+ type: "spring",
17167
+ stiffness: 320,
17168
+ damping: 36
17169
+ });
17170
+ }
17171
+ }, [isMobile, sheetHeight]);
17172
+ const handleDragEnd = React32.useCallback(
17173
+ (_, info) => {
17174
+ const vy = info.velocity.y;
17175
+ const dy = info.offset.y;
17176
+ const currentHeightStr = sheetHeight.get();
17177
+ const currentHeightPx = typeof currentHeightStr === "string" && currentHeightStr.endsWith("dvh") ? parseFloat(currentHeightStr) / 100 * window.innerHeight : parseFloat(currentHeightStr);
17178
+ const draggedHeightPx = currentHeightPx - dy;
17179
+ const collapsedPx = resolveSnapPx("collapsed");
17180
+ if (draggedHeightPx < collapsedPx - CLOSE_THRESHOLD || snap === "collapsed" && vy > VELOCITY_THRESHOLD) {
17181
+ onClose(id);
17182
+ return;
17183
+ }
17184
+ if (vy < -VELOCITY_THRESHOLD) {
17185
+ if (snap === "collapsed") {
17186
+ snapTo("peek");
17187
+ return;
17188
+ }
17189
+ if (snap === "peek") {
17190
+ snapTo("full");
17191
+ return;
17192
+ }
17193
+ }
17194
+ if (vy > VELOCITY_THRESHOLD) {
17195
+ if (snap === "full") {
17196
+ snapTo("peek");
17197
+ return;
17198
+ }
17199
+ if (snap === "peek") {
17200
+ snapTo("collapsed");
17201
+ return;
17202
+ }
17203
+ }
17204
+ const nearest = nearestSnap(draggedHeightPx);
17205
+ snapTo(nearest);
17206
+ },
17207
+ [id, onClose, snap, snapTo, sheetHeight]
17208
+ );
17058
17209
  const inputConnections = React32.useMemo(
17059
17210
  () => data.connections.filter((c) => c.type === "entrada"),
17060
17211
  [data.connections]
@@ -17069,19 +17220,19 @@ var IntegrationModal = ({
17069
17220
  const header = /* @__PURE__ */ jsxRuntime.jsxs(
17070
17221
  "div",
17071
17222
  {
17072
- className: "flex items-center justify-between py-1 border-b border-border shrink-0 max-w-lg",
17073
- onMouseDown: handleMouseDownLocal,
17074
- onTouchStart: handleTouchStartLocal,
17223
+ className: "flex items-center justify-between py-1 border-b border-border shrink-0",
17224
+ onMouseDown: !isMobile ? handleMouseDownLocal : void 0,
17225
+ onTouchStart: !isMobile ? handleTouchStartLocal : void 0,
17075
17226
  style: {
17076
- touchAction: "none",
17077
- cursor: dragging ? "grabbing" : "grab"
17227
+ touchAction: isMobile ? "auto" : "none",
17228
+ cursor: isMobile ? "default" : dragging ? "grabbing" : "grab"
17078
17229
  },
17079
17230
  children: [
17080
17231
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 px-3", children: [
17081
- /* @__PURE__ */ jsxRuntime.jsx(react.DotsSixVerticalIcon, { size: 16, className: "text-primary" }),
17232
+ !isMobile && /* @__PURE__ */ jsxRuntime.jsx(react.DotsSixVerticalIcon, { size: 16, className: "text-primary" }),
17082
17233
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-semibold text-muted-foreground uppercase tracking-wider", children: title })
17083
17234
  ] }),
17084
- /* @__PURE__ */ jsxRuntime.jsx(
17235
+ !isMobile && /* @__PURE__ */ jsxRuntime.jsx(
17085
17236
  ButtonBase,
17086
17237
  {
17087
17238
  variant: "ghost",
@@ -17095,7 +17246,15 @@ var IntegrationModal = ({
17095
17246
  ]
17096
17247
  }
17097
17248
  );
17098
- const bodyProps = { data, isLoading, connections, isInput, externalSystem };
17249
+ const bodyProps = {
17250
+ data,
17251
+ isLoading,
17252
+ connections,
17253
+ isInput,
17254
+ externalSystem,
17255
+ isMobile,
17256
+ scrollable: isMobile ? snap === "full" : true
17257
+ };
17099
17258
  if (isMobile) {
17100
17259
  return /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
17101
17260
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -17112,17 +17271,42 @@ var IntegrationModal = ({
17112
17271
  /* @__PURE__ */ jsxRuntime.jsxs(
17113
17272
  framerMotion.motion.div,
17114
17273
  {
17115
- className: "fixed bottom-0 left-0 right-0 z-[10000] bg-card border-t border-border/50 rounded-t-2xl shadow-2xl flex flex-col min-h-0",
17116
- style: { maxHeight: "85dvh" },
17117
- initial: { y: "100%" },
17118
- animate: { y: 0 },
17119
- exit: { y: "100%" },
17120
- transition: { type: "spring", stiffness: 320, damping: 36 },
17274
+ className: [
17275
+ "fixed bottom-0 left-0 right-0 z-[10000] bg-card border-t border-border/50 shadow-2xl flex flex-col",
17276
+ snap === "full" ? "rounded-t-[10px]" : "rounded-t-2xl"
17277
+ ].join(" "),
17278
+ style: {
17279
+ height: sheetHeight,
17280
+ touchAction: "none",
17281
+ overscrollBehavior: "none",
17282
+ boxShadow: snap === "full" ? "0 -8px 40px 0 rgba(0,0,0,0.32), 0 -1px 0 0 hsl(var(--border))" : void 0
17283
+ },
17284
+ drag: "y",
17285
+ dragConstraints: { top: 0, bottom: 0 },
17286
+ dragElastic: { top: 0.05, bottom: 0.25 },
17287
+ dragMomentum: false,
17288
+ onDragEnd: handleDragEnd,
17289
+ exit: { height: 0, opacity: 0, transition: { duration: 0.25 } },
17121
17290
  onClick: (e) => e.stopPropagation(),
17122
17291
  children: [
17123
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center pt-2.5 pb-1 shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-10 h-1 rounded-full bg-border" }) }),
17292
+ snap !== "full" && /* @__PURE__ */ jsxRuntime.jsx(
17293
+ "div",
17294
+ {
17295
+ className: "flex justify-center pt-3 pb-1 shrink-0 touch-none",
17296
+ style: { touchAction: "none" },
17297
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-10 h-1 rounded-full bg-muted-foreground/30" })
17298
+ }
17299
+ ),
17300
+ snap === "full" && /* @__PURE__ */ jsxRuntime.jsx(
17301
+ "div",
17302
+ {
17303
+ className: "flex items-center justify-between px-4 pt-3 pb-2 shrink-0 touch-none",
17304
+ style: { touchAction: "none" },
17305
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-10 h-1 rounded-full bg-muted-foreground/30 mx-auto" })
17306
+ }
17307
+ ),
17124
17308
  header,
17125
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 min-h-0 overflow-y-auto [&::-webkit-scrollbar]:w-1 [&::-webkit-scrollbar-track]:bg-transparent [&::-webkit-scrollbar-thumb]:bg-muted-foreground/20 [&::-webkit-scrollbar-thumb]:rounded-full hover:[&::-webkit-scrollbar-thumb]:bg-muted-foreground/40 transition-colors", children: /* @__PURE__ */ jsxRuntime.jsx(Body, { ...bodyProps }) })
17309
+ /* @__PURE__ */ jsxRuntime.jsx(Body, { ...bodyProps })
17126
17310
  ]
17127
17311
  },
17128
17312
  `sheet-${id}`