Files
blap/packages/shared-components/src/timeline/DateSeparatorView/DateSeparatorContextMenuView.tsx
T
rbondesson 11030ae68d Refactor DateSeparator using MVVM and move to shared-components (#32482)
* Refactor DateSeparator using MVVM and move to shared-components

* Add a few more stories, tests and screenshots

* Use the shared component and viewmodel in element-web

* Renaming custom content property an updating snapshots

* Fix lint errors and update snapshot after merge

* Change lifecycle handling for DateSeparatoreViewModel in components where manual handling is preferrable over wrapper component.

* Move context menu from viewmodel to shared components - step 1

* Create a jump to date picker component in shared components

* Add tests for coverage and fix layout issues and roving indexes

* Make element-web use the new component

* Simplify context menu and adjusting tests

* The HTMLExport now render shared components and need a I18nContext.Provider

* Updating unit tests for context menu

* Changed to {translate: _t} to let scripts pick up translations

* Fix lint issue and updating screenshots after merge

* Update snaps for element web components

* Renaming MVVM view components with suffix View.

* Fixing problem with input date calendar icon and system dark theme

* Changed the rendering of the menu and added a separate button component

* Handle input control with useRef in onKeyDown

* Updating DateSeparator snapshots on unit tests

* Updating layout after compound Menu got a className property

* Move files to new subfolder after merge

* Updated snapshot after merge

* Updating lock file

* Updates to styling from PR review

* Updates to focus/blur functionality

* Fixed tabbing and export documentation to stories

* Updated snapshots

---------

Co-authored-by: Zack <zazi21@student.bth.se>
2026-03-02 12:18:51 +00:00

96 lines
3.3 KiB
TypeScript

/*
* 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.
*/
import React, { type JSX, type PropsWithChildren, useRef } from "react";
import { Menu, MenuItem, Separator } from "@vector-im/compound-web";
import { capitalize } from "lodash";
import { useI18n } from "../../utils/i18nContext";
import { humanizeRelativeTime } from "../../utils/humanize";
import { type DateSeparatorViewModel } from "./DateSeparatorView";
import { DateSeparatorDatePickerView } from "./DateSeparatorDatePickerView";
import styles from "./DateSeparatorContextMenuView.module.css";
/**
* Props for DateSeparatorContextMenuView component.
*/
export interface DateSeparatorContextMenuViewProps {
/** The date separator view model. */
vm: DateSeparatorViewModel;
/** Whether the menu is open (controlled by the parent). */
open: boolean;
/** The element used as the menu trigger. */
trigger: React.ReactNode;
/** Called when the menu requests an open state change. */
onOpenChange?: (open: boolean) => void;
}
/**
* Date separator jump-to menu.
* Uses the wrapped child as the menu trigger.
*/
export const DateSeparatorContextMenuView: React.FC<PropsWithChildren<DateSeparatorContextMenuViewProps>> = ({
vm,
open,
trigger,
onOpenChange,
}): JSX.Element => {
const i18n = useI18n();
const { translate: _t } = useI18n();
const dateInputRef = useRef<HTMLInputElement>(null);
const onKeyDown = (event: React.KeyboardEvent<HTMLElement>): void => {
if (event.key !== "ArrowDown") return;
event.preventDefault();
dateInputRef.current?.focus();
};
return (
<Menu
open={open}
onOpenChange={(newOpen) => {
onOpenChange?.(newOpen);
}}
title={_t("room|jump_to_date")}
showTitle={false}
trigger={trigger}
align="start"
className={styles.picker_menu}
>
<MenuItem
label={capitalize(humanizeRelativeTime(i18n).format(-1, "week"))}
onSelect={() => vm.onLastWeekPicked?.()}
data-testid="jump-to-date-last-week"
hideChevron={true}
className={styles.picker_menu_item}
/>
<MenuItem
label={capitalize(humanizeRelativeTime(i18n).format(-1, "month"))}
onSelect={() => vm.onLastMonthPicked?.()}
data-testid="jump-to-date-last-month"
hideChevron={true}
className={styles.picker_menu_item}
/>
<MenuItem
label={_t("room|jump_to_date_beginning")}
onSelect={() => vm.onBeginningPicked?.()}
data-testid="jump-to-date-beginning"
hideChevron={true}
className={styles.picker_menu_item}
onKeyDown={onKeyDown}
/>
<Separator decorative className={styles.picker_separator} />
<DateSeparatorDatePickerView
vm={vm}
inputRef={dateInputRef}
onSubmitted={() => onOpenChange?.(false)}
onDismissed={() => onOpenChange?.(false)}
/>
</Menu>
);
};