guestbell-forms 3.0.103 → 3.0.105
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/components/base/input/useBaseInput.d.ts +44 -0
 - package/build/components/base/input/useBaseInput.js +181 -0
 - package/build/components/base/input/useBaseInput.js.map +1 -0
 - package/build/components/tags/Tags.d.ts +1 -1
 - package/build/components/tags/Tags.js +28 -15
 - package/build/components/tags/Tags.js.map +1 -1
 - package/build/dist/guestbell-forms.css +9 -10
 - package/build/dist/guestbell-forms.css.map +1 -1
 - package/build/dist/guestbell-forms.min.css +1 -1
 - package/build/dist/report.html +2 -2
 - package/build/scss/components/tags/tags.scss +9 -8
 - package/package.json +1 -1
 - package/src/lib/components/base/input/useBaseInput.tsx +239 -0
 - package/src/lib/components/tags/Tags.tsx +46 -24
 - package/src/lib/scss/components/tags/tags.scss +9 -8
 - package/src/stories/TagsDemo.tsx +9 -5
 
| 
         @@ -0,0 +1,239 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            // experimental and unfinished and unused for now
         
     | 
| 
      
 2 
     | 
    
         
            +
            import { useState, useRef, useCallback, useEffect } from 'react';
         
     | 
| 
      
 3 
     | 
    
         
            +
            import {
         
     | 
| 
      
 4 
     | 
    
         
            +
              AllowedHtmlElements,
         
     | 
| 
      
 5 
     | 
    
         
            +
              BaseTranslations,
         
     | 
| 
      
 6 
     | 
    
         
            +
              ValidationError,
         
     | 
| 
      
 7 
     | 
    
         
            +
            } from './BaseInput';
         
     | 
| 
      
 8 
     | 
    
         
            +
            import * as Validators from '../../../validators';
         
     | 
| 
      
 9 
     | 
    
         
            +
            import { FormContextState } from '../../form/FormContext';
         
     | 
| 
      
 10 
     | 
    
         
            +
            import guid from '../../utils/Guid';
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            interface UseBaseInputProps<TranslationsT extends BaseTranslations> {
         
     | 
| 
      
 13 
     | 
    
         
            +
              value?: string;
         
     | 
| 
      
 14 
     | 
    
         
            +
              required?: boolean;
         
     | 
| 
      
 15 
     | 
    
         
            +
              validators?: string[];
         
     | 
| 
      
 16 
     | 
    
         
            +
              customValidators?: Validators.IBaseValidator[];
         
     | 
| 
      
 17 
     | 
    
         
            +
              onTheFlightValidate?: (value: string) => boolean;
         
     | 
| 
      
 18 
     | 
    
         
            +
              onChange?: (
         
     | 
| 
      
 19 
     | 
    
         
            +
                event: React.ChangeEvent<AllowedHtmlElements>,
         
     | 
| 
      
 20 
     | 
    
         
            +
                isValid: boolean
         
     | 
| 
      
 21 
     | 
    
         
            +
              ) => void;
         
     | 
| 
      
 22 
     | 
    
         
            +
              onBlur?: () => void;
         
     | 
| 
      
 23 
     | 
    
         
            +
              onFocus?: () => void;
         
     | 
| 
      
 24 
     | 
    
         
            +
              errors?: ValidationError[];
         
     | 
| 
      
 25 
     | 
    
         
            +
              infoText?: string;
         
     | 
| 
      
 26 
     | 
    
         
            +
              touchOn?: 'focus' | 'blur';
         
     | 
| 
      
 27 
     | 
    
         
            +
              showValidation?: boolean;
         
     | 
| 
      
 28 
     | 
    
         
            +
              disabled?: boolean;
         
     | 
| 
      
 29 
     | 
    
         
            +
              ignoreContext?: boolean;
         
     | 
| 
      
 30 
     | 
    
         
            +
              formContext?: FormContextState;
         
     | 
| 
      
 31 
     | 
    
         
            +
              translations?: TranslationsT;
         
     | 
| 
      
 32 
     | 
    
         
            +
              validationName?: string;
         
     | 
| 
      
 33 
     | 
    
         
            +
              label?: string | JSX.Element;
         
     | 
| 
      
 34 
     | 
    
         
            +
            }
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
            export function useBaseInput<
         
     | 
| 
      
 37 
     | 
    
         
            +
              TranslationsT extends BaseTranslations = BaseTranslations
         
     | 
