1- import TagsInput from "react-tagsinput" ;
2- import Autosuggest from "react-autosuggest" ;
31import React , { useState , useRef , useEffect } from "react" ;
42import PropTypes from "prop-types" ;
53import axios from "axios" ;
64import { Flex , Field } from "@strapi/design-system" ;
75import { useIntl } from "react-intl" ;
6+ import TagsInput from "react-tagsinput" ;
7+ import Autosuggest from "react-autosuggest" ;
88import { css } from "./styles/global.ts" ;
99
1010const Tags = ( {
@@ -19,61 +19,61 @@ const Tags = ({
1919 value,
2020} ) => {
2121 const { formatMessage } = useIntl ( ) ;
22+ const apiUrl = attribute ?. options ?. apiUrl || "" ;
23+ const attrName = apiUrl . slice ( apiUrl . lastIndexOf ( "=" ) + 1 ) ;
24+ const inputEle = useRef ( null ) ;
25+
2226 const [ tags , setTags ] = useState ( ( ) => {
2327 try {
24- const values = JSON . parse ( value ) ;
25- return values . map ( ( value ) => value . name ) ;
28+ const values = typeof value === "string" ? JSON . parse ( value ) : value ;
29+ return values . map ( ( value ) => value [ attrName ] ) ;
2630 } catch ( e ) {
2731 return [ ] ;
2832 }
2933 } ) ;
34+
3035 const [ suggestions , setSuggestions ] = useState ( [ ] ) ;
31- const apiUrl = attribute ?. options ? attribute . options [ "apiUrl" ] : "" ;
32- const attrName = apiUrl . slice ( apiUrl . lastIndexOf ( '=' ) + 1 ) ;
33- let inputEle = useRef ( null ) ;
3436
3537 useEffect ( ( ) => {
36- document . getElementsByClassName (
37- "react-autosuggest__suggestions-container"
38- ) [ 0 ] . style . top = inputEle . current . offsetHeight + 5 + "px" ;
39-
40- function handleClickOutside ( event ) {
41- if ( inputEle . current && ! inputEle . current . contains ( event . target ) ) {
42- document
43- . getElementsByClassName ( "react-tagsinput" ) [ 0 ]
44- . classList . remove ( "react-tagsinput--focused" ) ;
45- } else {
46- document
47- . getElementsByClassName ( "react-tagsinput" ) [ 0 ]
48- . classList . add ( "react-tagsinput--focused" ) ;
49- }
38+ const suggestionsContainer = document . querySelector (
39+ ".react-autosuggest__suggestions-container"
40+ ) ;
41+ if ( suggestionsContainer && inputEle . current ) {
42+ suggestionsContainer . style . top = `${ inputEle . current . offsetHeight + 5 } px` ;
5043 }
51- document . addEventListener ( "mousedown" , handleClickOutside ) ;
52- return ( ) => {
53- document . removeEventListener ( "mousedown" , handleClickOutside ) ;
44+
45+ const handleClickOutside = ( event ) => {
46+ const tagsInput = document . querySelector ( ".react-tagsinput" ) ;
47+ if ( tagsInput ) {
48+ tagsInput . classList . toggle (
49+ "react-tagsinput--focused" ,
50+ inputEle . current ?. contains ( event . target )
51+ ) ;
52+ }
5453 } ;
55- } ) ;
5654
57- const handleTagsChange = ( tags ) => {
58- setTags ( tags ) ;
55+ document . addEventListener ( "mousedown" , handleClickOutside ) ;
56+ return ( ) => document . removeEventListener ( "mousedown" , handleClickOutside ) ;
57+ } , [ ] ) ;
58+
59+ const handleTagsChange = ( newTags ) => {
60+ setTags ( newTags ) ;
5961 onChange ( {
6062 target : {
6163 name,
62- value : JSON . stringify ( tags . map ( ( tag ) => ( { name : tag } ) ) ) ,
64+ value : JSON . stringify ( newTags . map ( ( tag ) => ( { [ attrName ] : tag } ) ) ) ,
6365 type : attribute . type ,
6466 } ,
6567 } ) ;
6668 } ;
6769
6870 const getSuggestions = async ( ) => {
69- if ( ! apiUrl ) {
70- return [ ] ;
71- }
71+ if ( ! apiUrl ) return ;
7272 try {
7373 const res = await axios . get ( apiUrl ) ;
7474 setSuggestions ( res . data ) ;
7575 } catch ( err ) {
76- console . log ( err ) ;
76+ console . error ( "Error fetching suggestions:" , err ) ;
7777 }
7878 } ;
7979
@@ -102,10 +102,9 @@ const Tags = ({
102102 : state [ attrName ] . toLowerCase ( ) ;
103103
104104 if ( suggestionName . slice ( 0 , inputLength ) === inputValue ) {
105- return {
106- id : state . id ,
107- name : suggestionName ,
108- } ;
105+ let suggObj = { id : state . id }
106+ suggObj [ attrName ] = suggestionName
107+ return suggObj ;
109108 }
110109 return null ;
111110 } )
@@ -117,13 +116,12 @@ const Tags = ({
117116 ref = { props . ref }
118117 suggestions = { s }
119118 shouldRenderSuggestions = { ( value ) => value && value . trim ( ) . length > 0 }
120- getSuggestionValue = { ( s ) => s . name }
121- renderSuggestion = { ( s ) => < span > { s . name } </ span > }
119+ getSuggestionValue = { ( s ) => s [ attrName ] }
120+ renderSuggestion = { ( s ) => < span > { s [ attrName ] } </ span > }
122121 inputProps = { { ...props , onChange : handleOnChange } }
123- onSuggestionSelected = { ( e , { suggestion } ) => {
124- props . addTag ( suggestion . name ) ;
125- } }
126- onSuggestionsClearRequested = { ( ) => this . setTags ( [ ] ) }
122+ onSuggestionSelected = { ( _ , { suggestion } ) =>
123+ props . addTag ( suggestion [ attrName ] )
124+ }
127125 onSuggestionsFetchRequested = { ( ) => { } }
128126 />
129127 ) ;
@@ -144,20 +142,17 @@ const Tags = ({
144142 direction = "column"
145143 alignItems = "stretch"
146144 gap = { 1 }
147- style = { {
148- position : `relative` ,
149- } }
145+ style = { { position : "relative" } }
150146 ref = { inputEle }
151147 >
152148 < Field . Label action = { labelAction } >
153149 { intlLabel && formatMessage ( { id : intlLabel } ) }
154150 </ Field . Label >
155151 < Flex direction = "column" >
156152 < TagsInput
157- classList = { [ "test" ] }
158153 value = { tags }
159154 onChange = { handleTagsChange }
160- onlyUnique = { true }
155+ onlyUnique
161156 renderInput = { autocompleteRenderInput }
162157 />
163158 </ Flex >
0 commit comments