diff --git a/packages/survey-core/src/common-styles/sv-drag-drop.scss b/packages/survey-core/src/common-styles/sv-drag-drop.scss index d7b5bb720f..54753b47e3 100644 --- a/packages/survey-core/src/common-styles/sv-drag-drop.scss +++ b/packages/survey-core/src/common-styles/sv-drag-drop.scss @@ -47,6 +47,31 @@ align-items: center; line-height: 0; } + + .sd-table__cell.sd-table__cell--drag { + >div { + background-color: $question-background; + min-height: calcSize(6); + } + } +} + +.sd-table__cell--header, +.sd-table__cell { + &.sd-table__cell--drag { + padding-right: 0; + padding-left: 0; + } +} + +.sd-question--mobile { + + .sd-table__cell--header, + .sd-table__cell { + &.sd-table__cell--drag { + display: none; + } + } } .sv-matrix-row--drag-drop-ghost-mod td { diff --git a/packages/survey-core/src/defaultV2-theme/blocks/sd-matrixdynamic.scss b/packages/survey-core/src/defaultV2-theme/blocks/sd-matrixdynamic.scss index 236703944d..229e96ab47 100644 --- a/packages/survey-core/src/defaultV2-theme/blocks/sd-matrixdynamic.scss +++ b/packages/survey-core/src/defaultV2-theme/blocks/sd-matrixdynamic.scss @@ -58,13 +58,33 @@ } } +.sd-table__row:hover { + .sd-drag-element__svg { + visibility: visible; + } +} + +.sd-table__cell.sd-table__cell--drag { + >div { + display: flex; + justify-content: end; + align-items: center; + margin-left: calcSize(-4); + width: calcSize(4); + background-color: $question-background; + min-height: calcSize(6); + } +} + .sd-drag-element__svg { - width: calcSize(2); - height: calcSize(2); + width: calcSize(3); + height: calcSize(3); display: block; + cursor: pointer; + visibility: hidden; use { - fill: $foreground-light; + fill: $primary; } } @@ -72,15 +92,18 @@ from { border-width: 0px; } + to { border-width: 8px; } } + @keyframes paddingAnimation { from { padding-top: 0; padding-bottom: 0; } + to { padding-top: 24px; padding-bottom: 32px; @@ -88,25 +111,27 @@ } @keyframes empty { - from { - } - to { - } + from {} + + to {} } + .sd-table__row--leave, .sd-table__row--enter { animation-name: empty; --move-whole-animation-duration: calc(var(--move-animation-duration) + var(--move-animation-delay)); --fade-whole-animation-duration: calc(var(--fade-animation-duration) + var(--fade-animation-delay)); animation-duration: max(var(--fade-whole-animation-duration), var(--move-whole-animation-duration)); - & > td { + + &>td { animation-name: borderAnimation; animation-direction: var(--animation-direction); animation-timing-function: var(--animation-timing-function); animation-duration: var(--move-animation-duration); animation-fill-mode: forwards; animation-delay: var(--move-animation-delay); - & > div { + + &>div { animation-name: fadeIn, moveInWithOverflow; opacity: 0; animation-direction: var(--animation-direction); @@ -117,6 +142,7 @@ } } } + .sd-table__row--enter { --move-animation-delay: 0s; --move-animation-duration: #{$matrix-row-move-in-duration}; @@ -125,6 +151,7 @@ --animation-direction: normal; --animation-timing-function: #{$ease-out}; } + .sd-table__row--leave { --move-animation-delay: #{$matrix-row-move-out-delay}; --move-animation-duration: #{$matrix-row-move-out-duration}; @@ -133,10 +160,12 @@ --animation-direction: reverse; --animation-timing-function: #{$reverse-ease-out}; } + .sd-table__row--detail { + &.sd-table__row--enter, &.sd-table__row--leave { - & > td { + &>td { animation-name: borderAnimation, paddingAnimation; animation-duration: var(--move-animation-duration); animation-fill-mode: forwards; @@ -153,6 +182,7 @@ --animation-direction: normal; --animation-timing-function: #{$ease-out}; } + &.sd-table__row--leave { --move-animation-delay: #{$matrix-detail-row-move-out-delay}; --move-animation-duration: #{$matrix-detail-row-move-out-duration}; @@ -161,4 +191,4 @@ --animation-direction: reverse; --animation-timing-function: #{$reverse-ease-out}; } -} +} \ No newline at end of file diff --git a/packages/survey-core/src/question_matrixdropdownrendered.ts b/packages/survey-core/src/question_matrixdropdownrendered.ts index 241dd1fe4b..3a45d7e7ae 100644 --- a/packages/survey-core/src/question_matrixdropdownrendered.ts +++ b/packages/survey-core/src/question_matrixdropdownrendered.ts @@ -494,7 +494,7 @@ export class QuestionMatrixDropdownRenderedTable extends Base { if (!isShown) return; this.headerRowValue = this.createRenderedRow(this.cssClasses); if (this.isRowsDragAndDrop) { - this.headerRow.cells.push(this.createHeaderCell(null, "action")); + this.headerRow.cells.push(this.createHeaderCell(null, "action", this.cssClasses.actionsCellDrag)); } if (this.hasActionCellInRows("start")) { this.headerRow.cells.push(this.createHeaderCell(null, "action")); @@ -1072,23 +1072,25 @@ export class QuestionMatrixDropdownRenderedTable extends Base { if (!choices || !Array.isArray(choices)) return null; return choices; } - private setHeaderCellCssClasses(cell: QuestionMatrixDropdownRenderedCell, cellType?: string): void { + private setHeaderCellCssClasses(cell: QuestionMatrixDropdownRenderedCell, cellType?: string, classMod?: string): void { cell.className = new CssClassBuilder() .append(this.cssClasses.headerCell) .append(this.cssClasses.columnTitleCell, this.matrix.isColumnLayoutHorizontal) .append(this.cssClasses.emptyCell, !!cell.isEmpty) .append(this.cssClasses.cell + "--" + cellType, !!cellType) + .append(classMod, !!classMod) .toString(); } private createHeaderCell( column: MatrixDropdownColumn, - cellType: string = null + cellType: string = null, + classMod?: string ): QuestionMatrixDropdownRenderedCell { let cell = !!column ? this.createTextCell(column.locTitle) : this.createEmptyCell(); cell.column = column; this.setHeaderCell(column, cell); if (!cellType) cellType = (!!column && column.cellType !== "default") ? column.cellType : this.matrix.cellType; - this.setHeaderCellCssClasses(cell, cellType); + this.setHeaderCellCssClasses(cell, cellType, classMod); return cell; } private setHeaderCell( diff --git a/packages/survey-core/src/question_matrixdynamic.ts b/packages/survey-core/src/question_matrixdynamic.ts index 98d30799c9..77ba1c042c 100644 --- a/packages/survey-core/src/question_matrixdynamic.ts +++ b/packages/survey-core/src/question_matrixdynamic.ts @@ -105,7 +105,7 @@ export class QuestionMatrixDynamicModel extends QuestionMatrixDropdownModelBase return true; } public onPointerDown(pointerDownEvent: PointerEvent, row: MatrixDropdownRowModelBase):void { - if (!row || !this.isRowsDragAndDrop) return; + if (!row || !this.isRowsDragAndDrop || this.isDesignMode) return; if (this.isBanStartDrag(pointerDownEvent)) return; if (row.isDetailPanelShowing) return; this.draggedRow = row; diff --git a/visualRegressionTests/tests/defaultV2/etalons/matrixdynamic-allowRowsDragAndDrop-lockedRowCount-2.png b/visualRegressionTests/tests/defaultV2/etalons/matrixdynamic-allowRowsDragAndDrop-lockedRowCount-2.png new file mode 100644 index 0000000000..e7b36388d9 Binary files /dev/null and b/visualRegressionTests/tests/defaultV2/etalons/matrixdynamic-allowRowsDragAndDrop-lockedRowCount-2.png differ diff --git a/visualRegressionTests/tests/defaultV2/etalons/matrixdynamic-allowRowsDragAndDrop-lockedRowCount.png b/visualRegressionTests/tests/defaultV2/etalons/matrixdynamic-allowRowsDragAndDrop-lockedRowCount.png index edc6f99972..cfdfbbc1b9 100644 Binary files a/visualRegressionTests/tests/defaultV2/etalons/matrixdynamic-allowRowsDragAndDrop-lockedRowCount.png and b/visualRegressionTests/tests/defaultV2/etalons/matrixdynamic-allowRowsDragAndDrop-lockedRowCount.png differ diff --git a/visualRegressionTests/tests/defaultV2/etalons/matrixdynamic-allowRowsDragAndDrop.png b/visualRegressionTests/tests/defaultV2/etalons/matrixdynamic-allowRowsDragAndDrop.png index 2c11c5caad..850bf045ef 100644 Binary files a/visualRegressionTests/tests/defaultV2/etalons/matrixdynamic-allowRowsDragAndDrop.png and b/visualRegressionTests/tests/defaultV2/etalons/matrixdynamic-allowRowsDragAndDrop.png differ diff --git a/visualRegressionTests/tests/defaultV2/matrixdynamic.ts b/visualRegressionTests/tests/defaultV2/matrixdynamic.ts index 2765e4083b..2a66cff717 100644 --- a/visualRegressionTests/tests/defaultV2/matrixdynamic.ts +++ b/visualRegressionTests/tests/defaultV2/matrixdynamic.ts @@ -231,6 +231,7 @@ frameworks.forEach(framework => { const matrixdynamicRoot = Selector(".sd-question"); await resetFocusToBody(); + await t.hover(matrixdynamicRoot.find(".sd-table__row")); await takeElementScreenshot("matrixdynamic-allowRowsDragAndDrop.png", matrixdynamicRoot, t, comparer); }); }); @@ -246,7 +247,10 @@ frameworks.forEach(framework => { const matrixdynamicRoot = Selector(".sd-question"); await resetFocusToBody(); + await t.hover(matrixdynamicRoot.find(".sd-table__row").nth(0)); await takeElementScreenshot("matrixdynamic-allowRowsDragAndDrop-lockedRowCount.png", matrixdynamicRoot, t, comparer); + await t.hover(matrixdynamicRoot.find(".sd-table__row").nth(1)); + await takeElementScreenshot("matrixdynamic-allowRowsDragAndDrop-lockedRowCount-2.png", matrixdynamicRoot, t, comparer); await ClientFunction(() => { (window as any).survey.getAllQuestions()[0].allowRowsDragAndDrop = false; })(); await takeElementScreenshot("matrixdynamic-lockedRowCount.png", matrixdynamicRoot, t, comparer);