Skip to content

Commit

Permalink
feat: rich colors support
Browse files Browse the repository at this point in the history
  • Loading branch information
gunnartorfis committed Sep 14, 2024
1 parent 2560331 commit 4a3d3e3
Show file tree
Hide file tree
Showing 10 changed files with 152 additions and 55 deletions.
31 changes: 16 additions & 15 deletions docs/docs/Toaster.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,19 +73,20 @@ import { ZView } from 'react-native-z-view';

## API Reference

| Property | Description | Default |
| :----------------------- | :------------------------------------------------------------------------------------------------: | --------------------------: |
| theme | `light`, `dark` | `light` |
| visibleToasts | Maximum number of visible toasts | `3` |
| position | Place where the toasts will be rendered | `top-center` |
| offset | Offset from the top or bottom | `0` |
| closeButton | Adds a close button to all toasts | `false` |
| invert | Dark toasts in light mode and vice versa. | `false` |
| toastOptions | These will act as default options for all toasts. See [toast()](/toast) for all available options. | `{}` |
| gap | Gap between toasts when expanded | `16` |
| icons | Changes the default icons | `-` |
| pauseWhenPageIsHidden | Pauses toast timers when the app enters background. | `{}` |
| Property | Description | Default |
| :------------------------ | :------------------------------------------------------------------------------------------------: | --------------------------: |
| theme | `light`, `dark` | `light` |
| visibleToasts | Maximum number of visible toasts | `3` |
| position | Place where the toasts will be rendered | `top-center` |
| offset | Offset from the top or bottom | `0` |
| closeButton | Adds a close button to all toasts | `false` |
| invert | Dark toasts in light mode and vice versa. | `false` |
| toastOptions | These will act as default options for all toasts. See [toast()](/toast) for all available options. | `{}` |
| gap | Gap between toasts when expanded | `16` |
| icons | Changes the default icons | `-` |
| pauseWhenPageIsHidden | Pauses toast timers when the app enters background. | `{}` |
| `swipeToDismissDirection` | Swipe direction to dismiss (`left`, `up`). | `up` |
| cn | Custom function for constructing/merging classes. | `filter(Boolean).join(' ')` |
|  ToasterOverlayWrapper |  Custom component to wrap the Toaster. | `div` |
|  autoWiggleOnUpdate | Adds a wiggle animation on toast update. `never`, `toast-change`, `always` | `never` |
| cn | Custom function for constructing/merging classes. | `filter(Boolean).join(' ')` |
| ToasterOverlayWrapper |  Custom component to wrap the Toaster. | `div` |
| autoWiggleOnUpdate | Adds a wiggle animation on toast update. `never`, `toast-change`, `always` | `never` |
| richColors |  Makes error and success state more colorful | `false` |
36 changes: 18 additions & 18 deletions docs/docs/sonner.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,24 +29,24 @@

## Toaster:

| Property | Sonner Native | Sonner Web |
| :----------------------- | ------------- | ---------- |
| theme |||
| visibleToasts |||
| position |||
| closeButton |||
| invert |||
| toastOptions |||
| gap |||
| icons |||
| Property | Sonner Native | Sonner Web |
| :------------------------ | ------------- | ---------- |
| theme |||
| visibleToasts |||
| position |||
| closeButton |||
| invert |||
| toastOptions |||
| gap |||
| icons |||
| `swipeToDismissDirection` |||
| dir |||
| richColors | ||
| expand | 🕸️ ||
| offset |||
| hotkey | 🕸️ ||
| loadingIcon |||
| pauseWhenPageIsHidden |||
| cn |||
| dir |||
| richColors | ||
| expand | 🕸️ ||
| offset |||
| hotkey | 🕸️ ||
| loadingIcon |||
| pauseWhenPageIsHidden |||
| cn |||

**🕸️: Not applicable for native apps.**
1 change: 1 addition & 0 deletions docs/docs/toast.md
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ Toasts can also be automatically wiggled by passing the `autoWiggleOnUpdate` pro
| actionButtonTextStyles | Styles for the action button text | `{}` |
| cancelButtonStyles | Styles for the cancel button | `{}` |
| cancelButtonTextStyles | Styles for the cancel button text | `{}` |
| richColors |  Makes error and success state more colorful | `false` |

