@connectif/ui-components 9.0.5 → 9.0.7

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/CHANGELOG.md CHANGED
@@ -1,6 +1,19 @@
1
1
  # Changelog
2
2
 
3
- ## [9.0.5] - 2026-06- 19
3
+ ## [9.0.7] - 2026-06-24
4
+
5
+ ### Fixed
6
+
7
+ - `Divider`: forced visible divider rendering by setting `opacity: 1` in the base styles.
8
+ - `Autocomplete`: fixed dropdown rounded corners.
9
+
10
+ ## [9.0.6] - 2026-06-23
11
+
12
+ ### Added
13
+
14
+ - `Autocomplete`: added optional `exclusiveOption` property.
15
+
16
+ ## [9.0.5] - 2026-06-19
4
17
 
5
18
  ### Added
6
19
 
@@ -124,9 +124,19 @@ export type AutocompleteProps<T extends string, Multiple extends boolean | undef
124
124
  * Ref to the inner HTMLInputElement
125
125
  */
126
126
  ref?: React.Ref<HTMLInputElement>;
127
+ /**
128
+ * When provided, this option is always displayed as the first item in the
129
+ * dropdown, separated from the rest by a divider. Selecting it clears all
130
+ * other selections; selecting any other option deselects this one.
131
+ * In multiple mode, while this option is active the input renders as plain
132
+ * text (no chips).
133
+ */
134
+ exclusiveOption?: AutocompleteOption<T> & {
135
+ label?: string;
136
+ };
127
137
  };
128
138
  /**
129
139
  * Powered TextField with the ability to select from a predefined list of options, allowing to select one or multiple values.
130
140
  */
131
- declare const Autocomplete: <T extends string, Multiple extends boolean | undefined = undefined, Value = AutocompleteValue<T, Multiple>>({ variant, value, multiple, textFieldProps, options, disabled, mode, isCaseSensitive, isDiacriticSensitive, onChange, renderLabel, isLoading, onSearch, loadingText, noOptionsText, allowFreeText, addNewValueText, closeOnSelect, maxValueLength, maxValues, maxValuesText, startIconId, onClose, onOpen, disableClear, disableCloseOnClickAway, size }: AutocompleteProps<T, Multiple, Value>) => import("react/jsx-runtime").JSX.Element;
141
+ declare const Autocomplete: <T extends string, Multiple extends boolean | undefined = undefined, Value = AutocompleteValue<T, Multiple>>({ variant, value, multiple, textFieldProps, options, disabled, mode, isCaseSensitive, isDiacriticSensitive, onChange, renderLabel, isLoading, onSearch, loadingText, noOptionsText, allowFreeText, addNewValueText, closeOnSelect, maxValueLength, maxValues, maxValuesText, startIconId, onClose, onOpen, disableClear, disableCloseOnClickAway, size, exclusiveOption }: AutocompleteProps<T, Multiple, Value>) => import("react/jsx-runtime").JSX.Element;
132
142
  export default Autocomplete;
@@ -67,9 +67,19 @@ export type AutocompleteInputProps<T extends string, Multiple extends boolean |
67
67
  onSearchValueChange: (event: React.SyntheticEvent, searchValue: string) => void;
68
68
  onPressEnter: (event: React.SyntheticEvent, inputValue: string) => void;
69
69
  onRemoveValue: (event: React.SyntheticEvent, value: Value) => void;
70
+ /**
71
+ * When true (exclusive option selected in multiple mode), chips are hidden
72
+ * and the input displays as a plain text field.
73
+ */
74
+ exclusiveOptionSelected?: boolean;
75
+ /**
76
+ * Label to display in the text field when the exclusive option is selected
77
+ * and the component is in multiple mode.
78
+ */
79
+ exclusiveOptionLabel?: string;
70
80
  };
71
81
  /**
72
82
  * Powered TextField Input.
73
83
  */
74
- declare const AutocompleteInput: <T extends string, Multiple extends boolean | undefined = undefined, Value = AutocompleteValue<T, Multiple>>({ variant, value, multiple, textFieldProps, hasFilteredOptions, disabled, renderLabel, maxValueLength, canAddValues, maxValuesText, disableClear, containerRef, inputRef, onClosePopover, onOpenPopover, isOpenPopover, inputValue, setInputValue, placeholder, startIconId, size, onSearchValueChange, onPressEnter, onRemoveValue }: AutocompleteInputProps<T, Multiple, Value>) => import("react/jsx-runtime").JSX.Element;
84
+ declare const AutocompleteInput: <T extends string, Multiple extends boolean | undefined = undefined, Value = AutocompleteValue<T, Multiple>>({ variant, value, multiple, textFieldProps, hasFilteredOptions, disabled, renderLabel, maxValueLength, canAddValues, maxValuesText, disableClear, containerRef, inputRef, onClosePopover, onOpenPopover, isOpenPopover, inputValue, setInputValue, placeholder, startIconId, size, onSearchValueChange, onPressEnter, onRemoveValue, exclusiveOptionSelected, exclusiveOptionLabel }: AutocompleteInputProps<T, Multiple, Value>) => import("react/jsx-runtime").JSX.Element;
75
85
  export default AutocompleteInput;
