@butternutbox/pawprint-native 0.10.9 → 0.10.10

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.
@@ -7,12 +7,12 @@
7
7
  CJS Build start
8
8
  ESM Build start
9
9
  DTS Build start
10
- CJS dist/index.cjs 1.80 MB
11
- CJS dist/index.cjs.map 2.70 MB
12
- CJS ⚡️ Build success in 11884ms
13
10
  ESM dist/index.js 1.72 MB
14
11
  ESM dist/index.js.map 2.70 MB
15
- ESM ⚡️ Build success in 11885ms
16
- DTS ⚡️ Build success in 22581ms
12
+ ESM ⚡️ Build success in 11267ms
13
+ CJS dist/index.cjs 1.80 MB
14
+ CJS dist/index.cjs.map 2.70 MB
15
+ CJS ⚡️ Build success in 11267ms
16
+ DTS ⚡️ Build success in 22659ms
17
17
  DTS dist/index.d.cts 91.44 KB
18
18
  DTS dist/index.d.ts 91.44 KB
package/CHANGELOG.md CHANGED
@@ -1,5 +1,28 @@
1
1
  # @butternutbox/pawprint-native
2
2
 
3
+ ## 0.10.10
4
+
5
+ ### Patch Changes
6
+
7
+ - 8d9523c: Drawer: fix the body collapsing to zero height on native (regression in 0.10.9).
8
+
9
+ 0.10.9 made the panel wrap its content with no explicit height, relying on
10
+ `DrawerBody`'s `maxHeight` to size the `flex: 1` ScrollView. On native a
11
+ `ScrollView` has no intrinsic size and `flex: 1` (flexBasis 0) needs a
12
+ definite-height parent, so every drawer body collapsed to ~0 — only the header
13
+ and footer rendered. (It looked correct in the react-native-web Storybook, whose
14
+ flexbox sizes to content, which is why it slipped through.)
15
+
16
+ The panel now keeps an explicit height again (the pre-0.10.9 structure that
17
+ gives the ScrollView a bounded parent) AND re-fits it: `DrawerBody` reports its
18
+ natural scroll-content height via `onContentSizeChange` (measured in the
19
+ ScrollView's unbounded content container, so it's independent of the frame — no
20
+ feedback loop) through a new `DrawerMeasureContext`, and `DrawerContent` sizes
21
+ the panel to `chrome + min(content, windowHeight - 300)`, capped at 90% of the
22
+ window. `chrome` is locked once from the first, unbounded layout and is
23
+ invariant thereafter. Content that grows or shrinks after open (async load,
24
+ expanding sections) re-fits the panel; tall content caps and scrolls.
25
+
3
26
  ## 0.10.9
4
27
 
5
28
  ### Patch Changes
