theme-ui#Grid TypeScript Examples

The following examples show how to use theme-ui#Grid. 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: layout.tsx    From desktop with MIT License 6 votes vote down vote up
export function Layout({ children }: IProps): JSX.Element {
  return (
    <Grid
      css={{
        height: `100vh`,
        width: `100vw`,
        gridTemplateRows: `34px 1fr`,
      }}
      gap={0}
    >
      <TabNavigation />
      {children}
    </Grid>
  )
}
Example #2
Source File: onboarding.tsx    From slice-machine with Apache License 2.0 6 votes vote down vote up
OnboardingGrid: React.FunctionComponent = ({ children }) => {
  return (
    <Grid
      sx={{
        width: "100vw",
        height: "100vh",
        gridGap: "1rem",
        gridTemplateAreas: `
          "top-left header top-right"
          "... content ..."
          "footer-left footer footer-right"
        `,
        gridTemplateRows: "84px 5fr 1fr",
      }}
      columns="1fr 2fr 1fr"
    >
      {children}
    </Grid>
  );
}
Example #3
Source File: onboarding.tsx    From slice-machine with Apache License 2.0 6 votes vote down vote up
StepIndicator = ({
  current,
  maxSteps,
}: {
  current: number;
  maxSteps: number;
}) => {
  const columns = Array(maxSteps).fill(1);
  return (
    <Box sx={{ width: "40%" }}>
      <Grid gap={2} columns={maxSteps}>
        {columns.map((_, i) => (
          <Box
            key={`box-${i + 1}`}
            sx={{
              bg: i <= current ? "primary" : "muted",
              borderRadius: "10px",
              height: "2px",
            }}
          />
        ))}
      </Grid>
    </Box>
  );
}
Example #4
Source File: ContractDetails.tsx    From nft-market with MIT License 6 votes vote down vote up
ContractDetails = () => {
  const { contractDetails } = useAppState()
  return (
    <Box>
      <Heading as="h1">NFT Contract Details</Heading>
      <Grid my={3}>
        {contractDetails &&
          Object.keys(contractDetails).map(a => (
            <Text key={a}>
              {a}:{' '}
              <Text variant="text.bold" as="span">
                {contractDetails[a as keyof ContractPropsDetails]}
              </Text>
            </Text>
          ))}
      </Grid>
    </Box>
  )
}
Example #5
Source File: editors-radio-button.tsx    From desktop with MIT License 5 votes vote down vote up
export function EditorsRadioButton({
  name,
  editors,
  onChange,
  required,
  error,
  selected = ``,
}: IProps): JSX.Element {
  const {
    getLegendProps,
    getOptionLabelProps,
    getOptionControlProps,
    errorProps,
  } = useAriaFormGroupField(`editors-radio-button`, {
    required: required,
    error,
  })

  return (
    <FormFieldset>
      <FormLegend
        css={visuallyHiddenCss}
        {...getLegendProps(`Please select your preferred code editor`)}
      />
      <Grid columns={[null, 1, 1, `repeat(auto-fit, 300px)`]} gap={7}>
        {editors.map((editor) => {
          const optionValue = editor

          return (
            <GroupInputCard
              key={editor}
              {...getOptionLabelProps(optionValue)}
              input={
                <StyledRadioButton
                  {...getOptionControlProps(optionValue)}
                  value={optionValue}
                  onChange={onChange}
                  name={name}
                  checked={editor === selected}
                />
              }
            >
              <Flex sx={{ alignItems: `center` }}>
                <img src={editorLogos[editor]} alt="" sx={{ mr: 5 }} />
                {editorLabels[editor]}
              </Flex>
            </GroupInputCard>
          )
        })}
      </Grid>
      <FormError {...errorProps} />
    </FormFieldset>
  )
}
Example #6
Source File: sites-checkbox-group.tsx    From desktop with MIT License 5 votes vote down vote up
export function SiteCheckboxGroup({
  name,
  sites,
  required,
  error,
  hiddenSites = [],
  setHiddenSites,
  browseSites,
}: IProps): JSX.Element {
  const {
    getLegendProps,
    getOptionLabelProps,
    getOptionControlProps,
    errorProps,
  } = useAriaFormGroupField(`site-checkbox-group`, {
    required: required,
    error,
  })

  const toggleSites = useCallback(
    (event: ChangeEvent<HTMLInputElement>) => {
      const hash = event.currentTarget.value
      if (event.currentTarget.checked) {
        setHiddenSites(hiddenSites.filter((site) => site !== hash))
      } else {
        setHiddenSites(Array.from(new Set([...hiddenSites, hash])))
      }
    },
    [setHiddenSites, hiddenSites]
  )

  return (
    <FormFieldset>
      <FormLegend
        css={visuallyHiddenCss}
        {...getLegendProps(`Select the sites you want to import.`)}
      />
      <Grid columns={[null, 1, 1, `repeat(auto-fit, 300px)`]} gap={7}>
        {sites.map((site) => {
          const optionValue = site.hash
          const hidden = hiddenSites.includes(optionValue)
          return (
            <GroupInputCard
              // We need this because we do an initial render before the config comes through
              // and if the key is the same it won't re-render the checkbox with the new default
              key={`${optionValue}${hidden}`}
              {...getOptionLabelProps(optionValue)}
              input={
                <StyledCheckbox
                  {...getOptionControlProps(optionValue)}
                  value={optionValue}
                  checked={!hiddenSites.includes(optionValue)}
                  name={name}
                  onChange={toggleSites}
                />
              }
              sx={{ pl: 7 }}
            >
              {site.name}
              <FolderName sitePath={site.root} />
            </GroupInputCard>
          )
        })}
        <GroupButtonCard icon={<MdArrowForward />} onClick={browseSites}>
          Add another site
        </GroupButtonCard>
      </Grid>
      <FormError {...errorProps} />
    </FormFieldset>
  )
}
Example #7
Source File: index.tsx    From desktop with MIT License 5 votes vote down vote up
export default function MainPage(): JSX.Element {
  const { filteredSites } = useSiteRunners()

  const [onboardingDone, setHasRunOnboarding, store] = useConfig(
    `hasRunOnboarding`
  )

  return (
    <Layout>
      <main
        sx={{
          px: 9,
          py: 7,
          overflowY: `auto`,
        }}
      >
        <Heading
          sx={{
            fontWeight: 600,
            fontFamily: `sans`,
            fontSize: 2,
          }}
        >
          All sites{` `}
          <Text as="span" size="S">
            ({filteredSites.length})
          </Text>
          <LinkButton
            to="/onboarding/intro"
            onClick={(): void => trackEvent(`CLICK_TO_RERUN_ONBOARDING`)}
            // Easter egg: right click to clear config
            onContextMenu={(): void => store?.clear()}
            size="S"
            variant="SECONDARY"
            rightIcon={<MdArrowForward />}
            sx={{ float: `right` }}
          >
            Onboarding
          </LinkButton>
        </Heading>
        <Grid
          gap={8}
          marginTop={7}
          columns="repeat(auto-fit, minmax(456px, 1fr))"
        >
          {filteredSites.map((site) => (
            <SiteCard key={site.hash} site={site} />
          ))}
        </Grid>
      </main>
    </Layout>
  )
}
Example #8
Source File: Gallery.tsx    From nft-market with MIT License 5 votes vote down vote up
Gallery = () => {
  const { user, tokensOnSale } = useAppState()
  const updateTokensOnSale = useAppState(
    useCallback(({ updateTokensOnSale }) => updateTokensOnSale, [])
  )

  const [order, setOrder] = useState<StateOrder>('alpha')

  useEffect(() => {
    updateTokensOnSale()
  }, [updateTokensOnSale])

  return (
    <Box>
      <Heading as="h1">Marketplace</Heading>
      <Flex sx={{ alignItems: 'center' }} mb={3}>
        <Heading as="h3" sx={{ color: 'lightGray' }}>
          Order:
        </Heading>
        <Flex ml={3}>
          <Button
            mr={2}
            onClick={() => setOrder('alpha')}
            variant="filter"
            disabled={order === 'alpha'}
          >
            Alphabetically
          </Button>
          <Button onClick={() => setOrder('price')} variant="filter" disabled={order === 'price'}>
            Price
          </Button>
        </Flex>
      </Flex>
      <Grid gap={4} columns={['1fr 1fr', '1fr 1fr', '1fr 1fr 1fr']}>
        {tokensOnSale
          ?.sort((a, b) =>
            order === 'alpha'
              ? BigNumber.from(a.id)
                  .toString()
                  .localeCompare(BigNumber.from(b.id).toString(), undefined, { numeric: true })
              : Number(utils.formatEther(a.price.sub(b.price)))
          )
          .map((i, index) => (
            <Token onBuy={!user?.ownedTokens.find(t => t.id === i.id)} token={i} key={index} />
          ))}
      </Grid>
    </Box>
  )
}
Example #9
Source File: Profile.tsx    From nft-market with MIT License 5 votes vote down vote up
Profile = () => {
  const { user, tokensOnSale } = useAppState()

  if (!user) return null

  const { address, balance, ownedTokens } = user

  return (
    <Box>
      <Heading as="h1">My Profile</Heading>
      <Grid columns={['1fr', '1fr 1fr']} sx={{ overflow: 'hidden', gap: '0 20px' }}>
        <Box>
          <Heading as="h4" sx={{ color: 'green' }}>
            Address
          </Heading>
          <Text>{address}</Text>
        </Box>
        <Box>
          <Heading as="h4" sx={{ color: 'green' }}>
            Balance
          </Heading>
          <Text>Ξ {balance}</Text>
        </Box>
      </Grid>
      <Divider variant="divider.nft" sx={{ my: 7 }} />
      <Box my={5}>
        {ownedTokens && ownedTokens.length > 0 ? (
          <Box>
            <Heading as="h2">
              My items{' '}
              <Text variant="text.body" as="span">
                ({ownedTokens.length} item)
              </Text>
            </Heading>
            <Grid gap={4} columns={['1fr 1fr', '1fr 1fr 1fr']}>
              {ownedTokens.map((t, index) => (
                <Token
                  isOnSale={
                    !!tokensOnSale?.find(a => utils.formatUnits(a.id) === utils.formatUnits(t.id))
                  }
                  onSale
                  onTransfer
                  token={t}
                  key={index}
                />
              ))}
            </Grid>
          </Box>
        ) : (
          ownedTokens && (
            <Box>
              <Heading as="h2">You don't own any NFT tokens</Heading>
            </Box>
          )
        )}
      </Box>
    </Box>
  )
}
Example #10
Source File: CartItem.tsx    From nextjs-shopify with MIT License 4 votes vote down vote up
CartItem = ({
  item,
  currencyCode,
}: {
  item: /*ShopifyBuy.LineItem todo: check if updated types*/ any
  currencyCode: string
}) => {
  const updateItem = useUpdateItemQuantity()
  const removeItem = useRemoveItemFromCart()
  const [quantity, setQuantity] = useState(item.quantity)
  const [removing, setRemoving] = useState(false)
  const updateQuantity = async (quantity: number) => {
    await updateItem(item.variant.id, quantity)
  }
  const handleQuantity = (e: ChangeEvent<HTMLInputElement>) => {
    const val = Number(e.target.value)

    if (Number.isInteger(val) && val >= 0) {
      setQuantity(val)
    }
  }
  const handleBlur = () => {
    const val = Number(quantity)

    if (val !== item.quantity) {
      updateQuantity(val)
    }
  }
  const increaseQuantity = (n = 1) => {
    const val = Number(quantity) + n

    if (Number.isInteger(val) && val >= 0) {
      setQuantity(val)
      updateQuantity(val)
    }
  }
  const handleRemove = async () => {
    setRemoving(true)

    try {
      // If this action succeeds then there's no need to do `setRemoving(true)`
      // because the component will be removed from the view
      await removeItem(item.variant.id)
    } catch (error) {
      console.error(error)
      setRemoving(false)
    }
  }

  useEffect(() => {
    // Reset the quantity state if the item quantity changes
    if (item.quantity !== Number(quantity)) {
      setQuantity(item.quantity)
    }
  }, [item.quantity])

  return (
    <Grid gap={2} sx={{ width: '100%', m: 12 }} columns={[2]}>
      <div
        sx={{
          padding: 1,
          border: '1px solid gray',
          display: 'flex',
          justifyContent: 'center',
          alignItems: 'center',
        }}
      >
        <Image
          height={130}
          width={130}
          unoptimized
          alt={item.variant.image.altText}
          src={item.variant.image.src}
        />
      </div>
      <div>
        <Themed.div
          as={Link}
          href={`/product/${item.variant.product.handle}/`}
          sx={{ fontSize: 3, m: 0, fontWeight: 700 }}
        >
          <>
            {item.title}
            <Text
              sx={{
                fontSize: 4,
                fontWeight: 700,
                display: 'block',
                marginLeft: 'auto',
              }}
            >
              {getPrice(
                item.variant.priceV2.amount,
                item.variant.priceV2.currencyCode || 'USD'
              )}
            </Text>
          </>
        </Themed.div>
        <Themed.ul sx={{ mt: 2, mb: 0, padding: 0, listStyle: 'none' }}>
          <li>
            <div sx={{ display: 'flex', justifyItems: 'center' }}>
              <IconButton onClick={() => increaseQuantity(-1)}>
                <Minus width={18} height={18} />
              </IconButton>

              <label>
                <Input
                  sx={{
                    height: '100%',
                    textAlign: 'center',
                  }}
                  type="number"
                  max={99}
                  min={0}
                  value={quantity}
                  onChange={handleQuantity}
                  onBlur={handleBlur}
                />
              </label>
              <IconButton onClick={() => increaseQuantity(1)}>
                <Plus width={18} height={18} />
              </IconButton>
            </div>
          </li>
          {item.variant.selectedOptions.map((option: any) => (
            <li key={option.value}>
              {option.name}:{option.value}
            </li>
          ))}
        </Themed.ul>
      </div>
    </Grid>
  )
}
Example #11
Source File: CartSidebarView.tsx    From nextjs-shopify with MIT License 4 votes vote down vote up
CartSidebarView: FC = () => {
  const checkoutUrl = useCheckoutUrl()
  const cart = useCart()
  const subTotal = cart?.subtotalPrice
  const total = ' - '

  const items = cart?.lineItems ?? []
  const isEmpty = items.length === 0
  const [cartUpsell, setCartUpsell] = useState()

  useEffect(() => {
    async function fetchContent() {
      const items = cart?.lineItems || []
      const cartUpsellContent = await builder
        .get('cart-upsell-sidebar', {
          cacheSeconds: 120,
          userAttributes: {
            itemInCart: items.map((item: any) => item.variant.product.handle),
          } as any,
        })
        .toPromise()
      setCartUpsell(cartUpsellContent)
    }
    fetchContent()
  }, [cart?.lineItems])

  return (
    <Themed.div
      sx={{
        height: '100%',
        overflow: 'auto',
        paddingBottom: 5,
        bg: 'text',
        display: 'flex',
        flexDirection: 'column',
        alignItems: 'center',
        px: 2,
        color: 'background',
        ...(isEmpty && { justifyContent: 'center' }),
      }}
    >
      {isEmpty ? (
        <>
          <Bag />
          Your cart is empty
          <Text>
            Biscuit oat cake wafer icing ice cream tiramisu pudding cupcake.
          </Text>
        </>
      ) : (
        <>
          {items.map((item: any) => (
            <CartItem
              key={item.id}
              item={item}
              // todo update types
              currencyCode={item.variant?.priceV2?.currencyCode || 'USD'}
            />
          ))}
          <Card sx={{ marginLeft: 'auto', minWidth: '10rem', paddingLeft: 5 }}>
            <Grid gap={1} columns={2} sx={{ my: 3 }}>
              <Text>Subtotal:</Text>
              <Text sx={{ marginLeft: 'auto' }}>{subTotal}</Text>
              <Text>Shipping:</Text>
              <Text sx={{ marginLeft: 'auto' }}> - </Text>
              <Text>Tax: </Text>
              <Text sx={{ marginLeft: 'auto' }}> - </Text>
            </Grid>

            <Divider />
            <Grid gap={1} columns={2}>
              <Text variant="bold">Estimated Total:</Text>
              <Text variant="bold" sx={{ marginLeft: 'auto' }}>
                {total}
              </Text>
            </Grid>
          </Card>
          <BuilderComponent content={cartUpsell} model="cart-upsell-sidebar" />
          {checkoutUrl && (
            <NavLink
              variant="nav"
              sx={{ width: '100%', m: 2, p: 12, textAlign: 'center' }}
              href={checkoutUrl!}
            >
              Proceed to Checkout
            </NavLink>
          )}
        </>
      )}
    </Themed.div>
  )
}
Example #12
Source File: ModalMapSelect.tsx    From HappyIslandDesigner with MIT License 4 votes vote down vote up
function IslandLayoutSelector() {
  const [layoutType, setLayoutType] = useState<LayoutType>(LayoutType.none);
  const [layout, setLayout] = useState<number>(-1);
  const [help, setHelp] = useState<boolean>(false);

  useEffect(() => {
    if (layout != -1)
    {
      const layoutData = getLayouts(layoutType)[layout];
      loadMapFromJSONString(layoutData.data);
      CloseMapSelectModal();
    }
  }, [layoutType, layout]);

  function getLayouts(type: LayoutType) {
    switch (type) {
      case LayoutType.west:
        return Layouts.west;
      case LayoutType.south:
        return Layouts.south;
      case LayoutType.east:
        return Layouts.east;
      case LayoutType.blank:
        return Layouts.blank;
    }
    return [];
  }

  if (help) {
    return (
      <Flex p={[0, 3]} sx={{flexDirection: 'column', alignItems: 'center', position: 'relative'}}>
        <Box sx={{position: 'absolute', left: 0, top: [1, 30]}}>
          <Button variant='icon' onClick={() => setHelp(false)}>
            <Image sx={{width: 'auto'}} src='static/img/back.png' />
          </Button>
        </Box>
        <Image sx={{width: 100, margin: 'auto'}} src={'static/img/blathers.png'}/>
        <Heading m={3} sx={{px: layoutType ? 4 : 0, textAlign: 'center'}}>{'Please help contribute!'}</Heading>
        <Text my={2}>{'Sorry, we don\'t have all the map templates yet (there are almost 100 river layouts in the game!). Each option you see here has been hand-made by a member of the community.'}</Text>
        <Text my={2}>{'You can use the \'Upload Screenshot\' tool to trace an image of your island. When you\'re done please consider contributing your island map in either the '}<Link href={'https://github.com/eugeneration/HappyIslandDesigner/issues/59'}>Github</Link>{' or '}<Link href={'https://discord.gg/EtaqD5H'}>Discord</Link>!</Text>
        <Text my={2}>{'Please note that your island may have different shaped rock formations, beaches, and building positions than another island with the same river layout.'}</Text>
      </Flex>
    )
  }

  let content;
  if (layoutType != LayoutType.none) {
    var layouts: Array<Layout> = getLayouts(layoutType);
    content = (
      <Grid
        gap={0}
        columns={[2, 3, 4]}
        sx={{justifyItems: 'center' }}>
        {
          layouts.map((layout, index) => (
            <Card
              key={index}
              onClick={() => {
                confirmDestructiveAction(
                  'Clear your map? You will lose all unsaved changes.',
                  () => {
                    setLayout(index);
                  });
              }}>
              <Image variant='card' src={`static/img/layouts/${layoutType}-${layout.name}.png`}/>
            </Card>
          )).concat(
            <Card key={'help'} onClick={()=>{setHelp(true)}}>
              <Image sx={{width: 24}} src={'static/img/menu-help.png'} />
              <Text sx={{fontFamily: 'body'}}>{'Why isn\'t my map here?'}</Text>
            </Card>
          )
        }
      </Grid>
    );
  }
  else {
    content = (
      <Flex sx={{flexDirection: ['column', 'row'], alignItems: 'center'}}>
        <Card onClick={() => setLayoutType(LayoutType.west)}><Image variant='card' src={'static/img/island-type-west.png'}/></Card>
        <Card onClick={() => setLayoutType(LayoutType.south)}><Image variant='card' src={'static/img/island-type-south.png'}/></Card>
        <Card onClick={() => setLayoutType(LayoutType.east)}><Image variant='card' src={'static/img/island-type-east.png'}/></Card>
        <Card onClick={() => {
          setLayoutType(LayoutType.blank);
          confirmDestructiveAction(
            'Clear your map? You will lose all unsaved changes.',
            () => {
              setLayout(0);
            });
        }}><Image variant='card' src={'static/img/island-type-blank.png'}/></Card>      </Flex>
    );
  }
  return (
    <Box p={[0, 3]} sx={{position: 'relative'}}>
      {layoutType && <Box sx={{position: 'absolute', top: [1, 3]}}>
        <Button variant='icon' onClick={() => setLayoutType(LayoutType.none)}>
          <Image src='static/img/back.png' />
        </Button>
      </Box>}
      <Heading m={2} sx={{px: layoutType ? 4 : 0, textAlign: 'center'}}>{layoutType ? 'Choose your Island!' : 'Choose your Layout!'}</Heading>
      {layoutType && <Text m={2} sx={{textAlign: 'center'}}>{'You probably won\'t find an exact match, but pick one that roughly resembles your island.'}</Text>}
      {content}
    </Box>
  );
}