Skip to content

Commit

Permalink
feat(assistant): add editor toolbar, #623
Browse files Browse the repository at this point in the history
  • Loading branch information
stanlee974 committed May 26, 2024
1 parent 4d318a2 commit a5e740d
Show file tree
Hide file tree
Showing 7 changed files with 167 additions and 69 deletions.
33 changes: 33 additions & 0 deletions packages/assistant/src/Commons.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import React from "react";

export const UUV_ASSISTANT_BAR_WIDTH = 60;

export type ResultSentence = {
key: React.Key;
result: string
}

export class Suggestion {
constructor(public accessibleAttribute: string = "", public accessibleValue = "", public code = "", public sentenceAfterCorrection: string[] = []) {
}
}

export type ActionEnum = CheckActionEnum | KeyboardActionEnum;

export enum CheckActionEnum {
NONE = "None", WITHIN = "Within", EXPECT = "Expect", CLICK = "Click"
}

export enum KeyboardActionEnum {
GLOBAL_NAVIGATION = "Navigation",
}

export enum ToolbarActionEnum {
CURRENT_NAVIGATION = "currentNavigation",
EXPECTED_NAVIGATION = "expectedNavigation",
}

export enum AdditionalLayerEnum {
CURRENT_NAVIGATION = "keyboard-layer-current-navigation",
EXPECTED_NAVIGATION = "keyboard-layer-expected-navigation",
}
13 changes: 0 additions & 13 deletions packages/assistant/src/Commons.tsx

This file was deleted.

11 changes: 10 additions & 1 deletion packages/assistant/src/UuvAssistant.css
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
:host {
--ua-color-primary: white;
--ua-color-secondary: #1668dc;
--ua-color-hover: #15417e;
--ua-bg-color: #001529;
--ua-menu-width: 60px;
}
Expand Down Expand Up @@ -34,7 +35,7 @@
opacity: 0.80;
}

#uuvAssistantResultZone header {
#uuvAssistantResultZone header, #uuvAssistantResultZone #toolbar {
padding: 10px;
border-bottom: solid 1px var(--ua-color-primary);
}
Expand Down Expand Up @@ -95,6 +96,14 @@
display: inline-flex !important;
}

.keyboardicon:hover {
color: var(--ua-color-hover) !important
}

.keyboardicon.active {
color: var(--ua-color-secondary) !important
}

.ant-layout-sider-children {
height: 100%;
}
Expand Down
112 changes: 77 additions & 35 deletions packages/assistant/src/UuvAssistant.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,24 @@
import React, { useEffect, useState } from "react";
import uuvLogoJson from "./assets/uuvLogo.json";

import { BaseSentence, CheckActionEnum, KeyboardActionEnum, StepCaseEnum, TranslateHelper, TranslateSentences } from "./helper/TranslateHelper";
import { Avatar, Button, ConfigProvider, Divider, Flex, Layout, Menu, MenuProps, notification, Spin, theme, Tooltip, Typography } from "antd";
import { BaseSentence, StepCaseEnum, TranslateHelper, TranslateSentences } from "./helper/TranslateHelper";
import {
Avatar,
Button,
ConfigProvider,
Divider,
Flex,
Layout,
Menu,
MenuProps,
message,
Space,
Spin,
Switch,
theme,
Tooltip,
Typography
} from "antd";
import { CloseOutlined, CopyOutlined, DesktopOutlined, DoubleLeftOutlined, DoubleRightOutlined, InteractionOutlined } from "@ant-design/icons";
import { StyleProvider } from "@ant-design/cssinjs";
import { CssHelper } from "./helper/CssHelper";
Expand All @@ -29,8 +45,8 @@ import { githubDark } from "@uiw/codemirror-theme-github";

import { enSentences } from "@uuv/runner-commons/wording/web/en";
import { KeyboardNavigationHelper } from "./helper/KeyboardNavigationHelper";
import { ResultSentence, Suggestion } from "./Commons";
import { buildResultingScript, buildUuvGutter } from "./helper/ResultScriptHelper";
import { ActionEnum, AdditionalLayerEnum, CheckActionEnum, KeyboardActionEnum, ResultSentence, Suggestion, ToolbarActionEnum } from "./Commons";

