From f7aab5a78a87d7be40024b15241b1f39f1a44a7a Mon Sep 17 00:00:00 2001 From: Maciek Date: Thu, 18 May 2023 13:53:36 +0200 Subject: [PATCH] feat(ui-toolkit,trading): allow toast box configuration (#3811) --- .../client-pages/settings/settings.tsx | 3 + .../ui-toolkit/src/components/toast/index.tsx | 1 + .../toast/toast-position-setter.tsx | 145 ++++++++++++++++++ .../src/components/toast/toasts-container.tsx | 18 ++- .../src/components/toast/use-toasts.ts | 27 ++++ 5 files changed, 191 insertions(+), 3 deletions(-) create mode 100644 libs/ui-toolkit/src/components/toast/toast-position-setter.tsx diff --git a/apps/trading/client-pages/settings/settings.tsx b/apps/trading/client-pages/settings/settings.tsx index 6a9dd38d0..c405301b8 100644 --- a/apps/trading/client-pages/settings/settings.tsx +++ b/apps/trading/client-pages/settings/settings.tsx @@ -5,6 +5,7 @@ import { RoundedWrapper, Switch, ThemeSwitcher, + ToastPositionSetter, } from '@vegaprotocol/ui-toolkit'; import { useThemeSwitcher } from '@vegaprotocol/react-helpers'; @@ -41,6 +42,8 @@ export const Settings = () => { 'Help identify bugs and improve the service by sharing anonymous usage data.' )} /> + + diff --git a/libs/ui-toolkit/src/components/toast/index.tsx b/libs/ui-toolkit/src/components/toast/index.tsx index 7b7c2c12a..1ccc9d48e 100644 --- a/libs/ui-toolkit/src/components/toast/index.tsx +++ b/libs/ui-toolkit/src/components/toast/index.tsx @@ -1,3 +1,4 @@ export * from './toast'; export * from './toasts-container'; export * from './use-toasts'; +export * from './toast-position-setter'; diff --git a/libs/ui-toolkit/src/components/toast/toast-position-setter.tsx b/libs/ui-toolkit/src/components/toast/toast-position-setter.tsx new file mode 100644 index 000000000..a4a06bf92 --- /dev/null +++ b/libs/ui-toolkit/src/components/toast/toast-position-setter.tsx @@ -0,0 +1,145 @@ +import classNames from 'classnames'; +import { t } from '@vegaprotocol/i18n'; +import { IconNames } from '@blueprintjs/icons'; +import { Icon } from '../icon'; +import { Button } from '../button'; +import { ToastPosition, useToastsConfiguration, useToasts } from './use-toasts'; +import { useCallback } from 'react'; +import { Intent } from '../../utils/intent'; + +const testToast = { + id: 'test-toast', + intent: Intent.Primary, + content: <>{t('This is an example of a toast notification')}, +}; + +export const ToastPositionSetter = () => { + const setPostion = useToastsConfiguration((store) => store.setPosition); + const position = useToastsConfiguration((store) => store.position); + const setToast = useToasts((store) => store.setToast); + const handleChange = useCallback( + (position: ToastPosition) => { + setPostion(position); + setToast(testToast); + }, + [setToast, setPostion] + ); + const iconCssClasses = 'absolute top-[4px] left-[4px]'; + const buttonCssClasses = + 'relative border-none bg-neutral-500/20 dark:bg-neutral-500/40'; + const activeButton = 'bg-neutral-800/80 dark:bg-neutral-200/40'; + const activeIcon = 'fill-white dark:fill-black'; + return ( +
+ {t('Toast location')} +
+ + + + + + +
+
+ ); +}; diff --git a/libs/ui-toolkit/src/components/toast/toasts-container.tsx b/libs/ui-toolkit/src/components/toast/toasts-container.tsx index a1675d6b3..bc4acd604 100644 --- a/libs/ui-toolkit/src/components/toast/toasts-container.tsx +++ b/libs/ui-toolkit/src/components/toast/toasts-container.tsx @@ -6,7 +6,7 @@ import { useLayoutEffect, useRef } from 'react'; import { Button } from '../button'; import { Toast } from './toast'; import type { Toasts } from './use-toasts'; -import { useToasts } from './use-toasts'; +import { ToastPosition, useToasts, useToastsConfiguration } from './use-toasts'; import { Portal } from '@radix-ui/react-portal'; @@ -21,7 +21,7 @@ export const ToastsContainer = ({ }: ToastsContainerProps) => { const ref = useRef(); const closeAll = useToasts((store) => store.closeAll); - + const position = useToastsConfiguration((store) => store.position); // Scroll to top for desc, bottom for asc when a toast is added. const count = usePrevious(Object.keys(toasts).length) || 0; useLayoutEffect(() => { @@ -46,7 +46,19 @@ export const ToastsContainer = ({ ref={ref as Ref} className={classNames( 'group', - 'absolute bottom-0 right-0 z-20 ', + 'absolute z-20', + { 'bottom-0 right-0': position === ToastPosition.BottomRight }, + { 'bottom-0 left-0': position === ToastPosition.BottomLeft }, + { 'top-0 left-0': position === ToastPosition.TopLeft }, + { 'top-0 right-0': position === ToastPosition.TopRight }, + { + 'top-0 left-[50%] translate-x-[-50%]': + position === ToastPosition.TopCenter, + }, + { + 'bottom-0 left-[50%] translate-x-[-50%]': + position === ToastPosition.BottomCenter, + }, 'p-[8px_16px_16px_16px]', 'max-w-full max-h-full overflow-x-hidden overflow-y-auto', { diff --git a/libs/ui-toolkit/src/components/toast/use-toasts.ts b/libs/ui-toolkit/src/components/toast/use-toasts.ts index 2295a6e4d..1f0652ac3 100644 --- a/libs/ui-toolkit/src/components/toast/use-toasts.ts +++ b/libs/ui-toolkit/src/components/toast/use-toasts.ts @@ -1,9 +1,12 @@ import { create } from 'zustand'; +import { persist } from 'zustand/middleware'; import { immer } from 'zustand/middleware/immer'; import type { Toast } from './toast'; import omit from 'lodash/omit'; import isEqual from 'lodash/isEqual'; +const STORAGE_KEY = 'vega_toast_store'; + export type Toasts = Record; const isUpdateable = (a: Toast, b: Toast) => @@ -96,3 +99,27 @@ export const useToasts = create()( removeAll: () => set({ toasts: {}, count: 0 }), })) ); + +export enum ToastPosition { + BottomRight, + BottomLeft, + TopLeft, + TopRight, + TopCenter, + BottomCenter, +} + +type ToastConfiguration = { + position: ToastPosition; + setPosition: (position: ToastPosition) => void; +}; + +export const useToastsConfiguration = create()( + persist( + immer((set) => ({ + position: ToastPosition.BottomRight, + setPosition: (position: ToastPosition) => set({ position }), + })), + { name: STORAGE_KEY } + ) +);