// Copyright (C) The Arvados Authors. All rights reserved. // // SPDX-License-Identifier: AGPL-3.0 import React from 'react'; import { Chip, Grid, StyleRulesCallback, withStyles } from '@material-ui/core'; import { DragSource, DragSourceSpec, DragSourceCollector, ConnectDragSource, DropTarget, DropTargetSpec, DropTargetCollector, ConnectDropTarget } from 'react-dnd'; import { compose } from 'lodash/fp'; import { WithStyles } from '@material-ui/core/styles'; interface ChipsProps { values: Value[]; getLabel?: (value: Value) => string; filler?: React.ReactNode; deletable?: boolean; orderable?: boolean; onChange: (value: Value[]) => void; clickable?: boolean; } type CssRules = 'root'; const styles: StyleRulesCallback = ({ spacing }) => ({ root: { margin: `0px -${spacing.unit / 2}px`, }, }); export const Chips = withStyles(styles)( class Chips extends React.Component & WithStyles> { render() { const { values, filler } = this.props; return {values && values.map(this.renderChip)} {filler && {filler}} ; } renderChip = (value: Value, index: number) => { const { deletable, getLabel } = this.props; return } type = 'chip'; dragSpec: DragSourceSpec, { value: Value }> = { beginDrag: ({ value }) => ({ value }), endDrag: ({ value: dragValue }, monitor) => { const result = monitor.getDropResult(); if (result) { const { value: dropValue } = monitor.getDropResult(); const dragIndex = this.props.values.indexOf(dragValue); const dropIndex = this.props.values.indexOf(dropValue); const newValues = this.props.values.slice(0); if (dragIndex < dropIndex) { newValues.splice(dragIndex, 1); newValues.splice(dropIndex - 1 || 0, 0, dragValue); } else if (dragIndex > dropIndex) { newValues.splice(dragIndex, 1); newValues.splice(dropIndex, 0, dragValue); } this.props.onChange(newValues); } } }; dragCollector: DragSourceCollector<{}> = connect => ({ connectDragSource: connect.dragSource(), }) dropSpec: DropTargetSpec> = { drop: ({ value }) => ({ value }), }; dropCollector: DropTargetCollector<{}> = (connect, monitor) => ({ connectDropTarget: connect.dropTarget(), isOver: monitor.isOver(), }) chip = compose( DragSource(this.type, this.dragSpec, this.dragCollector), DropTarget(this.type, this.dropSpec, this.dropCollector), )( ({ connectDragSource, connectDropTarget, isOver, value }: DraggableChipProps & CollectedProps) => { const connect = compose( connectDragSource, connectDropTarget, ); const chip = ; return this.props.orderable ? connect(chip) : chip; } ); deleteValue = (value: Value) => () => { const { values } = this.props; const index = values.indexOf(value); const newValues = values.slice(0); newValues.splice(index, 1); this.props.onChange(newValues); } }); interface CollectedProps { connectDragSource: ConnectDragSource; connectDropTarget: ConnectDropTarget; isOver: boolean; } interface DraggableChipProps { value: Value; }