@fibery/ui-kit 1.25.1 → 1.26.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fibery/ui-kit",
3
- "version": "1.25.1",
3
+ "version": "1.26.1",
4
4
  "private": false,
5
5
  "files": [
6
6
  "src/antd/styles.ts",
@@ -68,7 +68,7 @@
68
68
  "react-virtuoso": "4.6.0",
69
69
  "screenfull": "6.0.1",
70
70
  "ua-parser-js": "0.7.24",
71
- "@fibery/emoji-data": "2.3.0",
71
+ "@fibery/emoji-data": "2.4.0",
72
72
  "@fibery/react": "1.3.0",
73
73
  "@fibery/helpers": "1.2.0"
74
74
  },
@@ -77,8 +77,8 @@
77
77
  "react-dom": "^18.2.0"
78
78
  },
79
79
  "devDependencies": {
80
- "@babel/core": "7.20.5",
81
- "@babel/runtime": "7.20.6",
80
+ "@babel/core": "7.23.9",
81
+ "@babel/runtime": "7.23.9",
82
82
  "@linaria/babel-preset": "5.0.3",
83
83
  "@testing-library/dom": "8.19.1",
84
84
  "@testing-library/jest-dom": "5.16.5",
@@ -103,8 +103,8 @@
103
103
  "svgo": "2.8.0",
104
104
  "typescript": "5.1.6",
105
105
  "unist-util-reduce": "0.2.2",
106
- "@fibery/eslint-config": "8.5.0",
107
- "@fibery/babel-preset": "7.3.0"
106
+ "@fibery/babel-preset": "7.4.0",
107
+ "@fibery/eslint-config": "8.5.1"
108
108
  },
