feat: UI toast component (#160)
* chore: install radix toast * feat: add toast component * chore: display toast column * chore: remove commented lines * chore: fix animation
This commit is contained in:
parent
e28c7c6e96
commit
13a9a1e992
|
|
@ -21,6 +21,7 @@
|
||||||
"@headlessui/react": "^1.7.8",
|
"@headlessui/react": "^1.7.8",
|
||||||
"@radix-ui/colors": "^0.1.8",
|
"@radix-ui/colors": "^0.1.8",
|
||||||
"@radix-ui/react-avatar": "^1.0.1",
|
"@radix-ui/react-avatar": "^1.0.1",
|
||||||
|
"@radix-ui/react-toast": "^1.1.2",
|
||||||
"@react-icons/all-files": "^4.1.0",
|
"@react-icons/all-files": "^4.1.0",
|
||||||
"@reduxjs/toolkit": "^1.9.1",
|
"@reduxjs/toolkit": "^1.9.1",
|
||||||
"@stitches/react": "^1.2.8",
|
"@stitches/react": "^1.2.8",
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import { ComponentsTest, Home, Mint } from './views';
|
||||||
import { SVGTestScreen } from './views/svg-test'; // TODO: remove when done
|
import { SVGTestScreen } from './views/svg-test'; // TODO: remove when done
|
||||||
import { ConnectKitButton } from 'connectkit';
|
import { ConnectKitButton } from 'connectkit';
|
||||||
import { MintTest } from './views/mint-test';
|
import { MintTest } from './views/mint-test';
|
||||||
|
import { ToastProvider } from './components';
|
||||||
import { CreateAP } from './views/access-point';
|
import { CreateAP } from './views/access-point';
|
||||||
|
|
||||||
export const App = () => {
|
export const App = () => {
|
||||||
|
|
@ -14,6 +15,7 @@ export const App = () => {
|
||||||
{/* TODO remove after adding NavBar */}
|
{/* TODO remove after adding NavBar */}
|
||||||
<ConnectKitButton />
|
<ConnectKitButton />
|
||||||
</div>
|
</div>
|
||||||
|
<ToastProvider />
|
||||||
<HashRouter>
|
<HashRouter>
|
||||||
<Routes>
|
<Routes>
|
||||||
<Route path="/home" element={<Home />} />
|
<Route path="/home" element={<Home />} />
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ export interface IconButtonProps extends BaseButtonProps {
|
||||||
'aria-label': string;
|
'aria-label': string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const IconButton = forwardRef<IconButtonProps, 'button'>(
|
export const IconButton = forwardRef<HTMLButtonElement, IconButtonProps>(
|
||||||
function IconButton(props, ref) {
|
function IconButton(props, ref) {
|
||||||
const {
|
const {
|
||||||
icon,
|
icon,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
import { IconStyles as IS } from '../icon.styles';
|
||||||
|
|
||||||
|
export const ErrorIcon: React.FC<IS.CustomProps> = (props) => (
|
||||||
|
<IS.Custom
|
||||||
|
{...props}
|
||||||
|
viewBox="0 0 20 20"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M10 0.25C4.62391 0.25 0.25 4.62391 0.25 10C0.25 15.3761 4.62391 19.75 10 19.75C15.3761 19.75 19.75 15.3761 19.75 10C19.75 4.62391 15.3761 0.25 10 0.25ZM10 15.2458C9.81458 15.2458 9.63332 15.1908 9.47915 15.0878C9.32498 14.9848 9.20482 14.8384 9.13386 14.667C9.06291 14.4957 9.04434 14.3072 9.08051 14.1254C9.11669 13.9435 9.20598 13.7765 9.33709 13.6454C9.4682 13.5143 9.63525 13.425 9.8171 13.3888C9.99896 13.3526 10.1875 13.3712 10.3588 13.4421C10.5301 13.5131 10.6765 13.6333 10.7795 13.7874C10.8825 13.9416 10.9375 14.1229 10.9375 14.3083C10.9375 14.5569 10.8387 14.7954 10.6629 14.9712C10.4871 15.147 10.2486 15.2458 10 15.2458ZM11.0181 5.81687L10.7491 11.5356C10.7491 11.7345 10.67 11.9253 10.5294 12.066C10.3887 12.2066 10.198 12.2856 9.99906 12.2856C9.80015 12.2856 9.60938 12.2066 9.46873 12.066C9.32808 11.9253 9.24906 11.7345 9.24906 11.5356L8.98 5.81969V5.81734C8.9741 5.67997 8.99607 5.54282 9.04458 5.41415C9.09308 5.28549 9.16713 5.16797 9.26225 5.06868C9.35737 4.96938 9.47161 4.89037 9.59807 4.83639C9.72454 4.78241 9.86062 4.75458 9.99813 4.75458C10.1356 4.75458 10.2717 4.78241 10.3982 4.83639C10.5246 4.89037 10.6389 4.96938 10.734 5.06868C10.8291 5.16797 10.9032 5.28549 10.9517 5.41415C11.0002 5.54282 11.0221 5.67997 11.0162 5.81734L11.0181 5.81687Z"
|
||||||
|
fill="currentColor"
|
||||||
|
/>
|
||||||
|
</IS.Custom>
|
||||||
|
);
|
||||||
|
|
@ -8,18 +8,24 @@ import { IoCloudUploadSharp } from '@react-icons/all-files/io5/IoCloudUploadShar
|
||||||
import { MetamaskIcon, EthereumIcon } from './custom';
|
import { MetamaskIcon, EthereumIcon } from './custom';
|
||||||
import { IoCheckmarkCircleSharp } from '@react-icons/all-files/io5/IoCheckmarkCircleSharp';
|
import { IoCheckmarkCircleSharp } from '@react-icons/all-files/io5/IoCheckmarkCircleSharp';
|
||||||
import { AiOutlineTwitter } from '@react-icons/all-files/ai/AiOutlineTwitter';
|
import { AiOutlineTwitter } from '@react-icons/all-files/ai/AiOutlineTwitter';
|
||||||
|
import { ErrorIcon } from './custom/error';
|
||||||
|
import { IoClose } from '@react-icons/all-files/io5/IoClose';
|
||||||
|
import { AiFillCheckCircle } from '@react-icons/all-files/ai/AiFillCheckCircle';
|
||||||
|
|
||||||
export const IconLibrary = Object.freeze({
|
export const IconLibrary = Object.freeze({
|
||||||
back: IoArrowBackCircleSharp,
|
back: IoArrowBackCircleSharp,
|
||||||
check: AiOutlineCheck,
|
check: AiOutlineCheck,
|
||||||
'check-circle': IoCheckmarkCircleSharp,
|
'check-circle': IoCheckmarkCircleSharp,
|
||||||
'chevron-down': AiOutlineDown,
|
'chevron-down': AiOutlineDown,
|
||||||
|
close: IoClose,
|
||||||
|
error: ErrorIcon,
|
||||||
ethereum: EthereumIcon,
|
ethereum: EthereumIcon,
|
||||||
github: IoLogoGithub,
|
github: IoLogoGithub,
|
||||||
info: IoInformationCircleSharp,
|
info: IoInformationCircleSharp,
|
||||||
upload: IoCloudUploadSharp,
|
upload: IoCloudUploadSharp,
|
||||||
metamask: MetamaskIcon, //remove if not used
|
metamask: MetamaskIcon, //remove if not used
|
||||||
search: BiSearch,
|
search: BiSearch,
|
||||||
|
success: AiFillCheckCircle,
|
||||||
twitter: AiOutlineTwitter,
|
twitter: AiOutlineTwitter,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,3 +3,4 @@ export * from './layout';
|
||||||
export * from './form';
|
export * from './form';
|
||||||
export * from './card';
|
export * from './card';
|
||||||
export * from './spinner';
|
export * from './spinner';
|
||||||
|
export * from './toast';
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
export * from './toast';
|
||||||
|
|
@ -0,0 +1,101 @@
|
||||||
|
import { dripStitches } from '@/theme';
|
||||||
|
import * as ToastLib from '@radix-ui/react-toast';
|
||||||
|
import { Icon, IconButton } from '../core';
|
||||||
|
import { Flex } from '../layout';
|
||||||
|
|
||||||
|
const { styled, keyframes } = dripStitches;
|
||||||
|
|
||||||
|
export abstract class ToastStyles {
|
||||||
|
static readonly Provider = ToastLib.Provider;
|
||||||
|
|
||||||
|
static readonly DismissTimeout = 200;
|
||||||
|
|
||||||
|
static readonly ViewportPadding = '$md';
|
||||||
|
|
||||||
|
static readonly KeyFrames = {
|
||||||
|
hide: keyframes({
|
||||||
|
'0%': { opacity: 1 },
|
||||||
|
'100%': { opacity: 0 },
|
||||||
|
}),
|
||||||
|
show: keyframes({
|
||||||
|
'0%': { opacity: 0 },
|
||||||
|
'100%': { opacity: 1 },
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
|
||||||
|
static readonly Root = styled(ToastLib.Root, {
|
||||||
|
padding: '$4 $5',
|
||||||
|
borderRadius: '$lg',
|
||||||
|
borderWidth: '$default',
|
||||||
|
maxWidth: '$128',
|
||||||
|
|
||||||
|
variants: {
|
||||||
|
variant: {
|
||||||
|
error: {
|
||||||
|
backgroundColor: '$red3',
|
||||||
|
borderColor: '$red6',
|
||||||
|
color: '$red11',
|
||||||
|
},
|
||||||
|
success: {
|
||||||
|
backgroundColor: '$green3',
|
||||||
|
borderColor: '$green6',
|
||||||
|
color: '$green11',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
'@media (prefers-reduced-motion: no-preference)': {
|
||||||
|
'&[data-state="open"]': {
|
||||||
|
animation: `${this.KeyFrames.show} 750ms `,
|
||||||
|
},
|
||||||
|
'&[data-state="closed"]': {
|
||||||
|
animation: `${this.KeyFrames.hide} ${this.DismissTimeout}ms ease-in`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
static readonly Body = styled(ToastLib.Description, {
|
||||||
|
fontSize: '$md',
|
||||||
|
fontWeight: '$normal',
|
||||||
|
mr: '$5',
|
||||||
|
});
|
||||||
|
|
||||||
|
static readonly Close = styled(ToastLib.Close, {});
|
||||||
|
|
||||||
|
static readonly CloseButton = styled(IconButton, {
|
||||||
|
variants: {
|
||||||
|
colorScheme: {
|
||||||
|
error: {
|
||||||
|
color: '$red11 !important',
|
||||||
|
},
|
||||||
|
success: {
|
||||||
|
color: '$green11 !important',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
static readonly Viewport = styled(ToastLib.Viewport, {
|
||||||
|
padding: '$14',
|
||||||
|
|
||||||
|
position: 'fixed',
|
||||||
|
bottom: 0,
|
||||||
|
left: '50%',
|
||||||
|
transform: 'translate(-50%)',
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
gap: '$4',
|
||||||
|
});
|
||||||
|
|
||||||
|
static readonly Layout = styled(Flex, {
|
||||||
|
flexDirection: 'row',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
});
|
||||||
|
|
||||||
|
static readonly Icon = styled(Icon, {
|
||||||
|
fontSize: '$5',
|
||||||
|
marginRight: '$2h',
|
||||||
|
});
|
||||||
|
|
||||||
|
static readonly Content = styled(Flex, {});
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,73 @@
|
||||||
|
import {
|
||||||
|
toastsActions,
|
||||||
|
ToastsState,
|
||||||
|
useAppDispatch,
|
||||||
|
useToastsState,
|
||||||
|
} from '@/store';
|
||||||
|
import { useCallback, useState } from 'react';
|
||||||
|
import { Icon } from '../core';
|
||||||
|
import { ToastStyles } from './toast.styles';
|
||||||
|
|
||||||
|
type ToastProps = ToastsState.Toast;
|
||||||
|
|
||||||
|
const Toast: React.FC<ToastProps> = ({
|
||||||
|
id,
|
||||||
|
type,
|
||||||
|
message,
|
||||||
|
onDismiss,
|
||||||
|
duration = 3000,
|
||||||
|
}) => {
|
||||||
|
const dispatch = useAppDispatch();
|
||||||
|
const [open, setOpen] = useState(true);
|
||||||
|
|
||||||
|
const handleOpenChange = useCallback(
|
||||||
|
(value: boolean) => {
|
||||||
|
setOpen(value);
|
||||||
|
if (!value) {
|
||||||
|
if (onDismiss) onDismiss();
|
||||||
|
setTimeout(() => {
|
||||||
|
dispatch(toastsActions.dismiss(id));
|
||||||
|
}, ToastStyles.DismissTimeout);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[onDismiss, dispatch, id]
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ToastStyles.Root
|
||||||
|
open={open}
|
||||||
|
duration={duration}
|
||||||
|
variant={type}
|
||||||
|
onOpenChange={handleOpenChange}
|
||||||
|
>
|
||||||
|
<ToastStyles.Layout>
|
||||||
|
<ToastStyles.Content>
|
||||||
|
<ToastStyles.Icon name={type} />
|
||||||
|
<ToastStyles.Body>{message}</ToastStyles.Body>
|
||||||
|
</ToastStyles.Content>
|
||||||
|
<ToastStyles.Close asChild>
|
||||||
|
<ToastStyles.CloseButton
|
||||||
|
aria-label="close"
|
||||||
|
colorScheme={type}
|
||||||
|
variant="link"
|
||||||
|
icon={<Icon name="close" />}
|
||||||
|
onClick={onDismiss}
|
||||||
|
/>
|
||||||
|
</ToastStyles.Close>
|
||||||
|
</ToastStyles.Layout>
|
||||||
|
</ToastStyles.Root>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const ToastProvider: React.FC = () => {
|
||||||
|
const { toasts } = useToastsState();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ToastStyles.Provider duration={3000} swipeDirection="down">
|
||||||
|
{toasts.map((toast) => (
|
||||||
|
<Toast key={toast.id} {...toast} />
|
||||||
|
))}
|
||||||
|
<ToastStyles.Viewport />
|
||||||
|
</ToastStyles.Provider>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
@ -1,2 +1,3 @@
|
||||||
export * from './github';
|
|
||||||
export * from './ens';
|
export * from './ens';
|
||||||
|
export * from './github';
|
||||||
|
export * from './toasts';
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
export * from './toasts-slice';
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
|
||||||
|
|
||||||
|
import type { RootState } from '@/store';
|
||||||
|
import { useAppSelector } from '@/store/hooks';
|
||||||
|
|
||||||
|
export namespace ToastsState {
|
||||||
|
export type Toast = {
|
||||||
|
id: number;
|
||||||
|
type: 'success' | 'error';
|
||||||
|
message: string;
|
||||||
|
onDismiss?: () => void;
|
||||||
|
duration?: number;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ToastsState {
|
||||||
|
toasts: ToastsState.Toast[];
|
||||||
|
}
|
||||||
|
|
||||||
|
const initialState: ToastsState = {
|
||||||
|
toasts: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
export const toastsSlice = createSlice({
|
||||||
|
name: 'toasts',
|
||||||
|
initialState,
|
||||||
|
reducers: {
|
||||||
|
push: (state, action: PayloadAction<Omit<ToastsState.Toast, 'id'>>) => {
|
||||||
|
state.toasts = [...state.toasts, { ...action.payload, id: Date.now() }];
|
||||||
|
},
|
||||||
|
dismiss: (state, action: PayloadAction<number>) => {
|
||||||
|
state.toasts = state.toasts.filter(
|
||||||
|
(toast) => toast.id !== action.payload
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export const toastsActions = { ...toastsSlice.actions };
|
||||||
|
|
||||||
|
const selectToastsState = (state: RootState): ToastsState => state.toasts;
|
||||||
|
|
||||||
|
export const useToastsState = (): ToastsState =>
|
||||||
|
useAppSelector(selectToastsState);
|
||||||
|
|
||||||
|
export default toastsSlice.reducer;
|
||||||
|
|
@ -1,11 +1,13 @@
|
||||||
import { configureStore } from '@reduxjs/toolkit';
|
import { configureStore } from '@reduxjs/toolkit';
|
||||||
import githubReducer from './features/github/github-slice';
|
import githubReducer from './features/github/github-slice';
|
||||||
|
import toastsReducer from './features/toasts/toasts-slice';
|
||||||
import ensReducer from './features/ens/ens-slice';
|
import ensReducer from './features/ens/ens-slice';
|
||||||
|
|
||||||
export const store = configureStore({
|
export const store = configureStore({
|
||||||
reducer: {
|
reducer: {
|
||||||
github: githubReducer,
|
|
||||||
ens: ensReducer,
|
ens: ensReducer,
|
||||||
|
github: githubReducer,
|
||||||
|
toasts: toastsReducer,
|
||||||
},
|
},
|
||||||
middleware: (getDefaultMiddleware) =>
|
middleware: (getDefaultMiddleware) =>
|
||||||
getDefaultMiddleware({
|
getDefaultMiddleware({
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,3 @@
|
||||||
export * from './themes';
|
export * from './themes';
|
||||||
export * from './foundations';
|
export * from './foundations';
|
||||||
|
export * from './key-frames';
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
import { dripStitches } from './themes';
|
||||||
|
|
||||||
|
const { keyframes } = dripStitches;
|
||||||
|
|
||||||
|
export const KeyFrames = {
|
||||||
|
slideUpAndFade: keyframes({
|
||||||
|
'0%': { opacity: 0, transform: 'translateY(2px)' },
|
||||||
|
'100%': { opacity: 1, transform: 'translateY(0)' },
|
||||||
|
}),
|
||||||
|
slideRightAndFade: keyframes({
|
||||||
|
'0%': { opacity: 0, transform: 'translateX(-2px)' },
|
||||||
|
'100%': { opacity: 1, transform: 'translateX(0)' },
|
||||||
|
}),
|
||||||
|
slideDownAndFade: keyframes({
|
||||||
|
'0%': { opacity: 0, transform: 'translateY(-2px)' },
|
||||||
|
'100%': { opacity: 1, transform: 'translateY(0)' },
|
||||||
|
}),
|
||||||
|
slideLeftAndFade: keyframes({
|
||||||
|
'0%': { opacity: 0, transform: 'translateX(2px)' },
|
||||||
|
'100%': { opacity: 1, transform: 'translateX(0)' },
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
|
@ -2,3 +2,4 @@ export * from './format';
|
||||||
export * from './validation';
|
export * from './validation';
|
||||||
export * from './object';
|
export * from './object';
|
||||||
export * from './context';
|
export * from './context';
|
||||||
|
export * from './toast';
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
import { store, toastsActions, ToastsState } from '@/store';
|
||||||
|
|
||||||
|
type PushToast = (
|
||||||
|
type: ToastsState.Toast['type'],
|
||||||
|
message: ToastsState.Toast['message'],
|
||||||
|
extra?: Omit<ToastsState.Toast, 'id' | 'type' | 'message' | 'children'>
|
||||||
|
) => void;
|
||||||
|
|
||||||
|
export const pushToast: PushToast = (type, message, extra = {}) =>
|
||||||
|
store.dispatch(toastsActions.push({ type, message, ...extra }));
|
||||||
|
|
@ -0,0 +1,50 @@
|
||||||
|
import { Combobox, ComboboxItem, Flex } from '@/components';
|
||||||
|
import { useState } from 'react';
|
||||||
|
|
||||||
|
const itemsCombobox = [
|
||||||
|
{ label: 'Item 1', value: 'item-1' },
|
||||||
|
{ label: 'Item 2', value: 'item-2' },
|
||||||
|
{ label: 'Item 3', value: 'item-3' },
|
||||||
|
];
|
||||||
|
|
||||||
|
export const ComboboxTest = () => {
|
||||||
|
const [selectedValue, setSelectedValue] = useState({} as ComboboxItem);
|
||||||
|
const [selectedValueAutocomplete, setSelectedValueAutocomplete] = useState(
|
||||||
|
{} as ComboboxItem
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleComboboxChange = (item: ComboboxItem) => {
|
||||||
|
setSelectedValue(item);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleComboboxChangeAutocomplete = (item: ComboboxItem) => {
|
||||||
|
setSelectedValueAutocomplete(item);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Flex
|
||||||
|
css={{
|
||||||
|
flexDirection: 'column',
|
||||||
|
margin: '100px',
|
||||||
|
|
||||||
|
justifyContent: 'center',
|
||||||
|
gap: '10px',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<h1>Components Test</h1>
|
||||||
|
<Flex css={{ width: '400px', gap: '$2' }}>
|
||||||
|
<Combobox
|
||||||
|
items={itemsCombobox}
|
||||||
|
selectedValue={selectedValue}
|
||||||
|
onChange={handleComboboxChange}
|
||||||
|
/>
|
||||||
|
<Combobox
|
||||||
|
items={itemsCombobox}
|
||||||
|
selectedValue={selectedValueAutocomplete}
|
||||||
|
onChange={handleComboboxChangeAutocomplete}
|
||||||
|
withAutocomplete
|
||||||
|
/>
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
@ -1,50 +1,12 @@
|
||||||
import { Combobox, ComboboxItem, Flex } from '@/components';
|
import { Flex } from '@/components';
|
||||||
import { useState } from 'react';
|
import { ComboboxTest } from './combobox-test';
|
||||||
|
import { ToastTest } from './toast-test';
|
||||||
const itemsCombobox = [
|
|
||||||
{ label: 'Item 1', value: 'item-1' },
|
|
||||||
{ label: 'Item 2', value: 'item-2' },
|
|
||||||
{ label: 'Item 3', value: 'item-3' },
|
|
||||||
];
|
|
||||||
|
|
||||||
export const ComponentsTest = () => {
|
export const ComponentsTest = () => {
|
||||||
const [selectedValue, setSelectedValue] = useState({} as ComboboxItem);
|
|
||||||
const [selectedValueAutocomplete, setSelectedValueAutocomplete] = useState(
|
|
||||||
{} as ComboboxItem
|
|
||||||
);
|
|
||||||
|
|
||||||
const handleComboboxChange = (item: ComboboxItem) => {
|
|
||||||
setSelectedValue(item);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleComboboxChangeAutocomplete = (item: ComboboxItem) => {
|
|
||||||
setSelectedValueAutocomplete(item);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Flex
|
<Flex css={{ flexDirection: 'column' }}>
|
||||||
css={{
|
<ToastTest />
|
||||||
flexDirection: 'column',
|
<ComboboxTest />
|
||||||
margin: '100px',
|
|
||||||
|
|
||||||
justifyContent: 'center',
|
|
||||||
gap: '10px',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<h1>Components Test</h1>
|
|
||||||
<Flex css={{ width: '400px', gap: '$2' }}>
|
|
||||||
<Combobox
|
|
||||||
items={itemsCombobox}
|
|
||||||
selectedValue={selectedValue}
|
|
||||||
onChange={handleComboboxChange}
|
|
||||||
/>
|
|
||||||
<Combobox
|
|
||||||
items={itemsCombobox}
|
|
||||||
selectedValue={selectedValueAutocomplete}
|
|
||||||
onChange={handleComboboxChangeAutocomplete}
|
|
||||||
withAutocomplete
|
|
||||||
/>
|
|
||||||
</Flex>
|
|
||||||
</Flex>
|
</Flex>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
import { Button, Flex } from '@/components';
|
||||||
|
import { pushToast } from '@/utils';
|
||||||
|
|
||||||
|
export const ToastTest = () => {
|
||||||
|
return (
|
||||||
|
<Flex css={{ margin: '$22', gap: '$5' }}>
|
||||||
|
<h1>ToastTest</h1>
|
||||||
|
<Button
|
||||||
|
onClick={() => {
|
||||||
|
pushToast('error', 'Issue connecting Wallet, please try again.');
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Toggle Error Toast
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
onClick={() => {
|
||||||
|
pushToast('success', 'Message sent successfully!');
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Toggle Succes Toast
|
||||||
|
</Button>
|
||||||
|
</Flex>
|
||||||
|
);
|
||||||
|
};
|
||||||
98
ui/yarn.lock
98
ui/yarn.lock
|
|
@ -3710,6 +3710,13 @@
|
||||||
resolved "https://registry.yarnpkg.com/@radix-ui/colors/-/colors-0.1.8.tgz#b08c62536fc462a87632165fb28e9b18f9bd047e"
|
resolved "https://registry.yarnpkg.com/@radix-ui/colors/-/colors-0.1.8.tgz#b08c62536fc462a87632165fb28e9b18f9bd047e"
|
||||||
integrity sha512-jwRMXYwC0hUo0mv6wGpuw254Pd9p/R6Td5xsRpOmaWkUHlooNWqVcadgyzlRumMq3xfOTXwJReU0Jv+EIy4Jbw==
|
integrity sha512-jwRMXYwC0hUo0mv6wGpuw254Pd9p/R6Td5xsRpOmaWkUHlooNWqVcadgyzlRumMq3xfOTXwJReU0Jv+EIy4Jbw==
|
||||||
|
|
||||||
|
"@radix-ui/primitive@1.0.0":
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@radix-ui/primitive/-/primitive-1.0.0.tgz#e1d8ef30b10ea10e69c76e896f608d9276352253"
|
||||||
|
integrity sha512-3e7rn8FDMin4CgeL7Z/49smCA3rFYY3Ha2rUQ7HRWFadS5iCRw08ZgVT1LaNTCNqgvrUiyczLflrVrF0SRQtNA==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.13.10"
|
||||||
|
|
||||||
"@radix-ui/react-avatar@^1.0.1":
|
"@radix-ui/react-avatar@^1.0.1":
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-avatar/-/react-avatar-1.0.2.tgz#c72209882e191db00ac0bfa16a9d9c025f0958f0"
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-avatar/-/react-avatar-1.0.2.tgz#c72209882e191db00ac0bfa16a9d9c025f0958f0"
|
||||||
|
|
@ -3721,6 +3728,17 @@
|
||||||
"@radix-ui/react-use-callback-ref" "1.0.0"
|
"@radix-ui/react-use-callback-ref" "1.0.0"
|
||||||
"@radix-ui/react-use-layout-effect" "1.0.0"
|
"@radix-ui/react-use-layout-effect" "1.0.0"
|
||||||
|
|
||||||
|
"@radix-ui/react-collection@1.0.1":
|
||||||
|
version "1.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-collection/-/react-collection-1.0.1.tgz#259506f97c6703b36291826768d3c1337edd1de5"
|
||||||
|
integrity sha512-uuiFbs+YCKjn3X1DTSx9G7BHApu4GHbi3kgiwsnFUbOKCrwejAJv4eE4Vc8C0Oaxt9T0aV4ox0WCOdx+39Xo+g==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.13.10"
|
||||||
|
"@radix-ui/react-compose-refs" "1.0.0"
|
||||||
|
"@radix-ui/react-context" "1.0.0"
|
||||||
|
"@radix-ui/react-primitive" "1.0.1"
|
||||||
|
"@radix-ui/react-slot" "1.0.1"
|
||||||
|
|
||||||
"@radix-ui/react-compose-refs@1.0.0":
|
"@radix-ui/react-compose-refs@1.0.0":
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-compose-refs/-/react-compose-refs-1.0.0.tgz#37595b1f16ec7f228d698590e78eeed18ff218ae"
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-compose-refs/-/react-compose-refs-1.0.0.tgz#37595b1f16ec7f228d698590e78eeed18ff218ae"
|
||||||
|
|
@ -3735,6 +3753,43 @@
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/runtime" "^7.13.10"
|
"@babel/runtime" "^7.13.10"
|
||||||
|
|
||||||
|
"@radix-ui/react-dismissable-layer@1.0.2":
|
||||||
|
version "1.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.0.2.tgz#f04d1061bddf00b1ca304148516b9ddc62e45fb2"
|
||||||
|
integrity sha512-WjJzMrTWROozDqLB0uRWYvj4UuXsM/2L19EmQ3Au+IJWqwvwq9Bwd+P8ivo0Deg9JDPArR1I6MbWNi1CmXsskg==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.13.10"
|
||||||
|
"@radix-ui/primitive" "1.0.0"
|
||||||
|
"@radix-ui/react-compose-refs" "1.0.0"
|
||||||
|
"@radix-ui/react-primitive" "1.0.1"
|
||||||
|
"@radix-ui/react-use-callback-ref" "1.0.0"
|
||||||
|
"@radix-ui/react-use-escape-keydown" "1.0.2"
|
||||||
|
|
||||||
|
"@radix-ui/react-portal@1.0.1":
|
||||||
|
version "1.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-portal/-/react-portal-1.0.1.tgz#169c5a50719c2bb0079cf4c91a27aa6d37e5dd33"
|
||||||
|
integrity sha512-NY2vUWI5WENgAT1nfC6JS7RU5xRYBfjZVLq0HmgEN1Ezy3rk/UruMV4+Rd0F40PEaFC5SrLS1ixYvcYIQrb4Ig==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.13.10"
|
||||||
|
"@radix-ui/react-primitive" "1.0.1"
|
||||||
|
|
||||||
|
"@radix-ui/react-presence@1.0.0":
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-presence/-/react-presence-1.0.0.tgz#814fe46df11f9a468808a6010e3f3ca7e0b2e84a"
|
||||||
|
integrity sha512-A+6XEvN01NfVWiKu38ybawfHsBjWum42MRPnEuqPsBZ4eV7e/7K321B5VgYMPv3Xx5An6o1/l9ZuDBgmcmWK3w==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.13.10"
|
||||||
|
"@radix-ui/react-compose-refs" "1.0.0"
|
||||||
|
"@radix-ui/react-use-layout-effect" "1.0.0"
|
||||||
|
|
||||||
|
"@radix-ui/react-primitive@1.0.1":
|
||||||
|
version "1.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-primitive/-/react-primitive-1.0.1.tgz#c1ebcce283dd2f02e4fbefdaa49d1cb13dbc990a"
|
||||||
|
integrity sha512-fHbmislWVkZaIdeF6GZxF0A/NH/3BjrGIYj+Ae6eTmTCr7EB0RQAAVEiqsXK6p3/JcRqVSBQoceZroj30Jj3XA==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.13.10"
|
||||||
|
"@radix-ui/react-slot" "1.0.1"
|
||||||
|
|
||||||
"@radix-ui/react-primitive@1.0.2":
|
"@radix-ui/react-primitive@1.0.2":
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-primitive/-/react-primitive-1.0.2.tgz#54e22f49ca59ba88d8143090276d50b93f8a7053"
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-primitive/-/react-primitive-1.0.2.tgz#54e22f49ca59ba88d8143090276d50b93f8a7053"
|
||||||
|
|
@ -3751,6 +3806,25 @@
|
||||||
"@babel/runtime" "^7.13.10"
|
"@babel/runtime" "^7.13.10"
|
||||||
"@radix-ui/react-compose-refs" "1.0.0"
|
"@radix-ui/react-compose-refs" "1.0.0"
|
||||||
|
|
||||||
|
"@radix-ui/react-toast@^1.1.2":
|
||||||
|
version "1.1.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-toast/-/react-toast-1.1.2.tgz#53872fbf20c6515040bac54fc0660dbfe983ab90"
|
||||||
|
integrity sha512-Kpr4BBYoP0O5A1UeDBmao87UnCMNdAKGNioQH5JzEm6OYTUVGhuDRbOwoZxPwOZ6vsjJHeIpdUrwbiHEB65CCw==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.13.10"
|
||||||
|
"@radix-ui/primitive" "1.0.0"
|
||||||
|
"@radix-ui/react-collection" "1.0.1"
|
||||||
|
"@radix-ui/react-compose-refs" "1.0.0"
|
||||||
|
"@radix-ui/react-context" "1.0.0"
|
||||||
|
"@radix-ui/react-dismissable-layer" "1.0.2"
|
||||||
|
"@radix-ui/react-portal" "1.0.1"
|
||||||
|
"@radix-ui/react-presence" "1.0.0"
|
||||||
|
"@radix-ui/react-primitive" "1.0.1"
|
||||||
|
"@radix-ui/react-use-callback-ref" "1.0.0"
|
||||||
|
"@radix-ui/react-use-controllable-state" "1.0.0"
|
||||||
|
"@radix-ui/react-use-layout-effect" "1.0.0"
|
||||||
|
"@radix-ui/react-visually-hidden" "1.0.1"
|
||||||
|
|
||||||
"@radix-ui/react-use-callback-ref@1.0.0":
|
"@radix-ui/react-use-callback-ref@1.0.0":
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.0.0.tgz#9e7b8b6b4946fe3cbe8f748c82a2cce54e7b6a90"
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.0.0.tgz#9e7b8b6b4946fe3cbe8f748c82a2cce54e7b6a90"
|
||||||
|
|
@ -3758,6 +3832,22 @@
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/runtime" "^7.13.10"
|
"@babel/runtime" "^7.13.10"
|
||||||
|
|
||||||
|
"@radix-ui/react-use-controllable-state@1.0.0":
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.0.0.tgz#a64deaafbbc52d5d407afaa22d493d687c538b7f"
|
||||||
|
integrity sha512-FohDoZvk3mEXh9AWAVyRTYR4Sq7/gavuofglmiXB2g1aKyboUD4YtgWxKj8O5n+Uak52gXQ4wKz5IFST4vtJHg==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.13.10"
|
||||||
|
"@radix-ui/react-use-callback-ref" "1.0.0"
|
||||||
|
|
||||||
|
"@radix-ui/react-use-escape-keydown@1.0.2":
|
||||||
|
version "1.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.0.2.tgz#09ab6455ab240b4f0a61faf06d4e5132c4d639f6"
|
||||||
|
integrity sha512-DXGim3x74WgUv+iMNCF+cAo8xUHHeqvjx8zs7trKf+FkQKPQXLk2sX7Gx1ysH7Q76xCpZuxIJE7HLPxRE+Q+GA==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.13.10"
|
||||||
|
"@radix-ui/react-use-callback-ref" "1.0.0"
|
||||||
|
|
||||||
"@radix-ui/react-use-layout-effect@1.0.0":
|
"@radix-ui/react-use-layout-effect@1.0.0":
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.0.0.tgz#2fc19e97223a81de64cd3ba1dc42ceffd82374dc"
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.0.0.tgz#2fc19e97223a81de64cd3ba1dc42ceffd82374dc"
|
||||||
|
|
@ -3765,6 +3855,14 @@
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/runtime" "^7.13.10"
|
"@babel/runtime" "^7.13.10"
|
||||||
|
|
||||||
|
"@radix-ui/react-visually-hidden@1.0.1":
|
||||||
|
version "1.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.0.1.tgz#9a4ac4fc97ae8d72a10e727f16b3121b5f0aa469"
|
||||||
|
integrity sha512-K1hJcCMfWfiYUibRqf3V8r5Drpyf7rh44jnrwAbdvI5iCCijilBBeyQv9SKidYNZIopMdCyR9FnIjkHxHN0FcQ==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.13.10"
|
||||||
|
"@radix-ui/react-primitive" "1.0.1"
|
||||||
|
|
||||||
"@react-icons/all-files@^4.1.0":
|
"@react-icons/all-files@^4.1.0":
|
||||||
version "4.1.0"
|
version "4.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/@react-icons/all-files/-/all-files-4.1.0.tgz#477284873a0821928224b6fc84c62d2534d6650b"
|
resolved "https://registry.yarnpkg.com/@react-icons/all-files/-/all-files-4.1.0.tgz#477284873a0821928224b6fc84c62d2534d6650b"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue