Skip to content

Commit

Permalink
feat(ffe-message-box-react): rewrite to ts
Browse files Browse the repository at this point in the history
BREAKING CHANGE: props may have changed
  • Loading branch information
pethel committed May 19, 2024
1 parent a5aff76 commit 1bf9b79
Show file tree
Hide file tree
Showing 18 changed files with 234 additions and 264 deletions.
5 changes: 0 additions & 5 deletions packages/ffe-message-box-react/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,6 @@ npm install --save @sb1/ffe-message-box-react

Full documentation on message box usage is available at https://design.sparebank1.no/komponenter/meldinger/#messagebox.

## TypeScript definition files

This component supports TypeScript - please update `index.d.ts` if you change any
of the external methods or properties in this component.

## Development

To start a local development server, run the following from the designsystem root folder:
Expand Down
6 changes: 3 additions & 3 deletions packages/ffe-message-box-react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@
"url": "ssh://git@github.com:SpareBank1/designsystem.git"
},
"scripts": {
"build": "ffe-buildtool babel",
"build": "ffe-buildtool tsc",
"watch": "ffe-buildtool babel-watch",
"lint": "eslint src",
"lint:fix": "eslint src --fix",
"lint": "eslint src --ext ts,tsx",
"lint:fix": "eslint src --fix --ext ts,tsx",
"test": "ffe-buildtool jest",
"test:watch": "ffe-buildtool jest --watch"
},
Expand Down
56 changes: 0 additions & 56 deletions packages/ffe-message-box-react/src/BaseMessage.spec.js

This file was deleted.

81 changes: 81 additions & 0 deletions packages/ffe-message-box-react/src/BaseMessage.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import React from 'react';
import { BaseMessage, BaseMessageProps } from './BaseMessage';
import { Icon } from '@sb1/ffe-icons-react';
import { render, screen } from '@testing-library/react';

const defaultProps = {
type: 'info' as const,
icon: <Icon fileUrl="priority_high" />,
};

const TEST_ID = 'TEST_ID';

const renderBaseMessage = (props?: Partial<BaseMessageProps>) =>
render(<BaseMessage {...defaultProps} {...props} data-testid={TEST_ID} />);

describe('<BaseMessage />', () => {
it('renders the correct classes by default', () => {
const { rerender, container } = render(
<BaseMessage
{...defaultProps}
title="test title"
data-testid={TEST_ID}
/>,
);
const baseMessage = screen.getByTestId(TEST_ID);
expect(baseMessage.classList.contains('ffe-message-box')).toBe(true);

const types = ['info', 'error', 'success', 'tips'] as const;

types.forEach(type => {
rerender(
<BaseMessage
{...defaultProps}
title="test"
type={type}
data-testid={TEST_ID}
/>,
);
expect(
baseMessage.classList.contains(`ffe-message-box--${type}`),
).toBe(true);
expect(
container.querySelector(`.ffe-message-box__icon`),
).toBeTruthy();
});
});

it('renders with correct title class', () => {
const { container } = renderBaseMessage({ title: 'test title' });
expect(container.querySelector(`.ffe-message-box__title`)).toBeTruthy();
});
it('renders an icon by default', () => {
const { container } = renderBaseMessage();
expect(container.querySelector(`.ffe-message-box__icon`)).toBeTruthy();
});
it('renders the container with role="group" by default', () => {
renderBaseMessage();
const baseMessage = screen.getByTestId(TEST_ID);

expect(baseMessage.getAttribute('role')).toBe('group');
});
it('renders a title if specified', () => {
const { container } = renderBaseMessage({ title: 'test title' });

expect(
container.querySelector(`.ffe-message-box__title`)?.textContent,
).toBe('test title');
});
it('renders children if specified', () => {
renderBaseMessage({ children: <p>children</p> });
const baseMessage = screen.getByTestId(TEST_ID);

expect(baseMessage.textContent).toContain('children');
});
it('renders onColoredBg styling if specified', () => {
const { container } = renderBaseMessage({ onColoredBg: true });
expect(
container.querySelector('.ffe-message-box--coloredbg'),
).toBeTruthy();
});
});
Original file line number Diff line number Diff line change
@@ -1,21 +1,35 @@
import React from 'react';
import { bool, node, oneOf, string } from 'prop-types';
import classNames from 'classnames';