| 
      
 38 
     | 
    
         
            +
            >(props: UseBaseInputProps<TranslationsT>) {
         
     | 
| 
      
 39 
     | 
    
         
            +
              const {
         
     | 
| 
      
 40 
     | 
    
         
            +
                value: initialValue = '',
         
     | 
| 
      
 41 
     | 
    
         
            +
                required = false,
         
     | 
| 
      
 42 
     | 
    
         
            +
                validators = [],
         
     | 
| 
      
 43 
     | 
    
         
            +
                customValidators = [],
         
     | 
| 
      
 44 
     | 
    
         
            +
                onTheFlightValidate,
         
     | 
| 
      
 45 
     | 
    
         
            +
                onChange,
         
     | 
| 
      
 46 
     | 
    
         
            +
                onBlur,
         
     | 
| 
      
 47 
     | 
    
         
            +
                onFocus,
         
     | 
| 
      
 48 
     | 
    
         
            +
                //errors: propErrors = [],
         
     | 
| 
      
 49 
     | 
    
         
            +
                //infoText,
         
     | 
| 
      
 50 
     | 
    
         
            +
                touchOn = 'focus',
         
     | 
| 
      
 51 
     | 
    
         
            +
                //showValidation = true,
         
     | 
| 
      
 52 
     | 
    
         
            +
                disabled = false,
         
     | 
| 
      
 53 
     | 
    
         
            +
                ignoreContext = false,
         
     | 
| 
      
 54 
     | 
    
         
            +
                formContext,
         
     | 
| 
      
 55 
     | 
    
         
            +
                translations,
         
     | 
| 
      
 56 
     | 
    
         
            +
                validationName,
         
     | 
| 
      
 57 
     | 
    
         
            +
                label,
         
     | 
| 
      
 58 
     | 
    
         
            +
              } = props;
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
              const [value, setValue] = useState<string>(initialValue);
         
     | 
| 
      
 61 
     | 
    
         
            +
              const [touched, setTouched] = useState<boolean>(false);
         
     | 
| 
      
 62 
     | 
    
         
            +
              const [isValid, setIsValid] = useState<boolean>(true);
         
     | 
| 
      
 63 
     | 
    
         
            +
              const [errors, setErrors] = useState<ValidationError[]>([]);
         
     | 
| 
      
 64 
     | 
    
         
            +
              const [focused, setFocused] = useState<boolean>(false);
         
     | 
| 
      
 65 
     | 
    
         
            +
              const [componentDisabled, setComponentDisabled] = useState<boolean>(disabled);
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
              const inputRef = useRef<AllowedHtmlElements>(null);
         
     | 
| 
      
 68 
     | 
    
         
            +
              const containerRef = useRef<HTMLDivElement>(null);
         
     | 
| 
      
 69 
     | 
    
         
            +
              const componentId = useRef(guid());
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
              const handleValidation = useCallback(
         
     | 
| 
      
 72 
     | 
    
         
            +
                (currentValue: string, initializing = false) => {
         
     | 
| 
      
 73 
     | 
    
         
            +
                  let validationErrors: ValidationError[] = [];
         
     | 
| 
      
 74 
     | 
    
         
            +
                  let validationStatus = true;
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
                  if (required && !currentValue) {
         
     | 
| 
      
 77 
     | 
    
         
            +
                    validationErrors.push(
         
     | 
| 
      
 78 
     | 
    
         
            +
                      translations?.required || 'This field is required'
         
     | 
| 
      
 79 
     | 
    
         
            +
                    );
         
     | 
| 
      
 80 
     | 
    
         
            +
                    validationStatus = false;
         
     | 
| 
      
 81 
     | 
    
         
            +
                  } else if (validators) {
         
     | 
| 
      
 82 
     | 
    
         
            +
                    validators.forEach((validator) => {
         
     | 
| 
      
 83 
     | 
    
         
            +
                      let isValidForValidator = false;
         
     | 
| 
      
 84 
     | 
    
         
            +
                      switch (validator) {
         
     | 
| 
      
 85 
     | 
    
         
            +
                        case 'email':
         
     | 
| 
      
 86 
     | 
    
         
            +
                          isValidForValidator = new Validators.EmailValidator().Validate(
         
     | 
| 
      
 87 
     | 
    
         
            +
                            currentValue,
         
     | 
| 
      
 88 
     | 
    
         
            +
                            required,
         
     | 
| 
      
 89 
     | 
    
         
            +
                            (error) => validationErrors.push(error)
         
     | 
| 
      
 90 
     | 
    
         
            +
                          );
         
     | 
| 
      
 91 
     | 
    
         
            +
                          break;
         
     | 
| 
      
 92 
     | 
    
         
            +
                        // Add other validators as needed
         
     | 
| 
      
 93 
     | 
    
         
            +
                        default:
         
     | 
| 
      
 94 
     | 
    
         
            +
                          throw new Error(`Validator ${validator} not implemented`);
         
     | 
| 
      
 95 
     | 
    
         
            +
                      }
         
     | 
| 
      
 96 
     | 
    
         
            +
                      if (!isValidForValidator) validationStatus = false;
         
     | 
| 
      
 97 
     | 
    
         
            +
                    });
         
     | 
| 
      
 98 
     | 
    
         
            +
                  }
         
     | 
| 
      
 99 
     | 
    
         
            +
             
     | 
| 
      
 100 
     | 
    
         
            +
                  customValidators.forEach((customValidator) => {
         
     | 
| 
      
 101 
     | 
    
         
            +
                    const isValidForCustomValidator = customValidator.Validate(
         
     | 
| 
      
 102 
     | 
    
         
            +
                      currentValue,
         
     | 
| 
      
 103 
     | 
    
         
            +
                      required,
         
     | 
| 
      
 104 
     | 
    
         
            +
                      (error) => validationErrors.push(error)
         
     | 
| 
      
 105 
     | 
    
         
            +
                    );
         
     | 
| 
      
 106 
     | 
    
         
            +
                    if (!isValidForCustomValidator) validationStatus = false;
         
     | 
| 
      
 107 
     | 
    
         
            +
                  });
         
     | 
| 
      
 108 
     | 
    
         
            +
             
     | 
| 
      
 109 
     | 
    
         
            +
                  setErrors(validationErrors);
         
     | 
| 
      
 110 
     | 
    
         
            +
                  setIsValid(validationStatus);
         
     | 
| 
      
 111 
     | 
    
         
            +
             
     | 
| 
      
 112 
     | 
    
         
            +
                  if (!initializing && !ignoreContext) {
         
     | 
| 
      
 113 
     | 
    
         
            +
                    formContext?.updateCallback(componentId.current, {
         
     | 
| 
      
 114 
     | 
    
         
            +
                      isValid: validationStatus,
         
     | 
| 
      
 115 
     | 
    
         
            +
                      errors: validationErrors,
         
     | 
| 
      
 116 
     | 
    
         
            +
                    });
         
     | 
| 
      
 117 
     | 
    
         
            +
                  }
         
     | 
| 
      
 118 
     | 
    
         
            +
             
     | 
| 
      
 119 
     | 
    
         
            +
                  return { isValid: validationStatus, errors: validationErrors };
         
     | 
| 
      
 120 
     | 
    
         
            +
                },
         
     | 
| 
      
 121 
     | 
    
         
            +
                [
         
     | 
| 
      
 122 
     | 
    
         
            +
                  required,
         
     | 
| 
      
 123 
     | 
    
         
            +
                  validators,
         
     | 
| 
      
 124 
     | 
    
         
            +
                  customValidators,
         
     | 
| 
      
 125 
     | 
    
         
            +
                  formContext,
         
     | 
| 
      
 126 
     | 
    
         
            +
                  translations,
         
     | 
| 
      
 127 
     | 
    
         
            +
                  ignoreContext,
         
     | 
| 
      
 128 
     | 
    
         
            +
                ]
         
     | 
| 
      
 129 
     | 
    
         
            +
              );
         
     | 
| 
      
 130 
     | 
    
         
            +
             
     | 
| 
      
 131 
     | 
    
         
            +
              const handleValueChange = useCallback(
         
     | 
| 
      
 132 
     | 
    
         
            +
                (newValue: string) => {
         
     | 
| 
      
 133 
     | 
    
         
            +
                  if (!onTheFlightValidate || onTheFlightValidate(newValue)) {
         
     | 
| 
      
 134 
     | 
    
         
            +
                    const result = handleValidation(newValue);
         
     | 
| 
      
 135 
     | 
    
         
            +
                    setValue(newValue);
         
     | 
| 
      
 136 
     | 
    
         
            +
                    onChange?.(
         
     | 
| 
      
 137 
     | 
    
         
            +
                      {
         
     | 
| 
      
 138 
     | 
    
         
            +
                        target: { value: newValue },
         
     | 
| 
      
 139 
     | 
    
         
            +
                      } as React.ChangeEvent<AllowedHtmlElements>,
         
     | 
| 
      
 140 
     | 
    
         
            +
                      result.isValid
         
     | 
| 
      
 141 
     | 
    
         
            +
                    );
         
     | 
| 
      
 142 
     | 
    
         
            +
                  }
         
     | 
| 
      
 143 
     | 
    
         
            +
                },
         
     | 
| 
      
 144 
     | 
    
         
            +
                [handleValidation, onTheFlightValidate, onChange]
         
     | 
| 
      
 145 
     | 
    
         
            +
              );
         
     | 
| 
      
 146 
     | 
    
         
            +
             
     | 
| 
      
 147 
     | 
    
         
            +
              const handleFocus = useCallback(() => {
         
     | 
| 
      
 148 
     | 
    
         
            +
                if (!disabled) {
         
     | 
| 
      
 149 
     | 
    
         
            +
                  onFocus?.();
         
     | 
| 
      
 150 
     | 
    
         
            +
                  setFocused(true);
         
     | 
| 
      
 151 
     | 
    
         
            +
                  if (touchOn === 'focus') setTouched(true);
         
     | 
| 
      
 152 
     | 
    
         
            +
                }
         
     | 
| 
      
 153 
     | 
    
         
            +
              }, [disabled, onFocus, touchOn]);
         
     | 
| 
      
 154 
     | 
    
         
            +
             
     | 
| 
      
 155 
     | 
    
         
            +
              const handleBlur = useCallback(() => {
         
     | 
| 
      
 156 
     | 
    
         
            +
                onBlur?.();
         
     | 
| 
      
 157 
     | 
    
         
            +
                setFocused(false);
         
     | 
| 
      
 158 
     | 
    
         
            +
                if (touchOn === 'blur') setTouched(true);
         
     | 
| 
      
 159 
     | 
    
         
            +
              }, [onBlur, touchOn]);
         
     | 
| 
      
 160 
     | 
    
         
            +
             
     | 
| 
      
 161 
     | 
    
         
            +
              const scrollTo = useCallback(() => {
         
     | 
| 
      
 162 
     | 
    
         
            +
                containerRef.current?.scrollIntoView({ behavior: 'smooth' });
         
     | 
| 
      
 163 
     | 
    
         
            +
              }, []);
         
     | 
| 
      
 164 
     | 
    
         
            +
             
     | 
| 
      
 165 
     | 
    
         
            +
              const setValid = useCallback(() => {
         
     | 
| 
      
 166 
     | 
    
         
            +
                setIsValid(true);
         
     | 
| 
      
 167 
     | 
    
         
            +
                setErrors([]);
         
     | 
| 
      
 168 
     | 
    
         
            +
                formContext?.updateCallback(componentId.current, {
         
     | 
| 
      
 169 
     | 
    
         
            +
                  isValid: true,
         
     | 
| 
      
 170 
     | 
    
         
            +
                  errors: [],
         
     | 
| 
      
 171 
     | 
    
         
            +
                });
         
     | 
| 
      
 172 
     | 
    
         
            +
              }, [formContext]);
         
     | 
| 
      
 173 
     | 
    
         
            +
             
     | 
| 
      
 174 
     | 
    
         
            +
              const setInvalid = useCallback(
         
     | 
| 
      
 175 
     | 
    
         
            +
                (validationErrors: ValidationError[] = []) => {
         
     | 
| 
      
 176 
     | 
    
         
            +
                  setIsValid(false);
         
     | 
| 
      
 177 
     | 
    
         
            +
                  setErrors(validationErrors);
         
     | 
| 
      
 178 
     | 
    
         
            +
                  formContext?.updateCallback(componentId.current, {
         
     | 
| 
      
 179 
     | 
    
         
            +
                    isValid: false,
         
     | 
| 
      
 180 
     | 
    
         
            +
                    errors: validationErrors,
         
     | 
| 
      
 181 
     | 
    
         
            +
                  });
         
     | 
| 
      
 182 
     | 
    
         
            +
                },
         
     | 
| 
      
 183 
     | 
    
         
            +
                [formContext]
         
     | 
| 
      
 184 
     | 
    
         
            +
              );
         
     | 
| 
      
 185 
     | 
    
         
            +
             
     | 
| 
      
 186 
     | 
    
         
            +
              const disableComponent = useCallback(() => {
         
     | 
| 
      
 187 
     | 
    
         
            +
                setComponentDisabled(true);
         
     | 
| 
      
 188 
     | 
    
         
            +
              }, []);
         
     | 
| 
      
 189 
     | 
    
         
            +
             
     | 
| 
      
 190 
     | 
    
         
            +
              const enableComponent = useCallback(() => {
         
     | 
| 
      
 191 
     | 
    
         
            +
                setComponentDisabled(false);
         
     | 
| 
      
 192 
     | 
    
         
            +
              }, []);
         
     | 
| 
      
 193 
     | 
    
         
            +
             
     | 
| 
      
 194 
     | 
    
         
            +
              useEffect(() => {
         
     | 
| 
      
 195 
     | 
    
         
            +
                handleValidation(value, true);
         
     | 
| 
      
 196 
     | 
    
         
            +
             
     | 
| 
      
 197 
     | 
    
         
            +
                if (!ignoreContext && formContext) {
         
     | 
| 
      
 198 
     | 
    
         
            +
                  formContext.subscribe(componentId.current, {
         
     | 
| 
      
 199 
     | 
    
         
            +
                    componentApi: {
         
     | 
| 
      
 200 
     | 
    
         
            +
                      disableComponent,
         
     | 
| 
      
 201 
     | 
    
         
            +
                      enableComponent,
         
     | 
| 
      
 202 
     | 
    
         
            +
                      focus: () => inputRef.current?.focus(),
         
     | 
| 
      
 203 
     | 
    
         
            +
                      scrollTo,
         
     | 
| 
      
 204 
     | 
    
         
            +
                      touch: () => setTouched(true),
         
     | 
| 
      
 205 
     | 
    
         
            +
                      unTouch: () => setTouched(false),
         
     | 
| 
      
 206 
     | 
    
         
            +
                    },
         
     | 
| 
      
 207 
     | 
    
         
            +
                    validation: {
         
     | 
| 
      
 208 
     | 
    
         
            +
                      isValid,
         
     | 
| 
      
 209 
     | 
    
         
            +
                      errors,
         
     | 
| 
      
 210 
     | 
    
         
            +
                      name: validationName || label,
         
     | 
| 
      
 211 
     | 
    
         
            +
                    },
         
     | 
| 
      
 212 
     | 
    
         
            +
                  });
         
     | 
| 
      
 213 
     | 
    
         
            +
                }
         
     | 
| 
      
 214 
     | 
    
         
            +
             
     | 
| 
      
 215 
     | 
    
         
            +
                return () => {
         
     | 
| 
      
 216 
     | 
    
         
            +
                  if (!ignoreContext) formContext?.unSubscribe(componentId.current);
         
     | 
| 
      
 217 
     | 
    
         
            +
                };
         
     | 
| 
      
 218 
     | 
    
         
            +
              }, [formContext, ignoreContext, handleValidation, value]);
         
     | 
| 
      
 219 
     | 
    
         
            +
             
     | 
| 
      
 220 
     | 
    
         
            +
              return {
         
     | 
| 
      
 221 
     | 
    
         
            +
                value,
         
     | 
| 
      
 222 
     | 
    
         
            +
                setValue: handleValueChange,
         
     | 
| 
      
 223 
     | 
    
         
            +
                isValid,
         
     | 
| 
      
 224 
     | 
    
         
            +
                errors,
         
     | 
| 
      
 225 
     | 
    
         
            +
                touched,
         
     | 
| 
      
 226 
     | 
    
         
            +
                focused,
         
     | 
| 
      
 227 
     | 
    
         
            +
                inputRef,
         
     | 
| 
      
 228 
     | 
    
         
            +
                containerRef,
         
     | 
| 
      
 229 
     | 
    
         
            +
                handleFocus,
         
     | 
| 
      
 230 
     | 
    
         
            +
                handleBlur,
         
     | 
| 
      
 231 
     | 
    
         
            +
                scrollTo,
         
     | 
| 
      
 232 
     | 
    
         
            +
                setValid,
         
     | 
| 
      
 233 
     | 
    
         
            +
                setInvalid,
         
     | 
| 
      
 234 
     | 
    
         
            +
                disableComponent,
         
     | 
| 
      
 235 
     | 
    
         
            +
                enableComponent,
         
     | 
| 
      
 236 
     | 
    
         
            +
                setTouched,
         
     | 
| 
      
 237 
     | 
    
         
            +
                componentDisabled,
         
     | 
| 
      
 238 
     | 
    
         
            +
              };
         
     | 
| 
      
 239 
     | 
    
         
            +
            }
         
     | 
