Redesign product associations with animated drag reordering#2578
Merged
Conversation
Rework the product-associations section on the product edit page into a collapsed accordion matching the panel design: each relationship type is a card showing its label, hint, linked-product count and a Link action, and expands to reveal the linked products. - Add a sort column to product_associations (folded into the alpha baseline) and order the associations() relationship by it, so linking order drives both the panel and storefront display. - Assign an incrementing per-type sort when associating, and add a reorder endpoint scoped to the owning product and type. - Surface the cheapest default-currency price per linked product for the "From ..." label alongside the variant count. - Add a success flash on reorder, mirroring the add action. - Add assoc_count / assoc_from_price / assoc_variants / flash_associations_reordered across all 16 locales. - Cover sort assignment, reorder isolation and price surfacing with tests. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Reorder the associations list with slot transforms (the dnd-kit technique) instead of hover-driven array swaps. Row geometry is captured at dragstart, the target slot is derived purely from the pointer against that geometry, and displaced rows animate via translateY; the reorder commits once on drop. The slot computation never reads live positions, so the animation cannot feed back into it - eliminating the oscillation a hover-swap + FLIP approach caused. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Pull the slot-transform drag-reorder logic out of the associations page into a useDragSort composable (measures row geometry lazily on the first dragover, so it works whether the row or just its handle is draggable) and reuse it for the collection products list and the attribute list fields. A sortableCount bound lets the plain list keep its trailing add-row un-targetable. Update the attribute drag tests to drive the container dragover with stubbed row geometry. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add useGridSort - the 2-D analogue of useDragSort - and use it for the media tile grid. Each cell's rect is captured on the first dragover, the target is the cell nearest the pointer, and displaced cells translate to the slot they will occupy; the reorder commits once on drop. A cell crossing the hero slot slides at its own size and settles to the new size on drop (translate cannot resize). Update the media reorder test to drive the grid dragover with stubbed cell geometry. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Reworks the product-associations section on the product edit page into the panel's accordion design, adds ordering support, and gives every manual drag-sort in the panel a smooth, non-oscillating reorder animation.
Product associations
sortcolumn toproduct_associations(folded into the alpha baseline) and orders theassociations()relationship by it, so linking order drives both the panel and the storefront.sort; a reorder endpoint (scoped to the owning product and type) persists drag reordering.Animated drag reordering
useDragSort(vertical lists) anduseGridSort(2-D grids) implement the dnd-kit slot-transform technique: item order is frozen mid-drag, the target is derived purely from the pointer against captured geometry, displaced items animate via transforms, and the reorder commits once on drop. Because the slot computation never reads live positions, the animation cannot feed back into it.Migration note
The
sortcolumn was folded into the baselinecreate_product_associations_tablemigration (v2 alpha convention). Existing databases need the column added —migrate:fresh, or anALTER TABLEfor data you want to keep.Translations
assoc_count,assoc_from_price,assoc_variantsandflash_associations_reorderedadded across all 16 locales.Testing
pest --testsuite core,pest --testsuite panel,phpstan,pint,npm run type-check,npm test(211),npm run build.🤖 Generated with Claude Code