summaryrefslogtreecommitdiff
path: root/frontend
diff options
context:
space:
mode:
authorEMERALD <hudson.samuels@gmail.com>2023-02-01 19:16:42 -0600
committerGitHub <noreply@github.com>2023-02-01 17:16:42 -0800
commit43b2269ea710c02278f784f28521a99dc9d3915b (patch)
tree34dde12638d07f63864c84fabc8654253532b6ae /frontend
parent0c4e27cd343a81d386c11bc17f93296a2e598a5c (diff)
downloaddecky-loader-43b2269ea710c02278f784f28521a99dc9d3915b.tar.gz
decky-loader-43b2269ea710c02278f784f28521a99dc9d3915b.zip
Fix UI inconsistencies, various improvements (#357)
* Make version gray in plugin list * Settings/store icons together & plugin list fix * Navigation name/icon improvements * Decky settings overhaul and other fixes - Revert the tab icon to a plug - Rename DeckyFlat function to DeckyIcon - Add DialogBody to settings pages to improve scrolling - Add remote debugging settings to the developer settings - Fix React devtools interactions to work more easily - Add spacing to React devtools description - Specify Decky vs. plugin store - Compact version information by update button - Add current version to bottom of settings - Remove unnecessary settings icons - Change CEF debugger icon to Chrome (bug icon too generic, is Chromium) - Make buttons/dropdowns in settings have fixed width - Make download icon act/appear similar to Valve's for Deck * Final UI adjustments * Switch plugin settings icon to plug
Diffstat (limited to 'frontend')
-rw-r--r--frontend/src/components/DeckyIcon.tsx37
-rw-r--r--frontend/src/components/TitleView.tsx13
-rw-r--r--frontend/src/components/settings/index.tsx18
-rw-r--r--frontend/src/components/settings/pages/developer/index.tsx80
-rw-r--r--frontend/src/components/settings/pages/general/BranchSelect.tsx2
-rw-r--r--frontend/src/components/settings/pages/general/RemoteDebugging.tsx6
-rw-r--r--frontend/src/components/settings/pages/general/StoreSelect.tsx2
-rw-r--r--frontend/src/components/settings/pages/general/Updater.tsx22
-rw-r--r--frontend/src/components/settings/pages/general/index.tsx77
-rw-r--r--frontend/src/components/settings/pages/plugin_list/index.tsx98
10 files changed, 204 insertions, 151 deletions
diff --git a/frontend/src/components/DeckyIcon.tsx b/frontend/src/components/DeckyIcon.tsx
new file mode 100644
index 00000000..515bd847
--- /dev/null
+++ b/frontend/src/components/DeckyIcon.tsx
@@ -0,0 +1,37 @@
+export default function DeckyIcon() {
+ return (
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 456" width="512" height="456">
+ <g>
+ <path
+ style={{ fill: 'none' }}
+ d="M154.33,72.51v49.79c11.78-0.17,23.48,2,34.42,6.39c10.93,4.39,20.89,10.91,29.28,19.18
+ c8.39,8.27,15.06,18.13,19.61,29c4.55,10.87,6.89,22.54,6.89,34.32c0,11.78-2.34,23.45-6.89,34.32
+ c-4.55,10.87-11.21,20.73-19.61,29c-8.39,8.27-18.35,14.79-29.28,19.18c-10.94,4.39-22.63,6.56-34.42,6.39v49.77
+ c36.78,0,72.05-14.61,98.05-40.62c26-26.01,40.61-61.28,40.61-98.05c0-36.78-14.61-72.05-40.61-98.05
+ C226.38,87.12,191.11,72.51,154.33,72.51z"
+ />
+
+ <ellipse
+ transform="matrix(0.982 -0.1891 0.1891 0.982 -37.1795 32.9988)"
+ style={{ fill: 'none' }}
+ cx="154.33"
+ cy="211.33"
+ rx="69.33"
+ ry="69.33"
+ />
+ <path style={{ fill: 'none' }} d="M430,97h-52v187h52c7.18,0,13-5.82,13-13V110C443,102.82,437.18,97,430,97z" />
+ <path
+ style={{ fill: 'currentColor' }}
+ d="M432,27h-54V0H0v361c0,52.47,42.53,95,95,95h188c52.47,0,95-42.53,95-95v-7h54c44.18,0,80-35.82,80-80V107
+ C512,62.82,476.18,27,432,27z M85,211.33c0-38.29,31.04-69.33,69.33-69.33c38.29,0,69.33,31.04,69.33,69.33
+ c0,38.29-31.04,69.33-69.33,69.33C116.04,280.67,85,249.62,85,211.33z M252.39,309.23c-26.01,26-61.28,40.62-98.05,40.62v-49.77
+ c11.78,0.17,23.48-2,34.42-6.39c10.93-4.39,20.89-10.91,29.28-19.18c8.39-8.27,15.06-18.13,19.61-29
+ c4.55-10.87,6.89-22.53,6.89-34.32c0-11.78-2.34-23.45-6.89-34.32c-4.55-10.87-11.21-20.73-19.61-29
+ c-8.39-8.27-18.35-14.79-29.28-19.18c-10.94-4.39-22.63-6.56-34.42-6.39V72.51c36.78,0,72.05,14.61,98.05,40.61
+ c26,26.01,40.61,61.28,40.61,98.05C293,247.96,278.39,283.23,252.39,309.23z M443,271c0,7.18-5.82,13-13,13h-52V97h52
+ c7.18,0,13,5.82,13,13V271z"
+ />
+ </g>
+ </svg>
+ );
+}
diff --git a/frontend/src/components/TitleView.tsx b/frontend/src/components/TitleView.tsx
index cd1f9eba..7e529d21 100644
--- a/frontend/src/components/TitleView.tsx
+++ b/frontend/src/components/TitleView.tsx
@@ -1,6 +1,7 @@
import { DialogButton, Focusable, Router, staticClasses } from 'decky-frontend-lib';
import { CSSProperties, VFC } from 'react';
-import { FaArrowLeft, FaCog, FaStore } from 'react-icons/fa';
+import { BsGearFill } from 'react-icons/bs';
+import { FaArrowLeft, FaStore } from 'react-icons/fa';
import { useDeckyState } from './DeckyState';
@@ -26,18 +27,18 @@ const TitleView: VFC = () => {
if (activePlugin === null) {
return (
<Focusable style={titleStyles} className={staticClasses.Title}>
+ <div style={{ marginRight: 'auto', flex: 0.9 }}>Decky</div>
<DialogButton
style={{ height: '28px', width: '40px', minWidth: 0, padding: '10px 12px' }}
- onClick={onSettingsClick}
+ onClick={onStoreClick}
>
- <FaCog style={{ marginTop: '-4px', display: 'block' }} />
+ <FaStore style={{ marginTop: '-4px', display: 'block' }} />
</DialogButton>
- <div style={{ marginRight: 'auto', flex: 0.9 }}>Decky</div>
<DialogButton
style={{ height: '28px', width: '40px', minWidth: 0, padding: '10px 12px' }}
- onClick={onStoreClick}
+ onClick={onSettingsClick}
>
- <FaStore style={{ marginTop: '-4px', display: 'block' }} />
+ <BsGearFill style={{ marginTop: '-4px', display: 'block' }} />
</DialogButton>
</Focusable>
);
diff --git a/frontend/src/components/settings/index.tsx b/frontend/src/components/settings/index.tsx
index 01f7d407..6f104710 100644
--- a/frontend/src/components/settings/index.tsx
+++ b/frontend/src/components/settings/index.tsx
@@ -1,7 +1,9 @@
import { SidebarNavigation } from 'decky-frontend-lib';
import { lazy } from 'react';
+import { FaCode, FaPlug } from 'react-icons/fa';
import { useSetting } from '../../utils/hooks/useSetting';
+import DeckyIcon from '../DeckyIcon';
import WithSuspense from '../WithSuspense';
import GeneralSettings from './pages/general';
import PluginList from './pages/plugin_list';
@@ -13,19 +15,18 @@ export default function SettingsPage() {
const pages = [
{
- title: 'General',
+ title: 'Decky',
content: <GeneralSettings isDeveloper={isDeveloper} setIsDeveloper={setIsDeveloper} />,
route: '/decky/settings/general',
+ icon: <DeckyIcon />,
},
{
title: 'Plugins',
content: <PluginList />,
route: '/decky/settings/plugins',
+ icon: <FaPlug />,
},
- ];
-
- if (isDeveloper)
- pages.push({
+ {
title: 'Developer',
content: (
<WithSuspense>
@@ -33,7 +34,10 @@ export default function SettingsPage() {
</WithSuspense>
),
route: '/decky/settings/developer',
- });
+ icon: <FaCode />,
+ visible: isDeveloper,
+ },
+ ];
- return <SidebarNavigation title="Decky Settings" showTitle pages={pages} />;
+ return <SidebarNavigation pages={pages} />;
}
diff --git a/frontend/src/components/settings/pages/developer/index.tsx b/frontend/src/components/settings/pages/developer/index.tsx
index 447c9606..d9859c46 100644
--- a/frontend/src/components/settings/pages/developer/index.tsx
+++ b/frontend/src/components/settings/pages/developer/index.tsx
@@ -1,9 +1,10 @@
-import { Field, Focusable, TextField, Toggle } from 'decky-frontend-lib';
+import { DialogBody, Field, TextField, Toggle } from 'decky-frontend-lib';
import { useRef } from 'react';
import { FaReact, FaSteamSymbol } from 'react-icons/fa';
import { setShouldConnectToReactDevTools, setShowValveInternal } from '../../../../developer';
import { useSetting } from '../../../../utils/hooks/useSetting';
+import RemoteDebuggingSettings from '../general/RemoteDebugging';
export default function DeveloperSettings() {
const [enableValveInternal, setEnableValveInternal] = useSetting<boolean>('developer.valve_internal', false);
@@ -12,7 +13,8 @@ export default function DeveloperSettings() {
const textRef = useRef<HTMLDivElement>(null);
return (
- <>
+ <DialogBody>
+ <RemoteDebuggingSettings />
<Field
label="Enable Valve Internal"
description={
@@ -30,55 +32,33 @@ export default function DeveloperSettings() {
setShowValveInternal(toggleValue);
}}
/>
- </Field>{' '}
- <Focusable
- onTouchEnd={
- reactDevtoolsIP == ''
- ? () => {
- (textRef.current?.childNodes[0] as HTMLInputElement)?.focus();
- }
- : undefined
- }
- onClick={
- reactDevtoolsIP == ''
- ? () => {
- (textRef.current?.childNodes[0] as HTMLInputElement)?.focus();
- }
- : undefined
- }
- onOKButton={
- reactDevtoolsIP == ''
- ? () => {
- (textRef.current?.childNodes[0] as HTMLInputElement)?.focus();
- }
- : undefined
+ </Field>
+ <Field
+ label="Enable React DevTools"
+ description={
+ <>
+ <span style={{ whiteSpace: 'pre-line' }}>
+ Enables connection to a computer running React DevTools. Changing this setting will reload Steam. Set the
+ IP address before enabling.
+ </span>
+ <br />
+ <br />
+ <div ref={textRef}>
+ <TextField label={'IP'} value={reactDevtoolsIP} onChange={(e) => setReactDevtoolsIP(e?.target.value)} />
+ </div>
+ </>
}
+ icon={<FaReact style={{ display: 'block' }} />}
>
- <Field
- label="Enable React DevTools"
- description={
- <>
- <span style={{ whiteSpace: 'pre-line' }}>
- Enables connection to a computer running React DevTools. Changing this setting will reload Steam. Set
- the IP address before enabling.
- </span>
- <div ref={textRef}>
- <TextField label={'IP'} value={reactDevtoolsIP} onChange={(e) => setReactDevtoolsIP(e?.target.value)} />
- </div>
- </>
- }
- icon={<FaReact style={{ display: 'block' }} />}
- >
- <Toggle
- value={reactDevtoolsEnabled}
- disabled={reactDevtoolsIP == ''}
- onChange={(toggleValue) => {
- setReactDevtoolsEnabled(toggleValue);
- setShouldConnectToReactDevTools(toggleValue);
- }}
- />
- </Field>
- </Focusable>
- </>
+ <Toggle
+ value={reactDevtoolsEnabled}
+ disabled={reactDevtoolsIP == ''}
+ onChange={(toggleValue) => {
+ setReactDevtoolsEnabled(toggleValue);
+ setShouldConnectToReactDevTools(toggleValue);
+ }}
+ />
+ </Field>
+ </DialogBody>
);
}
diff --git a/frontend/src/components/settings/pages/general/BranchSelect.tsx b/frontend/src/components/settings/pages/general/BranchSelect.tsx
index 27db6229..5387b655 100644
--- a/frontend/src/components/settings/pages/general/BranchSelect.tsx
+++ b/frontend/src/components/settings/pages/general/BranchSelect.tsx
@@ -19,7 +19,7 @@ const BranchSelect: FunctionComponent<{}> = () => {
return (
// Returns numerical values from 0 to 2 (with current branch setup as of 8/28/22)
// 0 being stable, 1 being pre-release and 2 being nightly
- <Field label="Update Channel">
+ <Field label="Decky Update Channel" childrenContainerWidth={'fixed'}>
<Dropdown
rgOptions={Object.values(UpdateBranch)
.filter((branch) => typeof branch == 'string')
diff --git a/frontend/src/components/settings/pages/general/RemoteDebugging.tsx b/frontend/src/components/settings/pages/general/RemoteDebugging.tsx
index 36badf45..db604c69 100644
--- a/frontend/src/components/settings/pages/general/RemoteDebugging.tsx
+++ b/frontend/src/components/settings/pages/general/RemoteDebugging.tsx
@@ -1,5 +1,5 @@
import { Field, Toggle } from 'decky-frontend-lib';
-import { FaBug } from 'react-icons/fa';
+import { FaChrome } from 'react-icons/fa';
import { useSetting } from '../../../../utils/hooks/useSetting';
@@ -11,10 +11,10 @@ export default function RemoteDebuggingSettings() {
label="Allow Remote CEF Debugging"
description={
<span style={{ whiteSpace: 'pre-line' }}>
- Allow unauthenticated access to the CEF debugger to anyone in your network
+ Allows unauthenticated access to the CEF debugger to anyone in your network.
</span>
}
- icon={<FaBug style={{ display: 'block' }} />}
+ icon={<FaChrome style={{ display: 'block' }} />}
>
<Toggle
value={allowRemoteDebugging || false}
diff --git a/frontend/src/components/settings/pages/general/StoreSelect.tsx b/frontend/src/components/settings/pages/general/StoreSelect.tsx
index c24bacb9..40e70301 100644
--- a/frontend/src/components/settings/pages/general/StoreSelect.tsx
+++ b/frontend/src/components/settings/pages/general/StoreSelect.tsx
@@ -16,7 +16,7 @@ const StoreSelect: FunctionComponent<{}> = () => {
// 0 being Default, 1 being Testing and 2 being Custom
return (
<>
- <Field label="Store Channel">
+ <Field label="Plugin Store Channel" childrenContainerWidth={'fixed'}>
<Dropdown
rgOptions={Object.values(Store)
.filter((store) => typeof store == 'string')
diff --git a/frontend/src/components/settings/pages/general/Updater.tsx b/frontend/src/components/settings/pages/general/Updater.tsx
index f617e0ff..b38b6d01 100644
--- a/frontend/src/components/settings/pages/general/Updater.tsx
+++ b/frontend/src/components/settings/pages/general/Updater.tsx
@@ -11,7 +11,7 @@ import {
import { useCallback } from 'react';
import { Suspense, lazy } from 'react';
import { useEffect, useState } from 'react';
-import { FaArrowDown } from 'react-icons/fa';
+import { FaExclamation } from 'react-icons/fa';
import { VerInfo, callUpdaterMethod, finishUpdate } from '../../../../updater';
import { findSP } from '../../../../utils/windows';
@@ -95,21 +95,21 @@ export default function UpdaterSettings() {
<Field
onOptionsActionDescription={versionInfo?.all ? 'Patch Notes' : undefined}
onOptionsButton={versionInfo?.all ? showPatchNotes : undefined}
- label="Updates"
+ label="Decky Updates"
description={
- versionInfo && (
- <span style={{ whiteSpace: 'pre-line' }}>{`Current version: ${versionInfo.current}\n${
- versionInfo.updatable ? `Latest version: ${versionInfo.remote?.tag_name}` : ''
- }`}</span>
+ checkingForUpdates || versionInfo?.remote?.tag_name != versionInfo?.current || !versionInfo?.remote ? (
+ ''
+ ) : (
+ <span>Up to date: running {versionInfo?.current}</span>
)
}
icon={
- !versionInfo ? (
- <Spinner style={{ width: '1em', height: 20, display: 'block' }} />
- ) : (
- <FaArrowDown style={{ display: 'block' }} />
+ versionInfo?.remote &&
+ versionInfo?.remote?.tag_name != versionInfo?.current && (
+ <FaExclamation color="var(--gpColor-Yellow)" style={{ display: 'block' }} />
)
}
+ childrenContainerWidth={'fixed'}
>
{updateProgress == -1 && !isLoaderUpdating ? (
<DialogButton
@@ -144,7 +144,7 @@ export default function UpdaterSettings() {
/>
)}
</Field>
- {versionInfo?.remote && (
+ {versionInfo?.remote && versionInfo?.remote?.tag_name != versionInfo?.current && (
<InlinePatchNotes
title={versionInfo?.remote.name}
date={new Intl.RelativeTimeFormat('en-US', {
diff --git a/frontend/src/components/settings/pages/general/index.tsx b/frontend/src/components/settings/pages/general/index.tsx
index d661b779..e0bd9691 100644
--- a/frontend/src/components/settings/pages/general/index.tsx
+++ b/frontend/src/components/settings/pages/general/index.tsx
@@ -1,10 +1,17 @@
-import { DialogButton, Field, TextField, Toggle } from 'decky-frontend-lib';
+import {
+ DialogBody,
+ DialogButton,
+ DialogControlsSection,
+ DialogControlsSectionHeader,
+ Field,
+ TextField,
+ Toggle,
+} from 'decky-frontend-lib';
import { useState } from 'react';
-import { FaShapes, FaTools } from 'react-icons/fa';
import { installFromURL } from '../../../../store';
+import { useDeckyState } from '../../../DeckyState';
import BranchSelect from './BranchSelect';
-import RemoteDebuggingSettings from './RemoteDebugging';
import StoreSelect from './StoreSelect';
import UpdaterSettings from './Updater';
@@ -16,34 +23,44 @@ export default function GeneralSettings({
setIsDeveloper: (val: boolean) => void;
}) {
const [pluginURL, setPluginURL] = useState('');
+ const { versionInfo } = useDeckyState();
return (
- <div>
- <UpdaterSettings />
- <BranchSelect />
- <StoreSelect />
- <RemoteDebuggingSettings />
- <Field
- label="Developer mode"
- description={<span style={{ whiteSpace: 'pre-line' }}>Enables Decky's developer settings.</span>}
- icon={<FaTools style={{ display: 'block' }} />}
- >
- <Toggle
- value={isDeveloper}
- onChange={(toggleValue) => {
- setIsDeveloper(toggleValue);
- }}
- />
- </Field>
- <Field
- label="Manual plugin install"
- description={<TextField label={'URL'} value={pluginURL} onChange={(e) => setPluginURL(e?.target.value)} />}
- icon={<FaShapes style={{ display: 'block' }} />}
- >
- <DialogButton disabled={pluginURL.length == 0} onClick={() => installFromURL(pluginURL)}>
- Install
- </DialogButton>
- </Field>
- </div>
+ <DialogBody>
+ <DialogControlsSection>
+ <DialogControlsSectionHeader>Updates</DialogControlsSectionHeader>
+ <UpdaterSettings />
+ </DialogControlsSection>
+ <DialogControlsSection>
+ <DialogControlsSectionHeader>Beta Participation</DialogControlsSectionHeader>
+ <BranchSelect />
+ <StoreSelect />
+ </DialogControlsSection>
+ <DialogControlsSection>
+ <DialogControlsSectionHeader>Other</DialogControlsSectionHeader>
+ <Field label="Enable Developer Mode">
+ <Toggle
+ value={isDeveloper}
+ onChange={(toggleValue) => {
+ setIsDeveloper(toggleValue);
+ }}
+ />
+ </Field>
+ <Field
+ label="Install plugin from URL"
+ description={<TextField label={'URL'} value={pluginURL} onChange={(e) => setPluginURL(e?.target.value)} />}
+ >
+ <DialogButton disabled={pluginURL.length == 0} onClick={() => installFromURL(pluginURL)}>
+ Install
+ </DialogButton>
+ </Field>
+ </DialogControlsSection>
+ <DialogControlsSection>
+ <DialogControlsSectionHeader>About</DialogControlsSectionHeader>
+ <Field label="Decky Version" focusable={true}>
+ <div style={{ color: 'var(--gpSystemLighterGrey)' }}>{versionInfo?.current}</div>
+ </Field>
+ </DialogControlsSection>
+ </DialogBody>
);
}
diff --git a/frontend/src/components/settings/pages/plugin_list/index.tsx b/frontend/src/components/settings/pages/plugin_list/index.tsx
index 4eb89615..48894031 100644
--- a/frontend/src/components/settings/pages/plugin_list/index.tsx
+++ b/frontend/src/components/settings/pages/plugin_list/index.tsx
@@ -1,4 +1,12 @@
-import { DialogButton, Focusable, Menu, MenuItem, showContextMenu } from 'decky-frontend-lib';
+import {
+ DialogBody,
+ DialogButton,
+ DialogControlsSection,
+ Focusable,
+ Menu,
+ MenuItem,
+ showContextMenu,
+} from 'decky-frontend-lib';
import { useEffect } from 'react';
import { FaDownload, FaEllipsisH } from 'react-icons/fa';
@@ -21,46 +29,52 @@ export default function PluginList() {
}
return (
- <ul style={{ listStyleType: 'none' }}>
- {plugins.map(({ name, version }) => {
- const update = updates?.get(name);
- return (
- <li style={{ display: 'flex', flexDirection: 'row', alignItems: 'center', paddingBottom: '10px' }}>
- <span>
- {name} {version}
- </span>
- <Focusable style={{ marginLeft: 'auto', boxShadow: 'none', display: 'flex', justifyContent: 'right' }}>
- {update && (
- <DialogButton
- style={{ height: '40px', minWidth: '60px', marginRight: '10px' }}
- onClick={() => requestPluginInstall(name, update)}
- >
- <div style={{ display: 'flex', flexDirection: 'row' }}>
- Update to {update.name}
- <FaDownload style={{ paddingLeft: '2rem' }} />
- </div>
- </DialogButton>
- )}
- <DialogButton
- style={{ height: '40px', width: '40px', padding: '10px 12px', minWidth: '40px' }}
- onClick={(e: MouseEvent) =>
- showContextMenu(
- <Menu label="Plugin Actions">
- <MenuItem onSelected={() => window.DeckyPluginLoader.importPlugin(name, version)}>
- Reload
- </MenuItem>
- <MenuItem onSelected={() => window.DeckyPluginLoader.uninstallPlugin(name)}>Uninstall</MenuItem>
- </Menu>,
- e.currentTarget ?? window,
- )
- }
- >
- <FaEllipsisH />
- </DialogButton>
- </Focusable>
- </li>
- );
- })}
- </ul>
+ <DialogBody>
+ <DialogControlsSection>
+ <ul style={{ listStyleType: 'none', padding: '0' }}>
+ {plugins.map(({ name, version }) => {
+ const update = updates?.get(name);
+ return (
+ <li style={{ display: 'flex', flexDirection: 'row', alignItems: 'center', paddingBottom: '10px' }}>
+ <span>
+ {name} <span style={{ opacity: '50%' }}>{'(' + version + ')'}</span>
+ </span>
+ <Focusable style={{ marginLeft: 'auto', boxShadow: 'none', display: 'flex', justifyContent: 'right' }}>
+ {update && (
+ <DialogButton
+ style={{ height: '40px', minWidth: '60px', marginRight: '10px' }}
+ onClick={() => requestPluginInstall(name, update)}
+ >
+ <div style={{ display: 'flex', flexDirection: 'row' }}>
+ Update to {update.name}
+ <FaDownload style={{ paddingLeft: '2rem' }} />
+ </div>
+ </DialogButton>
+ )}
+ <DialogButton
+ style={{ height: '40px', width: '40px', padding: '10px 12px', minWidth: '40px' }}
+ onClick={(e: MouseEvent) =>
+ showContextMenu(
+ <Menu label="Plugin Actions">
+ <MenuItem onSelected={() => window.DeckyPluginLoader.importPlugin(name, version)}>
+ Reload
+ </MenuItem>
+ <MenuItem onSelected={() => window.DeckyPluginLoader.uninstallPlugin(name)}>
+ Uninstall
+ </MenuItem>
+ </Menu>,
+ e.currentTarget ?? window,
+ )
+ }
+ >
+ <FaEllipsisH />
+ </DialogButton>
+ </Focusable>
+ </li>
+ );
+ })}
+ </ul>
+ </DialogControlsSection>
+ </DialogBody>
);
}