diff --git a/frontend/__snapshots__/filters-person-property-select--default.png b/frontend/__snapshots__/filters-person-property-select--default.png index 4e618c3af0d..9cfbf784802 100644 Binary files a/frontend/__snapshots__/filters-person-property-select--default.png and b/frontend/__snapshots__/filters-person-property-select--default.png differ diff --git a/frontend/src/lib/components/PersonPropertySelect/PersonPropertySelect.tsx b/frontend/src/lib/components/PersonPropertySelect/PersonPropertySelect.tsx index 58726593b0a..0b5fe4cf3d5 100644 --- a/frontend/src/lib/components/PersonPropertySelect/PersonPropertySelect.tsx +++ b/frontend/src/lib/components/PersonPropertySelect/PersonPropertySelect.tsx @@ -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 => ( - - onRemove(name)}>{name} - -) +}): JSX.Element => { + const { setNodeRef, attributes, transform, transition, listeners } = useSortable({ id: name }) -const SortableProperty = SortableElement(PropertyTag) - -const SortablePropertyList = SortableContainer(({ children }: { children: React.ReactNode }) => { - return {children} -}) + return ( + + onRemove(name)}>{name} + + ) +} export const PersonPropertySelect = ({ onChange, @@ -60,23 +71,36 @@ export const PersonPropertySelect = ({ return (
- {sortable ? ( - - {selectedProperties.map((value, index) => ( - - ))} - - ) : ( - selectedProperties?.map((value) => ( - - )) - )} + { + if (over && active.id !== over.id) { + handleSort({ + oldIndex: selectedProperties.indexOf(active.id.toString()), + newIndex: selectedProperties.indexOf(over.id.toString()), + }) + } + }} + collisionDetection={closestCenter} + modifiers={[restrictToHorizontalAxis]} + > + +
+ {selectedProperties.map((value) => ( + + ))} +
+
+
+ setOpen(false)} diff --git a/package.json b/package.json index a5a751e7040..8e4ec82a7b2 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ad32f20ef86..0c8d51a7b38 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -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'}