X-Git-Url: https://git.arvados.org/arvados-workbench2.git/blobdiff_plain/8762c56e9600fdc415d74f3d5db0e1c0ac700d9a..a6d1469a04f5a6a658cdeac5fc8a11f01d3a1c02:/src/components/chips/chips.tsx

diff --git a/src/components/chips/chips.tsx b/src/components/chips/chips.tsx
index c63b584a..75ae00f4 100644
--- a/src/components/chips/chips.tsx
+++ b/src/components/chips/chips.tsx
@@ -3,94 +3,116 @@
 // SPDX-License-Identifier: AGPL-3.0
 
 import * as React from 'react';
-import { Chip, Grid } from '@material-ui/core';
+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<Value> {
     values: Value[];
     getLabel?: (value: Value) => string;
     filler?: React.ReactNode;
+    deletable?: boolean;
+    orderable?: boolean;
     onChange: (value: Value[]) => void;
+    clickable?: boolean;
 }
-export class Chips<Value> extends React.Component<ChipsProps<Value>> {
-    render() {
-        const { values, filler } = this.props;
-        return <Grid container spacing={8}>
-            {values.map(this.renderChip)}
-            {filler && <Grid item xs>{filler}</Grid>}
-        </Grid>;
-    }
 
-    renderChip = (value: Value, index: number) =>
-        <Grid item key={index}>
-            <this.chip {...{ value }} />
-        </Grid>
+type CssRules = 'root';
 
-    type = 'chip';
+const styles: StyleRulesCallback<CssRules> = ({ spacing }) => ({
+    root: {
+        margin: `0px -${spacing.unit / 2}px`,
+    },
+});
+export const Chips = withStyles(styles)(
+    class Chips<Value> extends React.Component<ChipsProps<Value> & WithStyles<CssRules>> {
+        render() {
+            const { values, filler } = this.props;
+            return <Grid container spacing={8} className={this.props.classes.root}>
+                {values.map(this.renderChip)}
+                {filler && <Grid item xs>{filler}</Grid>}
+            </Grid>;
+        }
+
+        renderChip = (value: Value, index: number) =>
+            <Grid item key={index}>
+                <this.chip {...{ value }} />
+            </Grid>
+
+        type = 'chip';
 
-    dragSpec: DragSourceSpec<DraggableChipProps<Value>, { 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);
+        dragSpec: DragSourceSpec<DraggableChipProps<Value>, { 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);
                 }
-                this.props.onChange(newValues);
             }
-        }
-    };
+        };
 
-    dragCollector: DragSourceCollector<{}> = connect => ({
-        connectDragSource: connect.dragSource(),
-    })
+        dragCollector: DragSourceCollector<{}> = connect => ({
+            connectDragSource: connect.dragSource(),
+        })
 
-    dropSpec: DropTargetSpec<DraggableChipProps<Value>> = {
-        drop: ({ value }) => ({ value }),
-    };
+        dropSpec: DropTargetSpec<DraggableChipProps<Value>> = {
+            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<Value> & CollectedProps) =>
-            compose(
-                connectDragSource,
-                connectDropTarget,
-            )(
-                <span>
-                    <Chip
-                        color={isOver ? 'primary' : 'default'}
-                        onDelete={this.deleteValue(value)}
-                        label={this.props.getLabel ?
-                            this.props.getLabel(value)
-                            : typeof value === 'object'
-                                ? JSON.stringify(value)
-                                : value} />
-                </span>
-            )
-    );
+        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<Value> & CollectedProps) => {
+                const connect = compose(
+                    connectDragSource,
+                    connectDropTarget,
+                );
 
-    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);
-    }
-}
+                const chip =
+                    <span>
+                        <Chip
+                            color={isOver ? 'primary' : 'default'}
+                            onDelete={this.props.deletable
+                                ? this.deleteValue(value)
+                                : undefined}
+                            clickable={this.props.clickable}
+                            label={this.props.getLabel ?
+                                this.props.getLabel(value)
+                                : typeof value === 'object'
+                                    ? JSON.stringify(value)
+                                    : value} />
+                    </span>;
+
+                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;
