-
+
}>
+
+
+
+
= ({
scrollY,
0,
calcScrollThreshold() * RESIZE_SPEED_FACTOR,
- 0,
+ 0.2,
1,
),
}}
@@ -295,3 +130,22 @@ export const HeroModel: React.FC = ({
)
}
+
+function Model({ url, ...props }) {
+ // useGLTF suspends the component, it literally stops processing
+ const { scene } = useGLTF(url) as any
+ // By the time we're here the model is gueranteed to be available
+ return
+}
+
+function Rotate(props) {
+ const ref = useRef()
+ useFrame((state) => {
+ if (ref.current) {
+ // @ts-ignore
+ return (ref.current.rotation.y = state.clock.elapsedTime)
+ }
+ return ref
+ })
+ return
+}
diff --git a/packages/logos-docusaurus-theme/src/client/components/mdx/HeroModel/HeroModel.utils.ts b/packages/logos-docusaurus-theme/src/client/components/mdx/HeroModel/HeroModel.utils.ts
new file mode 100644
index 0000000..003ca50
--- /dev/null
+++ b/packages/logos-docusaurus-theme/src/client/components/mdx/HeroModel/HeroModel.utils.ts
@@ -0,0 +1,26 @@
+import { calcScrollThreshold, mapFloat } from '../../../lib/ui.utils'
+import {
+ INITIAL_ZOOM,
+ MAX_ROTATE_SPEED,
+ MIN_ROTATE_SPEED,
+ MIN_ZOOM,
+ RESIZE_SPEED_FACTOR,
+} from './HeroModel.configs'
+
+export const calcRotateSpeed = (scrollY = 0, speed) => {
+ const sFactor = mapFloat(scrollY, 0, window.innerHeight, 1, 10)
+ return Math.max(Math.min(speed * sFactor, MAX_ROTATE_SPEED), MIN_ROTATE_SPEED)
+}
+
+export const calcZoom = (scrollY = 0, initZ = INITIAL_ZOOM) => {
+ return Math.max(
+ mapFloat(
+ scrollY,
+ 0,
+ calcScrollThreshold() * RESIZE_SPEED_FACTOR,
+ initZ,
+ MIN_ZOOM,
+ ),
+ MIN_ZOOM,
+ )
+}
diff --git a/packages/logos-docusaurus-theme/src/client/components/mdx/HeroModel/_HeroModel.tsx b/packages/logos-docusaurus-theme/src/client/components/mdx/HeroModel/_HeroModel.tsx
new file mode 100644
index 0000000..ab7b907
--- /dev/null
+++ b/packages/logos-docusaurus-theme/src/client/components/mdx/HeroModel/_HeroModel.tsx
@@ -0,0 +1,336 @@
+/*
+import {OrbitControls, useGLTF} from '@react-three/drei'
+import {Canvas, useFrame, useThree} from '@react-three/fiber'
+import clsx from 'clsx'
+import React, {
+ PropsWithChildren,
+ Suspense,
+ useEffect,
+ useLayoutEffect,
+ useMemo,
+ useRef,
+ useState,
+} from 'react'
+import * as THREE from 'three'
+import {AsciiEffect} from 'three-stdlib'
+import './HeroModel.scss'
+import {
+ calcScrollThreshold,
+ isTouchDevice,
+ mapFloat,
+ random,
+} from '../../../lib/ui.utils'
+import {useScrollY} from '../../../lib/useScrollY'
+
+let ROTATE_SPEED = 0.1
+const MIN_ROTATE_SPEED = 0.1
+const MAX_ROTATE_SPEED = 1
+
+const MAX_Z = 20 * 1.4 // or another value that suits your needs
+const MIN_Z = 0.2 * 1.4
+const MIN_Y = -0.25
+const MAX_Y = 0.25
+const MIN_X = -0.25
+const MAX_X = 0.25
+
+const MIN_ZOOM = 0.22
+const RESIZE_SPEED_FACTOR = 0.9
+const INITIAL_ZOOM = 3
+const calcZoom = (scrollY = 0, initZ = INITIAL_ZOOM) => {
+ return Math.max(
+ mapFloat(
+ scrollY,
+ 0,
+ calcScrollThreshold() * RESIZE_SPEED_FACTOR,
+ initZ,
+ MIN_ZOOM,
+ ),
+ MIN_ZOOM,
+ )
+}
+
+const calcRotateSpeed = (scrollY = 0, speed) => {
+ const sFactor = mapFloat(scrollY, 0, window.innerHeight, 1, 10)
+ return Math.max(Math.min(speed * sFactor, MAX_ROTATE_SPEED), MIN_ROTATE_SPEED)
+}
+
+function Model({url, ...props}) {
+ // useGLTF suspends the component, it literally stops processing
+ const {scene} = useGLTF(url) as any
+ // useLayoutEffect(() => {
+ // if (!camera) return
+ // const c = camera as THREE.PerspectiveCamera
+ // const fov = c.fov * (Math.PI / 180)
+ // const distance = Math.abs(Math.max(size.x, size.y) / Math.sin(fov / 2))
+ // c.position.setZ(distance)
+ // }, [size, camera])
+ return (
+
+ )
+}
+
+type RotateProps = PropsWithChildren<{
+ initialZ?: number
+ rotateSpeed?: number
+ enableZoom?: boolean
+ enableRotateOnScroll?: boolean
+}>
+
+function Movements({
+ initialZ,
+ rotateSpeed = ROTATE_SPEED,
+ enableZoom = true,
+ enableRotateOnScroll = true,
+ ...props
+ }: RotateProps) {
+ const ref = useRef
()
+ const scrollY = useScrollY()
+
+ useFrame((state, delta) => {
+ // const f = mapFloat(scrollY, 0, 1000, 1, 2);
+ // ref.current.rotation.x += delta * (ROTATE_SPEED);
+ // ref.current.rotation.y += delta * (ROTATE_SPEED);
+ const speed = enableRotateOnScroll
+ ? calcRotateSpeed(scrollY, rotateSpeed)
+ : rotateSpeed
+ ref.current.rotation.y += delta * speed
+ })
+
+ return (
+
+ )
+}
+
+type AsciiConfigs = {
+ characters?: string
+ invert?: boolean
+ color?: boolean
+ bgColor?: string
+ fgColor?: string
+ resolution?: number
+ renderIndex?: number
+}
+
+const defaultAsciiConfigs = {
+ renderIndex: 1,
+ bgColor: 'rgb(var(--lsd-surface-primary))',
+ fgColor: 'rgb(var(--lsd-text-primary))',
+ characters: ' l.o.g.o.s ',
+ invert: false,
+ color: false,
+ resolution: 0.2,
+}
+
+type AsciiEffectProps = {
+ config?: AsciiConfigs
+ initialZ?: number
+}
+
+function useAsciiEffect({config = {}, initialZ}: AsciiEffectProps) {
+ const {
+ renderIndex = defaultAsciiConfigs.renderIndex,
+ characters = defaultAsciiConfigs.characters,
+ invert = defaultAsciiConfigs.invert,
+ color = defaultAsciiConfigs.color,
+ resolution = defaultAsciiConfigs.resolution,
+ bgColor = defaultAsciiConfigs.bgColor,
+ fgColor = defaultAsciiConfigs.fgColor,
+ } = config
+
+ // Reactive state
+ const {gl, size, scene, camera, viewport} = useThree()
+
+ const effect = useMemo(() => {
+ const effect = new AsciiEffect(gl, " characters ", {
+ invert: true,
+ color: false,
+ resolution: 0.1,
+ })
+ effect.domElement.style.position = 'absolute'
+ effect.domElement.style.top = '0px'
+ effect.domElement.style.left = '0px'
+ effect.domElement.style.pointerEvents = 'none'
+ return effect
+ }, [characters, invert, color, resolution])
+
+ useLayoutEffect(() => {
+ effect.domElement.style.color = fgColor
+ // effect.domElement.style.backgroundColor = bgColor
+ }, [fgColor, bgColor])
+
+ // Append on mount, remove on unmount
+ useEffect(() => {
+ gl.domElement.style.opacity = '0'
+ gl.domElement.parentNode!.appendChild(effect.domElement)
+ return () => {
+ gl.domElement.style.opacity = '1'
+ gl.domElement.parentNode!.removeChild(effect.domElement)
+ }
+ }, [effect])
+
+ // Set size
+ useEffect(() => {
+ effect.setSize(size.width, size.height)
+ }, [effect, size])
+
+ // Take over render-loop (that is what the index is for)
+ useFrame((state) => {
+ effect.render(scene, camera)
+ }, renderIndex)
+}
+
+const AsciiRenderer = (props: AsciiEffectProps) => {
+ useAsciiEffect(props)
+ return <>>
+}
+
+export type HeroModelProps = React.HTMLAttributes & {
+ modelUrl: string
+ layout?: 'floating' | 'cropped'
+ renderer?: '3d' | 'ascii'
+ asciiConfig?: AsciiConfigs
+ initialZ?: number
+ initialX?: number
+ initialY?: number
+ rotateSpeed?: number
+ enableZoom?: boolean
+ enableRotateOnScroll?: boolean
+ withParallelEffect?: boolean
+}
+
+function Box(props) {
+ // This reference will give us direct access to the mesh
+ const mesh = useRef()
+ // Set up state for the hovered and active state
+ const [hovered, setHover] = useState(false)
+ const [active, setActive] = useState(false)
+ // Subscribe this component to the render-loop, rotate the mesh every frame
+ useFrame((state, delta) => {
+ if (mesh && mesh.current){
+ // @ts-ignore
+ return mesh.current.rotation.x += delta
+ }
+ })
+ // Return view, these are regular three.js elements expressed in JSX
+ return (
+ setActive(!active)}
+ onPointerOver={(event) => setHover(true)}
+ onPointerOut={(event) => setHover(false)}>
+
+
+
+ )
+}
+export const HeroModel: React.FC = ({}) => {
+ return (
+
+ )
+}
+
+// export const HeroModel: React.FC = ({
+// layout = 'floating',
+// renderer = '3d',
+// modelUrl,
+// className,
+// children,
+// asciiConfig,
+// initialX,
+// initialY,
+// initialZ,
+// rotateSpeed = ROTATE_SPEED,
+// enableZoom,
+// enableRotateOnScroll,
+// withParallelEffect,
+// ...props
+// }) => {
+ const scrollY = useScrollY()
+ const initialPosition = useMemo(() => {
+ if (typeof window === 'undefined') return new THREE.Vector3(0, 0, 0)
+ if (renderer === 'ascii') {
+ return new THREE.Vector3(
+ initialX || random(MIN_X, MAX_X),
+ initialY || random(MIN_Y, MAX_Y),
+ 0,
+ )
+ }
+ // if not ascii then use the max z
+ return new THREE.Vector3(3.1, initialY || random(MIN_Y, MAX_Y), 0)
+ }, [initialX, initialY, initialZ, renderer])
+// return (
+//
+
+//
+//
+//
+//
+// }>
+//
+//
+//
+
+//
+// )
+// }
+
+ */
+export default {}
diff --git a/packages/logos-docusaurus-theme/src/client/components/mdx/HeroModel/index.tsx b/packages/logos-docusaurus-theme/src/client/components/mdx/HeroModel/index.tsx
index 7da17d1..8e367da 100644
--- a/packages/logos-docusaurus-theme/src/client/components/mdx/HeroModel/index.tsx
+++ b/packages/logos-docusaurus-theme/src/client/components/mdx/HeroModel/index.tsx
@@ -1,17 +1,20 @@
-import BrowserOnly from '@docusaurus/BrowserOnly'
import React from 'react'
-import { HeroModelProps } from './HeroModel'
+import { HeroModel as Model, HeroModelProps } from './HeroModel'
export const HeroModel: React.FC = (props) => {
- return (
-
- {() => {
- const { HeroModel: Model } = require('./HeroModel')
+ if (typeof window === 'undefined') return null
- return
- }}
-
- )
+ return
+
+ // return (
+ //
+ // {() => {
+ // const { HeroModel: Model } = require('./HeroModel')
+ //
+ // return
+ // }}
+ //
+ // )
}
export type { HeroModelProps } from './HeroModel'
diff --git a/packages/logos-docusaurus-theme/src/client/components/mdx/HeroTitle/HeroTitle.scss b/packages/logos-docusaurus-theme/src/client/components/mdx/HeroTitle/HeroTitle.scss
index d38a9df..0e7e830 100644
--- a/packages/logos-docusaurus-theme/src/client/components/mdx/HeroTitle/HeroTitle.scss
+++ b/packages/logos-docusaurus-theme/src/client/components/mdx/HeroTitle/HeroTitle.scss
@@ -1,3 +1,6 @@
+@use '../../../css/utils';
+@use '../../../css/lsd';
+
.mdx-hero-title {
font-weight: 300 !important;
z-index: -2;
@@ -11,3 +14,13 @@
.mdx-hero-title--uppercase {
text-transform: uppercase;
}
+
+@include utils.responsive('lg', 'down') {
+ .mdx-hero-title {
+ @include lsd.typography('h3');
+ }
+
+ .mdx-hero-title--large {
+ font-size: 1.875rem !important;
+ }
+}
diff --git a/packages/logos-docusaurus-theme/src/client/components/mdx/Showcase/Showcase.scss b/packages/logos-docusaurus-theme/src/client/components/mdx/Showcase/Showcase.scss
index 49197e3..681d4de 100644
--- a/packages/logos-docusaurus-theme/src/client/components/mdx/Showcase/Showcase.scss
+++ b/packages/logos-docusaurus-theme/src/client/components/mdx/Showcase/Showcase.scss
@@ -1,7 +1,11 @@
+@use '../../../css/utils';
+@use '../../../css/lsd';
+
.mdx-showcase {
- padding-top: 8.25rem;
+ width: 100%;
+ overflow: hidden;
display: grid;
- grid-template-columns: repeat(3, 1fr);
+ grid-template-columns: repeat(4, 1fr);
gap: 1rem;
}
@@ -25,3 +29,23 @@
margin-top: 24px;
padding-top: 16px;
}
+
+@include utils.responsive('lg', 'down') {
+ .mdx-showcase {
+ grid-template-columns: repeat(2, 1fr);
+ gap: 1.5rem 1rem;
+ }
+
+ .mdx-showcase__item-name {
+ @include lsd.typography('h6');
+ }
+
+ .mdx-showcase__item-description {
+ margin-top: 1rem;
+ }
+
+ .mdx-showcase__item-logo {
+ width: 34px;
+ height: auto;
+ }
+}
diff --git a/packages/logos-docusaurus-theme/src/client/components/mdx/Showcase/Showcase.tsx b/packages/logos-docusaurus-theme/src/client/components/mdx/Showcase/Showcase.tsx
index e01708f..00ff5a3 100644
--- a/packages/logos-docusaurus-theme/src/client/components/mdx/Showcase/Showcase.tsx
+++ b/packages/logos-docusaurus-theme/src/client/components/mdx/Showcase/Showcase.tsx
@@ -34,7 +34,7 @@ export const Showcase: React.FC = ({
/>
{item.name}
diff --git a/packages/logos-docusaurus-theme/src/client/components/mdx/index.ts b/packages/logos-docusaurus-theme/src/client/components/mdx/index.ts
index 44f7474..7d0f06c 100644
--- a/packages/logos-docusaurus-theme/src/client/components/mdx/index.ts
+++ b/packages/logos-docusaurus-theme/src/client/components/mdx/index.ts
@@ -1,10 +1,12 @@
+export * from './Box'
+export * from './CallToActionButton'
export * from './CallToActionSection'
export * from './FeatureList'
export * from './Hero'
export * from './HeroAction'
export * from './HeroActions'
export * from './HeroDescription'
+export * from './HeroInfo'
export * from './HeroModel'
export * from './HeroTitle'
export * from './Showcase'
-export * from './HeroInfo'
diff --git a/packages/logos-docusaurus-theme/src/client/css/_lsd.scss b/packages/logos-docusaurus-theme/src/client/css/_lsd.scss
index 2e95d5b..bca8e23 100644
--- a/packages/logos-docusaurus-theme/src/client/css/_lsd.scss
+++ b/packages/logos-docusaurus-theme/src/client/css/_lsd.scss
@@ -1,5 +1,5 @@
@mixin typography($variant) {
- font-size: var(--lsd-#{$variant}-fontSize);
- line-height: var(--lsd-#{$variant}-lineHeight);
- font-family: var(--lsd-typography-generic-font-family);
+ font-size: var(--lsd-#{$variant}-fontSize) !important;
+ line-height: var(--lsd-#{$variant}-lineHeight) !important;
+ font-family: var(--lsd-typography-generic-font-family) !important;
}
diff --git a/packages/logos-docusaurus-theme/src/client/css/custom.scss b/packages/logos-docusaurus-theme/src/client/css/custom.scss
index 29753b4..59341d2 100644
--- a/packages/logos-docusaurus-theme/src/client/css/custom.scss
+++ b/packages/logos-docusaurus-theme/src/client/css/custom.scss
@@ -708,17 +708,17 @@ a[class^='sidebarLogo_'] {
margin-top: 0 !important;
margin-bottom: 80px !important;
}
-
& > main {
padding: 0;
&,
> .row,
& > .row > .col {
+ --ifm-spacing-horizontal: var(--content-padding);
+
width: 100% !important;
flex-basis: 100% !important;
max-width: unset;
- padding: 0;
margin: 0;
flex: unset;
}
@@ -996,3 +996,9 @@ a[class^='sidebarLogo_'] {
margin-left: unset;
}
}
+
+[data-hidden-doc-sidebar='true'] {
+ .theme-doc-sidebar-container {
+ display: none;
+ }
+}
diff --git a/packages/logos-docusaurus-theme/src/client/lib/makeStyle.ts b/packages/logos-docusaurus-theme/src/client/lib/makeStyle.ts
new file mode 100644
index 0000000..2b6d53e
--- /dev/null
+++ b/packages/logos-docusaurus-theme/src/client/lib/makeStyle.ts
@@ -0,0 +1,13 @@
+import React from 'react'
+
+export const makeStyle = (
+ style: React.CSSProperties,
+ vars: Record = {},
+) =>
+ ({
+ ...style,
+ ...Object.entries(vars).reduce(
+ (value, [name, val]) => ({ ...value, [`--${name}`]: val }),
+ {},
+ ),
+ } as React.CSSProperties)
diff --git a/packages/logos-docusaurus-theme/src/client/lib/ui.utils.ts b/packages/logos-docusaurus-theme/src/client/lib/ui.utils.ts
index 5c9a235..b39a78a 100644
--- a/packages/logos-docusaurus-theme/src/client/lib/ui.utils.ts
+++ b/packages/logos-docusaurus-theme/src/client/lib/ui.utils.ts
@@ -19,3 +19,15 @@ export const isTouchDevice = () => {
(navigator.msMaxTouchPoints && navigator.msMaxTouchPoints > 0)
)
}
+
+export const generateTextShadow = (steps: number): string => {
+ let shadows = ''
+ for (let i = 0; i < steps; i++) {
+ let colorValue = Math.floor((i / (steps - 1)) * 255) // Generate a value between 0 and 255
+ let shadow = `${-i * 5}px ${
+ -i * 5
+ }px 0px rgb(${colorValue}, ${colorValue}, ${colorValue})`
+ shadows += (i === 0 ? '' : ', ') + shadow
+ }
+ return shadows
+}
diff --git a/packages/logos-docusaurus-theme/src/client/lib/useThemeOptions.ts b/packages/logos-docusaurus-theme/src/client/lib/useThemeOptions.ts
new file mode 100644
index 0000000..df9bbcf
--- /dev/null
+++ b/packages/logos-docusaurus-theme/src/client/lib/useThemeOptions.ts
@@ -0,0 +1,17 @@
+import { useActivePlugin } from '@docusaurus/plugin-content-docs/lib/client/index.js'
+import useDocusaurusContext from '@docusaurus/useDocusaurusContext'
+import { DocConfig, ThemeOptions } from '../types/theme.types'
+
+export const useThemeOptions = (): ThemeOptions => {
+ const {
+ siteConfig: { customFields = {} },
+ } = useDocusaurusContext()
+
+ return (customFields['logos-docusaurus-theme'] ?? {}) as ThemeOptions
+}
+
+export const useDocThemeOptions = (): DocConfig => {
+ const activePlugin = useActivePlugin()
+ const themeOptions = useThemeOptions()
+ return activePlugin ? themeOptions?.docs?.[activePlugin?.pluginId] ?? {} : {}
+}
diff --git a/packages/logos-docusaurus-theme/src/client/theme/Navbar/Content/index.tsx b/packages/logos-docusaurus-theme/src/client/theme/Navbar/Content/index.tsx
index 071f7c3..ae303e6 100644
--- a/packages/logos-docusaurus-theme/src/client/theme/Navbar/Content/index.tsx
+++ b/packages/logos-docusaurus-theme/src/client/theme/Navbar/Content/index.tsx
@@ -11,6 +11,7 @@ import NavbarItem from '@theme/NavbarItem'
import SearchBar from '@theme/SearchBar'
import clsx from 'clsx'
import React from 'react'
+import { useHydrated } from '../../../lib/useHydrated'
import styles from './styles.module.scss'
function useNavbarItems() {
@@ -42,6 +43,7 @@ ${JSON.stringify(item, null, 2)}`,
}
export default function NavbarContent() {
+ const hydrated = useHydrated()
const mobileSidebar = useNavbarMobileSidebar()
const allItems = useNavbarItems()
const [leftItems, rightItems] = splitNavbarItems(
@@ -62,13 +64,20 @@ export default function NavbarContent() {
- {searchBarItem && }
- {!mobileSidebar.disabled && }
+ {hydrated && (
+
+ {searchBarItem && }
+
+ )}
+
+ {!mobileSidebar.disabled && }
+
diff --git a/packages/logos-docusaurus-theme/src/client/theme/Root.tsx b/packages/logos-docusaurus-theme/src/client/theme/Root.tsx
index c2fdb2a..8108e4e 100644
--- a/packages/logos-docusaurus-theme/src/client/theme/Root.tsx
+++ b/packages/logos-docusaurus-theme/src/client/theme/Root.tsx
@@ -4,10 +4,15 @@ import {
useColorMode,
} from '@docusaurus/theme-common/internal'
import React from 'react'
+import { useDocThemeOptions } from '../lib/useThemeOptions'
import styles from './style.module.css'
const Content = ({ children }) => {
const colorMode = useColorMode()
+
+ const options = useDocThemeOptions()
+ const hideDocSidebar = options?.sidebar?.hide
+
return (