theme-ui#Button JavaScript Examples

The following examples show how to use theme-ui#Button. 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: EditLink.js    From developer-portal with Apache License 2.0 6 votes vote down vote up
EditLink = ({ enterText = 'Edit This Site With TinaCMS', exitText = 'Exit Edit Mode' }) => {
  const cms = useCMS();
  return (
    <Button onClick={() => cms.toggle()}>
      <Flex sx={{ alignItems: 'center' }}>
        <Icon name={'edit'} sx={{ mr: 1 }}></Icon>
        {cms.enabled ? exitText : enterText}
      </Flex>
    </Button>
  );
}
Example #2
Source File: button-icon.js    From cards with MIT License 6 votes vote down vote up
ButtonIcon = styled(Button)`
  display: flex;
  cursor: pointer;
  background: none;
  border: 0;
  outline: 0;
  padding: 0;

  svg {
    transition: fill ${theme.transition.medium},
      stroke ${theme.transition.medium};
    stroke: ${({ color }) => color};
    fill: ${({ color }) => color};
  }

  &:hover svg {
    stroke: ${({ hoverColor }) => hoverColor};
    fill: ${({ hoverColor }) => hoverColor};
  }
`
Example #3
Source File: popup.stories.js    From proof-of-humanity-web with MIT License 5 votes vote down vote up
function Template(args) {
  return (
    <Popup trigger={<Button>Trigger</Button>} {...args}>
      Content
    </Popup>
  );
}
Example #4
Source File: price-product.js    From use-shopping-cart with MIT License 5 votes vote down vote up
PriceProduct = (product) => {
  const { addItem, redirectToCheckout } = useShoppingCart()
  const { name, price, image, currency } = product

  async function handleCheckout() {
    const response = await fetch('/.netlify/functions/prices-create-session', {
      method: 'post',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ [product.price_id]: { ...product, quantity: 1 } })
    })
      .then((res) => {
        return res.json()
      })
      .catch((error) => console.log(error))

    redirectToCheckout({ sessionId: response.sessionId })
  }

  return (
    <Flex
      sx={{
        flexDirection: 'column',
        justifyContent: 'center',
        alignItems: 'center'
      }}
    >
      <Image
        src={image}
        sx={{ width: 200, height: 200, objectFit: 'contain' }}
      />
      <Box>
        <h3>{name}</h3>
        <p>{formatCurrencyString({ value: price, currency })}</p>
      </Box>
      <Flex sx={{ flexDirection: 'column' }}>
        <Button
          onClick={() => addItem(product)}
          backgroundColor={'black'}
          marginBottom={10}
        >
          Add To Cart
        </Button>
        <Button onClick={handleCheckout} backgroundColor={'black'}>
          Buy Now
        </Button>
      </Flex>
    </Flex>
  )
}
Example #5
Source File: product.js    From use-shopping-cart with MIT License 5 votes vote down vote up
Product = (product) => {
  const { addItem, redirectToCheckout } = useShoppingCart()
  const { name, price, image, currency } = product

  async function handleCheckout() {
    const response = await fetch('/.netlify/functions/create-session', {
      method: 'post',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ [product.sku]: { ...product, quantity: 1 } })
    })
      .then((res) => {
        return res.json()
      })
      .catch((error) => console.log(error))

    redirectToCheckout({ sessionId: response.sessionId })
  }

  return (
    <Flex
      sx={{
        flexDirection: 'column',
        justifyContent: 'center',
        alignItems: 'center'
      }}
    >
      <Image
        src={image}
        sx={{ width: 200, height: 200, objectFit: 'contain' }}
      />
      <Box>
        <h3>{name}</h3>
        <p>{formatCurrencyString({ value: price, currency })}</p>
      </Box>
      <Flex sx={{ flexDirection: 'column' }}>
        <Button
          onClick={() => addItem(product)}
          backgroundColor={'black'}
          marginBottom={10}
        >
          Add To Cart
        </Button>
        <Button onClick={handleCheckout} backgroundColor={'black'}>
          Buy Now
        </Button>
      </Flex>
    </Flex>
  )
}
Example #6
Source File: pagination.js    From github-covid-finder with MIT License 5 votes vote down vote up
Pagination = ({ pageUp, pageDown, currentPage, totalResults }) => {
  const ButtonStyle = {
    cursor: 'pointer',
    width: 36,
    height: 36,
    padding: 0,
    borderRadius: 4,
    border: '1px solid',
    borderColor: 'cardBorder',
    backgroundColor: 'cardBackground',
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'center',
    fontSize: 18,
    color: 'text',
  }

  return (
    <Flex
      sx={{
        fontSize: [16, 26],
        color: 'textRreverse',
        textAlign: 'center',
        fontFamily: 'inter',
        padding: '8px',
        mt: '30px',
        alignItems: 'center',
        justifyContent: 'center',
      }}
    >
      {currentPage !== 1 && (
        <Button
          sx={{
            ...ButtonStyle,
          }}
          onClick={pageDown}
        >
          &#8592;
        </Button>
      )}
      <Text sx={{ color: 'text', px: 32, fontSize: 14 }}>
        Page {currentPage} ({totalResults} results)
      </Text>
      <Button
        sx={{
          ...ButtonStyle,
        }}
        onClick={pageUp}
      >
        &#8594;
      </Button>
    </Flex>
  )
}
Example #7
Source File: PreferencesRoute.js    From NoteMaster with GNU General Public License v3.0 4 votes vote down vote up
PreferencesRoute = ({ preferences, updatePreferences }) => {
  const history = useHistory();

  const fontFamilyChange = e => {
    updatePreferences({
      fontFamily: e.target.value,
      // HACK: If the initial content is updated to match the existing autosaveContent then the user will lose all changes
      // since the file was read from the disk into memory.
      editorContent: preferences.autosaveContent
    });
  };

  const fontSizeChange = e => {
    updatePreferences({
      fontSize: Number(e.target.value),
      // HACK: If the initial content is updated to match the existing autosaveContent then the user will lose all changes
      // since the file was read from the disk into memory.
      editorContent: preferences.autosaveContent
    });
  };

  const fontWeightChange = e => {
    updatePreferences({
      fontWeight: e.target.value,
      // HACK: If the initial content is updated to match the existing autosaveContent then the user will lose all changes
      // since the file was read from the disk into memory.
      editorContent: preferences.autosaveContent
    });
  };

  const lineHeightChange = e => {
    updatePreferences({
      lineHeight: Number(e.target.value),
      // HACK: If the initial content is updated to match the existing autosaveContent then the user will lose all changes
      // since the file was read from the disk into memory.
      editorContent: preferences.autosaveContent
    });
  };

  const lineNumbersChange = e => {
    updatePreferences({
      lineNumbers: e.target.value,
      // HACK: If the initial content is updated to match the existing autosaveContent then the user will lose all changes
      // since the file was read from the disk into memory.
      editorContent: preferences.autosaveContent
    });
  };

  const autoLaunchChange = e => {
    updatePreferences({
      autoLaunch: e.target.value === 'true',
      // HACK: If the initial content is updated to match the existing autosaveContent then the user will lose all changes
      // since the file was read from the disk into memory.
      editorContent: preferences.autosaveContent
    });
  };

  const nmlEnabledChange = e => {
    updatePreferences({
      nmlEnabled: e.target.value === 'true',
      // HACK: If the initial content is updated to match the existing autosaveContent then the user will lose all changes
      // since the file was read from the disk into memory.
      editorContent: preferences.autosaveContent
    });
  };

  const fontLigaturesChange = e => {
    updatePreferences({
      fontLigatures: e.target.value === 'true',
      // HACK: If the initial content is updated to match the existing autosaveContent then the user will lose all changes
      // since the file was read from the disk into memory.
      editorContent: preferences.autosaveContent
    });
  };

  const nmlBaseCurrencyChange = e => {
    updatePreferences({
      nmlBaseCurrency: e.target.value,
      // HACK: If the initial content is updated to match the existing autosaveContent then the user will lose all changes
      // since the file was read from the disk into memory.
      editorContent: preferences.autosaveContent
    });
  };

  const wrappingIndentChange = e => {
    updatePreferences({
      wrappingIndent: e.target.value,
      // HACK: If the initial content is updated to match the existing autosaveContent then the user will lose all changes
      // since the file was read from the disk into memory.
      editorContent: preferences.autosaveContent
    });
  };

  const editorThemeChange = e => {
    updatePreferences({
      editorTheme: e.target.value,
      // HACK: If the initial content is updated to match the existing autosaveContent then the user will lose all changes
      // since the file was read from the disk into memory.
      editorContent: preferences.autosaveContent
    });
  };

  const navigateToNotes = e => {
    updatePreferences({
      editorContent: preferences.autosaveContent
    });

    history.push('/');
  };

  const {
    editorTheme,
    fontFamily,
    fontSize,
    fontWeight,
    lineNumbers,
    lineHeight,
    fontLigatures,
    autoLaunch,
    nmlEnabled,
    nmlBaseCurrency,
    wrappingIndent
  } = preferences;

  const renderNmlOptions = () => {
    return (
      <Box
        className={
          nmlEnabled ? styles.smartOptionsActive : styles.smartOptionsHidden
        }
        mb="2"
      >
        <Flex mt="3">
          <Box sx={{ flex: '1 1 auto' }}>
            <TooltipComponent content="Set this value to your most commonly used currency. The default is: USD.">
              <Label mt="2" variant="labelTooltip">
                Base Currency
              </Label>
            </TooltipComponent>
          </Box>
          <Box>
            <Select
              disabled={!nmlEnabled}
              defaultValue={nmlBaseCurrency}
              onChange={nmlBaseCurrencyChange}
            >
              <option value="USD">USD</option>
              <option value="GBP">GBP</option>
              <option value="EUR">EUR</option>
            </Select>
          </Box>
        </Flex>
      </Box>
    );
  };

  return (
    <div className={styles.container} data-tid="container">
      <div className={styles.header}>
        <TitlebarComponent />
      </div>
      <div className={styles.preferences}>
        <ContainerComponent padding="0 8px 0 0">
          <Button variant="linkUpper" mb="0" onClick={navigateToNotes}>
            <i className="ri-arrow-left-line" /> Return to Notes
          </Button>
        </ContainerComponent>
        <ScrollableContentComponent>
          <ContainerComponent padding="0 8px 0 0">
            <Heading mt="0" as="h1">
              Preferences
            </Heading>
            <Text mt="1" mb="3" variant="muted">
              Customize NoteMaster to your desire. You can request features on{' '}
              <Link
                href="https://github.com/LiamRiddell/NoteMaster"
                target="_blank"
                rel="noreferer"
              >
                NoteMaster GitHub
              </Link>
              .
            </Text>

            {/* Editor */}
            <Box mb="4">
              <Text mb="2" variant="group">
                Editor
              </Text>

              <Flex mt="3">
                <Box sx={{ flex: '1 1 auto' }}>
                  <TooltipComponent content="When enabled, NoteMaster Smart Mode automatically recognizes keywords, and intelligently provides results as you type. The default is: Enabled.">
                    <Label mt="2" variant="labelTooltip">
                      Smart Mode
                    </Label>
                  </TooltipComponent>
                </Box>
                <Box>
                  <Select
                    defaultValue={nmlEnabled ? 'true' : 'false'}
                    onChange={nmlEnabledChange}
                  >
                    <option value="true">Enabled</option>
                    <option value="false">Disabled</option>
                  </Select>
                </Box>
              </Flex>

              {/* NoteMaster Language */}
              {renderNmlOptions()}

              {/* Line Numbers */}
              <Flex mt="3">
                <Box sx={{ flex: '1 1 auto' }}>
                  <TooltipComponent content="When enabled, line numbers will be displayed on the left side of the editor. The default is: Off.">
                    <Label mt="2" variant="labelTooltip">
                      Line Numbers
                    </Label>
                  </TooltipComponent>
                </Box>
                <Box>
                  <Select
                    defaultValue={lineNumbers}
                    onChange={lineNumbersChange}
                  >
                    <option value="off">Off</option>
                    <option value="on">On</option>
                    <option value="relative">Relative</option>
                    <option value="interval">Interval</option>
                  </Select>
                </Box>
              </Flex>

              {/* Text Wrap Indentation */}
              <Flex mt="3">
                <Box sx={{ flex: '1 1 auto' }}>
                  <TooltipComponent content="This effects how long sentences wrap onto a new line. The default is: Same.">
                    <Label mt="2" variant="labelTooltip">
                      Text Wrap Indent
                    </Label>
                  </TooltipComponent>
                </Box>
                <Box>
                  <Select
                    defaultValue={wrappingIndent}
                    onChange={wrappingIndentChange}
                  >
                    <option value="same">Same</option>
                    <option value="indent">Indent</option>
                    <option value="deepIndent">Deep Indent</option>
                    <option value="none">None</option>
                  </Select>
                </Box>
              </Flex>

              {/* Editor Theme */}
              <Flex mt="3">
                <Box sx={{ flex: '1 1 auto' }}>
                  <TooltipComponent content="Using the Dark theme will enable rich text highlighting, which compliments Smart Mode. Use Dark Basic, if you find the rich text highlighting distrating. The default is: Dark.">
                    <Label mt="2" variant="labelTooltip">
                      Theme
                    </Label>
                  </TooltipComponent>
                </Box>
                <Box>
                  <Select
                    defaultValue={editorTheme}
                    onChange={editorThemeChange}
                  >
                    <option value="notemaster-dark-nml-enabled">Dark</option>
                    <option value="notemaster-dark-nml-disabled">
                      Dark Basic
                    </option>
                  </Select>
                </Box>
              </Flex>
            </Box>

            {/* Typography Settings */}
            <Box mb="4">
              <Text mb="2" variant="group">
                Typography
              </Text>

              {/* Font */}
              <Flex mt="3">
                <Box sx={{ flex: '1 1 auto' }}>
                  <TooltipComponent content="Changes the font within the editor. The default is: Roboto.">
                    <Label mt="2" variant="labelTooltip">
                      Font
                    </Label>
                  </TooltipComponent>
                </Box>
                <Box>
                  <Select defaultValue={fontFamily} onChange={fontFamilyChange}>
                    <option value="Roboto">Roboto</option>
                    <option value="Arial">Arial</option>
                    <option value="Helvetica Neue">Helvetica Neue</option>
                    <option value="Monospace">Monospace</option>
                    <option value="Ubuntu">Ubuntu</option>
                    <option value="Segoe UI">Segoe UI</option>
                  </Select>
                </Box>
              </Flex>

              {/* Font Size */}
              <Flex mt="3">
                <Box sx={{ flex: '1 1 auto' }}>
                  <TooltipComponent content="You can adjust the font size within the editor. The default is: 16.">
                    <Label mt="2" variant="labelTooltip">
                      Font Size
                    </Label>
                  </TooltipComponent>
                </Box>
                <Box>
                  <Input
                    type="number"
                    defaultValue={fontSize}
                    onChange={fontSizeChange}
                    sx={{ width: '72px' }}
                  />
                </Box>
              </Flex>

              {/* Font Weight */}
              <Flex mt="3">
                <Box sx={{ flex: '1 1 auto' }}>
                  <TooltipComponent content="Changes the font thickness within the editor. The default is: Regular.">
                    <Label mt="2" variant="labelTooltip">
                      Font Weight
                    </Label>
                  </TooltipComponent>
                </Box>
                <Box>
                  <Select defaultValue={fontWeight} onChange={fontWeightChange}>
                    <option value="100">Thin</option>
                    <option value="200">Extra Light</option>
                    <option value="300">Light</option>
                    <option value="400">Regular</option>
                    <option value="500">Medium</option>
                    <option value="600">Semi-Bold</option>
                    <option value="700">Bold</option>
                    <option value="800">Extra Bold</option>
                    <option value="900">Black</option>
                  </Select>
                </Box>
              </Flex>

              {/* Line Height */}
              <Flex mt="3">
                <Box sx={{ flex: '1 1 auto' }}>
                  <TooltipComponent content="Change the line height within the editor. The default is: 24.">
                    <Label mt="2" variant="labelTooltip">
                      Line Height
                    </Label>
                  </TooltipComponent>
                </Box>
                <Box>
                  <Input
                    type="number"
                    defaultValue={lineHeight}
                    onChange={lineHeightChange}
                    sx={{ width: '72px' }}
                  />
                </Box>
              </Flex>

              {/*
              <Label mt="2" mb="1">
                Font Ligatures
              </Label>
              <Select
                defaultValue={fontLigatures ? 'true' : 'false'}
                onChange={fontLigaturesChange}
              >
                <option value="true">On</option>
                <option value="false">Off</option>
              </Select> */}
            </Box>

            {/* System */}
            <Box mb="4">
              <Text mb="2" variant="group">
                SYSTEM
              </Text>

              {/* Auto Launch */}
              <Flex mt="3">
                <Box sx={{ flex: '1 1 auto' }}>
                  <TooltipComponent content="When enabled, NoteMaster will be launched on startup. The default is: On.">
                    <Label mt="2" variant="labelTooltip">
                      Auto Launch
                    </Label>
                  </TooltipComponent>
                </Box>
                <Box>
                  <Select
                    defaultValue={autoLaunch ? 'true' : 'false'}
                    onChange={autoLaunchChange}
                  >
                    <option value="false">Off</option>
                    <option value="true">On</option>
                  </Select>
                </Box>
              </Flex>
            </Box>

            {/* Creation Rights */}
            <Box
              p={3}
              color="text"
              bg="#27292C"
              mb="1"
              sx={{ borderRadius: 3 }}
            >
              Thank you for downloading NoteMaster, an open-source project
              created and maintained by{' '}
              <Link href="https://github.com/LiamRiddell" target="_blank">
                Liam Riddell
              </Link>{' '}
              ❤️
            </Box>
          </ContainerComponent>
        </ScrollableContentComponent>
      </div>
    </div>
  );
}
Example #8
Source File: cart-display.js    From use-shopping-cart with MIT License 4 votes vote down vote up
CartDisplay = () => {
  const {
    cartDetails,
    cartCount,
    formattedTotalPrice,
    redirectToCheckout,
    clearCart,
    setItemQuantity
  } = useShoppingCart()

  async function handleSubmit(event) {
    event.preventDefault()

    const response = await fetch('/.netlify/functions/create-session', {
      method: 'post',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(cartDetails)
    })
      .then((res) => res.json())
      .catch((error) => console.log(error))

    redirectToCheckout({ sessionId: response.sessionId })
  }

  async function handleCheckout(event) {
    event.preventDefault()

    const response = await fetch('/.netlify/functions/redirect-to-checkout', {
      method: 'post',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(cartDetails)
    })
      .then((res) => res.json())
      .catch((error) => console.log(error))

    console.log('Checkout result:', response)
  }

  if (cartCount === 0) {
    return (
      <Flex
        sx={{
          textAlign: 'center',
          flexDirection: 'column',
          alignItems: 'center'
        }}
      >
        <h2>Shopping Cart Display Panel</h2>
        <p style={{ maxWidth: 300 }}>
          You haven't added any items to your cart yet. That's a shame.
        </p>
      </Flex>
    )
  } else {
    return (
      <Flex
        sx={{
          flexDirection: 'column'
        }}
      >
        <h2>Shopping Cart Display Panel</h2>
        {Object.keys(cartDetails).map((sku, index) => {
          const { name, quantity, image } = cartDetails[sku]
          return (
            <Flex
              key={sku}
              sx={{
                flexDirection: 'column',
                width: '100%',
                marginBottom: 25,
                paddingLeft: 20
              }}
            >
              <Flex sx={{ alignItems: 'center' }}>
                <Image
                  sx={{ width: 50, height: 'auto', marginRight: 10 }}
                  src={image}
                />
                <p>{name}</p>
              </Flex>
              <Input
                type={'number'}
                max={99}
                sx={{ width: 60 }}
                value={quantity}
                onChange={(event) => {
                  setItemQuantity(sku, event.target.valueAsNumber)
                }}
              />
            </Flex>
          )
        })}
        <Box>
          <p aria-live="polite" aria-atomic="true">
            Total Item Count: {cartCount}
          </p>
          <p aria-live="polite" aria-atomic="true">
            Total Price: {formattedTotalPrice}
          </p>
        </Box>
        <Button
          sx={{ backgroundColor: 'black' }}
          marginBottom={10}
          onClick={handleSubmit}
        >
          Checkout
        </Button>
        <Button
          sx={{ backgroundColor: 'black' }}
          marginBottom={10}
          onClick={() => clearCart()}
        >
          Clear Cart Items
        </Button>
        <Button sx={{ backgroundColor: 'black' }} onClick={handleCheckout}>
          Redirect To Checkout
        </Button>
      </Flex>
    )
  }
}
Example #9
Source File: header.js    From github-covid-finder with MIT License 4 votes vote down vote up
Header = ({ isShowSearch, searchCompProps, toggleModal }) => {
  const [colorMode, setColorMode] = useColorMode()
  return (
    <Box
      sx={{
        borderBottom: "1px solid",
        borderColor: 'cardBorder',
        marginBottom: '24px'
      }}>
      <Flex
        as="header"
        sx={{
          height: '120px',
          alignItems: 'center',
          justifyContent: 'space-between',
          margin: '0 auto',
          maxWidth: ['100%', '768px', '992px', '1400px'],
          px: '15px',
        }}
      >
        <Flex
          sx={{
            flex: 1,
            alignItems: 'center',
          }}
        >
          <Text
            sx={{
              fontSize: '24px',
              color: 'white',
              fontFamily: 'inter',
              textAlign: 'center',
            }}
          >
            <Link to="/" style={{ display: 'block', lineHeight: 0 }} >
              <Image style={{ fill: '#FF4136', width: 180 }} src={colorMode === 'dark' ? logoWhite : logoBlack} />
            </Link>
          </Text>
          { isShowSearch &&
            <Box
              sx={{
                width: '76%',
                margin: '16px 16px 0px 16px',
                '@media only screen and (max-width: 916px)': {
                  marginTop: 0,
                  width: 'auto',
                  display: 'flex',
                  justifyContent: 'flex-end',
                  margin: '0px 16px 0px auto',
                },
                '@media only screen and (max-width: 320px)': {
                  margin: '0px 6px',
                },
              }}
            >
              <Box
                sx={{
                  '@media only screen and (max-width: 916px)': {
                    display: 'none',
                  },
                }}
              >
                <Search {...searchCompProps}/>
              </Box>
              <Button
                name="toggle-modal-with-search"
                onClick={toggleModal}
                backgroundColor="rgb(157, 31, 30)"
                sx={{
                  padding: '6px 12px',
                  '@media only screen and (min-width: 916px)': {
                    display: 'none',
                  },
                }}
              >
                <SearchIcon
                  style={{
                    width: 16,
                    height: 16,
                  }}
                />
              </Button>
            </Box>
          }
        </Flex>
        <Flex
          sx={{
            alignItems: 'center',
            justifyContent: 'space-between',
            '@media only screen and (min-width: 916px)': {
              marginBottom: 9,
            },
          }}
        >
          <Link to="/about">
            <Text
              sx={{
                fontSize: '16px',
                color: 'text',
                fontFamily: 'inter',
                textAlign: 'center',
                mr: '1em'
              }}
            >
              About
          </Text>
          </Link>
          <a href="https://github.com/luisFilipePT/github-covid-finder" target="_blank" rel="noopener noreferrer">
            <Text sx={{color: 'text', marginTop: '4px'}}>
              <GithubIcon />
            </Text>
          </a>
          <Button sx={{
            fontFamily: 'inter',
            marginLeft: '24px',
            cursor: 'pointer'
          }} 
          variant='selectTheme'
          onClick={e => {
            setColorMode(colorMode === 'default' ? 'dark' : 'default')
          }}>
            {colorMode === 'default' ? 'Dark' : 'Light'}
          </Button>
        </Flex>
      </Flex>
    </Box>
  )
}
Example #10
Source File: index.js    From github-covid-finder with MIT License 4 votes vote down vote up
Index = () => {
  const refSearch = useRef(null)
  const [repos, setRepos] = useState(null)
  const [totalResults, setTotalResults] = useState(null)
  const [isFetchingData, setIsFetchingData] = useState(true)
  const [isShowModal, setIsShowModal] = useState(false)
  const [searchState, dispatch] = useReducer(reducer, INITIAL_STATE)
  const previousSearchState = usePrevious({ ...searchState })
  const [colorMode, _setColorMode] = useColorMode()

  useEffect(() => {
    const fetchDataAndSetState = async () => {
      const data = await fetchData(searchState)

      if (data) {
        setRepos(data)
        setTotalResults(data.total_count)
      }

      setIsFetchingData(false)
    }

    // Avoid request while developing
    if (process.env.NODE_ENV === 'development') {
      setRepos(mockRepos)
      setIsFetchingData(false)
      return
    }

    fetchDataAndSetState()
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [searchState])

  const onSearchChange = field => e => {
    if (searchState.page * 30 < totalResults && field === 'pageUp') {
      scrollTo('#wrapper')
      dispatch({ type: field, payload: searchState.page + 1 })
      return
    }

    if (searchState.page > 1 && field === 'pageDown') {
      scrollTo('#wrapper')
      dispatch({ type: field, payload: searchState.page - 1 })
      return
    }
  }

  const onSearchIconClick = async (input, stars, language) => {
    dispatch({ type: 'search', payload: input })
    dispatch({ type: 'sort', payload: stars })
    dispatch({ type: 'filter', payload: language })

    if (
      previousSearchState.term === searchState.term &&
      previousSearchState.sort === searchState.sort &&
      previousSearchState.filter === searchState.filter
    ) {
      return
    }

    setIsFetchingData(true)

    if (isShowModal) {
      setIsShowModal(false)
    }

    const data = await fetchData(searchState)

    if (data) {
      setRepos(data)
      setTotalResults(data.total_count)
    }

    setIsFetchingData(false)
  }

  const toggleModal = () => {
    setIsShowModal(!isShowModal)
  }

  const searchCompProps = {
    searchState,
    onSearchIconClick,
    onSortChange: onSearchChange('sort'),
    onSearchChange: onSearchChange('search'),
    onFilterChange: onSearchChange('filter'),
  }

  return (
    <>
      <Layout
        isShowSearch
        isShowModal={isShowModal}
        toggleModal={toggleModal}
        searchCompProps={searchCompProps}
      >
        <SEO />
        <span id="wrapper" ref={refSearch} />
        {isFetchingData ? (
          <Spinner
            color="rgb(255, 65, 54)"
            sx={{
              top: '50%',
              left: '50%',
              position: 'absolute',
              transform: 'translate(-50%, -50%)',
            }}
          />
        ) : repos.items.length > 0 ? (
          <>
            <Grid columns={[1, 1, 1, 3]}>
              {repos.items.map(repo => (
                <RepoCard key={repo.id} repo={repo} />
              ))}
            </Grid>
            <Pagination
              pageUp={onSearchChange('pageUp')}
              pageDown={onSearchChange('pageDown')}
              currentPage={searchState.page}
              totalResults={totalResults}
            />
          </>
        ) : (
          <Box
            sx={{
              top: '50%',
              left: '50%',
              position: 'absolute',
              transform: 'translate(-50%, -50%)',
            }}
          >
            <Text
              sx={{
                fontSize: 22,
                fontFamily: 'inter',
              }}
            >
              No result found
            </Text>
          </Box>
        )}
      </Layout>
      <Flex id="modal" className={isShowModal ? 'active' : null}>
        <Flex
          p="16px"
          bg={
            colorMode === 'dark'
              ? 'rgba(64,64,64,0.9)'
              : 'rgba(255,255,255,0.7)'
          }
          sx={{
            maxWidth: 660,
            margin: 'auto',
            borderRadius: 6,
            alignItems: 'flex-end',
            flexDirection: 'column',
            '@media only screen and (max-width: 425px)': {
              width: 360,
            },
            '@media only screen and (max-width: 320px)': {
              width: 300,
            },
          }}
        >
          <Search {...searchCompProps} />
          <Button
            mt="8px"
            backgroundColor="rgb(186, 65, 54)"
            onClick={toggleModal}
            sx={{
              fontFamily: 'inter',
            }}
          >
            Close
          </Button>
        </Flex>
      </Flex>
    </>
  )
}
Example #11
Source File: Feedback.js    From developer-portal with Apache License 2.0 4 votes vote down vote up
Feedback = ({ route, cms, mobile }) => {
  const ref = useRef(null);
  const rcRef = useRef(null);

  const [reaction, setReaction] = useState(null);

  const isNegative = reaction === 'negative';
  const isPositive = reaction === 'positive';
  const isSubmitted = reaction === 'submitted';

  const { title, placeholder } = isNegative
    ? {
        title: mobile ? 'sorryMobile' : 'sorry',
        placeholder: 'Please let us know how we can improve it.',
      }
    : isPositive
    ? {
        title: mobile ? 'gladMobile' : 'glad',
        placeholder: 'Please let us know how we can make it even better.',
      }
    : isSubmitted
    ? { title: mobile ? 'thanksMobile' : 'thanks' }
    : { title: mobile ? 'helpfulMobile' : 'helpful' };

  const sendFeedback = useCallback(async () => {
    const markdown = constructMarkdownString(reaction, rcRef.current?.value, ref.current?.value);

    try {
      const response = await fetch(process.env.FEEDBACK_ENDPOINT || '/api/feedback', {
        body: JSON.stringify({
          reaction,
          comment: markdown,
          tags: ['feedback', window.location.pathname],
        }),
        headers: {
          'Content-Type': 'application/json',
        },
        method: 'POST',
        credentials: 'same-origin',
        referrerPolicy: 'no-referrer',
      });

      if (!response.ok) {
        throw Error(response.statusText);
      }

      cms.alerts.success('Your feedback has been submitted');
      setReaction('submitted');
    } catch (err) {
      console.error(err);
      cms.alerts.error('there was an error in submitting your feedback');
    }
  }, [reaction, cms.alerts]);

  useEffect(() => {
    setReaction(null);
  }, [route]);

  return (
    <Card
      sx={{
        bg: 'background',
        border: 'light',
        borderColor: 'muted',
        borderRadius: 'small',
        width: '100%',
      }}
    >
      <Flex sx={{ justifyContent: 'space-between', alignItems: 'center' }}>
        <Flex sx={{ alignItems: 'center' }}>
          <Icon
            sx={{ mr: 2 }}
            color="primary"
            size="auto"
            height="20px"
            width="20px"
            name="document"
          ></Icon>
          <Heading variant="smallHeading">
            <InlineText name={title} />
          </Heading>
        </Flex>
        {isSubmitted ? (
          <Flex
            sx={{
              alignItems: 'center',
              justifyContent: 'center',
              bg: 'primary',
              size: 4,
              borderRadius: 'round',
              ml: 'auto',
            }}
          >
            <Icon name="checkmark" size="3" />
          </Flex>
        ) : (
          <Grid columns={2}>
            <Button
              variant="contrastButtonSmall"
              sx={{
                bg: isPositive ? 'primary' : undefined,
                color: isPositive ? 'onPrimary' : undefined,
                minWidth: 42,
              }}
              onClick={() => setReaction('positive')}
            >
              Yes
            </Button>
            <Button
              variant="contrastButtonSmall"
              sx={{
                bg: isNegative ? 'primary' : undefined,
                color: isNegative ? 'onPrimary' : undefined,
                minWidth: 42,
              }}
              onClick={() => setReaction('negative')}
            >
              No
            </Button>
          </Grid>
        )}
      </Flex>
      {(isNegative || isPositive) && (
        <Flex sx={{ flexDirection: 'column', alignItems: 'flex-start' }}>
          <Text sx={{ fontWeight: 'body', mb: 2, mt: 3 }} variant="caps">
            FEEDBACK
          </Text>
          <Textarea
            aria-label="Feedback textarea"
            ref={ref}
            placeholder={placeholder}
            sx={{
              mb: 2,
              bg: 'surface',
              borderColor: 'muted',
              fontSize: 3,
            }}
          ></Textarea>
          <Text sx={{ fontWeight: 'body', mb: 2, mt: 3 }} variant="caps">
            ROCKET CHAT HANDLE (OPTIONAL)
          </Text>
          <Flex sx={{ justifyContent: 'space-between', width: '100%' }}>
            <Input
              sx={{
                mr: 3,
                fontFamily: 'body',
                fontSize: 3,
                bg: 'surface',
                borderColor: 'muted',
                width: ['66%', '100%'],
              }}
              type="email"
              aria-label="Feedback handle"
              placeholder="Enter your Rocket Chat handle if you would like to be in contact."
              ref={rcRef}
            ></Input>
            <Button
              sx={{ px: [2, 4], width: ['33%', 'initial'] }}
              variant="small"
              onClick={sendFeedback}
            >
              Submit
            </Button>
          </Flex>
          <Flex sx={{ pt: 3, flexWrap: 'wrap' }}>
            <Text sx={{ color: 'onBackgroundMuted', pr: 3 }}>
              <InlineText name="additional" />
            </Text>
            <ThemeLink href={'https://chat.makerdao.com/channel/dev'} target="_blank">
              <Flex sx={{ alignItems: 'center' }}>
                <Icon sx={{ mr: 2 }} color="primary" name="chat"></Icon>
                <Text
                  sx={{
                    color: 'text',
                    cursor: 'pointer',
                    '&:hover': {
                      color: 'primaryEmphasis',
                    },
                  }}
                >
                  chat.makerdao.com
                </Text>
              </Flex>
            </ThemeLink>
          </Flex>
        </Flex>
      )}
    </Card>
  );
}
Example #12
Source File: NewsletterCallout.js    From developer-portal with Apache License 2.0 4 votes vote down vote up
NewsletterCallout = () => {
  const { inputEl, subscribe, loading, success, errorMessage } = useEmailSubscribe();
  return (
    <Container sx={{ display: 'flex', justifyContent: 'center', pb: 6 }}>
      <Grid gap={3}>
        <Heading sx={{ display: 'flex', justifyContent: 'center' }} variant="mediumHeading">
          Want Maker dev updates dripping into your inbox?
        </Heading>
        <Flex sx={{ flexDirection: 'column', justifyContent: 'center' }}>
          <Text variant="plainText" sx={{ alignSelf: 'center' }}>
            <InlineTextarea name="devUpdatesSubtext1" />
          </Text>
          <Text sx={{ alignSelf: 'center', pb: 3 }} variant="plainText">
            <InlineTextarea name="devUpdatesSubtext2" />
          </Text>
        </Flex>
        {success ? (
          <Card sx={{ p: 4 }}>
            <Flex sx={{ flexDirection: 'column', alignItems: 'center', position: 'relative' }}>
              <Flex
                sx={{
                  position: 'absolute',
                  top: '-50px',
                  alignItems: 'center',
                  justifyContent: 'center',
                  bg: 'primary',
                  size: '40px',
                  borderRadius: 'round',
                  mx: 2,
                }}
              >
                <Icon name="checkmark" size="3" />
              </Flex>
              <Text variant="plainText" sx={{ fontWeight: 'bold', fontSize: 4 }}>
                Thank you for signing up!
              </Text>
              <Text variant="plainText" sx={{ fontSize: 2 }}>
                Stay tuned, you will get dev updates soon.
              </Text>
            </Flex>
          </Card>
        ) : (
          <>
            <Flex sx={{ flexDirection: 'column' }}>
              <Flex sx={{ justifyContent: 'center' }}>
                <Input
                  aria-label="Email for newsletter"
                  ref={inputEl}
                  type="email"
                  placeholder="Email"
                  disabled={loading}
                  sx={{
                    fontFamily: 'heading',
                    fontSize: 5,
                    bg: 'onBackground',
                    borderColor: 'onBackground',
                    borderRadius: (theme) =>
                      `${theme.radii.small}px 0px 0px ${theme.radii.small}px`,
                    pl: 4,
                    '&:focus': {
                      color: 'background',
                    },
                  }}
                ></Input>
                <Button
                  disabled={loading}
                  onClick={subscribe}
                  sx={{
                    borderColor: 'primary',
                    borderRadius: (theme) =>
                      `0px ${theme.radii.small}px ${theme.radii.small}px 0px`,
                    py: 2,
                    width: 7,
                    fontSize: 5,
                  }}
                >
                  Sign up
                </Button>
              </Flex>
              {errorMessage && (
                <Text variant="plainText" sx={{ py: 2, px: 4, fontSize: 1, color: 'primary' }}>
                  {errorMessage}
                </Text>
              )}
            </Flex>
          </>
        )}
      </Grid>
    </Container>
  );
}
Example #13
Source File: section.js    From medusa with MIT License 4 votes vote down vote up
Section = ({ data, api }) => {
  const section = data;
  const [isExpanded, setIsExpanded] = useState(false)
  const { openSections, updateSection, updateMetadata, updateHash } = useContext(
    NavigationContext
  )

  const endpoints = section.paths
    .map((p) => {
      let path = p.name
      let ep = []

      p.methods.forEach((m) => {
        ep.push({ method: m.method, endpoint: path })
      })

      return ep
    })
    .flat()

  const sectionRef = useRef(null)

  const scrollIntoView = () => {
    if (sectionRef.current) {
      sectionRef.current.scrollIntoView({
        behavior: "smooth",
      })
    }
  }

  const handleExpand = () => {
    updateMetadata({
      title: section.section_name,
      description: section.schema?.description,
    })
    setIsExpanded(true)
    scrollIntoView()
  }

  useEffect(() => {
    const shouldOpen = openSections.includes(
      convertToKebabCase(section.section_name)
    )

    if (shouldOpen) {
      setIsExpanded(true)
    }
  }, [section.section_name, openSections, openSections.length])

  useEffect(() => {
    if (section.section_name) {
      updateHash(convertToKebabCase(section.section_name), section.paths && section.paths.length ? (section.paths[0].methods[0].path || '') : '', section)
    }
  }, [section.section_name])

  const [containerRef, isInView] = useInView({
    root: null,
    rootMargin: "0px 0px -80% 0px",
    threshold: 1.0,
  })

  useEffect(() => {
    const handleInView = () => {
      if (isInView) {
        updateSection({id: convertToKebabCase(section.section_name), section})
      }
    }
    handleInView()
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [isInView])

  return (
    <section ref={sectionRef} id={convertToKebabCase(section.section_name)}>
      <Box
        sx={{
          borderBottom: "hairline",
          padding: "5vw",
          backgroundColor: isExpanded ? "transparent" : "fadedContrast",
        }}
      >
        <Flex>
          <Heading
            as="h1"
            sx={{
              fontWeight: "500",
              fontSize: "22",
              mb: "3",
              cursor: "pointer",
            }}
            ref={containerRef}
            className={`header-${convertToKebabCase(section.section_name)}`}
            onClick={handleExpand}
          >
            {section.section_name}
          </Heading>
        </Flex>
        <Flex
          sx={{
            flexDirection: "column",
          }}
        >
          <ResponsiveContainer>
            <Flex
              sx={{
                flexDirection: "column",
                lineHeight: "26px",
                pr: "5",
                "@media screen and (max-width: 848px)": {
                  pr: "0",
                },
              }}
              className="info"
            >
              <Description>
                <Text mb={4}>
                  <Markdown>{section.schema?.description}</Markdown>
                </Text>
              </Description>
              {isExpanded && section.schema ? (
                <Parameters params={section.schema} type={"attr"} />
              ) : null}
            </Flex>
            <Flex
              className="code"
              sx={{
                flexDirection: "column",
              }}
            >
              <EndpointContainer endpoints={endpoints} />
              {isExpanded ? (
                <JsonContainer
                  json={section.schema?.object}
                  header={`${section.section_name.toUpperCase()} OBJECT`}
                />
              ) : null}
            </Flex>
          </ResponsiveContainer>
          {!isExpanded && (
            <Flex
              sx={{
                justifyContent: "center",
                alignItems: "center",
                width: "100%",
              }}
              mt={4}
            >
              <Button
                onClick={handleExpand}
                sx={{
                  display: "flex",
                  alignItems: "center",
                  borderRadius: "24px",
                  bg: "light",
                  fontWeight: "500",
                }}
              >
                SHOW <ChevronDown fill={"dark"} styles={{ mr: "-10px" }} />
              </Button>
            </Flex>
          )}
          <Box
            id="method-container"
            mt={4}
            sx={{
              display: isExpanded ? "block" : "none",
            }}
          >
            {section.paths.map((p, i) => {
              return (
                <Flex
                  key={i}
                  sx={{
                    flexDirection: "column",
                  }}
                >
                  {p.methods.map((m, i) => {
                    return (
                      <Method
                        api={api}
                        key={i}
                        data={m}
                        section={convertToKebabCase(section.section_name)}
                        sectionData={section}
                        pathname={p.name}
                      />
                    )
                  })}
                </Flex>
              )
            })}
          </Box>
        </Flex>
      </Box>
    </section>
  )
}