git.iko.soy/rowtype-yoga/ry-blocks
on main help sign in
Every Layout coming together
commitabe58716f7d9be51ffc2d563bc7cd412fdea8152 authorMark Eibes <mark.eibes@gmail.com> dateWed 2 Jun 2021, 23:32 (5 years ago) parent2fcd0ee
6 files changed+218−127
src/Yoga/Block.purs+8−2 src/Yoga/Block/Container/Style.purs+24−1 src/Yoga/Block/Layout/Sidebar/Style.purs+7−2 src/Yoga/Block/Layout/Sidebar/View.purs+8−1 src/Yoga/Block/Layout/Story.purs+169−119 src/Yoga/Block/Palette/Story.purs+2−2
src/Yoga/Block.purs+8−2
@@ -72,8 +72,14 @@ cover = el cover'
7272cover_ ∷ Array JSX -> JSX
7373cover_ = cover {}
7474
75−grid ∷ ∀ p q. Union p q Grid.Props => ReactComponent { children ∷ Array JSX | p }
76−grid = Grid.component
75+grid' ∷ ∀ p q. Union p q Grid.Props => ReactComponent { children ∷ Array JSX | p }
76+grid' = Grid.component
77+
78+grid ∷ ∀ p q. Lacks "children" p => Union p q Grid.Props => { | p } -> Array JSX -> JSX
79+grid = el grid'
80+
81+grid_ ∷ Array JSX -> JSX
82+grid_ = grid {}
7783
7884icon ∷ ∀ p q. Union p q Icon.Props => ReactComponent { | Icon.MandatoryProps p }
7985icon = Icon.component
src/Yoga/Block/Container/Style.purs+24−1
@@ -230,6 +230,7 @@ defaultColours =
230230 , backgroundLayer3: darken 0.05 >>> desaturate 0.1 $ lightBg
231231 , backgroundLayer4: darken 0.025 >>> desaturate 0.05 $ lightBg
232232 , backgroundLayer5: lightBg
233+ , backgroundLayer5Border: lightBg
233234 , backgroundCard: lightBg
234235 , popperBackground: (withAlpha 0.9 >>> darken 0.07 >>> desaturate 0.3) lightBg
235236 , popperBackgroundNoAlpha: (darken 0.07 >>> desaturate 0.3) lightBg
@@ -284,7 +285,8 @@ defaultColours =
284285 , backgroundLayer2: lighten 0.13 >>> saturate 0.10 $ darkBg
285286 , backgroundLayer3: lighten 0.16 >>> saturate 0.11 $ darkBg
286287 , backgroundLayer4: lighten 0.19 >>> saturate 0.11 $ darkBg
287− , backgroundLayer5: lighten 0.22 >>> saturate 0.08 $ darkBg
288+ , backgroundLayer5: lighten 0.21 >>> saturate 0.08 $ darkBg
289+ , backgroundLayer5Border: lighten 0.37 $ darkBg
288290 , backgroundCard: lighten 0.05 >>> saturate 0.1 $ darkBg
289291 , popperBackground: (withAlpha 0.8 >>> lighten 0.09 >>> saturate 0.05) darkBg
290292 , popperBackgroundNoAlpha: (lighten 0.09 >>> saturate 0.05) darkBg
@@ -403,6 +405,7 @@ type FlatTheme a =
403405 , backgroundLayer3 ∷ a
404406 , backgroundLayer4 ∷ a
405407 , backgroundLayer5 ∷ a
408+ , backgroundLayer5Border ∷ a
406409 , backgroundInverted ∷ a
407410 , backgroundCard ∷ a
408411 , interfaceBackground ∷ a
@@ -581,6 +584,26 @@ size =
581584 }
582585 }
583586
587+type BoxShadows =
588+ { s ∷ String
589+ , m ∷ String
590+ , l ∷ String
591+ , xl ∷ String
592+ , xxl ∷ String
593+ , default ∷ String
594+ }
595+
596+boxShadow ∷ BoxShadows
597+boxShadow =
598+ { s: "0 1px 2px 0 rgba(0,0,0,0.05)"
599+ , m: "0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)"
600+ , l: "0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)"
601+ , xl: "0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)"
602+ , xxl: "0 25px 50px -12px rgba(0, 0, 0, 0.25)"
603+ , default: "0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)"
604+ }
605+
606+
584607fontVariables ∷ { main ∷ String, mono ∷ String } -> Style
585608fontVariables { main, mono } =
586609 css
src/Yoga/Block/Layout/Sidebar/Style.purs+7−2
@@ -2,9 +2,12 @@ module Yoga.Block.Layout.Sidebar.Style where
22
33import Yoga.Prelude.Style
44
5+import Data.Interpolate (i)
6+
57data SidebarSide
68 = SidebarLeft
79 | SidebarRight
10+derive instance eqSidebarSide :: Eq SidebarSide
811
912type Props :: forall k. (Type -> k) -> Row k -> Row k
1013type Props f r
@@ -14,6 +17,7 @@ type Props f r
1417 , sideWidth ∷ f String
1518 , contentMin ∷ f String
1619 , noStretch ∷ f Boolean
20+ , reverseOnWrap ∷ f Boolean
1721 | r
1822 )
1923
@@ -32,7 +36,7 @@ sidebar props = styles <>? props.css
3236 nest
3337 { flexBasis: _0
3438 , flexGrow: "999" # str
35− , minWidth: "calc(" <> contentMin <> " - " <> space <> ")" # str
39+ , minWidth: i "calc(" contentMin " - " space " - " space ")" # str
3640 }
3741
3842 styles =
@@ -41,7 +45,7 @@ sidebar props = styles <>? props.css
4145 , "& > *":
4246 nest
4347 { display: flex
44− , flexWrap: wrap
48+ , flexWrap: if props.reverseOnWrap # isTruthy then str "wrap-reverse" else wrap
4549 , margin: "calc(" <> space <> " / 2 * -1)" # str
4650 , alignItems: props.noStretch # foldMap if _ then str "flex-start" else mempty
4751 }
@@ -56,3 +60,4 @@ sidebar props = styles <>? props.css
5660 <> case side of
5761 SidebarLeft -> css { "& > * > :last-child": nonSidebarStyle }
5862 SidebarRight -> css { "& > * > :first-child": nonSidebarStyle }
63+
src/Yoga/Block/Layout/Sidebar/View.purs+8−1
@@ -1,7 +1,10 @@
11module Yoga.Block.Layout.Sidebar.View (component, Props, PropsF) where
22
33import Yoga.Prelude.View
4+
5+import Data.Array as Array
46import React.Basic.DOM (div_)
7+import Yoga.Block.Layout.Sidebar.Style (SidebarSide(..))
58import Yoga.Block.Layout.Sidebar.Style as Style
69
710type PropsF f =
@@ -23,13 +26,17 @@ rawComponent ∷ ∀ p. ReactComponent { | p }
2326rawComponent =
2427 mkForwardRefComponent "Sidebar" do
2528 \(props ∷ { | PropsOptional }) ref -> React.do
29+ let
30+ flipChildren =
31+ if (props.side ?|| SidebarLeft) == SidebarRight then
32+ Array.reverse else identity
2633 pure
2734 $ emotionDiv ref
2835 props
2936 { className: "ry-sidebar " <>? props.className
3037 , css: Style.sidebar props
3138 , children:
32− [ div_
39+ [ div_ $ flipChildren
3340 [ div_ [ props.sidebar ]
3441 , div_ props.children
3542 ]
src/Yoga/Block/Layout/Story.purs+169−119
@@ -1,16 +1,22 @@
11module Yoga.Block.Layout.Story (default, layout) where
22
33import Prelude
4+
5+import Data.Interpolate (i)
46import Effect (Effect)
57import Effect.Unsafe (unsafePerformEffect)
68import React.Basic (JSX, element, fragment)
79import React.Basic.DOM as R
810import React.Basic.Emotion (nested)
911import React.Basic.Emotion as E
12+import React.Basic.Hooks (component)
13+import React.Basic.Hooks as React
1014import Yoga ((/>), (</*), (</*>))
1115import Yoga.Block as Block
12−import Yoga.Block.Container.Style (colour, size)
16+import Yoga.Block.Container.Style (boxShadow, colour, size)
1317import Yoga.Block.Container.Style as Styles
18+import Yoga.Block.Internal.CSS (nest)
19+import Yoga.Block.Layout.Sidebar.Style (SidebarSide(..))
1420import Yoga.Block.Typography as Typo
1521
1622default ∷
@@ -29,139 +35,183 @@ default =
2935 }
3036
3137layout ∷ Effect JSX
32−layout =
38+layout = do
39+ postPreview <- mkPostPreview
40+ let
41+ post1 =
42+ postPreview
43+ { title: "Some Post"
44+ , date: "16th May 2021"
45+ , author: "Someone W. Knowles"
46+ , image: "https://source.unsplash.com/3ujVzg9i2EI/105x130"
47+ , previewText: "When I was a young girl wrestling with 'undefined' not being a function my mother used to come up to me and say: 'Use PureScript'. Now, a mere twenty years later..."
48+ }
49+ post2 =
50+ postPreview
51+ { title: "The Big Beat Manifesto"
52+ , date: "2nd May 2008"
53+ , author: "Simon S. Hans"
54+ , image: "https://metro.co.uk/wp-content/uploads/2016/03/super-hans-006.jpg?quality=90&strip=all&zoom=1&resize=644%2C386"
55+ , previewText: "Have you read the Big Beat Manifesto lately? The Big Beat Manifesto goes \"Big Beats are the best, Get high all the time\"."
56+ }
57+ post3 =
58+ postPreview
59+ { title: "Here's my pitch: New management consultancy"
60+ , date: "9th Oct. 2009"
61+ , author: "Alan Johnson"
62+ , image: "https://preview.redd.it/3wsbjepf9yt11.png?width=960&crop=smart&auto=webp&s=d9989616ba615464b0a4a9e060250f8858c8a1f9"
63+ , previewText: "In. Fire 30% of the workforce. New logo. Boom! Out! You are now a fully trained management consultant."
64+ }
3365 pure
3466 $ fragment
3567 [ R.div_
3668 [ R.h1_ [ R.text "Some Layout combinations" ]
3769 , R.h2_ [ R.text "A Post Preview" ]
38− , postPreview
70+ , Block.grid { min: "30ch"}
71+ [ post1
72+ , post2
73+ , post3
74+ , post2
75+ , post1
76+ ]
3977 ]
4078 ]
41− where
42− postPreview =
43− Block.box
44− { padding: E.str $ size.l <> " " <> size.l <> " " <> size.xl
45− , className: "post-preview"
46− , css: boxCss
47− }
48− [ Block.stack { space: E.str size.s }
49− [ Block.stack { space: E.str size.m }
50− [ Block.sidebar { sidebar: avatar, contentMin: "25ch", space: size.l }
51− [ postTitle ]
52− , Block.cluster { justify: "space-between", space: size.m }
53− [ postAuthor, postDate ]
54− ]
55− , hr
56− , preview
57− ]
58− ]
59− where
60− hr =
61− R.hr'
62− </*> { className: "hr"
63− , css:
64− E.css
65− { backgroundColor: E.str $ colour.textInvertedPaler3
66− , height: E.px 1
67− , border: E.none
68− }
69− }
7079
71− preview =
72− R.p'
73− </* { className: "post-preview-text"
74− , css:
75− Typo.fontSizeSmall
76− <> E.css
77− { margin: E.str "0"
78− , lineHeight: E.str "1.6"
79− , color: E.str colour.textPaler2
80− }
81− }
82− /> [ R.text "When I was a young girl wrestling with 'undefined' not being a function my mother used to come up to me and say: 'Use PureScript'. Now, a mere twenty years later..." ]
80+mkPostPreview = do
81+ component "PostPreview" \{ title, date, author, previewText, image } -> React.do
82+ pure $
83+ Block.box
84+ { padding: E.str $ size.l <> " " <> size.l <> " " <> size.xl
85+ , className: "post-preview"
86+ , css: boxCss
87+ }
88+ [ Block.stack { space: E.str size.s, splitAfter: 2 }
89+ [ Block.stack { space: E.str size.m }
90+ [ Block.sidebar { sidebar: avatar image, side: SidebarRight, reverseOnWrap: true, contentMin: "30ch", space: size.l }
91+ [ postTitle title ]
92+ , Block.cluster { justify: "space-between", space: size.m }
93+ [ postDate date, postAuthor author]
94+ ]
95+ , hr
96+ , preview previewText
97+ ]
98+ ]
99+ where
100+ hr =
101+ R.hr'
102+ </*> { className: "hr"
103+ , css:
104+ E.css
105+ { backgroundColor: E.str colour.textInvertedPaler3
106+ , height: E.px 1
107+ , border: E.none
108+ }
109+ }
83110
84− boxCss =
85− Typo.fontSizeSmall
86− <> E.css
87− { background: E.str $ colour.backgroundLayer3
88− , borderRadius: E.str size.l
89− , maxWidth: E.ch 60.0
90− , paddingBottom: E.str size.xl
111+ preview text =
112+ R.p'
113+ </* { className: "post-preview-text"
114+ , css:
115+ Typo.fontSizeCopy
116+ <> E.css
117+ { margin: E.str "0"
118+ , lineHeight: E.str "1.6"
119+ , color: E.str colour.textPaler2
120+ }
91121 }
122+ /> [ R.text text ]
92123
93− avatar =
94− Block.centre { css: E.css { width: E.str $ size.xxl } }
95− [ R.div'
96− </* { className: "profile-picture-container"
97− , css:
98− E.css
99− { width: E.str $ size.xxl
100− , padding: E.str "0"
101− , margin: E.str "0"
102− , height: E.str size.xxl
103− , overflow: E.str "hidden"
104− , borderRadius: E.percent 50.0
105− , border: E.str $ size.xxs <> " solid " <> colour.highlight
106− , userSelect: E.none
107− }
124+ boxCss =
125+ Typo.fontSizeSmall
126+ <> E.css
127+ { background: E.str $ colour.backgroundLayer5
128+ , borderRadius: E.str size.m
129+ , borderColor: E.str colour.backgroundLayer5Border
130+ , borderWidth: E.str "1px"
131+ , maxWidth: E.ch 60.0
132+ , paddingBottom: E.str size.xl
133+ , boxShadow: E.str boxShadow.default
134+ , transition: E.str "450ms ease"
135+ , ":hover": nest
136+ { boxShadow: E.str boxShadow.xl
137+ , transform: E.str "translate(0, -2px) scale(1.02)"
138+ }
108139 }
109− /> [ R.img'
110− </*> { alt: "Profile Picture"
111− , src: "https://source.unsplash.com/z_8Jqe0Cc-s/360x200"
112− , className: "profile-picture"
113− , css:
114− E.css
115− { objectFit: E.str "cover"
116− , width: E.str $ size.xxl
117− , height: E.str $ size.xxl
118− , boxSizing: E.borderBox
119− , objectPosition: E.str "center right"
120− , transform: E.str "scaleX(-1)"
121− }
122− }
123− ]
124− ]
125140
126− postTitle =
127− Block.cover_ [
128− R.h2'
129− </* { className: "title"
141+ avatar image =
142+ Block.centre { css: E.css { width: E.str $ i "calc(" size.xxl " + " size.xxs " * 2)"} }
143+ [ R.div'
144+ </* { className: "profile-picture-container"
130145 , css:
131− Typo.fontSizeH3
132− <> E.css { color: E.str colour.textPaler2 }
146+ E.css
147+ { width: E.str $ size.xxl
148+ , padding: E.str "0"
149+ , margin: E.str "0"
150+ , height: E.str size.xxl
151+ , overflow: E.str "hidden"
152+ , borderRadius: E.percent 50.0
153+ , border: E.str $ i size.xxs " solid " colour.textPaler3
154+ , userSelect: E.none
155+ }
133156 }
134− /> [ R.text "How not to properly React" ]]
157+ /> [ R.img'
158+ </*> { alt: "Profile Picture"
159+ , src: image
160+ , className: "profile-picture"
161+ , css:
162+ E.css
163+ { objectFit: E.str "cover"
164+ , width: E.str $ size.xxl
165+ , height: E.str $ size.xxl
166+ , boxSizing: E.borderBox
167+ , objectPosition: E.str "center top"
168+ }
169+ }
170+ ]
171+ ]
135172
136− postAuthor =
137− R.h4'
138− </* { className: "author"
139− , css:
140− Typo.minimumSpacing
141− <> Typo.noMargins
142− <> Typo.allCaps
143− <> Typo.fontSizeSmall
144− <> Typo.regular
145− <> E.css
146− { "&::before":
147− nested $ E.css { content: E.str "'by '" }
148− <> Typo.thin
149− <> Typo.resetTextTransform
150− , color: E.str colour.textPaler3
173+ postTitle title =
174+ Block.cover_ [
175+ R.h3'
176+ </* { className: "title"
177+ , css:
178+ Typo.fontSizeH3
179+ <> E.css
180+ { color: E.str colour.textPaler2
181+ , fontWeight: E.str "500"
182+ }
151183 }
152− }
153− /> [ R.text "Someöne W. Knows" ]
184+ /> [ R.text title ]]
185+
186+ postAuthor author =
187+ R.h4'
188+ </* { className: "author"
189+ , css:
190+ Typo.minimumSpacing
191+ <> Typo.noMargins
192+ <> Typo.allCaps
193+ <> Typo.fontSizeSmall
194+ <> Typo.regular
195+ <> E.css
196+ { "&::before":
197+ nested $ E.css { content: E.str "'by '" }
198+ <> Typo.thin
199+ <> Typo.resetTextTransform
200+ , color: E.str colour.textPaler3
201+ }
202+ }
203+ /> [ R.text author ]
154204
155− postDate =
156− R.h4'
157− </* { className: "date"
158− , css:
159− Typo.minimumSpacing
160− <> Typo.noMargins
161− <> Typo.allCaps
162− <> Typo.fontSizeSmall
163− <> Typo.thin
164− <> Typo.rightAlign
165− <> E.css { color: E.str $ colour.textPaler3 }
166− }
167− /> [ R.text "16th May 2021" ]
205+ postDate date =
206+ R.h4'
207+ </* { className: "date"
208+ , css:
209+ Typo.minimumSpacing
210+ <> Typo.noMargins
211+ <> Typo.allCaps
212+ <> Typo.fontSizeSmall
213+ <> Typo.thin
214+ <> Typo.rightAlign
215+ <> E.css { color: E.str $ colour.textPaler3 }
216+ }
217+ /> [ R.text date ]
src/Yoga/Block/Palette/Story.purs+2−2
@@ -38,8 +38,8 @@ box ∷ Effect JSX
3838box =
3939 pure
4040 $ fragment
41− [ Block.grid </ { min: "100px" }
42− /> colourBoxes "Pink" Palette.pink
41+ [ Block.grid { min: "100px" }
42+ $ colourBoxes "Pink" Palette.pink
4343 <> colourBoxes "Mauve" Palette.mauve
4444 <> colourBoxes "Violet" Palette.violet
4545 <> colourBoxes "Blue" Palette.blue