mirror of
https://github.com/wavetermdev/docusaurus-og.git
synced 2026-08-05 13:46:35 -07:00
feat: landing page redesign
This commit is contained in:
+3
-5
@@ -50,11 +50,9 @@
|
||||
}
|
||||
}
|
||||
|
||||
@include utils.responsive('md', 'up') {
|
||||
.mdx-cta-section:not(.mdx-cta-section--with-description) {
|
||||
.mdx-cta-section__title {
|
||||
max-width: 65%;
|
||||
}
|
||||
.mdx-cta-section:not(.mdx-cta-section--with-description) {
|
||||
.mdx-cta-section__title {
|
||||
max-width: 886px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
.mdx-hero {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: calc(100vh - var(--ifm-navbar-height) - 8px);
|
||||
}
|
||||
|
||||
.mdx-hero--large {
|
||||
|
||||
@@ -19,6 +19,11 @@
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: stretch;
|
||||
z-index: 0;
|
||||
|
||||
& > * {
|
||||
flex-basis: 50%;
|
||||
}
|
||||
|
||||
> a,
|
||||
> a > button {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { Typography, TypographyProps } from '@acid-info/lsd-react'
|
||||
import clsx from 'clsx'
|
||||
import React from 'react'
|
||||
import './HeroActions.scss'
|
||||
|
||||
+3
-12
@@ -7,37 +7,28 @@
|
||||
z-index: -2;
|
||||
font-weight: 100 !important;
|
||||
text-shadow: 1px 1px 6px rgba(var(--lsd-surface-primary), 1);
|
||||
|
||||
opacity: 0.7;
|
||||
line-height: 2.3rem !important;
|
||||
max-width: 1280px;
|
||||
margin-top: 18px;
|
||||
}
|
||||
|
||||
.mdx-hero-description--small {
|
||||
//margin-top: 1rem;
|
||||
@include lsd.typography('h6');
|
||||
max-width: 1200px;
|
||||
}
|
||||
|
||||
.mdx-hero-description--large {
|
||||
@include lsd.typography('h4');
|
||||
}
|
||||
|
||||
.mdx-hero-description--medium {
|
||||
@include lsd.typography('h3');
|
||||
}
|
||||
|
||||
@include utils.responsive('lg', 'down') {
|
||||
.mdx-hero-description {
|
||||
margin-top: 12px;
|
||||
@include lsd.typography('subtitle1');
|
||||
}
|
||||
|
||||
.mdx-hero-description--large {
|
||||
//font-size: 1.875rem !important;
|
||||
//line-height: 2.25rem !important;
|
||||
//text-transform: uppercase;
|
||||
}
|
||||
|
||||
.mdx-hero-description--medium {
|
||||
@include lsd.typography('subtitle1');
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@ export const HeroDescription: React.FC<HeroDescriptionProps> = ({
|
||||
|
||||
return (
|
||||
<Typography
|
||||
variant={size === 'small' ? 'h5' : 'h2'}
|
||||
variant={'h5'}
|
||||
className={clsx(
|
||||
className,
|
||||
'mdx-hero-description',
|
||||
|
||||
@@ -1,17 +1,13 @@
|
||||
@use '../../../css/utils';
|
||||
|
||||
.mdx-hero-info {
|
||||
padding: var(--logos-hero-info-padding-bottom) 0
|
||||
var(--logos-hero-info-padding-bottom) 0;
|
||||
height: var(--logos-hero-info-height);
|
||||
padding: 32px 0;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: end;
|
||||
|
||||
border-bottom: 1px solid rgb(var(--lsd-surface-secondary));
|
||||
margin-bottom: calc(100vh - var(--logos-hero-info-height));
|
||||
|
||||
transition: margin-bottom 0.05s ease-in-out;
|
||||
}
|
||||
|
||||
@@ -19,7 +15,7 @@
|
||||
}
|
||||
|
||||
@include utils.responsive('lg', 'down') {
|
||||
:root {
|
||||
//--logos-hero-info-height: 340px;
|
||||
.mdx-hero-info {
|
||||
padding: 24px 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,8 @@
|
||||
import clsx from 'clsx'
|
||||
import React, { PropsWithChildren, useEffect } from 'react'
|
||||
import React, { PropsWithChildren } from 'react'
|
||||
import { useHero } from '../Hero/Hero.context'
|
||||
import { ScrollToBottom } from '../index'
|
||||
import './HeroInfo.scss'
|
||||
import { useScrollY } from '../../../lib/useScrollY'
|
||||
import {
|
||||
calcHeroInfoMb,
|
||||
calcScrollThreshold,
|
||||
isMobile,
|
||||
mapFloat,
|
||||
} from '../../../lib/ui.utils'
|
||||
|
||||
export type HeroInfoProps = PropsWithChildren<
|
||||
React.HTMLAttributes<HTMLDivElement>
|
||||
@@ -25,22 +18,11 @@ export const HeroInfo: React.FC<HeroInfoProps> = ({
|
||||
}) => {
|
||||
const ctx = useHero()
|
||||
const size = sizeProp ? sizeProp : ctx ? ctx.size : 'medium'
|
||||
const [mb, setMb] = React.useState(0)
|
||||
const scrollY = useScrollY()
|
||||
|
||||
useEffect(() => {
|
||||
if (isMobile()) {
|
||||
setMb(calcHeroInfoMb(scrollY))
|
||||
}
|
||||
}, [scrollY])
|
||||
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
className={clsx(className, 'mdx-hero-info', `mdx-hero-info--${size}`)}
|
||||
style={{
|
||||
marginBottom: `calc(100vh - var(--logos-hero-info-height) - ${mb}px)`,
|
||||
}}
|
||||
{...(props as any)}
|
||||
>
|
||||
{children}
|
||||
|
||||
@@ -2,20 +2,15 @@
|
||||
@use '../../../css/lsd';
|
||||
|
||||
.mdx-hero-title {
|
||||
font-weight: 300 !important;
|
||||
z-index: 1;
|
||||
text-shadow: 0px 0px 6px rgba(var(--lsd-surface-primary), 0.5);
|
||||
@include lsd.typography('h4');
|
||||
font-size: 70px !important;
|
||||
font-weight: 100 !important;
|
||||
line-height: 100% !important;
|
||||
}
|
||||
|
||||
.mdx-hero-title--large {
|
||||
@include lsd.typography('h1');
|
||||
//font-size: 5.0625rem !important;
|
||||
//line-height: 5rem !important;
|
||||
}
|
||||
|
||||
.mdx-hero-title--medium {
|
||||
@include lsd.typography('h2');
|
||||
}
|
||||
|
||||
.mdx-hero-title--uppercase {
|
||||
@@ -24,17 +19,12 @@
|
||||
|
||||
@include utils.responsive('lg', 'down') {
|
||||
.mdx-hero-title {
|
||||
@include lsd.typography('h4');
|
||||
text-transform: uppercase;
|
||||
font-size: 28px !important;
|
||||
}
|
||||
|
||||
.mdx-hero-title--medium {
|
||||
@include lsd.typography('h4');
|
||||
}
|
||||
|
||||
.mdx-hero-title--large {
|
||||
//font-size: 1.875rem !important;
|
||||
//line-height: 2.1rem !important;
|
||||
font-size: 2.175rem !important;
|
||||
line-height: 2.475rem !important;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
@use '../../../css/utils';
|
||||
|
||||
.mdx-hero-video {
|
||||
display: grid;
|
||||
grid-template-rows: 1fr;
|
||||
grid-template-columns: 1fr;
|
||||
|
||||
pointer-events: none;
|
||||
|
||||
--hero-video-scale: 58%;
|
||||
--hero-video-offset-y: -10%;
|
||||
--hero-video-scale-mobile: 117.8%;
|
||||
--hero-video-offset-y-mobile: -10%;
|
||||
|
||||
& > * {
|
||||
grid-row: 1 / 1;
|
||||
grid-column: 1 / 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
transform: translateY(var(--hero-video-offset-y));
|
||||
|
||||
max-width: 100%;
|
||||
height: 100%;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.mdx-hero-video__placeholder {
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
img,
|
||||
video {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
transform: scale(var(--hero-video-scale));
|
||||
margin-left: calc((var(--hero-video-scale) - 100%) * -1);
|
||||
transform-origin: top left;
|
||||
}
|
||||
}
|
||||
|
||||
.mdx-hero-video--loading {
|
||||
.mdx-hero-video__video {
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.mdx-hero-video__placeholder {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
|
||||
@include utils.responsive('lg', 'down') {
|
||||
.mdx-hero-video {
|
||||
> * {
|
||||
transform: translateY(var(--hero-video-offset-y-mobile));
|
||||
}
|
||||
|
||||
img,
|
||||
video {
|
||||
width: 100%;
|
||||
transform: scale(var(--hero-video-scale-mobile));
|
||||
margin-left: calc((var(--hero-video-scale-mobile) - 100%) * -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
import clsx from 'clsx'
|
||||
import React, { PropsWithChildren, useEffect, useRef, useState } from 'react'
|
||||
import { makeStyle } from '../../../lib/makeStyle'
|
||||
import { settle } from '../../../lib/settle'
|
||||
import { useHero } from '../Hero/Hero.context'
|
||||
import './HeroVideo.scss'
|
||||
|
||||
export type HeroVideoStyle = {
|
||||
scale?: string
|
||||
offsetY?: string
|
||||
}
|
||||
|
||||
export type HeroVideoProps = PropsWithChildren<
|
||||
React.HTMLAttributes<HTMLDivElement>
|
||||
> & {
|
||||
placeholderSrc: string
|
||||
desktop?: HeroVideoStyle
|
||||
mobile?: HeroVideoStyle
|
||||
}
|
||||
|
||||
export const HeroVideo: React.FC<HeroVideoProps> = ({
|
||||
placeholderSrc,
|
||||
desktop,
|
||||
mobile,
|
||||
className,
|
||||
style = {},
|
||||
children,
|
||||
...props
|
||||
}) => {
|
||||
const ctx = useHero()
|
||||
const ref = useRef<HTMLVideoElement>(null)
|
||||
const [loading, setLoading] = useState(true)
|
||||
|
||||
const play = async () => {
|
||||
const el = ref.current
|
||||
if (!el) return
|
||||
|
||||
await settle(() => el.play())
|
||||
}
|
||||
|
||||
const onCanPlay = async () => {
|
||||
loading && setLoading(false)
|
||||
await play()
|
||||
}
|
||||
|
||||
const onEnded = async () => {
|
||||
await play()
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
className={clsx(
|
||||
className,
|
||||
'mdx-hero-video',
|
||||
loading && 'mdx-hero-video--loading',
|
||||
)}
|
||||
style={makeStyle(
|
||||
{ ...style },
|
||||
{
|
||||
'hero-video-scale': desktop?.scale ?? '58%',
|
||||
'hero-video-offset-y': desktop?.offsetY ?? '-10%',
|
||||
'hero-video-scale-mobile': mobile?.scale ?? '117.8%',
|
||||
'hero-video-offset-y-desktop': mobile?.offsetY ?? '-10%',
|
||||
},
|
||||
)}
|
||||
{...(props as any)}
|
||||
>
|
||||
<div className="mdx-hero-video__placeholder">
|
||||
<img src={placeholderSrc} alt="" />
|
||||
</div>
|
||||
<div className="mdx-hero-video__video">
|
||||
<video
|
||||
muted
|
||||
autoPlay
|
||||
onEnded={onEnded}
|
||||
onCanPlay={onCanPlay}
|
||||
ref={ref}
|
||||
>
|
||||
{children}
|
||||
</video>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export * from './HeroVideo'
|
||||
+13
-10
@@ -1,9 +1,10 @@
|
||||
import { ArrowDownIcon, IconButton } from '@acid-info/lsd-react'
|
||||
import clsx from 'clsx'
|
||||
import React, { HTMLProps } from 'react'
|
||||
import styles from './styles.module.scss'
|
||||
import { useHydrated } from '../../../lib/useHydrated'
|
||||
import { useIsMobile } from '../../../lib/useIsMobile'
|
||||
import { useScrollY } from '../../../lib/useScrollY'
|
||||
import { calcHeroInfoMb, isMobile } from '../../../lib/ui.utils'
|
||||
import styles from './styles.module.scss'
|
||||
|
||||
type TProps = {}
|
||||
|
||||
@@ -11,7 +12,10 @@ export const ScrollToBottom = (
|
||||
props: TProps & HTMLProps<HTMLButtonElement>,
|
||||
): JSX.Element => {
|
||||
const { children, className, ...rest } = props
|
||||
const isHydrated = useHydrated()
|
||||
const scrollY = useScrollY()
|
||||
const isMobile = useIsMobile()
|
||||
|
||||
const handleScrollToBottom = () => {
|
||||
const article = document.querySelector('.main-wrapper article')
|
||||
const secondElement = article?.children?.[1]
|
||||
@@ -22,22 +26,21 @@ export const ScrollToBottom = (
|
||||
behavior: 'smooth',
|
||||
})
|
||||
|
||||
if (isMobile()) {
|
||||
window.scrollTo(0, secondElement.getBoundingClientRect().top - 200)
|
||||
} else {
|
||||
;(secondElement as HTMLElement)?.scrollIntoView?.({ behavior: 'smooth' })
|
||||
}
|
||||
return
|
||||
return window.scrollTo({
|
||||
left: 0,
|
||||
top: secondElement.getBoundingClientRect().top - (isMobile ? 200 : 0),
|
||||
behavior: 'smooth',
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<IconButton
|
||||
onClick={handleScrollToBottom}
|
||||
size="small"
|
||||
size={isMobile ? 'small' : 'large'}
|
||||
className={clsx(
|
||||
styles.scrollToBottom,
|
||||
className,
|
||||
scrollY > 20 ? styles.hide : '',
|
||||
(scrollY > 20 || !isHydrated) && styles.hide,
|
||||
)}
|
||||
{...(rest as any)}
|
||||
>
|
||||
|
||||
+1
-3
@@ -13,7 +13,5 @@
|
||||
transform: translateY(-10px);
|
||||
}
|
||||
|
||||
bottom: calc(
|
||||
var(--ifm-navbar-height) + var(--logos-hero-info-height) - 100vh + 16px
|
||||
);
|
||||
bottom: 2rem;
|
||||
}
|
||||
|
||||
@@ -13,3 +13,4 @@ export * from './HeroTitle'
|
||||
export * from './PoweredBy'
|
||||
export * from './ScrollToBottom'
|
||||
export * from './Showcase'
|
||||
export * from './HeroVideo'
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
@mixin typography($variant) {
|
||||
font-size: var(--lsd-#{$variant}-fontSize) !important;
|
||||
line-height: var(--lsd-#{$variant}-lineHeight) !important;
|
||||
font-family: var(--lsd-typography-generic-font-family) !important;
|
||||
font-weight: 400 !important;
|
||||
@mixin typography($variant, $important: true) {
|
||||
@if $important == true {
|
||||
font-size: var(--lsd-#{$variant}-fontSize) !important;
|
||||
line-height: var(--lsd-#{$variant}-lineHeight) !important;
|
||||
font-family: var(--lsd-typography-generic-font-family) !important;
|
||||
font-weight: 400 !important;
|
||||
} @else {
|
||||
font-size: var(--lsd-#{$variant}-fontSize);
|
||||
line-height: var(--lsd-#{$variant}-lineHeight);
|
||||
font-family: var(--lsd-typography-generic-font-family);
|
||||
font-weight: 400;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -299,19 +299,19 @@ svg * {
|
||||
}
|
||||
|
||||
h1 {
|
||||
@include lsd.typography('h1');
|
||||
@include lsd.typography('h1', false);
|
||||
}
|
||||
|
||||
h2 {
|
||||
@include lsd.typography('h2');
|
||||
@include lsd.typography('h2', false);
|
||||
}
|
||||
|
||||
h3 {
|
||||
@include lsd.typography('h3');
|
||||
@include lsd.typography('h3', false);
|
||||
}
|
||||
|
||||
h4 {
|
||||
@include lsd.typography('h4');
|
||||
@include lsd.typography('h4', false);
|
||||
}
|
||||
|
||||
code {
|
||||
@@ -335,11 +335,6 @@ a code {
|
||||
|
||||
--ifm-navbar-item-padding-vertical: 8px;
|
||||
--ifm-navbar-item-padding-horizontal: 12px;
|
||||
|
||||
--logos-navbar-height: var(--ifm-navbar-height);
|
||||
--logos-hero-info-height: 420px;
|
||||
--logos-hero-info-padding-top: 32px;
|
||||
--logos-hero-info-padding-bottom: 32px;
|
||||
}
|
||||
|
||||
.card,
|
||||
@@ -1218,4 +1213,8 @@ code {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
#__docusaurus {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
@import './blog.scss';
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
export const settle = async <R, E = Error>(
|
||||
promise: Promise<R>,
|
||||
promise: Promise<R> | (() => Promise<R>),
|
||||
): Promise<[R, undefined] | [undefined, E]> => {
|
||||
try {
|
||||
const result: R = await promise
|
||||
const result: R =
|
||||
typeof promise === 'function' ? await promise() : await promise
|
||||
return [result, undefined]
|
||||
} catch (error) {
|
||||
return [undefined, error as E]
|
||||
|
||||
Reference in New Issue
Block a user