@butternutbox/pawprint-native 0.0.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.
Files changed (105) hide show
  1. package/.turbo/turbo-build.log +30 -0
  2. package/COMPONENT_GUIDELINES.md +610 -0
  3. package/README.md +72 -0
  4. package/dist/ibm-plex-sans-condensed-400-normal-I2XLJNNB.woff2 +0 -0
  5. package/dist/ibm-plex-sans-condensed-500-normal-IEQBNVGX.woff2 +0 -0
  6. package/dist/ibm-plex-sans-condensed-600-normal-UX5ZU5T6.woff2 +0 -0
  7. package/dist/ibm-plex-sans-condensed-700-normal-4PFYFTSO.woff2 +0 -0
  8. package/dist/ida-narrow-500-normal-C6I2PK4T.woff2 +0 -0
  9. package/dist/ida-narrow-700-normal-UPHPRIN6.woff2 +0 -0
  10. package/dist/index.cjs +2686 -0
  11. package/dist/index.cjs.map +1 -0
  12. package/dist/index.d.cts +780 -0
  13. package/dist/index.d.ts +780 -0
  14. package/dist/index.js +2617 -0
  15. package/dist/index.js.map +1 -0
  16. package/eslint.config.js +3 -0
  17. package/llms.txt +458 -0
  18. package/package.json +57 -0
  19. package/src/components/atoms/Avatar/Avatar.stories.tsx +125 -0
  20. package/src/components/atoms/Avatar/Avatar.tsx +159 -0
  21. package/src/components/atoms/Avatar/index.ts +7 -0
  22. package/src/components/atoms/Badge/Badge.stories.tsx +231 -0
  23. package/src/components/atoms/Badge/Badge.tsx +184 -0
  24. package/src/components/atoms/Badge/index.ts +2 -0
  25. package/src/components/atoms/Button/Button.stories.tsx +145 -0
  26. package/src/components/atoms/Button/Button.tsx +261 -0
  27. package/src/components/atoms/Button/index.ts +7 -0
  28. package/src/components/atoms/Hint/Hint.stories.tsx +84 -0
  29. package/src/components/atoms/Hint/Hint.tsx +59 -0
  30. package/src/components/atoms/Hint/index.ts +2 -0
  31. package/src/components/atoms/Icon/Icon.stories.tsx +200 -0
  32. package/src/components/atoms/Icon/Icon.tsx +112 -0
  33. package/src/components/atoms/Icon/index.ts +8 -0
  34. package/src/components/atoms/IconButton/IconButton.stories.tsx +162 -0
  35. package/src/components/atoms/IconButton/IconButton.tsx +227 -0
  36. package/src/components/atoms/IconButton/index.ts +7 -0
  37. package/src/components/atoms/Illustration/Illustration.stories.tsx +167 -0
  38. package/src/components/atoms/Illustration/Illustration.tsx +81 -0
  39. package/src/components/atoms/Illustration/index.ts +6 -0
  40. package/src/components/atoms/Input/Input.stories.tsx +142 -0
  41. package/src/components/atoms/Input/Input.tsx +110 -0
  42. package/src/components/atoms/Input/InputDescription.tsx +49 -0
  43. package/src/components/atoms/Input/InputError.tsx +39 -0
  44. package/src/components/atoms/Input/InputField.tsx +119 -0
  45. package/src/components/atoms/Input/InputLabel.tsx +61 -0
  46. package/src/components/atoms/Input/index.ts +10 -0
  47. package/src/components/atoms/Link/Link.stories.tsx +119 -0
  48. package/src/components/atoms/Link/Link.tsx +118 -0
  49. package/src/components/atoms/Link/index.ts +2 -0
  50. package/src/components/atoms/Logo/Logo.registry.ts +39 -0
  51. package/src/components/atoms/Logo/Logo.tsx +68 -0
  52. package/src/components/atoms/Logo/index.ts +4 -0
  53. package/src/components/atoms/Spinner/Spinner.stories.tsx +98 -0
  54. package/src/components/atoms/Spinner/Spinner.tsx +91 -0
  55. package/src/components/atoms/Spinner/index.ts +2 -0
  56. package/src/components/atoms/Switch/Switch.stories.tsx +120 -0
  57. package/src/components/atoms/Switch/Switch.tsx +196 -0
  58. package/src/components/atoms/Switch/index.ts +2 -0
  59. package/src/components/atoms/Tag/Tag.stories.tsx +89 -0
  60. package/src/components/atoms/Tag/Tag.tsx +122 -0
  61. package/src/components/atoms/Tag/index.ts +2 -0
  62. package/src/components/atoms/Typography/Typography.stories.tsx +315 -0
  63. package/src/components/atoms/Typography/Typography.tsx +284 -0
  64. package/src/components/atoms/Typography/index.ts +2 -0
  65. package/src/components/atoms/index.ts +14 -0
  66. package/src/components/index.ts +2 -0
  67. package/src/components/molecules/ButtonDock/ButtonDock.stories.tsx +95 -0
  68. package/src/components/molecules/ButtonDock/ButtonDock.tsx +148 -0
  69. package/src/components/molecules/ButtonDock/index.ts +2 -0
  70. package/src/components/molecules/ButtonGroup/ButtonGroup.stories.tsx +82 -0
  71. package/src/components/molecules/ButtonGroup/ButtonGroup.tsx +94 -0
  72. package/src/components/molecules/ButtonGroup/index.ts +2 -0
  73. package/src/components/molecules/Checkbox/Checkbox.stories.tsx +148 -0
  74. package/src/components/molecules/Checkbox/Checkbox.tsx +279 -0
  75. package/src/components/molecules/Checkbox/CheckboxGroup.tsx +53 -0
  76. package/src/components/molecules/Checkbox/index.ts +4 -0
  77. package/src/components/molecules/Radio/Radio.stories.tsx +182 -0
  78. package/src/components/molecules/Radio/Radio.tsx +249 -0
  79. package/src/components/molecules/Radio/RadioGroup.tsx +142 -0
  80. package/src/components/molecules/Radio/index.ts +4 -0
  81. package/src/components/molecules/SegmentedControl/SegmentedControl.stories.tsx +151 -0
  82. package/src/components/molecules/SegmentedControl/SegmentedControl.tsx +323 -0
  83. package/src/components/molecules/SegmentedControl/index.ts +5 -0
  84. package/src/components/molecules/Slider/Slider.stories.tsx +144 -0
  85. package/src/components/molecules/Slider/Slider.tsx +303 -0
  86. package/src/components/molecules/Slider/index.ts +2 -0
  87. package/src/components/molecules/index.ts +6 -0
  88. package/src/fonts/ibm-plex-sans-condensed-400-normal.woff2 +0 -0
  89. package/src/fonts/ibm-plex-sans-condensed-500-normal.woff2 +0 -0
  90. package/src/fonts/ibm-plex-sans-condensed-600-normal.woff2 +0 -0
  91. package/src/fonts/ibm-plex-sans-condensed-700-normal.woff2 +0 -0
  92. package/src/fonts/ida-narrow-500-normal.woff2 +0 -0
  93. package/src/fonts/ida-narrow-700-normal.woff2 +0 -0
  94. package/src/fonts/index.ts +49 -0
  95. package/src/index.ts +9 -0
  96. package/src/theme/PawprintProvider.tsx +26 -0
  97. package/src/theme/ThemeProvider.tsx +63 -0
  98. package/src/theme/index.ts +5 -0
  99. package/src/theme/theme.ts +3 -0
  100. package/src/theme/utils.ts +31 -0
  101. package/src/types/fonts.d.ts +4 -0
  102. package/src/types/index.ts +1 -0
  103. package/src/types/theme.ts +24 -0
  104. package/tsconfig.json +5 -0
  105. package/tsup.config.ts +11 -0
