cozy-ui 127.3.0 → 127.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/dist/cozy-ui.min.css +1 -1
- package/package.json +1 -1
- package/react/GridList/Virtualized/Dnd/GridItem.jsx +86 -0
- package/react/GridList/Virtualized/Dnd/index.jsx +67 -0
- package/react/GridList/Virtualized/index.jsx +2 -1
- package/react/Layout/Layout.jsx +9 -19
- package/react/Layout/Layout.md +73 -23
- package/react/Table/Virtualized/Dnd/index.jsx +1 -1
- package/react/Table/Virtualized/Dnd/virtuosoComponents.jsx +1 -1
- package/react/utils/Dnd/CustomDrag/CustomDragLayer.jsx +45 -0
- package/react/utils/Dnd/CustomDrag/DragPreview.jsx +43 -0
- package/react/utils/Dnd/CustomDrag/DragPreviewWrapper.jsx +52 -0
- package/react/utils/Dnd/DnDConfigWrapper.jsx +48 -0
- package/scripts/screenshots/screenshotComponent.js +4 -8
- package/stylus/elements/defaults.styl +1 -11
- package/stylus/objects/layouts.styl +13 -47
- package/transpiled/react/GridList/Virtualized/Dnd/GridItem.d.ts +7 -0
- package/transpiled/react/GridList/Virtualized/Dnd/GridItem.js +139 -0
- package/transpiled/react/GridList/Virtualized/Dnd/index.d.ts +13 -0
- package/transpiled/react/GridList/Virtualized/Dnd/index.js +81 -0
- package/transpiled/react/GridList/Virtualized/index.js +3 -1
- package/transpiled/react/Layout/Layout.js +9 -9
- package/transpiled/react/Table/Virtualized/Dnd/index.js +1 -1
- package/transpiled/react/Table/Virtualized/Dnd/virtuosoComponents.js +1 -1
- package/transpiled/react/stylesheet.css +1 -1
- package/transpiled/react/utils/Dnd/CustomDrag/CustomDragLayer.d.ts +4 -0
- package/transpiled/react/utils/Dnd/CustomDrag/CustomDragLayer.js +47 -0
- package/transpiled/react/utils/Dnd/CustomDrag/DragPreview.d.ts +6 -0
- package/transpiled/react/utils/Dnd/CustomDrag/DragPreview.js +34 -0
- package/transpiled/react/utils/Dnd/CustomDrag/DragPreviewWrapper.d.ts +8 -0
- package/transpiled/react/utils/Dnd/CustomDrag/DragPreviewWrapper.js +63 -0
- package/transpiled/react/utils/Dnd/DnDConfigWrapper.d.ts +2 -0
- package/transpiled/react/utils/Dnd/DnDConfigWrapper.js +55 -0
package/package.json
CHANGED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import cx from 'classnames'
|
|
2
|
+
import React, { useEffect } from 'react'
|
|
3
|
+
import { useDrag, useDrop } from 'react-dnd'
|
|
4
|
+
import { getEmptyImage } from 'react-dnd-html5-backend'
|
|
5
|
+
|
|
6
|
+
const GridItem = ({ item, context, renderItem, className }) => {
|
|
7
|
+
const {
|
|
8
|
+
selectedItems = [],
|
|
9
|
+
itemsInDropProcess = [],
|
|
10
|
+
setItemsInDropProcess = () => {},
|
|
11
|
+
dragProps
|
|
12
|
+
} = context || {}
|
|
13
|
+
|
|
14
|
+
const {
|
|
15
|
+
onDrop,
|
|
16
|
+
canDrop: canDropProps,
|
|
17
|
+
canDrag: canDragProps,
|
|
18
|
+
dragId
|
|
19
|
+
} = dragProps
|
|
20
|
+
|
|
21
|
+
const isSelected = context?.isSelectedItem?.(item)
|
|
22
|
+
const isDisabled = itemsInDropProcess.includes(item._id)
|
|
23
|
+
|
|
24
|
+
const [{ isDragging }, dragRef, dragPreview] = useDrag(
|
|
25
|
+
() => ({
|
|
26
|
+
type: dragId,
|
|
27
|
+
isDragging: monitor => {
|
|
28
|
+
if (selectedItems.length > 0) {
|
|
29
|
+
return selectedItems.some(sel => sel._id === item._id)
|
|
30
|
+
}
|
|
31
|
+
return item._id === monitor.getItem().draggedItems?.[0]._id
|
|
32
|
+
},
|
|
33
|
+
item: {
|
|
34
|
+
draggedItems: selectedItems.length > 0 ? selectedItems : [item]
|
|
35
|
+
},
|
|
36
|
+
canDrag: () => {
|
|
37
|
+
const defaultCanDrag = canDragProps?.(item) ?? true
|
|
38
|
+
if (selectedItems.length > 0) {
|
|
39
|
+
return defaultCanDrag && isSelected
|
|
40
|
+
}
|
|
41
|
+
return defaultCanDrag
|
|
42
|
+
},
|
|
43
|
+
collect: monitor => ({
|
|
44
|
+
isDragging: monitor.isDragging()
|
|
45
|
+
})
|
|
46
|
+
}),
|
|
47
|
+
[item, selectedItems]
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
const [{ isOver }, dropRef] = useDrop(
|
|
51
|
+
() => ({
|
|
52
|
+
accept: dragId,
|
|
53
|
+
canDrop: () => (canDropProps ? canDropProps(item) : true),
|
|
54
|
+
drop: async draggedItem => {
|
|
55
|
+
setItemsInDropProcess(
|
|
56
|
+
draggedItem.draggedItems.map(dragged => dragged._id)
|
|
57
|
+
)
|
|
58
|
+
await onDrop(draggedItem.draggedItems, item, selectedItems)
|
|
59
|
+
setItemsInDropProcess([])
|
|
60
|
+
},
|
|
61
|
+
collect: monitor => ({
|
|
62
|
+
isOver: monitor.isOver()
|
|
63
|
+
})
|
|
64
|
+
}),
|
|
65
|
+
[item._id, selectedItems]
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
useEffect(() => {
|
|
69
|
+
dragPreview(getEmptyImage(), { captureDraggingState: true })
|
|
70
|
+
}, [dragPreview])
|
|
71
|
+
|
|
72
|
+
return (
|
|
73
|
+
<div
|
|
74
|
+
ref={node => dragRef(dropRef(node))}
|
|
75
|
+
className={cx(
|
|
76
|
+
className,
|
|
77
|
+
isDragging ? 'virtualized u-o-50' : 'virtualized'
|
|
78
|
+
)}
|
|
79
|
+
style={{ opacity: isDisabled ? 0.5 : 1 }}
|
|
80
|
+
>
|
|
81
|
+
{renderItem(item, { isDragging, isOver, isDisabled })}
|
|
82
|
+
</div>
|
|
83
|
+
)
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export default GridItem
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import React, { forwardRef, useState, useMemo } from 'react'
|
|
2
|
+
|
|
3
|
+
import GridItem from './GridItem'
|
|
4
|
+
import VirtualizedGridList from '../'
|
|
5
|
+
import CustomDragLayer from '../../../utils/Dnd/CustomDrag/CustomDragLayer'
|
|
6
|
+
import DnDConfigWrapper from '../../../utils/Dnd/DnDConfigWrapper'
|
|
7
|
+
|
|
8
|
+
const VirtualizedGridListDnd = ({
|
|
9
|
+
dragProps,
|
|
10
|
+
context,
|
|
11
|
+
itemRenderer,
|
|
12
|
+
children,
|
|
13
|
+
componentProps = {
|
|
14
|
+
List: {},
|
|
15
|
+
Item: {}
|
|
16
|
+
},
|
|
17
|
+
components,
|
|
18
|
+
...props
|
|
19
|
+
}) => {
|
|
20
|
+
const [itemsInDropProcess, setItemsInDropProcess] = useState([])
|
|
21
|
+
|
|
22
|
+
const _context = useMemo(
|
|
23
|
+
() => ({
|
|
24
|
+
...context,
|
|
25
|
+
dragProps,
|
|
26
|
+
itemRenderer,
|
|
27
|
+
itemsInDropProcess,
|
|
28
|
+
setItemsInDropProcess,
|
|
29
|
+
items: props.items
|
|
30
|
+
}),
|
|
31
|
+
[context, dragProps, itemRenderer, itemsInDropProcess, props.items]
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
return (
|
|
35
|
+
<>
|
|
36
|
+
<CustomDragLayer dragId={dragProps.dragId} />
|
|
37
|
+
<VirtualizedGridList
|
|
38
|
+
components={{
|
|
39
|
+
Scroller: forwardRef(({ ...scrollerProps }, ref) => (
|
|
40
|
+
<DnDConfigWrapper ref={ref}>
|
|
41
|
+
<div {...scrollerProps} ref={ref} />
|
|
42
|
+
</DnDConfigWrapper>
|
|
43
|
+
)),
|
|
44
|
+
Item: ({ context, children, ...props }) => {
|
|
45
|
+
const item = context?.items?.[props['data-index']]
|
|
46
|
+
return (
|
|
47
|
+
<GridItem
|
|
48
|
+
item={item}
|
|
49
|
+
context={context}
|
|
50
|
+
renderItem={() => <>{children}</>}
|
|
51
|
+
{...componentProps.Item}
|
|
52
|
+
/>
|
|
53
|
+
)
|
|
54
|
+
},
|
|
55
|
+
...components
|
|
56
|
+
}}
|
|
57
|
+
context={_context}
|
|
58
|
+
itemRenderer={itemRenderer}
|
|
59
|
+
{...props}
|
|
60
|
+
>
|
|
61
|
+
{children}
|
|
62
|
+
</VirtualizedGridList>
|
|
63
|
+
</>
|
|
64
|
+
)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export default VirtualizedGridListDnd
|
|
@@ -2,11 +2,12 @@ import React, { forwardRef } from 'react'
|
|
|
2
2
|
import { VirtuosoGrid } from 'react-virtuoso'
|
|
3
3
|
|
|
4
4
|
const VirtualizedGridList = forwardRef(
|
|
5
|
-
({ items = [], itemRenderer, components, ...props }, ref) => {
|
|
5
|
+
({ items = [], itemRenderer, components, context, ...props }, ref) => {
|
|
6
6
|
return (
|
|
7
7
|
<VirtuosoGrid
|
|
8
8
|
ref={ref}
|
|
9
9
|
components={components}
|
|
10
|
+
context={context}
|
|
10
11
|
style={{ height: '100%' }}
|
|
11
12
|
totalCount={items.length}
|
|
12
13
|
itemContent={index => itemRenderer(items[index])}
|
package/react/Layout/Layout.jsx
CHANGED
|
@@ -3,6 +3,7 @@ import PropTypes from 'prop-types'
|
|
|
3
3
|
import React, { createContext, forwardRef, useContext, useMemo } from 'react'
|
|
4
4
|
|
|
5
5
|
import styles from './styles.styl'
|
|
6
|
+
import { useBreakpoints } from '../providers/Breakpoints'
|
|
6
7
|
|
|
7
8
|
export const LayoutContext = createContext()
|
|
8
9
|
|
|
@@ -33,20 +34,13 @@ LayoutProvider.displayName = 'LayoutProvider'
|
|
|
33
34
|
|
|
34
35
|
export const Layout = forwardRef(
|
|
35
36
|
({ children, className, monoColumn, withTopBar, ...props }, ref) => {
|
|
36
|
-
const variant = monoColumn ? 'monocolumn' : '2panes'
|
|
37
|
-
|
|
38
37
|
return (
|
|
39
38
|
<LayoutProvider monoColumn={monoColumn} withTopBar={withTopBar}>
|
|
40
39
|
<div
|
|
41
40
|
ref={ref}
|
|
42
|
-
className={cx(
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
styles[`o-layout-${variant}`],
|
|
46
|
-
{
|
|
47
|
-
[styles[`o-layout-topbar`]]: withTopBar
|
|
48
|
-
}
|
|
49
|
-
)}
|
|
41
|
+
className={cx(className, styles['o-layout'], {
|
|
42
|
+
[styles['o-layout-main-2panes']]: !monoColumn
|
|
43
|
+
})}
|
|
50
44
|
{...props}
|
|
51
45
|
>
|
|
52
46
|
{children}
|
|
@@ -59,20 +53,16 @@ export const Layout = forwardRef(
|
|
|
59
53
|
Layout.displayName = 'Layout'
|
|
60
54
|
|
|
61
55
|
export const Main = forwardRef(({ className, children, ...props }, ref) => {
|
|
56
|
+
const { isDesktop } = useBreakpoints()
|
|
62
57
|
const { monoColumn, withTopBar } = useLayout()
|
|
63
|
-
const variant = monoColumn ? 'monocolumn' : '2panes'
|
|
64
58
|
|
|
65
59
|
return (
|
|
66
60
|
<main
|
|
67
61
|
ref={ref}
|
|
68
|
-
className={cx(
|
|
69
|
-
|
|
70
|
-
styles[
|
|
71
|
-
|
|
72
|
-
{
|
|
73
|
-
[styles[`o-layout-main-${variant}--topbar`]]: withTopBar
|
|
74
|
-
}
|
|
75
|
-
)}
|
|
62
|
+
className={cx(className, styles['o-layout-main'], {
|
|
63
|
+
[styles['o-layout-main-2panes']]: !monoColumn,
|
|
64
|
+
[styles[`o-layout-main-topbar`]]: withTopBar && !isDesktop
|
|
65
|
+
})}
|
|
76
66
|
{...props}
|
|
77
67
|
>
|
|
78
68
|
{children}
|
package/react/Layout/Layout.md
CHANGED
|
@@ -29,8 +29,13 @@ import Sidebar from 'cozy-ui/transpiled/react/Sidebar'
|
|
|
29
29
|
import Nav, { NavItem, NavIcon, NavText, genNavLink, NavDesktopLimiter } from 'cozy-ui/transpiled/react/Nav'
|
|
30
30
|
import cx from 'classnames'
|
|
31
31
|
import isEqual from 'lodash/isEqual'
|
|
32
|
+
import Icon from 'cozy-ui/transpiled/react/Icon'
|
|
33
|
+
import IconButton from 'cozy-ui/transpiled/react/IconButton'
|
|
32
34
|
import WarnIcon from 'cozy-ui/transpiled/react/Icons/Warn'
|
|
33
35
|
import CheckIcon from 'cozy-ui/transpiled/react/Icons/Check'
|
|
36
|
+
import CrossMediumIcon from 'cozy-ui/transpiled/react/Icons/CrossMedium'
|
|
37
|
+
import Button from 'cozy-ui/transpiled/react/Buttons'
|
|
38
|
+
import Dialog from 'cozy-ui/transpiled/react/Dialog'
|
|
34
39
|
import DownloadIcon from 'cozy-ui/transpiled/react/Icons/Download'
|
|
35
40
|
import DemoProvider from 'cozy-ui/docs/components/DemoProvider'
|
|
36
41
|
import { makeStyles } from 'cozy-ui/transpiled/react/styles'
|
|
@@ -51,18 +56,36 @@ const ExampleRouterNavLink = ({ children, className, active, activeClassName, on
|
|
|
51
56
|
const NavLink = genNavLink(ExampleRouterNavLink)
|
|
52
57
|
|
|
53
58
|
// Not necessary in a normal app
|
|
54
|
-
const useStyles = makeStyles({
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
'
|
|
59
|
-
|
|
59
|
+
const useStyles = makeStyles(theme => ({
|
|
60
|
+
topBar: { // same style than the cozy-bar
|
|
61
|
+
display: 'flex',
|
|
62
|
+
alignItems: 'center',
|
|
63
|
+
padding: '0 1rem',
|
|
64
|
+
minHeight: '3rem',
|
|
65
|
+
width: '100%',
|
|
66
|
+
boxSizing: 'border-box',
|
|
67
|
+
zIndex: 'var(--zIndex-bar)',
|
|
68
|
+
backgroundColor: theme.palette.background.default,
|
|
69
|
+
borderBottom: `1px solid ${theme.palette.divider}`,
|
|
70
|
+
position: 'fixed',
|
|
71
|
+
top: 0,
|
|
72
|
+
right: 0,
|
|
73
|
+
[theme.breakpoints.up('lg')]: {
|
|
74
|
+
position: 'relative',
|
|
60
75
|
}
|
|
76
|
+
},
|
|
77
|
+
closeButton: {
|
|
78
|
+
position: 'absolute',
|
|
79
|
+
top: '1.15rem',
|
|
80
|
+
right: '1.15rem',
|
|
81
|
+
zIndex: 'var(--zIndex-modal-toolbar)',
|
|
82
|
+
backgroundColor: theme.palette.background.paper
|
|
61
83
|
}
|
|
62
|
-
})
|
|
84
|
+
}))
|
|
63
85
|
|
|
64
|
-
const initialVariants = [{ monoColumn: false, withTopBar: true }]
|
|
86
|
+
const initialVariants = [{ monoColumn: false, withTopBar: true, longContent: true }]
|
|
65
87
|
const [active, setActive] = useState(['Section 1', 'Subsection 1'])
|
|
88
|
+
const [showDialog, setShowDialog] = useState(isTesting() ? true : false)
|
|
66
89
|
const styles = useStyles()
|
|
67
90
|
|
|
68
91
|
;
|
|
@@ -112,23 +135,50 @@ const SideBar = ({ variant }) => {
|
|
|
112
135
|
)
|
|
113
136
|
}
|
|
114
137
|
|
|
115
|
-
<Variants initialVariants={initialVariants}
|
|
138
|
+
<Variants initialVariants={initialVariants}>
|
|
116
139
|
{variant => (
|
|
117
140
|
<DemoProvider>
|
|
118
|
-
<
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
<
|
|
127
|
-
|
|
128
|
-
{
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
141
|
+
<Button className="u-mb-1" label="Open layout in modal" onClick={() => setShowDialog(true)} />
|
|
142
|
+
{showDialog && (
|
|
143
|
+
<Dialog
|
|
144
|
+
className="cozy-ui-body"
|
|
145
|
+
open
|
|
146
|
+
fullScreen
|
|
147
|
+
fullWidth
|
|
148
|
+
>
|
|
149
|
+
<IconButton
|
|
150
|
+
className={styles.closeButton}
|
|
151
|
+
onClick={() => setShowDialog(false)}
|
|
152
|
+
>
|
|
153
|
+
<Icon icon={CrossMediumIcon} />
|
|
154
|
+
</IconButton>
|
|
155
|
+
{variant.withTopBar &&
|
|
156
|
+
<div
|
|
157
|
+
id="coz-bar"
|
|
158
|
+
role="banner"
|
|
159
|
+
className={styles.topBar}
|
|
160
|
+
>
|
|
161
|
+
Fake TopBar
|
|
162
|
+
</div>
|
|
163
|
+
}
|
|
164
|
+
<div role="application">
|
|
165
|
+
<Layout
|
|
166
|
+
withTopBar={variant.withTopBar}
|
|
167
|
+
monoColumn={variant.monoColumn}
|
|
168
|
+
>
|
|
169
|
+
{!variant.monoColumn && <SideBar variant={variant} />}
|
|
170
|
+
<Main>
|
|
171
|
+
<Content className='u-p-1'>
|
|
172
|
+
<h2 className='u-mt-0'>{ active.join(' / ') }</h2>
|
|
173
|
+
<p>---Start---</p>
|
|
174
|
+
{variant.longContent ? content.ada.long : content.ada.short}
|
|
175
|
+
<p>---END---</p>
|
|
176
|
+
</Content>
|
|
177
|
+
</Main>
|
|
178
|
+
</Layout>
|
|
179
|
+
</div>
|
|
180
|
+
</Dialog>
|
|
181
|
+
)}
|
|
132
182
|
</DemoProvider>
|
|
133
183
|
)}
|
|
134
184
|
</Variants>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, { useState, useMemo } from 'react'
|
|
2
2
|
|
|
3
|
-
import CustomDragLayer from './CustomDrag/CustomDragLayer'
|
|
4
3
|
import virtuosoComponentsDnd from './virtuosoComponents'
|
|
4
|
+
import CustomDragLayer from '../../../utils/Dnd/CustomDrag/CustomDragLayer'
|
|
5
5
|
import VirtualizedTable from '../index'
|
|
6
6
|
import virtuosoComponents from '../virtuosoComponents'
|
|
7
7
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import React, { forwardRef } from 'react'
|
|
2
2
|
|
|
3
|
-
import DnDConfigWrapper from './DnDConfigWrapper'
|
|
4
3
|
import TableRowDnD from './TableRow'
|
|
5
4
|
import TableContainer from '../../../TableContainer'
|
|
5
|
+
import DnDConfigWrapper from '../../../utils/Dnd/DnDConfigWrapper'
|
|
6
6
|
import virtuosoComponents from '../virtuosoComponents'
|
|
7
7
|
|
|
8
8
|
/**
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { useDragLayer } from 'react-dnd'
|
|
3
|
+
|
|
4
|
+
import DragPreviewWrapper from './DragPreviewWrapper'
|
|
5
|
+
|
|
6
|
+
const layerStyles = {
|
|
7
|
+
position: 'fixed',
|
|
8
|
+
pointerEvents: 'none',
|
|
9
|
+
zIndex: 100,
|
|
10
|
+
left: 0,
|
|
11
|
+
top: 0,
|
|
12
|
+
width: '100%',
|
|
13
|
+
height: '100%'
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// Example find in the official documentation
|
|
17
|
+
// https://react-dnd.github.io/react-dnd/examples/drag-around/custom-drag-layer
|
|
18
|
+
export const CustomDragLayer = ({ dragId }) => {
|
|
19
|
+
const { itemType, isDragging, item, initialOffset, currentOffset } =
|
|
20
|
+
useDragLayer(monitor => ({
|
|
21
|
+
item: monitor.getItem(),
|
|
22
|
+
itemType: monitor.getItemType(),
|
|
23
|
+
initialOffset: monitor.getInitialSourceClientOffset(),
|
|
24
|
+
currentOffset: monitor.getSourceClientOffset(),
|
|
25
|
+
isDragging: monitor.isDragging()
|
|
26
|
+
}))
|
|
27
|
+
|
|
28
|
+
if (!isDragging) {
|
|
29
|
+
return null
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return (
|
|
33
|
+
<div style={layerStyles}>
|
|
34
|
+
<DragPreviewWrapper
|
|
35
|
+
item={item}
|
|
36
|
+
itemType={itemType}
|
|
37
|
+
dragId={dragId}
|
|
38
|
+
initialOffset={initialOffset}
|
|
39
|
+
currentOffset={currentOffset}
|
|
40
|
+
/>
|
|
41
|
+
</div>
|
|
42
|
+
)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export default CustomDragLayer
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
|
|
3
|
+
import Badge from '../../../Badge'
|
|
4
|
+
import Paper from '../../../Paper'
|
|
5
|
+
import Typography from '../../../Typography'
|
|
6
|
+
import { makeStyles } from '../../../styles'
|
|
7
|
+
|
|
8
|
+
const useStyles = makeStyles({
|
|
9
|
+
root: {
|
|
10
|
+
width: 'fit-content'
|
|
11
|
+
}
|
|
12
|
+
})
|
|
13
|
+
|
|
14
|
+
const DragPreview = ({ fileName, selectedCount }) => {
|
|
15
|
+
const classes = useStyles()
|
|
16
|
+
|
|
17
|
+
return (
|
|
18
|
+
<>
|
|
19
|
+
{selectedCount > 1 ? (
|
|
20
|
+
<Badge
|
|
21
|
+
badgeContent={selectedCount}
|
|
22
|
+
size="large"
|
|
23
|
+
color="primary"
|
|
24
|
+
anchorOrigin={{
|
|
25
|
+
vertical: 'top',
|
|
26
|
+
horizontal: 'right'
|
|
27
|
+
}}
|
|
28
|
+
overlap="rectangular"
|
|
29
|
+
>
|
|
30
|
+
<Paper classes={classes} className="u-p-half u-maw-5">
|
|
31
|
+
<Typography>{fileName}</Typography>
|
|
32
|
+
</Paper>
|
|
33
|
+
</Badge>
|
|
34
|
+
) : (
|
|
35
|
+
<Paper classes={classes} className="u-p-half u-maw-5">
|
|
36
|
+
<Typography>{fileName}</Typography>
|
|
37
|
+
</Paper>
|
|
38
|
+
)}
|
|
39
|
+
</>
|
|
40
|
+
)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export default React.memo(DragPreview)
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import React, { useEffect, useState } from 'react'
|
|
2
|
+
|
|
3
|
+
import DragPreview from './DragPreview'
|
|
4
|
+
|
|
5
|
+
const makeStyles = ({ x, y }) => {
|
|
6
|
+
if (!x || !y) {
|
|
7
|
+
return { display: 'none' }
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const transform = `translate(${x}px, ${y}px)`
|
|
11
|
+
|
|
12
|
+
return {
|
|
13
|
+
transform,
|
|
14
|
+
WebkitTransform: transform
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const DragPreviewWrapper = ({
|
|
19
|
+
item,
|
|
20
|
+
itemType,
|
|
21
|
+
dragId,
|
|
22
|
+
initialOffset,
|
|
23
|
+
currentOffset
|
|
24
|
+
}) => {
|
|
25
|
+
const [mousePosition, setMousePosition] = useState({ x: null, y: null })
|
|
26
|
+
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
const handleMouseMove = e => {
|
|
29
|
+
setMousePosition({ x: e.clientX, y: e.clientY })
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
window.addEventListener('dragover', handleMouseMove)
|
|
33
|
+
return () => {
|
|
34
|
+
window.removeEventListener('dragover', handleMouseMove)
|
|
35
|
+
}
|
|
36
|
+
}, [])
|
|
37
|
+
|
|
38
|
+
if (!initialOffset || !currentOffset || itemType !== dragId) {
|
|
39
|
+
return null
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return (
|
|
43
|
+
<div style={makeStyles(mousePosition)}>
|
|
44
|
+
<DragPreview
|
|
45
|
+
fileName={item.draggedItems[0].name}
|
|
46
|
+
selectedCount={item.draggedItems.length}
|
|
47
|
+
/>
|
|
48
|
+
</div>
|
|
49
|
+
)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export default DragPreviewWrapper
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { forwardRef, useEffect, useState } from 'react'
|
|
2
|
+
import { useDragDropManager } from 'react-dnd'
|
|
3
|
+
|
|
4
|
+
const DnDConfigWrapper = forwardRef(({ children }, ref) => {
|
|
5
|
+
const dragDropManager = useDragDropManager()
|
|
6
|
+
const monitor = dragDropManager.getMonitor()
|
|
7
|
+
const [isDragging, setIsDragging] = useState(false)
|
|
8
|
+
|
|
9
|
+
useEffect(() => {
|
|
10
|
+
const unsubscribe = monitor.subscribeToStateChange(() => {
|
|
11
|
+
setIsDragging(monitor.isDragging())
|
|
12
|
+
})
|
|
13
|
+
return () => unsubscribe()
|
|
14
|
+
}, [monitor])
|
|
15
|
+
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
if (!isDragging) return
|
|
18
|
+
|
|
19
|
+
const scrollThreshold = 100
|
|
20
|
+
const scrollMaxSpeed = 75
|
|
21
|
+
|
|
22
|
+
const intervalId = setInterval(() => {
|
|
23
|
+
const offset = monitor.getClientOffset()
|
|
24
|
+
const container = ref.current
|
|
25
|
+
if (!offset || !container) return
|
|
26
|
+
|
|
27
|
+
const { top, bottom } = container.getBoundingClientRect()
|
|
28
|
+
const distanceToTop = offset.y - top
|
|
29
|
+
const distanceToBottom = bottom - offset.y
|
|
30
|
+
|
|
31
|
+
if (distanceToTop < scrollThreshold) {
|
|
32
|
+
const speed = scrollMaxSpeed * (1 - distanceToTop / scrollThreshold)
|
|
33
|
+
container.scrollBy(0, -speed)
|
|
34
|
+
} else if (distanceToBottom < scrollThreshold) {
|
|
35
|
+
const speed = scrollMaxSpeed * (1 - distanceToBottom / scrollThreshold)
|
|
36
|
+
container.scrollBy(0, speed)
|
|
37
|
+
}
|
|
38
|
+
}, 16) // ~60fps
|
|
39
|
+
|
|
40
|
+
return () => clearInterval(intervalId)
|
|
41
|
+
}, [isDragging, monitor, ref])
|
|
42
|
+
|
|
43
|
+
return children
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
DnDConfigWrapper.displayName = 'DnDConfigWrapper'
|
|
47
|
+
|
|
48
|
+
export default DnDConfigWrapper
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const path = require('path')
|
|
2
|
+
|
|
2
3
|
const { sleep } = require('./helpers')
|
|
3
4
|
|
|
4
5
|
const rootDirectory = path.join(__dirname, '../')
|
|
@@ -22,17 +23,12 @@ const getDefaultScreenshotName = ({
|
|
|
22
23
|
* component.
|
|
23
24
|
*/
|
|
24
25
|
const screenshotComponent = async (page, options) => {
|
|
25
|
-
const {
|
|
26
|
-
|
|
27
|
-
screenshotDir,
|
|
28
|
-
viewport,
|
|
29
|
-
type,
|
|
30
|
-
variant,
|
|
31
|
-
componentConfig
|
|
32
|
-
} = options
|
|
26
|
+
const { component, screenshotDir, viewport, type, variant, componentConfig } =
|
|
27
|
+
options
|
|
33
28
|
const { link, name } = component
|
|
34
29
|
|
|
35
30
|
await page.goto(link)
|
|
31
|
+
await page.addStyleTag({ content: 'body {height: auto;}' }) // to resize viewport according to its content
|
|
36
32
|
await sleep(200) // to be sure the page is entirely loaded
|
|
37
33
|
|
|
38
34
|
const getScreenshotName =
|
|
@@ -35,21 +35,11 @@ body
|
|
|
35
35
|
textarea
|
|
36
36
|
@extend $font-labor
|
|
37
37
|
|
|
38
|
-
html
|
|
39
|
-
body
|
|
40
|
-
+medium-screen()
|
|
41
|
-
display block
|
|
42
|
-
height auto
|
|
43
|
-
|
|
44
38
|
[role=application]
|
|
45
39
|
display flex
|
|
46
40
|
height inherit
|
|
47
41
|
flex 1 1 100%
|
|
48
|
-
overflow
|
|
49
|
-
overflow-y auto
|
|
50
|
-
|
|
51
|
-
+medium-screen()
|
|
52
|
-
overflow visible
|
|
42
|
+
overflow hidden auto
|
|
53
43
|
|
|
54
44
|
// FORMS
|
|
55
45
|
@require '../components/forms'
|