-
Notifications
You must be signed in to change notification settings - Fork 31
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
6392c3f
commit 24c969e
Showing
16 changed files
with
598 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import classNames from 'classnames'; | ||
import React, { useEffect, useState } from 'react'; | ||
import { DndProvider } from 'react-dnd'; | ||
import { HTML5Backend } from 'react-dnd-html5-backend'; | ||
import update from 'immutability-helper'; | ||
import usePrefixCls from '../utils/hooks/use-prefix-cls'; | ||
import { PREFIX } from './constants'; | ||
import { DragListProps, OptionProps } from './interfance'; | ||
import DragItem from './DragItem'; | ||
|
||
|
||
|
||
const Drag:React.FC<DragListProps> = (props) => { | ||
const { onChange,className,style,options:propsOPtions,disabled,...rest } = props; | ||
|
||
const [options, setOptions] = useState(propsOPtions); | ||
useEffect(() => { | ||
setOptions(propsOPtions); | ||
}, [propsOPtions]); | ||
const prefixCls = `${usePrefixCls(PREFIX)}`; | ||
|
||
const onMoved = (dragIndex: number, hoverIndex: number) => { | ||
const dragCard = options[dragIndex]; | ||
const updateOptions = update(options, { | ||
$splice: [ | ||
[dragIndex, 1], | ||
[hoverIndex, 0, dragCard], | ||
], | ||
}); | ||
setOptions(updateOptions); | ||
onChange?.(updateOptions) | ||
}; | ||
|
||
return ( | ||
<DndProvider backend={HTML5Backend}> | ||
<div className={classNames(prefixCls,className)} | ||
style={style}> | ||
{options?.map((option:OptionProps,index:number) => <DragItem {...option} {...rest} index={index} onMoved={onMoved} disabled={option?.disabled ?? disabled}/>)} | ||
</div> | ||
</DndProvider> | ||
) | ||
} | ||
|
||
export default Drag |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import React, { useRef } from 'react'; | ||
import { DragSourceMonitor, DropTargetMonitor, useDrag, useDrop, XYCoord } from 'react-dnd'; | ||
import { DragItemProps } from './interfance'; | ||
import Item from './Item'; | ||
|
||
|
||
|
||
const DragItem:React.FC<DragItemProps> = (props) => { | ||
const { label, value, onMoved,index,...rest} = props; | ||
const ref = useRef<HTMLDivElement>(null) | ||
const [{ handlerId }, drop] = useDrop({ | ||
accept: 'drag-item', | ||
collect(monitor) { | ||
return { | ||
handlerId: monitor.getHandlerId(), | ||
} | ||
}, | ||
hover(item: {index:number,type:string,id:string}, monitor: DropTargetMonitor) { | ||
if (!ref.current) { | ||
return | ||
} | ||
const dragIndex = item.index | ||
const hoverIndex = index | ||
|
||
if (dragIndex === hoverIndex) { | ||
return | ||
} | ||
const hoverBoundingRect = ref.current?.getBoundingClientRect() | ||
const hoverMiddleY = | ||
(hoverBoundingRect.bottom - hoverBoundingRect.top) / 2 | ||
const clientOffset = monitor.getClientOffset() | ||
const hoverClientY = (clientOffset as XYCoord).y - hoverBoundingRect.top | ||
if (dragIndex < hoverIndex && hoverClientY < hoverMiddleY) { | ||
return | ||
} | ||
|
||
// Dragging upwards | ||
if (dragIndex > hoverIndex && hoverClientY > hoverMiddleY) { | ||
return | ||
} | ||
onMoved(dragIndex, hoverIndex) | ||
// eslint-disable-next-line no-param-reassign | ||
item.index = hoverIndex | ||
}, | ||
}) | ||
const [, drag] = useDrag({ | ||
item: { type:'drag-item',id:value,index }, | ||
collect: (monitor: DragSourceMonitor) => ({ | ||
isDragging: monitor.isDragging(), | ||
}), | ||
}) | ||
|
||
drag(drop(ref)); | ||
return <div ref={ref} data-handler-id={handlerId} key={value}> | ||
<Item label={label} value={value} {...rest} isDrag /> | ||
</div> | ||
} | ||
|
||
|
||
export default DragItem |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import React from 'react'; | ||
import usePrefixCls from '../utils/hooks/use-prefix-cls'; | ||
import { PREFIX } from './constants'; | ||
|
||
interface GroupPorps { | ||
title?:string | ||
} | ||
|
||
const Group:React.FC<GroupPorps> =(props) =>{ | ||
const { title,children } = props; | ||
const prefixCls = `${usePrefixCls(PREFIX)}--group`; | ||
return ( | ||
<div className={prefixCls}> | ||
<div className={`${prefixCls}--title`}> | ||
{title} | ||
</div> | ||
{children} | ||
</div> | ||
) | ||
} | ||
|
||
export default Group; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import classNames from 'classnames'; | ||
import React from 'react'; | ||
import { isArray } from 'lodash'; | ||
import { MoveOutlined } from '@gio-design/icons'; | ||
import usePrefixCls from '../utils/hooks/use-prefix-cls'; | ||
import { PREFIX } from './constants'; | ||
import { ItemProps } from './interfance'; | ||
import Checkbox from '../checkbox/Checkbox'; | ||
import BaseItem from './inner/baseItem'; | ||
|
||
const Item:React.FC<ItemProps> = (props)=>{ | ||
const { label,className,style,prefix,suffix,children,disabled,selectedValue,disabledTooltip,isMultiple,isDrag,value,onMouseEnter,onMouseLeave,onClick} = props; | ||
|
||
const prefixCls = `${usePrefixCls(PREFIX)}__item`; | ||
|
||
const handleClick = () => { | ||
if (!disabled && onClick) { | ||
onClick({label:children ?? label,value}); | ||
} | ||
} | ||
// multiple check | ||
const actived = isMultiple && isArray(selectedValue) | ||
? (selectedValue as (string | number)[])?.indexOf(value) !== -1 | ||
: selectedValue === value; | ||
|
||
return ( | ||
<li style={style} className={classNames(className,prefixCls,{ | ||
[`${prefixCls}--disabled`]: disabled, | ||
[`${prefixCls}--actived`]: actived, | ||
}, | ||
|
||
className)} | ||
key={value} | ||
aria-hidden="true" | ||
onClick={handleClick} | ||
onMouseEnter={onMouseEnter} | ||
onMouseLeave={onMouseLeave}> | ||
{ | ||
isMultiple && <Checkbox | ||
className={`${prefixCls}--checkbox`} | ||
checked={actived} | ||
disabled={disabled} | ||
/> | ||
} | ||
{ | ||
isDrag && <MoveOutlined className={`${prefixCls}--drag`} /> | ||
} | ||
<BaseItem label={label} value={value} disabled={disabled} disabledTooltip={disabledTooltip} prefix={prefix} suffix={suffix} >{children}</BaseItem> | ||
</li> | ||
) | ||
} | ||
|
||
export default Item; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import classNames from 'classnames'; | ||
import React from 'react'; | ||
import { difference, isArray, isNil } from 'lodash'; | ||
import { OptionProps, ItemProps, BaseListProps } from './interfance'; | ||
import usePrefixCls from '../utils/hooks/use-prefix-cls'; | ||
import { PREFIX } from './constants'; | ||
import Item from './Item'; | ||
|
||
const List: React.FC<BaseListProps> = (props)=> { | ||
const { className, style, options, children,disabled = false,value:controlledValue,isMultiple,prefix,suffix,onChange } = props; | ||
const prefixCls = `${usePrefixCls(PREFIX)}`; | ||
const handleClick = (option:OptionProps) => { | ||
if(isMultiple){ | ||
let multipleValues = []; | ||
if((controlledValue as (string | number)[])?.indexOf(option.value) !== -1 && !isNil(controlledValue)){ | ||
multipleValues = difference((controlledValue as (string | number)[]),[option.value]); | ||
} else { | ||
multipleValues = isArray(controlledValue) ? [...controlledValue,option.value] : [option.value]; | ||
} | ||
onChange?.(multipleValues) | ||
} else if(controlledValue !== option.value){ | ||
onChange?.(option.value) | ||
} | ||
|
||
} | ||
const renderChildrens = ()=> { | ||
if(isArray(options)){ | ||
return options?.map((option:OptionProps) => <Item {...option} prefix={prefix} suffix={suffix} disabled={option?.disabled ?? disabled} isMultiple={isMultiple} selectedValue={controlledValue} onClick={handleClick} />) | ||
} | ||
return React.Children.map(children, (node:React.ReactElement<ItemProps>,index) => { | ||
const { props:{className:itemClassName,disabled:itemDisabled,prefix:itemPrefix,suffix:itemSuffix,onClick,...rest} } = node; | ||
return React.cloneElement(node,{ | ||
className:classNames(itemClassName, { | ||
[`${prefixCls}__item--interval`]: index !== 0 | ||
}), | ||
disabled:itemDisabled ?? disabled, | ||
prefix:itemPrefix ?? prefix, | ||
suffix:itemSuffix ?? suffix, | ||
isMultiple, | ||
selectedValue:controlledValue, | ||
onClick:(option:OptionProps)=>{ | ||
handleClick(option); | ||
onClick?.(option); | ||
}, | ||
...rest | ||
}) | ||
}) | ||
} | ||
|
||
return ( | ||
<div className={ | ||
classNames(prefixCls,className) | ||
} | ||
style={style}> | ||
{renderChildrens()} | ||
</div> | ||
) | ||
} | ||
|
||
export default List |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
export const DEFAULT_SHOW_ITEMS_COUNT = 10; | ||
export const PREFIX = 'list-new'; | ||
|
||
export default { | ||
DEFAULT_SHOW_ITEMS_COUNT, | ||
PREFIX, | ||
}; |
Oops, something went wrong.