feat: Keyboard accessible property pane header (#11339)

This commit is contained in:
Aswath K 2022-02-24 12:34:31 +05:30 committed by GitHub
parent bd9636f514
commit 2ad121a092
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 52 additions and 18 deletions

View File

@ -378,7 +378,8 @@ const ButtonStyles = css<ThemeProp & ButtonProps>`
fill: ${(props) => btnColorStyles(props, "main").txtColor};
}
}
&:hover {
&:hover,
&:focus {
text-decoration: none;
background-color: ${(props) => btnColorStyles(props, "hover").bgColor};
color: ${(props) => btnColorStyles(props, "hover").txtColor};

View File

@ -687,14 +687,6 @@ export function RenderDropdownOptions(props: DropdownOptionsProps) {
maxHeight={props.dropdownMaxHeight || "auto"}
>
{options.map((option: DropdownOption, index: number) => {
if (renderOption) {
return renderOption({
option,
index,
optionClickHandler,
optionWidth,
});
}
let isSelected = false;
if (
props.isMultiSelect &&
@ -708,6 +700,15 @@ export function RenderDropdownOptions(props: DropdownOptionsProps) {
isSelected =
(props.selected as DropdownOption).value === option.value;
}
if (renderOption) {
return renderOption({
option,
index,
optionClickHandler,
optionWidth,
isSelectedNode: isSelected,
});
}
return !option.isSectionHeader ? (
<OptionWrapper
aria-selected={isSelected}

View File

@ -30,10 +30,11 @@ const StyledDiv = styled.div`
props.theme.spaces[7]}px;
margin: ${(props) => props.theme.spaces[2]}px 0px;
a:first-child {
button:first-child {
margin-top: ${(props) => props.theme.spaces[2]}px;
width: 100%;
}
a:nth-child(2) {
button:nth-child(2) {
border: none;
background-color: transparent;
text-transform: none;
@ -43,7 +44,7 @@ const StyledDiv = styled.div`
${(props) => getTypographyByKey(props, "p3")}
margin-top: ${(props) => props.theme.spaces[2]}px;
:hover {
:hover, :focus {
text-decoration: underline;
}
}
@ -95,11 +96,15 @@ function ConnectDataCTA(props: ConnectDataCTAProps) {
category={Category.primary}
onClick={onClick}
size={Size.large}
tabIndex={0}
tag="button"
text="CONNECT DATA"
/>
<Button
category={Category.tertiary}
onClick={openHelpModal}
tabIndex={0}
tag="button"
text="Learn more"
/>
</StyledDiv>

View File

@ -1,4 +1,4 @@
import React, { memo, useMemo, useCallback } from "react";
import React, { memo, useMemo, useCallback, useEffect } from "react";
import styled from "styled-components";
import Icon, { IconSize } from "components/ads/Icon";
import Dropdown, {
@ -125,6 +125,7 @@ const OptionWrapper = styled.div<{ hasError: boolean; fillIconColor: boolean }>`
const OptionContentWrapper = styled.div<{
hasError: boolean;
isSelected: boolean;
}>`
padding: ${(props) => props.theme.spaces[2] + 1}px
${(props) => props.theme.spaces[5]}px;
@ -134,6 +135,10 @@ const OptionContentWrapper = styled.div<{
line-height: 8px;
flex: 1;
min-width: 0;
background-color: ${(props) =>
props.isSelected &&
!props.hasError &&
props.theme.colors.dropdown.hovered.bg};
span:first-child {
font-size: 10px;
@ -210,7 +215,7 @@ const useDependencyList = (name: string) => {
const dependencyOptions =
entityDependencies?.directDependencies.map((e) => ({
label: e,
value: getEntityId(e),
value: getEntityId(e) ?? e,
})) ?? [];
const inverseDependencyOptions =
entityDependencies?.inverseDependencies.map((e) => ({
@ -245,12 +250,28 @@ function OptionNode(props: any) {
});
};
const handleKeyDown = (e: KeyboardEvent) => {
if (!props.isSelectedNode) return;
if (e.key === " " || e.key === "Enter") onClick();
};
useEffect(() => {
document.addEventListener("keydown", handleKeyDown);
return () => {
document.removeEventListener("keydown", handleKeyDown);
};
}, [props.isSelectedNode]);
return (
<OptionWrapper
fillIconColor={!entityInfo?.datasourceName}
hasError={!!entityInfo?.hasError}
>
<OptionContentWrapper hasError={!!entityInfo?.hasError} onClick={onClick}>
<OptionContentWrapper
hasError={!!entityInfo?.hasError}
isSelected={props.isSelectedNode}
onClick={onClick}
>
<span>{entityInfo?.icon}</span>
<Text type={TextType.H6}>
{props.option.label}{" "}
@ -297,6 +318,7 @@ const TriggerNode = memo((props: TriggerNodeProps) => {
<Tooltip
content={tooltipText}
disabled={props.isOpen}
openOnTargetFocus={false}
position={props.tooltipPosition}
>
{props.entityCount ? `${props.entityCount} ${ENTITY}` : "No Entity"}
@ -360,7 +382,12 @@ function PropertyPaneConnections(props: PropertyPaneConnectionsProps) {
height={`${CONNECTION_HEIGHT}px`}
options={dependencies.dependencyOptions}
renderOption={(optionProps) => {
return <OptionNode option={optionProps.option} />;
return (
<OptionNode
isSelectedNode={optionProps.isSelectedNode}
option={optionProps.option}
/>
);
}}
selected={selectedOption}
showDropIcon={false}

View File

@ -73,7 +73,7 @@ function PropertyPaneView(
tooltipPosition: "bottom-right",
icon: (
<button
className="p-1 hover:bg-warmGray-100 group t--copy-widget"
className="p-1 hover:bg-warmGray-100 focus:bg-warmGray-100 group t--copy-widget"
onClick={onCopy}
>
<CopyIcon className="w-4 h-4 text-gray-500" />
@ -85,7 +85,7 @@ function PropertyPaneView(
tooltipPosition: "bottom-right",
icon: (
<button
className="p-1 hover:bg-warmGray-100 group t--delete-widget"
className="p-1 hover:bg-warmGray-100 focus:bg-warmGray-100 group t--delete-widget"
onClick={onDelete}
>
<DeleteIcon className="w-4 h-4 text-gray-500" />