@bug-on/m3-expressive 1.2.2 → 1.2.4

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
@@ -6749,6 +6749,7 @@ var ButtonComponent = React61__namespace.forwardRef(
6749
6749
  loading = false,
6750
6750
  loadingVariant = "loading-indicator",
6751
6751
  asChild = false,
6752
+ fullWidth = false,
6752
6753
  outlineWidth,
6753
6754
  children,
6754
6755
  onClick,
@@ -6771,6 +6772,7 @@ var ButtonComponent = React61__namespace.forwardRef(
6771
6772
  "loading",
6772
6773
  "loadingVariant",
6773
6774
  "asChild",
6775
+ "fullWidth",
6774
6776
  "outlineWidth",
6775
6777
  "children",
6776
6778
  "onClick",
@@ -6850,7 +6852,8 @@ var ButtonComponent = React61__namespace.forwardRef(
6850
6852
  [loading, onClick, onKeyDown]
6851
6853
  );
6852
6854
  const buttonClassName = cn(
6853
- "relative w-fit shrink-0 inline-flex flex-row items-center justify-center",
6855
+ "relative inline-flex flex-row items-center justify-center",
6856
+ fullWidth ? "w-full" : "w-fit shrink-0",
6854
6857
  "whitespace-nowrap select-none cursor-pointer",
6855
6858
  "transition-[background-color,color,border-color,box-shadow,opacity,filter] duration-200",
6856
6859
  "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-m3-primary focus-visible:ring-offset-2",
@@ -8036,7 +8039,9 @@ var FABComponent = React61__namespace.forwardRef(
8036
8039
  asChild = false,
8037
8040
  onClick,
8038
8041
  onKeyDown,
8039
- "aria-label": ariaLabel
8042
+ "aria-label": ariaLabel,
8043
+ layout,
8044
+ layoutId
8040
8045
  } = _b, restProps = __objRest(_b, [
8041
8046
  "className",
8042
8047
  "style",
@@ -8052,7 +8057,9 @@ var FABComponent = React61__namespace.forwardRef(
8052
8057
  "asChild",
8053
8058
  "onClick",
8054
8059
  "onKeyDown",
8055
- "aria-label"
8060
+ "aria-label",
8061
+ "layout",
8062
+ "layoutId"
8056
8063
  ]);
8057
8064
  var _a2, _b2, _c, _d;
8058
8065
  const colors = (_a2 = COLOR_CLASSES2[colorStyle]) != null ? _a2 : COLOR_CLASSES2.primary;
@@ -8093,7 +8100,9 @@ var FABComponent = React61__namespace.forwardRef(
8093
8100
  /* @__PURE__ */ jsxRuntime.jsx(Ripple, { ripples, onRippleDone: removeRipple }),
8094
8101
  /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { mode: "wait", initial: false, children: loading ? /* @__PURE__ */ jsxRuntime.jsx(
8095
8102
  react.m.span,
8096
- __spreadProps(__spreadValues({}, ICON_SPAN_VARIANTS), {
8103
+ __spreadProps(__spreadValues({
8104
+ layout: "position"
8105
+ }, ICON_SPAN_VARIANTS), {
8097
8106
  transition: SPRING_TRANSITION,
8098
8107
  className: cn(
8099
8108
  "flex items-center justify-center shrink-0",
@@ -8120,7 +8129,9 @@ var FABComponent = React61__namespace.forwardRef(
8120
8129
  "loading"
8121
8130
  ) : /* @__PURE__ */ jsxRuntime.jsx(
8122
8131
  react.m.span,
8123
- __spreadProps(__spreadValues({}, ICON_SPAN_VARIANTS), {
8132
+ __spreadProps(__spreadValues({
8133
+ layout: "position"
8134
+ }, ICON_SPAN_VARIANTS), {
8124
8135
  transition: SPRING_TRANSITION,
8125
8136
  "aria-hidden": "true",
8126
8137
  className: cn(
@@ -8134,10 +8145,15 @@ var FABComponent = React61__namespace.forwardRef(
8134
8145
  /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { initial: false, children: extended && labelContent && /* @__PURE__ */ jsxRuntime.jsx(
8135
8146
  react.m.span,
8136
8147
  {
8148
+ layout: "position",
8137
8149
  initial: { width: 0, opacity: 0 },
8138
8150
  animate: { width: "auto", opacity: 1 },
8139
8151
  exit: { width: 0, opacity: 0 },
8140
- transition: SPRING_TRANSITION,
8152
+ transition: {
8153
+ opacity: { duration: 0.15, ease: "linear" },
8154
+ width: SPRING_TRANSITION,
8155
+ layout: SPRING_TRANSITION
8156
+ },
8141
8157
  className: "overflow-hidden whitespace-nowrap ml-3",
8142
8158
  children: labelContent
8143
8159
  },
@@ -8154,7 +8170,7 @@ var FABComponent = React61__namespace.forwardRef(
8154
8170
  colors.text,
8155
8171
  lowered ? "shadow-sm" : colors.shadow,
8156
8172
  (_d = SIZE_STYLES[size]) != null ? _d : "h-14 w-14",
8157
- extended && "w-auto px-6",
8173
+ extended && "w-auto pl-4 pr-6",
8158
8174
  SIZE_TEXT_CLASS[size],
8159
8175
  loading && "pointer-events-none opacity-75 cursor-not-allowed",
8160
8176
  className
@@ -8185,6 +8201,8 @@ var FABComponent = React61__namespace.forwardRef(
8185
8201
  __spreadProps(__spreadValues({
8186
8202
  ref,
8187
8203
  type: "button",
8204
+ layout: layout !== void 0 ? layout : true,
8205
+ layoutId,
8188
8206
  "aria-label": computedAriaLabel,
8189
8207
  "aria-busy": loading || void 0,
8190
8208
  "aria-disabled": loading || restProps.disabled,
@@ -8203,7 +8221,8 @@ var FABComponent = React61__namespace.forwardRef(
8203
8221
  transition: {
8204
8222
  borderRadius: SPRING_TRANSITION_FAST,
8205
8223
  scale: SPRING_TRANSITION,
8206
- opacity: { duration: 0.25, ease: "easeOut" }
8224
+ opacity: { duration: 0.25, ease: "easeOut" },
8225
+ layout: SPRING_TRANSITION
8207
8226
  },
8208
8227
  className: containerClassName
8209
8228
  }, restProps), {
@@ -15782,6 +15801,23 @@ var ListItemImpl = React61__namespace.forwardRef(
15782
15801
  );
15783
15802
  ListItemImpl.displayName = "ListItem";
15784
15803
  var ListItem = React61__namespace.memo(ListItemImpl);
15804
+
15805
+ // src/ui/navigation/navigation-shape-utils.ts
15806
+ function getNavigationShapeStyle(shape, width = 56, height = 56) {
15807
+ if (!shape || shape === "pill" || shape === "circle") {
15808
+ return void 0;
15809
+ }
15810
+ const polygon = MD3Shapes[shape];
15811
+ if (!polygon) {
15812
+ return void 0;
15813
+ }
15814
+ return {
15815
+ clipPath: toClipPath(polygon, width, height)
15816
+ };
15817
+ }
15818
+ function isSquareShape(shape) {
15819
+ return Boolean(shape && shape !== "pill");
15820
+ }
15785
15821
  var NavigationBarContext = React61__namespace.createContext({ variant: "flexible" });
15786
15822
  function cloneIconWithFill(icon, selected) {
15787
15823
  if (!React61__namespace.isValidElement(icon)) return icon;
@@ -15793,16 +15829,23 @@ function cloneIconWithFill(icon, selected) {
15793
15829
  }
15794
15830
  return icon;
15795
15831
  }
15796
- function ActivePill() {
15832
+ function ActivePill({
15833
+ shape = "pill",
15834
+ width = 56,
15835
+ height = 32
15836
+ }) {
15797
15837
  const { activeIndicatorTransition } = React61__namespace.useContext(NavigationBarContext);
15838
+ const shapeStyle = getNavigationShapeStyle(shape, width, height);
15798
15839
  return /* @__PURE__ */ jsxRuntime.jsx(
15799
15840
  react.m.div,
15800
15841
  {
15801
- className: "absolute inset-0 bg-m3-secondary-container pointer-events-none",
15802
- style: {
15803
- borderRadius: 9999,
15842
+ className: cn(
15843
+ "bg-m3-secondary-container pointer-events-none",
15844
+ shapeStyle ? "absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 rounded-none" : shape === "circle" ? "absolute inset-0 rounded-full" : "absolute inset-0 rounded-full"
15845
+ ),
15846
+ style: __spreadValues(__spreadValues({
15804
15847
  zIndex: 0
15805
- },
15848
+ }, shapeStyle ? { width, height } : {}), shapeStyle),
15806
15849
  initial: { opacity: 0, scale: 0.5 },
15807
15850
  animate: { opacity: 1, scale: 1 },
15808
15851
  exit: { opacity: 0, scale: 0.5 },
@@ -15810,11 +15853,42 @@ function ActivePill() {
15810
15853
  }
15811
15854
  );
15812
15855
  }
15813
- function HoverStateLayer() {
15814
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 rounded-full bg-m3-on-surface opacity-0 group-hover:opacity-[0.08] group-focus-visible:opacity-[0.10] active:opacity-[0.10] transition-opacity duration-200 pointer-events-none z-0" });
15856
+ function HoverStateLayer({
15857
+ shape = "pill",
15858
+ width = 56,
15859
+ height = 32
15860
+ }) {
15861
+ const shapeStyle = getNavigationShapeStyle(shape, width, height);
15862
+ return /* @__PURE__ */ jsxRuntime.jsx(
15863
+ "div",
15864
+ {
15865
+ className: cn(
15866
+ "bg-m3-on-surface opacity-0 group-hover:opacity-[0.08] group-focus-visible:opacity-[0.10] active:opacity-[0.10] transition-opacity duration-200 pointer-events-none z-0",
15867
+ shapeStyle ? "absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 rounded-none" : shape === "circle" ? "absolute inset-0 rounded-full" : "absolute inset-0 rounded-[16px]"
15868
+ ),
15869
+ style: __spreadValues(__spreadValues({}, shapeStyle ? { width, height } : {}), shapeStyle)
15870
+ }
15871
+ );
15815
15872
  }
15816
- function RippleLayer({ ripples, onRippleDone }) {
15817
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 rounded-full overflow-hidden pointer-events-none z-0", children: /* @__PURE__ */ jsxRuntime.jsx(Ripple, { ripples, onRippleDone }) });
15873
+ function RippleLayer({
15874
+ ripples,
15875
+ onRippleDone,
15876
+ shape = "pill",
15877
+ width = 56,
15878
+ height = 32
15879
+ }) {
15880
+ const shapeStyle = getNavigationShapeStyle(shape, width, height);
15881
+ return /* @__PURE__ */ jsxRuntime.jsx(
15882
+ "div",
15883
+ {
15884
+ className: cn(
15885
+ "overflow-hidden pointer-events-none z-0",
15886
+ shapeStyle ? "absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 rounded-none" : shape === "circle" ? "absolute inset-0 rounded-full" : "absolute inset-0 rounded-[16px]"
15887
+ ),
15888
+ style: __spreadValues(__spreadValues({}, shapeStyle ? { width, height } : {}), shapeStyle),
15889
+ children: /* @__PURE__ */ jsxRuntime.jsx(Ripple, { ripples, onRippleDone })
15890
+ }
15891
+ );
15818
15892
  }
15819
15893
  function IconContainer({ selected, badge, children }) {
15820
15894
  return /* @__PURE__ */ jsxRuntime.jsxs(
@@ -15840,16 +15914,33 @@ var NavigationBarItemComponent = React61__namespace.forwardRef(
15840
15914
  onClick,
15841
15915
  disabled = false,
15842
15916
  badge,
15917
+ shape: shapeProp,
15918
+ shapeSize: shapeSizeProp,
15919
+ hideLabel = false,
15843
15920
  className,
15844
- "aria-label": ariaLabelProp
15921
+ "aria-label": ariaLabelProp,
15922
+ asChild = false,
15923
+ children
15845
15924
  }, ref) => {
15925
+ var _a, _b, _c;
15846
15926
  const {
15847
15927
  variant,
15848
15928
  itemLayout,
15929
+ shape: contextShape,
15930
+ labelVisibility: contextLabelVisibility,
15931
+ shapeSize: contextShapeSize,
15849
15932
  itemClassName: contextItemClassName
15850
15933
  } = React61__namespace.useContext(NavigationBarContext);
15934
+ const activeShape = (_a = shapeProp != null ? shapeProp : contextShape) != null ? _a : "pill";
15935
+ const isSquare = isSquareShape(activeShape);
15936
+ const resolvedShapeSize = (_b = shapeSizeProp != null ? shapeSizeProp : contextShapeSize) != null ? _b : 56;
15851
15937
  const isForcedHorizontal = itemLayout === "horizontal";
15852
15938
  const isResponsiveHorizontal = (variant === "flexible" || variant === "xr") && itemLayout === void 0;
15939
+ const shouldShowLabel = !hideLabel && (() => {
15940
+ if (contextLabelVisibility === "unlabeled") return false;
15941
+ if (contextLabelVisibility === "auto") return selected;
15942
+ return true;
15943
+ })();
15853
15944
  const { ripples, onPointerDown, removeRipple } = useRippleState({
15854
15945
  disabled
15855
15946
  });
@@ -15870,6 +15961,145 @@ var NavigationBarItemComponent = React61__namespace.forwardRef(
15870
15961
  [disabled, selected, onClick]
15871
15962
  );
15872
15963
  const filledIcon = cloneIconWithFill(icon, selected);
15964
+ const itemClassName = cn(
15965
+ "group relative flex cursor-pointer transition-colors duration-200 outline-none select-none h-full items-center justify-center min-w-0",
15966
+ variant === "xr" ? isResponsiveHorizontal ? "flex-1 min-[600px]:flex-initial min-[600px]:w-auto" : isForcedHorizontal ? "flex-initial w-auto" : "flex-1" : isForcedHorizontal ? "flex-initial w-auto" : "flex-1",
15967
+ disabled && "pointer-events-none opacity-[0.38]",
15968
+ contextItemClassName,
15969
+ className
15970
+ );
15971
+ const iconPillWidth = isSquare ? resolvedShapeSize : 56;
15972
+ const iconPillHeight = isSquare ? resolvedShapeSize : 32;
15973
+ if (asChild && children) {
15974
+ const child = React61__namespace.Children.only(children);
15975
+ const innerContent = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
15976
+ /* @__PURE__ */ jsxRuntime.jsxs(
15977
+ "div",
15978
+ {
15979
+ className: cn(
15980
+ "relative flex items-center justify-center flex-col gap-y-1 w-full px-1 py-1.5",
15981
+ isResponsiveHorizontal && "min-[600px]:flex-row min-[600px]:gap-y-0 min-[600px]:gap-x-1.5 min-[600px]:h-10 min-[600px]:px-4 min-[600px]:py-0 min-[600px]:rounded-full min-[600px]:w-auto",
15982
+ isForcedHorizontal && "flex-row gap-y-0 gap-x-1.5 h-10 px-4 py-0 rounded-full w-auto",
15983
+ // When label is hidden and not horizontal, remove bottom gap
15984
+ !shouldShowLabel && !isForcedHorizontal && "gap-y-0"
15985
+ ),
15986
+ children: [
15987
+ !isSquare && /* @__PURE__ */ jsxRuntime.jsxs(
15988
+ "div",
15989
+ {
15990
+ className: cn(
15991
+ "absolute inset-0 z-0 hidden",
15992
+ isResponsiveHorizontal && "min-[600px]:block",
15993
+ isForcedHorizontal && "block!"
15994
+ ),
15995
+ children: [
15996
+ /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { initial: false, children: selected && /* @__PURE__ */ jsxRuntime.jsx(ActivePill, { shape: activeShape, width: 56, height: 40 }) }),
15997
+ /* @__PURE__ */ jsxRuntime.jsx(HoverStateLayer, { shape: activeShape, width: 56, height: 40 }),
15998
+ /* @__PURE__ */ jsxRuntime.jsx(
15999
+ RippleLayer,
16000
+ {
16001
+ ripples,
16002
+ onRippleDone: removeRipple,
16003
+ shape: activeShape,
16004
+ width: 56,
16005
+ height: 40
16006
+ }
16007
+ )
16008
+ ]
16009
+ }
16010
+ ),
16011
+ /* @__PURE__ */ jsxRuntime.jsxs(
16012
+ "div",
16013
+ {
16014
+ className: cn(
16015
+ "relative flex items-center justify-center shrink-0 z-10",
16016
+ isSquare ? "mx-auto" : "h-8 w-14 mx-auto rounded-[16px]",
16017
+ !isSquare && isResponsiveHorizontal && "min-[600px]:size-6 min-[600px]:w-auto min-[600px]:h-auto",
16018
+ !isSquare && isForcedHorizontal && "size-6 w-auto h-auto"
16019
+ ),
16020
+ style: isSquare ? { width: resolvedShapeSize, height: resolvedShapeSize } : void 0,
16021
+ children: [
16022
+ /* @__PURE__ */ jsxRuntime.jsxs(
16023
+ "div",
16024
+ {
16025
+ className: cn(
16026
+ "absolute inset-0 z-0",
16027
+ !isSquare && isResponsiveHorizontal && "min-[600px]:hidden",
16028
+ !isSquare && isForcedHorizontal && "hidden"
16029
+ ),
16030
+ children: [
16031
+ /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { initial: false, children: selected && /* @__PURE__ */ jsxRuntime.jsx(
16032
+ ActivePill,
16033
+ {
16034
+ shape: activeShape,
16035
+ width: iconPillWidth,
16036
+ height: iconPillHeight
16037
+ }
16038
+ ) }),
16039
+ /* @__PURE__ */ jsxRuntime.jsx(
16040
+ HoverStateLayer,
16041
+ {
16042
+ shape: activeShape,
16043
+ width: iconPillWidth,
16044
+ height: iconPillHeight
16045
+ }
16046
+ ),
16047
+ /* @__PURE__ */ jsxRuntime.jsx(
16048
+ RippleLayer,
16049
+ {
16050
+ ripples,
16051
+ onRippleDone: removeRipple,
16052
+ shape: activeShape,
16053
+ width: iconPillWidth,
16054
+ height: iconPillHeight
16055
+ }
16056
+ )
16057
+ ]
16058
+ }
16059
+ ),
16060
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative z-10 flex size-6 items-center justify-center text-current", children: /* @__PURE__ */ jsxRuntime.jsx(IconContainer, { selected, badge, children: filledIcon }) })
16061
+ ]
16062
+ }
16063
+ ),
16064
+ label && /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { mode: "popLayout", initial: false, children: shouldShowLabel && /* @__PURE__ */ jsxRuntime.jsx(
16065
+ react.m.span,
16066
+ {
16067
+ initial: { opacity: 0, height: 0, scale: 0.85, y: -2 },
16068
+ animate: { opacity: 1, height: "auto", scale: 1, y: 0 },
16069
+ exit: { opacity: 0, height: 0, scale: 0.85, y: -2 },
16070
+ transition: SPRING_TRANSITION_EXPRESSIVE,
16071
+ className: cn(
16072
+ "z-10 transition-colors duration-200 truncate px-1 inline-block overflow-hidden",
16073
+ selected ? "text-m3-on-surface font-medium" : "text-m3-on-surface-variant font-medium",
16074
+ "text-[12px] leading-4 tracking-[0.5px]"
16075
+ ),
16076
+ children: (_c = child.props.children) != null ? _c : label
16077
+ },
16078
+ "nav-label"
16079
+ ) })
16080
+ ]
16081
+ }
16082
+ ),
16083
+ /* @__PURE__ */ jsxRuntime.jsx(TouchTarget, {})
16084
+ ] });
16085
+ return /* @__PURE__ */ jsxRuntime.jsx(
16086
+ reactSlot.Slot,
16087
+ {
16088
+ ref,
16089
+ role: "menuitem",
16090
+ "aria-current": selected ? "page" : void 0,
16091
+ "aria-disabled": disabled ? true : void 0,
16092
+ "aria-label": (
16093
+ // Always provide aria-label even when label is visually hidden
16094
+ ariaLabelProp || (typeof label === "string" ? label : void 0)
16095
+ ),
16096
+ onClick: handleClick,
16097
+ onPointerDown,
16098
+ className: itemClassName,
16099
+ children: React61__namespace.cloneElement(child, { children: innerContent })
16100
+ }
16101
+ );
16102
+ }
15873
16103
  return /* @__PURE__ */ jsxRuntime.jsxs(
15874
16104
  react.m.button,
15875
16105
  {
@@ -15878,16 +16108,13 @@ var NavigationBarItemComponent = React61__namespace.forwardRef(
15878
16108
  role: "menuitem",
15879
16109
  "aria-current": selected ? "page" : void 0,
15880
16110
  "aria-disabled": disabled ? true : void 0,
15881
- "aria-label": ariaLabelProp || (typeof label === "string" ? label : void 0),
16111
+ "aria-label": (
16112
+ // Always provide aria-label even when label is visually hidden
16113
+ ariaLabelProp || (typeof label === "string" ? label : void 0)
16114
+ ),
15882
16115
  onClick: handleClick,
15883
16116
  onPointerDown,
15884
- className: cn(
15885
- "group relative flex cursor-pointer transition-colors duration-200 outline-none select-none h-full items-center justify-center min-w-0",
15886
- variant === "xr" ? isResponsiveHorizontal ? "flex-1 min-[600px]:flex-initial min-[600px]:w-auto" : isForcedHorizontal ? "flex-initial w-auto" : "flex-1" : isForcedHorizontal ? "flex-initial w-auto" : "flex-1",
15887
- disabled && "pointer-events-none opacity-[0.38]",
15888
- contextItemClassName,
15889
- className
15890
- ),
16117
+ className: itemClassName,
15891
16118
  children: [
15892
16119
  /* @__PURE__ */ jsxRuntime.jsxs(
15893
16120
  "div",
@@ -15895,10 +16122,12 @@ var NavigationBarItemComponent = React61__namespace.forwardRef(
15895
16122
  className: cn(
15896
16123
  "relative flex items-center justify-center flex-col gap-y-1 w-full px-1 py-1.5",
15897
16124
  isResponsiveHorizontal && "min-[600px]:flex-row min-[600px]:gap-y-0 min-[600px]:gap-x-1.5 min-[600px]:h-10 min-[600px]:px-4 min-[600px]:py-0 min-[600px]:rounded-full min-[600px]:w-auto",
15898
- isForcedHorizontal && "flex-row gap-y-0 gap-x-1.5 h-10 px-4 py-0 rounded-full w-auto"
16125
+ isForcedHorizontal && "flex-row gap-y-0 gap-x-1.5 h-10 px-4 py-0 rounded-full w-auto",
16126
+ // When label is hidden and not horizontal, remove bottom gap
16127
+ !shouldShowLabel && !isForcedHorizontal && "gap-y-0"
15899
16128
  ),
15900
16129
  children: [
15901
- /* @__PURE__ */ jsxRuntime.jsxs(
16130
+ !isSquare && /* @__PURE__ */ jsxRuntime.jsxs(
15902
16131
  "div",
15903
16132
  {
15904
16133
  className: cn(
@@ -15907,9 +16136,18 @@ var NavigationBarItemComponent = React61__namespace.forwardRef(
15907
16136
  isForcedHorizontal && "block!"
15908
16137
  ),
15909
16138
  children: [
15910
- /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { initial: false, children: selected && /* @__PURE__ */ jsxRuntime.jsx(ActivePill, {}) }),
15911
- /* @__PURE__ */ jsxRuntime.jsx(HoverStateLayer, {}),
15912
- /* @__PURE__ */ jsxRuntime.jsx(RippleLayer, { ripples, onRippleDone: removeRipple })
16139
+ /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { initial: false, children: selected && /* @__PURE__ */ jsxRuntime.jsx(ActivePill, { shape: activeShape, width: 56, height: 40 }) }),
16140
+ /* @__PURE__ */ jsxRuntime.jsx(HoverStateLayer, { shape: activeShape, width: 56, height: 40 }),
16141
+ /* @__PURE__ */ jsxRuntime.jsx(
16142
+ RippleLayer,
16143
+ {
16144
+ ripples,
16145
+ onRippleDone: removeRipple,
16146
+ shape: activeShape,
16147
+ width: 56,
16148
+ height: 40
16149
+ }
16150
+ )
15913
16151
  ]
15914
16152
  }
15915
16153
  ),
@@ -15918,23 +16156,47 @@ var NavigationBarItemComponent = React61__namespace.forwardRef(
15918
16156
  {
15919
16157
  className: cn(
15920
16158
  "relative flex items-center justify-center shrink-0 z-10",
15921
- "h-8 w-16 mx-auto rounded-full",
15922
- isResponsiveHorizontal && "min-[600px]:size-6 min-[600px]:w-auto min-[600px]:h-auto",
15923
- isForcedHorizontal && "size-6 w-auto h-auto"
16159
+ isSquare ? "mx-auto" : "h-8 w-14 mx-auto rounded-[16px]",
16160
+ !isSquare && isResponsiveHorizontal && "min-[600px]:size-6 min-[600px]:w-auto min-[600px]:h-auto",
16161
+ !isSquare && isForcedHorizontal && "size-6 w-auto h-auto"
15924
16162
  ),
16163
+ style: isSquare ? { width: resolvedShapeSize, height: resolvedShapeSize } : void 0,
15925
16164
  children: [
15926
16165
  /* @__PURE__ */ jsxRuntime.jsxs(
15927
16166
  "div",
15928
16167
  {
15929
16168
  className: cn(
15930
16169
  "absolute inset-0 z-0",
15931
- isResponsiveHorizontal && "min-[600px]:hidden",
15932
- isForcedHorizontal && "hidden"
16170
+ !isSquare && isResponsiveHorizontal && "min-[600px]:hidden",
16171
+ !isSquare && isForcedHorizontal && "hidden"
15933
16172
  ),
15934
16173
  children: [
15935
- /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { initial: false, children: selected && /* @__PURE__ */ jsxRuntime.jsx(ActivePill, {}) }),
15936
- /* @__PURE__ */ jsxRuntime.jsx(HoverStateLayer, {}),
15937
- /* @__PURE__ */ jsxRuntime.jsx(RippleLayer, { ripples, onRippleDone: removeRipple })
16174
+ /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { initial: false, children: selected && /* @__PURE__ */ jsxRuntime.jsx(
16175
+ ActivePill,
16176
+ {
16177
+ shape: activeShape,
16178
+ width: iconPillWidth,
16179
+ height: iconPillHeight
16180
+ }
16181
+ ) }),
16182
+ /* @__PURE__ */ jsxRuntime.jsx(
16183
+ HoverStateLayer,
16184
+ {
16185
+ shape: activeShape,
16186
+ width: iconPillWidth,
16187
+ height: iconPillHeight
16188
+ }
16189
+ ),
16190
+ /* @__PURE__ */ jsxRuntime.jsx(
16191
+ RippleLayer,
16192
+ {
16193
+ ripples,
16194
+ onRippleDone: removeRipple,
16195
+ shape: activeShape,
16196
+ width: iconPillWidth,
16197
+ height: iconPillHeight
16198
+ }
16199
+ )
15938
16200
  ]
15939
16201
  }
15940
16202
  ),
@@ -15942,13 +16204,17 @@ var NavigationBarItemComponent = React61__namespace.forwardRef(
15942
16204
  ]
15943
16205
  }
15944
16206
  ),
15945
- /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { mode: "popLayout", children: /* @__PURE__ */ jsxRuntime.jsx(
15946
- "span",
16207
+ label && /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { mode: "popLayout", initial: false, children: shouldShowLabel && /* @__PURE__ */ jsxRuntime.jsx(
16208
+ react.m.span,
15947
16209
  {
16210
+ initial: { opacity: 0, height: 0, scale: 0.85, y: -2 },
16211
+ animate: { opacity: 1, height: "auto", scale: 1, y: 0 },
16212
+ exit: { opacity: 0, height: 0, scale: 0.85, y: -2 },
16213
+ transition: SPRING_TRANSITION_EXPRESSIVE,
15948
16214
  className: cn(
15949
- "z-10 transition-all duration-200 truncate px-1",
15950
- selected ? "text-m3-on-surface" : "text-m3-on-surface-variant",
15951
- "font-medium text-[12px] leading-4 tracking-[0.5px]"
16215
+ "z-10 transition-colors duration-200 truncate px-1 inline-block overflow-hidden",
16216
+ selected ? "text-m3-on-surface font-medium" : "text-m3-on-surface-variant font-medium",
16217
+ "text-[12px] leading-4 tracking-[0.5px]"
15952
16218
  ),
15953
16219
  children: label
15954
16220
  },
@@ -15970,9 +16236,9 @@ var navContainerVariants = classVarianceAuthority.cva(
15970
16236
  {
15971
16237
  variants: {
15972
16238
  variant: {
15973
- flexible: "bottom-0 left-0 right-0 w-full h-16 pb-safe",
15974
- baseline: "bottom-0 left-0 right-0 w-full h-20 pb-safe",
15975
- xr: "bottom-6 left-1/2 -translate-x-1/2 w-auto max-w-[calc(100%-2rem)] min-[600px]:max-w-fit h-20 min-[600px]:h-16 rounded-[48px] px-2"
16239
+ flexible: "bottom-0 left-0 right-0 w-full min-h-16 py-1 pb-safe",
16240
+ baseline: "bottom-0 left-0 right-0 w-full min-h-20 py-1 pb-safe",
16241
+ xr: "bottom-6 left-1/2 -translate-x-1/2 w-auto max-w-[calc(100%-2rem)] min-[600px]:max-w-fit min-h-20 min-[600px]:min-h-16 rounded-[48px] px-2 py-1"
15976
16242
  },
15977
16243
  position: {
15978
16244
  fixed: "fixed",
@@ -15994,6 +16260,9 @@ var NavigationBarComponent = React61__namespace.forwardRef(
15994
16260
  ({
15995
16261
  variant = "flexible",
15996
16262
  itemLayout,
16263
+ shape,
16264
+ labelVisibility,
16265
+ shapeSize,
15997
16266
  hideOnScroll = false,
15998
16267
  elevated = false,
15999
16268
  fixed = true,
@@ -16008,6 +16277,13 @@ var NavigationBarComponent = React61__namespace.forwardRef(
16008
16277
  const lastScrollY = React61__namespace.useRef(
16009
16278
  typeof window !== "undefined" ? window.scrollY : 0
16010
16279
  );
16280
+ const isSquare = isSquareShape(shape);
16281
+ const effectiveShapeSize = shapeSize != null ? shapeSize : isSquare ? 56 : 32;
16282
+ const computedMinHeight = React61__namespace.useMemo(() => {
16283
+ const baseHeight = variant === "baseline" ? 80 : 64;
16284
+ const requiredHeight = itemLayout === "horizontal" || labelVisibility === "unlabeled" ? effectiveShapeSize + 16 : effectiveShapeSize + 32;
16285
+ return Math.max(baseHeight, requiredHeight);
16286
+ }, [variant, itemLayout, labelVisibility, effectiveShapeSize]);
16011
16287
  React61__namespace.useEffect(() => {
16012
16288
  if (typeof window === "undefined" || !hideOnScroll) {
16013
16289
  setIsVisible(true);
@@ -16054,6 +16330,9 @@ var NavigationBarComponent = React61__namespace.forwardRef(
16054
16330
  value: {
16055
16331
  variant,
16056
16332
  itemLayout,
16333
+ shape,
16334
+ labelVisibility,
16335
+ shapeSize,
16057
16336
  activeIndicatorTransition,
16058
16337
  itemClassName
16059
16338
  },
@@ -16064,7 +16343,7 @@ var NavigationBarComponent = React61__namespace.forwardRef(
16064
16343
  role: "navigation",
16065
16344
  "aria-label": "Main navigation",
16066
16345
  className: navBaseClasses,
16067
- style,
16346
+ style: __spreadValues({ minHeight: computedMinHeight }, style),
16068
16347
  initial: false,
16069
16348
  animate: {
16070
16349
  y: isVisible ? "0%" : variant === "xr" ? "calc(100% + 40px)" : "100%"
@@ -16076,8 +16355,8 @@ var NavigationBarComponent = React61__namespace.forwardRef(
16076
16355
  role: "menubar",
16077
16356
  "aria-orientation": "horizontal",
16078
16357
  className: cn(
16079
- "flex w-full h-full mx-auto",
16080
- variant === "xr" ? "gap-0 min-[600px]:gap-1.5 items-center justify-center px-1" : "max-w-7xl gap-1.5"
16358
+ "flex w-full h-full mx-auto items-center justify-center",
16359
+ variant === "xr" ? "gap-0 min-[600px]:gap-1.5 px-1" : "max-w-7xl gap-1.5"
16081
16360
  ),
16082
16361
  children
16083
16362
  }
@@ -16090,7 +16369,11 @@ var NavigationBarComponent = React61__namespace.forwardRef(
16090
16369
  );
16091
16370
  NavigationBarComponent.displayName = "NavigationBar";
16092
16371
  var NavigationBar = React61__namespace.memo(NavigationBarComponent);
16093
- var NavigationRailContext = React61__namespace.createContext({ variant: "collapsed", labelVisibility: "labeled" });
16372
+ var NavigationRailContext = React61__namespace.createContext({
16373
+ variant: "collapsed",
16374
+ labelVisibility: "labeled",
16375
+ activeIndicatorWidth: "hug"
16376
+ });
16094
16377
  var MD3_MODAL_TRANSITION = {
16095
16378
  type: "tween",
16096
16379
  ease: [0.05, 0.7, 0.1, 1],
@@ -16101,9 +16384,9 @@ var railContainerVariants = classVarianceAuthority.cva(
16101
16384
  {
16102
16385
  variants: {
16103
16386
  variant: {
16104
- collapsed: "items-center h-full pt-11 pb-4 shadow-none bg-m3-surface rounded-none",
16105
- expanded: "items-start h-full pt-11 pb-4 shadow-none bg-m3-surface rounded-none",
16106
- modal: "bg-m3-surface shadow-lg rounded-r-[var(--m3-shape-corner-large)] h-full pt-11 pb-4",
16387
+ collapsed: "items-center h-full pt-11 pb-14 shadow-none bg-m3-surface rounded-none",
16388
+ expanded: "items-start h-full pt-11 pb-14 shadow-none bg-m3-surface rounded-none",
16389
+ modal: "bg-m3-surface shadow-lg rounded-r-[var(--m3-shape-corner-large)] h-full pt-11 pb-14",
16107
16390
  xr: "h-fit py-5 rounded-[48px] shadow-xl bg-m3-surface border border-white/5"
16108
16391
  },
16109
16392
  narrow: {
@@ -16146,14 +16429,28 @@ function setFocusedItem(items, index) {
16146
16429
  target.focus();
16147
16430
  }
16148
16431
  }
16149
- function ActivePill2({ layoutId, disableInitial = false }) {
16432
+ function ActivePill2({
16433
+ layoutId,
16434
+ disableInitial = false,
16435
+ shape = "pill",
16436
+ width = 56,
16437
+ height = 32
16438
+ }) {
16150
16439
  const { activeIndicatorTransition } = React61__namespace.useContext(NavigationRailContext);
16440
+ const shapeStyle = getNavigationShapeStyle(shape, width, height);
16151
16441
  return /* @__PURE__ */ jsxRuntime.jsx(
16152
16442
  react.m.div,
16153
16443
  {
16154
16444
  layoutId,
16155
- className: "absolute inset-0 bg-m3-secondary-container pointer-events-none",
16156
- style: { borderRadius: 9999, zIndex: 0, originX: 0.5, originY: 0.5 },
16445
+ className: cn(
16446
+ "bg-m3-secondary-container pointer-events-none",
16447
+ shapeStyle ? "absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 rounded-none" : "absolute inset-0 rounded-full"
16448
+ ),
16449
+ style: __spreadValues(__spreadValues({
16450
+ zIndex: 0,
16451
+ originX: 0.5,
16452
+ originY: 0.5
16453
+ }, shapeStyle ? { width, height } : {}), shapeStyle),
16157
16454
  initial: disableInitial ? false : { opacity: 0, scale: 0.5 },
16158
16455
  animate: { opacity: 1, scale: 1 },
16159
16456
  exit: { opacity: 0, scale: 0.5, transition: { duration: 0.15 } },
@@ -16161,11 +16458,42 @@ function ActivePill2({ layoutId, disableInitial = false }) {
16161
16458
  }
16162
16459
  );
16163
16460
  }
16164
- function HoverStateLayer2() {
16165
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 rounded-full bg-m3-on-surface opacity-0 group-hover:opacity-[0.08] transition-opacity duration-200 pointer-events-none z-0" });
16461
+ function HoverStateLayer2({
16462
+ shape = "pill",
16463
+ width = 56,
16464
+ height = 32
16465
+ }) {
16466
+ const shapeStyle = getNavigationShapeStyle(shape, width, height);
16467
+ return /* @__PURE__ */ jsxRuntime.jsx(
16468
+ "div",
16469
+ {
16470
+ className: cn(
16471
+ "bg-m3-on-surface opacity-0 group-hover:opacity-[0.08] transition-opacity duration-200 pointer-events-none z-0",
16472
+ shapeStyle ? "absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 rounded-none" : "absolute inset-0 rounded-full"
16473
+ ),
16474
+ style: __spreadValues(__spreadValues({}, shapeStyle ? { width, height } : {}), shapeStyle)
16475
+ }
16476
+ );
16166
16477
  }
16167
- function RippleLayer2({ ripples, onRippleDone }) {
16168
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 rounded-full overflow-hidden pointer-events-none z-0", children: /* @__PURE__ */ jsxRuntime.jsx(Ripple, { ripples, onRippleDone }) });
16478
+ function RippleLayer2({
16479
+ ripples,
16480
+ onRippleDone,
16481
+ shape = "pill",
16482
+ width = 56,
16483
+ height = 32
16484
+ }) {
16485
+ const shapeStyle = getNavigationShapeStyle(shape, width, height);
16486
+ return /* @__PURE__ */ jsxRuntime.jsx(
16487
+ "div",
16488
+ {
16489
+ className: cn(
16490
+ "overflow-hidden pointer-events-none z-0",
16491
+ shapeStyle ? "absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 rounded-none" : "absolute inset-0 rounded-full"
16492
+ ),
16493
+ style: __spreadValues(__spreadValues({}, shapeStyle ? { width, height } : {}), shapeStyle),
16494
+ children: /* @__PURE__ */ jsxRuntime.jsx(Ripple, { ripples, onRippleDone })
16495
+ }
16496
+ );
16169
16497
  }
16170
16498
  function IconContainer2({ selected, badge, children }) {
16171
16499
  return /* @__PURE__ */ jsxRuntime.jsxs(
@@ -16191,15 +16519,31 @@ var NavigationRailItemComponent = React61__namespace.forwardRef(
16191
16519
  onClick,
16192
16520
  disabled = false,
16193
16521
  badge,
16522
+ shape: shapeProp,
16523
+ shapeSize: shapeSizeProp,
16524
+ activeIndicatorWidth: activeIndicatorWidthProp,
16194
16525
  className,
16195
- "aria-label": ariaLabelProp
16526
+ "aria-label": ariaLabelProp,
16527
+ asChild = false,
16528
+ children
16196
16529
  }, ref) => {
16197
- const { variant, labelVisibility } = React61__namespace.useContext(
16198
- NavigationRailContext
16199
- );
16530
+ var _a, _b, _c, _d;
16531
+ const {
16532
+ variant,
16533
+ labelVisibility,
16534
+ shape: contextShape,
16535
+ shapeSize: contextShapeSize,
16536
+ activeIndicatorWidth: contextActiveIndicatorWidth
16537
+ } = React61__namespace.useContext(NavigationRailContext);
16538
+ const activeShape = (_a = shapeProp != null ? shapeProp : contextShape) != null ? _a : "pill";
16539
+ const isSquare = isSquareShape(activeShape);
16540
+ const resolvedShapeSize = (_b = shapeSizeProp != null ? shapeSizeProp : contextShapeSize) != null ? _b : 56;
16541
+ const activeIndicatorWidth = (_c = activeIndicatorWidthProp != null ? activeIndicatorWidthProp : contextActiveIndicatorWidth) != null ? _c : "hug";
16200
16542
  const isExpanded = variant === "expanded" || variant === "modal";
16201
16543
  const isModal = variant === "modal";
16202
16544
  const enableLayout = !isModal;
16545
+ const isExpandedPill = isExpanded && !isSquare;
16546
+ const expandedPillWidthClass = activeIndicatorWidth === "fill" ? "w-full" : "w-fit";
16203
16547
  const activePillId = `rail-pill-${React61__namespace.useId()}`;
16204
16548
  const { ripples, onPointerDown, removeRipple } = useRippleState({
16205
16549
  disabled
@@ -16217,6 +16561,138 @@ var NavigationRailItemComponent = React61__namespace.forwardRef(
16217
16561
  );
16218
16562
  const filledIcon = cloneIconWithFill2(icon, selected);
16219
16563
  const labelInitial = isModal ? false : { opacity: 0, x: isExpanded ? -12 : 0, y: isExpanded ? 0 : -8 };
16564
+ const itemClassName = cn(
16565
+ "group relative flex cursor-pointer transition-colors duration-200 outline-none select-none",
16566
+ "focus-visible:ring-2 focus-visible:ring-m3-primary focus-visible:ring-offset-2 rounded-full",
16567
+ disabled && "pointer-events-none opacity-[0.38]",
16568
+ isExpanded ? "w-full flex-row items-center px-3 h-14" : "w-full flex-col justify-center h-14",
16569
+ className
16570
+ );
16571
+ const iconPillWidth = isSquare ? resolvedShapeSize : 56;
16572
+ const iconPillHeight = isSquare ? resolvedShapeSize : 32;
16573
+ if (asChild && children) {
16574
+ const child = React61__namespace.Children.only(children);
16575
+ const innerContent = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
16576
+ /* @__PURE__ */ jsxRuntime.jsxs(
16577
+ react.m.div,
16578
+ {
16579
+ layout: enableLayout,
16580
+ className: cn(
16581
+ "relative flex z-10",
16582
+ isExpanded ? cn(
16583
+ "flex-row items-center h-14 px-4 gap-x-3 rounded-full",
16584
+ expandedPillWidthClass
16585
+ ) : "flex-col items-center justify-center w-full gap-y-1 rounded-full"
16586
+ ),
16587
+ children: [
16588
+ isExpandedPill && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
16589
+ /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { initial: false, children: selected && /* @__PURE__ */ jsxRuntime.jsx(
16590
+ ActivePill2,
16591
+ {
16592
+ layoutId: activePillId,
16593
+ disableInitial: isModal,
16594
+ shape: activeShape
16595
+ }
16596
+ ) }),
16597
+ /* @__PURE__ */ jsxRuntime.jsx(HoverStateLayer2, { shape: activeShape }),
16598
+ /* @__PURE__ */ jsxRuntime.jsx(
16599
+ RippleLayer2,
16600
+ {
16601
+ ripples,
16602
+ onRippleDone: removeRipple,
16603
+ shape: activeShape
16604
+ }
16605
+ )
16606
+ ] }),
16607
+ /* @__PURE__ */ jsxRuntime.jsxs(
16608
+ react.m.div,
16609
+ {
16610
+ layout: enableLayout,
16611
+ className: cn(
16612
+ "relative flex items-center justify-center shrink-0 z-10",
16613
+ isSquare ? "mx-auto" : isExpandedPill ? "size-6" : "h-8 w-14 mx-auto rounded-full"
16614
+ ),
16615
+ style: isSquare ? { width: resolvedShapeSize, height: resolvedShapeSize } : void 0,
16616
+ children: [
16617
+ !isExpandedPill && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
16618
+ /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { initial: false, children: selected && /* @__PURE__ */ jsxRuntime.jsx(
16619
+ ActivePill2,
16620
+ {
16621
+ layoutId: activePillId,
16622
+ disableInitial: isModal,
16623
+ shape: activeShape,
16624
+ width: iconPillWidth,
16625
+ height: iconPillHeight
16626
+ }
16627
+ ) }),
16628
+ /* @__PURE__ */ jsxRuntime.jsx(
16629
+ HoverStateLayer2,
16630
+ {
16631
+ shape: activeShape,
16632
+ width: iconPillWidth,
16633
+ height: iconPillHeight
16634
+ }
16635
+ ),
16636
+ /* @__PURE__ */ jsxRuntime.jsx(
16637
+ RippleLayer2,
16638
+ {
16639
+ ripples,
16640
+ onRippleDone: removeRipple,
16641
+ shape: activeShape,
16642
+ width: iconPillWidth,
16643
+ height: iconPillHeight
16644
+ }
16645
+ )
16646
+ ] }),
16647
+ /* @__PURE__ */ jsxRuntime.jsx(
16648
+ react.m.div,
16649
+ {
16650
+ layout: enableLayout ? "position" : false,
16651
+ className: "relative z-10 flex size-6 items-center justify-center text-current",
16652
+ children: /* @__PURE__ */ jsxRuntime.jsx(IconContainer2, { selected, badge, children: filledIcon })
16653
+ }
16654
+ )
16655
+ ]
16656
+ }
16657
+ ),
16658
+ /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { mode: "popLayout", children: showLabel && (label || child.props.children) && /* @__PURE__ */ jsxRuntime.jsx(
16659
+ react.m.span,
16660
+ {
16661
+ layout: enableLayout ? "position" : false,
16662
+ initial: labelInitial,
16663
+ animate: { opacity: 1, x: 0, y: 0 },
16664
+ exit: { opacity: 0, transition: { duration: 0.1 } },
16665
+ transition: SPRING_TRANSITION,
16666
+ className: cn(
16667
+ "z-10 transition-colors duration-200 whitespace-nowrap",
16668
+ selected ? isExpandedPill ? "text-m3-on-secondary-container font-medium" : "text-m3-on-surface font-medium" : "text-m3-on-surface-variant font-medium",
16669
+ isExpanded ? "text-sm tracking-wide text-left" : "text-xs tracking-wide"
16670
+ ),
16671
+ children: (_d = child.props.children) != null ? _d : label
16672
+ },
16673
+ "rail-label"
16674
+ ) })
16675
+ ]
16676
+ }
16677
+ ),
16678
+ /* @__PURE__ */ jsxRuntime.jsx(TouchTarget, {})
16679
+ ] });
16680
+ return /* @__PURE__ */ jsxRuntime.jsx(react.LazyMotion, { features: react.domMax, strict: true, children: /* @__PURE__ */ jsxRuntime.jsx(
16681
+ reactSlot.Slot,
16682
+ {
16683
+ ref,
16684
+ role: "menuitem",
16685
+ "aria-current": selected ? "page" : void 0,
16686
+ "aria-disabled": disabled ? true : void 0,
16687
+ "aria-label": ariaLabelProp || (typeof label === "string" ? label : void 0),
16688
+ onClick: handleClick,
16689
+ onPointerDown,
16690
+ className: itemClassName,
16691
+ tabIndex: -1,
16692
+ children: React61__namespace.cloneElement(child, { children: innerContent })
16693
+ }
16694
+ ) });
16695
+ }
16220
16696
  return /* @__PURE__ */ jsxRuntime.jsx(react.LazyMotion, { features: react.domMax, strict: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
16221
16697
  react.m.button,
16222
16698
  {
@@ -16229,13 +16705,7 @@ var NavigationRailItemComponent = React61__namespace.forwardRef(
16229
16705
  "aria-label": ariaLabelProp || (typeof label === "string" ? label : void 0),
16230
16706
  onClick: handleClick,
16231
16707
  onPointerDown,
16232
- className: cn(
16233
- "group relative flex cursor-pointer transition-colors duration-200 outline-none select-none",
16234
- "focus-visible:ring-2 focus-visible:ring-m3-primary focus-visible:ring-offset-2 rounded-full",
16235
- disabled && "pointer-events-none opacity-[0.38]",
16236
- isExpanded ? "w-full flex-row items-center px-3 h-14" : "w-full flex-col justify-center h-14",
16237
- className
16238
- ),
16708
+ className: itemClassName,
16239
16709
  tabIndex: -1,
16240
16710
  children: [
16241
16711
  /* @__PURE__ */ jsxRuntime.jsxs(
@@ -16244,31 +16714,71 @@ var NavigationRailItemComponent = React61__namespace.forwardRef(
16244
16714
  layout: enableLayout,
16245
16715
  className: cn(
16246
16716
  "relative flex z-10",
16247
- isExpanded ? "flex-row items-center w-fit h-14 px-4 gap-x-3 rounded-full" : "flex-col items-center justify-center w-full gap-y-1 rounded-full"
16717
+ isExpanded ? cn(
16718
+ "flex-row items-center h-14 px-4 gap-x-3 rounded-full",
16719
+ expandedPillWidthClass
16720
+ ) : "flex-col items-center justify-center w-full gap-y-1 rounded-full"
16248
16721
  ),
16249
16722
  children: [
16250
- isExpanded && /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { initial: false, children: selected && /* @__PURE__ */ jsxRuntime.jsx(
16251
- ActivePill2,
16252
- {
16253
- layoutId: activePillId,
16254
- disableInitial: isModal
16255
- }
16256
- ) }),
16257
- isExpanded && /* @__PURE__ */ jsxRuntime.jsx(HoverStateLayer2, {}),
16258
- isExpanded && /* @__PURE__ */ jsxRuntime.jsx(RippleLayer2, { ripples, onRippleDone: removeRipple }),
16723
+ isExpandedPill && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
16724
+ /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { initial: false, children: selected && /* @__PURE__ */ jsxRuntime.jsx(
16725
+ ActivePill2,
16726
+ {
16727
+ layoutId: activePillId,
16728
+ disableInitial: isModal,
16729
+ shape: activeShape
16730
+ }
16731
+ ) }),
16732
+ /* @__PURE__ */ jsxRuntime.jsx(HoverStateLayer2, { shape: activeShape }),
16733
+ /* @__PURE__ */ jsxRuntime.jsx(
16734
+ RippleLayer2,
16735
+ {
16736
+ ripples,
16737
+ onRippleDone: removeRipple,
16738
+ shape: activeShape
16739
+ }
16740
+ )
16741
+ ] }),
16259
16742
  /* @__PURE__ */ jsxRuntime.jsxs(
16260
16743
  react.m.div,
16261
16744
  {
16262
16745
  layout: enableLayout,
16263
16746
  className: cn(
16264
16747
  "relative flex items-center justify-center shrink-0 z-10",
16265
- isExpanded ? "size-6" : "h-8 w-14 mx-auto"
16748
+ isSquare ? "mx-auto" : isExpandedPill ? "size-6" : "h-8 w-14 mx-auto rounded-full"
16266
16749
  ),
16267
- style: { borderRadius: 9999 },
16750
+ style: isSquare ? { width: resolvedShapeSize, height: resolvedShapeSize } : void 0,
16268
16751
  children: [
16269
- !isExpanded && /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { initial: false, children: selected && /* @__PURE__ */ jsxRuntime.jsx(ActivePill2, { layoutId: activePillId }) }),
16270
- !isExpanded && /* @__PURE__ */ jsxRuntime.jsx(HoverStateLayer2, {}),
16271
- !isExpanded && /* @__PURE__ */ jsxRuntime.jsx(RippleLayer2, { ripples, onRippleDone: removeRipple }),
16752
+ !isExpandedPill && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
16753
+ /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { initial: false, children: selected && /* @__PURE__ */ jsxRuntime.jsx(
16754
+ ActivePill2,
16755
+ {
16756
+ layoutId: activePillId,
16757
+ disableInitial: isModal,
16758
+ shape: activeShape,
16759
+ width: iconPillWidth,
16760
+ height: iconPillHeight
16761
+ }
16762
+ ) }),
16763
+ /* @__PURE__ */ jsxRuntime.jsx(
16764
+ HoverStateLayer2,
16765
+ {
16766
+ shape: activeShape,
16767
+ width: iconPillWidth,
16768
+ height: iconPillHeight
16769
+ }
16770
+ ),
16771
+ /* @__PURE__ */ jsxRuntime.jsx(
16772
+ RippleLayer2,
16773
+ {
16774
+ ripples,
16775
+ onRippleDone: removeRipple,
16776
+ shape: activeShape,
16777
+ width: iconPillWidth,
16778
+ height: iconPillHeight
16779
+ }
16780
+ )
16781
+ ] }),
16272
16782
  /* @__PURE__ */ jsxRuntime.jsx(
16273
16783
  react.m.div,
16274
16784
  {
@@ -16290,8 +16800,8 @@ var NavigationRailItemComponent = React61__namespace.forwardRef(
16290
16800
  transition: SPRING_TRANSITION,
16291
16801
  className: cn(
16292
16802
  "z-10 transition-colors duration-200 whitespace-nowrap",
16293
- selected ? "text-m3-on-surface" : "text-m3-on-surface-variant",
16294
- isExpanded ? "text-sm font-medium tracking-wide text-left" : "text-xs font-medium tracking-wide"
16803
+ selected ? isExpandedPill ? "text-m3-on-secondary-container font-medium" : "text-m3-on-surface font-medium" : "text-m3-on-surface-variant font-medium",
16804
+ isExpanded ? "text-sm tracking-wide text-left" : "text-xs tracking-wide"
16295
16805
  ),
16296
16806
  children: label
16297
16807
  },
@@ -16351,6 +16861,9 @@ var NavigationRailComponent = React61__namespace.forwardRef(
16351
16861
  ({
16352
16862
  variant = "collapsed",
16353
16863
  labelVisibility = "labeled",
16864
+ shape,
16865
+ shapeSize,
16866
+ activeIndicatorWidth = "hug",
16354
16867
  header,
16355
16868
  fab,
16356
16869
  fabPlacement = "contained",
@@ -16364,6 +16877,7 @@ var NavigationRailComponent = React61__namespace.forwardRef(
16364
16877
  style
16365
16878
  }, ref) => {
16366
16879
  const isModal = variant === "modal";
16880
+ const isExpanded = variant === "expanded" || variant === "modal";
16367
16881
  const isXr = variant === "xr";
16368
16882
  const isSpatial = isXr && fabPlacement === "spatialized";
16369
16883
  const applyAnimation = !isXr || !isSpatial;
@@ -16405,10 +16919,12 @@ var NavigationRailComponent = React61__namespace.forwardRef(
16405
16919
  transition: isModal ? MD3_MODAL_TRANSITION : SPRING_TRANSITION,
16406
16920
  children: [
16407
16921
  (header || fab && !isSpatial) && /* @__PURE__ */ jsxRuntime.jsxs(
16408
- "div",
16922
+ react.m.div,
16409
16923
  {
16924
+ layout: true,
16410
16925
  className: cn(
16411
- "flex w-full flex-col items-center justify-start shrink-0 empty:hidden",
16926
+ "flex w-full flex-col justify-start shrink-0 empty:hidden",
16927
+ isExpanded ? "items-start px-3" : "items-center",
16412
16928
  navHeaderSpacing
16413
16929
  ),
16414
16930
  children: [
@@ -16474,6 +16990,9 @@ var NavigationRailComponent = React61__namespace.forwardRef(
16474
16990
  const contextValue = {
16475
16991
  variant,
16476
16992
  labelVisibility,
16993
+ shape,
16994
+ shapeSize,
16995
+ activeIndicatorWidth,
16477
16996
  activeIndicatorTransition
16478
16997
  };
16479
16998
  if (isModal) {
@@ -23211,6 +23730,12 @@ var BottomDockedToolbar = React61__namespace.forwardRef(
23211
23730
  BottomDockedToolbar.displayName = "BottomDockedToolbar";
23212
23731
 
23213
23732
  // src/ui/toolbar/toolbar-tokens.ts
23733
+ var TOOLBAR_SPRING_TRANSITION = {
23734
+ type: "spring",
23735
+ stiffness: 300,
23736
+ damping: 30,
23737
+ mass: 0.8
23738
+ };
23214
23739
  var FloatingToolbarTokens = {
23215
23740
  ContainerBetweenSpace: 4,
23216
23741
  ContainerHeight: 64};
@@ -23240,6 +23765,10 @@ var ToolbarToggleButtonTokens = {
23240
23765
  PaddingX: 16,
23241
23766
  Gap: 8
23242
23767
  };
23768
+ var ToolbarToggleButtonRadiusTokens = {
23769
+ pillRadius: 24,
23770
+ pressedRadius: 12
23771
+ };
23243
23772
  var ALIGNMENT_CLASS = {
23244
23773
  start: "justify-start",
23245
23774
  center: "justify-center",
@@ -23642,13 +24171,17 @@ var ToolbarIconButton = React61__namespace.forwardRef(
23642
24171
  toolbarSize = "default",
23643
24172
  selected,
23644
24173
  asChild,
23645
- className
24174
+ className,
24175
+ transition,
24176
+ whileTap
23646
24177
  } = _b, props = __objRest(_b, [
23647
24178
  "emphasis",
23648
24179
  "toolbarSize",
23649
24180
  "selected",
23650
24181
  "asChild",
23651
- "className"
24182
+ "className",
24183
+ "transition",
24184
+ "whileTap"
23652
24185
  ]);
23653
24186
  const context = useToolbarContext();
23654
24187
  const widthClass = TOOLBAR_ICON_BUTTON_WIDTH[toolbarSize];
@@ -23659,16 +24192,20 @@ var ToolbarIconButton = React61__namespace.forwardRef(
23659
24192
  } : {
23660
24193
  variant: "default"
23661
24194
  };
24195
+ const motionProps = asChild ? __spreadValues(__spreadValues({}, transition !== void 0 && { transition }), whileTap !== void 0 && { whileTap }) : {
24196
+ transition: transition != null ? transition : TOOLBAR_SPRING_TRANSITION,
24197
+ whileTap: whileTap != null ? whileTap : { scale: 0.95 }
24198
+ };
23662
24199
  return /* @__PURE__ */ jsxRuntime.jsx(
23663
24200
  IconButton,
23664
- __spreadValues(__spreadProps(__spreadValues({
24201
+ __spreadValues(__spreadProps(__spreadValues(__spreadValues({
23665
24202
  ref,
23666
24203
  asChild,
23667
24204
  colorStyle,
23668
24205
  size: "md",
23669
24206
  shape: "round",
23670
24207
  iconSize: ToolbarIconButtonTokens.IconSize
23671
- }, iconButtonProps), {
24208
+ }, motionProps), iconButtonProps), {
23672
24209
  className: cn(
23673
24210
  "h-[48px]",
23674
24211
  widthClass,
@@ -23778,29 +24315,34 @@ var ToolbarToggleButton = React61__namespace.forwardRef(
23778
24315
  selected = false,
23779
24316
  icon,
23780
24317
  children,
23781
- pressScale = 0.95,
23782
- pressBounceOffset = 6,
24318
+ pressExpand = true,
24319
+ pressExpandRatio = 0.06,
23783
24320
  ripple = true,
23784
24321
  asChild = false,
23785
24322
  className,
23786
24323
  type = "button",
23787
24324
  disabled,
23788
- onPointerDown: onPointerDownProp
24325
+ onPointerDown: onPointerDownProp,
24326
+ onPointerUp: onPointerUpProp,
24327
+ onPointerLeave: onPointerLeaveProp
23789
24328
  } = _b, props = __objRest(_b, [
23790
24329
  "emphasis",
23791
24330
  "selected",
23792
24331
  "icon",
23793
24332
  "children",
23794
- "pressScale",
23795
- "pressBounceOffset",
24333
+ "pressExpand",
24334
+ "pressExpandRatio",
23796
24335
  "ripple",
23797
24336
  "asChild",
23798
24337
  "className",
23799
24338
  "type",
23800
24339
  "disabled",
23801
- "onPointerDown"
24340
+ "onPointerDown",
24341
+ "onPointerUp",
24342
+ "onPointerLeave"
23802
24343
  ]);
23803
24344
  const context = useToolbarContext();
24345
+ const [isPressed, setIsPressed] = React61__namespace.useState(false);
23804
24346
  const {
23805
24347
  ripples,
23806
24348
  onPointerDown: handleRipplePointerDown,
@@ -23810,6 +24352,7 @@ var ToolbarToggleButton = React61__namespace.forwardRef(
23810
24352
  });
23811
24353
  const handlePointerDown = React61__namespace.useCallback(
23812
24354
  (e) => {
24355
+ setIsPressed(true);
23813
24356
  if (!disabled && ripple) {
23814
24357
  handleRipplePointerDown(e);
23815
24358
  }
@@ -23817,7 +24360,21 @@ var ToolbarToggleButton = React61__namespace.forwardRef(
23817
24360
  },
23818
24361
  [disabled, ripple, handleRipplePointerDown, onPointerDownProp]
23819
24362
  );
23820
- const baseClasses = "relative overflow-hidden inline-flex items-center justify-center min-w-[95px] h-[48px] px-4 rounded-full text-sm font-medium transition-colors select-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-current/40 disabled:pointer-events-none disabled:opacity-38";
24363
+ const handlePointerUp = React61__namespace.useCallback(
24364
+ (e) => {
24365
+ setIsPressed(false);
24366
+ onPointerUpProp == null ? void 0 : onPointerUpProp(e);
24367
+ },
24368
+ [onPointerUpProp]
24369
+ );
24370
+ const handlePointerLeave = React61__namespace.useCallback(
24371
+ (e) => {
24372
+ setIsPressed(false);
24373
+ onPointerLeaveProp == null ? void 0 : onPointerLeaveProp(e);
24374
+ },
24375
+ [onPointerLeaveProp]
24376
+ );
24377
+ const baseClasses = "relative overflow-hidden inline-flex items-center justify-center min-w-[95px] h-[48px] px-4 text-sm font-medium select-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-current/40 disabled:pointer-events-none disabled:opacity-38";
23821
24378
  const variantClasses = {
23822
24379
  standard: selected ? "bg-current/16 text-current hover:bg-current/20 active:bg-current/24" : "bg-transparent text-current hover:bg-current/8 active:bg-current/12",
23823
24380
  tonal: selected ? "bg-m3-secondary-container text-m3-on-secondary-container hover:shadow-sm" : "bg-m3-surface-container-high text-m3-on-surface hover:bg-m3-surface-container-highest",
@@ -23829,27 +24386,17 @@ var ToolbarToggleButton = React61__namespace.forwardRef(
23829
24386
  context == null ? void 0 : context.itemClassName,
23830
24387
  className
23831
24388
  );
23832
- const whileTapConfig = React61__namespace.useMemo(
24389
+ const animateConfig = React61__namespace.useMemo(
23833
24390
  () => ({
23834
- scale: pressScale,
23835
- x: pressBounceOffset ? [
23836
- 0,
23837
- -pressBounceOffset,
23838
- pressBounceOffset,
23839
- -pressBounceOffset / 2,
23840
- pressBounceOffset / 2,
23841
- 0
23842
- ] : 0
24391
+ scaleX: pressExpand && isPressed ? 1 + pressExpandRatio : 1,
24392
+ borderRadius: isPressed ? ToolbarToggleButtonRadiusTokens.pressedRadius : ToolbarToggleButtonRadiusTokens.pillRadius
23843
24393
  }),
23844
- [pressScale, pressBounceOffset]
24394
+ [pressExpand, pressExpandRatio, isPressed]
23845
24395
  );
23846
24396
  const transitionConfig = React61__namespace.useMemo(
23847
24397
  () => ({
23848
- scale: FAST_SPATIAL_SPRING,
23849
- x: {
23850
- duration: 0.35,
23851
- ease: "easeInOut"
23852
- }
24398
+ scaleX: FAST_SPATIAL_SPRING,
24399
+ borderRadius: BUTTON_RADIUS_SPRING
23853
24400
  }),
23854
24401
  []
23855
24402
  );
@@ -23903,7 +24450,9 @@ var ToolbarToggleButton = React61__namespace.forwardRef(
23903
24450
  ref,
23904
24451
  "aria-pressed": selected,
23905
24452
  className: combinedClassName,
23906
- onPointerDown: handlePointerDown
24453
+ onPointerDown: handlePointerDown,
24454
+ onPointerUp: handlePointerUp,
24455
+ onPointerLeave: handlePointerLeave
23907
24456
  }, strippedProps), {
23908
24457
  children: React61__namespace.cloneElement(child, { children: innerChildContent })
23909
24458
  })
@@ -23916,9 +24465,13 @@ var ToolbarToggleButton = React61__namespace.forwardRef(
23916
24465
  type,
23917
24466
  "aria-pressed": selected,
23918
24467
  disabled,
23919
- whileTap: whileTapConfig,
24468
+ animate: animateConfig,
23920
24469
  transition: transitionConfig,
24470
+ initial: false,
24471
+ style: { transformOrigin: "center" },
23921
24472
  onPointerDown: handlePointerDown,
24473
+ onPointerUp: handlePointerUp,
24474
+ onPointerLeave: handlePointerLeave,
23922
24475
  className: combinedClassName
23923
24476
  }, props), {
23924
24477
  children: [