Class: Plutonium::UI::Table::Components::DragHandle

Inherits:
Phlexi::Table::HTML
  • Object
show all
Defined in:
lib/plutonium/ui/table/components/drag_handle.rb

Overview

The drag affordance for a reorderable row.

Why it lives inside the first cell rather than in a column of its own

A dedicated grip column would cost horizontal space on EVERY row of every reorderable table, forever, for a gesture used occasionally. So the grip is pulled left into the first cell's padding with a negative margin exactly equal to its own width: it occupies the padding the cell already had, and the cell's content does not shift by a pixel — with or without the grip, hovered or not.

(The padding, not a negative offset outside the cell: the body cell is overflow-hidden, which clips at the PADDING box. Anything positioned beyond it would simply be invisible.)

Why the grip is draggable and the is not

See positioned_controller.js — draggable="true" kills text selection inside the element, and a draggable row fights row_click_controller. Both would be silent regressions on an ordinary data table.

The disabled state IS the way out of the disabled state

Dropping between two rows only means something when the visual order is the stored order, so the server rejects a drop made under any other sort (including a DESCENDING position sort). Rather than hiding the affordance — which would leave the user with no hint that the table is reorderable at all, and no way to make it so — it renders as a link that applies the ascending position sort. That is precisely why position_on registers sort <attribute>.

Why one component serves both the table and the card grid

The behaviour — draggable button, keyboard hint, disabled-is-the-way-out link — is identical on both surfaces; only WHERE the grip sits differs. A table row has padding to hide it in, a card does not, so the placement is the one thing variant: switches (see Table::Theme). Two components would mean two chances for the drag contract to drift.

Defined Under Namespace

Classes: Cell

Constant Summary collapse

VARIANTS =

Placement only — never behaviour. :row tucks the grip into a table cell's existing left padding; :card floats it over the card's top-left corner, since a card has no spare gutter to hide it in.

{
  row: {grip: :drag_handle, disabled: :drag_handle_disabled},
  card: {grip: :drag_handle_card, disabled: :drag_handle_card_disabled}
}.freeze

Instance Method Summary collapse

Constructor Details

#initialize(sort_url: nil, variant: :row) ⇒ DragHandle

Returns a new instance of DragHandle.

Parameters:

  • sort_url (String, nil) (defaults to: nil)

    nil when dragging is live; otherwise the URL that puts the collection back into ascending position order.

  • variant (Symbol) (defaults to: :row)

    :row (table cell) or :card (grid card)



57
58
59
60
# File 'lib/plutonium/ui/table/components/drag_handle.rb', line 57

def initialize(sort_url: nil, variant: :row)
  @sort_url = sort_url
  @variant = VARIANTS.fetch(variant)
end

Instance Method Details

#view_templateObject



62
63
64
# File 'lib/plutonium/ui/table/components/drag_handle.rb', line 62

def view_template
  @sort_url ? render_disabled : render_grip
end