Skip to content

Commit ab9a6f6

Browse files
authored
Merge pull request #206 from citizennet/AS-1774/copy-to-clipboard-button
AS-1774 Add `Copy to Clipboard` Button
2 parents 856978e + c56a64f commit ab9a6f6

File tree

3 files changed

+528
-296
lines changed

3 files changed

+528
-296
lines changed

src/Clipboard.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
"use strict";
2+
3+
exports._writeText = function _writeText({ navigator, text }) {
4+
navigator.clipboard.writeText(text);
5+
}

src/Clipboard.purs

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
module Ocelot.Clipboard
2+
( Output(..)
3+
, Query(..)
4+
, Slot
5+
, component
6+
) where
7+
8+
import Prelude
9+
10+
import Data.Maybe (Maybe(..))
11+
import Effect (Effect)
12+
import Effect.Aff as Effect.Aff
13+
import Effect.Aff.Class (class MonadAff)
14+
import Effect.Uncurried as Effect.Uncurried
15+
import Halogen as Halogen
16+
import Halogen.HTML as Halogen.HTML
17+
import Halogen.HTML.Events as Halogen.HTML.Events
18+
import Halogen.HTML.Properties as Halogen.HTML.Propetires
19+
import Ocelot.Block.Button as Ocelot.Block.Button
20+
import Ocelot.Block.Icon as Ocelot.Block.Icon
21+
import Ocelot.HTML.Properties as Ocelot.HTML.Properties
22+
import Web.HTML as Web.HTML
23+
import Web.HTML.Navigator as Web.HTML.Navigator
24+
import Web.HTML.Window as Web.HTML.Window
25+
26+
type Slot
27+
= Halogen.Slot Query Output
28+
29+
type Component m
30+
= Halogen.Component Query Input Output m
31+
32+
type ComponentHTML m
33+
= Halogen.ComponentHTML Action ChildSlot m
34+
35+
type ComponentM m
36+
= Halogen.HalogenM State Action ChildSlot Output m
37+
38+
type State
39+
= { copied :: Boolean
40+
, input :: Input
41+
}
42+
43+
data Action
44+
= Copy
45+
| Receive Input
46+
47+
data Query (a :: Type)
48+
49+
type Input
50+
= { text :: String }
51+
52+
type Output
53+
= Void
54+
55+
type ChildSlot
56+
= () :: Row Type
57+
58+
component ::
59+
forall m.
60+
MonadAff m =>
61+
Component m
62+
component =
63+
Halogen.mkComponent
64+
{ eval:
65+
Halogen.mkEval
66+
Halogen.defaultEval
67+
{ handleAction = handleAction
68+
, receive = Just <<< Receive
69+
}
70+
, initialState
71+
, render
72+
}
73+
74+
initialState :: Input -> State
75+
initialState input =
76+
{ copied: false
77+
, input
78+
}
79+
80+
handleAction ::
81+
forall m.
82+
MonadAff m =>
83+
Action ->
84+
ComponentM m Unit
85+
handleAction = case _ of
86+
Copy -> copy
87+
Receive input -> receive input
88+
89+
copy ::
90+
forall m.
91+
MonadAff m =>
92+
ComponentM m Unit
93+
copy = do
94+
input <- Halogen.gets _.input
95+
Halogen.liftEffect
96+
$ copyToClipboard input.text
97+
Halogen.modify_ _ { copied = true }
98+
void $ Halogen.fork do
99+
Halogen.liftAff
100+
$ Effect.Aff.delay (Effect.Aff.Milliseconds 1000.0)
101+
Halogen.modify_ _ { copied = false }
102+
103+
copyToClipboard ::
104+
String ->
105+
Effect Unit
106+
copyToClipboard text = do
107+
window <- Web.HTML.window
108+
navigator <- Web.HTML.Window.navigator window
109+
writeText navigator text
110+
111+
receive ::
112+
forall m.
113+
Input ->
114+
ComponentM m Unit
115+
receive input = do
116+
Halogen.modify_ _ { input = input }
117+
118+
render ::
119+
forall m.
120+
State ->
121+
ComponentHTML m
122+
render state
123+
| state.copied = renderDone
124+
| otherwise = renderActive
125+
126+
renderActive :: forall m. ComponentHTML m
127+
renderActive =
128+
Ocelot.Block.Button.button
129+
[ Halogen.HTML.Events.onClick \_ -> Copy ]
130+
[ Ocelot.Block.Icon.dataSources_
131+
, Halogen.HTML.span
132+
[ Ocelot.HTML.Properties.css "ml-2" ]
133+
[ Halogen.HTML.text "Copy to Clipboard" ]
134+
]
135+
136+
renderDone :: forall m. ComponentHTML m
137+
renderDone =
138+
Ocelot.Block.Button.button
139+
[ Halogen.HTML.Propetires.disabled true ]
140+
[ Ocelot.Block.Icon.success
141+
[ Ocelot.HTML.Properties.css "text-green"]
142+
, Halogen.HTML.span
143+
[ Ocelot.HTML.Properties.css "ml-2" ]
144+
[ Halogen.HTML.text "Copied" ]
145+
]
146+
147+
foreign import _writeText ::
148+
Effect.Uncurried.EffectFn1
149+
{ navigator :: Web.HTML.Navigator.Navigator
150+
, text :: String
151+
}
152+
Unit
153+
154+
writeText ::
155+
Web.HTML.Navigator.Navigator ->
156+
String ->
157+
Effect Unit
158+
writeText navigator text =
159+
Effect.Uncurried.runEffectFn1 _writeText
160+
{ navigator
161+
, text
162+
}

0 commit comments

Comments
 (0)