matsuri-hooks 0.0.5 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +59 -27
- package/cjs/index.js +52 -0
- package/cjs/index.js.map +1 -0
- package/cjs/useAuth.js +70 -0
- package/cjs/useAuth.js.map +1 -0
- package/cjs/useClipboardCopy.js +33 -0
- package/cjs/useClipboardCopy.js.map +1 -0
- package/cjs/useFetch.js +135 -0
- package/cjs/useFetch.js.map +1 -0
- package/cjs/useIntersectionObserver.js +51 -0
- package/cjs/useIntersectionObserver.js.map +1 -0
- package/cjs/useKeyboardShortcut.js +28 -0
- package/cjs/useKeyboardShortcut.js.map +1 -0
- package/cjs/useOnClickOutside.js +43 -0
- package/cjs/useOnClickOutside.js.map +1 -0
- package/cjs/utils/isBrowser.js +7 -0
- package/cjs/utils/isBrowser.js.map +1 -0
- package/esm/index.js +3 -0
- package/esm/index.js.map +1 -0
- package/esm/useAuth.js +54 -54
- package/esm/useAuth.js.map +1 -0
- package/esm/useClipboardCopy.js +36 -0
- package/esm/useClipboardCopy.js.map +1 -0
- package/esm/useFetch.js +139 -166
- package/esm/useFetch.js.map +1 -0
- package/esm/useIntersectionObserver.js +42 -29
- package/esm/useIntersectionObserver.js.map +1 -0
- package/esm/useKeyboardShortcut.js +20 -0
- package/esm/useKeyboardShortcut.js.map +1 -0
- package/esm/useOnClickOutside.js +30 -21
- package/esm/useOnClickOutside.js.map +1 -0
- package/esm/utils/isBrowser.js +1 -0
- package/esm/utils/isBrowser.js.map +1 -0
- package/{esm/index.d.ts → index.d.ts} +2 -0
- package/index.js +7 -0
- package/index.js.map +1 -0
- package/index.test.d.ts +1 -0
- package/package.json +45 -66
- package/{dist → types}/index.d.ts +2 -0
- package/types/index.test.d.ts +1 -0
- package/{dist → types}/useAuth.d.ts +1 -1
- package/types/useAuth.test.d.ts +1 -0
- package/types/useClipboardCopy.d.ts +6 -0
- package/types/useFetch.d.ts +31 -0
- package/{dist → types}/useIntersectionObserver.d.ts +1 -0
- package/types/useKeyboardShortcut.d.ts +1 -0
- package/{dist → types}/useOnClickOutside.d.ts +1 -0
- package/types/useOnClickOutside.test.d.ts +1 -0
- package/{dist → types}/utils/isBrowser.d.ts +0 -0
- package/{esm/useAuth.d.ts → useAuth.d.ts} +1 -1
- package/useAuth.js +60 -0
- package/useAuth.js.map +1 -0
- package/useAuth.test.d.ts +1 -0
- package/useClipboardCopy.d.ts +6 -0
- package/useClipboardCopy.js +36 -0
- package/useClipboardCopy.js.map +1 -0
- package/useFetch.d.ts +31 -0
- package/useFetch.js +145 -0
- package/useFetch.js.map +1 -0
- package/{esm/useIntersectionObserver.d.ts → useIntersectionObserver.d.ts} +1 -0
- package/useIntersectionObserver.js +48 -0
- package/useIntersectionObserver.js.map +1 -0
- package/useKeyboardShortcut.d.ts +1 -0
- package/useKeyboardShortcut.js +20 -0
- package/useKeyboardShortcut.js.map +1 -0
- package/{esm/useOnClickOutside.d.ts → useOnClickOutside.d.ts} +1 -0
- package/useOnClickOutside.js +34 -0
- package/useOnClickOutside.js.map +1 -0
- package/useOnClickOutside.test.d.ts +1 -0
- package/{esm/utils → utils}/isBrowser.d.ts +0 -0
- package/utils/isBrowser.js +2 -0
- package/utils/isBrowser.js.map +1 -0
- package/CHANGELOG.md +0 -158
- package/LICENSE +0 -674
- package/dist/index.js +0 -1
- package/dist/useFetch.d.ts +0 -31
- package/esm/useFetch.d.ts +0 -31
package/README.md
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# Matsuri Hooks
|
|
2
2
|
|
|
3
3
|
<!-- vscode-markdown-toc -->
|
|
4
|
+
<!-- prettier-ignore -->
|
|
4
5
|
* [Motivation](#Motivation)
|
|
5
6
|
* [Usage](#Usage)
|
|
6
7
|
* [Installation](#Installation)
|
|
@@ -10,6 +11,8 @@
|
|
|
10
11
|
* [useAuthFetch](#useAuthFetch)
|
|
11
12
|
* [useIntersectionObserver](#useIntersectionObserver)
|
|
12
13
|
* [useOnClickOutside](#useOnClickOutside)
|
|
14
|
+
* [useKeyboardShortcut](#useKeyboardShortcut)
|
|
15
|
+
* [useClipboardCopy](#useClipboardCopy)
|
|
13
16
|
|
|
14
17
|
<!-- vscode-markdown-toc-config
|
|
15
18
|
numbering=false
|
|
@@ -17,13 +20,10 @@
|
|
|
17
20
|
/vscode-markdown-toc-config -->
|
|
18
21
|
<!-- /vscode-markdown-toc -->
|
|
19
22
|
|
|
20
|
-
|
|
21
|
-
|
|
22
23
|
## <a name='Motivation'></a>Motivation
|
|
23
24
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
- Provide complex processing with safety guaranteed by testing
|
|
26
|
+
- Be common processing for each product
|
|
27
27
|
|
|
28
28
|
## <a name='Usage'></a>Usage
|
|
29
29
|
|
|
@@ -41,31 +41,28 @@ yarn add matsuri-hooks
|
|
|
41
41
|
const { token, authenticated, signin, signout } = useAuth()
|
|
42
42
|
|
|
43
43
|
return (
|
|
44
|
-
<div>
|
|
45
|
-
{authenticated ? (
|
|
46
|
-
<button onClick={signout}>Signout</button>
|
|
47
|
-
):(
|
|
48
|
-
<button onClick={signin}>Signin</button>
|
|
49
|
-
)}
|
|
50
|
-
</div>
|
|
44
|
+
<div>{authenticated ? <button onClick={signout}>Signout</button> : <button onClick={signin}>Signin</button>}</div>
|
|
51
45
|
)
|
|
52
46
|
```
|
|
53
47
|
|
|
54
48
|
### <a name='useFetch'></a>useFetch
|
|
55
49
|
|
|
56
50
|
```tsx
|
|
57
|
-
const { data, error, refetch } = useFetch<{species: "fish"}>("https://example.com/fish", { method: "GET" })
|
|
51
|
+
const { data, error, refetch } = useFetch<{ species: "fish" }>("https://example.com/fish", { method: "GET" })
|
|
58
52
|
|
|
59
53
|
return (
|
|
60
54
|
<div>
|
|
61
55
|
<p>Species: {data?.species}</p>
|
|
62
56
|
<button onClick={refetch}>Refetch</button>
|
|
63
57
|
{error ? (
|
|
64
|
-
<p>
|
|
65
|
-
|
|
58
|
+
<p>
|
|
59
|
+
{error.name}: {error.message}
|
|
60
|
+
</p>
|
|
61
|
+
) : null}
|
|
66
62
|
</div>
|
|
67
63
|
)
|
|
68
64
|
```
|
|
65
|
+
|
|
69
66
|
### <a name='useAuthFetch'></a>useAuthFetch
|
|
70
67
|
|
|
71
68
|
This default token format is `X-Access-Token: [TOKEN]`.
|
|
@@ -75,7 +72,7 @@ const { token } = useAuth()
|
|
|
75
72
|
const { error, refetch } = useAuthFetch<never>(token, "https://example.com", { method: "POST", ... )
|
|
76
73
|
```
|
|
77
74
|
|
|
78
|
-
|
|
75
|
+
- useAuthBearerFetch:this default token format is `Authorization: Bearer [TOKEN]`.
|
|
79
76
|
|
|
80
77
|
### <a name='useIntersectionObserver'></a>useIntersectionObserver
|
|
81
78
|
|
|
@@ -86,7 +83,7 @@ const { entry, disconnect } = useIntersectionObserver(ref, { threshold: 0.1 })
|
|
|
86
83
|
const [image, setImage] = useState<string>()
|
|
87
84
|
|
|
88
85
|
useEffect(() => {
|
|
89
|
-
if(entry){
|
|
86
|
+
if (entry) {
|
|
90
87
|
const fetchImage = async () => {
|
|
91
88
|
//...
|
|
92
89
|
return image
|
|
@@ -94,29 +91,64 @@ useEffect(() => {
|
|
|
94
91
|
disconnect()
|
|
95
92
|
setImage(fetchImage())
|
|
96
93
|
}
|
|
97
|
-
},[])
|
|
94
|
+
}, [])
|
|
95
|
+
|
|
96
|
+
return <img ref={ref} src={image || "dummy.png"} />
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### <a name='useOnClickOutside'></a>useOnClickOutside
|
|
100
|
+
|
|
101
|
+
```tsx
|
|
102
|
+
const [open, setOpen] = useState(false)
|
|
103
|
+
const ref = useRef(null)
|
|
104
|
+
useOnClickOutside(ref, () => {
|
|
105
|
+
setOpen(false)
|
|
106
|
+
})
|
|
107
|
+
return (
|
|
108
|
+
<div>
|
|
109
|
+
<button onClick={() => setOpen(true)}>OPEN</button>
|
|
110
|
+
<Modal ref={ref} open={open} />
|
|
111
|
+
</div>
|
|
112
|
+
)
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### <a name='useKeyboardShortcut'></a>useKeyboardShortcut
|
|
116
|
+
|
|
117
|
+
If the specified key and control or meta key are pressed together, the second argument callback is executed.
|
|
98
118
|
|
|
119
|
+
```tsx
|
|
120
|
+
const [open, setOpen] = useState(false)
|
|
121
|
+
const ref = useRef(null)
|
|
122
|
+
useKeyboardShortcut("j", () => {
|
|
123
|
+
setOpen(true)
|
|
124
|
+
})
|
|
99
125
|
return (
|
|
100
|
-
<
|
|
126
|
+
<div>
|
|
127
|
+
<Modal ref={ref} open={open} />
|
|
128
|
+
</div>
|
|
101
129
|
)
|
|
102
130
|
```
|
|
103
131
|
|
|
104
|
-
### <a name='
|
|
132
|
+
### <a name='useClipboardCopy'></a>useClipboardCopy
|
|
105
133
|
|
|
134
|
+
If the specified key is pressed together with a control or meta key, or if the return method is called, the specified text is copied to clipboard.
|
|
135
|
+
Then, if the copy fails, onFailure is called, and if it succeeds, onSuccess is called.
|
|
106
136
|
|
|
107
137
|
```tsx
|
|
108
138
|
const [open, setOpen] = useState(false)
|
|
109
139
|
const ref = useRef(null)
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
() => {
|
|
113
|
-
|
|
140
|
+
const copy = useKeyboardShortcut(SOME_TOKEN, {
|
|
141
|
+
key: "j",
|
|
142
|
+
onSuccess: () => {
|
|
143
|
+
addAlert("Success")
|
|
144
|
+
},
|
|
145
|
+
onFailure: () => {
|
|
146
|
+
addAlert("Failed", { type: "error" })
|
|
114
147
|
}
|
|
115
|
-
)
|
|
148
|
+
})
|
|
116
149
|
return (
|
|
117
150
|
<div>
|
|
118
|
-
<
|
|
119
|
-
<Modal ref={ref} open={open}/>
|
|
151
|
+
<Button onClick={copy} />
|
|
120
152
|
</div>
|
|
121
153
|
)
|
|
122
154
|
```
|
package/cjs/index.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.__esModule = true;
|
|
4
|
+
|
|
5
|
+
var _useOnClickOutside = require("./useOnClickOutside");
|
|
6
|
+
|
|
7
|
+
Object.keys(_useOnClickOutside).forEach(function (key) {
|
|
8
|
+
if (key === "default" || key === "__esModule") return;
|
|
9
|
+
if (key in exports && exports[key] === _useOnClickOutside[key]) return;
|
|
10
|
+
exports[key] = _useOnClickOutside[key];
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
var _useAuth = require("./useAuth");
|
|
14
|
+
|
|
15
|
+
Object.keys(_useAuth).forEach(function (key) {
|
|
16
|
+
if (key === "default" || key === "__esModule") return;
|
|
17
|
+
if (key in exports && exports[key] === _useAuth[key]) return;
|
|
18
|
+
exports[key] = _useAuth[key];
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
var _useFetch = require("./useFetch");
|
|
22
|
+
|
|
23
|
+
Object.keys(_useFetch).forEach(function (key) {
|
|
24
|
+
if (key === "default" || key === "__esModule") return;
|
|
25
|
+
if (key in exports && exports[key] === _useFetch[key]) return;
|
|
26
|
+
exports[key] = _useFetch[key];
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
var _useIntersectionObserver = require("./useIntersectionObserver");
|
|
30
|
+
|
|
31
|
+
Object.keys(_useIntersectionObserver).forEach(function (key) {
|
|
32
|
+
if (key === "default" || key === "__esModule") return;
|
|
33
|
+
if (key in exports && exports[key] === _useIntersectionObserver[key]) return;
|
|
34
|
+
exports[key] = _useIntersectionObserver[key];
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
var _useClipboardCopy = require("./useClipboardCopy");
|
|
38
|
+
|
|
39
|
+
Object.keys(_useClipboardCopy).forEach(function (key) {
|
|
40
|
+
if (key === "default" || key === "__esModule") return;
|
|
41
|
+
if (key in exports && exports[key] === _useClipboardCopy[key]) return;
|
|
42
|
+
exports[key] = _useClipboardCopy[key];
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
var _useKeyboardShortcut = require("./useKeyboardShortcut");
|
|
46
|
+
|
|
47
|
+
Object.keys(_useKeyboardShortcut).forEach(function (key) {
|
|
48
|
+
if (key === "default" || key === "__esModule") return;
|
|
49
|
+
if (key in exports && exports[key] === _useKeyboardShortcut[key]) return;
|
|
50
|
+
exports[key] = _useKeyboardShortcut[key];
|
|
51
|
+
});
|
|
52
|
+
//# sourceMappingURL=index.js.map
|
package/cjs/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/index.ts"],"sourcesContent":["export * from \"./useOnClickOutside\"\nexport * from \"./useAuth\"\nexport * from \"./useFetch\"\nexport * from \"./useIntersectionObserver\"\nexport * from \"./useClipboardCopy\"\nexport * from \"./useKeyboardShortcut\"\n"],"mappings":";;;;AAAA;;AAAA;EAAA;EAAA;EAAA;AAAA;;AACA;;AAAA;EAAA;EAAA;EAAA;AAAA;;AACA;;AAAA;EAAA;EAAA;EAAA;AAAA;;AACA;;AAAA;EAAA;EAAA;EAAA;AAAA;;AACA;;AAAA;EAAA;EAAA;EAAA;AAAA;;AACA;;AAAA;EAAA;EAAA;EAAA;AAAA"}
|
package/cjs/useAuth.js
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.__esModule = true;
|
|
4
|
+
exports.useAuth = exports.tokenStorageApiWithLocalStorage = exports.checkJwtExpiration = void 0;
|
|
5
|
+
|
|
6
|
+
var _react = require("react");
|
|
7
|
+
|
|
8
|
+
const checkJwtExpiration = jwt => {
|
|
9
|
+
const splitted = jwt.split(".");
|
|
10
|
+
if (splitted.length !== 3) return false;
|
|
11
|
+
const [, payload] = splitted;
|
|
12
|
+
const exp = JSON.parse(atob(payload))["exp"];
|
|
13
|
+
return new Date() < new Date(exp * 1000);
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
exports.checkJwtExpiration = checkJwtExpiration;
|
|
17
|
+
const tokenStorageApiWithLocalStorage = {
|
|
18
|
+
setToken: token => {
|
|
19
|
+
return localStorage.setItem("auth_token", token);
|
|
20
|
+
},
|
|
21
|
+
getToken: () => {
|
|
22
|
+
return localStorage.getItem("auth_token");
|
|
23
|
+
},
|
|
24
|
+
clearToken: () => {
|
|
25
|
+
localStorage.removeItem("auth_token");
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
exports.tokenStorageApiWithLocalStorage = tokenStorageApiWithLocalStorage;
|
|
29
|
+
let tokenCache = null;
|
|
30
|
+
|
|
31
|
+
const useAuth = option => {
|
|
32
|
+
const tokenStorageApi = option?.tokenStorageApi ?? tokenStorageApiWithLocalStorage;
|
|
33
|
+
const jwtExpirationChecker = option?.jwtExpirationChecker ?? checkJwtExpiration;
|
|
34
|
+
if (!tokenCache) tokenCache = tokenStorageApi.getToken();
|
|
35
|
+
const [token, setToken] = (0, _react.useState)(tokenCache || "");
|
|
36
|
+
const [authenticated, setAuthenticated] = (0, _react.useState)(!!tokenCache);
|
|
37
|
+
const tryCheckAuth = (0, _react.useCallback)(() => {
|
|
38
|
+
const authToken = tokenStorageApi.getToken();
|
|
39
|
+
|
|
40
|
+
if (!(authToken && jwtExpirationChecker(authToken))) {
|
|
41
|
+
tokenStorageApi.clearToken();
|
|
42
|
+
setToken("");
|
|
43
|
+
setAuthenticated(false);
|
|
44
|
+
tokenCache = null;
|
|
45
|
+
} else {
|
|
46
|
+
setToken(authToken);
|
|
47
|
+
setAuthenticated(true);
|
|
48
|
+
}
|
|
49
|
+
}, [jwtExpirationChecker, tokenStorageApi]);
|
|
50
|
+
(0, _react.useEffect)(() => {
|
|
51
|
+
tryCheckAuth();
|
|
52
|
+
}, [tryCheckAuth]);
|
|
53
|
+
const signin = (0, _react.useCallback)(token => {
|
|
54
|
+
tokenStorageApi.setToken(token);
|
|
55
|
+
tryCheckAuth();
|
|
56
|
+
}, [tokenStorageApi, tryCheckAuth]);
|
|
57
|
+
const signout = (0, _react.useCallback)(() => {
|
|
58
|
+
tokenStorageApi.clearToken();
|
|
59
|
+
tryCheckAuth();
|
|
60
|
+
}, [tokenStorageApi, tryCheckAuth]);
|
|
61
|
+
return {
|
|
62
|
+
token,
|
|
63
|
+
authenticated,
|
|
64
|
+
signin,
|
|
65
|
+
signout
|
|
66
|
+
};
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
exports.useAuth = useAuth;
|
|
70
|
+
//# sourceMappingURL=useAuth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useAuth.js","names":["checkJwtExpiration","jwt","splitted","split","length","payload","exp","JSON","parse","atob","Date","tokenStorageApiWithLocalStorage","setToken","token","localStorage","setItem","getToken","getItem","clearToken","removeItem","tokenCache","useAuth","option","tokenStorageApi","jwtExpirationChecker","useState","authenticated","setAuthenticated","tryCheckAuth","useCallback","authToken","useEffect","signin","signout"],"sources":["../../src/useAuth.ts"],"sourcesContent":["import { useCallback, useEffect, useState } from \"react\"\n\nexport const checkJwtExpiration = (jwt: string): boolean => {\n const splitted = jwt.split(\".\")\n if (splitted.length !== 3) return false\n\n const [, payload] = splitted\n const exp = JSON.parse(atob(payload))[\"exp\"]\n return new Date() < new Date(exp * 1000)\n}\n\nexport interface TokenStorageApi {\n setToken: (token: string) => void\n getToken: () => string | null\n clearToken: () => void\n}\n\nexport const tokenStorageApiWithLocalStorage: TokenStorageApi = {\n setToken: (token: string) => {\n return localStorage.setItem(\"auth_token\", token)\n },\n getToken: (): string | null => {\n return localStorage.getItem(\"auth_token\")\n },\n clearToken: () => {\n localStorage.removeItem(\"auth_token\")\n }\n}\n\nlet tokenCache: null | string = null\n\nexport interface UseAuthOption {\n jwtExpirationChecker?: (jwt: string) => boolean\n tokenStorageApi?: TokenStorageApi\n}\n\nexport interface UseAuthState {\n token: string\n authenticated: boolean\n signin: (token: string) => void\n signout: () => void\n}\n\nexport const useAuth = (option?: UseAuthOption): UseAuthState => {\n const tokenStorageApi = option?.tokenStorageApi ?? tokenStorageApiWithLocalStorage\n const jwtExpirationChecker = option?.jwtExpirationChecker ?? checkJwtExpiration\n\n if (!tokenCache) tokenCache = tokenStorageApi.getToken()\n const [token, setToken] = useState<string>(tokenCache || \"\")\n const [authenticated, setAuthenticated] = useState(!!tokenCache)\n\n const tryCheckAuth = useCallback(() => {\n const authToken = tokenStorageApi.getToken()\n if (!(authToken && jwtExpirationChecker(authToken))) {\n tokenStorageApi.clearToken()\n setToken(\"\")\n setAuthenticated(false)\n tokenCache = null\n } else {\n setToken(authToken)\n setAuthenticated(true)\n }\n }, [jwtExpirationChecker, tokenStorageApi])\n\n useEffect(() => {\n tryCheckAuth()\n }, [tryCheckAuth])\n\n const signin = useCallback(\n (token: string) => {\n tokenStorageApi.setToken(token)\n tryCheckAuth()\n },\n [tokenStorageApi, tryCheckAuth]\n )\n\n const signout = useCallback(() => {\n tokenStorageApi.clearToken()\n tryCheckAuth()\n }, [tokenStorageApi, tryCheckAuth])\n\n return {\n token,\n authenticated,\n signin,\n signout\n }\n}\n"],"mappings":";;;;;AAAA;;AAEO,MAAMA,kBAAkB,GAAIC,GAAD,IAA0B;EACxD,MAAMC,QAAQ,GAAGD,GAAG,CAACE,KAAJ,CAAU,GAAV,CAAjB;EACA,IAAID,QAAQ,CAACE,MAAT,KAAoB,CAAxB,EAA2B,OAAO,KAAP;EAE3B,MAAM,GAAGC,OAAH,IAAcH,QAApB;EACA,MAAMI,GAAG,GAAGC,IAAI,CAACC,KAAL,CAAWC,IAAI,CAACJ,OAAD,CAAf,EAA0B,KAA1B,CAAZ;EACA,OAAO,IAAIK,IAAJ,KAAa,IAAIA,IAAJ,CAASJ,GAAG,GAAG,IAAf,CAApB;AACH,CAPM;;;AAeA,MAAMK,+BAAgD,GAAG;EAC5DC,QAAQ,EAAGC,KAAD,IAAmB;IACzB,OAAOC,YAAY,CAACC,OAAb,CAAqB,YAArB,EAAmCF,KAAnC,CAAP;EACH,CAH2D;EAI5DG,QAAQ,EAAE,MAAqB;IAC3B,OAAOF,YAAY,CAACG,OAAb,CAAqB,YAArB,CAAP;EACH,CAN2D;EAO5DC,UAAU,EAAE,MAAM;IACdJ,YAAY,CAACK,UAAb,CAAwB,YAAxB;EACH;AAT2D,CAAzD;;AAYP,IAAIC,UAAyB,GAAG,IAAhC;;AAcO,MAAMC,OAAO,GAAIC,MAAD,IAA0C;EAC7D,MAAMC,eAAe,GAAGD,MAAM,EAAEC,eAAR,IAA2BZ,+BAAnD;EACA,MAAMa,oBAAoB,GAAGF,MAAM,EAAEE,oBAAR,IAAgCxB,kBAA7D;EAEA,IAAI,CAACoB,UAAL,EAAiBA,UAAU,GAAGG,eAAe,CAACP,QAAhB,EAAb;EACjB,MAAM,CAACH,KAAD,EAAQD,QAAR,IAAoB,IAAAa,eAAA,EAAiBL,UAAU,IAAI,EAA/B,CAA1B;EACA,MAAM,CAACM,aAAD,EAAgBC,gBAAhB,IAAoC,IAAAF,eAAA,EAAS,CAAC,CAACL,UAAX,CAA1C;EAEA,MAAMQ,YAAY,GAAG,IAAAC,kBAAA,EAAY,MAAM;IACnC,MAAMC,SAAS,GAAGP,eAAe,CAACP,QAAhB,EAAlB;;IACA,IAAI,EAAEc,SAAS,IAAIN,oBAAoB,CAACM,SAAD,CAAnC,CAAJ,EAAqD;MACjDP,eAAe,CAACL,UAAhB;MACAN,QAAQ,CAAC,EAAD,CAAR;MACAe,gBAAgB,CAAC,KAAD,CAAhB;MACAP,UAAU,GAAG,IAAb;IACH,CALD,MAKO;MACHR,QAAQ,CAACkB,SAAD,CAAR;MACAH,gBAAgB,CAAC,IAAD,CAAhB;IACH;EACJ,CAXoB,EAWlB,CAACH,oBAAD,EAAuBD,eAAvB,CAXkB,CAArB;EAaA,IAAAQ,gBAAA,EAAU,MAAM;IACZH,YAAY;EACf,CAFD,EAEG,CAACA,YAAD,CAFH;EAIA,MAAMI,MAAM,GAAG,IAAAH,kBAAA,EACVhB,KAAD,IAAmB;IACfU,eAAe,CAACX,QAAhB,CAAyBC,KAAzB;IACAe,YAAY;EACf,CAJU,EAKX,CAACL,eAAD,EAAkBK,YAAlB,CALW,CAAf;EAQA,MAAMK,OAAO,GAAG,IAAAJ,kBAAA,EAAY,MAAM;IAC9BN,eAAe,CAACL,UAAhB;IACAU,YAAY;EACf,CAHe,EAGb,CAACL,eAAD,EAAkBK,YAAlB,CAHa,CAAhB;EAKA,OAAO;IACHf,KADG;IAEHa,aAFG;IAGHM,MAHG;IAIHC;EAJG,CAAP;AAMH,CA5CM"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.__esModule = true;
|
|
4
|
+
exports.useClipboardCopy = void 0;
|
|
5
|
+
|
|
6
|
+
var _react = require("react");
|
|
7
|
+
|
|
8
|
+
var _useKeyboardShortcut = require("./useKeyboardShortcut");
|
|
9
|
+
|
|
10
|
+
const useClipboardCopy = options => {
|
|
11
|
+
const copy = (0, _react.useCallback)(async otherText => {
|
|
12
|
+
const copyText = otherText || options?.text;
|
|
13
|
+
|
|
14
|
+
if (copyText === undefined) {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const successed = await navigator?.clipboard?.writeText(copyText).then(() => true).catch(() => false);
|
|
19
|
+
|
|
20
|
+
if (successed) {
|
|
21
|
+
options?.onSuccess?.(copyText);
|
|
22
|
+
} else {
|
|
23
|
+
options?.onFailure?.(copyText);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return successed;
|
|
27
|
+
}, [options]);
|
|
28
|
+
(0, _useKeyboardShortcut.useKeyboardShortcut)(options?.key, copy);
|
|
29
|
+
return copy;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
exports.useClipboardCopy = useClipboardCopy;
|
|
33
|
+
//# sourceMappingURL=useClipboardCopy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useClipboardCopy.js","names":["useClipboardCopy","options","copy","useCallback","otherText","copyText","text","undefined","successed","navigator","clipboard","writeText","then","catch","onSuccess","onFailure","useKeyboardShortcut","key"],"sources":["../../src/useClipboardCopy.tsx"],"sourcesContent":["import { useCallback } from \"react\"\nimport { useKeyboardShortcut } from \"./useKeyboardShortcut\"\n\nexport const useClipboardCopy = (options?: {\n text?: string\n onSuccess?: (text: string) => void\n onFailure?: (text: string) => void\n key?: string\n}) => {\n const copy = useCallback(\n async (otherText?: string) => {\n const copyText = otherText || options?.text\n if (copyText === undefined) {\n return false\n }\n const successed = await navigator?.clipboard\n ?.writeText(copyText)\n .then(() => true)\n .catch(() => false)\n if (successed) {\n options?.onSuccess?.(copyText)\n } else {\n options?.onFailure?.(copyText)\n }\n return successed\n },\n [options]\n )\n\n useKeyboardShortcut(options?.key, copy)\n return copy\n}\n"],"mappings":";;;;;AAAA;;AACA;;AAEO,MAAMA,gBAAgB,GAAIC,OAAD,IAK1B;EACF,MAAMC,IAAI,GAAG,IAAAC,kBAAA,EACT,MAAOC,SAAP,IAA8B;IAC1B,MAAMC,QAAQ,GAAGD,SAAS,IAAIH,OAAO,EAAEK,IAAvC;;IACA,IAAID,QAAQ,KAAKE,SAAjB,EAA4B;MACxB,OAAO,KAAP;IACH;;IACD,MAAMC,SAAS,GAAG,MAAMC,SAAS,EAAEC,SAAX,EAClBC,SADkB,CACRN,QADQ,EAEnBO,IAFmB,CAEd,MAAM,IAFQ,EAGnBC,KAHmB,CAGb,MAAM,KAHO,CAAxB;;IAIA,IAAIL,SAAJ,EAAe;MACXP,OAAO,EAAEa,SAAT,GAAqBT,QAArB;IACH,CAFD,MAEO;MACHJ,OAAO,EAAEc,SAAT,GAAqBV,QAArB;IACH;;IACD,OAAOG,SAAP;EACH,CAhBQ,EAiBT,CAACP,OAAD,CAjBS,CAAb;EAoBA,IAAAe,wCAAA,EAAoBf,OAAO,EAAEgB,GAA7B,EAAkCf,IAAlC;EACA,OAAOA,IAAP;AACH,CA5BM"}
|
package/cjs/useFetch.js
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.__esModule = true;
|
|
4
|
+
exports.useFetch = exports.useAuthFetch = exports.useAuthBearerFetch = exports.fetcher = void 0;
|
|
5
|
+
|
|
6
|
+
var _react = require("react");
|
|
7
|
+
|
|
8
|
+
var _swr = _interopRequireWildcard(require("swr"));
|
|
9
|
+
|
|
10
|
+
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
11
|
+
|
|
12
|
+
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
13
|
+
|
|
14
|
+
const fetcher = async (url, options) => {
|
|
15
|
+
try {
|
|
16
|
+
return {
|
|
17
|
+
data: await fetcherThrows(url, options),
|
|
18
|
+
error: undefined
|
|
19
|
+
};
|
|
20
|
+
} catch (e) {
|
|
21
|
+
return {
|
|
22
|
+
data: undefined,
|
|
23
|
+
error: e
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
exports.fetcher = fetcher;
|
|
29
|
+
|
|
30
|
+
const fetcherThrows = async (url, options) => {
|
|
31
|
+
const obj = {};
|
|
32
|
+
|
|
33
|
+
if (options.token) {
|
|
34
|
+
const header = options.authTokenHeader ?? "X-Access-Token";
|
|
35
|
+
obj.headers = {
|
|
36
|
+
[header]: header === "Authorization" ? `Bearer ${options.token}` : options.token
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (options.method) {
|
|
41
|
+
obj.method = options.method || "GET";
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (options?.body) {
|
|
45
|
+
obj.body = options.body;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (obj.body && obj.method === "GET") {
|
|
49
|
+
throw new TypeError("The `GET` method cannot be used with a body");
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
obj.headers = {
|
|
53
|
+
"Content-Type": "application/json",
|
|
54
|
+
...(obj.headers ?? {})
|
|
55
|
+
};
|
|
56
|
+
const resp = await (options.fetch ?? fetch)(url, obj);
|
|
57
|
+
|
|
58
|
+
if (!resp.ok) {
|
|
59
|
+
throw new Error(`${resp.status}: ${await resp.text()}`);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const bodyText = await resp.text(); // responseが空の場合があるのでケアする
|
|
63
|
+
|
|
64
|
+
return bodyText && JSON.parse(bodyText);
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const useFetch = (url, options) => {
|
|
68
|
+
const key = (0, _react.useMemo)(() => url ? [url, options.token, options.body] : null, [options.body, options.token, url]);
|
|
69
|
+
const fetcherWrapper = (0, _react.useMemo)(() => options.fetch ?? ((url, token) => {
|
|
70
|
+
return fetcherThrows(url, {
|
|
71
|
+
method: options.method,
|
|
72
|
+
token,
|
|
73
|
+
body: options.body,
|
|
74
|
+
authTokenHeader: options.authTokenHeader
|
|
75
|
+
});
|
|
76
|
+
}), [options.authTokenHeader, options.body, options.fetch, options.method]);
|
|
77
|
+
const {
|
|
78
|
+
data,
|
|
79
|
+
error
|
|
80
|
+
} = (0, _swr.default)(key, fetcherWrapper, options.swrConfig);
|
|
81
|
+
const refetch = (0, _react.useCallback)(async () => {
|
|
82
|
+
if (key) {
|
|
83
|
+
await (0, _swr.mutate)(key);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return;
|
|
87
|
+
}, [key]);
|
|
88
|
+
return {
|
|
89
|
+
data,
|
|
90
|
+
error,
|
|
91
|
+
refetch
|
|
92
|
+
};
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
exports.useFetch = useFetch;
|
|
96
|
+
|
|
97
|
+
const useAuthFetch = (token, url, options) => {
|
|
98
|
+
const key = (0, _react.useMemo)(() => url && token ? [url, token, options.body] : null, [options.body, token, url]);
|
|
99
|
+
const fetcherWrapper = (0, _react.useMemo)(() => options.fetch ?? ((url, token) => {
|
|
100
|
+
return fetcherThrows(url, {
|
|
101
|
+
method: options.method,
|
|
102
|
+
token,
|
|
103
|
+
body: options.body,
|
|
104
|
+
authTokenHeader: options.authTokenHeader ?? "X-Access-Token"
|
|
105
|
+
});
|
|
106
|
+
}), [options.authTokenHeader, options.body, options.fetch, options.method]);
|
|
107
|
+
const {
|
|
108
|
+
data,
|
|
109
|
+
error
|
|
110
|
+
} = (0, _swr.default)(key, fetcherWrapper, options.swrConfig);
|
|
111
|
+
const refetch = (0, _react.useCallback)(async () => {
|
|
112
|
+
if (key) {
|
|
113
|
+
await (0, _swr.mutate)(key);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return;
|
|
117
|
+
}, [key]);
|
|
118
|
+
return {
|
|
119
|
+
data,
|
|
120
|
+
error,
|
|
121
|
+
refetch
|
|
122
|
+
};
|
|
123
|
+
}; // Authorization: Bearer [TOKEN]の形式でセットするuseAuthFetch
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
exports.useAuthFetch = useAuthFetch;
|
|
127
|
+
|
|
128
|
+
const useAuthBearerFetch = (token, url, options) => {
|
|
129
|
+
return useAuthFetch(token, url, { ...options,
|
|
130
|
+
authTokenHeader: "Authorization"
|
|
131
|
+
});
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
exports.useAuthBearerFetch = useAuthBearerFetch;
|
|
135
|
+
//# sourceMappingURL=useFetch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useFetch.js","names":["fetcher","url","options","data","fetcherThrows","error","undefined","e","obj","token","header","authTokenHeader","headers","method","body","TypeError","resp","fetch","ok","Error","status","text","bodyText","JSON","parse","useFetch","key","useMemo","fetcherWrapper","useSWR","swrConfig","refetch","useCallback","mutate","useAuthFetch","useAuthBearerFetch"],"sources":["../../src/useFetch.ts"],"sourcesContent":["import { useCallback, useMemo } from \"react\"\nimport useSWR, { mutate, SWRConfiguration } from \"swr\"\n\nexport interface FetcherResult<T> {\n data: T | undefined\n error: Error | undefined\n}\n\nexport type AuthTokenHeader = \"Authorization\" | \"X-Access-Token\"\n\nexport interface FetcherOptions {\n method?: \"GET\" | \"POST\" | \"PATCH\" | \"PUT\" | \"DELETE\" | \"OPTIONS\" | \"HEAD\"\n token?: string\n body?: string\n fetch?: (info: RequestInfo, init?: RequestInit) => Promise<Response>\n authTokenHeader?: AuthTokenHeader\n}\n\nexport const fetcher = async <T>(url: string, options: FetcherOptions): Promise<FetcherResult<T>> => {\n try {\n return { data: await fetcherThrows(url, options), error: undefined }\n } catch (e) {\n return { data: undefined, error: (e as unknown) as Error }\n }\n}\n\nconst fetcherThrows = async <T>(url: string, options: FetcherOptions): Promise<T> => {\n const obj: RequestInit = {}\n if (options.token) {\n const header = options.authTokenHeader ?? \"X-Access-Token\"\n\n obj.headers = {\n [header]: header === \"Authorization\" ? `Bearer ${options.token}` : options.token\n }\n }\n if (options.method) {\n obj.method = options.method || \"GET\"\n }\n\n if (options?.body) {\n obj.body = options.body\n }\n\n if (obj.body && obj.method === \"GET\") {\n throw new TypeError(\"The `GET` method cannot be used with a body\")\n }\n\n obj.headers = {\n \"Content-Type\": \"application/json\",\n ...(obj.headers ?? {})\n }\n\n const resp = await (options.fetch ?? fetch)(url, obj)\n\n if (!resp.ok) {\n throw new Error(`${resp.status}: ${await resp.text()}`)\n }\n\n const bodyText = await resp.text()\n // responseが空の場合があるのでケアする\n return bodyText && JSON.parse(bodyText)\n}\n\nexport interface UseFetchState<T> extends FetcherResult<T> {\n refetch: () => Promise<void>\n}\n\nexport const useFetch = <T>(\n url: string | null,\n options: Omit<FetcherOptions, \"fetch\"> & {\n fetch?: (url: string, token?: string) => Promise<T>\n swrConfig?: Partial<SWRConfiguration>\n authTokenHeader?: AuthTokenHeader\n }\n): UseFetchState<T> => {\n const key = useMemo(() => url ? [url, options.token, options.body] : null,[options.body, options.token, url])\n const fetcherWrapper = useMemo(\n () =>\n options.fetch ??\n ((url: string, token?: string) => {\n return fetcherThrows<T>(url, {\n method: options.method,\n token,\n body: options.body,\n authTokenHeader: options.authTokenHeader\n })\n }),\n [options.authTokenHeader, options.body, options.fetch, options.method]\n )\n\n const { data, error } = useSWR<T>(key, fetcherWrapper, options.swrConfig)\n const refetch = useCallback(async () => {\n if (key) {\n await mutate(key)\n }\n\n return\n }, [key])\n\n return {\n data,\n error,\n refetch\n }\n}\n\nexport const useAuthFetch = <T>(\n token: string,\n url: string | null,\n options: Omit<FetcherOptions, \"fetch\" | \"token\"> & {\n fetch?: (url: string, token?: string) => Promise<T>\n swrConfig?: Partial<SWRConfiguration>\n authTokenHeader?: AuthTokenHeader\n }\n): UseFetchState<T> => {\n const key = useMemo(() => url && token ? [url, token, options.body] : null,[options.body, token, url])\n const fetcherWrapper = useMemo(\n () =>\n options.fetch ??\n ((url: string, token?: string) => {\n return fetcherThrows<T>(url, {\n method: options.method,\n token,\n body: options.body,\n authTokenHeader: options.authTokenHeader ?? \"X-Access-Token\"\n })\n }),\n [options.authTokenHeader, options.body, options.fetch, options.method]\n )\n\n const { data, error } = useSWR<T>(key, fetcherWrapper, options.swrConfig)\n const refetch = useCallback(async () => {\n if (key) {\n await mutate(key)\n }\n\n return\n }, [key])\n\n return {\n data,\n error,\n refetch\n }\n}\n\n// Authorization: Bearer [TOKEN]の形式でセットするuseAuthFetch\nexport const useAuthBearerFetch = <T>(\n token: string,\n url: string | null,\n options: Omit<FetcherOptions, \"fetch\" | \"token\"> & {\n fetch?: (url: string, token?: string) => Promise<T>\n swrConfig?: Partial<SWRConfiguration>\n }\n): UseFetchState<T> => {\n return useAuthFetch(token, url, { ...options, authTokenHeader: \"Authorization\" })\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.__esModule = true;
|
|
4
|
+
exports.useIntersectionObserver = void 0;
|
|
5
|
+
|
|
6
|
+
var _isBrowser = require("./utils/isBrowser");
|
|
7
|
+
|
|
8
|
+
var _react = require("react");
|
|
9
|
+
|
|
10
|
+
/* eslint-disable react-hooks/rules-of-hooks */
|
|
11
|
+
const useIntersectionObserver = (ref, options = {}) => {
|
|
12
|
+
const [entry, setEntry] = (0, _react.useState)();
|
|
13
|
+
const observer = (0, _react.useRef)();
|
|
14
|
+
const disconnect = (0, _react.useCallback)(() => {
|
|
15
|
+
observer?.current?.disconnect();
|
|
16
|
+
}, []);
|
|
17
|
+
|
|
18
|
+
if (!_isBrowser.isBrowser) {
|
|
19
|
+
return {
|
|
20
|
+
entry,
|
|
21
|
+
disconnect
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
(0, _react.useEffect)(() => {
|
|
26
|
+
const element = ref && ref.current;
|
|
27
|
+
|
|
28
|
+
if (!element) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
observer.current = new IntersectionObserver(entries => {
|
|
33
|
+
if (!entries.length) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
setEntry(entries[0]);
|
|
38
|
+
}, options);
|
|
39
|
+
observer.current.observe(element);
|
|
40
|
+
return () => {
|
|
41
|
+
disconnect();
|
|
42
|
+
};
|
|
43
|
+
}, [disconnect, options, ref]);
|
|
44
|
+
return {
|
|
45
|
+
entry,
|
|
46
|
+
disconnect
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
exports.useIntersectionObserver = useIntersectionObserver;
|
|
51
|
+
//# sourceMappingURL=useIntersectionObserver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useIntersectionObserver.js","names":["useIntersectionObserver","ref","options","entry","setEntry","useState","observer","useRef","disconnect","useCallback","current","isBrowser","useEffect","element","IntersectionObserver","entries","length","observe"],"sources":["../../src/useIntersectionObserver.ts"],"sourcesContent":["/* eslint-disable react-hooks/rules-of-hooks */\nimport { isBrowser } from \"./utils/isBrowser\"\nimport { useCallback, useEffect, useRef, useState } from \"react\"\n\nexport const useIntersectionObserver = <E extends Element = HTMLElement>(\n ref: React.RefObject<E>,\n options: IntersectionObserverInit = {}\n) => {\n const [entry, setEntry] = useState<IntersectionObserverEntry>()\n const observer = useRef<IntersectionObserver>()\n const disconnect = useCallback(() => {\n observer?.current?.disconnect()\n }, [])\n if (!isBrowser) {\n return { entry, disconnect }\n }\n useEffect(() => {\n const element = ref && ref.current\n if (!element) {\n return\n }\n observer.current = new IntersectionObserver((entries) => {\n if (!entries.length) {\n return\n }\n setEntry(entries[0])\n }, options)\n\n observer.current.observe(element)\n return () => {\n disconnect()\n }\n }, [disconnect, options, ref])\n return {\n entry,\n disconnect\n }\n}\n"],"mappings":";;;;;AACA;;AACA;;AAFA;AAIO,MAAMA,uBAAuB,GAAG,CACnCC,GADmC,EAEnCC,OAAiC,GAAG,EAFD,KAGlC;EACD,MAAM,CAACC,KAAD,EAAQC,QAAR,IAAoB,IAAAC,eAAA,GAA1B;EACA,MAAMC,QAAQ,GAAG,IAAAC,aAAA,GAAjB;EACA,MAAMC,UAAU,GAAG,IAAAC,kBAAA,EAAY,MAAM;IACjCH,QAAQ,EAAEI,OAAV,EAAmBF,UAAnB;EACH,CAFkB,EAEhB,EAFgB,CAAnB;;EAGA,IAAI,CAACG,oBAAL,EAAgB;IACZ,OAAO;MAAER,KAAF;MAASK;IAAT,CAAP;EACH;;EACD,IAAAI,gBAAA,EAAU,MAAM;IACZ,MAAMC,OAAO,GAAGZ,GAAG,IAAIA,GAAG,CAACS,OAA3B;;IACA,IAAI,CAACG,OAAL,EAAc;MACV;IACH;;IACDP,QAAQ,CAACI,OAAT,GAAmB,IAAII,oBAAJ,CAA0BC,OAAD,IAAa;MACrD,IAAI,CAACA,OAAO,CAACC,MAAb,EAAqB;QACjB;MACH;;MACDZ,QAAQ,CAACW,OAAO,CAAC,CAAD,CAAR,CAAR;IACH,CALkB,EAKhBb,OALgB,CAAnB;IAOAI,QAAQ,CAACI,OAAT,CAAiBO,OAAjB,CAAyBJ,OAAzB;IACA,OAAO,MAAM;MACTL,UAAU;IACb,CAFD;EAGH,CAhBD,EAgBG,CAACA,UAAD,EAAaN,OAAb,EAAsBD,GAAtB,CAhBH;EAiBA,OAAO;IACHE,KADG;IAEHK;EAFG,CAAP;AAIH,CAjCM"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.__esModule = true;
|
|
4
|
+
exports.useKeyboardShortcut = void 0;
|
|
5
|
+
|
|
6
|
+
var _react = require("react");
|
|
7
|
+
|
|
8
|
+
const useKeyboardShortcut = (key, callback) => {
|
|
9
|
+
(0, _react.useEffect)(() => {
|
|
10
|
+
if (key === undefined || callback === undefined) {
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const handler = event => {
|
|
15
|
+
if ((event.ctrlKey || event.metaKey) && event.key === key) {
|
|
16
|
+
callback();
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
window.addEventListener("keydown", handler);
|
|
21
|
+
return () => {
|
|
22
|
+
window.removeEventListener("keydown", handler);
|
|
23
|
+
};
|
|
24
|
+
}, [key, callback]);
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
exports.useKeyboardShortcut = useKeyboardShortcut;
|
|
28
|
+
//# sourceMappingURL=useKeyboardShortcut.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useKeyboardShortcut.js","names":["useKeyboardShortcut","key","callback","useEffect","undefined","handler","event","ctrlKey","metaKey","window","addEventListener","removeEventListener"],"sources":["../../src/useKeyboardShortcut.ts"],"sourcesContent":["import { useEffect } from \"react\"\n\nexport const useKeyboardShortcut = (key?: string, callback?: () => void) => {\n useEffect(() => {\n if (key === undefined || callback === undefined) {\n return\n }\n const handler = (event: KeyboardEvent) => {\n if ((event.ctrlKey || event.metaKey) && event.key === key) {\n callback()\n }\n }\n window.addEventListener(\"keydown\", handler)\n return () => {\n window.removeEventListener(\"keydown\", handler)\n }\n }, [key, callback])\n}\n"],"mappings":";;;;;AAAA;;AAEO,MAAMA,mBAAmB,GAAG,CAACC,GAAD,EAAeC,QAAf,KAAyC;EACxE,IAAAC,gBAAA,EAAU,MAAM;IACZ,IAAIF,GAAG,KAAKG,SAAR,IAAqBF,QAAQ,KAAKE,SAAtC,EAAiD;MAC7C;IACH;;IACD,MAAMC,OAAO,GAAIC,KAAD,IAA0B;MACtC,IAAI,CAACA,KAAK,CAACC,OAAN,IAAiBD,KAAK,CAACE,OAAxB,KAAoCF,KAAK,CAACL,GAAN,KAAcA,GAAtD,EAA2D;QACvDC,QAAQ;MACX;IACJ,CAJD;;IAKAO,MAAM,CAACC,gBAAP,CAAwB,SAAxB,EAAmCL,OAAnC;IACA,OAAO,MAAM;MACTI,MAAM,CAACE,mBAAP,CAA2B,SAA3B,EAAsCN,OAAtC;IACH,CAFD;EAGH,CAbD,EAaG,CAACJ,GAAD,EAAMC,QAAN,CAbH;AAcH,CAfM"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.__esModule = true;
|
|
4
|
+
exports.useOnClickOutside = void 0;
|
|
5
|
+
|
|
6
|
+
var _isBrowser = require("./utils/isBrowser");
|
|
7
|
+
|
|
8
|
+
var _react = require("react");
|
|
9
|
+
|
|
10
|
+
const useOnClickOutside = (ref, handler) => {
|
|
11
|
+
if (!_isBrowser.isBrowser) {
|
|
12
|
+
return;
|
|
13
|
+
} // eslint-disable-next-line react-hooks/rules-of-hooks
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
(0, _react.useEffect)(() => {
|
|
17
|
+
if (!handler) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const listener = event => {
|
|
22
|
+
if (!ref.current || ref.current.contains(event.target)) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
handler(event);
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
document.addEventListener("mousedown", listener, {
|
|
30
|
+
passive: true
|
|
31
|
+
});
|
|
32
|
+
document.addEventListener("touchstart", listener, {
|
|
33
|
+
passive: true
|
|
34
|
+
});
|
|
35
|
+
return () => {
|
|
36
|
+
document.removeEventListener("mousedown", listener);
|
|
37
|
+
document.removeEventListener("touchstart", listener);
|
|
38
|
+
};
|
|
39
|
+
}, [handler, ref]);
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
exports.useOnClickOutside = useOnClickOutside;
|
|
43
|
+
//# sourceMappingURL=useOnClickOutside.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useOnClickOutside.js","names":["useOnClickOutside","ref","handler","isBrowser","useEffect","listener","event","current","contains","target","document","addEventListener","passive","removeEventListener"],"sources":["../../src/useOnClickOutside.ts"],"sourcesContent":["import { isBrowser } from \"./utils/isBrowser\"\nimport { useEffect } from \"react\"\n\nexport const useOnClickOutside = <E extends Element = HTMLElement>(\n ref: React.RefObject<E>,\n handler?: (event: MouseEvent | TouchEvent) => void\n) => {\n if (!isBrowser) {\n return\n }\n // eslint-disable-next-line react-hooks/rules-of-hooks\n useEffect(() => {\n if (!handler) {\n return\n }\n const listener = (event: MouseEvent | TouchEvent) => {\n if (!ref.current || ref.current.contains(event.target as Node)) {\n return\n }\n\n handler(event)\n }\n\n document.addEventListener(\"mousedown\", listener, { passive: true })\n document.addEventListener(\"touchstart\", listener, { passive: true })\n\n return () => {\n document.removeEventListener(\"mousedown\", listener)\n document.removeEventListener(\"touchstart\", listener)\n }\n }, [handler, ref])\n}\n"],"mappings":";;;;;AAAA;;AACA;;AAEO,MAAMA,iBAAiB,GAAG,CAC7BC,GAD6B,EAE7BC,OAF6B,KAG5B;EACD,IAAI,CAACC,oBAAL,EAAgB;IACZ;EACH,CAHA,CAID;;;EACA,IAAAC,gBAAA,EAAU,MAAM;IACZ,IAAI,CAACF,OAAL,EAAc;MACV;IACH;;IACD,MAAMG,QAAQ,GAAIC,KAAD,IAAoC;MACjD,IAAI,CAACL,GAAG,CAACM,OAAL,IAAgBN,GAAG,CAACM,OAAJ,CAAYC,QAAZ,CAAqBF,KAAK,CAACG,MAA3B,CAApB,EAAgE;QAC5D;MACH;;MAEDP,OAAO,CAACI,KAAD,CAAP;IACH,CAND;;IAQAI,QAAQ,CAACC,gBAAT,CAA0B,WAA1B,EAAuCN,QAAvC,EAAiD;MAAEO,OAAO,EAAE;IAAX,CAAjD;IACAF,QAAQ,CAACC,gBAAT,CAA0B,YAA1B,EAAwCN,QAAxC,EAAkD;MAAEO,OAAO,EAAE;IAAX,CAAlD;IAEA,OAAO,MAAM;MACTF,QAAQ,CAACG,mBAAT,CAA6B,WAA7B,EAA0CR,QAA1C;MACAK,QAAQ,CAACG,mBAAT,CAA6B,YAA7B,EAA2CR,QAA3C;IACH,CAHD;EAIH,CAnBD,EAmBG,CAACH,OAAD,EAAUD,GAAV,CAnBH;AAoBH,CA5BM"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"isBrowser.js","names":["isBrowser","window","document"],"sources":["../../../src/utils/isBrowser.ts"],"sourcesContent":["export const isBrowser =\n typeof window !== \"undefined\" && typeof document !== \"undefined\" && window.document === document\n"],"mappings":";;;;AAAO,MAAMA,SAAS,GAClB,OAAOC,MAAP,KAAkB,WAAlB,IAAiC,OAAOC,QAAP,KAAoB,WAArD,IAAoED,MAAM,CAACC,QAAP,KAAoBA,QADrF"}
|
package/esm/index.js
CHANGED