Skip to content

NTNGL-5467 | Enable List Tile Drag and Drop#6973

Open
NicholasHallman wants to merge 14 commits into
mainfrom
NTNGL-5467/tile-mouse-drag-logic
Open

NTNGL-5467 | Enable List Tile Drag and Drop#6973
NicholasHallman wants to merge 14 commits into
mainfrom
NTNGL-5467/tile-mouse-drag-logic

Conversation

@NicholasHallman
Copy link
Copy Markdown
Contributor

@NicholasHallman NicholasHallman commented May 12, 2026

Almost entirely css changes to re-enable drag and keyboard arrangement functionality for tiles.

The rest of the css is for properly positioning the elements and rotating the marker

Functional Tests (Demo Manual QA)

  • Dragging an item to the left edge of the first card and dropping places the element at the front of the tile list
  • Dragging an item to the right edge of the last card and dropping places the element at the end of the list
  • Dragging an item to the left edge of a card in the middle of the list drops it to the left of the drop target
  • Dragging an item to the right edge of a card in the middle of the list drops it to the right of the drop target
  • The drag handle can be focused with the keyboard and splits into two arrows
  • The keyboard can be used to move cards
  • The screen reader properly reads out the new order of the card after moving.
  • Actions are clickable in the title bar
  • With href on or off the drag area extends to the width of the title bar
  • RTL, the marker is in the correct position
  • RTL, keyboard controls place card in the correct position (up, down, home and end)

Highlighting some design decisions we made in the meeting with Glen and Tayzia

  • The up and down arrows work fine for tiles
  • The screen reader announcements and position information is fine for tiles
  • If a tile is draggable it should always have the tile title header

@github-actions
Copy link
Copy Markdown
Contributor

Thanks for the PR! 🎉

We've deployed an automatic preview for this PR - you can see your changes here:

URL https://live.d2l.dev/prs/BrightspaceUI/core/pr-6973/

Note

The build needs to finish before your changes are deployed.
Changes to the PR will automatically update the instance.

Copy link
Copy Markdown
Contributor Author

@NicholasHallman NicholasHallman left a comment

Choose a reason for hiding this comment

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

Descriptions for what some of this css is accomplishing

}

:host([layout="tile"]) .d2l-list-item-drag-bottom-marker {
right: calc(-0.9rem + 3px);
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Lots of magic numbers here but to explain, the -0.9 rem is the gap between the cards and the 3px is half of the 6px that was previously used to center the markers

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for spelling this out. I would not be adverse to putting this in a comment for "future-us". I am sure we'll be wondering how we arrived at this down the road.

Comment on lines +350 to +354
:host([layout="tile"]) .d2l-list-item-drag-drop-grid {
display: grid;
grid-template-rows: 100%;
grid-template-columns: 1rem 1fr 1fr 1rem;
}
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This rotates the drop targets

Comment thread components/list/list-item-drag-drop-mixin.js Outdated
Comment thread components/list/list-item-generic-layout.js Outdated
Comment on lines +238 to 243
:host([layout="tile"]:not([is-draggable])) {
grid-template-columns:
[start outside-control-start] 0
[outside-control-end control-start] minmax(0, min-content)
[control-end actions-start] minmax(0, auto)
[actions-end end];
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This varient ensures that the selection box is the left most item when the drag handle isn't present. There's a fun layout issue that prevents minmax(0, min-content) from ever equalling 0. My guess is that this is due to the content below the header spanning this column and so chrome assumes the column can't have a width of 0.

Comment on lines +596 to +598
:host([layout="tile"][draggable]) d2l-selection-input {
margin: auto;
}
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

the drag handle makes the title bar slightly taller so we need to tell the selection to center itself

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

What's the height difference?

Copy link
Copy Markdown
Contributor Author

@NicholasHallman NicholasHallman May 26, 2026

Choose a reason for hiding this comment

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

Without the drag handles it's 39px tall, with it's 46px. So 7 pixels

Copy link
Copy Markdown
Contributor

@dbatiste dbatiste May 26, 2026

Choose a reason for hiding this comment

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

@glen-bartlett-d2l , @geurts what are your thoughts on this? I wonder if there is any way we can tighten things up so the header doesn't get thicker. Perhaps in this layout, we could render the drag handle differently so it's not quite so tall.

@NicholasHallman NicholasHallman marked this pull request as ready for review May 13, 2026 15:39
@NicholasHallman NicholasHallman requested a review from a team as a code owner May 13, 2026 15:39
Comment thread components/list/list-item-drag-drop-mixin.js
Comment thread components/list/list-item-drag-drop-mixin.js Outdated
@NicholasHallman NicholasHallman requested a review from dbatiste May 26, 2026 15:59
Comment thread components/list/list-item-mixin.js Outdated
this._hasListItemContent = !!this.shadowRoot.querySelector('slot:not([name])').assignedElements({ flatten: true })
.find(elem => elem.tagName === 'D2L-LIST-ITEM-CONTENT');
}
if (this.draggable && this.layout === 'tile' && this.tileHeader === false) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can this be simplified to if (this.draggable)?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yep seems like it. My thinking was that a more specific rule would keep it from running this code "by accident" but tile-head has no impact of regular list items so it looked fine in my testing with just this.draggable.

class ListItemPlacementMarker extends LitElement {

static properties = {
verticle: { type: Boolean, reflect: true }
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

orientation would be another possibility, but I think vertical is fine.

Note the spelling though.


.d2l-list-drag-marker-line {
height: 12px;
margin-left: -1px;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Don't feel like you need to change it... but we could probably update these two lines to margin-inline: -1px. I only mention it because margin-left and margin-right always raises red flags.

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.

2 participants