Skip to content

fix(plasma-hope): migrate PreviewGallery to dnd-kit for React 19#2889

Draft
Yeti-or wants to merge 6 commits into
devfrom
chore/fix-package-formatting
Draft

fix(plasma-hope): migrate PreviewGallery to dnd-kit for React 19#2889
Yeti-or wants to merge 6 commits into
devfrom
chore/fix-package-formatting

Conversation

@Yeti-or

@Yeti-or Yeti-or commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

PLASMA-WEB

PreviewGallery, UploadVisual

  • мигрирован PreviewGallery с react-sortable-hoc на @dnd-kit/core и @dnd-kit/sortable;
  • восстановлена совместимость публичного API sortable-пропсов (axis, distance, pressDelay, lockAxis, useDragHandle, disabled);
  • исправлены storybook-стори UploadVisual/Draggable и PreviewGallery/Draggable, падавшие в Storybook 10 на React 19.

What/why changed

react-sortable-hoc использует ReactDOM.findDOMNode, который удалён в React 19. Storybook 10 подтягивает React 19, из-за чего draggable-стори UploadVisual и PreviewGallery падали с ошибкой findDOMNode is not a function / indexOf при монтировании sortable-элементов.

Замена на @dnd-kit убирает зависимость от findDOMNode и восстанавливает drag-and-drop в галерее превью. Слой sortableCompat сохраняет прежнюю форму пропсов для потребителей компонента.

📦 Published PR as canary version: Canary Versions

✨ Test out this PR locally via:

npm install @salutejs/plasma-asdk@0.380.1-canary.2889.27703316223.0
npm install @salutejs/plasma-b2c@1.622.1-canary.2889.27703316223.0
npm install @salutejs/plasma-giga@0.349.1-canary.2889.27703316223.0
npm install @salutejs/plasma-homeds@0.349.1-canary.2889.27703316223.0
npm install @salutejs/plasma-hope@1.376.1-canary.2889.27703316223.0
npm install @salutejs/plasma-new-hope@0.366.1-canary.2889.27703316223.0
npm install @salutejs/plasma-ui@1.352.1-canary.2889.27703316223.0
npm install @salutejs/plasma-web@1.624.1-canary.2889.27703316223.0
npm install @salutejs/sdds-bizcom@0.354.1-canary.2889.27703316223.0
npm install @salutejs/sdds-cs@0.358.1-canary.2889.27703316223.0
npm install @salutejs/sdds-dfa@0.352.1-canary.2889.27703316223.0
npm install @salutejs/sdds-finai@0.345.1-canary.2889.27703316223.0
npm install @salutejs/sdds-insol@0.349.1-canary.2889.27703316223.0
npm install @salutejs/sdds-netology@0.353.1-canary.2889.27703316223.0
npm install @salutejs/sdds-os@0.24.1-canary.2889.27703316223.0
npm install @salutejs/sdds-platform-ai@0.353.1-canary.2889.27703316223.0
npm install @salutejs/sdds-sbcom@0.354.1-canary.2889.27703316223.0
npm install @salutejs/sdds-scan@0.352.1-canary.2889.27703316223.0
npm install @salutejs/sdds-serv@0.353.1-canary.2889.27703316223.0
npm install @salutejs/sdds-api-tests@0.11.1-canary.2889.27703316223.0
npm install @salutejs/plasma-sb-utils@0.230.1-canary.2889.27703316223.0
# or 
yarn add @salutejs/plasma-asdk@0.380.1-canary.2889.27703316223.0
yarn add @salutejs/plasma-b2c@1.622.1-canary.2889.27703316223.0
yarn add @salutejs/plasma-giga@0.349.1-canary.2889.27703316223.0
yarn add @salutejs/plasma-homeds@0.349.1-canary.2889.27703316223.0
yarn add @salutejs/plasma-hope@1.376.1-canary.2889.27703316223.0
yarn add @salutejs/plasma-new-hope@0.366.1-canary.2889.27703316223.0
yarn add @salutejs/plasma-ui@1.352.1-canary.2889.27703316223.0
yarn add @salutejs/plasma-web@1.624.1-canary.2889.27703316223.0
yarn add @salutejs/sdds-bizcom@0.354.1-canary.2889.27703316223.0
yarn add @salutejs/sdds-cs@0.358.1-canary.2889.27703316223.0
yarn add @salutejs/sdds-dfa@0.352.1-canary.2889.27703316223.0
yarn add @salutejs/sdds-finai@0.345.1-canary.2889.27703316223.0
yarn add @salutejs/sdds-insol@0.349.1-canary.2889.27703316223.0
yarn add @salutejs/sdds-netology@0.353.1-canary.2889.27703316223.0
yarn add @salutejs/sdds-os@0.24.1-canary.2889.27703316223.0
yarn add @salutejs/sdds-platform-ai@0.353.1-canary.2889.27703316223.0
yarn add @salutejs/sdds-sbcom@0.354.1-canary.2889.27703316223.0
yarn add @salutejs/sdds-scan@0.352.1-canary.2889.27703316223.0
yarn add @salutejs/sdds-serv@0.353.1-canary.2889.27703316223.0
yarn add @salutejs/sdds-api-tests@0.11.1-canary.2889.27703316223.0
yarn add @salutejs/plasma-sb-utils@0.230.1-canary.2889.27703316223.0

