@butternutbox/pawprint-native 0.8.0 → 0.9.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.
@@ -13,9 +13,9 @@
13
13
  CJS dist/ibm-plex-sans-condensed-500-normal-IEQBNVGX.woff2 19.48 KB
14
14
  CJS dist/ibm-plex-sans-condensed-600-normal-UX5ZU5T6.woff2 19.35 KB
15
15
  CJS dist/ibm-plex-sans-condensed-700-normal-4PFYFTSO.woff2 18.90 KB
16
- CJS dist/index.cjs 1.79 MB
17
- CJS dist/index.cjs.map 2.68 MB
18
- CJS ⚡️ Build success in 10912ms
16
+ CJS dist/index.cjs 1.78 MB
17
+ CJS dist/index.cjs.map 2.67 MB
18
+ CJS ⚡️ Build success in 11862ms
19
19
  ESM dist/ida-narrow-500-normal-C6I2PK4T.woff2 47.41 KB
20
20
  ESM dist/ida-narrow-700-normal-UPHPRIN6.woff2 49.90 KB
21
21
  ESM dist/ibm-plex-sans-condensed-400-normal-I2XLJNNB.woff2 19.33 KB
@@ -23,8 +23,8 @@
23
23
  ESM dist/ibm-plex-sans-condensed-600-normal-UX5ZU5T6.woff2 19.35 KB
24
24
  ESM dist/ibm-plex-sans-condensed-700-normal-4PFYFTSO.woff2 18.90 KB
25
25
  ESM dist/index.js 1.71 MB
26
- ESM dist/index.js.map 2.68 MB
27
- ESM ⚡️ Build success in 10913ms
28
- DTS ⚡️ Build success in 21798ms
29
- DTS dist/index.d.cts 90.51 KB
30
- DTS dist/index.d.ts 90.51 KB
26
+ ESM dist/index.js.map 2.67 MB
27
+ ESM ⚡️ Build success in 11871ms
28
+ DTS ⚡️ Build success in 22152ms
29
+ DTS dist/index.d.cts 90.17 KB
30
+ DTS dist/index.d.ts 90.17 KB
package/CHANGELOG.md CHANGED
@@ -1,5 +1,26 @@
1
1
  # @butternutbox/pawprint-native
2
2
 
3
+ ## 0.9.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 6d84559: Add a web `NumberField` molecule (stepper) mirroring the native API, and align `ProductDisplayCard` with Figma across both platforms:
8
+ - Use `NumberField` for the quantity stepper (web previously used the plain `NumberInput` atom).
9
+ - 148×148 image (`thumbnailWidth` defaults to 148) and banner styling: square top / 12px bottom radius, `md` horizontal + 27px top padding, tucked behind the card.
10
+ - Web `device` prop now drives title/subtext typography (desktop 20/16, mobile 16/14).
11
+ - Remove `showImageQuantityBadge`, `borderless`, `thumbnailBackgroundColor`, and the per-button `showIncrementButton`/`showDecrementButton` props (use `hideQuantityButtons` instead). Native is now mobile-only (no `device` prop).
12
+
13
+ ### Patch Changes
14
+
15
+ - 6d84559: Make `ProductDisplayCard` height responsive and cap its width (web + native):
16
+ - Replace the fixed `maxHeight: 148` with `minHeight: 148` so the card grows instead of clipping when the title wraps to multiple lines (e.g. translations).
17
+ - Cap the width at the Figma frame sizes — web 520 (desktop) / 358 (mobile), native 358 — while staying fluid below that.
18
+ - The image stretches to fill a taller card (cover crop) instead of leaving a gap, keeping its 148px width and square shape when the content fits.
19
+
20
+ - 6d84559: Align `ProductListingCard` with Figma (web + native): add the 12px image border radius, fix the pinned badge (un-double-wrap so the right radius is 4px, 8px horizontal padding, brand background), and tighten the title bottom spacing to 6px and the size→price spacing to 16px.
21
+
22
+ Web also fixes the responsive `Grid` (columns were stuck at 1 because the media queries lived in an inline `style` prop) and sizes the standalone stories to the Figma widths (232 / 192).
23
+
3
24
  ## 0.8.0
4
25
 
5
26
  ### Minor Changes
