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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
module Gargantext.Components.Bootstrap.Button (button) where
import Gargantext.Prelude
import DOM.Simple.Event as DE
import Data.Array (elem)
import Data.Foldable (intercalate)
import Effect (Effect)
import Gargantext.Components.Bootstrap.Spinner (spinner)
import Gargantext.Components.Bootstrap.Types (ButtonVariant(..), ComponentStatus(..), Sizing(..), Variant(..))
import Gargantext.Utils ((?))
import Gargantext.Utils.Reactix as R2
import Reactix as R
import Reactix.DOM.HTML as H
import Reactix.SyntheticEvent as RE
type Props =
( callback :: Unit -> Effect Unit
| Options
)
type Options =
( block :: Boolean
, className :: String
, size :: Sizing
, status :: ComponentStatus
, title :: String
, type :: String
, variant :: ButtonVariant
)
options :: Record Options
options =
{ block : false
, className : ""
, status : Enabled
, size : MediumSize
, title : ""
, type : "button"
, variant : ButtonVariant Primary
}
-- | Structural Component for the Bootstrap button
-- |
-- | https://getbootstrap.com/docs/4.6/components/buttons/
button :: forall r. R2.OptComponent Options Props r
button = R2.optComponent component options
componentName :: String
componentName = "b-button"
bootstrapName :: String
bootstrapName = "btn"
component :: R.Component Props
component = R.hooksComponent componentName cpt where
cpt props@{ callback
, status
} children = do
-- Computed
let
className = intercalate " "
-- provided custom className
[ props.className
-- BEM classNames
, componentName
, componentName <> "--" <> show status
-- Bootstrap specific classNames
, bootstrapName
, bootstrapName <> "-" <> show props.variant
, bootstrapName <> "-" <> show props.size
, props.block == true ?
bootstrapName <> "-block" $
mempty
]
click = onClick status callback
-- Render
pure $
H.button
{ className
, on: { click }
, disabled: elem status [ Disabled, Deferred ]
, type: props.type
, title: props.title
}
[
R2.when (status == Deferred) $
spinner
{ className: componentName <> "__spinner" }
,
H.span
{ className: componentName <> "__inner" }
children
]
-- | Clicked event will effectively be triggered according to the
-- | component status props
onClick ::
ComponentStatus
-> (Unit -> Effect Unit)
-> RE.SyntheticEvent DE.Event
-> Effect Unit
onClick status callback event = do
RE.preventDefault event
when (status == Enabled) $ callback unit