@@ -30,10 +30,19 @@ type AutocompleteListProps<T extends string, Multiple extends boolean | undefine
30
30
  highlightedIndex: number;
31
31
  onAddSelectedValue: (event: React.MouseEvent<HTMLElement, MouseEvent>, option: AutocompleteLabeledOption<T>) => void;
32
32
  onClickAwayPopover: (event: React.MouseEvent<HTMLElement, MouseEvent>) => void;
33
+ /**
34
+ * Option that is always shown first, separated by a divider, and when selected
35
+ * clears all other selections (and vice versa).
36
+ */
37
+ exclusiveOption?: AutocompleteLabeledOption<T>;
38
+ /**
39
+ * Whether the exclusive option is currently selected.
40
+ */
41
+ isExclusiveSelected?: boolean;
33
42
  };
34
43
  export declare const AUTOCOMPLETE_ITEM_HEIGHT = 44;
35
44
  /**
36
45
  * Powered autocomplete list.
37
46
  */
38
- declare const AutocompleteList: <T extends string, Multiple extends boolean | undefined = undefined>({ options, isLoading, loadingText, noOptionsText, addNewValueText, inputContainerRef, isOpen, selectedIndex, highlightedIndex, virtualListRef, filteredOptions, onAddSelectedValue, onClickAwayPopover }: AutocompleteListProps<T, Multiple>) => import("react/jsx-runtime").JSX.Element;
47
+ declare const AutocompleteList: <T extends string, Multiple extends boolean | undefined = undefined>({ options, isLoading, loadingText, noOptionsText, addNewValueText, inputContainerRef, isOpen, selectedIndex, highlightedIndex, virtualListRef, filteredOptions, onAddSelectedValue, onClickAwayPopover, exclusiveOption, isExclusiveSelected }: AutocompleteListProps<T, Multiple>) => import("react/jsx-runtime").JSX.Element;
39
48
  export default AutocompleteList;
