From 76ac44b0ee26d05b89f64083ff23af95a0d1b8f9 Mon Sep 17 00:00:00 2001 From: Volodymyr Koval Date: Tue, 29 Oct 2024 14:38:12 +0200 Subject: [PATCH] feat(TMC-2505/webapp): implement status bubble component (#5436) * feat(TMC-2505): implement status bubble component * feat(TMC-2505): implement status bubble component * feat(TMC-2505): implement status bubble component * fix tests in forms package --- .changeset/purple-mails-run.md | 5 +++ .../StatusBubblePrimitive.module.scss | 29 ++++++++++++++ .../Primitive/StatusBubblePrimitive.test.tsx | 12 ++++++ .../Primitive/StatusBubblePrimitive.tsx | 31 +++++++++++++++ .../components/StatusBubble/StatusBubble.tsx | 27 +++++++++++++ .../src/components/StatusBubble/index.ts | 15 +++++++ .../variations/StatusBubbleBeta.tsx | 16 ++++++++ .../variations/StatusBubbleError.tsx | 16 ++++++++ .../variations/StatusBubbleInformation.tsx | 18 +++++++++ .../variations/StatusBubbleSuccess.tsx | 18 +++++++++ .../variations/StatusBubbleWarning.tsx | 18 +++++++++ packages/design-system/src/index.ts | 1 + .../src/stories/feedback/StatusBubble.mdx | 21 ++++++++++ .../stories/feedback/StatusBubble.stories.tsx | 39 +++++++++++++++++++ .../fields/Date/DateTime.component.test.js | 2 +- .../TimezoneList/TimezoneList.utils.test.js | 4 +- 16 files changed, 269 insertions(+), 3 deletions(-) create mode 100644 .changeset/purple-mails-run.md create mode 100644 packages/design-system/src/components/StatusBubble/Primitive/StatusBubblePrimitive.module.scss create mode 100644 packages/design-system/src/components/StatusBubble/Primitive/StatusBubblePrimitive.test.tsx create mode 100644 packages/design-system/src/components/StatusBubble/Primitive/StatusBubblePrimitive.tsx create mode 100644 packages/design-system/src/components/StatusBubble/StatusBubble.tsx create mode 100644 packages/design-system/src/components/StatusBubble/index.ts create mode 100644 packages/design-system/src/components/StatusBubble/variations/StatusBubbleBeta.tsx create mode 100644 packages/design-system/src/components/StatusBubble/variations/StatusBubbleError.tsx create mode 100644 packages/design-system/src/components/StatusBubble/variations/StatusBubbleInformation.tsx create mode 100644 packages/design-system/src/components/StatusBubble/variations/StatusBubbleSuccess.tsx create mode 100644 packages/design-system/src/components/StatusBubble/variations/StatusBubbleWarning.tsx create mode 100644 packages/design-system/src/stories/feedback/StatusBubble.mdx create mode 100644 packages/design-system/src/stories/feedback/StatusBubble.stories.tsx diff --git a/.changeset/purple-mails-run.md b/.changeset/purple-mails-run.md new file mode 100644 index 00000000000..6f1682a5cb1 --- /dev/null +++ b/.changeset/purple-mails-run.md @@ -0,0 +1,5 @@ +--- +'@talend/design-system': minor +--- + +feat(TMC-2505/webapp): implement status bubble component diff --git a/packages/design-system/src/components/StatusBubble/Primitive/StatusBubblePrimitive.module.scss b/packages/design-system/src/components/StatusBubble/Primitive/StatusBubblePrimitive.module.scss new file mode 100644 index 00000000000..180c571d13d --- /dev/null +++ b/packages/design-system/src/components/StatusBubble/Primitive/StatusBubblePrimitive.module.scss @@ -0,0 +1,29 @@ +@use '@talend/design-tokens/lib/tokens' as tokens; + +.statusBubble { + display: block; + width: tokens.$coral-spacing-xs; + height: tokens.$coral-spacing-xs; + border-radius: 50%; + + &.beta { + background-color: tokens.$coral-color-beta-icon; + } + + &.error { + background-color: tokens.$coral-color-danger-icon; + } + + &.information { + background-color: tokens.$coral-color-info-icon; + } + + &.success { + background-color: tokens.$coral-color-success-icon; + } + + &.warning { + background-color: tokens.$coral-color-warning-icon; + } + +} diff --git a/packages/design-system/src/components/StatusBubble/Primitive/StatusBubblePrimitive.test.tsx b/packages/design-system/src/components/StatusBubble/Primitive/StatusBubblePrimitive.test.tsx new file mode 100644 index 00000000000..51b4870dcaa --- /dev/null +++ b/packages/design-system/src/components/StatusBubble/Primitive/StatusBubblePrimitive.test.tsx @@ -0,0 +1,12 @@ +import { describe, expect, it } from '@jest/globals'; +import { render, screen } from '@testing-library/react'; + +import StatusBubble, { variants } from './StatusBubblePrimitive'; + +describe('StatusBubble', (): void => { + it('Should render', (): void => { + render(); + + expect(screen.getByTestId('my-status-bubble-component')).toBeVisible(); + }); +}); diff --git a/packages/design-system/src/components/StatusBubble/Primitive/StatusBubblePrimitive.tsx b/packages/design-system/src/components/StatusBubble/Primitive/StatusBubblePrimitive.tsx new file mode 100644 index 00000000000..8ef65b92e4b --- /dev/null +++ b/packages/design-system/src/components/StatusBubble/Primitive/StatusBubblePrimitive.tsx @@ -0,0 +1,31 @@ +import { forwardRef, Ref } from 'react'; + +import classnames from 'classnames'; + +import { DataAttributes } from '../../../types'; + +import styles from './StatusBubblePrimitive.module.scss'; + +export const variants = { + beta: 'beta', + error: 'error', + information: 'information', + success: 'success', + warning: 'warning', +}; + +export type StatusBubbleProps = { + variant: string; +} & DataAttributes; + +const StatusBubblePrimitive = forwardRef( + ({ variant, ...rest }: StatusBubbleProps, ref: Ref) => { + return ( + + ); + }, +); + +StatusBubblePrimitive.displayName = 'StatusBubblePrimitive'; + +export default StatusBubblePrimitive; diff --git a/packages/design-system/src/components/StatusBubble/StatusBubble.tsx b/packages/design-system/src/components/StatusBubble/StatusBubble.tsx new file mode 100644 index 00000000000..2b0caa898a6 --- /dev/null +++ b/packages/design-system/src/components/StatusBubble/StatusBubble.tsx @@ -0,0 +1,27 @@ +import { forwardRef, Ref } from 'react'; + +import { StatusBubbleProps, variants } from './Primitive/StatusBubblePrimitive'; +import StatusBubbleBeta from './variations/StatusBubbleBeta'; +import StatusBubbleError from './variations/StatusBubbleError'; +import StatusBubbleInformation from './variations/StatusBubbleInformation'; +import StatusBubbleSuccess from './variations/StatusBubbleSuccess'; +import StatusBubbleWarning from './variations/StatusBubbleWarning'; + +const StatusBubble = forwardRef((props: StatusBubbleProps, ref: Ref) => { + switch (props.variant) { + case variants.beta: + return ; + case variants.error: + return ; + case variants.information: + return ; + case variants.success: + return ; + case variants.warning: + return ; + default: + return null; + } +}); + +export default StatusBubble; diff --git a/packages/design-system/src/components/StatusBubble/index.ts b/packages/design-system/src/components/StatusBubble/index.ts new file mode 100644 index 00000000000..19d03ad1a2d --- /dev/null +++ b/packages/design-system/src/components/StatusBubble/index.ts @@ -0,0 +1,15 @@ +import StatusBubble from './StatusBubble'; +import StatusBubbleBeta from './variations/StatusBubbleBeta'; +import StatusBubbleError from './variations/StatusBubbleError'; +import StatusBubbleInformation from './variations/StatusBubbleInformation'; +import StatusBubbleSuccess from './variations/StatusBubbleSuccess'; +import StatusBubbleWarning from './variations/StatusBubbleWarning'; + +export { + StatusBubble, + StatusBubbleBeta, + StatusBubbleError, + StatusBubbleInformation, + StatusBubbleSuccess, + StatusBubbleWarning, +}; diff --git a/packages/design-system/src/components/StatusBubble/variations/StatusBubbleBeta.tsx b/packages/design-system/src/components/StatusBubble/variations/StatusBubbleBeta.tsx new file mode 100644 index 00000000000..a792e88b6fd --- /dev/null +++ b/packages/design-system/src/components/StatusBubble/variations/StatusBubbleBeta.tsx @@ -0,0 +1,16 @@ +import { forwardRef, Ref } from 'react'; + +import StatusBubblePrimitive, { + StatusBubbleProps, + variants, +} from '../Primitive/StatusBubblePrimitive'; + +export type StatusBubbleBetaProps = Omit; + +const StatusBubbleBeta = forwardRef((props: StatusBubbleBetaProps, ref: Ref) => { + return ; +}); + +StatusBubbleBeta.displayName = 'StatusBubbleBeta'; + +export default StatusBubbleBeta; diff --git a/packages/design-system/src/components/StatusBubble/variations/StatusBubbleError.tsx b/packages/design-system/src/components/StatusBubble/variations/StatusBubbleError.tsx new file mode 100644 index 00000000000..fee48041b32 --- /dev/null +++ b/packages/design-system/src/components/StatusBubble/variations/StatusBubbleError.tsx @@ -0,0 +1,16 @@ +import { forwardRef, Ref } from 'react'; + +import StatusBubblePrimitive, { + StatusBubbleProps, + variants, +} from '../Primitive/StatusBubblePrimitive'; + +export type StatusBubbleErrorProps = Omit; + +const StatusBubbleError = forwardRef((props: StatusBubbleErrorProps, ref: Ref) => { + return ; +}); + +StatusBubbleError.displayName = 'StatusBubbleError'; + +export default StatusBubbleError; diff --git a/packages/design-system/src/components/StatusBubble/variations/StatusBubbleInformation.tsx b/packages/design-system/src/components/StatusBubble/variations/StatusBubbleInformation.tsx new file mode 100644 index 00000000000..c700be3ba5c --- /dev/null +++ b/packages/design-system/src/components/StatusBubble/variations/StatusBubbleInformation.tsx @@ -0,0 +1,18 @@ +import { forwardRef, Ref } from 'react'; + +import StatusBubblePrimitive, { + StatusBubbleProps, + variants, +} from '../Primitive/StatusBubblePrimitive'; + +export type StatusBubbleInformationProps = Omit; + +const StatusBubbleInformation = forwardRef( + (props: StatusBubbleInformationProps, ref: Ref) => { + return ; + }, +); + +StatusBubbleInformation.displayName = 'StatusBubbleInformation'; + +export default StatusBubbleInformation; diff --git a/packages/design-system/src/components/StatusBubble/variations/StatusBubbleSuccess.tsx b/packages/design-system/src/components/StatusBubble/variations/StatusBubbleSuccess.tsx new file mode 100644 index 00000000000..70625b2306b --- /dev/null +++ b/packages/design-system/src/components/StatusBubble/variations/StatusBubbleSuccess.tsx @@ -0,0 +1,18 @@ +import { forwardRef, Ref } from 'react'; + +import StatusBubblePrimitive, { + StatusBubbleProps, + variants, +} from '../Primitive/StatusBubblePrimitive'; + +export type StatusBubbleSuccessProps = Omit; + +const StatusBubbleSuccess = forwardRef( + (props: StatusBubbleSuccessProps, ref: Ref) => { + return ; + }, +); + +StatusBubbleSuccess.displayName = 'StatusBubbleSuccess'; + +export default StatusBubbleSuccess; diff --git a/packages/design-system/src/components/StatusBubble/variations/StatusBubbleWarning.tsx b/packages/design-system/src/components/StatusBubble/variations/StatusBubbleWarning.tsx new file mode 100644 index 00000000000..491778914a8 --- /dev/null +++ b/packages/design-system/src/components/StatusBubble/variations/StatusBubbleWarning.tsx @@ -0,0 +1,18 @@ +import { forwardRef, Ref } from 'react'; + +import StatusBubblePrimitive, { + StatusBubbleProps, + variants, +} from '../Primitive/StatusBubblePrimitive'; + +export type StatusBubbleWarningProps = Omit; + +const StatusBubbleWarning = forwardRef( + (props: StatusBubbleWarningProps, ref: Ref) => { + return ; + }, +); + +StatusBubbleWarning.displayName = 'StatusBubbleWarning'; + +export default StatusBubbleWarning; diff --git a/packages/design-system/src/index.ts b/packages/design-system/src/index.ts index 0f1d892ee80..1411c207e0c 100644 --- a/packages/design-system/src/index.ts +++ b/packages/design-system/src/index.ts @@ -27,6 +27,7 @@ export * from './components/RatioBar'; export * from './components/RichRadioButton'; export * from './components/Skeleton'; export * from './components/Status'; +export * from './components/StatusBubble'; export * from './components/Stepper'; export * from './components/Switch'; export * from './components/Tabs'; diff --git a/packages/design-system/src/stories/feedback/StatusBubble.mdx b/packages/design-system/src/stories/feedback/StatusBubble.mdx new file mode 100644 index 00000000000..d71a4748c86 --- /dev/null +++ b/packages/design-system/src/stories/feedback/StatusBubble.mdx @@ -0,0 +1,21 @@ +import { Canvas, Controls, Meta } from '@storybook/blocks'; + +import { FigmaImage } from '@talend/storybook-docs'; + +import * as Stories from './StatusBubble.stories'; +import { Status } from '../Status.block'; + + + + +# StatusBubble + +The status bubble component displays state information using circle shape with semantic colors + +### Variations + + + + + + diff --git a/packages/design-system/src/stories/feedback/StatusBubble.stories.tsx b/packages/design-system/src/stories/feedback/StatusBubble.stories.tsx new file mode 100644 index 00000000000..2836ed8dc35 --- /dev/null +++ b/packages/design-system/src/stories/feedback/StatusBubble.stories.tsx @@ -0,0 +1,39 @@ +import { + StatusBubble, + StatusBubbleBeta, + StatusBubbleError, + StatusBubbleInformation, + StatusBubbleSuccess, + StatusBubbleWarning, +} from '../../'; +import { + StatusBubbleProps, + variants, +} from '../../components/StatusBubble/Primitive/StatusBubblePrimitive'; + +export const Beta = () => ; +export const Error = () => ; +export const Information = () => ; +export const Success = () => ; +export const Warning = () => ; + +export const Usage = (props: StatusBubbleProps) => ; + +Usage.args = { + variant: variants.beta, +}; + +Usage.argTypes = { + variant: { + description: 'StatusBubble variation', + options: Object.values(variants), + control: { + type: 'select', + }, + }, +}; + +export default { + title: 'Feedback/StatusBubble', + component: StatusBubble, +}; diff --git a/packages/forms/src/UIForm/fields/Date/DateTime.component.test.js b/packages/forms/src/UIForm/fields/Date/DateTime.component.test.js index 2f3a356959c..1d666e8cdf8 100644 --- a/packages/forms/src/UIForm/fields/Date/DateTime.component.test.js +++ b/packages/forms/src/UIForm/fields/Date/DateTime.component.test.js @@ -122,7 +122,7 @@ describe('DateTime widget', () => { expect(props.onChange.mock.calls[1][1]).toMatchObject({ schema: timestampSchema, - value: new Date(2015, 8, 21, 0, 30, 0).getTime(), + value: new Date(2015, 8, 21, 1, 30, 0).getTime(), }); }); diff --git a/packages/forms/src/UIForm/fields/TimezoneList/TimezoneList.utils.test.js b/packages/forms/src/UIForm/fields/TimezoneList/TimezoneList.utils.test.js index 0a3a49a2fd1..f9c029281fb 100644 --- a/packages/forms/src/UIForm/fields/TimezoneList/TimezoneList.utils.test.js +++ b/packages/forms/src/UIForm/fields/TimezoneList/TimezoneList.utils.test.js @@ -95,8 +95,8 @@ describe('getTimezones', () => { value: 'Africa/Freetown', }, { - name: '(UTC +02:00) Europe/Berlin', - offset: 120, + name: '(UTC +01:00) Europe/Berlin', + offset: 60, timezoneName: 'Europe/Berlin', value: 'Europe/Berlin', },