@butternutbox/pawprint-native 0.1.0 → 0.2.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 +8 -8
- package/CHANGELOG.md +20 -0
- package/dist/index.cjs +2213 -2174
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -3
- package/dist/index.d.ts +2 -3
- package/dist/index.js +2212 -2173
- package/dist/index.js.map +1 -1
- package/package.json +3 -4
- package/src/components/atoms/Illustration/Illustration.stories.tsx +2 -2
- package/src/components/atoms/Illustration/Illustration.tsx +3 -3
- package/src/components/atoms/Link/Link.test.tsx +3 -3
- package/src/components/atoms/Link/Link.tsx +7 -6
- package/src/components/atoms/Switch/Switch.tsx +13 -5
- package/src/components/molecules/ButtonDock/ButtonDock.stories.tsx +44 -25
- package/src/components/molecules/ButtonDock/ButtonDock.tsx +16 -13
- package/src/components/molecules/ButtonGroup/ButtonGroup.stories.tsx +47 -22
- package/src/components/molecules/FilterTab/FilterTab.tsx +4 -4
- package/src/components/molecules/PasswordField/PasswordFieldError.tsx +6 -5
- package/src/components/molecules/PasswordField/PasswordFieldRequirements.tsx +11 -8
- package/src/components/molecules/PictureSelector/PictureSelector.stories.tsx +0 -39
- package/src/components/molecules/PictureSelector/PictureSelector.tsx +58 -36
- package/tsup.config.ts +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@butternutbox/pawprint-native",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "ButternutBox Pawprint Design System - React Native Components",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -22,19 +22,18 @@
|
|
|
22
22
|
"test": "vitest run"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@butternutbox/pawprint-tokens": "^0.
|
|
25
|
+
"@butternutbox/pawprint-tokens": "^0.2.0",
|
|
26
26
|
"@emotion/native": "^11.11.0",
|
|
27
27
|
"@emotion/react": "^11.14.0",
|
|
28
28
|
"@rn-primitives/avatar": "^1.4.0",
|
|
29
29
|
"@rn-primitives/checkbox": "^1.4.0",
|
|
30
30
|
"@rn-primitives/portal": "^1.0.5",
|
|
31
31
|
"@rn-primitives/progress": "^1.4.0",
|
|
32
|
+
"@rn-primitives/select": "^1.4.0",
|
|
32
33
|
"@rn-primitives/slider": "^1.4.0",
|
|
33
34
|
"@rn-primitives/slot": "^1.0.5",
|
|
34
35
|
"@rn-primitives/switch": "^1.4.0",
|
|
35
|
-
"@rn-primitives/toggle": "^1.4.0",
|
|
36
36
|
"@rn-primitives/tooltip": "^1.4.0",
|
|
37
|
-
"@rn-primitives/types": "^1.0.5",
|
|
38
37
|
"date-fns": "^4.1.0",
|
|
39
38
|
"expo": "^55.0.9"
|
|
40
39
|
},
|
|
@@ -42,7 +42,7 @@ export default {
|
|
|
42
42
|
argTypes: {
|
|
43
43
|
size: {
|
|
44
44
|
control: { type: "select" },
|
|
45
|
-
options: ["sm", "lg"] as IllustrationSize[],
|
|
45
|
+
options: ["sm", "lg", "xl"] as IllustrationSize[],
|
|
46
46
|
description: "Size variant (controls height)"
|
|
47
47
|
},
|
|
48
48
|
illustration: {
|
|
@@ -71,7 +71,7 @@ Default.args = {
|
|
|
71
71
|
size: "sm"
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
const allSizes: IllustrationSize[] = ["sm", "lg"]
|
|
74
|
+
const allSizes: IllustrationSize[] = ["sm", "lg", "xl"]
|
|
75
75
|
|
|
76
76
|
export const AllSizes = () => {
|
|
77
77
|
const sample = illustrationMap[defaultIllustration] as PawprintIllustration
|
|
@@ -3,7 +3,7 @@ import { View, ViewProps } from "react-native"
|
|
|
3
3
|
import styled from "@emotion/native"
|
|
4
4
|
import { useTheme } from "@emotion/react"
|
|
5
5
|
|
|
6
|
-
type IllustrationSize = "sm" | "lg"
|
|
6
|
+
type IllustrationSize = "sm" | "lg" | "xl"
|
|
7
7
|
|
|
8
8
|
type PawprintIllustration = React.ComponentType<{
|
|
9
9
|
width?: number
|
|
@@ -42,7 +42,7 @@ const StyledRoot = styled(View)<{
|
|
|
42
42
|
* ```
|
|
43
43
|
*
|
|
44
44
|
* @param illustration - **(required)** Illustration component
|
|
45
|
-
* @param size - *(optional)* Size variant: sm (default), lg
|
|
45
|
+
* @param size - *(optional)* Size variant: sm (default), lg, xl
|
|
46
46
|
* @param aria-label - *(optional)* Accessible label
|
|
47
47
|
*/
|
|
48
48
|
const Illustration = React.forwardRef<View, IllustrationProps>(
|
|
@@ -69,7 +69,7 @@ const Illustration = React.forwardRef<View, IllustrationProps>(
|
|
|
69
69
|
accessible={!!ariaLabel}
|
|
70
70
|
{...rest}
|
|
71
71
|
>
|
|
72
|
-
<IllustrationComponent height={dimension} />
|
|
72
|
+
<IllustrationComponent width={dimension} height={dimension} />
|
|
73
73
|
</StyledRoot>
|
|
74
74
|
)
|
|
75
75
|
}
|
|
@@ -19,10 +19,10 @@ describe("Link", () => {
|
|
|
19
19
|
})
|
|
20
20
|
|
|
21
21
|
describe("when rendering standalone", () => {
|
|
22
|
-
it("renders with trailing arrow", () => {
|
|
23
|
-
renderWithTheme(<Link standalone>Standalone</Link>)
|
|
22
|
+
it("renders with trailing arrow icon", () => {
|
|
23
|
+
const { container } = renderWithTheme(<Link standalone>Standalone</Link>)
|
|
24
24
|
expect(screen.getByText("Standalone")).toBeInTheDocument()
|
|
25
|
-
expect(
|
|
25
|
+
expect(container.querySelector("svg")).toBeInTheDocument()
|
|
26
26
|
})
|
|
27
27
|
})
|
|
28
28
|
|
|
@@ -7,6 +7,8 @@ import {
|
|
|
7
7
|
ViewStyle
|
|
8
8
|
} from "react-native"
|
|
9
9
|
import { useTheme } from "@emotion/react"
|
|
10
|
+
import { ArrowForward } from "@butternutbox/pawprint-icons/core"
|
|
11
|
+
import { Icon } from "../Icon"
|
|
10
12
|
import { Typography } from "../Typography"
|
|
11
13
|
|
|
12
14
|
export type LinkSize = "sm" | "md" | "lg"
|
|
@@ -101,12 +103,11 @@ export const Link = React.forwardRef<View, LinkProps>(
|
|
|
101
103
|
{children}
|
|
102
104
|
</Typography>
|
|
103
105
|
{standalone && (
|
|
104
|
-
<
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
</Typography>
|
|
106
|
+
<Icon
|
|
107
|
+
icon={ArrowForward}
|
|
108
|
+
size="xs"
|
|
109
|
+
customColour={pressed ? linkColour.hover : linkColour.default}
|
|
110
|
+
/>
|
|
110
111
|
)}
|
|
111
112
|
</>
|
|
112
113
|
)}
|
|
@@ -52,9 +52,13 @@ const StyledControlTrack = styled(View)<{
|
|
|
52
52
|
minWidth: controlWidth,
|
|
53
53
|
minHeight: controlHeight,
|
|
54
54
|
borderRadius: controlHeight,
|
|
55
|
-
|
|
55
|
+
// Keep the border width constant and only toggle the colour. Animating
|
|
56
|
+
// the width between 0 and 2 was causing a momentary background bleed on
|
|
57
|
+
// Android when transitioning back to the off state.
|
|
58
|
+
borderWidth: controlBorderWidth,
|
|
56
59
|
borderColor: switchChecked ? "transparent" : controlBorderColor,
|
|
57
60
|
backgroundColor: switchChecked ? controlBgChecked : controlBgDefault,
|
|
61
|
+
overflow: "hidden",
|
|
58
62
|
justifyContent: "center"
|
|
59
63
|
})
|
|
60
64
|
)
|
|
@@ -113,9 +117,13 @@ export const Switch = React.forwardRef<View, SwitchProps>(
|
|
|
113
117
|
const controlHeight = parseTokenValue(size.control.height)
|
|
114
118
|
const thumbSize = parseTokenValue(size.thumb.default)
|
|
115
119
|
const borderWidthValue = parseTokenValue(borderWidth.control.default)
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
120
|
+
// Thumb sits 2px inside the inner border edge in both states. With the
|
|
121
|
+
// border width constant, the absolute-position reference frame is the
|
|
122
|
+
// padding box in both states, so the on-state inset is
|
|
123
|
+
// controlWidth - 2*border - thumbSize - inset.
|
|
124
|
+
const inset = 2
|
|
125
|
+
const offTranslateX = inset
|
|
126
|
+
const onTranslateX = controlWidth - borderWidthValue * 2 - thumbSize - inset
|
|
119
127
|
|
|
120
128
|
const animValue = useRef(new Animated.Value(isChecked ? 1 : 0)).current
|
|
121
129
|
|
|
@@ -129,7 +137,7 @@ export const Switch = React.forwardRef<View, SwitchProps>(
|
|
|
129
137
|
|
|
130
138
|
const thumbTranslateX = animValue.interpolate({
|
|
131
139
|
inputRange: [0, 1],
|
|
132
|
-
outputRange: [
|
|
140
|
+
outputRange: [offTranslateX, onTranslateX]
|
|
133
141
|
})
|
|
134
142
|
|
|
135
143
|
const handleCheckedChange = (checked: boolean) => {
|
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
import React from "react"
|
|
2
|
-
import { View, StyleSheet
|
|
2
|
+
import { View, StyleSheet } from "react-native"
|
|
3
|
+
import {
|
|
4
|
+
KeyboardArrowLeft,
|
|
5
|
+
KeyboardArrowRight
|
|
6
|
+
} from "@butternutbox/pawprint-icons/core"
|
|
3
7
|
import { ButtonDock } from "./ButtonDock"
|
|
4
8
|
import type { ButtonDockProps } from "./ButtonDock"
|
|
5
9
|
import { Button } from "../../atoms/Button"
|
|
10
|
+
import { Icon } from "../../atoms/Icon"
|
|
6
11
|
|
|
7
12
|
export default {
|
|
8
13
|
title: "Molecules/ButtonDock",
|
|
@@ -11,7 +16,7 @@ export default {
|
|
|
11
16
|
variant: {
|
|
12
17
|
control: { type: "select" },
|
|
13
18
|
options: ["stacked", "inline"],
|
|
14
|
-
description: "Layout variant
|
|
19
|
+
description: "Layout variant"
|
|
15
20
|
},
|
|
16
21
|
description: {
|
|
17
22
|
control: { type: "text" },
|
|
@@ -23,13 +28,13 @@ export default {
|
|
|
23
28
|
export const Playground = {
|
|
24
29
|
args: {
|
|
25
30
|
variant: "stacked",
|
|
26
|
-
description: "
|
|
31
|
+
description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit."
|
|
27
32
|
},
|
|
28
33
|
render: (args: ButtonDockProps) => (
|
|
29
34
|
<ButtonDock {...args}>
|
|
30
35
|
<Button fullWidth>Continue</Button>
|
|
31
|
-
<Button fullWidth variant="
|
|
32
|
-
|
|
36
|
+
<Button fullWidth variant="filled" colour="secondary">
|
|
37
|
+
Back
|
|
33
38
|
</Button>
|
|
34
39
|
</ButtonDock>
|
|
35
40
|
)
|
|
@@ -37,10 +42,13 @@ export const Playground = {
|
|
|
37
42
|
|
|
38
43
|
export const Stacked = () => (
|
|
39
44
|
<View style={styles.column}>
|
|
40
|
-
<ButtonDock
|
|
45
|
+
<ButtonDock
|
|
46
|
+
variant="stacked"
|
|
47
|
+
description="Lorem ipsum dolor sit amet, consectetur adipiscing elit."
|
|
48
|
+
>
|
|
41
49
|
<Button fullWidth>Continue</Button>
|
|
42
|
-
<Button fullWidth variant="
|
|
43
|
-
|
|
50
|
+
<Button fullWidth variant="filled" colour="secondary">
|
|
51
|
+
Back
|
|
44
52
|
</Button>
|
|
45
53
|
</ButtonDock>
|
|
46
54
|
</View>
|
|
@@ -49,8 +57,22 @@ export const Stacked = () => (
|
|
|
49
57
|
export const Inline = () => (
|
|
50
58
|
<View style={styles.column}>
|
|
51
59
|
<ButtonDock variant="inline">
|
|
52
|
-
<Button
|
|
53
|
-
|
|
60
|
+
<Button
|
|
61
|
+
variant="filled"
|
|
62
|
+
colour="secondary"
|
|
63
|
+
startIcon={
|
|
64
|
+
<Icon icon={KeyboardArrowLeft} size="md" colour="action-default" />
|
|
65
|
+
}
|
|
66
|
+
>
|
|
67
|
+
Back
|
|
68
|
+
</Button>
|
|
69
|
+
<Button
|
|
70
|
+
endIcon={
|
|
71
|
+
<Icon icon={KeyboardArrowRight} size="md" colour="action-inverse" />
|
|
72
|
+
}
|
|
73
|
+
>
|
|
74
|
+
Continue
|
|
75
|
+
</Button>
|
|
54
76
|
</ButtonDock>
|
|
55
77
|
</View>
|
|
56
78
|
)
|
|
@@ -59,16 +81,12 @@ export const WithLeadingContent = () => (
|
|
|
59
81
|
<View style={styles.column}>
|
|
60
82
|
<ButtonDock
|
|
61
83
|
variant="stacked"
|
|
62
|
-
leadingContent={
|
|
63
|
-
|
|
64
|
-
By continuing you agree to our terms and conditions.
|
|
65
|
-
</Text>
|
|
66
|
-
}
|
|
67
|
-
description="You can change this later in settings."
|
|
84
|
+
leadingContent={<View style={styles.leadingSlot} />}
|
|
85
|
+
description="Lorem ipsum dolor sit amet, consectetur adipiscing elit."
|
|
68
86
|
>
|
|
69
|
-
<Button fullWidth>
|
|
70
|
-
<Button fullWidth variant="
|
|
71
|
-
|
|
87
|
+
<Button fullWidth>Continue</Button>
|
|
88
|
+
<Button fullWidth variant="filled" colour="secondary">
|
|
89
|
+
Back
|
|
72
90
|
</Button>
|
|
73
91
|
</ButtonDock>
|
|
74
92
|
</View>
|
|
@@ -76,8 +94,8 @@ export const WithLeadingContent = () => (
|
|
|
76
94
|
|
|
77
95
|
export const StackedSingleButton = () => (
|
|
78
96
|
<View style={styles.column}>
|
|
79
|
-
<ButtonDock variant="stacked"
|
|
80
|
-
<Button fullWidth>
|
|
97
|
+
<ButtonDock variant="stacked">
|
|
98
|
+
<Button fullWidth>Update</Button>
|
|
81
99
|
</ButtonDock>
|
|
82
100
|
</View>
|
|
83
101
|
)
|
|
@@ -87,9 +105,10 @@ const styles = StyleSheet.create({
|
|
|
87
105
|
flexDirection: "column",
|
|
88
106
|
gap: 24
|
|
89
107
|
},
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
108
|
+
leadingSlot: {
|
|
109
|
+
height: 64,
|
|
110
|
+
width: "100%",
|
|
111
|
+
backgroundColor: "#f5f5f5",
|
|
112
|
+
borderRadius: 8
|
|
94
113
|
}
|
|
95
114
|
})
|
|
@@ -39,12 +39,14 @@ const StyledDockRoot = styled(View)<{
|
|
|
39
39
|
})
|
|
40
40
|
)
|
|
41
41
|
|
|
42
|
-
const StyledStackedInner = styled(View)(
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
42
|
+
const StyledStackedInner = styled(View)<{ innerGap: number }>(
|
|
43
|
+
({ innerGap }) => ({
|
|
44
|
+
alignItems: "center",
|
|
45
|
+
gap: innerGap,
|
|
46
|
+
width: "100%",
|
|
47
|
+
maxWidth: 520
|
|
48
|
+
})
|
|
49
|
+
)
|
|
48
50
|
|
|
49
51
|
const StyledButtonGroup = styled(View)<{
|
|
50
52
|
groupDirection: "column" | "row"
|
|
@@ -85,7 +87,7 @@ const ButtonDock = React.forwardRef<View, ButtonDockProps>(
|
|
|
85
87
|
) => {
|
|
86
88
|
const theme = useTheme()
|
|
87
89
|
const { buttonDock, buttonGroup } = theme.tokens.components
|
|
88
|
-
const { dimensions } = theme.tokens.semantics
|
|
90
|
+
const { dimensions, typography } = theme.tokens.semantics
|
|
89
91
|
const isStacked = variant === "stacked"
|
|
90
92
|
|
|
91
93
|
const groupGap = parseTokenValue(
|
|
@@ -101,12 +103,14 @@ const ButtonDock = React.forwardRef<View, ButtonDockProps>(
|
|
|
101
103
|
dockBorderTopWidth={parseTokenValue(dimensions.borderWidth.sm)}
|
|
102
104
|
dockBorderTopColor={buttonDock.colour.border}
|
|
103
105
|
dockPaddingVertical={parseTokenValue(
|
|
104
|
-
buttonDock.spacing[variant].
|
|
106
|
+
buttonDock.spacing[variant].mobile.topPadding
|
|
105
107
|
)}
|
|
106
108
|
{...rest}
|
|
107
109
|
>
|
|
108
110
|
{isStacked ? (
|
|
109
|
-
<StyledStackedInner
|
|
111
|
+
<StyledStackedInner
|
|
112
|
+
innerGap={parseTokenValue(buttonGroup.spacing.gap)}
|
|
113
|
+
>
|
|
110
114
|
{leadingContent}
|
|
111
115
|
<StyledButtonGroup
|
|
112
116
|
groupDirection="column"
|
|
@@ -118,12 +122,11 @@ const ButtonDock = React.forwardRef<View, ButtonDockProps>(
|
|
|
118
122
|
</StyledButtonGroup>
|
|
119
123
|
{description && (
|
|
120
124
|
<Typography
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
weight="medium"
|
|
125
|
+
token={typography.body.medium.md}
|
|
126
|
+
color={buttonGroup.colour.text}
|
|
124
127
|
align="center"
|
|
125
128
|
>
|
|
126
|
-
{
|
|
129
|
+
{description}
|
|
127
130
|
</Typography>
|
|
128
131
|
)}
|
|
129
132
|
</StyledStackedInner>
|
|
@@ -11,59 +11,84 @@ export default {
|
|
|
11
11
|
layout: {
|
|
12
12
|
control: { type: "select" },
|
|
13
13
|
options: ["stacked", "inline"],
|
|
14
|
-
description: "Layout direction
|
|
14
|
+
description: "Layout direction for the buttons"
|
|
15
15
|
},
|
|
16
16
|
description: {
|
|
17
17
|
control: { type: "text" },
|
|
18
|
-
description: "Optional text below buttons"
|
|
18
|
+
description: "Optional text displayed below the buttons"
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
23
|
+
type PlaygroundArgs = ButtonGroupProps & {
|
|
24
|
+
primaryLabel: string
|
|
25
|
+
secondaryLabel: string
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export const Playground = ({
|
|
29
|
+
primaryLabel,
|
|
30
|
+
secondaryLabel,
|
|
31
|
+
...args
|
|
32
|
+
}: PlaygroundArgs) => (
|
|
33
|
+
<ButtonGroup {...args}>
|
|
34
|
+
<Button colour="primary">{primaryLabel}</Button>
|
|
35
|
+
{secondaryLabel?.trim() && (
|
|
36
|
+
<Button colour="secondary">{secondaryLabel}</Button>
|
|
37
|
+
)}
|
|
38
|
+
</ButtonGroup>
|
|
39
|
+
)
|
|
40
|
+
Playground.args = {
|
|
41
|
+
layout: "stacked",
|
|
42
|
+
description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
|
|
43
|
+
primaryLabel: "Confirm",
|
|
44
|
+
secondaryLabel: "Cancel"
|
|
45
|
+
}
|
|
46
|
+
Playground.argTypes = {
|
|
47
|
+
primaryLabel: {
|
|
48
|
+
control: { type: "text" },
|
|
49
|
+
description: "Label for the primary button"
|
|
27
50
|
},
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
)
|
|
51
|
+
secondaryLabel: {
|
|
52
|
+
control: { type: "text" },
|
|
53
|
+
description:
|
|
54
|
+
"Label for the secondary button (leave empty for single button)"
|
|
55
|
+
}
|
|
34
56
|
}
|
|
35
57
|
|
|
36
58
|
export const Stacked = () => (
|
|
37
59
|
<View style={styles.column}>
|
|
38
|
-
<ButtonGroup
|
|
39
|
-
<Button>
|
|
40
|
-
<Button
|
|
60
|
+
<ButtonGroup description="Lorem ipsum dolor sit amet, consectetur adipiscing elit.">
|
|
61
|
+
<Button colour="primary">Confirm</Button>
|
|
62
|
+
<Button colour="secondary">Cancel</Button>
|
|
41
63
|
</ButtonGroup>
|
|
42
64
|
</View>
|
|
43
65
|
)
|
|
44
66
|
|
|
45
67
|
export const Inline = () => (
|
|
46
68
|
<View style={styles.column}>
|
|
47
|
-
<ButtonGroup
|
|
69
|
+
<ButtonGroup
|
|
70
|
+
layout="inline"
|
|
71
|
+
description="Lorem ipsum dolor sit amet, consectetur adipiscing elit."
|
|
72
|
+
>
|
|
48
73
|
<Button colour="secondary">Cancel</Button>
|
|
49
|
-
<Button>Confirm</Button>
|
|
74
|
+
<Button colour="primary">Confirm</Button>
|
|
50
75
|
</ButtonGroup>
|
|
51
76
|
</View>
|
|
52
77
|
)
|
|
53
78
|
|
|
54
79
|
export const SingleButton = () => (
|
|
55
80
|
<View style={styles.column}>
|
|
56
|
-
<ButtonGroup
|
|
57
|
-
<Button>Continue</Button>
|
|
81
|
+
<ButtonGroup description="Lorem ipsum dolor sit amet, consectetur adipiscing elit.">
|
|
82
|
+
<Button colour="primary">Continue</Button>
|
|
58
83
|
</ButtonGroup>
|
|
59
84
|
</View>
|
|
60
85
|
)
|
|
61
86
|
|
|
62
87
|
export const WithoutDescription = () => (
|
|
63
88
|
<View style={styles.column}>
|
|
64
|
-
<ButtonGroup
|
|
65
|
-
<Button>Confirm</Button>
|
|
66
|
-
<Button
|
|
89
|
+
<ButtonGroup>
|
|
90
|
+
<Button colour="primary">Confirm</Button>
|
|
91
|
+
<Button colour="secondary">Cancel</Button>
|
|
67
92
|
</ButtonGroup>
|
|
68
93
|
</View>
|
|
69
94
|
)
|
|
@@ -64,7 +64,6 @@ const StyledItem = styled(Pressable)<{
|
|
|
64
64
|
itemHeight: number
|
|
65
65
|
itemMinWidth: number
|
|
66
66
|
itemPaddingH: number
|
|
67
|
-
itemPaddingV: number
|
|
68
67
|
itemBorderRadius: number
|
|
69
68
|
itemBgColor: string
|
|
70
69
|
itemOpacity: number
|
|
@@ -74,7 +73,6 @@ const StyledItem = styled(Pressable)<{
|
|
|
74
73
|
itemHeight,
|
|
75
74
|
itemMinWidth,
|
|
76
75
|
itemPaddingH,
|
|
77
|
-
itemPaddingV,
|
|
78
76
|
itemBorderRadius,
|
|
79
77
|
itemBgColor,
|
|
80
78
|
itemOpacity,
|
|
@@ -88,7 +86,10 @@ const StyledItem = styled(Pressable)<{
|
|
|
88
86
|
? { width: itemHeight, maxWidth: itemHeight }
|
|
89
87
|
: { minWidth: itemMinWidth }),
|
|
90
88
|
paddingHorizontal: itemPaddingH,
|
|
91
|
-
|
|
89
|
+
// Vertical padding is intentionally omitted: with a fixed `height` and
|
|
90
|
+
// flex centering, the label sits in the middle of the box. Applying
|
|
91
|
+
// `verticalPadding: 12px` on top of the 36px small height would leave a
|
|
92
|
+
// 12px inner area, clipping the 18px line-height text on Android.
|
|
92
93
|
borderRadius: itemBorderRadius,
|
|
93
94
|
backgroundColor: itemBgColor,
|
|
94
95
|
opacity: itemOpacity,
|
|
@@ -159,7 +160,6 @@ const FilterTabItem = React.forwardRef<View, FilterTabItemProps>(
|
|
|
159
160
|
itemHeight={height}
|
|
160
161
|
itemMinWidth={minWidth}
|
|
161
162
|
itemPaddingH={parseTokenValue(tabItem.spacing.horizontalPadding)}
|
|
162
|
-
itemPaddingV={parseTokenValue(tabItem.spacing.verticalPadding)}
|
|
163
163
|
itemBorderRadius={parseTokenValue(tabItem.borderRadius.default)}
|
|
164
164
|
itemBgColor={
|
|
165
165
|
isActive
|
|
@@ -30,18 +30,19 @@ export const PasswordFieldError = React.forwardRef<
|
|
|
30
30
|
PasswordFieldErrorProps
|
|
31
31
|
>(({ children, ...rest }, ref) => {
|
|
32
32
|
const theme = useTheme()
|
|
33
|
-
const {
|
|
33
|
+
const { listItem } = theme.tokens.components.validationList
|
|
34
|
+
const { typography } = theme.tokens.semantics
|
|
34
35
|
|
|
35
36
|
return (
|
|
36
37
|
<StyledErrorRow
|
|
37
38
|
ref={ref}
|
|
38
|
-
gap={parseTokenValue(spacing.
|
|
39
|
+
gap={parseTokenValue(listItem.spacing.gap)}
|
|
39
40
|
{...rest}
|
|
40
41
|
>
|
|
41
|
-
<Icon icon={Cancel} size="
|
|
42
|
+
<Icon icon={Cancel} size="xs" customColour={listItem.colour.icon.error} />
|
|
42
43
|
<Typography
|
|
43
|
-
token={
|
|
44
|
-
color={colour.
|
|
44
|
+
token={typography.body.medium.md}
|
|
45
|
+
color={listItem.colour.text.default}
|
|
45
46
|
>
|
|
46
47
|
{children}
|
|
47
48
|
</Typography>
|
|
@@ -46,7 +46,8 @@ export const PasswordFieldRequirements = React.forwardRef<
|
|
|
46
46
|
PasswordFieldRequirementsProps
|
|
47
47
|
>(({ requirements, ...rest }, ref) => {
|
|
48
48
|
const theme = useTheme()
|
|
49
|
-
const {
|
|
49
|
+
const { listItem, list } = theme.tokens.components.validationList
|
|
50
|
+
const { typography } = theme.tokens.semantics
|
|
50
51
|
|
|
51
52
|
if (!requirements || requirements.length === 0) {
|
|
52
53
|
return null
|
|
@@ -60,25 +61,27 @@ export const PasswordFieldRequirements = React.forwardRef<
|
|
|
60
61
|
return (
|
|
61
62
|
<StyledRequirementsList
|
|
62
63
|
ref={ref}
|
|
63
|
-
listGap={parseTokenValue(spacing.
|
|
64
|
+
listGap={parseTokenValue(list.spacing.gap)}
|
|
64
65
|
{...rest}
|
|
65
66
|
>
|
|
66
67
|
{normalizedRequirements.map((requirement, index) => {
|
|
67
|
-
const iconColour = requirement.satisfied
|
|
68
|
+
const iconColour = requirement.satisfied
|
|
69
|
+
? listItem.colour.icon.success
|
|
70
|
+
: listItem.colour.icon.error
|
|
68
71
|
|
|
69
72
|
return (
|
|
70
73
|
<StyledRequirementItem
|
|
71
74
|
key={index}
|
|
72
|
-
itemGap={parseTokenValue(spacing.
|
|
75
|
+
itemGap={parseTokenValue(listItem.spacing.gap)}
|
|
73
76
|
>
|
|
74
77
|
<Icon
|
|
75
78
|
icon={requirement.satisfied ? CheckCircle : Cancel}
|
|
76
|
-
size="
|
|
77
|
-
|
|
79
|
+
size="xs"
|
|
80
|
+
customColour={iconColour}
|
|
78
81
|
/>
|
|
79
82
|
<Typography
|
|
80
|
-
token={
|
|
81
|
-
color={colour.
|
|
83
|
+
token={typography.body.medium.md}
|
|
84
|
+
color={listItem.colour.text.default}
|
|
82
85
|
>
|
|
83
86
|
{requirement.text}
|
|
84
87
|
</Typography>
|
|
@@ -7,12 +7,6 @@ import {
|
|
|
7
7
|
ExcitedPrimaryFilled,
|
|
8
8
|
DogWithBallPrimaryFilled
|
|
9
9
|
} from "@butternutbox/pawprint-illustrations/poses"
|
|
10
|
-
import {
|
|
11
|
-
CheckCircle,
|
|
12
|
-
StarRate,
|
|
13
|
-
Female,
|
|
14
|
-
Male
|
|
15
|
-
} from "@butternutbox/pawprint-icons/core"
|
|
16
10
|
|
|
17
11
|
export default {
|
|
18
12
|
title: "Molecules/PictureSelector"
|
|
@@ -152,39 +146,6 @@ export const WithoutInsight = () => (
|
|
|
152
146
|
</View>
|
|
153
147
|
)
|
|
154
148
|
|
|
155
|
-
export const WithIcons = () => (
|
|
156
|
-
<View style={styles.column}>
|
|
157
|
-
<PictureSelector
|
|
158
|
-
label="Sex"
|
|
159
|
-
defaultValue="female"
|
|
160
|
-
items={[
|
|
161
|
-
{
|
|
162
|
-
value: "female",
|
|
163
|
-
icon: Female,
|
|
164
|
-
ariaLabel: "Female"
|
|
165
|
-
},
|
|
166
|
-
{
|
|
167
|
-
value: "male",
|
|
168
|
-
icon: Male,
|
|
169
|
-
ariaLabel: "Male"
|
|
170
|
-
},
|
|
171
|
-
{
|
|
172
|
-
value: "either",
|
|
173
|
-
icon: StarRate,
|
|
174
|
-
ariaLabel: "Either",
|
|
175
|
-
insightTitle: "Either",
|
|
176
|
-
insightDescription: "We'll help you decide later."
|
|
177
|
-
},
|
|
178
|
-
{
|
|
179
|
-
value: "verified",
|
|
180
|
-
icon: CheckCircle,
|
|
181
|
-
ariaLabel: "Verified"
|
|
182
|
-
}
|
|
183
|
-
]}
|
|
184
|
-
/>
|
|
185
|
-
</View>
|
|
186
|
-
)
|
|
187
|
-
|
|
188
149
|
export const WithDisabledItem = () => (
|
|
189
150
|
<View style={styles.column}>
|
|
190
151
|
<PictureSelector
|