| 
         @@ -176,7 +176,10 @@ export class TagsRaw< 
     | 
|
| 
       176 
176 
     | 
    
         
             
                }
         
     | 
| 
       177 
177 
     | 
    
         
             
              }
         
     | 
| 
       178 
178 
     | 
    
         | 
| 
       179 
     | 
    
         
            -
              public componentDidUpdate( 
     | 
| 
      
 179 
     | 
    
         
            +
              public componentDidUpdate(
         
     | 
| 
      
 180 
     | 
    
         
            +
                oldProps: TagsProps<IdT, T> & InjectedProps,
         
     | 
| 
      
 181 
     | 
    
         
            +
                oldState: TagsState<IdT, T>
         
     | 
| 
      
 182 
     | 
    
         
            +
              ) {
         
     | 
| 
       180 
183 
     | 
    
         
             
                if (
         
     | 
| 
       181 
184 
     | 
    
         
             
                  oldProps.tags !== this.props.tags ||
         
     | 
| 
       182 
185 
     | 
    
         
             
                  oldProps.validators !== this.props.validators ||
         
     | 
| 
         @@ -185,8 +188,14 @@ export class TagsRaw< 
     | 
|
| 
       185 
188 
     | 
    
         
             
                ) {
         
     | 
| 
       186 
189 
     | 
    
         
             
                  this.handleErrors(this.props.tags);
         
     | 
| 
       187 
190 
     | 
    
         
             
                }
         
     | 
| 
       188 
     | 
    
         
            -
                if ( 
     | 
| 
       189 
     | 
    
         
            -
                  this. 
     | 
| 
      
 191 
     | 
    
         
            +
                if (
         
     | 
| 
      
 192 
     | 
    
         
            +
                  this.state.suggestionsVisible &&
         
     | 
| 
      
 193 
     | 
    
         
            +
                  (oldProps.tags !== this.props.tags ||
         
     | 
| 
      
 194 
     | 
    
         
            +
                    oldProps.existingTags !== this.props.existingTags ||
         
     | 
| 
      
 195 
     | 
    
         
            +
                    this.state.value !== oldState.value ||
         
     | 
| 
      
 196 
     | 
    
         
            +
                    this.state.suggestionsVisible !== oldState.suggestionsVisible)
         
     | 
| 
      
 197 
     | 
    
         
            +
                ) {
         
     | 
| 
      
 198 
     | 
    
         
            +
                  this.fetchExistingTags(this.state.value);
         
     | 
| 
       190 
199 
     | 
    
         
             
                }
         
     | 
| 
       191 
200 
     | 
    
         
             
              }
         
     | 
| 
       192 
201 
     | 
    
         | 
| 
         @@ -450,7 +459,6 @@ export class TagsRaw< 
     | 
|
| 
       450 
459 
     | 
    
         
             
                if (!this.state.suggestionsVisible) {
         
     | 
| 
       451 
460 
     | 
    
         
             
                  this.props.onSuggestionsOpened?.();
         
     | 
| 
       452 
461 
     | 
    
         
             
                }
         
     | 
| 
       453 
     | 
    
         
            -
                this.fetchExistingTags(this.state.value);
         
     | 
| 
       454 
462 
     | 
    
         
             
                this.setState(
         
     | 
| 
       455 
463 
     | 
    
         
             
                  () => ({ textIsFocused: true, suggestionsVisible: true, touched: true }),
         
     | 
| 
       456 
464 
     | 
    
         
             
                  () => this.handleErrors()
         
     | 
| 
         @@ -493,13 +501,11 @@ export class TagsRaw< 
     | 
|
| 
       493 
501 
     | 
    
         
             
                      this.props.tags.concat(suggestions[this.state.preselectedSuggestion])
         
     | 
| 
       494 
502 
     | 
    
         
             
                    );
         
     | 
| 
       495 
503 
     | 
    
         
             
                    this.setState({ value: '', preselectedSuggestion: undefined }, () => {
         
     | 
| 
       496 
     | 
    
         
            -
                      this.fetchExistingTags();
         
     | 
| 
       497 
504 
     | 
    
         
             
                      this.handleErrors();
         
     | 
| 
       498 
505 
     | 
    
         
             
                    });
         
     | 
| 
       499 
506 
     | 
    
         
             
                  } else if (existingTag) {
         
     | 
| 
       500 
507 
     | 
    
         
             
                    this.props.onTagsChanged(this.props.tags.concat(existingTag));
         
     | 
| 
       501 
508 
     | 
    
         
             
                    this.setState({ value: '' }, () => {
         
     | 
| 
       502 
     | 
    
         
            -
                      this.fetchExistingTags();
         
     | 
| 
       503 
509 
     | 
    
         
             
                      this.handleErrors();
         
     | 
| 
       504 
510 
     | 
    
         
             
                    });
         
     | 
| 
       505 
511 
     | 
    
         
             
                  } else if (this.props.allowNew) {
         
     | 
| 
         @@ -537,13 +543,15 @@ export class TagsRaw< 
     | 
|
| 
       537 
543 
     | 
    
         
             
                    ? false
         
     | 
| 
       538 
544 
     | 
    
         
             
                    : this.state.suggestionsVisible,
         
     | 
| 
       539 
545 
     | 
    
         
             
                });
         
     | 
