simian 0.1.2

A command-line tool for exploring and implementing Machine Learning algorithms in Rust.
Documentation
import { FC, useMemo } from 'react'
import clsx from 'clsx'
import { Path, Text } from 'slate'
import { ReactEditor, useFocused, useSelected } from 'slate-react'

import { useEditor } from '@/ui/editor/context'
import { ElementProps } from '@/ui/editor/types'
import { getBlockContainer } from '@/ui/editor/utils'

import { Block } from '../../block'

import { useParagraph } from './context'

export const Paragraph: FC<ElementProps<'paragraph'>> = ({
  attributes,
  children,
  element,
}) => {
  const { editor, emptyPlaceholder: editorEmptyPlaceholder } = useEditor()
  const selected = useSelected()
  const focused = useFocused()
  const { emptyPlaceholder: paragraphEmptyPlaceholder } = useParagraph()

  const isFirstParagraph = useMemo(() => {
    // 1. Get the path of the current element
    let path: number[] = []

    try {
      path = ReactEditor.findPath(editor, element)
    } catch {
      // findPath can throw if the node is being unmounted
    }

    // 2. Get the "logical" container (Root or Editor)
    const container = getBlockContainer(editor)

    // 3. Check if it's the first child of that container
    // If nested: [rootIndex, 0]
    // If flat: [0]
    const expectedFirstPath = [...container.path, 0]
    return Path.equals(path, expectedFirstPath)
  }, [editor, element])

  // Check if the paragraph node is empty
  const isEmpty =
    element.children.length === 1 && (element.children[0] as Text).text === ''
  const emptyPlaceholder =
    (isFirstParagraph && editorEmptyPlaceholder) || paragraphEmptyPlaceholder
  //const showPlaceholder = emptyPlaceholder && isEmpty && selected && focused;

  // Update the condition to include Hover via a CSS class later
  // We only render the span if the placeholder exists and the block is empty
  const shouldRenderPlaceholder = !!emptyPlaceholder && isEmpty

  // We determine if it should be forced visible by React state
  // (for mobile or keyboard focus)
  const isForcedVisible = selected && focused

  return (
    <Block
      element={element}
      className={clsx(['mb-6 last:mt-0 group', isEmpty ? 'relative' : ''])}
      {...attributes}
    >
      {shouldRenderPlaceholder && (
        <span
          contentEditable={false}
          className={clsx([
            'absolute pointer-events-none opacity-30 select-none',
            isForcedVisible ? '' : 'hidden group-hover:block',
          ])}
        >
          {emptyPlaceholder}
        </span>
      )}

      {children}
    </Block>
  )
}