diff --git a/.changeset/cool-buttons-happen.md b/.changeset/cool-buttons-happen.md new file mode 100644 index 0000000000..aa09bacf3c --- /dev/null +++ b/.changeset/cool-buttons-happen.md @@ -0,0 +1,5 @@ +--- +'@kadena/react-ui': minor +--- + +Updated the Notification component API diff --git a/packages/apps/docs/src/components/BottomPageSection/components/Subscribe.tsx b/packages/apps/docs/src/components/BottomPageSection/components/Subscribe.tsx index 0542601ce7..ac389afd88 100644 --- a/packages/apps/docs/src/components/BottomPageSection/components/Subscribe.tsx +++ b/packages/apps/docs/src/components/BottomPageSection/components/Subscribe.tsx @@ -49,16 +49,16 @@ export const Subscribe: FC = () => { {Boolean(message) && ( - + {message} - + )} ) : ( Boolean(message) && ( - + {message} - + ) )} diff --git a/packages/apps/docs/src/components/CookieConsent/CookieConsent.tsx b/packages/apps/docs/src/components/CookieConsent/CookieConsent.tsx index a6f179b7f1..45cb619903 100644 --- a/packages/apps/docs/src/components/CookieConsent/CookieConsent.tsx +++ b/packages/apps/docs/src/components/CookieConsent/CookieConsent.tsx @@ -1,8 +1,15 @@ import { updateConsent } from '@/utils/analytics'; -import { Notification, Text } from '@kadena/react-ui'; +import { + Notification, + NotificationButton, + NotificationFooter, + NotificationHeading, + SystemIcon, + Text, +} from '@kadena/react-ui'; import type { FC } from 'react'; import React, { useCallback, useEffect, useState } from 'react'; -import { notificationClass } from './styles.css'; +import { containerClass, notificationWrapperClass } from './styles.css'; export const CookieConsent: FC = () => { const [cookieConsent, setCookieConsent] = useState(null); @@ -31,36 +38,34 @@ export const CookieConsent: FC = () => { if (cookieConsent !== null || !mounted) return null; return ( -
- - - This notification concerns the cookie policy requirement to ask users - for their consent to use Google Analytics or other - tracking tools for better optimizations/performances. - - - - Accept - - - Reject - - - -
+
+
+ } + role="none" + > + + Cookie Consent + + + This notification concerns the cookie policy requirement to ask + users for their consent to use Google Analytics or + other tracking tools for better optimizations/performances. + + + + Accept + + + + Reject + + + + +
+
); }; diff --git a/packages/apps/docs/src/components/CookieConsent/styles.css.ts b/packages/apps/docs/src/components/CookieConsent/styles.css.ts index dcd2ec2a3b..e45e7f439e 100644 --- a/packages/apps/docs/src/components/CookieConsent/styles.css.ts +++ b/packages/apps/docs/src/components/CookieConsent/styles.css.ts @@ -1,12 +1,20 @@ import { sprinkles } from '@kadena/react-ui/theme'; import { style } from '@vanilla-extract/css'; +import { $$pageWidth, globalClass } from '../Layout/global.css'; -export const notificationClass = style([ +export const containerClass = style([ sprinkles({ position: 'sticky', top: '$17', + bg: '$primarySurfaceInverted', }), { zIndex: 1000, }, ]); + +export const notificationWrapperClass = style([ + globalClass, + sprinkles({ marginX: 'auto' }), + { maxWidth: $$pageWidth }, +]); diff --git a/packages/apps/docs/src/components/Markdown/MDNotification/MDNotification.tsx b/packages/apps/docs/src/components/Markdown/MDNotification/MDNotification.tsx index ffebb7b097..a81178a95d 100644 --- a/packages/apps/docs/src/components/Markdown/MDNotification/MDNotification.tsx +++ b/packages/apps/docs/src/components/Markdown/MDNotification/MDNotification.tsx @@ -1,4 +1,4 @@ -import { Notification } from '@kadena/react-ui'; +import { Notification, NotificationHeading } from '@kadena/react-ui'; import classNames from 'classnames'; import type { FC, ReactNode } from 'react'; import React from 'react'; @@ -16,15 +16,15 @@ interface IProps { export const MDNotification: FC = ({ children, title = '', label }) => { return (
- + {title} {children} - +
); }; diff --git a/packages/apps/docs/src/components/Markdown/MDNotification/utils.ts b/packages/apps/docs/src/components/Markdown/MDNotification/utils.tsx similarity index 76% rename from packages/apps/docs/src/components/Markdown/MDNotification/utils.ts rename to packages/apps/docs/src/components/Markdown/MDNotification/utils.tsx index 6939dbad03..1af910dbc5 100644 --- a/packages/apps/docs/src/components/Markdown/MDNotification/utils.ts +++ b/packages/apps/docs/src/components/Markdown/MDNotification/utils.tsx @@ -1,4 +1,6 @@ import type { INotificationProps } from '@kadena/react-ui'; +import { SystemIcon } from '@kadena/react-ui'; +import React from 'react'; export type LabelType = | 'info' @@ -7,14 +9,10 @@ export type LabelType = | 'caution' | 'danger' | 'warning'; -type IconType = 'Information' | 'Bell' | undefined; export const getColor = (label?: LabelType): INotificationProps['color'] => { if (!label) return; switch (label) { - case 'note': - case 'info': - return 'primary'; case 'tip': return 'positive'; case 'danger': @@ -22,23 +20,23 @@ export const getColor = (label?: LabelType): INotificationProps['color'] => { return 'negative'; case 'caution': return 'warning'; + case 'note': + case 'info': default: - return 'primary'; + return 'info'; } }; -export const getIcon = (label?: LabelType): IconType => { +export const getIcon = (label?: LabelType): INotificationProps['icon'] => { if (!label) return undefined; switch (label) { - case 'note': - case 'info': - case 'tip': - return 'Information'; case 'caution': case 'warning': case 'danger': - return 'Bell'; - + return ; + case 'note': + case 'info': + case 'tip': default: return undefined; } diff --git a/packages/apps/docs/src/components/Search/components/SearchResults.tsx b/packages/apps/docs/src/components/Search/components/SearchResults.tsx index b31c1c2c41..21f773fd35 100644 --- a/packages/apps/docs/src/components/Search/components/SearchResults.tsx +++ b/packages/apps/docs/src/components/Search/components/SearchResults.tsx @@ -7,7 +7,9 @@ import { Button, Heading, Notification, + NotificationHeading, Stack, + SystemIcon, Tabs, useModal, } from '@kadena/react-ui'; @@ -98,14 +100,13 @@ export const SearchResults: FC = ({ )} {semanticError ? ( - } + role="status" > {semanticError} - + ) : ( <> @@ -136,11 +137,8 @@ export const SearchResults: FC = ({ - + } role="none"> + QA search is in beta QA search our latest AI vector-based search, designed to provide instant answers to your queries.
@@ -155,7 +153,7 @@ export const SearchResults: FC = ({ collect valuable data that will aid us in refining and enhancing the accuracy of our model’s responses in the future.

-
+
{isLoading && ( @@ -164,13 +162,13 @@ export const SearchResults: FC = ({
)} {error && ( - } + role="status" > {error} - + )} {conversation.history?.map((interaction, idx) => { diff --git a/packages/apps/graph-client/src/components/error-box/error-box.tsx b/packages/apps/graph-client/src/components/error-box/error-box.tsx index 18765a69d3..9d136bba2a 100644 --- a/packages/apps/graph-client/src/components/error-box/error-box.tsx +++ b/packages/apps/graph-client/src/components/error-box/error-box.tsx @@ -1,5 +1,5 @@ import type { ApolloError } from '@apollo/client'; -import { Box, Notification } from '@kadena/react-ui'; +import { Box, Notification, SystemIcon } from '@kadena/react-ui'; import React from 'react'; interface IErrorBoxProps { @@ -28,7 +28,7 @@ export const ErrorBox = (props: IErrorBoxProps): JSX.Element => { } return ( - + } role="status"> {errorTitle} {errorMessage} @@ -38,6 +38,6 @@ export const ErrorBox = (props: IErrorBoxProps): JSX.Element => { {errorExtra} )} - + ); }; diff --git a/packages/apps/graph-client/src/pages/account/overview/[module]/[account].tsx b/packages/apps/graph-client/src/pages/account/overview/[module]/[account].tsx index 39371e5b23..eff0c54bff 100644 --- a/packages/apps/graph-client/src/pages/account/overview/[module]/[account].tsx +++ b/packages/apps/graph-client/src/pages/account/overview/[module]/[account].tsx @@ -41,10 +41,10 @@ const Account: React.FC = () => { data?.account?.totalBalance === 0 && data?.account?.chainAccounts.length === 0 && ( <> - + We could not find any data on this account. Please check the module and account name. - + )} diff --git a/packages/apps/graph-client/src/pages/transactions/[key].tsx b/packages/apps/graph-client/src/pages/transactions/[key].tsx index 923966c77b..7d96aadd11 100644 --- a/packages/apps/graph-client/src/pages/transactions/[key].tsx +++ b/packages/apps/graph-client/src/pages/transactions/[key].tsx @@ -2,7 +2,14 @@ import { useGetTransactionByRequestKeySubscription } from '@/__generated__/sdk'; import LoaderAndError from '@/components/LoaderAndError/loader-and-error'; import routes from '@/constants/routes'; import { formatCode, formatLisp } from '@/utils/formatter'; -import { Box, Breadcrumbs, Link, Notification, Table } from '@kadena/react-ui'; +import { + Box, + Breadcrumbs, + Link, + Notification, + SystemIcon, + Table, +} from '@kadena/react-ui'; import { useRouter } from 'next/router'; import React from 'react'; @@ -47,10 +54,10 @@ const RequestKey: React.FC = () => { {data?.transaction?.badResult && ( - } + role="status" > Transaction failed with status:{' '}
@@ -60,24 +67,24 @@ const RequestKey: React.FC = () => {
                           4,
                         )}
                       
-
+ )} {data?.transaction?.goodResult && ( - } + role="status" > Transaction succeeded with status:
{formatCode(data?.transaction?.goodResult)}
-
+ )} {!data?.transaction?.goodResult && !data?.transaction?.badResult && ( - + Unknown transaction status - + )}
diff --git a/packages/apps/tools/src/components/Global/CloseableNotification/index.tsx b/packages/apps/tools/src/components/Global/CloseableNotification/index.tsx deleted file mode 100644 index c148683caf..0000000000 --- a/packages/apps/tools/src/components/Global/CloseableNotification/index.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import type { INotificationProps } from '@kadena/react-ui'; -import { Notification } from '@kadena/react-ui'; -import React from 'react'; - -export interface ICloseableNotificationProps - extends Omit {} - -export const CloseableNotification = ({ - onClose, - ...rest -}: ICloseableNotificationProps) => { - const [show, setShow] = React.useState(true); - if (!show) return null; - return ( - { - onClose?.(); - setShow(false); - }} - {...rest} - /> - ); -}; diff --git a/packages/apps/tools/src/components/Global/FormStatusNotification/index.tsx b/packages/apps/tools/src/components/Global/FormStatusNotification/index.tsx index fe88942b59..781fcd7df0 100644 --- a/packages/apps/tools/src/components/Global/FormStatusNotification/index.tsx +++ b/packages/apps/tools/src/components/Global/FormStatusNotification/index.tsx @@ -1,5 +1,9 @@ import type { INotificationProps } from '@kadena/react-ui'; -import { Notification } from '@kadena/react-ui'; +import { + Notification, + NotificationHeading, + SystemIcon, +} from '@kadena/react-ui'; import useTranslation from 'next-translate/useTranslation'; import type { FC } from 'react'; import React, { useCallback, useEffect, useState } from 'react'; @@ -18,10 +22,10 @@ const statusToColorMap: Record = { }; const statusToIconMap: Record = { - erroneous: 'AlertBox', - idle: 'AlertCircleOutline', - processing: 'Information', - successful: 'Check', + erroneous: , + idle: , + processing: , + successful: , }; export interface IFormStatusNotificationProps { @@ -75,18 +79,17 @@ export const FormStatusNotification: FC = ( return (
- + {title ?? titles[status!]} {body ?? bodies[status!]} {children} - +
); }; diff --git a/packages/apps/tools/src/pages/faucet/existing/index.tsx b/packages/apps/tools/src/pages/faucet/existing/index.tsx index 69330bc199..28aa584953 100644 --- a/packages/apps/tools/src/pages/faucet/existing/index.tsx +++ b/packages/apps/tools/src/pages/faucet/existing/index.tsx @@ -17,6 +17,7 @@ import { Card, Heading, Notification, + NotificationHeading, } from '@kadena/react-ui'; import Trans from 'next-translate/Trans'; import useTranslation from 'next-translate/useTranslation'; @@ -143,13 +144,10 @@ const ExistingAccountFaucetPage: FC = () => { {t('Add Funds to Existing Account')}
{mainnetSelected ? ( - + + + {t('The Faucet is not available on Mainnet')} + { />, ]} /> - + ) : null}
diff --git a/packages/apps/tools/src/pages/faucet/new/index.tsx b/packages/apps/tools/src/pages/faucet/new/index.tsx index 6ad4339a19..04e7319f81 100644 --- a/packages/apps/tools/src/pages/faucet/new/index.tsx +++ b/packages/apps/tools/src/pages/faucet/new/index.tsx @@ -8,6 +8,7 @@ import { Heading, IconButton, Notification, + NotificationHeading, } from '@kadena/react-ui'; import { @@ -33,7 +34,6 @@ import type { FormStatus } from '@/components/Global'; import { ChainSelect, FormStatusNotification } from '@/components/Global'; import { AccountHoverTag } from '@/components/Global/AccountHoverTag'; import AccountNameField from '@/components/Global/AccountNameField'; -import { CloseableNotification } from '@/components/Global/CloseableNotification'; import { HoverTag } from '@/components/Global/HoverTag'; import type { PredKey } from '@/components/Global/PredKeysSelect'; import { PredKeysSelect } from '@/components/Global/PredKeysSelect'; @@ -251,13 +251,10 @@ const NewAccountFaucetPage: FC = () => { {t('Create and Fund New Account')}
{mainnetSelected ? ( - + + + {t('The Faucet is not available on Mainnet')} + { />, ]} /> - + ) : null}
- + + {t(`Before you start`)} { />, ]} /> - +
{ {txError ? ( - { setTxError(''); }} - title="Warning" - icon={'AlertBox'} - variant="outlined" + icon={} + role="status" > + Warning {txError} - - + {t('Retry')} - - - + + + + ) : null} , - 'secondary' | 'tertiary' -> = { - info: 'info', - positive: 'positive', - warning: 'warning', - negative: 'negative', - primary: 'primary', -}; +const accentVar = createVar(); export const containerClass = style([ sprinkles({ display: 'flex', alignItems: 'flex-start', - borderStyle: 'solid', - justifyContent: 'center', - }), - { - borderLeftWidth: vars.sizes.$1, - }, -]); - -export const containerWrapperClass = style([ - sprinkles({ - padding: '$md', - display: 'flex', + padding: '$sm', + gap: '$sm', width: '100%', - alignItems: 'flex-start', - gap: '$md', }), - { - maxWidth: 1440, - }, ]); +export const colorVariants: Omit< + Record, + 'secondary' | 'tertiary' | 'inverted' | 'primary' +> = { + info: 'info', + positive: 'positive', + warning: 'warning', + negative: 'negative', +}; + export const cardColorVariants = styleVariants(colorVariants, (color) => { return [ sprinkles({ @@ -46,32 +32,26 @@ export const cardColorVariants = styleVariants(colorVariants, (color) => { borderColor: `$${color}ContrastInverted`, color: `$${color}ContrastInverted`, }), + { + vars: { + [accentVar]: vars.colors[`$${color}ContrastInverted`], + }, + }, ]; }); -export const expandVariants = styleVariants({ - true: [sprinkles({ width: '100%', maxWidth: '100%' })], - false: [sprinkles({ width: 'max-content', maxWidth: '$maxContentWidth' })], -}); - export const displayVariants = styleVariants({ - outlined: [sprinkles({ borderWidth: '$sm', borderRadius: '$sm' })], - standard: [sprinkles({ border: 'none', borderRadius: 0 })], -}); - -export const inlineVariants = styleVariants({ - true: [ + bordered: [ sprinkles({ - display: 'flex', - alignItems: { - md: 'flex-start', - }, - flexDirection: { - md: 'row', - }, + borderStyle: 'solid', + borderWidth: '$sm', + borderRadius: '$sm', }), + { + borderLeftWidth: vars.sizes.$1, + }, ], - false: [], + borderless: [], }); export const closeButtonClass = style([ @@ -87,10 +67,10 @@ export const closeButtonClass = style([ export const contentClass = style([ sprinkles({ - display: 'flex', - flexDirection: 'column', + color: '$neutral6', + fontSize: '$base', gap: '$xs', - width: '100%', + maxWidth: '$maxContentWidth', }), { marginTop: 2, @@ -99,25 +79,21 @@ export const contentClass = style([ export const titleClass = style([ sprinkles({ - color: 'inherit', fontSize: '$base', fontWeight: '$bold', + marginBottom: '$xs', }), -]); - -export const descriptionClass = style([ - sprinkles({ - color: '$neutral6', - fontSize: '$base', - }), + { + color: accentVar, + }, ]); export const actionsContainerClass = style([ sprinkles({ - marginTop: '$lg', + marginTop: '$md', display: 'flex', justifyContent: 'flex-start', - gap: '$12', + gap: '$xl', }), ]); @@ -148,3 +124,10 @@ export const actionButtonColorVariants = styleVariants( ]; }, ); + +export const iconClass = style([ + sprinkles({ + color: 'inherit', + size: '$6', + }), +]); diff --git a/packages/libs/react-ui/src/components/Notification/Notification.stories.tsx b/packages/libs/react-ui/src/components/Notification/Notification.stories.tsx index 0d18a42878..8715550071 100644 --- a/packages/libs/react-ui/src/components/Notification/Notification.stories.tsx +++ b/packages/libs/react-ui/src/components/Notification/Notification.stories.tsx @@ -1,15 +1,20 @@ -import { SystemIcon } from '@components/Icon'; import type { INotificationProps } from '@components/Notification'; -import { Notification } from '@components/Notification'; +import { + Notification, + NotificationButton, + NotificationFooter, + NotificationHeading, +} from '@components/Notification'; import type { Meta, StoryObj } from '@storybook/react'; import React from 'react'; +import { SystemIcon } from '..'; import { colorVariants, displayVariants } from './Notification.css'; -const meta: Meta< - { - text: string; - } & INotificationProps -> = { +type StoryType = { + heading: string; +} & INotificationProps; + +const meta: Meta = { title: 'Components/Notification', parameters: { status: { @@ -18,26 +23,20 @@ const meta: Meta< docs: { description: { component: - 'The Notification component renders a notification with an icon, title, and text. The color variant of the notification can be set with the `color` prop.', + 'The Notification component renders a notification with an icon, heading, body, and action buttons. This component is used to announce dynamic changes in the content of a live region by asserting a discreet alert or notification. The appropriate role should be used to ensure that assistive technologies announce these dynamic changes. In the case where a user wants to use the Notification component purely for visual purposes, the role can be set to `none`.', }, }, }, argTypes: { - variant: { - options: Object.keys(displayVariants) as (keyof typeof displayVariants)[], - control: { - type: 'select', - }, - }, - icon: { - options: Object.keys(SystemIcon) as (keyof typeof SystemIcon)[], + styleVariant: { + description: + 'The Notification component has bordered and borderless variants. The borderless variant is used for notifications that located within a card or content body, while the bordered variant can be used in all other cases. ', + options: Object.keys(displayVariants), control: { type: 'select', }, - }, - title: { - control: { - type: 'text', + table: { + defaultValue: { summary: 'bordered' }, }, }, color: { @@ -46,82 +45,67 @@ const meta: Meta< type: 'select', }, }, - expanded: { + hasCloseButton: { control: { type: 'boolean', }, }, - hasCloseButton: { + children: { control: { - type: 'boolean', + type: 'text', }, }, - inline: { + role: { + description: + "The Notification component has a role attribute that can be set to 'alert', 'status', or 'none'.", + options: ['alert', 'status', 'none'], control: { - type: 'boolean', + type: 'select', + }, + table: { + defaultValue: { summary: 'status' }, }, }, }, }; export default meta; -type Story = StoryObj< - { - text: string; - } & INotificationProps ->; - -/* - *👇 Render functions are a framework specific feature to allow you control on how the component renders. - * See https://storybook.js.org/docs/7.0/react/api/csf - * to learn how to use render functions. - */ +type Story = StoryObj; export const Primary: Story = { name: 'Notification', args: { - icon: 'Information', - title: 'Notification title', + heading: 'Notification Heading', hasCloseButton: true, - expanded: false, color: undefined, - text: 'Notification text to inform users about the event that occurred!', - variant: 'standard', - inline: false, + children: + 'Notification children to inform users about the event that occurred!', + styleVariant: 'bordered', }, - render: ({ - icon, - title, - hasCloseButton, - expanded, - color, - text, - variant, - inline, - }) => { + render: ({ heading, hasCloseButton, color, children, styleVariant }) => { return ( - { alert('Close button clicked'); }} - variant={variant} - inline={inline} + styleVariant={styleVariant} + role="none" > - {text} - - + {heading} + {children} + + Accept - - + + + Reject - - - + + + + ); }, }; diff --git a/packages/libs/react-ui/src/components/Notification/Notification.tsx b/packages/libs/react-ui/src/components/Notification/Notification.tsx new file mode 100644 index 0000000000..84cabac755 --- /dev/null +++ b/packages/libs/react-ui/src/components/Notification/Notification.tsx @@ -0,0 +1,67 @@ +// eslint-disable-next-line @typescript-eslint/consistent-type-imports +import { Close, Information } from '@components/Icon/System/SystemIcon'; +import classNames from 'classnames'; +import type { FC } from 'react'; +import React, { useState } from 'react'; +import { + cardColorVariants, + closeButtonClass, + containerClass, + contentClass, + displayVariants, + iconClass, +} from './Notification.css'; + +export interface INotificationProps { + children?: React.ReactNode; + color?: keyof typeof cardColorVariants; + styleVariant?: keyof typeof displayVariants; + hasCloseButton?: boolean; + onClose?: () => void; + icon?: React.ReactNode; + role: 'alert' | 'status' | 'none'; +} + +export const Notification: FC = ({ + children, + hasCloseButton = false, + color = 'info', + styleVariant = 'bordered', + onClose, + icon, + role, +}) => { + const [isClosed, setIsClosed] = useState(false); + const classList = classNames( + containerClass, + cardColorVariants[color], + displayVariants[styleVariant], + ); + + if (isClosed) return null; + + return ( +
+ {icon ? ( + {icon} + ) : ( + + )} + +
{children}
+ + {hasCloseButton && ( + + )} +
+ ); +}; diff --git a/packages/libs/react-ui/src/components/Notification/NotificationActions.tsx b/packages/libs/react-ui/src/components/Notification/NotificationActions.tsx deleted file mode 100644 index 192647c0de..0000000000 --- a/packages/libs/react-ui/src/components/Notification/NotificationActions.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import type { FC } from 'react'; -import React from 'react'; -import { actionsContainerClass } from './Notification.css'; - -export interface INotificationActionsProps { - children: React.ReactNode; -} - -export const NotificationActions: FC = ({ - children, -}) =>
{children}
; diff --git a/packages/libs/react-ui/src/components/Notification/NotificationButton.tsx b/packages/libs/react-ui/src/components/Notification/NotificationButton.tsx index 68f5450c2b..1e6f826f52 100644 --- a/packages/libs/react-ui/src/components/Notification/NotificationButton.tsx +++ b/packages/libs/react-ui/src/components/Notification/NotificationButton.tsx @@ -1,26 +1,20 @@ -import { SystemIcon } from '@components/Icon'; import type { FC } from 'react'; import React from 'react'; import { actionButtonColorVariants } from './Notification.css'; export interface INotificationButtonProps { - icon: keyof typeof SystemIcon; color: keyof typeof actionButtonColorVariants; onClick?: () => void; children: React.ReactNode; } export const NotificationButton: FC = ({ - icon, color, onClick, children, }) => { - const Icon = icon && SystemIcon[icon]; - return ( ); }; diff --git a/packages/libs/react-ui/src/components/Notification/NotificationContainer.tsx b/packages/libs/react-ui/src/components/Notification/NotificationContainer.tsx deleted file mode 100644 index 61770afea7..0000000000 --- a/packages/libs/react-ui/src/components/Notification/NotificationContainer.tsx +++ /dev/null @@ -1,84 +0,0 @@ -// eslint-disable-next-line @typescript-eslint/consistent-type-imports -import { SystemIcon } from '@components/Icon'; -import classNames from 'classnames'; -import type { FC } from 'react'; -import React from 'react'; -import type { colorVariants } from './Notification.css'; -import { - cardColorVariants, - closeButtonClass, - containerClass, - containerWrapperClass, - contentClass, - descriptionClass, - displayVariants, - expandVariants, - inlineVariants, - titleClass, -} from './Notification.css'; - -export interface INotificationProps { - icon?: keyof typeof SystemIcon; - title?: string; - children?: React.ReactNode; - expanded?: boolean; - color?: keyof typeof colorVariants; - hasCloseButton?: boolean; - onClose?: () => void; - variant?: keyof typeof displayVariants; - inline?: boolean; -} - -export const NotificationContainer: FC = ({ - icon, - title, - children, - hasCloseButton = false, - color = 'info', - expanded = false, - onClose, - variant = 'standard', - inline = false, -}) => { - const Icon = icon ? SystemIcon[icon] : SystemIcon.HelpCircle; - - const inlineVariantsClass = inlineVariants[inline ? 'true' : 'false']; - - const classList = classNames( - containerClass, - cardColorVariants[color], - displayVariants[variant], - expandVariants[expanded ? 'true' : 'false'], - inlineVariantsClass, - ); - - const contentClassList = classNames(contentClass, inlineVariantsClass); - - const descriptionClassList = classNames( - descriptionClass, - inlineVariantsClass, - ); - - return ( -
-
- - -
- {title && {title}} -
{children}
-
- - {hasCloseButton && ( - - )} -
-
- ); -}; diff --git a/packages/libs/react-ui/src/components/Notification/NotificationSubComponents.tsx b/packages/libs/react-ui/src/components/Notification/NotificationSubComponents.tsx new file mode 100644 index 0000000000..cf8e858098 --- /dev/null +++ b/packages/libs/react-ui/src/components/Notification/NotificationSubComponents.tsx @@ -0,0 +1,23 @@ +import type { ComponentPropsWithRef, FC } from 'react'; +import React from 'react'; +import { actionsContainerClass, titleClass } from './Notification.css'; + +export interface INotificationHeadingProps + extends ComponentPropsWithRef<'h5'> {} + +export const NotificationHeading: FC = ({ + children, + ...restProps +}) => ( +
+ {children} +
+); + +export interface INotificationFooterProps { + children: React.ReactNode; +} + +export const NotificationFooter: FC = ({ + children, +}) =>
{children}
; diff --git a/packages/libs/react-ui/src/components/Notification/index.ts b/packages/libs/react-ui/src/components/Notification/index.ts index 0217fe9b37..ae080eda0c 100644 --- a/packages/libs/react-ui/src/components/Notification/index.ts +++ b/packages/libs/react-ui/src/components/Notification/index.ts @@ -1,25 +1,12 @@ -import type { FC } from 'react'; -import type { INotificationActionsProps } from './NotificationActions'; -import { NotificationActions } from './NotificationActions'; -import type { INotificationButtonProps } from './NotificationButton'; -import { NotificationButton } from './NotificationButton'; -import type { INotificationProps } from './NotificationContainer'; -import { NotificationContainer } from './NotificationContainer'; - +export { Notification } from './Notification'; +export type { INotificationProps } from './Notification'; +export { NotificationButton } from './NotificationButton'; +export type { INotificationButtonProps } from './NotificationButton'; +export { + NotificationFooter, + NotificationHeading, +} from './NotificationSubComponents'; export type { - INotificationActionsProps, - INotificationButtonProps, - INotificationProps, -}; - -interface INotification { - Root: FC; - Actions: FC; - Button: FC; -} - -export const Notification: INotification = { - Root: NotificationContainer, - Actions: NotificationActions, - Button: NotificationButton, -}; + INotificationFooterProps, + INotificationHeadingProps, +} from './NotificationSubComponents'; diff --git a/packages/libs/react-ui/src/components/index.ts b/packages/libs/react-ui/src/components/index.ts index f054f4fb64..afd6f29433 100644 --- a/packages/libs/react-ui/src/components/index.ts +++ b/packages/libs/react-ui/src/components/index.ts @@ -44,8 +44,9 @@ export type { INavHeaderSelectProps, } from './NavHeader'; export type { - INotificationActionsProps, INotificationButtonProps, + INotificationFooterProps, + INotificationHeadingProps, INotificationProps, } from './Notification'; export type { IPaginationProps } from './Pagination'; @@ -98,7 +99,12 @@ export { maskValue } from './MaskedValue/utils'; export { Modal, ModalProvider, useModal } from './Modal'; export { NavFooter } from './NavFooter'; export { NavHeader } from './NavHeader'; -export { Notification } from './Notification'; +export { + Notification, + NotificationButton, + NotificationFooter, + NotificationHeading, +} from './Notification'; export { Pagination } from './Pagination'; export { ProfileSummary } from './ProfileSummary'; export { ProgressBar } from './ProgressBar'; diff --git a/packages/libs/react-ui/src/index.ts b/packages/libs/react-ui/src/index.ts index 962e4d0aa2..544625376f 100644 --- a/packages/libs/react-ui/src/index.ts +++ b/packages/libs/react-ui/src/index.ts @@ -36,8 +36,9 @@ export type { INavHeaderNavigationProps, INavHeaderRootProps, INavHeaderSelectProps, - INotificationActionsProps, INotificationButtonProps, + INotificationFooterProps, + INotificationHeadingProps, INotificationProps, IPaginationProps, IProfileSummaryLinkProps, @@ -87,6 +88,9 @@ export { NavFooter, NavHeader, Notification, + NotificationButton, + NotificationFooter, + NotificationHeading, Pagination, ProductIcon, ProfileSummary, diff --git a/packages/libs/react-ui/src/styles/sprinkles.css.ts b/packages/libs/react-ui/src/styles/sprinkles.css.ts index 6331fb85e8..e93a628529 100644 --- a/packages/libs/react-ui/src/styles/sprinkles.css.ts +++ b/packages/libs/react-ui/src/styles/sprinkles.css.ts @@ -28,6 +28,7 @@ const systemProperties = defineProperties({ top: vars.sizes, wordBreak: ['normal', 'keep-all', 'break-word', 'break-all'], zIndex: [-1, 0, 1], + whiteSpace: ['nowrap', 'break-spaces', 'normal', 'pre-wrap'], }, }); @@ -123,7 +124,6 @@ const responsiveProperties = defineProperties({ textAlign: ['left', 'center', 'right'], fontSize: vars.fontSizes, fontWeight: vars.fontWeights, - whiteSpace: ['nowrap', 'break-spaces', 'normal'], }, shorthands: { margin: ['marginTop', 'marginBottom', 'marginLeft', 'marginRight'],