@hello-pangea/dnd
Version:
Beautiful and accessible drag and drop for lists with React
101 lines (86 loc) • 2.69 kB
text/typescript
import { invariant } from '../../invariant';
import type { Props } from './droppable-types';
import { warning } from '../../dev-warning';
import checkIsValidInnerRef from '../check-is-valid-inner-ref';
import useDevSetupWarning from '../use-dev-setup-warning';
interface Args {
props: Props;
getDroppableRef: () => HTMLElement | null;
getPlaceholderRef: () => HTMLElement | null;
}
type CheckFn = (args: Args) => void;
function isBoolean(value: unknown): boolean {
return typeof value === 'boolean';
}
function runChecks(args: Args, checks: CheckFn[]) {
checks.forEach((check: CheckFn) => check(args));
}
const shared: CheckFn[] = [
function required({ props }: Args) {
invariant(props.droppableId, 'A Droppable requires a droppableId prop');
invariant(
typeof props.droppableId === 'string',
`A Droppable requires a [string] droppableId. Provided: [${typeof props.droppableId}]`,
);
},
function boolean({ props }: Args) {
invariant(
isBoolean(props.isDropDisabled),
'isDropDisabled must be a boolean',
);
invariant(
isBoolean(props.isCombineEnabled),
'isCombineEnabled must be a boolean',
);
invariant(
isBoolean(props.ignoreContainerClipping),
'ignoreContainerClipping must be a boolean',
);
},
function ref({ getDroppableRef }: Args) {
checkIsValidInnerRef(getDroppableRef());
},
];
const standard: CheckFn[] = [
function placeholder({ props, getPlaceholderRef }: Args) {
if (!props.placeholder) {
return;
}
const ref: HTMLElement | null = getPlaceholderRef();
if (ref) {
return;
}
warning(`
Droppable setup issue [droppableId: "${props.droppableId}"]:
DroppableProvided > placeholder could not be found.
Please be sure to add the {provided.placeholder} React Node as a child of your Droppable.
More information: https://github.com/hello-pangea/dnd/blob/main/docs/api/droppable.md
`);
},
];
const virtual: CheckFn[] = [
function hasClone({ props }: Args) {
invariant(
props.renderClone,
'Must provide a clone render function (renderClone) for virtual lists',
);
},
function hasNoPlaceholder({ getPlaceholderRef }: Args) {
invariant(
!getPlaceholderRef(),
'Expected virtual list to not have a placeholder',
);
},
];
export default function useValidation(args: Args) {
useDevSetupWarning(() => {
// wrapping entire block for better minification
runChecks(args, shared);
if (args.props.mode === 'standard') {
runChecks(args, standard);
}
if (args.props.mode === 'virtual') {
runChecks(args, virtual);
}
});
}