diff --git a/docs/6.x/docs/guides/migration.md b/docs/6.x/docs/guides/migration.md index 72aee6d00f..ac935d3d33 100644 --- a/docs/6.x/docs/guides/migration.md +++ b/docs/6.x/docs/guides/migration.md @@ -285,6 +285,17 @@ The `overlayAccessibilityLabel` prop was renamed to `dismissAccessibilityLabel`: ``` +### Avatar + +`Avatar.Icon` and `Avatar.Text` no longer derive their icon or text color from `style.backgroundColor`. Specify matching `color` explicitly when using custom background color. + +```diff + +``` + ### Searchbar The misspelled `traileringIcon` props have been renamed: diff --git a/src/components/Avatar/AvatarIcon.tsx b/src/components/Avatar/AvatarIcon.tsx index 2d2f08760b..f9f0d6caa4 100644 --- a/src/components/Avatar/AvatarIcon.tsx +++ b/src/components/Avatar/AvatarIcon.tsx @@ -2,13 +2,11 @@ import { StyleSheet, View } from 'react-native'; import type { StyleProp, ViewProps, ViewStyle } from 'react-native'; import { useInternalTheme } from '../../core/theming'; -import { white } from '../../theme/colors'; +import { cornerFull } from '../../theme/tokens/sys/shape'; import type { ThemeProp } from '../../theme/types'; -import getContrastingColor from '../../utils/getContrastingColor'; import Icon from '../Icon'; import type { IconSource } from '../Icon'; - -const defaultSize = 64; +import { DEFAULT_SIZE } from './utils'; export type Props = ViewProps & { /** @@ -45,17 +43,13 @@ export type Props = ViewProps & { */ const Avatar = ({ icon, - size = defaultSize, + size = DEFAULT_SIZE, style, theme: themeOverrides, + color: customColor, ...rest }: Props) => { const theme = useInternalTheme(themeOverrides); - const { backgroundColor = theme.colors?.primary, ...restStyle } = - StyleSheet.flatten(style) || {}; - const textColor = - rest.color ?? - getContrastingColor(backgroundColor, white, 'rgba(0, 0, 0, .54)'); return ( - + ); }; diff --git a/src/components/Avatar/AvatarImage.tsx b/src/components/Avatar/AvatarImage.tsx index e8b6e501b1..23f0601ef5 100644 --- a/src/components/Avatar/AvatarImage.tsx +++ b/src/components/Avatar/AvatarImage.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import { Image, StyleSheet, View } from 'react-native'; +import { Image, View } from 'react-native'; import type { ImageProps, ImageSourcePropType, @@ -8,11 +8,11 @@ import type { ViewStyle, } from 'react-native'; +import { DEFAULT_SIZE } from './utils'; import { useInternalTheme } from '../../core/theming'; +import { cornerFull } from '../../theme/tokens/sys/shape'; import type { ThemeProp } from '../../theme/types'; -const defaultSize = 64; - export type AvatarImageSource = | ImageSourcePropType | ((props: { size: number }) => React.ReactNode); @@ -74,7 +74,7 @@ export type Props = ViewProps & { * ``` */ const AvatarImage = ({ - size = defaultSize, + size = DEFAULT_SIZE, source, style, onError, @@ -87,8 +87,7 @@ const AvatarImage = ({ testID, ...rest }: Props) => { - const { colors } = useInternalTheme(themeOverrides); - const { backgroundColor = colors?.primary } = StyleSheet.flatten(style) || {}; + const theme = useInternalTheme(themeOverrides); return ( { const theme = useInternalTheme(themeOverrides); - const { backgroundColor = theme.colors?.primary, ...restStyle } = - StyleSheet.flatten(style) || {}; - const textColor = - customColor ?? - getContrastingColor(backgroundColor, white, 'rgba(0, 0, 0, .54)'); const { fontScale } = useWindowDimensions(); return ( @@ -77,19 +70,21 @@ const AvatarText = ({ { width: size, height: size, - borderRadius: size / 2, - backgroundColor, + borderRadius: cornerFull, + backgroundColor: theme.colors.primaryContainer, }, styles.container, - restStyle, + style, ]} {...rest} > { const callback = visible ? showCallback : hideCallback; @@ -175,12 +177,19 @@ const Banner = ({ visible ? 1 : 0, { duration: animationDuration, - easing: Easing.inOut(Easing.ease), + easing: Easing.bezier(...easing.standard), reduceMotion: ReduceMotion.Never, }, (finished) => scheduleOnRN(callback, { finished: finished ?? false }) ); - }, [animationDuration, hideCallback, position, showCallback, visible]); + }, [ + animationDuration, + easing, + hideCallback, + position, + showCallback, + visible, + ]); const surfaceStyle = useAnimatedStyle(() => ({ opacity: interpolate(position.value, [0, 0.1, 1], [0, 1, 1]), diff --git a/src/components/DataTable/DataTableCell.tsx b/src/components/DataTable/DataTableCell.tsx index af332b3ae4..f90e7c28ac 100644 --- a/src/components/DataTable/DataTableCell.tsx +++ b/src/components/DataTable/DataTableCell.tsx @@ -74,17 +74,20 @@ const DataTableCell = ({ numeric, maxFontSizeMultiplier, testID, + theme: themeOverrides, ...rest }: Props) => { return ( {children} @@ -96,16 +99,22 @@ const CellContent = ({ children, textStyle, maxFontSizeMultiplier, -}: Pick) => { + theme, +}: Pick< + Props, + 'children' | 'textStyle' | 'maxFontSizeMultiplier' | 'theme' +>) => { if (React.isValidElement(children)) { return children; } return ( {children} diff --git a/src/components/DataTable/DataTablePagination.tsx b/src/components/DataTable/DataTablePagination.tsx index 0fd2cb7a04..4126848a25 100644 --- a/src/components/DataTable/DataTablePagination.tsx +++ b/src/components/DataTable/DataTablePagination.tsx @@ -294,6 +294,8 @@ const DataTablePagination = ({ onItemsPerPageChange && ( )} { spin.value = withTiming(sortDirection === 'ascending' ? 0 : 180, { - duration: 150, - easing: Easing.inOut(Easing.ease), + duration: duration.short3 * scale, + easing: Easing.bezier(...easing.standard), reduceMotion: reduceMotion ? ReduceMotion.Always : ReduceMotion.Never, }); - }, [reduceMotion, sortDirection, spin]); + }, [duration, easing, reduceMotion, scale, sortDirection, spin]); const animatedStyle = useAnimatedStyle(() => ({ transform: [{ rotate: `${spin.value}deg` }], @@ -141,6 +144,8 @@ const DataTableTitle = ({ {icon} { hideCallback = undefined; }); + it('uses zero-duration animations when animation scale is disabled', async () => { + const view = await render( + + Text + + ); + + await view.rerender( + + Text + + ); + await act(() => { + jest.advanceTimersByTime(16); + }); + + expect(showCallback).toHaveBeenCalled(); + }); + describe('when component is rendered hidden', () => { // This behaviour is probably a bug. Needs triage before next version. it('will fire onHideAnimationFinished on mount', async () => { diff --git a/src/components/__tests__/__snapshots__/Avatar.test.tsx.snap b/src/components/__tests__/__snapshots__/Avatar.test.tsx.snap index 9e55666cef..0f0d336c07 100644 --- a/src/components/__tests__/__snapshots__/Avatar.test.tsx.snap +++ b/src/components/__tests__/__snapshots__/Avatar.test.tsx.snap @@ -5,8 +5,8 @@ exports[`renders avatar with icon 1`] = ` style={ [ { - "backgroundColor": "rgba(103, 80, 164, 1)", - "borderRadius": 32, + "backgroundColor": "rgba(234, 221, 255, 1)", + "borderRadius": 9999, "height": 64, "width": 64, }, @@ -14,7 +14,7 @@ exports[`renders avatar with icon 1`] = ` "alignItems": "center", "justifyContent": "center", }, - {}, + undefined, ] } > @@ -26,7 +26,7 @@ exports[`renders avatar with icon 1`] = ` style={ [ { - "color": "#ffffff", + "color": "rgba(33, 0, 93, 1)", "fontSize": 38.4, }, [ @@ -55,8 +55,8 @@ exports[`renders avatar with icon and custom background color 1`] = ` style={ [ { - "backgroundColor": "#f44336", - "borderRadius": 32, + "backgroundColor": "rgba(234, 221, 255, 1)", + "borderRadius": 9999, "height": 64, "width": 64, }, @@ -64,7 +64,9 @@ exports[`renders avatar with icon and custom background color 1`] = ` "alignItems": "center", "justifyContent": "center", }, - {}, + { + "backgroundColor": "#f44336", + }, ] } > @@ -76,7 +78,7 @@ exports[`renders avatar with icon and custom background color 1`] = ` style={ [ { - "color": "#ffffff", + "color": "rgba(33, 0, 93, 1)", "fontSize": 38.4, }, [ @@ -105,8 +107,8 @@ exports[`renders avatar with image 1`] = ` style={ [ { - "backgroundColor": "rgba(103, 80, 164, 1)", - "borderRadius": 32, + "backgroundColor": "rgba(234, 221, 255, 1)", + "borderRadius": 9999, "height": 64, "width": 64, }, @@ -123,7 +125,7 @@ exports[`renders avatar with image 1`] = ` } style={ { - "borderRadius": 32, + "borderRadius": 9999, "height": 64, "width": 64, } @@ -137,8 +139,8 @@ exports[`renders avatar with text 1`] = ` style={ [ { - "backgroundColor": "rgba(103, 80, 164, 1)", - "borderRadius": 32, + "backgroundColor": "rgba(234, 221, 255, 1)", + "borderRadius": 9999, "height": 64, "width": 64, }, @@ -146,7 +148,7 @@ exports[`renders avatar with text 1`] = ` "alignItems": "center", "justifyContent": "center", }, - {}, + undefined, ] } > @@ -159,24 +161,28 @@ exports[`renders avatar with text 1`] = ` }, { "color": "rgba(29, 27, 32, 1)", - "fontFamily": "System", - "fontWeight": "400", - "letterSpacing": 0, - }, - { "writingDirection": "ltr", }, [ { - "textAlign": "center", - "textAlignVertical": "center", - }, - { - "color": "#ffffff", - "fontSize": 32, - "lineHeight": 64, + "fontFamily": "System", + "fontSize": 16, + "fontWeight": "500", + "letterSpacing": 0.15, + "lineHeight": 24, }, - undefined, + [ + { + "textAlign": "center", + "textAlignVertical": "center", + }, + { + "color": "rgba(33, 0, 93, 1)", + "fontSize": 32, + "lineHeight": 64, + }, + undefined, + ], ], ] } @@ -191,8 +197,8 @@ exports[`renders avatar with text and custom background color 1`] = ` style={ [ { - "backgroundColor": "#f44336", - "borderRadius": 32, + "backgroundColor": "rgba(234, 221, 255, 1)", + "borderRadius": 9999, "height": 64, "width": 64, }, @@ -200,7 +206,9 @@ exports[`renders avatar with text and custom background color 1`] = ` "alignItems": "center", "justifyContent": "center", }, - {}, + { + "backgroundColor": "#f44336", + }, ] } > @@ -213,24 +221,28 @@ exports[`renders avatar with text and custom background color 1`] = ` }, { "color": "rgba(29, 27, 32, 1)", - "fontFamily": "System", - "fontWeight": "400", - "letterSpacing": 0, - }, - { "writingDirection": "ltr", }, [ { - "textAlign": "center", - "textAlignVertical": "center", - }, - { - "color": "#ffffff", - "fontSize": 32, - "lineHeight": 64, + "fontFamily": "System", + "fontSize": 16, + "fontWeight": "500", + "letterSpacing": 0.15, + "lineHeight": 24, }, - undefined, + [ + { + "textAlign": "center", + "textAlignVertical": "center", + }, + { + "color": "rgba(33, 0, 93, 1)", + "fontSize": 32, + "lineHeight": 64, + }, + undefined, + ], ], ] } @@ -245,8 +257,8 @@ exports[`renders avatar with text and custom colors 1`] = ` style={ [ { - "backgroundColor": "rgba(103, 80, 164, 1)", - "borderRadius": 32, + "backgroundColor": "rgba(234, 221, 255, 1)", + "borderRadius": 9999, "height": 64, "width": 64, }, @@ -254,7 +266,7 @@ exports[`renders avatar with text and custom colors 1`] = ` "alignItems": "center", "justifyContent": "center", }, - {}, + undefined, ] } > @@ -267,24 +279,28 @@ exports[`renders avatar with text and custom colors 1`] = ` }, { "color": "rgba(29, 27, 32, 1)", - "fontFamily": "System", - "fontWeight": "400", - "letterSpacing": 0, - }, - { "writingDirection": "ltr", }, [ { - "textAlign": "center", - "textAlignVertical": "center", + "fontFamily": "System", + "fontSize": 16, + "fontWeight": "500", + "letterSpacing": 0.15, + "lineHeight": 24, }, - { - "color": "#FFFFFF", - "fontSize": 32, - "lineHeight": 64, - }, - undefined, + [ + { + "textAlign": "center", + "textAlignVertical": "center", + }, + { + "color": "#FFFFFF", + "fontSize": 32, + "lineHeight": 64, + }, + undefined, + ], ], ] } @@ -299,8 +315,8 @@ exports[`renders avatar with text and custom size 1`] = ` style={ [ { - "backgroundColor": "rgba(103, 80, 164, 1)", - "borderRadius": 48, + "backgroundColor": "rgba(234, 221, 255, 1)", + "borderRadius": 9999, "height": 96, "width": 96, }, @@ -308,7 +324,7 @@ exports[`renders avatar with text and custom size 1`] = ` "alignItems": "center", "justifyContent": "center", }, - {}, + undefined, ] } > @@ -321,24 +337,28 @@ exports[`renders avatar with text and custom size 1`] = ` }, { "color": "rgba(29, 27, 32, 1)", - "fontFamily": "System", - "fontWeight": "400", - "letterSpacing": 0, - }, - { "writingDirection": "ltr", }, [ { - "textAlign": "center", - "textAlignVertical": "center", - }, - { - "color": "#ffffff", - "fontSize": 48, - "lineHeight": 96, + "fontFamily": "System", + "fontSize": 16, + "fontWeight": "500", + "letterSpacing": 0.15, + "lineHeight": 24, }, - undefined, + [ + { + "textAlign": "center", + "textAlignVertical": "center", + }, + { + "color": "rgba(33, 0, 93, 1)", + "fontSize": 48, + "lineHeight": 96, + }, + undefined, + ], ], ] } diff --git a/src/components/__tests__/__snapshots__/DataTable.test.tsx.snap b/src/components/__tests__/__snapshots__/DataTable.test.tsx.snap index 9084841e9b..6b369425c1 100644 --- a/src/components/__tests__/__snapshots__/DataTable.test.tsx.snap +++ b/src/components/__tests__/__snapshots__/DataTable.test.tsx.snap @@ -55,14 +55,18 @@ exports[`DataTable.Cell renders data table cell 1`] = ` }, { "color": "rgba(29, 27, 32, 1)", - "fontFamily": "System", - "fontWeight": "400", - "letterSpacing": 0, - }, - { "writingDirection": "ltr", }, - undefined, + [ + { + "fontFamily": "System", + "fontSize": 14, + "fontWeight": "400", + "letterSpacing": 0.25, + "lineHeight": 20, + }, + undefined, + ], ] } > @@ -359,14 +363,18 @@ exports[`DataTable.Cell renders data table cell with text content 1`] = ` }, { "color": "rgba(29, 27, 32, 1)", - "fontFamily": "System", - "fontWeight": "400", - "letterSpacing": 0, - }, - { "writingDirection": "ltr", }, - undefined, + [ + { + "fontFamily": "System", + "fontSize": 14, + "fontWeight": "400", + "letterSpacing": 0.25, + "lineHeight": 20, + }, + undefined, + ], ] } > @@ -432,14 +440,18 @@ exports[`DataTable.Cell renders right aligned data table cell 1`] = ` }, { "color": "rgba(29, 27, 32, 1)", - "fontFamily": "System", - "fontWeight": "400", - "letterSpacing": 0, - }, - { "writingDirection": "ltr", }, - undefined, + [ + { + "fontFamily": "System", + "fontSize": 14, + "fontWeight": "400", + "letterSpacing": 0.25, + "lineHeight": 20, + }, + undefined, + ], ] } > @@ -516,28 +528,30 @@ exports[`DataTable.Header renders data table header 1`] = ` }, { "color": "rgba(29, 27, 32, 1)", - "fontFamily": "System", - "fontWeight": "400", - "letterSpacing": 0, - }, - { "writingDirection": "ltr", }, [ { - "alignItems": "center", + "fontFamily": "System", "fontSize": 12, "fontWeight": "500", - "lineHeight": 24, - }, - { - "maxHeight": 48, - }, - {}, - { - "color": "rgba(73, 69, 79, 1)", + "letterSpacing": 0.5, + "lineHeight": 16, }, - undefined, + [ + { + "alignItems": "center", + "lineHeight": 24, + }, + { + "maxHeight": 48, + }, + {}, + { + "color": "rgba(73, 69, 79, 1)", + }, + undefined, + ], ], ] } @@ -597,28 +611,30 @@ exports[`DataTable.Header renders data table header 1`] = ` }, { "color": "rgba(29, 27, 32, 1)", - "fontFamily": "System", - "fontWeight": "400", - "letterSpacing": 0, - }, - { "writingDirection": "ltr", }, [ { - "alignItems": "center", + "fontFamily": "System", "fontSize": 12, "fontWeight": "500", - "lineHeight": 24, - }, - { - "maxHeight": 48, - }, - {}, - { - "color": "rgba(73, 69, 79, 1)", + "letterSpacing": 0.5, + "lineHeight": 16, }, - undefined, + [ + { + "alignItems": "center", + "lineHeight": 24, + }, + { + "maxHeight": 48, + }, + {}, + { + "color": "rgba(73, 69, 79, 1)", + }, + undefined, + ], ], ] } @@ -655,21 +671,24 @@ exports[`DataTable.Pagination renders data table pagination 1`] = ` }, { "color": "rgba(29, 27, 32, 1)", - "fontFamily": "System", - "fontWeight": "400", - "letterSpacing": 0, - }, - { "writingDirection": "ltr", }, [ { + "fontFamily": "System", "fontSize": 12, - "marginRight": 16, - }, - { - "color": "rgba(73, 69, 79, 1)", + "fontWeight": "400", + "letterSpacing": 0.4, + "lineHeight": 16, }, + [ + { + "marginRight": 16, + }, + { + "color": "rgba(73, 69, 79, 1)", + }, + ], ], ] } @@ -947,21 +966,24 @@ exports[`DataTable.Pagination renders data table pagination with fast-forward bu }, { "color": "rgba(29, 27, 32, 1)", - "fontFamily": "System", - "fontWeight": "400", - "letterSpacing": 0, - }, - { "writingDirection": "ltr", }, [ { + "fontFamily": "System", "fontSize": 12, - "marginRight": 16, - }, - { - "color": "rgba(73, 69, 79, 1)", + "fontWeight": "400", + "letterSpacing": 0.4, + "lineHeight": 16, }, + [ + { + "marginRight": 16, + }, + { + "color": "rgba(73, 69, 79, 1)", + }, + ], ], ] } @@ -1477,21 +1499,24 @@ exports[`DataTable.Pagination renders data table pagination with label 1`] = ` }, { "color": "rgba(29, 27, 32, 1)", - "fontFamily": "System", - "fontWeight": "400", - "letterSpacing": 0, - }, - { "writingDirection": "ltr", }, [ { + "fontFamily": "System", "fontSize": 12, - "marginRight": 16, - }, - { - "color": "rgba(73, 69, 79, 1)", + "fontWeight": "400", + "letterSpacing": 0.4, + "lineHeight": 16, }, + [ + { + "marginRight": 16, + }, + { + "color": "rgba(73, 69, 79, 1)", + }, + ], ], ] } @@ -1781,21 +1806,24 @@ exports[`DataTable.Pagination renders data table pagination with options select }, { "color": "rgba(29, 27, 32, 1)", - "fontFamily": "System", - "fontWeight": "400", - "letterSpacing": 0, - }, - { "writingDirection": "ltr", }, [ { + "fontFamily": "System", "fontSize": 12, - "marginRight": 16, - }, - { - "color": "rgba(73, 69, 79, 1)", + "fontWeight": "400", + "letterSpacing": 0.4, + "lineHeight": 16, }, + [ + { + "marginRight": 16, + }, + { + "color": "rgba(73, 69, 79, 1)", + }, + ], ], ] } @@ -2069,21 +2097,24 @@ exports[`DataTable.Pagination renders data table pagination with options select }, { "color": "rgba(29, 27, 32, 1)", - "fontFamily": "System", - "fontWeight": "400", - "letterSpacing": 0, - }, - { "writingDirection": "ltr", }, [ { + "fontFamily": "System", "fontSize": 12, - "marginRight": 16, - }, - { - "color": "rgba(73, 69, 79, 1)", + "fontWeight": "400", + "letterSpacing": 0.4, + "lineHeight": 16, }, + [ + { + "marginRight": 16, + }, + { + "color": "rgba(73, 69, 79, 1)", + }, + ], ], ] } @@ -2674,28 +2705,30 @@ exports[`DataTable.Title renders data table title with press handler 1`] = ` }, { "color": "rgba(29, 27, 32, 1)", - "fontFamily": "System", - "fontWeight": "400", - "letterSpacing": 0, - }, - { "writingDirection": "ltr", }, [ { - "alignItems": "center", + "fontFamily": "System", "fontSize": 12, "fontWeight": "500", - "lineHeight": 24, - }, - { - "maxHeight": 48, + "letterSpacing": 0.5, + "lineHeight": 16, }, - {}, - { - "marginLeft": 8, - }, - undefined, + [ + { + "alignItems": "center", + "lineHeight": 24, + }, + { + "maxHeight": 48, + }, + {}, + { + "marginLeft": 8, + }, + undefined, + ], ], ] } @@ -2806,28 +2839,30 @@ exports[`DataTable.Title renders data table title with sort icon 1`] = ` }, { "color": "rgba(29, 27, 32, 1)", - "fontFamily": "System", - "fontWeight": "400", - "letterSpacing": 0, - }, - { "writingDirection": "ltr", }, [ { - "alignItems": "center", + "fontFamily": "System", "fontSize": 12, "fontWeight": "500", - "lineHeight": 24, + "letterSpacing": 0.5, + "lineHeight": 16, }, - { - "maxHeight": 48, - }, - {}, - { - "marginLeft": 8, - }, - undefined, + [ + { + "alignItems": "center", + "lineHeight": 24, + }, + { + "maxHeight": 48, + }, + {}, + { + "marginLeft": 8, + }, + undefined, + ], ], ] } @@ -2892,28 +2927,30 @@ exports[`DataTable.Title renders right aligned data table title 1`] = ` }, { "color": "rgba(29, 27, 32, 1)", - "fontFamily": "System", - "fontWeight": "400", - "letterSpacing": 0, - }, - { "writingDirection": "ltr", }, [ { - "alignItems": "center", + "fontFamily": "System", "fontSize": 12, "fontWeight": "500", - "lineHeight": 24, - }, - { - "maxHeight": 48, + "letterSpacing": 0.5, + "lineHeight": 16, }, - {}, - { - "color": "rgba(73, 69, 79, 1)", - }, - undefined, + [ + { + "alignItems": "center", + "lineHeight": 24, + }, + { + "maxHeight": 48, + }, + {}, + { + "color": "rgba(73, 69, 79, 1)", + }, + undefined, + ], ], ] }