Skip to content

Commit 8510890

Browse files
committed
[IMPL] useClipboard hook
1 parent f469811 commit 8510890

21 files changed

Lines changed: 354 additions & 130 deletions

apps/react-tools-demo/scripts/generateMarkdown.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ function splitType(string){
4141
let newCode = [];
4242
let last = "";
4343
for (let part of string){
44-
if (last.split("<").length === last.split(">").length && last.split("(").length === last.split(")").length && last.split("[").length === last.split("]").length && last.split("{").length === last.split("}").length){
44+
if (last.split("<").length === last.split(/[^=]>/).length && last.split("(").length === last.split(")").length && last.split("[").length === last.split("]").length && last.split("{").length === last.split("}").length){
4545
last = part;
4646
newCode.push(part);
4747
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { useCallback, useRef, useState } from "react";
2+
import { useClipboard } from "../../../../../../packages/react-tools/src";
3+
4+
/**
5+
- The component has an internal state _val_ and invokes _useClipboard_ hook with these properties: _useValue_=__true__ _target_=__ref__ and _dataType_=__text__. It means that hook will return _value_ of type __string__ and _write_ and _read_ functions that handle __text__ data type. The component declares also two functions:
6+
- _copy_ that invokes __write__ function to write into clipboard text selected.
7+
- _paste_ that invokes __read__ function to get value from clipboard and setting it to internal stave variable _val_.
8+
- __ref__ is attached to a div that contains two buttons _COPY_ and _PASTE_, that have _copy_ and _paste_ functions respectively to handle their click event and two paragraph texts.
9+
- Another div is rendered that displays the internal state _val_ and current _clipboard_ values.
10+
*/
11+
export const UseClipboard = () => {
12+
const ref = useRef<HTMLDivElement>(null);
13+
const [val, setVal] = useState("");
14+
const [value, write, read] = useClipboard({ useValue: true, target: ref, dataType: "text" });
15+
const copy = useCallback(async () => {
16+
await write(getSelection()?.toString() || "");
17+
}, [write])
18+
19+
const paste = useCallback(async () => {
20+
const value = await read();
21+
setVal(value as string);
22+
}, [read])
23+
24+
return <div style={{ display: "grid", gridTemplateColumns: "50% 50%", columnGap: 15 }}>
25+
<div ref={ref} style={{ position: "relative", border: "1px solid lightgray" }}>
26+
<div style={{ display: "grid", gridTemplateColumns: "100px 100px", justifyContent: "center", columnGap: 15 }}>
27+
<button onClick={copy}>Copy</button>
28+
<button onClick={paste}>Paste</button>
29+
</div>
30+
<div>
31+
<p>Lorem ipsum, dolor sit amet consectetur adipisicing elit. Incidunt repudiandae fugit distinctio molestiae excepturi ex qui, impedit iste odit. Explicabo quis reprehenderit voluptates reiciendis nostrum minima autem temporibus sint doloribus</p>
32+
</div>
33+
<div>
34+
<p>Lorem ipsum, dolor sit amet consectetur adipisicing elit. Incidunt repudiandae fugit distinctio molestiae excepturi ex qui, impedit iste odit. Explicabo quis reprehenderit voluptates reiciendis nostrum minima autem temporibus sint doloribus</p>
35+
</div>
36+
</div>
37+
<div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", columnGap: 15, border: "1px solid lightgray" }}>
38+
<div style={{ textAlign: "left", padding: "0 1em", maxHeight: 300, overflow: "auto" }}>
39+
<p><strong>Use ClipboardValue:</strong></p>
40+
<pre>{JSON.stringify(value, null, 2)}</pre>
41+
</div>
42+
<div style={{ textAlign: "left", padding: "0 1em", maxHeight: 300, overflow: "auto" }}>
43+
<p><strong>Internal value:</strong></p>
44+
<pre>{JSON.stringify(val, null, 2)}</pre>
45+
</div>
46+
</div>
47+
</div>
48+
}

apps/react-tools-demo/src/constants/components.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ export const COMPONENTS = [
5555
"useTimeout",
5656
"useInterval",
5757
"useTextSelection",
58-
"useDocumentVisibility"
58+
"useDocumentVisibility",
59+
"useClipboard"
5960
]
6061
],
6162
//UTILS
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# useClipboard
2+
Hook to handle Clipboard. Refers to [Clipboard API](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard_API). __N.B.__: The hook has the same compatibility issues as the Clipboard API for Firefox, i.e. it is currently impossible to read from the clipboard.
3+
4+
## Usage
5+
6+
```tsx
7+
export const UseClipboard = () => {
8+
const ref = useRef<HTMLDivElement>(null);
9+
const [val, setVal] = useState("");
10+
const [value, write, read] = useClipboard({ useValue: true, target: ref, dataType: "text" });
11+
const copy = useCallback(async () => {
12+
await write(getSelection()?.toString() || "");
13+
}, [write])
14+
15+
const paste = useCallback(async () => {
16+
const value = await read();
17+
setVal(value as string);
18+
}, [read])
19+
20+
return <div style={{ display: "grid", gridTemplateColumns: "50% 50%", columnGap: 15 }}>
21+
<div ref={ref} style={{ position: "relative", border: "1px solid lightgray" }}>
22+
<div style={{ display: "grid", gridTemplateColumns: "100px 100px", justifyContent: "center", columnGap: 15 }}>
23+
<button onClick={copy}>Copy</button>
24+
<button onClick={paste}>Paste</button>
25+
</div>
26+
<div>
27+
<p>Lorem ipsum, dolor sit amet consectetur adipisicing elit. Incidunt repudiandae fugit distinctio molestiae excepturi ex qui, impedit iste odit. Explicabo quis reprehenderit voluptates reiciendis nostrum minima autem temporibus sint doloribus</p>
28+
</div>
29+
<div>
30+
<p>Lorem ipsum, dolor sit amet consectetur adipisicing elit. Incidunt repudiandae fugit distinctio molestiae excepturi ex qui, impedit iste odit. Explicabo quis reprehenderit voluptates reiciendis nostrum minima autem temporibus sint doloribus</p>
31+
</div>
32+
</div>
33+
<div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", columnGap: 15, border: "1px solid lightgray" }}>
34+
<div style={{ textAlign: "left", padding: "0 1em", maxHeight: 300, overflow: "auto" }}>
35+
<p><strong>Use ClipboardValue:</strong></p>
36+
<pre>{JSON.stringify(value, null, 2)}</pre>
37+
</div>
38+
<div style={{ textAlign: "left", padding: "0 1em", maxHeight: 300, overflow: "auto" }}>
39+
<p><strong>Internal value:</strong></p>
40+
<pre>{JSON.stringify(val, null, 2)}</pre>
41+
</div>
42+
</div>
43+
</div>
44+
}
45+
```
46+
47+
> - The component has an internal state _val_ and invokes _useClipboard_ hook with these properties: _useValue_=__true__ _target_=__ref__ and _dataType_=__text__. It means that hook will return _value_ of type __string__ and _write_ and _read_ functions that handle __text__ data type. The component declares also two functions:
48+
> - _copy_ that invokes __write__ function to write into clipboard text selected.
49+
> - _paste_ that invokes __read__ function to get value from clipboard and setting it to internal stave variable _val_.
50+
> - __ref__ is attached to a div that contains two buttons _COPY_ and _PASTE_, that have _copy_ and _paste_ functions respectively to handle their click event and two paragraph texts.
51+
> - Another div is rendered that displays the internal state _val_ and current _clipboard_ values.
52+
53+
54+
## API
55+
56+
```tsx
57+
useClipboard({ useValue, dataType, target }: { useValue: boolean, dataType: "text" | "any", target?: RefObject<HTMLElement> | HTMLElement }): [string, (text: string) => Promise<void>, () => Promise<string>] | [string | Blob | (string | Blob)[], (blob: Blob | Blob[]) => Promise<void>, () => Promise<string | Blob | (string | Blob)[]>] | [(text: string) => Promise<void>, () => Promise<string>] | [(blob: Blob | Blob[]) => Promise<void>, () => Promise<string | Blob | (string | Blob)[]>]
58+
```
59+
60+
> ### Params
61+
>
62+
> - __param__: _Object_
63+
> - __param.useValue__: _boolean_
64+
return a value with current clipboard value or not.
65+
> - __param.target?__: _RefObject<HTMLElement>|HTMLElement_
66+
target on which delimiter handling.
67+
> - __param.dataType?__: _"text"|"any"_
68+
data type handling. Based on it, Hook will return the functions for writing or reading text only or any type of data.
69+
>
70+
71+
> ### Returns
72+
>
73+
> __array__: elements depends on _useValue_ and _dataType_ values: if _dataType_ equals __text__ there will are only function to writing and reading text data type, otherwise any data type. If _useValue_ is true the first element will be _clipboard current value_.
74+
> - __Union of__:
75+
> - __Array__:
76+
> - _string_
77+
> - _(text: string) => Promise<void>_
78+
> - _() => Promise<string>_
79+
> - __Array__:
80+
> - _string|Blob|(string|Blob)[]_
81+
> - _(blob: Blob|Blob[]) => Promise<void>_
82+
> - _() => Promise<string|Blob|(string|Blob)[]>_
83+
> - __Array__:
84+
> - _(text: string) => Promise<void>_
85+
> - _() => Promise<string>_
86+
> - __Array__:
87+
> - _(blob: Blob|Blob[]) => Promise<void>_
88+
> - _() => Promise<string|Blob|(string|Blob)[]>_
89+
>

apps/react-tools-demo/src/markdown/useDebounce.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,5 +60,7 @@ if true, the function is executed after delay but only if the window is focused.
6060
>
6161
> __- array with debounced function, cancel function to abor debounced function and and immediate function to execute function immediately.__
6262
> - __Array__:
63-
> - _(...args: unknown[]) => void, ()=>void, (...args: unknown[]) => void_
63+
> - _(...args: unknown[]) => void_
64+
> - _()=>void_
65+
> - _(...args: unknown[]) => void_
6466
>

apps/react-tools-demo/src/markdown/useInterval.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,5 +58,7 @@ The number of milliseconds to wait before calling the `callback`.
5858
>
5959
> __- array: first element is the function to call setInterval; second element is the function to clearInterval; thrid element promisify setInterval.__
6060
> - __Array__:
61-
> - _(...args: TArgs) => void, () => void, (...args: TArgs) => Promise<void>_
61+
> - _(...args: TArgs) => void_
62+
> - _() => void_
63+
> - _(...args: TArgs) => Promise<void>_
6264
>

apps/react-tools-demo/src/markdown/useLocalStorageState.md

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,12 +77,11 @@ object with serializer and deserializer function to handle values in localStorag
7777
> - __Union of__:
7878
> - __Array__:
7979
> - _T_
80-
> - _() => T, () => void_
80+
> - _() => T_
81+
> - _() => void_
8182
> - __Array__:
82-
> - _Dispatch<SetStateAction<T>>_
83-
> - _() => T, () => void_
83+
> - _Dispatch<SetStateAction<T>>, () => T, () => void_
8484
> - __Array__:
8585
> - _T_
86-
> - _Dispatch<SetStateAction<T>>_
87-
> - _() => T, () => void_
86+
> - _Dispatch<SetStateAction<T>>, () => T, () => void_
8887
>

apps/react-tools-demo/src/markdown/useReducerGetReset.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,5 @@ Function that should return the _initial state_. If it’s not specified, the in
2828
> __array__
2929
> - __Array__:
3030
> - _ReducerState<R>_
31-
> - _Dispatch<ReducerAction<R>>_
32-
> - _()=>ReducerState<R>, ()=>void_
31+
> - _Dispatch<ReducerAction<R>>, ()=>ReducerState<R>, ()=>void_
3332
>

apps/react-tools-demo/src/markdown/useReducerHistory.md

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,5 @@ history capacity (default 'no-limit').
3030
> __array__
3131
> - __Array__:
3232
> - _ReducerState<R>_
33-
> - _Dispatch<ReducerAction<R>>_
34-
> - __Object__:
35-
> - __history__ : _readonly ReducerState<R>[]_
36-
> - __presentPointer__ : _number_
37-
> - __trackUpdate__ : _(enable:boolean) => void, canUndo: boolean, canRedo: boolean, undo: () => void, redo: () => void, go: (index: number) => void, clear: (value?: ReducerAction<R>) => void_
33+
> - _Dispatch<ReducerAction<R>>, {history: readonly ReducerState<R>[], presentPointer: number, trackUpdate: (enable:boolean) => void, canUndo: boolean, canRedo: boolean, undo: () => void, redo: () => void, go: (index: number) => void, clear: (value?: ReducerAction<R>) => void}_
3834
>

apps/react-tools-demo/src/markdown/useReducerHistoryGetter.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,5 @@ history capacity (default 'no-limit').
3030
> __array__
3131
> - __Array__:
3232
> - _ReducerState<R>_
33-
> - _Dispatch<ReducerAction<R>>_
34-
> - _()=>ReducerState<R>, {history: readonly ReducerState<R>[], presentPointer: number, trackUpdate: (enable:boolean) => void, canUndo: boolean, canRedo: boolean, undo: () => void, redo: () => void, go: (index: number) => void, clear: (value?: ReducerAction<R>) => void}_
33+
> - _Dispatch<ReducerAction<R>>, ()=>ReducerState<R>, {history: readonly ReducerState<R>[], presentPointer: number, trackUpdate: (enable:boolean) => void, canUndo: boolean, canRedo: boolean, undo: () => void, redo: () => void, go: (index: number) => void, clear: (value?: ReducerAction<R>) => void}_
3534
>

0 commit comments

Comments
 (0)