@ssa-ui-kit/core 2.15.0-canary-8972259-20250507 → 2.16.0

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/dist/index.js CHANGED
@@ -11307,11 +11307,11 @@ const Calendar_DatePickerCalendar = () => {
11307
11307
  };
11308
11308
  const {
11309
11309
  calendarType,
11310
- calendarClassname
11310
+ classNames
11311
11311
  } = useDateRangePickerContext();
11312
11312
  const Component = components[calendarType];
11313
11313
  return (0,jsx_runtime_namespaceObject.jsxs)(PopoverContent, {
11314
- className: ['popover', calendarClassname].filter(Boolean).join(' '),
11314
+ className: ['popover', classNames?.calendar].filter(Boolean).join(' '),
11315
11315
  "data-testid": "daterangepicker-calendar",
11316
11316
  css: /*#__PURE__*/(0,react_namespaceObject.css)({
11317
11317
  background: theme.colors.white,
@@ -11529,6 +11529,7 @@ const WithTriggerPopover = ({
11529
11529
  const TriggerInput = ({
11530
11530
  datepickerType,
11531
11531
  withPopover = false,
11532
+ className,
11532
11533
  onClick
11533
11534
  }) => {
11534
11535
  const {
@@ -11574,6 +11575,7 @@ const TriggerInput = ({
11574
11575
  ref: datepickerType === 'from' ? inputFromRef : inputToRef,
11575
11576
  disabled: disabled,
11576
11577
  register: register,
11578
+ className: className,
11577
11579
  inputProps: {
11578
11580
  onBlur: handleBlur,
11579
11581
  onClick: handleOpen,
@@ -11630,7 +11632,7 @@ const Trigger = () => {
11630
11632
  openCalendarMode,
11631
11633
  isOpen,
11632
11634
  showCalendarIcon,
11633
- triggerClassname,
11635
+ classNames,
11634
11636
  setIsOpen,
11635
11637
  handleToggleOpen
11636
11638
  } = useDateRangePickerContext();
@@ -11653,16 +11655,19 @@ const Trigger = () => {
11653
11655
  status: status,
11654
11656
  disabled: disabled,
11655
11657
  "data-testid": "daterangepicker",
11656
- className: triggerClassname,
11658
+ className: classNames?.trigger?.root,
11657
11659
  children: [(0,jsx_runtime_namespaceObject.jsx)(FieldLabel, {
11658
11660
  htmlFor: lastFocusedElement === 'from' ? nameFrom : nameTo,
11661
+ className: classNames?.label,
11659
11662
  children: label
11660
11663
  }), (0,jsx_runtime_namespaceObject.jsx)(FieldControl, {
11661
11664
  children: (0,jsx_runtime_namespaceObject.jsxs)(Wrapper_Wrapper, {
11662
11665
  ref: wrapperRef,
11666
+ className: classNames?.trigger?.controlsWrapper,
11663
11667
  children: [(0,jsx_runtime_namespaceObject.jsx)(TriggerInput, {
11664
11668
  withPopover: true,
11665
11669
  datepickerType: "from",
11670
+ className: classNames?.trigger?.inputFrom,
11666
11671
  onClick: () => {
11667
11672
  if (!isOpen) {
11668
11673
  setIsOpen(true);
@@ -11672,9 +11677,11 @@ const Trigger = () => {
11672
11677
  name: "carrot-right",
11673
11678
  size: 18,
11674
11679
  color: theme.colors.greyDarker80,
11680
+ className: classNames?.trigger?.icon,
11675
11681
  css: Trigger_ref
11676
11682
  }), (0,jsx_runtime_namespaceObject.jsx)(TriggerInput, {
11677
11683
  datepickerType: "to",
11684
+ className: classNames?.trigger?.inputTo,
11678
11685
  onClick: () => {
11679
11686
  if (!isOpen) {
11680
11687
  setIsOpen(true);
@@ -17514,7 +17521,6 @@ const TypeaheadContext = /*#__PURE__*/external_react_namespaceObject.createConte
17514
17521
  options: [],
17515
17522
  placeholder: '',
17516
17523
  useFormResult: {},
17517
- error: undefined,
17518
17524
  setValue: () => {
17519
17525
  /* no-op */
17520
17526
  },
@@ -17522,7 +17528,7 @@ const TypeaheadContext = /*#__PURE__*/external_react_namespaceObject.createConte
17522
17528
  /* eslint-disable-next-line @typescript-eslint/no-explicit-any */
17523
17529
  return {};
17524
17530
  },
17525
- onChange: () => {
17531
+ handleChange: () => {
17526
17532
  /* no-op */
17527
17533
  },
17528
17534
  handleClearAll: () => {
@@ -17542,6 +17548,9 @@ const TypeaheadContext = /*#__PURE__*/external_react_namespaceObject.createConte
17542
17548
  },
17543
17549
  handleRemoveSelectedClick: () => () => {
17544
17550
  /* no-op */
17551
+ },
17552
+ handleSelectedClick: () => {
17553
+ /* no-op */
17545
17554
  }
17546
17555
  });
17547
17556
  const useTypeaheadContext = () => external_react_namespaceObject.useContext(TypeaheadContext);
@@ -17549,18 +17558,10 @@ const useTypeaheadContext = () => external_react_namespaceObject.useContext(Type
17549
17558
 
17550
17559
 
17551
17560
 
17552
- const findExactMatch = (input, options) => {
17553
- const normalizedInput = input.toLowerCase();
17554
- return Object.values(options).find(opt => {
17555
- const labelText = (opt.label ?? opt.value).toString().toLowerCase();
17556
- return labelText === normalizedInput;
17557
- });
17558
- };
17559
17561
  const useTypeahead = ({
17560
17562
  name = 'typeahead-input',
17561
17563
  isOpen: isInitOpen,
17562
- selectedItems: providedSelectedItems,
17563
- defaultSelectedItems,
17564
+ selectedItems,
17564
17565
  isDisabled,
17565
17566
  isMultiple,
17566
17567
  children,
@@ -17573,8 +17574,8 @@ const useTypeahead = ({
17573
17574
  error,
17574
17575
  success,
17575
17576
  placeholder,
17576
- filterOptions = true,
17577
- autoSelect = true,
17577
+ register,
17578
+ setValue,
17578
17579
  onChange,
17579
17580
  onClearAll,
17580
17581
  onRemoveSelectedClick,
@@ -17582,250 +17583,271 @@ const useTypeahead = ({
17582
17583
  renderOption
17583
17584
  }) => {
17584
17585
  const inputName = `${name}-text`;
17585
- const defaultForm = (0,external_react_hook_form_namespaceObject.useForm)();
17586
- const form = (0,external_react_hook_form_namespaceObject.useFormContext)() ?? defaultForm;
17587
- const {
17588
- register,
17589
- setValue,
17590
- watch
17591
- } = form;
17592
- const formFieldValue = watch(name);
17593
- const controlledValue = (() => {
17594
- if (providedSelectedItems) {
17595
- return providedSelectedItems;
17596
- }
17597
- // controlledValue should be undefined if defaultSelectedItems is provided
17598
- if (defaultSelectedItems) {
17599
- return;
17586
+ const [isOpen, setIsOpen] = (0,external_react_namespaceObject.useState)(isInitOpen || false);
17587
+ const [selected, setSelected] = (0,external_react_namespaceObject.useState)(selectedItems || []);
17588
+ const [optionsWithKey, setOptionsWithKey] = (0,external_react_namespaceObject.useState)({});
17589
+ const [isEmpty, setIsEmpty] = (0,external_react_namespaceObject.useState)(true);
17590
+ const [isFirstRender, setFirstRender] = (0,external_react_namespaceObject.useState)(true);
17591
+ const [items, setItems] = (0,external_react_namespaceObject.useState)();
17592
+ const [inputValue, setInputValue] = (0,external_react_namespaceObject.useState)('');
17593
+ const [status, setStatus] = (0,external_react_namespaceObject.useState)('basic');
17594
+ const [firstSuggestion, setFirstSuggestion] = (0,external_react_namespaceObject.useState)('');
17595
+ const inputRef = (0,external_react_namespaceObject.useRef)(null);
17596
+ const typeaheadId = (0,external_react_namespaceObject.useId)();
17597
+ const triggerRef = (0,external_react_namespaceObject.useRef)(null);
17598
+ const useFormResult = (0,external_react_hook_form_namespaceObject.useForm)();
17599
+ (0,external_react_namespaceObject.useEffect)(() => {
17600
+ if (!register) {
17601
+ console.warn('Typeahead component must be used within a Form component');
17600
17602
  }
17603
+ }, []);
17604
+ (0,external_react_namespaceObject.useEffect)(() => {
17601
17605
  if (isMultiple) {
17602
- return Array.isArray(formFieldValue) ? formFieldValue : [];
17606
+ setValue?.(name, selected, {
17607
+ shouldDirty: !isFirstRender
17608
+ });
17609
+ setInputValue('');
17610
+ setFirstSuggestion('');
17611
+ } else {
17612
+ setValue?.(name, selected.length ? selected[0] : [], {
17613
+ shouldDirty: !isFirstRender
17614
+ });
17603
17615
  }
17604
- return ['number', 'string'].includes(typeof formFieldValue) ? [formFieldValue] : [];
17605
- })();
17606
- const [isOpen, _setIsOpen] = (0,hooks_namespaceObject.useUncontrolled)({
17607
- defaultValue: isInitOpen,
17608
- finalValue: false
17609
- });
17610
- const [selectedItems, setSelected] = (0,hooks_namespaceObject.useUncontrolled)({
17611
- value: controlledValue,
17612
- defaultValue: defaultSelectedItems,
17613
- finalValue: []
17614
- });
17615
- const [rawInput, setRawInput] = (0,external_react_namespaceObject.useState)(null);
17616
- const {
17617
- ref: inputRef
17618
- } = (0,hooks_namespaceObject.useElementSize)();
17619
- const triggerRef = (0,external_react_namespaceObject.useRef)(null);
17620
- (0,external_react_hook_form_namespaceObject.useController)({
17621
- name,
17622
- rules: validationSchema,
17623
- defaultValue: isMultiple ? selectedItems : selectedItems[0]
17624
- });
17625
- const typeaheadId = (0,external_react_namespaceObject.useId)();
17626
- const optionsWithKey = (0,external_react_namespaceObject.useMemo)(() => {
17627
- const opts = {};
17628
- external_react_default().Children.forEach(children, child => {
17629
- if (/*#__PURE__*/external_react_default().isValidElement(child)) {
17630
- opts[child.props.value] = child.props;
17631
- }
17616
+ handleOnEmptyChange(!selected.length);
17617
+ }, [selected]);
17618
+ (0,external_react_namespaceObject.useEffect)(() => {
17619
+ if (isDisabled && isOpen) {
17620
+ setIsOpen(false);
17621
+ }
17622
+ }, [isDisabled]);
17623
+ (0,external_react_namespaceObject.useEffect)(() => {
17624
+ const status = success ? 'success' : useFormResult.formState.errors[name] ? 'error' : 'basic';
17625
+ setStatus(status);
17626
+ }, [useFormResult.formState.errors[name], success]);
17627
+ (0,external_react_namespaceObject.useEffect)(() => {
17628
+ if (error) {
17629
+ useFormResult.setError(name, error);
17630
+ } else {
17631
+ setStatus('basic');
17632
+ useFormResult.resetField(name);
17633
+ }
17634
+ }, [error]);
17635
+ (0,external_react_namespaceObject.useEffect)(() => {
17636
+ processChildren({
17637
+ selectedLocal: selected
17632
17638
  });
17633
- return opts;
17634
17639
  }, [children]);
17635
- const inputValue = (0,external_react_namespaceObject.useMemo)(() => {
17636
- if (isMultiple) return rawInput ?? '';
17637
- if (rawInput != null) return rawInput;
17638
- return selectedItems.length === 1 ? optionsWithKey[selectedItems[0]]?.label?.toString() || '' : '';
17639
- }, [isMultiple, rawInput, selectedItems, optionsWithKey]);
17640
- const filteredChildren = (0,external_react_namespaceObject.useMemo)(() => {
17641
- // if filtering is disabled, or there's no input, show all
17642
- if (!filterOptions || !inputValue) return external_react_default().Children.toArray(children);
17643
- const needle = inputValue.toLowerCase();
17644
- return external_react_default().Children.toArray(children).filter(child => {
17645
- if (! /*#__PURE__*/external_react_default().isValidElement(child)) return false;
17646
- const {
17647
- label,
17648
- value
17649
- } = child.props;
17650
- const text = (label ?? value)?.toString().toLowerCase() || '';
17651
- return text.includes(needle);
17640
+ (0,external_react_namespaceObject.useEffect)(() => {
17641
+ setSelected(selectedItems || []);
17642
+ if (selectedItems?.length) {
17643
+ if (!isMultiple) {
17644
+ const currentOption = optionsWithKey[selectedItems[0]];
17645
+ const optionText = currentOption && (currentOption.children || currentOption.label || currentOption.value);
17646
+ setInputValue(`${optionText}`);
17647
+ }
17648
+ } else {
17649
+ setInputValue('');
17650
+ setFirstSuggestion('');
17651
+ }
17652
+ processChildren({
17653
+ selectedLocal: selectedItems || []
17652
17654
  });
17653
- }, [children, inputValue]);
17654
- const items = (0,external_react_namespaceObject.useMemo)(() => {
17655
- return filteredChildren.map((child, index) => {
17656
- if (! /*#__PURE__*/external_react_default().isValidElement(child)) return null;
17657
- const isActive = selectedItems.includes(child.props.value);
17655
+ }, [selectedItems]);
17656
+ (0,external_react_namespaceObject.useEffect)(() => {
17657
+ const childrenArray = external_react_default().Children.toArray(children).filter(Boolean);
17658
+ const filteredOptions = [...childrenArray];
17659
+ const childItems = filteredOptions.map((child, index) => {
17658
17660
  const {
17661
+ id,
17659
17662
  value,
17660
17663
  label,
17661
- id,
17662
17664
  isDisabled
17663
17665
  } = child.props;
17666
+ const isActive = selected.includes(child.props.value);
17664
17667
  return /*#__PURE__*/external_react_default().cloneElement(child, {
17665
- ...child.props,
17666
17668
  index,
17669
+ ...child.props,
17667
17670
  isActive,
17668
17671
  isDisabled,
17669
- role: 'option',
17672
+ id,
17670
17673
  'aria-selected': isActive,
17671
17674
  'aria-labelledby': `typeahead-label-${name}`,
17672
- onClick: e => {
17673
- e.preventDefault();
17675
+ role: 'option',
17676
+ onClick: event => {
17677
+ event.preventDefault();
17674
17678
  if (!isDisabled) {
17675
- const shouldClose = !isMultiple;
17676
- handleChange({
17677
- value,
17678
- shouldClose
17679
- });
17679
+ handleChange(child.props.value);
17680
17680
  }
17681
17681
  },
17682
- children: renderOption?.({
17682
+ children: renderOption ? renderOption({
17683
17683
  value: id || value,
17684
- input: inputValue,
17684
+ input: inputValue || '',
17685
17685
  label
17686
- }) ?? child.props.children ?? label ?? value
17686
+ }) : child.props.children || child.props.label || child.props.value
17687
17687
  });
17688
17688
  });
17689
- }, [children, selectedItems, inputValue]);
17690
- const firstSuggestion = (0,external_react_namespaceObject.useMemo)(() => {
17691
- if (!inputValue) return '';
17692
- const needle = inputValue.toLowerCase();
17693
- for (const child of filteredChildren) {
17694
- if (! /*#__PURE__*/external_react_default().isValidElement(child)) continue;
17695
- const labelText = (child.props.label ?? child.props.value).toString();
17696
- if (labelText.toLowerCase().startsWith(needle)) {
17697
- return inputValue + labelText.slice(inputValue.length);
17689
+ setItems(childItems);
17690
+ }, [inputValue, optionsWithKey, selected]);
17691
+ (0,external_react_namespaceObject.useEffect)(() => {
17692
+ if (!isMultiple && Object.keys(optionsWithKey).length) {
17693
+ const foundItem = Object.values(optionsWithKey).find(item => item.label === inputValue);
17694
+ if (!foundItem && selected.length) {
17695
+ setSelected([]);
17696
+ }
17697
+ if (foundItem && !selected.includes(foundItem?.value)) {
17698
+ setSelected([foundItem.value]);
17699
+ }
17700
+ }
17701
+ }, [optionsWithKey, inputValue]);
17702
+ (0,external_react_namespaceObject.useEffect)(() => {
17703
+ processSingleSelected({
17704
+ optionsWithKeyLocal: optionsWithKey,
17705
+ selectedLocal: selected
17706
+ });
17707
+ }, [selected]);
17708
+ (0,external_react_namespaceObject.useEffect)(() => {
17709
+ if (inputValue) {
17710
+ const newFirstSuggestion = Object.values(optionsWithKey)?.find(item => {
17711
+ const label = (0,utils_namespaceObject.propOr)('', 'label')(item);
17712
+ return label.toLowerCase().startsWith(inputValue.toLowerCase());
17713
+ });
17714
+ const firstSuggestionLabel = (0,utils_namespaceObject.propOr)('', 'label')(newFirstSuggestion);
17715
+ const humanSuggestionLabel = inputValue.concat(firstSuggestionLabel.slice(inputValue.length));
17716
+ setFirstSuggestion(humanSuggestionLabel);
17717
+ } else {
17718
+ setFirstSuggestion('');
17719
+ if (isMultiple) {
17720
+ setInputValue('');
17698
17721
  }
17699
17722
  }
17700
- return '';
17701
- }, [inputValue, filteredChildren]);
17702
- const setIsOpen = open => {
17703
- if (!open) {
17704
- form.trigger(name);
17723
+ }, [inputValue, items, selected]);
17724
+ const processSingleSelected = ({
17725
+ optionsWithKeyLocal = {},
17726
+ selectedLocal = []
17727
+ }) => {
17728
+ if (!isMultiple && selectedLocal.length && Object.keys(optionsWithKeyLocal).length) {
17729
+ const currentOption = optionsWithKeyLocal[selectedLocal[0]];
17730
+ const optionText = currentOption && (currentOption.children || currentOption.label || currentOption.value);
17731
+ setInputValue(`${optionText}`);
17705
17732
  }
17706
- _setIsOpen(open);
17707
17733
  };
17708
- const handleChange = ({
17709
- value,
17710
- shouldClose = true,
17711
- resetInput = true
17734
+ const processChildren = ({
17735
+ selectedLocal
17712
17736
  }) => {
17713
- if (isDisabled || value == null) return;
17714
- const alreadySelected = selectedItems.includes(value);
17715
- const updatedSelected = isMultiple ? alreadySelected ? selectedItems.filter(item => item !== value) : [...selectedItems, value] : alreadySelected ? [] : [value];
17716
- const fieldValue = isMultiple ? updatedSelected : updatedSelected[0];
17717
- setSelected(updatedSelected);
17718
- setValue?.(name, fieldValue);
17719
- form.clearErrors(name);
17720
- if (resetInput) {
17721
- const rawInputValue = isMultiple ? null : updatedSelected.length ? String(optionsWithKey[value]?.label) : null;
17722
- setRawInput(rawInputValue);
17737
+ const keyedOptions = {};
17738
+ const childItems = external_react_default().Children.toArray(children).filter(Boolean).map((child, index) => {
17739
+ keyedOptions[child.props.value] = {
17740
+ ...child.props
17741
+ };
17742
+ return /*#__PURE__*/external_react_default().cloneElement(child, {
17743
+ index,
17744
+ ...child.props
17745
+ });
17746
+ });
17747
+ setOptionsWithKey(keyedOptions);
17748
+ setItems(childItems);
17749
+ processSingleSelected({
17750
+ optionsWithKeyLocal: keyedOptions,
17751
+ selectedLocal
17752
+ });
17753
+ setFirstRender(false);
17754
+ };
17755
+ const handleOnEmptyChange = newIsEmptyValue => {
17756
+ if (newIsEmptyValue !== isEmpty) {
17757
+ setIsEmpty(newIsEmptyValue);
17758
+ onEmptyChange?.(newIsEmptyValue);
17723
17759
  }
17724
- if (shouldClose) {
17725
- setIsOpen(false);
17760
+ };
17761
+ const handleOpenChange = open => {
17762
+ if (!isDisabled) {
17763
+ setIsOpen(open);
17726
17764
  }
17727
- onChange?.(value, !alreadySelected);
17728
- onEmptyChange?.(updatedSelected.length === 0);
17729
17765
  };
17730
- const handleClearAll = e => {
17731
- if (isDisabled) return;
17732
- e.preventDefault();
17733
- e.stopPropagation();
17734
- setSelected([]);
17735
- setRawInput(null);
17766
+ const handleChange = changingValue => {
17767
+ if (isDisabled || changingValue === undefined) {
17768
+ return;
17769
+ }
17770
+ const isNewSelected = true;
17771
+ const isChangingItemSelected = selected.includes(changingValue);
17772
+ if (isMultiple) {
17773
+ setSelected(currentSelected => isChangingItemSelected ? currentSelected.filter(current => current !== changingValue) : [...currentSelected, changingValue]);
17774
+ setInputValue('');
17775
+ } else {
17776
+ if (selected[0] === changingValue) {
17777
+ setSelected([]);
17778
+ setInputValue('');
17779
+ } else {
17780
+ setSelected([changingValue]);
17781
+ }
17782
+ }
17736
17783
  setIsOpen(false);
17737
- setValue?.(name, undefined);
17738
- form.trigger(name);
17784
+ setFirstSuggestion('');
17739
17785
  inputRef.current?.focus();
17740
- onClearAll?.();
17741
- onEmptyChange?.(true);
17786
+ setStatus('basic');
17787
+ useFormResult.clearErrors(name);
17788
+ useFormResult.trigger(name);
17789
+ onChange?.(changingValue, isNewSelected);
17742
17790
  };
17743
- const handleInputChange = e => {
17744
- const input = e.target.value;
17745
- setRawInput(input);
17746
- if (!autoSelect || !filterOptions) return;
17747
- const match = findExactMatch(input, optionsWithKey);
17748
- if (match) {
17749
- handleChange({
17750
- value: match.value,
17751
- shouldClose: false
17752
- });
17791
+ const handleClearAll = event => {
17792
+ if (isDisabled) {
17753
17793
  return;
17754
17794
  }
17755
- // unset selected value if not fully matched
17756
- if (!isMultiple && selectedItems.length > 0) {
17757
- handleChange({
17758
- value: selectedItems[0],
17759
- shouldClose: false,
17760
- resetInput: false
17761
- });
17762
- }
17795
+ event.stopPropagation();
17796
+ event.preventDefault();
17797
+ setSelected([]);
17798
+ setInputValue('');
17799
+ setIsOpen(false);
17800
+ setFirstSuggestion('');
17801
+ useFormResult.trigger(name);
17802
+ inputRef.current?.focus();
17803
+ onClearAll?.();
17763
17804
  };
17764
- const handleInputClick = e => {
17765
- e.stopPropagation();
17766
- e.preventDefault();
17805
+ const handleInputClick = event => {
17767
17806
  if (!isDisabled) {
17768
17807
  inputRef.current?.focus();
17769
17808
  setIsOpen(true);
17770
17809
  }
17810
+ event.stopPropagation();
17811
+ event.preventDefault();
17771
17812
  };
17772
- const handleInputKeyDown = e => {
17773
- const isEnterOrTab = ['Enter', 'Tab'].includes(e.code);
17774
- if (isEnterOrTab && firstSuggestion && firstSuggestion !== inputValue) {
17775
- const match = findExactMatch(firstSuggestion, optionsWithKey);
17776
- if (match) {
17777
- handleChange({
17778
- value: match.value
17779
- });
17813
+ const handleInputKeyDown = event => {
17814
+ if (['Space'].includes(event.code) && !firstSuggestion) {
17815
+ setIsOpen(true);
17816
+ inputRef.current?.focus();
17817
+ event.stopPropagation();
17818
+ event.preventDefault();
17819
+ } else if (['Tab', 'Enter'].includes(event.code) && firstSuggestion && firstSuggestion !== inputValue) {
17820
+ const foundItem = Object.values(optionsWithKey).find(item => `${item.label}`.toLowerCase() === firstSuggestion.toLowerCase());
17821
+ handleChange(foundItem?.value);
17822
+ if (foundItem) {
17823
+ setInputValue(`${foundItem?.label}`);
17780
17824
  }
17781
- e.preventDefault();
17782
- return;
17783
- }
17784
- if (isMultiple && e.code === 'Backspace' && selectedItems.length && !inputValue) {
17785
- const lastSelected = selectedItems[selectedItems.length - 1];
17786
- handleChange({
17787
- value: lastSelected,
17788
- shouldClose: false
17789
- });
17790
- e.preventDefault();
17791
- return;
17792
- }
17793
- if (!isOpen && firstSuggestion !== inputValue) {
17825
+ event.preventDefault();
17826
+ return false;
17827
+ } else if (isMultiple && event.code === 'Backspace' && selected.length > 0 && !firstSuggestion) {
17828
+ handleChange(selected[selected.length - 1]);
17829
+ event.preventDefault();
17830
+ return false;
17831
+ } else if (!isOpen && firstSuggestion !== inputValue) {
17794
17832
  setIsOpen(true);
17795
17833
  }
17796
17834
  };
17797
- const handleRemoveSelectedClick = value => e => {
17798
- e.stopPropagation();
17799
- handleChange({
17800
- value
17801
- });
17802
- onRemoveSelectedClick?.(value);
17803
- form.trigger(name);
17835
+ const handleInputChange = event => {
17836
+ setInputValue(event.target.value);
17804
17837
  };
17805
- const handleOpenChange = (open, event, reason) => {
17806
- if (isDisabled || reason === 'reference-press') {
17807
- return;
17808
- }
17809
- setIsOpen(open);
17810
- if (!isMultiple && selectedItems.length > 0) {
17811
- const selectedValue = selectedItems[0];
17812
- const label = optionsWithKey[selectedValue]?.label;
17813
- setRawInput(label ? String(label) : null);
17814
- return;
17815
- }
17816
- setRawInput(null);
17838
+ const handleSelectedClick = event => {
17839
+ event.stopPropagation();
17840
+ };
17841
+ const handleRemoveSelectedClick = selectedItem => event => {
17842
+ event.stopPropagation();
17843
+ handleChange(selectedItem);
17844
+ onRemoveSelectedClick?.(selectedItem);
17817
17845
  };
17818
- const status = (() => {
17819
- if (form.formState.errors[name]) return 'error';
17820
- if (error) return 'error';
17821
- if (success) return 'success';
17822
- return 'basic';
17823
- })();
17824
17846
  return {
17825
17847
  isOpen,
17826
17848
  isDisabled,
17827
17849
  optionsWithKey,
17828
- selectedItems,
17850
+ selectedItems: selected,
17829
17851
  inputRef,
17830
17852
  firstSuggestion,
17831
17853
  isMultiple,
@@ -17841,18 +17863,18 @@ const useTypeahead = ({
17841
17863
  inputValue,
17842
17864
  validationSchema,
17843
17865
  status,
17844
- error: error ?? form.formState.errors[name],
17845
17866
  placeholder,
17846
17867
  options: items,
17847
- useFormResult: form,
17868
+ useFormResult,
17848
17869
  register,
17849
17870
  setValue,
17850
- onChange,
17871
+ handleChange,
17851
17872
  handleClearAll,
17852
17873
  handleOpenChange,
17853
17874
  handleInputChange,
17854
17875
  handleInputClick,
17855
17876
  handleInputKeyDown,
17877
+ handleSelectedClick,
17856
17878
  handleRemoveSelectedClick
17857
17879
  };
17858
17880
  };
@@ -17966,7 +17988,7 @@ const MultipleTrigger = () => {
17966
17988
  const theme = (0,react_namespaceObject.useTheme)();
17967
17989
  const context = useTypeaheadContext();
17968
17990
  const typeaheadInputAdditionalProps = {};
17969
- if (!context.selectedItems.length && !context.inputValue && !!context.placeholder) {
17991
+ if (!context.selectedItems.length && !!context.placeholder) {
17970
17992
  typeaheadInputAdditionalProps.placeholder = context.placeholder;
17971
17993
  }
17972
17994
  return (0,jsx_runtime_namespaceObject.jsxs)((external_react_default()).Fragment, {
@@ -17974,7 +17996,7 @@ const MultipleTrigger = () => {
17974
17996
  const currentOption = context.optionsWithKey[selectedItem];
17975
17997
  const optionText = currentOption ? currentOption.children || currentOption.label || currentOption.value : '';
17976
17998
  return (0,jsx_runtime_namespaceObject.jsxs)(TypeaheadItem, {
17977
- onClick: e => e.stopPropagation(),
17999
+ onClick: context.handleSelectedClick,
17978
18000
  isDisabled: context.isDisabled,
17979
18001
  children: [(0,jsx_runtime_namespaceObject.jsx)(TypeaheadItemLabel, {
17980
18002
  isDisabled: context.isDisabled,
@@ -18018,6 +18040,11 @@ const MultipleTrigger = () => {
18018
18040
  disabled: context.isDisabled,
18019
18041
  className: ['typeahead-input', TypeaheadInput(theme), TypeaheadInputPlaceholder].join(' '),
18020
18042
  ...typeaheadInputAdditionalProps
18043
+ }), (0,jsx_runtime_namespaceObject.jsx)("input", {
18044
+ type: "hidden",
18045
+ readOnly: true,
18046
+ value: context.selectedItems,
18047
+ ...context.register?.(context.name, context.validationSchema)
18021
18048
  })]
18022
18049
  }), !context.isDisabled && context.selectedItems.length ? (0,jsx_runtime_namespaceObject.jsx)(Button_Button, {
18023
18050
  variant: "tertiary",
@@ -18044,7 +18071,7 @@ const SingleTrigger = () => {
18044
18071
  const context = useTypeaheadContext();
18045
18072
  const theme = (0,react_namespaceObject.useTheme)();
18046
18073
  const typeaheadInputAdditionalProps = {};
18047
- if (!context.selectedItems.length && !context.inputValue && !!context.placeholder) {
18074
+ if (!context.selectedItems.length && !!context.placeholder) {
18048
18075
  typeaheadInputAdditionalProps.placeholder = context.placeholder;
18049
18076
  }
18050
18077
  return (0,jsx_runtime_namespaceObject.jsxs)(TypeaheadInputsGroupWrapper, {
@@ -18073,6 +18100,11 @@ const SingleTrigger = () => {
18073
18100
  tabIndex: -1,
18074
18101
  className: ['typeahead-input', TypeaheadInput(theme), TypeaheadInputPlaceholder].join(' '),
18075
18102
  ...typeaheadInputAdditionalProps
18103
+ }), (0,jsx_runtime_namespaceObject.jsx)("input", {
18104
+ type: "hidden",
18105
+ readOnly: true,
18106
+ value: context.selectedItems[0] || '',
18107
+ ...context.register?.(context.name, context.validationSchema)
18076
18108
  }), !context.isDisabled && context.selectedItems.length ? (0,jsx_runtime_namespaceObject.jsx)(Button_Button, {
18077
18109
  variant: "tertiary",
18078
18110
  "data-testid": "remove-all-button",
@@ -18179,7 +18211,6 @@ const Typeahead = ({
18179
18211
  name = 'typeahead-search',
18180
18212
  label,
18181
18213
  selectedItems,
18182
- defaultSelectedItems,
18183
18214
  isOpen,
18184
18215
  isDisabled,
18185
18216
  isMultiple,
@@ -18197,6 +18228,8 @@ const Typeahead = ({
18197
18228
  optionsClassName,
18198
18229
  wrapperClassName,
18199
18230
  width = 300,
18231
+ setValue,
18232
+ register,
18200
18233
  onChange,
18201
18234
  onEmptyChange,
18202
18235
  onClearAll,
@@ -18207,7 +18240,6 @@ const Typeahead = ({
18207
18240
  const hookResult = useTypeahead({
18208
18241
  name,
18209
18242
  selectedItems,
18210
- defaultSelectedItems,
18211
18243
  isOpen,
18212
18244
  isDisabled,
18213
18245
  isMultiple,
@@ -18221,6 +18253,8 @@ const Typeahead = ({
18221
18253
  success,
18222
18254
  validationSchema,
18223
18255
  placeholder,
18256
+ setValue,
18257
+ register,
18224
18258
  onChange,
18225
18259
  onEmptyChange,
18226
18260
  renderOption,
@@ -18268,7 +18302,7 @@ const Typeahead = ({
18268
18302
  status: hookResult.status,
18269
18303
  disabled: isDisabled,
18270
18304
  "data-testid": "helper-text",
18271
- children: hookResult.error ? hookResult.error?.message?.toString() : helperText
18305
+ children: error ? error?.message : helperText
18272
18306
  })]
18273
18307
  })
18274
18308
  });
@@ -19146,7 +19180,6 @@ const SelectWidget = props => {
19146
19180
  placeholder,
19147
19181
  onChange,
19148
19182
  onBlur,
19149
- onFocus,
19150
19183
  onChangeOverride,
19151
19184
  value
19152
19185
  } = props;
@@ -19161,44 +19194,43 @@ const SelectWidget = props => {
19161
19194
  const handleBlur = ({
19162
19195
  target
19163
19196
  }) => onBlur(id, target && target.value);
19164
- const handleFocus = ({
19165
- target
19166
- }) => onFocus(id, target && target.value);
19167
19197
  const onEmptyChange = isEmpty => {
19168
19198
  if (isEmpty) {
19169
19199
  handleChange();
19170
19200
  }
19171
19201
  };
19202
+ const register = fieldName => ({
19203
+ onBlur: handleBlur,
19204
+ onChange: handleChange,
19205
+ name: fieldName,
19206
+ ref: () => {}
19207
+ });
19172
19208
  const items = Array.isArray(enumOptions) ? enumOptions : [];
19173
19209
  const selectedItems = selectedIndex ? [items[Number(selectedIndex)].value] : [];
19174
- return (0,jsx_runtime_namespaceObject.jsx)("div", {
19175
- id: id,
19176
- onBlur: handleBlur,
19177
- onFocus: handleFocus,
19178
- children: (0,jsx_runtime_namespaceObject.jsx)(Typeahead, {
19179
- width: "100%",
19180
- selectedItems: selectedItems,
19181
- isDisabled: disabled,
19182
- name: name
19183
- // RJSF provides placeholder as empty string
19184
- ,
19185
- placeholder: placeholder || undefined,
19186
- onChange: handleChange,
19187
- onEmptyChange: onEmptyChange,
19188
- renderOption: ({
19189
- label,
19190
- input
19191
- }) => highlightInputMatch(label, input),
19192
- children: items.map(({
19193
- label,
19194
- value
19195
- }) => (0,jsx_runtime_namespaceObject.jsx)(TypeaheadOption_TypeaheadOption, {
19196
- value: value,
19197
- label: label || value,
19198
- isDisabled: disabled || Array.isArray(enumDisabled) && enumDisabled.includes(value),
19199
- children: label || value
19200
- }, value))
19201
- })
19210
+ return (0,jsx_runtime_namespaceObject.jsx)(Typeahead, {
19211
+ width: "100%",
19212
+ selectedItems: selectedItems,
19213
+ isDisabled: disabled,
19214
+ name: name
19215
+ // RJSF provides placeholder as empty string
19216
+ ,
19217
+ placeholder: placeholder || undefined,
19218
+ onChange: handleChange,
19219
+ register: register,
19220
+ onEmptyChange: onEmptyChange,
19221
+ renderOption: ({
19222
+ label,
19223
+ input
19224
+ }) => highlightInputMatch(label, input),
19225
+ children: items.map(({
19226
+ label,
19227
+ value
19228
+ }) => (0,jsx_runtime_namespaceObject.jsx)(TypeaheadOption_TypeaheadOption, {
19229
+ value: value,
19230
+ label: label || value,
19231
+ isDisabled: disabled || Array.isArray(enumDisabled) && enumDisabled.includes(value),
19232
+ children: label || value
19233
+ }, value))
19202
19234
  });
19203
19235
  };
19204
19236
  ;// ./src/components/JsonSchemaForm/widgets/PasswordWidget.tsx