Refactor className and children to component properties instead och view model snapshots in shared components (#32711)

* Refactor className? to component property in EncryptionEventView

* Refactor extraClassNames to default react className as component property for DecryptionFailureBodyView

* Refactor className to component property for MessageTimestampView

* Refactor className and children to component properties for ReactionsRowButton

* Refactor className to component property for DisambiguatedProfile

* Refactor className to a component property in DateSeparatorView

* Fix for lint errors and EncryptionEventView unsupported icon color

* EncryptionEventView fix for icon color css specificity/order
This commit is contained in:
rbondesson
2026-03-05 09:36:45 +01:00
committed by GitHub
parent 1963f268aa
commit 83d732d60e
61 changed files with 232 additions and 255 deletions
@@ -18,12 +18,17 @@ import { useMockedViewModel } from "../../viewmodel/useMockedViewModel";
import { withViewDocs } from "../../../.storybook/withViewDocs";
type MessageTimestampProps = MessageTimestampViewSnapshot & MessageTimestampViewActions;
const MessageTimestampWrapperImpl = ({ onClick, onContextMenu, ...rest }: MessageTimestampProps): ReactNode => {
const MessageTimestampWrapperImpl = ({
onClick,
onContextMenu,
className,
...rest
}: MessageTimestampProps & { className?: string }): ReactNode => {
const vm = useMockedViewModel(rest, {
onClick,
onContextMenu,
});
return <MessageTimestampView vm={vm} />;
return <MessageTimestampView vm={vm} className={className} />;
};
const MessageTimestampWrapper = withViewDocs(MessageTimestampWrapperImpl, MessageTimestampView);
@@ -69,12 +74,6 @@ export const HasInhibitTooltip: Story = {
},
};
export const HasExtraClassNames: Story = {
args: {
className: "extra_class_1 extra_class_2",
},
};
export const HasHref: Story = {
args: {
href: "~",
@@ -21,7 +21,7 @@ import { MockViewModel } from "../../viewmodel/MockViewModel.ts";
import { I18nContext } from "../../utils/i18nContext.ts";
import { I18nApi } from "../../index.ts";
const { Default, HasHref, HasExtraClassNames } = composeStories(stories);
const { Default, HasHref } = composeStories(stories);
const renderWithI18n = (ui: React.ReactElement): ReturnType<typeof render> =>
render(ui, {
@@ -38,9 +38,16 @@ describe("MessageTimestampView", () => {
expect(container).toMatchSnapshot();
});
it("renders the message timestamp with extra class names", async () => {
const { container } = render(<HasExtraClassNames />);
expect(container).toMatchSnapshot();
it("applies custom className to the timestamp element", async () => {
const vm = new MockViewModel<MessageTimestampViewSnapshot>({
ts: "04:58",
tsSentAt: "Thu, 17 Nov 2022, 4:58:32 pm",
});
renderWithI18n(<MessageTimestampView vm={vm} className="extra_class_1 extra_class_2" />);
const target = screen.getByText("04:58");
expect(target).toHaveClass("extra_class_1", "extra_class_2");
});
it("renders the message timestamp with href", async () => {
@@ -32,10 +32,6 @@ export interface MessageTimestampViewSnapshot {
* If set to true then no tooltip will be shown
*/
inhibitTooltip?: boolean;
/**
* Extra class name to apply to the component
*/
className?: string;
/**
* If specified, will be rendered as an anchor bearing the href, a `span` element will be used otherwise
*/
@@ -55,6 +51,9 @@ export interface MessageTimestampViewActions {
/**
* The view model for the message timestamp.
*
* Snapshot data describes timestamp content and rendering behavior, while
* container styling is supplied via component props.
*/
export type MessageTimestampViewModel = ViewModel<MessageTimestampViewSnapshot> & MessageTimestampViewActions;
@@ -63,6 +62,10 @@ interface MessageTimestampViewProps {
* The view model for the message timestamp.
*/
vm: MessageTimestampViewModel;
/**
* Optional CSS class name to apply to the component.
*/
className?: string;
}
/**
@@ -70,17 +73,18 @@ interface MessageTimestampViewProps {
*
* The view model provides the timestamp values and display options. The component
* can render as a link when `href` is set, and can show both sent-at and received-at
* times in the tooltip when `tsReceivedAt` is provided.
* times in the tooltip when `tsReceivedAt` is provided. Use `className` for
* host-level styling.
*
* @example
* ```tsx
* <MessageTimestampView vm={messageTimestampViewModel} />
* <MessageTimestampView vm={messageTimestampViewModel} className="mx_MessageTimestamp" />
* ```
*/
export function MessageTimestampView({ vm }: Readonly<MessageTimestampViewProps>): JSX.Element {
export function MessageTimestampView({ vm, className }: Readonly<MessageTimestampViewProps>): JSX.Element {
const { translate: _t } = useI18n();
const { ts, tsSentAt, tsReceivedAt, inhibitTooltip, className, href } = useViewModel(vm);
const { ts, tsSentAt, tsReceivedAt, inhibitTooltip, href } = useViewModel(vm);
const onKeyDown = (event: KeyboardEvent<HTMLElement>): void => {
if (vm.onClick) {
@@ -12,18 +12,6 @@ exports[`MessageTimestampView > renders the message timestamp in default state 1
</div>
`;
exports[`MessageTimestampView > renders the message timestamp with extra class names 1`] = `
<div>
<span
aria-live="off"
class="extra_class_1 extra_class_2 content"
tabindex="0"
>
04:58
</span>
</div>
`;
exports[`MessageTimestampView > renders the message timestamp with href 1`] = `
<div>
<a