Skip to content

Commit

Permalink
Various fixes in Notifications (#161)
Browse files Browse the repository at this point in the history
* fix: preset in Description component
* fix: minor layout fixes
* fix: missing onDismiss, add null to duration in toast, remove the duplicate module
* fix: review issues
  • Loading branch information
MrFlashAccount authored Jul 28, 2022
1 parent f0ac89a commit f5976df
Show file tree
Hide file tree
Showing 13 changed files with 75 additions and 67 deletions.
5 changes: 5 additions & 0 deletions .changeset/dull-parents-exercise.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@cube-dev/ui-kit": patch
---

Fixed description preset in notificaiton
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export const FloatingNotification = memo(function FloatingNotification(
const chainedOnDismiss = useChainedCallback(
() => onDismissNotification(id),
() => onRemoveNotification(id),
notificationProps.onDismiss,
);

const onKeyDown = useEvent<KeyboardEventHandler<HTMLElement>>(({ key }) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ const CloseButton = tasty(Button, {
top: '-0.75x',
display: 'flex',
placeItems: 'center',
padding: '0.75x',
width: '3.5x',
height: '3.5x',
padding: '0.625x',
width: '3x',
height: '3x',
fill: '#white',
shadow: '0 0.5x 2x #shadow',
color: { '': '#dark-02', hovered: '#dark-03', pressed: '#dark-02' },
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { HTMLAttributes, memo, ReactNode } from 'react';
import { HTMLAttributes, memo } from 'react';
import { tasty } from '../../../../tasty';
import { Paragraph } from '../../../content/Paragraph';
import { NotificationProps } from './types';
Expand All @@ -23,5 +23,9 @@ export const NotificationDescription = memo(function NotificationDescription(
) {
const { description, ...descriptionProps } = props;

return <Description {...descriptionProps}>{description}</Description>;
return (
<Description preset="t4m" {...descriptionProps}>
{description}
</Description>
);
});
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,21 @@ export type NotificationHeaderProps = {
header: NotificationProps['header'];
} & HTMLAttributes<HTMLElement>;

const Header = tasty(Title, { gridArea: 'header', margin: '0.25x 0 0.5x' });
const Header = tasty(Title, {
as: 'div',
preset: 'h6',
styles: {
gridArea: 'header',
'&:not(:empty)': {
margin: '0.25x 0 0.5x',
},
},
});

export const NotificationHeader = memo(function NotificationHeader(
props: NotificationHeaderProps,
): JSX.Element {
const { header, ...headerProps } = props;

return (
<Header as="div" preset="h6" {...headerProps}>
{header}
</Header>
);
return <Header {...headerProps}>{header}</Header>;
});
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,6 @@ const NotificationContainer = tasty({
'': '0 0 0 4bw #purple-04.0 inset',
focused: '0 0 0 4bw #purple-04 inset',
},
'&::before': {
zIndex: 0,
content: '""',
position: 'absolute',
top: '-8px',
left: '0',
right: '-8px',
bottom: '0',
display: { '': 'none', 'is-dismissible': 'flex' },
},
},
});

Expand Down Expand Up @@ -105,7 +95,7 @@ export const NotificationView = forwardRef(function NotificationView(
>
<NotificationIcon icon={icon} type={type} />

{header && <NotificationHeader header={header} id={labelID} />}
<NotificationHeader header={header} id={labelID} />

{description && (
<NotificationDescription
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export function useNotifications(
newToasts.set(id, {
id,
isDismissible,
duration: isDismissible ? 5_000 : null,
duration: duration ?? isDismissible ? 5_000 : null,
...rest,
} as CubeNotifyApiPropsWithID);

Expand Down
19 changes: 1 addition & 18 deletions src/components/overlays/NewNotifications/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,24 +70,7 @@ export type BaseNotificationProps = {
| NotificationActionType;
};

export type CubeNotificationProps = BaseNotificationProps &
EitherDismissibleOrNotNotification;

export type EitherDismissibleOrNotNotification =
| DismissibleNotification
| NonDismissibleNotification;

type DismissibleNotification = {
isDismissible?: true;
onDismiss?: () => void;
duration?: number;
};

type NonDismissibleNotification = {
isDismissible: false;
onDismiss?: never | undefined;
duration?: null;
};
export type CubeNotificationProps = BaseNotificationProps;

export type CubeNotifyApiProps = {
meta?: CubeNotificationMeta;
Expand Down
3 changes: 2 additions & 1 deletion src/components/overlays/Toasts/Toast.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { useEffect } from 'react';
import { useId } from '@react-aria/utils';
import { useToastsApi } from './use-toasts-api';
import { CubeToastsApiProps } from './types';
import { CubeNotifyApiProps } from '../NewNotifications';

export function Toast(props: CubeToastsApiProps) {
const { id: propsId } = props;
Expand All @@ -17,7 +18,7 @@ export function Toast(props: CubeToastsApiProps) {
}, [id]);

useEffect(() => {
update(id, props);
update(id, props as CubeNotifyApiProps);
});

return null;
Expand Down
30 changes: 30 additions & 0 deletions src/components/overlays/Toasts/toast.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { Toast } from './Toast';
import { renderWithRoot, screen } from '../../../test';

describe('useToastsApi', () => {
beforeAll(() => jest.useFakeTimers('modern'));
afterAll(() => jest.useRealTimers());

it('should add and dismiss toast on timeout', async () => {
const dismiss = jest.fn();
renderWithRoot(<Toast description="Test" onDismiss={dismiss} />);

jest.runAllTimers();

expect(
screen.queryByTestId('floating-notification'),
).not.toBeInTheDocument();
expect(dismiss).toBeCalledTimes(1);
});

it('should not unmount if duration is null', async () => {
const dismiss = jest.fn();
renderWithRoot(
<Toast description="Test" duration={null} onDismiss={dismiss} />,
);

jest.runAllTimers();
expect(screen.getByTestId('floating-notification')).toBeInTheDocument();
expect(dismiss).not.toBeCalled();
});
});
2 changes: 1 addition & 1 deletion src/components/overlays/Toasts/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export type CubeToastsApiProps = {
header?: ReactChild | ReactFragment;
id?: Key;
onDismiss?: () => void;
duration?: number;
duration?: number | null;
icon?: ReactNode;
type?: CubeNotificationType;
};
Expand Down
23 changes: 13 additions & 10 deletions src/components/overlays/Toasts/use-toasts-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@ export function useToastsApi() {
Object.assign<CubeToastsApiToastCallback, CubeToastsApiToastShortcuts>(
(props) =>
notify({
isDismissible: true,
putNotificationInDropdownOnDismiss: false,
duration: 5_000,
...unwrapProps(props),
}),
{
Expand All @@ -32,19 +30,24 @@ export function useToastsApi() {

function unwrapProps(props: CubeToastsApiProps | ReactChild | ReactFragment) {
return {
...(propsIsDescription(props)
? { description: props }
: (props as CubeToastsApiProps)),
...(propsIsToastProps(props)
? {
isDismissible: props.duration !== null,
duration: 5_000,
...(props as CubeToastsApiProps),
}
: { description: props, isDismissible: true, duration: 5_000 }),
};
}

function propsIsDescription(
function propsIsToastProps(
props: CubeToastsApiProps | ReactChild | ReactFragment,
) {
return (
): props is CubeToastsApiProps {
const isReactNode =
isElement(props) ||
isFragment(props) ||
typeof props === 'string' ||
typeof props === 'number'
);
typeof props === 'number';

return !isReactNode;
}

0 comments on commit f5976df

Please sign in to comment.