From bca486df7437e78c55b542ef04b47bad7698ef77 Mon Sep 17 00:00:00 2001 From: Sofiya Huts Date: Fri, 14 Dec 2018 15:21:09 +0100 Subject: [PATCH 1/7] fix(FocusZone): fix last breaking changes and make improvements when using Chat --- .../Behaviors/Chat/chatBehavior.ts | 7 +++++-- src/lib/accessibility/FocusZone/FocusZone.tsx | 21 +++++++++---------- .../FocusZone/FocusZone.types.ts | 4 ++-- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/lib/accessibility/Behaviors/Chat/chatBehavior.ts b/src/lib/accessibility/Behaviors/Chat/chatBehavior.ts index 5d3f9d71cd..06ba1fb789 100644 --- a/src/lib/accessibility/Behaviors/Chat/chatBehavior.ts +++ b/src/lib/accessibility/Behaviors/Chat/chatBehavior.ts @@ -21,7 +21,7 @@ const ChatBehavior: Accessibility = (props: any) => ({ props: { shouldEnterInnerZone: event => keyboardKey.getCode(event) === keyboardKey.Enter, direction: FocusZoneDirection.vertical, - shouldHandleKeyDownCapture: false, + shouldResetActiveElementWhenTabFromZone: true, defaultTabbableElement: getLastTabbableElement, // select last chat message by default [CHAT_FOCUSZONE_ATTRIBUTE]: '', // allows querying the default active element }, @@ -36,8 +36,11 @@ const ChatBehavior: Accessibility = (props: any) => ({ }) const getLastTabbableElement = (root: HTMLElement): HTMLElement => { + const lastVisibleMessage = root.querySelector('[data-last-visible]') as HTMLElement + if (lastVisibleMessage) return lastVisibleMessage + const chatItemsElements = root.querySelectorAll( - `[${CHAT_FOCUSZONE_ATTRIBUTE}] .ui-chat__item > [${IS_FOCUSABLE_ATTRIBUTE}]`, + `[${CHAT_FOCUSZONE_ATTRIBUTE}] .ui-chat__message[${IS_FOCUSABLE_ATTRIBUTE}]`, ) return chatItemsElements.length > 0 ? (chatItemsElements[chatItemsElements.length - 1] as HTMLElement) diff --git a/src/lib/accessibility/FocusZone/FocusZone.tsx b/src/lib/accessibility/FocusZone/FocusZone.tsx index 9be1567d53..d4c2697c27 100644 --- a/src/lib/accessibility/FocusZone/FocusZone.tsx +++ b/src/lib/accessibility/FocusZone/FocusZone.tsx @@ -67,7 +67,6 @@ export class FocusZone extends React.Component implements IFocus static defaultProps: FocusZoneProps = { isCircularNavigation: false, direction: FocusZoneDirection.bidirectional, - shouldHandleKeyDownCapture: true, as: 'div', } @@ -105,8 +104,6 @@ export class FocusZone extends React.Component implements IFocus public componentDidMount(): void { _allInstances[this._id] = this - const { shouldHandleKeyDownCapture, defaultTabbableElement, shouldFocusOnMount } = this.props - this.setRef(this) // called here to support functional components, we only need HTMLElement ref anyway if (this._root.current) { this.windowElement = getWindow(this._root.current) @@ -121,19 +118,14 @@ export class FocusZone extends React.Component implements IFocus parentElement = getParent(parentElement) } - if (!this._isInnerZone && shouldHandleKeyDownCapture) { + if (!this._isInnerZone) { this.windowElement.addEventListener('keydown', this.onKeyDownCapture, true) } // Assign initial tab indexes so that we can set initial focus as appropriate. this.updateTabIndexes() - if (defaultTabbableElement) { - const initialActiveElement = defaultTabbableElement(this._root.current) - initialActiveElement && this.setActiveElement(initialActiveElement) - } - - if (shouldFocusOnMount) { + if (this.props.shouldFocusOnMount) { this.focus() } } @@ -141,7 +133,7 @@ export class FocusZone extends React.Component implements IFocus public componentWillUnmount() { delete _allInstances[this._id] - if (this.windowElement && this.props.shouldHandleKeyDownCapture) { + if (this.windowElement) { this.windowElement.removeEventListener('keydown', this.onKeyDownCapture, true) } } @@ -471,6 +463,8 @@ export class FocusZone extends React.Component implements IFocus if (focusChanged) { break } + } else if (this.props.shouldResetActiveElementWhenTabFromZone) { + this._activeElement = null } return undefined @@ -844,6 +838,11 @@ export class FocusZone extends React.Component implements IFocus private updateTabIndexes(onElement?: HTMLElement) { let element = onElement + + if (!this._activeElement && this.props.defaultTabbableElement) { + this._activeElement = this.props.defaultTabbableElement(this._root.current) + } + if (!element && this._root.current) { this._defaultFocusElement = null element = this._root.current diff --git a/src/lib/accessibility/FocusZone/FocusZone.types.ts b/src/lib/accessibility/FocusZone/FocusZone.types.ts index 2d9336d34b..50a609ca13 100644 --- a/src/lib/accessibility/FocusZone/FocusZone.types.ts +++ b/src/lib/accessibility/FocusZone/FocusZone.types.ts @@ -59,9 +59,9 @@ export interface FocusZoneProps extends React.HTMLAttributes Date: Tue, 18 Dec 2018 10:22:29 +0100 Subject: [PATCH 2/7] set explicit query selector on boolean attributes --- src/lib/accessibility/Behaviors/Chat/chatBehavior.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/accessibility/Behaviors/Chat/chatBehavior.ts b/src/lib/accessibility/Behaviors/Chat/chatBehavior.ts index 06ba1fb789..0fa8ed9fc1 100644 --- a/src/lib/accessibility/Behaviors/Chat/chatBehavior.ts +++ b/src/lib/accessibility/Behaviors/Chat/chatBehavior.ts @@ -36,11 +36,11 @@ const ChatBehavior: Accessibility = (props: any) => ({ }) const getLastTabbableElement = (root: HTMLElement): HTMLElement => { - const lastVisibleMessage = root.querySelector('[data-last-visible]') as HTMLElement + const lastVisibleMessage = root.querySelector('[data-last-visible]="true"') as HTMLElement if (lastVisibleMessage) return lastVisibleMessage const chatItemsElements = root.querySelectorAll( - `[${CHAT_FOCUSZONE_ATTRIBUTE}] .ui-chat__message[${IS_FOCUSABLE_ATTRIBUTE}]`, + `[${CHAT_FOCUSZONE_ATTRIBUTE}] .ui-chat__message[${IS_FOCUSABLE_ATTRIBUTE}="true"]`, ) return chatItemsElements.length > 0 ? (chatItemsElements[chatItemsElements.length - 1] as HTMLElement) From 4a948ae5000415a4d76c1d66d81dd68612dccb38 Mon Sep 17 00:00:00 2001 From: Sofiya Huts Date: Tue, 18 Dec 2018 10:23:55 +0100 Subject: [PATCH 3/7] fix propTypes --- src/lib/accessibility/FocusZone/FocusZone.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/accessibility/FocusZone/FocusZone.tsx b/src/lib/accessibility/FocusZone/FocusZone.tsx index d4c2697c27..c8210d1b78 100644 --- a/src/lib/accessibility/FocusZone/FocusZone.tsx +++ b/src/lib/accessibility/FocusZone/FocusZone.tsx @@ -48,7 +48,7 @@ export class FocusZone extends React.Component implements IFocus defaultTabbableElement: PropTypes.func, shouldFocusOnMount: PropTypes.bool, shouldFocusFirstElementWhenReceivedFocus: PropTypes.bool, - shouldHandleKeyDownCapture: PropTypes.bool, + shouldResetActiveElementWhenTabFromZone: PropTypes.bool, disabled: PropTypes.bool, as: customPropTypes.as, isCircularNavigation: PropTypes.bool, From 585bd0cabc6085f33c096c6dcdfb7f18b60d3bbf Mon Sep 17 00:00:00 2001 From: Sofiya Huts Date: Tue, 18 Dec 2018 10:28:33 +0100 Subject: [PATCH 4/7] set explicit query selector on boolean attributes --- src/lib/accessibility/Behaviors/Chat/chatBehavior.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/accessibility/Behaviors/Chat/chatBehavior.ts b/src/lib/accessibility/Behaviors/Chat/chatBehavior.ts index 0fa8ed9fc1..6f067a2b44 100644 --- a/src/lib/accessibility/Behaviors/Chat/chatBehavior.ts +++ b/src/lib/accessibility/Behaviors/Chat/chatBehavior.ts @@ -36,7 +36,7 @@ const ChatBehavior: Accessibility = (props: any) => ({ }) const getLastTabbableElement = (root: HTMLElement): HTMLElement => { - const lastVisibleMessage = root.querySelector('[data-last-visible]="true"') as HTMLElement + const lastVisibleMessage = root.querySelector('[data-last-visible="true"]') as HTMLElement if (lastVisibleMessage) return lastVisibleMessage const chatItemsElements = root.querySelectorAll( From dcb48390ec290fb070cdaa65f85f519e8f41ed12 Mon Sep 17 00:00:00 2001 From: Sofiya Huts Date: Tue, 18 Dec 2018 10:29:48 +0100 Subject: [PATCH 5/7] Small fix of console error --- docs/src/prototypes/chatPane/services/messageFactoryMock.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/prototypes/chatPane/services/messageFactoryMock.tsx b/docs/src/prototypes/chatPane/services/messageFactoryMock.tsx index b0f22acbd6..d506900744 100644 --- a/docs/src/prototypes/chatPane/services/messageFactoryMock.tsx +++ b/docs/src/prototypes/chatPane/services/messageFactoryMock.tsx @@ -119,7 +119,7 @@ function createMessageContentWithAttachments(content: string, messageId: string) icon="file word outline" aria-label={`File attachment ${fileName}. Press tab for more options Press Enter to open the file`} header={fileName} - action={render => render(actionPopup)} + action={actionPopup} data-is-focusable={true} styles={{ '&:focus': { From 4e97e1377120b97be0fb677b3ea24514f8e19339 Mon Sep 17 00:00:00 2001 From: Sofiya Huts Date: Thu, 20 Dec 2018 12:50:21 +0100 Subject: [PATCH 6/7] update changelog --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3070a801db..f1f2bf2dc9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,7 +23,8 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm ### Fixes - Ensure `Popup` properly flips values of `offset` prop in RTL @kuzhelov ([#612](https://github.com/stardust-ui/react/pull/612)) - Fix `List` - items should be selectable @sophieH29 ([#566](https://github.com/stardust-ui/react/pull/566)) -- Respect `defaultTabbable` element when `FocusZone` container gets focus ([#637](https://github.com/stardust-ui/react/pull/637)) +- Respect `defaultTabbable` element when `FocusZone` container gets focus @sophieH29 ([#637](https://github.com/stardust-ui/react/pull/637)) +- Fix `FocusZone` - fix last breaking changes and make improvements for `Chat` usage @sophieH29 ([#614](https://github.com/stardust-ui/react/pull/614)) ### Features - Add `color` prop to `Text` component @Bugaa92 ([#597](https://github.com/stardust-ui/react/pull/597)) From 6f1b16fc9a202ff0b67bb18a8e5a292e172c7760 Mon Sep 17 00:00:00 2001 From: Sofiya Huts Date: Thu, 20 Dec 2018 12:51:23 +0100 Subject: [PATCH 7/7] update changelog --- src/lib/accessibility/FocusZone/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lib/accessibility/FocusZone/CHANGELOG.md b/src/lib/accessibility/FocusZone/CHANGELOG.md index 2148147902..d75845f0b7 100644 --- a/src/lib/accessibility/FocusZone/CHANGELOG.md +++ b/src/lib/accessibility/FocusZone/CHANGELOG.md @@ -8,6 +8,7 @@ This is a list of changes made to this Stardust copy of FocusZone in comparison - Fix `defaultTabbableElement` prop to be as a function ([#450](https://github.com/stardust-ui/react/pull/450)) - Remove role="presentation" @sophieH29 ([#530](https://github.com/stardust-ui/react/pull/530)) - Respect `defaultTabbable` element when FocusZone container receives focus @sophieH29 ([#637](https://github.com/stardust-ui/react/pull/637)) +- Fix `FocusZone` - add `shouldResetActiveElementWhenTabFromZone` prop @sophieH29 ([#614](https://github.com/stardust-ui/react/pull/614)) ### Features - Add embed mode for FocusZone and new Chat behavior ([#233](https://github.com/stardust-ui/react/pull/233))