Skip to content

Commit

Permalink
[8.x] [Index management] Fix a11y focus order in index mappings page (#…
Browse files Browse the repository at this point in the history
…203361) (#203628)

# Backport

This will backport the following commits from `main` to `8.x`:
- [[Index management] Fix a11y focus order in index mappings page
(#203361)](#203361)

<!--- Backport version: 9.4.3 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)

<!--BACKPORT [{"author":{"name":"Saarika
Bhasi","email":"[email protected]"},"sourceCommit":{"committedDate":"2024-12-10T15:46:20Z","message":"[Index
management] Fix a11y focus order in index mappings page (#203361)\n\n##
Summary\r\n\r\nFix a11y focus order in index mappings page. When new
field is in\r\npending state and after closing edit pending field
Flyout.\r\n\r\n\r\nhttps://github.com/user-attachments/assets/dbdf59e5-0ebd-47e0-9b5e-19ab1556e771\r\n\r\n###
Test instructions \r\n#### Adding a field\r\n1. Add new field in index
mappings page by navigating via tab \r\n2. Notice that type fields combo
box is focused\r\n3. Add field and click to Add field button again with
in pending fields\r\nform\r\n4. Notice focus is on new create field
form\r\n\r\n#### Edit field in pending state\r\n1. Add new fields via
tab key\r\n2. click on edit field \r\n3. Try closing, updating and
cancelling in the edit field flyout form\r\n4. Notice after edit field
flyout is closed, focus is on the pending\r\nfields
form","sha":"4b0c0e92693ad759e3ce45b4b259c9908ddd0d51","branchLabelMapping":{"^v9.0.0$":"main","^v8.18.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","v9.0.0","Team:Search","backport:prev-major","v8.16.0","v8.17.0"],"title":"[Index
management] Fix a11y focus order in index mappings page
","number":203361,"url":"https://github.com/elastic/kibana/pull/203361","mergeCommit":{"message":"[Index
management] Fix a11y focus order in index mappings page (#203361)\n\n##
Summary\r\n\r\nFix a11y focus order in index mappings page. When new
field is in\r\npending state and after closing edit pending field
Flyout.\r\n\r\n\r\nhttps://github.com/user-attachments/assets/dbdf59e5-0ebd-47e0-9b5e-19ab1556e771\r\n\r\n###
Test instructions \r\n#### Adding a field\r\n1. Add new field in index
mappings page by navigating via tab \r\n2. Notice that type fields combo
box is focused\r\n3. Add field and click to Add field button again with
in pending fields\r\nform\r\n4. Notice focus is on new create field
form\r\n\r\n#### Edit field in pending state\r\n1. Add new fields via
tab key\r\n2. click on edit field \r\n3. Try closing, updating and
cancelling in the edit field flyout form\r\n4. Notice after edit field
flyout is closed, focus is on the pending\r\nfields
form","sha":"4b0c0e92693ad759e3ce45b4b259c9908ddd0d51"}},"sourceBranch":"main","suggestedTargetBranches":["8.16","8.17"],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","branchLabelMappingKey":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/203361","number":203361,"mergeCommit":{"message":"[Index
management] Fix a11y focus order in index mappings page (#203361)\n\n##
Summary\r\n\r\nFix a11y focus order in index mappings page. When new
field is in\r\npending state and after closing edit pending field
Flyout.\r\n\r\n\r\nhttps://github.com/user-attachments/assets/dbdf59e5-0ebd-47e0-9b5e-19ab1556e771\r\n\r\n###
Test instructions \r\n#### Adding a field\r\n1. Add new field in index
mappings page by navigating via tab \r\n2. Notice that type fields combo
box is focused\r\n3. Add field and click to Add field button again with
in pending fields\r\nform\r\n4. Notice focus is on new create field
form\r\n\r\n#### Edit field in pending state\r\n1. Add new fields via
tab key\r\n2. click on edit field \r\n3. Try closing, updating and
cancelling in the edit field flyout form\r\n4. Notice after edit field
flyout is closed, focus is on the pending\r\nfields
form","sha":"4b0c0e92693ad759e3ce45b4b259c9908ddd0d51"}},{"branch":"8.16","label":"v8.16.0","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"8.17","label":"v8.17.0","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"}]}]
BACKPORT-->

Co-authored-by: Saarika Bhasi <[email protected]>
  • Loading branch information
kibanamachine and saarikabhasi authored Dec 10, 2024
1 parent 85f8a4b commit 049400b
Show file tree
Hide file tree
Showing 8 changed files with 51 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ interface Props {
onCancelAddingNewFields?: () => void;
isAddingFields?: boolean;
semanticTextInfo?: SemanticTextInfo;
pendingFieldsRef?: React.RefObject<HTMLDivElement>;
}
export const DocumentFields = React.memo(
({
Expand All @@ -35,6 +36,7 @@ export const DocumentFields = React.memo(
onCancelAddingNewFields,
isAddingFields,
semanticTextInfo,
pendingFieldsRef,
}: Props) => {
const { fields, documentFields } = useMappingsState();
const dispatch = useDispatch();
Expand All @@ -58,6 +60,7 @@ export const DocumentFields = React.memo(
onCancelAddingNewFields={onCancelAddingNewFields}
isAddingFields={isAddingFields}
semanticTextInfo={semanticTextInfo}
pendingFieldsRef={pendingFieldsRef}
/>
);

Expand All @@ -81,8 +84,9 @@ export const DocumentFields = React.memo(
useEffect(() => {
if (!isEditing) {
removeContentFromGlobalFlyout('mappingsEditField');
if (pendingFieldsRef?.current) pendingFieldsRef.current.focus();
}
}, [isEditing, removeContentFromGlobalFlyout]);
}, [isEditing, removeContentFromGlobalFlyout, pendingFieldsRef]);

useEffect(() => {
return () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,15 @@ interface Props {
isMultiField?: boolean | null;
showDocLink?: boolean;
isSemanticTextEnabled?: boolean;
fieldTypeInputRef?: React.MutableRefObject<HTMLInputElement | null>;
}

export const TypeParameter = ({
isMultiField,
isRootLevelField,
showDocLink = false,
isSemanticTextEnabled = true,
fieldTypeInputRef,
}: Props) => {
const fieldTypeOptions = useMemo(() => {
let options = isMultiField
Expand Down Expand Up @@ -97,6 +99,9 @@ export const TypeParameter = ({
onChange={typeField.setValue}
isClearable={false}
data-test-subj="fieldType"
inputRef={(input) => {
if (fieldTypeInputRef) fieldTypeInputRef.current = input;
}}
/>
</EuiFormRow>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { i18n } from '@kbn/i18n';
import { TrainedModelStat } from '@kbn/ml-plugin/common/types/trained_models';
import { MlPluginStart } from '@kbn/ml-plugin/public';
import classNames from 'classnames';
import React, { useEffect } from 'react';
import React, { useEffect, useRef } from 'react';
import { EUI_SIZE, TYPE_DEFINITION } from '../../../../constants';
import { fieldSerializer } from '../../../../lib';
import { isSemanticTextField } from '../../../../lib/utils';
Expand Down Expand Up @@ -62,6 +62,7 @@ interface Props {
onCancelAddingNewFields?: () => void;
isAddingFields?: boolean;
semanticTextInfo?: SemanticTextInfo;
createFieldFormRef?: React.RefObject<HTMLDivElement>;
}

export const CreateField = React.memo(function CreateFieldComponent({
Expand All @@ -74,9 +75,11 @@ export const CreateField = React.memo(function CreateFieldComponent({
onCancelAddingNewFields,
isAddingFields,
semanticTextInfo,
createFieldFormRef,
}: Props) {
const { isSemanticTextEnabled, ml, setErrorsInTrainedModelDeployment } = semanticTextInfo ?? {};
const dispatch = useDispatch();
const fieldTypeInputRef = useRef<HTMLInputElement>(null);

const { form } = useForm<Field>({
serializer: fieldSerializer,
Expand Down Expand Up @@ -111,6 +114,10 @@ export const CreateField = React.memo(function CreateFieldComponent({

const isSemanticText = form.getFormData().type === 'semantic_text';

useEffect(() => {
if (createFieldFormRef?.current) createFieldFormRef?.current.focus();
}, [createFieldFormRef]);

const submitForm = async (
e?: React.FormEvent,
exitAfter: boolean = false,
Expand All @@ -134,6 +141,10 @@ export const CreateField = React.memo(function CreateFieldComponent({
}
form.reset();
}

if (fieldTypeInputRef.current) {
fieldTypeInputRef.current.focus();
}
};

const onClickOutside = () => {
Expand All @@ -157,6 +168,7 @@ export const CreateField = React.memo(function CreateFieldComponent({
isMultiField={isMultiField}
showDocLink
isSemanticTextEnabled={isSemanticTextEnabled}
fieldTypeInputRef={fieldTypeInputRef}
/>
</EuiFlexItem>

Expand Down Expand Up @@ -266,6 +278,8 @@ export const CreateField = React.memo(function CreateFieldComponent({
: paddingLeft
}px`,
}}
ref={createFieldFormRef}
tabIndex={0}
>
<div className="mappingsEditor__createFieldContent">
{renderFormFields()}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ interface Props {
state: State;
setPreviousState?: (state: State) => void;
isAddingFields?: boolean;
pendingFieldsRef?: React.RefObject<HTMLDivElement>;
}

export const FieldsList = React.memo(function FieldsListComponent({
Expand All @@ -24,6 +25,7 @@ export const FieldsList = React.memo(function FieldsListComponent({
state,
setPreviousState,
isAddingFields,
pendingFieldsRef,
}: Props) {
if (fields === undefined) {
return null;
Expand All @@ -39,6 +41,7 @@ export const FieldsList = React.memo(function FieldsListComponent({
state={state}
setPreviousState={setPreviousState}
isAddingFields={isAddingFields}
pendingFieldsRef={pendingFieldsRef}
/>
))}
</ul>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ interface Props {
treeDepth: number;
state: State;
isAddingFields?: boolean;
createFieldFormRef?: React.RefObject<HTMLDivElement>;
pendingFieldsRef?: React.RefObject<HTMLDivElement>;
}

function FieldListItemComponent(
Expand All @@ -85,6 +87,7 @@ function FieldListItemComponent(
state,
isAddingFields,
setPreviousState,
pendingFieldsRef,
}: Props,
ref: React.Ref<HTMLLIElement>
) {
Expand Down Expand Up @@ -141,7 +144,6 @@ function FieldListItemComponent(

const { addMultiFieldButtonLabel, addPropertyButtonLabel, editButtonLabel, deleteButtonLabel } =
i18nTexts;

return (
<EuiFlexGroup gutterSize="s" className="mappingsEditor__fieldsListItem__actions">
{canHaveMultiFields && (
Expand Down Expand Up @@ -321,6 +323,7 @@ function FieldListItemComponent(
state={state}
isAddingFields={isAddingFields}
setPreviousState={setPreviousState}
pendingFieldsRef={pendingFieldsRef}
/>
)}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ interface Props {
state: State;
setPreviousState?: (state: State) => void;
isAddingFields?: boolean;
pendingFieldsRef?: React.RefObject<HTMLDivElement>;
}

export const FieldsListItemContainer = ({
Expand All @@ -27,6 +28,7 @@ export const FieldsListItemContainer = ({
state,
setPreviousState,
isAddingFields,
pendingFieldsRef,
}: Props) => {
const dispatch = useDispatch();
const listElement = useRef<HTMLLIElement | null>(null);
Expand Down Expand Up @@ -110,6 +112,7 @@ export const FieldsListItemContainer = ({
toggleExpand={toggleExpand}
state={state}
isAddingFields={isAddingFields}
pendingFieldsRef={pendingFieldsRef}
/>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import { EuiButtonEmpty, EuiSpacer } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React, { useCallback, useMemo } from 'react';
import React, { useCallback, useMemo, useRef } from 'react';

import { useDispatch, useMappingsState } from '../../mappings_state_context';
import { CreateField, FieldsList, SemanticTextInfo } from './fields';
Expand All @@ -16,19 +16,21 @@ interface Props {
onCancelAddingNewFields?: () => void;
isAddingFields?: boolean;
semanticTextInfo?: SemanticTextInfo;
pendingFieldsRef?: React.RefObject<HTMLDivElement>;
}

export const DocumentFieldsTreeEditor = ({
onCancelAddingNewFields,
isAddingFields,
semanticTextInfo,
pendingFieldsRef,
}: Props) => {
const dispatch = useDispatch();
const {
fields: { byId, rootLevelFields },
documentFields: { status, fieldToAddFieldTo },
} = useMappingsState();

const createFieldFormRef = useRef<HTMLDivElement>(null);
const getField = useCallback((fieldId: string) => byId[fieldId], [byId]);
const fields = useMemo(() => rootLevelFields.map(getField), [rootLevelFields, getField]);

Expand All @@ -52,6 +54,7 @@ export const DocumentFieldsTreeEditor = ({
onCancelAddingNewFields={onCancelAddingNewFields}
isAddingFields={isAddingFields}
semanticTextInfo={semanticTextInfo}
createFieldFormRef={createFieldFormRef}
/>
);
};
Expand All @@ -77,7 +80,12 @@ export const DocumentFieldsTreeEditor = ({

return (
<>
<FieldsList fields={fields} state={useMappingsState()} isAddingFields={isAddingFields} />
<FieldsList
fields={fields}
state={useMappingsState()}
isAddingFields={isAddingFields}
pendingFieldsRef={pendingFieldsRef}
/>
{renderCreateField()}
{renderAddFieldButton()}
</>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import {
import { css } from '@emotion/react';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n-react';
import React, { FunctionComponent, useCallback, useEffect, useMemo, useState } from 'react';
import React, { FunctionComponent, useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { ILicense } from '@kbn/licensing-plugin/public';
import { useUnsavedChangesPrompt } from '@kbn/unsaved-changes-prompt';
import {
Expand Down Expand Up @@ -83,6 +83,7 @@ export const DetailsPageMappingsContent: FunctionComponent<{
overlays,
history,
} = useAppContext();
const pendingFieldsRef = useRef<HTMLDivElement>(null);

const [isPlatinumLicense, setIsPlatinumLicense] = useState<boolean>(false);
useEffect(() => {
Expand Down Expand Up @@ -543,7 +544,7 @@ export const DetailsPageMappingsContent: FunctionComponent<{
</EuiFlexItem>
{errorSavingMappings}
{isAddingFields && (
<EuiFlexItem grow={false}>
<EuiFlexItem grow={false} ref={pendingFieldsRef} tabIndex={0}>
<EuiPanel hasBorder paddingSize="s">
<EuiAccordion
id={pendingFieldListId}
Expand Down Expand Up @@ -581,11 +582,13 @@ export const DetailsPageMappingsContent: FunctionComponent<{
onCancelAddingNewFields={onCancelAddingNewFields}
isAddingFields={isAddingFields}
semanticTextInfo={semanticTextInfo}
pendingFieldsRef={pendingFieldsRef}
/>
) : (
<DocumentFields
isAddingFields={isAddingFields}
semanticTextInfo={semanticTextInfo}
pendingFieldsRef={pendingFieldsRef}
/>
)}
</EuiPanel>
Expand Down

0 comments on commit 049400b

Please sign in to comment.