@coveord/plasma-mantine
Version:
A Plasma flavoured Mantine theme
147 lines (146 loc) • 5.67 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import { AddSize16Px } from '@coveord/plasma-react-icons';
import { DndContext, KeyboardSensor, PointerSensor, useSensor, useSensors } from '@dnd-kit/core';
import { restrictToParentElement, restrictToVerticalAxis } from '@dnd-kit/modifiers';
import { SortableContext, sortableKeyboardCoordinates, verticalListSortingStrategy } from '@dnd-kit/sortable';
import { Box, Group, Input, Stack, Tooltip, useProps, useStyles } from '@mantine/core';
import { useDidUpdate } from '@mantine/hooks';
import { identity } from '../../utils';
import { Button } from '../button';
import classes from './Collection.module.css';
import { CollectionProvider } from './CollectionContext';
import { CollectionItem } from './CollectionItem';
const defaultProps = {
draggable: false,
addLabel: 'Add item',
addDisabledTooltip: 'There is already an empty item',
disabled: false,
readOnly: false,
gap: 'xs',
required: false,
getItemId: ({ id })=>id
};
export const Collection = (props)=>{
const { value, onChange, onRemoveItem, onReorderItem, onInsertItem, disabled, readOnly, draggable, children, gap, required, newItem, addLabel, addDisabledTooltip, allowAdd, label, labelProps, withAsterisk, description, descriptionProps, error, errorProps, getItemId, ref, // Style props
style, className, classNames, styles, unstyled, ...others } = useProps('Collection', defaultProps, props);
const getStyles = useStyles({
name: 'Collection',
classes,
props,
className,
style,
classNames,
styles,
unstyled
});
const sensors = useSensors(useSensor(PointerSensor), useSensor(KeyboardSensor, {
coordinateGetter: sortableKeyboardCoordinates
}));
const canEdit = !disabled && !readOnly;
const hasOnlyOneItem = value.length === 1;
/**
* Enforcing onChange when the value is modified will make sure the errors are carried through.
*/ useDidUpdate(()=>{
onChange?.(value);
}, [
JSON.stringify(value)
]);
const isRequired = typeof withAsterisk === 'boolean' ? withAsterisk : required;
const _label = label ? /*#__PURE__*/ _jsx(Input.Label, {
required: isRequired,
...labelProps,
children: label
}) : null;
const _description = description ? /*#__PURE__*/ _jsx(Input.Description, {
...descriptionProps,
children: description
}) : null;
const _error = error ? /*#__PURE__*/ _jsx(Input.Error, {
...errorProps,
children: error
}) : null;
const _header = _label || _description ? /*#__PURE__*/ _jsxs(_Fragment, {
children: [
_label,
_description
]
}) : null;
const standardizedItems = value.map((item, index)=>({
id: getItemId?.(item) ?? String(index),
data: item
}));
const items = standardizedItems.map((item, index)=>/*#__PURE__*/ _jsx(CollectionItem, {
id: item.id,
disabled: !canEdit,
draggable: draggable,
onRemove: ()=>onRemoveItem?.(index),
removable: !(required && hasOnlyOneItem),
children: children(item.data, index)
}, item.id));
const addAllowed = allowAdd?.(value) ?? true;
const _addButton = canEdit ? /*#__PURE__*/ _jsx(Group, {
children: /*#__PURE__*/ _jsx(Tooltip, {
label: addDisabledTooltip,
disabled: addAllowed,
children: /*#__PURE__*/ _jsx(Box, {
children: /*#__PURE__*/ _jsx(Button, {
variant: "subtle",
leftSection: /*#__PURE__*/ _jsx(AddSize16Px, {
height: 16
}),
onClick: ()=>onInsertItem(newItem, value?.length ?? 0),
disabled: !addAllowed,
children: addLabel
})
})
})
}) : null;
const getIndex = (id)=>standardizedItems.findIndex((item)=>item.id === id);
const handleDragEnd = ({ over, active })=>{
if (over) {
const activeIndex = getIndex(String(active.id));
const overIndex = getIndex(String(over.id));
if (activeIndex !== overIndex) {
onReorderItem?.({
from: activeIndex,
to: overIndex
});
}
}
};
return /*#__PURE__*/ _jsx(CollectionProvider, {
value: {
getStyles
},
children: /*#__PURE__*/ _jsx(DndContext, {
onDragEnd: handleDragEnd,
sensors: sensors,
modifiers: [
restrictToVerticalAxis,
restrictToParentElement
],
children: /*#__PURE__*/ _jsx(SortableContext, {
items: standardizedItems,
strategy: verticalListSortingStrategy,
children: /*#__PURE__*/ _jsxs(Box, {
ref: ref,
...others,
...getStyles('root'),
children: [
_header,
/*#__PURE__*/ _jsxs(Stack, {
gap: gap,
children: [
items,
_addButton,
_error
]
})
]
})
})
})
});
};
Collection.extend = identity;
//# sourceMappingURL=Collection.js.map