| 
      
 546 
     | 
    
         
            +
                const newTags = newTag
         
     | 
| 
      
 547 
     | 
    
         
            +
                  ? this.props.tags
         
     | 
| 
      
 548 
     | 
    
         
            +
                    ? this.props.tags.concat(newTag)
         
     | 
| 
      
 549 
     | 
    
         
            +
                    : [newTag]
         
     | 
| 
      
 550 
     | 
    
         
            +
                  : this.props.tags;
         
     | 
| 
       540 
551 
     | 
    
         
             
                if (newTag) {
         
     | 
| 
       541 
     | 
    
         
            -
                  this.props.onTagsChanged(
         
     | 
| 
       542 
     | 
    
         
            -
                    this.props.tags ? this.props.tags.concat(newTag) : [newTag]
         
     | 
| 
       543 
     | 
    
         
            -
                  );
         
     | 
| 
      
 552 
     | 
    
         
            +
                  this.props.onTagsChanged(newTags);
         
     | 
| 
       544 
553 
     | 
    
         
             
                }
         
     | 
| 
       545 
554 
     | 
    
         
             
                this.setState({ value: '', textErrors: [] }, () => {
         
     | 
| 
       546 
     | 
    
         
            -
                  this.fetchExistingTags();
         
     | 
| 
       547 
555 
     | 
    
         
             
                  this.handleErrors();
         
     | 
| 
       548 
556 
     | 
    
         
             
                });
         
     | 
