## Summary
This PR adds the `lingui/no-unlocalized-strings` ESLint rule to detect
untranslated strings and fixes translation issues across multiple
components.
## Changes
### ESLint Configuration (`eslint.config.react.mjs`)
- Added comprehensive `ignore` patterns for non-translatable strings
(CSS values, HTML attributes, technical identifiers)
- Added `ignoreNames` for props that don't need translation (className,
data-*, aria-*, etc.)
- Added `ignoreFunctions` for console methods, URL APIs, and other
non-user-facing functions
- Disabled rule for debug files, storybook, and test files
### Components Fixed (~19 files)
- Object record components (field inputs, pickers, merge dialogs)
- Settings components (accounts, admin panel)
- Serverless function components
- Record table and title cell components
## Status
🚧 **Work in Progress** - ~124 files remaining to fix
This PR is being submitted as draft to allow progressive fixing of
remaining translation issues.
## Testing
- Run `npx eslint "src/**/*.tsx"` in `packages/twenty-front` to check
remaining issues
## Description
Fixed the height of the options menu button in the side panel footer to
be 24px instead of 32px, matching the height of other buttons in the
footer.
## Changes
- Added `size="small"` prop to the `Button` component in
`OptionsDropdownMenu.tsx`
- This ensures consistent button sizing across the side panel footer
## Before
The options menu button was 32px high (medium size), making it larger
than other footer buttons.
<img width="543" height="421" alt="image"
src="https://github.com/user-attachments/assets/3c4fdfd0-73d1-4884-a639-3382090dfe15"
/>
## After
The options menu button is now 24px high (small size), consistent with
other side panel footer buttons.
<img width="1000" height="824" alt="CleanShot 2025-11-26 at 18 50 43@2x"
src="https://github.com/user-attachments/assets/798e7975-a7a8-4c00-b2e7-c0d1261249f8"
/>
## Widget duplication
- Created a shared component for the option menu shared by the record
page, the dashboards and the workflows
- Fix arrow selection in the option menu in workflows, which wasn't
working
- Scroll to the new widget after creation and open the new widget
settings
https://github.com/user-attachments/assets/47b8dade-44bd-4ba2-a81c-01b09e8718d3
[Figma
Design](https://www.figma.com/design/xt8O9mFeLl46C5InWwoMrN/Twenty?node-id=81380-344641&t=FpjWNOK2gZuDQQfr-0)
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> Adds a side panel layout for the Command Menu, routes modals into a
local container, updates the top bar and context chips, and standardizes
small button sizes.
>
> - **Command Menu**:
> - **Side Panel Layout**: Introduces `CommandMenuSidePanelLayout` with
animated width, hosts `CommandMenuRouter`, and provides a modal
container via `ModalContainerContext`.
> - **Top Bar**: Redesign (`CommandMenuTopBar`) with back icon, optional
AI sparkles action, compact height
(`COMMAND_MENU_SEARCH_BAR_HEIGHT=40`), and updated placeholder.
> - **Context Chips**: Adds `CommandMenuLastContextChip` and
`CommandMenuRecordInfo`; extends `CommandMenuContextChip` with `page`
prop; updates `CommandMenuContextChipGroups` to render last chip as
record info when applicable.
> - **Container Simplification**: `CommandMenuContainer` simplified to
just provide contexts and `AgentChatProvider`.
> - **Modal System**:
> - Adds `ModalContainerContext` and updates `Modal` to portal into
provided container; `Modal.Backdrop` supports `isInContainer`.
> - Updates usages (e.g., `UserOrMetadataLoader`, `ActionModal`) to
align with new modal behavior.
> - **Page Integration**:
> - Replaces `PageBody` with `CommandMenuSidePanelLayout` in
`RecordShowPage` and `RecordIndexContainerGater`.
> - Removes global `CommandMenuRouter` from `DefaultLayout` (keeps
keyboard shortcuts).
> - **UI/Styling**:
> - Standardizes several buttons to `size="small"` (e.g., command
actions, open record, options, reply, workflow footer).
> - Adjusts `ShowPageSubContainer` styling when rendered inside command
menu.
> - Storybook tests updated for new placeholder text.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
81fcaa145618a2fa1c3e11e2dc88fe832c51374c. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
---------
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
Co-authored-by: Devessier <baptiste@devessier.fr>
Co-authored-by: Aman Raj <92664006+araj00@users.noreply.github.com>
Co-authored-by: Etienne <45695613+etiennejouan@users.noreply.github.com>
Co-authored-by: Paul Rastoin <45004772+prastoin@users.noreply.github.com>
# Complete color refactoring
Closes https://github.com/twentyhq/core-team-issues/issues/1779
- Updated all colors to use Radix colors with P3 color space allowing
for brighter colors
- Created our own gray scale interpolated on Radix's scale to have the
same values for grays as the old ones in the app
- Introduced dark and light colors as well as there transparent versions
- Added many new colors from radix that can be used in the tags or in
the graphs
- Updated multiple color utilities to match new behaviors
- Changed the computation of Avatar colors to return only colors from
the theme (before it was random hsl)
These changes allow the user to use new colors in tags or charts, the
colors are brighter and with better contrast. We have a full range of
color variations from 1 to 12 where before we only had 4 adaptative
colors.
All these changes will allow us to develop custom themes for the user
soon, where users can choose their accent colors, background colors and
there contrast.
## Overview
This PR fixes instances where `height` properties were incorrectly
defined multiple times within the same styled component definitions
across the codebase.
## Problem
Several styled components had duplicate `height` CSS properties where
the exact same property was declared twice in the same selector, causing
confusion and reducing code maintainability. The second declaration
would override the first, making the first one dead code.
## Changes
Fixed 4 files across the codebase:
### Duplicate `height: 100%` Removed
**StyledShowPageRightContainer** in twenty-front:
- `PageLayoutRendererContent.tsx`
- `ShowPageSubContainer.tsx`
- `PageLayoutRecordPageRenderer.tsx`
Each had `height: 100%` declared twice in the same component definition
(strict duplicates).
### Duplicate `height` with Different Values Removed
**StyledCommandKey** in twenty-ui:
- `MenuItemHotKeys.tsx` - Had both `height: ${({ theme }) =>
theme.spacing(5)}` and `height: 18px` declared. Removed the first
declaration as the second was overriding it.
## Testing
- ✅ ESLint checks pass
- ✅ TypeScript compilation successful
- ✅ CodeQL security analysis - no issues
- ✅ Comprehensive codebase scan confirms no remaining strict height
duplicates
## Impact
- **Visual Changes**: None - purely cleanup refactoring
- **Performance**: No runtime impact
- **Breaking Changes**: None
- **Code Quality**: Improved CSS maintainability by removing dead code
---
**Total:** 4 files modified, 5 lines removed
Created from VS Code via the <a
href="https://marketplace.visualstudio.com/items?itemName=GitHub.vscode-pull-request-github">GitHub
Pull Request</a> extension.
<!-- START COPILOT CODING AGENT SUFFIX -->
<details>
<summary>Original prompt</summary>
> Hi! It seems that a few styled components in the #codebase are defined
with duplicate `height: 100%`, like in
#file:PageLayoutRendererContent.tsx:27-36.
>
> Your job is to find all the places where we defined `height: 100%`
incorrectly several times and to keep only one `height` property.
</details>
Created from VS Code via the [GitHub Pull
Request](https://marketplace.visualstudio.com/items?itemName=GitHub.vscode-pull-request-github)
extension.
<!-- START COPILOT CODING AGENT TIPS -->
---
💡 You can make Copilot smarter by setting up custom instructions,
customizing its development environment and configuring Model Context
Protocol (MCP) servers. Learn more [Copilot coding agent
tips](https://gh.io/copilot-coding-agent-tips) in the docs.
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Devessier <29370468+Devessier@users.noreply.github.com>
Co-authored-by: Baptiste Devessier <baptiste@devessier.fr>
## Summary
Clean up and consolidate formatting configuration across the monorepo.
## Changes
### 1. Remove Redundant Configs
- ❌ Delete `packages/twenty-server/.prettierrc` (had invalid
`brakeBeforeElse` typo)
- ❌ Delete `packages/twenty-zapier/.prettierrc`
- ✅ Use root `.prettierrc` only (Prettier searches up directory tree
automatically)
### 2. Improve Root Prettier Config
- Change `endOfLine: 'auto'` → `'lf'` for consistent Unix line endings
across all OSes
### 3. Enhance VSCode Settings
- `files.eol: 'auto'` → `'\\n'` (consistent with Prettier)
- Add `files.insertFinalNewline: true` (explicit editor behavior)
- Add `files.trimTrailingWhitespace: true` (cleaner files)
### 4. Add `.gitattributes`
- Enforce LF line endings at Git level
- Prevents `core.autocrlf` from converting based on contributor's OS
- Mark patch files as binary (they have mixed line endings by design)
- Explicitly define binary file types
### 5. Fix Line Endings
- Convert 3 selectable-list state files from CRLF → LF
- These were the only source files with Windows line endings
## Why These Changes Matter
**Before:**
- 3 different Prettier configs (inconsistent, one had typo)
- Mixed CRLF/LF depending on contributor's OS
- No Git-level enforcement
**After:**
- Single source of truth for formatting
- All files use LF (Unix standard)
- Git enforces line endings regardless of OS
- Prettier warning about invalid option removed
## Result
- ✅ Single `.prettierrc` config
- ✅ Consistent LF line endings enforced by Git
- ✅ Better VSCode defaults
- ✅ No more CRLF files sneaking in from Windows contributors
This PR determines the minimal setup required to render dashboards
without errors while extracting them from the record show page. The
ultimate goal is to create a `PageLayoutRenderer` component that takes
any page layout configuration and correctly renders dashboards or record
pages.
Currently, the `DashboardCard` component renders itself the
`PageLayoutRenderer` component. The next step is to reverse the flow of
control and make `PageLayoutRenderer` take a configuration and decide
whether it should render a dashboard or something else.
This PR takes into consideration two comments left by Charles on [the
first PR scaffolding the
refactor](https://github.com/twentyhq/twenty/pull/15021): renaming
`targetRecord` to `targetRecordIdentifier` and adding tests to
`evaluateTabVisibility()`.
## Demo to assert this PR doesn't break everything
https://github.com/user-attachments/assets/b5b99cf3-08fa-43d3-8da1-79018bc63641
## Refactor: Prepare frontend record layouts for backend-driven
configuration
This PR simplifies and prepares the frontend record layout system for
eventual migration to backend-driven layouts, aligning the architecture
with the existing PageLayout system used for dashboards.
### Key Changes
**Architecture Improvements:**
- Created unified LayoutRenderingContext that works for both record
pages (with targetRecord) and dashboards (standalone)
- Replaced prop drilling with context-based data flow - cards access
targetRecord and isInRightDrawer via context hooks
- Introduced useTargetRecord() helper hook that provides type-safe
access to the current record
- Created generic CardRenderer component that handles configuration
injection and context guards uniformly
**Configuration System:**
- Converted all tab icons from React components to JSON-serializable
strings (e.g., Icon: IconCheckbox → icon: 'IconCheckbox')
- Added configuration field to cards, matching the widget configuration
pattern on the backend
- Created CardConfiguration types system similar to WidgetConfiguration
on the backend
- Moved widget-specific props (like showDuplicatesSection) into
configuration objects
**Code Organization:**
- Extracted visibility evaluation logic into reusable
evaluateTabVisibility() utility
- Organized layouts into dedicated files (one per object:
base-record-layout.ts, company-record-layout.ts, etc.)
- Renamed components to match their purpose: Notes → NotesCard,
Attachments → FilesCard, etc.
- Consolidated card rendering from registry object to direct
getCardComponent() function
**API Alignment:**
- Made ifNoReadPermissionObject an explicit part of TabVisibilityConfig
(follows if* naming convention)
- Removed redundant targetObjectNameSingular from tab-level (now derived
from visibility config)
- Card API now mirrors Widget API (both use type, configuration,
accessed via context)
This PR essentially refactors some hard-coded values for width and
height in the table.
It also fixes a few differences from the Figma design, on the checkbox
column width and the top bar and view bar left alignment with the table.
The blue color has been set like before the refactor of the focus portal
(`theme.adaptiveColors.blue4`)
Fixes in https://github.com/twentyhq/core-team-issues/issues/1490 :
- Fix first drag and drop column width that has changed from main (see
Figma)
- Unify all widths, heights, z-index, etc. with constants
- Put same blue as before for focused portal
Also removed `focus-active` class because we now use a portal for the
focus.
In this PR:
- Refactored the page layout renderer
- Converted all the states to component states
- Removed the page layout edition in settings
TODOs in next PRs:
- Fix bug with the drag selector not taking the scroll into account to
display the dragged area
- Readd the tab edition in edit mode
## Problem
**CRITICAL:** Two PRs were accidentally reverted when PR #14347 "Prevent
csv export injections" was merged:
1. **PR #14348** "[Page Layout] - Review Refactor" - ✅ **RESTORED**
2. **PR #14352** "Fix wrong path used by backend" - ✅ **RESTORED**
## Root Cause Analysis
During the merge of PR #14347, there was a complex merge conflict with
PR #14352 "Fix wrong path used by backend". The merge commit
`324d7204bb` in the PR #14347 branch brought in changes from PR #14352,
but during the conflict resolution, **BOTH PR #14348 and PR #14352's
changes were accidentally overwritten**.
## What This PR Restores
This PR restores **BOTH** PRs by cherry-picking their commits:
### ✅ PR #14348 Changes Restored:
- `GraphWidgetRenderer.tsx` - was deleted, now restored
- `WidgetRenderer.tsx` - was missing, now restored
- `SettingsPageLayoutTabsInstanceId.ts` - was deleted, now restored
- `useUpdatePageLayoutWidget.ts` - was renamed back, now restored with
correct name
- Multiple test files that were deleted
- Several hook files that were renamed/reverted
- File renames: `usePageLayoutWidgetUpdate.ts` →
`useUpdatePageLayoutWidget.ts`
- Hook refactoring and test file organization
- Page layout component improvements
### ✅ PR #14352 Changes Restored:
- **Types moved to twenty-shared:**
- `packages/twenty-shared/src/types/AppBasePath.ts` ✅ RESTORED
- `packages/twenty-shared/src/types/AppPath.ts` ✅ RESTORED
- `packages/twenty-shared/src/types/SettingsPath.ts` ✅ RESTORED
- **Navigation utilities moved to twenty-shared:**
- `packages/twenty-shared/src/utils/navigation/getAppPath.ts` ✅ RESTORED
- `packages/twenty-shared/src/utils/navigation/getSettingsPath.ts` ✅
RESTORED
- **200+ import statements updated** across the codebase to use
twenty-shared
- **Old type files deleted** from twenty-front/src/modules/types/
## Evidence of Complete Restoration
**Before (reverted state):**
- ❌ Types were in `packages/twenty-front/src/modules/types/`
- ❌ Page layout files missing
- ❌ Hook files incorrectly named
**After (this PR):**
- ✅ Types correctly in `packages/twenty-shared/src/types/`
- ✅ All page layout files restored
- ✅ Hook files correctly named
- ✅ All import statements updated
## Verification
**Total changes:**
- PR #14348: 36 files changed, 863 insertions(+), 442 deletions(-)
- PR #14352: 243 files changed, 492 insertions(+), 461 deletions(-)
- **Combined: 279 files changed, 1355 insertions(+), 903 deletions(-)**
## Impact
This completely restores both PRs that were accidentally lost, ensuring:
1. Page layout refactoring work is back
2. Type organization and path utilities are correctly in twenty-shared
3. Backend email paths work correctly again
4. No functionality is lost
Fixes the reversion caused by the merge conflict in PR #14347.
---------
Co-authored-by: nitin <142569587+ehconitin@users.noreply.github.com>
**Small Security Issue:** CSV exports were vulnerable to formula
injection attacks when users entered values starting with =, +, -, or @.
(only happens if a logged-in user injects corrupted data)
Solution:
- Added ZWJ (Zero-Width Joiner) protection that prefixes dangerous
values with invisible Unicode character
- This is the best way to preserve original data while preventing Excel
from executing formulas
- Added import cleanup to restore original values when re-importing
Changes:
- New sanitizeValueForCSVExport() function for security
- Updated all CSV export paths to use both security + formatting
functions
- Added comprehensive tests covering attack vectors and international
characters
- Also added cursor rules for better code consistency
---------
Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
After moving a section on the frontend, this broke the path that was
sent by email on the backend.
This kind of error comes back every ~2-3 month under different forms so
we need a more robust solution: I moved routes to the shared folder,
that way we will share one common source of truth between the frontend
and the backend.
Fixes#14343
The goal of this PR is to test if Twenty can support a large number of
members, a question which was raised by a large company that is
considering moving away from Salesforce.
I was expecting the currentWorkspaceMembersState to cause a lot more
issue. It would be very hard to get rid of it in the context of actors,
I think that would require a big refactoring. I thought we'd have to do
it but it turns out the perf are pretty good. One thing we need to
improve is the pagination on the roles page, we'll wait for @Bonapara to
update that
This PR prepares the refactor of record field definition and column
definition.
We need to separate the two concepts of FieldInput and FieldContext at
the cell level, and the new RecordField concept that will replace
FieldDefinition at the metadata and state level.
So we create a new ui sub-folder in the already existing record-field
folder, in order to separate those two concepts that are still very
close.
This PR removes any V2 naming in state management logic and some minor
utils and hooks.
It has a lot of changes but nearly all of them were made by the rename
functionality of vscode which is deterministic, so it shouldn't
introduce any regression.
QA has been made on this PR on the main features of the app without any
noticeable issue.
Also renamed some other v2 naming related items :
- TextInputV2 => TextInput
- TextInput => SettingsTextInput
- ObjectFilterDropdownFilterSelectMenuItemV2 =>
ObjectFilterDropdownFilterSelectMenuItem
- useInitDraftValueV2 => useInitDraftValue
- useOpenRecordTableCellV2 => useOpenRecordTableCell
This PR implements what's needed to edit field permissions on a role.
Field permissions that aren't useful are kept in the database to avoid
the overhead of adding cleaning logics both in front end and back end.
They just won't be taken into account if object permission doesn't allow
it.
In this PR we also handle the case were there's no object permission
override but where there are only field permission overrides, which can
happen if an object inherits from a "all object can read" but restricts
read only on some fields.
<img width="547" height="642" alt="image"
src="https://github.com/user-attachments/assets/77d81f89-4af9-42b6-97f3-fae3a6ba1eeb"
/>
<img width="590" height="912" alt="image"
src="https://github.com/user-attachments/assets/69fab8ee-7252-401a-bc6f-8a8b7c7f6bc4"
/>
Fixes https://github.com/twentyhq/core-team-issues/issues/1152
This PR lowers unit test coverage because the essential unit tests for
this PR have been written and writing more tests would not be a great
tradeoff for this feature which has already taken a lot of efforts.
This PR removes every legacy state management logic left in the code
base, we only keep our last component state management logic.
Removed :
- Scoped states logic
- Dropdown scope logic
- Scope id naming
- Component state v1
- Component state v2_alpha
# QA
| Component | Comments |
| --- | --- |
| AttachementDropdown | Ok |
| ObjectTasks | Ok |
| ActivityRichTextEditor | Ok |
| App | Ok dialogs work |
| AppRouterProviders | Ok dialogs work |
| RecordBoardScrollToFocusedCardEffect | Ok |
| RecordBoard | Ok |
| RecordBoardCard | OK |
| useSelectAllCards | Ok |
| RecordInlineCell | Ok |
| useInlineCell | Ok |
| RecordDetailRelationRecordsListItem | Ok |
| RecordDetailRelationSectionDropdownToMany | Ok |
| RecordDetailRelationSectionDropdownToOne | Ok |
| useHandleContainerMouseEnter | Ok |
| useResetTableRowSelection | Ok |
| useSelectAllRows | Ok |
| useSetRecordTableData | Ok |
| useRecordTable | Ok |
| useRecordTableMoveFocusedCell | Ok |
| useRecordTableMoveFocusedRow | Ok |
| useMoveHoverToCurrentCell | OK |
| useTriggerActionMenuDropdown | Ok |
| RecordTableBodyDragDropContextProvider | Ok |
| RecordTableHeaderCell | Ok |
| useSetCurrentRowSelected | Ok |
| useRecordTitleCell | Ok |
| SettingsObjectFieldActiveActionDropdown | Ok |
| SettingsObjectFieldInactiveActionDropdown | Ok |
| SettingsObjectFieldItemTableRow | Ok |
| SettingsObjectInactiveMenuDropDown | Ok |
| SettingsRoleEditEffect | Ok |
| SettingsRolesQueryEffect | Ok |
| Dropdown | Ok |
| useSelectableList | Ok |
| useSelectableListHotKeys | Ok |
| useSelectableListListenToEnterHotkeyOnItem | Ok |
| useNavigationSection | Ok |
| useCreateViewFromCurrentState | Ok |
| useDeleteViewFromCurrentState | Ok |
| useUpdateViewFromCurrentState | Ok |
| ViewPickerFavoriteFoldersDropdown | Ok |
| useCreateViewFromCurrentView | Ok |
| ViewBarDetails | Ok |
| WorkflowRunVisualizer | Ok |
| useHandleWorkflowRunDiagramCanvasInit | Ok |
| WorkflowDiagramCanvasBase | Ok |
| WorkflowRunVisualizerEffect | Ok |
| useRemoveStepFilter | Ok |
| useRemoveStepFilterGroup | Ok |
| useUpsertStepFilterSettings | Ok |
| WorkflowFindRecordsFilters | Ok |
| SettingsObjects | Ok |
resolve#13253
This PR enables the use of Google Place Autocomplete and Place Details
APIs in the backend. It allows users to automatically fill in address
fields by typing into the address1 input. The input is debounced, then
the Autocomplete API is called. Once the user selects an address, the
Place Details API is used to parse and fill in the individual address
fields.
https://github.com/user-attachments/assets/e04b8474-25b8-48f5-83d0-2074f8d5fc94
---------
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
This PR improves dropdown menu headers for filter and sort dropdown in
view bar and editable filter chips.
It adds what's necessary to navigate back or close the dropdown, so that
we don't rely solely on click outside to exit the dropdown.
This PR also refactors the components so that we clearly identify the
two code paths that can use filter dropdowns : view bar and filter chip,
everything that can be DRY stays in the object-filter-dropdown module
but we try to have our wrapping components in each distinct module
instead of blending everything with ternaries inside
object-filter-dropdown module.
The vector search input value wasn't correctly handled across the
different dropdowns, due to a wrong component instance management, since
the dropdown menu header improvement put this into light, I also
refactored the state management of the vector search input.
@Bonapara please check the QA video and tell me if it's ok, I didn't add
dropdown menu header on the advanced filter field list dropdown because
it's a select more than a standalone dropdown, what do you think ?
QA :
https://github.com/user-attachments/assets/17080f32-f302-436c-937b-3577715b7e84
QA Vector search fix :
https://github.com/user-attachments/assets/6367bbf6-8a98-4b53-86cf-6ba92be130eb
Fixes https://github.com/twentyhq/core-team-issues/issues/640
Fixes https://github.com/twentyhq/core-team-issues/issues/1206
This PR fixes two bugs :
- Some important push item to focus stack calls were setting global
hotkey conflicting keys to true (like open dropdown)
- Icon picker matrix items were broken
to resolve the issue #13047
It's my first contribution, I hope it's good enough!
When using the slash command (/) in the notes editor, a menu of commands
appears. When navigating this menu with the up and down arrow keys, the
selection changes, but the menu itself does not scroll. This means that
as the list of commands is long, items outside the visible area cannot
be seen when selected.
The issue was located in the [CustomSlashMenu.tsx] component. The menu
container didn't have vertical scrolling enabled, and there was no logic
to scroll the active item into the visible area.
The fix involved:
Adding overflow-y: auto to the menu's styled container in
[CustomSlashMenu.tsx].
Modifying the [DropdownMenuItemsContainer] component to accept and
forward a ref using React.forwardRef.
Implementing a useEffect hook in [CustomSlashMenu.tsx] that triggers on
selection change. This hook uses a ref to the items container to call
scrollIntoView({ block: 'nearest' }) on the currently selected menu
item.
---------
Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>