0
0
Fork 0
mirror of https://github.com/discourse/discourse.git synced 2026-08-06 13:08:40 +08:00
discourse/themes/horizon/scss/nav-pills.scss
Régis Hanol bb235b5540
UX: Add high context topic card layout option to Horizon theme (#36902)
## Summary

The existing column-based topic list API works well for simple layouts,
but becomes unwieldy when trying to create richer card designs. Adding
features like assigned users, vote counts, solved status, tags, and
excerpts to the grid system required increasingly complex CSS hacks and
left awkward empty spaces when optional elements weren't present.

This adds a new "high context" layout mode that takes a different
approach: instead of fighting the column system, we use the
topic-list-columns API to replace all columns with a single component
that has full control over its internal layout. This gives us the
flexibility to arrange content in logical rows (header, content,
context, footer) using simple flexbox, without the rigidity of the grid.

## Changes

### Horizon Theme

The new `topic_card_context` theme setting lets admins choose between:
- **Simple** - the existing compact layout
- **High Context (experimental)** - rich cards with additional
information

The high context cards display:
- Creator avatar and username with timestamp
- Solved/unsolved status pill (when discourse-solved is enabled)
- Hot/pinned status indicators
- Topic title with status icons
- Post excerpt
- Last reply info with relative timestamp
- Assigned users including post-level assignments (when discourse-assign
is enabled)
- Vote count badge (when discourse-topic-voting is enabled)
- Category badge and tags
- Reply and like counts
- Unread indicator and post badges

The layout is only applied to public topic list routes (discovery and
tag routes), falling back to simple layout on private messages, user
activity, and bookmarks pages.

### Core Changes

**BEM naming for topic status classes:**
- All status classes now use `--modifier` pattern: `--bookmarked`,
`--closed`, `--archived`, `--warning`, `--personal-message`, `--pinned`,
`--unpinned`, `--invisible`
- Updated discourse-solved plugin to use `--solved` and `--unsolved`

**Code cleanup:**
- Extracted duplicated bulk selection checkbox into reusable
`BulkSelectCheckbox` component
- Removed unused `newDotText` getter from topic-cell
- Added `className` parameter to `render-tags` helper for flexibility

---------

Co-authored-by: chapoi <101828855+chapoi@users.noreply.github.com>
2026-01-14 14:15:03 +01:00

64 lines
1.4 KiB
SCSS
Vendored

.list-controls {
position: sticky;
top: var(--header-offset);
background: var(--d-content-background);
z-index: z("base") + 1;
padding: 1rem 0 0 0;
max-width: unset;
border-top-left-radius: var(--d-border-radius-large);
border-top-right-radius: var(--d-border-radius-large);
.navigation-container {
gap: 1rem;
.category-breadcrumb {
order: 1;
}
}
.combo-box .combo-box-header {
// needs more specificity than just in the button file
background-color: var(--secondary);
border-radius: var(--d-border-radius);
border: 1px solid var(--primary-300);
&:hover {
border: 1px solid var(--accent-color);
}
&:focus-visible {
.discourse-no-touch & {
background: var(--secondary);
color: var(--accent-color);
box-shadow: 0 0 0 3px var(--button-box-shadow);
.d-icon {
color: var(--accent-color);
}
}
}
}
}
.select-kit.is-expanded .select-kit-body {
border-radius: var(--d-border-radius);
background-color: var(--d-content-background);
}
.nav-pills > li > a:hover,
.nav-pills > li button:hover {
.discourse-no-touch & {
background: transparent;
color: var(--d-nav-color--hover);
&::after {
content: "";
position: absolute;
left: 0;
bottom: 0;
right: 0;
height: var(--d-nav-underline-height);
background: var(--d-nav-color--hover);
}
}
}