@fibery/ui-kit 1.40.0 → 1.40.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,32 +1,22 @@
1
- import {css} from "@linaria/core";
2
- import {space, themeVars} from "./design-system";
1
+ import {themeVars} from "./design-system";
2
+ import {Dot} from "./dot";
3
+ import {CSSProperties} from "react";
3
4
 
4
- const activityIndicatorStyle = css`
5
- ${{
6
- backgroundColor: themeVars.active,
7
- borderRadius: "50%",
8
- position: "absolute",
9
- top: 0,
10
- }}
11
- `;
12
-
13
- type PropsType = {
5
+ type Props = {
14
6
  big?: boolean;
15
7
  color?: string;
16
- style?: Record<string, string | number | null>;
17
- };
8
+ } & React.ComponentProps<"div">;
18
9
 
19
- export const NotificationDot = ({big = true, color = themeVars.active, style}: PropsType) => {
20
- const size = big ? space.s6 : space.s4;
10
+ export const NotificationDot = ({big = true, color = themeVars.active, style}: Props) => {
21
11
  const marginTop = big ? -6 : -1;
22
12
  const marginRight = big ? -1 : 0;
23
13
  const styleObject = {
24
- backgroundColor: color,
25
- width: size,
26
- height: size,
14
+ position: "absolute",
15
+ top: 0,
27
16
  marginTop,
28
17
  marginRight,
29
18
  ...style,
30
- };
31
- return <div className={activityIndicatorStyle} style={styleObject} />;
19
+ } as CSSProperties;
20
+
21
+ return <Dot color={color} size={big ? "medium" : "small"} style={styleObject} />;
32
22
  };
@@ -45,6 +45,8 @@ import {useComposedRefs} from "@fibery/react/src/use-composed-refs";
45
45
  import {createContext} from "@fibery/react/src/create-context";
46
46
  import {Wrap} from "@fibery/react/src/wrap";
47
47
 
