@mlw-packages/react-components 1.9.14 → 1.9.16

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
@@ -1214,6 +1214,8 @@ var Toaster = ({ testId, ...props }) => {
1214
1214
  className: "toaster group",
1215
1215
  position: "top-center",
1216
1216
  duration: 4e3,
1217
+ swipeDirections: ["top", "bottom", "left", "right"],
1218
+ closeButton: true,
1217
1219
  toastOptions: {
1218
1220
  style: {
1219
1221
  backdropFilter: "blur(8px)",
@@ -1227,9 +1229,8 @@ var Toaster = ({ testId, ...props }) => {
1227
1229
  shadow-xl rounded-lg
1228
1230
  border-l-4
1229
1231
 
1230
- flex items-center gap-3
1232
+ flex items-center gap-3 pr-10
1231
1233
  transition-all duration-300
1232
- hover:scale-[1.02] hover:shadow-2xl
1233
1234
  data-[type=success]:border-l-green-500 data-[type=success]:bg-green-50/95 data-[type=success]:text-green-800 data-[type=success]:border-green-500 data-
1234
1235
  data-[type=error]:border-l-red-500 data-[type=error]:bg-red-50/95 data-[type=error]:text-red-800 data-[type=error]:border-red-500
1235
1236
  data-[type=warning]:border-l-yellow-500 data-[type=warning]:bg-yellow-50/95 data-[type=warning]:text-yellow-800 data-[type=warning]:border-yellow-500
@@ -1255,6 +1256,13 @@ var Toaster = ({ testId, ...props }) => {
1255
1256
  hover:bg-neutral-200 hover:scale-105
1256
1257
  transition-all duration-200
1257
1258
  active:scale-95
1259
+ `,
1260
+ closeButton: `
1261
+ !bg-transparent hover:!bg-black/5 dark:hover:!bg-white/10
1262
+ !border-0 !text-neutral-400 hover:!text-neutral-900 dark:hover:!text-neutral-100
1263
+ transition-all duration-200 !left-[auto] !right-3 !top-1/2 !-translate-y-1/2
1264
+ !w-7 !h-7 !rounded-lg flex items-center justify-center
1265
+ active:scale-95
1258
1266
  `
1259
1267
  }
1260
1268
  },
@@ -2050,7 +2058,7 @@ var CommandDebouncedInputBase = React32__namespace.forwardRef(
2050
2058
  }, ref) => /* @__PURE__ */ jsxRuntime.jsxs(
2051
2059
  "div",
2052
2060
  {
2053
- className: "flex items-center px-3 border-border border-b",
2061
+ className: "flex items-center px-3 border-border border-b focus:ring-0",
2054
2062
  "cmdk-input-wrapper": "",
2055
2063
  children: [
2056
2064
  /* @__PURE__ */ jsxRuntime.jsx(react.MagnifyingGlassIcon, { className: "mr-2 h-4 w-4 shrink-0 text-primary" }),
@@ -19336,6 +19344,12 @@ function useMediaQuery(query) {
19336
19344
  }, [query]);
19337
19345
  return value;
19338
19346
  }
19347
+ var CRUD_ITEMS = [
19348
+ { id: "edit", label: "Editar", icon: react.PencilIcon },
19349
+ { id: "copy", label: "Copiar", icon: react.CopyIcon },
19350
+ { id: "download", label: "Baixar", icon: react.DownloadIcon },
19351
+ { id: "delete", label: "Excluir", icon: react.TrashIcon, color: "danger" }
19352
+ ];
19339
19353
  var FULL_CIRCLE = 360;
19340
19354
  var START_ANGLE = -90;
19341
19355
  function degToRad(deg) {
@@ -19361,7 +19375,7 @@ function slicePath(index, total, wedgeRadius, innerRadius) {
19361
19375
  }
19362
19376
  function RadialMenu({
19363
19377
  children,
19364
- menuItems,
19378
+ menuItems = CRUD_ITEMS,
19365
19379
  size = 240,
19366
19380
  iconSize = 24,
19367
19381
  bandWidth = 60,
@@ -19372,44 +19386,13 @@ function RadialMenu({
19372
19386
  }) {
19373
19387
  const isMobile = useMediaQuery("(max-width: 768px)");
19374
19388
  const radius = size / 2;
19375
- const outerRingOuterRadius = radius;
19376
- const outerRingInnerRadius = outerRingOuterRadius - outerRingWidth;
19389
+ const outerRingInnerRadius = radius - outerRingWidth;
19377
19390
  const wedgeOuterRadius = outerRingInnerRadius - outerGap;
19378
19391
  const wedgeInnerRadius = wedgeOuterRadius - bandWidth;
19379
19392
  const iconRingRadius = (wedgeOuterRadius + wedgeInnerRadius) / 2;
19380
19393
  const centerRadius = Math.max(wedgeInnerRadius - innerGap, 0);
19381
19394
  const slice = 360 / menuItems.length;
19382
19395
  const [activeIndex, setActiveIndex] = React32__namespace.useState(null);
19383
- const timerRef = React32__namespace.useRef(null);
19384
- const isLongPress = React32__namespace.useRef(false);
19385
- const handleTouchStart = (e) => {
19386
- isLongPress.current = false;
19387
- const touch = e.touches[0];
19388
- const { clientX, clientY } = touch;
19389
- timerRef.current = setTimeout(() => {
19390
- isLongPress.current = true;
19391
- const event = new MouseEvent("contextmenu", {
19392
- bubbles: true,
19393
- cancelable: true,
19394
- view: window,
19395
- clientX,
19396
- clientY,
19397
- button: 2,
19398
- buttons: 2
19399
- });
19400
- e.target.dispatchEvent(event);
19401
- }, 1e3);
19402
- };
19403
- const handleTouchEnd = () => {
19404
- if (timerRef.current) {
19405
- clearTimeout(timerRef.current);
19406
- }
19407
- };
19408
- const handleTouchMove = () => {
19409
- if (timerRef.current) {
19410
- clearTimeout(timerRef.current);
19411
- }
19412
- };
19413
19396
  const containerVariants = {
19414
19397
  hidden: { opacity: 0, scale: 0.8 },
19415
19398
  visible: {
@@ -19439,22 +19422,13 @@ function RadialMenu({
19439
19422
  }
19440
19423
  };
19441
19424
  return /* @__PURE__ */ jsxRuntime.jsxs(ContextMenuBase, { children: [
19442
- /* @__PURE__ */ jsxRuntime.jsx(ContextMenuTriggerBase, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
19443
- "div",
19444
- {
19445
- className: "select-none outline-none group touch-none",
19446
- onTouchStart: handleTouchStart,
19447
- onTouchEnd: handleTouchEnd,
19448
- onTouchMove: handleTouchMove,
19449
- children: children || /* @__PURE__ */ jsxRuntime.jsx("div", { className: "size-80 flex justify-center items-center border-2 border-dashed border-muted-foreground/20 rounded-xl bg-muted/5 text-muted-foreground hover:bg-muted/10 transition-colors", children: "Right-click or Long-press here (1s)" })
19450
- }
19451
- ) }),
19425
+ /* @__PURE__ */ jsxRuntime.jsx(ContextMenuTriggerBase, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "select-none outline-none group touch-none", children: children || /* @__PURE__ */ jsxRuntime.jsx("div", { className: "size-80 flex justify-center items-center border-2 border-dashed border-muted-foreground/20 rounded-xl bg-muted/5 cursor-context-menu", children: "Clique com bot\xE3o direito" }) }) }),
19452
19426
  /* @__PURE__ */ jsxRuntime.jsx(
19453
19427
  ContextMenuContentBase,
19454
19428
  {
19455
19429
  className: "p-0 border-none bg-transparent shadow-none overflow-visible -translate-x-1/2 -translate-y-1/2",
19456
19430
  style: { width: size, height: size },
19457
- children: /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { mode: "wait", children: /* @__PURE__ */ jsxRuntime.jsxs(
19431
+ children: /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { mode: "wait", children: /* @__PURE__ */ jsxRuntime.jsx(
19458
19432
  framerMotion.motion.div,
19459
19433
  {
19460
19434
  className: "relative size-full drop-shadow-xl will-change-transform",
@@ -19462,97 +19436,260 @@ function RadialMenu({
19462
19436
  initial: "hidden",
19463
19437
  animate: "visible",
19464
19438
  exit: "exit",
19465
- children: [
19466
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 rounded-full bg-background/5 blur-2xl -z-10" }),
19467
- /* @__PURE__ */ jsxRuntime.jsxs(
19468
- "svg",
19469
- {
19470
- className: "absolute inset-0 size-full overflow-visible",
19471
- viewBox: `${-radius} ${-radius} ${radius * 2} ${radius * 2}`,
19472
- children: [
19473
- /* @__PURE__ */ jsxRuntime.jsx(
19474
- framerMotion.motion.circle,
19439
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
19440
+ "svg",
19441
+ {
19442
+ className: "absolute inset-0 size-full overflow-visible",
19443
+ viewBox: `${-radius} ${-radius} ${radius * 2} ${radius * 2}`,
19444
+ children: [
19445
+ /* @__PURE__ */ jsxRuntime.jsx(framerMotion.motion.circle, { r: centerRadius, className: "fill-background stroke-border stroke-1" }),
19446
+ /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children: activeIndex !== null && /* @__PURE__ */ jsxRuntime.jsx(
19447
+ framerMotion.motion.text,
19448
+ {
19449
+ initial: { opacity: 0, y: 5 },
19450
+ animate: { opacity: 1, y: 0 },
19451
+ exit: { opacity: 0 },
19452
+ textAnchor: "middle",
19453
+ dominantBaseline: "middle",
19454
+ className: "fill-foreground text-[11px] font-bold uppercase tracking-tighter pointer-events-none",
19455
+ children: menuItems[activeIndex].label
19456
+ }
19457
+ ) }),
19458
+ menuItems.map((item, index) => {
19459
+ const Icon = item.icon;
19460
+ const midDeg = START_ANGLE + slice * index;
19461
+ const { x: iconX, y: iconY } = polarToCartesian(iconRingRadius, midDeg);
19462
+ const isActive = activeIndex === index;
19463
+ const ICON_BOX = iconSize * 2.5;
19464
+ return /* @__PURE__ */ jsxRuntime.jsxs(
19465
+ framerMotion.motion.g,
19475
19466
  {
19476
- r: centerRadius,
19477
- initial: { scale: 0 },
19478
- animate: { scale: 1 },
19479
- transition: isMobile ? { duration: 0 } : {
19480
- type: "spring",
19481
- stiffness: 300,
19482
- delay: 0.2
19467
+ variants: itemVariants2,
19468
+ className: "cursor-pointer outline-none",
19469
+ onMouseEnter: () => setActiveIndex(index),
19470
+ onMouseLeave: () => setActiveIndex(null),
19471
+ onClick: (e) => {
19472
+ e.stopPropagation();
19473
+ onSelect?.(item);
19483
19474
  },
19484
- className: "fill-background stroke-border stroke-1 shadow-inner"
19485
- }
19486
- ),
19487
- menuItems.map((item, index) => {
19488
- const Icon = item.icon;
19489
- const midDeg = START_ANGLE + slice * index;
19490
- const { x: iconX, y: iconY } = polarToCartesian(
19491
- iconRingRadius,
19492
- midDeg
19493
- );
19494
- const isActive = activeIndex === index;
19495
- const ICON_BOX = iconSize * 2.5;
19496
- return /* @__PURE__ */ jsxRuntime.jsxs(
19497
- framerMotion.motion.g,
19498
- {
19499
- variants: itemVariants2,
19500
- className: "cursor-pointer outline-none",
19501
- onMouseEnter: () => setActiveIndex(index),
19502
- onMouseLeave: () => setActiveIndex(null),
19503
- onClick: () => onSelect?.(item),
19504
- style: { originX: "0px", originY: "0px" },
19505
- children: [
19506
- /* @__PURE__ */ jsxRuntime.jsx(
19507
- "path",
19508
- {
19509
- d: slicePath(
19510
- index,
19511
- menuItems.length,
19512
- wedgeOuterRadius,
19513
- wedgeInnerRadius
19514
- ),
19515
- className: cn(
19516
- "transition-colors duration-200 stroke-1",
19517
- isActive ? "fill-primary stroke-primary-foreground/20" : "fill-background/90 stroke-border/50 hover:fill-accent"
19518
- )
19475
+ style: { originX: "0px", originY: "0px" },
19476
+ children: [
19477
+ /* @__PURE__ */ jsxRuntime.jsx(
19478
+ "path",
19479
+ {
19480
+ d: slicePath(index, menuItems.length, wedgeOuterRadius, wedgeInnerRadius),
19481
+ className: cn(
19482
+ "transition-colors duration-200 stroke-1",
19483
+ isActive ? item.color === "danger" ? "fill-destructive stroke-destructive-foreground/20" : "fill-primary stroke-primary-foreground/20" : "fill-background/90 stroke-border/50 hover:fill-accent"
19484
+ )
19485
+ }
19486
+ ),
19487
+ /* @__PURE__ */ jsxRuntime.jsx("foreignObject", { x: iconX - ICON_BOX / 2, y: iconY - ICON_BOX / 2, width: ICON_BOX, height: ICON_BOX, className: "pointer-events-none", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "size-full flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
19488
+ Icon,
19489
+ {
19490
+ size: iconSize,
19491
+ weight: isActive ? "fill" : "regular",
19492
+ className: cn(
19493
+ "transition-all duration-200",
19494
+ isActive ? "text-primary-foreground" : item.color === "danger" ? "text-destructive" : "text-muted-foreground"
19495
+ )
19496
+ }
19497
+ ) }) })
19498
+ ]
19499
+ },
19500
+ item.id
19501
+ );
19502
+ })
19503
+ ]
19504
+ }
19505
+ )
19506
+ }
19507
+ ) })
19508
+ }
19509
+ )
19510
+ ] });
19511
+ }
19512
+ function ControlledCombobox({
19513
+ items,
19514
+ renderSelected,
19515
+ handleSelection,
19516
+ checkIsSelected,
19517
+ disabled = false,
19518
+ keepOpen = false,
19519
+ searchPlaceholder,
19520
+ empty = "Nenhum dado encontrado",
19521
+ error,
19522
+ label,
19523
+ labelClassname,
19524
+ testIds = {},
19525
+ onClear,
19526
+ hasSelected = false,
19527
+ hideClear = false,
19528
+ onSearchChange,
19529
+ search,
19530
+ onEndReached,
19531
+ loading = false
19532
+ }) {
19533
+ const [open, setOpen] = React32.useState(false);
19534
+ return /* @__PURE__ */ jsxRuntime.jsxs(
19535
+ "div",
19536
+ {
19537
+ className: "w-full flex flex-col",
19538
+ "data-testid": testIds.root ?? "combobox-base-root",
19539
+ children: [
19540
+ label && /* @__PURE__ */ jsxRuntime.jsx(LabelBase_default, { className: labelClassname, children: label }),
19541
+ /* @__PURE__ */ jsxRuntime.jsxs(
19542
+ PopoverBase,
19543
+ {
19544
+ open,
19545
+ onOpenChange: (v) => !disabled && setOpen(v),
19546
+ modal: false,
19547
+ children: [
19548
+ /* @__PURE__ */ jsxRuntime.jsx(
19549
+ PopoverTriggerBase,
19550
+ {
19551
+ asChild: true,
19552
+ className: "flex w-full justify-between dark:bg-[hsl(231,15%,19%)] p-3",
19553
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
19554
+ ButtonBase,
19555
+ {
19556
+ variant: "select",
19557
+ size: "select",
19558
+ role: "combobox",
19559
+ "aria-expanded": open,
19560
+ "aria-disabled": disabled || void 0,
19561
+ disabled,
19562
+ className: cn(
19563
+ `flex items-center gap-2 justify-between [&>div]:line-clamp-1 relative h-9 no-active-animation`,
19564
+ error && "border-red-500"
19565
+ ),
19566
+ "data-testid": testIds.trigger ?? "combobox-trigger",
19567
+ children: [
19568
+ renderSelected,
19569
+ /* @__PURE__ */ jsxRuntime.jsx(framerMotion.motion.span, { className: "flex items-center", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-row gap-0 items-center ", children: [
19570
+ hasSelected && onClear && !disabled && !hideClear && /* @__PURE__ */ jsxRuntime.jsx(
19571
+ ClearButton,
19572
+ {
19573
+ onClick: (e) => {
19574
+ if (e) e.stopPropagation();
19575
+ if (onClear && !disabled) {
19576
+ onClear();
19577
+ if (!keepOpen) setOpen(false);
19578
+ }
19519
19579
  }
19520
- ),
19521
- /* @__PURE__ */ jsxRuntime.jsx(
19522
- "foreignObject",
19523
- {
19524
- x: iconX - ICON_BOX / 2,
19525
- y: iconY - ICON_BOX / 2,
19526
- width: ICON_BOX,
19527
- height: ICON_BOX,
19528
- className: "pointer-events-none",
19529
- children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "size-full flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
19530
- Icon,
19580
+ }
19581
+ ),
19582
+ /* @__PURE__ */ jsxRuntime.jsx(
19583
+ framerMotion.motion.div,
19584
+ {
19585
+ animate: { rotate: open ? 180 : 0 },
19586
+ transition: { duration: 0.3 },
19587
+ children: /* @__PURE__ */ jsxRuntime.jsx(react.CaretDownIcon, { className: "h-4 w-4" })
19588
+ }
19589
+ )
19590
+ ] }) })
19591
+ ]
19592
+ }
19593
+ )
19594
+ }
19595
+ ),
19596
+ /* @__PURE__ */ jsxRuntime.jsx(
19597
+ PopoverContentBase,
19598
+ {
19599
+ className: "max-h-[--radix-popover-content-available-height] w-[--radix-popover-trigger-width] p-0 border-none focus:ring-0 focus:outline-none",
19600
+ "data-testid": testIds.popover ?? "combobox-popover",
19601
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
19602
+ CommandBase,
19603
+ {
19604
+ className: "dark:text-white hover:bg-rsecondary focus:ring-0 focus:outline-none",
19605
+ "data-testid": testIds.command ?? "combobox-command",
19606
+ filter: onSearchChange ? () => 1 : (value, search2) => {
19607
+ const label2 = items.find((item) => item.value === value)?.label || value;
19608
+ if (label2.toLowerCase().includes(search2.toLowerCase()))
19609
+ return 1;
19610
+ return 0;
19611
+ },
19612
+ children: [
19613
+ /* @__PURE__ */ jsxRuntime.jsx(
19614
+ CommandDebouncedInputBase,
19615
+ {
19616
+ tabIndex: -1,
19617
+ disabled,
19618
+ placeholder: searchPlaceholder ?? "Busque uma op\xE7\xE3o...",
19619
+ "data-testid": testIds.search ?? "combobox-search",
19620
+ onSearch: onSearchChange,
19621
+ search,
19622
+ debounce: 500
19623
+ }
19624
+ ),
19625
+ /* @__PURE__ */ jsxRuntime.jsxs(
19626
+ CommandListBase,
19627
+ {
19628
+ "data-testid": testIds.list ?? "combobox-list",
19629
+ onEndReached,
19630
+ className: "focus:ring-0 focus:outline-none",
19631
+ children: [
19632
+ /* @__PURE__ */ jsxRuntime.jsx(CommandEmptyBase, { "data-testid": testIds.empty ?? "combobox-empty", children: loading ? "Carregando..." : empty }),
19633
+ /* @__PURE__ */ jsxRuntime.jsx(CommandGroupBase, { "data-testid": testIds.group ?? "combobox-group", children: items.map((item) => {
19634
+ const isSelected = checkIsSelected(item.value);
19635
+ return /* @__PURE__ */ jsxRuntime.jsxs(
19636
+ CommandItemBase,
19531
19637
  {
19532
- size: iconSize,
19533
- weight: isActive ? "fill" : "regular",
19534
- className: cn(
19535
- "transition-all duration-200",
19536
- isActive ? "text-primary-foreground " : "text-muted-foreground"
19537
- )
19538
- }
19539
- ) })
19540
- }
19541
- )
19542
- ]
19543
- },
19544
- item.id
19545
- );
19546
- })
19547
- ]
19638
+ keywords: [item.label],
19639
+ value: item.value,
19640
+ onSelect: (value) => {
19641
+ if (disabled) return;
19642
+ handleSelection(value);
19643
+ if (!keepOpen) setOpen(false);
19644
+ },
19645
+ disabled,
19646
+ "data-testid": testIds.option ?? "combobox-option",
19647
+ children: [
19648
+ item.label,
19649
+ /* @__PURE__ */ jsxRuntime.jsx(
19650
+ framerMotion.motion.div,
19651
+ {
19652
+ initial: { scale: 0 },
19653
+ animate: { scale: isSelected ? 1 : 0 },
19654
+ transition: {
19655
+ type: "spring",
19656
+ stiffness: 500,
19657
+ damping: 30
19658
+ },
19659
+ className: "ml-auto ",
19660
+ children: /* @__PURE__ */ jsxRuntime.jsx(
19661
+ react.CheckIcon,
19662
+ {
19663
+ className: cn(
19664
+ "ml-auto",
19665
+ isSelected ? "opacity-100" : "opacity-0"
19666
+ ),
19667
+ "data-testid": isSelected ? testIds.check ?? "combobox-option-check" : void 0
19668
+ }
19669
+ )
19670
+ }
19671
+ )
19672
+ ]
19673
+ },
19674
+ item.value
19675
+ );
19676
+ }) }),
19677
+ loading && items.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center p-2", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-muted-foreground", children: "Carregando mais..." }) })
19678
+ ]
19679
+ }
19680
+ )
19681
+ ]
19682
+ }
19683
+ )
19548
19684
  }
19549
19685
  )
19550
19686
  ]
19551
19687
  }
19552
- ) })
19553
- }
19554
- )
19555
- ] });
19688
+ ),
19689
+ /* @__PURE__ */ jsxRuntime.jsx(ErrorMessage_default, { error })
19690
+ ]
19691
+ }
19692
+ );
19556
19693
  }
19557
19694
 
19558
19695
  exports.AddButton = AddButton;
@@ -19638,6 +19775,7 @@ exports.ContextMenuSubBase = ContextMenuSubBase;
19638
19775
  exports.ContextMenuSubContentBase = ContextMenuSubContentBase;
19639
19776
  exports.ContextMenuSubTriggerBase = ContextMenuSubTriggerBase;
19640
19777
  exports.ContextMenuTriggerBase = ContextMenuTriggerBase;
19778
+ exports.ControlledCombobox = ControlledCombobox;
19641
19779
  exports.CopyButton = CopyButton;
19642
19780
  exports.DateTimePicker = DateTimePicker;
19643
19781
  exports.DayView = DayView;