diff --git a/packages/report-e2e-tests/src/examples/axe-results-with-issues.snap.html b/packages/report-e2e-tests/src/examples/axe-results-with-issues.snap.html index 4f4bbb57fc3..f1b5f8f62ea 100644 --- a/packages/report-e2e-tests/src/examples/axe-results-with-issues.snap.html +++ b/packages/report-e2e-tests/src/examples/axe-results-with-issues.snap.html @@ -823,7 +823,7 @@ border: none; display: flex; align-items: baseline; - width: 100%; + width: auto; } .collapsible-container .collapsible-control:hover { background-color: var(--neutral-alpha-4); @@ -993,13 +993,27 @@ color: buttontext !important; } } -.kebab-menu-icon--EUIj-:hover { - border-style: solid !important; - border-width: 1px; - padding-left: 8px !important; - padding-right: 8px !important; - padding-top: 5px !important; - padding-bottom: 5px !important; +.fileissue--x5mek { + font-weight: 400 !important; +} +.fileissue--x5mek:hover > span > svg { + color: var(--insights-button-hover); +} +.fileissue--x5mek:focus { + outline: 1px solid; +} +.copyfailuredetails--NHZE4 { + font-weight: 400 !important; +} +.copyfailuredetails--NHZE4:hover > span > svg { + color: var(--insights-button-hover); +} +.menu-Button--ElHFS:hover { + border: 1px solid var(--primary-text) !important; + color: var(--primary-text) !important; +} +.menu-Button--ElHFS:focus { + outline: 1px solid; } .kebab-menu-button--9Qt0a { margin-right: 8px; @@ -1105,6 +1119,7 @@ display: flex; align-items: baseline; text-align: left; + font-weight: normal; } .rule-details-group--Tb-LW .rule-detail .outcome-chip { vertical-align: middle; diff --git a/packages/report-e2e-tests/src/examples/axe-results-without-issues.snap.html b/packages/report-e2e-tests/src/examples/axe-results-without-issues.snap.html index 6353a8da4ed..82cc6386c5b 100644 --- a/packages/report-e2e-tests/src/examples/axe-results-without-issues.snap.html +++ b/packages/report-e2e-tests/src/examples/axe-results-without-issues.snap.html @@ -823,7 +823,7 @@ border: none; display: flex; align-items: baseline; - width: 100%; + width: auto; } .collapsible-container .collapsible-control:hover { background-color: var(--neutral-alpha-4); @@ -993,13 +993,27 @@ color: buttontext !important; } } -.kebab-menu-icon--EUIj-:hover { - border-style: solid !important; - border-width: 1px; - padding-left: 8px !important; - padding-right: 8px !important; - padding-top: 5px !important; - padding-bottom: 5px !important; +.fileissue--x5mek { + font-weight: 400 !important; +} +.fileissue--x5mek:hover > span > svg { + color: var(--insights-button-hover); +} +.fileissue--x5mek:focus { + outline: 1px solid; +} +.copyfailuredetails--NHZE4 { + font-weight: 400 !important; +} +.copyfailuredetails--NHZE4:hover > span > svg { + color: var(--insights-button-hover); +} +.menu-Button--ElHFS:hover { + border: 1px solid var(--primary-text) !important; + color: var(--primary-text) !important; +} +.menu-Button--ElHFS:focus { + outline: 1px solid; } .kebab-menu-button--9Qt0a { margin-right: 8px; @@ -1105,6 +1119,7 @@ display: flex; align-items: baseline; text-align: left; + font-weight: normal; } .rule-details-group--Tb-LW .rule-detail .outcome-chip { vertical-align: middle; diff --git a/packages/report-e2e-tests/src/examples/combined-results-with-baseline-aware-issues.snap.html b/packages/report-e2e-tests/src/examples/combined-results-with-baseline-aware-issues.snap.html index 6ac41740ecd..8bd749c05c2 100644 --- a/packages/report-e2e-tests/src/examples/combined-results-with-baseline-aware-issues.snap.html +++ b/packages/report-e2e-tests/src/examples/combined-results-with-baseline-aware-issues.snap.html @@ -823,7 +823,7 @@ border: none; display: flex; align-items: baseline; - width: 100%; + width: auto; } .collapsible-container .collapsible-control:hover { background-color: var(--neutral-alpha-4); @@ -993,13 +993,27 @@ color: buttontext !important; } } -.kebab-menu-icon--EUIj-:hover { - border-style: solid !important; - border-width: 1px; - padding-left: 8px !important; - padding-right: 8px !important; - padding-top: 5px !important; - padding-bottom: 5px !important; +.fileissue--x5mek { + font-weight: 400 !important; +} +.fileissue--x5mek:hover > span > svg { + color: var(--insights-button-hover); +} +.fileissue--x5mek:focus { + outline: 1px solid; +} +.copyfailuredetails--NHZE4 { + font-weight: 400 !important; +} +.copyfailuredetails--NHZE4:hover > span > svg { + color: var(--insights-button-hover); +} +.menu-Button--ElHFS:hover { + border: 1px solid var(--primary-text) !important; + color: var(--primary-text) !important; +} +.menu-Button--ElHFS:focus { + outline: 1px solid; } .kebab-menu-button--9Qt0a { margin-right: 8px; @@ -1105,6 +1119,7 @@ display: flex; align-items: baseline; text-align: left; + font-weight: normal; } .rule-details-group--Tb-LW .rule-detail .outcome-chip { vertical-align: middle; diff --git a/packages/report-e2e-tests/src/examples/combined-results-with-issues.snap.html b/packages/report-e2e-tests/src/examples/combined-results-with-issues.snap.html index ee8684840cd..2e231865805 100644 --- a/packages/report-e2e-tests/src/examples/combined-results-with-issues.snap.html +++ b/packages/report-e2e-tests/src/examples/combined-results-with-issues.snap.html @@ -823,7 +823,7 @@ border: none; display: flex; align-items: baseline; - width: 100%; + width: auto; } .collapsible-container .collapsible-control:hover { background-color: var(--neutral-alpha-4); @@ -993,13 +993,27 @@ color: buttontext !important; } } -.kebab-menu-icon--EUIj-:hover { - border-style: solid !important; - border-width: 1px; - padding-left: 8px !important; - padding-right: 8px !important; - padding-top: 5px !important; - padding-bottom: 5px !important; +.fileissue--x5mek { + font-weight: 400 !important; +} +.fileissue--x5mek:hover > span > svg { + color: var(--insights-button-hover); +} +.fileissue--x5mek:focus { + outline: 1px solid; +} +.copyfailuredetails--NHZE4 { + font-weight: 400 !important; +} +.copyfailuredetails--NHZE4:hover > span > svg { + color: var(--insights-button-hover); +} +.menu-Button--ElHFS:hover { + border: 1px solid var(--primary-text) !important; + color: var(--primary-text) !important; +} +.menu-Button--ElHFS:focus { + outline: 1px solid; } .kebab-menu-button--9Qt0a { margin-right: 8px; @@ -1105,6 +1119,7 @@ display: flex; align-items: baseline; text-align: left; + font-weight: normal; } .rule-details-group--Tb-LW .rule-detail .outcome-chip { vertical-align: middle; diff --git a/packages/report-e2e-tests/src/examples/combined-results-without-issues.snap.html b/packages/report-e2e-tests/src/examples/combined-results-without-issues.snap.html index a32457f113f..8f385a00930 100644 --- a/packages/report-e2e-tests/src/examples/combined-results-without-issues.snap.html +++ b/packages/report-e2e-tests/src/examples/combined-results-without-issues.snap.html @@ -823,7 +823,7 @@ border: none; display: flex; align-items: baseline; - width: 100%; + width: auto; } .collapsible-container .collapsible-control:hover { background-color: var(--neutral-alpha-4); @@ -993,13 +993,27 @@ color: buttontext !important; } } -.kebab-menu-icon--EUIj-:hover { - border-style: solid !important; - border-width: 1px; - padding-left: 8px !important; - padding-right: 8px !important; - padding-top: 5px !important; - padding-bottom: 5px !important; +.fileissue--x5mek { + font-weight: 400 !important; +} +.fileissue--x5mek:hover > span > svg { + color: var(--insights-button-hover); +} +.fileissue--x5mek:focus { + outline: 1px solid; +} +.copyfailuredetails--NHZE4 { + font-weight: 400 !important; +} +.copyfailuredetails--NHZE4:hover > span > svg { + color: var(--insights-button-hover); +} +.menu-Button--ElHFS:hover { + border: 1px solid var(--primary-text) !important; + color: var(--primary-text) !important; +} +.menu-Button--ElHFS:focus { + outline: 1px solid; } .kebab-menu-button--9Qt0a { margin-right: 8px; @@ -1105,6 +1119,7 @@ display: flex; align-items: baseline; text-align: left; + font-weight: normal; } .rule-details-group--Tb-LW .rule-detail .outcome-chip { vertical-align: middle; diff --git a/packages/report-e2e-tests/src/examples/summary-scan-with-issues.snap.html b/packages/report-e2e-tests/src/examples/summary-scan-with-issues.snap.html index 48eb7885d27..2cffaae5f5e 100644 --- a/packages/report-e2e-tests/src/examples/summary-scan-with-issues.snap.html +++ b/packages/report-e2e-tests/src/examples/summary-scan-with-issues.snap.html @@ -823,7 +823,7 @@ border: none; display: flex; align-items: baseline; - width: 100%; + width: auto; } .collapsible-container .collapsible-control:hover { background-color: var(--neutral-alpha-4); @@ -993,13 +993,27 @@ color: buttontext !important; } } -.kebab-menu-icon--EUIj-:hover { - border-style: solid !important; - border-width: 1px; - padding-left: 8px !important; - padding-right: 8px !important; - padding-top: 5px !important; - padding-bottom: 5px !important; +.fileissue--x5mek { + font-weight: 400 !important; +} +.fileissue--x5mek:hover > span > svg { + color: var(--insights-button-hover); +} +.fileissue--x5mek:focus { + outline: 1px solid; +} +.copyfailuredetails--NHZE4 { + font-weight: 400 !important; +} +.copyfailuredetails--NHZE4:hover > span > svg { + color: var(--insights-button-hover); +} +.menu-Button--ElHFS:hover { + border: 1px solid var(--primary-text) !important; + color: var(--primary-text) !important; +} +.menu-Button--ElHFS:focus { + outline: 1px solid; } .kebab-menu-button--9Qt0a { margin-right: 8px; @@ -1105,6 +1119,7 @@ display: flex; align-items: baseline; text-align: left; + font-weight: normal; } .rule-details-group--Tb-LW .rule-detail .outcome-chip { vertical-align: middle; diff --git a/packages/report-e2e-tests/src/examples/summary-scan-without-issues.snap.html b/packages/report-e2e-tests/src/examples/summary-scan-without-issues.snap.html index a6da8970e97..5431243a905 100644 --- a/packages/report-e2e-tests/src/examples/summary-scan-without-issues.snap.html +++ b/packages/report-e2e-tests/src/examples/summary-scan-without-issues.snap.html @@ -823,7 +823,7 @@ border: none; display: flex; align-items: baseline; - width: 100%; + width: auto; } .collapsible-container .collapsible-control:hover { background-color: var(--neutral-alpha-4); @@ -993,13 +993,27 @@ color: buttontext !important; } } -.kebab-menu-icon--EUIj-:hover { - border-style: solid !important; - border-width: 1px; - padding-left: 8px !important; - padding-right: 8px !important; - padding-top: 5px !important; - padding-bottom: 5px !important; +.fileissue--x5mek { + font-weight: 400 !important; +} +.fileissue--x5mek:hover > span > svg { + color: var(--insights-button-hover); +} +.fileissue--x5mek:focus { + outline: 1px solid; +} +.copyfailuredetails--NHZE4 { + font-weight: 400 !important; +} +.copyfailuredetails--NHZE4:hover > span > svg { + color: var(--insights-button-hover); +} +.menu-Button--ElHFS:hover { + border: 1px solid var(--primary-text) !important; + color: var(--primary-text) !important; +} +.menu-Button--ElHFS:focus { + outline: 1px solid; } .kebab-menu-button--9Qt0a { margin-right: 8px; @@ -1105,6 +1119,7 @@ display: flex; align-items: baseline; text-align: left; + font-weight: normal; } .rule-details-group--Tb-LW .rule-detail .outcome-chip { vertical-align: middle; diff --git a/src/DetailsView/components/assessment-instance-table.tsx b/src/DetailsView/components/assessment-instance-table.tsx index c3fd59b0136..998e7c28d53 100644 --- a/src/DetailsView/components/assessment-instance-table.tsx +++ b/src/DetailsView/components/assessment-instance-table.tsx @@ -13,6 +13,7 @@ import { IRenderFunction } from '@fluentui/utilities'; import { AssessmentDefaultMessageGenerator } from 'assessments/assessment-default-message-generator'; import { InstanceTableHeaderType, InstanceTableRow } from 'assessments/types/instance-table-data'; import { InsightsCommandButton } from 'common/components/controls/insights-command-button'; +import { FluentUIV9Icon } from 'common/icons/fluentui-v9-icons'; import { ManualTestStatus } from 'common/types/store-data/manual-test-status'; import { hasIn } from 'lodash'; import * as React from 'react'; @@ -125,7 +126,9 @@ export class AssessmentInstanceTable extends React.Component, + }} onClick={this.onPassUnmarkedInstances} disabled={disabled} > diff --git a/src/DetailsView/components/command-bar-buttons-menu.scss b/src/DetailsView/components/command-bar-buttons-menu.scss index 93ca0e64e30..b5183d4665d 100644 --- a/src/DetailsView/components/command-bar-buttons-menu.scss +++ b/src/DetailsView/components/command-bar-buttons-menu.scss @@ -5,16 +5,62 @@ .command-bar-buttons-menu-button { font-size: 16px; + padding: 9px !important; + color: $primary-text !important; + + &:hover { + background-color: $neutral-2 !important; + } + + &:focus { + outline: 1px solid; + } +} + +.menu-list { + top: 19px !important; +} + +.menu-item { + padding-bottom: unset !important; + + &:hover { + background: none !important; + } +} + +.menu-button { + align-items: flex-start !important; + font-weight: 400 !important; + margin-left: -8px !important; + + &:hover { + background: 'none !important'; + color: $insights-button-hover; + + & > span { + & > svg { + color: $insights-button-hover; + } + } + } +} + +.refresh-icon { + color: $insights-button-hover !important; } .command-bar-buttons-submenu { + min-width: fit-content; + button { height: 36px; } - - min-width: fit-content; } .command-bar-buttons-menu { - height: $details-view-command-bar-height; + height: 17px; + margin-left: 9px !important; + margin-top: 8px !important; + margin-bottom: 16px !important; } diff --git a/src/DetailsView/components/command-bar-buttons-menu.tsx b/src/DetailsView/components/command-bar-buttons-menu.tsx index d63904e6627..21d1b682efb 100644 --- a/src/DetailsView/components/command-bar-buttons-menu.tsx +++ b/src/DetailsView/components/command-bar-buttons-menu.tsx @@ -1,13 +1,17 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. import { - CommandBarButton, - IButton, - IContextualMenuItem, - IRefObject, - TooltipHost, -} from '@fluentui/react'; + Menu, + MenuButton, + MenuList, + MenuPopover, + MenuProps, + MenuTrigger, + Tooltip, +} from '@fluentui/react-components'; +import { FluentUIV9Icon } from 'common/icons/fluentui-v9-icons'; import { NamedFC } from 'common/react/named-fc'; +import { ButtonRefFunction } from 'DetailsView/components/details-view-command-bar'; import { StartOverMenuItem } from 'DetailsView/components/start-over-component-factory'; import * as React from 'react'; import styles from './command-bar-buttons-menu.scss'; @@ -18,30 +22,33 @@ export type CommandBarButtonsMenuProps = { loadAssessmentButton?: JSX.Element | null; transferToAssessmentButton?: JSX.Element | null; getStartOverMenuItem: () => StartOverMenuItem; - buttonRef: IRefObject; + buttonRef?: ButtonRefFunction; + hasSubMenu?: boolean; }; export const CommandBarButtonsMenu = NamedFC( 'CommandBarButtonsMenu', props => { + const [open, setOpen] = React.useState(false); + const onOpenChange: MenuProps['onOpenChange'] = (e, data) => setOpen(data.open); const exportButton = props.renderExportReportButton(); - const overflowItems: IContextualMenuItem[] = []; + const overflowItems: any[] = []; if (exportButton != null) { overflowItems.push({ key: 'export report', - onRender: () =>
{exportButton}
, + children: <>{exportButton}, }); } if (props.saveAssessmentButton && props.loadAssessmentButton) { overflowItems.push( { key: 'save assessment', - onRender: () =>
{props.saveAssessmentButton}
, + children: <>{props.saveAssessmentButton}, }, { key: 'load assessment', - onRender: () =>
{props.loadAssessmentButton}
, + children: <>{props.loadAssessmentButton}, }, ); } @@ -49,7 +56,7 @@ export const CommandBarButtonsMenu = NamedFC( if (props.transferToAssessmentButton) { overflowItems.push({ key: 'transfer to assessment', - onRender: () =>
{props.transferToAssessmentButton}
, + children: <>{props.transferToAssessmentButton}, }); } @@ -59,19 +66,33 @@ export const CommandBarButtonsMenu = NamedFC( }); return ( - - - + <> + + + + } + className={styles.commandBarButtonsMenuButton} + ref={() => props.buttonRef} + /> + + + + + {overflowItems.map((item, index) => ( + {item?.children} + ))} + + + + ); }, ); diff --git a/src/DetailsView/components/command-button-styles.tsx b/src/DetailsView/components/command-button-styles.tsx new file mode 100644 index 00000000000..d5ab409246c --- /dev/null +++ b/src/DetailsView/components/command-button-styles.tsx @@ -0,0 +1,27 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +import { makeStyles, tokens } from '@fluentui/react-components'; + +export const useCommandButtonStyle = makeStyles({ + assessmentButton: { + fontWeight: '400 !important', + paddingLeft: '5px !important', + textDecoration: 'none !important', + + '&:focus': { + outline: '1px solid', + }, + + '&:hover': { + background: 'none !important', + color: tokens.colorNeutralForeground2BrandHover, + + '& > span': { + '& >svg': { + color: tokens.colorNeutralForeground2BrandHover, + }, + }, + }, + }, +}); diff --git a/src/DetailsView/components/common-dialog-styles.scss b/src/DetailsView/components/common-dialog-styles.scss index 3647cb137f7..ff960381e2e 100644 --- a/src/DetailsView/components/common-dialog-styles.scss +++ b/src/DetailsView/components/common-dialog-styles.scss @@ -3,13 +3,12 @@ div.insights-dialog-main-override { width: 75%; max-width: 500px; + user-select: text; @media screen and (width <= 500px) { min-width: 240px; width: 75%; } - user-select: text; - .dialog-body { font-size: 16px; } diff --git a/src/DetailsView/components/details-view-command-bar.tsx b/src/DetailsView/components/details-view-command-bar.tsx index a73659ca89f..51765cce4fe 100644 --- a/src/DetailsView/components/details-view-command-bar.tsx +++ b/src/DetailsView/components/details-view-command-bar.tsx @@ -35,6 +35,7 @@ import { SaveAssessmentButtonFactoryDeps, SaveAssessmentButtonFactoryProps, } from 'DetailsView/components/save-assessment-button-factory'; +import { SaveAssessmentDialog } from 'DetailsView/components/save-assessment-dialog'; import { ShouldShowReportExportButtonProps } from 'DetailsView/components/should-show-report-export-button'; import { StartOverFactoryDeps } from 'DetailsView/components/start-over-component-factory'; import { @@ -75,6 +76,7 @@ export type DetailsViewCommandBarState = { isInvalidLoadAssessmentDialogOpen: boolean; isLoadAssessmentDialogOpen: boolean; isReportExportDialogOpen: boolean; + isSaveAssessmentDialogOpen: boolean; loadedAssessmentData: VersionedAssessmentData; startOverDialogState: StartOverDialogState; }; @@ -91,6 +93,8 @@ export type TransferToAssessmentButtonFactory = ( props: TransferToAssessmentButtonProps, ) => JSX.Element | null; +export type ButtonRefFunction = (ref: any) => void; + export interface DetailsViewCommandBarProps { deps: DetailsViewCommandBarDeps; tabStoreData: TabStoreData; @@ -116,6 +120,7 @@ export class DetailsViewCommandBar extends React.Component< public exportDialogCloseFocus?: IButton; public startOverDialogCloseFocus?: IButton; public transferToAssessmentDialogCloseFocus?: IButton; + public loadAssessmentDialogFocus?: IButton; public constructor(props) { super(props); @@ -123,6 +128,7 @@ export class DetailsViewCommandBar extends React.Component< isInvalidLoadAssessmentDialogOpen: false, isLoadAssessmentDialogOpen: false, isReportExportDialogOpen: false, + isSaveAssessmentDialogOpen: false, loadedAssessmentData: {} as VersionedAssessmentData, startOverDialogState: 'none', }; @@ -142,6 +148,7 @@ export class DetailsViewCommandBar extends React.Component< {this.renderLoadAssessmentDialog()} {this.renderStartOverDialog()} {this.renderTransferToAssessmentDialog()} + {this.renderSaveAssessmentDialog()} ); } @@ -262,9 +269,20 @@ export class DetailsViewCommandBar extends React.Component< private renderSaveAssessmentButton = (): JSX.Element | null => { return this.props.switcherNavConfiguration.SaveAssessmentButton({ ...this.props, + handleSaveAssessmentButtonClick: this.handleSaveAssessmentButtonClick, }); }; + private renderSaveAssessmentDialog = (): JSX.Element | null => { + return ( + + ); + }; + private renderTransferToAssessmentButton = (): JSX.Element | null => { return this.props.switcherNavConfiguration.TransferToAssessmentButton({ ...this.props, @@ -326,6 +344,19 @@ export class DetailsViewCommandBar extends React.Component< })); }; + private toggleSaveAssessmentDialog = () => { + this.setState(prevState => ({ + isSaveAssessmentDialogOpen: !prevState.isSaveAssessmentDialogOpen, + })); + }; + + private handleSaveAssessmentButtonClick = (event: React.MouseEvent) => { + this.props.deps.getAssessmentActionMessageCreator().saveAssessment(event); + if (this.props.userConfigurationStoreData.showSaveAssessmentDialog) { + this.toggleSaveAssessmentDialog(); + } + }; + private setAssessmentState = (parsedAssessmentData: VersionedAssessmentData) => { this.setState(_ => ({ loadedAssessmentData: parsedAssessmentData, @@ -382,7 +413,7 @@ export class DetailsViewCommandBar extends React.Component< return { ...this.props, openDialog: this.showStartOverDialog, - buttonRef: ref => (this.startOverDialogCloseFocus = ref), + buttonRef: ref => (this.startOverDialogCloseFocus = ref ?? undefined), }; }; diff --git a/src/DetailsView/components/failure-instance-panel-control.tsx b/src/DetailsView/components/failure-instance-panel-control.tsx index f367db179aa..c0f592590f0 100644 --- a/src/DetailsView/components/failure-instance-panel-control.tsx +++ b/src/DetailsView/components/failure-instance-panel-control.tsx @@ -1,10 +1,11 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -import { ActionButton, Icon, ILabelStyles, ITextFieldStyles, TextField } from '@fluentui/react'; -import { Link } from '@fluentui/react-components'; +import { Icon, ILabelStyles, ITextFieldStyles, TextField } from '@fluentui/react'; +import { Link, Button } from '@fluentui/react-components'; import { AssessmentsProvider } from 'assessments/types/assessments-provider'; import { FlaggedComponent } from 'common/components/flagged-component'; import { FeatureFlags } from 'common/feature-flags'; +import { FluentUIV9Icon } from 'common/icons/fluentui-v9-icons'; import { CapturedInstanceActionType } from 'common/types/captured-instance-action-type'; import { FailureInstanceData } from 'common/types/failure-instance-data'; import { FeatureFlagStoreData } from 'common/types/store-data/feature-flag-store-data'; @@ -15,7 +16,6 @@ import { ActionAndCancelButtonsComponent } from './action-and-cancel-buttons-com import { FailureInstancePanelDetails } from './failure-instance-panel-details'; import styles from './failure-instance-panel.scss'; import { GenericPanel, GenericPanelProps } from './generic-panel'; - export interface FailureInstancePanelControlProps { step: string; test: VisualizationType; @@ -83,19 +83,20 @@ export class FailureInstancePanelControl extends React.Component< private renderButton(): JSX.Element { if (this.props.actionType === CapturedInstanceActionType.CREATE) { return ( - } onClick={this.openFailureInstancePanel} > {FailureInstancePanelControl.addFailureInstanceLabel} - + ); } else { return ( - + ); } @@ -207,7 +208,7 @@ export class FailureInstancePanelControl extends React.Component< }); }; - private onValidateSelector = (event): void => { + private onValidateSelector = (): void => { this.props.addPathForValidation(this.state.currentInstance.path); }; diff --git a/src/DetailsView/components/iframe-warning.tsx b/src/DetailsView/components/iframe-warning.tsx index 21a7f19eb42..707e64ba013 100644 --- a/src/DetailsView/components/iframe-warning.tsx +++ b/src/DetailsView/components/iframe-warning.tsx @@ -19,7 +19,11 @@ export const IframeWarningContainerAutomationId = 'iframe-warning-container'; export const IframeWarning = NamedFC('IframeWarning', props => (
There are iframes in the target page. To have complete results,{' '} - + give Accessibility Insights additional permissions ; this will trigger a rescan of the test. diff --git a/src/DetailsView/components/inline-start-over-button.tsx b/src/DetailsView/components/inline-start-over-button.tsx index 7e98b66b229..a2438ffb3ce 100644 --- a/src/DetailsView/components/inline-start-over-button.tsx +++ b/src/DetailsView/components/inline-start-over-button.tsx @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. - import { InsightsCommandButton } from 'common/components/controls/insights-command-button'; +import { FluentUIV9Icon } from 'common/icons/fluentui-v9-icons'; import { NamedFC } from 'common/react/named-fc'; import { VisualizationType } from 'common/types/visualization-type'; import { DetailsViewActionMessageCreator } from 'DetailsView/actions/details-view-action-message-creator'; @@ -23,11 +23,14 @@ export const InlineStartOverButton = NamedFC( return ( , + }} className={styles.inlineStartOverButton} data-automation-id={inlineStartOverButtonDataAutomationId} - /> + > + Start over + ); }, ); diff --git a/src/DetailsView/components/load-assessment-button.tsx b/src/DetailsView/components/load-assessment-button.tsx index 4c23fa027fb..37a0d5f5959 100644 --- a/src/DetailsView/components/load-assessment-button.tsx +++ b/src/DetailsView/components/load-assessment-button.tsx @@ -1,12 +1,16 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. - import { AssessmentDataParser } from 'common/assessment-data-parser'; import { InsightsCommandButton } from 'common/components/controls/insights-command-button'; +import { FluentUIV9Icon } from 'common/icons/fluentui-v9-icons'; +import { NamedFC } from 'common/react/named-fc'; import { AssessmentStoreData } from 'common/types/store-data/assessment-result-data'; import { TabStoreData } from 'common/types/store-data/tab-store-data'; import { UrlParser } from 'common/url-parser'; import { DetailsViewActionMessageCreator } from 'DetailsView/actions/details-view-action-message-creator'; +import { useCommandButtonStyle } from 'DetailsView/components/command-button-styles'; +import { ButtonRefFunction } from 'DetailsView/components/details-view-command-bar'; + import { LoadAssessmentHelper } from 'DetailsView/components/load-assessment-helper'; import * as React from 'react'; @@ -21,20 +25,29 @@ export interface LoadAssessmentButtonProps { tabStoreData: TabStoreData; assessmentStoreData: AssessmentStoreData; handleLoadAssessmentButtonClick: () => void; + isNarrowMode?: boolean; + buttonRef?: ButtonRefFunction; } export const loadAssessmentButtonAutomationId = 'load-assessment-button'; -export class LoadAssessmentButton extends React.Component { - public render(): JSX.Element { +export const LoadAssessmentButton = NamedFC( + 'LoadAssessmentButton', + props => { + const loadButtonStyles = useCommandButtonStyle(); return ( , + }} + onClick={props.handleLoadAssessmentButtonClick} + className={loadButtonStyles.assessmentButton} + ref={props.buttonRef} + {...props} > Load assessment ); - } -} + }, +); diff --git a/src/DetailsView/components/report-export-button.tsx b/src/DetailsView/components/report-export-button.tsx index 2f7e538a71d..9d101596389 100644 --- a/src/DetailsView/components/report-export-button.tsx +++ b/src/DetailsView/components/report-export-button.tsx @@ -1,24 +1,34 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -import { IButton, IRefObject } from '@fluentui/react'; import { InsightsCommandButton } from 'common/components/controls/insights-command-button'; +import { FluentUIV9Icon } from 'common/icons/fluentui-v9-icons'; import { NamedFC } from 'common/react/named-fc'; +import { useCommandButtonStyle } from 'DetailsView/components/command-button-styles'; +import { ButtonRefFunction } from 'DetailsView/components/details-view-command-bar'; import * as React from 'react'; export interface ReportExportButtonProps { showReportExportDialog: () => void; - buttonRef?: IRefObject; + buttonRef?: ButtonRefFunction; + isNarrowMode?: boolean; } export const reportExportButtonAutomationId = 'report-export-button'; export const ReportExportButton = NamedFC('ReportExportButton', props => { + const exportButtonStyles = useCommandButtonStyle(); + return ( , + }} onClick={props.showReportExportDialog} - componentRef={props.buttonRef} + ref={props.buttonRef} data-automation-id={reportExportButtonAutomationId} + id={reportExportButtonAutomationId} + className={exportButtonStyles.assessmentButton} + {...props} > Export result diff --git a/src/DetailsView/components/requirement-instructions.scss b/src/DetailsView/components/requirement-instructions.scss index 86cba129b64..8569cd4ed9d 100644 --- a/src/DetailsView/components/requirement-instructions.scss +++ b/src/DetailsView/components/requirement-instructions.scss @@ -9,6 +9,7 @@ line-height: 20px; padding-left: 0.5vw; display: block; + color: $neutral-80; } .requirement-instructions { diff --git a/src/DetailsView/components/requirement-view-next-requirement-configuration.tsx b/src/DetailsView/components/requirement-view-next-requirement-configuration.tsx index 72182239a06..9cc4ac93a44 100644 --- a/src/DetailsView/components/requirement-view-next-requirement-configuration.tsx +++ b/src/DetailsView/components/requirement-view-next-requirement-configuration.tsx @@ -1,6 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -import { PrimaryButton } from '@fluentui/react'; +import { Button } from '@fluentui/react-components'; import { AutomatedChecks } from 'assessments/automated-checks/assessment'; import { AssessmentsProvider } from 'assessments/types/assessments-provider'; import { Assessment } from 'assessments/types/iassessment'; @@ -71,14 +71,17 @@ export const getNextRequirementConfigurationForQuickAssess = ( ); if (requirementIndex === props.deps.quickAssessRequirementKeys.length - 1) { return ( - + > + Complete + ); } diff --git a/src/DetailsView/components/requirement-view.scss b/src/DetailsView/components/requirement-view.scss index ee2cedab751..1cffedec0b1 100644 --- a/src/DetailsView/components/requirement-view.scss +++ b/src/DetailsView/components/requirement-view.scss @@ -33,13 +33,13 @@ } .requirement-content { + padding-left: 32px; + @media screen and (width >= 1200px) { display: grid; grid-template-columns: 1fr 308px; } - padding-left: 32px; - .main-content { margin-top: 10px; width: 90%; diff --git a/src/DetailsView/components/save-assessment-button-factory.tsx b/src/DetailsView/components/save-assessment-button-factory.tsx index 9cba012860d..64090972935 100644 --- a/src/DetailsView/components/save-assessment-button-factory.tsx +++ b/src/DetailsView/components/save-assessment-button-factory.tsx @@ -24,6 +24,8 @@ export type SaveAssessmentButtonFactoryProps = { assessmentStoreData: AssessmentStoreData; tabStoreData: TabStoreData; userConfigurationStoreData: UserConfigurationStoreData; + isNarrowMode?: boolean; + handleSaveAssessmentButtonClick: (event: React.MouseEvent) => void; }; export function getSaveButtonForAssessment(props: SaveAssessmentButtonFactoryProps): JSX.Element { diff --git a/src/DetailsView/components/save-assessment-button.tsx b/src/DetailsView/components/save-assessment-button.tsx index c654dea7bb0..0c15a21f88d 100644 --- a/src/DetailsView/components/save-assessment-button.tsx +++ b/src/DetailsView/components/save-assessment-button.tsx @@ -1,13 +1,13 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -import { Checkbox, Dialog, DialogFooter, DialogType, PrimaryButton, Stack } from '@fluentui/react'; -import { useBoolean } from '@fluentui/react-hooks'; import { InsightsCommandButton } from 'common/components/controls/insights-command-button'; +import { FluentUIV9Icon } from 'common/icons/fluentui-v9-icons'; import { UserConfigMessageCreator } from 'common/message-creators/user-config-message-creator'; import { NamedFC } from 'common/react/named-fc'; import { UserConfigurationStoreData } from 'common/types/store-data/user-configuration-store'; import { AssessmentActionMessageCreator } from 'DetailsView/actions/assessment-action-message-creator'; -import styles from 'DetailsView/components/common-dialog-styles.scss'; +import { useCommandButtonStyle } from 'DetailsView/components/command-button-styles'; + import * as React from 'react'; export interface SaveAssessmentButtonDeps { @@ -19,75 +19,29 @@ export interface SaveAssessmentButtonProps { href: string; deps: SaveAssessmentButtonDeps; userConfigurationStoreData: UserConfigurationStoreData; + handleSaveAssessmentButtonClick: (event: React.MouseEvent) => void; + isNarrowMode?: boolean; + buttonRef?: React.RefObject; } export const SaveAssessmentButton = NamedFC( 'SaveAssessmentButton', props => { - const [dialogHidden, { setTrue: hideDialog, setFalse: showDialog }] = useBoolean(true); - - function handleSaveAssessmentClick(event: React.MouseEvent) { - props.deps.getAssessmentActionMessageCreator().saveAssessment(event); - if (props.userConfigurationStoreData.showSaveAssessmentDialog) { - showDialog(); - } - } - - function handleDontShowAgainClick(event: React.MouseEvent, checked?: boolean) { - if (checked === undefined) return; - props.deps.userConfigMessageCreator.setSaveAssessmentDialogState(!checked); - } + const saveAssessmentStyles = useCommandButtonStyle(); return ( - <> - - Save assessment - - - + , + }} + ref={props.buttonRef} + {...props} + > + Save assessment + ); }, ); diff --git a/src/DetailsView/components/save-assessment-dialog.tsx b/src/DetailsView/components/save-assessment-dialog.tsx new file mode 100644 index 00000000000..5399718dec2 --- /dev/null +++ b/src/DetailsView/components/save-assessment-dialog.tsx @@ -0,0 +1,76 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +import { Checkbox, Dialog, DialogFooter, DialogType, PrimaryButton, Stack } from '@fluentui/react'; +import { UserConfigMessageCreator } from 'common/message-creators/user-config-message-creator'; +import { NamedFC } from 'common/react/named-fc'; +import { UserConfigurationStoreData } from 'common/types/store-data/user-configuration-store'; +import { AssessmentActionMessageCreator } from 'DetailsView/actions/assessment-action-message-creator'; +import styles from 'DetailsView/components/common-dialog-styles.scss'; +import * as React from 'react'; + +export type SaveAssessmentDialogDeps = { + getAssessmentActionMessageCreator: () => AssessmentActionMessageCreator; + userConfigMessageCreator: UserConfigMessageCreator; +}; + +export const saveAssessmentDialogLoadButtonAutomationId = 'save-assessment-dialog-load-button'; +export interface SaveAssessmentDialogProps { + deps: SaveAssessmentDialogDeps; + isOpen: boolean; + onClose: () => void; + userConfigurationStoreData: UserConfigurationStoreData; +} + +export const SaveAssessmentDialog = NamedFC( + 'SaveAssessmentDialog', + props => { + function handleDontShowAgainClick(event: React.MouseEvent, checked?: boolean) { + if (checked === undefined) return; + props.deps.userConfigMessageCreator.setSaveAssessmentDialogState(!checked); + } + return ( + <> + + + ); + }, +); diff --git a/src/DetailsView/components/start-over-component-factory.tsx b/src/DetailsView/components/start-over-component-factory.tsx index d610fded63c..2d381389354 100644 --- a/src/DetailsView/components/start-over-component-factory.tsx +++ b/src/DetailsView/components/start-over-component-factory.tsx @@ -1,11 +1,13 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -import { IButton, IContextualMenuItem, IRefObject } from '@fluentui/react'; +import { IContextualMenuItem } from '@fluentui/react'; import { AssessmentsProvider } from 'assessments/types/assessments-provider'; import { InsightsCommandButton } from 'common/components/controls/insights-command-button'; +import { FluentUIV9Icon } from 'common/icons/fluentui-v9-icons'; import { AssessmentStoreData } from 'common/types/store-data/assessment-result-data'; import { VisualizationStoreData } from 'common/types/store-data/visualization-store-data'; import { DetailsViewActionMessageCreator } from 'DetailsView/actions/details-view-action-message-creator'; +import { ButtonRefFunction } from 'DetailsView/components/details-view-command-bar'; import { DetailsRightPanelConfiguration } from 'DetailsView/components/details-view-right-panel'; import { StartOverDialogType } from 'DetailsView/components/start-over-dialog'; import { @@ -27,7 +29,9 @@ export type StartOverFactoryProps = { rightPanelConfiguration: DetailsRightPanelConfiguration; visualizationStoreData: VisualizationStoreData; openDialog: (dialogType: StartOverDialogType) => void; - buttonRef: IRefObject; + buttonRef: ButtonRefFunction; + hasSubMenu?: boolean; + isNarrowMode?: boolean; }; export type StartOverMenuItem = Omit; @@ -41,9 +45,7 @@ export const AssessmentStartOverFactory: StartOverComponentFactory = { getStartOverComponent: props => getStartOverComponentForAssessment(props, 'down'), getStartOverMenuItem: props => { return { - onRender: () => ( -
{getStartOverComponentForAssessment(props, 'left')}
- ), + children:
{getStartOverComponentForAssessment(props, 'left')}
, }; }, }; @@ -52,26 +54,41 @@ export const QuickAssessStartOverFactory: StartOverComponentFactory = { getStartOverComponent: props => getStartOverComponentForQuickAssess(props, 'down'), getStartOverMenuItem: props => { return { - onRender: () => ( -
{getStartOverComponentForQuickAssess(props, 'left')}
- ), + children:
{getStartOverComponentForQuickAssess(props, 'left')}
, }; }, }; export const FastpassStartOverFactory: StartOverComponentFactory = { - getStartOverComponent: props => { - return ; + getStartOverComponent: props => getStartOverComponentFastPass(props), + getStartOverMenuItem: props => { + return { + children:
{getStartOverComponentFastPass(props)}
, + }; }, - getStartOverMenuItem: getStartOverPropsForFastPass, }; +export function getStartOverComponentFastPass(props: StartOverFactoryProps): JSX.Element { + const startOverProps = getStartOverPropsForFastPass(props); + return ( + , + }} + {...startOverProps} + > + {startOverProps.text} + + ); +} + export function getStartOverComponentForAssessment( props: StartOverFactoryProps, dropdownDirection: DropdownDirection, ): JSX.Element { const selectedTest = props.assessmentStoreData.assessmentNavState.selectedTestType; const test = props.deps.getProvider().forType(selectedTest); + const startOverProps: StartOverProps = { singleTestSuffix: test!.title, allTestSuffix: 'Assessment', @@ -80,6 +97,8 @@ export function getStartOverComponentForAssessment( buttonRef: props.buttonRef, rightPanelOptions: props.rightPanelConfiguration.startOverContextMenuKeyOptions, switcherStartOverPreferences: { showTest: true }, + hasSubMenu: props.hasSubMenu, + isNarrowMode: props.isNarrowMode, }; return ; @@ -101,6 +120,8 @@ export function getStartOverComponentForQuickAssess( buttonRef: props.buttonRef, rightPanelOptions: props.rightPanelConfiguration.startOverContextMenuKeyOptions, switcherStartOverPreferences: { showTest }, + hasSubMenu: props.hasSubMenu, + isNarrowMode: props.isNarrowMode, }; return ; @@ -119,5 +140,6 @@ export function getStartOverPropsForFastPass(props: StartOverFactoryProps): Star 'data-automation-id': startOverAutomationId, text: 'Start over', className: styles.startOverMenuItem, + isNarrowMode: props.isNarrowMode, }; } diff --git a/src/DetailsView/components/start-over-dropdown-styles.tsx b/src/DetailsView/components/start-over-dropdown-styles.tsx new file mode 100644 index 00000000000..ffcb99cf455 --- /dev/null +++ b/src/DetailsView/components/start-over-dropdown-styles.tsx @@ -0,0 +1,57 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +import { makeStyles, tokens } from '@fluentui/react-components'; + +export const useStartOverDropdownStyles: any = makeStyles({ + menuButton: { + alignItems: 'flex-start !important', + fontWeight: '400 !important', + color: tokens.colorNeutralForeground2, + paddingLeft: '4px', + + ':focus': { + outline: '1px solid', + }, + + ':hover': { + background: 'none !important', + color: tokens.colorNeutralForeground2BrandHover, + + '& > span': { + '& > svg': { + color: tokens.colorNeutralForeground2BrandHover, + }, + }, + }, + }, + + chevronIcon: { + color: tokens.colorNeutralForeground2, + + ':hover': { + background: 'none !important', + color: tokens.colorNeutralForeground2BrandHover, + }, + }, + + defaultChevron: { + color: `${tokens.colorNeutralStrokeAccessible} !important`, + + ':hover': { + color: `unset !important`, + }, + }, + + menuPopover: { + borderRadius: tokens.borderRadiusNone, + }, + + menuItem: { + borderRadius: tokens.borderRadiusNone, + + ':hover': { + backgroundColor: 'unset !important', + }, + }, +}); diff --git a/src/DetailsView/components/start-over-dropdown.tsx b/src/DetailsView/components/start-over-dropdown.tsx index 438e0931e1f..ab329c243f8 100644 --- a/src/DetailsView/components/start-over-dropdown.tsx +++ b/src/DetailsView/components/start-over-dropdown.tsx @@ -1,32 +1,45 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +import { DirectionalHint } from '@fluentui/react'; + import { - ContextualMenu, - DirectionalHint, - IButton, - IContextualMenuItem, - IRefObject, -} from '@fluentui/react'; -import { IPoint } from '@fluentui/utilities'; -import { InsightsCommandButton } from 'common/components/controls/insights-command-button'; + Menu, + MenuButton, + MenuItem, + MenuItemProps, + MenuList, + MenuPopover, + MenuTrigger, +} from '@fluentui/react-components'; + +import { FluentUIV9Icon } from 'common/icons/fluentui-v9-icons'; +import { NamedFC } from 'common/react/named-fc'; +import { ButtonRefFunction } from 'DetailsView/components/details-view-command-bar'; import { StartOverDialogType } from 'DetailsView/components/start-over-dialog'; +import { useStartOverDropdownStyles } from 'DetailsView/components/start-over-dropdown-styles'; import * as React from 'react'; import { StartOverContextMenuKeyOptions } from './details-view-right-panel'; +export type StartOverDropdownMenuItems = MenuItemProps & { + name: string; +}; + export interface StartOverState { isContextMenuVisible: boolean; - target?: HTMLElement | string | MouseEvent | IPoint | null; + target?: HTMLElement | string | MouseEvent | null; } export interface StartOverProps { singleTestSuffix: string; dropdownDirection: DropdownDirection; openDialog: (dialogType: StartOverDialogType) => void; - buttonRef: IRefObject; + buttonRef?: ButtonRefFunction; allTestSuffix: string; rightPanelOptions: StartOverContextMenuKeyOptions; switcherStartOverPreferences: StartOverContextMenuKeyOptions; + hasSubMenu?: boolean; + isNarrowMode?: boolean; } const dropdownDirections = { @@ -42,70 +55,26 @@ const dropdownDirections = { export type DropdownDirection = keyof typeof dropdownDirections; -export class StartOverDropdown extends React.Component { - constructor(props: StartOverProps) { - super(props); - - this.state = { - isContextMenuVisible: false, - }; - } - - public render(): JSX.Element { - const direction = this.props.dropdownDirection; - return ( -
- - {this.renderContextMenu()} -
- ); - } - - private renderContextMenu(): JSX.Element | null { - if (!this.state.isContextMenuVisible) { - return null; - } - - const direction = this.props.dropdownDirection; - - return ( - this.dismissDropdown()} - target={this.state.target} - items={this.getMenuItems()} - directionalHint={dropdownDirections[direction].directionalHint} - /> - ); - } - - private getMenuItems(): IContextualMenuItem[] { +export const StartOverDropdown = NamedFC('StartOverDropdown', props => { + const stylesValue: any = useStartOverDropdownStyles(); + const direction = props.dropdownDirection; + const getMenuItemsV9 = (): StartOverDropdownMenuItems[] => { const { singleTestSuffix, allTestSuffix, rightPanelOptions, switcherStartOverPreferences: startOverButtonOptionPreferences, - } = this.props; - const items: IContextualMenuItem[] = []; + } = props; + const items: StartOverDropdownMenuItems[] = []; const assessmentKey = { key: 'assessment', name: `Start over ${allTestSuffix}`, - onClick: this.onStartOverAllTestsMenu, + onClick: onStartOverAllTestsMenu, }; const testKey = { key: 'test', name: `Start over ${singleTestSuffix}`, - onClick: this.onStartOverTestMenu, + onClick: onStartOverTestMenu, }; items.push(assessmentKey); @@ -115,21 +84,59 @@ export class StartOverDropdown extends React.Component { - this.props.openDialog('test'); }; - private onStartOverAllTestsMenu = (): void => { - this.props.openDialog('assessment'); + const onStartOverTestMenu = (): void => { + props.openDialog('test'); }; - private openDropdown = (event): void => { - this.setState({ target: event.currentTarget, isContextMenuVisible: true }); + const onStartOverAllTestsMenu = (): void => { + props.openDialog('assessment'); }; - - private dismissDropdown(): void { - this.setState({ target: null, isContextMenuVisible: false }); - } -} + return ( +
+ + + } + aria-label="start over menu" + menuIcon={ + direction === 'left' ? ( + + ) : ( + + ) + } + > + Start over + + + + + {getMenuItemsV9().map(item => ( + + {item.name} + + ))} + + + +
+ ); +}); diff --git a/src/DetailsView/components/start-over-menu-item.scss b/src/DetailsView/components/start-over-menu-item.scss index 98d78dbb984..7a7915242c4 100644 --- a/src/DetailsView/components/start-over-menu-item.scss +++ b/src/DetailsView/components/start-over-menu-item.scss @@ -3,8 +3,23 @@ @import '../../common/styles/colors.scss'; .start-over-menu-item { + font-weight: 400 !important; + padding-left: 3px !important; + + &:hover { + background: none !important; + color: $insights-button-hover !important; + + & > span { + & > svg { + color: $insights-button-hover; + } + } + } + .start-over-menu-item-icon { line-height: 16px; + margin-left: -8px !important; } button:disabled, diff --git a/src/DetailsView/components/static-content-common.scss b/src/DetailsView/components/static-content-common.scss index 6e19200fead..4baec46015d 100644 --- a/src/DetailsView/components/static-content-common.scss +++ b/src/DetailsView/components/static-content-common.scss @@ -8,6 +8,8 @@ padding-right: $fast-pass-right-panel-margin-right; padding-left: $fast-pass-right-panel-margin-left; margin-bottom: auto; + background-color: $neutral-2; + height: 100%; ol { -webkit-padding-start: 16px; // Chrome versions before 87 use non-standard name: https://caniuse.com/mdn-css_properties_padding-inline-start @@ -21,9 +23,6 @@ i { font-size: 16px; } - - background-color: $neutral-2; - height: 100%; } .details-view-toggle { diff --git a/src/DetailsView/components/tab-stops/tab-stops-instance-section-props-factory.tsx b/src/DetailsView/components/tab-stops/tab-stops-instance-section-props-factory.tsx index 52855af3dae..c1400225d36 100644 --- a/src/DetailsView/components/tab-stops/tab-stops-instance-section-props-factory.tsx +++ b/src/DetailsView/components/tab-stops/tab-stops-instance-section-props-factory.tsx @@ -79,7 +79,7 @@ export const FastPassTabStopsInstanceSectionPropsFactory: TabStopsInstanceSectio buttonAriaLabel: buttonAriaLabel, headingLevel, deps: deps, - onExpandToggle: (event: React.MouseEvent) => { + onExpandToggle: (event: React.MouseEvent) => { deps.tabStopRequirementActionMessageCreator!.toggleTabStopRequirementExpand( result.id, event, diff --git a/src/DetailsView/components/transfer-to-assessment-button.tsx b/src/DetailsView/components/transfer-to-assessment-button.tsx index d5901d940ed..95fbb73f66e 100644 --- a/src/DetailsView/components/transfer-to-assessment-button.tsx +++ b/src/DetailsView/components/transfer-to-assessment-button.tsx @@ -1,19 +1,21 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -import { IRefObject, IButton } from '@fluentui/react'; import { InsightsCommandButton } from 'common/components/controls/insights-command-button'; +import { FluentUIV9Icon } from 'common/icons/fluentui-v9-icons'; import { NamedFC } from 'common/react/named-fc'; +import { useCommandButtonStyle } from 'DetailsView/components/command-button-styles'; +import { ButtonRefFunction } from 'DetailsView/components/details-view-command-bar'; import { DataTransferViewController } from 'DetailsView/data-transfer-view-controller'; import * as React from 'react'; export type TransferToAssessmentButtonDeps = { dataTransferViewController: DataTransferViewController; }; - export interface TransferToAssessmentButtonProps { deps: TransferToAssessmentButtonDeps; - buttonRef?: IRefObject; + buttonRef?: ButtonRefFunction; + isNarrowMode?: boolean; } export const transferToAssessmentButtonAutomationId = 'transfer-to-assessment-button'; @@ -21,14 +23,20 @@ export const transferToAssessmentButtonAutomationId = 'transfer-to-assessment-bu export const TransferToAssessmentButton = NamedFC( 'TransferToAssessmentButton', props => { + const saveAssessmentStyles = useCommandButtonStyle(); + return ( , + }} onClick={ props.deps.dataTransferViewController.showQuickAssessToAssessmentConfirmDialog } - componentRef={props.buttonRef} + ref={props.buttonRef} + isNarrowMode={props.isNarrowMode} > Move to assessment diff --git a/src/common/components/cards/card-footer-instance-action-buttons.scss b/src/common/components/cards/card-footer-instance-action-buttons.scss index 98e7830d437..b41623a07ca 100644 --- a/src/common/components/cards/card-footer-instance-action-buttons.scss +++ b/src/common/components/cards/card-footer-instance-action-buttons.scss @@ -11,14 +11,44 @@ @media screen and (forced-colors: active) { color: buttontext !important; } +} + +.fileissue { + font-weight: 400 !important; &:hover { - border-style: solid !important; - border-width: 1px; - padding-left: 8px !important; - padding-right: 8px !important; - padding-top: 5px !important; - padding-bottom: 5px !important; + & > span { + & > svg { + color: $insights-button-hover; + } + } + } + + &:focus { + outline: 1px solid; + } +} + +.copyfailuredetails { + font-weight: 400 !important; + + &:hover { + & > span { + & > svg { + color: $insights-button-hover; + } + } + } +} + +.menu-Button { + &:hover { + border: 1px solid $primary-text !important; + color: $primary-text !important; + } + + &:focus { + outline: 1px solid; } } diff --git a/src/common/components/cards/card-footer-instance-action-buttons.tsx b/src/common/components/cards/card-footer-instance-action-buttons.tsx index 2b61787c9c1..8aacb1e4a35 100644 --- a/src/common/components/cards/card-footer-instance-action-buttons.tsx +++ b/src/common/components/cards/card-footer-instance-action-buttons.tsx @@ -1,14 +1,24 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -import { ActionButton, DirectionalHint, IButton } from '@fluentui/react'; import { registerIcons } from '@fluentui/react/lib/Styling'; import { - CardFooterMenuItem, + Button, + Menu, + MenuButton, + MenuItem, + MenuList, + MenuPopover, + MenuTrigger, + tokens, +} from '@fluentui/react-components'; +import { CardFooterMenuItemsBuilder, CardFooterMenuItemsDeps, } from 'common/components/cards/card-footer-menu-items-builder'; import { CardsViewController } from 'common/components/cards/cards-view-controller'; +import { FluentUIV9Icon } from 'common/icons/fluentui-v9-icons'; import { MoreActionsMenuIcon } from 'common/icons/more-actions-menu-icon'; +import { NamedFC } from 'common/react/named-fc'; import { NarrowModeStatus } from 'DetailsView/components/narrow-mode-detector'; import * as React from 'react'; import { CreateIssueDetailsTextData } from '../../types/create-issue-details-text-data'; @@ -38,102 +48,113 @@ export interface CardFooterInstanceActionButtonsProps { narrowModeStatus?: NarrowModeStatus; } -export class CardFooterInstanceActionButtons extends React.Component { - private toastRef: React.RefObject; - private fileIssueButtonRef: IButton | null; - private kebabButtonRef: IButton | null; - constructor(props: CardFooterInstanceActionButtonsProps) { - super(props); - this.toastRef = React.createRef(); - } +export const CardFooterInstanceActionButtons = NamedFC( + 'CardFooterInstanceActionButtonsProps', + props => { + const toastRef = React.useRef(null); + const fileIssueButtonRef: any = React.useRef(null); + const kebabButtonRef: any = React.useRef(null); - public render(): JSX.Element | null { - const menuItems = this.getMenuItems(); - if (menuItems.length === 0) { - return null; - } + const focusButtonAfterDialogClosed = (): void => { + if (props?.narrowModeStatus?.isCardFooterCollapsed) { + kebabButtonRef?.current?.focus(); + } else { + fileIssueButtonRef?.current?.focus(); + } + }; - return ( - // The wrapper has to be a real element, not a <>, because we want the placeholder elements - // the dialog/toast involve to be considered as part of the button for the purposes of layout - // calculation in this component's parent. -
event.stopPropagation()}> - {this.renderButtons()} - {this.renderCopyFailureDetailsToast()} -
- ); - } + const getMenuItems = () => { + return props.deps.cardFooterMenuItemsBuilder.getCardFooterMenuItems({ + ...props, + toastRef: toastRef, + fileIssueButtonRef: ref => (fileIssueButtonRef.current = ref), + onIssueFilingSettingsDialogDismissed: focusButtonAfterDialogClosed, + }); + }; - public renderButtons(): JSX.Element { - if (this.props.narrowModeStatus?.isCardFooterCollapsed) { - return this.renderKebabButton(); - } else { - return this.renderExpandedButtons(); - } - } + const renderCopyFailureDetailsToast = () => { + const { cardInteractionSupport } = props.deps; - public renderKebabButton(): JSX.Element { - return ( - (this.kebabButtonRef = ref)} - ariaLabel={this.props.kebabMenuAriaLabel || 'More actions'} - menuIconProps={{ - iconName: 'MoreActionsMenuIcon', - className: styles.kebabMenuIcon, - }} - menuProps={{ - directionalHint: DirectionalHint.bottomRightEdge, - shouldFocusOnMount: true, - items: this.getMenuItems(), - }} - /> - ); - } + if (!cardInteractionSupport.supportsCopyFailureDetails) { + return null; + } - public renderExpandedButtons(): JSX.Element { - const menuItems = this.getMenuItems(); + return ; + }; - return ( - <> - {menuItems.map(props => ( - - { + return ( + + + (kebabButtonRef.current = ref)} + appearance="transparent" + shape="square" + aria-label={props?.kebabMenuAriaLabel} + icon={} /> - - ))} - - ); - } - - public renderCopyFailureDetailsToast(): JSX.Element | null { - const { cardInteractionSupport } = this.props.deps; + + + + {getMenuItems().map((item: any, index: number) => ( + } + {...item} + > + {item?.text} + + ))} + + + + ); + }; - if (!cardInteractionSupport.supportsCopyFailureDetails) { - return null; - } + const renderExpandedButtons = () => { + const menuItems = getMenuItems(); + return ( + <> + {menuItems.map(menuItem => ( + + ))} + + ); + }; - return ; - } + const renderButtons = () => { + if (props.narrowModeStatus?.isCardFooterCollapsed) { + return renderKebabButton(); + } else { + return renderExpandedButtons(); + } + }; - private getMenuItems(): CardFooterMenuItem[] { - return this.props.deps.cardFooterMenuItemsBuilder.getCardFooterMenuItems({ - ...this.props, - toastRef: this.toastRef, - fileIssueButtonRef: ref => (this.fileIssueButtonRef = ref), - onIssueFilingSettingsDialogDismissed: this.focusButtonAfterDialogClosed, - }); - } + const menuItems = getMenuItems(); + const menuItemsJsx = + menuItems?.length === 0 ? null : ( +
event.stopPropagation()}> + {renderButtons()} + {renderCopyFailureDetailsToast()} +
+ ); - private focusButtonAfterDialogClosed = (): void => { - if (this.props.narrowModeStatus?.isCardFooterCollapsed) { - this.kebabButtonRef?.focus(); - } else { - this.fileIssueButtonRef?.focus(); - } - }; -} + return menuItemsJsx; + }, +); diff --git a/src/common/components/cards/card-footer-menu-items-builder.ts b/src/common/components/cards/card-footer-menu-items-builder.ts index e602a20f446..62471a69d31 100644 --- a/src/common/components/cards/card-footer-menu-items-builder.ts +++ b/src/common/components/cards/card-footer-menu-items-builder.ts @@ -1,13 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -import { - IButton, - IButtonProps, - IContextualMenuItem, - IContextualMenuRenderItem, - IRefObject, -} from '@fluentui/react'; +import { IButtonProps, IContextualMenuItem } from '@fluentui/react'; import { IssueDetailsTextGenerator } from 'background/issue-details-text-generator'; import { CardInteractionSupport } from 'common/components/cards/card-interaction-support'; import { CardsViewController } from 'common/components/cards/cards-view-controller'; @@ -18,13 +12,14 @@ import { CreateIssueDetailsTextData } from 'common/types/create-issue-details-te import { ToolData } from 'common/types/store-data/unified-data-interface'; import { UserConfigurationStoreData } from 'common/types/store-data/user-configuration-store'; import { DetailsViewActionMessageCreator } from 'DetailsView/actions/details-view-action-message-creator'; +import { ButtonRefFunction } from 'DetailsView/components/details-view-command-bar'; import { IssueFilingServiceProvider } from 'issue-filing/issue-filing-service-provider'; import React from 'react'; export type CardFooterMenuItem = IContextualMenuItem & IButtonProps; export type CardFooterMenuItemsProps = { - fileIssueButtonRef: IRefObject & IRefObject; + fileIssueButtonRef: ButtonRefFunction; toastRef: React.RefObject; issueDetailsData: CreateIssueDetailsTextData; userConfigurationStoreData: UserConfigurationStoreData | null; @@ -54,11 +49,9 @@ export class CardFooterMenuItemsBuilder { items.push({ key: 'fileissue', text: 'File issue', - iconProps: { - iconName: 'ladybugSolid', - }, + iconName: 'BugFilled', onClick: event => this.fileIssue(props, event), - componentRef: props.fileIssueButtonRef, + componentRef: () => props.fileIssueButtonRef, }); } @@ -66,9 +59,7 @@ export class CardFooterMenuItemsBuilder { items.push({ key: 'copyfailuredetails', text: `Copy failure details`, - iconProps: { - iconName: 'copy', - }, + iconName: 'DocumentCopyRegular', onClick: event => void this.copyFailureDetails(props, event), }); } diff --git a/src/common/components/cards/collapsible-component-cards.scss b/src/common/components/cards/collapsible-component-cards.scss index 7a08179bd9e..767121076ca 100644 --- a/src/common/components/cards/collapsible-component-cards.scss +++ b/src/common/components/cards/collapsible-component-cards.scss @@ -36,8 +36,9 @@ border: none; display: flex; align-items: baseline; - width: 100%; + width: auto; height: fit-content; + margin-left: -5px; &:hover { background-color: $neutral-alpha-4; @@ -58,7 +59,7 @@ } .collapsible-container-content { - margin-left: 24px; + margin-left: 27px; &[aria-hidden='true'] { display: none; diff --git a/src/common/components/cards/collapsible-component-cards.tsx b/src/common/components/cards/collapsible-component-cards.tsx index db55a829077..abb81b60c5d 100644 --- a/src/common/components/cards/collapsible-component-cards.tsx +++ b/src/common/components/cards/collapsible-component-cards.tsx @@ -1,6 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -import { ActionButton } from '@fluentui/react'; +import { Button } from '@fluentui/react-components'; import { css } from '@fluentui/utilities'; import { HeadingElementForLevel, HeadingLevel } from 'common/components/heading-element-for-level'; import { NamedFC } from 'common/react/named-fc'; @@ -24,7 +24,7 @@ export interface CollapsibleComponentCardsProps { containerClassName?: string; buttonAriaLabel?: string; deps: CollapsibleComponentCardsDeps; - onExpandToggle: (event: React.MouseEvent) => void; + onExpandToggle: (event: React.MouseEvent) => void; isExpanded?: boolean; } @@ -58,7 +58,7 @@ const CollapsibleComponentCards = NamedFC( collapsedCSSClassName = null; } - const onClick = (event: React.MouseEvent) => { + const onClick = (event: React.MouseEvent) => { if (event.nativeEvent.detail === 0 && deps.setFocusVisibility != null) { // 0 => keyboard event deps.setFocusVisibility(true); @@ -77,15 +77,15 @@ const CollapsibleComponentCards = NamedFC( )} > - {header} - + {contentWrapper}
diff --git a/src/common/components/cards/expand-collapse-all-button-styles.tsx b/src/common/components/cards/expand-collapse-all-button-styles.tsx new file mode 100644 index 00000000000..cccc508b1a3 --- /dev/null +++ b/src/common/components/cards/expand-collapse-all-button-styles.tsx @@ -0,0 +1,19 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +import { makeStyles, tokens } from '@fluentui/react-components'; + +export const useExpandCollapseAllButtonStyles: any = makeStyles({ + expandCollapseAllButton: { + display: 'flex', + padding: 'unset', + paddingRight: '27px!important', + paddingLeft: '1px!important', + marginLeft: '1px!important', + marginTop: '2px!important', + fontWeight: tokens?.fontSizeBase400, + }, + + customStyleIcon: { + color: tokens.colorNeutralForeground2BrandHover, + }, +}); diff --git a/src/common/components/cards/expand-collapse-all-button.scss b/src/common/components/cards/expand-collapse-all-button.scss deleted file mode 100644 index 16378df2f2a..00000000000 --- a/src/common/components/cards/expand-collapse-all-button.scss +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -.expand-collapse-all-button { - display: flex; - padding: unset; - padding-right: 27px; - margin-left: -2px; - margin-top: 2px; -} diff --git a/src/common/components/cards/expand-collapse-all-button.tsx b/src/common/components/cards/expand-collapse-all-button.tsx index be52744e834..218cb8b6bbd 100644 --- a/src/common/components/cards/expand-collapse-all-button.tsx +++ b/src/common/components/cards/expand-collapse-all-button.tsx @@ -1,10 +1,11 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -import { ActionButton } from '@fluentui/react'; +import { Button } from '@fluentui/react-components'; +import { useExpandCollapseAllButtonStyles } from 'common/components/cards/expand-collapse-all-button-styles'; +import { FluentUIV9Icon } from 'common/icons/fluentui-v9-icons'; import { CardSelectionMessageCreator } from 'common/message-creators/card-selection-message-creator'; import { NamedFC } from 'common/react/named-fc'; import * as React from 'react'; -import styles from './expand-collapse-all-button.scss'; export type ExpandCollapseAllButtonProps = { allCardsCollapsed: boolean; @@ -14,30 +15,48 @@ export type ExpandCollapseAllButtonProps = { export const ExpandCollapseAllButton = NamedFC( 'ExpandCollapseAllButton', props => { + const getStyles: any = useExpandCollapseAllButtonStyles(); const { allCardsCollapsed, cardSelectionMessageCreator } = props; let expandCollapseAllButtonHandler = cardSelectionMessageCreator.collapseAllRules; let buttonText = 'Collapse all'; - let iconName = 'ChevronDown'; let ariaLabel: string | undefined = undefined; if (allCardsCollapsed) { expandCollapseAllButtonHandler = cardSelectionMessageCreator.expandAllRules; buttonText = 'Expand all'; - iconName = 'ChevronRight'; ariaLabel = 'Expand all rules to show failed instances.'; } + const IconName = () => { + if (allCardsCollapsed) { + return ( + + ); + } + return ( + + ); + }; + return ( - } + size="medium" + appearance="transparent" + className={getStyles?.expandCollapseAllButton} aria-label={ariaLabel} - className={styles.expandCollapseAllButton} + aria-expanded={!allCardsCollapsed} + onClick={expandCollapseAllButtonHandler} > {buttonText} - + ); }, ); diff --git a/src/common/components/cards/rules-with-instances.scss b/src/common/components/cards/rules-with-instances.scss index bacbcc52b6e..8d315a3daf8 100644 --- a/src/common/components/cards/rules-with-instances.scss +++ b/src/common/components/cards/rules-with-instances.scss @@ -13,6 +13,7 @@ display: flex; align-items: baseline; text-align: left; + font-weight: normal; :global(.outcome-chip) { vertical-align: middle; diff --git a/src/common/components/cards/rules-with-instances.tsx b/src/common/components/cards/rules-with-instances.tsx index 20d70033233..1c8d91cb4c1 100644 --- a/src/common/components/cards/rules-with-instances.tsx +++ b/src/common/components/cards/rules-with-instances.tsx @@ -85,7 +85,7 @@ export const RulesWithInstances = NamedFC( buttonAriaLabel: buttonAriaLabel, headingLevel, deps: deps, - onExpandToggle: (event: React.MouseEvent) => { + onExpandToggle: (event: React.MouseEvent) => { cardSelectionMessageCreator?.toggleRuleExpandCollapse(rule.id, event); }, isExpanded: rule.isExpanded, diff --git a/src/common/components/collapsible-component.scss b/src/common/components/collapsible-component.scss index d570ebce936..b5aec73b135 100644 --- a/src/common/components/collapsible-component.scss +++ b/src/common/components/collapsible-component.scss @@ -8,15 +8,18 @@ span.collapsible-title { } .collapsible { - padding: 0; cursor: pointer; - width: 100%; + width: auto; border: none; outline: none; line-height: 0.25px; display: flex; justify-content: flex-start; align-items: center; + padding-top: 5px; + padding-bottom: 5px; + padding-right: 27px !important; + padding-left: 1px !important; h2 { font-weight: $normal-title-font-weight; diff --git a/src/common/components/collapsible-component.tsx b/src/common/components/collapsible-component.tsx index 74f7e739002..e020f3cda5a 100644 --- a/src/common/components/collapsible-component.tsx +++ b/src/common/components/collapsible-component.tsx @@ -1,8 +1,9 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -import { ActionButton } from '@fluentui/react'; +import { Button } from '@fluentui/react-components'; import { css } from '@fluentui/utilities'; import styles from 'common/components/collapsible-component.scss'; +import { FluentUIV9Icon } from 'common/icons/fluentui-v9-icons'; import * as React from 'react'; export interface CollapsibleComponentProps { @@ -20,9 +21,6 @@ export class CollapsibleComponent extends React.Component< CollapsibleComponentProps, CollapsibleComponentState > { - private readonly iconNameDown = 'ChevronDown'; - private readonly iconNameUp = 'ChevronRight'; - constructor(props: CollapsibleComponentProps) { super(props); this.state = { showContent: true }; @@ -34,11 +32,9 @@ export class CollapsibleComponent extends React.Component< public render(): JSX.Element { const showContent = this.state.showContent; - let iconName = this.iconNameUp; let content: JSX.Element | null = null; if (showContent) { - iconName = this.iconNameDown; content = (
{this.props.content} @@ -48,14 +44,19 @@ export class CollapsibleComponent extends React.Component< return (
- + {showContent ? ( + + ) : ( + + )} {this.props.header} - + {content}
); diff --git a/src/common/components/controls/insights-command-button-style.tsx b/src/common/components/controls/insights-command-button-style.tsx new file mode 100644 index 00000000000..46448173caf --- /dev/null +++ b/src/common/components/controls/insights-command-button-style.tsx @@ -0,0 +1,14 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +import { makeStyles, tokens } from '@fluentui/react-components'; + +export const useInsightsCommandButtonStyle = makeStyles({ + button: { + fontWeight: tokens?.fontWeightRegular, + }, + + menuItem: { + border: 'unset !important', + }, +}); diff --git a/src/common/components/controls/insights-command-button.scss b/src/common/components/controls/insights-command-button.scss index 3be08255899..82e426e2bae 100644 --- a/src/common/components/controls/insights-command-button.scss +++ b/src/common/components/controls/insights-command-button.scss @@ -15,6 +15,10 @@ } } + &:hover { + background: none !important; + } + &:active:not(:disabled) { .command-bar-button-icon { color: $primary-text; diff --git a/src/common/components/controls/insights-command-button.tsx b/src/common/components/controls/insights-command-button.tsx index bd8b2f8e213..d9e0ac1cf69 100644 --- a/src/common/components/controls/insights-command-button.tsx +++ b/src/common/components/controls/insights-command-button.tsx @@ -1,25 +1,55 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -import { ActionButton, css, IButtonProps } from '@fluentui/react'; +import { mergeClasses, MenuButtonProps, Button, MenuItem } from '@fluentui/react-components'; + +import { useInsightsCommandButtonStyle } from 'common/components/controls/insights-command-button-style'; import { NamedFC } from 'common/react/named-fc'; import * as React from 'react'; import styles from './insights-command-button.scss'; -export type InsightsCommandButtonProps = IButtonProps; +export type InsightsCommandButtonIconProps = { + className?: string; + icon?: JSX.Element; +}; + +export type InsightsCommandButtonProps = (MenuButtonProps | any) & { + insightsCommandButtonIconProps?: InsightsCommandButtonIconProps; + isNarrowMode?: boolean; +}; // See https://www.figma.com/file/Wj4Ggf6GGQBQkiDIaHfXRX2B/Accessibility-Insights%3A-Styles?node-id=1%3A27 export const InsightsCommandButton = NamedFC( 'InsightsCommandButton', - props => { - return ( - { + const overrides = useInsightsCommandButtonStyle(); + return props.isNarrowMode ? ( + + {props.children} + + ) : ( + ); - }, + }), ); diff --git a/src/common/components/theme.tsx b/src/common/components/theme.tsx index f1d6f53e6c8..f228e9276e5 100644 --- a/src/common/components/theme.tsx +++ b/src/common/components/theme.tsx @@ -70,7 +70,10 @@ export class ThemeInner extends React.Component { private loadAppropriateTheme(isHighContrast: boolean): void { const appropriateThemeV8 = isHighContrast ? HighContrastTheme : DefaultTheme; const appropriateThemeV9 = isHighContrast ? ThemeV9DarkTheme : webLightTheme; - this.setState({ themeValueV8: appropriateThemeV8, themeValueV9: appropriateThemeV9 }); + this.setState({ + themeValueV8: appropriateThemeV8, + themeValueV9: appropriateThemeV9, + }); } private isHighContrastEnabled(props: ThemeInnerProps): boolean { diff --git a/src/common/icons/fluentui-v9-icons.tsx b/src/common/icons/fluentui-v9-icons.tsx new file mode 100644 index 00000000000..8471ec26417 --- /dev/null +++ b/src/common/icons/fluentui-v9-icons.tsx @@ -0,0 +1,74 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +import { makeStyles, mergeClasses, tokens } from '@fluentui/react-components'; +import { + ArrowExportRegular, + FolderArrowRightRegular, + FolderOpenRegular, + SaveRegular, + ArrowClockwiseRegular, + Checkmark20Filled, + ChevronDown20Regular, + ChevronRight20Regular, + InfoRegular, + DocumentCopyRegular, + BugFilled, + MoreVerticalRegular, + ChevronDown32Regular, + ChevronRight32Regular, + MoreHorizontalRegular, + AddRegular, + ChevronDown24Regular, + ChevronRight24Regular, +} from '@fluentui/react-icons'; +import { NamedFC } from 'common/react/named-fc'; +import { isUndefined } from 'lodash'; + +import React from 'react'; + +export const Icons = { + ArrowExportRegular: ArrowExportRegular, + FolderArrowRightRegular: FolderArrowRightRegular, + FolderOpenRegular: FolderOpenRegular, + SaveRegular: SaveRegular, + ArrowClockwiseRegular: ArrowClockwiseRegular, + Checkmark20Filled: Checkmark20Filled, + ChevronDown20Regular: ChevronDown20Regular, + ChevronRight20Regular: ChevronRight20Regular, + InfoRegular: InfoRegular, + BugFilled: BugFilled, + DocumentCopyRegular: DocumentCopyRegular, + MoreVerticalRegular: MoreVerticalRegular, + ChevronDown32Regular: ChevronDown32Regular, + ChevronRight32Regular: ChevronRight32Regular, + MoreHorizontalRegular: MoreHorizontalRegular, + AddRegular: AddRegular, + ChevronDown24Regular: ChevronDown24Regular, + ChevronRight24Regular: ChevronRight24Regular, +}; + +export const useIconStyles = makeStyles({ + refreshIcon: { + paddingLeft: '14px', + }, + IconTheme: { + color: tokens.colorCompoundBrandStrokeHover, + }, +}); + +export type FluentUIV9IconProps = { + iconName: string | any; + customClass?: string | any; +}; + +export const FluentUIV9Icon = NamedFC('FluentUIV9Icon', props => { + const styleClasses: any = useIconStyles(); + const isIconAvailable = !isUndefined(props?.iconName) && Icons[props.iconName]; + + if (isIconAvailable) { + const Icon = Icons[props?.iconName]; + return ; + } + + return null; +}); diff --git a/src/common/styles/theme-v9-dark-theme.ts b/src/common/styles/theme-v9-dark-theme.ts index 225f8bcf602..2e6469365db 100644 --- a/src/common/styles/theme-v9-dark-theme.ts +++ b/src/common/styles/theme-v9-dark-theme.ts @@ -1,6 +1,5 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. - import { webDarkTheme } from '@fluentui/react-components'; // This is a copy of our ThemeDark from V9 slightly adjusted to account for the page background @@ -9,4 +8,6 @@ import { webDarkTheme } from '@fluentui/react-components'; export const ThemeV9DarkTheme = { ...webDarkTheme, colorNeutralBackground1: '#161616', + colorNeutralForeground2: '#fff', + colorCompoundBrandStrokeHover: '#ffffff', }; diff --git a/src/popup/Styles/popup.scss b/src/popup/Styles/popup.scss index 50ba7f6c024..e0f55af42cd 100644 --- a/src/popup/Styles/popup.scss +++ b/src/popup/Styles/popup.scss @@ -153,12 +153,11 @@ html { } #popup-container .ms-Link { + color: $communication-primary; + font-weight: 600; @media screen and (forced-colors: active) { color: linktext !important; } - - color: $communication-primary; - font-weight: 600; } #popup-container .main-section { diff --git a/src/reports/automated-checks-report.scss b/src/reports/automated-checks-report.scss index d8ddd79bc5b..06a2b93c72c 100644 --- a/src/reports/automated-checks-report.scss +++ b/src/reports/automated-checks-report.scss @@ -89,7 +89,7 @@ $outcome-not-applicable-summary-color: $neutral-outcome; border: none; display: flex; align-items: baseline; - width: 100%; + width: auto; &:hover { background-color: $neutral-alpha-4; diff --git a/src/reports/components/instance-details.scss b/src/reports/components/instance-details.scss index ea035bd6225..13f7e6f479f 100644 --- a/src/reports/components/instance-details.scss +++ b/src/reports/components/instance-details.scss @@ -80,6 +80,7 @@ padding-bottom: 14px; padding-left: 0; padding-right: 20px; + border-bottom: 0.5px solid $neutral-10; > * { margin-top: 12px; @@ -89,8 +90,6 @@ padding: 0; } - border-bottom: 0.5px solid $neutral-10; - &:last-child { border-bottom: none; } diff --git a/src/reports/components/outcome-summary-bar.scss b/src/reports/components/outcome-summary-bar.scss index 7990591b419..984a03786b2 100644 --- a/src/reports/components/outcome-summary-bar.scss +++ b/src/reports/components/outcome-summary-bar.scss @@ -51,6 +51,7 @@ $outcome-not-applicable-color: $neutral-outcome; } .fail { + background-color: $outcome-fail-color; @extend %block; @include cross-icon-styles($outcome-summary-icon-size, 0, $outcome-fail-color); @@ -58,11 +59,10 @@ $outcome-not-applicable-color: $neutral-outcome; bottom: -1px; margin-right: 8px; } - - background-color: $outcome-fail-color; } .pass { + background-color: $outcome-pass-color; @extend %block; @include check-icon-styles($outcome-summary-icon-size, 0, $outcome-pass-color); @@ -71,12 +71,11 @@ $outcome-not-applicable-color: $neutral-outcome; margin-right: 8px; margin-left: 4px; } - - background-color: $outcome-pass-color; } .inapplicable, .unscannable { + background-color: $outcome-not-applicable-color; @extend %block; @include inapplicable-icon-styles( $outcome-summary-icon-size, @@ -89,11 +88,13 @@ $outcome-not-applicable-color: $neutral-outcome; margin-right: 8px; margin-left: 4px; } - - background-color: $outcome-not-applicable-color; } .incomplete { + background-color: $outcome-incomplete-summary-background; + color: $outcome-incomplete-summary-consistent-foreground; + border: 2px $outcome-incomplete-border-color solid; + height: 12px; @extend %block; @include incomplete-icon-styles(14px, 3px); @@ -101,11 +102,6 @@ $outcome-not-applicable-color: $neutral-outcome; margin-right: 6px; border-color: $outcome-incomplete-summary-consistent-foreground; } - - background-color: $outcome-incomplete-summary-background; - color: $outcome-incomplete-summary-consistent-foreground; - border: 2px $outcome-incomplete-border-color solid; - height: 12px; } .summary-bar-left-edge { diff --git a/src/reports/components/report-sections/collapsible-result-section.tsx b/src/reports/components/report-sections/collapsible-result-section.tsx index 84a3dc5dcb8..c9b5a88a4fb 100644 --- a/src/reports/components/report-sections/collapsible-result-section.tsx +++ b/src/reports/components/report-sections/collapsible-result-section.tsx @@ -37,7 +37,7 @@ export const CollapsibleResultSection = NamedFC( content: , headingLevel: props.headingLevel, testKey, - onExpandToggle: (event: React.MouseEvent) => { + onExpandToggle: (event: React.MouseEvent) => { cardSelectionMessageCreator?.toggleRuleExpandCollapse(containerId, event); }, }); diff --git a/src/reports/components/report-sections/combined-report-rules-only-sections.tsx b/src/reports/components/report-sections/combined-report-rules-only-sections.tsx index ab0f99433f6..4d6ea6994ba 100644 --- a/src/reports/components/report-sections/combined-report-rules-only-sections.tsx +++ b/src/reports/components/report-sections/combined-report-rules-only-sections.tsx @@ -43,7 +43,7 @@ const makeCombinedReportRulesOnlySection = (options: { outcomeType={outcomeType} /> ), - onExpandToggle: (event: React.MouseEvent) => { + onExpandToggle: (event: React.MouseEvent) => { cardSelectionMessageCreator?.toggleRuleExpandCollapse(sectionId, event); }, headingLevel: 3, diff --git a/src/reports/components/report-sections/report-collapsible-container.tsx b/src/reports/components/report-sections/report-collapsible-container.tsx index 288a0016460..6407b6ae983 100644 --- a/src/reports/components/report-sections/report-collapsible-container.tsx +++ b/src/reports/components/report-sections/report-collapsible-container.tsx @@ -14,7 +14,7 @@ export interface ReportCollapsibleContainerProps { containerClassName?: string; buttonAriaLabel?: string; testKey?: string; - onExpandToggle?: (event: React.MouseEvent) => void; + onExpandToggle?: (event: React.MouseEvent) => void; } const ReportCollapsibleContainer = NamedFC( diff --git a/src/tests/end-to-end/common/pretty-print-axe-violations.ts b/src/tests/end-to-end/common/pretty-print-axe-violations.ts index fadf2ac027f..6b7c408cc08 100644 --- a/src/tests/end-to-end/common/pretty-print-axe-violations.ts +++ b/src/tests/end-to-end/common/pretty-print-axe-violations.ts @@ -28,6 +28,9 @@ export function normalizeSelector(selector: string): string { const identifier = output.slice(1); output = `${output[0]}${normalizeOfficeFabricClassName(identifier)}`; } + if (/i\S+nth-child\(\d\)/.test(output)) { + output = 'i:nth-child(0)'; + } return output; } diff --git a/src/tests/end-to-end/tests/details-view/__snapshots__/reflow-ui.test.ts.snap b/src/tests/end-to-end/tests/details-view/__snapshots__/reflow-ui.test.ts.snap index f1048a42543..22a4d8b89d6 100644 --- a/src/tests/end-to-end/tests/details-view/__snapshots__/reflow-ui.test.ts.snap +++ b/src/tests/end-to-end/tests/details-view/__snapshots__/reflow-ui.test.ts.snap @@ -4,9 +4,79 @@ exports[`Details View -> Assessment -> Reflow With command bar button visible sh exports[`Details View -> Assessment -> Reflow With command bar button visible should pass accessibility validation with high contrast mode=true 1`] = `[]`; -exports[`Details View -> Assessment -> Reflow With command bar button visible with command bar button expanded should pass accessibility validation with command bar menu open and high contrast mode=false 1`] = `[]`; +exports[`Details View -> Assessment -> Reflow With command bar button visible with command bar button expanded should pass accessibility validation with command bar menu open and high contrast mode=false 1`] = ` +[ + { + "id": "aria-hidden-focus", + "nodes": [ + { + "failureSummary": "Fix all of the following: + Focusable content should have tabindex="-1" or be removed from the DOM", + "selector": [ + "i:nth-child(0)", + ], + }, + { + "failureSummary": "Fix all of the following: + Focusable content should have tabindex="-1" or be removed from the DOM", + "selector": [ + "i:nth-child(0)", + ], + }, + ], + }, + { + "id": "aria-required-children", + "nodes": [ + { + "failureSummary": "Fix any of the following: + Element has children which are not allowed: button[tabindex], [role=button] + Element uses aria-busy="true" while showing a loader", + "selector": [ + ".fui-MenuList", + ], + }, + ], + }, +] +`; -exports[`Details View -> Assessment -> Reflow With command bar button visible with command bar button expanded should pass accessibility validation with command bar menu open and high contrast mode=true 1`] = `[]`; +exports[`Details View -> Assessment -> Reflow With command bar button visible with command bar button expanded should pass accessibility validation with command bar menu open and high contrast mode=true 1`] = ` +[ + { + "id": "aria-hidden-focus", + "nodes": [ + { + "failureSummary": "Fix all of the following: + Focusable content should have tabindex="-1" or be removed from the DOM", + "selector": [ + "i:nth-child(0)", + ], + }, + { + "failureSummary": "Fix all of the following: + Focusable content should have tabindex="-1" or be removed from the DOM", + "selector": [ + "i:nth-child(0)", + ], + }, + ], + }, + { + "id": "aria-required-children", + "nodes": [ + { + "failureSummary": "Fix any of the following: + Element has children which are not allowed: button[tabindex], [role=button] + Element uses aria-busy="true" while showing a loader", + "selector": [ + ".fui-MenuList", + ], + }, + ], + }, +] +`; exports[`Details View -> Assessment -> Reflow With hamburger button visible should pass accessibility validation with high contrast mode=false 1`] = `[]`; @@ -16,13 +86,105 @@ exports[`Details View -> Assessment -> Reflow With hamburger button visible with exports[`Details View -> Assessment -> Reflow With hamburger button visible with hamburger button expanded should pass accessibility validation with command bar menu open and high contrast mode=true 1`] = `[]`; -exports[`Details View -> Fastpass -> Reflow With high contrast mode=false With command bar button visible with command bar button expanded should pass accessibility validation with command bar menu open and high contrast mode=%s 1`] = `[]`; +exports[`Details View -> Fastpass -> Reflow With high contrast mode=false With command bar button visible with command bar button expanded should pass accessibility validation with command bar menu open and high contrast mode=%s 1`] = ` +[ + { + "id": "aria-hidden-focus", + "nodes": [ + { + "failureSummary": "Fix all of the following: + Focusable content should have tabindex="-1" or be removed from the DOM", + "selector": [ + "i:nth-child(0)", + ], + }, + { + "failureSummary": "Fix all of the following: + Focusable content should have tabindex="-1" or be removed from the DOM", + "selector": [ + "i:nth-child(0)", + ], + }, + ], + }, + { + "id": "aria-required-children", + "nodes": [ + { + "failureSummary": "Fix any of the following: + Element has children which are not allowed: button[tabindex] + Element uses aria-busy="true" while showing a loader", + "selector": [ + ".fui-MenuList", + ], + }, + ], + }, +] +`; exports[`Details View -> Fastpass -> Reflow With high contrast mode=false and card kebab menu collapsed 1`] = `[]`; -exports[`Details View -> Fastpass -> Reflow With high contrast mode=false and card kebab menu expanded 1`] = `[]`; +exports[`Details View -> Fastpass -> Reflow With high contrast mode=false and card kebab menu expanded 1`] = ` +[ + { + "id": "aria-hidden-focus", + "nodes": [ + { + "failureSummary": "Fix all of the following: + Focusable content should have tabindex="-1" or be removed from the DOM", + "selector": [ + "i:nth-child(0)", + ], + }, + { + "failureSummary": "Fix all of the following: + Focusable content should have tabindex="-1" or be removed from the DOM", + "selector": [ + "i:nth-child(0)", + ], + }, + ], + }, +] +`; -exports[`Details View -> Fastpass -> Reflow With high contrast mode=true With command bar button visible with command bar button expanded should pass accessibility validation with command bar menu open and high contrast mode=%s 1`] = `[]`; +exports[`Details View -> Fastpass -> Reflow With high contrast mode=true With command bar button visible with command bar button expanded should pass accessibility validation with command bar menu open and high contrast mode=%s 1`] = ` +[ + { + "id": "aria-hidden-focus", + "nodes": [ + { + "failureSummary": "Fix all of the following: + Focusable content should have tabindex="-1" or be removed from the DOM", + "selector": [ + "i:nth-child(0)", + ], + }, + { + "failureSummary": "Fix all of the following: + Focusable content should have tabindex="-1" or be removed from the DOM", + "selector": [ + "i:nth-child(0)", + ], + }, + ], + }, + { + "id": "aria-required-children", + "nodes": [ + { + "failureSummary": "Fix any of the following: + Element has children which are not allowed: button[tabindex] + Element uses aria-busy="true" while showing a loader", + "selector": [ + ".fui-MenuList", + ], + }, + ], + }, +] +`; exports[`Details View -> Fastpass -> Reflow With high contrast mode=true and card kebab menu collapsed 1`] = ` [ @@ -42,15 +204,107 @@ exports[`Details View -> Fastpass -> Reflow With high contrast mode=true and car ] `; -exports[`Details View -> Fastpass -> Reflow With high contrast mode=true and card kebab menu expanded 1`] = `[]`; +exports[`Details View -> Fastpass -> Reflow With high contrast mode=true and card kebab menu expanded 1`] = ` +[ + { + "id": "aria-hidden-focus", + "nodes": [ + { + "failureSummary": "Fix all of the following: + Focusable content should have tabindex="-1" or be removed from the DOM", + "selector": [ + "i:nth-child(0)", + ], + }, + { + "failureSummary": "Fix all of the following: + Focusable content should have tabindex="-1" or be removed from the DOM", + "selector": [ + "i:nth-child(0)", + ], + }, + ], + }, +] +`; exports[`Details View -> Quick Assess -> Reflow With command bar button visible should pass accessibility validation with high contrast mode=false 1`] = `[]`; exports[`Details View -> Quick Assess -> Reflow With command bar button visible should pass accessibility validation with high contrast mode=true 1`] = `[]`; -exports[`Details View -> Quick Assess -> Reflow With command bar button visible with command bar button expanded should pass accessibility validation with command bar menu open and high contrast mode=false 1`] = `[]`; +exports[`Details View -> Quick Assess -> Reflow With command bar button visible with command bar button expanded should pass accessibility validation with command bar menu open and high contrast mode=false 1`] = ` +[ + { + "id": "aria-hidden-focus", + "nodes": [ + { + "failureSummary": "Fix all of the following: + Focusable content should have tabindex="-1" or be removed from the DOM", + "selector": [ + "i:nth-child(0)", + ], + }, + { + "failureSummary": "Fix all of the following: + Focusable content should have tabindex="-1" or be removed from the DOM", + "selector": [ + "i:nth-child(0)", + ], + }, + ], + }, + { + "id": "aria-required-children", + "nodes": [ + { + "failureSummary": "Fix any of the following: + Element has children which are not allowed: button[tabindex], [role=button] + Element uses aria-busy="true" while showing a loader", + "selector": [ + ".fui-MenuList", + ], + }, + ], + }, +] +`; -exports[`Details View -> Quick Assess -> Reflow With command bar button visible with command bar button expanded should pass accessibility validation with command bar menu open and high contrast mode=true 1`] = `[]`; +exports[`Details View -> Quick Assess -> Reflow With command bar button visible with command bar button expanded should pass accessibility validation with command bar menu open and high contrast mode=true 1`] = ` +[ + { + "id": "aria-hidden-focus", + "nodes": [ + { + "failureSummary": "Fix all of the following: + Focusable content should have tabindex="-1" or be removed from the DOM", + "selector": [ + "i:nth-child(0)", + ], + }, + { + "failureSummary": "Fix all of the following: + Focusable content should have tabindex="-1" or be removed from the DOM", + "selector": [ + "i:nth-child(0)", + ], + }, + ], + }, + { + "id": "aria-required-children", + "nodes": [ + { + "failureSummary": "Fix any of the following: + Element has children which are not allowed: button[tabindex], [role=button] + Element uses aria-busy="true" while showing a loader", + "selector": [ + ".fui-MenuList", + ], + }, + ], + }, +] +`; exports[`Details View -> Quick Assess -> Reflow With hamburger button visible should pass accessibility validation with high contrast mode=false 1`] = `[]`; diff --git a/src/tests/end-to-end/tests/details-view/reflow-ui.test.ts b/src/tests/end-to-end/tests/details-view/reflow-ui.test.ts index e4765658a49..84f7fba12ae 100644 --- a/src/tests/end-to-end/tests/details-view/reflow-ui.test.ts +++ b/src/tests/end-to-end/tests/details-view/reflow-ui.test.ts @@ -239,6 +239,12 @@ describe('Details View ->', () => { // this is a false positive because background is black and link is having yellow as per high contrast theme // standards so this criteria does not apply // Please refer for more information on the error:https://github.com/dequelabs/axe-core/issues/3464 + // this results object has a failure for aria-hidden-focus + // These are Tabster dummy inputs and they must be added to the exception list. + // They are intentionally aria - hidden as their purpose is to redirect focus to the correct element + // right when they receive focus and not having aria - hidden will result in the screen readers choking + // starting to announce them. + // Please refer for more information on the error:https://github.com/microsoft/fluentui/issues/25133 expect(results).toMatchSnapshot(); } diff --git a/src/tests/unit/tests/DetailsView/components/__snapshots__/assessment-instance-table.test.tsx.snap b/src/tests/unit/tests/DetailsView/components/__snapshots__/assessment-instance-table.test.tsx.snap index da7dfa6aaae..2fbf380a138 100644 --- a/src/tests/unit/tests/DetailsView/components/__snapshots__/assessment-instance-table.test.tsx.snap +++ b/src/tests/unit/tests/DetailsView/components/__snapshots__/assessment-instance-table.test.tsx.snap @@ -6,7 +6,7 @@ exports[`AssessmentInstanceTable with instances renders per snapshot 1`] = ` Pass unmarked instances @@ -72,8 +72,10 @@ exports[`AssessmentInstanceTable with instances renders per snapshot: InsightsCo "children": "Pass unmarked instances", "data-automation-id": "assessment-instance-table-pass-unmarked-instances-button", "disabled": false, - "iconProps": { - "iconName": "skypeCheck", + "insightsCommandButtonIconProps": { + "icon": , }, "onClick": [Function], } diff --git a/src/tests/unit/tests/DetailsView/components/__snapshots__/command-bar-buttons-menu.test.tsx.snap b/src/tests/unit/tests/DetailsView/components/__snapshots__/command-bar-buttons-menu.test.tsx.snap index 5173525f82c..ec3b7afef46 100644 --- a/src/tests/unit/tests/DetailsView/components/__snapshots__/command-bar-buttons-menu.test.tsx.snap +++ b/src/tests/unit/tests/DetailsView/components/__snapshots__/command-bar-buttons-menu.test.tsx.snap @@ -2,97 +2,66 @@ exports[`CommandBarButtonsMenu renders CommandBarButtonsMenu 1`] = ` - - - + + + + + + + + + Save assessment button + + + Load assessment button + + + Transfer to assessment button + + + + + `; -exports[`CommandBarButtonsMenu renders CommandBarButtonsMenu: CustomizedCommandBarButton props 1`] = ` -{ - "ariaLabel": "More actions", - "className": "commandBarButtonsMenu", - "componentRef": {}, - "menuIconProps": { - "className": "commandBarButtonsMenuButton", - "iconName": "More", - }, - "menuProps": { - "className": "commandBarButtonsSubmenu", - "items": [ - { - "key": "save assessment", - "onRender": [Function], - }, - { - "key": "load assessment", - "onRender": [Function], - }, - { - "key": "transfer to assessment", - "onRender": [Function], - }, - { - "key": "start over", - }, - ], - }, - "role": "button", -} +exports[`CommandBarButtonsMenu renders all child buttons with hasSubMenu false,: render export report menuitem 1`] = ` + + Report export button + `; -exports[`CommandBarButtonsMenu renders all child buttons,: render export report menuitem 1`] = ` -
- - Report export button - -
+exports[`CommandBarButtonsMenu renders all child buttons with hasSubMenu false,: render load assessment menuitem 1`] = ` + + Load assessment button + `; -exports[`CommandBarButtonsMenu renders all child buttons,: render load assessment menuitem 1`] = ` -
- - Load assessment button - -
+exports[`CommandBarButtonsMenu renders all child buttons with hasSubMenu false,: render save assessment menuitem 1`] = ` + + Save assessment button + `; -exports[`CommandBarButtonsMenu renders all child buttons,: render save assessment menuitem 1`] = ` -
- - Save assessment button - -
-`; - -exports[`CommandBarButtonsMenu renders all child buttons,: render start over menuitem 1`] = ` - - Start over button - -`; - -exports[`CommandBarButtonsMenu renders all child buttons,: render transfer to assessment menuitem 1`] = ` -
- - Transfer to assessment button - -
+exports[`CommandBarButtonsMenu renders all child buttons with hasSubMenu false,: render transfer to assessment menuitem 1`] = ` + + Transfer to assessment button + `; diff --git a/src/tests/unit/tests/DetailsView/components/__snapshots__/details-view-command-bar.test.tsx.snap b/src/tests/unit/tests/DetailsView/components/__snapshots__/details-view-command-bar.test.tsx.snap index 6bab4280c53..bcc6451902e 100644 --- a/src/tests/unit/tests/DetailsView/components/__snapshots__/details-view-command-bar.test.tsx.snap +++ b/src/tests/unit/tests/DetailsView/components/__snapshots__/details-view-command-bar.test.tsx.snap @@ -1,5 +1,271 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`DetailsViewCommandBar Button focus render statover component 1`] = ` +{ + "asFragment": [Function], + "baseElement": +
+
+
+
+ + Target page:  + + + + command-bar-test-tab-title + + +
+ + + + +
+
+ , + "container":
+
+
+ + Target page:  + + + + command-bar-test-tab-title + + +
+ + + + +
+
, + "debug": [Function], + "findAllByAltText": [Function], + "findAllByDisplayValue": [Function], + "findAllByLabelText": [Function], + "findAllByPlaceholderText": [Function], + "findAllByRole": [Function], + "findAllByTestId": [Function], + "findAllByText": [Function], + "findAllByTitle": [Function], + "findByAltText": [Function], + "findByDisplayValue": [Function], + "findByLabelText": [Function], + "findByPlaceholderText": [Function], + "findByRole": [Function], + "findByTestId": [Function], + "findByText": [Function], + "findByTitle": [Function], + "getAllByAltText": [Function], + "getAllByDisplayValue": [Function], + "getAllByLabelText": [Function], + "getAllByPlaceholderText": [Function], + "getAllByRole": [Function], + "getAllByTestId": [Function], + "getAllByText": [Function], + "getAllByTitle": [Function], + "getByAltText": [Function], + "getByDisplayValue": [Function], + "getByLabelText": [Function], + "getByPlaceholderText": [Function], + "getByRole": [Function], + "getByTestId": [Function], + "getByText": [Function], + "getByTitle": [Function], + "queryAllByAltText": [Function], + "queryAllByDisplayValue": [Function], + "queryAllByLabelText": [Function], + "queryAllByPlaceholderText": [Function], + "queryAllByRole": [Function], + "queryAllByTestId": [Function], + "queryAllByText": [Function], + "queryAllByTitle": [Function], + "queryByAltText": [Function], + "queryByDisplayValue": [Function], + "queryByLabelText": [Function], + "queryByPlaceholderText": [Function], + "queryByRole": [Function], + "queryByTestId": [Function], + "queryByText": [Function], + "queryByTitle": [Function], + "rerender": [Function], + "unmount": [Function], +} +`; + exports[`DetailsViewCommandBar renders invalid load assessment dialog: invalid load assessment dialog hidden 1`] = `