Skip to content
This repository was archived by the owner on Jun 20, 2022. It is now read-only.

Commit e37c708

Browse files
authored
feat: make modals accessible (#65)
Closes #31 Closes #26 Closes #25 BREAKING CHANGE: "persistent" prop has been removed from Modal, Modal are now non-persistent. "sui-modal-backdrop" has been removed, it is now "sui-modal".
1 parent 6b0767c commit e37c708

File tree

15 files changed

+312
-133
lines changed

15 files changed

+312
-133
lines changed

β€Ždocs/components/Modal.mdxβ€Ž

Lines changed: 65 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { PropsTable, Playground } from 'docz'
77
import { BlockList, PropDesc, getSystemPropDesc } from '@docs/utils'
88
import {
99
Modal,
10+
ModalCloseButton,
1011
ModalBody,
1112
ModalContent,
1213
ModalDialog,
@@ -25,6 +26,7 @@ Below is a static modal example (meaning its `position` and `display` have been
2526
<Playground>
2627
<ModalDialogExample>
2728
<ModalContent>
29+
<ModalCloseButton />
2830
<ModalHeader>
2931
<Typography variant="h5" m={0}>
3032
Modal title
@@ -53,6 +55,7 @@ You can toggle a modal from a `Button` using the `Toggler`.
5355
<Modal opened={toggled} onClose={() => onToggle(false)}>
5456
<ModalDialog>
5557
<ModalContent>
58+
<ModalCloseButton />
5659
<ModalHeader>
5760
<Typography variant="h5" m={0}>
5861
Modal title
@@ -73,6 +76,57 @@ You can toggle a modal from a `Button` using the `Toggler`.
7376
</Toggler>
7477
</Playground>
7578

79+
## Initial focus
80+
81+
Modal will focus the first focusable node by default, but you can specify a custom one using `initialFocusRef`.
82+
83+
In this example, the close button in `ModalFooter` will be focused instead of the `ModalCloseButton`.
84+
85+
<Playground>
86+
{() => {
87+
class App extends React.Component {
88+
constructor(props) {
89+
super(props)
90+
this.buttonRef = React.createRef()
91+
this.state = { showDialog: false }
92+
this.open = () => this.setState({ showDialog: true })
93+
this.close = () => this.setState({ showDialog: false })
94+
}
95+
96+
render() {
97+
return (
98+
<div>
99+
<Button variant="primary" onClick={this.open}>
100+
Open modal
101+
</Button>
102+
<Modal opened={this.state.showDialog} initialFocusRef={this.buttonRef} onClose={this.close}>
103+
<ModalDialog>
104+
<ModalContent>
105+
<ModalCloseButton />
106+
<ModalHeader>
107+
<Typography variant="h5" m={0}>
108+
Modal title
109+
</Typography>
110+
</ModalHeader>
111+
<ModalBody>Modal body</ModalBody>
112+
<ModalFooter>
113+
<Button variant="primary">Save changes</Button>
114+
<Button ref={this.buttonRef} variant="secondary" onClick={this.close}>
115+
Close
116+
</Button>
117+
</ModalFooter>
118+
</ModalContent>
119+
</ModalDialog>
120+
</Modal>
121+
</div>
122+
)
123+
}
124+
}
125+
126+
return <App />
127+
}}
128+
</Playground>
129+
76130
## Scrolling long content
77131

78132
When modals become too long for the user’s viewport or device, they scroll independent of the page itself. Try the demo below to see what we mean.
@@ -157,53 +211,6 @@ When modals become too long for the user’s viewport or device, they scroll ind
157211
</Toggler>
158212
</Playground>
159213

160-
## Persistent
161-
162-
Set `persistent` to `true` to keep the modal mounted even if closed.
163-
164-
<Playground>
165-
<BlockList>
166-
<Toggler>
167-
{({ toggled, onToggle }) => (
168-
<div>
169-
<Button variant="primary" onClick={() => onToggle(true)}>
170-
Open non-persistent
171-
</Button>
172-
<Modal persistent={false} opened={toggled} onClose={() => onToggle(false)}>
173-
<ModalDialog>
174-
<ModalContent>
175-
<ModalBody>
176-
Counter is resetted each time you open it <br />
177-
<Counter />
178-
</ModalBody>
179-
</ModalContent>
180-
</ModalDialog>
181-
</Modal>
182-
</div>
183-
)}
184-
</Toggler>
185-
<Toggler>
186-
{({ toggled, onToggle }) => (
187-
<div>
188-
<Button variant="primary" onClick={() => onToggle(true)}>
189-
Open persistent modal (default)
190-
</Button>
191-
<Modal opened={toggled} onClose={() => onToggle(false)}>
192-
<ModalDialog>
193-
<ModalContent>
194-
<ModalBody>
195-
Counter continue in background <br />
196-
<Counter />
197-
</ModalBody>
198-
</ModalContent>
199-
</ModalDialog>
200-
</Modal>
201-
</div>
202-
)}
203-
</Toggler>
204-
</BlockList>
205-
</Playground>
206-
207214

208215
## API
209216

@@ -214,7 +221,7 @@ Set `persistent` to `true` to keep the modal mounted even if closed.
214221
children: PropDesc.node,
215222
onClose: PropDesc.func,
216223
opened: PropDesc.bool,
217-
persistent: PropDesc.bool.defaultTo(true).desc('Set "persistent" to `true` to keep modal mounted when closed'),
224+
initialFocusRef: PropDesc.object,
218225
...getSystemPropDesc(Modal),
219226
})}
220227
/>
@@ -264,3 +271,13 @@ Set `persistent` to `true` to keep the modal mounted even if closed.
264271
...getSystemPropDesc(ModalHeader),
265272
})}
266273
/>
274+
275+
### ModalCloseButton
276+
277+
<PropsTable
278+
of={PropDesc({
279+
children: PropDesc.node,
280+
...getSystemPropDesc(ModalCloseButton),
281+
})}
282+
/>
283+

β€Ždocs/utils/PropDesc.jsβ€Ž

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ const string = type('string')
4848
const number = type('number')
4949
const bool = type('boolean')
5050
const func = type('function')
51+
const object = type('object')
5152
const array = type('array')
5253
const shape = types =>
5354
type('shape', {
@@ -69,5 +70,6 @@ PropDesc.array = array
6970
PropDesc.oneOf = oneOf
7071
PropDesc.oneOfType = oneOfType
7172
PropDesc.shape = shape
73+
PropDesc.object = object
7274

7375
export default PropDesc

β€Žpackages/core-em/package.jsonβ€Ž

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
"access": "public"
2727
},
2828
"dependencies": {
29+
"focus-trap": "^3.0.0",
2930
"polished": "^2.2.0",
3031
"prop-types": "^15.6.2",
3132
"react-transition-group": "^2.5.0"

β€Žpackages/core-sc/package.jsonβ€Ž

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
"access": "public"
2626
},
2727
"dependencies": {
28+
"focus-trap": "^3.0.0",
2829
"polished": "^2.2.0",
2930
"prop-types": "^15.6.2",
3031
"react-transition-group": "^2.5.0"

0 commit comments

Comments
Β (0)