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