| 
       549 
557 
     | 
    
         
             
              };
         
     | 
| 
         @@ -602,7 +610,6 @@ export class TagsRaw< 
     | 
|
| 
       602 
610 
     | 
    
         
             
                  }),
         
     | 
| 
       603 
611 
     | 
    
         
             
                  () => this.handleErrors()
         
     | 
| 
       604 
612 
     | 
    
         
             
                );
         
     | 
| 
       605 
     | 
    
         
            -
                this.fetchExistingTags(e.target.value);
         
     | 
| 
       606 
613 
     | 
    
         
             
              };
         
     | 
| 
       607 
614 
     | 
    
         | 
| 
       608 
615 
     | 
    
         
             
              private handleErrors = (tags: T[] = this.props.tags) => {
         
     | 
| 
         @@ -653,15 +660,30 @@ export class TagsRaw< 
     | 
|
| 
       653 
660 
     | 
    
         
             
                    () => this.setState(() => ({ fetchingExistingTags: true })),
         
     | 
| 
       654 
661 
     | 
    
         
             
                    this.props.loadingDelayMs
         
     | 
| 
       655 
662 
     | 
    
         
             
                  );
         
     | 
| 
       656 
     | 
    
         
            -
                  this.props
         
     | 
| 
       657 
     | 
    
         
            -
             
     | 
