86 lines
2.1 KiB
TypeScript
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>
|
|
);
|
|
}
|