{"size": 2623, "ext": "js", "max_stars_repo_path": "studio/components/dynamic-select.js", "max_stars_repo_name": "sickerman/hull-marketing-starter", "max_stars_repo_stars_event_min_datetime": null, "max_stars_repo_stars_event_max_datetime": null, "max_issues_repo_path": "studio/components/dynamic-select.js", "max_issues_repo_name": "sickerman/hull-marketing-starter", "max_issues_repo_issues_event_min_datetime": null, "max_issues_repo_issues_event_max_datetime": null, "max_forks_repo_path": "studio/components/dynamic-select.js", "max_forks_repo_name": "sickerman/hull-marketing-starter", "max_forks_repo_forks_event_min_datetime": null, "max_forks_repo_forks_event_max_datetime": null}
{"max_stars_count": null, "max_issues_count": null, "max_forks_count": null, "avg_line_length": 32.7875, "max_line_length": 80, "alphanum_fraction": 0.6111322913}
import React from 'react'
import Select from 'part:@sanity/components/selects/default'
import FormField from 'part:@sanity/components/formfields/default'
import { withDocument } from 'part:@sanity/form-builder'
import PatchEvent, { set } from 'part:@sanity/form-builder/patch-event'

const DynamicSelect = React.forwardRef((props, ref) => {
  const { document, onChange, type, value } = props
  const { title, description, level, options } = type // details about the field

  let dynamicOptions = []

  // are we mapping a subfield?
  if (options.fromSubField) {
    /*  ------------------------------------------------------------ */
    /*  1. Grab the other array field from document (fromField)
    /*  2. Map over the specified subfield string list (fromSubField)
    /*  3. build our array object
    /*    - reference a field from the main array (fromFieldData)
    /*    - store that with the subfield value (title:value)
    /*  ------------------------------------------------------------ */
    dynamicOptions = document[options.fromField]
      .map(opt => {
        // bail if we can't find the subfield
        if (!(options.fromSubField in opt)) return null

        // map over the subfield to build our list of options
        return opt[options.fromSubField].map(val => ({
          title: `${opt[options.fromFieldData.title]} - ${val}`,
          value: `${opt[options.fromFieldData.title]}:${val}`
        }))
      })
      .flat(1)
      .filter(x => x != null)

    // Map basic field array data
  } else {
    // bail if we can't find the field
    if (!(options.fromField in document)) return null

    // map over the field to build our list of options
    dynamicOptions = document[options.fromField].map(opt => ({
      title: opt[options.fromFieldData.title].toString(),
      value: opt[options.fromFieldData.value].toString()
    }))
  }

  // Let's make sure we include existing "list" values
  const selectOptions = [
    ...(options.list ? options.list : [{}]),
    ...dynamicOptions
  ]

  // find our currently active value
  const currentItem = selectOptions.find(opt => opt.value === value)

  // Save the new value on change
  const handleCustomFieldChange = option => {
    onChange(PatchEvent.from(set(option.value.toString())))
  }

  return (
    <FormField
      label={title}
      level={level}
      legend={title}
      description={description}
    >
      <Select
        ref={ref}
        items={selectOptions}
        onChange={evt => handleCustomFieldChange(evt)}
        value={currentItem}
      />
    </FormField>
  )
})

export default withDocument(DynamicSelect)
