Skip to content

Commit

Permalink
Feat(web-react): Add Message and Link for ToastBar #DS-1213
Browse files Browse the repository at this point in the history
  • Loading branch information
curdaj committed May 20, 2024
1 parent d65d18c commit 19f18db
Show file tree
Hide file tree
Showing 10 changed files with 70 additions and 44 deletions.
2 changes: 1 addition & 1 deletion packages/web-react/src/components/Toast/ToastBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ const ToastBar = (props: SpiritToastBarProps) => {
>
<div className={classProps.content}>
{(hasIcon || iconName) && <Icon name={toastIconName} boxSize={ICON_BOX_SIZE} />}
<div className={classProps.wrapper}>{children}</div>
<div className={classProps.container}>{children}</div>
</div>
<ToastCloseButton
id={id}
Expand Down
28 changes: 12 additions & 16 deletions packages/web-react/src/components/Toast/ToastBarLink.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,20 @@
import React from 'react';
import { ChildrenProps, ToastColorType } from '../../types';
import { ChildrenProps, SpiritButtonProps, SpiritLinkProps } from '../../types';
import { Link } from '../Link';
import { useToastBarStyleProps } from './useToastBarStyleProps';
import { DEFAULT_TOAST_COLOR } from './constants';
import { Button } from '../Button';

type ToastBarLinkProps = {
href: string;
color?: ToastColorType;
isUnderlined?: boolean;
} & ChildrenProps;
type ToastBarLinkProps<T extends React.ElementType = typeof Link> = {
elementType?: T;
} & ChildrenProps &
SpiritLinkProps &
SpiritButtonProps<typeof Button>;

const ToastBarLink = (props: ToastBarLinkProps) => {
const { href, color = DEFAULT_TOAST_COLOR, isUnderlined = false, children, ...restProps } = props;
const { classProps } = useToastBarStyleProps({ ...restProps });
export const ToastBarLink = <T extends React.ElementType = typeof Link | typeof Button>(
props: ToastBarLinkProps<T>,
): JSX.Element => {
const { elementType: ElementTag = Link, children, ...restProps } = props;

return (
<Link UNSAFE_className={classProps.link} href={href} color={color} {...restProps} isUnderlined={isUnderlined}>
{children}
</Link>
);
return <ElementTag {...restProps}>{children}</ElementTag>;
};

export default ToastBarLink;
12 changes: 3 additions & 9 deletions packages/web-react/src/components/Toast/ToastBarMessage.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
import React from 'react';
import { BaseToastBarProps, ChildrenProps } from '../../types';
import { useToastBarStyleProps } from './useToastBarStyleProps';
import { ChildrenProps } from '../../types';

type ToastBarMessageProps = Omit<BaseToastBarProps, 'id'> & ChildrenProps;

const ToastBarMessage = (props: ToastBarMessageProps) => {
const { children, ...restProps } = props;
const { classProps } = useToastBarStyleProps({ ...restProps });

return <div className={classProps.message}>{children}</div>;
const ToastBarMessage = ({ children }: ChildrenProps) => {
return <div>{children}</div>;
};

export default ToastBarMessage;
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import '@testing-library/jest-dom';
import { render, screen } from '@testing-library/react';
import React from 'react';
import { restPropsTest } from '../../../../tests/providerTests/restPropsTest';
import ToastBarLink from '../ToastBarLink';

describe('ToastBarLink', () => {
restPropsTest((props) => <ToastBarLink {...props} id="test" />, 'a');

beforeEach(() => {
render(
<ToastBarLink href="www.example.com" color="inverted" isUnderlined>
Action
</ToastBarLink>,
);
});

it('should render as link', () => {
const element = screen.getByRole('link');

expect(element).toBeInTheDocument();
expect(element).toHaveAttribute('href', 'www.example.com');
expect(element).toHaveClass('link-inverted link-underlined');
});

it('should render children', () => {
const element = screen.getByText('Action');

expect(element).toBeInTheDocument();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import '@testing-library/jest-dom';
import { render, screen } from '@testing-library/react';
import React from 'react';
import ToastBarMessage from '../ToastBarMessage';

describe('ToastBarMessage', () => {
it('should render children', () => {
render(<ToastBarMessage>Example children</ToastBarMessage>);

const element = screen.getByText('Example children');

expect(element).toBeInTheDocument();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ describe('useToastBarStyleProps', () => {

expect(result.current.classProps.root).toBe('ToastBar ToastBar--inverted');
expect(result.current.classProps.content).toBe('ToastBar__content');
expect(result.current.classProps.message).toBe('ToastBar__message');
expect(result.current.classProps.container).toBe('ToastBar__container');
});

it('should return dismissible class', () => {
Expand Down
8 changes: 2 additions & 6 deletions packages/web-react/src/components/Toast/demo/ToastColors.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,15 @@ const ToastColors = () => {
<>
<ToastBar id="inverted" onClose={() => {}} color="inverted" hasIcon isDismissible>
<ToastBarMessage>Inverted</ToastBarMessage>
<ToastBarLink href="#" isUnderlined>
<ToastBarLink elementType={Link} href="#" color="inverted" isUnderlined>
Action
</ToastBarLink>
</ToastBar>
<ToastBar id="informative" onClose={() => {}} color="informative" hasIcon isDismissible>
<ToastBarMessage>Informative</ToastBarMessage>
<ToastBarLink href="#" isUnderlined>
<ToastBarLink href="#" color="inverted" isUnderlined>
Action
</ToastBarLink>
{/*Informative*/}
{/*<Link href="#" color="inverted" isUnderlined>*/}
{/* Action*/}
{/*</Link>*/}
</ToastBar>
<ToastBar id="success" onClose={() => {}} color="success" hasIcon isDismissible>
Success
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const ToastContentVariations = () => {
</ToastBar>
<ToastBar id="custom-icon" isDismissible iconName="download">
<ToastBarMessage>Dismissible message with custom icon and action</ToastBarMessage>
<ToastBarLink href="#" isUnderlined>
<ToastBarLink href="#" color="inverted" isUnderlined>
Action
</ToastBarLink>
</ToastBar>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ export const useToastBarStyleProps = (props: Omit<SpiritToastBarProps, 'id' | 'o

const toastBarClass = useClassNamePrefix('ToastBar');
const toastBarContentClass = `${toastBarClass}__content`;
const toastBarWrapperClass = `${toastBarClass}__wrapper`;
const toastBarMessageClass = `${toastBarClass}__message`;
const toastBarContainerClass = `${toastBarClass}__container`;
const toastBarLinkClass = `${toastBarClass}__link`;
const colorClass = `${toastBarClass}--${color || 'inverted'}`;
const dismissibleClass = `${toastBarClass}--dismissible`;
Expand All @@ -18,8 +17,7 @@ export const useToastBarStyleProps = (props: Omit<SpiritToastBarProps, 'id' | 'o
classProps: {
root: rootClass,
content: toastBarContentClass,
wrapper: toastBarWrapperClass,
message: toastBarMessageClass,
container: toastBarContainerClass,
link: toastBarLinkClass,
},
props: restProps,
Expand Down
9 changes: 3 additions & 6 deletions packages/web/src/scss/components/Toast/_ToastBar.scss
Original file line number Diff line number Diff line change
Expand Up @@ -32,22 +32,19 @@
column-gap: theme.$bar-content-gap;
}

.ToastBar__wrapper {
.ToastBar__container {
@include typography.generate(theme.$bar-typography);

display: flex;
flex-wrap: wrap; // 3.
gap: theme.$bar-message-gap-y theme.$bar-message-gap-x;
}

.ToastBar__message {
}

.ToastBar__wrapper > :is(a, button):last-child {
.ToastBar__container > :is(a, button):last-child {
font-weight: 400;
}

.ToastBar--dismissible .ToastBar__wrapper > :is(a, button):last-child {
.ToastBar--dismissible .ToastBar__container > :is(a, button):last-child {
margin-inline-end: theme.$bar-action-margin-inline-end; // 4.
}

Expand Down

0 comments on commit 19f18db

Please sign in to comment.