xiiui ← Update collab avatar indicator design by formfcw · Pull Request #27162 · directus/directus · GitHub
Skip to content

xiiui ← Update collab avatar indicator design#27162

Open
formfcw wants to merge 6 commits intoflorian/cms-2143-update-primary-header-actions-to-show-label-and-replacefrom
florian/cms-1943-update-avatar-design
Open

xiiui ← Update collab avatar indicator design#27162
formfcw wants to merge 6 commits intoflorian/cms-2143-update-primary-header-actions-to-show-label-and-replacefrom
florian/cms-1943-update-avatar-design

Conversation

@formfcw
Copy link
Copy Markdown
Contributor

@formfcw formfcw commented Apr 17, 2026

Scope

What's changed:

  • Make the CollabIndicatorHeader / CollabIndicatorField user-limit responsive instead of a fixed constant of 3. Extracted logic into a new useCollabIndicator composable that returns a limit of 4 (default) or 2 (small viewports / inline drawer contexts), and reserves a slot for the +N overflow avatar only when it is actually needed.
  • Remove the now-unused COLLAB_USERS_DISPLAY_LIMIT constant and the unreferenced .more-users CSS class from CollabIndicatorHeader.vue.
  • Promote the previously local labelMin (25rem) threshold to a shared xs: 28rem breakpoint, added in both constants.ts and _breakpoints.scss (kept in sync). PrivateViewHeaderBarActionButton now consumes the shared token instead of declaring its own.
  • Fix avatar sizing in comment-item-header.vue: replace flex-basis: 1.375rem (which clamped width) with flex-shrink: 0 (preserves natural size, still won't be squeezed).
  • Add a short JSDoc to useInjectHeaderBarInline clarifying its return value.

Potential Risks / Drawbacks

Tested Scenarios

  • Collab indicator in the header bar: 1, 2, 3, 4, 5+ concurrent users on wide screen (expect up to 4 + +N) and narrow screen / inline drawer (expect up to 2 + +N).
  • Collab indicator on a focused field (CollabIndicatorField): same user counts, same breakpoints.
  • Primary header action buttons around the xs / sm / lg thresholds — labels collapse to icons at the right widths, tooltip still appears in icon-only state.
  • Comment list item rendered with both short and very long author names — avatar stays x-small circular, doesn't compress.

Review Notes / Questions

  • Overflow logic changes: at userCount > limit we now render limit - 1 avatars + +N, which differs slightly from the previous "always render limit, then +N" behavior.

Checklist

  • Added or updated tests
  • Documentation PR created here or not required
  • OpenAPI package PR created here or not required

Addresses CMS-1943

formfcw added 5 commits April 17, 2026 23:20
Introduce shared `xs` breakpoint (28rem) in both the TS constants and
the SCSS mixin so components can target very narrow viewports without
hardcoding values.
Replace ad-hoc `labelMin: 25rem` breakpoint with the shared `xs`
breakpoint to drive label/icon switching.
Replace static COLLAB_USERS_DISPLAY_LIMIT constant with a
`useCollabIndicator` composable that adapts the visible avatar count to
viewport size and header-bar inline state. Also document the
`useInjectHeaderBarInline` return value.
Swap `flex-basis: 1.375rem` for `flex-shrink: 0` so the avatar keeps
its intrinsic size without being stretched by flex sizing.
@formfcw formfcw requested a review from AlexGaillard as a code owner April 17, 2026 21:36
@linear
Copy link
Copy Markdown

linear Bot commented Apr 17, 2026

…label-and-replace' into florian/cms-1943-update-avatar-design
Copy link
Copy Markdown
Contributor

@alvarosabu alvarosabu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice refactor @formfcw.

I believe we can abstract a lot of repeated logic into this use-collab-indicator with computed properties, cleaner and easy to maintain.

<template>
<div class="collab-field">
<template v-for="(user, index) in users.slice(0, COLLAB_USERS_DISPLAY_LIMIT)" :key="user.id">
<template v-for="(user, index) in users.slice(0, indicatorLimit)" :key="user.id">
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion:

Since you are passing down the users on L25, I would rather have a computed visibleUsers on the useCollabIndicator since its directly tied to the computed limit

// use-collab-indicator.ts
export function useCollabIndicator<T>(users: ComputedRef<T[]>) {
	// ...existing breakpoint logic...

	const indicatorLimit = computed(() => {
		const actualLimit = shouldDisplayMinimal() ? 2 : 4;
		if (users.value.length > actualLimit) return actualLimit - 1;
		return actualLimit;
	});

	const visibleUsers = computed(() => users.value.slice(0, indicatorLimit.value));

	return { indicatorLimit, visibleUsers };
}

Comment on lines +94 to +97
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Following https://github.com/directus/directus/pull/27162/changes#r3126614384 approach, you can have computed properties for all these

// use-collab-indicator.ts
const hiddenUsers = computed(() => users.value.slice(indicatorLimit.value));
	const overflowCount = computed(() => users.value.length - indicatorLimit.value);
	const hasOverflow = computed(() => overflowCount.value > 0);

And then the template becomes cleaner:

<template v-for="(user, index) in visibleUsers" :key="user.id">
<!-- ... -->
<VMenu v-if="hasOverflow">
  <template #activator="{ toggle }">
    <VAvatar>+{{ overflowCount }}</VAvatar>
  </template>
  <VList>
    <VListItem v-for="user in hiddenUsers" :key="user.connection">

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