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