feat(fs.dev): MDX styling
This commit is contained in:
parent
334a6933fd
commit
99393b8629
10 changed files with 137 additions and 67 deletions
|
@ -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
|
|
@ -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>»</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>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
const Example = props => <p>FIXME: Example still todo</p>
|
||||
|
||||
export const Example
|
||||
export default Example
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
)
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
))}
|
||||
|
|
|
@ -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>
|
||||
)
|
||||
|
|
|
@ -11,7 +11,7 @@ module.exports = {
|
|||
],
|
||||
plugins: [
|
||||
require('daisyui'),
|
||||
require('@tailwindcss/typography'),
|
||||
//require('@tailwindcss/typography'),
|
||||
],
|
||||
daisyui: {
|
||||
styled: true,
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue