Repository: langgenius/dify
File: web/app/components/base/input-with-copy/index.tsx (TypeScript)

Code before:
} & Omit<InputProps, 'showClearIcon' | 'onCopy'> // Remove conflicting props

const prefixEmbedded = 'overview.appInfo.embedded'

const InputWithCopy = React.forwardRef<HTMLInputElement, InputWithCopyProps>((
  {
    showCopyButton = true,
    copyValue,
    onCopy,
    value,
    wrapperClassName,
    ...inputProps
  },
  ref,
) => {
  const { t } = useTranslation()
  // Determine what value to copy
  const valueToString = typeof value === 'string' ? value : String(value || '')
  const finalCopyValue = copyValue || valueToString

  const { copied, copy, reset } = useClipboard()

  const handleCopy = useCallback(() => {
    copy(finalCopyValue)
    onCopy?.(finalCopyValue)
  }, [copy, finalCopyValue, onCopy])

  return (
    <div className={cn('relative w-full', wrapperClassName)}>
      <input
        ref={ref}
        className={cn(
          'w-full appearance-none border border-transparent bg-components-input-bg-normal py-[7px] text-components-input-text-filled caret-primary-600 outline-none placeholder:text-components-input-text-placeholder hover:border-components-input-border-hover hover:bg-components-input-bg-hover focus:border-components-input-border-active focus:bg-components-input-bg-active focus:shadow-xs',
          'radius-md system-sm-regular px-3',
          showCopyButton && 'pr-8',
          inputProps.disabled && 'cursor-not-allowed border-transparent bg-components-input-bg-disabled text-components-input-text-filled-disabled hover:border-transparent hover:bg-components-input-bg-disabled',
          inputProps.className,
        )}
        value={value}
        {...(({ size: _size, ...rest }) => rest)(inputProps)}
      />
      {showCopyButton && (
        <div
          className="absolute right-2 top-1/2 -translate-y-1/2"
          onMouseLeave={reset}
        >
          <Tooltip
            popupContent={
              (copied
                ? t(`${prefixEmbedded}.copied`, { ns: 'appOverview' })
                : t(`${prefixEmbedded}.copy`, { ns: 'appOverview' })) || ''

Review comment (suggestion):
Because onCopy is being received as a parameter here, but this might be unstable, please remove the useCallback here.

Code after:

const prefixEmbedded = 'overview.appInfo.embedded'

const InputWithCopy = React.forwardRef<HTMLInputElement, InputWithCopyProps>((
  {
    showCopyButton = true,
    copyValue,
    onCopy,
    value,
    wrapperClassName,
    ...inputProps
  },
  ref,
) => {
  const { t } = useTranslation()
  // Determine what value to copy
  const valueToString = typeof value === 'string' ? value : String(value || '')
  const finalCopyValue = copyValue || valueToString

  const { copied, copy, reset } = useClipboard()

  const handleCopy = () => {
    copy(finalCopyValue)
    onCopy?.(finalCopyValue)
  }

  return (
    <div className={cn('relative w-full', wrapperClassName)}>
      <input
        ref={ref}
        className={cn(
          'w-full appearance-none border border-transparent bg-components-input-bg-normal py-[7px] text-components-input-text-filled caret-primary-600 outline-none placeholder:text-components-input-text-placeholder hover:border-components-input-border-hover hover:bg-components-input-bg-hover focus:border-components-input-border-active focus:bg-components-input-bg-active focus:shadow-xs',
          'radius-md system-sm-regular px-3',
          showCopyButton && 'pr-8',
          inputProps.disabled && 'cursor-not-allowed border-transparent bg-components-input-bg-disabled text-components-input-text-filled-disabled hover:border-transparent hover:bg-components-input-bg-disabled',
          inputProps.className,
        )}
        value={value}
        {...(({ size: _size, ...rest }) => rest)(inputProps)}
      />
      {showCopyButton && (
        <div
          className="absolute right-2 top-1/2 -translate-y-1/2"
          onMouseLeave={reset}
        >
          <Tooltip
            popupContent={
              (copied
                ? t(`${prefixEmbedded}.copied`, { ns: 'appOverview' })
                : t(`${prefixEmbedded}.copy`, { ns: 'appOverview' })) || ''
            }