@@ -0,0 +1,95 @@
1
+ import React from "react"
2
+ import { View, StyleSheet, Text } from "react-native"
3
+ import { ButtonDock } from "./ButtonDock"
4
+ import type { ButtonDockProps } from "./ButtonDock"
5
+ import { Button } from "../../atoms/Button"
6
+
7
+ export default {
8
+ title: "Molecules/ButtonDock",
9
+ component: ButtonDock,
10
+ argTypes: {
11
+ variant: {
12
+ control: { type: "select" },
13
+ options: ["stacked", "inline"],
14
+ description: "Layout variant (stacked or inline)"
15
+ },
16
+ description: {
17
+ control: { type: "text" },
18
+ description: "Helper text below buttons (stacked only)"
19
+ }
20
+ }
21
+ }
22
+
23
+ export const Playground = {
24
+ args: {
25
+ variant: "stacked",
26
+ description: "Helper text goes here"
27
+ },
28
+ render: (args: ButtonDockProps) => (
29
+ <ButtonDock {...args}>
30
+ <Button fullWidth>Continue</Button>
31
+ <Button fullWidth variant="outlined">
32
+ Go back
33
+ </Button>
34
+ </ButtonDock>
35
+ )
36
+ }
37
+
38
+ export const Stacked = () => (
39
+ <View style={styles.column}>
40
+ <ButtonDock variant="stacked" description="Need help? Contact support.">
41
+ <Button fullWidth>Continue</Button>
42
+ <Button fullWidth variant="outlined">
43
+ Go back
44
+ </Button>
45
+ </ButtonDock>
46
+ </View>
47
+ )
48
+
49
+ export const Inline = () => (
50
+ <View style={styles.column}>
51
+ <ButtonDock variant="inline">
52
+ <Button>Confirm</Button>
53
+ <Button variant="outlined">Cancel</Button>
54
+ </ButtonDock>
55
+ </View>
56
+ )
57
+
58
+ export const WithLeadingContent = () => (
59
+ <View style={styles.column}>
60
+ <ButtonDock
61
+ variant="stacked"
62
+ leadingContent={
63
+ <Text style={styles.leadingText}>
64
+ By continuing you agree to our terms and conditions.
65
+ </Text>
66
+ }
67
+ description="You can change this later in settings."
68
+ >
69
+ <Button fullWidth>Accept & Continue</Button>
70
+ <Button fullWidth variant="outlined">
71
+ Go back
72
+ </Button>
73
+ </ButtonDock>
74
+ </View>
75
+ )
76
+
77
+ export const StackedSingleButton = () => (
78
+ <View style={styles.column}>
79
+ <ButtonDock variant="stacked" description="Only one action available.">
80
+ <Button fullWidth>Continue</Button>
81
+ </ButtonDock>
82
+ </View>
83
+ )
84
+
85
+ const styles = StyleSheet.create({
86
+ column: {
87
+ flexDirection: "column",
88
+ gap: 24
89
+ },
90
+ leadingText: {
91
+ textAlign: "center",
92
+ fontSize: 14,
93
+ color: "#666"
94
+ }
95
+ })
@@ -0,0 +1,148 @@
1
+ import React from "react"
2
+ import { View, ViewProps } from "react-native"
3
+ import styled from "@emotion/native"
4
+ import { useTheme } from "@emotion/react"
5
+ import { Typography } from "../../atoms/Typography"
6
+
7
+ type ButtonDockVariant = "stacked" | "inline"
8
+
9
+ type ButtonDockOwnProps = {
10
+ variant?: ButtonDockVariant
11
+ leadingContent?: React.ReactNode
12
+ description?: React.ReactNode
13
+ }
14
+
15
+ type ButtonDockProps = ButtonDockOwnProps &
16
+ Omit<ViewProps, keyof ButtonDockOwnProps>
17
+
18
+ const parseTokenValue = (value: string): number => parseFloat(value)
19
+
20
+ const StyledDockRoot = styled(View)<{
21
+ dockBgColor: string
22
+ dockBorderTopWidth: number
23
+ dockBorderTopColor: string
24
+ dockPaddingVertical: number
25
+ }>(
26
+ ({
27
+ dockBgColor,
28
+ dockBorderTopWidth,
29
+ dockBorderTopColor,
30
+ dockPaddingVertical
31
+ }) => ({
32
+ alignItems: "center",
33
+ justifyContent: "center",
34
+ width: "100%",
35
+ backgroundColor: dockBgColor,
36
+ borderTopWidth: dockBorderTopWidth,
37
+ borderTopColor: dockBorderTopColor,
38
+ paddingVertical: dockPaddingVertical
39
+ })
40
+ )
41
+
42
+ const StyledStackedInner = styled(View)({
43
+ alignItems: "center",
44
+ gap: 16,
45
+ width: "100%",
46
+ maxWidth: 520
47
+ })
48
+
49
+ const StyledButtonGroup = styled(View)<{
50
+ groupDirection: "column" | "row"
51
+ groupAlign: "stretch" | "center"
52
+ groupJustify: "center" | "space-around"
53
+ groupGap: number
54
+ }>(({ groupDirection, groupAlign, groupJustify, groupGap }) => ({
55
+ flexDirection: groupDirection,
56
+ alignItems: groupAlign,
57
+ justifyContent: groupJustify,
58
+ gap: groupGap,
59
+ width: "100%",
60
+ ...(groupDirection === "column" ? { maxWidth: 520 } : {})
61
+ }))
62
+
63
+ /**
64
+ * A layout container for action buttons, typically placed at the bottom of a
65
+ * page or section.
66
+ *
67
+ * @example
68
+ * ```tsx
69
+ * import { ButtonDock, Button } from "@butternutbox/pawprint-native"
70
+ *
71
+ * <ButtonDock variant="stacked" description="Helper text">
72
+ * <Button fullWidth>Continue</Button>
73
+ * <Button fullWidth variant="filled" colour="secondary">Back</Button>
74
+ * </ButtonDock>
75
+ * ```
76
+ *
77
+ * @param variant - *(optional)* Layout variant: stacked (default) or inline
78
+ * @param leadingContent - *(optional)* Content rendered above buttons (stacked only)
79
+ * @param description - *(optional)* Helper text rendered below buttons (stacked only)
80
+ */
81
+ const ButtonDock = React.forwardRef<View, ButtonDockProps>(
82
+ (
83
+ { variant = "stacked", leadingContent, description, children, ...rest },
84
+ ref
85
+ ) => {
86
+ const theme = useTheme()
87
+ const { buttonDock, buttonGroup } = theme.tokens.components
88
+ const { dimensions } = theme.tokens.semantics
89
+ const isStacked = variant === "stacked"
90
+
91
+ const groupGap = parseTokenValue(
92
+ isStacked
93
+ ? buttonGroup.spacing.stacked.gap
94
+ : buttonGroup.spacing.sideBySide.gap
95
+ )
96
+
97
+ return (
98
+ <StyledDockRoot
99
+ ref={ref}
100
+ dockBgColor={buttonDock.colour.background}
101
+ dockBorderTopWidth={parseTokenValue(dimensions.borderWidth.sm)}
102
+ dockBorderTopColor={buttonDock.colour.border}
103
+ dockPaddingVertical={parseTokenValue(
104
+ buttonDock.spacing[variant].desktop.verticalPadding
105
+ )}
106
+ {...rest}
107
+ >
108
+ {isStacked ? (
109
+ <StyledStackedInner>
110
+ {leadingContent}
111
+ <StyledButtonGroup
112
+ groupDirection="column"
113
+ groupAlign="stretch"
114
+ groupJustify="center"
115
+ groupGap={groupGap}
116
+ >
117
+ {children}
118
+ </StyledButtonGroup>
119
+ {description && (
120
+ <Typography
121
+ variant="body"
122
+ size="md"
123
+ weight="medium"
124
+ align="center"
125
+ >
126
+ {typeof description === "string" ? description : description}
127
+ </Typography>
128
+ )}
129
+ </StyledStackedInner>
130
+ ) : (
131
+ <StyledButtonGroup
132
+ groupDirection="row"
133
+ groupAlign="center"
134
+ groupJustify="space-around"
135
+ groupGap={groupGap}
136
+ >
137
+ {children}
138
+ </StyledButtonGroup>
139
+ )}
140
+ </StyledDockRoot>
141
+ )
142
+ }
143
+ )
144
+
145
+ ButtonDock.displayName = "ButtonDock"
146
+
147
+ export { ButtonDock }
148
+ export type { ButtonDockProps, ButtonDockVariant }
@@ -0,0 +1,2 @@
1
+ export { ButtonDock } from "./ButtonDock"
2
+ export type { ButtonDockProps, ButtonDockVariant } from "./ButtonDock"
@@ -0,0 +1,82 @@
1
+ import React from "react"
2
+ import { View, StyleSheet } from "react-native"
3
+ import { ButtonGroup } from "./ButtonGroup"
4
+ import type { ButtonGroupProps } from "./ButtonGroup"
5
+ import { Button } from "../../atoms/Button"
6
+
7
+ export default {
8
+ title: "Molecules/ButtonGroup",
9
+ component: ButtonGroup,
10
+ argTypes: {
11
+ layout: {
12
+ control: { type: "select" },
13
+ options: ["stacked", "inline"],
14
+ description: "Layout direction (stacked or inline)"
15
+ },
16
+ description: {
17
+ control: { type: "text" },
18
+ description: "Optional text below buttons"
19
+ }
20
+ }
21
+ }
22
+
23
+ export const Playground = {
24
+ args: {
25
+ layout: "stacked",
26
+ description: "Choose an option below"
27
+ },
28
+ render: (args: ButtonGroupProps) => (
29
+ <ButtonGroup {...args}>
30
+ <Button fullWidth>Confirm</Button>
31
+ <Button fullWidth variant="outlined">
32
+ Cancel
33
+ </Button>
34
+ </ButtonGroup>
35
+ )
36
+ }
37
+
38
+ export const Stacked = () => (
39
+ <View style={styles.column}>
40
+ <ButtonGroup layout="stacked" description="Two buttons stacked vertically">
41
+ <Button fullWidth>Primary action</Button>
42
+ <Button fullWidth variant="outlined">
43
+ Secondary action
44
+ </Button>
45
+ </ButtonGroup>
46
+ </View>
47
+ )
48
+
49
+ export const Inline = () => (
50
+ <View style={styles.column}>
51
+ <ButtonGroup layout="inline" description="Two buttons side by side">
52
+ <Button>Confirm</Button>
53
+ <Button variant="outlined">Cancel</Button>
54
+ </ButtonGroup>
55
+ </View>
56
+ )
57
+
58
+ export const SingleButton = () => (
59
+ <View style={styles.column}>
60
+ <ButtonGroup layout="stacked" description="Just one button">
61
+ <Button fullWidth>Continue</Button>
62
+ </ButtonGroup>
63
+ </View>
64
+ )
65
+
66
+ export const WithoutDescription = () => (
67
+ <View style={styles.column}>
68
+ <ButtonGroup layout="stacked">
69
+ <Button fullWidth>Confirm</Button>
70
+ <Button fullWidth variant="outlined">
71
+ Cancel
72
+ </Button>
73
+ </ButtonGroup>
74
+ </View>
75
+ )
76
+
77
+ const styles = StyleSheet.create({
78
+ column: {
79
+ flexDirection: "column",
80
+ gap: 24
81
+ }
82
+ })
@@ -0,0 +1,94 @@
1
+ import React from "react"
2
+ import { View, ViewProps } from "react-native"
3
+ import styled from "@emotion/native"
4
+ import { useTheme } from "@emotion/react"
5
+ import { Typography } from "../../atoms/Typography"
6
+
7
+ export type ButtonGroupLayout = "stacked" | "inline"
8
+
9
+ type ButtonGroupOwnProps = {
10
+ layout?: ButtonGroupLayout
11
+ description?: React.ReactNode
12
+ children: React.ReactNode
13
+ }
14
+
15
+ export type ButtonGroupProps = ButtonGroupOwnProps &
16
+ Omit<ViewProps, keyof ButtonGroupOwnProps>
17
+
18
+ const parseTokenValue = (value: string): number => parseFloat(value)
19
+
20
+ const StyledGroupRoot = styled(View)<{
21
+ rootGap: number
22
+ }>(({ rootGap }) => ({
23
+ gap: rootGap,
24
+ alignItems: "center",
25
+ width: "100%"
26
+ }))
27
+
28
+ const StyledButtonRow = styled(View)<{
29
+ rowDirection: "row-reverse" | "column"
30
+ rowAlign?: "center"
31
+ rowGap: number
32
+ }>(({ rowDirection, rowAlign, rowGap }) => ({
33
+ flexDirection: rowDirection,
34
+ width: "100%",
35
+ gap: rowGap,
36
+ ...(rowAlign ? { alignItems: rowAlign } : {})
37
+ }))
38
+
39
+ /**
40
+ * ButtonGroup arranges 1 or 2 buttons in a stacked or inline layout
41
+ * with an optional description below.
42
+ *
43
+ * @example
44
+ * ```tsx
45
+ * <ButtonGroup description="Choose an option">
46
+ * <Button colour="primary">Confirm</Button>
47
+ * <Button colour="secondary">Cancel</Button>
48
+ * </ButtonGroup>
49
+ * ```
50
+ *
51
+ * @param {"stacked" | "inline"} [layout="stacked"] - Layout direction for buttons.
52
+ * @param {React.ReactNode} [description] - Optional text displayed below the buttons.
53
+ * @param {React.ReactNode} children - 1 or 2 Button elements.
54
+ */
55
+ export const ButtonGroup = React.forwardRef<View, ButtonGroupProps>(
56
+ ({ layout = "stacked", description, children, ...rest }, ref) => {
57
+ const theme = useTheme()
58
+ const { buttonGroup } = theme.tokens.components
59
+
60
+ const isInline = layout === "inline"
61
+
62
+ return (
63
+ <StyledGroupRoot
64
+ ref={ref}
65
+ accessibilityRole="none"
66
+ rootGap={parseTokenValue(buttonGroup.spacing.gap)}
67
+ {...rest}
68
+ >
69
+ <StyledButtonRow
70
+ rowDirection={isInline ? "row-reverse" : "column"}
71
+ rowAlign={isInline ? "center" : undefined}
72
+ rowGap={parseTokenValue(
73
+ isInline
74
+ ? buttonGroup.spacing.sideBySide.gap
75
+ : buttonGroup.spacing.stacked.gap
76
+ )}
77
+ >
78
+ {children}
79
+ </StyledButtonRow>
80
+ {description && (
81
+ <Typography
82
+ token={buttonGroup.typography.description}
83
+ color={buttonGroup.colour.text}
84
+ align="center"
85
+ >
86
+ {description}
87
+ </Typography>
88
+ )}
89
+ </StyledGroupRoot>
90
+ )
91
+ }
92
+ )
93
+
94
+ ButtonGroup.displayName = "ButtonGroup"
@@ -0,0 +1,2 @@
1
+ export { ButtonGroup } from "./ButtonGroup"
2
+ export type { ButtonGroupProps, ButtonGroupLayout } from "./ButtonGroup"
@@ -0,0 +1,148 @@
1
+ import React from "react"
2
+ import { View, StyleSheet } from "react-native"
3
+ import { Checkbox } from "./Checkbox"
4
+ import type { CheckboxProps } from "./Checkbox"
5
+ import { CheckboxGroup } from "./CheckboxGroup"
6
+ import { Typography } from "../../atoms/Typography"
7
+
8
+ export default {
9
+ title: "Molecules/Checkbox",
10
+ component: Checkbox,
11
+ argTypes: {
12
+ variant: {
13
+ control: { type: "select" },
14
+ options: ["standalone", "tile"],
15
+ description: "Visual layout variant"
16
+ },
17
+ label: {
18
+ control: { type: "text" },
19
+ description: "Visible label text"
20
+ },
21
+ subText: {
22
+ control: { type: "text" },
23
+ description: "Optional secondary descriptive text"
24
+ },
25
+ checked: {
26
+ control: { type: "boolean" },
27
+ description: "Controlled checked state"
28
+ },
29
+ disabled: {
30
+ control: { type: "boolean" },
31
+ description: "Prevents interaction"
32
+ }
33
+ }
34
+ }
35
+
36
+ export const Playground = {
37
+ args: {
38
+ variant: "standalone",
39
+ label: "Accept terms",
40
+ subText: "Required to proceed",
41
+ disabled: false
42
+ },
43
+ render: (args: CheckboxProps) => <Checkbox {...args} />
44
+ }
45
+
46
+ export const Standalone = () => (
47
+ <View style={styles.column}>
48
+ <View style={styles.section}>
49
+ <Typography size="sm" weight="semiBold" color="tertiary">
50
+ Default
51
+ </Typography>
52
+ <CheckboxGroup>
53
+ <Checkbox label="Chicken" subText="Tender & tasty" />
54
+ <Checkbox label="Beef" subText="Rich & hearty" />
55
+ <Checkbox label="Lamb" subText="Slow cooked" />
56
+ </CheckboxGroup>
57
+ </View>
58
+
59
+ <View style={styles.section}>
60
+ <Typography size="sm" weight="semiBold" color="tertiary">
61
+ Disabled
62
+ </Typography>
63
+ <CheckboxGroup>
64
+ <Checkbox label="Chicken" subText="Tender & tasty" disabled />
65
+ <Checkbox
66
+ label="Beef"
67
+ subText="Rich & hearty"
68
+ disabled
69
+ defaultChecked
70
+ />
71
+ </CheckboxGroup>
72
+ </View>
73
+ </View>
74
+ )
75
+
76
+ export const Tile = () => (
77
+ <View style={styles.column}>
78
+ <View style={styles.section}>
79
+ <Typography size="sm" weight="semiBold" color="tertiary">
80
+ Vertical
81
+ </Typography>
82
+ <CheckboxGroup orientation="vertical">
83
+ <Checkbox variant="tile" label="Chicken" subText="Tender & tasty" />
84
+ <Checkbox variant="tile" label="Beef" subText="Rich & hearty" />
85
+ <Checkbox variant="tile" label="Lamb" subText="Slow cooked" />
86
+ </CheckboxGroup>
87
+ </View>
88
+
89
+ <View style={styles.section}>
90
+ <Typography size="sm" weight="semiBold" color="tertiary">
91
+ Horizontal
92
+ </Typography>
93
+ <CheckboxGroup orientation="horizontal">
94
+ <Checkbox variant="tile" label="Chicken" />
95
+ <Checkbox variant="tile" label="Beef" />
96
+ <Checkbox variant="tile" label="Lamb" />
97
+ </CheckboxGroup>
98
+ </View>
99
+
100
+ <View style={styles.section}>
101
+ <Typography size="sm" weight="semiBold" color="tertiary">
102
+ Disabled
103
+ </Typography>
104
+ <CheckboxGroup orientation="vertical">
105
+ <Checkbox variant="tile" label="Chicken" disabled />
106
+ <Checkbox variant="tile" label="Beef" disabled defaultChecked />
107
+ </CheckboxGroup>
108
+ </View>
109
+ </View>
110
+ )
111
+
112
+ export const AllStates = () => (
113
+ <View style={styles.column}>
114
+ {(["standalone", "tile"] as const).map((variant) => (
115
+ <View key={variant} style={styles.section}>
116
+ <Typography size="sm" weight="semiBold" color="tertiary">
117
+ {variant}
118
+ </Typography>
119
+ <View style={styles.row}>
120
+ <Checkbox variant={variant} label="Unchecked" />
121
+ <Checkbox variant={variant} label="Checked" defaultChecked />
122
+ <Checkbox variant={variant} label="Disabled" disabled />
123
+ <Checkbox
124
+ variant={variant}
125
+ label="Checked + Disabled"
126
+ disabled
127
+ defaultChecked
128
+ />
129
+ </View>
130
+ </View>
131
+ ))}
132
+ </View>
133
+ )
134
+
135
+ const styles = StyleSheet.create({
136
+ column: {
137
+ flexDirection: "column",
138
+ gap: 32
139
+ },
140
+ section: {
141
+ flexDirection: "column",
142
+ gap: 12
143
+ },
144
+ row: {
145
+ flexDirection: "column",
146
+ gap: 8
147
+ }
148
+ })