git.iko.soy/rowtype-yoga/psfp
on 21e940e help sign in
142 lines 4.2 kB history raw
1module Container.Sidebar where
3import Prelude
5import Data.Monoid (guard)
6import Effect (Effect)
7import React.Basic (JSX)
8import React.Basic.DOM (css)
9import React.Basic.DOM as R
10import React.Basic.Events (handler_)
11import React.Basic.Hooks (ReactComponent, component, element)
12import React.Basic.Hooks as React
13import SVG.Icon (ActiveArrowDirection(..), mkMenu)
14import Theme.Styles (classNames, makeStyles)
15import Theme.Types (CSSTheme)
17mkSidebar ∷
18 Effect
19 ( ReactComponent
20 { children ∷ Array JSX
21 , modifyCollapsed ∷ (Boolean -> Boolean) -> Effect Unit
22 , collapsed ∷ Boolean
23 }
24 )
25mkSidebar = do
26 useStyles <-
27 makeStyles \(theme ∷ CSSTheme) ->
28 { sidebar:
29 css
30 { background: theme.backgroundColour
31 , fontFamily: theme.textFontFamily
32 , color: theme.textColour
33 , gridArea: "nav"
34 , display: "flex"
35 , flexDirection: "column"
36 , minHeight: "calc(100vh, -80px)"
37 , transition: "0.2s ease-in-out"
38 , overflowX: "hidden"
39 }
40 , sidebarCollapsed: css { width: "70px" }
41 , sidebarExpanded: css { width: "250px" }
42 , logo:
43 css
44 { width: "60px"
45 , height: "60px"
46 , padding: "0 5px 0 5px"
47 , transition: "0.2s ease-in-out"
48 , transitionDelay: "0.1s"
49 , alignSelf: "flex-end"
50 }
51 , logoCollapsed:
52 css
53 {} -- transform: "rotate(180deg)"}
54 }
55 menu <- mkMenu
56 component "Sidebar" \{ children, collapsed, modifyCollapsed } -> React.do
57 rawClasses <- useStyles
58 let
59 classes = flip classNames rawClasses
60 pure
61 $ R.nav
62 { className:
63 classes
64 [ _.sidebar
65 , if collapsed then _.sidebarCollapsed else _.sidebarExpanded
66 ]
67 , children:
68 [ R.ul
69 { className: classes [ _.logo, guard collapsed _.logoCollapsed ]
70 , onClick: handler_ $ (modifyCollapsed not)
71 , children:
72 [ element menu
73 { activeArrowDirection: if collapsed then ArrowPointsRight else ArrowPointsLeft }
74 ]
75 }
76 ]
77 <> children
78 }
80mkSidebarLink ∷ Effect (ReactComponent { name ∷ String, icon ∷ JSX, collapsed ∷ Boolean })
81mkSidebarLink = do
82 useStyles <-
83 makeStyles \(theme ∷ CSSTheme) ->
84 { sidebarEntry:
85 css
86 { fontFamily: theme.headingFontFamily
87 , alignSelf: "flex-end"
88 , justifyContent: "space-between"
89 , alignContent: "stretch"
90 , color: theme.textColour
91 , gridArea: "nav"
92 , display: "flex"
93 , flexDirection: "row"
94 , overflowX: "hidden"
95 , width: "190px"
96 , paddingLeft: "5px"
97 , borderRadius: "5px 0 0 5px"
98 , cursor: "pointer"
99 , "&:hover":
100 css
101 { background: theme.highlightColour
102 }
103 -- , "&:hover": css { opacity: "1.0"}
104 }
105 , label:
106 css
107 { fontFamily: theme.textFontFamily
108 , color: theme.textColour
109 , paddingLeft: "20px"
110 , textTransform: "uppercase"
111 , lineHeight: "60px"
112 , fontSize: "1.4em"
113 }
114 , icon:
115 css
116 { width: "50px"
117 , height: "50px"
118 , padding: "5px 10px 5px 5px"
119 , transition: "0.2s ease-in-out"
120 , transitionDelay: "0.1s"
121 , alignSelf: "flex-end"
122 , fill: theme.textColour <> " !important"
123 }
124 }
125 component "SidebarLink" \{ name, icon, collapsed } -> React.do
126 rawClasses <- useStyles
127 let
128 classes = flip classNames rawClasses
129 pure
130 $ R.li
131 { className: classes [ _.sidebarEntry ]
132 , children:
133 [ R.div
134 { className: classes [ _.label ]
135 , children: [ R.text name ]
136 }
137 , R.div
138 { className: classes [ _.icon ]
139 , children: [ icon ]
140 }
141 ]
142 }