type UuvAssistantProps = {
translator?: (el: FocusableElement) => string;
Expand All @@ -41,22 +57,24 @@ type UuvAssistantProps = {
/* eslint-disable @typescript-eslint/no-explicit-any */
function UuvAssistant(props: UuvAssistantProps) {
const [generatedScript, setGeneratedScript] = useState<string>("");
const [checkAction, setCheckAction] = useState<CheckActionEnum>(CheckActionEnum.EXPECT);
const [menuAction, setMenuAction] = useState<ActionEnum>(CheckActionEnum.EXPECT);
const [toolbarAction, setToolbarAction] = useState<ToolbarActionEnum>();
const [disabledElement, setDisabledElement] = useState("");
const [isExtended, setIsExtended] = useState(false);
const [isHide, setIsHide] = useState(false);
const [isDark, setIsDark] = useState(true);
const [isLoading, setIsLoading] = useState(false);
const [uuvGutter, setUuvGutter] = useState<Extension>(gutter({}));
const [currentKeyboardNavigation, setCurrentKeyboardNavigation] = useState<FocusableElement[]>([]);
const [expectedKeyboardNavigation, setExpectedKeyboardNavigation] = useState<FocusableElement[]>([]);

const Inspector = require("inspector-dom");
const inspector = Inspector({
root: "body",
outlineStyle: "2px solid red",
onClick: (el: HTMLElement) => {
setIsLoading(true);
console.log("checkAction2", checkAction);
translate(el, checkAction).then((translateSentences) => {
translate(el, menuAction).then((translateSentences) => {
setIsLoading(false);
setIsExtended(true);
setIsHide(false);
Expand All @@ -69,7 +87,7 @@ function UuvAssistant(props: UuvAssistantProps) {
setGeneratedScript(
buildResultingScript(
"Your amazing feature name",
`Action - ${checkAction}`,
`Action - ${menuAction}`,
data.map(sentence => sentence.result)
)
);
Expand All @@ -91,9 +109,15 @@ function UuvAssistant(props: UuvAssistantProps) {
);
}, [generatedScript]);

useEffect(() => {
if (currentKeyboardNavigation.length > 0) {
KeyboardNavigationHelper.switchKeyboardLayer(props.assistantAdditionalLayersRoot, AdditionalLayerEnum.CURRENT_NAVIGATION, currentKeyboardNavigation)
}
}, [currentKeyboardNavigation]);

function reset() {
inspector.cancel();
setCheckAction(CheckActionEnum.NONE);
setMenuAction(CheckActionEnum.NONE);
setDisabledElement("");
setIsDark(true);
setIsHide(false);
Expand All @@ -102,11 +126,8 @@ function UuvAssistant(props: UuvAssistantProps) {
const copyResult = () => {
if (generatedScript.length > 0) {
navigator.clipboard.writeText(generatedScript);
notification.success({
message: "Message",
description:
"Result copied to the clipboard",
placement: "bottom"
message.success({
content: "Result copied to the clipboard"
});
}
};
Expand All @@ -128,7 +149,7 @@ function UuvAssistant(props: UuvAssistantProps) {
e.preventDefault();
const element = document.elementFromPoint(e.clientX, e.clientY);
let internalDisabledElement = disabledElement;
if (checkAction !== CheckActionEnum.NONE && element && element.hasAttribute("disabled")) {
if (menuAction !== CheckActionEnum.NONE && element && element.hasAttribute("disabled")) {
internalDisabledElement = TranslateHelper.getSelector(element);
element.removeAttribute("disabled");
element.setAttribute("readonly", "true");
Expand All @@ -139,7 +160,6 @@ function UuvAssistant(props: UuvAssistantProps) {
querySelector?.setAttribute("disabled", "true");
querySelector?.removeAttribute("readonly");
setDisabledElement("");
console.debug("querySelector", disabledElement);
}
}
};
Expand All @@ -150,8 +170,9 @@ function UuvAssistant(props: UuvAssistantProps) {
const sentences: string[] = [];
const jsonBase: BaseSentence[] = enSentences;

const currentKeyboardNavigation = tabbable(document.body, {});
const expectedKeyboardNavigation = [...currentKeyboardNavigation].sort((a: FocusableElement, b: FocusableElement) => {
const currentKeyboardFocusableElements = tabbable(document.body, {});
setCurrentKeyboardNavigation(currentKeyboardFocusableElements);
const expectedKeyboardFocusableElements = [...currentKeyboardFocusableElements].sort((a: FocusableElement, b: FocusableElement) => {
const leftRect = a.getBoundingClientRect();
const rightRect = b.getBoundingClientRect();
if (leftRect.y < rightRect.y) {
Expand All @@ -162,13 +183,13 @@ function UuvAssistant(props: UuvAssistantProps) {
}
return 1;
});

if (expectedKeyboardNavigation) {
setExpectedKeyboardNavigation(expectedKeyboardFocusableElements);
if (expectedKeyboardFocusableElements) {
const startKeyboardNavigationSentence = jsonBase.find((el: BaseSentence) => el.key === "key.given.keyboard.startNavigationFromTheTop");
if (startKeyboardNavigationSentence) {
sentences.push(StepCaseEnum.AND + startKeyboardNavigationSentence.wording);
}
const promises = expectedKeyboardNavigation.map(async (node, index, focusableElements) => {
const promises = expectedKeyboardFocusableElements.map(async (node, index, focusableElements) => {
const focusBySelectorControlSentence = jsonBase
.find((el: BaseSentence) => el.key === "key.then.element.withSelectorFocused");
const focusByRoleAndNameControlSentence = jsonBase
Expand Down Expand Up @@ -204,7 +225,6 @@ function UuvAssistant(props: UuvAssistantProps) {
data.map(sentence => sentence.result)
)
);
KeyboardNavigationHelper.buildKeyboardLayer(props.assistantAdditionalLayersRoot, currentKeyboardNavigation);
setIsExtended(true);
}
}
Expand All @@ -221,8 +241,9 @@ function UuvAssistant(props: UuvAssistantProps) {
}

const handleSelectCheckActionClick = (newValue: CheckActionEnum) => {
KeyboardNavigationHelper.clearKeyboardLayer(props.assistantAdditionalLayersRoot);
setCheckAction(newValue);
KeyboardNavigationHelper.clearKeyboardLayer(props.assistantAdditionalLayersRoot, AdditionalLayerEnum.CURRENT_NAVIGATION);
KeyboardNavigationHelper.clearKeyboardLayer(props.assistantAdditionalLayersRoot, AdditionalLayerEnum.EXPECTED_NAVIGATION);
setMenuAction(newValue);
setIsHide(true);
startSelect();
};
Expand Down Expand Up @@ -277,10 +298,23 @@ function UuvAssistant(props: UuvAssistantProps) {
]),
getItem("A11y", "subA11y", false, () => {
}, <DesktopOutlined />, [
getItem("Keyboard navigation", "KeybNav", false, keyboardNavigation)
getItem("Keyboard navigation", "KeybNav", false, () => {
setMenuAction(KeyboardActionEnum.GLOBAL_NAVIGATION);
keyboardNavigation().then();
})
])
];

function switchKeyboardNavigationState(isCurrent: boolean): void {
if (isCurrent) {
KeyboardNavigationHelper.switchKeyboardLayer(props.assistantAdditionalLayersRoot, AdditionalLayerEnum.CURRENT_NAVIGATION, currentKeyboardNavigation);
setToolbarAction(ToolbarActionEnum.CURRENT_NAVIGATION);
} else {
KeyboardNavigationHelper.switchKeyboardLayer(props.assistantAdditionalLayersRoot, AdditionalLayerEnum.EXPECTED_NAVIGATION, expectedKeyboardNavigation);
setToolbarAction(ToolbarActionEnum.EXPECTED_NAVIGATION);
}
}

return (
<div id='uuvAssistantMenu'>
<StyleProvider container={props.assistantRoot}>
Expand All @@ -300,19 +334,27 @@ function UuvAssistant(props: UuvAssistantProps) {
<header>
<Flex justify={"space-between"} align={"center"}>
<Typography.Title level={2}>Result</Typography.Title>
<div>
<Tooltip placement='bottom' title='Copy' getPopupContainer={(triggerNode) => getAsideParentInHierarchy(triggerNode)}>
<Button type='link' shape='circle' icon={<CopyOutlined />} className='primary' onClick={copyResult} />
</Tooltip>
<Tooltip placement='bottom' title='Close' getPopupContainer={(triggerNode) => getAsideParentInHierarchy(triggerNode)}>
<Button type='link' shape='circle' icon={<CloseOutlined />} className='primary' onClick={() => {
KeyboardNavigationHelper.clearKeyboardLayer(props.assistantAdditionalLayersRoot);
setIsExtended(false);
}} />
</Tooltip>
</div>
<Tooltip placement='bottom' title='Close' getPopupContainer={(triggerNode) => getAsideParentInHierarchy(triggerNode)}>
<Button type='link' shape='circle' icon={<CloseOutlined />} className='primary' onClick={() => {
KeyboardNavigationHelper.clearKeyboardLayer(props.assistantAdditionalLayersRoot, AdditionalLayerEnum.CURRENT_NAVIGATION);
KeyboardNavigationHelper.clearKeyboardLayer(props.assistantAdditionalLayersRoot, AdditionalLayerEnum.EXPECTED_NAVIGATION);
setIsExtended(false);
}} />
</Tooltip>
</Flex>
</header>
<div id={"toolbar"}>
<Tooltip placement='bottom' title='Copy' getPopupContainer={(triggerNode) => getAsideParentInHierarchy(triggerNode)}>
<Button type='link' shape='circle' icon={<CopyOutlined />} className='primary' onClick={copyResult} />
</Tooltip>
{menuAction === KeyboardActionEnum.GLOBAL_NAVIGATION ?
<Space direction='vertical'>
<Switch checkedChildren='Current' unCheckedChildren='Expected' defaultChecked
title={`Show ${toolbarAction === ToolbarActionEnum.CURRENT_NAVIGATION ? "expected" : "current"} keyboard navigation`}
onChange={switchKeyboardNavigationState} />
</Space>
: ""}
</div>
<CodeMirror
readOnly={true}
indentWithTab={true}
Expand Down
Loading

0 comments on commit a5e740d

Please sign in to comment.