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 22, 2024
1 parent 4d318a2 commit 9916ed9
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 25 deletions.
File renamed without changes.
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
93 changes: 71 additions & 22 deletions packages/assistant/src/UuvAssistant.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,26 @@
import React, { useEffect, useState } from "react";
import uuvLogoJson from "./assets/uuvLogo.json";

import { BaseSentence, CheckActionEnum, KeyboardActionEnum, StepCaseEnum, TranslateHelper, TranslateSentences } from "./helper/TranslateHelper";
import {
ActionEnum,
BaseSentence,
CheckActionEnum,
KeyboardActionEnum,
StepCaseEnum,
ToolbarActionEnum,
TranslateHelper,
TranslateSentences
} from "./helper/TranslateHelper";
import { Avatar, Button, ConfigProvider, Divider, Flex, Layout, Menu, MenuProps, notification, Spin, theme, Tooltip, Typography } from "antd";
import { CloseOutlined, CopyOutlined, DesktopOutlined, DoubleLeftOutlined, DoubleRightOutlined, InteractionOutlined } from "@ant-design/icons";
import {
BranchesOutlined,
CloseOutlined,
CopyOutlined,
DesktopOutlined,
DoubleLeftOutlined,
DoubleRightOutlined,
InteractionOutlined
} from "@ant-design/icons";
import { StyleProvider } from "@ant-design/cssinjs";
import { CssHelper } from "./helper/CssHelper";
import { FocusableElement, tabbable } from "tabbable";
Expand All @@ -29,8 +46,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 { ResultSentence, Suggestion } from "./Commons";

type UuvAssistantProps = {
translator?: (el: FocusableElement) => string;
Expand All @@ -41,22 +58,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 +88,7 @@ function UuvAssistant(props: UuvAssistantProps) {
setGeneratedScript(
buildResultingScript(
"Your amazing feature name",
`Action - ${checkAction}`,
`Action - ${menuAction}`,
data.map(sentence => sentence.result)
)
);
Expand All @@ -93,7 +112,7 @@ function UuvAssistant(props: UuvAssistantProps) {

function reset() {
inspector.cancel();
setCheckAction(CheckActionEnum.NONE);
setMenuAction(CheckActionEnum.NONE);
setDisabledElement("");
setIsDark(true);
setIsHide(false);
Expand Down Expand Up @@ -128,7 +147,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 @@ -150,8 +169,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 +182,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 +224,6 @@ function UuvAssistant(props: UuvAssistantProps) {
data.map(sentence => sentence.result)
)
);
KeyboardNavigationHelper.buildKeyboardLayer(props.assistantAdditionalLayersRoot, currentKeyboardNavigation);
setIsExtended(true);
}
}
Expand All @@ -222,7 +241,7 @@ function UuvAssistant(props: UuvAssistantProps) {

const handleSelectCheckActionClick = (newValue: CheckActionEnum) => {
KeyboardNavigationHelper.clearKeyboardLayer(props.assistantAdditionalLayersRoot);
setCheckAction(newValue);
setMenuAction(newValue);
setIsHide(true);
startSelect();
};
Expand Down Expand Up @@ -277,7 +296,10 @@ 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();
})
])
];

Expand All @@ -300,19 +322,46 @@ 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>
</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 ?
<>
<Tooltip placement='bottom' title='Show current keyboard navigation'
getPopupContainer={(triggerNode) => getAsideParentInHierarchy(triggerNode)}>
<Button type='link' shape='circle' icon={<BranchesOutlined className={`keyboardicon ${toolbarAction === ToolbarActionEnum.CURRENT_NAVIGATION ? "active" : ""}`} style={{ color:"#cccccc" }}/>} className='primary' onClick={() => {
if (toolbarAction) {
KeyboardNavigationHelper.clearKeyboardLayer(props.assistantAdditionalLayersRoot);
setToolbarAction(undefined);
} else {
KeyboardNavigationHelper.buildKeyboardLayer(props.assistantAdditionalLayersRoot, expectedKeyboardNavigation);
setToolbarAction(ToolbarActionEnum.CURRENT_NAVIGATION);
}
}} />
</Tooltip>
<Tooltip placement='bottom' title='Show expected keyboard navigation'
getPopupContainer={(triggerNode) => getAsideParentInHierarchy(triggerNode)}>
<Button type='link' shape='circle' icon={<BranchesOutlined rotate={180} className={`keyboardicon ${toolbarAction === ToolbarActionEnum.EXPECTED_NAVIGATION ? "active" : ""}`}/>} className='primary' onClick={() => {
if (toolbarAction) {
KeyboardNavigationHelper.clearKeyboardLayer(props.assistantAdditionalLayersRoot);
setToolbarAction(undefined);
} else {
KeyboardNavigationHelper.buildKeyboardLayer(props.assistantAdditionalLayersRoot, expectedKeyboardNavigation);
setToolbarAction(ToolbarActionEnum.EXPECTED_NAVIGATION);
}
}} />
</Tooltip>
</> : ""}
</div>
<CodeMirror
readOnly={true}
indentWithTab={true}
Expand Down
10 changes: 8 additions & 2 deletions packages/assistant/src/helper/TranslateHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@


import { computeAccessibleName, getRole } from "dom-accessibility-api";
import { EN_ROLES, enSentences, enBasedRoleSentences } from "@uuv/runner-commons/wording/web/en";
import { EN_ROLES, enBasedRoleSentences, enSentences } from "@uuv/runner-commons/wording/web/en";
import { FocusableElement } from "tabbable";

export class Suggestion {
Expand All @@ -41,12 +41,18 @@ export type EnrichedSentence = {
wording: string;
}

export type ActionEnum = CheckActionEnum | KeyboardActionEnum;
export enum CheckActionEnum {
NONE = "None", WITHIN = "Within", EXPECT = "Expect", CLICK = "Click"
}

export enum KeyboardActionEnum {
GLOBAL_NAVIGATION = "Navigation"
GLOBAL_NAVIGATION = "Navigation",
}

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

export enum StepCaseEnum {
Expand Down

0 comments on commit 9916ed9

Please sign in to comment.