const BaseMessage = props => {
const {
type,
title,
titleElement = 'h2',
icon,
children,
className = '',
onColoredBg = false,
ariaLabel,
role = 'group',
...rest
} = props;
export interface BaseMessageProps
extends Omit<React.ComponentPropsWithoutRef<'div'>, 'title'> {
icon?: React.ReactNode;
title?: React.ReactNode;
/** HTML element for the title */
titleElement?: string;
/**
* Internal type enum for specifying the style of message box. Should not be used directly
* @ignore
*/
type: 'success' | 'error' | 'tips' | 'info';
/** Adds alternative styling for better contrast on certain backgrounds */
onColoredBg?: boolean;
ariaLabel?: string;
role?: 'alert' | 'group';
}

export const BaseMessage: React.FC<BaseMessageProps> = ({
type,
title,
titleElement = 'h2',
icon,
children,
className = '',
onColoredBg = false,
ariaLabel,
role = 'group',
...rest
}) => {
return (
<div
className={classNames(
Expand All @@ -29,11 +43,12 @@ const BaseMessage = props => {
{...rest}
>
<span className="ffe-message-box__icon">
{React.cloneElement(icon, {
...icon.props,
size: 'xl',
weight: 300,
})}
{React.isValidElement(icon) &&
React.cloneElement(icon, {
...icon.props,
size: 'xl',
weight: 300,
})}
</span>
<div className="ffe-message-box__box">
{title &&
Expand All @@ -49,23 +64,3 @@ const BaseMessage = props => {
</div>
);
};

BaseMessage.propTypes = {
children: node,
className: string,
icon: node.isRequired,
title: node,
/** HTML element for the title */
titleElement: string,
/**
* Internal type enum for specifying the style of message box. Should not be used directly
* @ignore
*/
type: oneOf(['success', 'error', 'tips', 'info']).isRequired,
/* Adds alternative styling for better contrast on certain backgrounds */
onColoredBg: bool,
ariaLabel: string,
role: oneOf(['alert', 'group']),
};

export default BaseMessage;
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
import React from 'react';
import { node, string, bool, oneOf } from 'prop-types';
import { Icon } from '@sb1/ffe-icons-react';
import BaseMessage from './BaseMessage';
import texts from './texts';
import { BaseMessage, BaseMessageProps } from './BaseMessage';
import { texts } from './texts';

const ErrorMessage = props => {
const { alert = true, locale = 'nb', ...rest } = props;
export interface ErrorMessageProps
extends Omit<BaseMessageProps, 'type' | 'icon'> {
/** When false, role is not set to alert, avoids message from being read up immediately after page load. Default value is true. */
alert?: boolean;
locale?: 'nb' | 'nn' | 'en';
}

export const ErrorMessage: React.FC<ErrorMessageProps> = ({
alert = true,
locale = 'nb',
...rest
}) => {
const priorityHighIcon =
'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iNDgiIHZpZXdCb3g9IjAgLTk2MCA5NjAgOTYwIiB3aWR0aD0iNDgiPjxwYXRoIGQ9Ik00NzkuODgxLTE2My4wOHEtMjEuNzg0IDAtMzcuMTc4LTE1LjUxMy0xNS4zOTQtMTUuNTEzLTE1LjM5NC0zNy4yOTd0MTUuNTEzLTM3LjE3OHExNS41MTMtMTUuMzk0IDM3LjI5Ny0xNS4zOTR0MzcuMTc4IDE1LjUxM3ExNS4zOTQgMTUuNTEzIDE1LjM5NCAzNy4yOTd0LTE1LjUxMyAzNy4xNzhxLTE1LjUxMyAxNS4zOTQtMzcuMjk3IDE1LjM5NFptLS4wNjEtMTk2LjE1MXEtMTkuNTg5IDAtMzMuMzU3LTEzLjg5Ni0xMy43NjktMTMuODk2LTEzLjc2OS0zMy40MXYtMzYzLjA3OHEwLTE5LjUxNCAxMy45NDktMzMuNDEgMTMuOTQ5LTEzLjg5NiAzMy41MzctMTMuODk2IDE5LjU4OSAwIDMzLjM1NyAxMy44OTYgMTMuNzY5IDEzLjg5NiAxMy43NjkgMzMuNDF2MzYzLjA3OHEwIDE5LjUxNC0xMy45NDkgMzMuNDEtMTMuOTQ5IDEzLjg5Ni0zMy41MzcgMTMuODk2WiIvPjwvc3ZnPg==';

Expand All @@ -20,20 +28,3 @@ const ErrorMessage = props => {
/>
);
};

ErrorMessage.propTypes = {
/** The content of the message box */
children: node,
/** Any extra class names to the wrapping DOM node */
className: string,
/** The icon to show. Has a default value, but can be overridden */
icon: node,
/** An optional title for the message */
title: node,
/** When false, role is not set to alert, avoids message from being read up immediately after page load. Default value is true. */
alert: bool,
/** 'nb', 'nn', or 'en' */
locale: oneOf(['en', 'nb', 'nn']),
};

export default ErrorMessage;
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
import React from 'react';
import { node, oneOf, string } from 'prop-types';
import { Icon } from '@sb1/ffe-icons-react';
import BaseMessage from './BaseMessage';
import texts from './texts';
import { BaseMessage, BaseMessageProps } from './BaseMessage';
import { texts } from './texts';

const InfoMessage = ({ locale = 'nb', ...rest }) => {
export interface InfoMessageProps
extends Omit<BaseMessageProps, 'type' | 'icon'> {
locale?: 'nb' | 'nn' | 'en';
}

export const InfoMessage: React.FC<InfoMessageProps> = ({
locale = 'nb',
...rest
}) => {
const infoIcon =
'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iNDgiIHZpZXdCb3g9IjAgLTk2MCA5NjAgOTYwIiB3aWR0aD0iNDgiPjxwYXRoIGQ9Ik00NzkuODgxLTY5NC42MTVxLTI2LjE4OCAwLTQ0LjM4MS0xOC4zMTEtMTguMTkyLTE4LjMxMi0xOC4xOTItNDQuNXQxOC4zMTItNDQuMzhxMTguMzExLTE4LjE5MyA0NC40OTktMTguMTkzIDI2LjE4OCAwIDQ0LjM4MSAxOC4zMTIgMTguMTkyIDE4LjMxMSAxOC4xOTIgNDQuNDk5IDAgMjYuMTg5LTE4LjMxMiA0NC4zODEtMTguMzExIDE4LjE5Mi00NC40OTkgMTguMTkyWm0uMDI0IDU1NC42MTRxLTE3LjgyOCAwLTMwLjIxMi0xMi40NTItMTIuMzg1LTEyLjQ1Mi0xMi4zODUtMzAuMjR2LTM1OS4yMjlxMC0xNy43ODkgMTIuNDgtMzAuMjQgMTIuNDc5LTEyLjQ1MiAzMC4zMDctMTIuNDUydDMwLjIxMiAxMi40NTJxMTIuMzg1IDEyLjQ1MSAxMi4zODUgMzAuMjR2MzU5LjIyOXEwIDE3Ljc4OC0xMi40OCAzMC4yNC0xMi40NzkgMTIuNDUyLTMwLjMwNyAxMi40NTJaIi8+PC9zdmc+';
return (
Expand All @@ -16,18 +23,3 @@ const InfoMessage = ({ locale = 'nb', ...rest }) => {
/>
);
};

InfoMessage.propTypes = {
/** The content of the message box */
children: node,
/** Any extra class names to the wrapping DOM node */
className: string,
/** The icon to show. Has a default value, but can be overridden */
icon: node,
/** An optional title for the message */
title: node,
/** 'nb', 'nn', or 'en' */
locale: oneOf(['en', 'nb', 'nn']),
};

export default InfoMessage;
25 changes: 0 additions & 25 deletions packages/ffe-message-box-react/src/InfoMessageList.js

This file was deleted.

Loading

0 comments on commit 1bf9b79

Please sign in to comment.