1

I have the following component that wraps a Material UI select:

  return (
    <Box display="flex" justifyContent={justifyContent}>
      <SortWrapper>
        <InputLabel htmlFor={id} shrink={true} >
          Sort by
        </InputLabel>
        <Select
          data-bdd={id}
          id={id}
          defaultValue={defaultSortOrder}
          onChange={handleChangeSort}
        >
          {options.map((f: any) => (
            <MenuItem key={f.sortableKey} value={f.sortableKey}>
              {f.displayName}
            </MenuItem>
          ))}
        </Select>
      </SortWrapper>
    </Box>
  )

and than I use it like so inside the UI:

...
              <SelectInput
                defaultSortOrder={defaultSortOrder}
                handleChangeSortOrder={handleChangeSortOrder}
                style={selectInputStyle}
                id="repairs-search-sort"
                options={sortableFields}
              />
...

and sortableFields is like so:

sortableFields: SortableField[]

the key and value are too tight to SortableField[]

export default class SortableField {
  public displayName: string = ''
  public sortableKey: string = ''
}

is there a way to make key and value values more generic?

Like <MenuItem key={ket} value={value}> regardless of the type we are consuming in the UI?

1 Answer 1

2

There's a couple techniques you can use, which I've seen in various third-party libraries:

  1. Define labelKey and valueKey props. This will let you define which properties to search for.
interface MyInterface1 {
  id: string;
  name: string;
}

interface MyInterface2 {
  key: {
    id: string,
    description: string
  };
}

<SelectInput<MyInterface1> labelKey="id" valueKey="name"/>

<SelectInput<MyInterface2> labelKey="key.id" valueKey="key.description"/>
  1. Expose a callback to return the label and values. Sometimes you need to grab data outside of the options array, or perform some formatting (Dates, Times, Composite labels).
interface MyInterface1 {
  id: string;
  firstName: string;
  lastName: string;
  email: string;
}

function buildLabel(option: MyInterface1): string {
  return `${option.firstName} ${option.lastName}`;
}

<SelectInput<MyInterface1> labelCallback="buildLabel" valueKey="id"/>
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.