| 
       658 
     | 
    
         
            -
                     
     | 
| 
       659 
     | 
    
         
            -
                       
     | 
| 
       660 
     | 
    
         
            -
             
     | 
| 
       661 
     | 
    
         
            -
             
     | 
| 
       662 
     | 
    
         
            -
             
     | 
| 
       663 
     | 
    
         
            -
             
     | 
| 
       664 
     | 
    
         
            -
             
     | 
| 
      
 663 
     | 
    
         
            +
                  const prom = this.props.fetchExistingTags(startsWith, this.props.tags);
         
     | 
| 
      
 664 
     | 
    
         
            +
                  if (prom) {
         
     | 
| 
      
 665 
     | 
    
         
            +
                    prom
         
     | 
| 
      
 666 
     | 
    
         
            +
                      .then((fetchedExistingTags) => {
         
     | 
| 
      
 667 
     | 
    
         
            +
                        if (fetchedExistingTags) {
         
     | 
| 
      
 668 
     | 
    
         
            +
                          clearTimeout(timer);
         
     | 
| 
      
 669 
     | 
    
         
            +
                          this.setState(() => ({
         
     | 
| 
      
 670 
     | 
    
         
            +
                            fetchedExistingTags,
         
     | 
| 
      
 671 
     | 
    
         
            +
                            fetchingExistingTags: false,
         
     | 
| 
      
 672 
     | 
    
         
            +
                          }));
         
     | 
| 
      
 673 
     | 
    
         
            +
                        }
         
     | 
| 
      
 674 
     | 
    
         
            +
                      })
         
     | 
| 
      
 675 
     | 
    
         
            +
                      .catch(() => {
         
     | 
| 
      
 676 
     | 
    
         
            +
                        clearTimeout(timer);
         
     | 
| 
      
 677 
     | 
    
         
            +
                        this.setState(() => ({
         
     | 
| 
      
 678 
     | 
    
         
            +
                          fetchingExistingTags: false,
         
     | 
| 
      
 679 
     | 
    
         
            +
                        }));
         
     | 
| 
      
 680 
     | 
    
         
            +
                      });
         
     | 
| 
      
 681 
     | 
    
         
            +
                  } else {
         
     | 
| 
      
 682 
     | 
    
         
            +
                    clearTimeout(timer);
         
     | 
| 
      
 683 
     | 
    
         
            +
                    this.setState(() => ({
         
     | 
| 
      
 684 
     | 
    
         
            +
                      fetchingExistingTags: false,
         
     | 
| 
      
 685 
     | 
    
         
            +
                    }));
         
     | 
| 
      
 686 
     | 
    
         
            +
                  }
         
     | 
