UNPKG

@coveord/plasma-mantine

Version:

A Plasma flavoured Mantine theme

147 lines (146 loc) 5.67 kB
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