refactor: revamp picker block (#4227)
Co-authored-by: crazywoola <100913391+crazywoola@users.noreply.github.com>pull/6078/head
parent
68b1d063f7
commit
0046ef7707
@ -1,85 +0,0 @@
|
|||||||
import { memo } from 'react'
|
|
||||||
import { MenuOption } from '@lexical/react/LexicalTypeaheadMenuPlugin'
|
|
||||||
|
|
||||||
export class VariableOption extends MenuOption {
|
|
||||||
title: string
|
|
||||||
icon?: JSX.Element
|
|
||||||
extraElement?: JSX.Element
|
|
||||||
keywords: Array<string>
|
|
||||||
keyboardShortcut?: string
|
|
||||||
onSelect: (queryString: string) => void
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
title: string,
|
|
||||||
options: {
|
|
||||||
icon?: JSX.Element
|
|
||||||
extraElement?: JSX.Element
|
|
||||||
keywords?: Array<string>
|
|
||||||
keyboardShortcut?: string
|
|
||||||
onSelect: (queryString: string) => void
|
|
||||||
},
|
|
||||||
) {
|
|
||||||
super(title)
|
|
||||||
this.title = title
|
|
||||||
this.keywords = options.keywords || []
|
|
||||||
this.icon = options.icon
|
|
||||||
this.extraElement = options.extraElement
|
|
||||||
this.keyboardShortcut = options.keyboardShortcut
|
|
||||||
this.onSelect = options.onSelect.bind(this)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type VariableMenuItemProps = {
|
|
||||||
isSelected: boolean
|
|
||||||
onClick: () => void
|
|
||||||
onMouseEnter: () => void
|
|
||||||
option: VariableOption
|
|
||||||
queryString: string | null
|
|
||||||
}
|
|
||||||
export const VariableMenuItem = memo(({
|
|
||||||
isSelected,
|
|
||||||
onClick,
|
|
||||||
onMouseEnter,
|
|
||||||
option,
|
|
||||||
queryString,
|
|
||||||
}: VariableMenuItemProps) => {
|
|
||||||
const title = option.title
|
|
||||||
let before = title
|
|
||||||
let middle = ''
|
|
||||||
let after = ''
|
|
||||||
|
|
||||||
if (queryString) {
|
|
||||||
const regex = new RegExp(queryString, 'i')
|
|
||||||
const match = regex.exec(option.title)
|
|
||||||
|
|
||||||
if (match) {
|
|
||||||
before = title.substring(0, match.index)
|
|
||||||
middle = match[0]
|
|
||||||
after = title.substring(match.index + match[0].length)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
key={option.key}
|
|
||||||
className={`
|
|
||||||
flex items-center px-3 h-6 rounded-md hover:bg-primary-50 cursor-pointer
|
|
||||||
${isSelected && 'bg-primary-50'}
|
|
||||||
`}
|
|
||||||
tabIndex={-1}
|
|
||||||
ref={option.setRefElement}
|
|
||||||
onMouseEnter={onMouseEnter}
|
|
||||||
onClick={onClick}>
|
|
||||||
<div className='mr-2'>
|
|
||||||
{option.icon}
|
|
||||||
</div>
|
|
||||||
<div className='grow text-[13px] text-gray-900 truncate' title={option.title}>
|
|
||||||
{before}
|
|
||||||
<span className='text-[#2970FF]'>{middle}</span>
|
|
||||||
{after}
|
|
||||||
</div>
|
|
||||||
{option.extraElement}
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
})
|
|
||||||
VariableMenuItem.displayName = 'VariableMenuItem'
|
|
||||||
@ -0,0 +1,31 @@
|
|||||||
|
import { MenuOption } from '@lexical/react/LexicalTypeaheadMenuPlugin'
|
||||||
|
import { Fragment } from 'react'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Corresponds to the `MenuRenderFn` type from `@lexical/react/LexicalTypeaheadMenuPlugin`.
|
||||||
|
*/
|
||||||
|
type MenuOptionRenderProps = {
|
||||||
|
isSelected: boolean
|
||||||
|
onSelect: () => void
|
||||||
|
onSetHighlight: () => void
|
||||||
|
queryString: string | null
|
||||||
|
}
|
||||||
|
|
||||||
|
export class PickerBlockMenuOption extends MenuOption {
|
||||||
|
public group?: string
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private data: {
|
||||||
|
key: string
|
||||||
|
group?: string
|
||||||
|
onSelect?: () => void
|
||||||
|
render: (menuRenderProps: MenuOptionRenderProps) => JSX.Element
|
||||||
|
},
|
||||||
|
) {
|
||||||
|
super(data.key)
|
||||||
|
this.group = data.group
|
||||||
|
}
|
||||||
|
|
||||||
|
public onSelectMenuOption = () => this.data.onSelect?.()
|
||||||
|
public renderMenuOption = (menuRenderProps: MenuOptionRenderProps) => <Fragment key={this.data.key}>{this.data.render(menuRenderProps)}</Fragment>
|
||||||
|
}
|
||||||
@ -1,37 +0,0 @@
|
|||||||
import { memo } from 'react'
|
|
||||||
import { PromptMenuItem } from './prompt-option'
|
|
||||||
|
|
||||||
type PromptMenuProps = {
|
|
||||||
startIndex: number
|
|
||||||
selectedIndex: number | null
|
|
||||||
options: any[]
|
|
||||||
onClick: (index: number, option: any) => void
|
|
||||||
onMouseEnter: (index: number, option: any) => void
|
|
||||||
}
|
|
||||||
const PromptMenu = ({
|
|
||||||
startIndex,
|
|
||||||
selectedIndex,
|
|
||||||
options,
|
|
||||||
onClick,
|
|
||||||
onMouseEnter,
|
|
||||||
}: PromptMenuProps) => {
|
|
||||||
return (
|
|
||||||
<div className='p-1'>
|
|
||||||
{
|
|
||||||
options.map((option, index: number) => (
|
|
||||||
<PromptMenuItem
|
|
||||||
startIndex={startIndex}
|
|
||||||
index={index}
|
|
||||||
isSelected={selectedIndex === index + startIndex}
|
|
||||||
onClick={onClick}
|
|
||||||
onMouseEnter={onMouseEnter}
|
|
||||||
key={option.key}
|
|
||||||
option={option}
|
|
||||||
/>
|
|
||||||
))
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default memo(PromptMenu)
|
|
||||||
@ -1,40 +0,0 @@
|
|||||||
import { memo } from 'react'
|
|
||||||
import { VariableMenuItem } from './variable-option'
|
|
||||||
|
|
||||||
type VariableMenuProps = {
|
|
||||||
startIndex: number
|
|
||||||
selectedIndex: number | null
|
|
||||||
options: any[]
|
|
||||||
onClick: (index: number, option: any) => void
|
|
||||||
onMouseEnter: (index: number, option: any) => void
|
|
||||||
queryString: string | null
|
|
||||||
}
|
|
||||||
const VariableMenu = ({
|
|
||||||
startIndex,
|
|
||||||
selectedIndex,
|
|
||||||
options,
|
|
||||||
onClick,
|
|
||||||
onMouseEnter,
|
|
||||||
queryString,
|
|
||||||
}: VariableMenuProps) => {
|
|
||||||
return (
|
|
||||||
<div className='p-1'>
|
|
||||||
{
|
|
||||||
options.map((option, index: number) => (
|
|
||||||
<VariableMenuItem
|
|
||||||
startIndex={startIndex}
|
|
||||||
index={index}
|
|
||||||
isSelected={selectedIndex === index + startIndex}
|
|
||||||
onClick={onClick}
|
|
||||||
onMouseEnter={onMouseEnter}
|
|
||||||
key={option.key}
|
|
||||||
option={option}
|
|
||||||
queryString={queryString}
|
|
||||||
/>
|
|
||||||
))
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default memo(VariableMenu)
|
|
||||||
Loading…
Reference in New Issue