Font-fiddling

This commit is contained in:
Mark Eibes 2021-01-06 09:43:17 +01:00
parent 60ca4cdf0a
commit f86fac1dca
6 changed files with 209 additions and 199 deletions

22
blog/package-lock.json generated
View File

@ -11,7 +11,9 @@
"dependencies": {
"@emotion/core": "^10.0.28",
"@fontsource/cormorant-garamond": "^4.1.0",
"@fontsource/cormorant-sc": "^4.1.0",
"@fontsource/inter": "^4.1.0",
"@fontsource/pt-serif": "^4.1.0",
"@material-ui/styles": "^4.9.0",
"@mdx-js/mdx": "^1.1.5",
"@mdx-js/react": "^1.1.5",
@ -1729,11 +1731,21 @@
"resolved": "https://registry.npmjs.org/@fontsource/cormorant-garamond/-/cormorant-garamond-4.1.0.tgz",
"integrity": "sha512-Q9q+uj3ZmBrqn3knh5pVAB6kVXPDfut74U5lGxhf3gHQihrckOv/0Cw3ObKMc69r6OBk+IRcQN7A5d1aVVBGhw=="
},
"node_modules/@fontsource/cormorant-sc": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/@fontsource/cormorant-sc/-/cormorant-sc-4.1.0.tgz",
"integrity": "sha512-cyXp0MZCr/vU+WF6Og5H8/Xn0rKuiMZ0DlbSjChm6HJJHbok3vuZwOAtzEn9rCV2aAxqBk6ARIl1l0aWcfSAoQ=="
},
"node_modules/@fontsource/inter": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/@fontsource/inter/-/inter-4.1.0.tgz",
"integrity": "sha512-v1JHGLAejSV0ec6fVR31vrojpM+JUiNVn0xJxL/ngmbyClDEf8qna5NFsu/xef67KT2kQ2YaU+wCuQEQHG55sw=="
},
"node_modules/@fontsource/pt-serif": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/@fontsource/pt-serif/-/pt-serif-4.1.0.tgz",
"integrity": "sha512-N2EpV4J0wgrwrNsEUG0wz3uX/wD44Yd3Tnm2vujbFHOCIBSSTAjiOImpl65ac7M7jRXxFnEpHjfofeDKSgvnFg=="
},
"node_modules/@graphql-tools/batch-execute": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/@graphql-tools/batch-execute/-/batch-execute-7.0.0.tgz",
@ -35244,11 +35256,21 @@
"resolved": "https://registry.npmjs.org/@fontsource/cormorant-garamond/-/cormorant-garamond-4.1.0.tgz",
"integrity": "sha512-Q9q+uj3ZmBrqn3knh5pVAB6kVXPDfut74U5lGxhf3gHQihrckOv/0Cw3ObKMc69r6OBk+IRcQN7A5d1aVVBGhw=="
},
"@fontsource/cormorant-sc": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/@fontsource/cormorant-sc/-/cormorant-sc-4.1.0.tgz",
"integrity": "sha512-cyXp0MZCr/vU+WF6Og5H8/Xn0rKuiMZ0DlbSjChm6HJJHbok3vuZwOAtzEn9rCV2aAxqBk6ARIl1l0aWcfSAoQ=="
},
"@fontsource/inter": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/@fontsource/inter/-/inter-4.1.0.tgz",
"integrity": "sha512-v1JHGLAejSV0ec6fVR31vrojpM+JUiNVn0xJxL/ngmbyClDEf8qna5NFsu/xef67KT2kQ2YaU+wCuQEQHG55sw=="
},
"@fontsource/pt-serif": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/@fontsource/pt-serif/-/pt-serif-4.1.0.tgz",
"integrity": "sha512-N2EpV4J0wgrwrNsEUG0wz3uX/wD44Yd3Tnm2vujbFHOCIBSSTAjiOImpl65ac7M7jRXxFnEpHjfofeDKSgvnFg=="
},
"@graphql-tools/batch-execute": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/@graphql-tools/batch-execute/-/batch-execute-7.0.0.tgz",

View File

