mirror of
https://github.com/responsively-org/responsively-app
synced 2024-11-10 06:44:13 +00:00
Dropdown flyout is rendered via portal
This commit is contained in:
parent
adac5eba3e
commit
cf2cd4a6b2
3 changed files with 106 additions and 54 deletions
|
@ -104,6 +104,7 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fontsource/lato": "^5.0.17",
|
"@fontsource/lato": "^5.0.17",
|
||||||
|
"@headlessui-float/react": "^0.12.0",
|
||||||
"@headlessui/react": "^1.7.4",
|
"@headlessui/react": "^1.7.4",
|
||||||
"@iconify/react": "^3.2.2",
|
"@iconify/react": "^3.2.2",
|
||||||
"@reduxjs/toolkit": "^1.9.5",
|
"@reduxjs/toolkit": "^1.9.5",
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { Menu, Transition } from '@headlessui/react';
|
import { Menu, Transition } from '@headlessui/react';
|
||||||
|
import { Float } from '@headlessui-float/react';
|
||||||
import { Icon } from '@iconify/react';
|
import { Icon } from '@iconify/react';
|
||||||
import cx from 'classnames';
|
import cx from 'classnames';
|
||||||
import { Fragment } from 'react';
|
import { Fragment } from 'react';
|
||||||
|
@ -23,66 +24,66 @@ interface Props {
|
||||||
|
|
||||||
export function DropDown({ label, options, className }: Props) {
|
export function DropDown({ label, options, className }: Props) {
|
||||||
return (
|
return (
|
||||||
<div className="text-right">
|
<div className="relative text-right">
|
||||||
<Menu as="div" className={`relative inline-block text-left ${className}`}>
|
<Menu as="div" className={`inline-block text-left ${className}`}>
|
||||||
<div>
|
<Float placement="bottom-end" flip portal>
|
||||||
<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">
|
<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">
|
||||||
{label}
|
{label}
|
||||||
<Icon icon="mdi:chevron-down" />
|
<Icon icon="mdi:chevron-down" />
|
||||||
</Menu.Button>
|
</Menu.Button>
|
||||||
</div>
|
<Transition
|
||||||
<Transition
|
as={Fragment}
|
||||||
as={Fragment}
|
enter="transition ease-out duration-100"
|
||||||
enter="transition ease-out duration-100"
|
enterFrom="transform opacity-0 scale-95"
|
||||||
enterFrom="transform opacity-0 scale-95"
|
enterTo="transform opacity-100 scale-100"
|
||||||
enterTo="transform opacity-100 scale-100"
|
leave="transition ease-in duration-75"
|
||||||
leave="transition ease-in duration-75"
|
leaveFrom="transform opacity-100 scale-100"
|
||||||
leaveFrom="transform opacity-100 scale-100"
|
leaveTo="transform opacity-0 scale-95"
|
||||||
leaveTo="transform opacity-0 scale-95"
|
>
|
||||||
>
|
<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">
|
||||||
<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">
|
<div className="px-1 py-1 ">
|
||||||
<div className="px-1 py-1 ">
|
{options.map((option, idx) => {
|
||||||
{options.map((option, idx) => {
|
if (option.type === 'separator') {
|
||||||
if (option.type === 'separator') {
|
return (
|
||||||
|
<div
|
||||||
|
className="m-1 border-t-[1px] border-t-slate-500"
|
||||||
|
// eslint-disable-next-line react/no-array-index-key
|
||||||
|
key={`divider-${idx}`}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<div
|
// eslint-disable-next-line react/no-array-index-key
|
||||||
className="m-1 border-t-[1px] border-t-slate-500"
|
<Menu.Item key={idx.toString()}>
|
||||||
// eslint-disable-next-line react/no-array-index-key
|
{({ active }) =>
|
||||||
key={`divider-${idx}`}
|
option.onClick !== null ? (
|
||||||
/>
|
<button
|
||||||
|
className={cx(
|
||||||
|
'group flex w-full items-center rounded-md px-2 py-2 text-sm',
|
||||||
|
{ 'bg-slate-200 dark:bg-slate-800': active }
|
||||||
|
)}
|
||||||
|
type="button"
|
||||||
|
onClick={option.onClick}
|
||||||
|
>
|
||||||
|
{option.label}
|
||||||
|
</button>
|
||||||
|
) : (
|
||||||
|
<div
|
||||||
|
className={cx(
|
||||||
|
'group mt-2 flex w-full items-center rounded-md px-2'
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{option.label}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</Menu.Item>
|
||||||
);
|
);
|
||||||
}
|
})}
|
||||||
return (
|
</div>
|
||||||
// eslint-disable-next-line react/no-array-index-key
|
</Menu.Items>
|
||||||
<Menu.Item key={idx.toString()}>
|
</Transition>
|
||||||
{({ active }) =>
|
</Float>
|
||||||
option.onClick !== null ? (
|
|
||||||
<button
|
|
||||||
className={cx(
|
|
||||||
'group flex w-full items-center rounded-md px-2 py-2 text-sm',
|
|
||||||
{ 'bg-slate-200 dark:bg-slate-800': active }
|
|
||||||
)}
|
|
||||||
type="button"
|
|
||||||
onClick={option.onClick}
|
|
||||||
>
|
|
||||||
{option.label}
|
|
||||||
</button>
|
|
||||||
) : (
|
|
||||||
<div
|
|
||||||
className={cx(
|
|
||||||
'group mt-2 flex w-full items-center rounded-md px-2'
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
{option.label}
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
</Menu.Item>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
</Menu.Items>
|
|
||||||
</Transition>
|
|
||||||
</Menu>
|
</Menu>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1381,6 +1381,42 @@
|
||||||
resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.36.0.tgz#9837f768c03a1e4a30bd304a64fb8844f0e72efe"
|
resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.36.0.tgz#9837f768c03a1e4a30bd304a64fb8844f0e72efe"
|
||||||
integrity sha512-lxJ9R5ygVm8ZWgYdUweoq5ownDlJ4upvoWmO4eLxBYHdMo+vZ/Rx0EN6MbKWDJOSUGrqJy2Gt+Dyv/VKml0fjg==
|
integrity sha512-lxJ9R5ygVm8ZWgYdUweoq5ownDlJ4upvoWmO4eLxBYHdMo+vZ/Rx0EN6MbKWDJOSUGrqJy2Gt+Dyv/VKml0fjg==
|
||||||
|
|
||||||
|
"@floating-ui/core@^1.3.0", "@floating-ui/core@^1.4.2":
|
||||||
|
version "1.5.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.5.0.tgz#5c05c60d5ae2d05101c3021c1a2a350ddc027f8c"
|
||||||
|
integrity sha512-kK1h4m36DQ0UHGj5Ah4db7R0rHemTqqO0QLvUqi1/mUUp3LuAWbWxdxSIf/XsnH9VS6rRVPLJCncjRzUvyCLXg==
|
||||||
|
dependencies:
|
||||||
|
"@floating-ui/utils" "^0.1.3"
|
||||||
|
|
||||||
|
"@floating-ui/dom@^1.3.0", "@floating-ui/dom@^1.5.1":
|
||||||
|
version "1.5.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.5.3.tgz#54e50efcb432c06c23cd33de2b575102005436fa"
|
||||||
|
integrity sha512-ClAbQnEqJAKCJOEbbLo5IUlZHkNszqhuxS4fHAVxRPXPya6Ysf2G8KypnYcOTpx6I8xcgF9bbHb6g/2KpbV8qA==
|
||||||
|
dependencies:
|
||||||
|
"@floating-ui/core" "^1.4.2"
|
||||||
|
"@floating-ui/utils" "^0.1.3"
|
||||||
|
|
||||||
|
"@floating-ui/react-dom@^2.0.3":
|
||||||
|
version "2.0.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/@floating-ui/react-dom/-/react-dom-2.0.4.tgz#b076fafbdfeb881e1d86ae748b7ff95150e9f3ec"
|
||||||
|
integrity sha512-CF8k2rgKeh/49UrnIBs4BdxPUV6vize/Db1d/YbCLyp9GiVZ0BEwf5AiDSxJRCr6yOkGqTFHtmrULxkEfYZ7dQ==
|
||||||
|
dependencies:
|
||||||
|
"@floating-ui/dom" "^1.5.1"
|
||||||
|
|
||||||
|
"@floating-ui/react@^0.26.0":
|
||||||
|
version "0.26.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@floating-ui/react/-/react-0.26.2.tgz#1a548f0f9aae64a742c868ae36aa620d15dec728"
|
||||||
|
integrity sha512-ocpz3MxYoZlgsASiVFayiTnKukR8QZDQUMqxMdF0YFLbu8lw/IL6AHKLROI8SOpp6CxpUGPh9Q4a03eBAVEZNQ==
|
||||||
|
dependencies:
|
||||||
|
"@floating-ui/react-dom" "^2.0.3"
|
||||||
|
"@floating-ui/utils" "^0.1.5"
|
||||||
|
tabbable "^6.0.1"
|
||||||
|
|
||||||
|
"@floating-ui/utils@^0.1.3", "@floating-ui/utils@^0.1.5":
|
||||||
|
version "0.1.6"
|
||||||
|
resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.1.6.tgz#22958c042e10b67463997bd6ea7115fe28cbcaf9"
|
||||||
|
integrity sha512-OfX7E2oUDYxtBvsuS4e/jSn4Q9Qb6DzgeYtsAdkPZ47znpoNsMgZw0+tVijiv3uGNR6dgNlty6r9rzIzHjtd/A==
|
||||||
|
|
||||||
"@fontsource/lato@^5.0.17":
|
"@fontsource/lato@^5.0.17":
|
||||||
version "5.0.17"
|
version "5.0.17"
|
||||||
resolved "https://registry.yarnpkg.com/@fontsource/lato/-/lato-5.0.17.tgz#7c75c443da1e3ae203ed1977b6455bb15c62c106"
|
resolved "https://registry.yarnpkg.com/@fontsource/lato/-/lato-5.0.17.tgz#7c75c443da1e3ae203ed1977b6455bb15c62c106"
|
||||||
|
@ -1399,6 +1435,15 @@
|
||||||
normalize-path "^2.0.1"
|
normalize-path "^2.0.1"
|
||||||
through2 "^2.0.3"
|
through2 "^2.0.3"
|
||||||
|
|
||||||
|
"@headlessui-float/react@^0.12.0":
|
||||||
|
version "0.12.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@headlessui-float/react/-/react-0.12.0.tgz#092ef8ee39a87526895f314fe8e4765e2e077cda"
|
||||||
|
integrity sha512-/oikFriS8t5nirJnRlHrvltrGx0PwhGUsUFNxxyfLOC/wNGX8k5kvNy+XCmSXBJ3fCYsSHYaDsPLct3lWDMXuw==
|
||||||
|
dependencies:
|
||||||
|
"@floating-ui/core" "^1.3.0"
|
||||||
|
"@floating-ui/dom" "^1.3.0"
|
||||||
|
"@floating-ui/react" "^0.26.0"
|
||||||
|
|
||||||
"@headlessui/react@^1.7.4":
|
"@headlessui/react@^1.7.4":
|
||||||
version "1.7.4"
|
version "1.7.4"
|
||||||
resolved "https://registry.yarnpkg.com/@headlessui/react/-/react-1.7.4.tgz#ba7f50fda20667276ee84fcd4c2a459aa26187e3"
|
resolved "https://registry.yarnpkg.com/@headlessui/react/-/react-1.7.4.tgz#ba7f50fda20667276ee84fcd4c2a459aa26187e3"
|
||||||
|
@ -12960,6 +13005,11 @@ synckit@^0.8.4:
|
||||||
"@pkgr/utils" "^2.3.1"
|
"@pkgr/utils" "^2.3.1"
|
||||||
tslib "^2.4.0"
|
tslib "^2.4.0"
|
||||||
|
|
||||||
|
tabbable@^6.0.1:
|
||||||
|
version "6.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/tabbable/-/tabbable-6.2.0.tgz#732fb62bc0175cfcec257330be187dcfba1f3b97"
|
||||||
|
integrity sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==
|
||||||
|
|
||||||
tailwindcss@^3.1.4:
|
tailwindcss@^3.1.4:
|
||||||
version "3.2.1"
|
version "3.2.1"
|
||||||
resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.2.1.tgz#1bd828fff3172489962357f8d531c184080a6786"
|
resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.2.1.tgz#1bd828fff3172489962357f8d531c184080a6786"
|
||||||
|
|
Loading…
Reference in a new issue