Skip to content

Commit

Permalink
feat(TMC-2505/webapp): implement status bubble component (#5436)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
VolodymyrKovalM authored Oct 29, 2024
1 parent 555b9f5 commit 76ac44b
Show file tree
Hide file tree
Showing 16 changed files with 269 additions and 3 deletions.
5 changes: 5 additions & 0 deletions .changeset/purple-mails-run.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@talend/design-system': minor
---

feat(TMC-2505/webapp): implement status bubble component
Original file line number Diff line number Diff line change
@@ -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;
}

}
Original file line number Diff line number Diff line change
@@ -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(<StatusBubble variant={variants.success} data-testid="my-status-bubble-component" />);

expect(screen.getByTestId('my-status-bubble-component')).toBeVisible();
});
});
Original file line number Diff line number Diff line change
@@ -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<HTMLSpanElement>) => {
return (
<span className={classnames(styles.statusBubble, styles[variant])} ref={ref} {...rest} />
);
},
);

StatusBubblePrimitive.displayName = 'StatusBubblePrimitive';

export default StatusBubblePrimitive;
Original file line number Diff line number Diff line change
@@ -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<HTMLSpanElement>) => {
switch (props.variant) {
case variants.beta:
return <StatusBubbleBeta {...props} ref={ref} />;
case variants.error:
return <StatusBubbleError {...props} ref={ref} />;
case variants.information:
return <StatusBubbleInformation {...props} ref={ref} />;
case variants.success:
return <StatusBubbleSuccess {...props} ref={ref} />;
case variants.warning:
return <StatusBubbleWarning {...props} ref={ref} />;
default:
return null;
}
});

export default StatusBubble;
15 changes: 15 additions & 0 deletions packages/design-system/src/components/StatusBubble/index.ts
Original file line number Diff line number Diff line change
@@ -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,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { forwardRef, Ref } from 'react';

import StatusBubblePrimitive, {
StatusBubbleProps,
variants,
} from '../Primitive/StatusBubblePrimitive';

export type StatusBubbleBetaProps = Omit<StatusBubbleProps, 'variant'>;

const StatusBubbleBeta = forwardRef((props: StatusBubbleBetaProps, ref: Ref<HTMLSpanElement>) => {
return <StatusBubblePrimitive variant={variants.beta} ref={ref} {...props} />;
});

StatusBubbleBeta.displayName = 'StatusBubbleBeta';

export default StatusBubbleBeta;
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { forwardRef, Ref } from 'react';

import StatusBubblePrimitive, {
StatusBubbleProps,
variants,
} from '../Primitive/StatusBubblePrimitive';

export type StatusBubbleErrorProps = Omit<StatusBubbleProps, 'variant'>;

const StatusBubbleError = forwardRef((props: StatusBubbleErrorProps, ref: Ref<HTMLSpanElement>) => {
return <StatusBubblePrimitive variant={variants.error} ref={ref} {...props} />;
});

StatusBubbleError.displayName = 'StatusBubbleError';

export default StatusBubbleError;
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { forwardRef, Ref } from 'react';

import StatusBubblePrimitive, {
StatusBubbleProps,
variants,
} from '../Primitive/StatusBubblePrimitive';

export type StatusBubbleInformationProps = Omit<StatusBubbleProps, 'variant'>;

const StatusBubbleInformation = forwardRef(
(props: StatusBubbleInformationProps, ref: Ref<HTMLSpanElement>) => {
return <StatusBubblePrimitive variant={variants.information} ref={ref} {...props} />;
},
);

StatusBubbleInformation.displayName = 'StatusBubbleInformation';

export default StatusBubbleInformation;
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { forwardRef, Ref } from 'react';

import StatusBubblePrimitive, {
StatusBubbleProps,
variants,
} from '../Primitive/StatusBubblePrimitive';

export type StatusBubbleSuccessProps = Omit<StatusBubbleProps, 'variant'>;

const StatusBubbleSuccess = forwardRef(
(props: StatusBubbleSuccessProps, ref: Ref<HTMLSpanElement>) => {
return <StatusBubblePrimitive variant={variants.success} ref={ref} {...props} />;
},
);

StatusBubbleSuccess.displayName = 'StatusBubbleSuccess';

export default StatusBubbleSuccess;
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { forwardRef, Ref } from 'react';

import StatusBubblePrimitive, {
StatusBubbleProps,
variants,
} from '../Primitive/StatusBubblePrimitive';

export type StatusBubbleWarningProps = Omit<StatusBubbleProps, 'variant'>;

const StatusBubbleWarning = forwardRef(
(props: StatusBubbleWarningProps, ref: Ref<HTMLSpanElement>) => {
return <StatusBubblePrimitive variant={variants.warning} ref={ref} {...props} />;
},
);

StatusBubbleWarning.displayName = 'StatusBubbleWarning';

export default StatusBubbleWarning;
1 change: 1 addition & 0 deletions packages/design-system/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down
21 changes: 21 additions & 0 deletions packages/design-system/src/stories/feedback/StatusBubble.mdx
Original file line number Diff line number Diff line change
@@ -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';

<Meta of={Stories} />
<Status id="status" />

# StatusBubble

The status bubble component displays state information using circle shape with semantic colors

### Variations

<Canvas of={Stories.Beta} />
<Canvas of={Stories.Error} />
<Canvas of={Stories.Information} />
<Canvas of={Stories.Success} />
<Canvas of={Stories.Warning} />
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import {
StatusBubble,
StatusBubbleBeta,
StatusBubbleError,
StatusBubbleInformation,
StatusBubbleSuccess,
StatusBubbleWarning,
} from '../../';
import {
StatusBubbleProps,
variants,
} from '../../components/StatusBubble/Primitive/StatusBubblePrimitive';

export const Beta = () => <StatusBubbleBeta />;
export const Error = () => <StatusBubbleError />;
export const Information = () => <StatusBubbleInformation />;
export const Success = () => <StatusBubbleSuccess />;
export const Warning = () => <StatusBubbleWarning />;

export const Usage = (props: StatusBubbleProps) => <StatusBubble {...props} />;

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,
};
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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',
},
Expand Down

0 comments on commit 76ac44b

Please sign in to comment.