git.iko.soy/rowtype-yoga/psfp
on 7e2c09a help sign in
214 lines 6.1 kB history raw
1module PSLayout where
3import Prelude
4import Yoga.CSS.Safer (cssSafer)
5import Yoga.Theme.CSSBaseline (mkCssBaseline)
6import Yoga.CompileEditor.Component (mkCompileEditor)
7import Data.Array as Array
8import Data.Maybe (Maybe(..), fromMaybe)
9import Data.Nullable (Nullable)
10import Data.Nullable as Nullable
11import Data.String as String
12import Effect (Effect)
13import Yoga.Header.Component (mkHeader)
14import Milkis.Impl (FetchImpl)
15import Yoga.Panel.Component (makeComponent) as Panel
16import React.Basic (JSX, ReactComponent)
17import React.Basic.DOM (unsafeCreateDOMComponent)
18import React.Basic.DOM as R
19import React.Basic.Hooks (ReactChildren, component, componentWithChildren, element, reactChildrenFromArray, reactChildrenToArray)
20import React.Basic.Hooks as React
21import Yoga.Theme (fromTheme)
22import Yoga.Theme.Default (darkTheme)
23import Yoga.Theme.Provider (mkThemeProvider)
24import Yoga.Theme.Styles (makeStyles)
25import Yoga.Theme.Types (CSSTheme)
26import Yoga.Typography.Header (HeadingLevel(..), mkH)
27import Yoga.Typography.Paragraph (mkP)
29type SiteQueryResult
30 = { site ∷
31 { siteMetadata ∷
32 { title ∷ String
33 , menuLinks ∷ Array { name ∷ String, link ∷ String }
34 }
35 }
36 }
38type PreProps
39 = { children ∷
40 Nullable
41 { props ∷
42 Nullable
43 { mdxType ∷ Nullable String
44 , children ∷ Nullable String
45 , className ∷ Nullable String
46 }
47 }
48 }
50mkLayout ∷
51 FetchImpl ->
52 Effect
53 ( ReactComponent
54 { children ∷ ReactChildren JSX
55 , siteInfo ∷ SiteQueryResult
56 }
57 )
58mkLayout fetchImpl = do
59 themeProvider <- mkThemeProvider
60 mdxProviderComponent <- mkMdxProviderComponent fetchImpl
61 componentWithChildren "MDXLayout" \{ children, siteInfo } -> React.do
62 pure
63 $ element themeProvider
64 { theme: fromTheme darkTheme
65 , children:
66 [ element mdxProviderComponent
67 { children
68 , siteInfo
69 }
70 ]
71 }
73mkMdxProviderComponent ∷
74 FetchImpl ->
75 Effect
76 ( ReactComponent
77 { children ∷ ReactChildren JSX
78 , siteInfo ∷ SiteQueryResult
79 }
80 )
81mkMdxProviderComponent fetchImpl = do
82 cssBaseline <- mkCssBaseline
83 editor <- mkCompileEditor fetchImpl
84 sidebar <- mkSidebar
85 header <- mkHeader
86 h <- mkH
87 p <- mkP
88 useStyles <-
89 makeStyles \(theme :: CSSTheme) ->
90 { code:
91 cssSafer
92 { fontFamily: "PragmataPro Liga"
93 , backgroundColor: theme.interfaceColour
94 , fontSize: "10pt"
95 , border: "1px solid #383c39"
96 , padding: "3px"
97 , borderRadius: "3px"
98 }
99 , margins:
100 cssSafer
101 { marginLeft: "35px"
102 , marginRight: "35px"
103 }
104 , flexer:
105 cssSafer
106 { display: "flex"
107 , flexDirection: "row"
108 }
109 }
110 componentWithChildren "MDXProviderComponent" \{ children, siteInfo } -> React.do
111 classes <- useStyles
112 let
113 baseline child = element cssBaseline { kids: child }
115 siteInfoJSX =
116 R.div
117 { children:
118 [ element header { kids: [ R.text siteInfo.site.siteMetadata.title ], className: "" }
119 , element sidebar { links: siteInfo.site.siteMetadata.menuLinks }
120 , R.div_ (reactChildrenToArray children)
121 ]
122 }
124 mdxComponents =
125 { h1:
126 \props ->
127 element h { level: H2, text: props.children, className: Just classes.margins }
128 , h2:
129 \props ->
130 element h { level: H3, text: props.children, className: Just classes.margins }
131 , h3:
132 \props ->
133 element h { level: H4, text: props.children, className: Just classes.margins }
134 , p:
135 \props ->
136 R.div
137 { children: [ element p { text: props.children } ]
138 , className: classes.margins
139 }
140 , inlineCode:
141 \props -> do
142 R.span { className: classes.code, children: props.children }
143 , pre:
144 \(props ∷ PreProps) -> do
145 let
146 childrenQ = Nullable.toMaybe props.children
148 propsQ = (_.props >>> Nullable.toMaybe) =<< childrenQ
150 mdxTypeQ = (_.mdxType >>> Nullable.toMaybe) =<< propsQ
152 childrenQ2 = (_.children >>> Nullable.toMaybe) =<< propsQ
154 classNameQ = (_.className >>> Nullable.toMaybe) =<< propsQ
156 isCode = fromMaybe false (mdxTypeQ <#> eq "code")
158 codeQ = childrenQ2
160 height =
161 (fromMaybe 200 >>> show >>> (_ <> "px")) do
162 code <- codeQ
163 pure
164 ( String.split (String.Pattern "\n") code
165 # Array.length
166 # \x -> (x * 12) + 100
167 )
169 language = fromMaybe "" (classNameQ >>= String.stripPrefix (String.Pattern "language-"))
170 if isCode then
171 element editor
172 { initialCode: fromMaybe "" codeQ
173 , height
174 , language
175 }
176 else
177 element (unsafeCreateDOMComponent "pre") props
178 }
179 pure
180 $ baseline
181 [ element mdxProvider
182 { children:
183 [ siteInfoJSX
184 ]
185 , components: mdxComponents
186 }
187 ]
189mkSidebar = do
190 panel <- Panel.makeComponent
191 useStyles <-
192 makeStyles \(theme :: CSSTheme) ->
193 { flexer:
194 cssSafer
195 { display: "flex"
196 , flexDirection: "row"
197 , width: "300px"
198 , height: "300px"
199 }
200 }
201 component "Sidebar" \{ links } -> React.do
202 classes <- useStyles
203 pure
204 $ element panel
205 { kids: [ R.div_ [ R.text "hahahaha"] ]
206 , className: Just classes.flexer
207 }
209foreign import mdxProvider ∷
210 ∀ r.
211 ReactComponent
212 { components ∷ { | r } -- TODO Don't lie
213 , children ∷ Array JSX
214 }