payload icon indicating copy to clipboard operation
payload copied to clipboard

docs: select field custom component example fixed and improved

Open barthy-koeln opened this issue 2 years ago • 6 comments

Description

I discovered a few things in this documentation code snippet that cost me time to figure out. I think the improvements are valid for most users.

There were also minor errors that needed fixing.

Fixes:

  • A typo where CustomSelectProps was declared in camelCase but referenced in PascalCase.
  • The callback value in onChange is potentially null, e.g., when clearing the select.

Regarding the onChange parameter, I think we should also change the Interface to add null:

export type SelectInputProps = Omit<SelectField, 'options' | 'type' | 'value'> & {
  // …
  onChange?: (value: Option|null) => void
  // …
}

Please let me know how to proceed with this one :)

Improvements:

  • Typescript types clarifying the expected output of the .filter function.
  • CSS classes as used in the default UI to make the example a drop-in replacement. We could also use fieldBaseClass here.
  • [x] I have read and understand the CONTRIBUTING.md document in this repository.

Type of change

  • [x] This change requires a documentation update

Checklist:

  • [ ] I have added tests that prove my fix is effective or that my feature works
  • [ ] Existing test suite passes locally with my changes
  • [ ] I have made corresponding changes to the documentation

barthy-koeln avatar Nov 04 '23 09:11 barthy-koeln

@barthy-koeln this all looks great 👍 except I don't think we should include null in the onChange handler because it does not match the function's type. If you can revert that change then I think this is mergable. Looks like it was missing the argument, though.

jacobsfletch avatar Nov 09 '23 05:11 jacobsfletch

For the record to use null you should include an option with the value of null to achieve this.

jacobsfletch avatar Nov 09 '23 05:11 jacobsfletch

@jacobsfletch

The issue is that ReactSelect has null in its type definition and its documentation:

onChange = (
    newValue: OnChangeValue<Option, IsMulti>,
    actionMeta: ActionMeta<Option>
)

export type OnChangeValue<Option, IsMulti extends boolean> = IsMulti extends true 
    ? MultiValue<Option> 
    : SingleValue<Option>

export type SingleValue<Option> = Option | null;

They use it when clearing the select, for example using the built-in clear button that is enabled in Payload UI by default:

  clearValue = () => {
    const { selectValue } = this.state;
    this.onChange(valueTernary(this.props.isMulti, [], null), {
      action: 'clear',
      removedValues: selectValue,
    });
  };

Which means that the current example for a custom select in the Payload docs throws errors when clearing the input.

onChange={(o) => setValue(o.value)}
react-dom.development.js:4312 Uncaught TypeError: Cannot read properties of null (reading 'value')
    at onChange (IconSelectComponent.tsx:61:123)
    at useStateManager-7e1e8489.esm.js:36:7
    at Select2._this.onChange (Select-aecb2a80.esm.js:1177:7)
    at Select2._this.clearValue (Select-aecb2a80.esm.js:1251:13)
    at Select2._this.onClearIndicatorMouseDown (Select-aecb2a80.esm.js:1378:13)
    …

barthy-koeln avatar Nov 09 '23 08:11 barthy-koeln

Ok interesting, thank you for pointing this out. I think the move here then is to adjust the Payload types accordingly to match React Select. I would expect that TS is throwing an error in your onChange handler because Option is never null according to Payload. Are you getting any type errors from your change?

jacobsfletch avatar Nov 15 '23 22:11 jacobsfletch

No, interestingly it doesn't throw any errors for comparisons with null and undefined, even with strictNullChecks.

Here's a simplified example

const num: number = 3

if (num === null) {
  console.info('this one is fine')
}

if (num === 'string') {
  console.info('this one is not')
}

See the output in the TypeScript Playground.

Should I extend this PR to also adapt the types?

barthy-koeln avatar Nov 16 '23 08:11 barthy-koeln

@jacobsfletch just a careful ping to see if I can further support here.

barthy-koeln avatar Dec 02 '23 06:12 barthy-koeln

Docs will be reworked for 3.0. Feel free to PR after release.

denolfe avatar May 01 '24 19:05 denolfe