/
Theme.purs
69 lines (58 loc) · 1.97 KB
/
Theme.purs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
module Lumi.Styles.Theme where
import Prelude
import Data.Int as Int
import Data.Newtype (class Newtype)
import Effect.Unsafe (unsafePerformEffect)
import Lumi.Components.Color (Color, ColorMap, ColorName, colorNames, colors)
import React.Basic (ReactContext, createContext)
import React.Basic.Hooks (Hook, UseContext, useContext)
newtype LumiTheme
= LumiTheme
{ colors :: ColorMap Color
, colorNames :: ColorMap ColorName
, fontSizes :: TextMap Int
-- | We store the factors for finding the line height and bottom margin for a
-- | given font size instead of actual values so that it's easier to override
-- | the theme with different font sizes while following the Lumi style
-- | guidelines.
, lineHeightFactor :: Number
, textMarginFactor :: Number
}
type TextMap a =
{ subtext :: a
, body :: a
, subsectionHeader :: a
, sectionHeader :: a
, title :: a
, mainHeader :: a
}
derive instance newtypeLumiTheme :: Newtype LumiTheme _
defaultTheme :: LumiTheme
defaultTheme = LumiTheme
{ colors
, colorNames
, fontSizes:
{ subtext: 12
, body: 14
, subsectionHeader: 17
, sectionHeader: 20
, title: 24
, mainHeader: 30
}
, lineHeightFactor: 17.0 / 14.0
, textMarginFactor: 9.0 / 17.0
}
lumiThemeContext :: ReactContext LumiTheme
lumiThemeContext =
unsafePerformEffect do
createContext defaultTheme
useTheme :: Hook (UseContext LumiTheme) LumiTheme
useTheme = useContext lumiThemeContext
textFontSize :: LumiTheme -> (forall a. TextMap a -> a) -> Int
textFontSize (LumiTheme { fontSizes }) selector = selector fontSizes
textLineHeight :: LumiTheme -> (forall a. TextMap a -> a) -> Int
textLineHeight (LumiTheme { fontSizes, lineHeightFactor }) selector =
Int.floor $ Int.toNumber (selector fontSizes) * lineHeightFactor
textMargin :: LumiTheme -> (forall a. TextMap a -> a) -> Int
textMargin (LumiTheme { fontSizes, textMarginFactor }) selector =
Int.floor $ Int.toNumber (selector fontSizes) * textMarginFactor