@coderabbitai

coderabbitai Bot commented Jun 16, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Migrates PreviewGallery in plasma-hope from react-sortable-hoc to @dnd-kit/core and @dnd-kit/sortable. A new sortableCompat.ts module provides backward-compatible types and helper functions. The list, container, and individual item components are updated to use the new DnD primitives and support an optional dedicated drag handle.

Changes

PreviewGallery: react-sortable-hoc → @dnd-kit migration

Layer / File(s) Summary
Dependency update and sortableCompat module
packages/plasma-hope/package.json, packages/plasma-hope/src/components/PreviewGallery/sortableCompat.ts
Replaces react-sortable-hoc with @dnd-kit/core and @dnd-kit/sortable. Adds sortableCompat.ts with backward-compatible types (PreviewGallerySortableAxis, PreviewGallerySortableItemProps, PreviewGallerySortableContainerProps), a prop key constant, and helpers: resolveSortableAxis, createAxisModifier, getSortableSensorOptions, splitSortableItemProps.
Shared prop types and public exports
packages/plasma-hope/src/components/PreviewGallery/types.ts, packages/plasma-hope/src/components/PreviewGallery/index.ts
Expands AddionalItemProps to include useDragHandle, dragHandleListeners, dragHandleAttributes, and disabled. Re-exports the three new sortable types from the module index.
PreviewGalleryListItems DnD core refactor
packages/plasma-hope/src/components/PreviewGallery/PreviewGalleryItems.tsx
Replaces SortableContainer/SortableElement with DndContext/SortableContext/useSortable. Adds memoized SortableGalleryItem wrapper, new list props (modifiers, sensorOptions, useDragHandle), and dual render paths: static grid when interactionType === 'selectable', DnD-wrapped grid otherwise.
PreviewGallery container wiring
packages/plasma-hope/src/components/PreviewGallery/PreviewGallery.tsx
Updates component type to PreviewGallerySortableContainerProps. Adds useMemo-derived resolvedAxis/modifiers/sensorOptions. Rewrites onSortEnd to accept DragEndEvent and resolve oldIndex/newIndex via active.id/over.id. Filters sortable-only props from forwarded HTML props.
Drag handle wiring in item components
packages/plasma-hope/src/components/PreviewGallery/PreviewGalleryItemBase.tsx, packages/plasma-hope/src/components/PreviewGallery/PreviewGalleryItemError.tsx
Both item components destructure useDragHandle, dragHandleListeners, and dragHandleAttributes, and conditionally spread them onto StyledIconDrag only when useDragHandle is enabled.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant DndContext
  participant SortableGalleryItem
  participant PreviewGallery
  participant onItemsSortEnd

  User->>DndContext: drag gallery item
  DndContext->>SortableGalleryItem: apply useSortable transform/transition
  User->>DndContext: release (drop)
  DndContext->>PreviewGallery: onSortEnd(DragEndEvent { active.id, over.id })
  PreviewGallery->>PreviewGallery: match ids → oldIndex / newIndex
  PreviewGallery->>onItemsSortEnd: onItemsSortEnd({ oldIndex, newIndex })
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Suggested reviewers

  • IgorYar
  • TitanKuzmich
  • Irinkv

Poem

🐇 Hop hop, the old hoc is gone today,
dnd-kit slides in with a smoother way!
Axes resolved, modifiers in place,
drag handles wired with elegant grace.
The gallery sorts with a brand-new beat —
this bunny thinks the migration's complete! 🎉

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately reflects the main objective: migrating PreviewGallery from react-sortable-hoc to dnd-kit for React 19 compatibility.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/fix-package-formatting

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions

Copy link
Copy Markdown
Contributor

Theme Builder app deployed!

https://plasma.sberdevices.ru/pr/plasma-theme-builder-pr-2889/

