recoil#useRecoilState TypeScript Examples
The following examples show how to use
recoil#useRecoilState.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: browseContext.ts From frames with Mozilla Public License 2.0 | 6 votes |
useGenreContext = () => {
const [genreContext, setGenreContext] = useRecoilState(GenreContextAtom);
const manageGenre = (genre: string) => {
if (genreContext.includes(genre))
setGenreContext(genreContext.filter(g => g !== genre));
else setGenreContext([...genreContext, genre]);
}
const isGenreSelected = (genre: string) => genreContext.includes(genre);
return {manageGenre, isGenreSelected};
}
Example #2
Source File: BooksPage.tsx From react-tutorials with MIT License | 6 votes |
BooksPage = () => {
const books: any = useRecoilValue(getAllBooks)
const [currentBookID, setCurrentBookID] = useRecoilState(currentBookIDState)
return (
<div className="BooksPageMain">
<h2>Eli Elad Elrom Technology Books</h2>
{books.map((book: { id: string; title: string }) => (
<div key={book.id}>
<button onClick={() => setCurrentBookID(book.id)}>
{book.id === currentBookID && '- '}
{book.title}
</button>
</div>
))}
{currentBookID && (
<Suspense fallback={<span>Loading</span>}>
<BookDetail />
</Suspense>
)}
</div>
)
}
Example #3
Source File: Header.tsx From mojito_pdm with Creative Commons Attribution Share Alike 4.0 International | 6 votes |
Header: React.FC = () => {
const [colorMode, setColorMode] = useRecoilState(GlobalState.theme)
const {setVisible} = useVisibility()
const handleExit = async () => {
try {
await fetchNui("exit")
setVisible(false);
} catch (e) {
console.error(e)
}
}
const handleThemeswitch = () => {
colorMode === "light" ? setColorMode("dark") : setColorMode("light")
}
return (
<AppBar position="sticky">
<Toolbar sx={{backgroundColor: "primary.dark"}}>
<Typography sx={{flex: 1}}>
<img src={logo} height="100px" alt=""/>
</Typography>
<CategorySelect/>
<IconButton sx={{ml: 1}} onClick={handleThemeswitch} color="inherit">
{colorMode === 'dark' ? <Brightness7Icon/> : <Brightness4Icon/>}
</IconButton>
<IconButton sx={{ml: 1}} onClick={handleExit} color="inherit">
<CloseIcon/>
</IconButton>
</Toolbar>
</AppBar>
)
}
Example #4
Source File: ModsToolbar.tsx From ow-mod-manager with MIT License | 6 votes |
ModsToolbar: React.FunctionComponent = () => {
const styles = useStyles();
const inAlphaMode = useRecoilValue(settingsState).alphaMode;
const [filter, setFilter] = useRecoilState(modFilterState);
const { owmlPath, alphaPath } = useRecoilValue(settingsState);
return (
<Paper>
<Toolbar className={styles.toolBar}>
<FilterInput
value={filter}
onChange={setFilter}
label={modsText.toolbar.findModsLabel}
/>
<Button
startIcon={<FolderIcon />}
onClick={() =>
openDirectory(
inAlphaMode ? `${alphaPath}/BepInEx/plugins` : `${owmlPath}/Mods`
)
}
variant="outlined"
>
{modsText.toolbar.modsDirectory}
</Button>
</Toolbar>
</Paper>
);
}
Example #5
Source File: Scales.tsx From arduino-web-oscilloscope with MIT License | 6 votes |
export default function Scales() {
const [isRunning, setIsRunning] = useRecoilState(isRunningState)
const [isSpaceActive, tapSpace] = useActiveBtns()
useEffect(() => {
MouseTrap.bind('space', (e) => {
e.preventDefault()
tapSpace()
setIsRunning((isRunning) => !isRunning)
})
return () => {
MouseTrap.unbind('space')
}
}, [setIsRunning, tapSpace])
return (
<Panel header="Scales" shaded collapsible defaultExpanded>
<Button
active={isSpaceActive}
style={{
color: 'white',
backgroundColor: isRunning ? 'green' : 'red',
width: '100%',
marginBottom: '10px'
}}
size="sm"
onClick={() => {
setIsRunning(!isRunning)
}}
>
{(isRunning ? 'Run' : 'Hold') + ' [space]'}
</Button>
<TimeScales />
<Amplifier />
</Panel>
)
}
Example #6
Source File: react-recoil-hooks-testing-library.test.tsx From react-recoil-hooks-testing-library with MIT License | 6 votes |
useRecoilTestHook = (initialProps: string) => {
const [valueA, setValueA] = useRecoilState(atomA);
const [valueB, setValueB] = useRecoilState(atomB);
const update = () => {
setValueA(123);
setValueB('Wow!');
};
return { update, valueA, valueB, initialProps };
}
Example #7
Source File: LanguageSwitcher.tsx From nextclade with MIT License | 6 votes |
export function LanguageSwitcher({ ...restProps }: LanguageSwitcherProps) {
const [currentLocale, setCurrentLocale] = useRecoilState(localeAtom)
const [dropdownOpen, setDropdownOpen] = useState(false)
const toggle = useCallback(() => setDropdownOpen((prevState) => !prevState), [])
const setLocaleLocal = useCallback((locale: Locale) => () => setCurrentLocale(locale), [setCurrentLocale])
return (
<Dropdown className="language-switcher" isOpen={dropdownOpen} toggle={toggle} {...restProps}>
<DropdownToggle nav caret>
<LanguageSwitcherItem locale={currentLocale} />
</DropdownToggle>
<DropdownMenu className="language-switcher-menu" positionFixed>
{localesArray.map((locale) => {
const isCurrent = locale.key === currentLocale.key
return (
<DropdownItem active={isCurrent} key={locale.key} onClick={setLocaleLocal(locale)}>
<LanguageSwitcherItem locale={locale} />
</DropdownItem>
)
})}
</DropdownMenu>
</Dropdown>
)
}
Example #8
Source File: ColorInput.tsx From phosphor-home with MIT License | 6 votes |
ColorInput: React.FC<ColorInputProps> = () => {
const [color, setColor] = useRecoilState(iconColorAtom);
const isDark = useRecoilValue(isDarkThemeSelector);
const handleColorChange = useCallback(
(event: React.ChangeEvent<HTMLInputElement>) => {
const {
target: { value: color },
} = event;
if (color[0] === "#") setColor(color);
},
[setColor]
);
const throttledColorChange = useThrottled(handleColorChange, 100, [
handleColorChange,
]);
return (
<div className="color-picker">
<input
className="color-input"
aria-label="Icon Color"
style={{ backgroundColor: color }}
type="color"
onChange={throttledColorChange}
value={color}
/>
<span style={{ color: isDark ? "black" : "white" }}>{color}</span>
</div>
);
}
Example #9
Source File: input.tsx From clean-react with GNU General Public License v3.0 | 6 votes |
Input: React.FC<Props> = ({ type, name, placeholder }: Props) => {
const [state, setState] = useRecoilState(loginState)
return (
<InputBase
type={type}
name={name}
placeholder={placeholder}
state={state}
setState={setState}
/>
)
}
Example #10
Source File: index.ts From react-pwa with MIT License | 6 votes |
function useHotKeysDialog(): [boolean, Actions] {
const [isOpen, setIsOpen] = useRecoilState(hotKeysDialogState);
function toggle() {
setIsOpen((isOpen: boolean) => !isOpen);
}
function close() {
setIsOpen(false);
}
function open() {
setIsOpen(true);
}
return [isOpen, { toggle, close, open }];
}
Example #11
Source File: Recommend.tsx From phonepare with MIT License | 6 votes |
Recommend : FC = () => {
const [ questionIndex, setQuestionIndex ] = useRecoilState(questionIndexState)
const [ questionTags, setQuestionTags ] = useRecoilState(questionTagsState)
const setSelecetedPhones = useSetRecoilState(selectedPhonesState)
return <Box py={10} textAlign='center'>
<Heading mb={3}>폰 추천받기</Heading>
{
questionIndex < Questions.length ? <Box px={{ base: 10, md: 32 }}>
<Flex height='60vh' alignItems='center' justifyContent='center'>
<Box>
<Heading fontSize='2xl'>{Questions[questionIndex].question}</Heading>
<Progress mt={4} mb={6} value={questionIndex} max={Questions.length} size='md' rounded='2xl' />
<Grid templateColumns={{ base: 'repeat(1, 1fr)', md: 'repeat(2, 1fr)' }} gap={5}>
{
Questions[questionIndex].options.map((option, index) => <Card key={index} onClick={() => {
setQuestionTags({ ...questionTags, [Questions[questionIndex].id]: option.value })
setQuestionIndex(questionIndex + 1)
if(questionIndex < Questions.length) setSelecetedPhones(getRecommended(questionTags).map(x => x.data.id) as [ string, string, string ])
}}>
<Text>{option.subLabel}</Text>
<Heading fontSize='xl'>{option.label}</Heading>
</Card>
)
}
</Grid>
</Box>
</Flex>
</Box> : <Box>
<Heading fontSize='2xl'>아래 휴대폰을 추천드립니다!</Heading>
<Button mt={4} onClick={() => setQuestionIndex(0)}>다시 고르기</Button>
<Compare asComponent />
</Box>
}
</Box>
}
Example #12
Source File: ContextMenuItem.tsx From wiregui with MIT License | 5 votes |
ContextMenuItem: React.FC<Props> = ({
children,
onClick,
color,
colorScheme,
disabled,
command,
icon,
...buttonProps
}) => {
const [contextMenusState, setContextMenusState] =
useRecoilState(contextMenusAtom);
return (
<Button
onClick={(e) => {
e.preventDefault();
// call the provided click handler with the event and the passthrough data from the trigger
onClick && onClick({ event: e, passData: contextMenusState.passData });
// TODO: make it more specific
// close all menus
setContextMenusState((oldState) => {
return {
...oldState,
menus: oldState.menus.map((m) => ({
...m,
isOpen: false,
})),
};
});
}}
borderRadius={0}
w="full"
justifyContent="space-between"
size="sm"
overflow="hidden"
textOverflow="ellipsis"
colorScheme={colorScheme}
color={color}
disabled={disabled}
{...buttonProps}
>
{/* left */}
<HStack spacing={2} alignItems="center" w="full" h="full">
{/* icon */}
{icon}
{/* children */}
<Text>{children}</Text>
</HStack>
{/* right */}
<Text size="sm" opacity={0.5} fontFamily="mono">
{command}
</Text>
</Button>
);
}
Example #13
Source File: misc.tsx From frames with Mozilla Public License 2.0 | 5 votes |
ShareFrame = () => {
const {copy} = useClipboard();
const base = useBase();
const {getBaseUrl} = useBasics();
const data = useRecoilValue(framesVideoStateAtom);
const [value, setValue] = useRecoilState(shareAndDownloadAtom);
const {current, duration} = useRecoilValue(FramesInformAtom);
const [frame, setFrame] = useState(base.generateKey(13, 1) || '');
const [shareUrl, setShareUrl] = useState(`${getBaseUrl()}/frame=${frame}`);
const sendZero = async (inform: boolean) => {
if (frame === '' && base) {
setFrame(base.generateKey(13, 1));
setShareUrl(`${getBaseUrl()}/frame=${frame}`);
}
if (frame !== '' && base) {
await copy(shareUrl, 'Video url copied successfully');
let position = 0;
if (inform)
position = Math.ceil((current / duration) * 1000);
await base.makeRequest('/api/stream/genCypher', {
cypher: frame,
position,
auth: data?.location
}, 'POST');
setFrame(base.generateKey(13, 1));
setShareUrl(`${getBaseUrl()}/frame=${frame}`);
}
}
return (
<div className={style.sc}
style={value.share ? {left: '2vw', visibility: "visible"} : {
left: '2vw',
opacity: 0,
visibility: "hidden"
}}
onClick={e => e.stopPropagation()}>
<div className={style.sm}>
<span>Share from current position ?</span>
<input type="text" value={shareUrl} className={style.so} readOnly/>
</div>
<ul className={style.sl} onClick={() => setValue({...value, share: false})}>
<li className={style.accept} onClick={() => sendZero(true)}>yes</li>
<li className={style.reject} onClick={() => sendZero(false)}>no</li>
</ul>
</div>
)
}
Example #14
Source File: CategorySelect.tsx From mojito_pdm with Creative Commons Attribution Share Alike 4.0 International | 5 votes |
CategorySelect: React.FC = () => {
const theme = useTheme()
const [category, setCategory] = useRecoilState(CarState.categorySearch)
const handleChange = (event: SelectChangeEvent) => {
setCategory(event.target.value)
};
return (
<>
<div>
<FormControl variant="outlined" sx={{margin: theme.spacing(1), minWidth: 240}} color="error">
<InputLabel sx={{color: "white"}}>Category</InputLabel>
<Select sx={{color: "white"}}
labelId="demo-simple-select-outlined-label"
id="demo-simple-select-outlined"
value={category}
onChange={handleChange}
label="Category"
>
<MenuItem value="">
<em>All</em>
</MenuItem>
<MenuItem value={"Sports"}>Sports</MenuItem>
<MenuItem value={"Compacts"}>Compacts</MenuItem>
<MenuItem value={"Muscle"}>Muscle</MenuItem>
<MenuItem value={"Sedan"}>Sedan</MenuItem>
<MenuItem value={"Coupe"}>Coupé</MenuItem>
<MenuItem value={"Super"}>Super</MenuItem>
<MenuItem value={"SUV"}>SUV</MenuItem>
<MenuItem value={"Vans"}>Vans</MenuItem>
<MenuItem value={"Offroad"}>Offroad</MenuItem>
<MenuItem value={"Sports Classics"}>Sports Classics</MenuItem>
<MenuItem value={"Motorcycles"}>Motorcycles</MenuItem>
</Select>
</FormControl>
</div>
</>
)
}
Example #15
Source File: Amplifier.tsx From arduino-web-oscilloscope with MIT License | 5 votes |
function Amplifier() {
const [amplifier, setAmplifier] = useRecoilState(useAmplifier.send)
const [isUpActive, tapUp] = useActiveBtns()
const [isDownActive, tapDown] = useActiveBtns()
useEffect(() => {
MouseTrap.bind('up', (e) => {
e.preventDefault()
tapUp()
setAmplifier(amplifier - 1)
})
MouseTrap.bind('down', (e) => {
e.preventDefault()
tapDown()
setAmplifier(amplifier + 1)
})
return () => {
MouseTrap.unbind('up')
MouseTrap.unbind('down')
}
}, [amplifier, setAmplifier, tapDown, tapUp])
return (
<div
style={{
width: ' 100%',
display: ' flex',
justifyContent: ' space-between',
marginBottom: 5
}}
>
<IconButton
active={isDownActive}
size="md"
icon={<Icon icon="down" />}
onClick={() => setAmplifier(amplifier + 1)}
/>
<SelectPicker
searchable={false}
value={amplifier}
cleanable={false}
onChange={setAmplifier}
data={voltageRanges.map((v, i) => {
return {
label: formatVoltage(v / 10) + ' / div',
value: i
}
})}
style={{ flex: 1, marginLeft: 5, marginRight: 5 }}
/>
<IconButton
active={isUpActive}
size="md"
icon={<Icon icon="up" />}
onClick={() => setAmplifier(amplifier - 1)}
/>
</div>
)
}
Example #16
Source File: index.tsx From rocketredis with MIT License | 5 votes |
ConnectionsList: React.FC = () => {
const [connections] = useRecoilState(connectionsState)
const [isCreateModalOpen, toggleCreateModalOpen] = useToggle(false)
const { t } = useTranslation('connectionList')
useEffect(() => {
ipcRenderer.addListener('newConnection', toggleCreateModalOpen)
return () => {
ipcRenderer.removeListener('newConnection', toggleCreateModalOpen)
}
}, [toggleCreateModalOpen])
return (
<>
<Container
width={300}
height={Infinity}
minConstraints={[240, Infinity]}
maxConstraints={[300, Infinity]}
className="app-sidebar"
>
<Connections>
<header>
<strong>{t('title')}</strong>
<button type="button" onClick={toggleCreateModalOpen}>
<FiPlusCircle />
</button>
</header>
<ul>
{connections.map(connection => (
<Connection key={connection.name} connection={connection} />
))}
</ul>
</Connections>
</Container>
<ConnectionFormModal
visible={isCreateModalOpen}
onRequestClose={toggleCreateModalOpen}
/>
</>
)
}
Example #17
Source File: WhatsNewButton.tsx From nextclade with MIT License | 5 votes |
export function WhatsNewButton() {
const { t } = useTranslation()
const [showChangelog, setShowChangelog] = useRecoilState(changelogIsShownAtom)
const [showChangelogOnUpdate, setShowChangelogOnUpdate] = useRecoilState(changelogShouldShowOnUpdatesAtom)
const toggleOpen = useCallback(() => {
setShowChangelog((showChangelog) => !showChangelog)
}, [setShowChangelog])
const open = useCallback(() => {
setShowChangelog(true)
}, [setShowChangelog])
const close = useCallback(() => {
setShowChangelog(false)
}, [setShowChangelog])
const text = t("What's new")
const closeText = t('Close this window')
return (
<>
<ButtonWhatsNewBase type="button" onClick={open} title={text}>
<FaListUl className="mr-xl-2" />
<span className="d-none d-xl-inline">{text}</span>
</ButtonWhatsNewBase>
<Modal centered isOpen={showChangelog} toggle={toggleOpen} fade={false} size="lg">
<ModalHeader toggle={close} tag="div">
<H1 className="text-center">{text}</H1>
</ModalHeader>
<ModalBody>
<MDXProvider components={components}>
<Changelog />
</MDXProvider>
</ModalBody>
<ModalFooter>
<Container fluid>
<Row noGutters className="my-2">
<Col className="d-flex w-100">
<div className="ml-auto">
<Toggle
className="m-0"
identifier={'show-whatsnew-again-toggle'}
checked={showChangelogOnUpdate}
onCheckedChanged={setShowChangelogOnUpdate}
>
{t('Show when a new version is available')}
</Toggle>
</div>
</Col>
</Row>
<Row noGutters className="my-2">
<Col className="d-flex w-100">
<ButtonOk className="ml-auto" type="button" color="success" onClick={close} title={closeText}>
{t('OK')}
</ButtonOk>
</Col>
</Row>
</Container>
</ModalFooter>
</Modal>
</>
)
}
Example #18
Source File: OptionModal.tsx From life-calendar with MIT License | 5 votes |
export default function OptionModal() {
const initialFocusRef = React.useRef();
const [state, setState] = useRecoilState<any>(appState);
return (
<Popover initialFocusRef={initialFocusRef} placement="bottom">
<PopoverTrigger>
<Button size="sm" colorScheme="black" mr={3}>
Options
</Button>
</PopoverTrigger>
<PopoverContent color="white" bg="blue.800" borderColor="blue.800">
{/* <PopoverHeader pt={4} fontWeight="bold" border="0" fontSize="sm">
Options
</PopoverHeader> */}
<PopoverArrow />
<PopoverCloseButton />
<PopoverBody fontSize="sm">
<Box mt={4} textAlign="left">
<Checkbox
defaultIsChecked={!!state.options.highlightYears}
onChange={(e) => {
const _state = { ...state };
_state.options = { ..._state.options, highlightYears: e.target.checked };
setState(_state);
}}
>
Highlight every year
</Checkbox>
<Checkbox
defaultIsChecked={!!state.options.showEveryYears}
onChange={(e) => {
const _state = { ...state };
_state.options = { ..._state.options, showEveryYears: e.target.checked ? 5 : 0 };
setState(_state);
}}
>
Show year numbers
</Checkbox>
<Checkbox
defaultIsChecked={!!state.options.oneRowOneYear}
onChange={(e) => {
const _state = { ...state };
_state.options = { ..._state.options, oneRowOneYear: e.target.checked };
setState(_state);
}}
>
One row is one year
</Checkbox>
</Box>
</PopoverBody>
<PopoverFooter border="0" d="flex" alignItems="center" justifyContent="space-between" pb={4}></PopoverFooter>
</PopoverContent>
</Popover>
);
}
Example #19
Source File: ColorfulBeads.tsx From Riakuto-StartingReact-ja3.1 with Apache License 2.0 | 5 votes |
EnhancedColorfulBeads: VFC<{ count?: number }> = () => {
const [count, _] = useRecoilState(counterState);
return <ColorfulBeads count={count} />;
}
Example #20
Source File: IconGridItem.tsx From phosphor-home with MIT License | 5 votes |
IconGridItem: React.FC<IconGridItemProps> = (props) => {
const { index, originOffset, entry } = props;
const { name, Icon } = entry;
const [open, setOpen] = useRecoilState(iconPreviewOpenAtom);
const isOpen = open === name;
const isNew = entry.tags.includes("*new*");
const isUpdated = entry.tags.includes("*updated*");
const delayRef = useRef<number>(0);
const offset = useRef({ top: 0, left: 0 });
const ref = useRef<any>();
const handleOpen = () => setOpen(isOpen ? false : name);
// The measurement for all elements happens in the layoutEffect cycle
// This ensures that when we calculate distance in the effect cycle
// all elements have already been measured
useLayoutEffect(() => {
const element = ref.current;
if (!element) return;
offset.current = {
top: element.offsetTop,
left: element.offsetLeft,
};
if (index === originIndex) {
originOffset.current = offset.current;
}
}, [index, originOffset]);
useEffect(() => {
const dx = Math.abs(offset.current.left - originOffset.current.left);
const dy = Math.abs(offset.current.top - originOffset.current.top);
const d = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2));
delayRef.current = d * delayPerPixel;
}, [originOffset]);
return (
<>
<motion.div
className="grid-item"
key={name}
ref={ref}
tabIndex={0}
style={{
order: index,
backgroundColor: isOpen ? "rgba(163, 159, 171, 0.1)" : undefined,
}}
custom={delayRef}
transition={transition}
variants={itemVariants}
onKeyPress={(e) => e.key === "Enter" && handleOpen()}
onClick={handleOpen}
>
<Icon />
<p>
{name}
{isNew && <span className="badge new">•</span>}
{isUpdated && <span className="badge updated">•</span>}
</p>
</motion.div>
<AnimatePresence initial={false}>
{isOpen && <DetailsPanel {...props} />}
</AnimatePresence>
</>
);
}
Example #21
Source File: login.tsx From clean-react with GNU General Public License v3.0 | 5 votes |
Login: React.FC<Props> = ({ validation, authentication }: Props) => {
const resetLoginState = useResetRecoilState(loginState)
const { setCurrentAccount } = useRecoilValue(currentAccountState)
const history = useHistory()
const [state, setState] = useRecoilState(loginState)
useEffect(() => resetLoginState(), [])
useEffect(() => validate('email'), [state.email])
useEffect(() => validate('password'), [state.password])
const validate = (field: string): void => {
const { email, password } = state
const formData = { email, password }
setState(old => ({ ...old, [`${field}Error`]: validation.validate(field, formData) }))
setState(old => ({ ...old, isFormInvalid: !!old.emailError || !!old.passwordError }))
}
const handleSubmit = async (event: React.FormEvent<HTMLFormElement>): Promise<void> => {
event.preventDefault()
try {
if (state.isLoading || state.isFormInvalid) {
return
}
setState(old => ({ ...old, isLoading: true }))
const account = await authentication.auth({
email: state.email,
password: state.password
})
setCurrentAccount(account)
history.replace('/')
} catch (error) {
setState(old => ({
...old,
isLoading: false,
mainError: error.message
}))
}
}
return (
<div className={Styles.loginWrap}>
<LoginHeader />
<form data-testid="form" className={Styles.form} onSubmit={handleSubmit}>
<h2>Login</h2>
<Input type="email" name="email" placeholder="Digite seu e-mail" />
<Input type="password" name="password" placeholder="Digite sua senha" />
<SubmitButton text="Entrar" />
<Link data-testid="signup-link" to="/signup" className={Styles.link}>Criar conta</Link>
<FormStatus />
</form>
<Footer />
</div>
)
}
Example #22
Source File: index.ts From react-pwa with MIT License | 5 votes |
function useNotifications(): [Notification[], Actions] {
const [notifications, setNotifications] = useRecoilState(notificationsState);
const push = useCallback(
(notification: Partial<Notification>) => {
// TODO (Suren): use uuid
const id = Math.random().toString();
setNotifications((notifications): Notification[] => [
// TODO (Suren): use immer
...notifications,
{
...notification,
message: notification.message,
dismissed: false,
options: {
...notificationsDefaults.options,
...notification.options,
key: id,
},
},
]);
return id;
},
[setNotifications],
);
const close = useCallback(
(key: SnackbarKey, dismissAll = !key) => {
setNotifications((notifications) =>
notifications.map((notification) =>
dismissAll || notification.options.key === key
? { ...notification, dismissed: true }
: { ...notification },
),
);
},
[setNotifications],
);
const remove = useCallback(
(key: SnackbarKey) => {
setNotifications((notifications) =>
notifications.filter((notification) => notification.options.key !== key),
);
},
[setNotifications],
);
const actions = useMemo(() => ({ push, close, remove }), [push, close, remove]);
return [notifications, actions];
}
Example #23
Source File: Phone.tsx From phonepare with MIT License | 5 votes |
Phone: FC<{
index: number
mobile?: boolean
select?: boolean
}> = ({ index, mobile=false, select=true } ) => {
const [ manufacturer, setManufacturer ] = useState<Manufacturer>()
const [ selectedPhones, setSelectedPhones ] = useRecoilState(selectedPhonesState)
const selectedPhonesData = useRecoilValue(selectedPhonesDataState)
function updatePhoneIndex(value: string): void {
setSelectedPhones(v => {
const copied = [ ...v ]
copied[index] = value
return copied as [ string, string, string ]
})
}
return <Box textAlign='left' {...( mobile ? { display: { base: 'none', lg: 'block' } } : {} )}>
{
select && <>
<Text>제조사</Text>
<Select mb={2} placeholder='선택 안함' onChange={(e) => {
updatePhoneIndex('')
setManufacturer(e.target.value as Manufacturer)
}}>
{
Manufacturers.map((m: Manufacturer) => <option key={m} value={m}>{ManufacturersName[m]}</option>)
}
</Select>
<Text>기종</Text>
<Select placeholder='선택해주세요' value={selectedPhones[index]} onChange={(e) => updatePhoneIndex(e.target.value)}>
{
Phones.filter(el => manufacturer ? el.data.manufacturer === manufacturer : true).map(phone => <option key={phone.data.id} value={phone.data.id}>{!manufacturer && `[${ManufacturersName[phone.data.manufacturer]}] `}{phone.data.name}</option>)
}
</Select>
</>
}
{
selectedPhonesData[index] ? <Box mt={10} textAlign='center'>
<Image mx='auto' src={selectedPhonesData[index]?.image} alt={selectedPhonesData[index]?.data.name} width={{ base: '150px', md: '350px' }} height={{ base: '200px', md: '450px' }} />
<Text fontSize='3xl' fontWeight='bold'>{selectedPhonesData[index]?.data.name}</Text>
<Text mt={2}>색상</Text>
<Flex wrap='wrap' justifyContent='center'>
{
selectedPhonesData[index]?.colors.map(color => <ColorLabel color={color} key={color.id} />)
}
</Flex>
</Box> : <Box mt={10} width={{ base: '150px', md: '350px' }} height={{ base: '200px', md: '450px' }} />
}
</Box>
}
Example #24
Source File: ContextMenuList.tsx From wiregui with MIT License | 4 votes |
ContextMenuList: React.FC<Props & MotionBoxProps> = ({
children,
menuId,
render,
...boxProps
}) => {
const [contextMenusState, setContextMenusState] =
useRecoilState(contextMenusAtom);
const menuRef: RefObject<HTMLDivElement> = useRef(null);
const menu = useMemo(
() => contextMenusState.menus.find((m) => m.id === menuId),
[contextMenusState]
);
// where should the menu be shown?
// the ContextMenuTrigger sets this
const [position, setPosition] = useState<Position>({
left: -100,
right: 0,
top: -100,
bottom: 0,
});
// TODO: Any less manual way to do this
// figure out where to show the menu
useEffect(() => {
let left: number | undefined;
let right: number | undefined;
let top: number | undefined;
let bottom: number | undefined;
const x = contextMenusState.position.x;
const y = contextMenusState.position.y;
const menuHeight = menuRef?.current?.clientHeight;
const menuWidth = menuRef?.current?.clientWidth;
const windowWidth = window.innerWidth;
const windowHeight = window.innerHeight;
if (!menuHeight || !menuWidth) {
return;
}
if (x + menuWidth > windowWidth) {
right = windowWidth - x;
} else {
left = x;
}
if (y + menuHeight > windowHeight) {
bottom = windowHeight - y;
} else {
top = y;
}
setPosition({
top: `${top}px`,
bottom: `${bottom}px`,
left: `${left}px`,
right: `${right}px`,
});
}, [menuRef, contextMenusState.position.x, contextMenusState.position.y]);
// when clicking outside the menu, close it
useOutsideClick({
ref: menuRef,
handler: () => {
// close all menus
closeContextMenus();
},
});
const bgColor = useColorModeValue("gray.50", "gray.300");
const closeContextMenus = () => {
setContextMenusState((oldState) => {
return {
...oldState,
position: {
x: -100,
y: -100,
},
menus: oldState.menus.map((m) => ({
...m,
isOpen: false,
})),
};
});
};
return (
<MotionBox
variants={motionVariants}
animate={menu && menu.isOpen ? "enter" : "exit"}
ref={menuRef}
borderWidth={1}
position="fixed"
bg={bgColor}
minW={40}
w={52}
// maxW={96}
borderRadius="md"
display="flex"
flexDirection="column"
zIndex="popover"
{...position}
{...boxProps}
>
{/* either use the render prop or the children */}
{render
? render({
menuId,
closeContextMenus,
passData: contextMenusState.passData,
})
: children}
</MotionBox>
);
}
Example #25
Source File: form.tsx From frames with Mozilla Public License 2.0 | 4 votes |
function Login() {
const [state, dispatch] = useRecoilState(AuthContextHandler);
const [email, setEmail] = useRecoilState(AuthContextEmailAtom);
const [pass, setPass] = useState('');
const {confirmMail, signIn, forgotPassword} = useUser();
const {emailError} = useRecoilValue(AuthErrors);
const {error, process} = state;
const submit = () => {
dispatch({fade: true, error: null});
setTimeout(async () => {
if (process === 'email') {
if (email !== '' && !error && !emailError)
dispatch({
process: await confirmMail(email)
})
else dispatch({error: 'enter a valid email address'});
fade()
} else if (process === 'password')
dispatch({error: await signIn(email, pass)});
}, 500)
}
const handleForgotPassword = () => {
dispatch({fade: true, error: null});
setTimeout(async () => {
if (email !== '' && !emailError) {
const data = await forgotPassword(email);
if (data)
dispatch({process: 'reset'});
else
dispatch({error: 'email not found'});
} else
dispatch({error: 'enter a valid email address', process: 'email'});
fade()
}, 500)
}
const fade = () => setTimeout(() => dispatch({fade: false}), 1000);
useEventListener('keyup', event => {
if (event.code === 'Enter')
submit();
})
useEffect(() => {
fade();
}, [])
return (
<>
<div className={styles["log-input-holder"]}>
<input readOnly={process !== "email"}
className={process === "email" ? styles["log-input"] : styles["log-pass"]}
style={error ? {borderColor: "rgba(245, 78, 78, .9)"} : {}} type="email"
placeholder="enter your email address" onChange={(e) => {
dispatch({error: null})
setEmail(e.currentTarget.value)
}}/>
<input className={process === "password" ? styles["log-input"] : styles["log-pass"]}
style={error ? {borderColor: "rgba(245, 78, 78, .9)"} : {}} type="password"
placeholder="enter your password" onChange={(e) => {
dispatch({error: null})
setPass(e.currentTarget.value)
}}/>
</div>
{process !== 'reset' ?
<div className={styles["submit-width"]}>
<button
className={styles["log-submit"]}
type="button"
style={{width: "100%"}}
onClick={submit}
>
Submit
</button>
</div> : null
}
{error === 'Incorrect password' ? <div className={styles["submit-width"]}>
<div className={styles.fp} onClick={handleForgotPassword}>forgot password?</div>
</div> : null}
</>
)
}