@ssa-ui-kit/core 2.13.1 → 2.15.0-canary-3fd3271-20250501

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
@@ -520,6 +520,14 @@ __webpack_require__.d(Employee_namespaceObject, {
520
520
  ICON_NAME: () => (Employee_ICON_NAME)
521
521
  });
522
522
 
523
+ // NAMESPACE OBJECT: ./src/components/Icon/icons/ExcelDownload.tsx
524
+ var ExcelDownload_namespaceObject = {};
525
+ __webpack_require__.r(ExcelDownload_namespaceObject);
526
+ __webpack_require__.d(ExcelDownload_namespaceObject, {
527
+ ExcelDownload: () => (ExcelDownload),
528
+ ICON_NAME: () => (ExcelDownload_ICON_NAME)
529
+ });
530
+
523
531
  // NAMESPACE OBJECT: ./src/components/Icon/icons/Expertise.tsx
524
532
  var Expertise_namespaceObject = {};
525
533
  __webpack_require__.r(Expertise_namespaceObject);
@@ -536,6 +544,14 @@ __webpack_require__.d(Filter_namespaceObject, {
536
544
  ICON_NAME: () => (Filter_ICON_NAME)
537
545
  });
538
546
 
547
+ // NAMESPACE OBJECT: ./src/components/Icon/icons/FilterFunnel.tsx
548
+ var FilterFunnel_namespaceObject = {};
549
+ __webpack_require__.r(FilterFunnel_namespaceObject);
550
+ __webpack_require__.d(FilterFunnel_namespaceObject, {
551
+ FilterFunnel: () => (FilterFunnel),
552
+ ICON_NAME: () => (FilterFunnel_ICON_NAME)
553
+ });
554
+
539
555
  // NAMESPACE OBJECT: ./src/components/Icon/icons/Geography.tsx
540
556
  var Geography_namespaceObject = {};
541
557
  __webpack_require__.r(Geography_namespaceObject);
@@ -873,8 +889,10 @@ __webpack_require__.d(all_namespaceObject, {
873
889
  Edit: () => (Edit_namespaceObject),
874
890
  Email: () => (Email_namespaceObject),
875
891
  Employee: () => (Employee_namespaceObject),
892
+ ExcelDownload: () => (ExcelDownload_namespaceObject),
876
893
  Expertise: () => (Expertise_namespaceObject),
877
894
  Filter: () => (Filter_namespaceObject),
895
+ FilterFunnel: () => (FilterFunnel_namespaceObject),
878
896
  Geography: () => (Geography_namespaceObject),
879
897
  Home: () => (Home_namespaceObject),
880
898
  Import: () => (Import_namespaceObject),
@@ -2596,6 +2614,36 @@ const Employee = ({
2596
2614
  })]
2597
2615
  });
2598
2616
  const Employee_ICON_NAME = 'employee';
2617
+ ;// ./src/components/Icon/icons/ExcelDownload.tsx
2618
+
2619
+ const ExcelDownload = ({
2620
+ fill = '#000',
2621
+ size = 24,
2622
+ tooltip = 'Excel download',
2623
+ ...props
2624
+ }) => (0,jsx_runtime_namespaceObject.jsxs)("svg", {
2625
+ xmlns: "http://www.w3.org/2000/svg",
2626
+ width: `${size}px`,
2627
+ height: `${size}px`,
2628
+ viewBox: "0 0 24 24",
2629
+ fill: "none",
2630
+ ...props,
2631
+ children: [(0,jsx_runtime_namespaceObject.jsx)("title", {
2632
+ children: tooltip
2633
+ }), (0,jsx_runtime_namespaceObject.jsx)("path", {
2634
+ fillRule: "evenodd",
2635
+ clipRule: "evenodd",
2636
+ d: "M6.04815 2C4.81157 2 3.7998 3.01813 3.7998 4.2625V17.7375C3.7998 18.9819 4.81157 20 6.04815 20H14.0058C13.6986 19.7203 13.5334 19.34 13.5176 18.9524H6.04815C5.37634 18.9524 4.84083 18.4135 4.84083 17.7375V4.2625C4.84083 3.58646 5.37634 3.04757 6.04815 3.04757H11.986C11.9879 3.04857 11.9915 3.05051 11.9972 3.05405L11.9999 3.05572L12.007 3.06013V6.00121C12.007 6.47167 12.1866 6.90245 12.4801 7.22748C12.8131 7.59634 13.2929 7.82903 13.8234 7.82903H16.7549L16.7586 9.39603V11.686C17.008 11.3746 17.3791 11.1648 17.7997 11.1287L17.7998 7.32704L17.7976 7.29664C17.7953 7.26342 17.792 7.21583 17.7895 7.20309C17.7694 7.1015 17.7199 7.00816 17.6471 6.9349L13.2753 2.53554C12.9348 2.19237 12.4726 2 11.991 2H6.04815ZM3.7998 4.2625L3.88836 4.29517V4.29274L3.7998 4.2625ZM13.048 6.00121V3.78825L16.0225 6.78145H13.8234C13.39 6.78145 13.048 6.43738 13.048 6.00121Z",
2637
+ fill: fill
2638
+ }), (0,jsx_runtime_namespaceObject.jsx)("path", {
2639
+ d: "M9.86867 12.4996L7.97338 9H9.74921L10.6803 11.0954C10.7534 11.2606 10.8189 11.4641 10.8757 11.6923H10.8862C10.9229 11.5562 10.9932 11.3425 11.0921 11.0718L12.121 9H13.7457L11.8068 12.4647L13.7998 16H12.0774L10.9516 13.717C10.9099 13.6323 10.8662 13.4775 10.8216 13.2492H10.8103C10.7888 13.3558 10.7377 13.5224 10.6593 13.7406L9.53276 15.9992H7.7998L9.86867 12.4996Z",
2640
+ fill: fill
2641
+ }), (0,jsx_runtime_namespaceObject.jsx)("path", {
2642
+ d: "M17.9128 11.9231C18.2994 11.9231 18.6128 12.2365 18.6128 12.6231V19.8599L20.372 18.359C20.6661 18.108 21.1079 18.143 21.3589 18.4371C21.6098 18.7312 21.5748 19.1731 21.2807 19.424L18.3677 21.9094C18.2212 22.0344 18.036 22.0895 17.8553 22.0745C17.6994 22.0618 17.5579 21.998 17.4476 21.8999L14.5003 19.4278C14.2041 19.1794 14.1654 18.7378 14.4138 18.4416C14.6623 18.1454 15.1038 18.1067 15.4 18.3552L17.2128 19.8757V12.6231C17.2128 12.2365 17.5262 11.9231 17.9128 11.9231Z",
2643
+ fill: fill
2644
+ })]
2645
+ });
2646
+ const ExcelDownload_ICON_NAME = 'excel-download';
2599
2647
  ;// ./src/components/Icon/icons/Expertise.tsx
