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:
Vipin Chaudhary 2025-02-08 20:54:23 +05:30 committed by GitHub
parent feb88e64a4
commit 14083ea7da
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 71 additions and 63 deletions

View file

@ -51,6 +51,10 @@ export const ListKeymap = ({ tabIndex }: { tabIndex?: number }) =>
} else if (this.editor.commands.liftListItem("taskItem")) {
return true;
}
// if tabIndex is set, we don't want to handle Tab key
if (tabIndex !== undefined && tabIndex !== null) {
return false;
}
return true;
},
Delete: ({ editor }) => {

View file

@ -90,6 +90,7 @@ export const CycleDropdown: React.FC<Props> = observer((props) => {
)}
onClick={handleOnClick}
disabled={disabled}
tabIndex={tabIndex}
>
{button}
</button>
@ -107,6 +108,7 @@ export const CycleDropdown: React.FC<Props> = observer((props) => {
)}
onClick={handleOnClick}
disabled={disabled}
tabIndex={tabIndex}
>
<DropdownButton
className={buttonClassName}
@ -134,7 +136,6 @@ export const CycleDropdown: React.FC<Props> = observer((props) => {
<ComboDropDown
as="div"
ref={dropdownRef}
tabIndex={tabIndex}
className={cn("h-full", className)}
value={value}
onChange={dropdownOnChange}

View file

@ -113,6 +113,7 @@ export const MemberDropdown: React.FC<Props> = observer((props) => {
className={cn("clickable block h-full w-full outline-none", buttonContainerClassName)}
onClick={handleOnClick}
disabled={disabled}
tabIndex={tabIndex}
>
{button}
</button>
@ -130,6 +131,7 @@ export const MemberDropdown: React.FC<Props> = observer((props) => {
)}
onClick={handleOnClick}
disabled={disabled}
tabIndex={tabIndex}
>
<DropdownButton
className={cn("text-xs", buttonClassName)}
@ -161,7 +163,6 @@ export const MemberDropdown: React.FC<Props> = observer((props) => {
<ComboDropDown
as="div"
ref={dropdownRef}
tabIndex={tabIndex}
className={cn("h-full", className)}
onChange={dropdownOnChange}
onKeyDown={handleKeyDown}

View file

@ -239,6 +239,7 @@ export const ModuleDropdown: React.FC<Props> = observer((props) => {
)}
onClick={handleOnClick}
disabled={disabled}
tabIndex={tabIndex}
>
{button}
</button>
@ -256,6 +257,7 @@ export const ModuleDropdown: React.FC<Props> = observer((props) => {
)}
onClick={handleOnClick}
disabled={disabled}
tabIndex={tabIndex}
>
<DropdownButton
className={buttonClassName}
@ -296,7 +298,6 @@ export const ModuleDropdown: React.FC<Props> = observer((props) => {
<ComboDropDown
as="div"
ref={dropdownRef}
tabIndex={tabIndex}
className={cn("h-full", className)}
onKeyDown={handleKeyDown}
button={comboButton}

View file

@ -394,6 +394,7 @@ export const PriorityDropdown: React.FC<Props> = (props) => {
className={cn("clickable block h-full w-full outline-none", buttonContainerClassName)}
onClick={handleOnClick}
disabled={disabled}
tabIndex={tabIndex}
>
{button}
</button>
@ -411,6 +412,7 @@ export const PriorityDropdown: React.FC<Props> = (props) => {
)}
onClick={handleOnClick}
disabled={disabled}
tabIndex={tabIndex}
>
<ButtonToRender
priority={value ?? undefined}
@ -435,7 +437,6 @@ export const PriorityDropdown: React.FC<Props> = (props) => {
<ComboDropDown
as="div"
ref={dropdownRef}
tabIndex={tabIndex}
className={cn(
"h-full",
{

View file

@ -141,11 +141,13 @@ export const StateDropdown: React.FC<Props> = observer((props) => {
className={cn("clickable block h-full w-full outline-none", buttonContainerClassName)}
onClick={handleOnClick}
disabled={disabled}
tabIndex={tabIndex}
>
{button}
</button>
) : (
<button
tabIndex={tabIndex}
ref={setReferenceElement}
type="button"
className={cn(
@ -197,7 +199,6 @@ export const StateDropdown: React.FC<Props> = observer((props) => {
<ComboDropDown
as="div"
ref={dropdownRef}
tabIndex={tabIndex}
className={cn("h-full", className)}
value={stateValue}
onChange={dropdownOnChange}

View file

@ -37,7 +37,7 @@ export const IssueTitleInput: React.FC<TIssueTitleInputProps> = observer((props)
return undefined;
};
return (
<>
<div tabIndex={getIndex("name")}>
<Controller
control={control}
name="name"
@ -63,12 +63,11 @@ export const IssueTitleInput: React.FC<TIssueTitleInputProps> = observer((props)
hasError={Boolean(errors.name)}
placeholder={t("title")}
className="w-full text-base"
tabIndex={getIndex("name")}
autoFocus
/>
)}
/>
<span className="text-xs font-medium text-red-500">{errors?.name?.message}</span>
</>
</div>
);
});

View file

@ -485,7 +485,7 @@ export const IssueFormRoot: FC<IssueFormProps> = observer((props) => {
setSelectedParentIssue={setSelectedParentIssue}
/>
</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 && (
<div
className="inline-flex items-center gap-1.5 cursor-pointer"
@ -493,7 +493,6 @@ export const IssueFormRoot: FC<IssueFormProps> = observer((props) => {
onKeyDown={(e) => {
if (e.key === "Enter") onCreateMoreToggleChange(!isCreateMoreToggleEnabled);
}}
tabIndex={getIndex("create_more")}
role="button"
>
<ToggleSwitch value={isCreateMoreToggleEnabled} onChange={() => {}} size="sm" />
@ -501,34 +500,37 @@ export const IssueFormRoot: FC<IssueFormProps> = observer((props) => {
</div>
)}
<div className="flex items-center gap-2">
<Button
variant="neutral-primary"
size="sm"
onClick={() => {
if (editorRef.current?.isEditorReadyToDiscard()) {
onClose();
} else {
setToast({
type: TOAST_TYPE.ERROR,
title: "Error!",
message: "Editor is still processing changes. Please wait before proceeding.",
});
}
}}
tabIndex={getIndex("discard_button")}
>
{t("discard")}
</Button>
<Button
variant={moveToIssue ? "neutral-primary" : "primary"}
type="submit"
size="sm"
ref={submitBtnRef}
loading={isSubmitting}
tabIndex={isDraft ? getIndex("submit_button") : getIndex("draft_button")}
>
{isSubmitting ? primaryButtonText.loading : primaryButtonText.default}
</Button>
<div tabIndex={getIndex("discard_button")}>
<Button
variant="neutral-primary"
size="sm"
onClick={() => {
if (editorRef.current?.isEditorReadyToDiscard()) {
onClose();
} else {
setToast({
type: TOAST_TYPE.ERROR,
title: "Error!",
message: "Editor is still processing changes. Please wait before proceeding.",
});
}
}}
>
{t("discard")}
</Button>
</div>
<div tabIndex={isDraft ? getIndex("submit_button") : getIndex("draft_button")}>
<Button
variant={moveToIssue ? "neutral-primary" : "primary"}
type="submit"
size="sm"
ref={submitBtnRef}
loading={isSubmitting}
>
{isSubmitting ? primaryButtonText.loading : primaryButtonText.default}
</Button>
</div>
{moveToIssue && (
<Button
variant="primary"

View file

@ -112,31 +112,29 @@ export const IssueLabelSelect: React.FC<Props> = observer((props) => {
disabled={disabled}
onKeyDown={handleKeyDown}
>
<Combobox.Button as={Fragment}>
<button
type="button"
ref={setReferenceElement}
className={cn("h-full flex cursor-pointer items-center gap-2 text-xs text-custom-text-200", buttonClassName)}
onClick={handleOnClick}
>
{label ? (
label
) : value && value.length > 0 ? (
<span className="flex items-center justify-center gap-2 text-xs h-full">
<IssueLabelsList
labels={value.map((v) => projectLabels?.find((l) => l.id === v)) ?? []}
length={3}
showLength
/>
</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">
<Tag className="h-3 w-3 flex-shrink-0" />
<span>{t("labels")}</span>
</div>
)}
</button>
</Combobox.Button>
<button
type="button"
ref={setReferenceElement}
className={cn("h-full flex cursor-pointer items-center gap-2 text-xs text-custom-text-200", buttonClassName)}
onClick={handleOnClick}
>
{label ? (
label
) : value && value.length > 0 ? (
<span className="flex items-center justify-center gap-2 text-xs h-full">
<IssueLabelsList
labels={value.map((v) => projectLabels?.find((l) => l.id === v)) ?? []}
length={3}
showLength
/>
</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">
<Tag className="h-3 w-3 flex-shrink-0" />
<span>{t("labels")}</span>
</div>
)}
</button>
{isDropdownOpen && (
<Combobox.Options className="fixed z-10" static>