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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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>
);
}