2600
2648
 
2601
2649
  const Expertise = ({
@@ -2647,6 +2695,33 @@ const Filter = ({
2647
2695
  })]
2648
2696
  });
2649
2697
  const Filter_ICON_NAME = 'filter';
2698
+ ;// ./src/components/Icon/icons/FilterFunnel.tsx
2699
+
2700
+ const FilterFunnel = ({
2701
+ fill = '#000',
2702
+ size = 24,
2703
+ tooltip = 'Filter funnel',
2704
+ ...props
2705
+ }) => (0,jsx_runtime_namespaceObject.jsxs)("svg", {
2706
+ xmlns: "http://www.w3.org/2000/svg",
2707
+ width: `${size}px`,
2708
+ height: `${size}px`,
2709
+ viewBox: "0 0 20 20",
2710
+ fill: "none",
2711
+ ...props,
2712
+ children: [(0,jsx_runtime_namespaceObject.jsx)("title", {
2713
+ children: tooltip
2714
+ }), (0,jsx_runtime_namespaceObject.jsx)("path", {
2715
+ d: "M2.73438 2.5C2.605 2.5 2.5 2.605 2.5 2.73438V4.60938C2.5 4.66281 2.51846 4.71461 2.55127 4.75586L8.125 11.723V15.9116C8.125 16.0067 8.182 16.0915 8.26965 16.1276L11.5509 17.4826C11.58 17.4943 11.6106 17.5 11.6406 17.5C11.6866 17.5 11.7313 17.4864 11.7706 17.4606C11.8358 17.417 11.875 17.3439 11.875 17.2656V11.723L17.4487 4.75586C17.4815 4.71461 17.5 4.66281 17.5 4.60938V2.73438C17.5 2.605 17.395 2.5 17.2656 2.5H2.73438ZM2.96875 2.96875H17.0312V4.52698L11.528 11.4062H8.47198L2.96875 4.52698V2.96875ZM8.59375 11.875H11.4062V16.9159L8.59375 15.755V11.875Z",
2716
+ fill: fill
2717
+ }), (0,jsx_runtime_namespaceObject.jsx)("path", {
2718
+ fillRule: "evenodd",
2719
+ clipRule: "evenodd",
2720
+ d: "M2.73438 2.25C2.46693 2.25 2.25 2.46693 2.25 2.73438V4.60938C2.25 4.7201 2.28853 4.82714 2.35605 4.91203L7.875 11.8107V15.6701C7.875 15.6701 7.86214 16.0606 7.91666 16.1667C7.98574 16.3011 8.17447 16.3588 8.17447 16.3588L11.4555 17.7137L11.4574 17.7145C11.5169 17.7385 11.5794 17.75 11.6406 17.75C11.7368 17.75 11.8288 17.7214 11.9076 17.6698L11.9096 17.6684C12.0438 17.5786 12.125 17.4277 12.125 17.2656V11.8107L17.6444 4.91149C17.7119 4.8266 17.75 4.7201 17.75 4.60938V2.73438C17.75 2.46693 17.5331 2.25 17.2656 2.25H2.73438ZM16.7812 3.21875H3.21875V4.43928L8.59214 11.1562H11.4079L16.7812 4.43928V3.21875ZM8.84375 12.125V15.5877L11.1562 16.5422V12.125H8.84375Z",
2721
+ fill: fill
2722
+ })]
2723
+ });
2724
+ const FilterFunnel_ICON_NAME = 'filter-funnel';
2650
2725
  ;// ./src/components/Icon/icons/Geography.tsx
2651
2726
 