@ -6,7 +6,9 @@
"dependencies": {
"@emotion/core": "^10.0.28",
"@fontsource/cormorant-garamond": "^4.1.0",
"@fontsource/cormorant-sc": "^4.1.0",
"@fontsource/inter": "^4.1.0",
"@fontsource/pt-serif": "^4.1.0",
"@material-ui/styles": "^4.9.0",
"@mdx-js/mdx": "^1.1.5",
"@mdx-js/react": "^1.1.5",

View File

@ -36,17 +36,17 @@ import Yoga.FillInTheGaps.Logic (Segment, findResult, parseSegments, toCode)
import Yoga.Helpers ((?||))
import Yoga as Y
type PreProps
= { children ∷
type PreProps =
{ children ∷
Nullable
{ props ∷
Nullable
{ props ∷
Nullable
{ mdxType ∷ Nullable String
, children ∷ Nullable String
, className ∷ Nullable String
}
{ mdxType ∷ Nullable String
, children ∷ Nullable String
, className ∷ Nullable String
}
}
}
}
isQuiz ∷ MDX -> Boolean
isQuiz (MDX a) =
@ -55,9 +55,9 @@ isQuiz (MDX a) =
&& ((unsafeCoerce a).props.children.props.mdxType == "code")
&& ((unsafeCoerce a).props.children.props.children # parseSegments # isJust)
type MdxProviderProps
= { children ∷ ReactChildren MDX
}
type MdxProviderProps =
{ children ∷ ReactChildren MDX
}
mkLiveMdxProviderComponent ∷ FetchImpl -> Effect (ReactComponent MdxProviderProps)
mkLiveMdxProviderComponent fetchImpl = mkMdxProviderComponent (apiCompiler fetchImpl)
@ -75,38 +75,33 @@ mkMdxProviderComponent compiler = do
visibleUntil /\ updateVisible <- useState 1
let
onFailure title kids = log "Oopsie daisy"
onSuccess = updateVisible (_ + one)
mapVisible ∷ Int -> MDX -> _
mapVisible i kid =
{ accum: i + if isQuiz kid then one else zero
, value: if (i < visibleUntil) then Just kid else Nothing
}
visibleKids ∷ Array MDX
visibleKids =
reactChildrenToArray children
# mapAccumL mapVisible zero
# _.value
# Array.catMaybes
contentMDX ∷ ReactChildren MDX
contentMDX = reactChildrenFromArray visibleKids
paragraph parChildren =
E.element M.p
( { layout: M.layout true
, css:
E.css
{ fontFamily: E.str "Cormorant Garamond"
, fontSize: E.str "min(calc(var(--s-1) + 2.4vw), var(--s1))"
, lineHeight: E.var "--line-height-small"
, "-ms-hyphens": E.str "auto"
, "-webkit-hyphens": E.str "auto"
, hyphens: E.str "auto"
, overflow: E.str "hidden"
}
E.css
{ fontFamily: E.str "Cormorant Garamond"
, fontSize: E.str "min(calc(var(--s-1) + 2.4vw), var(--s1))"
, lineHeight: E.var "--line-height-small"
, "-msHyphens": E.str "auto"
, "-webkitHyphens": E.str "auto"
, hyphens: E.str "auto"
, overflow: E.str "hidden"
}
, className: "blog-p"
, children: parChildren
}
@ -114,65 +109,56 @@ mkMdxProviderComponent compiler = do
let
mdxComponents =
{ "Sc":
\(props :: { children :: String }) ->
smallCaps props.children
\(props ∷ { children ∷ String }) ->
smallCaps props.children
, h1:
\(props ∷ { | M.MotionProps Props_h1 }) ->
React.element M.h1 (props { layout = M.layout true })
\(props ∷ { | M.MotionProps Props_h1 }) ->
React.element M.h1 (props { layout = M.layout true })
, h2:
\(props ∷ { | M.MotionProps Props_h2 }) ->
React.element M.h2 (props { layout = M.layout true })
\(props ∷ { | M.MotionProps Props_h2 }) ->
React.element M.h2 (props { layout = M.layout true })
, h3:
\(props ∷ { | M.MotionProps Props_h3 }) ->
React.element M.h3 (props { layout = M.layout true })
\(props ∷ { | M.MotionProps Props_h3 }) ->
React.element M.h3 (props { layout = M.layout true })
, h4:
\(props ∷ { | M.MotionProps Props_h4 }) ->
React.element M.h4 (props { layout = M.layout true })
\(props ∷ { | M.MotionProps Props_h4 }) ->
React.element M.h4 (props { layout = M.layout true })
, hr: (const $ R.hr {})
, p:
\(props ∷ { children :: Array JSX }) ->
paragraph props.children
\(props ∷ { children ∷ Array JSX }) ->
paragraph props.children
, inlineCode:
\props -> do
R.span { children: props.children }
\props -> do
R.span { children: props.children }
, pre:
mkFn2 \(props ∷ PreProps) other -> do
let
childrenQ = Nullable.toMaybe props.children
propsQ = (_.props >>> Nullable.toMaybe) =<< childrenQ
mdxTypeQ = (_.mdxType >>> Nullable.toMaybe) =<< propsQ
childrenQ2 = (_.children >>> Nullable.toMaybe) =<< propsQ
classNameQ = (_.className >>> Nullable.toMaybe) =<< propsQ
isCode = fromMaybe false (mdxTypeQ <#> eq "code")
codeQ = childrenQ2
height =
(fromMaybe 200 >>> show >>> (_ <> "px")) do
code <- codeQ
pure
( String.split (String.Pattern "\n") code
# Array.length
# \x -> (x * 12) + 100
)
language = fromMaybe "" (classNameQ >>= String.stripPrefix (String.Pattern "language-"))
segmentsQ = parseSegments (codeQ ?|| "")
case isCode, language, segmentsQ of
true, "purescript", Just initialSegments -> element quiz { initialSegments, onFailure, onSuccess }
true, _, _ ->
element editor
{ initialCode: fromMaybe "" codeQ
, height
, language
}
false, _, _ -> element (unsafePerformEffect $ unsafeCreateDOMComponent "pre") props
mkFn2 \(props ∷ PreProps) other -> do
let
childrenQ = Nullable.toMaybe props.children
propsQ = (_.props >>> Nullable.toMaybe) =<< childrenQ
mdxTypeQ = (_.mdxType >>> Nullable.toMaybe) =<< propsQ
childrenQ2 = (_.children >>> Nullable.toMaybe) =<< propsQ
classNameQ = (_.className >>> Nullable.toMaybe) =<< propsQ
isCode = fromMaybe false (mdxTypeQ <#> eq "code")
codeQ = childrenQ2
height =
(fromMaybe 200 >>> show >>> (_ <> "px")) do
code <- codeQ
pure
( String.split (String.Pattern "\n") code
# Array.length
# \x -> (x * 12) + 100
)
language = fromMaybe "" (classNameQ >>= String.stripPrefix (String.Pattern "language-"))
segmentsQ = parseSegments (codeQ ?|| "")
case isCode, language, segmentsQ of
true, "purescript", Just initialSegments -> element quiz { initialSegments, onFailure, onSuccess }
true, _, _ ->
element editor
{ initialCode: fromMaybe "" codeQ
, height
, language
}
false, _, _ -> element (unsafePerformEffect $ unsafeCreateDOMComponent "pre") props
}
pure
$ element mdxProvider
@ -180,11 +166,11 @@ mkMdxProviderComponent compiler = do
, components: mdxComponents
}
type QuizProps
= { initialSegments ∷ Array (Array Segment)
, onFailure ∷ String -> Array JSX -> Effect Unit
, onSuccess ∷ Effect Unit
}
type QuizProps =
{ initialSegments ∷ Array (Array Segment)
, onFailure ∷ String -> Array JSX -> Effect Unit
, onSuccess ∷ Effect Unit
}
mkQuiz ∷ ∀ r. { | Compiler r } -> Effect (ReactComponent QuizProps)
mkQuiz compiler = do
@ -196,24 +182,22 @@ mkQuiz compiler = do
$ element fillInTheGaps
{ segments
, run:
launchAff_ do
let
code = toCode segments
result <- compiler.compileAndRun { code }
liftEffect case result of
Right r
| String.stripSuffix (String.Pattern "\n") r.stdout == (findResult $ join segments) -> do
updateSolvedWith (const $ String.stripSuffix (String.Pattern "\n") r.stdout)
onSuccess
Right r
| r.stdout /= "\n" -> onFailure "Oh shit!" [ R.text r.stdout ]
Right r -> onFailure "Oh shit!" [ R.text r.stderr ]
Left (cr ∷ CompileResult) -> onFailure "Oh shit!" [ R.text (intercalate ", " (cr.result <#> _.message)) ]
launchAff_ do
let code = toCode segments
result <- compiler.compileAndRun { code }
liftEffect case result of
Right r
| String.stripSuffix (String.Pattern "\n") r.stdout == (findResult $ join segments) -> do
updateSolvedWith (const $ String.stripSuffix (String.Pattern "\n") r.stdout)
onSuccess
Right r
| r.stdout /= "\n" -> onFailure "Oh shit!" [ R.text r.stdout ]
Right r -> onFailure "Oh shit!" [ R.text r.stderr ]
Left (cr ∷ CompileResult) -> onFailure "Oh shit!" [ R.text (intercalate ", " (cr.result <#> _.message)) ]
, updateSegments:
\update -> do
let
updated = update segments
unless (segments == updated) do updateSegments (const updated)
\update -> do
let updated = update segments
unless (segments == updated) do updateSegments (const updated)
, solvedWith
}

View File

@ -23,12 +23,12 @@ import Yoga.Block.Icon.SVG as Icon
import Yoga.Block.Internal (_0)
import Yoga.Block.Modal as Modal
type SiteQueryResult
= { siteMetadata ∷
{ title ∷ String
, menuLinks ∷ Array { name ∷ String, link ∷ String }
}
type SiteQueryResult =
{ siteMetadata ∷
{ title ∷ String
, menuLinks ∷ Array { name ∷ String, link ∷ String }
}
}
data ShowModal
= ShowModal Modal.Props
@ -53,46 +53,44 @@ mkLayout fetchImpl = do
<#> case _ of
DarkMode -> ToggleIsRight
LightMode -> ToggleIsLeft
darkThemeToggle =
Block.toggle
Y.</> do
{ className: "dark-light-toggle"
, css:
Emotion.css
{ marginRight: Emotion.str "0"
, marginLeft: Emotion.str "auto"
}
Emotion.css
{ marginRight: Emotion.str "0"
, marginLeft: Emotion.str "auto"
}
, setTogglePosition:
case _ of
ToggleIsLeft -> setDarkOrLightMode (Just LightMode)
ToggleIsRight -> setDarkOrLightMode (Just DarkMode)
case _ of
ToggleIsLeft -> setDarkOrLightMode (Just LightMode)
ToggleIsRight -> setDarkOrLightMode (Just DarkMode)
, togglePosition: fromMaybe ToggleIsLeft maybeTogglePosition
, left:
Block.icon
Y.</> do
{ icon: Icon.moon
, stroke: Emotion.str "#eef"
}
Block.icon
Y.</> do
{ icon: Icon.moon
, stroke: Emotion.str "#eef"
}
, right:
Block.icon
Y.</> do
{ icon: Icon.sun
, stroke: Emotion.str "yellow"
}
Block.icon
Y.</> do
{ icon: Icon.sun
, stroke: Emotion.str "yellow"
}
, backgroundLeft:
Color.hsl 205.0 1.0 0.80
Color.hsl 205.0 1.0 0.80
, backgroundRight:
Color.hsl 250.0 1.0 0.1
Color.hsl 250.0 1.0 0.1
}
header =
Block.box
</ { className: "top-box"
, css:
Emotion.css
{ background: Emotion.str colour.backgroundLayer5
}
Emotion.css
{ background: Emotion.str colour.backgroundLayer5
}
}
/> [ Block.cluster
</* { justify: "space-between"
@ -105,13 +103,13 @@ mkLayout fetchImpl = do
R.span'
{ className: "blog-header"
, css:
Emotion.css
{ fontSize: Emotion.str "min(var(--s3), calc(var(--s1) + 1vw))"
, textTransform: Emotion.str "uppercase"
, letterSpacing: Emotion.str "calc(min(var(--s0) + 3vw), var(--s2) * -1.7)"
, fontWeight: Emotion.str "300"
, color: Emotion.str colour.text
}
Emotion.css
{ fontSize: Emotion.str "min(var(--s3), calc(var(--s1) + 1vw))"
, textTransform: Emotion.str "uppercase"
, letterSpacing: Emotion.str "calc(min(var(--s0) + 3vw), var(--s2) * -1.7)"
, fontWeight: Emotion.str "300"
, color: Emotion.str colour.text
}
}
[ R.text siteInfo.siteMetadata.title ]
, darkThemeToggle
@ -121,61 +119,62 @@ mkLayout fetchImpl = do
$ element Container.component
{ themeVariant: darkOrLightMode
, content:
Y.styled Block.stack
{ className: "blog-content"
, space: _0
, splitAfter: 2
, css:
Emotion.css
{ minHeight: Emotion.vh 100.0
, background: Emotion.str colour.backgroundLayer5
, borderRadius: Emotion.str "0 var(--s1) var(--s1) 0"
}
}
[ header
, Block.centre
</* { className: "centre"
, padding: _0
, gutters: _0
, css: Emotion.css { maxWidth: Emotion.ch 90.0 }
}
/> [ Block.box
</ do
{ padding: Emotion.px 16
, css:
Emotion.css
{ "& > p:first-of-type:first-letter":
Emotion.nested
$ Emotion.css
{ overflow: Emotion.str "hidden"
, float: Emotion.str "left"
, fontSize: Emotion.str "min(calc(var(--s0) * 1 + 8.03vw), var(--s5))"
, lineHeight: Emotion.str "min(calc(var(--s-1) + 2px + 3vw), var(--s3))"
, marginTop: Emotion.str "min(calc(var(--s-1) + 1.5vw), var(--s2))"
, marginRight: Emotion.var "--s-2"
, "&::selection":
Emotion.nested
$ Emotion.css
{ color: Emotion.str colour.highlightText
, background: Emotion.str colour.highlight
}
}
}
}
/> [ element mdxProviderComponent
{ children
}
]
]
, Y.styled Block.box
{ className: "blog-footer"
, css:
Emotion.css
{ background: Emotion.str colour.backgroundLayer1
, borderTop: Emotion.str $ "1px solid " <> colour.backgroundLayer3
, color: Emotion.str colour.text
}
Y.styled Block.stack
{ className: "blog-content"
, space: _0
, splitAfter: 2
, css:
Emotion.css
{ minHeight: Emotion.vh 100.0
, background: Emotion.str colour.background
, borderRadius: Emotion.str "0 var(--s1) var(--s1) 0"
}
}
[ header
, Block.centre
</* { className: "centre"
, padding: _0
, gutters: _0
, css: Emotion.css { maxWidth: Emotion.ch 90.0 }
}
[ R.text "Mark Eibes" ]
]
/> [ Block.box
</ do
{ padding: Emotion.px 16
, css:
Emotion.css
{ "& > p:first-of-type:first-letter":
Emotion.nested
$ Emotion.css
{ overflow: Emotion.str "visible"
, float: Emotion.str "left"
, fontSize: Emotion.str "min(calc(var(--s0) * 1 + 8.03vw), var(--s5))"
, fontFamily: Emotion.str "Cormorant Garamond"
, lineHeight: Emotion.str "min(calc(var(--s-1) + 2px + 3vw), var(--s3))"
, marginTop: Emotion.str "min(calc(var(--s-1) + 1.5vw), var(--s2))"
, marginRight: Emotion.var "--s-2"
, "&::selection":
Emotion.nested
$ Emotion.css
{ color: Emotion.str colour.highlightText
, background: Emotion.str colour.highlight
}
}
}
}
/> [ element mdxProviderComponent
{ children
}
]
]
, Y.styled Block.box
{ className: "blog-footer"
, css:
Emotion.css
{ background: Emotion.str colour.backgroundLayer1
, borderTop: Emotion.str $ "1px solid " <> colour.backgroundLayer3
, color: Emotion.str colour.text
}
}
[ R.text "Mark Eibes" ]
]
}

View File

@ -1,5 +1,8 @@
// Fonts
import "@fontsource/cormorant-garamond/500.css"
import "@fontsource/cormorant-garamond/500-italic.css"
import "@fontsource/cormorant-garamond/700.css"
import "@fontsource/cormorant-garamond/700-italic.css"
import "@fontsource/cormorant-garamond/latin-ext-500.css"
import "@fontsource/cormorant-garamond/latin-ext-500-italic.css"
import "@fontsource/cormorant-garamond/latin-ext-600.css"
import "@fontsource/cormorant-garamond/latin-ext-600-italic.css"
import "@fontsource/cormorant-garamond/latin-ext-700.css"
import "@fontsource/cormorant-garamond/latin-ext-700-italic.css"
import "@fontsource/cormorant-sc/latin-ext-500.css"

View File

@ -8,15 +8,15 @@ import React.Basic.Hooks (JSX)
import React.Basic.Hooks as React
import Yoga as Y
mkSmallCaps :: Effect (String -> JSX)
mkSmallCaps Effect (String -> JSX)
mkSmallCaps = do
React.component "SmallCaps" \text -> React.do
pure
$ Y.styled R.span'
{ className: "small-caps"
, css:
E.css
{ fontVariant: E.str "small-caps"
}
E.css
{ fontFamily: E.str "'Cormorant SC'"
}
}
[ R.text $ text ]