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 }
+ )
+);