|
9 | 9 | 'stack--done-column': isDoneColumn, |
10 | 10 | 'stack--bottom-add-empty': isEmptyStackWithBottomAddCard, |
11 | 11 | 'stack--add-card-at-top': canAddCardAtTop, |
| 12 | + 'stack--dragging-card': draggingCard, |
| 13 | + 'stack--drag-over': draggingOverStack, |
12 | 14 | }" |
13 | 15 | :data-cy-stack="stack.title"> |
14 | 16 | <div v-click-outside="stopCardCreation" |
|
142 | 144 | data-dragscroll-enabled |
143 | 145 | @should-accept-drop="canEdit" |
144 | 146 | @drag-start="draggingCard = true" |
145 | | - @drag-end="draggingCard = false" |
| 147 | + @drag-end="onDragEnd" |
| 148 | + @drag-enter="draggingOverStack = true" |
| 149 | + @drag-leave="draggingOverStack = false" |
146 | 150 | @drop="($event) => onDropCard(stack.id, $event)"> |
147 | 151 | <Draggable v-for="card in cardsByStack" :key="card.id"> |
148 | 152 | <transition :appear="animate && !card.animated && (card.animated=true)" |
|
153 | 157 | </Draggable> |
154 | 158 | </Container> |
155 | 159 |
|
156 | | - <Container v-if="canAddCardAtBottom && isEmptyStackWithBottomAddCard" |
157 | | - :get-child-payload="payloadForCard(stack.id)" |
158 | | - class="dnd-container stack__card-add stack__card-add--bottom stack__card-add--dropzone" |
159 | | - group-name="stack" |
160 | | - data-click-closes-sidebar="true" |
161 | | - non-drag-area-selector=".dragDisabled" |
162 | | - :drag-handle-selector="dragHandleSelector" |
163 | | - @should-accept-drop="canEdit" |
164 | | - @drag-start="draggingCard = true" |
165 | | - @drag-end="draggingCard = false" |
166 | | - @drop="($event) => onDropCard(stack.id, $event)"> |
167 | | - <NcButton v-if="!showAddCard" |
168 | | - data-cy="action:add-card" |
169 | | - class="stack__card-add-button" |
170 | | - type="tertiary" |
171 | | - :wide="true" |
172 | | - @click.stop="showAddCard=true"> |
173 | | - <template #icon> |
174 | | - <PlusIcon :size="20" /> |
175 | | - </template> |
176 | | - {{ t('deck', 'Add card') }} |
177 | | - </NcButton> |
178 | | - <form v-else |
179 | | - :class="{ 'icon-loading-small': stateCardCreating }" |
180 | | - @submit.prevent.stop="clickAddCard()"> |
181 | | - <label for="new-stack-input-main" class="hidden-visually">{{ t('deck', 'Add a new card') }}</label> |
182 | | - <input id="new-stack-input-main" |
183 | | - ref="newCardInput" |
184 | | - v-model="newCardTitle" |
185 | | - type="text" |
186 | | - class="no-close" |
187 | | - :disabled="stateCardCreating" |
188 | | - :placeholder="t('deck', 'Card name')" |
189 | | - required |
190 | | - pattern=".*\S+.*" |
191 | | - @focus="onCreateCardFocus" |
192 | | - @keydown.esc.stop="closeCardCreation"> |
193 | | - <input v-show="!stateCardCreating" |
194 | | - class="icon-confirm" |
195 | | - type="submit" |
196 | | - value=""> |
197 | | - </form> |
198 | | - </Container> |
199 | | - <div v-else-if="canAddCardAtBottom" class="stack__card-add stack__card-add--bottom"> |
| 160 | + <div v-if="canAddCardAtBottom" class="stack__card-add stack__card-add--bottom"> |
200 | 161 | <NcButton v-if="!showAddCard" |
201 | 162 | data-cy="action:add-card" |
202 | 163 | class="stack__card-add-button" |
@@ -279,6 +240,7 @@ export default { |
279 | 240 | return { |
280 | 241 | editing: false, |
281 | 242 | draggingCard: false, |
| 243 | + draggingOverStack: false, |
282 | 244 | copiedStack: '', |
283 | 245 | newCardTitle: '', |
284 | 246 | showAddCard: false, |
@@ -370,6 +332,11 @@ export default { |
370 | 332 | this.showAddCard = false |
371 | 333 | return false |
372 | 334 | }, |
| 335 | + onDragEnd() { |
| 336 | + this.draggingCard = false |
| 337 | + // drag-leave is not emitted when the card is dropped inside the stack |
| 338 | + this.draggingOverStack = false |
| 339 | + }, |
373 | 340 | async onDropCard(stackId, event) { |
374 | 341 | const { addedIndex, removedIndex, payload } = event |
375 | 342 | const card = Object.assign({}, payload) |
@@ -517,30 +484,36 @@ export default { |
517 | 484 | flex-grow: 1; |
518 | 485 | } |
519 | 486 |
|
520 | | - &:not(.stack--add-card-at-top) { |
| 487 | + &:not(.stack--add-card-at-top):not(.stack--bottom-add-empty) { |
521 | 488 | .dnd-container { |
522 | 489 | flex: 0 1 auto; |
523 | 490 | min-height: 0; |
524 | 491 | } |
525 | 492 | } |
526 | 493 |
|
527 | 494 | &.stack--bottom-add-empty { |
528 | | - // Collapse the card list while it is empty so the add card control is |
529 | | - // not pushed down. Once a card is dragged over, the drop placeholder |
530 | | - // becomes a child and the regular spacing applies again. |
531 | | - :deep(.stack__cards-list:empty) { |
532 | | - --stack-cards-spacing: 0; |
| 495 | + // The empty card list keeps filling the column so that it stays an |
| 496 | + // easy drop target, while the add card control floats on top of it, |
| 497 | + // right where the first card would be. |
| 498 | + .stack__card-add--bottom { |
| 499 | + position: absolute; |
| 500 | + inset-inline: 0; |
| 501 | + top: calc(var(--default-clickable-area) + #{$stack-gap}); |
| 502 | + transition: top var(--animation-quick); |
533 | 503 | } |
534 | 504 |
|
535 | | - // Spacing comes from the shared vertical dnd container rule in |
536 | | - // Board.vue, the min-height accounts for its vertical padding |
537 | | - .stack__card-add--dropzone { |
538 | | - flex: 0 0 auto; |
539 | | - display: flex; |
540 | | - align-items: center; |
541 | | - min-height: calc(var(--stack-card-add-control-height) + (2 * #{$stack-gap})); |
542 | | - box-sizing: border-box; |
543 | | - position: relative; |
| 505 | + // Make way for the drop placeholder while a card is dragged over the |
| 506 | + // list. The list itself is left untouched, resizing it would move it |
| 507 | + // away from under the pointer. |
| 508 | + &.stack--drag-over .stack__card-add--bottom { |
| 509 | + top: calc(var(--default-clickable-area) + var(--stack-card-add-control-height) + 2 * #{$stack-gap}); |
| 510 | + } |
| 511 | +
|
| 512 | + // smooth-dnd resolves the hovered container with elementFromPoint(), so |
| 513 | + // the floating control has to let the drag through to the list below it, |
| 514 | + // otherwise dragging over it would count as leaving the list. |
| 515 | + &.stack--dragging-card .stack__card-add--bottom { |
| 516 | + pointer-events: none; |
544 | 517 | } |
545 | 518 | } |
546 | 519 |
|
|
0 commit comments