mirror of
https://github.com/langgenius/dify.git
synced 2026-05-01 01:00:51 -04:00
refactor(web): continue replacing PortalToFollowElem with Popover components (#35431)
Co-authored-by: CodingOnStar <hanxujiang@dify.com> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
@@ -1,32 +1,32 @@
|
||||
import { fireEvent, render, waitFor } from '@testing-library/react'
|
||||
import { fireEvent, render, screen, waitFor } from '@testing-library/react'
|
||||
import { NoteTheme } from '../../../types'
|
||||
import ColorPicker, { COLOR_LIST } from '../color-picker'
|
||||
import ColorPicker from '../color-picker'
|
||||
|
||||
vi.mock('@langgenius/dify-ui/popover', () => import('@/__mocks__/base-ui-popover'))
|
||||
|
||||
describe('NoteEditor ColorPicker', () => {
|
||||
it('should open the palette and apply the selected theme', async () => {
|
||||
const onThemeChange = vi.fn()
|
||||
const { container } = render(
|
||||
render(
|
||||
<ColorPicker theme={NoteTheme.blue} onThemeChange={onThemeChange} />,
|
||||
)
|
||||
|
||||
const trigger = container.querySelector('[data-state="closed"]') as HTMLElement
|
||||
fireEvent.click(screen.getByTestId('popover-trigger'))
|
||||
|
||||
fireEvent.click(trigger)
|
||||
|
||||
const popup = document.body.querySelector('[role="tooltip"]')
|
||||
const popup = screen.getByTestId('popover-content')
|
||||
|
||||
expect(popup).toBeInTheDocument()
|
||||
|
||||
const options = popup?.querySelectorAll('.group.relative')
|
||||
const options = popup.querySelectorAll('.group.relative')
|
||||
|
||||
expect(options).toHaveLength(COLOR_LIST.length)
|
||||
expect(options).toHaveLength(6)
|
||||
|
||||
fireEvent.click(options?.[COLOR_LIST.length - 1] as Element)
|
||||
fireEvent.click(options[5] as Element)
|
||||
|
||||
expect(onThemeChange).toHaveBeenCalledWith(NoteTheme.violet)
|
||||
|
||||
await waitFor(() => {
|
||||
expect(document.body.querySelector('[role="tooltip"]')).not.toBeInTheDocument()
|
||||
expect(screen.queryByTestId('popover-content')).not.toBeInTheDocument()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { fireEvent, render, screen } from '@testing-library/react'
|
||||
import FontSizeSelector from '../font-size-selector'
|
||||
|
||||
vi.mock('@langgenius/dify-ui/popover', () => import('@/__mocks__/base-ui-popover'))
|
||||
|
||||
const {
|
||||
mockHandleFontSize,
|
||||
mockHandleOpenFontSizeSelector,
|
||||
@@ -52,4 +54,12 @@ describe('NoteEditor FontSizeSelector', () => {
|
||||
expect(mockHandleFontSize).toHaveBeenCalledWith('16px')
|
||||
expect(mockHandleOpenFontSizeSelector).toHaveBeenCalledWith(false)
|
||||
})
|
||||
|
||||
it('should fall back to the small label when current font size is unknown', () => {
|
||||
mockFontSize = '18px'
|
||||
|
||||
render(<FontSizeSelector />)
|
||||
|
||||
expect(screen.getByText('workflow.nodes.note.editor.small')).toBeInTheDocument()
|
||||
})
|
||||
})
|
||||
|
||||
@@ -76,11 +76,14 @@ describe('NoteEditor Toolbar', () => {
|
||||
|
||||
expect(screen.getByText('workflow.nodes.note.editor.medium')).toBeInTheDocument()
|
||||
|
||||
const triggers = container.querySelectorAll('[data-state="closed"]')
|
||||
const buttons = container.querySelectorAll('button[type="button"]')
|
||||
fireEvent.click(buttons[0] as HTMLElement)
|
||||
|
||||
fireEvent.click(triggers[0] as HTMLElement)
|
||||
await waitFor(() => {
|
||||
expect(document.body.querySelectorAll('.group.relative').length).toBeGreaterThan(0)
|
||||
})
|
||||
|
||||
const colorOptions = document.body.querySelectorAll('[role="tooltip"] .group.relative')
|
||||
const colorOptions = document.body.querySelectorAll('.group.relative')
|
||||
|
||||
fireEvent.click(colorOptions[colorOptions.length - 1] as Element)
|
||||
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
import { cn } from '@langgenius/dify-ui/cn'
|
||||
import {
|
||||
Popover,
|
||||
PopoverContent,
|
||||
PopoverTrigger,
|
||||
} from '@langgenius/dify-ui/popover'
|
||||
import {
|
||||
memo,
|
||||
useState,
|
||||
} from 'react'
|
||||
import {
|
||||
PortalToFollowElem,
|
||||
PortalToFollowElemContent,
|
||||
PortalToFollowElemTrigger,
|
||||
} from '@/app/components/base/portal-to-follow-elem'
|
||||
import { THEME_MAP } from '../../constants'
|
||||
import { NoteTheme } from '../../types'
|
||||
|
||||
export const COLOR_LIST = [
|
||||
const COLOR_LIST = [
|
||||
{
|
||||
key: NoteTheme.blue,
|
||||
inner: THEME_MAP[NoteTheme.blue]!.title,
|
||||
@@ -55,28 +55,35 @@ const ColorPicker = ({
|
||||
const [open, setOpen] = useState(false)
|
||||
|
||||
return (
|
||||
<PortalToFollowElem
|
||||
<Popover
|
||||
open={open}
|
||||
onOpenChange={setOpen}
|
||||
placement="top"
|
||||
offset={4}
|
||||
>
|
||||
<PortalToFollowElemTrigger onClick={() => setOpen(!open)}>
|
||||
<div className={cn(
|
||||
'flex h-8 w-8 cursor-pointer items-center justify-center rounded-md hover:bg-black/5',
|
||||
open && 'bg-black/5',
|
||||
)}
|
||||
>
|
||||
<div
|
||||
<PopoverTrigger
|
||||
nativeButton
|
||||
render={(
|
||||
<button
|
||||
type="button"
|
||||
className={cn(
|
||||
'h-4 w-4 rounded-full border border-black/5',
|
||||
THEME_MAP[theme]!.title,
|
||||
'flex h-8 w-8 cursor-pointer items-center justify-center rounded-md hover:bg-black/5',
|
||||
open && 'bg-black/5',
|
||||
)}
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</PortalToFollowElemTrigger>
|
||||
<PortalToFollowElemContent>
|
||||
<div
|
||||
className={cn(
|
||||
'h-4 w-4 rounded-full border border-black/5',
|
||||
THEME_MAP[theme]!.title,
|
||||
)}
|
||||
>
|
||||
</div>
|
||||
</button>
|
||||
)}
|
||||
/>
|
||||
<PopoverContent
|
||||
placement="top"
|
||||
sideOffset={4}
|
||||
popupClassName="border-none bg-transparent shadow-none"
|
||||
>
|
||||
<div className="grid grid-cols-3 grid-rows-2 gap-0.5 rounded-lg border-[0.5px] border-components-actionbar-border bg-components-actionbar-bg p-0.5 shadow-lg">
|
||||
{
|
||||
COLOR_LIST.map(color => (
|
||||
@@ -107,8 +114,8 @@ const ColorPicker = ({
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</PortalToFollowElemContent>
|
||||
</PortalToFollowElem>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { cn } from '@langgenius/dify-ui/cn'
|
||||
import {
|
||||
Popover,
|
||||
PopoverContent,
|
||||
PopoverTrigger,
|
||||
} from '@langgenius/dify-ui/popover'
|
||||
import { RiFontSize } from '@remixicon/react'
|
||||
import { memo } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Check } from '@/app/components/base/icons/src/vender/line/general'
|
||||
import {
|
||||
PortalToFollowElem,
|
||||
PortalToFollowElemContent,
|
||||
PortalToFollowElemTrigger,
|
||||
} from '@/app/components/base/portal-to-follow-elem'
|
||||
import { useFontSize } from './hooks'
|
||||
|
||||
const FontSizeSelector = () => {
|
||||
@@ -34,23 +34,30 @@ const FontSizeSelector = () => {
|
||||
} = useFontSize()
|
||||
|
||||
return (
|
||||
<PortalToFollowElem
|
||||
<Popover
|
||||
open={fontSizeSelectorShow}
|
||||
onOpenChange={handleOpenFontSizeSelector}
|
||||
placement="bottom-start"
|
||||
offset={2}
|
||||
>
|
||||
<PortalToFollowElemTrigger onClick={() => handleOpenFontSizeSelector(!fontSizeSelectorShow)}>
|
||||
<div className={cn(
|
||||
'flex h-8 cursor-pointer items-center rounded-md pr-1.5 pl-2 text-[13px] font-medium text-text-tertiary hover:bg-state-base-hover hover:text-text-secondary',
|
||||
fontSizeSelectorShow && 'bg-state-base-hover text-text-secondary',
|
||||
<PopoverTrigger
|
||||
nativeButton
|
||||
render={(
|
||||
<button
|
||||
type="button"
|
||||
className={cn(
|
||||
'flex h-8 cursor-pointer items-center rounded-md pr-1.5 pl-2 text-[13px] font-medium text-text-tertiary hover:bg-state-base-hover hover:text-text-secondary',
|
||||
fontSizeSelectorShow && 'bg-state-base-hover text-text-secondary',
|
||||
)}
|
||||
>
|
||||
<RiFontSize className="mr-1 h-4 w-4" />
|
||||
{FONT_SIZE_LIST.find(font => font.key === fontSize)?.value || t('nodes.note.editor.small', { ns: 'workflow' })}
|
||||
</button>
|
||||
)}
|
||||
>
|
||||
<RiFontSize className="mr-1 h-4 w-4" />
|
||||
{FONT_SIZE_LIST.find(font => font.key === fontSize)?.value || t('nodes.note.editor.small', { ns: 'workflow' })}
|
||||
</div>
|
||||
</PortalToFollowElemTrigger>
|
||||
<PortalToFollowElemContent>
|
||||
/>
|
||||
<PopoverContent
|
||||
placement="bottom-start"
|
||||
sideOffset={2}
|
||||
popupClassName="border-none bg-transparent shadow-none"
|
||||
>
|
||||
<div className="w-[120px] rounded-md border-[0.5px] border-components-panel-border bg-components-panel-bg-blur p-1 text-text-secondary shadow-xl">
|
||||
{
|
||||
FONT_SIZE_LIST.map(font => (
|
||||
@@ -77,8 +84,8 @@ const FontSizeSelector = () => {
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</PortalToFollowElemContent>
|
||||
</PortalToFollowElem>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user