123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 |
- import { useState } from 'react'
- import type { FC, ReactNode } from 'react'
- import { FloatingFocusManager, type OffsetOptions, autoUpdate, flip, offset, shift, useDismiss, useFloating, useHover, useInteractions, useRole } from '@floating-ui/react'
- import { RiDeleteBinLine } from '@remixicon/react'
- // @ts-expect-error no types available
- import lineClamp from 'line-clamp'
- import type { SliceProps } from './type'
- import { SliceContainer, SliceContent, SliceDivider, SliceLabel } from './shared'
- import classNames from '@/utils/classnames'
- import ActionButton, { ActionButtonState } from '@/app/components/base/action-button'
- type EditSliceProps = SliceProps<{
- label: ReactNode
- onDelete: () => void
- labelClassName?: string
- labelInnerClassName?: string
- contentClassName?: string
- showDivider?: boolean
- offsetOptions?: OffsetOptions
- }>
- export const EditSlice: FC<EditSliceProps> = (props) => {
- const {
- label,
- className,
- text,
- onDelete,
- labelClassName,
- labelInnerClassName,
- contentClassName,
- showDivider = true,
- offsetOptions,
- ...rest
- } = props
- const [delBtnShow, setDelBtnShow] = useState(false)
- const [isDelBtnHover, setDelBtnHover] = useState(false)
- const { refs, floatingStyles, context } = useFloating({
- open: delBtnShow,
- onOpenChange: setDelBtnShow,
- placement: 'right-start',
- whileElementsMounted: autoUpdate,
- middleware: [
- flip(),
- shift(),
- offset(offsetOptions),
- ],
- })
- const hover = useHover(context, {})
- const dismiss = useDismiss(context)
- const role = useRole(context)
- const { getReferenceProps, getFloatingProps } = useInteractions([hover, dismiss, role])
- const isDestructive = delBtnShow && isDelBtnHover
- return (
- <>
- <SliceContainer {...rest}
- className={classNames('block mr-0', className)}
- ref={(ref) => {
- refs.setReference(ref)
- if (ref)
- lineClamp(ref, 4)
- }}
- {...getReferenceProps()}
- >
- <SliceLabel
- className={classNames(
- isDestructive && '!bg-state-destructive-solid !text-text-primary-on-surface',
- labelClassName,
- )}
- labelInnerClassName={labelInnerClassName}
- >
- {label}
- </SliceLabel>
- <SliceContent
- className={classNames(
- isDestructive && '!bg-state-destructive-hover-alt',
- contentClassName,
- )}
- >
- {text}
- </SliceContent>
- {showDivider && <SliceDivider
- className={classNames(
- isDestructive && '!bg-state-destructive-hover-alt',
- )}
- />}
- {delBtnShow && <FloatingFocusManager
- context={context}
- >
- <span
- ref={refs.setFloating}
- style={floatingStyles}
- {...getFloatingProps()}
- className='p-1 rounded-lg bg-components-actionbar-bg shadow inline-flex items-center justify-center'
- onMouseEnter={() => setDelBtnHover(true)}
- onMouseLeave={() => setDelBtnHover(false)}
- >
- <ActionButton
- onClick={(e) => {
- e.stopPropagation()
- onDelete()
- setDelBtnShow(false)
- }}
- state={ActionButtonState.Destructive}
- >
- <RiDeleteBinLine className='w-4 h-4' />
- </ActionButton>
- </span>
- </FloatingFocusManager>}
- </SliceContainer>
- </>
- )
- }
|