Skip to content

Conversation

fvsch
Copy link
Contributor

@fvsch fvsch commented Jul 13, 2025

Header title UI issues

I started this as a follow-up to #3325 because it turns out that the improved target area of the back button was clipped on the left by an overflow: hidden on a container, as shown here:

Elk mobile view header showing the back button with its target area painted as a purple background. The left side of the button shows less padding than the right side.

As I looked into this, I found a few more issues with the layout of the left-side elements of the MainContent header (back button and/or title):

  1. There is the overflow: hidden issue as shown above. This can be fixed by reducing the padding on the header, removing this overflow: hidden if not needed, and using padding on the children (buttons and titles) instead.

  2. Most titles are clickable and have @click="$scrollToTop, but their target areas are a bit small because they have no padding, meaning that if you end up clicking just a bit above, below or at the right of the text (just left of the icon) then nothing happens. If these titles are treated as clickable buttons, they should follow general usability rules for buttons. This can be fixed with a bit of padding. Here's a before and after:

elk-header-title-area
  1. Titles are supposed to be truncated if they overflow, but it doesn't work. That's because the element containing the title, which inherit white-space: nowrap, are flex children with an initial style of min-width: auto, and here auto translates to the full width of the uninterrupted line of text. (A common fix is using min-width: 0 or some other small value for min-width.)
Screenshot of the Elk timeline header for the Federated Timeline view, on a narrow mobile screen, where the word Timeline is clipped at the middle and does not show the intended ellipsis dots.
  1. The styles for MainContent header titles are mostly duplicated across 20+ views. There is a shared timeline-title-style style that applies a few text styles, but all the structure and spacing (especially when there is an icon) is duplicated. This makes it challenging to evolve this style to modify the spacing or fix the truncation issue.

  2. There is duplicated logic as well, because most of the instances of the MainContent titles use @click="$scrollToTop", but a few don't, and when they don't it doesn't seem to be for a specific reason, so I suspect it could be an oversight.

Proposed refactoring with a new component

For all those reasons, I propose creating a shared component, tentatively named MainTitle (app/components/main/MainTitle.vue), which renders a timeline title with an optional icon, with appropriate spacing and truncation, and the scrollToTop behavior by default.

This creates a pretty big diff, but it's a straightforward refactor overall. The simpler usage looks like:

  <template #title>
-   <div timeline-title-style>{{ $t('some.title') }}</div>
+   <MainTitle>{{ $t('some.title') }}</MainTitle>
  </template>

When the title had an icon, we get:

  <template #title>
-   <div timeline-title-style flex items-center gap-2 cursor-pointer @click="$scrollToTop">
-     <div i-ri:some-icon />
-     <span>{{ t('some.title') }}</span>
-   </div>
+   <MainTitle icon="i-ri:some-icon">
+     {{ t('some.title') }}
+   </MainTitle>
  </template>

Finally, half the titles doubled as links, using NuxtLink. This is a bit more tricky to implement using a single component. One option would be to wrap <NuxtLink><MainTitle>{{ title }}</MainTitle></NuxtLink>, but I don't love the verbosity — or the unstyled <a> wrapper element, which could cause styling or layout issues. I opted for this pattern, which has limitations in terms of TypeScript autocompletions for props, and requires using RouterLink instead of NuxtLink for some reasons I cannot fathom:

  <template #title>
-   <NuxtLink to="/some/route" timeline-title-style flex items-center gap-2 cursor-pointer @click="$scrollToTop">
-     <div i-ri:some-icon />
-     <span>{{ t('some.title') }}</span>
-   </NuxtLink>
+   <MainTitle as="router-link" to="/some/route" icon="i-ri:some-icon">
+     {{ t('some.title') }}
+   </MainTitle>
  </template>

Outsanding questions

Can as="router-link" be inferred from props?

I tried only passing the to prop and then inferring the value of the is prop (<component :is="to ? 'router-link' : 'div'">), but it doesn't work and shows JS errors in the console.

Should the title be a H1?

  • Currently in the codebase it's usually a <span>, a <div> or a <a>, with only one instance where it's a <h1> (in one of the Settings views).
  • Defaulting to a H1 or H2 would be easy, but when the element is rendered as a router-link (i.e. as a <a> element) then we wouldn't have a title. This can be fixed by nesting elements a little bit, however.

Do we need the primary-vs-secondary styles?

Currently the header title colors are:

  • Orange (var(--c-primary)) for most views.
  • White (default color) for the titles used in the Settings sub-pages.

I implemented the white style for the settings sub-pages using a secondary?: boolean prop, but it could make sense to drop this style and just usage orange everywhere.

Should we harmonize the design of those titles and of the back button?

The icon for the header's back button and the new <MainTitle icon="foo" /> have similar sizes and spacing, and appear in the same place.

When we show either a back button or a <MainTitle> with an icon, things look pretty good and consistent.

One possible issue is when there is both a back button and a <MainTitle> in the header. Both the button and the title have padding, and end up spaced pretty far apart. See the difference between the title_icon ↔︎ title spacing (2 steps, i.e. 0.5rem) and the back_icon ↔︎title spacing (2x3 steps, i.e. 1.5rem).

It should be possible to harmonize both, possibly by folding the back button feature within the <MainTitle> component and turning it into a split button when there is both a back button and a title to display. Should we go with that, or is that too much of a change?

Copy link

netlify bot commented Jul 13, 2025

Deploy Preview for elk-zone ready!

Name Link
🔨 Latest commit 2554ed6
🔍 Latest deploy log https://app.netlify.com/projects/elk-zone/deploys/68b81f55511c8d0008027a34
😎 Deploy Preview https://deploy-preview-3331--elk-zone.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Copy link

netlify bot commented Jul 13, 2025

Deploy Preview for elk-docs canceled.

Name Link
🔨 Latest commit 2554ed6
🔍 Latest deploy log https://app.netlify.com/projects/elk-docs/deploys/68b81f55f6437400086ee992

@shuuji3 shuuji3 assigned shuuji3 and unassigned shuuji3 Jul 31, 2025
@shuuji3 shuuji3 self-requested a review July 31, 2025 05:41
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