2652
2727
  const Geography = ({
@@ -3934,6 +4009,10 @@ const Warning_ICON_NAME = 'warning';
3934
4009
 
3935
4010
 
3936
4011
 
4012
+
4013
+
4014
+
4015
+
3937
4016
 
3938
4017
 
3939
4018
 
@@ -7839,12 +7918,14 @@ const TooltipContent = /*#__PURE__*/(0,external_react_namespaceObject.forwardRef
7839
7918
 
7840
7919
 
7841
7920
  const TooltipTrigger = ({
7842
- children
7921
+ children,
7922
+ className
7843
7923
  }) => {
7844
7924
  const tooltipCtx = useTooltipContext();
7845
7925
  if (/*#__PURE__*/(0,external_react_namespaceObject.isValidElement)(children)) {
7846
7926
  return /*#__PURE__*/(0,external_react_namespaceObject.cloneElement)(children, tooltipCtx?.getReferenceProps({
7847
- ref: tooltipCtx.refs.setReference
7927
+ ref: tooltipCtx.refs.setReference,
7928
+ className: [children.props?.className, className].filter(Boolean).join(' ')
7848
7929
  }));
7849
7930
  }
7850
7931
  return null;
@@ -17433,6 +17514,7 @@ const TypeaheadContext = /*#__PURE__*/external_react_namespaceObject.createConte
17433
17514
  options: [],
17434
17515
  placeholder: '',
17435
17516
  useFormResult: {},
17517
+ error: undefined,
17436
17518
  setValue: () => {
17437
17519
  /* no-op */
17438
17520
  },
@@ -17440,7 +17522,7 @@ const TypeaheadContext = /*#__PURE__*/external_react_namespaceObject.createConte
17440
17522
  /* eslint-disable-next-line @typescript-eslint/no-explicit-any */
17441
17523
  return {};
17442
17524
  },
17443
- handleChange: () => {
17525
+ onChange: () => {
17444
17526
  /* no-op */
17445
17527
  },
17446
17528
  handleClearAll: () => {
@@ -17460,9 +17542,6 @@ const TypeaheadContext = /*#__PURE__*/external_react_namespaceObject.createConte
17460
17542
  },
17461
17543
  handleRemoveSelectedClick: () => () => {
17462
17544
  /* no-op */
17463
- },
17464
- handleSelectedClick: () => {
17465
- /* no-op */
17466
17545
  }
17467
17546
  });
17468
17547
  const useTypeaheadContext = () => external_react_namespaceObject.useContext(TypeaheadContext);
@@ -17470,10 +17549,18 @@ const useTypeaheadContext = () => external_react_namespaceObject.useContext(Type
17470
17549
 
17471
17550
 
17472
17551
 
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
+ };
17473
17559
  const useTypeahead = ({
17474
17560
  name = 'typeahead-input',
17475
17561
  isOpen: isInitOpen,
17476
17562
  selectedItems,
17563
+ defaultSelectedItems,
17477
17564
  isDisabled,
17478
17565
  isMultiple,
17479
17566
  children,
@@ -17486,8 +17573,8 @@ const useTypeahead = ({
17486
17573
  error,
17487
17574
  success,
17488
17575
  placeholder,
17489
- register,
17490
- setValue,
17576
+ filterOptions = true,
17577
+ autoSelect = true,
17491
17578
  onChange,
17492
17579
  onClearAll,
17493
17580
  onRemoveSelectedClick,
@@ -17495,266 +17582,240 @@ const useTypeahead = ({
17495
17582
  renderOption
17496
17583
  }) => {
17497
17584
  const inputName = `${name}-text`;
17498
- const [isOpen, setIsOpen] = (0,external_react_namespaceObject.useState)(isInitOpen || false);
17499
- const [selected, setSelected] = (0,external_react_namespaceObject.useState)(selectedItems || []);
17500
- const [optionsWithKey, setOptionsWithKey] = (0,external_react_namespaceObject.useState)({});
17501
- const [isEmpty, setIsEmpty] = (0,external_react_namespaceObject.useState)(true);
17502
- const [isFirstRender, setFirstRender] = (0,external_react_namespaceObject.useState)(true);
17503
- const [items, setItems] = (0,external_react_namespaceObject.useState)();
17504
- const [inputValue, setInputValue] = (0,external_react_namespaceObject.useState)('');
17505
- const [status, setStatus] = (0,external_react_namespaceObject.useState)('basic');
17506
- const [firstSuggestion, setFirstSuggestion] = (0,external_react_namespaceObject.useState)('');
17507
- const inputRef = (0,external_react_namespaceObject.useRef)(null);
17508
- const typeaheadId = (0,external_react_namespaceObject.useId)();
17585
+ const [isOpen, _setIsOpen] = (0,hooks_namespaceObject.useUncontrolled)({
17586
+ defaultValue: isInitOpen,
17587
+ finalValue: false
17588
+ });
17589
+ const [selected, setSelected] = (0,hooks_namespaceObject.useUncontrolled)({
17590
+ value: selectedItems,
17591
+ defaultValue: defaultSelectedItems,
17592
+ finalValue: []
17593
+ });
17594
+ const [rawInput, setRawInput] = (0,external_react_namespaceObject.useState)(null);
17595
+ const {
17596
+ ref: inputRef
17597
+ } = (0,hooks_namespaceObject.useElementSize)();
17509
17598
  const triggerRef = (0,external_react_namespaceObject.useRef)(null);
17510
- const useFormResult = (0,external_react_hook_form_namespaceObject.useForm)();
17599
+ const defaultForm = (0,external_react_hook_form_namespaceObject.useForm)();
17600
+ const form = (0,external_react_hook_form_namespaceObject.useFormContext)() ?? defaultForm;
17601
+ const {
17602
+ register,
17603
+ setValue
17604
+ } = form;
17511
17605
  (0,external_react_namespaceObject.useEffect)(() => {
17512
- if (!register) {
17513
- console.warn('Typeahead component must be used within a Form component');
17606
+ if (!selected.length) {
17607
+ return;
17514
17608
  }
17515
- }, []);
17516
- (0,external_react_namespaceObject.useEffect)(() => {
17517
17609
  if (isMultiple) {
17518
17610
  setValue?.(name, selected, {
17519
- shouldDirty: !isFirstRender
17611
+ shouldDirty: false
17520
17612
  });
17521
- setInputValue('');
17522
- setFirstSuggestion('');
17523
17613
  } else {
17524
- setValue?.(name, selected.length ? selected[0] : [], {
17525
- shouldDirty: !isFirstRender
17614
+ setValue?.(name, selected[0], {
17615
+ shouldDirty: false
17526
17616
  });
17527
17617
  }
17528
- handleOnEmptyChange(!selected.length);
17529
- }, [selected]);
17530
- (0,external_react_namespaceObject.useEffect)(() => {
17531
- if (isDisabled && isOpen) {
17532
- setIsOpen(false);
17533
- }
17534
- }, [isDisabled]);
17535
- (0,external_react_namespaceObject.useEffect)(() => {
17536
- const status = success ? 'success' : useFormResult.formState.errors[name] ? 'error' : 'basic';
17537
- setStatus(status);
17538
- }, [useFormResult.formState.errors[name], success]);
17539
- (0,external_react_namespaceObject.useEffect)(() => {
17540
- if (error) {
17541
- useFormResult.setError(name, error);
17542
- } else {
17543
- setStatus('basic');
17544
- useFormResult.resetField(name);
17545
- }
17546
- }, [error]);
17547
- (0,external_react_namespaceObject.useEffect)(() => {
17548
- processChildren({
17549
- selectedLocal: selected
17618
+ }, []);
17619
+ const typeaheadId = (0,external_react_namespaceObject.useId)();
17620
+ const optionsWithKey = (0,external_react_namespaceObject.useMemo)(() => {
17621
+ const opts = {};
17622
+ external_react_default().Children.forEach(children, child => {
17623
+ if (/*#__PURE__*/external_react_default().isValidElement(child)) {
17624
+ opts[child.props.value] = child.props;
17625
+ }
17550
17626
  });
17627
+ return opts;
17551
17628
  }, [children]);
17552
- (0,external_react_namespaceObject.useEffect)(() => {
17553
- setSelected(selectedItems || []);
17554
- if (selectedItems?.length) {
17555
- if (!isMultiple) {
17556
- const currentOption = optionsWithKey[selectedItems[0]];
17557
- const optionText = currentOption && (currentOption.children || currentOption.label || currentOption.value);
17558
- setInputValue(`${optionText}`);
17559
- }
17560
- } else {
17561
- setInputValue('');
17562
- setFirstSuggestion('');
17563
- }
17564
- processChildren({
17565
- selectedLocal: selectedItems || []
17629
+ const inputValue = (0,external_react_namespaceObject.useMemo)(() => {
17630
+ if (isMultiple) return rawInput ?? '';
17631
+ if (rawInput != null) return rawInput;
17632
+ return selected.length === 1 ? optionsWithKey[selected[0]]?.label?.toString() || '' : '';
17633
+ }, [isMultiple, rawInput, selected, optionsWithKey]);
17634
+ const filteredChildren = (0,external_react_namespaceObject.useMemo)(() => {
17635
+ // if filtering is disabled, or there's no input, show all
17636
+ if (!filterOptions || !inputValue) return external_react_default().Children.toArray(children);
17637
+ const needle = inputValue.toLowerCase();
17638
+ return external_react_default().Children.toArray(children).filter(child => {
17639
+ if (! /*#__PURE__*/external_react_default().isValidElement(child)) return false;
17640
+ const {
17641
+ label,
17642
+ value
17643
+ } = child.props;
17644
+ const text = (label ?? value)?.toString().toLowerCase() || '';
17645
+ return text.includes(needle);
17566
17646
  });
17567
- }, [selectedItems]);
17568
- (0,external_react_namespaceObject.useEffect)(() => {
17569
- const childrenArray = external_react_default().Children.toArray(children).filter(Boolean);
17570
- const filteredOptions = [...childrenArray];
17571
- const childItems = filteredOptions.map((child, index) => {
17647
+ }, [children, inputValue]);
17648
+ const items = (0,external_react_namespaceObject.useMemo)(() => {
17649
+ return filteredChildren.map((child, index) => {
17650
+ if (! /*#__PURE__*/external_react_default().isValidElement(child)) return null;
17651
+ const isActive = selected.includes(child.props.value);
17572
17652
  const {
17573
- id,
17574
17653
  value,
17575
17654
  label,
17655
+ id,
17576
17656
  isDisabled
17577
17657
  } = child.props;
17578
- const isActive = selected.includes(child.props.value);
17579
17658
  return /*#__PURE__*/external_react_default().cloneElement(child, {
17580
- index,
17581
17659
  ...child.props,
17660
+ index,
17582
17661
  isActive,
17583
17662
  isDisabled,
17584
- id,
17663
+ role: 'option',
17585
17664
  'aria-selected': isActive,
17586
17665
  'aria-labelledby': `typeahead-label-${name}`,
17587
- role: 'option',
17588
- onClick: event => {
17589
- event.preventDefault();
17666
+ onClick: e => {
17667
+ e.preventDefault();
17590
17668
  if (!isDisabled) {
17591
- handleChange(child.props.value);
17669
+ const shouldClose = !isMultiple;
17670
+ handleChange({
17671
+ value,
17672
+ shouldClose
17673
+ });
17592
17674
  }
17593
17675
  },
17594
- children: renderOption ? renderOption({
17676
+ children: renderOption?.({
17595
17677
  value: id || value,
17596
- input: inputValue || '',
17678
+ input: inputValue,
17597
17679
  label
17598
- }) : child.props.children || child.props.label || child.props.value
17680
+ }) ?? child.props.children ?? label ?? value
17599
17681
  });
17600
17682
  });
17601
- setItems(childItems);
17602
- }, [inputValue, optionsWithKey, selected]);
17603
- (0,external_react_namespaceObject.useEffect)(() => {
17604
- if (!isMultiple && Object.keys(optionsWithKey).length) {
17605
- const foundItem = Object.values(optionsWithKey).find(item => item.label === inputValue);
17606
- if (!foundItem && selected.length) {
17607
- setSelected([]);
17608
- }
17609
- if (foundItem && !selected.includes(foundItem?.value)) {
17610
- setSelected([foundItem.value]);
17611
- }
17612
- }
17613
- }, [optionsWithKey, inputValue]);
17614
- (0,external_react_namespaceObject.useEffect)(() => {
17615
- processSingleSelected({
17616
- optionsWithKeyLocal: optionsWithKey,
17617
- selectedLocal: selected
17618
- });
17619
- }, [selected]);
17620
- (0,external_react_namespaceObject.useEffect)(() => {
17621
- if (inputValue) {
17622
- const newFirstSuggestion = Object.values(optionsWithKey)?.find(item => {
17623
- const label = (0,utils_namespaceObject.propOr)('', 'label')(item);
17624
- return label.toLowerCase().startsWith(inputValue.toLowerCase());
17625
- });
17626
- const firstSuggestionLabel = (0,utils_namespaceObject.propOr)('', 'label')(newFirstSuggestion);
17627
- const humanSuggestionLabel = inputValue.concat(firstSuggestionLabel.slice(inputValue.length));
17628
- setFirstSuggestion(humanSuggestionLabel);
17629
- } else {
17630
- setFirstSuggestion('');
17631
- if (isMultiple) {
17632
- setInputValue('');
17683
+ }, [children, selected, inputValue]);
17684
+ const firstSuggestion = (0,external_react_namespaceObject.useMemo)(() => {
17685
+ if (!inputValue) return '';
17686
+ const needle = inputValue.toLowerCase();
17687
+ for (const child of filteredChildren) {
17688
+ if (! /*#__PURE__*/external_react_default().isValidElement(child)) continue;
17689
+ const labelText = (child.props.label ?? child.props.value).toString();
17690
+ if (labelText.toLowerCase().startsWith(needle)) {
17691
+ return inputValue + labelText.slice(inputValue.length);
17633
17692
  }
17634
17693
  }
17635
- }, [inputValue, items, selected]);
17636
- const processSingleSelected = ({
17637
- optionsWithKeyLocal = {},
17638
- selectedLocal = []
17639
- }) => {
17640
- if (!isMultiple && selectedLocal.length && Object.keys(optionsWithKeyLocal).length) {
17641
- const currentOption = optionsWithKeyLocal[selectedLocal[0]];
17642
- const optionText = currentOption && (currentOption.children || currentOption.label || currentOption.value);
17643
- setInputValue(`${optionText}`);
17694
+ return '';
17695
+ }, [inputValue, filteredChildren]);
17696
+ const setIsOpen = open => {
17697
+ if (!open) {
17698
+ form.trigger();
17644
17699
  }
17700
+ _setIsOpen(open);
17645
17701
  };
17646
- const processChildren = ({
17647
- selectedLocal
17702
+ const handleChange = ({
17703
+ value,
17704
+ shouldClose = true,
17705
+ resetInput = true
17648
17706
  }) => {
17649
- const keyedOptions = {};
17650
- const childItems = external_react_default().Children.toArray(children).filter(Boolean).map((child, index) => {
17651
- keyedOptions[child.props.value] = {
17652
- ...child.props
17653
- };
17654
- return /*#__PURE__*/external_react_default().cloneElement(child, {
17655
- index,
17656
- ...child.props
17657
- });
17658
- });
17659
- setOptionsWithKey(keyedOptions);
17660
- setItems(childItems);
17661
- processSingleSelected({
17662
- optionsWithKeyLocal: keyedOptions,
17663
- selectedLocal
17664
- });
17665
- setFirstRender(false);
17666
- };
17667
- const handleOnEmptyChange = newIsEmptyValue => {
17668
- if (newIsEmptyValue !== isEmpty) {
17669
- setIsEmpty(newIsEmptyValue);
17670
- onEmptyChange?.(newIsEmptyValue);
17707
+ if (isDisabled || value == null) return;
17708
+ const alreadySelected = selected.includes(value);
17709
+ const updatedSelected = isMultiple ? alreadySelected ? selected.filter(item => item !== value) : [...selected, value] : alreadySelected ? [] : [value];
17710
+ const fieldValue = isMultiple ? updatedSelected : updatedSelected[0];
17711
+ setSelected(updatedSelected);
17712
+ setValue?.(name, fieldValue);
17713
+ form.clearErrors(name);
17714
+ if (resetInput) {
17715
+ const rawInputValue = isMultiple ? null : updatedSelected.length ? String(optionsWithKey[value]?.label) : null;
17716
+ setRawInput(rawInputValue);
17671
17717
  }
17672
- };
17673
- const handleOpenChange = open => {
17674
- if (!isDisabled) {
17675
- setIsOpen(open);
17718
+ if (shouldClose) {
17719
+ setIsOpen(false);
17676
17720
  }
17721
+ onChange?.(value, !alreadySelected);
17722
+ onEmptyChange?.(updatedSelected.length === 0);
17677
17723
  };
17678
- const handleChange = changingValue => {
17679
- if (isDisabled || changingValue === undefined) {
17680
- return;
17681
- }
17682
- const isNewSelected = true;
17683
- const isChangingItemSelected = selected.includes(changingValue);
17684
- if (isMultiple) {
17685
- setSelected(currentSelected => isChangingItemSelected ? currentSelected.filter(current => current !== changingValue) : [...currentSelected, changingValue]);
17686
- setInputValue('');
17687
- } else {
17688
- if (selected[0] === changingValue) {
17689
- setSelected([]);
17690
- setInputValue('');
17691
- } else {
17692
- setSelected([changingValue]);
17693
- }
17694
- }
17724
+ const handleClearAll = e => {
17725
+ if (isDisabled) return;
17726
+ e.preventDefault();
17727
+ e.stopPropagation();
17728
+ setSelected([]);
17729
+ setRawInput(null);
17695
17730
  setIsOpen(false);
17696
- setFirstSuggestion('');
17731
+ setValue?.(name, undefined);
17732
+ form.trigger(name);
17697
17733
  inputRef.current?.focus();
17698
- setStatus('basic');
17699
- useFormResult.clearErrors(name);
17700
- useFormResult.trigger(name);
17701
- onChange?.(changingValue, isNewSelected);
17734
+ onClearAll?.();
17735
+ onEmptyChange?.(true);
17702
17736
  };
17703
- const handleClearAll = event => {
17704
- if (isDisabled) {
17737
+ const handleInputChange = e => {
17738
+ const input = e.target.value;
17739
+ setRawInput(input);
17740
+ if (!autoSelect || !filterOptions) return;
17741
+ const match = findExactMatch(input, optionsWithKey);
17742
+ if (match) {
17743
+ handleChange({
17744
+ value: match.value,
17745
+ shouldClose: false
17746
+ });
17705
17747
  return;
17706
17748
  }
17707
- event.stopPropagation();
17708
- event.preventDefault();
17709
- setSelected([]);
17710
- setInputValue('');
17711
- setIsOpen(false);
17712
- setFirstSuggestion('');
17713
- useFormResult.trigger(name);
17714
- inputRef.current?.focus();
17715
- onClearAll?.();
17749
+ // unset selected value if not fully matched
17750
+ if (!isMultiple && selected.length > 0) {
17751
+ handleChange({
17752
+ value: selected[0],
17753
+ shouldClose: false,
17754
+ resetInput: false
17755
+ });
17756
+ }
17716
17757
  };
17717
- const handleInputClick = event => {
17758
+ const handleInputClick = e => {
17759
+ e.stopPropagation();
17760
+ e.preventDefault();
17718
17761
  if (!isDisabled) {
17719
17762
  inputRef.current?.focus();
17720
17763
  setIsOpen(true);
17721
17764
  }
17722
- event.stopPropagation();
17723
- event.preventDefault();
17724
17765
  };
17725
- const handleInputKeyDown = event => {
17726
- if (['Space'].includes(event.code) && !firstSuggestion) {
17727
- setIsOpen(true);
17728
- inputRef.current?.focus();
17729
- event.stopPropagation();
17730
- event.preventDefault();
17731
- } else if (['Tab', 'Enter'].includes(event.code) && firstSuggestion && firstSuggestion !== inputValue) {
17732
- const foundItem = Object.values(optionsWithKey).find(item => `${item.label}`.toLowerCase() === firstSuggestion.toLowerCase());
17733
- handleChange(foundItem?.value);
17734
- if (foundItem) {
17735
- setInputValue(`${foundItem?.label}`);
17766
+ const handleInputKeyDown = e => {
17767
+ const isEnterOrTab = ['Enter', 'Tab'].includes(e.code);
17768
+ if (isEnterOrTab && firstSuggestion && firstSuggestion !== inputValue) {
17769
+ const match = findExactMatch(firstSuggestion, optionsWithKey);
17770
+ if (match) {
17771
+ handleChange({
17772
+ value: match.value,
17773
+ shouldClose: false
17774
+ });
17736
17775
  }
17737
- event.preventDefault();
17738
- return false;
17739
- } else if (isMultiple && event.code === 'Backspace' && selected.length > 0 && !firstSuggestion) {
17740
- handleChange(selected[selected.length - 1]);
17741
- event.preventDefault();
17742
- return false;
17743
- } else if (!isOpen && firstSuggestion !== inputValue) {
17776
+ e.preventDefault();
17777
+ return;
17778
+ }
17779
+ if (isMultiple && e.code === 'Backspace' && selected.length && !inputValue) {
17780
+ const lastSelected = selected[selected.length - 1];
17781
+ handleChange({
17782
+ value: lastSelected,
17783
+ shouldClose: false
17784
+ });
17785
+ e.preventDefault();
17786
+ return;
17787
+ }
17788
+ if (!isOpen && firstSuggestion !== inputValue) {
17744
17789
  setIsOpen(true);
17745
17790
  }
17746
17791
  };
17747
- const handleInputChange = event => {
17748
- setInputValue(event.target.value);
17749
- };
17750
- const handleSelectedClick = event => {
17751
- event.stopPropagation();
17792
+ const handleRemoveSelectedClick = value => e => {
17793
+ e.stopPropagation();
17794
+ handleChange({
17795
+ value
17796
+ });
17797
+ onRemoveSelectedClick?.(value);
17798
+ form.trigger(name);
17752
17799
  };
17753
- const handleRemoveSelectedClick = selectedItem => event => {
17754
- event.stopPropagation();
17755
- handleChange(selectedItem);
17756
- onRemoveSelectedClick?.(selectedItem);
17800
+ const handleOpenChange = (open, event, reason) => {
17801
+ if (isDisabled || reason === 'reference-press') {
17802
+ return;
17803
+ }
17804
+ setIsOpen(open);
17805
+ if (!isMultiple && selected.length > 0) {
17806
+ const selectedValue = selected[0];
17807
+ const label = optionsWithKey[selectedValue]?.label;
17808
+ setRawInput(label ? String(label) : null);
17809
+ return;
17810
+ }
17811
+ setRawInput(null);
17757
17812
  };
17813
+ const status = (() => {
17814
+ if (form.formState.errors[name]) return 'error';
17815
+ if (error) return 'error';
17816
+ if (success) return 'success';
17817
+ return 'basic';
17818
+ })();
17758
17819
  return {
17759
17820
  isOpen,
17760
17821
  isDisabled,
@@ -17775,18 +17836,18 @@ const useTypeahead = ({
17775
17836
  inputValue,
17776
17837
  validationSchema,
17777
17838
  status,
17839
+ error: error ?? form.formState.errors[name],
17778
17840
  placeholder,
17779
17841
  options: items,
17780
- useFormResult,
17842
+ useFormResult: form,
17781
17843
  register,
17782
17844
  setValue,
17783
- handleChange,
17845
+ onChange,
17784
17846
  handleClearAll,
17785
17847
  handleOpenChange,
17786
17848
  handleInputChange,
17787
17849
  handleInputClick,
17788
17850
  handleInputKeyDown,
17789
- handleSelectedClick,
17790
17851
  handleRemoveSelectedClick
17791
17852
  };
17792
17853
  };
@@ -17900,7 +17961,7 @@ const MultipleTrigger = () => {
17900
17961
  const theme = (0,react_namespaceObject.useTheme)();
17901
17962
  const context = useTypeaheadContext();
17902
17963
  const typeaheadInputAdditionalProps = {};
17903
- if (!context.selectedItems.length && !!context.placeholder) {
17964
+ if (!context.selectedItems.length && !context.inputValue && !!context.placeholder) {
17904
17965
  typeaheadInputAdditionalProps.placeholder = context.placeholder;
17905
17966
  }
17906
17967
  return (0,jsx_runtime_namespaceObject.jsxs)((external_react_default()).Fragment, {
@@ -17908,7 +17969,7 @@ const MultipleTrigger = () => {
17908
17969
  const currentOption = context.optionsWithKey[selectedItem];
17909
17970
  const optionText = currentOption ? currentOption.children || currentOption.label || currentOption.value : '';
17910
17971
  return (0,jsx_runtime_namespaceObject.jsxs)(TypeaheadItem, {
17911
- onClick: context.handleSelectedClick,
17972
+ onClick: e => e.stopPropagation(),
17912
17973
  isDisabled: context.isDisabled,
17913
17974
  children: [(0,jsx_runtime_namespaceObject.jsx)(TypeaheadItemLabel, {
17914
17975
  isDisabled: context.isDisabled,
@@ -17983,7 +18044,7 @@ const SingleTrigger = () => {
17983
18044
  const context = useTypeaheadContext();
17984
18045
  const theme = (0,react_namespaceObject.useTheme)();
17985
18046
  const typeaheadInputAdditionalProps = {};
17986
- if (!context.selectedItems.length && !!context.placeholder) {
18047
+ if (!context.selectedItems.length && !context.inputValue && !!context.placeholder) {
17987
18048
  typeaheadInputAdditionalProps.placeholder = context.placeholder;
17988
18049
  }
17989
18050
  return (0,jsx_runtime_namespaceObject.jsxs)(TypeaheadInputsGroupWrapper, {
@@ -18123,6 +18184,7 @@ const Typeahead = ({
18123
18184
  name = 'typeahead-search',
18124
18185
  label,
18125
18186
  selectedItems,
18187
+ defaultSelectedItems,
18126
18188
  isOpen,
18127
18189
  isDisabled,
18128
18190
  isMultiple,
@@ -18140,8 +18202,6 @@ const Typeahead = ({
18140
18202
  optionsClassName,
18141
18203
  wrapperClassName,
18142
18204
  width = 300,
18143
- setValue,
18144
- register,
18145
18205
  onChange,
18146
18206
  onEmptyChange,
18147
18207
  onClearAll,
@@ -18152,6 +18212,7 @@ const Typeahead = ({
18152
18212
  const hookResult = useTypeahead({
18153
18213
  name,
18154
18214
  selectedItems,
18215
+ defaultSelectedItems,
18155
18216
  isOpen,
18156
18217
  isDisabled,
18157
18218
  isMultiple,
@@ -18165,8 +18226,6 @@ const Typeahead = ({
18165
18226
  success,
18166
18227
  validationSchema,
18167
18228
  placeholder,
18168
- setValue,
18169
- register,
18170
18229
  onChange,
18171
18230
  onEmptyChange,
18172
18231
  renderOption,
@@ -18214,7 +18273,7 @@ const Typeahead = ({
18214
18273
  status: hookResult.status,
18215
18274
  disabled: isDisabled,
18216
18275
  "data-testid": "helper-text",
18217
- children: error ? error?.message : helperText
18276
+ children: hookResult.error ? hookResult.error?.message?.toString() : helperText
18218
18277
  })]
18219
18278
  })
18220
18279
  });
@@ -19092,6 +19151,7 @@ const SelectWidget = props => {
19092
19151
  placeholder,
19093
19152
  onChange,
19094
19153
  onBlur,
19154
+ onFocus,
19095
19155
  onChangeOverride,
19096
19156
  value
19097
19157
  } = props;
@@ -19106,43 +19166,44 @@ const SelectWidget = props => {
19106
19166
  const handleBlur = ({
19107
19167
  target
19108
19168
  }) => onBlur(id, target && target.value);
19169
+ const handleFocus = ({
19170
+ target
19171
+ }) => onFocus(id, target && target.value);
19109
19172
  const onEmptyChange = isEmpty => {
19110
19173
  if (isEmpty) {
19111
19174
  handleChange();
19112
19175
  }
19113
19176
  };
19114
- const register = fieldName => ({
19115
- onBlur: handleBlur,
19116
- onChange: handleChange,
19117
- name: fieldName,
19118
- ref: () => {}
19119
- });
19120
19177
  const items = Array.isArray(enumOptions) ? enumOptions : [];
19121
19178
  const selectedItems = selectedIndex ? [items[Number(selectedIndex)].value] : [];
19122
- return (0,jsx_runtime_namespaceObject.jsx)(Typeahead, {
19123
- width: "100%",
19124
- selectedItems: selectedItems,
19125
- isDisabled: disabled,
19126
- name: name
19127
- // RJSF provides placeholder as empty string
19128
- ,
19129
- placeholder: placeholder || undefined,
19130
- onChange: handleChange,
19131
- register: register,
19132
- onEmptyChange: onEmptyChange,
19133
- renderOption: ({
19134
- label,
19135
- input
19136
- }) => highlightInputMatch(label, input),
19137
- children: items.map(({
19138
- label,
19139
- value
19140
- }) => (0,jsx_runtime_namespaceObject.jsx)(TypeaheadOption_TypeaheadOption, {
19141
- value: value,
19142
- label: label || value,
19143
- isDisabled: disabled || Array.isArray(enumDisabled) && enumDisabled.includes(value),
19144
- children: label || value
19145
- }, value))
19179
+ return (0,jsx_runtime_namespaceObject.jsx)("div", {
19180
+ id: id,
19181
+ onBlur: handleBlur,
19182
+ onFocus: handleFocus,
19183
+ children: (0,jsx_runtime_namespaceObject.jsx)(Typeahead, {
19184
+ width: "100%",
19185
+ selectedItems: selectedItems,
19186
+ isDisabled: disabled,
19187
+ name: name
19188
+ // RJSF provides placeholder as empty string
19189
+ ,
19190
+ placeholder: placeholder || undefined,
19191
+ onChange: handleChange,
19192
+ onEmptyChange: onEmptyChange,
19193
+ renderOption: ({
19194
+ label,
19195
+ input
19196
+ }) => highlightInputMatch(label, input),
19197
+ children: items.map(({
19198
+ label,
19199
+ value
19200
+ }) => (0,jsx_runtime_namespaceObject.jsx)(TypeaheadOption_TypeaheadOption, {
19201
+ value: value,
19202
+ label: label || value,
19203
+ isDisabled: disabled || Array.isArray(enumDisabled) && enumDisabled.includes(value),
19204
+ children: label || value
19205
+ }, value))
19206
+ })
19146
19207
  });
19147
19208
  };
19148
19209
  ;// ./src/components/JsonSchemaForm/widgets/PasswordWidget.tsx