SoftwareBrothers / adminjs

AdminJS is an admin panel for apps written in node.js
https://adminjs.co
MIT License
8.07k stars 650 forks source link

[Bug]: inputs in Modals lose focus every key press #1622

Open AshotN opened 5 months ago

AshotN commented 5 months ago

Contact Details

No response

What happened?

I am using a custom component that is a modal with an input field in it. Every onChange event causes a re-render and the input loses focus.

Bug prevalence

Often

AdminJS dependencies version

    "@adminjs/design-system": "4.0.3",
    "@adminjs/koa": "4.1.0",
    "adminjs": "7.5.10",

What browsers do you see the problem on?

Firefox

Relevant log output

No response

Relevant code that's giving you issues

import React, { useState } from 'react'
import { Button, FormGroup, Input, InputGroup, Modal } from '@adminjs/design-system'
import { ApiClient, BasePropertyProps } from 'adminjs'

const ModalExample = (props: BasePropertyProps) => {
  const { record, resource } = props
  if (!record) throw new Error('Missing record')
  const { params } = record

  const [amount, setAmount] = useState(0)

  const api = new ApiClient()

  return (
    <Modal>
      <form
        onSubmit={(e) => {
          e.preventDefault()
          api.recordAction({
            actionName: 'asdf',
            resourceId: resource.id,
            recordId: record.id,
            data: {
              amount
            }
          })
        }}
      >
        <FormGroup>
          <div
            style={{ display: 'flex', flexDirection: 'column', gap: '10px', justifyContent: 'space-between' }}
          >
            <InputGroup>
              <label>
                Amount:{' '}
                <Input
                  placeholder="Base APY"
                  type="number"
                  value={amount}
                  onChange={(e: React.ChangeEvent<HTMLInputElement>) => setAmount(parseFloat(e.target.value))}
                />
              </label>
            </InputGroup>
            <Button variant="success" type="submit">
              Submit
            </Button>
          </div>
        </FormGroup>
      </form>
    </Modal>
  )
}

export default ModalExample
eakenbor commented 3 months ago

@AshotN did you find a solution to this?

eakenbor commented 3 months ago

@dziraf please can you have a look at this?

AshotN commented 3 months ago

No, I haven't found a solution. It's still a problem for me.

eakenbor commented 2 months ago

@AshotN I managed to get around it using useRef by doing the following:

<Modal>
        <Input
                    ref={amountRef}
                    required
                    type='number'
                    value={amount}
                    onChange={event => {
                      setAmount(parseFloat(event.target.value))
                      setTimeout(() => {
                        amountRef.current.focus()
                      }, 0)
                    }}
                    disabled={type == 'SERVICE'}
                  ></Input>
</Modal>

However, this hack does not work for CurrencyInput.

@dziraf do you intend to solve this bug anytime soon? CurrencyInput is very important to us.

AshotN commented 2 months ago

Ya that's a bit hacky, but probably a good stop gap. Hoping there is a proper fix soon.