```
Expand Down
9 changes: 9 additions & 0 deletions example/src/ToastDemo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,15 @@ export const ToastDemo: React.FC = () => {
});
}}
/>
<Button
title="Rich colors"
onPress={() => {
toast.warning('Rich colors', {
description: 'Your changes have been saved successfully',
richColors: true,
});
}}
/>
<Button
title="Show toast with description and action"
onPress={() => {
Expand Down
2 changes: 2 additions & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export const toastDefaultValues: {
gap: number;
theme: ToastTheme;
autoWiggleOnUpdate: AutoWiggle;
richColors: boolean;
} = {
duration: 4000,
position: 'top-center',
Expand All @@ -38,4 +39,5 @@ export const toastDefaultValues: {
gap: 14,
theme: 'system',
autoWiggleOnUpdate: 'never',
richColors: false,
};
46 changes: 29 additions & 17 deletions src/toast.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import { ToastSwipeHandler } from './gestures';
import { CircleCheck, CircleX, Info, TriangleAlert, X } from './icons';
import { isToastAction, type ToastProps, type ToastRef } from './types';
import { useAppStateListener } from './use-app-state';
import { useColors } from './use-colors';
import { useDefaultStyles } from './use-default-styles';

export const Toast = React.forwardRef<ToastRef, ToastProps>(
Expand Down Expand Up @@ -49,7 +48,7 @@ export const Toast = React.forwardRef<ToastRef, ToastProps>(
unstyled: unstyledProps,
important,
invert: invertProps,
// richColors: richColorsProps,
richColors: richColorsProps,
},
ref
) => {
Expand All @@ -61,7 +60,7 @@ export const Toast = React.forwardRef<ToastRef, ToastProps>(
pauseWhenPageIsHidden,
cn,
invert: invertCtx,
// richColors: richColorsCtx,
richColors: richColorsCtx,
toastOptions: {
unstyled: unstyledCtx,
toastContainerStyle: toastContainerStyleCtx,
Expand All @@ -80,12 +79,11 @@ export const Toast = React.forwardRef<ToastRef, ToastProps>(
},
} = useToastContext();
const invert = invertProps ?? invertCtx;
// const richColors = richColorsProps ?? richColorsCtx;
const richColors = richColorsProps ?? richColorsCtx;
const unstyled = unstyledProps ?? unstyledCtx;
const duration = durationProps ?? durationCtx;
const closeButton = closeButtonProps ?? closeButtonCtx;

const colors = useColors(invert);
const { entering, exiting } = useToastLayoutAnimations(position);

const isDragging = React.useRef(false);
Expand Down Expand Up @@ -256,9 +254,10 @@ export const Toast = React.forwardRef<ToastRef, ToastProps>(

const defaultStyles = useDefaultStyles({
invert,
// richColors,
richColors,
unstyled,
description,
variant,
});

if (jsx) {
Expand Down Expand Up @@ -329,7 +328,11 @@ export const Toast = React.forwardRef<ToastRef, ToastProps>(
) : variant in icons ? (
icons[variant]
) : (
<ToastIcon variant={variant} invert={invert} />
<ToastIcon
variant={variant}
invert={invert}
richColors={richColors}
/>
)}
<View style={{ flex: 1 }}>
<Text
Expand Down Expand Up @@ -430,7 +433,7 @@ export const Toast = React.forwardRef<ToastRef, ToastProps>(
>
<X
size={20}
color={colors['text-secondary']}
color={defaultStyles.closeButtonColor}
style={[closeButtonIconStyleCtx, styles?.closeButtonIcon]}
className={cn(
classNamesCtx?.closeButtonIcon,
Expand All @@ -448,21 +451,30 @@ export const Toast = React.forwardRef<ToastRef, ToastProps>(

Toast.displayName = 'Toast';

export const ToastIcon: React.FC<Pick<ToastProps, 'variant' | 'invert'>> = ({
variant,
invert,
}) => {
const colors = useColors(invert);
export const ToastIcon: React.FC<
Pick<ToastProps, 'variant'> & {
invert: boolean;
richColors: boolean;
}
> = ({ variant, invert, richColors }) => {
const color = useDefaultStyles({
variant,
invert,
richColors,
unstyled: false,
description: undefined,
}).iconColor;

switch (variant) {
case 'success':
return <CircleCheck size={20} color={colors.success} />;
return <CircleCheck size={20} color={color} />;
case 'error':
return <CircleX size={20} color={colors.error} />;
return <CircleX size={20} color={color} />;
case 'warning':
return <TriangleAlert size={20} color={colors.warning} />;
return <TriangleAlert size={20} color={color} />;
default:
case 'info':
return <Info size={20} color={colors.info} />;
return <Info size={20} color={color} />;
}
};

Expand Down
3 changes: 3 additions & 0 deletions src/toaster.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ export const ToasterUI: React.FC<ToasterProps> = ({
gap,
theme,
autoWiggleOnUpdate,
richColors,
...props
}) => {
const [toasts, setToasts] = React.useState<ToastProps[]>([]);
Expand Down Expand Up @@ -198,6 +199,7 @@ export const ToasterUI: React.FC<ToasterProps> = ({
toastOptions,
autoWiggleOnUpdate:
autoWiggleOnUpdate ?? toastDefaultValues.autoWiggleOnUpdate,
richColors: richColors ?? toastDefaultValues.richColors,
}),
[
duration,
Expand All @@ -214,6 +216,7 @@ export const ToasterUI: React.FC<ToasterProps> = ({
theme,
toastOptions,
autoWiggleOnUpdate,
richColors,
]
);

Expand Down
3 changes: 3 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ export type ToastProps = StyleProps & {
icon?: React.ReactNode;
action?: ToastAction | React.ReactNode;
cancel?: ToastAction | React.ReactNode;
richColors?: boolean;
onDismiss?: (id: string | number) => void;
onAutoClose?: (id: string | number) => void;
promiseOptions?: PromiseOptions;
Expand Down Expand Up @@ -128,6 +129,7 @@ export type ToasterProps = {
};
gap?: number;
loadingIcon?: React.ReactNode;
richColors?: boolean;
// pauseWhenPageIsHidden?: boolean; (false)
icons?: {
success?: React.ReactNode;
Expand Down Expand Up @@ -162,6 +164,7 @@ export type ToasterContextType = Required<
| 'theme'
| 'toastOptions'
| 'autoWiggleOnUpdate'
| 'richColors'
>
> & {
addToast: AddToastContextHandler;
Expand Down
46 changes: 46 additions & 0 deletions src/use-colors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,29 @@ const light = {
'error': '#ff3a41',
'warning': '#e37a00',
'info': '#286efa',

'rich': {
success: {
background: '#ecfdf3',
foreground: '#008a2e',
border: '#d3fde5',
},
error: {
background: '#fff0f0',
foreground: '#e60000',
border: '#ffe0e1',
},
warning: {
background: '#fffcf0',
foreground: '#dc7609',
border: '#fdf5d3',
},
info: {
background: '#f0f8ff',
foreground: '#0973dc',
border: '#d3e0fd',
},
},
};

const dark: typeof light = {
Expand All @@ -25,6 +48,29 @@ const dark: typeof light = {
'error': '#FF999D',
'warning': '#ffd089',
'info': '#B3CDFF',

'rich': {
success: {
background: '#001f0f',
foreground: '#59f3a6',
border: '#003d1c',
},
error: {
background: '#2d0607',
foreground: '#ff9ea1',
border: '#4d0408',
},
warning: {
background: '#1d1f00',
foreground: '#f3cf58',
border: '#3d3d00',
},
info: {
background: '#000d1f',
foreground: '#5896f3',
border: '#00113d',
},
},
};

export const useColors = (invertProps?: boolean) => {
Expand Down
Loading

0 comments on commit 4a3d3e3

Please sign in to comment.