Refactor MessageActionBar using MVVM and move to shared-components (#32784)

* Refactor MessageActionBar into MVVM ActionBarView

* Adding tooltips for menu items and correct i18n strings

* Layout changes

* Renaming some properties

* Rename property

* Create a first version of the view model and refactor media visibility logic

* Refactor view to take options and rections menu as optional properties

* Cleaner interface between view and view model

* Refactor view properties and replace Menu and MenuItem

* Bugfixes and switching to ActionBarView instead of MessageActionBar in element-web

* Avoid creating view models and render toolbar until it is actually shown

* Added unit and playwright tests and documented the view

* Added view model unit tests and updated snapshots of dependant tests

* Remove unused components and unnecessary css

* Remove unused language tags

* Fix for handling join-rules correctly

* Prettier

* Add handling of stale view model in async calls

* Prettier

* Split the element-web css into two different. One for legacy components and one for the ActionBarView

* Missing variables used for linting

* Fix for showing ActionBarView when using keyboard for navigation

* Handle visibility on context menu closing

* ThreadPanel uses the ActionBarView so restore css rule

* Fix for visibility of the ActionBarView in Thread panel

* Fix for ActionBarVuew visibility when closing right-click context menu and not still hovering

* Add roving index to function as a toolbar

* Adjust the RoomView test to send hover to the EventTile instead of the message text

* Fix SonarCloud issues

* Fix for SonarCloud issue

* Merge fix

* Rename mx_LegacyActionBar to mx_ThreadActionBar

* Added documentation and simplified join rules

* Generalize the ActionBarView and move logic to view model

* Add the four new buttons to the ActionBarView

* Update view model and tests to use the updated ActionBarView

* Refactor element-web to use ActionBarView

* Clean up styling in element-web

* Clean up and updating snaps and screenshots

* Added unit-tests for better coverage

* Moving ActionBarView to the correct folder in shared components

* Update snaps in element-web

* Better documentation in stories

* Merge fixes

* Updates after review comments

* Review comment fixes

* Added documentation to view models and updated snaps

* Hide button had the wrong label

* Replace createRef with useRef
This commit is contained in:
rbondesson
2026-04-01 12:27:03 +00:00
committed by GitHub
parent 0391543bbc
commit 4315038346
46 changed files with 4071 additions and 2155 deletions
+1
View File
@@ -238,6 +238,7 @@
@import "./views/messages/_ReactionsRow.pcss";
@import "./views/messages/_RoomAvatarEvent.pcss";
@import "./views/messages/_TextualEvent.pcss";
@import "./views/messages/_ThreadActionBar.pcss";
@import "./views/messages/_UnknownBody.pcss";
@import "./views/messages/_ViewSourceEvent.pcss";
@import "./views/messages/_common_CryptoEvent.pcss";
@@ -82,13 +82,11 @@ Please see LICENSE files in the repository root for full details.
}
}
.mx_MessageActionBar .mx_AccessibleButton {
display: flex;
align-items: center;
.mx_HistoryActionBar {
border-radius: 0 !important;
}
padding-inline-start: $spacing-8;
padding-inline-end: $spacing-8;
font-size: $font-15px;
.mx_HistoryActionBar [data-presentation="label"] {
line-height: 24px !important;
}
}
@@ -9,19 +9,8 @@ Please see LICENSE files in the repository root for full details.
.mx_MessageActionBar {
--MessageActionBar-size-button: 28px;
--MessageActionBar-size-margin: 3px;
--MessageActionBar-item-hover-background: var(--cpd-color-bg-subtle-secondary);
--MessageActionBar-item-hover-borderRadius: 6px;
--MessageActionBar-item-hover-zIndex: 1;
position: absolute;
visibility: hidden;
cursor: pointer;
display: flex;
gap: var(--cpd-space-0-5x);
line-height: $font-24px;
border-radius: 8px;
background: $background;
border: var(--cpd-border-width-1) solid var(--cpd-color-border-disabled);
top: calc(
-1 *
(
@@ -75,51 +64,4 @@ Please see LICENSE files in the repository root for full details.
left: 0;
}
}
> * {
white-space: nowrap;
display: inline-block;
position: relative;
margin: var(--MessageActionBar-size-margin);
&:hover {
background: var(--MessageActionBar-item-hover-background);
border-radius: var(--MessageActionBar-item-hover-borderRadius);
z-index: var(--MessageActionBar-item-hover-zIndex);
}
}
.mx_MessageActionBar_iconButton {
--MessageActionBar-icon-size: 20px;
width: var(--MessageActionBar-size-button);
height: var(--MessageActionBar-size-button);
color: var(--cpd-color-icon-secondary);
display: flex;
align-items: center;
justify-content: center;
svg {
height: var(--MessageActionBar-icon-size);
width: var(--MessageActionBar-icon-size);
flex: 0 0 var(--MessageActionBar-icon-size);
}
&:disabled,
&[disabled] {
cursor: not-allowed;
opacity: 0.75;
}
&:hover {
color: var(--cpd-color-icon-primary);
}
&.mx_MessageActionBar_downloadButton {
&.mx_MessageActionBar_downloadSpinnerButton {
svg {
display: none; /* hide the download icon */
}
}
}
}
}
@@ -0,0 +1,58 @@
/*
* Copyright 2026 Element Creations Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
* Please see LICENSE files in the repository root for full details.
*/
.mx_ThreadActionBar {
position: absolute;
visibility: hidden;
top: calc(-1 * (28px + 2 * (3px + var(--cpd-border-width-1))));
right: 8px;
user-select: none;
/* Ensure the action bar appears above other things like the read marker */
/* and sender avatar (for small screens) */
z-index: 10;
/* Adds a previous event safe area so that you can't accidentally hover the */
/* previous event while trying to mouse into the action bar or from the */
/* react button to its tooltip. */
&::before {
content: "";
position: absolute;
/* tooltip safe mousing area + tooltip overhang + */
/* action bar + action bar offset from event */
width: calc(10px + 48px + 100% + 8px);
/* safe area + action bar */
height: calc(20px + 100%);
top: -12px;
left: -58px;
z-index: -1;
cursor: initial;
/* stylelint-disable-next-line max-line-length */
.mx_GenericEventListSummary[data-layout="bubble"]
.mx_GenericEventListSummary_toggle
~ .mx_GenericEventListSummary_unstyledList
.mx_EventTile_info:first-of-type
& {
/* improve clickability of "collapse" link button on bubble layout by reducing width and height values */
/* mx_GenericEventListSummary_toggle ~: to apply rules to action bar when "collapse" button is available */
/* mx_EventTile_info:first-of-type: to apply rules to the info event tile just under "collapse" button */
/* TODO: use a new class name instead */
width: 100%;
height: 100%;
top: 0;
left: 0;
}
.mx_EventTile_info .mx_ViewSourceEvent ~ & {
/* improve clickability of view source event toggle button by removing vertical safe area */
width: 100%;
height: 100%;
top: 0;
left: 0;
}
}
}
+4 -4
View File
@@ -938,10 +938,10 @@ $left-gutter: 64px;
}
}
.mx_EventTile:hover .mx_MessageActionBar,
.mx_EventTile.mx_EventTile_actionBarFocused .mx_MessageActionBar,
[data-whatinput="keyboard"] .mx_EventTile:focus-within .mx_MessageActionBar,
.mx_EventTile:focus-visible:focus-within .mx_MessageActionBar {
.mx_EventTile:hover .mx_ThreadActionBar,
.mx_EventTile.mx_EventTile_actionBarFocused .mx_ThreadActionBar,
[data-whatinput="keyboard"] .mx_EventTile:focus-within .mx_ThreadActionBar,
.mx_EventTile:focus-visible:focus-within .mx_ThreadActionBar {
visibility: visible;
}