/
Slider.purs
78 lines (68 loc) · 2.24 KB
/
Slider.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
70
71
72
73
74
75
76
77
78
module Lumi.Components.Slider where
import Prelude
import Color (cssStringHSLA)
import Data.Int (fromString)
import Data.Maybe (Maybe(..), fromMaybe)
import Data.Nullable (toNullable)
import Effect.Uncurried (EffectFn1, runEffectFn1)
import Effect.Unsafe (unsafePerformEffect)
import JSS (JSS, jss)
import Lumi.Components.Color (colors)
import Lumi.Components.Input as Input
import React.Basic.Classic (Component, JSX, createComponent, element, makeStateless)
import React.Basic.DOM as R
import React.Basic.DOM.Events (targetValue)
import React.Basic.Events as Events
type SliderProps =
{ completed :: Int
, onChange :: EffectFn1 Int Unit
, style :: R.CSS
}
component :: Component SliderProps
component = createComponent "Slider"
slider :: SliderProps -> JSX
slider = makeStateless component render
where
render props =
lumiSliderElement
{ style: props.style
, children:
[ Input.input Input.range
{ value = show props.completed
, min = toNullable $ Just 0.0
, max = toNullable $ Just 100.0
, onChange = Events.handler targetValue \targetValue -> do
runEffectFn1 props.onChange $ fromMaybe 0 $ fromString =<< targetValue
}
, lumiValueBarElement
{ style: R.css { width: show props.completed <> "%" }
}
]
}
lumiSliderElement = element $ unsafePerformEffect $ R.unsafeCreateDOMComponent "lumi-slider"
lumiValueBarElement = element $ unsafePerformEffect $ R.unsafeCreateDOMComponent "lumi-value-bar"
styles :: JSS
styles = jss
{ "@global":
{ "lumi-slider":
{ position: "relative"
, width: "100%"
, "& input.lumi[type=\"range\"]":
{ position: "absolute"
, left: "0px"
, padding: "0px"
, margin: "0px"
, width: "100%"
, height: "4px"
}
, "& lumi-value-bar":
{ position: "absolute"
, padding: "0px"
, margin: "0px"
, backgroundColor: cssStringHSLA colors.primary
, height: "4px"
, pointerEvents: "none"
}
}
}
}