1
0
Fork 0

feat(fs.dev): MDX styling

This commit is contained in:
Joost De Cock 2021-12-21 20:47:13 +01:00
parent 334a6933fd
commit 99393b8629
10 changed files with 137 additions and 67 deletions

View file

@ -1,13 +0,0 @@
const H1 = props => (
<h1
className={`
text-4xl py-4 font-bold
lg:text-6xl
`}
style={{letterSpacing: '-0.15rem'}}
>
{props.children}
</h1>
)
export default H1

View file

@ -1,18 +1,64 @@
import { useState } from 'react'
import { useRouter } from 'next/router'
import Link from 'next/link'
// Shared components
import PrimaryMenu from 'shared/components/navigation/primary'
//import Breadcrumbs from '@/shared/components/navigation/breadcrumbs'
import H1 from 'shared/components/elements/h1'
//import Icon from '@/shared/components/icon'
//import Button from '@/shared/components/elements/button'
// Site components
//import NavigationButtons from '@/site/components/navigation-buttons'
//import Search from '@/site/components/search'
import Logo from 'shared/components/logos/freesewing.js'
import PrimaryNavigation from 'shared/components/navigation/primary'
import get from 'lodash.get'
const iconSize= 48
const DefaultLayout = props => {
const PageTitle = ({ app, slug, title }) => {
if (title) return <h1>{title}</h1>
if (slug) return <h1>{get(app.navigation, slug.split('/')).__title}</h1>
return <h1>FIXME: This page has no title</h1>
}
const Breadcrumbs = ({ app, slug=false, title }) => {
if (!slug) return null
const crumbs = []
const chunks = slug.split('/')
for (const i in chunks) {
const page = get(app.navigation, chunks.slice(0,i+1))
crumbs.push([page.__linktitle, '/'+chunks.slice(0,i+1).join('/'), (i+1 < chunks.length)])
}
return (
<ul className="flex flex-row gap-2 font-bold">
<li>
<Link href="/">
<a title="To the homepage">
<Logo size={24} />
</a>
</Link>
</li>
{crumbs.map(crumb => (
<>
<li>&raquo;</li>
<li>
{crumb[2]
? (
<Link href={crumb[1]}>
<a title={crumb[0]} className="text-secondary hover:text-secondary-focus">
{crumb[0]}
</a>
</Link>
)
: crumb[0]
}
</li>
</>
))}
</ul>
)
}
const DefaultLayout = ({ app, title=false, children=[]}) => {
const router = useRouter()
const slug = router.asPath.slice(1)
const [leftNav, setLeftNav] = useState(false)
const toggleLeftNav = () => setLeftNav(!leftNav)
@ -23,7 +69,7 @@ const DefaultLayout = props => {
min-h-screen
bg-base-100
lg:py-8
`} data-theme={props.app.theme}>
`} data-theme={app.theme}>
<header className={`
bg-primary
p-4
@ -36,26 +82,32 @@ const DefaultLayout = props => {
grow flex flex-row
sm:py-8
gap-2
lg:gap-8
xl:gap-18
lg:gap-16
xl:gap-32
`}>
<aside className={`
fixed top-0 right-0
${props.app.primaryMenu ? '' : 'translate-x-[-100%]'} transition-transform
${app.primaryMenu ? '' : 'translate-x-[-100%]'} transition-transform
sm:relative sm:transform-none
h-screen w-screen
bg-base-200
sm:bg-base-100
bg-base-50
sm:bg-base-50
sm:max-w-[38.2%]
sm:flex sm:flex-row-reverse
overflow-scroll
py-8
sm:sticky
overflow-y-scroll
py-4
`}>
<PrimaryMenu app={props.app}/>
<PrimaryNavigation app={app} active={slug}/>
</aside>
<section className='max-w-screen-lg'>
<H1>{props.title}</H1>
{props.children}
<section className='max-w-screen-lg lg:pt-8 p-4'>
{title && (
<>
<Breadcrumbs app={app} slug={slug} title={title} />
<PageTitle app={app} slug={slug} title={title} />
</>
)}
{children}
</section>
</main>
<footer className="bg-primary p-8">footer</footer>

View file

@ -1,4 +1,4 @@
const Example = props => <p>FIXME: Example still todo</p>
export const Example
export default Example

View file

@ -13,7 +13,7 @@ const Highlight = ({
: (className === '') ? 'js' : className.split('-').pop()
return (
<div className="hljs my-4 not-prose">
<div className="hljs my-4">
<div className={`text-xs uppercase font-bold text-info mt-1 text-center border-b border-info border-opacity-20 py-1 mb-2 lg:text-sm`}>
{names[language] ? names[language] : language}
</div>

View file

@ -30,35 +30,44 @@ const Chevron = ({w=8, m=2}) => <svg
const currentChildren = current => Object.values(current)
.filter(entry => (typeof entry === 'object'))
const linkClasses = "text-lg py-2 text-base-content hover:cursor-pointer hover:text-secondary bg-opacity-50"
const howActive = (slug) => {
}
// Shared classes for links
const linkClasses = "text-lg lg:text-xl py-1 text-base-content hover:cursor-pointer hover:text-secondary bg-opacity-50"
// Component that renders a sublevel of navigation
const SubLevel = ({ nodes={} }) => (
<ul className='list-inside'>
const SubLevel = ({ nodes={}, level=1 }) => (
<ul className="pl-5 list-inside">
{currentChildren(nodes).map(child => (Object.keys(child).length > 4)
? (
<li key={child.__slug}>
<details>
<li key={child.__slug} className="flex flex-row">
<details className="grow">
<summary className={`
flex flex-row gap-4
p-1 px-2
flex flex-row
px-2
text-base-content
hover:cursor-row-resize
items-center
`}>
<Link href={child.__slug}>
<a title={child.__title} className={`grow ${linkClasses}`}>
{ child?.__linktitle || child.__title }
</a>
</Link>
<Link href={child.__slug}>
<a title={child.__title} className={`grow pl-2 border-l-2 ${linkClasses} hover:border-secondary`}>
<Icon icon="middot" size="24" className="text-secondary inline" />
{ child?.__linktitle || child.__title }
</a>
</Link>
<Chevron w={6} m={3}/>
</summary>
<SubLevel nodes={child} />
<SubLevel nodes={child} level={level+1} />
</details>
</li>
) : (
<li className='pl-2'>
<li className='pl-2 flex flex-row items-center'>
<Link href={child.__slug} title={child.__title}>
<a className={linkClasses}>
<a className={`pl-2 border-l-2 ${linkClasses} grow hover:border-secondary`}>
<Icon icon="middot" size="24" className="text-secondary inline" />
{child.__linktitle}
</a>
</Link>
@ -70,8 +79,8 @@ const SubLevel = ({ nodes={} }) => (
)
// Component that renders a toplevel of navigation
const TopLevel = ({ icon, title, nav, current, slug, showChildren=false }) => (
<details className='py-1' open={((keepClosed.indexOf(current._slug) === -1) ? 1 : 0)}>
const TopLevel = ({ icon, title, nav, current, slug, hasChildren=false, active }) => (
<details className='py-1' open={((keepClosed.indexOf(current.__slug) === -1) ? 1 : 0)}>
<summary className={`
flex flex-row uppercase gap-4 font-bold text-lg
hover:cursor-row-resize
@ -80,14 +89,14 @@ const TopLevel = ({ icon, title, nav, current, slug, showChildren=false }) => (
items-center
`}>
{icon}
<Link href={`/${current._slug}/`}>
<Link href={`/${current.__slug}/`}>
<a className={`grow ${linkClasses}`}>
{title}
{title} {active}
</a>
</Link>
{showChildren && <Chevron />}
{hasChildren && <Chevron />}
</summary>
{showChildren && <SubLevel nodes={current} />}
{hasChildren && <SubLevel nodes={current} />}
</details>
)
@ -129,13 +138,15 @@ const TopTheme = ({ app }) => (
Theme
</div>
</div>
<ThemePicker app={app} />
<div className="p-2">
<ThemePicker app={app} className="pr-8"/>
</div>
</>
)
// TODO: Get rid of this when markdown has been restructured
const remove = ['contributors', 'developers', 'editors', 'translators']
const Navigation = ({ app }) => {
const Navigation = ({ app, active }) => {
if (!app.navigation) return null
const output = []
for (const key of Object.keys(app.navigation).sort()) {
@ -144,16 +155,17 @@ const Navigation = ({ app }) => {
title={key}
slug={key}
key={key}
showChildren={keepClosed.indexOf(key) === -1}
hasChildren={keepClosed.indexOf(key) === -1}
nav={app.navigation}
current={orderBy(app.navigation[key], ['order', 'title'], ['asc', 'asc'])}
active={active}
/>)
}
return output
}
const PrimaryMenu = ({ app }) => {
const PrimaryMenu = ({ app, active }) => {
return (
<nav className={`
@ -161,7 +173,7 @@ const PrimaryMenu = ({ app }) => {
grow
`}>
<TopLogo app={app}/>
<Navigation app={app}/>
<Navigation app={app} active={active} />
<TopTheme app={app}/>
</nav>
)

View file

@ -31,7 +31,7 @@ const Popout = (props) => {
return (
<div className="relative my-4">
<div className={`
border-l-4 px-8 py-2 prose lg:prose-lg shadow border-${color}`}>
border-l-4 px-8 py-2 shadow border-${color}`}>
<div className={`font-bold uppercase text-${color}`}>
{type}
</div>

View file

@ -1,8 +1,11 @@
import themes from 'shared/themes/index.js'
const ThemePicker = ({ app }) => {
const ThemePicker = ({ app, className='' }) => {
return (
<select className="select select-bordered w-full max-w-xs" onChange={evt => app.setTheme(evt.target.value)}>
<select
className={`select select-bordered w-full max-w-sm text-base-content ${className}`}
onChange={evt => app.setTheme(evt.target.value)}
>
{Object.keys(themes).map(theme => (
<option>{theme}</option>
))}

View file

@ -36,7 +36,7 @@ const MdxWrapper = ({mdx, app, components={}}) => {
const MdxContent = mdxModule ? mdxModule.default : Fragment
return (
<div className="prose lg:prose-xl prose-pre:bg-primary text-primary">
<div className="text-primary mdx max-w-prose text-base-content max-w-prose text-lg lg:text-xl">
<MdxContent components={allComponents}/>
</div>
)

View file

@ -11,7 +11,7 @@ module.exports = {
],
plugins: [
require('daisyui'),
require('@tailwindcss/typography'),
//require('@tailwindcss/typography'),
],
daisyui: {
styled: true,

View file

@ -4,6 +4,22 @@
@import './code.css';
/* Applied styles for common HTML tags */
@layer components {
h1 { @apply text-base-content text-4xl py-5 font-bold lg:text-6xl }
h2 { @apply text-base-content text-3xl py-4 font-bold lg:text-4xl }
h3 { @apply text-base-content text-2xl py-3 font-bold lg:text-3xl }
h4 { @apply text-base-content text-xl py-2 font-bold lg:text-2xl }
h5 { @apply text-base-content text-lg py-1 font-bold lg:text-xl }
h6 { @apply text-base-content text-base font-bold lg:text-lg }
p { @apply text-base-content my-1 py-2 lg:text-xl }
/* mdx styles */
.mdx a { @apply text-secondary }
.mdx a:hover { @apply text-secondary-focus }
.mdx p > code { @apply text-info px-1 rounded-lg }
.mdx ul { @apply pl-4 list-disc list-inside text-base-content }
}
details { user-select: none; }
details > summary > svg.details-toggle {
transform: rotate(90deg);