Repository: h2oai/wave
File: ui/src/combobox.tsx (TypeScript)

Code before:
 * When collapsed the user can select a new value by typing.
 */
export interface Combobox {
  /** An identifying name for this component. */
  name: Id
  /** Text to be displayed alongside the component. */
  label?: S
  /** A string that provides a brief hint to the user as to what kind of information is expected in the field. */
  placeholder?: S
  /** The name of the selected choice. */
  value?: S
  /** The choices to be presented. */
  choices?: S[]
  /** Text to be displayed as an error below the text box. */
  error?: S
  /** True if this field is disabled. */
  disabled?: B
  /** The width of the combobox, e.g. '100px'. Defaults to '100%'. */
  width?: S
  /** True if the component should be visible. Defaults to True. */
  visible?: B
  /** An optional tooltip message displayed when a user clicks the help icon to the right of the component. */
  tooltip?: S
  /** True if the choice should be submitted when an item from the dropdown is selected or the textbox value changes. */
  trigger?: B
  /** True if this is a required field. */
  required?: B
}


export const
  XCombobox = ({ model: m }: { model: Combobox }) => {
    const
      [text, setText] = React.useState(m.value),
      options = (m.choices || []).map((text, i): Fluent.IComboBoxOption => ({ key: `${i}`, text })),
      onChange = (_e: React.FormEvent<Fluent.IComboBox>, option?: Fluent.IComboBoxOption, _index?: number, value?: string) => {
        const v = option?.text || value || ''
        wave.args[m.name] = v
        setText(v)
        if (m.trigger) wave.push()
      }
    // eslint-disable-next-line react-hooks/exhaustive-deps
    React.useEffect(() => { wave.args[m.name] = m.value || null }, [])

    return (
      <Fluent.ComboBox
        data-test={m.name}
        label={m.label}
        placeholder={m.placeholder}
        options={options}
        required={m.required}

Review comment (suggestion):
```suggestion
  /** True if this is a required field. Defaults to false. */
```

Code after:
 * When collapsed the user can select a new value by typing.
 */
export interface Combobox {
  /** An identifying name for this component. */
  name: Id
  /** Text to be displayed alongside the component. */
  label?: S
  /** A string that provides a brief hint to the user as to what kind of information is expected in the field. */
  placeholder?: S
  /** The name of the selected choice. */
  value?: S
  /** The choices to be presented. */
  choices?: S[]
  /** Text to be displayed as an error below the text box. */
  error?: S
  /** True if this field is disabled. */
  disabled?: B
  /** The width of the combobox, e.g. '100px'. Defaults to '100%'. */
  width?: S
  /** True if the component should be visible. Defaults to True. */
  visible?: B
  /** An optional tooltip message displayed when a user clicks the help icon to the right of the component. */
  tooltip?: S
  /** True if the choice should be submitted when an item from the dropdown is selected or the textbox value changes. */
  trigger?: B
  /** True if this is a required field. Defaults to False. */
  required?: B
}


export const
  XCombobox = ({ model: m }: { model: Combobox }) => {
    const
      [text, setText] = React.useState(m.value),
      options = (m.choices || []).map((text, i): Fluent.IComboBoxOption => ({ key: `${i}`, text })),
      onChange = (_e: React.FormEvent<Fluent.IComboBox>, option?: Fluent.IComboBoxOption, _index?: number, value?: string) => {
        const v = option?.text || value || ''
        wave.args[m.name] = v
        setText(v)
        if (m.trigger) wave.push()
      }
    // eslint-disable-next-line react-hooks/exhaustive-deps
    React.useEffect(() => { wave.args[m.name] = m.value || null }, [])

    return (
      <Fluent.ComboBox
        data-test={m.name}
        label={m.label}
        placeholder={m.placeholder}
        options={options}
        required={m.required}