react-icons/fi#FiCheck TypeScript Examples

The following examples show how to use react-icons/fi#FiCheck. 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: UserBox.tsx    From tobira with Apache License 2.0 6 votes vote down vote up
LanguageMenu: React.FC = () => {
    const { t, i18n } = useTranslation();

    return <>
        {Object.keys(languages).map(lng => (
            <MenuItem
                key={lng}
                icon={lng === i18n.resolvedLanguage ? <FiCheck /> : undefined}
                onClick={() => i18n.changeLanguage(lng)}
            >{t("language-name", { lng })}</MenuItem>
        ))}
    </>;

}
Example #2
Source File: Input.tsx    From tobira with Apache License 2.0 6 votes vote down vote up
CopyableInput: React.FC<CopyableInputProps> = ({ value, ...rest }) => {
    const { t } = useTranslation();

    const [wasCopied, setWasCopied] = useState(false);
    const copy = async () => {
        await navigator.clipboard.writeText(value);
        setWasCopied(true);
    };

    return (
        <div css={{ display: "flex" }} {...rest}>
            <input disabled value={value} css={{
                ...style(false),
                padding: "4px 10px",
                borderTopRightRadius: 0,
                borderBottomRightRadius: 0,
                verticalAlign: "bottom",
                borderRight: "none",
                flex: "1",
            }} />
            {/* TODO: use BaseButton or sth once merged */}
            <Button
                kind="happy"
                onClick={copy}
                title={t("copy-to-clipboard")}
                css={{
                    borderTopLeftRadius: 0,
                    borderBottomLeftRadius: 0,
                    height: 34,
                }}
            >
                {wasCopied ? <FiCheck /> : <FiCopy />}
            </Button>
        </div>
    );
}
Example #3
Source File: CopyButton.tsx    From meshtastic-web with GNU General Public License v3.0 6 votes vote down vote up
CopyButton = ({
  data,
  ...props
}: CopyButtonProps): JSX.Element => {
  const [isCopied, setCopied] = useCopyClipboard(data, {
    successDuration: 1000,
  });

  return (
    <IconButton
      placeholder={``}
      onClick={(): void => {
        setCopied();
      }}
      icon={isCopied ? <FiCheck /> : <FiClipboard />}
      {...props}
    />
  );
}
Example #4
Source File: VariantSelectButton.tsx    From Meshtastic with GNU General Public License v3.0 5 votes vote down vote up
VariantSelectButton = ({
  options,
}: VariantSelectButtonProps): JSX.Element => {
  const [selected, setSelected] = useState(options[options.length - 1]);

  return (
    <Listbox value={selected} onChange={setSelected}>
      {({ open }) => (
        <>
          <div className="relative select-none">
            <Listbox.Button as={Fragment}>
              <motion.button
                whileHover={{ backgroundColor: 'var(--tertiary)' }}
                whileTap={{ scale: 0.99 }}
                className="relative -mt-5 ml-2 flex w-fit gap-1 rounded-lg bg-secondary p-2 py-2 pl-3 pr-10 text-lg font-medium leading-6 shadow-md md:mt-2"
              >
                <span className="block truncate">{selected.name}</span>
                <span className="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-2">
                  <HiSelector
                    className="h-5 w-5 text-gray-400"
                    aria-hidden="true"
                  />
                </span>
              </motion.button>
            </Listbox.Button>

            <Transition
              show={open}
              as={Fragment}
              leave="transition ease-in duration-100"
              leaveFrom="opacity-100"
              leaveTo="opacity-0"
            >
              <Listbox.Options className="absolute z-10 mt-1 max-h-60 w-full overflow-auto rounded-md bg-primary py-1 shadow-md ring-1 ring-black ring-opacity-5 focus:outline-none sm:text-sm">
                {options.map((variant, index) => (
                  <Listbox.Option
                    key={index}
                    className={({ active }) =>
                      `relative cursor-default select-none py-2 pl-3 pr-9 ${
                        active ? 'bg-secondary' : ''
                      }`
                    }
                    value={variant}
                  >
                    {({ selected, active }) => (
                      <>
                        <span
                          className={`block truncate ${
                            selected ? 'font-semibold' : 'font-normal'
                          }`}
                        >
                          {variant.name}
                        </span>

                        {selected ? (
                          <span
                            className={`absolute inset-y-0 right-0 flex items-center pr-4 ${
                              active ? '' : 'text-primaryInv'
                            }`}
                          >
                            <FiCheck className="h-5 w-5" aria-hidden="true" />
                          </span>
                        ) : null}
                      </>
                    )}
                  </Listbox.Option>
                ))}
              </Listbox.Options>
            </Transition>
          </div>
        </>
      )}
    </Listbox>
  );
}
Example #5
Source File: Button.tsx    From meshtastic-web with GNU General Public License v3.0 5 votes vote down vote up
Button = ({
  icon,
  className,
  border,
  size = ButtonSize.Medium,
  confirmAction,
  onClick,
  disabled,
  children,
}: ButtonProps): JSX.Element => {
  const [hasConfirmed, setHasConfirmed] = useState(false);

  const handleConfirm = (): void => {
    if (typeof confirmAction == 'function') {
      if (hasConfirmed) {
        void confirmAction();
      }
      setHasConfirmed(true);
      setTimeout(() => {
        setHasConfirmed(false);
      }, 3000);
    }
  };

  return (
    <m.button
      whileHover={{ scale: 1.01 }}
      whileTap={{ scale: 0.97 }}
      onClick={handleConfirm}
      className={`flex select-none items-center space-x-3 rounded-md border border-transparent text-sm focus-within:border-primary focus-within:shadow-border dark:text-white dark:focus-within:border-primary
        ${
          size === ButtonSize.Small
            ? 'p-0'
            : size === ButtonSize.Medium
            ? 'p-2'
            : 'p-4'
        }
      ${
        disabled
          ? 'cursor-not-allowed bg-white dark:bg-primaryDark'
          : 'cursor-pointer hover:bg-white hover:drop-shadow-md dark:hover:bg-secondaryDark'
      } ${border ? 'border-gray-400 dark:border-gray-200' : ''} ${
        className ?? ''
      }`}
      onClickCapture={onClick}
    >
      {icon && (
        <div className="text-gray-500 dark:text-gray-400">
          {hasConfirmed ? <FiCheck /> : icon}
        </div>
      )}

      <span>{children}</span>
    </m.button>
  );
}
Example #6
Source File: FilterMenu.tsx    From dxvote with GNU Affero General Public License v3.0 4 votes vote down vote up
FilterMenu = () => {
  const [showState, setShowState] = useState(false);
  const [showType, setShowType] = useState(false);
  const [showCurrency, setShowCurrency] = useState(false);

  const {
    onToggleState,
    onResetState,
    isStateSelected,
    countStateSelected,
    onToggleType,
    onResetType,
    isTypeSelected,
    countTypeSelected,
    onToggleCurrency,
    onResetCurrency,
    isCurrencySelected,
    countCurrencySelected,
  } = useFilter();
  const stateRef = useRef(null);
  const typeRef = useRef(null);
  const currencyRef = useRef(null);

  // hook that handles the click outside the ref element, when clicked calls callback to close.
  useDetectBlur(stateRef, () => setShowState(false));
  useDetectBlur(typeRef, () => setShowType(false));
  useDetectBlur(currencyRef, () => setShowCurrency(false));

  return (
    <FilterButtons>
      <DropdownMenu ref={stateRef} position={DropdownPosition.BottomRight}>
        <FilterButton
          iconRight
          onClick={() => {
            setShowState(!showState);
          }}
          active={countStateSelected > 0}
        >
          State <FiChevronDown />
        </FilterButton>
        <DropdownContent fullScreenMobile={true} show={showState}>
          {isMobile && (
            <DropdownHeader onClick={() => setShowState(false)}>
              <FiArrowLeft /> <span>State</span>{' '}
              <FilterResetMobile onClick={onResetState}>
                Reset
              </FilterResetMobile>
            </DropdownHeader>
          )}
          <Menu>
            <DropdownMenuItem onClick={() => onToggleState('a')}>
              State 1 {isStateSelected('a') && <FiCheck />}
            </DropdownMenuItem>
            <DropdownMenuItem onClick={() => onToggleState('b')}>
              State 2 {isStateSelected('b') && <FiCheck />}
            </DropdownMenuItem>
            <DropdownMenuItem onClick={() => onToggleState('c')}>
              State 3 {isStateSelected('c') && <FiCheck />}
            </DropdownMenuItem>
          </Menu>
          {isDesktop && countStateSelected > 0 && (
            <FilterResetDesktop onClick={onResetState}>
              Reset
            </FilterResetDesktop>
          )}
        </DropdownContent>
      </DropdownMenu>
      <DropdownMenu ref={typeRef} position={DropdownPosition.BottomRight}>
        <FilterButton
          iconRight
          onClick={() => setShowType(!showType)}
          active={countTypeSelected > 0}
        >
          Type <FiChevronDown />
        </FilterButton>
        <DropdownContent fullScreenMobile={true} show={showType}>
          {isMobile && (
            <DropdownHeader onClick={() => setShowType(false)}>
              <FiArrowLeft /> <span>Type</span>{' '}
              <FilterResetMobile onClick={onResetType}>Reset</FilterResetMobile>
            </DropdownHeader>
          )}
          <Menu>
            <DropdownMenuItem onClick={() => onToggleType('a')}>
              Type a {isTypeSelected('a') && <FiCheck />}
            </DropdownMenuItem>
            <DropdownMenuItem onClick={() => onToggleType('b')}>
              Type b {isTypeSelected('b') && <FiCheck />}
            </DropdownMenuItem>
            <DropdownMenuItem onClick={() => onToggleType('c')}>
              Type c {isTypeSelected('c') && <FiCheck />}
            </DropdownMenuItem>
            <DropdownMenuItem onClick={() => onToggleType('d')}>
              Type d {isTypeSelected('d') && <FiCheck />}
            </DropdownMenuItem>
          </Menu>
          {isDesktop && countTypeSelected > 0 && (
            <FilterResetDesktop onClick={onResetType}>Reset</FilterResetDesktop>
          )}
        </DropdownContent>
      </DropdownMenu>

      <DropdownMenu ref={currencyRef} position={DropdownPosition.BottomRight}>
        <FilterButton
          iconRight
          onClick={() => setShowCurrency(!showCurrency)}
          active={countCurrencySelected > 0}
        >
          Currency <FiChevronDown />
        </FilterButton>
        <DropdownContent fullScreenMobile={true} show={showCurrency}>
          {isMobile && (
            <DropdownHeader onClick={() => setShowCurrency(false)}>
              <FiArrowLeft /> <span>Currency</span>{' '}
              <FilterResetMobile onClick={onResetCurrency}>
                Reset
              </FilterResetMobile>
            </DropdownHeader>
          )}
          <Menu>
            <DropdownMenuItem onClick={() => onToggleCurrency('a')}>
              Currency a {isCurrencySelected('a') && <FiCheck />}
            </DropdownMenuItem>
            <DropdownMenuItem onClick={() => onToggleCurrency('b')}>
              Currency b {isCurrencySelected('b') && <FiCheck />}
            </DropdownMenuItem>
            <DropdownMenuItem onClick={() => onToggleCurrency('c')}>
              Currency c {isCurrencySelected('c') && <FiCheck />}
            </DropdownMenuItem>
            <DropdownMenuItem onClick={() => onToggleCurrency('d')}>
              Currency d {isCurrencySelected('d') && <FiCheck />}
            </DropdownMenuItem>
          </Menu>
          {isDesktop && countCurrencySelected > 0 && (
            <FilterResetDesktop onClick={onResetCurrency}>
              Reset
            </FilterResetDesktop>
          )}
        </DropdownContent>
      </DropdownMenu>
    </FilterButtons>
  );
}
Example #7
Source File: Login.tsx    From tobira with Apache License 2.0 4 votes vote down vote up
LoginBox: React.FC = () => {
    const { t, i18n } = useTranslation();
    const { register, handleSubmit, watch, formState: { errors } } = useForm<FormData>();
    const userid = watch("userid", "");
    const password = watch("password", "");

    const validation = { required: t<string>("this-field-is-required") };

    type State = "idle" | "pending" | "success";
    const [state, setState] = useState<State>("idle");
    const [loginError, setLoginError] = useState<string | null>(null);

    const onSubmit = async (data: FormData) => {
        setState("pending");
        const response = await fetch("/~login", {
            method: "POST",
            body: new URLSearchParams(data),
        });

        if (response.status === 204) {
            // 204 No content is expected on successful login. We assume that
            // the response also set some headers (or some other sticky
            // information) that is used to authorize the user in future
            // requests.
            setState("success");

            // We hard forward to the home page. We do that to invalidate every
            // data that we might have cached. It's probably be possible to
            // wipe the relay cache manually, but I cannot figure it out right
            // now. And well, this way we are sure everything is reloaded.
            const redirectTo = window.sessionStorage.getItem(REDIRECT_STORAGE_KEY) ?? "/";
            window.sessionStorage.removeItem(REDIRECT_STORAGE_KEY);
            window.location.href = redirectTo;
        } else if (response.status === 403) {
            // 403 Forbidden means the login data was incorrect
            setState("idle");
            setLoginError(t("login-page.bad-credentials"));
        } else {
            // Everything else is unexpected and should not happen.
            setState("idle");
            setLoginError(t("login-page.unexpected-response"));
        }
    };

    return (
        <div css={{
            width: 400,
            maxWidth: "100%",
            padding: 24,
            border: "1px solid var(--grey80)",
            borderRadius: 4,
        }}>
            {CONFIG.auth.loginPageNote && (
                <div css={{
                    backgroundColor: "var(--grey97)",
                    marginBottom: 32,
                    borderRadius: 4,
                    padding: "8px 16px",
                }}>{translatedConfig(CONFIG.auth.loginPageNote, i18n)}</div>
            )}

            <form
                onSubmit={handleSubmit(onSubmit)}
                noValidate
                css={{
                    "& > *:not(:last-child)": { marginBottom: 32 },
                    textAlign: "center",
                }}
            >
                <div>
                    <Field isEmpty={userid === ""}>
                        <label htmlFor="userid">
                            {CONFIG.auth.userIdLabel
                                ? translatedConfig(CONFIG.auth.userIdLabel, i18n)
                                : t("login-page.user-id")}
                        </label>
                        <input
                            id="userid"
                            autoComplete="username email"
                            required
                            autoFocus
                            {...register("userid", validation)}
                        />
                    </Field>
                    {boxError(errors.userid?.message)}
                </div>
                <div>
                    <Field isEmpty={password === ""}>
                        <label htmlFor="password">
                            {CONFIG.auth.passwordLabel
                                ? translatedConfig(CONFIG.auth.passwordLabel, i18n)
                                : t("login-page.password")}
                        </label>
                        <input
                            id="password"
                            type="password"
                            autoComplete="current-password"
                            required
                            {...register("password", validation)}
                        />
                    </Field>
                    {boxError(errors.password?.message)}
                </div>

                <Button
                    kind="happy"
                    type="submit"
                    disabled={state === "pending"}
                    extraCss={{ padding: "6px 16px" }}
                >
                    {t("user.login")}
                    {match(state, {
                        "idle": () => null,
                        "pending": () => <Spinner size={20} />,
                        "success": () => <FiCheck />,
                    })}
                </Button>

                {loginError && <div><Card kind="error" iconPos="top">{loginError}</Card></div>}
            </form>
        </div>
    );
}