@butternutbox/pawprint-native 0.4.0 → 0.4.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 +6 -0
- package/dist/index.cjs +56 -31
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +12 -6
- package/dist/index.d.ts +12 -6
- package/dist/index.js +56 -31
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/molecules/NumberField/NumberFieldInput.tsx +14 -24
- package/src/components/molecules/ProductDisplayCard/ProductDisplayCard.stories.tsx +44 -17
- package/src/components/molecules/ProductDisplayCard/ProductDisplayCard.tsx +62 -13
package/package.json
CHANGED
|
@@ -74,29 +74,20 @@ const StyledTextInput = styled(TextInput)<{
|
|
|
74
74
|
inputFontFamily: string
|
|
75
75
|
inputFontWeight?: FontWeight
|
|
76
76
|
inputFontSize: number
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
width: "100%",
|
|
92
|
-
height: "100%",
|
|
93
|
-
color: inputColor,
|
|
94
|
-
fontFamily: inputFontFamily,
|
|
95
|
-
...(inputFontWeight ? { fontWeight: inputFontWeight } : {}),
|
|
96
|
-
fontSize: inputFontSize,
|
|
97
|
-
lineHeight: inputLineHeight
|
|
98
|
-
})
|
|
99
|
-
)
|
|
77
|
+
}>(({ inputColor, inputFontFamily, inputFontWeight, inputFontSize }) => ({
|
|
78
|
+
textAlign: "center" as const,
|
|
79
|
+
outlineStyle: "none" as unknown as undefined,
|
|
80
|
+
padding: 0,
|
|
81
|
+
minWidth: 0,
|
|
82
|
+
minHeight: 0,
|
|
83
|
+
width: "100%",
|
|
84
|
+
height: "100%",
|
|
85
|
+
color: inputColor,
|
|
86
|
+
fontFamily: inputFontFamily,
|
|
87
|
+
...(inputFontWeight ? { fontWeight: inputFontWeight } : {}),
|
|
88
|
+
fontSize: inputFontSize,
|
|
89
|
+
lineHeight: 0
|
|
90
|
+
}))
|
|
100
91
|
|
|
101
92
|
const StyledRow = styled(View)<{
|
|
102
93
|
rowGap: number
|
|
@@ -256,7 +247,6 @@ export const NumberFieldInput = React.forwardRef<
|
|
|
256
247
|
: undefined
|
|
257
248
|
}
|
|
258
249
|
inputFontSize={parseTokenValue(typographyToken.fontSize)}
|
|
259
|
-
inputLineHeight={parseTokenValue(typographyToken.lineHeight)}
|
|
260
250
|
keyboardType="numeric"
|
|
261
251
|
editable={!disabled}
|
|
262
252
|
onFocus={handleFocus}
|
|
@@ -1,14 +1,9 @@
|
|
|
1
1
|
import React from "react"
|
|
2
|
-
import { View, StyleSheet
|
|
2
|
+
import { View, StyleSheet } from "react-native"
|
|
3
3
|
import { ProductDisplayCard } from "./ProductDisplayCard"
|
|
4
4
|
import type { ProductDisplayCardProps } from "./ProductDisplayCard"
|
|
5
5
|
|
|
6
|
-
const
|
|
7
|
-
<Image
|
|
8
|
-
source={{ uri: "https://placeholder.co/148x148?text=Recipe" }}
|
|
9
|
-
style={{ width: "100%", height: "100%" }}
|
|
10
|
-
/>
|
|
11
|
-
)
|
|
6
|
+
const placeholderImageUrl = "https://placeholder.co/100x100?text=Recipe"
|
|
12
7
|
|
|
13
8
|
const styles = StyleSheet.create({
|
|
14
9
|
column: { flexDirection: "column", gap: 24, padding: 16 }
|
|
@@ -43,6 +38,10 @@ export default {
|
|
|
43
38
|
control: { type: "boolean" },
|
|
44
39
|
description: "Show/hide quantity picker"
|
|
45
40
|
},
|
|
41
|
+
showImageQuantityBadge: {
|
|
42
|
+
control: { type: "boolean" },
|
|
43
|
+
description: "Show/hide quantity badge overlay on image"
|
|
44
|
+
},
|
|
46
45
|
disableQuantityButtons: {
|
|
47
46
|
control: { type: "boolean" },
|
|
48
47
|
description: "Disable quantity buttons"
|
|
@@ -111,7 +110,7 @@ Playground.args = {
|
|
|
111
110
|
bannerType: "info",
|
|
112
111
|
showBannerIcon: false,
|
|
113
112
|
banner: " High in protein • Natural ingredients • Vet approved",
|
|
114
|
-
image:
|
|
113
|
+
image: placeholderImageUrl
|
|
115
114
|
}
|
|
116
115
|
|
|
117
116
|
export const Default = () => (
|
|
@@ -124,7 +123,7 @@ export const Default = () => (
|
|
|
124
123
|
quantity={1}
|
|
125
124
|
showQuantityPicker={false}
|
|
126
125
|
showBanner={false}
|
|
127
|
-
image={
|
|
126
|
+
image={placeholderImageUrl}
|
|
128
127
|
/>
|
|
129
128
|
</View>
|
|
130
129
|
)
|
|
@@ -139,7 +138,7 @@ export const Desktop = () => (
|
|
|
139
138
|
quantity={1}
|
|
140
139
|
showQuantityPicker
|
|
141
140
|
showBanner={false}
|
|
142
|
-
image={
|
|
141
|
+
image={placeholderImageUrl}
|
|
143
142
|
/>
|
|
144
143
|
</View>
|
|
145
144
|
)
|
|
@@ -154,7 +153,7 @@ export const Mobile = () => (
|
|
|
154
153
|
quantity={1}
|
|
155
154
|
showQuantityPicker
|
|
156
155
|
showBanner={false}
|
|
157
|
-
image={
|
|
156
|
+
image={placeholderImageUrl}
|
|
158
157
|
/>
|
|
159
158
|
</View>
|
|
160
159
|
)
|
|
@@ -172,7 +171,7 @@ export const WithBanner = () => (
|
|
|
172
171
|
bannerType="success"
|
|
173
172
|
showBannerIcon={false}
|
|
174
173
|
banner="High in protein • Natural ingredients • Vet approved"
|
|
175
|
-
image={
|
|
174
|
+
image={placeholderImageUrl}
|
|
176
175
|
/>
|
|
177
176
|
</View>
|
|
178
177
|
)
|
|
@@ -190,7 +189,7 @@ export const WithBannerIcon = () => (
|
|
|
190
189
|
bannerType="success"
|
|
191
190
|
showBannerIcon
|
|
192
191
|
banner="High in protein • Natural ingredients • Vet approved"
|
|
193
|
-
image={
|
|
192
|
+
image={placeholderImageUrl}
|
|
194
193
|
/>
|
|
195
194
|
</View>
|
|
196
195
|
)
|
|
@@ -204,7 +203,35 @@ export const NoSubtext = () => (
|
|
|
204
203
|
quantity={1}
|
|
205
204
|
showQuantityPicker
|
|
206
205
|
showBanner={false}
|
|
207
|
-
image={
|
|
206
|
+
image={placeholderImageUrl}
|
|
207
|
+
/>
|
|
208
|
+
</View>
|
|
209
|
+
)
|
|
210
|
+
|
|
211
|
+
export const WithImageQuantityBadge = () => (
|
|
212
|
+
<View style={styles.column}>
|
|
213
|
+
<ProductDisplayCard
|
|
214
|
+
device="mobile"
|
|
215
|
+
title="Gobble Gobble Turkey"
|
|
216
|
+
subtext="+£0.50/pouch"
|
|
217
|
+
showSubtext
|
|
218
|
+
quantity={4}
|
|
219
|
+
showQuantityPicker={false}
|
|
220
|
+
showImageQuantityBadge
|
|
221
|
+
showBanner={false}
|
|
222
|
+
image={placeholderImageUrl}
|
|
223
|
+
/>
|
|
224
|
+
|
|
225
|
+
<ProductDisplayCard
|
|
226
|
+
device="mobile"
|
|
227
|
+
title="Salmon Delight"
|
|
228
|
+
subtext="+£0.25/pouch"
|
|
229
|
+
showSubtext
|
|
230
|
+
quantity={2}
|
|
231
|
+
showQuantityPicker
|
|
232
|
+
showImageQuantityBadge
|
|
233
|
+
showBanner={false}
|
|
234
|
+
image={placeholderImageUrl}
|
|
208
235
|
/>
|
|
209
236
|
</View>
|
|
210
237
|
)
|
|
@@ -219,7 +246,7 @@ export const AllVariants = () => (
|
|
|
219
246
|
quantity={1}
|
|
220
247
|
showQuantityPicker
|
|
221
248
|
showBanner={false}
|
|
222
|
-
image={
|
|
249
|
+
image={placeholderImageUrl}
|
|
223
250
|
/>
|
|
224
251
|
|
|
225
252
|
<ProductDisplayCard
|
|
@@ -230,7 +257,7 @@ export const AllVariants = () => (
|
|
|
230
257
|
quantity={2}
|
|
231
258
|
showQuantityPicker
|
|
232
259
|
showBanner={false}
|
|
233
|
-
image={
|
|
260
|
+
image={placeholderImageUrl}
|
|
234
261
|
/>
|
|
235
262
|
|
|
236
263
|
<ProductDisplayCard
|
|
@@ -242,7 +269,7 @@ export const AllVariants = () => (
|
|
|
242
269
|
showQuantityPicker
|
|
243
270
|
showBanner
|
|
244
271
|
banner=" High in protein • Natural ingredients"
|
|
245
|
-
image={
|
|
272
|
+
image={placeholderImageUrl}
|
|
246
273
|
/>
|
|
247
274
|
</View>
|
|
248
275
|
)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from "react"
|
|
2
|
-
import { View, ViewProps } from "react-native"
|
|
2
|
+
import { View, ViewProps, Image } from "react-native"
|
|
3
3
|
import styled from "@emotion/native"
|
|
4
4
|
import { Typography } from "../../atoms/Typography"
|
|
5
5
|
import { NumberField } from "../../molecules/NumberField"
|
|
@@ -11,7 +11,7 @@ export type ProductDisplayCardDevice = "desktop" | "mobile"
|
|
|
11
11
|
export type ProductDisplayCardProps = ViewProps & {
|
|
12
12
|
device?: ProductDisplayCardDevice
|
|
13
13
|
title: string
|
|
14
|
-
subtext?: string
|
|
14
|
+
subtext?: string | React.ReactNode
|
|
15
15
|
showSubtext?: boolean
|
|
16
16
|
quantity?: number
|
|
17
17
|
onQuantityChange?: (quantity: number) => void
|
|
@@ -22,7 +22,9 @@ export type ProductDisplayCardProps = ViewProps & {
|
|
|
22
22
|
showDecrementButton?: boolean
|
|
23
23
|
incrementDisabled?: boolean
|
|
24
24
|
decrementDisabled?: boolean
|
|
25
|
-
image?: React.ReactNode
|
|
25
|
+
image?: string | React.ReactNode
|
|
26
|
+
imageBackgroundColor?: string
|
|
27
|
+
showImageQuantityBadge?: boolean
|
|
26
28
|
banner?: React.ReactNode
|
|
27
29
|
showBanner?: boolean
|
|
28
30
|
bannerType?: "error" | "success" | "warning" | "info"
|
|
@@ -55,13 +57,38 @@ const StyledCardContainer = styled(View)<{
|
|
|
55
57
|
}
|
|
56
58
|
})
|
|
57
59
|
|
|
58
|
-
const StyledImage = styled(View)
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
60
|
+
const StyledImage = styled(View)<{ imageBackgroundColor?: string }>(
|
|
61
|
+
({ theme, imageBackgroundColor }) => ({
|
|
62
|
+
flexShrink: 0,
|
|
63
|
+
backgroundColor:
|
|
64
|
+
imageBackgroundColor ||
|
|
65
|
+
theme.tokens.semantics.colour.background.container.secondary,
|
|
66
|
+
overflow: "hidden",
|
|
67
|
+
aspectRatio: "1 / 1",
|
|
68
|
+
height: "100%",
|
|
69
|
+
position: "relative"
|
|
70
|
+
})
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
const StyledQuantityBadge = styled(View)(({ theme }) => {
|
|
74
|
+
const spacing = theme.tokens.semantics.dimensions.spacing
|
|
75
|
+
const borderRadius = theme.tokens.semantics.dimensions.borderRadius
|
|
76
|
+
const { colour } = theme.tokens.semantics
|
|
77
|
+
|
|
78
|
+
return {
|
|
79
|
+
position: "absolute",
|
|
80
|
+
top: parseTokenValue(spacing["2xs"]),
|
|
81
|
+
right: parseTokenValue(spacing["2xs"]),
|
|
82
|
+
backgroundColor: colour.background.container.brand,
|
|
83
|
+
borderRadius: parseTokenValue(borderRadius.xs),
|
|
84
|
+
paddingHorizontal: parseTokenValue(spacing.sm),
|
|
85
|
+
height: parseTokenValue(spacing["2xl"]),
|
|
86
|
+
minWidth: parseTokenValue(spacing["2xl"]),
|
|
87
|
+
alignItems: "center",
|
|
88
|
+
justifyContent: "center",
|
|
89
|
+
zIndex: 2
|
|
90
|
+
}
|
|
91
|
+
})
|
|
65
92
|
|
|
66
93
|
const StyledContentArea = styled(View)<{
|
|
67
94
|
contentDevice: ProductDisplayCardDevice
|
|
@@ -122,12 +149,14 @@ const StyledNotification = styled(Notification as any)(({ theme }) => {
|
|
|
122
149
|
*
|
|
123
150
|
* @param device - *(optional)* Device variant: "desktop" or "mobile" (default)
|
|
124
151
|
* @param title - Product title
|
|
125
|
-
* @param subtext - *(optional)* Subtitle text (e.g. price)
|
|
152
|
+
* @param subtext - *(optional)* Subtitle text or JSX element (e.g. price)
|
|
126
153
|
* @param showSubtext - *(optional)* Show/hide subtext
|
|
127
154
|
* @param quantity - *(optional)* Current quantity value
|
|
128
155
|
* @param onQuantityChange - *(optional)* Callback when quantity changes
|
|
129
156
|
* @param showQuantityPicker - *(optional)* Show/hide quantity picker
|
|
130
|
-
* @param image - *(optional)* Image
|
|
157
|
+
* @param image - *(optional)* Image URL string or React element/JSX content
|
|
158
|
+
* @param imageBackgroundColor - *(optional)* Background color for image container (default: theme background.container.secondary)
|
|
159
|
+
* @param showImageQuantityBadge - *(optional)* Show/hide quantity badge overlay on image
|
|
131
160
|
* @param banner - *(optional)* Banner content to show below card
|
|
132
161
|
* @param showBanner - *(optional)* Show/hide banner
|
|
133
162
|
* @param bannerType - *(optional)* Banner notification type: "error", "success", "warning", or "info" (default)
|
|
@@ -153,6 +182,8 @@ export const ProductDisplayCard = React.forwardRef<
|
|
|
153
182
|
incrementDisabled = false,
|
|
154
183
|
decrementDisabled = false,
|
|
155
184
|
image,
|
|
185
|
+
imageBackgroundColor,
|
|
186
|
+
showImageQuantityBadge = false,
|
|
156
187
|
banner,
|
|
157
188
|
showBanner = false,
|
|
158
189
|
bannerType = "info",
|
|
@@ -169,7 +200,25 @@ export const ProductDisplayCard = React.forwardRef<
|
|
|
169
200
|
|
|
170
201
|
const cardContent = (
|
|
171
202
|
<StyledCardContainer ref={ref} cardDevice={device} {...rest}>
|
|
172
|
-
{image &&
|
|
203
|
+
{image && (
|
|
204
|
+
<StyledImage imageBackgroundColor={imageBackgroundColor}>
|
|
205
|
+
{typeof image === "string" ? (
|
|
206
|
+
<Image
|
|
207
|
+
source={{ uri: image }}
|
|
208
|
+
style={{ width: "100%", height: "100%" }}
|
|
209
|
+
/>
|
|
210
|
+
) : (
|
|
211
|
+
image
|
|
212
|
+
)}
|
|
213
|
+
{showImageQuantityBadge && quantity && (
|
|
214
|
+
<StyledQuantityBadge>
|
|
215
|
+
<Typography variant="body" size="sm" weight="bold">
|
|
216
|
+
{quantity}
|
|
217
|
+
</Typography>
|
|
218
|
+
</StyledQuantityBadge>
|
|
219
|
+
)}
|
|
220
|
+
</StyledImage>
|
|
221
|
+
)}
|
|
173
222
|
|
|
174
223
|
<StyledContentArea contentDevice={device}>
|
|
175
224
|
<StyledTextContainer>
|