| @@ -44,10 +44,10 @@ export default (({ tags, setTags }: Props) => { | |||||
| const handleTagSelect = (tag: Tag) => { | const handleTagSelect = (tag: Tag) => { | ||||
| setSuggestionsVsbl (false) | setSuggestionsVsbl (false) | ||||
| const textarea = ref.current! | const textarea = ref.current! | ||||
| const newValue = replaceToken (tags, bounds.start, bounds.end, tag.name) | |||||
| const newValue = replaceToken (tags, bounds.start, bounds.end, tag.name + ' ') | |||||
| setTags (newValue) | setTags (newValue) | ||||
| requestAnimationFrame (async () => { | requestAnimationFrame (async () => { | ||||
| const p = bounds.start + tag.name.length | |||||
| const p = bounds.start + tag.name.length + 1 | |||||
| textarea.selectionStart = textarea.selectionEnd = p | textarea.selectionStart = textarea.selectionEnd = p | ||||
| textarea.focus () | textarea.focus () | ||||
| await recompute (p, newValue) | await recompute (p, newValue) | ||||
| @@ -56,8 +56,15 @@ export default (({ tags, setTags }: Props) => { | |||||
| const recompute = async (pos: number, v: string = tags) => { | const recompute = async (pos: number, v: string = tags) => { | ||||
| const { start, end, token } = getTokenAt (v, pos) | const { start, end, token } = getTokenAt (v, pos) | ||||
| if (!(token.trim ())) | |||||
| { | |||||
| setSuggestionsVsbl (false) | |||||
| return | |||||
| } | |||||
| setBounds ({ start, end }) | setBounds ({ start, end }) | ||||
| const data = await apiGet<Tag[]> ('/tags/autocomplete', { params: { q: token, nico: 0 } }) | |||||
| const data = await apiGet<Tag[]> ('/tags/autocomplete', { params: { q: token, nico: '0' } }) | |||||
| setSuggestions (data.filter (t => t.postCount > 0)) | setSuggestions (data.filter (t => t.postCount > 0)) | ||||
| setSuggestionsVsbl (suggestions.length > 0) | setSuggestionsVsbl (suggestions.length > 0) | ||||
| } | } | ||||
| @@ -72,11 +79,13 @@ export default (({ tags, setTags }: Props) => { | |||||
| onSelect={async (ev: SyntheticEvent<HTMLTextAreaElement>) => { | onSelect={async (ev: SyntheticEvent<HTMLTextAreaElement>) => { | ||||
| const pos = (ev.target as HTMLTextAreaElement).selectionStart | const pos = (ev.target as HTMLTextAreaElement).selectionStart | ||||
| await recompute (pos) | await recompute (pos) | ||||
| }}/> | |||||
| <TagSearchBox suggestions={suggestionsVsbl && suggestions.length | |||||
| ? suggestions | |||||
| : [] as Tag[]} | |||||
| activeIndex={-1} | |||||
| onSelect={handleTagSelect}/> | |||||
| }} | |||||
| onBlur={() => setSuggestionsVsbl (false)}/> | |||||
| <TagSearchBox | |||||
| suggestions={suggestionsVsbl && suggestions.length > 0 | |||||
| ? suggestions | |||||
| : [] as Tag[]} | |||||
| activeIndex={-1} | |||||
| onSelect={handleTagSelect}/> | |||||
| </div>) | </div>) | ||||
| }) satisfies FC<Props> | }) satisfies FC<Props> | ||||