109
109
  "jest": {
110
110
  "testEnvironment": "jsdom",
@@ -3,6 +3,6 @@
3
3
 
4
4
  import { IconDefinition } from '../types';
5
5
 
6
- const AppDetails: IconDefinition = {"icon":{"type":"root","children":[{"type":"element","tagName":"svg","properties":{"viewBox":"0 0 20 20"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","clipRule":"evenodd","d":"M11.75 2a.75.75 0 0 1 .75.75v1h4.75a.75.75 0 0 1 0 1.5H12.5v1a.75.75 0 0 1-1.5 0v-3.5a.75.75 0 0 1 .75-.75ZM2 4.5a.75.75 0 0 1 .75-.75H8.5a.75.75 0 0 1 0 1.5H2.75A.75.75 0 0 1 2 4.5Zm4.75 3a.75.75 0 0 1 .75.75v3.5a.75.75 0 0 1-1.5 0v-1H2.75a.75.75 0 0 1 0-1.5H6v-1a.75.75 0 0 1 .75-.75Zm2.5 2.5a.75.75 0 0 1 .75-.75h7.25a.75.75 0 0 1 0 1.5H10a.75.75 0 0 1-.75-.75Zm4 3a.75.75 0 0 1 .75.75v1l3.25-.003a.75.75 0 1 1 0 1.5l-3.25.002v1.001a.75.75 0 0 1-1.5 0v-3.5a.75.75 0 0 1 .75-.75ZM2 15.497a.75.75 0 0 1 .75-.75H10a.75.75 0 0 1 0 1.5H2.75a.75.75 0 0 1-.75-.75Z"},"children":[]}],"metadata":""}]},"name":"app-details"};
6
+ const AppDetails: IconDefinition = {"icon":{"type":"root","children":[{"type":"element","tagName":"svg","properties":{"viewBox":"0 0 20 20"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","clipRule":"evenodd","d":"M11.5 3.75c-1.12 0-2.067.736-2.386 1.75H2.75a.75.75 0 0 0 0 1.5h6.364A2.501 2.501 0 1 0 11.5 3.75Zm-.864 2.5a.864.864 0 1 0 1.728 0 .864.864 0 0 0-1.728 0Z"},"children":[]},{"type":"element","tagName":"path","properties":{"d":"M15.5 6.25a.75.75 0 0 1 .75-.75h1a.75.75 0 0 1 0 1.5h-1a.75.75 0 0 1-.75-.75Z"},"children":[]},{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","clipRule":"evenodd","d":"M2 13.75a.75.75 0 0 1 .75-.75h1.364a2.501 2.501 0 1 1 0 1.5H2.75a.75.75 0 0 1-.75-.75Zm4.5.864a.864.864 0 1 1 0-1.728.864.864 0 0 1 0 1.728Z"},"children":[]},{"type":"element","tagName":"path","properties":{"d":"M10.5 13.75a.75.75 0 0 1 .75-.75h6a.75.75 0 0 1 0 1.5h-6a.75.75 0 0 1-.75-.75Z"},"children":[]}],"metadata":""}]},"name":"app-details"};
7
7
 
8
8
  export default AppDetails;
@@ -0,0 +1,8 @@
1
+
2
+ // This icon file is generated automatically.
3
+
4
+ import { IconDefinition } from '../types';
5
+
6
+ const ArrowForward: IconDefinition = {"icon":{"type":"root","children":[{"type":"element","tagName":"svg","properties":{"viewBox":"0 0 20 20"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","clipRule":"evenodd","d":"M10.461 16.018a.75.75 0 0 1 .024-1.06l4.146-3.96H4a.75.75 0 0 1 0-1.5h10.63l-4.145-3.955a.75.75 0 1 1 1.036-1.086l5.498 5.249a.75.75 0 0 1 0 1.085l-5.498 5.251a.75.75 0 0 1-1.06-.024Z"},"children":[]}],"metadata":""}]},"name":"arrow-forward"};
7
+
8
+ export default ArrowForward;
@@ -0,0 +1,8 @@
1
+
2
+ // This icon file is generated automatically.
3
+
4
+ import { IconDefinition } from '../types';
5
+
6
+ const Highlights: IconDefinition = {"icon":{"type":"root","children":[{"type":"element","tagName":"svg","properties":{"viewBox":"0 0 20 20"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","clipRule":"evenodd","d":"M5.25 2.75A.75.75 0 0 1 6 2h4a.75.75 0 0 1 0 1.5H8.75v13H10a.75.75 0 0 1 0 1.5H6a.75.75 0 0 1 0-1.5h1.25v-13H6a.75.75 0 0 1-.75-.75ZM3.75 6.5a.25.25 0 0 0-.25.25v6.5c0 .138.112.25.25.25H5A.75.75 0 0 1 5 15H3.75A1.75 1.75 0 0 1 2 13.25v-6.5C2 5.784 2.784 5 3.75 5H5a.75.75 0 0 1 0 1.5H3.75Zm6.5-.75A.75.75 0 0 1 11 5h5.25c.966 0 1.75.784 1.75 1.75v6.5A1.75 1.75 0 0 1 16.25 15H11a.75.75 0 0 1 0-1.5h5.25a.25.25 0 0 0 .25-.25v-6.5a.25.25 0 0 0-.25-.25H11a.75.75 0 0 1-.75-.75Zm.5 4.25a.75.75 0 0 1 .75-.75H14a.75.75 0 0 1 0 1.5h-2.5a.75.75 0 0 1-.75-.75Z"},"children":[]}],"metadata":""}]},"name":"highlights"};
7
+
8
+ export default Highlights;
@@ -26,6 +26,7 @@ export { default as ArrowBarRight } from './ArrowBarRight';
26
26
  export { default as ArrowBottom } from './ArrowBottom';
27
27
  export { default as ArrowCollapseVertical } from './ArrowCollapseVertical';
28
28
  export { default as ArrowCollapse } from './ArrowCollapse';
29
+ export { default as ArrowForward } from './ArrowForward';
29
30
  export { default as ArrowLeft } from './ArrowLeft';
30
31
  export { default as ArrowRight } from './ArrowRight';
31
32
  export { default as ArrowTop } from './ArrowTop';
@@ -102,6 +103,7 @@ export { default as GoogleMap } from './GoogleMap';
102
103
  export { default as HeadphonesAi } from './HeadphonesAi';
103
104
  export { default as Headphones } from './Headphones';
104
105
  export { default as Hide } from './Hide';
106
+ export { default as Highlights } from './Highlights';
105
107
  export { default as Hint } from './Hint';
106
108
  export { default as Home } from './Home';
107
109
  export { default as ImageXmark } from './ImageXmark';
@@ -0,0 +1,12 @@
1
+ // This icon file is generated automatically.
2
+
3
+ import ArrowForwardSvg from '../ast/ArrowForward';
4
+ import { Icon } from '../Icon';
5
+ import { IconBaseProps } from '../types';
6
+
7
+ const ArrowForward = (
8
+ props: IconBaseProps,
9
+ ): JSX.Element => <Icon {...props} icon={ArrowForwardSvg} />;
10
+
11
+ ArrowForward.displayName = 'ArrowForward';
12
+ export default ArrowForward;
@@ -0,0 +1,12 @@
1
+ // This icon file is generated automatically.
2
+
3
+ import HighlightsSvg from '../ast/Highlights';
4
+ import { Icon } from '../Icon';
5
+ import { IconBaseProps } from '../types';
6
+
7
+ const Highlights = (
8
+ props: IconBaseProps,
9
+ ): JSX.Element => <Icon {...props} icon={HighlightsSvg} />;
10
+
11
+ Highlights.displayName = 'Highlights';
12
+ export default Highlights;
@@ -26,6 +26,7 @@ export { default as ArrowBarRight } from './ArrowBarRight';
26
26
  export { default as ArrowBottom } from './ArrowBottom';
27
27
  export { default as ArrowCollapseVertical } from './ArrowCollapseVertical';
28
28
  export { default as ArrowCollapse } from './ArrowCollapse';
29
+ export { default as ArrowForward } from './ArrowForward';
29
30
  export { default as ArrowLeft } from './ArrowLeft';
30
31
  export { default as ArrowRight } from './ArrowRight';
31
32
  export { default as ArrowTop } from './ArrowTop';
@@ -102,6 +103,7 @@ export { default as GoogleMap } from './GoogleMap';
102
103
  export { default as HeadphonesAi } from './HeadphonesAi';
103
104
  export { default as Headphones } from './Headphones';
104
105
  export { default as Hide } from './Hide';
106
+ export { default as Highlights } from './Highlights';
105
107
  export { default as Hint } from './Hint';
106
108
  export { default as Home } from './Home';
107
109
  export { default as ImageXmark } from './ImageXmark';
@@ -30,7 +30,7 @@ export const listRowSurfaceStylesBase = css`
30
30
  max-width: 100%;
31
31
  flex-basis: 100%;
32
32
  display: flex;
33
- cursor: default;
33
+ cursor: pointer;
34
34
  align-items: center;
35
35
  align-content: center;
36
36
  padding: 0 ${space.s4}px;
@@ -39,7 +39,6 @@ export const listRowSurfaceStylesBase = css`
39
39
  color: ${themeVars.textColor};
40
40
  border-radius: ${border.radius6}px;
41
41
  transition: background-color;
42
-
43
42
  &:focus {
44
43
  outline: none;
45
44
  }
@@ -1,6 +1,6 @@
1
1
  import {GroupHeadingProps, GroupProps, MenuListProps} from "react-select";
2
2
  import {ItemContent, Virtuoso, VirtuosoHandle} from "react-virtuoso";
3
- import {Children, ComponentType, ReactNode, useContext, useEffect, useRef, useState} from "react";
3
+ import {Children, ComponentType, CSSProperties, ReactNode, useContext, useEffect, useRef, useState} from "react";
4
4
  import {GroupBase, ReactSelectRefContext} from "../util";
5
5
  import {layout} from "../../../src/design-system";
6
6
  import _, {isFunction, isObject} from "lodash";
@@ -54,19 +54,12 @@ export function MenuListVirtualized<
54
54
  Option,
55
55
  IsMulti extends boolean = boolean,
56
56
  Group extends GroupBase<Option> = GroupBase<Option>
57
- >({
58
- children,
59
- focusedOption,
60
- innerRef,
61
- maxHeight,
62
- theme,
63
- getStyles,
64
- cx,
65
- selectProps,
66
- }: MenuListProps<Option, IsMulti, Group>) {
57
+ >(props: MenuListProps<Option, IsMulti, Group>) {
58
+ const {children, focusedOption, innerRef, maxHeight, theme, getStyles, cx, selectProps} = props;
67
59
  const virtuoso = useRef<VirtuosoHandle>(null);
68
- // options props come non-filtered and we have insufficient info (props) to render groups and options from here.
69
- // Also you never know what contents also possible as list content.
60
+
61
+ // options props come non-filtered, and we have insufficient info (props) to render groups and options from here.
62
+ // Also, you never know what contents also possible as list content.
70
63
  // that's why it is better working with children and find options and groups among them (hope internal API does not change)
71
64
  // The best strategy to scroll to index and to evade height calculations is to
72
65
  // deconstruct group into it's header and children (options) and render then side by side without group-wrapping div
@@ -98,41 +91,43 @@ export function MenuListVirtualized<
98
91
  //to define initially focused option react select uses whole Option object reference equality which is not always the case
99
92
  //if select value is not exactly same object as option, we end up having initially focusedOption being just first option.
100
93
  //fix below ensures that initial focusedOption is always selectedOption in cost of one more rerender
101
- if (select.current && flattenChildren.length && !initialFocusedOption) {
102
- let firstExistingOption: unknown;
103
- let selectedOption: unknown;
104
- //if an options exists, but there is no focused option, looking for first selected / existing option
105
- for (let i = 0; i < flattenChildren.length; i++) {
106
- const child = flattenChildren[i];
107
- if (
108
- isObject(child) &&
109
- "props" in child &&
110
- isObject(child.props) &&
111
- "type" in child.props &&
112
- child.props.type === "option" &&
113
- "isSelected" in child.props
114
- ) {
115
- //well it is an option, check if it has data (just for ts and be sure)
116
- if ("data" in child.props && isObject(child.props.data)) {
117
- if ("isSelected" in child.props && child.props.isSelected) {
118
- //setting selected option data as focused option, wrapping up
119
- selectedOption = child.props.data;
120
- break;
121
- }
122
- if (!firstExistingOption) {
123
- firstExistingOption = child.props.data;
94
+ useEffect(() => {
95
+ if (select.current && flattenChildren.length && !initialFocusedOption) {
96
+ let firstExistingOption: unknown;
97
+ let selectedOption: unknown;
98
+ //if an options exists, but there is no focused option, looking for first selected / existing option
99
+ for (let i = 0; i < flattenChildren.length; i++) {
100
+ const child = flattenChildren[i];
101
+ if (
102
+ isObject(child) &&
103
+ "props" in child &&
104
+ isObject(child.props) &&
105
+ "type" in child.props &&
106
+ child.props.type === "option" &&
107
+ "isSelected" in child.props
108
+ ) {
109
+ //well it is an option, check if it has data (just for ts and be sure)
110
+ if ("data" in child.props && isObject(child.props.data)) {
111
+ if ("isSelected" in child.props && child.props.isSelected) {
112
+ //setting selected option data as focused option, wrapping up
113
+ selectedOption = child.props.data;
114
+ break;
115
+ }
116
+ if (!firstExistingOption) {
117
+ firstExistingOption = child.props.data;
118
+ }
124
119
  }
125
120
  }
126
121
  }
122
+ if (selectedOption) {
123
+ setInitialFocusedOption(selectedOption as Option);
124
+ select.current.setState({focusedOption: selectedOption});
125
+ } else if (firstExistingOption) {
126
+ setInitialFocusedOption(firstExistingOption as Option);
127
+ select.current.setState({focusedOption: firstExistingOption});
128
+ }
127
129
  }
128
- if (selectedOption) {
129
- setInitialFocusedOption(selectedOption as Option);
130
- select.current.setState({focusedOption: selectedOption});
131
- } else if (firstExistingOption) {
132
- setInitialFocusedOption(firstExistingOption as Option);
133
- select.current.setState({focusedOption: firstExistingOption});
134
- }
135
- }
130
+ }, [flattenChildren, initialFocusedOption, select]);
136
131
  const menuHeight = Math.min(flattenChildren.length * layout.menuItemHeight, maxHeight);
137
132
  //scrolling to focused option
138
133
  useEffect(() => {
@@ -178,7 +173,7 @@ export function MenuListVirtualized<
178
173
  }, [focusedOption, flattenChildren, menuHeight, initialFocusedOption, virtuoso]);
179
174
  return (
180
175
  // Needed for correct display inside portals and etc.
181
- <div>
176
+ <div style={getStyles("menuList", props) as CSSProperties}>
182
177
  <Virtuoso
183
178
  ref={virtuoso}
184
179
  // in reality only HTMLDiveElement | null will appear here. We do not use Virtuoso's useWindowScroll prop
@@ -1,26 +1,37 @@
1
- import React, {ReactNode} from "react";
1
+ import React, {CSSProperties} from "react";
2
2
  import {ListRowContent} from "../../lists/list-row-surface";
3
3
  import {css} from "@linaria/core";
4
- import {space, layout, textStyles} from "../../design-system";
4
+ import {space, textStyles} from "../../design-system";
5
+ import {NoticeProps} from "react-select";
6
+ import {GroupBase} from "../util";
5
7
 
6
8
  const noOptionMessageClass = css`
7
9
  padding: 0 ${space.s6}px;
8
10
  cursor: default;
9
11
  user-select: none;
12
+ max-width: 100%;
10
13
  `;
11
14
  const noOptionMessageContentClass = css`
12
- padding: 0 ${space.s6}px;
13
- white-space: nowrap;
14
15
  overflow: hidden;
15
16
  text-overflow: ellipsis;
17
+ white-space: normal;
18
+ max-width: 100%;
16
19
  ${{...textStyles.regular}}
17
- line-height: ${layout.menuItemHeight}px;
20
+ padding: ${space.s4}px ${space.s6}px;
18
21
  `;
19
22
 
20
- export const NoOptionsMessage = ({children}: {children: ReactNode}) => {
23
+ export const NoOptionsMessage = <Option, isMulty extends boolean, Group extends GroupBase<Option> = GroupBase<Option>>(
24
+ props: NoticeProps<Option, isMulty, Group>
25
+ ) => {
26
+ const {children, getStyles} = props;
21
27
  return (
22
28
  <div className={noOptionMessageClass}>
23
- <ListRowContent contentClassName={noOptionMessageContentClass}>{children}</ListRowContent>
29
+ <ListRowContent
30
+ contentClassName={noOptionMessageContentClass}
31
+ style={getStyles("noOptionsMessage", props) as CSSProperties}
32
+ >
33
+ {children}
34
+ </ListRowContent>
24
35
  </div>
25
36
  );
26
37
  };
@@ -115,6 +115,7 @@ type Props<Option, IsMulti extends boolean, Group extends GroupBase<Option>> = {
115
115
  value?: PropsValue<Option>;
116
116
  menuIsOpen?: boolean;
117
117
  autoFocus?: boolean;
118
+ virtualized?: boolean;
118
119
  defaultMenuIsOpen?: boolean;
119
120
  placeholder?: string;
120
121
  noOptionsMessage: () => string | JSX.Element | null;
@@ -147,6 +148,7 @@ function SelectInPopoverInner<Option, IsMulti extends boolean, Group extends Gro
147
148
  ) {
148
149
  const {
149
150
  value,
151
+ virtualized,
150
152
  menuIsOpen = false,
151
153
  autoFocus,
152
154
  defaultMenuIsOpen,
@@ -321,6 +323,7 @@ function SelectInPopoverInner<Option, IsMulti extends boolean, Group extends Gro
321
323
  filterOption={filterOption}
322
324
  inputValue={inputValue}
323
325
  menuIsOpen
326
+ virtualized={virtualized}
324
327
  maxMenuHeight={maxMenuHeight}
325
328
  disabled={disabled}
326
329
  onFocus={onFocus}
@@ -63,6 +63,12 @@ export const zIndexStyles = (zIndex: number): StylesConfig => ({
63
63
 
64
64
  export const componentsStyles: StylesConfig = {
65
65
  option: () => OptionNulledStyles,
66
+ noOptionsMessage: (provided) => ({
67
+ ...provided,
68
+ paddingLeft: "",
69
+ paddingTop: "",
70
+ paddingBottom: "",
71
+ }),
66
72
  placeholder: (provided) => ({
67
73
  ...provided,
68
74
  color: themeVars.disabledTextColor,