import { useEffect, useState } from 'react'
import { __ } from '@wordpress/i18n'
import { RestrictToVerticalAxis } from '@dnd-kit/abstract/modifiers'
import { RestrictToElement } from '@dnd-kit/dom/modifiers'
import { FormComponentConstructor } from '../../lib/types'
import { FormFieldProps } from '../../types'
import { useField } from '../../lib/hooks/useField'
import { Label } from '../Label/Label'
import {
SortableList,
useSortableItem,
} from '../../../SortableList/SortableList'
import plusIcon from '../../../../../../public/images/icon-plus-green.svg'
import trashIcon from '../../../../../../public/images/icon-trash.svg'
import { NestedNumberItem } from './types'
import {
createNestedNumberItem,
parseNestedNumbers,
readNestedNumbers,
serializeNestedNumbers,
} from './utils'
import './NestedNumbersField.scss'
const isPartialNumber = (value: string) =>
value === '' || /^-?\d*\.?\d*$/.test(value)
type NestedNumberRowProps = {
item: NestedNumberItem
listRef: (element: Element | null) => void
onChange: (value: string) => void
onRemove: () => void
}
const NestedNumberRow = ({
item,
listRef,
onChange,
onRemove,
}: NestedNumberRowProps) => {
const { handleRef } = useSortableItem()
return (
{
const nextValue = event.target.value
if (!isPartialNumber(nextValue)) {
return
}
onChange(nextValue)
}}
/>
)
}
export const createNestedNumbersField: FormComponentConstructor =
({ field, fieldConfig }) => {
return ({ name, label, misc }: FormFieldProps) => {
const { value, setValue } = useField(field)
const [items, setItems] = useState([])
const listId = `nested-numbers-${name}`
const maxLength = Number(
misc?.max_length ?? fieldConfig.misc?.max_length ?? 0
)
const canAdd = !maxLength || items.length < maxLength
useEffect(() => {
setItems((currentItems) => {
const incoming = readNestedNumbers(value)
const current = serializeNestedNumbers(currentItems)
if (
incoming.length === current.length &&
incoming.every((number, index) => number === current[index])
) {
return currentItems
}
return parseNestedNumbers(value)
})
}, [value])
const commitItems = (nextItems: NestedNumberItem[]) => {
setItems(nextItems)
setValue(serializeNestedNumbers(nextItems))
}
return (
{items.length > 0 && (
(
{
const nextItems = items.map(
(current, itemIndex) =>
itemIndex === index
? {
...current,
value: nextValue,
}
: current
)
commitItems(nextItems)
}}
onRemove={() =>
commitItems(
items.filter(
(_, itemIndex) =>
itemIndex !== index
)
)
}
/>
)}
/>
)}
{canAdd && (
)}
)
}
}