/
Link.purs
87 lines (79 loc) · 2.64 KB
/
Link.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
79
80
81
82
83
84
85
86
87
module Lumi.Components.Link where
import Prelude
import Color (cssStringHSLA)
import Data.Foldable (foldMap)
import Data.Maybe (Maybe(..))
import Data.Newtype (un)
import Data.Nullable (toNullable)
import Effect (Effect)
import Effect.Uncurried (runEffectFn1)
import JSS (JSS, jss)
import Lumi.Components.Color (colors)
import React.Basic (Component, JSX, createComponent, element, empty, makeStateless)
import React.Basic.DOM (CSS, css, unsafeCreateDOMComponent)
import React.Basic.DOM.Events (altKey, button, ctrlKey, metaKey, preventDefault, shiftKey, stopPropagation)
import React.Basic.Events (handler, merge, syntheticEvent)
import Web.HTML.History (URL(..))
type LinkProps =
{ className :: Maybe String
, href :: URL
, navigate :: Maybe (Effect Unit)
, style :: CSS
, target :: Maybe String
, testId :: Maybe String
, text :: JSX
}
component :: Component LinkProps
component = createComponent "Link"
link :: LinkProps -> JSX
link = makeStateless component render
where
lumiAnchorElement = element (unsafeCreateDOMComponent "a")
render { className, href, navigate, style, target, testId, text } =
lumiAnchorElement
{ children: text
, className: "lumi" <> foldMap (" " <> _) className
, "data-testid": toNullable testId
, href: un URL href
, onClick: handler (merge { button, metaKey, altKey, ctrlKey, shiftKey, syntheticEvent })
\{ button, metaKey, altKey, ctrlKey, shiftKey, syntheticEvent } -> do
case navigate, button, metaKey, altKey, ctrlKey, shiftKey of
Just n', Just 0, Just false, Just false, Just false, Just false ->
runEffectFn1
(handler (stopPropagation <<< preventDefault) $ const n')
syntheticEvent
_ , _ , _ , _ , _ , _ ->
runEffectFn1
(handler stopPropagation mempty)
syntheticEvent
, style
, target: toNullable target
}
defaults :: LinkProps
defaults =
{ className: Nothing
, href: URL ""
, navigate: Nothing
, style: css {}
, target: Nothing
, testId: Nothing
, text: empty
}
styles :: JSS
styles = jss
{ "@global":
{ "a.lumi":
{ color: cssStringHSLA colors.primary
, textDecoration: "none"
, "&:visited":
{ color: cssStringHSLA colors.primary
, textDecoration: "none"
}
, "&:hover":
{ cursor: "pointer"
, textDecoration: "underline"
}
, "&:focus, &:active": { outline: "0" }
}
}
}