git.iko.soy/rowtype-yoga/psfp
on a333b88 help sign in
177 lines 6.7 kB history raw
1module PSLayout where
3import Prelude
4import Color as Color
5import Data.Maybe (Maybe(..), fromMaybe)
6import Data.Tuple.Nested ((/\))
7import Effect (Effect)
8import MDX (MDX)
9import MDXProvider (MdxProviderProps)
10import Milkis.Impl (FetchImpl)
11import React.Basic (ReactComponent)
12import React.Basic.DOM as R
13import React.Basic.Emotion as Emotion
14import React.Basic.Hooks (ReactChildren, element, reactComponentWithChildren, useState')
15import React.Basic.Hooks as React
16import Yoga ((/>), (</), (</*))
17import Yoga as Y
18import Yoga.Block as Block
19import Yoga.Block.Atom.Toggle.Types (TogglePosition(..))
20import Yoga.Block.Container as Container
21import Yoga.Block.Container.Style (DarkOrLightMode(..), colour)
22import Yoga.Block.Icon.SVG as Icon
23import Yoga.Block.Internal (_0)
24import Yoga.Block.Modal as Modal
26type SiteQueryResult
27 = { siteMetadata ∷
28 { title ∷ String
29 , menuLinks ∷ Array { name ∷ String, link ∷ String }
30 }
31 }
33data ShowModal
34 = ShowModal Modal.Props
35 | HideModal
37mkLayout ∷
38 FetchImpl ->
39 Effect
40 ( ReactComponent
41 { children ∷ ReactChildren MDX
42 , siteInfo ∷ SiteQueryResult
43 , mdxProviderComponent ∷ ReactComponent MdxProviderProps
44 }
45 )
46mkLayout fetchImpl = do
47 -- mdxProviderComponent <- mkMdxProviderComponent (apiCompiler fetchImpl)
48 reactComponentWithChildren "MDXLayout" \{ children, siteInfo, mdxProviderComponent } -> React.do
49 darkOrLightMode /\ setDarkOrLightMode <- useState' Nothing
50 let
51 maybeTogglePosition =
52 darkOrLightMode
53 <#> case _ of
54 DarkMode -> ToggleIsRight
55 LightMode -> ToggleIsLeft
57 darkThemeToggle =
58 Block.toggle
59 Y.</> do
60 { className: "dark-light-toggle"
61 , css:
62 Emotion.css
63 { marginRight: Emotion.str "0"
64 , marginLeft: Emotion.str "auto"
65 }
66 , setTogglePosition:
67 case _ of
68 ToggleIsLeft -> setDarkOrLightMode (Just LightMode)
69 ToggleIsRight -> setDarkOrLightMode (Just DarkMode)
70 , togglePosition: fromMaybe ToggleIsLeft maybeTogglePosition
71 , left:
72 Block.icon
73 Y.</> do
74 { icon: Icon.moon
75 , stroke: Emotion.str "#eef"
76 }
77 , right:
78 Block.icon
79 Y.</> do
80 { icon: Icon.sun
81 , stroke: Emotion.str "yellow"
82 }
83 , backgroundLeft:
84 Color.hsl 205.0 1.0 0.80
85 , backgroundRight:
86 Color.hsl 250.0 1.0 0.1
87 }
89 header =
90 Block.box
91 </ { className: "top-box"
92 , css:
93 Emotion.css
94 { background: Emotion.str colour.backgroundLayer5
95 }
96 }
97 /> [ Block.cluster
98 </* { justify: "space-between"
99 , className: "header"
100 , space: "var(--s-2)"
101 , css: Emotion.css { width: Emotion.percent 100.0 }
102 }
103 /> do
104 [ Y.styled
105 R.span'
106 { className: "blog-header"
107 , css:
108 Emotion.css
109 { fontSize: Emotion.str "min(var(--s3), calc(var(--s1) + 1vw))"
110 , textTransform: Emotion.str "uppercase"
111 , letterSpacing: Emotion.str "calc(min(var(--s0) + 3vw), var(--s2) * -1.7)"
112 , fontWeight: Emotion.str "300"
113 , color: Emotion.str colour.text
114 }
115 }
116 [ R.text siteInfo.siteMetadata.title ]
117 , darkThemeToggle
118 ]
119 ]
120 pure
121 $ element Container.component
122 { themeVariant: darkOrLightMode
123 , content:
124 Y.styled Block.stack
125 { className: "blog-content"
126 , space: _0
127 , splitAfter: 2
128 , css:
129 Emotion.css
130 { minHeight: Emotion.vh 100.0
131 , background: Emotion.str colour.backgroundLayer5
132 , borderRadius: Emotion.str "0 var(--s1) var(--s1) 0"
133 }
134 }
135 [ header
136 , Block.centre
137 </* { className: "centre"
138 , padding: _0
139 , gutters: _0
140 , css: Emotion.css { maxWidth: Emotion.ch 90.0 }
141 }
142 /> [ Block.box
143 </ do
144 { padding: Emotion.px 16
145 , css:
146 Emotion.css
147 { "& > p:first-of-type:first-letter":
148 Emotion.nested
149 $ Emotion.css
150 { fontSize: Emotion.var "--s4"
151 , height: Emotion.var "--s3"
152 , display: Emotion.str "block"
153 , overflow: Emotion.str "hidden"
154 , float: Emotion.str "left"
155 , marginTop: Emotion.str "calc(var(--s0))"
156 , lineHeight: Emotion.var "--s3"
157 , marginRight: Emotion.var "--s-2"
158 }
159 }
160 }
161 /> [ element mdxProviderComponent
162 { children
163 }
164 ]
165 ]
166 , Y.styled Block.box
167 { className: "blog-footer"
168 , css:
169 Emotion.css
170 { background: Emotion.str colour.backgroundLayer1
171 , borderTop: Emotion.str $ "1px solid " <> colour.backgroundLayer3
172 , color: Emotion.str colour.text
173 }
174 }
175 [ R.text "Mark Eibes" ]
176 ]
177 }