package/dist/index.cjs CHANGED
@@ -8877,6 +8877,8 @@ var DrawerOverlay = React65__default.default.forwardRef(({ accessible = false },
8877
8877
  DrawerOverlay.displayName = "Drawer.Overlay";
8878
8878
  var DrawerDragContext = React65__default.default.createContext(null);
8879
8879
  var useDrawerDragContext = () => React65__default.default.useContext(DrawerDragContext);
8880
+ var DrawerMeasureContext = React65.createContext(null);
8881
+ var useDrawerMeasureContext = () => React65.useContext(DrawerMeasureContext);
8880
8882
  var DrawerFooterContext = React65__default.default.createContext(false);
8881
8883
  var useDrawerFooterContext = () => React65__default.default.useContext(DrawerFooterContext);
8882
8884
  var DrawerHeaderContext = React65__default.default.createContext(null);
@@ -8895,17 +8897,12 @@ var StyledPanel2 = styled50__default.default(reactNative.View)(
8895
8897
  panelShadowColor,
8896
8898
  panelShadowOffsetY,
8897
8899
  panelShadowBlur,
8898
- panelMaxHeight
8899
- }) => ({
8900
+ panelFlex
8901
+ }) => __spreadProps(__spreadValues({
8900
8902
  width: "100%",
8901
8903
  maxWidth: panelMaxWidth,
8902
- // The panel wraps its content and caps at maxHeight. It is intentionally
8903
- // NOT given a fixed height: letting it size to content means it re-fits
8904
- // automatically whenever the body grows or shrinks (async load, expanding
8905
- // sections). The body's own maxHeight (see DrawerBody) bounds scrolling and
8906
- // keeps the ScrollView from collapsing, so no fixed panel height is needed.
8907
- maxHeight: panelMaxHeight,
8908
- alignSelf: "center",
8904
+ alignSelf: "center"
8905
+ }, panelFlex != null ? { flex: panelFlex } : void 0), {
8909
8906
  borderTopLeftRadius: panelBorderRadius,
8910
8907
  borderTopRightRadius: panelBorderRadius,
8911
8908
  borderTopWidth: panelBorderWidth,
@@ -8931,6 +8928,7 @@ var DrawerContent = React65__default.default.forwardRef(
8931
8928
  const { isOpen, closeDrawer, onExitComplete } = useDrawerContext();
8932
8929
  const { height: windowHeight } = reactNative.useWindowDimensions();
8933
8930
  const maxHeight = windowHeight * 0.9;
8931
+ const bodyMaxHeight = windowHeight - 300;
8934
8932
  const closeDrawerRef = React65.useRef(closeDrawer);
8935
8933
  React65.useEffect(() => {
8936
8934
  closeDrawerRef.current = closeDrawer;
@@ -8941,12 +8939,22 @@ var DrawerContent = React65__default.default.forwardRef(
8941
8939
  const entryRanRef = React65.useRef(false);
8942
8940
  const isOpenRef = React65.useRef(isOpen);
8943
8941
  const activeAnim = React65.useRef(null);
8942
+ const [panelHeight, setPanelHeight] = React65.useState(0);
8943
+ const chromeRef = React65.useRef(0);
8944
+ const bodyContentRef = React65.useRef(0);
8945
+ const firstNaturalRef = React65.useRef(0);
8944
8946
  React65.useEffect(() => {
8945
8947
  const id = translateY.addListener(({ value }) => {
8946
8948
  translateYValue.current = value;
8947
8949
  });
8948
8950
  return () => translateY.removeListener(id);
8949
8951
  }, [translateY]);
8952
+ React65.useEffect(() => {
8953
+ if (panelHeightRef.current > 0 && panelHeightRef.current > maxHeight) {
8954
+ setPanelHeight(maxHeight);
8955
+ panelHeightRef.current = maxHeight;
8956
+ }
8957
+ }, [maxHeight]);
8950
8958
  const runEntry = React65.useCallback(() => {
8951
8959
  var _a3;
8952
8960
  if (panelHeightRef.current === 0) return;
@@ -8993,17 +9001,59 @@ var DrawerContent = React65__default.default.forwardRef(
8993
9001
  runExit();
8994
9002
  }
8995
9003
  }, [isOpen, runEntry, runExit]);
9004
+ const applyRefit = React65.useCallback(() => {
9005
+ const chrome = chromeRef.current;
9006
+ const content = bodyContentRef.current;
9007
+ if (chrome <= 0 || content <= 0) return;
9008
+ const desired = Math.min(
9009
+ chrome + Math.min(content, bodyMaxHeight),
9010
+ maxHeight
9011
+ );
9012
+ if (Math.abs(desired - panelHeightRef.current) > 1) {
9013
+ panelHeightRef.current = desired;
9014
+ setPanelHeight(desired);
9015
+ }
9016
+ }, [bodyMaxHeight, maxHeight]);
9017
+ const lockChrome = React65.useCallback(() => {
9018
+ if (chromeRef.current > 0) return;
9019
+ const natural = firstNaturalRef.current;
9020
+ const content = bodyContentRef.current;
9021
+ if (natural <= 0 || content <= 0) return;
9022
+ chromeRef.current = natural - Math.min(content, bodyMaxHeight);
9023
+ }, [bodyMaxHeight]);
9024
+ const setBodyContentHeight = React65.useCallback(
9025
+ (height) => {
9026
+ if (height <= 0) return;
9027
+ bodyContentRef.current = height;
9028
+ lockChrome();
9029
+ applyRefit();
9030
+ },
9031
+ [lockChrome, applyRefit]
9032
+ );
9033
+ const measureContextValue = React65.useMemo(
9034
+ () => ({ setBodyContentHeight }),
9035
+ [setBodyContentHeight]
9036
+ );
8996
9037
  const onLayout = React65.useCallback(
8997
9038
  ({ nativeEvent }) => {
8998
9039
  const h = nativeEvent.layout.height;
8999
9040
  const capped = Math.min(h, maxHeight);
9000
9041
  if (capped <= 0) return;
9001
- panelHeightRef.current = capped;
9002
- if (isOpenRef.current && !entryRanRef.current) {
9042
+ if (entryRanRef.current) return;
9043
+ if (chromeRef.current <= 0) {
9044
+ firstNaturalRef.current = h;
9045
+ lockChrome();
9046
+ }
9047
+ if (capped !== panelHeightRef.current) {
9048
+ panelHeightRef.current = capped;
9049
+ setPanelHeight(capped);
9050
+ }
9051
+ if (isOpenRef.current) {
9003
9052
  runEntry();
9004
9053
  }
9054
+ applyRefit();
9005
9055
  },
9006
- [runEntry, maxHeight]
9056
+ [runEntry, maxHeight, lockChrome, applyRefit]
9007
9057
  );
9008
9058
  const panResponder = React65.useRef(
9009
9059
  reactNative.PanResponder.create({
@@ -9072,10 +9122,14 @@ var DrawerContent = React65__default.default.forwardRef(
9072
9122
  const headerContextValue = headerChild != null ? {
9073
9123
  variant: (_a2 = headerChild.props.variant) != null ? _a2 : "titleAndText"
9074
9124
  } : null;
9075
- return /* @__PURE__ */ jsxRuntime.jsx(DrawerHeaderContext.Provider, { value: headerContextValue, children: /* @__PURE__ */ jsxRuntime.jsx(DrawerFooterContext.Provider, { value: hasFooter, children: /* @__PURE__ */ jsxRuntime.jsx(DrawerDragContext.Provider, { value: dragContextValue, children: /* @__PURE__ */ jsxRuntime.jsx(
9125
+ return /* @__PURE__ */ jsxRuntime.jsx(DrawerHeaderContext.Provider, { value: headerContextValue, children: /* @__PURE__ */ jsxRuntime.jsx(DrawerFooterContext.Provider, { value: hasFooter, children: /* @__PURE__ */ jsxRuntime.jsx(DrawerMeasureContext.Provider, { value: measureContextValue, children: /* @__PURE__ */ jsxRuntime.jsx(DrawerDragContext.Provider, { value: dragContextValue, children: /* @__PURE__ */ jsxRuntime.jsx(
9076
9126
  reactNative.Animated.View,
9077
9127
  {
9078
- style: [styles.animatedWrapper, { transform: [{ translateY }] }],
9128
+ style: [
9129
+ styles.animatedWrapper,
9130
+ panelHeight > 0 ? { height: panelHeight } : void 0,
9131
+ { transform: [{ translateY }] }
9132
+ ],
9079
9133
  children: /* @__PURE__ */ jsxRuntime.jsx(
9080
9134
  StyledPanel2,
9081
9135
  __spreadProps(__spreadValues({
@@ -9084,7 +9138,7 @@ var DrawerContent = React65__default.default.forwardRef(
9084
9138
  panelBorderRadius: parseTokenValue22(drawer.borderRadius.top),
9085
9139
  panelBgColor: colour.background.container.default,
9086
9140
  panelMaxWidth: parseTokenValue22(drawer.size.maxWidth),
9087
- panelMaxHeight: maxHeight,
9141
+ panelFlex: panelHeight > 0 ? 1 : void 0,
9088
9142
  panelBorderWidth: parseTokenValue22(dimensions3.borderWidth.sm),
9089
9143
  panelBorderColor: colour.border.default,
9090
9144
  panelShadowColor: modal.shadow.color,
@@ -9098,7 +9152,7 @@ var DrawerContent = React65__default.default.forwardRef(
9098
9152
  })
9099
9153
  )
9100
9154
  }
9101
- ) }) }) });
9155
+ ) }) }) }) });
9102
9156
  }
9103
9157
  );
9104
9158
  DrawerContent.displayName = "Drawer.Content";
@@ -9414,14 +9468,22 @@ var StyledScrollView = styled50__default.default(reactNative.ScrollView)(
9414
9468
  );
9415
9469
  var DrawerBody = React65__default.default.forwardRef(
9416
9470
  (_a, ref) => {
9417
- var _b = _a, { children, contentContainerStyle } = _b, props = __objRest(_b, ["children", "contentContainerStyle"]);
9471
+ var _b = _a, { children, contentContainerStyle, onContentSizeChange } = _b, props = __objRest(_b, ["children", "contentContainerStyle", "onContentSizeChange"]);
9418
9472
  const theme2 = react.useTheme();
9419
9473
  const { spacing } = theme2.tokens.components.drawer;
9420
9474
  const { buttons } = theme2.tokens.components;
9421
9475
  const { content } = spacing;
9422
9476
  const headerContext = useDrawerHeaderContext();
9423
9477
  const footerContext = useDrawerFooterContext();
9478
+ const measureContext = useDrawerMeasureContext();
9424
9479
  const { height: windowHeight } = reactNative.useWindowDimensions();
9480
+ const handleContentSizeChange = React65.useCallback(
9481
+ (width, height) => {
9482
+ measureContext == null ? void 0 : measureContext.setBodyContentHeight(height);
9483
+ onContentSizeChange == null ? void 0 : onContentSizeChange(width, height);
9484
+ },
9485
+ [measureContext, onContentSizeChange]
9486
+ );
9425
9487
  const gap = parseTokenValue26(content.slot.gap);
9426
9488
  const horizontalPadding = parseTokenValue26(content.slot.horizontalPadding);
9427
9489
  const topPadding = parseTokenValue26(content.slot.verticalPadding);
@@ -9437,6 +9499,7 @@ var DrawerBody = React65__default.default.forwardRef(
9437
9499
  bodyGap: gap,
9438
9500
  bodyMaxHeight,
9439
9501
  bodyPaddingBottom,
9502
+ onContentSizeChange: handleContentSizeChange,
9440
9503
  contentContainerStyle: [
9441
9504
  {
9442
9505
  gap,