diff --git a/packages/manager/.changeset/pr-9932-tech-stories-1700688400660.md b/packages/manager/.changeset/pr-9932-tech-stories-1700688400660.md
new file mode 100644
index 00000000000..987413f2225
--- /dev/null
+++ b/packages/manager/.changeset/pr-9932-tech-stories-1700688400660.md
@@ -0,0 +1,5 @@
+---
+"@linode/manager": Tech Stories
+---
+
+Dismissible Banner V7 story migration ([#9932](https://github.com/linode/manager/pull/9932))
diff --git a/packages/manager/src/components/AbuseTicketBanner/AbuseTicketBanner.tsx b/packages/manager/src/components/AbuseTicketBanner/AbuseTicketBanner.tsx
index e424526575a..aab45644f4c 100644
--- a/packages/manager/src/components/AbuseTicketBanner/AbuseTicketBanner.tsx
+++ b/packages/manager/src/components/AbuseTicketBanner/AbuseTicketBanner.tsx
@@ -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';
diff --git a/packages/manager/src/components/DismissibleBanner/DismissibleBanner.stories.mdx b/packages/manager/src/components/DismissibleBanner/DismissibleBanner.stories.mdx
deleted file mode 100644
index e7c963079b7..00000000000
--- a/packages/manager/src/components/DismissibleBanner/DismissibleBanner.stories.mdx
+++ /dev/null
@@ -1,126 +0,0 @@
-import { ArgsTable, Canvas, Meta, Story } from '@storybook/addon-docs';
-import { Button } from 'src/components/Button/Button';
-import { DismissibleBanner } from './DismissibleBanner';
-import Grid from '@mui/material/Unstable_Grid2';
-import { Link } from 'src/components/Link';
-import { Typography } from 'src/components/Typography';
-
-
-
-# Dismissible Banners
-
-### 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 DismissibleBannerTemplate = (args) => {
- return (
-
- This is an example of a dismissible banner.
-
- );
-};
-
-export const CallToActionBanner = () => {
- return (
-
-
-
- A new version of Kubernetes is available.
-
-
-
-
-
-
- );
-};
-
-export const StatusBannersTemplate = (args) => {
- const { message, title, status, impact, href } = args;
- return ;
-};
-
-export const BetaBanner = () => {
- return (
-
-
- 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{' '}
-
- Early Adopter Program SLA
-
- .
-
-
- );
-};
-
-#### Beta Banner
-
-Beta banners, along with [beta chips](/docs/elements-chips-beta-chips--default-story), provide notice to users about beta features.
-
-
-
-#### Call to Action Banner
-
-
-
-### Component API
-
-
-
-#### Beta
-
-Beta banners, along with [beta chips](/docs/elements-chips-beta-chips--default-story), provide notice to users about beta features.
-
-
-
-
diff --git a/packages/manager/src/components/DismissibleBanner/DismissibleBanner.stories.tsx b/packages/manager/src/components/DismissibleBanner/DismissibleBanner.stories.tsx
new file mode 100644
index 00000000000..25f38245c01
--- /dev/null
+++ b/packages/manager/src/components/DismissibleBanner/DismissibleBanner.stories.tsx
@@ -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;
+
+export const Default: Story = {
+ render: (args) => (
+
+ This is an example of a dismissible banner.
+
+ ),
+};
+
+/**
+ * Example of a dismissible banner with an associated action
+ */
+export const CallToActionBanner: Story = {
+ render: () => (
+ null}>
+ Upgrade Version
+
+ }
+ preferenceKey="cluster-v1"
+ variant="info"
+ >
+ A new version of Kubernetes is available.
+
+ ),
+};
+
+/**
+ * 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: () => (
+
+
+ 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{' '}
+
+ Early Adopter Program SLA
+
+ .
+
+
+ ),
+};
+
+const meta: Meta = {
+ args: { preferenceKey: 'dismissible-banner' },
+ component: DismissibleBanner,
+ title: 'Components/Notifications/Dismissible Banners',
+};
+
+export default meta;
diff --git a/packages/manager/src/components/DismissibleBanner/DismissibleBanner.styles.ts b/packages/manager/src/components/DismissibleBanner/DismissibleBanner.styles.ts
new file mode 100644
index 00000000000..7ac4261bf71
--- /dev/null
+++ b/packages/manager/src/components/DismissibleBanner/DismissibleBanner.styles.ts
@@ -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,
+ })
+);
diff --git a/packages/manager/src/components/DismissibleBanner/DismissibleBanner.test.tsx b/packages/manager/src/components/DismissibleBanner/DismissibleBanner.test.tsx
new file mode 100644
index 00000000000..cba9ba38d02
--- /dev/null
+++ b/packages/manager/src/components/DismissibleBanner/DismissibleBanner.test.tsx
@@ -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(
+
+ This is a dismissible banner
+
+ );
+ 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(
+
+ Action button
+
+ }
+ >
+ Banner with action button
+
+ );
+ const button = getByText('Action button');
+ expect(button).toBeVisible();
+ fireEvent.click(button);
+ expect(onClickProp.onClick).toHaveBeenCalled();
+ });
+});
diff --git a/packages/manager/src/components/DismissibleBanner/DismissibleBanner.tsx b/packages/manager/src/components/DismissibleBanner/DismissibleBanner.tsx
index b20a25167a9..53207a8ad60 100644
--- a/packages/manager/src/components/DismissibleBanner/DismissibleBanner.tsx
+++ b/packages/manager/src/components/DismissibleBanner/DismissibleBanner.tsx
@@ -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;
+/**
+ * ## 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,
@@ -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,
-}));
diff --git a/packages/manager/src/components/DismissibleBanner/index.ts b/packages/manager/src/components/DismissibleBanner/index.ts
deleted file mode 100644
index 19bfe9df306..00000000000
--- a/packages/manager/src/components/DismissibleBanner/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export { DismissibleBanner } from './DismissibleBanner';
diff --git a/packages/manager/src/components/ProductInformationBanner/ProductInformationBanner.tsx b/packages/manager/src/components/ProductInformationBanner/ProductInformationBanner.tsx
index 21e67df23b0..c0b9eec83c8 100644
--- a/packages/manager/src/components/ProductInformationBanner/ProductInformationBanner.tsx
+++ b/packages/manager/src/components/ProductInformationBanner/ProductInformationBanner.tsx
@@ -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';
diff --git a/packages/manager/src/features/Domains/DomainBanner.tsx b/packages/manager/src/features/Domains/DomainBanner.tsx
index 1aa60481d29..911be5f9f45 100644
--- a/packages/manager/src/features/Domains/DomainBanner.tsx
+++ b/packages/manager/src/features/Domains/DomainBanner.tsx
@@ -2,7 +2,7 @@ import { styled } from '@mui/material/styles';
import { DateTime } from 'luxon';
import * as React from 'react';
-import { DismissibleBanner } from 'src/components/DismissibleBanner';
+import { DismissibleBanner } from 'src/components/DismissibleBanner/DismissibleBanner';
import { Link } from 'src/components/Link';
import { Typography } from 'src/components/Typography';
diff --git a/packages/manager/src/features/GlobalNotifications/APIMaintenanceBanner.tsx b/packages/manager/src/features/GlobalNotifications/APIMaintenanceBanner.tsx
index 561d756115d..4e8316e03d1 100644
--- a/packages/manager/src/features/GlobalNotifications/APIMaintenanceBanner.tsx
+++ b/packages/manager/src/features/GlobalNotifications/APIMaintenanceBanner.tsx
@@ -1,8 +1,8 @@
-import { Stack } from 'src/components/Stack';
import * as React from 'react';
-import { DismissibleBanner } from 'src/components/DismissibleBanner';
+import { DismissibleBanner } from 'src/components/DismissibleBanner/DismissibleBanner';
import { Link } from 'src/components/Link';
+import { Stack } from 'src/components/Stack';
import { Typography } from 'src/components/Typography';
import { SuppliedMaintenanceData } from 'src/featureFlags';
import { queryPresets } from 'src/queries/base';
diff --git a/packages/manager/src/features/GlobalNotifications/ComplianceBanner.tsx b/packages/manager/src/features/GlobalNotifications/ComplianceBanner.tsx
index 0c3f5392307..cda10f1c5ad 100644
--- a/packages/manager/src/features/GlobalNotifications/ComplianceBanner.tsx
+++ b/packages/manager/src/features/GlobalNotifications/ComplianceBanner.tsx
@@ -3,7 +3,7 @@ import * as React from 'react';
import { Box } from 'src/components/Box';
import { Button } from 'src/components/Button/Button';
-import { DismissibleBanner } from 'src/components/DismissibleBanner';
+import { DismissibleBanner } from 'src/components/DismissibleBanner/DismissibleBanner';
import { Typography } from 'src/components/Typography';
import { complianceUpdateContext } from 'src/context/complianceUpdateContext';
import { useNotificationsQuery } from 'src/queries/accountNotifications';
diff --git a/packages/manager/src/features/GlobalNotifications/TaxCollectionBanner.tsx b/packages/manager/src/features/GlobalNotifications/TaxCollectionBanner.tsx
index d96a9ad9a05..55ddbbf2b9e 100644
--- a/packages/manager/src/features/GlobalNotifications/TaxCollectionBanner.tsx
+++ b/packages/manager/src/features/GlobalNotifications/TaxCollectionBanner.tsx
@@ -3,7 +3,7 @@ import * as React from 'react';
import { useHistory } from 'react-router-dom';
import { Button } from 'src/components/Button/Button';
-import { DismissibleBanner } from 'src/components/DismissibleBanner';
+import { DismissibleBanner } from 'src/components/DismissibleBanner/DismissibleBanner';
import { Link } from 'src/components/Link';
import { Typography } from 'src/components/Typography';
import { useFlags } from 'src/hooks/useFlags';
diff --git a/packages/manager/src/features/Help/StatusBanners.tsx b/packages/manager/src/features/Help/StatusBanners.tsx
index 445961d71a4..5dea406c15a 100644
--- a/packages/manager/src/features/Help/StatusBanners.tsx
+++ b/packages/manager/src/features/Help/StatusBanners.tsx
@@ -3,7 +3,7 @@ import { DateTime } from 'luxon';
import * as React from 'react';
import { Box } from 'src/components/Box';
-import { DismissibleBanner } from 'src/components/DismissibleBanner';
+import { DismissibleBanner } from 'src/components/DismissibleBanner/DismissibleBanner';
import { Link } from 'src/components/Link';
import { Typography } from 'src/components/Typography';
import {
diff --git a/packages/manager/src/features/Kubernetes/KubernetesClusterDetail/UpgradeKubernetesVersionBanner.tsx b/packages/manager/src/features/Kubernetes/KubernetesClusterDetail/UpgradeKubernetesVersionBanner.tsx
index 6030d1992f7..56cbf4734d9 100644
--- a/packages/manager/src/features/Kubernetes/KubernetesClusterDetail/UpgradeKubernetesVersionBanner.tsx
+++ b/packages/manager/src/features/Kubernetes/KubernetesClusterDetail/UpgradeKubernetesVersionBanner.tsx
@@ -2,7 +2,7 @@ import Grid from '@mui/material/Unstable_Grid2';
import * as React from 'react';
import { Button } from 'src/components/Button/Button';
-import { DismissibleBanner } from 'src/components/DismissibleBanner';
+import { DismissibleBanner } from 'src/components/DismissibleBanner/DismissibleBanner';
import { Typography } from 'src/components/Typography';
import { useKubernetesVersionQuery } from 'src/queries/kubernetes';
diff --git a/packages/manager/src/features/Linodes/LinodesDetail/LinodesDetailNavigation.tsx b/packages/manager/src/features/Linodes/LinodesDetail/LinodesDetailNavigation.tsx
index a73b3d6f441..69addb34d5b 100644
--- a/packages/manager/src/features/Linodes/LinodesDetail/LinodesDetailNavigation.tsx
+++ b/packages/manager/src/features/Linodes/LinodesDetail/LinodesDetailNavigation.tsx
@@ -8,7 +8,7 @@ import {
} from 'react-router-dom';
import { CircleProgress } from 'src/components/CircleProgress';
-import { DismissibleBanner } from 'src/components/DismissibleBanner';
+import { DismissibleBanner } from 'src/components/DismissibleBanner/DismissibleBanner';
import { DocumentTitleSegment } from 'src/components/DocumentTitle';
import { ErrorState } from 'src/components/ErrorState/ErrorState';
import { TabPanels } from 'src/components/ReachTabPanels';
diff --git a/packages/manager/src/features/ObjectStorage/ObjectStorageLanding.tsx b/packages/manager/src/features/ObjectStorage/ObjectStorageLanding.tsx
index eaae1dff96b..2c1679d8097 100644
--- a/packages/manager/src/features/ObjectStorage/ObjectStorageLanding.tsx
+++ b/packages/manager/src/features/ObjectStorage/ObjectStorageLanding.tsx
@@ -4,7 +4,7 @@ import * as React from 'react';
import { useHistory, useParams } from 'react-router-dom';
import { StyledLinkButton } from 'src/components/Button/StyledLinkButton';
-import { DismissibleBanner } from 'src/components/DismissibleBanner';
+import { DismissibleBanner } from 'src/components/DismissibleBanner/DismissibleBanner';
import { DocumentTitleSegment } from 'src/components/DocumentTitle';
import { LandingHeader } from 'src/components/LandingHeader';
import { Link } from 'src/components/Link';
diff --git a/packages/manager/src/features/VPCs/VPCDetail/VPCDetail.tsx b/packages/manager/src/features/VPCs/VPCDetail/VPCDetail.tsx
index 9f342a5814e..5025209e915 100644
--- a/packages/manager/src/features/VPCs/VPCDetail/VPCDetail.tsx
+++ b/packages/manager/src/features/VPCs/VPCDetail/VPCDetail.tsx
@@ -6,7 +6,7 @@ import { useParams } from 'react-router-dom';
import { Box } from 'src/components/Box';
import { StyledLinkButton } from 'src/components/Button/StyledLinkButton';
import { CircleProgress } from 'src/components/CircleProgress/CircleProgress';
-import { DismissibleBanner } from 'src/components/DismissibleBanner';
+import { DismissibleBanner } from 'src/components/DismissibleBanner/DismissibleBanner';
import { DocumentTitleSegment } from 'src/components/DocumentTitle';
import { EntityHeader } from 'src/components/EntityHeader/EntityHeader';
import { ErrorState } from 'src/components/ErrorState/ErrorState';