@butternutbox/pawprint-native 1.0.0 → 1.1.1
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/.turbo/turbo-build.log +7 -7
- package/CHANGELOG.md +16 -0
- package/dist/index.cjs +5 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +36 -9
- package/dist/index.d.ts +36 -9
- package/dist/index.js +5 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/molecules/ProductDisplayCard/ProductDisplayCard.stories.tsx +40 -5
- package/src/components/molecules/ProductDisplayCard/ProductDisplayCard.test.tsx +58 -3
- package/src/components/molecules/ProductDisplayCard/ProductDisplayCard.tsx +36 -12
package/package.json
CHANGED
|
@@ -38,7 +38,12 @@ export default {
|
|
|
38
38
|
quantityBadge: {
|
|
39
39
|
control: { type: "boolean" },
|
|
40
40
|
description:
|
|
41
|
-
"Show a quantity badge over the image instead of the picker
|
|
41
|
+
"@deprecated — use `thumbnailBadge`. Show a legacy quantity badge over the image instead of the picker."
|
|
42
|
+
},
|
|
43
|
+
thumbnailBadge: {
|
|
44
|
+
control: false,
|
|
45
|
+
description:
|
|
46
|
+
"Render a Badge over the image (accepts any BadgeProps). Mutually exclusive with the quantity picker."
|
|
42
47
|
},
|
|
43
48
|
disableQuantityButtons: {
|
|
44
49
|
control: { type: "boolean" },
|
|
@@ -277,10 +282,42 @@ export const WithCustomBanner = () => (
|
|
|
277
282
|
</View>
|
|
278
283
|
)
|
|
279
284
|
|
|
285
|
+
export const WithThumbnailBadge = () => (
|
|
286
|
+
<View style={styles.column}>
|
|
287
|
+
{/* Consumer controls the badge content and variant. */}
|
|
288
|
+
<ProductDisplayCard
|
|
289
|
+
title="Recipe Name"
|
|
290
|
+
subtext="+£0.00/pouch"
|
|
291
|
+
showSubtext
|
|
292
|
+
thumbnailBadge={{ variant: "primary", size: "large", children: "New" }}
|
|
293
|
+
image={placeholderImageUrl}
|
|
294
|
+
/>
|
|
295
|
+
<ProductDisplayCard
|
|
296
|
+
title="Recipe Name"
|
|
297
|
+
subtext="+£0.00/pouch"
|
|
298
|
+
showSubtext
|
|
299
|
+
thumbnailBadge={{ variant: "promo", size: "large", children: "Popular" }}
|
|
300
|
+
image={placeholderImageUrl}
|
|
301
|
+
/>
|
|
302
|
+
{/* Suppresses the picker even when showQuantityPicker is set. */}
|
|
303
|
+
<ProductDisplayCard
|
|
304
|
+
title="Recipe Name"
|
|
305
|
+
subtext="+£0.00/pouch"
|
|
306
|
+
showSubtext
|
|
307
|
+
quantity={2}
|
|
308
|
+
showQuantityPicker
|
|
309
|
+
thumbnailBadge={{ variant: "primary", size: "large", children: "2" }}
|
|
310
|
+
image={placeholderImageUrl}
|
|
311
|
+
/>
|
|
312
|
+
</View>
|
|
313
|
+
)
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
* @deprecated Prefer `thumbnailBadge`. This story documents the legacy
|
|
317
|
+
* `quantityBadge` prop behaviour during the deprecation window.
|
|
318
|
+
*/
|
|
280
319
|
export const WithQuantityBadge = () => (
|
|
281
320
|
<View style={styles.column}>
|
|
282
|
-
{/* OOB recipe / Extras card: quantity shown as a badge over the image
|
|
283
|
-
instead of the picker. The two are mutually exclusive. */}
|
|
284
321
|
<ProductDisplayCard
|
|
285
322
|
title="Recipe Name"
|
|
286
323
|
subtext="+£0.00/pouch"
|
|
@@ -289,8 +326,6 @@ export const WithQuantityBadge = () => (
|
|
|
289
326
|
quantityBadge
|
|
290
327
|
image={placeholderImageUrl}
|
|
291
328
|
/>
|
|
292
|
-
{/* Even with showQuantityPicker set, the badge wins and the picker is
|
|
293
|
-
suppressed. */}
|
|
294
329
|
<ProductDisplayCard
|
|
295
330
|
title="Recipe Name"
|
|
296
331
|
subtext="+£0.00/pouch"
|
|
@@ -222,7 +222,7 @@ describe("ProductDisplayCard (Native)", () => {
|
|
|
222
222
|
expect(screen.queryByText("6")).toBeFalsy()
|
|
223
223
|
})
|
|
224
224
|
|
|
225
|
-
it("
|
|
225
|
+
it("renders the quantity picker alongside a quantityBadge", () => {
|
|
226
226
|
renderWithTheme(
|
|
227
227
|
<ProductDisplayCard
|
|
228
228
|
title="Test Product"
|
|
@@ -239,7 +239,62 @@ describe("ProductDisplayCard (Native)", () => {
|
|
|
239
239
|
|
|
240
240
|
// The badge shows the quantity...
|
|
241
241
|
expect(screen.getByText("3")).toBeTruthy()
|
|
242
|
-
// ...and the picker
|
|
243
|
-
expect(screen.
|
|
242
|
+
// ...and the picker is rendered independently of it.
|
|
243
|
+
expect(screen.getByDisplayValue("3")).toBeTruthy()
|
|
244
|
+
})
|
|
245
|
+
|
|
246
|
+
it("renders a thumbnailBadge from BadgeProps", () => {
|
|
247
|
+
renderWithTheme(
|
|
248
|
+
<ProductDisplayCard
|
|
249
|
+
title="Test Product"
|
|
250
|
+
thumbnailBadge={{ variant: "primary", size: "large", children: "New" }}
|
|
251
|
+
image={
|
|
252
|
+
<View>
|
|
253
|
+
<Text>Image</Text>
|
|
254
|
+
</View>
|
|
255
|
+
}
|
|
256
|
+
/>
|
|
257
|
+
)
|
|
258
|
+
|
|
259
|
+
expect(screen.getByText("New")).toBeTruthy()
|
|
260
|
+
})
|
|
261
|
+
|
|
262
|
+
it("renders the quantity picker alongside a thumbnailBadge", () => {
|
|
263
|
+
renderWithTheme(
|
|
264
|
+
<ProductDisplayCard
|
|
265
|
+
title="Test Product"
|
|
266
|
+
quantity={2}
|
|
267
|
+
thumbnailBadge={{ children: "New" }}
|
|
268
|
+
showQuantityPicker
|
|
269
|
+
image={
|
|
270
|
+
<View>
|
|
271
|
+
<Text>Image</Text>
|
|
272
|
+
</View>
|
|
273
|
+
}
|
|
274
|
+
/>
|
|
275
|
+
)
|
|
276
|
+
|
|
277
|
+
expect(screen.getByText("New")).toBeTruthy()
|
|
278
|
+
expect(screen.getByDisplayValue("2")).toBeTruthy()
|
|
279
|
+
})
|
|
280
|
+
|
|
281
|
+
it("prefers thumbnailBadge over the deprecated quantityBadge when both are set", () => {
|
|
282
|
+
renderWithTheme(
|
|
283
|
+
<ProductDisplayCard
|
|
284
|
+
title="Test Product"
|
|
285
|
+
quantity={9}
|
|
286
|
+
quantityBadge
|
|
287
|
+
thumbnailBadge={{ children: "Popular" }}
|
|
288
|
+
image={
|
|
289
|
+
<View>
|
|
290
|
+
<Text>Image</Text>
|
|
291
|
+
</View>
|
|
292
|
+
}
|
|
293
|
+
/>
|
|
294
|
+
)
|
|
295
|
+
|
|
296
|
+
expect(screen.getByText("Popular")).toBeTruthy()
|
|
297
|
+
// The legacy quantity badge should not render alongside it.
|
|
298
|
+
expect(screen.queryByText("9")).toBeFalsy()
|
|
244
299
|
})
|
|
245
300
|
})
|
|
@@ -3,7 +3,7 @@ import { View, ViewProps, Image, Pressable } from "react-native"
|
|
|
3
3
|
import styled from "@emotion/native"
|
|
4
4
|
import { useTheme } from "@emotion/react"
|
|
5
5
|
import { Typography } from "../../atoms/Typography"
|
|
6
|
-
import { Badge } from "../../atoms/Badge"
|
|
6
|
+
import { Badge, type BadgeProps } from "../../atoms/Badge"
|
|
7
7
|
import { NumberField } from "../../molecules/NumberField"
|
|
8
8
|
import { Notification } from "../Notification"
|
|
9
9
|
import { parseTokenValue } from "../../../utils"
|
|
@@ -16,12 +16,23 @@ export type ProductDisplayCardProps = ViewProps & {
|
|
|
16
16
|
onQuantityChange?: (quantity: number) => void
|
|
17
17
|
showQuantityPicker?: boolean
|
|
18
18
|
/**
|
|
19
|
+
* @deprecated Use `thumbnailBadge` instead. When both are set, `thumbnailBadge`
|
|
20
|
+
* wins. This prop will be removed in a future major release.
|
|
21
|
+
*
|
|
19
22
|
* Show a quantity badge overlaid on the top-right of the image (rendering the
|
|
20
|
-
* current `quantity`)
|
|
21
|
-
*
|
|
22
|
-
* at a time; when `quantityBadge` is true the picker is never rendered.
|
|
23
|
+
* current `quantity`). Defaults to `false`. Independent of the quantity
|
|
24
|
+
* picker — use `showQuantityPicker` to control that separately.
|
|
23
25
|
*/
|
|
24
26
|
quantityBadge?: boolean
|
|
27
|
+
/**
|
|
28
|
+
* Render a `Badge` overlaid on the top-right of the image. Accepts any
|
|
29
|
+
* `BadgeProps` (variant, size, icon, children, etc.) — pass them as an object.
|
|
30
|
+
* Independent of the quantity picker: both can be shown at the same time.
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* thumbnailBadge={{ variant: "primary", size: "large", children: "New" }}
|
|
34
|
+
*/
|
|
35
|
+
thumbnailBadge?: BadgeProps
|
|
25
36
|
disableQuantityButtons?: boolean
|
|
26
37
|
hideQuantityButtons?: boolean
|
|
27
38
|
incrementDisabled?: boolean
|
|
@@ -194,9 +205,14 @@ const StyledNoneBanner = styled(View)(({ theme }) => {
|
|
|
194
205
|
* @param quantity - *(optional)* Current quantity value
|
|
195
206
|
* @param onQuantityChange - *(optional)* Callback when quantity changes
|
|
196
207
|
* @param showQuantityPicker - *(optional)* Show/hide quantity picker
|
|
197
|
-
* @param quantityBadge - *(optional)*
|
|
198
|
-
*
|
|
199
|
-
*
|
|
208
|
+
* @param quantityBadge - *(optional)* **@deprecated** — use `thumbnailBadge` instead.
|
|
209
|
+
* Show a legacy quantity badge over the image (renders the current `quantity`
|
|
210
|
+
* as a primary/large Badge). Mutually exclusive with the picker; defaults to
|
|
211
|
+
* `false`. When both `thumbnailBadge` and `quantityBadge` are set, `thumbnailBadge`
|
|
212
|
+
* wins.
|
|
213
|
+
* @param thumbnailBadge - *(optional)* Render a `Badge` overlaid on the top-right
|
|
214
|
+
* of the image. Accepts any `BadgeProps` (`variant`, `size`, `icon`, `children`, …).
|
|
215
|
+
* Mutually exclusive with the quantity picker.
|
|
200
216
|
* @param quantityStep - *(optional)* Increment/decrement amount (default: 1)
|
|
201
217
|
* @param image - *(optional)* Image URL string or React element
|
|
202
218
|
* @param banner - *(optional)* Banner content string or React element to show below card
|
|
@@ -217,6 +233,7 @@ export const ProductDisplayCard = React.forwardRef<
|
|
|
217
233
|
onQuantityChange,
|
|
218
234
|
showQuantityPicker = false,
|
|
219
235
|
quantityBadge = false,
|
|
236
|
+
thumbnailBadge,
|
|
220
237
|
disableQuantityButtons = false,
|
|
221
238
|
hideQuantityButtons = false,
|
|
222
239
|
incrementDisabled = false,
|
|
@@ -241,6 +258,15 @@ export const ProductDisplayCard = React.forwardRef<
|
|
|
241
258
|
}
|
|
242
259
|
}
|
|
243
260
|
|
|
261
|
+
// `thumbnailBadge` supersedes the deprecated `quantityBadge`. When set,
|
|
262
|
+
// consumers control the entire badge; when unset, the legacy `quantityBadge`
|
|
263
|
+
// boolean falls back to the previous hardcoded quantity chip.
|
|
264
|
+
const resolvedBadgeProps: BadgeProps | undefined =
|
|
265
|
+
thumbnailBadge ??
|
|
266
|
+
(quantityBadge
|
|
267
|
+
? { variant: "primary", size: "large", children: String(quantity) }
|
|
268
|
+
: undefined)
|
|
269
|
+
|
|
244
270
|
const cardContent = (
|
|
245
271
|
<StyledCardContainer
|
|
246
272
|
ref={ref}
|
|
@@ -262,11 +288,9 @@ export const ProductDisplayCard = React.forwardRef<
|
|
|
262
288
|
) : (
|
|
263
289
|
image
|
|
264
290
|
)}
|
|
265
|
-
{
|
|
291
|
+
{resolvedBadgeProps && (
|
|
266
292
|
<StyledBadgeOverlay pointerEvents="none">
|
|
267
|
-
<Badge
|
|
268
|
-
{String(quantity)}
|
|
269
|
-
</Badge>
|
|
293
|
+
<Badge {...resolvedBadgeProps} />
|
|
270
294
|
</StyledBadgeOverlay>
|
|
271
295
|
)}
|
|
272
296
|
</StyledImage>
|
|
@@ -286,7 +310,7 @@ export const ProductDisplayCard = React.forwardRef<
|
|
|
286
310
|
)}
|
|
287
311
|
</StyledTextContainer>
|
|
288
312
|
|
|
289
|
-
{showQuantityPicker &&
|
|
313
|
+
{showQuantityPicker && (
|
|
290
314
|
<View style={{ marginLeft: "auto" }}>
|
|
291
315
|
<NumberField
|
|
292
316
|
size="sm"
|