48
+ export const mobileZIndex = 1002;
49
+
48
50
  const Backdrop = ({className}: {className?: string}) => {
49
51
  return (
50
52
  <div
@@ -171,7 +173,7 @@ export function MobilePopup({
171
173
  right: var(${safeAreaInsetRightVar});
172
174
  top: var(${safeAreaInsetTopVar});
173
175
  bottom: var(${safeAreaInsetBottomVar});
174
- z-index: 1002;
176
+ z-index: ${mobileZIndex};
175
177
  `,
176
178
  !height && mobileAnimationClassName,
177
179
  !height && popupContentClassName,
@@ -32,6 +32,7 @@ export function Menu<T, U extends boolean, V extends GroupBase<T>>(props: MenuPr
32
32
 
33
33
  const menuTransparentCss = css`
34
34
  background-color: ${themeVars.transparent};
35
+ overflow: auto;
35
36
  `;
36
37
 
37
38
  export function MenuTransparent<T, U extends boolean, V extends GroupBase<T>>(props: MenuProps<T, U, V>) {
@@ -1,44 +1,13 @@
1
1
  /* eslint-disable no-use-before-define */
2
- import {useComposedRefs} from "@fibery/react/src/use-composed-refs";
3
- import {ForwardedRef, forwardRef, RefObject, useCallback, useMemo, useRef, useState} from "react";
4
- import BaseSelect, {
5
- ActionMeta,
6
- components as reactSelectComponents,
7
- createFilter,
8
- MenuListProps,
9
- MenuProps,
10
- ControlProps,
11
- mergeStyles,
12
- MultiValue,
13
- MultiValueProps,
14
- OnChangeValue,
15
- OptionProps,
16
- OptionsOrGroups,
17
- Props as BaseSelectProps,
18
- PropsValue,
19
- SelectInstance,
20
- SingleValue,
21
- SingleValueProps,
22
- StylesConfig,
23
- } from "react-select";
24
- import BaseCreatableSelect, {CreatableProps} from "react-select/creatable";
25
- import {ClearIndicator, NoClearIndicator} from "./components/clear-indicator";
26
- import {DropdownIndicator} from "./components/drop-down-indicator";
27
- import {GroupHeading} from "./components/group-heading";
28
- import {Menu} from "./components/menu";
29
- import {MenuListVirtualized} from "./components/menu-list-virtualized";
30
- import {NoOptionsMessage} from "./components/no-option-message";
31
- import {Option, OptionSlow} from "./components/option";
32
- import {useSelectControlSettings} from "./select-control-settings-context";
33
- import {
34
- makeComponentsStyles,
35
- makeNonVirtualizedStyles,
36
- makeSingleLineStyles,
37
- makeVirtualizedStyles,
38
- makeZIndexStyles,
39
- } from "./styles";
40
- import {countOptions, GroupBase, ReactSelectRefContext} from "./util";
41
- import _ from "lodash";
2
+ import {useIsPhone} from "../use-is-phone";
3
+ import {SelectComponent} from "./select";
4
+ import React, {ForwardedRef, forwardRef} from "react";
5
+ import type {SelectProps, GroupBase, SelectInstance} from "./select";
6
+ import {SelectInPopover} from "./select-in-popover";
7
+ import {combineStyles} from "./select";
8
+ import {makeSingleLineStyles} from "./styles";
9
+ import {css} from "@linaria/core";
10
+ import {$TSFixMe} from "../tsfixme";
42
11
 
43
12
  export type {
44
13
  ActionMeta,
@@ -57,244 +26,111 @@ export type {
57
26
  StylesConfig,
58
27
  SelectInstance,
59
28
  BaseSelectProps,
60
- };
29
+ SelectProps,
30
+ } from "./select";
61
31
 
62
- export {reactSelectComponents as components, MenuListVirtualized, createFilter};
32
+ export {components, MenuListVirtualized, createFilter} from "./select";
63
33
 
64
- function GroupVirtualized() {
65
- return null;
66
- }
67
-
68
- export function combineStyles<T, U extends boolean, V extends GroupBase<T>>(styles: StylesConfig<T, U, V>[]) {
69
- return styles.reduce(mergeStyles, {});
70
- }
34
+ export {combineStyles} from "./select";
71
35
 
72
- export type SelectProps<T = unknown, U extends boolean = boolean, V extends GroupBase<T> = GroupBase<T>> = Omit<
73
- Omit<Omit<BaseSelectProps<T, U, V>, "isMulti">, "backspaceRemovesValue">,
74
- "isDisabled"
75
- > & {
76
- virtualized?: boolean;
77
- isCollectionMode?: U;
78
- disabled?: boolean;
79
- forbidValuesClearInCollnMode?: boolean;
36
+ const emptyComponents = {
37
+ Menu: () => null,
80
38
  };
81
39
 
82
- export function SingleRowSelect<T = unknown, U extends boolean = boolean, V extends GroupBase<T> = GroupBase<T>>({
83
- styles = {},
84
- ...rest
85
- }: SelectProps<T, U, V>) {
86
- return <Select<T, U, V> {...rest} styles={combineStyles([makeSingleLineStyles(), styles])} />;
87
- }
88
-
89
- const FAST_OPTION_USAGE_THRESHOLD = 200;
90
-
91
- function useSelectComponents<T, U extends boolean, V extends GroupBase<T>>({
92
- components,
93
- optionsCount,
94
- virtualized,
95
- isCollectionMode,
96
- forbidValuesClearInCollnMode,
97
- }: {
98
- components: SelectProps<T, U, V>["components"];
99
- optionsCount: number;
100
- virtualized: boolean;
101
- isCollectionMode?: U;
102
- forbidValuesClearInCollnMode?: boolean;
103
- }) {
104
- const shouldUseFastOption = optionsCount > FAST_OPTION_USAGE_THRESHOLD;
105
- const shouldHideMultiValueRemove = isCollectionMode && forbidValuesClearInCollnMode;
106
-
107
- return {
108
- Menu,
109
- DropdownIndicator,
110
- ClearIndicator,
111
- MultiValueRemove: shouldHideMultiValueRemove ? NoClearIndicator : ClearIndicator,
112
- NoOptionsMessage,
113
- GroupHeading,
114
- Option: shouldUseFastOption ? Option : OptionSlow,
115
- ...components,
116
- Group: virtualized ? GroupVirtualized : components?.Group ? components.Group : reactSelectComponents.Group,
117
- MenuList: virtualized
118
- ? MenuListVirtualized
119
- : components?.MenuList
120
- ? components.MenuList
121
- : reactSelectComponents.MenuList,
122
- };
123
- }
124
-
125
- function useSelectStyles<T, U extends boolean, V extends GroupBase<T>>({
126
- virtualized,
127
- zIndex,
128
- styles,
129
- }: {
130
- virtualized: boolean;
131
- zIndex?: number;
132
- styles?: SelectProps<T, U, V>["styles"];
133
- }) {
134
- return useMemo(() => {
135
- return combineStyles<T, U, V>(
136
- _.compact([
137
- makeComponentsStyles<T, U, V>(),
138
- virtualized ? makeVirtualizedStyles<T, U, V>() : makeNonVirtualizedStyles<T, U, V>(),
139
- zIndex ? makeZIndexStyles<T, U, V>(zIndex) : null,
140
- styles,
141
- ])
142
- );
143
- }, [styles, virtualized, zIndex]);
144
- }
145
-
146
- export const Select = forwardRef(function Select<
40
+ export const Select = forwardRef(function SelectInner<
147
41
  T = unknown,
148
42
  U extends boolean = boolean,
149
43
  V extends GroupBase<T> = GroupBase<T>
150
44
  >(
151
45
  {
152
- components,
153
- isCollectionMode,
154
- menuPortalTarget,
155
- onKeyDown,
46
+ maxMenuHeight,
47
+ options = [],
48
+ formatOptionLabel,
49
+ isOptionDisabled,
156
50
  styles,
157
- virtualized = true,
158
- onMenuOpen,
159
- onMenuClose,
160
- onChange,
161
- forbidValuesClearInCollnMode,
162
- ...rest
51
+ isClearable,
52
+ placeholder,
53
+ title,
54
+ isSearchable,
55
+ ...restProps
163
56
  }: SelectProps<T, U, V>,
164
57
  forwardedRef: ForwardedRef<SelectInstance<T, U, V>>
165
58
  ) {
166
- const {getPopupContainerElement, zIndex} = useSelectControlSettings();
167
- const [menuOpenState, setMenuOpenState] = useState(rest.defaultMenuIsOpen);
168
- const optionsCount = useMemo(() => countOptions(rest.options), [rest.options]);
169
-
170
- const onMenuOpenWrapped = useCallback(() => {
171
- setMenuOpenState(true);
172
- onMenuOpen && onMenuOpen();
173
- }, [onMenuOpen]);
174
-
175
- const onMenuCloseWrapped = useCallback(() => {
176
- setMenuOpenState(false);
177
- onMenuClose && onMenuClose();
178
- }, [onMenuClose]);
179
-
180
- const handleKeyDown: React.KeyboardEventHandler<HTMLInputElement> = useCallback(
181
- (e) => {
182
- switch (e.key) {
183
- case "Escape":
184
- // we can't rely on "menuIsOpen" prop here, as user may not pass this prop and rely on internal component behavior instead.
185
- if (menuOpenState) {
186
- e.stopPropagation();
187
- }
188
- break;
189
- case "Home":
190
- e.preventDefault();
191
- if (e.shiftKey) {
192
- (e.target as HTMLInputElement).selectionStart = 0;
193
- } else {
194
- (e.target as HTMLInputElement).setSelectionRange(0, 0);
195
- }
196
- break;
197
- case "End": {
198
- e.preventDefault();
199
- const len = (e.target as HTMLInputElement).value.length;
200
- if (e.shiftKey) {
201
- (e.target as HTMLInputElement).selectionEnd = len;
202
- } else {
203
- (e.target as HTMLInputElement).setSelectionRange(len, len);
204
- }
205
- break;
59
+ const isPhone = useIsPhone();
60
+ if (isPhone) {
61
+ return (
62
+ <SelectInPopover
63
+ {...(restProps as $TSFixMe)}
64
+ options={options}
65
+ isSearchable={isSearchable}
66
+ title={title || typeof placeholder === "string" ? placeholder : ""}
67
+ isClearable={typeof isClearable === "undefined" ? false : isClearable}
68
+ formatOptionLabel={
69
+ formatOptionLabel as ((option: T, {context}: {context: "menu" | "value"}) => React.ReactNode) | undefined
206
70
  }
207
- default:
208
- }
209
- onKeyDown && onKeyDown(e);
210
- },
211
- [onKeyDown, menuOpenState]
212
- );
213
-
214
- const selectRef = useRef<SelectInstance<T, U, V> | null>(null);
215
- const composedRef = useComposedRefs(forwardedRef, selectRef);
216
-
217
- const selectComponents = useSelectComponents({
218
- components,
219
- optionsCount,
220
- virtualized,
221
- isCollectionMode,
222
- forbidValuesClearInCollnMode,
223
- });
224
-
225
- const combinedStyles = useSelectStyles({virtualized, zIndex, styles});
226
-
227
- return (
228
- <ReactSelectRefContext.Provider value={selectRef as RefObject<SelectInstance>}>
229
- <BaseSelect<T, U, V>
230
- ref={composedRef}
231
- // There are places, where it is useful to override menuPortalTarget globally for all selects.
232
- // When you are already in some popup. e.g. user input in buttons, relation filter popover.
233
- menuPortalTarget={getPopupContainerElement ? getPopupContainerElement() : menuPortalTarget}
234
- menuPlacement={"auto"}
235
- styles={combinedStyles}
236
- isMulti={isCollectionMode}
237
- backspaceRemovesValue={isCollectionMode && !forbidValuesClearInCollnMode}
238
- tabSelectsValue={false}
239
- components={selectComponents}
240
- {...rest}
241
- onKeyDown={handleKeyDown}
242
- onMenuOpen={onMenuOpenWrapped}
243
- onMenuClose={onMenuCloseWrapped}
244
- onChange={rest.disabled ? undefined : onChange}
245
- isDisabled={rest.disabled}
71
+ isOptionDisabled={isOptionDisabled as ((option: T) => boolean) | undefined}
72
+ renderValue={() => {
73
+ return (
74
+ <div
75
+ className={css`
76
+ display: block;
77
+ position: relative;
78
+ `}
79
+ >
80
+ <div
81
+ className={css`
82
+ position: absolute;
83
+ inset: 0;
84
+ z-index: 1;
85
+ `}
86
+ />
87
+ <div
88
+ className={css`
89
+ pointer-events: none;
90
+ `}
91
+ >
92
+ <SelectComponent
93
+ {...restProps}
94
+ isSearchable={false}
95
+ components={emptyComponents}
96
+ placeholder={placeholder}
97
+ maxMenuHeight={maxMenuHeight}
98
+ options={options}
99
+ styles={styles}
100
+ formatOptionLabel={formatOptionLabel}
101
+ isOptionDisabled={isOptionDisabled}
102
+ isClearable={isClearable}
103
+ menuIsOpen={false}
104
+ />
105
+ </div>
106
+ </div>
107
+ );
108
+ }}
246
109
  />
247
- </ReactSelectRefContext.Provider>
110
+ );
111
+ }
112
+ return (
113
+ <SelectComponent<T, U, V>
114
+ ref={forwardedRef}
115
+ maxMenuHeight={maxMenuHeight}
116
+ options={options}
117
+ placeholder={placeholder}
118
+ formatOptionLabel={formatOptionLabel}
119
+ isOptionDisabled={isOptionDisabled}
120
+ isClearable={isClearable}
121
+ styles={styles}
122
+ {...restProps}
123
+ />
248
124
  );
249
125
  }) as <Option = unknown, IsMulti extends boolean = boolean, Group extends GroupBase<Option> = GroupBase<Option>>(
250
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
251
- props: SelectProps<Option, IsMulti, Group> & {ref?: any}
126
+ props: SelectProps<Option, IsMulti, Group> & {ref?: $TSFixMe}
252
127
  ) => JSX.Element;
253
128
 
254
- function CreatableSelectInner<T = unknown, U extends boolean = boolean, V extends GroupBase<T> = GroupBase<T>>(
255
- {
256
- components,
257
- isCollectionMode,
258
- menuPortalTarget,
259
- styles = {},
260
- virtualized = true,
261
- forbidValuesClearInCollnMode,
262
- ...rest
263
- }: CreatableProps<T, U, V> & SelectProps<T, U, V>,
264
- ref: ForwardedRef<SelectInstance<T, U, V>>
265
- ) {
266
- const optionsCount = useMemo(() => countOptions(rest.options), [rest.options]);
267
-
268
- const selectComponents = useSelectComponents({
269
- components,
270
- optionsCount,
271
- virtualized,
272
- isCollectionMode,
273
- forbidValuesClearInCollnMode,
274
- });
275
-
276
- const combinedStyles = useSelectStyles({virtualized, styles});
277
-
278
- return (
279
- <BaseCreatableSelect
280
- ref={ref}
281
- menuPortalTarget={menuPortalTarget}
282
- menuPlacement={"auto"}
283
- styles={combinedStyles}
284
- isMulti={isCollectionMode}
285
- backspaceRemovesValue={isCollectionMode}
286
- tabSelectsValue={false}
287
- components={selectComponents}
288
- {...rest}
289
- isDisabled={rest.disabled}
290
- />
291
- );
129
+ export function SingleRowSelect<T = unknown, U extends boolean = boolean, V extends GroupBase<T> = GroupBase<T>>({
130
+ styles = {},
131
+ ...rest
132
+ }: SelectProps<T, U, V>) {
133
+ return <Select {...rest} styles={combineStyles([makeSingleLineStyles<T, U, V>(), styles])} />;
292
134
  }
293
135
 
294
- export const CreatableSelect = forwardRef(CreatableSelectInner) as <
295
- T = unknown,
296
- U extends boolean = boolean,
297
- V extends GroupBase<T> = GroupBase<T>
298
- >(
299
- props: CreatableProps<T, U, V> & SelectProps<T, U, V>
300
- ) => ReturnType<typeof CreatableSelectInner>;
136
+ export {CreatableSelect} from "./select";
@@ -25,10 +25,10 @@ import {
25
25
  OnChangeValue,
26
26
  OptionsOrGroups,
27
27
  PropsValue,
28
- Select as ReactSelect,
28
+ SelectComponent as ReactSelect,
29
29
  SelectProps,
30
30
  StylesConfig,
31
- } from "./index";
31
+ } from "./select";
32
32
  import {SelectControlSettingsProvider} from "./select-control-settings-context";
33
33
  import {ButtonColor, ButtonVariant} from "../button/base-button";
34
34
  import {makeSelectInPopoverStyles} from "./styles";
@@ -131,6 +131,7 @@ export type SelectInPopoverRef<T, U extends boolean, V extends GroupBase<T>> = {
131
131
 
132
132
  type Props<T, U extends boolean, V extends GroupBase<T>> = {
133
133
  value?: PropsValue<T>;
134
+ isSearchable?: boolean;
134
135
  menuIsOpen?: boolean;
135
136
  autoFocus?: boolean;
136
137
  virtualized?: boolean;
@@ -139,6 +140,7 @@ type Props<T, U extends boolean, V extends GroupBase<T>> = {
139
140
  noOptionsMessage?: () => string | JSX.Element | null;
140
141
  options: OptionsOrGroups<T, V>;
141
142
  filterOption?: SelectProps<T, U, V>["filterOption"];
143
+ menuPortalTarget?: SelectProps<T, U, V>["menuPortalTarget"];
142
144
  inputValue?: string;
143
145
  disabled?: boolean;
144
146
  isCollectionMode?: U;
@@ -203,7 +205,11 @@ function SelectInPopoverInner<T, U extends boolean, V extends GroupBase<T>>(
203
205
  otherSelectProps,
204
206
  forbidValuesClearInCollnMode,
205
207
  isOptionDisabled,
208
+ isSearchable = true,
209
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
210
+ menuPortalTarget,
206
211
  popoverPlacement = "bottom-start",
212
+ ...rest
207
213
  } = props;
208
214
  const [visible, setVisible] = useControllableState({
209
215
  value: menuIsOpen,
@@ -381,9 +387,10 @@ function SelectInPopoverInner<T, U extends boolean, V extends GroupBase<T>>(
381
387
  {/*So in dom react-select will be a child of popover. */}
382
388
  <SelectControlSettingsProvider inPopover={true} getPopupContainerElement={undefined}>
383
389
  <ReactSelect<T, U, V>
390
+ {...rest}
384
391
  ref={selectRef}
385
392
  styles={styles}
386
- isSearchable={true}
393
+ isSearchable={isSearchable}
387
394
  onKeyDown={onKeyDown}
388
395
  autoFocus={autoFocus}
389
396
  onBlur={onBlur}
@@ -408,6 +415,7 @@ function SelectInPopoverInner<T, U extends boolean, V extends GroupBase<T>>(
408
415
  isClearable={!isCollectionMode && isClearable}
409
416
  formatGroupLabel={formatGroupLabel}
410
417
  formatOptionLabel={formatOptionLabel}
418
+ menuShouldBlockScroll={false}
411
419
  {...otherSelectProps}
412
420
  components={selectComponents}
413
421
  forbidValuesClearInCollnMode={forbidValuesClearInCollnMode}