| 
       665 
687 
     | 
    
         
             
                }
         
     | 
| 
       666 
688 
     | 
    
         
             
              }
         
     | 
| 
       667 
689 
     | 
    
         | 
| 
         @@ -702,11 +724,11 @@ export class TagsRaw< 
     | 
|
| 
       702 
724 
     | 
    
         
             
                        circular={true}
         
     | 
| 
       703 
725 
     | 
    
         
             
                        blank={true}
         
     | 
| 
       704 
726 
     | 
    
         
             
                        onClick={this.tagRemoveClick(tag)}
         
     | 
| 
       705 
     | 
    
         
            -
                        className=" 
     | 
| 
      
 727 
     | 
    
         
            +
                        className="tags-input__tag__removeButton p-0"
         
     | 
| 
       706 
728 
     | 
    
         
             
                        Component={TagButtonComponent}
         
     | 
| 
       707 
729 
     | 
    
         
             
                        preventsDefault={false}
         
     | 
| 
       708 
730 
     | 
    
         
             
                      >
         
     | 
| 
       709 
     | 
    
         
            -
                        <PlusIcon />
         
     | 
| 
      
 731 
     | 
    
         
            +
                        <PlusIcon className="transform-rotate--45" />
         
     | 
| 
       710 
732 
     | 
    
         
             
                      </Button>
         
     | 
| 
       711 
733 
     | 
    
         
             
                    )}
         
     | 
| 
       712 
734 
     | 
    
         
             
                  </>
         
     | 
| 
         @@ -727,9 +749,9 @@ export class TagsRaw< 
     | 
|
| 
       727 
749 
     | 
    
         
             
                  );
         
     | 
| 
       728 
750 
     | 
    
         
             
                }
         
     | 
| 
       729 
751 
     | 
    
         
             
                return (
         
     | 
| 
       730 
     | 
    
         
            -
                  < 
     | 
| 
      
 752 
     | 
    
         
            +
                  <span onClick={this.tagClick(tag)} className={className} key={index}>
         
     | 
| 
       731 
753 
     | 
    
         
             
                    {body}
         
     | 
| 
       732 
     | 
    
         
            -
                  </ 
     | 
| 
      
 754 
     | 
    
         
            +
                  </span>
         
     | 
| 
       733 
755 
     | 
    
         
             
                );
         
     | 
| 
       734 
756 
     | 
    
         
             
              }
         
     | 
| 
       735 
757 
     | 
    
         | 
| 
         @@ -12,26 +12,27 @@ 
     | 
|
| 
       12 
12 
     | 
    
         
             
              }
         
     | 
| 
       13 
