List

Set up neatly-formatted lists of content in bordered rows with some additional optional decorations.


React Component

Default configuration

SageList is implemented most simply by passing the desired contents for the items through the SageList items property. This assumes that the contents of the list are already formatted as desired or you're outputting simple content values.

Sortable configuration

Sortable lists can be created with SageList by adding sortable: true and a sortable_resource. You can also pass a sortable_update_url for sorting callbacks to items that will be called after the user finishes sorting an item.

  1. Item Product lorem
  2. Item Product ipsum
  3. Item Product dolor sit
  4. Item Product amet
  5. Item Product vel aliquam

Fully draggable row

By default only the drag handle is active for dragging/sorting a row. However, drag_handle_type can be set to "row" in order to allow the whole row to be draggable instead.

  1. Item Product lorem
  2. Item Product ipsum
  3. Item Product dolor sit
  4. Item Product amet
  5. Item Product vel aliquam

Compositional approach

If you need more native content formatting you can instead opt to render items using a nested loop and the SageListItem component. Note that this example also implements the Reveal utility class.

  1. Product lorem

    Item 1 specs

  2. Product ipsum

    Item 2 specs

  3. Product dolor sit

    Item 3 specs

  4. Product amet

    Item 4 specs

  5. Product vel aliquam

    Item 5 specs

Sage Component

SageList
<%
def dropdown_items(id)
  sample_product_actions = [
    {
      slug: "duplicate",
      name: "Duplicate",
    },
    {
      slug: "archive",
      name: "Archive",
    },
    {
      slug: "stats",
      name: "View stats",
    },
    {
      slug: "delete",
      name: "Delete permanently",
      style: "danger",
    }
  ].map do | action |
    {
      attributes: {
        href: "#action/#{action[:slug]}/#{id}",
      },
      style: action[:style] || nil,
      value: action[:name],
    }
  end
end

sample_products = [
  {
    id: 1,
    name: 'Product lorem',
  },
  {
    id: 2,
    name: 'Product ipsum',
  },
  {
    id: 3,
    name: 'Product dolor sit',
  },
  {
    id: 4,
    name: 'Product amet',
  },
  {
    id: 5,
    name: 'Product vel aliquam',
  }
]
%>

<h3 class="<%= SageClassnames::TYPE::HEADING_6 %>">Default configuration</h3>
<%= md("
`SageList` is implemented most simply by passing the desired contents for the items through the `SageList` `items` property.
This assumes that the contents of the list are already formatted as desired or you're outputting simple content values.
", use_sage_type: true) %>

<%= sage_component SageList, {
  items: sample_products.map { | item | {
      content: "Item #{item[:name]}",
      id: "example-default-item-#{item[:id]}",
      more_actions: { items: dropdown_items(item[:id]) },
    }
  },
} %>

<h3 class="<%= SageClassnames::TYPE::HEADING_6 %>">Sortable configuration</h3>
<%= md("
Sortable lists can be created with `SageList` by adding `sortable: true` and a `sortable_resource`.
You can also pass a `sortable_update_url` for sorting callbacks to items
that will be called after the user finishes sorting an item.
", use_sage_type: true) %>

<%= sage_component SageList, {
  sortable: true,
  sortable_resource: "sample_products",
  items: sample_products.map { | item | {
      content: "Item #{item[:name]}",
      id: "example-sortable-item-#{item[:id]}",
      more_actions: { items: dropdown_items(item[:id]) },
      sortable_update_url: "#sortable-update-url?item=#{item[:id]}",
    }
  },
} %>

<h3 class="<%= SageClassnames::TYPE::HEADING_6 %>">Fully draggable row</h3>
<%= md('
By default only the drag handle is active for dragging/sorting a row.
However, `drag_handle_type` can be set to `"row"` in order to allow the whole row to be draggable instead.
', use_sage_type: true) %>

<%= sage_component SageList, {
  sortable: true,
  sortable_resource: "sample_products_2",
  items: sample_products.map { | item | {
    content: "Item #{item[:name]}",
    id: "example-fully-draggable-item-#{item[:id]}",
    more_actions: { items: dropdown_items(item[:id]) },
    sortable_update_url: "#sortable-update-url?item=#{item[:id]}",
  }},
  drag_handle_type: "row",
} %>

<h3 class="<%= SageClassnames::TYPE::HEADING_6 %>">Compositional approach</h3>
<%= md("
If you need more native content formatting you can instead opt to render items using a nested loop and the `SageListItem` component.
Note that this example also implements the [Reveal utility class](#{pages_helpers_path(:reveal)}).
", use_sage_type: true) %>

<%= sage_component SageList, {
  sortable: true,
  sortable_resource: "sample_products_3",
  drag_handle_type: "row",
} do %>
  <% sample_products.each do | item | %>
    <%= sage_component SageListItem, {
      id: "example-default-item-#{item[:id]}",
      more_actions: { items: dropdown_items(item[:id]) },
      sortable_update_url: "#sortable-update-url?item={item[:id]}",
      css_classes: SageClassnames::REVEAL_CONTAINER,
    } do %>
      <%= sage_component SageCardRow, { grid_template: "ete" } do %>
        <img src="https://source.unsplash.com/random/240x160?v=<%= item[:id] %>" width="64" alt="" />
        <%= sage_component SageCardBlock, {} do %>
          <h4><%= item[:name] %></h4>
          <p>Item <%= item[:id] %> specs</p>
        <% end %>
        <%= sage_component SageButtonGroup, {
          gap: :md,
          css_classes: SageClassnames::REVEAL_ON_CONTAINER_HOVER
        } do %>
          <%= sage_component SageButton, {
            value: "Preview",
            style: "secondary",
            subtle: true,
            icon: { name: "preview-on", style: "only" }
          } %>
          <%= sage_component SageButton, {
            value: "Edit",
            style: "secondary",
            subtle: true,
            icon: { name: "pen", style: "only" }
          } %>
        <% end %>
      <% end %>
    <% end %>
  <% end %>
<% end %>
Property Description Type Default

SageList (container)

items

Provide the set of items to render within the list.

See schema for SageListItem below.

[]

drag_handle_type

By default only the drag handle is active for dragging/sorting a row. However, drag_handle_type can be set to "row" in order to allow the whole row to be draggable instead.

"default" | "row"

"default"

sortable_resource

Provide the resource name for a sortable list. Required only when sortable is activated for any child items

String

nil

SageListItem

id

Unique identifier for the list item.

String

nil

more_actions

Optional set of actions to appear in a dropdown at the end of the row.

See schema for SageDropdown

nil

sortable

Whether or not to show a sortable drag handle on this row.

Boolean

false

sortable_update_url

If sortable is true we attempt to call a URL when this sortable is dragged to a new position. Provide the desired URL here.

String

nil