mirror of
https://github.com/oceanprotocol/market.git
synced 2024-06-16 09:23:24 +02:00
52eaee0ad5
* feat: add autocomplete tag component * feat: pass tags aggregated list to autocomplete component * feat: add initial styling to autocomplete tag component * fix: autocomplete style types * feat: move styling elements to module.css file * feat: update placeholder text for tag input field * feat: add default value to tags if present * feat: add edit tags functionality * fix: default tag value * fix: style for automplete menu's keyboard navigation * fix: tags aggregation query size * feat: return sorted tags aggregated list suggestion in publish * fix: set tags value touched state in edit mode * add package back * enhancement: autocomplete tag component config (#1679) * fix publishing when connecting wallet on publish form * fix reset pricing on tx execution * removed changing steps * cleanup * Fix headers (#1663) * test * test * test * test * test * test * test * remove link * enhancement: tag autocomplete settings * feat: add cursor type text * feat: tweak filter and sort for matched tags * fix: tags input font color * fix: tag autocomplete component input color Co-authored-by: EnzoVezzaro <enzo-vezzaro@live.it> Co-authored-by: mihaisc <mihai.scarlat@smartcontrol.ro> Co-authored-by: Ana <84312885+AnaLoznianu@users.noreply.github.com> * fix lock * test * fix * fix * minor fixes * fix cursor on remove item (x) * style updates * UX tweaks * start suggestions upon first key stroke * remove redundant help tooltip * change placeholder copy * remove input clear action * edit updates Co-authored-by: mihaisc <mihai.scarlat@smartcontrol.ro> Co-authored-by: EnzoVezzaro <enzo-vezzaro@live.it> Co-authored-by: Ana <84312885+AnaLoznianu@users.noreply.github.com> Co-authored-by: Matthias Kretschmann <m@kretschmann.io>
93 lines
2.7 KiB
TypeScript
93 lines
2.7 KiB
TypeScript
import React, { ReactElement, useEffect, useState } from 'react'
|
|
import CreatableSelect from 'react-select/creatable'
|
|
import { OnChangeValue } from 'react-select'
|
|
import { useField } from 'formik'
|
|
import { InputProps } from '.'
|
|
import { getTagsList } from '@utils/aquarius'
|
|
import { chainIds } from 'app.config'
|
|
import { useCancelToken } from '@hooks/useCancelToken'
|
|
import styles from './TagsAutoComplete.module.css'
|
|
import { matchSorter } from 'match-sorter'
|
|
|
|
interface AutoCompleteOption {
|
|
readonly value: string
|
|
readonly label: string
|
|
}
|
|
|
|
export default function TagsAutoComplete({
|
|
...props
|
|
}: InputProps): ReactElement {
|
|
const { name, placeholder } = props
|
|
const [tagsList, setTagsList] = useState<AutoCompleteOption[]>()
|
|
const [matchedTagsList, setMatchedTagsList] = useState<AutoCompleteOption[]>(
|
|
[]
|
|
)
|
|
const [field, meta, helpers] = useField(name)
|
|
const [input, setInput] = useState<string>()
|
|
|
|
const newCancelToken = useCancelToken()
|
|
|
|
const generateAutocompleteOptions = (
|
|
options: string[]
|
|
): AutoCompleteOption[] => {
|
|
return options?.map((tag) => ({
|
|
value: tag,
|
|
label: tag
|
|
}))
|
|
}
|
|
|
|
const defaultTags = !field.value
|
|
? undefined
|
|
: generateAutocompleteOptions(field.value)
|
|
|
|
useEffect(() => {
|
|
const generateTagsList = async () => {
|
|
const tags = await getTagsList(chainIds, newCancelToken())
|
|
const autocompleteOptions = generateAutocompleteOptions(tags)
|
|
setTagsList(autocompleteOptions)
|
|
}
|
|
generateTagsList()
|
|
}, [newCancelToken])
|
|
|
|
const handleChange = (userInput: OnChangeValue<AutoCompleteOption, true>) => {
|
|
const normalizedInput = userInput.map((input) => input.value)
|
|
helpers.setValue(normalizedInput)
|
|
helpers.setTouched(true)
|
|
}
|
|
|
|
const handleOptionsFilter = (
|
|
options: AutoCompleteOption[],
|
|
input: string
|
|
): void => {
|
|
setInput(input)
|
|
const matchedTagsList = matchSorter(options, input, { keys: ['value'] })
|
|
setMatchedTagsList(matchedTagsList)
|
|
}
|
|
|
|
return (
|
|
<CreatableSelect
|
|
components={{
|
|
DropdownIndicator: () => null,
|
|
IndicatorSeparator: () => null
|
|
}}
|
|
className={styles.select}
|
|
defaultValue={defaultTags}
|
|
hideSelectedOptions
|
|
isMulti
|
|
isClearable={false}
|
|
noOptionsMessage={() =>
|
|
'Start typing to get suggestions based on tags from all published assets.'
|
|
}
|
|
onChange={(value: AutoCompleteOption[]) => handleChange(value)}
|
|
onInputChange={(value) => handleOptionsFilter(tagsList, value)}
|
|
openMenuOnClick
|
|
options={!input || input?.length < 1 ? [] : matchedTagsList}
|
|
placeholder={placeholder}
|
|
theme={(theme) => ({
|
|
...theme,
|
|
colors: { ...theme.colors, primary25: 'var(--border-color)' }
|
|
})}
|
|
/>
|
|
)
|
|
}
|