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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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}
        </>
    )
}