From da8b51da4afa8d00c5c48bf7b2af778d45ca8c4e Mon Sep 17 00:00:00 2001 From: Eugene Olonov Date: Wed, 28 Sep 2022 19:39:03 -0700 Subject: [PATCH 1/6] a11y: disable subscriptions input if no subscriptions available Fixes [75832](https://fuselabs.visualstudio.com/Composer/_workitems/edit/75832/) --- .../azurePublish/src/components/azureProvisionDialog.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/extensions/azurePublish/src/components/azureProvisionDialog.tsx b/extensions/azurePublish/src/components/azureProvisionDialog.tsx index ef0ab9f2f8..9d56c37c3d 100644 --- a/extensions/azurePublish/src/components/azureProvisionDialog.tsx +++ b/extensions/azurePublish/src/components/azureProvisionDialog.tsx @@ -818,7 +818,7 @@ export const AzureProvisionDialog: React.FC = () => { {renderPropertyInfoIcon(formatMessage('The subscription that will be billed for the resources.'))} { {renderPropertyInfoIcon(formatMessage('The region where your resources and bot will be used.'))} { Date: Wed, 28 Sep 2022 19:53:49 -0700 Subject: [PATCH 2/6] a11y: fix collapse button aria Fixes [75830](https://fuselabs.visualstudio.com/Composer/_workitems/edit/75830/) --- .../src/components/CollapseField.tsx | 30 ++++++++++--------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/Composer/packages/adaptive-form/src/components/CollapseField.tsx b/Composer/packages/adaptive-form/src/components/CollapseField.tsx index 9d6392bf63..c7427c5807 100644 --- a/Composer/packages/adaptive-form/src/components/CollapseField.tsx +++ b/Composer/packages/adaptive-form/src/components/CollapseField.tsx @@ -5,12 +5,16 @@ import { css, jsx } from '@emotion/react'; import { Fragment, useState, useEffect, useLayoutEffect, useRef } from 'react'; import { FontSizes, FontWeights } from '@fluentui/react/lib/Styling'; -import { IconButton } from '@fluentui/react/lib/Button'; import { Label } from '@fluentui/react/lib/Label'; import { NeutralColors } from '@fluentui/theme'; import formatMessage from 'format-message'; +import { Icon } from '@fluentui/react/lib/Icon'; +import styled from '@emotion/styled'; const styles = { + title: css` + font-weight: ${FontWeights.semibold}; + `, description: css` font-size: ${FontSizes.medium}; `, @@ -19,6 +23,8 @@ const styles = { overflow: hidden; `, header: css` + appearance: none; + border: none; background-color: #eff6fc; display: flex; margin: 4px -18px; @@ -26,6 +32,11 @@ const styles = { `, }; +const CollapseIcon = styled(Icon)({ + color: NeutralColors.gray150, + marginRight: '4px', +}); + interface CollapseField { defaultExpanded?: boolean; description?: string; @@ -37,28 +48,19 @@ export const CollapseField: React.FC = ({ children, description, return ( -
{ setIsOpen(!isOpen); }} > - - {title && } + + {title && } {description &&  - {description}} -
+
{children}
From c2632b82bb0aceb87b3b8d6e53a7e73a5a13e36a Mon Sep 17 00:00:00 2001 From: Eugene Olonov Date: Wed, 28 Sep 2022 20:08:58 -0700 Subject: [PATCH 3/6] a11y: restore focus on toolbar menu dismiss event Fixes [75833](https://fuselabs.visualstudio.com/Composer/_workitems/edit/75833/) --- .../code-editor/src/components/toolbar/ToolbarButtonMenu.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Composer/packages/lib/code-editor/src/components/toolbar/ToolbarButtonMenu.tsx b/Composer/packages/lib/code-editor/src/components/toolbar/ToolbarButtonMenu.tsx index 0a687054bb..9fac4f217c 100644 --- a/Composer/packages/lib/code-editor/src/components/toolbar/ToolbarButtonMenu.tsx +++ b/Composer/packages/lib/code-editor/src/components/toolbar/ToolbarButtonMenu.tsx @@ -341,9 +341,11 @@ export const ToolbarButtonMenu = React.memo((props: ToolbarButtonMenuProps) => { } }, [menuItems, flatPropertyListItems, flatFunctionListItems, noSearchResultMenuItem, query, payload.kind]); + const menuButtonRef = React.useRef(null); const onMenuDismissed = React.useCallback(() => { onReset(); setPropertyTreeExpanded({}); + menuButtonRef?.current?.focus(); }, []); const menuProps: IContextualMenuProps = React.useMemo(() => { @@ -449,6 +451,7 @@ export const ToolbarButtonMenu = React.memo((props: ToolbarButtonMenuProps) => { className={dismissHandlerClassName} data-testid="menuButton" disabled={disabled} + elementRef={menuButtonRef} menuProps={menuProps} styles={buttonStyles} onRenderIcon={renderIcon} From f9fc331d0965bfdaf81cb408278d4222df50239e Mon Sep 17 00:00:00 2001 From: Eugene Olonov Date: Thu, 29 Sep 2022 15:02:32 -0700 Subject: [PATCH 4/6] a11y: fix code-editor properties tree aria Fixes [75854](https://fuselabs.visualstudio.com/Composer/_workitems/edit/75854/) --- .../components/toolbar/PropertyTreeItem.tsx | 25 +++- .../components/toolbar/ToolbarButtonMenu.tsx | 120 ++++++++++-------- extensions/azurePublish/yarn-berry.lock | 4 +- 3 files changed, 88 insertions(+), 61 deletions(-) diff --git a/Composer/packages/lib/code-editor/src/components/toolbar/PropertyTreeItem.tsx b/Composer/packages/lib/code-editor/src/components/toolbar/PropertyTreeItem.tsx index aa9bbdcd08..5472b1fc99 100644 --- a/Composer/packages/lib/code-editor/src/components/toolbar/PropertyTreeItem.tsx +++ b/Composer/packages/lib/code-editor/src/components/toolbar/PropertyTreeItem.tsx @@ -4,8 +4,10 @@ import styled from '@emotion/styled'; import { NeutralColors } from '@fluentui/theme'; import { Icon, IIconStyles } from '@fluentui/react/lib/Icon'; +import { Button } from '@fluentui/react/lib/Button'; import { Stack } from '@fluentui/react/lib/Stack'; import * as React from 'react'; +import { IContextualMenuItem } from '@fluentui/react/lib/ContextualMenu'; import { PropertyItem } from '../../types'; @@ -23,7 +25,7 @@ const toggleExpandIconStyle: IIconStyles = { fontSize: 8, transition: 'background 250ms ease', selectors: { - '&:hover': { background: NeutralColors.gray50 }, + '&:hover, &:focus-within': { background: NeutralColors.gray50 }, '&:before': { content: '""', }, @@ -32,7 +34,9 @@ const toggleExpandIconStyle: IIconStyles = { }; const Root = styled(Stack)({ + width: '100%', height: DEFAULT_TREE_ITEM_HEIGHT, + border: 'none', }); const Content = styled(Stack)<{ @@ -42,6 +46,10 @@ const Content = styled(Stack)<{ })); type PropertyTreeItemProps = { + onClick?: ( + ev?: React.MouseEvent | React.KeyboardEvent, + item?: IContextualMenuItem + ) => boolean | void; item: PropertyItem; level: number; onRenderLabel: (item: PropertyItem) => React.ReactNode; @@ -50,7 +58,7 @@ type PropertyTreeItemProps = { }; export const PropertyTreeItem = React.memo((props: PropertyTreeItemProps) => { - const { expanded = false, item, level, onToggleExpand, onRenderLabel } = props; + const { expanded = false, item, level, onToggleExpand, onRenderLabel, ...rest } = props; const paddingLeft = level * DEFAULT_INDENTATION_PADDING; @@ -65,7 +73,18 @@ export const PropertyTreeItem = React.memo((props: PropertyTreeItemProps) => { const isExpandable = !!item.children?.length && onToggleExpand; return ( - + {isExpandable ? ( { setPropertyTreeExpanded({ ...propertyTreeExpanded, [itemId]: expanded }); }; - return nodes.map((node) => ({ + return nodes.map((node, index) => ({ key: node.id, text: node.name, secondaryText: paths[node.id], @@ -234,6 +234,7 @@ export const ToolbarButtonMenu = React.memo((props: ToolbarButtonMenuProps) => { path: paths[node.id], level: levels[node.id] - 1, onToggleExpand, + index, }, })); } @@ -266,7 +267,7 @@ export const ToolbarButtonMenu = React.memo((props: ToolbarButtonMenuProps) => { const { root, onSelectProperty } = propertyTreeConfig; const { nodes, paths } = getAllNodes(root, { skipRoot: true }); - return nodes.map((node) => ({ + return nodes.map((node, index) => ({ text: node.id, key: node.id, secondaryText: paths[node.id], @@ -278,6 +279,7 @@ export const ToolbarButtonMenu = React.memo((props: ToolbarButtonMenuProps) => { node, path: paths[node.id], level: 0, + index, }, })) as IContextualMenuItem[]; } @@ -380,64 +382,70 @@ export const ToolbarButtonMenu = React.memo((props: ToolbarButtonMenuProps) => { } as IContextualMenuProps; } case 'property': { + const renderMenuItem = (item: IContextualMenuItem) => { + const { secondaryText: path } = item; + const { onToggleExpand, level, node, index } = item.data as { + node: PropertyItem; + onToggleExpand: (itemId: string, expanded: boolean) => void; + level: number; + index: number; + }; + + const renderLabel = () => { + const pathNodes = (path ?? '').split('.'); + return ( + + {pathNodes.map((pathNode, idx) => ( + + {`${pathNode}${idx === pathNodes.length - 1 && node.children.length === 0 ? '' : '.'}`} + + ))} + + ); + }; + + const renderSearchResultLabel = () => ( + + {path} + + ); + + return ( + + ); + }; return { onMenuDismissed, - items, + items: items.map((item) => ({ + ...item, + onRender: renderMenuItem, + })), calloutProps, onRenderMenuList, - contextualMenuItemAs: (itemProps: IContextualMenuItemProps) => { - const { - item: { secondaryText: path }, - } = itemProps; - const { onToggleExpand, level, node } = itemProps.item.data as { - node: PropertyItem; - onToggleExpand: (itemId: string, expanded: boolean) => void; - level: number; - }; - - const renderLabel = () => { - const pathNodes = (path ?? '').split('.'); - return ( - - {pathNodes.map((pathNode, idx) => ( - - {`${pathNode}${idx === pathNodes.length - 1 && node.children.length === 0 ? '' : '.'}`} - - ))} - - ); - }; - - const renderSearchResultLabel = () => ( - - {path} - - ); - - return ( - - ); - }, } as IContextualMenuProps; } } diff --git a/extensions/azurePublish/yarn-berry.lock b/extensions/azurePublish/yarn-berry.lock index d1fa21626d..bac799e301 100644 --- a/extensions/azurePublish/yarn-berry.lock +++ b/extensions/azurePublish/yarn-berry.lock @@ -1879,7 +1879,7 @@ __metadata: "@bfc/code-editor@file:../../Composer/packages/lib/code-editor::locator=azurePublish%40workspace%3A.": version: 0.0.0 - resolution: "@bfc/code-editor@file:../../Composer/packages/lib/code-editor#../../Composer/packages/lib/code-editor::hash=96fbdb&locator=azurePublish%40workspace%3A." + resolution: "@bfc/code-editor@file:../../Composer/packages/lib/code-editor#../../Composer/packages/lib/code-editor::hash=71a195&locator=azurePublish%40workspace%3A." dependencies: "@emotion/react": ^11.1.3 "@emotion/styled": ^11.1.3 @@ -1902,7 +1902,7 @@ __metadata: "@bfc/ui-shared": "*" react: 16.13.1 react-dom: 16.13.1 - checksum: cae0fcb331c2a391dc48da25f945a9d9ab3e65ed1151621d3b431c003b9b6f585ab90331c63e82ee06f5f43da7d747d99ebaa071e4bb337d6acdaa49526b600a + checksum: 22ec5585e706ba4a9efa444fa97f98cd86f6dc291d9d0aea0bc2c4b7e1c04ea94d0e9c02f05f53f9de629c9708fa3066e10451f363f658e916a842e6bd89dd08 languageName: node linkType: hard From 54930614d54ff7fe1e8fa92f848f66e970f93b66 Mon Sep 17 00:00:00 2001 From: Eugene Olonov Date: Thu, 29 Sep 2022 16:19:17 -0700 Subject: [PATCH 5/6] a11y: scope color adjustments to disabled forced-colors Fixes [75828](https://fuselabs.visualstudio.com/Composer/_workitems/edit/75828/) --- .../client/src/components/EditableField.tsx | 36 ++++++++++++------- .../src/components/FieldWithCustomButton.tsx | 10 +++--- .../client/src/pages/knowledge-base/styles.ts | 8 +++-- 3 files changed, 34 insertions(+), 20 deletions(-) diff --git a/Composer/packages/client/src/components/EditableField.tsx b/Composer/packages/client/src/components/EditableField.tsx index dd06a44bd5..a40e9ae2e0 100644 --- a/Composer/packages/client/src/components/EditableField.tsx +++ b/Composer/packages/client/src/components/EditableField.tsx @@ -20,13 +20,15 @@ const allowedNavigationKeys = ['ArrowDown', 'ArrowUp', 'ArrowLeft', 'ArrowRight' const defaultContainerStyle = (hasFocus, hasErrors) => css` display: flex; width: 100%; - outline: ${hasErrors - ? `2px solid ${SharedColors.red10}` - : hasFocus - ? `2px solid ${SharedColors.cyanBlue10}` - : undefined}; - background: ${hasFocus || hasErrors ? NeutralColors.white : 'inherit'}; margin-top: 2px; + @media (forced-colors: none) { + background: ${hasFocus || hasErrors ? NeutralColors.white : 'inherit'}; + outline: ${hasErrors + ? `2px solid ${SharedColors.red10}` + : hasFocus + ? `2px solid ${SharedColors.cyanBlue10}` + : undefined}; + } :hover .ms-Button-icon, :focus-within .ms-Button-icon { visibility: visible; @@ -41,6 +43,12 @@ const defaultContainerStyle = (hasFocus, hasErrors) => css` } `; +const requiredText = css` + @media (forced-colors: none) { + color: ${SharedColors.red20}; + } +`; + // turncat to show two line. const maxCharacterNumbers = 120; @@ -270,8 +278,10 @@ const EditableField: React.FC = (props) => { ':hover': { borderColor: hasFocus ? undefined : NeutralColors.gray30, }, - '.ms-TextField-field': { - background: hasFocus || hasEditingErrors ? NeutralColors.white : 'inherit', + '@media (forced-colors: none)': { + '.ms-TextField-field': { + background: hasFocus || hasEditingErrors ? NeutralColors.white : 'inherit', + }, }, }, }, @@ -312,17 +322,17 @@ const EditableField: React.FC = (props) => { }} styles={{ root: { - background: hasFocus ? NeutralColors.white : 'inherit', + '@media (forced-colors: none)': { + background: hasFocus ? NeutralColors.white : 'inherit', + }, }, }} onClick={iconProps?.onClick || resetValue} /> )} - {hasErrors && hasBeenEdited && ( - {requiredMessage || formErrors.value} - )} - {error && {error}} + {hasErrors && hasBeenEdited && {requiredMessage || formErrors.value}} + {error && {error}} {hasErrors && hasBeenEdited && } {error && }
diff --git a/Composer/packages/client/src/components/FieldWithCustomButton.tsx b/Composer/packages/client/src/components/FieldWithCustomButton.tsx index 7c31a660c0..902455c125 100644 --- a/Composer/packages/client/src/components/FieldWithCustomButton.tsx +++ b/Composer/packages/client/src/components/FieldWithCustomButton.tsx @@ -18,10 +18,12 @@ const disabledTextFieldStyle = mergeStyleSets(customFieldLabel, { root: { selectors: { '.ms-TextField-field': { - background: '#ddf3db', - }, - '.ms-Dropdown-title': { - background: '#ddf3db', + '@media (forced-colors: none)': { + background: '#ddf3db', + }, + '.ms-Dropdown-title': { + background: '#ddf3db', + }, }, 'p > span': { width: '100%', diff --git a/Composer/packages/client/src/pages/knowledge-base/styles.ts b/Composer/packages/client/src/pages/knowledge-base/styles.ts index df6014c1ac..2e40f355c7 100644 --- a/Composer/packages/client/src/pages/knowledge-base/styles.ts +++ b/Composer/packages/client/src/pages/knowledge-base/styles.ts @@ -98,7 +98,7 @@ export const rowDetails = { background: NeutralColors.gray30, selectors: { '.ms-TextField-fieldGroup': { - background: NeutralColors.gray30, + background: 'transparent', }, '.ms-Button--icon': { visibility: 'visible', @@ -117,7 +117,7 @@ export const rowDetails = { visibility: 'visible', }, '.ms-TextField-fieldGroup': { - background: NeutralColors.gray30, + background: 'transparent', }, }, }, @@ -140,8 +140,10 @@ export const addAlternative = { fontSize: 12, paddingLeft: 0, marginLeft: -5, - color: SharedColors.cyanBlue10, display: 'none', + '@media (forced-colors: none)': { + color: SharedColors.cyanBlue10, + }, }, } as IButtonStyles; From dbb1987009369adb545b66b7a15f718b0dbf5d1f Mon Sep 17 00:00:00 2001 From: Eugene Olonov Date: Fri, 30 Sep 2022 11:23:24 -0700 Subject: [PATCH 6/6] Update lock files --- extensions/azurePublish/yarn-berry.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extensions/azurePublish/yarn-berry.lock b/extensions/azurePublish/yarn-berry.lock index bac799e301..a02ba2c117 100644 --- a/extensions/azurePublish/yarn-berry.lock +++ b/extensions/azurePublish/yarn-berry.lock @@ -1879,7 +1879,7 @@ __metadata: "@bfc/code-editor@file:../../Composer/packages/lib/code-editor::locator=azurePublish%40workspace%3A.": version: 0.0.0 - resolution: "@bfc/code-editor@file:../../Composer/packages/lib/code-editor#../../Composer/packages/lib/code-editor::hash=71a195&locator=azurePublish%40workspace%3A." + resolution: "@bfc/code-editor@file:../../Composer/packages/lib/code-editor#../../Composer/packages/lib/code-editor::hash=11552c&locator=azurePublish%40workspace%3A." dependencies: "@emotion/react": ^11.1.3 "@emotion/styled": ^11.1.3 @@ -1902,7 +1902,7 @@ __metadata: "@bfc/ui-shared": "*" react: 16.13.1 react-dom: 16.13.1 - checksum: 22ec5585e706ba4a9efa444fa97f98cd86f6dc291d9d0aea0bc2c4b7e1c04ea94d0e9c02f05f53f9de629c9708fa3066e10451f363f658e916a842e6bd89dd08 + checksum: 4d7fbf613915d6ae65bc1737346d5ad353766f36bb03f4fef0f94ce063d056166da9043677a4e8e610a2dbadb627e29df1893eda8dcac8f74201a2e77baccea2 languageName: node linkType: hard