package/dist/index.cjs CHANGED
@@ -14275,8 +14275,8 @@ var BadgeContainer = styled51__default.default(reactNative.View)(({ theme: theme
14275
14275
  alignItems: "center",
14276
14276
  justifyContent: "center",
14277
14277
  height: parseTokenValue55(sizing["2xl"]),
14278
- paddingRight: parseTokenValue55(spacing.sm),
14279
- backgroundColor: colour.background.container.alt,
14278
+ paddingRight: parseTokenValue55(spacing.xs),
14279
+ backgroundColor: colour.background.container.brand,
14280
14280
  borderTopRightRadius: parseTokenValue55(borderRadius.xs),
14281
14281
  borderBottomRightRadius: parseTokenValue55(borderRadius.xs)
14282
14282
  };
@@ -14353,37 +14353,25 @@ var StyledRoot16 = styled51__default.default(reactNative.Pressable)(({ theme: th
14353
14353
  width: "100%"
14354
14354
  };
14355
14355
  });
14356
- var ImageContainer = styled51__default.default(reactNative.View)({
14356
+ var ImageContainer = styled51__default.default(reactNative.View)(({ theme: theme2 }) => ({
14357
14357
  position: "relative",
14358
14358
  width: "100%",
14359
14359
  aspectRatio: 1,
14360
- overflow: "hidden"
14361
- });
14360
+ overflow: "hidden",
14361
+ borderRadius: parseTokenValue56(
14362
+ theme2.tokens.semantics.dimensions.borderRadius.md
14363
+ )
14364
+ }));
14362
14365
  var StyledImage2 = styled51__default.default(reactNative.Image)({
14363
14366
  width: "100%",
14364
14367
  height: "100%",
14365
14368
  resizeMode: "cover"
14366
14369
  });
14367
- var BadgeContainer2 = styled51__default.default(reactNative.View)(({ theme: theme2 }) => {
14368
- const spacing = theme2.tokens.semantics.dimensions.spacing;
14369
- const { sizing, borderRadius } = theme2.tokens.semantics.dimensions;
14370
- const { colour } = theme2.tokens.semantics;
14371
- return {
14372
- position: "absolute",
14373
- top: parseTokenValue56(spacing.md),
14374
- left: 0,
14375
- display: "flex",
14376
- flexDirection: "row",
14377
- gap: parseTokenValue56(spacing["2xs"]),
14378
- alignItems: "center",
14379
- justifyContent: "center",
14380
- height: parseTokenValue56(sizing["2xl"]),
14381
- paddingRight: parseTokenValue56(spacing.sm),
14382
- backgroundColor: colour.background.container.alt,
14383
- borderTopRightRadius: parseTokenValue56(borderRadius.sm),
14384
- borderBottomRightRadius: parseTokenValue56(borderRadius.sm)
14385
- };
14386
- });
14370
+ var BadgeContainer2 = styled51__default.default(reactNative.View)(({ theme: theme2 }) => ({
14371
+ position: "absolute",
14372
+ top: parseTokenValue56(theme2.tokens.semantics.dimensions.spacing.md),
14373
+ left: 0
14374
+ }));
14387
14375
  var ContentContainer = styled51__default.default(reactNative.View)(({ theme: theme2 }) => {
14388
14376
  const spacing = theme2.tokens.semantics.dimensions.spacing;
14389
14377
  return {
@@ -14406,20 +14394,12 @@ var CategoryWrapper = styled51__default.default(reactNative.View)(({ theme: them
14406
14394
  marginBottom: parseTokenValue56(spacing["3xs"])
14407
14395
  };
14408
14396
  });
14409
- var TitleContainer = styled51__default.default(reactNative.View)(({ theme: theme2 }) => {
14410
- const spacing = theme2.tokens.semantics.dimensions.spacing;
14411
- return {
14412
- display: "flex",
14413
- flexDirection: "row",
14414
- width: "100%",
14415
- marginBottom: parseTokenValue56(spacing.xs)
14416
- };
14417
- });
14418
- var SizeWrapper = styled51__default.default(reactNative.View)(({ theme: theme2 }) => {
14419
- const spacing = theme2.tokens.semantics.dimensions.spacing;
14420
- return {
14421
- marginBottom: parseTokenValue56(spacing.md)
14422
- };
14397
+ var TitleContainer = styled51__default.default(reactNative.View)({
14398
+ display: "flex",
14399
+ flexDirection: "row",
14400
+ width: "100%",
14401
+ // 6px below the title to match Figma (4px title bottom padding + 2px gap).
14402
+ marginBottom: 6
14423
14403
  });
14424
14404
  var PricingContainer = styled51__default.default(reactNative.View)(({ theme: theme2 }) => {
14425
14405
  const spacing = theme2.tokens.semantics.dimensions.spacing;
@@ -14480,7 +14460,7 @@ var _ProductListingCard = React60__default.default.forwardRef(
14480
14460
  /* @__PURE__ */ jsxRuntime.jsxs(DetailsContainer, { children: [
14481
14461
  showCategory && category && /* @__PURE__ */ jsxRuntime.jsx(CategoryWrapper, { children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", size: "sm", color: "secondary", children: category }) }),
14482
14462
  showTitle && /* @__PURE__ */ jsxRuntime.jsx(TitleContainer, { children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "heading", size: "xs", children: title }) }),
14483
- showSize && size && /* @__PURE__ */ jsxRuntime.jsx(SizeWrapper, { children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", size: "md", color: "secondary", children: size }) })
14463
+ showSize && size && /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", size: "md", color: "secondary", children: size })
14484
14464
  ] }),
14485
14465
  showPrice && price && /* @__PURE__ */ jsxRuntime.jsxs(PricingContainer, { children: [
14486
14466
  /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", size: "md", color: "secondary", children: price }),
@@ -14504,78 +14484,50 @@ var ProductListingCardWithBadgeAndGrid = Object.assign(_ProductListingCard, {
14504
14484
  Badge: Badge2,
14505
14485
  Grid
14506
14486
  });
14507
- var StyledCardContainer = styled51__default.default(reactNative.View)(({
14508
- theme: theme2,
14509
- borderless
14510
- }) => {
14487
+ var StyledCardContainer = styled51__default.default(reactNative.View)(({ theme: theme2 }) => {
14511
14488
  const { spacing, borderRadius } = theme2.tokens.semantics.dimensions;
14512
14489
  const { colour } = theme2.tokens.semantics;
14513
14490
  const spacingMd = parseTokenValue8(spacing.md);
14514
14491
  const spacingXl = parseTokenValue8(spacing.xl);
14515
- return __spreadProps(__spreadValues({
14492
+ return {
14516
14493
  flexDirection: "row",
14517
14494
  width: "100%",
14518
- height: borderless ? void 0 : "100%",
14519
- maxHeight: spacingXl * 6 + spacingMd,
14520
- backgroundColor: colour.background.surface.default
14521
- }, borderless ? {} : {
14495
+ // Cap at the Figma mobile card width (can be narrower — responsive).
14496
+ maxWidth: 358,
14497
+ // The 148px image sets the baseline height; the card grows if the content
14498
+ // is taller (e.g. a long or translated title wrapping to multiple lines)
14499
+ // so nothing is clipped.
14500
+ minHeight: 148,
14501
+ backgroundColor: colour.background.surface.default,
14522
14502
  borderWidth: 1,
14523
14503
  borderColor: colour.border.default,
14524
14504
  shadowColor: "#522a10",
14525
14505
  shadowOffset: { width: 0, height: spacingMd / 4 },
14526
14506
  shadowOpacity: 0.05,
14527
14507
  shadowRadius: spacingXl - 4,
14528
- elevation: 5
14529
- }), {
14508
+ elevation: 5,
14530
14509
  borderRadius: parseTokenValue8(borderRadius.md),
14531
14510
  overflow: "hidden",
14532
14511
  zIndex: 1
14533
- });
14534
- });
14535
- var StyledImage3 = styled51__default.default(reactNative.View)(
14536
- ({
14537
- theme: theme2,
14538
- imageBackgroundColor,
14539
- thumbnailWidth = 100,
14540
- thumbnailBackgroundColor
14541
- }) => ({
14542
- flexShrink: 0,
14543
- backgroundColor: thumbnailBackgroundColor || imageBackgroundColor || theme2.tokens.semantics.colour.background.container.secondary,
14544
- overflow: "hidden",
14545
- aspectRatio: "1 / 1",
14546
- width: thumbnailWidth,
14547
- height: thumbnailWidth,
14548
- position: "relative"
14549
- })
14550
- );
14551
- var StyledQuantityBadge = styled51__default.default(reactNative.View)(({ theme: theme2 }) => {
14552
- const spacing = theme2.tokens.semantics.dimensions.spacing;
14553
- const borderRadius = theme2.tokens.semantics.dimensions.borderRadius;
14554
- const { colour } = theme2.tokens.semantics;
14555
- return {
14556
- position: "absolute",
14557
- top: parseTokenValue8(spacing["2xs"]),
14558
- right: parseTokenValue8(spacing["2xs"]),
14559
- backgroundColor: colour.background.container.brand,
14560
- borderRadius: parseTokenValue8(borderRadius.xs),
14561
- paddingHorizontal: parseTokenValue8(spacing.sm),
14562
- height: parseTokenValue8(spacing["2xl"]),
14563
- minWidth: parseTokenValue8(spacing["2xl"]),
14564
- alignItems: "center",
14565
- justifyContent: "center",
14566
- zIndex: 2
14567
14512
  };
14568
14513
  });
14569
- var StyledContentArea = styled51__default.default(reactNative.View)(({
14570
- theme: theme2,
14571
- borderless
14572
- }) => {
14514
+ var StyledImage3 = styled51__default.default(reactNative.View)(({ theme: theme2, imageBackgroundColor, thumbnailWidth = 148 }) => ({
14515
+ flexShrink: 0,
14516
+ backgroundColor: imageBackgroundColor || theme2.tokens.semantics.colour.background.container.secondary,
14517
+ overflow: "hidden",
14518
+ width: thumbnailWidth,
14519
+ // Square (148) by default; stretches taller to fill the card when the
14520
+ // content makes it taller than the image.
14521
+ minHeight: thumbnailWidth,
14522
+ position: "relative"
14523
+ }));
14524
+ var StyledContentArea = styled51__default.default(reactNative.View)(({ theme: theme2 }) => {
14573
14525
  const { spacing } = theme2.tokens.semantics.dimensions;
14574
14526
  const paddingValue = parseTokenValue8(spacing.md);
14575
14527
  return {
14576
14528
  flex: 1,
14577
14529
  paddingHorizontal: paddingValue,
14578
- paddingVertical: borderless ? 0 : paddingValue,
14530
+ paddingVertical: paddingValue,
14579
14531
  gap: parseTokenValue8(spacing.xs),
14580
14532
  justifyContent: "space-between"
14581
14533
  };
@@ -14583,25 +14535,38 @@ var StyledContentArea = styled51__default.default(reactNative.View)(({
14583
14535
  var StyledTextContainer = styled51__default.default(reactNative.View)(() => ({
14584
14536
  gap: 2
14585
14537
  }));
14586
- var StyledBannerWrapper = styled51__default.default(reactNative.View)(() => ({
14587
- width: "100%",
14588
- marginTop: -48,
14589
- paddingTop: 24,
14590
- paddingBottom: 16
14591
- }));
14538
+ var StyledBannerWrapper = styled51__default.default(reactNative.View)(({ theme: theme2 }) => {
14539
+ const { spacing, borderRadius } = theme2.tokens.semantics.dimensions;
14540
+ return {
14541
+ width: "100%",
14542
+ // Tuck the banner up behind the card by the corner radius so its square top
14543
+ // corners hide under the card's rounded bottom; the rest sits below.
14544
+ marginTop: -parseTokenValue8(borderRadius.md),
14545
+ paddingBottom: parseTokenValue8(spacing.md)
14546
+ };
14547
+ });
14592
14548
  var StyledRootWrapper = styled51__default.default(reactNative.View)(() => {
14593
14549
  return {
14594
14550
  flexDirection: "column",
14595
14551
  width: "100%",
14596
- height: "100%"
14552
+ maxWidth: 358
14597
14553
  };
14598
14554
  });
14599
14555
  var StyledNotification = styled51__default.default(Notification)(({ theme: theme2 }) => {
14600
- const { spacing } = theme2.tokens.semantics.dimensions;
14556
+ const { spacing, borderRadius } = theme2.tokens.semantics.dimensions;
14557
+ const spacingMd = parseTokenValue8(spacing.md);
14558
+ const radiusMd = parseTokenValue8(borderRadius.md);
14601
14559
  return {
14602
- top: parseTokenValue8(spacing.md),
14603
- paddingHorizontal: parseTokenValue8(spacing.xl),
14604
- paddingVertical: parseTokenValue8(spacing.md)
14560
+ paddingHorizontal: spacingMd,
14561
+ // 27px top padding (Figma) leaves a small cream reveal above the text once
14562
+ // the banner tucks behind the card.
14563
+ paddingTop: 27,
14564
+ paddingBottom: spacingMd,
14565
+ // Square top corners, rounded bottom corners (banner tucks under the card).
14566
+ borderTopLeftRadius: 0,
14567
+ borderTopRightRadius: 0,
14568
+ borderBottomLeftRadius: radiusMd,
14569
+ borderBottomRightRadius: radiusMd
14605
14570
  };
14606
14571
  });
14607
14572
  var ProductDisplayCard = React60__default.default.forwardRef(
@@ -14615,16 +14580,11 @@ var ProductDisplayCard = React60__default.default.forwardRef(
14615
14580
  showQuantityPicker = false,
14616
14581
  disableQuantityButtons = false,
14617
14582
  hideQuantityButtons = false,
14618
- showIncrementButton,
14619
- showDecrementButton,
14620
14583
  incrementDisabled = false,
14621
14584
  decrementDisabled = false,
14622
14585
  image,
14623
14586
  imageBackgroundColor,
14624
14587
  thumbnailWidth,
14625
- thumbnailBackgroundColor,
14626
- showImageQuantityBadge = false,
14627
- borderless = false,
14628
14588
  banner,
14629
14589
  showBanner = false,
14630
14590
  bannerType = "info",
@@ -14638,16 +14598,11 @@ var ProductDisplayCard = React60__default.default.forwardRef(
14638
14598
  "showQuantityPicker",
14639
14599
  "disableQuantityButtons",
14640
14600
  "hideQuantityButtons",
14641
- "showIncrementButton",
14642
- "showDecrementButton",
14643
14601
  "incrementDisabled",
14644
14602
  "decrementDisabled",
14645
14603
  "image",
14646
14604
  "imageBackgroundColor",
14647
14605
  "thumbnailWidth",
14648
- "thumbnailBackgroundColor",
14649
- "showImageQuantityBadge",
14650
- "borderless",
14651
14606
  "banner",
14652
14607
  "showBanner",
14653
14608
  "bannerType",
@@ -14658,26 +14613,23 @@ var ProductDisplayCard = React60__default.default.forwardRef(
14658
14613
  onQuantityChange == null ? void 0 : onQuantityChange(newQuantity);
14659
14614
  }
14660
14615
  };
14661
- const cardContent = /* @__PURE__ */ jsxRuntime.jsxs(StyledCardContainer, __spreadProps(__spreadValues({ ref, borderless }, rest), { children: [
14662
- image && /* @__PURE__ */ jsxRuntime.jsxs(
14616
+ const cardContent = /* @__PURE__ */ jsxRuntime.jsxs(StyledCardContainer, __spreadProps(__spreadValues({ ref }, rest), { children: [
14617
+ image && /* @__PURE__ */ jsxRuntime.jsx(
14663
14618
  StyledImage3,
14664
14619
  {
14665
14620
  imageBackgroundColor,
14666
14621
  thumbnailWidth,
14667
- thumbnailBackgroundColor,
14668
- children: [
14669
- typeof image === "string" ? /* @__PURE__ */ jsxRuntime.jsx(
14670
- reactNative.Image,
14671
- {
14672
- source: { uri: image },
14673
- style: { width: "100%", height: "100%" }
14674
- }
14675
- ) : image,
14676
- showImageQuantityBadge && quantity && /* @__PURE__ */ jsxRuntime.jsx(StyledQuantityBadge, { children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", size: "sm", weight: "bold", children: quantity }) })
14677
- ]
14622
+ children: typeof image === "string" ? /* @__PURE__ */ jsxRuntime.jsx(
14623
+ reactNative.Image,
14624
+ {
14625
+ source: { uri: image },
14626
+ resizeMode: "cover",
14627
+ style: { flex: 1, width: "100%" }
14628
+ }
14629
+ ) : image
14678
14630
  }
14679
14631
  ),
14680
- /* @__PURE__ */ jsxRuntime.jsxs(StyledContentArea, { borderless, children: [
14632
+ /* @__PURE__ */ jsxRuntime.jsxs(StyledContentArea, { children: [
14681
14633
  /* @__PURE__ */ jsxRuntime.jsxs(StyledTextContainer, { children: [
14682
14634
  /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "heading", size: "2xs", color: "primary", children: title }),
14683
14635
  showSubtext && subtext && /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", size: "sm", color: "secondary", children: subtext })
@@ -14698,8 +14650,8 @@ var ProductDisplayCard = React60__default.default.forwardRef(
14698
14650
  min: 1,
14699
14651
  accessible: true,
14700
14652
  accessibilityLabel: `Quantity: ${quantity}`,
14701
- showIncrementButton: showIncrementButton !== void 0 ? showIncrementButton : !hideQuantityButtons,
14702
- showDecrementButton: showDecrementButton !== void 0 ? showDecrementButton : !hideQuantityButtons,
14653
+ showIncrementButton: !hideQuantityButtons,
14654
+ showDecrementButton: !hideQuantityButtons,
14703
14655
  incrementDisabled: incrementDisabled || disableQuantityButtons,
14704
14656
  decrementDisabled: decrementDisabled || disableQuantityButtons
14705
14657
  }