best-doctor/ke

View on GitHub
src/DetailView/widgets/InputWidget.tsx

Summary

Maintainability
B
4 hrs
Test Coverage
A
100%
// Это легаси
/* eslint-disable react/jsx-props-no-spreading */
import React, { forwardRef } from 'react'
import { Textarea, Input, TextareaProps, StyleProps } from '@chakra-ui/react'

import { DebounceInput } from '@components/controls'
import { useCreateTestId } from '@aspects/test-id/TestIdProvider'
import { useWidgetInitialization } from '../../common/hooks/useWidgetInitialization'
import { WidgetWrapper } from '../../common/components/WidgetWrapper'
import { getAccessor, getCopyHandler, getPayload } from '../utils/dataAccess'
import { pushAnalytics, EventNameEnum, WidgetTypeEnum } from '../../integration/analytics'

import type { Accessor, WidgetProps } from '../../typing'

export type InputWidgetProps = WidgetProps & {
  isTextarea?: boolean
  height?: number
  debounce?: number
  isDisabled?: Accessor<boolean>
  textareaResize?: TextareaProps['resize']
  inputProps?: StyleProps
}

const InputWidget = forwardRef<HTMLInputElement, InputWidgetProps>((props: InputWidgetProps, ref): JSX.Element => {
  const {
    name,
    helpText,
    targetPayload,
    style,
    submitChange,
    setInitialValue,
    containerStore,
    isTextarea = true,
    height,
    debounce = 1000,
    notifier,
    copyValue,
    useClipboard,
    isDisabled,
    mainDetailObject,
    textareaResize = 'none',
    containerProps,
    labelContainerProps,
    inputProps,
  } = props
  const context = containerStore.getState()

  const { targetUrl, content, isRequired, widgetDescription } = useWidgetInitialization({ ...props, context })

  setInitialValue({ [name]: content })

  const handleChange = (value: string): void => {
    pushAnalytics({
      eventName: EventNameEnum.INPUT_CHANGE,
      widgetType: WidgetTypeEnum.INPUT,
      value,
      objectForAnalytics: props.mainDetailObject,
      ...props,
    })

    const inputPayload = getPayload(value, name, targetPayload)
    submitChange({ url: targetUrl, payload: inputPayload })
  }

  const handleCopyValue = getCopyHandler(content, copyValue)

  const { getDataTestId } = useCreateTestId()

  return (
    <WidgetWrapper
      name={name}
      style={style}
      helpText={helpText}
      description={widgetDescription}
      required={isRequired}
      notifier={notifier}
      useClipboard={useClipboard}
      copyValue={handleCopyValue}
      containerProps={containerProps}
      labelContainerProps={labelContainerProps}
      {...getDataTestId(props)}
    >
      <DebounceInput
        name={name}
        value={content as string}
        height={height || (isTextarea ? 263 : undefined)}
        debounceTimeout={debounce}
        element={isTextarea ? (Textarea as React.FC) : (Input as React.FC)}
        onChange={handleChange}
        inputRef={ref}
        disabled={getAccessor(isDisabled, mainDetailObject, context)}
        resize={isTextarea ? textareaResize : undefined}
        {...inputProps}
      />
    </WidgetWrapper>
  )
})

export { InputWidget }