@butternutbox/pawprint-native 0.7.0 → 0.8.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@butternutbox/pawprint-native",
3
- "version": "0.7.0",
3
+ "version": "0.8.0",
4
4
  "type": "module",
5
5
  "description": "ButternutBox Pawprint Design System - React Native Components",
6
6
  "main": "./dist/index.cjs",
@@ -77,7 +77,9 @@ const StyledThumb = styled(Animated.View)<{
77
77
  const StyledContent = styled(View)<{
78
78
  contentGap: number
79
79
  }>(({ contentGap }) => ({
80
- gap: contentGap
80
+ gap: contentGap,
81
+ flex: 1,
82
+ minWidth: 0
81
83
  }))
82
84
 
83
85
  /**
@@ -53,6 +53,7 @@ export const AllInlineVariants = {
53
53
  type="error"
54
54
  title="Optional headline here"
55
55
  onClose={() => {}}
56
+ link={{ label: "Optional link" }}
56
57
  >
57
58
  Try to keep the copy length here to a maximum of 2 lines
58
59
  </Notification>
@@ -60,6 +61,7 @@ export const AllInlineVariants = {
60
61
  type="success"
61
62
  title="Optional headline here"
62
63
  onClose={() => {}}
64
+ link={{ label: "Optional link" }}
63
65
  >
64
66
  Try to keep the copy length here to a maximum of 2 lines
65
67
  </Notification>
@@ -67,6 +69,7 @@ export const AllInlineVariants = {
67
69
  type="warning"
68
70
  title="Optional headline here"
69
71
  onClose={() => {}}
72
+ link={{ label: "Optional link" }}
70
73
  >
71
74
  Try to keep the copy length here to a maximum of 2 lines
72
75
  </Notification>
@@ -74,6 +77,7 @@ export const AllInlineVariants = {
74
77
  type="info"
75
78
  title="Optional headline here"
76
79
  onClose={() => {}}
80
+ link={{ label: "Optional link" }}
77
81
  >
78
82
  Try to keep the copy length here to a maximum of 2 lines
79
83
  </Notification>
@@ -278,30 +278,36 @@ export const Notification = React.forwardRef<View, NotificationProps>(
278
278
  rootAlignCenter={isLarge}
279
279
  {...(rest as ViewProps)}
280
280
  >
281
- {showIcon && (
282
- <Icon
283
- icon={IconComponent}
284
- size="md"
285
- colour={type}
286
- aria-label={type}
287
- />
288
- )}
289
- <View style={{ flexDirection: "column", gap: 8, flex: 1 }}>
290
- <Typography
291
- token={systemNotifications.notifications.typography.default}
292
- color={systemNotifications.notification.colour.text.default}
293
- >
294
- {children}
295
- </Typography>
296
- {link && (
297
- <Link
298
- href={link.href}
299
- onPress={link.onPress}
300
- weight="semiBold"
281
+ <View style={{ flexDirection: "column", flex: 1 }}>
282
+ {showIcon && (
283
+ <Icon
284
+ icon={IconComponent}
301
285
  size="md"
286
+ colour={type}
287
+ aria-label={type}
288
+ />
289
+ )}
290
+ <View style={{ flexDirection: "column", gap: 8, flex: 1 }}>
291
+ <Typography
292
+ token={systemNotifications.notifications.typography.default}
293
+ color={systemNotifications.notification.colour.text.default}
294
+ >
295
+ {children}
296
+ </Typography>
297
+ </View>
298
+ {link && (
299
+ <StyledLinkWrapper
300
+ linkPaddingLeft={parseTokenValue(sizeTokens.content.gap)}
302
301
  >
303
- {link.label}
304
- </Link>
302
+ <Link
303
+ href={link.href}
304
+ onPress={link.onPress}
305
+ weight="semiBold"
306
+ size="md"
307
+ >
308
+ {link.label}
309
+ </Link>
310
+ </StyledLinkWrapper>
305
311
  )}
306
312
  </View>
307
313
  </StyledSystemRoot>
@@ -418,22 +424,23 @@ export const Notification = React.forwardRef<View, NotificationProps>(
418
424
  >
419
425
  {children}
420
426
  </Typography>
427
+
428
+ {link && (
429
+ <StyledLinkWrapper
430
+ linkPaddingLeft={parseTokenValue(content.copy.spacing.gap)}
431
+ >
432
+ <Link
433
+ href={link.href}
434
+ onPress={link.onPress}
435
+ weight="semiBold"
436
+ size="md"
437
+ >
438
+ {link.label}
439
+ </Link>
440
+ </StyledLinkWrapper>
441
+ )}
421
442
  </StyledInlineCopy>
422
443
  </StyledCopyRow>
423
- {link && (
424
- <StyledLinkWrapper
425
- linkPaddingLeft={parseTokenValue(content.copy.spacing.gap)}
426
- >
427
- <Link
428
- href={link.href}
429
- onPress={link.onPress}
430
- weight="semiBold"
431
- size="md"
432
- >
433
- {link.label}
434
- </Link>
435
- </StyledLinkWrapper>
436
- )}
437
444
  </StyledContents>
438
445
  {onClose && (
439
446
  <StyledCloseButton
@@ -1,5 +1,6 @@
1
1
  import React from "react"
2
2
  import { View, StyleSheet } from "react-native"
3
+ import { Home } from "@butternutbox/pawprint-icons/core"
3
4
  import { TabNavigation } from "./TabNavigation"
4
5
  import type { TabNavigationProps } from "./TabNavigation"
5
6
  import { Typography } from "../../atoms/Typography"
@@ -149,6 +150,40 @@ export const States = {
149
150
  )
150
151
  }
151
152
 
153
+ const DOG_PHOTO_URL = "https://placedog.net/200/200"
154
+
155
+ export const WithIconsAndAvatars = {
156
+ name: "With Icons & Avatars",
157
+ render: () => (
158
+ <View style={styles.container}>
159
+ <TabNavigation defaultValue="home" layout="fixed">
160
+ <TabNavigation.List>
161
+ <TabNavigation.Tab value="home" icon={Home}>
162
+ Home
163
+ </TabNavigation.Tab>
164
+ <TabNavigation.Tab
165
+ value="dog"
166
+ avatar={{
167
+ src: DOG_PHOTO_URL,
168
+ alt: "Your dog",
169
+ size: "sm",
170
+ border: "sm"
171
+ }}
172
+ >
173
+ Your dog
174
+ </TabNavigation.Tab>
175
+ </TabNavigation.List>
176
+ <TabNavigation.Panel value="home">
177
+ <PanelBody>A leading icon sits before the label.</PanelBody>
178
+ </TabNavigation.Panel>
179
+ <TabNavigation.Panel value="dog">
180
+ <PanelBody>The Avatar atom can lead the label too.</PanelBody>
181
+ </TabNavigation.Panel>
182
+ </TabNavigation>
183
+ </View>
184
+ )
185
+ }
186
+
152
187
  export const AnimatedContent = {
153
188
  name: "Animated Content (fade)",
154
189
  render: () => (
@@ -10,6 +10,8 @@ import styled from "@emotion/native"
10
10
  import { useTheme } from "@emotion/react"
11
11
  import * as TabsPrimitive from "@rn-primitives/tabs"
12
12
  import { Typography, type TypographyProps } from "../../atoms/Typography"
13
+ import { Icon, type PawprintIcon } from "../../atoms/Icon"
14
+ import { Avatar, type AvatarProps } from "../../atoms/Avatar"
13
15
  import { Animated, type AnimatedVariant } from "../Animated"
14
16
 
15
17
  type TabNavigationLayout = "fixed" | "intrinsic"
@@ -64,6 +66,8 @@ export type TabNavigationListProps = TabNavigationListOwnProps &
64
66
  type TabNavigationTabOwnProps = {
65
67
  value: string
66
68
  disabled?: boolean
69
+ icon?: PawprintIcon
70
+ avatar?: AvatarProps
67
71
  children: React.ReactNode
68
72
  }
69
73
 
@@ -169,12 +173,18 @@ TabNavigationList.displayName = "TabNavigation.List"
169
173
  * disabled state). Unlike the web version there are no hover or focus-visible
170
174
  * states (not applicable on mobile).
171
175
  *
176
+ * Optionally renders a leading `Avatar` and/or `Icon` before the label, matching
177
+ * the Figma design. The icon colour tracks the tab's label colour (brand when
178
+ * active/idle, muted when disabled); the avatar is rendered as-is from its props.
179
+ *
172
180
  * @param {string} value - Unique identifier; matches the `value` of a `TabNavigation.Panel`.
173
181
  * @param {boolean} [disabled=false] - Whether this tab is disabled.
182
+ * @param {PawprintIcon} [icon] - Optional leading icon from `@butternutbox/pawprint-icons`.
183
+ * @param {AvatarProps} [avatar] - Optional leading `Avatar`; props are forwarded to the `Avatar` atom.
174
184
  * @param {React.ReactNode} children - Tab label (and optional leading content).
175
185
  */
176
186
  const TabNavigationTab = React.forwardRef<View, TabNavigationTabProps>(
177
- ({ value, disabled = false, children, ...rest }, ref) => {
187
+ ({ value, disabled = false, icon, avatar, children, ...rest }, ref) => {
178
188
  const { layout } = useTabNavigationContext()
179
189
  const { value: selectedValue } = TabsPrimitive.useRootContext()
180
190
  const theme = useTheme()
@@ -209,6 +219,10 @@ const TabNavigationTab = React.forwardRef<View, TabNavigationTabProps>(
209
219
  tabFlex={layout === "fixed" ? 1 : undefined}
210
220
  {...rest}
211
221
  >
222
+ {avatar && <Avatar {...avatar} />}
223
+ {icon && (
224
+ <Icon icon={icon} customColour={textColour as string} aria-hidden />
225
+ )}
212
226
  <Typography token={token} color={textColour}>
213
227
  {children}
214
228
  </Typography>