feat(packages/excalidraw): support nested dropdown menu (#10749)

Co-authored-by: Barnabás Molnár <38168628+barnabasmolnar@users.noreply.github.com>
This commit is contained in:
David Luzar
2026-02-08 22:27:34 +01:00
committed by GitHub
co-authored by Barnabás Molnár
parent b43260d97b
commit 063533aede
46 changed files with 1265 additions and 431 deletions
@@ -1,7 +1,7 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`Test <MermaidToExcalidraw/> > should open mermaid popup when active tool is mermaid 1`] = `
"<div class="Modal Dialog ttd-dialog" role="dialog" aria-modal="true" aria-labelledby="dialog-title"><div class="Modal__background"></div><div class="Modal__content" style="--max-width: 1520px;" tabindex="0"><div class="Island"><div class="Dialog__content"><div dir="ltr" data-orientation="horizontal" class="ttd-dialog-tabs-root"><p class="dialog-mermaid-title">Mermaid to Excalidraw</p><div data-state="active" data-orientation="horizontal" role="tabpanel" aria-labelledby="radix-:r0:-trigger-mermaid" id="radix-:r0:-content-mermaid" tabindex="0" class="ttd-dialog-content" style=""><div class="ttd-dialog-desc">Currently only <a href="https://mermaid.js.org/syntax/flowchart.html">Flowchart</a>,<a href="https://mermaid.js.org/syntax/sequenceDiagram.html"> Sequence, </a> and <a href="https://mermaid.js.org/syntax/classDiagram.html">Class </a>Diagrams are supported. The other types will be rendered as image in Excalidraw.</div><div class="ttd-dialog-panels"><div class="ttd-dialog-panel"><textarea class="ttd-dialog-input" placeholder="Write Mermaid diagram defintion here...">flowchart TD
"<div class="Modal Dialog ttd-dialog" role="dialog" aria-modal="true" aria-labelledby="dialog-title"><div class="Modal__background"></div><div class="Modal__content" style="--max-width: 1520px;" tabindex="0"><div class="Island"><div class="Dialog__content"><div dir="ltr" data-orientation="horizontal" class="ttd-dialog-tabs-root"><p class="dialog-mermaid-title">Mermaid to Excalidraw</p><div data-state="active" data-orientation="horizontal" role="tabpanel" aria-labelledby="radix-:r4:-trigger-mermaid" id="radix-:r4:-content-mermaid" tabindex="0" class="ttd-dialog-content" style=""><div class="ttd-dialog-desc">Currently only <a href="https://mermaid.js.org/syntax/flowchart.html">Flowchart</a>,<a href="https://mermaid.js.org/syntax/sequenceDiagram.html"> Sequence, </a> and <a href="https://mermaid.js.org/syntax/classDiagram.html">Class </a>Diagrams are supported. The other types will be rendered as image in Excalidraw.</div><div class="ttd-dialog-panels"><div class="ttd-dialog-panel"><textarea class="ttd-dialog-input" placeholder="Write Mermaid diagram defintion here...">flowchart TD
A[Christmas] --&gt;|Get money| B(Go shopping)
B --&gt; C{Let me think}
C --&gt;|One| D[Laptop]
@@ -2,15 +2,31 @@
exports[`<Excalidraw/> > <MainMenu/> > should render main menu with host menu items if passed from host 1`] = `
<div
class="dropdown-menu"
aria-labelledby="radix-:r7t:"
aria-orientation="vertical"
class="dropdown-menu main-menu"
data-align="start"
data-orientation="vertical"
data-radix-menu-content=""
data-side="bottom"
data-state="open"
data-testid="dropdown-menu"
dir="ltr"
id="radix-:r7u:"
role="menu"
style="outline: none; --radix-dropdown-menu-content-transform-origin: var(--radix-popper-transform-origin); --radix-dropdown-menu-content-available-width: var(--radix-popper-available-width); --radix-dropdown-menu-content-available-height: var(--radix-popper-available-height); --radix-dropdown-menu-trigger-width: var(--radix-popper-anchor-width); --radix-dropdown-menu-trigger-height: var(--radix-popper-anchor-height); animation: none;"
tabindex="-1"
>
<div
class="Island dropdown-menu-container"
style="--padding: 2; z-index: 2;"
style="--padding: 2;"
>
<button
class="dropdown-menu-item dropdown-menu-item-base"
class="radix-menu-item dropdown-menu-item dropdown-menu-item-base"
data-orientation="vertical"
data-radix-collection-item=""
role="menuitem"
tabindex="-1"
>
<div
class="dropdown-menu-item__text"
@@ -23,9 +39,13 @@ exports[`<Excalidraw/> > <MainMenu/> > should render main menu with host menu it
</div>
</button>
<a
class="dropdown-menu-item dropdown-menu-item-base"
class="radix-menu-item dropdown-menu-item dropdown-menu-item-base"
data-orientation="vertical"
data-radix-collection-item=""
href="blog.excalidaw.com"
rel="noopener"
rel="noopener noopener"
role="menuitem"
tabindex="-1"
target="_blank"
>
<div
@@ -49,8 +69,12 @@ exports[`<Excalidraw/> > <MainMenu/> > should render main menu with host menu it
</div>
<button
aria-label="Help"
class="dropdown-menu-item dropdown-menu-item-base"
class="radix-menu-item dropdown-menu-item dropdown-menu-item-base"
data-orientation="vertical"
data-radix-collection-item=""
data-testid="help-menu-item"
role="menuitem"
tabindex="-1"
title="Help"
>
<div
@@ -114,17 +138,33 @@ exports[`<Excalidraw/> > <MainMenu/> > should render main menu with host menu it
exports[`<Excalidraw/> > Test UIOptions prop > Test canvasActions > should render menu with default items when "UIOPtions" is "undefined" 1`] = `
<div
class="dropdown-menu"
aria-labelledby="radix-:rq:"
aria-orientation="vertical"
class="dropdown-menu main-menu"
data-align="start"
data-orientation="vertical"
data-radix-menu-content=""
data-side="bottom"
data-state="open"
data-testid="dropdown-menu"
dir="ltr"
id="radix-:rr:"
role="menu"
style="outline: none; --radix-dropdown-menu-content-transform-origin: var(--radix-popper-transform-origin); --radix-dropdown-menu-content-available-width: var(--radix-popper-available-width); --radix-dropdown-menu-content-available-height: var(--radix-popper-available-height); --radix-dropdown-menu-trigger-width: var(--radix-popper-anchor-width); --radix-dropdown-menu-trigger-height: var(--radix-popper-anchor-height); animation: none;"
tabindex="-1"
>
<div
class="Island dropdown-menu-container"
style="--padding: 2; z-index: 2;"
style="--padding: 2;"
>
<button
aria-label="Open"
class="dropdown-menu-item dropdown-menu-item-base"
class="radix-menu-item dropdown-menu-item dropdown-menu-item-base"
data-orientation="vertical"
data-radix-collection-item=""
data-testid="load-button"
role="menuitem"
tabindex="-1"
title="Open"
>
<div
@@ -164,8 +204,12 @@ exports[`<Excalidraw/> > Test UIOptions prop > Test canvasActions > should rende
</button>
<button
aria-label="Save to..."
class="dropdown-menu-item dropdown-menu-item-base"
class="radix-menu-item dropdown-menu-item dropdown-menu-item-base"
data-orientation="vertical"
data-radix-collection-item=""
data-testid="json-export-button"
role="menuitem"
tabindex="-1"
title="Save to..."
>
<div
@@ -200,8 +244,12 @@ exports[`<Excalidraw/> > Test UIOptions prop > Test canvasActions > should rende
</button>
<button
aria-label="Export image..."
class="dropdown-menu-item dropdown-menu-item-base"
class="radix-menu-item dropdown-menu-item dropdown-menu-item-base"
data-orientation="vertical"
data-radix-collection-item=""
data-testid="image-export-button"
role="menuitem"
tabindex="-1"
title="Export image..."
>
<div
@@ -265,8 +313,12 @@ exports[`<Excalidraw/> > Test UIOptions prop > Test canvasActions > should rende
</button>
<button
aria-label="Find on canvas"
class="dropdown-menu-item dropdown-menu-item-base"
class="radix-menu-item dropdown-menu-item dropdown-menu-item-base"
data-orientation="vertical"
data-radix-collection-item=""
data-testid="search-menu-button"
role="menuitem"
tabindex="-1"
title="Find on canvas"
>
<div
@@ -318,8 +370,12 @@ exports[`<Excalidraw/> > Test UIOptions prop > Test canvasActions > should rende
</button>
<button
aria-label="Help"
class="dropdown-menu-item dropdown-menu-item-base"
class="radix-menu-item dropdown-menu-item dropdown-menu-item-base"
data-orientation="vertical"
data-radix-collection-item=""
data-testid="help-menu-item"
role="menuitem"
tabindex="-1"
title="Help"
>
<div
@@ -379,8 +435,12 @@ exports[`<Excalidraw/> > Test UIOptions prop > Test canvasActions > should rende
</button>
<button
aria-label="Reset the canvas"
class="dropdown-menu-item dropdown-menu-item-base"
class="radix-menu-item dropdown-menu-item dropdown-menu-item-base"
data-orientation="vertical"
data-radix-collection-item=""
data-testid="clear-canvas-button"
role="menuitem"
tabindex="-1"
title="Reset the canvas"
>
<div
@@ -414,7 +474,7 @@ exports[`<Excalidraw/> > Test UIOptions prop > Test canvasActions > should rende
</div>
</button>
<div
style="height: 1px; margin: .5rem 0px; flex: 0 0 auto;"
style="height: 1px; margin: 6px 0px; flex: 0 0 auto;"
/>
<div
class="dropdown-menu-group "
@@ -426,9 +486,13 @@ exports[`<Excalidraw/> > Test UIOptions prop > Test canvasActions > should rende
</p>
<a
aria-label="GitHub"
class="dropdown-menu-item dropdown-menu-item-base"
class="radix-menu-item dropdown-menu-item dropdown-menu-item-base"
data-orientation="vertical"
data-radix-collection-item=""
href="https://github.com/excalidraw/excalidraw"
rel="noopener"
rel="noopener noopener"
role="menuitem"
tabindex="-1"
target="_blank"
title="GitHub"
>
@@ -464,9 +528,13 @@ exports[`<Excalidraw/> > Test UIOptions prop > Test canvasActions > should rende
</a>
<a
aria-label="X"
class="dropdown-menu-item dropdown-menu-item-base"
class="radix-menu-item dropdown-menu-item dropdown-menu-item-base"
data-orientation="vertical"
data-radix-collection-item=""
href="https://x.com/excalidraw"
rel="noopener"
rel="noopener noopener"
role="menuitem"
tabindex="-1"
target="_blank"
title="X"
>
@@ -514,9 +582,13 @@ exports[`<Excalidraw/> > Test UIOptions prop > Test canvasActions > should rende
</a>
<a
aria-label="Discord"
class="dropdown-menu-item dropdown-menu-item-base"
class="radix-menu-item dropdown-menu-item dropdown-menu-item-base"
data-orientation="vertical"
data-radix-collection-item=""
href="https://discord.gg/UexuTaE"
rel="noopener"
rel="noopener noopener"
role="menuitem"
tabindex="-1"
target="_blank"
title="Discord"
>
@@ -558,12 +630,16 @@ exports[`<Excalidraw/> > Test UIOptions prop > Test canvasActions > should rende
</a>
</div>
<div
style="height: 1px; margin: .5rem 0px; flex: 0 0 auto;"
style="height: 1px; margin: 6px 0px; flex: 0 0 auto;"
/>
<button
aria-label="Dark mode"
class="dropdown-menu-item dropdown-menu-item-base"
class="radix-menu-item dropdown-menu-item dropdown-menu-item-base"
data-orientation="vertical"
data-radix-collection-item=""
data-testid="toggle-dark-mode"
role="menuitem"
tabindex="-1"
title="Dark mode"
>
<div
@@ -603,11 +679,11 @@ exports[`<Excalidraw/> > Test UIOptions prop > Test canvasActions > should rende
</div>
</button>
<div
style="margin-top: 0.5rem;"
style="margin-top: 0.75rem;"
>
<div
data-testid="canvas-background-label"
style="font-size: .75rem; margin-bottom: .5rem;"
style="font-size: 0.875rem; margin-bottom: 0.25rem; margin-left: 0.5rem;"
>
Canvas background
</div>
@@ -683,7 +759,7 @@ exports[`<Excalidraw/> > Test UIOptions prop > Test canvasActions > should rende
style="width: 1px; height: 1rem; margin: 0px auto;"
/>
<button
aria-controls="radix-:r0:"
aria-controls="radix-:r16:"
aria-expanded="false"
aria-haspopup="dialog"
aria-label="Canvas background"