Skip to content

Commit

Permalink
feat: add dragable to @uform/next table field (#561)
Browse files Browse the repository at this point in the history
  • Loading branch information
soulwu authored and janryWang committed Dec 30, 2019
1 parent d66cee7 commit 4c94730
Show file tree
Hide file tree
Showing 6 changed files with 328 additions and 10 deletions.
53 changes: 53 additions & 0 deletions docs/Examples/next/List.md
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,59 @@ const App = () => (
ReactDOM.render(<App />, document.getElementById('root'))
```

# Dragable Table Style

> 数组场景,列表型数组,使用拖拽排序,对于需要做数据对比分析的场景,比较适合,但是它对数据结构
> 的要求,必须是 ObjectList
#### Demo 示例

```jsx
import React from 'react'
import ReactDOM from 'react-dom'
import SchemaForm, { SchemaMarkupField as Field } from '@uform/next'
import '@alifd/next/dist/next.css'
import Printer from '@uform/printer'

const App = () => (
<Printer>
<SchemaForm
initialValues={{
array: [
{ aa: 'a1', bb: 'b1', cc: 'c1' },
{ aa: 'a2', bb: 'b2', cc: 'c2' },
{ aa: 'a3', bb: 'b3', cc: 'c3' }
]
}}
>
<Field
title="数组"
name="array"
maxItems={5}
type="array"
x-component="table"
x-component-props={{
dragable: true,
primaryKey: 'aa',
renderMoveUp: () => {},
renderMoveDown: () => {},
operations: {
width: 100
}
}}
>
<Field type="object">
<Field name="aa" type="string" title="字段1" editable={true} />
<Field name="bb" type="string" title="字段2" />
<Field name="cc" type="string" title="字段3" />
</Field>
</Field>
</SchemaForm>
</Printer>
)
ReactDOM.render(<App />, document.getElementById('root'))
```

# Card Style

> 数组场景,卡片数组,信息层级结构更加清晰的要求,必须是 ObjectList
Expand Down
2 changes: 2 additions & 0 deletions packages/next/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
"@uform/react-shared-components": "^1.0.0-rc.0",
"@uform/shared": "^1.0.0-rc.0",
"classnames": "^2.2.6",
"react-dnd": "^10.0.2",
"react-dnd-html5-backend": "^10.0.2",
"react-eva": "^1.0.0-alpha.0",
"react-stikky": "^0.1.15",
"rxjs": "^6.5.1",
Expand Down
219 changes: 209 additions & 10 deletions packages/next/src/fields/table.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React from 'react'
import { Icon } from '@alifd/next'
import React, { forwardRef, useRef } from 'react'
import {
registerFormField,
ISchemaFieldComponentProps,
Expand All @@ -9,10 +8,24 @@ import {
import { toArr, isFn, isArr, FormPath } from '@uform/shared'
import { ArrayList } from '@uform/react-shared-components'
import { CircleButton, TextButton } from '../components/Button'
import { Table, Form } from '@alifd/next'
import { Table, Form, Icon } from '@alifd/next'
import styled from 'styled-components'
import { CompatNextFormItemProps } from '../compat/FormItem'
import cls from 'classnames'
import { DndProvider, useDrag, useDrop } from 'react-dnd'
import HTML5Backend from 'react-dnd-html5-backend'
import {
IDragableRowWrapperProps,
IDragableRowProps,
IDragableTableProps,
IDragObject,
ICollectedProps,
IDragHandlerCellProps
} from '../types'

const ArrayComponents = {
Wrapper: Table,
Item: Table.Column,
CircleButton,
TextButton,
AdditionIcon: () => <Icon type="add" className="next-icon-first" />,
Expand All @@ -27,6 +40,181 @@ const ArrayComponents = {
)
}

const DragHandlerCell = styled(
({ children, drag, ...props }: IDragHandlerCellProps) => {
const ref = useRef(null)
drag(ref)

return (
<div {...props}>
<span ref={ref} className="drag-handler" />
<span className="drag-cell-content">{children}</span>
</div>
)
}
)`
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: flex-start;
align-content: flex-start;
align-items: center;
margin-left: -3px;
.drag-handler {
flex-shrink: 0;
width: 7px;
display: inline-block;
height: 14px;
border: 2px dotted #c5c5c5;
border-top: 0;
border-bottom: 0;
cursor: move;
vertical-align: -3px;
margin-right: 15px;
}
.drag-cell-content {
flex: 1;
}
`

const RowWrapper = styled(
({
children,
rowIndex,
moveRow,
preview,
...props
}: IDragableRowWrapperProps) => {
const ref = useRef(null)
const [{ isOver, dragingIndex }, drop] = useDrop<
IDragObject,
any,
ICollectedProps
>({
accept: 'row',
drop(item, monitor) {
const dragIndex = item.index
const dropIndex = rowIndex
if (dragIndex === dropIndex) {
return
}
moveRow(dragIndex, dropIndex)
item.index = dropIndex
},
collect(monitor) {
const dragingItem = monitor.getItem()

return {
isOver: monitor.isOver(),
dragingIndex: dragingItem ? dragingItem.index : -1
}
}
})

drop(ref)
preview(ref)

const child = React.Children.only(children)

return React.cloneElement(child, {
...child.props,
ref,
className: cls(child.props.className, props.className, {
'drop-over-downward': isOver && rowIndex > dragingIndex,
'drop-over-upward': isOver && rowIndex < dragingIndex
})
})
}
)`
&.drop-over-downward {
td {
border-bottom: 2px dashed #0070cc !important;
}
}
&.drop-over-upward {
td {
border-top: 2px dashed #0070cc !important;
}
}
`

const DragableRow = forwardRef(
({ moveRow, columns, ...props }: IDragableRowProps, ref) => {
const [, drag, preview] = useDrag<IDragObject>({
item: {
type: 'row',
id: props.record[props.primaryKey],
index: props.rowIndex
}
})

const [firstCol, ...otherCols] = columns

const createWrapper = row => {
return (
<RowWrapper
rowIndex={props.rowIndex}
moveRow={moveRow}
preview={preview}
>
{row}
</RowWrapper>
)
}

return (
<Table.SelectionRow
{...props}
ref={ref}
columns={[
{
...firstCol,
cell: (value, index, record, context) => {
let content = value
if (firstCol.cell) {
content = firstCol.cell
if (React.isValidElement(content)) {
content = React.cloneElement(content, {
value,
index,
record,
context
})
} else if (isFn(content)) {
content = content(value, index, record, context)
}
}
return <DragHandlerCell drag={drag}>{content}</DragHandlerCell>
}
},
...otherCols
]}
wrapper={createWrapper}
/>
)
}
)

const DragableTable = styled(({ onMoveRow, ...props }: IDragableTableProps) => {
return (
<DndProvider backend={HTML5Backend}>
<Table
{...props}
rowProps={() => ({ moveRow: onMoveRow })}
components={{
Row: DragableRow
}}
/>
</DndProvider>
)
})`
&.next-table .next-table-header th:nth-child(1) .next-table-cell-wrapper {
padding-left: 26px;
}
`

const FormTableField = styled(
(props: ISchemaFieldComponentProps & { className: string }) => {
const { value, schema, className, editable, path, mutators } = props
Expand All @@ -39,6 +227,7 @@ const FormTableField = styled(
renderExtraOperations,
operationsWidth,
operations,
dragable,
...componentProps
} = schema.getExtendsComponentProps() || {}
const onAdd = () => {
Expand All @@ -47,14 +236,17 @@ const FormTableField = styled(
: schema.items
mutators.push(items.getEmptyValue())
}
const onMoveRow = (dragIndex, dropIndex) => {
mutators.move(dragIndex, dropIndex)
}
const renderColumns = (items: Schema) => {
return items.mapProperties((props, key) => {
const itemProps = {
...props.getExtendsItemProps(),
...props.getExtendsProps()
}
return (
<Table.Column
<ArrayList.Item
width={200}
{...itemProps}
title={props.title}
Expand All @@ -74,7 +266,6 @@ const FormTableField = styled(
/>
)
})
return []
}
return (
<div className={className}>
Expand All @@ -83,7 +274,10 @@ const FormTableField = styled(
minItems={schema.minItems}
maxItems={schema.maxItems}
editable={editable}
components={ArrayComponents}
components={{
...ArrayComponents,
Wrapper: dragable ? DragableTable : ArrayComponents.Wrapper
}}
renders={{
renderAddition,
renderRemove,
Expand All @@ -92,17 +286,22 @@ const FormTableField = styled(
renderEmpty
}}
>
<Table {...componentProps} size="small" dataSource={toArr(value)}>
<ArrayList.Wrapper
size="small"
{...componentProps}
{...(dragable ? { onMoveRow } : {})}
dataSource={toArr(value)}
>
{isArr(schema.items)
? schema.items.reduce((buf, items) => {
return buf.concat(renderColumns(items))
}, [])
: renderColumns(schema.items)}
<Table.Column
<ArrayList.Item
width={200}
lock="right"
{...operations}
key="operations"
lock="right"
dataIndex="operations"
cell={(value: any, index: number) => {
return (
Expand All @@ -128,7 +327,7 @@ const FormTableField = styled(
)
}}
/>
</Table>
</ArrayList.Wrapper>
<ArrayList.Addition>
{({ children }) => {
return (
Expand Down
Loading

0 comments on commit 4c94730

Please sign in to comment.