mirror of
https://github.com/langgenius/dify.git
synced 2026-05-05 01:48:04 +08:00
chore: change headlessui api to new
This commit is contained in:
@ -1,6 +1,6 @@
|
||||
import { Fragment, useCallback } from 'react'
|
||||
import type { ElementType, ReactNode } from 'react'
|
||||
import { Dialog, Transition } from '@headlessui/react'
|
||||
import { Dialog, DialogPanel, DialogTitle, Transition } from '@headlessui/react'
|
||||
import classNames from '@/utils/classnames'
|
||||
|
||||
// https://headlessui.com/react/dialog
|
||||
@ -34,7 +34,7 @@ const CustomDialog = ({
|
||||
return (
|
||||
<Transition appear show={show} as={Fragment}>
|
||||
<Dialog as="div" className="relative z-40" onClose={close}>
|
||||
<Transition.Child
|
||||
{/* <Transition.Child
|
||||
as={Fragment}
|
||||
enter="ease-out duration-300"
|
||||
enterFrom="opacity-0"
|
||||
@ -44,11 +44,13 @@ const CustomDialog = ({
|
||||
leaveTo="opacity-0"
|
||||
>
|
||||
<div className="fixed inset-0 bg-black bg-opacity-25" />
|
||||
</Transition.Child>
|
||||
</Transition.Child> */}
|
||||
{/* TODO: to new Transition */}
|
||||
<div className="fixed inset-0 bg-black bg-opacity-25" />
|
||||
|
||||
<div className="fixed inset-0 overflow-y-auto">
|
||||
<div className="flex items-center justify-center min-h-full">
|
||||
<Transition.Child
|
||||
{/* <Transition.Child
|
||||
as={Fragment}
|
||||
enter="ease-out duration-300"
|
||||
enterFrom="opacity-0 scale-95"
|
||||
@ -57,14 +59,14 @@ const CustomDialog = ({
|
||||
leaveFrom="opacity-100 scale-100"
|
||||
leaveTo="opacity-0 scale-95"
|
||||
>
|
||||
<Dialog.Panel className={classNames('w-full max-w-[800px] p-6 overflow-hidden transition-all transform bg-components-panel-bg border-[0.5px] border-components-panel-border shadow-xl rounded-2xl', className)}>
|
||||
<DialogPanel className={classNames('w-full max-w-[800px] p-6 overflow-hidden transition-all transform bg-components-panel-bg border-[0.5px] border-components-panel-border shadow-xl rounded-2xl', className)}>
|
||||
{Boolean(title) && (
|
||||
<Dialog.Title
|
||||
<DialogTitle
|
||||
as={titleAs || 'h3'}
|
||||
className={classNames('pr-8 pb-3 title-2xl-semi-bold text-text-primary', titleClassName)}
|
||||
>
|
||||
{title}
|
||||
</Dialog.Title>
|
||||
</DialogTitle>
|
||||
)}
|
||||
<div className={classNames(bodyClassName)}>
|
||||
{children}
|
||||
@ -74,8 +76,27 @@ const CustomDialog = ({
|
||||
{footer}
|
||||
</div>
|
||||
)}
|
||||
</Dialog.Panel>
|
||||
</Transition.Child>
|
||||
</DialogPanel>
|
||||
</Transition.Child> */}
|
||||
{/* TODO: to new Transition */}
|
||||
<DialogPanel className={classNames('w-full max-w-[800px] p-6 overflow-hidden transition-all transform bg-components-panel-bg border-[0.5px] border-components-panel-border shadow-xl rounded-2xl', className)}>
|
||||
{Boolean(title) && (
|
||||
<DialogTitle
|
||||
as={titleAs || 'h3'}
|
||||
className={classNames('pr-8 pb-3 title-2xl-semi-bold text-text-primary', titleClassName)}
|
||||
>
|
||||
{title}
|
||||
</DialogTitle>
|
||||
)}
|
||||
<div className={classNames(bodyClassName)}>
|
||||
{children}
|
||||
</div>
|
||||
{Boolean(footer) && (
|
||||
<div className={classNames('flex items-center justify-end gap-2 px-6 pb-6 pt-3', footerClassName)}>
|
||||
{footer}
|
||||
</div>
|
||||
)}
|
||||
</DialogPanel>
|
||||
</div>
|
||||
</div>
|
||||
</Dialog>
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
'use client'
|
||||
import { Dialog } from '@headlessui/react'
|
||||
import { Dialog, DialogBackdrop, DialogTitle } from '@headlessui/react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { XMarkIcon } from '@heroicons/react/24/outline'
|
||||
import Button from '../button'
|
||||
@ -48,21 +48,21 @@ export default function Drawer({
|
||||
>
|
||||
<div className={cn('flex w-screen h-screen justify-end', positionCenter && '!justify-center')}>
|
||||
{/* mask */}
|
||||
<Dialog.Overlay
|
||||
<DialogBackdrop
|
||||
className={cn('z-40 fixed inset-0', mask && 'bg-black bg-opacity-30')}
|
||||
/>
|
||||
<div className={cn('relative z-50 flex flex-col justify-between bg-components-panel-bg w-full max-w-sm p-6 overflow-hidden text-left align-middle shadow-xl', panelClassname)}>
|
||||
<>
|
||||
{title && <Dialog.Title
|
||||
{title && <DialogTitle
|
||||
as="h3"
|
||||
className="text-lg font-medium leading-6 text-text-primary"
|
||||
>
|
||||
{title}
|
||||
</Dialog.Title>}
|
||||
{showClose && <Dialog.Title className="flex items-center mb-4" as="div">
|
||||
</DialogTitle>}
|
||||
{showClose && <DialogTitle className="flex items-center mb-4" as="div">
|
||||
<XMarkIcon className='w-4 h-4 text-text-tertiary' onClick={onClose} />
|
||||
</Dialog.Title>}
|
||||
{description && <Dialog.Description className='text-text-tertiary text-xs font-normal mt-2'>{description}</Dialog.Description>}
|
||||
</DialogTitle>}
|
||||
{description && <div className='text-text-tertiary text-xs font-normal mt-2'>{description}</div>}
|
||||
{children}
|
||||
</>
|
||||
{footer || (footer === null
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { Fragment, useCallback } from 'react'
|
||||
import type { ReactNode } from 'react'
|
||||
import { Dialog, Transition } from '@headlessui/react'
|
||||
import { Dialog, DialogPanel, Transition } from '@headlessui/react'
|
||||
import cn from '@/utils/classnames'
|
||||
|
||||
type DialogProps = {
|
||||
@ -22,7 +22,7 @@ const DialogWrapper = ({
|
||||
return (
|
||||
<Transition appear show={show} as={Fragment}>
|
||||
<Dialog as="div" className="relative z-40" onClose={close}>
|
||||
<Transition.Child
|
||||
{/* <Transition.Child
|
||||
as={Fragment}
|
||||
enter="ease-out duration-300"
|
||||
enterFrom="opacity-0"
|
||||
@ -32,11 +32,13 @@ const DialogWrapper = ({
|
||||
leaveTo="opacity-0"
|
||||
>
|
||||
<div className="fixed inset-0 bg-black bg-opacity-25" />
|
||||
</Transition.Child>
|
||||
</Transition.Child> */}
|
||||
{/* TODO: to new Transition */}
|
||||
<div className="fixed inset-0 bg-black bg-opacity-25" />
|
||||
|
||||
<div className="fixed inset-0">
|
||||
<div className={cn('flex flex-col items-end justify-center min-h-full pb-2', inWorkflow ? 'pt-[112px]' : 'pt-[64px] pr-2')}>
|
||||
<Transition.Child
|
||||
{/* <Transition.Child
|
||||
as={Fragment}
|
||||
enter="ease-out duration-300"
|
||||
enterFrom="opacity-0 scale-95"
|
||||
@ -45,10 +47,14 @@ const DialogWrapper = ({
|
||||
leaveFrom="opacity-100 scale-100"
|
||||
leaveTo="opacity-0 scale-95"
|
||||
>
|
||||
<Dialog.Panel className={cn('grow flex flex-col relative w-[420px] h-0 p-0 overflow-hidden text-left align-middle transition-all transform bg-components-panel-bg-alt border-components-panel-border shadow-xl', inWorkflow ? 'border-t-[0.5px] border-l-[0.5px] border-b-[0.5px] rounded-l-2xl' : 'border-[0.5px] rounded-2xl', className)}>
|
||||
<DialogPanel className={cn('grow flex flex-col relative w-[420px] h-0 p-0 overflow-hidden text-left align-middle transition-all transform bg-components-panel-bg-alt border-components-panel-border shadow-xl', inWorkflow ? 'border-t-[0.5px] border-l-[0.5px] border-b-[0.5px] rounded-l-2xl' : 'border-[0.5px] rounded-2xl', className)}>
|
||||
{children}
|
||||
</Dialog.Panel>
|
||||
</Transition.Child>
|
||||
</DialogPanel>
|
||||
</Transition.Child> */}
|
||||
{/* TODO: to new Transition */}
|
||||
<DialogPanel className={cn('grow flex flex-col relative w-[420px] h-0 p-0 overflow-hidden text-left align-middle transition-all transform bg-components-panel-bg-alt border-components-panel-border shadow-xl', inWorkflow ? 'border-t-[0.5px] border-l-[0.5px] border-b-[0.5px] rounded-l-2xl' : 'border-[0.5px] rounded-2xl', className)}>
|
||||
{children}
|
||||
</DialogPanel>
|
||||
</div>
|
||||
</div>
|
||||
</Dialog>
|
||||
|
||||
@ -5,7 +5,7 @@ import React, { Fragment } from 'react'
|
||||
import { usePathname } from 'next/navigation'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { RiCloseLine } from '@remixicon/react'
|
||||
import { Listbox, Transition } from '@headlessui/react'
|
||||
import { Listbox, ListboxButton, ListboxOption, ListboxOptions, Transition } from '@headlessui/react'
|
||||
import { CheckIcon, ChevronDownIcon } from '@heroicons/react/20/solid'
|
||||
import { useFeatures, useFeaturesStore } from '@/app/components/base/features/hooks'
|
||||
import type { Item } from '@/app/components/base/select'
|
||||
@ -67,7 +67,7 @@ const VoiceParamConfig = ({
|
||||
<>
|
||||
<div className='mb-4 flex items-center justify-between'>
|
||||
<div className='text-text-primary system-xl-semibold'>{t('appDebug.voice.voiceSettings.title')}</div>
|
||||
<div className='p-1 cursor-pointer' onClick={onClose}><RiCloseLine className='w-4 h-4 text-text-tertiary'/></div>
|
||||
<div className='p-1 cursor-pointer' onClick={onClose}><RiCloseLine className='w-4 h-4 text-text-tertiary' /></div>
|
||||
</div>
|
||||
<div className='mb-3'>
|
||||
<div className='mb-1 py-1 flex items-center text-text-secondary system-sm-semibold'>
|
||||
@ -92,7 +92,7 @@ const VoiceParamConfig = ({
|
||||
}}
|
||||
>
|
||||
<div className='relative h-8'>
|
||||
<Listbox.Button
|
||||
<ListboxButton
|
||||
className={'w-full h-full rounded-lg border-0 bg-gray-100 py-1.5 pl-3 pr-10 sm:text-sm sm:leading-6 focus-visible:outline-none focus-visible:bg-gray-200 group-hover:bg-gray-200 cursor-pointer'}>
|
||||
<span className={classNames('block truncate text-left', !languageItem?.name && 'text-gray-400')}>
|
||||
{languageItem?.name ? t(`common.voice.language.${languageItem?.value.replace('-', '')}`) : localLanguagePlaceholder}
|
||||
@ -103,7 +103,7 @@ const VoiceParamConfig = ({
|
||||
aria-hidden="true"
|
||||
/>
|
||||
</span>
|
||||
</Listbox.Button>
|
||||
</ListboxButton>
|
||||
<Transition
|
||||
as={Fragment}
|
||||
leave="transition ease-in duration-100"
|
||||
@ -111,10 +111,10 @@ const VoiceParamConfig = ({
|
||||
leaveTo="opacity-0"
|
||||
>
|
||||
|
||||
<Listbox.Options
|
||||
<ListboxOptions
|
||||
className="absolute z-10 mt-1 px-1 max-h-60 w-full overflow-auto rounded-md bg-white py-1 text-base shadow-lg border-gray-200 border-[0.5px] focus:outline-none sm:text-sm">
|
||||
{languages.map((item: Item) => (
|
||||
<Listbox.Option
|
||||
<ListboxOption
|
||||
key={item.value}
|
||||
className={({ active }) =>
|
||||
`relative cursor-pointer select-none py-2 pl-3 pr-9 rounded-lg hover:bg-gray-100 text-gray-700 ${active ? 'bg-gray-100' : ''
|
||||
@ -133,14 +133,14 @@ const VoiceParamConfig = ({
|
||||
'absolute inset-y-0 right-0 flex items-center pr-4 text-gray-700',
|
||||
)}
|
||||
>
|
||||
<CheckIcon className="h-5 w-5" aria-hidden="true"/>
|
||||
<CheckIcon className="h-5 w-5" aria-hidden="true" />
|
||||
</span>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</Listbox.Option>
|
||||
</ListboxOption>
|
||||
))}
|
||||
</Listbox.Options>
|
||||
</ListboxOptions>
|
||||
</Transition>
|
||||
</div>
|
||||
</Listbox>
|
||||
@ -160,7 +160,7 @@ const VoiceParamConfig = ({
|
||||
}}
|
||||
>
|
||||
<div className={'grow relative h-8'}>
|
||||
<Listbox.Button
|
||||
<ListboxButton
|
||||
className={'w-full h-full rounded-lg border-0 bg-gray-100 py-1.5 pl-3 pr-10 sm:text-sm sm:leading-6 focus-visible:outline-none focus-visible:bg-gray-200 group-hover:bg-gray-200 cursor-pointer'}>
|
||||
<span
|
||||
className={classNames('block truncate text-left', !voiceItem?.name && 'text-gray-400')}>{voiceItem?.name ?? localVoicePlaceholder}</span>
|
||||
@ -170,7 +170,7 @@ const VoiceParamConfig = ({
|
||||
aria-hidden="true"
|
||||
/>
|
||||
</span>
|
||||
</Listbox.Button>
|
||||
</ListboxButton>
|
||||
<Transition
|
||||
as={Fragment}
|
||||
leave="transition ease-in duration-100"
|
||||
@ -178,10 +178,10 @@ const VoiceParamConfig = ({
|
||||
leaveTo="opacity-0"
|
||||
>
|
||||
|
||||
<Listbox.Options
|
||||
<ListboxOptions
|
||||
className="absolute z-10 mt-1 px-1 max-h-60 w-full overflow-auto rounded-md bg-white py-1 text-base shadow-lg border-gray-200 border-[0.5px] focus:outline-none sm:text-sm">
|
||||
{voiceItems?.map((item: Item) => (
|
||||
<Listbox.Option
|
||||
<ListboxOption
|
||||
key={item.value}
|
||||
className={({ active }) =>
|
||||
`relative cursor-pointer select-none py-2 pl-3 pr-9 rounded-lg hover:bg-gray-100 text-gray-700 ${active ? 'bg-gray-100' : ''
|
||||
@ -199,14 +199,14 @@ const VoiceParamConfig = ({
|
||||
'absolute inset-y-0 right-0 flex items-center pr-4 text-gray-700',
|
||||
)}
|
||||
>
|
||||
<CheckIcon className="h-5 w-5" aria-hidden="true"/>
|
||||
<CheckIcon className="h-5 w-5" aria-hidden="true" />
|
||||
</span>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</Listbox.Option>
|
||||
</ListboxOption>
|
||||
))}
|
||||
</Listbox.Options>
|
||||
</ListboxOptions>
|
||||
</Transition>
|
||||
</div>
|
||||
</Listbox>
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { Dialog, Transition } from '@headlessui/react'
|
||||
import { Dialog, DialogPanel, Transition } from '@headlessui/react'
|
||||
import { Fragment } from 'react'
|
||||
import { RiCloseLargeLine } from '@remixicon/react'
|
||||
import classNames from '@/utils/classnames'
|
||||
@ -27,7 +27,7 @@ export default function FullScreenModal({
|
||||
return (
|
||||
<Transition show={open} as={Fragment}>
|
||||
<Dialog as="div" className={classNames('modal-dialog', wrapperClassName)} onClose={onClose}>
|
||||
<Transition.Child
|
||||
{/* <Transition.Child
|
||||
as={Fragment}
|
||||
enter="ease-out duration-300"
|
||||
enterFrom="opacity-0"
|
||||
@ -37,7 +37,9 @@ export default function FullScreenModal({
|
||||
leaveTo="opacity-0"
|
||||
>
|
||||
<div className="fixed inset-0 bg-background-overlay-backdrop backdrop-blur-[6px]" />
|
||||
</Transition.Child>
|
||||
</Transition.Child> */}
|
||||
{/* TODO: to new Transition */}
|
||||
<div className="fixed inset-0 bg-background-overlay-backdrop backdrop-blur-[6px]" />
|
||||
|
||||
<div
|
||||
className="fixed inset-0 h-screen w-screen p-4"
|
||||
@ -47,7 +49,7 @@ export default function FullScreenModal({
|
||||
}}
|
||||
>
|
||||
<div className="w-full h-full bg-background-default-subtle rounded-2xl border border-effects-highlight relative">
|
||||
<Transition.Child
|
||||
{/* <Transition.Child
|
||||
as={Fragment}
|
||||
enter="ease-out duration-300"
|
||||
enterFrom="opacity-0 scale-95"
|
||||
@ -56,7 +58,7 @@ export default function FullScreenModal({
|
||||
leaveFrom="opacity-100 scale-100"
|
||||
leaveTo="opacity-0 scale-95"
|
||||
>
|
||||
<Dialog.Panel className={classNames(
|
||||
<DialogPanel className={classNames(
|
||||
'h-full',
|
||||
overflowVisible ? 'overflow-visible' : 'overflow-hidden',
|
||||
className,
|
||||
@ -72,8 +74,26 @@ export default function FullScreenModal({
|
||||
<RiCloseLargeLine className='w-3.5 h-3.5 text-components-button-tertiary-text' />
|
||||
</div>}
|
||||
{children}
|
||||
</Dialog.Panel>
|
||||
</Transition.Child>
|
||||
</DialogPanel>
|
||||
</Transition.Child> */}
|
||||
{/* TODO: to new Transition */}
|
||||
<DialogPanel className={classNames(
|
||||
'h-full',
|
||||
overflowVisible ? 'overflow-visible' : 'overflow-hidden',
|
||||
className,
|
||||
)}>
|
||||
{closable
|
||||
&& <div
|
||||
className='absolute z-50 top-3 right-3 w-9 h-9 flex items-center justify-center rounded-[10px]
|
||||
bg-components-button-tertiary-bg hover:bg-components-button-tertiary-bg-hover cursor-pointer'
|
||||
onClick={(e) => {
|
||||
e.stopPropagation()
|
||||
onClose()
|
||||
}}>
|
||||
<RiCloseLargeLine className='w-3.5 h-3.5 text-components-button-tertiary-text' />
|
||||
</div>}
|
||||
{children}
|
||||
</DialogPanel>
|
||||
</div>
|
||||
</div>
|
||||
</Dialog>
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { Dialog, Transition } from '@headlessui/react'
|
||||
import { Dialog, DialogPanel, DialogTitle, Transition } from '@headlessui/react'
|
||||
import { Fragment } from 'react'
|
||||
import { RiCloseLine } from '@remixicon/react'
|
||||
import classNames from '@/utils/classnames'
|
||||
@ -30,7 +30,7 @@ export default function Modal({
|
||||
return (
|
||||
<Transition appear show={isShow} as={Fragment}>
|
||||
<Dialog as="div" className={classNames('relative z-[60]', wrapperClassName)} onClose={onClose}>
|
||||
<Transition.Child
|
||||
{/* <Transition.Child
|
||||
as={Fragment}
|
||||
enter="ease-out duration-300"
|
||||
enterFrom="opacity-0"
|
||||
@ -40,7 +40,9 @@ export default function Modal({
|
||||
leaveTo="opacity-0"
|
||||
>
|
||||
<div className="fixed inset-0 bg-background-overlay" />
|
||||
</Transition.Child>
|
||||
</Transition.Child> */}
|
||||
{/* TODO: to new Transition */}
|
||||
<div className="fixed inset-0 bg-background-overlay" />
|
||||
|
||||
<div
|
||||
className="fixed inset-0 overflow-y-auto"
|
||||
@ -50,7 +52,7 @@ export default function Modal({
|
||||
}}
|
||||
>
|
||||
<div className="flex min-h-full items-center justify-center p-4 text-center">
|
||||
<Transition.Child
|
||||
{/* <Transition.Child
|
||||
as={Fragment}
|
||||
enter="ease-out duration-300"
|
||||
enterFrom="opacity-0 scale-95"
|
||||
@ -59,20 +61,20 @@ export default function Modal({
|
||||
leaveFrom="opacity-100 scale-100"
|
||||
leaveTo="opacity-0 scale-95"
|
||||
>
|
||||
<Dialog.Panel className={classNames(
|
||||
<DialogPanel className={classNames(
|
||||
'w-full max-w-[480px] transform rounded-2xl bg-components-panel-bg p-6 text-left align-middle shadow-xl transition-all',
|
||||
overflowVisible ? 'overflow-visible' : 'overflow-hidden',
|
||||
className,
|
||||
)}>
|
||||
{title && <Dialog.Title
|
||||
{title && <DialogTitle
|
||||
as="h3"
|
||||
className="title-2xl-semi-bold text-text-primary"
|
||||
>
|
||||
{title}
|
||||
</Dialog.Title>}
|
||||
{description && <Dialog.Description className='text-text-secondary body-md-regular mt-2'>
|
||||
</DialogTitle>}
|
||||
{description && <div className='text-text-secondary body-md-regular mt-2'>
|
||||
{description}
|
||||
</Dialog.Description>}
|
||||
</div>}
|
||||
{closable
|
||||
&& <div className='absolute z-10 top-6 right-6 w-5 h-5 rounded-2xl flex items-center justify-center hover:cursor-pointer hover:bg-state-base-hover'>
|
||||
<RiCloseLine className='w-4 h-4 text-text-tertiary' onClick={
|
||||
@ -83,8 +85,34 @@ export default function Modal({
|
||||
} />
|
||||
</div>}
|
||||
{children}
|
||||
</Dialog.Panel>
|
||||
</Transition.Child>
|
||||
</DialogPanel>
|
||||
</Transition.Child> */}
|
||||
{/* TODO: to new Transition */}
|
||||
<DialogPanel className={classNames(
|
||||
'w-full max-w-[480px] transform rounded-2xl bg-components-panel-bg p-6 text-left align-middle shadow-xl transition-all',
|
||||
overflowVisible ? 'overflow-visible' : 'overflow-hidden',
|
||||
className,
|
||||
)}>
|
||||
{title && <DialogTitle
|
||||
as="h3"
|
||||
className="title-2xl-semi-bold text-text-primary"
|
||||
>
|
||||
{title}
|
||||
</DialogTitle>}
|
||||
{description && <div className='text-text-secondary body-md-regular mt-2'>
|
||||
{description}
|
||||
</div>}
|
||||
{closable
|
||||
&& <div className='absolute z-10 top-6 right-6 w-5 h-5 rounded-2xl flex items-center justify-center hover:cursor-pointer hover:bg-state-base-hover'>
|
||||
<RiCloseLine className='w-4 h-4 text-text-tertiary' onClick={
|
||||
(e) => {
|
||||
e.stopPropagation()
|
||||
onClose()
|
||||
}
|
||||
} />
|
||||
</div>}
|
||||
{children}
|
||||
</DialogPanel>
|
||||
</div>
|
||||
</div>
|
||||
</Dialog>
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
'use client'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Fragment } from 'react'
|
||||
import { Menu, Transition } from '@headlessui/react'
|
||||
import { Menu, MenuButton, MenuItem, MenuItems, Transition } from '@headlessui/react'
|
||||
import NotionIcon from '../../notion-icon'
|
||||
import s from './index.module.css'
|
||||
import cn from '@/utils/classnames'
|
||||
@ -25,7 +25,7 @@ export default function WorkspaceSelector({
|
||||
{
|
||||
({ open }) => (
|
||||
<>
|
||||
<Menu.Button className={`flex items-center justify-center h-7 rounded-md hover:bg-gray-50 ${open && 'bg-gray-50'} cursor-pointer`}>
|
||||
<MenuButton className={`flex items-center justify-center h-7 rounded-md hover:bg-gray-50 ${open && 'bg-gray-50'} cursor-pointer`}>
|
||||
<NotionIcon
|
||||
className='ml-1 mr-2'
|
||||
src={currentWorkspace?.workspace_icon}
|
||||
@ -34,7 +34,7 @@ export default function WorkspaceSelector({
|
||||
<div className='mr-1 w-[90px] text-left text-sm font-medium text-gray-700 truncate' title={currentWorkspace?.workspace_name}>{currentWorkspace?.workspace_name}</div>
|
||||
<div className='mr-1 px-1 h-[18px] bg-primary-50 rounded-lg text-xs font-medium text-primary-600'>{currentWorkspace?.pages.length}</div>
|
||||
<div className={cn(s['down-arrow'], 'mr-2 w-3 h-3')} />
|
||||
</Menu.Button>
|
||||
</MenuButton>
|
||||
<Transition
|
||||
as={Fragment}
|
||||
enter="transition ease-out duration-100"
|
||||
@ -44,7 +44,7 @@ export default function WorkspaceSelector({
|
||||
leaveFrom="transform opacity-100 scale-100"
|
||||
leaveTo="transform opacity-0 scale-95"
|
||||
>
|
||||
<Menu.Items
|
||||
<MenuItems
|
||||
className={cn(
|
||||
s.popup,
|
||||
`absolute left-0 top-8 w-80
|
||||
@ -55,7 +55,7 @@ export default function WorkspaceSelector({
|
||||
<div className="p-1 max-h-50 overflow-auto">
|
||||
{
|
||||
items.map(item => (
|
||||
<Menu.Item key={item.workspace_id}>
|
||||
<MenuItem key={item.workspace_id}>
|
||||
<div
|
||||
className='flex items-center px-3 h-9 hover:bg-gray-50 cursor-pointer'
|
||||
onClick={() => onSelect(item.workspace_id)}
|
||||
@ -70,11 +70,11 @@ export default function WorkspaceSelector({
|
||||
{item.pages.length} {t('common.dataSource.notion.selector.pageSelected')}
|
||||
</div>
|
||||
</div>
|
||||
</Menu.Item>
|
||||
</MenuItem>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</Menu.Items>
|
||||
</MenuItems>
|
||||
</Transition>
|
||||
</>
|
||||
)
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { Popover, Transition } from '@headlessui/react'
|
||||
import { Popover, PopoverButton, PopoverPanel, Transition } from '@headlessui/react'
|
||||
import { Fragment, cloneElement, useRef } from 'react'
|
||||
import cn from '@/utils/classnames'
|
||||
|
||||
@ -59,7 +59,7 @@ export default function CustomPopover({
|
||||
onMouseEnter: () => onMouseEnter(open),
|
||||
})}
|
||||
>
|
||||
<Popover.Button
|
||||
<PopoverButton
|
||||
ref={buttonRef}
|
||||
disabled={disabled}
|
||||
className={cn(
|
||||
@ -70,9 +70,9 @@ export default function CustomPopover({
|
||||
)}
|
||||
>
|
||||
{btnElement}
|
||||
</Popover.Button>
|
||||
</PopoverButton>
|
||||
<Transition as={Fragment}>
|
||||
<Popover.Panel
|
||||
<PopoverPanel
|
||||
className={cn(
|
||||
'absolute z-10 w-full max-w-sm px-4 mt-1 sm:px-0 lg:max-w-3xl',
|
||||
position === 'bottom' && '-translate-x-1/2 left-1/2',
|
||||
@ -109,7 +109,7 @@ export default function CustomPopover({
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
</Popover.Panel>
|
||||
</PopoverPanel>
|
||||
</Transition>
|
||||
</div>
|
||||
</>
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
'use client'
|
||||
import type { FC } from 'react'
|
||||
import React, { Fragment, useEffect, useState } from 'react'
|
||||
import { Combobox, Listbox, Transition } from '@headlessui/react'
|
||||
import { Combobox, ComboboxButton, ComboboxInput, ComboboxOption, ComboboxOptions, Listbox, ListboxButton, ListboxOption, ListboxOptions, Transition } from '@headlessui/react'
|
||||
import { ChevronDownIcon, ChevronUpIcon, XMarkIcon } from '@heroicons/react/20/solid'
|
||||
import Badge from '../badge/index'
|
||||
import { RiCheckLine } from '@remixicon/react'
|
||||
@ -101,7 +101,7 @@ const Select: FC<ISelectProps> = ({
|
||||
<div className={classNames('relative')}>
|
||||
<div className='group text-text-secondary'>
|
||||
{allowSearch
|
||||
? <Combobox.Input
|
||||
? <ComboboxInput
|
||||
className={`w-full rounded-lg border-0 ${bgClassName} py-1.5 pl-3 pr-10 shadow-sm sm:text-sm sm:leading-6 focus-visible:outline-none focus-visible:bg-state-base-hover group-hover:bg-state-base-hover ${disabled ? 'cursor-not-allowed' : 'cursor-pointer'}`}
|
||||
onChange={(event) => {
|
||||
if (!disabled)
|
||||
@ -109,28 +109,28 @@ const Select: FC<ISelectProps> = ({
|
||||
}}
|
||||
displayValue={(item: Item) => item?.name}
|
||||
/>
|
||||
: <Combobox.Button onClick={
|
||||
: <ComboboxButton onClick={
|
||||
() => {
|
||||
if (!disabled)
|
||||
setOpen(!open)
|
||||
}
|
||||
} className={classNames(`flex items-center h-9 w-full rounded-lg border-0 ${bgClassName} py-1.5 pl-3 pr-10 shadow-sm sm:text-sm sm:leading-6 focus-visible:outline-none focus-visible:bg-state-base-hover group-hover:bg-state-base-hover`, optionClassName)}>
|
||||
<div className='w-0 grow text-left truncate' title={selectedItem?.name}>{selectedItem?.name}</div>
|
||||
</Combobox.Button>}
|
||||
<Combobox.Button className="absolute inset-y-0 right-0 flex items-center rounded-r-md px-2 focus:outline-none" onClick={
|
||||
</ComboboxButton>}
|
||||
<ComboboxButton className="absolute inset-y-0 right-0 flex items-center rounded-r-md px-2 focus:outline-none" onClick={
|
||||
() => {
|
||||
if (!disabled)
|
||||
setOpen(!open)
|
||||
}
|
||||
}>
|
||||
{open ? <ChevronUpIcon className="h-5 w-5" /> : <ChevronDownIcon className="h-5 w-5" />}
|
||||
</Combobox.Button>
|
||||
</ComboboxButton>
|
||||
</div>
|
||||
|
||||
{(filteredItems.length > 0 && open) && (
|
||||
<Combobox.Options className={`absolute z-10 mt-1 px-1 max-h-60 w-full overflow-auto rounded-md bg-components-panel-bg-blur backdrop-blur-sm py-1 text-base shadow-lg border-components-panel-border border-[0.5px] focus:outline-none sm:text-sm ${overlayClassName}`}>
|
||||
<ComboboxOptions className={`absolute z-10 mt-1 px-1 max-h-60 w-full overflow-auto rounded-md bg-components-panel-bg-blur backdrop-blur-sm py-1 text-base shadow-lg border-components-panel-border border-[0.5px] focus:outline-none sm:text-sm ${overlayClassName}`}>
|
||||
{filteredItems.map((item: Item) => (
|
||||
<Combobox.Option
|
||||
<ComboboxOption
|
||||
key={item.value}
|
||||
value={item}
|
||||
className={({ active }: { active: boolean }) =>
|
||||
@ -161,9 +161,9 @@ const Select: FC<ISelectProps> = ({
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</Combobox.Option>
|
||||
</ComboboxOption>
|
||||
))}
|
||||
</Combobox.Options>
|
||||
</ComboboxOptions>
|
||||
)}
|
||||
</div>
|
||||
</Combobox >
|
||||
@ -210,9 +210,9 @@ const SimpleSelect: FC<ISelectProps> = ({
|
||||
}}
|
||||
>
|
||||
<div className={classNames('group/simple-select relative h-9', wrapperClassName)}>
|
||||
{renderTrigger && <Listbox.Button className='w-full'>{renderTrigger(selectedItem)}</Listbox.Button>}
|
||||
{renderTrigger && <ListboxButton className='w-full'>{renderTrigger(selectedItem)}</ListboxButton>}
|
||||
{!renderTrigger && (
|
||||
<Listbox.Button className={classNames(`flex items-center w-full h-full rounded-lg border-0 bg-components-input-bg-normal pl-3 pr-10 sm:text-sm sm:leading-6 focus-visible:outline-none focus-visible:bg-state-base-hover-alt group-hover/simple-select:bg-state-base-hover-alt ${disabled ? 'cursor-not-allowed' : 'cursor-pointer'}`, className)}>
|
||||
<ListboxButton className={classNames(`flex items-center w-full h-full rounded-lg border-0 bg-components-input-bg-normal pl-3 pr-10 sm:text-sm sm:leading-6 focus-visible:outline-none focus-visible:bg-state-base-hover-alt group-hover/simple-select:bg-state-base-hover-alt ${disabled ? 'cursor-not-allowed' : 'cursor-pointer'}`, className)}>
|
||||
<span className={classNames('block truncate text-left system-sm-regular text-components-input-text-filled', !selectedItem?.name && 'text-components-input-text-placeholder')}>{selectedItem?.name ?? localPlaceholder}</span>
|
||||
<span className="absolute inset-y-0 right-0 flex items-center pr-2">
|
||||
{(selectedItem && !notClearable)
|
||||
@ -234,7 +234,7 @@ const SimpleSelect: FC<ISelectProps> = ({
|
||||
/>
|
||||
)}
|
||||
</span>
|
||||
</Listbox.Button>
|
||||
</ListboxButton>
|
||||
)}
|
||||
|
||||
{!disabled && (
|
||||
@ -245,9 +245,9 @@ const SimpleSelect: FC<ISelectProps> = ({
|
||||
leaveTo="opacity-0"
|
||||
>
|
||||
|
||||
<Listbox.Options className={classNames('absolute z-10 mt-1 px-1 max-h-60 w-full overflow-auto rounded-md bg-components-panel-bg-blur backdrop-blur-sm py-1 text-base shadow-lg border-components-panel-border border-[0.5px] focus:outline-none sm:text-sm', optionWrapClassName)}>
|
||||
<ListboxOptions className={classNames('absolute z-10 mt-1 px-1 max-h-60 w-full overflow-auto rounded-md bg-components-panel-bg-blur backdrop-blur-sm py-1 text-base shadow-lg border-components-panel-border border-[0.5px] focus:outline-none sm:text-sm', optionWrapClassName)}>
|
||||
{items.map((item: Item) => (
|
||||
<Listbox.Option
|
||||
<ListboxOption
|
||||
key={item.value}
|
||||
className={({ active }) =>
|
||||
classNames(
|
||||
@ -276,9 +276,9 @@ const SimpleSelect: FC<ISelectProps> = ({
|
||||
</>)}
|
||||
</>
|
||||
)}
|
||||
</Listbox.Option>
|
||||
</ListboxOption>
|
||||
))}
|
||||
</Listbox.Options>
|
||||
</ListboxOptions>
|
||||
</Transition>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
'use client'
|
||||
import { Menu, Transition } from '@headlessui/react'
|
||||
import { Menu, MenuButton, MenuItem, MenuItems, Transition } from '@headlessui/react'
|
||||
import { Fragment } from 'react'
|
||||
import { GlobeAltIcon } from '@heroicons/react/24/outline'
|
||||
import cn from '@/utils/classnames'
|
||||
|
||||
type ISelectProps = {
|
||||
items: Array<{ value: string; name: string }>
|
||||
@ -21,14 +22,14 @@ export default function Select({
|
||||
<div className="w-56 text-right">
|
||||
<Menu as="div" className="relative inline-block text-left">
|
||||
<div>
|
||||
<Menu.Button className="inline-flex w-full h-[44px]justify-center items-center
|
||||
<MenuButton className="inline-flex w-full h-[44px]justify-center items-center
|
||||
rounded-lg px-[10px] py-[6px]
|
||||
text-gray-900 text-[13px] font-medium
|
||||
border border-gray-200
|
||||
hover:bg-gray-100">
|
||||
<GlobeAltIcon className="w-5 h-5 mr-1" aria-hidden="true" />
|
||||
{item?.name}
|
||||
</Menu.Button>
|
||||
</MenuButton>
|
||||
</div>
|
||||
<Transition
|
||||
as={Fragment}
|
||||
@ -39,14 +40,13 @@ export default function Select({
|
||||
leaveFrom="transform opacity-100 scale-100"
|
||||
leaveTo="transform opacity-0 scale-95"
|
||||
>
|
||||
<Menu.Items className="absolute right-0 mt-2 w-[200px] origin-top-right divide-y divide-gray-100 rounded-md bg-white shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none z-10">
|
||||
<MenuItems className="absolute right-0 mt-2 w-[200px] origin-top-right divide-y divide-gray-100 rounded-md bg-white shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none z-10">
|
||||
<div className="px-1 py-1 ">
|
||||
{items.map((item) => {
|
||||
return <Menu.Item key={item.value}>
|
||||
return <MenuItem key={item.value}>
|
||||
{({ active }) => (
|
||||
<button
|
||||
className={`${active ? 'bg-gray-100' : ''
|
||||
} group flex w-full items-center rounded-lg px-3 py-2 text-sm text-gray-700`}
|
||||
className={cn(active && 'bg-gray-100', 'group flex w-full items-center rounded-lg px-3 py-2 text-sm text-gray-700')}
|
||||
onClick={(evt) => {
|
||||
evt.preventDefault()
|
||||
onChange && onChange(item.value)
|
||||
@ -55,12 +55,12 @@ export default function Select({
|
||||
{item.name}
|
||||
</button>
|
||||
)}
|
||||
</Menu.Item>
|
||||
</MenuItem>
|
||||
})}
|
||||
|
||||
</div>
|
||||
|
||||
</Menu.Items>
|
||||
</MenuItems>
|
||||
</Transition>
|
||||
</Menu>
|
||||
</div>
|
||||
@ -77,9 +77,9 @@ export function InputSelect({
|
||||
<div className="w-full">
|
||||
<Menu as="div" className="w-full">
|
||||
<div>
|
||||
<Menu.Button className="appearance-none block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm placeholder-gray-400 sm:text-sm h-[38px] text-left">
|
||||
<MenuButton className="appearance-none block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm placeholder:text-gray-400 sm:text-sm h-[38px] text-left">
|
||||
{item?.name}
|
||||
</Menu.Button>
|
||||
</MenuButton>
|
||||
</div>
|
||||
<Transition
|
||||
as={Fragment}
|
||||
@ -90,14 +90,13 @@ export function InputSelect({
|
||||
leaveFrom="transform opacity-100 scale-100"
|
||||
leaveTo="transform opacity-0 scale-95"
|
||||
>
|
||||
<Menu.Items className="absolute right-0 mt-2 w-full origin-top-right divide-y divide-gray-100 rounded-md bg-white shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none z-10">
|
||||
<MenuItems className="absolute right-0 mt-2 w-full origin-top-right divide-y divide-gray-100 rounded-md bg-white shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none z-10">
|
||||
<div className="px-1 py-1 ">
|
||||
{items.map((item) => {
|
||||
return <Menu.Item key={item.value}>
|
||||
return <MenuItem key={item.value}>
|
||||
{({ active }) => (
|
||||
<button
|
||||
className={`${active ? 'bg-gray-100' : ''
|
||||
} group flex w-full items-center rounded-md px-2 py-2 text-sm`}
|
||||
className={`${active ? 'bg-gray-100' : ''} group flex w-full items-center rounded-md px-2 py-2 text-sm`}
|
||||
onClick={() => {
|
||||
onChange && onChange(item.value)
|
||||
}}
|
||||
@ -105,12 +104,12 @@ export function InputSelect({
|
||||
{item.name}
|
||||
</button>
|
||||
)}
|
||||
</Menu.Item>
|
||||
</MenuItem>
|
||||
})}
|
||||
|
||||
</div>
|
||||
|
||||
</Menu.Items>
|
||||
</MenuItems>
|
||||
</Transition>
|
||||
</Menu>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user