X-Git-Url: https://git.arvados.org/arvados-workbench2.git/blobdiff_plain/4a789cf1c48960362fb179680fa55a353c94e53e..d8f669aadc5f3d7241395abd6aa764406079d7d3:/src/components/chips/chips.tsx diff --git a/src/components/chips/chips.tsx b/src/components/chips/chips.tsx index c0130800..2a6fafc3 100644 --- a/src/components/chips/chips.tsx +++ b/src/components/chips/chips.tsx @@ -2,84 +2,126 @@ // // SPDX-License-Identifier: AGPL-3.0 -import * as React from 'react'; -import { Chip, Grid } from '@material-ui/core'; -import { DragSource, DragSourceSpec, DragSourceCollector, ConnectDragSource, DragDropContextProvider, DropTarget, DropTargetSpec, DropTargetCollector, ConnectDropTarget } from 'react-dnd'; -import HTML5Backend from 'react-dnd-html5-backend'; +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'; -interface ChipsFieldProps { +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; } -export class Chips extends React.Component> { - render() { - const { values } = this.props; - return - + +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.map(this.renderChip)} + {filler && {filler}} + ; + } + + renderChip = (value: Value, index: number) => + + - ; - } - renderChip = (value: Value, index: number) => - - - + type = 'chip'; - 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); + } + } + }; - dragSpec: DragSourceSpec, { value: Value }> = { - beginDrag: ({ value }) => ({ value }), - endDrag: ({ value: dragValue }, monitor) => { - 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); - newValues.splice(dragIndex, 1, dropValue); - newValues.splice(dropIndex, 1, dragValue); - this.props.onChange(newValues); - } - }; + dragCollector: DragSourceCollector<{}> = connect => ({ + connectDragSource: connect.dragSource(), + }) - dragCollector: DragSourceCollector<{}> = connect => ({ - connectDragSource: connect.dragSource(), - }) + dropSpec: DropTargetSpec> = { + drop: ({ value }) => ({ value }), + }; - 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, + ); - 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) => - compose( - connectDragSource, - connectDropTarget, - )( - - - - ) - ); + const 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); - } -} + 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;