diff --git a/addons/web/static/src/core/utils/nested_sortable.js b/addons/web/static/src/core/utils/nested_sortable.js index ddba72ba34d..134536bcbb0 100644 --- a/addons/web/static/src/core/utils/nested_sortable.js +++ b/addons/web/static/src/core/utils/nested_sortable.js @@ -38,6 +38,8 @@ import { makeDraggableHook } from "@web/core/utils/draggable_hook_builder"; * the list can accept. If set to '0' the levels are unlimited. Default: 0 * @property {(DraggableHookContext) => boolean}) [isAllowed] You can specify a custom function * to verify if a drop location is allowed. return True by default + * @property {boolean} [useElementSize] The placeholder use the dragged element size instead + * of the small 8px lines. Default:false * * HANDLERS (also optional) * @@ -84,6 +86,7 @@ export const useNestedSortable = makeDraggableHook({ nestInterval: [Number], maxLevels: [Number], isAllowed: [Function], + useElementSize: [Boolean], }, defaultParams: { connectGroups: false, @@ -97,6 +100,7 @@ export const useNestedSortable = makeDraggableHook({ nestInterval: 15, maxLevels: 0, isAllowed: (ctx) => true, + useElementSize: false, }, // Set the parameters. @@ -118,6 +122,7 @@ export const useNestedSortable = makeDraggableHook({ ctx.isRTL = localization.direction === "rtl"; ctx.maxLevels = params.maxLevels || 0; ctx.isAllowed = params.isAllowed ?? (() => true); + ctx.useElementSize = params.useElementSize; }, // Set the current group and create the placeholder row that will take the @@ -134,12 +139,13 @@ export const useNestedSortable = makeDraggableHook({ ctx.prevNestX = ctx.pointer.x; } ctx.current.placeHolder = ctx.current.element.cloneNode(false); - ctx.current.placeHolder.classList.add( - "o_nested_sortable_placeholder", - "w-100", - "d-block", - "py-0" - ); + ctx.current.placeHolder.classList.add("w-100", "d-block", "py-0"); + if (ctx.useElementSize) { + ctx.current.placeHolder.style.height = getComputedStyle(ctx.current.element).height; + ctx.current.placeHolder.classList.add("o_nested_sortable_placeholder_realsize"); + } else { + ctx.current.placeHolder.classList.add("o_nested_sortable_placeholder"); + } addCleanup(() => ctx.current.placeHolder.remove()); }, diff --git a/addons/web/static/src/core/utils/nested_sortable.scss b/addons/web/static/src/core/utils/nested_sortable.scss index 023c9adc935..05b713a1dbf 100644 --- a/addons/web/static/src/core/utils/nested_sortable.scss +++ b/addons/web/static/src/core/utils/nested_sortable.scss @@ -3,3 +3,7 @@ background-color: deepskyblue; height: 5px; } +.o_nested_sortable_placeholder_realsize { + outline: 1px dashed $o-gray-600; + background-color: $o-gray-100; +} diff --git a/addons/web/static/tests/core/utils/nested_sortable_tests.js b/addons/web/static/tests/core/utils/nested_sortable_tests.js index c9b1f8edf4e..bdc1a56a3af 100644 --- a/addons/web/static/tests/core/utils/nested_sortable_tests.js +++ b/addons/web/static/tests/core/utils/nested_sortable_tests.js @@ -1045,6 +1045,53 @@ QUnit.module("Draggable", ({ beforeEach }) => { assert.verifySteps(["start", "allowed_check", "allowed_check", "end"]); }); + QUnit.test("placeholder and drag element have same size", async (assert) => { + assert.expect(5); + target.style.top = "1px"; + class NestedSortable extends Component { + static template = xml` +
+ +
+ `; + + setup() { + useNestedSortable({ + ref: useRef("root"), + elements: ".item", + useElementSize: true, + onDrop({ element, placeholder }) { + assert.strictEqual(element.id, "dragged"); + assert.strictEqual(placeholder.id, "dragged"); + assert.ok( + placeholder.classList.contains("o_nested_sortable_placeholder_realsize") + ); + assert.notOk( + placeholder.classList.contains("o_nested_sortable_placeholder") + ); + assert.strictEqual( + element.getBoundingClientRect().height, + placeholder.getBoundingClientRect().height + ); + }, + }); + } + } + + await mount(NestedSortable, target); + const draggedNode = target.querySelector(".item#dragged"); + const { drop, moveTo } = await drag(draggedNode); + await moveTo("#target", "right"); + await drop(); + }); + QUnit.test("Ignore specified elements", async (assert) => { assert.expect(6);