@ -112,11 +112,11 @@ const DropdownMenuItem = ({ index, item, onClick, autoFocus, onSetTab }: IDropdo
|
||||
}, [itemRef.current, index]);
|
||||
|
||||
if (item === null) {
|
||||
return <hr className='mx-2 my-1 block h-[2px] border-none bg-gray-100 dark:bg-gray-800' />;
|
||||
return <hr />;
|
||||
}
|
||||
|
||||
return (
|
||||
<li className='truncate focus-visible:ring-2 focus-visible:ring-primary-500'>
|
||||
<li>
|
||||
<a
|
||||
href={item.href || item.to || '#'}
|
||||
role='button'
|
||||
|
||||
@ -5,7 +5,6 @@ import React, { useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
import ReactSwipeableViews from 'react-swipeable-views';
|
||||
|
||||
import HStack from '@/components/ui/hstack';
|
||||
import IconButton from '@/components/ui/icon-button';
|
||||
import Portal from '@/components/ui/portal';
|
||||
import { userTouching } from '@/is-mobile';
|
||||
@ -136,7 +135,7 @@ const DropdownMenuContent: React.FC<IDropdownMenuContent> = ({ handleClose, item
|
||||
};
|
||||
|
||||
const renderItems = (items: Menu | undefined) => (
|
||||
<ul className='overflow-hidden'>
|
||||
<ul className='⁂-dropdown-menu__items'>
|
||||
{items?.map((item, idx) => (
|
||||
<DropdownMenuItem
|
||||
key={idx}
|
||||
@ -151,27 +150,26 @@ const DropdownMenuContent: React.FC<IDropdownMenuContent> = ({ handleClose, item
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={clsx('max-h-full overflow-auto', className)} ref={ref}>
|
||||
<div className={clsx('⁂-dropdown-menu__content', className)} ref={ref}>
|
||||
{items?.some(item => item?.items?.length) ? (
|
||||
<ReactSwipeableViews animateHeight index={tab === undefined ? 0 : 1} style={{ width }}>
|
||||
<div className={clsx('max-w-full', { 'w-full': touchscreen })} style={{ width }}>
|
||||
<div className='⁂-dropdown-menu__page' style={{ width }}>
|
||||
{Component && <Component handleClose={handleClose} />}
|
||||
{(items?.length || touchscreen) && renderItems(items)}
|
||||
</div>
|
||||
<div className={clsx({ 'w-full': touchscreen, 'fit-content mr-auto': !touchscreen })} style={{ width }}>
|
||||
<div className='⁂-dropdown-menu__expanded-page' style={{ width }}>
|
||||
{tab !== undefined && (
|
||||
<>
|
||||
<HStack className='mx-2 my-1 text-gray-700 dark:text-gray-300' space={3} alignItems='center'>
|
||||
<div className='⁂-dropdown-menu__header'>
|
||||
<IconButton
|
||||
theme='transparent'
|
||||
src={require('@phosphor-icons/core/regular/arrow-left.svg')}
|
||||
iconClassName='h-5 w-5'
|
||||
onClick={handleExitSubmenu}
|
||||
autoFocus
|
||||
title={intl.formatMessage(messages.back)}
|
||||
/>
|
||||
{items![tab]?.text}
|
||||
</HStack>
|
||||
</div>
|
||||
{renderItems(items![tab]?.items)}
|
||||
</>
|
||||
)}
|
||||
|
||||
@ -30,22 +30,16 @@ const DropdownMenuModal: React.FC<BaseModalProps & DropdownMenuModalProps> = ({
|
||||
return (
|
||||
<div
|
||||
id='dropdown-menu-modal'
|
||||
className='absolute inset-0'
|
||||
className={clsx('⁂-dropdown-menu-modal', {
|
||||
'⁂-dropdown-menu-modal--first-render': firstRender,
|
||||
})}
|
||||
role='presentation'
|
||||
onClick={handleClickOutside}
|
||||
>
|
||||
<div
|
||||
className={clsx('pointer-events-auto fixed inset-x-0 z-[1001] mx-auto max-h-[calc(100dvh-1rem)] w-[calc(100vw-2rem)] max-w-lg overflow-auto rounded-t-xl bg-white py-1 shadow-lg duration-200 ease-in-out focus:outline-none black:bg-black no-reduce-motion:transition-all dark:bg-gray-900 dark:ring-2 dark:ring-primary-700', {
|
||||
'bottom-0 opacity-100': !firstRender,
|
||||
'no-reduce-motion:-bottom-32 no-reduce-motion:opacity-0': firstRender,
|
||||
})}
|
||||
>
|
||||
<div>
|
||||
{content}
|
||||
<div className='p-2 px-3'>
|
||||
<button
|
||||
className='flex w-full appearance-none place-content-center items-center rounded-full border border-gray-700 bg-transparent p-2 text-sm font-medium text-gray-700 transition-all hover:bg-white/10 focus:outline-none focus:ring-2 focus:ring-offset-2 dark:border-gray-500 dark:text-gray-500'
|
||||
onClick={handleClick}
|
||||
>
|
||||
<div className='⁂-dropdown-menu-modal__close'>
|
||||
<button onClick={handleClick}>
|
||||
<FormattedMessage id='lightbox.close' defaultMessage='Close' />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@ -299,20 +299,6 @@ a.⁂-list-item,
|
||||
}
|
||||
}
|
||||
|
||||
.⁂-dropdown-menu {
|
||||
z-index: 1001;
|
||||
display: flex;
|
||||
|
||||
> div {
|
||||
z-index: 1001;
|
||||
@apply bg-white py-1 shadow-lg ease-in-out focus:outline-none black:bg-black no-reduce-motion:transition-all dark:bg-gray-900 dark:ring-2 dark:ring-primary-700 rounded-md min-w-56 max-w-sm duration-100;
|
||||
}
|
||||
|
||||
&__arrow {
|
||||
@apply pointer-events-none absolute z-[-1] size-3 bg-white black:bg-black dark:bg-gray-900;
|
||||
}
|
||||
}
|
||||
|
||||
.⁂-autosuggest-suggestions {
|
||||
@apply fixed w-full z-[1001] shadow bg-white dark:bg-gray-900 rounded-lg py-1 dark:ring-2 dark:ring-primary-700 focus:outline-none hidden;
|
||||
|
||||
@ -438,4 +424,54 @@ div[data-viewport-type="window"]:has(.⁂-empty-message) {
|
||||
p {
|
||||
@include mixins.text($align: center, $theme: muted);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
.⁂-dropdown-menu {
|
||||
z-index: 1001;
|
||||
display: flex;
|
||||
|
||||
> div {
|
||||
z-index: 1001;
|
||||
@apply bg-white py-1 shadow-lg ease-in-out focus:outline-none black:bg-black no-reduce-motion:transition-all dark:bg-gray-900 dark:ring-2 dark:ring-primary-700 rounded-md min-w-56 max-w-sm duration-100;
|
||||
}
|
||||
|
||||
&__arrow {
|
||||
@apply pointer-events-none absolute z-[-1] size-3 bg-white black:bg-black dark:bg-gray-900;
|
||||
}
|
||||
|
||||
&__content {
|
||||
max-height: 100%;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
&__page {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
&__expanded-page {
|
||||
width: fit-content;
|
||||
@apply mr-auto;
|
||||
}
|
||||
|
||||
&__header {
|
||||
@apply flex gap-3 items-center mx-2 my-1 text-gray-700 dark:text-gray-300;
|
||||
|
||||
svg {
|
||||
@apply h-5 w-5;
|
||||
}
|
||||
}
|
||||
|
||||
&__items {
|
||||
overflow: hidden;
|
||||
|
||||
hr {
|
||||
@apply mx-2 my-1 block h-[2px] border-none bg-gray-100 dark:bg-gray-800;
|
||||
}
|
||||
|
||||
li {
|
||||
@apply truncate focus-visible:ring-2 focus-visible:ring-primary-500;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -135,4 +135,38 @@
|
||||
border-radius: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.⁂-dropdown-menu-modal {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
|
||||
> div {
|
||||
@apply pointer-events-auto fixed inset-x-0 z-[1001] mx-auto max-h-[calc(100dvh-1rem)] w-[calc(100vw-2rem)] max-w-lg overflow-auto rounded-t-xl bg-white py-1 shadow-lg duration-200 ease-in-out focus:outline-none black:bg-black no-reduce-motion:transition-all dark:bg-gray-900 dark:ring-2 dark:ring-primary-700;
|
||||
}
|
||||
|
||||
&:not(&--first-render) {
|
||||
> div {
|
||||
@apply bottom-0 opacity-100;
|
||||
}
|
||||
}
|
||||
|
||||
&--first-render {
|
||||
> div {
|
||||
@apply no-reduce-motion:-bottom-32 no-reduce-motion:opacity-0;
|
||||
}
|
||||
}
|
||||
|
||||
&__close {
|
||||
@apply p-2 px-3;
|
||||
|
||||
button {
|
||||
@apply flex w-full appearance-none place-content-center items-center rounded-full border border-gray-700 bg-transparent p-2 text-sm font-medium text-gray-700 transition-all hover:bg-white/10 focus:outline-none focus:ring-2 focus:ring-offset-2 dark:border-gray-500 dark:text-gray-500;
|
||||
}
|
||||
}
|
||||
|
||||
.⁂-dropdown-menu__page,
|
||||
.⁂-dropdown-menu__expanded-page {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user