/* eslint-disable react-hooks/rules-of-hooks */ import React, { useState, useLayoutEffect, useEffect, useMemo, useRef, forwardRef } from 'react'; import classNames from 'classnames'; import { cssClasses } from '@douyinfe/semi-foundation/form/constants'; import { isValid, generateValidatesFromRules, mergeOptions, mergeProps, getDisplayName, transformTrigger, transformDefaultBooleanAPI } from '@douyinfe/semi-foundation/form/utils'; import * as ObjectUtil from '@douyinfe/semi-foundation/utils/object'; import isPromise from '@douyinfe/semi-foundation/utils/isPromise'; import warning from '@douyinfe/semi-foundation/utils/warning'; import { useFormState, useStateWithGetter, useFormUpdater, useArrayFieldState } from '../hooks/index'; import ErrorMessage from '../errorMessage'; import { isElement } from '../../_base/reactUtils'; import Label from '../label'; import { Col } from '../../grid'; import type { CallOpts, WithFieldOption } from '@douyinfe/semi-foundation/form/interface'; import type { CommonFieldProps, CommonexcludeType } from '../interface'; import { noop } from "lodash"; function shallowEqualArray(a: any[] | undefined, b: any[] | undefined): boolean { if (a === b) { return true; } if (!a || !b || a.length !== b.length) { return false; } for (let i = 0; i < a.length; i++) { if (!Object.is(a[i], b[i])) { return false; } } return true; } /** * Keep a stable array reference when items are shallow-equal. * * Why do we need this? * - In this file we memoize the rendered Field subtree for performance. * - We need to make the `useMemo` dependency list have a CONSTANT length between renders. * React will warn if the deps array size changes: * "The final argument passed to useMemo changed size between renders" * - Some wrappers (Tooltip/Popover) inject event handlers into children via `cloneElement`. * That can ADD/REMOVE props keys (e.g. onMouseEnter/onMouseLeave) and therefore change * the length of something like `Object.values(props)`. * * So we represent `props` as two arrays (sorted keys + values in that key order), and then * stabilize those arrays by shallow-equality so we don't trigger memo recalculation when * nothing actually changed. */ function useShallowStableArray(next: T): T { const ref = useRef(next); if (!shallowEqualArray(ref.current, next)) { ref.current = next; } return ref.current; } const prefix = cssClasses.PREFIX; // To avoid useLayoutEffect warning when ssr, refer: https://gist.github.com/gaearon/e7d97cdf38a2907924ea12e4ebdf3c85 // Fix issue 1140 const useIsomorphicEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect; /** * withFiled is used to inject components * 1. Takes over the value and onChange of the component and synchronizes them to Form Foundation * 2. Insert