1 | import React from 'react';
|
2 | import { code, md, Example, Props } from '@atlaskit/docs';
|
3 | import SectionMessage from '@atlaskit/section-message';
|
4 |
|
5 | export default md`
|
6 | ${(
|
7 | <SectionMessage
|
8 | appearance="warning"
|
9 | title="Note: @atlaskit/layer-manager is deprecated."
|
10 | >
|
11 | {md`
|
12 | As of component versions:
|
13 |
|
14 | - \`@atlaskit/modal-dialog@7.0.0\`
|
15 | - \`@atlaskit/tooltip@12.0.2\`
|
16 | - \`@atlaskit/flag@9.0.6\`
|
17 | - \`@atlaskit/onboarding@6.0.0\`
|
18 |
|
19 | No component requires global coordination to layer correctly.
|
20 | All of these components are built using \`@atlaskit/portal\` which has full support for React Context.
|
21 | `}
|
22 | <p>
|
23 | If you are after a scroll lock component we recommend{' '}
|
24 | <a href="https://github.com/jossmac/react-scrolllock">
|
25 | react-scrolllock
|
26 | </a>
|
27 | , if you need a focus lock component check out{' '}
|
28 | <a href="https://github.com/theKashey/react-focus-lock">
|
29 | react-focus-lock
|
30 | </a>
|
31 | .
|
32 | </p>
|
33 | </SectionMessage>
|
34 | )}
|
35 |
|
36 | ## Why?
|
37 | The layer manager is used to render React DOM into a new context (aka "Portal").
|
38 | This can be used to implement various UI components such as modals.
|
39 |
|
40 | The impetus for creating this package was the constant war with z-indexes.
|
41 | When you wrap your app in a \`<LayerManager />\` it will create slots for each
|
42 | package that is supported, and portal each instance to the correct slot when
|
43 | rendered inside your react app.
|
44 |
|
45 | ## Usage
|
46 | Super simple to use, just wrap your app with the default export -- we'll listen
|
47 | to the context it broadcasts, and inject your components where they belong.
|
48 |
|
49 | ${code`
|
50 | import LayerManager from '@atlaskit/layer-manager';
|
51 |
|
52 | export default class App extends Component {
|
53 | render() {
|
54 | return (
|
55 | <LayerManager>
|
56 | ...
|
57 | </LayerManager>
|
58 | );
|
59 | }
|
60 | }
|
61 | `}
|
62 |
|
63 | ${(
|
64 | <Example
|
65 | packageName="@atlaskit/layer-manager"
|
66 | Component={require('../examples/0-basic').default}
|
67 | source={require('!!raw-loader!../examples/0-basic')}
|
68 | title="Supported Components"
|
69 | />
|
70 | )}
|
71 |
|
72 | ## Focus Lock
|
73 |
|
74 | This component is used to trap focus inside an area of the screen. The main use
|
75 | case for this FocusLock component is to keep focus inside modal dialogs.
|
76 |
|
77 | ${(
|
78 | <Example
|
79 | packageName="@atlaskit/layer-manager"
|
80 | Component={require('../examples/2-focus-lock').default}
|
81 | source={require('!!raw-loader!../examples/2-focus-lock')}
|
82 | title="Focus Lock"
|
83 | />
|
84 | )}
|
85 |
|
86 | ${(
|
87 | <Props
|
88 | heading="Focus Lock Props"
|
89 | props={{
|
90 | kind: 'program',
|
91 | component: {
|
92 | kind: 'generic',
|
93 | value: {
|
94 | kind: 'object',
|
95 | members: [
|
96 | {
|
97 | kind: 'property',
|
98 | key: { kind: 'id', name: 'ariaHiddenNode' },
|
99 | value: {
|
100 | kind: 'generic',
|
101 | value: { kind: 'id', name: 'HTMLElement' },
|
102 | },
|
103 | optional: true,
|
104 | leadingComments: [
|
105 | {
|
106 | type: 'commentBlock',
|
107 | value:
|
108 | 'DOM Element to apply `aria-hidden=true` to when this component gains focus.\nThis is provided via context when used within @atlaskit/layer-manager.',
|
109 | raw:
|
110 | '*\n DOM Element to apply `aria-hidden=true` to when this component gains focus.\n This is provided via context when used within @atlaskit/layer-manager.\n ',
|
111 | },
|
112 | ],
|
113 | },
|
114 | {
|
115 | kind: 'property',
|
116 | key: { kind: 'id', name: 'autoFocus' },
|
117 | value: {
|
118 | kind: 'union',
|
119 | types: [
|
120 | { kind: 'boolean' },
|
121 | {
|
122 | parameters: [],
|
123 | returnType: {
|
124 | kind: 'union',
|
125 | types: [
|
126 | {
|
127 | kind: 'generic',
|
128 | value: { kind: 'id', name: 'HTMLElement' },
|
129 | },
|
130 | { kind: 'null' },
|
131 | ],
|
132 | },
|
133 | kind: 'function',
|
134 | },
|
135 | ],
|
136 | },
|
137 | optional: false,
|
138 | leadingComments: [
|
139 | {
|
140 | type: 'commentBlock',
|
141 | value:
|
142 | 'Boolean indicating whether to focus on the first tabbable element inside the focus lock.',
|
143 | raw:
|
144 | '*\n Boolean indicating whether to focus on the first tabbable element inside the focus lock.\n ',
|
145 | },
|
146 | ],
|
147 | default: { kind: 'boolean', value: true },
|
148 | },
|
149 | {
|
150 | kind: 'property',
|
151 | key: { kind: 'id', name: 'children' },
|
152 | value: {
|
153 | kind: 'generic',
|
154 | value: {
|
155 | kind: 'import',
|
156 | importKind: 'type',
|
157 | name: 'Node',
|
158 | moduleSpecifier: 'react',
|
159 | referenceIdName: 'Node',
|
160 | },
|
161 | },
|
162 | optional: true,
|
163 | leadingComments: [
|
164 | {
|
165 | type: 'commentBlock',
|
166 | value: 'Content inside the focus lock.',
|
167 | raw: '*\n Content inside the focus lock.\n ',
|
168 | },
|
169 | ],
|
170 | },
|
171 | {
|
172 | kind: 'property',
|
173 | key: { kind: 'id', name: 'enabled' },
|
174 | value: { kind: 'boolean' },
|
175 | optional: false,
|
176 | leadingComments: [
|
177 | {
|
178 | type: 'commentBlock',
|
179 | value: 'Whether the focus lock is active or not.',
|
180 | raw: '*\n Whether the focus lock is active or not.\n ',
|
181 | },
|
182 | ],
|
183 | default: { kind: 'boolean', value: true },
|
184 | },
|
185 | {
|
186 | kind: 'property',
|
187 | key: { kind: 'id', name: 'returnFocus' },
|
188 | value: { kind: 'boolean' },
|
189 | optional: false,
|
190 | leadingComments: [
|
191 | {
|
192 | type: 'commentBlock',
|
193 | value:
|
194 | 'Whether to return the focus to the previous active element.',
|
195 | raw:
|
196 | '*\n Whether to return the focus to the previous active element.\n ',
|
197 | },
|
198 | ],
|
199 | default: { kind: 'boolean', value: true },
|
200 | },
|
201 | ],
|
202 | trailingComments: [
|
203 | {
|
204 | type: 'commentBlock',
|
205 | value: 'eslint-disable react/sort-comp',
|
206 | raw: ' eslint-disable react/sort-comp ',
|
207 | },
|
208 | ],
|
209 | referenceIdName: 'Props',
|
210 | },
|
211 | name: { kind: 'id', name: 'FocusLock', type: null },
|
212 | },
|
213 | }}
|
214 | />
|
215 | )}
|
216 |
|
217 | ### Auto focusing an element
|
218 |
|
219 | There are a couple of options to focus an element that is not focused by default.
|
220 | The first is to use the autoFocus attribute on React dom elements. In the example below,
|
221 | 'button one' is the default but 'button two' will have focus.
|
222 |
|
223 | ${code`
|
224 | const App = () => (
|
225 | <FocusLock>
|
226 | <button>button one</button>
|
227 | <button autoFocus>button two</button>
|
228 | </FocusLock>
|
229 | )
|
230 | `}
|
231 |
|
232 | The other option is to attach a ref to the dom element and imperatively call \`focus()\`.
|
233 | This technique is described in [this section](https://reactjs.org/docs/refs-and-the-dom.html#adding-a-ref-to-a-dom-element)
|
234 | of the React documentation.
|
235 |
|
236 | ## Scroll Lock
|
237 |
|
238 | Component used to lock scroll positioning.
|
239 |
|
240 | ${(
|
241 | <React.Fragment>
|
242 | <SectionMessage appearance="warning">
|
243 | <p>
|
244 | <strong>ScrollLock is deprecated.</strong>
|
245 | </p>
|
246 | <p>
|
247 | Please use{' '}
|
248 | <a href="https://github.com/jossmac/react-scrolllock">
|
249 | react-scrolllock
|
250 | </a>{' '}
|
251 | instead.
|
252 | </p>
|
253 | </SectionMessage>
|
254 | <Example
|
255 | packageName="@atlaskit/layer-manager"
|
256 | Component={require('../examples/1-scroll-lock').default}
|
257 | source={require('!!raw-loader!../examples/1-scroll-lock')}
|
258 | title="Scroll Lock - DEPRECATED"
|
259 | />
|
260 | </React.Fragment>
|
261 | )}
|
262 |
|
263 | ## Other Helpers
|
264 |
|
265 | There are a few patterns that are common among the supported packages, and have
|
266 | been abstracted into discrete components. While primarily for use internally,
|
267 | they're available as named exports from \`@atlaskit/layer-manager\`.
|
268 |
|
269 | ${(
|
270 | <Example
|
271 | packageName="@atlaskit/layer-manager"
|
272 | Component={require('../examples/3-with-context').default}
|
273 | source={require('!!raw-loader!../examples/3-with-context')}
|
274 | title="With Context from Props"
|
275 | />
|
276 | )}
|
277 |
|
278 | ${(
|
279 | <Props
|
280 | heading="LayerManager Props"
|
281 | props={{
|
282 | kind: 'program',
|
283 | component: {
|
284 | kind: 'generic',
|
285 | value: {
|
286 | kind: 'object',
|
287 | members: [
|
288 | {
|
289 | kind: 'property',
|
290 | key: { kind: 'id', name: 'children' },
|
291 | value: {
|
292 | kind: 'generic',
|
293 | value: {
|
294 | kind: 'import',
|
295 | importKind: 'type',
|
296 | name: 'Node',
|
297 | moduleSpecifier: 'react',
|
298 | referenceIdName: 'Node',
|
299 | },
|
300 | },
|
301 | optional: false,
|
302 | },
|
303 | ],
|
304 | referenceIdName: 'Props',
|
305 | },
|
306 | name: { kind: 'id', name: 'LayerManager', type: null },
|
307 | },
|
308 | }}
|
309 | />
|
310 | )}
|
311 | `;
|
312 |
|
\ | No newline at end of file |