Skip to content
This repository was archived by the owner on Mar 4, 2020. It is now read-only.
Merged
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm

## [Unreleased]

### BREAKING CHANGES
- Add `trapFocus` and `autoFocus` props to `Popup` and remove `popupFocusTrapBehavior` and `popupAutoFocusBehavior` @sophieH29 ([#1565](https://github.com/stardust-ui/react/pull/1565))

<!--------------------------------[ v0.34.1 ]------------------------------- -->
## [v0.34.1](https://github.com/stardust-ui/react/tree/v0.34.1) (2019-07-11)
[Compare changes](https://github.com/stardust-ui/react/compare/v0.34.0...v0.34.1)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import * as React from 'react'
import { Button, Flex, Input, Header, Popup, popupFocusTrapBehavior } from '@stardust-ui/react'
import { Button, Flex, Input, Header, Popup } from '@stardust-ui/react'

const PopupFocusTrapExample = () => (
<Flex gap="gap.smaller">
<Popup
/** Provided behavior introduces focus trap to popup content. */
accessibility={popupFocusTrapBehavior}
/** Provided prop introduces focus trap to popup content. */
trapFocus
trigger={<Button icon="expand" content="Trap focus on appearence" />}
content={{
content: (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as React from 'react'
import { Button, Flex, Popup, popupFocusTrapBehavior } from '@stardust-ui/react'
import { Button, Flex, Popup } from '@stardust-ui/react'

const contentWithButtons = {
content: (
Expand All @@ -15,19 +15,19 @@ const PopupExampleOnWithFocusTrap = () => (
<Popup
trigger={<Button icon="expand" content="Click" aria-label="Click button" />}
content={contentWithButtons}
accessibility={popupFocusTrapBehavior}
trapFocus
on="click"
/>
<Popup
trigger={<Button icon="expand" content="Hover" aria-label="Hover button" />}
content={contentWithButtons}
accessibility={popupFocusTrapBehavior}
trapFocus
on="hover"
/>
<Popup
trigger={<Button icon="expand" content="Focus" aria-label="Focus button" />}
content={contentWithButtons}
accessibility={popupFocusTrapBehavior}
trapFocus
on="focus"
/>
</Flex>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class PortalExampleFocusTrapped extends React.Component {
elementToFocusOnDismiss: null,
// Indicates whether to force focus inside a Portal, if the 'focus' event was invoked at any place.
// 'false' by default.
forceFocusInsideTrap: false,
forceFocusInsideTrapOnOutsideFocus: false,
// Ignore focusing element which activated Portal after it was closed.
// 'false' by default.
ignoreExternalFocusing: false,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as React from 'react'
import keyboardKey from 'keyboard-key'
import { Popup, Menu, Reaction, ReactionProps, popupAutoFocusBehavior } from '@stardust-ui/react'
import { Popup, Menu, Reaction, ReactionProps } from '@stardust-ui/react'

const getAriaLabel = ({ content: numberOfPersons, icon: emojiType }: ReactionProps) => {
if (numberOfPersons === 1) {
Expand All @@ -27,6 +27,7 @@ class ReactionPopup extends React.Component<ReactionProps, { open: boolean }> {
render() {
return (
<Popup
autoFocus
trigger={
<Reaction
as="button"
Expand All @@ -47,7 +48,6 @@ class ReactionPopup extends React.Component<ReactionProps, { open: boolean }> {
on="hover"
open={this.state.open}
onOpenChange={this.handleOpenChange}
accessibility={popupAutoFocusBehavior}
/>
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import {
Popup,
Button,
Menu,
popupFocusTrapBehavior,
AvatarProps,
ChatMessageProps,
DividerProps,
Expand Down Expand Up @@ -127,7 +126,7 @@ function createMessageContentWithAttachments(content: string, messageId: string)

const actionPopup = (
<Popup
accessibility={popupFocusTrapBehavior}
trapFocus
trigger={
<Button
aria-label="More attachment options"
Expand Down
13 changes: 7 additions & 6 deletions docs/src/views/Accessibility.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -326,17 +326,18 @@ export default () => (

<Header as="h3" content="Focus Trap Zone" />
<p>
FocusTrapZone is used to trap the focus in any html element. Pressing TAB key will circle
focus within the inner focusable elements of the FocusTrapZone. For example, when Popup opens,
we want the focus go inside Popup and trap there.{' '}
FocusTrapZone is used to grab and trap the focus inside an HTML element. Currently can be used
only in {code('Popup')} and {code('Dialog')} components. Pressing TAB key will circle focus
within the inner focusable elements of the FocusTrapZone. For example, when Popup opens, we
want the focus to go inside Popup and trap there.{' '}
{link('Read more about FocusTrapZone.', '/focus-trap-zone')}
</p>

<Header as="h3" content="Auto Focus Zone" />
<p>
AutoFocusZone is used to focus inner element on mount. For example, when we want to focus
inner element in Popup when it mounts, but still without focus trap.{' '}
{link('Read more about AutoFocusZone.', '/auto-focus-zone')}
AutoFocusZone is used to focus inner element on mount. Currently can be used in{' '}
{code('Popup')}. For example, when we want to focus inner element in Popup when it mounts, but
still without focus trap. {link('Read more about AutoFocusZone.', '/auto-focus-zone')}
</p>

<Header as="h3" content="Focus indicator" />
Expand Down
16 changes: 0 additions & 16 deletions docs/src/views/AccessibilityBehaviors.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,20 +59,6 @@ export default () => (
<Link to="focus-zone">Read more about FocusZone.</Link>
<p>Type: {code('{ mode: FocusZoneMode, props?: FocusZoneProps }')}.</p>
</li>
<li>
<b>focusTrap</b> - {code('FocusTrapZone')} grabs the focus and traps it within an HTML
element, usually a dialog or popup.{' '}
<Link to="focus-trap-zone">Read more about FocusTrapZone.</Link>
<p>Type: {code('FocusTrapZoneProps | boolean')}.</p>
</li>
<li>
<b>autoFocus</b> - {code('AutoFocusZone')} is used to grab focus and put it to inner
element when component mounts. For example, when it is needed to focus an inner element in
the Popup when it mounts. If true, it is enabled with default properties or can be
modified by setting object.{' '}
<Link to="auto-focus-zone">Read more about AutoFocusZone.</Link>
<p>Type: {code('AutoFocusZoneProps | boolean')}.</p>
</li>
<li>
<b>childBehaviors</b> - {code('{ [childBehaviorSlot: string]: Accessibility }')} are used
for components such as {code('Menu')} that contain children which, in turn, require their
Expand Down Expand Up @@ -214,8 +200,6 @@ export default () => (
},
},
focusZone: {},
focusTrap: {},
autoFocus: {},
})
`}
/>
Expand Down
45 changes: 14 additions & 31 deletions docs/src/views/AutoFocusZone.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,25 +16,24 @@ export default () => (
</ul>
<Header as="h2">Overview</Header>
<p>
{code('AutoFocusZone')} can wrap a component and is used to grab focus and put it to an inner
element when the component mounts. For example, when it is needed to focus an inner element in
the Popup when it mounts.
{code('AutoFocusZone')} can be integrated into {code('Popup')} component and is used to grab
focus and put it to an inner element when the component mounts. This can be achieved by
specifying {code('autoFocus')} prop on the {code('Popup')}.
</p>
<p>
If you need both - grabbing the focus and trap the focus in the component - use{' '}
<Link to="focus-trap-zone">FocusTrapZone</Link>.
{code('trapFocus')} prop for {code('Popup')}
to integrate <Link to="focus-trap-zone">FocusTrapZone</Link>.
</p>
<Header as="h2">Usage</Header>
<p>
In Stardust, {code('AutoFocusZone')} is applied through accessibility behavior, as for{' '}
{code('FocusZone')} and
{code('FocusTrapZone')}. To enable auto focus for a component, in the behavior set prop{' '}
{code('autoFocus')} to {code('true')}
with default settings or set an object with desired values for auto focus zone props.{' '}
<Link to="accessibility-behaviors">Read more about Accessibility Behaviors.</Link>
In {code('Popup')}, set {code('autoFocus')} to {code('true')} with default settings or set an
object with desired values for auto focus zone props.
</p>
<p>By default, focus will be set to the first tabbable element in the Popup:</p>
<CodeSnippet label="PopupExample.jsx" value={`const Example = () => <Popup autoFocus />`} />
<p>
{code('AutoFocusZone')}'s props which can be applied in accessibility behavior (
{code('AutoFocusZone')}'s props which can be applied to {code('autoFocus')} prop (
{link(
'lookup for API on GitHub',
'https://github.com/stardust-ui/react/blob/master/packages/react/src/lib/accessibility/AutoFocusZone/AutoFocusZone.types.tsx',
Expand All @@ -44,31 +43,15 @@ export default () => (
<ComponentPropsTable componentName="AutoFocusZone" />
<Header as="h2">Override {code('AutoFocusZone')} settings</Header>
<p>
To be able to add/override {code('AutoFocusZone')} props already set for a component, it is
needed to override or create a new accessibility behavior.
For example, we want to specify the focusable selector for Popup with auto focus. On Popup
mount, focus will go to the element matched to that selector. For that purpose, we can specify{' '}
{code('firstFocusableSelector')}.
</p>
<p>
For example, we want to specify the focusable selector for Popup with auto focus, so on Popup
mount, focus will go to the element matched to that selector. For that purpose, we can to
override {code('popupAutoFocusBehavior')} and specify {code('firstFocusableSelector')} there.
</p>
<CodeSnippet
value={`
const overridenAutoFocusBehavior: Accessibility = (props: any) => {
const behavior = popupFocusTrapBehavior(props)

behavior.autoFocus.firstFocusableSelector = ".btn-submit";

return behavior
}
`}
/>
And then use this new behavior by Popup component:
<CodeSnippet
label="PopupExample.jsx"
value={`
const Popup = () => (
<Popup accessibility={overridenAutoFocusBehavior} />
<Popup autoFocus={{ firstFocusableSelector: "btn-submit" }} />
)`}
/>
<p>Read more about:</p>
Expand Down
53 changes: 24 additions & 29 deletions docs/src/views/FocusTrapZone.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,12 @@ export default () => (
</ul>
<Header as="h2">Overview</Header>
<p>
{code('FocusTrapZone')} grabs the focus and traps it within an HTML element, usually a dialog
or popup. Pressing {code('TAB')} key will circle focus within the inner focusable elements of
the {code('FocusTrapZone')}. The main purpose is to block user interaction outside{' '}
{code('FocusTrapZone')}
in any way. Therefore, keyboard events are not propagated outside {code('FocusTrapZone')}.
{code('FocusTrapZone')} grabs the focus and traps it within an HTML element. Currently can be
used only in {code('Popup')}
and {code('Dialog')} components. Pressing {code('TAB')} key will circle focus within the inner
focusable elements of the {code('FocusTrapZone')}. The main purpose is to block user
interaction outside {code('FocusTrapZone')} in any way. Therefore, keyboard events are not
propagated outside {code('FocusTrapZone')}, hence {code('Popup')} or {code('Dialog')}.
</p>
<p>
Stardust leverages Focus Trap Zone component which is based on the{' '}
Expand All @@ -32,16 +33,18 @@ export default () => (
</p>
<Header as="h2">Usage</Header>
<p>
Stardust applies focus trap via accessibility behavior, the same way as it's done for{' '}
<Link to="focus-zone">FocusZone</Link>. To enable focus trap for component, it is needed, in
behavior, to set prop {code('trapFocus')} to
To apply {code('FocusTrapZone')} to {code('Popup')} set prop {code('trapFocus')} to
{code('true')} with default settings or set an object with desired values for focus trap zone
props. <Link to="accessibility-behaviors">Read more about Accessibility Behaviors.</Link>{' '}
Currently, it is used for Popup via {code('popupFocusTrapBehavior')} and Dialog via{' '}
{code('dialogBehavior')}.
props.
</p>
<CodeSnippet label="PopupExample.jsx" value={`const Example = () => <Popup trapFocus />`} />
<p>
{code('FocusTrapZone')}'s props which can be applied in accessibility behavior (
{code('Dialog')} component has always set {code('trapFocus')} prop to {code('true')}, but it
is also possible to override default settings by specifying object of{' '}
{code('FocusTrapZoneProps')}.
</p>
<p>
{code('FocusTrapZone')}'s props which can be applied to {code('trapFocus')} prop (
{link(
'lookup for API on GitHub',
'https://github.com/stardust-ui/react/blob/master/packages/react/src/lib/accessibility/FocusTrapZone/FocusTrapZone.types.tsx',
Expand All @@ -50,31 +53,23 @@ export default () => (
</p>
<ComponentPropsTable componentName="FocusTrapZone" />
<Header as="h2">Override {code('FocusTrapZone')} settings</Header>
<p>
To be able to add/override {code('FocusTrapZone')} props already set for a component, it is
needed to override or create a new accessibility behavior.
</p>
<p>
For example, we want to disable first focus on Popup mount, so we can control the initial
focus by ourselves.
focus by ourselves:
</p>
<CodeSnippet
label="PopupExample.jsx"
value={`
const overridenFocusTrapBehavior: Accessibility = (props: any) => {
const behavior = popupFocusTrapBehavior(props)

behavior.trapFocus.disableFirstFocus = true;

return behavior
}
`}
const Popup = () => (
<Popup trapFocus={{ disableFirstFocus: true }} />
)`}
/>
And then use this new behavior by Popup component:
<p>Same usage applies to {code('Dialog')} component:</p>
<CodeSnippet
label="PopupExample.jsx"
label="DialogExample.jsx"
value={`
const Popup = () => (
<Popup accessibility={overridenFocusTrapBehavior} />
const Dialog = () => (
<Dialog trapFocus={{ focusTriggerOnOutsideClick: true }} />
)`}
/>
<p>Read more about:</p>
Expand Down
Loading