feat: implement universal grid refs #116

This commit is contained in:
Hossein Mehrabi
2023-10-10 12:53:05 +03:30
parent 49bb3471d8
commit cdbe63620c
13 changed files with 643 additions and 101 deletions
@@ -3,40 +3,46 @@ title: Join the community
---
import { Community } from '../../logos-docusaurus-theme/src/client/components/mdx'
import { SocialCard, Grid } from '@site/src/components/mdx'
# Join the community
Welcome to the Waku community! Whether you are interested in building with Waku, contributing to the network, expanding your knowledge, or staying abreast of our progress, we have something for everyone.
<Community
items={[
{
type: 'x',
link: 'https://discord.gg/2NXGrsqmDq',
linkLabel: 'Follow us on X',
},
{
type: 'discord',
logoSrcDark: '/icons/discord.svg',
link: 'https://discord.gg/2NXGrsqmDq',
linkLabel: 'Join the community on Discord',
},
{
type: 'telegram',
logoSrcDark: '/icons/discord.svg',
link: 'https://discord.gg/2NXGrsqmDq',
linkLabel: 'Jump in the conversation on Telegram',
},
{
logoSrcDark: '/icons/discord.svg',
link: 'https://discord.gg/2NXGrsqmDq',
linkLabel:
'Share your thoughts on the latest research on the Vac research forum',
},
{
type: 'github',
link: 'https://discord.gg/2NXGrsqmDq',
linkLabel: 'Contribute to Github',
},
]}
/>
<Grid xs={{ cols: 1, gap: '1rem' }} md={{ cols: 2 }}>
<Grid.Item xs={1}>
<SocialCard
logoSrcDark="/icons/x.svg"
href="https://discord.gg/2NXGrsqmDq"
description="Follow us on X"
/>
</Grid.Item>
<Grid.Item xs={1}>
<SocialCard
logoSrcDark="/icons/discord-white.svg"
href="https://discord.gg/2NXGrsqmDq"
description="Join the community on Discord"
/>
</Grid.Item>
<Grid.Item xs={1}>
<SocialCard
logoSrcDark="/icons/telegram-white.svg"
href="https://discord.gg/2NXGrsqmDq"
description="Jump in the conversation on Telegram"
/>
</Grid.Item>
<Grid.Item xs={1}>
<SocialCard
logoSrcDark="/icons/discord.svg"
href="https://discord.gg/2NXGrsqmDq"
description="Share your thoughts on the latest research on the Vac research forum"
/>
</Grid.Item>
<Grid.Item xs={1}>
<SocialCard
logoSrcDark="/icons/github.svg"
href="https://discord.gg/2NXGrsqmDq"
description="Contribute to Github"
/>
</Grid.Item>
</Grid>
@@ -11,6 +11,8 @@ import {
Showcase,
HeroInfo,
Box,
Grid,
ProfileCard,
ProfileCards,
} from '../components/mdx'
@@ -89,72 +91,84 @@ import {
href="/about/team"
target="_self"
/>
<ProfileCards
items={[
{
name: 'Jeremy',
githubUsername: 'jeremyjeremyjeremy',
githubLink: 'https://github.com/acid-info',
discordUsername: 'jeremyjeremyjeremy#0001',
discordLink: 'https://discord.gg/2NXGrsqmDq',
},
{
name: 'Dimitriy',
imgSrc:
'https://statusim.bamboohr.com/employees/photos/?h=297aeedfad6fed82ed60a93a9d850762',
githubUsername: 'dimitriy',
githubLink: 'https://github.com/acid-info',
discordUsername: 'dimitriy#0001',
discordLink: 'https://discord.gg/2NXGrsqmDq',
},
{
name: 'Slava',
imgSrc:
'https://statusim.bamboohr.com/employees/photos/?h=c9028ddcd6da2b7b0aaaf6fabbad7b31',
githubUsername: 'slava',
githubLink: 'https://discord.gg/2NXGrsqmDq',
},
{
name: 'Eric',
imgSrc:
'https://statusim.bamboohr.com/employees/photos/?h=a620c567ee3da938757bb0a43eda4ec9',
discordUsername: 'eric#0001',
discordLink: 'https://discord.gg/2NXGrsqmDq',
},
{
name: 'Tomas',
imgSrc:
'https://statusim.bamboohr.com/employees/photos/?h=8f6066f7e4b7517702c86d85f3ad828d',
},
{
name: 'Adam',
imgSrc:
'https://statusim.bamboohr.com/employees/photos/?h=5edf032c2d62576d36090cf09b5939e5',
githubUsername: 'adam',
githubLink: 'https://github.com/acid-info',
discordUsername: 'adam#0001',
discordLink: 'https://discord.gg/2NXGrsqmDq',
},
{
name: 'Ben',
imgSrc:
'https://statusim.bamboohr.com/employees/photos/?h=406fd339da77e69aeef5f357ece3ff3d',
githubUsername: 'ben',
githubLink: 'https://github.com/acid-info',
discordUsername: 'ben#0001',
discordLink: 'https://discord.gg/2NXGrsqmDq',
},
{
name: 'Leo',
imgSrc:
'https://statusim.bamboohr.com/employees/photos/?h=4d6fcc7c245ca327414ab4d282b509f2',
githubUsername: 'leo',
githubLink: 'https://github.com/acid-info',
discordUsername: 'leo#0001',
discordLink: 'https://discord.gg/2NXGrsqmDq',
},
]}
/>
<Box top={{ xs: 40, md: 80 }} bottom={{ xs: 40, md: 80 }}>
<Grid
xs={{ cols: 3, gap: '1rem', wrap: false }}
md={{ cols: 4, gap: '1rem', wrap: true }}
>
<Grid.Item sm={1}>
<ProfileCard
name="Jeremy"
githubUsername="jeremyjeremyjeremy"
githubLink="https://github.com/acid-info"
discordUsername="jeremyjeremyjeremy#0001"
discordLink="https://discord.gg/2NXGrsqmDq"
/>
</Grid.Item>
<Grid.Item sm={1}>
<ProfileCard
name="Dimitriy"
imgSrc="https://statusim.bamboohr.com/employees/photos/?h=297aeedfad6fed82ed60a93a9d850762"
githubUsername="dimitriy"
githubLink="https://github.com/acid-info"
discordUsername="dimitriy#0001"
discordLink="https://discord.gg/2NXGrsqmDq"
/>
</Grid.Item>
<Grid.Item sm={1}>
<ProfileCard
name="Slava"
imgSrc="https://statusim.bamboohr.com/employees/photos/?h=c9028ddcd6da2b7b0aaaf6fabbad7b31"
githubUsername="slava"
githubLink="https://discord.gg/2NXGrsqmDq"
/>
</Grid.Item>
<Grid.Item sm={1}>
<ProfileCard
name="Eric"
imgSrc="https://statusim.bamboohr.com/employees/photos/?h=a620c567ee3da938757bb0a43eda4ec9"
discordUsername="eric#0001"
discordLink="https://discord.gg/2NXGrsqmDq"
/>
</Grid.Item>
<Grid.Item sm={1}>
<ProfileCard
name="Tomas"
imgSrc="https://statusim.bamboohr.com/employees/photos/?h=8f6066f7e4b7517702c86d85f3ad828d"
/>
</Grid.Item>
<Grid.Item sm={1}>
<ProfileCard
name="Adam"
imgSrc="https://statusim.bamboohr.com/employees/photos/?h=5edf032c2d62576d36090cf09b5939e5"
githubUsername="adam"
githubLink="https://github.com/acid-info"
discordUsername="adam#0001"
discordLink="https://discord.gg/2NXGrsqmDq"
/>
</Grid.Item>
<Grid.Item sm={1}>
<ProfileCard
name="Ben"
imgSrc="https://statusim.bamboohr.com/employees/photos/?h=406fd339da77e69aeef5f357ece3ff3d"
githubUsername="ben"
githubLink="https://github.com/acid-info"
discordUsername="ben#0001"
discordLink="https://discord.gg/2NXGrsqmDq"
/>
</Grid.Item>
<Grid.Item sm={1}>
<ProfileCard
name="Leo"
imgSrc="https://statusim.bamboohr.com/employees/photos/?h=4d6fcc7c245ca327414ab4d282b509f2"
githubUsername="leo"
githubLink="https://github.com/acid-info"
discordUsername="leo#0001"
discordLink="https://discord.gg/2NXGrsqmDq"
/>
</Grid.Item>
</Grid>
</Box>
</Box>
<Box top={{ xs: 144, lg: 216 }}>
@@ -0,0 +1,85 @@
import { THEME_BREAKPOINTS } from '@acid-info/lsd-react'
import { css } from '@emotion/react'
import styled from '@emotion/styled'
import clsx from 'clsx'
import React from 'react'
import { lsdUtils } from '../../../lib/lsd.utils'
import { GridItem } from './GridItem'
export type GridProps = React.ComponentProps<typeof GridRoot> & {}
export const Grid: { Item: typeof GridItem } & React.FC<GridProps> = ({
children,
...props
}) => {
return (
<GridRoot {...props} className={clsx(props.className, 'hidden-scrollbar')}>
{children}
</GridRoot>
)
}
Grid.Item = GridItem
type GridBreakpointProps = {
cols?: number
wrap?: boolean
gap?: string | number
}
const GridRoot = styled.div<{
xs?: GridBreakpointProps
sm?: GridBreakpointProps
md?: GridBreakpointProps
lg?: GridBreakpointProps
xl?: GridBreakpointProps
}>`
width: 100%;
overflow: hidden;
display: grid;
gap: var(--grid-gap);
grid-template-columns: repeat(var(--grid-cols), minmax(0, 1fr));
${(props) =>
THEME_BREAKPOINTS.map((key) => {
if (!props[key]) return null
const bp = props[key] as GridBreakpointProps
return lsdUtils.responsive(
props.theme as any,
key,
'up',
)(css`
${typeof bp.cols !== 'undefined' &&
`
--grid-cols: ${bp.cols};
`}
${typeof bp.gap !== 'undefined' &&
`
--grid-gap: ${bp.gap};
`}
${(typeof bp.wrap === 'undefined' || bp.wrap === true) &&
`
display: grid;
flex-wrap: unset;
overflow-x: unset;
overflow-y: unset;
scroll-snap-type: unset;
`}
${typeof bp.wrap !== 'undefined' &&
bp.wrap === false &&
`
display: flex;
flex-wrap: nowrap;
overflow-x: scroll;
overflow-y: hidden;
scroll-snap-type: x mandatory;
`}
`)
})}
`
@@ -0,0 +1,40 @@
import clsx from 'clsx'
import React from 'react'
import styled from '@emotion/styled'
import { THEME_BREAKPOINTS } from '@acid-info/lsd-react'
import { lsdUtils } from '../../../lib/lsd.utils'
import { css } from '@emotion/react'
export type GridItemProps = React.ComponentProps<typeof Root> & {}
export const GridItem: React.FC<GridItemProps> = ({ children, ...props }) => {
return (
<Root {...props} className={clsx(props.className)}>
{children}
</Root>
)
}
const Root = styled.div<{
xs?: number
sm?: number
md?: number
lg?: number
xl?: number
}>`
${(props) =>
THEME_BREAKPOINTS.map((key) => {
if (!props[key]) return null
const bp = props[key] as number
return lsdUtils.responsive(
props.theme as any,
key,
'up',
)(css`
grid-column: span ${bp};
flex-basis: calc(100% / var(--grid-cols) * ${bp});
`)
})}
`
@@ -0,0 +1,2 @@
export * from './Grid'
export * from './GridItem'
@@ -0,0 +1,108 @@
@use '../../../css/utils';
@use '../../../css/lsd';
:root {
--card-height: 188px;
--mobile-width: 253px;
--mobile-height: 176px;
}
.mdx-profile-card {
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: flex-start;
padding: 1rem;
border: 1px solid rgb(var(--lsd-border-primary));
height: var(--card-height);
}
.mdx-profile-card__profile {
display: flex;
flex-direction: column;
gap: 20px;
}
.mdx-profile-card__avatar {
width: 40px !important;
height: 40px !important;
border-radius: 50%;
svg {
width: 40px !important;
height: 40px !important;
rect {
fill: unset !important;
}
}
}
.mdx-profile-card__name {
@include lsd.typography('h4');
}
.mdx-profile-card__buttons {
display: flex;
flex-direction: row;
gap: 8px;
width: 100%;
}
.mdx-profile-card__link {
text-decoration: none;
height: fit-content;
position: relative;
max-width: calc(50% - 4px);
}
.mdx-profile-card__button {
padding: 4px 12px 4px 10px !important;
height: 28px !important;
max-width: 100% !important;
> span {
display: flex;
gap: 12px;
align-items: center;
}
svg {
width: 14px;
height: 14px;
}
}
.mdx-profile-card__link__label {
display: -webkit-box;
-webkit-line-clamp: 1;
-webkit-box-orient: vertical;
overflow: hidden;
}
.mdx-profile-card__label {
text-align: center;
}
@include utils.responsive('lg', 'down') {
.mdx-profile-card {
grid-template-columns: 1fr;
}
}
@include utils.responsive('md', 'down') {
.mdx-profile-card {
flex: 0 0 var(--mobile-width);
width: var(--mobile-width);
height: var(--mobile-height);
scroll-snap-align: start !important;
}
.mdx-profile-card__profile {
gap: 16px;
}
.mdx-profile-card__name {
@include lsd.typography('h6');
}
}
@@ -0,0 +1,94 @@
import { Button, Typography } from '@acid-info/lsd-react'
import Link from '@docusaurus/Link'
import React from 'react'
import { IconAvatar, IconDiscordWhite, IconGithub } from '../../Icon'
import './ProfileCard.scss'
import clsx from 'clsx'
export type ProfileCardProps = React.HTMLProps<HTMLDivElement> & {
imgSrc?: string
name?: string
githubUsername?: string
githubLink?: string
discordUsername?: string
discordLink?: string
}
export const ProfileCard: React.FC<ProfileCardProps> = ({
imgSrc,
name,
githubUsername,
githubLink,
discordUsername,
discordLink,
...props
}) => {
return (
<div {...props} className={clsx('mdx-profile-card', props.className)}>
<div className="mdx-profile-card__profile">
{typeof imgSrc === 'undefined' ? (
<IconAvatar className="mdx-profile-card__avatar" />
) : (
<img
alt={typeof name === 'string' ? name : ''}
className="mdx-profile-card__avatar"
src={imgSrc}
/>
)}
<Typography
className="mdx-profile-card__name"
variant="h4"
component="h4"
>
{name}
</Typography>
</div>
<div className="mdx-profile-card__buttons">
{githubUsername && githubLink && (
<Link
href={githubLink}
target="_blank"
className={'mdx-profile-card__link'}
>
<Button
size={'small'}
variant={'outlined'}
className={'mdx-profile-card__button'}
>
<IconGithub />
<Typography
variant="body2"
className="mdx-profile-card__link__label"
>
{githubUsername}
</Typography>
</Button>
</Link>
)}
{discordUsername && discordLink && (
<Link
href={discordLink}
target="_blank"
className={'mdx-profile-card__link'}
>
<Button
size={'small'}
variant={'outlined'}
className={'mdx-profile-card__button'}
>
<IconDiscordWhite />
<Typography
variant="body2"
className="mdx-profile-card__link__label"
>
{discordUsername}
</Typography>
</Button>
</Link>
)}
</div>
</div>
)
}
@@ -0,0 +1 @@
export * from './ProfileCard'
@@ -0,0 +1,37 @@
@use '../../../css/utils';
@use '../../../css/lsd';
.mdx-social-card {
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: flex-start;
padding: 1rem;
border: 1px solid rgb(var(--lsd-border-primary));
min-height: 144px;
text-decoration: none !important;
}
.mdx-social-card:hover {
text-decoration: underline !important;
}
.mdx-social-card__row {
display: flex;
justify-content: space-between;
width: 100%;
}
.mdx-social-card__logo {
width: 40px !important;
height: 40px !important;
svg {
width: 40px !important;
height: 40px !important;
}
}
.mdx-social-card__description {
}
@@ -0,0 +1,49 @@
import { Typography } from '@acid-info/lsd-react'
import ThemedImage from '@theme/ThemedImage'
import clsx from 'clsx'
import React from 'react'
import { IconExternalLink } from '../../Icon'
import './SocialCard.scss'
export type SocialCardProps = React.HTMLProps<HTMLAnchorElement> & {
logoSrc?: string
logoSrcDark?: string
description?: React.ReactNode
}
export const SocialCard: React.FC<SocialCardProps> = ({
title,
logoSrc,
logoSrcDark,
description,
...props
}) => {
return (
<a
target="_blank"
{...props}
className={clsx(props.className, 'mdx-social-card')}
>
<div className="mdx-social-card__row">
{(logoSrc || logoSrcDark) && (
<ThemedImage
sources={{
dark: logoSrcDark ?? logoSrc ?? '',
light: logoSrc ?? logoSrcDark ?? '',
}}
alt={title ?? 'social card logo'}
className="mdx-social-card__logo"
/>
)}
<IconExternalLink className="mdx-social-card__external-link" />
</div>
<Typography
variant="body1"
component="span"
className="mdx-social-card__description"
>
{description}
</Typography>
</a>
)
}
@@ -0,0 +1 @@
export * from './SocialCard'
@@ -4,6 +4,7 @@ export * from './CallToActionSection'
export * from './Community'
export * from './DocMetadata'
export * from './FeatureList'
export * from './Grid'
export * from './Hero'
export * from './HeroAction'
export * from './HeroActions'
@@ -11,9 +12,11 @@ export * from './HeroDescription'
export * from './HeroInfo'
export * from './HeroModel'
export * from './HeroTitle'
export * from './HeroVideo'
export * from './PoweredBy'
export * from './ProfileCard'
export * from './ProfileCards'
export * from './Roadmap'
export * from './ScrollToBottom'
export * from './Showcase'
export * from './Roadmap'
export * from './HeroVideo'
export * from './ProfileCards'
export * from './SocialCard'
@@ -0,0 +1,102 @@
import {
Breakpoints,
Theme,
THEME_BREAKPOINTS,
TypographyVariants,
} from '@acid-info/lsd-react'
import { css, SerializedStyles } from '@emotion/react'
export class LsdUtils {
private _breakpoints: Record<
string,
Record<string, { min: number; max: number }>
> = {}
private getBreakpoints = (theme: Theme) => {
if (this._breakpoints[theme.name]) {
return this._breakpoints[theme.name]
}
const breakpoints: (typeof this._breakpoints)[string] = {}
for (let i = 0; i < THEME_BREAKPOINTS.length; i++) {
const name = THEME_BREAKPOINTS[i]!
const breakpoint = theme.breakpoints[name]
const next = theme.breakpoints[THEME_BREAKPOINTS[i + 1]!]
const min = breakpoint.width
const max = next ? next.width - 1 : Number.MAX_SAFE_INTEGER
breakpoints[name] = {
min,
max,
}
}
this._breakpoints[theme.name] = breakpoints
return breakpoints
}
private getBreakpoint = (theme: Theme, breakpoint: Breakpoints) => {
const breakpoints = this.getBreakpoints(theme)
return breakpoints![breakpoint]
}
breakpoints = (exclude: Breakpoints[] = []) =>
THEME_BREAKPOINTS.filter((b) => !exclude.find((b2) => b2 === b))
typography = (variant: TypographyVariants | 'subtitle3', important = false) =>
variant === 'subtitle3'
? `
font-size: 12px !important;
font-weight: 400 !important;
line-height: 16px !important;
`
: `
font-size: var(--lsd-${variant}-fontSize)${important ? '!important' : ''};
font-weight: var(--lsd-${variant}-fontWeight)${
important ? '!important' : ''
};
line-height: var(--lsd-${variant}-lineHeight)${
important ? '!important' : ''
};
`
breakpoint = (
theme: Theme,
breakpoint: Breakpoints,
func: 'exact' | 'up' | 'down' | 'between' = 'up',
next?: Breakpoints,
) => {
const { min, max } = this.getBreakpoint(theme, breakpoint)!
let media = `@media `
if (func === 'up') {
media += `(min-width: ${min}px)`
} else if (func === 'down') media += `(max-width: ${max}px)`
else if (func === 'between' && !!next) {
const nextBreakpoint = this.getBreakpoint(theme, next)
media += `(min-width: ${min}px) and (max-width: ${
nextBreakpoint!.min - 1
}px)`
} else media += `(min-width: ${min}px) and (max-width: ${max}px)`
return `${media}`
}
responsive = (
theme: Theme,
breakpoint: Breakpoints,
func: 'exact' | 'up' | 'down' = 'up',
) => {
const media = lsdUtils.breakpoint(theme, breakpoint, func)
return (styles: SerializedStyles) => css`
${media} {
${styles}
}
`
}
}
export const lsdUtils = new LsdUtils()