Skip to content

Tables Styles ​

File Information ​

  • Path: app/assets/scss/components/_tables.scss
  • Purpose: Table/list view styles with columns, headers, and responsive design
  • Type: Component

Overview ​

Every list view in the portal (search results, folders, folder detail, collages, collage detail, sharing) is a .table-lists-view container with a .table-header row of .table-header-column cells and a .table-body of .table-list-item rows made of .table-body-column cells. Column width is never set per page: each column carries one minwNNN class and the breakpoints below decide what that class means.

Column width classes ​

The base value is a min-width floor in px plus a width in vw. From 1640px up the floor switches to vw so columns grow with the screen; below 1281px and 600px the floors shrink.

ClassBase (< 1640px)>= 1640px<= 1280.98px<= 599.98px
minw100min 100px, width 6vw8vw / 8vwunchangedunchanged
minw130min 130px, width 8vw10vw / 10vwunchangedunchanged
minw170min 170px, width 10vw12vw / 12vwmin 150pxmin 130px
minw200min 200px, width 12vw15vw / 15vwmin 170pxmin 150px
minw250min 250px, width 16vw20vw / 20vwmin 210pxmin 180px
minw300min 300px, width 20vw25vw / 25vwmin 260pxmin 220px
minw350min 350px, width 24vw30vw / 30vwmin 310pxmin 270px

"Matched In" column (minw170 match-column) ​

The search "Matched In" column uses minw170 match-column. The class pair comes from MATCH_COLUMN.minWidthClass in app/composables/core/common/useSearchUtils.ts and is hard-coded on the header and body cells in SearchBar.vue, SearchAssets.vue, SearchLibraryItems.vue, folders/[id]/index.vue and collage/[id]/index.vue. Each renders the column only when hasMatchColumn is true (at least one item has search_matches).

The 190px floor for this column lives inside @media (max-width: 1639.98px) (moved there in e3c490b; it used to sit in the base .minw170 rule). The effect:

ViewportMatch column min-widthWhy
>= 1640px12vw (from the minw170 wide rule)The 190px rule does not apply, so the column scales like any other minw170 column (12vw is at least 196.8px here).
1281px - 1639.98px190px.table-lists-view .minw170.match-column (3 classes) beats the base .minw170.
<= 1280.98px and <= 599.98px190pxThe narrower .minw170 overrides (150px, 130px) have only 2 classes, so the match-column rule still wins on specificity.

The match column therefore never shrinks below 190px on smaller screens, while other minw170 columns do.

Action column widths ​

The kebab/action column is sized by how many buttons it holds. Values depend on whether the list has .height-small:

Class.height-smalldefault
one_action68px72px
two_action108px116px
three_action148px160px
four_action188px204px

Action cells (.table-body-column.v-list-item-action) are right-aligned and the .optionIcon is hidden (opacity: 0, margin-right: -48px) until the row is hovered or its menu is open (aria-expanded="true"). Every non-action body cell gets cursor: pointer.

Rows, header and checkbox layout ​

  • Header: flex row, 16px side padding; a following .table-body gets height: calc(100% - 40px). Header cells are 14px bold, capitalized, padding: 8px 16px.
  • Body cells: min-height: 62px (52px at <= 1280.98px), padding: 0 16px.
  • Rows (.table-list-item) get a 1px border and small radius; hover and active states use the brand variables --primary-700 / --primary-100, so they follow the portal's branding colors.
  • .table-checkbox: first column is a 40px checkbox with no right padding and the second header column flexes; without .table-checkbox the first header column flexes.

Edge cases ​

  • Hover styling is skipped on .table-list-skeleton, but the :active rule is guarded by :not(.tableListSkeleton) (camelCase). No component uses tableListSkeleton, so skeleton rows still show the pressed border on click.
  • At <= 1280.98px a .horizontalScroll.table-lists-view keeps its header and body at min-width: 900px and scrolls sideways (4px scrollbar, thumb shown on hover), bleeding 24px right (16px at <= 960.98px). In the same range the row .optionIcon is always visible (opacity: 1, margin-right: 0) because touch screens have no hover to reveal it.
  • .brand-portal-listing sets the listing height to calc(100% - 64px), - 60px at <= 1280.98px and - 56px at <= 960.98px to match the header height at each breakpoint.