From 4a9e16c194e145c6881583f2362bccd8974bc1fc Mon Sep 17 00:00:00 2001 From: Tiffany Yeung Date: Wed, 11 Dec 2024 12:26:43 -0800 Subject: [PATCH] feat(react): add Placeholder color props (#6232) * feat(placeholder): add `startColor` and `endColor` props * update component and export tests * update docs tests and examples * add changeset --- .changeset/add-placeholder-color-props.md | 5 ++++ .../__snapshots__/props-table.test.ts.snap | 14 +++++++++ .../placeholder/PlaceholderControls.tsx | 29 +++++++++++++++++++ .../components/placeholder/demo.tsx | 6 +++- .../examples/PlaceholderColorExample.tsx | 11 +++++++ .../components/placeholder/examples/index.ts | 1 + .../components/placeholder/react.mdx | 13 +++++++++ .../placeholder/usePlaceholderProps.ts | 25 ++++++++++++++-- .../__tests__/__snapshots__/exports.ts.snap | 6 ++++ .../primitives/Placeholder/Placeholder.tsx | 11 ++++++- .../__tests__/Placeholder.test.tsx | 27 ++++++++++++++++- .../react/src/primitives/types/placeholder.ts | 15 ++++++++++ 12 files changed, 158 insertions(+), 5 deletions(-) create mode 100644 .changeset/add-placeholder-color-props.md create mode 100644 docs/src/pages/[platform]/components/placeholder/examples/PlaceholderColorExample.tsx diff --git a/.changeset/add-placeholder-color-props.md b/.changeset/add-placeholder-color-props.md new file mode 100644 index 00000000000..057c3520080 --- /dev/null +++ b/.changeset/add-placeholder-color-props.md @@ -0,0 +1,5 @@ +--- +"@aws-amplify/ui-react": patch +--- + +feat(react): add Placeholder color props diff --git a/docs/__tests__/__snapshots__/props-table.test.ts.snap b/docs/__tests__/__snapshots__/props-table.test.ts.snap index 990d85af63d..ba55feddf0e 100644 --- a/docs/__tests__/__snapshots__/props-table.test.ts.snap +++ b/docs/__tests__/__snapshots__/props-table.test.ts.snap @@ -8095,6 +8095,13 @@ exports[`Props Table 1`] = ` "category": "BaseComponentProps", "isOptional": true }, + "endColor": { + "name": "endColor", + "type": "StyleToken | undefined", + "description": "This property will change the animation end color of the placeholder component", + "category": "BasePlaceholderProps", + "isOptional": true + }, "isLoaded": { "name": "isLoaded", "type": "boolean | undefined", @@ -8109,6 +8116,13 @@ exports[`Props Table 1`] = ` "category": "BasePlaceholderProps", "isOptional": true }, + "startColor": { + "name": "startColor", + "type": "StyleToken | undefined", + "description": "This property will change the animation start color of the placeholder component", + "category": "BasePlaceholderProps", + "isOptional": true + }, "isDisabled": { "name": "isDisabled", "type": "boolean | undefined", diff --git a/docs/src/pages/[platform]/components/placeholder/PlaceholderControls.tsx b/docs/src/pages/[platform]/components/placeholder/PlaceholderControls.tsx index 92bb3c75733..9549fbb6c59 100644 --- a/docs/src/pages/[platform]/components/placeholder/PlaceholderControls.tsx +++ b/docs/src/pages/[platform]/components/placeholder/PlaceholderControls.tsx @@ -4,9 +4,16 @@ import { PlaceholderProps, SelectField, SwitchField, + TextField, } from '@aws-amplify/ui-react'; export interface PlaceholderPropControlsProps extends PlaceholderProps { + setStartColor: ( + value: React.SetStateAction + ) => void; + setEndColor: ( + value: React.SetStateAction + ) => void; setSize: (value: React.SetStateAction) => void; setIsLoaded: ( value: React.SetStateAction @@ -18,6 +25,10 @@ interface PlaceholderPropControlsInterface { } export const PlaceholderControls: PlaceholderPropControlsInterface = ({ + startColor, + setStartColor, + endColor, + setEndColor, size, setSize, isLoaded, @@ -25,6 +36,24 @@ export const PlaceholderControls: PlaceholderPropControlsInterface = ({ }) => { return ( + { + setStartColor(event.target.value); + }} + label="startColor" + /> + { + setEndColor(event.target.value); + }} + label="endColor" + /> diff --git a/docs/src/pages/[platform]/components/placeholder/demo.tsx b/docs/src/pages/[platform]/components/placeholder/demo.tsx index 60b6daf9681..0847c931438 100644 --- a/docs/src/pages/[platform]/components/placeholder/demo.tsx +++ b/docs/src/pages/[platform]/components/placeholder/demo.tsx @@ -9,6 +9,8 @@ import { demoState } from '@/utils/demoState'; const propsToCode = (props: PlaceholderProps) => { return ( '' @@ -28,8 +30,10 @@ export const PlaceholderDemo = () => { propControls={} > ); diff --git a/docs/src/pages/[platform]/components/placeholder/examples/PlaceholderColorExample.tsx b/docs/src/pages/[platform]/components/placeholder/examples/PlaceholderColorExample.tsx new file mode 100644 index 00000000000..d67c39f5de3 --- /dev/null +++ b/docs/src/pages/[platform]/components/placeholder/examples/PlaceholderColorExample.tsx @@ -0,0 +1,11 @@ +import { Placeholder, useTheme } from '@aws-amplify/ui-react'; + +export const PlaceholderColorExample = () => { + const { tokens } = useTheme(); + return ( + + ); +}; diff --git a/docs/src/pages/[platform]/components/placeholder/examples/index.ts b/docs/src/pages/[platform]/components/placeholder/examples/index.ts index cffbbb492a1..e84cbfb8b9d 100644 --- a/docs/src/pages/[platform]/components/placeholder/examples/index.ts +++ b/docs/src/pages/[platform]/components/placeholder/examples/index.ts @@ -1,5 +1,6 @@ export { DefaultPlaceholderExample } from './DefaultPlaceholderExample'; export { PlaceholderIsLoadedExample } from './PlaceholderIsLoadedExample'; export { PlaceholderSizeExample } from './PlaceholderSizeExample'; +export { PlaceholderColorExample } from './PlaceholderColorExample'; export { PlaceholderStylePropsExample } from './PlaceholderStylePropsExample'; export { PlaceholderThemeExample } from './PlaceholderThemeExample'; diff --git a/docs/src/pages/[platform]/components/placeholder/react.mdx b/docs/src/pages/[platform]/components/placeholder/react.mdx index 1dbd55f3d36..aef2286bef6 100644 --- a/docs/src/pages/[platform]/components/placeholder/react.mdx +++ b/docs/src/pages/[platform]/components/placeholder/react.mdx @@ -4,6 +4,7 @@ import { Placeholder } from '@aws-amplify/ui-react'; import { PlaceholderDemo } from './demo'; import { DefaultPlaceholderExample, + PlaceholderColorExample, PlaceholderIsLoadedExample, PlaceholderSizeExample, PlaceholderStylePropsExample, @@ -59,6 +60,18 @@ Use the `size` prop to change the Placeholder size. Available options are `small +### Colors + +Pass `startColor` and `endColor` props to color your own Placeholder. + + + + + ```jsx file=./examples/PlaceholderColorExample.tsx + ``` + + + ## Customization diff --git a/docs/src/pages/[platform]/components/placeholder/usePlaceholderProps.ts b/docs/src/pages/[platform]/components/placeholder/usePlaceholderProps.ts index 5edf2eb6254..50b3182b7bf 100644 --- a/docs/src/pages/[platform]/components/placeholder/usePlaceholderProps.ts +++ b/docs/src/pages/[platform]/components/placeholder/usePlaceholderProps.ts @@ -9,6 +9,12 @@ interface UsePlaceholderProps { } export const usePlaceholderProps: UsePlaceholderProps = (initialValues) => { + const [startColor, setStartColor] = React.useState< + PlaceholderProps['startColor'] + >(initialValues.startColor); + const [endColor, setEndColor] = React.useState( + initialValues.endColor + ); const [size, setSize] = React.useState( initialValues.size ); @@ -18,18 +24,33 @@ export const usePlaceholderProps: UsePlaceholderProps = (initialValues) => { React.useEffect(() => { demoState.set(Placeholder.displayName, { + startColor, + endColor, size, isLoaded, }); - }, [size, isLoaded]); + }, [startColor, endColor, size, isLoaded]); return React.useMemo( () => ({ + startColor, + setStartColor, + endColor, + setEndColor, size, setSize, isLoaded, setIsLoaded, }), - [size, setSize, isLoaded, setIsLoaded] + [ + startColor, + setStartColor, + endColor, + setEndColor, + size, + setSize, + isLoaded, + setIsLoaded, + ] ); }; diff --git a/packages/react/__tests__/__snapshots__/exports.ts.snap b/packages/react/__tests__/__snapshots__/exports.ts.snap index 46e74f0012f..cadfd91bc45 100644 --- a/packages/react/__tests__/__snapshots__/exports.ts.snap +++ b/packages/react/__tests__/__snapshots__/exports.ts.snap @@ -10106,6 +10106,9 @@ exports[`primitive catalog should match primitives catalog snapshot 1`] = ` "display": { "type": "string", }, + "endColor": { + "type": "string", + }, "flex": { "type": "string", }, @@ -10262,6 +10265,9 @@ exports[`primitive catalog should match primitives catalog snapshot 1`] = ` "size": { "type": "string", }, + "startColor": { + "type": "string", + }, "testId": { "type": "string", }, diff --git a/packages/react/src/primitives/Placeholder/Placeholder.tsx b/packages/react/src/primitives/Placeholder/Placeholder.tsx index a7e2f7da2b0..91a3de881bf 100644 --- a/packages/react/src/primitives/Placeholder/Placeholder.tsx +++ b/packages/react/src/primitives/Placeholder/Placeholder.tsx @@ -12,8 +12,13 @@ import { import { View } from '../View'; import { primitiveWithForwardRef } from '../utils/primitiveWithForwardRef'; +export const CSS_VAR_START_COLOR: string = + '--amplify-components-placeholder-start-color'; +export const CSS_VAR_END_COLOR: string = + '--amplify-components-placeholder-end-color'; + const PlaceholderPrimitive: Primitive = ( - { className, children, isLoaded, size, ...rest }, + { className, children, endColor, isLoaded, size, startColor, ...rest }, ref ) => { if (isLoaded) { @@ -28,6 +33,10 @@ const PlaceholderPrimitive: Primitive = ( className )} ref={ref} + style={{ + [CSS_VAR_START_COLOR]: startColor && `${startColor}`, + [CSS_VAR_END_COLOR]: endColor && `${endColor}`, + }} {...rest} /> ); diff --git a/packages/react/src/primitives/Placeholder/__tests__/Placeholder.test.tsx b/packages/react/src/primitives/Placeholder/__tests__/Placeholder.test.tsx index dc564c7fd7a..ee402074b8b 100644 --- a/packages/react/src/primitives/Placeholder/__tests__/Placeholder.test.tsx +++ b/packages/react/src/primitives/Placeholder/__tests__/Placeholder.test.tsx @@ -1,7 +1,11 @@ import * as React from 'react'; import { render, screen } from '@testing-library/react'; -import { Placeholder } from '../Placeholder'; +import { + CSS_VAR_END_COLOR, + CSS_VAR_START_COLOR, + Placeholder, +} from '../Placeholder'; import { Text } from '../../Text'; import { ComponentClassName } from '@aws-amplify/ui'; @@ -14,6 +18,8 @@ describe('Placeholder:', () => { true ); expect(placeholder.dataset['size']).toBeUndefined(); + expect(placeholder.dataset['startColor']).toBeUndefined(); + expect(placeholder.dataset['endColor']).toBeUndefined(); }); it('should render size classes for Placeholder', async () => { @@ -86,6 +92,25 @@ describe('Placeholder:', () => { ); }); + it('can apply startColor and endColor styling via props', async () => { + const startColor = 'green'; + const endColor = 'gray'; + render( + + ); + const placeholder = await screen.findByTestId('placeholderId'); + expect(placeholder.style.getPropertyValue(CSS_VAR_START_COLOR)).toBe( + startColor + ); + expect(placeholder.style.getPropertyValue(CSS_VAR_END_COLOR)).toBe( + endColor + ); + }); + it('can apply styling via props', async () => { render(); const placeholder = await screen.findByTestId('placeholderId'); diff --git a/packages/react/src/primitives/types/placeholder.ts b/packages/react/src/primitives/types/placeholder.ts index 8882ac3c73a..b250425f03f 100644 --- a/packages/react/src/primitives/types/placeholder.ts +++ b/packages/react/src/primitives/types/placeholder.ts @@ -1,10 +1,19 @@ +import { Property } from 'csstype'; + import { Sizes } from './base'; +import { StyleToken } from './style'; import { ElementType, PrimitiveProps, BaseViewProps } from './view'; export type PlaceholderSizes = Sizes; /** @deprecated For internal use only */ export interface BasePlaceholderProps extends BaseViewProps { + /** + * @description + * This property will change the animation end color of the placeholder component + */ + endColor?: StyleToken; + /** * @description * If true, the placeholder won't show, if false the placeholder will show. @@ -18,6 +27,12 @@ export interface BasePlaceholderProps extends BaseViewProps { * Controls the display size of placeholder */ size?: PlaceholderSizes; + + /** + * @description + * This property will change the animation start color of the placeholder component + */ + startColor?: StyleToken; } export type PlaceholderProps =