@synerise/ds-autocomplete 1.2.48 → 1.2.50

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
@@ -3,6 +3,14 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [1.2.50](https://github.com/Synerise/synerise-design/compare/@synerise/ds-autocomplete@1.2.49...@synerise/ds-autocomplete@1.2.50) (2026-07-16)
7
+
8
+ **Note:** Version bump only for package @synerise/ds-autocomplete
9
+
10
+ ## [1.2.49](https://github.com/Synerise/synerise-design/compare/@synerise/ds-autocomplete@1.2.48...@synerise/ds-autocomplete@1.2.49) (2026-07-09)
11
+
12
+ **Note:** Version bump only for package @synerise/ds-autocomplete
13
+
6
14
  ## [1.2.48](https://github.com/Synerise/synerise-design/compare/@synerise/ds-autocomplete@1.2.47...@synerise/ds-autocomplete@1.2.48) (2026-06-17)
7
15
 
8
16
  **Note:** Version bump only for package @synerise/ds-autocomplete
@@ -1,7 +1,10 @@
1
- import { AutoComplete as AntdAutoComplete } from 'antd';
2
- import { FC } from 'react';
1
+ import { default as React } from 'react';
3
2
  import { AutocompleteProps } from './Autocomplete.types';
4
- declare const Autocomplete: FC<AutocompleteProps> & {
5
- Option: typeof AntdAutoComplete.Option;
3
+ declare const Autocomplete: {
4
+ ({ className, style, label, description, errorText, disabled, error, handleInputRef, getPopupContainer, autoResize, readOnly, tooltip, tooltipConfig, icon1, icon1Tooltip, icon2, icon2Tooltip, options, children, value, defaultValue, placeholder, allowClear, autoFocus, maxLength, id, defaultActiveFirstOption, notFoundContent, placement, open, defaultOpen, onDropdownVisibleChange, onChange, onSearch, filterOption, onSelect, onFocus, onBlur, }: AutocompleteProps): React.JSX.Element;
5
+ Option: {
6
+ (_props: import('./Option').OptionProps): null;
7
+ displayName: string;
8
+ };
6
9
  };
7
10
  export default Autocomplete;
@@ -1,16 +1,18 @@
1
- import { jsx, Fragment, jsxs } from "react/jsx-runtime";
2
- import { AutoComplete } from "antd";
3
- import { useRef, useEffect, useCallback, useMemo } from "react";
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
+ import { useRef, useState, useMemo, useCallback, useEffect } from "react";
3
+ import Dropdown from "@synerise/ds-dropdown";
4
4
  import FormField from "@synerise/ds-form-field";
5
- import { AutosizeWrapper } from "@synerise/ds-input";
5
+ import { useAutosizeWidth, SIZER_STYLE } from "@synerise/ds-input";
6
6
  import Tooltip from "@synerise/ds-tooltip";
7
- import { useResizeObserver } from "@synerise/ds-utils";
8
- import { IconWrapper, AutocompleteWrapper, ComponentWrapper } from "./Autocomplete.styles.js";
7
+ import { IconWrapper, AutocompleteWrapper, ComponentWrapper, InputContainer, NativeInput, ClearButton } from "./Autocomplete.styles.js";
8
+ import AutocompleteDropdown from "./AutocompleteDropdown/AutocompleteDropdown.js";
9
+ import { Option } from "./Option.js";
9
10
  import { getIconsWidth } from "./utils/getIconsWidth.js";
10
- import "./style/index.css";
11
+ import { getOptionsFromChildren } from "./utils/getOptionsFromChildren.js";
11
12
  const AUTOSIZE_EXTRA_WIDTH = 27;
12
13
  const Autocomplete = ({
13
14
  className,
15
+ style,
14
16
  label,
15
17
  description,
16
18
  errorText,
@@ -26,67 +28,184 @@ const Autocomplete = ({
26
28
  icon1Tooltip,
27
29
  icon2,
28
30
  icon2Tooltip,
29
- ...rest
31
+ options,
32
+ children,
33
+ value,
34
+ defaultValue,
35
+ placeholder,
36
+ allowClear,
37
+ autoFocus,
38
+ maxLength,
39
+ id,
40
+ defaultActiveFirstOption = true,
41
+ notFoundContent,
42
+ placement = "bottomLeft",
43
+ open,
44
+ defaultOpen,
45
+ onDropdownVisibleChange,
46
+ onChange,
47
+ onSearch,
48
+ filterOption,
49
+ onSelect,
50
+ onFocus,
51
+ onBlur
30
52
  }) => {
31
- const scrollLeftRef = useRef(0);
32
- const antSelectRef = useRef(null);
33
53
  const inputRef = useRef(null);
34
- const autosizeRef = useRef(null);
35
- const autocompleteInputRef = useRef(null);
36
- const elementRef = useRef(null);
37
- useEffect(() => {
38
- handleInputRef && handleInputRef(antSelectRef);
39
- }, [antSelectRef, handleInputRef]);
40
- useEffect(() => {
41
- if (autosizeRef.current) {
42
- autocompleteInputRef.current = autosizeRef.current.inputWrapperRef.current;
43
- inputRef.current = autosizeRef.current.inputRef.current;
54
+ const externalHandleRef = useRef(null);
55
+ const skipOpenOnFocusRef = useRef(false);
56
+ const isDisabled = !!(readOnly || disabled);
57
+ const isControlledOpen = open !== void 0;
58
+ const [internalOpen, setInternalOpen] = useState(!!defaultOpen);
59
+ const isOpen = isControlledOpen ? !!open : internalOpen;
60
+ const [internalValue, setInternalValue] = useState(typeof defaultValue === "string" ? defaultValue : "");
61
+ const currentValue = value !== void 0 ? value : internalValue;
62
+ const resolvedOptions = useMemo(() => {
63
+ if (options && options.length > 0) {
64
+ return options;
44
65
  }
45
- }, []);
46
- const getParentNode = (triggerNode) => {
47
- return triggerNode.parentNode;
48
- };
49
- const stretchToFit = autoResize && autoResize !== true && Boolean(autoResize.stretchToFit);
50
- const placeholderString = typeof rest.placeholder === "string" ? rest.placeholder : void 0;
51
- const handlePreAutosize = useCallback(() => {
52
- scrollLeftRef.current = inputRef.current?.scrollLeft || 0;
53
- autocompleteInputRef.current && autocompleteInputRef.current.style.removeProperty("max-width");
54
- }, []);
55
- const handleAutosize = useCallback(() => {
56
- const parentRect = elementRef.current && elementRef.current.getBoundingClientRect();
57
- if (stretchToFit && autocompleteInputRef.current && parentRect?.width) {
58
- autocompleteInputRef.current.style.maxWidth = `${parentRect?.width + 1}px`;
59
- inputRef.current && inputRef.current.scrollTo(scrollLeftRef.current, 0);
66
+ return getOptionsFromChildren(children);
67
+ }, [options, children]);
68
+ const displayedOptions = useMemo(() => {
69
+ const query = currentValue;
70
+ if (!filterOption || !query) {
71
+ return resolvedOptions;
60
72
  }
61
- }, [stretchToFit]);
62
- const handleWrapperResize = useCallback(() => {
63
- handlePreAutosize();
64
- handleAutosize();
65
- }, [handleAutosize, handlePreAutosize]);
66
- const transformRef = useCallback((element) => {
67
- autocompleteInputRef.current = element;
68
- return element.querySelector("input");
69
- }, []);
70
- useResizeObserver(elementRef, handleWrapperResize);
73
+ const match = typeof filterOption === "function" ? filterOption : (input, option) => {
74
+ const optionLabel = typeof option.label === "string" ? option.label : "";
75
+ return `${option.value} ${optionLabel}`.toLowerCase().includes(input.toLowerCase());
76
+ };
77
+ return resolvedOptions.filter((option) => match(query, option));
78
+ }, [filterOption, resolvedOptions, currentValue]);
79
+ const setOpen = useCallback((nextOpen) => {
80
+ if (isDisabled) {
81
+ return;
82
+ }
83
+ if (!isControlledOpen) {
84
+ setInternalOpen(nextOpen);
85
+ }
86
+ onDropdownVisibleChange && onDropdownVisibleChange(nextOpen);
87
+ }, [isControlledOpen, isDisabled, onDropdownVisibleChange]);
88
+ const handleSelect = useCallback((selectedValue) => {
89
+ if (value === void 0) {
90
+ setInternalValue(selectedValue);
91
+ if (inputRef.current) {
92
+ inputRef.current.value = selectedValue;
93
+ }
94
+ }
95
+ onSelect && onSelect(selectedValue);
96
+ onChange && onChange(selectedValue);
97
+ setOpen(false);
98
+ skipOpenOnFocusRef.current = true;
99
+ inputRef.current && inputRef.current.focus();
100
+ }, [onChange, onSelect, setOpen, value]);
101
+ const handleChange = useCallback((event) => {
102
+ const nextValue = event.currentTarget.value;
103
+ if (value === void 0) {
104
+ setInternalValue(nextValue);
105
+ }
106
+ onSearch && onSearch(nextValue);
107
+ onChange && onChange(nextValue);
108
+ if (!isOpen) {
109
+ setOpen(true);
110
+ }
111
+ }, [isOpen, onChange, onSearch, setOpen, value]);
112
+ const handleFocus = useCallback((event) => {
113
+ onFocus && onFocus(event);
114
+ if (skipOpenOnFocusRef.current) {
115
+ skipOpenOnFocusRef.current = false;
116
+ return;
117
+ }
118
+ setOpen(true);
119
+ }, [onFocus, setOpen]);
120
+ const handleClick = useCallback(() => {
121
+ if (!isOpen) {
122
+ setOpen(true);
123
+ }
124
+ }, [isOpen, setOpen]);
125
+ const handleClear = useCallback(() => {
126
+ if (value === void 0) {
127
+ setInternalValue("");
128
+ if (inputRef.current) {
129
+ inputRef.current.value = "";
130
+ }
131
+ }
132
+ onSearch && onSearch("");
133
+ onChange && onChange("");
134
+ inputRef.current && inputRef.current.focus();
135
+ }, [onChange, onSearch, value]);
136
+ const handleKeyDown = useCallback((event) => {
137
+ if (event.key === "Enter" && isOpen && defaultActiveFirstOption !== false) {
138
+ const firstEnabled = displayedOptions.find((option) => !option.disabled);
139
+ if (firstEnabled) {
140
+ event.preventDefault();
141
+ handleSelect(firstEnabled.value);
142
+ }
143
+ }
144
+ }, [isOpen, defaultActiveFirstOption, displayedOptions, handleSelect]);
145
+ useEffect(() => {
146
+ externalHandleRef.current = {
147
+ focus: () => inputRef.current?.focus(),
148
+ blur: () => inputRef.current?.blur(),
149
+ input: inputRef.current
150
+ };
151
+ handleInputRef && handleInputRef(externalHandleRef);
152
+ }, [handleInputRef]);
153
+ const getParentNode = useCallback((triggerNode) => triggerNode.parentNode, []);
71
154
  const iconCount = +!!icon1 + +!!icon2;
155
+ const placeholderString = typeof placeholder === "string" ? placeholder : void 0;
156
+ const {
157
+ sizerRef,
158
+ containerRef
159
+ } = useAutosizeWidth({
160
+ value: currentValue,
161
+ placeholder: placeholderString,
162
+ extraWidth: AUTOSIZE_EXTRA_WIDTH + getIconsWidth(iconCount),
163
+ inputRef
164
+ });
72
165
  const handleIconsClick = useCallback(() => {
73
- antSelectRef.current?.focus();
166
+ inputRef.current && inputRef.current.focus();
74
167
  }, []);
75
168
  const icons = useMemo(() => {
169
+ if (!icon1 && !icon2) {
170
+ return null;
171
+ }
76
172
  const icon1WithTooltip = icon1Tooltip ? /* @__PURE__ */ jsx(Tooltip, { title: icon1Tooltip, children: icon1 }) : icon1;
77
173
  const icon2WithTooltip = icon2Tooltip ? /* @__PURE__ */ jsx(Tooltip, { title: icon2Tooltip, children: icon2 }) : icon2;
78
- return /* @__PURE__ */ jsx(Fragment, { children: (icon1WithTooltip || icon2WithTooltip) && /* @__PURE__ */ jsxs(IconWrapper, { onClick: handleIconsClick, children: [
174
+ return /* @__PURE__ */ jsxs(IconWrapper, { onClick: handleIconsClick, children: [
79
175
  icon1WithTooltip,
80
176
  " ",
81
177
  icon2WithTooltip
82
- ] }) });
178
+ ] });
83
179
  }, [handleIconsClick, icon1, icon2, icon1Tooltip, icon2Tooltip]);
84
- return /* @__PURE__ */ jsx(AutocompleteWrapper, { ref: elementRef, autoResize, className: `ds-autocomplete ${className || ""}`, children: /* @__PURE__ */ jsx(FormField, { label, tooltip, tooltipConfig, description, errorText, children: /* @__PURE__ */ jsx(ComponentWrapper, { readOnly, error: !!errorText || error, iconCount, children: /* @__PURE__ */ jsxs(AutosizeWrapper, { autoResize: !!autoResize, value: rest.value, placeholder: placeholderString, transformRef, ref: autosizeRef, extraWidth: AUTOSIZE_EXTRA_WIDTH + getIconsWidth(iconCount), preAutosize: handlePreAutosize, onAutosize: handleAutosize, children: [
85
- /* @__PURE__ */ jsx(AutoComplete, { ...rest, disabled: readOnly || disabled, dropdownClassName: "ds-autocomplete-dropdown ps__child--consume", getPopupContainer: getPopupContainer || getParentNode, ref: antSelectRef, "data-testid": "autocomplete-autosize-input" }),
86
- icons
87
- ] }) }) }) });
180
+ const showClear = !!allowClear && !isDisabled && currentValue !== "";
181
+ const hasDropdownContent = displayedOptions.length > 0 || notFoundContent !== void 0 && notFoundContent !== null;
182
+ return /* @__PURE__ */ jsx(AutocompleteWrapper, { autoResize, style, className: `ds-autocomplete ${className || ""}`, children: /* @__PURE__ */ jsx(FormField, { label, tooltip, tooltipConfig, description, errorText, id, children: /* @__PURE__ */ jsx(ComponentWrapper, { readOnly, error: !!errorText || error, iconCount, children: /* @__PURE__ */ jsx(
183
+ Dropdown,
184
+ {
185
+ open: isOpen && hasDropdownContent,
186
+ onOpenChange: setOpen,
187
+ disabled: isDisabled,
188
+ placement,
189
+ size: "match-trigger",
190
+ trigger: [],
191
+ getPopupContainer: getPopupContainer || getParentNode,
192
+ overlayClassName: "ds-autocomplete-dropdown ps__child--consume",
193
+ asChild: true,
194
+ overlay: /* @__PURE__ */ jsx(AutocompleteDropdown, { options: displayedOptions, notFoundContent, onSelect: handleSelect }),
195
+ children: /* @__PURE__ */ jsxs(InputContainer, { ref: containerRef, autoResize, children: [
196
+ /* @__PURE__ */ jsx(NativeInput, { ref: inputRef, iconCount, role: "combobox", "aria-expanded": isOpen, "aria-autocomplete": "list", autoComplete: "off", "data-testid": "autocomplete-autosize-input", id, ...value !== void 0 ? {
197
+ value
198
+ } : {
199
+ defaultValue
200
+ }, placeholder: placeholderString, disabled: isDisabled, autoFocus, maxLength, onChange: handleChange, onClick: handleClick, onKeyDown: handleKeyDown, onFocus: handleFocus, onBlur }),
201
+ autoResize && /* @__PURE__ */ jsx("span", { ref: sizerRef, style: SIZER_STYLE, "aria-hidden": true }),
202
+ showClear && /* @__PURE__ */ jsx(ClearButton, { type: "button", "aria-label": "clear", "data-testid": "autocomplete-clear", onClick: handleClear, children: "×" }),
203
+ icons
204
+ ] })
205
+ }
206
+ ) }) }) });
88
207
  };
89
- Autocomplete.Option = AutoComplete.Option;
208
+ Autocomplete.Option = Option;
90
209
  export {
91
210
  Autocomplete as default
92
211
  };
@@ -1,8 +1,15 @@
1
1
  import { AutoResizeProp } from '@synerise/ds-input';
2
+ export declare const InputContainer: import('styled-components').StyledComponent<"div", any, {
3
+ autoResize?: AutoResizeProp;
4
+ }, never>;
5
+ export declare const NativeInput: import('styled-components').StyledComponent<"input", any, {
6
+ iconCount?: number;
7
+ }, never>;
2
8
  export declare const AutocompleteWrapper: import('styled-components').StyledComponent<"div", any, {
3
9
  autoResize?: AutoResizeProp;
4
10
  }, never>;
5
11
  export declare const IconWrapper: import('styled-components').StyledComponent<"div", any, {}, never>;
12
+ export declare const ClearButton: import('styled-components').StyledComponent<"button", any, {}, never>;
6
13
  export declare const ComponentWrapper: import('styled-components').StyledComponent<"div", any, {
7
14
  error?: boolean;
8
15
  readOnly?: boolean;
@@ -1,43 +1,59 @@
1
1
  import styled, { css } from "styled-components";
2
- import { autoresizeConfObjToCss } from "@synerise/ds-input/dist/Input.styles";
3
2
  import { ICON_OFFSET, ICON_GAP } from "./Autocomplete.const.js";
4
3
  import { getIconsWidth } from "./utils/getIconsWidth.js";
5
- const active = () => css(["transition:ease-in-out all 0.2s,width 0s,min-width 0s,max-width 0s;box-shadow:inset 0 0 0 1px ", ";border:1px solid ", ";background-color:", ";"], (props) => props.theme.palette["blue-600"], (props) => props.theme.palette["blue-600"], (props) => props.theme.palette["blue-050"]);
6
- const error = () => css(["transition:ease-in-out all 0.2s,width 0s,min-width 0s,max-width 0s;box-shadow:inset 0 0 0 1px ", ";background:", ";border:1px solid ", ";"], (props) => props.theme.palette["red-600"], (props) => props.theme.palette["red-050"], (props) => props.theme.palette["red-600"]);
7
- const readonly = () => css(["background-color:", ";color:", ";input{cursor:auto;}"], (props) => props.theme.palette.white, (props) => props.theme.palette["grey-700"]);
4
+ const baseTransition = /* @__PURE__ */ css(["transition:ease-in-out all 0.2s,width 0s,min-width 0s,max-width 0s;"]);
5
+ const active = () => css(["", ";box-shadow:inset 0 0 0 1px ", ";border:1px solid ", ";background-color:", ";"], baseTransition, (props) => props.theme.palette["blue-600"], (props) => props.theme.palette["blue-600"], (props) => props.theme.palette["blue-050"]);
6
+ const errorStyle = () => css(["", ";box-shadow:inset 0 0 0 1px ", ";background:", ";border:1px solid ", ";"], baseTransition, (props) => props.theme.palette["red-600"], (props) => props.theme.palette["red-050"], (props) => props.theme.palette["red-600"]);
7
+ const readonly = () => css(["background-color:", ";color:", ";cursor:auto;"], (props) => props.theme.palette.white, (props) => props.theme.palette["grey-700"]);
8
+ const InputContainer = /* @__PURE__ */ styled.div.withConfig({
9
+ displayName: "Autocompletestyles__InputContainer",
10
+ componentId: "sc-10de6ms-0"
11
+ })(["position:relative;display:inline-flex;align-items:center;box-sizing:border-box;width:", ";", ""], (props) => props.autoResize ? "auto" : "100%", (props) => {
12
+ const ar = props.autoResize;
13
+ if (!ar || ar === true) {
14
+ return "";
15
+ }
16
+ let maxWidth = "";
17
+ if (ar.maxWidth) {
18
+ maxWidth = `max-width: ${ar.maxWidth};`;
19
+ } else if (ar.stretchToFit) {
20
+ maxWidth = "max-width: 100%;";
21
+ }
22
+ return css(["min-width:", ";", ""], ar.minWidth, maxWidth);
23
+ });
24
+ const NativeInput = /* @__PURE__ */ styled.input.withConfig({
25
+ displayName: "Autocompletestyles__NativeInput",
26
+ componentId: "sc-10de6ms-1"
27
+ })(["box-sizing:border-box;width:100%;height:32px;margin:0;&&{padding:0 10px;padding-right:", ";}border:1px solid ", ";border-radius:3px;background-color:", ";color:", ";font-family:inherit;font-size:13px;line-height:1.54;font-feature-settings:'tnum';outline:none;", ";&::placeholder{color:", ";}&:hover:not(:disabled){border-color:", ";}&:disabled{background-color:", ";color:", ";cursor:not-allowed;}&:focus{", ";&:hover{", ";}}"], (props) => `${getIconsWidth(props.iconCount || 0) + 10}px`, (props) => props.theme.palette["grey-300"], (props) => props.theme.palette.white, (props) => props.theme.palette["grey-700"], baseTransition, (props) => props.theme.palette["grey-500"], (props) => props.theme.palette["grey-400"], (props) => props.theme.palette["grey-050"], (props) => props.theme.palette["grey-400"], active(), active());
8
28
  const AutocompleteWrapper = /* @__PURE__ */ styled.div.withConfig({
9
29
  displayName: "Autocompletestyles__AutocompleteWrapper",
10
- componentId: "sc-10de6ms-0"
11
- })(["input{font-feature-settings:'tnum';}.ant-select-auto-complete{width:", ";", ";grid-area:1 / 1;}.ant-select > span{position:absolute;left:0;top:0;}.ant-select-dropdown{.ant-select-selection__rendered{margin:0;}.ant-select-selection:hover .ant-select-selection__rendered{margin-right:10px;}.ant-select-selection__clear{font-size:15px;color:", ";width:16px;height:16px;margin-top:-7px;}&.ant-select:not(.ant-select-no-arrow) .ant-select-selection__clear{right:12px;&:hover{color:", ";}}.ant-select-dropdown-menu-item{font-weight:normal;strong{font-weight:500;}}}.ant-select-selection-search-input{padding:0;padding-right:10px;}"], (props) => props.autoResize ? "100%" : "200px", (props) => autoresizeConfObjToCss({
12
- ...props,
13
- boxSizing: "border-box"
14
- }), (props) => props.theme.palette["grey-600"], (props) => props.theme.palette["grey-700"]);
30
+ componentId: "sc-10de6ms-2"
31
+ })(["width:", ";"], (props) => props.autoResize ? "100%" : "200px");
15
32
  const IconWrapper = /* @__PURE__ */ styled.div.withConfig({
16
33
  displayName: "Autocompletestyles__IconWrapper",
17
- componentId: "sc-10de6ms-1"
34
+ componentId: "sc-10de6ms-3"
18
35
  })(["position:absolute;right:", "px;top:0;display:flex;bottom:0;align-items:center;gap:", "px;z-index:5;"], ICON_OFFSET, ICON_GAP);
36
+ const ClearButton = /* @__PURE__ */ styled.button.withConfig({
37
+ displayName: "Autocompletestyles__ClearButton",
38
+ componentId: "sc-10de6ms-4"
39
+ })(["position:absolute;right:8px;top:50%;transform:translateY(-50%);display:flex;align-items:center;justify-content:center;width:16px;height:16px;padding:0;border:none;background:transparent;color:", ";font-size:15px;line-height:1;cursor:pointer;z-index:6;&:hover{color:", ";}"], (props) => props.theme.palette["grey-600"], (props) => props.theme.palette["grey-700"]);
19
40
  const ComponentWrapper = /* @__PURE__ */ styled.div.withConfig({
20
41
  displayName: "Autocompletestyles__ComponentWrapper",
21
- componentId: "sc-10de6ms-2"
22
- })(["&&&{", ";.ant-select-auto-complete{", "}}}"], (props) => props.iconCount && `
23
- position: relative;
24
- display: inline-block;
25
- & {
26
- .ant-select .ant-select-selector .ant-select-selection-search {
27
- right: ${getIconsWidth(props.iconCount)}px;
28
- }
29
- }
30
- `, (props) => {
42
+ componentId: "sc-10de6ms-5"
43
+ })(["&&&{", ";", "}"], (props) => props.iconCount ? css(["position:relative;"]) : "", (props) => {
31
44
  if (props.readOnly) {
32
- return css([".ant-select-selector{&:hover{", "}", "}"], readonly(), readonly());
45
+ return css(["", "{", ";&:hover{", ";}}"], NativeInput, readonly(), readonly());
33
46
  }
34
47
  if (props.error) {
35
- return css([".ant-select-selector{&:hover{", "}", "}"], error(), error());
48
+ return css(["", "{", ";&:hover{", ";}}"], NativeInput, errorStyle(), errorStyle());
36
49
  }
37
- return css(["&.ant-select{.ant-select-selector{padding:0 10px;}.ant-input{transition:ease-in-out all 0.3s,width 0s,min-width 0s,max-width 0s;&:focus{", " &:hover{", "}}}}"], active(), active());
50
+ return "";
38
51
  });
39
52
  export {
40
53
  AutocompleteWrapper,
54
+ ClearButton,
41
55
  ComponentWrapper,
42
- IconWrapper
56
+ IconWrapper,
57
+ InputContainer,
58
+ NativeInput
43
59
  };
@@ -1,17 +1,76 @@
1
- import { AutoCompleteProps as OriginalProps, RefSelectProps } from 'antd';
2
- import { MutableRefObject, ReactNode } from 'react';
1
+ import { CSSProperties, MutableRefObject, ReactNode } from 'react';
2
+ import { DropdownPlacement } from '@synerise/ds-dropdown';
3
3
  import { FormFieldCommonProps } from '@synerise/ds-form-field';
4
4
  import { AutoResizeProp } from '@synerise/ds-input';
5
- export type OverrideProps = FormFieldCommonProps & {
5
+ export type AutocompleteOption = {
6
+ value: string;
7
+ label?: ReactNode;
8
+ disabled?: boolean;
9
+ };
10
+ /**
11
+ * Imperative handle exposed through `handleInputRef`. Native replacement for the
12
+ * antd `RefSelectProps` — only the focus affordance the icon slots rely on is
13
+ * guaranteed, alongside the underlying `<input>` element.
14
+ */
15
+ export type AutocompleteInputHandle = {
16
+ focus: () => void;
17
+ blur: () => void;
18
+ input: HTMLInputElement | null;
19
+ };
20
+ export type AutocompleteProps = FormFieldCommonProps & {
6
21
  className?: string;
22
+ /** Inline style applied to the outer wrapper (e.g. `{ width: 350 }`). */
23
+ style?: CSSProperties;
7
24
  icon1?: ReactNode;
8
25
  icon1Tooltip?: ReactNode;
9
26
  icon2?: ReactNode;
10
27
  icon2Tooltip?: ReactNode;
11
28
  error?: boolean;
12
- getPopupContainer?: (node: HTMLElement) => HTMLElement;
13
29
  readOnly?: boolean;
14
- handleInputRef?: (ref: MutableRefObject<RefSelectProps | null>) => void;
15
30
  autoResize?: AutoResizeProp;
31
+ /**
32
+ * Container the floating dropdown is mounted into. Defaults to the trigger's
33
+ * `parentNode` (mirrors the legacy antd `getParentNode`).
34
+ */
35
+ getPopupContainer?: (node: HTMLElement) => HTMLElement;
36
+ handleInputRef?: (ref: MutableRefObject<AutocompleteInputHandle | null>) => void;
37
+ /** Options shown in the dropdown. The component does NOT filter them. */
38
+ options?: AutocompleteOption[];
39
+ /** Declarative options via `Autocomplete.Option` children. */
40
+ children?: ReactNode;
41
+ value?: string;
42
+ defaultValue?: string;
43
+ placeholder?: ReactNode;
44
+ disabled?: boolean;
45
+ allowClear?: boolean;
46
+ autoFocus?: boolean;
47
+ maxLength?: number;
48
+ id?: string;
49
+ /**
50
+ * antd parity. When `true` (default), pressing Enter while the dropdown is open —
51
+ * before arrow-navigating into the list — selects the first enabled option. Set
52
+ * `false` to require explicit arrow-key navigation before Enter selects.
53
+ */
54
+ defaultActiveFirstOption?: boolean;
55
+ /** Rendered inside the dropdown when there are no options. */
56
+ notFoundContent?: ReactNode;
57
+ placement?: DropdownPlacement;
58
+ /** Controlled dropdown visibility. */
59
+ open?: boolean;
60
+ /** Initial open state when uncontrolled. */
61
+ defaultOpen?: boolean;
62
+ onDropdownVisibleChange?: (open: boolean) => void;
63
+ onChange?: (value: string) => void;
64
+ /** Fired on every input keystroke. */
65
+ onSearch?: (value: string) => void;
66
+ /**
67
+ * Optional client-side filtering (antd-parity). Off by default (consumers
68
+ * filter server-side via `onSearch`). `true` = default match on the option's
69
+ * value / string label; a function `(inputValue, option) => boolean` = custom.
70
+ */
71
+ filterOption?: boolean | ((inputValue: string, option: AutocompleteOption) => boolean);
72
+ /** Fired when an option is chosen. */
73
+ onSelect?: (value: string) => void;
74
+ onFocus?: (event: React.FocusEvent<HTMLInputElement>) => void;
75
+ onBlur?: (event: React.FocusEvent<HTMLInputElement>) => void;
16
76
  };
17
- export type AutocompleteProps = OverrideProps & Omit<OriginalProps, 'tagRender' | 'fieldNames' | 'filterSort' | 'filterOption' | 'tokenSeparators' | 'transitionName' | 'showArrow' | 'animation' | 'searchValue' | 'showArrow' | 'listItemHeight' | 'menuItemSelectedIcon' | 'maxTagCount' | 'maxTagPlaceholder' | 'maxTagTextLength' | 'fieldNames' | 'filterOption' | 'backfill' | 'bordered' | 'choiceTransitionName' | 'showSearch'>;
@@ -0,0 +1,4 @@
1
+ import { default as React } from 'react';
2
+ import { AutocompleteDropdownProps } from './AutocompleteDropdown.types';
3
+ declare const AutocompleteDropdown: ({ options, notFoundContent, visibleRows, rowHeight, onSelect, }: AutocompleteDropdownProps) => React.JSX.Element;
4
+ export default AutocompleteDropdown;
@@ -0,0 +1,25 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import Scrollbar from "@synerise/ds-scrollbar";
3
+ import { DropdownWrapper, NotFound, ScrollList, Inner, ListItem } from "./AutocompleteDropdown.style.js";
4
+ const DEFAULT_ROW_HEIGHT = 32;
5
+ const DEFAULT_VISIBLE_ROWS = 10;
6
+ const AutocompleteDropdown = ({
7
+ options,
8
+ notFoundContent,
9
+ visibleRows = DEFAULT_VISIBLE_ROWS,
10
+ rowHeight = DEFAULT_ROW_HEIGHT,
11
+ onSelect
12
+ }) => {
13
+ if (options.length === 0) {
14
+ return /* @__PURE__ */ jsx(DropdownWrapper, { children: /* @__PURE__ */ jsx(NotFound, { "data-testid": "autocomplete-not-found", children: notFoundContent }) });
15
+ }
16
+ const maxHeight = Math.min(visibleRows, options.length) * rowHeight;
17
+ return /* @__PURE__ */ jsx(DropdownWrapper, { children: /* @__PURE__ */ jsx(ScrollList, { children: /* @__PURE__ */ jsx(Scrollbar, { absolute: true, maxHeight, children: /* @__PURE__ */ jsx(Inner, { children: options.map((option) => /* @__PURE__ */ jsx(ListItem, { role: "option", "data-testid": "autocomplete-option", text: option.label ?? option.value, disabled: option.disabled, onClick: () => {
18
+ if (!option.disabled) {
19
+ onSelect(option.value);
20
+ }
21
+ } }, option.value)) }) }) }) });
22
+ };
23
+ export {
24
+ AutocompleteDropdown as default
25
+ };
@@ -0,0 +1,6 @@
1
+ import { StyledListItem } from '@synerise/ds-list-item';
2
+ export declare const DropdownWrapper: import('styled-components').StyledComponent<"div", any, {}, never>;
3
+ export declare const ScrollList: import('styled-components').StyledComponent<({ children, onClick, maxToShowItems, texts, ...htmlAttributes }: import('@synerise/ds-list-item').ListWrapperProps) => React.JSX.Element, any, {}, never>;
4
+ export declare const Inner: import('styled-components').StyledComponent<"div", any, {}, never>;
5
+ export declare const NotFound: import('styled-components').StyledComponent<"div", any, {}, never>;
6
+ export declare const ListItem: StyledListItem;
@@ -0,0 +1,31 @@
1
+ import styled from "styled-components";
2
+ import DSListItem, { ListWrapper } from "@synerise/ds-list-item";
3
+ const DropdownWrapper = /* @__PURE__ */ styled.div.withConfig({
4
+ displayName: "AutocompleteDropdownstyle__DropdownWrapper",
5
+ componentId: "sc-7kdjse-0"
6
+ })(["display:flex;flex-direction:column;align-items:stretch;justify-content:flex-start;min-width:200px;"]);
7
+ const ScrollList = /* @__PURE__ */ styled(ListWrapper).withConfig({
8
+ displayName: "AutocompleteDropdownstyle__ScrollList",
9
+ componentId: "sc-7kdjse-1"
10
+ })(["&&{padding-right:0;}"]);
11
+ const Inner = /* @__PURE__ */ styled.div.withConfig({
12
+ displayName: "AutocompleteDropdownstyle__Inner",
13
+ componentId: "sc-7kdjse-2"
14
+ })(["padding-right:8px;"]);
15
+ const NotFound = /* @__PURE__ */ styled.div.withConfig({
16
+ displayName: "AutocompleteDropdownstyle__NotFound",
17
+ componentId: "sc-7kdjse-3"
18
+ })(["display:flex;align-items:center;justify-content:center;padding:8px 12px;color:", ";font-weight:normal;"], ({
19
+ theme
20
+ }) => theme.palette["grey-600"]);
21
+ const ListItem = /* @__PURE__ */ styled(DSListItem).withConfig({
22
+ displayName: "AutocompleteDropdownstyle__ListItem",
23
+ componentId: "sc-7kdjse-4"
24
+ })(["min-width:auto;font-weight:normal;strong{font-weight:500;}"]);
25
+ export {
26
+ DropdownWrapper,
27
+ Inner,
28
+ ListItem,
29
+ NotFound,
30
+ ScrollList
31
+ };
@@ -0,0 +1,9 @@
1
+ import { ReactNode } from 'react';
2
+ import { AutocompleteOption } from '../Autocomplete.types';
3
+ export type AutocompleteDropdownProps = {
4
+ options: AutocompleteOption[];
5
+ notFoundContent?: ReactNode;
6
+ visibleRows?: number;
7
+ rowHeight?: number;
8
+ onSelect: (value: string) => void;
9
+ };
@@ -0,0 +1,15 @@
1
+ import { ReactNode } from 'react';
2
+ export type OptionProps = {
3
+ value: string;
4
+ disabled?: boolean;
5
+ children?: ReactNode;
6
+ };
7
+ /**
8
+ * Declarative option marker. It renders nothing on its own — `Autocomplete`
9
+ * reads its props (`value`, `children` → label) to build the internal options
10
+ * list. Kept for backwards compatibility with the antd `AutoComplete.Option` API.
11
+ */
12
+ export declare const Option: {
13
+ (_props: OptionProps): null;
14
+ displayName: string;
15
+ };
package/dist/Option.js ADDED
@@ -0,0 +1,5 @@
1
+ const Option = (_props) => null;
2
+ Option.displayName = "Autocomplete.Option";
3
+ export {
4
+ Option
5
+ };
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
- import { AutocompleteProps } from './Autocomplete.types';
1
+ import { AutocompleteInputHandle, AutocompleteOption, AutocompleteProps } from './Autocomplete.types';
2
+ import { OptionProps } from './Option';
2
3
  export { default } from './Autocomplete';
3
- export type { AutocompleteProps };
4
+ export type { AutocompleteProps, AutocompleteOption, AutocompleteInputHandle, OptionProps, };
@@ -0,0 +1,7 @@
1
+ import { ReactNode } from 'react';
2
+ import { AutocompleteOption } from '../Autocomplete.types';
3
+ /**
4
+ * Maps declarative `<Autocomplete.Option>` children to the internal option
5
+ * shape. Only direct `Option` children are considered; anything else is ignored.
6
+ */
7
+ export declare const getOptionsFromChildren: (children: ReactNode) => AutocompleteOption[];
@@ -0,0 +1,24 @@
1
+ import { Children, isValidElement } from "react";
2
+ import { Option } from "../Option.js";
3
+ const getOptionsFromChildren = (children) => {
4
+ const options = [];
5
+ Children.forEach(children, (child) => {
6
+ if (!isValidElement(child) || child.type !== Option) {
7
+ return;
8
+ }
9
+ const {
10
+ value,
11
+ disabled,
12
+ children: label
13
+ } = child.props;
14
+ options.push({
15
+ value,
16
+ disabled,
17
+ label
18
+ });
19
+ });
20
+ return options;
21
+ };
22
+ export {
23
+ getOptionsFromChildren
24
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@synerise/ds-autocomplete",
3
- "version": "1.2.48",
3
+ "version": "1.2.50",
4
4
  "description": "Autocomplete UI Component for the Synerise Design System",
5
5
  "license": "ISC",
6
6
  "repository": "Synerise/synerise-design",
@@ -41,17 +41,20 @@
41
41
  ],
42
42
  "types": "dist/index.d.ts",
43
43
  "dependencies": {
44
+ "@synerise/ds-dropdown": "^1.3.19",
44
45
  "@synerise/ds-form-field": "^1.3.23",
45
- "@synerise/ds-input": "^1.7.11",
46
+ "@synerise/ds-input": "^1.7.12",
47
+ "@synerise/ds-list-item": "^1.6.1",
48
+ "@synerise/ds-scrollbar": "^1.5.1",
49
+ "@synerise/ds-search": "^1.5.33",
46
50
  "@synerise/ds-tooltip": "^1.5.3",
47
51
  "@synerise/ds-utils": "^1.10.1"
48
52
  },
49
53
  "peerDependencies": {
50
54
  "@synerise/ds-core": "*",
51
- "antd": "4.24.16",
52
55
  "react": ">=16.9.0 <= 18.3.1",
53
56
  "styled-components": "^5.3.3",
54
57
  "vitest": "4"
55
58
  },
56
- "gitHead": "d8c64070f58f14e3fb1bfbcbf00d1e3b8fd51eb8"
59
+ "gitHead": "a81ab6519d49a3dea9c0cfebcdc9104cbb4f4226"
57
60
  }
File without changes
@@ -1 +0,0 @@
1
- .ant-select-auto-complete{box-sizing:border-box;margin:0;padding:0;color:#6a7580;font-size:13px;font-variant:tabular-nums;line-height:1.38;list-style:none;font-feature-settings:'tnum'}.ant-select-auto-complete .ant-select-clear{right:13px}.ant-select-single .ant-select-selector{display:flex}.ant-select-single .ant-select-selector .ant-select-selection-search{position:absolute;top:0;right:15px;bottom:0;left:15px}.ant-select-single .ant-select-selector .ant-select-selection-search-input{width:100%}.ant-select-single .ant-select-selector .ant-select-selection-item,.ant-select-single .ant-select-selector .ant-select-selection-placeholder{padding:0;line-height:30px;transition:all .3s,visibility 0s}.ant-select-single .ant-select-selector .ant-select-selection-item{position:relative;user-select:none}.ant-select-single .ant-select-selector .ant-select-selection-placeholder{transition:none;pointer-events:none}.ant-select-single .ant-select-selector .ant-select-selection-item::after,.ant-select-single .ant-select-selector .ant-select-selection-placeholder::after,.ant-select-single .ant-select-selector::after{display:inline-block;width:0;visibility:hidden;content:'\a0'}.ant-select-single.ant-select-show-arrow .ant-select-selection-search{right:28px}.ant-select-single.ant-select-show-arrow .ant-select-selection-item,.ant-select-single.ant-select-show-arrow .ant-select-selection-placeholder{padding-right:17px}.ant-select-single.ant-select-open .ant-select-selection-item{color:#b5bdc3}.ant-select-single:not(.ant-select-customize-input) .ant-select-selector{width:100%;height:32px;padding:0 15px}.ant-select-single:not(.ant-select-customize-input) .ant-select-selector .ant-select-selection-search-input{height:30px}.ant-select-single:not(.ant-select-customize-input) .ant-select-selector::after{line-height:30px}.ant-select-single.ant-select-customize-input .ant-select-selector::after{display:none}.ant-select-single.ant-select-customize-input .ant-select-selector .ant-select-selection-search{position:static;width:100%}.ant-select-single.ant-select-customize-input .ant-select-selector .ant-select-selection-placeholder{position:absolute;right:0;left:0;padding:0 15px}.ant-select-single.ant-select-customize-input .ant-select-selector .ant-select-selection-placeholder::after{display:none}.ant-select-single.ant-select-lg:not(.ant-select-customize-input) .ant-select-selector{height:40px}.ant-select-single.ant-select-lg:not(.ant-select-customize-input) .ant-select-selector .ant-select-selection-item,.ant-select-single.ant-select-lg:not(.ant-select-customize-input) .ant-select-selector .ant-select-selection-placeholder,.ant-select-single.ant-select-lg:not(.ant-select-customize-input) .ant-select-selector::after{line-height:38px}.ant-select-single.ant-select-lg:not(.ant-select-customize-input):not(.ant-select-customize-input) .ant-select-selection-search-input{height:38px}.ant-select-single.ant-select-sm:not(.ant-select-customize-input) .ant-select-selector{height:24px}.ant-select-single.ant-select-sm:not(.ant-select-customize-input) .ant-select-selector .ant-select-selection-item,.ant-select-single.ant-select-sm:not(.ant-select-customize-input) .ant-select-selector .ant-select-selection-placeholder,.ant-select-single.ant-select-sm:not(.ant-select-customize-input) .ant-select-selector::after{line-height:22px}.ant-select-single.ant-select-sm:not(.ant-select-customize-input):not(.ant-select-customize-input) .ant-select-selection-search-input{height:22px}.ant-select-single.ant-select-sm:not(.ant-select-customize-input) .ant-select-selection-search{right:7px;left:7px}.ant-select-single.ant-select-sm:not(.ant-select-customize-input) .ant-select-selector{padding:0 7px}.ant-select-single.ant-select-sm:not(.ant-select-customize-input).ant-select-show-arrow .ant-select-selection-search{right:26.5px}.ant-select-single.ant-select-sm:not(.ant-select-customize-input).ant-select-show-arrow .ant-select-selection-item,.ant-select-single.ant-select-sm:not(.ant-select-customize-input).ant-select-show-arrow .ant-select-selection-placeholder{padding-right:19.5px}.ant-select-single.ant-select-lg:not(.ant-select-customize-input) .ant-select-selector{padding:0 15px}.ant-select-selection-overflow{position:relative;display:flex;flex:auto;flex-wrap:wrap;max-width:100%}.ant-select-selection-overflow-item{flex:none;align-self:center;max-width:100%}.ant-select-multiple .ant-select-selector{display:flex;flex-wrap:wrap;align-items:center;padding:1px 4px}.ant-select-show-search.ant-select-multiple .ant-select-selector{cursor:text}.ant-select-disabled.ant-select-multiple .ant-select-selector{background:#f9fafb;cursor:not-allowed}.ant-select-multiple .ant-select-selector::after{display:inline-block;width:0;margin:2px 0;line-height:24px;visibility:hidden;content:'\a0'}.ant-select-multiple.ant-select-allow-clear .ant-select-selector,.ant-select-multiple.ant-select-show-arrow .ant-select-selector{padding-right:27px}.ant-select-multiple .ant-select-selection-item{position:relative;display:flex;flex:none;box-sizing:border-box;max-width:100%;height:24px;margin-top:2px;margin-bottom:2px;line-height:22px;background:#f3f5f6;border:1px solid #e9edee;border-radius:3px;cursor:default;transition:font-size .3s,line-height .3s,height .3s;user-select:none;margin-inline-end:4px;padding-inline-start:8px;padding-inline-end:4px}.ant-select-disabled.ant-select-multiple .ant-select-selection-item{color:#bfbfbf;border-color:#dbe0e3;cursor:not-allowed}.ant-select-multiple .ant-select-selection-item-content{display:inline-block;margin-right:4px;overflow:hidden;white-space:pre;text-overflow:ellipsis}.ant-select-multiple .ant-select-selection-item-remove{color:inherit;font-style:normal;line-height:0;text-align:center;text-transform:none;vertical-align:-.125em;text-rendering:optimizelegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;display:inline-flex;align-items:center;color:#232936;font-weight:700;font-size:10px;line-height:inherit;cursor:pointer}.ant-select-multiple .ant-select-selection-item-remove>*{line-height:1}.ant-select-multiple .ant-select-selection-item-remove svg{display:inline-block}.ant-select-multiple .ant-select-selection-item-remove::before{display:none}.ant-select-multiple .ant-select-selection-item-remove .ant-select-multiple .ant-select-selection-item-remove-icon{display:block}.ant-select-multiple .ant-select-selection-item-remove>.anticon{vertical-align:middle}.ant-select-multiple .ant-select-selection-item-remove:hover{color:rgba(0,0,0,.75)}.ant-select-multiple .ant-select-selection-overflow-item+.ant-select-selection-overflow-item .ant-select-selection-search{margin-inline-start:0}.ant-select-multiple .ant-select-selection-search{position:relative;max-width:100%;margin-inline-start:11px}.ant-select-multiple .ant-select-selection-search-input,.ant-select-multiple .ant-select-selection-search-mirror{height:24px;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue',Arial,'Noto Sans',sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol','Noto Color Emoji';line-height:24px;transition:all .3s}.ant-select-multiple .ant-select-selection-search-input{width:100%;min-width:4.1px}.ant-select-multiple .ant-select-selection-search-mirror{position:absolute;top:0;left:0;z-index:999;white-space:pre;visibility:hidden}.ant-select-multiple .ant-select-selection-placeholder{position:absolute;top:50%;right:15px;left:15px;transform:translateY(-50%);transition:all .3s}.ant-select-multiple.ant-select-lg .ant-select-selector::after{line-height:40px}.ant-select-multiple.ant-select-lg .ant-select-selection-item{height:40px;line-height:38px}.ant-select-multiple.ant-select-lg .ant-select-selection-search{height:40px;line-height:40px}.ant-select-multiple.ant-select-lg .ant-select-selection-search-input,.ant-select-multiple.ant-select-lg .ant-select-selection-search-mirror{height:40px;line-height:38px}.ant-select-multiple.ant-select-sm .ant-select-selector::after{line-height:16px}.ant-select-multiple.ant-select-sm .ant-select-selection-item{height:16px;line-height:14px}.ant-select-multiple.ant-select-sm .ant-select-selection-search{height:16px;line-height:16px}.ant-select-multiple.ant-select-sm .ant-select-selection-search-input,.ant-select-multiple.ant-select-sm .ant-select-selection-search-mirror{height:16px;line-height:14px}.ant-select-multiple.ant-select-sm .ant-select-selection-placeholder{left:7px}.ant-select-multiple.ant-select-sm .ant-select-selection-search{margin-inline-start:3px}.ant-select-disabled .ant-select-selection-item-remove{display:none}.ant-select-status-error.ant-select:not(.ant-select-disabled):not(.ant-select-customize-input):not(.ant-pagination-size-changer) .ant-select-selector{background-color:#fff;border-color:#f52922!important}.ant-select-status-error.ant-select:not(.ant-select-disabled):not(.ant-select-customize-input):not(.ant-pagination-size-changer).ant-select-focused .ant-select-selector,.ant-select-status-error.ant-select:not(.ant-select-disabled):not(.ant-select-customize-input):not(.ant-pagination-size-changer).ant-select-open .ant-select-selector{border-color:#ff584d;box-shadow:0 0 0 0 rgba(245,41,34,.2);border-right-width:1px;outline:0}.ant-select-status-warning.ant-select:not(.ant-select-disabled):not(.ant-select-customize-input):not(.ant-pagination-size-changer) .ant-select-selector{background-color:#fff;border-color:#fab700!important}.ant-select-status-warning.ant-select:not(.ant-select-disabled):not(.ant-select-customize-input):not(.ant-pagination-size-changer).ant-select-focused .ant-select-selector,.ant-select-status-warning.ant-select:not(.ant-select-disabled):not(.ant-select-customize-input):not(.ant-pagination-size-changer).ant-select-open .ant-select-selector{border-color:#ffcd29;box-shadow:0 0 0 0 rgba(250,183,0,.2);border-right-width:1px;outline:0}.ant-select-status-error.ant-select-has-feedback .ant-select-clear,.ant-select-status-success.ant-select-has-feedback .ant-select-clear,.ant-select-status-validating.ant-select-has-feedback .ant-select-clear,.ant-select-status-warning.ant-select-has-feedback .ant-select-clear{right:32px}.ant-select-status-error.ant-select-has-feedback .ant-select-selection-selected-value,.ant-select-status-success.ant-select-has-feedback .ant-select-selection-selected-value,.ant-select-status-validating.ant-select-has-feedback .ant-select-selection-selected-value,.ant-select-status-warning.ant-select-has-feedback .ant-select-selection-selected-value{padding-right:42px}.ant-select{box-sizing:border-box;margin:0;padding:0;color:#6a7580;font-size:13px;font-variant:tabular-nums;line-height:1.38;list-style:none;font-feature-settings:'tnum';position:relative;display:inline-block;cursor:pointer}.ant-select:not(.ant-select-customize-input) .ant-select-selector{position:relative;background-color:#fff;border:1px solid #dbe0e3;border-radius:3px;transition:all .3s cubic-bezier(.645, .045, .355, 1)}.ant-select:not(.ant-select-customize-input) .ant-select-selector input{cursor:pointer}.ant-select-show-search.ant-select:not(.ant-select-customize-input) .ant-select-selector{cursor:text}.ant-select-show-search.ant-select:not(.ant-select-customize-input) .ant-select-selector input{cursor:auto}.ant-select-focused:not(.ant-select-disabled).ant-select:not(.ant-select-customize-input) .ant-select-selector{border-color:#38f;box-shadow:0 0 0 0 rgba(11,104,255,.2);border-right-width:1px;outline:0}.ant-select-disabled.ant-select:not(.ant-select-customize-input) .ant-select-selector{color:#b5bdc3;background:#f9fafb;cursor:not-allowed}.ant-select-multiple.ant-select-disabled.ant-select:not(.ant-select-customize-input) .ant-select-selector{background:#f9fafb}.ant-select-disabled.ant-select:not(.ant-select-customize-input) .ant-select-selector input{cursor:not-allowed}.ant-select:not(.ant-select-customize-input) .ant-select-selector .ant-select-selection-search-input{margin:0;padding:0;background:0 0;border:none;outline:0;appearance:none}.ant-select:not(.ant-select-customize-input) .ant-select-selector .ant-select-selection-search-input::-webkit-search-cancel-button{display:none;-webkit-appearance:none}.ant-select:not(.ant-select-disabled):hover .ant-select-selector{border-color:#b5bdc3;border-right-width:1px}.ant-select-selection-item{flex:1;overflow:hidden;font-weight:400;white-space:nowrap;text-overflow:ellipsis}@media all and (-ms-high-contrast:none){.ant-select-selection-item,.ant-select-selection-item ::-ms-backdrop{flex:auto}}.ant-select-selection-placeholder{flex:1;overflow:hidden;color:#b5bdc3;white-space:nowrap;text-overflow:ellipsis;pointer-events:none}@media all and (-ms-high-contrast:none){.ant-select-selection-placeholder,.ant-select-selection-placeholder ::-ms-backdrop{flex:auto}}.ant-select-arrow{display:inline-flex;color:inherit;font-style:normal;line-height:0;text-transform:none;vertical-align:-.125em;text-rendering:optimizelegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;position:absolute;top:50%;right:15px;display:flex;align-items:center;height:11px;margin-top:-5.5px;color:#b5bdc3;font-size:11px;line-height:1;text-align:center;pointer-events:none}.ant-select-arrow>*{line-height:1}.ant-select-arrow svg{display:inline-block}.ant-select-arrow::before{display:none}.ant-select-arrow .ant-select-arrow-icon{display:block}.ant-select-arrow .anticon{vertical-align:top;transition:transform .3s}.ant-select-arrow .anticon>svg{vertical-align:top}.ant-select-arrow .anticon:not(.ant-select-suffix){pointer-events:auto}.ant-select-disabled .ant-select-arrow{cursor:not-allowed}.ant-select-arrow>:not(:last-child){margin-inline-end:8px}.ant-select-clear{position:absolute;top:50%;right:15px;z-index:1;display:inline-block;width:11px;height:11px;margin-top:-5.5px;color:#b5bdc3;font-size:11px;font-style:normal;line-height:1;text-align:center;text-transform:none;background:#fff;cursor:pointer;opacity:0;transition:color .3s ease,opacity .15s ease;text-rendering:auto}.ant-select-clear::before{display:block}.ant-select-clear:hover{color:#232936}.ant-select:hover .ant-select-clear{opacity:1}.ant-select-dropdown{margin:0;padding:0;color:#6a7580;font-variant:tabular-nums;line-height:1.38;list-style:none;font-feature-settings:'tnum';position:absolute;top:-9999px;left:-9999px;z-index:991050;box-sizing:border-box;padding:4px 0;overflow:hidden;font-size:13px;font-variant:initial;background-color:#fff;border-radius:3px;outline:0;box-shadow:0 2px 6px rgba(171,178,183,.12)}.ant-select-dropdown.ant-slide-up-appear.ant-slide-up-appear-active.ant-select-dropdown-placement-bottomLeft,.ant-select-dropdown.ant-slide-up-enter.ant-slide-up-enter-active.ant-select-dropdown-placement-bottomLeft{animation-name:antSlideUpIn}.ant-select-dropdown.ant-slide-up-appear.ant-slide-up-appear-active.ant-select-dropdown-placement-topLeft,.ant-select-dropdown.ant-slide-up-enter.ant-slide-up-enter-active.ant-select-dropdown-placement-topLeft{animation-name:antSlideDownIn}.ant-select-dropdown.ant-slide-up-leave.ant-slide-up-leave-active.ant-select-dropdown-placement-bottomLeft{animation-name:antSlideUpOut}.ant-select-dropdown.ant-slide-up-leave.ant-slide-up-leave-active.ant-select-dropdown-placement-topLeft{animation-name:antSlideDownOut}.ant-select-dropdown-hidden{display:none}.ant-select-dropdown-empty{color:#b5bdc3}.ant-select-item-empty{position:relative;display:block;min-height:32px;padding:5px 16px;color:#6a7580;font-weight:400;font-size:13px;line-height:22px;color:#b5bdc3}.ant-select-item{position:relative;display:block;min-height:32px;padding:5px 16px;color:#6a7580;font-weight:400;font-size:13px;line-height:22px;cursor:pointer;transition:background .3s ease}.ant-select-item-group{color:#232936;font-size:11px;cursor:default}.ant-select-item-option{display:flex}.ant-select-item-option-content{flex:auto;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.ant-select-item-option-state{flex:none}.ant-select-item-option-active:not(.ant-select-item-option-disabled){background-color:#f4faff}.ant-select-item-option-selected:not(.ant-select-item-option-disabled){color:#6a7580;font-weight:500;background-color:#fff}.ant-select-item-option-selected:not(.ant-select-item-option-disabled) .ant-select-item-option-state{color:#0b68ff}.ant-select-item-option-disabled{color:#b5bdc3;cursor:not-allowed}.ant-select-item-option-disabled.ant-select-item-option-selected{background-color:#f9fafb}.ant-select-item-option-grouped{padding-left:32px}.ant-select-lg{font-size:13px}.ant-select-borderless .ant-select-selector{background-color:transparent!important;border-color:transparent!important;box-shadow:none!important}.ant-select.ant-select-in-form-item{width:100%}.ant-select-compact-item:not(.ant-select-compact-last-item){margin-right:-1px}.ant-select-compact-item:not(.ant-select-compact-last-item).ant-select-compact-item-rtl{margin-right:0;margin-left:-1px}.ant-select-compact-item:active>*,.ant-select-compact-item:focus>*,.ant-select-compact-item:hover>*{z-index:2}.ant-select-compact-item.ant-select-focused>*{z-index:2}.ant-select-compact-item[disabled]>*{z-index:0}.ant-select-compact-item:not(.ant-select-compact-first-item):not(.ant-select-compact-last-item).ant-select>.ant-select-selector{border-radius:0}.ant-select-compact-item.ant-select-compact-first-item.ant-select:not(.ant-select-compact-last-item):not(.ant-select-compact-item-rtl)>.ant-select-selector{border-top-right-radius:0;border-bottom-right-radius:0}.ant-select-compact-item.ant-select-compact-last-item.ant-select:not(.ant-select-compact-first-item):not(.ant-select-compact-item-rtl)>.ant-select-selector{border-top-left-radius:0;border-bottom-left-radius:0}.ant-select-compact-item.ant-select.ant-select-compact-first-item.ant-select-compact-item-rtl:not(.ant-select-compact-last-item)>.ant-select-selector{border-top-left-radius:0;border-bottom-left-radius:0}.ant-select-compact-item.ant-select.ant-select-compact-last-item.ant-select-compact-item-rtl:not(.ant-select-compact-first-item)>.ant-select-selector{border-top-right-radius:0;border-bottom-right-radius:0}.ant-select-rtl{direction:rtl}.ant-select-rtl .ant-select-arrow{right:initial;left:15px}.ant-select-rtl .ant-select-clear{right:initial;left:15px}.ant-select-dropdown-rtl{direction:rtl}.ant-select-dropdown-rtl .ant-select-item-option-grouped{padding-right:32px;padding-left:16px}.ant-select-rtl.ant-select-multiple.ant-select-allow-clear .ant-select-selector,.ant-select-rtl.ant-select-multiple.ant-select-show-arrow .ant-select-selector{padding-right:4px;padding-left:27px}.ant-select-rtl.ant-select-multiple .ant-select-selection-item{text-align:right}.ant-select-rtl.ant-select-multiple .ant-select-selection-item-content{margin-right:0;margin-left:4px;text-align:right}.ant-select-rtl.ant-select-multiple .ant-select-selection-search-mirror{right:0;left:auto}.ant-select-rtl.ant-select-multiple .ant-select-selection-placeholder{right:15px;left:auto}.ant-select-rtl.ant-select-multiple.ant-select-sm .ant-select-selection-placeholder{right:7px}.ant-select-rtl.ant-select-single .ant-select-selector .ant-select-selection-item,.ant-select-rtl.ant-select-single .ant-select-selector .ant-select-selection-placeholder{right:0;left:9px;text-align:right}.ant-select-rtl.ant-select-single.ant-select-show-arrow .ant-select-selection-search{right:15px;left:28px}.ant-select-rtl.ant-select-single.ant-select-show-arrow .ant-select-selection-item,.ant-select-rtl.ant-select-single.ant-select-show-arrow .ant-select-selection-placeholder{padding-right:0;padding-left:17px}.ant-select-rtl.ant-select-single.ant-select-sm:not(.ant-select-customize-input).ant-select-show-arrow .ant-select-selection-search{right:6px}.ant-select-rtl.ant-select-single.ant-select-sm:not(.ant-select-customize-input).ant-select-show-arrow .ant-select-selection-item,.ant-select-rtl.ant-select-single.ant-select-sm:not(.ant-select-customize-input).ant-select-show-arrow .ant-select-selection-placeholder{padding-right:0;padding-left:19.5px}.ant-select-selection-selected-value{color:#57616d}.ant-select-selection-placeholder{color:#949ea6;padding-left:2px}.ant-select-dropdown{margin-top:4px}.ant-select-dropdown-menu-item{font-weight:500;color:#57616d}.ant-select-dropdown-menu-item:hover{background-color:#f9fafb;color:#0b68ff}.ant-select-item-group{padding:8px 12px;text-transform:uppercase;color:#949ea6;font-size:10px;line-height:16px;font-weight:500}.ant-select-multiple .ant-select-selection-item{background-color:#f3f5f6}.ant-select-multiple .ant-select-selection-item:hover{background-color:#e9edee}.ant-select-multiple .ant-select-selection-item:hover .ant-select-selection-item-remove svg{color:#f52922;fill:#f52922}.ant-select-dropdown-menu-item:hover:not( .ant-select-dropdown-menu-item-disabled){background-color:#f9fafb}.ant-select-dropdown-menu-item-active{background-color:#f9fafb;color:#57616d}.ant-select-dropdown-menu-item-active:not( .ant-select-dropdown-menu-item-disabled){background:#f9fafb;color:#0b68ff}.ant-select-item-option-disabled{opacity:.4}.ant-select-item-option-disabled:hover .ant-select-item-option-content{background-color:#f9fafb;color:#57616d}.ant-select-dropdown-menu-item-selected.ant-select-dropdown-menu-item-selected{background:0 0;color:#57616d}.ant-select-item-option-selected:after{position:absolute;width:24px;height:24px;right:8px;content:url('data:image/svg+xml;base64,PHN2ZyBpZD0iaWNvbnMiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgZmlsbD0iIzc2ZGMyNSIgdmlld0JveD0iMCAwIDI0IDI0Ij48ZGVmcz48c3R5bGU+LmNscy0xe2ZpbGw6bm9uZTt9PC9zdHlsZT48L2RlZnM+PHRpdGxlPjAxLTAyLWNoZWNrLXM8L3RpdGxlPjxyZWN0IGlkPSJjYW52YXMiIGNsYXNzPSJjbHMtMSIgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0Ii8+PHBhdGggZD0iTTEwLjYxLDE1Ljc0YS43NS43NSwwLDAsMS0uNTMtLjIyTDcsMTIuMzZhLjc1Ljc1LDAsMSwxLDEuMDYtMWwyLjU4LDIuNjFMMTYsOC40OGEuNzcuNzcsMCwwLDEsMS4wNywwLC43NS43NSwwLDAsMSwwLDEuMDZsLTUuODksNkEuNzkuNzksMCwwLDEsMTAuNjEsMTUuNzRaIi8+PC9zdmc+');color:#54cb0b;font-size:20px;z-index:11}.ant-select-item-option-selected>.ant-select-item-option-content{padding-right:32px}.ant-select-dropdown{box-shadow:0 8px 16px rgba(171,178,183,.32)}.ant-select-dropdown .ant-empty{display:flex;flex-direction:column;justify-content:center;align-items:center}.ant-select-dropdown .ant-empty p{margin:0}.ant-select-arrow{background-image:url('data:image/svg+xml;base64,PHN2ZyBpZD0iaWNvbnMiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDI0IDI0Ij48ZGVmcz48c3R5bGU+LmNscy0xe2ZpbGw6bm9uZTt9PC9zdHlsZT48L2RlZnM+PHRpdGxlPjAxLTAzLWFuZ2xlLWRvd24tczwvdGl0bGU+PHJlY3QgaWQ9ImNhbnZhcyIgY2xhc3M9ImNscy0xIiB3aWR0aD0iMjQiIGhlaWdodD0iMjQiLz48cGF0aCBmaWxsPSIjNmE3NTgwIiBkPSJNMTIsMTQuMzhhLjc5Ljc5LDAsMCwxLS41My0uMjJMOC4yMiwxMC45MWEuNzcuNzcsMCwwLDEsMC0xLjA3Ljc1Ljc1LDAsMCwxLDEuMDYsMEwxMiwxMi41NmwyLjcyLTIuNzJhLjc1Ljc1LDAsMCwxLDEuMDYsMCwuNzcuNzcsMCwwLDEsMCwxLjA3bC0zLjI1LDMuMjVBLjc5Ljc5LDAsMCwxLDEyLDE0LjM4WiIvPjwvc3ZnPg==');width:24px;height:24px;background-position:center;background-repeat:no-repeat;background-size:contain;top:50%;right:8px;transform-origin:50% 25%;display:flex;transform:translateY(-50%);align-items:center;justify-content:center;margin-top:0}.ant-select-arrow .anticon-down{display:none}.ant-select-arrow i{display:none!important}.ant-select-open:not(.ant-select-show-search) .ant-select-arrow{transform:rotateZ(-180deg)}.ant-select-open.ant-select-show-search .ant-select-arrow{background:0 0}.ant-select-dropdown{box-shadow:0 16px 32px 0 rgba(35,41,54,.1);padding:8px}.ant-select-dropdown .ant-select-item-option-content{font-size:13px;line-height:18px;color:#57616d;font-weight:500}.ant-select-dropdown .ant-select-item-option-active{background-color:transparent}.ant-select-dropdown .ant-select-item-option{border-radius:3px;height:32px;display:flex;align-items:center;justify-content:flex-start;padding:0 8px 0 12px}.ant-select-dropdown .ant-select-item-option:hover{background-color:#f9fafb}.ant-select-dropdown .ant-select-item-option:hover .ant-select-item-option-content{color:#0b68ff}.ant-select-dropdown .ant-select-item-option-disabled{opacity:.4}.ant-select-dropdown .ant-select-item-option-disabled:hover{background-color:transparent}.ant-select-dropdown .ant-select-item-option-disabled:hover .ant-select-item-option-content{background-color:transparent;color:#57616d}.ant-select-item-option-state{display:none}.ant-select{color:#57616d;font-size:13px;line-height:18px;font-weight:400}.ant-select.ant-select-single .ant-select-selector{padding:0 12px}.ant-select:hover.error .ant-select-selector{border-color:#f52922}.ant-select-focused .ant-select-selector,.ant-select-selector:active,.ant-select-selector:focus{border-color:#0b68ff!important;box-shadow:inset 0 0 0 1px #0b68ff!important;background:#f4faff!important}.ant-select-disabled .ant-select-selector{border-color:#dbe0e3!important;box-shadow:none!important;background:#f9fafb!important}.ant-select-focused .ant-select-clear{background-color:#f4faff!important}.ant-select .ant-select-clear{width:24px;height:24px;top:9px;right:8px}.ant-select .ant-select-clear svg{fill:#f52922;color:#f52922}.ant-select .ant-select-selector .ant-select-selection-search .ant-select-selection-search-input{left:12px;right:12px}.ant-select-multiple.ant-select-multiple.ant-select-multiple .ant-select-selection-search{left:12px;margin:0;min-width:10px}.ant-select-multiple.ant-select-multiple.ant-select-multiple .ant-select-selection-placeholder{left:12px;right:12px}.ant-select-multiple.ant-select-multiple.ant-select-multiple .ant-select-selection-search-input{margin:0;margin-left:0!important;padding:0}.ant-select-multiple.ant-select-multiple.ant-select-multiple .ant-select-selection-item{padding:0 0 0 8px;border:0}.ant-select-multiple.ant-select-multiple.ant-select-multiple .ant-select-selection-item{margin-left:2px;margin-right:2px}.ant-select-multiple.ant-select-multiple.ant-select-multiple .ant-select-selection-item+.ant-select-selection-search{left:4px}.ant-select-multiple .ant-select-selector{padding:1px 10px 1px 1px}.ant-select-multiple .ant-select-selection-item-remove svg{fill:#f52922;color:#f52922}.ant-select-dropdown-menu-item-group-title{color:#57616d}.ant-select-single .ant-select-selector .ant-select-selection-search{left:10px}.ds-autocomplete-dropdown.ds-autocomplete-dropdown{box-shadow:0 16px 32px 0 rgba(35,41,54,.1);padding:8px}.ds-autocomplete-dropdown.ds-autocomplete-dropdown .ant-select-item-option.ant-select-item-option-active:not(.ant-select-item-option-disabled){color:#57616d;background:#f9fafb}.ds-autocomplete .ant-select .ant-select-selector .ant-select-selection-search .ant-select-selection-search-input{right:15px}.ds-autocomplete .ant-select-single .ant-select-selector .ant-select-selection-search{left:12px}