mirror of
https://github.com/PostHog/posthog.git
synced 2024-11-21 21:49:51 +01:00
chore: migrate to dnd kit (#16962)
chore: migrate selectable person properties to dnd-sortable
This commit is contained in:
parent
23c3b525b0
commit
d2f4217a2b
Binary file not shown.
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 7.5 KiB |
@ -1,13 +1,17 @@
|
||||
import { TaxonomicFilterGroupType } from 'lib/components/TaxonomicFilter/types'
|
||||
import { TaxonomicFilter } from 'lib/components/TaxonomicFilter/TaxonomicFilter'
|
||||
import { Popover } from 'lib/lemon-ui/Popover/Popover'
|
||||
import { SortableContainer, SortableElement } from 'react-sortable-hoc'
|
||||
import { LemonButton } from '@posthog/lemon-ui'
|
||||
import { IconPlus } from 'lib/lemon-ui/icons'
|
||||
import { LemonSnack } from 'lib/lemon-ui/LemonSnack/LemonSnack'
|
||||
import clsx from 'clsx'
|
||||
import { useState } from 'react'
|
||||
|
||||
import { DndContext, closestCenter } from '@dnd-kit/core'
|
||||
import { useSortable, SortableContext, horizontalListSortingStrategy } from '@dnd-kit/sortable'
|
||||
import { CSS } from '@dnd-kit/utilities'
|
||||
import { restrictToHorizontalAxis } from '@dnd-kit/modifiers'
|
||||
|
||||
export interface PersonPropertySelectProps {
|
||||
addText: string
|
||||
onChange: (names: string[]) => void
|
||||
@ -15,25 +19,32 @@ export interface PersonPropertySelectProps {
|
||||
sortable?: boolean
|
||||
}
|
||||
|
||||
const PropertyTag = ({
|
||||
const SortableProperty = ({
|
||||
name,
|
||||
onRemove,
|
||||
sortable = false,
|
||||
sortable,
|
||||
}: {
|
||||
name: string
|
||||
onRemove: (val: string) => void
|
||||
sortable?: boolean
|
||||
}): JSX.Element => (
|
||||
<span className={clsx(sortable ? 'cursor-move' : 'cursor-auto')}>
|
||||
<LemonSnack onClose={() => onRemove(name)}>{name}</LemonSnack>
|
||||
</span>
|
||||
)
|
||||
}): JSX.Element => {
|
||||
const { setNodeRef, attributes, transform, transition, listeners } = useSortable({ id: name })
|
||||
|
||||
const SortableProperty = SortableElement(PropertyTag)
|
||||
|
||||
const SortablePropertyList = SortableContainer(({ children }: { children: React.ReactNode }) => {
|
||||
return <span className="flex items-center gap-2">{children}</span>
|
||||
})
|
||||
return (
|
||||
<span
|
||||
ref={setNodeRef}
|
||||
className={clsx(sortable ? 'cursor-move' : 'cursor-auto')}
|
||||
{...attributes}
|
||||
{...listeners}
|
||||
style={{
|
||||
transform: CSS.Translate.toString(transform),
|
||||
transition,
|
||||
}}
|
||||
>
|
||||
<LemonSnack onClose={() => onRemove(name)}>{name}</LemonSnack>
|
||||
</span>
|
||||
)
|
||||
}
|
||||
|
||||
export const PersonPropertySelect = ({
|
||||
onChange,
|
||||
@ -60,23 +71,36 @@ export const PersonPropertySelect = ({
|
||||
|
||||
return (
|
||||
<div className="flex items-center flex-wrap gap-2">
|
||||
{sortable ? (
|
||||
<SortablePropertyList onSortEnd={handleSort} axis="x" lockAxis="x" lockToContainerEdges distance={5}>
|
||||
{selectedProperties.map((value, index) => (
|
||||
<SortableProperty
|
||||
key={`item-${value}`}
|
||||
index={index}
|
||||
name={value}
|
||||
onRemove={handleRemove}
|
||||
sortable
|
||||
/>
|
||||
))}
|
||||
</SortablePropertyList>
|
||||
) : (
|
||||
selectedProperties?.map((value) => (
|
||||
<PropertyTag key={`item-${value}`} name={value} onRemove={handleRemove} />
|
||||
))
|
||||
)}
|
||||
<DndContext
|
||||
onDragEnd={({ active, over }) => {
|
||||
if (over && active.id !== over.id) {
|
||||
handleSort({
|
||||
oldIndex: selectedProperties.indexOf(active.id.toString()),
|
||||
newIndex: selectedProperties.indexOf(over.id.toString()),
|
||||
})
|
||||
}
|
||||
}}
|
||||
collisionDetection={closestCenter}
|
||||
modifiers={[restrictToHorizontalAxis]}
|
||||
>
|
||||
<SortableContext
|
||||
disabled={!sortable}
|
||||
items={selectedProperties}
|
||||
strategy={horizontalListSortingStrategy}
|
||||
>
|
||||
<div className="flex items-center gap-2">
|
||||
{selectedProperties.map((value) => (
|
||||
<SortableProperty
|
||||
key={`item-${value}`}
|
||||
name={value}
|
||||
onRemove={handleRemove}
|
||||
sortable={sortable}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</SortableContext>
|
||||
</DndContext>
|
||||
|
||||
<Popover
|
||||
visible={open}
|
||||
onClickOutside={() => setOpen(false)}
|
||||
|
@ -63,6 +63,10 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@ant-design/icons": "^4.7.0",
|
||||
"@dnd-kit/core": "^6.0.8",
|
||||
"@dnd-kit/modifiers": "^6.0.1",
|
||||
"@dnd-kit/sortable": "^7.0.2",
|
||||
"@dnd-kit/utilities": "^3.2.1",
|
||||
"@floating-ui/react": "^0.16.0",
|
||||
"@lottiefiles/react-lottie-player": "^3.4.7",
|
||||
"@medv/finder": "^2.1.0",
|
||||
|
@ -8,6 +8,18 @@ dependencies:
|
||||
'@ant-design/icons':
|
||||
specifier: ^4.7.0
|
||||
version: 4.7.0(react-dom@16.14.0)(react@16.14.0)
|
||||
'@dnd-kit/core':
|
||||
specifier: ^6.0.8
|
||||
version: 6.0.8(react-dom@16.14.0)(react@16.14.0)
|
||||
'@dnd-kit/modifiers':
|
||||
specifier: ^6.0.1
|
||||
version: 6.0.1(@dnd-kit/core@6.0.8)(react@16.14.0)
|
||||
'@dnd-kit/sortable':
|
||||
specifier: ^7.0.2
|
||||
version: 7.0.2(@dnd-kit/core@6.0.8)(react@16.14.0)
|
||||
'@dnd-kit/utilities':
|
||||
specifier: ^3.2.1
|
||||
version: 3.2.1(react@16.14.0)
|
||||
'@floating-ui/react':
|
||||
specifier: ^0.16.0
|
||||
version: 0.16.0(@types/react@16.14.34)(react-dom@16.14.0)(react@16.14.0)
|
||||
@ -2245,6 +2257,61 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@dnd-kit/accessibility@3.0.1(react@16.14.0):
|
||||
resolution: {integrity: sha512-HXRrwS9YUYQO9lFRc/49uO/VICbM+O+ZRpFDe9Pd1rwVv2PCNkRiTZRdxrDgng/UkvdC3Re9r2vwPpXXrWeFzg==}
|
||||
peerDependencies:
|
||||
react: '>=16.8.0'
|
||||
dependencies:
|
||||
react: 16.14.0
|
||||
tslib: 2.4.1
|
||||
dev: false
|
||||
|
||||
/@dnd-kit/core@6.0.8(react-dom@16.14.0)(react@16.14.0):
|
||||
resolution: {integrity: sha512-lYaoP8yHTQSLlZe6Rr9qogouGUz9oRUj4AHhDQGQzq/hqaJRpFo65X+JKsdHf8oUFBzx5A+SJPUvxAwTF2OabA==}
|
||||
peerDependencies:
|
||||
react: '>=16.8.0'
|
||||
react-dom: '>=16.8.0'
|
||||
dependencies:
|
||||
'@dnd-kit/accessibility': 3.0.1(react@16.14.0)
|
||||
'@dnd-kit/utilities': 3.2.1(react@16.14.0)
|
||||
react: 16.14.0
|
||||
react-dom: 16.14.0(react@16.14.0)
|
||||
tslib: 2.4.1
|
||||
dev: false
|
||||
|
||||
/@dnd-kit/modifiers@6.0.1(@dnd-kit/core@6.0.8)(react@16.14.0):
|
||||
resolution: {integrity: sha512-rbxcsg3HhzlcMHVHWDuh9LCjpOVAgqbV78wLGI8tziXY3+qcMQ61qVXIvNKQFuhj75dSfD+o+PYZQ/NUk2A23A==}
|
||||
peerDependencies:
|
||||
'@dnd-kit/core': ^6.0.6
|
||||
react: '>=16.8.0'
|
||||
dependencies:
|
||||
'@dnd-kit/core': 6.0.8(react-dom@16.14.0)(react@16.14.0)
|
||||
'@dnd-kit/utilities': 3.2.1(react@16.14.0)
|
||||
react: 16.14.0
|
||||
tslib: 2.4.1
|
||||
dev: false
|
||||
|
||||
/@dnd-kit/sortable@7.0.2(@dnd-kit/core@6.0.8)(react@16.14.0):
|
||||
resolution: {integrity: sha512-wDkBHHf9iCi1veM834Gbk1429bd4lHX4RpAwT0y2cHLf246GAvU2sVw/oxWNpPKQNQRQaeGXhAVgrOl1IT+iyA==}
|
||||
peerDependencies:
|
||||
'@dnd-kit/core': ^6.0.7
|
||||
react: '>=16.8.0'
|
||||
dependencies:
|
||||
'@dnd-kit/core': 6.0.8(react-dom@16.14.0)(react@16.14.0)
|
||||
'@dnd-kit/utilities': 3.2.1(react@16.14.0)
|
||||
react: 16.14.0
|
||||
tslib: 2.4.1
|
||||
dev: false
|
||||
|
||||
/@dnd-kit/utilities@3.2.1(react@16.14.0):
|
||||
resolution: {integrity: sha512-OOXqISfvBw/1REtkSK2N3Fi2EQiLMlWUlqnOK/UpOISqBZPWpE6TqL+jcPtMOkE8TqYGiURvRdPSI9hltNUjEA==}
|
||||
peerDependencies:
|
||||
react: '>=16.8.0'
|
||||
dependencies:
|
||||
react: 16.14.0
|
||||
tslib: 2.4.1
|
||||
dev: false
|
||||
|
||||
/@esbuild/linux-loong64@0.14.54:
|
||||
resolution: {integrity: sha512-bZBrLAIX1kpWelV0XemxBZllyRmM6vgFQQG2GdNb+r3Fkp0FOh1NJSvekXDs7jq70k4euu1cryLMfU+mTXlEpw==}
|
||||
engines: {node: '>=12'}
|
||||
|
Loading…
Reference in New Issue
Block a user