package/dist/index.js CHANGED
@@ -8342,6 +8342,7 @@ var Divider = ({
8342
8342
  variant,
8343
8343
  ...rest,
8344
8344
  sx: {
8345
+ opacity: 1,
8345
8346
  ...sx,
8346
8347
  ...color2 && { borderColor: color2 }
8347
8348
  }
@@ -24321,7 +24322,9 @@ var AutocompleteInput = function AutocompleteInput2({
24321
24322
  size,
24322
24323
  onSearchValueChange,
24323
24324
  onPressEnter,
24324
- onRemoveValue
24325
+ onRemoveValue,
24326
+ exclusiveOptionSelected = false,
24327
+ exclusiveOptionLabel
24325
24328
  }) {
24326
24329
  const { palette: palette2 } = useCustomTheme();
24327
24330
  const { t } = useTranslation();
@@ -24367,7 +24370,7 @@ var AutocompleteInput = function AutocompleteInput2({
24367
24370
  },
24368
24371
  maxLength: maxValueLength,
24369
24372
  placeholder: !canAddValues ? maxValuesText || t("AUTOCOMPLETE.MAX_VALUES") : Array.isArray(value) && value.length > 0 || !Array.isArray(value) && !!value ? "" : placeholder,
24370
- value: inputValue || (!Array.isArray(value) ? renderLabel(value) : ""),
24373
+ value: inputValue || exclusiveOptionLabel || (!Array.isArray(value) ? renderLabel(value) : ""),
24371
24374
  multiline: false,
24372
24375
  disabled: disabled || !canAddValues,
24373
24376
  onChange: (event) => {
@@ -24405,7 +24408,7 @@ var AutocompleteInput = function AutocompleteInput2({
24405
24408
  }
24406
24409
  },
24407
24410
  containerRef,
24408
- startAdornment: multiple ? /* @__PURE__ */ jsx135(
24411
+ startAdornment: multiple && !exclusiveOptionSelected ? /* @__PURE__ */ jsx135(
24409
24412
  AutocompleteInputSelection_default,
24410
24413
  {
24411
24414
  value,
@@ -24537,11 +24540,14 @@ var AutocompleteList = function AutocompleteList2({
24537
24540
  virtualListRef,
24538
24541
  filteredOptions,
24539
24542
  onAddSelectedValue,
24540
- onClickAwayPopover
24543
+ onClickAwayPopover,
24544
+ exclusiveOption,
24545
+ isExclusiveSelected
24541
24546
  }) {
24542
24547
  const { palette: palette2 } = useCustomTheme();
24543
24548
  const { t } = useTranslation();
24544
24549
  const listRef = React76.useRef(null);
24550
+ const popoverWidth = inputContainerRef.current?.clientWidth;
24545
24551
  const getText = (option) => {
24546
24552
  const isInOptions = options.some((elem) => elem.id === option.id);
24547
24553
  if (!isInOptions) {
@@ -24598,58 +24604,99 @@ var AutocompleteList = function AutocompleteList2({
24598
24604
  anchorEl: inputContainerRef.current,
24599
24605
  open: isOpen,
24600
24606
  sx: { zIndex: 3e3 },
24601
- children: /* @__PURE__ */ jsx136(Paper_default, { sx: { boxShadow: shadows[1], borderRadius: "8px" }, children: /* @__PURE__ */ jsxs66(
24602
- Box_default2,
24607
+ children: /* @__PURE__ */ jsx136(
24608
+ Paper_default,
24603
24609
  {
24604
24610
  sx: {
24605
- maxHeight: "40vh",
24606
- height: !isLoading && filteredOptions.length ? filteredOptions.length * 44 : "auto",
24607
- width: inputContainerRef.current ? inputContainerRef.current.clientWidth : null,
24608
- borderRadius: "8px"
24611
+ boxShadow: shadows[1],
24612
+ borderRadius: "8px",
24613
+ width: popoverWidth ?? "auto"
24609
24614
  },
24610
- className: "Slim-Vertical-Scroll",
24611
- ref: listRef,
24612
- children: [
24613
- isLoading && /* @__PURE__ */ jsx136(
24614
- ListItem_default,
24615
- {
24616
- text: loadingText ?? t("AUTOCOMPLETE.LOADING")
24617
- }
24618
- ),
24619
- !isLoading && filteredOptions.length === 0 && /* @__PURE__ */ jsx136(
24620
- ListItem_default,
24621
- {
24622
- text: noOptionsText ?? t("AUTOCOMPLETE.NO_OPTIONS")
24623
- }
24624
- ),
24625
- !isLoading && filteredOptions.length > 0 && /* @__PURE__ */ jsx136(AutoSizer5, { children: ({
24626
- height: height2,
24627
- width: width2
24628
- }) => /* @__PURE__ */ jsx136(
24629
- FixedSizeList3,
24630
- {
24631
- overscanCount: 3,
24632
- height: height2,
24633
- itemCount: filteredOptions.length,
24634
- itemSize: AUTOCOMPLETE_ITEM_HEIGHT,
24635
- width: width2,
24636
- className: "Slim-Vertical-Scroll",
24637
- ref: virtualListRef,
24638
- initialScrollOffset: getInitialListScroll(
24615
+ children: /* @__PURE__ */ jsxs66(
24616
+ Box_default2,
24617
+ {
24618
+ sx: {
24619
+ width: "100%",
24620
+ borderRadius: "8px",
24621
+ overflow: "hidden"
24622
+ },
24623
+ children: [
24624
+ !!exclusiveOption && /* @__PURE__ */ jsxs66(Fragment34, { children: [
24625
+ /* @__PURE__ */ jsx136(
24626
+ ListItemButton_default,
24627
+ {
24628
+ selected: isExclusiveSelected,
24629
+ tabIndex: -1,
24630
+ role: "option",
24631
+ baseSx: {
24632
+ color: palette2.grey[900]
24633
+ },
24634
+ text: exclusiveOption.label,
24635
+ onClick: (event) => onAddSelectedValue(
24636
+ event,
24637
+ exclusiveOption
24638
+ ),
24639
+ "data-testid": `autocomplete-option-${exclusiveOption.id}`
24640
+ }
24641
+ ),
24642
+ /* @__PURE__ */ jsx136(Divider_default, {})
24643
+ ] }),
24644
+ /* @__PURE__ */ jsxs66(
24645
+ Box_default2,
24639
24646
  {
24640
- itemHeight: AUTOCOMPLETE_ITEM_HEIGHT,
24641
- containerHeight: listRef.current?.clientHeight ?? 0,
24642
- highlightedIndex,
24643
- selectedIndex,
24644
- totalItems: filteredOptions.length
24647
+ sx: {
24648
+ maxHeight: !exclusiveOption ? "40vh" : "calc(40vh - 44px)",
24649
+ height: !isLoading && filteredOptions.length ? filteredOptions.length * 44 : "auto",
24650
+ width: "100%"
24651
+ },
24652
+ className: "Slim-Vertical-Scroll",
24653
+ ref: listRef,
24654
+ children: [
24655
+ isLoading && /* @__PURE__ */ jsx136(
24656
+ ListItem_default,
24657
+ {
24658
+ text: loadingText ?? t("AUTOCOMPLETE.LOADING")
24659
+ }
24660
+ ),
24661
+ !isLoading && filteredOptions.length === 0 && /* @__PURE__ */ jsx136(
24662
+ ListItem_default,
24663
+ {
24664
+ text: noOptionsText ?? t("AUTOCOMPLETE.NO_OPTIONS")
24665
+ }
24666
+ ),
24667
+ !isLoading && filteredOptions.length > 0 && /* @__PURE__ */ jsx136(AutoSizer5, { children: ({
24668
+ height: height2,
24669
+ width: width2
24670
+ }) => /* @__PURE__ */ jsx136(
24671
+ FixedSizeList3,
24672
+ {
24673
+ overscanCount: 3,
24674
+ height: height2,
24675
+ itemCount: filteredOptions.length,
24676
+ itemSize: AUTOCOMPLETE_ITEM_HEIGHT,
24677
+ width: width2,
24678
+ className: "Slim-Vertical-Scroll",
24679
+ ref: virtualListRef,
24680
+ initialScrollOffset: getInitialListScroll(
24681
+ {
24682
+ itemHeight: AUTOCOMPLETE_ITEM_HEIGHT,
24683
+ containerHeight: listRef.current?.clientHeight ?? 0,
24684
+ highlightedIndex,
24685
+ selectedIndex,
24686
+ totalItems: filteredOptions.length
24687
+ }
24688
+ ),
24689
+ children: ListItemButtonWrapper
24690
+ }
24691
+ ) })
24692
+ ]
24645
24693
  }
24646
- ),
24647
- children: ListItemButtonWrapper
24648
- }
24649
- ) })
24650
- ]
24694
+ )
24695
+ ]
24696
+ }
24697
+ )
24651
24698
  }
24652
- ) })
24699
+ )
24653
24700
  }
24654
24701
  )
24655
24702
  }
@@ -24687,7 +24734,8 @@ var Autocomplete = function Autocomplete2({
24687
24734
  onOpen = () => ({}),
24688
24735
  disableClear,
24689
24736
  disableCloseOnClickAway = false,
24690
- size = "S"
24737
+ size = "S",
24738
+ exclusiveOption
24691
24739
  }) {
24692
24740
  const anchorRef = React77.useRef(null);
24693
24741
  const inputRef = React77.useRef(null);
@@ -24697,6 +24745,24 @@ var Autocomplete = function Autocomplete2({
24697
24745
  const _renderLabel = React77.useCallback((id) => id, []);
24698
24746
  const [inputValue, setInputValue] = React77.useState("");
24699
24747
  const [isDirty, setDirty] = React77.useState(false);
24748
+ const labeledExclusiveOption = React77.useMemo(() => {
24749
+ if (!exclusiveOption) {
24750
+ return void 0;
24751
+ }
24752
+ return {
24753
+ ...exclusiveOption,
24754
+ label: exclusiveOption.label ?? (renderLabel ?? _renderLabel)(exclusiveOption.id)
24755
+ };
24756
+ }, [exclusiveOption, renderLabel, _renderLabel]);
24757
+ const isExclusiveSelected = React77.useMemo(() => {
24758
+ if (!exclusiveOption) {
24759
+ return false;
24760
+ }
24761
+ if (Array.isArray(value)) {
24762
+ return value.includes(exclusiveOption.id);
24763
+ }
24764
+ return value === exclusiveOption.id;
24765
+ }, [exclusiveOption, value]);
24700
24766
  const getOptionsLabeled = React77.useCallback(
24701
24767
  (options2, inputValue2 = "") => {
24702
24768
  const searchValue = escapeRegExp2(inputValue2.trim());
@@ -24898,28 +24964,43 @@ var Autocomplete = function Autocomplete2({
24898
24964
  onChange && onChange(event, newValue);
24899
24965
  onClosePopoverAfterSelect(newValue, newFilteredOptions);
24900
24966
  };
24901
- const onSelectValueMultiple = (newValue, value2, event) => {
24967
+ const onSelectValueMultiple = (newValue, value2, event, options2) => {
24902
24968
  if (!onChange) {
24903
24969
  return;
24904
24970
  }
24905
24971
  let newValues = [];
24906
- if (value2.includes(newValue)) {
24972
+ const exclusiveCurrentlySelected = exclusiveOption && value2.includes(exclusiveOption.id);
24973
+ const selectingExclusive = exclusiveOption && newValue === exclusiveOption.id;
24974
+ if (selectingExclusive && !value2.includes(newValue)) {
24975
+ newValues = [newValue];
24976
+ } else if (value2.includes(newValue)) {
24907
24977
  newValues = value2.filter((v) => v !== newValue);
24908
24978
  } else if (newValue) {
24909
24979
  newValues = [...value2, newValue];
24980
+ if (exclusiveCurrentlySelected) {
24981
+ newValues = newValues.filter((v) => v !== exclusiveOption.id);
24982
+ }
24910
24983
  }
24911
24984
  onChange(event, newValues);
24912
- onClosePopoverAfterSelect(newValues);
24985
+ onClosePopoverAfterSelect(
24986
+ newValues,
24987
+ void 0,
24988
+ options2
24989
+ );
24913
24990
  };
24914
- const onSelectValueSingle = (newValue, event) => {
24991
+ const onSelectValueSingle = (newValue, event, options2) => {
24915
24992
  if (!onChange) {
24916
24993
  return;
24917
24994
  }
24918
24995
  onChange(event, newValue);
24919
- onClosePopoverAfterSelect(newValue);
24996
+ onClosePopoverAfterSelect(
24997
+ newValue,
24998
+ void 0,
24999
+ options2
25000
+ );
24920
25001
  };
24921
- const onClosePopoverAfterSelect = (selectedValue, newFilteredOptions) => {
24922
- if (closeOnSelect) {
25002
+ const onClosePopoverAfterSelect = (selectedValue, newFilteredOptions, options2) => {
25003
+ if (closeOnSelect || options2?.forceClose) {
24923
25004
  closePopover();
24924
25005
  } else {
24925
25006
  setNextIndexByValue(selectedValue, newFilteredOptions);
@@ -24930,10 +25011,22 @@ var Autocomplete = function Autocomplete2({
24930
25011
  if (!onChange) {
24931
25012
  return;
24932
25013
  }
25014
+ const isSelectingExclusiveOption = !!exclusiveOption && option.id === exclusiveOption.id && (!Array.isArray(value) || !value.includes(option.id));
25015
+ if (isSelectingExclusiveOption) {
25016
+ setInputValue("");
25017
+ setDirty(false);
25018
+ setPlaceholder(textFieldProps?.placeholder ?? "");
25019
+ setFilteredOptions(getOptionsLabeled([...options]));
25020
+ onSearch && onSearch("");
25021
+ }
24933
25022
  if (Array.isArray(value)) {
24934
- onSelectValueMultiple(option.id, value, event);
25023
+ onSelectValueMultiple(option.id, value, event, {
25024
+ forceClose: isSelectingExclusiveOption
25025
+ });
24935
25026
  } else {
24936
- onSelectValueSingle(option.id, event);
25027
+ onSelectValueSingle(option.id, event, {
25028
+ forceClose: isSelectingExclusiveOption
25029
+ });
24937
25030
  }
24938
25031
  setPlaceholder(textFieldProps?.placeholder ?? "");
24939
25032
  };
@@ -25013,7 +25106,9 @@ var Autocomplete = function Autocomplete2({
25013
25106
  setInputValue,
25014
25107
  placeholder,
25015
25108
  size,
25016
- onRemoveValue: onRemoveInputValue
25109
+ onRemoveValue: onRemoveInputValue,
25110
+ exclusiveOptionSelected: !!multiple && isExclusiveSelected,
25111
+ exclusiveOptionLabel: isExclusiveSelected ? labeledExclusiveOption?.label : void 0
25017
25112
  }
25018
25113
  ),
25019
25114
  /* @__PURE__ */ jsx137(
@@ -25031,7 +25126,9 @@ var Autocomplete = function Autocomplete2({
25031
25126
  highlightedIndex,
25032
25127
  inputContainerRef: anchorRef,
25033
25128
  onAddSelectedValue: handleSelectValue,
25034
- onClickAwayPopover
25129
+ onClickAwayPopover,
25130
+ exclusiveOption: labeledExclusiveOption,
25131
+ isExclusiveSelected
25035
25132
  }
25036
25133
  )
25037
25134
  ] });