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