@bolttech/molecules-dropdown 0.4.3 → 0.5.1

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/index.cjs CHANGED
@@ -2414,12 +2414,13 @@ const DropdownOptionsContainer = /*#__PURE__*/styled__default["default"].div.wit
2414
2414
  })(["position:absolute;inset:0;top:100%;"]);
2415
2415
 
2416
2416
  const ReusableDropdownComponent = ({
2417
+ id,
2418
+ dataTestId,
2417
2419
  label,
2418
2420
  variant: _variant = 'grey',
2419
2421
  required,
2420
2422
  inputValue,
2421
2423
  inputLabel,
2422
- hasError,
2423
2424
  disabled,
2424
2425
  errorMessage,
2425
2426
  onChangeInputValue,
@@ -2428,9 +2429,11 @@ const ReusableDropdownComponent = ({
2428
2429
  showSelectComponent,
2429
2430
  setSelectedOptionOnInputValue,
2430
2431
  inputRef,
2431
- dataTestId,
2432
- placeholder
2432
+ placeholder,
2433
+ onBlur,
2434
+ onFocus
2433
2435
  }) => {
2436
+ const hasError = !!errorMessage;
2434
2437
  // we have to type cast because of jest. when testing it sets the type of useTheme to DefaultTheme
2435
2438
  const theme = /*#__PURE__*/styled.useTheme();
2436
2439
  const sizeIcon = Number(theme.components.dropdown.icon.size.replace(/[^\d.-]+/g, ''));
@@ -2449,11 +2452,12 @@ const ReusableDropdownComponent = ({
2449
2452
  }
2450
2453
  }, {
2451
2454
  children: [jsxRuntime.jsx("label", Object.assign({
2455
+ htmlFor: `${id}-input`,
2452
2456
  className: "fieldLabel",
2453
2457
  "data-testid": `${dataTestId}-label`
2454
2458
  }, {
2455
2459
  children: label
2456
- })), required && jsxRuntime.jsx("label", Object.assign({
2460
+ })), required && jsxRuntime.jsx("span", Object.assign({
2457
2461
  className: "requiredLabel",
2458
2462
  "data-testid": `${dataTestId}-label-required`
2459
2463
  }, {
@@ -2461,6 +2465,7 @@ const ReusableDropdownComponent = ({
2461
2465
  }))]
2462
2466
  })), jsxRuntime.jsx(InputAndIconDropdown, {
2463
2467
  children: jsxRuntime.jsx(atomsInput.InputStyled, {
2468
+ id: `${id}-input`,
2464
2469
  "data-testid": `${dataTestId}-input`,
2465
2470
  ref: inputRef,
2466
2471
  disabled: disabled,
@@ -2473,14 +2478,16 @@ const ReusableDropdownComponent = ({
2473
2478
  onChangeInputLabel(((_b = e === null || e === void 0 ? void 0 : e.target) === null || _b === void 0 ? void 0 : _b.value) || '');
2474
2479
  setShowSelectComponent(true);
2475
2480
  },
2476
- onFocus: () => {
2481
+ onFocus: event => {
2477
2482
  onChangeInputValue('');
2478
2483
  onChangeInputLabel('');
2479
2484
  setShowSelectComponent(true);
2485
+ onFocus && onFocus(event);
2480
2486
  },
2481
- onBlur: () => {
2487
+ onBlur: event => {
2482
2488
  setSelectedOptionOnInputValue();
2483
2489
  setShowSelectComponent(false);
2490
+ onBlur && onBlur(event);
2484
2491
  }
2485
2492
  })
2486
2493
  })]
@@ -2635,15 +2642,17 @@ const Dropdown = ({
2635
2642
  label,
2636
2643
  variant: _variant = 'grey',
2637
2644
  required,
2638
- hasError,
2639
2645
  optionList,
2640
2646
  disabled,
2641
2647
  errorMessage,
2642
2648
  urlFilterOptions,
2643
- dataTestId,
2649
+ id: _id = 'dropdown-id',
2650
+ dataTestId: _dataTestId = 'dropdown-data-testid',
2644
2651
  filterOptionsParam: _filterOptionsParam = filterOptions,
2645
- selectedOption,
2646
- setSelectedOption,
2652
+ value,
2653
+ onChange,
2654
+ onBlur,
2655
+ onFocus,
2647
2656
  placeholder
2648
2657
  }) => {
2649
2658
  var _a;
@@ -2651,7 +2660,8 @@ const Dropdown = ({
2651
2660
  const [currentOptionList, setCurrentOptionList] = react.useState([]);
2652
2661
  const [inputValue, setInputValue] = react.useState('');
2653
2662
  const [inputLabel, setInputLabel] = react.useState('');
2654
- const [internalSelectedOption, setInternalSelectedOption] = react.useState(selectedOption);
2663
+ const [internalSelectedOption, setInternalSelectedOption] = react.useState();
2664
+ const [isFirstRender, setIsFirstRender] = react.useState(true);
2655
2665
  const inputRef = react.useRef(null);
2656
2666
  react.useEffect(() => {
2657
2667
  const normalizeOptionList = () => __awaiter(void 0, void 0, void 0, function* () {
@@ -2676,45 +2686,54 @@ const Dropdown = ({
2676
2686
  react.useEffect(() => {
2677
2687
  setSelectedOptionOnInputValue();
2678
2688
  // eslint-disable-next-line react-hooks/exhaustive-deps
2679
- }, []);
2689
+ }, [internalSelectedOption]);
2690
+ react.useEffect(() => {
2691
+ if (!isFirstRender || currentOptionList.length === 0) return;
2692
+ setInternalSelectedOption(currentOptionList.find(option => option.id === value));
2693
+ setIsFirstRender(false);
2694
+ }, [currentOptionList, isFirstRender, setSelectedOptionOnInputValue, value]);
2680
2695
  return jsxRuntime.jsxs(SectionContainer, Object.assign({
2681
2696
  onClick: () => {
2682
2697
  var _a;
2683
2698
  return (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
2684
2699
  },
2685
2700
  variant: _variant,
2686
- "data-testid": `${dataTestId}-container`,
2701
+ id: `${_id}-container`,
2702
+ "data-testid": `${_dataTestId}-container`,
2687
2703
  style: {
2688
2704
  maxWidth: (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.style.width
2689
2705
  }
2690
2706
  }, {
2691
2707
  children: [jsxRuntime.jsx(ReusableDropdownComponent, {
2708
+ id: _id,
2709
+ dataTestId: _dataTestId,
2692
2710
  label: label,
2693
2711
  variant: _variant,
2694
2712
  required: required,
2695
2713
  inputValue: inputValue,
2696
2714
  inputLabel: inputLabel,
2697
- dataTestId: dataTestId,
2698
2715
  disabled: disabled,
2699
2716
  errorMessage: errorMessage,
2700
- hasError: hasError,
2701
2717
  showSelectComponent: showSelectComponent,
2702
2718
  inputRef: inputRef,
2703
2719
  placeholder: placeholder,
2704
2720
  setShowSelectComponent: setShowSelectComponent,
2705
2721
  onChangeInputValue: setInputValue,
2706
2722
  setSelectedOptionOnInputValue: setSelectedOptionOnInputValue,
2707
- onChangeInputLabel: setInputLabel
2723
+ onChangeInputLabel: setInputLabel,
2724
+ onBlur: onBlur,
2725
+ onFocus: onFocus
2708
2726
  }), showSelectComponent && !disabled && jsxRuntime.jsx(DropdownOptionsContainer, {
2709
2727
  children: jsxRuntime.jsx(atomsSelect.Select, {
2710
- dataTestId: `${dataTestId}-select`,
2728
+ id: `${_id}-select`,
2729
+ dataTestId: `${_dataTestId}-select`,
2711
2730
  onChange: selectedValue => {
2712
2731
  var _a;
2713
2732
  setInputValue(selectedValue.value);
2714
2733
  setInputLabel(selectedValue.label);
2715
2734
  setInternalSelectedOption(Object.assign({}, selectedValue));
2716
2735
  reactDom.flushSync(() => {
2717
- setSelectedOption(selectedValue);
2736
+ onChange(selectedValue);
2718
2737
  });
2719
2738
  (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.blur();
2720
2739
  },
@@ -2725,34 +2744,29 @@ const Dropdown = ({
2725
2744
  }));
2726
2745
  };
2727
2746
 
2728
- const DropdownOptionsWithHeaders = ({
2747
+ const DropdownWithHeaders = ({
2729
2748
  label,
2730
2749
  variant: _variant = 'grey',
2731
2750
  required,
2732
- hasError,
2733
2751
  optionList,
2734
2752
  disabled,
2735
2753
  errorMessage,
2736
2754
  urlFilterOptions,
2737
2755
  dataTestId,
2738
2756
  filterOptionsParam: _filterOptionsParam = filterOptionsWithHeaders,
2739
- selectedOption,
2740
- setSelectedOption,
2757
+ value,
2758
+ onChange,
2759
+ onBlur,
2760
+ onFocus,
2741
2761
  placeholder
2742
2762
  }) => {
2743
2763
  const [showSelectComponent, setShowSelectComponent] = react.useState(false);
2744
2764
  const [currentOptionList, setCurrentOptionList] = react.useState([]);
2745
2765
  const [inputValue, setInputValue] = react.useState('');
2746
2766
  const [inputLabel, setInputLabel] = react.useState('');
2747
- const [internalSelectedOption, setInternalSelectedOption] = react.useState(selectedOption);
2767
+ const [internalSelectedOption, setInternalSelectedOption] = react.useState();
2768
+ const [isFirstRender, setIsFirstRender] = react.useState(true);
2748
2769
  const inputRef = react.useRef(null);
2749
- react.useEffect(() => {
2750
- var _a;
2751
- if (internalSelectedOption) {
2752
- (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.blur();
2753
- setSelectedOption(internalSelectedOption);
2754
- }
2755
- }, [internalSelectedOption, setSelectedOption]);
2756
2770
  react.useEffect(() => {
2757
2771
  const normalizeOptionList = () => __awaiter(void 0, void 0, void 0, function* () {
2758
2772
  return yield _filterOptionsParam(inputValue, optionList, urlFilterOptions);
@@ -2777,6 +2791,17 @@ const DropdownOptionsWithHeaders = ({
2777
2791
  }
2778
2792
  }
2779
2793
  }, [currentOptionList, inputValue, internalSelectedOption]);
2794
+ react.useEffect(() => {
2795
+ setSelectedOptionOnInputValue();
2796
+ // eslint-disable-next-line react-hooks/exhaustive-deps
2797
+ }, [internalSelectedOption]);
2798
+ react.useEffect(() => {
2799
+ if (!isFirstRender || currentOptionList.length === 0) return;
2800
+ setInternalSelectedOption(currentOptionList.map(optionsList => {
2801
+ return optionsList.options.find(option => option.id === value);
2802
+ })[0] || undefined);
2803
+ setIsFirstRender(false);
2804
+ }, [currentOptionList, isFirstRender, setSelectedOptionOnInputValue, value]);
2780
2805
  return jsxRuntime.jsxs(SectionContainer, Object.assign({
2781
2806
  onClick: () => {
2782
2807
  var _a;
@@ -2794,23 +2819,29 @@ const DropdownOptionsWithHeaders = ({
2794
2819
  dataTestId: dataTestId,
2795
2820
  disabled: disabled,
2796
2821
  errorMessage: errorMessage,
2797
- hasError: hasError,
2798
2822
  showSelectComponent: showSelectComponent,
2799
2823
  inputRef: inputRef,
2800
2824
  placeholder: placeholder,
2801
2825
  setShowSelectComponent: setShowSelectComponent,
2802
2826
  onChangeInputValue: setInputValue,
2803
2827
  onChangeInputLabel: setInputLabel,
2804
- setSelectedOptionOnInputValue: setSelectedOptionOnInputValue
2828
+ setSelectedOptionOnInputValue: setSelectedOptionOnInputValue,
2829
+ onBlur: onBlur,
2830
+ onFocus: onFocus
2805
2831
  }), showSelectComponent && !disabled && jsxRuntime.jsx(DropdownOptionsContainer, {
2806
2832
  children: jsxRuntime.jsx(atomsSelect.SelectWithHeaders, {
2807
2833
  dataTestId: `${dataTestId}-select`,
2808
2834
  onChange: selectedValue => {
2835
+ var _a;
2809
2836
  setInputLabel(selectedValue.label);
2810
2837
  setInputValue(selectedValue.value);
2811
2838
  setInternalSelectedOption(Object.assign({}, selectedValue));
2839
+ reactDom.flushSync(() => {
2840
+ onChange(selectedValue);
2841
+ });
2842
+ (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.blur();
2812
2843
  },
2813
- active: selectedOption,
2844
+ active: internalSelectedOption,
2814
2845
  options: currentOptionList
2815
2846
  })
2816
2847
  })]
@@ -2818,4 +2849,4 @@ const DropdownOptionsWithHeaders = ({
2818
2849
  };
2819
2850
 
2820
2851
  exports.Dropdown = Dropdown;
2821
- exports.DropdownOptionsWithHeaders = DropdownOptionsWithHeaders;
2852
+ exports.DropdownWithHeaders = DropdownWithHeaders;
package/package.json CHANGED
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "name": "@bolttech/molecules-dropdown",
3
- "version": "0.4.3",
3
+ "version": "0.5.1",
4
4
  "main": "./index.cjs",
5
5
  "type": "commonjs",
6
6
  "types": "./src/index.d.ts",
7
7
  "dependencies": {
8
- "@bolttech/atoms-icon": "0.5.0",
9
- "@bolttech/atoms-input": "0.0.1",
10
- "@bolttech/atoms-select": "0.5.0",
11
- "@edirect/frontend-foundations": "0.0.53",
8
+ "@bolttech/atoms-icon": "0.5.1",
9
+ "@bolttech/atoms-input": "0.5.0",
10
+ "@bolttech/atoms-select": "0.5.1",
11
+ "@edirect/frontend-foundations": "0.0.55",
12
12
  "jest-styled-components": "7.1.1",
13
13
  "react": "18.2.0",
14
14
  "react-dom": "18.2.0",
package/src/index.d.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  export { Dropdown } from './lib/molecules-dropdown';
2
- export { DropdownOptionsWithHeaders } from './lib/molecules-dropdown-with-header-options';
3
- export type { DropdownProps, DropdownOptionsWithHeadersProps } from './lib/molecules-dropdown.type';
2
+ export { DropdownWithHeaders } from './lib/molecules-dropdown-with-header-options';
3
+ export type { DropdownProps, DropdownWithHeadersProps, } from './lib/molecules-dropdown.type';
@@ -1,3 +1,3 @@
1
1
  /// <reference types="react" />
2
- import { DropdownOptionsWithHeadersProps } from './molecules-dropdown.type';
3
- export declare const DropdownOptionsWithHeaders: ({ label, variant, required, hasError, optionList, disabled, errorMessage, urlFilterOptions, dataTestId, filterOptionsParam, selectedOption, setSelectedOption, placeholder, }: DropdownOptionsWithHeadersProps) => JSX.Element;
2
+ import { DropdownWithHeadersProps } from './molecules-dropdown.type';
3
+ export declare const DropdownWithHeaders: ({ label, variant, required, optionList, disabled, errorMessage, urlFilterOptions, dataTestId, filterOptionsParam, value, onChange, onBlur, onFocus, placeholder, }: DropdownWithHeadersProps) => JSX.Element;
@@ -1,3 +1,3 @@
1
1
  /// <reference types="react" />
2
2
  import { DropdownProps } from './molecules-dropdown.type';
3
- export declare const Dropdown: ({ label, variant, required, hasError, optionList, disabled, errorMessage, urlFilterOptions, dataTestId, filterOptionsParam, selectedOption, setSelectedOption, placeholder, }: DropdownProps) => JSX.Element;
3
+ export declare const Dropdown: ({ label, variant, required, optionList, disabled, errorMessage, urlFilterOptions, id, dataTestId, filterOptionsParam, value, onChange, onBlur, onFocus, placeholder, }: DropdownProps) => JSX.Element;
@@ -13,7 +13,6 @@ Default props for Dropdown component
13
13
  @property disabled - An optional boolean to disable the dropdown
14
14
  @property dataTestId - An optional string to use as the data-testid attribute for the dropdown
15
15
  @property errorMessage - An optional string to display as an error message for the dropdown
16
- @property hasError - An optional boolean to indicate if the dropdown has an error
17
16
  @property required - An optional boolean to indicate if the dropdown is required
18
17
  @property variant - An optional string to set the variant of the dropdown
19
18
  */
@@ -21,11 +20,13 @@ type DefaultProps = {
21
20
  label: string;
22
21
  placeholder?: string;
23
22
  disabled?: boolean;
23
+ id?: string;
24
24
  dataTestId?: string;
25
25
  errorMessage?: string;
26
- hasError?: boolean;
27
26
  required?: boolean;
28
27
  variant?: StyleVariants;
28
+ onBlur?: ((value?: unknown) => void) | ((evt: React.FocusEvent<HTMLElement, Element>) => void);
29
+ onFocus?: ((value?: unknown) => void) | ((evt: React.FocusEvent<HTMLElement, Element>) => void);
29
30
  };
30
31
  /**
31
32
  Props for Dropdown component
@@ -84,8 +85,8 @@ export type DropdownProps = DefaultProps & {
84
85
  * }
85
86
  * <Dropdown setSelectedOption={manipulateData} />
86
87
  */
87
- setSelectedOption: (selectedOption?: OptionType) => void | React.Dispatch<React.SetStateAction<OptionType>>;
88
- selectedOption?: OptionType;
88
+ onChange: (selectedOption?: OptionType) => void | React.Dispatch<React.SetStateAction<OptionType>>;
89
+ value?: string;
89
90
  };
90
91
  /**
91
92
  Props for DropdownOptionsWithHeaders component
@@ -96,7 +97,7 @@ export type DropdownProps = DefaultProps & {
96
97
  @property setSelectedOption - A function to set the selected option
97
98
  @property selectedOption - An optional object representing the currently selected option
98
99
  */
99
- export type DropdownOptionsWithHeadersProps = DefaultProps & {
100
+ export type DropdownWithHeadersProps = DefaultProps & {
100
101
  optionList?: OptionWithHeaderType[];
101
102
  /**
102
103
  * An optional function that filters the option list based on input value
@@ -150,8 +151,8 @@ export type DropdownOptionsWithHeadersProps = DefaultProps & {
150
151
  * }
151
152
  * <Dropdown setSelectedOption={manipulateData} />
152
153
  */
153
- setSelectedOption: (selectedOption?: OptionType) => void | React.Dispatch<React.SetStateAction<OptionType>>;
154
- selectedOption?: OptionType;
154
+ onChange: (selectedOption?: OptionType) => void | React.Dispatch<React.SetStateAction<OptionType>>;
155
+ value?: string;
155
156
  };
156
157
  /**
157
158
  Props for ReusableDropdownComponent component
@@ -1,3 +1,3 @@
1
1
  /// <reference types="react" />
2
2
  import { ReusableDropdownComponentProps } from './molecules-dropdown.type';
3
- export declare const ReusableDropdownComponent: ({ label, variant, required, inputValue, inputLabel, hasError, disabled, errorMessage, onChangeInputValue, onChangeInputLabel, setShowSelectComponent, showSelectComponent, setSelectedOptionOnInputValue, inputRef, dataTestId, placeholder, }: ReusableDropdownComponentProps) => JSX.Element;
3
+ export declare const ReusableDropdownComponent: ({ id, dataTestId, label, variant, required, inputValue, inputLabel, disabled, errorMessage, onChangeInputValue, onChangeInputLabel, setShowSelectComponent, showSelectComponent, setSelectedOptionOnInputValue, inputRef, placeholder, onBlur, onFocus, }: ReusableDropdownComponentProps) => JSX.Element;