@tinybigui/react 0.20.0 → 0.21.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.
package/dist/index.cjs CHANGED
@@ -9632,105 +9632,354 @@ var Badge = React.forwardRef(
9632
9632
  }
9633
9633
  );
9634
9634
  Badge.displayName = "Badge";
9635
- var splitButtonContainerVariants = classVarianceAuthority.cva(
9636
- ["inline-flex items-center rounded-full overflow-hidden"],
9635
+ var splitButtonContainerVariants = classVarianceAuthority.cva([
9636
+ "relative inline-flex items-stretch",
9637
+ "gap-0.5"
9638
+ // MD3 2dp gap between segments
9639
+ ]);
9640
+ var splitButtonLeadingVariants = classVarianceAuthority.cva(
9641
+ [
9642
+ // Layout
9643
+ "group/sb-leading relative inline-flex items-center justify-center",
9644
+ "cursor-pointer select-none",
9645
+ // Shape — asymmetric corners via CSS variable
9646
+ "rounded-tl-full rounded-bl-full",
9647
+ "rounded-tr-[var(--sb-inner-radius,var(--radius-xs))]",
9648
+ "rounded-br-[var(--sb-inner-radius,var(--radius-xs))]",
9649
+ // Inner-corner morph — xs/sm/md defaults; lg/xl override in size variants below.
9650
+ // Specificity ladder: rest (0,0,0) < hover (0,1,0) < focus (0,2,0) < pressed (0,3,0)
9651
+ "[--sb-inner-radius:var(--radius-xs)]",
9652
+ "data-[hovered]:[--sb-inner-radius:var(--radius-sm)]",
9653
+ "data-[focus-visible]:data-[focus-visible]:[--sb-inner-radius:var(--radius-sm)]",
9654
+ // Pressed morphs stronger than hover/focus — tripled selector → (0,3,0)
9655
+ "data-[pressed]:data-[pressed]:data-[pressed]:[--sb-inner-radius:var(--radius-lg)]",
9656
+ // Spatial transition for border-radius morphing
9657
+ "transition-[border-radius]",
9658
+ "duration-expressive-fast-spatial ease-expressive-fast-spatial",
9659
+ // Disabled — self-targeting
9660
+ "data-[disabled]:cursor-not-allowed data-[disabled]:pointer-events-none"
9661
+ ],
9637
9662
  {
9638
9663
  variants: {
9664
+ /**
9665
+ * Visual variant — controls container color, text color, and elevation.
9666
+ * State layer color is handled in splitButtonStateLayerVariants.
9667
+ */
9639
9668
  variant: {
9640
- filled: "bg-primary shadow-elevation-0 hover:shadow-elevation-1",
9641
- tonal: "bg-secondary-container",
9642
- outlined: "border border-outline bg-transparent"
9669
+ /**
9670
+ * Filled — highest emphasis.
9671
+ * container=primary, label=on-primary
9672
+ * Elevation: 0 base → 1 hover → 0 focus/pressed
9673
+ */
9674
+ filled: [
9675
+ "bg-primary text-on-primary shadow-none",
9676
+ "group-data-[hovered]/sb-leading:shadow-elevation-1",
9677
+ "group-data-[focus-visible]/sb-leading:shadow-none",
9678
+ "group-data-[pressed]/sb-leading:group-data-[pressed]/sb-leading:shadow-none",
9679
+ // Disabled
9680
+ "data-[disabled]:bg-on-surface/12 data-[disabled]:text-on-surface/38 data-[disabled]:shadow-none"
9681
+ ],
9682
+ /**
9683
+ * Tonal — secondary emphasis.
9684
+ * container=secondary-container, label=on-secondary-container
9685
+ * Elevation: 0 base → 1 hover → 0 focus/pressed
9686
+ */
9687
+ tonal: [
9688
+ "bg-secondary-container text-on-secondary-container shadow-none",
9689
+ "group-data-[hovered]/sb-leading:shadow-elevation-1",
9690
+ "group-data-[focus-visible]/sb-leading:shadow-none",
9691
+ "group-data-[pressed]/sb-leading:group-data-[pressed]/sb-leading:shadow-none",
9692
+ // Disabled
9693
+ "data-[disabled]:bg-on-surface/12 data-[disabled]:text-on-surface/38 data-[disabled]:shadow-none"
9694
+ ],
9695
+ /**
9696
+ * Outlined — medium emphasis. Transparent with border.
9697
+ * container=transparent, border=outline, label=primary
9698
+ * Elevation: always 0
9699
+ */
9700
+ outlined: [
9701
+ "bg-transparent border border-outline text-primary",
9702
+ // Disabled
9703
+ "data-[disabled]:border-on-surface/12 data-[disabled]:text-on-surface/38"
9704
+ ],
9705
+ /**
9706
+ * Elevated — uses surface-container-low with a level-1 shadow base.
9707
+ * container=surface-container-low, label=primary
9708
+ * Elevation: 1 base → 2 hover → 1 focus/pressed
9709
+ */
9710
+ elevated: [
9711
+ "bg-surface-container-low text-primary shadow-elevation-1",
9712
+ "group-data-[hovered]/sb-leading:shadow-elevation-2",
9713
+ "group-data-[focus-visible]/sb-leading:shadow-elevation-1",
9714
+ "group-data-[pressed]/sb-leading:group-data-[pressed]/sb-leading:shadow-elevation-1",
9715
+ // Disabled
9716
+ "data-[disabled]:bg-on-surface/12 data-[disabled]:text-on-surface/38 data-[disabled]:shadow-none"
9717
+ ]
9643
9718
  },
9719
+ /**
9720
+ * Size — governs height, horizontal padding, typography, and inner-corner rest/morph values.
9721
+ * lg/xl need larger rest radii so their morph steps differ from xs/sm/md.
9722
+ */
9644
9723
  size: {
9645
- small: "h-8",
9646
- medium: "h-10",
9647
- large: "h-12"
9648
- },
9649
- isDisabled: {
9650
- true: "opacity-38 pointer-events-none",
9651
- false: ""
9724
+ xs: "h-8 pl-4 pr-3 text-label-large",
9725
+ sm: "h-10 pl-6 pr-4 text-label-large",
9726
+ md: "h-14 pl-8 pr-6 text-title-medium",
9727
+ lg: [
9728
+ "h-24 pl-10 pr-8 text-headline-small",
9729
+ // lg rest=sm, hover/focus→lg, pressed→xl
9730
+ "[--sb-inner-radius:var(--radius-sm)]",
9731
+ "data-[hovered]:[--sb-inner-radius:var(--radius-lg)]",
9732
+ "data-[focus-visible]:data-[focus-visible]:[--sb-inner-radius:var(--radius-lg)]",
9733
+ "data-[pressed]:data-[pressed]:data-[pressed]:[--sb-inner-radius:var(--radius-xl)]"
9734
+ ],
9735
+ xl: [
9736
+ "h-[8.5rem] pl-12 pr-10 text-headline-large",
9737
+ // xl rest=md, hover/focus→lg, pressed→xl
9738
+ "[--sb-inner-radius:var(--radius-md)]",
9739
+ "data-[hovered]:[--sb-inner-radius:var(--radius-lg)]",
9740
+ "data-[focus-visible]:data-[focus-visible]:[--sb-inner-radius:var(--radius-lg)]",
9741
+ "data-[pressed]:data-[pressed]:data-[pressed]:[--sb-inner-radius:var(--radius-xl)]"
9742
+ ]
9652
9743
  }
9653
9744
  },
9654
9745
  defaultVariants: {
9655
9746
  variant: "filled",
9656
- size: "medium",
9657
- isDisabled: false
9747
+ size: "sm"
9658
9748
  }
9659
9749
  }
9660
9750
  );
9661
- var splitButtonPrimaryVariants = classVarianceAuthority.cva(
9751
+ var splitButtonTrailingVariants = classVarianceAuthority.cva(
9662
9752
  [
9663
- "group/primary relative inline-flex items-center justify-center cursor-pointer",
9664
- "h-full font-medium tracking-[0.1px]",
9665
- "focus-visible:outline-primary focus-visible:outline-2 focus-visible:outline-offset-2"
9753
+ // Layout square so that selected (rounded-full on all corners) = perfect circle
9754
+ "group/sb-trailing relative inline-flex items-center justify-center shrink-0",
9755
+ "cursor-pointer select-none",
9756
+ // Shape — asymmetric corners, inner on the left side
9757
+ "rounded-tr-full rounded-br-full",
9758
+ "rounded-tl-[var(--sb-inner-radius,var(--radius-xs))]",
9759
+ "rounded-bl-[var(--sb-inner-radius,var(--radius-xs))]",
9760
+ // Inner-corner morph — xs/sm/md defaults; lg/xl override in size variants below.
9761
+ // Specificity ladder: rest (0,0,0) < hover (0,1,0) < focus (0,2,0) < pressed (0,3,0) < selected (0,4,0)
9762
+ "[--sb-inner-radius:var(--radius-xs)]",
9763
+ "data-[hovered]:[--sb-inner-radius:var(--radius-sm)]",
9764
+ "data-[focus-visible]:data-[focus-visible]:[--sb-inner-radius:var(--radius-sm)]",
9765
+ // Pressed morphs stronger than hover/focus — tripled → (0,3,0)
9766
+ "data-[pressed]:data-[pressed]:data-[pressed]:[--sb-inner-radius:var(--radius-lg)]",
9767
+ // Selected (menu open) → full circle; quadrupled → (0,4,0) always wins
9768
+ "data-[selected]:data-[selected]:data-[selected]:data-[selected]:[--sb-inner-radius:var(--radius-full)]",
9769
+ // Spatial transition for border-radius morphing
9770
+ "transition-[border-radius]",
9771
+ "duration-expressive-fast-spatial ease-expressive-fast-spatial",
9772
+ // Disabled — self-targeting
9773
+ "data-[disabled]:cursor-not-allowed data-[disabled]:pointer-events-none"
9666
9774
  ],
9667
9775
  {
9668
9776
  variants: {
9669
9777
  variant: {
9670
- filled: "text-on-primary",
9671
- tonal: "text-on-secondary-container",
9672
- outlined: "text-primary"
9778
+ filled: [
9779
+ "bg-primary text-on-primary shadow-none",
9780
+ "group-data-[hovered]/sb-trailing:shadow-elevation-1",
9781
+ "group-data-[focus-visible]/sb-trailing:shadow-none",
9782
+ "group-data-[pressed]/sb-trailing:group-data-[pressed]/sb-trailing:shadow-none",
9783
+ "data-[disabled]:bg-on-surface/12 data-[disabled]:text-on-surface/38 data-[disabled]:shadow-none"
9784
+ ],
9785
+ tonal: [
9786
+ "bg-secondary-container text-on-secondary-container shadow-none",
9787
+ "group-data-[hovered]/sb-trailing:shadow-elevation-1",
9788
+ "group-data-[focus-visible]/sb-trailing:shadow-none",
9789
+ "group-data-[pressed]/sb-trailing:group-data-[pressed]/sb-trailing:shadow-none",
9790
+ "data-[disabled]:bg-on-surface/12 data-[disabled]:text-on-surface/38 data-[disabled]:shadow-none"
9791
+ ],
9792
+ outlined: [
9793
+ "bg-transparent border border-outline text-primary",
9794
+ "data-[disabled]:border-on-surface/12 data-[disabled]:text-on-surface/38"
9795
+ ],
9796
+ elevated: [
9797
+ "bg-surface-container-low text-primary shadow-elevation-1",
9798
+ "group-data-[hovered]/sb-trailing:shadow-elevation-2",
9799
+ "group-data-[focus-visible]/sb-trailing:shadow-elevation-1",
9800
+ "group-data-[pressed]/sb-trailing:group-data-[pressed]/sb-trailing:shadow-elevation-1",
9801
+ "data-[disabled]:bg-on-surface/12 data-[disabled]:text-on-surface/38 data-[disabled]:shadow-none"
9802
+ ]
9673
9803
  },
9674
9804
  size: {
9675
- small: "pl-4 pr-3 text-xs",
9676
- medium: "pl-6 pr-4 text-sm",
9677
- large: "pl-8 pr-5 text-base"
9805
+ // Square dimensions (width = height) so selected state = perfect circle.
9806
+ // Per-size inner-radius rest/morph values mirror the leading segment.
9807
+ xs: "h-8 w-8",
9808
+ sm: "h-10 w-10",
9809
+ md: "h-14 w-14",
9810
+ lg: [
9811
+ "h-24 w-24",
9812
+ // lg rest=sm, hover/focus→lg, pressed→xl; selected→full handled in base classes
9813
+ "[--sb-inner-radius:var(--radius-sm)]",
9814
+ "data-[hovered]:[--sb-inner-radius:var(--radius-lg)]",
9815
+ "data-[focus-visible]:data-[focus-visible]:[--sb-inner-radius:var(--radius-lg)]",
9816
+ "data-[pressed]:data-[pressed]:data-[pressed]:[--sb-inner-radius:var(--radius-xl)]"
9817
+ ],
9818
+ xl: [
9819
+ "h-[8.5rem] w-[8.5rem]",
9820
+ // xl rest=md, hover/focus→lg, pressed→xl; selected→full handled in base classes
9821
+ "[--sb-inner-radius:var(--radius-md)]",
9822
+ "data-[hovered]:[--sb-inner-radius:var(--radius-lg)]",
9823
+ "data-[focus-visible]:data-[focus-visible]:[--sb-inner-radius:var(--radius-lg)]",
9824
+ "data-[pressed]:data-[pressed]:data-[pressed]:[--sb-inner-radius:var(--radius-xl)]"
9825
+ ]
9678
9826
  }
9679
9827
  },
9680
9828
  defaultVariants: {
9681
9829
  variant: "filled",
9682
- size: "medium"
9830
+ size: "sm"
9683
9831
  }
9684
9832
  }
9685
9833
  );
9686
- var splitButtonDropdownVariants = classVarianceAuthority.cva(
9834
+ var splitButtonStateLayerVariants = classVarianceAuthority.cva(
9687
9835
  [
9688
- "group/dropdown relative inline-flex items-center justify-center cursor-pointer",
9689
- "h-full",
9690
- "focus-visible:outline-primary focus-visible:outline-2 focus-visible:outline-offset-2"
9836
+ "absolute inset-0 rounded-[inherit] overflow-hidden pointer-events-none opacity-0",
9837
+ "transition-opacity duration-spring-standard-fast-effects ease-spring-standard-fast-effects"
9691
9838
  ],
9692
9839
  {
9693
9840
  variants: {
9694
9841
  variant: {
9695
- filled: "text-on-primary border-l border-on-primary/38",
9696
- tonal: "text-on-secondary-container border-l border-on-secondary-container/38",
9697
- outlined: "text-primary border-l border-outline"
9842
+ filled: "bg-on-primary",
9843
+ tonal: "bg-on-secondary-container",
9844
+ outlined: "bg-primary",
9845
+ elevated: "bg-primary"
9698
9846
  },
9699
- size: {
9700
- small: "px-1.5",
9701
- medium: "px-2",
9702
- large: "px-3"
9847
+ /**
9848
+ * groupScope identifies which segment this state layer belongs to so it
9849
+ * reads from the correct group-data-[x]/<scope> selectors.
9850
+ */
9851
+ groupScope: {
9852
+ leading: [
9853
+ "group-data-[hovered]/sb-leading:opacity-8",
9854
+ "group-data-[focus-visible]/sb-leading:opacity-10",
9855
+ "group-data-[pressed]/sb-leading:group-data-[pressed]/sb-leading:opacity-10",
9856
+ "group-data-[disabled]/sb-leading:hidden"
9857
+ ],
9858
+ trailing: [
9859
+ "group-data-[hovered]/sb-trailing:opacity-8",
9860
+ "group-data-[focus-visible]/sb-trailing:opacity-10",
9861
+ "group-data-[pressed]/sb-trailing:group-data-[pressed]/sb-trailing:opacity-10",
9862
+ "group-data-[disabled]/sb-trailing:hidden"
9863
+ ]
9703
9864
  }
9704
9865
  },
9705
9866
  defaultVariants: {
9706
9867
  variant: "filled",
9707
- size: "medium"
9868
+ groupScope: "leading"
9708
9869
  }
9709
9870
  }
9710
9871
  );
9872
+ var splitButtonFocusRingVariants = classVarianceAuthority.cva(
9873
+ [
9874
+ "pointer-events-none absolute inset-[-3px]",
9875
+ "outline outline-2 outline-offset-0 outline-secondary",
9876
+ "transition-opacity duration-spring-standard-fast-effects ease-spring-standard-fast-effects",
9877
+ "opacity-0"
9878
+ ],
9879
+ {
9880
+ variants: {
9881
+ /**
9882
+ * Corner shape must match the segment it wraps.
9883
+ * Leading: full-left, inner-right follows --sb-inner-radius.
9884
+ * Trailing: full-right, inner-left follows --sb-inner-radius.
9885
+ */
9886
+ groupScope: {
9887
+ leading: [
9888
+ "rounded-tl-full rounded-bl-full",
9889
+ "rounded-tr-[calc(var(--sb-inner-radius,var(--radius-xs))+3px)]",
9890
+ "rounded-br-[calc(var(--sb-inner-radius,var(--radius-xs))+3px)]",
9891
+ "group-data-[focus-visible]/sb-leading:opacity-100"
9892
+ ],
9893
+ trailing: [
9894
+ "rounded-tr-full rounded-br-full",
9895
+ "rounded-tl-[calc(var(--sb-inner-radius,var(--radius-xs))+3px)]",
9896
+ "rounded-bl-[calc(var(--sb-inner-radius,var(--radius-xs))+3px)]",
9897
+ "group-data-[focus-visible]/sb-trailing:opacity-100"
9898
+ ]
9899
+ }
9900
+ },
9901
+ defaultVariants: { groupScope: "leading" }
9902
+ }
9903
+ );
9904
+ var splitButtonLabelVariants = classVarianceAuthority.cva(["relative z-10 inline-flex items-center"]);
9905
+ var splitButtonIconVariants = classVarianceAuthority.cva(
9906
+ [
9907
+ "relative z-10 inline-flex shrink-0 items-center justify-center",
9908
+ // Spatial spring motion for the optical-offset translate
9909
+ "transition-transform duration-spring-standard-fast-spatial ease-spring-standard-fast-spatial",
9910
+ // Reset offset when the trailing segment is in selected state (menu open)
9911
+ "group-data-[selected]/sb-trailing:translate-x-0"
9912
+ ],
9913
+ {
9914
+ variants: {
9915
+ size: {
9916
+ // Include per-size icon dimension + unselected optical offset
9917
+ xs: ["size-5", "-translate-x-px"],
9918
+ sm: ["size-5", "-translate-x-px"],
9919
+ md: ["size-6", "-translate-x-0.5"],
9920
+ lg: ["size-8", "-translate-x-[3px]"],
9921
+ xl: ["size-10", "-translate-x-[6px]"]
9922
+ }
9923
+ },
9924
+ defaultVariants: { size: "sm" }
9925
+ }
9926
+ );
9927
+ var splitButtonMenuVariants = classVarianceAuthority.cva([
9928
+ "absolute top-full right-0 z-50 mt-1 min-w-40",
9929
+ "bg-surface-container rounded-md py-2",
9930
+ "shadow-elevation-2",
9931
+ "animate-md-scale-in"
9932
+ ]);
9933
+ var splitButtonMenuItemVariants = classVarianceAuthority.cva(
9934
+ [
9935
+ "text-body-large text-on-surface cursor-pointer px-4 py-2",
9936
+ "hover:bg-on-surface/8",
9937
+ "focus:bg-on-surface/10 focus:outline-none"
9938
+ ],
9939
+ {
9940
+ variants: {
9941
+ isDisabled: {
9942
+ true: "text-on-surface/38 pointer-events-none cursor-not-allowed",
9943
+ false: ""
9944
+ }
9945
+ },
9946
+ defaultVariants: { isDisabled: false }
9947
+ }
9948
+ );
9711
9949
  var splitButtonVariants = {
9712
9950
  container: splitButtonContainerVariants,
9713
- primary: splitButtonPrimaryVariants,
9714
- dropdown: splitButtonDropdownVariants
9951
+ leading: splitButtonLeadingVariants,
9952
+ trailing: splitButtonTrailingVariants,
9953
+ stateLayer: splitButtonStateLayerVariants,
9954
+ focusRing: splitButtonFocusRingVariants,
9955
+ label: splitButtonLabelVariants,
9956
+ icon: splitButtonIconVariants,
9957
+ menu: splitButtonMenuVariants,
9958
+ menuItem: splitButtonMenuItemVariants
9715
9959
  };
9716
- var ChevronIcon = ({ isOpen }) => /* @__PURE__ */ jsxRuntime.jsx(
9960
+ var ChevronIcon = ({
9961
+ isOpen,
9962
+ reducedMotion
9963
+ }) => /* @__PURE__ */ jsxRuntime.jsx(
9717
9964
  "svg",
9718
9965
  {
9719
9966
  "aria-hidden": "true",
9720
9967
  "data-testid": "split-button-chevron",
9721
- width: "18",
9722
- height: "18",
9723
9968
  viewBox: "0 0 24 24",
9724
9969
  fill: "none",
9725
9970
  xmlns: "http://www.w3.org/2000/svg",
9726
- className: cn("duration-short4 ease-standard transition-transform", isOpen && "rotate-180"),
9971
+ className: cn(
9972
+ "size-full",
9973
+ !reducedMotion && "duration-expressive-fast-spatial ease-expressive-fast-spatial transition-transform",
9974
+ isOpen && "rotate-180"
9975
+ ),
9727
9976
  children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M7 10l5 5 5-5H7z", fill: "currentColor" })
9728
9977
  }
9729
9978
  );
9730
9979
  var SplitButton = React.forwardRef(
9731
9980
  ({
9732
9981
  variant = "filled",
9733
- size = "medium",
9982
+ size = "sm",
9734
9983
  primaryLabel,
9735
9984
  onPrimaryAction,
9736
9985
  items,
@@ -9738,32 +9987,73 @@ var SplitButton = React.forwardRef(
9738
9987
  "aria-label": ariaLabel,
9739
9988
  className
9740
9989
  }, forwardedRef) => {
9741
- const primaryRef = React.useRef(null);
9742
- const dropdownRef = React.useRef(null);
9990
+ const leadingRef = React.useRef(null);
9991
+ const trailingRef = React.useRef(null);
9743
9992
  const menuRef = React.useRef(null);
9993
+ const reducedMotion = useReducedMotion();
9744
9994
  const menuState = reactStately.useMenuTriggerState({});
9745
- const { buttonProps: primaryButtonProps } = reactAria.useButton(
9995
+ const [isLeadingPressed, setIsLeadingPressed] = React.useState(false);
9996
+ const handleLeadingPressStart = React.useCallback(() => setIsLeadingPressed(true), []);
9997
+ const handleLeadingPressEnd = React.useCallback(() => setIsLeadingPressed(false), []);
9998
+ const { isHovered: isLeadingHovered, hoverProps: leadingHoverProps } = reactAria.useHover({
9999
+ isDisabled
10000
+ });
10001
+ const { isFocusVisible: isLeadingFocusVisible, focusProps: leadingFocusProps } = reactAria.useFocusRing();
10002
+ const { buttonProps: leadingButtonProps } = reactAria.useButton(
9746
10003
  {
9747
10004
  isDisabled,
9748
10005
  onPress: onPrimaryAction,
10006
+ onPressStart: handleLeadingPressStart,
10007
+ onPressEnd: handleLeadingPressEnd,
9749
10008
  elementType: "button"
9750
10009
  },
9751
- primaryRef
10010
+ leadingRef
9752
10011
  );
9753
- const handleDropdownPress = React.useCallback(() => {
10012
+ const [isTrailingPressed, setIsTrailingPressed] = React.useState(false);
10013
+ const handleTrailingPressStart = React.useCallback(() => setIsTrailingPressed(true), []);
10014
+ const handleTrailingPressEnd = React.useCallback(() => setIsTrailingPressed(false), []);
10015
+ const { isHovered: isTrailingHovered, hoverProps: trailingHoverProps } = reactAria.useHover({
10016
+ isDisabled
10017
+ });
10018
+ const { isFocusVisible: isTrailingFocusVisible, focusProps: trailingFocusProps } = reactAria.useFocusRing();
10019
+ const handleTrailingPress = React.useCallback(() => {
9754
10020
  if (menuState.isOpen) {
9755
10021
  menuState.close();
9756
10022
  } else {
9757
10023
  menuState.open();
9758
10024
  }
9759
10025
  }, [menuState]);
9760
- const { buttonProps: dropdownButtonProps } = reactAria.useButton(
10026
+ const { buttonProps: trailingButtonProps } = reactAria.useButton(
9761
10027
  {
9762
10028
  isDisabled,
9763
- onPress: handleDropdownPress,
10029
+ onPress: handleTrailingPress,
10030
+ onPressStart: handleTrailingPressStart,
10031
+ onPressEnd: handleTrailingPressEnd,
9764
10032
  elementType: "button"
9765
10033
  },
9766
- dropdownRef
10034
+ trailingRef
10035
+ );
10036
+ const { onMouseDown: handleLeadingRipple, ripples: leadingRipples } = useRipple({
10037
+ disabled: isDisabled
10038
+ });
10039
+ const { onMouseDown: handleTrailingRipple, ripples: trailingRipples } = useRipple({
10040
+ disabled: isDisabled
10041
+ });
10042
+ const onLeadingMouseDown = React.useCallback(
10043
+ (e) => {
10044
+ const ariaHandler = leadingButtonProps.onMouseDown;
10045
+ ariaHandler?.(e);
10046
+ handleLeadingRipple(e);
10047
+ },
10048
+ [leadingButtonProps, handleLeadingRipple]
10049
+ );
10050
+ const onTrailingMouseDown = React.useCallback(
10051
+ (e) => {
10052
+ const ariaHandler = trailingButtonProps.onMouseDown;
10053
+ ariaHandler?.(e);
10054
+ handleTrailingRipple(e);
10055
+ },
10056
+ [trailingButtonProps, handleTrailingRipple]
9767
10057
  );
9768
10058
  const handleMenuItemSelect = React.useCallback(
9769
10059
  (item) => {
@@ -9779,13 +10069,11 @@ var SplitButton = React.forwardRef(
9779
10069
  const handleGlobalKeyDown = (e) => {
9780
10070
  if (e.key === "Escape") {
9781
10071
  menuState.close();
9782
- dropdownRef.current?.focus();
10072
+ trailingRef.current?.focus();
9783
10073
  }
9784
10074
  };
9785
10075
  document.addEventListener("keydown", handleGlobalKeyDown);
9786
- return () => {
9787
- document.removeEventListener("keydown", handleGlobalKeyDown);
9788
- };
10076
+ return () => document.removeEventListener("keydown", handleGlobalKeyDown);
9789
10077
  }, [menuState, menuState.isOpen]);
9790
10078
  const handleMenuKeyDown = React.useCallback(
9791
10079
  (e) => {
@@ -9818,7 +10106,7 @@ var SplitButton = React.forwardRef(
9818
10106
  }
9819
10107
  case "Escape": {
9820
10108
  menuState.close();
9821
- dropdownRef.current?.focus();
10109
+ trailingRef.current?.focus();
9822
10110
  break;
9823
10111
  }
9824
10112
  }
@@ -9843,28 +10131,6 @@ var SplitButton = React.forwardRef(
9843
10131
  },
9844
10132
  [menuState]
9845
10133
  );
9846
- const { onMouseDown: handlePrimaryRipple, ripples: primaryRipples } = useRipple({
9847
- disabled: isDisabled
9848
- });
9849
- const { onMouseDown: handleDropdownRipple, ripples: dropdownRipples } = useRipple({
9850
- disabled: isDisabled
9851
- });
9852
- const onPrimaryMouseDown = React.useCallback(
9853
- (e) => {
9854
- const ariaHandler = primaryButtonProps.onMouseDown;
9855
- ariaHandler?.(e);
9856
- handlePrimaryRipple(e);
9857
- },
9858
- [primaryButtonProps, handlePrimaryRipple]
9859
- );
9860
- const onDropdownMouseDown = React.useCallback(
9861
- (e) => {
9862
- const ariaHandler = dropdownButtonProps.onMouseDown;
9863
- ariaHandler?.(e);
9864
- handleDropdownRipple(e);
9865
- },
9866
- [dropdownButtonProps, handleDropdownRipple]
9867
- );
9868
10134
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative inline-flex", children: [
9869
10135
  /* @__PURE__ */ jsxRuntime.jsxs(
9870
10136
  "div",
@@ -9872,63 +10138,81 @@ var SplitButton = React.forwardRef(
9872
10138
  ref: forwardedRef,
9873
10139
  role: "group",
9874
10140
  "aria-label": ariaLabel ?? `${primaryLabel} split button`,
9875
- className: cn(splitButtonContainerVariants({ variant, size, isDisabled }), className),
10141
+ className: cn(splitButtonContainerVariants(), className),
9876
10142
  children: [
9877
10143
  /* @__PURE__ */ jsxRuntime.jsxs(
9878
10144
  "button",
9879
10145
  {
9880
- ...primaryButtonProps,
9881
- ref: primaryRef,
10146
+ ...reactAria.mergeProps(leadingButtonProps, leadingHoverProps, leadingFocusProps),
10147
+ ref: leadingRef,
9882
10148
  type: "button",
9883
10149
  tabIndex: isDisabled ? -1 : 0,
9884
- onMouseDown: onPrimaryMouseDown,
9885
- className: splitButtonPrimaryVariants({ variant, size }),
10150
+ onMouseDown: onLeadingMouseDown,
10151
+ ...getInteractionDataAttributes({
10152
+ isHovered: isLeadingHovered,
10153
+ isFocusVisible: isLeadingFocusVisible,
10154
+ isPressed: isLeadingPressed,
10155
+ isDisabled
10156
+ }),
10157
+ className: splitButtonLeadingVariants({ variant, size }),
9886
10158
  children: [
9887
10159
  /* @__PURE__ */ jsxRuntime.jsx(
9888
10160
  "span",
9889
10161
  {
9890
10162
  "data-testid": "primary-state-layer",
9891
10163
  "aria-hidden": "true",
9892
- className: cn(
9893
- "pointer-events-none absolute inset-0 bg-current opacity-0",
9894
- "duration-spring-standard-fast-effects ease-spring-standard-fast-effects transition-opacity",
9895
- "group-hover/primary:opacity-8"
9896
- )
10164
+ className: splitButtonStateLayerVariants({ variant, groupScope: "leading" })
9897
10165
  }
9898
10166
  ),
9899
- primaryRipples,
9900
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "relative z-10", children: primaryLabel })
10167
+ leadingRipples,
10168
+ /* @__PURE__ */ jsxRuntime.jsx(
10169
+ "span",
10170
+ {
10171
+ "aria-hidden": "true",
10172
+ className: splitButtonFocusRingVariants({ groupScope: "leading" })
10173
+ }
10174
+ ),
10175
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: splitButtonLabelVariants(), children: primaryLabel })
9901
10176
  ]
9902
10177
  }
9903
10178
  ),
9904
- /* @__PURE__ */ jsxRuntime.jsx("span", { "data-testid": "split-button-divider", "aria-hidden": "true" }),
9905
10179
  /* @__PURE__ */ jsxRuntime.jsxs(
9906
10180
  "button",
9907
10181
  {
9908
- ...dropdownButtonProps,
9909
- ref: dropdownRef,
10182
+ ...reactAria.mergeProps(trailingButtonProps, trailingHoverProps, trailingFocusProps),
10183
+ ref: trailingRef,
9910
10184
  type: "button",
9911
10185
  tabIndex: isDisabled ? -1 : 0,
9912
10186
  "aria-haspopup": "menu",
9913
10187
  "aria-expanded": menuState.isOpen,
9914
10188
  "aria-label": `${primaryLabel} options, expand`,
9915
- onMouseDown: onDropdownMouseDown,
9916
- className: splitButtonDropdownVariants({ variant, size }),
10189
+ onMouseDown: onTrailingMouseDown,
10190
+ ...getInteractionDataAttributes({
10191
+ isHovered: isTrailingHovered,
10192
+ isFocusVisible: isTrailingFocusVisible,
10193
+ isPressed: isTrailingPressed,
10194
+ isSelected: menuState.isOpen,
10195
+ isDisabled
10196
+ }),
10197
+ className: splitButtonTrailingVariants({ variant, size }),
9917
10198
  children: [
9918
10199
  /* @__PURE__ */ jsxRuntime.jsx(
9919
10200
  "span",
9920
10201
  {
9921
10202
  "data-testid": "dropdown-state-layer",
9922
10203
  "aria-hidden": "true",
9923
- className: cn(
9924
- "pointer-events-none absolute inset-0 bg-current opacity-0",
9925
- "duration-spring-standard-fast-effects ease-spring-standard-fast-effects transition-opacity",
9926
- "group-hover/dropdown:opacity-8"
9927
- )
10204
+ className: splitButtonStateLayerVariants({ variant, groupScope: "trailing" })
10205
+ }
10206
+ ),
10207
+ trailingRipples,
10208
+ /* @__PURE__ */ jsxRuntime.jsx(
10209
+ "span",
10210
+ {
10211
+ "aria-hidden": "true",
10212
+ className: splitButtonFocusRingVariants({ groupScope: "trailing" })
9928
10213
  }
9929
10214
  ),
9930
- dropdownRipples,
9931
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "relative z-10", children: /* @__PURE__ */ jsxRuntime.jsx(ChevronIcon, { isOpen: menuState.isOpen }) })
10215
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: splitButtonIconVariants({ size }), children: /* @__PURE__ */ jsxRuntime.jsx(ChevronIcon, { isOpen: menuState.isOpen, reducedMotion }) })
9932
10216
  ]
9933
10217
  }
9934
10218
  )
@@ -9942,10 +10226,7 @@ var SplitButton = React.forwardRef(
9942
10226
  role: "menu",
9943
10227
  "aria-label": `${primaryLabel} options`,
9944
10228
  onKeyDown: handleMenuKeyDown,
9945
- className: cn(
9946
- "bg-surface-container absolute top-full right-0 z-50 mt-1 min-w-40 rounded-md py-2",
9947
- "shadow-elevation-2"
9948
- ),
10229
+ className: splitButtonMenuVariants(),
9949
10230
  children: items.map((item) => /* @__PURE__ */ jsxRuntime.jsx(
9950
10231
  "li",
9951
10232
  {
@@ -9954,11 +10235,7 @@ var SplitButton = React.forwardRef(
9954
10235
  "aria-disabled": item.isDisabled ?? void 0,
9955
10236
  onClick: () => handleMenuItemSelect(item),
9956
10237
  onKeyDown: (e) => handleMenuItemKeyDown(e, item),
9957
- className: cn(
9958
- "text-body-large text-on-surface cursor-pointer px-4 py-2",
9959
- "hover:bg-on-surface/8",
9960
- item.isDisabled && "text-on-surface/38 pointer-events-none"
9961
- ),
10238
+ className: splitButtonMenuItemVariants({ isDisabled: item.isDisabled ?? false }),
9962
10239
  children: item.label
9963
10240
  },
9964
10241
  item.label
@@ -9978,32 +10255,32 @@ var SplitButtonHeadless = React.forwardRef(
9978
10255
  "aria-label": ariaLabel,
9979
10256
  className
9980
10257
  }, forwardedRef) => {
9981
- const primaryRef = React.useRef(null);
9982
- const dropdownRef = React.useRef(null);
10258
+ const leadingRef = React.useRef(null);
10259
+ const trailingRef = React.useRef(null);
9983
10260
  const menuRef = React.useRef(null);
9984
10261
  const menuState = reactStately.useMenuTriggerState({});
9985
- const { buttonProps: primaryButtonProps } = reactAria.useButton(
10262
+ const { buttonProps: leadingButtonProps } = reactAria.useButton(
9986
10263
  {
9987
10264
  isDisabled,
9988
10265
  onPress: onPrimaryAction,
9989
10266
  elementType: "button"
9990
10267
  },
9991
- primaryRef
10268
+ leadingRef
9992
10269
  );
9993
- const handleDropdownPress = React.useCallback(() => {
10270
+ const handleTrailingPress = React.useCallback(() => {
9994
10271
  if (menuState.isOpen) {
9995
10272
  menuState.close();
9996
10273
  } else {
9997
10274
  menuState.open();
9998
10275
  }
9999
10276
  }, [menuState]);
10000
- const { buttonProps: dropdownButtonProps } = reactAria.useButton(
10277
+ const { buttonProps: trailingButtonProps } = reactAria.useButton(
10001
10278
  {
10002
10279
  isDisabled,
10003
- onPress: handleDropdownPress,
10280
+ onPress: handleTrailingPress,
10004
10281
  elementType: "button"
10005
10282
  },
10006
- dropdownRef
10283
+ trailingRef
10007
10284
  );
10008
10285
  const handleMenuItemSelect = React.useCallback(
10009
10286
  (item) => {
@@ -10019,13 +10296,11 @@ var SplitButtonHeadless = React.forwardRef(
10019
10296
  const handleGlobalKeyDown = (e) => {
10020
10297
  if (e.key === "Escape") {
10021
10298
  menuState.close();
10022
- dropdownRef.current?.focus();
10299
+ trailingRef.current?.focus();
10023
10300
  }
10024
10301
  };
10025
10302
  document.addEventListener("keydown", handleGlobalKeyDown);
10026
- return () => {
10027
- document.removeEventListener("keydown", handleGlobalKeyDown);
10028
- };
10303
+ return () => document.removeEventListener("keydown", handleGlobalKeyDown);
10029
10304
  }, [menuState, menuState.isOpen]);
10030
10305
  const handleMenuKeyDown = React.useCallback(
10031
10306
  (e) => {
@@ -10058,7 +10333,7 @@ var SplitButtonHeadless = React.forwardRef(
10058
10333
  }
10059
10334
  case "Escape": {
10060
10335
  menuState.close();
10061
- dropdownRef.current?.focus();
10336
+ trailingRef.current?.focus();
10062
10337
  break;
10063
10338
  }
10064
10339
  }
@@ -10094,19 +10369,18 @@ var SplitButtonHeadless = React.forwardRef(
10094
10369
  /* @__PURE__ */ jsxRuntime.jsx(
10095
10370
  "button",
10096
10371
  {
10097
- ...primaryButtonProps,
10098
- ref: primaryRef,
10372
+ ...leadingButtonProps,
10373
+ ref: leadingRef,
10099
10374
  type: "button",
10100
10375
  tabIndex: isDisabled ? -1 : 0,
10101
10376
  children: primaryLabel
10102
10377
  }
10103
10378
  ),
10104
- /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true" }),
10105
10379
  /* @__PURE__ */ jsxRuntime.jsx(
10106
10380
  "button",
10107
10381
  {
10108
- ...dropdownButtonProps,
10109
- ref: dropdownRef,
10382
+ ...trailingButtonProps,
10383
+ ref: trailingRef,
10110
10384
  type: "button",
10111
10385
  tabIndex: isDisabled ? -1 : 0,
10112
10386
  "aria-haspopup": "menu",
@@ -16376,8 +16650,14 @@ exports.sliderHandleVariants = sliderHandleVariants;
16376
16650
  exports.sliderInactiveTrackVariants = sliderInactiveTrackVariants;
16377
16651
  exports.sliderTrackLayoutVariants = sliderTrackLayoutVariants;
16378
16652
  exports.splitButtonContainerVariants = splitButtonContainerVariants;
16379
- exports.splitButtonDropdownVariants = splitButtonDropdownVariants;
16380
- exports.splitButtonPrimaryVariants = splitButtonPrimaryVariants;
16653
+ exports.splitButtonFocusRingVariants = splitButtonFocusRingVariants;
16654
+ exports.splitButtonIconVariants = splitButtonIconVariants;
16655
+ exports.splitButtonLabelVariants = splitButtonLabelVariants;
16656
+ exports.splitButtonLeadingVariants = splitButtonLeadingVariants;
16657
+ exports.splitButtonMenuItemVariants = splitButtonMenuItemVariants;
16658
+ exports.splitButtonMenuVariants = splitButtonMenuVariants;
16659
+ exports.splitButtonStateLayerVariants = splitButtonStateLayerVariants;
16660
+ exports.splitButtonTrailingVariants = splitButtonTrailingVariants;
16381
16661
  exports.splitButtonVariants = splitButtonVariants;
16382
16662
  exports.supportingTextVariants = supportingTextVariants;
16383
16663
  exports.timeInputFieldVariants = timeInputFieldVariants;