Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: [M3-7449] - Dismissible Banner v7 story migration #9932

Merged
merged 6 commits into from
Nov 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@linode/manager": Tech Stories
---

Dismissible Banner V7 story migration ([#9932](https://github.com/linode/manager/pull/9932))
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { DateTime } from 'luxon';
import * as React from 'react';
import { Link, useLocation } from 'react-router-dom';

import { DismissibleBanner } from 'src/components/DismissibleBanner';
import { DismissibleBanner } from 'src/components/DismissibleBanner/DismissibleBanner';
import { Typography } from 'src/components/Typography';
import { useNotificationsQuery } from 'src/queries/accountNotifications';
import { getAbuseTickets } from 'src/store/selectors/getAbuseTicket';
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import * as React from 'react';

import { Button } from 'src/components/Button/Button';
import { Link } from 'src/components/Link';
import { Typography } from 'src/components/Typography';

import { DismissibleBanner } from './DismissibleBanner';

import type { Meta, StoryObj } from '@storybook/react';

type Story = StoryObj<typeof DismissibleBanner>;

export const Default: Story = {
render: (args) => (
<DismissibleBanner {...args}>
<Typography>This is an example of a dismissible banner.</Typography>
</DismissibleBanner>
),
};

/**
* Example of a dismissible banner with an associated action
*/
export const CallToActionBanner: Story = {
render: () => (
<DismissibleBanner
actionButton={
<Button buttonType="primary" onClick={() => null}>
Upgrade Version
</Button>
}
preferenceKey="cluster-v1"
variant="info"
>
<Typography>A new version of Kubernetes is available.</Typography>
</DismissibleBanner>
),
};

/**
* Beta banners, along with [beta chips](/docs/elements-chips-beta-chips--default-story), provide notice to users about beta features.
*/
export const BetaBanner: Story = {
render: () => (
<DismissibleBanner preferenceKey="beta-banner" variant="info">
<Typography>
Managed Database for MySQL is available in a free, open beta period
until May 2nd, 2022. This is a beta environment and should not be used
to support production workloads. Review the{' '}
<Link to="https://www.linode.com/legal-eatp">
Early Adopter Program SLA
</Link>
.
</Typography>
</DismissibleBanner>
),
};

const meta: Meta<typeof DismissibleBanner> = {
args: { preferenceKey: 'dismissible-banner' },
component: DismissibleBanner,
title: 'Components/Notifications/Dismissible Banners',
};

export default meta;
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { styled } from '@mui/material/styles';

import { Notice } from 'src/components/Notice/Notice';

import { StyledLinkButton } from '../Button/StyledLinkButton';

export const StyledNotice = styled(Notice, { label: 'StyledNotice' })(
({ theme }) => ({
'&&': {
p: {
lineHeight: '1.25rem',
},
},
alignItems: 'center',
background: theme.bg.bgPaper,
borderRadius: 1,
display: 'flex',
flexFlow: 'row nowrap',
justifyContent: 'space-between',
marginBottom: theme.spacing(),
padding: theme.spacing(2),
})
);

export const StyledButton = styled(StyledLinkButton, { label: 'StyledButton' })(
({ theme }) => ({
color: theme.textColors.tableStatic,
display: 'flex',
marginLeft: 20,
})
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { fireEvent } from '@testing-library/react';
import * as React from 'react';

import { Button } from 'src/components/Button/Button';
import { Typography } from 'src/components/Typography';
import { renderWithTheme } from 'src/utilities/testHelpers';

import { DismissibleBanner } from './DismissibleBanner';

describe('Dismissible banner', () => {
const props = {
preferenceKey: 'dismissible-banner',
};

it('renders a dismissible banner and can dismiss it', () => {
const { getByLabelText, getByText } = renderWithTheme(
<DismissibleBanner {...props}>
<Typography>This is a dismissible banner</Typography>
</DismissibleBanner>
);
const text = getByText('This is a dismissible banner');
expect(text).toBeVisible();
const dismissButton = getByLabelText('Dismiss dismissible-banner banner');
expect(dismissButton).toBeVisible();
fireEvent.click(dismissButton);
expect(dismissButton).not.toBeInTheDocument();
});
it('renders a dismissible banner with an action button', () => {
const onClickProp = {
onClick: vi.fn(),
};

const { getByText } = renderWithTheme(
<DismissibleBanner
{...props}
actionButton={
<Button {...onClickProp} buttonType="primary">
Action button
</Button>
}
>
<Typography>Banner with action button</Typography>
</DismissibleBanner>
);
const button = getByText('Action button');
expect(button).toBeVisible();
fireEvent.click(button);
expect(onClickProp.onClick).toHaveBeenCalled();
});
});
Original file line number Diff line number Diff line change
@@ -1,29 +1,63 @@
import Close from '@mui/icons-material/Close';
import Grid from '@mui/material/Unstable_Grid2';
import { styled } from '@mui/material/styles';
import { SxProps } from '@mui/system';
import * as React from 'react';

import { Box } from 'src/components/Box';
import { Notice } from 'src/components/Notice/Notice';
import {
DismissibleNotificationOptions,
useDismissibleNotifications,
} from 'src/hooks/useDismissibleNotifications';

import { StyledButton, StyledNotice } from './DismissibleBanner.styles';

import type { NoticeProps } from 'src/components/Notice/Notice';

interface Props {
/**
* Optional element to pass to the banner to trigger actions
*/
actionButton?: JSX.Element;
/**
* Child element to pass to the banner
*/
children: JSX.Element;
/**
* Additional classes to the root element
*/
className?: string;
/**
* Additional controls to pass to the Dismissible Banner
*/
options?: DismissibleNotificationOptions;
/**
* Used to check if this banner has already been dismissed
*/
preferenceKey: string;
/**
* Additional styles to apply to the root element
*/
sx?: SxProps;
}

type CombinedProps = Props & Partial<NoticeProps>;

/**
* ## Usage
*
* Banners appear between the top nav and page content and are a visual interruption of the normal page layout. Their use must be approved by all project stakeholders.
*
* ## Design
* - Banners are dismissible using an 'X' icon.
* - Consider adding a link to a doc or a guide for users to learn more.
* - Banners should be considered as one part of a larger communications plan; messaging should be developed with the marketing team.
*
* ## Variants
* Under the hood, banners use the [Notice](/docs/components-notifications-notices--success) component so they have the same variants such as:
* - Success: Informs users of a new feature or improved service.
* - Warning: Informs users of an impending change that will have an impact on their service(s).
* - Call to action: Primary Button or text link allows a user to take action directly from the banner.
*/
export const DismissibleBanner = (props: CombinedProps) => {
const {
actionButton,
Expand Down Expand Up @@ -92,26 +126,3 @@ export const useDismissibleBanner = (

return { handleDismiss, hasDismissedBanner };
};

const StyledNotice = styled(Notice)(({ theme }) => ({
'&&': {
p: {
lineHeight: '1.25rem',
},
},
alignItems: 'center',
background: theme.bg.bgPaper,
borderRadius: 1,
display: 'flex',
flexFlow: 'row nowrap',
justifyContent: 'space-between',
marginBottom: theme.spacing(),
padding: theme.spacing(2),
}));

const StyledButton = styled('button')(({ theme }) => ({
...theme.applyLinkStyles,
color: theme.textColors.tableStatic,
display: 'flex',
marginLeft: 20,
}));

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { ProductInformationBannerLocation } from 'src/featureFlags';
import { useFlags } from 'src/hooks/useFlags';
import { isAfter } from 'src/utilities/date';

import { DismissibleBanner } from '../DismissibleBanner';
import { DismissibleBanner } from '../DismissibleBanner/DismissibleBanner';

import type { NoticeProps } from 'src/components/Notice/Notice';

Expand Down
Loading