@Yeti-or Yeti-or marked this pull request as ready for review June 16, 2026 17:30
@Yeti-or Yeti-or marked this pull request as draft June 16, 2026 17:32

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/plasma-hope/src/components/PreviewGallery/PreviewGalleryItems.tsx`:
- Around line 163-169: The grabbing state is set on drag start but only cleared
on drag end, leaving it stuck if drag is cancelled. You need to wire up the
DndContext cancel path. In
packages/plasma-hope/src/components/PreviewGallery/PreviewGallery.tsx#L94-L116,
add a new callback const onSortCancel = useCallback(() => setGrabbing(false),
[]) alongside the existing onSortStart and onSortEnd callbacks. Then in
packages/plasma-hope/src/components/PreviewGallery/PreviewGallery.tsx#L119-L131,
pass onSortCancel as a prop into PreviewGalleryListItems. Finally, in
packages/plasma-hope/src/components/PreviewGallery/PreviewGalleryItems.tsx#L163-L169,
add onDragCancel={onSortCancel} to the DndContext component to invoke the cancel
handler when drag is cancelled.
- Around line 128-131: The useSensors hook in PreviewGalleryItems.tsx currently
only includes MouseSensor and TouchSensor, which prevents keyboard users from
initiating drag-to-reorder operations. Add KeyboardSensor as a third useSensor
call alongside the existing mouse and touch sensors, passing
sortableKeyboardCoordinates as the coordinate function to the KeyboardSensor.
You will need to import KeyboardSensor and sortableKeyboardCoordinates from the
appropriate dnd-kit libraries if they are not already imported.
- Around line 87-95: In the PreviewGalleryItemBase component, when useDragHandle
is enabled and a custom component is provided, the custom component branch
(lines 184-190) is missing the drag handle activator that the default
image-based path includes. Add the StyledIconDrag component to the custom
component branch to match the structure used in the image-based path (lines
173-178), ensuring custom items can be properly dragged when the drag handle is
activated.

In `@packages/plasma-hope/src/components/PreviewGallery/sortableCompat.ts`:
- Around line 89-92: The getSortableSensorOptions function checks pressDelay
using truthiness, which incorrectly treats an explicit pressDelay={0} as falsy
and falls through to the default behavior. Replace the truthiness checks for
pressDelay in both the mouseActivation and touchActivation variable assignments
with an explicit undefined check (such as pressDelay !== undefined) to ensure
that a zero value is correctly recognized as an intentional parameter value
rather than an absent parameter.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 9b3f72cc-1329-410e-bb3c-83aea2cc41bf

📥 Commits

Reviewing files that changed from the base of the PR and between a53e74b and f9ab598.

⛔ Files ignored due to path filters (1)
  • packages/plasma-hope/package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (8)
  • packages/plasma-hope/package.json
  • packages/plasma-hope/src/components/PreviewGallery/PreviewGallery.tsx
  • packages/plasma-hope/src/components/PreviewGallery/PreviewGalleryItemBase.tsx
  • packages/plasma-hope/src/components/PreviewGallery/PreviewGalleryItemError.tsx
  • packages/plasma-hope/src/components/PreviewGallery/PreviewGalleryItems.tsx
  • packages/plasma-hope/src/components/PreviewGallery/index.ts
  • packages/plasma-hope/src/components/PreviewGallery/sortableCompat.ts
  • packages/plasma-hope/src/components/PreviewGallery/types.ts

Comment thread packages/plasma-hope/src/components/PreviewGallery/sortableCompat.ts Outdated
@Yeti-or Yeti-or force-pushed the chore/fix-package-formatting branch from 41984da to f9ab598 Compare June 16, 2026 17:45
Yeti-or and others added 6 commits June 17, 2026 19:16
Replace react-sortable-hoc to fix draggable UploadVisual and PreviewGallery
stories broken by removed findDOMNode in React 19.

Co-authored-by: Cursor <cursoragent@cursor.com>
Map axis, distance, pressDelay, lockAxis, useDragHandle, and item disabled
to @dnd-kit while keeping the react-sortable-hoc public API shape.

Co-authored-by: Cursor <cursoragent@cursor.com>
Add keyboard sorting, drag cancel handling, custom component drag handle,
and fix pressDelay=0 sensor activation.

Co-authored-by: Cursor <cursoragent@cursor.com>
Simulate sortable drag with document-level MouseEvent sequence on dnd-kit
sortable wrappers instead of react-sortable-hoc mousemove on target item.

Co-authored-by: Cursor <cursoragent@cursor.com>
Assert the post-drag layout via arrayItemSwapping instead of simulating
pointer drag, which is unreliable with @dnd-kit in Cypress.

Co-authored-by: Cursor <cursoragent@cursor.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant