[Curation] Add support for a custom drag handle to the Result component (#94652)
* Update Result component to render a custom drag handle * Update Result library with a draggable example - note: this doesn't actually handle reorder logic, it's purely a UI/UX example * Update CurationResult to pass dragHandleProps through to Result
This commit is contained in:
parent
c937f2648e
commit
badf38b0cd
|
@ -8,6 +8,7 @@
|
|||
import { setMockValues } from '../../../../../__mocks__';
|
||||
|
||||
import React from 'react';
|
||||
import { DraggableProvidedDragHandleProps } from 'react-beautiful-dnd';
|
||||
|
||||
import { shallow, ShallowWrapper } from 'enzyme';
|
||||
|
||||
|
@ -29,12 +30,15 @@ describe('CurationResult', () => {
|
|||
{ title: 'add', iconType: 'plus', onClick: () => {} },
|
||||
{ title: 'remove', iconType: 'minus', onClick: () => {} },
|
||||
];
|
||||
const mockDragging = {} as DraggableProvidedDragHandleProps; // Passed from EuiDraggable
|
||||
|
||||
let wrapper: ShallowWrapper;
|
||||
|
||||
beforeAll(() => {
|
||||
setMockValues(values);
|
||||
wrapper = shallow(<CurationResult result={mockResult} actions={mockActions} />);
|
||||
wrapper = shallow(
|
||||
<CurationResult result={mockResult} actions={mockActions} dragHandleProps={mockDragging} />
|
||||
);
|
||||
});
|
||||
|
||||
it('passes EngineLogic state', () => {
|
||||
|
@ -42,8 +46,9 @@ describe('CurationResult', () => {
|
|||
expect(wrapper.find(Result).prop('schemaForTypeHighlights')).toEqual('some mock schema');
|
||||
});
|
||||
|
||||
it('passes result and actions props', () => {
|
||||
it('passes result, actions, and dragHandleProps props', () => {
|
||||
expect(wrapper.find(Result).prop('result')).toEqual(mockResult);
|
||||
expect(wrapper.find(Result).prop('actions')).toEqual(mockActions);
|
||||
expect(wrapper.find(Result).prop('dragHandleProps')).toEqual(mockDragging);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { DraggableProvidedDragHandleProps } from 'react-beautiful-dnd';
|
||||
|
||||
import { useValues } from 'kea';
|
||||
|
||||
|
@ -18,9 +19,10 @@ import { Result as ResultType, ResultAction } from '../../../result/types';
|
|||
interface Props {
|
||||
result: ResultType;
|
||||
actions: ResultAction[];
|
||||
dragHandleProps?: DraggableProvidedDragHandleProps;
|
||||
}
|
||||
|
||||
export const CurationResult: React.FC<Props> = ({ result, actions }) => {
|
||||
export const CurationResult: React.FC<Props> = ({ result, actions, dragHandleProps }) => {
|
||||
const {
|
||||
isMetaEngine,
|
||||
engine: { schema },
|
||||
|
@ -33,6 +35,7 @@ export const CurationResult: React.FC<Props> = ({ result, actions }) => {
|
|||
actions={actions}
|
||||
isMetaEngine={isMetaEngine}
|
||||
schemaForTypeHighlights={schema}
|
||||
dragHandleProps={dragHandleProps}
|
||||
/>
|
||||
<EuiSpacer size="m" />
|
||||
</>
|
||||
|
|
|
@ -14,6 +14,9 @@ import {
|
|||
EuiTitle,
|
||||
EuiPageContentBody,
|
||||
EuiPageContent,
|
||||
EuiDragDropContext,
|
||||
EuiDroppable,
|
||||
EuiDraggable,
|
||||
} from '@elastic/eui';
|
||||
|
||||
import { SetAppSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome';
|
||||
|
@ -228,6 +231,28 @@ export const Library: React.FC = () => {
|
|||
<Result {...props} actions={actions} shouldLinkToDetailPage />
|
||||
<EuiSpacer />
|
||||
|
||||
<EuiSpacer />
|
||||
<EuiTitle size="s">
|
||||
<h3>With a drag handle</h3>
|
||||
</EuiTitle>
|
||||
<EuiSpacer />
|
||||
<EuiDragDropContext onDragEnd={() => {}}>
|
||||
<EuiDroppable spacing="m" droppableId="DraggableResultsTest">
|
||||
{[1, 2, 3].map((_, i) => (
|
||||
<EuiDraggable
|
||||
spacing="m"
|
||||
key={`draggable-${i}`}
|
||||
index={i}
|
||||
draggableId={`draggable-${i}`}
|
||||
customDragHandle
|
||||
>
|
||||
{(provided) => <Result {...props} dragHandleProps={provided.dragHandleProps} />}
|
||||
</EuiDraggable>
|
||||
))}
|
||||
</EuiDroppable>
|
||||
</EuiDragDropContext>
|
||||
<EuiSpacer />
|
||||
|
||||
<EuiSpacer />
|
||||
<EuiTitle size="s">
|
||||
<h3>With field value type highlights</h3>
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
.appSearchResult {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr auto;
|
||||
grid-template-rows: 1fr auto;
|
||||
grid-template-columns: auto 1fr auto;
|
||||
grid-template-rows: auto 1fr auto;
|
||||
grid-template-areas:
|
||||
'content actions'
|
||||
'toggle actions';
|
||||
'drag content actions'
|
||||
'drag toggle actions';
|
||||
overflow: hidden; // Prevents child background-colors from clipping outside of panel border-radius
|
||||
|
||||
&__content {
|
||||
|
@ -52,6 +52,15 @@
|
|||
background-color: $euiPageBackgroundColor;
|
||||
}
|
||||
}
|
||||
|
||||
&__dragHandle {
|
||||
grid-area: drag;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: $euiSizeXL;
|
||||
border-right: $euiBorderThin;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { DraggableProvidedDragHandleProps } from 'react-beautiful-dnd';
|
||||
|
||||
import { shallow, ShallowWrapper } from 'enzyme';
|
||||
|
||||
|
@ -129,6 +130,20 @@ describe('Result', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('dragging', () => {
|
||||
// In the real world, the drag library sets data attributes, role, tabIndex, etc.
|
||||
const mockDragHandleProps = ({
|
||||
someMockProp: true,
|
||||
} as unknown) as DraggableProvidedDragHandleProps;
|
||||
|
||||
it('will render a drag handle with the passed props', () => {
|
||||
const wrapper = shallow(<Result {...props} dragHandleProps={mockDragHandleProps} />);
|
||||
|
||||
expect(wrapper.find('.appSearchResult__dragHandle')).toHaveLength(1);
|
||||
expect(wrapper.find('.appSearchResult__dragHandle').prop('someMockProp')).toEqual(true);
|
||||
});
|
||||
});
|
||||
|
||||
it('will render field details with type highlights if schemaForTypeHighlights has been provided', () => {
|
||||
const wrapper = shallow(
|
||||
<Result {...props} shouldLinkToDetailPage schemaForTypeHighlights={schema} />
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
|
||||
import React, { useState, useMemo } from 'react';
|
||||
import { DraggableProvidedDragHandleProps } from 'react-beautiful-dnd';
|
||||
|
||||
import classNames from 'classnames';
|
||||
|
||||
|
@ -31,6 +32,7 @@ interface Props {
|
|||
shouldLinkToDetailPage?: boolean;
|
||||
schemaForTypeHighlights?: Schema;
|
||||
actions?: ResultAction[];
|
||||
dragHandleProps?: DraggableProvidedDragHandleProps;
|
||||
}
|
||||
|
||||
const RESULT_CUTOFF = 5;
|
||||
|
@ -42,6 +44,7 @@ export const Result: React.FC<Props> = ({
|
|||
shouldLinkToDetailPage = false,
|
||||
schemaForTypeHighlights,
|
||||
actions = [],
|
||||
dragHandleProps,
|
||||
}) => {
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
|
||||
|
@ -87,6 +90,11 @@ export const Result: React.FC<Props> = ({
|
|||
values: { id: result[ID].raw },
|
||||
})}
|
||||
>
|
||||
{dragHandleProps && (
|
||||
<div {...dragHandleProps} className="appSearchResult__dragHandle">
|
||||
<EuiIcon type="grab" />
|
||||
</div>
|
||||
)}
|
||||
{conditionallyLinkedArticle(
|
||||
<>
|
||||
<ResultHeader
|
||||
|
|
Loading…
Reference in a new issue