components#useTheme TypeScript Examples
The following examples show how to use
components#useTheme.
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: colors.tsx From geist-ui with MIT License | 6 votes |
Colors: React.FC<React.PropsWithChildren<unknown>> = () => {
const theme = useTheme()
return (
<div className="colors">
<Grid.Container gap={1} pl={0} mr="10px">
{types.map((type, index) => {
return (
<Grid xs={12} key={`${type}-${index}`}>
<Card w="100%" type={type as CardTypes}>
{type}
</Card>
</Grid>
)
})}
</Grid.Container>
<style jsx>{`
.colors {
display: flex;
flex-wrap: wrap;
}
.color-card {
display: flex;
width: 9rem;
margin-right: ${theme.layout.gapHalf};
margin-bottom: ${theme.layout.gapHalf};
}
`}</style>
</div>
)
}
Example #2
Source File: playground.tsx From geist-ui with MIT License | 6 votes |
Playground: React.FC<PlaygroundProps> = React.memo(
({
title: inputTitle,
code: inputCode,
desc,
scope,
}: PlaygroundProps & typeof defaultProps) => {
const theme = useTheme()
const { isChinese } = useConfigs()
const code = inputCode.trim()
const title = inputTitle || (isChinese ? '基础的' : 'General')
return (
<>
<Title title={title} desc={desc} />
<div className="playground">
<DynamicLive code={code} scope={scope} />
<style jsx>{`
.playground {
width: 100%;
border-radius: ${theme.layout.radius};
border: 1px solid ${theme.palette.accents_2};
}
`}</style>
</div>
</>
)
},
)
Example #3
Source File: layout.tsx From geist-ui with MIT License | 6 votes |
CustomizationLayout: React.FC<React.PropsWithChildren<unknown>> = ({
children,
}) => {
const theme = useTheme()
return (
<div className="layout">
<Grid.Container>
<Grid xs={24}>
<Demo />
<div className="content">{children}</div>
</Grid>
<Grid xs={24}>
<CustomizationCodes />
</Grid>
</Grid.Container>
<style jsx>{`
.layout {
min-height: calc(100vh - 108px);
max-width: ${theme.layout.pageWidthWithMargin};
margin: 0 auto;
padding: 0 ${theme.layout.gap};
display: flex;
flex-direction: column;
box-sizing: border-box;
}
.content {
flex: 1;
overflow: hidden;
}
`}</style>
</div>
)
}
Example #4
Source File: dynamic-live.tsx From geist-ui with MIT License | 6 votes |
DynamicLive: React.FC<Props> = ({ code, scope }) => {
const theme = useTheme()
const codeTheme = makeCodeTheme(theme)
return (
<LiveProvider code={code} scope={scope} theme={codeTheme}>
<div className="wrapper">
<LivePreview />
<LiveError className="live-error" />
</div>
<Editor code={code} />
<style jsx>{`
.wrapper {
width: 100%;
padding: ${theme.layout.pageMargin};
display: flex;
flex-direction: column;
box-sizing: border-box;
}
.wrapper > :global(div) {
width: 100%;
background-color: transparent;
}
.wrapper > :global(.live-error) {
padding: 10px 12px 0 12px;
margin-bottom: 0;
border: 2px ${theme.palette.error} dotted;
border-radius: 10px;
color: ${theme.palette.errorLight};
font-size: 13px;
}
`}</style>
</LiveProvider>
)
}
Example #5
Source File: grid-demo.tsx From geist-ui with MIT License | 6 votes |
GridDemo: React.FC<React.PropsWithChildren<unknown>> = ({ children }) => {
const theme = useTheme()
const bgColor = addColorAlpha(theme.palette.accents_2, 0.5)
return (
<div className="grid-demo">
{children}
<style jsx>{`
.grid-demo {
background: transparent;
background-image: linear-gradient(${bgColor} 1px, transparent 0),
linear-gradient(90deg, ${bgColor} 1px, transparent 0);
background-size: 15px 15px, 15px 15px, 75px 75px, 75px 75px;
border: 2px solid ${bgColor};
border-radius: 4px;
overflow: hidden;
width: 500px;
height: 150px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
margin-bottom: 15px;
}
.grid-demo :global(> *) {
margin-bottom: 15px;
}
.grid-demo :global(> *:last-of-type) {
margin-bottom: 0;
}
`}</style>
</div>
)
}
Example #6
Source File: home-cell.tsx From geist-ui with MIT License | 5 votes |
HomeCell: React.FC<HomeCellProps> = ({ url, title, desc, icon }) => {
const theme = useTheme()
return (
<NextLink href={url} passHref>
<Link>
<Card padding="5px" shadow width="100%">
<h4 className="feature__title">
<div className="feature__icon">{icon}</div>
{title}
</h4>
<p className="feature__description">{desc}</p>
</Card>
<style jsx>{`
.feature__title {
display: flex;
flex-direction: row;
align-items: center;
}
.feature__icon {
height: 2.5rem;
width: 2.5rem;
padding: 0.625rem;
margin-right: ${theme.layout.gapHalf};
display: flex;
align-items: center;
justify-content: center;
background: linear-gradient(#3291ff, #0761d1);
color: #fff;
border-radius: 2rem;
}
.feature__icon :global(svg) {
width: 100%;
height: 100%;
}
.feature__description {
color: ${theme.palette.accents_6};
}
`}</style>
</Link>
</NextLink>
)
}
Example #7
Source File: index.tsx From geist-ui with MIT License | 5 votes |
Home: NextPage<unknown> = () => {
const theme = useTheme()
return (
<>
<div className="layout">
<div className="hero">
<h1 className="title">Geist</h1>
<h3 className="desc">一个用于构建现代 Web 应用的开源设计系统</h3>
</div>
<Grid.Container gap={2} justify="center">
<Grid xs={24} md={8}>
<HomeCell
icon={<PackageIcon />}
url="/zh-cn/components"
title="Components"
desc="Ever-increasing list of concise and aesthetic components."
/>
</Grid>
<Grid xs={24} md={8}>
<HomeCell
icon={<FeatherIcon />}
url="/zh-cn/guide/themes"
title="Customizable"
desc="Configure sizes, colors, appearances, shapes, and more."
/>
</Grid>
<Grid xs={24} md={8}>
<HomeCell
icon={<GitHubIcon />}
url="https://github.com/geist-org/geist-ui"
title="Open Sourced"
desc="Geist is open sourced and available free under MIT licence."
/>
</Grid>
</Grid.Container>
</div>
<style jsx>{`
.layout {
min-height: calc(100vh - var(--geist-page-nav-height));
max-width: ${theme.layout.pageWidthWithMargin};
margin: 0 auto;
padding: 0 ${theme.layout.gap} calc(${theme.layout.gap} * 2);
box-sizing: border-box;
}
.hero {
height: calc(100vh - var(--geist-page-nav-height) - 300px);
min-height: 30vh;
max-width: 100%;
margin: 0 auto;
text-align: center;
align-items: center;
justify-content: center;
display: flex;
flex-direction: column;
}
.title {
font-size: 3.75rem;
font-weight: 700;
margin: 0;
}
.desc {
color: ${theme.palette.accents_5};
font-size: 1.5rem;
font-weight: 500;
margin: 0 0 ${theme.layout.gap};
}
`}</style>
</>
)
}
Example #8
Source File: index.tsx From geist-ui with MIT License | 5 votes |
Application: NextPage<{}> = () => {
const theme = useTheme()
return (
<>
<div className="layout">
<div className="hero">
<h1 className="title">Geist</h1>
<h3 className="desc">
An open source design system for building modern websites and applications.
</h3>
</div>
<Grid.Container gap={2} justify="center">
<Grid xs={24} md={8}>
<HomeCell
icon={<PackageIcon />}
url="/en-us/components"
title="Components"
desc="Ever-increasing list of concise and aesthetic components."
/>
</Grid>
<Grid xs={24} md={8}>
<HomeCell
icon={<FeatherIcon />}
url="/en-us/guide/themes"
title="Customizable"
desc="Configure sizes, colors, appearances, shapes, and more."
/>
</Grid>
<Grid xs={24} md={8}>
<HomeCell
icon={<GitHubIcon />}
url="https://github.com/geist-org/geist-ui"
title="Open Sourced"
desc="Geist is open sourced and available free under MIT licence."
/>
</Grid>
</Grid.Container>
</div>
<style jsx>{`
.layout {
min-height: calc(100vh - var(--geist-page-nav-height));
max-width: ${theme.layout.pageWidthWithMargin};
margin: 0 auto;
padding: 0 ${theme.layout.gap} calc(${theme.layout.gap} * 2);
box-sizing: border-box;
}
.hero {
height: calc(100vh - var(--geist-page-nav-height) - 300px);
min-height: 30vh;
max-width: 500px;
margin: 0 auto;
text-align: center;
align-items: center;
justify-content: center;
display: flex;
flex-direction: column;
}
.title {
font-size: 3.75rem;
font-weight: 700;
margin: 0;
}
.desc {
color: ${theme.palette.accents_5};
font-size: 1.5rem;
font-weight: 500;
margin: 0 0 ${theme.layout.gap};
}
`}</style>
</>
)
}
Example #9
Source File: config-provider.tsx From geist-ui with MIT License | 5 votes |
ConfigProvider: React.FC<React.PropsWithChildren<ConfigProviderProps>> = React.memo(
({
onThemeChange,
onThemeTypeChange,
children,
}: React.PropsWithChildren<ConfigProviderProps> & typeof defaultProps) => {
const theme = useTheme()
const { pathname } = useRouter()
const [isChinese, setIsChinese] = useState<boolean>(() =>
pathname.includes(CHINESE_LANGUAGE_IDENT),
)
const [scrollHeight, setScrollHeight] = useState<number>(0)
const [customTheme, setCustomTheme] = useState<GeistUIThemes>(theme)
const updateSidebarScrollHeight = (height: number) => setScrollHeight(height)
const updateChineseState = (state: boolean) => setIsChinese(state)
const updateCustomTheme = (nextTheme: DeepPartial<GeistUIThemes>) => {
const mergedTheme = Themes.create(theme, { ...nextTheme, type: CUSTOM_THEME_TYPE })
setCustomTheme(mergedTheme)
onThemeChange && onThemeChange(mergedTheme)
}
const switchTheme = (type: string) => {
onThemeTypeChange && onThemeTypeChange(type)
}
const initialValue = useMemo<Configs>(
() => ({
onThemeChange,
isChinese,
customTheme,
switchTheme,
updateCustomTheme,
updateChineseState,
sidebarScrollHeight: scrollHeight,
updateSidebarScrollHeight,
}),
[onThemeChange, scrollHeight, isChinese],
)
return (
<ConfigContext.Provider value={initialValue}>{children}</ConfigContext.Provider>
)
},
)
Example #10
Source File: search-item.tsx From geist-ui with MIT License | 5 votes |
SearchItem: React.FC<SearchItemProps> = ({
data,
onMouseOver,
onSelect,
onFocus,
onBlur = () => {},
}) => {
const theme = useTheme()
const selectHandler = () => {
onSelect(data.url)
}
return (
<li role="option">
<button
className="container"
onClick={selectHandler}
onMouseOver={onMouseOver}
onFocus={onFocus}
onBlur={onBlur}
data-search-item>
<SearchIcon data={data} />
<Text pl="12px" font="14px" className="value" span>
{data.name}
</Text>
<style jsx>{`
.container {
width: 100%;
height: 48px;
padding: 0 1rem;
display: flex;
align-items: center;
cursor: pointer;
position: relative;
transition: color 200ms ease;
outline: none;
border: 0;
color: ${theme.palette.accents_4};
background-color: transparent;
}
.container:focus {
color: ${theme.palette.foreground};
}
.container:global(.value) {
}
.container:global(svg) {
width: 16px;
height: 16px;
}
`}</style>
</button>
</li>
)
}
Example #11
Source File: index.tsx From geist-ui with MIT License | 5 votes |
VirtualAnchor: React.FC<React.PropsWithChildren<Props>> = ({ children, pure }) => {
const theme = useTheme()
const ref = useRef<HTMLAnchorElement>(null)
const [id, setId] = useState<string | undefined>()
useEffect(() => {
if (!ref.current) return
setId(virtualAnchorEncode(ref.current.textContent || undefined))
}, [ref.current])
return (
<span className="parent" ref={ref}>
<Link href={`#${id}`}>{children}</Link>
<span className="virtual" id={id} />
{!pure && (
<span className="icon">
<AnchorIcon />
</span>
)}
<style jsx>{`
.parent {
position: relative;
color: inherit;
}
.parent :global(a) {
color: inherit;
}
.virtual {
position: absolute;
top: -65px;
left: 0;
opacity: 0;
pointer-events: none;
visibility: hidden;
}
.icon {
display: inline-flex;
justify-content: center;
align-items: center;
overflow: hidden;
left: -1.5em;
top: 50%;
transform: translateY(-50%);
position: absolute;
opacity: 0;
visibility: hidden;
font-size: inherit;
width: 0.8em;
height: 0.8em;
margin-top: 1px;
color: ${theme.palette.accents_5};
}
.parent:hover > .icon {
opacity: 1;
visibility: visible;
}
`}</style>
</span>
)
}
Example #12
Source File: mock-page.tsx From geist-ui with MIT License | 5 votes |
MockPage: React.FC<React.PropsWithChildren<Props>> = ({
visible: customVisible,
onClose,
children,
}) => {
const theme = useTheme()
const [visible, setVisible] = useState<boolean>(false)
useEffect(() => {
if (customVisible !== undefined) {
setVisible(customVisible)
}
}, [customVisible])
const clickHandler = () => {
setVisible(false)
onClose && onClose()
}
return (
<section onClick={clickHandler} className={visible ? 'active' : ''}>
{children}
<style jsx>{`
section {
position: fixed;
width: 100vw;
height: 100vh;
background-color: ${theme.palette.background};
z-index: 5000;
top: -5000px;
left: -5000px;
display: none;
}
.active {
top: 0;
left: 0;
bottom: 0;
display: block;
}
`}</style>
</section>
)
}
Example #13
Source File: icons-cell.tsx From geist-ui with MIT License | 5 votes |
IconsCell: React.FC<Props> = ({ component: Component, name, onClick }) => {
const theme = useTheme()
return (
<div className="icon-item" key={name} onClick={() => onClick(name)}>
<Component />
<Text type="secondary" small>
{name}
</Text>
<style jsx>{`
.icon-item {
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-evenly;
flex-grow: 0;
flex-basis: 125px;
min-width: 0px;
height: 95px;
margin: 12px 5px;
border-radius: ${theme.layout.radius};
box-sizing: border-box;
cursor: pointer;
user-select: none;
transition: all 150ms ease-in-out;
}
.icon-item > :global(small) {
display: inline-block;
width: 90%;
text-align: center;
overflow: hidden;
text-overflow: ellipsis;
}
.icon-item:hover {
box-shadow: ${theme.expressiveness.shadowMedium};
}
@media only screen and (max-width: ${theme.layout.breakpointMobile}) {
.icon-item {
flex-basis: 30%;
}
}
`}</style>
</div>
)
}
Example #14
Source File: editor-input-item.tsx From geist-ui with MIT License | 5 votes |
EditorInputItem: React.FC<React.PropsWithChildren<Props>> = ({
groupName,
keyName,
}) => {
const theme = useTheme()
const { updateCustomTheme } = useConfigs()
const currentVal = useMemo(() => {
const group = theme[groupName]
const key = keyName as keyof typeof group
return theme[groupName][key]
}, [theme.expressiveness, keyName])
const width = useMemo(() => (`${currentVal}`.length > 15 ? '350px' : 'auto'), [])
const changeHandler = (event: React.ChangeEvent<HTMLInputElement>) => {
updateCustomTheme({
[groupName]: { [keyName]: event.target.value },
})
}
return (
<div className="editor-item">
<Input
value={currentVal as string}
label={keyName}
onChange={changeHandler}
className="editor-input"
/>
<style jsx>{`
.editor-item {
background-color: transparent;
width: auto;
padding: 0;
line-height: 2rem;
display: inline-flex;
align-items: center;
color: ${theme.palette.accents_5};
margin-right: 0.75rem;
margin-bottom: 0.5rem;
cursor: pointer;
transition: color 200ms ease;
}
.editor-item :global(.editor-input) {
width: ${width};
}
`}</style>
</div>
)
}
Example #15
Source File: attributes-title.tsx From geist-ui with MIT License | 5 votes |
AttributesTitle: React.FC<React.PropsWithChildren<AttributesTitleProps>> =
React.memo(({ children, alias }) => {
const theme = useTheme()
const { isChinese } = useConfigs()
return (
<>
<h4 className="title">
<Code>
<VirtualAnchor pure>{children}</VirtualAnchor>
</Code>
{getAlias(!!isChinese, alias)}
</h4>
<style jsx>{`
h4 {
display: inline-flex;
align-items: center;
height: 2rem;
padding-left: ${theme.layout.gapQuarter};
padding-right: ${theme.layout.gapHalf};
background-color: ${theme.palette.accents_1};
border-radius: ${theme.layout.radius};
margin-bottom: 0;
}
h4 :global(small) {
font-size: 0.65em;
padding-left: 0.65rem;
color: ${theme.palette.accents_4};
align-self: flex-end;
line-height: 1.6rem;
}
h4 :global(span) {
color: ${theme.palette.accents_6};
}
`}</style>
</>
)
})
Example #16
Source File: index.tsx From geist-ui with MIT License | 5 votes |
Colors: React.FC<Props> = ({ type }) => {
const theme = useTheme()
const { copy } = useClipboard()
const { setToast } = useToasts()
const copyText = (text: string) => {
copy(text)
setToast({
text: (
<span>
Copied <Code>{text}</Code>
</span>
),
})
}
const colorItems = useMemo(
() => getColorItem(type, theme.palette, copyText),
[type, theme.palette],
)
return (
<div className="colors">
{colorItems}
<style jsx>{`
.colors {
display: flex;
flex-direction: column;
width: 100%;
}
.colors :global(.color) {
padding: ${theme.layout.gap};
position: relative;
user-select: none;
}
.colors :global(.color:first-child) {
border-top-left-radius: ${theme.layout.radius};
border-top-right-radius: ${theme.layout.radius};
}
.colors :global(.color:last-child) {
border-bottom-left-radius: ${theme.layout.radius};
border-bottom-right-radius: ${theme.layout.radius};
}
.colors :global(.color h4) {
margin: 0;
}
.colors :global(.usage) {
font-size: 1rem;
padding: 1rem;
cursor: pointer;
}
.colors :global(.value) {
font-size: 0.875rem;
text-transform: uppercase;
padding: 1rem;
cursor: pointer;
}
`}</style>
</div>
)
}
Example #17
Source File: active-link.tsx From geist-ui with MIT License | 5 votes |
ActiveLink: React.FC<Props> = React.memo(({ href, text }) => {
const theme = useTheme()
const { pathname } = useRouter()
const [title, subtitle] = useMemo(() => {
if (!/[\u4E00-\u9FA5]/.test(text)) return [text, null]
if (/zeit|ui|ZEIT|geist|Geist|UI/.test(text)) return [text, null]
return [text.replace(/[^\u4E00-\u9FA5]/g, ''), text.replace(/[^a-zA-Z]/g, '')]
}, [text])
const isActive = pathname === href
return (
<>
<Link href={href}>
<a className={`link ${isActive ? 'active' : ''}`}>
{title}
{subtitle && <span> {subtitle}</span>}
</a>
</Link>
<style jsx>{`
a {
font: inherit;
}
.link {
display: flex;
align-items: baseline;
font-size: 1rem;
color: ${theme.palette.accents_6};
padding: calc(${theme.layout.unit} * 0.375) 0;
transition: all 200ms ease;
}
span {
font-size: 0.75rem;
color: ${theme.palette.accents_4};
font-weight: 400;
}
.link.active {
color: ${theme.palette.success};
font-weight: 600;
}
.link.active span {
color: ${theme.palette.successLight};
}
`}</style>
</>
)
})
Example #18
Source File: sidebar.tsx From geist-ui with MIT License | 5 votes |
Sidebar: React.FC<Props> = React.memo(() => {
const theme = useTheme()
const boxRef = useRef<HTMLDivElement>(null)
const { sidebarScrollHeight, updateSidebarScrollHeight } = useConfigs()
const { locale, tabbar } = useLocale()
const tabbarData = useMemo(() => {
const allSides = Metadata[locale]
const currentSide = allSides.find(side => side.name === tabbar)
return (currentSide?.children || []) as Array<Sides>
}, [locale, tabbar])
useEffect(() => {
Router.events.on('routeChangeStart', () => {
if (!boxRef.current) return
updateSidebarScrollHeight(boxRef.current.scrollTop || 0)
})
}, [])
useEffect(() => {
if (!boxRef.current) return
boxRef.current.scrollTo({ top: sidebarScrollHeight })
}, [boxRef.current])
return (
<div ref={boxRef} className="sides box">
<SideItem sides={tabbarData}>
<SideGroup />
</SideItem>
<Spacer />
<style jsx>{`
.sides {
width: 100%;
padding-bottom: ${theme.layout.gap};
}
.box {
overflow-y: auto;
overflow-x: hidden;
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
}
.box::-webkit-scrollbar {
width: 0;
background-color: transparent;
}
.box > :global(.item) {
margin-bottom: ${theme.layout.gap};
}
`}</style>
</div>
)
})
Example #19
Source File: menu.tsx From geist-ui with MIT License | 4 votes |
Menu: React.FC<unknown> = () => {
const router = useRouter()
const theme = useTheme()
const { isChinese } = useConfigs()
const { tabbar: currentUrlTabValue, locale } = useLocale()
const [expanded, setExpanded] = useState<boolean>(false)
const [, setBodyHidden] = useBodyScroll(null, { delayReset: 300 })
const isMobile = useMediaQuery('xs', { match: 'down' })
const allSides = useMemo(() => Metadata[locale], [locale])
useEffect(() => {
const prefetch = async () => {
const urls = isChinese
? ['/zh-cn/guide/introduction', '/zh-cn/components/text', '/zh-cn/customization']
: ['/en-us/guide/introduction', '/en-us/components/text', '/en-us/customization']
await Promise.all(
urls.map(async url => {
await router.prefetch(url)
}),
)
}
prefetch()
.then()
.catch(err => console.log(err))
}, [isChinese])
useEffect(() => {
setBodyHidden(expanded)
}, [expanded])
useEffect(() => {
if (!isMobile) {
setExpanded(false)
}
}, [isMobile])
useEffect(() => {
const handleRouteChange = () => {
setExpanded(false)
}
router.events.on('routeChangeComplete', handleRouteChange)
return () => router.events.off('routeChangeComplete', handleRouteChange)
}, [router.events])
const handleTabChange = useCallback(
(tab: string) => {
const shouldRedirectDefaultPage = currentUrlTabValue !== tab
if (!shouldRedirectDefaultPage) return
const defaultPath = `/${locale}/${tab}`
router.push(defaultPath)
},
[currentUrlTabValue, locale],
)
const [isLocked, setIsLocked] = useState<boolean>(false)
useEffect(() => {
const handler = () => {
const isLocked = document.body.style.overflow === 'hidden'
setIsLocked(last => (last !== isLocked ? isLocked : last))
}
const observer = new MutationObserver(mutations => {
mutations.forEach(function (mutation) {
if (mutation.type !== 'attributes') return
handler()
})
})
observer.observe(document.body, {
attributes: true,
})
return () => {
observer.disconnect()
}
}, [])
return (
<>
<div className="menu-wrapper">
<nav className="menu">
<div className="content">
<div className="logo">
<NextLink href={`/${locale}`}>
<a aria-label="Go Home">
<Image
src="/images/logo.png"
width="20px"
height="20px"
mr={0.5}
draggable={false}
title="Logo"
/>
Geist
</a>
</NextLink>
</div>
<div className="tabs">
<Tabs
value={currentUrlTabValue}
leftSpace={0}
activeClassName="current"
align="center"
hideDivider
hideBorder
onChange={handleTabChange}>
<Tabs.Item font="14px" label={isChinese ? '主页' : 'Home'} value="" />
{allSides.map((tab, index) => (
<Tabs.Item
font="14px"
label={tab.localeName || tab.name}
value={tab.name}
key={`${tab.localeName || tab.name}-${index}`}
/>
))}
</Tabs>
</div>
<div className="controls">
{isMobile ? (
<Button
className="menu-toggle"
auto
type="abort"
onClick={() => setExpanded(!expanded)}>
<MenuIcon size="1.125rem" />
</Button>
) : (
<Controls />
)}
</div>
</div>
</nav>
</div>
<MenuMobile expanded={expanded} />
<style jsx>{`
.menu-wrapper {
height: var(--geist-page-nav-height);
}
.menu {
position: fixed;
top: 0;
left: 0;
right: 0;
padding-right: ${isLocked ? 'var(--geist-page-scrollbar-width)' : 0};
height: var(--geist-page-nav-height);
//width: 100%;
backdrop-filter: saturate(180%) blur(5px);
background-color: ${addColorAlpha(theme.palette.background, 0.8)};
box-shadow: ${theme.type === 'dark'
? '0 0 0 1px #333'
: '0 0 15px 0 rgba(0, 0, 0, 0.1)'};
z-index: 999;
}
nav .content {
display: flex;
align-items: center;
justify-content: space-between;
max-width: 1000px;
height: 100%;
margin: 0 auto;
user-select: none;
padding: 0 ${theme.layout.gap};
}
.logo {
flex: 1 1;
display: flex;
align-items: center;
justify-content: flex-start;
}
.logo a {
display: inline-flex;
flex-direction: row;
align-items: center;
font-size: 1.125rem;
font-weight: 500;
color: inherit;
height: 28px;
}
.logo :global(.image) {
border: 1px solid ${theme.palette.border};
border-radius: 2rem;
}
.tabs {
flex: 1 1;
padding: 0 ${theme.layout.gap};
}
.tabs :global(.content) {
display: none;
}
@media only screen and (max-width: ${theme.breakpoints.xs.max}) {
.tabs {
display: none;
}
}
.controls {
flex: 1 1;
display: flex;
align-items: center;
justify-content: flex-end;
}
.controls :global(.menu-toggle) {
display: flex;
align-items: center;
min-width: 40px;
height: 40px;
padding: 0;
}
`}</style>
</>
)
}
Example #20
Source File: menu-mobile.tsx From geist-ui with MIT License | 4 votes |
MenuMobile: React.FC<Props> = ({ expanded }) => {
const theme = useTheme()
const { pathname } = useRouter()
const { isChinese } = useConfigs()
const { locale } = useLocale()
const menuData = useMemo(() => Metadata[locale], [locale])
const [expandedGroupName, setExpandedGroupName] = React.useState<string | null>(null)
const handleGroupClick = (name: string) => {
setExpandedGroupName(expandedGroupName === name ? null : name)
}
if (!expanded) return null
return (
<div className="mobile-menu">
<div className="content">
<NextLink href={`/${locale}`}>
<a className={`menu-item fadein ${pathname === `/${locale}` ? 'active' : ''}`}>
{isChinese ? '主页' : 'Home'}
</a>
</NextLink>
{menuData.map((group, index) => (
<div
key={group.name}
className="fadein"
style={{ animationDelay: `${(index + 1) * 50}ms` }}>
<button
className={`menu-item ${expandedGroupName === group.name && 'expanded'}`}
onClick={() => handleGroupClick(group.name)}>
<ChevronRightIcon
size="1rem"
strokeWidth={2}
color={theme.palette.accents_4}
/>
{group.name}
</button>
{expandedGroupName === group.name && (
<div className="group">
{(group.children as Array<Sides>).map(section => (
<div key={section.name}>
<span className="section-name">{section.name}</span>
{(section.children as Array<Sides>).map(item => (
<NextLink href={item.url || '/'} key={item.url}>
<a
className={`section-item ${
pathname === item.url ? 'active' : ''
}`}>
{item.name}
</a>
</NextLink>
))}
</div>
))}
</div>
)}
</div>
))}
</div>
<style jsx>{`
.mobile-menu {
position: fixed;
top: var(--geist-page-nav-height);
height: calc(100vh - var(--geist-page-nav-height));
width: 100vw;
overflow-y: auto;
z-index: 999;
box-sizing: border-box;
background-color: ${theme.palette.background};
overflow-y: auto;
}
.fadein {
animation: fadeIn 200ms ease;
animation-fill-mode: forwards;
opacity: 0;
}
.menu-item {
padding: 0 ${theme.layout.gapHalf};
margin: 0 ${theme.layout.gap};
height: 48px;
width: 100%;
display: flex;
align-items: center;
border: none;
background: none;
outline: none;
border-bottom: 1px solid ${theme.palette.accents_2};
text-transform: capitalize;
color: ${theme.palette.accents_6};
cursor: pointer;
}
.menu-item :global(svg) {
transform: translateX(${theme.layout.gapQuarterNegative});
transition: transform 250ms ease;
}
.menu-item.expanded {
border-bottom: none;
}
.menu-item.expanded :global(svg) {
transform: rotate(90deg) translateY(${theme.layout.gapQuarter});
}
.group {
background: ${theme.palette.accents_1};
padding: 0 calc(${theme.layout.gap} * 1.5) ${theme.layout.gap};
border-top: 1px solid ${theme.palette.accents_2};
}
.section-name {
display: block;
font-size: 0.75rem;
text-transform: uppercase;
color: ${theme.palette.accents_5};
margin-top: ${theme.layout.gap};
margin-bottom: ${theme.layout.gapHalf};
}
.section-item {
padding: ${theme.layout.gapQuarter} ${theme.layout.gap};
margin: 0 ${theme.layout.gapQuarter};
width: 100%;
display: flex;
align-items: center;
border: none;
background: none;
outline: none;
color: ${theme.palette.accents_6};
border-left: 1px solid ${theme.palette.accents_2};
}
.active {
color: ${theme.palette.link};
font-weight: 500;
}
@keyframes fadeIn {
from {
transform: translate3d(0, 0.375rem, 0);
opacity: 0;
}
to {
transform: translate3d(0, 0, 0);
opacity: 1;
}
}
`}</style>
</div>
)
}
Example #21
Source File: editor.tsx From geist-ui with MIT License | 4 votes |
Editor: React.FC<Props> = ({ code }) => {
const theme = useTheme()
const { copy } = useClipboard()
const { isChinese } = useConfigs()
const [visible, setVisible] = useState(false)
const { setToast } = useToasts()
const clickHandler = (event: React.MouseEvent) => {
event.stopPropagation()
event.preventDefault()
setVisible(!visible)
}
const copyHandler = (event: React.MouseEvent) => {
event.stopPropagation()
event.preventDefault()
copy(code)
setToast({ text: isChinese ? '代码已拷贝至剪切板。' : 'code copied.' })
}
return (
<div className="editor">
<details open={visible}>
<summary onClick={clickHandler}>
<div className="summary-safari">
<div className="action">
<span className="arrow">
<RightIcon size={16} />
</span>
<span>{isChinese ? '编辑代码' : 'Code Editor'}</span>
</div>
<div className="action">
{visible && (
<span
className="copy"
onClick={copyHandler}
title={isChinese ? '拷贝代码' : 'Copy Code'}>
<CopyIcon size={18} />
</span>
)}
</div>
</div>
</summary>
<div className="area">
<LiveEditor />
</div>
</details>
<style jsx>{`
.editor {
border-bottom-left-radius: ${theme.layout.radius};
border-bottom-right-radius: ${theme.layout.radius};
}
details {
transition: all 0.2s ease;
overflow: hidden;
border-bottom-left-radius: ${theme.layout.radius};
border-bottom-right-radius: ${theme.layout.radius};
}
details summary::-webkit-details-marker {
display: none;
}
summary {
box-sizing: border-box;
border-top: 1px solid ${theme.palette.accents_2};
color: ${theme.palette.accents_5};
width: 100%;
list-style: none;
user-select: none;
outline: none;
}
.summary-safari {
box-sizing: border-box;
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
height: 2.875rem;
padding: 0 ${theme.layout.gap};
}
summary :global(svg) {
cursor: pointer;
}
.action {
width: auto;
display: flex;
align-items: center;
font-size: 0.8rem;
}
.area {
position: relative;
box-sizing: border-box;
white-space: pre;
font-family: ${theme.font.mono};
color: ${theme.palette.foreground};
background-color: ${theme.palette.background};
font-size: 1em;
overflow: hidden;
border-top: 1px solid ${theme.palette.accents_2};
padding: ${theme.layout.gapHalf};
}
.arrow {
transition: all 0.2s ease;
transform: rotate(${visible ? 90 : 0}deg);
display: inline-flex;
align-items: center;
width: 1rem;
height: 1rem;
margin-right: 0.5rem;
}
.copy {
display: inline-flex;
align-items: center;
color: ${theme.palette.accents_4};
transition: color 0.2s ease;
}
.copy:hover {
color: ${theme.palette.accents_6};
}
`}</style>
</div>
)
}
Example #22
Source File: editor.tsx From geist-ui with MIT License | 4 votes |
Editor = () => {
const theme = useTheme()
const DefaultTheme = Themes.getPresetStaticTheme()
const { updateCustomTheme, isChinese } = useConfigs()
// const resetLayout = () => updateCustomTheme({ layout: DefaultTheme.layout })
const restColors = () => updateCustomTheme({ palette: DefaultTheme.palette })
const resetExpressiveness = () => {
updateCustomTheme({ expressiveness: DefaultTheme.expressiveness })
}
return (
<div className="editor">
<Text h3 mt="40px" font="22px">
{isChinese ? '色彩' : 'Colors'}
<Button
type="abort"
icon={<RotateCcwIcon />}
auto
px={0.65}
scale={0.4}
ml="10px"
onClick={restColors}
/>
</Text>
<p className="subtitle">{isChinese ? '基础' : 'basic'}</p>
<div className="content">
{basicColors.map((item, index) => (
<EditorColorItem key={`${item}-${index}`} keyName={item} />
))}
</div>
<p className="subtitle">{isChinese ? '状态' : 'status'}</p>
<div className="content">
{statusColors.map((item, index) => (
<EditorColorItem key={`${item}-${index}`} keyName={item} />
))}
</div>
<p className="subtitle">{isChinese ? '其他' : 'others'}</p>
<div className="content">
{otherColors.map((item, index) => (
<EditorColorItem key={`${item}-${index}`} keyName={item} />
))}
</div>
<Text h3 mt="40px">
{isChinese ? '表现力' : 'Expressiveness'}
<Button
type="abort"
icon={<RotateCcwIcon />}
auto
px={0.65}
scale={0.4}
ml="10px"
onClick={resetExpressiveness}
/>
</Text>
<p className="subtitle">{isChinese ? '基础' : 'basic'}</p>
<div className="content">
{expressiveness.map((item, index) => (
<EditorInputItem
key={`${item}-${index}`}
groupName="expressiveness"
keyName={item}
/>
))}
</div>
<style jsx>{`
.content {
display: flex;
justify-content: flex-start;
align-items: center;
flex-wrap: wrap;
width: auto;
margin: 0 auto;
padding-left: ${theme.layout.gapQuarter};
}
.subtitle {
color: ${theme.palette.accents_4};
text-transform: uppercase;
font-size: 0.75rem;
margin-top: 2rem;
}
`}</style>
</div>
)
}
Example #23
Source File: attributes-table.tsx From geist-ui with MIT License | 4 votes |
AttributesTable: React.FC<React.PropsWithChildren<unknown>> = ({ children }) => {
const theme = useTheme()
return (
<Card className="attr">
{children}
<style jsx global>{`
.attr .pre {
margin-top: 12px !important;
}
.attr table {
margin-top: 12px;
margin-right: ${theme.layout.gap};
}
.attr h4.title {
margin-top: calc(${theme.layout.gap} * 2.2);
}
.attr h4.title:first-of-type {
margin-top: 0;
}
.attr table {
border-collapse: separate;
border-spacing: 0;
width: 100%;
}
.attr thead th td {
height: 2.5rem;
}
.attr tbody tr td {
height: 3.333rem;
}
.attr th,
.attr td {
padding: 0 0.625rem;
text-align: left;
}
.attr th {
height: 2.5rem;
color: ${theme.palette.accents_5};
font-size: 0.75rem;
font-weight: 400;
letter-spacing: 0;
background: ${theme.palette.accents_1};
border-bottom: 1px solid ${theme.palette.border};
border-top: 1px solid ${theme.palette.border};
}
.attr th:nth-child(1) {
border-bottom: 1px solid ${theme.palette.border};
border-left: 1px solid ${theme.palette.border};
border-radius: 4px 0 0 4px;
border-top: 1px solid ${theme.palette.border};
}
.attr th:last-child {
border-bottom: 1px solid ${theme.palette.border};
border-radius: 0 4px 4px 0;
border-right: 1px solid ${theme.palette.border};
border-top: 1px solid ${theme.palette.border};
}
.attr tr td {
border-bottom: 1px solid ${theme.palette.border};
color: ${theme.palette.accents_6};
font-size: 0.875rem;
height: 2.5rem;
}
.attr td:nth-child(1) {
border-left: 1px solid transparent;
}
@media only screen and (max-width: ${theme.layout.breakpointMobile}) {
.attr {
overflow-x: scroll;
}
.attr::-webkit-scrollbar {
width: 0;
height: 0;
background-color: transparent;
}
}
`}</style>
</Card>
)
}
Example #24
Source File: controls.tsx From geist-ui with MIT License | 4 votes |
Controls: React.FC<unknown> = React.memo(() => {
const theme = useTheme()
const { themes } = useAllThemes()
const { switchTheme, updateChineseState } = useConfigs()
const { pathname } = useRouter()
const { locale } = useLocale()
const isChinese = useMemo(() => locale === CHINESE_LANGUAGE_IDENT, [locale])
const nextLocalePath = useMemo(() => {
const nextLocale = isChinese ? ENGLISH_LANGUAGE_IDENT : CHINESE_LANGUAGE_IDENT
return pathname.replace(locale, nextLocale)
}, [locale, pathname])
const hasCustomTheme = useMemo(() => Themes.hasUserCustomTheme(themes), [themes])
const switchThemes = (type: string) => {
switchTheme(type)
if (typeof window === 'undefined' || !window.localStorage) return
window.localStorage.setItem('theme', type)
}
const switchLanguages = () => {
updateChineseState(!isChinese)
Router.push(nextLocalePath)
}
const redirectGithub = () => {
if (typeof window === 'undefined') return
window.open(GITHUB_URL)
}
return (
<div className="wrapper">
<Keyboard
h="28px"
command
font="12px"
className="shortcuts"
title="Command + K to search.">
K
</Keyboard>
<Spacer w={0.75} />
<Button
w="28px"
h="28px"
py={0}
px={0}
onClick={switchLanguages}
title={isChinese ? '切换语言' : 'switch language'}>
<Text font="13px" style={{ fontWeight: 500 }}>
{isChinese ? 'En' : '中'}
</Text>
</Button>
<Spacer w={0.75} />
<Button
w="28px"
h="28px"
py={0}
px={0}
icon={<GitHubIcon />}
onClick={redirectGithub}
title={isChinese ? '代码仓库' : 'GitHub Repository'}
/>
<Spacer w={0.75} />
<Select
scale={0.5}
h="28px"
pure
onChange={switchThemes}
value={theme.type}
title={isChinese ? '切换主题' : 'Switch Themes'}>
<Select.Option value="light">
<span className="select-content">
<SunIcon size={14} /> {isChinese ? '明亮' : 'Light'}
</span>
</Select.Option>
<Select.Option value="dark">
<span className="select-content">
<MoonIcon size={14} /> {isChinese ? '暗黑' : 'Dark'}
</span>
</Select.Option>
{hasCustomTheme && (
<Select.Option value={CUSTOM_THEME_TYPE}>
<span className="select-content">
<UserIcon size={14} /> {CUSTOM_THEME_TYPE}
</span>
</Select.Option>
)}
</Select>
<style jsx>{`
.wrapper {
display: flex;
align-items: center;
}
.wrapper :global(kbd.shortcuts) {
line-height: 28px !important;
cursor: help;
opacity: 0.75;
border: none;
}
.wrapper :global(.select) {
width: 85px;
min-width: 85px;
}
.select-content {
width: auto;
height: 18px;
display: flex;
justify-content: space-between;
align-items: center;
}
.select-content :global(svg) {
margin-right: 10px;
margin-left: 2px;
}
`}</style>
</div>
)
})
Example #25
Source File: editor-color-item.tsx From geist-ui with MIT License | 4 votes |
EditorColorItem: React.FC<React.PropsWithChildren<Props>> = ({ keyName }) => {
const theme = useTheme()
const { updateCustomTheme } = useConfigs()
const label = `${keyName}`
const mainColor = useMemo(() => theme.palette[keyName], [theme.palette, keyName])
const randomColors = useMemo(() => getRandomColors(), [])
const colorChangeHandler = ({ hex }: ColorResult) => {
updateCustomTheme({
palette: { [keyName]: hex },
})
}
const popoverContent = (color: string) => (
<TwitterPicker
triangle="hide"
color={color}
onChangeComplete={colorChangeHandler}
colors={randomColors}
/>
)
return (
<Popover
content={() => popoverContent(mainColor)}
portalClassName="editor-popover"
offset={3}>
<div className="editor-item">
<div className="dot-box">
<span className="dot" />
</div>
{label}
<style jsx>{`
.editor-item {
background-color: transparent;
width: auto;
padding: 0 ${theme.layout.gapHalf};
line-height: 2rem;
display: inline-flex;
align-items: center;
border: 1px solid ${theme.palette.border};
border-radius: ${theme.layout.radius};
color: ${theme.palette.accents_5};
margin-right: 0.75rem;
margin-bottom: 0.5rem;
cursor: pointer;
transition: color 200ms ease;
}
:global(.editor-popover .inner) {
padding: 0 !important;
}
:global(.editor-popover .twitter-picker) {
box-shadow: none !important;
border: 0 !important;
background: transparent !important;
}
.editor-item:hover {
color: ${theme.palette.accents_8};
}
.editor-item:hover .dot {
transform: scale(1);
}
.dot-box,
.dot {
display: inline-flex;
justify-content: center;
align-items: center;
}
.dot-box {
width: 1rem;
height: 1rem;
margin-right: 0.75rem;
}
.dot {
width: 100%;
height: 100%;
border-radius: 50%;
background-color: ${mainColor};
transform: scale(0.8);
transition: transform 200ms ease;
}
`}</style>
</div>
</Popover>
)
}
Example #26
Source File: search-items.tsx From geist-ui with MIT License | 4 votes |
SearchItems = React.forwardRef<
SearchItemsRef,
React.PropsWithChildren<SearchItemsProps>
>(
(
{ data, onSelect, preventHoverHighlightSync },
outRef: React.Ref<SearchItemsRef | null>,
) => {
const theme = useTheme()
const { rect, setRect } = useRect()
const ref = useRef<HTMLUListElement | null>(null)
const [displayHighlight, setDisplayHighlight] = useState<boolean>(false)
useImperativeHandle(outRef, () =>
Object.assign(ref.current, {
closeHighlight: () => setDisplayHighlight(false),
}),
)
const hoverHandler = (event: MouseEvent<HTMLButtonElement>) => {
if (preventHoverHighlightSync) return
if (!isSearchItem(event.target as HTMLButtonElement)) return
;(event.target as HTMLButtonElement).focus()
}
const focusHandler = (event: FocusEvent<HTMLButtonElement>) => {
if (!isSearchItem(event.target as HTMLButtonElement)) return
setRect(event, () => ref.current)
setDisplayHighlight(true)
}
const blurHandler = () => {
setDisplayHighlight(false)
}
const grouppedResults = useMemo(() => groupResults(data), [data])
return (
<ul className="results" role="listbox" ref={ref}>
<Highlight
className="results-hover"
rect={rect}
visible={displayHighlight}
activeOpacity={0.5}
/>
{grouppedResults.map((group) => (
<li role="presentation" key={group.title}>
<div className="group-title">{group.title}</div>
<ul role="group">
{group.items.map(item => (
<SearchItem
onSelect={onSelect}
onMouseOver={hoverHandler}
onFocus={focusHandler}
onBlur={blurHandler}
data={item}
key={item.url}
/>
))}
</ul>
</li>
))}
<style jsx>{`
.results {
width: 100%;
max-height: 300px;
overflow-y: auto;
position: relative;
scroll-behavior: smooth;
margin-bottom: 0.5rem;
}
.results :global(li:before) {
content: none;
}
.group-title {
color: ${theme.palette.accents_5};
font-size: 0.75rem;
text-align: start;
margin: 0.25rem 0;
}
.results:global(div.highlight.results-hover) {
border-radius: 8px;
}
`}</style>
</ul>
)
},
)
Example #27
Source File: search.tsx From geist-ui with MIT License | 4 votes |
Search: React.FC<unknown> = () => {
const theme = useTheme()
const router = useRouter()
const { locale } = useLocale()
const [preventHover, setPreventHover, preventHoverRef] = useCurrentState<boolean>(false)
const ref = useRef<HTMLInputElement | null>(null)
const itemsRef = useRef<SearchItemsRef | null>(null)
const [state, setState] = useState<SearchResults>([])
const { bindings, setVisible, visible } = useModal(false)
const { bindings: inputBindings, setState: setInput, state: input } = useInput('')
const cleanAfterModalClose = () => {
setVisible(false)
const timer = window.setTimeout(() => {
setState([])
setInput('')
itemsRef.current?.scrollTo(0, 0)
setPreventHover(true)
window.clearTimeout(timer)
}, 400)
}
useKeyboard(() => {
setVisible(true)
const timer = setTimeout(() => {
ref.current?.focus()
window.clearTimeout(timer)
}, 0)
}, [KeyMod.CtrlCmd, KeyCode.KEY_K])
useEffect(() => {
if (!input) return setState([])
setPreventHover(true)
setState(search(input, locale))
itemsRef.current?.scrollTo(0, 0)
}, [input])
useEffect(() => {
if (visible) return
cleanAfterModalClose()
}, [visible])
useEffect(() => {
const eventHandler = () => {
if (!preventHoverRef.current) return
setPreventHover(false)
}
document.addEventListener('mousemove', eventHandler)
return () => {
document.removeEventListener('mousemove', eventHandler)
}
}, [])
const selectHandler = (url: string) => {
if (url.startsWith('http')) return window.open(url)
router.push(url)
setVisible(false)
}
const { bindings: KeyBindings } = useKeyboard(
event => {
const isBack = event.keyCode === KeyCode.UpArrow
focusNextElement(
itemsRef.current,
() => {
setPreventHover(true)
},
isBack,
)
},
[KeyCode.DownArrow, KeyCode.UpArrow],
{
disableGlobalEvent: true,
},
)
return (
<div className="container" {...KeyBindings}>
<Modal
{...bindings}
py={0}
px={0.75}
wrapClassName="search-menu"
positionClassName="search-position">
<Input
ref={ref}
w="100%"
font="1.125rem"
py={0.75}
placeholder="Search a component"
className="search-input"
clearable
{...inputBindings}
/>
{state.length > 0 && (
<>
<Divider mt={0} mb={1} />
<SearchItems
preventHoverHighlightSync={preventHover}
ref={itemsRef}
data={state}
onSelect={selectHandler}
/>
</>
)}
</Modal>
<style jsx>{`
.title {
width: 100%;
color: ${theme.palette.background};
background-color: ${theme.palette.violet};
display: flex;
justify-content: flex-end;
padding: 0 10px;
user-select: none;
}
.container {
visibility: hidden;
}
:global(.search-menu ul),
:global(.search-menu li) {
padding: 0;
margin: 0;
list-style: none;
}
:global(.search-menu .input-container.search-input) {
border: none;
border-radius: 0;
}
:global(.search-menu .input-container div.input-wrapper) {
border: none;
border-radius: 0;
}
:global(.search-menu .input-container .input-wrapper.hover) {
border: none;
}
:global(.search-menu .input-container .input-wrapper:active) {
border: none;
}
:global(div.search-position.position) {
position: absolute;
top: 100px;
left: 50%;
transform: translateX(-50%);
transition: all 500ms ease;
width: 500px;
height: auto;
}
:global(.search-menu.wrapper) {
box-shadow: 0 5px 20px 0 rgba(0, 0, 0, 0.15), 0 -5px 20px 0 rgba(0, 0, 0, 0.15) !important;
}
`}</style>
</div>
)
}
Example #28
Source File: demo.tsx From geist-ui with MIT License | 4 votes |
Demo: React.FC<React.PropsWithChildren<unknown>> = () => {
const theme = useTheme()
const { isChinese } = useConfigs()
return (
<div className="demo">
<div className="content">
{isChinese ? (
<>
<Text h2 mb={0} font="13px" type="secondary">
预览
</Text>
<Text>
这里是你变更主题后的即时预览。此外,当你每次更新主题变量时,整个文档站点也会随之变化。
</Text>
</>
) : (
<>
<Text h2 mb={0} font="13px">
PREVIEWS
</Text>
<Text>
Here's a preview of your changes to the Theme. When you set the changes,
the entire document site will change with the theme.
</Text>
</>
)}
<Spacer h={1.7} />
<Text h3 font="13px" type="secondary">
{isChinese ? '色彩' : 'COLORS'}
</Text>
<Colors />
<Spacer h={1.7} />
<Text h3 font="13px" type="secondary">
{isChinese ? '排版' : 'Typography'}
</Text>
<Text>
<Link rel="nofollow" href="https://en.wikipedia.org/wiki/HTTP/2" color>
HTTP/2
</Link>{' '}
allows the server to <Code>push</Code> content, that is, to respond with data
for more queries than the client requested. This allows the server to supply
data it knows a web browser will need to render a web page, without waiting for
the browser to examine the first response, and without the overhead of an
additional request cycle.
</Text>
<Text h6>Heading</Text>
<Text h5>Heading</Text>
<Text h4>Heading</Text>
<Text h3>Heading</Text>
<Spacer h={1.7} />
<Text h3 font="13px" type="secondary">
{isChinese ? '基础组件' : 'Basic Components'}
</Text>
<Select width="90%" placeholder="Choose one" initialValue="1">
<Select.Option value="1">Option 1</Select.Option>
<Select.Option value="2">Option 2</Select.Option>
</Select>
<Spacer h={1} />
<Grid.Container width="100%">
<Grid xs={8}>
<Button disabled auto>
Action
</Button>
</Grid>
<Grid xs={8}>
<Button auto>Action</Button>
</Grid>
<Grid xs={8}>
<Button auto type="secondary">
Action
</Button>
</Grid>
</Grid.Container>
</div>
<style jsx>{`
.demo {
width: 34%;
margin-top: calc(${theme.layout.gap} * 2);
margin-right: ${theme.layout.gap};
padding-right: ${theme.layout.gapQuarter};
position: relative;
border-right: 1px solid ${theme.palette.border};
height: auto;
transition: width 200ms ease;
}
.content {
width: 100%;
}
@media only screen and (max-width: ${theme.layout.breakpointMobile}) {
.demo {
display: none;
}
}
`}</style>
</div>
)
}
Example #29
Source File: _app.tsx From geist-ui with MIT License | 4 votes |
Application: NextPage<AppProps<{}>> = ({ Component, pageProps }) => {
const theme = useTheme()
const [themeType, setThemeType] = useState<string>()
const [customTheme, setCustomTheme] = useState<GeistUIThemes>(theme)
const themeChangeHandle = (theme: GeistUIThemes) => {
setCustomTheme(theme)
setThemeType(theme.type)
}
useEffect(() => {
const theme = window.localStorage.getItem('theme')
if (theme !== 'dark') return
setThemeType('dark')
}, [])
useDomClean()
return (
<>
<Head>
<title>Geist UI - Modern and minimalist React UI library</title>
<meta name="google" content="notranslate" />
<meta name="twitter:creator" content="@echo_witt" />
<meta name="referrer" content="strict-origin" />
<meta property="og:title" content="Geist UI" />
<meta property="og:site_name" content="Geist UI" />
<meta property="og:url" content="https://geist-ui.dev" />
<link rel="dns-prefetch" href="//geist-ui.dev" />
<meta name="twitter:card" content="summary_large_image" />
<meta name="generator" content="Geist UI" />
<meta
name="description"
content="An open-source design system for building modern websites and applications."
/>
<meta
property="og:description"
content="An open-source design system for building modern websites and applications."
/>
<meta
itemProp="image"
property="og:image"
content="https://user-images.githubusercontent.com/11304944/91128466-dfc96c00-e6da-11ea-8b03-a96e6b98667d.png"
/>
<meta
property="og:image"
content="https://user-images.githubusercontent.com/11304944/91128466-dfc96c00-e6da-11ea-8b03-a96e6b98667d.png"
/>
<meta
property="twitter:image"
content="https://user-images.githubusercontent.com/11304944/91128466-dfc96c00-e6da-11ea-8b03-a96e6b98667d.png"
/>
<meta
name="viewport"
content="initial-scale=1, maximum-scale=1, minimum-scale=1, viewport-fit=cover"
/>
</Head>
<GeistProvider themeType={themeType} themes={[customTheme]}>
<CssBaseline />
<ConfigContext
onThemeChange={themeChangeHandle}
onThemeTypeChange={type => setThemeType(type)}>
<Menu />
<Search />
<MDXProvider
components={{
a: HybridLink,
img: Image,
pre: HybridCode,
}}>
<Component {...pageProps} />
</MDXProvider>
</ConfigContext>
<style global jsx>{`
.tag {
color: ${theme.palette.accents_5};
}
.punctuation {
color: ${theme.palette.accents_5};
}
.attr-name {
color: ${theme.palette.accents_6};
}
.attr-value {
color: ${theme.palette.accents_4};
}
.language-javascript {
color: ${theme.palette.accents_4};
}
span.class-name {
color: ${theme.palette.warning};
}
span.maybe-class-name {
color: ${theme.palette.purple};
}
span.token.string {
color: ${theme.palette.accents_5};
}
span.token.comment {
color: ${theme.palette.accents_3};
}
span.keyword {
color: ${theme.palette.success};
}
span.plain-text {
color: ${theme.palette.accents_3};
}
body::-webkit-scrollbar {
width: var(--geist-page-scrollbar-width);
background-color: ${theme.palette.accents_1};
}
body::-webkit-scrollbar-thumb {
background-color: ${theme.palette.accents_2};
border-radius: ${theme.layout.radius};
}
:root {
--geist-page-nav-height: 64px;
--geist-page-scrollbar-width: 4px;
}
`}</style>
</GeistProvider>
</>
)
}