13 
     | 
    
         
             
              .tags-input__tag {
         
     | 
| 
       14 
14 
     | 
    
         
             
                position: relative;
         
     | 
| 
       15 
     | 
    
         
            -
                display: inline-flex;
         
     | 
| 
       16 
     | 
    
         
            -
                align-items: center;
         
     | 
| 
       17 
     | 
    
         
            -
                padding-left: 0.25rem;
         
     | 
| 
       18 
15 
     | 
    
         
             
                margin-right: 0.25rem;
         
     | 
| 
       19 
     | 
    
         
            -
                margin-bottom: 0.125rem;
         
     | 
| 
       20 
     | 
    
         
            -
                margin-top: 0.125rem;
         
     | 
| 
       21 
16 
     | 
    
         
             
                &.tags-input__tag-chip {
         
     | 
| 
       22 
17 
     | 
    
         
             
                  border: 1px solid;
         
     | 
| 
       23 
18 
     | 
    
         
             
                  border-radius: 1.5rem;
         
     | 
| 
       24 
19 
     | 
    
         
             
                }
         
     | 
| 
       25 
20 
     | 
    
         
             
              }
         
     | 
| 
      
 21 
     | 
    
         
            +
              .tags-input__tag__removeButton {
         
     | 
| 
      
 22 
     | 
    
         
            +
                margin-left: 2px;
         
     | 
| 
      
 23 
     | 
    
         
            +
                svg {
         
     | 
| 
      
 24 
     | 
    
         
            +
                  vertical-align: -0.4rem;
         
     | 
| 
      
 25 
     | 
    
         
            +
                }
         
     | 
| 
      
 26 
     | 
    
         
            +
              }
         
     | 
| 
       26 
27 
     | 
    
         
             
              .tags-input__tags__wrapper {
         
     | 
| 
       27 
28 
     | 
    
         
             
                display: flex;
         
     | 
| 
       28 
29 
     | 
    
         
             
                align-items: center;
         
     | 
| 
      
 30 
     | 
    
         
            +
                line-height: 1.75;
         
     | 
| 
       29 
31 
     | 
    
         
             
              }
         
     | 
| 
       30 
32 
     | 
    
         
             
              .tags-input__tag__wrapper {
         
     | 
| 
       31 
     | 
    
         
            -
                display: inline-flex;
         
     | 
| 
       32 
     | 
    
         
            -
                flex-wrap: wrap;
         
     | 
| 
       33 
33 
     | 
    
         
             
                padding-top: 0.25rem;
         
     | 
| 
       34 
     | 
    
         
            -
                padding- 
     | 
| 
      
 34 
     | 
    
         
            +
                padding-left: 0.25rem;
         
     | 
| 
      
 35 
     | 
    
         
            +
                padding-right: 0.25rem;
         
     | 
| 
       35 
36 
     | 
    
         
             
              }
         
     | 
| 
       36 
37 
     | 
    
         
             
              &.tags-input--readOnly {
         
     | 
| 
       37 
38 
     | 
    
         
             
                border-bottom-color: transparent !important;
         
     | 
    
        package/src/stories/TagsDemo.tsx
    CHANGED
    
    | 
         @@ -38,15 +38,19 @@ export function TagsDemo(props: TagsProps) { 
     | 
|
| 
       38 
38 
     | 
    
         
             
                <Tags
         
     | 
| 
       39 
39 
     | 
    
         
             
                  title="Tags suggestions"
         
     | 
| 
       40 
40 
     | 
    
         
             
                  label="Choose or create tags"
         
     | 
| 
       41 
     | 
    
         
            -
                  fetchExistingTags={(startsWith) =>
         
     | 
| 
       42 
     | 
    
         
            -
                    new Promise<Tag[]>((resolve) =>
         
     | 
| 
      
 41 
     | 
    
         
            +
                  fetchExistingTags={(startsWith, tags) => {
         
     | 
| 
      
 42 
     | 
    
         
            +
                    return new Promise<Tag[]>((resolve) =>
         
     | 
| 
       43 
43 
     | 
    
         
             
                      setTimeout(
         
     | 
| 
       44 
44 
     | 
    
         
             
                        () =>
         
     | 
| 
       45 
     | 
    
         
            -
                          resolve( 
     | 
| 
      
 45 
     | 
    
         
            +
                          resolve(
         
     | 
| 
      
 46 
     | 
    
         
            +
                            existingTags
         
     | 
| 
      
 47 
     | 
    
         
            +
                              .filter((e) => e.name.includes(startsWith))
         
     | 
| 
      
 48 
     | 
    
         
            +
                              .filter((e) => !tags.find((t) => t.id === e.id))
         
     | 
| 
      
 49 
     | 
    
         
            +
                          ),
         
     | 
| 
       46 
50 
     | 
    
         
             
                        1000
         
     | 
| 
       47 
51 
     | 
    
         
             
                      )
         
     | 
| 
       48 
     | 
    
         
            -
                    )
         
     | 
| 
       49 
     | 
    
         
            -
                  }
         
     | 
| 
      
 52 
     | 
    
         
            +
                    );
         
     | 
| 
      
 53 
     | 
    
         
            +
                  }}
         
     | 
| 
       50 
54 
     | 
    
         
             
                  suggestionsEmptyComponent={'Not found'}
         
     | 
| 
       51 
55 
     | 
    
         
             
                  tags={tags}
         
     | 
| 
       52 
56 
     | 
    
         
             
                  onTagsChanged={setTags}
         
     |