@fibery/ui-kit 1.0.1 → 1.0.4

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/package.json CHANGED
@@ -1,14 +1,15 @@
1
1
  {
2
2
  "name": "@fibery/ui-kit",
3
- "version": "1.0.1",
3
+ "version": "1.0.4",
4
4
  "main": "index.ts",
5
5
  "private": false,
6
6
  "files": [
7
+ "src/antd/styles.ts",
7
8
  "src/Button.d.ts",
8
9
  "src/Button.js",
9
10
  "src/designSystem.ts",
10
11
  "src/create-inline-theme.ts",
11
- "src/FormFieldLoader.js",
12
+ "src/form-field-loader.tsx",
12
13
  "src/ThemeProvider.tsx",
13
14
  "src/Item.tsx",
14
15
  "src/Loaders.d.ts",
@@ -47,9 +48,9 @@
47
48
  "react-color": "2.13.8",
48
49
  "react-day-picker": "7.4.8",
49
50
  "react-popper": "2.2.5",
50
- "react-select": "3.0.8",
51
+ "react-select": "5.3.2",
51
52
  "react-select-country-list": "2.2.1",
52
- "react-windowed-select": "2.0.5",
53
+ "react-windowed-select": "5.0.0",
53
54
  "screenfull": "6.0.1"
54
55
  },
55
56
  "peerDependencies": {
@@ -64,6 +65,7 @@
64
65
  "@types/chroma-js": "2.1.3",
65
66
  "@types/color-hash": "1.0.2",
66
67
  "@types/emoji-mart": "3.0.8",
68
+ "csstype": "3.0.8",
67
69
  "enzyme": "3.11.0",
68
70
  "enzyme-adapter-react-16": "1.15.6",
69
71
  "fs-extra": "10.0.0",
@@ -0,0 +1,87 @@
1
+ import {useCallback, ReactNode} from "react";
2
+ import {css} from "@linaria/core";
3
+ import {components} from "react-windowed-select";
4
+ import RemoveIcon from "../icons/react/Remove";
5
+ import {OptionProps, DropdownIndicatorProps, ClearIndicatorProps, MultiValueRemoveProps, GroupBase} from "react-select";
6
+ import {Button} from "../Button";
7
+ import {themeVars, space} from "../designSystem";
8
+ import ArrowBottom from "../icons/react/ArrowBottom";
9
+ import {dropdownIndicatorSize, expanderStyle} from "./styles";
10
+
11
+ export const Option = <
12
+ TOption,
13
+ IsMulti extends boolean = boolean,
14
+ Group extends GroupBase<TOption> = GroupBase<TOption>
15
+ >({
16
+ children,
17
+ ...props
18
+ }: OptionProps<TOption, IsMulti, Group>) => {
19
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
20
+ const {onMouseMove, onMouseOver, ...rest} = props.innerProps;
21
+ const newProps = Object.assign(props, {innerProps: rest});
22
+ return <components.Option {...newProps}>{children}</components.Option>;
23
+ };
24
+
25
+ export function DropdownIndicator<
26
+ TOption,
27
+ IsMulti extends boolean = boolean,
28
+ Group extends GroupBase<TOption> = GroupBase<TOption>
29
+ >(props: DropdownIndicatorProps<TOption, IsMulti, Group>) {
30
+ return (
31
+ <div
32
+ className={expanderStyle}
33
+ style={{
34
+ transform: props.selectProps.menuIsOpen ? "rotate(180deg)" : "",
35
+ }}
36
+ >
37
+ <ArrowBottom iconSize={dropdownIndicatorSize} color={themeVars.disabledTextColor} />
38
+ </div>
39
+ );
40
+ }
41
+
42
+ export function ClearIndicator<
43
+ TOption,
44
+ IsMulti extends boolean = boolean,
45
+ Group extends GroupBase<TOption> = GroupBase<TOption>
46
+ >({
47
+ innerProps,
48
+ selectProps,
49
+ }: ClearIndicatorProps<TOption, IsMulti, Group> | MultiValueRemoveProps<TOption, IsMulti, Group>) {
50
+ const onMouseDown = innerProps.onMouseDown;
51
+ const wrappedOnMouseDown = useCallback(
52
+ (e) => {
53
+ onMouseDown?.(e);
54
+ // This prevents false positive triggering in rc-trigger
55
+ e.nativeEvent.stopImmediatePropagation();
56
+ },
57
+ [onMouseDown]
58
+ );
59
+ return (
60
+ <div {...innerProps}>
61
+ <Button
62
+ borderless
63
+ Icon={RemoveIcon}
64
+ disabled={selectProps.isDisabled}
65
+ size={":button-size/super-small"}
66
+ onMouseDown={wrappedOnMouseDown}
67
+ />
68
+ </div>
69
+ );
70
+ }
71
+
72
+ export const NoOptionsMessage = ({children}: {children: ReactNode}) => {
73
+ return (
74
+ <div
75
+ className={css`
76
+ ${{
77
+ paddingLeft: space.l + 2,
78
+ paddingRight: space.l + 2,
79
+ paddingTop: space.m,
80
+ paddingBottom: space.m,
81
+ }}
82
+ `}
83
+ >
84
+ {children}
85
+ </div>
86
+ );
87
+ };
@@ -0,0 +1,210 @@
1
+ import cn from "classnames";
2
+ import {useCallback, forwardRef} from "react";
3
+ import BaseSelect, {
4
+ GroupHeadingProps,
5
+ MenuProps,
6
+ StylesConfig,
7
+ Props as BaseSelectProps,
8
+ GroupBase,
9
+ OptionsOrGroups,
10
+ OptionProps,
11
+ SingleValueProps,
12
+ MultiValueProps,
13
+ } from "react-select";
14
+ import BaseCreatableSelect from "react-select/creatable";
15
+ import WindowedSelect, {components, WindowedMenuList} from "react-windowed-select";
16
+ import {createInlineTheme} from "../designSystem";
17
+ import {useTheme} from "../ThemeProvider";
18
+ import {ClearIndicator, DropdownIndicator, NoOptionsMessage, Option as OptionComponent} from "./components";
19
+ import {componentsStyles, singleLineComponentsStyle} from "./styles";
20
+
21
+ export type {OptionsOrGroups, GroupBase, StylesConfig, OptionProps, SingleValueProps, MultiValueProps};
22
+
23
+ function GroupHeading<
24
+ Option = unknown,
25
+ IsMulti extends boolean = boolean,
26
+ Group extends GroupBase<Option> = GroupBase<Option>
27
+ >(props: GroupHeadingProps<Option, IsMulti, Group>) {
28
+ if (!props.children) {
29
+ return null;
30
+ }
31
+ return <components.GroupHeading {...props} />;
32
+ }
33
+
34
+ function Menu<Option = unknown, IsMulti extends boolean = boolean, Group extends GroupBase<Option> = GroupBase<Option>>(
35
+ props: MenuProps<Option, IsMulti, Group>
36
+ ) {
37
+ const theme = useTheme();
38
+ const {innerProps, className} = props;
39
+ const overridedInnerProps = {...innerProps, style: {...innerProps.style, ...createInlineTheme(theme)}};
40
+ return <components.Menu {...props} innerProps={overridedInnerProps} className={cn(className, "react-select-menu")} />;
41
+ }
42
+
43
+ export {components};
44
+
45
+ export function combineStyles<
46
+ Option,
47
+ IsMulti extends boolean = boolean,
48
+ Group extends GroupBase<Option> = GroupBase<Option>
49
+ >(stylesArray: StylesConfig<Option, IsMulti, Group>[]): StylesConfig<Option, IsMulti, Group> {
50
+ return stylesArray.reduce<StylesConfig<Option, IsMulti, Group>>((acc, style) => {
51
+ Object.keys(style).forEach((key) => {
52
+ /* eslint-disable @typescript-eslint/ban-ts-comment */
53
+ // @ts-ignore
54
+ if (acc[key]) {
55
+ // @ts-ignore
56
+ const temp = acc[key];
57
+ // @ts-ignore
58
+ acc[key] = (provided, state) => style[key](temp(provided, state), state);
59
+ } else {
60
+ // @ts-ignore
61
+ acc[key] = (provided, state) => style[key](provided, state);
62
+ }
63
+ /* eslint-enable @typescript-eslint/ban-ts-comment */
64
+ });
65
+ return acc;
66
+ }, {});
67
+ }
68
+
69
+ export type SelectProps<
70
+ Option = unknown,
71
+ IsMulti extends boolean = boolean,
72
+ Group extends GroupBase<Option> = GroupBase<Option>
73
+ > = Omit<Omit<Omit<BaseSelectProps<Option, IsMulti, Group>, "isMulti">, "backspaceRemovesValue">, "isDisabled"> & {
74
+ virtualized?: boolean;
75
+ isCollectionMode?: IsMulti;
76
+ disabled?: boolean;
77
+ };
78
+ export function SingleRowSelect<
79
+ Option = unknown,
80
+ IsMulti extends boolean = boolean,
81
+ Group extends GroupBase<Option> = GroupBase<Option>
82
+ >({styles = {}, ...rest}: SelectProps<Option, IsMulti, Group>) {
83
+ return (
84
+ <Select<Option, IsMulti, Group>
85
+ {...rest}
86
+ styles={combineStyles<Option, IsMulti, Group>([
87
+ singleLineComponentsStyle as unknown as StylesConfig<Option, IsMulti, Group>,
88
+ styles,
89
+ ])}
90
+ />
91
+ );
92
+ }
93
+
94
+ export const Select = forwardRef(function Select<
95
+ Option = unknown,
96
+ IsMulti extends boolean = boolean,
97
+ Group extends GroupBase<Option> = GroupBase<Option>
98
+ >(
99
+ {
100
+ components,
101
+ isCollectionMode,
102
+ menuPortalTarget,
103
+ onKeyDown,
104
+ styles = {},
105
+ virtualized = true,
106
+ ...rest
107
+ }: SelectProps<Option, IsMulti, Group>,
108
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
109
+ forwardedRef: any
110
+ ) {
111
+ const handleKeyDown = useCallback(
112
+ (e) => {
113
+ switch (e.key) {
114
+ case "Escape":
115
+ if (rest.menuIsOpen) {
116
+ e.stopPropagation();
117
+ }
118
+ break;
119
+ case "Home":
120
+ e.preventDefault();
121
+ if (e.shiftKey) {
122
+ e.target.selectionStart = 0;
123
+ } else {
124
+ e.target.setSelectionRange(0, 0);
125
+ }
126
+ break;
127
+ case "End": {
128
+ e.preventDefault();
129
+ const len = e.target.value.length;
130
+ if (e.shiftKey) {
131
+ e.target.selectionEnd = len;
132
+ } else {
133
+ e.target.setSelectionRange(len, len);
134
+ }
135
+ break;
136
+ }
137
+ default:
138
+ }
139
+ onKeyDown && onKeyDown(e);
140
+ },
141
+ [onKeyDown, rest.menuIsOpen]
142
+ );
143
+
144
+ const SelectComponent = (virtualized ? WindowedSelect : BaseSelect) as unknown as typeof BaseSelect;
145
+
146
+ return (
147
+ <SelectComponent
148
+ ref={forwardedRef}
149
+ menuPortalTarget={menuPortalTarget}
150
+ menuPlacement={"auto"}
151
+ styles={combineStyles<Option, IsMulti, Group>([
152
+ componentsStyles as unknown as StylesConfig<Option, IsMulti, Group>,
153
+ styles,
154
+ ])}
155
+ isMulti={isCollectionMode}
156
+ backspaceRemovesValue={isCollectionMode}
157
+ tabSelectsValue={false}
158
+ components={{
159
+ Menu,
160
+ DropdownIndicator,
161
+ ClearIndicator,
162
+ Option: OptionComponent,
163
+ MultiValueRemove: ClearIndicator,
164
+ NoOptionsMessage,
165
+ GroupHeading,
166
+ ...components,
167
+ }}
168
+ {...rest}
169
+ onKeyDown={handleKeyDown}
170
+ isDisabled={rest.disabled}
171
+ />
172
+ );
173
+ // eslint-disable-next-line no-use-before-define
174
+ }) as <Option = unknown, IsMulti extends boolean = boolean, Group extends GroupBase<Option> = GroupBase<Option>>(
175
+ // eslint-disable-next-line no-use-before-define,@typescript-eslint/no-explicit-any
176
+ props: SelectProps<Option, IsMulti, Group> & {ref?: any}
177
+ ) => JSX.Element;
178
+
179
+ export function CreatableSelect<
180
+ Option = unknown,
181
+ IsMulti extends boolean = boolean,
182
+ Group extends GroupBase<Option> = GroupBase<Option>
183
+ >({components, isCollectionMode, menuPortalTarget, styles = {}, ...rest}: SelectProps<Option, IsMulti, Group>) {
184
+ return (
185
+ <BaseCreatableSelect
186
+ menuPortalTarget={menuPortalTarget}
187
+ menuPlacement={"auto"}
188
+ styles={combineStyles<Option, IsMulti, Group>([
189
+ componentsStyles as unknown as StylesConfig<Option, IsMulti, Group>,
190
+ styles,
191
+ ])}
192
+ isMulti={isCollectionMode}
193
+ backspaceRemovesValue={isCollectionMode}
194
+ tabSelectsValue={false}
195
+ components={{
196
+ Menu,
197
+ MenuList: WindowedMenuList,
198
+ DropdownIndicator,
199
+ ClearIndicator,
200
+ Option: OptionComponent,
201
+ MultiValueRemove: ClearIndicator,
202
+ NoOptionsMessage,
203
+ GroupHeading,
204
+ ...components,
205
+ }}
206
+ {...rest}
207
+ isDisabled={rest.disabled}
208
+ />
209
+ );
210
+ }
@@ -1,4 +1,4 @@
1
- import {FormFieldLoader} from "../FormFieldLoader";
1
+ import {FormFieldLoader} from "../form-field-loader";
2
2
  import {LoadingSausageList} from "../loading-sausage";
3
3
 
4
4
  export const SelectLoader = () => (
@@ -1,4 +1,6 @@
1
1
  import {css} from "@linaria/core";
2
+ import {Property} from "csstype";
3
+ import type {StylesConfig, CSSObjectWithLabel, ControlProps} from "react-select";
2
4
  import {inputOverrides} from "../antd/styles";
3
5
  import {border, layout, space, textStyles, themeVars, transition} from "../designSystem";
4
6
 
@@ -12,8 +14,12 @@ export const expanderStyle = css`
12
14
  }}
13
15
  `;
14
16
 
15
- function createControlStyle({isSingleLine}) {
16
- const childDivStyle = {
17
+ function createControlStyle({
18
+ isSingleLine,
19
+ }: {
20
+ isSingleLine: boolean;
21
+ }): (base: CSSObjectWithLabel, props: ControlProps) => CSSObjectWithLabel {
22
+ const childDivStyle: CSSObjectWithLabel = {
17
23
  padding: 0,
18
24
  overflow: "visible",
19
25
  };
@@ -22,23 +28,24 @@ function createControlStyle({isSingleLine}) {
22
28
  childDivStyle.flexWrap = "nowrap";
23
29
  }
24
30
 
25
- return (provided, state) => ({
26
- display: "flex",
27
- flexWrap: isSingleLine ? "nowrap" : "wrap",
28
- justifyContent: "space-between",
29
- width: "100%",
30
- minHeight: layout.inputHeight,
31
- ...inputOverrides.main,
32
- ...(state.isFocused && inputOverrides.focus),
33
- ...(state.isDisabled && inputOverrides.disabled),
34
- ":hover": !state.isFocused && !state.isDisabled && inputOverrides.hover,
35
- paddingLeft: space.l,
36
- paddingRight: space.l,
37
- "& > div": childDivStyle,
38
- });
31
+ return (provided, state) =>
32
+ ({
33
+ display: "flex",
34
+ flexWrap: isSingleLine ? "nowrap" : "wrap",
35
+ justifyContent: "space-between",
36
+ width: "100%",
37
+ ...inputOverrides.main,
38
+ minHeight: layout.inputHeight,
39
+ ...(state.isFocused && inputOverrides.focus),
40
+ ...(state.isDisabled && inputOverrides.disabled),
41
+ ":hover": !state.isFocused && !state.isDisabled ? inputOverrides.hover : {},
42
+ paddingLeft: space.l,
43
+ paddingRight: space.l,
44
+ "& > div": childDivStyle,
45
+ } as unknown as CSSObjectWithLabel);
39
46
  }
40
47
 
41
- export const componentsStyles = {
48
+ export const componentsStyles: StylesConfig = {
42
49
  option: (provided, state) => {
43
50
  const disabledStyles = {
44
51
  cursor: "not-allowed",
@@ -117,7 +124,7 @@ export const componentsStyles = {
117
124
  ...provided,
118
125
  zIndex: 1050,
119
126
  backgroundColor: themeVars.actionMenuInnerBg,
120
- boxShadow: themeVars.actionMenuShadow,
127
+ boxShadow: themeVars.actionMenuShadow as unknown as Property.BoxShadow,
121
128
  borderRadius: border.radius6,
122
129
  }),
123
130
  container: (provided, state) => ({
@@ -128,6 +135,6 @@ export const componentsStyles = {
128
135
  indicatorSeparator: () => ({}),
129
136
  };
130
137
 
131
- export const singleLineComponentsStyle = {
138
+ export const singleLineComponentsStyle: StylesConfig = {
132
139
  control: createControlStyle({isSingleLine: true}),
133
140
  };
@@ -0,0 +1,119 @@
1
+ import {css} from "@linaria/core";
2
+ import {colors, layout, opacity, border, shadows, space, textStyles, themeVars, transition} from "../designSystem";
3
+
4
+ export const inputOverrides = {
5
+ main: {
6
+ font: "inherit",
7
+ color: themeVars.textColor,
8
+ outline: "none",
9
+ backgroundColor: themeVars.inputBgColor,
10
+ borderRadius: border.radius6,
11
+ minHeight: layout.inputHeight,
12
+ paddingTop: 0,
13
+ paddingBottom: 0,
14
+ paddingLeft: space.l,
15
+ paddingRight: space.l,
16
+ border: 0,
17
+ borderColor: colors.transparent,
18
+ transition: `box-shadow ${transition}`,
19
+ boxShadow: themeVars.inputBorderColor,
20
+ letterSpacing: 0,
21
+ "::placeholder": {
22
+ color: themeVars.inputPlaceholderTextColor,
23
+ opacity: 1,
24
+ },
25
+ },
26
+ hover: {
27
+ boxShadow: `0 0 0 1px ${themeVars.opacity.regular} !important`,
28
+ transition: `box-shadow ${transition}`,
29
+ },
30
+ focus: {
31
+ boxShadow: `0 0 0 1px ${themeVars.opacity.light}, 0 0 0 3px ${themeVars.focus} !important`,
32
+ transition: `box-shadow ${transition}`,
33
+ },
34
+ disabled: {
35
+ color: themeVars.accentTextColor,
36
+ backgroundColor: themeVars.inputDisabledBgColor,
37
+ borderColor: colors.transparent,
38
+ boxShadow: `${themeVars.inputBorderColor} !important`,
39
+ transition: `box-shadow ${transition}`,
40
+ WebkitTextFillColor: "currentColor",
41
+ cursor: "default",
42
+ ":hover": {
43
+ boxShadow: `${themeVars.inputBorderColor}`,
44
+ },
45
+ },
46
+ };
47
+
48
+ export const inputStyles = css`
49
+ & .ant-input-prefix {
50
+ margin-right: -24px;
51
+ z-index: 1;
52
+ position: relative;
53
+ }
54
+ ${{
55
+ ...textStyles.regular,
56
+ "& .ant-input-group-addon": {
57
+ backgroundColor: colors.transparent,
58
+ border: "none",
59
+ padding: 0,
60
+ textAlign: "left",
61
+ boxShadow: shadows.border,
62
+ ":hover": inputOverrides.hover,
63
+ ":focus": inputOverrides.focus,
64
+ },
65
+ "& .ant-input-group": {borderSpacing: 1, ...textStyles.regular},
66
+ "& .ant-input": inputOverrides.main,
67
+ "& .ant-input[readonly].ant-input[readonly]": {...inputOverrides.disabled, cursor: "inherit"},
68
+ "& .ant-input:hover[readonly].ant-input:hover[readonly]": {...inputOverrides.disabled, cursor: "inherit"},
69
+ "& .ant-input-affix-wrapper:hover .ant-input[readonly]": {...inputOverrides.disabled, cursor: "inherit"},
70
+ "& .ant-input-affix-wrapper > input.ant-input": {
71
+ padding: "0 12px",
72
+ border: "inherit",
73
+ outline: "inherit",
74
+ },
75
+ "& .ant-input-affix-wrapper": {
76
+ font: "inherit",
77
+ padding: 0,
78
+ border: "none",
79
+ boxShadow: "none",
80
+ backgroundColor: colors.transparent,
81
+ },
82
+ "& .ant-input-affix-wrapper.ant-input-affix-wrapper-readonly": {
83
+ border: "none !important",
84
+ outline: "none !important",
85
+ boxShadow: "none !important",
86
+ },
87
+ "& .ant-input-affix-wrapper:hover .ant-input:not(.ant-input-disabled)": {
88
+ borderColor: "transparent",
89
+ },
90
+ "& .ant-cascader-picker:focus .ant-cascader-input, & .ant-cascader-picker:focus:hover .ant-cascader-input":
91
+ inputOverrides.focus,
92
+ "& .ant-select-auto-complete.ant-select": {
93
+ ...textStyles.regular,
94
+ "& .ant-select-selection--single": {height: layout.inputHeight},
95
+ "& .ant-input": inputOverrides.main,
96
+ "& .ant-input.ant-input:hover": inputOverrides.hover,
97
+ "& .ant-input.ant-input:focus": inputOverrides.focus,
98
+ "& .ant-input.ant-input-disabled": inputOverrides.disabled,
99
+ },
100
+ "& textarea.ant-input": {
101
+ paddingTop: space.m,
102
+ paddingBottom: space.m,
103
+ },
104
+ "& .ant-select-disabled .ant-select-selection": {
105
+ backgroundColor: colors.transparent,
106
+ },
107
+ "&& input:hover:not(:focus):not(:disabled), && textarea:hover:not(:focus):not(:disabled), && .ant-input:hover:not(:focus):not(:disabled)":
108
+ inputOverrides.hover,
109
+ "&& input:focus, && textarea:focus, && input:active, && textarea:active": inputOverrides.focus,
110
+ "&& .ant-input-disabled, && .ant-input-disabled:hover, && .ant-input-disabled:focus, && .ant-input-disabled:active":
111
+ inputOverrides.disabled,
112
+ "&& input::placeholder, && textarea::placeholder": {
113
+ color: themeVars.textColor,
114
+ opacity: opacity.regular,
115
+ },
116
+ "& .ant-input-affix-wrapper .ant-input-prefix": {left: space.s},
117
+ "& .ant-input-affix-wrapper .ant-input:not(:first-child)": {paddingLeft: space.s + space.xl + space.m}, // Match TitlePreview spacing
118
+ }}
119
+ `;
@@ -1,6 +1,5 @@
1
- import {PureComponent} from "react";
1
+ import {PureComponent, ReactNode} from "react";
2
2
  import {css} from "@linaria/core";
3
- import * as PropTypes from "prop-types";
4
3
  import cn from "classnames";
5
4
  import {space, border, themeVars} from "./designSystem";
6
5
 
@@ -17,14 +16,9 @@ const loaderStyle = css`
17
16
  background-color: ${themeVars.inputBgColor};
18
17
  `;
19
18
 
20
- export class FormFieldLoader extends PureComponent {
19
+ export class FormFieldLoader extends PureComponent<{additionClassname?: string; children: ReactNode}> {
21
20
  render() {
22
21
  const {additionClassname, children} = this.props;
23
22
  return <div className={cn(loaderStyle, additionClassname)}>{children}</div>;
24
23
  }
25
24
  }
26
-
27
- FormFieldLoader.propTypes = {
28
- additionClassname: PropTypes.string,
29
- children: PropTypes.node,
30
- };
@@ -1,64 +0,0 @@
1
- import {useCallback} from "react";
2
- import {css} from "@linaria/core";
3
- import {components} from "react-windowed-select";
4
- import RemoveIcon from "../icons/react/Remove";
5
- import {Button} from "../Button";
6
- import {themeVars, space} from "../designSystem";
7
- import ArrowBottom from "../icons/react/ArrowBottom";
8
- import {dropdownIndicatorSize, expanderStyle} from "./styles";
9
-
10
- export const Option = ({children, ...props}) => {
11
- const {onMouseMove, onMouseOver, ...rest} = props.innerProps;
12
- const newProps = Object.assign(props, {innerProps: rest});
13
- return <components.Option {...newProps}>{children}</components.Option>;
14
- };
15
-
16
- export const DropdownIndicator = (props) => (
17
- <div
18
- className={expanderStyle}
19
- style={{
20
- transform: props.selectProps.menuIsOpen ? "rotate(180deg)" : "",
21
- }}
22
- >
23
- <ArrowBottom iconSize={dropdownIndicatorSize} color={themeVars.disabledTextColor} />
24
- </div>
25
- );
26
-
27
- export const ClearIndicator = ({innerProps, selectProps}) => {
28
- const onMouseDown = innerProps.onMouseDown;
29
- const wrappedOnMouseDown = useCallback(
30
- (e) => {
31
- onMouseDown(e);
32
- // This prevents false positive triggering in rc-trigger
33
- e.nativeEvent.stopImmediatePropagation();
34
- },
35
- [onMouseDown]
36
- );
37
- return (
38
- <Button
39
- borderless
40
- Icon={RemoveIcon}
41
- disabled={selectProps.isDisabled}
42
- size={":button-size/super-small"}
43
- {...innerProps}
44
- onMouseDown={wrappedOnMouseDown}
45
- />
46
- );
47
- };
48
-
49
- export const NoOptionsMessage = ({children}) => {
50
- return (
51
- <div
52
- className={css`
53
- ${{
54
- paddingLeft: space.l + 2,
55
- paddingRight: space.l + 2,
56
- paddingTop: space.m,
57
- paddingBottom: space.m,
58
- }}
59
- `}
60
- >
61
- {children}
62
- </div>
63
- );
64
- };
@@ -1,11 +0,0 @@
1
- import {FunctionComponent, ForwardRefRenderFunction} from "react";
2
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
3
- export const Select: ForwardRefRenderFunction<{focus: () => void}, any>;
4
- export const CreatableSelect: FunctionComponent<any>;
5
- export const components: {
6
- GroupHeading: FunctionComponent<any>;
7
- Option: FunctionComponent<any>;
8
- SingleValue: FunctionComponent<any>;
9
- MultiValue: FunctionComponent<any>;
10
- };
11
- export const combineStyles: (...args: any[]) => any;
@@ -1,140 +0,0 @@
1
- import cn from "classnames";
2
- import {useCallback, forwardRef} from "react";
3
- import BaseSelect from "react-select";
4
- import BaseCreatableSelect from "react-select/creatable";
5
- import WindowedSelect, {components, WindowedMenuList} from "react-windowed-select";
6
- import {createInlineTheme} from "../designSystem";
7
- import {useTheme} from "../ThemeProvider";
8
- import {ClearIndicator, DropdownIndicator, NoOptionsMessage, Option} from "./components";
9
- import {componentsStyles, singleLineComponentsStyle} from "./styles";
10
-
11
- const GroupHeading = (props) => {
12
- if (!props.children) {
13
- return null;
14
- }
15
- return <components.GroupHeading {...props} />;
16
- };
17
-
18
- function Menu(props) {
19
- const theme = useTheme();
20
- const {innerProps, className} = props;
21
- const overridedInnerProps = {...innerProps, style: {...innerProps.style, ...createInlineTheme(theme)}};
22
- return <components.Menu {...props} innerProps={overridedInnerProps} className={cn(className, "react-select-menu")} />;
23
- }
24
-
25
- export {components};
26
-
27
- export const combineStyles = (stylesArray) => {
28
- return stylesArray.reduce((acc, style) => {
29
- Object.keys(style).forEach((key) => {
30
- if (acc[key]) {
31
- const temp = acc[key];
32
- acc[key] = (provided, state) => style[key](temp(provided, state), state);
33
- } else {
34
- acc[key] = (provided, state) => style[key](provided, state);
35
- }
36
- });
37
- return acc;
38
- }, {});
39
- };
40
-
41
- export function SingleRowSelect({styles = {}, ...rest}) {
42
- return <Select {...rest} styles={combineStyles([singleLineComponentsStyle, styles])} />;
43
- }
44
-
45
- export const Select = forwardRef(function Select(
46
- {components, isCollectionMode, menuPortalTarget, onKeyDown, styles = {}, virtualized = true, ...rest},
47
- forwardedRef
48
- ) {
49
- const theme = useTheme();
50
- const combineThemes = useCallback((providedTheme) => ({...providedTheme, ...theme}), [theme]);
51
- const handleKeyDown = useCallback(
52
- (e) => {
53
- switch (e.key) {
54
- case "Escape":
55
- if (rest.menuIsOpen) {
56
- e.stopPropagation();
57
- }
58
- break;
59
- case "Home":
60
- e.preventDefault();
61
- if (e.shiftKey) {
62
- e.target.selectionStart = 0;
63
- } else {
64
- e.target.setSelectionRange(0, 0);
65
- }
66
- break;
67
- case "End":
68
- e.preventDefault();
69
- const len = e.target.value.length;
70
- if (e.shiftKey) {
71
- e.target.selectionEnd = len;
72
- } else {
73
- e.target.setSelectionRange(len, len);
74
- }
75
- break;
76
- default:
77
- }
78
- onKeyDown && onKeyDown(e);
79
- },
80
- [onKeyDown, rest.menuIsOpen]
81
- );
82
-
83
- const SelectComponent = virtualized ? WindowedSelect : BaseSelect;
84
-
85
- return (
86
- <SelectComponent
87
- ref={forwardedRef}
88
- menuPortalTarget={menuPortalTarget}
89
- menuPlacement={"auto"}
90
- style={createInlineTheme(theme)}
91
- styles={combineStyles([componentsStyles, styles])}
92
- theme={combineThemes}
93
- isMulti={isCollectionMode}
94
- backspaceRemovesValue={isCollectionMode}
95
- tabSelectsValue={false}
96
- components={{
97
- Menu,
98
- DropdownIndicator,
99
- ClearIndicator,
100
- Option,
101
- MultiValueRemove: ClearIndicator,
102
- NoOptionsMessage,
103
- GroupHeading,
104
- ...components,
105
- }}
106
- {...rest}
107
- onKeyDown={handleKeyDown}
108
- isDisabled={rest.disabled}
109
- />
110
- );
111
- });
112
-
113
- export function CreatableSelect({components, isCollectionMode, menuPortalTarget, styles = {}, ...rest}) {
114
- const theme = useTheme();
115
- const combineThemes = useCallback((providedTheme) => ({...providedTheme, ...theme}), [theme]);
116
- return (
117
- <BaseCreatableSelect
118
- menuPortalTarget={menuPortalTarget}
119
- menuPlacement={"auto"}
120
- styles={combineStyles([componentsStyles, styles])}
121
- theme={combineThemes}
122
- isMulti={isCollectionMode}
123
- backspaceRemovesValue={isCollectionMode}
124
- tabSelectsValue={false}
125
- components={{
126
- Menu,
127
- MenuList: WindowedMenuList,
128
- DropdownIndicator,
129
- ClearIndicator,
130
- Option,
131
- MultiValueRemove: ClearIndicator,
132
- NoOptionsMessage,
133
- GroupHeading,
134
- ...components,
135
- }}
136
- {...rest}
137
- isDisabled={rest.disabled}
138
- />
139
- );
140
- }
@@ -1,35 +0,0 @@
1
- import {lazy, Suspense, forwardRef} from "react";
2
- import {SelectLoader} from "./select-loader";
3
-
4
- const LazySelect = lazy(async () => {
5
- const {Select} = await import("./index");
6
- return {default: Select};
7
- });
8
-
9
- export const ReactSelect = forwardRef((props, forwardedRef) => (
10
- <Suspense fallback={<SelectLoader />}>
11
- <LazySelect {...props} ref={forwardedRef} />
12
- </Suspense>
13
- ));
14
-
15
- const CreatableLazySelect = lazy(async () => {
16
- const {CreatableSelect} = await import("./index");
17
- return {default: CreatableSelect};
18
- });
19
-
20
- export const CreatableReactSelect = (props) => (
21
- <Suspense fallback={<SelectLoader />}>
22
- <CreatableLazySelect {...props} />
23
- </Suspense>
24
- );
25
-
26
- const SingleRowLazySelect = lazy(async () => {
27
- const {SingleRowSelect} = await import("./index");
28
- return {default: SingleRowSelect};
29
- });
30
-
31
- export const SingleRowReactSelect = (props) => (
32
- <Suspense fallback={<SelectLoader />}>
33
- <SingleRowLazySelect {...props} />
34
- </Suspense>
35
- );