insert-block.tsx 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. import {
  2. memo,
  3. useCallback,
  4. useState,
  5. } from 'react'
  6. import { useNodesInteractions } from '../../hooks'
  7. import type {
  8. BlockEnum,
  9. OnSelectBlock,
  10. } from '../../types'
  11. import BlockSelector from '../../block-selector'
  12. import cn from '@/utils/classnames'
  13. type InsertBlockProps = {
  14. startNodeId: string
  15. availableBlocksTypes: BlockEnum[]
  16. }
  17. const InsertBlock = ({
  18. startNodeId,
  19. availableBlocksTypes,
  20. }: InsertBlockProps) => {
  21. const [open, setOpen] = useState(false)
  22. const { handleNodeAdd } = useNodesInteractions()
  23. const handleOpenChange = useCallback((v: boolean) => {
  24. setOpen(v)
  25. }, [])
  26. const handleInsert = useCallback<OnSelectBlock>((nodeType, toolDefaultValue) => {
  27. handleNodeAdd(
  28. {
  29. nodeType,
  30. toolDefaultValue,
  31. },
  32. {
  33. nextNodeId: startNodeId,
  34. nextNodeTargetHandle: 'target',
  35. },
  36. )
  37. }, [startNodeId, handleNodeAdd])
  38. return (
  39. <div
  40. className={cn(
  41. 'nopan nodrag',
  42. 'hidden group-hover/insert:block absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2',
  43. open && '!block',
  44. )}
  45. >
  46. <BlockSelector
  47. open={open}
  48. onOpenChange={handleOpenChange}
  49. asChild
  50. onSelect={handleInsert}
  51. availableBlocksTypes={availableBlocksTypes}
  52. triggerClassName={() => 'hover:scale-125 transition-all'}
  53. />
  54. </div>
  55. )
  56. }
  57. export default memo(InsertBlock)