Skip to content

Commit 8f3ade4

Browse files
authored
Merge pull request #1163 from responsively-org/dropdown-overflow-fix
Dropdown flyout is rendered via portal
2 parents adac5eb + e55fe6a commit 8f3ade4

File tree

4 files changed

+113
-59
lines changed

4 files changed

+113
-59
lines changed

desktop-app/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@
104104
},
105105
"dependencies": {
106106
"@fontsource/lato": "^5.0.17",
107+
"@headlessui-float/react": "^0.12.0",
107108
"@headlessui/react": "^1.7.4",
108109
"@iconify/react": "^3.2.2",
109110
"@reduxjs/toolkit": "^1.9.5",

desktop-app/src/renderer/components/DropDown/index.tsx

Lines changed: 55 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { Menu, Transition } from '@headlessui/react';
2+
import { Float } from '@headlessui-float/react';
23
import { Icon } from '@iconify/react';
34
import cx from 'classnames';
45
import { Fragment } from 'react';
@@ -23,66 +24,66 @@ interface Props {
2324

2425
export function DropDown({ label, options, className }: Props) {
2526
return (
26-
<div className="text-right">
27-
<Menu as="div" className={`relative inline-block text-left ${className}`}>
28-
<div>
27+
<div className="relative text-right">
28+
<Menu as="div" className={`inline-block text-left ${className}`}>
29+
<Float placement="bottom-end" flip portal>
2930
<Menu.Button className="inline-flex w-full justify-center gap-1 rounded-md bg-opacity-20 p-2 text-sm font-medium hover:bg-slate-300 hover:bg-opacity-30 focus:outline-none focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-opacity-75 dark:hover:bg-slate-700">
3031
{label}
3132
<Icon icon="mdi:chevron-down" />
3233
</Menu.Button>
33-
</div>
34-
<Transition
35-
as={Fragment}
36-
enter="transition ease-out duration-100"
37-
enterFrom="transform opacity-0 scale-95"
38-
enterTo="transform opacity-100 scale-100"
39-
leave="transition ease-in duration-75"
40-
leaveFrom="transform opacity-100 scale-100"
41-
leaveTo="transform opacity-0 scale-95"
42-
>
43-
<Menu.Items className="absolute right-0 z-50 mt-2 w-fit origin-top-right divide-y divide-slate-100 rounded-md bg-slate-100 shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none dark:bg-slate-900">
44-
<div className="px-1 py-1 ">
45-
{options.map((option, idx) => {
46-
if (option.type === 'separator') {
34+
<Transition
35+
as={Fragment}
36+
enter="transition ease-out duration-100"
37+
enterFrom="transform opacity-0 scale-95"
38+
enterTo="transform opacity-100 scale-100"
39+
leave="transition ease-in duration-75"
40+
leaveFrom="transform opacity-100 scale-100"
41+
leaveTo="transform opacity-0 scale-95"
42+
>
43+
<Menu.Items className="z-50 mt-2 w-fit origin-top-right divide-y divide-slate-100 rounded-md bg-slate-100 shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none dark:bg-slate-900">
44+
<div className="px-1 py-1 ">
45+
{options.map((option, idx) => {
46+
if (option.type === 'separator') {
47+
return (
48+
<div
49+
className="m-1 border-t-[1px] border-t-slate-500"
50+
// eslint-disable-next-line react/no-array-index-key
51+
key={`divider-${idx}`}
52+
/>
53+
);
54+
}
4755
return (
48-
<div
49-
className="m-1 border-t-[1px] border-t-slate-500"
50-
// eslint-disable-next-line react/no-array-index-key
51-
key={`divider-${idx}`}
52-
/>
56+
// eslint-disable-next-line react/no-array-index-key
57+
<Menu.Item key={idx.toString()}>
58+
{({ active }) =>
59+
option.onClick !== null ? (
60+
<button
61+
className={cx(
62+
'group flex w-full items-center rounded-md px-2 py-2 text-sm',
63+
{ 'bg-slate-200 dark:bg-slate-800': active }
64+
)}
65+
type="button"
66+
onClick={option.onClick}
67+
>
68+
{option.label}
69+
</button>
70+
) : (
71+
<div
72+
className={cx(
73+
'group mt-2 flex w-full items-center rounded-md px-2'
74+
)}
75+
>
76+
{option.label}
77+
</div>
78+
)
79+
}
80+
</Menu.Item>
5381
);
54-
}
55-
return (
56-
// eslint-disable-next-line react/no-array-index-key
57-
<Menu.Item key={idx.toString()}>
58-
{({ active }) =>
59-
option.onClick !== null ? (
60-
<button
61-
className={cx(
62-
'group flex w-full items-center rounded-md px-2 py-2 text-sm',
63-
{ 'bg-slate-200 dark:bg-slate-800': active }
64-
)}
65-
type="button"
66-
onClick={option.onClick}
67-
>
68-
{option.label}
69-
</button>
70-
) : (
71-
<div
72-
className={cx(
73-
'group mt-2 flex w-full items-center rounded-md px-2'
74-
)}
75-
>
76-
{option.label}
77-
</div>
78-
)
79-
}
80-
</Menu.Item>
81-
);
82-
})}
83-
</div>
84-
</Menu.Items>
85-
</Transition>
82+
})}
83+
</div>
84+
</Menu.Items>
85+
</Transition>
86+
</Float>
8687
</Menu>
8788
</div>
8889
);

desktop-app/src/renderer/context/ThemeProvider/index.tsx

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,20 @@ const ThemeProvider = ({ children }: { children: React.ReactNode }) => {
66
const darkMode = useSelector(selectDarkMode);
77

88
useEffect(() => {
9+
const body = document.querySelector('body');
10+
'bg-slate-200 text-light-normal dark:bg-slate-800 dark:text-dark-normal'
11+
.split(' ')
12+
.forEach((className) => {
13+
body?.classList.add(className);
14+
});
915
if (darkMode) {
1016
document.documentElement.classList.add('dark');
1117
} else {
1218
document.documentElement.classList.remove('dark');
1319
}
1420
}, [darkMode]);
1521

16-
return (
17-
<div className="min-w-screen min-h-screen bg-slate-200 text-light-normal dark:bg-slate-800 dark:text-dark-normal">
18-
{children}
19-
</div>
20-
);
22+
return <div className="min-w-screen min-h-screen">{children}</div>;
2123
};
2224

2325
export default ThemeProvider;

desktop-app/yarn.lock

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1381,6 +1381,42 @@
13811381
resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.36.0.tgz#9837f768c03a1e4a30bd304a64fb8844f0e72efe"
13821382
integrity sha512-lxJ9R5ygVm8ZWgYdUweoq5ownDlJ4upvoWmO4eLxBYHdMo+vZ/Rx0EN6MbKWDJOSUGrqJy2Gt+Dyv/VKml0fjg==
13831383

1384+
"@floating-ui/core@^1.3.0", "@floating-ui/core@^1.4.2":
1385+
version "1.5.0"
1386+
resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.5.0.tgz#5c05c60d5ae2d05101c3021c1a2a350ddc027f8c"
1387+
integrity sha512-kK1h4m36DQ0UHGj5Ah4db7R0rHemTqqO0QLvUqi1/mUUp3LuAWbWxdxSIf/XsnH9VS6rRVPLJCncjRzUvyCLXg==
1388+
dependencies:
1389+
"@floating-ui/utils" "^0.1.3"
1390+
1391+
"@floating-ui/dom@^1.3.0", "@floating-ui/dom@^1.5.1":
1392+
version "1.5.3"
1393+
resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.5.3.tgz#54e50efcb432c06c23cd33de2b575102005436fa"
1394+
integrity sha512-ClAbQnEqJAKCJOEbbLo5IUlZHkNszqhuxS4fHAVxRPXPya6Ysf2G8KypnYcOTpx6I8xcgF9bbHb6g/2KpbV8qA==
1395+
dependencies:
1396+
"@floating-ui/core" "^1.4.2"
1397+
"@floating-ui/utils" "^0.1.3"
1398+
1399+
"@floating-ui/react-dom@^2.0.3":
1400+
version "2.0.4"
1401+
resolved "https://registry.yarnpkg.com/@floating-ui/react-dom/-/react-dom-2.0.4.tgz#b076fafbdfeb881e1d86ae748b7ff95150e9f3ec"
1402+
integrity sha512-CF8k2rgKeh/49UrnIBs4BdxPUV6vize/Db1d/YbCLyp9GiVZ0BEwf5AiDSxJRCr6yOkGqTFHtmrULxkEfYZ7dQ==
1403+
dependencies:
1404+
"@floating-ui/dom" "^1.5.1"
1405+
1406+
"@floating-ui/react@^0.26.0":
1407+
version "0.26.2"
1408+
resolved "https://registry.yarnpkg.com/@floating-ui/react/-/react-0.26.2.tgz#1a548f0f9aae64a742c868ae36aa620d15dec728"
1409+
integrity sha512-ocpz3MxYoZlgsASiVFayiTnKukR8QZDQUMqxMdF0YFLbu8lw/IL6AHKLROI8SOpp6CxpUGPh9Q4a03eBAVEZNQ==
1410+
dependencies:
1411+
"@floating-ui/react-dom" "^2.0.3"
1412+
"@floating-ui/utils" "^0.1.5"
1413+
tabbable "^6.0.1"
1414+
1415+
"@floating-ui/utils@^0.1.3", "@floating-ui/utils@^0.1.5":
1416+
version "0.1.6"
1417+
resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.1.6.tgz#22958c042e10b67463997bd6ea7115fe28cbcaf9"
1418+
integrity sha512-OfX7E2oUDYxtBvsuS4e/jSn4Q9Qb6DzgeYtsAdkPZ47znpoNsMgZw0+tVijiv3uGNR6dgNlty6r9rzIzHjtd/A==
1419+
13841420
"@fontsource/lato@^5.0.17":
13851421
version "5.0.17"
13861422
resolved "https://registry.yarnpkg.com/@fontsource/lato/-/lato-5.0.17.tgz#7c75c443da1e3ae203ed1977b6455bb15c62c106"
@@ -1399,6 +1435,15 @@
13991435
normalize-path "^2.0.1"
14001436
through2 "^2.0.3"
14011437

1438+
"@headlessui-float/react@^0.12.0":
1439+
version "0.12.0"
1440+
resolved "https://registry.yarnpkg.com/@headlessui-float/react/-/react-0.12.0.tgz#092ef8ee39a87526895f314fe8e4765e2e077cda"
1441+
integrity sha512-/oikFriS8t5nirJnRlHrvltrGx0PwhGUsUFNxxyfLOC/wNGX8k5kvNy+XCmSXBJ3fCYsSHYaDsPLct3lWDMXuw==
1442+
dependencies:
1443+
"@floating-ui/core" "^1.3.0"
1444+
"@floating-ui/dom" "^1.3.0"
1445+
"@floating-ui/react" "^0.26.0"
1446+
14021447
"@headlessui/react@^1.7.4":
14031448
version "1.7.4"
14041449
resolved "https://registry.yarnpkg.com/@headlessui/react/-/react-1.7.4.tgz#ba7f50fda20667276ee84fcd4c2a459aa26187e3"
@@ -12960,6 +13005,11 @@ synckit@^0.8.4:
1296013005
"@pkgr/utils" "^2.3.1"
1296113006
tslib "^2.4.0"
1296213007

13008+
tabbable@^6.0.1:
13009+
version "6.2.0"
13010+
resolved "https://registry.yarnpkg.com/tabbable/-/tabbable-6.2.0.tgz#732fb62bc0175cfcec257330be187dcfba1f3b97"
13011+
integrity sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==
13012+
1296313013
tailwindcss@^3.1.4:
1296413014
version "3.2.1"
1296513015
resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.2.1.tgz#1bd828fff3172489962357f8d531c184080a6786"

0 commit comments

Comments
 (0)