Skip to content

Commit f5ed1a9

Browse files
authored
feat(notifications): new light/dark mode colors (#1842)
1 parent 4a4b92d commit f5ed1a9

38 files changed

+900
-476
lines changed

packages/notifications/src/elements/Alert.tsx

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,20 @@ import React from 'react';
99
import PropTypes from 'prop-types';
1010
import { IAlertProps, TYPE } from '../types';
1111
import { StyledAlert, StyledIcon } from '../styled';
12-
import { validationIcons, validationHues } from '../utils/icons';
13-
import { Hue, NotificationsContext } from '../utils/useNotificationsContext';
12+
import { validationIcons } from '../utils/icons';
13+
import { NotificationsContext } from '../utils/useNotificationsContext';
1414
import { Title } from './content/Title';
1515
import { Paragraph } from './content/Paragraph';
1616
import { Close } from './content/Close';
1717

1818
export const AlertComponent = React.forwardRef<HTMLDivElement, IAlertProps>(
19-
({ role, ...props }, ref) => {
20-
const hue = validationHues[props.type];
21-
const Icon = validationIcons[props.type] as any;
19+
({ role, type, ...props }, ref) => {
20+
const Icon = validationIcons[type] as any;
2221

2322
return (
24-
<NotificationsContext.Provider value={hue as Hue}>
25-
<StyledAlert ref={ref} hue={hue} role={role === undefined ? 'alert' : role} {...props}>
26-
<StyledIcon $hue={hue}>
23+
<NotificationsContext.Provider value={type}>
24+
<StyledAlert ref={ref} $type={type} role={role === undefined ? 'alert' : role} {...props}>
25+
<StyledIcon $type={type}>
2726
<Icon />
2827
</StyledIcon>
2928
{props.children}

packages/notifications/src/elements/Notification.tsx

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,24 +10,22 @@ import PropTypes from 'prop-types';
1010
import InfoStrokeIcon from '@zendeskgarden/svg-icons/src/16/info-stroke.svg';
1111
import { INotificationProps, TYPE } from '../types';
1212
import { StyledNotification, StyledIcon } from '../styled';
13-
import { validationIcons, validationHues } from '../utils/icons';
13+
import { validationIcons } from '../utils/icons';
1414
import { Title } from './content/Title';
1515
import { Paragraph } from './content/Paragraph';
1616
import { Close } from './content/Close';
1717

1818
export const NotificationComponent = forwardRef<HTMLDivElement, INotificationProps>(
1919
({ children, type, ...props }, ref) => {
2020
const Icon = type ? validationIcons[type] : InfoStrokeIcon;
21-
const hue = type && validationHues[type];
2221

2322
return (
24-
<StyledNotification ref={ref} type={type} isFloating role="alert" {...props}>
23+
<StyledNotification ref={ref} $type={type} $isFloating role="alert" {...props}>
2524
{type && (
26-
<StyledIcon $hue={hue}>
25+
<StyledIcon $type={type}>
2726
<Icon />
2827
</StyledIcon>
2928
)}
30-
3129
{children}
3230
</StyledNotification>
3331
);

packages/notifications/src/elements/Well.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,11 @@ import { StyledWell } from '../styled';
1212
import { Title } from './content/Title';
1313
import { Paragraph } from './content/Paragraph';
1414

15-
export const WellComponent = React.forwardRef<HTMLDivElement, IWellProps>((props, ref) => (
16-
<StyledWell ref={ref} {...props} />
17-
));
15+
export const WellComponent = React.forwardRef<HTMLDivElement, IWellProps>(
16+
({ isFloating, isRecessed, ...props }, ref) => (
17+
<StyledWell ref={ref} $isFloating={isFloating} $isRecessed={isRecessed} {...props} />
18+
)
19+
);
1820

1921
WellComponent.displayName = 'Well';
2022

packages/notifications/src/elements/content/Close.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import React, { ButtonHTMLAttributes } from 'react';
99
import { StyledClose } from '../../styled';
1010
import { useNotificationsContext } from '../../utils/useNotificationsContext';
1111
import { useText } from '@zendeskgarden/react-theming';
12-
import XStrokeIcon from '@zendeskgarden/svg-icons/src/12/x-stroke.svg';
12+
import XStrokeIcon from '@zendeskgarden/svg-icons/src/16/x-stroke.svg';
1313

1414
/**
1515
* @deprecated use `Alert.Close` or `Notification.Close` instead
@@ -19,10 +19,10 @@ import XStrokeIcon from '@zendeskgarden/svg-icons/src/12/x-stroke.svg';
1919
export const Close = React.forwardRef<HTMLButtonElement, ButtonHTMLAttributes<HTMLButtonElement>>(
2020
(props, ref) => {
2121
const ariaLabel = useText(Close, props, 'aria-label', 'Close');
22-
const hue = useNotificationsContext();
22+
const type = useNotificationsContext();
2323

2424
return (
25-
<StyledClose ref={ref} hue={hue} aria-label={ariaLabel} {...props}>
25+
<StyledClose ref={ref} $type={type} aria-label={ariaLabel} {...props} focusInset size="small">
2626
<XStrokeIcon />
2727
</StyledClose>
2828
);

packages/notifications/src/elements/content/Title.spec.tsx

Lines changed: 16 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,12 @@
77

88
import React from 'react';
99
import { css } from 'styled-components';
10-
import { render } from 'garden-test-utils';
11-
import { DEFAULT_THEME, PALETTE_V8 } from '@zendeskgarden/react-theming';
10+
import { getRenderFn, render } from 'garden-test-utils';
11+
import { DEFAULT_THEME, PALETTE } from '@zendeskgarden/react-theming';
1212
import { Notification } from '../Notification';
1313
import { Title } from './Title';
1414
import { StyledTitle } from '../../styled';
15+
import { Type } from '../../types';
1516

1617
describe('Title', () => {
1718
it('passes ref to underlying DOM element', () => {
@@ -53,56 +54,23 @@ describe('Title', () => {
5354
);
5455
});
5556

56-
it('renders success styling', () => {
57-
const { container } = render(
58-
<Notification type="success">
57+
it.each<{ mode: 'light' | 'dark'; type: Type; color: string }>([
58+
{ mode: 'light', type: 'success', color: PALETTE.green[700] },
59+
{ mode: 'dark', type: 'success', color: PALETTE.green[400] },
60+
{ mode: 'light', type: 'error', color: PALETTE.red[700] },
61+
{ mode: 'dark', type: 'error', color: PALETTE.red[400] },
62+
{ mode: 'light', type: 'warning', color: PALETTE.yellow[700] },
63+
{ mode: 'dark', type: 'warning', color: PALETTE.yellow[400] },
64+
{ mode: 'light', type: 'info', color: PALETTE.grey[900] },
65+
{ mode: 'dark', type: 'info', color: PALETTE.grey[300] }
66+
])('renders $mode mode $type color', ({ mode, type, color }) => {
67+
const { container } = getRenderFn(mode)(
68+
<Notification type={type}>
5969
<Title>title</Title>
6070
</Notification>
6171
);
6272

63-
expect(container.firstChild).toHaveStyleRule('color', PALETTE_V8.green[600], {
64-
modifier: css`
65-
${StyledTitle}
66-
` as any
67-
});
68-
});
69-
70-
it('renders error styling', () => {
71-
const { container } = render(
72-
<Notification type="error">
73-
<Title>title</Title>
74-
</Notification>
75-
);
76-
77-
expect(container.firstChild).toHaveStyleRule('color', PALETTE_V8.red[600], {
78-
modifier: css`
79-
${StyledTitle}
80-
` as any
81-
});
82-
});
83-
84-
it('renders warning styling', () => {
85-
const { container } = render(
86-
<Notification type="warning">
87-
<Title>title</Title>
88-
</Notification>
89-
);
90-
91-
expect(container.firstChild).toHaveStyleRule('color', PALETTE_V8.yellow[700], {
92-
modifier: css`
93-
${StyledTitle}
94-
` as any
95-
});
96-
});
97-
98-
it('renders info styling', () => {
99-
const { container } = render(
100-
<Notification type="info">
101-
<Title>title</Title>
102-
</Notification>
103-
);
104-
105-
expect(container.firstChild).toHaveStyleRule('color', PALETTE_V8.grey[800], {
73+
expect(container.firstChild).toHaveStyleRule('color', color, {
10674
modifier: css`
10775
${StyledTitle}
10876
` as any

packages/notifications/src/elements/content/Title.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ import { StyledTitle } from '../../styled';
1414
*
1515
* @extends HTMLAttributes<HTMLDivElement>
1616
*/
17-
export const Title = React.forwardRef<HTMLDivElement, ITitleProps>((props, ref) => (
18-
<StyledTitle ref={ref} {...props} />
19-
));
17+
export const Title = React.forwardRef<HTMLDivElement, ITitleProps>(
18+
({ isRegular, ...props }, ref) => <StyledTitle ref={ref} $isRegular={isRegular} {...props} />
19+
);
2020

2121
Title.displayName = 'Title';

packages/notifications/src/elements/global-alert/GlobalAlert.tsx

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,23 @@
77

88
import React, { forwardRef, useMemo } from 'react';
99
import PropTypes from 'prop-types';
10+
import { ThemeProvider } from 'styled-components';
1011
import InfoIcon from '@zendeskgarden/svg-icons/src/16/info-stroke.svg';
1112
import ErrorIcon from '@zendeskgarden/svg-icons/src/16/alert-error-stroke.svg';
1213
import WarningIcon from '@zendeskgarden/svg-icons/src/16/alert-warning-stroke.svg';
1314
import SuccessIcon from '@zendeskgarden/svg-icons/src/16/check-circle-stroke.svg';
1415

1516
import { TYPE, IGlobalAlertProps } from '../../types';
1617
import { StyledGlobalAlert, StyledGlobalAlertIcon } from '../../styled';
17-
import { GlobalAlertContext } from './utility';
18+
import { GlobalAlertContext } from '../../utils/useGlobalAlertContext';
1819
import { GlobalAlertButton } from './GlobalAlertButton';
1920
import { GlobalAlertClose } from './GlobalAlertClose';
2021
import { GlobalAlertContent } from './GlobalAlertContent';
2122
import { GlobalAlertTitle } from './GlobalAlertTitle';
2223

2324
/**
24-
* 1. role='status' on `div` is valid WAI-ARIA usage in this context.
25+
* 1. Global Alert always renders with light theme colors
26+
* 2. role='status' on `div` is valid WAI-ARIA usage in this context.
2527
* https://www.w3.org/TR/wai-aria-1.1/#status
2628
*/
2729

@@ -35,14 +37,17 @@ const GlobalAlertComponent = forwardRef<HTMLDivElement, IGlobalAlertProps>(
3537
}[type];
3638

3739
return (
38-
<GlobalAlertContext.Provider value={useMemo(() => ({ type }), [type])}>
39-
{/* [1] */}
40-
{/* eslint-disable-next-line jsx-a11y/prefer-tag-over-role */}
41-
<StyledGlobalAlert ref={ref} role="status" alertType={type} {...props}>
42-
<StyledGlobalAlertIcon>{icon}</StyledGlobalAlertIcon>
43-
{props.children}
44-
</StyledGlobalAlert>
45-
</GlobalAlertContext.Provider>
40+
/* [1] */
41+
<ThemeProvider theme={theme => ({ ...theme, colors: { ...theme.colors, base: 'light' } })}>
42+
<GlobalAlertContext.Provider value={useMemo(() => ({ type }), [type])}>
43+
{/* [2] */}
44+
{/* eslint-disable-next-line jsx-a11y/prefer-tag-over-role */}
45+
<StyledGlobalAlert ref={ref} role="status" $alertType={type} {...props}>
46+
<StyledGlobalAlertIcon $alertType={type}>{icon}</StyledGlobalAlertIcon>
47+
{props.children}
48+
</StyledGlobalAlert>
49+
</GlobalAlertContext.Provider>
50+
</ThemeProvider>
4651
);
4752
}
4853
);

packages/notifications/src/elements/global-alert/GlobalAlertButton.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,9 @@
77

88
import React, { forwardRef } from 'react';
99
import PropTypes from 'prop-types';
10-
1110
import { IGlobalAlertButtonProps } from '../../types';
1211
import { StyledGlobalAlertButton } from '../../styled';
13-
import { useGlobalAlertContext } from './utility';
12+
import { useGlobalAlertContext } from '../../utils/useGlobalAlertContext';
1413

1514
/**
1615
* @extends ButtonHTMLAttributes<HTMLButtonElement>
@@ -22,8 +21,9 @@ export const GlobalAlertButton = forwardRef<HTMLButtonElement, IGlobalAlertButto
2221
return (
2322
<StyledGlobalAlertButton
2423
ref={ref}
25-
alertType={type}
24+
$alertType={type}
2625
{...props}
26+
size="small"
2727
isPrimary={!isBasic}
2828
isBasic={isBasic}
2929
/>

packages/notifications/src/elements/global-alert/GlobalAlertClose.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { useText } from '@zendeskgarden/react-theming';
1010
import XStrokeIcon from '@zendeskgarden/svg-icons/src/16/x-stroke.svg';
1111

1212
import { StyledGlobalAlertClose } from '../../styled';
13-
import { useGlobalAlertContext } from './utility';
13+
import { useGlobalAlertContext } from '../../utils/useGlobalAlertContext';
1414

1515
/**
1616
* 1. role='img' on `svg` is valid WAI-ARIA usage in this context.
@@ -28,7 +28,7 @@ export const GlobalAlertClose = forwardRef<
2828
const label = useText(GlobalAlertClose, props, 'aria-label', 'Close');
2929

3030
return (
31-
<StyledGlobalAlertClose ref={ref} alertType={type} {...props}>
31+
<StyledGlobalAlertClose ref={ref} $alertType={type} {...props} size="small">
3232
{/* [1] */}
3333
{/* eslint-disable-next-line jsx-a11y/prefer-tag-over-role */}
3434
<XStrokeIcon role="img" aria-label={label} />

packages/notifications/src/elements/global-alert/GlobalAlertTitle.tsx

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,18 @@ import PropTypes from 'prop-types';
1010

1111
import { IGlobalAlertTitleProps } from '../../types';
1212
import { StyledGlobalAlertTitle } from '../../styled';
13-
import { useGlobalAlertContext } from './utility';
13+
import { useGlobalAlertContext } from '../../utils/useGlobalAlertContext';
1414

1515
/**
1616
* @extends HTMLAttributes<HTMLDivElement>
1717
*/
18-
export const GlobalAlertTitle = forwardRef<HTMLDivElement, IGlobalAlertTitleProps>((props, ref) => {
19-
const { type } = useGlobalAlertContext();
18+
export const GlobalAlertTitle = forwardRef<HTMLDivElement, IGlobalAlertTitleProps>(
19+
({ isRegular, ...props }, ref) => {
20+
const { type } = useGlobalAlertContext();
2021

21-
return <StyledGlobalAlertTitle alertType={type} ref={ref} {...props} />;
22-
});
22+
return <StyledGlobalAlertTitle $alertType={type} $isRegular={isRegular} ref={ref} {...props} />;
23+
}
24+
);
2325

2426
GlobalAlertTitle.displayName = 'GlobalAlert.Title';
2527

0 commit comments

Comments
 (0)