react-dnd#useDrag JavaScript Examples
The following examples show how to use
react-dnd#useDrag.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: index.js From dstack-server with Apache License 2.0 | 6 votes |
DnDItem = memo(({id, onMoveItem, children}) => {
const ref = useRef(null);
const [, connectDrag] = useDrag({
item: {id, type: 'IMG'},
collect: monitor => {
return {isDragging: monitor.isDragging()};
},
});
const [, connectDrop] = useDrop({
accept: 'IMG',
drop: hoveredOverItem => {
if (hoveredOverItem.id !== id) {
onMoveItem(hoveredOverItem.id, id);
}
},
});
connectDrag(ref);
connectDrop(ref);
return React.Children.map(children, child =>
React.cloneElement(child, {forwardedRef: ref})
);
})
Example #2
Source File: drag-sorting.jsx From virtuoso-design-system with MIT License | 6 votes |
DragableUploadListItem = ({ originNode, moveRow, file, fileList }) => {
const ref = React.useRef();
const index = fileList.indexOf(file);
const [{ isOver, dropClassName }, drop] = useDrop({
accept: type,
collect: monitor => {
const { index: dragIndex } = monitor.getItem() || {};
if (dragIndex === index) {
return {};
}
return {
isOver: monitor.isOver(),
dropClassName: dragIndex < index ? ' drop-over-downward' : ' drop-over-upward',
};
},
drop: item => {
moveRow(item.index, index);
},
});
const [, drag] = useDrag({
type,
item: { index },
collect: monitor => ({
isDragging: monitor.isDragging(),
}),
});
drop(drag(ref));
const errorNode = <Tooltip title="Upload Error">{originNode.props.children}</Tooltip>;
return (
<div
ref={ref}
className={`ant-upload-draggable-list-item ${isOver ? dropClassName : ''}`}
style={{ cursor: 'move' }}
>
{file.status === 'error' ? errorNode : originNode}
</div>
);
}
Example #3
Source File: drag-sorting.jsx From virtuoso-design-system with MIT License | 6 votes |
DragableBodyRow = ({ index, moveRow, className, style, ...restProps }) => {
const ref = useRef();
const [{ isOver, dropClassName }, drop] = useDrop({
accept: type,
collect: monitor => {
const { index: dragIndex } = monitor.getItem() || {};
if (dragIndex === index) {
return {};
}
return {
isOver: monitor.isOver(),
dropClassName: dragIndex < index ? ' drop-over-downward' : ' drop-over-upward',
};
},
drop: item => {
moveRow(item.index, index);
},
});
const [, drag] = useDrag({
type,
item: { index },
collect: monitor => ({
isDragging: monitor.isDragging(),
}),
});
drop(drag(ref));
return (
<tr
ref={ref}
className={`${className}${isOver ? dropClassName : ''}`}
style={{ cursor: 'move', ...style }}
{...restProps}
/>
);
}
Example #4
Source File: index.jsx From taro-form with MIT License | 6 votes |
Module = ({ item, editForm }) => {
const [, drag] = useDrag({
item: { type: EditTypes.FORM_ADD, tpl: item.tpl },
begin() {
editForm(-1)
}
})
return <View ref={drag} className='item'>
<Text className='text'>{item.text}</Text>
</View>
}
Example #5
Source File: Fields.jsx From signdocs with MIT License | 6 votes |
FieldItem = (props) => {
const { children, disabled, type } = props;
const [, drag] = useDrag({
canDrag: !disabled,
item: {
...props,
hideSourceOnDrag: true,
},
collect: (monitor) => ({
isDragging: monitor.isDragging(),
}),
});
let classNames = 'draggable';
if (disabled) classNames += ' disabled-drag';
return (
<li ref={drag} className={classNames} id={`FIELD-${type}`}>
{children}
</li>
);
}
Example #6
Source File: sort.js From actual with MIT License | 6 votes |
export function useDraggable({
item,
type,
makePreview,
children,
canDrag,
onDragChange
}) {
let _onDragChange = useRef(onDragChange);
//eslint-disable-next-line
const [{ isDragging }, dragRef] = useDrag({
item: { type, item },
collect: monitor => ({ isDragging: monitor.isDragging() }),
begin(monitor) {
_onDragChange.current({ state: 'start-preview', type, item });
setTimeout(() => {
_onDragChange.current({ state: 'start' });
}, 0);
},
end(item, monitor) {
_onDragChange.current({ state: 'end', type, item });
},
canDrag() {
return canDrag;
}
});
useLayoutEffect(() => {
_onDragChange.current = onDragChange;
});
return { dragRef };
}
Example #7
Source File: useRowDrag.js From os-league-tools with MIT License | 6 votes |
export default function useRowDrag(type, index) {
return useDrag({
type,
item: { index },
collect: monitor => ({
isDragging: monitor.isDragging(),
}),
});
}
Example #8
Source File: dragTarget.js From ant-simple-pro with MIT License | 6 votes |
DragTarget = memo(function DragTarget({itemValue}) {
const [, drager] = useDrag({
type:"Box",
item:itemValue
});
return (
<div ref={ drager } className={style.drapTarget}>
<SvgIcon iconClass={itemValue.type} className='svg-style' />
<p>{itemValue.title}</p>
</div>
)
})
Example #9
Source File: sortable-item.js From Quest with MIT License | 5 votes |
// https://react-dnd.github.io/react-dnd/examples/sortable/simple
function SortableItem({ id, text, index, moveCard }) {
const ref = useRef(null);
const [, drop] = useDrop({
accept: "item",
hover(item, monitor) {
if (!ref.current) {
return;
}
const dragIndex = item.index;
const hoverIndex = index;
// Don't replace items with themselves
if (dragIndex === hoverIndex) {
return;
}
const hoverBoundingRect = ref.current.getBoundingClientRect();
const hoverMiddleY = (hoverBoundingRect.bottom - hoverBoundingRect.top) / 2;
const clientOffset = monitor.getClientOffset();
const hoverClientY = clientOffset.y - hoverBoundingRect.top;
if (dragIndex < hoverIndex && hoverClientY < hoverMiddleY) {
return;
}
// Dragging upwards
if (dragIndex > hoverIndex && hoverClientY > hoverMiddleY) {
return;
}
moveCard(dragIndex, hoverIndex);
item.index = hoverIndex;
},
});
const [{ isDragging }, drag] = useDrag({
item: { type: "item", id, index },
collect: (monitor) => ({ isDragging: monitor.isDragging() }),
});
const opacity = isDragging ? 0.2 : 1;
drag(drop(ref));
return (
<div
className={`${CARD} ${ELEVATION_2}`}
ref={ref}
style={{ opacity, margin: "8px 0px", cursor: "move" }}
>
<Icon icon="drag-handle-vertical" />
<H5 style={{ display: "inline" }}>{text}</H5>
</div>
);
}
Example #10
Source File: DraggableBox.jsx From signdocs with MIT License | 5 votes |
DraggableBox = ({ cfData, thisPage }) => {
const dispatch = useDispatch();
const {
type,
bbox,
hideSourceOnDrag = false,
signatoryId,
placeholder,
} = cfData;
const onRemove = () => dispatch(deleteContentField(cfData.id));
const signatory = useSelector(getUserDetails(signatoryId));
const [{ isDragging, opacity }, drag, preview] = useDrag({
item: { ...cfData, type },
collect: (monitor) => ({
isDragging: monitor.isDragging(),
opacity: monitor.isDragging() ? 0.4 : 1,
}),
});
if (isDragging && hideSourceOnDrag) {
return <div ref={drag} />;
}
const style = convertBBOXtoPixels(bbox, thisPage);
if (type === ItemTypes.UNFILLED_SIGNATURE)
return (
<div
ref={preview}
className="content-field draggable-item"
style={{ ...style, opacity }}
>
<UnfilledSignature
onRemove={onRemove}
signatoryName={signatory.fullName}
width={style.width}
height={style.height}
ref={drag}
/>
</div>
);
if (type === ItemTypes.UNFILLED_TEXT)
return (
<div
ref={preview}
className="content-field draggable-item fillable"
style={{ ...style, opacity }}
>
<UnfilledTextBox
placeholder={placeholder}
onRemove={onRemove}
width={style.width}
height={style.height}
ref={drag}
/>
</div>
);
}
Example #11
Source File: Thumbnail.js From vindr-lab-viewer with MIT License | 5 votes |
function Thumbnail(props) {
const {
active,
altImageText,
error,
displaySetInstanceUID,
imageId,
imageSrc,
SeriesDescription,
stackPercentComplete,
StudyInstanceUID,
onClick,
onDoubleClick,
onMouseDown,
supportsDrag,
} = props;
const [collectedProps, drag, dragPreview] = useDrag({
// `droppedItem` in `dropTarget`
// The only data it will have access to
item: {
StudyInstanceUID,
displaySetInstanceUID,
type: 'thumbnail', // Has to match `dropTarget`'s type
},
canDrag: function(monitor) {
return supportsDrag;
},
});
const hasImage = imageSrc || imageId;
const hasAltText = altImageText !== undefined;
return (
<div
ref={drag}
className={classNames('thumbnail', {
active_item: active,
})}
onClick={onClick}
onDoubleClick={onDoubleClick}
onMouseDown={onMouseDown}
>
{SeriesDescription && (
<div className="series-description">{SeriesDescription || ''}</div>
)}
{/* SHOW IMAGE */}
{hasImage && (
<ImageThumbnail
imageSrc={imageSrc}
imageId={imageId}
error={error}
stackPercentComplete={stackPercentComplete}
width={97}
/>
)}
{/* SHOW TEXT ALTERNATIVE */}
{!hasImage && hasAltText && (
<div className={'alt-image-text p-x-1'}>
<h1>{altImageText}</h1>
</div>
)}
{ThumbnailFooter(props)}
</div>
);
}
Example #12
Source File: DndItem.js From the-eye-knows-the-garbage with MIT License | 4 votes |
Card = function Card(_ref) {
var id = _ref.id,
_end = _ref.end,
move = _ref.move,
children = _ref.children,
index = _ref.index;
var ref = useRef(null);
var _useDrop = useDrop({
accept: ItemTypes.CARD,
hover: function hover(item, monitor) {
if (!ref.current) {
return;
}
var dragIndex = item.index;
var hoverIndex = index; // Don't replace items with themselves
if (dragIndex === hoverIndex) {
return;
} // Determine rectangle on screen
var hoverBoundingRect = ref.current.getBoundingClientRect(); // Get vertical middle
var hoverMiddleY = (hoverBoundingRect.bottom - hoverBoundingRect.top) / 2; // Determine mouse position
var clientOffset = monitor.getClientOffset(); // Get pixels to the top
var hoverClientY = clientOffset.y - hoverBoundingRect.top; // Only perform the move when the mouse has crossed half of the items height
// When dragging downwards, only move when the cursor is below 50%
// When dragging upwards, only move when the cursor is above 50%
// Dragging downwards
if (dragIndex < hoverIndex && hoverClientY < hoverMiddleY) {
return;
} // Dragging upwards
if (dragIndex > hoverIndex && hoverClientY > hoverMiddleY) {
return;
} // Time to actually perform the action
if (move) {
move(dragIndex, hoverIndex);
} // Note: we're mutating the monitor item here!
// Generally it's better to avoid mutations,
// but it's good here for the sake of performance
// to avoid expensive index searches.
// eslint-disable-next-line no-param-reassign
item.index = hoverIndex;
}
}),
_useDrop2 = _slicedToArray(_useDrop, 2),
drop = _useDrop2[1];
var _useDrag = useDrag({
item: {
type: ItemTypes.CARD,
id: id,
index: index
},
collect: function collect(monitor) {
return {
isDragging: monitor.isDragging()
};
},
end: function end(item) {
if (!item) {
return;
}
_end(item.id, item.index);
}
}),
_useDrag2 = _slicedToArray(_useDrag, 2),
isDragging = _useDrag2[0].isDragging,
drag = _useDrag2[1];
var opacity = isDragging ? 0 : 1;
drag(drop(ref));
return React.createElement("div", {
ref: ref,
style: {
opacity: opacity
}
}, children);
}
Example #13
Source File: DraggableCard.js From cards-of-personality-frontend with GNU Affero General Public License v3.0 | 4 votes |
DraggableCard = ({
bgColor,
isBroadcastingDrag = true,
isFlipBroadcasted,
color,
socket,
text,
type,
setUserIsDragging,
flippedByDefault = false,
isFlippable = true,
screen = '',
isMyCardsOpen,
isSubmittedTableOpen,
}) => {
const [ghostCard, setGhostCard] = useState({});
const [isFlipped, setFlipped] = useState(flippedByDefault);
const [{isDragging, getDifferenceFromInitialOffset}, drag] = useDrag({
item: {
type,
id: 0,
text,
bgColor,
color,
isFlipped,
},
collect: (monitor) => ({
isDragging: !!monitor.isDragging() && !Object.keys(ghostCard).length,
getDifferenceFromInitialOffset:
!!monitor.isDragging() && monitor.getDifferenceFromInitialOffset(),
}),
});
if (isDragging && getDifferenceFromInitialOffset) {
const {x, y} = getDifferenceFromInitialOffset;
if (isBroadcastingDrag) {
// send dragged card to server
socket.emit('dragged card', {type, text, x, y});
}
}
useEffect(() => {
setUserIsDragging(type);
if (isBroadcastingDrag) {
if (!isDragging) {
// send card that was let go to server
socket.emit('let go card', {ghostDragging: false, type, text});
}
}
if (!isDragging) {
setUserIsDragging(null);
}
return () => {
setUserIsDragging(null);
};
}, [isBroadcastingDrag, setUserIsDragging, socket, text, type, isDragging]);
useEffect(() => {
let isMounted = true;
if (isBroadcastingDrag) {
// on everyones client but the sender, show the card being returned to deck if let go prematurely
socket.on('let go card', ({text: otherText}) => {
if (isMounted && text === otherText) {
setGhostCard({});
}
});
// on everyones client but the sender, show the card being dragged
socket.on('dragged card', ({text: otherText, x, y, type}) => {
if (isMounted && text === otherText) {
// if i'm looking at my cards, never drag cards on other screens
if (isMyCardsOpen && !isSubmittedTableOpen) {
return;
}
// if the card that is being dragged is on the submitted cards screen
// and the submitted cards screen isn't open, then don't set state
if (screen === 'submittedCards' && !isSubmittedTableOpen) {
return;
}
// if the card that is being dragged is on the main screen
// and the submitted cards screen is open, then don't set state
if (screen === 'main' && isSubmittedTableOpen) {
return;
}
setGhostCard({x, y, text});
}
});
}
if (isFlipBroadcasted) {
socket.on('card is flipped', function ({isFlipped, text: otherText}) {
if (isMounted && text === otherText) {
setFlipped(isFlipped);
}
});
}
return () => {
// socket.off('let go card');
// socket.off('dragged cards');
isMounted = false;
};
}, [
isBroadcastingDrag,
setUserIsDragging,
socket,
text,
type,
isFlipBroadcasted,
isMyCardsOpen,
isSubmittedTableOpen,
screen
]);
const getTransform = () => {
if (isBroadcastingDrag) {
// any cards being dragged by someone else
if (Object.keys(ghostCard).length) {
if (ghostCard.text === text) {
return {
pointerEvents: 'none',
opacity: '1',
transform: `translate3d(${ghostCard.x}px, ${ghostCard.y}px, 0)`,
zIndex: '999',
};
} else {
return {pointerEvents: 'none', transform: 'translate3d(0, 0, 0)'};
}
}
}
// on the client that's actually dragging the card
if (isDragging && getDifferenceFromInitialOffset) {
return {
pointerEvents: 'none',
transform: `translate3d(${getDifferenceFromInitialOffset.x}px, ${getDifferenceFromInitialOffset.y}px, 0)`,
};
}
return {transform: 'translate3d(0, 0, 0)'};
};
const getClassName = () => {
if (isBroadcastingDrag) {
// any cards being dragged by someone else
if (Object.keys(ghostCard).length) {
if (ghostCard.text === text) {
return 'is-dragging';
} else {
return null;
}
}
}
// on the client that's actually dragging the card
if (isDragging && getDifferenceFromInitialOffset) {
return 'is-dragging';
}
return null;
};
return (
<CardElement
className={getClassName()}
onClick={() => {
if (isFlippable) {
setFlipped((isFlipped) => {
socket.emit('card is flipped', {isFlipped: !isFlipped, text});
return !isFlipped;
});
}
}}
ref={drag}
style={{
zIndex: isDragging ? 999 : '0',
...getTransform(),
backgroundColor: bgColor,
color,
justifyContent: isFlipped ? '' : 'flex-start',
}}
>
{isFlipped ? (
text
) : (
<>
<div
className={`LogoInCard ${
type === 'whiteCard' ? 'LogoInCard--whiteCard' : ''
}`}
/>
{type.includes('black') && (
<TouchIconWrap>
<TouchIcon />
</TouchIconWrap>
)}
</>
)}
</CardElement>
);
}
Example #14
Source File: QueueCard.js From qasong with ISC License | 4 votes |
export default function ImgMediaCard({
id,
index,
nowPlaying,
onClickImage,
moveCard,
qid,
queue,
setQueue,
thumbnail,
title,
}) {
const classes = useStyles();
const ref = useRef(null);
const removeQueueItem = () => {
setQueue(
queue.filter((item) => {
return item.qid !== qid;
})
);
};
const [, drop] = useDrop({
accept: "card",
hover(item, monitor) {
if (!ref.current) {
return;
}
const dragIndex = item.index;
const hoverIndex = index;
// Don't replace items with themselves
if (dragIndex === hoverIndex) {
return;
}
// Determine rectangle on screen
const hoverBoundingRect = ref.current?.getBoundingClientRect();
// Get vertical middle
const hoverMiddleY = (hoverBoundingRect.bottom - hoverBoundingRect.top) / 2;
// Determine mouse position
const clientOffset = monitor.getClientOffset();
// Get pixels to the top
const hoverClientY = clientOffset.y - hoverBoundingRect.top;
// Only perform the move when the mouse has crossed half of the items height
// When dragging downwards, only move when the cursor is below 50%
// When dragging upwards, only move when the cursor is above 50%
// Dragging downwards
if (dragIndex < hoverIndex && hoverClientY < hoverMiddleY) {
return;
}
// Dragging upwards
if (dragIndex > hoverIndex && hoverClientY > hoverMiddleY) {
return;
}
// Time to actually perform the action
moveCard(dragIndex, hoverIndex);
// Note: we're mutating the monitor item here!
// Generally it's better to avoid mutations,
// but it's good here for the sake of performance
// to avoid expensive index searches.
item.index = hoverIndex;
},
});
const [{ isDragging }, drag] = useDrag({
item: { type: "card", id, index },
collect: (monitor) => ({
isDragging: monitor.isDragging(),
}),
});
const opacity = isDragging ? 0 : 1;
drag(drop(ref));
return (
<Card
ref={ref}
className={classes.card}
style={{
backgroundColor: (nowPlaying && nowPlaying.qid) === qid && qasongOrange,
opacity,
}}
>
<CardActionArea style={{ height: "100px" }} onClick={() => onClickImage(qid)}>
<CardMedia
className={classes.media}
component="img"
alt={title}
image={thumbnail}
title={title}
/>
<Box p={1}>
<Grid container direction="column">
<Grid item>
<Typography style={{ fontSize: "8px" }} gutterBottom>
{formatVideoTitle(title)}
</Typography>
</Grid>
</Grid>
</Box>
</CardActionArea>
{/* Remove from queue overlay */}
<Box className={classes.overlay}>
<Tooltip title="remove from queue">
<IconButton
edge="end"
color="secondary"
onClick={removeQueueItem}
size="small"
style={{ color: "red", background: "#00000080" }}
>
<ClearIcon />
</IconButton>
</Tooltip>
</Box>
</Card>
);
}
Example #15
Source File: User.js From virtualdojo-rooms with GNU General Public License v3.0 | 4 votes |
function User({
user,
currentUser,
avatarSize,
inRoom,
avatarColor,
changeRoom,
dragDisabled,
}) {
const { setIsDragging } = useContext(store);
const classes = useStyles();
const [anchorEl, setAnchorEl] = useState(null);
const handlePopoverOpen = (event) => {
setAnchorEl(event.currentTarget);
};
const handlePopoverClose = () => {
setAnchorEl(null);
};
const canDrag = currentUser.isMentor && !dragDisabled;
const [{ isDragging }, drag] = useDrag({
item: { name: user.userName, type: ItemTypes.USER },
begin: () => setIsDragging(true),
canDrag,
end: (item, monitor) => {
const dropResult = monitor.getDropResult();
setIsDragging(false);
if (item && dropResult) {
changeRoom(user.userId, dropResult.room.roomId);
}
},
collect: (monitor) => ({
isDragging: monitor.isDragging(),
}),
});
const avatarWidthHeight = avatarSize === "sm" ? 24 : 36;
const popoverOpen = !isDragging && Boolean(anchorEl);
const initials = user.userName
.trim()
.split(" ")
.slice(0, 2)
.map((s) => (s && [...s].length > 0 ? [...s][0].toUpperCase() : ""));
console.log(initials);
return (
<Grid
item
style={{
opacity: isDragging ? "0.4" : "1",
}}
onMouseEnter={handlePopoverOpen}
onMouseLeave={handlePopoverClose}
>
<Avatar
style={{
...avatarColor,
width: avatarWidthHeight,
height: avatarWidthHeight,
cursor: canDrag ? "grab" : "default",
borderRadius: user.isMentor ? 0 : "50%",
}}
ref={drag}
>
{initials}
</Avatar>
<Popover
id="mouse-over-popover"
className={classes.popover}
classes={{
paper: classes.paper,
}}
open={popoverOpen}
anchorEl={anchorEl}
anchorOrigin={{
vertical: "bottom",
horizontal: "left",
}}
transformOrigin={{
vertical: "top",
horizontal: "left",
}}
onClose={handlePopoverClose}
disableRestoreFocus
>
<Typography>
{user.userName}
{user.isMentor && <b> (Mentor)</b>}
</Typography>
</Popover>
</Grid>
);
}
Example #16
Source File: QueueRow.js From qasong with ISC License | 4 votes |
export default function ImgMediaCard({
id,
index,
nowPlaying,
onClickMusicRow,
moveCard,
qid,
queue,
setQueue,
title,
timestamp,
}) {
const classes = useStyles();
const ref = useRef(null);
const removeQueueItem = (e) => {
e.stopPropagation();
setQueue(
queue.filter((item) => {
return item.qid !== qid;
})
);
};
const [, drop] = useDrop({
accept: "card",
hover(item, monitor) {
if (!ref.current) {
return;
}
const dragIndex = item.index;
const hoverIndex = index;
// Don't replace items with themselves
if (dragIndex === hoverIndex) {
return;
}
// Determine rectangle on screen
const hoverBoundingRect = ref.current?.getBoundingClientRect();
// Get vertical middle
const hoverMiddleY = (hoverBoundingRect.bottom - hoverBoundingRect.top) / 2;
// Determine mouse position
const clientOffset = monitor.getClientOffset();
// Get pixels to the top
const hoverClientY = clientOffset.y - hoverBoundingRect.top;
// Only perform the move when the mouse has crossed half of the items height
// When dragging downwards, only move when the cursor is below 50%
// When dragging upwards, only move when the cursor is above 50%
// Dragging downwards
if (dragIndex < hoverIndex && hoverClientY < hoverMiddleY) {
return;
}
// Dragging upwards
if (dragIndex > hoverIndex && hoverClientY > hoverMiddleY) {
return;
}
// Time to actually perform the action
moveCard(dragIndex, hoverIndex);
// Note: we're mutating the monitor item here!
// Generally it's better to avoid mutations,
// but it's good here for the sake of performance
// to avoid expensive index searches.
item.index = hoverIndex;
},
});
const [{ isDragging }, drag, preview] = useDrag({
item: { type: "card", id, index },
collect: (monitor) => ({
isDragging: monitor.isDragging(),
}),
});
const opacity = isDragging ? 0 : 1;
drag(drop(ref));
return (
<Grid
item
container
className={classes.row + " qasong-queueitem"}
onClick={() => onClickMusicRow(qid)}
direction="row"
alignItems="center"
ref={preview}
style={{
backgroundColor: (nowPlaying && nowPlaying.qid) === qid && qasongOrange,
opacity,
}}
>
<Grid item xs={1}>
<IconButton>
<PlayArrowIcon />
</IconButton>
</Grid>
<Grid item xs={9}>
<Typography>{title}</Typography>
</Grid>
<Grid item xs={1}>
<IconButton className={classes.dragHandle} ref={ref}>
<DragHandleIcon />
</IconButton>
</Grid>
<Grid item xs={1}>
<Typography>{timestamp}</Typography>
</Grid>
{/* Remove from queue overlay */}
<Box className={classes.overlay}>
<Tooltip title="remove from queue">
<IconButton
edge="end"
onClick={removeQueueItem}
size="small"
style={{ color: "red", background: "#00000080" }}
>
<ClearIcon />
</IconButton>
</Tooltip>
</Box>
</Grid>
);
}
Example #17
Source File: Card.jsx From ashteki with GNU Affero General Public License v3.0 | 4 votes |
Card = ({
canDrag,
card,
cardBackUrl,
className,
disableMouseOver,
onClick,
onAltClick,
onDieClick,
onMenuItemClick,
onMouseOut,
onMouseOver,
orientation = 'vertical',
showAltIcon,
side,
size,
source,
style,
wrapped = true
}) => {
const cardBack = cardBackUrl || (card.isConjuration ? conjback : spellback);
const sizeClass = {
[size]: size !== 'normal'
};
const [showMenu, setShowMenu] = useState(false);
const [{ dragOffset, isDragging }, drag, preview] = useDrag({
item: { card: card, source: source, type: ItemTypes.CARD },
canDrag: () => canDrag || (!card.unselectable && card.canPlay),
collect: (monitor) => ({
isDragging: monitor.isDragging(),
dragOffset: monitor.getSourceClientOffset()
})
});
const isAllowedMenuSource = () => {
return source === 'play area' || source === 'spellboard';
};
const onCardClicked = (event, card) => {
event.preventDefault();
event.stopPropagation();
if (isAllowedMenuSource() && card.menu && card.menu.length !== 0) {
setShowMenu(!showMenu);
return;
}
onClick && onClick(card);
};
const getCountersForCard = (card) => {
let counters = [];
let needsFade = UpgradeCardTypes.includes(card.type) && !['full deck'].includes(source);
if (card.acquiredEffects?.length) {
card.acquiredEffects.forEach((e) => {
counters.push({
icon: e.effect,
name: e.source,
count: 1,
fade: needsFade,
showValue: false
});
});
}
if (card.armor > 0) {
counters.push({
name: 'armor',
count: card.armor,
fade: needsFade,
showValue: true
});
}
if (card.guarded || card.cannotBlock) {
counters.push({
name: 'guarded',
count: 1,
fade: needsFade,
showValue: false
});
}
for (const [key, token] of Object.entries(card.tokens || {})) {
counters.push({
name: key,
count: token,
fade: needsFade,
showValue: true
});
}
for (const upgrade of card.upgrades || []) {
counters = counters.concat(getCountersForCard(upgrade));
}
return counters.filter((counter) => counter.count >= 0);
};
const getCardSizeMultiplier = () => {
switch (size) {
case 'small':
return 0.6;
case 'large':
return 1.4;
case 'x-large':
return 2;
}
return 1;
};
const getupgrades = () => {
if (!['full deck', 'play area', 'spellboard'].includes(source)) {
return null;
}
if (['full deck', 'play area'].includes(source) && !card.upgrades) {
return null;
}
if ('spellboard' === source && !card.childCards) {
return null;
}
let index = 1;
const cardsToRender = 'spellboard' === source
? card.childCards
: card.upgrades;
let upgrades = cardsToRender.map((upgrade) => {
let returnedupgrade = (
<Card
key={upgrade.uuid}
source={source}
card={upgrade}
className={classNames('upgrade', `upgrade-${index}`)}
wrapped={false}
onMouseOver={
!disableMouseOver && onMouseOver
? (upgrade) => onMouseOver(upgrade)
: undefined
}
onMouseOut={!disableMouseOver && onMouseOut}
onClick={onClick}
onMenuItemClick={onMenuItemClick}
size={size}
/>
);
index += 1;
return returnedupgrade;
});
return upgrades;
};
const renderUnderneathCards = () => {
// TODO: Right now it is assumed that all cards in the childCards array
// are being placed underneath the current card. In the future there may
// be other types of cards in this array and it should be filtered.
let underneathCards = card.childCards;
if (!underneathCards || underneathCards.length === 0 || card.location === 'spellboard') {
return;
}
let maxCards = 1 + (underneathCards.length - 1) / 6;
return (
<SquishableCardPanel
cardSize={size}
cards={underneathCards}
className='underneath'
maxCards={maxCards}
onCardClick={onClick}
onMouseOut={onMouseOut}
onMouseOver={onMouseOver}
source='underneath'
/>
);
};
const getCardOrdering = () => {
if (!card.order) {
return null;
}
return <div className='card-ordering'>{card.order}</div>;
};
const shouldShowMenu = () => {
if (!isAllowedMenuSource()) {
return false;
}
if (!card.menu || !showMenu) {
return false;
}
return true;
};
const showCounters = () => {
if (['full deck'].includes(source)) {
return true;
}
if (card.facedown || UpgradeCardTypes.includes(card.type)) {
return false;
}
return true;
};
const isFacedown = () => {
return card.facedown || !card.name;
};
const getDragFrame = (image) => {
if (!isDragging) {
return null;
}
let style = {};
if (dragOffset && isDragging) {
let x = dragOffset.x;
let y = dragOffset.y;
style = {
left: x,
top: y
};
}
return (
<div className='drag-preview' style={style} ref={preview}>
{image}
</div>
);
};
const getBoostedFlags = (card) => {
if (card.flags) {
let flagItems = Object.keys(card.flags)
.sort((a, b) => (a < b ? -1 : 1))
.map((key, index) => {
return (
<div key={key + index} className={`darkbg flag ${key}`}>
<span className='sr-only'>{key[0]}</span>
{card.flags[key]}
</div>
);
});
return <div className='flags'>{flagItems}</div>;
}
return '';
};
const getChainIcon = (card) => {
if (card.isChained) {
return (
<div className='card-chain-icon'>
<FontAwesomeIcon icon={faLink} />
</div>
);
}
return '';
};
const getAltIcon = (card) => {
if (showAltIcon && card.altArts) {
return (
<div className='card-alt-icon'>
<button className=''
onClick={() => onAltClick(card)}
>Alt</button>
</div>
);
}
return '';
};
const getCard = () => {
if (!card) {
return <div />;
}
let statusClass = getStatusClass();
const combatClass = card.isAttacker || card.isDefender ? 'combat-' + side : null;
let cardClass = classNames(
'game-card',
`card-type-${card.type}`,
className,
sizeClass,
statusClass,
combatClass,
{
'custom-card': card.code && card.code.startsWith('custom'),
horizontal: orientation !== 'vertical',
vertical: orientation === 'vertical',
'can-play':
statusClass !== 'selected' &&
statusClass !== 'selectable' &&
!card.unselectable &&
!card.isAttacker &&
!card.isDefender &&
card.canPlay,
unselectable: !card.selected && card.unselectable,
dragging: isDragging,
controlled: card.controlled,
attacker: card.isAttacker,
defender: card.isDefender
}
);
let imageClass = classNames('card-image vertical', sizeClass, {
exhausted: orientation === 'exhausted' || orientation === 'horizontal'
});
let image = card ? (
<div className={imageClass}>
<CardImage card={card} cardBack={cardBack} />
{getChainIcon(card)}
{getBoostedFlags(card)}
</div>
) : null;
let dice =
card.dieUpgrades && card.dieUpgrades.length > 0
? card.dieUpgrades.map((d) => (
<Die key={'dup-' + d.uuid} die={d} onClick={onDieClick} />
))
: null;
return (
<div className='card-frame' ref={drag}>
{getDragFrame(image)}
{getCardOrdering()}
<div
tabIndex={0}
className={cardClass}
onMouseOver={
!disableMouseOver && (!isFacedown() || !card.parent) && onMouseOver
? () => onMouseOver(card)
: undefined
}
onMouseOut={!disableMouseOver && !isFacedown() ? onMouseOut : undefined}
onClick={(event) => onCardClicked(event, card)}
>
<div>
<span className='card-name'>{card.name}</span>
{image}
</div>
{showCounters() && <CardCounters counters={getCountersForCard(card)} />}
<div className='die-upgrades'>{dice}</div>
</div>
{shouldShowMenu() && (
<CardMenu
menu={card.menu}
side={side}
onMenuItemClick={(menuItem) => {
onMenuItemClick && onMenuItemClick(card, menuItem);
setShowMenu(!showMenu);
}}
/>
)}
</div>
);
};
const getStatusClass = () => {
if (!card) {
return undefined;
}
// location prevents highlighting cards we're about to meditate
if (card.selected && card.location !== 'deck') {
return 'selected';
} else if (card.selectable) {
// if (card.isAttacker) return 'attacker-' + side + ' selectable ';
return 'selectable';
// } else if (card.isAttacker) {
// return 'attacker-' + side;
// } else if (card.isDefender) {
// return 'defender-' + side;
} else if (card.new) {
return 'new';
}
return undefined;
};
let styleCopy = Object.assign({}, style);
if (card.upgrades) {
styleCopy.top = card.upgrades.length * (15 * getCardSizeMultiplier());
}
if (wrapped) {
return (
<div className={'card-wrapper'} style={style}>
{getAltIcon(card)}
{getCard()}
{getupgrades()}
{renderUnderneathCards()}
</div>
);
}
return getCard();
}
Example #18
Source File: LicenseFieldItem.js From react-invenio-deposit with MIT License | 4 votes |
LicenseFieldItem = ({
license,
moveLicense,
replaceLicense,
removeLicense,
searchConfig,
serializeLicenses,
}) => {
const dropRef = React.useRef(null);
const [_, drag, preview] = useDrag({
item: { index: license.index, type: 'license' },
});
const [{ hidden }, drop] = useDrop({
accept: 'license',
hover(item, monitor) {
if (!dropRef.current) {
return;
}
const dragIndex = item.index;
const hoverIndex = license.index;
// Don't replace items with themselves
if (dragIndex === hoverIndex) {
return;
}
if (monitor.isOver({ shallow: true })) {
moveLicense(dragIndex, hoverIndex);
item.index = hoverIndex;
}
},
collect: (monitor) => ({
hidden: monitor.isOver({ shallow: true }),
}),
});
// Initialize the ref explicitely
drop(dropRef);
return (
<Ref innerRef={dropRef} key={license.key}>
<List.Item
key={license.key}
className={
hidden ? 'deposit-drag-listitem hidden' : 'deposit-drag-listitem'
}
>
<List.Content floated="right">
<LicenseModal
searchConfig={searchConfig}
onLicenseChange={(selectedLicense) => {
replaceLicense(license.index, selectedLicense);
}}
mode={license.type}
initialLicense={license.initial}
action="edit"
trigger={
<Button size="mini" primary type="button">
{i18next.t('Edit')}
</Button>
}
serializeLicenses={serializeLicenses}
/>
<Button
size="mini"
type="button"
onClick={() => {
removeLicense(license.index);
}}
>
{i18next.t('Remove')}
</Button>
</List.Content>
<Ref innerRef={drag}>
<List.Icon name="bars" className="drag-anchor" />
</Ref>
<Ref innerRef={preview}>
<List.Content>
<List.Header>{license.title}</List.Header>
{license.description && (
<List.Description>
{_truncate(license.description, { length: 300 })}
</List.Description>
)}
{license.link && (
<span>
<a href={license.link} target="_blank" rel="noopener noreferrer">
{license.description && <span> </span>}
{i18next.t('Read more')}
</a>
</span>
)}
</List.Content>
</Ref>
</List.Item>
</Ref>
);
}
Example #19
Source File: FundingFieldItem.js From react-invenio-deposit with MIT License | 4 votes |
FundingFieldItem = ({
compKey,
index,
fundingItem,
awardType,
moveFunding,
replaceFunding,
removeFunding,
searchConfig,
deserializeAward,
deserializeFunder,
computeFundingContents
}) => {
const dropRef = React.useRef(null);
const [_, drag, preview] = useDrag({
item: { index, type: 'award' },
});
const [{ hidden }, drop] = useDrop({
accept: 'award',
hover(item, monitor) {
if (!dropRef.current) {
return;
}
const dragIndex = item.index;
const hoverIndex = index;
// Don't replace items with themselves
if (dragIndex === hoverIndex) {
return;
}
if (monitor.isOver({ shallow: true })) {
moveFunding(dragIndex, hoverIndex);
item.index = hoverIndex;
}
},
collect: (monitor) => ({
hidden: monitor.isOver({ shallow: true }),
}),
});
let { headerContent, descriptionContent, awardOrFunder } = computeFundingContents(fundingItem);
// Initialize the ref explicitely
drop(dropRef);
return (
<Ref innerRef={dropRef} key={compKey}>
<List.Item
key={compKey}
className={
hidden ? 'deposit-drag-listitem hidden' : 'deposit-drag-listitem'
}
>
<List.Content floated="right">
<FundingModal
searchConfig={searchConfig}
onAwardChange={(selectedFunding) => {
replaceFunding(index, selectedFunding);
}}
mode={awardType}
action="edit"
trigger={
<Button size="mini" primary type="button">
{i18next.t('Edit')}
</Button>
}
deserializeAward={deserializeAward}
deserializeFunder={deserializeFunder}
computeFundingContents={computeFundingContents}
initialFunding={fundingItem}
/>
<Button size="mini" type="button" onClick={() => removeFunding(index)}>
{i18next.t('Remove')}
</Button>
</List.Content>
<Ref innerRef={drag}>
<List.Icon name="bars" className="drag-anchor" />
</Ref>
<Ref innerRef={preview}>
<List.Content>
<List.Header>
{(
<>
<span className="mr-5">
{headerContent}
</span>
{awardOrFunder === 'award'
? (fundingItem?.award?.number && (
<Label basic size="mini" className="mr-5">
{fundingItem.award.number}
</Label>)
)
: ''}
{
awardOrFunder === 'award'
? (fundingItem?.award?.url && (
<a
href={`${fundingItem.award.url}`}
target="_blank"
rel="noopener noreferrer"
aria-label={i18next.t('Open external link')}
>
<Icon link name="external alternate" />
</a>
))
: ''
}
</>
)}
</List.Header>
<List.Description>
{descriptionContent ? descriptionContent : <br/>}
</List.Description>
</List.Content>
</Ref>
</List.Item>
</Ref>
);
}
Example #20
Source File: CreatibutorsFieldItem.js From react-invenio-deposit with MIT License | 4 votes |
CreatibutorsFieldItem = ({
compKey,
identifiersError,
index,
replaceCreatibutor,
removeCreatibutor,
moveCreatibutor,
addLabel,
editLabel,
initialCreatibutor,
displayName,
roleOptions,
schema,
autocompleteNames,
}) => {
const dropRef = React.useRef(null);
const [_, drag, preview] = useDrag({
item: { index, type: 'creatibutor' },
});
const [{ hidden }, drop] = useDrop({
accept: 'creatibutor',
hover(item, monitor) {
if (!dropRef.current) {
return;
}
const dragIndex = item.index;
const hoverIndex = index;
// Don't replace items with themselves
if (dragIndex === hoverIndex) {
return;
}
if (monitor.isOver({ shallow: true })) {
moveCreatibutor(dragIndex, hoverIndex);
item.index = hoverIndex;
}
},
collect: (monitor) => ({
hidden: monitor.isOver({ shallow: true }),
}),
});
const renderRole = (role, roleOptions) => {
if (role) {
const friendlyRole =
roleOptions.find(({ value }) => value === role)?.text ?? role;
return <Label size="tiny">{friendlyRole}</Label>;
}
};
const firstError =
identifiersError &&
identifiersError.find((elem) => ![undefined, null].includes(elem));
// Initialize the ref explicitely
drop(dropRef);
return (
<Ref innerRef={dropRef} key={compKey}>
<List.Item
key={compKey}
className={
hidden ? 'deposit-drag-listitem hidden' : 'deposit-drag-listitem'
}
>
<List.Content floated="right">
<CreatibutorsModal
addLabel={addLabel}
editLabel={editLabel}
onCreatibutorChange={(selectedCreatibutor) => {
replaceCreatibutor(index, selectedCreatibutor);
}}
initialCreatibutor={initialCreatibutor}
roleOptions={roleOptions}
schema={schema}
autocompleteNames={autocompleteNames}
action="edit"
trigger={
<Button size="mini" primary type="button">
{i18next.t('Edit')}
</Button>
}
/>
<Button
size="mini"
type="button"
onClick={() => removeCreatibutor(index)}
>
{i18next.t('Remove')}
</Button>
</List.Content>
<Ref innerRef={drag}>
<List.Icon name="bars" className="drag-anchor" />
</Ref>
<Ref innerRef={preview}>
<List.Content>
<List.Description>
<span className="creatibutor">
{_get(initialCreatibutor, 'person_or_org.identifiers', []).some(
(identifier) => identifier.scheme === 'orcid'
) && (
<img
alt="ORCID logo"
className="inline-id-icon mr-5"
src="/static/images/orcid.svg"
width="16"
height="16"
/>
)}
{_get(initialCreatibutor, 'person_or_org.identifiers', []).some(
(identifier) => identifier.scheme === 'ror'
) && (
<img
alt="ROR logo"
className="inline-id-icon mr-5"
src="/static/images/ror-icon.svg"
width="16"
height="16"
/>
)}
{_get(initialCreatibutor, 'person_or_org.identifiers', []).some(
(identifier) => identifier.scheme === 'gnd'
) && (
<img
alt="GND logo"
className="inline-id-icon mr-5"
src="/static/images/gnd-icon.svg"
width="16"
height="16"
/>
)}
{displayName}{' '}
{renderRole(initialCreatibutor?.role, roleOptions)}
</span>
</List.Description>
{firstError && (
<Label pointing="left" prompt>
{firstError.scheme ? firstError.scheme : 'Invalid identifiers'}
</Label>
)}
</List.Content>
</Ref>
</List.Item>
</Ref>
);
}
Example #21
Source File: FieldDefCard.js From acsys with MIT License | 4 votes |
Card = memo(({ id, details, moveCard }) => {
const ref = useRef(null);
const [{ isDragging }, connectDrag] = useDrag({
item: { id, type: ItemTypes.CARD },
collect: (monitor) => {
const result = {
isDragging: monitor.isDragging(),
};
return result;
},
});
const [, connectDrop] = useDrop({
accept: ItemTypes.CARD,
hover({ id: draggedId }) {
if (draggedId !== id) {
moveCard(draggedId, id);
}
},
});
connectDrag(ref);
connectDrop(ref);
const opacity = isDragging ? 0 : 1;
const containerStyle = useMemo(() => ({ ...style, opacity }), [opacity]);
const data = [];
data.push(<option value="none">none</option>);
if (details.type === 'string') {
data.push(<option value="autoGen">autoGen</option>);
data.push(<option value="textEditor">textEditor</option>);
data.push(<option value="richTextEditor">richTextEditor</option>);
data.push(<option value="dateTimePicker">dateTimePicker</option>);
data.push(<option value="imageReference">imageReference</option>);
data.push(<option value="imageURL">imageURL</option>);
data.push(<option value="videoReference">videoReference</option>);
data.push(<option value="videoURL">videoURL</option>);
}
if (details.type === 'boolean') {
data.push(<option value="booleanSelect">boolean</option>);
}
if (details.type === 'number') {
data.push(<option value="numberEditor">numberEditor</option>);
data.push(<option value="booleanSelect">boolean</option>);
}
const width = [];
for (let i = 0; i < 12; i++) {
width.push(<option value={i + 1}>{i + 1}</option>);
}
const setControl = (event) => {
details.control = event;
};
const setKey = (event) => {
details.is_key = event;
};
const showOnTable = (event) => {
details.is_visible_on_table = event;
};
const showOnPage = (event) => {
details.is_visible_on_page = event;
};
const setWidth = (event) => {
details.width = parseInt(event);
};
return (
<Paper style={{ maxHeight: 160, marginBottom: 30 }}>
<AppBar
style={{ height: 30, borderBottom: '1px solid rgba(0, 0, 0, 0.12)' }}
position="static"
color="default"
elevation={0}
>
<Typography variant="subtitle1" align="center">
{details.field_name}
</Typography>
</AppBar>
<div ref={ref} style={containerStyle}>
<Grid container spacing={2}>
<Grid item xs={3}>
<div>
<Typography>Control</Typography>
</div>
</Grid>
<Grid item xs={2}>
<div>
<Typography>Key</Typography>
</div>
</Grid>
<Grid item xs={2}>
<div>
<Typography>Show on table</Typography>
</div>
</Grid>
<Grid item xs={2}>
<div>
<Typography>Show on page</Typography>
</div>
</Grid>
<Grid item xs={2}>
<div>
<Typography>Width on page</Typography>
</div>
</Grid>
<Grid item xs={3}>
<div>
<NativeSelect
defaultValue={details.control}
onChange={(e) => setControl(e.target.value)}
>
{data}
</NativeSelect>
</div>
</Grid>
<Grid item xs={2}>
<div>
<NativeSelect
defaultValue={Boolean(details.is_key)}
onChange={(e) => setKey(e.target.value == 'true')}
>
<option value={true}>True</option>
<option value={false}>False</option>
</NativeSelect>
</div>
</Grid>
<Grid item xs={2}>
<div>
<NativeSelect
defaultValue={Boolean(details.is_visible_on_table)}
onChange={(e) => showOnTable(e.target.value == 'true')}
>
<option value={true}>Show</option>
<option value={false}>Hide</option>
</NativeSelect>
</div>
</Grid>
<Grid item xs={2}>
<div>
<NativeSelect
defaultValue={Boolean(details.is_visible_on_page)}
onChange={(e) => showOnPage(e.target.value == 'true')}
>
<option value={true}>Show</option>
<option value={false}>Hide</option>
</NativeSelect>
</div>
</Grid>
<Grid item xs={2}>
<div>
<NativeSelect
defaultValue={details.width}
onChange={(e) => setWidth(e.target.value)}
>
{width}
</NativeSelect>
</div>
</Grid>
</Grid>
</div>
{moveCard}
</Paper>
);
})
Example #22
Source File: index.js From strapi-molecules with MIT License | 4 votes |
DraggedItem = ({
componentFieldName,
componentUid,
doesPreviousFieldContainErrorsAndIsOpen,
fields,
hasErrors,
hasMinError,
isFirst,
isReadOnly,
isOpen,
moveCollapse,
onClickToggle,
removeCollapse,
schema,
toggleCollapses,
dataForCurrentVersion,
isVersionCurrent,
// Retrieved from the select function
moveComponentField,
removeRepeatableField,
triggerFormValidation,
checkFormErrors,
displayedValue,
}) => {
const { setIsDraggingComponent, unsetIsDraggingComponent } = useEditView();
const dragRef = useRef(null);
const dropRef = useRef(null);
const [showForm, setShowForm] = useState(false);
useEffect(() => {
if (isOpen || !isVersionCurrent) {
setShowForm(true);
}
}, [isOpen]);
useEffect(() => {
if (!isVersionCurrent) {
setShowForm(true);
}
}, [isVersionCurrent]);
const [, drop] = useDrop({
accept: ItemTypes.COMPONENT,
canDrop() {
return false;
},
hover(item, monitor) {
if (!dropRef.current) {
return;
}
const dragPath = item.originalPath;
const hoverPath = componentFieldName;
const fullPathToComponentArray = dragPath.split(".");
const dragIndexString = fullPathToComponentArray
.slice()
.splice(-1)
.join("");
const hoverIndexString = hoverPath.split(".").splice(-1).join("");
const pathToComponentArray = fullPathToComponentArray.slice(
0,
fullPathToComponentArray.length - 1,
);
const dragIndex = parseInt(dragIndexString, 10);
const hoverIndex = parseInt(hoverIndexString, 10);
// Don't replace items with themselves
if (dragIndex === hoverIndex) {
return;
}
// Determine rectangle on screen
const hoverBoundingRect = dropRef.current.getBoundingClientRect();
// Get vertical middle
const hoverMiddleY =
(hoverBoundingRect.bottom - hoverBoundingRect.top) / 2;
// Determine mouse position
const clientOffset = monitor.getClientOffset();
// Get pixels to the top
const hoverClientY = clientOffset.y - hoverBoundingRect.top;
// Only perform the move when the mouse has crossed half of the items height
// When dragging downwards, only move when the cursor is below 50%
// When dragging upwards, only move when the cursor is above 50%
// Dragging downwards
if (dragIndex < hoverIndex && hoverClientY < hoverMiddleY) {
return;
}
// Dragging upwards
if (dragIndex > hoverIndex && hoverClientY > hoverMiddleY) {
return;
}
// Time to actually perform the action in the data
moveComponentField(pathToComponentArray, dragIndex, hoverIndex);
// Time to actually perform the action in the synchronized collapses
moveCollapse(dragIndex, hoverIndex);
// Note: we're mutating the monitor item here!
// Generally it's better to avoid mutations,
// but it's good here for the sake of performance
// to avoid expensive index searches.
item.originalPath = hoverPath;
},
});
const [{ isDragging }, drag, preview] = useDrag({
item: {
type: ItemTypes.COMPONENT,
displayedValue,
originalPath: componentFieldName,
},
begin: () => {
// Close all collapses
toggleCollapses(-1);
// Prevent the relations select from firing requests
setIsDraggingComponent();
},
end: () => {
// Enable the relations select to fire requests
unsetIsDraggingComponent();
// Update the errors
triggerFormValidation();
},
collect: (monitor) => ({
isDragging: monitor.isDragging(),
}),
});
useEffect(() => {
preview(getEmptyImage(), { captureDraggingState: false });
}, [preview]);
const getField = (fieldName) =>
get(schema, ["schema", "attributes", fieldName], {});
const getMeta = (fieldName) =>
get(schema, ["metadatas", fieldName, "edit"], {});
// Create the refs
// We need 1 for the drop target
// 1 for the drag target
const refs = {
dragRef: drag(dragRef),
dropRef: drop(dropRef),
};
return (
<>
<Banner
componentFieldName={componentFieldName}
hasErrors={hasErrors}
hasMinError={hasMinError}
isFirst={isFirst}
displayedValue={displayedValue}
doesPreviousFieldContainErrorsAndIsOpen={
doesPreviousFieldContainErrorsAndIsOpen
}
isDragging={isDragging}
isOpen={isVersionCurrent ? isOpen : true}
isReadOnly={isReadOnly}
onClickToggle={onClickToggle}
onClickRemove={() => {
removeRepeatableField(componentFieldName);
removeCollapse();
}}
ref={refs}
/>
<Collapse
isOpen={isVersionCurrent ? isOpen : true}
style={{ backgroundColor: "#FAFAFB" }}
onExited={() => setShowForm(false)}
>
{!isDragging && (
<FormWrapper
hasErrors={hasErrors}
isOpen={isVersionCurrent ? isOpen : true}
isReadOnly={isReadOnly}
>
{showForm &&
fields.map((fieldRow, key) => {
return (
<div className="row" key={key}>
{fieldRow.map((field) => {
const currentField = getField(field.name);
const isComponent =
get(currentField, "type", "") === "component";
const keys = `${componentFieldName}.${field.name}`;
if (isComponent) {
const componentUid = currentField.component;
const metas = getMeta(field.name);
return (
<FieldComponent
componentUid={componentUid}
isRepeatable={currentField.repeatable}
key={field.name}
label={metas.label}
isNested
name={keys}
max={currentField.max}
min={currentField.min}
/>
);
}
return (
<div key={field.name} className={`col-${field.size}`}>
<Inputs
autoFocus={false}
componentUid={componentUid}
keys={keys}
layout={schema}
name={field.name}
onBlur={hasErrors ? checkFormErrors : null}
dataForCurrentVersion={dataForCurrentVersion}
isVersionCurrent={isVersionCurrent}
/>
</div>
);
})}
</div>
);
})}
</FormWrapper>
)}
</Collapse>
</>
);
}
Example #23
Source File: create_dnd.jsx From taro-form with MIT License | 4 votes |
DragDrog = ({ children, moveForm, editForm, indexs, tpl, compName, form }) => {
const ref = useRef(null)
// 是否横向布局
const isRow = (() => {
if (!ref.current) {
return 'row'
}
const style = document.defaultView.getComputedStyle(ref.current.parentNode, null)
const direction = style.flexDirection
const display = style.display
if (display === 'block') {
return false
} else {
return direction === 'row'
}
})()
const [{ isDragging }, drag] = useDrag({
item: { type: EditTypes.FORM_MOVE, indexs, ref, tpl },
collect: monitor => ({
isDragging: monitor.isDragging()
}),
begin() {
editForm(-1)
}
})
const [{ over }, drop] = useDrop({
accept: [EditTypes.FORM_MOVE, EditTypes.FORM_ADD],
hover(item, monitor) {
if (item.type === EditTypes.FORM_ADD) {
return
}
if (!ref.current || !item.ref || !item.ref.current) {
return
}
if (!monitor.isOver({ shallow: true })) {
return
}
if (comp.isChildDisable(compName, item.tpl)) {
return
}
// 跳过相同的位置
if (item.indexs.join() === indexs.join()) {
return
}
// 禁止将父组件拖动到自己的子组件
if (item.indexs.length < indexs.length && item.indexs.join() === indexs.slice(0, item.indexs.length).join()) {
return
}
const dragRect = item.ref.current?.getBoundingClientRect()
const drarPos = monitor.getSourceClientOffset()
const dropRect = ref.current?.getBoundingClientRect()
const long = {
drag: dragRect[isRow ? 'width' : 'height'],
drop: dropRect[isRow ? 'width' : 'height']
}
// 拖动的块比 放开的块小 需要判断是否可以替换
if (long.drag < long.drop) {
const start = {
drag: drarPos[isRow ? 'x' : 'y'],
drop: dropRect[isRow ? 'left' : 'top']
}
const end = {
drag: start.drag + long.drag,
drop: start.drop + long.drop
}
const width = long.drop - long.drag
const startWidth = start.drag - start.drop
const endWidth = end.drop - end.drag
// 超过三倍 在中间区域
if (startWidth > width && endWidth > width) {
return
}
// 更接近开始位置 并且当前的块在开始位置 则跳过
if (startWidth < endWidth && item.indexs.length === indexs.length && item.indexs[item.indexs.length - 1] < indexs[indexs.length - 1]) {
return
}
// 更接近结束位置 并且当前的块在结束位置 则跳过
if (startWidth >= endWidth && item.indexs.length === indexs.length && item.indexs[item.indexs.length - 1] > indexs[indexs.length - 1]) {
return
}
}
moveForm(item.indexs, indexs, 'move')
// 更改索引
item.indexs = indexs
},
drop(item, monitor) {
if (item.type === EditTypes.FORM_MOVE) {
return
}
if (!monitor.isOver({ shallow: true })) {
return
}
// 禁止放进子组件
if (comp.isChildDisable(compName, item.tpl)) {
return
}
// 子组件数量判断
if (!comp.isChildAdd(compName, form.length)) {
return
}
moveForm(item.tpl, indexs)
},
collect(monitor) {
const item = monitor.getItem()
return {
over: item
&& item.type === EditTypes.FORM_ADD
&& monitor.isOver({ shallow: true })
&& !comp.isChildDisable(compName, item.tpl)
&& comp.isChildAdd(compName, form.length)
}
}
})
drag(drop(ref))
return <View
ref={ref}
className={`form-drag-drop${isDragging ? ' form-drag-drop--hover' : ''}${isRow ? ' form-drag-drop--row' : ''}`}
onClick={e => {
e.stopPropagation()
editForm()
}}
>
{over && <View className='form-drag-drop__add'>
<Text className='form-drag-drop__add__text'>放开添加</Text>
</View>}
{children}
</View>
}
Example #24
Source File: InventoryItem.js From CyberStateRP with MIT License | 4 votes |
InventoryItem = props => {
const [itemImage, setItemImage] = useState(null)
const ref = useRef(null)
const { inv } = useContext(InventoryContext)
const images = require.context('../../../assets/images/', true)
const [{ isDragging }, drag] = useDrag({
item: {
sqlId: props.sqlId,// eslint-disable-line
type: props.type,// eslint-disable-line
itemId: props.itemId,// eslint-disable-line
width: props.width,// eslint-disable-line
height: props.height,// eslint-disable-line
inVehicle: props.inVehicle,// eslint-disable-line
},
begin: monitor => {
inv.updateDraggedItem(
{
sqlId: props.sqlId,
itemId: props.itemId,
x: props.gridX,
y: props.gridY,
initGroup: props.parentId,
}
)
},
end: (item, monitor) => {
if (!monitor.didDrop()) {
inv.updateHoverIndexes({})
}
},
collect: monitor => ({
isDragging: monitor.isDragging(),
}),
})
const loadSVG = imageName => {
setItemImage(images(`./${imageName}.svg`))
}
const loadImage = imageName => {
switch (imageName) {
case 1:
loadSVG('glasses')
break
case 2:
loadSVG('tie')
break
case 3:
loadSVG('vest')
break
case 4:
loadSVG('tshirt')
break
case 5:
loadSVG('visa-card')
break
case 6:
loadSVG('cap')
break
case 7:
loadSVG('jacket')
break
case 8:
loadSVG('pants')
break
case 9:
loadSVG('shoes')
break
case 10:
loadSVG('chain')
break
case 11:
loadSVG('apple-watch')
break
case 12:
loadSVG('arm')
break
case 13:
loadSVG('backpack')
break
case 14:
loadSVG('mask')
break
case 15:
loadSVG('phone')
break
case 16:
loadSVG('passport')
break
case 54:
loadSVG('keycar')
break
case 59:
loadSVG('keyhome')
break
default:
setItemImage(images(`./items/${imageName}.png`))
}
}
const showModal = active => {
inv.showModal(active, props, ref.current.getBoundingClientRect())
}
const showMenu = active => {
inv.showItemMenu(active, props, ref.current.getBoundingClientRect())
}
const { gridX, gridY, width, height, layout, itemId, parentId, sqlId, inVehicle } = props
useEffect(() => {
loadImage(itemId)
}, [])
const { margin, itemSize } = layout
const realM = (itemId >= 1 && (itemId <= 16 || itemId === 54 || itemId === 59) && parentId === -1) ? 0 : margin
const { x, y } = calGridItemPosition((gridX < 0) ? 0 : gridX, (gridY < 0) ? 0 : gridY, realM, itemSize)
const { wPx, hPx } = calWHtoPx(width, height, realM, itemSize)
const realW = (itemId >= 1 && (itemId <= 16 || itemId === 54 || itemId === 59) && parentId === -1 && (inVehicle === false || !inVehicle)) ? '100%' : wPx
const realH = (itemId >= 1 && (itemId <= 16 || itemId === 54 || itemId === 59) && parentId === -1 && (inVehicle === false || !inVehicle)) ? '100%' : hPx
drag(ref)
// loadImage(itemId)
return (
<React.Fragment>
<div
ref={ref}
onMouseEnter={() => showModal(true)}
onMouseLeave={() => showModal(false)}
onContextMenu={() => showMenu(true)}
role="presentation"
key={sqlId}
className="card"
style={{
width: realW,
height: realH,
opacity: isDragging ? 0.4 : 1,
transform: `translate(${x}px, ${y}px)`,
}}
>
<div
className={`${itemId <= 16 || itemId === 54 || itemId === 59 ? 'svgImage' : 'pngImage'}`}
style={{
[(itemId > 16 && itemId !== 54 && itemId !== 59 ? 'backgroundImage' : 'WebkitMaskImage')]:
itemImage ? `url(${itemImage})` : '',
backgroundSize: 'contain',
backgroundRepeat: 'no-repeat',
backgroundPosition: 'center',
}}
/>
<InventoryMergeLayer
key={sqlId}
id={sqlId}
type="mergeLayer"
index={sqlId}
inVehicle={!!inVehicle}
/>
</div>
</React.Fragment>
)
}
Example #25
Source File: MovablePanel.jsx From ashteki with GNU Affero General Public License v3.0 | 4 votes |
MovablePanel = ({ children, name, onCloseClick, side, title }) => {
const key = `${name}-${side}`;
const savedStyle = localStorage.getItem(key);
const style = (savedStyle && JSON.parse(savedStyle)) || PopupDefaults[key];
if (style) {
if (style.left >= window.innerWidth) {
style.left = window.innerWidth - 50;
}
if (style.top >= window.innerHeight) {
style.top = window.innerHeight - 50;
}
}
const [position, setPosition] = useState(Object.assign({}, style));
const popupRef = useRef(null);
const getStyle = (offset) => {
const style = {
left: Math.max(offset.x, 10),
top: Math.max(offset.y, 50),
position: 'fixed'
};
const popup = $(popupRef.current);
style.top -= popup.height();
if (style.top < 50) {
style.top = 50;
}
if (style.left + popup.width() > window.innerWidth) {
style.left = window.innerWidth - popup.width();
}
if (style.top + 50 > window.innerHeight) {
style.top = window.innerHeight - 50;
}
return style;
};
const [{ isDragging, dragOffset }, drag] = useDrag({
item: { name: key, type: ItemTypes.PANEL },
collect: (monitor) => {
return {
isDragging: monitor.isDragging(),
dragOffset: monitor.getSourceClientOffset()
};
},
end: (_, monitor) => {
const offset = monitor.getSourceClientOffset();
const style = getStyle(offset);
localStorage.setItem(`${key}`, JSON.stringify(style));
}
});
useEffect(() => {
if (isDragging) {
let style = getStyle(dragOffset);
setPosition(style);
}
}, [dragOffset, isDragging]);
let content = (
<div ref={popupRef}>
<div ref={drag} className='panel panel-primary' style={position}>
<div className='panel-heading' onClick={(event) => event.stopPropagation()}>
<span className='text-center'>{title}</span>
<span className='float-right'>
<a className='close-button' onClick={onCloseClick}>
<FontAwesomeIcon icon={faTimes} />
</a>
</span>
</div>
{children}
</div>
</div>
);
return content;
}