Skip to content

Conversation

@ZacksBot
Copy link
Member

@ZacksBot ZacksBot commented Jan 20, 2026

Checklist

Refactor TimelineSeparator to shared-components

Summary

  • Moved TimelineSeparator component to @element-hq/web-shared-components package as TimelineSeparatorView
  • Adopted the ViewModel pattern (MVVM) for the component, introducing TimelineSeparatorViewSnapshot interface
  • Moved SeperatorKind from TimelineSeparator to MessagePanel.tsx

Changes

New shared component

Added TimelineSeparatorView under packages/shared-components/src/message-body/TimelineSeparator/ with:

  • View component using useViewModel hook
  • CSS module for styling
  • Storybook stories for visual testing
  • Unit tests with snapshot coverage

Codebase migration

  • MessagePanel.tsx: Updated late event separator to use TimelineSeparatorView
  • DateSeparator.tsx: Now renders TimelineSeparatorView instead of the old component
  • CreationGrouper.tsx / MainGrouper.tsx: Updated SeparatorKind imports to use MessagePanel.tsx

Test plan

  • Verify timeline separators render correctly in rooms
  • Verify date separators display proper labels (Today, Yesterday, dates)
  • Verify late event separators appear when expected
  • Run existing unit tests: npm test -- --testPathPatterns="TimelineSeparatorView" -u
  • Check Storybook stories render correctly

Tests

image image image

Before & After

  • Before Refactoring
image
  • After Refactoring
image

@ZacksBot ZacksBot requested a review from a team as a code owner January 20, 2026 08:33
@CLAassistant
Copy link

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@github-actions github-actions bot added the Z-Community-PR Issue is solved by a community member's PR label Jan 20, 2026
Copy link
Member

@florianduros florianduros left a comment

Choose a reason for hiding this comment

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

Good first PR!

The PR is missing the view model. MockedViewModel is only for testing. We should create new view model class for TimelineSeparator

ZacksBot and others added 10 commits January 20, 2026 12:35
…index.ts

Co-authored-by: Florian Duros <florian.duros@ormaz.fr>
…TimelineSeparatorView.module.css

Co-authored-by: Florian Duros <florian.duros@ormaz.fr>
…TimelineSeparatorView.tsx

Co-authored-by: Florian Duros <florian.duros@ormaz.fr>
…TimelineSeparatorView.test.tsx

Co-authored-by: Florian Duros <florian.duros@ormaz.fr>
…TimelineSeparatorView.stories.tsx

Co-authored-by: Florian Duros <florian.duros@ormaz.fr>
…TimelineSeparatorView.tsx

Co-authored-by: Florian Duros <florian.duros@ormaz.fr>
Comment on lines +44 to +50
* TimelineSeparatorView component renders a visual separator inside the message timeline.
* It draws horizontal rules with an accessible label and optional children rendered between them.
*
* @param label the accessible label string describing the separator (used for `aria-label`)
* @param children optional React nodes to render between the separators
*
*/
Copy link
Member Author

Choose a reason for hiding this comment

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

@florianduros Does this look better? If not, what do you suggest?


.timelineSeparator {
clear: both;
margin: var(--cpdSpace1X, var(--cpdSpace0X));
Copy link
Member Author

Choose a reason for hiding this comment

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

Like this?

/**
* Optional children to render inside the timeline separator
*/
children?: PropsWithChildren["children"];
Copy link
Member Author

Choose a reason for hiding this comment

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

Would it be fine using ["children"];


// Keep mx_TimelineSeparator to support the compatibility with existing timeline and the all the layout
return (
<div className={classNames("mx_TimelineSeparator", styles.timelineSeparator)} role="separator" aria-label={label}>
Copy link
Member Author

Choose a reason for hiding this comment

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

{classNames("mx_TimelineSeparator", styles.timelineSeparator)}

I would like to hear your opinion regarding this, this is like to comment says, to "Keep mx_TimelineSeparator to support the compatibility with existing timeline and the all the layout"

…Children for improved type safety of children
Comment on lines +346 to +354
interface TimeLineSeperatorBodyWrapper {
label: string;
children?: ReactNode;
}

function TimeLineSeperatorBodyWrapper({ label, children }: TimeLineSeperatorBodyWrapper): JSX.Element {
const dateSeperatorVM = useCreateAutoDisposedViewModel(() => new TimelineSeparatorViewModel({ label, children }));
return <TimelineSeparatorView vm={dateSeperatorVM} />;
}
Copy link
Member Author

Choose a reason for hiding this comment

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

Can these be placed at the bottom? I found a similar file where these were located at the bottom, which is why I placed them there. I suggest moving them up and adding a comment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

T-Task Tasks for the team like planning Z-Community-PR Issue is solved by a community member's PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants