From 194f7c8dd8d3b5f6ab6028407d09ef17b69183ad Mon Sep 17 00:00:00 2001 From: Nidhi Kumari Date: Mon, 1 Aug 2022 15:14:33 +0530 Subject: [PATCH] added AvatarBase Component (#15307) * added AvatarBase Component * added README file to storybook * converted avatar-base to base-avatar * props for snapshot testing * replaced snapshot testing * Updates to stories and component * used arrow function for component * fixed merge conflicts * removed box stories * changed import order for scss files * replaced base-avatar import with component scss file Co-authored-by: georgewrmarshall --- .../component-library/base-avatar/README.mdx | 53 ++++++ .../base-avatar/base-avatar.js | 44 +++++ .../base-avatar/base-avatar.scss | 31 ++++ .../base-avatar/base-avatar.stories.js | 158 ++++++++++++++++++ .../base-avatar/base-avatar.test.js | 28 ++++ .../component-library/base-avatar/index.js | 1 + .../component-library-components.scss | 2 + ui/components/ui/box/box.js | 4 +- ui/components/ui/box/index.js | 8 +- ui/css/index.scss | 1 + 10 files changed, 327 insertions(+), 3 deletions(-) create mode 100644 ui/components/component-library/base-avatar/README.mdx create mode 100644 ui/components/component-library/base-avatar/base-avatar.js create mode 100644 ui/components/component-library/base-avatar/base-avatar.scss create mode 100644 ui/components/component-library/base-avatar/base-avatar.stories.js create mode 100644 ui/components/component-library/base-avatar/base-avatar.test.js create mode 100644 ui/components/component-library/base-avatar/index.js create mode 100644 ui/components/component-library/component-library-components.scss diff --git a/ui/components/component-library/base-avatar/README.mdx b/ui/components/component-library/base-avatar/README.mdx new file mode 100644 index 000000000..ac010bab7 --- /dev/null +++ b/ui/components/component-library/base-avatar/README.mdx @@ -0,0 +1,53 @@ +import { Story, Canvas, ArgsTable } from '@storybook/addon-docs'; + +import { BaseAvatar } from './base-avatar'; + +### This is a base component. It should not be used in your feature code directly but as a "base" for other UI components + +# BaseAvatar + +The `BaseAvatar` is a wrapper component responsible for enforcing dimensions and border radius for Avatar components + + + + + +## Props + +The `BaseAvatar` accepts all props below as well as all [Box](/ui-components-ui-box-box-stories-js--default-story) component props. + + + +### Size + +Use the `size` prop to set the size of the `BaseAvatar`. + +Possible sizes include: + +- `xs` 16px +- `sm` 24px +- `md` 32px +- `lg` 40px +- `xl` 48px + +Defaults to `md` + + + + + +### Children + +The `BaseAvatar` component can contain images, icons or text + + + + + +### Background and border color + +Use the `backgroundColor` and `borderColor` prop to set the background and border colors of the avatar + + + + diff --git a/ui/components/component-library/base-avatar/base-avatar.js b/ui/components/component-library/base-avatar/base-avatar.js new file mode 100644 index 000000000..46cdfe8f4 --- /dev/null +++ b/ui/components/component-library/base-avatar/base-avatar.js @@ -0,0 +1,44 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; +import Box from '../../ui/box/box'; +import { COLORS, SIZES } from '../../../helpers/constants/design-system'; + +export const BaseAvatar = ({ + size = SIZES.MD, + children, + backgroundColor = COLORS.BACKGROUND_ALTERNATIVE, + borderColor = COLORS.BORDER_DEFAULT, + ...props +}) => ( + + {children} + +); + +BaseAvatar.propTypes = { + /** + * The size of the BaseAvatar. + * Possible values could be 'xs', 'sm', 'md', 'lg', 'xl', + */ + size: PropTypes.oneOf(Object.values(SIZES)), + /** + * The children to be rendered inside the BaseAvatar + */ + children: PropTypes.node, + /** + * The background color of the BaseAvatar + */ + backgroundColor: Box.propTypes.backgroundColor, + /** + * The background color of the BaseAvatar + */ + borderColor: Box.propTypes.borderColor, + /** + * BaseAvatar accepts all the props from Box + */ + ...Box.propTypes, +}; diff --git a/ui/components/component-library/base-avatar/base-avatar.scss b/ui/components/component-library/base-avatar/base-avatar.scss new file mode 100644 index 000000000..bd1a9c31f --- /dev/null +++ b/ui/components/component-library/base-avatar/base-avatar.scss @@ -0,0 +1,31 @@ +.base-avatar { + --avatar-size: var(--size, 16px); + + &--size-xs { + --size: 16px; + } + + &--size-sm { + --size: 24px; + } + + &--size-md { + --size: 32px; + } + + &--size-lg { + --size: 40px; + } + + &--size-xl { + --size: 48px; + } + + height: var(--avatar-size); + width: var(--avatar-size); + border-radius: 100%; + overflow: hidden; + display: flex; + align-items: center; + justify-content: center; +} diff --git a/ui/components/component-library/base-avatar/base-avatar.stories.js b/ui/components/component-library/base-avatar/base-avatar.stories.js new file mode 100644 index 000000000..36226b084 --- /dev/null +++ b/ui/components/component-library/base-avatar/base-avatar.stories.js @@ -0,0 +1,158 @@ +import React from 'react'; +import { + ALIGN_ITEMS, + COLORS, + DISPLAY, + SIZES, +} from '../../../helpers/constants/design-system'; +import { ValidBackgroundColors, ValidBorderColors } from '../../ui/box'; +import Box from '../../ui/box/box'; + +import README from './README.mdx'; +import { BaseAvatar } from './base-avatar'; + +const marginSizeKnobOptions = [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 'auto', +]; + +export default { + title: 'Components/ComponentLibrary/BaseAvatar', + id: __filename, + component: BaseAvatar, + parameters: { + docs: { + page: README, + }, + }, + argTypes: { + size: { + control: 'select', + options: Object.values(SIZES), + }, + backgroundColor: { + options: ValidBackgroundColors, + control: 'select', + }, + borderColor: { + options: ValidBorderColors, + control: 'select', + }, + display: { + options: Object.values(DISPLAY), + control: 'select', + defaultValue: DISPLAY.FLEX, + table: { category: 'box props' }, + }, + marginTop: { + options: marginSizeKnobOptions, + control: 'select', + table: { category: 'box props' }, + }, + marginRight: { + options: marginSizeKnobOptions, + control: 'select', + table: { category: 'box props' }, + }, + marginBottom: { + options: marginSizeKnobOptions, + control: 'select', + table: { category: 'box props' }, + }, + marginLeft: { + options: marginSizeKnobOptions, + control: 'select', + table: { category: 'box props' }, + }, + }, + args: { + size: SIZES.MD, + backgroundColor: COLORS.BACKGROUND_ALTERNATIVE, + borderColor: COLORS.BORDER_DEFAULT, + }, +}; + +export const DefaultStory = (args) => B; + +DefaultStory.storyName = 'Default'; + +export const Size = (args) => ( + + + + + + + +); + +export const Children = (args) => ( + + + + + + + + + + + A + + + + +); + +export const BackgroundAndBorderColor = (args) => ( + + B + + K + + + R + + + G + + + R + + +); diff --git a/ui/components/component-library/base-avatar/base-avatar.test.js b/ui/components/component-library/base-avatar/base-avatar.test.js new file mode 100644 index 000000000..5c37030f6 --- /dev/null +++ b/ui/components/component-library/base-avatar/base-avatar.test.js @@ -0,0 +1,28 @@ +/* eslint-disable jest/require-top-level-describe */ +import { render } from '@testing-library/react'; +import React from 'react'; + +import { BaseAvatar } from './base-avatar'; + +describe('BaseAvatar', () => { + it('should render correctly', () => { + const { getByTestId } = render(); + expect(getByTestId('base-avatar')).toBeDefined(); + }); + it('should render with different size classes', () => { + const { getByTestId } = render( + <> + + + + + + , + ); + expect(getByTestId('base-avatar-xs')).toHaveClass('base-avatar--size-xs'); + expect(getByTestId('base-avatar-sm')).toHaveClass('base-avatar--size-sm'); + expect(getByTestId('base-avatar-md')).toHaveClass('base-avatar--size-md'); + expect(getByTestId('base-avatar-lg')).toHaveClass('base-avatar--size-lg'); + expect(getByTestId('base-avatar-xl')).toHaveClass('base-avatar--size-xl'); + }); +}); diff --git a/ui/components/component-library/base-avatar/index.js b/ui/components/component-library/base-avatar/index.js new file mode 100644 index 000000000..b37a9d558 --- /dev/null +++ b/ui/components/component-library/base-avatar/index.js @@ -0,0 +1 @@ +export { BaseAvatar } from './base-avatar'; diff --git a/ui/components/component-library/component-library-components.scss b/ui/components/component-library/component-library-components.scss new file mode 100644 index 000000000..b1e580564 --- /dev/null +++ b/ui/components/component-library/component-library-components.scss @@ -0,0 +1,2 @@ +/** Please import your files in alphabetical order **/ +@import 'base-avatar/base-avatar'; diff --git a/ui/components/ui/box/box.js b/ui/components/ui/box/box.js index b2157338f..8484172d2 100644 --- a/ui/components/ui/box/box.js +++ b/ui/components/ui/box/box.js @@ -74,8 +74,8 @@ export const BorderColors = [ const ValidSize = PropTypes.oneOf(Sizes); const ValidSizeAndAuto = PropTypes.oneOf([...Sizes, 'auto']); -const ValidBackgroundColors = PropTypes.oneOf(BackgroundColors); -const ValidBorderColors = PropTypes.oneOf(BorderColors); +export const ValidBackgroundColors = PropTypes.oneOf(BackgroundColors); +export const ValidBorderColors = PropTypes.oneOf(BorderColors); const ArrayOfValidSizes = PropTypes.arrayOf(ValidSize); export const MultipleSizes = PropTypes.oneOfType([ diff --git a/ui/components/ui/box/index.js b/ui/components/ui/box/index.js index 89a9055ff..0f0516c14 100644 --- a/ui/components/ui/box/index.js +++ b/ui/components/ui/box/index.js @@ -1 +1,7 @@ -export { default, MultipleSizes, MultipleSizesAndAuto } from './box'; +export { + default, + MultipleSizes, + MultipleSizesAndAuto, + ValidBackgroundColors, + ValidBorderColors, +} from './box'; diff --git a/ui/css/index.scss b/ui/css/index.scss index 4e3df4d23..d861b7210 100644 --- a/ui/css/index.scss +++ b/ui/css/index.scss @@ -8,6 +8,7 @@ @import './design-system/index'; @import './utilities/colors.scss'; @import './base-styles.scss'; +@import '../components/component-library/component-library-components.scss'; @import '../components/app/app-components'; @import '../components/ui/ui-components'; @import '../pages/pages';