@snksergio/design-system 0.48.0 → 0.49.0

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.
@@ -433,12 +433,21 @@ const Carousel = React.forwardRef(
433
433
  );
434
434
  const [canScrollPrev, setCanScrollPrev] = React.useState(false);
435
435
  const [canScrollNext, setCanScrollNext] = React.useState(false);
436
+ const [selectedIndex, setSelectedIndex] = React.useState(0);
437
+ const [scrollSnaps, setScrollSnaps] = React.useState([]);
436
438
  const onSelect = React.useCallback((api2) => {
437
439
  if (!api2) {
438
440
  return;
439
441
  }
440
442
  setCanScrollPrev(api2.canScrollPrev());
441
443
  setCanScrollNext(api2.canScrollNext());
444
+ setSelectedIndex(api2.selectedScrollSnap());
445
+ }, []);
446
+ const onInit = React.useCallback((api2) => {
447
+ if (!api2) {
448
+ return;
449
+ }
450
+ setScrollSnaps(api2.scrollSnapList());
442
451
  }, []);
443
452
  const scrollPrev = React.useCallback(() => {
444
453
  api?.scrollPrev();
@@ -446,6 +455,12 @@ const Carousel = React.forwardRef(
446
455
  const scrollNext = React.useCallback(() => {
447
456
  api?.scrollNext();
448
457
  }, [api]);
458
+ const scrollTo = React.useCallback(
459
+ (index) => {
460
+ api?.scrollTo(index);
461
+ },
462
+ [api]
463
+ );
449
464
  const handleKeyDown = React.useCallback(
450
465
  (event) => {
451
466
  if (event.key === "ArrowLeft") {
@@ -468,13 +483,17 @@ const Carousel = React.forwardRef(
468
483
  if (!api) {
469
484
  return;
470
485
  }
486
+ onInit(api);
471
487
  onSelect(api);
488
+ api.on("reInit", onInit);
472
489
  api.on("reInit", onSelect);
473
490
  api.on("select", onSelect);
474
491
  return () => {
492
+ api?.off("reInit", onInit);
493
+ api?.off("reInit", onSelect);
475
494
  api?.off("select", onSelect);
476
495
  };
477
- }, [api, onSelect]);
496
+ }, [api, onInit, onSelect]);
478
497
  return /* @__PURE__ */ jsx(
479
498
  CarouselContext.Provider,
480
499
  {
@@ -486,7 +505,10 @@ const Carousel = React.forwardRef(
486
505
  scrollPrev,
487
506
  scrollNext,
488
507
  canScrollPrev,
489
- canScrollNext
508
+ canScrollNext,
509
+ selectedIndex,
510
+ scrollSnaps,
511
+ scrollTo
490
512
  },
491
513
  children: /* @__PURE__ */ jsx(
492
514
  "div",
@@ -507,18 +529,53 @@ const Carousel = React.forwardRef(
507
529
  Carousel.displayName = "Carousel";
508
530
  const CarouselContent = React.forwardRef(({ className, ...props }, ref) => {
509
531
  const { carouselRef, orientation } = useCarousel();
510
- return /* @__PURE__ */ jsx("div", { ref: carouselRef, className: "overflow-hidden", children: /* @__PURE__ */ jsx(
511
- "div",
512
- {
513
- ref,
514
- className: cn(
515
- "flex",
516
- orientation === "horizontal" ? "-ml-4" : "-mt-4 flex-col",
517
- className
518
- ),
519
- ...props
520
- }
521
- ) });
532
+ return (
533
+ /**
534
+ * A folga de 4px existe pra borda do slide não ser comida pelo corte.
535
+ *
536
+ * O Embla posiciona o trilho com `translate` em pixel FRACIONÁRIO, e no padrão de
537
+ * gutter do shadcn (`-ml-4` no trilho + `pl-4` no item) a borda esquerda do conteúdo
538
+ * cai **exatamente** sobre o limite do `overflow-hidden`. Medido em 2026-08-24, no
539
+ * slide 3: limite do clip em 651.5px e a borda do card em 649.99px — 1.5px inteiros
540
+ * do lado de fora, então a borda de 1px desaparecia. E variava entre medições, porque
541
+ * depende de onde o Embla para no sub-pixel: às vezes 2px dentro, às vezes fora. Só o
542
+ * primeiro slide era imune (translate 0, sem fração) — o relato foi exatamente "do
543
+ * card 2 pra frente".
544
+ *
545
+ * `overflow` corta no limite do PADDING box, então o padding dá a folga; a margem
546
+ * negativa devolve a posição, pra geometria externa não mudar. Não revela o slide
547
+ * vizinho: o que aparece nessa faixa é o gutter transparente de 16px do item.
548
+ *
549
+ * **4px e não 2px** porque o gutter do shadcn é só do lado ESQUERDO (`-ml`/`pl`): a
550
+ * direita do último card visível encosta no limite por construção. Com 2px, o caso de
551
+ * `slidesToScroll: 2` media −0.06px de folga na direita na última parada — o mesmo
552
+ * defeito, menor. Com 4px as duas bordas ficam positivas em todas as paradas.
553
+ */
554
+ /* @__PURE__ */ jsx(
555
+ "div",
556
+ {
557
+ ref: carouselRef,
558
+ className: cn(
559
+ "overflow-hidden",
560
+ // A folga vai no EIXO que rola: no vertical o gutter é `-mt`/`pt` e quem encosta
561
+ // no corte é a borda de cima. Padding no eixo errado não conserta nada.
562
+ orientation === "horizontal" ? "px-sp-xs -mx-sp-xs" : "py-sp-xs -my-sp-xs"
563
+ ),
564
+ children: /* @__PURE__ */ jsx(
565
+ "div",
566
+ {
567
+ ref,
568
+ className: cn(
569
+ "flex",
570
+ orientation === "horizontal" ? "-ml-4" : "-mt-4 flex-col",
571
+ className
572
+ ),
573
+ ...props
574
+ }
575
+ )
576
+ }
577
+ )
578
+ );
522
579
  });
523
580
  CarouselContent.displayName = "CarouselContent";
524
581
  const CarouselItem = React.forwardRef(({ className, ...props }, ref) => {
@@ -589,6 +646,55 @@ const CarouselNext = React.forwardRef(({ className, ...props }, ref) => {
589
646
  );
590
647
  });
591
648
  CarouselNext.displayName = "CarouselNext";
649
+ const CarouselDots = React.forwardRef(({ className, ...props }, ref) => {
650
+ const { scrollSnaps, selectedIndex, scrollTo, orientation } = useCarousel();
651
+ if (scrollSnaps.length <= 1) {
652
+ return null;
653
+ }
654
+ return /* @__PURE__ */ jsx(
655
+ "div",
656
+ {
657
+ ref,
658
+ role: "group",
659
+ "aria-label": "Posição no carrossel",
660
+ className: cn(
661
+ "flex items-center justify-center gap-gp-2xs",
662
+ orientation === "vertical" && "flex-col",
663
+ className
664
+ ),
665
+ ...props,
666
+ children: scrollSnaps.map((_, i) => {
667
+ const atual = i === selectedIndex;
668
+ return /* @__PURE__ */ jsx(
669
+ "button",
670
+ {
671
+ type: "button",
672
+ onClick: () => scrollTo(i),
673
+ "aria-label": `Ir para ${i + 1} de ${scrollSnaps.length}`,
674
+ "aria-current": atual ? "true" : void 0,
675
+ className: cn(
676
+ "grid size-comp-3xs shrink-0 cursor-pointer place-items-center",
677
+ "rounded-radius-full",
678
+ // Padrão 1 — focus estático
679
+ "focus-visible:outline-none focus-visible:ring-4 focus-visible:ring-ring-brand"
680
+ ),
681
+ children: /* @__PURE__ */ jsx(
682
+ "span",
683
+ {
684
+ className: cn(
685
+ "size-[8px] rounded-radius-full transition-colors",
686
+ atual ? "bg-bg-brand" : "bg-bg-emphasis hover:bg-bg-accent"
687
+ )
688
+ }
689
+ )
690
+ },
691
+ i
692
+ );
693
+ })
694
+ }
695
+ );
696
+ });
697
+ CarouselDots.displayName = "CarouselDots";
592
698
  const ContextMenu = ContextMenuPrimitive.Root;
593
699
  const ContextMenuTrigger = ContextMenuPrimitive.Trigger;
594
700
  const ContextMenuGroup = ContextMenuPrimitive.Group;
@@ -1517,83 +1623,84 @@ const ToggleGroupItem = React.forwardRef(({ className, children, variant, size,
1517
1623
  });
1518
1624
  ToggleGroupItem.displayName = ToggleGroupPrimitive.Item.displayName;
1519
1625
  export {
1520
- HoverCardTrigger as $,
1626
+ HoverCardContent as $,
1521
1627
  Accordion as A,
1522
1628
  Badge as B,
1523
1629
  Card as C,
1524
- ContextMenuGroup as D,
1525
- ContextMenuItem as E,
1526
- ContextMenuLabel as F,
1527
- ContextMenuPortal as G,
1528
- ContextMenuRadioGroup as H,
1529
- ContextMenuRadioItem as I,
1530
- ContextMenuSeparator as J,
1531
- ContextMenuShortcut as K,
1532
- ContextMenuSub as L,
1533
- ContextMenuSubContent as M,
1534
- ContextMenuSubTrigger as N,
1535
- ContextMenuTrigger as O,
1536
- Drawer as P,
1537
- DrawerClose as Q,
1538
- DrawerContent as R,
1539
- DrawerDescription as S,
1540
- DrawerFooter as T,
1541
- DrawerHeader as U,
1542
- DrawerOverlay as V,
1543
- DrawerPortal as W,
1544
- DrawerTitle as X,
1545
- DrawerTrigger as Y,
1546
- HoverCard as Z,
1547
- HoverCardContent as _,
1630
+ ContextMenuContent as D,
1631
+ ContextMenuGroup as E,
1632
+ ContextMenuItem as F,
1633
+ ContextMenuLabel as G,
1634
+ ContextMenuPortal as H,
1635
+ ContextMenuRadioGroup as I,
1636
+ ContextMenuRadioItem as J,
1637
+ ContextMenuSeparator as K,
1638
+ ContextMenuShortcut as L,
1639
+ ContextMenuSub as M,
1640
+ ContextMenuSubContent as N,
1641
+ ContextMenuSubTrigger as O,
1642
+ ContextMenuTrigger as P,
1643
+ Drawer as Q,
1644
+ DrawerClose as R,
1645
+ DrawerContent as S,
1646
+ DrawerDescription as T,
1647
+ DrawerFooter as U,
1648
+ DrawerHeader as V,
1649
+ DrawerOverlay as W,
1650
+ DrawerPortal as X,
1651
+ DrawerTitle as Y,
1652
+ DrawerTrigger as Z,
1653
+ HoverCard as _,
1548
1654
  AccordionContent as a,
1549
- InputOTP as a0,
1550
- InputOTPGroup as a1,
1551
- InputOTPSeparator as a2,
1552
- InputOTPSlot as a3,
1553
- Label as a4,
1554
- Menubar as a5,
1555
- MenubarCheckboxItem as a6,
1556
- MenubarContent as a7,
1557
- MenubarGroup as a8,
1558
- MenubarItem as a9,
1559
- Slider as aA,
1560
- Tabs as aB,
1561
- TabsContent as aC,
1562
- TabsList as aD,
1563
- TabsTrigger as aE,
1564
- Toggle as aF,
1565
- ToggleGroup as aG,
1566
- ToggleGroupItem as aH,
1567
- badgeVariants as aI,
1568
- navigationMenuTriggerStyle as aJ,
1569
- slotVariants as aK,
1570
- toggleVariants as aL,
1571
- MenubarLabel as aa,
1572
- MenubarMenu as ab,
1573
- MenubarPortal as ac,
1574
- MenubarRadioGroup as ad,
1575
- MenubarRadioItem as ae,
1576
- MenubarSeparator as af,
1577
- MenubarShortcut as ag,
1578
- MenubarSub as ah,
1579
- MenubarSubContent as ai,
1580
- MenubarSubTrigger as aj,
1581
- MenubarTrigger as ak,
1582
- NavigationMenu as al,
1583
- NavigationMenuContent as am,
1584
- NavigationMenuIndicator as an,
1585
- NavigationMenuItem as ao,
1586
- NavigationMenuLink as ap,
1587
- NavigationMenuList as aq,
1588
- NavigationMenuTrigger as ar,
1589
- NavigationMenuViewport as as,
1590
- Progress as at,
1591
- RadioGroup as au,
1592
- RadioGroupItem as av,
1593
- ScrollArea as aw,
1594
- ScrollBar as ax,
1595
- Separator as ay,
1596
- Skeleton as az,
1655
+ HoverCardTrigger as a0,
1656
+ InputOTP as a1,
1657
+ InputOTPGroup as a2,
1658
+ InputOTPSeparator as a3,
1659
+ InputOTPSlot as a4,
1660
+ Label as a5,
1661
+ Menubar as a6,
1662
+ MenubarCheckboxItem as a7,
1663
+ MenubarContent as a8,
1664
+ MenubarGroup as a9,
1665
+ Skeleton as aA,
1666
+ Slider as aB,
1667
+ Tabs as aC,
1668
+ TabsContent as aD,
1669
+ TabsList as aE,
1670
+ TabsTrigger as aF,
1671
+ Toggle as aG,
1672
+ ToggleGroup as aH,
1673
+ ToggleGroupItem as aI,
1674
+ badgeVariants as aJ,
1675
+ navigationMenuTriggerStyle as aK,
1676
+ slotVariants as aL,
1677
+ toggleVariants as aM,
1678
+ MenubarItem as aa,
1679
+ MenubarLabel as ab,
1680
+ MenubarMenu as ac,
1681
+ MenubarPortal as ad,
1682
+ MenubarRadioGroup as ae,
1683
+ MenubarRadioItem as af,
1684
+ MenubarSeparator as ag,
1685
+ MenubarShortcut as ah,
1686
+ MenubarSub as ai,
1687
+ MenubarSubContent as aj,
1688
+ MenubarSubTrigger as ak,
1689
+ MenubarTrigger as al,
1690
+ NavigationMenu as am,
1691
+ NavigationMenuContent as an,
1692
+ NavigationMenuIndicator as ao,
1693
+ NavigationMenuItem as ap,
1694
+ NavigationMenuLink as aq,
1695
+ NavigationMenuList as ar,
1696
+ NavigationMenuTrigger as as,
1697
+ NavigationMenuViewport as at,
1698
+ Progress as au,
1699
+ RadioGroup as av,
1700
+ RadioGroupItem as aw,
1701
+ ScrollArea as ax,
1702
+ ScrollBar as ay,
1703
+ Separator as az,
1597
1704
  AccordionItem as b,
1598
1705
  AccordionTrigger as c,
1599
1706
  Alert as d,
@@ -1613,11 +1720,11 @@ export {
1613
1720
  CardTitle as r,
1614
1721
  Carousel as s,
1615
1722
  CarouselContent as t,
1616
- CarouselItem as u,
1617
- CarouselNext as v,
1618
- CarouselPrevious as w,
1619
- ContextMenu as x,
1620
- ContextMenuCheckboxItem as y,
1621
- ContextMenuContent as z
1723
+ CarouselDots as u,
1724
+ CarouselItem as v,
1725
+ CarouselNext as w,
1726
+ CarouselPrevious as x,
1727
+ ContextMenu as y,
1728
+ ContextMenuCheckboxItem as z
1622
1729
  };
1623
- //# sourceMappingURL=toggle-group-CnAN6ZnT.mjs.map
1730
+ //# sourceMappingURL=toggle-group-C3srOzNZ.mjs.map