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

Code before:
      { name, label, required, disabled, values, choices, trigger, placeholder } = m,
      isMultivalued = !!values,
      selection = React.useMemo(() => isMultivalued ? new Set<S>(values) : null, [isMultivalued, values]),
      [singleValue, setSingleValue] = React.useState(m.value),
      [multiValues, setMultiValues] = React.useState(values),
      options = (choices || []).map(({ name, label, disabled }): Fluent.IDropdownOption => ({ key: name, text: label || name, disabled })),
      onChange = (_e?: React.FormEvent<HTMLElement>, option?: Fluent.IDropdownOption) => {
        if (option) {
          const optionKey = option.key as S
          if (isMultivalued && selection !== null) {
            option.selected ? selection.add(optionKey) : selection.delete(optionKey)

            const selectedOpts = Array.from(selection)
            wave.args[name] = selectedOpts
            setMultiValues(selectedOpts)
          } else {
            setSingleValue(optionKey)
            wave.args[name] = optionKey
            m.value = optionKey
          }
        }

        // HACK: Push clears args so run it after useEffect sets them due to model.value change.
        if (trigger) setTimeout(() => wave.push(), 0)
      },
      selectAll = (checked = true) => () => {
        if (!selection) return
        if (checked) selection.clear()

        options.forEach(({ disabled, key }) => {
          checked
            ? !disabled || values?.includes(key as S) ? selection.add(key as S) : null
            : !disabled ? selection.delete(key as S) : null
        })

        const selectedOpts = Array.from(selection)
        setMultiValues(selectedOpts)
        wave.args[name] = selectedOpts

        onChange()
      }

    React.useEffect(() => {
      if (!isMultivalued) return
      setMultiValues(values || [])
      wave.args[name] = values ?? null
    }, [name, values, isMultivalued])

    React.useEffect(() => {
      if (isMultivalued) return
      setSingleValue(m.value || '')

Review comment (suggestion):
Let's name this `select` (imperative) so that it's clear we should either select or deselect within the function. 

```suggestion
      selectAll = (select = true) => () => {
```

Code after:
      { name, label, required, disabled, values, choices, trigger, placeholder } = m,
      isMultivalued = !!values,
      selection = React.useMemo(() => isMultivalued ? new Set<S>(values) : null, [isMultivalued, values]),
      [singleValue, setSingleValue] = React.useState(m.value),
      [multiValues, setMultiValues] = React.useState(values),
      options = (choices || []).map(({ name, label, disabled }): Fluent.IDropdownOption => ({ key: name, text: label || name, disabled })),
      onChange = (_e?: React.FormEvent<HTMLElement>, option?: Fluent.IDropdownOption) => {
        if (option) {
          const optionKey = option.key as S
          if (isMultivalued && selection !== null) {
            option.selected ? selection.add(optionKey) : selection.delete(optionKey)

            const selectedOpts = Array.from(selection)
            wave.args[name] = selectedOpts
            setMultiValues(selectedOpts)
          } else {
            setSingleValue(optionKey)
            wave.args[name] = optionKey
            m.value = optionKey
          }
        }

        // HACK: Push clears args so run it after useEffect sets them due to model.value change.
        if (trigger) setTimeout(() => wave.push(), 0)
      },
      selectAll = (select = true) => () => {
        if (!selection) return
        const prevSelection = new Set(selection)
        selection.clear()

        options.forEach(({ disabled, key }) => {
          const k = key as S
          if ((disabled && prevSelection.has(k)) || (!disabled && select)) selection.add(k)
        })

        const selectedOpts = Array.from(selection)
        setMultiValues(selectedOpts)
        wave.args[name] = selectedOpts

        onChange()
      }

    React.useEffect(() => {
      if (!isMultivalued) return
      setMultiValues(values || [])
      wave.args[name] = values ?? null
    }, [name, values, isMultivalued])

    React.useEffect(() => {
      if (isMultivalued) return
      setSingleValue(m.value || '')