fix: handle shift tab tab-index focus (#6554)
* handle shift tab tab-index focus * add comment * fix double tap * make label focus * fix title focus * focus discard and save * remove comment
This commit is contained in:
parent
feb88e64a4
commit
14083ea7da
9 changed files with 71 additions and 63 deletions
|
|
@ -51,6 +51,10 @@ export const ListKeymap = ({ tabIndex }: { tabIndex?: number }) =>
|
||||||
} else if (this.editor.commands.liftListItem("taskItem")) {
|
} else if (this.editor.commands.liftListItem("taskItem")) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
// if tabIndex is set, we don't want to handle Tab key
|
||||||
|
if (tabIndex !== undefined && tabIndex !== null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
Delete: ({ editor }) => {
|
Delete: ({ editor }) => {
|
||||||
|
|
|
||||||
|
|
@ -90,6 +90,7 @@ export const CycleDropdown: React.FC<Props> = observer((props) => {
|
||||||
)}
|
)}
|
||||||
onClick={handleOnClick}
|
onClick={handleOnClick}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
|
tabIndex={tabIndex}
|
||||||
>
|
>
|
||||||
{button}
|
{button}
|
||||||
</button>
|
</button>
|
||||||
|
|
@ -107,6 +108,7 @@ export const CycleDropdown: React.FC<Props> = observer((props) => {
|
||||||
)}
|
)}
|
||||||
onClick={handleOnClick}
|
onClick={handleOnClick}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
|
tabIndex={tabIndex}
|
||||||
>
|
>
|
||||||
<DropdownButton
|
<DropdownButton
|
||||||
className={buttonClassName}
|
className={buttonClassName}
|
||||||
|
|
@ -134,7 +136,6 @@ export const CycleDropdown: React.FC<Props> = observer((props) => {
|
||||||
<ComboDropDown
|
<ComboDropDown
|
||||||
as="div"
|
as="div"
|
||||||
ref={dropdownRef}
|
ref={dropdownRef}
|
||||||
tabIndex={tabIndex}
|
|
||||||
className={cn("h-full", className)}
|
className={cn("h-full", className)}
|
||||||
value={value}
|
value={value}
|
||||||
onChange={dropdownOnChange}
|
onChange={dropdownOnChange}
|
||||||
|
|
|
||||||
|
|
@ -113,6 +113,7 @@ export const MemberDropdown: React.FC<Props> = observer((props) => {
|
||||||
className={cn("clickable block h-full w-full outline-none", buttonContainerClassName)}
|
className={cn("clickable block h-full w-full outline-none", buttonContainerClassName)}
|
||||||
onClick={handleOnClick}
|
onClick={handleOnClick}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
|
tabIndex={tabIndex}
|
||||||
>
|
>
|
||||||
{button}
|
{button}
|
||||||
</button>
|
</button>
|
||||||
|
|
@ -130,6 +131,7 @@ export const MemberDropdown: React.FC<Props> = observer((props) => {
|
||||||
)}
|
)}
|
||||||
onClick={handleOnClick}
|
onClick={handleOnClick}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
|
tabIndex={tabIndex}
|
||||||
>
|
>
|
||||||
<DropdownButton
|
<DropdownButton
|
||||||
className={cn("text-xs", buttonClassName)}
|
className={cn("text-xs", buttonClassName)}
|
||||||
|
|
@ -161,7 +163,6 @@ export const MemberDropdown: React.FC<Props> = observer((props) => {
|
||||||
<ComboDropDown
|
<ComboDropDown
|
||||||
as="div"
|
as="div"
|
||||||
ref={dropdownRef}
|
ref={dropdownRef}
|
||||||
tabIndex={tabIndex}
|
|
||||||
className={cn("h-full", className)}
|
className={cn("h-full", className)}
|
||||||
onChange={dropdownOnChange}
|
onChange={dropdownOnChange}
|
||||||
onKeyDown={handleKeyDown}
|
onKeyDown={handleKeyDown}
|
||||||
|
|
|
||||||
|
|
@ -239,6 +239,7 @@ export const ModuleDropdown: React.FC<Props> = observer((props) => {
|
||||||
)}
|
)}
|
||||||
onClick={handleOnClick}
|
onClick={handleOnClick}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
|
tabIndex={tabIndex}
|
||||||
>
|
>
|
||||||
{button}
|
{button}
|
||||||
</button>
|
</button>
|
||||||
|
|
@ -256,6 +257,7 @@ export const ModuleDropdown: React.FC<Props> = observer((props) => {
|
||||||
)}
|
)}
|
||||||
onClick={handleOnClick}
|
onClick={handleOnClick}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
|
tabIndex={tabIndex}
|
||||||
>
|
>
|
||||||
<DropdownButton
|
<DropdownButton
|
||||||
className={buttonClassName}
|
className={buttonClassName}
|
||||||
|
|
@ -296,7 +298,6 @@ export const ModuleDropdown: React.FC<Props> = observer((props) => {
|
||||||
<ComboDropDown
|
<ComboDropDown
|
||||||
as="div"
|
as="div"
|
||||||
ref={dropdownRef}
|
ref={dropdownRef}
|
||||||
tabIndex={tabIndex}
|
|
||||||
className={cn("h-full", className)}
|
className={cn("h-full", className)}
|
||||||
onKeyDown={handleKeyDown}
|
onKeyDown={handleKeyDown}
|
||||||
button={comboButton}
|
button={comboButton}
|
||||||
|
|
|
||||||
|
|
@ -394,6 +394,7 @@ export const PriorityDropdown: React.FC<Props> = (props) => {
|
||||||
className={cn("clickable block h-full w-full outline-none", buttonContainerClassName)}
|
className={cn("clickable block h-full w-full outline-none", buttonContainerClassName)}
|
||||||
onClick={handleOnClick}
|
onClick={handleOnClick}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
|
tabIndex={tabIndex}
|
||||||
>
|
>
|
||||||
{button}
|
{button}
|
||||||
</button>
|
</button>
|
||||||
|
|
@ -411,6 +412,7 @@ export const PriorityDropdown: React.FC<Props> = (props) => {
|
||||||
)}
|
)}
|
||||||
onClick={handleOnClick}
|
onClick={handleOnClick}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
|
tabIndex={tabIndex}
|
||||||
>
|
>
|
||||||
<ButtonToRender
|
<ButtonToRender
|
||||||
priority={value ?? undefined}
|
priority={value ?? undefined}
|
||||||
|
|
@ -435,7 +437,6 @@ export const PriorityDropdown: React.FC<Props> = (props) => {
|
||||||
<ComboDropDown
|
<ComboDropDown
|
||||||
as="div"
|
as="div"
|
||||||
ref={dropdownRef}
|
ref={dropdownRef}
|
||||||
tabIndex={tabIndex}
|
|
||||||
className={cn(
|
className={cn(
|
||||||
"h-full",
|
"h-full",
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -141,11 +141,13 @@ export const StateDropdown: React.FC<Props> = observer((props) => {
|
||||||
className={cn("clickable block h-full w-full outline-none", buttonContainerClassName)}
|
className={cn("clickable block h-full w-full outline-none", buttonContainerClassName)}
|
||||||
onClick={handleOnClick}
|
onClick={handleOnClick}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
|
tabIndex={tabIndex}
|
||||||
>
|
>
|
||||||
{button}
|
{button}
|
||||||
</button>
|
</button>
|
||||||
) : (
|
) : (
|
||||||
<button
|
<button
|
||||||
|
tabIndex={tabIndex}
|
||||||
ref={setReferenceElement}
|
ref={setReferenceElement}
|
||||||
type="button"
|
type="button"
|
||||||
className={cn(
|
className={cn(
|
||||||
|
|
@ -197,7 +199,6 @@ export const StateDropdown: React.FC<Props> = observer((props) => {
|
||||||
<ComboDropDown
|
<ComboDropDown
|
||||||
as="div"
|
as="div"
|
||||||
ref={dropdownRef}
|
ref={dropdownRef}
|
||||||
tabIndex={tabIndex}
|
|
||||||
className={cn("h-full", className)}
|
className={cn("h-full", className)}
|
||||||
value={stateValue}
|
value={stateValue}
|
||||||
onChange={dropdownOnChange}
|
onChange={dropdownOnChange}
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ export const IssueTitleInput: React.FC<TIssueTitleInputProps> = observer((props)
|
||||||
return undefined;
|
return undefined;
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<>
|
<div tabIndex={getIndex("name")}>
|
||||||
<Controller
|
<Controller
|
||||||
control={control}
|
control={control}
|
||||||
name="name"
|
name="name"
|
||||||
|
|
@ -63,12 +63,11 @@ export const IssueTitleInput: React.FC<TIssueTitleInputProps> = observer((props)
|
||||||
hasError={Boolean(errors.name)}
|
hasError={Boolean(errors.name)}
|
||||||
placeholder={t("title")}
|
placeholder={t("title")}
|
||||||
className="w-full text-base"
|
className="w-full text-base"
|
||||||
tabIndex={getIndex("name")}
|
|
||||||
autoFocus
|
autoFocus
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
<span className="text-xs font-medium text-red-500">{errors?.name?.message}</span>
|
<span className="text-xs font-medium text-red-500">{errors?.name?.message}</span>
|
||||||
</>
|
</div>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -485,7 +485,7 @@ export const IssueFormRoot: FC<IssueFormProps> = observer((props) => {
|
||||||
setSelectedParentIssue={setSelectedParentIssue}
|
setSelectedParentIssue={setSelectedParentIssue}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center justify-end gap-4 py-3">
|
<div className="flex items-center justify-end gap-4 py-3" tabIndex={getIndex("create_more")}>
|
||||||
{!data?.id && (
|
{!data?.id && (
|
||||||
<div
|
<div
|
||||||
className="inline-flex items-center gap-1.5 cursor-pointer"
|
className="inline-flex items-center gap-1.5 cursor-pointer"
|
||||||
|
|
@ -493,7 +493,6 @@ export const IssueFormRoot: FC<IssueFormProps> = observer((props) => {
|
||||||
onKeyDown={(e) => {
|
onKeyDown={(e) => {
|
||||||
if (e.key === "Enter") onCreateMoreToggleChange(!isCreateMoreToggleEnabled);
|
if (e.key === "Enter") onCreateMoreToggleChange(!isCreateMoreToggleEnabled);
|
||||||
}}
|
}}
|
||||||
tabIndex={getIndex("create_more")}
|
|
||||||
role="button"
|
role="button"
|
||||||
>
|
>
|
||||||
<ToggleSwitch value={isCreateMoreToggleEnabled} onChange={() => {}} size="sm" />
|
<ToggleSwitch value={isCreateMoreToggleEnabled} onChange={() => {}} size="sm" />
|
||||||
|
|
@ -501,34 +500,37 @@ export const IssueFormRoot: FC<IssueFormProps> = observer((props) => {
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<Button
|
<div tabIndex={getIndex("discard_button")}>
|
||||||
variant="neutral-primary"
|
<Button
|
||||||
size="sm"
|
variant="neutral-primary"
|
||||||
onClick={() => {
|
size="sm"
|
||||||
if (editorRef.current?.isEditorReadyToDiscard()) {
|
onClick={() => {
|
||||||
onClose();
|
if (editorRef.current?.isEditorReadyToDiscard()) {
|
||||||
} else {
|
onClose();
|
||||||
setToast({
|
} else {
|
||||||
type: TOAST_TYPE.ERROR,
|
setToast({
|
||||||
title: "Error!",
|
type: TOAST_TYPE.ERROR,
|
||||||
message: "Editor is still processing changes. Please wait before proceeding.",
|
title: "Error!",
|
||||||
});
|
message: "Editor is still processing changes. Please wait before proceeding.",
|
||||||
}
|
});
|
||||||
}}
|
}
|
||||||
tabIndex={getIndex("discard_button")}
|
}}
|
||||||
>
|
>
|
||||||
{t("discard")}
|
{t("discard")}
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
</div>
|
||||||
variant={moveToIssue ? "neutral-primary" : "primary"}
|
<div tabIndex={isDraft ? getIndex("submit_button") : getIndex("draft_button")}>
|
||||||
type="submit"
|
<Button
|
||||||
size="sm"
|
variant={moveToIssue ? "neutral-primary" : "primary"}
|
||||||
ref={submitBtnRef}
|
type="submit"
|
||||||
loading={isSubmitting}
|
size="sm"
|
||||||
tabIndex={isDraft ? getIndex("submit_button") : getIndex("draft_button")}
|
ref={submitBtnRef}
|
||||||
>
|
loading={isSubmitting}
|
||||||
{isSubmitting ? primaryButtonText.loading : primaryButtonText.default}
|
>
|
||||||
</Button>
|
{isSubmitting ? primaryButtonText.loading : primaryButtonText.default}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
|
||||||
{moveToIssue && (
|
{moveToIssue && (
|
||||||
<Button
|
<Button
|
||||||
variant="primary"
|
variant="primary"
|
||||||
|
|
|
||||||
|
|
@ -112,31 +112,29 @@ export const IssueLabelSelect: React.FC<Props> = observer((props) => {
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
onKeyDown={handleKeyDown}
|
onKeyDown={handleKeyDown}
|
||||||
>
|
>
|
||||||
<Combobox.Button as={Fragment}>
|
<button
|
||||||
<button
|
type="button"
|
||||||
type="button"
|
ref={setReferenceElement}
|
||||||
ref={setReferenceElement}
|
className={cn("h-full flex cursor-pointer items-center gap-2 text-xs text-custom-text-200", buttonClassName)}
|
||||||
className={cn("h-full flex cursor-pointer items-center gap-2 text-xs text-custom-text-200", buttonClassName)}
|
onClick={handleOnClick}
|
||||||
onClick={handleOnClick}
|
>
|
||||||
>
|
{label ? (
|
||||||
{label ? (
|
label
|
||||||
label
|
) : value && value.length > 0 ? (
|
||||||
) : value && value.length > 0 ? (
|
<span className="flex items-center justify-center gap-2 text-xs h-full">
|
||||||
<span className="flex items-center justify-center gap-2 text-xs h-full">
|
<IssueLabelsList
|
||||||
<IssueLabelsList
|
labels={value.map((v) => projectLabels?.find((l) => l.id === v)) ?? []}
|
||||||
labels={value.map((v) => projectLabels?.find((l) => l.id === v)) ?? []}
|
length={3}
|
||||||
length={3}
|
showLength
|
||||||
showLength
|
/>
|
||||||
/>
|
</span>
|
||||||
</span>
|
) : (
|
||||||
) : (
|
<div className="h-full flex items-center justify-center gap-1 rounded border-[0.5px] border-custom-border-300 px-2 py-1 text-xs hover:bg-custom-background-80">
|
||||||
<div className="h-full flex items-center justify-center gap-1 rounded border-[0.5px] border-custom-border-300 px-2 py-1 text-xs hover:bg-custom-background-80">
|
<Tag className="h-3 w-3 flex-shrink-0" />
|
||||||
<Tag className="h-3 w-3 flex-shrink-0" />
|
<span>{t("labels")}</span>
|
||||||
<span>{t("labels")}</span>
|
</div>
|
||||||
</div>
|
)}
|
||||||
)}
|
</button>
|
||||||
</button>
|
|
||||||
</Combobox.Button>
|
|
||||||
|
|
||||||
{isDropdownOpen && (
|
{isDropdownOpen && (
|
||||||
<Combobox.Options className="fixed z-10" static>
|
<Combobox.Options className="fixed z-10" static>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue