Skip to content

Commit

Permalink
Merge pull request #9 from pcbowers/add-option-validation
Browse files Browse the repository at this point in the history
feat: ✨ Added a new 'check valid' feature
  • Loading branch information
pcbowers authored Apr 26, 2022
2 parents 3f5eeeb + 6e2ae47 commit 156e24e
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 8 deletions.
23 changes: 22 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ Dive into the [Options Section](#options) for more advanced use cases like prede
customLabel?: string
customValue?: string
allowCreate?: boolean
onCreate?: (inputValue: string) => Tag
onCreate?: (inputValue: string) => Tag | Promise<Tag>
checkValid?: (inputValue: string, currentValues: string[]) => boolean
reactSelectOptions?: {
[key: string]: any
}
Expand Down Expand Up @@ -187,6 +188,26 @@ If you want to edit the label or value of the tag when a new one is created befo
}
```

### checkValid

`default: (inputValue: string, currentValues: string[]) => !currentValues.includes(inputValue) && !!inputValue && inputValue.trim() === inputValue`

This allows you to check the validity of a tag when creation is allowed. `inputValue` contains the string of the input while `currentValues` contains an array of strings that represent all of the values of any options available to select as well as any already-selected options.

```javascript
{
// ...
checkValid: (input, values) => {
return (
!!input &&
input.trim() === input &&
!values.includes(input.trim().toLowerCase().replace(/\W/g, '-'))
)
}
// ...
}
```

### reactSelectOptions

`default: {}`
Expand Down
30 changes: 24 additions & 6 deletions src/components/Input.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import React from 'react'
import {FormField} from '@sanity/base/components'
import PatchEvent, {set, unset} from '@sanity/form-builder/PatchEvent'
import PatchEvent, {
set as setPatchValue,
unset as unsetPatchValue,
} from '@sanity/form-builder/PatchEvent'
import {useId} from '@reach/auto-id'
import CreatableSelect from 'react-select/creatable'
import Select from 'react-select'
Expand All @@ -19,6 +22,7 @@ import {
getPredefinedTags,
getTagsFromReference,
getTagsFromRelated,
set,
} from '../utils'

import {ReferenceCreateWarning, ReferencePredefinedWarning} from './ReferenceWarnings'
Expand Down Expand Up @@ -61,10 +65,14 @@ export default withDocument(
customLabel = 'label',
customValue = 'value',
allowCreate = true,
onCreate = async (val: string): Promise<GeneralTag> => ({
[customLabel]: val,
[customValue]: val,
}),
onCreate = async (val: string): Promise<GeneralTag> => {
const tag: GeneralTag = {}
set(tag, customLabel, val)
set(tag, customValue, val)
return tag
},
checkValid = (inputValue: string, currentValues: string[]) =>
!currentValues.includes(inputValue) && !!inputValue && inputValue.trim() === inputValue,
reactSelectOptions = {} as SelectProps<typeof isMulti>,
} = type.options ? type.options : {}

Expand Down Expand Up @@ -192,7 +200,11 @@ export default withDocument(
})

// save the values
onChange(PatchEvent.from(tagsForEvent ? set(tagsForEvent) : unset(tagsForEvent)))
onChange(
PatchEvent.from(
tagsForEvent ? setPatchValue(tagsForEvent) : unsetPatchValue(tagsForEvent)
)
)
},
[onChange]
)
Expand All @@ -210,6 +222,12 @@ export default withDocument(
isMulti,
options,
value: selected,
isValidNewOption: (inputValue: string, selectedValues: Tag[], selectedOptions: Tag[]) => {
return checkValid(inputValue, [
...selectedOptions.map((opt) => opt.value),
...selectedValues.map((val) => val.value),
])
},
onCreateOption: handleCreate,
onChange: handleChange,
isDisabled: readOnly || isLoading,
Expand Down
3 changes: 2 additions & 1 deletion src/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ declare global {
customLabel?: string
customValue?: string
allowCreate?: boolean
onCreate?: (inputValue: string) => GeneralTag
onCreate?: (inputValue: string) => GeneralTag | Promise<GeneralTag>
checkValid?: (inputValue: string, currentValues: string[]) => boolean
reactSelectOptions?: Props<Tag, boolean, GroupBase<Tag>>
}

Expand Down

0 comments on commit 156e24e

Please sign in to comment.