feat: select field filter options (#12487)

It is a common pattern to dynamically show and validate a select field's
options based on various criteria such as the current user or underlying
document.

Some examples of this might include:
- Restricting options based on a user's role, e.g. admin-only options
- Displaying different options based on the value of another field, e.g.
a city/state selector
 
While this is already possible to do with a custom `validate` function,
the user can still view and select the forbidden option...unless you
_also_ wired up a custom component.

Now, you can define `filterOptions` on select fields.

This behaves similarly to the existing `filterOptions` property on
relationship and upload fields, except the return value of this function
is simply an array of options, not a query constraint. The result of
this function will determine what is shown to the user and what is
validated on the server.

Here's an example:

```ts
{
  name: 'select',
  type: 'select',
  options: [
    {
      label: 'One',
      value: 'one',
    },
    {
      label: 'Two',
      value: 'two',
    },
    {
      label: 'Three',
      value: 'three',
    },
  ],
  filterOptions: ({ options, data }) =>
    data.disallowOption1
      ? options.filter(
          (option) => (typeof option === 'string' ? options : option.value) !== 'one',
        )
      : options,
}
```
This commit is contained in:
Jacob Fletcher
2025-05-22 15:54:12 -04:00
committed by GitHub
parent 45f4c5c22c
commit f75d62c79b
30 changed files with 228 additions and 25 deletions

View File

@@ -1380,6 +1380,8 @@ export interface SelectField {
category?: ('a' | 'b')[] | null;
};
selectWithJsxLabelOption?: ('one' | 'two' | 'three') | null;
disallowOption1?: boolean | null;
selectWithFilteredOptions?: ('one' | 'two' | 'three') | null;
updatedAt: string;
createdAt: string;
}
@@ -2877,6 +2879,8 @@ export interface SelectFieldsSelect<T extends boolean = true> {
category?: T;
};
selectWithJsxLabelOption?: T;
disallowOption1?: T;
selectWithFilteredOptions?: T;
updatedAt?: T;
createdAt?: T;
}