import React from "react" import { Box } from "@chakra-ui/react" import { useThingtime } from "../Thingtime/useThingtime" export const MagicInput = React.forwardRef((props: any, ref) => { const { thingtime, setThingtime, loading } = useThingtime() const [inputValue, setInputValue] = React.useState() const [isClientSide, setIsClientSide] = React.useState(false) React.useEffect(() => { setIsClientSide(true) }, []) const contentEditableRef = React.useRef(null) const editValueRef = React.useRef({}) const fullPath = React.useMemo(() => { const ret = props?.fullPath || props?.path // store this thing in the global db try { // window.meta.things[ret] = props?.value } catch { // nothing } return ret }, [props?.fullPath, props?.path, props?.value]) const [contentEditableValue, setContentEditableValue] = React.useState( props?.value || props?.placeholder ) const updateContentEditableValue = React.useCallback((value) => { // replace all new line occurences in value with

console.log("MagicInput updating contentEditableValue with value", value) // extract all series of new lines const newlines = value?.split?.(/[^\n]/)?.filter((v) => v !== "") let newValue = value // replace all new lines groups with

newlines?.forEach?.((newline) => { const baseLength = "\n"?.length const newlineClone = newline const newlineClonePart1 = newlineClone?.replace( "\n\n\n", "

" ) const newlineClonePart2 = newlineClonePart1?.replace( /\n\n/g, "

" ) const newlineClonePart3 = newlineClonePart2?.replace(/\n/g, "
") newValue = newValue?.replace(newline, newlineClonePart3) }) setContentEditableValue(newValue) }, []) React.useEffect(() => { setInputValue(contentEditableValue) }, [contentEditableValue]) React.useEffect(() => { const entries = Object.entries(editValueRef.current) const propsValueInEntries = entries?.find?.( (entry) => entry[1] === props?.value ) if (!propsValueInEntries) { // const valueToUse = props?.value || props?.placeholder const valueToUse = props?.value updateContentEditableValue(valueToUse) // setContentEditableValue(props?.value) } else { const [time, value] = propsValueInEntries if (time && value) { delete editValueRef.current[time] } } }, [props?.value, props?.placeholder, updateContentEditableValue]) const onValueChange = React.useCallback( (args) => { const { value } = args props?.onValueChange?.({ value }) props?.onChange?.({ value }) // updateContentEditableValue(value) }, [props?.onValueChange, props?.onChange] ) const updateValue = React.useCallback( (args) => { const { value } = args onValueChange({ value }) setInputValue(value) // setThingtime(fullPath, value) }, [fullPath, setThingtime, onValueChange] ) const onFocus = React.useCallback( (e) => { props?.onFocus?.(e) }, [props?.onFocus] ) const maybeUpdateValue = React.useCallback( (e) => { const { key } = e if (key === "Enter") { if (props?.onEnter) { e?.preventDefault?.() } props?.onEnter?.({ value: inputValue }) } }, [inputValue, props?.onEnter] ) const dangerouslySetInnerHTML = React.useMemo(() => { if (!props?.readonly) { return { __html: contentEditableValue } } // return { __html: contentEditableValue } }, [contentEditableValue, props?.readonly]) return ( { const innerText = value?.target?.innerText console.log("MagicInput got onInput event value", value) console.log("MagicInput got onInput event innerText", innerText) if (typeof innerText === "string") { const time = Date.now() editValueRef.current[time] = innerText updateValue({ value: innerText }) } }} onKeyDown={maybeUpdateValue} > {props?.readonly ? props?.value : null} Imagine.. {props?.placeholder || "Imagine.."} ) })