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