kibana/x-pack/plugins/lens/public/drag_drop/providers/reorder_provider.tsx

86 lines
2.1 KiB
TypeScript

/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import React, { useState, useMemo } from 'react';
import classNames from 'classnames';
export interface ReorderState {
/**
* Ids of the elements that are translated up or down
*/
reorderedItems: Array<{ id: string; height?: number }>;
/**
* Direction of the move of dragged element in the reordered list
*/
direction: '-' | '+';
/**
* height of the dragged element
*/
draggingHeight: number;
/**
* indicates that user is in keyboard mode
*/
isReorderOn: boolean;
/**
* reorder group needed for screen reader aria-described-by attribute
*/
groupId: string;
}
type SetReorderStateDispatch = (prevState: ReorderState) => ReorderState;
export interface ReorderContextState {
reorderState: ReorderState;
setReorderState: (dispatch: SetReorderStateDispatch) => void;
}
export const ReorderContext = React.createContext<ReorderContextState>({
reorderState: {
reorderedItems: [],
direction: '-',
draggingHeight: 40,
isReorderOn: false,
groupId: '',
},
setReorderState: () => () => {},
});
export function ReorderProvider({
id,
children,
className,
}: {
id: string;
children: React.ReactNode;
className?: string;
}) {
const [state, setState] = useState<ReorderContextState['reorderState']>({
reorderedItems: [],
direction: '-',
draggingHeight: 40,
isReorderOn: false,
groupId: id,
});
const setReorderState = useMemo(() => (dispatch: SetReorderStateDispatch) => setState(dispatch), [
setState,
]);
return (
<div
data-test-subj="lnsDragDrop-reorderableGroup"
className={classNames(className, {
'lnsDragDrop-isActiveGroup': state.isReorderOn && React.Children.count(children) > 1,
})}
>
<ReorderContext.Provider value={{ reorderState: state, setReorderState }}>
{children}
</ReorderContext.Provider>
</div>
);
}